Arman
Arman

Reputation: 4626

How to convert for loop to STL for_each statement

I would like to convert my for loop to STL std::for_each loop.

 bool CMyclass::SomeMember()
 {
    int ii;
        for(int i=0;i<iR20;i++)
            {
              ii=indexR[i];
              ishell=static_cast<int>(R[ii]/xStep);
              theta=atan2(data->pPOS[ii*3+1], data->pPOS[ii*3]);
              al2[ishell] += massp*cos(fm*theta);
            }
 }

Actually I was planning to use parallel STL from g++4.4

 g++ -D_GLIBCXX_PARALLEL -fopenmp

which is allow to run code in parallel without changes if the code is written in standard STL library.

Upvotes: 5

Views: 1246

Answers (4)

Fred Larson
Fred Larson

Reputation: 62063

You'll need to convert the loop body into a function or functor. There are a lot of undeclared variables in there, so I can't easily tell how to separate out the loop body. Here's a stab at it:

class DoStuff
{
  int* R;
  int xStep;
  Data* data;
  double massp;
  double fm;
  double* al2;
public:
  DoStuff(int* R_, int xStep_, Data* data_, double massp_, double fm_, double* al2_) :
    R(R_), xStep(xStep_), data(data_), massp(massp_), fm(fm_), al2(al2_) {}

  void operator()(int ii)
  {
     int ishell = static_cast<int>(R[ii]/xStep);
     double theta = atan2(data->pPOS[ii*3+1], data->pPOS[ii*3]);
     al2[ishell] += massp*cos(fm*theta);
  }
};

for_each(indexR, indexR+iR20, DoStuff(R, xStep, data, massp, fm, al2));

Upvotes: 0

Oleg
Oleg

Reputation: 220

You cannot just separate cycle body into functor and assume that it will be paralellised because you have too many dependencies inside cycle body. Cycle will be able to run in parallel only if you have no global arrays or pointers. If you provide full function body then we can think how to change it to parallel version.

Upvotes: 1

amit kumar
amit kumar

Reputation: 21022

class F {
   public:
   void operator()(int ii) {
              ishell=static_cast<int>(R[ii]/xStep);
              theta=atan2(data->pPOS[ii*3+1], data->pPOS[ii*3]);
              al2[ishell] += massp*cos(fm*theta);
   } 
   F(int[] r): //and other parameters should also be passed into the constructor
      r_(r) {}
   void:
   int[] r_; // refers to R[ii] array
   // and other parameters should also be stored
};

F f(R); // pass other parameters too  
for_each(&indexR[0], &indexR[iR20], f);

However it might not be a good idea to use this "automatic parallelization" since you need to keep in mind the grainsize of each parallel computation -- I am not sure how well the compiler takes the grain size into account.

Upvotes: 1

JoeG
JoeG

Reputation: 13182

You need to seperate out the loop body into a seperate function or functor; I've assumed all the undeclared variables are member variables.

void CMyclass::LoopFunc(int ii)  {
    ishell=static_cast<int>(R[ii]/xStep);
    theta=atan2(data->pPOS[ii*3+1],
    data->pPOS[ii*3]);
    al2[ishell] += massp*cos(fm*theta);
}

bool CMyclass::SomeMember()  { 
    std::for_each(&indexR[0],&indexR[iR20],std::tr1::bind(&CMyclass::LoopFunc,std::tr1::ref(*this));
}

Upvotes: 5

Related Questions