1
$\begingroup$

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

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.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.