These are chat archives for Fortran-FOSS-Programmers/General-Discussion

12th
Apr 2017
Stefano Zaghi
@szaghi
Apr 12 2017 07:50

@tomedunn and @/all interest (in particular @certik could be helpful...),
I have been successful to wrap some WenOOF facilities by means of ctypes, here is the python-wrapper test: this is already enough, but moving toward the wrapping of the actual interpolator object could be better. However, there are some things that I do not understand, in particular concerning ctypes.

The Fortran wrapped procedures now look like:

  subroutine wenoof_interpolate_c_wrap(S, stencil, interpolation) bind(c, name='wenoof_interpolate_c_wrap')
  !< Interpolate over stencils values by means of WenOOF interpolator.
  integer(C_INT32_T), intent(in), value  :: S                 !< Stencils number/dimension.
  real(C_DOUBLE),     intent(in)         :: stencil(1-S:-1+S) !< Stencil of the interpolation.
  real(C_DOUBLE),     intent(out)        :: interpolation     !< Result of the interpolation.

  call interpolator_c_wrap%interpolate(stencil=stencil, interpolation=interpolation)
  endsubroutine wenoof_interpolate_c_wrap

The current (naive) Python wrapper looks like:

from ctypes import CDLL, c_double, c_int, POINTER
import numpy as np

wenoof = CDLL('./shared/libwenoof.so')
wenoof.wenoof_interpolate_c_wrap.argtypes = [c_int, POINTER(c_double), POINTER(c_double)]

cells_number = 50
x_cell, dx = np.linspace(start=-np.pi, stop=np.pi, num=cells_number + 2 * stencils, endpoint=True, retstep=True)
y_cell = np.sin(x_cell)
y_weno = np.empty(cells_number + 2 * stencils, dtype="double")
interpolation = np.empty(1, dtype="double")
for i, x in enumerate(x_cell):
  if i >= stencils and i < cells_number + stencils:
    wenoof.wenoof_interpolate_c_wrap(stencils,
                                     y_cell[i+1-stencils:].ctypes.data_as(POINTER(c_double)),
                                     interpolation.ctypes.data_as(POINTER(c_double)))
    y_weno[i] = interpolation

The oddities for my limited vision are:

  • I was not able to use y_weno numpy array directly into the wenoof_interpolate_c_wrap calling: I have to pass through the temporary 1-element array interpolation; surely this is due to my ignorance about ctypes, but google does not offer me much insight...
  • I do not understand in details the rationale about data_as(POINTER...), refby and similar of ctypes and the corresponding Fortran exploitation of value attribute; the guide of @certik provides a very clear example, but it does not enter in details.

How do you simplify this workflow? Are the Fortran dummy arguments well defined? How the Python wrapper can be simplified/improved? At the end, how to wrap a class(integrator), allocatableobject or at least a type(integrator_js) concrete instance? I definitely need more documentation about Python-ctypes-Fortran mixing...

Thank you in advance for any hints.

Cheers