@@ -416,14 +416,12 @@ T* BroadcastConvBias(const T* data, const size_t channel, const std::vector<size
416416// Broadcast a tensor from shape to targetShape according to numpy broadcasting rules
417417// See more at https://numpy.org/doc/stable/user/basics.broadcasting.html
418418// and https://github.com/onnx/onnx/blob/main/docs/Broadcasting.md .
419- template <typename T, class ConstContT = std::span<const T>, class ContT = std::span<T> >
420- void BroadcastTensor (ConstContT data, const std::vector<size_t >& shape, const std::vector<size_t >& targetShape, ContT broadcastedData) {
419+ template <typename T, class ConstContT = std::span<const T>>
420+ void BroadcastTensor (ConstContT data, const std::vector<size_t >& shape, const std::vector<size_t >& targetShape, T * broadcastedData) {
421421 // Size of the shapes (tensor input here have shapes with same sizes, we have already added the needed ones )
422422 size_t size = shape.size ();
423423 // Current length of the broadcasted tensor
424424 size_t curLength = data.size ();
425- size_t targetLength = broadcastedData.size ();
426- assert (ConvertShapeToLength (targetShape) == targetLength);
427425 // special case when broadcasting last dimensions (initial shapes must be the same)
428426 if (size > 1 && shape.front () == targetShape.front () && shape.back () == 1 ) {
429427 size_t bsize = targetShape.back ();
@@ -433,16 +431,16 @@ void BroadcastTensor(ConstContT data, const std::vector<size_t>& shape, const st
433431 bsize *= targetShape[k];
434432 }
435433 for (size_t i = 0 ; i < curLength; i++) {
436- std::fill (broadcastedData. begin () + i*bsize, broadcastedData. begin () + (i+1 )*bsize , data[i]);
434+ std::fill (broadcastedData + i*bsize, broadcastedData + (i+1 )*bsize , data[i]);
437435 }
438436 return ;
439437 }
440438
441- std::copy (data.begin (), data.end (), broadcastedData. begin () );
439+ std::copy (data.begin (), data.end (), broadcastedData);
442440 // Product of the previous dimensions of targetShape
443441 size_t arrayNum = 1 ;
444442 // New broadcasted data: is this needed?
445- std::vector<T> newData (targetLength );
443+ std::vector<T> newData (ConvertShapeToLength (targetShape) );
446444
447445 for (size_t idx = 0 ; idx < size; idx++) {
448446 size_t dim = shape[idx];
@@ -458,8 +456,8 @@ void BroadcastTensor(ConstContT data, const std::vector<size_t>& shape, const st
458456 for (size_t arrayIdx = 0 ; arrayIdx < arrayNum; arrayIdx++) {
459457 for (size_t targetIdx = 0 ; targetIdx < targetDim; targetIdx++) {
460458 size_t offset = arrayIdx * arrayLength * targetDim + targetIdx * arrayLength;
461- std::copy (broadcastedData. begin () + arrayIdx * arrayLength,
462- broadcastedData. begin () + (arrayIdx + 1 ) * arrayLength,
459+ std::copy (broadcastedData + arrayIdx * arrayLength,
460+ broadcastedData + (arrayIdx + 1 ) * arrayLength,
463461 newData.begin () + offset);
464462 }
465463 }
@@ -473,23 +471,20 @@ void BroadcastTensor(ConstContT data, const std::vector<size_t>& shape, const st
473471 // Update current length
474472 curLength = newLength;
475473 // Update broadcasted data
476- std::copy (newData.begin (), newData.begin () + newLength, broadcastedData. begin () );
474+ std::copy (newData.begin (), newData.begin () + newLength, broadcastedData);
477475 }
478476 // Update the number of arrays
479477 arrayNum *= targetDim;
480478 }
481- // return broadcastedData;
482479}
483480
484481// interface where we allocate a new array for broadcasted data
485482template <typename T>
486483T* CreateBroadcastTensor (const T* data, const std::vector<size_t >& shape, const std::vector<size_t >& targetShape, size_t targetLength) {
487484 // newShape is an array of size equal to dimension along which we are broadcasting the tensor
488485 T* broadcastedData = new T[targetLength];
489- std::span<T> bData (broadcastedData, broadcastedData+targetLength);
490486 size_t curLength = ConvertShapeToLength (shape);
491- std::span<const T> inData (data, curLength);
492- BroadcastTensor<T, std::span<const T>, std::span<T>>(inData, shape, targetShape, bData);
487+ BroadcastTensor<T>({data, curLength}, shape, targetShape, broadcastedData);
493488 return broadcastedData;
494489}
495490// Unidirectional broadcasting shape to targetShape// In unidirectional broadcast - only tensor B can have the shape changed not
@@ -502,14 +497,14 @@ T* UnidirectionalBroadcast(const T* data, const std::vector<size_t>& shape, cons
502497 std::vector<size_t > newShape (targetSize, 1 );
503498 size_t offset = targetSize - shape.size ();
504499 std::copy (shape.begin (), shape.end (), newShape.begin () + offset);
505- return CreateBroadcastTensor<T> (data, newShape, targetShape, ConvertShapeToLength (targetShape));
500+ return CreateBroadcastTensor (data, newShape, targetShape, ConvertShapeToLength (targetShape));
506501 }
507- return CreateBroadcastTensor<T> (data, shape, targetShape, ConvertShapeToLength (targetShape));
502+ return CreateBroadcastTensor (data, shape, targetShape, ConvertShapeToLength (targetShape));
508503}
509504
510505// Unidirectional broadcasting shape to targetShape using a passed vector to avoid allocations
511506template <typename T>
512- void UnidirectionalBroadcast (const T* data, const std::vector<size_t >& shape, const std::vector<size_t >& targetShape, std::span<T> broadcastedData) {
507+ void UnidirectionalBroadcast (const T* data, const std::vector<size_t >& shape, const std::vector<size_t >& targetShape, T * broadcastedData) {
513508 size_t curLength = ConvertShapeToLength (shape);
514509 std::span<T> inData (const_cast <T*>(data), curLength);
515510 // Prepend shape with ones
@@ -518,9 +513,9 @@ void UnidirectionalBroadcast(const T* data, const std::vector<size_t>& shape, co
518513 std::vector<size_t > newShape (targetSize, 1 );
519514 size_t offset = targetSize - shape.size ();
520515 std::copy (shape.begin (), shape.end (), newShape.begin () + offset);
521- BroadcastTensor<T> (inData, newShape, targetShape, broadcastedData);
516+ BroadcastTensor (inData, newShape, targetShape, broadcastedData);
522517 }
523- BroadcastTensor<T, std::span<T>> (inData, shape, targetShape, broadcastedData);
518+ BroadcastTensor (inData, shape, targetShape, broadcastedData);
524519}
525520
526521// / compute stride of a tensor given its shape (assume layout is row-major)
0 commit comments