| 913 | } // namespace |
| 914 | |
| 915 | std::vector<ComputeTaskDescriptorPtr> Convolution( |
| 916 | int id, ValueId input_id, ValueId output_id, |
| 917 | const Convolution2DAttributes& params, const RuntimeOptions& options) { |
| 918 | auto desc = std::make_shared<ComputeTaskDescriptor>(); |
| 919 | desc->id = id; |
| 920 | desc->is_linkable = false; |
| 921 | desc->shader_source = GetKernelForConv(params); |
| 922 | |
| 923 | desc->input_buffers = { |
| 924 | {input_id, "device FLT4* const src_buffer"}, |
| 925 | }; |
| 926 | |
| 927 | desc->output_buffer = { |
| 928 | output_id, "device FLT4* dst_buffer", |
| 929 | [input_id, params](const std::map<ValueId, BHWC>& buffers) { |
| 930 | return CalculateOutputShape(buffers.find(input_id)->second, params); |
| 931 | }}; |
| 932 | |
| 933 | auto weights_reordered = ReorderWeightsForConvShared(params); |
| 934 | auto weights = options.storage_precision == RuntimeOptions::Precision::FP32 |
| 935 | ? VectorToUint8Vector(weights_reordered) |
| 936 | : VectorFloatToHalf(weights_reordered); |
| 937 | auto biases = options.storage_precision == RuntimeOptions::Precision::FP32 |
| 938 | ? VectorToUint8Vector(params.bias.data) |
| 939 | : VectorFloatToHalf(params.bias.data); |
| 940 | desc->immutable_buffers = { |
| 941 | {"device FLT4* const weights", weights}, |
| 942 | {"device FLT4* const biases", biases}, |
| 943 | }; |
| 944 | |
| 945 | desc->uniform_buffers = { |
| 946 | {"constant uniforms& params", |
| 947 | [input_id, output_id, params](const std::map<ValueId, BHWC>& buffers) { |
| 948 | const auto& input_dimensions = buffers.find(input_id)->second; |
| 949 | const auto& output_dimensions = buffers.find(output_id)->second; |
| 950 | return GetUniformBufferForConvShared(input_dimensions, |
| 951 | output_dimensions, params); |
| 952 | }}, |
| 953 | }; |
| 954 | |
| 955 | desc->resize_function = [output_id, |
| 956 | params](const std::map<ValueId, BHWC>& buffers) { |
| 957 | const auto& output_dims = buffers.find(output_id)->second; |
| 958 | const int num_output_slices = GetNumOutputSlices(params.weights.shape.o); |
| 959 | const uint3 group_size{8, 4, 1}; |
| 960 | int groups_x = IntegralDivideRoundUp(output_dims.w, group_size.x); |
| 961 | int groups_y = IntegralDivideRoundUp(output_dims.h, group_size.y); |
| 962 | const int dst_depth = IntegralDivideRoundUp(params.weights.shape.o, 4); |
| 963 | int groups_z = IntegralDivideRoundUp(dst_depth, num_output_slices); |
| 964 | return std::make_pair(group_size, uint3{groups_x, groups_y, groups_z}); |
| 965 | }; |
| 966 | |
| 967 | return {desc}; |
| 968 | } |
| 969 | |
| 970 | std::vector<ComputeTaskDescriptorPtr> Convolution1x1( |
| 971 | int id, ValueId input_id, ValueId output_id, |
no test coverage detected