From e8052e830e5653dcde1005e327f8de29bd457e13 Mon Sep 17 00:00:00 2001 From: nihui Date: Tue, 21 Jan 2020 23:34:29 +0800 Subject: [PATCH] add more pack8 shaders --- .../shader/instancenorm_coeffs_pack8.comp | 65 +++++ .../shader/instancenorm_norm_pack8.comp | 61 +++++ .../instancenorm_reduce_mean_pack8.comp | 64 +++++ ...cenorm_reduce_sum4_fp16_to_fp32_pack8.comp | 92 +++++++ .../instancenorm_reduce_sum4_fp32_pack8.comp | 92 +++++++ .../instancenorm_sub_mean_square_pack8.comp | 62 +++++ .../vulkan/shader/normalize_coeffs_pack8.comp | 79 ++++++ .../vulkan/shader/normalize_norm_pack8.comp | 91 +++++++ ...malize_reduce_sum4_fp16_to_fp32_pack4.comp | 64 +++-- ...malize_reduce_sum4_fp16_to_fp32_pack8.comp | 227 ++++++++++++++++++ .../normalize_reduce_sum4_fp32_pack8.comp | 203 ++++++++++++++++ src/layer/vulkan/shader/permute_pack8to1.comp | 123 ++++++++++ 12 files changed, 1188 insertions(+), 35 deletions(-) create mode 100644 src/layer/vulkan/shader/instancenorm_coeffs_pack8.comp create mode 100644 src/layer/vulkan/shader/instancenorm_norm_pack8.comp create mode 100644 src/layer/vulkan/shader/instancenorm_reduce_mean_pack8.comp create mode 100644 src/layer/vulkan/shader/instancenorm_reduce_sum4_fp16_to_fp32_pack8.comp create mode 100644 src/layer/vulkan/shader/instancenorm_reduce_sum4_fp32_pack8.comp create mode 100644 src/layer/vulkan/shader/instancenorm_sub_mean_square_pack8.comp create mode 100644 src/layer/vulkan/shader/normalize_coeffs_pack8.comp create mode 100644 src/layer/vulkan/shader/normalize_norm_pack8.comp create mode 100644 src/layer/vulkan/shader/normalize_reduce_sum4_fp16_to_fp32_pack8.comp create mode 100644 src/layer/vulkan/shader/normalize_reduce_sum4_fp32_pack8.comp create mode 100644 src/layer/vulkan/shader/permute_pack8to1.comp diff --git a/src/layer/vulkan/shader/instancenorm_coeffs_pack8.comp b/src/layer/vulkan/shader/instancenorm_coeffs_pack8.comp new file mode 100644 index 000000000..380b0c613 --- /dev/null +++ b/src/layer/vulkan/shader/instancenorm_coeffs_pack8.comp @@ -0,0 +1,65 @@ +// Tencent is pleased to support the open source community by making ncnn available. +// +// Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// https://opensource.org/licenses/BSD-3-Clause +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#version 450 + +#if NCNN_fp16_storage +#extension GL_EXT_shader_16bit_storage: require +struct sfpvec8 { f16vec4 abcd; f16vec4 efgh; }; +#endif +#if NCNN_fp16_arithmetic +#extension GL_EXT_shader_explicit_arithmetic_types_float16: require +#endif + +layout (constant_id = 0) const float eps = 0; + +layout (local_size_x_id = 233) in; +layout (local_size_y_id = 234) in; +layout (local_size_z_id = 235) in; + +layout (binding = 0) writeonly buffer coeffs_blob { sfpvec8 coeffs_blob_data[]; }; +layout (binding = 1) readonly buffer mean_blob { sfpvec8 mean_data[]; }; +layout (binding = 2) readonly buffer var_blob { sfpvec8 var_data[]; }; +layout (binding = 3) readonly buffer gamma_blob { sfpvec8 gamma_data[]; }; +layout (binding = 4) readonly buffer beta_blob { sfpvec8 beta_data[]; }; + +layout (push_constant) uniform parameter +{ + int w; +} p; + +void main() +{ + int gx = int(gl_GlobalInvocationID.x); + int gy = int(gl_GlobalInvocationID.y); + int gz = int(gl_GlobalInvocationID.z); + + if (gx >= p.w || gy >= 1 || gz >= 1) + return; + + afpvec8 mean = buffer_ld8(mean_data, gx); + afpvec8 var = buffer_ld8(var_data, gx); + afpvec8 gamma = buffer_ld8(gamma_data, gx); + afpvec8 beta = buffer_ld8(beta_data, gx); + + afpvec8 a; + afpvec8 b; + a[0] = gamma[0] / (sqrt(var[0] + afp(eps))); + a[1] = gamma[1] / (sqrt(var[1] + afp(eps))); + b[0] = - mean[0] * a[0] + beta[0]; + b[1] = - mean[1] * a[1] + beta[1]; + + buffer_st8(coeffs_blob_data, gx*2, a); + buffer_st8(coeffs_blob_data, gx*2 +1, b); +} diff --git a/src/layer/vulkan/shader/instancenorm_norm_pack8.comp b/src/layer/vulkan/shader/instancenorm_norm_pack8.comp new file mode 100644 index 000000000..a92e8887a --- /dev/null +++ b/src/layer/vulkan/shader/instancenorm_norm_pack8.comp @@ -0,0 +1,61 @@ +// Tencent is pleased to support the open source community by making ncnn available. +// +// Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// https://opensource.org/licenses/BSD-3-Clause +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#version 450 + +#if NCNN_fp16_storage +#extension GL_EXT_shader_16bit_storage: require +struct sfpvec8 { f16vec4 abcd; f16vec4 efgh; }; +#endif +#if NCNN_fp16_arithmetic +#extension GL_EXT_shader_explicit_arithmetic_types_float16: require +#endif + +layout (local_size_x_id = 233) in; +layout (local_size_y_id = 234) in; +layout (local_size_z_id = 235) in; + +layout (binding = 0) buffer bottom_top_blob { sfpvec8 bottom_top_blob_data[]; }; +layout (binding = 1) readonly buffer coeffs_blob { sfpvec8 coeffs_blob_data[]; }; + +layout (push_constant) uniform parameter +{ + int dims; + int w; + int h; + int c; + int cstep; +} p; + +void main() +{ + int gx = int(gl_GlobalInvocationID.x); + int gy = int(gl_GlobalInvocationID.y); + int gz = int(gl_GlobalInvocationID.z); + + if (gx >= p.w || gy >= p.h || gz >= p.c) + return; + + const int gi = gz * p.cstep + gy * p.w + gx; + + afpvec8 v = buffer_ld8(bottom_top_blob_data, gi); + + afpvec8 a = buffer_ld8(coeffs_blob_data, gz*2); + afpvec8 b = buffer_ld8(coeffs_blob_data, gz*2 +1); + + v[0] = v[0] * a[0] + b[0]; + v[1] = v[1] * a[1] + b[1]; + + buffer_st8(bottom_top_blob_data, gi, v); +} diff --git a/src/layer/vulkan/shader/instancenorm_reduce_mean_pack8.comp b/src/layer/vulkan/shader/instancenorm_reduce_mean_pack8.comp new file mode 100644 index 000000000..deca3e0e6 --- /dev/null +++ b/src/layer/vulkan/shader/instancenorm_reduce_mean_pack8.comp @@ -0,0 +1,64 @@ +// Tencent is pleased to support the open source community by making ncnn available. +// +// Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// https://opensource.org/licenses/BSD-3-Clause +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#version 450 + +#if NCNN_fp16_storage +#extension GL_EXT_shader_16bit_storage: require +struct sfpvec8 { f16vec4 abcd; f16vec4 efgh; }; +#endif +#if NCNN_fp16_arithmetic +#extension GL_EXT_shader_explicit_arithmetic_types_float16: require +#endif + +layout (local_size_x_id = 233) in; +layout (local_size_y_id = 234) in; +layout (local_size_z_id = 235) in; + +layout (binding = 0) readonly buffer bottom_top_blob { mat2x4 bottom_top_blob_data[]; }; +layout (binding = 1) writeonly buffer mean_blob { sfpvec8 mean_data[]; }; + +layout (push_constant) uniform parameter +{ + int size; + int c; + int cstep; + float area; +} p; + +void main() +{ + int gx = int(gl_GlobalInvocationID.x); + int gy = int(gl_GlobalInvocationID.y); + int gz = int(gl_GlobalInvocationID.z); + + if (gx >= p.c || gy >= 1 || gz >= 1) + return; + + afpvec8 sum = afpvec8(afpvec4(0.f), afpvec4(0.f)); + + int v_offset = gx * p.cstep; + + for (int i = 0; i < p.size; i++) + { + sum += afpvec8(bottom_top_blob_data[v_offset]); + v_offset += 1; + } + + afpvec8 mean; + mean[0] = sum[0] / afp(p.area); + mean[1] = sum[1] / afp(p.area); + + buffer_st8(mean_data, gx, mean); +} diff --git a/src/layer/vulkan/shader/instancenorm_reduce_sum4_fp16_to_fp32_pack8.comp b/src/layer/vulkan/shader/instancenorm_reduce_sum4_fp16_to_fp32_pack8.comp new file mode 100644 index 000000000..5a01e29e2 --- /dev/null +++ b/src/layer/vulkan/shader/instancenorm_reduce_sum4_fp16_to_fp32_pack8.comp @@ -0,0 +1,92 @@ +// Tencent is pleased to support the open source community by making ncnn available. +// +// Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// https://opensource.org/licenses/BSD-3-Clause +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#version 450 + +#if NCNN_fp16_storage +#extension GL_EXT_shader_16bit_storage: require +struct sfpvec8 { f16vec4 abcd; f16vec4 efgh; }; +#endif +#if NCNN_fp16_arithmetic +#extension GL_EXT_shader_explicit_arithmetic_types_float16: require +#endif + +layout (local_size_x_id = 233) in; +layout (local_size_y_id = 234) in; +layout (local_size_z_id = 235) in; + +layout (binding = 0) readonly buffer bottom_top_blob { sfpvec8 bottom_top_blob_data[]; }; +layout (binding = 1) writeonly buffer sum_blob { mat2x4 sum_blob_data[]; }; + +layout (push_constant) uniform parameter +{ + int size; + int c; + int cstep; + + int outsize; + int outc; + int outcstep; +} p; + +void main() +{ + int gx = int(gl_GlobalInvocationID.x); + int gy = int(gl_GlobalInvocationID.y); + int gz = int(gl_GlobalInvocationID.z); + + if (gx >= p.outsize || gy >= 1 || gz >= p.outc) + return; + + int gi = gz * p.outcstep + gx; + + int sx = gx * 4; + + int v_offset = gz * p.cstep + sx; + + if (sx == p.size - 1) + { + sum_blob_data[gi] = mat2x4(buffer_ld8(bottom_top_blob_data, v_offset)); + } + else if (sx == p.size - 2) + { + mat2x4 v0 = mat2x4(buffer_ld8(bottom_top_blob_data, v_offset)); + mat2x4 v1 = mat2x4(buffer_ld8(bottom_top_blob_data, v_offset + 1)); + + mat2x4 sum = v0 + v1; + + sum_blob_data[gi] = sum; + } + else if (sx == p.size - 3) + { + mat2x4 v0 = mat2x4(buffer_ld8(bottom_top_blob_data, v_offset)); + mat2x4 v1 = mat2x4(buffer_ld8(bottom_top_blob_data, v_offset + 1)); + mat2x4 v2 = mat2x4(buffer_ld8(bottom_top_blob_data, v_offset + 2)); + + mat2x4 sum = v0 + v1 + v2; + + sum_blob_data[gi] = sum; + } + else + { + mat2x4 v0 = mat2x4(buffer_ld8(bottom_top_blob_data, v_offset)); + mat2x4 v1 = mat2x4(buffer_ld8(bottom_top_blob_data, v_offset + 1)); + mat2x4 v2 = mat2x4(buffer_ld8(bottom_top_blob_data, v_offset + 2)); + mat2x4 v3 = mat2x4(buffer_ld8(bottom_top_blob_data, v_offset + 3)); + + mat2x4 sum = v0 + v1 + v2 + v3; + + sum_blob_data[gi] = sum; + } +} diff --git a/src/layer/vulkan/shader/instancenorm_reduce_sum4_fp32_pack8.comp b/src/layer/vulkan/shader/instancenorm_reduce_sum4_fp32_pack8.comp new file mode 100644 index 000000000..ec8f3b8f8 --- /dev/null +++ b/src/layer/vulkan/shader/instancenorm_reduce_sum4_fp32_pack8.comp @@ -0,0 +1,92 @@ +// Tencent is pleased to support the open source community by making ncnn available. +// +// Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// https://opensource.org/licenses/BSD-3-Clause +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#version 450 + +#if NCNN_fp16_storage +#extension GL_EXT_shader_16bit_storage: require +struct sfpvec8 { f16vec4 abcd; f16vec4 efgh; }; +#endif +#if NCNN_fp16_arithmetic +#extension GL_EXT_shader_explicit_arithmetic_types_float16: require +#endif + +layout (local_size_x_id = 233) in; +layout (local_size_y_id = 234) in; +layout (local_size_z_id = 235) in; + +layout (binding = 0) readonly buffer square_blob { mat2x4 square_blob_data[]; }; +layout (binding = 1) writeonly buffer sqsum_blob { mat2x4 sqsum_blob_data[]; }; + +layout (push_constant) uniform parameter +{ + int size; + int c; + int cstep; + + int outsize; + int outc; + int outcstep; +} p; + +void main() +{ + int gx = int(gl_GlobalInvocationID.x); + int gy = int(gl_GlobalInvocationID.y); + int gz = int(gl_GlobalInvocationID.z); + + if (gx >= p.outsize || gy >= 1 || gz >= p.outc) + return; + + int gi = gz * p.outcstep + gx; + + int sx = gx * 4; + + int v_offset = gz * p.cstep + sx; + + if (sx == p.size - 1) + { + sqsum_blob_data[gi] = square_blob_data[v_offset]; + } + else if (sx == p.size - 2) + { + mat2x4 v0 = square_blob_data[v_offset]; + mat2x4 v1 = square_blob_data[v_offset + 1]; + + mat2x4 sum = v0 + v1; + + sqsum_blob_data[gi] = sum; + } + else if (sx == p.size - 3) + { + mat2x4 v0 = square_blob_data[v_offset]; + mat2x4 v1 = square_blob_data[v_offset + 1]; + mat2x4 v2 = square_blob_data[v_offset + 2]; + + mat2x4 sum = v0 + v1 + v2; + + sqsum_blob_data[gi] = sum; + } + else + { + mat2x4 v0 = square_blob_data[v_offset]; + mat2x4 v1 = square_blob_data[v_offset + 1]; + mat2x4 v2 = square_blob_data[v_offset + 2]; + mat2x4 v3 = square_blob_data[v_offset + 3]; + + mat2x4 sum = v0 + v1 + v2 + v3; + + sqsum_blob_data[gi] = sum; + } +} diff --git a/src/layer/vulkan/shader/instancenorm_sub_mean_square_pack8.comp b/src/layer/vulkan/shader/instancenorm_sub_mean_square_pack8.comp new file mode 100644 index 000000000..b00b72781 --- /dev/null +++ b/src/layer/vulkan/shader/instancenorm_sub_mean_square_pack8.comp @@ -0,0 +1,62 @@ +// Tencent is pleased to support the open source community by making ncnn available. +// +// Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// https://opensource.org/licenses/BSD-3-Clause +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#version 450 + +#if NCNN_fp16_storage +#extension GL_EXT_shader_16bit_storage: require +struct sfpvec8 { f16vec4 abcd; f16vec4 efgh; }; +#endif +#if NCNN_fp16_arithmetic +#extension GL_EXT_shader_explicit_arithmetic_types_float16: require +#endif + +layout (local_size_x_id = 233) in; +layout (local_size_y_id = 234) in; +layout (local_size_z_id = 235) in; + +layout (binding = 0) readonly buffer bottom_top_blob { sfpvec8 bottom_top_blob_data[]; }; +layout (binding = 1) readonly buffer mean_blob { sfpvec8 mean_data[]; }; +layout (binding = 2) writeonly buffer square_blob { mat2x4 square_blob_data[]; }; + +layout (push_constant) uniform parameter +{ + int dims; + int w; + int h; + int c; + int cstep; +} p; + +void main() +{ + int gx = int(gl_GlobalInvocationID.x); + int gy = int(gl_GlobalInvocationID.y); + int gz = int(gl_GlobalInvocationID.z); + + if (gx >= p.w || gy >= p.h || gz >= p.c) + return; + + const int gi = gz * p.cstep + gy * p.w + gx; + + afpvec8 v = buffer_ld8(bottom_top_blob_data, gi); + afpvec8 mean = buffer_ld8(mean_data, gz); + + v[0] = v[0] - mean[0]; + v[1] = v[1] - mean[1]; + v[0] = v[0] * v[0]; + v[1] = v[1] * v[1]; + + square_blob_data[gi] = mat2x4(v); +} diff --git a/src/layer/vulkan/shader/normalize_coeffs_pack8.comp b/src/layer/vulkan/shader/normalize_coeffs_pack8.comp new file mode 100644 index 000000000..3f8b1db97 --- /dev/null +++ b/src/layer/vulkan/shader/normalize_coeffs_pack8.comp @@ -0,0 +1,79 @@ +// Tencent is pleased to support the open source community by making ncnn available. +// +// Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// https://opensource.org/licenses/BSD-3-Clause +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#version 450 + +#if NCNN_fp16_storage +#extension GL_EXT_shader_16bit_storage: require +struct sfpvec8 { f16vec4 abcd; f16vec4 efgh; }; +#endif +#if NCNN_fp16_arithmetic +#extension GL_EXT_shader_explicit_arithmetic_types_float16: require +#endif + +layout (constant_id = 0) const float eps = 0.f; +layout (constant_id = 1) const int eps_mode = 0; + +layout (local_size_x_id = 233) in; +layout (local_size_y_id = 234) in; +layout (local_size_z_id = 235) in; + +layout (binding = 0) readonly buffer sqsum_blob { mat2x4 sqsum_blob_data[]; }; +layout (binding = 1) writeonly buffer coeffs_blob { sfpvec8 coeffs_blob_data[]; }; + +layout (push_constant) uniform parameter +{ + int size; + int c; + int cstep; +} p; + +void main() +{ + int gx = int(gl_GlobalInvocationID.x); + int gy = int(gl_GlobalInvocationID.y); + int gz = int(gl_GlobalInvocationID.z); + + if (gx >= p.size || gy >= 1 || gz >= p.c) + return; + + int gi = gz * p.cstep + gx; + + mat2x4 sqsum_8 = sqsum_blob_data[gi]; + + vec4 sqsum_4 = sqsum_8[0] + sqsum_8[1]; + + afp sqsum = afp(sqsum_4.r + sqsum_4.g + sqsum_4.b + sqsum_4.a); + + afp a; + + if (eps_mode == 0) // caffe/mxnet + { + a = afp(1.f) / sqrt(sqsum + afp(eps)); + } + + if (eps_mode == 1) // pytorch + { + a = afp(1.f) / max(sqrt(sqsum), afp(eps)); + } + + if (eps_mode == 2) // tensorflow + { + a = afp(1.f) / sqrt(max(sqsum, afp(eps))); + } + + afpvec8 a8 = afpvec8(afpvec4(a), afpvec4(a)); + + buffer_st8(coeffs_blob_data, gi, a8); +} diff --git a/src/layer/vulkan/shader/normalize_norm_pack8.comp b/src/layer/vulkan/shader/normalize_norm_pack8.comp new file mode 100644 index 000000000..b31b385f9 --- /dev/null +++ b/src/layer/vulkan/shader/normalize_norm_pack8.comp @@ -0,0 +1,91 @@ +// Tencent is pleased to support the open source community by making ncnn available. +// +// Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// https://opensource.org/licenses/BSD-3-Clause +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#version 450 + +#if NCNN_fp16_storage +#extension GL_EXT_shader_16bit_storage: require +struct sfpvec8 { f16vec4 abcd; f16vec4 efgh; }; +#endif +#if NCNN_fp16_arithmetic +#extension GL_EXT_shader_explicit_arithmetic_types_float16: require +#endif + +layout (constant_id = 0) const int across_spatial = 0; +layout (constant_id = 1) const int across_channel = 0; +layout (constant_id = 2) const int channel_shared = 0; +layout (constant_id = 3) const int scale_term = 0; + +layout (local_size_x_id = 233) in; +layout (local_size_y_id = 234) in; +layout (local_size_z_id = 235) in; + +layout (binding = 0) buffer bottom_top_blob { sfpvec8 bottom_top_blob_data[]; }; +layout (binding = 1) readonly buffer coeffs_blob { sfpvec8 coeffs_blob_data[]; }; +layout (binding = 2) readonly buffer scale_blob { sfpvec8 scale_blob_data[]; }; + +layout (push_constant) uniform parameter +{ + int dims; + int w; + int h; + int c; + int cstep; +} p; + +void main() +{ + int gx = int(gl_GlobalInvocationID.x); + int gy = int(gl_GlobalInvocationID.y); + int gz = int(gl_GlobalInvocationID.z); + + if (gx >= p.w || gy >= p.h || gz >= p.c) + return; + + const int gi = gz * p.cstep + gy * p.w + gx; + + afpvec8 v = buffer_ld8(bottom_top_blob_data, gi); + + afpvec8 a; + + if (across_spatial == 1 && across_channel == 1) + { + a = buffer_ld8(coeffs_blob_data, 0); + } + + if (across_spatial == 1 && across_channel == 0) + { + a = buffer_ld8(coeffs_blob_data, gz); + } + + if (across_spatial == 0 && across_channel == 1) + { + a = buffer_ld8(coeffs_blob_data, gy * p.w + gx); + } + + v[0] = v[0] * a[0]; + v[1] = v[1] * a[1]; + + if (scale_term == 1) + { + int si = channel_shared == 1 ? 0 : gz; + + afpvec8 scale = buffer_ld8(scale_blob_data, si); + + v[0] = v[0] * scale[0]; + v[1] = v[1] * scale[1]; + } + + buffer_st8(bottom_top_blob_data, gi, v); +} diff --git a/src/layer/vulkan/shader/normalize_reduce_sum4_fp16_to_fp32_pack4.comp b/src/layer/vulkan/shader/normalize_reduce_sum4_fp16_to_fp32_pack4.comp index 5fa93897c..478a52bd1 100644 --- a/src/layer/vulkan/shader/normalize_reduce_sum4_fp16_to_fp32_pack4.comp +++ b/src/layer/vulkan/shader/normalize_reduce_sum4_fp16_to_fp32_pack4.comp @@ -21,12 +21,6 @@ #extension GL_EXT_shader_explicit_arithmetic_types_float16: require #endif -#if NCNN_fp16_packed -#define sfp2floatvec4(v) vec4(unpackHalf2x16(v.x), unpackHalf2x16(v.y)) -#else -#define sfp2floatvec4(v) vec4(v) -#endif - layout (constant_id = 0) const int across_spatial = 0; layout (constant_id = 1) const int across_channel = 0; @@ -71,7 +65,7 @@ void main() { if (sx == p.size - 1) { - vec4 v0 = sfp2floatvec4(bottom_top_blob_data[v_offset0.r]); + vec4 v0 = vec4(buffer_ld4(bottom_top_blob_data, v_offset0.r)); vec4 sqsum = v0 * v0; @@ -79,8 +73,8 @@ void main() } else { - vec4 v0 = sfp2floatvec4(bottom_top_blob_data[v_offset0.r]); - vec4 v1 = sfp2floatvec4(bottom_top_blob_data[v_offset0.g]); + vec4 v0 = vec4(buffer_ld4(bottom_top_blob_data, v_offset0.r)); + vec4 v1 = vec4(buffer_ld4(bottom_top_blob_data, v_offset0.g)); vec4 sqsum = v0 * v0 + v1 * v1; @@ -91,8 +85,8 @@ void main() { if (sx == p.size - 1) { - vec4 v0 = sfp2floatvec4(bottom_top_blob_data[v_offset0.r]); - vec4 v2 = sfp2floatvec4(bottom_top_blob_data[v_offset1.r]); + vec4 v0 = vec4(buffer_ld4(bottom_top_blob_data, v_offset0.r)); + vec4 v2 = vec4(buffer_ld4(bottom_top_blob_data, v_offset1.r)); vec4 sqsum = v0 * v0 + v2 * v2; @@ -100,10 +94,10 @@ void main() } else { - vec4 v0 = sfp2floatvec4(bottom_top_blob_data[v_offset0.r]); - vec4 v1 = sfp2floatvec4(bottom_top_blob_data[v_offset0.g]); - vec4 v2 = sfp2floatvec4(bottom_top_blob_data[v_offset1.r]); - vec4 v3 = sfp2floatvec4(bottom_top_blob_data[v_offset1.g]); + vec4 v0 = vec4(buffer_ld4(bottom_top_blob_data, v_offset0.r)); + vec4 v1 = vec4(buffer_ld4(bottom_top_blob_data, v_offset0.g)); + vec4 v2 = vec4(buffer_ld4(bottom_top_blob_data, v_offset1.r)); + vec4 v3 = vec4(buffer_ld4(bottom_top_blob_data, v_offset1.g)); vec4 sqsum = v0 * v0 + v1 * v1 + v2 * v2 + v3 * v3; @@ -121,7 +115,7 @@ void main() if (sx == p.size - 1) { - vec4 v0 = sfp2floatvec4(bottom_top_blob_data[v_offset.r]); + vec4 v0 = vec4(buffer_ld4(bottom_top_blob_data, v_offset.r)); vec4 sqsum = v0 * v0; @@ -129,8 +123,8 @@ void main() } else if (sx == p.size - 2) { - vec4 v0 = sfp2floatvec4(bottom_top_blob_data[v_offset.r]); - vec4 v1 = sfp2floatvec4(bottom_top_blob_data[v_offset.g]); + vec4 v0 = vec4(buffer_ld4(bottom_top_blob_data, v_offset.r)); + vec4 v1 = vec4(buffer_ld4(bottom_top_blob_data, v_offset.g)); vec4 sqsum = v0 * v0 + v1 * v1; @@ -138,9 +132,9 @@ void main() } else if (sx == p.size - 3) { - vec4 v0 = sfp2floatvec4(bottom_top_blob_data[v_offset.r]); - vec4 v1 = sfp2floatvec4(bottom_top_blob_data[v_offset.g]); - vec4 v2 = sfp2floatvec4(bottom_top_blob_data[v_offset.b]); + vec4 v0 = vec4(buffer_ld4(bottom_top_blob_data, v_offset.r)); + vec4 v1 = vec4(buffer_ld4(bottom_top_blob_data, v_offset.g)); + vec4 v2 = vec4(buffer_ld4(bottom_top_blob_data, v_offset.b)); vec4 sqsum = v0 * v0 + v1 * v1 + v2 * v2; @@ -148,10 +142,10 @@ void main() } else { - vec4 v0 = sfp2floatvec4(bottom_top_blob_data[v_offset.r]); - vec4 v1 = sfp2floatvec4(bottom_top_blob_data[v_offset.g]); - vec4 v2 = sfp2floatvec4(bottom_top_blob_data[v_offset.b]); - vec4 v3 = sfp2floatvec4(bottom_top_blob_data[v_offset.a]); + vec4 v0 = vec4(buffer_ld4(bottom_top_blob_data, v_offset.r)); + vec4 v1 = vec4(buffer_ld4(bottom_top_blob_data, v_offset.g)); + vec4 v2 = vec4(buffer_ld4(bottom_top_blob_data, v_offset.b)); + vec4 v3 = vec4(buffer_ld4(bottom_top_blob_data, v_offset.a)); vec4 sqsum = v0 * v0 + v1 * v1 + v2 * v2 + v3 * v3; @@ -168,7 +162,7 @@ void main() if (sz == p.c - 1) { - vec4 v0 = sfp2floatvec4(bottom_top_blob_data[v_offset.r]); + vec4 v0 = vec4(buffer_ld4(bottom_top_blob_data, v_offset.r)); vec4 sqsum = v0 * v0; @@ -176,8 +170,8 @@ void main() } else if (sz == p.c - 2) { - vec4 v0 = sfp2floatvec4(bottom_top_blob_data[v_offset.r]); - vec4 v1 = sfp2floatvec4(bottom_top_blob_data[v_offset.g]); + vec4 v0 = vec4(buffer_ld4(bottom_top_blob_data, v_offset.r)); + vec4 v1 = vec4(buffer_ld4(bottom_top_blob_data, v_offset.g)); vec4 sqsum = v0 * v0 + v1 * v1; @@ -185,9 +179,9 @@ void main() } else if (sz == p.c - 3) { - vec4 v0 = sfp2floatvec4(bottom_top_blob_data[v_offset.r]); - vec4 v1 = sfp2floatvec4(bottom_top_blob_data[v_offset.g]); - vec4 v2 = sfp2floatvec4(bottom_top_blob_data[v_offset.b]); + vec4 v0 = vec4(buffer_ld4(bottom_top_blob_data, v_offset.r)); + vec4 v1 = vec4(buffer_ld4(bottom_top_blob_data, v_offset.g)); + vec4 v2 = vec4(buffer_ld4(bottom_top_blob_data, v_offset.b)); vec4 sqsum = v0 * v0 + v1 * v1 + v2 * v2; @@ -195,10 +189,10 @@ void main() } else { - vec4 v0 = sfp2floatvec4(bottom_top_blob_data[v_offset.r]); - vec4 v1 = sfp2floatvec4(bottom_top_blob_data[v_offset.g]); - vec4 v2 = sfp2floatvec4(bottom_top_blob_data[v_offset.b]); - vec4 v3 = sfp2floatvec4(bottom_top_blob_data[v_offset.a]); + vec4 v0 = vec4(buffer_ld4(bottom_top_blob_data, v_offset.r)); + vec4 v1 = vec4(buffer_ld4(bottom_top_blob_data, v_offset.g)); + vec4 v2 = vec4(buffer_ld4(bottom_top_blob_data, v_offset.b)); + vec4 v3 = vec4(buffer_ld4(bottom_top_blob_data, v_offset.a)); vec4 sqsum = v0 * v0 + v1 * v1 + v2 * v2 + v3 * v3; diff --git a/src/layer/vulkan/shader/normalize_reduce_sum4_fp16_to_fp32_pack8.comp b/src/layer/vulkan/shader/normalize_reduce_sum4_fp16_to_fp32_pack8.comp new file mode 100644 index 000000000..7588c1c99 --- /dev/null +++ b/src/layer/vulkan/shader/normalize_reduce_sum4_fp16_to_fp32_pack8.comp @@ -0,0 +1,227 @@ +// Tencent is pleased to support the open source community by making ncnn available. +// +// Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// https://opensource.org/licenses/BSD-3-Clause +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#version 450 + +#if NCNN_fp16_storage +#extension GL_EXT_shader_16bit_storage: require +struct sfpvec8 { f16vec4 abcd; f16vec4 efgh; }; +#endif +#if NCNN_fp16_arithmetic +#extension GL_EXT_shader_explicit_arithmetic_types_float16: require +#endif + +layout (constant_id = 0) const int across_spatial = 0; +layout (constant_id = 1) const int across_channel = 0; + +layout (local_size_x_id = 233) in; +layout (local_size_y_id = 234) in; +layout (local_size_z_id = 235) in; + +layout (binding = 0) readonly buffer bottom_top_blob { sfpvec8 bottom_top_blob_data[]; }; +layout (binding = 1) writeonly buffer sqsum_blob { mat2x4 sqsum_blob_data[]; }; + +layout (push_constant) uniform parameter +{ + int size; + int c; + int cstep; + + int outsize; + int outc; + int outcstep; +} p; + +void main() +{ + int gx = int(gl_GlobalInvocationID.x); + int gy = int(gl_GlobalInvocationID.y); + int gz = int(gl_GlobalInvocationID.z); + + if (gx >= p.outsize || gy >= 1 || gz >= p.outc) + return; + + int gi = gz * p.outcstep + gx; + + if (across_spatial == 1 && across_channel == 1) + { + int sz = gz * 2; + int sx = gx * 2; + + ivec2 v_offset0 = sz * p.cstep + sx + ivec2(0, 1); + ivec2 v_offset1 = v_offset0 + p.cstep; + + if (sz == p.c - 1) + { + if (sx == p.size - 1) + { + mat2x4 v0 = mat2x4(buffer_ld8(bottom_top_blob_data, v_offset0.r)); + + mat2x4 sqsum; + sqsum[0] = v0[0] * v0[0]; + sqsum[1] = v0[1] * v0[1]; + + sqsum_blob_data[gi] = sqsum; + } + else + { + mat2x4 v0 = mat2x4(buffer_ld8(bottom_top_blob_data, v_offset0.r)); + mat2x4 v1 = mat2x4(buffer_ld8(bottom_top_blob_data, v_offset0.g)); + + mat2x4 sqsum; + sqsum[0] = v0[0] * v0[0] + v1[0] * v1[0]; + sqsum[1] = v0[1] * v0[1] + v1[1] * v1[1]; + + sqsum_blob_data[gi] = sqsum; + } + } + else + { + if (sx == p.size - 1) + { + mat2x4 v0 = mat2x4(buffer_ld8(bottom_top_blob_data, v_offset0.r)); + mat2x4 v2 = mat2x4(buffer_ld8(bottom_top_blob_data, v_offset1.r)); + + mat2x4 sqsum; + sqsum[0] = v0[0] * v0[0] + v2[0] * v2[0]; + sqsum[1] = v0[1] * v0[1] + v2[1] * v2[1]; + + sqsum_blob_data[gi] = sqsum; + } + else + { + mat2x4 v0 = mat2x4(buffer_ld8(bottom_top_blob_data, v_offset0.r)); + mat2x4 v1 = mat2x4(buffer_ld8(bottom_top_blob_data, v_offset0.g)); + mat2x4 v2 = mat2x4(buffer_ld8(bottom_top_blob_data, v_offset1.r)); + mat2x4 v3 = mat2x4(buffer_ld8(bottom_top_blob_data, v_offset1.g)); + + mat2x4 sqsum; + sqsum[0] = v0[0] * v0[0] + v1[0] * v1[0] + v2[0] * v2[0] + v3[0] * v3[0]; + sqsum[1] = v0[1] * v0[1] + v1[1] * v1[1] + v2[1] * v2[1] + v3[1] * v3[1]; + + sqsum_blob_data[gi] = sqsum; + } + } + } + + if (across_spatial == 1 && across_channel == 0) + { + int sz = gz; + int sx = gx * 4; + + ivec4 v_offset = sz * p.cstep + sx + ivec4(0, 1, 2, 3); + + if (sx == p.size - 1) + { + mat2x4 v0 = mat2x4(buffer_ld8(bottom_top_blob_data, v_offset.r)); + + mat2x4 sqsum; + sqsum[0] = v0[0] * v0[0]; + sqsum[1] = v0[1] * v0[1]; + + sqsum_blob_data[gi] = sqsum; + } + else if (sx == p.size - 2) + { + mat2x4 v0 = mat2x4(buffer_ld8(bottom_top_blob_data, v_offset.r)); + mat2x4 v1 = mat2x4(buffer_ld8(bottom_top_blob_data, v_offset.g)); + + mat2x4 sqsum; + sqsum[0] = v0[0] * v0[0] + v1[0] * v1[0]; + sqsum[1] = v0[1] * v0[1] + v1[1] * v1[1]; + + sqsum_blob_data[gi] = sqsum; + } + else if (sx == p.size - 3) + { + mat2x4 v0 = mat2x4(buffer_ld8(bottom_top_blob_data, v_offset.r)); + mat2x4 v1 = mat2x4(buffer_ld8(bottom_top_blob_data, v_offset.g)); + mat2x4 v2 = mat2x4(buffer_ld8(bottom_top_blob_data, v_offset.b)); + + mat2x4 sqsum; + sqsum[0] = v0[0] * v0[0] + v1[0] * v1[0] + v2[0] * v2[0]; + sqsum[1] = v0[1] * v0[1] + v1[1] * v1[1] + v2[1] * v2[1]; + + sqsum_blob_data[gi] = sqsum; + } + else + { + mat2x4 v0 = mat2x4(buffer_ld8(bottom_top_blob_data, v_offset.r)); + mat2x4 v1 = mat2x4(buffer_ld8(bottom_top_blob_data, v_offset.g)); + mat2x4 v2 = mat2x4(buffer_ld8(bottom_top_blob_data, v_offset.b)); + mat2x4 v3 = mat2x4(buffer_ld8(bottom_top_blob_data, v_offset.a)); + + mat2x4 sqsum; + sqsum[0] = v0[0] * v0[0] + v1[0] * v1[0] + v2[0] * v2[0] + v3[0] * v3[0]; + sqsum[1] = v0[1] * v0[1] + v1[1] * v1[1] + v2[1] * v2[1] + v3[1] * v3[1]; + + sqsum_blob_data[gi] = sqsum; + } + } + + if (across_spatial == 0 && across_channel == 1) + { + int sz = gz * 4; + int sx = gx; + + ivec4 v_offset = (sz + ivec4(0, 1, 2, 3)) * p.cstep + sx; + + if (sz == p.c - 1) + { + mat2x4 v0 = mat2x4(buffer_ld8(bottom_top_blob_data, v_offset.r)); + + mat2x4 sqsum; + sqsum[0] = v0[0] * v0[0]; + sqsum[1] = v0[1] * v0[1]; + + sqsum_blob_data[gi] = sqsum; + } + else if (sz == p.c - 2) + { + mat2x4 v0 = mat2x4(buffer_ld8(bottom_top_blob_data, v_offset.r)); + mat2x4 v1 = mat2x4(buffer_ld8(bottom_top_blob_data, v_offset.g)); + + mat2x4 sqsum; + sqsum[0] = v0[0] * v0[0] + v1[0] * v1[0]; + sqsum[1] = v0[1] * v0[1] + v1[1] * v1[1]; + + sqsum_blob_data[gi] = sqsum; + } + else if (sz == p.c - 3) + { + mat2x4 v0 = mat2x4(buffer_ld8(bottom_top_blob_data, v_offset.r)); + mat2x4 v1 = mat2x4(buffer_ld8(bottom_top_blob_data, v_offset.g)); + mat2x4 v2 = mat2x4(buffer_ld8(bottom_top_blob_data, v_offset.b)); + + mat2x4 sqsum; + sqsum[0] = v0[0] * v0[0] + v1[0] * v1[0] + v2[0] * v2[0]; + sqsum[1] = v0[1] * v0[1] + v1[1] * v1[1] + v2[1] * v2[1]; + + sqsum_blob_data[gi] = sqsum; + } + else + { + mat2x4 v0 = mat2x4(buffer_ld8(bottom_top_blob_data, v_offset.r)); + mat2x4 v1 = mat2x4(buffer_ld8(bottom_top_blob_data, v_offset.g)); + mat2x4 v2 = mat2x4(buffer_ld8(bottom_top_blob_data, v_offset.b)); + mat2x4 v3 = mat2x4(buffer_ld8(bottom_top_blob_data, v_offset.a)); + + mat2x4 sqsum; + sqsum[0] = v0[0] * v0[0] + v1[0] * v1[0] + v2[0] * v2[0] + v3[0] * v3[0]; + sqsum[1] = v0[1] * v0[1] + v1[1] * v1[1] + v2[1] * v2[1] + v3[1] * v3[1]; + + sqsum_blob_data[gi] = sqsum; + } + } +} diff --git a/src/layer/vulkan/shader/normalize_reduce_sum4_fp32_pack8.comp b/src/layer/vulkan/shader/normalize_reduce_sum4_fp32_pack8.comp new file mode 100644 index 000000000..39d0a76ad --- /dev/null +++ b/src/layer/vulkan/shader/normalize_reduce_sum4_fp32_pack8.comp @@ -0,0 +1,203 @@ +// Tencent is pleased to support the open source community by making ncnn available. +// +// Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// https://opensource.org/licenses/BSD-3-Clause +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#version 450 + +#if NCNN_fp16_storage +#extension GL_EXT_shader_16bit_storage: require +struct sfpvec8 { f16vec4 abcd; f16vec4 efgh; }; +#endif +#if NCNN_fp16_arithmetic +#extension GL_EXT_shader_explicit_arithmetic_types_float16: require +#endif + +layout (constant_id = 0) const int across_spatial = 0; +layout (constant_id = 1) const int across_channel = 0; + +layout (local_size_x_id = 233) in; +layout (local_size_y_id = 234) in; +layout (local_size_z_id = 235) in; + +layout (binding = 0) readonly buffer square_blob { mat2x4 square_blob_data[]; }; +layout (binding = 1) writeonly buffer sqsum_blob { mat2x4 sqsum_blob_data[]; }; + +layout (push_constant) uniform parameter +{ + int size; + int c; + int cstep; + + int outsize; + int outc; + int outcstep; +} p; + +void main() +{ + int gx = int(gl_GlobalInvocationID.x); + int gy = int(gl_GlobalInvocationID.y); + int gz = int(gl_GlobalInvocationID.z); + + if (gx >= p.outsize || gy >= 1 || gz >= p.outc) + return; + + int gi = gz * p.outcstep + gx; + + if (across_spatial == 1 && across_channel == 1) + { + int sz = gz * 2; + int sx = gx * 2; + + ivec2 v_offset0 = sz * p.cstep + sx + ivec2(0, 1); + ivec2 v_offset1 = v_offset0 + p.cstep; + + if (sz == p.c - 1) + { + if (sx == p.size - 1) + { + mat2x4 v0 = square_blob_data[v_offset0.r]; + + mat2x4 sqsum = v0; + + sqsum_blob_data[gi] = sqsum; + } + else + { + mat2x4 v0 = square_blob_data[v_offset0.r]; + mat2x4 v1 = square_blob_data[v_offset0.g]; + + mat2x4 sqsum = v0 + v1; + + sqsum_blob_data[gi] = sqsum; + } + } + else + { + if (sx == p.size - 1) + { + mat2x4 v0 = square_blob_data[v_offset0.r]; + mat2x4 v2 = square_blob_data[v_offset1.r]; + + mat2x4 sqsum = v0 + v2; + + sqsum_blob_data[gi] = sqsum; + } + else + { + mat2x4 v0 = square_blob_data[v_offset0.r]; + mat2x4 v1 = square_blob_data[v_offset0.g]; + mat2x4 v2 = square_blob_data[v_offset1.r]; + mat2x4 v3 = square_blob_data[v_offset1.g]; + + mat2x4 sqsum = v0 + v1 + v2 + v3; + + sqsum_blob_data[gi] = sqsum; + } + } + } + + if (across_spatial == 1 && across_channel == 0) + { + int sz = gz; + int sx = gx * 4; + + ivec4 v_offset = sz * p.cstep + sx + ivec4(0, 1, 2, 3); + + if (sx == p.size - 1) + { + mat2x4 v0 = square_blob_data[v_offset.r]; + + mat2x4 sqsum = v0; + + sqsum_blob_data[gi] = sqsum; + } + else if (sx == p.size - 2) + { + mat2x4 v0 = square_blob_data[v_offset.r]; + mat2x4 v1 = square_blob_data[v_offset.g]; + + mat2x4 sqsum = v0 + v1; + + sqsum_blob_data[gi] = sqsum; + } + else if (sx == p.size - 3) + { + mat2x4 v0 = square_blob_data[v_offset.r]; + mat2x4 v1 = square_blob_data[v_offset.g]; + mat2x4 v2 = square_blob_data[v_offset.b]; + + mat2x4 sqsum = v0 + v1 + v2; + + sqsum_blob_data[gi] = sqsum; + } + else + { + mat2x4 v0 = square_blob_data[v_offset.r]; + mat2x4 v1 = square_blob_data[v_offset.g]; + mat2x4 v2 = square_blob_data[v_offset.b]; + mat2x4 v3 = square_blob_data[v_offset.a]; + + mat2x4 sqsum = v0 + v1 + v2 + v3; + + sqsum_blob_data[gi] = sqsum; + } + } + + if (across_spatial == 0 && across_channel == 1) + { + int sz = gz * 4; + int sx = gx; + + ivec4 v_offset = (sz + ivec4(0, 1, 2, 3)) * p.cstep + sx; + + if (sz == p.c - 1) + { + mat2x4 v0 = square_blob_data[v_offset.r]; + + mat2x4 sqsum = v0; + + sqsum_blob_data[gi] = sqsum; + } + else if (sz == p.c - 2) + { + mat2x4 v0 = square_blob_data[v_offset.r]; + mat2x4 v1 = square_blob_data[v_offset.g]; + + mat2x4 sqsum = v0 + v1; + + sqsum_blob_data[gi] = sqsum; + } + else if (sz == p.c - 3) + { + mat2x4 v0 = square_blob_data[v_offset.r]; + mat2x4 v1 = square_blob_data[v_offset.g]; + mat2x4 v2 = square_blob_data[v_offset.b]; + + mat2x4 sqsum = v0 + v1 + v2; + + sqsum_blob_data[gi] = sqsum; + } + else + { + mat2x4 v0 = square_blob_data[v_offset.r]; + mat2x4 v1 = square_blob_data[v_offset.g]; + mat2x4 v2 = square_blob_data[v_offset.b]; + mat2x4 v3 = square_blob_data[v_offset.a]; + + mat2x4 sqsum = v0 + v1 + v2 + v3; + + sqsum_blob_data[gi] = sqsum; + } + } +} diff --git a/src/layer/vulkan/shader/permute_pack8to1.comp b/src/layer/vulkan/shader/permute_pack8to1.comp new file mode 100644 index 000000000..acb88ae31 --- /dev/null +++ b/src/layer/vulkan/shader/permute_pack8to1.comp @@ -0,0 +1,123 @@ +// Tencent is pleased to support the open source community by making ncnn available. +// +// Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// https://opensource.org/licenses/BSD-3-Clause +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#version 450 + +#if NCNN_fp16_storage +#extension GL_EXT_shader_16bit_storage: require +struct sfpvec8 { f16vec4 abcd; f16vec4 efgh; }; +#endif +#if NCNN_fp16_arithmetic +#extension GL_EXT_shader_explicit_arithmetic_types_float16: require +#endif + +layout (constant_id = 0) const int order_type = 0; + +layout (local_size_x_id = 233) in; +layout (local_size_y_id = 234) in; +layout (local_size_z_id = 235) in; + +layout (binding = 0) readonly buffer bottom_blob { sfpvec8 bottom_blob_data[]; }; +layout (binding = 1) writeonly buffer top_blob { sfp top_blob_data[]; }; + +layout (push_constant) uniform parameter +{ + int dims; + int w; + int h; + int c; + int cstep; + + int outdims; + int outw; + int outh; + int outc; + int outcstep; +} p; + +void main() +{ + int gx = int(gl_GlobalInvocationID.x); + int gy = int(gl_GlobalInvocationID.y); + int gz = int(gl_GlobalInvocationID.z); + + if (gx >= p.w || gy >= p.h || gz >= p.c) + return; + + ivec4 v_offset; + ivec4 vv_offset; + + if (p.dims == 2) + { + // order_type + // 0 = w h + // 1 = h w + + if (order_type == 0) + { + v_offset = ivec4((gy * 8) * p.outw + gx) + ivec4(0, 1, 2, 3) * p.outw; + vv_offset = v_offset + 4 * p.outw; + } + if (order_type == 1) + { + v_offset = ivec4(gx * p.outw + gy * 8) + ivec4(0, 1, 2, 3); + vv_offset = v_offset + 4; + } + } + else if (p.dims == 3) + { + // order_type + // 0 = w h c + // 1 = h w c + // 2 = w c h + // 3 = c w h + // 4 = h c w + // 5 = c h w + + if (order_type == 0) + { + v_offset = ivec4((gz * 8) * p.outcstep + gy * p.outw + gx) + ivec4(0, 1, 2, 3) * p.outcstep; + vv_offset = v_offset + 4 * p.outcstep; + } + if (order_type == 1) + { + v_offset = ivec4((gz * 8) * p.outcstep + gx * p.outw + gy) + ivec4(0, 1, 2, 3) * p.outcstep; + vv_offset = v_offset + 4 * p.outcstep; + } + if (order_type == 2) + { + v_offset = ivec4(gy * p.outcstep + (gz * 8) * p.outw + gx) + ivec4(0, 1, 2, 3) * p.outw; + vv_offset = v_offset + 4 * p.outw; + } + if (order_type == 3) + { + v_offset = ivec4(gy * p.outcstep + gx * p.outw + gz * 8) + ivec4(0, 1, 2, 3); + vv_offset = v_offset + 4; + } + if (order_type == 4) + { + v_offset = ivec4(gx * p.outcstep + (gz * 8) * p.outw + gy) + ivec4(0, 1, 2, 3) * p.outw; + vv_offset = v_offset + 4 * p.outw; + } + if (order_type == 5) + { + v_offset = ivec4(gx * p.outcstep + gy * p.outw + gz * 8) + ivec4(0, 1, 2, 3); + vv_offset = v_offset + 4; + } + } + + int gi = gz * p.cstep + gy * p.w + gx; + + buffer_cp8to1(top_blob_data, v_offset, vv_offset, bottom_blob_data, gi); +}