1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-29 15:23:05 +04:00
Files
opencv/modules/dnn/src/vkcom/shader/conv.comp
T
WuZhiwen 3d44e9ad92 Merge pull request #13520 from wzw-intel:hang
* dnn/Vulkan: fix GPU hang for heavy convolution tasks

Intel i915 driver will declare GPU hang if the compute shader
takes too long to complete. See
https://bugs.freedesktop.org/show_bug.cgi?id=108947 for details.

The idea in this commit is to divide heavy task into several light
ones and run compute shader multiple times to make each run take
short time enough.

TODO: Add more efficient compute shader

Signed-off-by: Wu Zhiwen <zhiwen.wu@intel.com>

* dnn/Vulkan: add a more efficient conv shader
2018-12-27 15:06:44 +03:00

77 lines
2.2 KiB
Plaintext

#version 450
#define LOCAL_SZ_X 256
layout(binding = 0) readonly buffer Input0{
float image_data[];
};
layout(binding = 1) readonly buffer Input1 {
float bias_data[];
};
layout(binding = 2) readonly buffer Input3{
float weight_data[];
};
layout(binding = 3) writeonly buffer Output{
float convolved_image_data[];
};
layout(push_constant) uniform pushBlock {
int in_h;
int in_w;
int out_h;
int out_w;
int stride_h;
int stride_w;
int pad_h;
int pad_w;
int filter_h;
int filter_w;
int dilation_h;
int dilation_w;
int channels;
int batch;
int has_bias;
int M;
int K;
int N;
int basic_shader_batch_idx;
int basic_shader_partition_idx;
int basic_shader_partition_size;
} p;
layout(local_size_x = LOCAL_SZ_X, local_size_y = 1, local_size_z = 1) in;
void main()
{
int gx = int(gl_GlobalInvocationID.x);
int gy = int(gl_GlobalInvocationID.y) + p.basic_shader_partition_idx * p.basic_shader_partition_size;
int gz = p.basic_shader_batch_idx;
if(gx < p.M && gy < p.N)
{
float sum = 0.0f;
int output_y = gx / p.out_w;
int output_x = gx % p.out_w;
int org_y = output_y * p.stride_h - p.pad_h;
int org_x = output_x * p.stride_w - p.pad_w;
int weight_off = gy * p.K;
int input_off = gz * p.in_h * p.in_w * p.channels + (org_y * p.in_w + org_x);
for(int c = 0; c < p.channels; c++)
{
for(int y = 0; y < p.filter_h; y++)
{
for(int x = 0; x < p.filter_w; x++)
{
if((org_y + y * p.dilation_h >= 0) && (org_y + y * p.dilation_h < p.in_h) && (org_x + x * p.dilation_w >= 0) && (org_x + x * p.dilation_w < p.in_w))
{
sum += image_data[input_off + x * p.dilation_w] * weight_data[weight_off + x];
}
}
input_off += p.in_w * p.dilation_h;
weight_off += p.filter_w;
}
input_off += p.in_h * p.in_w - p.in_w * p.filter_h * p.dilation_h;
}
int offset = gz * p.M * p.N + gx + gy * p.M;
if (p.has_bias == 1)
sum += bias_data[gy];
convolved_image_data[offset] = sum;
}
}