Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ set(REALM_SOURCES
network.cc
codedesc.cc
logging.cc
loader.cc
mutex.cc
profiling.cc
timers.cc
Expand Down
55 changes: 44 additions & 11 deletions src/realm/cuda/cuda_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#define REALM_CUDA_INTERNAL_H

#include "realm/cuda/cuda_module.h"
#include "realm/loader.h"

#include <memory>
#include <unordered_map>
Expand Down Expand Up @@ -67,8 +68,8 @@
#define REPORT_CU_ERROR(level, cmd, ret) \
do { \
const char *name, *str; \
CUDA_DRIVER_FNPTR(Realm::Cuda::cuGetErrorName)(ret, &name); \
CUDA_DRIVER_FNPTR(Realm::Cuda::cuGetErrorString)(ret, &str); \
CUDA_DRIVER_FNPTR(cuGetErrorName)(ret, &name); \
CUDA_DRIVER_FNPTR(cuGetErrorString)(ret, &str); \
log_gpu.newmsg(level) << __FILE__ << '(' << __LINE__ << "):" << cmd << " = " << ret \
<< '(' << name << "): " << str; \
} while(0)
Expand Down Expand Up @@ -1292,9 +1293,15 @@ namespace Realm {
#endif
#endif

// cuda driver and/or runtime entry points
#define CUDA_DRIVER_HAS_FNPTR(name) ((name##_fnptr) != nullptr)
#define CUDA_DRIVER_FNPTR(name) (assert(name##_fnptr != nullptr), name##_fnptr)
// cuda driver and/or runtime entry points
#if defined(REALM_CUDA_DYNAMIC_LOAD)
#define CUDA_DRIVER_HAS_FNPTR(name) ((cuda_loader.name##_fnptr) != nullptr)
#define CUDA_DRIVER_FNPTR(name) \
(assert(cuda_loader.name##_fnptr != nullptr), cuda_loader.name##_fnptr)
#else
#define CUDA_DRIVER_HAS_FNPTR(name) ((name) != nullptr)
#define CUDA_DRIVER_FNPTR(name) (assert(name != nullptr), name)
#endif

// Only APIs that are available in the minimum base driver version that Realm supports
// should be listed here
Expand Down Expand Up @@ -1410,12 +1417,17 @@ namespace Realm {
__op__(cuCtxRecordEvent, 12050); \
__op__(cuArrayGetMemoryRequirements, CUDA_VERSION_MIN);

struct CudaLoader : public Loader<CudaLoader> {
// Make sure to only use decltype, to ensure it matches the cuda.h definition
#define DECL_FNPTR_EXTERN(name, ver) extern decltype(&name) name##_fnptr;
CUDA_DRIVER_APIS(DECL_FNPTR_EXTERN);
#undef DECL_FNPTR_EXTERN
#define DECL_FNPTR(name, ver) decltype(&name) name##_fnptr = nullptr;
CUDA_DRIVER_APIS(DECL_FNPTR);
#undef DECL_FNPTR
bool load_symbols();
};

#define NVML_FNPTR(name) (name##_fnptr)
extern CudaLoader cuda_loader;

#define NVML_FNPTR(name) (nvml_loader.name##_fnptr)

#if NVML_API_VERSION >= 11
#define NVML_11_APIS(__op__) __op__(nvmlDeviceGetMemoryAffinity);
Expand Down Expand Up @@ -1464,6 +1476,16 @@ namespace Realm {
NVML_11_APIS(__op__); \
NVML_12_APIS(__op__);

struct NVMLLoader : public Loader<NVMLLoader> {
// Make sure to only use decltype, to ensure it matches the cuda.h definition
#define DECL_FNPTR(name) decltype(&name) name##_fnptr = nullptr;
NVML_APIS(DECL_FNPTR);
#undef DECL_FNPTR
bool load_symbols();
};

extern NVMLLoader nvml_loader;

#define DECL_FNPTR_EXTERN(name) extern decltype(&name) name##_fnptr;
NVML_APIS(DECL_FNPTR_EXTERN)
#undef DECL_FNPTR_EXTERN
Expand All @@ -1484,8 +1506,19 @@ namespace Realm {
CUPTI_APIS(DECL_FNPTR_EXTERN)
#undef DECL_FNPTR_EXTERN

#define CUPTI_HAS_FNPTR(name) (name##_fnptr != nullptr)
#define CUPTI_FNPTR(name) (assert(name##_fnptr != nullptr), name##_fnptr)
#define CUPTI_HAS_FNPTR(name) (cupti_loader.name##_fnptr != nullptr)
#define CUPTI_FNPTR(name) \
(assert(cupti_loader.name##_fnptr != nullptr), cupti_loader.name##_fnptr)

struct CUPTILoader : public Loader<CUPTILoader> {
// Make sure to only use decltype, to ensure it matches the cuda.h definition
#define DECL_FNPTR(name) decltype(&name) name##_fnptr = nullptr;
CUPTI_APIS(DECL_FNPTR);
#undef DECL_FNPTR
bool load_symbols();
};

extern CUPTILoader cupti_loader;

}; // namespace Cuda

Expand Down
168 changes: 58 additions & 110 deletions src/realm/cuda/cuda_module.cc
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ namespace Realm {
Logger log_cudart("cudart");
Logger log_cudaipc("cudaipc");
Logger log_cupti("cupti");
CudaLoader cuda_loader;
NVMLLoader nvml_loader;
CUPTILoader cupti_loader;

Logger log_stream("gpustream");
bool nvml_api_fnptrs_loaded = false;
Expand All @@ -106,14 +109,6 @@ namespace Realm {
bool cupti_api_initialized = false;
CUresult cuda_init_code = CUDA_ERROR_UNKNOWN;

bool cuda_api_fnptrs_loaded = false;

// Make sure to only use decltype here, to ensure it matches the cuda.h definition
#define DEFINE_FNPTR(name, ver) decltype(&name) name##_fnptr = 0;

CUDA_DRIVER_APIS(DEFINE_FNPTR);
#undef DEFINE_FNPTR

static unsigned ctz(uint64_t v)
{
#ifdef REALM_ON_WINDOWS
Expand All @@ -136,12 +131,6 @@ namespace Realm {
#endif
}

#define DEFINE_FNPTR(name) decltype(&name) name##_fnptr = 0;

NVML_APIS(DEFINE_FNPTR);
CUPTI_APIS(DEFINE_FNPTR);
#undef DEFINE_FNPTR

// function pointers for cuda hook
typedef void (*PFN_cuhook_register_callback)(void);
typedef void (*PFN_cuhook_start_task)(CUstream current_task_stream);
Expand Down Expand Up @@ -2694,128 +2683,87 @@ namespace Realm {
}
}

static bool resolve_cuda_api_fnptrs(void)
bool CudaLoader::load_symbols()
{
if(cuda_api_fnptrs_loaded) {
return true;
}

decltype(&cuGetProcAddress) cuGetProcAddress_fnptr = nullptr;

#if defined(REALM_USE_LIBDL)
log_gpu.info() << "dynamically loading libcuda.so";
void *libcuda = dlopen("libcuda.so.1", RTLD_NOW);
if(!libcuda) {
log_gpu.info() << "could not open libcuda.so: " << strerror(errno);
return false;
}
// Use the symbol we get from the dynamically loaded library
cuGetProcAddress_fnptr = reinterpret_cast<decltype(cuGetProcAddress_fnptr)>(
dlsym(libcuda, STRINGIFY(cuGetProcAddress)));
#elif CUDA_VERSION >= 11030
// Use the statically available symbol
cuGetProcAddress_fnptr = &cuGetProcAddress;
#endif

get_symbol(STRINGIFY(cuGetProcAddress), cuGetProcAddress_fnptr);
if(cuGetProcAddress_fnptr != nullptr) {
#define DRIVER_GET_FNPTR(name, ver) \
#define GET_SYMBOL(name, ver) \
cuGetProcAddress_stable(cuGetProcAddress_fnptr, name##_fnptr, #name, ver, \
"Could not retrieve symbol " #name);

CUDA_DRIVER_APIS(DRIVER_GET_FNPTR);
#undef DRIVER_GET_FNPTR
CUDA_DRIVER_APIS(GET_SYMBOL);
#undef GET_SYMBOL
} else {
#if defined(REALM_USE_LIBDL)
#define DRIVER_GET_FNPTR(name, ver) \
if(CUDA_SUCCESS != (nullptr != (name##_fnptr = reinterpret_cast<decltype(&name)>( \
dlsym(libcuda, STRINGIFY(name)))))) { \
log_gpu.info() << "Could not retrieve symbol " #name; \
#define GET_SYMBOL(name, ver) \
if(!get_symbol(STRINGIFY(name), name##_fnptr)) { \
log_gpu.info("Could not retrieve symbol %s", STRINGIFY(name)); \
}
CUDA_DRIVER_APIS(DRIVER_GET_FNPTR)
#undef DRIVER_GET_FNPTR
#else
#define DRIVER_GET_FNPTR(name, ver) name##_fnptr = &name;
// Only enumerate the driver apis for the base toolkit version, extra features
// cannot be enumerated
CUDA_DRIVER_APIS_BASE(DRIVER_GET_FNPTR);
#undef DRIVER_GET_FNPTR
#endif /* REALM_USE_LIBDL */
CUDA_DRIVER_APIS(GET_SYMBOL);
#undef GET_SYMBOL
}
return true;
}

cuda_api_fnptrs_loaded = true;
bool NVMLLoader::load_symbols()
{
#define GET_SYMBOL(name) \
if(!get_symbol(STRINGIFY(name), name##_fnptr)) { \
log_gpu.info("Could not retrieve symbol %s", STRINGIFY(name)); \
}
NVML_APIS(GET_SYMBOL);
return true;
}

bool CUPTILoader::load_symbols()
{
#define GET_SYMBOL(name) \
if(!get_symbol(STRINGIFY(name), name##_fnptr)) { \
log_gpu.info("Could not retrieve symbol %s", STRINGIFY(name)); \
}
CUPTI_APIS(GET_SYMBOL);
return true;
}

static bool resolve_nvml_api_fnptrs()
static bool resolve_cuda_api_fnptrs(void)
{
#ifdef REALM_USE_LIBDL
void *libnvml = NULL;
if(nvml_api_fnptrs_loaded)
#if !defined(REALM_CUDA_DYNAMIC_LOAD)
return true;
#else
if(cuda_loader) {
return true;
log_gpu.info() << "dynamically loading libnvidia-ml.so";
libnvml = dlopen("libnvidia-ml.so.1", RTLD_NOW);
if(libnvml == NULL) {
log_gpu.info() << "could not open libnvidia-ml.so" << strerror(errno);
return false;
}

#define DRIVER_GET_FNPTR(name) \
do { \
void *sym = dlsym(libnvml, STRINGIFY(name)); \
if(!sym) { \
log_gpu.info() << "symbol '" STRINGIFY(name) " missing from libnvidia-ml.so!"; \
} \
name##_fnptr = reinterpret_cast<decltype(&name)>(sym); \
} while(0)

NVML_APIS(DRIVER_GET_FNPTR);
#undef DRIVER_GET_FNPTR

nvml_api_fnptrs_loaded = true;
return true;
return cuda_loader.load({
#if defined(REALM_ON_WINDOWS)
"nvcuda.dll",
#else
return false;
"libcuda.so.1",
#endif
});
#endif
}

static bool resolve_cupti_api_fnptrs()
static bool resolve_nvml_api_fnptrs()
{
#if defined(REALM_USE_LIBDL)
void *libcupti = NULL;
if(cupti_api_fnptrs_loaded) {
if(nvml_loader) {
return true;
}
log_gpu.info("dynamically loading libcupti.so");
libcupti = dlopen("libcupti.so", RTLD_NOW);
if(libcupti == NULL) {
log_gpu.info("Failed to retrieve libcupti.so from LD_LIBRARY_PATH, trying "
"/usr/local/cuda/extras/CUPTI/lib64!");
libcupti = dlopen("/usr/local/cuda/extras/CUPTI/lib64/libcupti.so", RTLD_NOW);
if(libcupti == NULL) {
log_gpu.info() << "Could not open libcupti.so" << strerror(errno);
return false;
}
}

#define DRIVER_GET_FNPTR(name) \
do { \
void *sym = dlsym(libcupti, STRINGIFY(name)); \
if(!sym) { \
log_gpu.info() << "symbol '" STRINGIFY(name) " missing from libcupti.so!"; \
} \
name##_fnptr = reinterpret_cast<decltype(&name)>(sym); \
} while(0)

CUPTI_APIS(DRIVER_GET_FNPTR);
#undef DRIVER_GET_FNPTR

log_gpu.info() << "Loaded cupti!";
cupti_api_fnptrs_loaded = true;
return true;
return nvml_loader.load({
#if defined(REALM_ON_WINDOWS)
"nvml.dll",
#else
return false;
"libnvidia-ml.so",
#endif
});
}

static bool resolve_cupti_api_fnptrs()
{
if(cupti_loader) {
return true;
}
return cupti_loader.load(
{"libcupti.so", "/usr/local/cuda/extras/CUPTI/libcupti.so"});
}

/*static*/ ModuleConfig *CudaModule::create_module_config(RuntimeImpl *runtime)
Expand Down
14 changes: 6 additions & 8 deletions src/realm/gasnetex/gasnetex_internal.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "realm/runtime_impl.h"
Comment thread
muraj marked this conversation as resolved.
#include "realm/mem_impl.h"
#include "realm/logging.h"
#include "realm/loader.h"

#ifdef REALM_USE_CUDA
#include "realm/cuda/cuda_module.h"
Expand All @@ -33,8 +34,6 @@
#include "realm/hip/hip_internal.h"
#endif

#include <dlfcn.h>

namespace Realm {

// defined in gasnetex_module.cc
Expand Down Expand Up @@ -3178,25 +3177,24 @@ namespace Realm {
static const char default_gex_wrapper_name[] = "librealm_gex_wrapper.so";
const char *gex_wrapper_name = getenv("REALM_GASNETEX_WRAPPER");
gex_wrapper_init_pfn realm_gex_wrapper_init_fnptr = nullptr;
void *librealm_gex_wrapper_handle = nullptr;
lib_handle_t librealm_gex_wrapper_handle = nullptr;

if(gex_wrapper_name == nullptr) {
gex_wrapper_name = default_gex_wrapper_name;
}

log_gex.debug("Loading gex wrapper: %s", gex_wrapper_name);
librealm_gex_wrapper_handle = dlopen(gex_wrapper_name, RTLD_NOW);
librealm_gex_wrapper_handle = Realm::load_library(gex_wrapper_name, LOADLIB_NOW);
if(librealm_gex_wrapper_handle == nullptr) {
log_gex.error("Failed to load gex wrapper at %s", gex_wrapper_name);
goto Error;
}

realm_gex_wrapper_init_fnptr = reinterpret_cast<gex_wrapper_init_pfn>(
dlsym(librealm_gex_wrapper_handle, "realm_gex_wrapper_init"));
Realm::get_symbol(librealm_gex_wrapper_handle, "realm_gex_wrapper_init"));
if(realm_gex_wrapper_init_fnptr == nullptr) {
const char *dlsym_error = dlerror();
log_gex.error("Cannot load wrapper entry symbol: %s\n", dlsym_error);
dlclose(librealm_gex_wrapper_handle);
log_gex.error("Cannot load wrapper entry symbol\n");
Realm::close_library(librealm_gex_wrapper_handle);
goto Error;
}
if(0 != realm_gex_wrapper_init_fnptr(&gex_wrapper_handle)) {
Expand Down
Loading
Loading