2

C++ で autodesk maya 2013 用のプラグインを作成しています。一連の最適化問題をできるだけ早く解決する必要があります。このタスクにはオープン MP を使用しています。問題は、並列計算の経験があまりないことです。私は使用しようとしました:

#pragma omp parallel for schedule (static)

私のforループで(それがどのように機能するかを十分に理解していない)、一部のコードでは非常にうまく機能しましたが、コードの別の部分がクラッシュしました.

以下は、omp ディレクティブが原因でクラッシュする関数の例です。

void PlanarizationConstraint::fillSparseMatrix(const Optimizer& opt, vector<T>& elements, double mu)
{
    int size = 3;
    #pragma omp parallel for schedule (static)
    for(int i = 0; i < opt.FVIc.outerSize(); i++)
    {
        int index = 3*i;
        Eigen::Matrix<double,3,3> Qxyz = Eigen::Matrix<double,3,3>::Zero();
        for(SpMat::InnerIterator it(opt.FVIc,i); it; ++it)
        {
            int face = it.row();
            for(int n = 0; n < size; n++)
            {
                Qxyz.row(n) += N(face,n)*N.row(face);
                elements.push_back(T(index+n,offset+face,(1 - mu)*N(face,n)));
            }
        }

        for(int n = 0; n < size; n++)
        {
            for(int k = 0; k < size; k++)
            {
                elements.push_back(T(index+n,index+k,(1-mu)*Qxyz(n,k)));
            }
        }
    }

    #pragma omp parallel for schedule (static)
    for(int j = 0; j < opt.VFIc.outerSize(); j++)
    {
        elements.push_back(T(offset+j,offset+j,opt.fvi[j]));
        for(SpMat::InnerIterator it(opt.VFIc,j); it; ++it)
        {
            int index = 3*it.row();
            for(int n = 0; n < size; n++)
            {
                elements.push_back(T(offset+j,index+n,N(j,n)));
            }
        }
    }
}

そして、これらのディレクティブで非常にうまく機能するコードの例を次に示します (そのため高速です)。

Eigen::MatrixXd Optimizer::OptimizeLLGeneral()
{
    ConstraintsManager manager;
    SurfaceConstraint surface(1,true);
    PlanarizationConstraint planarization(1,true,3^Nv,Nf);
    manager.addConstraint(&surface);
    manager.addConstraint(&planarization);
    double mu = mu0;
    for(int k = 0; k < iterations; k++)
    {
        #pragma omp parallel for schedule (static)
        for(int j = 0; j < VFIc.outerSize(); j++)
        {
            manager.calcVariableMatrix(*this,j);
        }
        #pragma omp parallel for schedule (static)
        for(int i = 0; i < FVIc.outerSize(); i++)
        {
            Eigen::MatrixXd A = Eigen::Matrix<double, 3, 3>::Zero();
            Eigen::MatrixXd b = Eigen::Matrix<double, 1, 3>::Zero();
            manager.addLocalMatrixComponent(*this,i,A,b,mu);
            Eigen::VectorXd temp = b.transpose();
            Q.row(i) = A.colPivHouseholderQr().solve(temp);
        }
        mu = r*mu;
    }
    return Q;
}

私の質問は、1 つの関数が omp ディレクティブでうまく機能する理由と、他の関数がクラッシュする理由です。omp ディレクティブの動作が異なる違いは何ですか?

4

1 に答える 1