Skip to content

Instantly share code, notes, and snippets.

@GroupTheorist12
Created May 5, 2021 23:49
Show Gist options
  • Save GroupTheorist12/48a2cecfc7aa7d5251d6b933754ac9bb to your computer and use it in GitHub Desktop.
Save GroupTheorist12/48a2cecfc7aa7d5251d6b933754ac9bb to your computer and use it in GitHub Desktop.

Calling Fortran LAPACK Subroutines from C#

Introduction

LAPACK is written in Fortran 90 and provides routines for solving systems of simultaneous linear equations, least-squares solutions of linear systems of equations, eigenvalue problems, and singular value problems. The associated matrix factorizations (LU, Cholesky, QR, SVD, Schur, generalized Schur) are also provided, as are related computations such as reordering of the Schur factorizations and estimating condition numbers. Dense and banded matrices are handled, but not general sparse matrices. In all areas, similar functionality is provided for real and complex matrices, in both single and double precision.

I have been writing code professionally in C# since around 2001 and I love the language. I also love math and the thought of recreating algorithms in C# that somebody had already coded seemed like a big waste of time.

I stumbled upon LAPACK since I was working on a mapping app that needed to solve thousands of simultaneous equations. I figured why not use code that had been battle tested for years.

One problem it was written in Fortran. So I boned up on Fortran using the gfortran compiler on Linux and used the C/PInvoke feature of C#. (See my first foray at the git below:) to call Fortran routines which use the iso_c_binding so that the subroutines can be called by name from c (Fortran name mangles subroutines by default)

Modern Fortran

From Fortran Wiki:

iso_c_binding is a standard intrinsic module which defines named constants, types, and procedures for C interoperability.

iso_c_binding

The code in this git exploits this interoperability to call Fortran routines from C# using P/Invoke (Platform Invocation Services). Below is a Fortran subroutine we wish to call:

Example Fortran Subroutine with iso_c_binding

https://gist.github.com/5eb3cd43a409391bdced3ea1b909646c

This example can solve a series of simultaneous equations.

AX = B

Below is the C# code which will call the Fortran subroutine.

Example P/Invoke C# code to call Fortran Subroutine.

undefined

Setting up your environment

The assumption is that you have gfortran, make and the .NET 5.0 SDK installed either on Linux or on Windows in the WSL Linux subsystem. If not, directions for Ubuntu are given below.

Install gfortran

https://gist.github.com/08e34dcfd2307925ccafc4277ae036cf

Install make

https://gist.github.com/3e71a2c24b9eaeddd7cb2e4fc27095fd

Install .NET 5.0 SDK

Install the .NET SDK

Example C# console project

Let's walk through the steps to create a C# .NET 5.0 project to call the above Fortran subroutine.

Create console app using dotnet cli.

Open a terminal window and enter the following (I am doing it from my HOME directory):

https://gist.github.com/f70c0480bac259cd4fc2d0f6bd4f5ac6

Change directories to CSharpCallingLaPack

https://gist.github.com/380007b99c59b63afdba5d11fc689eb8

Edit Program.cs

With your trusty editor (I am using VSCode) edit the Program.cs and cut and paste the code from below into it:

https://gist.github.com/5dfbcdd3a6d6655391baed579fa34bda

Copy LAPACK libraries to your usr/local/lib directory

I have provided the libraries on my github site so you can just wget them into your /usr/local/lib directory.

Enter the following into a terminal window.

undefined

Create Fortran Source File lapack_module.f90

Change back to the CSharpCallingLaPack directory and with your favorite editor cut and paste the Fortran code below and save it.

https://gist.github.com/53f067696811d69263ad8038ebe8427d

Create Fortran Shared Library

Enter the following in your terminal window to create the Fortran shared library.

https://gist.github.com/d5085cf4de3144e07d1df1fb9ad4fecd

Run the dotnet build command

Enter the following in your terminal window to build the C# project and copy the Fortran module

https://gist.github.com/90d9a40c9291a008572751b92f448641

Run the app

Run the following from the terminal window to run the app.

https://gist.github.com/ad951ab2b0a526027b1806ebbbe336fc

You should see the following output:

https://gist.github.com/1df0aaca0b6eb5a219b91df6dd201fe4

Final Remarks

I was surprised by how much I enjoyed working with Fortran and the huge amount of mathematical library code that is written in it. The cool thing about Fortran is that optimizing compilers (Intel) can really speed up operations that involve huge arrays and matrices.

The source code for the above project and other projects I am working on can be found at:

Thanks for reading!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment