# An efficient way to convert between MKL and Armadillo types

We use Armadillo a lot in our code but there are places where we prefer to use MKL directly from Vector Math Library. We have cx_vec i.e. vector of doubles. But the exp function of armadillo uses std::exp which is not great so we started using MKL for it. The problem comes when converting cx_vec into MKL_Complex16 arrays and back. The method works but I am not sure if there is a better way to do it or a recommended way. Is there a better way to use MKL from Armadillo? Here is the example of code we use currently. Note the cast at the begining and a copy at the end which is what I would like to rewrite. Any suggestion is welcome.

void Exp_MKL(const cx_vec& VectorInput, cx_vec& VectorOutput) {
if (VectorInput.size() != VectorOutput.size())
VectorOutput.set_size(VectorInput.size());

const MKL_Complex16* in = reinterpret_cast<const MKL_Complex16*>(VectorInput.memptr());
const int size = VectorInput.n_elem;
MKL_Complex16* out = (MKL_Complex16*) mkl_malloc(size * sizeof(MKL_Complex16), 64);

VZEXP(&size, in, out);
cx_vec newoutput(reinterpret_cast<cx_double*>(out), VectorInput.size(), false);
VectorOutput = newoutput;
mkl_free(out);
}

• Couldn't you just give the VZEXP function the memptr in the VectorOutput? That would remove the allocations. – LKlevin May 6 '14 at 20:15
• I suppose that should work. Thanks.Is this what you are referring to? VZEXP(&size, (MKL_Complex16*)VectorInput.memptr(), (MKL_Complex16*)VectorOutput.memptr()); – Sai Venkat May 7 '14 at 3:30
• Yop. You may want to check that the output and input sizes are the same, but other than that. – LKlevin May 7 '14 at 6:41

Note that Armadillo's cx_double (which is used by cx_vec) is just an alias for std::complex<double>, so in fact you're converting between std::complex<double> and MKL_Complex16. The only requirement for the reinterpret_cast to behave as expected is the compatibility of memory layouts of the involved structures -- in this case they are compatible. The MKL User Guide even has an example where MKL_Complex16 is redefined to std::complex<double>, in which case there is no need to do the casts manually and you can just pass the Armadillo pointers directly.