• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In
Build has been canceled!

daisytuner / sdfglib / 16439608634

22 Jul 2025 08:57AM UTC coverage: 65.982% (+0.9%) from 65.094%
16439608634

Pull #153

github

web-flow
Merge 373570200 into abe57c083
Pull Request #153: Restricts memlets to contiguous memory

213 of 317 new or added lines in 30 files covered. (67.19%)

66 existing lines in 7 files now uncovered.

8321 of 12611 relevant lines covered (65.98%)

128.51 hits per line

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

82.82
/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/data_flow/library_nodes/math/math.h"
10

11
#include "sdfg/data_flow/library_nodes/barrier_local_node.h"
12
#include "sdfg/data_flow/library_nodes/metadata_node.h"
13

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

32
namespace sdfg {
33
namespace serializer {
34

35
FunctionType function_type_from_string(const std::string& str) {
4✔
36
    if (str == FunctionType_CPU.value()) {
4✔
37
        return FunctionType_CPU;
4✔
38
    } else if (str == FunctionType_NV_GLOBAL.value()) {
×
39
        return FunctionType_NV_GLOBAL;
×
40
    }
41

42
    return FunctionType(str);
×
43
}
4✔
44

45
types::StorageType storage_type_from_string(const std::string& str) {
35✔
46
    if (str == types::StorageType_CPU_Heap.value()) {
35✔
47
        return types::StorageType_CPU_Heap;
×
48
    } else if (str == types::StorageType_CPU_Stack.value()) {
35✔
49
        return types::StorageType_CPU_Stack;
35✔
50
    } else if (str == types::StorageType_NV_Global.value()) {
×
51
        return types::StorageType_NV_Global;
×
52
    } else if (str == types::StorageType_NV_Shared.value()) {
×
53
        return types::StorageType_NV_Shared;
×
54
    } else if (str == types::StorageType_NV_Constant.value()) {
×
55
        return types::StorageType_NV_Constant;
×
56
    } else if (str == types::StorageType_NV_Generic.value()) {
×
57
        return types::StorageType_NV_Generic;
×
58
    }
59

60
    return types::StorageType(str);
×
61
}
35✔
62

63
structured_control_flow::ScheduleType schedule_type_from_string(const std::string& str) {
1✔
64
    if (str == structured_control_flow::ScheduleType_Sequential.value()) {
1✔
65
        return structured_control_flow::ScheduleType_Sequential;
1✔
66
    } else if (str == structured_control_flow::ScheduleType_CPU_Parallel.value()) {
×
67
        return structured_control_flow::ScheduleType_CPU_Parallel;
×
68
    }
69

70
    return structured_control_flow::ScheduleType(str);
×
71
}
1✔
72

73
/*
74
 * * JSONSerializer class
75
 * * Serialization logic
76
 */
77

78
nlohmann::json JSONSerializer::serialize(const sdfg::StructuredSDFG& sdfg) {
4✔
79
    nlohmann::json j;
4✔
80

81
    j["name"] = sdfg.name();
4✔
82
    j["element_counter"] = sdfg.element_counter();
4✔
83
    j["type"] = std::string(sdfg.type().value());
4✔
84

85
    j["structures"] = nlohmann::json::array();
4✔
86
    for (const auto& structure_name : sdfg.structures()) {
5✔
87
        const auto& structure = sdfg.structure(structure_name);
1✔
88
        nlohmann::json structure_json;
1✔
89
        structure_definition_to_json(structure_json, structure);
1✔
90
        j["structures"].push_back(structure_json);
1✔
91
    }
1✔
92

93
    j["containers"] = nlohmann::json::object();
4✔
94
    for (const auto& container : sdfg.containers()) {
13✔
95
        nlohmann::json desc;
9✔
96
        type_to_json(desc, sdfg.type(container));
9✔
97
        j["containers"][container] = desc;
9✔
98
    }
9✔
99

100
    j["arguments"] = nlohmann::json::array();
4✔
101
    for (const auto& argument : sdfg.arguments()) {
7✔
102
        j["arguments"].push_back(argument);
3✔
103
    }
104

105
    j["externals"] = nlohmann::json::array();
4✔
106
    for (const auto& external : sdfg.externals()) {
5✔
107
        j["externals"].push_back(external);
1✔
108
    }
109

110
    j["metadata"] = nlohmann::json::object();
4✔
111
    for (const auto& entry : sdfg.metadata()) {
5✔
112
        j["metadata"][entry.first] = entry.second;
1✔
113
    }
114

115
    // Walk the SDFG
116
    nlohmann::json root_json;
4✔
117
    sequence_to_json(root_json, sdfg.root());
4✔
118
    j["root"] = root_json;
4✔
119

120
    return j;
4✔
121
}
4✔
122

123
void JSONSerializer::dataflow_to_json(nlohmann::json& j, const data_flow::DataFlowGraph& dataflow) {
21✔
124
    j["type"] = "dataflow";
21✔
125
    j["nodes"] = nlohmann::json::array();
21✔
126
    j["edges"] = nlohmann::json::array();
21✔
127

128
    for (auto& node : dataflow.nodes()) {
41✔
129
        nlohmann::json node_json;
20✔
130
        node_json["element_id"] = node.element_id();
20✔
131

132
        node_json["debug_info"] = nlohmann::json::object();
20✔
133
        debug_info_to_json(node_json["debug_info"], node.debug_info());
20✔
134

135
        if (auto tasklet = dynamic_cast<const data_flow::Tasklet*>(&node)) {
20✔
136
            node_json["type"] = "tasklet";
5✔
137
            node_json["code"] = tasklet->code();
5✔
138
            node_json["inputs"] = nlohmann::json::array();
5✔
139
            for (auto& input : tasklet->inputs()) {
15✔
140
                nlohmann::json input_json;
10✔
141
                nlohmann::json type_json;
10✔
142
                type_to_json(type_json, input.second);
10✔
143
                input_json["type"] = type_json;
10✔
144
                input_json["name"] = input.first;
10✔
145
                node_json["inputs"].push_back(input_json);
10✔
146
            }
10✔
147
            node_json["output"] = nlohmann::json::object();
5✔
148
            node_json["output"]["name"] = tasklet->output().first;
5✔
149
            nlohmann::json type_json;
5✔
150
            type_to_json(type_json, tasklet->output().second);
5✔
151
            node_json["output"]["type"] = type_json;
5✔
152
            // node_json["conditional"] = tasklet->is_conditional();
153
            // if (tasklet->is_conditional()) {
154
            //     node_json["condition"] = dumps_expression(tasklet->condition());
155
            // }
156
        } else if (auto lib_node = dynamic_cast<const data_flow::LibraryNode*>(&node)) {
20✔
157
            node_json["type"] = "library_node";
×
158
            auto serializer_fn =
159
                LibraryNodeSerializerRegistry::instance().get_library_node_serializer(lib_node->code().value());
×
160
            if (serializer_fn == nullptr) {
×
161
                throw std::runtime_error("Unknown library node code: " + std::string(lib_node->code().value()));
×
162
            }
163
            auto serializer = serializer_fn();
×
164
            auto lib_node_json = serializer->serialize(*lib_node);
×
165
            node_json.merge_patch(lib_node_json);
×
166
        } else if (auto code_node = dynamic_cast<const data_flow::AccessNode*>(&node)) {
15✔
167
            node_json["type"] = "access_node";
15✔
168
            node_json["data"] = code_node->data();
15✔
169
        } else {
15✔
170
            throw std::runtime_error("Unknown node type");
×
171
        }
172

173
        j["nodes"].push_back(node_json);
20✔
174
    }
20✔
175

176
    for (auto& edge : dataflow.edges()) {
36✔
177
        nlohmann::json edge_json;
15✔
178
        edge_json["element_id"] = edge.element_id();
15✔
179

180
        edge_json["debug_info"] = nlohmann::json::object();
15✔
181
        debug_info_to_json(edge_json["debug_info"], edge.debug_info());
15✔
182

183
        edge_json["src"] = edge.src().element_id();
15✔
184
        edge_json["dst"] = edge.dst().element_id();
15✔
185

186
        edge_json["src_conn"] = edge.src_conn();
15✔
187
        edge_json["dst_conn"] = edge.dst_conn();
15✔
188

189
        edge_json["subset"] = nlohmann::json::array();
15✔
190
        for (auto& subset : edge.subset()) {
21✔
191
            edge_json["subset"].push_back(expression(subset));
6✔
192
        }
193

194
        edge_json["begin_subset"] = nlohmann::json::array();
15✔
195
        for (auto& subset : edge.begin_subset()) {
21✔
196
            edge_json["begin_subset"].push_back(expression(subset));
6✔
197
        }
198

199
        edge_json["end_subset"] = nlohmann::json::array();
15✔
200
        for (auto& subset : edge.end_subset()) {
21✔
201
            edge_json["end_subset"].push_back(expression(subset));
6✔
202
        }
203

204
        j["edges"].push_back(edge_json);
15✔
205
    }
15✔
206
}
21✔
207

208
void JSONSerializer::block_to_json(nlohmann::json& j, const structured_control_flow::Block& block) {
19✔
209
    j["type"] = "block";
19✔
210
    j["element_id"] = block.element_id();
19✔
211

212
    j["debug_info"] = nlohmann::json::object();
19✔
213
    debug_info_to_json(j["debug_info"], block.debug_info());
19✔
214

215
    nlohmann::json dataflow_json;
19✔
216
    dataflow_to_json(dataflow_json, block.dataflow());
19✔
217
    j["dataflow"] = dataflow_json;
19✔
218
}
19✔
219

220
void JSONSerializer::for_to_json(nlohmann::json& j, const structured_control_flow::For& for_node) {
2✔
221
    j["type"] = "for";
2✔
222
    j["element_id"] = for_node.element_id();
2✔
223

224
    j["debug_info"] = nlohmann::json::object();
2✔
225
    debug_info_to_json(j["debug_info"], for_node.debug_info());
2✔
226

227
    j["indvar"] = expression(for_node.indvar());
2✔
228
    j["init"] = expression(for_node.init());
2✔
229
    j["condition"] = expression(for_node.condition());
2✔
230
    j["update"] = expression(for_node.update());
2✔
231

232
    nlohmann::json body_json;
2✔
233
    sequence_to_json(body_json, for_node.root());
2✔
234
    j["root"] = body_json;
2✔
235
}
2✔
236

237
void JSONSerializer::if_else_to_json(nlohmann::json& j, const structured_control_flow::IfElse& if_else_node) {
2✔
238
    j["type"] = "if_else";
2✔
239
    j["element_id"] = if_else_node.element_id();
2✔
240

241
    j["debug_info"] = nlohmann::json::object();
2✔
242
    debug_info_to_json(j["debug_info"], if_else_node.debug_info());
2✔
243

244
    j["branches"] = nlohmann::json::array();
2✔
245
    for (size_t i = 0; i < if_else_node.size(); i++) {
6✔
246
        nlohmann::json branch_json;
4✔
247
        branch_json["condition"] = expression(if_else_node.at(i).second);
4✔
248
        nlohmann::json body_json;
4✔
249
        sequence_to_json(body_json, if_else_node.at(i).first);
4✔
250
        branch_json["root"] = body_json;
4✔
251
        j["branches"].push_back(branch_json);
4✔
252
    }
4✔
253
}
2✔
254

255
void JSONSerializer::while_node_to_json(nlohmann::json& j, const structured_control_flow::While& while_node) {
5✔
256
    j["type"] = "while";
5✔
257
    j["element_id"] = while_node.element_id();
5✔
258

259
    j["debug_info"] = nlohmann::json::object();
5✔
260
    debug_info_to_json(j["debug_info"], while_node.debug_info());
5✔
261

262
    nlohmann::json body_json;
5✔
263
    sequence_to_json(body_json, while_node.root());
5✔
264
    j["root"] = body_json;
5✔
265
}
5✔
266

267
void JSONSerializer::break_node_to_json(nlohmann::json& j, const structured_control_flow::Break& break_node) {
2✔
268
    j["type"] = "break";
2✔
269
    j["element_id"] = break_node.element_id();
2✔
270

271
    j["debug_info"] = nlohmann::json::object();
2✔
272
    debug_info_to_json(j["debug_info"], break_node.debug_info());
2✔
273
}
2✔
274

275
void JSONSerializer::continue_node_to_json(nlohmann::json& j, const structured_control_flow::Continue& continue_node) {
2✔
276
    j["type"] = "continue";
2✔
277
    j["element_id"] = continue_node.element_id();
2✔
278

279
    j["debug_info"] = nlohmann::json::object();
2✔
280
    debug_info_to_json(j["debug_info"], continue_node.debug_info());
2✔
281
}
2✔
282

283
void JSONSerializer::map_to_json(nlohmann::json& j, const structured_control_flow::Map& map_node) {
2✔
284
    j["type"] = "map";
2✔
285
    j["element_id"] = map_node.element_id();
2✔
286

287
    j["debug_info"] = nlohmann::json::object();
2✔
288
    debug_info_to_json(j["debug_info"], map_node.debug_info());
2✔
289

290
    j["indvar"] = expression(map_node.indvar());
2✔
291
    j["init"] = expression(map_node.init());
2✔
292
    j["condition"] = expression(map_node.condition());
2✔
293
    j["update"] = expression(map_node.update());
2✔
294

295
    j["schedule_type"] = std::string(map_node.schedule_type().value());
2✔
296

297
    nlohmann::json body_json;
2✔
298
    sequence_to_json(body_json, map_node.root());
2✔
299
    j["root"] = body_json;
2✔
300
}
2✔
301

302
void JSONSerializer::return_node_to_json(nlohmann::json& j, const structured_control_flow::Return& return_node) {
2✔
303
    j["type"] = "return";
2✔
304
    j["element_id"] = return_node.element_id();
2✔
305

306
    j["debug_info"] = nlohmann::json::object();
2✔
307
    debug_info_to_json(j["debug_info"], return_node.debug_info());
2✔
308
}
2✔
309

310
void JSONSerializer::sequence_to_json(nlohmann::json& j, const structured_control_flow::Sequence& sequence) {
20✔
311
    j["type"] = "sequence";
20✔
312
    j["element_id"] = sequence.element_id();
20✔
313

314
    j["debug_info"] = nlohmann::json::object();
20✔
315
    debug_info_to_json(j["debug_info"], sequence.debug_info());
20✔
316

317
    j["children"] = nlohmann::json::array();
20✔
318
    j["transitions"] = nlohmann::json::array();
20✔
319

320
    for (size_t i = 0; i < sequence.size(); i++) {
41✔
321
        nlohmann::json child_json;
21✔
322
        auto& child = sequence.at(i).first;
21✔
323
        auto& transition = sequence.at(i).second;
21✔
324

325
        if (auto block = dynamic_cast<const structured_control_flow::Block*>(&child)) {
21✔
326
            block_to_json(child_json, *block);
17✔
327
        } else if (auto for_node = dynamic_cast<const structured_control_flow::For*>(&child)) {
21✔
328
            for_to_json(child_json, *for_node);
×
329
        } else if (auto sequence_node = dynamic_cast<const structured_control_flow::Sequence*>(&child)) {
4✔
330
            sequence_to_json(child_json, *sequence_node);
×
331
        } else if (auto condition_node = dynamic_cast<const structured_control_flow::IfElse*>(&child)) {
4✔
332
            if_else_to_json(child_json, *condition_node);
×
333
        } else if (auto while_node = dynamic_cast<const structured_control_flow::While*>(&child)) {
4✔
334
            while_node_to_json(child_json, *while_node);
×
335
        } else if (auto return_node = dynamic_cast<const structured_control_flow::Return*>(&child)) {
4✔
336
            return_node_to_json(child_json, *return_node);
×
337
        } else if (auto break_node = dynamic_cast<const structured_control_flow::Break*>(&child)) {
4✔
338
            break_node_to_json(child_json, *break_node);
2✔
339
        } else if (auto continue_node = dynamic_cast<const structured_control_flow::Continue*>(&child)) {
4✔
340
            continue_node_to_json(child_json, *continue_node);
2✔
341
        } else if (auto map_node = dynamic_cast<const structured_control_flow::Map*>(&child)) {
2✔
342
            map_to_json(child_json, *map_node);
×
343
        } else {
×
344
            throw std::runtime_error("Unknown child type");
×
345
        }
346

347
        j["children"].push_back(child_json);
21✔
348

349
        // Add transition information
350
        nlohmann::json transition_json;
21✔
351
        transition_json["type"] = "transition";
21✔
352
        transition_json["element_id"] = transition.element_id();
21✔
353

354
        transition_json["debug_info"] = nlohmann::json::object();
21✔
355
        debug_info_to_json(transition_json["debug_info"], transition.debug_info());
21✔
356

357
        transition_json["assignments"] = nlohmann::json::array();
21✔
358
        for (const auto& assignment : transition.assignments()) {
24✔
359
            nlohmann::json assignment_json;
3✔
360
            assignment_json["symbol"] = expression(assignment.first);
3✔
361
            assignment_json["expression"] = expression(assignment.second);
3✔
362
            transition_json["assignments"].push_back(assignment_json);
3✔
363
        }
3✔
364

365
        j["transitions"].push_back(transition_json);
21✔
366
    }
21✔
367
}
20✔
368

369
void JSONSerializer::type_to_json(nlohmann::json& j, const types::IType& type) {
47✔
370
    if (auto scalar_type = dynamic_cast<const types::Scalar*>(&type)) {
47✔
371
        j["type"] = "scalar";
36✔
372
        j["primitive_type"] = scalar_type->primitive_type();
36✔
373
        j["storage_type"] = std::string(scalar_type->storage_type().value());
36✔
374
        j["initializer"] = scalar_type->initializer();
36✔
375
        j["alignment"] = scalar_type->alignment();
36✔
376
    } else if (auto array_type = dynamic_cast<const types::Array*>(&type)) {
47✔
377
        j["type"] = "array";
3✔
378
        nlohmann::json element_type_json;
3✔
379
        type_to_json(element_type_json, array_type->element_type());
3✔
380
        j["element_type"] = element_type_json;
3✔
381
        j["num_elements"] = expression(array_type->num_elements());
3✔
382
        j["storage_type"] = std::string(array_type->storage_type().value());
3✔
383
        j["initializer"] = array_type->initializer();
3✔
384
        j["alignment"] = array_type->alignment();
3✔
385
    } else if (auto pointer_type = dynamic_cast<const types::Pointer*>(&type)) {
11✔
386
        j["type"] = "pointer";
3✔
387
        nlohmann::json pointee_type_json;
3✔
388
        type_to_json(pointee_type_json, pointer_type->pointee_type());
3✔
389
        j["pointee_type"] = pointee_type_json;
3✔
390
        j["storage_type"] = std::string(pointer_type->storage_type().value());
3✔
391
        j["initializer"] = pointer_type->initializer();
3✔
392
        j["alignment"] = pointer_type->alignment();
3✔
393
    } else if (auto structure_type = dynamic_cast<const types::Structure*>(&type)) {
8✔
394
        j["type"] = "structure";
3✔
395
        j["name"] = structure_type->name();
3✔
396
        j["storage_type"] = std::string(structure_type->storage_type().value());
3✔
397
        j["initializer"] = structure_type->initializer();
3✔
398
        j["alignment"] = structure_type->alignment();
3✔
399
    } else if (auto function_type = dynamic_cast<const types::Function*>(&type)) {
5✔
400
        j["type"] = "function";
2✔
401
        nlohmann::json return_type_json;
2✔
402
        type_to_json(return_type_json, function_type->return_type());
2✔
403
        j["return_type"] = return_type_json;
2✔
404
        j["params"] = nlohmann::json::array();
2✔
405
        for (size_t i = 0; i < function_type->num_params(); i++) {
5✔
406
            nlohmann::json param_json;
3✔
407
            type_to_json(param_json, function_type->param_type(symbolic::integer(i)));
3✔
408
            j["params"].push_back(param_json);
3✔
409
        }
3✔
410
        j["is_var_arg"] = function_type->is_var_arg();
2✔
411
        j["storage_type"] = std::string(function_type->storage_type().value());
2✔
412
        j["initializer"] = function_type->initializer();
2✔
413
        j["alignment"] = function_type->alignment();
2✔
414
    } else {
2✔
415
        throw std::runtime_error("Unknown type");
×
416
    }
417
}
47✔
418

419
void JSONSerializer::structure_definition_to_json(nlohmann::json& j, const types::StructureDefinition& definition) {
2✔
420
    j["name"] = definition.name();
2✔
421
    j["members"] = nlohmann::json::array();
2✔
422
    for (size_t i = 0; i < definition.num_members(); i++) {
4✔
423
        nlohmann::json member_json;
2✔
424
        type_to_json(member_json, definition.member_type(symbolic::integer(i)));
2✔
425
        j["members"].push_back(member_json);
2✔
426
    }
2✔
427
    j["is_packed"] = definition.is_packed();
2✔
428
}
2✔
429

430
void JSONSerializer::debug_info_to_json(nlohmann::json& j, const DebugInfo& debug_info) {
112✔
431
    j["has"] = debug_info.has();
112✔
432
    j["filename"] = debug_info.filename();
112✔
433
    j["start_line"] = debug_info.start_line();
112✔
434
    j["start_column"] = debug_info.start_column();
112✔
435
    j["end_line"] = debug_info.end_line();
112✔
436
    j["end_column"] = debug_info.end_column();
112✔
437
}
112✔
438

439
/*
440
 * * Deserialization logic
441
 */
442

443
std::unique_ptr<StructuredSDFG> JSONSerializer::deserialize(nlohmann::json& j) {
4✔
444
    assert(j.contains("name"));
4✔
445
    assert(j["name"].is_string());
4✔
446
    assert(j.contains("type"));
4✔
447
    assert(j["type"].is_string());
4✔
448
    assert(j["element_counter"].is_number_integer());
4✔
449

450
    FunctionType function_type = function_type_from_string(j["type"].get<std::string>());
4✔
451
    builder::StructuredSDFGBuilder builder(j["name"], function_type);
4✔
452

453
    size_t element_counter = j["element_counter"];
4✔
454
    builder.set_element_counter(element_counter);
4✔
455

456
    // deserialize structures
457
    assert(j.contains("structures"));
4✔
458
    assert(j["structures"].is_array());
4✔
459
    for (const auto& structure : j["structures"]) {
5✔
460
        assert(structure.contains("name"));
1✔
461
        assert(structure["name"].is_string());
1✔
462
        json_to_structure_definition(structure, builder);
1✔
463
    }
464

465
    nlohmann::json& containers = j["containers"];
4✔
466

467
    // deserialize externals
468
    for (const auto& name : j["externals"]) {
5✔
469
        auto& type_desc = containers.at(name.get<std::string>());
1✔
470
        auto type = json_to_type(type_desc);
1✔
471
        builder.add_container(name, *type, false, true);
1✔
472
    }
1✔
473

474
    // deserialize arguments
475
    for (const auto& name : j["arguments"]) {
7✔
476
        auto& type_desc = containers.at(name.get<std::string>());
3✔
477
        auto type = json_to_type(type_desc);
3✔
478
        builder.add_container(name, *type, true, false);
3✔
479
    }
3✔
480

481
    // deserialize transients
482
    for (const auto& entry : containers.items()) {
13✔
483
        if (builder.subject().is_argument(entry.key())) {
9✔
484
            continue;
3✔
485
        }
486
        if (builder.subject().is_external(entry.key())) {
6✔
487
            continue;
1✔
488
        }
489
        auto type = json_to_type(entry.value());
5✔
490
        builder.add_container(entry.key(), *type, false, false);
5✔
491
    }
5✔
492

493
    // deserialize root node
494
    assert(j.contains("root"));
4✔
495
    auto& root = builder.subject().root();
4✔
496
    json_to_sequence(j["root"], builder, root);
4✔
497

498
    // deserialize metadata
499
    assert(j.contains("metadata"));
4✔
500
    assert(j["metadata"].is_object());
4✔
501
    for (const auto& entry : j["metadata"].items()) {
5✔
502
        builder.subject().add_metadata(entry.key(), entry.value());
1✔
503
    }
504

505
    builder.set_element_counter(element_counter);
4✔
506

507
    return builder.move();
4✔
508
}
4✔
509

510
void JSONSerializer::json_to_structure_definition(const nlohmann::json& j, builder::StructuredSDFGBuilder& builder) {
2✔
511
    assert(j.contains("name"));
2✔
512
    assert(j["name"].is_string());
2✔
513
    assert(j.contains("members"));
2✔
514
    assert(j["members"].is_array());
2✔
515
    assert(j.contains("is_packed"));
2✔
516
    assert(j["is_packed"].is_boolean());
2✔
517
    auto is_packed = j["is_packed"];
2✔
518
    auto& definition = builder.add_structure(j["name"], is_packed);
2✔
519
    for (const auto& member : j["members"]) {
4✔
520
        nlohmann::json member_json;
2✔
521
        auto member_type = json_to_type(member);
2✔
522
        definition.add_member(*member_type);
2✔
523
    }
2✔
524
}
2✔
525

526
std::vector<std::pair<std::string, types::Scalar>> JSONSerializer::json_to_arguments(const nlohmann::json& j) {
4✔
527
    std::vector<std::pair<std::string, types::Scalar>> arguments;
4✔
528
    for (const auto& argument : j) {
12✔
529
        assert(argument.contains("name"));
8✔
530
        assert(argument["name"].is_string());
8✔
531
        assert(argument.contains("type"));
8✔
532
        assert(argument["type"].is_object());
8✔
533
        std::string name = argument["name"];
8✔
534
        auto type = json_to_type(argument["type"]);
8✔
535
        arguments.emplace_back(name, *dynamic_cast<types::Scalar*>(type.get()));
8✔
536
    }
8✔
537
    return arguments;
4✔
538
}
4✔
539

540
void JSONSerializer::json_to_dataflow(
11✔
541
    const nlohmann::json& j, builder::StructuredSDFGBuilder& builder, structured_control_flow::Block& parent
542
) {
543
    std::unordered_map<size_t, data_flow::DataFlowNode&> nodes_map;
11✔
544

545
    assert(j.contains("nodes"));
11✔
546
    assert(j["nodes"].is_array());
11✔
547
    for (const auto& node : j["nodes"]) {
27✔
548
        assert(node.contains("type"));
16✔
549
        assert(node["type"].is_string());
16✔
550
        assert(node.contains("element_id"));
16✔
551
        assert(node["element_id"].is_number_integer());
16✔
552
        std::string type = node["type"];
16✔
553
        if (type == "tasklet") {
16✔
554
            assert(node.contains("code"));
4✔
555
            assert(node["code"].is_number_integer());
4✔
556
            assert(node.contains("inputs"));
4✔
557
            assert(node["inputs"].is_array());
4✔
558
            assert(node.contains("output"));
4✔
559
            assert(node["output"].is_object());
4✔
560
            assert(node["output"].contains("name"));
4✔
561
            assert(node["output"].contains("type"));
4✔
562
            auto inputs = json_to_arguments(node["inputs"]);
4✔
563

564
            auto output_name = node["output"]["name"];
4✔
565
            auto output_type = json_to_type(node["output"]["type"]);
4✔
566
            auto& output_type_scalar = dynamic_cast<types::Scalar&>(*output_type);
4✔
567

568
            auto& tasklet = builder.add_tasklet(
8✔
569
                parent, node["code"], {output_name, output_type_scalar}, inputs, json_to_debug_info(node["debug_info"])
4✔
570
            );
571
            tasklet.element_id_ = node["element_id"];
4✔
572
            nodes_map.insert({node["element_id"], tasklet});
4✔
573
        } else if (type == "library_node") {
16✔
574
            assert(node.contains("code"));
×
575
            data_flow::LibraryNodeCode code(node["code"].get<std::string>());
×
576

577
            auto serializer_fn = LibraryNodeSerializerRegistry::instance().get_library_node_serializer(code.value());
×
578
            if (serializer_fn == nullptr) {
×
579
                throw std::runtime_error("Unknown library node code: " + std::string(code.value()));
×
580
            }
581
            auto serializer = serializer_fn();
×
582
            auto& lib_node = serializer->deserialize(node, builder, parent);
×
583
            lib_node.element_id_ = node["element_id"];
×
584
            nodes_map.insert({node["element_id"], lib_node});
×
585
        } else if (type == "access_node") {
12✔
586
            assert(node.contains("data"));
12✔
587
            auto& access_node = builder.add_access(parent, node["data"], json_to_debug_info(node["debug_info"]));
12✔
588
            access_node.element_id_ = node["element_id"];
12✔
589
            nodes_map.insert({node["element_id"], access_node});
12✔
590
        } else {
12✔
591
            throw std::runtime_error("Unknown node type");
×
592
        }
593
    }
16✔
594

595
    assert(j.contains("edges"));
11✔
596
    assert(j["edges"].is_array());
11✔
597
    for (const auto& edge : j["edges"]) {
23✔
598
        assert(edge.contains("src"));
12✔
599
        assert(edge["src"].is_number_integer());
12✔
600
        assert(edge.contains("dst"));
12✔
601
        assert(edge["dst"].is_number_integer());
12✔
602
        assert(edge.contains("src_conn"));
12✔
603
        assert(edge["src_conn"].is_string());
12✔
604
        assert(edge.contains("dst_conn"));
12✔
605
        assert(edge["dst_conn"].is_string());
12✔
606
        assert(edge.contains("subset"));
12✔
607
        assert(edge["subset"].is_array());
12✔
608

609
        assert(nodes_map.find(edge["src"]) != nodes_map.end());
12✔
610
        assert(nodes_map.find(edge["dst"]) != nodes_map.end());
12✔
611
        auto& source = nodes_map.at(edge["src"]);
12✔
612
        auto& target = nodes_map.at(edge["dst"]);
12✔
613

614
        if (edge.contains("begin_subset") && edge.contains("end_subset")) {
12✔
615
            assert(edge["begin_subset"].is_array());
12✔
616
            assert(edge["end_subset"].is_array());
12✔
617
            std::vector<symbolic::Expression> begin_subset;
12✔
618
            std::vector<symbolic::Expression> end_subset;
12✔
619
            for (const auto& subset_str : edge["begin_subset"]) {
16✔
620
                assert(subset_str.is_string());
4✔
621
                SymEngine::Expression subset_expr(subset_str);
4✔
622
                begin_subset.push_back(subset_expr);
4✔
623
            }
4✔
624
            for (const auto& subset_str : edge["end_subset"]) {
16✔
625
                assert(subset_str.is_string());
4✔
626
                SymEngine::Expression subset_expr(subset_str);
4✔
627
                end_subset.push_back(subset_expr);
4✔
628
            }
4✔
629
            auto& memlet = builder.add_memlet(
24✔
630
                parent,
12✔
631
                source,
12✔
632
                edge["src_conn"],
12✔
633
                target,
12✔
634
                edge["dst_conn"],
12✔
635
                begin_subset,
636
                end_subset,
637
                json_to_debug_info(edge["debug_info"])
12✔
638
            );
639
            memlet.element_id_ = edge["element_id"];
12✔
640
        } else if (edge.contains("subset")) {
12✔
NEW
641
            assert(edge["subset"].is_array());
×
NEW
642
            std::vector<symbolic::Expression> subset;
×
NEW
643
            for (const auto& subset_str : edge["subset"]) {
×
NEW
644
                assert(subset_str.is_string());
×
NEW
645
                SymEngine::Expression subset_expr(subset_str);
×
NEW
646
                subset.push_back(subset_expr);
×
NEW
647
            }
×
NEW
648
            auto& memlet = builder.add_memlet(
×
NEW
649
                parent,
×
NEW
650
                source,
×
NEW
651
                edge["src_conn"],
×
NEW
652
                target,
×
NEW
653
                edge["dst_conn"],
×
654
                subset,
NEW
655
                json_to_debug_info(edge["debug_info"])
×
656
            );
NEW
657
            memlet.element_id_ = edge["element_id"];
×
658
        } else {
×
659
            throw std::runtime_error("Subsets not specified in json");
×
660
        }
661
    }
662
}
11✔
663

664
void JSONSerializer::json_to_sequence(
13✔
665
    const nlohmann::json& j, builder::StructuredSDFGBuilder& builder, structured_control_flow::Sequence& sequence
666
) {
667
    assert(j.contains("type"));
13✔
668
    assert(j["type"].is_string());
13✔
669
    assert(j.contains("children"));
13✔
670
    assert(j["children"].is_array());
13✔
671
    assert(j.contains("transitions"));
13✔
672
    assert(j["transitions"].is_array());
13✔
673
    assert(j["transitions"].size() == j["children"].size());
13✔
674

675
    sequence.element_id_ = j["element_id"];
13✔
676
    sequence.debug_info_ = json_to_debug_info(j["debug_info"]);
13✔
677

678
    std::string type = j["type"];
13✔
679
    if (type == "sequence") {
13✔
680
        for (size_t i = 0; i < j["children"].size(); i++) {
24✔
681
            auto& child = j["children"][i];
11✔
682
            auto& transition = j["transitions"][i];
11✔
683
            assert(child.contains("type"));
11✔
684
            assert(child["type"].is_string());
11✔
685

686
            assert(transition.contains("type"));
11✔
687
            assert(transition["type"].is_string());
11✔
688
            assert(transition.contains("assignments"));
11✔
689
            assert(transition["assignments"].is_array());
11✔
690
            control_flow::Assignments assignments;
11✔
691
            for (const auto& assignment : transition["assignments"]) {
13✔
692
                assert(assignment.contains("symbol"));
2✔
693
                assert(assignment["symbol"].is_string());
2✔
694
                assert(assignment.contains("expression"));
2✔
695
                assert(assignment["expression"].is_string());
2✔
696
                SymEngine::Expression expr(assignment["expression"]);
2✔
697
                assignments.insert({symbolic::symbol(assignment["symbol"]), expr});
2✔
698
            }
2✔
699

700
            if (child["type"] == "block") {
11✔
701
                json_to_block_node(child, builder, sequence, assignments);
9✔
702
            } else if (child["type"] == "for") {
11✔
703
                json_to_for_node(child, builder, sequence, assignments);
×
704
            } else if (child["type"] == "if_else") {
2✔
705
                json_to_if_else_node(child, builder, sequence, assignments);
×
706
            } else if (child["type"] == "while") {
2✔
707
                json_to_while_node(child, builder, sequence, assignments);
×
708
            } else if (child["type"] == "break") {
2✔
709
                json_to_break_node(child, builder, sequence, assignments);
1✔
710
            } else if (child["type"] == "continue") {
2✔
711
                json_to_continue_node(child, builder, sequence, assignments);
1✔
712
            } else if (child["type"] == "return") {
1✔
713
                json_to_return_node(child, builder, sequence, assignments);
×
714
            } else if (child["type"] == "map") {
×
715
                json_to_map_node(child, builder, sequence, assignments);
×
716
            } else if (child["type"] == "sequence") {
×
717
                auto& subseq = builder.add_sequence(sequence, assignments, json_to_debug_info(child["debug_info"]));
×
718
                json_to_sequence(child, builder, subseq);
×
719
            } else {
×
720
                throw std::runtime_error("Unknown child type");
×
721
            }
722

723
            sequence.at(i).second.debug_info_ = json_to_debug_info(transition["debug_info"]);
11✔
724
            sequence.at(i).second.element_id_ = transition["element_id"];
11✔
725
        }
11✔
726
    } else {
13✔
727
        throw std::runtime_error("expected sequence type");
×
728
    }
729
}
13✔
730

731
void JSONSerializer::json_to_block_node(
10✔
732
    const nlohmann::json& j,
733
    builder::StructuredSDFGBuilder& builder,
734
    structured_control_flow::Sequence& parent,
735
    control_flow::Assignments& assignments
736
) {
737
    assert(j.contains("type"));
10✔
738
    assert(j["type"].is_string());
10✔
739
    assert(j.contains("dataflow"));
10✔
740
    assert(j["dataflow"].is_object());
10✔
741
    auto& block = builder.add_block(parent, assignments, json_to_debug_info(j["debug_info"]));
10✔
742
    block.element_id_ = j["element_id"];
10✔
743
    assert(j["dataflow"].contains("type"));
10✔
744
    assert(j["dataflow"]["type"].is_string());
10✔
745
    std::string type = j["dataflow"]["type"];
10✔
746
    if (type == "dataflow") {
10✔
747
        json_to_dataflow(j["dataflow"], builder, block);
10✔
748
    } else {
10✔
749
        throw std::runtime_error("Unknown dataflow type");
×
750
    }
751
}
10✔
752

753
void JSONSerializer::json_to_for_node(
1✔
754
    const nlohmann::json& j,
755
    builder::StructuredSDFGBuilder& builder,
756
    structured_control_flow::Sequence& parent,
757
    control_flow::Assignments& assignments
758
) {
759
    assert(j.contains("type"));
1✔
760
    assert(j["type"].is_string());
1✔
761
    assert(j.contains("indvar"));
1✔
762
    assert(j["indvar"].is_string());
1✔
763
    assert(j.contains("init"));
1✔
764
    assert(j["init"].is_string());
1✔
765
    assert(j.contains("condition"));
1✔
766
    assert(j["condition"].is_string());
1✔
767
    assert(j.contains("update"));
1✔
768
    assert(j["update"].is_string());
1✔
769
    assert(j.contains("root"));
1✔
770
    assert(j["root"].is_object());
1✔
771

772
    symbolic::Symbol indvar = symbolic::symbol(j["indvar"]);
1✔
773
    SymEngine::Expression init(j["init"]);
1✔
774
    SymEngine::Expression condition_expr(j["condition"]);
1✔
775
    assert(!SymEngine::rcp_static_cast<const SymEngine::Boolean>(condition_expr.get_basic()).is_null());
1✔
776
    symbolic::Condition condition = SymEngine::rcp_static_cast<const SymEngine::Boolean>(condition_expr.get_basic());
1✔
777
    SymEngine::Expression update(j["update"]);
1✔
778
    auto& for_node =
1✔
779
        builder.add_for(parent, indvar, condition, init, update, assignments, json_to_debug_info(j["debug_info"]));
1✔
780
    for_node.element_id_ = j["element_id"];
1✔
781

782
    assert(j["root"].contains("type"));
1✔
783
    assert(j["root"]["type"].is_string());
1✔
784
    assert(j["root"]["type"] == "sequence");
1✔
785
    json_to_sequence(j["root"], builder, for_node.root());
1✔
786
}
1✔
787

788
void JSONSerializer::json_to_if_else_node(
1✔
789
    const nlohmann::json& j,
790
    builder::StructuredSDFGBuilder& builder,
791
    structured_control_flow::Sequence& parent,
792
    control_flow::Assignments& assignments
793
) {
794
    assert(j.contains("type"));
1✔
795
    assert(j["type"].is_string());
1✔
796
    assert(j["type"] == "if_else");
1✔
797
    assert(j.contains("branches"));
1✔
798
    assert(j["branches"].is_array());
1✔
799
    auto& if_else_node = builder.add_if_else(parent, assignments, json_to_debug_info(j["debug_info"]));
1✔
800
    if_else_node.element_id_ = j["element_id"];
1✔
801
    for (const auto& branch : j["branches"]) {
3✔
802
        assert(branch.contains("condition"));
2✔
803
        assert(branch["condition"].is_string());
2✔
804
        assert(branch.contains("root"));
2✔
805
        assert(branch["root"].is_object());
2✔
806
        SymEngine::Expression condition_expr(branch["condition"]);
2✔
807
        assert(!SymEngine::rcp_static_cast<const SymEngine::Boolean>(condition_expr.get_basic()).is_null());
2✔
808
        symbolic::Condition condition = SymEngine::rcp_static_cast<const SymEngine::Boolean>(condition_expr.get_basic()
2✔
809
        );
810
        auto& branch_node = builder.add_case(if_else_node, condition);
2✔
811
        assert(branch["root"].contains("type"));
2✔
812
        assert(branch["root"]["type"].is_string());
2✔
813
        std::string type = branch["root"]["type"];
2✔
814
        if (type == "sequence") {
2✔
815
            json_to_sequence(branch["root"], builder, branch_node);
2✔
816
        } else {
2✔
817
            throw std::runtime_error("Unknown child type");
×
818
        }
819
    }
2✔
820
}
1✔
821

822
void JSONSerializer::json_to_while_node(
3✔
823
    const nlohmann::json& j,
824
    builder::StructuredSDFGBuilder& builder,
825
    structured_control_flow::Sequence& parent,
826
    control_flow::Assignments& assignments
827
) {
828
    assert(j.contains("type"));
3✔
829
    assert(j["type"].is_string());
3✔
830
    assert(j["type"] == "while");
3✔
831
    assert(j.contains("root"));
3✔
832
    assert(j["root"].is_object());
3✔
833

834
    auto& while_node = builder.add_while(parent, assignments, json_to_debug_info(j["debug_info"]));
3✔
835
    while_node.element_id_ = j["element_id"];
3✔
836

837
    assert(j["root"]["type"] == "sequence");
3✔
838
    json_to_sequence(j["root"], builder, while_node.root());
3✔
839
}
3✔
840

841
void JSONSerializer::json_to_break_node(
1✔
842
    const nlohmann::json& j,
843
    builder::StructuredSDFGBuilder& builder,
844
    structured_control_flow::Sequence& parent,
845
    control_flow::Assignments& assignments
846
) {
847
    assert(j.contains("type"));
1✔
848
    assert(j["type"].is_string());
1✔
849
    assert(j["type"] == "break");
1✔
850
    auto& node = builder.add_break(parent, assignments, json_to_debug_info(j["debug_info"]));
1✔
851
    node.element_id_ = j["element_id"];
1✔
852
}
1✔
853

854
void JSONSerializer::json_to_continue_node(
1✔
855
    const nlohmann::json& j,
856
    builder::StructuredSDFGBuilder& builder,
857
    structured_control_flow::Sequence& parent,
858
    control_flow::Assignments& assignments
859
) {
860
    assert(j.contains("type"));
1✔
861
    assert(j["type"].is_string());
1✔
862
    assert(j["type"] == "continue");
1✔
863
    auto& node = builder.add_continue(parent, assignments, json_to_debug_info(j["debug_info"]));
1✔
864
    node.element_id_ = j["element_id"];
1✔
865
}
1✔
866

867
void JSONSerializer::json_to_map_node(
1✔
868
    const nlohmann::json& j,
869
    builder::StructuredSDFGBuilder& builder,
870
    structured_control_flow::Sequence& parent,
871
    control_flow::Assignments& assignments
872
) {
873
    assert(j.contains("type"));
1✔
874
    assert(j["type"].is_string());
1✔
875
    assert(j["type"] == "map");
1✔
876
    assert(j.contains("indvar"));
1✔
877
    assert(j["indvar"].is_string());
1✔
878
    assert(j.contains("init"));
1✔
879
    assert(j["init"].is_string());
1✔
880
    assert(j.contains("condition"));
1✔
881
    assert(j["condition"].is_string());
1✔
882
    assert(j.contains("update"));
1✔
883
    assert(j["update"].is_string());
1✔
884
    assert(j.contains("root"));
1✔
885
    assert(j["root"].is_object());
1✔
886
    assert(j.contains("schedule_type"));
1✔
887
    assert(j["schedule_type"].is_string());
1✔
888

889
    structured_control_flow::ScheduleType schedule_type =
890
        schedule_type_from_string(j["schedule_type"].get<std::string>());
1✔
891

892
    symbolic::Symbol indvar = symbolic::symbol(j["indvar"]);
1✔
893
    SymEngine::Expression init(j["init"]);
1✔
894
    SymEngine::Expression condition_expr(j["condition"]);
1✔
895
    assert(!SymEngine::rcp_static_cast<const SymEngine::Boolean>(condition_expr.get_basic()).is_null());
1✔
896
    symbolic::Condition condition = SymEngine::rcp_static_cast<const SymEngine::Boolean>(condition_expr.get_basic());
1✔
897
    SymEngine::Expression update(j["update"]);
1✔
898

899
    auto& map_node = builder.add_map(
2✔
900
        parent, indvar, condition, init, update, schedule_type, assignments, json_to_debug_info(j["debug_info"])
1✔
901
    );
902
    map_node.element_id_ = j["element_id"];
1✔
903

904
    assert(j["root"].contains("type"));
1✔
905
    assert(j["root"]["type"].is_string());
1✔
906
    assert(j["root"]["type"] == "sequence");
1✔
907
    json_to_sequence(j["root"], builder, map_node.root());
1✔
908
}
1✔
909

910
void JSONSerializer::json_to_return_node(
1✔
911
    const nlohmann::json& j,
912
    builder::StructuredSDFGBuilder& builder,
913
    structured_control_flow::Sequence& parent,
914
    control_flow::Assignments& assignments
915
) {
916
    assert(j.contains("type"));
1✔
917
    assert(j["type"].is_string());
1✔
918
    assert(j["type"] == "return");
1✔
919

920
    auto& node = builder.add_return(parent, assignments, json_to_debug_info(j["debug_info"]));
1✔
921
    node.element_id_ = j["element_id"];
1✔
922
}
1✔
923

924
std::unique_ptr<types::IType> JSONSerializer::json_to_type(const nlohmann::json& j) {
35✔
925
    if (j.contains("type")) {
35✔
926
        if (j["type"] == "scalar") {
35✔
927
            // Deserialize scalar type
928
            assert(j.contains("primitive_type"));
28✔
929
            types::PrimitiveType primitive_type = j["primitive_type"];
28✔
930
            assert(j.contains("storage_type"));
28✔
931
            types::StorageType storage_type = storage_type_from_string(j["storage_type"].get<std::string>());
28✔
932
            assert(j.contains("initializer"));
28✔
933
            std::string initializer = j["initializer"];
28✔
934
            assert(j.contains("alignment"));
28✔
935
            size_t alignment = j["alignment"];
28✔
936
            return std::make_unique<types::Scalar>(storage_type, alignment, initializer, primitive_type);
28✔
937
        } else if (j["type"] == "array") {
35✔
938
            // Deserialize array type
939
            assert(j.contains("element_type"));
2✔
940
            std::unique_ptr<types::IType> member_type = json_to_type(j["element_type"]);
2✔
941
            assert(j.contains("num_elements"));
2✔
942
            std::string num_elements_str = j["num_elements"];
2✔
943
            // Convert num_elements_str to symbolic::Expression
944
            SymEngine::Expression num_elements(num_elements_str);
2✔
945
            assert(j.contains("storage_type"));
2✔
946
            types::StorageType storage_type = storage_type_from_string(j["storage_type"].get<std::string>());
2✔
947
            assert(j.contains("initializer"));
2✔
948
            std::string initializer = j["initializer"];
2✔
949
            assert(j.contains("alignment"));
2✔
950
            size_t alignment = j["alignment"];
2✔
951
            return std::make_unique<types::Array>(storage_type, alignment, initializer, *member_type, num_elements);
2✔
952
        } else if (j["type"] == "pointer") {
7✔
953
            // Deserialize pointer type
954
            assert(j.contains("pointee_type"));
2✔
955
            std::unique_ptr<types::IType> pointee_type = json_to_type(j["pointee_type"]);
2✔
956
            assert(j.contains("storage_type"));
2✔
957
            types::StorageType storage_type = storage_type_from_string(j["storage_type"].get<std::string>());
2✔
958
            assert(j.contains("initializer"));
2✔
959
            std::string initializer = j["initializer"];
2✔
960
            assert(j.contains("alignment"));
2✔
961
            size_t alignment = j["alignment"];
2✔
962
            return std::make_unique<types::Pointer>(storage_type, alignment, initializer, *pointee_type);
2✔
963
        } else if (j["type"] == "structure") {
5✔
964
            // Deserialize structure type
965
            assert(j.contains("name"));
2✔
966
            std::string name = j["name"];
2✔
967
            assert(j.contains("storage_type"));
2✔
968
            types::StorageType storage_type = storage_type_from_string(j["storage_type"].get<std::string>());
2✔
969
            assert(j.contains("initializer"));
2✔
970
            std::string initializer = j["initializer"];
2✔
971
            assert(j.contains("alignment"));
2✔
972
            size_t alignment = j["alignment"];
2✔
973
            return std::make_unique<types::Structure>(storage_type, alignment, initializer, name);
2✔
974
        } else if (j["type"] == "function") {
3✔
975
            // Deserialize function type
976
            assert(j.contains("return_type"));
1✔
977
            std::unique_ptr<types::IType> return_type = json_to_type(j["return_type"]);
1✔
978
            assert(j.contains("params"));
1✔
979
            std::vector<std::unique_ptr<types::IType>> params;
1✔
980
            for (const auto& param : j["params"]) {
3✔
981
                params.push_back(json_to_type(param));
2✔
982
            }
983
            assert(j.contains("is_var_arg"));
1✔
984
            bool is_var_arg = j["is_var_arg"];
1✔
985
            assert(j.contains("storage_type"));
1✔
986
            types::StorageType storage_type = storage_type_from_string(j["storage_type"].get<std::string>());
1✔
987
            assert(j.contains("initializer"));
1✔
988
            std::string initializer = j["initializer"];
1✔
989
            assert(j.contains("alignment"));
1✔
990
            size_t alignment = j["alignment"];
1✔
991
            auto function =
992
                std::make_unique<types::Function>(storage_type, alignment, initializer, *return_type, is_var_arg);
1✔
993
            for (const auto& param : params) {
3✔
994
                function->add_param(*param);
2✔
995
            }
996
            return function->clone();
1✔
997

998
        } else {
1✔
999
            throw std::runtime_error("Unknown type");
×
1000
        }
1001
    } else {
1002
        throw std::runtime_error("Type not found");
×
1003
    }
1004
}
35✔
1005

1006
DebugInfo JSONSerializer::json_to_debug_info(const nlohmann::json& j) {
71✔
1007
    assert(j.contains("has"));
71✔
1008
    assert(j["has"].is_boolean());
71✔
1009
    if (!j["has"]) {
71✔
1010
        return DebugInfo();
71✔
1011
    }
1012
    assert(j.contains("filename"));
×
1013
    assert(j["filename"].is_string());
×
1014
    std::string filename = j["filename"];
×
1015
    assert(j.contains("start_line"));
×
1016
    assert(j["start_line"].is_number_integer());
×
1017
    size_t start_line = j["start_line"];
×
1018
    assert(j.contains("start_column"));
×
1019
    assert(j["start_column"].is_number_integer());
×
1020
    size_t start_column = j["start_column"];
×
1021
    assert(j.contains("end_line"));
×
1022
    assert(j["end_line"].is_number_integer());
×
1023
    size_t end_line = j["end_line"];
×
1024
    assert(j.contains("end_column"));
×
1025
    assert(j["end_column"].is_number_integer());
×
1026
    size_t end_column = j["end_column"];
×
1027
    return DebugInfo(filename, start_line, start_column, end_line, end_column);
×
1028
}
71✔
1029

1030
std::string JSONSerializer::expression(const symbolic::Expression& expr) {
47✔
1031
    JSONSymbolicPrinter printer;
47✔
1032
    return printer.apply(expr);
47✔
1033
};
47✔
1034

1035
void JSONSymbolicPrinter::bvisit(const SymEngine::Equality& x) {
×
1036
    str_ = apply(x.get_args()[0]) + " == " + apply(x.get_args()[1]);
×
1037
    str_ = parenthesize(str_);
×
1038
};
×
1039

1040
void JSONSymbolicPrinter::bvisit(const SymEngine::Unequality& x) {
×
1041
    str_ = apply(x.get_args()[0]) + " != " + apply(x.get_args()[1]);
×
1042
    str_ = parenthesize(str_);
×
1043
};
×
1044

1045
void JSONSymbolicPrinter::bvisit(const SymEngine::LessThan& x) {
×
1046
    str_ = apply(x.get_args()[0]) + " <= " + apply(x.get_args()[1]);
×
1047
    str_ = parenthesize(str_);
×
1048
};
×
1049

1050
void JSONSymbolicPrinter::bvisit(const SymEngine::StrictLessThan& x) {
4✔
1051
    str_ = apply(x.get_args()[0]) + " < " + apply(x.get_args()[1]);
4✔
1052
    str_ = parenthesize(str_);
4✔
1053
};
4✔
1054

1055
void JSONSymbolicPrinter::bvisit(const SymEngine::Min& x) {
×
1056
    std::ostringstream s;
×
1057
    auto container = x.get_args();
×
1058
    if (container.size() == 1) {
×
1059
        s << apply(*container.begin());
×
1060
    } else {
×
1061
        s << "min(";
×
1062
        s << apply(*container.begin());
×
1063

1064
        // Recursively apply __daisy_min to the arguments
1065
        SymEngine::vec_basic subargs;
×
1066
        for (auto it = ++(container.begin()); it != container.end(); ++it) {
×
1067
            subargs.push_back(*it);
×
1068
        }
×
1069
        auto submin = SymEngine::min(subargs);
×
1070
        s << ", " << apply(submin);
×
1071

1072
        s << ")";
×
1073
    }
×
1074

1075
    str_ = s.str();
×
1076
};
×
1077

1078
void JSONSymbolicPrinter::bvisit(const SymEngine::Max& x) {
×
1079
    std::ostringstream s;
×
1080
    auto container = x.get_args();
×
1081
    if (container.size() == 1) {
×
1082
        s << apply(*container.begin());
×
1083
    } else {
×
1084
        s << "max(";
×
1085
        s << apply(*container.begin());
×
1086

1087
        // Recursively apply __daisy_max to the arguments
1088
        SymEngine::vec_basic subargs;
×
1089
        for (auto it = ++(container.begin()); it != container.end(); ++it) {
×
1090
            subargs.push_back(*it);
×
1091
        }
×
1092
        auto submax = SymEngine::max(subargs);
×
1093
        s << ", " << apply(submax);
×
1094

1095
        s << ")";
×
1096
    }
×
1097

1098
    str_ = s.str();
×
1099
};
×
1100

1101
void LibraryNodeSerializerRegistry::
1102
    register_library_node_serializer(std::string library_node_code, LibraryNodeSerializerFn fn) {
6✔
1103
    std::lock_guard<std::mutex> lock(mutex_);
6✔
1104
    if (factory_map_.find(library_node_code) != factory_map_.end()) {
6✔
1105
        throw std::runtime_error(
×
1106
            "Library node serializer already registered for library node code: " + std::string(library_node_code)
×
1107
        );
1108
    }
1109
    factory_map_[library_node_code] = std::move(fn);
6✔
1110
}
6✔
1111

1112
LibraryNodeSerializerFn LibraryNodeSerializerRegistry::get_library_node_serializer(std::string library_node_code) {
1✔
1113
    auto it = factory_map_.find(library_node_code);
1✔
1114
    if (it != factory_map_.end()) {
1✔
1115
        return it->second;
1✔
1116
    }
1117
    return nullptr;
×
1118
}
1✔
1119

1120
size_t LibraryNodeSerializerRegistry::size() const { return factory_map_.size(); }
×
1121

1122
void register_default_serializers() {
2✔
1123
    LibraryNodeSerializerRegistry::instance()
2✔
1124
        .register_library_node_serializer(data_flow::LibraryNodeType_Metadata.value(), []() {
2✔
1125
            return std::make_unique<data_flow::MetadataNodeSerializer>();
×
1126
        });
1127
    LibraryNodeSerializerRegistry::instance()
2✔
1128
        .register_library_node_serializer(data_flow::LibraryNodeType_BarrierLocal.value(), []() {
3✔
1129
            return std::make_unique<data_flow::BarrierLocalNodeSerializer>();
1✔
1130
        });
1131

1132
    /* Math */
1133
    LibraryNodeSerializerRegistry::instance()
2✔
1134
        .register_library_node_serializer(math::ml::LibraryNodeType_ReLU.value(), []() {
2✔
1135
            return std::make_unique<math::ml::ReLUNodeSerializer>();
×
1136
        });
1137
    // Add more serializers as needed
1138
}
2✔
1139

1140
} // namespace serializer
1141
} // 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