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

daisytuner / sdfglib / 15656007340

14 Jun 2025 08:51PM UTC coverage: 13.234% (-49.9%) from 63.144%
15656007340

Pull #76

github

web-flow
Merge 9586c8161 into 413c53212
Pull Request #76: New Loop Dependency Analysis

361 of 465 new or added lines in 7 files covered. (77.63%)

6215 existing lines in 110 files now uncovered.

1612 of 12181 relevant lines covered (13.23%)

13.64 hits per line

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

0.0
/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/serializer/library_node_serializer_registry.h"
13
#include "sdfg/structured_control_flow/block.h"
14
#include "sdfg/structured_control_flow/for.h"
15
#include "sdfg/structured_control_flow/if_else.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

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

UNCOV
39
    j["name"] = sdfg->name();
×
UNCOV
40
    j["type"] = std::string(sdfg->type().value());
×
41

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

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

UNCOV
57
    j["arguments"] = nlohmann::json::array();
×
UNCOV
58
    for (const auto& argument : sdfg->arguments()) {
×
UNCOV
59
        j["arguments"].push_back(argument);
×
60
    }
61

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

UNCOV
67
    j["metadata"] = nlohmann::json::object();
×
UNCOV
68
    for (const auto& entry : sdfg->metadata()) {
×
UNCOV
69
        j["metadata"][entry.first] = entry.second;
×
70
    }
71

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

UNCOV
77
    return j;
×
UNCOV
78
}
×
79

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

UNCOV
85
    for (auto& node : dataflow.nodes()) {
×
UNCOV
86
        nlohmann::json node_json;
×
UNCOV
87
        node_json["element_id"] = node.element_id();
×
88

UNCOV
89
        node_json["debug_info"] = nlohmann::json::object();
×
UNCOV
90
        debug_info_to_json(node_json["debug_info"], node.debug_info());
×
91

UNCOV
92
        if (auto tasklet = dynamic_cast<const data_flow::Tasklet*>(&node)) {
×
UNCOV
93
            node_json["type"] = "tasklet";
×
UNCOV
94
            node_json["code"] = tasklet->code();
×
UNCOV
95
            node_json["inputs"] = nlohmann::json::array();
×
UNCOV
96
            for (auto& input : tasklet->inputs()) {
×
UNCOV
97
                nlohmann::json input_json;
×
UNCOV
98
                nlohmann::json type_json;
×
UNCOV
99
                type_to_json(type_json, input.second);
×
UNCOV
100
                input_json["type"] = type_json;
×
UNCOV
101
                input_json["name"] = input.first;
×
UNCOV
102
                node_json["inputs"].push_back(input_json);
×
UNCOV
103
            }
×
UNCOV
104
            node_json["output"] = nlohmann::json::object();
×
UNCOV
105
            node_json["output"]["name"] = tasklet->output().first;
×
UNCOV
106
            nlohmann::json type_json;
×
UNCOV
107
            type_to_json(type_json, tasklet->output().second);
×
UNCOV
108
            node_json["output"]["type"] = type_json;
×
109
            // node_json["conditional"] = tasklet->is_conditional();
110
            // if (tasklet->is_conditional()) {
111
            //     node_json["condition"] = dumps_expression(tasklet->condition());
112
            // }
UNCOV
113
        } else if (auto lib_node = dynamic_cast<const data_flow::LibraryNode*>(&node)) {
×
114
            auto serializer_fn =
115
                LibraryNodeSerializerRegistry::instance().get_library_node_serializer(
×
116
                    lib_node->code().value());
×
117
            if (serializer_fn == nullptr) {
×
118
                throw std::runtime_error("Unknown library node code: " +
×
119
                                         std::string(lib_node->code().value()));
×
120
            }
121
            auto serializer = serializer_fn();
×
122
            auto lib_node_json = serializer->serialize(*lib_node);
×
123
            node_json.merge_patch(lib_node_json);
×
UNCOV
124
        } else if (auto code_node = dynamic_cast<const data_flow::AccessNode*>(&node)) {
×
UNCOV
125
            node_json["type"] = "access_node";
×
UNCOV
126
            node_json["data"] = code_node->data();
×
UNCOV
127
        } else {
×
128
            throw std::runtime_error("Unknown node type");
×
129
        }
130

UNCOV
131
        j["nodes"].push_back(node_json);
×
UNCOV
132
    }
×
133

UNCOV
134
    for (auto& edge : dataflow.edges()) {
×
UNCOV
135
        nlohmann::json edge_json;
×
UNCOV
136
        edge_json["element_id"] = edge.element_id();
×
137

UNCOV
138
        edge_json["debug_info"] = nlohmann::json::object();
×
UNCOV
139
        debug_info_to_json(edge_json["debug_info"], edge.debug_info());
×
140

UNCOV
141
        edge_json["src"] = edge.src().element_id();
×
UNCOV
142
        edge_json["dst"] = edge.dst().element_id();
×
143

UNCOV
144
        edge_json["src_conn"] = edge.src_conn();
×
UNCOV
145
        edge_json["dst_conn"] = edge.dst_conn();
×
146

UNCOV
147
        edge_json["subset"] = nlohmann::json::array();
×
UNCOV
148
        for (auto& subset : edge.subset()) {
×
UNCOV
149
            edge_json["subset"].push_back(expression(subset));
×
150
        }
151

UNCOV
152
        j["edges"].push_back(edge_json);
×
UNCOV
153
    }
×
UNCOV
154
}
×
155

UNCOV
156
void JSONSerializer::block_to_json(nlohmann::json& j, const structured_control_flow::Block& block) {
×
UNCOV
157
    j["type"] = "block";
×
UNCOV
158
    j["element_id"] = block.element_id();
×
159

UNCOV
160
    j["debug_info"] = nlohmann::json::object();
×
UNCOV
161
    debug_info_to_json(j["debug_info"], block.debug_info());
×
162

UNCOV
163
    nlohmann::json dataflow_json;
×
UNCOV
164
    dataflow_to_json(dataflow_json, block.dataflow());
×
UNCOV
165
    j["dataflow"] = dataflow_json;
×
UNCOV
166
}
×
167

UNCOV
168
void JSONSerializer::for_to_json(nlohmann::json& j, const structured_control_flow::For& for_node) {
×
UNCOV
169
    j["type"] = "for";
×
UNCOV
170
    j["element_id"] = for_node.element_id();
×
171

UNCOV
172
    j["debug_info"] = nlohmann::json::object();
×
UNCOV
173
    debug_info_to_json(j["debug_info"], for_node.debug_info());
×
174

UNCOV
175
    j["indvar"] = expression(for_node.indvar());
×
UNCOV
176
    j["init"] = expression(for_node.init());
×
UNCOV
177
    j["condition"] = expression(for_node.condition());
×
UNCOV
178
    j["update"] = expression(for_node.update());
×
179

UNCOV
180
    nlohmann::json body_json;
×
UNCOV
181
    sequence_to_json(body_json, for_node.root());
×
UNCOV
182
    j["root"] = body_json;
×
UNCOV
183
}
×
184

UNCOV
185
void JSONSerializer::if_else_to_json(nlohmann::json& j,
×
186
                                     const structured_control_flow::IfElse& if_else_node) {
UNCOV
187
    j["type"] = "if_else";
×
UNCOV
188
    j["element_id"] = if_else_node.element_id();
×
189

UNCOV
190
    j["debug_info"] = nlohmann::json::object();
×
UNCOV
191
    debug_info_to_json(j["debug_info"], if_else_node.debug_info());
×
192

UNCOV
193
    j["branches"] = nlohmann::json::array();
×
UNCOV
194
    for (size_t i = 0; i < if_else_node.size(); i++) {
×
UNCOV
195
        nlohmann::json branch_json;
×
UNCOV
196
        branch_json["condition"] = expression(if_else_node.at(i).second);
×
UNCOV
197
        nlohmann::json body_json;
×
UNCOV
198
        sequence_to_json(body_json, if_else_node.at(i).first);
×
UNCOV
199
        branch_json["root"] = body_json;
×
UNCOV
200
        j["branches"].push_back(branch_json);
×
UNCOV
201
    }
×
UNCOV
202
}
×
203

UNCOV
204
void JSONSerializer::while_node_to_json(nlohmann::json& j,
×
205
                                        const structured_control_flow::While& while_node) {
UNCOV
206
    j["type"] = "while";
×
UNCOV
207
    j["element_id"] = while_node.element_id();
×
208

UNCOV
209
    j["debug_info"] = nlohmann::json::object();
×
UNCOV
210
    debug_info_to_json(j["debug_info"], while_node.debug_info());
×
211

UNCOV
212
    nlohmann::json body_json;
×
UNCOV
213
    sequence_to_json(body_json, while_node.root());
×
UNCOV
214
    j["root"] = body_json;
×
UNCOV
215
}
×
216

UNCOV
217
void JSONSerializer::break_node_to_json(nlohmann::json& j,
×
218
                                        const structured_control_flow::Break& break_node) {
UNCOV
219
    j["type"] = "break";
×
UNCOV
220
    j["element_id"] = break_node.element_id();
×
221

UNCOV
222
    j["debug_info"] = nlohmann::json::object();
×
UNCOV
223
    debug_info_to_json(j["debug_info"], break_node.debug_info());
×
UNCOV
224
}
×
225

UNCOV
226
void JSONSerializer::continue_node_to_json(nlohmann::json& j,
×
227
                                           const structured_control_flow::Continue& continue_node) {
UNCOV
228
    j["type"] = "continue";
×
UNCOV
229
    j["element_id"] = continue_node.element_id();
×
230

UNCOV
231
    j["debug_info"] = nlohmann::json::object();
×
UNCOV
232
    debug_info_to_json(j["debug_info"], continue_node.debug_info());
×
UNCOV
233
}
×
234

UNCOV
235
void JSONSerializer::map_to_json(nlohmann::json& j, const structured_control_flow::Map& map_node) {
×
UNCOV
236
    j["type"] = "map";
×
UNCOV
237
    j["element_id"] = map_node.element_id();
×
238

UNCOV
239
    j["debug_info"] = nlohmann::json::object();
×
UNCOV
240
    debug_info_to_json(j["debug_info"], map_node.debug_info());
×
241

UNCOV
242
    j["indvar"] = expression(map_node.indvar());
×
UNCOV
243
    j["num_iterations"] = expression(map_node.num_iterations());
×
UNCOV
244
    j["schedule_type"] = std::string(map_node.schedule_type().value());
×
245

UNCOV
246
    nlohmann::json body_json;
×
UNCOV
247
    sequence_to_json(body_json, map_node.root());
×
UNCOV
248
    j["root"] = body_json;
×
UNCOV
249
}
×
250

UNCOV
251
void JSONSerializer::return_node_to_json(nlohmann::json& j,
×
252
                                         const structured_control_flow::Return& return_node) {
UNCOV
253
    j["type"] = "return";
×
UNCOV
254
    j["element_id"] = return_node.element_id();
×
255

UNCOV
256
    j["debug_info"] = nlohmann::json::object();
×
UNCOV
257
    debug_info_to_json(j["debug_info"], return_node.debug_info());
×
UNCOV
258
}
×
259

UNCOV
260
void JSONSerializer::sequence_to_json(nlohmann::json& j,
×
261
                                      const structured_control_flow::Sequence& sequence) {
UNCOV
262
    j["type"] = "sequence";
×
UNCOV
263
    j["element_id"] = sequence.element_id();
×
264

UNCOV
265
    j["debug_info"] = nlohmann::json::object();
×
UNCOV
266
    debug_info_to_json(j["debug_info"], sequence.debug_info());
×
267

UNCOV
268
    j["children"] = nlohmann::json::array();
×
UNCOV
269
    j["transitions"] = nlohmann::json::array();
×
270

UNCOV
271
    for (size_t i = 0; i < sequence.size(); i++) {
×
UNCOV
272
        nlohmann::json child_json;
×
UNCOV
273
        auto& child = sequence.at(i).first;
×
UNCOV
274
        auto& transition = sequence.at(i).second;
×
275

UNCOV
276
        if (auto block = dynamic_cast<const structured_control_flow::Block*>(&child)) {
×
UNCOV
277
            block_to_json(child_json, *block);
×
UNCOV
278
        } else if (auto for_node = dynamic_cast<const structured_control_flow::For*>(&child)) {
×
279
            for_to_json(child_json, *for_node);
×
UNCOV
280
        } else if (auto sequence_node =
×
UNCOV
281
                       dynamic_cast<const structured_control_flow::Sequence*>(&child)) {
×
282
            sequence_to_json(child_json, *sequence_node);
×
UNCOV
283
        } else if (auto condition_node =
×
UNCOV
284
                       dynamic_cast<const structured_control_flow::IfElse*>(&child)) {
×
285
            if_else_to_json(child_json, *condition_node);
×
UNCOV
286
        } else if (auto while_node = dynamic_cast<const structured_control_flow::While*>(&child)) {
×
287
            while_node_to_json(child_json, *while_node);
×
UNCOV
288
        } else if (auto return_node =
×
UNCOV
289
                       dynamic_cast<const structured_control_flow::Return*>(&child)) {
×
290
            return_node_to_json(child_json, *return_node);
×
UNCOV
291
        } else if (auto break_node = dynamic_cast<const structured_control_flow::Break*>(&child)) {
×
UNCOV
292
            break_node_to_json(child_json, *break_node);
×
UNCOV
293
        } else if (auto continue_node =
×
UNCOV
294
                       dynamic_cast<const structured_control_flow::Continue*>(&child)) {
×
UNCOV
295
            continue_node_to_json(child_json, *continue_node);
×
UNCOV
296
        } else if (auto map_node = dynamic_cast<const structured_control_flow::Map*>(&child)) {
×
297
            map_to_json(child_json, *map_node);
×
298
        } else {
×
299
            throw std::runtime_error("Unknown child type");
×
300
        }
301

UNCOV
302
        j["children"].push_back(child_json);
×
303

304
        // Add transition information
UNCOV
305
        nlohmann::json transition_json;
×
UNCOV
306
        transition_json["type"] = "transition";
×
UNCOV
307
        transition_json["element_id"] = transition.element_id();
×
308

UNCOV
309
        transition_json["debug_info"] = nlohmann::json::object();
×
UNCOV
310
        debug_info_to_json(transition_json["debug_info"], transition.debug_info());
×
311

UNCOV
312
        transition_json["assignments"] = nlohmann::json::array();
×
UNCOV
313
        for (const auto& assignment : transition.assignments()) {
×
UNCOV
314
            nlohmann::json assignment_json;
×
UNCOV
315
            assignment_json["symbol"] = expression(assignment.first);
×
UNCOV
316
            assignment_json["expression"] = expression(assignment.second);
×
UNCOV
317
            transition_json["assignments"].push_back(assignment_json);
×
UNCOV
318
        }
×
319

UNCOV
320
        j["transitions"].push_back(transition_json);
×
UNCOV
321
    }
×
UNCOV
322
}
×
323

UNCOV
324
void JSONSerializer::type_to_json(nlohmann::json& j, const types::IType& type) {
×
UNCOV
325
    if (auto scalar_type = dynamic_cast<const types::Scalar*>(&type)) {
×
UNCOV
326
        j["type"] = "scalar";
×
UNCOV
327
        j["primitive_type"] = scalar_type->primitive_type();
×
UNCOV
328
        j["storage_type"] = std::string(scalar_type->storage_type().value());
×
UNCOV
329
        j["initializer"] = scalar_type->initializer();
×
UNCOV
330
        j["alignment"] = scalar_type->alignment();
×
UNCOV
331
    } else if (auto array_type = dynamic_cast<const types::Array*>(&type)) {
×
UNCOV
332
        j["type"] = "array";
×
UNCOV
333
        nlohmann::json element_type_json;
×
UNCOV
334
        type_to_json(element_type_json, array_type->element_type());
×
UNCOV
335
        j["element_type"] = element_type_json;
×
UNCOV
336
        j["num_elements"] = expression(array_type->num_elements());
×
UNCOV
337
        j["storage_type"] = std::string(array_type->storage_type().value());
×
UNCOV
338
        j["initializer"] = array_type->initializer();
×
UNCOV
339
        j["alignment"] = array_type->alignment();
×
UNCOV
340
    } else if (auto pointer_type = dynamic_cast<const types::Pointer*>(&type)) {
×
UNCOV
341
        j["type"] = "pointer";
×
UNCOV
342
        nlohmann::json pointee_type_json;
×
UNCOV
343
        type_to_json(pointee_type_json, pointer_type->pointee_type());
×
UNCOV
344
        j["pointee_type"] = pointee_type_json;
×
UNCOV
345
        j["storage_type"] = std::string(pointer_type->storage_type().value());
×
UNCOV
346
        j["initializer"] = pointer_type->initializer();
×
UNCOV
347
        j["alignment"] = pointer_type->alignment();
×
UNCOV
348
    } else if (auto structure_type = dynamic_cast<const types::Structure*>(&type)) {
×
UNCOV
349
        j["type"] = "structure";
×
UNCOV
350
        j["name"] = structure_type->name();
×
UNCOV
351
        j["storage_type"] = std::string(structure_type->storage_type().value());
×
UNCOV
352
        j["initializer"] = structure_type->initializer();
×
UNCOV
353
        j["alignment"] = structure_type->alignment();
×
UNCOV
354
    } else if (auto function_type = dynamic_cast<const types::Function*>(&type)) {
×
UNCOV
355
        j["type"] = "function";
×
UNCOV
356
        nlohmann::json return_type_json;
×
UNCOV
357
        type_to_json(return_type_json, function_type->return_type());
×
UNCOV
358
        j["return_type"] = return_type_json;
×
UNCOV
359
        j["params"] = nlohmann::json::array();
×
UNCOV
360
        for (size_t i = 0; i < function_type->num_params(); i++) {
×
UNCOV
361
            nlohmann::json param_json;
×
UNCOV
362
            type_to_json(param_json, function_type->param_type(symbolic::integer(i)));
×
UNCOV
363
            j["params"].push_back(param_json);
×
UNCOV
364
        }
×
UNCOV
365
        j["is_var_arg"] = function_type->is_var_arg();
×
UNCOV
366
        j["storage_type"] = std::string(function_type->storage_type().value());
×
UNCOV
367
        j["initializer"] = function_type->initializer();
×
UNCOV
368
        j["alignment"] = function_type->alignment();
×
UNCOV
369
    } else {
×
370
        throw std::runtime_error("Unknown type");
×
371
    }
UNCOV
372
}
×
373

UNCOV
374
void JSONSerializer::structure_definition_to_json(nlohmann::json& j,
×
375
                                                  const types::StructureDefinition& definition) {
UNCOV
376
    j["name"] = definition.name();
×
UNCOV
377
    j["members"] = nlohmann::json::array();
×
UNCOV
378
    for (size_t i = 0; i < definition.num_members(); i++) {
×
UNCOV
379
        nlohmann::json member_json;
×
UNCOV
380
        type_to_json(member_json, definition.member_type(symbolic::integer(i)));
×
UNCOV
381
        j["members"].push_back(member_json);
×
UNCOV
382
    }
×
UNCOV
383
    j["is_packed"] = definition.is_packed();
×
UNCOV
384
}
×
385

UNCOV
386
void JSONSerializer::debug_info_to_json(nlohmann::json& j, const DebugInfo& debug_info) {
×
UNCOV
387
    j["has"] = debug_info.has();
×
UNCOV
388
    j["filename"] = debug_info.filename();
×
UNCOV
389
    j["start_line"] = debug_info.start_line();
×
UNCOV
390
    j["start_column"] = debug_info.start_column();
×
UNCOV
391
    j["end_line"] = debug_info.end_line();
×
UNCOV
392
    j["end_column"] = debug_info.end_column();
×
UNCOV
393
}
×
394

395
/*
396
 * * Deserialization logic
397
 */
398

UNCOV
399
std::unique_ptr<StructuredSDFG> JSONSerializer::deserialize(nlohmann::json& j) {
×
UNCOV
400
    assert(j.contains("name"));
×
UNCOV
401
    assert(j["name"].is_string());
×
UNCOV
402
    assert(j.contains("type"));
×
UNCOV
403
    assert(j["type"].is_string());
×
404

UNCOV
405
    FunctionType type{"Unknown"};
×
UNCOV
406
    if (j["type"] == FunctionType_CPU.value()) {
×
UNCOV
407
        type = FunctionType_CPU;
×
UNCOV
408
    } else if (j["type"] == FunctionType_NV_GLOBAL.value()) {
×
409
        type = FunctionType_NV_GLOBAL;
×
410
    } else {
×
411
        throw std::runtime_error("Unknown function type");
×
412
    }
UNCOV
413
    builder::StructuredSDFGBuilder builder(j["name"], type);
×
414

415
    // deserialize structures
UNCOV
416
    assert(j.contains("structures"));
×
UNCOV
417
    assert(j["structures"].is_array());
×
UNCOV
418
    for (const auto& structure : j["structures"]) {
×
419
        assert(structure.contains("name"));
×
420
        assert(structure["name"].is_string());
×
421
        json_to_structure_definition(structure, builder);
×
422
    }
423

UNCOV
424
    nlohmann::json& containers = j["containers"];
×
425

426
    // deserialize externals
UNCOV
427
    for (const auto& name : j["externals"]) {
×
428
        auto& type_desc = containers.at(name.get<std::string>());
×
429
        auto type = json_to_type(type_desc);
×
430
        builder.add_container(name, *type, false, true);
×
431
    }
×
432

433
    // deserialize arguments
UNCOV
434
    for (const auto& name : j["arguments"]) {
×
UNCOV
435
        auto& type_desc = containers.at(name.get<std::string>());
×
UNCOV
436
        auto type = json_to_type(type_desc);
×
UNCOV
437
        builder.add_container(name, *type, true, false);
×
UNCOV
438
    }
×
439

440
    // deserialize transients
UNCOV
441
    for (const auto& entry : containers.items()) {
×
UNCOV
442
        if (builder.subject().is_argument(entry.key())) {
×
UNCOV
443
            continue;
×
444
        }
UNCOV
445
        if (builder.subject().is_external(entry.key())) {
×
446
            continue;
×
447
        }
UNCOV
448
        auto type = json_to_type(entry.value());
×
UNCOV
449
        builder.add_container(entry.key(), *type, false, false);
×
UNCOV
450
    }
×
451

452
    // deserialize root node
UNCOV
453
    assert(j.contains("root"));
×
UNCOV
454
    auto& root = builder.subject().root();
×
UNCOV
455
    json_to_sequence(j["root"], builder, root);
×
456

457
    // deserialize metadata
UNCOV
458
    assert(j.contains("metadata"));
×
UNCOV
459
    assert(j["metadata"].is_object());
×
UNCOV
460
    for (const auto& entry : j["metadata"].items()) {
×
UNCOV
461
        builder.subject().add_metadata(entry.key(), entry.value());
×
462
    }
463

UNCOV
464
    return builder.move();
×
UNCOV
465
}
×
466

UNCOV
467
void JSONSerializer::json_to_structure_definition(const nlohmann::json& j,
×
468
                                                  builder::StructuredSDFGBuilder& builder) {
UNCOV
469
    assert(j.contains("name"));
×
UNCOV
470
    assert(j["name"].is_string());
×
UNCOV
471
    assert(j.contains("members"));
×
UNCOV
472
    assert(j["members"].is_array());
×
UNCOV
473
    assert(j.contains("is_packed"));
×
UNCOV
474
    assert(j["is_packed"].is_boolean());
×
UNCOV
475
    auto is_packed = j["is_packed"];
×
UNCOV
476
    auto& definition = builder.add_structure(j["name"], is_packed);
×
UNCOV
477
    for (const auto& member : j["members"]) {
×
UNCOV
478
        nlohmann::json member_json;
×
UNCOV
479
        auto member_type = json_to_type(member);
×
UNCOV
480
        definition.add_member(*member_type);
×
UNCOV
481
    }
×
UNCOV
482
}
×
483

UNCOV
484
std::vector<std::pair<std::string, types::Scalar>> JSONSerializer::json_to_arguments(
×
485
    const nlohmann::json& j) {
UNCOV
486
    std::vector<std::pair<std::string, types::Scalar>> arguments;
×
UNCOV
487
    for (const auto& argument : j) {
×
UNCOV
488
        assert(argument.contains("name"));
×
UNCOV
489
        assert(argument["name"].is_string());
×
UNCOV
490
        assert(argument.contains("type"));
×
UNCOV
491
        assert(argument["type"].is_object());
×
UNCOV
492
        std::string name = argument["name"];
×
UNCOV
493
        auto type = json_to_type(argument["type"]);
×
UNCOV
494
        arguments.emplace_back(name, *dynamic_cast<types::Scalar*>(type.get()));
×
UNCOV
495
    }
×
UNCOV
496
    return arguments;
×
UNCOV
497
}
×
498

UNCOV
499
void JSONSerializer::json_to_dataflow(const nlohmann::json& j,
×
500
                                      builder::StructuredSDFGBuilder& builder,
501
                                      structured_control_flow::Block& parent) {
UNCOV
502
    std::unordered_map<std::string, data_flow::DataFlowNode&> nodes_map;
×
503

UNCOV
504
    assert(j.contains("nodes"));
×
UNCOV
505
    assert(j["nodes"].is_array());
×
UNCOV
506
    for (const auto& node : j["nodes"]) {
×
UNCOV
507
        assert(node.contains("type"));
×
UNCOV
508
        assert(node["type"].is_string());
×
UNCOV
509
        assert(node.contains("element_id"));
×
UNCOV
510
        assert(node["element_id"].is_string());
×
UNCOV
511
        std::string type = node["type"];
×
UNCOV
512
        if (type == "tasklet") {
×
UNCOV
513
            assert(node.contains("code"));
×
UNCOV
514
            assert(node["code"].is_number_integer());
×
UNCOV
515
            assert(node.contains("inputs"));
×
UNCOV
516
            assert(node["inputs"].is_array());
×
UNCOV
517
            assert(node.contains("output"));
×
UNCOV
518
            assert(node["output"].is_object());
×
UNCOV
519
            assert(node["output"].contains("name"));
×
UNCOV
520
            assert(node["output"].contains("type"));
×
UNCOV
521
            auto inputs = json_to_arguments(node["inputs"]);
×
522

UNCOV
523
            auto output_name = node["output"]["name"];
×
UNCOV
524
            auto output_type = json_to_type(node["output"]["type"]);
×
UNCOV
525
            auto& output_type_scalar = dynamic_cast<types::Scalar&>(*output_type);
×
526

UNCOV
527
            auto& tasklet =
×
UNCOV
528
                builder.add_tasklet(parent, node["code"], {output_name, output_type_scalar}, inputs,
×
UNCOV
529
                                    json_to_debug_info(node["debug_info"]));
×
UNCOV
530
            tasklet.element_id_ = node["element_id"];
×
UNCOV
531
            nodes_map.insert({node["element_id"], tasklet});
×
UNCOV
532
        } else if (type == "library_node") {
×
533
            assert(node.contains("code"));
×
534
            assert(node.contains("inputs"));
×
535
            assert(node["inputs"].is_array());
×
536
            assert(node.contains("outputs"));
×
537
            assert(node["outputs"].is_array());
×
538
            data_flow::LibraryNodeCode code(node["code"].get<std::string_view>());
×
539

540
            auto serializer_fn =
541
                LibraryNodeSerializerRegistry::instance().get_library_node_serializer(code.value());
×
542
            if (serializer_fn == nullptr) {
×
543
                throw std::runtime_error("Unknown library node code: " + std::string(code.value()));
×
544
            }
545
            auto serializer = serializer_fn();
×
546
            auto& lib_node = serializer->deserialize(node, builder, parent);
×
547
            lib_node.element_id_ = node["element_id"];
×
548
            nodes_map.insert({node["element_id"], lib_node});
×
UNCOV
549
        } else if (type == "access_node") {
×
UNCOV
550
            assert(node.contains("data"));
×
UNCOV
551
            auto& access_node =
×
UNCOV
552
                builder.add_access(parent, node["data"], json_to_debug_info(node["debug_info"]));
×
UNCOV
553
            access_node.element_id_ = node["element_id"];
×
UNCOV
554
            nodes_map.insert({node["element_id"], access_node});
×
UNCOV
555
        } else {
×
556
            throw std::runtime_error("Unknown node type");
×
557
        }
UNCOV
558
    }
×
559

UNCOV
560
    assert(j.contains("edges"));
×
UNCOV
561
    assert(j["edges"].is_array());
×
UNCOV
562
    for (const auto& edge : j["edges"]) {
×
UNCOV
563
        assert(edge.contains("src"));
×
UNCOV
564
        assert(edge["src"].is_string());
×
UNCOV
565
        assert(edge.contains("dst"));
×
UNCOV
566
        assert(edge["dst"].is_string());
×
UNCOV
567
        assert(edge.contains("src_conn"));
×
UNCOV
568
        assert(edge["src_conn"].is_string());
×
UNCOV
569
        assert(edge.contains("dst_conn"));
×
UNCOV
570
        assert(edge["dst_conn"].is_string());
×
UNCOV
571
        assert(edge.contains("subset"));
×
UNCOV
572
        assert(edge["subset"].is_array());
×
573

UNCOV
574
        assert(nodes_map.find(edge["src"]) != nodes_map.end());
×
UNCOV
575
        assert(nodes_map.find(edge["dst"]) != nodes_map.end());
×
UNCOV
576
        auto& source = nodes_map.at(edge["src"]);
×
UNCOV
577
        auto& target = nodes_map.at(edge["dst"]);
×
578

UNCOV
579
        assert(edge.contains("subset"));
×
UNCOV
580
        assert(edge["subset"].is_array());
×
UNCOV
581
        std::vector<symbolic::Expression> subset;
×
UNCOV
582
        for (const auto& subset_str : edge["subset"]) {
×
UNCOV
583
            assert(subset_str.is_string());
×
UNCOV
584
            SymEngine::Expression subset_expr(subset_str);
×
UNCOV
585
            subset.push_back(subset_expr);
×
UNCOV
586
        }
×
UNCOV
587
        auto& memlet =
×
UNCOV
588
            builder.add_memlet(parent, source, edge["src_conn"], target, edge["dst_conn"], subset,
×
UNCOV
589
                               json_to_debug_info(edge["debug_info"]));
×
UNCOV
590
        memlet.element_id_ = edge["element_id"];
×
UNCOV
591
    }
×
UNCOV
592
}
×
593

UNCOV
594
void JSONSerializer::json_to_sequence(const nlohmann::json& j,
×
595
                                      builder::StructuredSDFGBuilder& builder,
596
                                      structured_control_flow::Sequence& sequence) {
UNCOV
597
    assert(j.contains("type"));
×
UNCOV
598
    assert(j["type"].is_string());
×
UNCOV
599
    assert(j.contains("children"));
×
UNCOV
600
    assert(j["children"].is_array());
×
UNCOV
601
    assert(j.contains("transitions"));
×
UNCOV
602
    assert(j["transitions"].is_array());
×
UNCOV
603
    assert(j["transitions"].size() == j["children"].size());
×
604

UNCOV
605
    sequence.element_id_ = j["element_id"];
×
UNCOV
606
    sequence.debug_info_ = json_to_debug_info(j["debug_info"]);
×
607

UNCOV
608
    std::string type = j["type"];
×
UNCOV
609
    if (type == "sequence") {
×
UNCOV
610
        for (size_t i = 0; i < j["children"].size(); i++) {
×
UNCOV
611
            auto& child = j["children"][i];
×
UNCOV
612
            auto& transition = j["transitions"][i];
×
UNCOV
613
            assert(child.contains("type"));
×
UNCOV
614
            assert(child["type"].is_string());
×
615

UNCOV
616
            assert(transition.contains("type"));
×
UNCOV
617
            assert(transition["type"].is_string());
×
UNCOV
618
            assert(transition.contains("assignments"));
×
UNCOV
619
            assert(transition["assignments"].is_array());
×
UNCOV
620
            control_flow::Assignments assignments;
×
UNCOV
621
            for (const auto& assignment : transition["assignments"]) {
×
UNCOV
622
                assert(assignment.contains("symbol"));
×
UNCOV
623
                assert(assignment["symbol"].is_string());
×
UNCOV
624
                assert(assignment.contains("expression"));
×
UNCOV
625
                assert(assignment["expression"].is_string());
×
UNCOV
626
                SymEngine::Expression expr(assignment["expression"]);
×
UNCOV
627
                assignments.insert({symbolic::symbol(assignment["symbol"]), expr});
×
UNCOV
628
            }
×
629

UNCOV
630
            if (child["type"] == "block") {
×
UNCOV
631
                json_to_block_node(child, builder, sequence, assignments);
×
UNCOV
632
            } else if (child["type"] == "for") {
×
633
                json_to_for_node(child, builder, sequence, assignments);
×
UNCOV
634
            } else if (child["type"] == "if_else") {
×
635
                json_to_if_else_node(child, builder, sequence, assignments);
×
UNCOV
636
            } else if (child["type"] == "while") {
×
637
                json_to_while_node(child, builder, sequence, assignments);
×
UNCOV
638
            } else if (child["type"] == "break") {
×
UNCOV
639
                json_to_break_node(child, builder, sequence, assignments);
×
UNCOV
640
            } else if (child["type"] == "continue") {
×
UNCOV
641
                json_to_continue_node(child, builder, sequence, assignments);
×
UNCOV
642
            } else if (child["type"] == "return") {
×
643
                json_to_return_node(child, builder, sequence, assignments);
×
644
            } else if (child["type"] == "map") {
×
645
                json_to_map_node(child, builder, sequence, assignments);
×
646
            } else if (child["type"] == "sequence") {
×
647
                auto& subseq = builder.add_sequence(sequence, assignments,
×
648
                                                    json_to_debug_info(child["debug_info"]));
×
649
                json_to_sequence(child, builder, subseq);
×
650
            } else {
×
651
                throw std::runtime_error("Unknown child type");
×
652
            }
653

UNCOV
654
            sequence.at(i).second.debug_info_ = json_to_debug_info(transition["debug_info"]);
×
UNCOV
655
            sequence.at(i).second.element_id_ = transition["element_id"];
×
UNCOV
656
        }
×
UNCOV
657
    } else {
×
658
        throw std::runtime_error("expected sequence type");
×
659
    }
UNCOV
660
}
×
661

UNCOV
662
void JSONSerializer::json_to_block_node(const nlohmann::json& j,
×
663
                                        builder::StructuredSDFGBuilder& builder,
664
                                        structured_control_flow::Sequence& parent,
665
                                        control_flow::Assignments& assignments) {
UNCOV
666
    assert(j.contains("type"));
×
UNCOV
667
    assert(j["type"].is_string());
×
UNCOV
668
    assert(j.contains("dataflow"));
×
UNCOV
669
    assert(j["dataflow"].is_object());
×
UNCOV
670
    auto& block = builder.add_block(parent, assignments, json_to_debug_info(j["debug_info"]));
×
UNCOV
671
    block.element_id_ = j["element_id"];
×
UNCOV
672
    assert(j["dataflow"].contains("type"));
×
UNCOV
673
    assert(j["dataflow"]["type"].is_string());
×
UNCOV
674
    std::string type = j["dataflow"]["type"];
×
UNCOV
675
    if (type == "dataflow") {
×
UNCOV
676
        json_to_dataflow(j["dataflow"], builder, block);
×
UNCOV
677
    } else {
×
678
        throw std::runtime_error("Unknown dataflow type");
×
679
    }
UNCOV
680
}
×
681

UNCOV
682
void JSONSerializer::json_to_for_node(const nlohmann::json& j,
×
683
                                      builder::StructuredSDFGBuilder& builder,
684
                                      structured_control_flow::Sequence& parent,
685
                                      control_flow::Assignments& assignments) {
UNCOV
686
    assert(j.contains("type"));
×
UNCOV
687
    assert(j["type"].is_string());
×
UNCOV
688
    assert(j.contains("indvar"));
×
UNCOV
689
    assert(j["indvar"].is_string());
×
UNCOV
690
    assert(j.contains("init"));
×
UNCOV
691
    assert(j["init"].is_string());
×
UNCOV
692
    assert(j.contains("condition"));
×
UNCOV
693
    assert(j["condition"].is_string());
×
UNCOV
694
    assert(j.contains("update"));
×
UNCOV
695
    assert(j["update"].is_string());
×
UNCOV
696
    assert(j.contains("root"));
×
UNCOV
697
    assert(j["root"].is_object());
×
698

UNCOV
699
    symbolic::Symbol indvar = symbolic::symbol(j["indvar"]);
×
UNCOV
700
    SymEngine::Expression init(j["init"]);
×
UNCOV
701
    SymEngine::Expression condition_expr(j["condition"]);
×
UNCOV
702
    assert(!SymEngine::rcp_static_cast<const SymEngine::Boolean>(condition_expr.get_basic())
×
703
                .is_null());
704
    symbolic::Condition condition =
UNCOV
705
        SymEngine::rcp_static_cast<const SymEngine::Boolean>(condition_expr.get_basic());
×
UNCOV
706
    SymEngine::Expression update(j["update"]);
×
UNCOV
707
    auto& for_node = builder.add_for(parent, indvar, condition, init, update, assignments,
×
UNCOV
708
                                     json_to_debug_info(j["debug_info"]));
×
UNCOV
709
    for_node.element_id_ = j["element_id"];
×
710

UNCOV
711
    assert(j["root"].contains("type"));
×
UNCOV
712
    assert(j["root"]["type"].is_string());
×
UNCOV
713
    assert(j["root"]["type"] == "sequence");
×
UNCOV
714
    json_to_sequence(j["root"], builder, for_node.root());
×
UNCOV
715
}
×
716

UNCOV
717
void JSONSerializer::json_to_if_else_node(const nlohmann::json& j,
×
718
                                          builder::StructuredSDFGBuilder& builder,
719
                                          structured_control_flow::Sequence& parent,
720
                                          control_flow::Assignments& assignments) {
UNCOV
721
    assert(j.contains("type"));
×
UNCOV
722
    assert(j["type"].is_string());
×
UNCOV
723
    assert(j["type"] == "if_else");
×
UNCOV
724
    assert(j.contains("branches"));
×
UNCOV
725
    assert(j["branches"].is_array());
×
UNCOV
726
    auto& if_else_node =
×
UNCOV
727
        builder.add_if_else(parent, assignments, json_to_debug_info(j["debug_info"]));
×
UNCOV
728
    if_else_node.element_id_ = j["element_id"];
×
UNCOV
729
    for (const auto& branch : j["branches"]) {
×
UNCOV
730
        assert(branch.contains("condition"));
×
UNCOV
731
        assert(branch["condition"].is_string());
×
UNCOV
732
        assert(branch.contains("root"));
×
UNCOV
733
        assert(branch["root"].is_object());
×
UNCOV
734
        SymEngine::Expression condition_expr(branch["condition"]);
×
UNCOV
735
        assert(!SymEngine::rcp_static_cast<const SymEngine::Boolean>(condition_expr.get_basic())
×
736
                    .is_null());
737
        symbolic::Condition condition =
UNCOV
738
            SymEngine::rcp_static_cast<const SymEngine::Boolean>(condition_expr.get_basic());
×
UNCOV
739
        auto& branch_node = builder.add_case(if_else_node, condition);
×
UNCOV
740
        assert(branch["root"].contains("type"));
×
UNCOV
741
        assert(branch["root"]["type"].is_string());
×
UNCOV
742
        std::string type = branch["root"]["type"];
×
UNCOV
743
        if (type == "sequence") {
×
UNCOV
744
            json_to_sequence(branch["root"], builder, branch_node);
×
UNCOV
745
        } else {
×
746
            throw std::runtime_error("Unknown child type");
×
747
        }
UNCOV
748
    }
×
UNCOV
749
}
×
750

UNCOV
751
void JSONSerializer::json_to_while_node(const nlohmann::json& j,
×
752
                                        builder::StructuredSDFGBuilder& builder,
753
                                        structured_control_flow::Sequence& parent,
754
                                        control_flow::Assignments& assignments) {
UNCOV
755
    assert(j.contains("type"));
×
UNCOV
756
    assert(j["type"].is_string());
×
UNCOV
757
    assert(j["type"] == "while");
×
UNCOV
758
    assert(j.contains("root"));
×
UNCOV
759
    assert(j["root"].is_object());
×
760

UNCOV
761
    auto& while_node = builder.add_while(parent, assignments, json_to_debug_info(j["debug_info"]));
×
UNCOV
762
    while_node.element_id_ = j["element_id"];
×
763

UNCOV
764
    assert(j["root"]["type"] == "sequence");
×
UNCOV
765
    json_to_sequence(j["root"], builder, while_node.root());
×
UNCOV
766
}
×
767

UNCOV
768
void JSONSerializer::json_to_break_node(const nlohmann::json& j,
×
769
                                        builder::StructuredSDFGBuilder& builder,
770
                                        structured_control_flow::Sequence& parent,
771
                                        control_flow::Assignments& assignments) {
UNCOV
772
    assert(j.contains("type"));
×
UNCOV
773
    assert(j["type"].is_string());
×
UNCOV
774
    assert(j["type"] == "break");
×
UNCOV
775
    auto& node = builder.add_break(parent, assignments, json_to_debug_info(j["debug_info"]));
×
UNCOV
776
    node.element_id_ = j["element_id"];
×
UNCOV
777
}
×
778

UNCOV
779
void JSONSerializer::json_to_continue_node(const nlohmann::json& j,
×
780
                                           builder::StructuredSDFGBuilder& builder,
781
                                           structured_control_flow::Sequence& parent,
782
                                           control_flow::Assignments& assignments) {
UNCOV
783
    assert(j.contains("type"));
×
UNCOV
784
    assert(j["type"].is_string());
×
UNCOV
785
    assert(j["type"] == "continue");
×
UNCOV
786
    auto& node = builder.add_continue(parent, assignments, json_to_debug_info(j["debug_info"]));
×
UNCOV
787
    node.element_id_ = j["element_id"];
×
UNCOV
788
}
×
789

UNCOV
790
void JSONSerializer::json_to_map_node(const nlohmann::json& j,
×
791
                                      builder::StructuredSDFGBuilder& builder,
792
                                      structured_control_flow::Sequence& parent,
793
                                      control_flow::Assignments& assignments) {
UNCOV
794
    assert(j.contains("type"));
×
UNCOV
795
    assert(j["type"].is_string());
×
UNCOV
796
    assert(j["type"] == "map");
×
UNCOV
797
    assert(j.contains("indvar"));
×
UNCOV
798
    assert(j["indvar"].is_string());
×
UNCOV
799
    assert(j.contains("num_iterations"));
×
UNCOV
800
    assert(j["num_iterations"].is_string());
×
UNCOV
801
    assert(j.contains("root"));
×
UNCOV
802
    assert(j["root"].is_object());
×
UNCOV
803
    assert(j.contains("schedule_type"));
×
UNCOV
804
    assert(j["schedule_type"].is_string());
×
UNCOV
805
    structured_control_flow::ScheduleType schedule_type{j["schedule_type"].get<std::string_view>()};
×
UNCOV
806
    symbolic::Symbol indvar = symbolic::symbol(j["indvar"]);
×
UNCOV
807
    SymEngine::Expression num_iterations(j["num_iterations"]);
×
808

UNCOV
809
    auto& map_node = builder.add_map(parent, indvar, num_iterations, schedule_type, assignments,
×
UNCOV
810
                                     json_to_debug_info(j["debug_info"]));
×
UNCOV
811
    map_node.element_id_ = j["element_id"];
×
812

UNCOV
813
    assert(j["root"].contains("type"));
×
UNCOV
814
    assert(j["root"]["type"].is_string());
×
UNCOV
815
    assert(j["root"]["type"] == "sequence");
×
UNCOV
816
    json_to_sequence(j["root"], builder, map_node.root());
×
UNCOV
817
}
×
818

UNCOV
819
void JSONSerializer::json_to_return_node(const nlohmann::json& j,
×
820
                                         builder::StructuredSDFGBuilder& builder,
821
                                         structured_control_flow::Sequence& parent,
822
                                         control_flow::Assignments& assignments) {
UNCOV
823
    assert(j.contains("type"));
×
UNCOV
824
    assert(j["type"].is_string());
×
UNCOV
825
    assert(j["type"] == "return");
×
826

UNCOV
827
    auto& node = builder.add_return(parent, assignments, json_to_debug_info(j["debug_info"]));
×
UNCOV
828
    node.element_id_ = j["element_id"];
×
UNCOV
829
}
×
830

UNCOV
831
std::unique_ptr<types::IType> JSONSerializer::json_to_type(const nlohmann::json& j) {
×
UNCOV
832
    if (j.contains("type")) {
×
UNCOV
833
        if (j["type"] == "scalar") {
×
834
            // Deserialize scalar type
UNCOV
835
            assert(j.contains("primitive_type"));
×
UNCOV
836
            types::PrimitiveType primitive_type = j["primitive_type"];
×
UNCOV
837
            assert(j.contains("storage_type"));
×
UNCOV
838
            types::StorageType storage_type{j["storage_type"].get<std::string_view>()};
×
UNCOV
839
            assert(j.contains("initializer"));
×
UNCOV
840
            std::string initializer = j["initializer"];
×
UNCOV
841
            assert(j.contains("alignment"));
×
UNCOV
842
            size_t alignment = j["alignment"];
×
UNCOV
843
            return std::make_unique<types::Scalar>(storage_type, alignment, initializer,
×
844
                                                   primitive_type);
UNCOV
845
        } else if (j["type"] == "array") {
×
846
            // Deserialize array type
UNCOV
847
            assert(j.contains("element_type"));
×
UNCOV
848
            std::unique_ptr<types::IType> member_type = json_to_type(j["element_type"]);
×
UNCOV
849
            assert(j.contains("num_elements"));
×
UNCOV
850
            std::string num_elements_str = j["num_elements"];
×
851
            // Convert num_elements_str to symbolic::Expression
UNCOV
852
            SymEngine::Expression num_elements(num_elements_str);
×
UNCOV
853
            assert(j.contains("storage_type"));
×
UNCOV
854
            types::StorageType storage_type{j["storage_type"].get<std::string_view>()};
×
UNCOV
855
            assert(j.contains("initializer"));
×
UNCOV
856
            std::string initializer = j["initializer"];
×
UNCOV
857
            assert(j.contains("alignment"));
×
UNCOV
858
            size_t alignment = j["alignment"];
×
UNCOV
859
            return std::make_unique<types::Array>(storage_type, alignment, initializer,
×
UNCOV
860
                                                  *member_type, num_elements);
×
UNCOV
861
        } else if (j["type"] == "pointer") {
×
862
            // Deserialize pointer type
UNCOV
863
            assert(j.contains("pointee_type"));
×
UNCOV
864
            std::unique_ptr<types::IType> pointee_type = json_to_type(j["pointee_type"]);
×
UNCOV
865
            assert(j.contains("storage_type"));
×
UNCOV
866
            types::StorageType storage_type{j["storage_type"].get<std::string_view>()};
×
UNCOV
867
            assert(j.contains("initializer"));
×
UNCOV
868
            std::string initializer = j["initializer"];
×
UNCOV
869
            assert(j.contains("alignment"));
×
UNCOV
870
            size_t alignment = j["alignment"];
×
UNCOV
871
            return std::make_unique<types::Pointer>(storage_type, alignment, initializer,
×
UNCOV
872
                                                    *pointee_type);
×
UNCOV
873
        } else if (j["type"] == "structure") {
×
874
            // Deserialize structure type
UNCOV
875
            assert(j.contains("name"));
×
UNCOV
876
            std::string name = j["name"];
×
UNCOV
877
            assert(j.contains("storage_type"));
×
UNCOV
878
            types::StorageType storage_type{j["storage_type"].get<std::string_view>()};
×
UNCOV
879
            assert(j.contains("initializer"));
×
UNCOV
880
            std::string initializer = j["initializer"];
×
UNCOV
881
            assert(j.contains("alignment"));
×
UNCOV
882
            size_t alignment = j["alignment"];
×
UNCOV
883
            return std::make_unique<types::Structure>(storage_type, alignment, initializer, name);
×
UNCOV
884
        } else if (j["type"] == "function") {
×
885
            // Deserialize function type
UNCOV
886
            assert(j.contains("return_type"));
×
UNCOV
887
            std::unique_ptr<types::IType> return_type = json_to_type(j["return_type"]);
×
UNCOV
888
            assert(j.contains("params"));
×
UNCOV
889
            std::vector<std::unique_ptr<types::IType>> params;
×
UNCOV
890
            for (const auto& param : j["params"]) {
×
UNCOV
891
                params.push_back(json_to_type(param));
×
892
            }
UNCOV
893
            assert(j.contains("is_var_arg"));
×
UNCOV
894
            bool is_var_arg = j["is_var_arg"];
×
UNCOV
895
            assert(j.contains("storage_type"));
×
UNCOV
896
            types::StorageType storage_type{j["storage_type"].get<std::string_view>()};
×
UNCOV
897
            assert(j.contains("initializer"));
×
UNCOV
898
            std::string initializer = j["initializer"];
×
UNCOV
899
            assert(j.contains("alignment"));
×
UNCOV
900
            size_t alignment = j["alignment"];
×
UNCOV
901
            auto function = std::make_unique<types::Function>(storage_type, alignment, initializer,
×
UNCOV
902
                                                              *return_type, is_var_arg);
×
UNCOV
903
            for (const auto& param : params) {
×
UNCOV
904
                function->add_param(*param);
×
905
            }
UNCOV
906
            return function->clone();
×
907

UNCOV
908
        } else {
×
909
            throw std::runtime_error("Unknown type");
×
910
        }
911
    } else {
912
        throw std::runtime_error("Type not found");
×
913
    }
UNCOV
914
}
×
915

UNCOV
916
DebugInfo JSONSerializer::json_to_debug_info(const nlohmann::json& j) {
×
UNCOV
917
    assert(j.contains("has"));
×
UNCOV
918
    assert(j["has"].is_boolean());
×
UNCOV
919
    if (!j["has"]) {
×
UNCOV
920
        return DebugInfo();
×
921
    }
922
    assert(j.contains("filename"));
×
923
    assert(j["filename"].is_string());
×
924
    std::string filename = j["filename"];
×
925
    assert(j.contains("start_line"));
×
926
    assert(j["start_line"].is_number_integer());
×
927
    size_t start_line = j["start_line"];
×
928
    assert(j.contains("start_column"));
×
929
    assert(j["start_column"].is_number_integer());
×
930
    size_t start_column = j["start_column"];
×
931
    assert(j.contains("end_line"));
×
932
    assert(j["end_line"].is_number_integer());
×
933
    size_t end_line = j["end_line"];
×
934
    assert(j.contains("end_column"));
×
935
    assert(j["end_column"].is_number_integer());
×
936
    size_t end_column = j["end_column"];
×
937
    return DebugInfo(filename, start_line, start_column, end_line, end_column);
×
UNCOV
938
}
×
939

UNCOV
940
std::string JSONSerializer::expression(const symbolic::Expression& expr) {
×
UNCOV
941
    JSONSymbolicPrinter printer;
×
UNCOV
942
    return printer.apply(expr);
×
UNCOV
943
};
×
944

945
void JSONSymbolicPrinter::bvisit(const SymEngine::Equality& x) {
×
946
    str_ = apply(x.get_args()[0]) + " == " + apply(x.get_args()[1]);
×
947
    str_ = parenthesize(str_);
×
948
};
×
949

950
void JSONSymbolicPrinter::bvisit(const SymEngine::Unequality& x) {
×
951
    str_ = apply(x.get_args()[0]) + " != " + apply(x.get_args()[1]);
×
952
    str_ = parenthesize(str_);
×
953
};
×
954

955
void JSONSymbolicPrinter::bvisit(const SymEngine::LessThan& x) {
×
956
    str_ = apply(x.get_args()[0]) + " <= " + apply(x.get_args()[1]);
×
957
    str_ = parenthesize(str_);
×
958
};
×
959

UNCOV
960
void JSONSymbolicPrinter::bvisit(const SymEngine::StrictLessThan& x) {
×
UNCOV
961
    str_ = apply(x.get_args()[0]) + " < " + apply(x.get_args()[1]);
×
UNCOV
962
    str_ = parenthesize(str_);
×
UNCOV
963
};
×
964

965
void JSONSymbolicPrinter::bvisit(const SymEngine::Min& x) {
×
966
    std::ostringstream s;
×
967
    auto container = x.get_args();
×
968
    if (container.size() == 1) {
×
969
        s << apply(*container.begin());
×
970
    } else {
×
971
        s << "min(";
×
972
        s << apply(*container.begin());
×
973

974
        // Recursively apply __daisy_min to the arguments
975
        SymEngine::vec_basic subargs;
×
976
        for (auto it = ++(container.begin()); it != container.end(); ++it) {
×
977
            subargs.push_back(*it);
×
978
        }
×
979
        auto submin = SymEngine::min(subargs);
×
980
        s << ", " << apply(submin);
×
981

982
        s << ")";
×
983
    }
×
984

985
    str_ = s.str();
×
986
};
×
987

988
void JSONSymbolicPrinter::bvisit(const SymEngine::Max& x) {
×
989
    std::ostringstream s;
×
990
    auto container = x.get_args();
×
991
    if (container.size() == 1) {
×
992
        s << apply(*container.begin());
×
993
    } else {
×
994
        s << "max(";
×
995
        s << apply(*container.begin());
×
996

997
        // Recursively apply __daisy_max to the arguments
998
        SymEngine::vec_basic subargs;
×
999
        for (auto it = ++(container.begin()); it != container.end(); ++it) {
×
1000
            subargs.push_back(*it);
×
1001
        }
×
1002
        auto submax = SymEngine::max(subargs);
×
1003
        s << ", " << apply(submax);
×
1004

1005
        s << ")";
×
1006
    }
×
1007

1008
    str_ = s.str();
×
1009
};
×
1010

1011
}  // namespace serializer
1012
}  // 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

© 2026 Coveralls, Inc