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

daisytuner / sdfglib / 17697650771

13 Sep 2025 02:09PM UTC coverage: 60.533% (+1.2%) from 59.335%
17697650771

Pull #219

github

web-flow
Merge 0edf508a7 into 6c1992b40
Pull Request #219: stdlib Library Nodes and ConstantNodes

563 of 1790 new or added lines in 102 files covered. (31.45%)

102 existing lines in 38 files now uncovered.

9442 of 15598 relevant lines covered (60.53%)

107.06 hits per line

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

0.0
/src/data_flow/library_nodes/call_node.cpp
1
#include "sdfg/data_flow/library_nodes/call_node.h"
2

3
namespace sdfg {
4
namespace data_flow {
5

NEW
6
CallNode::CallNode(
×
7
    size_t element_id,
8
    const DebugInfo& debug_info,
9
    const graph::Vertex vertex,
10
    data_flow::DataFlowGraph& parent,
11
    const std::string& function_name,
12
    const std::vector<std::string>& outputs,
13
    const std::vector<std::string>& inputs
14
)
NEW
15
    : LibraryNode(
×
NEW
16
          element_id,
×
NEW
17
          debug_info,
×
NEW
18
          vertex,
×
NEW
19
          parent,
×
20
          LibraryNodeType_Call,
NEW
21
          outputs,
×
NEW
22
          inputs,
×
23
          true,
24
          data_flow::ImplementationType_NONE
25
      ),
NEW
26
      function_name_(function_name) {}
×
27

NEW
28
const std::string& CallNode::function_name() const { return this->function_name_; }
×
29

NEW
30
const types::Function& CallNode::function_type(const Function& sdfg) const {
×
31
    // function_name is a symbol referring to a global variable of type Function
NEW
32
    return dynamic_cast<const types::Function&>(sdfg.type(this->function_name_));
×
33
}
34

NEW
35
bool CallNode::is_void(const Function& sdfg) const {
×
NEW
36
    auto& func_type = this->function_type(sdfg);
×
NEW
37
    if (func_type.return_type().type_id() == types::TypeID::Scalar) {
×
NEW
38
        auto& ret_type = static_cast<const types::Scalar&>(func_type.return_type());
×
NEW
39
        if (ret_type.primitive_type() == types::PrimitiveType::Void) {
×
NEW
40
            return true;
×
41
        }
NEW
42
    }
×
NEW
43
    return false;
×
NEW
44
}
×
45

NEW
46
void CallNode::validate(const Function& function) const {
×
NEW
47
    if (!function.exists(this->function_name_)) {
×
NEW
48
        throw InvalidSDFGException("CallNode: Function '" + this->function_name_ + "' does not exist.");
×
49
    }
NEW
50
    auto& type = function.type(this->function_name_);
×
NEW
51
    if (!dynamic_cast<const types::Function*>(&type)) {
×
NEW
52
        throw InvalidSDFGException("CallNode: '" + this->function_name_ + "' is not a function.");
×
53
    }
NEW
54
    auto& func_type = static_cast<const types::Function&>(type);
×
55

NEW
56
    if (inputs_.size() != func_type.num_params()) {
×
NEW
57
        throw InvalidSDFGException(
×
NEW
58
            "CallNode: Number of inputs does not match number of function parameters. Expected " +
×
NEW
59
            std::to_string(func_type.num_params()) + ", got " + std::to_string(inputs_.size())
×
60
        );
61
    }
NEW
62
    if (!this->is_void(function) && outputs_.size() < 1) {
×
NEW
63
        throw InvalidSDFGException(
×
NEW
64
            "CallNode: Non-void function must have at least one output to store the return value."
×
65
        );
66
    }
NEW
67
}
×
68

NEW
69
symbolic::SymbolSet CallNode::symbols() const { return {}; }
×
70

71
std::unique_ptr<data_flow::DataFlowNode> CallNode::
NEW
72
    clone(size_t element_id, const graph::Vertex vertex, data_flow::DataFlowGraph& parent) const {
×
NEW
73
    return std::make_unique<CallNode>(element_id, debug_info_, vertex, parent, function_name_, outputs_, inputs_);
×
74
}
75

NEW
76
void CallNode::replace(const symbolic::Expression old_expression, const symbolic::Expression new_expression) {}
×
77

NEW
78
nlohmann::json CallNodeSerializer::serialize(const data_flow::LibraryNode& library_node) {
×
NEW
79
    const CallNode& node = static_cast<const CallNode&>(library_node);
×
80

NEW
81
    nlohmann::json j;
×
NEW
82
    j["code"] = node.code().value();
×
NEW
83
    j["function_name"] = node.function_name();
×
NEW
84
    j["outputs"] = node.outputs();
×
NEW
85
    j["inputs"] = node.inputs();
×
86

NEW
87
    return j;
×
NEW
88
}
×
89

NEW
90
data_flow::LibraryNode& CallNodeSerializer::deserialize(
×
91
    const nlohmann::json& j, builder::StructuredSDFGBuilder& builder, structured_control_flow::Block& parent
92
) {
NEW
93
    assert(j.contains("code"));
×
NEW
94
    assert(j.contains("function_name"));
×
NEW
95
    assert(j.contains("outputs"));
×
NEW
96
    assert(j.contains("inputs"));
×
NEW
97
    assert(j.contains("debug_info"));
×
98

NEW
99
    auto code = j["code"].get<std::string>();
×
NEW
100
    if (code != LibraryNodeType_Call.value()) {
×
NEW
101
        throw InvalidSDFGException("Invalid library node code");
×
102
    }
103

NEW
104
    sdfg::serializer::JSONSerializer serializer;
×
NEW
105
    DebugInfo debug_info = serializer.json_to_debug_info(j["debug_info"]);
×
106

NEW
107
    std::string function_name = j["function_name"].get<std::string>();
×
NEW
108
    auto outputs = j["outputs"].get<std::vector<std::string>>();
×
NEW
109
    auto inputs = j["inputs"].get<std::vector<std::string>>();
×
110

NEW
111
    return builder.add_library_node<CallNode>(parent, debug_info, function_name, outputs, inputs);
×
NEW
112
}
×
113

NEW
114
CallNodeDispatcher::CallNodeDispatcher(
×
115
    codegen::LanguageExtension& language_extension,
116
    const Function& function,
117
    const data_flow::DataFlowGraph& data_flow_graph,
118
    const CallNode& node
119
)
NEW
120
    : codegen::LibraryNodeDispatcher(language_extension, function, data_flow_graph, node) {}
×
121

NEW
122
void CallNodeDispatcher::dispatch_code(
×
123
    codegen::PrettyPrinter& stream,
124
    codegen::PrettyPrinter& globals_stream,
125
    codegen::CodeSnippetFactory& library_snippet_factory
126
) {
NEW
127
    auto& node = static_cast<const CallNode&>(node_);
×
128

129
    // Declare function
NEW
130
    if (this->language_extension_.language() == "C") {
×
NEW
131
        globals_stream << "extern ";
×
NEW
132
    } else if (this->language_extension_.language() == "C++") {
×
NEW
133
        globals_stream << "extern \"C\" ";
×
NEW
134
    }
×
NEW
135
    globals_stream << language_extension_.declaration(node.function_name(), node.function_type(this->function_)) << ";"
×
NEW
136
                   << std::endl;
×
137

NEW
138
    if (!node.is_void(function_)) {
×
NEW
139
        stream << node.outputs().at(0) << " = ";
×
NEW
140
    }
×
NEW
141
    stream << node.function_name() << "(";
×
NEW
142
    for (size_t i = 0; i < node.inputs().size(); ++i) {
×
NEW
143
        stream << node.inputs().at(i);
×
NEW
144
        if (i < node.inputs().size() - 1) {
×
NEW
145
            stream << ", ";
×
NEW
146
        }
×
NEW
147
    }
×
NEW
148
    stream << ")" << ";";
×
NEW
149
    stream << std::endl;
×
NEW
150
}
×
151

152
} // namespace data_flow
153
} // 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