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

How to pass an input array to another subroutine?

junziyang
Beginner
1,734 Views

subroutineA
.......
CALLBVPMS(FCNEQN,FCNJAC,FCNBC,NEQNS,TLEFT,TRIGHT,DTOL,BTOL,MAXIT,NINIT,TINIT,YINIT,LDYINI,NMAX,NFINAL,TFINAL,YFINAL,LDYFIN)

endsubroutineA


subroutineFCNEQN(NEQNS,T,Y,P,DYDT)
......
!common/yy/Y
!REALY(NEQNS)

CALLNEQBF(FCN,N,XGUESS,XSCALE,FSCALE,IPARAM,RPARAM,X,FVEC)
......
endsubroutineFCNEQN

subroutineFCN(N,X,F)
......
!Y will be used in this subroutine
endsubroutineFCN



The code in GREEN issue the following error:
error#6406:Conflictingattributesormultipledeclarationofname.
error#6756:ACOMMONblockdataobjectmustnotbeanautomaticobject.

My Question: How to pass Y to subroutine FCN?

Thanks!

0 Kudos
1 Solution
Jugoslav_Dujic
Valued Contributor II
1,734 Views
Quoting - junziyang

I have also tried the following code:

COMMON /pptr/ pt

REAL, POINTER :: pt

pt=> Y

error #6796: The variable must have the TARGET attribute or be a subobject of an object with the TARGET attribute, or it must have the POINTER attribute.

Since you can't define the storage of Y, using a pointer seems a way to go.

However, your syntax is wrong. You need something like:

[cpp]subroutine FCNEQN(NEQNS, ..., Y, ...)
real, target:: Y(NEQNS)

real, pointer:: pY(:)
common /pptr/ pY
...
pY => Y[/cpp]

View solution in original post

0 Kudos
5 Replies
TimP
Honored Contributor III
1,734 Views
Quoting - junziyang

subroutineA
.......
CALLBVPMS(FCNEQN,FCNJAC,FCNBC,NEQNS,TLEFT,TRIGHT,DTOL,BTOL,MAXIT,NINIT,TINIT,YINIT,LDYINI,NMAX,NFINAL,TFINAL,YFINAL,LDYFIN)

endsubroutineA


subroutineFCNEQN(NEQNS,T,Y,P,DYDT)
......
!common/yy/Y
!REALY(NEQNS)

CALLNEQBF(FCN,N,XGUESS,XSCALE,FSCALE,IPARAM,RPARAM,X,FVEC)
......
endsubroutineFCNEQN

subroutineFCN(N,X,F)
......
!Y will be used in this subroutine
endsubroutineFCN



The code in GREEN issue the following error:
error#6406:Conflictingattributesormultipledeclarationofname.
error#6756:ACOMMONblockdataobjectmustnotbeanautomaticobject.

My Question: How to pass Y to subroutine FCN?

Thanks!

Are you asking more than one question? You could include the COMMON block in the subroutine, or pass a dummy argument (preferably with appropriate IN, OUT, or INOUT). In simple cases, the standard prohibits conflicts where there would be ambiguity between a dummy argument value passed at an earlier stage of execution, and a COMMON block value which is always up to date. In more complicated cases, the standard won't protect you.

0 Kudos
anthonyrichards
New Contributor III
1,734 Views
When displaying this thread, the text reaches beyond the right hand edge of the window and there is no scroll bar. There is noreplyto option at the bottom, but there is reply to thread button at the top, above the window. When I press reply and the edit window opens, there is no cancel button if Ihave second thoughts. Thisforum software appears to have a problem with my browser (IE7). Any more thoughts on how to get it functioningas intended?
0 Kudos
Jugoslav_Dujic
Valued Contributor II
1,734 Views
Quoting - junziyang


subroutineFCNEQN(NEQNS,T,Y,P,DYDT)
......
!common/yy/Y
!REALY(NEQNS)

CALLNEQBF(FCN,N,XGUESS,XSCALE,FSCALE,IPARAM,RPARAM,X,FVEC)
......

endsubroutineFCNEQN


The code in GREEN issue the following error:
error#6406:Conflictingattributesormultipledeclarationofname.
error#6756:ACOMMONblockdataobjectmustnotbeanautomaticobject.

My Question: How to pass Y to subroutine FCN?

Thanks!

You can use COMMON to share Y among different unis. What you cannot do is size the arrays in common dynamically -- NEQNS is a variable, and you cannot use that. It has to be a literal constant or a PARAMETER.

Alternatively, and more flexibly, you can define Y within a MODULE and USE that module in both routines. In that case, Y can be declared ALLOCATABLE, and you can ALLOCATE it to a desired size before use.

Finally, if you can change the source of NEQBF, you can pass Y through. If I recall correctly, it's an IMSL routine, so it's not an option.

0 Kudos
junziyang
Beginner
1,734 Views
Quoting - Jugoslav Dujic

You can use COMMON to share Y among different unis. What you cannot do is size the arrays in common dynamically -- NEQNS is a variable, and you cannot use that. It has to be a literal constant or a PARAMETER.

Alternatively, and more flexibly, you can define Y within a MODULE and USE that module in both routines. In that case, Y can be declared ALLOCATABLE, and you can ALLOCATE it to a desired size before use.

Finally, if you can change the source of NEQBF, you can pass Y through. If I recall correctly, it's an IMSL routine, so it's not an option.

Thank you.

Yes, BVPMS and NEQBFare IMSL routines. The problem is Y isnot difined by me but passed to FCNEQN by BVPMS and its value is changing on each entry. So I cant't put Y in a module.

The fortran code is ina MATLAB Fortran mex file. NEQNS is passedin from MATLAB. IF I define NEQNS a parameter, then I have to change its valuewhen the number of equations changed and remex the programm. It's inconvenient.

According to your advice "not size the array in common", I delete the code "REAL Y(NEQNS), I got the following error:

error #6412: A dummy argument name is invalid in this context.

I have also tried the following code:

COMMON /pptr/ pt

REAL, POINTER :: pt

pt=> Y

error #6796: The variable must have the TARGET attribute or be a subobject of an object with the TARGET attribute, or it must have the POINTER attribute.

0 Kudos
Jugoslav_Dujic
Valued Contributor II
1,735 Views
Quoting - junziyang

I have also tried the following code:

COMMON /pptr/ pt

REAL, POINTER :: pt

pt=> Y

error #6796: The variable must have the TARGET attribute or be a subobject of an object with the TARGET attribute, or it must have the POINTER attribute.

Since you can't define the storage of Y, using a pointer seems a way to go.

However, your syntax is wrong. You need something like:

[cpp]subroutine FCNEQN(NEQNS, ..., Y, ...)
real, target:: Y(NEQNS)

real, pointer:: pY(:)
common /pptr/ pY
...
pY => Y[/cpp]

0 Kudos
Reply