Merge pull request #29594 from abhishek-gola:bitcast_matmul_dft_layers

Added Bitcast layer & extended MatMul and DFT layers support - #29594

### 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
This commit is contained in:
Abhishek Gola
2026-09-01 12:53:57 +05:30
committed by GitHub
parent 16e83222dc
commit c7dd924be3
14 changed files with 542 additions and 90 deletions

View File

@@ -8,6 +8,8 @@
#include "cv2_util.hpp"
#include "opencv2/core/utils/logger.hpp"
#include <limits>
PyTypeObject* pyopencv_Mat_TypePtr = nullptr;
//======================================================================================================================
@@ -25,6 +27,25 @@ static std::string pycv_dumpArray(const T* arr, int n)
return out.str();
}
static bool int64ArrayFitsInt32(PyArrayObject* arr)
{
// Not GETCONTIGUOUS: PyArray_TYPE() also reports NPY_LONGLONG for byte-swapped dtypes.
PyArrayObject* contig = (PyArrayObject*)PyArray_FROM_OTF((PyObject*)arr, NPY_INT64, NPY_ARRAY_IN_ARRAY);
if (!contig)
{
PyErr_Clear();
return false;
}
const int64_t* data = (const int64_t*)PyArray_DATA(contig);
const npy_intp total = PyArray_SIZE(contig);
bool fits = true;
for (npy_intp i = 0; i < total && fits; i++)
fits = data[i] >= (int64_t)std::numeric_limits<int32_t>::min() &&
data[i] <= (int64_t)std::numeric_limits<int32_t>::max();
Py_DECREF(contig);
return fits;
}
static inline std::string getArrayTypeName(PyArrayObject* arr)
{
PyArray_Descr* dtype = PyArray_DESCR(arr);
@@ -133,19 +154,18 @@ bool pyopencv_to(PyObject* o, Mat& m, const ArgInfo& info)
if( type < 0 )
{
if( typenum == NPY_INT64 || typenum == NPY_LONG || typenum == NPY_LONGLONG )
{
needcopy = needcast = true;
new_typenum = NPY_INT;
type = CV_32S;
}
else
{
const std::string dtype_name = getArrayTypeName(oarr);
failmsg("%s data type = %s is not supported", info.name,
dtype_name.c_str());
return false;
}
const std::string dtype_name = getArrayTypeName(oarr);
failmsg("%s data type = %s is not supported", info.name,
dtype_name.c_str());
return false;
}
// int64 is numpy's default int dtype: narrow for CV_32S APIs, but only losslessly.
if( type == CV_64S && int64ArrayFitsInt32(oarr) )
{
needcopy = needcast = true;
new_typenum = NPY_INT;
type = CV_32S;
}
#ifndef CV_MAX_DIM

View File

@@ -42,8 +42,10 @@ int numpyTypeToCvDepth(int typenum)
case NPY_SHORT: return CV_16S;
case NPY_UINT: return CV_32U;
case NPY_INT: return CV_32S;
case NPY_LONGLONG: return CV_64S;
case NPY_ULONGLONG: return CV_64U;
// 'long' is 64-bit on LP64 but 32-bit on LLP64, so decide by size, not by name.
case NPY_LONG: return NPY_SIZEOF_LONG == 8 ? CV_64S : CV_32S;
case NPY_ULONG: return NPY_SIZEOF_LONG == 8 ? CV_64U : CV_32U;
case NPY_HALF: return CV_16F;
case NPY_FLOAT: return CV_32F;