imate
C++/CUDA Reference
dynamic_loading Namespace Reference

Dynamic loading of shared libraries using dlopen tool. More...

Functions

template<typename Signature >
Signature load_symbol (const char *lib_name, const char *symbol_name)
 Loads a symbol within a library and returns a pointer to the symbol (function pointer). More...
 

Detailed Description

Dynamic loading of shared libraries using dlopen tool.

The dynamic loading is compiled with CUDA_DYNAMIC_LOADING set to 1. When enabeld, the CUDA libraries are loaded at the run- time. This method has an advantage and a disadvatage:

  • Advantage: when dynamic loading is enabled, this package can be distributed without bundling the large cuda libraries. That is, when the wheel of this package is repaired with auditwheel tool in manylinux platform, the cuda libraries will not be bundled to the wheel, so the size of the wheel does not increase. In contrast, if this package is not compiled with dynamic loading, the cuda *.so (or *.dll) shared library files will be bundled with the wheel and increase the size of the wheel upto 400MB. Such a large wheel file cannot be uploaded to PyPI due to the 100MB size limit. But with dynamic loading, the package requires these libraries only at the run-time, not at the compile time.
  • Disadvantage: The end-user must install the same cuda version that this package is compiled with. For example, if this package is compiled with cuda 11.x, the user must install cuda 11.x (such as 11.0, 11.1, etc), but not cuda 10.x.

The run time with/without dynamic loading is the same. That is, using the dynamic loading doesn't affect the performance at all.

The functions in this namespace load any generic libraries. We use them to load libcudart, libcublas, and libcusparse.

Note
When this package is compiled with dynamic loading enabled, make sure that cuda toolkit is available at run-time. For instance on a linux cluster, run:
module load cuda
See also
cudartSymbols, cublasSymbols, cusparseSymbols

Function Documentation

◆ load_symbol()

template<typename Signature >
Signature dynamic_loading::load_symbol ( const char *  lib_name,
const char *  symbol_name 
)

Loads a symbol within a library and returns a pointer to the symbol (function pointer).

Template Parameters
SignatureThe template parameter. The returned symbol pointer is cast from void* to the template parameter Signature, which is essentially a typedef for the output function.
Parameters
[in]lib_nameName of the library.
[in]symbol_nameName of the symbol within the library.
Returns
Returns a pointer to the symbol, which is a pointer to a callable function.

Definition at line 164 of file dynamic_loading.h.

167  {
168  #if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && \
169  !defined(__CYGWIN__)
170 
171  HMODULE handle = get_library_handle_windows(lib_name);
172  FARPROC symbol = GetProcAddress(handle, symbol_name);
173 
174  if (symbol == NULL)
175  {
176  std::ostringstream oss;
177  oss << "The symbol '" << symbol << "' is failed to load " \
178  << "from the shared library '" << lib_name << "'." \
179  << std::endl;
180  std::string message = oss.str();
181  throw std::runtime_error(message);
182  }
183 
184  #elif defined(__unix__) || defined(__unix) || \
185  (defined(__APPLE__) && defined(__MACH__))
186 
187  void* handle = get_library_handle_unix(lib_name);
188  void* symbol = dlsym(handle, symbol_name);
189 
190  char *error = dlerror();
191  if (error != NULL)
192  {
193  throw std::runtime_error(dlerror());
194  }
195 
196  #else
197  #error "Unknown compiler"
198  #endif
199 
200 
201  return reinterpret_cast<Signature>(symbol);
202  }