2

Do OpenMP 'For' loops work with multiple loop variables? For example:

int i;
double k;
#pragma omp parallel for
for (k = 0, i = 0; k < 1; k += 0.1, i++)
{ }

It works fine without OpenMP, but using it I get the following errors:

  • C3015: initialization in OpemMP 'for' statement has improper form
  • C3019: increment in OpenMP 'for' statement has improper form
Nicholas
  • 1,392
  • 16
  • 38

2 Answers2

4

You can do this

#pragma omp parallel for
for (int i = 0; i<10; i++) {
    double k = 0.1*i;
}

If you really want to avoid the multiplication in the loop and be closer to your original code you can do this

#pragma omp parallel 
{
    int nthreads = omp_get_num_threads();
    int ithread = omp_get_thread_num();
    int starti = ithread*10/nthreads;
    int finishi = (ithread+1)*10/nthreads;
    double start = 0.1*starti;
    double finish = 0.1*finishi;

    double k;
    int i;
    for (k = start, i = starti; k < finish; k += 0.1, i++) {
   }  
}

When I first wrote this answer I did not realize one subtle point.

The conversion from

for (k = 0; k < 1; k += 0.1)

to

for (int i = 0; i<10; i++) double k = 0.1*i;

is not one-to-one. I mean the results are not necessarily identical. That's because for floating point math multiplication times an integer is not necessarily repeated addition. It may be fine in many cases it's important to be aware that they are not the same thing.

It's possible to go the other way from multiplication to repeated addition if you use Kahan summation but going from repeated addition to multiplication is not guaranteed to give the same result.

You can read more about it at floating-point-multiplication-vs-repeated-addition.

Community
  • 1
  • 1
Z boson
  • 32,619
  • 11
  • 123
  • 226
1

You need to convert the code to only use i (i.e., the int variable with the simple increment) for the the loop itself, and work with k in code controlled by the loop:

double k = 0.0;
int i;

for (i=0; i<10; i++) {
    // body of loop goes here
    k+=0.1;
}
Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • but in that case k is shared not like an open MP loop increment.... so take care of k I don't know all what you're planning to do with k but here begins the interesting stuff – alexbuisson Apr 01 '14 at 06:37
  • @alexbuisson: Yes, depending on how it's used, you may well (for one possible example) want to use `private(k)` in your OpenMP `#pragma`. – Jerry Coffin Apr 01 '14 at 06:43
  • k is used in a parameterised function. Wouldn't using private(k) or as above imply that k would never get assigned to the full range (0-->1) on ANY thread? ie. wouldn't k get evaluated N times using k=0.0, 0.1, and 0.2 only? – Nicholas Apr 01 '14 at 23:10