1
1
#include " param_info.h"
2
2
3
+ #include " quartz/utils/string_utils.h"
4
+
3
5
#include < cassert>
4
6
5
7
namespace quartz {
@@ -36,14 +38,15 @@ std::vector<ParamType> ParamInfo::get_all_generated_parameters() const {
36
38
}
37
39
38
40
ParamType ParamInfo::get_param_value (int id) const {
39
- assert (id >= 0 && id < (int )parameter_values_ .size ());
40
- assert (!is_parameter_symbolic_ [id]);
41
+ assert (id >= 0 && id < (int )parameter_class_ .size ());
42
+ assert (parameter_class_ [id]. is_const () );
41
43
return parameter_values_[id];
42
44
}
43
45
44
46
void ParamInfo::set_param_value (int id, const ParamType ¶m) {
45
- assert (id >= 0 && id < (int )is_parameter_symbolic_.size ());
46
- assert (!is_parameter_symbolic_[id]);
47
+ assert (id >= 0 && id < (int )parameter_class_.size ());
48
+ assert (parameter_class_[id] == ParamClass::concrete_const ||
49
+ parameter_class_[id] == ParamClass::arithmetic_int);
47
50
while (id >= (int )parameter_values_.size ()) {
48
51
parameter_values_.emplace_back ();
49
52
}
@@ -55,10 +58,22 @@ std::vector<ParamType> ParamInfo::get_all_input_param_values() const {
55
58
}
56
59
57
60
int ParamInfo::get_new_param_id (const ParamType ¶m) {
58
- int id = (int )is_parameter_symbolic_.size ();
59
- assert (id == (int )is_parameter_halved_.size ());
60
- is_parameter_symbolic_.push_back (false );
61
- is_parameter_halved_.push_back (false );
61
+ int id = (int )parameter_class_.size ();
62
+ assert (id == (int )parameter_class_.size ());
63
+ parameter_class_.emplace_back (ParamClass::concrete_const);
64
+ auto wire = std::make_unique<CircuitWire>();
65
+ wire->type = CircuitWire::input_param;
66
+ wire->index = id;
67
+ parameter_wires_.push_back (std::move (wire));
68
+ set_param_value (id, param);
69
+ return id;
70
+ }
71
+
72
+ int ParamInfo::get_new_arithmetic_param_id (const ParamType ¶m) {
73
+ int id = (int )parameter_class_.size ();
74
+ assert (id == (int )parameter_class_.size ());
75
+ assert ((int )param == param);
76
+ parameter_class_.emplace_back (ParamClass::arithmetic_int);
62
77
auto wire = std::make_unique<CircuitWire>();
63
78
wire->type = CircuitWire::input_param;
64
79
wire->index = id;
@@ -68,9 +83,9 @@ int ParamInfo::get_new_param_id(const ParamType ¶m) {
68
83
}
69
84
70
85
int ParamInfo::get_new_param_id (bool is_halved) {
71
- int id = (int )is_parameter_symbolic_ .size ();
72
- is_parameter_symbolic_. push_back ( true );
73
- is_parameter_halved_. push_back (is_halved );
86
+ int id = (int )parameter_class_ .size ();
87
+ parameter_class_. emplace_back (is_halved ? ParamClass::symbolic_halved
88
+ : ParamClass::symbolic );
74
89
// Make sure to generate a random parameter for each symbolic parameter.
75
90
gen_random_parameters (id + 1 );
76
91
auto wire = std::make_unique<CircuitWire>();
@@ -83,11 +98,15 @@ int ParamInfo::get_new_param_id(bool is_halved) {
83
98
int ParamInfo::get_new_param_expression_id (
84
99
const std::vector<int > ¶meter_indices, Gate *op) {
85
100
bool is_symbolic = is_symbolic_constant (op);
101
+ bool is_const = true ;
86
102
for (auto &input_id : parameter_indices) {
87
- assert (input_id >= 0 && input_id < (int )is_parameter_symbolic_ .size ());
88
- if (param_is_symbolic ( input_id)) {
103
+ assert (input_id >= 0 && input_id < (int )parameter_class_ .size ());
104
+ if (parameter_class_[ input_id]. is_symbolic ( )) {
89
105
is_symbolic = true ;
90
106
}
107
+ if (!parameter_class_[input_id].is_const ()) {
108
+ is_const = false ;
109
+ }
91
110
}
92
111
if (!is_symbolic) {
93
112
// A concrete parameter, no need to create an expression.
@@ -99,9 +118,9 @@ int ParamInfo::get_new_param_expression_id(
99
118
}
100
119
return get_new_param_id (op->compute (input_params));
101
120
}
102
- int id = (int )is_parameter_symbolic_ .size ();
103
- is_parameter_symbolic_. push_back ( true );
104
- is_parameter_halved_. push_back ( false );
121
+ int id = (int )parameter_class_ .size ();
122
+ parameter_class_. emplace_back (is_const ? ParamClass::symbolic_constexpr
123
+ : ParamClass::expression );
105
124
auto circuit_gate = std::make_unique<CircuitGate>();
106
125
circuit_gate->gate = op;
107
126
for (auto &input_id : parameter_indices) {
@@ -119,21 +138,21 @@ int ParamInfo::get_new_param_expression_id(
119
138
}
120
139
121
140
int ParamInfo::get_num_parameters () const {
122
- return (int )is_parameter_symbolic_ .size ();
141
+ return (int )parameter_class_ .size ();
123
142
}
124
143
125
144
int ParamInfo::get_num_input_symbolic_parameters () const {
126
145
return (int )random_parameters_.size ();
127
146
}
128
147
129
148
bool ParamInfo::param_is_symbolic (int id) const {
130
- return id >= 0 && id < (int )is_parameter_symbolic_ .size () &&
131
- is_parameter_symbolic_ [id];
149
+ return id >= 0 && id < (int )parameter_class_ .size () &&
150
+ parameter_class_ [id]. is_symbolic () ;
132
151
}
133
152
134
- bool ParamInfo::param_has_value (int id) const {
135
- return id >= 0 && id < (int )is_parameter_symbolic_ .size () &&
136
- !is_parameter_symbolic_ [id];
153
+ bool ParamInfo::param_is_const (int id) const {
154
+ return id >= 0 && id < (int )parameter_class_ .size () &&
155
+ parameter_class_ [id]. is_const () ;
137
156
}
138
157
139
158
bool ParamInfo::param_is_expression (int id) const {
@@ -142,8 +161,9 @@ bool ParamInfo::param_is_expression(int id) const {
142
161
}
143
162
144
163
bool ParamInfo::param_is_halved (int id) const {
145
- return id >= 0 && id < (int )is_parameter_halved_.size () &&
146
- is_parameter_halved_[id];
164
+ return id >= 0 && id < (int )parameter_class_.size () &&
165
+ parameter_class_[id] == ParamClass::symbolic_halved;
166
+ // TODO: halved parameter expressions
147
167
}
148
168
149
169
CircuitWire *ParamInfo::get_param_wire (int id) const {
@@ -158,10 +178,10 @@ std::vector<ParamType>
158
178
ParamInfo::compute_parameters (const std::vector<ParamType> &input_parameters) {
159
179
// Creates a param list, assuming that all symbolic params are defined first.
160
180
auto result = input_parameters;
161
- result.resize (is_parameter_symbolic_ .size ());
181
+ result.resize (parameter_class_ .size ());
162
182
// Populates constant parameters.
163
183
for (int i = 0 ; i < result.size (); ++i) {
164
- if (!is_parameter_symbolic_ [i]) {
184
+ if (parameter_class_ [i]. is_const () ) {
165
185
result[i] = parameter_values_[i];
166
186
}
167
187
}
@@ -180,7 +200,7 @@ ParamInfo::compute_parameters(const std::vector<ParamType> &input_parameters) {
180
200
}
181
201
182
202
std::vector<InputParamMaskType> ParamInfo::get_param_masks () const {
183
- std::vector<InputParamMaskType> param_mask (is_parameter_symbolic_ .size ());
203
+ std::vector<InputParamMaskType> param_mask (parameter_class_ .size ());
184
204
for (int i = 0 ; i < (int )param_mask.size (); i++) {
185
205
if (!param_is_expression (i)) {
186
206
param_mask[i] = ((InputParamMaskType)1 ) << i;
@@ -195,4 +215,35 @@ std::vector<InputParamMaskType> ParamInfo::get_param_masks() const {
195
215
}
196
216
return param_mask;
197
217
}
218
+
219
+ std::string ParamInfo::to_json () const {
220
+ std::string result = " [" ;
221
+ result += " [" ;
222
+ result += std::to_string (parameter_class_.size ());
223
+ for (int i = 0 ; i < (int )parameter_class_.size (); i++) {
224
+ result += " , " ;
225
+ if (parameter_class_[i] == ParamClass::arithmetic_int) {
226
+ // arithmetic int
227
+ result += std::to_string ((int )parameter_values_[i]);
228
+ } else if (parameter_class_[i].is_input ()) {
229
+ if (parameter_class_[i].is_symbolic ()) {
230
+ // input symbolic
231
+ result += " \"\" " ;
232
+ // TODO: halved parameter
233
+ } else {
234
+ // input concrete
235
+ result += to_string_with_precision (parameter_values_[i],
236
+ /* precision=*/ 17 );
237
+ }
238
+ } else {
239
+ // expression
240
+ result += parameter_wires_[i]->input_gates [0 ]->to_json ();
241
+ }
242
+ }
243
+ result += " ], " ;
244
+ result += to_json_style_string_with_precision (random_parameters_,
245
+ /* precision=*/ 17 );
246
+ result += " ]" ;
247
+ return result;
248
+ }
198
249
} // namespace quartz
0 commit comments