I'm trying to call an MKL matrix multiplication routine from inside Julia.
I have julia version 0.4.3 compiled with intel MKL. I've noticed however
some weird behavior involving the ccall function. If I run the following
code inside a Julia terminal, I get no errors:
Tv *=* Float*64*
>
>
> n *=* *10*
>
>
> transa *=* *'**N**'*
>
> A *=* speye*(**10**)*
>
> x *=* StridedVector{Tv}*(*randn*(*n*))*
>
> y *=* StridedVector{Tv}*(*zeros*(*n*))*
>
> alpha *=* *(*Tv*)(**1**)*
>
> beta *=* *(*Tv*)(**0**)*
>
> matdescra *=* ASCIIString*(**"SLNF"**)*
>
>
> println*(*alpha *** A *** x *+* beta *** y*)*
>
>
> ccall*((*:mkl_dcscmv, *"libmkl_rt"**)*, Void,
>
> *(*Ptr{UInt8}, Ptr{Int64}, Ptr{Int64}, Ptr{Tv},
>
> Ptr{UInt8}, Ptr{Tv}, Ptr{Int64}, Ptr{Int64},
>
> Ptr{Int64}, Ptr{Tv}, Ptr{Tv}, Ptr{Tv}*)*,
>
> &transa, &A.m, &A.n, &alpha,
>
> matdescra, A.nzval, A.rowval, A.colptr[1:A.n],
>
> A.colptr[2:*(*A.n+1*)*], x, &beta, y*)*
>
>
> println*(*y*)*
>
I also get alpha * A * x + beta * y and y being the same, which indicates
the code is working properly (as mkl_dcscmv sets y = alpha * A * x + beta *
y).
However, if I take the above code, and plug it into a function, the code
breaks.
*function* mklmatmul*()*
>
> Tv *=* Float*64*
>
>
> n *=* *10*
>
>
> transa *=* *'**N**'*
>
> A *=* speye*(**10**)*
>
> x *=* StridedVector{Tv}*(*randn*(*n*))*
>
> y *=* StridedVector{Tv}*(*zeros*(*n*))*
>
> alpha *=* *(*Tv*)(**1**)*
>
> beta *=* *(*Tv*)(**0**)*
>
> matdescra *=* ASCIIString*(**"SLNF"**)*
>
>
> println*(*alpha *** A *** x *+* beta *** y*)*
>
>
> ccall*((*:mkl_dcscmv, *"libmkl_rt"**)*, Void,
>
> *(*Ptr{UInt8}, Ptr{Int64}, Ptr{Int64}, Ptr{Tv},
>
> Ptr{UInt8}, Ptr{Tv}, Ptr{Int64}, Ptr{Int64},
>
> Ptr{Int64}, Ptr{Tv}, Ptr{Tv}, Ptr{Tv}*)*,
>
> &transa, &A.m, &A.n, &alpha,
>
> matdescra, A.nzval, A.rowval, A.colptr[1:A.n],
>
> A.colptr[2:*(*A.n+1*)*], x, &beta, y*)*
>
>
> *return* y
>
>
> end
>
ccall breaks and I get the error:
> *ERROR: error interpreting ccall argument tuple*
>
> * in mklmatmul at /home/serbanstan/julia-0.4.3/mklmatmul.jl:19*
>
However, if I replace Tv with Float64 everywhere in the program, ccall
works in the second case as well.
I don't have any good explanation for this - I was just guessing that Tv
needs to somehow be global to be correctly read by ccall, but this is just
a hunch. Is this correct? Or is something else going on here.