- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hey,
I am migrating a legacy HP UX f90 program to a Linux Intel ifort program. There is a call to a subroutine where one of the actual arguments is an integer array output from the subroutine but the subroutine dummy argument is a real array. This works fine on the legacy unix program but does not work when I try it on Linux. It compiles and runs but when the code later tries to use a value from this integer array, the value is wrong which ultimately causes an error found during a check. I tried to find a compiler option to allow this conversion to work with ifort but I had no luck. Is there such an option? Thanks!
Sub call where the loc array is of type integer.
call ntran(idr(ilt),2,4096,loc(1,1,1,1,ilt),lerr,22)
Sub declaration where the ARRAY array is of type real and dynamically sized in ntran. Array is populated in ntran and passed back to the calling program.
SUBROUTINE NTRAN(IU,IOP,NW,ARRAY,LERR,IWAIT)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
No, there is no option to do conversion and I'm guessing that the HP compiler didn't convert either. What is more likely happening is that the HP system was "big-endian" and integers, when loaded as reals, look like "normal" numbers. As long as the called routine doesn't try doing arithmetic with them, for example if it simply copied them, it would (usually) work.
Intel systems are "little-endian" and many integers have a bit pattern that, when interpreted as a real, look like a denormalized number and may get changed to zero. Another possibility is an integer that "looks like" a signaling NaN and gets converted to a "quiet NaN" on load by the processor.
The program is not legal Fortran. If you can provide more details as to what NTRAN does, I may be able to offer some suggestions.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
No, there is no option to do conversion and I'm guessing that the HP compiler didn't convert either. What is more likely happening is that the HP system was "big-endian" and integers, when loaded as reals, look like "normal" numbers. As long as the called routine doesn't try doing arithmetic with them, for example if it simply copied them, it would (usually) work.
Intel systems are "little-endian" and many integers have a bit pattern that, when interpreted as a real, look like a denormalized number and may get changed to zero. Another possibility is an integer that "looks like" a signaling NaN and gets converted to a "quiet NaN" on load by the processor.
The program is not legal Fortran. If you can provide more details as to what NTRAN does, I may be able to offer some suggestions.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks, Steve.
I think you hit the nail on the head. Ntran is reading integer data from a binary file as real that was created on the HP as big endian. I open the file using convert='BIG_ENDIAN' to be able to use the HP data file and you are correct that when I print out the values they have been changed to zero. We are trying to make our legacy programs "endian aware" because we want to be able to read legacy data files. How can I make this work?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Perhaps I don't understand the immediate problem.
When you read unformatted data with CONVERT='BIG_ENDIAN', the values are converted to little-endian for the read, so you have little-endian data (whether it be real or integer). The issue here is the type mismatch. What is the data flow here? Are you reading the data as integers (but they're really reals), or as reals? How do the integer values get created that are passed to NTRAN? What does NTRAN do with them?
If NTRAN is just copying data and not interpreting the values, change the type of the array arguments from real to integer. It should still operate the same but now you won't get values being changed.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Whoever the clown was that wrote this mess way back when ('80's) used ntran to read real data from the binary file at times and then at other times to read integer data. He used a real array to read the data in both situations and handled the type conversion in the argument list call to NTRAN. Which is not working for me in the case of integer data for the reason you explained in your first response.
Based on what I think you are telling me, I plan to try creating another subroutine called NTRANi to be called when the data to be read from the file are integers instead of reals. It will use an integer array when reading from the file. Do you think this will work?
read(unit=lu,iomsg=msg,rec=ipos,err=998)(iarray(i),i=1,nw)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
So it's NTRAN that actually reads the data, and how it's interpreted depends on what the argument type was that was passed to NTRAN? If so, I think the simple solution is to edit NTRAN to have it read an array of integers rather than reals. Assuming you don't have the Generated Interface Checking option enabled, this will store the bit-correct values in either a REAL or INTEGER actual argument.
Your idea would work too, of course.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks, Steve. It worked when I implemented the fix I described in my last post. I had previously learned this lesson with reading character data on a big endian file and now I will make sure I read integer data as integers as well. Thanks again for getting me on the right track to fix this problem.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page