18 using clock = std::chrono::steady_clock;
21 const int OPS = 20000;
24 auto SRC_A = std::make_shared<Block>(); SRC_A->blockname =
"SRC_A"; SRC_A->set_scale(1.0);
25 auto SRC_B = std::make_shared<Block>(); SRC_B->blockname =
"SRC_B"; SRC_B->set_scale(1.0);
26 for (
int i = 0; i < N; ++i) {
28 SRC_A->store(
id, make_param(
"SRC_A",
id, 1.0*i));
29 SRC_B->store(
id, make_param(
"SRC_B",
id, 2.0*i));
32 int fused_updates = 0;
35 auto make_fused = [&](
auto& fused_ptr){
36 fused_ptr = std::make_shared<DependentBlock>(
37 std::unordered_map<std::string, std::shared_ptr<Block>>{
41 [&fused_updates, N](
const BlockSrc& srcs, std::shared_ptr<DependentBlock> self) {
43 for (
int i = 0; i < N; ++i) {
45 double a = srcs.get_val(
"SRC_A",
id);
46 double b = srcs.get_val(
"SRC_B",
id);
48 if (self->contains(
id)) self->assign(
id, z);
49 else self->store(
id, std::make_shared<Parameter>(
ParamId(self->get_name(),
id), z, 0., 0.));
53 fused_ptr->blockname =
"FUSED"; fused_ptr->set_scale(1.0);
55 SRC_A->addObserver(fused_ptr);
56 SRC_B->addObserver(fused_ptr);
59 std::shared_ptr<DependentBlock> FUSED;
62 auto DERIVED = std::make_shared<Block>(); DERIVED->blockname =
"DERIVED"; DERIVED->set_scale(1.0);
63 auto srcA_sum = SRC_A->retrieve(
LhaID(id_sum));
64 auto srcB_sum = SRC_B->retrieve(
LhaID(id_sum));
65 const ParamId a_id = srcA_sum->get_id();
66 const ParamId b_id = srcB_sum->get_id();
68 auto SUM = std::make_shared<DependentParameter>(
70 std::unordered_map<ParamId, std::shared_ptr<Parameter>>{
74 [a_id, b_id, &sum_updates](
const ParamSrc& src, std::shared_ptr<DependentParameter> self) {
76 self->set_expected(src.get_val(a_id) + src.get_val(b_id));
80 DERIVED->store(
LhaID(1000), SUM);
82 auto BA1 = std::make_shared<BlockAccessor>();
83 BA1->emplace(
"SRC_A", SRC_A);
84 BA1->emplace(
"FUSED", FUSED);
85 auto BA2 = std::make_shared<BlockAccessor>();
86 BA2->emplace(
"SRC_B", SRC_B);
87 BA2->emplace(
"DERIVED", DERIVED);
88 ParamOptimizer opt(std::vector<std::shared_ptr<BlockAccessor>>{BA1, BA2});
91 fused_updates = 0; sum_updates = 0;
92 auto t0 = clock::now();
93 for (
int k = 0; k < OPS; ++k) {
95 SRC_A->assign(
LhaID(i),
double(k) * 0.1);
96 SRC_B->assign(
LhaID(i),
double(k) * 0.2);
98 auto t1 = clock::now();
99 auto naive_ms = std::chrono::duration_cast<std::chrono::milliseconds>(t1 - t0).count();
101 std::cout <<
"[NAIF] updates FUSED = " << fused_updates
102 <<
", updates SUM = " << sum_updates
103 <<
", time = " << naive_ms <<
" ms\n";
107 double a = SRC_A->retrieve(
LhaID(i))->get_val();
108 double b = SRC_B->retrieve(
LhaID(i))->get_val();
109 double z = FUSED->retrieve(
LhaID(i))->get_val();
110 assert(std::abs(z - (a+b)) < 1e-12);
111 assert(std::abs(SUM->get_val() - (srcA_sum->get_val()+srcB_sum->get_val())) < 1e-12);
115 fused_updates = 0; sum_updates = 0;
116 auto t2 = clock::now();
117 for (
int k = 0; k < OPS; ++k) {
119 opt.set_value(
"SRC_A",
LhaID(i),
double(k) * 0.1);
120 opt.set_value(
"SRC_B",
LhaID(i),
double(k) * 0.2);
123 auto t3 = clock::now();
124 auto opt_ms = std::chrono::duration_cast<std::chrono::milliseconds>(t3 - t2).count();
126 std::cout <<
"[OPT ] updates FUSED = " << fused_updates
127 <<
", updates SUM = " << sum_updates
128 <<
", time = " << opt_ms <<
" ms\n";
132 double a = SRC_A->retrieve(
LhaID(i))->get_val();
133 double b = SRC_B->retrieve(
LhaID(i))->get_val();
134 double z = FUSED->retrieve(
LhaID(i))->get_val();
135 assert(std::abs(z - (a+b)) < 1e-12);
136 assert(std::abs(SUM->get_val() - (srcA_sum->get_val()+srcB_sum->get_val())) < 1e-12);
140 fused_updates = 0; sum_updates = 0;
141 for (
int j = 0; j < 100; ++j) {
143 opt.set_value(
"SRC_A", new_id, 42.0);
144 opt.remove(
"SRC_A", new_id);
150 double a = SRC_A->retrieve(
LhaID(i))->get_val();
151 double b = SRC_B->retrieve(
LhaID(i))->get_val();
152 double z = FUSED->retrieve(
LhaID(i))->get_val();
153 assert(std::abs(z - (a+b)) < 1e-12);
156 std::cout <<
"OK: cohérence et bench terminés.\n";