1#ifndef TMVA_SOFIE_ROPERATOR_BASICNARY
2#define TMVA_SOFIE_ROPERATOR_BASICNARY
13namespace Experimental{
18template<
typename T, EBasicNaryOperator Op>
23 static const std::string
Name() {
return "Max";}
24 static std::string
Expr(
const std::vector<std::string> &inputs)
26 std::stringstream out;
27 out <<
"std::max({ " << inputs[0];
28 for (
size_t i = 1; i < inputs.size(); i++) {
29 out <<
", " << inputs[i];
34 static std::string
Op(
const std::string &res, std::vector<std::string> &inputs)
36 return res +
" = " + Expr(inputs) +
";\n";
38 static size_t Func(
const std::vector<size_t> &values) {
return *std::max_element(values.begin(), values.end()); }
43 static const std::string
Name() {
return "Min";}
44 static std::string
Expr(
const std::vector<std::string> &inputs)
46 std::stringstream out;
47 out <<
"std::min({ " << inputs[0];
48 for (
size_t i = 1; i < inputs.size(); i++) {
49 out <<
", " << inputs[i];
54 static std::string
Op(
const std::string &res, std::vector<std::string> &inputs)
56 return res +
" = " + Expr(inputs) +
";\n";
58 static size_t Func(
const std::vector<size_t> &values) {
return *std::min_element(values.begin(), values.end()); }
63 static const std::string
Name() {
return "Mean";}
64 static std::string
Expr(
const std::vector<std::string> &inputs)
66 std::stringstream out;
67 out <<
"((" << inputs[0];
68 for (
size_t i = 1; i < inputs.size(); i++) {
69 out <<
" + " << inputs[i];
75 static std::string
Op(
const std::string &res, std::vector<std::string> &inputs)
77 return res +
" = " + Expr(inputs) +
";\n";
79 static size_t Func(
const std::vector<size_t> &values)
82 for (
auto &
v : values)
84 return sum / values.size();
90 static const std::string
Name() {
return "Sum";}
91 static std::string
Expr(
const std::vector<std::string> &inputs)
93 std::stringstream out;
94 out <<
"(" << inputs[0];
95 for (
size_t i = 1; i < inputs.size(); i++) {
96 out <<
" + " << inputs[i];
101 static std::string
Op(
const std::string &res, std::vector<std::string> &inputs)
103 return res +
" = " + Expr(inputs) +
";\n";
105 static size_t Func(
const std::vector<size_t> &values)
108 for (
auto &
v : values)
114template <
typename T, EBasicNaryOperator Op>
136 fNY(UTILITY::Clean_name(nameY)){
137 fNInputs.reserve(inputNames.size());
138 for (
auto &
name : inputNames)
143 [](
const std::string& s) -> std::string_view { return s; });
152 bool hasShapeTensor =
false;
153 bool isScalar =
true;
158 if (!model.IsShapeTensor(
name) && !model.IsInitializedTensor(
name))
160 hasShapeTensor |= model.IsShapeTensor(
name);
161 auto shape = model.GetTensorShape(
name);
162 if (shape.size() > 1)
164 if (!shape.empty()) {
176 std::vector<std::vector<Dim>> values(
fNInputs.size(), std::vector<Dim>(
length));
177 for (
size_t i = 0; i <
fNInputs.size(); i++) {
179 if (model.IsShapeTensor(
name)) {
180 auto &dims = model.GetShapeTensorValues(
name);
181 for (
size_t j = 0; j <
length; j++)
182 values[i][j] = (dims.size() == 1) ? dims[0] : dims[j];
184 auto data =
static_cast<int64_t *
>(model.GetInitializedTensorData(
name).get());
186 for (
size_t j = 0; j <
length; j++)
187 values[i][j] =
Dim{
static_cast<size_t>(
data[(
n == 1) ? 0 : j])};
194 std::vector<Dim> outputValues(
length);
195 for (
size_t j = 0; j <
length; j++) {
196 bool isConstant =
true;
197 std::vector<size_t> dims(
fNInputs.size());
198 std::vector<std::string> exprs(
fNInputs.size());
199 for (
size_t i = 0; i <
fNInputs.size(); i++) {
200 isConstant &= !values[i][j].isParam;
201 dims[i] = values[i][j].dim;
203 exprs[i] =
"size_t(" + values[i][j].GetVal() +
")";
210 model.AddShapeTensor(
fNY, outputValues, isScalar);
212 if (model.Verbose()) {
213 std::cout << NaryOperatorTraits<T, Op>::Name() <<
" : --> " <<
fNY <<
" "
220 std::vector<std::vector<size_t>> inputShapes;
222 if (!model.CheckIfTensorAlreadyExist(it)) {
223 throw std::runtime_error(
"TMVA SOFIE BasicNary Op Input Tensor " + it +
" is not found in model");
231 if (model.IsDimInputTensor(it))
232 throw std::runtime_error(
"TMVA SOFIE BasicNary : supports only 2 inputs for dynamic tensors");
234 inputShapes.push_back(model.GetTensorShape(it));
252 auto IsInputDimParam = [&](
const std::string &
p) {
253 auto inputNames = model.GetInputTensorNames();
254 for (
auto &
input : inputNames) {
255 for (
auto &i_s : model.GetDimTensorShape(
input)) {
256 if (i_s.isParam && i_s.param ==
p)
264 for (
size_t i = 0; i <
fDimShapeY.size(); i++) {
266 if (s.isParam && s.param.find(
"std::max") != std::string::npos) {
267 if (IsInputDimParam(shapeA[i].param)) {
269 if (shapeA[i].dim != 1)
273 }
else if (IsInputDimParam(shapeB[i].param)) {
274 if (shapeB[i].dim != 1)
293 if (model.Verbose()) {
294 std::cout << NaryOperatorTraits<T, Op>::Name() <<
" : ";
302 std::string
Generate(std::string OpName)
override {
305 OpName =
"op_" + OpName;
307 throw std::runtime_error(
"TMVA SOFIE BasicNary called to Generate without being initialized first");
309 std::stringstream out;
311 out <<
SP <<
"\n//------ BasicNary operator\n";
316 out <<
SP <<
"std::copy(tensor_" <<
fNInputs[0] <<
", tensor_" <<
fNInputs[0] <<
" + ";
317 out <<
length <<
", tensor_" <<
fNY <<
");\n";
321 std::vector<std::vector<Dim>> inputStrides(nInputs);
322 for (
int i = 0; i < nInputs; i++)
328 std::string compute_idx_Y;
334 for (
size_t i = 0; i <
fDimShapeY.size(); ++i) {
337 for (
int j = 0; j < nloop; j++) out <<
SP;
338 out <<
"for (size_t idx_" << i <<
" = 0; idx_" << i <<
" < " <<
fDimShapeY[i]
339 <<
"; ++idx_" << i <<
"){\n";
340 compute_idx_Y +=
"idx_" + std::to_string(i);
341 if (stridesY[i].GetVal() !=
"1")
342 compute_idx_Y +=
" * " + stridesY[i].GetVal();
343 compute_idx_Y +=
" + ";
347 for (
int j = 0; j < 3; j++)
348 compute_idx_Y.pop_back();
351 std::vector<std::string> inputs(nInputs);
352 for (
int ipt = 0; ipt < nInputs; ipt++ ) {
353 std::string compute_idx_X;
355 auto & stride = inputStrides[ipt];
357 std::all_of(shape.begin(), shape.end(), [](
Dim d) { return d.dim == 1 || d.GetVal() ==
"1"; })) {
360 for (
size_t i = 0; i < shape.size(); ++i) {
361 if (shape[i].dim == 1 || shape[i].GetVal() ==
"1")
363 compute_idx_X +=
"idx_" + std::to_string(i + (
fDimShapeY.size() - shape.size()));
364 if (stride[i].GetVal() !=
"1")
365 compute_idx_X +=
" * " + stride[i].GetVal();
366 compute_idx_X +=
" + ";
369 for (
int j = 0; j < 3; j++)
370 compute_idx_X.pop_back();
372 inputs[ipt] =
"tensor_" +
fNInputs[ipt] +
"[" + compute_idx_X +
"]";
376 for (
int j = 0; j < nloop + 1; j++) out <<
SP;
377 std::string output =
"tensor_" +
fNY +
"[" + compute_idx_Y +
"]";
378 out << NaryOperatorTraits<T,Op>::Op(output, inputs);
380 for (
int i = nloop; i > 0; i--) {
381 for (
int j = 0; j < i; j++) out <<
SP;
388 std::vector<std::string>
GetStdLibs()
override {
return { std::string(
"cmath") }; }
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void input
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 Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h length
std::vector< std::vector< Dim > > fShapeInputs
bool InitializeShapeTensorOutput(RModel &model)
std::vector< size_t > fShapeY
std::vector< std::string > fNBroadcastedInputs
ROperator_BasicNary(const std::vector< std::string > &inputNames, const std::string &nameY)
std::vector< std::string > GetStdLibs() override
std::string Generate(std::string OpName) override
void Initialize(RModel &model) override
std::vector< std::string > fNInputs
std::vector< Dim > fDimShapeY
std::vector< std::string_view > fInputTensorNames
bool fIsOutputConstant
flag to identify if operator has a constant output (no need to generate code)
const std::string SP
space used to correctly indent the generated C++ code
std::vector< std::string_view > fOutputTensorNames
std::string Clean_name(std::string input_tensor_name)
std::vector< size_t > MultidirectionalBroadcastShape(std::vector< std::vector< size_t > >)
std::vector< size_t > ComputeStrideFromShape(const std::vector< size_t > &shape)
compute stride of a tensor given its shape (assume layout is row-major)
std::string ConvertDimShapeToString(const std::vector< Dim > &shape)
std::size_t ConvertShapeToLength(const std::vector< size_t > &shape)
std::vector< Dim > ConvertShapeToDim(const std::vector< size_t > &shape)
Convert shape from integer format to dynamic one (based on Dim)
ETensorType GetTemplatedType(T)
std::string ConvertTypeToString(ETensorType type)
std::string ConvertDimShapeToLength(const std::vector< Dim > &shape)
create variable transformations
static std::string Expr(const std::vector< std::string > &inputs)
static std::string Op(const std::string &res, std::vector< std::string > &inputs)
static size_t Func(const std::vector< size_t > &values)
static const std::string Name()
static size_t Func(const std::vector< size_t > &values)
static std::string Expr(const std::vector< std::string > &inputs)
static std::string Op(const std::string &res, std::vector< std::string > &inputs)
static const std::string Name()
static std::string Expr(const std::vector< std::string > &inputs)
static size_t Func(const std::vector< size_t > &values)
static std::string Op(const std::string &res, std::vector< std::string > &inputs)
static const std::string Name()
static std::string Expr(const std::vector< std::string > &inputs)
static const std::string Name()
static std::string Op(const std::string &res, std::vector< std::string > &inputs)
static size_t Func(const std::vector< size_t > &values)
static uint64_t sum(uint64_t i)