7#include <unordered_map>
11namespace Experimental {
18 std::vector<Dim> ret_shape(shape.size());
19 for (
size_t i =0; i < shape.size(); i++){
20 ret_shape[i].dim = shape[i];
29 std::vector<size_t> ret_shape(shape.size());
30 for (
size_t i =0; i < shape.size(); i++){
31 if (shape[i].isParam) {
35 val = std::stoi(shape[i].param);
36 if (val >= 0) ret_shape[i] =
static_cast<size_t>(val);
42 catch (
const std::invalid_argument& ) {
46 catch (
const std::out_of_range& ) {
51 ret_shape[i] = shape[i].dim;
60 std::size_t fLength = 1;
61 for (
const auto &dim : shape)
102 return "other_" + std::to_string( (
int)
type);
110 if(
type ==
"float32" ||
type ==
"float" ||
type ==
"Float"){
113 else if(
type ==
"int64" ||
type ==
"int64_t"){
116 else if(
type ==
"int32" ||
type ==
"int32_t"){
119 else if (
type ==
"double" ||
type ==
"float64"){
122 else if (
type ==
"bool" ||
type ==
"uint8_t" ){
131 std::stringstream out;
133 for (
size_t i = 0; i < shape.size(); i++) {
135 if (i < shape.size()-1) out <<
" , ";
142 std::stringstream out;
144 for (
size_t i = 0; i < shape.size(); i++) {
146 if (i < shape.size()-1) out <<
" , ";
157 if (shape.empty())
return "1";
158 int64_t int_length = -1;
159 for (
size_t i = 0; i < shape.size(); i++) {
160 if (shape[i].isParam) {
164 if (int_length == -1)
165 int_length = shape[i].dim;
167 int_length *= shape[i].dim;
172 if (int_length >= 0) {
173 if (!
length.empty() && int_length > 1) {
175 length += std::to_string(int_length);
176 }
else if (
length.empty()) {
177 length = std::to_string(int_length);
187 std::memcpy(
target,
input, input_size *
sizeof(T));
188 int_t already_copied = 1;
190 while (already_copied * 2 <= no_of_copies){
191 std::memcpy(
target + already_copied * input_size,
target, already_copied * input_size *
sizeof(T));
195 if (already_copied < no_of_copies){
196 std::memcpy(
target + already_copied * input_size,
target, (no_of_copies - already_copied) * input_size *
sizeof(T));
203 auto [ptr, ec] = std::from_chars(s.data(), s.data() + s.size(),
value);
204 return ec == std::errc() && ptr == s.data() + s.size();
208 if (shapeA.size() != shapeB.size()) {
211 for (
size_t dim = 0; dim < shapeA.size(); dim++) {
212 if (shapeA[dim] != shapeB[dim]) {
219 if (shapeA.size() != shapeB.size()) {
222 for (
size_t dim = 0; dim < shapeA.size(); dim++) {
223 if (shapeB[dim].isParam)
return false;
224 if (shapeA[dim] != shapeB[dim].dim) {
231 if (shapeA.size() != shapeB.size()) {
234 for (
size_t dim = 0; dim < shapeA.size(); dim++) {
235 if (shapeA[dim].GetVal() != shapeB[dim].GetVal()) {
244 if (shape.size() < 2) {
246 std::runtime_error(
"TMVA::SOFIE - MultidirectionalBroadcastShape requires at least 2 input shapes.");
249 size_t n = shape.size();
251 size_t targetSize = shape[0].size();
252 for (
size_t i = 1; i <
n; i++) {
253 targetSize = std::max(targetSize, shape[i].
size());
256 bool sameSize =
true;
257 for (
size_t i = 0; i <
n; i++) {
258 if (shape[i].
size() != targetSize) {
265 bool sameShape =
true;
266 for (
size_t i = 1; i <
n; i++) {
267 for (
size_t dim = 0; dim < shape[0].size(); dim++) {
268 if (shape[i][dim] != shape[0][dim]) {
281 std::vector<size_t> targetShape(targetSize, 1);
282 for (
size_t i = 0; i <
n; i++) {
283 for (
size_t dim = 0; dim < targetSize; dim++) {
284 targetShape[dim] = std::max(targetShape[dim], shape[i][dim]);
288 bool broadcastable =
true;
289 for (
size_t i = 0; i <
n; i++) {
290 for (
size_t dim = 0; dim < targetSize; dim++) {
291 if (shape[i][dim] != 1 && targetShape[dim] != 1 && shape[i][dim] != targetShape[dim]) {
292 broadcastable =
false;
295 if (!broadcastable) {
304 std::stringstream ss;
305 ss <<
"TMVA::SOFIE - Error multidirectional broadcasting shapes ";
306 for (
size_t i = 0; i <
n; i++) {
308 if (
n > 2 && i <
n - 2) {
310 }
else if (
n >=2 && i ==
n - 2) {
314 ss <<
" to the same shape.";
316 std::runtime_error(ss.str());
321 for (
size_t i = 0; i <
n; i++) {
322 if (shape[i].
size() < targetSize) {
323 std::vector<size_t> newShape(targetSize, 1);
324 size_t offset = targetSize - shape[i].size();
325 std::copy(shape[i].begin(), shape[i].end(), newShape.begin() +
offset);
330 std::vector<size_t> targetShape(targetSize, 1);
331 for (
size_t i = 0; i <
n; i++) {
332 for (
size_t dim = 0; dim < targetSize; dim++) {
333 targetShape[dim] = std::max(targetShape[dim], shape[i][dim]);
337 bool broadcastable =
true;
338 for (
size_t i = 0; i <
n; i++) {
339 for (
size_t dim = 0; dim < targetSize; dim++) {
340 if (shape[i][dim] != targetShape[dim] && shape[i][dim] != 1 && targetShape[dim] != 1) {
341 broadcastable =
false;
345 if (!broadcastable) {
352 std::stringstream ss;
353 ss <<
"TMVA::SOFIE - Error multidirectional broadcasting shapes ";
354 for (
size_t i = 0; i <
n; i++) {
356 if (
n > 2 && i <
n - 2) {
358 }
else if (
n >=2 && i ==
n - 2) {
362 ss <<
" to the same shape.";
364 std::runtime_error(ss.str());
376 size_t sizeA = shapeA.size();
377 size_t sizeB = shapeB.size();
380 return std::make_pair(0, shapeA);
383 size_t size = std::max(sizeA, sizeB);
386 std::vector<size_t> newShapeA(
size, 1);
388 std::copy(shapeA.begin(), shapeA.end(), newShapeA.begin() +
offset);
389 shapeA = std::move(newShapeA);
392 std::vector<size_t> newShapeB(
size, 1);
394 std::copy(shapeB.begin(), shapeB.end(), newShapeB.begin() +
offset);
395 shapeB = std::move(newShapeB);
397 bool broadcastable =
true;
398 for (
size_t i = 0; i <
size; i++) {
399 if (shapeA[i] != shapeB[i] && shapeA[i] != 1 && shapeB[i] != 1) {
400 broadcastable =
false;
404 int broadcastFlag = 0;
407 std::vector<size_t> targetShape(
size, 1);
408 for (
size_t i = 0; i <
size; i++) {
409 targetShape[i] = std::max(shapeA[i], shapeB[i]);
410 if (shapeB[i] < targetShape[i]) broadcastFlag |= 1;
411 if (shapeA[i] < targetShape[i]) broadcastFlag |= 2;
413 return std::make_pair(broadcastFlag, targetShape);
416 std::runtime_error(
"TMVA::SOFIE - Error multidirectional broadcasting tensors of shape "
418 +
" to a common shape.");
427 std::runtime_error(
"TMVA::SOFIE - Error unidirectional broadcasting tensors of shape "
429 +
" in a common shape.");
440 size_t sizeA = shapeA.size();
441 size_t sizeB = shapeB.size();
444 return std::make_pair(0, shapeA);
447 size_t size = std::max(sizeA, sizeB);
450 std::vector<Dim> newShapeA(
size,
Dim{1});
452 std::copy(shapeA.begin(), shapeA.end(), newShapeA.begin() +
offset);
453 shapeA = std::move(newShapeA);
456 std::vector<Dim> newShapeB(
size,
Dim{1});
458 std::copy(shapeB.begin(), shapeB.end(), newShapeB.begin() +
offset);
459 shapeB = std::move(newShapeB);
462 int broadcastFlag = 0;
464 std::vector<Dim> targetShape(
size);
465 for (
size_t i = 0; i <
size; i++) {
467 if (shapeA[i] == shapeB[i]) {
468 targetShape[i] = shapeA[i];
469 }
else if (shapeA[i].isParam && shapeB[i].GetVal() ==
"1" ) {
471 targetShape[i] = shapeA[i];
473 }
else if (shapeA[i].GetVal() ==
"1" && shapeB[i].isParam) {
475 targetShape[i] = shapeB[i];
477 }
else if (!shapeA[i].isParam && !shapeB[i].isParam) {
478 if (shapeB[i].dim == 1) {
479 targetShape[i] = shapeA[i];
481 }
else if (shapeA[i].dim == 1) {
482 targetShape[i] = shapeB[i];
488 }
else if (shapeA[i].isParam && shapeB[i].isParam) {
491 s <<
"std::max(" << shapeA[i] <<
"," << shapeB[i] <<
")";
493 targetShape[i] =
Dim { s.str() ,
static_cast<size_t>(-1)};
495 }
else if (shapeA[i].isParam && !shapeB[i].isParam) {
497 targetShape[i] = shapeB[i];
499 }
else if (!shapeA[i].isParam && shapeB[i].isParam) {
501 targetShape[i] = shapeA[i];
505 throw std::runtime_error(
"TMVA::SOFIE - Fatal error in MultiDirectionalBroadCastDimShape");
508 if (broadcastFlag == -1) {
509 throw std::runtime_error(
"TMVA::SOFIE - Error multidirectional broadcasting tensors of shape " +
511 " to a common shape.");
514 return std::make_pair(broadcastFlag, targetShape);
518 std::string s (input_tensor_name);
519 std::replace( s.begin(), s.end(),
'-',
'_');
521 s.erase(std::remove_if(s.begin(), s.end(), [](
char const&
c ) ->
bool { return !std::isalnum(static_cast<unsigned char>(c)) && c !=
'_'; } ), s.end());
527 const auto size = shape.size();
528 std::vector<size_t> strides(
size,1);
529 for (std::size_t i = 1; i <
size; i++) {
530 strides[
size - 1 - i] = strides[
size - i ] * shape[
size - i];
537 const auto size = shape.size();
538 std::vector<Dim> strides(
size);
541 for (std::size_t i = 1; i <
size; i++) {
542 if (!shape[
size-i].isParam && !strides[
size-i].isParam)
545 if (strides[
size-i].GetVal() ==
"1")
546 strides[
size - 1 - i] = shape[
size-i];
547 else if (shape[
size-i].GetVal() ==
"1")
548 strides[
size - 1 - i] = strides[
size-i];
550 strides[
size - 1 - i] =
Dim{std::string(strides[
size-i].GetVal() +
"*" + shape[
size-i].GetVal())};
562const std::string
SP =
" ";
563void EmitNestedLoops(std::stringstream &out,
size_t loopRank,
const std::vector<Dim> shape) {
564 for (
size_t i = 0; i < loopRank; ++i) {
565 for (
size_t s = 0; s < i + 2; ++s) out <<
SP;
567 out <<
"for (size_t idx_" << i <<
" = 0; idx_" << i
568 <<
" < " << shape[i] <<
"; ++idx_" << i <<
") {\n";
572 for (int64_t i = loopRank - 1; i >= 0; --i) {
573 for (int64_t s = 0; s < i + 2; ++s) out <<
SP;
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
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
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 Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t target
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
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
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 Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
bool AreSameShape(const std::vector< size_t > &, const std::vector< size_t > &)
std::vector< size_t > UnidirectionalBroadcastShape(std::vector< size_t > &, std::vector< size_t > &)
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)
std::vector< size_t > ConvertShapeToInt(const std::vector< Dim > &shape)
Convert shape based on Dim to integer format.
std::string ConvertTypeToString(ETensorType type)
ETensorType ConvertStringToType(std::string type)
std::string ConvertDimShapeToLength(const std::vector< Dim > &shape)
void EmitNestedLoops(std::stringstream &out, size_t loopRank, const std::vector< Dim > shape)
std::string ConvertShapeToString(const std::vector< size_t > &shape)
void CloseNestedLoops(std::stringstream &out, size_t loopRank)
bool IsInteger(const std::string &s)
create variable transformations