@@ -277,59 +277,31 @@ void ElmanRNNLayer::calculate_forward_feed(
277277 return ;
278278 }
279279
280- std::vector<double > flattened_inputs (batch_size * num_time_steps * N_prev);
280+ std::vector<double > flattened_batch_inputs (batch_size * num_time_steps * N_prev);
281281 for (size_t b = 0 ; b < batch_size; ++b)
282282 {
283283 const auto & rnn_in = batch_gradients_and_outputs[b].get_rnn_outputs (prev_layer_index);
284284 if (!rnn_in.empty ())
285285 {
286- std::copy (rnn_in.begin (), rnn_in.end (), flattened_inputs .begin () + b * num_time_steps * N_prev);
286+ std::copy (rnn_in.begin (), rnn_in.end (), flattened_batch_inputs .begin () + b * num_time_steps * N_prev);
287287 }
288288 else
289289 {
290290 const auto std_in = batch_gradients_and_outputs[b].get_outputs (prev_layer_index);
291291 for (size_t t = 0 ; t < num_time_steps; ++t)
292292 {
293- std::copy (std_in.begin (), std_in.end (), flattened_inputs .begin () + (b * num_time_steps + t) * N_prev);
293+ std::copy (std_in.begin (), std_in.end (), flattened_batch_inputs .begin () + (b * num_time_steps + t) * N_prev);
294294 }
295295 }
296296 }
297297
298298 // 2. Pre-calculate Input-to-Hidden (W * x_t) for all ticks
299299 std::vector<double > batch_pre_act (batch_size * num_time_steps * N_this, 0.0 );
300300
301- auto precalc_gates = [&](size_t b_start, size_t b_end)
302- {
303- for (size_t b = b_start; b < b_end; ++b)
304- {
305- for (size_t t = 0 ; t < num_time_steps; ++t)
306- {
307- const double * x_t = &flattened_inputs[(b * num_time_steps + t) * N_prev];
308- double * pre_t = &batch_pre_act[(b * num_time_steps + t) * N_this];
309-
310- if (has_bias ())
311- {
312- std::copy (get_b_values ().begin (), get_b_values ().end (), pre_t );
313- }
314-
315- for (size_t i = 0 ; i < N_prev; ++i)
316- {
317- const double xi = x_t [i];
318- if (xi == 0.0 )
319- {
320- continue ;
321- }
322- const double * w_row = &get_w_values ()[i * N_this];
323- simd::mul_add (xi, w_row, pre_t , N_this);
324- }
325- }
326- }
327- };
328-
329301 const auto & num_threads = _task_queue_pool->get_number_of_threads ();
330302 if (num_threads <= 1 )
331303 {
332- precalc_gates (0 , batch_size);
304+ pre_calculate_gates (0 , batch_size, N_this, N_prev, num_time_steps, flattened_batch_inputs, batch_pre_act );
333305 }
334306 else
335307 {
@@ -340,10 +312,10 @@ void ElmanRNNLayer::calculate_forward_feed(
340312 size_t end = start + size;
341313 if (start < end)
342314 {
343- _task_queue_pool->enqueue ([&precalc_gates, start, end ]()
344- {
345- precalc_gates (start, end);
346- });
315+ _task_queue_pool->enqueue ([start, end, N_this, N_prev, num_time_steps, &flattened_batch_inputs, &batch_pre_act, this ]()
316+ {
317+ pre_calculate_gates (start, end, N_this, N_prev, num_time_steps, flattened_batch_inputs, batch_pre_act );
318+ });
347319 }
348320 start = end;
349321 }
@@ -448,6 +420,42 @@ void ElmanRNNLayer::calculate_forward_feed(
448420 }
449421}
450422
423+ void ElmanRNNLayer::pre_calculate_gates (
424+ const size_t & b_start,
425+ const size_t & b_end,
426+ const size_t N_this,
427+ const size_t N_prev,
428+ const size_t num_time_steps,
429+ const std::vector<double >& flattened_batch_inputs,
430+ std::vector<double >& batch_pre_act
431+ ) const
432+ {
433+ for (size_t b = b_start; b < b_end; ++b)
434+ {
435+ for (size_t t = 0 ; t < num_time_steps; ++t)
436+ {
437+ const double * x_t = &flattened_batch_inputs[(b * num_time_steps + t) * N_prev];
438+ double * pre_t = &batch_pre_act[(b * num_time_steps + t) * N_this];
439+
440+ if (has_bias ())
441+ {
442+ std::copy (get_b_values ().begin (), get_b_values ().end (), pre_t );
443+ }
444+
445+ for (size_t i = 0 ; i < N_prev; ++i)
446+ {
447+ const double xi = x_t [i];
448+ if (xi == 0.0 )
449+ {
450+ continue ;
451+ }
452+ const double * w_row = &get_w_values ()[i * N_this];
453+ simd::mul_add (xi, w_row, pre_t , N_this);
454+ }
455+ }
456+ }
457+ }
458+
451459void ElmanRNNLayer::calculate_output_gradients (std::vector<GradientsAndOutputs>& batch_gradients_and_outputs, std::vector<std::vector<double >>::const_iterator target_outputs_begin, const std::vector<HiddenStates>& batch_hidden_states, size_t batch_size) const
452460{
453461 MYODDWEB_PROFILE_FUNCTION (" ElmanRNNLayer" );
0 commit comments