- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Link Copied
51 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In the same code, when I increase the array, I get the error that my variable CMB it too large for NTCOFF (Bigger than 2gb). CMB is a common statement like this:
COMMON /CMB/ CM(IRESRV), IP((2*MAXSEG), IB11, IC11, ID11, NEQMAT, NEQ, NEQ2
Now, above this I have IMPLICIT REAL*8 (A-H,O-Z) and IMPLICIT INTEGER*8 (I-N). Now, the this common statement is located about 5 other subroutines. I added the ALLOCATABLE statement like this:
COMMON ALLOCATABLE /CMB/ ...
and still get the same error (CMB too large for NTCOFF). I tried different methods but got syntaxed errors. Where do I go from here in order to allocate enough memory for the arrays. Thanks.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Forgot to mention that the values for the arrays, such as IRESRV and MAXSEG are stored in an include file as a parameter (such as PARAMETER (MAXSEG=200000, MAXMAT=7500) and in the code IRESRV=MAXMAT**2 where this variable MAXMAT is defined in the parameter statement in the include file as well). Any help is appreciated. Thanks.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You'll have to move away from COMMON. Also, you'll have to build for 64-bits if you aren't already.
ALLOCATABLE is a variable attribute and not compatible with COMMON. I recommend creating a module that declares the allocatable arrays, something like this:
[fortran]
module CMB_MOD
IMPLICIT NONE
real(8), allocatable:: CM(:)
integer(8), allocatable:: IP(:)
integer(8) :: IB11, IC11, ID11, NEQMAT, NEQ, NEQ2
end module CMB_MOD
[/fortran]
Now in the places that you INCLUDEd the COMMON definitions, instead say:
use CMB_MOD
(This has to go before any IMPLICIT or other declarations.)
At the start of your program, where you have also done the USE (the definitions of IRESRV and MAXSEG should also go in the module), say:
allocate (CM(IRESRV), IP(2*MAXSEG)
The rest of your program can remain unchanged except for needing the USE.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
To address your original Q re the needed libraries: I too have this problem and would like to see such a list. But, the specific problem you describe should have a very fast solution: If you are programming with a valid Intel Visual Fortran installation then you also have contextual access to help, and all you should need to do is look up SETMESSAGEQQ. It will tell you that you need USE IFQWIN. Most of ifqwin overlaps with dflib, but there are differences. There is no problem having USE both in your code (although possibly inefficient, I don't know). If you really want to remember that IFQWIN is only there to solve this one unresolved external, then put USE IFQWIN, ONLY: SETMESSAGEQQ.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
SETMESSAGEQQ is a QuickWin routine. As I noted above, USE DFLIB should work fine for this in Intel Visual Fortran. We don't support USE MSFLIB. If you want to change to USE IFQWIN, that's fine too. Note that your application needs to be built as a QuickWin project type in order to use that routine.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks. I tried it on one portion of the code, and it compiled and linked fine. Now, just want to make sure I understand - the "USE" statement (placed in all the required subroutines) will act as the COMMON statement in that all data will be shared amongst the subroutines. Also, it looked like the ALLOCATE(...) worked when I put it at the end all the COMMON statements in a routine, which I guess is where it should go (also after include, parameters, implicits, declarations). Is this correct? I'll have some other questions later. Thanks again.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The USE makes the declarations in the MODULE visible. This includes the variable declarations that replace the COMMON. The ALLOCATE goes somewhere in executable code where you will do that statement before using the array.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I've been making the changes as suggest here, compiling and linking with no errors. Now when I run the code (excutable), it says that "allocatable array is already allocated". I suspect that in other subroutines, maybe a Dimenstion statement is being used that shouldn's since I'm allocating the space. I like to have some clues on this, so when it crashes, it dumps 4 columns (PC, Routine, Line, and Source). All columns say UNKNOWN accept for the PC column. Is there a way to turn on something that fills these columns in so I can get a clue as to where the "already allocated" variable is? This would help a lot in converting this code over more quickly. Thanks.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
/traceback is what you want if you're building from the command line - this should be on by default for VS builds. A DIMENSION attribute would not be relevant here - rather, you have an allocatable array that is previously allocated. Is this a local array to the routine? Is it named in a SAVE statement or is /Qsave enabled?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I replaced the COMMON block you suggested with the USE statement for the subroutines that contained the COMMON block. I would imagine it's a local array to the routine. I went ahead and added the /traceback and /Qsave, and ran it again, it gave me again the columns each with 10 rows, but only two of these were filled in with two routines and line numbers, the rest unknowns. The routines it indicated didn't seem to give me any clue about what was be allocated already. What is /QSave? Let me look at this for a bit - I think this is helping me somewhat to trace what is going on here. I'll get back with more specifics. Thanks.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Actually, I wanted you to remove /Qsave if it had been added. This is Fortran > Data > Local variable storage > All variables SAVE in VS. This has an unfortunate side-effect on local allocatable variables.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I solved this allocate problem (I allocated a variable in main with the USE and did the same in a subroutine, and didn't need it in the subroutine, so I understand what is going on there) Now, I have another COMMON statement that I replaced with a USE. I placed it in one subroutine that had an equivalence statement : EQUIVALENCE (CAB,ALP),(SAB,BET). I obtained the error "attribtes of this name conflict with those made accessible by a USE statement". So I moved the EQUIVALENCE to the USE module, which solved that, but when I compile it, I get "An equivalence data object must not have the ALLOCATABLE or Pointer attribute" and "Variables containing ultimate allocatable array components cannot appear in COMMON or EQUIVALENCE statements. Variables ALP and BET are defined as REAL(8), ALLOCATABLE in module (have to be). Any way around equivalence, or something that is the same in fortran that works with ALLOCATABLE?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Also wanted to add that the CAB and SAB variables I mentioned above are defined in the subroutine as DIMENSION CAB(1), SAB(1).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Did some research. THe Fortran EQUIVALENCE was introduced as a means to inform the compiler that two or more different variables (usually arrays) could share the same storage locations because the programmer had arranged to complete the use of one of them before using any of the others. I guess years ago, memory and storage was limited, and newer machines don't have that issue. So I guess I could just comment out the equivalence and keep the Dimension statement - is that OK to do? It compiles or course with no errors.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
More often, EQUIVALENCE was used to provide access to a variable with a different type or length. You need to look at how the variables named in the EQUIVALENCE were used. If you simply take out the EQUIVALENCE, then instead of one set of data you have two - and probably introduce uninitialized references.
There's no universal answer to your question. It all depends on what the application used EQUIVALENCE for.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Now that you mentioned this, the EQUIVALENCE statement is something like this: EQUIVALENCE(CAB, ALP) where CAB and ALP are defined as follows: ALP(MAXSEG), where MAXSEG = 2000 in an include file and DIMENSION CAB(1). These appear to have different lengths. I would imagine you are talking about this. In this particular case, what is going on with the variables in the equivalence in terms of what equals what or what is being shared. If I understand this concept, I'll be able to make some intelligent changes to this code. Thanks.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Some thoughts/ideas on the subject.
modules are not sequential like common storage used to be back in the day.
equivalence to modules does not insure you are 1:1.
to get around that be sure to set equivalence each variable to the array.
for example, if you have in the old code
real something (3)
real one, two, three
In the old days you could say
equivalence (something(1), one)
and it would equate all three items to the something() since they existed in sequence.
not so much anymore.
now you need to be specific about it
equivalence (something(1), one), (something(2), two), (something(3), three)
very tedious to set up but then once set up it works as expected.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
As I'm going through the code making the substitution of USE cases for the COMMON statements, I make one change, run a test case, then make the next, etc. I made one change where I commented out a COMMON, replaced it with a USE, and I got a divide by zero error. I traced it down to a few COMMONs, don't know which one, but here's what I think is going on, and I need some advice just to save me some time:
It looks like the USE statement doesn't appear to work exactly as a COMMON (I replaced a COMMON with a USE and got a divide by zero, restored it, and it was fine). In the code I'm trying to convert over to 64-bit with large arrays, some subroutines apparently when called have variables that are initialized and the COMMON captures these values in the subroutine, and these values are used/passed by other subroutines that contain these values. Now, worst yet, some of these subroutines contain an "if" statement, which can change the stored values in the COMMON statement when called by another subroutine that passes the value that satisfies the “if”. Now, in the module, I have the arrays as allocatable, non-arrays as either integer(8) or real(8) (as described above), and I allocate the arrays only once in the Main program, and then use the USE in replacement for the COMMON. So, I’m wondering does the USE capture changes to its variables in a subroutines that reassigns that values, or do I need to do something else to make this act exactly like these COMMON statements. As a side note, I compiled this under linux, don’t have the array allocation issues as in Windows. Thanks.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
OK, maybe I talked out of line too soon, below is a test program, and it appears that the module captures changes in both subroutines, the print out should be 3333 and 4444.0, which it is. So, I guess the USE acts exactly as a COMMON, am I correct?
Module myModule
INTEGER i1
REAL f1
END MODULE
PROGRAM myProg
USE myModule
IMPLICIT NONE
C INTEGER i1
C REAL f1
i1=1111
f1=2222
CALL mysub1
WRITE(*,*) 'FROM mysbu1', i1, f1
CALL mysub2
WRITE(*,*) 'FROM mysub2', i1, f1
END
C
C
SUBROUTINE mysub1
USE myModule
IMPLICIT NONE
C
i1=3333
f1=4444
END
C
SUBROUTINE mysub2
USE myModule
IMPLICIT NONE
i1=5555
f1=6666
CALL mysub1
END
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I would not say that USE is "exactly like COMMON", though, as has been suggested in this thread, module variables made accessible by USE are usually a suitable replacement for COMMON as it is normally used.
COMMON declares a layout of variables that overlay other declarations of the same named COMMON in other program units. If all of these COMMON layouts are the same and each variable is accessed individually, then it is pretty much the same as module variables. But COMMON allows different layouts in different program units (for named COMMON, all must be the same length) and it establishes a "storage sequence" of the variables as a group, which USE does not.

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page