I am trying to create a python interface to a C function with the following structure: (Full code can be found here)
void get_pi_typed (int *type,
double *x,
double *y,
int *len,
int *typeA,
int *typeB,
double *r_low,
double *r,
int *len_r,
int *inds,
double *rc) {
\*DETAILS LEFT OUT
for (i=0;i<*len_r;i++) {
\*DETAILS LEFT OUT
rc[i] = (double)num_cnt/denom_cnt;
}
}
My Python code looks like this:
import numpy as np
import ctypes as ct
# must be a double array, with single dimension that is contiguous
array_1d_int = np.ctypeslib.ndpointer(dtype=np.int32, ndim=1, flags='CONTIGUOUS')
array_1d_double = np.ctypeslib.ndpointer(dtype=np.double, ndim=1, flags='CONTIGUOUS')
# Load the library as _libspfc.
_libspfc = np.ctypeslib.load_library('../src/libspatialfuncs', '.')
_libspfc.get_pi_typed.argtypes = [array_1d_int,\
array_1d_double,\
array_1d_double,\
ct.c_int,\
ct.c_int,\
ct.c_int,\
array_1d_double,\
array_1d_double,\
ct.c_int,\
ct.c_int,\
array_1d_double,\
]
_libspfc.get_pi_typed.restype = None
def getPiTyped(posmat,typeA=-1,typeB=-1,r=np.array([1.]),rLow=None):
"""
Python equivalent to get_pi_typed.
posmat: a matrix with columns type, x and y
typeA: the "from" type that we are interested in, -1 is wildcard
typeB: the "to" type that we are interested i, -1 is wildcard
r: the series of spatial distances wer are interested in
rLow: the low end of each range....0 by default
"""
if not isinstance(r, np.ndarray): #if it is not a 1D numpy array (for ex a scalar or a list), bring it into that shape
r=np.array(r)
r=r.reshape((-1))
if rLow is None:
rLow = np.zeros_like(r)
if not isinstance(rLow, np.ndarray): #if it is not a 1D numpy array (for ex a scalar or a list), bring it into that shape
rLow=np.array(rLow)
rLow=rLow.reshape((-1))
#prepare output array
rc = np.empty_like(r, dtype=np.double)
_libspfc.get_theta_typed(posmat[:,0],posmat[:,1],posmat[:,2],posmat.shape[0],typeA,typeB,rLow,r,r.shape[0],np.arange(1,r.shape[0]+1),rc)
return rc
However, when I try to run the code I get the following error, which seems to be related to the type conversion of the 1st parameter:
x =np.array([[1.,0.,0.],[1.,1.,0.],[2.,0.5,np.sqrt(.75)]])
sf.getPiTyped(x,1,2,1.5)
ArgumentError: argument 1: <type 'exceptions.TypeError'>: Don't know how to convert parameter 1
I tried many variations of argtypes, as well as to convert posmat[:,0]
to int
or int32
via .astype
, however I always get the same error. What am I doing wrong?
EDIT:
According to the 1st comment below I added .ctypes.data
to all array input arguments. The ArgumentError
is now gone. However I get a Segmentation Fault
, very difficult to investigate because python crashes
EDIT2: I tried to make the array column-contiguous
posmat=np.ascontiguousarray(np.asfortranarray(posmat))
but I still get the seg fault