From 3efdfb3979c429f3f0c8e2e7a47672de8deceac6 Mon Sep 17 00:00:00 2001 From: ohadagoogle Date: Mon, 20 Jun 2022 16:16:13 +0000 Subject: Enable loading OpenCL symbols in Android App native code, NDK environment. * Based on ArmNN work: IVGCVSW-6960 Device not found running MLTS with Support Library Change-Id: I8cb8acc30c8a4afa60bc1cf80eb5b6b2c43dfdc1 Signed-off-by: Ohad Almagor Reviewed-on: https://review.mlplatform.org/c/ml/ComputeLibrary/+/7836 Tested-by: Arm Jenkins Reviewed-by: Gian Marco Iodice Comments-Addressed: Arm Jenkins Benchmark: Arm Jenkins --- arm_compute/core/CL/OpenCL.h | 5 +++-- src/core/CL/OpenCL.cpp | 40 +++++++++++++++++++++++++++++++++++++--- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/arm_compute/core/CL/OpenCL.h b/arm_compute/core/CL/OpenCL.h index 93f7c318dd..058214bd07 100644 --- a/arm_compute/core/CL/OpenCL.h +++ b/arm_compute/core/CL/OpenCL.h @@ -75,11 +75,12 @@ public: static CLSymbols &get(); /** Load symbols from the given OpenCL library path. * - * @param[in] library Path to the OpenCL library. + * @param[in] library Path to the OpenCL library. + * @param[in] use_loader Use symbol loader function loadOpenCLPointer. * * @return True if loading the library is successful. */ - bool load(const std::string &library); + bool load(const std::string &library, bool use_loader = false); /** Load symbols from any of the default OpenCL library names. * * @return True if loading any library is successful. diff --git a/src/core/CL/OpenCL.cpp b/src/core/CL/OpenCL.cpp index d5034ba8fa..b391950e1b 100644 --- a/src/core/CL/OpenCL.cpp +++ b/src/core/CL/OpenCL.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2021 Arm Limited. + * Copyright (c) 2017-2022 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -62,18 +62,32 @@ bool CLSymbols::load_default() for(const auto &lib : libraries) { - if(load(lib)) + 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; } } +#ifdef __ANDROID__ + // When running in NDK environment, the above libraries are not accessible. + static const std::vector android_libraries{ "libOpenCL-pixel.so", "libOpenCL-car.so" }; + + for(const auto &lib : android_libraries) + { + 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; + } + } +#endif /* __ANDROID__ */ + std::cerr << "Couldn't find any OpenCL library.\n"; return false; } -bool CLSymbols::load(const std::string &library) +bool CLSymbols::load(const std::string &library, bool use_loader) { void *handle = dlopen(library.c_str(), RTLD_LAZY | RTLD_LOCAL); @@ -85,8 +99,28 @@ bool CLSymbols::load(const std::string &library) return false; } +#ifdef __ANDROID__ + typedef void* (*loadOpenCLPointer_t)(const char* name); + loadOpenCLPointer_t loadOpenCLPointer; + if (use_loader) { + typedef void (*enableOpenCL_t)(); + enableOpenCL_t enableOpenCL = + reinterpret_cast(dlsym(handle, "enableOpenCL")); + enableOpenCL(); + + loadOpenCLPointer = reinterpret_cast( + dlsym(handle, "loadOpenCLPointer")); + } else { + loadOpenCLPointer = nullptr; + } +#define LOAD_FUNCTION_PTR(func_name, _handle) \ + func_name##_ptr = reinterpret_cast( use_loader ? \ + loadOpenCLPointer(#func_name) : dlsym(handle, #func_name)); +#else /* __ANDROID__ */ + (void)use_loader; // Avoid unused warning #define LOAD_FUNCTION_PTR(func_name, handle) \ func_name##_ptr = reinterpret_cast(dlsym(handle, #func_name)); +#endif /* __ANDROID__ */ LOAD_FUNCTION_PTR(clCreateContext, handle); LOAD_FUNCTION_PTR(clCreateContextFromType, handle); -- cgit v1.2.1