ginkgo icon indicating copy to clipboard operation
ginkgo copied to clipboard

Adding Python, Fortran(?) bindings

Open tcojean opened this issue 6 years ago • 4 comments

I learned yesterday of frameworks which generate bindings for other languages automatically from C++ code, here are some examples:

  • cppyy, which is specific to generating python bindings it seems. There was at least one advanced C++ user of this framework yesterday at the SIAM CSE conference.
  • SWIG this framework seems more generic and able to produce code for Fortran, python and a lot of other languages (from C++). This seems to be used by Trilinos for creating fortran bindings.

It would be interesting to look at the capacities of both of these framework, if there is anything important missing or problematic to generate bindings for Ginkgo automatically through these frameworks, and maybe try them out on one of Ginkgo's classes.

tcojean avatar Feb 26 '19 17:02 tcojean

The SWIG-Fortran talk from ORNL was quite interesting.

  • We of course need explicit instantiations for everything, and as far as I could see, we give each explicit instantiation a unique C/Fortran name, almost like name-mangling. I asked whether we can automate the naming scheme and the answer seems to be 'yes'.
  • I didn't see an example where a templated class is wrapped, so I'm not sure how complicated it is, but they say it's supported. I think a class template instantiation is mapped to a C struct and Fortran module.
  • I asked whether they can handle smart pointers, and indeed they have a system to do that, though no examples were shown in the talk itself. I didn't have time enquire about the depth of support - does reference counting work in case of shared_ptr, say? It's not clear, but at least it seems to be on their agenda.
  • I may be wrong on this, but I don't expect automatic RAII support in general
  • As I had expected, it does go via C, and uses Fortran 2003 iso_c_binding. So we can use it generate both C and Fortran interfaces.

I think this should be the first thing we look at if we decide to have a C/Fortran wrapper.

Slaedr avatar May 14 '21 08:05 Slaedr

I also paste the cppyy first try here it almost follows the simple solver but only uses iterations as criterion. When I use it, it sometimes require you do the correct thing in the beginning like include or load library otherwise need to reboot the notebook. And do not have consistent way to handle shared pointer. sometimes needs .__smartptr__ but sometime can not.

import cppyy
cppyy.add_include_path('/home/mike/cpypy/ginkgo/include')
cppyy.include('ginkgo/ginkgo.hpp')
cppyy.load_library('libginkgo')
from cppyy.gbl import gko
from cppyy.gbl.std import ifstream

omp = gko.OmpExecutor.create()
csr = gko.matrix.Csr['double', 'int']
A = gko.read[csr](ifstream("ginkgo/examples/simple-solver/data/A.mtx"), omp.__smartptr__())
B = gko.share(cppyy.gbl.std.move(A.__smartptr__()))
dense = gko.matrix.Dense['double']
x = gko.read[dense](ifstream("ginkgo/examples/simple-solver/data/x0.mtx"), omp.__smartptr__())
b = gko.read[dense](ifstream("ginkgo/examples/simple-solver/data/b.mtx"), omp.__smartptr__())
iters = gko.stop.Iteration.build().with_max_iters(20).on(omp)
iters_s = gko.share(cppyy.gbl.std.move(iters.__smartptr__()))
solver_gen = gko.solver.Cg['double'].build().with_criteria(iters_s.__smartptr__()).on(omp)
solver = solver_gen.generate(B.__smartptr__())
solver.apply(b, x)

yhmtsai avatar May 17 '21 20:05 yhmtsai

@yhmtsai That looks really good, except for the __smartptr__. Ideally in a dynamically typed garbage collected language like Python, there should be a way to handle smart pointers transparently. It looks like it creates a 'dictionary' of classes for C++ templates, which I think is nice.

Is it easy to use other executors like cuda as well?

Slaedr avatar May 18 '21 17:05 Slaedr

Also the example with Resource manager (to avoid the creation of the LinOp image )

yhmtsai avatar Nov 12 '21 11:11 yhmtsai