From e5b871fa7ea391169d7ca2be0e30f6a25535750c Mon Sep 17 00:00:00 2001 From: Abduragim Shtanchaev <44877829+Abdurrahheem@users.noreply.github.com> Date: Fri, 23 Aug 2024 16:25:48 +0400 Subject: [PATCH] Merge pull request #26059 from Abdurrahheem:ash/fix-einsum-allocation Einsum buffer allocation fix #26059 This PR fixed buffer allocation issue in Einsum layer that causes segmentation fault on 32bit platforms. Related issue #26008 ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [x] There is a reference to the original bug report and related work - [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [x] The feature is well documented and sample code can be built with the project CMake --- modules/dnn/src/layers/einsum_layer.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/modules/dnn/src/layers/einsum_layer.cpp b/modules/dnn/src/layers/einsum_layer.cpp index 4e3eca2378..59157763a1 100644 --- a/modules/dnn/src/layers/einsum_layer.cpp +++ b/modules/dnn/src/layers/einsum_layer.cpp @@ -459,6 +459,7 @@ public: { CV_TRACE_FUNCTION(); CV_TRACE_ARG_VALUE(name, "name", name.c_str()); + CV_CheckEQ((size_t)inputs_arr.total(), (size_t)numInputs, "Number of inputs in forward and inputs during graph constructions do not match"); if (inputs_arr.depth() == CV_16F) { @@ -541,7 +542,7 @@ public: // Use either the preprocessed inputs (if it is available) or the corresponding raw inputs result = pairwiseOperandProcess(!result.empty() ? result : rawInputs[0], !result.empty() ? tmpResult : homogenizedInputDims[0], - !preProcessedInputs[input].empty() ? preProcessedInputs[input] : rawInputs[input], + (!preProcessedInputs[input].empty()) ? preProcessedInputs[input] : rawInputs[input], homogenizedInputDims[input], reducedDims, isFinalPair); @@ -605,8 +606,8 @@ void LayerEinsumImpl::preProcessInputs(InputArrayOfArrays& inputs_arr) std::vector inputs; inputs_arr.getMatVector(inputs); - preProcessedInputs.reserve(inputs.size()); - homogenizedInputDims.reserve(inputs.size()); + preProcessedInputs.resize(inputs.size()); + homogenizedInputDims.resize(inputs.size()); int inputIter = 0; for(const Mat& input : inputs) @@ -615,6 +616,11 @@ void LayerEinsumImpl::preProcessInputs(InputArrayOfArrays& inputs_arr) // variable to hold processed version of the original input MatShape input_dims = shape(input); + if (input_dims.empty()){ + homogenizedInputDims[inputIter] = MatShape(numLetterIndices, 1); + ++inputIter; + continue; + } const auto& currSubscriptIndices = inputSubscriptIndices[inputIter]; @@ -667,9 +673,9 @@ void LayerEinsumImpl::preProcessInputs(InputArrayOfArrays& inputs_arr) { preprocessed = preprocessed.reshape(1, homogenizedInputDims_.size(), homogenizedInputDims_.data()); } + preProcessedInputs[inputIter] = preprocessed; + homogenizedInputDims[inputIter] = homogenizedInputDims_; - preProcessedInputs.emplace_back(preprocessed); - homogenizedInputDims.emplace_back(homogenizedInputDims_); ++inputIter; } }