- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I must say that I have been confused about the MKL calling conventions when some of the arguments are strings for the blas and lapack functions. First of all if it is callable in Fortran, it must at least conform to the default Fortran convention which passes string lengths as hidden arguments at the end of argument list. For instance, mkl_blas.h defines
void DGEMM(const char *transa, const char *transb, const MKL_INT *m, const MKL_INT *n, const MKL_INT *k,
const double *alpha, const double *a, const MKL_INT *lda, const double *b, const MKL_INT *ldb,
const double *beta, double *c, const MKL_INT *ldc);
shouldn't it be (in C++):
void DGEMM(const char *transa, const char *transb, const MKL_INT *m, const MKL_INT *n, const MKL_INT *k,
const double *alpha, const double *a, const MKL_INT *lda, const double *b, const MKL_INT *ldb,
const double *beta, double *c, const MKL_INT *ldc, int lengths=1, int lengths=1);
or
void DGEMM(const char *transa, const char *transb, const MKL_INT *m, const MKL_INT *n, const MKL_INT *k,
const double *alpha, const double *a, const MKL_INT *lda, const double *b, const MKL_INT *ldb,
const double *beta, double *c, const MKL_INT *ldc, int const& lengtha=1, int const& lengthb=1);
?
I guess in the c calling convention, where arguments are passed from right to left on the stack and the stack is cleaned by the caller, and fortunately lapack routines do not check the string length, it really does not matter. That's probably why it works anyway you call it.
void DGEMM(const char *transa, const char *transb, const MKL_INT *m, const MKL_INT *n, const MKL_INT *k,
const double *alpha, const double *a, const MKL_INT *lda, const double *b, const MKL_INT *ldb,
const double *beta, double *c, const MKL_INT *ldc);
shouldn't it be (in C++):
void DGEMM(const char *transa, const char *transb, const MKL_INT *m, const MKL_INT *n, const MKL_INT *k,
const double *alpha, const double *a, const MKL_INT *lda, const double *b, const MKL_INT *ldb,
const double *beta, double *c, const MKL_INT *ldc, int lengths=1, int lengths=1);
or
void DGEMM(const char *transa, const char *transb, const MKL_INT *m, const MKL_INT *n, const MKL_INT *k,
const double *alpha, const double *a, const MKL_INT *lda, const double *b, const MKL_INT *ldb,
const double *beta, double *c, const MKL_INT *ldc, int const& lengtha=1, int const& lengthb=1);
?
I guess in the c calling convention, where arguments are passed from right to left on the stack and the stack is cleaned by the caller, and fortunately lapack routines do not check the string length, it really does not matter. That's probably why it works anyway you call it.
Link Copied
4 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In C++, extern "C" is required, to make a C compatible call without name mangling. I've seen people try to pass by reference (&) even in such cases, but that would not match the appended character length arguments. Basically, I believe you're correct about appended const int string length arguments. As there are include files with suggested C prototypes (which you quoted), it's definitely the responsibility of the library to make it work when you conform with those include files.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - tim18
In C++, extern "C" is required, to make a C compatible call without name mangling. I've seen people try to pass by reference (&) even in such cases, but that would not match the appended character length arguments. Basically, I believe you're correct about appended const int string length arguments. As there are include files with suggested C prototypes (which you quoted), it's definitely the responsibility of the library to make it work when you conform with those include files.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - Hanyou Chu
Yes, I am aware of extern "C" for C++. I was specifically referring to the default parameter values. I just want some one from Intel MKL team to clarify the exact calling conventions because the definitions in their header files don't seem to be consistent with their Fortran compiler conventions. Besides, I would protype the functions with referrences instead of pointers whenever possible for C++.
You're right, C definitions don't contain length parameters as it's supposed by Fortran calling convention. Actually,these parameters are never used, and these are not necessary to be passed. This just simplifies calling MKL routine from C. Is it a problem for you that C prototypes don't have lentghs?
We use pointers in prototypesbecauseheader filesare for C customers generally. Do you want MKL todistribute "C++ style" headers (not actually C++, but using references instead of pointers)?
Michael.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - Michael Chuvelev (Intel)
You're right, C definitions don't contain length parameters as it's supposed by Fortran calling convention. Actually,these parameters are never used, and these are not necessary to be passed. This just simplifies calling MKL routine from C. Is it a problem for you that C prototypes don't have lentghs?
We use pointers in prototypesbecauseheader filesare for C customers generally. Do you want MKL todistribute "C++ style" headers (not actually C++, but using references instead of pointers)?
Michael.
I do prefer C++ style headers since I use C++ and references are much more convenient to use, especially for constant references. I usually write my own header files.

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