passing float _Complex from C to Fortran

passing float _Complex from C to Fortran

Hello,I'm trying to pass some complex data from a C to a Fortran program without success for the moment.I managed to reproduce the problem in the small example belowC code:

#include void func(float _Complex x); int main(){ func((float _Complex)_Complex_I); return 1; } 
Fortran code:
subroutine func(x) bind(c) use iso_c_binding complex(c_float_complex), value :: x write(*,*)'x:',x return end subroutine func
The value of x printed is(0.0000000E+00,1.5932920E-10). Am I doing anything wrong here?Note that the same code works fine with GNU and IBM compilers. Moreover, if "float" is replaced with "double" in both sources, then it works ok.Can anybody help please?thanks in advance

12 post / 0 nuovi
Ultimo contenuto
Per informazioni complete sulle ottimizzazioni del compilatore, consultare l'Avviso sull'ottimizzazione

No problems with gcc 4.5 and IFort 11.1.073 (32 bit) on X64 Linux:

$ cc -m32 -g -c cplx.c
$ ifort -g -nofor-main cplx.o cfun.f90
$ ./a.out
x: (0.0000000E+00,1.000000)

If you are running on an Apple-Mac, have you checked regarding the X-Code bugs and work-arounds?

Hello,I'm running on a linux 64-bit system with intel icc and ifort V11.1.072. This is how I compile:$ icc -g -c comp_main.c$ ifort -g -nofor_main comp_fun.f90 comp_main.o$ ./a.outx: (0.0000000E+00,1.5932920E-10)maybe I should check if it works with 11.1.073?Thanks Mecej

Best Reply

I see the error with the 64-bit version of 11.1.073 on Linux-x64. The IFort compiled subroutine expects to see the real and imaginary parts in separate xmm registers, whereas C (Gcc or Intel C) passes the parts in the upper and lower halves of xmm0. Thus, the IFort compiled function takes the trash in xmm1 and prints it as the imaginary part.

It would be interesting to see if the soon-to-be-released 64-bit version of the Intel compiler also has this problem.

Dear Mecej,easy to imagine that if the argument is passed by reference instead of by value then everything works.Now the question is, is there a correct behavior for passing complex type arguments by value? Is it left to the compiler to decide whether to put the complex number in one or two registers? In this case this means that C codes compiled with different compilers may not be compatible, right? this looks pretty bad.Thanks for your helpAlfredo

There is an "ABI" (Application Binary Interface) document that describes, for a given architecture, how such things are done, but who defines this can be a subject of discussion. On Linux, the gcc documents are usually considered the standard here and I know that the Intel compiler has made changes over time to match that.

This issue sounds vaguely familiar and I'll look to see if we know about this.

Steve - Intel Developer Support


Although this statement is correct in this specific example, I would not count on the assumption in general:

"if the argument is passed by reference instead of by value then everything works"

because in C complex variables are structures, whereas in Fortran COMPLEX is an INTRINSIC type. Since structures are subject to padding/packing, mismatches can occur even if passing is done by reference.

Secondly, I think that the question

"In this case this means that C codes compiled with different compilers may not be compatible, right?"

puts the blame on the wrong entity. On Linux, for good or bad, GCC sets the standard and, as far as I know, did not deviate from the ABI defined by AMD. Discrepancies such as in this problem, therefore, are attributable to Fortran compilers rather than C compilers. In fact, your code runs fine with GFortran.

I am sure that Intel will do the right thing, once the issue is tagged as a bug.

By the way, the code runs correctly on IA64 (IFort 11.1.072, GCC) and Windows-XP64 (IFort 11.1.067-X64, Microsoft C). On the latter platform, however, Microsoft C uses an ABI that is almost completely different from the AMD/INTEL ABI, so GCC and its conventions do not enter the picture.

Steve, Mecej,I couldn't ask for a better explanation. Thanks for making this regardsAlfredo

Mecej,just to inform that this issue is still present in the new12.0.0.084 version o the ifort compiler.regardsalfredo

Alfredo, the problem seems to be worse (more pervasive, and not specific to C-interoperability) than I thought. I have modified your code and posted a reproducer here which is entirely in Fortran.

I reported this defect to Development (internal tracking id noted below) and will keep both posts updated with new status as I learn it.

Thank you again mecej4 for isolation details and convenient reproducer.

(Internal tracking id: DPD200198349)

(Resolution Update on 10/14/2012): This defect is fixed in the Intel® Fortran Compiler XE Update 6 ( - Linux)

Please pardon the delayed update. This defect is fixed in the Intel® Fortran Compiler XE Update 6 ( - Linux)

Lascia un commento

Eseguire l'accesso per aggiungere un commento. Non siete membri? Iscriviti oggi