c++multithreadingopenmpstdvector

Passing vector by reference in OpenMP loop


Is it safe to update a vector passed by reference in an OpenMP loop?

In this example, I update the vector out_vector from a function inside the parallel loop to which it is passed by reference.

#include <omp.h>
#include <vector>
#include <cstddef>
#include <cstdlib>

void inner_fun(const std::vector<int>& in_vector, std::vector<int>& out_vector, const std::size_t j, const std::size_t loop_vector_length) {
  
  const std::size_t starting_index = j * loop_vector_length;
  std::srand(starting_index);
  
  for(std::size_t i = starting_index; i < starting_index + loop_vector_length; ++i) {
    out_vector[i] = in_vector[i] + rand() % 10000;
  }
}

std::vector<int> outer_fun(const std::vector<int>& in_vector, const std::size_t loop_vector_length) {
  
  const std::size_t vector_length = in_vector.size();
  std::vector<int> out_vector (vector_length);
  
  #pragma omp parallel for num_threads(5)
  for(std::size_t j = 0; j < vector_length / loop_vector_length; ++j) {
    inner_fun(in_vector, out_vector, j, loop_vector_length);
  }
  
  return out_vector;
}

I know that it would be safe to update out_vector directly inside the loop. Though, I am not sure whether that also applies to a function inside the loop to which the vector is passed by reference.

I had assumed that this question had been answered on SO, but did not find a respective post. Feel free to mark this question as a duplicate, if you find a post that already answered this question.

Thanks.


Solution

  • Yes, that is safe to do, passing it to a other function by reference doesn't change that.

    One remark to the code: With the inner_fun you split the array in chunks and let every chunk be processed by one worker of the parallel region. Such an effect can also be achieved by using a spezific schedule in the omp directive. See the specification for all options https://www.openmp.org/spec-html/5.1/openmpsu48.html#x73-730002.11.4

    Example:

    #pragma omp parallel for schedule(static)