This function computes exact, first-order derivatives of the RNN model with respect to its inputs: `x`, `hx` and for the LSTM cell type also `cx`. The following buffers should contain to the same data as in the preceding `rnn_forward()` call: `y`, the initial hidden state `hx`, and the initial cell state `cx` (for LSTM only). This function accepts any combination of `dhy`, `dhx`, `dcy`, `dcx` be
(
&self,
rnn_desc: &RnnDescriptor<T1, T2>,
device_seq_lengths: &impl GpuBuffer<i32>,
y_desc: &RnnDataDescriptor<T1, L>,
y: &impl GpuBuffer<T1>,
dy: &imp
| 1788 | /// |
| 1789 | /// Returns errors if an invalid or incompatible input argument was encountered. |
| 1790 | pub fn rnn_backward_data<T1, T2, L>( |
| 1791 | &self, |
| 1792 | rnn_desc: &RnnDescriptor<T1, T2>, |
| 1793 | device_seq_lengths: &impl GpuBuffer<i32>, |
| 1794 | y_desc: &RnnDataDescriptor<T1, L>, |
| 1795 | y: &impl GpuBuffer<T1>, |
| 1796 | dy: &impl GpuBuffer<T1>, |
| 1797 | x_desc: &RnnDataDescriptor<T1, L>, |
| 1798 | dx: &mut impl GpuBuffer<T1>, |
| 1799 | h_desc: Option<&TensorDescriptor<T1, NCHW, 3>>, |
| 1800 | hx: Option<&impl GpuBuffer<T1>>, |
| 1801 | dhy: Option<&impl GpuBuffer<T1>>, |
| 1802 | dhx: Option<&mut impl GpuBuffer<T1>>, |
| 1803 | c_desc: Option<&TensorDescriptor<T1, NCHW, 3>>, |
| 1804 | cx: Option<&impl GpuBuffer<T1>>, |
| 1805 | dcy: Option<&impl GpuBuffer<T1>>, |
| 1806 | dcx: Option<&mut impl GpuBuffer<T1>>, |
| 1807 | weight_space: &mut impl GpuBuffer<u8>, |
| 1808 | work_space: &mut impl GpuBuffer<u8>, |
| 1809 | reserve_space: &mut impl GpuBuffer<u8>, |
| 1810 | ) -> Result<(), CudnnError> |
| 1811 | where |
| 1812 | T1: DataType + RnnDataType, |
| 1813 | T2: DataType + SupportedPrec<T1>, |
| 1814 | L: RnnDataLayout, |
| 1815 | NCHW: SupportedType<T1>, |
| 1816 | { |
| 1817 | let device_sequence_lengths_ptr = device_seq_lengths.as_device_ptr().as_ptr(); |
| 1818 | |
| 1819 | let y_ptr = y.as_device_ptr().as_raw(); |
| 1820 | let dy_ptr = dy.as_device_ptr().as_raw(); |
| 1821 | |
| 1822 | let dx_ptr = dx.as_device_ptr().as_ptr(); |
| 1823 | |
| 1824 | let h_desc = h_desc.map_or(std::ptr::null_mut(), |desc| desc.raw); |
| 1825 | |
| 1826 | let hx_ptr = hx.map_or(std::ptr::null(), |buff| buff.as_device_ptr().as_ptr()); |
| 1827 | let dhy_ptr = dhy.map_or(std::ptr::null(), |buff| buff.as_device_ptr().as_ptr()); |
| 1828 | let dhx_ptr = dhx.map_or(std::ptr::null_mut(), |buff| { |
| 1829 | buff.as_device_ptr().as_mut_ptr() |
| 1830 | }); |
| 1831 | |
| 1832 | let c_desc = c_desc.map_or(std::ptr::null_mut(), |desc| desc.raw); |
| 1833 | |
| 1834 | let cx_ptr = cx.map_or(std::ptr::null(), |buff| buff.as_device_ptr().as_ptr()); |
| 1835 | let dcy_ptr = dcy.map_or(std::ptr::null(), |buff| buff.as_device_ptr().as_mut_ptr()); |
| 1836 | let dcx_ptr = dcx.map_or(std::ptr::null_mut(), |buff| { |
| 1837 | buff.as_device_ptr().as_mut_ptr() |
| 1838 | }); |
| 1839 | |
| 1840 | let weight_space_ptr = weight_space.as_device_ptr().as_ptr(); |
| 1841 | let work_space_ptr = work_space.as_device_ptr().as_ptr(); |
| 1842 | let reserve_space_ptr = reserve_space.as_device_ptr().as_ptr(); |
| 1843 | |
| 1844 | unsafe { |
| 1845 | sys::cudnnRNNBackwardData_v8( |
| 1846 | self.raw, |
| 1847 | rnn_desc.raw, |
nothing calls this directly
no test coverage detected