Thanks for the help so far, I'm still having some trouble and need some clarification.
The code I have so far (which I've pasted at the bottom of this reply), which is based on examples provided with the installation, has a seg fault which I'd like some help resolving. I've located the error at the point where I assign values to the 'val' vector at line 43 (the nnz elements of my matrx). I've tried several things but maybe there's something obvious I'm doing wrong (I'm not used to working in C).
Also, I have a couple of more general questions:
1. Is calling the routine magma_z_solver equivalent to calling the routine corresponding to the solver parameters?
2. zlobpcg doesn't seem to have output parameters in its documentation, does it return the eigenvalues as opposed to its error code?
3. Does zlobpcg not calculate eigenvectors at all?
4. I'm used to seeing routines that handle Hermitian or symmetric matrices take a parameter that specifies whether the input matrix is lower or upper triangular, to save memory by only having to create one half of the matrix. Does zlobpcg not do this or does it just do one or the other as a default?
Code: Select all
//Compiles with the corresponding makefile.
//Takes in the 3 vectors of CSR format, creates MAGMA format sparse matrix, returns its spectrum.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "magma_v2.h"
#include "magmasparse.h"
int main()
{
//Setup
int n = 3; //Dimension of the nxn matrix
magmaDoubleComplex *sol;
//Testing with matrix {{4,1-i,2+i},{1+i,-1,1},{2-i,1,3}} that has spectrum {6.08807,-1.61431,1.52624}
int *col; //Column indices of NNZ in A
col = (int*) calloc(n*n, sizeof(int));
col[0] = 0; col[1]=1; col[2] = 2;
col[3] = 0; col[4]=1; col[5] = 2;
col[6] = 0; col[7]=1; col[8] = 2;
int *row; //Row pointer of NNZ in A
row = (int*) calloc(n+1, sizeof(int));
row[0] = 0; row[1] = 3; row[2] = 6; row[3] = 9;
//NNZ of the matrix A:
magmaDoubleComplex *val;
magma_zmalloc(&val, 9);
if (val == NULL)
{
fprintf( stderr, "malloc failed\n" );
return 0;
}
else
{
fprintf( stderr, "malloc succeeded\n" );
}
val[0] = MAGMA_Z_MAKE(4,0);
// val[1] = MAGMA_Z_MAKE(1,-1); val[2] = MAGMA_Z_MAKE(2,1);
// val[3] = MAGMA_Z_MAKE(1,1); val[4] = MAGMA_Z_MAKE(-1,0); val[5] = MAGMA_Z_MAKE(1,0);
// val[6] = MAGMA_Z_MAKE(2,-1); val[7] = MAGMA_Z_MAKE(1,0); val[8] = MAGMA_Z_MAKE(3,0);
printf("val created successfully\n");
//Initialize MAGMA
magma_init();
magma_zopts opts;
magma_queue_t queue;
magma_queue_create(0, &queue);
magma_z_matrix A={Magma_CSR}, dA={Magma_CSR};
magma_z_matrix b={Magma_CSR}, db={Magma_CSR};
magma_z_matrix x={Magma_CSR}, dx={Magma_CSR};
//Pass the system to MAGMA
magma_zcsrset(n,n,row,col,val,&A,queue);
// Choose a solver, preconditioner, etc. - see documentation for options.
opts.solver_par.solver = Magma_LOBPCG; // choose an LOBPCG solver
opts.solver_par.num_eigenvalues = 3; // number of eigenvalues you want to compute
opts.solver_par.maxiter = 1000; // max number of iterations
opts.solver_par.rtol = 1e-10; // stopping criterion - relative accuracy of first eigenvalue
opts.precond_par.solver = Magma_ILU; // preconditioner
opts.precond_par.levels = 0; // ILU(0) - no fill-in
opts.precond_par.trisolver = Magma_CUSOLVE; //exact triangular solves
//Copy the system to device
magma_zmtransfer(A, &dA, Magma_CPU, Magma_DEV, queue);
//Generate the preconditioner
magma_z_precondsetup(dA, db, &opts.solver_par, &opts.precond_par, queue);
//Calling zlobpcg to find eigenvalues
magma_z_solver(dA, db, &dx, &opts, queue);
// magma_zlobpcg(A, &opts, &opts, queue);
//Then copy the solution back to the host
magma_zmfree( &x, queue );
magma_zmtransfer( dx, &x, Magma_CPU, Magma_DEV, queue );
//and back to the application code
magma_zvget( x, &n, &n, &sol, queue );
//Free the allocated memory...
magma_zmfree( &dx, queue );
magma_zmfree( &db, queue );
magma_zmfree( &dA, queue );
//and finalize MAGMA.
magma_queue_destroy( queue );
magma_finalize();
//Output
int i;
for (i = 0; i < n; ++i) {
printf("%.4f\n", sol[i]);
}
printf("\n\n\n\n");
return 0;
}
Compiled with the makefile:
Code: Select all
default:
gcc -Wall -DADD_ -I/usr/local/magma/include -I/usr/local/magma/sparse/include -I/usr/local/cuda/include -c -o Magma.o Magma.c
gcc -Wall -o Magma Magma.o -L/usr/local/magma/lib -lmagma_sparse -lmagma -L/usr/local/cuda/lib64 -lcublas -lcudart -lcusparse -L/usr/local/openblas/lib -lopenblas
Sorry if I'm being a bit demanding but thanks for the help so far.