Commit 630d24de by FritzFlorian

Restructure to allow a clean interface for end users.

We need some tricks in template programming to have a clean user facing API while internally using our classes with more capabilities.
parent 552fefb3
// Headers are available because we added the pls target
#include <string>
#include <cstdio>
#include <tuple>
#include <pls/pls.h>
#include <pls/dataflow/inputs.h>
#include <pls/dataflow/outputs.h>
#include <pls/dataflow/graph.h>
int main() {
pls::dataflow::inputs<int, std::string> in;
pls::dataflow::outputs<int> out1;
pls::dataflow::outputs<std::string> out2;
using namespace pls::dataflow;
out1.get<0>().connect(in.get<0>());
out2.get<0>().connect(in.get<1>());
graph<inputs<int>, outputs<int, int>, 8> graph;
}
......@@ -10,12 +10,12 @@ add_library(pls STATIC
include/pls/algorithms/scan_impl.h
include/pls/dataflow/dataflow.h
include/pls/dataflow/token.h
include/pls/dataflow/internal/token.h
include/pls/dataflow/graph.h
include/pls/dataflow/inputs.h
include/pls/dataflow/outputs.h
include/pls/dataflow/input.h
include/pls/dataflow/output.h
include/pls/dataflow/internal/inputs.h
include/pls/dataflow/internal/outputs.h
include/pls/dataflow/internal/input.h
include/pls/dataflow/internal/output.h
include/pls/internal/base/spin_lock.h
include/pls/internal/base/tas_spin_lock.h src/internal/base/tas_spin_lock.cpp
......@@ -47,7 +47,7 @@ add_library(pls STATIC
include/pls/internal/scheduling/scheduler_impl.h
include/pls/internal/scheduling/task.h src/internal/scheduling/task.cpp
include/pls/internal/scheduling/scheduler_memory.h src/internal/scheduling/scheduler_memory.cpp
include/pls/internal/scheduling/lambda_task.h)
include/pls/internal/scheduling/lambda_task.h include/pls/dataflow/inputs.h include/pls/dataflow/outputs.h)
# Add everything in `./include` to be in the include path of this project
target_include_directories(pls
PUBLIC
......
......@@ -2,14 +2,17 @@
#ifndef PLS_DATAFLOW_GRAPH_H_
#define PLS_DATAFLOW_GRAPH_H_
#include "inputs.h"
#include "outputs.h"
namespace pls {
namespace dataflow {
template<
template<typename I, typename O, int P>
class graph {
using internal_inputs = typename I::template internal_inputs<P>;
using internal_outputs = typename O::template internal_outputs<P>;
};
}
}
......
......@@ -4,21 +4,15 @@
#include <tuple>
#include "input.h"
#include "internal/inputs.h"
namespace pls {
namespace dataflow {
template<typename I1, typename ...I>
class inputs {
using values_type = std::tuple<input<I1>, input<I>...>;
values_type values_;
public:
template<int N>
typename std::tuple_element<N, values_type>::type &get() {
return std::get<N>(values_);
}
struct inputs {
template<int P>
using internal_inputs = internal::inputs<P, I1, I...>;
};
}
......
#ifndef PLS_DATAFLOW_INPUT_H_
#define PLS_DATAFLOW_INPUT_H_
#ifndef PLS_DATAFLOW_INTERNAL_INPUT_H_
#define PLS_DATAFLOW_INTERNAL_INPUT_H_
#include "token.h"
......@@ -8,6 +8,7 @@
namespace pls {
namespace dataflow {
namespace internal {
template<typename T>
class input {
......@@ -26,16 +27,19 @@ class input {
connected_ = true;
}
public:
input() : filled_{false}, connected_{false} {};
bool has_token(color color) const {
bool has_token(token_color color) const {
return filled_ && token_.color() == color;
}
const token<T> &get_token() const { return token_; }
public:
};
}
}
}
#endif //PLS_DATAFLOW_INPUT_H_
#endif //PLS_DATAFLOW_INTERNAL_INPUT_H_
#ifndef PLS_DATAFLOW_OUTPUT_H_
#define PLS_DATAFLOW_OUTPUT_H_
#ifndef PLS_DATAFLOW_INTERNAL_OUTPUT_H_
#define PLS_DATAFLOW_INTERNAL_OUTPUT_H_
#include "token.h"
#include "input.h"
......@@ -9,6 +9,7 @@
namespace pls {
namespace dataflow {
namespace internal {
template<typename T>
class output {
......@@ -31,5 +32,6 @@ class output {
}
}
}
#endif //PLS_DATAFLOW_OUTPUT_H_
#endif //PLS_DATAFLOW_INTERNAL_OUTPUT_H_
#ifndef PLS_DATAFLOW_TOKEN_H_
#define PLS_DATAFLOW_TOKEN_H_
#ifndef PLS_DATAFLOW_INTERNAL_TOKEN_H_
#define PLS_DATAFLOW_INTERNAL_TOKEN_H_
namespace pls {
namespace dataflow {
namespace internal {
/**
* Parallel invocations of the same sub-graph are usually working with some kind of coloring
* for tokens to distinguishe different invocations. As this concept is abstract and we could
* change it in the future (for e.g. more advanced features/dataflows) we encapsulate it.
*/
struct color {
struct token_color {
unsigned int clock_;
};
template<typename T>
class token {
T value_;
color color_;
token_color color_;
public:
T value() const { return value_; }
color color() const { return color_; }
token_color color() const { return color_; }
};
}
}
}
#endif //PLS_DATAFLOW_TOKEN_H_
#endif //PLS_DATAFLOW_INTERNAL_TOKEN_H_
......@@ -2,23 +2,16 @@
#ifndef PLS_DATAFLOW_OUTPUTS_H_
#define PLS_DATAFLOW_OUTPUTS_H_
#include <tuple>
#include "output.h"
#include "internal/outputs.h"
#include "outputs.h"
namespace pls {
namespace dataflow {
template<typename O1, typename ...O>
class outputs {
using values_type = std::tuple<output<O1>, output<O>...>;
values_type values_;
public:
template<int N>
typename std::tuple_element<N, values_type>::type &get() {
return std::get<N>(values_);
}
struct outputs {
template<int P>
using internal_outputs = internal::outputs<P, O1, O...>;
};
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment