| 968 | } |
| 969 | |
| 970 | std::vector<ComputeTaskDescriptorPtr> Convolution1x1( |
| 971 | int id, ValueId input_id, ValueId output_id, |
| 972 | const Convolution2DAttributes& params, |
| 973 | const metal::RuntimeOptions& options) { |
| 974 | auto desc = std::make_shared<ComputeTaskDescriptor>(); |
| 975 | desc->id = id; |
| 976 | desc->is_linkable = false; |
| 977 | const int z_out = GetNumOutputSlices(params.weights.shape.o); |
| 978 | desc->shader_source = GetKernelForConv1x1(params, z_out); |
| 979 | |
| 980 | desc->input_buffers = { |
| 981 | {input_id, "device FLT4* const src_buffer"}, |
| 982 | }; |
| 983 | |
| 984 | desc->output_buffer = { |
| 985 | output_id, "device FLT4* dst_buffer", |
| 986 | [input_id, params](const std::map<ValueId, BHWC>& buffers) { |
| 987 | auto out_shape = |
| 988 | CalculateOutputShape(buffers.find(input_id)->second, params); |
| 989 | return out_shape; |
| 990 | }}; |
| 991 | |
| 992 | auto weights_reordered = ReorderWeightsForConv(params, z_out); |
| 993 | auto weights = |
| 994 | options.storage_precision == metal::RuntimeOptions::Precision::FP32 |
| 995 | ? VectorToUint8Vector(weights_reordered) |
| 996 | : VectorFloatToHalf(weights_reordered); |
| 997 | auto biases = |
| 998 | options.storage_precision == metal::RuntimeOptions::Precision::FP32 |
| 999 | ? VectorToUint8Vector(params.bias.data) |
| 1000 | : VectorFloatToHalf(params.bias.data); |
| 1001 | desc->immutable_buffers = { |
| 1002 | {"device FLT4* const filters", weights}, |
| 1003 | {"device FLT4* const biases", biases}, |
| 1004 | }; |
| 1005 | |
| 1006 | desc->uniform_buffers = { |
| 1007 | {"constant uniforms& params", |
| 1008 | [input_id, output_id, params](const std::map<ValueId, BHWC>& buffers) { |
| 1009 | const auto& input_dimensions = buffers.find(input_id)->second; |
| 1010 | const auto& output_dimensions = buffers.find(output_id)->second; |
| 1011 | return GetUniformBufferForConv(input_dimensions, output_dimensions, |
| 1012 | params); |
| 1013 | }}, |
| 1014 | }; |
| 1015 | |
| 1016 | desc->resize_function = [output_id, |
| 1017 | params](const std::map<ValueId, BHWC>& buffers) { |
| 1018 | const auto& output_dims = buffers.find(output_id)->second; |
| 1019 | const uint3 group_size = GetWorkGroupForConv(); |
| 1020 | const uint3 groups_count = GetGroupsCountForConv(group_size, output_dims); |
| 1021 | return std::make_pair( |
| 1022 | group_size, uint3{groups_count.z, groups_count.x, groups_count.y}); |
| 1023 | }; |
| 1024 | |
| 1025 | return {desc}; |
| 1026 | } |
| 1027 |
no test coverage detected