| 264 | } // namespace |
| 265 | |
| 266 | void TrMul(TrMulParams* params, Context* context) { |
| 267 | gemmlowp::ScopedProfilingLabel label("TrMul"); |
| 268 | |
| 269 | PMatrix& packed_lhs = params->packed[Side::kLhs]; |
| 270 | PMatrix& packed_rhs = params->packed[Side::kRhs]; |
| 271 | DMatrix& lhs = params->src[Side::kLhs]; |
| 272 | DMatrix& rhs = params->src[Side::kRhs]; |
| 273 | |
| 274 | const int rows = lhs.layout.cols; |
| 275 | const int cols = rhs.layout.cols; |
| 276 | const int depth = lhs.layout.rows; |
| 277 | |
| 278 | int thread_count = GetThreadCount(context, rows, cols, depth); |
| 279 | const auto loop_structure = |
| 280 | GetLoopStructure(thread_count, rows, cols, depth, |
| 281 | params->cache_friendly_traversal_threshold); |
| 282 | Allocator* allocator = context->GetMainAllocator(); |
| 283 | |
| 284 | // Allocate packed matrices |
| 285 | for (Side side : {Side::kLhs, Side::kRhs}) { |
| 286 | if (!params->is_prepacked[side]) { |
| 287 | AllocatePMatrix(allocator, ¶ms->packed[side]); |
| 288 | } |
| 289 | } |
| 290 | |
| 291 | // Case of running this TrMul as a simple loop. |
| 292 | // This is a good place to start reading this function: all the rest |
| 293 | // of this function is just an optimized, but functionally equivalent, |
| 294 | // version of that. |
| 295 | if (loop_structure == LoopStructure::kSimple) { |
| 296 | gemmlowp::ScopedProfilingLabel label_simple("TrMulImpl, simple loop"); |
| 297 | Tuning tuning = context->GetMainThreadTuning(); |
| 298 | |
| 299 | const SidePair<int> origin{0, 0}; |
| 300 | const SidePair<int> rounded_dims{packed_lhs.layout.cols, |
| 301 | packed_rhs.layout.cols}; |
| 302 | for (Side side : {Side::kLhs, Side::kRhs}) { |
| 303 | if (!params->is_prepacked[side]) { |
| 304 | params->RunPack(side, tuning, origin[side], rounded_dims[side]); |
| 305 | } |
| 306 | } |
| 307 | params->RunKernel(tuning, origin, rounded_dims); |
| 308 | |
| 309 | allocator->FreeAll(); |
| 310 | return; |
| 311 | } |
| 312 | |
| 313 | gemmlowp::ScopedProfilingLabel label_general("TrMulImpl, general case"); |
| 314 | |
| 315 | auto* trace = NewTraceOrNull(&context->tracing, rows, depth, cols); |
| 316 | TraceRecordStart(trace); |
| 317 | |
| 318 | // Initialize block map. |
| 319 | BlockMap block_map; |
| 320 | MakeBlockMap(packed_lhs.layout.cols, packed_rhs.layout.cols, depth, |
| 321 | packed_lhs.layout.kernel.cols, packed_rhs.layout.kernel.cols, |
| 322 | packed_lhs.data_type.size, packed_rhs.data_type.size, |
| 323 | params->cache_friendly_traversal_threshold, &block_map); |
no test coverage detected