Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28469 Discussions

Getting large array into common block when calling an in-process server com dll

Marr__David
Beginner
419 Views
Hello, I am migrating some legacy fortran code into a Fortran (Intel v12) com dll in-process server. I am calling this com dll from C# (VS 2010) and passing a few large arrays to the com dll by reference. Within the fortran com dll, the existing code contains few large arrays located in the common block which are defined/located in a header file. I would like to pass these arrays to the com dll by reference (no problem there) and "move" them into the common block for access by all functions/subroutine within my com dll fortran code. Currently I can only do this by setting the common block array = the array passed to the com dll when it is called, but this takes longer than desired. Is there a way to pass these arrays into the common block of my com dll when it is called without creating an additional (and unnecessary) copy? The goal is to reduce runtime and creating copies of the arrays is significantly increasing the time for my com dll to finish its task. I have tried "pointer" and "equivalence" with no luck although I am still fairly new to the com dll world.
Thanks!
0 Kudos
1 Solution
Steven_L_Intel1
Employee
419 Views
You cannot "convert" an argument passed in to a COMMON. But if you want a variable that is shared, you can have a POINTER in a MODULE and do a pointer assignment to the dummy argument (with the TARGET attribute). As long as you don't return back to C# it will still be valid.

View solution in original post

0 Kudos
5 Replies
Andrew_Smith
Valued Contributor I
419 Views
Are there no issues with the structure and fomat of data arrays in C# compared to Intel Fortran? It is not something I could comment on. But since you say copying works then I would think the pointer option should work too. What error did you get?
0 Kudos
Marr__David
Beginner
419 Views
My conflict there is that pointers require a deferred-shape array whereas the COMMON block requires a defined array size (via the error when trying toaccess the array"This COMMON scalar or array is invalid in this context"). Is there a workaround for this catch 22 use of pointer in my application?
0 Kudos
Steven_L_Intel1
Employee
420 Views
You cannot "convert" an argument passed in to a COMMON. But if you want a variable that is shared, you can have a POINTER in a MODULE and do a pointer assignment to the dummy argument (with the TARGET attribute). As long as you don't return back to C# it will still be valid.
0 Kudos
jimdempseyatthecove
Honored Contributor III
419 Views


real(4), pointer :: common1Dreal(:)
real(8), pointer :: common1Ddouble(:)

real(4), pointer :: common2Dreal(:,:)
real(8), pointer :: common2Ddouble(:,:)
...

Then depending on the call arguments, initialize the proper pointer (and nullify the other pointers to catch bugs).

The problem is with the variable rank requirements.

You can create a user type

type argType_t
sequence
integer :: argType
union
map
real(4), pointer :: r1D(:)
end map
map
real(8), pointer :: d1D(:)
end map
map
real(4), pointer :: r2D(:,:)
end map
map
real(8), pointer :: d2D(:,:)
end map
...
end union
end type argType_t

and in common

type(argType) :: arg1, arg2, arg3, ...

Using the union will conserve memory HOWEVER using seperate and nullified pointers will catch programming bugs.

Jim Dempsey

0 Kudos
Marr__David
Beginner
419 Views
POINTER via a MODULE worked great - thanks to everyone for your help!
0 Kudos
Reply