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

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

Marr__David
Einsteiger
1.124Aufrufe
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 Lösung
Steven_L_Intel1
Mitarbeiter
1.124Aufrufe
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.

Lösung in ursprünglichem Beitrag anzeigen

5 Antworten
Andrew_Smith
Geschätzter Beitragender I
1.124Aufrufe
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?
Marr__David
Einsteiger
1.124Aufrufe
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?
Steven_L_Intel1
Mitarbeiter
1.125Aufrufe
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.
jimdempseyatthecove
Geehrter Beitragender III
1.124Aufrufe


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

Marr__David
Einsteiger
1.124Aufrufe
POINTER via a MODULE worked great - thanks to everyone for your help!
Antworten