1use std::{mem};
3use std::ptr::null_mut;
4use cuda_runtime_sys::dim3;
5use libc::c_void;
6use rcudnn_sys::{cudaError, cudaMemcpyKind, cudaStream_t};
7use crate::error::CudaRuntimeError;
8
9pub fn malloc<T>(size: usize) -> Result<*mut T,rcudnn::Error> {
22 let size = mem::size_of::<T>() * size;
23 let mut ptr: *mut T = null_mut();
24
25 match unsafe { rcudnn_sys::cudaMalloc(&mut ptr as *mut *mut T as *mut *mut libc::c_void, size) } {
26 cudaError::cudaSuccess => {
27 assert_ne!(ptr,
28 null_mut(),
29 "cudaMalloc is succeeded, but returned null pointer!");
30 Ok(ptr)
31 },
32 cudaError::cudaErrorInvalidValue => {
33 Err(rcudnn::Error::InvalidValue("The range of one or more of the entered parameters is out of tolerance."))
34 },
35 cudaError::cudaErrorMemoryAllocation => {
36 Err(rcudnn::Error::AllocFailed("Device memory allocation failed."))
37 },
38 status => {
39 Err(rcudnn::Error::Unknown("Unable to create the CUDA cuDNN context/resources.", status as i32 as u64))
40 }
41 }
42}
43
44pub fn malloc_host<T>(size: usize, flags:libc::c_uint) -> Result<*mut T,rcudnn::Error> {
57 let size = mem::size_of::<T>() * size;
58 let mut ptr: *mut T = null_mut();
59
60 match unsafe { rcudnn_sys::cudaHostAlloc(&mut ptr as *mut *mut T as *mut *mut libc::c_void, size, flags) } {
61 cudaError::cudaSuccess => {
62 assert_ne!(ptr,
63 null_mut(),
64 "cudaMalloc is succeeded, but returned null pointer!");
65 Ok(ptr)
66 },
67 cudaError::cudaErrorInvalidValue => {
68 Err(rcudnn::Error::InvalidValue("The range of one or more of the entered parameters is out of tolerance."))
69 },
70 cudaError::cudaErrorMemoryAllocation => {
71 Err(rcudnn::Error::AllocFailed("Device memory allocation failed."))
72 },
73 status => {
74 Err(rcudnn::Error::Unknown("Unable to create the CUDA cuDNN context/resources.", status as i32 as u64))
75 }
76 }
77}
78
79pub fn memcpy<T>(dst: *mut T, src: *const T, size: usize, kind: cudaMemcpyKind) -> Result<(),rcudnn::Error> {
92 let size = mem::size_of::<T>() * size;
93
94 match unsafe {
95 rcudnn_sys::cudaMemcpy(dst as *mut libc::c_void, src as *mut libc::c_void, size, kind)
96 } {
97 cudaError::cudaSuccess => {
98 Ok(())
99 },
100 cudaError::cudaErrorInvalidMemcpyDirection => {
101 Err(rcudnn::Error::BadParam("Incorrect specification of memory transfer direction."))
102 },
103 status => {
104 Err(rcudnn::Error::Unknown("Unable to create the CUDA cuDNN context/resources.", status as i32 as u64))
105 }
106 }
107}
108
109pub fn memcpy_async<T>(dst: *mut T, src: *const T, size: usize, kind: cudaMemcpyKind, stream: cudaStream_t) -> Result<(),rcudnn::Error> {
123 let size = mem::size_of::<T>() * size;
124 match unsafe {
125 rcudnn_sys::cudaMemcpyAsync(dst as *mut libc::c_void, src as *mut libc::c_void, size, kind, stream)
126 } {
127 cudaError::cudaSuccess => {
128 Ok(())
129 },
130 cudaError::cudaErrorInvalidMemcpyDirection => {
131 Err(rcudnn::Error::BadParam("Incorrect specification of memory transfer direction."))
132 },
133 status => {
134 Err(rcudnn::Error::Unknown("Unable to create the CUDA cuDNN context/resources.", status as i32 as u64))
135 }
136 }
137}
138
139pub fn free<T>(devptr: *mut T) -> Result<(),rcudnn::Error> {
149 match unsafe { rcudnn_sys::cudaFree(devptr as *mut libc::c_void) } {
150 cudaError::cudaSuccess => Ok(()),
151 cudaError::cudaErrorInvalidValue => {
152 Err(rcudnn::Error::InvalidValue("Invalid pointer passed as argument."))
153 },
154 status => {
155 Err(rcudnn::Error::Unknown("Unable to create the CUDA cuDNN context/resources.", status as i32 as u64))
156 }
157 }
158}
159
160pub fn free_host<T>(devptr: *mut T) -> Result<(),rcudnn::Error> {
170 match unsafe { rcudnn_sys::cudaFreeHost(devptr as *mut libc::c_void) } {
171 cudaError::cudaSuccess => Ok(()),
172 cudaError::cudaErrorInvalidValue => {
173 Err(rcudnn::Error::InvalidValue("Invalid pointer passed as argument."))
174 },
175 status => {
176 Err(rcudnn::Error::Unknown("Unable to create the CUDA cuDNN context/resources.", status as i32 as u64))
177 }
178 }
179}
180fn launch_with_stream(func: *const c_void,
181 grid_dim: dim3,
182 block_dim: dim3,
183 args: &mut [*mut c_void],
184 shared_mem: usize,
185 stream:cuda_runtime_sys::cudaStream_t)
186 -> Result<(),CudaRuntimeError> {
187 let cuda_error = unsafe {
188 cuda_runtime_sys::cudaLaunchKernel(func,
189 grid_dim,
190 block_dim,
191 args.as_mut_ptr(),
192 shared_mem,
193 stream)
194 };
195
196 if cuda_error == cuda_runtime_sys::cudaError::cudaSuccess {
197 Ok(())
198 } else {
199 Err(CudaRuntimeError::new(cuda_error))
200 }
201}
202fn launch_cooperative_with_stream(func: *const c_void,
203 grid_dim: dim3,
204 block_dim: dim3,
205 args: &mut [*mut c_void],
206 shared_mem: usize,
207 stream:cuda_runtime_sys::cudaStream_t)
208 -> Result<(),CudaRuntimeError> {
209 let cuda_error = unsafe {
210 cuda_runtime_sys::cudaLaunchCooperativeKernel(func,
211 grid_dim,
212 block_dim,
213 args.as_mut_ptr(),
214 shared_mem,
215 stream)
216 };
217
218 if cuda_error == cuda_runtime_sys::cudaError::cudaSuccess {
219 Ok(())
220 } else {
221 Err(CudaRuntimeError::new(cuda_error))
222 }
223}
224pub fn launch(func: *const c_void,
237 grid_dim: dim3,
238 block_dim: dim3,
239 args: &mut [*mut c_void],
240 shared_mem: usize)
241 -> Result<(),CudaRuntimeError> {
242 launch_with_stream(func,
243 grid_dim,
244 block_dim,
245 args,
246 shared_mem,
247 null_mut())
248}
249pub fn launch_cooperative(func: *const c_void,
263 grid_dim: dim3,
264 block_dim: dim3,
265 args: &mut [*mut c_void],
266 shared_mem: usize)
267 -> Result<(),CudaRuntimeError> {
268 launch_cooperative_with_stream(func,
269 grid_dim,
270 block_dim,
271 args,
272 shared_mem,
273 null_mut())
274}
275pub fn device_synchronize() -> Result<(),CudaRuntimeError> {
282 let cuda_error = unsafe { cuda_runtime_sys::cudaDeviceSynchronize() };
283
284 if cuda_error == cuda_runtime_sys::cudaError::cudaSuccess {
285 Ok(())
286 } else {
287 Err(CudaRuntimeError::new(cuda_error))
288 }
289}