main.cpp 3.02 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
#include <pls/pls.h>
8 9
#include <pls/dataflow/internal/inputs.h>
#include <pls/dataflow/internal/outputs.h>
10
#include <pls/dataflow/internal/function_node.h>
11
#include <pls/dataflow/internal/graph.h>
12 13 14
#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{minus_one};

33 34 35 36 37
  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};

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

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

51 52
  // Connect

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

  // 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();
71

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

  // Build
  graph.build();

79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
  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;
  });
94
}