views:

99

answers:

2

My question is similar to this one here, but there are some difference.

I have a fortran dll as the backend, and a C# exe as the front end. I use PInvoke to pass data between them.

There are 22 parameters between the C# and the fortran code. And some of them are integer, double, pointers ( C# pointers), array and whatnot. So it's a mix of types.

The problem is that for small arrays, the code works fine, however, for large arrays (~10k element size), a stackoverflowexception was thrown right after my code enters into the managed code.

Edit: I've managed to scale down everything. Here's the fortran code:

  subroutine chartest(maxncv,ldv)

  !DEC$ ATTRIBUTES DLLEXPORT::chartest
  !DEC$ ATTRIBUTES ALIAS:'chartest'::chartest
   !DEC$ ATTRIBUTES VALUE :: maxncv,ldv

 &    

   integer, intent(in)  :: maxncv, ldv

  Double precision
 &                  v(ldv,maxncv),d(maxncv,2)

   print *, 'hello'

  end

And here's my C# declaration:

    public static extern void chartest(

       [MarshalAs(UnmanagedType.I4)] int maxncv,
          [MarshalAs(UnmanagedType.I4)] int ldv


   );

If I call chartest(546, 547), I would get a stackoverflowexception.

546*547=298662, that doesn't seem like a lot of element, no?

A: 

I am rather puzzled by this, but some googling seems to indicate that it is not possible to "easily" change the stack size in a managed app. It could be my lack of knowledge prevents me from understanding why that is not important. But it seems that you can grow the stack size with a utility called editbin.exe if it is called from your main thread. If you make the call on a separate thread that you create, you can specify the stack size. This blog post talks about it.

Mark Wilkins
+2  A: 

You don't mention what you're compiling your Fortran with, but it's obvious that when you allocate the array, that memory is being allocated on the stack, which is a very bad thing. .NET assumes that most of the stuff that will end up on the stack is going to be small, like object references or integers, so it defaults to 1 MB stack size.

Your example of 298662 doubles (each of which is probably 8 or 10 bytes) is in the realm of 2-3 MB, which exceeds the 1MB stack size.

I found a reference to an option for the Intel Fortran compiler:

http://software.intel.com/en-us/forums/showthread.php?t=53881

It says you can avoid allocating arrays on the stack by passing /heap-arrays to the compiler. I would hope other Fortran compilers would have something similar, or use heap arrays by default.

Bryce Wagner