diff --git a/app/playground/main.cpp b/app/playground/main.cpp index cde3abd..2a48764 100644 --- a/app/playground/main.cpp +++ b/app/playground/main.cpp @@ -1,14 +1,17 @@ // Headers are available because we added the pls target -#include -#include -#include -#include -#include -#include -#include +#include + +#include #include +#include +#include int main() { + pls::dataflow::inputs in; + pls::dataflow::outputs out1; + pls::dataflow::outputs out2; + out1.get<0>().connect(in.get<0>()); + out2.get<0>().connect(in.get<1>()); } diff --git a/lib/pls/CMakeLists.txt b/lib/pls/CMakeLists.txt index 8d46447..3dae953 100644 --- a/lib/pls/CMakeLists.txt +++ b/lib/pls/CMakeLists.txt @@ -9,6 +9,14 @@ add_library(pls STATIC include/pls/algorithms/scan.h include/pls/algorithms/scan_impl.h + include/pls/dataflow/dataflow.h + include/pls/dataflow/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/internal/base/spin_lock.h include/pls/internal/base/tas_spin_lock.h src/internal/base/tas_spin_lock.cpp include/pls/internal/base/ttas_spin_lock.h src/internal/base/ttas_spin_lock.cpp @@ -22,6 +30,7 @@ add_library(pls STATIC include/pls/internal/data_structures/aligned_stack.h src/internal/data_structures/aligned_stack.cpp include/pls/internal/data_structures/aligned_stack_impl.h + include/pls/internal/data_structures/deque.h include/pls/internal/data_structures/locking_deque.h include/pls/internal/data_structures/locking_deque_impl.h include/pls/internal/data_structures/work_stealing_deque.h include/pls/internal/data_structures/work_stealing_deque_impl.h @@ -38,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/data_structures/deque.h) + include/pls/internal/scheduling/lambda_task.h) # Add everything in `./include` to be in the include path of this project target_include_directories(pls PUBLIC diff --git a/lib/pls/include/pls/dataflow/dataflow.h b/lib/pls/include/pls/dataflow/dataflow.h new file mode 100644 index 0000000..b9bc7f5 --- /dev/null +++ b/lib/pls/include/pls/dataflow/dataflow.h @@ -0,0 +1,5 @@ + +#ifndef PLS_DATAFLOW_DATAFLOW_H_ +#define PLS_DATAFLOW_DATAFLOW_H_ + +#endif //PLS_DATAFLOW_DATAFLOW_H_ diff --git a/lib/pls/include/pls/dataflow/graph.h b/lib/pls/include/pls/dataflow/graph.h new file mode 100644 index 0000000..1f94b02 --- /dev/null +++ b/lib/pls/include/pls/dataflow/graph.h @@ -0,0 +1,16 @@ + +#ifndef PLS_DATAFLOW_GRAPH_H_ +#define PLS_DATAFLOW_GRAPH_H_ + +namespace pls { +namespace dataflow { + +template< +class graph { + +}; + +} +} + +#endif //PLS_DATAFLOW_GRAPH_H_ diff --git a/lib/pls/include/pls/dataflow/input.h b/lib/pls/include/pls/dataflow/input.h new file mode 100644 index 0000000..c47581a --- /dev/null +++ b/lib/pls/include/pls/dataflow/input.h @@ -0,0 +1,41 @@ + +#ifndef PLS_DATAFLOW_INPUT_H_ +#define PLS_DATAFLOW_INPUT_H_ + +#include "token.h" + +#include "pls/internal/base/error_handling.h" + +namespace pls { +namespace dataflow { + +template +class input { + template + friend + class output; + + token token_; + bool filled_; + bool connected_; + + void connect() { + if (connected_) { + PLS_ERROR("Must only connect on input once. Disconnect the output pointing to it before reconnecting.") + } + connected_ = true; + } + + public: + input() : filled_{false}, connected_{false} {}; + + bool has_token(color color) const { + return filled_ && token_.color() == color; + } + const token &get_token() const { return token_; } +}; + +} +} + +#endif //PLS_DATAFLOW_INPUT_H_ diff --git a/lib/pls/include/pls/dataflow/inputs.h b/lib/pls/include/pls/dataflow/inputs.h new file mode 100644 index 0000000..24f7d95 --- /dev/null +++ b/lib/pls/include/pls/dataflow/inputs.h @@ -0,0 +1,27 @@ + +#ifndef PLS_DATAFLOW_INPUTS_H_ +#define PLS_DATAFLOW_INPUTS_H_ + +#include + +#include "input.h" + +namespace pls { +namespace dataflow { + +template +class inputs { + using values_type = std::tuple, input...>; + values_type values_; + + public: + template + typename std::tuple_element::type &get() { + return std::get(values_); + } +}; + +} +} + +#endif //PLS_DATAFLOW_INPUTS_H_ diff --git a/lib/pls/include/pls/dataflow/output.h b/lib/pls/include/pls/dataflow/output.h new file mode 100644 index 0000000..2c2c3cb --- /dev/null +++ b/lib/pls/include/pls/dataflow/output.h @@ -0,0 +1,35 @@ + +#ifndef PLS_DATAFLOW_OUTPUT_H_ +#define PLS_DATAFLOW_OUTPUT_H_ + +#include "token.h" +#include "input.h" + +#include "pls/internal/base/error_handling.h" + +namespace pls { +namespace dataflow { + +template +class output { + input *target_; + bool connected_; + + public: + output() : target_{nullptr}, connected_{false} {}; + + void connect(input &target) { + if (connected_) { + PLS_ERROR("Must only connect output once. Please disconnect it before reconnecting.") + } + + target.connect(); + target_ = ⌖ + connected_ = true; + } +}; + +} +} + +#endif //PLS_DATAFLOW_OUTPUT_H_ diff --git a/lib/pls/include/pls/dataflow/outputs.h b/lib/pls/include/pls/dataflow/outputs.h new file mode 100644 index 0000000..68f1f20 --- /dev/null +++ b/lib/pls/include/pls/dataflow/outputs.h @@ -0,0 +1,27 @@ + +#ifndef PLS_DATAFLOW_OUTPUTS_H_ +#define PLS_DATAFLOW_OUTPUTS_H_ + +#include + +#include "output.h" + +namespace pls { +namespace dataflow { + +template +class outputs { + using values_type = std::tuple, output...>; + values_type values_; + + public: + template + typename std::tuple_element::type &get() { + return std::get(values_); + } +}; + +} +} + +#endif //PLS_DATAFLOW_OUTPUTS_H_ diff --git a/lib/pls/include/pls/dataflow/token.h b/lib/pls/include/pls/dataflow/token.h new file mode 100644 index 0000000..6492944 --- /dev/null +++ b/lib/pls/include/pls/dataflow/token.h @@ -0,0 +1,30 @@ + +#ifndef PLS_DATAFLOW_TOKEN_H_ +#define PLS_DATAFLOW_TOKEN_H_ + +namespace pls { +namespace dataflow { + +/** + * 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 { + unsigned int clock_; +}; + +template +class token { + T value_; + color color_; + + public: + T value() const { return value_; } + color color() const { return color_; } +}; + +} +} + +#endif //PLS_DATAFLOW_TOKEN_H_ diff --git a/lib/pls/include/pls/internal/base/error_handling.h b/lib/pls/include/pls/internal/base/error_handling.h index 381758a..341b7fb 100644 --- a/lib/pls/include/pls/internal/base/error_handling.h +++ b/lib/pls/include/pls/internal/base/error_handling.h @@ -2,7 +2,8 @@ #ifndef PLS_ERROR_HANDLING_H #define PLS_ERROR_HANDLING_H -#include +#include +#include /** * Called when there is an non-recoverable error/invariant in the scheduler. @@ -10,7 +11,7 @@ * The implementation can be changed if for example no iostream is available on a system * (or its inclusion adds too much overhead). */ -#define PLS_ERROR(msg) std::cout << msg << std::endl; exit(1); +#define PLS_ERROR(msg) printf("%s\n", msg); exit(1); #define PLS_ASSERT(cond, msg) if (!cond) { PLS_ERROR(msg) } #endif //PLS_ERROR_HANDLING_H diff --git a/lib/pls/include/pls/internal/data_structures/aligned_stack_impl.h b/lib/pls/include/pls/internal/data_structures/aligned_stack_impl.h index 0952968..e04567b 100644 --- a/lib/pls/include/pls/internal/data_structures/aligned_stack_impl.h +++ b/lib/pls/include/pls/internal/data_structures/aligned_stack_impl.h @@ -2,6 +2,8 @@ #ifndef PLS_ALIGNED_STACK_IMPL_H #define PLS_ALIGNED_STACK_IMPL_H +#include + namespace pls { namespace internal { namespace data_structures { diff --git a/lib/pls/include/pls/internal/data_structures/work_stealing_deque_impl.h b/lib/pls/include/pls/internal/data_structures/work_stealing_deque_impl.h index d3316be..0730674 100644 --- a/lib/pls/include/pls/internal/data_structures/work_stealing_deque_impl.h +++ b/lib/pls/include/pls/internal/data_structures/work_stealing_deque_impl.h @@ -2,6 +2,9 @@ #ifndef PLS_WORK_STEALING_DEQUE_IMPL_H_ #define PLS_WORK_STEALING_DEQUE_IMPL_H_ +#include +#include + namespace pls { namespace internal { namespace data_structures {