cl3/runtime/
utils.rs

1// Copyright (c) 2024 Via Technology Ltd.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//    http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::sync::OnceLock;
16
17use dlopen2::{Error, wrapper::Container};
18
19use super::OpenCl;
20
21/// `dlopen2` container with all loaded API functions.
22pub type OpenClRuntime = Container<OpenCl>;
23
24static OPENCL_RUNTIME: OnceLock<Result<OpenClRuntime, Error>> = OnceLock::new();
25
26/// Utility function to load the `OpenCL` shared library (actual load will be performed only once).
27///
28/// Returns an error if the library is not found.
29pub fn load_library() -> &'static Result<OpenClRuntime, Error> {
30    const LIBRARY_NAME: &str = if cfg!(target_os = "windows") {
31        "OpenCL.dll"
32    } else if cfg!(target_os = "macos") {
33        "/System/Library/Frameworks/OpenCL.framework/OpenCL"
34    } else {
35        "libOpenCL.so"
36    };
37
38    OPENCL_RUNTIME.get_or_init(|| {
39        if let Ok(env_var) = std::env::var("OPENCL_DYLIB_PATH") {
40            for library_path in env_var.split(';') {
41                let library = unsafe { Container::load(library_path) };
42                if library.is_ok() {
43                    return library;
44                }
45            }
46        }
47
48        unsafe { Container::load(LIBRARY_NAME) }
49    })
50}
51
52/// Utility function to check if the `OpenCL` shared library is loaded successfully.
53#[must_use]
54pub fn is_opencl_runtime_available() -> bool {
55    load_library().is_ok()
56}