Ensure OpenCL runtimes are initialized first
The OpenCL API Specification states:
> The behavior of OpenCL API functions called from global constructors
> or destructors is therefore implementation-defined.
This patch improves compatibility with OpenCL runtimes that use static
objects to hold their internal state.
Change-Id: I850be378e9c6f0b5aa8db926fe0c62833a936724
Signed-off-by: Marco Antognini <marco.antognini@arm.com>
Reviewed-on: https://review.mlplatform.org/c/ml/ComputeLibrary/+/5383
Reviewed-by: Georgios Pinitas <georgios.pinitas@arm.com>
Comments-Addressed: Sheri Zhang <sheri.zhang@arm.com>
Tested-by: Arm Jenkins <bsgcomp@arm.com>
diff --git a/src/core/CL/OpenCL.cpp b/src/core/CL/OpenCL.cpp
index aff6285..dd9960a 100644
--- a/src/core/CL/OpenCL.cpp
+++ b/src/core/CL/OpenCL.cpp
@@ -152,6 +152,23 @@
bool opencl_is_available()
{
CLSymbols::get().load_default();
+
+ // Using static objects that rely on OpenCL in their constructor or
+ // destructor is implementation defined according to the OpenCL API
+ // Specification. These objects include CLScheduler.
+ //
+ // For compatibility with OpenCL runtimes that also use static objects to
+ // hold their state, we call a harmless OpenCL function (clGetPlatformIDs
+ // with invalid parameters must result in CL_INVALID_VALUE) to ensure the
+ // runtimes have a chance to initialize their static objects first. Thanks
+ // to C++11 rules about normal program termination (cf [basic.start]), this
+ // ensures their static objects are destroyed last, i.e. after the
+ // singleton CLScheduler is destroyed.
+ //
+ // When OpenCL is not available, this call results in CL_OUT_OF_RESOURCES,
+ // which is equally harmless.
+ (void)clGetPlatformIDs(0, nullptr, nullptr);
+
return CLSymbols::get().clBuildProgram_ptr != nullptr;
}
} // namespace arm_compute