C compiles with g++ but not with Cilk++

C compiles with g++ but not with Cilk++

Imagen de hillelav

My code compiles perfectly with g++. When replacing g++ with cilk++, I get a lot of:

error: Calling Cilk functionF from non-Cilk context G

error: invalid conversion from'void (cilk*)()' to 'void (*)()'

publicaciones de 9 / 0 nuevos
Último envío
Para obtener más información sobre las optimizaciones del compilador, consulte el aviso sobre la optimización.
Imagen de William Leiserson (Intel)

Hi,

Cilk++ functions have different linkage from C++ functions. Although C++ functions can be called directly from Cilk++ functions, you cannot go the other way. In your code, G() is a C++ function, and it cannot call F(), a Cilk++ function.

There are a couple of solutions:

1. If this is a simple test program, you can make _all_ functions Cilk++ by compiling all of the files with the cilk++ compiler. Also, rename main() to cilk_main() which is an indication to the compiler to use cilk_main(), a function with Cilk++ linkage,as your entrypoint (main() is a C function).

2. You can call F() from G() by using cilk::run(). There is some overhead associated with entering Cilk++. It shouldn't be a problem if you're only doing it once. But if you have, e.g., a loop:

G () {
for (int i = 0; i < 1000; ++i) F();
}

then you might consider making G() a Cilk++ function or at least refactor the loop out of G().

3. The _new_ Cilk (Intel Cilk Plus) has better integration with C++ so that the linkage is the same. In Cilk Plus, you can simply call F() from G() without an error. To enter the Beta program you can email Ron Green (ronald.w.green@intel.com).

Imagen de hillelav

The code I compile is actually legacy C code. I only changed the makefile. I compile all the code with cilk++ but it does call some precompiled libraries. Currently there is no Cilk++ functions in the code. I tried to rename main to cilk_main but it did not help.

Imagen de William Leiserson (Intel)

cilk++ assumes all functions are Cilk++ (except those in system headers), so you have to identify other functions as having C or C++ linkage. This is a portability change you have to makegoingfrom C to C++ anyway, if the libraries are compiled by a C compiler.

The libraries that are pre-compiled presumably have header files. You should specify that the functions are C functions in the header files like so:

extern "C" {
void foo ();
void bar ();
/* etc. */
}

The "extern" with a language string indicates to the compiler that it should treat the functions declared (or defined) within as having linkage (which will be reflected in name mangling) of that language. You can do it to the whole header file either within the header or in the .cilk file that includes them. E.g.,

extern "C" {
#include "baz.h"
}

Imagen de Barry Tannenbaum (Intel)

You can avoid having to modify your header files by using the -isystem option instead of -I to specify include directories. The compiler will assume that the default linkage for files in that directory is C++.

- Barry

Imagen de hillelav

I added -isystem . -isystem /usr/include (well, there was no -I previously) in the makefile, but still getting the same errors.

Imagen de William Leiserson (Intel)

What are the error messages you're getting, exactly?

Imagen de hillelav

Multiple of the following:

error: Calling Cilk function 'void cilk G()' from non-Cilk context 'void F()'
invalid conversion from 'void (cilk*)(void*)' to 'void (*)(void*)'

Imagen de William Leiserson (Intel)

Is F() declared or defined within an 'extern "C"' or 'extern "C++"' block? If so, and if you want to keep the linkage of the other functions in that context, you can use 'extern "Cilk++"' within the 'extern "C++"' block to specify Cilk++ linkage for F().

Inicie sesión para dejar un comentario.