Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Concurrent device listing #189

Open
michaelmattig opened this issue Sep 10, 2020 · 5 comments
Open

Concurrent device listing #189

michaelmattig opened this issue Sep 10, 2020 · 5 comments

Comments

@michaelmattig
Copy link

I'm facing the issue that concurrent access of the available OpenCL devices fails. While one call gets the correct device, a parallel call gets shown no devices at all.

If I run the following tests in parallel:

#[cfg(test)]
mod tests {
    use super::*;
    use ocl::{Platform, Device};
    use std::{thread, time};

    fn ocl(){
        let platform = Platform::default();
        println!("Platform:{:?}", platform);
        println!("Devices:{:?}", Device::list_all(platform));
        let device = Device::first(platform).unwrap();
        println!("Device:{:?}", device);
    }

    #[test]
    fn test1() {
        ocl()
    }

    #[test]
    fn test2() {
        // thread::sleep(time::Duration::from_secs(1));
        ocl()
    }
}

most of the time only one test succeeds and yields

Platform:Platform(PlatformId(0x7fc3ffff7020))
Devices:Ok([Device(DeviceId(0x7fc400001040))])
Device:Device(DeviceId(0x7fc400001040))

while the other one shows:

Platform:Platform(PlatformId(0x7fc3ffff7020))
Devices:Ok([])

called Result::unwrap() on an Err value:

################################ OPENCL ERROR ###############################

Error executing function: clGetDeviceIDs

Status error code: CL_DEVICE_NOT_FOUND (-1)

Executing only one test or adding a sleep before the first one, both tests succeed.

@dmarcuse
Copy link
Contributor

As a temporary workaround you can also force the tests to run concurrently with cargo test -- --test-threads 1

@michaelmattig
Copy link
Author

michaelmattig commented Sep 10, 2020

As a temporary workaround you can also force the tests to run concurrently with cargo test -- --test-threads 1

sure, but I actually need to compile and run kernels in parallel in my application.

@dmarcuse
Copy link
Contributor

dmarcuse commented Sep 10, 2020

As a temporary workaround you can also force the tests to run concurrently with cargo test -- --test-threads 1

sure, but I actually need to compile and run kernels in parallel in my application.

Maybe you could use a global Mutex lock to synchronize things? This seems like an issue with the underlying OpenCL driver rather than the bindings, which makes it hard to fix.

@michaelmattig
Copy link
Author

michaelmattig commented Sep 10, 2020

I will use a static reference to the device for now (see code below). I would very much like to see this issue fixed though, as thread-safety is stated to be a major goal of this crate.

#[cfg(test)]
mod tests {
    use super::*;
    use ocl::{Platform, Device};
    use lazy_static::lazy_static;

    lazy_static! {
        static ref DEVICE: Device = Device::first(Platform::default()).expect("Device has to exist");
    }

    fn ocl(){
        let platform = Platform::default();
        println!("Platform:{:?}", platform);
        let device = *DEVICE;
        println!("Device{:?}", device);
    }

    #[test]
    fn test1() {
        ocl()
    }

    #[test]
    fn test2() {
        ocl()
    }
}

@dmarcuse
Copy link
Contributor

I don't think this is an issue with this library though - all the OpenCL calls involved in this example are supposed to be thread safe at the driver level; if the driver is breaking its own safety guarantees that's a problem with the driver.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants