1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-31 00:03:03 +04:00
Files
Abhishek Gola bdf348c13a Merge pull request #28934 from abhishek-gola:mlas_gemm
Added MLAS third party module and integrated into GeMM path #28934

### 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
2026-05-22 20:22:15 +03:00

116 lines
2.3 KiB
C++

/*++
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the MIT License.
Module Name:
sgemm_pack_b_rvv.cpp
Abstract:
This module implements an RVV packing helper for the single precision
matrix/matrix multiply operation (SGEMM) on riscv64.
--*/
#include "mlasi.h"
#if defined(MLAS_USE_RVV)
#include <riscv_vector.h>
namespace {
// Keep MLAS packing in 16-column tiles, but let RVV decide the actual chunk
// size at runtime via vsetvl so the same code works across different VLENs.
constexpr size_t kPackedCountN = 16;
MLAS_FORCEINLINE
void
MlasStoreZeroPaddedBlock(
float* D,
const float* B,
size_t CountX
)
{
size_t remaining = kPackedCountN;
size_t offset = 0;
while (remaining > 0) {
const size_t vl = __riscv_vsetvl_e32m4(remaining);
__riscv_vse32_v_f32m4(D + offset, __riscv_vfmv_v_f_f32m4(0.0f, vl), vl);
offset += vl;
remaining -= vl;
}
remaining = CountX;
offset = 0;
while (remaining > 0) {
const size_t vl = __riscv_vsetvl_e32m4(remaining);
__riscv_vse32_v_f32m4(D + offset, __riscv_vle32_v_f32m4(B + offset, vl), vl);
offset += vl;
remaining -= vl;
}
}
MLAS_FORCEINLINE
void
MlasStoreFullBlock(
float* D,
const float* B
)
{
size_t remaining = kPackedCountN;
size_t offset = 0;
while (remaining > 0) {
const size_t vl = __riscv_vsetvl_e32m4(remaining);
__riscv_vse32_v_f32m4(D + offset, __riscv_vle32_v_f32m4(B + offset, vl), vl);
offset += vl;
remaining -= vl;
}
}
} // namespace
void
MlasSgemmCopyPackBRvv(
float* D,
const float* B,
size_t ldb,
size_t CountX,
size_t CountY
)
{
while (CountX >= kPackedCountN) {
const float* b = B;
size_t y = CountY;
do {
MlasStoreFullBlock(D, b);
D += kPackedCountN;
b += ldb;
y--;
} while (y > 0);
B += kPackedCountN;
CountX -= kPackedCountN;
}
if (CountX > 0) {
size_t y = CountY;
do {
MlasStoreZeroPaddedBlock(D, B, CountX);
D += kPackedCountN;
B += ldb;
y--;
} while (y > 0);
}
}
#endif // defined(MLAS_USE_RVV)