Graph Framework
Loading...
Searching...
No Matches
random.hpp
Go to the documentation of this file.
1//------------------------------------------------------------------------------
6//------------------------------------------------------------------------------
7
8#ifndef random_h
9#define random_h
10
11#include "node.hpp"
12
13namespace graph {
14//******************************************************************************
16//******************************************************************************
17//------------------------------------------------------------------------------
22//------------------------------------------------------------------------------
23 template<jit::float_scalar T, bool SAFE_MATH=false>
24 class random_state_node final : public leaf_node<T, SAFE_MATH> {
25 public:
26//------------------------------------------------------------------------------
30//------------------------------------------------------------------------------
31 static void compile_random_state(std::ostringstream &stream) {
32 stream << "struct mt_state {" << std::endl
33 << " array<uint32_t, 624> array;" << std::endl
34 << " uint16_t index;" << std::endl
35#ifdef USE_CUDA
36 << " uint16_t padding[3];" << std::endl
37#endif
38 << "};" << std::endl;
39 }
40
41//------------------------------------------------------------------------------
43//------------------------------------------------------------------------------
44 struct mt_state {
46 std::array<uint32_t, 624> array;
49#ifdef USE_CUDA
52#endif
53 };
54
55//------------------------------------------------------------------------------
60//------------------------------------------------------------------------------
61 random_state_node(const size_t size,
62 const uint32_t seed=0) :
63 leaf_node<T, SAFE_MATH> (random_state_node::to_string(), 1, false) {
64 for (uint32_t i = 0; i < size; i++) {
65 states.push_back(initialize_state(seed + i));
66 }
67 }
68
69//------------------------------------------------------------------------------
73//------------------------------------------------------------------------------
75 backend::buffer<T> result;
76 return result;
77 }
78
79//------------------------------------------------------------------------------
84//------------------------------------------------------------------------------
88
89//------------------------------------------------------------------------------
99//------------------------------------------------------------------------------
100 virtual void compile_preamble(std::ostringstream &stream,
101 jit::register_map &registers,
106 int &avail_const_mem) {
107 if (visited.find(this) == visited.end()) {
108 visited.insert(this);
109#ifdef SHOW_USE_COUNT
110 usage[this] = 1;
111 } else {
112 ++usage[this];
113#endif
114 }
115 }
116
117//------------------------------------------------------------------------------
125//------------------------------------------------------------------------------
127 compile(std::ostringstream &stream,
128 jit::register_map &registers,
130 const jit::register_usage &usage) {
131 return this->shared_from_this();
132 }
133
134//------------------------------------------------------------------------------
136//------------------------------------------------------------------------------
137 virtual void to_latex() const {
138 std::cout << "state";
139 }
140
141//------------------------------------------------------------------------------
147//------------------------------------------------------------------------------
148 virtual shared_leaf<T, SAFE_MATH> to_vizgraph(std::stringstream &stream,
149 jit::register_map &registers) {
150 if (registers.find(this) == registers.end()) {
151 const std::string name = jit::to_string('r', this);
152 registers[this] = name;
153 stream << " " << name
154 << " [label = \"state\", shape = box, style = \"rounded,filled\", fillcolor = black, fontcolor = white];" << std::endl;
155 }
156
157 return this->shared_from_this();
158 }
159
160//------------------------------------------------------------------------------
164//------------------------------------------------------------------------------
165 virtual bool is_all_variables() const {
166 return false;
167 }
168
169//------------------------------------------------------------------------------
173//------------------------------------------------------------------------------
175 return constant<T, SAFE_MATH> (static_cast<T> (1.0));
176 }
177
178//------------------------------------------------------------------------------
182//------------------------------------------------------------------------------
183 size_t size() {
184 return states.size();
185 }
186
187//------------------------------------------------------------------------------
191//------------------------------------------------------------------------------
192 size_t get_size_bytes() {
193 return size()*sizeof(mt_state);
194 }
195
196//------------------------------------------------------------------------------
200//------------------------------------------------------------------------------
202 return states.data();
203 }
204
205 private:
207 std::vector<mt_state> states;
208
209//------------------------------------------------------------------------------
213//------------------------------------------------------------------------------
214 static std::string to_string() {
215 return "random_state";
216 }
217
218//------------------------------------------------------------------------------
223//------------------------------------------------------------------------------
224 mt_state initialize_state(const uint32_t seed) {
225 mt_state state;
226 state.array[0] = seed;
227 for (uint16_t i = 1, ie = state.array.size(); i < ie; i++) {
228 state.array[i] = 1812433253U*(state.array[i - 1]^(state.array[i - 1] >> 30)) + i;
229 }
230 state.index = 0;
231
232 return state;
233 }
234 };
235
236//------------------------------------------------------------------------------
245//------------------------------------------------------------------------------
246 template<jit::float_scalar T, bool SAFE_MATH=false>
248 const uint32_t seed=0) {
249 auto temp = std::make_shared<random_state_node<T, SAFE_MATH>> (size, seed)->reduce();
250// Test for hash collisions.
251 for (size_t i = temp->get_hash();
253 if (leaf_node<T, SAFE_MATH>::caches.nodes.find(i) ==
256 return temp;
257 } else if (temp->is_match(leaf_node<T, SAFE_MATH>::caches.nodes[i])) {
259 }
260 }
261#if defined(__clang__) || defined(__GNUC__)
263#else
264 assert(false && "Should never reach.");
265#endif
266 }
267
269 template<jit::float_scalar T, bool SAFE_MATH=false>
270 using shared_random_state = std::shared_ptr<random_state_node<T, SAFE_MATH>>;
271
272//------------------------------------------------------------------------------
280//------------------------------------------------------------------------------
281 template<jit::float_scalar T, bool SAFE_MATH=false>
283 return std::dynamic_pointer_cast<random_state_node<T, SAFE_MATH>> (x);
284 }
285
286//******************************************************************************
287// Random constant.
288//******************************************************************************
289//------------------------------------------------------------------------------
294//------------------------------------------------------------------------------
295 template<jit::float_scalar T, bool SAFE_MATH=false>
296 class random_node final : public straight_node<T, SAFE_MATH> {
297 private:
298
299//------------------------------------------------------------------------------
303//------------------------------------------------------------------------------
304 static std::string to_string() {
305 return "random";
306 }
307
308 public:
309//------------------------------------------------------------------------------
313//------------------------------------------------------------------------------
314 static void compile_random(std::ostringstream &stream) {
315 jit::add_type<T> (stream);
316 stream << " random(";
317 if constexpr (jit::use_metal<T> ()) {
318 stream << "device ";
319 }
320 stream <<"mt_state &state) {" << std::endl
321 << " uint16_t k = state.index;" << std::endl
322 << " uint16_t j = (k + 1) % 624;" << std::endl
323 << " uint32_t x = (state.array[k] & 0x80000000U) |" << std::endl
324 << " (state.array[j] & 0x7fffffffU);" << std::endl
325 << " uint32_t xA = x >> 1;" << std::endl
326 << " if (x & 0x00000001U) {" << std::endl
327 << " xA ^= 0x9908b0dfU;" << std::endl
328 << " }" << std::endl
329 << " j = (k + 397) % 624;" << std::endl
330 << " x = state.array[j]^xA;" << std::endl
331 << " state.array[k] = x;" << std::endl
332 << " state.index = (k + 1) % 624;" << std::endl
333 << " uint32_t y = x^(x >> 11);" << std::endl
334 << " y = y^((y << 7) & 0x9d2c5680U);" << std::endl
335 << " y = y^((y << 15) & 0xefc60000U);" << std::endl
336 << " return static_cast<";
337 jit::add_type<T> (stream);
338 stream << "> (y^(y >> 18));" << std::endl
339 << "}" << std::endl;
340 }
341
342//------------------------------------------------------------------------------
346//------------------------------------------------------------------------------
349
350//------------------------------------------------------------------------------
354//------------------------------------------------------------------------------
356 backend::buffer<T> result;
357 return result;
358 }
359
360//------------------------------------------------------------------------------
367//------------------------------------------------------------------------------
371
372//------------------------------------------------------------------------------
382//------------------------------------------------------------------------------
383 virtual void compile_preamble(std::ostringstream &stream,
384 jit::register_map &registers,
389 int &avail_const_mem) {
390 if (visited.find(this) == visited.end()) {
391 this->arg->compile_preamble(stream, registers,
392 visited, usage,
395
396 visited.insert(this);
397#ifdef SHOW_USE_COUNT
398 usage[this] = 1;
399 } else {
400 ++usage[this];
401#endif
402 }
403 }
404
405//------------------------------------------------------------------------------
413//------------------------------------------------------------------------------
415 compile(std::ostringstream &stream,
416 jit::register_map &registers,
418 const jit::register_usage &usage) {
419 if (registers.find(this) == registers.end()) {
420 shared_leaf<T, SAFE_MATH> a = this->arg->compile(stream,
421 registers,
422 indices,
423 usage);
424
425 registers[this] = "random(" + registers[a.get()] + ")";
426 }
427
428 return this->shared_from_this();
429 }
430
431//------------------------------------------------------------------------------
441//------------------------------------------------------------------------------
443 return false;
444 }
445
446//------------------------------------------------------------------------------
448//------------------------------------------------------------------------------
449 virtual void to_latex() const {
450 std::cout << "random(";
451 this->arg->to_latex();
452 std::cout << ")";
453 }
454
455//------------------------------------------------------------------------------
461//------------------------------------------------------------------------------
462 virtual shared_leaf<T, SAFE_MATH> to_vizgraph(std::stringstream &stream,
463 jit::register_map &registers) {
464 if (registers.find(this) == registers.end()) {
465 const std::string name = jit::to_string('r', this);
466 registers[this] = name;
467 stream << " " << name
468 << " [label = \"state\", shape = box, style = \"rounded,filled\", fillcolor = black, fontcolor = white];" << std::endl;
469
470 auto a = this->arg->to_vizgraph(stream, registers);
471 stream << " " << name << " -- " << registers[a.get()] << ";" << std::endl;
472 }
473
474 return this->shared_from_this();
475 }
476
477//------------------------------------------------------------------------------
481//------------------------------------------------------------------------------
482 virtual bool is_all_variables() const {
483 return false;
484 }
485
486//------------------------------------------------------------------------------
490//------------------------------------------------------------------------------
492 return constant<T, SAFE_MATH> (static_cast<T> (1.0));
493 }
494 };
495
496//------------------------------------------------------------------------------
504//------------------------------------------------------------------------------
505 template<jit::float_scalar T, bool SAFE_MATH=false>
507 auto temp = std::make_shared<random_node<T, SAFE_MATH>> (state)->reduce();
508// Test for hash collisions.
509 for (size_t i = temp->get_hash();
511 if (leaf_node<T, SAFE_MATH>::caches.nodes.find(i) ==
514 return temp;
515 } else if (temp->is_match(leaf_node<T, SAFE_MATH>::caches.nodes[i])) {
517 }
518 }
519#if defined(__clang__) || defined(__GNUC__)
521#else
522 assert(false && "Should never reach.");
523#endif
524 }
525
527 template<jit::float_scalar T, bool SAFE_MATH=false>
528 using shared_random = std::shared_ptr<random_node<T, SAFE_MATH>>;
529
530//------------------------------------------------------------------------------
538//------------------------------------------------------------------------------
539 template<jit::float_scalar T, bool SAFE_MATH=false>
541 return std::dynamic_pointer_cast<random_node<T, SAFE_MATH>> (x);
542 }
543
544//------------------------------------------------------------------------------
551//------------------------------------------------------------------------------
552 template<jit::float_scalar T, bool SAFE_MATH=false>
554 return constant<T, SAFE_MATH> (static_cast<T> (std::numeric_limits<uint32_t>::max()));
555 }
556}
557
558#endif /* random_h */
Class representing a generic buffer.
Definition backend.hpp:29
Class representing a node leaf.
Definition node.hpp:364
Class representing a random_node leaf.
Definition random.hpp:296
virtual bool is_match(shared_leaf< T, SAFE_MATH > x)
Query if the nodes match.
Definition random.hpp:442
random_node(shared_random_state< T, SAFE_MATH > x)
Construct a constant node from a vector.
Definition random.hpp:347
virtual backend::buffer< T > evaluate()
Evaluate the results of random node.
Definition random.hpp:355
virtual shared_leaf< T, SAFE_MATH > get_power_exponent() const
Get the exponent of a power.
Definition random.hpp:491
virtual void to_latex() const
Convert the node to latex.
Definition random.hpp:449
static void compile_random(std::ostringstream &stream)
Write the preamble for the random function.
Definition random.hpp:314
virtual bool is_all_variables() const
Test if all the sub-nodes terminate in variables.
Definition random.hpp:482
virtual shared_leaf< T, SAFE_MATH > to_vizgraph(std::stringstream &stream, jit::register_map &registers)
Convert the node to vizgraph.
Definition random.hpp:462
virtual void compile_preamble(std::ostringstream &stream, jit::register_map &registers, jit::visiter_map &visited, jit::register_usage &usage, jit::texture1d_list &textures1d, jit::texture2d_list &textures2d, int &avail_const_mem)
Compile preamble.
Definition random.hpp:383
virtual shared_leaf< T, SAFE_MATH > compile(std::ostringstream &stream, jit::register_map &registers, jit::register_map &indices, const jit::register_usage &usage)
Compile the node.
Definition random.hpp:415
virtual shared_leaf< T, SAFE_MATH > df(shared_leaf< T, SAFE_MATH > x)
Transform node to derivative.
Definition random.hpp:368
Random state.
Definition random.hpp:24
virtual shared_leaf< T, SAFE_MATH > to_vizgraph(std::stringstream &stream, jit::register_map &registers)
Convert the node to vizgraph.
Definition random.hpp:148
size_t size()
Get the size of the random state vector in bytes.
Definition random.hpp:183
virtual shared_leaf< T, SAFE_MATH > compile(std::ostringstream &stream, jit::register_map &registers, jit::register_map &indices, const jit::register_usage &usage)
Compile the node.
Definition random.hpp:127
random_state_node(const size_t size, const uint32_t seed=0)
Construct a constant node from a vector.
Definition random.hpp:61
virtual bool is_all_variables() const
Test if all the sub-nodes terminate in variables.
Definition random.hpp:165
virtual shared_leaf< T, SAFE_MATH > df(shared_leaf< T, SAFE_MATH > x)
Transform node to derivative.
Definition random.hpp:85
virtual void to_latex() const
Convert the node to latex.
Definition random.hpp:137
virtual backend::buffer< T > evaluate()
Evaluate the results of random_state_node.
Definition random.hpp:74
virtual void compile_preamble(std::ostringstream &stream, jit::register_map &registers, jit::visiter_map &visited, jit::register_usage &usage, jit::texture1d_list &textures1d, jit::texture2d_list &textures2d, int &avail_const_mem)
Compile preamble.
Definition random.hpp:100
size_t get_size_bytes()
Get the size of the random state vector in bytes.
Definition random.hpp:192
virtual shared_leaf< T, SAFE_MATH > get_power_exponent() const
Get the exponent of a power.
Definition random.hpp:174
mt_state * data()
Get the size of the random state vector in bytes.
Definition random.hpp:201
static void compile_random_state(std::ostringstream &stream)
Write the preamble for the random state struct.
Definition random.hpp:31
Class representing a straight node.
Definition node.hpp:1051
shared_leaf< T, SAFE_MATH > arg
Argument.
Definition node.hpp:1054
subroutine assert(test, message)
Assert check.
Definition f_binding_test.f90:38
Name space for graph nodes.
Definition arithmetic.hpp:13
constexpr shared_leaf< T, SAFE_MATH > random_scale()
Create a random_scale constant.
Definition random.hpp:553
shared_random_state< T, SAFE_MATH > random_state_cast(shared_leaf< T, SAFE_MATH > x)
Cast to a random_state node.
Definition random.hpp:282
constexpr shared_leaf< T, SAFE_MATH > zero()
Forward declare for zero.
Definition node.hpp:986
shared_leaf< T, SAFE_MATH > random(shared_random_state< T, SAFE_MATH > state)
Define random convenience function.
Definition random.hpp:506
std::shared_ptr< random_state_node< T, SAFE_MATH > > shared_random_state
Convenience type alias for shared sqrt nodes.
Definition random.hpp:270
std::shared_ptr< random_node< T, SAFE_MATH > > shared_random
Convenience type alias for shared sqrt nodes.
Definition random.hpp:528
constexpr T i
Convenience type for imaginary constant.
Definition node.hpp:1018
std::shared_ptr< leaf_node< T, SAFE_MATH > > shared_leaf
Convenience type alias for shared leaf nodes.
Definition node.hpp:676
shared_random< T, SAFE_MATH > random_cast(shared_leaf< T, SAFE_MATH > x)
Cast to a random node.
Definition random.hpp:540
shared_leaf< T, SAFE_MATH > random_state(const size_t size, const uint32_t seed=0)
Define random_state convenience function.
Definition random.hpp:247
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
std::set< void * > visiter_map
Type alias for listing visited nodes.
Definition register.hpp:261
std::string to_string(const char prefix, const NODE *pointer)
Convert a graph::leaf_node pointer to a string.
Definition register.hpp:246
Base nodes of graph computation framework.
Random state structure.
Definition random.hpp:44
uint16_t index
State index.
Definition random.hpp:48
std::array< uint32_t, 624 > array
State array.
Definition random.hpp:46