| 2145 | |
| 2146 | template <class T> |
| 2147 | bool MIOpenSupport::DoRnnBackwardImpl( |
| 2148 | Stream* stream, const MIOpenRnnDescriptor& rnn_desc, |
| 2149 | const MIOpenRnnSequenceTensorDescriptor& input_desc, |
| 2150 | const DeviceMemory<T>& input_data, |
| 2151 | const MIOpenRnnStateTensorDescriptor& input_h_desc, |
| 2152 | const DeviceMemory<T>& input_h_data, |
| 2153 | const MIOpenRnnStateTensorDescriptor& input_c_desc, |
| 2154 | const DeviceMemory<T>& input_c_data, const DeviceMemory<T>& params, |
| 2155 | const MIOpenRnnSequenceTensorDescriptor& output_desc, |
| 2156 | const DeviceMemory<T>& output_data, |
| 2157 | const MIOpenRnnStateTensorDescriptor& output_h_desc, |
| 2158 | const DeviceMemory<T>& output_h_data, |
| 2159 | const MIOpenRnnStateTensorDescriptor& output_c_desc, |
| 2160 | const DeviceMemory<T>& output_c_data, |
| 2161 | const DeviceMemory<T>& output_backprop_data, |
| 2162 | const DeviceMemory<T>& output_h_backprop_data, |
| 2163 | const DeviceMemory<T>& output_c_backprop_data, |
| 2164 | DeviceMemory<T>* input_backprop_data, |
| 2165 | DeviceMemory<T>* input_h_backprop_data, |
| 2166 | DeviceMemory<T>* input_c_backprop_data, |
| 2167 | DeviceMemory<T>* params_backprop_data, |
| 2168 | DeviceMemory<uint8>* reserve_space_data, |
| 2169 | ScratchAllocator* workspace_allocator, |
| 2170 | dnn::ProfileResult* output_profile_result) { |
| 2171 | // extract model parameters |
| 2172 | RnnModelDims model_dims; |
| 2173 | bool res = ExtractAndCheckRnnForward( |
| 2174 | rnn_desc, input_desc, input_data, input_h_desc, input_h_data, |
| 2175 | input_c_desc, input_c_data, params, output_desc, output_data, |
| 2176 | output_h_desc, output_h_data, output_c_desc, output_c_data, &model_dims); |
| 2177 | if (!res) { |
| 2178 | LOG(ERROR) << "Invalid parameters for RNN Model"; |
| 2179 | return false; |
| 2180 | } |
| 2181 | |
| 2182 | auto miopen = miopen_->GetHandle(parent_, stream); |
| 2183 | |
| 2184 | // check params size |
| 2185 | |
| 2186 | if (!CheckRNNParameterSize(miopen.handle(), rnn_desc, input_desc)) { |
| 2187 | LOG(ERROR) << "Invalid parameters"; |
| 2188 | return false; |
| 2189 | } |
| 2190 | |
| 2191 | // create the workspace |
| 2192 | DeviceMemory<uint8> workspace; |
| 2193 | if (!CreateRnnWorkspace(stream, miopen.handle(), rnn_desc, input_desc, |
| 2194 | workspace_allocator, &workspace)) { |
| 2195 | LOG(ERROR) << "Unable to create rnn workspace"; |
| 2196 | return false; |
| 2197 | } |
| 2198 | |
| 2199 | // workaround for missing initialization support in MIOpen. |
| 2200 | // TODO: remove this when MIOpen is ready. |
| 2201 | auto size_data = input_desc.seq_length() * input_desc.batch_size() * |
| 2202 | input_desc.data_size(); |
| 2203 | if ((size_data > 0) && (input_backprop_data->opaque() != nullptr)) |
| 2204 | stream->ThenMemZero(input_backprop_data, size_data * sizeof(float)); |
nothing calls this directly
no test coverage detected