From: Johnson, S. R. <joh...@or...> - 2017-05-03 11:49:10
|
Awesome! The overhead should be minimal, since the wrapper function is essentially a passthrough. For example, the C++ declaration template<class T> void sort(T* arr, int count); with the SWIG code %apply (SWIGTYPE* ARRAY, int SIZE) { (TYPE* arr, int count) } %template(sort) sort< TYPE >; turns into the wrapper code SWIGEXPORT void swigc_sort__SWIG_2(float* farg1, int* farg2) { float *arg1 = (float *) 0 ; int arg2 ; arg1 = farg1; arg2 = *farg2; sort< float >(arg1,arg2); } which becomes the assembly (GCC 5.2 with -O2) _swigc_sort__SWIG_2: movl (%rsi), %esi # *farg2_3(D), jmp __Z4sortIfEvPT_i # which I suspect even a linker can basically inline. The corresponding Fortran wrapper code (with "sort" templated for integers and doubles as well) is: <SNIP> interface sort module procedure :: sort__SWIG_1, sort__SWIG_2, sort__SWIG_3 end interface private interface <SNIP> subroutine swigc_sort__SWIG_2(farg1, farg2) & bind(C, name="swigc_sort__SWIG_2") use, intrinsic :: ISO_C_BINDING real(C_FLOAT), dimension(*), intent(inout) :: farg1 integer(C_INT), intent(in) :: farg2 end subroutine <SNIP> contains subroutine sort__SWIG_2(arr) use, intrinsic :: ISO_C_BINDING real(C_FLOAT), dimension(:), intent(inout) :: arr call swigc_sort__SWIG_2(arr, size(arr)) end subroutine <SNIP> so you can call it from the Fortran simply as use algorithm, only : sort real(C_FLOAT), dimension(4) :: test_real = (/ 0.1, 1.9, -2.0, 4.0 /) call sort(test_real) Here at ORNL we have a collection of nuclear reactor analysis codes called SCALE, which has traditionally been Fortran and now is a blend of that language and C++. Till now they've been using a limited set of custom wrapping scripts to interface the two, but this should give them an even better way to couple them. I suspect it will be the same at NIST. We have got the typemap for generating wrappers to C++ functions that accept function pointers, so (although you'll have to make the correct "bind" declaration yourself for your fortran function) I think callbacks work in our current implementation. It's a requirement for our overall project so we'll get it working for sure. The one major hole in our implementation so far is using the assignment operator for classes on the fortran side, because of the lack of destructors and copy constructors in Fortran. My next task will be to improve handling of that stuff. Any C++11 features supported by SWIG should be supported by the Fortran language. The main project I work on is C++11 with Python wrappers generated from SWIG. Unfortunately we usually keep the C++11 out of those header files that are wrapped because of the limited support and for backward compatibility. Best, Seth -- Seth R. Johnson, Ph.D. R&D Staff Member, Monte Carlo Methods and Development Oak Ridge National Laboratory 865.574.7384 On May 2, 2017, at 23:44, Ian Bell <ian...@gm...<mailto:ian...@gm...>> wrote: Seth, Can I just say how super excited I am about this? In my day job at NIST (buddies in the federal gov) I work on a large monolithic FORTRAN codebase, and I'm trying to push us, slowly, towards C++. This swig interface seems totally fantastic and a great way to make baby steps in that direction. That raises a couple of questions: 1) Have you profiled? How punitive is the call overhead into C++ from fortran? Our code is pretty computationally constrained. Rough estimates for class instantiation, etc. 2) Have you investigated callback functions callable from Fortran into C++? I can imagine that might be rather painful. 3) What about C++11 features? I'm mostly python <-> C++11 programming now, and pybind11 does a super amazing job of interfacing C++11/C++14 and python. I'm sure with the limitations of FORTRAN, getting that far will be difficult/impossible, but I'm curious to hear how far you plan to push this. Best, Ian |