1#ifndef TMVA_SOFIE_ROperator_Where
2#define TMVA_SOFIE_ROperator_Where
12namespace Experimental{
69 auto ret = std::vector<std::vector<size_t>>(1,
input[0]);
75 if (!model.CheckIfTensorAlreadyExist(
fNX)){
76 throw std::runtime_error(std::string(
"TMVA SOFIE Where Op Input Tensor ") +
fNX +
"is not found in model");
78 if (!model.CheckIfTensorAlreadyExist(
fNY)) {
79 throw std::runtime_error(std::string(
"TMVA SOFIE Where Op Input Tensor ") +
fNY +
"is not found in model");
81 if (!model.CheckIfTensorAlreadyExist(
fNC)) {
82 throw std::runtime_error(std::string(
"TMVA SOFIE Where Op Input Tensor ") +
fNC +
"is not found in model");
85 if (model.IsReadyInputTensor(
fNC))
93 if (model.IsDynamicTensor(
fNC)) {
100 if (model.IsDynamicTensor(
fNX)) {
107 if (model.IsDynamicTensor(
fNY)) {
116 if (model.Verbose()) {
157 if (model.IsInitializedTensor(
fNX)) {
158 auto data = model.GetInitializedTensorData(
fNX);
161 std::default_delete<T[]>());
176 if (model.IsInitializedTensor(
fNY)) {
177 auto data = model.GetInitializedTensorData(
fNY);
180 std::default_delete<T[]>());
196 if (model.IsInitializedTensor(
fNC)) {
197 auto data = model.GetInitializedTensorData(
fNC);
200 std::default_delete<T[]>());
216 if (model.IsInitializedTensor(
fNC)) {
218 auto dataC =
static_cast<bool *
>(model.GetInitializedTensorData(
nameC).get());
219 model.SetNotWritableInitializedTensor(
nameC);
224 if (model.IsInitializedTensor(
fNX)) {
226 dataX =
static_cast<T *
>(model.GetInitializedTensorData(
nameX).get());
228 model.SetNotWritableInitializedTensor(
nameX);
229 }
else if (model.IsShapeTensor(
fNX)) {
232 if (model.IsInitializedTensor(
fNY)) {
234 dataY =
static_cast<T *
>(model.GetInitializedTensorData(
nameY).get());
235 model.SetNotWritableInitializedTensor(
nameY);
236 }
else if (model.IsShapeTensor(
fNY)) {
239 std::vector<T>
dataZ;
248 for (
size_t i = 0; i <
dataZ.size(); i++)
254 for (
size_t i = 0; i <
shapeDataZ.size(); i++) {
263 for (
size_t i = 0; i <
shapeDataZ.size(); i++) {
272 for (
size_t i = 0; i <
shapeDataZ.size(); i++) {
282 if (
dataZ.size() > 0)
292 << ((
dataZ.size() > 0) ?
" (constant)" :
" (shape)") << std::endl;
301 model.AddIntermediateTensor(
fNZ, model.GetTensorType(
fNX),
fShapeZ);
323 for (
auto &
input : model.GetInputTensorNames())
324 for (
auto &s : model.GetDimTensorShape(
input))
325 if (s.isParam && s.param ==
p)
return true;
328 for (
size_t i = 0; i <
fDimShapeZ.size(); i++) {
330 if (s.isParam && s.param.find(
"std::max") != std::string::npos) {
365 std::stringstream out;
372 std::stringstream out;
386 for (
size_t i = 0; i <
fDimShapeZ.size(); i++) {
392 <<
"throw std::runtime_error(\"SOFIE Where: cannot broadcast A dim " << i <<
" in " <<
opName <<
"\");\n";
399 <<
"throw std::runtime_error(\"SOFIE Where: cannot broadcast B dim " << i <<
" in " <<
opName <<
"\");\n";
406 <<
"throw std::runtime_error(\"SOFIE Where: cannot broadcast C dim " << i <<
" in " <<
opName <<
"\");\n";
421 const std::vector<Dim> &strides,
422 size_t rankZ) -> std::string {
425 [](
Dim d) { return d.dim == 1 || d.GetVal() ==
"1"; }))
429 for (
size_t i = 0; i <
dimShape.size(); ++i) {
432 if (strides[i].GetVal() !=
"1")
433 expr +=
" * " + strides[i].GetVal();
436 if (
expr.size() >= 3)
437 for (
int j = 0;
j < 3;
j++)
expr.pop_back();
451 [](
Dim d) { return d.dim == 1 || d.GetVal() ==
"1"; })) {
454 for (
size_t i = 0; i <
fDimShapeZ.size(); ++i) {
458 out <<
"for (size_t idx_" << i <<
" = 0; idx_" << i
459 <<
" < " <<
fDimShapeZ[i] <<
"; ++idx_" << i <<
") {\n";
460 idxZ +=
"idx_" + std::to_string(i);
466 if (
idxZ.size() >= 3)
467 for (
int j = 0;
j < 3;
j++)
idxZ.pop_back();
471 for (
int j = 0;
j <
nloop + 1;
j++) out <<
SP;
472 out <<
"tensor_" <<
fNZ <<
"[" <<
idxZ <<
"] = "
473 <<
"tensor_" <<
fNC <<
"[" <<
idxC <<
"] ? "
474 <<
"tensor_" <<
fNX <<
"[" <<
idxX <<
"] : "
475 <<
"tensor_" <<
fNY <<
"[" <<
idxY <<
"];\n";
478 for (
int i =
nloop; i > 0; i--) {
479 for (
int j = 0;
j < i;
j++) out <<
SP;
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
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 offset
const_iterator begin() const
const_iterator end() const
std::vector< Dim > fDimShapeX
std::vector< size_t > fShapeY
std::vector< size_t > fShapeX
std::vector< size_t > fShapeC
std::string fNBroadcastedX
std::vector< std::vector< size_t > > ShapeInference(std::vector< std::vector< size_t > > input) override
std::string Generate(std::string opName) override
std::vector< ETensorType > TypeInference(std::vector< ETensorType > input) override
std::vector< Dim > fDimShapeY
ROperator_Where(const std::string &nameC, const std::string &nameX, const std::string &nameY, const std::string &nameZ)
void Initialize(RModel &model) override
std::vector< Dim > fDimShapeZ
std::string fNBroadcastedC
std::string fNBroadcastedY
std::vector< Dim > fDimShapeC
std::vector< size_t > fShapeZ
std::string GenerateInitCode() override
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
bool AreSameShape(const std::vector< size_t > &, const std::vector< size_t > &)
std::vector< size_t > MultidirectionalBroadcastShape(std::vector< std::vector< size_t > >)
T * UnidirectionalBroadcast(const T *data, const std::vector< size_t > &shape, const std::vector< size_t > &targetShape)
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::string ConvertValuesToString(size_t n, const T *data, size_t maxprint=-1)
std::vector< Dim > ConvertShapeToDim(const std::vector< size_t > &shape)
Convert shape from integer format to dynamic one (based on Dim)
std::string ConvertDimShapeToLength(const std::vector< Dim > &shape)
std::string ConvertShapeToString(const std::vector< size_t > &shape)
create variable transformations