c++ opencv parallel-processing openmp reduction

c++ - reducción de omp en el vector de cv:: Mat o cv:: Mat en general



opencv parallel-processing (1)

Los tipos como cv::Mat1f , que usan referencias en lugar de copiar, son realmente peligrosos en este contexto. Usted hace una solución clara y explícita al dividir la región parallel y el ciclo for .

#pragma omp declare reduction(vec_mat1f_plus : std::vector<cv::Mat1f> : / std::transform(omp_out.begin(), omp_out.end(), omp_in.begin(), omp_out.begin(), std::plus<cv::Mat1f>())); // initializer not necessary if you initialize explicitly std::vector<cv::Mat1f> mat; #pragma omp parallel reduction(vec_mat1f_plus : mat) { mat = std::vector<cv::Mat1f>(5); for (auto& elem : mat) { elem = cv:Mat1f::zeros(1, n); } #pragma omp for for(size_t i=0; i<m; i++){ mat[indexes[m]] += 1; } }

No he probado si std::plus<cv::Mat1f> funciona, pero se ve bien .

Su enfoque con vectMat también funcionará si proporciona un operator= que copia profundamente el Mat subyacente con clone() y conserva el inicializador.

//In other words, this equilavent to cv::Mat1f mat(5,n) //i.e. a matrix 5xn std::vector<cv::Mat1f> mat(5,cv::Mat1f::zeros(1,n)); std::vector<float> indexes(m); // fill indexes // m >> nThreads (from hundreds to thousands) for(size_t i=0; i<m; i++){ mat[indexes[m]] += 1; }

El resultado esperado es aumentar cada elemento de cada fila en uno. Este es un ejemplo de juguete, la suma real es mucho más compatible. Traté de paralelizarlo con:

#pragma omp declare reduction(vec_float_plus : std::vector<cv::Mat1f> : / std::transform(omp_out.begin(), omp_out.end(), omp_in.begin(), omp_out.begin(), std::plus<cv::Mat1f>())) / initializer(omp_priv=omp_orig); #pragma omp parallel for reduction(vec_float_plus : mat) for(size_t i=0; i<m; i++){ mat[indexes[m]] += 1; }

Pero esto falla porque cada elemento de cada fila está inizitializado aleatoriamente. ¿Como puedo resolver esto?

Entonces descubrí que el problema está relacionado con esto . Entonces debería inicializar mat con:

std::vector<cv::Mat1f> mat(5); for(size_t i=0; i<mat.size(); i++) mat[i] = cv::Mat1f::zeros(1,n);

Pero esto crearía problemas con omp_priv = omp_orig , ya que consideraría std::vector<cv::Mat1f> mat(5); y sus valores no están definidos. ¿Como puedo resolver esto? La única solución que me vino a la mente es crear una estructura de contenedor, algo así como:

class vectMat{ public: vectMat(size_t rows, size_t j){ for(size_t i=0; i<rows; i++) mats.push_back(cv::Mat1f::zeros(1,j)); } private: std::vector<cv::Mat1f> mats; };

Pero entonces, ¿qué debería implementar para que funcione con el resto del código?