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 // Headers are available because we added the pls target
#include <string> #include <string>
#include <cstdio> #include <cstdio>
#include <tuple>
#include <pls/pls.h> #include <pls/pls.h>
#include <pls/dataflow/inputs.h> #include <pls/dataflow/graph.h>
#include <pls/dataflow/outputs.h>
int main() { int main() {
pls::dataflow::inputs<int, std::string> in; using namespace pls::dataflow;
pls::dataflow::outputs<int> out1;
pls::dataflow::outputs<std::string> out2;
out1.get<0>().connect(in.get<0>()); graph<inputs<int>, outputs<int, int>, 8> graph;
out2.get<0>().connect(in.get<1>());
} }
...@@ -10,12 +10,12 @@ add_library(pls STATIC ...@@ -10,12 +10,12 @@ add_library(pls STATIC
include/pls/algorithms/scan_impl.h include/pls/algorithms/scan_impl.h
include/pls/dataflow/dataflow.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/graph.h
include/pls/dataflow/inputs.h include/pls/dataflow/internal/inputs.h
include/pls/dataflow/outputs.h include/pls/dataflow/internal/outputs.h
include/pls/dataflow/input.h include/pls/dataflow/internal/input.h
include/pls/dataflow/output.h include/pls/dataflow/internal/output.h
include/pls/internal/base/spin_lock.h include/pls/internal/base/spin_lock.h
include/pls/internal/base/tas_spin_lock.h src/internal/base/tas_spin_lock.cpp include/pls/internal/base/tas_spin_lock.h src/internal/base/tas_spin_lock.cpp
...@@ -47,7 +47,7 @@ add_library(pls STATIC ...@@ -47,7 +47,7 @@ add_library(pls STATIC
include/pls/internal/scheduling/scheduler_impl.h include/pls/internal/scheduling/scheduler_impl.h
include/pls/internal/scheduling/task.h src/internal/scheduling/task.cpp 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/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 # Add everything in `./include` to be in the include path of this project
target_include_directories(pls target_include_directories(pls
PUBLIC PUBLIC
......
...@@ -2,14 +2,17 @@ ...@@ -2,14 +2,17 @@
#ifndef PLS_DATAFLOW_GRAPH_H_ #ifndef PLS_DATAFLOW_GRAPH_H_
#define PLS_DATAFLOW_GRAPH_H_ #define PLS_DATAFLOW_GRAPH_H_
#include "inputs.h"
#include "outputs.h"
namespace pls { namespace pls {
namespace dataflow { namespace dataflow {
template< template<typename I, typename O, int P>
class graph { class graph {
using internal_inputs = typename I::template internal_inputs<P>;
using internal_outputs = typename O::template internal_outputs<P>;
}; };
} }
} }
......
...@@ -4,21 +4,15 @@ ...@@ -4,21 +4,15 @@
#include <tuple> #include <tuple>
#include "input.h" #include "internal/inputs.h"
namespace pls { namespace pls {
namespace dataflow { namespace dataflow {
template<typename I1, typename ...I> template<typename I1, typename ...I>
class inputs { struct inputs {
using values_type = std::tuple<input<I1>, input<I>...>; template<int P>
values_type values_; using internal_inputs = internal::inputs<P, I1, I...>;
public:
template<int N>
typename std::tuple_element<N, values_type>::type &get() {
return std::get<N>(values_);
}
}; };
} }
......
#ifndef PLS_DATAFLOW_INPUT_H_ #ifndef PLS_DATAFLOW_INTERNAL_INPUT_H_
#define PLS_DATAFLOW_INPUT_H_ #define PLS_DATAFLOW_INTERNAL_INPUT_H_
#include "token.h" #include "token.h"
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
namespace pls { namespace pls {
namespace dataflow { namespace dataflow {
namespace internal {
template<typename T> template<typename T>
class input { class input {
...@@ -26,16 +27,19 @@ class input { ...@@ -26,16 +27,19 @@ class input {
connected_ = true; connected_ = true;
} }
public:
input() : filled_{false}, connected_{false} {}; input() : filled_{false}, connected_{false} {};
bool has_token(color color) const { bool has_token(token_color color) const {
return filled_ && token_.color() == color; return filled_ && token_.color() == color;
} }
const token<T> &get_token() const { return token_; } 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_ #ifndef PLS_DATAFLOW_INTERNAL_OUTPUT_H_
#define PLS_DATAFLOW_OUTPUT_H_ #define PLS_DATAFLOW_INTERNAL_OUTPUT_H_
#include "token.h" #include "token.h"
#include "input.h" #include "input.h"
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
namespace pls { namespace pls {
namespace dataflow { namespace dataflow {
namespace internal {
template<typename T> template<typename T>
class output { class output {
...@@ -31,5 +32,6 @@ class output { ...@@ -31,5 +32,6 @@ class output {
} }
} }
}
#endif //PLS_DATAFLOW_OUTPUT_H_ #endif //PLS_DATAFLOW_INTERNAL_OUTPUT_H_
#ifndef PLS_DATAFLOW_TOKEN_H_ #ifndef PLS_DATAFLOW_INTERNAL_TOKEN_H_
#define PLS_DATAFLOW_TOKEN_H_ #define PLS_DATAFLOW_INTERNAL_TOKEN_H_
namespace pls { namespace pls {
namespace dataflow { namespace dataflow {
namespace internal {
/** /**
* Parallel invocations of the same sub-graph are usually working with some kind of coloring * 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 * 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. * change it in the future (for e.g. more advanced features/dataflows) we encapsulate it.
*/ */
struct color { struct token_color {
unsigned int clock_; unsigned int clock_;
}; };
template<typename T> template<typename T>
class token { class token {
T value_; T value_;
color color_; token_color color_;
public: public:
T value() const { return value_; } 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 @@ ...@@ -2,23 +2,16 @@
#ifndef PLS_DATAFLOW_OUTPUTS_H_ #ifndef PLS_DATAFLOW_OUTPUTS_H_
#define PLS_DATAFLOW_OUTPUTS_H_ #define PLS_DATAFLOW_OUTPUTS_H_
#include <tuple> #include "internal/outputs.h"
#include "outputs.h"
#include "output.h"
namespace pls { namespace pls {
namespace dataflow { namespace dataflow {
template<typename O1, typename ...O> template<typename O1, typename ...O>
class outputs { struct outputs {
using values_type = std::tuple<output<O1>, output<O>...>; template<int P>
values_type values_; using internal_outputs = internal::outputs<P, O1, O...>;
public:
template<int N>
typename std::tuple_element<N, values_type>::type &get() {
return std::get<N>(values_);
}
}; };
} }
......
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