From 9c4ec3eca2e6ac62e26e9cd94d20bf146897ced4 Mon Sep 17 00:00:00 2001 From: Evgeny Mankov Date: Sun, 15 Sep 2019 21:13:56 +0300 Subject: [PATCH] [HIPIFY] Scripting related refactoring + Move generating hipify-perl and hipify-python into separate namespaces and files + Move getAbsoluteFilePath and getAbsoluteDirectoryPath to StringUtils [ROCm/clr commit: db2fee682b84c4daeb96bb86bcb4bfa7f9ba8274] --- .../hipamd/hipify-clang/src/CUDA2HIP_Perl.cpp | 139 +++++++++++ .../hipify-clang/src/CUDA2HIP_Python.cpp | 103 ++++++++ .../hipify-clang/src/CUDA2HIP_Scripting.h | 33 +++ .../hipamd/hipify-clang/src/StringUtils.cpp | 60 +++++ .../clr/hipamd/hipify-clang/src/StringUtils.h | 12 + projects/clr/hipamd/hipify-clang/src/main.cpp | 227 +----------------- 6 files changed, 352 insertions(+), 222 deletions(-) create mode 100644 projects/clr/hipamd/hipify-clang/src/CUDA2HIP_Perl.cpp create mode 100644 projects/clr/hipamd/hipify-clang/src/CUDA2HIP_Python.cpp create mode 100644 projects/clr/hipamd/hipify-clang/src/CUDA2HIP_Scripting.h diff --git a/projects/clr/hipamd/hipify-clang/src/CUDA2HIP_Perl.cpp b/projects/clr/hipamd/hipify-clang/src/CUDA2HIP_Perl.cpp new file mode 100644 index 0000000000..e40b0df379 --- /dev/null +++ b/projects/clr/hipamd/hipify-clang/src/CUDA2HIP_Perl.cpp @@ -0,0 +1,139 @@ +/* +Copyright (c) 2015 - present Advanced Micro Devices, Inc. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#include +#include +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/Support/Path.h" +#include "CUDA2HIP.h" +#include "CUDA2HIP_Scripting.h" +#include "ArgParse.h" +#include "StringUtils.h" +#include "LLVMCompat.h" +#include "Statistics.h" + +using namespace llvm; + +namespace perl { + + const std::string space = " "; + const std::string double_space = space + space; + const std::string triple_space = double_space + space; + + void generateUnsupportedDeviceFunctions(std::unique_ptr& perlStreamPtr) { + unsigned int num = 0; + std::stringstream sUnsupported; + for (auto& ma : CUDA_DEVICE_FUNC_MAP) { + if (Statistics::isUnsupported(ma.second)) { + sUnsupported << (num ? ",\n" : "") << double_space << "\"" << ma.first.str() << "\""; + num++; + } + } + 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 math at the beginning of a word, but not if it already has a namespace qualifier ('::') :\n"; + *perlStreamPtr.get() << double_space << "my $mt = m/[:]?[:]?\\b($func)\\b(\\w*\\()/g;\n"; + *perlStreamPtr.get() << double_space << "if ($mt) {\n"; + *perlStreamPtr.get() << triple_space << "$m += $mt;\n"; + *perlStreamPtr.get() << triple_space << "print STDERR \" warning: $fileName:#$line_num : unsupported device function : $_\\n\";\n"; + *perlStreamPtr.get() << double_space << "}\n"; + *perlStreamPtr.get() << space << "}\n"; + *perlStreamPtr.get() << space << "return $m;\n"; + *perlStreamPtr.get() << "}\n"; + } + } + + bool generate(bool Generate) { + if (!Generate) { + return true; + } + std::string dstPerlMap = OutputPerlMapFilename, dstPerlMapDir = OutputPerlMapDir; + if (dstPerlMap.empty()) { + dstPerlMap = "hipify-perl-map"; + } + std::error_code EC; + if (!dstPerlMapDir.empty()) { + std::string sOutputPerlMapDirAbsPath = getAbsoluteDirectoryPath(OutputPerlMapDir, EC, "output hipify-perl map"); + if (EC) { + return false; + } + dstPerlMap = sOutputPerlMapDirAbsPath + "/" + dstPerlMap; + } + SmallString<128> tmpFile; + StringRef ext = "hipify-tmp"; + EC = sys::fs::createTemporaryFile(dstPerlMap, ext, tmpFile); + if (EC) { + llvm::errs() << "\n" << sHipify << sError << EC.message() << ": " << tmpFile << "\n"; + return false; + } + std::unique_ptr perlStreamPtr = std::unique_ptr(new std::ofstream(tmpFile.c_str(), std::ios_base::trunc)); + std::string sConv = "my $conversions = "; + *perlStreamPtr.get() << "@statNames = ("; + for (int i = 0; i < NUM_CONV_TYPES - 1; i++) { + *perlStreamPtr.get() << "\"" << counterNames[i] << "\", "; + sConv += "$ft{'" + std::string(counterNames[i]) + "'} + "; + } + *perlStreamPtr.get() << "\"" << counterNames[NUM_CONV_TYPES - 1] << "\");\n\n"; + *perlStreamPtr.get() << sConv << "$ft{'" << counterNames[NUM_CONV_TYPES - 1] << "'};\n\n"; + for (int i = 0; i < NUM_CONV_TYPES; i++) { + if (i == CONV_INCLUDE_CUDA_MAIN_H || i == CONV_INCLUDE) { + for (auto& ma : CUDA_INCLUDE_MAP) { + if (Statistics::isUnsupported(ma.second)) { + continue; + } + if (i == ma.second.type) { + std::string sCUDA = ma.first.str(); + std::string sHIP = ma.second.hipName.str(); + sCUDA = std::regex_replace(sCUDA, std::regex("/"), "\\/"); + sHIP = std::regex_replace(sHIP, std::regex("/"), "\\/"); + *perlStreamPtr.get() << "$ft{'" << counterNames[ma.second.type] << "'} += s/\\b" << sCUDA << "\\b/" << sHIP << "/g;\n"; + } + } + } + else { + for (auto& ma : CUDA_RENAMES_MAP()) { + if (Statistics::isUnsupported(ma.second)) { + continue; + } + if (i == ma.second.type) { + *perlStreamPtr.get() << "$ft{'" << counterNames[ma.second.type] << "'} += s/\\b" << ma.first.str() << "\\b/" << ma.second.hipName.str() << "/g;\n"; + } + } + } + } + generateUnsupportedDeviceFunctions(perlStreamPtr); + perlStreamPtr.get()->flush(); + bool ret = true; + EC = sys::fs::copy_file(tmpFile, dstPerlMap); + if (EC) { + llvm::errs() << "\n" << sHipify << sError << EC.message() << ": while copying " << tmpFile << " to " << dstPerlMap << "\n"; + ret = false; + } + if (!SaveTemps) { + sys::fs::remove(tmpFile); + } + return ret; + } +} diff --git a/projects/clr/hipamd/hipify-clang/src/CUDA2HIP_Python.cpp b/projects/clr/hipamd/hipify-clang/src/CUDA2HIP_Python.cpp new file mode 100644 index 0000000000..5ffd84e0b0 --- /dev/null +++ b/projects/clr/hipamd/hipify-clang/src/CUDA2HIP_Python.cpp @@ -0,0 +1,103 @@ +/* +Copyright (c) 2015 - present Advanced Micro Devices, Inc. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#include +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/Support/Path.h" +#include "CUDA2HIP.h" +#include "CUDA2HIP_Scripting.h" +#include "ArgParse.h" +#include "StringUtils.h" +#include "LLVMCompat.h" +#include "Statistics.h" + +using namespace llvm; + +namespace python { + + bool generate(bool Generate) { + if (!Generate) { + return true; + } + std::string dstPythonMap = "cuda_to_hip_mappings.py", dstPythonMapDir = OutputPythonMapDir; + std::error_code EC; + if (!dstPythonMapDir.empty()) { + std::string sOutputPythonMapDirAbsPath = getAbsoluteDirectoryPath(OutputPythonMapDir, EC, "output hipify-python map"); + if (EC) { + return false; + } + dstPythonMap = sOutputPythonMapDirAbsPath + "/" + dstPythonMap; + } + SmallString<128> tmpFile; + StringRef ext = "hipify-tmp"; + EC = sys::fs::createTemporaryFile(dstPythonMap, ext, tmpFile); + if (EC) { + llvm::errs() << "\n" << sHipify << sError << EC.message() << ": " << tmpFile << "\n"; + return false; + } + std::unique_ptr pythonStreamPtr = std::unique_ptr(new std::ofstream(tmpFile.c_str(), std::ios_base::trunc)); + *pythonStreamPtr.get() << "import collections\n\n"; + *pythonStreamPtr.get() << "from pyHIPIFY.constants import *\n\n"; + *pythonStreamPtr.get() << "CUDA_RENAMES_MAP = collections.OrderedDict([\n"; + const std::string sHIP_UNS = ", HIP_UNSUPPORTED"; + for (int i = 0; i < NUM_CONV_TYPES; i++) { + if (i == CONV_INCLUDE_CUDA_MAIN_H || i == CONV_INCLUDE) { + for (auto& ma : CUDA_INCLUDE_MAP) { + if (i == ma.second.type) { + std::string sUnsupported; + if (Statistics::isUnsupported(ma.second)) { + sUnsupported = sHIP_UNS; + } + StringRef repName = Statistics::isToRoc(ma.second) ? ma.second.rocName : ma.second.hipName; + *pythonStreamPtr.get() << " (\"" << ma.first.str() << "\", (\"" << repName.str() << "\", " << counterTypes[i] << ", " << apiTypes[ma.second.apiType] << sUnsupported << ")),\n"; + } + } + } + else { + for (auto& ma : CUDA_RENAMES_MAP()) { + if (i == ma.second.type) { + std::string sUnsupported; + if (Statistics::isUnsupported(ma.second)) { + sUnsupported = sHIP_UNS; + } + StringRef repName = Statistics::isToRoc(ma.second) ? ma.second.rocName : ma.second.hipName; + *pythonStreamPtr.get() << " (\"" << ma.first.str() << "\", (\"" << repName.str() << "\", " << counterTypes[i] << ", " << apiTypes[ma.second.apiType] << sUnsupported << ")),\n"; + } + } + } + } + *pythonStreamPtr.get() << "])\n\n"; + *pythonStreamPtr.get() << "CUDA_TO_HIP_MAPPINGS = [CUDA_RENAMES_MAP, C10_MAPPINGS, PYTORCH_SPECIFIC_MAPPINGS]\n"; + pythonStreamPtr.get()->flush(); + bool ret = true; + EC = sys::fs::copy_file(tmpFile, dstPythonMap); + if (EC) { + llvm::errs() << "\n" << sHipify << sError << EC.message() << ": while copying " << tmpFile << " to " << dstPythonMap << "\n"; + ret = false; + } + if (!SaveTemps) { + sys::fs::remove(tmpFile); + } + return true; + } +} diff --git a/projects/clr/hipamd/hipify-clang/src/CUDA2HIP_Scripting.h b/projects/clr/hipamd/hipify-clang/src/CUDA2HIP_Scripting.h new file mode 100644 index 0000000000..c585a47d47 --- /dev/null +++ b/projects/clr/hipamd/hipify-clang/src/CUDA2HIP_Scripting.h @@ -0,0 +1,33 @@ +/* +Copyright (c) 2015 - present Advanced Micro Devices, Inc. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#pragma once + +namespace perl { + + bool generate(bool Generate = true); +} + +namespace python { + + bool generate(bool Generate = true); +} diff --git a/projects/clr/hipamd/hipify-clang/src/StringUtils.cpp b/projects/clr/hipamd/hipify-clang/src/StringUtils.cpp index a8edf3661f..78d0f8113e 100644 --- a/projects/clr/hipamd/hipify-clang/src/StringUtils.cpp +++ b/projects/clr/hipamd/hipify-clang/src/StringUtils.cpp @@ -21,6 +21,10 @@ THE SOFTWARE. */ #include "StringUtils.h" +#include "LLVMCompat.h" +#include "llvm/ADT/SmallString.h" + +using namespace llvm; llvm::StringRef unquoteStr(llvm::StringRef s) { if (s.size() > 1 && s.front() == '"' && s.back() == '"') { @@ -35,3 +39,59 @@ void removePrefixIfPresent(std::string &s, const std::string& prefix) { } s.erase(0, prefix.size()); } + +std::string getAbsoluteFilePath(const std::string& sFile, std::error_code& EC) { + if (sFile.empty()) { + return sFile; + } + if (!sys::fs::exists(sFile)) { + llvm::errs() << "\n" << sHipify << sError << "source file: " << sFile << " doesn't exist\n"; + EC = std::error_code(static_cast(std::errc::no_such_file_or_directory), std::generic_category()); + return ""; + } + SmallString<256> fileAbsPath; + EC = llcompat::real_path(sFile, fileAbsPath, true); + if (EC) { + llvm::errs() << "\n" << sHipify << sError << EC.message() << ": source file: " << sFile << "\n"; + return ""; + } + EC = std::error_code(); + return fileAbsPath.c_str(); +} + +std::string getAbsoluteDirectoryPath(const std::string& sDir, std::error_code& EC, + const std::string& sDirType, bool bCreateDir) { + if (sDir.empty()) { + return sDir; + } + EC = std::error_code(); + SmallString<256> dirAbsPath; + if (sys::fs::exists(sDir)) { + if (sys::fs::is_regular_file(sDir)) { + llvm::errs() << "\n" << sHipify << sError << sDir << " is not a directory\n"; + EC = std::error_code(static_cast(std::errc::not_a_directory), std::generic_category()); + return ""; + } + } + else { + if (bCreateDir) { + EC = sys::fs::create_directory(sDir); + if (EC) { + llvm::errs() << "\n" << sHipify << sError << EC.message() << ": " << sDirType << " directory: " << sDir << "\n"; + return ""; + } + } + else { + llvm::errs() << "\n" << sHipify << sError << sDirType << " directory: " << sDir << " doesn't exist\n"; + EC = std::error_code(static_cast(std::errc::no_such_file_or_directory), std::generic_category()); + return ""; + } + } + EC = llcompat::real_path(sDir, dirAbsPath, true); + if (EC) { + llvm::errs() << "\n" << sHipify << sError << EC.message() << ": " << sDirType << " directory: " << sDir << "\n"; + return ""; + } + return dirAbsPath.c_str(); +} + diff --git a/projects/clr/hipamd/hipify-clang/src/StringUtils.h b/projects/clr/hipamd/hipify-clang/src/StringUtils.h index b18c864244..39ce726d1b 100644 --- a/projects/clr/hipamd/hipify-clang/src/StringUtils.h +++ b/projects/clr/hipamd/hipify-clang/src/StringUtils.h @@ -34,3 +34,15 @@ llvm::StringRef unquoteStr(llvm::StringRef s); * If `s` starts with `prefix`, remove it. Otherwise, does nothing. */ void removePrefixIfPresent(std::string &s, const std::string& prefix); + +/** + * Returns Absolute File Path based on filename, otherwise - error. + */ +std::string getAbsoluteFilePath(const std::string& sFile, std::error_code& EC); + +/** + * Returns Absolute Directory Path based on directory name, otherwise - error; + * by default the directory is temporary and created. + */ +std::string getAbsoluteDirectoryPath(const std::string& sDir, std::error_code& EC, + const std::string& sDirType = "temporary", bool bCreateDir = true); diff --git a/projects/clr/hipamd/hipify-clang/src/main.cpp b/projects/clr/hipamd/hipify-clang/src/main.cpp index 68dddb5025..4b426b41f7 100644 --- a/projects/clr/hipamd/hipify-clang/src/main.cpp +++ b/projects/clr/hipamd/hipify-clang/src/main.cpp @@ -27,235 +27,18 @@ THE SOFTWARE. #include #include #include -#include #include "CUDA2HIP.h" +#include "CUDA2HIP_Scripting.h" #include "LLVMCompat.h" #include "HipifyAction.h" #include "ArgParse.h" +#include "StringUtils.h" #include "llvm/Support/Debug.h" -#include "llvm/Support/Path.h" -#define DEBUG_TYPE "cuda2hip" +constexpr auto DEBUG_TYPE = "cuda2hip"; namespace ct = clang::tooling; -std::string getAbsoluteFilePath(const std::string& sFile, std::error_code& EC) { - if (sFile.empty()) { - return sFile; - } - if (!sys::fs::exists(sFile)) { - llvm::errs() << "\n" << sHipify << sError << "source file: " << sFile << " doesn't exist\n"; - EC = std::error_code(static_cast(std::errc::no_such_file_or_directory), std::generic_category()); - return ""; - } - SmallString<256> fileAbsPath; - EC = llcompat::real_path(sFile, fileAbsPath, true); - if (EC) { - llvm::errs() << "\n" << sHipify << sError << EC.message() << ": source file: " << sFile << "\n"; - return ""; - } - EC = std::error_code(); - return fileAbsPath.c_str(); -} - -std::string getAbsoluteDirectoryPath(const std::string& sDir, std::error_code& EC, - const std::string& sDirType = "temporary", - bool bCreateDir = true) { - if (sDir.empty()) { - return sDir; - } - EC = std::error_code(); - SmallString<256> dirAbsPath; - if (sys::fs::exists(sDir)) { - if (sys::fs::is_regular_file(sDir)) { - llvm::errs() << "\n" << sHipify << sError << sDir << " is not a directory\n"; - EC = std::error_code(static_cast(std::errc::not_a_directory), std::generic_category()); - return ""; - } - } else { - if (bCreateDir) { - EC = sys::fs::create_directory(sDir); - if (EC) { - llvm::errs() << "\n" << sHipify << sError << EC.message() << ": " << sDirType << " directory: " << sDir << "\n"; - return ""; - } - } else { - llvm::errs() << "\n" << sHipify << sError << sDirType << " directory: " << sDir << " doesn't exist\n"; - EC = std::error_code(static_cast(std::errc::no_such_file_or_directory), std::generic_category()); - return ""; - } - } - EC = llcompat::real_path(sDir, dirAbsPath, true); - if (EC) { - llvm::errs() << "\n" << sHipify << sError << EC.message() << ": " << sDirType << " directory: " << sDir << "\n"; - return ""; - } - return dirAbsPath.c_str(); -} - -bool generatePerl(bool Generate = true) { - if (!Generate) { - return true; - } - std::string dstPerlMap = OutputPerlMapFilename, dstPerlMapDir = OutputPerlMapDir; - if (dstPerlMap.empty()) { - dstPerlMap = "hipify-perl-map"; - } - std::error_code EC; - if (!dstPerlMapDir.empty()) { - std::string sOutputPerlMapDirAbsPath = getAbsoluteDirectoryPath(OutputPerlMapDir, EC, "output hipify-perl map"); - if (EC) { - return false; - } - dstPerlMap = sOutputPerlMapDirAbsPath + "/" + dstPerlMap; - } - SmallString<128> tmpFile; - StringRef ext = "hipify-tmp"; - EC = sys::fs::createTemporaryFile(dstPerlMap, ext, tmpFile); - if (EC) { - llvm::errs() << "\n" << sHipify << sError << EC.message() << ": " << tmpFile << "\n"; - return false; - } - std::unique_ptr perlStreamPtr = std::unique_ptr(new std::ofstream(tmpFile.c_str(), std::ios_base::trunc)); - std::string sConv = "my $conversions = "; - *perlStreamPtr.get() << "@statNames = ("; - for (int i = 0; i < NUM_CONV_TYPES - 1; i++) { - *perlStreamPtr.get() << "\"" << counterNames[i] << "\", "; - sConv += "$ft{'" + std::string(counterNames[i]) + "'} + "; - } - *perlStreamPtr.get() << "\"" << counterNames[NUM_CONV_TYPES - 1] << "\");\n\n"; - *perlStreamPtr.get() << sConv << "$ft{'" << counterNames[NUM_CONV_TYPES - 1] << "'};\n\n"; - for (int i = 0; i < NUM_CONV_TYPES; i++) { - if (i == CONV_INCLUDE_CUDA_MAIN_H || i == CONV_INCLUDE) { - for (auto& ma : CUDA_INCLUDE_MAP) { - if (Statistics::isUnsupported(ma.second)) { - continue; - } - if (i == ma.second.type) { - std::string sCUDA = ma.first.str(); - std::string sHIP = ma.second.hipName.str(); - sCUDA = std::regex_replace(sCUDA, std::regex("/"), "\\/"); - sHIP = std::regex_replace(sHIP, std::regex("/"), "\\/"); - *perlStreamPtr.get() << "$ft{'" << counterNames[ma.second.type] << "'} += s/\\b" << sCUDA << "\\b/" << sHIP << "/g;\n"; - } - } - } else { - for (auto& ma : CUDA_RENAMES_MAP()) { - if (Statistics::isUnsupported(ma.second)) { - continue; - } - if (i == ma.second.type) { - *perlStreamPtr.get() << "$ft{'" << counterNames[ma.second.type] << "'} += s/\\b" << ma.first.str() << "\\b/" << ma.second.hipName.str() << "/g;\n"; - } - } - } - } - - unsigned int num = 0; - std::stringstream sUnsupported; - const std::string space = " "; - const std::string double_space = space + space; - const std::string triple_space = double_space + space; - for (auto& ma : CUDA_DEVICE_FUNC_MAP) { - if (Statistics::isUnsupported(ma.second)) { - sUnsupported << (num ? ",\n" : "") << double_space << "\"" << ma.first.str() << "\""; - num++; - } - } - 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 math at the beginning of a word, but not if it already has a namespace qualifier ('::') :\n"; - *perlStreamPtr.get() << double_space << "my $mt = m/[:]?[:]?\\b($func)\\b(\\w*\\()/g;\n"; - *perlStreamPtr.get() << double_space << "if ($mt) {\n"; - *perlStreamPtr.get() << triple_space << "$m += $mt;\n"; - *perlStreamPtr.get() << triple_space << "print STDERR \" warning: $fileName:#$line_num : unsupported device function : $_\\n\";\n"; - *perlStreamPtr.get() << double_space << "}\n"; - *perlStreamPtr.get() << space << "}\n"; - *perlStreamPtr.get() << space << "return $m;\n"; - *perlStreamPtr.get() << "}\n"; - } - - perlStreamPtr.get()->flush(); - bool ret = true; - EC = sys::fs::copy_file(tmpFile, dstPerlMap); - if (EC) { - llvm::errs() << "\n" << sHipify << sError << EC.message() << ": while copying " << tmpFile << " to " << dstPerlMap << "\n"; - ret = false; - } - if (!SaveTemps) { - sys::fs::remove(tmpFile); - } - return ret; -} - -bool generatePython(bool Generate = true) { - if (!Generate) { - return true; - } - std::string dstPythonMap = "cuda_to_hip_mappings.py", dstPythonMapDir = OutputPythonMapDir; - std::error_code EC; - if (!dstPythonMapDir.empty()) { - std::string sOutputPythonMapDirAbsPath = getAbsoluteDirectoryPath(OutputPythonMapDir, EC, "output hipify-python map"); - if (EC) { - return false; - } - dstPythonMap = sOutputPythonMapDirAbsPath + "/" + dstPythonMap; - } - SmallString<128> tmpFile; - StringRef ext = "hipify-tmp"; - EC = sys::fs::createTemporaryFile(dstPythonMap, ext, tmpFile); - if (EC) { - llvm::errs() << "\n" << sHipify << sError << EC.message() << ": " << tmpFile << "\n"; - return false; - } - std::unique_ptr pythonStreamPtr = std::unique_ptr(new std::ofstream(tmpFile.c_str(), std::ios_base::trunc)); - *pythonStreamPtr.get() << "import collections\n\n"; - *pythonStreamPtr.get() << "from pyHIPIFY.constants import *\n\n"; - *pythonStreamPtr.get() << "CUDA_RENAMES_MAP = collections.OrderedDict([\n"; - const std::string sHIP_UNS = ", HIP_UNSUPPORTED"; - for (int i = 0; i < NUM_CONV_TYPES; i++) { - if (i == CONV_INCLUDE_CUDA_MAIN_H || i == CONV_INCLUDE) { - for (auto& ma : CUDA_INCLUDE_MAP) { - if (i == ma.second.type) { - std::string sUnsupported; - if (Statistics::isUnsupported(ma.second)) { - sUnsupported = sHIP_UNS; - } - StringRef repName = Statistics::isToRoc(ma.second) ? ma.second.rocName : ma.second.hipName; - *pythonStreamPtr.get() << " (\"" << ma.first.str() << "\", (\"" << repName.str() << "\", " << counterTypes[i] << ", " << apiTypes[ma.second.apiType] << sUnsupported << ")),\n"; - } - } - } - else { - for (auto& ma : CUDA_RENAMES_MAP()) { - if (i == ma.second.type) { - std::string sUnsupported; - if (Statistics::isUnsupported(ma.second)) { - sUnsupported = sHIP_UNS; - } - StringRef repName = Statistics::isToRoc(ma.second) ? ma.second.rocName : ma.second.hipName; - *pythonStreamPtr.get() << " (\"" << ma.first.str() << "\", (\"" << repName.str() << "\", " << counterTypes[i] << ", " << apiTypes[ma.second.apiType] << sUnsupported << ")),\n"; - } - } - } - } - *pythonStreamPtr.get() << "])\n\n"; - *pythonStreamPtr.get() << "CUDA_TO_HIP_MAPPINGS = [CUDA_RENAMES_MAP, C10_MAPPINGS, PYTORCH_SPECIFIC_MAPPINGS]\n"; - pythonStreamPtr.get()->flush(); - bool ret = true; - EC = sys::fs::copy_file(tmpFile, dstPythonMap); - if (EC) { - llvm::errs() << "\n" << sHipify << sError << EC.message() << ": while copying " << tmpFile << " to " << dstPythonMap << "\n"; - ret = false; - } - if (!SaveTemps) { - sys::fs::remove(tmpFile); - } - return true; -} - int main(int argc, const char **argv) { std::vector new_argv(argv, argv + argc); if (std::find(new_argv.begin(), new_argv.end(), std::string("--")) == new_argv.end()) { @@ -274,13 +57,13 @@ int main(int argc, const char **argv) { llvm::errs() << "\n" << sHipify << sError << "Must specify at least 1 positional argument for source file" << "\n"; return 1; } - if (!generatePerl(GeneratePerl)) { + if (!perl::generate(GeneratePerl)) { llvm::errs() << "\n" << sHipify << sError << "hipify-perl generating failed" << "\n"; return 1; } bool bToRoc = TranslateToRoc; TranslateToRoc = true; - bool bToPython = generatePython(GeneratePython); + bool bToPython = python::generate(GeneratePython); TranslateToRoc = bToRoc; if (!bToPython) { llvm::errs() << "\n" << sHipify << sError << "hipify-python generating failed" << "\n";