Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RModel_GraphIndependent.cxx
Go to the documentation of this file.
1#include <limits>
2#include <algorithm>
3#include <cctype>
4
6
7namespace TMVA {
8namespace Experimental {
9namespace SOFIE {
10
12 edges_update_block = std::move(other.edges_update_block);
13 nodes_update_block = std::move(other.nodes_update_block);
14 globals_update_block = std::move(other.globals_update_block);
15
16 num_nodes = std::move(other.num_nodes);
17 num_edges = std::move(other.num_edges);
18
19 fName = std::move(other.fName);
20 fFileName = std::move(other.fFileName);
21 fParseTime = std::move(other.fParseTime);
22}
23
25 edges_update_block = std::move(other.edges_update_block);
26 nodes_update_block = std::move(other.nodes_update_block);
27 globals_update_block = std::move(other.globals_update_block);
28
29 num_nodes = std::move(other.num_nodes);
30 num_edges = std::move(other.num_edges);
31
32 fName = std::move(other.fName);
33 fFileName = std::move(other.fFileName);
34 fParseTime = std::move(other.fParseTime);
35
36 return *this;
37}
38
40 edges_update_block = std::move(graph_input_struct.edges_update_block);
41 nodes_update_block = std::move(graph_input_struct.nodes_update_block);
42 globals_update_block = std::move(graph_input_struct.globals_update_block);
43
44 num_nodes = graph_input_struct.num_nodes;
45 num_edges = graph_input_struct.edges.size();
46 num_node_features = graph_input_struct.num_node_features;
47 num_edge_features = graph_input_struct.num_edge_features;
48 num_global_features = graph_input_struct.num_global_features;
49
50 fFileName = graph_input_struct.filename;
51 fName = fFileName.substr(0, fFileName.rfind("."));
52
53 std::time_t ttime = std::time(0);
54 std::tm* gmt_time = std::gmtime(&ttime);
55 fParseTime = std::asctime(gmt_time);
56}
57
59 std::string hgname;
60 GenerateHeaderInfo(hgname);
61
62 std::ofstream f;
63 f.open(fName+".dat");
64 f.close();
65
66
67 long next_pos = 0;
68 auto num_edge_features_input = num_edge_features;
69 auto num_node_features_input = num_node_features;
70 auto num_global_features_input = num_global_features;
71
72 //Generating Infer function definition for Edge update function
74 size_t block_size = num_edges;
75 fGC += "\n\nnamespace Edge_Update{\nstruct Session {\n";
76 std::vector<std::vector<Dim>> update_Input = { { Dim{"num_edges",block_size}, Dim{num_edge_features}} };
77 edges_update_block->Initialize();
78 edges_update_block->AddInputTensors(update_Input);
79 fGC += edges_update_block->GenerateModel(fName);
80 next_pos = edges_update_block->GetFunctionBlock()->WriteInitializedTensorsToFile(fName + ".dat");
81 fGC += "};\n}\n";
82
83 // the number of output edges features can be smaller, so we need to correct here
84 // assume num_edge_features is not a parametric shape
85 auto edges_update_output_shape = edges_update_block->GetFunctionBlock()->GetDynamicTensorShape(edges_update_block->GetFunctionBlock()->GetOutputTensorNames()[0]);
86 if(!edges_update_output_shape[1].isParam && edges_update_output_shape[1].dim != num_edge_features_input) {
87 num_edge_features = edges_update_output_shape[1].dim;
88 }
89 }
90
92 fGC+="\n\nnamespace Node_Update{\nstruct Session {\n";
93 // Generating Infer function definition for Node Update function
94 // num_node_features is the output one
95 size_t block_size = num_nodes;
96 std::vector<std::vector<Dim>> update_Input = { {Dim{"num_nodes", block_size}, Dim{num_node_features}} };
97 nodes_update_block->Initialize();
98 nodes_update_block->AddInputTensors(update_Input);
99 fGC+=nodes_update_block->GenerateModel(fName,next_pos);
100 next_pos = nodes_update_block->GetFunctionBlock()->WriteInitializedTensorsToFile(fName+".dat");
101 fGC+="};\n}\n";
102
103 // we need to correct the output number of node features
104 auto nodes_update_output_shape = nodes_update_block->GetFunctionBlock()->GetDynamicTensorShape(nodes_update_block->GetFunctionBlock()->GetOutputTensorNames()[0]);
105 if(!nodes_update_output_shape[1].isParam && nodes_update_output_shape[1].dim != num_node_features_input) {
106 num_node_features = nodes_update_output_shape[1].dim;
107 }
108 }
109
110 // Generating Infer function definition for Global Update function
112 fGC+="\n\nnamespace Global_Update{\nstruct Session {\n";
113 std::vector<std::vector<std::size_t>> update_Input = {{1, num_global_features}};
114 globals_update_block->Initialize();
115 globals_update_block->AddInputTensors(update_Input);
116 fGC+=globals_update_block->GenerateModel(fName,next_pos);
117 next_pos = globals_update_block->GetFunctionBlock()->WriteInitializedTensorsToFile(fName+".dat");
118 fGC+="};\n}\n";
119
120 // we need to correct the output number of global features
121 // global features are in shape[1]
122#if 0
123 auto globals_update_output_shape = globals_update_block->GetFunctionBlock()->GetDynamicTensorShape(globals_update_block->GetFunctionBlock()->GetOutputTensorNames()[0]);
124 if(!globals_update_output_shape[1].isParam && globals_update_output_shape[1].dim != num_global_features_input) {
125 num_global_features = globals_update_output_shape[1].dim;
126 }
127#endif
128 if(globals_update_block->GetFunctionBlock()->GetTensorShape(globals_update_block->GetFunctionBlock()->GetOutputTensorNames()[0])[1] != num_global_features) {
129 num_global_features = globals_update_block->GetFunctionBlock()->GetTensorShape(globals_update_block->GetFunctionBlock()->GetOutputTensorNames()[0])[1];
130 }
131 }
132
133
134 // computing inplace on input graph
135 fGC += "struct Session {\n";
136 fGC += "\n// Instantiating session objects for graph components\n";
137 // create session classes and corresponding temporary vectors
138 if (edges_update_block) {
139 fGC += "Edge_Update::Session edge_update;\n";
140 // this we can remove when we support full dynamic edges and nodes
141 fGC += "std::vector<float> fEdgeInputs = std::vector<float>(" + std::to_string(num_edges) + "*" + std::to_string(num_edge_features_input) + ");\n";
142 //fGC += "std::vector<float> fEdgeUpdates {" + std::to_string(num_edges) + "*" + std::to_string(num_edge_features) + "};";
143 }
144 if (nodes_update_block) {
145 fGC += "Node_Update::Session node_update;\n";
146 fGC += "std::vector<float> fNodeInputs = std::vector<float>(" + std::to_string(num_nodes) + "*" + std::to_string(num_node_features_input) + ");\n";
147 //fGC += "std::vector<float> fNodeUpdates {" + std::to_string(num_nodes) + "*" + std::to_string(num_node_features) + "};";
148 }
150 fGC += "Global_Update::Session global_update;\n\n";
151 //fGC += "std::vector<float> fGlobalUpdates {" + std::to_string(num_global_features) + "};";
152 }
153
154 fGC += "\nvoid infer(TMVA::Experimental::SOFIE::GNN_Data& input_graph){\n";
155
156 // computing updated edge attributes
157 // could use std::span
158 if (edges_update_block) {
159 fGC += "\n// --- Edge Update ---\n";
160
161 std::string e_size_input = std::to_string(num_edge_features_input);
162 fGC += "size_t n_edges = input_graph.edge_data.GetShape()[0];\n";
163 fGC += "for (size_t k = 0; k < n_edges; k++) { \n";
164 fGC += " std::copy(input_graph.edge_data.GetData() + k * " + e_size_input +
165 ", input_graph.edge_data.GetData() + (k + 1) * " + e_size_input + ", fEdgeInputs.begin() + k * " +
166 e_size_input + ");\n";
167 fGC += "}\n";
168
169 fGC += "auto edgeUpdates = " + edges_update_block->Generate({"n_edges","fEdgeInputs.data()"}) + "\n";
170
171 if (num_edge_features != num_edge_features_input) {
172 fGC += "\n// resize edge graph data since output feature size is not equal to input size\n";
173 fGC += "input_graph.edge_data = input_graph.edge_data.Resize({ n_edges, " +
174 std::to_string(num_edge_features) + "});\n";
175 }
176 // copy output
177 fGC += "\nfor (size_t k = 0; k < n_edges; k++) { \n";
178 fGC += " std::copy(edgeUpdates.begin()+ k * " + std::to_string(num_edge_features) +
179 ", edgeUpdates.begin()+ (k+1) * " + std::to_string(num_edge_features) +
180 ",input_graph.edge_data.GetData() + k * " + std::to_string(num_edge_features) + ");\n";
181 fGC += "}\n";
182 fGC += "\n";
183 }
184
185 // computing updated node attributes
186 if (nodes_update_block) {
187 std::string n_size_input = std::to_string(num_node_features_input);
188 fGC += "\n// --- Node Update ---\n";
189 fGC += "size_t n_nodes = input_graph.node_data.GetShape()[0];\n";
190 fGC += "for (size_t k = 0; k < n_nodes; k++) { \n";
191 fGC += " std::copy(input_graph.node_data.GetData() + k * " + n_size_input +
192 ", input_graph.node_data.GetData() + (k + 1) * " + n_size_input + ", fNodeInputs.begin() + k * " +
193 n_size_input + ");\n";
194 fGC += "}\n";
195
196 fGC += "auto nodeUpdates = ";
197 fGC += nodes_update_block->Generate({"n_nodes","fNodeInputs.data()"}); // computing updated node attributes
198 fGC += "\n";
199
200 if (num_node_features != num_node_features_input) {
201 fGC += "\n// resize node graph data since output feature size is not equal to input size\n";
202 fGC += "input_graph.node_data = input_graph.node_data.Resize({ n_nodes, " +
203 std::to_string(num_node_features) + "});\n";
204 }
205 // copy output
206 fGC += "\nfor (size_t k = 0; k < n_nodes; k++) { \n";
207 fGC += " std::copy(nodeUpdates.begin()+ k * " + std::to_string(num_node_features) +
208 ", nodeUpdates.begin() + (k+1) * " + std::to_string(num_node_features) +
209 ",input_graph.node_data.GetData() + k * " + std::to_string(num_node_features) + ");\n";
210 fGC += "}\n";
211 fGC += "\n";
212 }
213
214 // computing updated global attributes
216 fGC += "\n// --- Global Update ---\n";
217 fGC += "std::vector<float> Global_Data = ";
218 fGC += globals_update_block->Generate({"input_graph.global_data.GetData()"});
219 fGC += "\n";
220
221 if (num_global_features != num_global_features_input) {
222 fGC += "\n// resize global graph data since output feature size is not equal to input size\n";
223 fGC += "input_graph.global_data = input_graph.global_data.Resize({" + std::to_string(num_global_features) +
224 "});\n";
225 }
226
227 fGC += "\nstd::copy(Global_Data.begin(), Global_Data.end(), input_graph.global_data.GetData());";
228 fGC += "\n";
229 }
230
231 fGC += ("}\n};\n} //TMVA_SOFIE_" + fName + "\n");
232 fGC += "\n#endif // TMVA_SOFIE_" + hgname + "\n";
233
234}
235
236}//SOFIE
237}//Experimental
238}//TMVA
#define f(i)
Definition RSha256.hxx:104
void GenerateHeaderInfo(std::string &hgname)
RModel_GraphIndependent & operator=(RModel_GraphIndependent &&other)
RModel_GraphIndependent()=default
Default constructor.
create variable transformations
std::unique_ptr< RFunction_Update > globals_update_block