dlpark 0.8.0-alpha.3

dlpack Rust binding for Python
Documentation
use pyo3::exceptions::PyBufferError;

use crate::{
    ffi::{DLDevice, DLDeviceType},
    python::{DlpackStream, stream},
};

unsafe impl DlpackStream for cudarc::driver::CudaStream {
    fn as_python_arg(
        &self,
        _py: pyo3::Python<'_>,
        device: DLDevice,
    ) -> pyo3::PyResult<stream::StreamArg> {
        if device.device_type != DLDeviceType::CUDA
            && device.device_type != DLDeviceType::CUDAMANAGED
        {
            return Err(PyBufferError::new_err(format!(
                "a CUDA stream cannot consume DLPack device {:?}",
                device.device_type
            )));
        }

        let ordinal = i32::try_from(self.context().ordinal()).map_err(|_| {
            PyBufferError::new_err("CUDA stream device ordinal does not fit in i32")
        })?;
        if ordinal != device.device_id {
            return Err(PyBufferError::new_err(format!(
                "CUDA stream is on device {ordinal}, but the tensor is on device {}",
                device.device_id
            )));
        }

        Ok(stream::cuda(self.cu_stream().cast()))
    }
}

unsafe impl DlpackStream for std::sync::Arc<cudarc::driver::CudaStream> {
    fn as_python_arg(
        &self,
        py: pyo3::Python<'_>,
        device: DLDevice,
    ) -> pyo3::PyResult<stream::StreamArg> {
        self.as_ref().as_python_arg(py, device)
    }
}