Commit 76afcbb3 by Marcus Winter

dataflow_cpp: number of slices can now be set at runtime

parent 2f7e8112
...@@ -35,6 +35,7 @@ class Scheduler; ...@@ -35,6 +35,7 @@ class Scheduler;
class ClockListener; class ClockListener;
struct InitData { struct InitData {
int slices;
Scheduler * sched; Scheduler * sched;
ClockListener * sink_listener; ClockListener * sink_listener;
}; };
......
...@@ -35,11 +35,11 @@ namespace embb { ...@@ -35,11 +35,11 @@ namespace embb {
namespace dataflow { namespace dataflow {
namespace internal { namespace internal {
template <int Slices, typename Type> template <typename Type>
class ConstantSource class ConstantSource
: public Node { : public Node {
public: public:
typedef Outputs<Slices, Type> OutputsType; typedef Outputs<Type> OutputsType;
private: private:
OutputsType outputs_; OutputsType outputs_;
......
...@@ -41,18 +41,18 @@ namespace internal { ...@@ -41,18 +41,18 @@ namespace internal {
class Scheduler; class Scheduler;
template <typename, int> template <typename>
class Out; class Out;
template <typename Type, int Slices> template <typename Type>
class In { class In {
public: public:
typedef Signal<Type> SignalType; typedef Signal<Type> SignalType;
In() : connected_(false) {} In() : values_(NULL), connected_(false), slices_(0) {}
SignalType const & GetSignal(int clock) const { SignalType const & GetSignal(int clock) const {
return values_[clock % Slices]; return values_[clock % slices_];
} }
Type GetValue(int clock) const { Type GetValue(int clock) const {
...@@ -66,26 +66,37 @@ class In { ...@@ -66,26 +66,37 @@ class In {
bool IsConnected() const { return connected_; } bool IsConnected() const { return connected_; }
void SetConnected() { connected_ = true; } void SetConnected() { connected_ = true; }
void SetSlices(int slices) {
slices_ = slices;
values_ = reinterpret_cast<SignalType*>(
embb::base::Allocation::Allocate(
sizeof(SignalType)*slices_));
for (int ii = 0; ii < slices_; ii++) {
values_[ii] = SignalType();
}
}
void SetListener(ClockListener * listener) { listener_ = listener; } void SetListener(ClockListener * listener) { listener_ = listener; }
void Clear(int clock) { void Clear(int clock) {
const int idx = clock % Slices; const int idx = clock % slices_;
values_[idx].Clear(); values_[idx].Clear();
} }
friend class Out<Type, Slices>; friend class Out<Type>;
private: private:
SignalType values_[Slices]; SignalType * values_;
ClockListener * listener_; ClockListener * listener_;
bool connected_; bool connected_;
int slices_;
#if EMBB_DATAFLOW_TRACE_SIGNAL_HISTORY #if EMBB_DATAFLOW_TRACE_SIGNAL_HISTORY
embb::base::Spinlock lock_; embb::base::Spinlock lock_;
std::vector<SignalType> history_; std::vector<SignalType> history_;
#endif #endif
void Receive(SignalType const & value) { void Receive(SignalType const & value) {
const int idx = value.GetClock() % Slices; const int idx = value.GetClock() % slices_;
if (values_[idx].GetClock() >= value.GetClock()) if (values_[idx].GetClock() >= value.GetClock())
EMBB_THROW(embb::base::ErrorException, EMBB_THROW(embb::base::ErrorException,
"Received signal does not increase clock."); "Received signal does not increase clock.");
...@@ -99,6 +110,7 @@ class In { ...@@ -99,6 +110,7 @@ class In {
} }
void ReceiveInit(InitData * init_data) { void ReceiveInit(InitData * init_data) {
SetSlices(init_data->slices);
listener_->OnInit(init_data); listener_->OnInit(init_data);
} }
}; };
......
...@@ -36,7 +36,6 @@ namespace dataflow { ...@@ -36,7 +36,6 @@ namespace dataflow {
namespace internal { namespace internal {
template < template <
int,
typename = embb::base::internal::Nil, typename = embb::base::internal::Nil,
typename = embb::base::internal::Nil, typename = embb::base::internal::Nil,
typename = embb::base::internal::Nil, typename = embb::base::internal::Nil,
...@@ -44,8 +43,8 @@ template < ...@@ -44,8 +43,8 @@ template <
typename = embb::base::internal::Nil> typename = embb::base::internal::Nil>
class Inputs; class Inputs;
template <int Slices> template <>
class Inputs<Slices, embb::base::internal::Nil, embb::base::internal::Nil, class Inputs<embb::base::internal::Nil, embb::base::internal::Nil,
embb::base::internal::Nil, embb::base::internal::Nil, embb::base::internal::Nil, embb::base::internal::Nil,
embb::base::internal::Nil> embb::base::internal::Nil>
: public Tuple<embb::base::internal::Nil, embb::base::internal::Nil, : public Tuple<embb::base::internal::Nil, embb::base::internal::Nil,
...@@ -60,17 +59,15 @@ class Inputs<Slices, embb::base::internal::Nil, embb::base::internal::Nil, ...@@ -60,17 +59,15 @@ class Inputs<Slices, embb::base::internal::Nil, embb::base::internal::Nil,
virtual void OnInit(InitData * /*init_data*/) {} virtual void OnInit(InitData * /*init_data*/) {}
}; };
template <int Slices, typename T1> template <typename T1>
class Inputs<Slices, T1, embb::base::internal::Nil, embb::base::internal::Nil, class Inputs<T1, embb::base::internal::Nil, embb::base::internal::Nil,
embb::base::internal::Nil, embb::base::internal::Nil> embb::base::internal::Nil, embb::base::internal::Nil>
: public Tuple<In<T1, Slices>, embb::base::internal::Nil, : public Tuple<In<T1>, embb::base::internal::Nil,
embb::base::internal::Nil, embb::base::internal::Nil, embb::base::internal::Nil, embb::base::internal::Nil,
embb::base::internal::Nil> embb::base::internal::Nil>
, public ClockListener { , public ClockListener {
public: public:
Inputs() { Inputs() {
for (int ii = 0; ii < Slices; ii++)
count_[ii] = 1;
test_count_ = 1; test_count_ = 1;
} }
void SetListener(ClockListener * listener) { void SetListener(ClockListener * listener) {
...@@ -89,7 +86,7 @@ class Inputs<Slices, T1, embb::base::internal::Nil, embb::base::internal::Nil, ...@@ -89,7 +86,7 @@ class Inputs<Slices, T1, embb::base::internal::Nil, embb::base::internal::Nil,
this->template Get<0>().Clear(clock); this->template Get<0>().Clear(clock);
} }
virtual void OnClock(int clock) { virtual void OnClock(int clock) {
const int idx = clock % Slices; const int idx = clock % slices_;
if (count_[idx] == 0) { if (count_[idx] == 0) {
EMBB_THROW(embb::base::ErrorException, EMBB_THROW(embb::base::ErrorException,
"All inputs already fired for this clock."); "All inputs already fired for this clock.");
...@@ -101,25 +98,31 @@ class Inputs<Slices, T1, embb::base::internal::Nil, embb::base::internal::Nil, ...@@ -101,25 +98,31 @@ class Inputs<Slices, T1, embb::base::internal::Nil, embb::base::internal::Nil,
} }
virtual void OnInit(InitData * init_data) { virtual void OnInit(InitData * init_data) {
if (--test_count_ == 0) { if (--test_count_ == 0) {
slices_ = init_data->slices;
count_ = reinterpret_cast<embb::base::Atomic<int>*>(
embb::base::Allocation::Allocate(
sizeof(embb::base::Atomic<int>)*slices_));
for (int ii = 0; ii < slices_; ii++) {
count_[ii] = 1;
}
listener_->OnInit(init_data); listener_->OnInit(init_data);
} }
} }
private: private:
embb::base::Atomic<int> count_[Slices]; embb::base::Atomic<int> * count_;
int test_count_; int test_count_;
ClockListener * listener_; ClockListener * listener_;
int slices_;
}; };
template <int Slices, typename T1, typename T2> template <typename T1, typename T2>
class Inputs<Slices, T1, T2, embb::base::internal::Nil, class Inputs<T1, T2, embb::base::internal::Nil,
embb::base::internal::Nil, embb::base::internal::Nil> embb::base::internal::Nil, embb::base::internal::Nil>
: public Tuple<In<T1, Slices>, In<T2, Slices>, embb::base::internal::Nil, : public Tuple<In<T1>, In<T2>, embb::base::internal::Nil,
embb::base::internal::Nil, embb::base::internal::Nil> embb::base::internal::Nil, embb::base::internal::Nil>
, public ClockListener { , public ClockListener {
public: public:
Inputs() { Inputs() {
for (int ii = 0; ii < Slices; ii++)
count_[ii] = 2;
test_count_ = 2; test_count_ = 2;
} }
void SetListener(ClockListener * listener) { void SetListener(ClockListener * listener) {
...@@ -142,7 +145,7 @@ class Inputs<Slices, T1, T2, embb::base::internal::Nil, ...@@ -142,7 +145,7 @@ class Inputs<Slices, T1, T2, embb::base::internal::Nil,
this->template Get<1>().Clear(clock); this->template Get<1>().Clear(clock);
} }
virtual void OnClock(int clock) { virtual void OnClock(int clock) {
const int idx = clock % Slices; const int idx = clock % slices_;
if (count_[idx] == 0) { if (count_[idx] == 0) {
EMBB_THROW(embb::base::ErrorException, EMBB_THROW(embb::base::ErrorException,
"All inputs already fired for this clock."); "All inputs already fired for this clock.");
...@@ -154,25 +157,31 @@ class Inputs<Slices, T1, T2, embb::base::internal::Nil, ...@@ -154,25 +157,31 @@ class Inputs<Slices, T1, T2, embb::base::internal::Nil,
} }
virtual void OnInit(InitData * init_data) { virtual void OnInit(InitData * init_data) {
if (--test_count_ == 0) { if (--test_count_ == 0) {
slices_ = init_data->slices;
count_ = reinterpret_cast<embb::base::Atomic<int>*>(
embb::base::Allocation::Allocate(
sizeof(embb::base::Atomic<int>)*slices_));
for (int ii = 0; ii < slices_; ii++) {
count_[ii] = 2;
}
listener_->OnInit(init_data); listener_->OnInit(init_data);
} }
} }
private: private:
embb::base::Atomic<int> count_[Slices]; embb::base::Atomic<int> * count_;
int test_count_; int test_count_;
ClockListener * listener_; ClockListener * listener_;
int slices_;
}; };
template <int Slices, typename T1, typename T2, typename T3> template <typename T1, typename T2, typename T3>
class Inputs<Slices, T1, T2, T3, embb::base::internal::Nil, class Inputs<T1, T2, T3, embb::base::internal::Nil,
embb::base::internal::Nil> embb::base::internal::Nil>
: public Tuple<In<T1, Slices>, In<T2, Slices>, In<T3, Slices>, : public Tuple<In<T1>, In<T2>, In<T3>,
embb::base::internal::Nil, embb::base::internal::Nil> embb::base::internal::Nil, embb::base::internal::Nil>
, public ClockListener { , public ClockListener {
public: public:
Inputs() { Inputs() {
for (int ii = 0; ii < Slices; ii++)
count_[ii] = 3;
test_count_ = 3; test_count_ = 3;
} }
void SetListener(ClockListener * listener) { void SetListener(ClockListener * listener) {
...@@ -199,7 +208,7 @@ class Inputs<Slices, T1, T2, T3, embb::base::internal::Nil, ...@@ -199,7 +208,7 @@ class Inputs<Slices, T1, T2, T3, embb::base::internal::Nil,
this->template Get<2>().Clear(clock); this->template Get<2>().Clear(clock);
} }
virtual void OnClock(int clock) { virtual void OnClock(int clock) {
const int idx = clock % Slices; const int idx = clock % slices_;
if (count_[idx] == 0) { if (count_[idx] == 0) {
EMBB_THROW(embb::base::ErrorException, EMBB_THROW(embb::base::ErrorException,
"All inputs already fired for this clock."); "All inputs already fired for this clock.");
...@@ -211,24 +220,30 @@ class Inputs<Slices, T1, T2, T3, embb::base::internal::Nil, ...@@ -211,24 +220,30 @@ class Inputs<Slices, T1, T2, T3, embb::base::internal::Nil,
} }
virtual void OnInit(InitData * init_data) { virtual void OnInit(InitData * init_data) {
if (--test_count_ == 0) { if (--test_count_ == 0) {
slices_ = init_data->slices;
count_ = reinterpret_cast<embb::base::Atomic<int>*>(
embb::base::Allocation::Allocate(
sizeof(embb::base::Atomic<int>)*slices_));
for (int ii = 0; ii < slices_; ii++) {
count_[ii] = 3;
}
listener_->OnInit(init_data); listener_->OnInit(init_data);
} }
} }
private: private:
embb::base::Atomic<int> count_[Slices]; embb::base::Atomic<int> * count_;
int test_count_; int test_count_;
ClockListener * listener_; ClockListener * listener_;
int slices_;
}; };
template <int Slices, typename T1, typename T2, typename T3, typename T4> template <typename T1, typename T2, typename T3, typename T4>
class Inputs<Slices, T1, T2, T3, T4, embb::base::internal::Nil> class Inputs<T1, T2, T3, T4, embb::base::internal::Nil>
: public Tuple<In<T1, Slices>, In<T2, Slices>, In<T3, Slices>, : public Tuple<In<T1>, In<T2>, In<T3>,
In<T4, Slices>, embb::base::internal::Nil> In<T4>, embb::base::internal::Nil>
, public ClockListener { , public ClockListener {
public: public:
Inputs() { Inputs() {
for (int ii = 0; ii < Slices; ii++)
count_[ii] = 4;
test_count_ = 4; test_count_ = 4;
} }
void SetListener(ClockListener * listener) { void SetListener(ClockListener * listener) {
...@@ -259,7 +274,7 @@ class Inputs<Slices, T1, T2, T3, T4, embb::base::internal::Nil> ...@@ -259,7 +274,7 @@ class Inputs<Slices, T1, T2, T3, T4, embb::base::internal::Nil>
this->template Get<3>().Clear(clock); this->template Get<3>().Clear(clock);
} }
virtual void OnClock(int clock) { virtual void OnClock(int clock) {
const int idx = clock % Slices; const int idx = clock % slices_;
if (count_[idx] == 0) { if (count_[idx] == 0) {
EMBB_THROW(embb::base::ErrorException, EMBB_THROW(embb::base::ErrorException,
"All inputs already fired for this clock."); "All inputs already fired for this clock.");
...@@ -271,25 +286,31 @@ class Inputs<Slices, T1, T2, T3, T4, embb::base::internal::Nil> ...@@ -271,25 +286,31 @@ class Inputs<Slices, T1, T2, T3, T4, embb::base::internal::Nil>
} }
virtual void OnInit(InitData * init_data) { virtual void OnInit(InitData * init_data) {
if (--test_count_ == 0) { if (--test_count_ == 0) {
slices_ = init_data->slices;
count_ = reinterpret_cast<embb::base::Atomic<int>*>(
embb::base::Allocation::Allocate(
sizeof(embb::base::Atomic<int>)*slices_));
for (int ii = 0; ii < slices_; ii++) {
count_[ii] = 4;
}
listener_->OnInit(init_data); listener_->OnInit(init_data);
} }
} }
private: private:
embb::base::Atomic<int> count_[Slices]; embb::base::Atomic<int> * count_;
int test_count_; int test_count_;
ClockListener * listener_; ClockListener * listener_;
int slices_;
}; };
template <int Slices, typename T1, typename T2, typename T3, typename T4, template <typename T1, typename T2, typename T3, typename T4,
typename T5> typename T5>
class Inputs class Inputs
: public Tuple<In<T1, Slices>, In<T2, Slices>, In<T3, Slices>, : public Tuple<In<T1>, In<T2>, In<T3>,
In<T4, Slices>, In<T5, Slices> > In<T4>, In<T5> >
, public ClockListener { , public ClockListener {
public: public:
Inputs() { Inputs() {
for (int ii = 0; ii < Slices; ii++)
count_[ii] = 5;
test_count_ = 5; test_count_ = 5;
} }
void SetListener(ClockListener * listener) { void SetListener(ClockListener * listener) {
...@@ -324,7 +345,7 @@ class Inputs ...@@ -324,7 +345,7 @@ class Inputs
this->template Get<4>().Clear(clock); this->template Get<4>().Clear(clock);
} }
virtual void OnClock(int clock) { virtual void OnClock(int clock) {
const int idx = clock % Slices; const int idx = clock % slices_;
if (count_[idx] == 0) { if (count_[idx] == 0) {
EMBB_THROW(embb::base::ErrorException, EMBB_THROW(embb::base::ErrorException,
"All inputs already fired for this clock."); "All inputs already fired for this clock.");
...@@ -336,13 +357,21 @@ class Inputs ...@@ -336,13 +357,21 @@ class Inputs
} }
virtual void OnInit(InitData * init_data) { virtual void OnInit(InitData * init_data) {
if (--test_count_ == 0) { if (--test_count_ == 0) {
slices_ = init_data->slices;
count_ = reinterpret_cast<embb::base::Atomic<int>*>(
embb::base::Allocation::Allocate(
sizeof(embb::base::Atomic<int>)*slices_));
for (int ii = 0; ii < slices_; ii++) {
count_[ii] = 5;
}
listener_->OnInit(init_data); listener_->OnInit(init_data);
} }
} }
private: private:
embb::base::Atomic<int> count_[Slices]; embb::base::Atomic<int> * count_;
int test_count_; int test_count_;
ClockListener * listener_; ClockListener * listener_;
int slices_;
}; };
} // namespace internal } // namespace internal
......
...@@ -37,11 +37,11 @@ namespace internal { ...@@ -37,11 +37,11 @@ namespace internal {
class Scheduler; class Scheduler;
template <typename Type, int Slices> template <typename Type>
class Out { class Out {
public: public:
typedef Signal<Type> SignalType; typedef Signal<Type> SignalType;
typedef In<Type, Slices> InType; typedef In<Type> InType;
Out() { Out() {
} }
......
...@@ -35,7 +35,6 @@ namespace dataflow { ...@@ -35,7 +35,6 @@ namespace dataflow {
namespace internal { namespace internal {
template < template <
int,
typename = embb::base::internal::Nil, typename = embb::base::internal::Nil,
typename = embb::base::internal::Nil, typename = embb::base::internal::Nil,
typename = embb::base::internal::Nil, typename = embb::base::internal::Nil,
...@@ -43,8 +42,8 @@ template < ...@@ -43,8 +42,8 @@ template <
typename = embb::base::internal::Nil > typename = embb::base::internal::Nil >
class Outputs; class Outputs;
template <int Slices> template <>
class Outputs<Slices, embb::base::internal::Nil, embb::base::internal::Nil, class Outputs<embb::base::internal::Nil, embb::base::internal::Nil,
embb::base::internal::Nil, embb::base::internal::Nil, embb::base::internal::Nil, embb::base::internal::Nil,
embb::base::internal::Nil> embb::base::internal::Nil>
: public Tuple<embb::base::internal::Nil, embb::base::internal::Nil, : public Tuple<embb::base::internal::Nil, embb::base::internal::Nil,
...@@ -53,43 +52,43 @@ class Outputs<Slices, embb::base::internal::Nil, embb::base::internal::Nil, ...@@ -53,43 +52,43 @@ class Outputs<Slices, embb::base::internal::Nil, embb::base::internal::Nil,
public: public:
}; };
template <int Slices, typename T1> template <typename T1>
class Outputs<Slices, T1, embb::base::internal::Nil, embb::base::internal::Nil, class Outputs<T1, embb::base::internal::Nil, embb::base::internal::Nil,
embb::base::internal::Nil, embb::base::internal::Nil> embb::base::internal::Nil, embb::base::internal::Nil>
: public Tuple<Out<T1, Slices>, embb::base::internal::Nil, : public Tuple<Out<T1>, embb::base::internal::Nil,
embb::base::internal::Nil, embb::base::internal::Nil, embb::base::internal::Nil, embb::base::internal::Nil,
embb::base::internal::Nil> { embb::base::internal::Nil> {
public: public:
}; };
template <int Slices, typename T1, typename T2> template <typename T1, typename T2>
class Outputs<Slices, T1, T2, embb::base::internal::Nil, class Outputs<T1, T2, embb::base::internal::Nil,
embb::base::internal::Nil, embb::base::internal::Nil> embb::base::internal::Nil, embb::base::internal::Nil>
: public Tuple<Out<T1, Slices>, Out<T2, Slices>, embb::base::internal::Nil, : public Tuple<Out<T1>, Out<T2>, embb::base::internal::Nil,
embb::base::internal::Nil, embb::base::internal::Nil> { embb::base::internal::Nil, embb::base::internal::Nil> {
public: public:
}; };
template <int Slices, typename T1, typename T2, typename T3> template <typename T1, typename T2, typename T3>
class Outputs<Slices, T1, T2, T3, embb::base::internal::Nil, class Outputs<T1, T2, T3, embb::base::internal::Nil,
embb::base::internal::Nil> embb::base::internal::Nil>
: public Tuple<Out<T1, Slices>, Out<T2, Slices>, Out<T3, Slices>, : public Tuple<Out<T1>, Out<T2>, Out<T3>,
embb::base::internal::Nil, embb::base::internal::Nil> { embb::base::internal::Nil, embb::base::internal::Nil> {
public: public:
}; };
template <int Slices, typename T1, typename T2, typename T3, typename T4> template <typename T1, typename T2, typename T3, typename T4>
class Outputs<Slices, T1, T2, T3, T4, embb::base::internal::Nil> class Outputs<T1, T2, T3, T4, embb::base::internal::Nil>
: public Tuple<Out<T1, Slices>, Out<T2, Slices>, Out<T3, Slices>, : public Tuple<Out<T1>, Out<T2>, Out<T3>,
Out<T4, Slices>, embb::base::internal::Nil>{ Out<T4>, embb::base::internal::Nil>{
public: public:
}; };
template <int Slices, typename T1, typename T2, typename T3, typename T4, template <typename T1, typename T2, typename T3, typename T4,
typename T5> typename T5>
class Outputs class Outputs
: public Tuple<Out<T1, Slices>, Out<T2, Slices>, Out<T3, Slices>, : public Tuple<Out<T1>, Out<T2>, Out<T3>,
Out<T4, Slices>, Out<T5, Slices> > { Out<T4>, Out<T5> > {
public: public:
}; };
......
...@@ -37,24 +37,25 @@ namespace embb { ...@@ -37,24 +37,25 @@ namespace embb {
namespace dataflow { namespace dataflow {
namespace internal { namespace internal {
template <int Slices, bool Serial, class INPUTS, class OUTPUTS> class Process; template <bool Serial, class INPUTS, class OUTPUTS> class Process;
template < template <
int Slices, bool Serial, bool Serial,
typename I1, typename I2, typename I3, typename I4, typename I5, typename I1, typename I2, typename I3, typename I4, typename I5,
typename O1, typename O2, typename O3, typename O4, typename O5> typename O1, typename O2, typename O3, typename O4, typename O5>
class Process< Slices, Serial, Inputs<Slices, I1, I2, I3, I4, I5>, class Process< Serial, Inputs<I1, I2, I3, I4, I5>,
Outputs<Slices, O1, O2, O3, O4, O5> > Outputs<O1, O2, O3, O4, O5> >
: public Node : public Node
, public ClockListener { , public ClockListener {
public: public:
typedef Inputs<Slices, I1, I2, I3, I4, I5> InputsType; typedef Inputs<I1, I2, I3, I4, I5> InputsType;
typedef Outputs<Slices, O1, O2, O3, O4, O5> OutputsType; typedef Outputs<O1, O2, O3, O4, O5> OutputsType;
typedef ProcessExecutor< InputsType, OutputsType > ExecutorType; typedef ProcessExecutor< InputsType, OutputsType > ExecutorType;
typedef typename ExecutorType::FunctionType FunctionType; typedef typename ExecutorType::FunctionType FunctionType;
explicit Process(FunctionType function) explicit Process(FunctionType function)
: executor_(function) { : executor_(function)
, slices_(0) {
next_clock_ = 0; next_clock_ = 0;
queued_clock_ = 0; queued_clock_ = 0;
bool ordered = Serial; bool ordered = Serial;
...@@ -79,6 +80,14 @@ class Process< Slices, Serial, Inputs<Slices, I1, I2, I3, I4, I5>, ...@@ -79,6 +80,14 @@ class Process< Slices, Serial, Inputs<Slices, I1, I2, I3, I4, I5>,
} }
virtual void Init(InitData * init_data) { virtual void Init(InitData * init_data) {
slices_ = init_data->slices;
//inputs_.SetSlices(init_data->slices);
action_ = reinterpret_cast<Action*>(
embb::base::Allocation::Allocate(
sizeof(Action)*slices_));
for (int ii = 0; ii < slices_; ii++) {
action_[ii] = Action();
}
SetScheduler(init_data->sched); SetScheduler(init_data->sched);
executor_.Init(init_data, outputs_); executor_.Init(init_data, outputs_);
} }
...@@ -117,7 +126,7 @@ class Process< Slices, Serial, Inputs<Slices, I1, I2, I3, I4, I5>, ...@@ -117,7 +126,7 @@ class Process< Slices, Serial, Inputs<Slices, I1, I2, I3, I4, I5>,
bool retry = true; bool retry = true;
while (retry) { while (retry) {
int clk = next_clock_; int clk = next_clock_;
int clk_end = clk + Slices; int clk_end = clk + slices_;
int clk_res = clk; int clk_res = clk;
for (int ii = clk; ii < clk_end; ii++) { for (int ii = clk; ii < clk_end; ii++) {
if (!inputs_.AreAtClock(ii)) { if (!inputs_.AreAtClock(ii)) {
...@@ -129,7 +138,7 @@ class Process< Slices, Serial, Inputs<Slices, I1, I2, I3, I4, I5>, ...@@ -129,7 +138,7 @@ class Process< Slices, Serial, Inputs<Slices, I1, I2, I3, I4, I5>,
if (next_clock_.CompareAndSwap(clk, clk_res)) { if (next_clock_.CompareAndSwap(clk, clk_res)) {
while (queued_clock_.Load() < clk) continue; while (queued_clock_.Load() < clk) continue;
for (int ii = clk; ii < clk_res; ii++) { for (int ii = clk; ii < clk_res; ii++) {
const int idx = ii % Slices; const int idx = ii % slices_;
action_[idx] = Action(this, ii); action_[idx] = Action(this, ii);
sched_->Enqueue(queue_id_, action_[idx]); sched_->Enqueue(queue_id_, action_[idx]);
} }
...@@ -141,7 +150,7 @@ class Process< Slices, Serial, Inputs<Slices, I1, I2, I3, I4, I5>, ...@@ -141,7 +150,7 @@ class Process< Slices, Serial, Inputs<Slices, I1, I2, I3, I4, I5>,
} }
} }
} else { } else {
const int idx = clock % Slices; const int idx = clock % slices_;
action_[idx] = Action(this, clock); action_[idx] = Action(this, clock);
sched_->Spawn(action_[idx]); sched_->Spawn(action_[idx]);
} }
...@@ -155,10 +164,11 @@ class Process< Slices, Serial, Inputs<Slices, I1, I2, I3, I4, I5>, ...@@ -155,10 +164,11 @@ class Process< Slices, Serial, Inputs<Slices, I1, I2, I3, I4, I5>,
InputsType inputs_; InputsType inputs_;
OutputsType outputs_; OutputsType outputs_;
ExecutorType executor_; ExecutorType executor_;
Action action_[Slices]; Action * action_;
embb::base::Atomic<int> next_clock_; embb::base::Atomic<int> next_clock_;
embb::base::Atomic<int> queued_clock_; embb::base::Atomic<int> queued_clock_;
int queue_id_; int queue_id_;
int slices_;
}; };
} // namespace internal } // namespace internal
......
...@@ -36,12 +36,17 @@ namespace embb { ...@@ -36,12 +36,17 @@ namespace embb {
namespace dataflow { namespace dataflow {
namespace internal { namespace internal {
template <int Slices>
class SchedulerMTAPI : public Scheduler { class SchedulerMTAPI : public Scheduler {
public: public:
SchedulerMTAPI() { SchedulerMTAPI(int slices)
: slices_(slices) {
embb::tasks::Node & node = embb::tasks::Node::GetInstance(); embb::tasks::Node & node = embb::tasks::Node::GetInstance();
for (int ii = 0; ii < Slices; ii++) {
group_ = reinterpret_cast<embb::tasks::Group**>(
embb::base::Allocation::Allocate(
sizeof(embb::tasks::Group*)*slices_));
for (int ii = 0; ii < slices_; ii++) {
embb::tasks::Group & group = node.CreateGroup(); embb::tasks::Group & group = node.CreateGroup();
group_[ii] = &group; group_[ii] = &group;
} }
...@@ -58,21 +63,22 @@ class SchedulerMTAPI : public Scheduler { ...@@ -58,21 +63,22 @@ class SchedulerMTAPI : public Scheduler {
} }
virtual ~SchedulerMTAPI() { virtual ~SchedulerMTAPI() {
embb::tasks::Node & node = embb::tasks::Node::GetInstance(); embb::tasks::Node & node = embb::tasks::Node::GetInstance();
for (int ii = 0; ii < Slices; ii++) { for (int ii = 0; ii < slices_; ii++) {
group_[ii]->WaitAll(MTAPI_INFINITE); group_[ii]->WaitAll(MTAPI_INFINITE);
node.DestroyGroup(*group_[ii]); node.DestroyGroup(*group_[ii]);
} }
embb::base::Allocation::Free(group_);
for (int ii = 0; ii < queue_count_; ii++) { for (int ii = 0; ii < queue_count_; ii++) {
node.DestroyQueue(*queue_[ii]); node.DestroyQueue(*queue_[ii]);
} }
embb::base::Allocation::Free(queue_); embb::base::Allocation::Free(queue_);
} }
virtual void Spawn(Action & action) { virtual void Spawn(Action & action) {
const int idx = action.GetClock() % Slices; const int idx = action.GetClock() % slices_;
group_[idx]->Spawn(embb::base::MakeFunction(action, &Action::RunMTAPI)); group_[idx]->Spawn(embb::base::MakeFunction(action, &Action::RunMTAPI));
} }
virtual void Enqueue(int process_id, Action & action) { virtual void Enqueue(int process_id, Action & action) {
const int idx = action.GetClock() % Slices; const int idx = action.GetClock() % slices_;
const int queue_id = process_id % queue_count_; const int queue_id = process_id % queue_count_;
queue_[queue_id]->Spawn(group_[idx], queue_[queue_id]->Spawn(group_[idx],
embb::base::MakeFunction(action, &Action::RunMTAPI)); embb::base::MakeFunction(action, &Action::RunMTAPI));
...@@ -82,9 +88,10 @@ class SchedulerMTAPI : public Scheduler { ...@@ -82,9 +88,10 @@ class SchedulerMTAPI : public Scheduler {
} }
private: private:
embb::tasks::Group * group_[Slices]; embb::tasks::Group ** group_;
embb::tasks::Queue ** queue_; embb::tasks::Queue ** queue_;
int queue_count_; int queue_count_;
int slices_;
}; };
} // namespace internal } // namespace internal
......
...@@ -27,7 +27,6 @@ ...@@ -27,7 +27,6 @@
#ifndef EMBB_DATAFLOW_INTERNAL_SELECT_H_ #ifndef EMBB_DATAFLOW_INTERNAL_SELECT_H_
#define EMBB_DATAFLOW_INTERNAL_SELECT_H_ #define EMBB_DATAFLOW_INTERNAL_SELECT_H_
#include <embb/dataflow/internal/action.h>
#include <embb/dataflow/internal/signal.h> #include <embb/dataflow/internal/signal.h>
#include <embb/dataflow/internal/node.h> #include <embb/dataflow/internal/node.h>
#include <embb/dataflow/internal/inputs.h> #include <embb/dataflow/internal/inputs.h>
...@@ -37,13 +36,13 @@ namespace embb { ...@@ -37,13 +36,13 @@ namespace embb {
namespace dataflow { namespace dataflow {
namespace internal { namespace internal {
template <int Slices, typename Type> template <typename Type>
class Select class Select
: public Node : public Node
, public ClockListener { , public ClockListener {
public: public:
typedef Inputs<Slices, bool, Type, Type> InputsType; typedef Inputs<bool, Type, Type> InputsType;
typedef Outputs<Slices, Type> OutputsType; typedef Outputs<Type> OutputsType;
Select() { Select() {
inputs_.SetListener(this); inputs_.SetListener(this);
...@@ -82,6 +81,8 @@ class Select ...@@ -82,6 +81,8 @@ class Select
} }
virtual void Init(InitData * init_data) { virtual void Init(InitData * init_data) {
slices_ = init_data->slices;
//inputs_.SetSlices(slices_);
SetScheduler(init_data->sched); SetScheduler(init_data->sched);
GetOutput<0>().SendInit(init_data); GetOutput<0>().SendInit(init_data);
} }
...@@ -124,7 +125,7 @@ class Select ...@@ -124,7 +125,7 @@ class Select
private: private:
InputsType inputs_; InputsType inputs_;
OutputsType outputs_; OutputsType outputs_;
Action action_[Slices]; int slices_;
}; };
} // namespace internal } // namespace internal
......
...@@ -36,16 +36,15 @@ namespace embb { ...@@ -36,16 +36,15 @@ namespace embb {
namespace dataflow { namespace dataflow {
namespace internal { namespace internal {
template <int Slices, class Inputs> class Sink; template <class Inputs> class Sink;
template < template <
int Slices,
typename I1, typename I2, typename I3, typename I4, typename I5> typename I1, typename I2, typename I3, typename I4, typename I5>
class Sink< Slices, Inputs<Slices, I1, I2, I3, I4, I5> > class Sink< Inputs<I1, I2, I3, I4, I5> >
: public Node : public Node
, public ClockListener { , public ClockListener {
public: public:
typedef Inputs<Slices, I1, I2, I3, I4, I5> InputsType; typedef Inputs<I1, I2, I3, I4, I5> InputsType;
typedef SinkExecutor< InputsType > ExecutorType; typedef SinkExecutor< InputsType > ExecutorType;
typedef typename ExecutorType::FunctionType FunctionType; typedef typename ExecutorType::FunctionType FunctionType;
...@@ -73,6 +72,13 @@ class Sink< Slices, Inputs<Slices, I1, I2, I3, I4, I5> > ...@@ -73,6 +72,13 @@ class Sink< Slices, Inputs<Slices, I1, I2, I3, I4, I5> >
} }
virtual void Init(InitData * init_data) { virtual void Init(InitData * init_data) {
slices_ = init_data->slices;
action_ = reinterpret_cast<Action*>(
embb::base::Allocation::Allocate(
sizeof(Action)*slices_));
for (int ii = 0; ii < slices_; ii++) {
action_[ii] = Action();
}
SetListener(init_data->sink_listener); SetListener(init_data->sink_listener);
SetScheduler(init_data->sched); SetScheduler(init_data->sched);
listener_->OnInit(init_data); listener_->OnInit(init_data);
...@@ -96,7 +102,7 @@ class Sink< Slices, Inputs<Slices, I1, I2, I3, I4, I5> > ...@@ -96,7 +102,7 @@ class Sink< Slices, Inputs<Slices, I1, I2, I3, I4, I5> >
bool retry = true; bool retry = true;
while (retry) { while (retry) {
int clk = next_clock_; int clk = next_clock_;
int clk_end = clk + Slices; int clk_end = clk + slices_;
int clk_res = clk; int clk_res = clk;
for (int ii = clk; ii < clk_end; ii++) { for (int ii = clk; ii < clk_end; ii++) {
if (!inputs_.AreAtClock(ii)) { if (!inputs_.AreAtClock(ii)) {
...@@ -108,7 +114,7 @@ class Sink< Slices, Inputs<Slices, I1, I2, I3, I4, I5> > ...@@ -108,7 +114,7 @@ class Sink< Slices, Inputs<Slices, I1, I2, I3, I4, I5> >
if (next_clock_.CompareAndSwap(clk, clk_res)) { if (next_clock_.CompareAndSwap(clk, clk_res)) {
while (queued_clock_.Load() < clk) continue; while (queued_clock_.Load() < clk) continue;
for (int ii = clk; ii < clk_res; ii++) { for (int ii = clk; ii < clk_res; ii++) {
const int idx = ii % Slices; const int idx = ii % slices_;
action_[idx] = Action(this, ii); action_[idx] = Action(this, ii);
sched_->Enqueue(queue_id_, action_[idx]); sched_->Enqueue(queue_id_, action_[idx]);
} }
...@@ -128,11 +134,12 @@ class Sink< Slices, Inputs<Slices, I1, I2, I3, I4, I5> > ...@@ -128,11 +134,12 @@ class Sink< Slices, Inputs<Slices, I1, I2, I3, I4, I5> >
private: private:
InputsType inputs_; InputsType inputs_;
ExecutorType executor_; ExecutorType executor_;
Action action_[Slices]; Action * action_;
ClockListener * listener_; ClockListener * listener_;
embb::base::Atomic<int> next_clock_; embb::base::Atomic<int> next_clock_;
embb::base::Atomic<int> queued_clock_; embb::base::Atomic<int> queued_clock_;
int queue_id_; int queue_id_;
int slices_;
}; };
} // namespace internal } // namespace internal
......
...@@ -38,8 +38,8 @@ namespace internal { ...@@ -38,8 +38,8 @@ namespace internal {
template <class Inputs> template <class Inputs>
class SinkExecutor; class SinkExecutor;
template <int Slices, typename I1> template <typename I1>
class SinkExecutor< Inputs<Slices, I1> > { class SinkExecutor< Inputs<I1> > {
public: public:
typedef embb::base::Function<void, I1 const &> FunctionType; typedef embb::base::Function<void, I1 const &> FunctionType;
...@@ -47,7 +47,7 @@ class SinkExecutor< Inputs<Slices, I1> > { ...@@ -47,7 +47,7 @@ class SinkExecutor< Inputs<Slices, I1> > {
void Execute( void Execute(
int clock, int clock,
Inputs<Slices, I1> & inputs) { Inputs<I1> & inputs) {
function_( function_(
inputs.template Get<0>().GetValue(clock)); inputs.template Get<0>().GetValue(clock));
} }
...@@ -56,8 +56,8 @@ class SinkExecutor< Inputs<Slices, I1> > { ...@@ -56,8 +56,8 @@ class SinkExecutor< Inputs<Slices, I1> > {
FunctionType function_; FunctionType function_;
}; };
template <int Slices, typename I1, typename I2> template <typename I1, typename I2>
class SinkExecutor< Inputs<Slices, I1, I2> > { class SinkExecutor< Inputs<I1, I2> > {
public: public:
typedef embb::base::Function<void, I1 const &, I2 const &> FunctionType; typedef embb::base::Function<void, I1 const &, I2 const &> FunctionType;
...@@ -65,7 +65,7 @@ class SinkExecutor< Inputs<Slices, I1, I2> > { ...@@ -65,7 +65,7 @@ class SinkExecutor< Inputs<Slices, I1, I2> > {
void Execute( void Execute(
int clock, int clock,
Inputs<Slices, I1, I2> & inputs) { Inputs<I1, I2> & inputs) {
function_( function_(
inputs.template Get<0>().GetValue(clock), inputs.template Get<0>().GetValue(clock),
inputs.template Get<1>().GetValue(clock)); inputs.template Get<1>().GetValue(clock));
...@@ -75,8 +75,8 @@ class SinkExecutor< Inputs<Slices, I1, I2> > { ...@@ -75,8 +75,8 @@ class SinkExecutor< Inputs<Slices, I1, I2> > {
FunctionType function_; FunctionType function_;
}; };
template <int Slices, typename I1, typename I2, typename I3> template <typename I1, typename I2, typename I3>
class SinkExecutor< Inputs<Slices, I1, I2, I3> > { class SinkExecutor< Inputs<I1, I2, I3> > {
public: public:
typedef embb::base::Function<void, I1 const &, I2 const &, I3 const &> typedef embb::base::Function<void, I1 const &, I2 const &, I3 const &>
FunctionType; FunctionType;
...@@ -85,7 +85,7 @@ class SinkExecutor< Inputs<Slices, I1, I2, I3> > { ...@@ -85,7 +85,7 @@ class SinkExecutor< Inputs<Slices, I1, I2, I3> > {
void Execute( void Execute(
int clock, int clock,
Inputs<Slices, I1, I2, I3> & inputs) { Inputs<I1, I2, I3> & inputs) {
function_( function_(
inputs.template Get<0>().GetValue(clock), inputs.template Get<0>().GetValue(clock),
inputs.template Get<1>().GetValue(clock), inputs.template Get<1>().GetValue(clock),
...@@ -96,8 +96,8 @@ class SinkExecutor< Inputs<Slices, I1, I2, I3> > { ...@@ -96,8 +96,8 @@ class SinkExecutor< Inputs<Slices, I1, I2, I3> > {
FunctionType function_; FunctionType function_;
}; };
template <int Slices, typename I1, typename I2, typename I3, typename I4> template <typename I1, typename I2, typename I3, typename I4>
class SinkExecutor< Inputs<Slices, I1, I2, I3, I4> > { class SinkExecutor< Inputs<I1, I2, I3, I4> > {
public: public:
typedef embb::base::Function<void, I1 const &, I2 const &, I3 const &, typedef embb::base::Function<void, I1 const &, I2 const &, I3 const &,
I4 const &> FunctionType; I4 const &> FunctionType;
...@@ -106,7 +106,7 @@ class SinkExecutor< Inputs<Slices, I1, I2, I3, I4> > { ...@@ -106,7 +106,7 @@ class SinkExecutor< Inputs<Slices, I1, I2, I3, I4> > {
void Execute( void Execute(
int clock, int clock,
Inputs<Slices, I1, I2, I3, I4> & inputs) { Inputs<I1, I2, I3, I4> & inputs) {
function_( function_(
inputs.template Get<0>().GetValue(clock), inputs.template Get<0>().GetValue(clock),
inputs.template Get<1>().GetValue(clock), inputs.template Get<1>().GetValue(clock),
...@@ -118,9 +118,9 @@ class SinkExecutor< Inputs<Slices, I1, I2, I3, I4> > { ...@@ -118,9 +118,9 @@ class SinkExecutor< Inputs<Slices, I1, I2, I3, I4> > {
FunctionType function_; FunctionType function_;
}; };
template <int Slices, typename I1, typename I2, typename I3, typename I4, template <typename I1, typename I2, typename I3, typename I4,
typename I5> typename I5>
class SinkExecutor< Inputs<Slices, I1, I2, I3, I4, I5> > { class SinkExecutor< Inputs<I1, I2, I3, I4, I5> > {
public: public:
typedef embb::base::Function<void, I1 const &, I2 const &, I3 const &, typedef embb::base::Function<void, I1 const &, I2 const &, I3 const &,
I4 const &, I5 const &> FunctionType; I4 const &, I5 const &> FunctionType;
...@@ -129,7 +129,7 @@ class SinkExecutor< Inputs<Slices, I1, I2, I3, I4, I5> > { ...@@ -129,7 +129,7 @@ class SinkExecutor< Inputs<Slices, I1, I2, I3, I4, I5> > {
void Execute( void Execute(
int clock, int clock,
Inputs<Slices, I1, I2, I3, I4, I5> & inputs) { Inputs<I1, I2, I3, I4, I5> & inputs) {
function_( function_(
inputs.template Get<0>().GetValue(clock), inputs.template Get<0>().GetValue(clock),
inputs.template Get<1>().GetValue(clock), inputs.template Get<1>().GetValue(clock),
......
...@@ -35,15 +35,14 @@ namespace embb { ...@@ -35,15 +35,14 @@ namespace embb {
namespace dataflow { namespace dataflow {
namespace internal { namespace internal {
template <int Slices, class Outputs> class Source; template <class Outputs> class Source;
template < template <
int Slices,
typename O1, typename O2, typename O3, typename O4, typename O5> typename O1, typename O2, typename O3, typename O4, typename O5>
class Source< Slices, Outputs<Slices, O1, O2, O3, O4, O5> > class Source< Outputs<O1, O2, O3, O4, O5> >
: public Node { : public Node {
public: public:
typedef Outputs<Slices, O1, O2, O3, O4, O5> OutputsType; typedef Outputs<O1, O2, O3, O4, O5> OutputsType;
typedef SourceExecutor< OutputsType > ExecutorType; typedef SourceExecutor< OutputsType > ExecutorType;
typedef typename ExecutorType::FunctionType FunctionType; typedef typename ExecutorType::FunctionType FunctionType;
......
...@@ -41,8 +41,8 @@ class Scheduler; ...@@ -41,8 +41,8 @@ class Scheduler;
template <class OUTPUTS> template <class OUTPUTS>
class SourceExecutor; class SourceExecutor;
template <int Slices, typename O1> template <typename O1>
class SourceExecutor< Outputs<Slices, O1> > { class SourceExecutor< Outputs<O1> > {
public: public:
typedef embb::base::Function<bool, O1 &> FunctionType; typedef embb::base::Function<bool, O1 &> FunctionType;
...@@ -50,14 +50,14 @@ class SourceExecutor< Outputs<Slices, O1> > { ...@@ -50,14 +50,14 @@ class SourceExecutor< Outputs<Slices, O1> > {
bool Execute( bool Execute(
int clock, int clock,
Outputs<Slices, O1> & outputs) { Outputs<O1> & outputs) {
O1 o1; O1 o1;
bool result = function_(o1); bool result = function_(o1);
outputs.template Get<0>().Send(Signal<O1>(clock, o1)); outputs.template Get<0>().Send(Signal<O1>(clock, o1));
return result; return result;
} }
void Init(InitData * init_data, Outputs<Slices, O1> & outputs) { void Init(InitData * init_data, Outputs<O1> & outputs) {
outputs.template Get<0>().SendInit(init_data); outputs.template Get<0>().SendInit(init_data);
} }
...@@ -65,8 +65,8 @@ class SourceExecutor< Outputs<Slices, O1> > { ...@@ -65,8 +65,8 @@ class SourceExecutor< Outputs<Slices, O1> > {
FunctionType function_; FunctionType function_;
}; };
template <int Slices, typename O1, typename O2> template <typename O1, typename O2>
class SourceExecutor< Outputs<Slices, O1, O2> > { class SourceExecutor< Outputs<O1, O2> > {
public: public:
typedef embb::base::Function<bool, O1 &, O2 &> FunctionType; typedef embb::base::Function<bool, O1 &, O2 &> FunctionType;
...@@ -74,7 +74,7 @@ class SourceExecutor< Outputs<Slices, O1, O2> > { ...@@ -74,7 +74,7 @@ class SourceExecutor< Outputs<Slices, O1, O2> > {
bool Execute( bool Execute(
int clock, int clock,
Outputs<Slices, O1, O2> & outputs) { Outputs<O1, O2> & outputs) {
O1 o1; O1 o1;
O2 o2; O2 o2;
bool result = function_(o1, o2); bool result = function_(o1, o2);
...@@ -83,7 +83,7 @@ class SourceExecutor< Outputs<Slices, O1, O2> > { ...@@ -83,7 +83,7 @@ class SourceExecutor< Outputs<Slices, O1, O2> > {
return result; return result;
} }
void Init(InitData * init_data, Outputs<Slices, O1, O2> & outputs) { void Init(InitData * init_data, Outputs<O1, O2> & outputs) {
outputs.template Get<0>().SendInit(init_data); outputs.template Get<0>().SendInit(init_data);
outputs.template Get<1>().SendInit(init_data); outputs.template Get<1>().SendInit(init_data);
} }
...@@ -92,8 +92,8 @@ class SourceExecutor< Outputs<Slices, O1, O2> > { ...@@ -92,8 +92,8 @@ class SourceExecutor< Outputs<Slices, O1, O2> > {
FunctionType function_; FunctionType function_;
}; };
template <int Slices, typename O1, typename O2, typename O3> template <typename O1, typename O2, typename O3>
class SourceExecutor< Outputs<Slices, O1, O2, O3> > { class SourceExecutor< Outputs<O1, O2, O3> > {
public: public:
typedef embb::base::Function<bool, O1 &, O2 &, O3 &> FunctionType; typedef embb::base::Function<bool, O1 &, O2 &, O3 &> FunctionType;
...@@ -101,7 +101,7 @@ class SourceExecutor< Outputs<Slices, O1, O2, O3> > { ...@@ -101,7 +101,7 @@ class SourceExecutor< Outputs<Slices, O1, O2, O3> > {
bool Execute( bool Execute(
int clock, int clock,
Outputs<Slices, O1, O2, O3> & outputs) { Outputs<O1, O2, O3> & outputs) {
O1 o1; O1 o1;
O2 o2; O2 o2;
O3 o3; O3 o3;
...@@ -112,7 +112,7 @@ class SourceExecutor< Outputs<Slices, O1, O2, O3> > { ...@@ -112,7 +112,7 @@ class SourceExecutor< Outputs<Slices, O1, O2, O3> > {
return result; return result;
} }
void Init(InitData * init_data, Outputs<Slices, O1, O2, O3> & outputs) { void Init(InitData * init_data, Outputs<O1, O2, O3> & outputs) {
outputs.template Get<0>().SendInit(init_data); outputs.template Get<0>().SendInit(init_data);
outputs.template Get<1>().SendInit(init_data); outputs.template Get<1>().SendInit(init_data);
outputs.template Get<2>().SendInit(init_data); outputs.template Get<2>().SendInit(init_data);
...@@ -122,8 +122,8 @@ class SourceExecutor< Outputs<Slices, O1, O2, O3> > { ...@@ -122,8 +122,8 @@ class SourceExecutor< Outputs<Slices, O1, O2, O3> > {
FunctionType function_; FunctionType function_;
}; };
template <int Slices, typename O1, typename O2, typename O3, typename O4> template <typename O1, typename O2, typename O3, typename O4>
class SourceExecutor< Outputs<Slices, O1, O2, O3, O4> > { class SourceExecutor< Outputs<O1, O2, O3, O4> > {
public: public:
typedef embb::base::Function<bool, O1 &, O2 &, O3 &, O4 &> FunctionType; typedef embb::base::Function<bool, O1 &, O2 &, O3 &, O4 &> FunctionType;
...@@ -131,7 +131,7 @@ class SourceExecutor< Outputs<Slices, O1, O2, O3, O4> > { ...@@ -131,7 +131,7 @@ class SourceExecutor< Outputs<Slices, O1, O2, O3, O4> > {
bool Execute( bool Execute(
int clock, int clock,
Outputs<Slices, O1, O2, O3, O4> & outputs) { Outputs<O1, O2, O3, O4> & outputs) {
O1 o1; O1 o1;
O2 o2; O2 o2;
O3 o3; O3 o3;
...@@ -144,7 +144,7 @@ class SourceExecutor< Outputs<Slices, O1, O2, O3, O4> > { ...@@ -144,7 +144,7 @@ class SourceExecutor< Outputs<Slices, O1, O2, O3, O4> > {
return result; return result;
} }
void Init(InitData * init_data, Outputs<Slices, O1, O2, O3, O4> & outputs) { void Init(InitData * init_data, Outputs<O1, O2, O3, O4> & outputs) {
outputs.template Get<0>().SendInit(init_data); outputs.template Get<0>().SendInit(init_data);
outputs.template Get<1>().SendInit(init_data); outputs.template Get<1>().SendInit(init_data);
outputs.template Get<2>().SendInit(init_data); outputs.template Get<2>().SendInit(init_data);
...@@ -155,9 +155,9 @@ class SourceExecutor< Outputs<Slices, O1, O2, O3, O4> > { ...@@ -155,9 +155,9 @@ class SourceExecutor< Outputs<Slices, O1, O2, O3, O4> > {
FunctionType function_; FunctionType function_;
}; };
template <int Slices, typename O1, typename O2, typename O3, typename O4, template <typename O1, typename O2, typename O3, typename O4,
typename O5> typename O5>
class SourceExecutor< Outputs<Slices, O1, O2, O3, O4, O5> > { class SourceExecutor< Outputs<O1, O2, O3, O4, O5> > {
public: public:
typedef embb::base::Function<bool, O1 &, O2 &, O3 &, O4 &, O5 &> FunctionType; typedef embb::base::Function<bool, O1 &, O2 &, O3 &, O4 &, O5 &> FunctionType;
...@@ -165,7 +165,7 @@ class SourceExecutor< Outputs<Slices, O1, O2, O3, O4, O5> > { ...@@ -165,7 +165,7 @@ class SourceExecutor< Outputs<Slices, O1, O2, O3, O4, O5> > {
bool Execute( bool Execute(
int clock, int clock,
Outputs<Slices, O1, O2, O3, O4, O5> & outputs) { Outputs<O1, O2, O3, O4, O5> & outputs) {
O1 o1; O1 o1;
O2 o2; O2 o2;
O3 o3; O3 o3;
...@@ -181,7 +181,7 @@ class SourceExecutor< Outputs<Slices, O1, O2, O3, O4, O5> > { ...@@ -181,7 +181,7 @@ class SourceExecutor< Outputs<Slices, O1, O2, O3, O4, O5> > {
} }
void Init( void Init(
InitData * init_data, Outputs<Slices, O1, O2, O3, O4, O5> & outputs) { InitData * init_data, Outputs<O1, O2, O3, O4, O5> & outputs) {
outputs.template Get<0>().SendInit(init_data); outputs.template Get<0>().SendInit(init_data);
outputs.template Get<1>().SendInit(init_data); outputs.template Get<1>().SendInit(init_data);
outputs.template Get<2>().SendInit(init_data); outputs.template Get<2>().SendInit(init_data);
......
...@@ -27,7 +27,6 @@ ...@@ -27,7 +27,6 @@
#ifndef EMBB_DATAFLOW_INTERNAL_SWITCH_H_ #ifndef EMBB_DATAFLOW_INTERNAL_SWITCH_H_
#define EMBB_DATAFLOW_INTERNAL_SWITCH_H_ #define EMBB_DATAFLOW_INTERNAL_SWITCH_H_
#include <embb/dataflow/internal/action.h>
#include <embb/dataflow/internal/signal.h> #include <embb/dataflow/internal/signal.h>
#include <embb/dataflow/internal/node.h> #include <embb/dataflow/internal/node.h>
#include <embb/dataflow/internal/inputs.h> #include <embb/dataflow/internal/inputs.h>
...@@ -37,13 +36,13 @@ namespace embb { ...@@ -37,13 +36,13 @@ namespace embb {
namespace dataflow { namespace dataflow {
namespace internal { namespace internal {
template <int Slices, typename Type> template <typename Type>
class Switch class Switch
: public Node : public Node
, public ClockListener { , public ClockListener {
public: public:
typedef Inputs<Slices, bool, Type> InputsType; typedef Inputs<bool, Type> InputsType;
typedef Outputs<Slices, Type, Type> OutputsType; typedef Outputs<Type, Type> OutputsType;
Switch() { Switch() {
inputs_.SetListener(this); inputs_.SetListener(this);
...@@ -79,6 +78,7 @@ class Switch ...@@ -79,6 +78,7 @@ class Switch
} }
virtual void Init(InitData * init_data) { virtual void Init(InitData * init_data) {
//inputs_.SetSlices(init_data->slices);
SetScheduler(init_data->sched); SetScheduler(init_data->sched);
GetOutput<0>().SendInit(init_data); GetOutput<0>().SendInit(init_data);
GetOutput<1>().SendInit(init_data); GetOutput<1>().SendInit(init_data);
...@@ -122,7 +122,6 @@ class Switch ...@@ -122,7 +122,6 @@ class Switch
private: private:
InputsType inputs_; InputsType inputs_;
OutputsType outputs_; OutputsType outputs_;
Action action_[Slices];
}; };
} // namespace internal } // namespace internal
......
...@@ -669,7 +669,6 @@ class Network { ...@@ -669,7 +669,6 @@ class Network {
#else #else
template <int Slices>
class Network : public internal::ClockListener { class Network : public internal::ClockListener {
public: public:
Network() {} Network() {}
...@@ -679,7 +678,7 @@ class Network : public internal::ClockListener { ...@@ -679,7 +678,7 @@ class Network : public internal::ClockListener {
typename T4 = embb::base::internal::Nil, typename T4 = embb::base::internal::Nil,
typename T5 = embb::base::internal::Nil> typename T5 = embb::base::internal::Nil>
struct Inputs { struct Inputs {
typedef internal::Inputs<Slices, T1, T2, T3, T4, T5> Type; typedef internal::Inputs<T1, T2, T3, T4, T5> Type;
}; };
template <typename T1, typename T2 = embb::base::internal::Nil, template <typename T1, typename T2 = embb::base::internal::Nil,
...@@ -687,7 +686,7 @@ class Network : public internal::ClockListener { ...@@ -687,7 +686,7 @@ class Network : public internal::ClockListener {
typename T4 = embb::base::internal::Nil, typename T4 = embb::base::internal::Nil,
typename T5 = embb::base::internal::Nil> typename T5 = embb::base::internal::Nil>
struct Outputs { struct Outputs {
typedef internal::Outputs<Slices, T1, T2, T3, T4, T5> Type; typedef internal::Outputs<T1, T2, T3, T4, T5> Type;
}; };
template <class Inputs, class Outputs> class SerialProcess; template <class Inputs, class Outputs> class SerialProcess;
...@@ -695,20 +694,20 @@ class Network : public internal::ClockListener { ...@@ -695,20 +694,20 @@ class Network : public internal::ClockListener {
template < template <
typename I1, typename I2, typename I3, typename I4, typename I5, typename I1, typename I2, typename I3, typename I4, typename I5,
typename O1, typename O2, typename O3, typename O4, typename O5> typename O1, typename O2, typename O3, typename O4, typename O5>
class SerialProcess< internal::Inputs<Slices, I1, I2, I3, I4, I5>, class SerialProcess< internal::Inputs<I1, I2, I3, I4, I5>,
internal::Outputs<Slices, O1, O2, O3, O4, O5> > internal::Outputs<O1, O2, O3, O4, O5> >
: public internal::Process< Slices, true, : public internal::Process< true,
internal::Inputs<Slices, I1, I2, I3, I4, I5>, internal::Inputs<I1, I2, I3, I4, I5>,
internal::Outputs<Slices, O1, O2, O3, O4, O5> > { internal::Outputs<O1, O2, O3, O4, O5> > {
public: public:
typedef typename internal::Process< Slices, true, typedef typename internal::Process< true,
internal::Inputs<Slices, I1, I2, I3, I4, I5>, internal::Inputs<I1, I2, I3, I4, I5>,
internal::Outputs<Slices, O1, O2, O3, O4, O5> >::FunctionType internal::Outputs<O1, O2, O3, O4, O5> >::FunctionType
FunctionType; FunctionType;
explicit SerialProcess(FunctionType function) explicit SerialProcess(FunctionType function)
: internal::Process< Slices, true, : internal::Process< true,
internal::Inputs<Slices, I1, I2, I3, I4, I5>, internal::Inputs<I1, I2, I3, I4, I5>,
internal::Outputs<Slices, O1, O2, O3, O4, O5> >(function) { internal::Outputs<O1, O2, O3, O4, O5> >(function) {
//empty //empty
} }
}; };
...@@ -718,31 +717,31 @@ class Network : public internal::ClockListener { ...@@ -718,31 +717,31 @@ class Network : public internal::ClockListener {
template < template <
typename I1, typename I2, typename I3, typename I4, typename I5, typename I1, typename I2, typename I3, typename I4, typename I5,
typename O1, typename O2, typename O3, typename O4, typename O5> typename O1, typename O2, typename O3, typename O4, typename O5>
class ParallelProcess< internal::Inputs<Slices, I1, I2, I3, I4, I5>, class ParallelProcess< internal::Inputs<I1, I2, I3, I4, I5>,
internal::Outputs<Slices, O1, O2, O3, O4, O5> > internal::Outputs<O1, O2, O3, O4, O5> >
: public internal::Process< Slices, false, : public internal::Process< false,
internal::Inputs<Slices, I1, I2, I3, I4, I5>, internal::Inputs<I1, I2, I3, I4, I5>,
internal::Outputs<Slices, O1, O2, O3, O4, O5> >{ internal::Outputs<O1, O2, O3, O4, O5> >{
public: public:
typedef typename internal::Process< Slices, false, typedef typename internal::Process< false,
internal::Inputs<Slices, I1, I2, I3, I4, I5>, internal::Inputs<I1, I2, I3, I4, I5>,
internal::Outputs<Slices, O1, O2, O3, O4, O5> >::FunctionType internal::Outputs<O1, O2, O3, O4, O5> >::FunctionType
FunctionType; FunctionType;
explicit ParallelProcess(FunctionType function) explicit ParallelProcess(FunctionType function)
: internal::Process< Slices, false, : internal::Process< false,
internal::Inputs<Slices, I1, I2, I3, I4, I5>, internal::Inputs<I1, I2, I3, I4, I5>,
internal::Outputs<Slices, O1, O2, O3, O4, O5> >(function) { internal::Outputs<O1, O2, O3, O4, O5> >(function) {
//empty //empty
} }
}; };
template<typename Type> template<typename Type>
class Switch : public internal::Switch<Slices, Type> { class Switch : public internal::Switch<Type> {
public: public:
}; };
template<typename Type> template<typename Type>
class Select : public internal::Select<Slices, Type> { class Select : public internal::Select<Type> {
public: public:
}; };
...@@ -750,15 +749,15 @@ class Network : public internal::ClockListener { ...@@ -750,15 +749,15 @@ class Network : public internal::ClockListener {
typename I3 = embb::base::internal::Nil, typename I3 = embb::base::internal::Nil,
typename I4 = embb::base::internal::Nil, typename I4 = embb::base::internal::Nil,
typename I5 = embb::base::internal::Nil> typename I5 = embb::base::internal::Nil>
class Sink : public internal::Sink<Slices, class Sink : public internal::Sink<
internal::Inputs<Slices, I1, I2, I3, I4, I5> > { internal::Inputs<I1, I2, I3, I4, I5> > {
public: public:
typedef typename internal::Sink<Slices, typedef typename internal::Sink<
internal::Inputs<Slices, I1, I2, I3, I4, I5> >::FunctionType FunctionType; internal::Inputs<I1, I2, I3, I4, I5> >::FunctionType FunctionType;
explicit Sink(FunctionType function) explicit Sink(FunctionType function)
: internal::Sink<Slices, : internal::Sink<
internal::Inputs<Slices, I1, I2, I3, I4, I5> >(function) { internal::Inputs<I1, I2, I3, I4, I5> >(function) {
//empty //empty
} }
}; };
...@@ -767,16 +766,16 @@ class Network : public internal::ClockListener { ...@@ -767,16 +766,16 @@ class Network : public internal::ClockListener {
typename O3 = embb::base::internal::Nil, typename O3 = embb::base::internal::Nil,
typename O4 = embb::base::internal::Nil, typename O4 = embb::base::internal::Nil,
typename O5 = embb::base::internal::Nil> typename O5 = embb::base::internal::Nil>
class Source : public internal::Source<Slices, class Source : public internal::Source<
internal::Outputs<Slices, O1, O2, O3, O4, O5> > { internal::Outputs<O1, O2, O3, O4, O5> > {
public: public:
typedef typename internal::Source<Slices, typedef typename internal::Source<
internal::Outputs<Slices, O1, O2, O3, O4, O5> >::FunctionType internal::Outputs<O1, O2, O3, O4, O5> >::FunctionType
FunctionType; FunctionType;
explicit Source(FunctionType function) explicit Source(FunctionType function)
: internal::Source<Slices, : internal::Source<
internal::Outputs<Slices, O1, O2, O3, O4, O5> >(function) { internal::Outputs<O1, O2, O3, O4, O5> >(function) {
//empty //empty
} }
}; };
...@@ -787,10 +786,10 @@ class Network : public internal::ClockListener { ...@@ -787,10 +786,10 @@ class Network : public internal::ClockListener {
} }
template<typename Type> template<typename Type>
class ConstantSource : public internal::ConstantSource<Slices, Type> { class ConstantSource : public internal::ConstantSource<Type> {
public: public:
explicit ConstantSource(Type value) explicit ConstantSource(Type value)
: internal::ConstantSource<Slices, Type>(value) { : internal::ConstantSource<Type>(value) {
//empty //empty
} }
}; };
...@@ -800,24 +799,36 @@ class Network : public internal::ClockListener { ...@@ -800,24 +799,36 @@ class Network : public internal::ClockListener {
sources_.push_back(&source); sources_.push_back(&source);
} }
void operator () () { void operator () (int slices) {
slices_ = slices;
internal::SchedulerSequential sched_seq; internal::SchedulerSequential sched_seq;
internal::SchedulerMTAPI<Slices> sched_mtapi; internal::SchedulerMTAPI sched_mtapi(slices_);
internal::Scheduler * sched = &sched_mtapi; internal::Scheduler * sched = &sched_mtapi;
internal::InitData init_data; internal::InitData init_data;
init_data.slices = slices_;
init_data.sched = sched; init_data.sched = sched;
init_data.sink_listener = this; init_data.sink_listener = this;
sink_counter_ = reinterpret_cast<embb::base::Atomic<int>*>(
embb::base::Allocation::Allocate(
sizeof(embb::base::Atomic<int>)*slices_));
for (int ii = 0; ii < slices_; ii++) {
sink_counter_[ii] = 0;
}
sink_count_ = 0; sink_count_ = 0;
for (size_t it = 0; it < sources_.size(); it++) for (size_t it = 0; it < sources_.size(); it++)
sources_[it]->Init(&init_data); sources_[it]->Init(&init_data);
for (int ii = 0; ii < Slices; ii++) sink_counter_[ii] = 0; for (int ii = 0; ii < slices_; ii++) {
sink_counter_[ii] = 0;
}
int clock = 0; int clock = 0;
while (clock >= 0) { while (clock >= 0) {
const int idx = clock % Slices; const int idx = clock % slices_;
while (sink_counter_[idx] > 0) embb::base::Thread::CurrentYield(); while (sink_counter_[idx] > 0) embb::base::Thread::CurrentYield();
sched->WaitForSlice(idx); sched->WaitForSlice(idx);
if (!SpawnClock(clock)) if (!SpawnClock(clock))
...@@ -825,10 +836,10 @@ class Network : public internal::ClockListener { ...@@ -825,10 +836,10 @@ class Network : public internal::ClockListener {
clock++; clock++;
} }
int ii = clock - Slices + 1; int ii = clock - slices_ + 1;
if (ii < 0) ii = 0; if (ii < 0) ii = 0;
for (; ii < clock; ii++) { for (; ii < clock; ii++) {
const int idx = ii % Slices; const int idx = ii % slices_;
while (sink_counter_[idx] > 0) embb::base::Thread::CurrentYield(); while (sink_counter_[idx] > 0) embb::base::Thread::CurrentYield();
sched->WaitForSlice(idx); sched->WaitForSlice(idx);
} }
...@@ -841,7 +852,7 @@ class Network : public internal::ClockListener { ...@@ -841,7 +852,7 @@ class Network : public internal::ClockListener {
* corresponding slot, thus allowing a new token to be emitted. * corresponding slot, thus allowing a new token to be emitted.
*/ */
virtual void OnClock(int clock) { virtual void OnClock(int clock) {
const int idx = clock % Slices; const int idx = clock % slices_;
const int cnt = --sink_counter_[idx]; const int cnt = --sink_counter_[idx];
if (cnt < 0) if (cnt < 0)
EMBB_THROW(embb::base::ErrorException, EMBB_THROW(embb::base::ErrorException,
...@@ -861,15 +872,16 @@ class Network : public internal::ClockListener { ...@@ -861,15 +872,16 @@ class Network : public internal::ClockListener {
std::vector<internal::Node*> processes_; std::vector<internal::Node*> processes_;
std::vector<internal::Node*> sources_; std::vector<internal::Node*> sources_;
std::vector<internal::Node*> sinks_; std::vector<internal::Node*> sinks_;
embb::base::Atomic<int> sink_counter_[Slices]; embb::base::Atomic<int> * sink_counter_;
int sink_count_; int sink_count_;
int slices_;
#if EMBB_DATAFLOW_TRACE_SIGNAL_HISTORY #if EMBB_DATAFLOW_TRACE_SIGNAL_HISTORY
std::vector<int> spawn_history_[Slices]; std::vector<int> spawn_history_[Slices];
#endif #endif
bool SpawnClock(int clock) { bool SpawnClock(int clock) {
const int idx = clock % Slices; const int idx = clock % slices_;
bool result = true; bool result = true;
#if EMBB_DATAFLOW_TRACE_SIGNAL_HISTORY #if EMBB_DATAFLOW_TRACE_SIGNAL_HISTORY
spawn_history_[idx].push_back(clock); spawn_history_[idx].push_back(clock);
......
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
#define NUM_SLICES 8 #define NUM_SLICES 8
#define TEST_COUNT 12 #define TEST_COUNT 12
typedef embb::dataflow::Network<NUM_SLICES> MyNetwork; typedef embb::dataflow::Network MyNetwork;
typedef MyNetwork::ConstantSource< int > MyConstantSource; typedef MyNetwork::ConstantSource< int > MyConstantSource;
typedef MyNetwork::Source< int > MySource; typedef MyNetwork::Source< int > MySource;
typedef MyNetwork::SerialProcess< MyNetwork::Inputs<int>::Type, typedef MyNetwork::SerialProcess< MyNetwork::Inputs<int>::Type,
...@@ -206,7 +206,7 @@ void SimpleTest::TestBasic() { ...@@ -206,7 +206,7 @@ void SimpleTest::TestBasic() {
network.AddSource(source); network.AddSource(source);
try { try {
network(); network(NUM_SLICES);
} catch (embb::base::ErrorException & e) { } catch (embb::base::ErrorException & e) {
PT_ASSERT_MSG(false, e.What()); PT_ASSERT_MSG(false, e.What());
} }
......
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