Integrate MLGO into CLGEMM and CLGEMMLowpMatrixMultiplyCore: Part1

* 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>
diff --git a/src/runtime/CL/CLGEMMHeuristicsHandle.cpp b/src/runtime/CL/CLGEMMHeuristicsHandle.cpp
new file mode 100644
index 0000000..7168259
--- /dev/null
+++ b/src/runtime/CL/CLGEMMHeuristicsHandle.cpp
@@ -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
diff --git a/src/runtime/CL/mlgo/Common.h b/src/runtime/CL/mlgo/Common.h
index a2d3ec8..9e06689 100644
--- a/src/runtime/CL/mlgo/Common.h
+++ b/src/runtime/CL/mlgo/Common.h
@@ -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 @@
 
 } // 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
diff --git a/src/runtime/CL/mlgo/HeuristicTree.h b/src/runtime/CL/mlgo/HeuristicTree.h
index 2899688..d5c7de2 100644
--- a/src/runtime/CL/mlgo/HeuristicTree.h
+++ b/src/runtime/CL/mlgo/HeuristicTree.h
@@ -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 @@
 
 } // 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
diff --git a/src/runtime/CL/mlgo/MLGOHeuristics.cpp b/src/runtime/CL/mlgo/MLGOHeuristics.cpp
index ec99b50..80f3bb8 100644
--- a/src/runtime/CL/mlgo/MLGOHeuristics.cpp
+++ b/src/runtime/CL/mlgo/MLGOHeuristics.cpp
@@ -22,8 +22,10 @@
  * 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 @@
 {
 }
 
-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 @@
     }
     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 @@
     }
     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 @@
     }
     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)
     {
diff --git a/src/runtime/CL/mlgo/MLGOHeuristics.h b/src/runtime/CL/mlgo/MLGOHeuristics.h
index 02e8111..aa21225 100644
--- a/src/runtime/CL/mlgo/MLGOHeuristics.h
+++ b/src/runtime/CL/mlgo/MLGOHeuristics.h
@@ -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 @@
     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 @@
 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 @@
 
 } // 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
diff --git a/src/runtime/CL/mlgo/MLGOParser.h b/src/runtime/CL/mlgo/MLGOParser.h
index e4a31c1..49d8b9c 100644
--- a/src/runtime/CL/mlgo/MLGOParser.h
+++ b/src/runtime/CL/mlgo/MLGOParser.h
@@ -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 @@
 } // 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
diff --git a/src/runtime/CL/mlgo/Utils.cpp b/src/runtime/CL/mlgo/Utils.cpp
index bd06bdf..81d418c 100644
--- a/src/runtime/CL/mlgo/Utils.cpp
+++ b/src/runtime/CL/mlgo/Utils.cpp
@@ -23,10 +23,23 @@
  */
 #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 @@
            << "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 @@
     }
     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 @@
     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;
diff --git a/src/runtime/CL/mlgo/Utils.h b/src/runtime/CL/mlgo/Utils.h
index 2e324dd..c634a88 100644
--- a/src/runtime/CL/mlgo/Utils.h
+++ b/src/runtime/CL/mlgo/Utils.h
@@ -21,14 +21,16 @@
  * 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 @@
 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