Intel® oneAPI Math Kernel Library
Ask questions and share information with other developers who use Intel® Math Kernel Library.
7108 Discussions

LAPACK functions cladiv, zladiv documented incorrectly?

andrew_reidnist_gov
499 Views
I've just run into some difficulty compiling Fortran code which calls the LAPACK function cladiv to compute a complex-number quotient. The documentation says that, for cladiv and zladiv, this is a function which takes two arguments and returns the result, but I kept getting mysterious segfaults in my code related to this call. I eventually wrote a C equivalent, and discovered when inspecting the declarations in mkl_lapack.h, that in C, it's declared as a three-argument function taking struct MKL_Complex pointers. This lead me to guess that the Fortran code should perhaps be "call cladiv(a,b,c)" instead of the "a=cladiv(b,c)" that I had been using. This gave correct results and eliminated the mysterious segfaults.

It seems that the documentation is incorrect, and that zladiv and cladiv actually work analogously to their realtives, sladiv and dladiv. Both the man page and the description in the reference manual are wrong. I have quite a compact test case which demonstrates the probem.

Is there an errata list for the docs? I'm concerned that other functions might pull similar surprises on me.

This is for the MKL bundled with version 11.0/074 of the compiler suite, and I'm running it on an ia64 system under SuSE SLES 10.0.
0 Kudos
2 Replies
Michael_C_Intel4
Employee
499 Views

Hello.

MKL documentation is correct, you should call cladiv as c = cladiv( a, b ) in Fortran. The reason why you get segmentation fault while passing two arguments in C is the general Fortran calling convention in case of complex return (it isn't related to MKL - it's just a Fortran convention). The problem is that a real value can be returned on a CPU fp register while complex values can't be that easily mapped on a register. That's why this convention is established:

if the function returns acomplex value, the argument is added implicitly to the beginning of the argument list containing the address of the complex value returned, additionally the function return this address on a general purpose register

That is, the following function in Fortran:

complex function cladiv( a, b )
complex a, b

has the following exact analogue in C:

complex* cladiv( complex* retvalue, complex* a, complex* b );

So you call it as

complex a, b, c;
(void) cladiv( &c, &a, &b );

and have the result in c.

The same is working for all the functions returning complex values and for double precision complex too.
0 Kudos
andrew_reidnist_gov
499 Views

Hello.

MKL documentation is correct, you should call cladiv as c = cladiv( a, b ) in Fortran. The reason why you get segmentation fault while passing two arguments in C is the general Fortran calling convention in case of complex return (it isn't related to MKL - it's just a Fortran convention). The problem is that a real value can be returned on a CPU fp register while complex values can't be that easily mapped on a register. That's why this convention is established:


Aha! This turned out to be the vital clue. Actually, the segfault was happening for the two-argument version in both Fortran and C, but the problem was that I was not declaring the CLADIV function as "COMPLEX" in the Fortran code, so it didn't know to do the little return-value dance that you describe. (This, in turn, is because my Fortran skills are very rusty -- I'm assisting another user, who first reported the problem to me.)

If I remember to declare the CLADIV function, then you're right, the documented version works.

It's apparently also true that CLADIV(RES, NUMERATOR, DENOMINATOR) works in Fortran. I guess that's an undocumented feature -- I won't rely on it.

Thanks!
0 Kudos
Reply