Hyperiso 1.0.3
Modular flavour-physics calculations, Wilson coefficients and statistical inference
Loading...
Searching...
No Matches
test_little_optimizer.cpp
Go to the documentation of this file.
1#include <iostream>
2#include <chrono>
3#include <memory>
4#include <unordered_map>
5#include <cassert>
6
7#include "Block.h"
8#include "BlockAccessor.h"
10#include "ParamOptimizer.h"
11#include "SourcesView.h"
12
13static std::shared_ptr<Parameter> make_param(const std::string& block, const LhaID& id, double v) {
14 return std::make_shared<Parameter>(ParamId(block, id), v, 0., 0.);
15}
16
17int main() {
18 using clock = std::chrono::steady_clock;
19
20 const int N = 400;
21 const int OPS = 20000;
22 const int id_sum = 3;
23
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) {
27 LhaID id(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));
30 }
31
32 int fused_updates = 0;
33 int sum_updates = 0;
34
35 auto make_fused = [&](auto& fused_ptr){
36 fused_ptr = std::make_shared<DependentBlock>(
37 std::unordered_map<std::string, std::shared_ptr<Block>>{
38 {"SRC_A", SRC_A},
39 {"SRC_B", SRC_B}
40 },
41 [&fused_updates, N](const BlockSrc& srcs, std::shared_ptr<DependentBlock> self) {
42 ++fused_updates;
43 for (int i = 0; i < N; ++i) {
44 LhaID id(i);
45 double a = srcs.get_val("SRC_A", id);
46 double b = srcs.get_val("SRC_B", id);
47 double z = a + b;
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.));
50 }
51 }
52 );
53 fused_ptr->blockname = "FUSED"; fused_ptr->set_scale(1.0);
54 fused_ptr->init();
55 SRC_A->addObserver(fused_ptr);
56 SRC_B->addObserver(fused_ptr);
57 };
58
59 std::shared_ptr<DependentBlock> FUSED;
60 make_fused(FUSED);
61
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();
67
68 auto SUM = std::make_shared<DependentParameter>(
69 ParamId{ParameterType::SM, "DERIVED", LhaID(1000)},
70 std::unordered_map<ParamId, std::shared_ptr<Parameter>>{
71 { a_id, srcA_sum },
72 { b_id, srcB_sum },
73 },
74 [a_id, b_id, &sum_updates](const ParamSrc& src, std::shared_ptr<DependentParameter> self) {
75 ++sum_updates;
76 self->set_expected(src.get_val(a_id) + src.get_val(b_id));
77 }
78 );
79 SUM->init();
80 DERIVED->store(LhaID(1000), SUM);
81
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});
89
90 //sloooow
91 fused_updates = 0; sum_updates = 0;
92 auto t0 = clock::now();
93 for (int k = 0; k < OPS; ++k) {
94 int i = k % N;
95 SRC_A->assign(LhaID(i), double(k) * 0.1);
96 SRC_B->assign(LhaID(i), double(k) * 0.2);
97 }
98 auto t1 = clock::now();
99 auto naive_ms = std::chrono::duration_cast<std::chrono::milliseconds>(t1 - t0).count();
100
101 std::cout << "[NAIF] updates FUSED = " << fused_updates
102 << ", updates SUM = " << sum_updates
103 << ", time = " << naive_ms << " ms\n";
104
105 {
106 int i = 17;
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);
112 }
113
114 //Niiiiiice
115 fused_updates = 0; sum_updates = 0;
116 auto t2 = clock::now();
117 for (int k = 0; k < OPS; ++k) {
118 int i = k % N;
119 opt.set_value("SRC_A", LhaID(i), double(k) * 0.1);
120 opt.set_value("SRC_B", LhaID(i), double(k) * 0.2);
121 }
122 opt.commit(true);
123 auto t3 = clock::now();
124 auto opt_ms = std::chrono::duration_cast<std::chrono::milliseconds>(t3 - t2).count();
125
126 std::cout << "[OPT ] updates FUSED = " << fused_updates
127 << ", updates SUM = " << sum_updates
128 << ", time = " << opt_ms << " ms\n";
129
130 {
131 int i = 123;
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);
137 }
138
139 // opt, store+remove on new keys ()
140 fused_updates = 0; sum_updates = 0;
141 for (int j = 0; j < 100; ++j) {
142 LhaID new_id(N + j);
143 opt.set_value("SRC_A", new_id, 42.0); // store
144 opt.remove("SRC_A", new_id); // sera ignoré (clé inexistante avant commit)
145 }
146 opt.commit(true);
147
148 {
149 int i = 7;
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);
154 }
155
156 std::cout << "OK: cohérence et bench terminés.\n";
157 return 0;
158}
Alias-aware façade for accessing and manipulating multiple parameter blocks.
Defines classes used to store parameters and to build derived/dependent parameter blocks.
Defines parameters whose values are lazily computed from other parameters.
Defines the ParamOptimizer class to apply batched updates to parameters.
Lightweight view over a set of source blocks.
Definition SourcesView.h:71
Helper class to batch parameter updates on one or several BlockAccessor scopes.
Lightweight view over a set of source parameters keyed by ParamId.
Represents an identifier of a LHA element, possibly containing several sub-ids.
Definition LhaID.h:56
Composite identifier for a single parameter.
Definition ParamID.h:57