in my quest to solve eigenvector problems of symmetric, real matrices quickly (I only need the first N eigenvalues and vectors, where "first" refers to the one with largest (real) value), I'm trying to get ARPack++ running on Windows. I use MSVS 2010 for development.
I'm currently in linker hell. I'm also not a 99 years C++ professional who eats bits for breakfast.
First, ARPACK++ is a header-only library, that's good! It depends on ARPACK, and ARPACK again has required dependencies on BLAS and LAPACK. Luckily, for windows users, the .lib and .dll files are available for BLAS, LAPACK and ARPACK, and ARPACK++ has been patched such that it works with modern compilers (and includes some bug-fixes).
As it seems, ARPACK++ introduces the required dependency to the SuperLU library. This is because, in my case I need to use the
ARluSymStdEig<ARFLOAT> prob(nev, matrix, which, ncv, tol,
maxit, resid, AutoShift);
class/CTOR, which has "lu" in its name, and I do indeed get missing symbols.
The next thing I tried was to grab the SuperLU library from around that time (2000ish), which is SuperLU 2.0. This one can be compiled using MSVS2010 directly (compared to ARPACK for example which has to be compiled with MinGW/MSys, unless you pay for Intel's FORTRAN compilers). I included the static superlu2.lib I created, but it seems SuperLU itself has methods that are just declared but not implemented, particularly
void cusolve(int, int, complex*, complex*);
void clsolve(int, int, complex*, complex*);
void cmatvec(int, int, int, complex*, complex*, complex*);
in cgstrs.c. Now I'm stuck and don't know how to continue :/ It seems like SuperLU has dependencies again, but they're not mentioned.
It turns out all I forgot to do was to add not only all .c and .h files from "src" of SuperLU to the VS project, but ALSO add the files from "cblas" directory. All dependencies are thus solved.
Related
I'm doing some work in C++ on Fibonacci numbers which quickly grow out of bounds and I can't use them anymore. I need big integer functionality, which is not built in to C++ and int primitives aren't good enough.
I've found a few libraries that work with big ints, like GMP and CLN (the C++ Library for Numbers) but the installation instructions don't make sense to me.
How would I install GMP to work on windows 10? I use Codeblocks to write and build and run everything and my compiler is MinGW which is in my C:\ directory. How do I add GMP so that I can #include the library in a codeblocks C++ project?
I am a moron, and I require step by step instructions down to "download the file in this directory, move the .lib file into this directory, etc". I am not capable of understanding the given instructions for installation on the GMP website.
I'm developing a large software package consisting of many packages which are compiled to shared objects. For performance reasons, I want to compile Eigen 3 (a header-only library) with vector instructions, but the templated methods are being compiled all over the place. How can I ensure that the Eigen functions are compiled into a specific object file?
This software consists of ~2000 individual packages. To keep development going at a reasonable pace, the recommended way of compiling the program is to sparsely check out some of the packages and compile them, after which the program can be executed using precompiled (by some CI system) shared libraries.
The problem is that part of my responsibility is to optimise the CPU time of the program. In order to do so, I wanted to compile the package I am working on (let's call it A.so) with the -march flag so Eigen can exploit modern SIMD processor extensions.
Unfortunately, because Eigen is a header-only library, the Eigen functions are compiled into many different shared objects. For example, one of the most CPU intensive methods called in A.so is the matrix multiplaction kernel which is compiled in B.so. Many other Eigen functions are compiled into C.so, D.so, etc. Since these objects are compiled for older, more widely implemented instruction set extensions, they are not compiled with AVX, AVX2, etc.
Of course, one possible solution is to include packages B, C, D, etc. into my own sparse compilation but this negates the advantage of compiling only a part of the project. In addition, it leaves me including ever more and more packages if I really want to vectorise all linear algebra operations in the code of package A.
What I am looking for is a way to compile all the Eigen functions that package A uses into A.so, as if the Eigen functions were defined with the static keyword. Is this possible? Is there some mechanism in the compiler/linker that I can leverage to make this happen?
One obvious solution is to hide these symbols. This happens (if I understand the problem properly) because these functions are exported and can be used by other subsequently loaded libraries.
When you build your library and link against the other libraries, the linker reuses what it can. And the old packages as well. I hope you don't require these libraries for your own build?
So two options:
Force the loading of A before the other libraries (but if you need the other libraries, I don't think this is doable),
Tell the linker that these functions should not be visible by other libraries (visibility=hidden by default).
I saw something similar happening with a badly compiled 3rd-party library. It was built in debug mode, shipped in the product, and all of a sudden one of our libraries experienced a slow down. The map files identified where the culprit debug function came from, as it exported all its symbols by default.
An alternative way to change visibility without modifying the code is to filter symbols during linking stage using version scripts -> https://sourceware.org/binutils/docs/ld/VERSION.html. You'll need something like
{
global: *;
local:
extern "C++"
{
Eigen::*;
*Eigen::internal::*;
};
};
I am using pre-built 3.2.5 Eigen lib files, downloaded from website:
http://eigen.tuxfamily.org/index.php?title=Main_Page
I heard if I built the files by myself on my PC I could achieve higher compatibility with my processor what would lead to slight increase of lib's performance. Currently I am struggling with eigensolver calculation time being too long.
I use Visual Studio 2005 and I just add Eigen files location to my projects properties linker.
Is there any way to build those files myself on my platform? I am a bit confused how could I do it. Is it related to CMake?
There is no library to build, as Eigen is a "pure template header library". From the main site:
Requirements
Eigen doesn't have any dependencies other than the C++ standard
library.
We use the CMake build system, but only to build the documentation and
unit-tests, and to automate installation. If you just want to use
Eigen, you can use the header files right away. There is no binary
library to link to, and no configured header file. Eigen is a pure
template library defined in the headers.
You don't need to add the files location to the linker, but to the (additional) included directories in your project or to a property sheet.
Regarding calculation time, make sure you're running in Release and not Debug. There is a difference of about 100 in the speed. Also, make sure that optimizations are turned on (/O2 or /Ox).
Some projects provide a single set of "Windows" binaries for C (and possible C++ - not sure) libraries. For example, see the links on the right side of this libxml-related page.
I'm pretty sure there's no way to convert between VC++ .lib files and MinGW GCC .a files, so calling them "Windows" rather than "Microsoft" binaries seems a tad misleading. But I'm also surprised that there's no apparent need for different binaries for different VC++ versions.
I seem to remember, many years ago, having problems writing plugins for tracker-style music program (Jeskola Buzz) because that program was using VC++6, and I had upgraded to VC++7. I don't remember the exact issue - it may have been partly DLL related, but I know those don't need to care about VC++ version. I think the issue related to the .lib files provided and maybe also to the runtime libraries that they linked to. It was a long while ago, though, so it's all a bit vague.
Anyway, can libraries compiled by one version of MS VC++ be linked into projects built with another version? What limitations apply, if any?
I'm interested in both C and C++ libraries, which will be called from C++ projects (I rarely use C, except for C libraries called from C++).
The MS COFF format (.lib, .obj, etc) is the same for all VC++ versions and even for other languages.
The problem is that .obj files depend on other .obj (.lib) files.
For C++ code, there is a happy chance that code won't compile with new version of VC++ standard library implementation. For example, an old version of CRT used extern "C++" void internal_foo(int), and newer CRT uses extern "C++" void internal_foo(int, int), so linker will fail with "unresolved external symbol" error.
For C code, there is a chance that code will compile, because for extern "C", symbol names doesn't encode whole signature. But at runtime application will crash after this function will be called.
The same thing can happen if layout of some data structure will change, linker will not detect it.
I just installed GSL and BLAS on Visual Studio 2010 successfully using this guide:
However the matrix multiplications using cblas are ridicously slow. A friend on Linux had the same problem. Instead of linking via GSL to BLAS, he linked directly to cBLAS (I don't exactly understand what this means but maybe you do?) and it got about ten times as fast.
How can I do this in Visual Studio? In the file I downloaded I couldn't find any more files that I could build with Visual Studio.
BLAS was the fortran mathematics library of simple operations, like multiplying or adding vectors and matrices. It implemented the vector-vector, vector-matrix, and matrix-matrix operations.
Later, different libraries was created which do the same as original BLAS but with more performance. The interface was saved, so you can use any of BLAS-compatible library, e.g. from your CPU vendor.
This FAQ http://www.netlib.org/blas/faq.html has some libraries listed; wikipedia has another list: http://en.wikipedia.org/wiki/Basic_Linear_Algebra_Subprograms
The only problem with GSL - is in using C language. Interface of BLAS may be converted to C in various ways (the problem is in fortran functions name translation to c functions name, e.g. fortran DGEMM may be called DGEMM or DGEMM in C). GSL uses CBLAS convention: cblas_ prefix, e.g. GEMM will be named cblas_gemm.
So, try some libraries, from the lists, and check, is there cblas_ function aliases in the library. If yes, gsl may use this library.