cuda-api-wrappers
Thin C++-flavored wrappers for the CUDA Runtime API
module.hpp
Go to the documentation of this file.
1 
11 #pragma once
12 #ifndef MULTI_WRAPPER_IMPLS_MODULE_HPP_
13 #define MULTI_WRAPPER_IMPLS_MODULE_HPP_
14 
15 #include "context.hpp"
16 #include "../device.hpp"
17 #include "../module.hpp"
18 
19 namespace cuda {
20 
21 // Moved over from context.hpp
22 template <typename ContiguousContainer,
23 cuda::detail_::enable_if_t<detail_::is_kinda_like_contiguous_container<ContiguousContainer>::value, bool>>
24 module_t context_t::create_module(ContiguousContainer module_data) const
25 {
26  return module::create<ContiguousContainer>(*this, module_data);
27 }
28 
29 template <typename ContiguousContainer,
30 cuda::detail_::enable_if_t<detail_::is_kinda_like_contiguous_container<ContiguousContainer>::value, bool>>
31 module_t context_t::create_module(ContiguousContainer module_data, const link::options_t& link_options) const
32 {
33  return module::create<ContiguousContainer>(*this, module_data, link_options);
34 }
35 
36 
37 // These API calls are not really the way you want to work.
38 inline cuda::kernel_t module_t::get_kernel(const char* name) const
39 {
40  CAW_SET_SCOPE_CONTEXT(context_handle_);
41  kernel::handle_t kernel_function_handle;
42  auto result = cuModuleGetFunction(&kernel_function_handle, handle_, name);
43  throw_if_error_lazy(result, ::std::string("Failed obtaining function ") + name
44  + " from " + module::detail_::identify(*this));
45  return kernel::wrap(context::detail_::get_device_id(context_handle_), context_handle_, kernel_function_handle);
46 }
47 
48 
49 namespace module {
50 
51 namespace detail_ {
52 
53 template <typename Creator>
54 module_t create(const context_t& context, const void* module_data, Creator creator_function)
55 {
56  CAW_SET_SCOPE_CONTEXT(context.handle());
57  handle_t new_module_handle;
58  auto status = creator_function(new_module_handle, module_data);
59  throw_if_error_lazy(status, ::std::string("Failed loading a module from memory location ")
60  + cuda::detail_::ptr_as_hex(module_data)
61  + " within " + context::detail_::identify(context));
62  bool do_take_ownership { true };
63  bool doesnt_hold_pc_refcount_unit { false };
64  // TODO: Do we want to allow holding a refcount unit here, if context is
65  // the primary context?
66 
67  // TODO: Make sure the default-constructed options correspond to what cuModuleLoadData uses as defaults
68  return detail_::wrap(
69  context.device_id(), context.handle(), new_module_handle,
70  do_take_ownership, doesnt_hold_pc_refcount_unit);
71 }
72 
73 // TODO: Consider adding create_module() methods to context_t
74 inline module_t create(const context_t& context, const void* module_data, const link::options_t& link_options)
75 {
76  auto creator_function =
77  [&link_options](handle_t& new_module_handle, const void* module_data_) {
78  auto marshalled_options = marshal(link_options);
79  return cuModuleLoadDataEx(
80  &new_module_handle,
81  module_data_,
82  marshalled_options.count(),
83  const_cast<link::option_t *>(marshalled_options.options()),
84  const_cast<void **>(marshalled_options.values())
85  );
86  };
87  return detail_::create(context, module_data, creator_function);
88 }
89 
90 inline module_t create(const context_t& context, const void* module_data)
91 {
92  auto creator_function =
93  [](handle_t& new_module_handle, const void* module_data_) {
94  return cuModuleLoadData(&new_module_handle, module_data_);
95  };
96  return detail_::create(context, module_data, creator_function);
97 }
98 
99 
100 
101 inline device::primary_context_t get_context_for(device_t& locus) { return locus.primary_context(); }
102 
103 } // namespace detail_
104 
105 inline module_t load_from_file(
106  const device_t& device,
107  const char* path)
108 {
109  auto pc = device.primary_context();
110  device::primary_context::detail_::increase_refcount(device.id());
111  return load_from_file(pc, path);
112 }
113 
114 inline module_t load_from_file(const char* path)
115 {
116  return load_from_file(device::current::get(), path);
117 }
118 
119 } // namespace module
120 
121 inline context_t module_t::context() const { return context::detail_::from_handle(context_handle_); }
122 inline device_t module_t::device() const { return device::get(context::detail_::get_device_id(context_handle_)); }
123 
124 #if CUDA_VERSION < 12000
125 inline CUsurfref module_t::get_surface(const char* name) const
126 {
127  CAW_SET_SCOPE_CONTEXT(context_handle_);
128  CUsurfref raw_surface_reference;
129  auto status = cuModuleGetSurfRef(&raw_surface_reference, handle_, name);
130  throw_if_error_lazy(status, ::std::string("Failed obtaining a reference to surface \"") + name + "\" from "
131  + module::detail_::identify(*this));
132  return raw_surface_reference;
133 }
134 
135 inline CUtexref module_t::get_texture_reference(const char* name) const
136 {
137  CAW_SET_SCOPE_CONTEXT(context_handle_);
138  CUtexref raw_texture_reference;
139  auto status = cuModuleGetTexRef(&raw_texture_reference, handle_, name);
140  throw_if_error_lazy(status, ::std::string("Failed obtaining a reference to texture \"") + name + "\" from "
141  + module::detail_::identify(*this));
142  return raw_texture_reference;
143 }
144 #endif
145 
146 
147 } // namespace cuda
148 
149 #endif // MULTI_WRAPPER_IMPLS_MODULE_HPP_
150 
Wrapper class for a CUDA context.
Definition: context.hpp:220
All definitions and functionality wrapping the CUDA Runtime API.
Definition: array.hpp:22
context::handle_t handle() const noexcept
The CUDA context ID this object is wrapping.
Definition: context.hpp:308
A class for holding the primary context of a CUDA device (device_t).
Definition: primary_context.hpp:110
cuda::kernel_t get_kernel(const char *name) const
Obtains an already-compiled kernel previously associated with this module.
Definition: module.hpp:38
Wrapper class for a CUDA code module.
Definition: module.hpp:97
Definition: kernel_launch.hpp:77
Implementations requiring the definitions of multiple CUDA entity proxy classes, and which regard con...
device::id_t device_id() const noexcept
The device with which this context is associated.
Definition: context.hpp:313