2017-04-03 11 views
2
//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; 
} 

예상되는 결과는 각 행의 각 요소를 하나씩 증가시키는 것입니다. 이것은 장난감의 예입니다. 실제 합계는 훨씬 더 복잡합니다. 나는 그것을 병렬 처리하려고 :일반적으로 cv :: Mat 또는 cv :: Mat 벡터의 omp 감소

#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; 
}  

그러나 각 행의 각 요소는 무작위로 inizitialized 때문에이 실패합니다. 이 문제를 어떻게 해결할 수 있습니까?

그래서이 문제는 this과 관련이 있다는 것을 알게되었습니다. 그래서와 mat 초기화해야합니다

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

을하지만 std::vector<cv::Mat1f> mat(5);을 고려할 것하고 값이 정의되지 이후 다음이, omp_priv = omp_orig 문제를 만들 것입니다. 이 문제를 어떻게 해결할 수 있습니까? 나는 그것이 코드의 나머지 부분과 함께 작동하도록 구현해야하는지 다음

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; 
}; 

하지만 내 마음에 온 유일한 해결책은, 같은 것을 래퍼 구조를 만드는 것입니다?

+0

* "각 행의 각 요소가 무작위로 구성되지 않습니다"*? – Zulan

+0

@ Zulan 앞의 경우 서로 다른 줄이 "연결"되어 있으므로 첫 번째 경우처럼'mat'을 초기화 할 수 없지만'omp_priv = omp_orig'에 문제가있는 것 같습니까? – justHelloWorld

+0

@ Zulan 제 질문을 – justHelloWorld

답변

1

복사 대신 참조를 사용하는 cv::Mat1f과 같은 유형은 실제로이 컨텍스트에서 위험합니다. parallel 영역과 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; 
    } 
} 

내가 std::plus<cv::Mat1f> 여부를 작동하지만 looks good을 테스트하지 않았습니다.

vectMat와 귀하의 접근 방식은 또한 깊은 사본이 clone()Mat 놓인 operator=를 제공하는 경우 작동 및 초기화를 유지합니다.

+0

답변 해 주셔서 감사합니다. 내 예를 지나치게 단순화 시켰습니다. 업데이트 된 질문을 보시기 바랍니다. – justHelloWorld

+0

@justHelloWorld 업데이트 된 질문에 대한 답변을 업데이트했습니다. 내가 네가 필요로하는 것이 아니라고 생각해. – Zulan

+0

감사합니다. 그러나,이 코드의 끝에'mat.size() = 0' :( – justHelloWorld