Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.

MSFLIB and DFLIB

thomasglallen
Beginner
8,282 Views

I have some legacy code that uses MSFLIB and DFLIB, which apparently came from COMPAQ fortran.  When I get to the llinking, I get "error LNK2019: unresolved external symbol _f_setmessageqq referenced in the a routine".  I know that I'm using, in the routine, SETMESSAGEQQ(...), and that is the problem.  It either comes from MSLIB or DFLIB, don't know.  I get no error with the statements USE MSLIB and USE DFLIB in the fortran code, so does someone have a listing of intel  statements that are equivalent to the legacy statements in MSLIB and DFLIB.  I've searched and can't find any reference to the routines found in these libraries. Thanks.

Tom

0 Kudos
51 Replies
thomasglallen
Beginner
2,406 Views
As I’m going through this code that I mentioned earlier, I’ve come up against the following error (tried a variety of things but can’t seem to resolve it): Test.f(648): error #6401: The attributes of this name conflict with those made accessible by a USE statement. [SI] EQUIVALENCE (X2(1),SI(1)), (Y2(1),ALP(1)), (Z2(1),BET(1)) -------------------------^ Test.f(648): error #6401: The attributes of this name conflict with those made accessible by a USE statement. [ALP] EQUIVALENCE (X2(1),SI(1)), (Y2(1),ALP(1)), (Z2(1),BET(1)) ----------------------------------------^ Test.f(648): error #6401: The attributes of this name conflict with those made accessible by a USE s tatement. [BET] EQUIVALENCE (X2(1),SI(1)), (Y2(1),ALP(1)), (Z2(1),BET(1)) --------------------------------------------------------^ compilation aborted for Test.f (code 1) I have the following module that I’m using as a USE statement (I call it DATA_MOD): module DATA_MOD IMPLICIT NONE REAL(8), ALLOCATABLE::X(:),Y(:),Z(:),SI(:), BI(:), ALP(:), & BET(:),SALP(:),T2X(:),T2Y(:), T2Z(:) REAL(8)::CAB,SAB INTEGER(8), ALLOCATABLE::ICON1(:),ICON2(:),ITAG(:),ICONX(:) INTEGER(8)::IPSYM,LD,N1,N2,N,NP,M1,M2,M,MP END module DATA_MOD This substitutes the COMMON block named /DATA/: COMMON /DATA/ X(MAXSEG),Y(MAXSEG),Z(MAXSEG),SI(MAXSEG),BI(MAXSEG), &ALP(MAXSEG),BET(MAXSEG),SALP(MAXSEG),T2X(MAXSEG),T2Y(MAXSEG), &T2Z(MAXSEG),ICON1(MAXSEG),ICON2(MAXSEG),ITAG(MAXSEG), &ICONX(MAXSEG),IPSYM,LD,N1,N2,N,NP,M1,M2,M,MP . Now, Main (where the Program name is) is where I allocated these values as follows: ALLOCATE (X(MAXSEG),Y(MAXSEG),Z(MAXSEG),SI(MAXSEG),BI(MAXSEG), &ALP(MAXSEG),BET(MAXSEG),SALP(MAXSEG),T2X(MAXSEG),T2Y(MAXSEG), &T2Z(MAXSEG),ICON1(MAXSEG),ICON2(MAXSEG),ITAG(MAXSEG), &ICONX(MAXSEG)) Where the value of MAXSEG is defined in a PARAMETER statement as an include file (the USE is placed before the include statement). The subroutine the error is occuring is in this routine: SUBROUTINE CATNRY(XW1,YW1,ZW1,XW2,YW2,ZW2,RAD,ICT,RHMP,ZMP,NS,ITG) USE DATA_MOD INCLUDE 'NECPAR.INC' IMPLICIT REAL*8 (A-H,O-Z) ! COMMON /DATA/ X(MAXSEG),Y(MAXSEG),Z(MAXSEG),SI(MAXSEG),BI(MAXSEG), ! &ALP(MAXSEG),BET(MAXSEG),SALP(MAXSEG),T2X(MAXSEG),T2Y(MAXSEG), ! &T2Z(MAXSEG),ICON1(MAXSEG),ICON2(MAXSEG),ITAG(MAXSEG), ! &ICONX(MAXSEG),IPSYM,LD,N1,N2,N,NP,M1,M2,M,MP DIMENSION X2(1), Y2(1), Z2(1) !Moved to Data Module EQUIVALENCE (X2(1),SI(1)), (Y2(1),ALP(1)), (Z2(1),BET(1)) This gives you enough information I believe. I trued moving the equivalence statement to the module, but still got the same error. Any suggestions as to how to fix this error. Thanks.
0 Kudos
Steven_L_Intel1
Employee
2,406 Views
Move the EQUIVALENCE (and declarations of any variables mentioned there) to the module. You can't EQUIVALENCE variables that became visible through USE.
0 Kudos
thomasglallen
Beginner
2,406 Views
When I move the EQUIVALENCE to the MODULE, in order for the EQUIVALENCE to work, I have to change the arrays associated in the EQUIVALENCE to static. I would like the EQUIVALENCE to have arrays that are dynamic using the ALLOCATION statement because the MAXSEG variable is of interest to me, because this is the one we want to make as big as possible. Is there a way to use EQUIVALENCE and ALLOCATION? If not, is there another way to handle this issue. Also, the EQUIVALENCE as shown above and in subsequent routines as I have found through examination is that it equivalences two corresponding elements (e.g., X2(1),SI(1)) and will let the array be referred to by either X2 or SI. As I said, anyway to use ALLOCATABLE/ALLOCATE with EQUIVALENCE or is their another way to do this using the allocation option. Thanks for your help.
0 Kudos
Steven_L_Intel1
Employee
2,406 Views
You can't use EQUIVALENCE with ALLOCATABLE. I suggest rewriting the code to not use EQUIVALENCE.
0 Kudos
thomasglallen
Beginner
2,406 Views
What would be the best way to right an EQUIVALENCE. Just want to get some ideas here so that I don't start drawing on straws. I thought of pointers and DO/WHILE loops. Also, if you have any references from others who have had this problem would be greatly appreciated as well.
0 Kudos
Steven_L_Intel1
Employee
2,406 Views
I don't think there's any one way to do this - it depends on what the program was trying to do. From the snippets you posted, it seems at best that the program was trying to avoid array bounds checking. I haven't seen enough of the program to know if that's the case. Ideally you'd want to eliminate the idea of aliases at all. It's probably a lot of work.
0 Kudos
thomasglallen
Beginner
2,406 Views
At the moment, I'm trying to understand how EQUIVALENCE statements work. Given the example above, consider the following: DIMENSION X2(1), Y2(1), Z2(1) !Moved to Data Module EQUIVALENCE (X2(1),SI(1)), (Y2(1),ALP(1)), (Z2(1),BET(1)) Now, SI,ALP, and BET are in the COMMON statements and are in some sense GLOBAL and visible to all subroutines that have COMMON/DATA/. Now, S1 is of size S1(MAXSEG), which, by EQUIVALENCING X2 to S1, makes X2 of size X2(MAXSEG). This is what is happening in the code. This I understand. But, by EQUIVALENCING X2 to S1, does X2 now become visible to other routines that contain the common COMMON/DATA/, like the variables in the COMMON/DATA/? It appears something like this is happening in this code because when I comment out the EQUIVALENCE, I get an error (an error that is caught by the code itself, it has some error checking - don't need to go into details), but when I uncomment the EQUIVALENCE, it runs normally. Thanks.
0 Kudos
mecej4
Honored Contributor III
2,406 Views
EQUIVALENCE has been in Fortran for decades, and it had its uses given the limitations of older versions of the language. Now that we have modules in the language, it is best if EQUIVALENCE is retired, given the numerous restrictions on its usage and the complicated side-effects caused by using it. If, however, you have old code and it is not feasible to remove the usage of EQUIVALENCE in it, you have to become aware of all the properties of the statement. Perhaps this analogy will help: think of memory as a row of mailboxes. Variable names correspond to labels on some of the mailboxes. EQUIVALENCE allows you to put additional labels on the same mailboxes. It does not allocate more mailboxes to a person (variable).
Now, S1 is of size S1(MAXSEG), which, by EQUIVALENCING X2 to S1, makes X2 of size X2(MAXSEG).
This is a misconception. Consider this example (no COMMON used, to keep things simple) [fortran] program tequivalence implicit none integer :: x(3),y(6),i equivalence (x(2),y(4)) do i=1,6 y(i)=i end do write(*,*)x write(*,*)y end program tequivalence [/fortran] The output of the program: [bash] 3 4 5 1 2 3 4 5 6 [/bash] Note that the EQUIVALENCE specification did not change the length of array x or that of array y.
0 Kudos
thomasglallen
Beginner
2,406 Views
OK, then what I understand you saying (again, taking the code shown above), is that in the following statements (set MAXSEG equal to 2000): IMPLICIT REAL*8 (A-H,O-Z) COMMON /DATA/ X(MAXSEG),Y(MAXSEG),Z(MAXSEG),SI(MAXSEG),BI(MAXSEG), & ALP(MAXSEG),BET(MAXSEG),SALP(MAXSEG),T2X(MAXSEG),T2Y(MAXSEG), & T2Z(MAXSEG),ICON1(MAXSEG),ICON2(MAXSEG),ITAG(MAXSEG), &ICONX(MAXSEG),IPSYM,LD,N1,N2,N,NP,M1,M2,M,MP DIMENSION X2(1), Y2(1), Z2(1) !Moved to Data Module EQUIVALENCE (X2(1),SI(1)), (Y2(1),ALP(1)), (Z2(1),BET(1)) even though the size of SI,ALP,and BET are size 2000, then X2(1), Y2(1), and Z2(1) are of size one, and therefore their sizes don't change; then, X2(1) is a label for the memory location SI(1), Y2(1) is a label memory location for ALP(1), and Z2(1) is a memory location for BET(1), and so there is no values for X2(2), Y2(2), and Z2(2) - or at least is garbage, all the way up to MAXSEG? Is this correct? Also, since SI,ALP,and BET are available to other subroutines with the COMMON statement, I'm assuming the X2,Y2, and Z2 are also visible to these subroutines, even though they are not explicitly contained in the COMMON statement? Is this correct as well? Also, I would imagine that SI(1),ALP(1), and BET(1) also can take on the values for X2(1), Y2(1), and Z2(1) as well. Is this correct? Sorry for the ignorant questions, but I'm trying to fully understand this EQUIVALENCE - I've written some snippets, but want to make sure this is your understanding as well. Thanks for your help on this matter. Tom
0 Kudos
mecej4
Honored Contributor III
2,406 Views
As declared in your code, X2, Y2 and Z2 are aliases for sections (of length 1) of arrays SI, ALP, BET. Once your code is compiled, all these variable names are gone (let's overlook debug symbols, etc.). X2(1) and and SI(1) are represented by the same memory address. Once X2 has been declared with dimension (1), code using other subscripts is in error, although the compiler need not detect such errors. Furthermore, even though X2(2) is illegal to use, the memory that it would be taken to refer to would be part of another properly allocated array, and referencing it would not cause access violations. The EQUIVALENCE statement applies only within the scope of the program unit where it occurs. Outside that program unit, the equivalence-d names do not exist. Thus, if you replicate the common block elsewhere, using the same variable names (X, Y, Z, ...), and proceed to reference X2, Y2 and Z2, which are not among the members of the block, these would be undeclared variables, and treated using IMPLICIT type rules if permitted. Here is an example: [fortran] program xeq IMPLICIT NONE integer,parameter :: MAXSEG=5 real, dimension(MAXSEG) :: X,Y,Z,SI,BI,ALP,BET,SALP,T2X,T2Y,T2Z integer, dimension(MAXSEG) :: ICON1,ICON2,ITAG,ICONX integer :: IPSYM,LD,N1,N2,N,NP,M1,M2,M,MP COMMON /DATA/ X,Y,Z,SI,BI,ALP,BET,SALP,T2X,T2Y,T2Z,ICON1,ICON2,ITAG, & ICONX,IPSYM,LD,N1,N2,N,NP,M1,M2,M,MP real, dimension(1) :: X2, Y2, Z2 EQUIVALENCE (X2,SI), (Y2,ALP), (Z2,BET) integer :: i do i=1,2 SI(i) = sqrt(2.0*i) end do write(*,*)X2 !X2 was never set, but SI(1) was set X2(2) = 5.5 !subscript out of range error call sub end program xeq subroutine sub IMPLICIT NONE integer,parameter :: MAXSEG=5 real, dimension(MAXSEG) :: X,Y,Z,SI,BI,ALP,BET,SALP,T2X,T2Y,T2Z integer, dimension(MAXSEG) :: ICON1,ICON2,ITAG,ICONX integer :: IPSYM,LD,N1,N2,N,NP,M1,M2,M,MP COMMON /DATA/ X,Y,Z,SI,BI,ALP,BET,SALP,T2X,T2Y,T2Z,ICON1,ICON2,ITAG, & ICONX,IPSYM,LD,N1,N2,N,NP,M1,M2,M,MP write(*,*)si write(*,*)X2 !X2 not declared, compile time error return end subroutine [/fortran]
0 Kudos
thomasglallen
Beginner
2,406 Views

So far I'm succeeding in converting this code over using allocatable variables; have a handle on the equivalences also.  But I have a question about some other things in the code.  There is a common statement called COMMON /SCRATM/.  Now, some subroutines it's COMMON /SCRATM/ D(2*MAXSEG), other subroutintes it is COMMON /SCRATM/ GAIN(4*MAXSEG), and in others it is COMMON /SCRATM/ Y(2*MAXSEG).  COMMON acts like globals, but there are different variables in this common located in different subroutines.  In a situation like this, does this represent COMMON /SCRATM/ D(2*MAXSEG),GAIN(4*MAXSEG), Y((2*MAXSEG)?  And should I treat it as such.  Again, I'm converting the commons over to modules.  What is the best way to convert this common over to a module?  Also, I don't understand what is being shared here if the common has different variables.  This looks like very bad programming, unless you have a good explanation.  Or is something else going on here I don't understand?  Thanks for your help. 

0 Kudos
thomasglallen
Beginner
2,406 Views

One more thing, it compiles and runs as it should as well with no warnings or errorrs - I just discovered this today as I'm converting commons over to modules.

0 Kudos
thomasglallen
Beginner
2,406 Views

One more item forgot to mention, the GAIN variable is a real value, the other ones (D and Y) are defined as COMPLEX*16.  So what is going on here also?

0 Kudos
mecej4
Honored Contributor III
2,406 Views

Also, I don't understand what is being shared here if the common has different variables.

The names of variables in a COMMON block are local in scope. COMMONality is by offset from the base of the COMMON block, not by name. For example, if the following statements occur in different subprograms

[fortran]subroutine subA

REAL a,b,c

COMMON /XYZ/a,b,c

...

subroutine subX

REAL p,q,r

COMMON /XYZ/p,q,r

[/fortran]

variable pairs (a, p), (b, q), (c, r) differ only in name. Variable 'a' in SubA has the same value as 'p' in SubX, etc.

When COMMON block members differ in type from one declaration to another, it gets "interesting".

0 Kudos
John_Campbell
New Contributor II
2,406 Views
I'd expect that what you are describing is basically a memory sharing strategy. Non-conforming, but very effective when there was limited available memory. . You might be able to use the POINTER attribute to replace the EQUIVALENCE between these arrays. I'd expect that EQUIVALENCE is being used to share memory for arrays that arn't used at the same time. . If you are mixing the TYPE or KIND of the variables, then the previous values were probably overwritten. However, if in this case, the values are being retained, such as mixing real and complex addressing, then the use of POINTER attribute might be more challenging. . With increased memory available, the clean solution might be to not share the storage locations, but use them independently. . Alternatively, EQUIVALENCE was used to allow memory locations to be re-named. This could allow addressing of storage with different rank arrays. Reducing the array rank was a way of improving performance. This is possibly no longer required and could be removed. (POINTER might be used in this case.) . All this involves changing old, non-standard code, with the associated problems of introducing new coding bugs, that need to be tested. . Handle with care ! . John
0 Kudos
thomasglallen
Beginner
2,406 Views

Have another issue: in the application discussed above, there is something like this declared: Complex *16 CM and below is Dimenstion CM(NR,*).  Now, NR is not defined anywhere in the routine, to include "include" statement.  Of course, everything comples and runs OK, so what is assumed here for the integer varialbe NR?

0 Kudos
Steven_L_Intel1
Employee
2,406 Views

Please show the actual code. Your description is not likely to be correct. In this context, NR could be a PARAMETER constant or the name of a dummy argument, COMMON variable or USE or host-associated variable. If CM is a dummy argument, then (unless NR is a PARAMETER), it is an "adjustable array" where the first bound is taken from the current value of NR. If it is not a dummy, then it is an "automatic" array, allocated on the stack (by default) with a first dimension of NR.

0 Kudos
mecej4
Honored Contributor III
2,406 Views

For a declaration such as CM(NR,*) that was accepted by the compiler, it is probable that both CM and NR are dummy arguments to a subprogram. Please check your sources.

0 Kudos
thomasglallen
Beginner
2,406 Views

Thanks.  I'm busy with a few other items here at work, and will upload the snipets of the code (enough to evaluate) some time this week.

0 Kudos
thomasglallen
Beginner
2,332 Views

I figured it out - been looking at this code too long.  The value of the array is coming in via the subroutine call it's under.  Sorry for the inconvenience.  I have another one: In many places in this code, an array is defined as an asterisk (wild card I'm assuming).  So you have something like this:

Complex*16, E

Dimension E(*)

Will the following be the same (want to make sure):

Complex(8), Dimension(:), Allocatable::E

Allocate(E(0))   ! size zero to start with

Also, if the array is a double array, then is "...Dimension(:,:) ... Allocate(E(0,0)) OK to use?  I think it is, but want your opinion.

One more question: I have allocations every which way but loose in the code (in modules, subroutines).  When it returns to main and exits, is there a wild card that I can use to deallocate the memory, or does it automatically deallocate when it exits?  Thanks.

 

0 Kudos
thomasglallen
Beginner
2,332 Views

One other question not related to the above one (or might be).  I have the code working with dynamic arrays.  This may have reference to deallocation, not sure.  But before conversion, I used an input file and runs in about a few minutes.  After conversion (converting to modules, allocation statements), I increased the arrays by 10x to test the dynamic arrays, and using the same input file, it runs much, much longer.  Should I be deallocating every time the code exits a subroutine to speed things up, or is there something else I can do to speed the code up.  Any suggestions would be appreciated.  Thanks.

0 Kudos
Reply