| @@ -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<vk_specialization_type> specializations(11); | |||
| std::vector<vk_specialization_type> 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<vk_specialization_type> specializations(5); | |||
| std::vector<vk_specialization_type> 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<VkMat>& 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<VkMat>& 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<VkMat>& 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()) | |||
| @@ -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; | |||
| @@ -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); | |||
| } | |||
| } | |||
| } | |||
| @@ -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; | |||
| } | |||