Error when using MKL and Eigen LAPACK simultaneously - c++

I am trying to run SVD from the Eigen library with MKL but get the following errors
In file included from blas_mkl.cpp:6:
In file included from /usr/local/include/eigen3/Eigen/SVD:11:
In file included from /usr/local/include/eigen3/Eigen/QR:45:
/usr/local/include/eigen3/Eigen/src/QR/ColPivHouseholderQR_LAPACKE.h:85:1: error: cannot initialize a variable of type 'long long *' with an rvalue of type
'Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >::Scalar *' (aka 'int *')
EIGEN_LAPACKE_QR_COLPIV(double, double, d, ColMajor, LAPACK_COL_MAJOR)
...
/usr/local/include/eigen3/Eigen/src/QR/ColPivHouseholderQR_LAPACKE.h:74:15: note: expanded from macro 'EIGEN_LAPACKE_QR_COLPIV'
lapack_int *perm = m_colsPermutation.indices().data(); \
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8 errors generated.
I have the latest version of MKL, and my cpp file is
//blas_mkl.cpp
#define EIGEN_USE_MKL_VML
#define EIGEN_USE_LAPACKE
#include <iostream>
#include <eigen3/Eigen/Core>
#include <eigen3/Eigen/SVD>
using namespace Eigen;
using namespace std;
int main() {
MatrixXf data(4, 2);
data << 76, 8,
0, 0,
82, 3,
80, 0;
JacobiSVD<MatrixXf> svd(data, ComputeThinU | ComputeThinV);
cout << svd.matrixU() * svd.singularValues().asDiagonal() * svd.matrixV().transpose() << endl;
cout << data << endl;
return 0;
}
and I use the following command to run the code
g++ -DMKL_ILP64 -m64 -I${MKLROOT}/include ${MKLROOT}/lib/libmkl_intel_ilp64.a ${MKLROOT}/lib/libmkl_intel_thread.a ${MKLROOT}/lib/libmkl_core.a -liomp5 -lpthread -lm -ldl -o blas_mkl blas_mkl.cpp
where echo ${MKLROOT} gives
/opt/intel/compilers_and_libraries_2020.2.258/mac/mkl
But the code actually works fine when I keep only #define EIGEN_USE_MKL_VML, but I get segmentation fault 11 when I keep the LAPACKE. Can someone tell me what's going on here?

I see the option -DMKL_ILP64 in your command line. Under ILP64, MKL_INT and lapack_int are type aliases for long long, under LP64 they are aliases for int. Hence, the error message (though it is not clear how it is related to a segfault): you can't assign int* to long long*. But the Eigen documentation states that only LP64 is supported (emphasis is mine):
Using Intel MKL through Eigen is easy:
define the EIGEN_USE_MKL_ALL macro before including any Eigen's header, link your program to MKL libraries (see the MKL linking advisor), on a 64bits system, you must use the LP64 interface (not the ILP64 one).
Try to remove -DMKL_ILP64 flag and link against LP64 library version.

Related

Compiler, library, or user error? Eigen::Array, GCC 12.1, "array subscript [...] is partly outside array bounds"

After updating to GCC 12.1, I got a array subscript ‘__m256d_u[0]’ is partly outside array bounds error (or rather warning with -Werror) in my project, so I tried isolating the problem.
Here's an MWE, which I also put on godbolt (vector type is __m512d_u instead, but otherwise it's the same error):
#include <Eigen/Dense>
#include <iostream>
using Eigen::Array;
Array<double, 3, 2> foo(){
Array<double, 2, 2> a;
a.setRandom();
Array<double, 3, 2> b;
b.col(0).tail(2) = a.col(1);
// b.col(0).template tail<2>() = a.col(1);
return b;
}
int main(){
std::cout << foo() << '\n';
return 0;
}
Relevant compile options are -Wall -Wextra -Werror -O3 -march=native, and the error message notes note: at offset [16, 24] into object ‘a’ of size 32.
The error does not occur under the following circumstances:
on GCC 11.3 or older,
when removing -march=native
when using -O1 or below
when replacing the line b.col(0).tail(2) = a.col(1); with b.col(0).template tail<2>() = a.col(1);
So it looks like GCC sees the 3x2 array and the 2x2 array, and doesn't realise that only two entries are accessed each.
My question now is: Who should this be reported to? GCC, Eigen? Or is it a user bug?
Bonus points for telling me what the 24 in the error note (offset [16, 24]) is. The 16 is the start, is the 24 the read size?
EDIT: Example can be further simplified by using Array3d and Array2d, see here.

Eigen with -O3 warning: argument 1 value ‘X’ exceeds maximum object size Y

What happens
When I try to add an Eigen::Vector3f into an std::vector following the tutorial on Eigen website like this:
#include <Eigen/Core>
#include <Eigen/StdVector>
#include <iostream>
template <class EigenT>
using EigenStdVector = std::vector<EigenT, Eigen::aligned_allocator<EigenT>>;
int main() {
EigenStdVector<Eigen::Vector3f> vec;
vec.emplace_back(1.0f, 1.0f, 1.0f);
std::cerr << vec.back().transpose() << std::endl;
return 0;
}
I get the following warning:
In file included from /usr/include/eigen3/Eigen/Core:349:0,
from /home/igor/Code/eigen_example/example.cpp:3:
In function ‘void* Eigen::internal::aligned_malloc(std::size_t)’,
inlined from ‘void std::vector<_Tp, _Alloc>::_M_realloc_insert(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {float, float, float}; _Tp = Eigen::Matrix<float, 3, 1>; _Alloc = Eigen::aligned_allocator<Eigen::Matrix<float, 3, 1> >]’ at /usr/include/eigen3/Eigen/src/Core/util/Memory.h:742:76:
/usr/include/eigen3/Eigen/src/Core/util/Memory.h:159:12: warning: argument 1 value ‘18446744073709551612’ exceeds maximum object size 9223372036854775807 [-Walloc-size-larger-than=]
result = std::malloc(size);
How to reproduce
I am on Ubuntu 18.04 and have Eigen 3.3.4 installed.
You can build the code in this question with the following command if you have Eigen installed with the following command:
g++ -I/usr/include/eigen3 -O3 example.cpp
What triggers the warning
The warning only shows when using Vector2f, Vector3f, etc. It is not shown for types like Matrix2f, Matrix3f, etc.
The warning is shown whenever I have -O[1-3] enabled and does not happen with -O0
Further info:
This question seems to be related, but I don't see how it could help me.
I have made a small example for everyone who wants a ready-to-run example. You can find it on my GitHub.
Does anybody have an idea what might be wrong here?
In the file Eigen/src/Core/util/Memory.h in the implementation of Eigen::aligned_allocator these lines can be found:
#if EIGEN_COMP_GNUC_STRICT && EIGEN_GNUC_AT_LEAST(7,0)
// In gcc std::allocator::max_size() is bugged making gcc triggers a warning:
// eigen/Eigen/src/Core/util/Memory.h:189:12: warning: argument 1 value '18446744073709551612' exceeds maximum object size 9223372036854775807
// See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87544
size_type max_size() const {
return (std::numeric_limits<std::ptrdiff_t>::max)()/sizeof(T);
}
#endif
So, it seems that this is connected to this GCC bug.
As far as I can see, the commit fixing this appeared on 2018-10-07, and should be available in Eigen 3.3.6.

Problems compiling C++ programs with wineg++/winelib

I am having trouble compiling C++ programs with wineg++. To illustrate my problem, I have written two test programs.
msgbox.cpp
#include <algorithm>
#include <iterator>
#include <cstdio>
#include <windows.h>
int APIENTRY WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
char buf[30], *pos = buf;
int xs[] = {1,3,2,4,3,5,4,6,5,7,6,8,7,9};
std::sort( std::begin(xs), std::end(xs) );
for (int x : xs) {
pos += std::sprintf(pos, "%d ", x);
}
MessageBox(0, buf, "Hello", 0);
return 0;
}
frame.cpp
#include "../win32xx/include/wxx_wincore.h"
#include "../win32xx/include/wxx_frame.h"
int APIENTRY WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
CWinApp winApp;
CFrame frame;
CWnd view;
frame.SetView(view);
frame.Create();
winApp.Run();
}
The second program uses the Win32++ library, which I can't recommend enough.
Both programs compile and run just fine using a cross-compiler:
okuu% x86_64-w64-mingw32-g++ msgbox.cpp -o msgbox.exe
okuu% wine ./msgbox.exe
okuu% x86_64-w64-mingw32-g++ frame.cpp -o frame.exe -lgdi32 -lcomctl32 -static
okuu% wine ./frame.exe
okuu% rm *exe*
But I want to use winelib so that I can use both the Windows API and Unix libraries. This is what I tried first:
okuu% wineg++ msgbox.cpp -o msgbox.exe
okuu% ./msgbox.exe
okuu% wineg++ frame.cpp -o frame.exe -mwindows
In file included from ../win32xx/include/wxx_appcore.h:57:0,
from ../win32xx/include/wxx_wincore.h:96,
from frame.cpp:1:
../win32xx/include/wxx_appcore0.h:120:12: fatal error: process.h: No such file or directory
#include <process.h>
^~~~~~~~~~~
compilation terminated.
winegcc: g++ failed
Then I read wineg++'s man page, which says:
-mno-cygwin
Use Wine implementation of MSVCRT, instead of linking against the host system libc. This is necessary for the vast majority of Win32 applications, as they typically depend on various features of MSVCRT. This switch is also used by the MinGW compiler to link against MSVCRT on Windows, instead of linking against Cygwin libc. Sharing the syntax with MinGW makes it very easy to write Makefiles that work under Wine, MinGW+MSYS, or MinGW+Cygwin.
So I tried again with -mno-cygwin, and got a 2000-line error message that begins with:
okuu% wineg++ frame.cpp -o frame.exe -mwindows -mno-cygwin
In file included from /usr/include/c++/7.2.1/cstdlib:75:0,
from /usr/include/c++/7.2.1/bits/stl_algo.h:59,
from /usr/include/c++/7.2.1/algorithm:62,
from ../win32xx/include/wxx_appcore0.h:110,
from ../win32xx/include/wxx_appcore.h:57,
from ../win32xx/include/wxx_wincore.h:96,
from frame.cpp:1:
/usr/include/stdlib.h:310:5: error: ‘int32_t’ does not name a type; did you mean ‘wint_t’?
int32_t *fptr; /* Front pointer. */
^~~~~~~
wint_t
/usr/include/stdlib.h:311:5: error: ‘int32_t’ does not name a type; did you mean ‘wint_t’?
int32_t *rptr; /* Rear pointer. */
^~~~~~~
wint_t
/usr/include/stdlib.h:312:5: error: ‘int32_t’ does not name a type; did you mean ‘wint_t’?
int32_t *state; /* Array of state values. */
^~~~~~~
wint_t
/usr/include/stdlib.h:316:5: error: ‘int32_t’ does not name a type; did you mean ‘wint_t’?
int32_t *end_ptr; /* Pointer behind state table. */
^~~~~~~
wint_t
/usr/include/stdlib.h:320:8: error: ‘int32_t’ has not been declared
int32_t *__restrict __result) __THROW __nonnull ((1, 2));
^~~~~~~
So it seems C99's fixed-size integer types are not available. That seems easy enough to solve:
frame.cpp
#include <stdint.h>
#include "../win32xx/include/wxx_wincore.h"
#include "../win32xx/include/wxx_frame.h"
// etc. etc. etc.
And I tried again, but got a different 2000-line error message that begins with:
okuu% wineg++ frame.cpp -o frame.exe -mwindows -mno-cygwin
In file included from /usr/include/c++/7.2.1/cwchar:44:0,
from /usr/include/c++/7.2.1/bits/postypes.h:40,
from /usr/include/c++/7.2.1/bits/char_traits.h:40,
from /usr/include/c++/7.2.1/string:40,
from ../win32xx/include/wxx_appcore0.h:111,
from ../win32xx/include/wxx_appcore.h:57,
from ../win32xx/include/wxx_wincore.h:96,
from frame.cpp:2:
/usr/local/include/wine/msvcrt/wchar.h:398:23: error: conflicting declaration of C function ‘size_t mbstowcs(wchar_t*, const char*, size_t)’
size_t __cdecl mbstowcs(wchar_t*,const char*,size_t);
^~~~~~~~
At this point I have run out of ideas. This is what I have understood so far:
My system's libc and Wine's MSVCRT have conflicting definitions. (This was probably to be expected.)
My system's libc++ is hardwired to work with my system's libc.
Wine comes with a MSVCRT, but not with a C++ standard library implementation.
The logical course of action with the information I have so far would be to look for a C++ standard library implementation that's compatible with Wine's MSVCRT, but I don't know of one. Does anybody here know of one?
The only solution I can think of is to stick with the system libc and write your own process.h. This file should either #include the standard header files that have the functions Win32++ needs or provide its own implementations of those functions. If Win32++ won't compile without a particular function but your program does not actually depend on that function, the implementation of that function can simply return 0 or another fake value.
If the system libc has a header file that Win32++ asks for, but the file does not declare all of the functions that Win32++ expects, you'll have to write a header file such as win32xx-compat.h that defines those functions and #include it before any Win32++ header.

error: 'make_array' is not a member of 'boost::serialization

I am unable to compile a basic boost vector example.
I am on Windows 10, and I am using the nuwen MinGW distro version 15.0, without git included. This version contains GCC 7.10 and Boost 1.64. I have unpacked MinGw and placed it in the root of my file system and I am following the MinGW usage instruction A to run set_distro_paths.bat. Below is the code, which is failing to build on my system:
vector-fail.cpp:
#include <boost/numeric/ublas/vector.hpp>
#include <boost/numeric/ublas/io.hpp>
int main () {
using namespace boost::numeric::ublas;
vector<double> v (3);
for (unsigned i = 0; i < v.size (); ++ i)
v (i) = i;
std::cout << v << std::endl;
}
Makefile:
vector-fail: vector-fail.o
g++ vector-fail.o -o vector-fail
vector-fail.o: vector-fail.cpp
g++ -c vector-fail.cpp -o vector-fail.o
Output:
g++ -c vector-fail.cpp -o vector-fail.o
In file included from C:\MinGW\include/boost/numeric/ublas/vector.hpp:21:0,
from vector-fail.cpp:1:
C:\MinGW\include/boost/numeric/ublas/storage.hpp: In member function 'void
boost::numeric::ublas::unbounded_array<T, ALLOC>::serialize(Archive&, unsigned int)':
C:\MinGW\include/boost/numeric/ublas/storage.hpp:299:33: error: 'make_array' is not a member of 'boost::serialization'
ar & serialization::make_array(data_, s);
^~~~~~~~~~
C:\MinGW\include/boost/numeric/ublas/storage.hpp:299:33: note: suggested alternative: 'make_nvp'
ar & serialization::make_array(data_, s);
^~~~~~~~~~
make_nvp
C:\MinGW\include/boost/numeric/ublas/storage.hpp: In member function 'void boost::numeric::ublas::bounded_array<T, N, ALLOC>::serialize(Archive&, unsigned int)':
C:\MinGW\include/boost/numeric/ublas/storage.hpp:494:33: error: 'make_array' is not a member of 'boost::serialization'
ar & serialization::make_array(data_, s);
^~~~~~~~~~
C:\MinGW\include/boost/numeric/ublas/storage.hpp:494:33: note: suggested alternative: 'make_nvp'
ar & serialization::make_array(data_, s);
^~~~~~~~~~
make_nvp
make: *** [Makefile:5: vector-fail.o] Error 1
Unfortunately none of those errors are occurring within my code, rather they are caused by files within include files within the boost library its self. What changes could be made in application level code or the Makefile to allow the program to compile?
Yes this is an issue with the ublas headers. I ran into it before. You can workaround it by including
#include <boost/serialization/array_wrapper.hpp>
before that point though. I'd consider reporting it to the maintainers of the ublas code.

Why are std::stoi and std::array not compiling with g++ c++11?

I've been learning C++ and using the Terminal for the last couple of months. My code was compiling and running fine using g++ and C++11, but in the last couple of days it started giving errors and I have had problems compiling since. The only programs I can compile and run depend on older C++ standards.
The errors I first got related to #include < array > in the header file. Not sure why this happened, but I got around it by using boost/array instead. Another error I can't solve is with std::stoi. Both array and stoi should be in the C++11 standard library. I made the following simple code to demonstrate what's going on:
//
// stoi_test.cpp
//
// Created by ecg
//
#include <iostream>
#include <string> // stoi should be in here
int main() {
std::string test = "12345";
int myint = std::stoi(test); // using stoi, specifying in standard library
std::cout << myint << '\n'; // printing the integer
return(0);
}
Try to compile using ecg$ g++ -o stoi_trial stoi_trial.cpp -std=c++11
array.cpp:13:22: error: no member named 'stoi' in namespace 'std'; did you mean
'atoi'?
int myint = std::stoi(test);
~~~~~^~~~
atoi
/usr/include/stdlib.h:149:6: note: 'atoi' declared here
int atoi(const char *);
^
array.cpp:13:27: error: no viable conversion from 'std::string' (aka
'basic_string') to 'const char *'
int myint = std::stoi(test);
^~~~
/usr/include/stdlib.h:149:23: note: passing argument to parameter here
int atoi(const char *);
^
2 errors generated.
I also get these errors at compilation when using gcc or clang++ and with -std=gnu++11 (I guess they all depend on the same file structure). I also get the same error whether I specify std:: in the code, or if I specify using namespace std;
I worry that these issues arose because of the September Command Line Tools update via Xcode or because I installed boost and this somehow messed up my C++11 libraries. Hopefully there is a simple solution.
My system:
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-> dir=/usr/include/c++/4.2.1
Apple LLVM version 5.0 (clang-500.2.76) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin12.5.0
Thread model: posix
Thanks for any insight you can offer.
clang has a weird stdlib, you need to add the following flag when you compile
-stdlib=libc++
your snippet works on my mac with
g++ -std=gnu++11 -stdlib=libc++ test.cpp -o test
This answer describes the problem