Skip to content

Commit 2e4c112

Browse files
committed
init mutations
1 parent 1357972 commit 2e4c112

39 files changed

+862
-130
lines changed

examples/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@ add_subdirectory(count)
77
add_subdirectory(ports)
88
add_subdirectory(hello)
99
add_subdirectory(power_train)
10+
add_subdirectory(multiport_mutation)
11+
add_subdirectory(unit_tests_mutations)

examples/count/main.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ class Count : public Reactor {
1212
LogicalAction<int> counter{"counter", this};
1313

1414
// reactions_
15-
Reaction r_init{"r_init", 1, this, [this]() { init(); }};
16-
Reaction r_counter{"r_counter", 2, this, [this]() { print_count(); }};
15+
Reaction r_init{"r_init", 1, false, this, [this]() { this->init(); }};
16+
Reaction r_counter{"r_counter", 2, false, this, [this]() { this->print_count(); }};
1717

1818
public:
1919
explicit Count(Environment* env)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
add_executable(mutation_multiports main.cc)
2+
target_link_libraries(mutation_multiports reactor-cpp)
3+
add_dependencies(examples mutation_multiports)
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
//
2+
// Created by tanneberger on 11/17/24.
3+
//
4+
5+
#ifndef CONSUMER_HH
6+
#define CONSUMER_HH
7+
8+
#include <reactor-cpp/reactor-cpp.hh>
9+
10+
using namespace reactor;
11+
using namespace std::chrono_literals;
12+
13+
class Consumer : public Reactor {
14+
private:
15+
class Inner: public Scope {
16+
Inner(Reactor* reactor, std::size_t index) : Scope(reactor), index_(index) {}
17+
std::size_t index_;
18+
19+
[[maybe_unused]] const Inner& __lf_inner = *this;
20+
21+
void reaction_1([[maybe_unused]] const Input<unsigned>& scale) {
22+
std::cout << "consumer: " << index_ << " received value!" << std::endl;
23+
}
24+
25+
friend Consumer;
26+
};
27+
28+
Inner __lf_inner;
29+
Reaction handle{"handle", 1, this, [this]() { __lf_inner.reaction_1(this->in); }};
30+
public:
31+
Consumer(const std::string& name, Environment* env, std::size_t index) : Reactor(name, env), __lf_inner(this, index) {
32+
std::cout << "creating instance of consumer" << std::endl;
33+
}
34+
~Consumer() override {
35+
std::cout << "Consumer Object is deleted" << std::endl;
36+
};
37+
38+
Input<unsigned> in{"in", this};
39+
40+
void assemble() override {
41+
handle.declare_trigger(&in);
42+
}
43+
};
44+
45+
46+
#endif //CONSUMER_HH
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
//
2+
// Created by tanneberger on 11/17/24.
3+
//
4+
5+
#ifndef LOAD_BALANCER_HH
6+
#define LOAD_BALANCER_HH
7+
8+
#include <reactor-cpp/reactor-cpp.hh>
9+
10+
#include "../../lib/mutation/multiport.cc"
11+
#include "reactor-cpp/mutations/multiport.hh"
12+
13+
using namespace reactor;
14+
using namespace std::chrono_literals;
15+
16+
class LoadBalancer : public Reactor {
17+
private:
18+
class Inner: public MutableScope {
19+
Inner(Reactor* reactor) : MutableScope(reactor) {}
20+
[[maybe_unused]] const Inner& __lf_inner = *this;
21+
22+
// reaction bodies
23+
void reaction_1(const Input<unsigned>& inbound, LogicalAction<unsigned>& scale_action, Multiport<Output<unsigned>>& outbound) {
24+
if (rand() % 30 == 0) {
25+
scale_action.schedule(rand() % 20 + 1);
26+
}
27+
28+
std::cout << "multiport size: " << outbound.size() << std::endl;
29+
outbound[rand() % outbound.size()].set(inbound.get());
30+
}
31+
32+
void reaction_2(ModifableMultiport<Output<unsigned>>&outbound, [[maybe_unused]] const LogicalAction<unsigned>& scale, Output<unsigned>& scale_bank) {
33+
ModifableMultiport<Output<unsigned>>* temp = &outbound;
34+
std::size_t new_size = *scale.get();
35+
36+
auto antideps = (outbound[0]).anti_dependencies();
37+
38+
MutationChangeOutputMultiportSize change_size{temp, this->reactor_, antideps, new_size};
39+
40+
add_to_transaction(&change_size);
41+
42+
commit_transaction();
43+
44+
scale_bank.set(new_size);
45+
}
46+
47+
friend LoadBalancer;
48+
};
49+
50+
Inner __lf_inner;
51+
Reaction process{"process", 2, this, [this]() { __lf_inner.reaction_1(this->inbound, this->scale_action, this->out); }};
52+
Reaction scale{"scale", 1, this, [this]() { __lf_inner.reaction_2(this->out, this->scale_action, this->scale_bank); }};
53+
54+
public:
55+
LoadBalancer(const std::string& name, Environment* env)
56+
: Reactor(name, env), __lf_inner(this) {
57+
std::cout << "creating instance of load balancer" << std::endl;
58+
out.reserve(4);
59+
for (size_t _lf_idx = 0; _lf_idx < 4; _lf_idx++) {
60+
std::string _lf_port_name = out.name() + "_" + std::to_string(_lf_idx);
61+
out.emplace_back(_lf_port_name, this);
62+
}
63+
}
64+
65+
LogicalAction<unsigned> scale_action{"scale", this, 1us};
66+
ModifableMultiport<Output<unsigned>> out{"out"};
67+
Input<unsigned> inbound{"inbound", this}; // NOLINT
68+
Output<unsigned> scale_bank{"scale_bank", this};
69+
70+
void assemble() override {
71+
std::cout << "assemble LoadBalancer\n";
72+
for (auto& __lf_port : out) {
73+
process.declare_antidependency(&__lf_port);
74+
}
75+
process.declare_trigger(&inbound);
76+
scale.declare_trigger(&scale_action);
77+
}
78+
};
79+
80+
81+
82+
#endif //LOAD_BALANCER_HH

examples/multiport_mutation/main.cc

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
#include <iostream>
2+
3+
#include <reactor-cpp/mutations/bank.hh>
4+
#include <reactor-cpp/mutations/connection.hh>
5+
6+
#include "./consumer.hh"
7+
#include "./load_balancer.hh"
8+
#include "./producer.hh"
9+
#include "../../lib/mutation/bank.cc"
10+
#include "../../lib/mutation/connection.cc"
11+
#include <reactor-cpp/reactor-cpp.hh>
12+
13+
class Deployment : public Reactor {
14+
std::unique_ptr<Producer> producer_;
15+
std::unique_ptr<LoadBalancer> load_balancer_;
16+
std::vector<std::unique_ptr<Consumer>> consumers_;
17+
18+
Reaction scale_bank{"scale_bank", 1, this, [this](){this->__inner.reaction_1(this->scale, this->consumers_, load_balancer_->out);}};
19+
20+
public:
21+
22+
class Inner: public MutableScope {
23+
int state = 0;
24+
[[maybe_unused]] const Inner& __lf_inner = *this;
25+
public:
26+
27+
Inner(Reactor* reactor) : MutableScope(reactor) {}
28+
void reaction_1(const Input<unsigned>& scale, std::vector<std::unique_ptr<Consumer>>& reactor_bank, ModifableMultiport<Output<unsigned>>& load_balancer) {
29+
std::size_t new_size = *scale.get();
30+
std::size_t old_size = reactor_bank.size();
31+
32+
std::function<std::unique_ptr<Consumer>(Reactor*, std::size_t)> lambda = [](Reactor* reactor, std::size_t index) {
33+
std::string __lf_inst_name = "consumer_" + std::to_string(index);
34+
return std::make_unique<Consumer>(__lf_inst_name, reactor->environment(), index);
35+
};
36+
MutationChangeBankSize change_size{&reactor_bank, this->reactor_, new_size, lambda};
37+
38+
add_to_transaction(&change_size);
39+
40+
// old topology
41+
commit_transaction();
42+
// new topology
43+
44+
if (old_size > new_size) {
45+
46+
for (auto i = 0; i < old_size - new_size; i++) {
47+
}
48+
} else {
49+
std::cout << "load_balancer size:" << load_balancer.size() << " bank size: " << reactor_bank.size() << std::endl;
50+
for (auto i = 0; i < new_size - old_size; i++) {
51+
std::cout << "add connection: " << i + old_size << std::endl;
52+
MutationAddConnection<Output<unsigned>, Input<unsigned>> add_conn{&load_balancer[i + old_size], &reactor_bank[i + old_size].get()->in, reactor_};
53+
add_to_transaction(&add_conn);
54+
commit_transaction();
55+
}
56+
}
57+
58+
std::cout << "new bank size:" << reactor_bank.size() << std::endl;
59+
}
60+
61+
friend LoadBalancer;
62+
};
63+
64+
Inner __inner;
65+
66+
Deployment(const std::string& name, Environment* env) : Reactor(name, env), __inner(this),
67+
producer_(std::make_unique<Producer>("producer", environment())),
68+
load_balancer_(std::make_unique<LoadBalancer>("load_balancer", environment())) {
69+
std::cout << "creating instance of deployment" << std::endl;
70+
consumers_.reserve(4);
71+
for (size_t __lf_idx = 0; __lf_idx < 4; __lf_idx++) {
72+
std::string __lf_inst_name = "consumer_" + std::to_string(__lf_idx);
73+
consumers_.push_back(std::make_unique<Consumer>(__lf_inst_name, environment(), __lf_idx));
74+
}
75+
}
76+
~Deployment() override = default;
77+
78+
Input<unsigned> scale{"scale", this};
79+
80+
void assemble() override {
81+
for (size_t __lf_idx = 0; __lf_idx < 4; __lf_idx++) {
82+
environment()->draw_connection(load_balancer_->out[__lf_idx], consumers_[__lf_idx]->in, ConnectionProperties{});
83+
environment()->draw_connection(producer_->value, load_balancer_->inbound, ConnectionProperties{});
84+
}
85+
environment()->draw_connection(load_balancer_->scale_bank, scale, ConnectionProperties{});
86+
scale_bank.declare_trigger(&this->scale);
87+
}
88+
};
89+
90+
91+
auto main() -> int {
92+
//srand(time(nullptr));
93+
Environment env{4};
94+
auto deployment = std::make_unique<Deployment>("c1", &env);
95+
env.optimize();
96+
env.assemble();
97+
auto thread = env.startup();
98+
thread.join();
99+
return 0;
100+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
//
2+
// Created by tanneberger on 11/17/24.
3+
//
4+
5+
#ifndef PRODUCER_HH
6+
#define PRODUCER_HH
7+
8+
#include <reactor-cpp/reactor-cpp.hh>
9+
10+
using namespace reactor;
11+
using namespace std::chrono_literals;
12+
13+
class Producer : public Reactor {
14+
private:
15+
Timer timer{"timer", this, 1s, 1s};
16+
Reaction r_timer{"r_timer", 1, this, [this]() { __lf_inner.reaction_1(this->value);}};
17+
18+
class Inner: public Scope {
19+
[[maybe_unused]] const Inner& __lf_inner = *this;
20+
void reaction_1([[maybe_unused]] Output<unsigned>& out) {
21+
std::cout << "producing value" << std::endl;
22+
out.set(42);
23+
}
24+
explicit Inner(Reactor* reactor) : Scope(reactor) {}
25+
26+
friend Producer;
27+
};
28+
29+
Inner __lf_inner;
30+
public:
31+
Producer(const std::string& name, Environment* env) : Reactor(name, env), __lf_inner(this) {
32+
std::cout << "creating instance of producer" << std::endl;
33+
}
34+
Producer() = delete;
35+
~Producer() override = default;
36+
37+
Output<unsigned> value{"value", this};
38+
39+
void assemble() override {
40+
r_timer.declare_trigger(&timer);
41+
r_timer.declare_antidependency(&value);
42+
}
43+
};
44+
45+
#endif //PRODUCER_HH

examples/ports/main.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ class Counter : public Reactor {
5151

5252
class Printer : public Reactor {
5353
private:
54-
Reaction r_value{"r_value", 1, this, [this]() { on_value(); }};
54+
Reaction r_value{"r_value", 1, this, [this]() { this->on_value(); }};
5555

5656
public:
5757
Input<int> value{"value", this}; // NOLINT
@@ -69,7 +69,7 @@ class Printer : public Reactor {
6969

7070
class Adder : public Reactor {
7171
private:
72-
Reaction r_add{"r_add", 1, this, [this]() { add(); }};
72+
Reaction r_add{"r_add", 1, this, [this]() { this->add(); }};
7373

7474
public:
7575
Input<int> i1{"i1", this}; // NOLINT
@@ -85,7 +85,7 @@ class Adder : public Reactor {
8585
r_add.declare_antidependency(&sum);
8686
}
8787

88-
void add(Adder* self) {
88+
void add() {
8989
if (i1.is_present() && i2.is_present()) {
9090
sum.set(*i1.get() + *i2.get());
9191
std::cout << "setting sum\n";
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
add_executable(unit_tests_mutations main.cc)
2+
target_link_libraries(unit_tests_mutations reactor-cpp)
3+
add_dependencies(examples unit_tests_mutations)

0 commit comments

Comments
 (0)