diff --git a/src/layer/vulkan/priorbox_vulkan.cpp b/src/layer/vulkan/priorbox_vulkan.cpp index f3f59b592..c3b10f290 100644 --- a/src/layer/vulkan/priorbox_vulkan.cpp +++ b/src/layer/vulkan/priorbox_vulkan.cpp @@ -30,6 +30,32 @@ PriorBox_vulkan::PriorBox_vulkan() int PriorBox_vulkan::create_pipeline(const Option& opt) { + const Mat& shape = bottom_shapes.empty() ? Mat() : bottom_shapes[0]; + + 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; + + size_t elemsize; + if (opt.use_fp16_storage) + { + elemsize = elempack * 2u; + } + else if (opt.use_fp16_packed) + { + elemsize = elempack == 1 ? 4u : elempack * 2u; + } + else + { + elemsize = elempack * 4u; + } + + 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); + // caffe style { int num_min_size = min_sizes.w; @@ -40,7 +66,7 @@ int PriorBox_vulkan::create_pipeline(const Option& opt) if (flip) num_prior += num_min_size * num_aspect_ratio; - std::vector specializations(11); + std::vector specializations(11 + 2); specializations[0].i = flip; specializations[1].i = clip; specializations[2].f = offset; @@ -52,6 +78,8 @@ int PriorBox_vulkan::create_pipeline(const Option& opt) specializations[8].i = num_max_size; specializations[9].i = num_aspect_ratio; specializations[10].i = num_prior; + specializations[11 + 0].i = shape_packed.w; + specializations[11 + 1].i = shape_packed.h; pipeline_priorbox = new Pipeline(vkdev); pipeline_priorbox->set_optimal_local_size_xyz(); @@ -65,12 +93,14 @@ int PriorBox_vulkan::create_pipeline(const Option& opt) int num_prior = num_sizes - 1 + num_ratios; - std::vector specializations(5); + std::vector specializations(5 + 2); specializations[0].i = clip; specializations[1].f = offset; specializations[2].i = num_sizes; specializations[3].i = num_ratios; specializations[4].i = num_prior; + specializations[5 + 0].i = shape_packed.w; + specializations[5 + 1].i = shape_packed.h; pipeline_priorbox_mxnet = new Pipeline(vkdev); pipeline_priorbox_mxnet->set_optimal_local_size_xyz(); @@ -107,12 +137,6 @@ int PriorBox_vulkan::forward(const std::vector& bottom_blobs, std::vector { int w = bottom_blobs[0].w; int h = bottom_blobs[0].h; - size_t elemsize = 4u; - - if (opt.use_fp16_storage) - { - elemsize = 2u; - } if (bottom_blobs.size() == 1 && image_width == -233 && image_height == -233 && max_sizes.empty()) { @@ -129,8 +153,16 @@ int PriorBox_vulkan::forward(const std::vector& bottom_blobs, std::vector int num_prior = num_sizes - 1 + num_ratios; + int elempack = 4; + + size_t elemsize = elempack * 4u; + if (opt.use_fp16_packed || opt.use_fp16_storage) + { + elemsize = elempack * 2u; + } + VkMat& top_blob = top_blobs[0]; - top_blob.create(4 * w * h * num_prior, elemsize, 1, opt.blob_vkallocator, opt.staging_vkallocator); + top_blob.create(4 * w * h * num_prior / elempack, elemsize, elempack, opt.blob_vkallocator, opt.staging_vkallocator); if (top_blob.empty()) return -100; @@ -177,6 +209,12 @@ int PriorBox_vulkan::forward(const std::vector& bottom_blobs, std::vector if (flip) num_prior += num_min_size * num_aspect_ratio; + size_t elemsize = 4u; + if (opt.use_fp16_storage) + { + elemsize = 2u; + } + VkMat& top_blob = top_blobs[0]; top_blob.create(4 * w * h * num_prior, 2, elemsize, 1, opt.blob_vkallocator, opt.staging_vkallocator); if (top_blob.empty()) diff --git a/src/layer/vulkan/shader/priorbox.comp b/src/layer/vulkan/shader/priorbox.comp index 4166a604c..1503b8866 100644 --- a/src/layer/vulkan/shader/priorbox.comp +++ b/src/layer/vulkan/shader/priorbox.comp @@ -87,12 +87,7 @@ void main() afp min_size = buffer_ld1(min_sizes_data, gx); -#if NCNN_fp16_packed - vec4 variances = vec4(variances_0, variances_1, variances_2, variances_3); -#elif !NCNN_fp16_storage - // per component assignment makes qcom-adreno driver unhappy :( - sfpvec4 variances = sfpvec4(variances_0, variances_1, variances_2, variances_3); -#endif + afpvec4 variances = afpvec4(variances_0, variances_1, variances_2, variances_3); // min size box box_w = box_h = min_size; @@ -102,25 +97,10 @@ void main() #if NCNN_fp16_packed top_blob_data[v_offset] = vec4(box); + top_blob_data[var_offset] = vec4(variances); #else buffer_st4(top_blob_data, v_offset, box); -#endif -#if NCNN_fp16_packed || !NCNN_fp16_storage - top_blob_data[var_offset] = variances; -#elif NCNN_fp16_storage - float variances_0_fp32 = variances_0; - float variances_1_fp32 = variances_1; - float variances_2_fp32 = variances_2; - float variances_3_fp32 = variances_3; - top_blob_data[var_offset].r = sfp(variances_0_fp32); - top_blob_data[var_offset].g = sfp(variances_1_fp32); - top_blob_data[var_offset].b = sfp(variances_2_fp32); - top_blob_data[var_offset].a = sfp(variances_3_fp32); -#else - top_blob_data[var_offset].r = sfp(variances_0); - top_blob_data[var_offset].g = sfp(variances_1); - top_blob_data[var_offset].b = sfp(variances_2); - top_blob_data[var_offset].a = sfp(variances_3); + buffer_st4(top_blob_data, var_offset, variances); #endif v_offset += 1; @@ -138,26 +118,12 @@ void main() #if NCNN_fp16_packed top_blob_data[v_offset] = vec4(box); + top_blob_data[var_offset] = vec4(variances); #else buffer_st4(top_blob_data, v_offset, box); + buffer_st4(top_blob_data, var_offset, variances); #endif -#if NCNN_fp16_packed || !NCNN_fp16_storage - top_blob_data[var_offset] = variances; -#elif NCNN_fp16_storage - float variances_0_fp32 = variances_0; - float variances_1_fp32 = variances_1; - float variances_2_fp32 = variances_2; - float variances_3_fp32 = variances_3; - top_blob_data[var_offset].r = sfp(variances_0_fp32); - top_blob_data[var_offset].g = sfp(variances_1_fp32); - top_blob_data[var_offset].b = sfp(variances_2_fp32); - top_blob_data[var_offset].a = sfp(variances_3_fp32); -#else - top_blob_data[var_offset].r = sfp(variances_0); - top_blob_data[var_offset].g = sfp(variances_1); - top_blob_data[var_offset].b = sfp(variances_2); - top_blob_data[var_offset].a = sfp(variances_3); -#endif + v_offset += 1; var_offset += 1; } @@ -175,25 +141,10 @@ void main() #if NCNN_fp16_packed top_blob_data[v_offset] = vec4(box); + top_blob_data[var_offset] = vec4(variances); #else buffer_st4(top_blob_data, v_offset, box); -#endif -#if NCNN_fp16_packed || !NCNN_fp16_storage - top_blob_data[var_offset] = variances; -#elif NCNN_fp16_storage - float variances_0_fp32 = variances_0; - float variances_1_fp32 = variances_1; - float variances_2_fp32 = variances_2; - float variances_3_fp32 = variances_3; - top_blob_data[var_offset].r = sfp(variances_0_fp32); - top_blob_data[var_offset].g = sfp(variances_1_fp32); - top_blob_data[var_offset].b = sfp(variances_2_fp32); - top_blob_data[var_offset].a = sfp(variances_3_fp32); -#else - top_blob_data[var_offset].r = sfp(variances_0); - top_blob_data[var_offset].g = sfp(variances_1); - top_blob_data[var_offset].b = sfp(variances_2); - top_blob_data[var_offset].a = sfp(variances_3); + buffer_st4(top_blob_data, var_offset, variances); #endif v_offset += 1; @@ -206,25 +157,10 @@ void main() #if NCNN_fp16_packed top_blob_data[v_offset] = vec4(box); + top_blob_data[var_offset] = vec4(variances); #else buffer_st4(top_blob_data, v_offset, box); -#endif -#if NCNN_fp16_packed || !NCNN_fp16_storage - top_blob_data[var_offset] = variances; -#elif NCNN_fp16_storage - float variances_0_fp32 = variances_0; - float variances_1_fp32 = variances_1; - float variances_2_fp32 = variances_2; - float variances_3_fp32 = variances_3; - top_blob_data[var_offset].r = sfp(variances_0_fp32); - top_blob_data[var_offset].g = sfp(variances_1_fp32); - top_blob_data[var_offset].b = sfp(variances_2_fp32); - top_blob_data[var_offset].a = sfp(variances_3_fp32); -#else - top_blob_data[var_offset].r = sfp(variances_0); - top_blob_data[var_offset].g = sfp(variances_1); - top_blob_data[var_offset].b = sfp(variances_2); - top_blob_data[var_offset].a = sfp(variances_3); + buffer_st4(top_blob_data, var_offset, variances); #endif v_offset += 1; diff --git a/src/layer/vulkan/shader/priorbox_mxnet.comp b/src/layer/vulkan/shader/priorbox_mxnet.comp index 6aa582c20..bec66fde9 100644 --- a/src/layer/vulkan/shader/priorbox_mxnet.comp +++ b/src/layer/vulkan/shader/priorbox_mxnet.comp @@ -66,29 +66,27 @@ void main() // ratio = 1, various sizes afp size = buffer_ld1(min_sizes_data, gx); - afp cw = size * afp(psc(h)) / afp(psc(w)) / afp(2); - afp ch = size / afp(2); + afp cw = size * afp(0.5f) * afp(psc(h)) / afp(psc(w)); + afp ch = size * afp(0.5f); afpvec4 box = center + afpvec4(-cw, -ch, cw, ch); box = clip == 1 ? clamp(box, afp(0.f), afp(1.f)) : box; buffer_st4(top_blob_data, v_offset, box); - if (gx == num_sizes - 1) + if (gx == 0) { // various ratios, size = min_size = size[0] - afp size = buffer_ld1(min_sizes_data, 0); for (int pi = 1; pi < num_ratios; pi++) { afp v = buffer_ld1(aspect_ratios_data, pi); - afp ratio = sqrt(v); - afp cwr = size * afp(psc(h)) / afp(psc(w)) * ratio / afp(2); - afp chr = size / ratio / afp(2); + afp cwr = cw * sqrt(v); + afp chr = ch / sqrt(v); afpvec4 box = center + afpvec4(-cwr, -chr, cwr, chr); box = clip == 1 ? clamp(box, afp(0.f), afp(1.f)) : box; - buffer_st4(top_blob_data, v_offset + pi, box); + buffer_st4(top_blob_data, v_offset + num_sizes - 1 + pi, box); } } } diff --git a/src/pipeline.cpp b/src/pipeline.cpp index cb94fef91..0fb7a1cda 100644 --- a/src/pipeline.cpp +++ b/src/pipeline.cpp @@ -347,7 +347,7 @@ int Pipeline::create_pipeline(VkShaderModule shader_module, const char* entry_na VkResult ret = vkCreateComputePipelines(vkdev->vkdevice(), 0, 1, &computePipelineCreateInfo, 0, &pipeline); if (ret != VK_SUCCESS) { - fprintf(stderr, "vkCreateComputePipelines failed %d\n", ret); + fprintf(stderr, "vkCreateComputePipelines failed %d %s\n", ret, entry_name); return -1; }