Integrate MLGO into CLGEMM and CLGEMMLowpMatrixMultiplyCore: Part1
authorSiCong Li <sicong.li@arm.com>
Fri, 5 Feb 2021 09:19:51 +0000 (09:19 +0000)
committerSiCong Li <sicong.li@arm.com>
Tue, 9 Feb 2021 09:47:22 +0000 (09:47 +0000)
* Create a new public handle class CLGEMMHeuristicsHandle
  It is responsible for the loading and lifetime management of the
  underlying heuristics

* Add to_string utility to several mlgo constructs for logging

Resolves: COMPMID-3843, COMPMID-3844

Signed-off-by: SiCong Li <sicong.li@arm.com>
Change-Id: Ib9c65e076daa6a9a204999cde9abf366dbabc496
Reviewed-on: https://review.mlplatform.org/c/ml/ComputeLibrary/+/5001
Tested-by: Arm Jenkins <bsgcomp@arm.com>
Reviewed-by: Georgios Pinitas <georgios.pinitas@arm.com>
Comments-Addressed: Arm Jenkins <bsgcomp@arm.com>

Android.bp
arm_compute/runtime/CL/CLGEMMHeuristicsHandle.h [new file with mode: 0644]
src/runtime/CL/CLGEMMHeuristicsHandle.cpp [new file with mode: 0644]
src/runtime/CL/mlgo/Common.h
src/runtime/CL/mlgo/HeuristicTree.h
src/runtime/CL/mlgo/MLGOHeuristics.cpp
src/runtime/CL/mlgo/MLGOHeuristics.h
src/runtime/CL/mlgo/MLGOParser.h
src/runtime/CL/mlgo/Utils.cpp
src/runtime/CL/mlgo/Utils.h
tests/validation/CL/UNIT/MLGOHeuristics.cpp

index 94a4e6c13a4686142b85fd3bb222c667d609e283..b531457673dbc159f4b8259d737fd695e53a3464 100644 (file)
@@ -463,6 +463,7 @@ cc_library_static {
         "src/runtime/BlobMemoryPool.cpp",
         "src/runtime/CL/CLBufferAllocator.cpp",
         "src/runtime/CL/CLDistribution1D.cpp",
+        "src/runtime/CL/CLGEMMHeuristicsHandle.cpp",
         "src/runtime/CL/CLHOG.cpp",
         "src/runtime/CL/CLHelpers.cpp",
         "src/runtime/CL/CLLut.cpp",
diff --git a/arm_compute/runtime/CL/CLGEMMHeuristicsHandle.h b/arm_compute/runtime/CL/CLGEMMHeuristicsHandle.h
new file mode 100644 (file)
index 0000000..d81c55b
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2021 Arm Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef ARM_COMPUTE_RUNTIME_CL_CL_GEMM_HEURISTICS_HANDLE_H
+#define ARM_COMPUTE_RUNTIME_CL_CL_GEMM_HEURISTICS_HANDLE_H
+
+#include <memory>
+
+namespace arm_compute
+{
+namespace mlgo
+{
+/** Forward declaration for the underlying heuristics: MLGOHeuristics */
+class MLGOHeuristics;
+} // namespace mlgo
+
+/** Handle for loading and retrieving GEMM heuristics */
+class CLGEMMHeuristicsHandle
+{
+public:
+    /** Constructor */
+    CLGEMMHeuristicsHandle();
+    /** Destructor */
+    ~CLGEMMHeuristicsHandle();
+    /** Prevent Copy Construct */
+    CLGEMMHeuristicsHandle(const CLGEMMHeuristicsHandle &) = delete;
+    /** Prevent Copy Assignment */
+    CLGEMMHeuristicsHandle &operator=(const CLGEMMHeuristicsHandle &) = delete;
+    /** Default Move Constructor */
+    CLGEMMHeuristicsHandle(CLGEMMHeuristicsHandle &&) = default;
+    /** Default Move Assignment */
+    CLGEMMHeuristicsHandle &operator=(CLGEMMHeuristicsHandle &&) = default;
+    /** (Re)Load the heuristics from reading a dotmlgo file
+     *
+     * @param[in] filename Path to the dotmlgo file
+     *
+     * @return bool Signals if the reload succeeded or failed
+     */
+    bool reload_from_file(const std::string &filename);
+    /** Return a pointer to underlying heuristics for querying purposes
+     *
+     * @return MLGOHeuristics*
+     */
+    const mlgo::MLGOHeuristics *get() const;
+
+private:
+    std::unique_ptr<mlgo::MLGOHeuristics> _heuristics; /**< Pointer to underlying heuristics */
+};
+
+} // namespace arm_compute
+
+#endif // ARM_COMPUTE_RUNTIME_CL_CL_GEMM_HEURISTICS_HANDLE_H
\ No newline at end of file
diff --git a/src/runtime/CL/CLGEMMHeuristicsHandle.cpp b/src/runtime/CL/CLGEMMHeuristicsHandle.cpp
new file mode 100644 (file)
index 0000000..7168259
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2021 Arm Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#include "arm_compute/runtime/CL/CLGEMMHeuristicsHandle.h"
+
+#include "src/runtime/CL/mlgo/MLGOHeuristics.h"
+
+namespace arm_compute
+{
+CLGEMMHeuristicsHandle::CLGEMMHeuristicsHandle()
+    : _heuristics(std::make_unique<mlgo::MLGOHeuristics>())
+{
+}
+CLGEMMHeuristicsHandle::~CLGEMMHeuristicsHandle() = default;
+
+bool CLGEMMHeuristicsHandle::reload_from_file(const std::string &filename)
+{
+    return _heuristics->reload_from_file(filename);
+}
+const mlgo::MLGOHeuristics *CLGEMMHeuristicsHandle::get() const
+{
+    return _heuristics.get();
+}
+
+} // namespace arm_compute
index a2d3ec8241b9c3b7b744193713bc190dbd713a5b..9e06689cc86673c18acf786ec42bce81e9c02693 100644 (file)
@@ -21,8 +21,8 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef SRC_MLGO_COMMON_H
-#define SRC_MLGO_COMMON_H
+#ifndef SRC_RUNTIME_CL_MLGO_COMMON_H
+#define SRC_RUNTIME_CL_MLGO_COMMON_H
 
 #include "arm_compute/core/Types.h"
 #include "arm_compute/runtime/CL/CLTypes.h"
@@ -78,4 +78,4 @@ struct GEMMConfigReshaped
 
 } // namespace mlgo
 } // namespace arm_compute
-#endif // SRC_MLGO_COMMON_H
\ No newline at end of file
+#endif // SRC_RUNTIME_CL_MLGO_COMMON_H
\ No newline at end of file
index 28996889b33b4f9acfaadea43d867dba2fe42bec..d5c7de22155c2ec40b528e92fc7c22d56b906abe 100644 (file)
@@ -21,8 +21,8 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef SRC_MLGO_HEURISTICTREE_H
-#define SRC_MLGO_HEURISTICTREE_H
+#ifndef SRC_RUNTIME_CL_MLGO_HEURISTIC_TREE_H
+#define SRC_RUNTIME_CL_MLGO_HEURISTIC_TREE_H
 
 #include "arm_compute/core/Types.h"
 #include "src/runtime/CL/mlgo/Common.h"
@@ -195,4 +195,4 @@ private:
 
 } // namespace arm_compute
 
-#endif //SRC_MLGO_HEURISTICTREE_H
\ No newline at end of file
+#endif //SRC_RUNTIME_CL_MLGO_HEURISTIC_TREE_H
\ No newline at end of file
index ec99b50488c70b3d6a74b94dd419f1fb94506f77..80f3bb85e900655f5e034540e1bd67eae15f989e 100644 (file)
  * SOFTWARE.
  */
 #include "src/runtime/CL/mlgo/MLGOHeuristics.h"
+
 #include "arm_compute/core/Log.h"
 #include "src/runtime/CL/mlgo/MLGOParser.h"
+#include "src/runtime/CL/mlgo/Utils.h"
 
 #include <fstream>
 
@@ -53,9 +55,9 @@ MLGOHeuristics::MLGOHeuristics()
 {
 }
 
-std::pair<bool, GEMMType> MLGOHeuristics::query_gemm_type(Query query) const
+std::pair<bool, GEMMType> MLGOHeuristics::query_gemm_type(const Query &query) const
 {
-    ARM_COMPUTE_LOG_INFO_MSG_CORE("MLGOHeuristics querying gemm type");
+    ARM_COMPUTE_LOG_INFO_MSG_WITH_FORMAT_CORE("MLGOHeuristics querying gemm type. %s.", to_string(query).c_str());
     const auto invalid = GEMMType::RESHAPED;
     if(!_valid)
     {
@@ -71,9 +73,9 @@ std::pair<bool, GEMMType> MLGOHeuristics::query_gemm_type(Query query) const
     }
     return _trees.at(index).query<GEMMType>(shape_query);
 }
-std::pair<bool, GEMMConfigNative> MLGOHeuristics::query_gemm_config_native(Query query) const
+std::pair<bool, GEMMConfigNative> MLGOHeuristics::query_gemm_config_native(const Query &query) const
 {
-    ARM_COMPUTE_LOG_INFO_MSG_CORE("MLGOHeuristics querying gemm config native");
+    ARM_COMPUTE_LOG_INFO_MSG_WITH_FORMAT_CORE("MLGOHeuristics querying gemm config native. %s.", to_string(query).c_str());
     const auto invalid = GEMMConfigNative{};
     if(!_valid)
     {
@@ -89,9 +91,9 @@ std::pair<bool, GEMMConfigNative> MLGOHeuristics::query_gemm_config_native(Query
     }
     return _trees.at(index).query<GEMMConfigNative>(shape_query);
 }
-std::pair<bool, GEMMConfigReshapedOnlyRHS> MLGOHeuristics::query_gemm_config_reshaped_only_rhs(Query query) const
+std::pair<bool, GEMMConfigReshapedOnlyRHS> MLGOHeuristics::query_gemm_config_reshaped_only_rhs(const Query &query) const
 {
-    ARM_COMPUTE_LOG_INFO_MSG_CORE("MLGOHeuristics querying gemm config reshaped only rhs");
+    ARM_COMPUTE_LOG_INFO_MSG_WITH_FORMAT_CORE("MLGOHeuristics querying gemm config reshaped only rhs. %s.", to_string(query).c_str());
     const auto invalid = GEMMConfigReshapedOnlyRHS{};
     if(!_valid)
     {
@@ -107,9 +109,9 @@ std::pair<bool, GEMMConfigReshapedOnlyRHS> MLGOHeuristics::query_gemm_config_res
     }
     return _trees.at(index).query<GEMMConfigReshapedOnlyRHS>(shape_query);
 }
-std::pair<bool, GEMMConfigReshaped> MLGOHeuristics::query_gemm_config_reshaped(Query query) const
+std::pair<bool, GEMMConfigReshaped> MLGOHeuristics::query_gemm_config_reshaped(const Query &query) const
 {
-    ARM_COMPUTE_LOG_INFO_MSG_CORE("MLGOHeuristics querying gemm config reshaped");
+    ARM_COMPUTE_LOG_INFO_MSG_WITH_FORMAT_CORE("MLGOHeuristics querying gemm config reshaped. %s.", to_string(query).c_str());
     const auto invalid = GEMMConfigReshaped{};
     if(!_valid)
     {
index 02e8111b6ebc53a7b30052af5f45425c5ef4fb99..aa212259595bb52ac9d834f43275ec9a540cc349 100644 (file)
@@ -21,8 +21,8 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef SRC_RUNTIME_MLGO_MLGOHEURISTICS_H
-#define SRC_RUNTIME_MLGO_MLGOHEURISTICS_H
+#ifndef SRC_RUNTIME_CL_MLGO_MLGO_HEURISTICS_H
+#define SRC_RUNTIME_CL_MLGO_MLGO_HEURISTICS_H
 
 #include "src/runtime/CL/mlgo/Common.h"
 #include "src/runtime/CL/mlgo/HeuristicTree.h"
@@ -46,6 +46,7 @@ struct Query
     unsigned int b;         /**< Batch size */
 };
 
+bool operator==(const GEMMConfigNative &lhs, const GEMMConfigNative &rhs);
 bool operator==(const GEMMConfigReshapedOnlyRHS &lhs, const GEMMConfigReshapedOnlyRHS &rhs);
 bool operator==(const GEMMConfigReshaped &lhs, const GEMMConfigReshaped &rhs);
 
@@ -55,34 +56,44 @@ class MLGOHeuristics
 public:
     /** Constructor */
     MLGOHeuristics();
+    /** Default Destructor */
+    ~MLGOHeuristics() = default;
+    /** Prevent Copy Construct */
+    MLGOHeuristics(const MLGOHeuristics &) = delete;
+    /** Prevent Copy Assignment */
+    MLGOHeuristics &operator=(const MLGOHeuristics &) = delete;
+    /** Default Move Constructor */
+    MLGOHeuristics(MLGOHeuristics &&) = default;
+    /** Default Move Assignment */
+    MLGOHeuristics &operator=(MLGOHeuristics &&) = default;
     /** Query the gemm type
      *
      * @param[in] query Query
      *
      * @return std::pair<bool, GEMMType>  signals if the query succeeded or failed
      */
-    std::pair<bool, GEMMType> query_gemm_type(Query) const;
+    std::pair<bool, GEMMType> query_gemm_type(const Query &query) const;
     /** Query the gemm configuration for native kernel
      *
      * @param[in] query Query
      *
      * @return std::pair<bool, GEMMConfigNative>   bool signals if the query succeeded or failed
      */
-    std::pair<bool, GEMMConfigNative> query_gemm_config_native(Query query) const;
+    std::pair<bool, GEMMConfigNative> query_gemm_config_native(const Query &query) const;
     /** Query the gemm configuration for reshaped only rhs kernel
      *
      * @param[in] query Query
      *
      * @return std::pair<bool, GEMMConfigReshapedOnlyRHS>   bool signals if the query succeeded or failed
      */
-    std::pair<bool, GEMMConfigReshapedOnlyRHS> query_gemm_config_reshaped_only_rhs(Query) const;
+    std::pair<bool, GEMMConfigReshapedOnlyRHS> query_gemm_config_reshaped_only_rhs(const Query &query) const;
     /** Query the gemm configuration for reshaped kernel
      *
      * @param[in] query Query
      *
      * @return std::pair<bool, GEMMConfigReshaped>   bool signals if the query succeeded or failed
      */
-    std::pair<bool, GEMMConfigReshaped> query_gemm_config_reshaped(Query) const;
+    std::pair<bool, GEMMConfigReshaped> query_gemm_config_reshaped(const Query &query) const;
     /** (Re)Load the heuristics from reading a dotmlgo file
      *
      * @param[in] filename Path to the dotmlgo file
@@ -136,4 +147,4 @@ private:
 
 } // namespace mlgo
 } // namespace arm_compute
-#endif //SRC_MLGO_MLGOHEURISTICS_H
\ No newline at end of file
+#endif //SRC_RUNTIME_CL_MLGO_MLGO_HEURISTICS_H
\ No newline at end of file
index e4a31c1f557456fe3ed2bd18ab3bbed445b24ed3..49d8b9c644e25b64583d77c869b3de1334b37f69 100644 (file)
@@ -21,8 +21,8 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef SRC_MLGO_MLGOPARSER_H
-#define SRC_MLGO_MLGOPARSER_H
+#ifndef SRC_RUNTIME_CL_MLGO_MLGO_PARSER_H
+#define SRC_RUNTIME_CL_MLGO_MLGO_PARSER_H
 
 #include "src/runtime/CL/mlgo/MLGOHeuristics.h"
 
@@ -196,4 +196,4 @@ std::pair<bool, MLGOHeuristics> parse_mlgo(std::istream &in);
 } // namespace parser
 } // namespace mlgo
 } // namespace arm_compute
-#endif //SRC_MLGO_MLGOPARSER_H
\ No newline at end of file
+#endif //SRC_RUNTIME_CL_MLGO_MLGO_PARSER_H
\ No newline at end of file
index bd06bdf5219220ab81d11dc4613cdd689115cd5d..81d418c28ec70ac045a7068ffc02517b5e24978e 100644 (file)
  */
 #include "src/runtime/CL/mlgo/Utils.h"
 
+#include <sstream>
+
 namespace arm_compute
 {
 namespace mlgo
 {
+namespace
+{
+template <typename T>
+inline std::string to_str(const T &val)
+{
+    std::stringstream ss;
+    ss << val;
+    return ss.str();
+}
+} // namespace
+
 std::ostream &operator<<(std::ostream &os, const GEMMConfigNative &config)
 {
     return os << "Native:{"
@@ -61,7 +74,7 @@ std::ostream &operator<<(std::ostream &os, const GEMMConfigReshaped &config)
            << "export_cl_image: " << config.export_cl_image
            << "}";
 }
-std::ostream &operator<<(std::ostream &os, const HeuristicType &ht)
+std::ostream &operator<<(std::ostream &os, HeuristicType ht)
 {
     switch(ht)
     {
@@ -88,7 +101,7 @@ std::ostream &operator<<(std::ostream &os, const HeuristicType &ht)
     }
     return os;
 }
-std::ostream &operator<<(std::ostream &os, const DataType &dt)
+std::ostream &operator<<(std::ostream &os, DataType dt)
 {
     switch(dt)
     {
@@ -128,10 +141,41 @@ std::ostream &operator<<(std::ostream &os, const HeuristicTree::Index &index)
     os << ")";
     return os;
 }
+std::ostream &operator<<(std::ostream &os, const Query &query)
+{
+    os << "Query(";
+    os << "IP=" << query.ip_target << ",";
+    os << "DataType=" << query.data_type << ",";
+    os << "M=" << query.m << ",";
+    os << "N=" << query.n << ",";
+    os << "K=" << query.k << ",";
+    os << "B=" << query.b << ")";
+    return os;
+}
+
+std::string to_string(const GEMMConfigNative &config)
+{
+    return to_str(config);
+}
+
+std::string to_string(const GEMMConfigReshapedOnlyRHS &config)
+{
+    return to_str(config);
+}
+
+std::string to_string(const GEMMConfigReshaped &config)
+{
+    return to_str(config);
+}
+
+std::string to_string(const Query &query)
+{
+    return to_str(query);
+}
 
 namespace parser
 {
-std::ostream &operator<<(std::ostream &os, CharPosition pos)
+std::ostream &operator<<(std::ostream &os, const CharPosition &pos)
 {
     os << "(Ln: " << pos.ln << ", Col: " << pos.col << ")";
     return os;
index 2e324dd4390a08e2f2e28a65390d82f112741f4c..c634a887e949b344470037087dcb10f2b2cb4363 100644 (file)
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef SRC_MLGO_UTILS_H
-#define SRC_MLGO_UTILS_H
+#ifndef SRC_RUNTIME_CL_MLGO_UTILS_H
+#define SRC_RUNTIME_CL_MLGO_UTILS_H
 
 #include "src/runtime/CL/mlgo/Common.h"
 #include "src/runtime/CL/mlgo/HeuristicTree.h"
+#include "src/runtime/CL/mlgo/MLGOHeuristics.h"
 #include "src/runtime/CL/mlgo/MLGOParser.h"
 
 #include <ostream>
+#include <string>
 
 namespace arm_compute
 {
@@ -37,14 +39,19 @@ namespace mlgo
 std::ostream &operator<<(std::ostream &os, const GEMMConfigNative &config);
 std::ostream &operator<<(std::ostream &os, const GEMMConfigReshapedOnlyRHS &config);
 std::ostream &operator<<(std::ostream &os, const GEMMConfigReshaped &config);
-std::ostream &operator<<(std::ostream &os, const HeuristicType &ht);
-std::ostream &operator<<(std::ostream &os, const DataType &dt);
+std::ostream &operator<<(std::ostream &os, HeuristicType ht);
+std::ostream &operator<<(std::ostream &os, DataType dt);
 std::ostream &operator<<(std::ostream &os, const HeuristicTree::Index &index);
+std::ostream &operator<<(std::ostream &os, const Query &query);
+std::string to_string(const GEMMConfigNative &config);
+std::string to_string(const GEMMConfigReshapedOnlyRHS &config);
+std::string to_string(const GEMMConfigReshaped &config);
+std::string to_string(const Query &query);
 namespace parser
 {
-std::ostream &operator<<(std::ostream &os, CharPosition tok);
+std::ostream &operator<<(std::ostream &os, const CharPosition &pos);
 } // namespace parser
 } // namespace mlgo
 } // namespace arm_compute
 
-#endif //SRC_MLGO_UTILS_H
\ No newline at end of file
+#endif //SRC_RUNTIME_CL_MLGO_UTILS_H
\ No newline at end of file
index 895b4b51d0a76052a72c6109320659f1b9ecce66..e26464f9f7978c15ff243f7f33b641854a14b639 100644 (file)
@@ -40,12 +40,15 @@ TEST_SUITE(MLGOHeuristics)
 TEST_CASE(CorrectDotMLGOShouldLoadCorrectly, framework::DatasetMode::ALL)
 {
     std::string       mlgo_str = R"_(
+
         <header>
+
         gemm-version, [1,2,1]
         ip-type,gpu
         </header>
         <heuristics-table>
         0, g76 , 8, f32, best-performance, static, gemm-type, [m,n,k,n]
+
         1, g71 , 8, f16, best-performance, static, gemm-config-reshaped-only-rhs, [m,n,k,n]
         2, g76 , 8, f16, best-performance, static, gemm-config-reshaped, [m,n,k,n]
         </heuristics-table>
@@ -53,23 +56,29 @@ TEST_CASE(CorrectDotMLGOShouldLoadCorrectly, framework::DatasetMode::ALL)
         b , 0, var, m, ==, num, 10., 1, 2
         l , 1, gemm-type, reshaped
         b , 2, var, r_mn, >=, num, 2., 3, 6
+
         b , 3, var, n, >=, num, 200., 4, 5
-        l , 4, gemm-type, reshaped-only-rhs
+        l, 4,                          gemm-type, reshaped-only-rhs
         l , 5, gemm-type, reshaped
         l , 6, gemm-type, reshaped-only-rhs
         </heuristic>
         <heuristic, 1>
         b ,0,var, n, >, num, 100., 1, 4
         b ,1,var, r_mnk, <=, num, 20., 2, 3
+
+
         l ,2,gemm-config-reshaped-only-rhs, [4, 4,4,2,1,0,1]
         l ,3,gemm-config-reshaped-only-rhs,[ 2, 2,4,2,1,1, 1 ]
         b ,4,var, n, >=, num, 199.12, 5, 6
         l ,5,gemm-config-reshaped-only-rhs, [1, 4,3,4,0,0,0]
         l ,6,gemm-config-reshaped-only-rhs, [5, 4,4,5,1,1,0]
         </heuristic>
+
         <heuristic, 2>
         l ,0,gemm-config-reshaped,[4,2,4,2,8,1,0,1,0]
+
         </heuristic>
+
     )_";
     std::stringstream ss(mlgo_str);
     MLGOHeuristics    heuristics;
@@ -106,6 +115,7 @@ TEST_CASE(InvalidDotmlgoSyntaxShouldReturnInvalidStatus, framework::DatasetMode:
         </header>
         <heuristics-table>
         0, g76 , 8, f32, best-performance, static, gemm-config-reshaped, [m,n,k,n]
+
         </heurist
         <heuristic, 0>
         l ,0,gemm-config-reshaped,[4,2,4,2,8,1,0,1,0]
@@ -139,7 +149,9 @@ TEST_CASE(MismatchesBetweenHeuristicsTableEntriesAndHeuristicTrees, framework::D
             ip-type,gpu
             </header>
             <heuristics-table>
+
             0, g76 , 8, f32, best-performance, static, gemm-config-reshaped, [m,n,k,n]
+
             </heuristics-table>
         )_";
         std::stringstream ss(mlgo_str);