Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29612 ディスカッション

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

Marr__David
ビギナー
1,822件の閲覧回数
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 件の賞賛
1 解決策
Steven_L_Intel1
従業員
1,822件の閲覧回数
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.

元の投稿で解決策を見る

5 返答(返信)
Andrew_Smith
高評価コントリビューター I
1,822件の閲覧回数
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
ビギナー
1,822件の閲覧回数
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
従業員
1,823件の閲覧回数
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
名誉コントリビューター III
1,822件の閲覧回数


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
ビギナー
1,822件の閲覧回数
POINTER via a MODULE worked great - thanks to everyone for your help!
返信