Browse Source

fix vkmat download on integrated gpu, workaround priorbox fp16s with online spirv, fix #1700 fix #1805

tags/20200616
nihuini 6 years ago
parent
commit
bb56b5439f
4 changed files with 177 additions and 166 deletions
  1. +22
    -8
      src/command.cpp
  2. +8
    -7
      src/gpu.cpp
  3. +137
    -151
      src/layer/vulkan/packing_vulkan.cpp
  4. +10
    -0
      src/layer/vulkan/priorbox_vulkan.cpp

+ 22
- 8
src/command.cpp View File

@@ -144,6 +144,7 @@ void VkCompute::record_upload(const Mat& src, VkMat& dst, const Option& opt)
else
dst_elempack = elemcount % 4 == 0 ? 4 : 1;

// gpu cast to fp16 on the fly (integrated gpu)
vkdev->convert_packing(dst_staging, dst, dst_elempack, *this, opt);
}

@@ -206,6 +207,7 @@ void VkCompute::record_upload(const Mat& src, VkImageMat& dst, const Option& opt
else
dst_elempack = elemcount % 4 == 0 ? 4 : 1;

// gpu cast to fp16 on the fly (integrated gpu)
vkdev->convert_packing(dst_staging, dst, dst_elempack, *this, opt);
}

@@ -226,14 +228,21 @@ void VkCompute::record_download(const VkMat& src, Mat& dst, const Option& opt)
else
dst_elempack = 1;

// gpu cast to fp32 on the fly (integrated gpu)
Option opt_staging = opt;
if (vkdev->info.type == 1)
{
opt_staging.use_fp16_packed = false;
opt_staging.use_fp16_storage = false;
}

VkMat dst_staging;
if (opt.blob_vkallocator->mappable)
if (opt_staging.blob_vkallocator->mappable)
{
vkdev->convert_packing(src, dst_staging, dst_elempack, *this, opt);
vkdev->convert_packing(src, dst_staging, dst_elempack, *this, opt_staging);
}
else
{
Option opt_staging = opt;
opt_staging.blob_vkallocator = opt.staging_vkallocator;
vkdev->convert_packing(src, dst_staging, dst_elempack, *this, opt_staging);
}
@@ -310,7 +319,6 @@ void VkCompute::record_download(const VkMat& src, Mat& dst, const Option& opt)
if (dims == 3)
dst.create(dst_fp16.w, dst_fp16.h, dst_fp16.c, (size_t)(dst_fp16.elempack * 4u), dst_fp16.elempack, opt.blob_allocator);

download_post_mats_fp16.push_back(dst_fp16);
download_post_mats.push_back(dst);

record r;
@@ -348,14 +356,21 @@ void VkCompute::record_download(const VkImageMat& src, Mat& dst, const Option& o
else
dst_elempack = 1;

// gpu cast to fp32 on the fly (integrated gpu)
Option opt_staging = opt;
if (vkdev->info.type == 1)
{
opt_staging.use_fp16_packed = false;
opt_staging.use_fp16_storage = false;
}

VkMat dst_staging;
if (opt.blob_vkallocator->mappable)
if (opt_staging.blob_vkallocator->mappable)
{
vkdev->convert_packing(src, dst_staging, dst_elempack, *this, opt);
vkdev->convert_packing(src, dst_staging, dst_elempack, *this, opt_staging);
}
else
{
Option opt_staging = opt;
opt_staging.blob_vkallocator = opt.staging_vkallocator;
vkdev->convert_packing(src, dst_staging, dst_elempack, *this, opt_staging);
}
@@ -432,7 +447,6 @@ void VkCompute::record_download(const VkImageMat& src, Mat& dst, const Option& o
if (dims == 3)
dst.create(dst_fp16.w, dst_fp16.h, dst_fp16.c, (size_t)(dst_fp16.elempack * 4u), dst_fp16.elempack, opt.blob_allocator);

download_post_mats_fp16.push_back(dst_fp16);
download_post_mats.push_back(dst);

record r;


+ 8
- 7
src/gpu.cpp View File

@@ -1687,7 +1687,7 @@ void VulkanDevice::convert_packing(const VkMat& src, VkMat& dst, int dst_elempac
Option opt = _opt;
opt.use_image_storage = false;

int cast_type_from_index = src.elemsize == src.elempack * 4u ? 0 : opt.use_fp16_storage ? 2 : 1;
int cast_type_from_index = src.elemsize == src.elempack * 4u ? 0 : src.elemsize == src.elempack * 2u && info.support_fp16_storage ? 2 : 1;
int cast_type_to_index = opt.use_fp16_storage ? 2 : opt.use_fp16_packed && dst_elempack % 4 == 0 ? 1 : 0;
int packing_type_to_index = dst_elempack == 1 ? 0 : dst_elempack == 4 ? 1 : 2;

@@ -1705,7 +1705,7 @@ void VulkanDevice::convert_packing(const VkImageMat& src, VkImageMat& dst, int d
return;
}

int cast_type_from_index = src.elemsize == src.elempack * 4u ? 0 : opt.use_fp16_storage ? 2 : 1;
int cast_type_from_index = src.elemsize == src.elempack * 4u ? 0 : src.elemsize == src.elempack * 2u && info.support_fp16_storage ? 2 : 1;
int cast_type_to_index = opt.use_fp16_storage ? 2 : opt.use_fp16_packed && dst_elempack % 4 == 0 ? 1 : 0;
int packing_type_to_index = dst_elempack == 1 ? 0 : dst_elempack == 4 ? 1 : 2;

@@ -1723,7 +1723,7 @@ void VulkanDevice::convert_packing(const VkMat& src, VkImageMat& dst, int dst_el
return;
}

int cast_type_from_index = src.elemsize == src.elempack * 4u ? 0 : opt.use_fp16_storage ? 2 : 1;
int cast_type_from_index = src.elemsize == src.elempack * 4u ? 0 : src.elemsize == src.elempack * 2u && info.support_fp16_storage ? 2 : 1;
int cast_type_to_index = opt.use_fp16_storage ? 2 : opt.use_fp16_packed && dst_elempack % 4 == 0 ? 1 : 0;
int packing_type_to_index = dst_elempack == 1 ? 0 : dst_elempack == 4 ? 1 : 2;

@@ -1741,7 +1741,7 @@ void VulkanDevice::convert_packing(const VkImageMat& src, VkMat& dst, int dst_el
return;
}

int cast_type_from_index = src.elemsize == src.elempack * 4u ? 0 : opt.use_fp16_storage ? 2 : 1;
int cast_type_from_index = src.elemsize == src.elempack * 4u ? 0 : src.elemsize == src.elempack * 2u && info.support_fp16_storage ? 2 : 1;
int cast_type_to_index = opt.use_fp16_storage ? 2 : opt.use_fp16_packed && dst_elempack % 4 == 0 ? 1 : 0;
int packing_type_to_index = dst_elempack == 1 ? 0 : dst_elempack == 4 ? 1 : 2;

@@ -2082,7 +2082,7 @@ int VulkanDevice::create_utility_operator()
if (!info.support_fp16_storage && opt.use_fp16_storage)
continue;

// from pack1 | pack4 | pack8
// to pack1 | pack4 | pack8
for (int k=0; k<3; k++)
{
// enable pack8 for pack8to1/pack8to4
@@ -2141,10 +2141,11 @@ void VulkanDevice::destroy_utility_operator()
if (!info.support_fp16_storage && opt.use_fp16_storage)
continue;

// from pack1 | pack4 | pack8
// to pack1 | pack4 | pack8
for (int k=0; k<3; k++)
{
opt.use_shader_pack8 = (k == 2 || k == 2);
// enable pack8 for pack8to1/pack8to4
opt.use_shader_pack8 = true;

ncnn::Layer* uop = uop_packing[i0][i1][j0][j1][k];



+ 137
- 151
src/layer/vulkan/packing_vulkan.cpp View File

@@ -42,23 +42,36 @@ int Packing_vulkan::create_pipeline(const Option& _opt)
const Mat& out_shape = top_shapes.empty() ? Mat() : top_shapes[0];

size_t out_elemsize;
if (opt.use_fp16_storage)
if (cast_type_to == 0)
{
out_elemsize = out_elempack * 2u;
if (opt.use_fp16_storage)
{
out_elemsize = out_elempack * 2u;
}
else if (opt.use_fp16_packed)
{
if (out_elempack == 8) out_elemsize = 8*2u;
if (out_elempack == 4) out_elemsize = 4*2u;
if (out_elempack == 1) out_elemsize = 4u;
}
else
{
out_elemsize = out_elempack * 4u;
}
}
else if (opt.use_fp16_packed)
else if (cast_type_to == 1)
{
out_elemsize = out_elempack == 1 ? 4u : out_elempack * 2u;
out_elemsize = out_elempack * 4u;
}
else
else if (cast_type_to == 2)
{
out_elemsize = out_elempack * 4u;
if (out_elempack == 8) out_elemsize = 8*2u;
if (out_elempack == 4) out_elemsize = 4*2u;
if (out_elempack == 1) out_elemsize = 4u;
}

// type casting override
if (cast_type_to == 1)
else // if (cast_type_to == 3)
{
out_elemsize = out_elempack * 4u;
out_elemsize = out_elempack * 2u;
}

Mat out_shape_packed;
@@ -272,6 +285,39 @@ int Packing_vulkan::forward(const VkMat& bottom_blob, VkMat& top_blob, VkCompute
}
}

size_t out_elemsize;
if (cast_type_to == 0)
{
if (opt.use_fp16_storage)
{
out_elemsize = out_elempack * 2u;
}
else if (opt.use_fp16_packed)
{
if (out_elempack == 8) out_elemsize = 8*2u;
if (out_elempack == 4) out_elemsize = 4*2u;
if (out_elempack == 1) out_elemsize = 4u;
}
else
{
out_elemsize = out_elempack * 4u;
}
}
else if (cast_type_to == 1)
{
out_elemsize = out_elempack * 4u;
}
else if (cast_type_to == 2)
{
if (out_elempack == 8) out_elemsize = 8*2u;
if (out_elempack == 4) out_elemsize = 4*2u;
if (out_elempack == 1) out_elemsize = 4u;
}
else // if (cast_type_to == 3)
{
out_elemsize = out_elempack * 2u;
}

if (dims == 1)
{
if (opt.use_fp16_storage && out_elempack == 1 && cast_type_from == cast_type_to && bottom_blob.allocator == opt.blob_vkallocator)
@@ -285,19 +331,6 @@ int Packing_vulkan::forward(const VkMat& bottom_blob, VkMat& top_blob, VkCompute
}

int outw = (w * elempack + out_elempack - 1) / out_elempack;
size_t out_elemsize = elemsize / elempack * out_elempack;
if (opt.use_fp16_packed && !opt.use_fp16_storage)
{
if (out_elempack == 8) out_elemsize = 8*2u;
if (out_elempack == 4) out_elemsize = 4*2u;
if (out_elempack == 1) out_elemsize = 4u;
}

// type casting override
if (cast_type_to == 1)
{
out_elemsize = out_elempack * 4u;
}

top_blob.create(outw, out_elemsize, out_elempack, opt.blob_vkallocator);
if (top_blob.empty())
@@ -307,19 +340,6 @@ int Packing_vulkan::forward(const VkMat& bottom_blob, VkMat& top_blob, VkCompute
if (dims == 2)
{
int outh = (h * elempack + out_elempack - 1) / out_elempack;
size_t out_elemsize = elemsize / elempack * out_elempack;
if (opt.use_fp16_packed && !opt.use_fp16_storage)
{
if (out_elempack == 8) out_elemsize = 8*2u;
if (out_elempack == 4) out_elemsize = 4*2u;
if (out_elempack == 1) out_elemsize = 4u;
}

// type casting override
if (cast_type_to == 1)
{
out_elemsize = out_elempack * 4u;
}

top_blob.create(w, outh, out_elemsize, out_elempack, opt.blob_vkallocator);
if (top_blob.empty())
@@ -329,19 +349,6 @@ int Packing_vulkan::forward(const VkMat& bottom_blob, VkMat& top_blob, VkCompute
if (dims == 3)
{
int outc = (channels * elempack + out_elempack - 1) / out_elempack;
size_t out_elemsize = elemsize / elempack * out_elempack;
if (opt.use_fp16_packed && !opt.use_fp16_storage)
{
if (out_elempack == 8) out_elemsize = 8*2u;
if (out_elempack == 4) out_elemsize = 4*2u;
if (out_elempack == 1) out_elemsize = 4u;
}

// type casting override
if (cast_type_to == 1)
{
out_elemsize = out_elempack * 4u;
}

top_blob.create(w, h, outc, out_elemsize, out_elempack, opt.blob_vkallocator);
if (top_blob.empty())
@@ -425,7 +432,6 @@ int Packing_vulkan::forward(const VkImageMat& bottom_blob, VkImageMat& top_blob,
int h = bottom_blob.h;
int channels = bottom_blob.c;
int dims = bottom_blob.dims;
size_t elemsize = bottom_blob.elemsize;

if (!use_padding)
{
@@ -447,22 +453,42 @@ int Packing_vulkan::forward(const VkImageMat& bottom_blob, VkImageMat& top_blob,
}
}

if (dims == 1)
size_t out_elemsize;
if (cast_type_to == 0)
{
int outw = (w * elempack + out_elempack - 1) / out_elempack;
size_t out_elemsize = elemsize / elempack * out_elempack;
if (opt.use_fp16_packed && !opt.use_fp16_storage)
if (opt.use_fp16_storage)
{
out_elemsize = out_elempack * 2u;
}
else if (opt.use_fp16_packed)
{
if (out_elempack == 8) out_elemsize = 8*2u;
if (out_elempack == 4) out_elemsize = 4*2u;
if (out_elempack == 1) out_elemsize = 4u;
}

// type casting override
if (cast_type_to == 1)
else
{
out_elemsize = out_elempack * 4u;
}
}
else if (cast_type_to == 1)
{
out_elemsize = out_elempack * 4u;
}
else if (cast_type_to == 2)
{
if (out_elempack == 8) out_elemsize = 8*2u;
if (out_elempack == 4) out_elemsize = 4*2u;
if (out_elempack == 1) out_elemsize = 4u;
}
else // if (cast_type_to == 3)
{
out_elemsize = out_elempack * 2u;
}

if (dims == 1)
{
int outw = (w * elempack + out_elempack - 1) / out_elempack;

top_blob.create(outw, out_elemsize, out_elempack, opt.blob_vkallocator);
if (top_blob.empty())
@@ -472,19 +498,6 @@ int Packing_vulkan::forward(const VkImageMat& bottom_blob, VkImageMat& top_blob,
if (dims == 2)
{
int outh = (h * elempack + out_elempack - 1) / out_elempack;
size_t out_elemsize = elemsize / elempack * out_elempack;
if (opt.use_fp16_packed && !opt.use_fp16_storage)
{
if (out_elempack == 8) out_elemsize = 8*2u;
if (out_elempack == 4) out_elemsize = 4*2u;
if (out_elempack == 1) out_elemsize = 4u;
}

// type casting override
if (cast_type_to == 1)
{
out_elemsize = out_elempack * 4u;
}

top_blob.create(w, outh, out_elemsize, out_elempack, opt.blob_vkallocator);
if (top_blob.empty())
@@ -494,19 +507,6 @@ int Packing_vulkan::forward(const VkImageMat& bottom_blob, VkImageMat& top_blob,
if (dims == 3)
{
int outc = (channels * elempack + out_elempack - 1) / out_elempack;
size_t out_elemsize = elemsize / elempack * out_elempack;
if (opt.use_fp16_packed && !opt.use_fp16_storage)
{
if (out_elempack == 8) out_elemsize = 8*2u;
if (out_elempack == 4) out_elemsize = 4*2u;
if (out_elempack == 1) out_elemsize = 4u;
}

// type casting override
if (cast_type_to == 1)
{
out_elemsize = out_elempack * 4u;
}

top_blob.create(w, h, outc, out_elemsize, out_elempack, opt.blob_vkallocator);
if (top_blob.empty())
@@ -580,7 +580,6 @@ int Packing_vulkan::forward(const VkMat& bottom_blob, VkImageMat& top_blob, VkCo
int h = bottom_blob.h;
int channels = bottom_blob.c;
int dims = bottom_blob.dims;
size_t elemsize = bottom_blob.elemsize;

// if (!use_padding)
// {
@@ -589,22 +588,42 @@ int Packing_vulkan::forward(const VkMat& bottom_blob, VkImageMat& top_blob, VkCo
// return -1;
// }

if (dims == 1)
size_t out_elemsize;
if (cast_type_to == 0)
{
int outw = (w * elempack + out_elempack - 1) / out_elempack;
size_t out_elemsize = elemsize / elempack * out_elempack;
if (opt.use_fp16_packed && !opt.use_fp16_storage)
if (opt.use_fp16_storage)
{
out_elemsize = out_elempack * 2u;
}
else if (opt.use_fp16_packed)
{
if (out_elempack == 8) out_elemsize = 8*2u;
if (out_elempack == 4) out_elemsize = 4*2u;
if (out_elempack == 1) out_elemsize = 4u;
}

// type casting override
if (cast_type_to == 1)
else
{
out_elemsize = out_elempack * 4u;
}
}
else if (cast_type_to == 1)
{
out_elemsize = out_elempack * 4u;
}
else if (cast_type_to == 2)
{
if (out_elempack == 8) out_elemsize = 8*2u;
if (out_elempack == 4) out_elemsize = 4*2u;
if (out_elempack == 1) out_elemsize = 4u;
}
else // if (cast_type_to == 3)
{
out_elemsize = out_elempack * 2u;
}

if (dims == 1)
{
int outw = (w * elempack + out_elempack - 1) / out_elempack;

top_blob.create(outw, out_elemsize, out_elempack, opt.blob_vkallocator);
if (top_blob.empty())
@@ -614,19 +633,6 @@ int Packing_vulkan::forward(const VkMat& bottom_blob, VkImageMat& top_blob, VkCo
if (dims == 2)
{
int outh = (h * elempack + out_elempack - 1) / out_elempack;
size_t out_elemsize = elemsize / elempack * out_elempack;
if (opt.use_fp16_packed && !opt.use_fp16_storage)
{
if (out_elempack == 8) out_elemsize = 8*2u;
if (out_elempack == 4) out_elemsize = 4*2u;
if (out_elempack == 1) out_elemsize = 4u;
}

// type casting override
if (cast_type_to == 1)
{
out_elemsize = out_elempack * 4u;
}

top_blob.create(w, outh, out_elemsize, out_elempack, opt.blob_vkallocator);
if (top_blob.empty())
@@ -636,19 +642,6 @@ int Packing_vulkan::forward(const VkMat& bottom_blob, VkImageMat& top_blob, VkCo
if (dims == 3)
{
int outc = (channels * elempack + out_elempack - 1) / out_elempack;
size_t out_elemsize = elemsize / elempack * out_elempack;
if (opt.use_fp16_packed && !opt.use_fp16_storage)
{
if (out_elempack == 8) out_elemsize = 8*2u;
if (out_elempack == 4) out_elemsize = 4*2u;
if (out_elempack == 1) out_elemsize = 4u;
}

// type casting override
if (cast_type_to == 1)
{
out_elemsize = out_elempack * 4u;
}

top_blob.create(w, h, outc, out_elemsize, out_elempack, opt.blob_vkallocator);
if (top_blob.empty())
@@ -722,7 +715,6 @@ int Packing_vulkan::forward(const VkImageMat& bottom_blob, VkMat& top_blob, VkCo
int h = bottom_blob.h;
int channels = bottom_blob.c;
int dims = bottom_blob.dims;
size_t elemsize = bottom_blob.elemsize;

// if (!use_padding)
// {
@@ -731,22 +723,42 @@ int Packing_vulkan::forward(const VkImageMat& bottom_blob, VkMat& top_blob, VkCo
// return -1;
// }

if (dims == 1)
size_t out_elemsize;
if (cast_type_to == 0)
{
int outw = (w * elempack + out_elempack - 1) / out_elempack;
size_t out_elemsize = elemsize / elempack * out_elempack;
if (opt.use_fp16_packed && !opt.use_fp16_storage)
if (opt.use_fp16_storage)
{
out_elemsize = out_elempack * 2u;
}
else if (opt.use_fp16_packed)
{
if (out_elempack == 8) out_elemsize = 8*2u;
if (out_elempack == 4) out_elemsize = 4*2u;
if (out_elempack == 1) out_elemsize = 4u;
}

// type casting override
if (cast_type_to == 1)
else
{
out_elemsize = out_elempack * 4u;
}
}
else if (cast_type_to == 1)
{
out_elemsize = out_elempack * 4u;
}
else if (cast_type_to == 2)
{
if (out_elempack == 8) out_elemsize = 8*2u;
if (out_elempack == 4) out_elemsize = 4*2u;
if (out_elempack == 1) out_elemsize = 4u;
}
else // if (cast_type_to == 3)
{
out_elemsize = out_elempack * 2u;
}

if (dims == 1)
{
int outw = (w * elempack + out_elempack - 1) / out_elempack;

top_blob.create(outw, out_elemsize, out_elempack, opt.blob_vkallocator);
if (top_blob.empty())
@@ -756,19 +768,6 @@ int Packing_vulkan::forward(const VkImageMat& bottom_blob, VkMat& top_blob, VkCo
if (dims == 2)
{
int outh = (h * elempack + out_elempack - 1) / out_elempack;
size_t out_elemsize = elemsize / elempack * out_elempack;
if (opt.use_fp16_packed && !opt.use_fp16_storage)
{
if (out_elempack == 8) out_elemsize = 8*2u;
if (out_elempack == 4) out_elemsize = 4*2u;
if (out_elempack == 1) out_elemsize = 4u;
}

// type casting override
if (cast_type_to == 1)
{
out_elemsize = out_elempack * 4u;
}

top_blob.create(w, outh, out_elemsize, out_elempack, opt.blob_vkallocator);
if (top_blob.empty())
@@ -778,19 +777,6 @@ int Packing_vulkan::forward(const VkImageMat& bottom_blob, VkMat& top_blob, VkCo
if (dims == 3)
{
int outc = (channels * elempack + out_elempack - 1) / out_elempack;
size_t out_elemsize = elemsize / elempack * out_elempack;
if (opt.use_fp16_packed && !opt.use_fp16_storage)
{
if (out_elempack == 8) out_elemsize = 8*2u;
if (out_elempack == 4) out_elemsize = 4*2u;
if (out_elempack == 1) out_elemsize = 4u;
}

// type casting override
if (cast_type_to == 1)
{
out_elemsize = out_elempack * 4u;
}

top_blob.create(w, h, outc, out_elemsize, out_elempack, opt.blob_vkallocator);
if (top_blob.empty())


+ 10
- 0
src/layer/vulkan/priorbox_vulkan.cpp View File

@@ -16,6 +16,7 @@
#include <algorithm>
#include <math.h>
#include "layer_shader_type.h"
#include "platform.h"

namespace ncnn {

@@ -31,6 +32,15 @@ PriorBox_vulkan::PriorBox_vulkan()

int PriorBox_vulkan::create_pipeline(const Option& opt)
{
#if NCNN_VULKAN_ONLINE_SPIRV
if (opt.use_fp16_storage)
{
// TODO investigate why fp16s produce wrong output
support_vulkan = false;
return 0;
}
#endif

const Mat& shape = bottom_shapes.empty() ? Mat() : bottom_shapes[0];

int elempack = 1;


Loading…
Cancel
Save