HIP: Heterogenous-computing Interface for Portability
Loading...
Searching...
No Matches
hipBin_nvidia.h
1/*
2Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved.
3
4Permission is hereby granted, free of charge, to any person obtaining a copy
5of this software and associated documentation files (the "Software"), to deal
6in the Software without restriction, including without limitation the rights
7to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8copies of the Software, and to permit persons to whom the Software is
9furnished to do so, subject to the following conditions:
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20THE SOFTWARE.
21*/
22
23#ifndef SRC_HIPBIN_NVIDIA_H_
24#define SRC_HIPBIN_NVIDIA_H_
25
26#include "hipBin_base.h"
27#include "hipBin_util.h"
28#include <iostream>
29#include <vector>
30#include <string>
31
32class HipBinNvidia : public HipBinBase {
33 private:
34 HipBinUtil* hipBinUtilPtr_;
35 string cudaPath_ = "";
36 PlatformInfo platformInfoNV_;
37 string hipCFlags_, hipCXXFlags_, hipLdFlags_;
38
39 public:
41 virtual ~HipBinNvidia() = default;
42 virtual bool detectPlatform();
43 virtual void constructCompilerPath();
44 virtual const string& getCompilerPath() const;
45 virtual const PlatformInfo& getPlatformInfo() const;
46 virtual string getCppConfig();
47 virtual void printFull();
48 virtual void printCompilerInfo() const;
49 virtual string getCompilerVersion();
50 virtual void checkHipconfig();
51 virtual string getDeviceLibPath() const;
52 virtual string getHipLibPath() const;
53 virtual string getHipCC() const;
54 virtual string getCompilerIncludePath();
55 virtual string getHipInclude() const;
56 virtual void initializeHipCXXFlags();
57 virtual void initializeHipCFlags();
58 virtual void initializeHipLdFlags();
59 virtual const string& getHipCXXFlags() const;
60 virtual const string& getHipCFlags() const;
61 virtual const string& getHipLdFlags() const;
62 virtual void executeHipCCCmd(vector<string> argv);
63};
64
65HipBinNvidia::HipBinNvidia() {
66 PlatformInfo platformInfo;
67 platformInfo.os = getOSInfo();
68 platformInfo.platform = nvidia;
69 platformInfo.runtime = cuda;
70 platformInfo.compiler = nvcc;
71 platformInfoNV_ = platformInfo;
72 constructCompilerPath();
73}
74
75// detects if cuda is installed
76bool HipBinNvidia::detectPlatform() {
77 string out;
78 const string& nvccPath = getCompilerPath();
79 fs::path cmdNv = nvccPath;
80 cmdNv /= "bin/nvcc";
81 const OsType& os = getOSInfo();
82 const EnvVariables& var = getEnvVariables();
83 bool detected = false;
84 if (var.hipPlatformEnv_.empty()) {
85 if (canRunCompiler(cmdNv.string(), out) || (canRunCompiler("nvcc", out))) {
86 detected = true;
87 }
88 } else {
89 if (var.hipPlatformEnv_ == "nvidia" || var.hipPlatformEnv_ == "nvcc") {
90 detected = true;
91 if (var.hipPlatformEnv_ == "nvcc")
92 std::cerr << "Warning: HIP_PLATFORM=nvcc is deprecated."
93 << "Please use HIP_PLATFORM=nvidia." << endl;
94 }
95 }
96 return detected;
97}
98
99
100
101// returns device lib path
102string HipBinNvidia::getDeviceLibPath() const {
103 cout << "TODO Not required for now" << endl;
104 return "";
105}
106
107// returns compiler path
108string HipBinNvidia::getHipCC() const {
109 string hipCC;
110 const string& cudaPath = getCompilerPath();
111 fs::path hipCCPath;
112 hipCCPath = cudaPath;
113 hipCCPath /= "bin/nvcc";
114 hipCC = hipCCPath.string();
115 return hipCC;
116}
117
118// returns compiler include path
119string HipBinNvidia::getCompilerIncludePath() {
120 cout << "TODO Not required for now" << endl;
121 return "";
122}
123
124
125// checks Hipconfig
126void HipBinNvidia::checkHipconfig() {
127 cout << endl << "Check system installation: " << endl;
128 cout << "check hipconfig in PATH..." << endl;
129 if (system("which hipconfig > /dev/null 2>&1") != 0) {
130 std::cerr << "FAIL " << endl;
131 } else {
132 cout << "good" << endl;
133 }
134}
135
136// prints full
137void HipBinNvidia::printFull() {
138 const string& hipVersion = getHipVersion();
139 const string& hipPath = getHipPath();
140 const string& roccmPath = getRoccmPath();
141 const PlatformInfo& platformInfo = getPlatformInfo();
142 const string& ccpConfig = getCppConfig();
143 const string& cudaPath = getCompilerPath();
144 cout << "HIP version: " << hipVersion << endl;
145 cout << endl << "==hipconfig" << endl;
146 cout << "HIP_PATH :" << hipPath << endl;
147 cout << "ROCM_PATH :" << roccmPath << endl;
148 cout << "HIP_COMPILER :" << CompilerTypeStr(
149 platformInfo.compiler) << endl;
150 cout << "HIP_PLATFORM :" << PlatformTypeStr(
151 platformInfo.platform) << endl;
152 cout << "HIP_RUNTIME :" << RuntimeTypeStr(
153 platformInfo.runtime) << endl;
154 cout << "CPP_CONFIG :" << ccpConfig << endl;
155 cout << endl << "== nvcc" << endl;
156 cout << "CUDA_PATH :" << cudaPath <<endl;
157 printCompilerInfo();
158 cout << endl << "== Envirnoment Variables" << endl;
159 printEnvironmentVariables();
160 getSystemInfo();
161 if (fs::exists("/usr/bin/lsb_release"))
162 system("/usr/bin/lsb_release -a");
163}
164
165// returns hip include
166string HipBinNvidia::getHipInclude() const {
167 string hipPath, hipInclude;
168 hipPath = getHipPath();
169 fs::path hipIncludefs = hipPath;
170 hipIncludefs /= "include";
171 hipInclude = hipIncludefs.string();
172 return hipInclude;
173}
174
175// initializes Hip ld Flags
176void HipBinNvidia::initializeHipLdFlags() {
177 string hipLdFlags;
178 const string& cudaPath = getCompilerPath();
179 hipLdFlags = " -Wno-deprecated-gpu-targets -lcuda -lcudart -L" +
180 cudaPath + "/lib64";
181 hipLdFlags_ = hipLdFlags;
182}
183
184
185// returns hipc Flags
186const string& HipBinNvidia::getHipCFlags() const {
187 return hipCFlags_;
188}
189
190// returns hip ld flags
191const string& HipBinNvidia::getHipLdFlags() const {
192 return hipLdFlags_;
193}
194
195// initialize Hipc flags
196void HipBinNvidia::initializeHipCFlags() {
197 string hipCFlags;
198 const string& cudaPath = getCompilerPath();
199 hipCFlags += " -isystem " + cudaPath + "/include";
200 string hipIncludePath;
201 hipIncludePath = getHipInclude();
202 hipCFlags += " -isystem \"" + hipIncludePath + "\"";
203 hipCFlags_ = hipCFlags;
204}
205
206// returns Hipccx flags
207const string& HipBinNvidia::getHipCXXFlags() const {
208 return hipCXXFlags_;
209}
210
211// initializes the HIPCCX flags
212void HipBinNvidia::initializeHipCXXFlags() {
213 string hipCXXFlags = " -Wno-deprecated-gpu-targets ";
214 const string& cudaPath = getCompilerPath();
215 hipCXXFlags += " -isystem " + cudaPath + "/include";
216 string hipIncludePath;
217 hipIncludePath = getHipInclude();
218 hipCXXFlags += " -isystem \"" + hipIncludePath + "\"";
219 hipCXXFlags_ = hipCXXFlags;
220}
221
222// returns Hip Lib Path
223string HipBinNvidia::getHipLibPath() const {
224 string hipLibPath;
225 const EnvVariables& env = getEnvVariables();
226 hipLibPath = env.hipLibPathEnv_;
227 return hipLibPath;
228}
229
230// gets nvcc compiler Path
231void HipBinNvidia::constructCompilerPath() {
232 string complierPath;
233 const EnvVariables& envVariables = getEnvVariables();
234 if (envVariables.cudaPathEnv_.empty()) {
235 fs::path cudaPathfs;
236 cudaPathfs = "/usr/local/cuda";
237 complierPath = cudaPathfs.string();
238 } else {
239 complierPath = envVariables.cudaPathEnv_;
240 }
241 cudaPath_ = complierPath;
242}
243
244
245// returns nvcc compiler Path
246const string& HipBinNvidia::getCompilerPath() const {
247 return cudaPath_;
248}
249
250// returns nvcc information
251void HipBinNvidia::printCompilerInfo() const {
252 string cmd;
253 fs::path nvcc;
254 nvcc = getCompilerPath();
255 nvcc /= "bin/nvcc";
256 cmd = nvcc.string() + " --version";
257 system(cmd.c_str());
258}
259
260// returns nvcc version
261string HipBinNvidia::getCompilerVersion() {
262 string complierVersion, cmd;
263 fs::path nvcc;
264 nvcc = getCompilerPath();
265 nvcc /= "bin/nvcc";
266 cmd = nvcc.string() + " --version";
267 system(cmd.c_str());
268 return complierVersion;
269}
270
271// returns nvidia platform
272const PlatformInfo& HipBinNvidia::getPlatformInfo() const {
273 return platformInfoNV_;
274}
275
276// returns the cpp config
277string HipBinNvidia::getCppConfig() {
278 string cppConfig =
279 " - D__HIP_PLATFORM_NVCC__ = -D__HIP_PLATFORM_NVIDIA__ = -I";
280 string hipPath;
281 hipPath = getHipPath();
282 cppConfig += hipPath;
283 cppConfig += "/include -I";
284 cppConfig += cudaPath_;
285 cppConfig += "/include";
286 return cppConfig;
287}
288
289// performs hipcc command
290void HipBinNvidia::executeHipCCCmd(vector<string> argv) {
291 if (argv.size() < 2) {
292 cout<< "No Arguments passed, exiting ...\n";
293 exit(EXIT_SUCCESS);
294 }
295 const EnvVariables& var = getEnvVariables();
296 int verbose = 0;
297 if (!var.verboseEnv_.empty())
298 verbose = stoi(var.verboseEnv_);
299 // Verbose: 0x1=commands, 0x2=paths, 0x4=hipcc args
300 // set if user explicitly requests -stdlib=libc++.
301 // (else we default to libstdc++ for better interop with g++):
302 bool setStdLib = 0;
303 bool default_amdgpu_target = 1;
304 bool compileOnly = 0;
305 bool needCXXFLAGS = 0; // need to add CXX flags to compile step
306 bool needCFLAGS = 0; // need to add C flags to compile step
307 bool needLDFLAGS = 1; // need to add LDFLAGS to compile step.
308 bool fileTypeFlag = 0; // to see if -x flag is mentioned
309 bool hasOMPTargets = 0; // If OMP targets is mentioned
310 bool hasC = 0; // options contain a c-style file
311 // options contain a cpp-style file (NVCC must force recognition as GPU file)
312 bool hasCXX = 0;
313 // options contain a cu-style file (HCC must force recognition as GPU file)
314 bool hasCU = 0;
315 // options contain a hip-style file (HIP-Clang must pass offloading options)
316 bool hasHIP = 0;
317 bool printHipVersion = 0; // print HIP version
318 bool printCXXFlags = 0; // print HIPCXXFLAGS
319 bool printLDFlags = 0; // print HIPLDFLAGS
320 bool runCmd = 1;
321 bool buildDeps = 0;
322 bool linkType = 1;
323 bool setLinkType = 0;
324 string hsacoVersion;
325 bool funcSupp = 0; // enable function support
326 bool rdc = 0; // whether -fgpu-rdc is on
327 string prevArg;
328 // TODO(hipcc): convert toolArgs to an array rather than a string
329 string toolArgs;
330 string optArg;
331 vector<string> options, inputs;
332 // TODO(hipcc): hipcc uses --amdgpu-target for historical reasons.
333 // It should be replaced by clang option --offload-arch.
334 vector<string> targetOpts = {"--offload-arch=", "--amdgpu-target="};
335 string targetsStr;
336 bool skipOutputFile = false;
337 const OsType& os = getOSInfo();
338 string hip_compile_cxx_as_hip;
339 if (var.hipCompileCxxAsHipEnv_.empty()) {
340 hip_compile_cxx_as_hip = "1";
341 } else {
342 hip_compile_cxx_as_hip = var.hipCompileCxxAsHipEnv_;
343 }
344 string HIPLDARCHFLAGS;
345 initializeHipCXXFlags();
346 initializeHipCFlags();
347 initializeHipLdFlags();
348 string HIPCXXFLAGS, HIPCFLAGS, HIPLDFLAGS;
349 HIPCFLAGS = getHipCFlags();
350 HIPCXXFLAGS = getHipCXXFlags();
351 HIPLDFLAGS = getHipLdFlags();
352 string hipPath;
353 hipPath = getHipPath();
354 const PlatformInfo& platformInfo = getPlatformInfo();
355 const string& nvccPath = getCompilerPath();
356 const string& hipVersion = getHipVersion();
357 if (verbose & 0x2) {
358 cout << "HIP_PATH=" << hipPath << endl;
359 cout << "HIP_PLATFORM=" << PlatformTypeStr(platformInfo.platform) <<endl;
360 cout << "HIP_COMPILER=" << CompilerTypeStr(platformInfo.compiler) <<endl;
361 cout << "HIP_RUNTIME=" << RuntimeTypeStr(platformInfo.runtime) <<endl;
362 cout << "CUDA_PATH=" << nvccPath <<endl;
363 }
364 if (verbose & 0x4) {
365 cout << "hipcc-args: ";
366 for (unsigned int i = 1; i< argv.size(); i++) {
367 cout << argv.at(i) << " ";
368 }
369 cout << endl;
370 }
371 // Handle code object generation
372 string ISACMD;
373 ISACMD += hipPath + "/bin/hipcc -ptx ";
374 if (argv.at(1) == "--genco") {
375 for (unsigned int i = 2; i < argv.size(); i++) {
376 string isaarg = argv.at(i);
377 ISACMD += " ";
378 ISACMD += isaarg;
379 }
380 if (verbose & 0x1) {
381 cout<< "hipcc-cmd: " << ISACMD << "\n";
382 }
383 system(ISACMD.c_str());
384 exit(EXIT_SUCCESS);
385 }
386 for (unsigned int argcount = 1; argcount < argv.size(); argcount++) {
387 // Save $arg, it can get changed in the loop.
388 string arg = argv.at(argcount);
389 regex toRemove("\\s+");
390 // TODO(hipcc): figure out why this space removal is wanted.
391 // TODO(hipcc): If someone has gone to the effort of quoting
392 // the spaces to the shell
393 // TODO(hipcc): why are we removing it here?
394 string trimarg = hipBinUtilPtr_->replaceRegex(arg, toRemove, "");
395 bool swallowArg = false;
396 bool escapeArg = true;
397 if (arg == "-c" || arg == "--genco" || arg == "-E") {
398 compileOnly = true;
399 needLDFLAGS = false;
400 }
401 if (skipOutputFile) {
402 // TODO(hipcc): handle filename with shell metacharacters
403 toolArgs += " \"" + arg +"\"";
404 prevArg = arg;
405 skipOutputFile = 0;
406 continue;
407 }
408 if (arg == "-o") {
409 needLDFLAGS = 1;
410 skipOutputFile = 1;
411 }
412 if ((trimarg == "-stdlib=libc++") && (setStdLib == 0)) {
413 HIPCXXFLAGS += " -stdlib=libc++";
414 setStdLib = 1;
415 }
416 // Check target selection option: --offload-arch= and --amdgpu-target=...
417 for (unsigned int i = 0; i <targetOpts.size(); i++) {
418 string targetOpt = targetOpts.at(i);
419 string pattern = "^" + targetOpt + ".*";
420 if (hipBinUtilPtr_->stringRegexMatch(arg, pattern)) {
421 // If targets string is not empty, add a comma before
422 // adding new target option value.
423 targetsStr.size() >0 ? targetsStr += ",": targetsStr += "";
424 targetsStr += arg.substr(targetOpt.size());
425 default_amdgpu_target = 0;
426 }
427 }
428 if (trimarg == "--version") {
429 printHipVersion = 1;
430 }
431 if (trimarg == "--short-version") {
432 printHipVersion = 1;
433 runCmd = 0;
434 }
435 if (trimarg == "--cxxflags") {
436 printCXXFlags = 1;
437 runCmd = 0;
438 }
439 if (trimarg == "--ldflags") {
440 printLDFlags = 1;
441 runCmd = 0;
442 }
443 if (trimarg == "-M") {
444 compileOnly = 1;
445 buildDeps = 1;
446 }
447 if (trimarg == "-use_fast_math") {
448 HIPCXXFLAGS += " -DHIP_FAST_MATH ";
449 HIPCFLAGS += " -DHIP_FAST_MATH ";
450 }
451 if ((trimarg == "-use-staticlib") && (setLinkType == 0)) {
452 linkType = 0;
453 setLinkType = 1;
454 swallowArg = 1;
455 }
456 if ((trimarg == "-use-sharedlib") && (setLinkType == 0)) {
457 linkType = 1;
458 setLinkType = 1;
459 }
460 if (hipBinUtilPtr_->stringRegexMatch(arg, "^-O.*")) {
461 optArg = arg;
462 }
463 if (hipBinUtilPtr_->substringPresent(
464 arg, "--amdhsa-code-object-version=")) {
465 arg = hipBinUtilPtr_->replaceStr(
466 arg, "--amdhsa-code-object-version=", "");
467 hsacoVersion = arg;
468 swallowArg = 1;
469 }
470 // nvcc does not handle standard compiler options properly
471 // This can prevent hipcc being used as standard CXX/C Compiler
472 // To fix this we need to pass -Xcompiler for options
473 if (arg == "-fPIC" || hipBinUtilPtr_->substringPresent(arg, "-Wl,")) {
474 HIPCXXFLAGS += " -Xcompiler "+ arg;
475 swallowArg = 1;
476 }
477 if (arg == "-x") {
478 fileTypeFlag = 1;
479 } else if ((arg == "c" && prevArg == "-x") || (arg == "-xc")) {
480 fileTypeFlag = 1;
481 hasC = 1;
482 hasCXX = 0;
483 hasHIP = 0;
484 } else if ((arg == "c++" && prevArg == "-x") || (arg == "-xc++")) {
485 fileTypeFlag = 1;
486 hasC = 0;
487 hasCXX = 1;
488 hasHIP = 0;
489 } else if ((arg == "hip" && prevArg == "-x") || (arg == "-xhip")) {
490 fileTypeFlag = 1;
491 hasC = 0;
492 hasCXX = 0;
493 hasHIP = 1;
494 } else if (hipBinUtilPtr_->substringPresent(arg, "-fopenmp-targets=")) {
495 hasOMPTargets = 1;
496 } else if (hipBinUtilPtr_->stringRegexMatch(arg, "^-.*")) {
497 if (arg == "-fgpu-rdc") {
498 rdc = 1;
499 } else if (arg == "-fno-gpu-rdc") {
500 rdc = 0;
501 }
502 if (hipBinUtilPtr_->stringRegexMatch(arg, "^--hipcc.*")) {
503 swallowArg = 1;
504 if (arg == "--hipcc-func-supp") {
505 funcSupp = 1;
506 } else if (arg == "--hipcc-no-func-supp") {
507 funcSupp = 0;
508 }
509 } else {
510 options.push_back(arg);
511 }
512 } else if (prevArg != "-o") {
513 if (fileTypeFlag == 0) {
514 if (hipBinUtilPtr_->stringRegexMatch(arg, ".*\\.c$")) {
515 hasC = 1;
516 needCFLAGS = 1;
517 toolArgs += " -x c";
518 } else if ((hipBinUtilPtr_->stringRegexMatch(arg, ".*\\.cpp$")) ||
519 (hipBinUtilPtr_->stringRegexMatch(arg, ".*\\.cxx$")) ||
520 (hipBinUtilPtr_->stringRegexMatch(arg, ".*\\.cc$")) ||
521 (hipBinUtilPtr_->stringRegexMatch(arg, ".*\\.C$"))) {
522 needCXXFLAGS = 1;
523 hasCXX = 1;
524 } else if (((hipBinUtilPtr_->stringRegexMatch(arg, ".*\\.cu$") ||
525 hipBinUtilPtr_->stringRegexMatch(arg, ".*\\.cuh$")) &&
526 hip_compile_cxx_as_hip != "0") ||
527 (hipBinUtilPtr_->stringRegexMatch(arg, ".*\\.hip$"))) {
528 needCXXFLAGS = 1;
529 hasCU = 1;
530 }
531 }
532 if (hasC) {
533 needCFLAGS = 1;
534 } else if (hasCXX || hasHIP) {
535 needCXXFLAGS = 1;
536 }
537 inputs.push_back(arg);
538 }
539 // Windows needs different quoting, ignore for now
540 if (os != windows && escapeArg) {
541 regex reg("[^-a-zA-Z0-9_=+,.\\/]");
542 arg = regex_replace(arg, reg, "\\$&");
543 }
544 if (!swallowArg)
545 toolArgs += " " + arg;
546 prevArg = arg;
547 } // end of for loop
548 if (hasCXX) {
549 HIPCXXFLAGS += " -x cu";
550 }
551 if (buildDeps) {
552 HIPCXXFLAGS += " -M -D__CUDACC__";
553 HIPCFLAGS += " -M -D__CUDACC__";
554 }
555 if (!var.hipccCompileFlagsAppendEnv_.empty()) {
556 HIPCXXFLAGS += "\" " + var.hipccCompileFlagsAppendEnv_ + "\"";
557 HIPCFLAGS += "\" " + var.hipccCompileFlagsAppendEnv_ + "\"";
558 }
559 if (!var.hipccLinkFlagsAppendEnv_.empty()) {
560 HIPLDFLAGS += "\" " + var.hipccLinkFlagsAppendEnv_ + "\"";
561 }
562 string compiler;
563 compiler = getHipCC();
564 string CMD = compiler;
565 if (needCFLAGS) {
566 CMD += " " + HIPCFLAGS;
567 }
568 if (needCXXFLAGS) {
569 CMD += " " + HIPCXXFLAGS;
570 }
571 if (needLDFLAGS && !compileOnly) {
572 CMD += " " + HIPLDFLAGS;
573 }
574 CMD += " " + toolArgs;
575 if (verbose & 0x1) {
576 cout << "hipcc-cmd: " << CMD << "\n";
577 }
578 if (printHipVersion) {
579 if (runCmd) {
580 cout << "HIP version: ";
581 }
582 cout << hipVersion << endl;
583 }
584 if (printCXXFlags) {
585 cout << HIPCXXFLAGS;
586 }
587 if (printLDFlags) {
588 cout << HIPLDFLAGS;
589 }
590 if (runCmd) {
591 SystemCmdOut sysOut;
592 sysOut = hipBinUtilPtr_->exec(CMD.c_str(), true);
593 string cmdOut = sysOut.out;
594 int CMD_EXIT_CODE = sysOut.exitCode;
595 if (CMD_EXIT_CODE !=0) {
596 cout << "failed to execute:" << CMD << std::endl;
597 }
598 exit(CMD_EXIT_CODE);
599 }
600} // end of function
601
602
603#endif // SRC_HIPBIN_NVIDIA_H_
Definition hipBin_base.h:207
Definition hipBin_nvidia.h:32
Definition hipBin_util.h:144
Definition hipBin_base.h:141
Definition hipBin_base.h:134
Definition hipBin_util.h:138