Avoid printing error message for each not found OpenCl library

- Only print can't load any opencl library if none of
  "libOpenCL.so", "libGLES_mali.so", "libmali.so" are found.
- If any of them is found, then no need to print any error message.

Resolves: COMPMID-5973
Signed-off-by: Ramy Elgammal <ramy.elgammal@arm.com>
Change-Id: I9d62bd33545bbbf54d69836a4dca58a6294bc479
Reviewed-on: https://eu-gerrit-1.euhpc.arm.com/c/VisualCompute/ComputeLibrary/+/511804
Tested-by: bsgcomp <bsgcomp@arm.com>
Reviewed-by: Pablo Tello <pablo.tello@arm.com>
Comments-Addressed: bsgcomp <bsgcomp@arm.com>
Reviewed-on: https://review.mlplatform.org/c/ml/ComputeLibrary/+/9483
Tested-by: Arm Jenkins <bsgcomp@arm.com>
Reviewed-by: Pablo Marquez Tello <pablo.tello@arm.com>
Comments-Addressed: Arm Jenkins <bsgcomp@arm.com>
Benchmark: Arm Jenkins <bsgcomp@arm.com>
diff --git a/arm_compute/core/CL/OpenCL.h b/arm_compute/core/CL/OpenCL.h
index 058214b..1e1f529 100644
--- a/arm_compute/core/CL/OpenCL.h
+++ b/arm_compute/core/CL/OpenCL.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2022 Arm Limited.
+ * Copyright (c) 2016-2023 Arm Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -73,15 +73,16 @@
      * @return The static instance of CLSymbols.
      */
     static CLSymbols &get();
-    /** Load symbols from the given OpenCL library path.
+    /** This method attempts to load the OpenCL symbols from the first available library from the provided OpenCL libraries.
      *
-     * @param[in] library    Path to the OpenCL library.
-     * @param[in] use_loader Use symbol loader function loadOpenCLPointer.
+     * @param[in] libraries_filenames Vector containing the filenames of the libraries to be loaded.
+     * @param[in] use_loader          Use symbol loader function loadOpenCLPointer.
      *
-     * @return True if loading the library is successful.
+     * @return True if loading the library is successful. False if all the provided libraries could not be loaded.
      */
-    bool load(const std::string &library, bool use_loader = false);
+    bool load(const std::vector<std::string> &libraries_filenames, bool use_loader = false);
     /** Load symbols from any of the default OpenCL library names.
+     *  If all the default libraries could not be loaded, this method will print a warning message and return false.
      *
      * @return True if loading any library is successful.
      */
diff --git a/src/core/CL/OpenCL.cpp b/src/core/CL/OpenCL.cpp
index b391950..8aa9b2b 100644
--- a/src/core/CL/OpenCL.cpp
+++ b/src/core/CL/OpenCL.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2022 Arm Limited.
+ * Copyright (c) 2017-2023 Arm Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -29,8 +29,10 @@
 
 #include "arm_compute/core/Error.h"
 
+#include <algorithm>
 #include <dlfcn.h>
 #include <iostream>
+#include <sstream>
 
 namespace arm_compute
 {
@@ -50,7 +52,7 @@
 
 bool CLSymbols::load_default()
 {
-    static const std::vector<std::string> libraries{ "libOpenCL.so", "libGLES_mali.so", "libmali.so" };
+    static const std::vector<std::string> libraries_filenames{ "libOpenCL.so", "libGLES_mali.so", "libmali.so" };
 
     if(_loaded.first)
     {
@@ -60,40 +62,53 @@
     // Indicate that default loading has been tried
     _loaded.first = true;
 
-    for(const auto &lib : libraries)
+    if(load(libraries_filenames, /* use_loader */ false))
     {
-        if(load(lib, /* use_loader */false))
-        {
-            ARM_COMPUTE_ERROR_ON_MSG(this->clBuildProgram_ptr == nullptr, "Failed to load OpenCL symbols from shared library");
-            return true;
-        }
+        ARM_COMPUTE_ERROR_ON_MSG(this->clBuildProgram_ptr == nullptr, "Failed to load OpenCL symbols from shared library");
+        return true;
     }
 
 #ifdef __ANDROID__
     // When running in NDK environment, the above libraries are not accessible.
-    static const std::vector<std::string> android_libraries{ "libOpenCL-pixel.so", "libOpenCL-car.so" };
+    static const std::vector<std::string> android_libraries_filenames{ "libOpenCL-pixel.so", "libOpenCL-car.so" };
 
-    for(const auto &lib : android_libraries)
+    if(load(android_libraries_filenames, /* use_loader */ true))
     {
-        if(load(lib, /* use_loader */true))
-        {
-            ARM_COMPUTE_ERROR_ON_MSG(this->clBuildProgram_ptr == nullptr, "Failed to load OpenCL symbols from android shared library");
-            return true;
-        }
+        ARM_COMPUTE_ERROR_ON_MSG(this->clBuildProgram_ptr == nullptr, "Failed to load OpenCL symbols from android shared library");
+        return true;
     }
-#endif /* __ANDROID__ */
+#endif // __ANDROID__
 
-    std::cerr << "Couldn't find any OpenCL library.\n";
+    // If not returned till here then libraries not found
+    std::stringstream ss;
+    std::for_each(libraries_filenames.begin(), libraries_filenames.end(), [&ss](const std::string & s)
+    {
+        ss << s << " ";
+    });
+#ifdef __ANDROID__
+    std::for_each(android_libraries_filenames.begin(), android_libraries_filenames.end(), [&ss](const std::string & s)
+    {
+        ss << s << " ";
+    });
+#endif // __ANDROID__
+    std::cerr << "Couldn't find any of the following OpenCL library: " << ss.str() << std::endl;
     return false;
 }
 
-bool CLSymbols::load(const std::string &library, bool use_loader)
+bool CLSymbols::load(const std::vector<std::string> &libraries_filenames, bool use_loader)
 {
-    void *handle = dlopen(library.c_str(), RTLD_LAZY | RTLD_LOCAL);
-
-    if(handle == nullptr)
+    void        *handle = nullptr;
+    unsigned int index  = 0;
+    for(index = 0; index < libraries_filenames.size(); ++index)
     {
-        std::cerr << "Can't load " << library << ": " << dlerror() << "\n";
+        handle = dlopen(libraries_filenames[index].c_str(), RTLD_LAZY | RTLD_LOCAL);
+        if(handle != nullptr)
+        {
+            break;
+        }
+    }
+    if(index == libraries_filenames.size())
+    {
         // Set status of loading to failed
         _loaded.second = false;
         return false;