Operating System - OpenVMS
1751894 Members
5262 Online
108783 Solutions
New Discussion

Re: Alpha to Integrity application porting - issue

 
SOLVED
Go to solution
Jenwae
Advisor

Alpha to Integrity application porting - issue

Hi All,

 

I have a Fortran application running on Alpha 8.3 re-written in C and now being ported to Integrity.

The application reads from and writes to legacy binary data files on disk.

We have re-compiled the C application with the option /FLOAT=G_FLOAT to support the data files.

Everything seems to run just fine, except for 2 issues we recently encountered:

 

1) On certain occasion, the application will crash with SYSTEM-F-FLTINV, floating invalid operation.

For example, at the source line:

     double my_local_double;

     my_local_double += common_double_variable_read_from_file;

 

2) We have variables declared as float. Apparently, after compiling in g_float, the data in the float changed.

 

So we wrote a small program to test out.

The value changed after passed to a subroutine/function.

For example, in MYPROGRAM.C

    int main() {

       float my_local_float = 12233.00

       printf(" Float value = %f", my_local_float");

       foo(my_local_float);

       return

    }

    

In FOO.C

    void foo(float x) {

      printf(" Float value = %f", x);

      return;

    }

 

The value printed in MYPROGRAM.C is different than in FOO.C

 

Any advice is appreciated.

Thank you,

James

22 REPLIES 22
Eberhard Heuser
Frequent Advisor

Re: Alpha to Integrity application porting - issue

Strange:

 

#include <stdio.h>
    void foo(float x) {
      printf(" Float value = %f", x);
      return;
    }

int main() {

       float my_local_float = 12233.00;
       printf(" Float value = %f", my_local_float);
       foo(my_local_float);
    }

 

$ cc/float=g_float tf.c

$ link tk

$ r tf

 Float value = 12233.000000 Float value = 12233.000000

 

$ cc/version
HP C V7.3-020 on OpenVMS IA64 V8.4

+ all actual patches (i.e. CRTL)

 

Eberhard

abrsvc
Respected Contributor

Re: Alpha to Integrity application porting - issue

One thing that would be helpful here is knowing what the actual difference is.  Please provide the actual output from the programs as listed that show the problem.  Also, you initially describe using double, yet the supplied program uses standard float.  Where is the problem, with double float or float? 

 

If you can show the different values, please also print out the variables in hex.  An examination of the actual stored binary (in hex) will be helpful as well.

 

Dan

Duncan Morris
Honored Contributor

Re: Alpha to Integrity application porting - issue

Look out for your compiler warnings!

 

$ ty test.c
int main() {
       float my_local_float = 12233.00;
       printf(" Float value = %f", my_local_float);
       foo(my_local_float);
       return 1;
    }
void foo(float x) {
      printf(" Float value = %f", x);
      return;
    }

 

produces:

 

$ cc/ver
HP C V7.3-020 on OpenVMS IA64 V8.4
$ cc/float=g_float test
 
       printf(" Float value = %f", my_local_float);
.......^
%CC-I-IMPLICITFUNC, In this statement, the identifier "printf" is implicitly declared as a function.
at line number 3 in file SYS$SYSROOT:[SYSMGR]TEST.C;2
 
       foo(my_local_float);
.......^
%CC-I-IMPLICITFUNC, In this statement, the identifier "foo" is implicitly declared as a function.
at line number 4 in file SYS$SYSROOT:[SYSMGR]TEST.C;2
 
void foo(float x) {
.....^
%CC-W-NOTCOMPATIMP, In this declaration, the type of the function "foo" is not compatible with the earlier implicit declaration of "
foo" at line number 4 in file SYS$SYSROOT:[SYSMGR]TEST.C;2.
at line number 7 in file SYS$SYSROOT:[SYSMGR]TEST.C;2


$ link test
%ILINK-W-COMPWARN, compilation warnings
        module: TEST
        file: SYS$SYSROOT:[SYSMGR]TEST.OBJ;3


$ run test
 Float value = 12233.000000 Float value = 1.811661

 

but

 

$ ty test.c
void foo(float x) {
      printf(" Float value = %f", x);
      return;
    }
int main() {
       float my_local_float = 12233.00;
       printf(" Float value = %f", my_local_float);
       foo(my_local_float);
       return 1;
    }
$ cc/float=g_float test
 
      printf(" Float value = %f", x);
......^
%CC-I-IMPLICITFUNC, In this statement, the identifier "printf" is implicitly declared as a function.
at line number 2 in file SYS$SYSROOT:[SYSMGR]TEST.C;3
$ link test
$ run test
 Float value = 12233.000000 Float value = 12233.000000
$

 

Duncan

abrsvc
Respected Contributor

Re: Alpha to Integrity application porting - issue

If you have shown the same as the original poster, then this is clearly an indication that the "bits" of the variable are being interpreted differently (as one would expect).

The variables are passed by reference. In other words the memory address of the variable is passed NOT the actual variable value. This means that at address A, the bits are interpreted as a G_float using 64 bits and in the FOO routine, address A is interpreted as a float using 32 bits.

All floating numbers are composed of 3 parts:
1) Sign bit
2) Exponent
3) fraction bits

For G_float, bits 0-51 are part of the fraction

Note that the fraction portion of hte G_float will be the only part used if the address is viewed as a standard 32 bit floating variable. Thus the difference in reported value.

Dan
Craig A Berry
Honored Contributor

Re: Alpha to Integrity application porting - issue

@abrsvc wrote:

The variables are passed by reference.
No, in C they are passed by value, but the value placed on the stack is in the format of the caller.  If the function called expects a different format, bad things happen.
For the OP question #1.  Are you absolutely certain the data read from the file are G_FLOAT, not D_FLOAT and that there aren't other problems such as structure member alignment in the move from Fortran to C?  Have you stepped through the program in the debugger and done
examine/g_float common_double_variable_read_from_file
examine/d_float common_double_variable_read_from_file
?
For question #2, are you sure you are recompiling both modules myprogram.c and foo.c with the same floating point options?  If one is compiled with /G_FLOAT and one is not, you will very likely get the symptom you are seeing or worse.
Hein van den Heuvel
Honored Contributor

Re: Alpha to Integrity application porting - issue

 

 

     double my_local_double;
     my_local_double += common_double_variable_read_from_file; 

 

As presented, that's broken / unpredictable code because my_local_double is not initialized.

Try: 

 

double my_local_double = 0;

 

fwiw,

Hein.

Jenwae
Advisor

Re: Alpha to Integrity application porting - issue

Hi All,

 

Thank you for your review and replies.

Here is my response/clarifcation to your queries.

 

To Eberhard:

Yes, strange indeed. If routine Foo is declared in the same file as main, then both float values printed out are the same, REGARDLESS if the compile option /FLOAT=ieee_float or /FLOAT=g_float is used.

 

However, if Foo is declared as a separate C file, then it gets interesting.

 

When compiled with ieee_float, result is normal. With /FLOAT=g_float, the values are mangled

Here what I got when I compiled BOTH the C files (myprogram.c, foo.c) with cc/float=g_float, and linked as link myprogram, foo.

 

 

Float value in main = 12233.000000 (hex)=e48040e7)
Float value in Foo = 1.811661 (hex=fc90401c)

 

 

To ABSRVC (Dan):

We actually encountered 2 issues.

The 2nd issue is with the float variable, which I wrote simple C programs to prove the point.

The output is as displayed above.

 

 

To Duncan:

Yes, if we put the FOO routine in the same file as the main (MYPROGRAM.C), then we don't have a problem (whether we compile with IEEE_FLOAT or G_FLOAT).

 

The float value  changes only when FOO routine is in its own file (FOO.C), and we compile both files (FOO.C and MYPROGRAM.C) with G_FLOAT. Why is this not documented by HP, or maybe I'm overlooking something.

 

 

To Craig:

Yes, I compiled both C files with the same /FLOAT option. With /FLOAT=IEEE_FLOAT, no problem, but with /FLOAT=G_FLOAT, I get mangled float variable values.

 

For your 1st query, yes, those FP data are G_FLOAT.

I did step through, and when I examine in BINARY, it shows zeroes.

 

examine/binary common_double_variable_read_from_file

 

I will examine in g_float and d_float and let you know the outcome.

 

 

To Hein:

I did init the local variable double.

But I think the FLTINV exception is triggered by the common_double_variable_read_from_file.

 

     double my_local_double = 0;

     my_local_double += common_double_variable_read_from_file;

 

 

Any clarification is appreciated. I'm trying to avoid doing Database conversion,

 

Thank you so much!

Joel

 

 

 

John Gillings
Honored Contributor

Re: Alpha to Integrity application porting - issue

James,

 

>We have re-compiled the C application with the option /FLOAT=G_FLOAT to support the data files.

 

I'd recommend you bite the bullet and convert everything to the native floating format of your new system (IEEE). Making the application non-standard for the sake of some legacy data files is a bad tradeoff. You risk the consequences of floating format mismatches (which is almost certainly what's going on here), as well as potential performance issues.

 

Build yourself a small program to convert the data in any existing files. In theory this should be very simple and very easy to validate. Tag the data files so you can tell if they're in the wrong format. The extra effort will be well worth it in the long run, even if there's a lot of data. You don't need to convert everything up front, just as needed. (Indeed, you could even build a conversion step into the application itself, making it transparent to users). 

A crucible of informative mistakes
jreagan
Advisor

Re: Alpha to Integrity application porting - issue

How did you compile the Fortran application? 

 

Don't forget that the default changed from VAX F/G on Alpha to IEEE S/T on Itanium.  It changed for BOTH Fortran and C.  And the /IEEE_MODE changed from FAST to DENORM.