libocca / occa

Portable and vendor neutral framework for parallel programming on heterogeneous platforms.
https://libocca.org
MIT License
389 stars 82 forks source link

OKL incorrect macro expansion #750

Open IuriiKobein opened 6 months ago

IuriiKobein commented 6 months ago

Hello, My team currently testing a new OKL transpiler based on clang frontend against different libraries that using OCCA.

We have found the bug in legacy OKL preprocessor. Input :

#define MYSTR my_fn_

inline void my_fn_1() {}
inline void my_fn_2() {}

@directive("#define MYMACRO(idx) MYSTR ## idx")

@kernel void hello_kern() {
    for (int i = 0; i < 10; ++i; @outer) {
        for (int j = 0; j < 10; ++j; @inner) {

            MYMACRO(1)();
            MYMACRO(2)();

        }
    }
}

OKL legacy outputs:

inline void my_fn_1() {}

inline void my_fn_2() {}

extern "C" void hello_kern() {
#pragma omp parallel for
  for (int i = 0; i < 10; ++i) {
    for (int j = 0; j < 10; ++j) {
      my_fn_1();
      my_fn_2();
    }
  }
}

New OKL transpiler output:

inline void my_fn_1() {}

inline void my_fn_2() {}

extern "C" void hello_kern() {
#pragma omp parallel for
  for (int i = 0; i < 10; ++i) {
    for (int j = 0; j < 10; ++j) {
      MYSTR1();
      MYSTR2();
    }
  }

Actually to the latest one is correct according to C preprocessor spec. To archive desire behavior additional level of macro directive is required

define CONCAT(id1, id2) id1##id2

define MYMACRO(idx) CONCAT(MYSTR, idx)