Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compatibility with Intel Fortran compiler #433

Closed
xiexiguo opened this issue Aug 4, 2020 · 7 comments · Fixed by #434
Closed

Compatibility with Intel Fortran compiler #433

xiexiguo opened this issue Aug 4, 2020 · 7 comments · Fixed by #434
Assignees

Comments

@xiexiguo
Copy link

xiexiguo commented Aug 4, 2020

I try to compile a simple fortran code which using zdotc function. I found that when the code is compiled using intel fortran complier and linked with blis, the result is wrong. It is OK when using gfortran. So I am wandering whether blis is compatible with Intel fortran complier.
Blis is compiled with gcc, with blas and cblas interface enabled. I searched the code, and found all the code is C/C++, no fortran code (except some test code) is found. So, how fortran code can call blas function? Is blis only compatible with GNU compiler?
The following is the test code.
`
program zdotc_test

 implicit none

 complex*16 :: a(10), b(10)
 complex*16 :: c
 complex*16 :: zdotc
 integer*4  :: i

 do i = 1,10
     a(i) = cmplx(i, i)
     b(i) = cmplx(i, 0)
 end do

 c = zdotc(10, a, 1, b, 1)

 write(*,*) a
 write(*,*) b
 write(*,*) c

 end program

`

@devinamatthews
Copy link
Member

Unfortunately Intel and GNU Fortran compilers use incompatible mechanisms to return complex numbers: Intel adds a hidden first parameter (e.g. the above would be equivalent to call zdotc(c, 10, a, 1, b, 1)) while GNU returns the real and imaginary parts in xmm0 and xmm1 like in C.

I tried to look around for flags to emulate the behavior of the other compiler in each but did not have much luck. Since these mechanisms are mutually incompatible we have to pick only one, but perhaps we could add a configure option to select between the two.

@devinamatthews devinamatthews self-assigned this Aug 4, 2020
@xiexiguo
Copy link
Author

xiexiguo commented Aug 5, 2020

That will be great if a configure options will be added to support Intel Fortran, since in most scenarios Intel Fortran has better performance than gfortran. Is that on the plan in the future release?

devinamatthews added a commit that referenced this issue Aug 6, 2020
ifort apparently does not return complex numbers in registers as in C/C++ (or gfortran), but instead creates a "hidden" first parameter for the return value. The option --complex-return=gnu|intel has been added, as well as a guess based on a provided FC if not specified (otherwise default to gnu). This option affects the signatures of cdotc, cdotu, zdotc, and zdotu, and a single library cannot be used with both GNU and Intel Fortran compilers. Fixes #433.
devinamatthews added a commit that referenced this issue Aug 6, 2020
ifort apparently does not return complex numbers in registers as in C/C++ (or gfortran), but instead creates a "hidden" first parameter for the return value. The option --complex-return=gnu|intel has been added, as well as a guess based on a provided FC if not specified (otherwise default to gnu). This option affects the signatures of cdotc, cdotu, zdotc, and zdotu, and a single library cannot be used with both GNU and Intel Fortran compilers. Fixes #433.
@devinamatthews
Copy link
Member

@xiexiguo please try the intel-zdot branch. You will need to configure with either configure --complex-return=intel ... or configure FC=ifort ... (for the latter you can also set FC before calling configure).

@xiexiguo
Copy link
Author

xiexiguo commented Aug 7, 2020

Thanks! I have done some test, and it works! But there are still some errors when cblas interface(--enable-cblas) is enabled. Some erros like this.
Compiling obj/zen/frame/compat/cblas/f77_sub/f77_dot_sub.o ('zen' CFLAGS for framework code) frame/compat/cblas/f77_sub/f77_dot_sub.c: In function ‘cdotcsub_’: frame/compat/cblas/f77_sub/f77_dot_sub.c:55:4: warning: passing argument 1 of ‘cdotc_’ from incompatible pointer type [-Wincompatible-pointer-types] n, \ ^ include/zen/blis.h:2732:1: note: in expansion of macro ‘GENTFUNCDOT’ GENTFUNCDOT( scomplex, c, c, BLIS_CONJUGATE, blasname, blisname ) \ ^~~~~~~~~~~ include/zen/blis.h:2744:1: note: in expansion of macro ‘INSERT_GENTFUNCDOTC_BLAS’ INSERT_GENTFUNCDOTC_BLAS( blasname, blisname ) ^~~~~~~~~~~~~~~~~~~~~~~~

@devinamatthews
Copy link
Member

Oops, forgot about CBLAS. Will fix.

@devinamatthews
Copy link
Member

Should be fixed now in #434.

@xiexiguo
Copy link
Author

xiexiguo commented Aug 8, 2020

Yeah, I just did some tests, and it works well.
I also use this verision combined with lapack(netlib, compiled by ifort) to compile some big applications, and these apps run OK.
But if libflame is used instead of lapack(ifort version), the application also fails when zdotc is called. Maybe the call interface of libflame to blis is still GNU-style. The calling stack is the following.
Is it possible to call blis from libflame using ifort-style or using cblas interface?

0 0x00000000019a2016 bli_zdotv_zen_ref() ???:0
1 0x00000000018fac35 zdotc_() ???:0
2 0x00000000015dbf99 zdotc_f2c_() ???:0
3 0x000000000167be1e zhetd2_() ???:0
4 0x00000000015afa7b zhetrd_() ???:0
5 0x00000000015af16e zheev_() ???:0
6 0x00000000015adba4 zhegv_() ???:0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants