From 818c787e0079f67b856e9c7998182df2cfaa1621 Mon Sep 17 00:00:00 2001
From: foreman
Date: Thu, 26 Sep 2019 17:47:32 -0400
Subject: [PATCH] P4 to Git Change 2005049 by skudchad@skudchad_rocm on
2019/09/26 17:24:59
SWDEV-199293 - HIP_RTC inprocess implementation.
ReviewBoardURL = http://ocltc.amd.com/reviews/r/18014/diff/
Affected files ...
... //depot/stg/opencl/drivers/opencl/api/hip/hip_internal.hpp#41 edit
... //depot/stg/opencl/drivers/opencl/api/hip/hip_rtc.cpp#5 edit
... //depot/stg/opencl/drivers/opencl/api/hip/hiprtc_internal.hpp#1 add
... //depot/stg/opencl/drivers/opencl/runtime/platform/program.hpp#49 edit
[ROCm/clr commit: 129333387ad368a87f984628765f043a351b57a1]
---
projects/clr/hipamd/api/hip/hip_internal.hpp | 10 +-
projects/clr/hipamd/api/hip/hip_rtc.cpp | 363 ++++++++----------
.../clr/hipamd/api/hip/hiprtc_internal.hpp | 44 +++
3 files changed, 219 insertions(+), 198 deletions(-)
create mode 100644 projects/clr/hipamd/api/hip/hiprtc_internal.hpp
diff --git a/projects/clr/hipamd/api/hip/hip_internal.hpp b/projects/clr/hipamd/api/hip/hip_internal.hpp
index 7b0ff09ed9..1b422afd3d 100644
--- a/projects/clr/hipamd/api/hip/hip_internal.hpp
+++ b/projects/clr/hipamd/api/hip/hip_internal.hpp
@@ -56,6 +56,11 @@ typedef struct ihipIpcMemHandle_st {
} \
HIP_INIT();
+#define HIP_RETURN(ret) \
+ hip::g_lastError = ret; \
+ LogPrintfInfo("[%zx] %s: Returned %s", std::this_thread::get_id(), __func__, hipGetErrorName(hip::g_lastError)); \
+ return hip::g_lastError;
+
namespace hc {
class accelerator;
class accelerator_view;
@@ -179,11 +184,6 @@ extern amd::Memory* getMemoryObject(const void* ptr, size_t& offset);
extern bool CL_CALLBACK getSvarInfo(cl_program program, std::string var_name, void** var_addr,
size_t* var_size);
-#define HIP_RETURN(ret) \
- hip::g_lastError = ret; \
- LogPrintfInfo("[%zx] %s: Returned %s", std::this_thread::get_id(), __func__, hipGetErrorName(hip::g_lastError)); \
- return hip::g_lastError; \
-
inline std::ostream& operator<<(std::ostream& os, const dim3& s) {
os << '{';
os << s.x;
diff --git a/projects/clr/hipamd/api/hip/hip_rtc.cpp b/projects/clr/hipamd/api/hip/hip_rtc.cpp
index 8446b5112b..9b378cd637 100644
--- a/projects/clr/hipamd/api/hip/hip_rtc.cpp
+++ b/projects/clr/hipamd/api/hip/hip_rtc.cpp
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2015 - present Advanced Micro Devices, Inc. All rights reserved.
+Copyright (c) 2018 - 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
@@ -21,9 +21,73 @@ THE SOFTWARE.
*/
#include
-#include "cl_common.hpp"
+#include "hiprtc_internal.hpp"
#include
-#include
+#include "platform/program.hpp"
+
+namespace hiprtc {
+thread_local hiprtcResult g_lastRtcError = HIPRTC_SUCCESS;
+}
+
+class ProgramState {
+ amd::Monitor lock_;
+private:
+ static ProgramState* programState_;
+
+ ProgramState() : lock_("Guards program state") {}
+ ~ProgramState() {}
+
+ std::unordered_map, std::vector>> progHeaders_;
+ std::vector nameExpresssion_;
+public:
+ static ProgramState& instance();
+ void createProgramHeaders(amd::Program* program, int numHeaders,
+ const char** headers, const char** headerNames);
+ void getProgramHeaders(amd::Program* program, int* numHeaders, char** headers, char ** headerNames);
+ uint32_t addNameExpression(const char* name_expression);
+};
+
+ProgramState* ProgramState::programState_ = nullptr;
+
+ProgramState& ProgramState::instance() {
+ if (programState_ == nullptr) {
+ programState_ = new ProgramState;
+ }
+ return *programState_;
+}
+
+void ProgramState::createProgramHeaders(amd::Program* program, int numHeaders,
+ const char** headers, const char** headerNames) {
+ amd::ScopedLock lock(lock_);
+ std::vector vHeaderNames;
+ std::vector vHeaders;
+ for (auto i = 0; i != numHeaders; ++i) {
+ vHeaders.emplace_back(headers[i]);
+ vHeaderNames.emplace_back(headerNames[i]);
+ progHeaders_[program] = std::make_pair(std::move(vHeaders), std::move(vHeaderNames));
+ }
+}
+
+void ProgramState::getProgramHeaders(amd::Program* program, int* numHeaders,
+ char** headers, char ** headerNames) {
+ amd::ScopedLock lock(lock_);
+
+ const auto it = progHeaders_.find(program);
+ if (it != progHeaders_.cend()) {
+ *numHeaders = it->second.first.size();
+ *headers = reinterpret_cast(it->second.first.data());
+ *headerNames = reinterpret_cast(it->second.second.data());
+ }
+}
+
+
+uint32_t ProgramState::addNameExpression(const char* name_expression) {
+ amd::ScopedLock lock(lock_);
+ nameExpresssion_.emplace_back(name_expression);
+ return nameExpresssion_.size();
+}
+
const char* hiprtcGetErrorString(hiprtcResult x) {
switch (x) {
@@ -56,238 +120,151 @@ const char* hiprtcGetErrorString(hiprtcResult x) {
};
}
-namespace hip_impl {
-inline std::string demangle(const char* x) {
- if (!x) {
- return {};
+hiprtcResult hiprtcCreateProgram(hiprtcProgram* prog, const char* src, const char* name,
+ int numHeaders, const char** headers, const char** headerNames) {
+ HIPRTC_INIT_API(prog, src, name, numHeaders, headers, headerNames);
+
+ if (prog == nullptr) {
+ HIPRTC_RETURN(HIPRTC_ERROR_INVALID_PROGRAM);
}
- return boost::core::demangle(x);
-}
-} // Namespace hip_impl
-
-struct _hiprtcProgram {
- static amd::Monitor lock_;
- static std::vector> programs_;
-
- std::vector> headers;
- std::vector> names;
- std::vector loweredNames;
- std::vector elf;
- std::string source;
- std::string name;
- std::string log;
- bool compiled;
-
- static _hiprtcProgram* build(std::string s, std::string n,
- std::vector> h) {
- std::unique_ptr<_hiprtcProgram> tmp{
- new _hiprtcProgram{std::move(h), {}, {}, {}, std::move(s), std::move(n), {}, false}};
-
- amd::ScopedLock lock(_hiprtcProgram::lock_);
-
- programs_.push_back(move(tmp));
-
- return programs_.back().get();
+ if (numHeaders < 0) {
+ HIPRTC_RETURN(HIPRTC_ERROR_INVALID_INPUT);
+ }
+ if (numHeaders && (headers == nullptr || headerNames == nullptr)) {
+ HIPRTC_RETURN(HIPRTC_ERROR_INVALID_INPUT);
}
- static hiprtcResult destroy(_hiprtcProgram* p) {
- amd::ScopedLock lock(_hiprtcProgram::lock_);
-
- const auto it{ std::find_if(programs_.cbegin(), programs_.cend(),
- [=](const std::unique_ptr<_hiprtcProgram>& x)
- { return x.get() == p; }) };
-
- if (it == programs_.cend()) {
- return HIPRTC_ERROR_INVALID_PROGRAM;
- }
-
- return HIPRTC_SUCCESS;
+ amd::Program* program = new amd::Program(*hip::getCurrentContext(), src, amd::Program::HIP);
+ if (program == NULL) {
+ HIPRTC_RETURN(HIPRTC_ERROR_INVALID_INPUT);
}
- static std::string handleMangledName(std::string name) {
- name = hip_impl::demangle(name.c_str());
-
- if (name.empty()) {
- return name;
- }
-
- if (name.find("void ") == 0) {
- name.erase(0, strlen("void "));
- }
-
- auto dx {name.find_first_of("(<")};
-
- if (dx == std::string::npos) {
- return name;
- }
-
- if (name[dx] == '<') {
- auto cnt{1u};
- do {
- ++dx;
- cnt += (name[dx] == '<') ? 1 : ((name[dx] == '>') ? -1 : 0);
- } while (cnt);
-
- name.erase(++dx);
- } else {
- name.erase(dx);
- }
-
- return name;
+ if (CL_SUCCESS != program->addDeviceProgram(*hip::getCurrentContext()->devices()[0])) {
+ program->release();
+ HIPRTC_RETURN(HIPRTC_ERROR_PROGRAM_CREATION_FAILURE);
}
- static bool isValid(_hiprtcProgram* p) {
- return std::find_if(programs_.cbegin(), programs_.cend(),
- [=](const std::unique_ptr<_hiprtcProgram>& x) {
- return x.get() == p; }) != programs_.cend();
- }
-};
+ ProgramState::instance().createProgramHeaders(program, numHeaders, headers, headerNames);
-// Init
-std::vector> _hiprtcProgram::programs_{};
-amd::Monitor _hiprtcProgram::lock_("hiprtcProgram lock");
+ *prog = reinterpret_cast(as_cl(program));
-inline bool isValidProgram(const hiprtcProgram p) {
- if (p == nullptr) {
- return false;
- }
-
- amd::ScopedLock lock(_hiprtcProgram::lock_);
-
- return _hiprtcProgram::isValid(p);
+ HIPRTC_RETURN(HIPRTC_SUCCESS);
}
-hiprtcResult hiprtcCreateProgram(hiprtcProgram* p, const char* src, const char* name, int n,
- const char** hdrs, const char** incs) {
- if (p == nullptr) {
- return HIPRTC_ERROR_INVALID_PROGRAM;
- }
- if (n < 0) {
- return HIPRTC_ERROR_INVALID_INPUT;
- }
- if (n && (hdrs == nullptr || incs == nullptr)) {
- return HIPRTC_ERROR_INVALID_INPUT;
+
+hiprtcResult hiprtcCompileProgram(hiprtcProgram prog, int numOptions, const char** options) {
+
+ // FIXME[skudchad] Add headers to amd::Program::build and device::Program::build,
+ // pass the saved from ProgramState to amd::Program::build
+ HIPRTC_INIT_API(prog, numOptions, options);
+
+ amd::Program* program = as_amd(reinterpret_cast(prog));
+
+ std::ostringstream ostrstr;
+ std::vector oarr(&options[0], &options[numOptions]);
+ std::copy(oarr.begin(), oarr.end(), std::ostream_iterator(ostrstr, " "));
+
+ std::vector devices{hip::getCurrentContext()->devices()[0]};
+ if (CL_SUCCESS != program->build(devices, ostrstr.str().c_str(), nullptr, nullptr)) {
+ HIPRTC_RETURN(HIPRTC_ERROR_COMPILATION);
}
- std::vector> h;
-
- for (auto i = 0; i != n; ++i) {
- h.emplace_back(incs[i], hdrs[i]);
- }
- *p = _hiprtcProgram::build(src, name ? name : "default_name", std::move(h));
-
- return HIPRTC_SUCCESS;
+ HIPRTC_RETURN(HIPRTC_SUCCESS);
}
-hiprtcResult hiprtcAddNameExpression(hiprtcProgram p, const char* n) {
- return HIPRTC_SUCCESS;
+hiprtcResult hiprtcAddNameExpression(hiprtcProgram prog, const char* name_expression) {
+ HIPRTC_INIT_API(prog, name_expression);
+
+ if (name_expression == nullptr) {
+ HIPRTC_RETURN(HIPRTC_ERROR_INVALID_INPUT);
+ }
+ amd::Program* program = as_amd(reinterpret_cast(prog));
+
+ uint32_t id = ProgramState::instance().addNameExpression(name_expression);
+
+ const auto var{"__hiprtc_" + std::to_string(id)};
+ const auto code{"\nextern \"C\" constexpr auto " + var + " = " + name_expression + ';'};
+
+ program->appendToSource(code.c_str());
+
+ HIPRTC_RETURN(HIPRTC_SUCCESS);
}
-hiprtcResult hiprtcCompileProgram(hiprtcProgram p, int n, const char** o) {
- return HIPRTC_SUCCESS;
+hiprtcResult hiprtcGetLoweredName(hiprtcProgram prog, const char* name_expression,
+ const char** loweredNames) {
+ HIPRTC_INIT_API(prog, name_expression, loweredNames);
+
+ if (name_expression == nullptr || loweredNames == nullptr) {
+ HIPRTC_RETURN(HIPRTC_ERROR_INVALID_INPUT);
+ }
+
+ HIPRTC_RETURN(HIPRTC_SUCCESS);
}
-hiprtcResult hiprtcDestroyProgram(hiprtcProgram* p) {
- if (p == nullptr) {
- return HIPRTC_SUCCESS;
+hiprtcResult hiprtcDestroyProgram(hiprtcProgram* prog) {
+ HIPRTC_INIT_API(prog);
+
+ if (prog == NULL) {
+ HIPRTC_RETURN(HIPRTC_ERROR_INVALID_INPUT);
}
- return _hiprtcProgram::destroy(*p);
+ amd::Program* program = as_amd(reinterpret_cast(prog));
+
+ program->release();
+
+ HIPRTC_RETURN(HIPRTC_SUCCESS);
}
-hiprtcResult hiprtcGetLoweredName(hiprtcProgram p, const char* n, const char** loweredNames) {
- if (n == nullptr || loweredNames == nullptr) {
- return HIPRTC_ERROR_INVALID_INPUT;
- }
+hiprtcResult hiprtcGetCode(hiprtcProgram prog, char* binaryMem) {
+ HIPRTC_INIT_API(prog, binaryMem);
- if (!isValidProgram(p)) {
- return HIPRTC_ERROR_INVALID_PROGRAM;
- }
- if (!p->compiled) {
- return HIPRTC_ERROR_INVALID_PROGRAM;
- }
+ amd::Program* program = as_amd(reinterpret_cast(prog));
+ const device::Program::binary_t& binary =
+ program->getDeviceProgram(*hip::getCurrentContext()->devices()[0])->binary();
- const auto it{ std::find_if(p->names.cbegin(), p->names.cend(),
- [=](const std::pair& x)
- { return x.first == n; })};
+ ::memcpy(binaryMem, binary.first, binary.second);
- if (it == p->names.cend()) {
- return HIPRTC_ERROR_NAME_EXPRESSION_NOT_VALID;
- }
-
- *loweredNames = p->loweredNames[distance(p->names.cbegin(), it)].c_str();
-
- return HIPRTC_SUCCESS;
+ HIPRTC_RETURN(HIPRTC_SUCCESS);
}
-hiprtcResult hiprtcGetProgramLog(hiprtcProgram p, char* log) {
- if (log == nullptr) {
- return HIPRTC_ERROR_INVALID_INPUT;
- }
+hiprtcResult hiprtcGetCodeSize(hiprtcProgram prog, size_t* binarySizeRet) {
- if (!isValidProgram(p)) {
- return HIPRTC_ERROR_INVALID_PROGRAM;
- }
+ HIPRTC_INIT_API(prog, binarySizeRet);
- if (!p->compiled) {
- return HIPRTC_ERROR_INVALID_PROGRAM;
- }
+ amd::Program* program = as_amd(reinterpret_cast(prog));
- log = std::copy_n(p->log.data(), p->log.size(), log);
- *log = '\0';
+ *binarySizeRet =
+ program->getDeviceProgram(*hip::getCurrentContext()->devices()[0])->binary().second;
- return HIPRTC_SUCCESS;
+ HIPRTC_RETURN(HIPRTC_SUCCESS);
}
-hiprtcResult hiprtcGetProgramLogSize(hiprtcProgram p, std::size_t* sz) {
- if (sz == nullptr) {
- return HIPRTC_ERROR_INVALID_INPUT;
- }
+hiprtcResult hiprtcGetProgramLog(hiprtcProgram prog, char* dst) {
- if (!isValidProgram(p)) {
- return HIPRTC_ERROR_INVALID_PROGRAM;
- }
+ HIPRTC_INIT_API(prog, dst);
+ amd::Program* program = as_amd(reinterpret_cast(prog));
+ const device::Program* devProgram =
+ program->getDeviceProgram(*hip::getCurrentContext()->devices()[0]);
- if (!p->compiled) {
- return HIPRTC_ERROR_INVALID_PROGRAM;
- }
+ auto log = program->programLog() + devProgram->buildLog().c_str();
- *sz = p->log.empty() ? 0 : p->log.size() + 1;
- return HIPRTC_SUCCESS;
+ log.copy(dst, log.size());
+ dst[log.size()] = '\0';
+
+ HIPRTC_RETURN(HIPRTC_SUCCESS);
}
-hiprtcResult hiprtcGetCode(hiprtcProgram p, char* c) {
- if (c == nullptr) {
- return HIPRTC_ERROR_INVALID_INPUT;
- }
+hiprtcResult hiprtcGetProgramLogSize(hiprtcProgram prog, size_t* logSizeRet) {
- if (!isValidProgram(p)) {
- return HIPRTC_ERROR_INVALID_PROGRAM;
- }
+ HIPRTC_INIT_API(prog, logSizeRet);
- if (!p->compiled) {
- return HIPRTC_ERROR_INVALID_PROGRAM;
- }
+ amd::Program* program = as_amd(reinterpret_cast(prog));
+ const device::Program* devProgram =
+ program->getDeviceProgram(*hip::getCurrentContext()->devices()[0]);
- std::copy_n(p->elf.data(), p->elf.size(), c);
+ auto log = program->programLog() + devProgram->buildLog().c_str();
- return HIPRTC_SUCCESS;
-}
+ *logSizeRet = log.size() + 1;
-hiprtcResult hiprtcGetCodeSize(hiprtcProgram p, std::size_t* sz) {
- if (sz == nullptr) {
- return HIPRTC_ERROR_INVALID_INPUT;
- }
-
- if (!isValidProgram(p)) {
- return HIPRTC_ERROR_INVALID_PROGRAM;
- }
-
- if (!p->compiled) {
- return HIPRTC_ERROR_INVALID_PROGRAM;
- }
-
- *sz = p->elf.size();
-
- return HIPRTC_SUCCESS;
+ HIPRTC_RETURN(HIPRTC_SUCCESS);
}
\ No newline at end of file
diff --git a/projects/clr/hipamd/api/hip/hiprtc_internal.hpp b/projects/clr/hipamd/api/hip/hiprtc_internal.hpp
new file mode 100644
index 0000000000..dc3371615c
--- /dev/null
+++ b/projects/clr/hipamd/api/hip/hiprtc_internal.hpp
@@ -0,0 +1,44 @@
+/*
+Copyright (c) 2019 - 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.
+*/
+
+#ifndef HIPRTC_SRC_HIP_INTERNAL_H
+#define HIPRTC_SRC_HIP_INTERNAL_H
+
+#include "hip_internal.hpp"
+
+// This macro should be called at the beginning of every HIP RTC API.
+#define HIPRTC_INIT_API(...) \
+ LogPrintfInfo("[%zx] %s ( %s )", std::this_thread::get_id(), __func__, ToString( __VA_ARGS__ ).c_str()); \
+ amd::Thread* thread = amd::Thread::current(); \
+ if (!CL_CHECK_THREAD(thread)) { \
+ HIPRTC_RETURN(HIPRTC_ERROR_INTERNAL_ERROR); \
+ } \
+ HIP_INIT();
+
+#define HIPRTC_RETURN(ret) \
+ hiprtc::g_lastRtcError = ret; \
+ LogPrintfInfo("[%zx] %s: Returned %s", std::this_thread::get_id(), __func__, \
+ hiprtcGetErrorString(hiprtc::g_lastRtcError)); \
+ return hiprtc::g_lastRtcError;
+
+
+#endif // HIPRTC_SRC_HIP_INTERNAL_H