I'm trying to write a program in C++, using ScaLAPACK directly. In that way, I'm calling its functions through extern "C" block and it's working, until I came around PDLAPRNT() function, i.e. a printing of double arrays.
When I'm trying to run it to print a simple 9-element-long array, I'm getting the following error:
/usr/bin/mpirun --oversubscribe -n 6 ./ex3print
Operating system error: Cannot allocate memory
Memory allocation failure in xrealloc
--------------------------------------------------------------------------
Primary job terminated normally, but 1 process returned
a non-zero exit code. Per user-direction, the job has been aborted.
--------------------------------------------------------------------------
--------------------------------------------------------------------------
mpirun detected that one or more processes exited with non-zero status, thus causing
the job to be terminated. The first process to do so was:
Process name: [[10150,1],0]
Exit code: 1
--------------------------------------------------------------------------
Process finished with exit code 1
Do you have any idea, what I'm doing wrong? I guess, my "mapping" of the original FORTRAN function is incorrect, but I have no idea why.
FORTRAN Signature
SUBROUTINE pdlaprnt( M, N, A, IA, JA, DESCA, IRPRNT, ICPRNT, CMATNM, NOUT, WORK )
Where, M, N, IA, JA, IRPRNT, ICPRNT and NOUT are of type INTEGER, A and WORK are DOUBLE PRECISION arrays, DESCA is an INTEGER array and finally CMATNM is of type CHARACTER*(*).
My C++ "interface"
extern void pdlaprnt_(int *m, int *n, double *A, int *iA, int *jA, int *descA, int *irprnt, int *icprnt, char *cmatnm,
int *nout, double *work);
My code
#include <iostream>
extern "C" {
extern void sl_init_(int *ictxt, int *nprow, int *npcol);
extern void blacs_gridexit_(int *ictxt);
extern void blacs_gridinfo_(int *ictxt, int *nprow, int *npcol, int *myrow, int *mycol);
extern void blacs_exit_(int *cont);
extern void descinit_(int *desc, int *m, int *n, int *mb, int *nb, int *rsrc, int *csrc, int *ictxt, int *mxllda,
int *info);
extern void pdlaprnt_(int *m, int *n, double *A, int *iA, int *jA, int *descA, int *irprnt, int *icprnt, char *cmatnm,
int *nout, double *work);
}
/* BLACS context handle */
int ictxt = 0;
/* Number of rows and columns of the process grid */
int nprow = 2;
int npcol = 3;
/* Row and column indices in a process grid */
int myrow, mycol;
/* Row and column block size */
int mb = 2;
int nb = 2;
int nbrhs = 1;
/* Array descriptors for the global matrices */
int* descB = (int*)malloc(sizeof(int) * mb);
/* Number of right-hand sides b */
int nrhs = 1;
/* Process row and column over which the first row of the array A is distributed */
int rsrc = 0;
int csrc = 0;
/* Leading dimension of the local array */
int mxlldb = 5;
/* Allocate b array */
double* b = (double*)malloc(sizeof(double) * mxlldb);
/* Return code */
int info;
/* BLACS continue code */
int continue_code = 0;
int main(){
/* Initialize the process grid */
sl_init_(&ictxt, &nprow, &npcol);
blacs_gridinfo_(&ictxt, &nprow, &npcol, &myrow, &mycol);
/* Initialize array descriptors */
descinit_(descB, &nb, &nrhs, &nb, &nbrhs, &rsrc, &csrc, &ictxt, &mxlldb, &info);
/* Init b vector */
for(unsigned int i = 0; i < 9; i++) {
b[i] = 6;
}
int iB = 1, jB = 1;
double* work = (double*)malloc(sizeof(double) * mxlldb);
int irprnt = 0;
int icprnt = 0;
char* cmatnm = (char*)"B";
int nout = 6;
/* Print RHS b */
pdlaprnt_(&nb, &nrhs, b, &iB, &jB, descB, &irprnt, &icprnt, cmatnm, &nout, work);
/* Free BLACS context */
blacs_gridexit_(&ictxt);
/* Exit BLACS */
blacs_exit_(&continue_code);
return 0;
}