2017-04-03 3 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); 

しかし、それは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

関連する問題