Commit 552fefb3 by FritzFlorian

Create basic dataflow input/output data structures.

This is the base building block for creating the actual dataflow functions and networks, as their main functionality is having data flow through connected nodes.
parent 220baad3
// Headers are available because we added the pls target
#include <iostream>
#include <functional>
#include <array>
#include <atomic>
#include <memory>
#include <typeindex>
#include <tuple>
#include <string>
#include <cstdio>
#include <pls/pls.h>
#include <pls/dataflow/inputs.h>
#include <pls/dataflow/outputs.h>
int main() {
pls::dataflow::inputs<int, std::string> in;
pls::dataflow::outputs<int> out1;
pls::dataflow::outputs<std::string> out2;
out1.get<0>().connect(in.get<0>());
out2.get<0>().connect(in.get<1>());
}
......@@ -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
......
#ifndef PLS_DATAFLOW_DATAFLOW_H_
#define PLS_DATAFLOW_DATAFLOW_H_
#endif //PLS_DATAFLOW_DATAFLOW_H_
#ifndef PLS_DATAFLOW_GRAPH_H_
#define PLS_DATAFLOW_GRAPH_H_
namespace pls {
namespace dataflow {
template<
class graph {
};
}
}
#endif //PLS_DATAFLOW_GRAPH_H_
#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<typename T>
class input {
template<typename OT>
friend
class output;
token<T> 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<T> &get_token() const { return token_; }
};
}
}
#endif //PLS_DATAFLOW_INPUT_H_
#ifndef PLS_DATAFLOW_INPUTS_H_
#define PLS_DATAFLOW_INPUTS_H_
#include <tuple>
#include "input.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_);
}
};
}
}
#endif //PLS_DATAFLOW_INPUTS_H_
#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<typename T>
class output {
input<T> *target_;
bool connected_;
public:
output() : target_{nullptr}, connected_{false} {};
void connect(input<T> &target) {
if (connected_) {
PLS_ERROR("Must only connect output once. Please disconnect it before reconnecting.")
}
target.connect();
target_ = &target;
connected_ = true;
}
};
}
}
#endif //PLS_DATAFLOW_OUTPUT_H_
#ifndef PLS_DATAFLOW_OUTPUTS_H_
#define PLS_DATAFLOW_OUTPUTS_H_
#include <tuple>
#include "output.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_);
}
};
}
}
#endif //PLS_DATAFLOW_OUTPUTS_H_
#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<typename T>
class token {
T value_;
color color_;
public:
T value() const { return value_; }
color color() const { return color_; }
};
}
}
#endif //PLS_DATAFLOW_TOKEN_H_
......@@ -2,7 +2,8 @@
#ifndef PLS_ERROR_HANDLING_H
#define PLS_ERROR_HANDLING_H
#include <iostream>
#include <cstdio>
#include <cstdlib>
/**
* 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
......@@ -2,6 +2,8 @@
#ifndef PLS_ALIGNED_STACK_IMPL_H
#define PLS_ALIGNED_STACK_IMPL_H
#include <utility>
namespace pls {
namespace internal {
namespace data_structures {
......
......@@ -2,6 +2,9 @@
#ifndef PLS_WORK_STEALING_DEQUE_IMPL_H_
#define PLS_WORK_STEALING_DEQUE_IMPL_H_
#include <utility>
#include <new>
namespace pls {
namespace internal {
namespace data_structures {
......
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