tensorflow/lite/kernels/internal/optimized/neon_tensor_utils.cc
// Empirically determined breakpoints on when to use CpuBackendGemm vs.
// standard MatrixBatchVectorMultiplyAccumulate. Briefly, if the batch size
// is above 8 and the device does not have sdot, use CpuBackendGemm. Otherwise,
// for large batch sizes, it makes sense to use CpuBackendGemm if the matrix
// is not extremely rectangular.
Empirically determined breakpoints on when to use CpuBackendGemm vs.
Empirically determined breakpoints on when to use CpuBackendGemm vs .
bool UseCpuBackendGemm(int rows, int cols, int batch) {
  if (!HasSdotInstruction()) {
    return batch >= 8;
  }
  if (batch < 16) {
    return false;
  }
  constexpr int kCpuBackendGemmThreshold = 2;
  int row_rect = rows / cols;
  int col_rect = cols / rows;
  int rectangularness_lg2 =
      row_rect > 0 ? FloorLog2(row_rect) : FloorLog2(col_rect);
  int batch_lg2 = FloorLog2(batch);
  int batch_lg2_minus_rect_lg2 = batch_lg2 - rectangularness_lg2;
  return batch_lg2_minus_rect_lg2 > kCpuBackendGemmThreshold;
}
bool UseCpuBackendGemm ( int rows , int cols , int batch ) { if ( ! HasSdotInstruction ( ) ) { return batch >= 8 ; } if ( batch < 16 ) { return false ; } constexpr int kCpuBackendGemmThreshold = 2 ; int row_rect = rows / cols ; int col_rect = cols / rows ; int rectangularness_lg2 = row_rect > 0 ? FloorLog2 ( row_rect ) : FloorLog2 ( col_rect ) ; int batch_lg2 = FloorLog2 ( batch ) ; int batch_lg2_minus_rect_lg2 = batch_lg2 - rectangularness_lg2 ; return batch_lg2_minus_rect_lg2 > kCpuBackendGemmThreshold ; }
Empirically determined breakpoints on when to use CpuBackendGemm vs.
standard MatrixBatchVectorMultiplyAccumulate.
Empirically determined breakpoints on when to use CpuBackendGemm vs . standard MatrixBatchVectorMultiplyAccumulate .
// Calculate "rectangularness" as a measure of how far from square the // the LHS matrix is. // Large batch sizes move us above the threshold, but can be offset // by significant rectangularness.