#ifdef __CLING__
#endif
#include "encoder.hxx"
#include "core.hxx"
#include "decoder.hxx"
#include "output_transform.hxx"
#include <vector>
const int num_max_nodes = 100;
const int num_max_edges = 300;
const int NODE_FEATURE_SIZE = 4;
const int EDGE_FEATURE_SIZE = 4;
const int GLOBAL_FEATURE_SIZE = 1;
const int LATENT_SIZE = 100;
double check_mem(std::string s = ""){
printf("%s - ",s.c_str());
printf(" Rmem = %8.3f MB, Vmem = %8.f3 MB \n",
);
return p.fMemResident / 1024.;
}
struct GNN_Data {
size_t num_nodes = 0;
size_t num_edges = 0;
std::vector<float> node_data;
std::vector<float> edge_data;
std::vector<float> global_data;
std::vector<int64_t> receivers;
std::vector<int64_t> senders;
};
std::vector<float> ConcatenateFeatures(
const std::vector<float> &
a,
const std::vector<float> &
b,
size_t rows)
{
size_t fa =
a.size() / rows, fb =
b.size() / rows;
std::vector<float> out(rows * (fa + fb));
for (size_t i = 0; i < rows; i++) {
std::copy(
a.begin() + i * fa,
a.begin() + (i + 1) * fa, out.begin() + i * (fa + fb));
std::copy(
b.begin() + i * fb,
b.begin() + (i + 1) * fb, out.begin() + i * (fa + fb) + fa);
}
return out;
}
struct SOFIE_GNN {
TMVA_SOFIE_encoder::Session encoder{"encoder.dat", num_max_edges, num_max_nodes};
TMVA_SOFIE_core::Session core{"core.dat", num_max_edges, num_max_nodes};
TMVA_SOFIE_decoder::Session decoder{"decoder.dat", num_max_edges, num_max_nodes};
TMVA_SOFIE_output_transform::Session output_transform{"output_transform.dat", num_max_edges, num_max_nodes};
std::vector<std::vector<float>> Infer(
const GNN_Data &
d,
int nsteps) {
auto latent = encoder.infer(
d.num_nodes,
d.node_data.data(),
d.num_edges,
d.edge_data.data(),
auto latent0 = latent;
std::vector<std::vector<float>> output;
for (int i = 0; i < nsteps; i++) {
auto node_input = ConcatenateFeatures(latent0[0], latent[0],
d.num_nodes);
auto edge_input = ConcatenateFeatures(latent0[1], latent[1],
d.num_edges);
auto global_input = ConcatenateFeatures(latent0[2], latent[2], 1);
latent = core.infer(
d.num_nodes, node_input.data(),
d.num_edges, edge_input.data(),
global_input.data(),
d.receivers.data(),
d.senders.data());
auto decoded = decoder.infer(
d.num_nodes, latent[0].data(),
d.num_edges, latent[1].data(),
latent[2].data());
output = output_transform.infer(
d.num_nodes, decoded[0].data(),
d.num_edges, decoded[1].data(),
decoded[2].data());
}
return output;
}
};
std::vector<GNN_Data> ReadData(std::string treename, std::string
filename) {
int nevts = ndata.GetPtr()->
size();
std::vector<GNN_Data> dataSet;
dataSet.reserve(nevts);
for (int i = 0; i < nevts; i++) {
GNN_Data gd;
auto &
n = (*(ndata.GetPtr()))[i];
auto &
e = (*(edata.GetPtr()))[i];
auto &
g = (*(gdata.GetPtr()))[i];
auto &
r = (*(rdata.GetPtr()))[i];
auto & s = (*(sdata.GetPtr()))[i];
gd.num_nodes =
n.size()/NODE_FEATURE_SIZE;
gd.num_edges =
e.size()/EDGE_FEATURE_SIZE;
gd.node_data.assign(
n.begin(),
n.end());
gd.edge_data.assign(
e.begin(),
e.end());
gd.global_data.assign(
g.begin(),
g.end());
gd.receivers.assign(
r.begin(),
r.end());
gd.senders.assign(s.begin(), s.end());
dataSet.emplace_back(std::move(gd));
}
return dataSet;
}
void TMVA_SOFIE_GNN_Application (bool verbose = false)
{
check_mem("Initial memory");
SOFIE_GNN gnn;
check_mem("After creating GNN");
const int nproc_steps = 5;
std::cout << "reading data\n";
auto inputData = ReadData("gdata","graph_data.root");
int nevts = inputData.size();
auto h1 =
new TH1D(
"h1_sofie",
"SOFIE Node data",40,1,0);
auto h2 =
new TH1D(
"h2_sofie",
"SOFIE Edge data",40,1,0);
auto h3 =
new TH1D(
"h3_sofie",
"SOFIE Global data",40,1,0);
std::cout << "doing inference...\n";
check_mem("Before evaluating");
for (int i = 0; i < nevts; i++) {
auto result = gnn.Infer(inputData[i], nproc_steps);
}
check_mem("End evaluation");
auto c2 =
new TCanvas(
"c2",
"Reference Results");
auto o1 = file->Get<
TH1D>(
"h1");
auto o2 = file->Get<
TH1D>(
"h2");
auto o3 = file->Get<
TH1D>(
"h3");
if (verbose)
std::cout <<
"SOFIE global mean " << h3->GetMean() <<
" reference " << o3->
GetMean() << std::endl;
if (std::abs(h3->GetMean() - o3->
GetMean()) > 5
e-4)
std::cerr << "Error in comparing SOFIE and reference results" << std::endl;
}
#define R__ADD_INCLUDE_PATH(PATH)
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
R__EXTERN TSystem * gSystem
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.
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)
virtual Double_t GetMean(Int_t axis=1) const
For axis = 1,2 or 3 returns the mean value of the histogram along X,Y or Z axis.
virtual Int_t Fill(Double_t x)
Increment bin with abscissa X by 1.
void Draw(Option_t *option="") override
Draw this histogram with options.
virtual Bool_t Divide(TF1 *f1, Double_t c1=1)
Performs the operation: this = this/(c1*f1) if errors are defined (see TH1::Sumw2),...
void Start(Bool_t reset=kTRUE)
Start the stopwatch.
virtual int GetProcInfo(ProcInfo_t *info) const
Returns cpu and memory used by this process into the ProcInfo_t structure.
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.