#[cfg(feature = "cuda")]
use crate::cuda;
use crate::error::GPUError;
#[cfg(feature = "opencl")]
use crate::opencl;
pub enum Program {
#[cfg(feature = "cuda")]
Cuda(cuda::Program),
#[cfg(feature = "opencl")]
Opencl(opencl::Program),
}
impl Program {
#[cfg(all(feature = "cuda", feature = "opencl"))]
pub fn run<F1, F2, R, E, A>(&self, fun: (F1, F2), arg: A) -> Result<R, E>
where
E: From<GPUError>,
F1: FnOnce(&cuda::Program, A) -> Result<R, E>,
F2: FnOnce(&opencl::Program, A) -> Result<R, E>,
{
match self {
Self::Cuda(program) => program.run(fun.0, arg),
Self::Opencl(program) => program.run(fun.1, arg),
}
}
#[cfg(all(feature = "cuda", not(feature = "opencl")))]
pub fn run<F1, F2, R, E, A>(&self, fun: (F1, F2), arg: A) -> Result<R, E>
where
E: From<GPUError>,
F1: FnOnce(&cuda::Program, A) -> Result<R, E>,
{
match self {
Self::Cuda(program) => program.run(fun.0, arg),
}
}
#[cfg(all(not(feature = "cuda"), feature = "opencl"))]
pub fn run<F1, F2, R, E, A>(&self, fun: (F1, F2), arg: A) -> Result<R, E>
where
E: From<GPUError>,
F2: FnOnce(&opencl::Program, A) -> Result<R, E>,
{
match self {
Self::Opencl(program) => program.run(fun.1, arg),
}
}
pub fn device_name(&self) -> &str {
match self {
#[cfg(feature = "cuda")]
Self::Cuda(program) => program.device_name(),
#[cfg(feature = "opencl")]
Self::Opencl(program) => program.device_name(),
}
}
}
#[cfg(all(feature = "cuda", feature = "opencl"))]
#[macro_export]
macro_rules! program_closures {
(|$program:ident, $arg:ident| -> $ret:ty $body:block) => {
(
|$program: &$crate::cuda::Program, $arg| -> $ret { $body },
|$program: &$crate::opencl::Program, $arg| -> $ret { $body },
)
};
(|$program:ident, $arg:ident: $arg_type:ty| -> $ret:ty $body:block) => {
(
|$program: &$crate::cuda::Program, $arg: $arg_type| -> $ret { $body },
|$program: &$crate::opencl::Program, $arg: $arg_type| -> $ret { $body },
)
};
}
#[macro_export]
#[cfg(all(feature = "cuda", not(feature = "opencl")))]
macro_rules! program_closures {
(|$program:ident, $arg:ident| -> $ret:ty $body:block) => {
(
|$program: &$crate::cuda::Program, $arg| -> $ret { $body },
(),
)
};
(|$program:ident, $arg:ident: $arg_type:ty| -> $ret:ty $body:block) => {
(
|$program: &$crate::cuda::Program, $arg: $arg_type| -> $ret { $body },
(),
)
};
}
#[macro_export]
#[cfg(all(not(feature = "cuda"), feature = "opencl"))]
macro_rules! program_closures {
(|$program:ident, $arg:ident| -> $ret:ty $body:block) => {
((), |$program: &$crate::opencl::Program, $arg| -> $ret {
$body
})
};
(|$program:ident, $arg:ident: $arg_type:ty| -> $ret:ty $body:block) => {
(
(),
|$program: &$crate::opencl::Program, $arg: $arg_type| -> $ret { $body },
)
};
}