@@ -227,7 +227,8 @@ void FFLayer::calculate_forward_feed(
227227 }
228228
229229 const size_t effective_batch_size = batch_size * num_time_steps;
230- std::vector<double > batch_inputs_buffer (effective_batch_size * N_prev);
230+ thread_local std::vector<double > batch_inputs_buffer;
231+ batch_inputs_buffer.resize (effective_batch_size * N_prev);
231232
232233 for (size_t b = 0 ; b < batch_size; ++b)
233234 {
@@ -246,7 +247,8 @@ void FFLayer::calculate_forward_feed(
246247 }
247248 }
248249
249- std::vector<double > batch_pre_activation_sums_buffer (effective_batch_size * N_this, 0.0 );
250+ thread_local std::vector<double > batch_pre_activation_sums_buffer;
251+ batch_pre_activation_sums_buffer.assign (effective_batch_size * N_this, 0.0 );
250252
251253 // 2. Initialize with bias values
252254 if (has_bias ())
@@ -275,16 +277,18 @@ void FFLayer::calculate_forward_feed(
275277 }
276278 else
277279 {
280+ auto & batch_inputs_buffer_ref = batch_inputs_buffer;
281+ auto & batch_pre_activation_sums_buffer_ref = batch_pre_activation_sums_buffer;
278282 size_t start = 0 ;
279283 for (unsigned int t = 0 ; t < active_gemm_threads; ++t)
280284 {
281285 size_t size = (effective_batch_size / active_gemm_threads) + (t < (effective_batch_size % active_gemm_threads) ? 1 : 0 );
282286 size_t end = start + size;
283287 if (start < end)
284288 {
285- _task_queue_pool->enqueue ([start, end, N_prev, N_this, &batch_inputs_buffer , &batch_pre_activation_sums_buffer , this ]()
289+ _task_queue_pool->enqueue ([start, end, N_prev, N_this, &batch_inputs_buffer_ref , &batch_pre_activation_sums_buffer_ref , this ]()
286290 {
287- run_gemm (start, end, N_prev, N_this, batch_inputs_buffer, batch_pre_activation_sums_buffer );
291+ run_gemm (start, end, N_prev, N_this, batch_inputs_buffer_ref, batch_pre_activation_sums_buffer_ref );
288292 });
289293 }
290294 start = end;
@@ -301,16 +305,18 @@ void FFLayer::calculate_forward_feed(
301305 }
302306 else
303307 {
308+ auto & batch_inputs_buffer_ref = batch_inputs_buffer;
309+ auto & batch_pre_activation_sums_buffer_ref = batch_pre_activation_sums_buffer;
304310 size_t start = 0 ;
305311 for (unsigned int t = 0 ; t < active_post_threads; ++t)
306312 {
307313 size_t size = (batch_size / active_post_threads) + (t < (batch_size % active_post_threads) ? 1 : 0 );
308314 size_t end = start + size;
309315 if (start < end)
310316 {
311- _task_queue_pool->enqueue ([start, end, num_time_steps, N_this, &batch_gradients_and_outputs, &batch_residual_output_values, &batch_hidden_states, &batch_inputs_buffer , &batch_pre_activation_sums_buffer , is_training, this ]()
317+ _task_queue_pool->enqueue ([start, end, num_time_steps, N_this, &batch_gradients_and_outputs, &batch_residual_output_values, &batch_hidden_states, &batch_inputs_buffer_ref , &batch_pre_activation_sums_buffer_ref , is_training, this ]()
312318 {
313- run_post_gemm (start, end, num_time_steps, N_this, batch_gradients_and_outputs, batch_residual_output_values, batch_hidden_states, batch_inputs_buffer, batch_pre_activation_sums_buffer , is_training);
319+ run_post_gemm (start, end, num_time_steps, N_this, batch_gradients_and_outputs, batch_residual_output_values, batch_hidden_states, batch_inputs_buffer_ref, batch_pre_activation_sums_buffer_ref , is_training);
314320 });
315321 }
316322 start = end;
@@ -488,7 +494,8 @@ void FFLayer::calculate_hidden_gradients(
488494 const size_t num_time_steps = batch_hidden_states[0 ].at (get_layer_index ()).size ();
489495 if (num_time_steps == 0 ) return ;
490496
491- std::vector<double > flattened_next_grads_buffer (batch_size * num_time_steps * N_next, 0.0 );
497+ thread_local std::vector<double > flattened_next_grads_buffer;
498+ flattened_next_grads_buffer.assign (batch_size * num_time_steps * N_next, 0.0 );
492499 const bool use_direct_gradients = batch_next_grad_matrix.empty ();
493500 for (size_t b = 0 ; b < batch_size; ++b)
494501 {
@@ -531,7 +538,8 @@ void FFLayer::calculate_hidden_gradients(
531538 }
532539
533540 const size_t effective_batch_size = batch_size * num_time_steps;
534- std::vector<double > flattened_this_grads_buffer (effective_batch_size * N_this, 0.0 );
541+ thread_local std::vector<double > flattened_this_grads_buffer;
542+ flattened_this_grads_buffer.assign (effective_batch_size * N_this, 0.0 );
535543 const double * W_next = next_layer.get_w_values ().data ();
536544
537545 const auto & num_threads = _task_queue_pool->get_number_of_threads ();
@@ -548,9 +556,11 @@ void FFLayer::calculate_hidden_gradients(
548556 }
549557 else
550558 {
559+ auto & flattened_next_grads_buffer_ref = flattened_next_grads_buffer;
560+ auto & flattened_this_grads_buffer_ref = flattened_this_grads_buffer;
551561 if (!use_gemm_mt)
552562 {
553- run_gemm_backward (0 , effective_batch_size, N_next, N_this, W_next, flattened_next_grads_buffer, flattened_this_grads_buffer );
563+ run_gemm_backward (0 , effective_batch_size, N_next, N_this, W_next, flattened_next_grads_buffer_ref, flattened_this_grads_buffer_ref );
554564 }
555565 else
556566 {
@@ -559,15 +569,15 @@ void FFLayer::calculate_hidden_gradients(
559569 {
560570 size_t size = (effective_batch_size / active_gemm_threads) + (t < (effective_batch_size % active_gemm_threads) ? 1 : 0 );
561571 size_t end = start + size;
562- if (start < end) _task_queue_pool->enqueue ([start, end, N_next, N_this, W_next, &flattened_next_grads_buffer , &flattened_this_grads_buffer , this ]() { run_gemm_backward (start, end, N_next, N_this, W_next, flattened_next_grads_buffer, flattened_this_grads_buffer ); });
572+ if (start < end) _task_queue_pool->enqueue ([start, end, N_next, N_this, W_next, &flattened_next_grads_buffer_ref , &flattened_this_grads_buffer_ref , this ]() { run_gemm_backward (start, end, N_next, N_this, W_next, flattened_next_grads_buffer_ref, flattened_this_grads_buffer_ref ); });
563573 start = end;
564574 }
565575 _task_queue_pool->get ();
566576 }
567577
568578 if (!use_post_mt)
569579 {
570- run_post_gemm_backward (0 , batch_size, N_this, batch_gradients_and_outputs, batch_hidden_states, flattened_this_grads_buffer );
580+ run_post_gemm_backward (0 , batch_size, N_this, batch_gradients_and_outputs, batch_hidden_states, flattened_this_grads_buffer_ref );
571581 }
572582 else
573583 {
@@ -576,7 +586,7 @@ void FFLayer::calculate_hidden_gradients(
576586 {
577587 size_t size = (batch_size / active_post_threads) + (t < (batch_size % active_post_threads) ? 1 : 0 );
578588 size_t end = start + size;
579- if (start < end) _task_queue_pool->enqueue ([start, end, N_this, &batch_gradients_and_outputs, &batch_hidden_states, &flattened_this_grads_buffer , this ]() { run_post_gemm_backward (start, end, N_this, batch_gradients_and_outputs, batch_hidden_states, flattened_this_grads_buffer ); });
589+ if (start < end) _task_queue_pool->enqueue ([start, end, N_this, &batch_gradients_and_outputs, &batch_hidden_states, &flattened_this_grads_buffer_ref , this ]() { run_post_gemm_backward (start, end, N_this, batch_gradients_and_outputs, batch_hidden_states, flattened_this_grads_buffer_ref ); });
580590 start = end;
581591 }
582592 _task_queue_pool->get ();
@@ -594,7 +604,8 @@ void FFLayer::calculate_hidden_gradients_from_output_gradients(std::vector<Gradi
594604 if (num_time_steps == 0 ) return ;
595605
596606 const size_t effective_batch_size = batch_size * num_time_steps;
597- std::vector<double > flattened_this_grads_buffer (effective_batch_size * N_this, 0.0 );
607+ thread_local std::vector<double > flattened_this_grads_buffer;
608+ flattened_this_grads_buffer.assign (effective_batch_size * N_this, 0.0 );
598609 const bool use_direct_gradients = batch_output_gradients.empty ();
599610 for (size_t b = 0 ; b < batch_size; ++b)
600611 {
@@ -643,16 +654,17 @@ void FFLayer::calculate_hidden_gradients_from_output_gradients(std::vector<Gradi
643654 }
644655 else
645656 {
657+ auto & flattened_this_grads_buffer_ref = flattened_this_grads_buffer;
646658 size_t start = 0 ;
647659 for (unsigned int t = 0 ; t < active_threads; ++t)
648660 {
649661 size_t size = (batch_size / active_threads) + (t < (batch_size % active_threads) ? 1 : 0 );
650662 size_t end = start + size;
651663 if (start < end)
652664 {
653- _task_queue_pool->enqueue ([start, end, N_this, &batch_gradients_and_outputs, &batch_hidden_states, &flattened_this_grads_buffer , this ]()
665+ _task_queue_pool->enqueue ([start, end, N_this, &batch_gradients_and_outputs, &batch_hidden_states, &flattened_this_grads_buffer_ref , this ]()
654666 {
655- run_post_gemm_backward (start, end, N_this, batch_gradients_and_outputs, batch_hidden_states, flattened_this_grads_buffer );
667+ run_post_gemm_backward (start, end, N_this, batch_gradients_and_outputs, batch_hidden_states, flattened_this_grads_buffer_ref );
656668 });
657669 }
658670 start = end;
@@ -817,8 +829,9 @@ void FFLayer::run_post_gemm_backward(
817829{
818830 MYODDWEB_PROFILE_FUNCTION (" FFLayer" );
819831
820- std::vector<double > deriv_buf (N_this);
821- std::vector<double > rnn_grads_row;
832+ thread_local std::vector<double > deriv_buf;
833+ deriv_buf.resize (N_this);
834+ thread_local std::vector<double > rnn_grads_row;
822835 for (size_t b = start; b < end; b++)
823836 {
824837 const auto & layer_states = batch_hidden_states[b].at (get_layer_index ());
0 commit comments