18#include "output_transform.hxx"
32double check_mem(std::string s =
""){
34 printf(
"%s - ",s.c_str());
36 printf(
" Rmem = %8.3f MB, Vmem = %8.f3 MB \n",
49 size_t nrows = (shape.size() > 1) ? shape[0] : 1;
50 size_t ncols = (shape.size() > 1) ? t.
GetStrides()[0] : shape[0];
51 for (
size_t i = 0; i < nrows; i++) {
52 for (
size_t j = 0; j < ncols; j++) {
54 if (j>10) std::cout <<
"... ";
55 std::cout << *p << std::endl;
58 std::cout << *p <<
", ";
62 std::cout << std::endl;
65 if (!txt.empty()) std::cout << std::endl << txt << std::endl;
66 std::cout <<
"node data:"; PrintTensor(
d.node_data);
67 std::cout <<
"edge data:"; PrintTensor(
d.edge_data);
68 std::cout <<
"global data:"; PrintTensor(
d.global_data);
69 std::cout <<
"edge index:"; PrintTensor(
d.edge_index);
74 TMVA_SOFIE_encoder::Session encoder;
75 TMVA_SOFIE_core::Session core;
76 TMVA_SOFIE_decoder::Session decoder;
77 TMVA_SOFIE_output_transform::Session output_transform;
79 std::vector<GNN_Data> Infer(
const GNN_Data & data,
int nsteps) {
81 auto input_data =
Copy(data);
82 if (verbose)
Print(input_data,
"input_data");
83 encoder.infer(input_data);
85 auto latent0 =
Copy(input_data);
86 GNN_Data latent = input_data;
87 std::vector<GNN_Data> outputData;
88 for (
int i = 0; i < nsteps; i++) {
89 if (verbose)
Print(latent0,
"input decoded data");
90 if (verbose)
Print(latent,
"latent data");
92 if (verbose)
Print(core_input,
"after concatenate");
93 core.infer(core_input);
94 if (verbose)
Print(core_input,
"after core inference");
96 latent =
Copy(core_input);
97 decoder.infer(core_input);
98 output_transform.infer(core_input);
99 outputData.push_back(
Copy(core_input));
104 SOFIE_GNN(
bool v =
false) :
verbose(
v) {}
108const int num_max_nodes = 10;
109const int num_max_edges = 30;
110const int NODE_FEATURE_SIZE = 4;
111const int EDGE_FEATURE_SIZE = 4;
112const int GLOBAL_FEATURE_SIZE = 1;
114std::vector<GNN_Data> GenerateData(
int nevts,
int seed) {
116 std::vector<GNN_Data> dataSet;
117 dataSet.reserve(nevts);
118 for (
int i = 0; i < nevts; i++) {
122 size_t num_nodes =
r.Integer(num_max_nodes-2) + 2;
123 size_t num_edges =
r.Integer(num_max_edges-1) + 1;
130 auto genValue = [&]() {
return r.Rndm()*10 -5; };
131 auto genLink = [&] () {
return r.Integer(num_nodes);};
136 dataSet.emplace_back(gd);
141std::vector<GNN_Data> ReadData(std::string treename, std::string filename) {
149 int nevts = ndata.GetPtr()->
size();
150 std::vector<GNN_Data> dataSet;
151 dataSet.reserve(nevts);
152 for (
int i = 0; i < nevts; i++) {
154 auto &
n = (*(ndata.GetPtr()))[i];
155 size_t num_nodes =
n.size()/NODE_FEATURE_SIZE;
156 auto &
e = (*(edata.GetPtr()))[i];
157 size_t num_edges =
e.size()/EDGE_FEATURE_SIZE;
158 auto &
g = (*(gdata.GetPtr()))[i];
163 auto &
r = (*(rdata.GetPtr()))[i];
164 auto & s = (*(sdata.GetPtr()))[i];
169 dataSet.emplace_back(
Copy(gd));
170 if (i < 1 && verbose)
Print(dataSet[i],
"Input for Event" + std::to_string(i));
176void TMVA_SOFIE_GNN_Application (
bool verbose =
false)
178 check_mem(
"Initial memory");
180 check_mem(
"After creating GNN");
183 const int seed = 111;
184 const int nproc_steps = 5;
192 std::cout <<
"reading data\n";
193 auto inputData = ReadData(
"gdata",
"graph_data.root");
194 nevts = inputData.size();
199 auto h1 =
new TH1D(
"h1",
"SOFIE Node data",40,1,0);
200 auto h2 =
new TH1D(
"h2",
"SOFIE Edge data",40,1,0);
201 auto h3 =
new TH1D(
"h3",
"SOFIE Global data",40,1,0);
202 std::cout <<
"doing inference...\n";
205 check_mem(
"Before evaluating");
207 for (
int i = 0; i < nevts; i++) {
208 auto result = gnn.Infer(inputData[i], nproc_steps);
210 auto & lr = result.back();
211 if (i < 1 && verbose)
Print(lr,
"Output for Event" + std::to_string(i));
212 h1->Fill(
TMath::Mean(lr.node_data.begin(), lr.node_data.end()));
213 h2->Fill(
TMath::Mean(lr.edge_data.begin(), lr.edge_data.end()));
214 h3->Fill(
TMath::Mean(lr.global_data.begin(), lr.global_data.end()));
218 check_mem(
"End evaluation");
219 auto c1 =
new TCanvas(
"c1",
"SOFIE Results");
221 c1->cd(1);
h1->Draw();
222 c1->cd(2); h2->Draw();
223 c1->cd(3); h3->Draw();
227 auto c2 =
new TCanvas(
"c2",
"Reference Results");
229 auto o1 = file->Get(
"h1");
230 auto o2 = file->Get(
"h2");
231 auto o3 = file->Get(
"h3");
233 c2->cd(1); o1->Draw();
234 c2->cd(2); o2->Draw();
235 c2->cd(3); o3->Draw();
#define R__ADD_INCLUDE_PATH(PATH)
ROOT's RDataFrame offers a modern, high-level interface for analysis of data stored in TTree ,...
A "std::vector"-like collection of values implementing handy operation to analyse them.
RTensor is a container with contiguous memory and shape information.
const Shape_t & GetStrides() const
std::size_t GetSize() const
Iterator begin() noexcept
const Shape_t & GetShape() const
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault, Int_t netopt=0)
Create / open a file.
1-D histogram with a double per channel (see TH1 documentation)
Random number generator class based on M.
RVec< Common_t > Concatenate(const RVec< T0 > &v0, const RVec< T1 > &v1)
Return the concatenation of two RVecs.
void Copy(void *source, void *dest)
void Print(std::ostream &os, const OptionType &opt)
std::string ConvertShapeToString(const std::vector< size_t > &shape)
GNN_Data Copy(const GNN_Data &data)
Double_t Mean(Long64_t n, const T *a, const Double_t *w=nullptr)
Returns the weighted mean of an array a with length n.
RTensor< float > global_data
RTensor< float > edge_data
RTensor< int > edge_index
RTensor< float > node_data