mirror of
https://github.com/opencv/opencv.git
synced 2026-10-05 04:03:32 +03:00
Merge pull request #30080 from pratham-mcw:invert_opt_5.x
core: add ARMPL HAL backend for cv::invert(DECOMP_LU) - #30080 ## Summary - Follow-up to #[30035](https://github.com/opencv/opencv/pull/30035) to apply the same `cv::invert` optimization to the 5.x branch. - Adds an ARM Performance Library (ArmPL) HAL backend for cv::invert under DECOMP_LU (cv_hal_LU32f / cv_hal_LU64f), replacing OpenCV's default LU decomposition path with ArmPL's LAPACKE_sgesv / LAPACKE_dgesv for float and double matrices on AArch64. ## Changes **hal/armpl/include/armpl_hal_core.hpp:** - Declare armpl_hal_LU32f / armpl_hal_LU64f and register them as cv_hal_LU32f / cv_hal_LU64f. **hal/armpl/src/armpl_hal_core.cpp:** - Add armpl_lu() function (works for both float and double), that does the LU decomposition of the matrix: - If a right-hand side b is given, then LAPACKE_sgesv/dgesv is called. - If no right-hand side is given, it only factorizes the matrix using LAPACKE_sgetrf/dgetrf - Fall back to OpenCV's default (non-HAL) implementation for small matrices (m < 100).
This commit is contained in:
1 parent
e6f8c94063
commit
08f84c19c2
2 files changed
+70
No files matched your search
@@ -108,6 +108,14 @@ int armpl_hal_gemm64fc(const double* src1, size_t src1_step, const double* src2,
|
||||
#undef cv_hal_gemm64fc
|
||||
#define cv_hal_gemm64fc armpl_hal_gemm64fc
|
||||
|
||||
int armpl_hal_LU32f(float* a, size_t a_step, int m, float* b, size_t b_step, int n, int* info);
|
||||
int armpl_hal_LU64f(double* a, size_t a_step, int m, double* b, size_t b_step, int n, int* info);
|
||||
|
||||
#undef cv_hal_LU32f
|
||||
#define cv_hal_LU32f armpl_hal_LU32f
|
||||
#undef cv_hal_LU64f
|
||||
#define cv_hal_LU64f armpl_hal_LU64f
|
||||
|
||||
#endif // HAVE_ARMPL
|
||||
|
||||
#endif // OPENCV_ARMPL_HAL_CORE_HPP
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include <fftw3.h>
|
||||
#include <cblas.h>
|
||||
#include <lapacke.h>
|
||||
#include <algorithm>
|
||||
#include <complex>
|
||||
#include <cstring>
|
||||
@@ -11,6 +12,7 @@
|
||||
#include <cmath>
|
||||
|
||||
#define ARMPL_GEMM_MIN_WORK_VOLUME 10000
|
||||
#define ARMPL_LU_SMALL_MATRIX_THRESH 100
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -172,6 +174,66 @@ int armpl_hal_gemm64fc(const double *src1, size_t src1_step, const double *src2,
|
||||
reinterpret_cast<const cplx*>(src3), src3_step, beta, reinterpret_cast<cplx*>(dst), dst_step, m, n, k, flags);
|
||||
}
|
||||
|
||||
static inline armpl_int_t armpl_lapacke_gesv(int m, int n, float *a, int lda, armpl_int_t *ipiv, float *b, int ldb){
|
||||
return LAPACKE_sgesv(LAPACK_ROW_MAJOR, m, n, a, lda, ipiv, b, ldb);
|
||||
}
|
||||
static inline armpl_int_t armpl_lapacke_gesv(int m, int n, double *a, int lda, armpl_int_t *ipiv, double *b, int ldb){
|
||||
return LAPACKE_dgesv(LAPACK_ROW_MAJOR, m, n, a, lda, ipiv, b, ldb);
|
||||
}
|
||||
static inline armpl_int_t armpl_lapacke_getrf(int m, float *a, int lda, armpl_int_t *ipiv){
|
||||
return LAPACKE_sgetrf(LAPACK_ROW_MAJOR, m, m, a, lda, ipiv);
|
||||
}
|
||||
static inline armpl_int_t armpl_lapacke_getrf(int m, double *a, int lda, armpl_int_t *ipiv){
|
||||
return LAPACKE_dgetrf(LAPACK_ROW_MAJOR, m, m, a, lda, ipiv);
|
||||
}
|
||||
|
||||
template <typename fptype> static inline int
|
||||
armpl_lu(fptype *a, size_t a_step, int m, fptype *b, size_t b_step, int n, int *info)
|
||||
{
|
||||
if(!info)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
int lda = (int)(a_step / sizeof(fptype));
|
||||
std::vector<armpl_int_t> ipiv(m);
|
||||
armpl_int_t linfo;
|
||||
|
||||
if (b)
|
||||
{
|
||||
int ldb = (int)(b_step / sizeof(fptype));
|
||||
linfo = armpl_lapacke_gesv(m, n, a, lda, ipiv.data(), b, ldb);
|
||||
}
|
||||
else
|
||||
{
|
||||
linfo = armpl_lapacke_getrf(m, a, lda, ipiv.data());
|
||||
}
|
||||
|
||||
if (linfo < 0)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
if (linfo == 0)
|
||||
{
|
||||
int sign = 0;
|
||||
for (int i = 0; i < m; i++)
|
||||
sign ^= (ipiv[i] != i + 1);
|
||||
*info = sign ? -1 : 1;
|
||||
}
|
||||
else
|
||||
*info = 0;
|
||||
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
int armpl_hal_LU32f(float *a, size_t a_step, int m, float *b, size_t b_step, int n, int *info) {
|
||||
if (m < ARMPL_LU_SMALL_MATRIX_THRESH)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
return armpl_lu(a, a_step, m, b, b_step, n, info);
|
||||
}
|
||||
int armpl_hal_LU64f(double *a, size_t a_step, int m, double *b, size_t b_step, int n, int *info) {
|
||||
if (m < ARMPL_LU_SMALL_MATRIX_THRESH)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
return armpl_lu(a, a_step, m, b, b_step, n, info);
|
||||
}
|
||||
|
||||
enum ArmPLDFTMode
|
||||
{
|
||||
ARMPL_DFT_C2C,
|
||||
|
||||
Reference in new issue
Block a user