1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-29 07:13:02 +04:00

add accuracy test for fastGemmThin

This commit is contained in:
Teddy-Yangjiale
2026-07-23 10:17:18 +08:00
parent 7cc9947809
commit 6b04d456b3
+85
View File
@@ -0,0 +1,85 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "test_precomp.hpp"
namespace opencv_test { namespace {
static Mat referenceMatMul(const Mat& A, const Mat& B, bool trans_a, float alpha)
{
const int M = trans_a ? A.cols : A.rows;
const int K = trans_a ? A.rows : A.cols;
const int N = B.cols;
Mat expected(M, N, CV_32F);
for (int m = 0; m < M; m++)
{
float* dst = expected.ptr<float>(m);
for (int n = 0; n < N; n++)
{
float acc = 0.f;
for (int k = 0; k < K; k++)
{
const float a = trans_a ? A.ptr<float>(k)[m] : A.ptr<float>(m)[k];
acc += a * B.ptr<float>(k)[n];
}
dst[n] = alpha * acc;
}
}
return expected;
}
// Exercises the fastGemmThin path (constant-B MatMul): M covers every register
// block width and the multi-block remainder, N covers full strips and partial
// column tails for any VLEN <= 512.
TEST(DNN_FastGemmThin, MatMulAccuracy)
{
static const int m_values[] = { 1, 2, 3, 4, 5 };
static const int k_values[] = { 1, 3, 4, 7, 16, 64 };
static const int n_values[] = { 16, 19, 64, 67, 80, 83 };
static const float alpha_values[] = { 1.f, -0.5f };
RNG rng(0x5EED);
for (int M : m_values)
{
for (int N : n_values)
{
for (int K : k_values)
{
Mat B(K, N, CV_32F);
rng.fill(B, RNG::UNIFORM, -1.f, 1.f);
for (int trans_a = 0; trans_a <= 1; trans_a++)
{
Mat A(trans_a ? K : M, trans_a ? M : K, CV_32F);
rng.fill(A, RNG::UNIFORM, -1.f, 1.f);
for (float alpha : alpha_values)
{
LayerParams lp;
lp.type = "MatMul";
lp.name = "thin_matmul";
lp.set("transA", trans_a != 0);
lp.set("transB", false);
lp.set("alpha", alpha);
lp.blobs.push_back(B);
Net net;
net.addLayerToPrev(lp.name, lp.type, lp);
net.setInputsNames(std::vector<String>{ "A" });
net.setInput(A, "A");
Mat actual = net.forward();
Mat expected = referenceMatMul(A, B, trans_a != 0, alpha);
EXPECT_LE(cv::norm(expected, actual, NORM_INF), 2e-5f * std::max(K, 1))
<< "M=" << M << ", N=" << N << ", K=" << K
<< ", trans_a=" << trans_a << ", alpha=" << alpha;
}
}
}
}
}
}
}} // namespace