Graph Framework
Loading...
Searching...
No Matches
workflow.hpp
Go to the documentation of this file.
1//------------------------------------------------------------------------------
6//------------------------------------------------------------------------------
7
8#ifndef workflow_h
9#define workflow_h
10
11#include "jit.hpp"
12
14namespace workflow {
24
25//------------------------------------------------------------------------------
30//------------------------------------------------------------------------------
31 template<jit::float_scalar T, bool SAFE_MATH=false>
32 class item {
33 public:
34//------------------------------------------------------------------------------
38//------------------------------------------------------------------------------
40
41//------------------------------------------------------------------------------
43//------------------------------------------------------------------------------
44 virtual void run() = 0;
45 };
46
47//------------------------------------------------------------------------------
52//------------------------------------------------------------------------------
53 template<jit::float_scalar T, bool SAFE_MATH=false>
54 class callback_item : public item<T, SAFE_MATH> {
55 protected:
57 std::function<void(void)> callback;
59 std::function<void(void)> kernel;
60
61 public:
62//------------------------------------------------------------------------------
66//------------------------------------------------------------------------------
67 callback_item(std::function<void(void)> callback) :
69
70//------------------------------------------------------------------------------
74//------------------------------------------------------------------------------
76 kernel = context.run_function(callback);
77 }
78
79//------------------------------------------------------------------------------
81//------------------------------------------------------------------------------
82 virtual void run() {
83 kernel();
84 }
85 };
86
87//------------------------------------------------------------------------------
92//------------------------------------------------------------------------------
93 template<jit::float_scalar T, bool SAFE_MATH=false>
94 class zero_item : public item<T, SAFE_MATH> {
95 protected:
97 std::function<void(void)> kernel;
100
101 public:
102//------------------------------------------------------------------------------
106//------------------------------------------------------------------------------
109
110//------------------------------------------------------------------------------
114//------------------------------------------------------------------------------
116 kernel = context.create_zero_call(inputs);
117 }
118
119//------------------------------------------------------------------------------
121//------------------------------------------------------------------------------
122 virtual void run() {
123 kernel();
124 }
125 };
126
127//------------------------------------------------------------------------------
132//------------------------------------------------------------------------------
133 template<jit::float_scalar T, bool SAFE_MATH=false>
134 class copy_item : public item<T, SAFE_MATH> {
135 protected:
137 std::function<void(void)> kernel;
140
141 public:
142//------------------------------------------------------------------------------
146//------------------------------------------------------------------------------
149
150//------------------------------------------------------------------------------
154//------------------------------------------------------------------------------
156 kernel = context.create_copy_call(maps);
157 }
158
159//------------------------------------------------------------------------------
161//------------------------------------------------------------------------------
162 virtual void run() {
163 kernel();
164 }
165 };
166
167//------------------------------------------------------------------------------
172//------------------------------------------------------------------------------
173 template<jit::float_scalar T, bool SAFE_MATH=false>
174 class work_item : public item<T, SAFE_MATH> {
175 protected:
177 std::function<void(void)> kernel;
179 const std::string kernel_name;
181 const size_t kernel_size;
190
191 public:
192//------------------------------------------------------------------------------
203//------------------------------------------------------------------------------
209 const std::string name, const size_t size,
211 inputs(in), outputs(out), atomics(atomics), state(state),
212 kernel_name(name), kernel_size(size) {
213 context.add_kernel(name, in, out, maps, atomics, state, size);
214 }
215
216//------------------------------------------------------------------------------
220//------------------------------------------------------------------------------
225
226//------------------------------------------------------------------------------
228//------------------------------------------------------------------------------
229 virtual void run() {
230 kernel();
231 }
232 };
233
234//------------------------------------------------------------------------------
239//------------------------------------------------------------------------------
240 template<jit::float_scalar T, bool SAFE_MATH=false>
241 class loop_item final : public item<T, SAFE_MATH> {
242 protected:
244 std::function<void(void)> kernel;
246 const std::string kernel_name;
248 const size_t kernel_size;
257
258 public:
259//------------------------------------------------------------------------------
271//------------------------------------------------------------------------------
277 const std::string name, const size_t size,
279 const size_t iterations) :
281 kernel_name(name), kernel_size(size) {
282 context.add_kernel(name, in, out, maps, atomics,
283 state, size, iterations);
284 }
285
286//------------------------------------------------------------------------------
290//------------------------------------------------------------------------------
295
296//------------------------------------------------------------------------------
298//------------------------------------------------------------------------------
299 virtual void run() {
300 kernel();
301 }
302 };
303
304//------------------------------------------------------------------------------
309//------------------------------------------------------------------------------
310 template<jit::float_scalar T, bool SAFE_MATH=false>
311 class converge_item final : public work_item<T, SAFE_MATH> {
312 private:
314 std::function<T(void)> max_kernel;
316 const T tolerance;
318 const size_t max_iterations;
319
320 public:
321//------------------------------------------------------------------------------
334//------------------------------------------------------------------------------
340 const std::string name, const size_t size,
342 const T tol=1.0E-30,
343 const size_t max_iter=1000) :
344 work_item<T, SAFE_MATH> (inputs, outputs, maps, atomics,
345 state, name, size, context),
346 tolerance(tol), max_iterations(max_iter) {
347 context.add_max_reduction(size);
348 }
349
350//------------------------------------------------------------------------------
354//------------------------------------------------------------------------------
357 max_kernel = context.create_max_call(this->outputs.back(),
358 this->kernel);
359 }
360
361//------------------------------------------------------------------------------
363//------------------------------------------------------------------------------
364 virtual void run() {
365 size_t iterations = 0;
366 T max_residual = max_kernel();
367 T last_max = std::numeric_limits<T>::max();
368 T off_last_max = std::numeric_limits<T>::max();
369 while (std::abs(max_residual) > std::abs(tolerance) &&
370 std::abs(last_max - max_residual) > std::abs(tolerance) &&
371 std::abs(off_last_max - max_residual) > std::abs(tolerance) &&
372 iterations++ < max_iterations) {
373 last_max = max_residual;
374 if (!(iterations%2)) {
375 off_last_max = max_residual;
376 }
377 max_residual = max_kernel();
378 }
379
380// In release mode asserts are disables so write error to standard err. Need to
381// flip the comparison operator because we want to assert to trip if false.
382 assert(iterations < max_iterations &&
383 "Workitem failed to converge.");
384 if (iterations > max_iterations) {
385 std::cerr << "Workitem failed to converge with in given iterations."
386 << std::endl;
387 std::cerr << "Minimum residual reached: " << max_residual
388 << std::endl;
389 }
390 }
391 };
392
393//------------------------------------------------------------------------------
398//------------------------------------------------------------------------------
399 template<jit::float_scalar T, bool SAFE_MATH=false>
400 class manager {
401 private:
405 std::vector<std::unique_ptr<item<T, SAFE_MATH>>> preitems;
407 std::vector<std::unique_ptr<item<T, SAFE_MATH>>> items;
409 std::vector<std::unique_ptr<item<T, SAFE_MATH>>> postitems;
411 bool add_reduction;
412
413 public:
414//------------------------------------------------------------------------------
424//------------------------------------------------------------------------------
425 manager(const size_t index) : context(index), add_reduction(false) {}
426
427//------------------------------------------------------------------------------
433//------------------------------------------------------------------------------
434 template<order O=run_item>
435 void add_callback_item(std::function<void(void)> callback) {
436 if constexpr (O == pre_run_item) {
437 preitems.push_back(std::make_unique<callback_item<T, SAFE_MATH>> (callback));
438 } else if constexpr (O == run_item) {
439 items.push_back(std::make_unique<callback_item<T, SAFE_MATH>> (callback));
440 } else {
441 postitems.push_back(std::make_unique<callback_item<T, SAFE_MATH>> (callback));
442 }
443 }
444
445//------------------------------------------------------------------------------
457//------------------------------------------------------------------------------
458 template<order O=run_item>
464 const std::string name, const size_t size) {
465 if constexpr (O == pre_run_item) {
466 preitems.push_back(std::make_unique<work_item<T, SAFE_MATH>> (in, out,
467 maps,
468 atomics,
469 state,
470 name, size,
471 context));
472 } else if constexpr (O == run_item) {
473 items.push_back(std::make_unique<work_item<T, SAFE_MATH>> (in, out,
474 maps,
475 atomics,
476 state,
477 name, size,
478 context));
479 } else {
480 postitems.push_back(std::make_unique<work_item<T, SAFE_MATH>> (in, out,
481 maps,
482 atomics,
483 state,
484 name, size,
485 context));
486 }
487 }
488
489//------------------------------------------------------------------------------
495//------------------------------------------------------------------------------
496 template<order O=run_item>
498 if constexpr (O == pre_run_item) {
499 preitems.push_back(std::make_unique<zero_item<T, SAFE_MATH>> (in));
500 } else if constexpr (O == run_item) {
501 items.push_back(std::make_unique<zero_item<T, SAFE_MATH>> (in));
502 } else {
503 postitems.push_back(std::make_unique<zero_item<T, SAFE_MATH>> (in));
504 }
505 }
506
507//------------------------------------------------------------------------------
513//------------------------------------------------------------------------------
514 template<order O=run_item>
516 if constexpr (O == pre_run_item) {
517 preitems.push_back(std::make_unique<copy_item<T, SAFE_MATH>> (maps));
518 } else if constexpr (O == run_item) {
519 items.push_back(std::make_unique<copy_item<T, SAFE_MATH>> (maps));
520 } else {
521 postitems.push_back(std::make_unique<copy_item<T, SAFE_MATH>> (maps));
522 }
523 }
524
525//------------------------------------------------------------------------------
538//------------------------------------------------------------------------------
539 template<order O=run_item>
545 const std::string name, const size_t size,
546 const size_t iterations) {
547 if constexpr (O == pre_run_item) {
548 preitems.push_back(std::make_unique<loop_item<T, SAFE_MATH>> (in, out,
549 maps,
550 atomics,
551 state,
552 name, size,
553 context,
554 iterations));
555 } else if constexpr (O == run_item) {
556 items.push_back(std::make_unique<loop_item<T, SAFE_MATH>> (in, out,
557 maps,
558 atomics,
559 state,
560 name, size,
561 context,
562 iterations));
563 } else {
564 postitems.push_back(std::make_unique<loop_item<T, SAFE_MATH>> (in, out,
565 maps,
566 atomics,
567 state,
568 name, size,
569 context,
570 iterations));
571 }
572 }
573
574//------------------------------------------------------------------------------
588//------------------------------------------------------------------------------
589 template<order O=run_item>
595 const std::string name, const size_t size,
596 const T tol=1.0E-30,
597 const size_t max_iter=1000) {
598 add_reduction = true;
599 if constexpr (O == pre_run_item) {
600 items.push_back(std::make_unique<converge_item<T, SAFE_MATH>> (in, out,
601 maps,
602 atomics,
603 state,
604 name, size,
605 context, tol,
606 max_iter));
607 } else if constexpr (O == run_item) {
608 items.push_back(std::make_unique<converge_item<T, SAFE_MATH>> (in, out,
609 maps,
610 atomics,
611 state,
612 name, size,
613 context, tol,
614 max_iter));
615 } else {
616 postitems.push_back(std::make_unique<converge_item<T, SAFE_MATH>> (in, out,
617 maps,
618 atomics,
619 state,
620 name, size,
621 context, tol,
622 max_iter));
623 }
624 }
625
626//------------------------------------------------------------------------------
628//------------------------------------------------------------------------------
629 void compile() {
630 context.compile(add_reduction);
631
632 for (auto &item : preitems) {
633 item->create_kernel_call(context);
634 }
635 for (auto &item : items) {
636 item->create_kernel_call(context);
637 }
638 for (auto &item : postitems) {
639 item->create_kernel_call(context);
640 }
641 }
642
643//------------------------------------------------------------------------------
647//------------------------------------------------------------------------------
648 template<order O=run_item>
649 void run() {
650 if constexpr (O == pre_run_item) {
651 for (auto &item : preitems) {
652 item->run();
653 }
654 } else if constexpr (O == run_item) {
655 for (auto &item : items) {
656 item->run();
657 }
658 } else {
659 for (auto &item : postitems) {
660 item->run();
661 }
662 }
663 }
664
665//------------------------------------------------------------------------------
667//------------------------------------------------------------------------------
668 void wait() {
669 context.wait();
670 }
671
672//------------------------------------------------------------------------------
677//------------------------------------------------------------------------------
679 T *destination) {
680 context.copy_to_device(node, destination);
681 }
682
683//------------------------------------------------------------------------------
688//------------------------------------------------------------------------------
690 T *destination) {
691 context.copy_to_host(node, destination);
692 }
693
694//------------------------------------------------------------------------------
699//------------------------------------------------------------------------------
700 void print(const size_t index,
702 context.print(index, nodes);
703 }
704
705//------------------------------------------------------------------------------
711//------------------------------------------------------------------------------
712 T check_value(const size_t index,
714 return context.check_value(index, node);
715 }
716
717//------------------------------------------------------------------------------
721//------------------------------------------------------------------------------
723 return context;
724 }
725 };
726}
727
728#endif /* workflow_h */
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
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
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 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 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 copy_to_host(graph::shared_leaf< T, SAFE_MATH > &node, T *destination)
Copy contexts of buffer to host.
Definition jit.hpp:384
Callback item.
Definition workflow.hpp:54
std::function< void(void)> callback
Callback function.
Definition workflow.hpp:57
callback_item(std::function< void(void)> callback)
Construct a workflow item.
Definition workflow.hpp:67
virtual void run()
Run the work item.
Definition workflow.hpp:82
std::function< void(void)> kernel
Kernel function.
Definition workflow.hpp:59
virtual void create_kernel_call(jit::context< T, SAFE_MATH > &context)
Set the kernel function.
Definition workflow.hpp:75
Class representing a convergence work item.
Definition workflow.hpp:311
virtual void create_kernel_call(jit::context< T, SAFE_MATH > &context)
Set the kernel function.
Definition workflow.hpp:355
converge_item(graph::input_nodes< T, SAFE_MATH > &inputs, graph::output_nodes< T, SAFE_MATH > &outputs, graph::map_nodes< T, SAFE_MATH > &maps, graph::input_nodes< T, SAFE_MATH > &atomics, graph::shared_random_state< T, SAFE_MATH > &state, const std::string name, const size_t size, jit::context< T, SAFE_MATH > &context, const T tol=1.0E-30, const size_t max_iter=1000)
Construct a workflow item.
Definition workflow.hpp:335
virtual void run()
Run the workitem.
Definition workflow.hpp:364
Copy one buffer item to another.
Definition workflow.hpp:134
graph::copy_nodes< T, SAFE_MATH > maps
Input nodes.
Definition workflow.hpp:139
copy_item(graph::copy_nodes< T, SAFE_MATH > maps)
Construct a workflow item.
Definition workflow.hpp:147
std::function< void(void)> kernel
Kernel function.
Definition workflow.hpp:137
virtual void create_kernel_call(jit::context< T, SAFE_MATH > &context)
Set the kernel function.
Definition workflow.hpp:155
virtual void run()
Run the work item.
Definition workflow.hpp:162
Interface class representing items.
Definition workflow.hpp:32
virtual void run()=0
Run the work item.
virtual void create_kernel_call(jit::context< T, SAFE_MATH > &context)=0
Set the kernel function.
Run a work item in a fixed iteration loop.
Definition workflow.hpp:241
graph::input_nodes< T, SAFE_MATH > inputs
Input nodes.
Definition workflow.hpp:250
loop_item(graph::input_nodes< T, SAFE_MATH > &in, graph::output_nodes< T, SAFE_MATH > &out, graph::map_nodes< T, SAFE_MATH > &maps, graph::input_nodes< T, SAFE_MATH > &atomics, graph::shared_random_state< T, SAFE_MATH > &state, const std::string name, const size_t size, jit::context< T, SAFE_MATH > &context, const size_t iterations)
Construct a workflow item.
Definition workflow.hpp:272
graph::shared_random_state< T, SAFE_MATH > state
Random state node.
Definition workflow.hpp:256
graph::input_nodes< T, SAFE_MATH > atomics
Atomic nodes.
Definition workflow.hpp:254
graph::output_nodes< T, SAFE_MATH > outputs
Output nodes.
Definition workflow.hpp:252
virtual void create_kernel_call(jit::context< T, SAFE_MATH > &context)
Set the kernel function.
Definition workflow.hpp:291
const size_t kernel_size
Size of the GPU kernel.
Definition workflow.hpp:248
virtual void run()
Run the workitem.
Definition workflow.hpp:299
std::function< void(void)> kernel
Kernel function.
Definition workflow.hpp:244
const std::string kernel_name
Name of the GPU kernel.
Definition workflow.hpp:246
Class representing a workflow manager.
Definition workflow.hpp:400
void add_item(graph::input_nodes< T, SAFE_MATH > in, graph::output_nodes< T, SAFE_MATH > out, graph::map_nodes< T, SAFE_MATH > maps, graph::input_nodes< T, SAFE_MATH > atomics, graph::shared_random_state< T, SAFE_MATH > state, const std::string name, const size_t size)
Add a workflow item.
Definition workflow.hpp:459
void add_callback_item(std::function< void(void)> callback)
Add a pre callback function.
Definition workflow.hpp:435
void wait()
Wait for GPU queue to finish.
Definition workflow.hpp:668
void add_copy_item(graph::copy_nodes< T, SAFE_MATH > maps)
Add a copy item.
Definition workflow.hpp:515
void copy_to_host(graph::shared_leaf< T, SAFE_MATH > &node, T *destination)
Copy contexts of buffer to host.
Definition workflow.hpp:689
void add_converge_item(graph::input_nodes< T, SAFE_MATH > in, graph::output_nodes< T, SAFE_MATH > out, graph::map_nodes< T, SAFE_MATH > maps, graph::input_nodes< T, SAFE_MATH > atomics, graph::shared_random_state< T, SAFE_MATH > state, const std::string name, const size_t size, const T tol=1.0E-30, const size_t max_iter=1000)
Add a converge item.
Definition workflow.hpp:590
void run()
Run work items.
Definition workflow.hpp:649
void print(const size_t index, const graph::output_nodes< T, SAFE_MATH > &nodes)
Print results.
Definition workflow.hpp:700
void add_loop_item(graph::input_nodes< T, SAFE_MATH > in, graph::output_nodes< T, SAFE_MATH > out, graph::map_nodes< T, SAFE_MATH > maps, graph::input_nodes< T, SAFE_MATH > atomics, graph::shared_random_state< T, SAFE_MATH > state, const std::string name, const size_t size, const size_t iterations)
Add a loop item.
Definition workflow.hpp:540
void copy_to_device(graph::shared_leaf< T, SAFE_MATH > &node, T *destination)
Copy buffer contents to the device.
Definition workflow.hpp:678
jit::context< T, SAFE_MATH > & get_context()
Get the jit context.
Definition workflow.hpp:722
manager(const size_t index)
Workflow manager constructor.
Definition workflow.hpp:425
void add_zero_item(graph::input_nodes< T, SAFE_MATH > in)
Add a zero item.
Definition workflow.hpp:497
void compile()
Compile the workflow items.
Definition workflow.hpp:629
T check_value(const size_t index, const graph::shared_leaf< T, SAFE_MATH > &node)
Check the value.
Definition workflow.hpp:712
Class representing a work item.
Definition workflow.hpp:174
virtual void run()
Run the work item.
Definition workflow.hpp:229
const std::string kernel_name
Name of the GPU kernel.
Definition workflow.hpp:179
virtual void create_kernel_call(jit::context< T, SAFE_MATH > &context)
Set the kernel function.
Definition workflow.hpp:221
graph::shared_random_state< T, SAFE_MATH > state
Random state node.
Definition workflow.hpp:189
graph::input_nodes< T, SAFE_MATH > inputs
Input nodes.
Definition workflow.hpp:183
work_item(graph::input_nodes< T, SAFE_MATH > &in, graph::output_nodes< T, SAFE_MATH > &out, graph::map_nodes< T, SAFE_MATH > &maps, graph::input_nodes< T, SAFE_MATH > &atomics, graph::shared_random_state< T, SAFE_MATH > &state, const std::string name, const size_t size, jit::context< T, SAFE_MATH > &context)
Construct a workflow item.
Definition workflow.hpp:204
graph::input_nodes< T, SAFE_MATH > atomics
Atomic nodes.
Definition workflow.hpp:187
const size_t kernel_size
Size of the GPU kernel.
Definition workflow.hpp:181
graph::output_nodes< T, SAFE_MATH > outputs
Output nodes.
Definition workflow.hpp:185
std::function< void(void)> kernel
Kernel function.
Definition workflow.hpp:177
Clear buffer item.
Definition workflow.hpp:94
virtual void run()
Run the work item.
Definition workflow.hpp:122
std::function< void(void)> kernel
Kernel function.
Definition workflow.hpp:97
virtual void create_kernel_call(jit::context< T, SAFE_MATH > &context)
Set the kernel function.
Definition workflow.hpp:115
graph::input_nodes< T, SAFE_MATH > inputs
Input nodes.
Definition workflow.hpp:99
zero_item(graph::input_nodes< T, SAFE_MATH > in)
Construct a workflow item.
Definition workflow.hpp:107
subroutine assert(test, message)
Assert check.
Definition f_binding_test.f90:38
Class to just in time compile a kernel.
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 workflows.
Definition workflow.hpp:14
order
Items order.
Definition workflow.hpp:16
@ pre_run_item
Pre items.
Definition workflow.hpp:18
@ post_run_item
Post items.
Definition workflow.hpp:22
@ run_item
Items.
Definition workflow.hpp:20