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

subroutine argument real to integer conversion

Lowell_S_
Beginner
903 Views

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)                             

 

0 Kudos
1 Solution
Steven_L_Intel1
Employee
903 Views

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.

View solution in original post

0 Kudos
6 Replies
Steven_L_Intel1
Employee
904 Views

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.

0 Kudos
Lowell_S_
Beginner
903 Views

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?

0 Kudos
Steven_L_Intel1
Employee
903 Views

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.

0 Kudos
Lowell_S_
Beginner
903 Views

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)    


 

0 Kudos
Steven_L_Intel1
Employee
903 Views

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.

0 Kudos
Lowell_S_
Beginner
903 Views

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.

0 Kudos
Reply