C++ and OpenMP

tacosareveryyummy

Supreme [H]ardness
Joined
Jul 25, 2005
Messages
5,300
It isn't immediately obvious to me what the error is. I am trying to use OpenMP to parallelize the given loop. Each thread should execute the lines of code up to "run.random_walk()", then update the shared variables n and n_previous which keep track of my current and previous ensemble sizes, and lastly save to a 2x2 vector based on the value of the variable w which is calculated using n/n_previous. The code works and compiles fine sequentially.

Here is the error (Not very elucidating.) :
Code:
mal@ubuntu:~/Desktop/research/modification$ g++ -fopenmp montecarlo.cc
montecarlo.cc: In function ‘int main(int, char**)’:
montecarlo.cc:114:3: error: invalid controlling predicate

Here is the loop:
Code:
#pragma omp parallel for private(n_e, index, current_time, step, state_vector, step_values, state_vector_p, w) shared(n, n_previous) schedule(dynamic)
  for(n_e = 0; n_e < N_e; n_e++)
    {	
      run.generate_val(total_time/time_step);
      
      for(int i = 0; i < initial_state_size; i++)
	{ state_vector.push_back(state_vector_i[i]); }         
      
      for(current_time = 0.0; current_time < total_time; current_time = current_time + time_step)
	{	
	  state_vector_p.clear();
	  for(int k = 0; k < initial_state_size; k++)
	    { state_vector_p.push_back(state_vector[k]); }
	  index = current_time/time_step;
	  step = step_values[index];
	  
	  run.random_walk(step); 
	  
	  w = run.weight();     
	  n_previous = n;  
	  n = n + w; //This keeps track of the ensemble size for the normalization energy.     
	  
	  for(int v = 0; v < w; v++)
	    {
	      vector<float> row; //Create an empty row.
	      for(int o = 0; o < initial_state_size; o++)
		{ row.push_back(state_vector[o]); }//Add elements to row.
	      n_m.push_back(row); //Add row to the vector n_m.
	    } 	  
	}          
    }

Here is int main():
Code:
int main(int argc, char **argv)
{

  int step = 0, n_e;
  float w = 0.0;
  float value = 0.0;
  float current_time = 0;
  int index = 0; 
  CSMC_solver run;
 
  ifstream infile2;

  srand(time(NULL));
 
  //Check for interaction file 
  if(argc != 2)
    { 
      cerr << "Usage: " << argv[0] << " <interaction file> " << endl;
      return 1;
    }
  
  /*--------Read interaction file---------*/
  /*Format of input file assumes
    1st line: ensemble size N_e and G
    2nd line: number of pair orbitals for |n> 
    3rd line: s.p. energy of each orbital
    all other: n_i i.e. pair occupation numbers
  */

  infile2.open(argv[1]);
  infile2 >> N_e;
  infile2 >> G_ij;
  infile2 >> initial_state_size;

  for(int i = 0; i < initial_state_size; i++)
    { 
      infile2 >> value;
      epsilon_values.push_back(value);
    } 

  for(int i = 0; i < initial_state_size; i++) 
    { 
      infile2 >> value;
      state_vector_i.push_back(value); 
    }
 
  infile2.close();
  n = N_e;

#pragma omp parallel for private(n_e, index, current_time, step, state_vector, step_values, state_vector_p, w) shared(n, n_previous) schedule(dynamic)
  for(n_e = 0; n_e < N_e; n_e++)
    {	
      run.generate_val(total_time/time_step);
      
      for(int i = 0; i < initial_state_size; i++)
	{ state_vector.push_back(state_vector_i[i]); }         
      
      for(current_time = 0.0; current_time < total_time; current_time = current_time + time_step)
	{	
	  state_vector_p.clear();
	  for(int k = 0; k < initial_state_size; k++)
	    { state_vector_p.push_back(state_vector[k]); }
	  index = current_time/time_step;
	  step = step_values[index];
	  
	  run.random_walk(step); 
	  
	  w = run.weight();     
	  n_previous = n;  
	  n = n + w; //This keeps track of the ensemble size for the normalization energy.     
	  
	  for(int v = 0; v < w; v++)
	    {
	      vector<float> row; //Create an empty row.
	      for(int o = 0; o < initial_state_size; o++)
		{ row.push_back(state_vector[o]); }//Add elements to row.
	      n_m.push_back(row); //Add row to the vector n_m.
	    } 	  
	}          
    }
  
  run.Energy();
  
  return 0;
}
 
Could you humor me here? "The" for statement? really?
for(n_e = 0; n_e < N_e; n_e++)
for(int i = 0; i < initial_state_size; i++)
for(current_time = 0.0; current_time < total_time; current_time = current_time + time_step)
for(int k = 0; k < initial_state_size; k++)
for(int v = 0; v < w; v++)
for(int o = 0; o < initial_state_size; o++)
 
Last edited:
Ahhh, I ment the first for loop immediatley after the #pragma omp line. Ill have to get back to you on the version of gcc/openmp.
 
One thing that you may try... Change N_e to a predefined value and see what happens.
 
The only thing that looks odd to me is this:

Code:
schedule(dynamic)

Try this:

Code:
schedule(dynamic,16)

Also note that you can break up the code using the '\' character on the #pragma...it helps with readability:

Code:
#pragma omp parallel for \
    private(n_e, index, current_time, step, state_vector, step_values, state_vector_p, w) \
    shared(n, n_previous) \
    schedule(dynamic,16)

Also this cleans up the private list a lot (if you want to use it that is):
Code:
#pragma omp parallel for \
    default(none) \
    shared(n, n_previous) \
    schedule(dynamic,16)

If nothing else helps here try commenting out pieces of the loop to hunt down any errors. Line 114 could mean anything belonging to the parallel for loop and if your compiler is crappy enough it could certainly mislead you.
 
Last edited:
It was an issue with ints and floats. n_e was declared as an int and N_e was declared as a float because I was also using it in another part of the code. It now compiles but I have a seg fault somewhere.

Thanks for the help so far.
 
I don't see the declaration of N_e.
There was a lot of code that was missing from that paste. E.g. if you look at the error, it references .line 114, but there aren't even 114 lines in the "main". My guess is he had declared them globally. *shrug*
 
Back
Top