M_PI undefined

M_PI undefined

I am compiling with the command line option std=c99, my code compiles fine without out this command, but put it in and all of a sudden you get M_PI undefined. This also happens when compiling with gcc; adding std=c99 creates a lot of M_PI undefined errors.

You may ask why am I compiling with std=c99 as a command line option.

I must do it. My previous thread about false error messages when compiling with icc without the std=c99 option. One cannot nest for loops with cilk_for option; if you do you get a error message.

The workaround is touse

std=c99.

plus some other cl options, but they are secondary. How should I fix this error?

Thanks in advance.

Newport_j

11 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Once again, this is a base compiler question. You should ask those in the Intel C Compiler forum.

As I explained in reply #7 in the cilkifying c source thread, the "cilk_for initialization must be a declaration" error is due to the nested cilk_for in PRC_RAY2 using the index "i" declared at function level. Even if the compiler were resolving the reference correctly, itwould bea race betweenparallel iterations of the outer cilk_for loop. Which would certainly be harder to find.

You can work aroundthe error(and the race!) without using std=c99by declaringyour loop index inside the cilk_for loop indexed by IRAY.

In other words, change your code as follows:

  /*-----------------------------------------
    Copy the ray type into the unfolded type.
    -----------------------------------------*/

  cilk_for(IRAY=IRAY1;IRAY<=IRAY2;IRAY++){
    int inner_i;
    :
    :

    cilk_for(inner_i=0;inner_i<(*Env).Nfreq;inner_i++){
      URAYu[IRAY*MAX_NUM_FREQ+inner_i] = TRD[IRAY].URAY[inner_i] 
	- 2.0 * M_PI * (*Env).frequency_Hz[inner_i] * TIMv;
      FRAYu[IRAY*MAX_NUM_FREQ+inner_i] = TRD[IRAY].FRAY[inner_i];
    };
    ORAYu[IRAY] = TRD[IRAY].ORAY;

  };

Note that I'm assuming that you're using std=c99 to allow you to declare the loop index in the cilk_for. Like:

    cilk_for(int i=0;i<(*Env).Nfreq;i++)

The fix above has the same effect.

- Barry

Quoting newport_j
I am compiling with the command line option std=c99, my code compiles fine without out this command, but put it in and all of a sudden you get M_PI undefined. This also happens when compiling with gcc; adding std=c99 creates a lot of M_PI undefined errors...

I just verified adeclaration of 'M_PI'in fourdifferent C/C++ compilers andit is defined in 'math.h' header file.I hope that a directive:

...
#include
...

will solve your problem. If not, I woulddefine my own 'M_PI' as follows:

...
#define M_PI 3.14159265358979323846
...

Best regards,
Sergey

In the glibc math.h on Red Hat, the more accurate M_PIl is guarded by #ifdef __USE_GNU, which explains why setting std=c99 (in case you wanted std=gnu99) takes away the definition. There is a 20-digit value value guarded by #if defined __USE_BSD || defined __USE_XOPEN. The constants in those groups are not permitted by the C standard to be defined in strict standard conforming mode. The math.h which comes with icc doesn't have those constants. So, you need to have gnu89 mode (the default) or gnu99 mode set to see the definitions you may be expecting. Much of what I just said is there for you to read in your installation.

Ihave a questions about your response. It could probably be answered by referring me to a reference in one ofintel's manuals. If that is the case, then refer me to the correct manual reference instead of typing a long answer.

I see where you change the inner loop from i to inner_i, you also define inner_i to be an integer inside the outer loop.The questions:

1. Why distingush i byrenaming it inner_i, there is no outer loop index i, so why call i inner_i?

2. Why define inner_i to be an integer inside outer loop. It seems that you could simply define it where all the other definitions are.

Note : I tried defining i in the general definition area at the start of the program; it did not work.Scope issue.

Again, I am sure these could be answered by referring me to a document published by Intel. if thta is so then refer me.

Thanks in advance.

Newport_j

> 1. Why distingush i by renaming it inner_i, there is no outer loop index i, so why call i inner_i?

For some reason I thought "i" was used elsewhere in the function. If that's true, then there's no reason not to simply move the declaration of "i" into the outer loop.

> 2. Why define inner_i to be an integer inside outer loop. It seems that you could simply define it
> where all the other definitions are.

It's the fact that it's at the top of the function that's the root of the problem.

When the compiler sees a cilk_for loop, it silently creates a lambda function from the loop body. All of the variables declared at an outer scope are "captured" so they can be referenced from the lambda function. You've got a nested cilk_for, so the process repeats; the compiler creates a lambda function for the inner cilk_for body and captures all of the variables declared in the outer scope again.The problemis thatthe compiler is attempting to access the captured variable "i" in the inner loop andfailing since it needs to go up two levels.

And even if the compiler were generating the correct code to access "i", it would still be incorrect. Let's assume that the outer cilk_for (the one indexed by IRAY) is split into halves, and the second half is stolen. Now both halves initialize the "i" variable at function scope and start to increment it: You've got a race.

Moving the declaration of "i" to inside the outer cilk_for means that each of the outer cilk_for iterations has it's own instance of "i." Which will fix the compiler error and remove the race. And as a by-product remove the need to use the c99 language variant which is causing all of the glitches you're running into.

- Barry

Okay, so we must define the inner loop's index as an integer before the inner loop begins, but after the outer loopstarts?

The is of course assumes the inner loop ion comilation is giving the error "initialization must be a declaration".

The index of the outer loop is irrelevant?

Thanks in advance.

Newport_j

Correct. The index of the outer loop is irrelevant. It's already where it needs to be.

The key is where the inner loop index is declared.The inner loop indexneeds to be declared in the lambda function for the outer loop body. Using C99 allows you to use C++-style loop indexes that are declared as part of the for loop statement, so the loop index variable is in the "correct" place. But you can get the same effect by moving the inner loop index variable declaration into the outer loop body.

This is of course assuming that the example in reply #7of cilkifying c source matches your problem.

- Barry

In reply to the reply dated April 25, 2012. can we nest these loop where the one must declare an inner_i for the cilk_for loop and there is another loop inside of that loop where the inner_inner_i is declared and used? Same rules apply, but cilk_for loops that are now nexted and both will give error:

declaration required on initialization

If they are not given new parametersspecific to the cilk_for loop and declared before the cilk_for loop begins. Even the innermost loop must do this.

That would make one outer loop a cilk_for loop, oneinner loop ainner cilk_for loop and one inner inner loop an cilk_for loop?

I hope this is clear, if not let me know.

I am runing Ubuntu 11.04 on a quad core. The icc versionis 12.1.

How is syntax on this?

Thanks in advance.

Newport_j

Sorry,I'm not sure what you're asking.

If you're asking can this be nested further, the answer is sure. The following should also work:

#include 

int main()
{
    int i;
    int ary[42];

    cilk_for(i = 0; i < 42; i++)
    {
        int j;
        ary[i] = i;

        cilk_for(j = 0; j < 42; j++)
        {
            int k;
            ary[j] = j;

            cilk_for(k = 0; k < 42; k++)
            {
                ary[k] = k;
            }
        }
    }

    return 0;
}

The key is that the loop index is declared in the scope nearest it's use as a cilk_for index. You can nest as deep as you want to go.

Are you looking to reference "i" in the loop indexed by "k" perhaps?

- Barry

I believe this reply answerd my question.

Thanks.

newport_j

Leave a Comment

Please sign in to add a comment. Not a member? Join today