diff --git a/projects/clr/rocclr/runtime/device/appprofile.hpp b/projects/clr/rocclr/runtime/device/appprofile.hpp index b81f1fe4cb..c328419447 100644 --- a/projects/clr/rocclr/runtime/device/appprofile.hpp +++ b/projects/clr/rocclr/runtime/device/appprofile.hpp @@ -17,6 +17,9 @@ public: bool init(); const std::string& GetBuildOptsAppend() const { return buildOptsAppend_; } + + const std::string& appFileName() const { return appFileName_; } + protected: enum DataTypes { diff --git a/projects/clr/rocclr/runtime/platform/program.cpp b/projects/clr/rocclr/runtime/platform/program.cpp index f883deca97..a4c7b3238a 100644 --- a/projects/clr/rocclr/runtime/platform/program.cpp +++ b/projects/clr/rocclr/runtime/platform/program.cpp @@ -12,6 +12,9 @@ #include // for malloc #include // for strcmp +#include +#include +#include #include namespace amd { @@ -413,6 +416,46 @@ Program::link( return retval; } +void Program::StubProgramSource(const std::string& app_name) +{ + static uint program_counter = 0; + std::fstream stub_read; + std::stringstream file_name; + std::string app_name_no_ext; + + std::size_t length = app_name.rfind(".exe"); + if (length == std::string::npos) { + length = app_name.size(); + } + app_name_no_ext.assign(app_name.c_str(), length); + + // Construct a unique file name for the CL program + file_name << app_name_no_ext << "_program_" << program_counter << ".cl"; + + stub_read.open(file_name.str().c_str(), (std::fstream::in | std::fstream::binary)); + // Check if we have OpenCL program + if (stub_read.is_open()) { + // Find the stream size + stub_read.seekg(0, std::fstream::end); + size_t size = stub_read.tellg(); + stub_read.seekg(0, std::ios::beg); + + char* data = new char[size]; + stub_read.read(data, size); + stub_read.close(); + + sourceCode_.assign(data, size); + delete[] data; + } + else { + std::fstream stub_write; + stub_write.open(file_name.str().c_str(), (std::fstream::out | std::fstream::binary)); + stub_write << sourceCode_; + stub_write.close(); + } + program_counter++; +} + cl_int Program::build( const std::vector& devices, @@ -431,6 +474,11 @@ Program::build( } } + if (OCL_STUB_PROGRAMS && !sourceCode_.empty()) { + // The app name should be the samme for all device + StubProgramSource(devices[0]->appProfile()->appFileName()); + } + // Clear the program object clear(); diff --git a/projects/clr/rocclr/runtime/platform/program.hpp b/projects/clr/rocclr/runtime/platform/program.hpp index aa7638c59b..bcc89e0733 100644 --- a/projects/clr/rocclr/runtime/platform/program.hpp +++ b/projects/clr/rocclr/runtime/platform/program.hpp @@ -77,6 +77,9 @@ public: typedef std::map symbols_t; private: + //! Replaces the compiled program with the new version from HD + void StubProgramSource(const std::string& app_name); + //! The context this program is part of. SharedReference context_; diff --git a/projects/clr/rocclr/runtime/utils/flags.hpp b/projects/clr/rocclr/runtime/utils/flags.hpp index 0dcbfdd03a..cbed0e4567 100644 --- a/projects/clr/rocclr/runtime/utils/flags.hpp +++ b/projects/clr/rocclr/runtime/utils/flags.hpp @@ -181,6 +181,8 @@ release(uint, GPU_WAVES_PER_SIMD, 0, \ "Force the number of waves per SIMD (1-10)") \ release(bool, GPU_WAVE_LIMIT_ENABLE, false, \ "1 = Enable adaptive wave limiter") \ +release(bool, OCL_STUB_PROGRAMS, false, \ + "1 = Enables OCL programs stubing") \ release_on_stg(uint, GPU_WAVE_LIMIT_CU_PER_SH, 0, \ "Assume the number of CU per SH for wave limiter") \ release_on_stg(uint, GPU_WAVE_LIMIT_MAX_WAVE, 10, \