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

daisytuner / sdfglib / 17651658650

11 Sep 2025 04:58PM UTC coverage: 61.012% (+1.3%) from 59.755%
17651658650

Pull #219

github

web-flow
Merge 742a12367 into f744ac9f5
Pull Request #219: stdlib Library Nodes and ConstantNodes

499 of 1681 new or added lines in 81 files covered. (29.68%)

95 existing lines in 36 files now uncovered.

9718 of 15928 relevant lines covered (61.01%)

108.0 hits per line

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

84.3
/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/barrier_local_node.h"
10
#include "sdfg/data_flow/library_nodes/call_node.h"
11
#include "sdfg/data_flow/library_nodes/math/math.h"
12
#include "sdfg/data_flow/library_nodes/metadata_node.h"
13
#include "sdfg/data_flow/library_nodes/stdlib/stdlib.h"
14

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

35
namespace sdfg {
36
namespace serializer {
37

38
FunctionType function_type_from_string(const std::string& str) {
5✔
39
    if (str == FunctionType_CPU.value()) {
5✔
40
        return FunctionType_CPU;
5✔
41
    } else if (str == FunctionType_NV_GLOBAL.value()) {
×
42
        return FunctionType_NV_GLOBAL;
×
43
    }
44

45
    return FunctionType(str);
×
46
}
5✔
47

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

63
    return types::StorageType(str);
×
64
}
46✔
65

66
/*
67
 * * JSONSerializer class
68
 * * Serialization logic
69
 */
70

71
nlohmann::json JSONSerializer::serialize(const sdfg::StructuredSDFG& sdfg) {
5✔
72
    nlohmann::json j;
5✔
73

74
    j["name"] = sdfg.name();
5✔
75
    j["element_counter"] = sdfg.element_counter();
5✔
76
    j["type"] = std::string(sdfg.type().value());
5✔
77
    j["debug_info"] = nlohmann::json::object();
5✔
78
    debug_table_to_json(j["debug_info"], sdfg.debug_info());
5✔
79

80
    nlohmann::json return_type_json;
5✔
81
    type_to_json(return_type_json, sdfg.return_type());
5✔
82
    j["return_type"] = return_type_json;
5✔
83

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

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

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

104
    j["externals"] = nlohmann::json::array();
5✔
105
    for (const auto& external : sdfg.externals()) {
9✔
106
        nlohmann::json external_json;
4✔
107
        external_json["name"] = external;
4✔
108
        external_json["linkage_type"] = sdfg.linkage_type(external);
4✔
109
        j["externals"].push_back(external_json);
4✔
110
    }
4✔
111

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

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

122
    return j;
5✔
123
}
5✔
124

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

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

134
        node_json["debug_info"] = nlohmann::json::object();
20✔
135
        debug_info_region_to_json(node_json["debug_info"], node.debug_info());
20✔
136

137
        if (auto tasklet = dynamic_cast<const data_flow::Tasklet*>(&node)) {
20✔
138
            node_json["type"] = "tasklet";
5✔
139
            node_json["code"] = tasklet->code();
5✔
140
            node_json["inputs"] = nlohmann::json::array();
5✔
141
            for (auto& input : tasklet->inputs()) {
15✔
142
                node_json["inputs"].push_back(input);
10✔
143
            }
144
            node_json["output"] = tasklet->output();
5✔
145
        } else if (auto lib_node = dynamic_cast<const data_flow::LibraryNode*>(&node)) {
20✔
UNCOV
146
            node_json["type"] = "library_node";
×
147
            node_json["implementation_type"] = std::string(lib_node->implementation_type().value());
×
148
            auto serializer_fn =
149
                LibraryNodeSerializerRegistry::instance().get_library_node_serializer(lib_node->code().value());
×
150
            if (serializer_fn == nullptr) {
×
151
                throw std::runtime_error("Unknown library node code: " + std::string(lib_node->code().value()));
×
152
            }
153
            auto serializer = serializer_fn();
×
154
            auto lib_node_json = serializer->serialize(*lib_node);
×
155
            node_json.merge_patch(lib_node_json);
×
156
        } else if (auto code_node = dynamic_cast<const data_flow::ConstantNode*>(&node)) {
15✔
NEW
157
            node_json["type"] = "constant_node";
×
NEW
158
            node_json["data"] = code_node->data();
×
159

NEW
160
            nlohmann::json type_json;
×
NEW
161
            type_to_json(type_json, code_node->type());
×
NEW
162
            node_json["data_type"] = type_json;
×
163
        } else if (auto code_node = dynamic_cast<const data_flow::AccessNode*>(&node)) {
15✔
164
            node_json["type"] = "access_node";
15✔
165
            node_json["data"] = code_node->data();
15✔
166
        } else {
15✔
167
            throw std::runtime_error("Unknown node type");
×
168
        }
169

170
        j["nodes"].push_back(node_json);
20✔
171
    }
20✔
172

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

177
        edge_json["debug_info"] = nlohmann::json::object();
15✔
178
        debug_info_region_to_json(edge_json["debug_info"], edge.debug_info());
15✔
179

180
        edge_json["src"] = edge.src().element_id();
15✔
181
        edge_json["dst"] = edge.dst().element_id();
15✔
182

183
        edge_json["src_conn"] = edge.src_conn();
15✔
184
        edge_json["dst_conn"] = edge.dst_conn();
15✔
185

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

191
        nlohmann::json base_type_json;
15✔
192
        type_to_json(base_type_json, edge.base_type());
15✔
193
        edge_json["base_type"] = base_type_json;
15✔
194

195
        j["edges"].push_back(edge_json);
15✔
196
    }
15✔
197
}
21✔
198

199
void JSONSerializer::block_to_json(nlohmann::json& j, const structured_control_flow::Block& block) {
19✔
200
    j["type"] = "block";
19✔
201
    j["element_id"] = block.element_id();
19✔
202

203
    j["debug_info"] = nlohmann::json::object();
19✔
204
    debug_info_region_to_json(j["debug_info"], block.debug_info());
19✔
205

206
    nlohmann::json dataflow_json;
19✔
207
    dataflow_to_json(dataflow_json, block.dataflow());
19✔
208
    j["dataflow"] = dataflow_json;
19✔
209
}
19✔
210

211
void JSONSerializer::for_to_json(nlohmann::json& j, const structured_control_flow::For& for_node) {
2✔
212
    j["type"] = "for";
2✔
213
    j["element_id"] = for_node.element_id();
2✔
214

215
    j["debug_info"] = nlohmann::json::object();
2✔
216
    debug_info_region_to_json(j["debug_info"], for_node.debug_info());
2✔
217

218
    j["indvar"] = expression(for_node.indvar());
2✔
219
    j["init"] = expression(for_node.init());
2✔
220
    j["condition"] = expression(for_node.condition());
2✔
221
    j["update"] = expression(for_node.update());
2✔
222

223
    nlohmann::json body_json;
2✔
224
    sequence_to_json(body_json, for_node.root());
2✔
225
    j["root"] = body_json;
2✔
226
}
2✔
227

228
void JSONSerializer::if_else_to_json(nlohmann::json& j, const structured_control_flow::IfElse& if_else_node) {
2✔
229
    j["type"] = "if_else";
2✔
230
    j["element_id"] = if_else_node.element_id();
2✔
231

232
    j["debug_info"] = nlohmann::json::object();
2✔
233
    debug_info_region_to_json(j["debug_info"], if_else_node.debug_info());
2✔
234

235
    j["branches"] = nlohmann::json::array();
2✔
236
    for (size_t i = 0; i < if_else_node.size(); i++) {
6✔
237
        nlohmann::json branch_json;
4✔
238
        branch_json["condition"] = expression(if_else_node.at(i).second);
4✔
239
        nlohmann::json body_json;
4✔
240
        sequence_to_json(body_json, if_else_node.at(i).first);
4✔
241
        branch_json["root"] = body_json;
4✔
242
        j["branches"].push_back(branch_json);
4✔
243
    }
4✔
244
}
2✔
245

246
void JSONSerializer::while_node_to_json(nlohmann::json& j, const structured_control_flow::While& while_node) {
5✔
247
    j["type"] = "while";
5✔
248
    j["element_id"] = while_node.element_id();
5✔
249

250
    j["debug_info"] = nlohmann::json::object();
5✔
251
    debug_info_region_to_json(j["debug_info"], while_node.debug_info());
5✔
252

253
    nlohmann::json body_json;
5✔
254
    sequence_to_json(body_json, while_node.root());
5✔
255
    j["root"] = body_json;
5✔
256
}
5✔
257

258
void JSONSerializer::break_node_to_json(nlohmann::json& j, const structured_control_flow::Break& break_node) {
2✔
259
    j["type"] = "break";
2✔
260
    j["element_id"] = break_node.element_id();
2✔
261

262
    j["debug_info"] = nlohmann::json::object();
2✔
263
    debug_info_region_to_json(j["debug_info"], break_node.debug_info());
2✔
264
}
2✔
265

266
void JSONSerializer::continue_node_to_json(nlohmann::json& j, const structured_control_flow::Continue& continue_node) {
2✔
267
    j["type"] = "continue";
2✔
268
    j["element_id"] = continue_node.element_id();
2✔
269

270
    j["debug_info"] = nlohmann::json::object();
2✔
271
    debug_info_region_to_json(j["debug_info"], continue_node.debug_info());
2✔
272
}
2✔
273

274
void JSONSerializer::map_to_json(nlohmann::json& j, const structured_control_flow::Map& map_node) {
2✔
275
    j["type"] = "map";
2✔
276
    j["element_id"] = map_node.element_id();
2✔
277

278
    j["debug_info"] = nlohmann::json::object();
2✔
279
    debug_info_region_to_json(j["debug_info"], map_node.debug_info());
2✔
280

281
    j["indvar"] = expression(map_node.indvar());
2✔
282
    j["init"] = expression(map_node.init());
2✔
283
    j["condition"] = expression(map_node.condition());
2✔
284
    j["update"] = expression(map_node.update());
2✔
285

286
    j["schedule_type"] = nlohmann::json::object();
2✔
287
    schedule_type_to_json(j["schedule_type"], map_node.schedule_type());
2✔
288

289
    nlohmann::json body_json;
2✔
290
    sequence_to_json(body_json, map_node.root());
2✔
291
    j["root"] = body_json;
2✔
292
}
2✔
293

294
void JSONSerializer::return_node_to_json(nlohmann::json& j, const structured_control_flow::Return& return_node) {
2✔
295
    j["type"] = "return";
2✔
296
    j["element_id"] = return_node.element_id();
2✔
297
    j["data"] = return_node.data();
2✔
298
    j["unreachable"] = return_node.unreachable();
2✔
299

300
    j["debug_info"] = nlohmann::json::object();
2✔
301
    debug_info_region_to_json(j["debug_info"], return_node.debug_info());
2✔
302
}
2✔
303

304
void JSONSerializer::sequence_to_json(nlohmann::json& j, const structured_control_flow::Sequence& sequence) {
21✔
305
    j["type"] = "sequence";
21✔
306
    j["element_id"] = sequence.element_id();
21✔
307

308
    j["debug_info"] = nlohmann::json::object();
21✔
309
    debug_info_region_to_json(j["debug_info"], sequence.debug_info());
21✔
310

311
    j["children"] = nlohmann::json::array();
21✔
312
    j["transitions"] = nlohmann::json::array();
21✔
313

314
    for (size_t i = 0; i < sequence.size(); i++) {
42✔
315
        nlohmann::json child_json;
21✔
316
        auto& child = sequence.at(i).first;
21✔
317
        auto& transition = sequence.at(i).second;
21✔
318

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

341
        j["children"].push_back(child_json);
21✔
342

343
        // Add transition information
344
        nlohmann::json transition_json;
21✔
345
        transition_json["type"] = "transition";
21✔
346
        transition_json["element_id"] = transition.element_id();
21✔
347

348
        transition_json["debug_info"] = nlohmann::json::object();
21✔
349
        debug_info_region_to_json(transition_json["debug_info"], transition.debug_info());
21✔
350

351
        transition_json["assignments"] = nlohmann::json::array();
21✔
352
        for (const auto& assignment : transition.assignments()) {
24✔
353
            nlohmann::json assignment_json;
3✔
354
            assignment_json["symbol"] = expression(assignment.first);
3✔
355
            assignment_json["expression"] = expression(assignment.second);
3✔
356
            transition_json["assignments"].push_back(assignment_json);
3✔
357
        }
3✔
358

359
        j["transitions"].push_back(transition_json);
21✔
360
    }
21✔
361
}
21✔
362

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

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

426
void JSONSerializer::debug_loc_to_json(nlohmann::json& j, const DebugLoc& loc) {
7✔
427
    j["has"] = loc.has;
7✔
428
    if (!loc.has) {
7✔
429
        return;
×
430
    }
431
    j["filename"] = loc.filename;
7✔
432
    j["function"] = loc.function;
7✔
433
    j["line"] = loc.line;
7✔
434
    j["column"] = loc.column;
7✔
435
}
7✔
436

437

438
void JSONSerializer::debug_info_element_to_json(nlohmann::json& j, const DebugInfo& debug_info_element) {
3✔
439
    j["has"] = debug_info_element.has();
3✔
440
    if (!debug_info_element.has()) {
3✔
441
        return;
×
442
    }
443
    j["locations"] = nlohmann::json::array();
3✔
444
    for (const auto& loc : debug_info_element.locations()) {
9✔
445
        nlohmann::json loc_json;
6✔
446
        debug_loc_to_json(loc_json, loc);
6✔
447
        j["locations"].push_back(loc_json);
6✔
448
    }
6✔
449
}
3✔
450

451
void JSONSerializer::debug_info_region_to_json(nlohmann::json& j, const DebugInfoRegion& debug_info) {
115✔
452
    j["has"] = debug_info.has();
115✔
453
    j["filename"] = debug_info.filename();
115✔
454
    j["function"] = debug_info.function();
115✔
455
    j["start_line"] = debug_info.start_line();
115✔
456
    j["start_column"] = debug_info.start_column();
115✔
457
    j["end_line"] = debug_info.end_line();
115✔
458
    j["end_column"] = debug_info.end_column();
115✔
459

460
    j["indices"] = nlohmann::json::array();
115✔
461
    for (const auto& index : debug_info.indices()) {
119✔
462
        j["indices"].push_back(index);
4✔
463
    }
464
}
115✔
465

466
void JSONSerializer::debug_table_to_json(nlohmann::json& j, const DebugTable& debug_info) {
6✔
467
    j["elements"] = nlohmann::json::array();
6✔
468
    for (const auto& instruction : debug_info.elements()) {
8✔
469
        nlohmann::json instruction_json;
2✔
470
        debug_info_element_to_json(instruction_json, instruction);
2✔
471
        j["elements"].push_back(instruction_json);
2✔
472
    }
2✔
473
}
6✔
474

475
void JSONSerializer::schedule_type_to_json(nlohmann::json& j, const ScheduleType& schedule_type) {
3✔
476
    j["value"] = schedule_type.value();
3✔
477
    j["properties"] = nlohmann::json::object();
3✔
478
    for (const auto& prop : schedule_type.properties()) {
4✔
479
        j["properties"][prop.first] = prop.second;
1✔
480
    }
481
}
3✔
482

483
/*
484
 * * Deserialization logic
485
 */
486

487
std::unique_ptr<StructuredSDFG> JSONSerializer::deserialize(nlohmann::json& j) {
5✔
488
    assert(j.contains("name"));
5✔
489
    assert(j["name"].is_string());
5✔
490
    assert(j.contains("type"));
5✔
491
    assert(j["type"].is_string());
5✔
492
    assert(j.contains("element_counter"));
5✔
493
    assert(j["element_counter"].is_number_integer());
5✔
494
    assert(j.contains("return_type"));
5✔
495
    assert(j["return_type"].is_object());
5✔
496
    assert(j.contains("debug_info"));
5✔
497
    assert(j["debug_info"].is_object());
5✔
498

499
    FunctionType function_type = function_type_from_string(j["type"].get<std::string>());
5✔
500
    auto return_type = json_to_type(j["return_type"]);
5✔
501
    DebugTable debug_info = json_to_debug_table(j["debug_info"]);
5✔
502
    debug_info_ = &debug_info;
5✔
503

504
    builder::StructuredSDFGBuilder builder(j["name"], function_type, *return_type);
5✔
505
    builder.subject().debug_info(debug_info);
5✔
506

507
    size_t element_counter = j["element_counter"];
5✔
508
    builder.set_element_counter(element_counter);
5✔
509

510
    // deserialize structures
511
    assert(j.contains("structures"));
5✔
512
    assert(j["structures"].is_array());
5✔
513
    for (const auto& structure : j["structures"]) {
6✔
514
        assert(structure.contains("name"));
1✔
515
        assert(structure["name"].is_string());
1✔
516
        json_to_structure_definition(structure, builder);
1✔
517
    }
518

519
    nlohmann::json& containers = j["containers"];
5✔
520

521
    // deserialize externals
522
    for (const auto& external : j["externals"]) {
9✔
523
        assert(external.contains("name"));
4✔
524
        assert(external["name"].is_string());
4✔
525
        assert(external.contains("linkage_type"));
4✔
526
        assert(external["linkage_type"].is_number_integer());
4✔
527
        auto& type_desc = containers.at(external["name"].get<std::string>());
4✔
528
        auto type = json_to_type(type_desc);
4✔
529
        builder.add_external(external["name"], *type, LinkageType(external["linkage_type"]));
4✔
530
    }
4✔
531

532
    // deserialize arguments
533
    for (const auto& name : j["arguments"]) {
8✔
534
        auto& type_desc = containers.at(name.get<std::string>());
3✔
535
        auto type = json_to_type(type_desc);
3✔
536
        builder.add_container(name, *type, true, false);
3✔
537
    }
3✔
538

539
    // deserialize transients
540
    for (const auto& entry : containers.items()) {
17✔
541
        if (builder.subject().is_argument(entry.key())) {
12✔
542
            continue;
3✔
543
        }
544
        if (builder.subject().is_external(entry.key())) {
9✔
545
            continue;
4✔
546
        }
547
        auto type = json_to_type(entry.value());
5✔
548
        builder.add_container(entry.key(), *type, false, false);
5✔
549
    }
5✔
550

551
    // deserialize root node
552
    assert(j.contains("root"));
5✔
553
    auto& root = builder.subject().root();
5✔
554
    json_to_sequence(j["root"], builder, root);
5✔
555

556
    // deserialize metadata
557
    assert(j.contains("metadata"));
5✔
558
    assert(j["metadata"].is_object());
5✔
559
    for (const auto& entry : j["metadata"].items()) {
6✔
560
        builder.subject().add_metadata(entry.key(), entry.value());
1✔
561
    }
562

563
    builder.set_element_counter(element_counter);
5✔
564

565
    return builder.move();
5✔
566
}
5✔
567

568
void JSONSerializer::json_to_structure_definition(const nlohmann::json& j, builder::StructuredSDFGBuilder& builder) {
2✔
569
    assert(j.contains("name"));
2✔
570
    assert(j["name"].is_string());
2✔
571
    assert(j.contains("members"));
2✔
572
    assert(j["members"].is_array());
2✔
573
    assert(j.contains("is_packed"));
2✔
574
    assert(j["is_packed"].is_boolean());
2✔
575
    auto is_packed = j["is_packed"];
2✔
576
    auto& definition = builder.add_structure(j["name"], is_packed);
2✔
577
    for (const auto& member : j["members"]) {
4✔
578
        nlohmann::json member_json;
2✔
579
        auto member_type = json_to_type(member);
2✔
580
        definition.add_member(*member_type);
2✔
581
    }
2✔
582
}
2✔
583

584
std::vector<std::pair<std::string, types::Scalar>> JSONSerializer::json_to_arguments(const nlohmann::json& j) {
×
585
    std::vector<std::pair<std::string, types::Scalar>> arguments;
×
586
    for (const auto& argument : j) {
×
587
        assert(argument.contains("name"));
×
588
        assert(argument["name"].is_string());
×
589
        assert(argument.contains("type"));
×
590
        assert(argument["type"].is_object());
×
591
        std::string name = argument["name"];
×
592
        auto type = json_to_type(argument["type"]);
×
593
        arguments.emplace_back(name, *dynamic_cast<types::Scalar*>(type.get()));
×
594
    }
×
595
    return arguments;
×
596
}
×
597

598
void JSONSerializer::json_to_dataflow(
11✔
599
    const nlohmann::json& j, builder::StructuredSDFGBuilder& builder, structured_control_flow::Block& parent
600
) {
601
    std::unordered_map<size_t, data_flow::DataFlowNode&> nodes_map;
11✔
602

603
    assert(j.contains("nodes"));
11✔
604
    assert(j["nodes"].is_array());
11✔
605
    for (const auto& node : j["nodes"]) {
27✔
606
        assert(node.contains("type"));
16✔
607
        assert(node["type"].is_string());
16✔
608
        assert(node.contains("element_id"));
16✔
609
        assert(node["element_id"].is_number_integer());
16✔
610
        std::string type = node["type"];
16✔
611
        if (type == "tasklet") {
16✔
612
            assert(node.contains("code"));
4✔
613
            assert(node["code"].is_number_integer());
4✔
614
            assert(node.contains("inputs"));
4✔
615
            assert(node["inputs"].is_array());
4✔
616
            assert(node.contains("output"));
4✔
617
            assert(node["output"].is_string());
4✔
618
            auto inputs = node["inputs"].get<std::vector<std::string>>();
4✔
619

620
            auto& tasklet = builder.add_tasklet(
8✔
621
                parent,
4✔
622
                node["code"],
4✔
623
                node["output"],
4✔
624
                inputs,
625
                builder.subject().debug_info().get_region(json_to_debug_info_region(node["debug_info"], *debug_info_)
8✔
626
                                                              .indices())
4✔
627
            );
628
            tasklet.element_id_ = node["element_id"];
4✔
629
            nodes_map.insert({node["element_id"], tasklet});
4✔
630
        } else if (type == "library_node") {
16✔
631
            assert(node.contains("code"));
×
632
            data_flow::LibraryNodeCode code(node["code"].get<std::string>());
×
633

634
            auto serializer_fn = LibraryNodeSerializerRegistry::instance().get_library_node_serializer(code.value());
×
635
            if (serializer_fn == nullptr) {
×
636
                throw std::runtime_error("Unknown library node code: " + std::string(code.value()));
×
637
            }
638
            auto serializer = serializer_fn();
×
639
            auto& lib_node = serializer->deserialize(node, builder, parent);
×
640
            lib_node.implementation_type() =
×
641
                data_flow::ImplementationType(node["implementation_type"].get<std::string>());
×
642
            lib_node.element_id_ = node["element_id"];
×
643
            nodes_map.insert({node["element_id"], lib_node});
×
644
        } else if (type == "access_node") {
12✔
645
            assert(node.contains("data"));
12✔
646
            auto& access_node = builder.add_access(
24✔
647
                parent,
12✔
648
                node["data"],
12✔
649
                builder.subject().debug_info().get_region(json_to_debug_info_region(node["debug_info"], *debug_info_)
24✔
650
                                                              .indices())
12✔
651
            );
652
            access_node.element_id_ = node["element_id"];
12✔
653
            nodes_map.insert({node["element_id"], access_node});
12✔
654
        } else if (type == "constant_node") {
12✔
NEW
655
            assert(node.contains("data"));
×
NEW
656
            assert(node.contains("data_type"));
×
657

NEW
658
            auto type = json_to_type(node["data_type"]);
×
659

NEW
660
            auto& constant_node = builder.add_constant(
×
NEW
661
                parent,
×
NEW
662
                node["data"],
×
NEW
663
                *type,
×
NEW
664
                builder.subject().debug_info().get_region(json_to_debug_info_region(node["debug_info"], *debug_info_)
×
NEW
665
                                                              .indices())
×
666
            );
NEW
667
            constant_node.element_id_ = node["element_id"];
×
NEW
668
            nodes_map.insert({node["element_id"], constant_node});
×
669
        } else {
×
670
            throw std::runtime_error("Unknown node type");
×
671
        }
672
    }
16✔
673

674
    assert(j.contains("edges"));
11✔
675
    assert(j["edges"].is_array());
11✔
676
    for (const auto& edge : j["edges"]) {
23✔
677
        assert(edge.contains("src"));
12✔
678
        assert(edge["src"].is_number_integer());
12✔
679
        assert(edge.contains("dst"));
12✔
680
        assert(edge["dst"].is_number_integer());
12✔
681
        assert(edge.contains("src_conn"));
12✔
682
        assert(edge["src_conn"].is_string());
12✔
683
        assert(edge.contains("dst_conn"));
12✔
684
        assert(edge["dst_conn"].is_string());
12✔
685
        assert(edge.contains("subset"));
12✔
686
        assert(edge["subset"].is_array());
12✔
687

688
        assert(nodes_map.find(edge["src"]) != nodes_map.end());
12✔
689
        assert(nodes_map.find(edge["dst"]) != nodes_map.end());
12✔
690
        auto& source = nodes_map.at(edge["src"]);
12✔
691
        auto& target = nodes_map.at(edge["dst"]);
12✔
692

693
        auto base_type = json_to_type(edge["base_type"]);
12✔
694

695
        assert(edge.contains("subset"));
12✔
696
        assert(edge["subset"].is_array());
12✔
697
        std::vector<symbolic::Expression> subset;
12✔
698
        for (const auto& subset_str : edge["subset"]) {
16✔
699
            assert(subset_str.is_string());
4✔
700
            SymEngine::Expression subset_expr(subset_str);
4✔
701
            subset.push_back(subset_expr);
4✔
702
        }
4✔
703
        auto& memlet = builder.add_memlet(
24✔
704
            parent,
12✔
705
            source,
12✔
706
            edge["src_conn"],
12✔
707
            target,
12✔
708
            edge["dst_conn"],
12✔
709
            subset,
710
            *base_type,
12✔
711
            builder.subject().debug_info().get_region(json_to_debug_info_region(edge["debug_info"], *debug_info_)
24✔
712
                                                          .indices())
12✔
713
        );
714
        memlet.element_id_ = edge["element_id"];
12✔
715
    }
12✔
716
}
11✔
717

718
void JSONSerializer::json_to_sequence(
14✔
719
    const nlohmann::json& j, builder::StructuredSDFGBuilder& builder, structured_control_flow::Sequence& sequence
720
) {
721
    assert(j.contains("type"));
14✔
722
    assert(j["type"].is_string());
14✔
723
    assert(j.contains("children"));
14✔
724
    assert(j["children"].is_array());
14✔
725
    assert(j.contains("transitions"));
14✔
726
    assert(j["transitions"].is_array());
14✔
727
    assert(j["transitions"].size() == j["children"].size());
14✔
728

729
    sequence.element_id_ = j["element_id"];
14✔
730
    sequence.debug_info_ = json_to_debug_info_region(j["debug_info"], *debug_info_);
14✔
731

732
    std::string type = j["type"];
14✔
733
    if (type == "sequence") {
14✔
734
        for (size_t i = 0; i < j["children"].size(); i++) {
25✔
735
            auto& child = j["children"][i];
11✔
736
            auto& transition = j["transitions"][i];
11✔
737
            assert(child.contains("type"));
11✔
738
            assert(child["type"].is_string());
11✔
739

740
            assert(transition.contains("type"));
11✔
741
            assert(transition["type"].is_string());
11✔
742
            assert(transition.contains("assignments"));
11✔
743
            assert(transition["assignments"].is_array());
11✔
744
            control_flow::Assignments assignments;
11✔
745
            for (const auto& assignment : transition["assignments"]) {
13✔
746
                assert(assignment.contains("symbol"));
2✔
747
                assert(assignment["symbol"].is_string());
2✔
748
                assert(assignment.contains("expression"));
2✔
749
                assert(assignment["expression"].is_string());
2✔
750
                SymEngine::Expression expr(assignment["expression"]);
2✔
751
                assignments.insert({symbolic::symbol(assignment["symbol"]), expr});
2✔
752
            }
2✔
753

754
            if (child["type"] == "block") {
11✔
755
                json_to_block_node(child, builder, sequence, assignments);
9✔
756
            } else if (child["type"] == "for") {
11✔
757
                json_to_for_node(child, builder, sequence, assignments);
×
758
            } else if (child["type"] == "if_else") {
2✔
759
                json_to_if_else_node(child, builder, sequence, assignments);
×
760
            } else if (child["type"] == "while") {
2✔
761
                json_to_while_node(child, builder, sequence, assignments);
×
762
            } else if (child["type"] == "break") {
2✔
763
                json_to_break_node(child, builder, sequence, assignments);
1✔
764
            } else if (child["type"] == "continue") {
2✔
765
                json_to_continue_node(child, builder, sequence, assignments);
1✔
766
            } else if (child["type"] == "return") {
1✔
767
                json_to_return_node(child, builder, sequence, assignments);
×
768
            } else if (child["type"] == "map") {
×
769
                json_to_map_node(child, builder, sequence, assignments);
×
770
            } else if (child["type"] == "sequence") {
×
771
                auto& subseq = builder.add_sequence(
×
772
                    sequence,
×
773
                    assignments,
774
                    builder.subject()
×
775
                        .debug_info()
×
776
                        .get_region(json_to_debug_info_region(child["debug_info"], *debug_info_).indices())
×
777
                );
778
                json_to_sequence(child, builder, subseq);
×
779
            } else {
×
780
                throw std::runtime_error("Unknown child type");
×
781
            }
782

783
            sequence.at(i).second.debug_info_ = json_to_debug_info_region(transition["debug_info"], *debug_info_);
11✔
784
            sequence.at(i).second.element_id_ = transition["element_id"];
11✔
785
        }
11✔
786
    } else {
14✔
787
        throw std::runtime_error("expected sequence type");
×
788
    }
789
}
14✔
790

791
void JSONSerializer::json_to_block_node(
10✔
792
    const nlohmann::json& j,
793
    builder::StructuredSDFGBuilder& builder,
794
    structured_control_flow::Sequence& parent,
795
    control_flow::Assignments& assignments
796
) {
797
    assert(j.contains("type"));
10✔
798
    assert(j["type"].is_string());
10✔
799
    assert(j.contains("dataflow"));
10✔
800
    assert(j["dataflow"].is_object());
10✔
801
    auto& block = builder.add_block(
20✔
802
        parent,
10✔
803
        assignments,
10✔
804
        builder.subject().debug_info().get_region(json_to_debug_info_region(j["debug_info"], *debug_info_).indices())
10✔
805
    );
806
    block.element_id_ = j["element_id"];
10✔
807
    assert(j["dataflow"].contains("type"));
10✔
808
    assert(j["dataflow"]["type"].is_string());
10✔
809
    std::string type = j["dataflow"]["type"];
10✔
810
    if (type == "dataflow") {
10✔
811
        json_to_dataflow(j["dataflow"], builder, block);
10✔
812
    } else {
10✔
813
        throw std::runtime_error("Unknown dataflow type");
×
814
    }
815
}
10✔
816

817
void JSONSerializer::json_to_for_node(
1✔
818
    const nlohmann::json& j,
819
    builder::StructuredSDFGBuilder& builder,
820
    structured_control_flow::Sequence& parent,
821
    control_flow::Assignments& assignments
822
) {
823
    assert(j.contains("type"));
1✔
824
    assert(j["type"].is_string());
1✔
825
    assert(j.contains("indvar"));
1✔
826
    assert(j["indvar"].is_string());
1✔
827
    assert(j.contains("init"));
1✔
828
    assert(j["init"].is_string());
1✔
829
    assert(j.contains("condition"));
1✔
830
    assert(j["condition"].is_string());
1✔
831
    assert(j.contains("update"));
1✔
832
    assert(j["update"].is_string());
1✔
833
    assert(j.contains("root"));
1✔
834
    assert(j["root"].is_object());
1✔
835

836
    symbolic::Symbol indvar = symbolic::symbol(j["indvar"]);
1✔
837
    SymEngine::Expression init(j["init"]);
1✔
838
    SymEngine::Expression condition_expr(j["condition"]);
1✔
839
    assert(!SymEngine::rcp_static_cast<const SymEngine::Boolean>(condition_expr.get_basic()).is_null());
1✔
840
    symbolic::Condition condition = SymEngine::rcp_static_cast<const SymEngine::Boolean>(condition_expr.get_basic());
1✔
841
    SymEngine::Expression update(j["update"]);
1✔
842
    auto& for_node = builder.add_for(
2✔
843
        parent,
1✔
844
        indvar,
845
        condition,
846
        init,
1✔
847
        update,
1✔
848
        assignments,
1✔
849
        builder.subject().debug_info().get_region(json_to_debug_info_region(j["debug_info"], *debug_info_).indices())
1✔
850
    );
851
    for_node.element_id_ = j["element_id"];
1✔
852

853
    assert(j["root"].contains("type"));
1✔
854
    assert(j["root"]["type"].is_string());
1✔
855
    assert(j["root"]["type"] == "sequence");
1✔
856
    json_to_sequence(j["root"], builder, for_node.root());
1✔
857
}
1✔
858

859
void JSONSerializer::json_to_if_else_node(
1✔
860
    const nlohmann::json& j,
861
    builder::StructuredSDFGBuilder& builder,
862
    structured_control_flow::Sequence& parent,
863
    control_flow::Assignments& assignments
864
) {
865
    assert(j.contains("type"));
1✔
866
    assert(j["type"].is_string());
1✔
867
    assert(j["type"] == "if_else");
1✔
868
    assert(j.contains("branches"));
1✔
869
    assert(j["branches"].is_array());
1✔
870
    auto& if_else_node = builder.add_if_else(
2✔
871
        parent,
1✔
872
        assignments,
1✔
873
        builder.subject().debug_info().get_region(json_to_debug_info_region(j["debug_info"], *debug_info_).indices())
1✔
874
    );
875
    if_else_node.element_id_ = j["element_id"];
1✔
876
    for (const auto& branch : j["branches"]) {
3✔
877
        assert(branch.contains("condition"));
2✔
878
        assert(branch["condition"].is_string());
2✔
879
        assert(branch.contains("root"));
2✔
880
        assert(branch["root"].is_object());
2✔
881
        SymEngine::Expression condition_expr(branch["condition"]);
2✔
882
        assert(!SymEngine::rcp_static_cast<const SymEngine::Boolean>(condition_expr.get_basic()).is_null());
2✔
883
        symbolic::Condition condition = SymEngine::rcp_static_cast<const SymEngine::Boolean>(condition_expr.get_basic()
2✔
884
        );
885
        auto& branch_node = builder.add_case(if_else_node, condition);
2✔
886
        assert(branch["root"].contains("type"));
2✔
887
        assert(branch["root"]["type"].is_string());
2✔
888
        std::string type = branch["root"]["type"];
2✔
889
        if (type == "sequence") {
2✔
890
            json_to_sequence(branch["root"], builder, branch_node);
2✔
891
        } else {
2✔
892
            throw std::runtime_error("Unknown child type");
×
893
        }
894
    }
2✔
895
}
1✔
896

897
void JSONSerializer::json_to_while_node(
3✔
898
    const nlohmann::json& j,
899
    builder::StructuredSDFGBuilder& builder,
900
    structured_control_flow::Sequence& parent,
901
    control_flow::Assignments& assignments
902
) {
903
    assert(j.contains("type"));
3✔
904
    assert(j["type"].is_string());
3✔
905
    assert(j["type"] == "while");
3✔
906
    assert(j.contains("root"));
3✔
907
    assert(j["root"].is_object());
3✔
908

909
    auto& while_node = builder.add_while(
6✔
910
        parent,
3✔
911
        assignments,
3✔
912
        builder.subject().debug_info().get_region(json_to_debug_info_region(j["debug_info"], *debug_info_).indices())
3✔
913
    );
914
    while_node.element_id_ = j["element_id"];
3✔
915

916
    assert(j["root"]["type"] == "sequence");
3✔
917
    json_to_sequence(j["root"], builder, while_node.root());
3✔
918
}
3✔
919

920
void JSONSerializer::json_to_break_node(
1✔
921
    const nlohmann::json& j,
922
    builder::StructuredSDFGBuilder& builder,
923
    structured_control_flow::Sequence& parent,
924
    control_flow::Assignments& assignments
925
) {
926
    assert(j.contains("type"));
1✔
927
    assert(j["type"].is_string());
1✔
928
    assert(j["type"] == "break");
1✔
929
    auto& node = builder.add_break(
2✔
930
        parent,
1✔
931
        assignments,
1✔
932
        builder.subject().debug_info().get_region(json_to_debug_info_region(j["debug_info"], *debug_info_).indices())
1✔
933
    );
934
    node.element_id_ = j["element_id"];
1✔
935
}
1✔
936

937
void JSONSerializer::json_to_continue_node(
1✔
938
    const nlohmann::json& j,
939
    builder::StructuredSDFGBuilder& builder,
940
    structured_control_flow::Sequence& parent,
941
    control_flow::Assignments& assignments
942
) {
943
    assert(j.contains("type"));
1✔
944
    assert(j["type"].is_string());
1✔
945
    assert(j["type"] == "continue");
1✔
946
    auto& node = builder.add_continue(
2✔
947
        parent,
1✔
948
        assignments,
1✔
949
        builder.subject().debug_info().get_region(json_to_debug_info_region(j["debug_info"], *debug_info_).indices())
1✔
950
    );
951
    node.element_id_ = j["element_id"];
1✔
952
}
1✔
953

954
void JSONSerializer::json_to_map_node(
1✔
955
    const nlohmann::json& j,
956
    builder::StructuredSDFGBuilder& builder,
957
    structured_control_flow::Sequence& parent,
958
    control_flow::Assignments& assignments
959
) {
960
    assert(j.contains("type"));
1✔
961
    assert(j["type"].is_string());
1✔
962
    assert(j["type"] == "map");
1✔
963
    assert(j.contains("indvar"));
1✔
964
    assert(j["indvar"].is_string());
1✔
965
    assert(j.contains("init"));
1✔
966
    assert(j["init"].is_string());
1✔
967
    assert(j.contains("condition"));
1✔
968
    assert(j["condition"].is_string());
1✔
969
    assert(j.contains("update"));
1✔
970
    assert(j["update"].is_string());
1✔
971
    assert(j.contains("root"));
1✔
972
    assert(j["root"].is_object());
1✔
973
    assert(j.contains("schedule_type"));
1✔
974
    assert(j["schedule_type"].is_object());
1✔
975

976
    structured_control_flow::ScheduleType schedule_type = json_to_schedule_type(j["schedule_type"]);
1✔
977

978
    symbolic::Symbol indvar = symbolic::symbol(j["indvar"]);
1✔
979
    SymEngine::Expression init(j["init"]);
1✔
980
    SymEngine::Expression condition_expr(j["condition"]);
1✔
981
    assert(!SymEngine::rcp_static_cast<const SymEngine::Boolean>(condition_expr.get_basic()).is_null());
1✔
982
    symbolic::Condition condition = SymEngine::rcp_static_cast<const SymEngine::Boolean>(condition_expr.get_basic());
1✔
983
    SymEngine::Expression update(j["update"]);
1✔
984

985
    auto& map_node = builder.add_map(
2✔
986
        parent,
1✔
987
        indvar,
988
        condition,
989
        init,
1✔
990
        update,
1✔
991
        schedule_type,
992
        assignments,
1✔
993
        builder.subject().debug_info().get_region(json_to_debug_info_region(j["debug_info"], *debug_info_).indices())
1✔
994
    );
995
    map_node.element_id_ = j["element_id"];
1✔
996

997
    assert(j["root"].contains("type"));
1✔
998
    assert(j["root"]["type"].is_string());
1✔
999
    assert(j["root"]["type"] == "sequence");
1✔
1000
    json_to_sequence(j["root"], builder, map_node.root());
1✔
1001
}
1✔
1002

1003
void JSONSerializer::json_to_return_node(
1✔
1004
    const nlohmann::json& j,
1005
    builder::StructuredSDFGBuilder& builder,
1006
    structured_control_flow::Sequence& parent,
1007
    control_flow::Assignments& assignments
1008
) {
1009
    assert(j.contains("type"));
1✔
1010
    assert(j["type"].is_string());
1✔
1011
    assert(j["type"] == "return");
1✔
1012
    assert(j.contains("data"));
1✔
1013
    assert(j["data"].is_string());
1✔
1014
    assert(j.contains("unreachable"));
1✔
1015
    assert(j["unreachable"].is_boolean());
1✔
1016

1017
    std::string data = j["data"];
1✔
1018
    bool unreachable = j["unreachable"];
1✔
1019
    auto& node = builder.add_return(
2✔
1020
        parent,
1✔
1021
        data,
1022
        unreachable,
1✔
1023
        assignments,
1✔
1024
        builder.subject().debug_info().get_region(json_to_debug_info_region(j["debug_info"], *debug_info_).indices())
1✔
1025
    );
1026
    node.element_id_ = j["element_id"];
1✔
1027
}
1✔
1028

1029
std::unique_ptr<types::IType> JSONSerializer::json_to_type(const nlohmann::json& j) {
46✔
1030
    if (j.contains("type")) {
46✔
1031
        if (j["type"] == "scalar") {
46✔
1032
            // Deserialize scalar type
1033
            assert(j.contains("primitive_type"));
35✔
1034
            types::PrimitiveType primitive_type = j["primitive_type"];
35✔
1035
            assert(j.contains("storage_type"));
35✔
1036
            types::StorageType storage_type = storage_type_from_string(j["storage_type"].get<std::string>());
35✔
1037
            assert(j.contains("initializer"));
35✔
1038
            std::string initializer = j["initializer"];
35✔
1039
            assert(j.contains("alignment"));
35✔
1040
            size_t alignment = j["alignment"];
35✔
1041
            return std::make_unique<types::Scalar>(storage_type, alignment, initializer, primitive_type);
35✔
1042
        } else if (j["type"] == "array") {
46✔
1043
            // Deserialize array type
1044
            assert(j.contains("element_type"));
2✔
1045
            std::unique_ptr<types::IType> member_type = json_to_type(j["element_type"]);
2✔
1046
            assert(j.contains("num_elements"));
2✔
1047
            std::string num_elements_str = j["num_elements"];
2✔
1048
            // Convert num_elements_str to symbolic::Expression
1049
            SymEngine::Expression num_elements(num_elements_str);
2✔
1050
            assert(j.contains("storage_type"));
2✔
1051
            types::StorageType storage_type = storage_type_from_string(j["storage_type"].get<std::string>());
2✔
1052
            assert(j.contains("initializer"));
2✔
1053
            std::string initializer = j["initializer"];
2✔
1054
            assert(j.contains("alignment"));
2✔
1055
            size_t alignment = j["alignment"];
2✔
1056
            return std::make_unique<types::Array>(storage_type, alignment, initializer, *member_type, num_elements);
2✔
1057
        } else if (j["type"] == "pointer") {
11✔
1058
            // Deserialize pointer type
1059
            std::optional<std::unique_ptr<types::IType>> pointee_type;
6✔
1060
            if (j.contains("pointee_type")) {
6✔
1061
                assert(j.contains("pointee_type"));
5✔
1062
                pointee_type = json_to_type(j["pointee_type"]);
5✔
1063
            } else {
5✔
1064
                pointee_type = std::nullopt;
1✔
1065
            }
1066
            assert(j.contains("storage_type"));
6✔
1067
            types::StorageType storage_type = storage_type_from_string(j["storage_type"].get<std::string>());
6✔
1068
            assert(j.contains("initializer"));
6✔
1069
            std::string initializer = j["initializer"];
6✔
1070
            assert(j.contains("alignment"));
6✔
1071
            size_t alignment = j["alignment"];
6✔
1072
            if (pointee_type.has_value()) {
6✔
1073
                return std::make_unique<types::Pointer>(storage_type, alignment, initializer, *pointee_type.value());
5✔
1074
            } else {
1075
                return std::make_unique<types::Pointer>(storage_type, alignment, initializer);
1✔
1076
            }
1077
        } else if (j["type"] == "structure") {
9✔
1078
            // Deserialize structure type
1079
            assert(j.contains("name"));
2✔
1080
            std::string name = j["name"];
2✔
1081
            assert(j.contains("storage_type"));
2✔
1082
            types::StorageType storage_type = storage_type_from_string(j["storage_type"].get<std::string>());
2✔
1083
            assert(j.contains("initializer"));
2✔
1084
            std::string initializer = j["initializer"];
2✔
1085
            assert(j.contains("alignment"));
2✔
1086
            size_t alignment = j["alignment"];
2✔
1087
            return std::make_unique<types::Structure>(storage_type, alignment, initializer, name);
2✔
1088
        } else if (j["type"] == "function") {
3✔
1089
            // Deserialize function type
1090
            assert(j.contains("return_type"));
1✔
1091
            std::unique_ptr<types::IType> return_type = json_to_type(j["return_type"]);
1✔
1092
            assert(j.contains("params"));
1✔
1093
            std::vector<std::unique_ptr<types::IType>> params;
1✔
1094
            for (const auto& param : j["params"]) {
3✔
1095
                params.push_back(json_to_type(param));
2✔
1096
            }
1097
            assert(j.contains("is_var_arg"));
1✔
1098
            bool is_var_arg = j["is_var_arg"];
1✔
1099
            assert(j.contains("storage_type"));
1✔
1100
            types::StorageType storage_type = storage_type_from_string(j["storage_type"].get<std::string>());
1✔
1101
            assert(j.contains("initializer"));
1✔
1102
            std::string initializer = j["initializer"];
1✔
1103
            assert(j.contains("alignment"));
1✔
1104
            size_t alignment = j["alignment"];
1✔
1105
            auto function =
1106
                std::make_unique<types::Function>(storage_type, alignment, initializer, *return_type, is_var_arg);
1✔
1107
            for (const auto& param : params) {
3✔
1108
                function->add_param(*param);
2✔
1109
            }
1110
            return function->clone();
1✔
1111

1112
        } else {
1✔
1113
            throw std::runtime_error("Unknown type");
×
1114
        }
1115
    } else {
1116
        throw std::runtime_error("Type not found");
×
1117
    }
1118
}
46✔
1119

1120
DebugLoc JSONSerializer::json_to_debug_loc(const nlohmann::json& j) {
7✔
1121
    assert(j.contains("has"));
7✔
1122
    assert(j["has"].is_boolean());
7✔
1123
    if (!j["has"]) {
7✔
1124
        return DebugLoc();
×
1125
    }
1126
    assert(j.contains("filename"));
7✔
1127
    assert(j["filename"].is_string());
7✔
1128
    std::string filename = j["filename"];
7✔
1129
    assert(j.contains("function"));
7✔
1130
    assert(j["function"].is_string());
7✔
1131
    std::string function = j["function"];
7✔
1132
    assert(j.contains("line"));
7✔
1133
    assert(j["line"].is_number_integer());
7✔
1134
    size_t line = j["line"];
7✔
1135
    assert(j.contains("column"));
7✔
1136
    assert(j["column"].is_number_integer());
7✔
1137
    size_t column = j["column"];
7✔
1138
    return DebugLoc(filename, function, line, column, true);
7✔
1139
}
7✔
1140

1141
DebugInfo JSONSerializer::json_to_debug_info_element(const nlohmann::json& j) {
3✔
1142
    assert(j.contains("has"));
3✔
1143
    assert(j["has"].is_boolean());
3✔
1144
    if (!j["has"]) {
3✔
1145
        return DebugInfo();
×
1146
    }
1147
    assert(j.contains("locations"));
3✔
1148
    assert(j["locations"].is_array());
3✔
1149
    std::vector<DebugLoc> locations;
3✔
1150
    for (const auto& loc_json : j["locations"]) {
9✔
1151
        locations.push_back(json_to_debug_loc(loc_json));
6✔
1152
    }
1153
    return DebugInfo(locations);
3✔
1154
}
3✔
1155

1156
DebugInfoRegion JSONSerializer::json_to_debug_info_region(const nlohmann::json& j, const DebugTable& debug_info) {
74✔
1157
    assert(j.contains("has"));
74✔
1158
    assert(j["has"].is_boolean());
74✔
1159
    if (!j["has"]) {
74✔
1160
        return DebugInfoRegion();
72✔
1161
    }
1162

1163
    assert(j.contains("indices"));
2✔
1164
    assert(j["indices"].is_array());
2✔
1165
    std::unordered_set<size_t> indices;
2✔
1166
    for (auto index_json : j["indices"]) {
6✔
1167
        size_t index = index_json;
4✔
1168
        indices.insert(index);
4✔
1169
    }
4✔
1170
    DebugInfoRegion debug_info_region(indices, debug_info.elements());
2✔
1171
    assert(j.contains("filename"));
2✔
1172
    assert(j["filename"].is_string());
2✔
1173
    std::string filename = j["filename"];
2✔
1174
    assert(filename == debug_info_region.filename());
2✔
1175

1176
    assert(j.contains("function"));
2✔
1177
    assert(j["function"].is_string());
2✔
1178
    std::string function = j["function"];
2✔
1179
    assert(function == debug_info_region.function());
2✔
1180

1181
    assert(j.contains("start_line"));
2✔
1182
    assert(j["start_line"].is_number_integer());
2✔
1183
    size_t start_line = j["start_line"];
2✔
1184
    assert(start_line == debug_info_region.start_line());
2✔
1185

1186
    assert(j.contains("start_column"));
2✔
1187
    assert(j["start_column"].is_number_integer());
2✔
1188
    size_t start_column = j["start_column"];
2✔
1189
    assert(start_column == debug_info_region.start_column());
2✔
1190

1191
    assert(j.contains("end_line"));
2✔
1192
    assert(j["end_line"].is_number_integer());
2✔
1193
    size_t end_line = j["end_line"];
2✔
1194
    assert(end_line == debug_info_region.end_line());
2✔
1195

1196
    assert(j.contains("end_column"));
2✔
1197
    assert(j["end_column"].is_number_integer());
2✔
1198
    size_t end_column = j["end_column"];
2✔
1199
    assert(end_column == debug_info_region.end_column());
2✔
1200

1201
    return debug_info_region;
2✔
1202
}
74✔
1203

1204
DebugTable JSONSerializer::json_to_debug_table(const nlohmann::json& j) {
6✔
1205
    assert(j.contains("elements"));
6✔
1206
    assert(j["elements"].is_array());
6✔
1207
    DebugTable debug_info;
6✔
1208
    DebugInfos elements;
6✔
1209
    for (const auto& entry_json : j["elements"]) {
8✔
1210
        debug_info.add_element(json_to_debug_info_element(entry_json));
2✔
1211
    }
1212
    return debug_info;
6✔
1213
}
6✔
1214

1215
ScheduleType JSONSerializer::json_to_schedule_type(const nlohmann::json& j) {
2✔
1216
    assert(j.contains("value"));
2✔
1217
    assert(j["value"].is_string());
2✔
1218
    assert(j.contains("properties"));
2✔
1219
    assert(j["properties"].is_object());
2✔
1220
    ScheduleType schedule_type(j["value"].get<std::string>());
2✔
1221
    for (const auto& [key, value] : j["properties"].items()) {
4✔
1222
        assert(value.is_string());
1✔
1223
        schedule_type.set_property(key, value.get<std::string>());
1✔
1224
    }
1225
    return schedule_type;
2✔
1226
}
2✔
1227

1228
std::string JSONSerializer::expression(const symbolic::Expression& expr) {
36✔
1229
    JSONSymbolicPrinter printer;
36✔
1230
    return printer.apply(expr);
36✔
1231
};
36✔
1232

1233
void JSONSymbolicPrinter::bvisit(const SymEngine::Equality& x) {
×
1234
    str_ = apply(x.get_args()[0]) + " == " + apply(x.get_args()[1]);
×
1235
    str_ = parenthesize(str_);
×
1236
};
×
1237

1238
void JSONSymbolicPrinter::bvisit(const SymEngine::Unequality& x) {
×
1239
    str_ = apply(x.get_args()[0]) + " != " + apply(x.get_args()[1]);
×
1240
    str_ = parenthesize(str_);
×
1241
};
×
1242

1243
void JSONSymbolicPrinter::bvisit(const SymEngine::LessThan& x) {
×
1244
    str_ = apply(x.get_args()[0]) + " <= " + apply(x.get_args()[1]);
×
1245
    str_ = parenthesize(str_);
×
1246
};
×
1247

1248
void JSONSymbolicPrinter::bvisit(const SymEngine::StrictLessThan& x) {
4✔
1249
    str_ = apply(x.get_args()[0]) + " < " + apply(x.get_args()[1]);
4✔
1250
    str_ = parenthesize(str_);
4✔
1251
};
4✔
1252

1253
void JSONSymbolicPrinter::bvisit(const SymEngine::Min& x) {
×
1254
    std::ostringstream s;
×
1255
    auto container = x.get_args();
×
1256
    if (container.size() == 1) {
×
1257
        s << apply(*container.begin());
×
1258
    } else {
×
1259
        s << "min(";
×
1260
        s << apply(*container.begin());
×
1261

1262
        // Recursively apply __daisy_min to the arguments
1263
        SymEngine::vec_basic subargs;
×
1264
        for (auto it = ++(container.begin()); it != container.end(); ++it) {
×
1265
            subargs.push_back(*it);
×
1266
        }
×
1267
        auto submin = SymEngine::min(subargs);
×
1268
        s << ", " << apply(submin);
×
1269

1270
        s << ")";
×
1271
    }
×
1272

1273
    str_ = s.str();
×
1274
};
×
1275

1276
void JSONSymbolicPrinter::bvisit(const SymEngine::Max& x) {
×
1277
    std::ostringstream s;
×
1278
    auto container = x.get_args();
×
1279
    if (container.size() == 1) {
×
1280
        s << apply(*container.begin());
×
1281
    } else {
×
1282
        s << "max(";
×
1283
        s << apply(*container.begin());
×
1284

1285
        // Recursively apply __daisy_max to the arguments
1286
        SymEngine::vec_basic subargs;
×
1287
        for (auto it = ++(container.begin()); it != container.end(); ++it) {
×
1288
            subargs.push_back(*it);
×
1289
        }
×
1290
        auto submax = SymEngine::max(subargs);
×
1291
        s << ", " << apply(submax);
×
1292

1293
        s << ")";
×
1294
    }
×
1295

1296
    str_ = s.str();
×
1297
};
×
1298

1299
void LibraryNodeSerializerRegistry::
1300
    register_library_node_serializer(std::string library_node_code, LibraryNodeSerializerFn fn) {
34✔
1301
    std::lock_guard<std::mutex> lock(mutex_);
34✔
1302
    if (factory_map_.find(library_node_code) != factory_map_.end()) {
34✔
1303
        throw std::runtime_error(
×
1304
            "Library node serializer already registered for library node code: " + std::string(library_node_code)
×
1305
        );
1306
    }
1307
    factory_map_[library_node_code] = std::move(fn);
34✔
1308
}
34✔
1309

1310
LibraryNodeSerializerFn LibraryNodeSerializerRegistry::get_library_node_serializer(std::string library_node_code) {
1✔
1311
    auto it = factory_map_.find(library_node_code);
1✔
1312
    if (it != factory_map_.end()) {
1✔
1313
        return it->second;
1✔
1314
    }
1315
    return nullptr;
×
1316
}
1✔
1317

1318
size_t LibraryNodeSerializerRegistry::size() const { return factory_map_.size(); }
×
1319

1320
void register_default_serializers() {
2✔
1321
    // stdlib
1322
    LibraryNodeSerializerRegistry::instance()
2✔
1323
        .register_library_node_serializer(stdlib::LibraryNodeType_Alloca.value(), []() {
2✔
NEW
1324
            return std::make_unique<stdlib::AllocaNodeSerializer>();
×
1325
        });
1326
    LibraryNodeSerializerRegistry::instance()
2✔
1327
        .register_library_node_serializer(stdlib::LibraryNodeType_Calloc.value(), []() {
2✔
NEW
1328
            return std::make_unique<stdlib::CallocNodeSerializer>();
×
1329
        });
1330
    LibraryNodeSerializerRegistry::instance()
2✔
1331
        .register_library_node_serializer(stdlib::LibraryNodeType_Fprintf.value(), []() {
2✔
NEW
1332
            return std::make_unique<stdlib::FprintfNodeSerializer>();
×
1333
        });
1334
    LibraryNodeSerializerRegistry::instance()
2✔
1335
        .register_library_node_serializer(stdlib::LibraryNodeType_Fputc.value(), []() {
2✔
NEW
1336
            return std::make_unique<stdlib::FputcNodeSerializer>();
×
1337
        });
1338
    LibraryNodeSerializerRegistry::instance()
2✔
1339
        .register_library_node_serializer(stdlib::LibraryNodeType_Free.value(), []() {
2✔
NEW
1340
            return std::make_unique<stdlib::FreeNodeSerializer>();
×
1341
        });
1342
    LibraryNodeSerializerRegistry::instance()
2✔
1343
        .register_library_node_serializer(stdlib::LibraryNodeType_FWrite.value(), []() {
2✔
NEW
1344
            return std::make_unique<stdlib::FWriteNodeSerializer>();
×
1345
        });
1346
    LibraryNodeSerializerRegistry::instance()
2✔
1347
        .register_library_node_serializer(stdlib::LibraryNodeType_Malloc.value(), []() {
2✔
NEW
1348
            return std::make_unique<stdlib::MallocNodeSerializer>();
×
1349
        });
1350
    LibraryNodeSerializerRegistry::instance()
2✔
1351
        .register_library_node_serializer(stdlib::LibraryNodeType_Memcpy.value(), []() {
2✔
NEW
1352
            return std::make_unique<stdlib::MemcpyNodeSerializer>();
×
1353
        });
1354
    LibraryNodeSerializerRegistry::instance()
2✔
1355
        .register_library_node_serializer(stdlib::LibraryNodeType_Memmove.value(), []() {
2✔
NEW
1356
            return std::make_unique<stdlib::MemmoveNodeSerializer>();
×
1357
        });
1358
    LibraryNodeSerializerRegistry::instance()
2✔
1359
        .register_library_node_serializer(stdlib::LibraryNodeType_Memset.value(), []() {
2✔
NEW
1360
            return std::make_unique<stdlib::MemsetNodeSerializer>();
×
1361
        });
1362
    LibraryNodeSerializerRegistry::instance()
2✔
1363
        .register_library_node_serializer(stdlib::LibraryNodeType_Rand.value(), []() {
2✔
NEW
1364
            return std::make_unique<stdlib::RandNodeSerializer>();
×
1365
        });
1366
    LibraryNodeSerializerRegistry::instance()
2✔
1367
        .register_library_node_serializer(stdlib::LibraryNodeType_Srand.value(), []() {
2✔
NEW
1368
            return std::make_unique<stdlib::SrandNodeSerializer>();
×
1369
        });
1370

1371
    // Metadata
1372
    LibraryNodeSerializerRegistry::instance()
2✔
1373
        .register_library_node_serializer(data_flow::LibraryNodeType_Metadata.value(), []() {
2✔
NEW
1374
            return std::make_unique<data_flow::MetadataNodeSerializer>();
×
1375
        });
1376

1377
    // Barrier
1378
    LibraryNodeSerializerRegistry::instance()
2✔
1379
        .register_library_node_serializer(data_flow::LibraryNodeType_BarrierLocal.value(), []() {
3✔
1380
            return std::make_unique<data_flow::BarrierLocalNodeSerializer>();
1✔
1381
        });
1382

1383
    // Barrier
1384
    LibraryNodeSerializerRegistry::instance()
2✔
1385
        .register_library_node_serializer(data_flow::LibraryNodeType_Call.value(), []() {
2✔
NEW
1386
            return std::make_unique<data_flow::CallNodeSerializer>();
×
1387
        });
1388

1389
    // ML
1390
    // LibraryNodeSerializerRegistry::instance()
1391
    //     .register_library_node_serializer(math::ml::LibraryNodeType_Abs.value(), []() {
1392
    //         return std::make_unique<math::ml::AbsNodeSerializer>();
1393
    //     });
1394
    // LibraryNodeSerializerRegistry::instance()
1395
    //     .register_library_node_serializer(math::ml::LibraryNodeType_Add.value(), []() {
1396
    //         return std::make_unique<math::ml::AddNodeSerializer>();
1397
    //     });
1398
    // LibraryNodeSerializerRegistry::instance()
1399
    //     .register_library_node_serializer(math::ml::LibraryNodeType_BatchNormalization.value(), []() {
1400
    //         return std::make_unique<math::ml::BatchNormalizationNodeSerializer>();
1401
    //     });
1402
    // LibraryNodeSerializerRegistry::instance()
1403
    //     .register_library_node_serializer(math::ml::LibraryNodeType_Clip.value(), []() {
1404
    //         return std::make_unique<math::ml::ClipNodeSerializer>();
1405
    //     });
1406
    // LibraryNodeSerializerRegistry::instance()
1407
    //     .register_library_node_serializer(math::ml::LibraryNodeType_Conv.value(), []() {
1408
    //         return std::make_unique<math::ml::ConvNodeSerializer>();
1409
    //     });
1410
    // LibraryNodeSerializerRegistry::instance()
1411
    //     .register_library_node_serializer(math::ml::LibraryNodeType_Div.value(), []() {
1412
    //         return std::make_unique<math::ml::DivNodeSerializer>();
1413
    //     });
1414
    // LibraryNodeSerializerRegistry::instance()
1415
    //     .register_library_node_serializer(math::ml::LibraryNodeType_Dropout.value(), []() {
1416
    //         return std::make_unique<math::ml::DropoutSerializer>();
1417
    //     });
1418
    // LibraryNodeSerializerRegistry::instance()
1419
    //     .register_library_node_serializer(math::ml::LibraryNodeType_Elu.value(), []() {
1420
    //         return std::make_unique<math::ml::EluNodeSerializer>();
1421
    //     });
1422
    // LibraryNodeSerializerRegistry::instance()
1423
    //     .register_library_node_serializer(math::ml::LibraryNodeType_Erf.value(), []() {
1424
    //         return std::make_unique<math::ml::ErfNodeSerializer>();
1425
    //     });
1426
    // LibraryNodeSerializerRegistry::instance()
1427
    //     .register_library_node_serializer(math::ml::LibraryNodeType_Gemm.value(), []() {
1428
    //         return std::make_unique<math::ml::GemmNodeSerializer>();
1429
    //     });
1430
    // LibraryNodeSerializerRegistry::instance()
1431
    //     .register_library_node_serializer(math::ml::LibraryNodeType_HardSigmoid.value(), []() {
1432
    //         return std::make_unique<math::ml::HardSigmoidNodeSerializer>();
1433
    //     });
1434
    // LibraryNodeSerializerRegistry::instance()
1435
    //     .register_library_node_serializer(math::ml::LibraryNodeType_LayerNormalization.value(), []() {
1436
    //         return std::make_unique<math::ml::LayerNormalizationNodeSerializer>();
1437
    //     });
1438
    // LibraryNodeSerializerRegistry::instance()
1439
    //     .register_library_node_serializer(math::ml::LibraryNodeType_LeakyReLU.value(), []() {
1440
    //         return std::make_unique<math::ml::LeakyReLUNodeSerializer>();
1441
    //     });
1442
    // LibraryNodeSerializerRegistry::instance()
1443
    //     .register_library_node_serializer(math::ml::LibraryNodeType_LogSoftmax.value(), []() {
1444
    //         return std::make_unique<math::ml::LogSoftmaxNodeSerializer>();
1445
    //     });
1446
    // LibraryNodeSerializerRegistry::instance()
1447
    //     .register_library_node_serializer(math::ml::LibraryNodeType_MatMul.value(), []() {
1448
    //         return std::make_unique<math::ml::MatMulNodeSerializer>();
1449
    //     });
1450
    // LibraryNodeSerializerRegistry::instance()
1451
    //     .register_library_node_serializer(math::ml::LibraryNodeType_MaxPool.value(), []() {
1452
    //         return std::make_unique<math::ml::MaxPoolNodeSerializer>();
1453
    //     });
1454
    // LibraryNodeSerializerRegistry::instance()
1455
    //     .register_library_node_serializer(math::ml::LibraryNodeType_Mul.value(), []() {
1456
    //         return std::make_unique<math::ml::MulNodeSerializer>();
1457
    //     });
1458
    // LibraryNodeSerializerRegistry::instance()
1459
    //     .register_library_node_serializer(math::ml::LibraryNodeType_Pow.value(), []() {
1460
    //         return std::make_unique<math::ml::PowNodeSerializer>();
1461
    //     });
1462
    // LibraryNodeSerializerRegistry::instance()
1463
    //     .register_library_node_serializer(math::ml::LibraryNodeType_ReduceMean.value(), []() {
1464
    //         return std::make_unique<math::ml::ReduceMeanNodeSerializer>();
1465
    //     });
1466
    // LibraryNodeSerializerRegistry::instance()
1467
    //     .register_library_node_serializer(math::ml::LibraryNodeType_ReLU.value(), []() {
1468
    //         return std::make_unique<math::ml::ReLUNodeSerializer>();
1469
    //     });
1470
    // LibraryNodeSerializerRegistry::instance()
1471
    //     .register_library_node_serializer(math::ml::LibraryNodeType_Sigmoid.value(), []() {
1472
    //         return std::make_unique<math::ml::SigmoidNodeSerializer>();
1473
    //     });
1474
    // LibraryNodeSerializerRegistry::instance()
1475
    //     .register_library_node_serializer(math::ml::LibraryNodeType_Softmax.value(), []() {
1476
    //         return std::make_unique<math::ml::SoftmaxNodeSerializer>();
1477
    //     });
1478
    // LibraryNodeSerializerRegistry::instance()
1479
    //     .register_library_node_serializer(math::ml::LibraryNodeType_Sqrt.value(), []() {
1480
    //         return std::make_unique<math::ml::SqrtNodeSerializer>();
1481
    //     });
1482
    // LibraryNodeSerializerRegistry::instance()
1483
    //     .register_library_node_serializer(math::ml::LibraryNodeType_Sub.value(), []() {
1484
    //         return std::make_unique<math::ml::SubNodeSerializer>();
1485
    //     });
1486
    // LibraryNodeSerializerRegistry::instance()
1487
    //     .register_library_node_serializer(math::ml::LibraryNodeType_Tanh.value(), []() {
1488
    //         return std::make_unique<math::ml::TanhNodeSerializer>();
1489
    //     });
1490

1491
    // BLAS
1492
    LibraryNodeSerializerRegistry::instance()
2✔
1493
        .register_library_node_serializer(math::blas::LibraryNodeType_DOT.value(), []() {
2✔
1494
            return std::make_unique<math::blas::DotNodeSerializer>();
×
1495
        });
1496
    LibraryNodeSerializerRegistry::instance()
2✔
1497
        .register_library_node_serializer(math::blas::LibraryNodeType_GEMM.value(), []() {
2✔
1498
            return std::make_unique<math::blas::GEMMNodeSerializer>();
×
1499
        });
1500
}
2✔
1501

1502
} // namespace serializer
1503
} // 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