17#elif defined(USE_CUDA)
33#define START_GPU @autoreleasepool {
48 template<
float_scalar T,
bool SAFE_MATH=false>
52 std::ostringstream source_buffer;
56 std::vector<std::string> kernel_names;
58 std::map<std::string, texture1d_list> kernel_1dtextures;
60 std::map<std::string, texture2d_list> kernel_2dtextures;
63 using gpu_context_type =
typename std::conditional<use_gpu<T> (),
66#elif defined(USE_METAL)
74 gpu_context_type gpu_context;
88 const size_t num = gpu_context_type::max_concurrency();
89 std::cout <<
"Located " << num <<
" "
90 << gpu_context_type::device_type() <<
" device"
91 << (num == 1 ?
"." :
"s.")
101 context(
const size_t index) : gpu_context(index), used_random(false) {
102 source_buffer << std::setprecision(max_digits10<T> ());
103 gpu_context.create_header(source_buffer);
124 kernel_names.push_back(name);
126 if (state.get() && !used_random) {
132 std::vector<bool> is_constant(inputs.size(),
true);
137 for (
auto &[out, in] : setters) {
138 auto found = std::distance(inputs.begin(),
139 std::find(inputs.begin(),
141 if (found < is_constant.size()) {
142 is_constant[found] =
false;
144 out->compile_preamble(source_buffer, registers,
146 kernel_1dtextures[name],
147 kernel_2dtextures[name],
148 gpu_context.remaining_const_memory);
150 for (
auto &out : outputs) {
151 out->compile_preamble(source_buffer, registers,
153 kernel_1dtextures[name],
154 kernel_2dtextures[name],
155 gpu_context.remaining_const_memory);
158 for (
auto &in : inputs) {
159 if (usage.find(in.get()) == usage.end()) {
164 gpu_context.create_kernel_prefix(source_buffer,
165 name, inputs, outputs, state,
168 kernel_1dtextures[name],
169 kernel_2dtextures[name]);
172 for (
auto &[out, in] : setters) {
173 out->compile(source_buffer, registers, indices, usage);
175 for (
auto &out : outputs) {
176 out->compile(source_buffer, registers, indices, usage);
179 gpu_context.create_kernel_postfix(source_buffer, outputs,
181 registers, indices, usage);
184 std::vector<void *> removed_elements;
185 for (
auto &[key, value] : registers) {
186 if (value[0] ==
'r') {
187 removed_elements.push_back(key);
191 for (
auto &key : removed_elements) {
192 registers.erase(key);
202 gpu_context.create_reduction(source_buffer, size);
209 std::cout << std::endl << source_buffer.str() << std::endl;
216 std::string source = source_buffer.str();
217 std::ostringstream filename;
218 filename << std::hash<std::string> {} (source)
219 << std::hash<std::thread::id>{}(std::this_thread::get_id());
222 }
else if constexpr (use_metal<T> ()) {
223 filename <<
".metal";
228 std::ofstream outFile(filename.str());
238 void compile(
const bool add_reduction=
false) {
239#ifdef SAVE_KERNEL_SOURCE
242 gpu_context.compile(source_buffer.str(),
261 const size_t num_rays) {
262 return gpu_context.create_kernel_call(kernel_name, inputs, outputs, state, num_rays,
263 kernel_1dtextures[kernel_name],
264 kernel_2dtextures[kernel_name]);
275 std::function<
void(
void)> run) {
276 return gpu_context.create_max_call(argument, run);
287 gpu_context.print_results(index, nodes);
299 return gpu_context.check_value(index, node);
317 gpu_context.copy_to_device(node, source);
328 gpu_context.copy_to_host(node, destination);
337 return gpu_context.get_buffer(node);
Class representing a cpu context.
Definition cpu_context.hpp:82
Class representing a cuda gpu context.
Definition cuda_context.hpp:73
Class representing a metal gpu context.
Definition metal_context.hpp:25
static void compile_random(std::ostringstream &stream)
Write the preamble for the random function.
Definition random.hpp:314
static void compile_random_state(std::ostringstream &stream)
Write the preamble for the random state struct.
Definition random.hpp:31
Class for JIT compile of the GPU kernels.
Definition jit.hpp:49
void compile(const bool add_reduction=false)
Compile the kernel.
Definition jit.hpp:238
static constexpr size_t random_state_size
Size of random state needed.
Definition jit.hpp:80
static size_t max_concurrency()
Get the maximum number of concurrent instances.
Definition jit.hpp:87
void wait()
Wait for kernel to finish.
Definition jit.hpp:305
context(const size_t index)
Construct a jit context object.
Definition jit.hpp:101
std::function< T(void)> create_max_call(graph::shared_leaf< T, SAFE_MATH > &argument, std::function< void(void)> run)
Create a max compute kernel calling function.
Definition jit.hpp:274
void add_max_reduction(const size_t size)
Add max reduction kernel.
Definition jit.hpp:201
void save_source()
Save the kernel source code.
Definition jit.hpp:215
std::function< void(void)> create_kernel_call(const std::string kernel_name, graph::input_nodes< T, SAFE_MATH > inputs, graph::output_nodes< T, SAFE_MATH > outputs, graph::shared_random_state< T, SAFE_MATH > state, const size_t num_rays)
Create a kernel calling function.
Definition jit.hpp:257
void print(const size_t index, const graph::output_nodes< T, SAFE_MATH > &nodes)
Print output.
Definition jit.hpp:285
void copy_to_device(graph::shared_leaf< T, SAFE_MATH > &node, T *source)
Copy contexts of buffer to device.
Definition jit.hpp:315
T * get_buffer(graph::shared_leaf< T, SAFE_MATH > &node)
Get buffer from the gpu_context.
Definition jit.hpp:336
T check_value(const size_t index, const graph::shared_leaf< T, SAFE_MATH > &node)
Check the value.
Definition jit.hpp:297
void add_kernel(const std::string name, graph::input_nodes< T, SAFE_MATH > inputs, graph::output_nodes< T, SAFE_MATH > outputs, graph::map_nodes< T, SAFE_MATH > setters, graph::shared_random_state< T, SAFE_MATH > state, const size_t size)
Add a kernel.
Definition jit.hpp:118
void print_source()
Print the kernel source.
Definition jit.hpp:208
void copy_to_host(graph::shared_leaf< T, SAFE_MATH > &node, T *destination)
Copy contexts of buffer to host.
Definition jit.hpp:326
Cuda context for metal based gpus.
Metal context for metal based gpus.
std::shared_ptr< random_state_node< T, SAFE_MATH > > shared_random_state
Convenience type alias for shared sqrt nodes.
Definition random.hpp:270
std::vector< shared_variable< T, SAFE_MATH > > input_nodes
Convenience type alias for a vector of inputs.
Definition node.hpp:1711
std::shared_ptr< leaf_node< T, SAFE_MATH > > shared_leaf
Convenience type alias for shared leaf nodes.
Definition node.hpp:676
std::vector< std::pair< shared_leaf< T, SAFE_MATH >, shared_variable< T, SAFE_MATH > > > map_nodes
Convenience type alias for mapping end codes back to inputs.
Definition node.hpp:1715
std::vector< shared_leaf< T, SAFE_MATH > > output_nodes
Convenience type alias for a vector of output nodes.
Definition node.hpp:691
Name space for JIT functions.
Definition jit.hpp:41
std::map< void *, size_t > texture1d_list
Type alias for indexing 1D textures.
Definition register.hpp:263
std::map< void *, std::array< size_t, 2 > > texture2d_list
Type alias for indexing 2D textures.
Definition register.hpp:265
std::map< void *, size_t > register_usage
Type alias for counting register usage.
Definition register.hpp:259
std::map< void *, std::string > register_map
Type alias for mapping node pointers to register names.
Definition register.hpp:257
constexpr bool use_cuda()
Test to use Cuda.
Definition register.hpp:67
std::set< void * > visiter_map
Type alias for listing visited nodes.
Definition register.hpp:261