| @@ -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); | |||
| } | |||
| @@ -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); | |||
| } | |||
| @@ -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); | |||
| } | |||
| @@ -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; | |||
| } | |||
| } | |||
| @@ -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; | |||
| } | |||
| } | |||
| @@ -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); | |||
| } | |||
| @@ -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); | |||
| } | |||
| @@ -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); | |||
| } | |||
| @@ -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; | |||
| @@ -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; | |||
| } | |||
| } | |||
| } | |||
| @@ -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; | |||
| } | |||
| } | |||
| } | |||
| @@ -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); | |||
| } | |||