RockyML  0.0.1
A High-Performance Scientific Computing Framework
dena.h
1 /*
2  Copyright (C) 2022 Amirabbas Asadi , All Rights Reserved
3  distributed under Apache-2.0 license
4 */
5 #ifndef ROCKY_ZAGROS_DENA_GUARD
6 #define ROCKY_ZAGROS_DENA_GUARD
7 
8 #include<vector>
9 #include<deque>
10 #include<map>
11 #include<stack>
12 #include<type_traits>
13 #include<variant>
14 
15 #include<rocky/zagros/strategies/log.h>
16 
17 
18 namespace rocky{
19 namespace zagros{
20 
21 namespace dena{
22 
23 
28 struct flow_node{
29  // a unique identifier
30  int tag;
31 };
32 
33 struct null_node: public flow_node{};
34 
35 struct container_node: public flow_node{};
37  std::string id;
38  int n_particles;
39  int group_size;
40 };
42  std::string des;
43  std::string src;
44 };
46  std::string id;
47 };
48 
49 struct init_node: public flow_node{};
51  std::string id;
52 };
53 struct init_normal_node: public init_node{};
54 
55 struct log_node: public flow_node{};
57  std::string id;
58  local_log_handler* handler;
59 };
61  std::string id;
62  comet_log_handler* handler;
63 };
64 
65 struct comm_node: public flow_node{};
67  std::string id;
68 };
69 
70 struct pso_node: public flow_node{};
72  std::string memory_id;
73  std::string main_cnt_id;
74 };
75 struct pso_step_node: public pso_node{
76  std::string memory_id;
77  std::string main_cnt_id;
78 };
81 
82 struct mutate_node: public flow_node{};
84  std::string id;
85  int dims;
86  float mu;
87  float sigma;
88 };
89 
90 struct crossover_node: public flow_node{};
92  std::string id;
93  int dims;
94 };
96  std::string id;
97  float crossover_prob;
98  float differential_weight;
99 };
101  std::string id;
102  int segment_length;
103 };
104 
105 struct eda_node: public flow_node{};
106 struct eda_mvn_node: public eda_node{};
108  std::string id;
109 };
110 
111 struct analysis_node: public flow_node{};
112 struct plot_node: public analysis_node{};
114  int width;
115  int height;
116  std::string label;
117 };
119  std::string id;
121 };
122 
123 struct bcd_node: public flow_node{};
124 enum bcd_mask_generator { uniform };
125 struct bcd_mask_node: public bcd_node{
126  bcd_mask_generator generator;
127 };
128 
129 struct run_node: public flow_node{
130  std::vector<int> sub_procedure;
131 };
133  std::string id;
134  int max_check;
135 };
137  float prob;
138 };
139 struct run_n_times_node: public run_node{
140  int n_iters;
141 };
143  int period;
144 };
145 
146 
147 // a variant containing all nodes
148 typedef std::variant<log_local_best_node,
170  run_until_no_improve_node> flow_node_variant;
171 
172 class node{
173 public:
174  static std::vector<flow_node_variant>& nodes(){
175  static std::vector<flow_node_variant> nodes_;
176  return nodes_;
177  }
178  static std::map<int, int>& next_node(){
179  static std::map<int, int> next_node_;
180  return next_node_;
181  }
182  template<typename T_n>
183  static int register_node(T_n flow_node){
184  flow_node.tag = node::nodes().size();
185  node::nodes().push_back(flow_node);
186  next_node()[flow_node.tag] = -1;
187  return flow_node.tag;
188  }
189  static void register_link(int s, int e){
190  node::next_node()[s] = e;
191  }
192  static int next(int tag){
193  return node::next_node()[tag];
194  }
195 };
196 
197 class flow{
198 public:
199  std::vector<int> procedure;
200  size_t total_memory;
201 
202  flow& operator >>(const flow& f){
203  // concat the two procedures
204  auto last_node = procedure.back();
205  auto first_node = f.procedure.front();
206  node::register_link(last_node, first_node);
207  this->procedure.insert(this->procedure.end(), f.procedure.begin(), f.procedure.end());
208  return *this;
209  }
210 };
211 
216 class container{
217 public:
226  static flow create(std::string id, int n_particles, int group_size){
227  flow f;
229  node.id = id;
230  node.n_particles = n_particles;
231  node.group_size = group_size;
232  auto node_tag = node::register_node<>(node);
233  f.procedure.push_back(node_tag);
234  return f;
235  }
236  static flow create(std::string id, int n_particles){
237  return create(id, n_particles, n_particles);
238  }
239  static flow create(std::string id){
240  return create(id, 1, 1);
241  }
250  static flow take_best(std::string des, std::string src){
251  flow f;
253  node.des = des;
254  node.src = src;
255  auto node_tag = node::register_node<>(node);
256  f.procedure.push_back(node_tag);
257  return f;
258  }
265  static flow eval(std::string id){
266  flow f;
268  node.id = id;
269  auto node_tag = node::register_node<>(node);
270  f.procedure.push_back(node_tag);
271  return f;
272  }
273 };
274 
279 class utils{
280 public:
285  static std::string temp_name(int tag){
286  return fmt::format("__temp__T[{}]__", tag);
287  }
292  static std::string temp_name(int tag, std::string desc){
293  return fmt::format("__temp__{}__{}__", tag, desc);
294  }
295 };
296 
301 class init{
302 public:
308  static flow uniform(std::string id){
309  flow f;
311  node.id = id;
312  auto node_tag = node::register_node<>(node);
313  f.procedure.push_back(node_tag);
314  return f;
315  }
316 }; // end of init
317 
318 namespace log{
319 class local{
320 public:
326  static flow best(std::string id, local_log_handler& handler){
327  flow f;
329  node.id = id;
330  node.handler = &handler;
331  auto node_tag = node::register_node<>(node);
332  f.procedure.push_back(node_tag);
333  return f;
334  }
335  // an overload of the best function which selects the best continer automatically
336  static flow best(local_log_handler& handler){
337  return best("__best__", handler);
338  }
339 }; // end of local
340 
341 class comet{
342 public:
348  static flow best(std::string id, comet_log_handler& handler){
349  flow f;
351  node.id = id;
352  node.handler = &handler;
353  auto node_tag = node::register_node<>(node);
354  f.procedure.push_back(node_tag);
355  return f;
356  }
357  // an overload of the best function which selects the best continer automatically
358  static flow best(comet_log_handler& handler){
359  return best(std::string("__best__"), handler);
360  }
361 }; // end of comet
362 
363 }; // end of log
364 
365 namespace block{
369 class uniform{
370 public:
371  static flow select(){
372  flow f;
374  node.generator = bcd_mask_generator::uniform;
375  auto node_tag = node::register_node<>(node);
376  f.procedure.push_back(node_tag);
377  return f;
378  }
379 }; // end of uniform
380 }; // end of blocked descent
381 
382 
383 namespace propagate{
384 class cluster{
385 public:
392 static flow best(std::string id){
393  flow f;
395  node.id = id;
396  auto node_tag = node::register_node<>(node);
397  f.procedure.push_back(node_tag);
398  return f;
399 }
400 }; // end of cluster
401 }; // end of comm
402 
407 class run{
408 public:
416  static flow n_times(int iters, const flow& wrapped_flow){
417  flow f;
419  node.n_iters = iters;
420  node.sub_procedure.insert(node.sub_procedure.end(), wrapped_flow.procedure.begin(), wrapped_flow.procedure.end());
421  auto node_tag = node::register_node<>(node);
422  f.procedure.push_back(node_tag);
423  return f;
424  }
432  static flow with_probability(float prob, const flow& wrapped_flow){
433  flow f;
435  node.prob = prob;
436  node.sub_procedure.insert(node.sub_procedure.end(), wrapped_flow.procedure.begin(), wrapped_flow.procedure.end());
437  auto node_tag = node::register_node<>(node);
438  f.procedure.push_back(node_tag);
439  return f;
440  }
448  static flow every_n_steps(int n, const flow& wrapped_flow){
449  flow f;
451  node.period = n;
452  node.sub_procedure.insert(node.sub_procedure.end(), wrapped_flow.procedure.begin(), wrapped_flow.procedure.end());
453  auto node_tag = node::register_node<>(node);
454  f.procedure.push_back(node_tag);
455  return f;
456  }
465  static flow while_improve(std::string id, int n, const flow& wrapped_flow){
466  flow f;
468  node.id = id;
469  node.max_check = n;
470  node.sub_procedure.insert(node.sub_procedure.end(), wrapped_flow.procedure.begin(), wrapped_flow.procedure.end());
471  auto node_tag = node::register_node<>(node);
472  f.procedure.push_back(node_tag);
473  return f;
474  }
482  static flow while_improve(int n, const flow& wrapped_flow){
483  return while_improve(std::string("__best__"), n, wrapped_flow);
484  }
491  static flow while_improve(const flow& wrapped_flow){
492  return while_improve(std::string("__best__"), 20, wrapped_flow);
493  }
494 
495 }; // end of init
496 
497 
498 namespace pso{
503 class memory{
504 public:
512  static flow create(std::string mem_id, std::string main_id){
513  flow f;
515  node.memory_id = mem_id;
516  node.main_cnt_id = main_id;
517  auto node_tag = node::register_node<>(node);
518  f.procedure.push_back(node_tag);
519  return f;
520  }
527  static std::string particles_vel(std::string base){
528  return base + std::string("__pvel__");
529  }
536  static std::string particles_mem(std::string base){
537  return base + std::string("__pmem__");
538  }
545  static std::string groups_mem(std::string base){
546  return base + std::string("__gmem__");
547  }
554  static std::string node_mem(std::string base){
555  return base + std::string("__nmem__");
556  }
563  static std::string cluster_mem(std::string base){
564  return base + std::string("__cmem__");
565  }
566 }; // end of memory
567 
572 class local{
573 public:
581  static flow step(std::string mem_id, std::string main_id){
582  flow f;
584  node.memory_id = mem_id;
585  node.main_cnt_id = main_id;
586  auto node_tag = node::register_node<>(node);
587  f.procedure.push_back(node_tag);
588  return f;
589  }
590 }; // end of group level
591 
596 class global{
597 public:
605  static flow step(std::string mem_id, std::string main_id){
606  flow f;
608  node.memory_id = mem_id;
609  node.main_cnt_id = main_id;
610  auto node_tag = node::register_node<>(node);
611  f.procedure.push_back(node_tag);
612  return f;
613  }
614 }; // end of group level
615 
616 }; // end of pso
617 
618 class mutate{
619 public:
629  static flow gaussian(std::string id, int dims=1, float mu=0.0, float sigma=1.0){
630  flow f;
632  node.id = id;
633  node.dims = dims;
634  node.mu = mu;
635  node.sigma = sigma;
636  auto node_tag = node::register_node<>(node);
637  f.procedure.push_back(node_tag);
638  return f;
639  }
640 
641 }; // end of mutate
642 
643 class crossover{
644 public:
652  static flow multipoint(std::string id, int dims=1){
653  flow f;
655  node.id = id;
656  node.dims = dims;
657  auto node_tag = node::register_node<>(node);
658  f.procedure.push_back(node_tag);
659  return f;
660  }
669  static flow differential_evolution(std::string id, float cr=0.9, float dw=0.9){
670  flow f;
672  node.id = id;
673  node.crossover_prob = cr;
674  node.differential_weight = dw;
675  auto node_tag = node::register_node<>(node);
676  f.procedure.push_back(node_tag);
677  return f;
678  }
679  static flow segment(std::string id, int segment_length){
680  flow f;
682  node.id = id;
683  node.segment_length = segment_length;
684  auto node_tag = node::register_node<>(node);
685  f.procedure.push_back(node_tag);
686  return f;
687  }
688 
689 }; // end of mutate
690 
695 namespace eda{
700 class mvn{
701 public:
709  static flow full_cov(std::string id){
710  flow f;
712  node.id = id;
713  auto node_tag = node::register_node<>(node);
714  f.procedure.push_back(node_tag);
715  return f;
716  }
717 }; // end of mvn
718 }; // end of eda
719 
724 namespace analyze{
725 
730 class plot{
731 public:
740  static flow heatmap(std::string label, int width, int height){
741  flow f;
743  node.label = label;
744  node.width = width;
745  node.height = height;
746  auto node_tag = node::register_node<>(node);
747  f.procedure.push_back(node_tag);
748  return f;
749  }
750  static flow heatmap(std::string label, int width){
751  return heatmap(label, width, width);
752  }
753  static flow heatmap(std::string label){
754  return heatmap(label, 500);
755  }
756  static flow heatmap(){
757  return heatmap(std::string("heatmap"));
758  }
766  static flow container(std::string id, container_analysis_handler& handler){
767  flow f;
769  node.id = id;
770  node.handler = &handler;
771  auto node_tag = node::register_node<>(node);
772  f.procedure.push_back(node_tag);
773  return f;
774  }
775 }; // end of plot
776 
777 }; // end of analysis
778 
779 }; // end of dena
780 }; // end of zagros
781 }; // end of rocky
782 #endif
rocky::zagros::dena::flow_node
abstract flow node
Definition: dena.h:28
rocky::zagros::dena::container::eval
static flow eval(std::string id)
evaluate all solutions in a container
Definition: dena.h:265
rocky::zagros::dena::container::create
static flow create(std::string id, int n_particles, int group_size)
create a solution
Definition: dena.h:226
rocky::zagros::comet_log_handler
Definition: log.h:99
rocky::zagros::dena::pso::memory::particles_vel
static std::string particles_vel(std::string base)
id of particles velocity
Definition: dena.h:527
rocky::zagros::dena::pso::global::step
static flow step(std::string mem_id, std::string main_id)
single step based on pso-l3
Definition: dena.h:605
rocky::zagros::dena::utils::temp_name
static std::string temp_name(int tag)
generate the name for temporal containers
Definition: dena.h:285
rocky::zagros::dena::mutate
Definition: dena.h:618
rocky::zagros::dena::block::uniform
factories for uniform BCD strategy *
Definition: dena.h:369
rocky::zagros::dena::analysis_node
Definition: dena.h:111
rocky::zagros::dena::pso_node
Definition: dena.h:70
rocky::zagros::dena::container_create_node
Definition: dena.h:36
rocky::zagros::dena::utils::temp_name
static std::string temp_name(int tag, std::string desc)
generate the name for temporal containers
Definition: dena.h:292
rocky::zagros::dena::init_uniform_node
Definition: dena.h:50
rocky::zagros::dena::node
Definition: dena.h:172
rocky::zagros::dena::plot_heatmap_node
Definition: dena.h:113
rocky::zagros::dena::init_normal_node
Definition: dena.h:53
rocky::zagros::dena::log::local::best
static flow best(std::string id, local_log_handler &handler)
local logging strategies
Definition: dena.h:326
rocky::zagros::dena::pso::memory::node_mem
static std::string node_mem(std::string base)
id of node memory
Definition: dena.h:554
rocky::zagros::dena::pso::global
cluster level particle convergence
Definition: dena.h:596
rocky::zagros::dena::run::n_times
static flow n_times(int iters, const flow &wrapped_flow)
run the wrapped flow n times [todo] there is a problem with the last node
Definition: dena.h:416
rocky::zagros::dena::container
factories for soultion containers
Definition: dena.h:216
rocky::zagros::dena::utils
utils for dena
Definition: dena.h:279
rocky::zagros::local_log_handler
Definition: log.h:27
rocky::zagros::dena::flow
Definition: dena.h:197
rocky::zagros::dena::analyze::plot
utilities for plotting loss function or optimization stage
Definition: dena.h:730
rocky::zagros::dena::pso::memory::cluster_mem
static std::string cluster_mem(std::string base)
id of cluster memory
Definition: dena.h:563
rocky::zagros::dena::crossover_differential_evolution_node
Definition: dena.h:95
rocky::zagros::dena::crossover::multipoint
static flow multipoint(std::string id, int dims=1)
multipoint crossover
Definition: dena.h:652
rocky::zagros::dena::container_select_from_node
Definition: dena.h:41
rocky::zagros::dena::log::comet::best
static flow best(std::string id, comet_log_handler &handler)
local logging strategies
Definition: dena.h:348
rocky::zagros::dena::crossover::differential_evolution
static flow differential_evolution(std::string id, float cr=0.9, float dw=0.9)
differential evolution
Definition: dena.h:669
rocky::zagros::dena::pso::memory::groups_mem
static std::string groups_mem(std::string base)
id of groups memory
Definition: dena.h:545
rocky::zagros::dena::init_node
Definition: dena.h:49
rocky::zagros::dena::eda_mvn_node
Definition: dena.h:106
rocky::zagros::dena::analyze::plot::container
static flow container(std::string id, container_analysis_handler &handler)
record the position of particles at each step
Definition: dena.h:766
rocky::zagros::dena::container::take_best
static flow take_best(std::string des, std::string src)
take best solutions from another container only if any of the solutions in source was better than any...
Definition: dena.h:250
rocky::zagros::dena::container_recorder_node
Definition: dena.h:118
rocky::zagros::dena::pso_cluster_level_step_node
Definition: dena.h:80
rocky::zagros::dena::pso::local::step
static flow step(std::string mem_id, std::string main_id)
single step based on pso-l1
Definition: dena.h:581
rocky::zagros::dena::run
factories for composable flows
Definition: dena.h:407
rocky::zagros::dena::propagate::cluster::best
static flow best(std::string id)
propagate the best solution across nodes
Definition: dena.h:392
rocky::zagros::dena::comm_node
Definition: dena.h:65
rocky::zagros::dena::pso::memory
utilities for manipulating pso memory
Definition: dena.h:503
rocky::zagros::dena::eda::mvn
mutivariate normal EDA
Definition: dena.h:700
rocky::zagros::dena::comm_cluster_prop_best_node
Definition: dena.h:66
rocky::zagros::dena::bcd_mask_node
Definition: dena.h:125
rocky::zagros::dena::pso::local
group level particle convergence
Definition: dena.h:572
rocky::zagros::dena::propagate::cluster
Definition: dena.h:384
rocky::zagros::dena::mutate_gaussian_node
Definition: dena.h:83
rocky::zagros::dena::bcd_node
Definition: dena.h:123
rocky::zagros::dena::run_node
Definition: dena.h:129
rocky::zagros::dena::container_eval_node
Definition: dena.h:45
rocky::zagros::dena::eda::mvn::full_cov
static flow full_cov(std::string id)
Multivariate Normal with Full Covariance Matrix.
Definition: dena.h:709
rocky::zagros::dena::mutate_node
Definition: dena.h:82
rocky::zagros::dena::init::uniform
static flow uniform(std::string id)
initialize particles uniformly
Definition: dena.h:308
rocky::zagros::dena::run_until_no_improve_node
Definition: dena.h:132
rocky::zagros::dena::log_node
Definition: dena.h:55
rocky::zagros::dena::pso::memory::create
static flow create(std::string mem_id, std::string main_id)
creating a node for pso memory allocation
Definition: dena.h:512
rocky::zagros::dena::eda_mvn_fullcov_node
Definition: dena.h:107
rocky::zagros::dena::pso_memory_create_node
Definition: dena.h:71
rocky::zagros::dena::crossover_segment_node
Definition: dena.h:100
rocky::zagros::dena::run::while_improve
static flow while_improve(std::string id, int n, const flow &wrapped_flow)
run a flow until the best solution of a container does not improve
Definition: dena.h:465
rocky::zagros::dena::crossover_node
Definition: dena.h:90
rocky::zagros::container_analysis_handler
Definition: analysis.h:104
rocky::zagros::dena::run::while_improve
static flow while_improve(int n, const flow &wrapped_flow)
run a flow until the best solution does not improve
Definition: dena.h:482
rocky::zagros::dena::run_every_n_steps_node
Definition: dena.h:142
rocky::zagros::dena::log::local
Definition: dena.h:319
rocky::zagros::dena::null_node
Definition: dena.h:33
rocky::zagros::dena::crossover
Definition: dena.h:643
rocky::zagros::dena::run::every_n_steps
static flow every_n_steps(int n, const flow &wrapped_flow)
run a flow with given period
Definition: dena.h:448
rocky::zagros::dena::run_with_probability_node
Definition: dena.h:136
rocky::zagros::dena::log_local_best_node
Definition: dena.h:56
rocky::zagros::dena::run::with_probability
static flow with_probability(float prob, const flow &wrapped_flow)
run a flow with a specified probability
Definition: dena.h:432
rocky::zagros::dena::run_n_times_node
Definition: dena.h:139
rocky::zagros::dena::pso_step_node
Definition: dena.h:75
rocky::zagros::dena::crossover_multipoint_node
Definition: dena.h:91
rocky::zagros::dena::analyze::plot::heatmap
static flow heatmap(std::string label, int width, int height)
plotting a heatmap of loss function
Definition: dena.h:740
rocky::zagros::dena::init
factories for initialization strategies
Definition: dena.h:301
rocky::zagros::dena::pso::memory::particles_mem
static std::string particles_mem(std::string base)
id of particles memory
Definition: dena.h:536
rocky::zagros::dena::eda_node
Definition: dena.h:105
rocky::zagros::dena::log_comet_best_node
Definition: dena.h:60
rocky::zagros::dena::pso_group_level_step_node
Definition: dena.h:79
rocky::zagros::dena::run::while_improve
static flow while_improve(const flow &wrapped_flow)
run a flow until the best solution does not improve
Definition: dena.h:491
rocky::zagros::dena::container_node
Definition: dena.h:35
rocky::zagros::dena::log::comet
Definition: dena.h:341
rocky::zagros::dena::plot_node
Definition: dena.h:112
rocky::zagros::dena::mutate::gaussian
static flow gaussian(std::string id, int dims=1, float mu=0.0, float sigma=1.0)
Gaussian mutation.
Definition: dena.h:629