diff --git a/hipamd/bin/hipify-perl b/hipamd/bin/hipify-perl index b5fc365955..b75b68d3b4 100755 --- a/hipamd/bin/hipify-perl +++ b/hipamd/bin/hipify-perl @@ -1812,15 +1812,191 @@ if ($count_conversions) { sub countSupportedDeviceFunctions { my $m = 0; - # TODO: list all of the supported functions - # TODO: split the list on math, device, and maybe fp16 foreach $func ( - # Synchronization: - "__syncthreads", + "abs", + "acos", + "acosf", + "acosh", + "acoshf", + "asin", + "asinf", + "asinh", + "asinhf", + "atan", + "atan2", + "atan2f", + "atanf", + "atanh", + "atanhf", + "cbrt", + "cbrtf", + "ceil", + "ceilf", + "copysign", + "copysignf", + "cos", + "cosf", + "cosh", + "coshf", + "cospi", + "cospif", + "cyl_bessel_i0", + "cyl_bessel_i0f", + "cyl_bessel_i1", + "cyl_bessel_i1f", + "erf", + "erfc", + "erfcf", + "erfcinv", + "erfcinvf", + "erfcx", + "erfcxf", + "erff", + "erfinv", + "erfinvf", + "exp", + "exp10", + "exp10f", + "exp2", + "exp2f", + "expf", + "expm1", + "expm1f", + "fabs", + "fabsf", + "fdim", + "fdimf", + "floor", + "floorf", + "fma", + "fmaf", + "fmax", + "fmaxf", + "fmin", + "fminf", + "fmod", + "fmodf", + "frexp", + "frexpf", + "hypot", + "hypotf", + "ilogb", + "ilogbf", + "isfinite", + "isinf", + "isnan", + "j0", + "j0f", + "j1", + "j1f", + "jn", + "jnf", + "labs", + "ldexp", + "ldexpf", + "lgamma", + "lgammaf", + "llabs", + "llrint", + "llrintf", + "llround", + "llroundf", + "log", + "log10", + "log10f", + "log1p", + "log1pf", + "log2", + "log2f", + "logb", + "logbf", + "logf", + "lrint", + "lrintf", + "lround", + "lroundf", + "max", + "min", + "modf", + "modff", + "nan", + "nanf", + "nearbyint", + "nearbyintf", + "nextafter", + "nextafterf", + "norm", + "norm3d", + "norm3df", + "norm4d", + "norm4df", + "normcdf", + "normcdff", + "normcdfinv", + "normcdfinvf", + "normf", + "pow", + "powf", + "rcbrt", + "rcbrtf", + "remainder", + "remainderf", + "remquo", + "remquof", + "rhypot", + "rhypotf", + "rint", + "rintf", + "rnorm", + "rnorm3d", + "rnorm3df", + "rnorm4d", + "rnorm4df", + "rnormf", + "round", + "roundf", + "rsqrt", + "rsqrtf", + "scalbln", + "scalblnf", + "scalbn", + "scalbnf", + "signbit", + "sin", + "sincos", + "sincosf", + "sincospi", + "sincospif", + "sinf", + "sinh", + "sinhf", + "sinpi", + "sinpif", + "sqrt", + "sqrtf", + "tan", + "tanf", + "tanh", + "tanhf", + "tgamma", + "tgammaf", + "trunc", + "truncf", + "y0", + "y0f", + "y1", + "y1f", + "yn", + "ynf" ) { - # match device func at the beginning of a word, but not if it already has a namespace qualifier ('::') : - $m += m/[:]?[:]?\b($func)\b(\w*\()/g; + # match device function from the list, except those, which have a namespace prefix (aka somenamespace::umin(...)); + # function with only global namespace qualifier '::' (aka ::umin(...)) should be treated as a device function (and warned as well as without such qualifier); + my $mt_namespace = m/(\w+)::($func)\s*\(\s*.*\s*\)/g; + my $mt = m/($func)\s*\(\s*.*\s*\)/g; + if ($mt && !$mt_namespace) { + $m += $mt; + } } return $m; } @@ -1956,7 +2132,7 @@ sub warnUnsupportedDeviceFunctions "umul24" ) { - # match device function from the list of unsupported, except those, which have a namespace prefix (aka somenamespace::umin(...)); + # match device function from the list, except those, which have a namespace prefix (aka somenamespace::umin(...)); # function with only global namespace qualifier '::' (aka ::umin(...)) should be treated as a device function (and warned as well as without such qualifier); my $mt_namespace = m/(\w+)::($func)\s*\(\s*.*\s*\)/g; my $mt = m/($func)\s*\(\s*.*\s*\)/g; diff --git a/hipamd/hipify-clang/src/CUDA2HIP_Device_functions.cpp b/hipamd/hipify-clang/src/CUDA2HIP_Device_functions.cpp index af48279a95..b2271366b1 100644 --- a/hipamd/hipify-clang/src/CUDA2HIP_Device_functions.cpp +++ b/hipamd/hipify-clang/src/CUDA2HIP_Device_functions.cpp @@ -25,6 +25,181 @@ THE SOFTWARE. // Maps CUDA header names to HIP header names const std::map CUDA_DEVICE_FUNC_MAP{ // math functions + {"abs", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"labs", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"llabs", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"fabs", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"fabsf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"min", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"fminf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"fmin", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"max", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"fmaxf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"fmax", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"sin", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"cos", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"sincos", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"sincosf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"tan", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"sqrt", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"rsqrt", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"rsqrtf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"log2", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"exp2", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"exp2f", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"exp10", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"exp10f", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"expm1", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"expm1f", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"log2f", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"log10", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"log", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"log1p", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"log1pf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"floor", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"exp", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"cosh", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"sinh", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"tanh", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"acosh", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"acoshf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"asinh", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"asinhf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"atanh", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"atanhf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"ldexp", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"ldexpf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"logb", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"logbf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"ilogb", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"ilogbf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"scalbn", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"scalbnf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"scalbln", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"scalblnf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"frexp", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"frexpf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"round", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"roundf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"lround", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"lroundf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"llround", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"llroundf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"rint", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"rintf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"lrint", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"lrintf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"llrint", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"llrintf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"nearbyint", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"nearbyintf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"ceil", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"trunc", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"truncf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"fdim", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"fdimf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"atan2", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"atan", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"acos", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"asin", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"hypot", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"rhypot", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"hypotf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"rhypotf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"norm3d", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"rnorm3d", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"norm4d", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"rnorm4d", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"norm", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"rnorm", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"rnormf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"normf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"norm3df", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"rnorm3df", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"norm4df", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"rnorm4df", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"cbrt", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"cbrtf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"rcbrt", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"rcbrtf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"sinpi", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"sinpif", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"cospi", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"cospif", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"sincospi", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"sincospif", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"pow", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"modf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"fmod", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"remainder", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"remainderf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"remquo", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"remquof", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"j0", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"j0f", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"j1", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"j1f", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"jn", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"jnf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"y0", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"y0f", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"y1", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"y1f", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"yn", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"ynf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"cyl_bessel_i0", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"cyl_bessel_i0f", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"cyl_bessel_i1", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"cyl_bessel_i1f", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"erf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"erff", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"erfinv", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"erfinvf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"erfc", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"erfcf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"lgamma", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"erfcinv", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"erfcinvf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"normcdfinv", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"normcdfinvf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"normcdf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"normcdff", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"erfcx", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"erfcxf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"lgammaf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"tgamma", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"tgammaf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"copysign", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"copysignf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"nextafter", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"nextafterf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"nan", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"nanf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"fma", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"fmaf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"acosf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"asinf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"atanf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"atan2f", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"cosf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"sinf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"tanf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"coshf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"sinhf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"tanhf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"expf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"logf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"log10f", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"modff", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"powf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"sqrtf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"ceilf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"floorf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"fmodf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"signbit", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"isfinite", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"isnan", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, + {"isinf", {"", "", CONV_DEVICE_FUNC, API_RUNTIME}}, {"umin", {"", "", CONV_DEVICE_FUNC, API_RUNTIME, UNSUPPORTED}}, {"llmin", {"", "", CONV_DEVICE_FUNC, API_RUNTIME, UNSUPPORTED}}, {"ullmin", {"", "", CONV_DEVICE_FUNC, API_RUNTIME, UNSUPPORTED}}, diff --git a/hipamd/hipify-clang/src/CUDA2HIP_Perl.cpp b/hipamd/hipify-clang/src/CUDA2HIP_Perl.cpp index 75afc0a534..25705e5bd6 100644 --- a/hipamd/hipify-clang/src/CUDA2HIP_Perl.cpp +++ b/hipamd/hipify-clang/src/CUDA2HIP_Perl.cpp @@ -39,32 +39,64 @@ namespace perl { const std::string space = " "; const std::string double_space = space + space; const std::string triple_space = double_space + space; + const std::string sSub = "sub"; + const std::string sReturn_0 = "return 0;\n"; - void generateUnsupportedDeviceFunctions(std::unique_ptr& perlStreamPtr) { - unsigned int num = 0; + void generateDeviceFunctions(std::unique_ptr& perlStreamPtr) { + unsigned int countUnsupported = 0; + unsigned int countSupported = 0; + std::stringstream sSupported; std::stringstream sUnsupported; for (auto& ma : CUDA_DEVICE_FUNC_MAP) { - if (Statistics::isUnsupported(ma.second)) { - sUnsupported << (num ? ",\n" : "") << double_space << "\"" << ma.first.str() << "\""; - num++; + bool isUnsupported = Statistics::isUnsupported(ma.second); + (isUnsupported ? sUnsupported : sSupported) << ((isUnsupported && countUnsupported) || (!isUnsupported && countSupported) ? ",\n" : "") << double_space << "\"" << ma.first.str() << "\""; + if (isUnsupported) { + countUnsupported++; + } else { + countSupported++; } } - if (num) { - *perlStreamPtr.get() << "\nsub warnUnsupportedDeviceFunctions\n" << "{\n" << space << "my $line_num = shift;\n" << space << "my $m = 0;\n" << space << "foreach $func (\n"; - *perlStreamPtr.get() << sUnsupported.str() << "\n" << space << ")\n"; - *perlStreamPtr.get() << space << "{\n"; - *perlStreamPtr.get() << double_space << "# match device function from the list of unsupported, except those, which have a namespace prefix (aka somenamespace::umin(...));\n"; - *perlStreamPtr.get() << double_space << "# function with only global namespace qualifier '::' (aka ::umin(...)) should be treated as a device function (and warned as well as without such qualifier);\n"; - *perlStreamPtr.get() << double_space << "my $mt_namespace = m/(\\w+)::($func)\\s*\\(\\s*.*\\s*\\)/g;\n"; - *perlStreamPtr.get() << double_space << "my $mt = m/($func)\\s*\\(\\s*.*\\s*\\)/g;\n"; - *perlStreamPtr.get() << double_space << "if ($mt && !$mt_namespace) {\n"; - *perlStreamPtr.get() << triple_space << "$m += $mt;\n"; - *perlStreamPtr.get() << triple_space << "print STDERR \" warning: $fileName:$line_num: unsupported device function \\\"$func\\\": $_\\n\";\n"; - *perlStreamPtr.get() << double_space << "}\n"; - *perlStreamPtr.get() << space << "}\n"; - *perlStreamPtr.get() << space << "return $m;\n"; - *perlStreamPtr.get() << "}\n"; + std::stringstream subCountSupported; + std::stringstream subWarnUnsupported; + std::stringstream subCommon; + std::string sCommon = space + "my $m = 0;\n" + space + "foreach $func (\n"; + subCountSupported << "\n" << sSub << " countSupportedDeviceFunctions\n" << "{\n" << (countSupported ? sCommon : space + sReturn_0); + subWarnUnsupported << "\n" << sSub << " warnUnsupportedDeviceFunctions\n" << "{\n" << (countUnsupported ? space + "my $line_num = shift;\n" + sCommon : space + sReturn_0); + if (countSupported) { + subCountSupported << sSupported.str() << "\n" << space << ")\n"; } + if (countUnsupported) { + subWarnUnsupported << sUnsupported.str() << "\n" << space << ")\n"; + } + if (countSupported || countUnsupported) { + subCommon << space << "{\n"; + subCommon << double_space << "# match device function from the list, except those, which have a namespace prefix (aka somenamespace::umin(...));\n"; + subCommon << double_space << "# function with only global namespace qualifier '::' (aka ::umin(...)) should be treated as a device function (and warned as well as without such qualifier);\n"; + subCommon << double_space << "my $mt_namespace = m/(\\w+)::($func)\\s*\\(\\s*.*\\s*\\)/g;\n"; + subCommon << double_space << "my $mt = m/($func)\\s*\\(\\s*.*\\s*\\)/g;\n"; + subCommon << double_space << "if ($mt && !$mt_namespace) {\n"; + subCommon << triple_space << "$m += $mt;\n"; + } + if (countSupported) { + subCountSupported << subCommon.str(); + } + if (countUnsupported) { + subWarnUnsupported << subCommon.str(); + subWarnUnsupported << triple_space << "print STDERR \" warning: $fileName:$line_num: unsupported device function \\\"$func\\\": $_\\n\";\n"; + } + if (countSupported || countUnsupported) { + sCommon = double_space + "}\n" + space + "}\n" + space + "return $m;\n"; + } + if (countSupported) { + subCountSupported << sCommon; + } + if (countUnsupported) { + subWarnUnsupported << sCommon; + } + subCountSupported << "}\n"; + subWarnUnsupported << "}\n"; + *perlStreamPtr.get() << subCountSupported.str(); + *perlStreamPtr.get() << subWarnUnsupported.str(); } bool generate(bool Generate) { @@ -125,7 +157,7 @@ namespace perl { } } } - generateUnsupportedDeviceFunctions(perlStreamPtr); + generateDeviceFunctions(perlStreamPtr); perlStreamPtr.get()->flush(); bool ret = true; EC = sys::fs::copy_file(tmpFile, dstPerlMap); diff --git a/hipamd/hipify-clang/src/HipifyAction.cpp b/hipamd/hipify-clang/src/HipifyAction.cpp index 80d80b5f2c..e52c4cd2e9 100644 --- a/hipamd/hipify-clang/src/HipifyAction.cpp +++ b/hipamd/hipify-clang/src/HipifyAction.cpp @@ -83,7 +83,7 @@ void HipifyAction::RewriteToken(const clang::Token& t) { void HipifyAction::FindAndReplace(llvm::StringRef name, clang::SourceLocation sl, - const std::map& repMap) { + const std::map& repMap, bool bReplace) { const auto found = repMap.find(name); if (found == repMap.end()) { // So it's an identifier, but not CUDA? Boring. @@ -100,6 +100,9 @@ void HipifyAction::FindAndReplace(llvm::StringRef name, DE.Report(sl, ID) << sWarn; return; } + if (!bReplace) { + return; + } StringRef repName = Statistics::isToRoc(found->second) ? found->second.rocName : found->second.hipName; clang::SourceManager& SM = getCompilerInstance().getSourceManager(); ct::Replacement Rep(SM, sl, name.size(), repName.str()); @@ -392,7 +395,7 @@ bool HipifyAction::cudaSharedIncompleteArrayVar(const clang::ast_matchers::Match bool HipifyAction::cudaDeviceFuncCall(const clang::ast_matchers::MatchFinder::MatchResult& Result) { if (const clang::CallExpr *call = Result.Nodes.getNodeAs("cudaDeviceFuncCall")) { const clang::FunctionDecl *funcDcl = call->getDirectCallee(); - FindAndReplace(funcDcl->getDeclName().getAsString(), llcompat::getBeginLoc(call), CUDA_DEVICE_FUNC_MAP); + FindAndReplace(funcDcl->getDeclName().getAsString(), llcompat::getBeginLoc(call), CUDA_DEVICE_FUNC_MAP, false); } return true; } diff --git a/hipamd/hipify-clang/src/HipifyAction.h b/hipamd/hipify-clang/src/HipifyAction.h index d38eddca0a..208e6fb0b2 100644 --- a/hipamd/hipify-clang/src/HipifyAction.h +++ b/hipamd/hipify-clang/src/HipifyAction.h @@ -100,5 +100,5 @@ protected: void run(const clang::ast_matchers::MatchFinder::MatchResult& Result) override; std::unique_ptr CreateASTConsumer(clang::CompilerInstance &CI, llvm::StringRef InFile) override; bool Exclude(const hipCounter & hipToken); - void FindAndReplace(llvm::StringRef name, clang::SourceLocation sl, const std::map& repMap); + void FindAndReplace(llvm::StringRef name, clang::SourceLocation sl, const std::map& repMap, bool bReplace = true); };