2017-04-03 99 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; 
} 

预期结果是将每行的每个元素增加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; 
}  

但是这样做会失败,因为每行的每个元素都是随机初始化的。我该如何解决这个问题?

所以我发现问题与this有关。所以,我应该初始化mat有:

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

但随后这将创建问题omp_priv = omp_orig,因为它会考虑std::vector<cv::Mat1f> mat(5);,它的价值是不确定的。我该如何解决这个问题?即来到我的脑海里唯一的解决方案是创建一个包装结构是这样的:

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

你是什么意思*“每行的每个元素随机inizitialized”*? – 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

如果提供operator=深 - 复制标的Matclone()您与vectMat方式也将工作,并保持初始化。

+0

感谢您的回答。我简化了我的示例,请查看我更新的问题 – justHelloWorld

+0

@justHelloWorld我更新了有关更新问题的答案。认为我没有得到你所需要的。 – Zulan

+0

感谢您的更新。然而,在这段代码'mat.size()= 0'的末尾:( – justHelloWorld