- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Versions used (in debug and optimized modes) :
ifort (IFORT) 10.0 20070809
gcc version 3.3.5 (Debian 1:3.3.5-13)
and
ifort (IFORT) 10.0 20070426
gcc version 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)
I get a wrong result with the following test example (g95 gives the correct answer but gfortran does not want to compile
) :
File test15.f90 :
PROGRAM test
USE iso_c_binding
TYPE, BIND(C) :: mytype
INTEGER(C_INT) :: ival
REAL(C_DOUBLE) :: dval
END TYPE
INTERFACE
FUNCTION get_c_pointer(n) RESULT BIND(C,name="get_c_pointer")
USE iso_c_binding
TYPE(C_PTR) :: r
INTEGER(C_INT),VALUE,INTENT(IN) :: n
END FUNCTION
END INTERFACE
TYPE(mytype),POINTER :: array(:)
DOUBLE PRECISION,POINTER :: vector(:)
TYPE(C_PTR) :: cptr
cptr= get_c_pointer(10)
CALL C_F_POINTER(cptr,array,(/10/))
vector => array(:)%dval
WRITE(*,*) vector
END PROGRAM
File get_c_pointer :
#include
typedef struct{
int ival;
double dval;
}mytype;
mytype* get_c_pointer(int n){
int i;
mytype *s;
s=(mytype*)malloc(n*sizeof(mytype));
for(i=0;i s.ival=i;
s.dval=i;
}
return s;
}
g95 result :
0. 1. 2. 3. 4. 5. 6. 7. 8. 9.
ifort result :
2.121995790965272E-314 9.881312916824931E-324 3.00000000000000
1.114099596794633E-313 2.964393875047479E-323 7.00000000000000
1.962949719718608E-313 2.865224816750859E-309 0.000000000000000E+000
0.000000000000000E+000
ifort (IFORT) 10.0 20070809
gcc version 3.3.5 (Debian 1:3.3.5-13)
and
ifort (IFORT) 10.0 20070426
gcc version 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)
I get a wrong result with the following test example (g95 gives the correct answer but gfortran does not want to compile
![Sad smiley [:(]](/isn/Community/en-US/emoticons/emotion-9.gif)
File test15.f90 :
PROGRAM test
USE iso_c_binding
TYPE, BIND(C) :: mytype
INTEGER(C_INT) :: ival
REAL(C_DOUBLE) :: dval
END TYPE
INTERFACE
FUNCTION get_c_pointer(n) RESULT BIND(C,name="get_c_pointer")
USE iso_c_binding
TYPE(C_PTR) :: r
INTEGER(C_INT),VALUE,INTENT(IN) :: n
END FUNCTION
END INTERFACE
TYPE(mytype),POINTER :: array(:)
DOUBLE PRECISION,POINTER :: vector(:)
TYPE(C_PTR) :: cptr
cptr= get_c_pointer(10)
CALL C_F_POINTER(cptr,array,(/10/))
vector => array(:)%dval
WRITE(*,*) vector
END PROGRAM
File get_c_pointer :
#include
typedef struct{
int ival;
double dval;
}mytype;
mytype* get_c_pointer(int n){
int i;
mytype *s;
s=(mytype*)malloc(n*sizeof(mytype));
for(i=0;i
s.dval=i;
}
return s;
}
g95 result :
0. 1. 2. 3. 4. 5. 6. 7. 8. 9.
ifort result :
2.121995790965272E-314 9.881312916824931E-324 3.00000000000000
1.114099596794633E-313 2.964393875047479E-323 7.00000000000000
1.962949719718608E-313 2.865224816750859E-309 0.000000000000000E+000
0.000000000000000E+000
Link Copied
12 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The mistake probably comes from a misalignment of double values.
Indeed, when I add a new integer variable in the definition of the derived type, then the result is OK :
FORTRAN side
TYPE, BIND(C) :: mytype
INTEGER(C_INT) :: ival,ival2
REAL(C_DOUBLE) :: dval
END TYPE
C side
typedef struct{
int ival,ival2;
double dval;
}mytype;
Result with ifort and gcc
0.000000000000000E+000 1.00000000000000 2.00000000000000
3.00000000000000 4.00000000000000 5.00000000000000
6.00000000000000 7.00000000000000 8.00000000000000
9.00000000000000
Indeed, when I add a new integer variable in the definition of the derived type, then the result is OK :
FORTRAN side
TYPE, BIND(C) :: mytype
INTEGER(C_INT) :: ival,ival2
REAL(C_DOUBLE) :: dval
END TYPE
C side
typedef struct{
int ival,ival2;
double dval;
}mytype;
Result with ifort and gcc
0.000000000000000E+000 1.00000000000000 2.00000000000000
3.00000000000000 4.00000000000000 5.00000000000000
6.00000000000000 7.00000000000000 8.00000000000000
9.00000000000000
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hmm,, I'm going to have to regression test this a bit - I have the 10.1 compiler on my Mac and I get the correct answer. Have you tried the latest 10.1 compiler on your development platform?
Here's what I'm seeing on my Mac with 10.1.007 and gcc:
rwgreen$ gcc -m64 -c get_c_pointer.c
rwgreen$ ifort test15.f90 get_c_pointer.o
test15.f90(27): (col. 3) remark: LOOP WAS VECTORIZED.
mbp0017f2df31c3:~/quads/forums/30247174 rwgreen$ ./a.out
0.000000000000000E+000 1.00000000000000 2.00000000000000
3.00000000000000 4.00000000000000 5.00000000000000
6.00000000000000 7.00000000000000 8.00000000000000
9.00000000000000
Here's what I'm seeing on my Mac with 10.1.007 and gcc:
rwgreen$ gcc -m64 -c get_c_pointer.c
rwgreen$ ifort test15.f90 get_c_pointer.o
test15.f90(27): (col. 3) remark: LOOP WAS VECTORIZED.
mbp0017f2df31c3:~/quads/forums/30247174 rwgreen$ ./a.out
0.000000000000000E+000 1.00000000000000 2.00000000000000
3.00000000000000 4.00000000000000 5.00000000000000
6.00000000000000 7.00000000000000 8.00000000000000
9.00000000000000
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
10.1.013 on Windows shows me the same good results Ron saw on MacOS.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I will bet $20 you are using a 32bit Linux system, yes?
I can reproduce this with the latest 10.1 iforts, but ONLY on 32bit Linux and Mac OS X. So it seems to be an issue with the 32bit compiler.
On my Mac, I can compile in 32bits:
rwgreen$ gcc -m32 -c get_c_pointer.c
rwgreen$ ifort -m32 test15.f90 get_c_pointer.o
test15.f90(27): (col. 3) remark: LOOP WAS VECTORIZED.
mbp0017f2df31c3:~/quads/forums/30247174 rwgreen$ ./a.out
2.121995790965272E-314 9.881312916824931E-324 3.00000000000000
1.114099596794633E-313 2.964393875047479E-323 7.00000000000000
1.962949719718608E-313 0.000000000000000E+000 0.000000000000000E+000
0.000000000000000E+000
On Linux, I used a 32bit Linux host, hence the 32bit gcc and 32bit Ifort to the same results.
If you can, use a 64bit Linux host and 64 bit gcc and ifort to work around this issue.
Please go to premier.intel.com and open a bug report. Reference T82358-CP in your Premier issue. This is the internal bug report that I opened on this. If you don't have Premier access let me know so I an assign the bug to myself instead of you.
ron
I can reproduce this with the latest 10.1 iforts, but ONLY on 32bit Linux and Mac OS X. So it seems to be an issue with the 32bit compiler.
On my Mac, I can compile in 32bits:
rwgreen$ gcc -m32 -c get_c_pointer.c
rwgreen$ ifort -m32 test15.f90 get_c_pointer.o
test15.f90(27): (col. 3) remark: LOOP WAS VECTORIZED.
mbp0017f2df31c3:~/quads/forums/30247174 rwgreen$ ./a.out
2.121995790965272E-314 9.881312916824931E-324 3.00000000000000
1.114099596794633E-313 2.964393875047479E-323 7.00000000000000
1.962949719718608E-313 0.000000000000000E+000 0.000000000000000E+000
0.000000000000000E+000
On Linux, I used a 32bit Linux host, hence the 32bit gcc and 32bit Ifort to the same results.
If you can, use a 64bit Linux host and 64 bit gcc and ifort to work around this issue.
Please go to premier.intel.com and open a bug report. Reference T82358-CP in your Premier issue. This is the internal bug report that I opened on this. If you don't have Premier access let me know so I an assign the bug to myself instead of you.
ron
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes this is a 32 bit Linux
No I cannot switch to a 64 bit system easily. I have the choice between my personal computer (core 2 duo 2.4Gz), a Cluster of 128 Linux OS nodes (32bit 3.2Gz), 1 cluster of 32 nodes (32bit 3Gz), and a farm of PCs (about 1 hundred PCs with Intel or AMD processors 32 or 64 bits). And the codes I develop must be install everywhere.
No, I haven't Premier access. I just use the free ifort version on my personal computer and an official 10.0 version on the clusters : the maintenance team managing this network has surely a Premier access but not me.
F. Jacq
No I cannot switch to a 64 bit system easily. I have the choice between my personal computer (core 2 duo 2.4Gz), a Cluster of 128 Linux OS nodes (32bit 3.2Gz), 1 cluster of 32 nodes (32bit 3Gz), and a farm of PCs (about 1 hundred PCs with Intel or AMD processors 32 or 64 bits). And the codes I develop must be install everywhere.
No, I haven't Premier access. I just use the free ifort version on my personal computer and an official 10.0 version on the clusters : the maintenance team managing this network has surely a Premier access but not me.
F. Jacq
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You have access to Intel Premier Support even with the free non-commercial license. Just register your serial number and check the box to register for support.
What I found is that the Fortran compiler needs to know whether or not the "companion C processor" inserts padding for misaligned members of structs by default. Apparently some do (MSVC) and some don't (gcc?).
What I found is that the Fortran compiler needs to know whether or not the "companion C processor" inserts padding for misaligned members of structs by default. Apparently some do (MSVC) and some don't (gcc?).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
OK, how about just using -malign-double with gcc?
rwgreen$ gcc -m32 -malign-double -c get_c_pointer.c
rwgreen$ ifort -m32 test15.f90 get_c_pointer.o
test15.f90(27): (col. 3) remark: LOOP WAS VECTORIZED.
mbp0017f2df31c3:~/quads/forums/30247174 rwgreen$ ./a.out
0.000000000000000E+000 1.00000000000000 2.00000000000000
3.00000000000000 4.00000000000000 5.00000000000000
6.00000000000000 7.00000000000000 8.00000000000000
9.00000000000000
Try this on your linux box.
and some cautions from our GNUish friends:
"-malign-double
-mno-align-double
Control whether GCC aligns double, long double, and long long variables on a two word boundary or a one word boundary. Aligning double variables on a two word boundary will produce code that runs somewhat faster on a `Pentium' at the expense of more memory.
On x86-64, -malign-double is enabled by default.
Warning: if you use the -malign-double switch, structures containing the above types will be aligned differently than the published application binary interface specifications for the 386 and will not be binary compatible with structures in code compiled without that switch. "
SO you will have to use that switch for ALL your source files. But hey, as a side benefit you will get a little performance increase (in theory).
cheers
ron
rwgreen$ gcc -m32 -malign-double -c get_c_pointer.c
rwgreen$ ifort -m32 test15.f90 get_c_pointer.o
test15.f90(27): (col. 3) remark: LOOP WAS VECTORIZED.
mbp0017f2df31c3:~/quads/forums/30247174 rwgreen$ ./a.out
0.000000000000000E+000 1.00000000000000 2.00000000000000
3.00000000000000 4.00000000000000 5.00000000000000
6.00000000000000 7.00000000000000 8.00000000000000
9.00000000000000
Try this on your linux box.
and some cautions from our GNUish friends:
"-malign-double
-mno-align-double
Control whether GCC aligns double, long double, and long long variables on a two word boundary or a one word boundary. Aligning double variables on a two word boundary will produce code that runs somewhat faster on a `Pentium' at the expense of more memory.
On x86-64, -malign-double is enabled by default.
Warning: if you use the -malign-double switch, structures containing the above types will be aligned differently than the published application binary interface specifications for the 386 and will not be binary compatible with structures in code compiled without that switch. "
SO you will have to use that switch for ALL your source files. But hey, as a side benefit you will get a little performance increase (in theory).
cheers
ron
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Just so it's crystal clear, don't use -m32 on your Linux system. This is a Mac-ism.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
this is an important issue for me..but I can't even use the iso_c_binding module. How do I link in the appropriate module?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
gcc and gfortran switch from 64-bit to 32-bit code by the -m32 switch. The equivalent switch with ifort is to set environment variables according to the scripts in /opt/intel/fce/bin (64-bit) or /opt/intel/fc/bin (32-bit, if both are installed).
iso_c_binding is invoked by the USE, in accordance with any textbook, or see e.g.
http://www.fortran.bcs.org/2002/interop.htm
iso_c_binding is invoked by the USE, in accordance with any textbook, or see e.g.
http://www.fortran.bcs.org/2002/interop.htm
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I should clarify. I used the discussion's first example as an introduction to using c-bind. I copied the above example, and on a mac w/ Leopard, using the 32-bit ifort, I saved the 2 portions of code in a fortran and c file. ifort -c test1.f failed at compile time, even though I source the variables in the intel variable script. The error is that the "use" statement :
fortcom: Error: c_bindtest.f, line 4: Error in opening the compiled module file. Check INCLUDE paths. [ISO_C_BINDINGROGRAMTEST]
USE iso_c_binding
I don't think I have to explicitly include the intel compiler include path, do I?
fortcom: Error: c_bindtest.f, line 4: Error in opening the compiled module file. Check INCLUDE paths. [ISO_C_BINDINGROGRAMTEST]
USE iso_c_binding
I don't think I have to explicitly include the intel compiler include path, do I?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Fixed. I was using a *.f suffix, the correct one is *.f90.
Sorry for the confusion.
Sorry for the confusion.

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