Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"invalid controlling predicate" compiler error using OpenMP

Tags:

c

openmp

I'm creating a basic prime number checker, based on C - determine if a number is prime , but utilising OpenMP.

int isPrime(int value)
{
    omp_set_num_threads(4);

    #pragma omp parallel for 
    for( int j = 2;  j * j <= value; j++)
    {
    if ( value % j == 0) return 0;
    }
    return value;
}

When compiling with -fopenmp, GCC version 4.7.2 is erroring, stating invalid controlling predicate with respect to the for loop.

It looks like this error is caused by the j squared in the for loop. Is there a way I can work around this and still achieve the desired output from the algorithm?

like image 260
Nick Avatar asked Jul 10 '13 15:07

Nick


2 Answers

return is not allowed inside the loop as it will cause exit before the curly braces.

Note the definition given below :

From the OpenMP V2.5 spec, 1.2.2 OpenMP language terminology, p2:17-

structured block - For C/C++, an executable statement, possibly compound, with a single entry at the top and a single exit at the bottom.

A structured block starts with the open { and ends with the closing }. The return is contained within these braces, so this program also violates the OpenMP definition for a structured block, because it has two exits (one at the return and one at the exit through the brace)

OpenMP places the following five restrictions on which loops can be threaded:

  • The loop variable must be of type signed integer. Unsigned integers, such as DWORD's, will not work.
  • The comparison operation must be in the form loop_variable <, <=, >, or >= loop_invariant_integer
  • The third expression or increment portion of the for loop must be either integer addition or integer subtraction and by a loop invariant value.
  • If the comparison operation is < or <=, the loop variable must increment on every iteration, and conversely, if the comparison operation is > or >=, the loop variable must decrement on every iteration.
  • The loop must be a basic block, meaning no jumps from the inside of the loop to the outside are permitted with the exception of the exit statement, which terminates the whole application. If the statements goto or break are used, they must jump within the loop, not outside it. The same goes for exception handling; exceptions must be caught within the loop.
like image 190
0decimal0 Avatar answered Oct 20 '22 01:10

0decimal0


According to the OpenMP standard (§2.5.1, p.40), the acceptable forms of the controlling predicate of the for loop are:

  • var relational-op b, and
  • b relational-op var

Your use of j * j <= value is a clear violation of this requirement. The rationale is that it requires the compiler to emit code that computes the integer square root of value at run time, with the latter being undefined for some values of value, specifically for the negative ones.

You can replace j * j <= value with j <= sqrt_value, where sqrt_value is the integer square root of value, but then would come the problem with having an alternative exit path in the structured block inside the loop. Unfortunately no easy solution exists in this case since OpenMP does not support premature termination of parallel loops.

like image 29
Hristo Iliev Avatar answered Oct 19 '22 23:10

Hristo Iliev