C Sharp and pgfortran interoperability

Hello, I’m trying to call cuda fortran code from C Sharp.
Here what I’ve got:

Fortran library (f.cuf):

FUNCTION TSAT11(P) 
!DEC$ ATTRIBUTES ALIAS:'TSAT11' :: TSAT11
!DEC$ ATTRIBUTES DLLEXPORT :: TSAT11
!DEC$ ATTRIBUTES VALUE :: P
REAL, INTENT(IN) :: P   
REAL :: TSAT11
    ! Examle calculation
    TSAT11 = P - 273.15
RETURN 
END FUNCTION

Compiled with PGI Bash (pgfortran is 12.5-0 32 bit on Windows):

PGI$ pgfortran -c -Bdynamic f.cuf
PGI$ pgfortran -Mmakedll -Bdynamic f.obj -o fortran.dll
   Creating library fortran.lib and object fortran.exp

C Sharp code:

class Program
{
    [DllImport("fortran.dll")]
    static extern float TSAT11(float P);

    static void Main(string[] args)
    {
        float p = 300f;
        float t = TSAT11(p);
        // should return 26.8500061
    } 
 }

After run it’s showing next error:

An unhandled exception of type 'System.DllNotFoundException' occurred in riemannCsharp.exe

Additional information: Unable to load DLL 'fortran.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)

Tried google, and found that this error will show even when dll located in same directory (you need all dependent dll’s). So I’ve installed Dependency Walker: http://www.dependencywalker.com/
And it shows me that fortran.dll depends on pgc.dll, pgf90.dll, pgf90_rpm1.dll, pgftnrtl.dll. I copied them to fortran.dll location, run again and it’s okay.

So, question is: Is there any way to compile all needed dll’s into one single dll that will contain all dependencies and methods needed to run properly?

Hi Brute11k,

Sorry, but I’m not really sure. Though, in doing a web search I came across the following link indicating that it may be possible.

Note that directory containing the run time DLLs just need need to be in your PATH and don’t need to copied to the local directory.

  • MAt

Hi there, Mat! Thanks for your answer.

First, I wanted to make CUDA fortran subroutine executed by C# call and result value returned as array to C# (then I could draw some plots with the help of ZedGraph). I solved this problem using files (input.dat/output.dat). All I need to do now is use Process class:

Process CUDAProcess = new Process();
CUDAProcess.StartInfo.FileName = "cuda.exe";
CUDAProcess.StartInfo.CreateNoWindow = true;
CUDAProcess.StartInfo.UseShellExecute = false;
CUDAProcess.StartInfo.RedirectStandardOutput = true;
CUDAProcess.Start();
//CUDAProcess.StandardOutput.ReadToEnd();
CUDAProcess.WaitForExit();

This is probably not good solution because you have to access HDD, but I have not so much time here and I’m happy with it for now.

Second (and this is already offtopic), I really want to make executable that didn’t require any libraries installed on another PC, except NVIDIA drivers and CUDA API (which comes with drivers I guess).

I tried compile with -Bstatic flag:

pgf90 -Bstatic -m32 project.cuf a.obj

And hopefully it should work (so far tested with one machine). The only thing it’s needed is cudart32_40_17.dll.

Thank for your time and hopefully I’ll get to this problem later.

And hopefully it should work (so far tested with one machine). The only thing it’s needed is cudart32_40_17.dll

Depending upon the system, you may need to install the Microsoft C run time libs (vcredist_x86.exe). If the exe fails to run or you get a “side by side” error, this is the most likely cause.

  • Mat