From fb9cf7982dac87963452d420e51403e100883b47 Mon Sep 17 00:00:00 2001 From: nihui Date: Wed, 15 Feb 2023 22:48:03 +0800 Subject: [PATCH] eltwise 4d (#4529) --- src/layer/arm/eltwise_arm.cpp | 8 +++-- src/layer/arm/eltwise_arm_asimdhp.cpp | 8 +++-- src/layer/eltwise.cpp | 3 +- src/layer/loongarch/eltwise_loongarch.cpp | 3 +- src/layer/mips/eltwise_mips.cpp | 3 +- src/layer/vulkan/eltwise_vulkan.cpp | 20 +++++++---- src/layer/x86/eltwise_x86.cpp | 3 +- tests/test_eltwise.cpp | 44 +++++++++++++++++++++-- 8 files changed, 73 insertions(+), 19 deletions(-) diff --git a/src/layer/arm/eltwise_arm.cpp b/src/layer/arm/eltwise_arm.cpp index 2332a52ba..38517ebb7 100644 --- a/src/layer/arm/eltwise_arm.cpp +++ b/src/layer/arm/eltwise_arm.cpp @@ -60,9 +60,10 @@ int Eltwise_arm::forward(const std::vector& bottom_blobs, std::vector& const Mat& bottom_blob = bottom_blobs[0]; int w = bottom_blob.w; int h = bottom_blob.h; + int d = bottom_blob.d; int channels = bottom_blob.c; int elempack = bottom_blob.elempack; - int size = w * h * elempack; + int size = w * h * d * elempack; Mat& top_blob = top_blobs[0]; top_blob.create_like(bottom_blob, opt.blob_allocator); @@ -477,9 +478,10 @@ int Eltwise_arm::forward_bf16s(const std::vector& bottom_blobs, std::vector const Mat& bottom_blob = bottom_blobs[0]; int w = bottom_blob.w; int h = bottom_blob.h; + int d = bottom_blob.d; int channels = bottom_blob.c; int elempack = bottom_blob.elempack; - int size = w * h * elempack; + int size = w * h * d * elempack; Mat& top_blob = top_blobs[0]; top_blob.create_like(bottom_blob, opt.blob_allocator); @@ -705,7 +707,7 @@ int Eltwise_arm::forward_bf16s(const std::vector& bottom_blobs, std::vector return 0; } - Mat top_blob_fp32(w, h, channels, (size_t)4u * elempack, elempack, opt.workspace_allocator); + Mat top_blob_fp32(w, h, d, channels, (size_t)4u * elempack, elempack, opt.workspace_allocator); if (top_blob_fp32.empty()) return -100; diff --git a/src/layer/arm/eltwise_arm_asimdhp.cpp b/src/layer/arm/eltwise_arm_asimdhp.cpp index 212dccbdd..4335db6c3 100644 --- a/src/layer/arm/eltwise_arm_asimdhp.cpp +++ b/src/layer/arm/eltwise_arm_asimdhp.cpp @@ -26,9 +26,10 @@ int Eltwise_arm::forward_fp16s(const std::vector& bottom_blobs, std::vector const Mat& bottom_blob = bottom_blobs[0]; int w = bottom_blob.w; int h = bottom_blob.h; + int d = bottom_blob.d; int channels = bottom_blob.c; int elempack = bottom_blob.elempack; - int size = w * h * elempack; + int size = w * h * d * elempack; Mat& top_blob = top_blobs[0]; top_blob.create_like(bottom_blob, opt.blob_allocator); @@ -287,7 +288,7 @@ int Eltwise_arm::forward_fp16s(const std::vector& bottom_blobs, std::vector return 0; } - Mat top_blob_fp32(w, h, channels, (size_t)4u * elempack, elempack, opt.workspace_allocator); + Mat top_blob_fp32(w, h, d, channels, (size_t)4u * elempack, elempack, opt.workspace_allocator); if (top_blob_fp32.empty()) return -100; @@ -1097,9 +1098,10 @@ int Eltwise_arm::forward_fp16sa(const std::vector& bottom_blobs, std::vecto const Mat& bottom_blob = bottom_blobs[0]; int w = bottom_blob.w; int h = bottom_blob.h; + int d = bottom_blob.d; int channels = bottom_blob.c; int elempack = bottom_blob.elempack; - int size = w * h * elempack; + int size = w * h * d * elempack; Mat& top_blob = top_blobs[0]; top_blob.create_like(bottom_blob, opt.blob_allocator); diff --git a/src/layer/eltwise.cpp b/src/layer/eltwise.cpp index c561f8d5b..0a9d155dd 100644 --- a/src/layer/eltwise.cpp +++ b/src/layer/eltwise.cpp @@ -35,8 +35,9 @@ int Eltwise::forward(const std::vector& bottom_blobs, std::vector& top const Mat& bottom_blob = bottom_blobs[0]; int w = bottom_blob.w; int h = bottom_blob.h; + int d = bottom_blob.d; int channels = bottom_blob.c; - int size = w * h; + int size = w * h * d; Mat& top_blob = top_blobs[0]; top_blob.create_like(bottom_blob, opt.blob_allocator); diff --git a/src/layer/loongarch/eltwise_loongarch.cpp b/src/layer/loongarch/eltwise_loongarch.cpp index d803fc3db..0a6ca32c3 100644 --- a/src/layer/loongarch/eltwise_loongarch.cpp +++ b/src/layer/loongarch/eltwise_loongarch.cpp @@ -34,9 +34,10 @@ int Eltwise_loongarch::forward(const std::vector& bottom_blobs, std::vector const Mat& bottom_blob = bottom_blobs[0]; int w = bottom_blob.w; int h = bottom_blob.h; + int d = bottom_blob.d; int channels = bottom_blob.c; int elempack = bottom_blob.elempack; - int size = w * h * elempack; + int size = w * h * d * elempack; Mat& top_blob = top_blobs[0]; top_blob.create_like(bottom_blob, opt.blob_allocator); diff --git a/src/layer/mips/eltwise_mips.cpp b/src/layer/mips/eltwise_mips.cpp index e22a6cab1..c1457aee0 100644 --- a/src/layer/mips/eltwise_mips.cpp +++ b/src/layer/mips/eltwise_mips.cpp @@ -34,9 +34,10 @@ int Eltwise_mips::forward(const std::vector& bottom_blobs, std::vector const Mat& bottom_blob = bottom_blobs[0]; int w = bottom_blob.w; int h = bottom_blob.h; + int d = bottom_blob.d; int channels = bottom_blob.c; int elempack = bottom_blob.elempack; - int size = w * h * elempack; + int size = w * h * d * elempack; Mat& top_blob = top_blobs[0]; top_blob.create_like(bottom_blob, opt.blob_allocator); diff --git a/src/layer/vulkan/eltwise_vulkan.cpp b/src/layer/vulkan/eltwise_vulkan.cpp index eb37aebc1..e965d7518 100644 --- a/src/layer/vulkan/eltwise_vulkan.cpp +++ b/src/layer/vulkan/eltwise_vulkan.cpp @@ -38,7 +38,7 @@ int Eltwise_vulkan::create_pipeline(const Option& opt) int elempack = 1; if (shape.dims == 1) elempack = opt.use_shader_pack8 && shape.w % 8 == 0 ? 8 : shape.w % 4 == 0 ? 4 : 1; if (shape.dims == 2) elempack = opt.use_shader_pack8 && shape.h % 8 == 0 ? 8 : shape.h % 4 == 0 ? 4 : 1; - if (shape.dims == 3) elempack = opt.use_shader_pack8 && shape.c % 8 == 0 ? 8 : shape.c % 4 == 0 ? 4 : 1; + if (shape.dims == 3 || shape.dims == 4) elempack = opt.use_shader_pack8 && shape.c % 8 == 0 ? 8 : shape.c % 4 == 0 ? 4 : 1; size_t elemsize; if (opt.use_fp16_storage) @@ -57,14 +57,14 @@ int Eltwise_vulkan::create_pipeline(const Option& opt) Mat shape_packed; if (shape.dims == 1) shape_packed = Mat(shape.w / elempack, (void*)0, elemsize, elempack); if (shape.dims == 2) shape_packed = Mat(shape.w, shape.h / elempack, (void*)0, elemsize, elempack); - if (shape.dims == 3) shape_packed = Mat(shape.w, shape.h, shape.c / elempack, (void*)0, elemsize, elempack); + if (shape.dims == 3 || shape.dims == 4) shape_packed = Mat(shape.w, shape.h, shape.c / elempack, (void*)0, elemsize, elempack); std::vector specializations(2 + 5); specializations[0].i = op_type; specializations[1].i = coeffs.w == 0 ? 0 : 1; specializations[2 + 0].i = shape_packed.dims; specializations[2 + 1].i = shape_packed.w; - specializations[2 + 2].i = shape_packed.h; + specializations[2 + 2].i = shape_packed.h * shape_packed.d; specializations[2 + 3].i = shape_packed.c; specializations[2 + 4].i = shape_packed.cstep; @@ -87,6 +87,12 @@ int Eltwise_vulkan::create_pipeline(const Option& opt) local_size_xyz.h = std::min(4, shape_packed.h); local_size_xyz.c = std::min(4, shape_packed.c); } + if (shape_packed.dims == 4) + { + local_size_xyz.w = std::min(4, shape_packed.w); + local_size_xyz.h = std::min(4, shape_packed.h * shape_packed.d); + local_size_xyz.c = std::min(4, shape_packed.c); + } // pack1 if (shape.dims == 0 || elempack == 1) @@ -164,7 +170,7 @@ int Eltwise_vulkan::forward(const std::vector& bottom_blobs, std::vector< std::vector constants(5 + 2); constants[0].i = top_blob.dims; constants[1].i = top_blob.w; - constants[2].i = top_blob.h; + constants[2].i = top_blob.h * top_blob.d; constants[3].i = top_blob.c; constants[4].i = top_blob.cstep; constants[5].f = coeffs.w == 0 ? 1.f : coeffs[0]; @@ -186,7 +192,7 @@ int Eltwise_vulkan::forward(const std::vector& bottom_blobs, std::vector< std::vector constants(5 + 2); constants[0].i = top_blob.dims; constants[1].i = top_blob.w; - constants[2].i = top_blob.h; + constants[2].i = top_blob.h * top_blob.d; constants[3].i = top_blob.c; constants[4].i = top_blob.cstep; constants[5].f = 1.f; @@ -222,7 +228,7 @@ int Eltwise_vulkan::forward(const std::vector& bottom_blobs, std::ve std::vector constants(5 + 2); constants[0].i = top_blob.dims; constants[1].i = top_blob.w; - constants[2].i = top_blob.h; + constants[2].i = top_blob.h * top_blob.d; constants[3].i = top_blob.c; constants[4].i = 0; //top_blob.cstep; constants[5].f = coeffs.w == 0 ? 1.f : coeffs[0]; @@ -244,7 +250,7 @@ int Eltwise_vulkan::forward(const std::vector& bottom_blobs, std::ve std::vector constants(5 + 2); constants[0].i = top_blob.dims; constants[1].i = top_blob.w; - constants[2].i = top_blob.h; + constants[2].i = top_blob.h * top_blob.d; constants[3].i = top_blob.c; constants[4].i = 0; //top_blob.cstep; constants[5].f = 1.f; diff --git a/src/layer/x86/eltwise_x86.cpp b/src/layer/x86/eltwise_x86.cpp index 10fbbd4af..f1cf1f343 100644 --- a/src/layer/x86/eltwise_x86.cpp +++ b/src/layer/x86/eltwise_x86.cpp @@ -36,9 +36,10 @@ int Eltwise_x86::forward(const std::vector& bottom_blobs, std::vector& const Mat& bottom_blob = bottom_blobs[0]; int w = bottom_blob.w; int h = bottom_blob.h; + int d = bottom_blob.d; int channels = bottom_blob.c; int elempack = bottom_blob.elempack; - int size = w * h * elempack; + int size = w * h * d * elempack; Mat& top_blob = top_blobs[0]; top_blob.create_like(bottom_blob, opt.blob_allocator); diff --git a/tests/test_eltwise.cpp b/tests/test_eltwise.cpp index c721becda..25da0196c 100644 --- a/tests/test_eltwise.cpp +++ b/tests/test_eltwise.cpp @@ -36,7 +36,7 @@ static int test_eltwise(const std::vector& a, int op_type, const ncnn int ret = test_layer("Eltwise", pd, weights, a); if (ret != 0) { - fprintf(stderr, "test_eltwise failed a[0].dims=%d a[0]=(%d %d %d) op_type=%d", a[0].dims, a[0].w, a[0].h, a[0].c, op_type); + fprintf(stderr, "test_eltwise failed a[0].dims=%d a[0]=(%d %d %d %d) op_type=%d", a[0].dims, a[0].w, a[0].h, a[0].d, a[0].c, op_type); fprintf(stderr, " coeffs="); print_float_array(coeffs); fprintf(stderr, "\n"); @@ -315,6 +315,45 @@ static int test_eltwise_11() || test_eltwise(a, 2, RandomMat(5)); } +static int test_eltwise_12() +{ + std::vector a(2); + a[0] = RandomMat(31, 5, 3, 12); + a[1] = RandomMat(31, 5, 3, 12); + + std::vector b(3); + b[0] = RandomMat(32, 4, 5, 32); + b[1] = RandomMat(32, 4, 5, 32); + b[2] = RandomMat(32, 4, 5, 32); + + std::vector c(4); + c[0] = RandomMat(33, 6, 7, 7); + c[1] = RandomMat(33, 6, 7, 7); + c[2] = RandomMat(33, 6, 7, 7); + c[3] = RandomMat(33, 6, 7, 7); + + return 0 + || test_eltwise(a, 0, ncnn::Mat()) + || test_eltwise(a, 1, ncnn::Mat()) + || test_eltwise(a, 2, ncnn::Mat()) + || test_eltwise(b, 0, ncnn::Mat()) + || test_eltwise(b, 1, ncnn::Mat()) + || test_eltwise(b, 2, ncnn::Mat()) + || test_eltwise(c, 0, ncnn::Mat()) + || test_eltwise(c, 1, ncnn::Mat()) + || test_eltwise(c, 2, ncnn::Mat()) + + || test_eltwise(a, 0, RandomMat(2)) + || test_eltwise(a, 1, RandomMat(2)) + || test_eltwise(a, 2, RandomMat(2)) + || test_eltwise(b, 0, RandomMat(3)) + || test_eltwise(b, 1, RandomMat(3)) + || test_eltwise(b, 2, RandomMat(3)) + || test_eltwise(c, 0, RandomMat(4)) + || test_eltwise(c, 1, RandomMat(4)) + || test_eltwise(c, 2, RandomMat(4)); +} + int main() { SRAND(7767517); @@ -331,5 +370,6 @@ int main() || test_eltwise_8() || test_eltwise_9() || test_eltwise_10() - || test_eltwise_11(); + || test_eltwise_11() + || test_eltwise_12(); }