xtensor-stack / xtensor-blas

BLAS extension to xtensor
BSD 3-Clause "New" or "Revised" License
155 stars 54 forks source link

Build with `-DMKL_ILP64` fails. #209

Open hansenms opened 2 years ago

hansenms commented 2 years ago

Build does not work when using 64 bit integer C API.

To repro, create a simple test program (saved as temp/xtensor_blas_test.cpp):

#include "xtensor-blas/xlinalg.hpp"
#include <complex>
#include <iostream>
#include <xtensor/xarray.hpp>
#include <xtensor/xio.hpp>

int main(int argc, char** argv) {
  xt::xarray<std::complex<float>> my_array = xt::ones<std::complex<float>>({10, 10});
  auto norm = xt::linalg::norm(my_array);
  std::cout << "Array Norm: " << norm << std::endl;
}

If you build with:

g++ -o temp/xt-blas -DHAVE_CBLAS=1 -m64 -I"${MKLROOT}/include" -L${MKLROOT}/lib/intel64 -Wl,--no-as-needed -lmkl_intel_lp64 -lmkl_sequential -lmkl_core -lpthread -lm -ldl temp/xtensor_blas_test.cpp

This works, however, if you build with:

g++ -o temp/xt-blas -DHAVE_CBLAS=1 -DMKL_ILP64 -m64 -I"${MKLROOT}/include" -L${MKLROOT}/lib/intel64 -Wl,--no-as-needed -lmkl_intel_ilp64 -lmkl_sequential -lmkl_core -lpthread -lm -ldl temp/xtensor_blas_test.cpp

The build fails with:

In file included from /usr/local/include/xflens/cxxlapack/interface/interface.tcc:89,
                 from /usr/local/include/xflens/cxxlapack/cxxlapack.tcc:36,
                 from /usr/local/include/xflens/cxxlapack/cxxlapack.cxx:37,
                 from /usr/local/include/xtensor-blas/xlapack.hpp:24,
                 from /usr/local/include/xtensor-blas/xlinalg.hpp:31,
                 from temp/xtensor_blas_test.cpp:1:
/usr/local/include/xflens/cxxlapack/interface/gesdd.tcc: In instantiation of ‘IndexType cxxlapack::gesdd(char, IndexType, IndexType, std::complex<float>*, IndexType, float*, std::complex<float>*, IndexType, std::complex<float>*, IndexType, std::complex<float>*, IndexType, float*, IndexType*) [with IndexType = int]’:
/usr/local/include/xtensor-blas/xlapack.hpp:370:50:   required from ‘auto xt::lapack::gesdd(E&, char) [with E = xt::xarray_container<xt::uvector<std::complex<float>, std::allocator<std::complex<float> > >, xt::layout_type::column_major, xt::svector<long unsigned int, 4, std::allocator<long unsigned int>, true>, xt::xtensor_expression_tag>; std::enable_if_t<xtl::is_complex<typename T::value_type>::value>* <anonymous> = 0]’
/usr/local/include/xtensor-blas/xlinalg.hpp:120:47:   required from ‘auto xt::linalg::norm(const xt::xexpression<D>&, int) [with E = xt::xarray_container<xt::uvector<std::complex<float>, std::allocator<std::complex<float> > >, xt::layout_type::row_major, xt::svector<long unsigned int, 4, std::allocator<long unsigned int>, true>, xt::xtensor_expression_tag>]’
/usr/local/include/xtensor-blas/xlinalg.hpp:209:24:   required from ‘typename E::value_type xt::linalg::norm(const xt::xexpression<D>&) [with E = xt::xarray_container<xt::uvector<std::complex<float>, std::allocator<std::complex<float> > >, xt::layout_type::row_major, xt::svector<long unsigned int, 4, std::allocator<long unsigned int>, true>, xt::xtensor_expression_tag>; typename E::value_type = std::complex<float>]’
temp/xtensor_blas_test.cpp:9:40:   required from here
/usr/local/include/xflens/cxxlapack/interface/gesdd.tcc:144:26: error: cannot convert ‘int*’ to ‘const INTEGER*’ {aka ‘const long int*’}
  144 |                         &m,
      |                          ^
      |                          |
      |                          int*
In file included from /usr/local/include/xflens/cxxlapack/netlib/netlib.h:25,
                 from /usr/local/include/xflens/cxxlapack/interface/bbcsd.tcc:39,
                 from /usr/local/include/xflens/cxxlapack/interface/interface.tcc:36,
                 from /usr/local/include/xflens/cxxlapack/cxxlapack.tcc:36,
                 from /usr/local/include/xflens/cxxlapack/cxxlapack.cxx:37,
                 from /usr/local/include/xtensor-blas/xlapack.hpp:24,
                 from /usr/local/include/xtensor-blas/xlinalg.hpp:31,
                 from temp/xtensor_blas_test.cpp:1:
/usr/local/include/xflens/cxxlapack/netlib/interface/lapack.in.h:818:39: note:   initializing argument 2 of ‘void cxxlapack::cgesdd_(const char*, const INTEGER*, const INTEGER*, cxxlapack::FLOAT_COMPLEX*, const INTEGER*, cxxlapack::FLOAT*, cxxlapack::FLOAT_COMPLEX*, const INTEGER*, cxxlapack::FLOAT_COMPLEX*, const INTEGER*, cxxlapack::FLOAT_COMPLEX*, const INTEGER*, cxxlapack::FLOAT*, cxxlapack::INTEGER*, cxxlapack::INTEGER*)’
  818 |                     const INTEGER    *M,
      |                     ~~~~~~~~~~~~~~~~~~^
hxhc commented 1 year ago

I think it should be intel_lp64 instead of il64. As intel doc said, lp64 may be for better compatibility.

The LP64 interface provides compatibility with the previous Intel® oneAPI Math Kernel Library versions because "LP64" is just a new name for the only interface that the Intel® oneAPI Math Kernel Library versions lower than 9.1 provided. Choose the ILP64 interface if your application uses Intel® oneAPI Math Kernel Library for calculations with large data arrays or the library may be used so in the future.