Avoid division with zero on CLGEMM lhs/rhs configuration

Resolves COMPMID-4285

Signed-off-by: Georgios Pinitas <georgios.pinitas@arm.com>
Change-Id: I414e3ba352ed86345d6355d9ae366ea92e641842
Reviewed-on: https://review.mlplatform.org/c/ml/ComputeLibrary/+/5153
Tested-by: Arm Jenkins <bsgcomp@arm.com>
Reviewed-by: Michele Di Giorgio <michele.digiorgio@arm.com>
Comments-Addressed: Arm Jenkins <bsgcomp@arm.com>
diff --git a/src/core/CL/gemm/CLGEMMHelpers.cpp b/src/core/CL/gemm/CLGEMMHelpers.cpp
index d60626b..5abe224 100644
--- a/src/core/CL/gemm/CLGEMMHelpers.cpp
+++ b/src/core/CL/gemm/CLGEMMHelpers.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2020 Arm Limited.
+ * Copyright (c) 2019-2021 Arm Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -40,6 +40,7 @@
 std::pair<GEMMLHSMatrixInfo, GEMMRHSMatrixInfo> configure_lhs_rhs_info(unsigned int m, unsigned int n, unsigned int m0, unsigned int n0, unsigned int k0, unsigned int v0, unsigned int h0,
                                                                        bool lhs_interleave, bool rhs_interleave, bool lhs_transpose, bool rhs_transpose, bool export_to_cl_image)
 {
+    ARM_COMPUTE_ERROR_ON(m0 == 0 || n0 == 0);
     v0 = std::max(std::min(static_cast<int>(m / m0), static_cast<int>(v0)), static_cast<int>(1));
     h0 = std::max(std::min(static_cast<int>(n / n0), static_cast<int>(h0)), static_cast<int>(1));
 
diff --git a/src/runtime/CL/gemm_auto_heuristics/CLGEMMAutoHeuristics.cpp b/src/runtime/CL/gemm_auto_heuristics/CLGEMMAutoHeuristics.cpp
index 45a6398..489be35 100644
--- a/src/runtime/CL/gemm_auto_heuristics/CLGEMMAutoHeuristics.cpp
+++ b/src/runtime/CL/gemm_auto_heuristics/CLGEMMAutoHeuristics.cpp
@@ -105,14 +105,14 @@
     if(valid)
     {
         ARM_COMPUTE_LOG_INFO_MSG_WITH_FORMAT_CORE("MLGOHeuristics query returns gemm config: %s.", to_string(config).c_str());
+        // Setting irrelevant unsigned int parameters to 1 and bool parameters to false as they do no matter
+        std::tie(lhs_info, rhs_info) = configure_lhs_rhs_info(query.m, query.n, config.m0, config.n0, config.k0, 1, config.h0, false, config.interleave_rhs, !config.transpose_rhs, config.transpose_rhs,
+                                                              config.export_cl_image);
     }
     else
     {
         ARM_COMPUTE_LOG_INFO_MSG_CORE("MLGOHeuristics query failed");
     }
-    // Setting irrelevant unsigned int parameters to 1 and bool parameters to false as they do no matter
-    std::tie(lhs_info, rhs_info) = configure_lhs_rhs_info(query.m, query.n, config.m0, config.n0, config.k0, 1, config.h0, false, config.interleave_rhs, !config.transpose_rhs, config.transpose_rhs,
-                                                          config.export_cl_image);
     return GEMMConfigResult{ valid, lhs_info, rhs_info };
 }
 
@@ -140,14 +140,13 @@
     if(valid)
     {
         ARM_COMPUTE_LOG_INFO_MSG_WITH_FORMAT_CORE("MLGOHeuristics query returns gemm config: %s.", to_string(config).c_str());
+        std::tie(lhs_info, rhs_info) = configure_lhs_rhs_info(query.m, query.n, config.m0, config.n0, config.k0, config.v0, config.h0, config.interleave_lhs, config.interleave_rhs, !config.transpose_rhs,
+                                                              config.transpose_rhs, config.export_cl_image);
     }
     else
     {
         ARM_COMPUTE_LOG_INFO_MSG_CORE("MLGOHeuristics query failed");
     }
-    std::tie(lhs_info, rhs_info) = configure_lhs_rhs_info(query.m, query.n, config.m0, config.n0, config.k0, config.v0, config.h0, config.interleave_lhs, config.interleave_rhs, !config.transpose_rhs,
-                                                          config.transpose_rhs,
-                                                          config.export_cl_image);
     return GEMMConfigResult{ valid, lhs_info, rhs_info };
 }
 
@@ -175,13 +174,13 @@
     if(valid)
     {
         ARM_COMPUTE_LOG_INFO_MSG_WITH_FORMAT_CORE("MLGOHeuristics query returns gemm config: %s.", to_string(config).c_str());
+        // Setting irrelevant unsigned int parameters to 1 and bool parameters to false as they do no matter
+        std::tie(lhs_info, rhs_info) = configure_lhs_rhs_info(query.m, query.n, config.m0, config.n0, config.k0, 1, 1, false, false, false, false, false);
     }
     else
     {
         ARM_COMPUTE_LOG_INFO_MSG_CORE("MLGOHeuristics query failed");
     }
-    // Setting irrelevant unsigned int parameters to 1 and bool parameters to false as they do no matter
-    std::tie(lhs_info, rhs_info) = configure_lhs_rhs_info(query.m, query.n, config.m0, config.n0, config.k0, 1, 1, false, false, false, false, false);
     return GEMMConfigResult{ valid, lhs_info, rhs_info };
 }
 } // namespace auto_heuristics
diff --git a/src/runtime/CL/mlgo/Common.h b/src/runtime/CL/mlgo/Common.h
index 9e06689..c451bd9 100644
--- a/src/runtime/CL/mlgo/Common.h
+++ b/src/runtime/CL/mlgo/Common.h
@@ -45,35 +45,35 @@
 /** GEMM Configuration for Native kernel */
 struct GEMMConfigNative
 {
-    unsigned int m0; /**< Number of rows processed by the matrix multiplication */
-    unsigned int n0; /**< Number of columns processed by the matrix multiplication */
-    unsigned int k0; /**< Number of partial accumulations performed by the matrix multiplication */
+    unsigned int m0{ 1 }; /**< Number of rows processed by the matrix multiplication */
+    unsigned int n0{ 1 }; /**< Number of columns processed by the matrix multiplication */
+    unsigned int k0{ 1 }; /**< Number of partial accumulations performed by the matrix multiplication */
 };
 
 /** GEMM Configuration for Reshaped Only RHS kernel */
 struct GEMMConfigReshapedOnlyRHS
 {
-    unsigned int m0;              /**< Number of rows processed by the matrix multiplication */
-    unsigned int n0;              /**< Number of columns processed by the matrix multiplication */
-    unsigned int k0;              /**< Number of partial accumulations performed by the matrix multiplication */
-    unsigned int h0;              /**< Number of horizontal blocks of size (k0xn0) stored on the same output row */
-    bool         interleave_rhs;  /**< True if the h0 (k0xn0) blocks have to be interleaved in the output row */
-    bool         transpose_rhs;   /**< True if the (k0xn0) block has to be transposed before been stored */
-    bool         export_cl_image; /**< True if the reshaped rhs has to be exported to cl_image. n0 must be equal to 4 */
+    unsigned int m0{ 1 };                  /**< Number of rows processed by the matrix multiplication */
+    unsigned int n0{ 1 };                  /**< Number of columns processed by the matrix multiplication */
+    unsigned int k0{ 1 };                  /**< Number of partial accumulations performed by the matrix multiplication */
+    unsigned int h0{ 1 };                  /**< Number of horizontal blocks of size (k0xn0) stored on the same output row */
+    bool         interleave_rhs{ false };  /**< True if the h0 (k0xn0) blocks have to be interleaved in the output row */
+    bool         transpose_rhs{ false };   /**< True if the (k0xn0) block has to be transposed before been stored */
+    bool         export_cl_image{ false }; /**< True if the reshaped rhs has to be exported to cl_image. n0 must be equal to 4 */
 };
 
 /** GEMM Configuration for Reshaped kernel */
 struct GEMMConfigReshaped
 {
-    unsigned int m0;              /**< Number of rows processed by the matrix multiplication */
-    unsigned int n0;              /**< Number of columns processed by the matrix multiplication */
-    unsigned int k0;              /**< Number of partial accumulations performed by the matrix multiplication */
-    unsigned int v0;              /**< Number of vertical blocks of size (m0xk0) stored on the same output row */
-    unsigned int h0;              /**< Number of horizontal blocks of size (k0xn0) stored on the same output row */
-    bool         interleave_lhs;  /**< True if the v0 (m0xk0) blocks have to be interleaved in the output row */
-    bool         interleave_rhs;  /**< True if the h0 (k0xn0) blocks have to be interleaved in the output row */
-    bool         transpose_rhs;   /**< True if the (k0xn0) block has to be transposed before been stored */
-    bool         export_cl_image; /**< True if the reshaped rhs has to be exported to cl_image. n0 must be equal to 4 */
+    unsigned int m0{ 1 };                  /**< Number of rows processed by the matrix multiplication */
+    unsigned int n0{ 1 };                  /**< Number of columns processed by the matrix multiplication */
+    unsigned int k0{ 1 };                  /**< Number of partial accumulations performed by the matrix multiplication */
+    unsigned int v0{ 1 };                  /**< Number of vertical blocks of size (m0xk0) stored on the same output row */
+    unsigned int h0{ 1 };                  /**< Number of horizontal blocks of size (k0xn0) stored on the same output row */
+    bool         interleave_lhs{ false };  /**< True if the v0 (m0xk0) blocks have to be interleaved in the output row */
+    bool         interleave_rhs{ false };  /**< True if the h0 (k0xn0) blocks have to be interleaved in the output row */
+    bool         transpose_rhs{ false };   /**< True if the (k0xn0) block has to be transposed before been stored */
+    bool         export_cl_image{ false }; /**< True if the reshaped rhs has to be exported to cl_image. n0 must be equal to 4 */
 };
 
 } // namespace mlgo