17#elif defined(USE_CUDA)
33#define START_GPU @autoreleasepool {
48 template<
float_scalar T,
bool SAFE_MATH=false>
52 std::ostringstream source_buffer;
58 std::vector<std::string> kernel_names;
60 std::unordered_map<std::string, texture1d_list> kernel_1dtextures;
62 std::unordered_map<std::string, texture2d_list> kernel_2dtextures;
65 using gpu_context_type =
typename std::conditional<use_gpu<T> (),
68#elif defined(USE_METAL)
76 gpu_context_type gpu_context;
98 const size_t num = gpu_context_type::max_concurrency();
99 std::cout <<
"Located " << num <<
" "
100 << gpu_context_type::device_type() <<
" device"
101 << (num == 1 ?
"." :
"s.")
111 context(
const size_t index) : gpu_context(index) {
112 source_buffer << std::setprecision(max_digits10<T> ());
113 gpu_context.create_header(source_buffer);
137 const size_t iterations=1) {
138 kernel_names.push_back(name);
140 std::vector<bool> is_constant(inputs.size(),
true);
145 for (
auto &[out, in] : setters) {
146 auto found = std::distance(inputs.begin(),
147 std::find(inputs.begin(),
149 if (found < is_constant.size()) {
150 is_constant[found] =
false;
152 out->compile_preamble(source_buffer, registers,
154 kernel_1dtextures[name],
155 kernel_2dtextures[name],
157 gpu_context.remaining_const_memory);
159 for (
auto &out : outputs) {
160 out->compile_preamble(source_buffer, registers,
162 kernel_1dtextures[name],
163 kernel_2dtextures[name],
165 gpu_context.remaining_const_memory);
168 for (
auto &in : inputs) {
169 if (usage.find(in.get()) == usage.end()) {
177 gpu_context.create_kernel_prefix(source_buffer,
178 name, inputs, outputs,
182 kernel_1dtextures[name],
183 kernel_2dtextures[name],
188 for (
auto &[out, in] : setters) {
189 out->compile(source_buffer, registers, thread_mem, usage);
191 for (
auto &out : outputs) {
192 out->compile(source_buffer, registers, thread_mem, usage);
195 gpu_context.create_kernel_postfix(source_buffer, outputs,
203 std::vector<void *> removed_elements;
204 for (
auto &[key, value] : registers) {
205 if (value[0] ==
'r' ||
208 removed_elements.push_back(key);
211 for (
auto &out : outputs) {
213 removed_elements.push_back(out.get());
217 for (
auto &key : removed_elements) {
218 registers.erase(key);
228 gpu_context.create_reduction(source_buffer, size);
238 return gpu_context.create_zero_call(inputs);
248 return gpu_context.create_copy_call(setters);
255 std::cout << std::endl << source_buffer.str() << std::endl;
262 std::string source = source_buffer.str();
263 std::ostringstream filename;
264 filename << std::hash<std::string> {} (source)
265 << std::hash<std::thread::id>{}(std::this_thread::get_id());
268 }
else if constexpr (use_metal<T> ()) {
269 filename <<
".metal";
274 std::ofstream outFile(filename.str());
284 void compile(
const bool add_reduction=
false) {
285#ifdef SAVE_KERNEL_SOURCE
288 gpu_context.compile(source_buffer.str(),
309 const size_t num_rays) {
310 return gpu_context.create_kernel_call(kernel_name, inputs, outputs,
311 atomics, state, num_rays,
312 kernel_1dtextures[kernel_name],
313 kernel_2dtextures[kernel_name]);
324 std::function<
void(
void)> run) {
325 return gpu_context.create_max_call(argument, run);
336 gpu_context.print_results(index, nodes);
348 return gpu_context.check_value(index, node);
363 std::function<void(
void)>
run_function(std::function<
void(
void)> callback) {
364 return gpu_context.run_function(callback);
375 gpu_context.copy_to_device(node, source);
386 gpu_context.copy_to_host(node, destination);
395 return gpu_context.get_buffer(node);
Class representing a cpu context.
Definition cpu_context.hpp:83
Class representing a cuda gpu context.
Definition cuda_context.hpp:74
Class representing a metal gpu context.
Definition metal_context.hpp:25
Class for JIT compile of the GPU kernels.
Definition jit.hpp:49
std::function< void(void)> create_copy_call(graph::copy_nodes< T, SAFE_MATH > setters)
Add copy.
Definition jit.hpp:247
void compile(const bool add_reduction=false)
Compile the kernel.
Definition jit.hpp:284
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:97
void wait()
Wait for kernel to finish.
Definition jit.hpp:354
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::input_nodes< T, SAFE_MATH > atomics, graph::shared_random_state< T, SAFE_MATH > state, const size_t num_rays)
Create a kernel calling function.
Definition jit.hpp:304
context(const size_t index)
Construct a jit context object.
Definition jit.hpp:111
static size_t max_random_state_size(const size_t size)
Get the number of random states needed.
Definition jit.hpp:88
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:323
std::function< void(void)> create_zero_call(graph::input_nodes< T, SAFE_MATH > inputs)
Add zero.
Definition jit.hpp:237
void add_max_reduction(const size_t size)
Add max reduction kernel.
Definition jit.hpp:227
void save_source()
Save the kernel source code.
Definition jit.hpp:261
void print(const size_t index, const graph::output_nodes< T, SAFE_MATH > &nodes)
Print output.
Definition jit.hpp:334
void copy_to_device(graph::shared_leaf< T, SAFE_MATH > &node, T *source)
Copy contexts of buffer to device.
Definition jit.hpp:373
T * get_buffer(graph::shared_leaf< T, SAFE_MATH > &node)
Get buffer from the gpu_context.
Definition jit.hpp:394
T check_value(const size_t index, const graph::shared_leaf< T, SAFE_MATH > &node)
Check the value.
Definition jit.hpp:346
std::function< void(void)> run_function(std::function< void(void)> callback)
Run a function.
Definition jit.hpp:363
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::input_nodes< T, SAFE_MATH > &atomics, graph::shared_random_state< T, SAFE_MATH > &state, const size_t size, const size_t iterations=1)
Add a kernel.
Definition jit.hpp:130
void print_source()
Print the kernel source.
Definition jit.hpp:254
void copy_to_host(graph::shared_leaf< T, SAFE_MATH > &node, T *destination)
Copy contexts of buffer to host.
Definition jit.hpp:384
Cuda context for metal based gpus.
Metal context for metal based gpus.
shared_atomic_accumulate_1D< T, SAFE_MATH > atomic_accumulate_1D_cast(shared_leaf< T, SAFE_MATH > x)
Cast to a atomic accumulate 1D node.
Definition piecewise.hpp:2426
std::shared_ptr< random_state_node< T, SAFE_MATH > > shared_random_state
Convenience type alias for shared sqrt nodes.
Definition random.hpp:269
std::vector< shared_variable< T, SAFE_MATH > > input_nodes
Convenience type alias for a vector of inputs.
Definition node.hpp:2149
std::vector< std::pair< shared_variable< T, SAFE_MATH >, shared_variable< T, SAFE_MATH > > > copy_nodes
Convenience type alias for copying buffers.
Definition node.hpp:2157
std::shared_ptr< leaf_node< T, SAFE_MATH > > shared_leaf
Convenience type alias for shared leaf nodes.
Definition node.hpp:691
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:2153
std::vector< shared_leaf< T, SAFE_MATH > > output_nodes
Convenience type alias for a vector of output nodes.
Definition node.hpp:706
Name space for JIT functions.
Definition jit.hpp:41
std::unordered_set< void * > visiter_map
Type alias for listing visited nodes.
Definition register.hpp:263
std::unordered_map< void *, size_t > register_usage
Type alias for counting register usage.
Definition register.hpp:261
std::unordered_set< std::string > preamble_map
Type alias for preamble defined functions.
Definition register.hpp:269
std::unordered_map< void *, std::string > register_map
Type alias for mapping node pointers to register names.
Definition register.hpp:259
constexpr bool use_cuda()
Test to use Cuda.
Definition register.hpp:68
std::unordered_map< void *, std::array< size_t, 2 > > texture2d_list
Type alias for indexing 2D textures.
Definition register.hpp:267
std::unordered_map< void *, size_t > texture1d_list
Type alias for indexing 1D textures.
Definition register.hpp:265
std::unordered_set< void * > argument_set
Type for tacking thread shared memory.
Definition register.hpp:271