Last active
March 14, 2018 09:31
-
-
Save webstory/9281cd4e9df92e2de302508c76252889 to your computer and use it in GitHub Desktop.
Python ffi
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* filename: diffusion.c | |
* compile: | |
* gcc -O3 -std=gnu99 -c diffusion.c | |
* gcc -shared -o diffusion.so diffusion.o | |
* | |
* .so file place /usr/lib or /usr/local/lib or set LD_LIBRARY_PATH for custom location | |
*/ | |
void evolve(int w, int h, double **in, double **out, double D, double dt) { | |
int i, j; | |
double laplacian; | |
for(i = 1; i < h; i++) { | |
for(j = 1; j < w; j++) { | |
laplacian = in[i+1][j] + in[i-1][j] + in[i][j+1] + in[i][j-1] - 4 * in[i][j]; | |
out[i][j] = in[i][j] + D * dt * laplacian; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ffi = FFI() | |
ffi.cdef(r'''void evolve(int Nx, int Ny, double **in, double **out, double D, double dt);''') | |
lib = ffi.verify(r''' | |
void evolve(int Nx, int Ny, double in[][Ny], double out[][Ny], double D, double dt) { | |
int i, j; | |
double laplacian; | |
for(i = 1; i < h; i++) { | |
for(j = 1; j < w; j++) { | |
laplacian = in[i+1][j] + in[i-1][j] + in[i][j+1] + in[i][j-1] - 4 * in[i][j]; | |
out[i][j] = in[i][j] + D * dt * laplacian; | |
} | |
} | |
} | |
''', extra_compile_args=["-O3",]) # JIT compile | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# use cffi instead! | |
import ctypes | |
grid_shape = (512, 512) | |
_diffusion = ctypes.CDLL("diffusion.so") | |
TYPE_INT = ctypes.c_int | |
TYPE_DOUBLE = ctypes.c_double | |
TYPE_DOUBLE_SS = ctypes.POINTER(ctypes.POINTER(ctypes.c_double)) | |
# void evolve(int, int, double**, double**, double, double) | |
_diffusion.evolve.argtypes = [TYPE_INT, TYPE_INT, TYPE_DOUBLE_SS, TYPE_DOUBLE_SS, TYPE_DOUBLE, TYPE_DOUBLE] | |
_diffusion.evolve.restype = None | |
def evolve(grid, out, dt, D=1.0): | |
cX = TYPE_INT(grid_shape[0]) | |
cY = TYPE_INT(grid_shape[1]) | |
cdt = TYPE_DOUBLE(dt) | |
cD = TYPE_DOUBLE(D) | |
pointer_grid = grid.ctypes.data_ss(TYPE_DOUBLE_SS) # numpy array | |
pointer_out = out.ctypes.data_as(TYPE_DOUBLE_SS) # numpy array | |
_diffusion.evolve(cX, cY, pointer_grid, pointer_out, cD, cdt) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from cffi import FFI | |
ffi = FFI() | |
ffi.cdef(r'''void evolve(int w, int h, double **in, double **out, double D, double dt);''') | |
lib = ffi.dlopen("diffusion.so") | |
grid_shape = (512, 512) | |
def evolve(grid, dt, out, D=1.0): | |
X, Y = grid_shape | |
pointer_grid = ffi.cast('double**', grid.ctypes.data) | |
pointer_out = ffi.cast('double**' , out.ctypes.data) | |
lib.evolve(X, Y, pointer_grid, pointer_out, D, dt) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Is this work as-is? | |
from cffi import FFI | |
ffi = FFI() | |
ffi.cdef(r''' | |
struct Point { | |
double x; | |
double y; | |
...; | |
}; | |
struct Point do_calculation(); | |
''') | |
lib = ffi.verify(r''' | |
#include "complecated.h" | |
''') | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment