ARM-software / ComputeLibrary

The Compute Library is a set of computer vision and machine learning functions optimised for both Arm CPUs and GPUs using SIMD technologies.
MIT License
2.8k stars 774 forks source link

libarm_compute-static.a export OpenCL API which is unnecessary #1128

Closed YiGe-MediaTek closed 2 weeks ago

YiGe-MediaTek commented 1 month ago

libarm_compute-static.a expose OpenCL API which is unnecessary, when I linked it to application which is also linked to library contains OpenCL API, it got conflicted, cannot build successfully

strings libarm_compute-static.a | grep arm_compute_version (base) mtk31770@NB22120271:~/ComputeLibrary/build$ strings libarm_compute-static.a | grep arm_compute_version arm_compute_version=v24.06 Build options: {'Werror': '1', 'debug': '0', 'asserts': '1', 'neon': '0', 'opencl': '1', 'embed_kernels': '1', 'os': 'android', 'arch': 'armv8a', 'benchmark_tests': '1', 'mali': '1', 'benchmark_examples': '1'}

Platform:

Operating System: Android platform

Problem description: the issue happens when I tried to link libarm_compute-static.a into Geekbench benchmark code Here is part of the error log ld.lld:error: duplicate symbol: clCreateBuffer

defined at OpenCL.cpp OpenCL.o (clCreateBuffer) in archive third_part/acl/libarm_compute-static.a defined at opencl_library.cpp opencl_library.o (.text + oxCo) in archive build.android.aarch64/libhalogen.a

Could we can make OpenCL API call hidden?, I thought ACL should only export Op related class and API, not low level API

ramelg01 commented 1 month ago

Thanks @YiGe-MediaTek for reporting it, looking into it and coming back soon.

YiGe-MediaTek commented 4 weeks ago

Any update on this? Thanks!

morgolock commented 4 weeks ago

Hi @YiGe-MediaTek

Thanks for reporting this issue, we are looking into it. It seems libhalogen.a contains the opencl API calls too and that's causing problems because ACL also has these identifier declared in the global namespace: see https://github.com/ARM-software/ComputeLibrary/blob/main/src/core/CL/OpenCL.cpp#L835

Maybe you could try moving all these functions from the global namespace into arm_compute?

What's libhalogen.a? Could you please provide more information about how to reproduce the linker error.

YiGe-MediaTek commented 4 weeks ago

@morgolock Thanks for tips. I cannot move all these functions from global namespace into arm_compute, I understand where you come from. These OpenCL API is like wrapper of real implementation, if I put them into arm_compute, the linker won't find corresponding symbol, it is going to fail. BTW, libhalogen.a is module from Geekbench benchmark.

YiGe-MediaTek commented 4 weeks ago

@morgolock for reproducing the issue, in the Geekbench SConstruct, add following image then just build the Geekbench, it will give u the error. Geekbench is licensed software, I cannot share with you, but ARM has the license (GB version 6.3). I also tried dynamic loading, During running, it will give bad cast error.

morgolock commented 3 weeks ago

Hi @YiGe-MediaTek

I'd try making the opencl api symbols in ACL private moving them into the arm_compute namespace as show in the patch below and then when building libarm_compute-static.a make sure you link against libOpenCL.so or libhalogen.a. You can do it with the following scons option extra_link_flags="-L./libopencl/ -lOpenCL -lmali" or extra_link_flags="-L./path/to/libHalogen -libhalogen.a"

user@dev:~/work/acl/ComputeLibrary$ git diff
diff --git a/src/core/CL/OpenCL.cpp b/src/core/CL/OpenCL.cpp
index 2ebc3274a..15d94753f 100644
--- a/src/core/CL/OpenCL.cpp
+++ b/src/core/CL/OpenCL.cpp
@@ -255,7 +255,6 @@ bool opencl_is_available()

     return CLSymbols::get().clBuildProgram_ptr != nullptr;
 }
-} // namespace arm_compute

 cl_int clEnqueueMarker(cl_command_queue command_queue, cl_event *event)
 {
@@ -1257,3 +1256,7 @@ cl_mem clImportMemoryARM(cl_context                      context,
         return nullptr;
     }
 }
+
+} // namespace arm_compute

The patch above will make the symbols in ACL private.

This approach should work and all the OpenCL api call within ACL will get resolved with the symbols in libmali.so/libOpenCL.so

Hope this helps

UPDATE: You'll have to potentially disable the code in the files below too.

src/core/CL/CLCommandBuffer.cpp
src/core/CL/CLCompatCommandBuffer.cpp
src/core/CL/CLMutableCommandBuffer.cpp

You will either have to link acl against libhalogen.a or libmali.so which you can pull from your device.

YiGe-MediaTek commented 2 weeks ago

@morgolock Thanks a lot for helping out. Yes, either put stub function into arm_compute namespace or just remove it, it will compile as long as you build directly against the openCL library, but cl_sgemm test case will fail, somehow, it is related to tunner. BTW, I will close this one, and work with you guys through ARM internal support. Thanks!