Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Embed python into fortran 90

I was looking at the option of embedding python into fortran90 to add python functionality to my existing fortran90 code. I know that it can be done the other way around by extending python with fortran90 using the f2py from numpy. But, i want to keep my super optimized main loop in fortran and add python to do some additional tasks / evaluate further developments before I can do it in fortran, and also to ease up code maintenance. I am looking for answers for the following questions:

1) Is there a library that already exists from which I can embed python into fortran? (I am aware of f2py and it does it the other way around) 2) How do we take care of data transfer from fortran to python and back? 3) How can we have a call back functionality implemented? (Let me describe the scenario a bit....I have my main_fortran program in Fortran, that call Func1_Python module in python. Now, from this Func1_Python, I want to call another function...say Func2_Fortran in fortran) 4) What would be the impact of embedding the interpreter of python inside fortran in terms of performance....like loading time, running time, sending data (a large array in double precision) across etc.

Thanks a lot in advance for your help!!

Edit1: I want to set the direction of the discussion right by adding some more information about the work I am doing. I am into scientific computing stuff. So, I would be working a lot on huge arrays / matrices in double precision and doing floating point operations. So, there are very few options other than fortran really to do the work for me. The reason i want to include python into my code is that I can use NumPy for doing some basic computations if necessary and extend the capabilities of the code with minimal effort. For example, I can use several libraries available to link between python and some other package (say OpenFoam using PyFoam library).

like image 478
Ravi Avatar asked Jun 12 '13 21:06

Ravi


2 Answers

I have developed the library Forpy that allows you to use Python in Fortran (embedding). It uses Fortran C interoperability to call Python C API functions.

While I agree that extending (using Fortran in Python) is often preferable, embedding has its uses:

  • Large, existing Fortran codes might need a substantial amount of refactoring before they can be used from Python - here embedding can save development time
  • Replacing a part of an existing code with a Python implementation
  • Temporarily embedding Python to experiment with a given Fortran code: for example to test alternative algorithms or to extract intermediary results

Besides embedding, Forpy also supports extending Python. With Forpy you can write a Python extension module entirely in Fortran. An advantage to existing tools such as f2py is that you can use Python datatypes (e. g. to write a function that takes a Python list as argument or a function that returns a Python dict).

Working with existing, possibly legacy, Fortran codes is often very challenging and I think that developers should have tools at their disposal both for embedding and extending Python.

like image 187
ylikx Avatar answered Sep 18 '22 12:09

ylikx


1. Don't do it

I know that you're wanting to add Python code inside a Fortan program, instead of having a Python program with Fortran extensions. My first piece of advice is to not do this. Fortran is faster than Python at array arithmetic, but Python is easier to write than Fortran, it's easier to extend Python code with OOP techniques, and Python may have access to libraries that are important to you. You mention having a super-optimized main loop in Fortran; Fortran is great for super-optimized inner loops. The logic for passing a Fortran array around in a Python program with Numpy is much more straightforward than what you would have to do to correctly handle a Python object in Fortran.

When I start a scientific computing project from scratch, I always write first in Python, identify performance bottlenecks, and translate those into Fortran. Being able to test faster Fortran code against validated Python code makes it easier to show that the code is working correctly.

Since you have existing code, extending the Python code with a module made in Fortran will require refactoring, but this process should be straightforward. Separate the initialization code from the main loop, break the loop into logical pieces, wrap each of these routines in a Python function, and then your main Python code can call the Fortran subroutines and interleave these with Python functions as appropriate. In this process, you may be able to preserve a lot of the optimizations you have in your main loop in Fortran. F2PY is a reasonably standard tool for this, so it won't be tough to find people who can help you with whatever problems will arise.

2. System calls

If you absolutely must have Fortran code calling Python code, instead of the other way around, the simplest way to do this is to just have the Fortran code write some data to disk, and run the Python code with a SYSTEM or EXECUTE_COMMAND_LINE. If you use EXECUTE_COMMAND_LINE, you can have the Python code output its result to stdout, and the Fortran code can read it as character data; if you have a lot of output (e.g., a big matrix), it would make more sense for the Python code to output a file that the Fortran code then reads. Disk read/write overhead could wind up being prohibitively significant for this. Also, you would have to write Fortran code to output your data, Python code to read it, Python code to output it again, and Fortran code to re-input the data. This code should be straightforward to write and test, but keeping these four parts in sync as you edit the code may turn into a headache.

(This approach is tried in this Stack Overflow question)

3. Embedding Python in C in Fortran

There is no way that I know of to directly pass a Python object in memory to Fortran. However, Fortran code can call C code, and C code can have Python embedded in it. (See the Python tutorial on extending and embedding.) In general, extending Python (like I recommend in point 1) is preferable to embedding it in C/C++. (See Extending Vs. Embedding: There is Only One Correct Decision.) Getting this to work will be a nightmare, because any communication problems between Python and Fortran could happen between Python and C, or between C and Fortran. I don't know if anyone is actually embedding Python in C in Fortran, and so getting help will be difficult.

like image 39
Alex Szatmary Avatar answered Sep 19 '22 12:09

Alex Szatmary