BlueBrain / nmodl

Code Generation Framework For NEURON MODeling Language
https://bluebrain.github.io/nmodl/
Apache License 2.0
57 stars 15 forks source link

Issue while compiling generated code with oneAPI compiler and OpenMP enabled #1050

Open pramodk opened 1 year ago

pramodk commented 1 year ago

On Intel machines, I am installing NEURON+CoreNEURON with the OpenMP variant i.e.

spack install neuron~report+caliper@develop+openmp%oneapi

and this produces build time errors like:

[NMODL] [info] :: Parsing Units
[NMODL] [info] :: Running nmodl inline visitor
[NMODL] [info] :: Running local variable rename visitor
[NMODL] [info] :: Running cnexp visitor
[NMODL] [info] :: Running C backend code generator
x86_64/corenrn/mod2c/exp2syn.cpp:291:9: error: expected a for, while, or do-while loop to follow '#pragma ivdep'
        #pragma omp simd
        ^
x86_64/corenrn/mod2c/netstim.cpp:659:13: error: expected a for, while, or do-while loop to follow '#pragma ivdep'
            #pragma omp simd
            ^
x86_64/corenrn/mod2c/exp2syn.cpp:325:13: error: expected a for, while, or do-while loop to follow '#pragma ivdep'
            #pragma omp simd
            ^
x86_64/corenrn/mod2c/exp2syn.cpp:377:9: error: expected a for, while, or do-while loop to follow '#pragma ivdep'
        #pragma omp simd
        ^
x86_64/corenrn/mod2c/exp2syn.cpp:416:9: error: expected a for, while, or do-while loop to follow '#pragma ivdep'
        #pragma omp simd
        ^
x86_64/corenrn/mod2c/expsyn.cpp:276:9: error: expected a for, while, or do-while loop to follow '#pragma ivdep'
        #pragma omp simd
        ^
x86_64/corenrn/mod2c/expsyn.cpp:310:13: error: expected a for, while, or do-while loop to follow '#pragma ivdep'
            #pragma omp simd
            ^
x86_64/corenrn/mod2c/expsyn.cpp:349:9: error: expected a for, while, or do-while loop to follow '#pragma ivdep'
        #pragma omp simd
        ^
x86_64/corenrn/mod2c/expsyn.cpp:388:9: error: expected a for, while, or do-while loop to follow '#pragma ivdep'
        #pragma omp simd
        ^

Looking quickly with a simple reproducer:

$ cat foo.cpp
extern int n;
extern void bar();

void foo() {
    #pragma ivdep
    #pragma omp simd
    for(int i =0; i <n; i++) {
        bar();
    }
}

and

$ icx foo.cpp -c -fopenmp
foo.cpp:6:2: error: expected a for, while, or do-while loop to follow '#pragma ivdep'
        #pragma omp simd
        ^
1 error generated.

i.e. #pragma ivdep expects a for loop but we print #pragma omp simd in https://github.com/BlueBrain/nmodl/blob/ce25655088cb082b5c0c9dc9cc9a423739799806/src/codegen/codegen_cpp_visitor.cpp#L1119.

Note that we print ivdep in order to help vectorization when OpenMP is not enabled. We need to handle this better.

iomaganaris commented 1 year ago

I think to fix this issue we can remove the #pragma ivdep and instead print only #pragma omp simd and by default add the compilation flag -fiopenmp-simd in NEURON/CoreNEURON for the Intel compiler (and maybe move the same option for GCC in CMake instead of the spack recipe)