MCPcopy Create free account
hub / github.com/alibaba/MNN / reference_conv2d

Function reference_conv2d

test/op/ConvolutionTest.cpp:27–88  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

25using namespace MNN;
26using namespace MNN::Express;
27static void reference_conv2d(const std::vector<float>& input, const std::vector<float>& weight,
28 const std::vector<float>& bias, std::vector<float>& output, std::vector<float>& outputDataSeparateBias, int batch, int ic, int oc,
29 int ih, int iw, PadMode mode, int pad_h, int pad_w, int kh, int kw, int stride,
30 int dilation, int group, ConvertFP32 functor) {
31 int oh, ow;
32 if (mode == PadMode_SAME) {
33 oh = (ih + stride - 1) / stride; // oh = ceil(ih / stride)
34 ow = (iw + stride - 1) / stride; // ow = ceil(iw / stride)
35 pad_h = ((oh - 1) * stride + (kh - 1) * dilation + 1 - ih) / 2;
36 pad_w = ((ow - 1) * stride + (kw - 1) * dilation + 1 - iw) / 2;
37 } else {
38 if (mode == PadMode_VALID) {
39 pad_h = pad_w = 0;
40 }
41 oh = (ih + 2 * pad_h - (kh - 1) * dilation - 1) / stride + 1;
42 ow = (iw + 2 * pad_w - (kw - 1) * dilation - 1) / stride + 1;
43 }
44
45 MNN_ASSERT(oc % group == 0 && ic % group == 0);
46 if (oh <= 0 || ow <= 0) {
47 output.clear();
48 return;
49 }
50 output.resize(batch * oh * ow * oc);
51 /*
52 In CPUConvolutionDepthwise, bias function 'MNNAxByClampBroadcastUnit' is called separately with MNNConvRunForLineDepthwise,
53 this would affect the precision when using bf16 or fp16.
54 winograd convolution also did this.
55 we keep the two result for checking.
56 */
57 outputDataSeparateBias.resize(batch * oh * ow * oc);
58
59 int ocGroup = oc / group, icGroup = ic / group;
60 for (int b = 0; b < batch; ++b) {
61 for (int oz = 0; oz < oc; ++oz) {
62 int gId = oz / ocGroup;
63 for (int oy = 0; oy < oh; ++oy) {
64 for (int ox = 0; ox < ow; ++ox) {
65 float sum = 0;
66 auto destOffset = ((b * oc + oz) * oh + oy) * ow + ox;
67 for (int sz = gId * icGroup; sz < (gId + 1) * icGroup; ++sz) {
68 for (int ky = 0; ky < kh; ++ky) {
69 for (int kx = 0; kx < kw; ++kx) {
70 int ix = ox * stride + kx * dilation - pad_w, iy = oy * stride + ky * dilation - pad_h;
71 float xValue = 0.0f;
72 if (ix >= 0 && ix < iw && iy >= 0 && iy < ih) {
73 xValue = input[(((b * ic + sz) * ih + iy) * iw + ix)];
74 }
75 float convertX = functor(xValue);
76 float convertW = functor(weight[(((gId * ocGroup + oz % ocGroup) * icGroup + sz % icGroup) * kh + ky) * kw + kx]);
77 sum += convertX * convertW;
78 }
79 }
80 }
81
82 output[destOffset] = functor(sum + functor(bias[oz]));
83 outputDataSeparateBias[destOffset] = functor(functor(sum) + functor(bias[oz]));
84 }

Callers 2

testMethod · 0.85
testUnitMethod · 0.85

Calls 2

clearMethod · 0.45
resizeMethod · 0.45

Tested by

no test coverage detected