cusolverDnDsyevd eigenvectors transposed?


I’m having a ball with the cuSolver routines–faster than MAGMA by a significant margin in all the ways that I’m keen on using, and also more stable (in that they have never crashed on me, whereas MAGMA dsyevd has crashed a lot).

However, when I look at the results returned from cusolverDnDsyevd, expecting to find the eigenvectors in the erstwhile matrix memory space, I find that the vectors appear to have been transposed relative to what GNU octave produces (and which appear to be valid eigenvectors). The original matrix was symmetric, so transposing the input is not the issue. Is this expected behavior?

The code I am using is attached. Run with ./cusolver_example -rank 8 -spy to see results…

Dave Cerutti
cusolver_example.cpp (4.3 KB)

Some suggestions:

  1. Don’t post code as an attachment. It makes it more difficult to do a quick inspection. The forum has facilities for posting code in-line with your question. It also makes the code searchable, which is a generally useful feature for the community.

  2. Don’t make test cases dependent on extraneous libraries if it can be avoided. Using armadillo means that in order to run your test case, I have to find out what armadillo is, and how to install it.

These are just suggestions of course. Do as you wish. If you make it easy for me to help you, I’m more likely to do so.

`cusolverDnDsyevd computes V, not V^H, matrices column-major and the result is compatible with NetLib’s SYEVD.

I guess Armadillo is a wrapper on top of LAPACK, so maybe there is some confusion around the data layouts? (i.e. how the data is created / initialized / printed).

Recommend initializing the array A with a simple 2x2 matrix by hand to debug the problem.

BTW, you do not copy the matrices to/from the device, for max performance, specially on small matrices, the data must be ready on the device before calling any math lib API.

Just a sanity check before we deep dive into it, please double check that the printed output (line 121 of your sample code, using the spy flag) follows the Column-major convention, i.e. each eigen-vector should occupy a column in the output matrix. You may be printing it transposed (each vector on a row) and use the same for the compared values on other software.

Thanks to all for their input. I will try to post code inline in the future, and remove dependencies such as armadillo to make it as easy as possible to compile and see what might be wrong. I think that the column-major Fortran convention may be winning, here, and since the matrix is initially symmetric it can just assume that it is in column-major order and produce a result as such. However, I was expecting to read the matrix in row-major order, i.e. every nth value produces the next element of an eigenvector for an n x n matrix.