summaryrefslogtreecommitdiff
path: root/libcuda/cuda_runtime_api.cc
diff options
context:
space:
mode:
authorWilliamMTK <[email protected]>2024-12-11 16:52:40 -0500
committerGitHub <[email protected]>2024-12-11 21:52:40 +0000
commit752d4e5bf622b0d7c730e3eb2f1b3e3cf91e81fa (patch)
treec21658a59c854d8251706796570ce80e34a6ef7b /libcuda/cuda_runtime_api.cc
parent667834cfe5214523edd7769aeab77f91b7137686 (diff)
Add SST integration into gpgpusim (#44)
* Add accommodations to run gpgpusim with SST simulation framework through balar * Output setup_environment options when sourcing * Add SST directive check when creating sim thread * Add sst side test for jenkins * sst-integration: update Jenkinsfile with offical sst-elements repo and fix bugs in pipeline script * sst-integration: direct jenkins to rebuild gpgpusim before testing for sst * sst-integration: fix bugs in sst repos config * sst-integration: let Jenkins rebuilds simulator Since the simulator needs to be configured with both normal mode and sst mode, need to rebuild make target to clean prior runs. * sst-integration: Update Jenkinsfile to source env vars when running balar test * sst-integration: refactor code to remove __SST__ flag * sst-integration: fix a bug that init cluster twice for sst * sst-integration: fix a bug of not sending mem packets to SST * sst-integration: remove sst flags from makefiles and setup_env * sst-integration: add comments to SST changes * sst-integration: remove rebuilding simulator in jenkins when testing for SST * sst-integration: revert simulator build script * Add a function to support querying function argument info for SST * sst-integration: add version detection for vanadis binary * Automated Format * add version detection support for gcc 10+ * sst-integration: add cudaMallocHost for SST * sst-integration: fix a compilation bug * sst-integration: add sst balar unittest CI * sst-integration: specify GPU_ARCH for CI test * sst-integration: use bash for github actions * sst-integration: use https links for sst repos * sst-integration: add SST dependencies to CI config * sst-integration: remove sudo * sst-integration: default to yes for apt install * sst-integration: add manual trigger for github action * sst-integration: remove wrong on event * sst-integration: limit CPU usage for compilation * sst-integration: fix wrong path * sst-integration: use personal repo for testing * sst-integration: remove sst-core source in CI to free space * sst-integration: SST_Cycle use print stats with stream id * Automated Format * sst-integration: check for diskspace and try to clean it * sst-integration: move out of docker image * sst-integration: testing for ci path * sst-integration: fix syntax * sst-integration: pass env vars * sst-integration: set env properly * sst-integration: merge LLVM build and test into same job * sst-integration: fix step order * sst-integration: checkout correct branch for env-setup * sst-integration: remove resourcing gpu apps * sst-integration: revert back to docker github action * sst-integration: enable debug trace for sst testing * sst-integration: resourcing gpu app for env vars * sst-integration: use GPUAPPS_ROOT for path for gpu app * sst-integration: use GPUAPPS_ROOT for path for gpu app * sst-integration: enable parallel ci tests and fix not returning with cudaMallocHostSST * sst-integration: using debug flag for CI run * sst-integration: revert debug ci run * sst-integration: CI skips cuda sdk download and launch multiple jobs * sst-integration: reenable parallel tests * sst-integration: reduce concurrent test thread count * sst-integration: skip long test for github runner * sst-integration: try running CI with single core * sst-integrtion: add callback to SST to check thread sync is done in SST_Cycle() * sst-integration: ignore lookup if already found and add callbacks to SST * Automated Format * sst-integration: add support for indirect texture access * Automated Format * sste-integration: fix up for PR * Automated Format --------- Co-authored-by: purdue-jenkins <[email protected]>
Diffstat (limited to 'libcuda/cuda_runtime_api.cc')
-rw-r--r--libcuda/cuda_runtime_api.cc274
1 files changed, 252 insertions, 22 deletions
diff --git a/libcuda/cuda_runtime_api.cc b/libcuda/cuda_runtime_api.cc
index b540ffd..5dfd3fc 100644
--- a/libcuda/cuda_runtime_api.cc
+++ b/libcuda/cuda_runtime_api.cc
@@ -109,6 +109,7 @@
#include <string.h>
#include <time.h>
#include <fstream>
+#include <functional>
#include <iostream>
#include <regex>
#include <sstream>
@@ -151,6 +152,9 @@
#include <mach-o/dyld.h>
#endif
+// SST cycle
+extern bool SST_Cycle();
+
/*DEVICE_BUILTIN*/
struct cudaArray {
void *devPtr;
@@ -412,6 +416,13 @@ void setCuobjdumpsassfilename(
//! processes (e.g. cuobjdump) reading /proc/<pid>/exe will see the emulator
//! executable instead of the application binary.
//!
+// In SST need the string to pass the binary information
+// as we cannot get it from /proc/self/exe
+std::string get_app_binary(const char *fn) {
+ printf("self exe links to: %s\n", fn);
+ return fn;
+}
+
std::string get_app_binary() {
char self_exe_path[1025];
#ifdef __APPLE__
@@ -453,19 +464,25 @@ char *get_app_binary_name(std::string abs_path) {
return self_exe_path;
}
-static int get_app_cuda_version() {
+static int get_app_cuda_version_internal(std::string app_binary) {
int app_cuda_version = 0;
char fname[1024];
snprintf(fname, 1024, "_app_cuda_version_XXXXXX");
int fd = mkstemp(fname);
close(fd);
+ // Weili: Add way to extract CUDA version information from Balar Vanadis
+ // binary (stored as a const string)
std::string app_cuda_version_command =
- "ldd " + get_app_binary() +
+ "ldd " + app_binary +
" | grep libcudart.so | sed 's/.*libcudart.so.\\(.*\\) =>.*/\\1/' > " +
+ fname + " && strings " + app_binary +
+ " | grep libcudart_vanadis.a | sed "
+ "'s/.*libcudart_vanadis.a.\\(.*\\)/\\1/' >> " +
fname;
int res = system(app_cuda_version_command.c_str());
if (res == -1) {
- printf("Error - Cannot detect the app's CUDA version.\n");
+ printf("Error - Cannot detect the app's CUDA version. Command: %s\n",
+ app_cuda_version_command.c_str());
exit(1);
}
FILE *cmd = fopen(fname, "r");
@@ -476,12 +493,24 @@ static int get_app_cuda_version() {
}
fclose(cmd);
if (app_cuda_version == 0) {
- printf("Error - Cannot detect the app's CUDA version.\n");
+ printf("Error - Cannot detect the app's CUDA version. Command: %s\n",
+ app_cuda_version_command.c_str());
exit(1);
}
return app_cuda_version;
}
+static int get_app_cuda_version(const char *fn) {
+ // Use for other simulator integration
+ std::string app_binary = get_app_binary(fn);
+ return get_app_cuda_version_internal(app_binary);
+}
+
+static int get_app_cuda_version() {
+ std::string app_binary = get_app_binary();
+ return get_app_cuda_version_internal(app_binary);
+}
+
//! Keep track of the association between filename and cubin handle
void cuda_runtime_api::cuobjdumpRegisterFatBinary(unsigned int handle,
const char *filename,
@@ -574,8 +603,11 @@ __host__ cudaError_t CUDARTAPI cudaDeviceGetLimitInternal(
return g_last_cudaError = cudaSuccess;
}
-void **cudaRegisterFatBinaryInternal(void *fatCubin,
- gpgpu_context *gpgpu_ctx = NULL) {
+// Internal implementation for cudaRegisterFatBiaryInternal
+void **cudaRegisterFatBiaryInternal_impl(
+ void *fatCubin, gpgpu_context *gpgpu_ctx, std::string &app_binary_path,
+ int app_cuda_version,
+ std::function<void(gpgpu_context *)> ctx_cuobjdumpInit_func) {
gpgpu_context *ctx;
if (gpgpu_ctx) {
ctx = gpgpu_ctx;
@@ -606,11 +638,9 @@ void **cudaRegisterFatBinaryInternal(void *fatCubin,
// compiled with a newer version of CUDA to run apps compiled with older
// versions of CUDA. This is especially useful for PTXPLUS execution.
// Skip cuda version check for pytorch application
- std::string app_binary_path = get_app_binary();
int pos = app_binary_path.find("python");
if (pos == std::string::npos) {
// Not pytorch app : checking cuda version
- int app_cuda_version = get_app_cuda_version();
assert(
app_cuda_version == CUDART_VERSION / 1000 &&
"The app must be compiled with same major version as the simulator.");
@@ -661,7 +691,7 @@ void **cudaRegisterFatBinaryInternal(void *fatCubin,
* then for next calls, only returns the appropriate number
*/
assert(fat_cubin_handle >= 1);
- if (fat_cubin_handle == 1) ctx->api->cuobjdumpInit();
+ if (fat_cubin_handle == 1) ctx_cuobjdumpInit_func(ctx);
ctx->api->cuobjdumpRegisterFatBinary(fat_cubin_handle, filename, context);
return (void **)fat_cubin_handle;
@@ -753,6 +783,28 @@ void **cudaRegisterFatBinaryInternal(void *fatCubin,
#endif
}
+void **cudaRegisterFatBinaryInternal(const char *fn, void *fatCubin,
+ gpgpu_context *gpgpu_ctx = NULL) {
+ std::string app_binary_path = get_app_binary(fn);
+ int app_cuda_version = get_app_cuda_version(fn);
+ auto ctx_cuobjdumpInit = [=](gpgpu_context *ctx) {
+ ctx->api->cuobjdumpInit(fn);
+ };
+ return cudaRegisterFatBiaryInternal_impl(fatCubin, gpgpu_ctx, app_binary_path,
+ app_cuda_version, ctx_cuobjdumpInit);
+}
+
+void **cudaRegisterFatBinaryInternal(void *fatCubin,
+ gpgpu_context *gpgpu_ctx = NULL) {
+ std::string app_binary_path = get_app_binary();
+ int app_cuda_version = get_app_cuda_version();
+ auto ctx_cuobjdumpInit = [](gpgpu_context *ctx) {
+ ctx->api->cuobjdumpInit();
+ };
+ return cudaRegisterFatBiaryInternal_impl(fatCubin, gpgpu_ctx, app_binary_path,
+ app_cuda_version, ctx_cuobjdumpInit);
+}
+
void cudaRegisterFunctionInternal(void **fatCubinHandle, const char *hostFun,
char *deviceFun, const char *deviceName,
int thread_limit, uint3 *tid, uint3 *bid,
@@ -1057,6 +1109,24 @@ cudaError_t cudaMallocHostInternal(void **ptr, size_t size,
}
}
+// SST malloc done by vanadis, we just need to record the memory addr
+cudaError_t CUDARTAPI cudaMallocHostSSTInternal(
+ void *addr, size_t size, gpgpu_context *gpgpu_ctx = NULL) {
+ gpgpu_context *ctx;
+ if (gpgpu_ctx) {
+ ctx = gpgpu_ctx;
+ } else {
+ ctx = GPGPU_Context();
+ }
+ if (g_debug_execution >= 3) {
+ announce_call(__my_func__);
+ }
+ // track pinned memory size allocated in the host so that same amount of
+ // memory is also allocated in GPU.
+ ctx->api->pinned_memory_size[addr] = size;
+ return g_last_cudaError = cudaSuccess;
+}
+
__host__ cudaError_t CUDARTAPI
cudaMallocPitchInternal(void **devPtr, size_t *pitch, size_t width,
size_t height, gpgpu_context *gpgpu_ctx = NULL) {
@@ -2301,13 +2371,77 @@ cudaDeviceSynchronizeInternal(gpgpu_context *gpgpu_ctx = NULL) {
* *
*******************************************************************************/
-extern "C" {
-
/*******************************************************************************
* *
- * *
+ * SST Specific functions, used by Balar *
* *
*******************************************************************************/
+
+/**
+ * @brief Custom function to get CUDA function parameter size and offset
+ * from PTX parsing result
+ *
+ * @param hostFun
+ * @param index
+ * @return std::tuple<cudaError_t, size_t, unsigned>
+ */
+std::tuple<cudaError_t, size_t, unsigned> SST_cudaGetParamConfig(
+ uint64_t hostFun, unsigned index) {
+ if (g_debug_execution >= 3) {
+ announce_call(__my_func__);
+ }
+ CUctx_st *context = GPGPUSim_Context(GPGPU_Context());
+ function_info *entry = context->get_kernel((char *)hostFun);
+ cudaError_t result = cudaSuccess;
+ size_t size = 0;
+ unsigned alignment = 0;
+ if (index >= entry->num_args()) {
+ result = cudaErrorAssert;
+ } else {
+ std::pair<size_t, unsigned> p = entry->get_param_config(index);
+ size = p.first;
+ alignment = p.second;
+ }
+ return std::tuple<cudaError_t, size_t, unsigned>(result, size, alignment);
+}
+
+extern "C" {
+void SST_receive_mem_reply(unsigned core_id, void *mem_req) {
+ CUctx_st *context = GPGPUSim_Context(GPGPU_Context());
+ static_cast<sst_gpgpu_sim *>(context->get_device()->get_gpgpu())
+ ->SST_receive_mem_reply(core_id, mem_req);
+ // printf("GPGPU-sim: Recived Request\n");
+}
+
+bool SST_gpu_core_cycle() { return SST_Cycle(); }
+
+void SST_gpgpusim_numcores_equal_check(unsigned sst_numcores) {
+ CUctx_st *context = GPGPUSim_Context(GPGPU_Context());
+ static_cast<sst_gpgpu_sim *>(context->get_device()->get_gpgpu())
+ ->SST_gpgpusim_numcores_equal_check(sst_numcores);
+}
+
+uint64_t cudaMallocSST(void **devPtr, size_t size) {
+ if (g_debug_execution >= 3) {
+ announce_call(__my_func__);
+ }
+ void *test_malloc;
+ test_malloc = (void *)malloc(size);
+ void **test_malloc2 = &test_malloc;
+ CUctx_st *context = GPGPUSim_Context(GPGPU_Context());
+ *test_malloc2 = context->get_device()->get_gpgpu()->gpu_malloc(size);
+ printf("GPGPU-Sim PTX: cudaMallocing %zu bytes starting at 0x%llx..\n", size,
+ (unsigned long long)*test_malloc2);
+ if (g_debug_execution >= 3)
+ printf("GPGPU-Sim PTX: cudaMallocing %zu bytes starting at 0x%llx..\n",
+ size, (unsigned long long)*test_malloc2);
+ return (uint64_t)*test_malloc2;
+}
+
+__host__ cudaError_t CUDARTAPI cudaMallocHostSST(void *addr, size_t size) {
+ return cudaMallocHostSSTInternal(addr, size);
+}
+
cudaError_t cudaPeekAtLastError(void) { return g_last_cudaError; }
__host__ cudaError_t CUDARTAPI cudaMalloc(void **devPtr, size_t size) {
@@ -2534,6 +2668,7 @@ cudaError_t CUDARTAPI cudaOccupancyMaxActiveBlocksPerMultiprocessorWithFlags(
* *
* *
*******************************************************************************/
+
__host__ cudaError_t CUDARTAPI cudaMemset(void *mem, int c, size_t count) {
return cudaMemsetInternal(mem, c, count);
}
@@ -2754,11 +2889,32 @@ __host__ const char *CUDARTAPI cudaGetErrorString(cudaError_t error) {
return strdup(buf);
}
+// SST specific cuda apis
+__host__ cudaError_t CUDARTAPI cudaSetupArgumentSST(uint64_t arg,
+ uint8_t value[200],
+ size_t size,
+ size_t offset) {
+ void *local_value;
+ local_value = (void *)malloc(size);
+
+ if (arg) {
+ memcpy(local_value, (void *)&arg, size);
+ } else {
+ memcpy(local_value, value, size);
+ }
+ return cudaSetupArgumentInternal(local_value, size, offset);
+}
+
__host__ cudaError_t CUDARTAPI cudaSetupArgument(const void *arg, size_t size,
size_t offset) {
return cudaSetupArgumentInternal(arg, size, offset);
}
+// SST specific cuda apis
+__host__ cudaError_t CUDARTAPI cudaLaunchSST(uint64_t hostFun) {
+ return cudaLaunchInternal((char *)hostFun);
+}
+
__host__ cudaError_t CUDARTAPI cudaLaunch(const char *hostFun) {
return cudaLaunchInternal(hostFun);
}
@@ -2933,6 +3089,27 @@ __host__ cudaError_t CUDARTAPI cudaThreadSynchronize(void) {
return cudaThreadSynchronizeInternal();
}
+__host__ cudaError_t CUDARTAPI cudaThreadSynchronizeSST(void) {
+ // For SST, perform a one-time check and let SST_Cycle()
+ // do the polling test and invoke callback to SST
+ // to signal ThreadSynchonize done
+ gpgpu_context *ctx = GPGPU_Context();
+ if (g_debug_execution >= 3) {
+ announce_call(__my_func__);
+ }
+
+ // Called on host side
+ bool thread_sync_done = ctx->synchronize_check();
+ g_last_cudaError = cudaSuccess;
+ if (thread_sync_done) {
+ // We are already done, so no need to poll for sync done
+ ctx->requested_synchronize = false;
+ return cudaSuccess;
+ } else {
+ return cudaErrorNotReady;
+ }
+}
+
int CUDARTAPI __cudaSynchronizeThreads(void **, void *) {
if (g_debug_execution >= 3) {
announce_call(__my_func__);
@@ -2992,10 +3169,10 @@ __host__ cudaError_t CUDARTAPI cudaGetExportTable(
// extracts all ptx files from binary and dumps into
// prog_name.unique_no.sm_<>.ptx files
-void cuda_runtime_api::extract_ptx_files_using_cuobjdump(CUctx_st *context) {
+void cuda_runtime_api::extract_ptx_files_using_cuobjdump_internal(
+ CUctx_st *context, std::string &app_binary) {
char command[1000];
char *pytorch_bin = getenv("PYTORCH_BIN");
- std::string app_binary = get_app_binary();
char ptx_list_file_name[1024];
snprintf(ptx_list_file_name, 1024, "_cuobjdump_list_ptx_XXXXXX");
@@ -3062,6 +3239,17 @@ void cuda_runtime_api::extract_ptx_files_using_cuobjdump(CUctx_st *context) {
}
}
+void cuda_runtime_api::extract_ptx_files_using_cuobjdump(CUctx_st *context,
+ const char *fn) {
+ std::string app_binary = get_app_binary(fn);
+ this->extract_ptx_files_using_cuobjdump_internal(context, app_binary);
+}
+
+void cuda_runtime_api::extract_ptx_files_using_cuobjdump(CUctx_st *context) {
+ std::string app_binary = get_app_binary();
+ this->extract_ptx_files_using_cuobjdump_internal(context, app_binary);
+}
+
//! Call cuobjdump to extract everything (-elf -sass -ptx)
/*!
* This Function extract the whole PTX (for all the files) using cuobjdump
@@ -3069,13 +3257,12 @@ void cuda_runtime_api::extract_ptx_files_using_cuobjdump(CUctx_st *context) {
*with each binary in its own file It is also responsible for extracting the
*libraries linked to the binary if the option is enabled
* */
-void cuda_runtime_api::extract_code_using_cuobjdump() {
- CUctx_st *context = GPGPUSim_Context(gpgpu_ctx);
-
+void cuda_runtime_api::extract_code_using_cuobjdump_internal(
+ CUctx_st *context, std::string &app_binary,
+ std::function<void(CUctx_st *)> ctx_extract_ptx_func) {
// prevent the dumping by cuobjdump everytime we execute the code!
const char *override_cuobjdump = getenv("CUOBJDUMP_SIM_FILE");
char command[1000];
- std::string app_binary = get_app_binary();
// Running cuobjdump using dynamic link to current process
snprintf(command, 1000, "md5sum %s ", app_binary.c_str());
printf("Running md5sum using \"%s\"\n", command);
@@ -3090,7 +3277,7 @@ void cuda_runtime_api::extract_code_using_cuobjdump() {
// used by ptxas.
int result = 0;
#if (CUDART_VERSION >= 6000)
- extract_ptx_files_using_cuobjdump(context);
+ ctx_extract_ptx_func(context);
return;
#endif
// TODO: redundant to dump twice. how can it be prevented?
@@ -3222,6 +3409,26 @@ void cuda_runtime_api::extract_code_using_cuobjdump() {
}
}
+void cuda_runtime_api::extract_code_using_cuobjdump(const char *fn) {
+ CUctx_st *context = GPGPUSim_Context(gpgpu_ctx);
+ std::string app_binary = get_app_binary(fn);
+ auto ctx_extract_ptx_func = [=](CUctx_st *context) {
+ extract_ptx_files_using_cuobjdump(context, fn);
+ };
+ extract_code_using_cuobjdump_internal(context, app_binary,
+ ctx_extract_ptx_func);
+}
+
+void cuda_runtime_api::extract_code_using_cuobjdump() {
+ CUctx_st *context = GPGPUSim_Context(gpgpu_ctx);
+ std::string app_binary = get_app_binary();
+ auto ctx_extract_ptx_func = [=](CUctx_st *context) {
+ extract_ptx_files_using_cuobjdump(context);
+ };
+ extract_code_using_cuobjdump_internal(context, app_binary,
+ ctx_extract_ptx_func);
+}
+
//! Read file into char*
// TODO: convert this to C++ streams, will be way cleaner
char *readfile(const std::string filename) {
@@ -3466,10 +3673,11 @@ cuobjdumpPTXSection *cuda_runtime_api::findPTXSection(
}
//! Extract the code using cuobjdump and remove unnecessary sections
-void cuda_runtime_api::cuobjdumpInit() {
+void cuda_runtime_api::cuobjdumpInit_internal(
+ std::function<void()> ctx_extract_code_func) {
CUctx_st *context = GPGPUSim_Context(gpgpu_ctx);
- extract_code_using_cuobjdump(); // extract all the output of cuobjdump to
- // _cuobjdump_*.*
+ ctx_extract_code_func(); // extract all the output of cuobjdump to
+ // _cuobjdump_*.*
const char *pre_load = getenv("CUOBJDUMP_SIM_FILE");
if (pre_load == NULL || strlen(pre_load) == 0) {
cuobjdumpSectionList = pruneSectionList(context);
@@ -3477,6 +3685,16 @@ void cuda_runtime_api::cuobjdumpInit() {
}
}
+void cuda_runtime_api::cuobjdumpInit(const char *fn) {
+ auto ctx_extract_code_func = [=]() { extract_code_using_cuobjdump(fn); };
+ cuobjdumpInit_internal(ctx_extract_code_func);
+}
+
+void cuda_runtime_api::cuobjdumpInit() {
+ auto ctx_extract_code_func = [=]() { extract_code_using_cuobjdump(); };
+ cuobjdumpInit_internal(ctx_extract_code_func);
+}
+
//! Either submit PTX for simulation or convert SASS to PTXPlus and submit it
void gpgpu_context::cuobjdumpParseBinary(unsigned int handle) {
CUctx_st *context = GPGPUSim_Context(this);
@@ -3587,6 +3805,10 @@ void gpgpu_context::cuobjdumpParseBinary(unsigned int handle) {
extern "C" {
+void **CUDARTAPI __cudaRegisterFatBinarySST(const char *fn) {
+ return cudaRegisterFatBinaryInternal(fn, NULL);
+}
+
void **CUDARTAPI __cudaRegisterFatBinary(void *fatCubin) {
if (g_debug_execution >= 3) {
announce_call(__my_func__);
@@ -3619,6 +3841,14 @@ cudaError_t CUDARTAPI __cudaPopCallConfiguration(dim3 *gridDim, dim3 *blockDim,
return g_last_cudaError = cudaSuccess;
}
+void CUDARTAPI __cudaRegisterFunctionSST(unsigned fatCubinHandle,
+ uint64_t hostFun,
+ char deviceFun[512]) {
+ cudaRegisterFunctionInternal((void **)fatCubinHandle, (const char *)hostFun,
+ (char *)deviceFun, NULL, NULL, NULL, NULL, NULL,
+ NULL);
+}
+
void CUDARTAPI __cudaRegisterFunction(void **fatCubinHandle,
const char *hostFun, char *deviceFun,
const char *deviceName, int thread_limit,