use crate::ffi::*;
use crate::utils::DataType;
use crate::{Error, API};
impl API {
#[allow(clippy::too_many_arguments)]
pub fn get_rnn_temp_space_sizes(
handle: cudnnHandle_t,
rnn_desc: cudnnRNNDescriptor_t,
mode: cudnnForwardMode_t,
x_desc: cudnnRNNDataDescriptor_t,
) -> Result<(usize, usize), Error> {
let mut work_space_size: ::libc::size_t = 0;
let mut reserved_space_size: ::libc::size_t = 0;
unsafe {
API::ffi_get_rnn_temp_space_sizes(
handle,
rnn_desc,
mode,
x_desc,
&mut work_space_size,
&mut reserved_space_size,
)
}?;
Ok((work_space_size, reserved_space_size))
}
#[allow(clippy::too_many_arguments)]
unsafe fn ffi_get_rnn_temp_space_sizes(
handle: cudnnHandle_t,
rnn_desc: cudnnRNNDescriptor_t,
mode: cudnnForwardMode_t,
x_desc: cudnnRNNDataDescriptor_t,
work_space_size: *mut ::libc::size_t,
reserved_space_size: *mut ::libc::size_t,
) -> Result<(), Error> {
let status = cudnnGetRNNTempSpaceSizes(
handle,
rnn_desc,
mode,
x_desc,
work_space_size,
reserved_space_size,
);
match status {
cudnnStatus_t::CUDNN_STATUS_SUCCESS => Ok(()),
cudnnStatus_t::CUDNN_STATUS_BAD_PARAM => {
Err(Error::BadParam("An invalid input argument was detected."))
}
cudnnStatus_t::CUDNN_STATUS_NOT_SUPPORTED => Err(Error::NotSupported(
"An incompatible or unsupported combination of input arguments was detected.",
)),
status => Err(Error::Unknown(
"Unable to obtain space sized for cuDNN rnn forward.",
status as u64,
)),
}
}
pub fn get_rnn_workspace_size(
handle: cudnnHandle_t,
rnn_desc: cudnnRNNDescriptor_t,
unroll_sequence_length: i32,
x_desc: Vec<cudnnTensorDescriptor_t>,
) -> Result<usize, Error> {
unsafe {
API::ffi_get_rnn_workspace_size(
handle,
rnn_desc,
unroll_sequence_length,
x_desc.as_slice(),
)
}
}
unsafe fn ffi_get_rnn_workspace_size(
handle: cudnnHandle_t,
rnn_desc: cudnnRNNDescriptor_t,
unroll_sequence_length: i32,
x_desc: &[cudnnTensorDescriptor_t],
) -> Result<::libc::size_t, Error> {
let mut size: ::libc::size_t = 0;
let size_ptr: *mut ::libc::size_t = &mut size;
match cudnnGetRNNWorkspaceSize(handle, rnn_desc, unroll_sequence_length, x_desc.as_ptr(), size_ptr) {
cudnnStatus_t::CUDNN_STATUS_SUCCESS => Ok(size),
cudnnStatus_t::CUDNN_STATUS_BAD_PARAM => Err(Error::BadParam("At least one of the following conditions are met: One of the parameters `x_desc`, `rnn_desc` is NULL. The tensors in `x_desc` are not of the same data type. The batch size of the tensors `x_desc` are not decreasing or staying constant.")),
cudnnStatus_t::CUDNN_STATUS_NOT_SUPPORTED => Err(Error::NotSupported("The data type used in `src_desc` is not supported for RNN.")),
status => Err(Error::Unknown("Unable to get CUDA cuDNN RNN Forward Workspace size.", status as i32 as u64)),
}
}
pub fn get_rnn_training_reserve_size(
handle: cudnnHandle_t,
rnn_desc: cudnnRNNDescriptor_t,
seq_length: ::libc::c_int,
x_desc: Vec<cudnnTensorDescriptor_t>,
) -> Result<usize, Error> {
unsafe {
API::ffi_get_rnn_training_reserve_size(handle, rnn_desc, seq_length, x_desc.as_slice())
}
}
unsafe fn ffi_get_rnn_training_reserve_size(
handle: cudnnHandle_t,
rnn_desc: cudnnRNNDescriptor_t,
seq_length: ::libc::c_int,
x_desc: &[cudnnTensorDescriptor_t],
) -> Result<::libc::size_t, Error> {
let mut size: ::libc::size_t = 0;
let size_ptr: *mut ::libc::size_t = &mut size;
match cudnnGetRNNTrainingReserveSize(handle, rnn_desc,seq_length, x_desc.as_ptr(), size_ptr) {
cudnnStatus_t::CUDNN_STATUS_SUCCESS => Ok(size),
cudnnStatus_t::CUDNN_STATUS_BAD_PARAM => Err(Error::BadParam("At least one of the following conditions are met: One of the parameters `handle`, `x_desc`, `rnn_desc` is NULL. The tensors in `x_desc` are not of the same data type. The batch size of the tensors `x_desc` are not decreasing or staying constant.")),
cudnnStatus_t::CUDNN_STATUS_NOT_SUPPORTED => Err(Error::NotSupported("The data type used in `src_desc` is not supported for RNN.")),
status => Err(Error::Unknown("Unable to get CUDA cuDNN RNN Training Reserve size.", status as i32 as u64)),
}
}
pub fn get_rnn_params_size(
handle: cudnnHandle_t,
rnn_desc: cudnnRNNDescriptor_t,
x_desc: cudnnTensorDescriptor_t,
data_type: DataType,
) -> Result<usize, Error> {
unsafe {
API::ffi_get_rnn_params_size(handle, rnn_desc, x_desc, API::cudnn_data_type(data_type))
}
}
unsafe fn ffi_get_rnn_params_size(
handle: cudnnHandle_t,
rnn_desc: cudnnRNNDescriptor_t,
x_desc: cudnnTensorDescriptor_t,
data_type: cudnnDataType_t,
) -> Result<::libc::size_t, Error> {
let mut size: ::libc::size_t = 0;
let size_ptr: *mut ::libc::size_t = &mut size;
match cudnnGetRNNParamsSize(handle, rnn_desc, x_desc, size_ptr, data_type) {
cudnnStatus_t::CUDNN_STATUS_SUCCESS => Ok(size),
cudnnStatus_t::CUDNN_STATUS_BAD_PARAM => Err(Error::BadParam("One of the following; rnnDesc is invalid, x_desc is invalid, x_desc isn't fully packed, dataType & tensor Description type don't match")),
cudnnStatus_t::CUDNN_STATUS_NOT_SUPPORTED => Err(Error::NotSupported("The data type used in `rnn_desc` is not supported for RNN.")),
status => Err(Error::Unknown("Unable to get CUDA cuDNN RNN Params Size", status as i32 as u64)),
}
}
}
impl API {
pub fn create_rnn_descriptor() -> Result<cudnnRNNDescriptor_t, Error> {
unsafe { API::ffi_create_rnn_descriptor() }
}
unsafe fn ffi_create_rnn_descriptor() -> Result<cudnnRNNDescriptor_t, Error> {
let mut rnn_desc: cudnnRNNDescriptor_t = ::std::ptr::null_mut();
match cudnnCreateRNNDescriptor(&mut rnn_desc) {
cudnnStatus_t::CUDNN_STATUS_SUCCESS => Ok(rnn_desc),
cudnnStatus_t::CUDNN_STATUS_ALLOC_FAILED => {
Err(Error::AllocFailed("The resources could not be allocated"))
}
status => Err(Error::Unknown(
"Unable create generic CUDA cuDNN RNN Descriptor",
status as i32 as u64,
)),
}
}
pub fn create_rnn_data_descriptor() -> Result<cudnnRNNDataDescriptor_t, Error> {
unsafe { API::ffi_create_rnn_data_descriptor() }
}
unsafe fn ffi_create_rnn_data_descriptor() -> Result<cudnnRNNDataDescriptor_t, Error> {
let mut rnn_data_descriptor: cudnnRNNDataDescriptor_t = ::std::ptr::null_mut();
match cudnnCreateRNNDataDescriptor(&mut rnn_data_descriptor) {
cudnnStatus_t::CUDNN_STATUS_SUCCESS => Ok(rnn_data_descriptor),
status => Err(Error::Unknown(
"Unable to create RNN Data Descriptor",
status as i32 as u64,
)),
}
}
pub fn set_rnn_data_descriptor(
rnn_data_descriptor: cudnnRNNDataDescriptor_t,
data_type: cudnnDataType_t,
layout: cudnnRNNDataLayout_t,
max_sequence_length: i32,
batch_size: i32,
vector_size: i32,
sequence_length_array: &[i32],
_padding: *mut ::libc::c_void,
) -> Result<cudnnRNNDataDescriptor_t, Error> {
unsafe {
API::ffi_set_rnn_data_descriptor(
rnn_data_descriptor,
data_type,
layout,
max_sequence_length,
batch_size,
vector_size,
sequence_length_array,
::std::ptr::null_mut() as *mut ::libc::c_void,
)
}
}
unsafe fn ffi_set_rnn_data_descriptor(
rnn_data_descriptor: cudnnRNNDataDescriptor_t,
data_type: cudnnDataType_t,
layout: cudnnRNNDataLayout_t,
max_sequence_length: i32,
batch_size: i32,
vector_size: i32,
sequence_length_array: &[i32],
padding: *mut ::libc::c_void,
) -> Result<cudnnRNNDataDescriptor_t, Error> {
match cudnnSetRNNDataDescriptor(
rnn_data_descriptor,
data_type,
layout,
max_sequence_length,
batch_size,
vector_size,
sequence_length_array.as_ptr(),
padding,
) {
cudnnStatus_t::CUDNN_STATUS_SUCCESS => Ok(rnn_data_descriptor),
cudnnStatus_t::CUDNN_STATUS_NOT_SUPPORTED => Err(Error::NotSupported(
"dataType is not one of CUDNN_DATA_HALF, CUDNN_DATA_FLOAT or CUDNN_DATA_DOUBLE",
)),
cudnnStatus_t::CUDNN_STATUS_ALLOC_FAILED => Err(Error::AllocFailed(
"The allocation of internal array storage has failed.",
)),
cudnnStatus_t::CUDNN_STATUS_BAD_PARAM => Err(Error::BadParam(
r#"One of these have occurred:
* rnn_data_desc is `null`.
* Any one of `max_sequence_length`, `batch_size` or `sequence_length_array` is less than or equal to zero.
* An element of `sequence_length_array` is less than zero or greater than `max_sequence_length`.
* `layout` is not one of `CUDNN_RNN_DATA_LAYOUT_SEQ_MAJOR_UNPACKED`, `CUDNN_RNN_DATA_LAYOUT_SEQ_MAJOR_PACKED` or `CUDNN_RNN_DATA_LAYOUT_BATCH_MAJOR_UNPACKED`.
"#,
)),
status => Err(Error::Unknown(
"Unable to set RNN Data Descriptor",
status as i32 as u64,
)),
}
}
pub fn destroy_rnn_descriptor(desc: cudnnRNNDescriptor_t) -> Result<(), Error> {
unsafe { API::ffi_destroy_rnn_descriptor(desc) }
}
unsafe fn ffi_destroy_rnn_descriptor(rnn_desc: cudnnRNNDescriptor_t) -> Result<(), Error> {
match cudnnDestroyRNNDescriptor(rnn_desc) {
cudnnStatus_t::CUDNN_STATUS_SUCCESS => Ok(()),
status => Err(Error::Unknown(
"Unable to destroy CUDA cuDNN Dropout Descriptor",
status as i32 as u64,
)),
}
}
#[allow(clippy::too_many_arguments)]
pub fn set_rnn_descriptor(
handle: cudnnHandle_t,
desc: cudnnRNNDescriptor_t,
hidden_size: i32,
num_layers: i32,
dropout_desc: cudnnDropoutDescriptor_t,
input_mode: cudnnRNNInputMode_t,
direction: cudnnDirectionMode_t,
mode: cudnnRNNMode_t,
algorithm: cudnnRNNAlgo_t,
data_type: DataType,
) -> Result<(), Error> {
unsafe {
API::ffi_set_rnn_descriptor(
handle,
desc,
hidden_size,
num_layers,
dropout_desc,
input_mode,
direction,
mode,
algorithm,
API::cudnn_data_type(data_type),
)
}
}
#[allow(clippy::too_many_arguments)]
unsafe fn ffi_set_rnn_descriptor(
handle: cudnnHandle_t,
desc: cudnnRNNDescriptor_t,
hidden_size: i32,
num_layers: i32,
dropout_desc: cudnnDropoutDescriptor_t,
input_mode: cudnnRNNInputMode_t,
direction: cudnnDirectionMode_t,
mode: cudnnRNNMode_t,
algorithm: cudnnRNNAlgo_t,
data_type: cudnnDataType_t,
) -> Result<(), Error> {
match cudnnSetRNNDescriptor_v6(
handle,
desc,
hidden_size,
num_layers,
dropout_desc,
input_mode,
direction,
mode,
algorithm,
data_type,
) {
cudnnStatus_t::CUDNN_STATUS_SUCCESS => Ok(()),
cudnnStatus_t::CUDNN_STATUS_BAD_PARAM => Err(Error::BadParam("FIXME RNN")),
cudnnStatus_t::CUDNN_STATUS_NOT_SUPPORTED => Err(Error::NotSupported("FIXME RNN")),
status => Err(Error::Unknown(
"Unable to set CUDA cuDNN RNN Descriptor.",
status as i32 as u64,
)),
}
}
pub fn set_rnn_matrix_math_type(
rnn_desc: cudnnRNNDescriptor_t,
math_type: cudnnMathType_t,
) -> Result<(), Error> {
unsafe { API::ffi_set_rnn_matrix_math_type(rnn_desc, math_type) }
}
unsafe fn ffi_set_rnn_matrix_math_type(
rnn_desc: cudnnRNNDescriptor_t,
math_type: cudnnMathType_t,
) -> Result<(), Error> {
match cudnnSetRNNMatrixMathType(rnn_desc, math_type) {
cudnnStatus_t::CUDNN_STATUS_SUCCESS => Ok(()),
cudnnStatus_t::CUDNN_STATUS_BAD_PARAM => Err(Error::BadParam("FIXME RNN")),
cudnnStatus_t::CUDNN_STATUS_NOT_SUPPORTED => Err(Error::NotSupported("FIXME RNN")),
status => Err(Error::Unknown(
"Unable to set CUDA cuDNN RNN Matrix Math Type.",
status as i32 as u64,
)),
}
}
pub fn set_rnn_padding_mode(
rnn_desc: cudnnRNNDescriptor_t,
padding_mode: cudnnRNNPaddingMode_t,
) -> Result<(), Error> {
unsafe { API::ffi_set_rnn_padding_mode(rnn_desc, padding_mode) }
}
unsafe fn ffi_set_rnn_padding_mode(
rnn_desc: cudnnRNNDescriptor_t,
padding_mode: cudnnRNNPaddingMode_t,
) -> Result<(), Error> {
match cudnnSetRNNPaddingMode(
rnn_desc,
padding_mode,
) {
cudnnStatus_t::CUDNN_STATUS_SUCCESS => Ok(()),
cudnnStatus_t::CUDNN_STATUS_BAD_PARAM => Err(Error::BadParam("cudnnSetRnnPaddingMode - Bad Param - Either RNN Desc is Null or paddingMode has an invalid enum (Unlikely due to Bindgen. Likely RNN Desc is somehow NULL")),
status => Err(Error::Unknown("Unable to set CUDA cuDNN RNN Padding Mode.", status as i32 as u64)),
}
}
}
impl API {
#[allow(clippy::too_many_arguments)]
pub fn rnn_forward_training(
handle: cudnnHandle_t,
rnn_desc: cudnnRNNDescriptor_t,
seq_length: ::libc::c_int,
x_desc: Vec<cudnnTensorDescriptor_t>,
x: *const ::libc::c_void,
hx_desc: cudnnTensorDescriptor_t,
hx: *const ::libc::c_void,
cx_desc: cudnnTensorDescriptor_t,
cx: *const ::libc::c_void,
w_desc: cudnnFilterDescriptor_t,
w: *const ::libc::c_void,
y_desc: Vec<cudnnTensorDescriptor_t>,
y: *mut ::libc::c_void,
hy_desc: cudnnTensorDescriptor_t,
hy: *mut ::libc::c_void,
cy_desc: cudnnTensorDescriptor_t,
cy: *mut ::libc::c_void,
workspace: *mut ::libc::c_void,
workspace_size_in_bytes: usize,
reserve: *mut ::libc::c_void,
reserve_size_in_bytes: usize,
) -> Result<(), Error> {
unsafe {
API::ffi_rnn_forward_training(
handle,
rnn_desc,
seq_length,
x_desc.as_slice(),
x,
hx_desc,
hx,
cx_desc,
cx,
w_desc,
w,
y_desc.as_slice(),
y,
hy_desc,
hy,
cy_desc,
cy,
workspace,
workspace_size_in_bytes,
reserve,
reserve_size_in_bytes,
)
}
}
#[allow(clippy::too_many_arguments)]
unsafe fn ffi_rnn_forward_training(
handle: cudnnHandle_t,
rnn_desc: cudnnRNNDescriptor_t,
seq_length: ::libc::c_int,
x_desc: &[cudnnTensorDescriptor_t],
x: *const ::libc::c_void,
hx_desc: cudnnTensorDescriptor_t,
hx: *const ::libc::c_void,
cx_desc: cudnnTensorDescriptor_t,
cx: *const ::libc::c_void,
w_desc: cudnnFilterDescriptor_t,
w: *const ::libc::c_void,
y_desc: &[cudnnTensorDescriptor_t],
y: *mut ::libc::c_void,
hy_desc: cudnnTensorDescriptor_t,
hy: *mut ::libc::c_void,
cy_desc: cudnnTensorDescriptor_t,
cy: *mut ::libc::c_void,
workspace: *mut ::libc::c_void,
work_space_size_in_bytes: usize,
reserve_space: *mut ::libc::c_void,
reserve_space_size_in_bytes: usize,
) -> Result<(), Error> {
let status = cudnnRNNForwardTraining(
handle,
rnn_desc,
seq_length,
x_desc.as_ptr(),
x,
hx_desc,
hx,
cx_desc,
cx,
w_desc,
w,
y_desc.as_ptr(),
y,
hy_desc,
hy,
cy_desc,
cy,
workspace,
work_space_size_in_bytes,
reserve_space,
reserve_space_size_in_bytes,
);
match status {
cudnnStatus_t::CUDNN_STATUS_SUCCESS => Ok(()),
cudnnStatus_t::CUDNN_STATUS_BAD_PARAM => Err(Error::BadParam("At least one of the following conditions was met: rnnDesc is invalid, hx_desc, w_desc, hy_desc, cy_desc, or one of the x_desc or y_desc is invalid. The descriptors for x_desc, cx_desc, _hx_desc, w_desc, y_desc, hy_desc, cy_desc have incorrect strides/dimensions. Workspace size is too small. Reserve space size is too small.")),
cudnnStatus_t::CUDNN_STATUS_NOT_SUPPORTED => Err(Error::NotSupported(r#"At least one of the following conditions are met:
* `src_desc` or `dest_desc` have negative tensor striding.
* `src_desc`, `rnn_desc` or `dest_desc` has a number of dimensions that is not 4 or 5.
* The chosen `algo` does not support the parameters provided; see the reference for exhaustive list of parameter support for each algo"#)),
cudnnStatus_t::CUDNN_STATUS_EXECUTION_FAILED => Err(Error::ExecutionFailed("The function failed to launch on the GPU.")),
cudnnStatus_t::CUDNN_STATUS_INVALID_VALUE => Err(Error::InvalidValue("cudnnSetPersistentRNNPlan() was not called prior to the current function when CUDNN_RNN_ALGO_PERSIST_DYNAMIC was selected in the RNN descriptor.")),
cudnnStatus_t::CUDNN_STATUS_ALLOC_FAILED => Err(Error::AllocFailed("The function was unable to allocate memory.")),
status => Err(Error::Unknown("Unable to compute CUDA cuDNN rnn forward.", status as u64)),
}
}
#[allow(clippy::too_many_arguments)]
pub fn rnn_forward_inference(
handle: cudnnHandle_t,
rnn_desc: cudnnRNNDescriptor_t,
seq_length: ::libc::c_int,
x_desc: *const cudnnTensorDescriptor_t,
x: *mut ::libc::c_void,
hx_desc: cudnnTensorDescriptor_t,
hx: *mut ::libc::c_void,
cx_desc: cudnnTensorDescriptor_t,
cx: *mut ::libc::c_void,
w_desc: cudnnFilterDescriptor_t,
w: *mut ::libc::c_void,
y_desc: *const cudnnTensorDescriptor_t,
y: *mut ::libc::c_void,
hy_desc: cudnnTensorDescriptor_t,
hy: *mut ::libc::c_void,
cy_desc: cudnnTensorDescriptor_t,
cy: *mut ::libc::c_void,
work_space: *mut ::libc::c_void,
work_size_in_bytes: ::libc::size_t,
) -> Result<(), Error> {
unsafe {
API::ffi_rnn_forward_inference(
handle,
rnn_desc,
seq_length,
x_desc,
x,
hx_desc,
hx,
cx_desc,
cx,
w_desc,
w,
y_desc,
y,
hy_desc,
hy,
cy_desc,
cy,
work_space,
work_size_in_bytes,
)
}
}
#[allow(clippy::too_many_arguments)]
unsafe fn ffi_rnn_forward_inference(
handle: cudnnHandle_t,
rnn_desc: cudnnRNNDescriptor_t,
seq_length: ::libc::c_int,
x_desc: *const cudnnTensorDescriptor_t,
x: *const ::libc::c_void,
hx_desc: cudnnTensorDescriptor_t,
hx: *const ::libc::c_void,
cx_desc: cudnnTensorDescriptor_t,
cx: *const ::libc::c_void,
w_desc: cudnnFilterDescriptor_t,
w: *const ::libc::c_void,
y_desc: *const cudnnTensorDescriptor_t,
y: *mut ::libc::c_void,
hy_desc: cudnnTensorDescriptor_t,
hy: *mut ::libc::c_void,
cy_desc: cudnnTensorDescriptor_t,
cy: *mut ::libc::c_void,
workspace: *mut ::libc::c_void,
work_space_size_in_bytes: usize,
) -> Result<(), Error> {
let status = cudnnRNNForwardInference(
handle,
rnn_desc,
seq_length,
x_desc,
x,
hx_desc,
hx,
cx_desc,
cx,
w_desc,
w,
y_desc,
y,
hy_desc,
hy,
cy_desc,
cy,
workspace,
work_space_size_in_bytes,
);
match status {
cudnnStatus_t::CUDNN_STATUS_SUCCESS => Ok(()),
cudnnStatus_t::CUDNN_STATUS_BAD_PARAM => Err(Error::BadParam("At least one of the following conditions are met: At least one of the following is NULL: `handle`, `src_desc`, `rnn_desc`, `conv_desc`, `dest_desc`, `src_data`, `alpha`, `beta`. `src_desc` and `dest_desc` have a non-matching number of dimensions. `src_desc` and `rnn_desc` have a non-matching number of dimensions. `src_desc` has fewer than three number of dimensions. `src_desc`s number of dimensions is not equal to `conv_desc`s `array_length` + 2. `src_desc` and `rnn_desc` have a non-matching number of input feature maps per image. `src_desc`, `rnn_desc` and `dest_desc` have a non-matching data type. For some spatial dimension, `rnn_desc` has a spatial size that is larger than the input spatial size (including zero-padding size).")),
cudnnStatus_t::CUDNN_STATUS_NOT_SUPPORTED => Err(Error::NotSupported("At least one of the following conditions are met: `src_desc` or `dest_desc` have negative tensor striding. `src_desc`, `rnn_desc` or `dest_desc` has a number of dimensions that is not 4 or 5. The chosen algo does not support the parameters provided; see the reference for exhaustive list of parameter support for each algo")),
status => Err(Error::Unknown("Unable to compute CUDA cuDNN rnnal forward.", status as i32 as u64)),
}
}
}
impl API {
#[allow(clippy::too_many_arguments)]
pub fn rnn_backward_data(
handle: cudnnHandle_t,
rnn_desc: cudnnRNNDescriptor_t,
seq_length: ::libc::c_int,
y_desc: *const cudnnTensorDescriptor_t,
y: *const ::libc::c_void,
dy_desc: *const cudnnTensorDescriptor_t,
dy: *const ::libc::c_void,
dhy_desc: cudnnTensorDescriptor_t,
dhy: *const ::libc::c_void,
dcy_desc: cudnnTensorDescriptor_t,
dcy: *const ::libc::c_void,
w_desc: cudnnFilterDescriptor_t,
w: *const ::libc::c_void,
hx_desc: cudnnTensorDescriptor_t,
hx: *const ::libc::c_void,
cx_desc: cudnnTensorDescriptor_t,
cx: *const ::libc::c_void,
dx_desc: *const cudnnTensorDescriptor_t,
dx: *mut ::libc::c_void,
dhx_desc: cudnnTensorDescriptor_t,
dhx: *mut ::libc::c_void,
dcx_desc: cudnnTensorDescriptor_t,
dcx: *mut ::libc::c_void,
workspace: *mut ::libc::c_void,
workspace_size_in_bytes: usize,
reserve_space: *mut ::libc::c_void,
reserve_space_size_in_bytes: usize,
) -> Result<(), Error> {
unsafe {
API::ffi_rnn_backward_data(
handle,
rnn_desc,
seq_length,
y_desc,
y,
dy_desc,
dy,
dhy_desc,
dhy,
dcy_desc,
dcy,
w_desc,
w,
hx_desc,
hx,
cx_desc,
cx,
dx_desc,
dx,
dhx_desc,
dhx,
dcx_desc,
dcx,
workspace,
workspace_size_in_bytes,
reserve_space,
reserve_space_size_in_bytes,
)
}
}
#[allow(clippy::too_many_arguments)]
unsafe fn ffi_rnn_backward_data(
handle: cudnnHandle_t,
rnn_desc: cudnnRNNDescriptor_t,
seq_length: ::libc::c_int,
y_desc: *const cudnnTensorDescriptor_t,
y: *const ::libc::c_void,
dy_desc: *const cudnnTensorDescriptor_t,
dy: *const ::libc::c_void,
dhy_desc: cudnnTensorDescriptor_t,
dhy: *const ::libc::c_void,
dcy_desc: cudnnTensorDescriptor_t,
dcy: *const ::libc::c_void,
w_desc: cudnnFilterDescriptor_t,
w: *const ::libc::c_void,
hx_desc: cudnnTensorDescriptor_t,
hx: *const ::libc::c_void,
cx_desc: cudnnTensorDescriptor_t,
cx: *const ::libc::c_void,
dx_desc: *const cudnnTensorDescriptor_t,
dx: *mut ::libc::c_void,
dhx_desc: cudnnTensorDescriptor_t,
dhx: *mut ::libc::c_void,
dcx_desc: cudnnTensorDescriptor_t,
dcx: *mut ::libc::c_void,
workspace: *mut ::libc::c_void,
workspace_size_in_bytes: usize,
reserve_space: *mut ::libc::c_void,
reserve_space_size_in_bytes: usize,
) -> Result<(), Error> {
match cudnnRNNBackwardData(
handle,
rnn_desc,
seq_length,
y_desc,
y,
dy_desc,
dy,
dhy_desc,
dhy,
dcy_desc,
dcy,
w_desc,
w,
hx_desc,
hx,
cx_desc,
cx,
dx_desc,
dx,
dhx_desc,
dhx,
dcx_desc,
dcx,
workspace,
workspace_size_in_bytes,
reserve_space,
reserve_space_size_in_bytes
) {
cudnnStatus_t::CUDNN_STATUS_SUCCESS => Ok(()),
cudnnStatus_t::CUDNN_STATUS_BAD_PARAM => Err(Error::BadParam("At least one of the following conditions are met: At least one of the following is NULL: `handle`, `diff_desc`, `rnn_desc`, `conv_desc`, `grad_desc`, `diff_data`, `rnn_data`, `grad_data`, `alpha`, `beta`. `rnn_desc` and `diff_desc` have a non-matching number of dimensions. `rnn_desc` and `grad_desc` have a non-matching number of dimensions. `rnn_desc has fewer than three number of dimensions. `rnn_desc`, `grad_desc` and `diff_desc` have a non-matching data type. `rnn_desc` and `grad_desc` have a non-matching number of input feature maps per image. `diff_desc`s spatial sizes do not match with the expected size as determined by `cudnnGetRNNNdForwardOutputDim()`.")),
cudnnStatus_t::CUDNN_STATUS_NOT_SUPPORTED => Err(Error::NotSupported("At least one of the following conditions are met: `diff_desc` or `grad_desc` have negative tensor striding. `diff_desc`, `rnn_desc` or `grad_desc` has a number of dimensions that is not 4 or 5. The chosen algo does not support the parameters provided; see the reference for exhaustive list of parameter support for each algo")),
cudnnStatus_t::CUDNN_STATUS_MAPPING_ERROR => Err(Error::MappingError("An error occurs during the texture binding of the rnn data or the input differential tensor data.")),
cudnnStatus_t::CUDNN_STATUS_EXECUTION_FAILED => Err(Error::ExecutionFailed("Execution failed to launch on GPU.")),
status => Err(Error::Unknown("Unable to compute CUDA cuDNN rnnal backward data.", status as i32 as u64)),
}
}
#[allow(clippy::too_many_arguments)]
pub fn rnn_backward_weights(
handle: cudnnHandle_t,
rnn_desc: cudnnRNNDescriptor_t,
seq_length: ::libc::c_int,
x_desc: *const cudnnTensorDescriptor_t,
x: *const ::libc::c_void,
hx_desc: cudnnTensorDescriptor_t,
hx: *const ::libc::c_void,
y_desc: *const cudnnTensorDescriptor_t,
y: *const ::libc::c_void,
workspace: *const ::libc::c_void,
work_space_size_in_bytes: usize,
dw_desc: cudnnFilterDescriptor_t,
dw: *mut ::libc::c_void,
reserve_space: *const ::libc::c_void,
reserve_space_size_in_bytes: usize,
) -> Result<(), Error> {
unsafe {
API::ffi_rnn_backward_weights(
handle,
rnn_desc,
seq_length,
x_desc,
x,
hx_desc,
hx,
y_desc,
y,
workspace,
work_space_size_in_bytes,
dw_desc,
dw,
reserve_space,
reserve_space_size_in_bytes,
)
}
}
#[allow(clippy::too_many_arguments)]
unsafe fn ffi_rnn_backward_weights(
handle: cudnnHandle_t,
rnn_desc: cudnnRNNDescriptor_t,
seq_length: ::libc::c_int,
x_desc: *const cudnnTensorDescriptor_t,
x: *const ::libc::c_void,
hx_desc: cudnnTensorDescriptor_t,
hx: *const ::libc::c_void,
y_desc: *const cudnnTensorDescriptor_t,
y: *const ::libc::c_void,
workspace: *const ::libc::c_void,
work_space_size_in_bytes: usize,
dw_desc: cudnnFilterDescriptor_t,
dw: *mut ::libc::c_void,
reserve_space: *const ::libc::c_void,
reserve_space_size_in_bytes: usize,
) -> Result<(), Error> {
match cudnnRNNBackwardWeights(
handle,
rnn_desc,
seq_length,
x_desc,
x,
hx_desc,
hx,
y_desc,
y,
workspace,
work_space_size_in_bytes,
dw_desc,
dw,
reserve_space,
reserve_space_size_in_bytes,
) {
cudnnStatus_t::CUDNN_STATUS_SUCCESS => Ok(()),
cudnnStatus_t::CUDNN_STATUS_BAD_PARAM => Err(Error::BadParam("At least one of the following conditions are met: At least one of the following is NULL: `handle`, `src_desc`, `diff_desc`, `conv_desc`, `grad_desc`, `src_data`, `diff_data`, `grad_data`, `alpha`, `beta`. `src_desc` and `diff_desc` have a non-matching number of dimensions. `src_desc` and `grad_desc` have a non-matching number of dimensions. `src_desc` has fewer than three number of dimensions. `src_desc`, `diff_desc` and `grad_desc` have a non-matching data type. `src_desc` and `grad_desc` have a non-matching number of input feature maps per image.")),
cudnnStatus_t::CUDNN_STATUS_NOT_SUPPORTED => Err(Error::NotSupported("At least one of the following conditions are met: `src_desc` or `diff_desc` have negative tensor striding. `src_desc`, `diff_desc` or `grad_desc` has a number of dimensions that is not 4 or 5. The chosen algo does not support the parameters provided; see the reference for exhaustive list of parameter support for each algo")),
cudnnStatus_t::CUDNN_STATUS_MAPPING_ERROR => Err(Error::MappingError("An error occurs during the texture binding of the rnn data.")),
cudnnStatus_t::CUDNN_STATUS_EXECUTION_FAILED => Err(Error::ExecutionFailed("Execution failed to launch on GPU.")),
status => Err(Error::Unknown("Unable to compute CUDA cuDNN rnnal backward rnn.", status as i32 as u64)),
}
}
}