Search code examples
pythonarraysnumpypypypython-cffi

Python PYPY Cffi with Numpy array


I'm trying to learn to use cffi, but I'm fairly new to c, so its a bit tricky. I'm practicing with a simple function to compute the sum of an array of doubles. Strangely my sum function is not giving the correct output. Can anyone see why? Am I handling the array correctly? I don't understand why I have to cast numpy arrays as pointers.

from cffi import FFI
import numpy as np

ffi = FFI()
ffi.cdef("""
double sum(double[], int);
""")
C = ffi.verify("""
double sum(double numbers[],int num_elements){
   int i, sum=0.0;
   for (i=0; i<num_elements; i++)
   {
     sum = sum + numbers[i];
   }
   return(sum);
}
""")
numbers = np.random.gamma(1,1,100)
print 'numpy', sum(numbers)

numbers_p = ffi.cast('double *',numbers.ctypes.data)
sm = C.sum(numbers_p, len(numbers))

print 'cffi', sm

output:

numpy 119.436940423
cffi 80.0

Solution

  • Notice how the result is a nice flat integer.

    Your C code is wrong. You need to specify the correct type for sum.

    Suggested changes:

    C = ffi.verify("""
    double sum(double numbers[],int num_elements){
       int i;
       double sum=0.0; //Now it has the correct data type.
       for (i=0; i<num_elements; i++)
       {
         sum = sum + numbers[i];
       }
       return(sum);
    }
    """)
    

    With that correction:

    >>> sm = C.sum(numbers_p, len(numbers))
    >>> sm
    98.53688973595715
    >>> sum(numbers)
    98.536889735957146
    >>> sum(numbers) == sm
    True