HIP: Heterogenous-computing Interface for Portability
Loading...
Searching...
No Matches
hipBin_amd.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_AMD_H_
24#define SRC_HIPBIN_AMD_H_
25
26#include "hipBin_base.h"
27#include "hipBin_util.h"
28#include <iostream>
29#include <vector>
30#include <string>
31#include <unordered_set>
32#include <cassert>
33
34
35// Use (void) to silent unused warnings.
36#define assertm(exp, msg) assert(((void)msg, exp))
37
38// Known Features
39 std::unordered_set
40 <std::string> knownFeatures = { "sramecc-" , "sramecc+",
41 "xnack-", "xnack+" };
42
43class HipBinAmd : public HipBinBase {
44 private:
45 HipBinUtil* hipBinUtilPtr_;
46 string hipClangPath_ = "";
47 string roccmPathEnv_, hipRocclrPathEnv_, hsaPathEnv_;
48 PlatformInfo platformInfoAMD_;
49 string hipCFlags_, hipCXXFlags_, hipLdFlags_;
50 void constructRocclrHomePath();
51 void constructHsaPath();
52
53 public:
54 HipBinAmd();
55 virtual ~HipBinAmd() = default;
56 virtual bool detectPlatform();
57 virtual void constructCompilerPath();
58 virtual const string& getCompilerPath() const;
59 virtual const PlatformInfo& getPlatformInfo() const;
60 virtual string getCppConfig();
61 virtual void printFull();
62 virtual void printCompilerInfo() const;
63 virtual string getCompilerVersion();
64 virtual void checkHipconfig();
65 virtual string getDeviceLibPath() const;
66 virtual string getHipLibPath() const;
67 virtual string getHipCC() const;
68 virtual string getHipInclude() const;
69 virtual void initializeHipCXXFlags();
70 virtual void initializeHipCFlags();
71 virtual void initializeHipLdFlags();
72 virtual const string& getHipCXXFlags() const;
73 virtual const string& getHipCFlags() const;
74 virtual const string& getHipLdFlags() const;
75 virtual void executeHipCCCmd(vector<string> argv);
76 // non virtual functions
77 const string& getHsaPath() const;
78 const string& getRocclrHomePath() const;
79};
80
81HipBinAmd::HipBinAmd() {
82 PlatformInfo platformInfo;
83 platformInfo.os = getOSInfo();
84 platformInfo.platform = amd;
85 platformInfo.runtime = rocclr;
86 platformInfo.compiler = clang;
87 platformInfoAMD_ = platformInfo;
88}
89
90// returns the Rocclr Home path
91void HipBinAmd::constructRocclrHomePath() {
92 fs::path full_path(fs::current_path());
93 fs::path hipvars_dir = full_path;
94 fs::path bitcode = hipvars_dir;
95 string rocclrHomePath = getEnvVariables().hipRocclrPathEnv_;
96 if (rocclrHomePath.empty()) {
97 bitcode /= "../lib/bitcode";
98 if (!fs::exists(bitcode)) {
99 rocclrHomePath = getHipPath();
100 } else {
101 hipvars_dir /= "..";
102 rocclrHomePath = hipvars_dir.string();
103 }
104 }
105 hipRocclrPathEnv_ = rocclrHomePath;
106}
107
108
109// construct hsa Path
110void HipBinAmd::constructHsaPath() {
111 fs::path hsaPathfs;
112 string hsaPath = getEnvVariables().hsaPathEnv_;
113 if (hsaPath.empty()) {
114 hsaPath = getRoccmPath();
115 hsaPathfs = hsaPath;
116 hsaPathfs /= "hsa";
117 hsaPath = hsaPathfs.string();
118 hsaPathEnv_ = hsaPath;
119 } else {
120 hsaPathEnv_ = hsaPath;
121 }
122}
123
124// returns the Rocclr Home path
125const string& HipBinAmd::getRocclrHomePath() const {
126 return hipRocclrPathEnv_;
127}
128
129// returns hsa Path
130const string& HipBinAmd::getHsaPath() const {
131 // return variables_.hsaPathEnv_;
132 return hsaPathEnv_;
133}
134
135
136const string& HipBinAmd::getHipCFlags() const {
137 return hipCFlags_;
138}
139
140
141const string& HipBinAmd::getHipLdFlags() const {
142 return hipLdFlags_;
143}
144
145
146void HipBinAmd::initializeHipLdFlags() {
147 string hipLibPath;
148 string hipLdFlags;
149 const string& hipClangPath = getCompilerPath();
150 // If $HIPCC clang++ is not compiled, use clang instead
151 string hipCC = "\"" + hipClangPath + "/clang++";
152 if (!fs::exists(hipCC)) {
153 hipLdFlags = "--driver-mode=g++";
154 }
155 hipLibPath = getHipLibPath();
156 hipLdFlags += " -L\"" + hipLibPath + "\"";
157 const OsType& os = getOSInfo();
158 if (os == windows) {
159 hipLdFlags += " -lamdhip64";
160 }
161 hipLdFlags_ = hipLdFlags;
162}
163
164void HipBinAmd::initializeHipCFlags() {
165 string hipCFlags;
166 const OsType& os = getOSInfo();
167 if (os != windows) {
168 string hsaPath;
169 hsaPath = getHsaPath();
170 hipCFlags += " -isystem " + hsaPath + "/include";
171 }
172 string hipIncludePath;
173 hipIncludePath = getHipInclude();
174 hipCFlags += " -isystem \"" + hipIncludePath + "\"";
175 hipCFlags_ = hipCFlags;
176}
177
178const string& HipBinAmd::getHipCXXFlags() const {
179 return hipCXXFlags_;
180}
181
182
183string HipBinAmd::getHipInclude() const {
184 const string& rocclrHomePath = getRocclrHomePath();
185 fs::path hipIncludefs = rocclrHomePath;
186 hipIncludefs /= "include";
187 if (hipIncludefs.string().empty()) {
188 const string& hipPath = getHipPath();
189 hipIncludefs = hipPath;
190 hipIncludefs /= "include";
191 }
192 string hipInclude = hipIncludefs.string();
193 return hipInclude;
194}
195
196
197void HipBinAmd::initializeHipCXXFlags() {
198 string hipCXXFlags;
199 const OsType& os = getOSInfo();
200 const EnvVariables& var = getEnvVariables();
201 // Allow __fp16 as function parameter and return type.
202 if (var.hipClangHccCompactModeEnv_.compare("1") == 0) {
203 hipCXXFlags +=
204 " -Xclang -fallow-half-arguments-and-returns -D__HIP_HCC_COMPAT_MODE__=1";
205 }
206
207 if (os != windows) {
208 const string& hsaPath = getHsaPath();
209 hipCXXFlags += " -isystem " + hsaPath + "/include";
210 }
211 // Add paths to common HIP includes:
212 string hipIncludePath;
213 hipIncludePath = getHipInclude();
214 hipCXXFlags += " -isystem \"" + hipIncludePath + "\"";
215 hipCXXFlags_ = hipCXXFlags;
216}
217
218// populates clang path.
219void HipBinAmd::constructCompilerPath() {
220 string complierPath;
221 const EnvVariables& envVariables = getEnvVariables();
222 if (envVariables.hipClangPathEnv_.empty()) {
223 fs::path hipClangPath;
224 const OsType& osInfo = getOSInfo();
225 if (osInfo == windows) {
226 complierPath = getHipPath();
227 hipClangPath = complierPath;
228 } else {
229 complierPath = getRoccmPath();
230 hipClangPath = complierPath;
231 }
232 if (fs::exists("llvm/bin/clang++")) {
233 hipClangPath /= "llvm/bin";
234 } else {
235 hipClangPath /= "bin";
236 }
237 complierPath = hipClangPath.string();
238 } else {
239 complierPath = envVariables.hipClangPathEnv_;
240 }
241 hipClangPath_ = complierPath;
242}
243
244// returns clang path.
245const string& HipBinAmd::getCompilerPath() const {
246 return hipClangPath_;
247}
248
249void HipBinAmd::printCompilerInfo() const {
250 const OsType& os = getOSInfo();
251 const string& hipClangPath = getCompilerPath();
252 const string& hipPath = getHipPath();
253 if (os == windows) {
254 string cmd = hipClangPath + "/clang++ --version";
255 system(cmd.c_str()); // hipclang version
256 cout << "llc-version :" << endl;
257 cmd = hipClangPath + "/llc --version";
258 system(cmd.c_str()); // llc version
259 cout << "hip-clang-cxxflags :" << endl;
260 cmd = hipPath + "/bin/hipcc --cxxflags";
261 system(cmd.c_str()); // cxx flags
262 cout << endl << "hip-clang-ldflags :" << endl;
263 cmd = hipPath + "/bin/hipcc --ldflags";
264 system(cmd.c_str()); // ld flags
265 cout << endl;
266 } else {
267 string cmd = hipClangPath + "/clang++ --version";
268 system(cmd.c_str()); // hipclang version
269 cmd = hipClangPath + "/llc --version";
270 system(cmd.c_str()); // llc version
271 cout << "hip-clang-cxxflags :" << endl;
272 cmd = hipPath + "/bin/hipcc --cxxflags";
273 system(cmd.c_str()); // cxx flags
274 cout << endl << "hip-clang-ldflags :" << endl;
275 cmd = hipPath + "/bin/hipcc --ldflags";
276 system(cmd.c_str()); // ldflags version
277 cout << endl;
278 }
279}
280
281string HipBinAmd::getCompilerVersion() {
282 string out, complierVersion;
283 const string& hipClangPath = getCompilerPath();
284 fs::path cmdAmd = hipClangPath;
285 cmdAmd /= "clang++";
286 if (canRunCompiler(cmdAmd.string(), out) || canRunCompiler("clang++", out)) {
287 regex regexp("([0-9.]+)");
288 smatch m;
289 if (regex_search(out, m, regexp)) {
290 if (m.size() > 1) {
291 // get the index =1 match, 0=whole match we ignore
292 std::ssub_match sub_match = m[1];
293 complierVersion = sub_match.str();
294 }
295 }
296 } else {
297 std::cerr << "Hip Clang Compiler not found" << endl;
298 }
299 return complierVersion;
300}
301
302
303
304const PlatformInfo& HipBinAmd::getPlatformInfo() const {
305 return platformInfoAMD_;
306}
307
308
309string HipBinAmd::getCppConfig() {
310 string cppConfig = " -D__HIP_PLATFORM_HCC__= -D__HIP_PLATFORM_AMD__=";
311
312 string compilerVersion;
313 compilerVersion = getCompilerVersion();
314
315 fs::path hipPathInclude, cppConfigFs;
316 const string& hipPath = getHipPath();
317 hipPathInclude = hipPath;
318 hipPathInclude /= "include";
319 const OsType& osInfo = getOSInfo();
320 if (osInfo == windows) {
321 cppConfig += " -I" + hipPathInclude.string();
322 cppConfigFs = cppConfig;
323 cppConfigFs /= "/";
324 } else {
325 const string& hsaPath = getHsaPath();
326 cppConfig += " -I" + hipPathInclude.string() +
327 " -I" + hsaPath;
328 cppConfigFs = cppConfig;
329 cppConfigFs /= "include";
330 cppConfig = cppConfigFs.string();
331 }
332 return cppConfig;
333}
334
335string HipBinAmd::getDeviceLibPath() const {
336 const EnvVariables& var = getEnvVariables();
337 string deviceLibPath = var.deviceLibPathEnv_;
338 return deviceLibPath;
339}
340
341
342bool HipBinAmd::detectPlatform() {
343 string out;
344 const string& hipClangPath = getCompilerPath();
345 fs::path cmdAmd = hipClangPath;
346 cmdAmd /= "clang++";
347 const EnvVariables& var = getEnvVariables();
348 bool detected = false;
349 if (var.hipPlatformEnv_.empty()) {
350 if (canRunCompiler(cmdAmd.string(), out) ||
351 (canRunCompiler("clang++", out))) {
352 detected = true;
353 }
354 } else {
355 if (var.hipPlatformEnv_ == "amd" ||
356 var.hipPlatformEnv_ == "hcc") {
357 detected = true;
358 if (var.hipPlatformEnv_ == "hcc")
359 std::cerr <<
360 "Warning: HIP_PLATFORM=hcc is deprecated."<<
361 "Please use HIP_PLATFORM=amd." << endl;
362 }
363 }
364 return detected;
365}
366
367string HipBinAmd::getHipLibPath() const {
368 string hipLibPath;
369 const EnvVariables& env = getEnvVariables();
370 if (env.hipLibPathEnv_.empty()) {
371 const string& rocclrHomePath = getRocclrHomePath();
372 fs::path libPath = rocclrHomePath;
373 libPath /= "lib";
374 hipLibPath = libPath.string();
375 }
376 if (hipLibPath.empty()) {
377 const string& hipPath = getHipPath();
378 fs::path libPath = hipPath;
379 libPath /= "lib";
380 hipLibPath = libPath.string();
381 }
382 return hipLibPath;
383}
384
385string HipBinAmd::getHipCC() const {
386 string hipCC;
387 const string& hipClangPath = getCompilerPath();
388 fs::path compiler = hipClangPath;
389 compiler /= "clang++";
390 if (!fs::exists(compiler)) {
391 fs::path compiler = hipClangPath;
392 compiler /= "clang";
393 }
394 hipCC = compiler.string();
395 return hipCC;
396}
397
398void HipBinAmd::checkHipconfig() {
399 printFull();
400 cout << endl << "Check system installation: " << endl;
401 cout << "check hipconfig in PATH..." << endl;
402 if (system("which hipconfig > /dev/null 2>&1") != 0) {
403 std::cerr << "FAIL " << endl;
404 } else {
405 cout << "good" << endl;
406 }
407 string ldLibraryPath;
408 const EnvVariables& env = getEnvVariables();
409 ldLibraryPath = env.ldLibraryPathEnv_;
410 const string& hsaPath = getHsaPath();
411 cout << "check LD_LIBRARY_PATH (" << ldLibraryPath <<
412 ") contains HSA_PATH (" << hsaPath << ")..." << endl;
413 if (ldLibraryPath.find(hsaPath) == string::npos) {
414 std::cerr << "FAIL" << endl;
415 } else {
416 cout << "good" << endl;
417 }
418}
419
420void HipBinAmd::printFull() {
421 const string& hipVersion = getHipVersion();
422 const string& hipPath = getHipPath();
423 const string& roccmPath = getRoccmPath();
424 const PlatformInfo& platformInfo = getPlatformInfo();
425 const string& ccpConfig = getCppConfig();
426 const string& hsaPath = getHsaPath();
427 const string& hipClangPath = getCompilerPath();
428
429 cout << "HIP version: " << hipVersion << endl;
430 cout << endl << "==hipconfig" << endl;
431 cout << "HIP_PATH :" << hipPath << endl;
432 cout << "ROCM_PATH :" << roccmPath << endl;
433 cout << "HIP_COMPILER :" << CompilerTypeStr(
434 platformInfo.compiler) << endl;
435 cout << "HIP_PLATFORM :" << PlatformTypeStr(
436 platformInfo.platform) << endl;
437 cout << "HIP_RUNTIME :" << RuntimeTypeStr(
438 platformInfo.runtime) << endl;
439 cout << "CPP_CONFIG :" << ccpConfig << endl;
440
441 cout << endl << "==hip-clang" << endl;
442 cout << "HSA_PATH :" << hsaPath << endl;
443 cout << "HIP_CLANG_PATH :" << hipClangPath << endl;
444 printCompilerInfo();
445 cout << endl << "== Envirnoment Variables" << endl;
446 printEnvironmentVariables();
447 getSystemInfo();
448 if (fs::exists("/usr/bin/lsb_release"))
449 system("/usr/bin/lsb_release -a");
450 cout << endl;
451}
452
453
454void HipBinAmd::executeHipCCCmd(vector<string> argv) {
455 if (argv.size() < 2) {
456 cout<< "No Arguments passed, exiting ...\n";
457 exit(EXIT_SUCCESS);
458 }
459 const EnvVariables& var = getEnvVariables();
460 int verbose = 0;
461 if (!var.verboseEnv_.empty())
462 verbose = stoi(var.verboseEnv_);
463
464 // Verbose: 0x1=commands, 0x2=paths, 0x4=hipcc args
465 // set if user explicitly requests -stdlib=libc++
466 // (else we default to libstdc++ for better interop with g++)
467 bool setStdLib = 0;
468 bool default_amdgpu_target = 1;
469 bool compileOnly = 0;
470 bool needCXXFLAGS = 0; // need to add CXX flags to compile step
471 bool needCFLAGS = 0; // need to add C flags to compile step
472 bool needLDFLAGS = 1; // need to add LDFLAGS to compile step.
473 bool fileTypeFlag = 0; // to see if -x flag is mentioned
474 bool hasOMPTargets = 0; // If OMP targets is mentioned
475 bool hasC = 0; // options contain a c-style file
476 // options contain a cpp-style file (NVCC must force recognition as GPU file)
477 bool hasCXX = 0;
478 // options contain a hip-style file (HIP-Clang must pass offloading options)
479 bool hasHIP = 0;
480 bool printHipVersion = 0; // print HIP version
481 bool printCXXFlags = 0; // print HIPCXXFLAGS
482 bool printLDFlags = 0; // print HIPLDFLAGS
483 bool runCmd = 1;
484 bool buildDeps = 0;
485 bool linkType = 1;
486 bool setLinkType = 0;
487 string hsacoVersion;
488 bool funcSupp = 0; // enable function support
489 bool rdc = 0; // whether -fgpu-rdc is on
490
491 string prevArg; // previous argument
492 // TODO(hipcc): convert toolArgs to an array rather than a string
493 string toolArgs; // arguments to pass to the clang or nvcc tool
494 string optArg; // -O args
495 vector<string> options, inputs;
496
497 // TODO(hipcc): hipcc uses --amdgpu-target for historical reasons.
498 // It should be replaced
499 // by clang option --offload-arch.
500 vector<string> targetOpts = {"--offload-arch=", "--amdgpu-target="};
501 string targetsStr;
502 // file followed by -o should not contibute in picking compiler flags
503 bool skipOutputFile = false;
504
505 const OsType& os = getOSInfo();
506 string hip_compile_cxx_as_hip;
507 if (var.hipCompileCxxAsHipEnv_.empty()) {
508 hip_compile_cxx_as_hip = "1";
509 } else {
510 hip_compile_cxx_as_hip = var.hipCompileCxxAsHipEnv_;
511 }
512
513 string HIPLDARCHFLAGS;
514 string HIPCXXFLAGS, HIPCFLAGS, HIPLDFLAGS;
515
516 // ARGV Processing Loop
517 // TODO(hipcc): create a proper Options Processing function/routine
518 for (unsigned int argcount = 1; argcount < argv.size(); argcount++) {
519 // Save $arg, it can get changed in the loop.
520 string arg = argv.at(argcount);
521 // TODO(hipcc): figure out why this space removal is wanted.
522 // TODO(hipcc): If someone has gone to the effort of
523 // quoting the spaces to the shell
524 // TODO(hipcc): why are we removing it here?
525 regex toRemove("\\s+");
526 // Remove whitespace
527 string trimarg = hipBinUtilPtr_->replaceRegex(arg, toRemove, "");
528 bool swallowArg = false;
529 bool escapeArg = true;
530 if (arg == "-c" || arg == "--genco" || arg == "-E") {
531 compileOnly = true;
532 needLDFLAGS = false;
533 }
534
535 if (skipOutputFile) {
536 // TODO(hipcc): handle filename with shell metacharacters
537 toolArgs += " \"" + arg +"\"";
538 prevArg = arg;
539 skipOutputFile = 0;
540 continue;
541 }
542
543 if (arg == "-o") {
544 needLDFLAGS = 1;
545 skipOutputFile = 1;
546 }
547
548 if ((trimarg == "-stdlib=libc++") && (setStdLib == 0)) {
549 HIPCXXFLAGS += " -stdlib=libc++";
550 setStdLib = 1;
551 }
552
553 // Process --rocm-path option
554 const string& rocmPathOption = "--rocm-path=";
555 if (arg.compare(0,rocmPathOption.length(),rocmPathOption) == 0)
556 rocm_pathOption_ = arg.substr(rocmPathOption.length());
557
558 // Check target selection option: --offload-arch= and --amdgpu-target=...
559 for (unsigned int i = 0; i <targetOpts.size(); i++) {
560 string targetOpt = targetOpts.at(i);
561 // match arg with the starting of targetOpt
562 string pattern = "^" + targetOpt + ".*";
563 if (hipBinUtilPtr_->stringRegexMatch(arg, pattern)) {
564 if (targetOpt == "--amdgpu-target=") {
565 std::cerr << "Warning: The --amdgpu-target option has been deprecated and will be removed in the future."
566 << " Use --offload-arch instead.\n";
567 }
568 // If targets string is not empty,
569 // add a comma before adding new target option value.
570 targetsStr.size() >0 ? targetsStr += ",": targetsStr += "";
571 targetsStr += arg.substr(targetOpt.size()); // argument of targetOpts
572 default_amdgpu_target = 0;
573 // Collect the GPU arch options and pass them to clang later.
574 swallowArg = 1;
575 }
576 } // end of for targetOpts for loop
577
578 if (hipBinUtilPtr_->substringPresent(arg, "--genco")) {
579 arg = "--cuda-device-only";
580 }
581
582 if (trimarg == "--version") {
583 printHipVersion = 1;
584 }
585 if (trimarg == "--short-version") {
586 printHipVersion = 1;
587 runCmd = 0;
588 }
589 if (trimarg == "--cxxflags") {
590 printCXXFlags = 1;
591 runCmd = 0;
592 }
593 if (trimarg == "--ldflags") {
594 printLDFlags = 1;
595 runCmd = 0;
596 }
597 if (trimarg == "-M") {
598 compileOnly = 1;
599 buildDeps = 1;
600 }
601 if ((trimarg == "-use-staticlib") && (setLinkType == 0)) {
602 linkType = 0;
603 setLinkType = 1;
604 swallowArg = 1;
605 }
606 if ((trimarg == "-use-sharedlib") && (setLinkType == 0)) {
607 linkType = 1;
608 setLinkType = 1;
609 }
610 if (hipBinUtilPtr_->stringRegexMatch(arg, "^-O.*")) {
611 optArg = arg;
612 }
613 if (hipBinUtilPtr_->substringPresent(
614 arg, "--amdhsa-code-object-version=")) {
615 std::cerr << "Warning: The --amdhsa-code-object-version option has been deprecated and will be removed in the future."
616 << " Use -mllvm -mcode-object-version instead.\n";
617 arg = hipBinUtilPtr_->replaceStr(
618 arg, "--amdhsa-code-object-version=", "");
619 hsacoVersion = arg;
620 swallowArg = 1;
621 }
622
623 if (arg == "-x") {
624 fileTypeFlag = 1;
625 } else if ((arg == "c" && prevArg == "-x") || (arg == "-xc")) {
626 fileTypeFlag = 1;
627 hasC = 1;
628 hasCXX = 0;
629 hasHIP = 0;
630 } else if ((arg == "c++" && prevArg == "-x") || (arg == "-xc++")) {
631 fileTypeFlag = 1;
632 hasC = 0;
633 hasCXX = 1;
634 hasHIP = 0;
635 } else if ((arg == "hip" && prevArg == "-x") || (arg == "-xhip")) {
636 fileTypeFlag = 1;
637 hasC = 0;
638 hasCXX = 0;
639 hasHIP = 1;
640 } else if (hipBinUtilPtr_->substringPresent(arg, "-fopenmp-targets=")) {
641 hasOMPTargets = 1;
642 // options start with -
643 } else if (hipBinUtilPtr_->stringRegexMatch(arg, "^-.*")) {
644 if (arg == "-fgpu-rdc") {
645 rdc = 1;
646 } else if (arg == "-fno-gpu-rdc") {
647 rdc = 0;
648 }
649 //# Process HIPCC options here:
650 if (hipBinUtilPtr_->stringRegexMatch(arg, "^--hipcc.*")) {
651 swallowArg = 1;
652 if (arg == "--hipcc-func-supp") {
653 std::cerr << "Warning: The --hipcc-func-supp option has been deprecated and will be removed in the future.\n";
654 funcSupp = 1;
655 } else if (arg == "--hipcc-no-func-supp") {
656 std::cerr << "Warning: The --hipcc-no-func-supp option has been deprecated and will be removed in the future.\n";
657 funcSupp = 0;
658 }
659 } else {
660 options.push_back(arg);
661 }
662 // print "O: <$arg>\n";
663 } else if (prevArg != "-o") {
664 // input files and libraries
665 // Skip guessing if `-x {c|c++|hip}` is already specified.
666 // Add proper file extension before each file type
667 // File Extension -> Flag
668 // .c -> -x c
669 // .cpp/.cxx/.cc/.cu/.cuh/.hip -> -x hip
670
671 if (fileTypeFlag == 0) {
672 if (hipBinUtilPtr_->stringRegexMatch(arg, ".*\\.c$")) {
673 hasC = 1;
674 needCFLAGS = 1;
675 toolArgs += " -x c";
676 } else if ((hipBinUtilPtr_->stringRegexMatch(arg, ".*\\.cpp$")) ||
677 (hipBinUtilPtr_->stringRegexMatch(arg, ".*\\.cxx$")) ||
678 (hipBinUtilPtr_->stringRegexMatch(arg, ".*\\.cc$")) ||
679 (hipBinUtilPtr_->stringRegexMatch(arg, ".*\\.C$"))) {
680 needCXXFLAGS = 1;
681 if (hip_compile_cxx_as_hip == "0" || hasOMPTargets == 1) {
682 hasCXX = 1;
683 } else {
684 hasHIP = 1;
685 toolArgs += " -x hip";
686 }
687 } else if (((hipBinUtilPtr_->stringRegexMatch(arg, ".*\\.cu$") ||
688 hipBinUtilPtr_->stringRegexMatch(arg, ".*\\.cuh$")) &&
689 hip_compile_cxx_as_hip != "0") ||
690 (hipBinUtilPtr_->stringRegexMatch(arg, ".*\\.hip$"))) {
691 needCXXFLAGS = 1;
692 hasHIP = 1;
693 toolArgs += " -x hip";
694 }
695 }
696 if (hasC) {
697 needCFLAGS = 1;
698 } else if (hasCXX || hasHIP) {
699 needCXXFLAGS = 1;
700 }
701 inputs.push_back(arg);
702 // print "I: <$arg>\n";
703 }
704 // Produce a version of $arg where characters significant to the shell are
705 // quoted. One could quote everything of course but don't bother for
706 // common characters such as alphanumerics.
707 // Do the quoting here because sometimes the $arg is changed in the loop
708 // Important to have all of '-Xlinker' in the set of unquoted characters.
709 // Windows needs different quoting, ignore for now
710 if (os != windows && escapeArg) {
711 regex reg("[^-a-zA-Z0-9_=+,.\\/]");
712 arg = regex_replace(arg, reg, "\\$&");
713 }
714 if (!swallowArg)
715 toolArgs += " " + arg;
716 prevArg = arg;
717 } // end of ARGV Processing Loop
718
719 // now construct Paths ...
720 constructRoccmPath(); // constructs Roccm Path
721 constructHipPath(); // constructs HIP Path
722 readHipVersion(); // stores the hip version
723 constructCompilerPath();
724 constructRocclrHomePath();
725 constructHsaPath();
726
727 initializeHipCXXFlags();
728 initializeHipCFlags();
729 initializeHipLdFlags();
730 HIPCFLAGS = getHipCFlags();
731 HIPCXXFLAGS = getHipCXXFlags();
732 HIPLDFLAGS = getHipLdFlags();
733
734 string hipLibPath;
735 string hipIncludePath, deviceLibPath;
736 hipLibPath = getHipLibPath();
737 const string& roccmPath = getRoccmPath();
738 const string& hipPath = getHipPath();
739 const PlatformInfo& platformInfo = getPlatformInfo();
740 const string& rocclrHomePath = getRocclrHomePath();
741 const string& hipClangPath = getCompilerPath();
742 hipIncludePath = getHipInclude();
743 deviceLibPath = getDeviceLibPath();
744 const string& hipVersion = getHipVersion();
745 if (verbose & 0x2) {
746 cout << "HIP_PATH=" << hipPath << endl;
747 cout << "HIP_PLATFORM=" << PlatformTypeStr(platformInfo.platform) <<endl;
748 cout << "HIP_COMPILER=" << CompilerTypeStr(platformInfo.compiler) <<endl;
749 cout << "HIP_RUNTIME=" << RuntimeTypeStr(platformInfo.runtime) <<endl;
750 cout << "ROCM_PATH=" << roccmPath << endl;
751 cout << "HIP_ROCCLR_HOME="<< rocclrHomePath << endl;
752 cout << "HIP_CLANG_PATH=" << hipClangPath <<endl;
753 cout << "HIP_INCLUDE_PATH="<< hipIncludePath <<endl;
754 cout << "HIP_LIB_PATH="<< hipLibPath <<endl;
755 cout << "DEVICE_LIB_PATH="<< deviceLibPath <<endl;
756 }
757
758 if (verbose & 0x4) {
759 cout << "hipcc-args: ";
760 for (unsigned int i = 1; i< argv.size(); i++) {
761 cout << argv.at(i) << " ";
762 }
763 cout << endl;
764 }
765
766 // No AMDGPU target specified at commandline. So look for HCC_AMDGPU_TARGET
767 if (default_amdgpu_target == 1) {
768 if (!var.hccAmdGpuTargetEnv_.empty()) {
769 targetsStr = var.hccAmdGpuTargetEnv_;
770 } else if (os != windows) {
771 // Else try using rocm_agent_enumerator
772 string ROCM_AGENT_ENUM;
773 ROCM_AGENT_ENUM = roccmPath + "/bin/rocm_agent_enumerator";
774 targetsStr = ROCM_AGENT_ENUM +" -t GPU";
775 SystemCmdOut sysOut = hipBinUtilPtr_->exec(targetsStr.c_str());
776 regex toReplace("\n+");
777 targetsStr = hipBinUtilPtr_->replaceRegex(sysOut.out, toReplace, ",");
778 }
779 default_amdgpu_target = 0;
780 }
781 // Parse the targets collected in targetStr
782 // and set corresponding compiler options.
783 vector<string> targets = hipBinUtilPtr_->splitStr(targetsStr, ',');
784 string GPU_ARCH_OPT = " --offload-arch=";
785
786 for (auto &val : targets) {
787 // Ignore 'gfx000' target reported by rocm_agent_enumerator.
788 if (val != "gfx000") {
789 vector<string> procAndFeatures = hipBinUtilPtr_->splitStr(val, ':');
790 size_t len = procAndFeatures.size();
791 // proc and features
792 assertm(procAndFeatures.size() >= 1, "Pass the correct device/feature");
793 for (size_t i = 1; i < len; i++) {
794 // fixme: currently it checks only for validity of the feature string.
795 // does not check if the device supports the feature or not
796 // e.g. vega10 does not support sramecc
797 if (knownFeatures.find(procAndFeatures.at(i)) == knownFeatures.end()) {
798 std::cerr << "Warning: The Feature: "<< procAndFeatures.at(i) <<
799 " is unknown. Correct compilation is not guaranteed.\n";
800 }
801 }
802 string GPU_ARCH_ARG;
803 GPU_ARCH_ARG = GPU_ARCH_OPT + val;
804
805 HIPLDARCHFLAGS += GPU_ARCH_ARG;
806 if (hasHIP) {
807 HIPCXXFLAGS += GPU_ARCH_ARG;
808 }
809 } // end of val != "gfx000"
810 } // end of targets for loop
811 string HCC_EXTRA_LIBRARIES;
812 if (hsacoVersion.size() > 0) {
813 if (compileOnly == 0) {
814 HIPLDFLAGS += " -mcode-object-version=" + hsacoVersion;
815 } else {
816 HIPCXXFLAGS += " -mcode-object-version=" + hsacoVersion;
817 }
818 }
819
820 // rocm_agent_enumerator failed! Throw an error and die if linking is required
821 if (default_amdgpu_target == 1 && compileOnly == 0) {
822 // TODO(agunashe) exit from function
823 std::cerr << "No valid AMD GPU target was either specified or found."
824 << "Please specify a valid target using --offload-arch=<target>.\n";
825 }
826 HCC_EXTRA_LIBRARIES ="\n"; // TODO(agunashe) write to env
827
828 if (buildDeps) {
829 HIPCXXFLAGS += " --cuda-host-only";
830 }
831 // Add --hip-link only if it is compile only and -fgpu-rdc is on.
832 if (rdc && !compileOnly) {
833 HIPLDFLAGS += " --hip-link";
834 HIPLDFLAGS += HIPLDARCHFLAGS;
835 }
836
837 // hipcc currrently requires separate compilation of source files,
838 // ie it is not possible to pass
839 // CPP files combined with .O files
840 // Reason is that NVCC uses the file extension to determine
841 // whether to compile in CUDA mode or
842 // pass-through CPP mode.
843 // Set default optimization level to -O3 for hip-clang.
844 if (optArg.empty()) {
845 HIPCXXFLAGS += " -O3";
846 HIPCFLAGS += " -O3";
847 HIPLDFLAGS += " -O3";
848 }
849
850 if (!funcSupp && optArg != "-O0" && hasHIP) {
851 HIPCXXFLAGS +=
852 " -mllvm -amdgpu-early-inline-all=true -mllvm -amdgpu-function-calls=false";
853 if (needLDFLAGS && !needCXXFLAGS) {
854 HIPLDFLAGS +=
855 " -mllvm -amdgpu-early-inline-all=true"
856 " -mllvm -amdgpu-function-calls=false";
857 }
858 }
859
860 if (hasHIP) {
861 if (!deviceLibPath.empty()) {
862 string hip_device_lib_str = " --hip-device-lib-path=\""
863 + deviceLibPath + "\"";
864 HIPCXXFLAGS += hip_device_lib_str;
865 }
866 }
867 if (os != windows) {
868 HIPLDFLAGS += " -lgcc_s -lgcc -lpthread -lm -lrt";
869 }
870
871 if (os != windows && !compileOnly) {
872 string hipClangVersion, toolArgTemp;
873 if (linkType == 0) {
874 toolArgTemp = " -L"+ hipLibPath + "-lamdhip64 -L" +
875 roccmPath+ "/lib -lhsa-runtime64 -ldl -lnuma " + toolArgs;
876 toolArgs = toolArgTemp;
877 } else {
878 toolArgTemp = toolArgs + " -Wl,-rpath=" + hipLibPath + ":"
879 + roccmPath+"/lib -lamdhip64 ";
880 toolArgs = toolArgTemp;
881 }
882
883 hipClangVersion = getCompilerVersion();
884 // To support __fp16 and _Float16, explicitly link with compiler-rt
885 toolArgs += " -L" + hipClangPath + "/../lib/clang/" +
886 hipClangVersion + "/lib/linux -lclang_rt.builtins-x86_64 ";
887 }
888 if (!var.hipccCompileFlagsAppendEnv_.empty()) {
889 HIPCXXFLAGS += " " + var.hipccCompileFlagsAppendEnv_ + " ";
890 HIPCFLAGS += " " + var.hipccCompileFlagsAppendEnv_ + " ";
891 }
892 if (!var.hipccLinkFlagsAppendEnv_.empty()) {
893 HIPLDFLAGS += " " + var.hipccLinkFlagsAppendEnv_ + " ";
894 }
895 // TODO(hipcc): convert CMD to an array rather than a string
896 string compiler;
897 compiler = getHipCC();
898 string CMD = compiler;
899 if (needCFLAGS) {
900 CMD += " " + HIPCFLAGS;
901 }
902
903 if (needCXXFLAGS) {
904 CMD += " " + HIPCXXFLAGS;
905 }
906
907 if (needLDFLAGS && !compileOnly) {
908 CMD += " " + HIPLDFLAGS;
909 }
910
911 CMD += " " + toolArgs;
912 if (verbose & 0x1) {
913 cout << "hipcc-cmd: " << CMD << "\n";
914 }
915
916 if (printHipVersion) {
917 if (runCmd) {
918 cout << "HIP version: ";
919 }
920 cout << hipVersion << endl;
921 }
922 if (printCXXFlags) {
923 cout << HIPCXXFLAGS;
924 }
925 if (printLDFlags) {
926 cout << HIPLDFLAGS;
927 }
928 if (runCmd) {
929 SystemCmdOut sysOut;
930 sysOut = hipBinUtilPtr_->exec(CMD.c_str(), true);
931 string cmdOut = sysOut.out;
932 int CMD_EXIT_CODE = sysOut.exitCode;
933 if (CMD_EXIT_CODE !=0) {
934 std::cerr << "failed to execute:" << CMD << std::endl;
935 }
936 exit(CMD_EXIT_CODE);
937 } // end of runCmd section
938} // end of function
939
940#endif // SRC_HIPBIN_AMD_H_
Definition hipBin_amd.h:43
Definition hipBin_base.h:207
Definition hipBin_util.h:144
Definition hipBin_base.h:141
Definition hipBin_base.h:134
Definition hipBin_util.h:138