8 #ifndef CUDA_API_WRAPPERS_LIBRARY_HPP_ 9 #define CUDA_API_WRAPPERS_LIBRARY_HPP_ 11 #if CUDA_VERSION >= 12000 16 #if __cplusplus >= 201703L 41 using option_t = CUlibraryOption;
49 inline library_t
wrap(
51 bool take_ownership =
false) noexcept;
53 inline ::
std::
string identify(const library::
handle_t &handle)
55 return ::std::string(
"library ") + cuda::detail_::ptr_as_hex(handle);
58 ::std::string identify(
const library_t &library);
68 template <
typename ContiguousContainer,
70 cuda::detail_::enable_if_t<cuda::detail_::is_kinda_like_contiguous_container<ContiguousContainer>::value,
bool> =
true >
72 ContiguousContainer library_data,
73 optional<link::options_t> link_options,
74 bool code_is_preserved);
83 auto status = cuLibraryGetKernel(&kernel_handle, library_handle, name);
85 + name +
"' from " + library::detail_::identify(library_handle));
91 CAW_SET_SCOPE_CONTEXT(context_handle);
92 return get_kernel_in_current_context(library_handle, name);
97 inline kernel_t get_kernel(
const library_t& library,
const char* name);
98 inline kernel_t get_kernel(context_t& context,
const library_t& library,
const char* name);
102 memory::region_t get_global(
const context_t& context,
const library_t& library,
const char* name);
103 memory::region_t get_managed_region(
const library_t& library,
const char* name);
107 module_t create(
const context_t& context,
const library_t& library);
108 module_t create(
const library_t& library);
112 void* get_unified_function(
const context_t& context,
const library_t& library,
const char* symbol);
135 library::kernel_t get_kernel(
const context_t& context,
const char* name)
const;
136 library::kernel_t get_kernel(
const context_t& context, const ::std::string& name)
const;
137 library::kernel_t get_kernel(
const char* name)
const;
138 library::kernel_t get_kernel(const ::std::string& name)
const;
142 return cuda::get_global(context::current::get(), *
this, name);
147 return get_global(name.c_str());
152 return cuda::get_managed_region(*
this, name);
157 return get_managed(name.c_str());
163 : handle_(handle), owning_(owning)
172 library_t(
const library_t&) =
delete;
174 library_t(library_t&& other) noexcept : library_t(other.handle_, other.owning_)
176 other.owning_ =
false;
179 ~library_t() noexcept(false)
182 auto status = cuLibraryUnload(handle_);
189 library_t& operator=(
const library_t&) =
delete;
190 library_t& operator=(library_t&& other) noexcept
192 ::std::swap(handle_, other.handle_);
193 ::std::swap(owning_, other.owning_);
204 inline memory::region_t get_global(
const context_t& context,
const library_t& library,
const char* name)
208 auto result = cuLibraryGetGlobal(&dptr, &size, library.handle(), name);
210 ::std::string(
"Obtaining the memory address and size for the global object '") + name +
"' from " 211 + library::detail_::identify(library) +
" in context " + context::detail_::identify(context));
221 inline memory::region_t get_managed_region(
const library_t& library,
const char* name)
225 auto status = cuLibraryGetManaged(®ion_start, ®ion_size, library.handle(), name);
226 throw_if_error_lazy(status, ::std::string(
"Failed obtaining the managed memory region '") + name
227 +
"' from " + library::detail_::identify(library));
236 inline module_t create(
const context_t& context,
const library_t& library)
238 CAW_SET_SCOPE_CONTEXT(context.handle());
240 auto status = cuLibraryGetModule(&new_handle, library.handle());
242 +
"' from " + library::detail_::identify(library) +
" in " + context::detail_::identify(context));
243 constexpr
const bool is_owning {
true };
245 is_owning, do_hold_primary_context_refcount_unit);
253 inline void* get_unified_function(
const context_t& context,
const library_t& library,
const char* symbol)
255 CAW_SET_SCOPE_CONTEXT(context.handle());
257 auto status = cuLibraryGetUnifiedFunction(&function_ptr, library.handle(), symbol);
258 throw_if_error_lazy(status, ::std::string(
"Failed obtaining a pointer for function '") + symbol
259 +
"' from " + library::detail_::identify(library) +
" in " + context::detail_::identify(context));
267 template <
typename Creator,
typename DataSource,
typename ErrorStringGenerator>
270 DataSource data_source,
271 ErrorStringGenerator error_string_generator,
272 const link::options_t& link_options = {},
273 bool code_is_preserved =
false)
276 auto raw_link_opts = link::detail_::marshal(link_options);
278 detail_::option_t options[1];
281 } raw_opts = { { CU_LIBRARY_BINARY_IS_PRESERVED }, { &code_is_preserved }, 1 };
282 auto status = creator(
283 &new_lib_handle, data_source,
284 const_cast<link::detail_::option_t*>(raw_link_opts.options()),
285 const_cast<void**>(raw_link_opts.values()), raw_link_opts.count(),
286 raw_opts.options, raw_opts.values, raw_opts.count
289 ::std::string(
"Failed loading a compiled CUDA code library from ") + error_string_generator());
290 bool do_take_ownership{
true};
310 const link::options_t& link_options = {},
311 bool code_is_preserved =
false)
313 return detail_::create(
314 cuLibraryLoadFromFile, path,
315 [path]() { return ::std::string(
"file ") + path; },
316 link_options, code_is_preserved);
320 const ::std::string& path,
321 const link::options_t& link_options = {},
322 bool code_is_preserved =
false)
324 return load_from_file(path.c_str(), link_options, code_is_preserved);
327 #if __cplusplus >= 201703L 330 const ::std::filesystem::path& path,
331 const link::options_t& link_options = {},
332 bool code_is_preserved =
false)
334 return load_from_file(path.c_str(), link_options, code_is_preserved);
342 inline library_t
wrap(
handle_t handle,
bool take_ownership) noexcept
344 return library_t{handle, take_ownership};
356 inline library_t create(
357 const void* module_data,
358 const link::options_t& link_options = {},
359 bool code_is_preserved =
false)
361 return detail_::create(
362 cuLibraryLoadData, module_data,
363 [module_data]() { return ::std::string(
"data at ") + cuda::detail_::ptr_as_hex(module_data); },
364 link_options, code_is_preserved);
373 inline ::std::string identify(
const library_t& library)
375 return identify(library.handle());
380 template <
typename ContiguousContainer,
381 cuda::detail_::enable_if_t<cuda::detail_::is_kinda_like_contiguous_container<ContiguousContainer>::value,
bool> >
383 ContiguousContainer library_data,
384 optional<link::options_t> link_options,
385 bool code_is_preserved)
387 return create(library_data.data(), link_options, code_is_preserved);
394 #endif // CUDA_VERSION >= 12000 396 #endif // CUDA_API_WRAPPERS_LIBRARY_HPP_ Definitions and functionality wrapping CUDA APIs.
Definition: array.hpp:22
device::id_t count()
Get the number of CUDA devices usable on the system (with the current CUDA library and kernel driver)...
Definition: miscellany.hpp:63
detail_::region_helper< memory::region_t > region_t
A child class of the generic region_t with some managed-memory-specific functionality.
Definition: memory.hpp:1960
module_t load_from_file(const context_t &context, const char *path)
Load a module from an appropriate compiled or semi-compiled file, allocating all relevant resources f...
Definition: module.hpp:317
#define throw_if_error_lazy(status__,...)
A macro for only throwing an error if we've failed - which also ensures no string is constructed unle...
Definition: error.hpp:316
CUarray handle_t
Raw CUDA driver handle for arrays (of any dimension)
Definition: array.hpp:34
array_t< T, NumDimensions > wrap(device::id_t device_id, context::handle_t context_handle, handle_t handle, dimensions_t< NumDimensions > dimensions) noexcept
Wrap an existing CUDA array in an array_t instance.
Definition: array.hpp:264
void * as_pointer(device::address_t address) noexcept
Definition: types.hpp:700
CUdeviceptr address_t
The numeric type which can represent the range of memory addresses on a CUDA device.
Definition: types.hpp:672
A host-side binary object with embedded device code; a .o file.