main.cpp 3.15 KB
Newer Older
1
// Headers are available because we added the pls target
2 3
#include <string>
#include <cstdio>
4
#include <tuple>
5
#include <array>
6

7 8 9 10 11 12 13 14
#include "pls/pls.h"
#include "pls/dataflow/internal/inputs.h"
#include "pls/dataflow/internal/outputs.h"
#include "pls/dataflow/internal/function_node.h"
#include "pls/dataflow/internal/graph.h"
#include "pls/dataflow/internal/switch_node.h"
#include "pls/dataflow/internal/split_node.h"
#include "pls/dataflow/internal/merge_node.h"
15

16
int main() {
17
  using namespace pls::dataflow;
18 19
  using namespace pls::dataflow::internal;

20 21
  // Define
  graph<inputs<int, int>, outputs<int>> graph;
22

23 24
  auto triple = [](const int &i1, int &o1) {
    o1 = i1 * 3;
25
  };
26
  function_node<inputs<int>, outputs<int>, decltype(triple)> triple_node{triple};
27

28 29
  auto minus_one = [](const int &i1, int &o1) {
    o1 = i1 - 1;
30
  };
31 32
  function_node<inputs<int>, outputs<int>, decltype(minus_one)> minus_one_node_1{minus_one};
  function_node<inputs<int>, outputs<int>, decltype(minus_one)> minus_one_node_2{minus_one};
33

34 35 36 37 38
  auto is_positive = [](const int &i1, bool &o1) {
    o1 = i1 > 0;
  };
  function_node<inputs<int>, outputs<bool>, decltype(is_positive)> is_positive_node{is_positive};

39
  auto recursion = [&](const int &i1, const int &i2, int &o1) {
40 41 42 43
    std::tuple<int> out;
    graph.run({i1, i2}, out);
    pls::scheduler::wait_for_all();
    o1 = std::get<0>(out);
44 45
  };
  function_node<inputs<int, int>, outputs<int>, decltype(recursion)> recursion_node{recursion};
46

47 48 49 50 51
  split_node<int> minus_split;
  split_node<bool> decision_split;
  switch_node<int> recursion_split;
  merge_node<int> recursion_merge;

52
  // Connect
53
  minus_one_node_1 >> minus_one_node_2;
54

55
  // Inputs to first processing step
56
  graph.input<0>() >> minus_one_node_1.in_port<0>();
57
  graph.input<1>() >> triple_node.in_port<0>();
58
  minus_one_node_2.out_port<0>() >> minus_split.value_in_port();
59 60 61 62 63 64 65 66 67 68 69 70 71 72

  // Prepare decision...
  minus_split.out_port_1() >> is_positive_node.in_port<0>();
  is_positive_node.out_port<0>() >> decision_split.value_in_port();
  triple_node.out_port<0>() >> recursion_split.value_in_port();
  decision_split.out_port_1() >> recursion_split.condition_in_port();

  // Connect true case (recursion)
  minus_split.out_port_2() >> recursion_node.in_port<0>();
  recursion_split.true_out_port() >> recursion_node.in_port<1>();
  recursion_node.out_port<0>() >> recursion_merge.true_in_port();

  // Connect false case (no recursion)
  recursion_split.false_out_port() >> recursion_merge.false_in_port();
73

74 75 76
  // Deliver final result (back from merge)
  decision_split.out_port_2() >> recursion_merge.condition_in_port();
  recursion_merge.value_out_port() >> graph.output<0>();
77 78 79 80

  // Build
  graph.build();

81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
  pls::malloc_scheduler_memory my_scheduler_memory{8, 2u << 18u};
  pls::scheduler scheduler{&my_scheduler_memory, 8};
  scheduler.perform_work([&] {
    // Schedule Execution
    std::tuple<int> out1, out2, out3;
    graph.run({1, 2}, out1);
    graph.run({1, 1}, out2);
    graph.run({5, 6}, out3);

    // Wait for results and print
    pls::scheduler::wait_for_all();
    std::cout << std::get<0>(out1) << std::endl;
    std::cout << std::get<0>(out2) << std::endl;
    std::cout << std::get<0>(out3) << std::endl;
  });
96
}