Browse Source

priorbox shader fix

tags/20200226
nihui 6 years ago
parent
commit
82fa27967e
4 changed files with 64 additions and 92 deletions
  1. +47
    -9
      src/layer/vulkan/priorbox_vulkan.cpp
  2. +10
    -74
      src/layer/vulkan/shader/priorbox.comp
  3. +6
    -8
      src/layer/vulkan/shader/priorbox_mxnet.comp
  4. +1
    -1
      src/pipeline.cpp

+ 47
- 9
src/layer/vulkan/priorbox_vulkan.cpp View File

@@ -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())


+ 10
- 74
src/layer/vulkan/shader/priorbox.comp View File

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


+ 6
- 8
src/layer/vulkan/shader/priorbox_mxnet.comp View File

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

+ 1
- 1
src/pipeline.cpp View File

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



Loading…
Cancel
Save