• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

daisytuner / sdfglib / 15454586163

04 Jun 2025 11:09PM UTC coverage: 58.236% (-0.03%) from 58.264%
15454586163

push

github

web-flow
Merge pull request #55 from daisytuner/deserialization

deserialize element ids

80 of 108 new or added lines in 1 file covered. (74.07%)

1 existing line in 1 file now uncovered.

8160 of 14012 relevant lines covered (58.24%)

107.27 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

82.23
/src/serializer/json_serializer.cpp
1
#include "sdfg/serializer/json_serializer.h"
2

3
#include <cassert>
4
#include <memory>
5
#include <unordered_map>
6
#include <utility>
7
#include <vector>
8

9
#include "sdfg/builder/structured_sdfg_builder.h"
10
#include "sdfg/data_flow/library_node.h"
11
#include "sdfg/element.h"
12
#include "sdfg/structured_control_flow/block.h"
13
#include "sdfg/structured_control_flow/for.h"
14
#include "sdfg/structured_control_flow/if_else.h"
15
#include "sdfg/structured_control_flow/kernel.h"
16
#include "sdfg/structured_control_flow/return.h"
17
#include "sdfg/structured_control_flow/sequence.h"
18
#include "sdfg/structured_control_flow/while.h"
19
#include "sdfg/structured_sdfg.h"
20
#include "sdfg/symbolic/symbolic.h"
21
#include "sdfg/types/function.h"
22
#include "sdfg/types/scalar.h"
23
#include "sdfg/types/type.h"
24
#include "symengine/expression.h"
25
#include "symengine/logic.h"
26
#include "symengine/symengine_rcp.h"
27

28
namespace sdfg {
29
namespace serializer {
30

31
/*
32
 * * JSONSerializer class
33
 * * Serialization logic
34
 */
35

36
nlohmann::json JSONSerializer::serialize(std::unique_ptr<sdfg::StructuredSDFG>& sdfg) {
3✔
37
    nlohmann::json j;
3✔
38

39
    j["name"] = sdfg->name();
3✔
40

41
    j["structures"] = nlohmann::json::array();
3✔
42
    for (const auto& structure_name : sdfg->structures()) {
3✔
43
        const auto& structure = sdfg->structure(structure_name);
×
44
        nlohmann::json structure_json;
×
45
        structure_definition_to_json(structure_json, structure);
×
46
        j["structures"].push_back(structure_json);
×
47
    }
×
48

49
    j["containers"] = nlohmann::json::object();
3✔
50
    for (const auto& container : sdfg->containers()) {
8✔
51
        nlohmann::json desc;
5✔
52
        type_to_json(desc, sdfg->type(container));
5✔
53
        j["containers"][container] = desc;
5✔
54
    }
5✔
55

56
    j["arguments"] = nlohmann::json::array();
3✔
57
    for (const auto& argument : sdfg->arguments()) {
5✔
58
        j["arguments"].push_back(argument);
2✔
59
    }
60

61
    j["externals"] = nlohmann::json::array();
3✔
62
    for (const auto& external : sdfg->externals()) {
3✔
63
        j["externals"].push_back(external);
×
64
    }
65

66
    j["metadata"] = nlohmann::json::object();
3✔
67
    for (const auto& entry : sdfg->metadata()) {
4✔
68
        j["metadata"][entry.first] = entry.second;
1✔
69
    }
70

71
    // Walk the SDFG
72
    nlohmann::json root_json;
3✔
73
    sequence_to_json(root_json, sdfg->root());
3✔
74
    j["root"] = root_json;
3✔
75

76
    return j;
3✔
77
}
3✔
78

79
void JSONSerializer::dataflow_to_json(nlohmann::json& j, const data_flow::DataFlowGraph& dataflow) {
22✔
80
    j["type"] = "dataflow";
22✔
81
    j["nodes"] = nlohmann::json::array();
22✔
82
    j["edges"] = nlohmann::json::array();
22✔
83

84
    for (auto& node : dataflow.nodes()) {
42✔
85
        nlohmann::json node_json;
20✔
86
        node_json["element_id"] = node.element_id();
20✔
87

88
        node_json["debug_info"] = nlohmann::json::object();
20✔
89
        debug_info_to_json(node_json["debug_info"], node.debug_info());
20✔
90

91
        if (auto code_node = dynamic_cast<const data_flow::Tasklet*>(&node)) {
20✔
92
            node_json["type"] = "tasklet";
5✔
93
            node_json["code"] = code_node->code();
5✔
94
            node_json["inputs"] = nlohmann::json::array();
5✔
95
            for (auto& input : code_node->inputs()) {
15✔
96
                nlohmann::json input_json;
10✔
97
                nlohmann::json type_json;
10✔
98
                type_to_json(type_json, input.second);
10✔
99
                input_json["type"] = type_json;
10✔
100
                input_json["name"] = input.first;
10✔
101
                node_json["inputs"].push_back(input_json);
10✔
102
            }
10✔
103
            node_json["outputs"] = nlohmann::json::array();
5✔
104
            for (auto& output : code_node->outputs()) {
10✔
105
                nlohmann::json output_json;
5✔
106
                nlohmann::json type_json;
5✔
107
                type_to_json(type_json, output.second);
5✔
108
                output_json["type"] = type_json;
5✔
109
                output_json["name"] = output.first;
5✔
110
                node_json["outputs"].push_back(output_json);
5✔
111
            }
5✔
112
            // node_json["conditional"] = code_node->is_conditional();
113
            // if (code_node->is_conditional()) {
114
            //     node_json["condition"] = dumps_expression(code_node->condition());
115
            // }
116
        } else if (auto lib_node = dynamic_cast<const data_flow::LibraryNode*>(&node)) {
20✔
117
            node_json["type"] = "library_node";
×
118
            node_json["call"] = lib_node->call();
×
119
            node_json["has_side_effect"] = lib_node->has_side_effect();
×
120
            node_json["inputs"] = nlohmann::json::array();
×
121
            for (auto& input : lib_node->inputs()) {
×
122
                nlohmann::json input_json;
×
123
                nlohmann::json type_json;
×
124
                type_to_json(type_json, input.second);
×
125
                input_json["type"] = type_json;
×
126
                input_json["name"] = input.first;
×
127
                node_json["inputs"].push_back(input_json);
×
128
            }
×
129
            node_json["outputs"] = nlohmann::json::array();
×
130
            for (auto& output : lib_node->outputs()) {
×
131
                nlohmann::json output_json;
×
132
                nlohmann::json type_json;
×
133
                type_to_json(type_json, output.second);
×
134
                output_json["type"] = type_json;
×
135
                output_json["name"] = output.first;
×
136
                node_json["outputs"].push_back(output_json);
×
137
            }
×
138
        } else if (auto code_node = dynamic_cast<const data_flow::AccessNode*>(&node)) {
15✔
139
            node_json["type"] = "access_node";
15✔
140
            node_json["data"] = code_node->data();
15✔
141
        } else {
15✔
142
            throw std::runtime_error("Unknown node type");
×
143
        }
144

145
        j["nodes"].push_back(node_json);
20✔
146
    }
20✔
147

148
    for (auto& edge : dataflow.edges()) {
37✔
149
        nlohmann::json edge_json;
15✔
150
        edge_json["element_id"] = edge.element_id();
15✔
151

152
        edge_json["debug_info"] = nlohmann::json::object();
15✔
153
        debug_info_to_json(edge_json["debug_info"], edge.debug_info());
15✔
154

155
        edge_json["src"] = edge.src().element_id();
15✔
156
        edge_json["dst"] = edge.dst().element_id();
15✔
157

158
        edge_json["src_conn"] = edge.src_conn();
15✔
159
        edge_json["dst_conn"] = edge.dst_conn();
15✔
160

161
        edge_json["subset"] = nlohmann::json::array();
15✔
162
        for (auto& subset : edge.subset()) {
21✔
163
            edge_json["subset"].push_back(expression(subset));
6✔
164
        }
165

166
        j["edges"].push_back(edge_json);
15✔
167
    }
15✔
168
}
22✔
169

170
void JSONSerializer::block_to_json(nlohmann::json& j, const structured_control_flow::Block& block) {
20✔
171
    j["type"] = "block";
20✔
172
    j["element_id"] = block.element_id();
20✔
173

174
    j["debug_info"] = nlohmann::json::object();
20✔
175
    debug_info_to_json(j["debug_info"], block.debug_info());
20✔
176

177
    nlohmann::json dataflow_json;
20✔
178
    dataflow_to_json(dataflow_json, block.dataflow());
20✔
179
    j["dataflow"] = dataflow_json;
20✔
180
}
20✔
181

182
void JSONSerializer::for_to_json(nlohmann::json& j, const structured_control_flow::For& for_node) {
2✔
183
    j["type"] = "for";
2✔
184
    j["element_id"] = for_node.element_id();
2✔
185

186
    j["debug_info"] = nlohmann::json::object();
2✔
187
    debug_info_to_json(j["debug_info"], for_node.debug_info());
2✔
188

189
    j["indvar"] = expression(for_node.indvar());
2✔
190
    j["init"] = expression(for_node.init());
2✔
191
    j["condition"] = expression(for_node.condition());
2✔
192
    j["update"] = expression(for_node.update());
2✔
193

194
    nlohmann::json body_json;
2✔
195
    sequence_to_json(body_json, for_node.root());
2✔
196
    j["root"] = body_json;
2✔
197
}
2✔
198

199
void JSONSerializer::if_else_to_json(nlohmann::json& j,
2✔
200
                                     const structured_control_flow::IfElse& if_else_node) {
201
    j["type"] = "if_else";
2✔
202
    j["element_id"] = if_else_node.element_id();
2✔
203

204
    j["debug_info"] = nlohmann::json::object();
2✔
205
    debug_info_to_json(j["debug_info"], if_else_node.debug_info());
2✔
206

207
    j["branches"] = nlohmann::json::array();
2✔
208
    for (size_t i = 0; i < if_else_node.size(); i++) {
6✔
209
        nlohmann::json branch_json;
4✔
210
        branch_json["condition"] = expression(if_else_node.at(i).second);
4✔
211
        nlohmann::json body_json;
4✔
212
        sequence_to_json(body_json, if_else_node.at(i).first);
4✔
213
        branch_json["root"] = body_json;
4✔
214
        j["branches"].push_back(branch_json);
4✔
215
    }
4✔
216
}
2✔
217

218
void JSONSerializer::while_node_to_json(nlohmann::json& j,
5✔
219
                                        const structured_control_flow::While& while_node) {
220
    j["type"] = "while";
5✔
221
    j["element_id"] = while_node.element_id();
5✔
222

223
    j["debug_info"] = nlohmann::json::object();
5✔
224
    debug_info_to_json(j["debug_info"], while_node.debug_info());
5✔
225

226
    nlohmann::json body_json;
5✔
227
    sequence_to_json(body_json, while_node.root());
5✔
228
    j["root"] = body_json;
5✔
229
}
5✔
230

231
void JSONSerializer::break_node_to_json(nlohmann::json& j,
2✔
232
                                        const structured_control_flow::Break& break_node) {
233
    j["type"] = "break";
2✔
234
    j["element_id"] = break_node.element_id();
2✔
235

236
    j["debug_info"] = nlohmann::json::object();
2✔
237
    debug_info_to_json(j["debug_info"], break_node.debug_info());
2✔
238
}
2✔
239

240
void JSONSerializer::continue_node_to_json(nlohmann::json& j,
2✔
241
                                           const structured_control_flow::Continue& continue_node) {
242
    j["type"] = "continue";
2✔
243
    j["element_id"] = continue_node.element_id();
2✔
244

245
    j["debug_info"] = nlohmann::json::object();
2✔
246
    debug_info_to_json(j["debug_info"], continue_node.debug_info());
2✔
247
}
2✔
248

249
void JSONSerializer::kernel_to_json(nlohmann::json& j,
2✔
250
                                    const structured_control_flow::Kernel& kernel_node) {
251
    j["type"] = "kernel";
2✔
252
    j["element_id"] = kernel_node.element_id();
2✔
253

254
    j["debug_info"] = nlohmann::json::object();
2✔
255
    debug_info_to_json(j["debug_info"], kernel_node.debug_info());
2✔
256

257
    j["suffix"] = kernel_node.suffix();
2✔
258

259
    nlohmann::json body_json;
2✔
260
    sequence_to_json(body_json, kernel_node.root());
2✔
261
    j["root"] = body_json;
2✔
262
}
2✔
263

264
void JSONSerializer::map_to_json(nlohmann::json& j, const structured_control_flow::Map& map_node) {
2✔
265
    j["type"] = "map";
2✔
266
    j["element_id"] = map_node.element_id();
2✔
267

268
    j["debug_info"] = nlohmann::json::object();
2✔
269
    debug_info_to_json(j["debug_info"], map_node.debug_info());
2✔
270

271
    j["indvar"] = expression(map_node.indvar());
2✔
272
    j["num_iterations"] = expression(map_node.num_iterations());
2✔
273
    nlohmann::json body_json;
2✔
274
    sequence_to_json(body_json, map_node.root());
2✔
275
    j["root"] = body_json;
2✔
276
}
2✔
277

278
void JSONSerializer::return_node_to_json(nlohmann::json& j,
2✔
279
                                         const structured_control_flow::Return& return_node) {
280
    j["type"] = "return";
2✔
281
    j["element_id"] = return_node.element_id();
2✔
282

283
    j["debug_info"] = nlohmann::json::object();
2✔
284
    debug_info_to_json(j["debug_info"], return_node.debug_info());
2✔
285
}
2✔
286

287
void JSONSerializer::sequence_to_json(nlohmann::json& j,
21✔
288
                                      const structured_control_flow::Sequence& sequence) {
289
    j["type"] = "sequence";
21✔
290
    j["element_id"] = sequence.element_id();
21✔
291

292
    j["debug_info"] = nlohmann::json::object();
21✔
293
    debug_info_to_json(j["debug_info"], sequence.debug_info());
21✔
294

295
    j["children"] = nlohmann::json::array();
21✔
296
    j["transitions"] = nlohmann::json::array();
21✔
297

298
    for (size_t i = 0; i < sequence.size(); i++) {
43✔
299
        nlohmann::json child_json;
22✔
300
        auto& child = sequence.at(i).first;
22✔
301
        auto& transition = sequence.at(i).second;
22✔
302

303
        if (auto block = dynamic_cast<const structured_control_flow::Block*>(&child)) {
22✔
304
            block_to_json(child_json, *block);
18✔
305
        } else if (auto for_node = dynamic_cast<const structured_control_flow::For*>(&child)) {
22✔
306
            for_to_json(child_json, *for_node);
×
307
        } else if (auto sequence_node =
4✔
308
                       dynamic_cast<const structured_control_flow::Sequence*>(&child)) {
4✔
309
            sequence_to_json(child_json, *sequence_node);
×
310
        } else if (auto condition_node =
4✔
311
                       dynamic_cast<const structured_control_flow::IfElse*>(&child)) {
4✔
312
            if_else_to_json(child_json, *condition_node);
×
313
        } else if (auto while_node = dynamic_cast<const structured_control_flow::While*>(&child)) {
4✔
314
            while_node_to_json(child_json, *while_node);
×
315
        } else if (auto kernel_node =
4✔
316
                       dynamic_cast<const structured_control_flow::Kernel*>(&child)) {
4✔
317
            kernel_to_json(child_json, *kernel_node);
×
318
        } else if (auto return_node =
4✔
319
                       dynamic_cast<const structured_control_flow::Return*>(&child)) {
4✔
320
            return_node_to_json(child_json, *return_node);
×
321
        } else if (auto break_node = dynamic_cast<const structured_control_flow::Break*>(&child)) {
4✔
322
            break_node_to_json(child_json, *break_node);
2✔
323
        } else if (auto continue_node =
4✔
324
                       dynamic_cast<const structured_control_flow::Continue*>(&child)) {
2✔
325
            continue_node_to_json(child_json, *continue_node);
2✔
326
        } else if (auto map_node = dynamic_cast<const structured_control_flow::Map*>(&child)) {
2✔
327
            map_to_json(child_json, *map_node);
×
328
        } else {
×
329
            throw std::runtime_error("Unknown child type");
×
330
        }
331

332
        j["children"].push_back(child_json);
22✔
333

334
        // Add transition information
335
        nlohmann::json transition_json;
22✔
336
        transition_json["type"] = "transition";
22✔
337
        transition_json["element_id"] = transition.element_id();
22✔
338

339
        transition_json["debug_info"] = nlohmann::json::object();
22✔
340
        debug_info_to_json(transition_json["debug_info"], transition.debug_info());
22✔
341

342
        transition_json["assignments"] = nlohmann::json::array();
22✔
343
        for (const auto& assignment : transition.assignments()) {
24✔
344
            nlohmann::json assignment_json;
2✔
345
            assignment_json["symbol"] = expression(assignment.first);
2✔
346
            assignment_json["expression"] = expression(assignment.second);
2✔
347
            transition_json["assignments"].push_back(assignment_json);
2✔
348
        }
2✔
349

350
        j["transitions"].push_back(transition_json);
22✔
351
    }
22✔
352
}
21✔
353

354
void JSONSerializer::type_to_json(nlohmann::json& j, const types::IType& type) {
43✔
355
    if (auto scalar_type = dynamic_cast<const types::Scalar*>(&type)) {
43✔
356
        j["type"] = "scalar";
33✔
357
        j["primitive_type"] = scalar_type->primitive_type();
33✔
358
        j["address_space"] = scalar_type->address_space();
33✔
359
        j["initializer"] = scalar_type->initializer();
33✔
360
        j["device_location"] = scalar_type->device_location();
33✔
361
    } else if (auto array_type = dynamic_cast<const types::Array*>(&type)) {
43✔
362
        j["type"] = "array";
3✔
363
        nlohmann::json element_type_json;
3✔
364
        type_to_json(element_type_json, array_type->element_type());
3✔
365
        j["element_type"] = element_type_json;
3✔
366
        j["num_elements"] = expression(array_type->num_elements());
3✔
367
        j["address_space"] = array_type->address_space();
3✔
368
        j["initializer"] = array_type->initializer();
3✔
369
        j["device_location"] = array_type->device_location();
3✔
370
        j["alignment"] = array_type->alignment();
3✔
371
    } else if (auto pointer_type = dynamic_cast<const types::Pointer*>(&type)) {
10✔
372
        j["type"] = "pointer";
3✔
373
        nlohmann::json pointee_type_json;
3✔
374
        type_to_json(pointee_type_json, pointer_type->pointee_type());
3✔
375
        j["pointee_type"] = pointee_type_json;
3✔
376
        j["address_space"] = pointer_type->address_space();
3✔
377
        j["initializer"] = pointer_type->initializer();
3✔
378
        j["device_location"] = pointer_type->device_location();
3✔
379
    } else if (auto structure_type = dynamic_cast<const types::Structure*>(&type)) {
7✔
380
        j["type"] = "structure";
2✔
381
        j["name"] = structure_type->name();
2✔
382
        j["address_space"] = structure_type->address_space();
2✔
383
        j["initializer"] = structure_type->initializer();
2✔
384
        j["device_location"] = structure_type->device_location();
2✔
385
    } else if (auto function_type = dynamic_cast<const types::Function*>(&type)) {
4✔
386
        j["type"] = "function";
2✔
387
        nlohmann::json return_type_json;
2✔
388
        type_to_json(return_type_json, function_type->return_type());
2✔
389
        j["return_type"] = return_type_json;
2✔
390
        j["params"] = nlohmann::json::array();
2✔
391
        for (size_t i = 0; i < function_type->num_params(); i++) {
5✔
392
            nlohmann::json param_json;
3✔
393
            type_to_json(param_json, function_type->param_type(symbolic::integer(i)));
3✔
394
            j["params"].push_back(param_json);
3✔
395
        }
3✔
396
        j["is_var_arg"] = function_type->is_var_arg();
2✔
397
        j["address_space"] = function_type->address_space();
2✔
398
        j["initializer"] = function_type->initializer();
2✔
399
        j["device_location"] = function_type->device_location();
2✔
400
    } else {
2✔
401
        throw std::runtime_error("Unknown type");
×
402
    }
403
}
43✔
404

405
void JSONSerializer::structure_definition_to_json(nlohmann::json& j,
1✔
406
                                                  const types::StructureDefinition& definition) {
407
    j["name"] = definition.name();
1✔
408
    j["members"] = nlohmann::json::array();
1✔
409
    for (size_t i = 0; i < definition.num_members(); i++) {
3✔
410
        nlohmann::json member_json;
2✔
411
        type_to_json(member_json, definition.member_type(symbolic::integer(i)));
2✔
412
        j["members"].push_back(member_json);
2✔
413
    }
2✔
414
    j["is_packed"] = definition.is_packed();
1✔
415
}
1✔
416

417
void JSONSerializer::debug_info_to_json(nlohmann::json& j, const DebugInfo& debug_info) {
117✔
418
    j["has"] = debug_info.has();
117✔
419
    j["filename"] = debug_info.filename();
117✔
420
    j["start_line"] = debug_info.start_line();
117✔
421
    j["start_column"] = debug_info.start_column();
117✔
422
    j["end_line"] = debug_info.end_line();
117✔
423
    j["end_column"] = debug_info.end_column();
117✔
424
}
117✔
425

426
/*
427
 * * Deserialization logic
428
 */
429

430
std::unique_ptr<StructuredSDFG> JSONSerializer::deserialize(nlohmann::json& j) {
3✔
431
    assert(j.contains("name"));
3✔
432
    assert(j["name"].is_string());
3✔
433

434
    builder::StructuredSDFGBuilder builder(j["name"]);
3✔
435

436
    // deserialize structures
437
    assert(j.contains("structures"));
3✔
438
    assert(j["structures"].is_array());
3✔
439
    for (const auto& structure : j["structures"]) {
3✔
440
        assert(structure.contains("name"));
×
441
        assert(structure["name"].is_string());
×
442
        json_to_structure_definition(structure, builder);
×
443
    }
444

445
    nlohmann::json& containers = j["containers"];
3✔
446

447
    // deserialize externals
448
    for (const auto& name : j["externals"]) {
3✔
449
        auto& type_desc = containers.at(name.get<std::string>());
×
450
        auto type = json_to_type(type_desc);
×
451
        builder.add_container(name, *type, false, true);
×
452
    }
×
453

454
    // deserialize arguments
455
    for (const auto& name : j["arguments"]) {
5✔
456
        auto& type_desc = containers.at(name.get<std::string>());
2✔
457
        auto type = json_to_type(type_desc);
2✔
458
        builder.add_container(name, *type, true, false);
2✔
459
    }
2✔
460

461
    // deserialize transients
462
    for (const auto& entry : containers.items()) {
8✔
463
        if (builder.subject().is_argument(entry.key())) {
5✔
464
            continue;
2✔
465
        }
466
        if (builder.subject().is_external(entry.key())) {
3✔
467
            continue;
×
468
        }
469
        auto type = json_to_type(entry.value());
3✔
470
        builder.add_container(entry.key(), *type, false, false);
3✔
471
    }
3✔
472

473
    // deserialize root node
474
    assert(j.contains("root"));
3✔
475
    auto& root = builder.subject().root();
3✔
476
    json_to_sequence(j["root"], builder, root);
3✔
477

478
    // deserialize metadata
479
    assert(j.contains("metadata"));
3✔
480
    assert(j["metadata"].is_object());
3✔
481
    for (const auto& entry : j["metadata"].items()) {
4✔
482
        builder.subject().add_metadata(entry.key(), entry.value());
1✔
483
    }
484

485
    return builder.move();
3✔
486
}
3✔
487

488
void JSONSerializer::json_to_structure_definition(const nlohmann::json& j,
1✔
489
                                                  builder::StructuredSDFGBuilder& builder) {
490
    assert(j.contains("name"));
1✔
491
    assert(j["name"].is_string());
1✔
492
    assert(j.contains("members"));
1✔
493
    assert(j["members"].is_array());
1✔
494
    assert(j.contains("is_packed"));
1✔
495
    assert(j["is_packed"].is_boolean());
1✔
496
    auto is_packed = j["is_packed"];
1✔
497
    auto& definition = builder.add_structure(j["name"], is_packed);
1✔
498
    for (const auto& member : j["members"]) {
3✔
499
        nlohmann::json member_json;
2✔
500
        auto member_type = json_to_type(member);
2✔
501
        definition.add_member(*member_type);
2✔
502
    }
2✔
503
}
1✔
504

505
std::vector<std::pair<std::string, types::Scalar>> JSONSerializer::json_to_arguments(
8✔
506
    const nlohmann::json& j) {
507
    std::vector<std::pair<std::string, types::Scalar>> arguments;
8✔
508
    for (const auto& argument : j) {
20✔
509
        assert(argument.contains("name"));
12✔
510
        assert(argument["name"].is_string());
12✔
511
        assert(argument.contains("type"));
12✔
512
        assert(argument["type"].is_object());
12✔
513
        std::string name = argument["name"];
12✔
514
        auto type = json_to_type(argument["type"]);
12✔
515
        arguments.emplace_back(name, *dynamic_cast<types::Scalar*>(type.get()));
12✔
516
    }
12✔
517
    return arguments;
8✔
518
}
8✔
519

520
void JSONSerializer::json_to_dataflow(const nlohmann::json& j,
11✔
521
                                      builder::StructuredSDFGBuilder& builder,
522
                                      structured_control_flow::Block& parent) {
523
    std::unordered_map<std::string, data_flow::DataFlowNode&> nodes_map;
11✔
524

525
    assert(j.contains("nodes"));
11✔
526
    assert(j["nodes"].is_array());
11✔
527
    for (const auto& node : j["nodes"]) {
27✔
528
        assert(node.contains("type"));
16✔
529
        assert(node["type"].is_string());
16✔
530
        assert(node.contains("element_id"));
16✔
531
        assert(node["element_id"].is_string());
16✔
532
        std::string type = node["type"];
16✔
533
        if (type == "tasklet") {
16✔
534
            assert(node.contains("code"));
4✔
535
            assert(node["code"].is_number_integer());
4✔
536
            assert(node.contains("inputs"));
4✔
537
            assert(node["inputs"].is_array());
4✔
538
            assert(node.contains("outputs"));
4✔
539
            assert(node["outputs"].is_array());
4✔
540
            auto outputs = json_to_arguments(node["outputs"]);
4✔
541
            assert(outputs.size() == 1);
4✔
542
            auto inputs = json_to_arguments(node["inputs"]);
4✔
543
            auto& tasklet = builder.add_tasklet(parent, node["code"], outputs.at(0), inputs,
8✔
544
                                                json_to_debug_info(node["debug_info"]));
4✔
545
            tasklet.element_id_ = node["element_id"];
4✔
546
            nodes_map.insert({node["element_id"], tasklet});
4✔
547
        } else if (type == "library_node") {
16✔
548
            assert(node.contains("call"));
×
549
            assert(node.contains("inputs"));
×
550
            assert(node["inputs"].is_array());
×
551
            assert(node.contains("outputs"));
×
552
            assert(node["outputs"].is_array());
×
553
            auto outputs = json_to_arguments(node["outputs"]);
×
554
            auto inputs = json_to_arguments(node["inputs"]);
×
NEW
555
            auto& lib_node = builder.add_library_node(parent, node["call"], outputs, inputs,
×
NEW
556
                                                      node["has_side_effect"],
×
NEW
557
                                                      json_to_debug_info(node["debug_info"]));
×
NEW
558
            lib_node.element_id_ = node["element_id"];
×
UNCOV
559
            nodes_map.insert({node["element_id"], lib_node});
×
560
        } else if (type == "access_node") {
12✔
561
            assert(node.contains("data"));
12✔
562
            auto& access_node =
12✔
563
                builder.add_access(parent, node["data"], json_to_debug_info(node["debug_info"]));
12✔
564
            access_node.element_id_ = node["element_id"];
12✔
565
            nodes_map.insert({node["element_id"], access_node});
12✔
566
        } else {
12✔
567
            throw std::runtime_error("Unknown node type");
×
568
        }
569
    }
16✔
570

571
    assert(j.contains("edges"));
11✔
572
    assert(j["edges"].is_array());
11✔
573
    for (const auto& edge : j["edges"]) {
23✔
574
        assert(edge.contains("src"));
12✔
575
        assert(edge["src"].is_string());
12✔
576
        assert(edge.contains("dst"));
12✔
577
        assert(edge["dst"].is_string());
12✔
578
        assert(edge.contains("src_conn"));
12✔
579
        assert(edge["src_conn"].is_string());
12✔
580
        assert(edge.contains("dst_conn"));
12✔
581
        assert(edge["dst_conn"].is_string());
12✔
582
        assert(edge.contains("subset"));
12✔
583
        assert(edge["subset"].is_array());
12✔
584

585
        assert(nodes_map.find(edge["src"]) != nodes_map.end());
12✔
586
        assert(nodes_map.find(edge["dst"]) != nodes_map.end());
12✔
587
        auto& source = nodes_map.at(edge["src"]);
12✔
588
        auto& target = nodes_map.at(edge["dst"]);
12✔
589

590
        assert(edge.contains("subset"));
12✔
591
        assert(edge["subset"].is_array());
12✔
592
        std::vector<symbolic::Expression> subset;
12✔
593
        for (const auto& subset_str : edge["subset"]) {
16✔
594
            assert(subset_str.is_string());
4✔
595
            SymEngine::Expression subset_expr(subset_str);
4✔
596
            subset.push_back(subset_expr);
4✔
597
        }
4✔
598
        auto& memlet =
12✔
599
            builder.add_memlet(parent, source, edge["src_conn"], target, edge["dst_conn"], subset,
24✔
600
                               json_to_debug_info(edge["debug_info"]));
12✔
601
        memlet.element_id_ = edge["element_id"];
12✔
602
    }
12✔
603
}
11✔
604

605
void JSONSerializer::json_to_sequence(const nlohmann::json& j,
13✔
606
                                      builder::StructuredSDFGBuilder& builder,
607
                                      structured_control_flow::Sequence& sequence) {
608
    assert(j.contains("type"));
13✔
609
    assert(j["type"].is_string());
13✔
610
    assert(j.contains("children"));
13✔
611
    assert(j["children"].is_array());
13✔
612
    assert(j.contains("transitions"));
13✔
613
    assert(j["transitions"].is_array());
13✔
614
    assert(j["transitions"].size() == j["children"].size());
13✔
615

616
    sequence.element_id_ = j["element_id"];
13✔
617
    sequence.debug_info_ = json_to_debug_info(j["debug_info"]);
13✔
618

619
    std::string type = j["type"];
13✔
620
    if (type == "sequence") {
13✔
621
        for (size_t i = 0; i < j["children"].size(); i++) {
24✔
622
            auto& child = j["children"][i];
11✔
623
            auto& transition = j["transitions"][i];
11✔
624
            assert(child.contains("type"));
11✔
625
            assert(child["type"].is_string());
11✔
626

627
            assert(transition.contains("type"));
11✔
628
            assert(transition["type"].is_string());
11✔
629
            assert(transition.contains("assignments"));
11✔
630
            assert(transition["assignments"].is_array());
11✔
631
            symbolic::Assignments assignments;
11✔
632
            for (const auto& assignment : transition["assignments"]) {
12✔
633
                assert(assignment.contains("symbol"));
1✔
634
                assert(assignment["symbol"].is_string());
1✔
635
                assert(assignment.contains("expression"));
1✔
636
                assert(assignment["expression"].is_string());
1✔
637
                SymEngine::Expression expr(assignment["expression"]);
1✔
638
                assignments.insert({symbolic::symbol(assignment["symbol"]), expr});
1✔
639
            }
1✔
640

641
            if (child["type"] == "block") {
11✔
642
                json_to_block_node(child, builder, sequence, assignments);
9✔
643
            } else if (child["type"] == "for") {
11✔
644
                json_to_for_node(child, builder, sequence, assignments);
×
645
            } else if (child["type"] == "if_else") {
2✔
NEW
646
                json_to_if_else_node(child, builder, sequence, assignments);
×
647
            } else if (child["type"] == "while") {
2✔
648
                json_to_while_node(child, builder, sequence, assignments);
×
649
            } else if (child["type"] == "break") {
2✔
650
                json_to_break_node(child, builder, sequence, assignments);
1✔
651
            } else if (child["type"] == "continue") {
2✔
652
                json_to_continue_node(child, builder, sequence, assignments);
1✔
653
            } else if (child["type"] == "kernel") {
1✔
NEW
654
                json_to_kernel_node(child, builder, sequence, assignments);
×
655
            } else if (child["type"] == "return") {
×
656
                json_to_return_node(child, builder, sequence, assignments);
×
NEW
657
            } else if (child["type"] == "map") {
×
NEW
658
                json_to_map_node(child, builder, sequence, assignments);
×
NEW
659
            } else if (child["type"] == "sequence") {
×
NEW
660
                auto& subseq = builder.add_sequence(sequence, assignments,
×
NEW
661
                                                    json_to_debug_info(child["debug_info"]));
×
NEW
662
                json_to_sequence(child, builder, subseq);
×
663
            } else {
×
664
                throw std::runtime_error("Unknown child type");
×
665
            }
666

667
            sequence.at(i).second.debug_info_ = json_to_debug_info(transition["debug_info"]);
11✔
668
            sequence.at(i).second.element_id_ = transition["element_id"];
11✔
669
        }
11✔
670
    } else {
13✔
671
        throw std::runtime_error("expected sequence type");
×
672
    }
673
}
13✔
674

675
void JSONSerializer::json_to_block_node(const nlohmann::json& j,
10✔
676
                                        builder::StructuredSDFGBuilder& builder,
677
                                        structured_control_flow::Sequence& parent,
678
                                        symbolic::Assignments& assignments) {
679
    assert(j.contains("type"));
10✔
680
    assert(j["type"].is_string());
10✔
681
    assert(j.contains("dataflow"));
10✔
682
    assert(j["dataflow"].is_object());
10✔
683
    auto& block = builder.add_block(parent, assignments, json_to_debug_info(j["debug_info"]));
10✔
684
    block.element_id_ = j["element_id"];
10✔
685
    assert(j["dataflow"].contains("type"));
10✔
686
    assert(j["dataflow"]["type"].is_string());
10✔
687
    std::string type = j["dataflow"]["type"];
10✔
688
    if (type == "dataflow") {
10✔
689
        json_to_dataflow(j["dataflow"], builder, block);
10✔
690
    } else {
10✔
691
        throw std::runtime_error("Unknown dataflow type");
×
692
    }
693
}
10✔
694

695
void JSONSerializer::json_to_for_node(const nlohmann::json& j,
1✔
696
                                      builder::StructuredSDFGBuilder& builder,
697
                                      structured_control_flow::Sequence& parent,
698
                                      symbolic::Assignments& assignments) {
699
    assert(j.contains("type"));
1✔
700
    assert(j["type"].is_string());
1✔
701
    assert(j.contains("indvar"));
1✔
702
    assert(j["indvar"].is_string());
1✔
703
    assert(j.contains("init"));
1✔
704
    assert(j["init"].is_string());
1✔
705
    assert(j.contains("condition"));
1✔
706
    assert(j["condition"].is_string());
1✔
707
    assert(j.contains("update"));
1✔
708
    assert(j["update"].is_string());
1✔
709
    assert(j.contains("root"));
1✔
710
    assert(j["root"].is_object());
1✔
711

712
    symbolic::Symbol indvar = symbolic::symbol(j["indvar"]);
1✔
713
    SymEngine::Expression init(j["init"]);
1✔
714
    SymEngine::Expression condition_expr(j["condition"]);
1✔
715
    assert(!SymEngine::rcp_static_cast<const SymEngine::Boolean>(condition_expr.get_basic())
1✔
716
                .is_null());
717
    symbolic::Condition condition =
718
        SymEngine::rcp_static_cast<const SymEngine::Boolean>(condition_expr.get_basic());
1✔
719
    SymEngine::Expression update(j["update"]);
1✔
720
    auto& for_node = builder.add_for(parent, indvar, condition, init, update, assignments,
2✔
721
                                     json_to_debug_info(j["debug_info"]));
1✔
722
    for_node.element_id_ = j["element_id"];
1✔
723

724
    assert(j["root"].contains("type"));
1✔
725
    assert(j["root"]["type"].is_string());
1✔
726
    assert(j["root"]["type"] == "sequence");
1✔
727
    json_to_sequence(j["root"], builder, for_node.root());
1✔
728
}
1✔
729

730
void JSONSerializer::json_to_if_else_node(const nlohmann::json& j,
1✔
731
                                          builder::StructuredSDFGBuilder& builder,
732
                                          structured_control_flow::Sequence& parent,
733
                                          symbolic::Assignments& assignments) {
734
    assert(j.contains("type"));
1✔
735
    assert(j["type"].is_string());
1✔
736
    assert(j["type"] == "if_else");
1✔
737
    assert(j.contains("branches"));
1✔
738
    assert(j["branches"].is_array());
1✔
739
    auto& if_else_node =
1✔
740
        builder.add_if_else(parent, assignments, json_to_debug_info(j["debug_info"]));
1✔
741
    if_else_node.element_id_ = j["element_id"];
1✔
742
    for (const auto& branch : j["branches"]) {
3✔
743
        assert(branch.contains("condition"));
2✔
744
        assert(branch["condition"].is_string());
2✔
745
        assert(branch.contains("root"));
2✔
746
        assert(branch["root"].is_object());
2✔
747
        SymEngine::Expression condition_expr(branch["condition"]);
2✔
748
        assert(!SymEngine::rcp_static_cast<const SymEngine::Boolean>(condition_expr.get_basic())
2✔
749
                    .is_null());
750
        symbolic::Condition condition =
751
            SymEngine::rcp_static_cast<const SymEngine::Boolean>(condition_expr.get_basic());
2✔
752
        auto& branch_node = builder.add_case(if_else_node, condition);
2✔
753
        assert(branch["root"].contains("type"));
2✔
754
        assert(branch["root"]["type"].is_string());
2✔
755
        std::string type = branch["root"]["type"];
2✔
756
        if (type == "sequence") {
2✔
757
            json_to_sequence(branch["root"], builder, branch_node);
2✔
758
        } else {
2✔
759
            throw std::runtime_error("Unknown child type");
×
760
        }
761
    }
2✔
762
}
1✔
763

764
void JSONSerializer::json_to_while_node(const nlohmann::json& j,
3✔
765
                                        builder::StructuredSDFGBuilder& builder,
766
                                        structured_control_flow::Sequence& parent,
767
                                        symbolic::Assignments& assignments) {
768
    assert(j.contains("type"));
3✔
769
    assert(j["type"].is_string());
3✔
770
    assert(j["type"] == "while");
3✔
771
    assert(j.contains("root"));
3✔
772
    assert(j["root"].is_object());
3✔
773

774
    auto& while_node = builder.add_while(parent, assignments, json_to_debug_info(j["debug_info"]));
3✔
775
    while_node.element_id_ = j["element_id"];
3✔
776

777
    assert(j["root"]["type"] == "sequence");
3✔
778
    json_to_sequence(j["root"], builder, while_node.root());
3✔
779
}
3✔
780

781
void JSONSerializer::json_to_break_node(const nlohmann::json& j,
1✔
782
                                        builder::StructuredSDFGBuilder& builder,
783
                                        structured_control_flow::Sequence& parent,
784
                                        symbolic::Assignments& assignments) {
785
    assert(j.contains("type"));
1✔
786
    assert(j["type"].is_string());
1✔
787
    assert(j["type"] == "break");
1✔
788
    auto& node = builder.add_break(parent, assignments, json_to_debug_info(j["debug_info"]));
1✔
789
    node.element_id_ = j["element_id"];
1✔
790
}
1✔
791

792
void JSONSerializer::json_to_continue_node(const nlohmann::json& j,
1✔
793
                                           builder::StructuredSDFGBuilder& builder,
794
                                           structured_control_flow::Sequence& parent,
795
                                           symbolic::Assignments& assignments) {
796
    assert(j.contains("type"));
1✔
797
    assert(j["type"].is_string());
1✔
798
    assert(j["type"] == "continue");
1✔
799
    auto& node = builder.add_continue(parent, assignments, json_to_debug_info(j["debug_info"]));
1✔
800
    node.element_id_ = j["element_id"];
1✔
801
}
1✔
802

803
void JSONSerializer::json_to_kernel_node(const nlohmann::json& j,
1✔
804
                                         builder::StructuredSDFGBuilder& builder,
805
                                         structured_control_flow::Sequence& parent,
806
                                         symbolic::Assignments& assignments) {
807
    assert(j.contains("type"));
1✔
808
    assert(j["type"].is_string());
1✔
809
    assert(j["type"] == "kernel");
1✔
810
    assert(j.contains("suffix"));
1✔
811
    assert(j["suffix"].is_string());
1✔
812
    assert(j.contains("root"));
1✔
813
    assert(j["root"].is_object());
1✔
814
    auto& kernel_node =
1✔
815
        builder.add_kernel(parent, j["suffix"], json_to_debug_info(j["debug_info"]));
1✔
816
    kernel_node.element_id_ = j["element_id"];
1✔
817

818
    assert(j["root"].contains("type"));
1✔
819
    assert(j["root"]["type"].is_string());
1✔
820
    assert(j["root"]["type"] == "sequence");
1✔
821
    json_to_sequence(j["root"], builder, kernel_node.root());
1✔
822
}
1✔
823

824
void JSONSerializer::json_to_map_node(const nlohmann::json& j,
1✔
825
                                      builder::StructuredSDFGBuilder& builder,
826
                                      structured_control_flow::Sequence& parent,
827
                                      symbolic::Assignments& assignments) {
828
    assert(j.contains("type"));
1✔
829
    assert(j["type"].is_string());
1✔
830
    assert(j["type"] == "map");
1✔
831
    assert(j.contains("indvar"));
1✔
832
    assert(j["indvar"].is_string());
1✔
833
    assert(j.contains("num_iterations"));
1✔
834
    assert(j["num_iterations"].is_string());
1✔
835
    assert(j.contains("root"));
1✔
836
    assert(j["root"].is_object());
1✔
837
    symbolic::Symbol indvar = symbolic::symbol(j["indvar"]);
1✔
838
    SymEngine::Expression num_iterations(j["num_iterations"]);
1✔
839

840
    auto& map_node = builder.add_map(parent, indvar, num_iterations, assignments,
2✔
841
                                     json_to_debug_info(j["debug_info"]));
1✔
842
    map_node.element_id_ = j["element_id"];
1✔
843

844
    assert(j["root"].contains("type"));
1✔
845
    assert(j["root"]["type"].is_string());
1✔
846
    assert(j["root"]["type"] == "sequence");
1✔
847
    json_to_sequence(j["root"], builder, map_node.root());
1✔
848
}
1✔
849

850
void JSONSerializer::json_to_return_node(const nlohmann::json& j,
1✔
851
                                         builder::StructuredSDFGBuilder& builder,
852
                                         structured_control_flow::Sequence& parent,
853
                                         symbolic::Assignments& assignments) {
854
    assert(j.contains("type"));
1✔
855
    assert(j["type"].is_string());
1✔
856
    assert(j["type"] == "return");
1✔
857

858
    auto& node = builder.add_return(parent, assignments, json_to_debug_info(j["debug_info"]));
1✔
859
    node.element_id_ = j["element_id"];
1✔
860
}
1✔
861

862
std::unique_ptr<types::IType> JSONSerializer::json_to_type(const nlohmann::json& j) {
31✔
863
    if (j.contains("type")) {
31✔
864
        if (j["type"] == "scalar") {
31✔
865
            // Deserialize scalar type
866
            assert(j.contains("primitive_type"));
25✔
867
            types::PrimitiveType primitive_type = j["primitive_type"];
25✔
868
            assert(j.contains("device_location"));
25✔
869
            types::DeviceLocation device_location = j["device_location"];
25✔
870
            assert(j.contains("address_space"));
25✔
871
            uint address_space = j["address_space"];
25✔
872
            assert(j.contains("initializer"));
25✔
873
            std::string initializer = j["initializer"];
25✔
874
            return std::make_unique<types::Scalar>(primitive_type, device_location, address_space,
25✔
875
                                                   initializer);
876
        } else if (j["type"] == "array") {
31✔
877
            // Deserialize array type
878
            assert(j.contains("element_type"));
2✔
879
            std::unique_ptr<types::IType> member_type = json_to_type(j["element_type"]);
2✔
880
            assert(j.contains("num_elements"));
2✔
881
            std::string num_elements_str = j["num_elements"];
2✔
882
            // Convert num_elements_str to symbolic::Expression
883
            SymEngine::Expression num_elements(num_elements_str);
2✔
884
            assert(j.contains("address_space"));
2✔
885
            uint address_space = j["address_space"];
2✔
886
            assert(j.contains("initializer"));
2✔
887
            std::string initializer = j["initializer"];
2✔
888
            assert(j.contains("device_location"));
2✔
889
            types::DeviceLocation device_location = j["device_location"];
2✔
890
            assert(j.contains("alignment"));
2✔
891
            size_t alignment = j["alignment"];
2✔
892
            return std::make_unique<types::Array>(*member_type, num_elements, device_location,
2✔
893
                                                  address_space, initializer, alignment);
894
        } else if (j["type"] == "pointer") {
6✔
895
            // Deserialize pointer type
896
            assert(j.contains("pointee_type"));
2✔
897
            std::unique_ptr<types::IType> pointee_type = json_to_type(j["pointee_type"]);
2✔
898
            assert(j.contains("address_space"));
2✔
899
            uint address_space = j["address_space"];
2✔
900
            assert(j.contains("initializer"));
2✔
901
            std::string initializer = j["initializer"];
2✔
902
            assert(j.contains("device_location"));
2✔
903
            types::DeviceLocation device_location = j["device_location"];
2✔
904
            return std::make_unique<types::Pointer>(*pointee_type, device_location, address_space,
2✔
905
                                                    initializer);
906
        } else if (j["type"] == "structure") {
4✔
907
            // Deserialize structure type
908
            assert(j.contains("name"));
1✔
909
            std::string name = j["name"];
1✔
910
            assert(j.contains("address_space"));
1✔
911
            uint address_space = j["address_space"];
1✔
912
            assert(j.contains("initializer"));
1✔
913
            std::string initializer = j["initializer"];
1✔
914
            assert(j.contains("device_location"));
1✔
915
            types::DeviceLocation device_location = j["device_location"];
1✔
916
            return std::make_unique<types::Structure>(name, device_location, address_space,
1✔
917
                                                      initializer);
918
        } else if (j["type"] == "function") {
2✔
919
            // Deserialize function type
920
            assert(j.contains("return_type"));
1✔
921
            std::unique_ptr<types::IType> return_type = json_to_type(j["return_type"]);
1✔
922
            assert(j.contains("params"));
1✔
923
            std::vector<std::unique_ptr<types::IType>> params;
1✔
924
            for (const auto& param : j["params"]) {
3✔
925
                params.push_back(json_to_type(param));
2✔
926
            }
927
            assert(j.contains("is_var_arg"));
1✔
928
            bool is_var_arg = j["is_var_arg"];
1✔
929
            assert(j.contains("address_space"));
1✔
930
            uint address_space = j["address_space"];
1✔
931
            assert(j.contains("initializer"));
1✔
932
            std::string initializer = j["initializer"];
1✔
933
            assert(j.contains("device_location"));
1✔
934
            types::DeviceLocation device_location = j["device_location"];
1✔
935
            auto function = std::make_unique<types::Function>(
1✔
936
                *return_type, is_var_arg, device_location, address_space, initializer);
1✔
937
            for (const auto& param : params) {
3✔
938
                function->add_param(*param);
2✔
939
            }
940
            return function->clone();
1✔
941

942
        } else {
1✔
943
            throw std::runtime_error("Unknown type");
×
944
        }
945
    } else {
946
        throw std::runtime_error("Type not found");
×
947
    }
948
}
31✔
949

950
DebugInfo JSONSerializer::json_to_debug_info(const nlohmann::json& j) {
72✔
951
    assert(j.contains("has"));
72✔
952
    assert(j["has"].is_boolean());
72✔
953
    if (!j["has"]) {
72✔
954
        return DebugInfo();
72✔
955
    }
NEW
956
    assert(j.contains("filename"));
×
NEW
957
    assert(j["filename"].is_string());
×
NEW
958
    std::string filename = j["filename"];
×
NEW
959
    assert(j.contains("start_line"));
×
NEW
960
    assert(j["start_line"].is_number_integer());
×
NEW
961
    size_t start_line = j["start_line"];
×
NEW
962
    assert(j.contains("start_column"));
×
NEW
963
    assert(j["start_column"].is_number_integer());
×
NEW
964
    size_t start_column = j["start_column"];
×
NEW
965
    assert(j.contains("end_line"));
×
NEW
966
    assert(j["end_line"].is_number_integer());
×
NEW
967
    size_t end_line = j["end_line"];
×
NEW
968
    assert(j.contains("end_column"));
×
NEW
969
    assert(j["end_column"].is_number_integer());
×
NEW
970
    size_t end_column = j["end_column"];
×
NEW
971
    return DebugInfo(filename, start_line, start_column, end_line, end_column);
×
972
}
72✔
973

974
std::string JSONSerializer::expression(const symbolic::Expression& expr) {
29✔
975
    JSONSymbolicPrinter printer;
29✔
976
    return printer.apply(expr);
29✔
977
};
29✔
978

979
void JSONSymbolicPrinter::bvisit(const SymEngine::Equality& x) {
×
980
    str_ = apply(x.get_args()[0]) + " == " + apply(x.get_args()[1]);
×
981
    str_ = parenthesize(str_);
×
982
};
×
983

984
void JSONSymbolicPrinter::bvisit(const SymEngine::Unequality& x) {
×
985
    str_ = apply(x.get_args()[0]) + " != " + apply(x.get_args()[1]);
×
986
    str_ = parenthesize(str_);
×
987
};
×
988

989
void JSONSymbolicPrinter::bvisit(const SymEngine::LessThan& x) {
×
990
    str_ = apply(x.get_args()[0]) + " <= " + apply(x.get_args()[1]);
×
991
    str_ = parenthesize(str_);
×
992
};
×
993

994
void JSONSymbolicPrinter::bvisit(const SymEngine::StrictLessThan& x) {
2✔
995
    str_ = apply(x.get_args()[0]) + " < " + apply(x.get_args()[1]);
2✔
996
    str_ = parenthesize(str_);
2✔
997
};
2✔
998

999
void JSONSymbolicPrinter::bvisit(const SymEngine::Min& x) {
×
1000
    std::ostringstream s;
×
1001
    auto container = x.get_args();
×
1002
    if (container.size() == 1) {
×
1003
        s << apply(*container.begin());
×
1004
    } else {
×
1005
        s << "min(";
×
1006
        s << apply(*container.begin());
×
1007

1008
        // Recursively apply __daisy_min to the arguments
1009
        SymEngine::vec_basic subargs;
×
1010
        for (auto it = ++(container.begin()); it != container.end(); ++it) {
×
1011
            subargs.push_back(*it);
×
1012
        }
×
1013
        auto submin = SymEngine::min(subargs);
×
1014
        s << ", " << apply(submin);
×
1015

1016
        s << ")";
×
1017
    }
×
1018

1019
    str_ = s.str();
×
1020
};
×
1021

1022
void JSONSymbolicPrinter::bvisit(const SymEngine::Max& x) {
×
1023
    std::ostringstream s;
×
1024
    auto container = x.get_args();
×
1025
    if (container.size() == 1) {
×
1026
        s << apply(*container.begin());
×
1027
    } else {
×
1028
        s << "max(";
×
1029
        s << apply(*container.begin());
×
1030

1031
        // Recursively apply __daisy_max to the arguments
1032
        SymEngine::vec_basic subargs;
×
1033
        for (auto it = ++(container.begin()); it != container.end(); ++it) {
×
1034
            subargs.push_back(*it);
×
1035
        }
×
1036
        auto submax = SymEngine::max(subargs);
×
1037
        s << ", " << apply(submax);
×
1038

1039
        s << ")";
×
1040
    }
×
1041

1042
    str_ = s.str();
×
1043
};
×
1044

1045
}  // namespace serializer
1046
}  // namespace sdfg
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc