Interfacing C+OpenACC and Python: issue

I am trying to call a C function that makes use of OpenACC directives and GPU computing, from inside python using SWIG. The C function in question is called fastregrid. What I want to do is to compile the C code with pgcc and then use it from inside python like:

import fastregrid
fastregrid.regrid(variables etc)

I have done this successfully with a CPU-only, gcc-compiled C function. But I am having issues with my pgcc code. It compiles fine, but when calling the function in python it gives the following error:

~/anaconda3/lib/python3.7/importlib/_bootstrap_external.py in create_module(self, spec)

~/anaconda3/lib/python3.7/importlib/_bootstrap.py in _call_with_frames_removed(f, *args, **kwds)

ImportError: /home/nemmen/codes/mickey/src/_fastregrid.so: undefined symbol: __PGI_CUDA_LOC

During handling of the above exception, another exception occurred:

ImportError Traceback (most recent call last)
in
----> 1 import fastregrid


ImportError: /home/nemmen/codes/mickey/src/_fastregrid.so: undefined symbol: __PGI_CUDA_LOC

So python is complaining about the undefined symbol __PGI_CUDA_LOC.

My Makefile looks like this:

PROGRAM	= fastregrid

CC	= pgcc
CFLAGS	= -acc -fPIC -O2 -Minfo=accel -c

...UNIMPORTANT PARTS OMMITED...

# if the user is running Linux
LFLAGS  = -I$(HOME)/anaconda3/include/python3.$(PYV_MIN)m -I$(HOME)/anaconda3/lib/python3.$(PYV_MIN)/site-packages/numpy/core/include
LDFLAGS= -shared -undefined suppress

all: ${PROGRAM}

${PROGRAM}:	${PROGRAM}.c
	[ -f ./numpy.i ] && echo "numpy.i already here, good" || wget https://raw.githubusercontent.com/numpy/numpy/master/tools/swig/numpy.i

	swig -python -o ${PROGRAM}_wrap.c ${PROGRAM}.i
	$(CC) ${CFLAGS} ${PROGRAM}.c -o ${PROGRAM}.o
	$(CC) ${CFLAGS} ${PROGRAM}_wrap.c -o ${PROGRAM}_wrap.o ${LFLAGS}
	ld ${LDFLAGS} -o _${PROGRAM}.so *.o

This makefile was written based on instructions from swig and has been tested with success with gcc, not pgcc.

Any suggestions of what might be going on or the recommended way of interfacing pgcc code with python?

Hi nemmen,

Try compiling with “-ta=tesla:nordc”.

While we added support for RDC (relocatable device code) in PGI 19.1, I’m assuming you’re using PGI 18.10 so disabling RDC is needed.

Hope this helps,
Mat

Hey, thanks for the help, Mat! I tried your suggestion but now when importing in python it throws another error it is throwing another error:

_fastregrid.so: undefined symbol: __c_bzero

Will keep working on it.

hey, it is working now! Here is what I’ve changed.

Code which was not working

         swig -python -o ${PROGRAM}_wrap.c ${PROGRAM}.i
         pgcc -acc -fPIC -Minfo=accel -c ${PROGRAM}.c -o ${PROGRAM}.o
         pgcc -acc -fPIC -Minfo=accel -c ${PROGRAM}_wrap.c -o ${PROGRAM}_wrap.o ${LFLAGS}
         ld -shared -undefined suppress -o _${PROGRAM}.so *.o

New, fixed code, imports correctly in python

	swig -python -o ${PROGRAM}_wrap.c ${PROGRAM}.i
	pgcc -acc -fPIC -Minfo=accel -c -ta=tesla:nordc ${PROGRAM}.c -o ${PROGRAM}.o
	pgcc -acc -fPIC -Minfo=accel -c -ta=tesla:nordc ${PROGRAM}_wrap.c -o ${PROGRAM}_wrap.o ${LFLAGS}
	pgcc -acc -Minfo=accel -shared -ta=tesla:nordc -o _${PROGRAM}.so *.o

Hi nemmen,

Glad you were able to get things working and see a good speed-up over OpenCL.

The undefined reference is most likely due to you missing the PGI runtime libraries on the “ld” link line. By linking with pgcc instead, these libraries were implicitly included on the link.

If you did want to go back to using ld directly, the easiest thing to do is run “pgcc -acc -Minfo=accel -shared -ta=tesla:nordc -dryrun x.o” and then copy the libraries we include on the link line.

-Mat