| 200 | ClFullyConnected::~ClFullyConnected() = default; |
| 201 | |
| 202 | void ClFullyConnected::configure_mm(const CLCompileContext &compile_context, |
| 203 | ITensorInfo *src, |
| 204 | ITensorInfo *weights, |
| 205 | ITensorInfo *bias, |
| 206 | ITensorInfo *dst, |
| 207 | const FullyConnectedLayerInfo &fc_info) |
| 208 | { |
| 209 | // If weights are dynamic and matmul is supported use matmul, else use gemm |
| 210 | if (_use_matmul) |
| 211 | { |
| 212 | // Specify whether transpose weights is necessary in matmul info |
| 213 | const MatMulInfo mat_info = MatMulInfo().adj_rhs(_transpose_weights); |
| 214 | |
| 215 | // Note: MatMul does not need offset negation unlike gemm |
| 216 | // 1. Change shape when calling matmul to fit batch expectations. |
| 217 | _lhs_to_use = src->clone()->set_tensor_shape(get_reshaped_matmul_tensor(_lhs_to_use.tensor_shape())); |
| 218 | |
| 219 | // 2. Use heuristics to get kernel info object |
| 220 | const GPUTarget gpu_target = CLScheduler::get().target(); |
| 221 | std::unique_ptr<cl_matmul::IClMatMulNativeKernelConfig> kernel_config = |
| 222 | cl_matmul::ClMatMulNativeKernelConfigurationFactory::create(gpu_target); |
| 223 | MatMulKernelInfo kernel_info = kernel_config->configure(src, weights, mat_info); |
| 224 | |
| 225 | // 3. Configure relevant matmul kernel |
| 226 | if (_is_quantized) |
| 227 | { |
| 228 | _matmul_lowp_native_kernel = std::make_unique<kernels::ClMatMulLowpNativeKernel>(); |
| 229 | _matmul_lowp_native_kernel->set_target(gpu_target); |
| 230 | _matmul_lowp_native_kernel->configure(compile_context, src, weights, bias, dst, kernel_info, |
| 231 | fc_info.activation_info); |
| 232 | } |
| 233 | else |
| 234 | { |
| 235 | _matmul_native_kernel = std::make_unique<kernels::ClMatMulNativeKernel>(); |
| 236 | _matmul_native_kernel->set_target(gpu_target); |
| 237 | _matmul_native_kernel->configure(compile_context, src, weights, bias, dst, kernel_info, |
| 238 | fc_info.activation_info); |
| 239 | } |
| 240 | } |
| 241 | else |
| 242 | { |
| 243 | // Configure GEMM |
| 244 | GEMMLowpOutputStageInfo gemmlowp_output_stage; |
| 245 | construct_gemmlowp_output_stage(*src, *weights, *dst, gemmlowp_output_stage, fc_info.activation_info); |
| 246 | |
| 247 | const GEMMInfo &gemm_info = GEMMInfo(false, // is_a_reshaped |
| 248 | false, // is_b_reshaped |
| 249 | !_dynamic_gemm, // reshape_b_only_on_first_run |
| 250 | 0, // depth_output_gemm3d |
| 251 | false, // reinterpret_input_as_3d |
| 252 | fc_info.retain_internal_weights, // retain_internal_weights |
| 253 | gemmlowp_output_stage, // gemmlowp_output_stage |
| 254 | fc_info.fp_mixed_precision, // fp_mixed_precision |
| 255 | false, // fast_math |
| 256 | true, // broadcast_bias |
| 257 | fc_info.activation_info); // activation_info |
| 258 | |
| 259 | if (_is_quantized) |
nothing calls this directly
no test coverage detected