Archives


- Beowulf
- Beowulf Announce
- Scyld-users
- Beowulf on Debian

LAM: SCALAPACK users?

Many of your questions may have already been answered in earlier discussions or in the FAQ. The search results page will indicate current discussions as well as past list serves, articles, and papers.

Search

Camm Maguire camm at enhanced.com
Wed Aug 30 07:42:56 PDT 2000


Greetings!  The following sample program (matrix definition ommitted),
which implements an inverse iteration method to generate a particular
eigenvector of a matrix, should clarify things, I hope.  Please write
back if I can be of more assistance!

(P.S. One other thing I forgot to mention is that all fortran routines
assume passed matrices are *column-major*.  The code below should
clarify.)  

Take care,

=============================================================================
main.c:
=============================================================================
#include <getopt.h>
#include <math.h>
#include <sys/time.h>
#include <mpi.h>

#define TINY 1.0e-10

[snip]....


static void
mpiend(void) {

  int i;

  i=0;
  blacs_exit__(&i);
  

}

int
main(int argc,char * argv[]) {

  int ic,nr=1,nc=1,mr,mc,N,nb=64,rsrc=0,mxlda,info,i,j,k,np,*iwork;
  int desca[9],descaf[9],descb[9],descv[9],*ipiv,ione=1,lr,lc;
  double **a,**af,**b,**v,*work,*x,*r,*c,rcond,ferr,berr,*q;
  double xi,pp,pa,ps,pc,bx,t,l,l1;
/*    struct timeval tv,tv1; */
  int ch,debug=0,liwork=-1,lwork=-1,izero=0,itwo=2;
  char *f,eq;

  

  MPI_Init(&argc,&argv);
  MPI_Comm_size(MPI_COMM_WORLD,&np);
  if (atexit(mpiend))
    error("Can't setup mpiabort on exit\n");

  nc=nr=(int)sqrt(np);

  sl_init__(&ic,&nr,&nc);
  blacs_gridinfo__(&ic,&nr,&nc,&mr,&mc);
/*    Cblacs_gridinfo(ic,nr,nc,&mr,&mc); */
  
  i=0;
  if (mr<0)
    blacs_exit__(&i);

  pc=1.0;
  
  while ((ch=getopt(argc,argv,"x:i:p:a:s:c:n:d:"))!=EOF)
    switch(ch) {
    case 'x':
      sscanf(optarg,"%lf",&bx);
      break;
    case 'i':
      sscanf(optarg,"%lf",&xi);
      break;
    case 'p':
      sscanf(optarg,"%lf",&pp);
      break;
    case 'a':
      sscanf(optarg,"%lf",&pa);
      break;
    case 's':
      sscanf(optarg,"%lf",&ps);
      break;
    case 'c':
      sscanf(optarg,"%lf",&pc);
      break;
    case 'n':
      sscanf(optarg,"%d",&N);
      break;
    case 'd':
      sscanf(optarg,"%d",&debug);
      break;
    default:
      break;
    }

  mxlda=N/nc + N%nc;
  if (mxlda%nb) mxlda+=(nb-mxlda%nb);

  lr=numroc_(&N,&nb,&mr,&rsrc,&nr);
  lc=numroc_(&N,&nb,&mc,&rsrc,&nc);
/*    lc=lr=mxlda; */
  mem2(a,lc,lr);
  mem2(af,lc,lr);
  mem2(b,1,lr);
  mem2(v,1,lr);
  mem(x,N);
  mem(ipiv,lr+nb);
  mem(r,lr);
  mem(c,lc);
  mem(q,mxlda*mxlda);

  for (i=0;i<N;i++)
    x[i]=bx+xi*i;

  l=1.0;
  for (i=0;i<N;i++)
    for (j=0;j<N;j++) {
      int ni,nj;

      ni=i;
      ni/=nb;
      if (ni%nr!=mr)
	continue;
      ni/=nr;
      ni*=nb;
      ni+=i%nb;

      nj=j;
      nj/=nb;
      if (nj%nc!=mc)
	continue;
      nj/=nc;
      nj*=nb;
      nj+=j%nb;

      a[nj][ni]=kernel(x[i],x[j],0.0,pc*pp,pa/pc,ps/pc)*xi;
      if (i==j)
	a[nj][ni]-=l;

    }

  descinit_(desca,&N,&N,&nb,&nb,&rsrc,&rsrc,&ic,&lr,&info);
  descinit_(descaf,&N,&N,&nb,&nb,&rsrc,&rsrc,&ic,&lr,&info);
  descinit_(descv,&N,&ione,&nb,&nb,&rsrc,&rsrc,&ic,&lr,&info);
  descinit_(descb,&N,&ione,&nb,&nb,&rsrc,&rsrc,&ic,&lr,&info);
  
  if (!mc) {
    randnor(b[0],lr,1.0);
  
    t=0.0;
    for (i=0;i<lr;i++)
      t+=b[0][i]*b[0][i];
    dgsum2d_(&ic,"C"," ",&ione,&ione,&t,&ione,&izero,&mc);
    dgebr2d_(&ic,"C"," ",&ione,&ione,&t,&ione,&izero,&mc);
      
    t=1.0/sqrt(t);
    for (i=0;i<lr;i++)
      b[0][i]*=t;
  }


  if (!mr && !mc) {
    fprintf(stderr,"Starting ev search\n");
    fflush(stderr);
  }

  f="N";
  k=-1;
  pdgesvx_(f,"N",&N,&ione,a[0],&ione,&ione,desca,
	   af[0],&ione,&ione,descaf,ipiv,&eq,
	   r,c,b[0],&ione,&ione,descb,v[0],&ione,&ione,descv,
	   &rcond,&ferr,&berr,&t,&k,&j,&k,&info);
  lwork=t;
  mem(work,lwork);
  liwork=j;
  mem(iwork,liwork);
  pdgesvx_(f,"N",&N,&ione,a[0],&ione,&ione,desca,
	   af[0],&ione,&ione,descaf,ipiv,&eq,
	   r,c,b[0],&ione,&ione,descb,v[0],&ione,&ione,descv,
	   &rcond,&ferr,&berr,work,&lwork,iwork,&liwork,&info);
  if (debug && !mr && !mc)
    fprintf(stderr,"Factor done: info %d rc %e fe %e be %e eq %c\n",
	    info,rcond,ferr,berr,eq);
  if (info)
    if (!mr && !mc)
      error("Factorization failed: info %d rc %e fe %e be %e eq %c\n",
	    info,rcond,ferr,berr,eq);
    else
      return -1;

  f="F";

  for (i=0;i<200 && (!debug || i<debug);i++) {

    double t,t1[2];
    int j;

    if (!mc) {

      for (j=0,t1[0]=t1[1]=0.0;j<lr;j++) {
	t1[0]+=v[0][j]*v[0][j];
	t1[1]+=v[0][j];
      }
      dgsum2d_(&ic,"C"," ",&itwo,&ione,t1,&itwo,&izero,&mc);
      dgebr2d_(&ic,"C"," ",&itwo,&ione,t1,&itwo,&izero,&mc);
      
      t=1.0/sqrt(t1[0]);
      t=t1[1]<0.0 ? -t : t;
      
      for (j=0;j<lr;j++)
	v[0][j]*=t;

      for (t=0.0,j=0;j<lr;j++)
	t+=(b[0][j]-v[0][j])*(b[0][j]-v[0][j]);
      
      dgsum2d_(&ic,"C"," ",&ione,&ione,&t,&ione,&izero,&mc);
      dgebr2d_(&ic,"C"," ",&ione,&ione,&t,&ione,&izero,&mc);
      
      t=sqrt(t);
    }
    if (!mc)
      memcpy(b[0],v[0],lr*sizeof(*b[0]));

    if (debug && !mc) {

      if (!mr)
	fprintf(stderr,"Result %d: diff %e\n",i,t);

      for (j=0;j<nr;j++) {
	if (j==mr) 
	  memcpy(q+j*mxlda,b[0],lr*sizeof(*b[0]));
	dgebr2d_(&ic,"C"," ",&mxlda,&ione,q+j*mxlda,&N,&j,&mc);
      }
      
      if (!mr) {
	for (j=0;j<N;j++) {
	  int nj,nbb;
	  
	  nj=j;
	  nj/=nb;
	  nbb=nj%nr;
	  nj/=nr;
	  nj*=nb;
	  nj+=j%nb;
	  printf("%e %e\n",x[j],q[nbb*mxlda+nj]);
	}
	printf("\n\n");
      }
    }

    pdgesvx_(f,"N",&N,&ione,a[0],&ione,&ione,desca,
	     af[0],&ione,&ione,descaf,ipiv,&eq,
	     r,c,b[0],&ione,&ione,descb,v[0],&ione,&ione,descv,
	     &rcond,&ferr,&berr,work,&lwork,iwork,&liwork,&info);
    if (debug && !mr && !mc)
      fprintf(stderr,"Iteration %d: info %d rc %e fe %e be%e eq %c\n",
	      i,info,rcond,ferr,berr,eq);

    dgebr2d_(&ic,"R"," ",&ione,&ione,&t,&ione,&mr,&izero);

    if (t<TINY*N)
      break;

  }

  if (!mc) {

    for (t=0.0,j=0;j<lr;j++)
      t+=b[0][j]*v[0][j];
    
    dgsum2d_(&ic,"C"," ",&ione,&ione,&t,&ione,&izero,&mc);
    dgebr2d_(&ic,"C"," ",&ione,&ione,&t,&ione,&izero,&mc);
    
    l1=l+1.0/t;

    if (!mr) {
      fprintf(stderr,"done, %d iterations, eigenv %f\n",i,l1);
      fflush(stderr);
    }

    for (j=0;j<nr;j++) {
      if (j==mr) 
	memcpy(q+j*mxlda,b[0],lr*sizeof(*b[0]));
      dgebr2d_(&ic,"C"," ",&mxlda,&ione,q+j*mxlda,&N,&j,&mc);
    }
      
    if (!mr)
      for (i=0;i<N;i++) {
	int ni,nbb;

	ni=i;
	ni/=nb;
	nbb=ni%nr;
	ni/=nr;
	ni*=nb;
	ni+=i%nb;
	printf("%e %e\n",x[i],q[nbb*mxlda+ni]);
      }
  }

  blacs_gridexit__(&ic);

  exit(0);

}
=============================================================================
Makefile:
=============================================================================
SC=-lscalapack-lam -lpblas-lam -ltools-lam -lredist-lam
BL=-lblacsCinit-lam -lblacs-lam -lblacsCinit-lam
BLAS=-lblas

LOADLIBES = $(SC) $(BL) $(BLAS) -lstd -lnum -lm -lmpi
LINK=g77
CFLAGS+=-I /usr/include/mpi

include $(HOME)/etc/Makefile

=============================================================================

"Horatio B. Bogbindero" <wyy at cersa.admu.edu.ph> writes:

> > 
> > > are there any scalapack users in the list? i have a few questions to ask:
> > > 
> > 
> > Here!
> > 
> > > -is there s C/C++ implementation of SCALAPACK? if not, can i call the
> > > fortran SCALAPACK/PBLAS functions from C/C++?
> > > 
> > 
> > No c interface, to use routines:
> > 
> > 1) add a '_' after routine name
> > 2) Pass all arguments as pointers  (i.e. an arg of '1' would have to
> > 	be passed as &i, with i having been set to 1.)
> > 3) Link with g77
> > 
> hmmm. let me get this right. is it...
> 
> to call BLACS:
> 
> CALL BLACS_PINFO( IAM, NPROCS)
> 
> to c/c++ :
> 
> blacs_pinfo_(iam, nprocs);
> 
> to call a scalapack routine:
> 
> CALL PDGETRF( N( I ), N( I ), MEM( IPA ), 1, 1, DESCA, MEM( IPPIV ), INFO)
> 
> to c/c++:
> 
> pdgetrf_(n,n,mem1,1,1,desca,mem2,info);
> 
> ???
> 
> > > -are there any good scalapack documentation/manuals out there? the
> > > scalapack site only feature some lawns but nothing like a users manual.
> > > 
> > 
> > The faq and user's guide at netlib are both good.  They're included in
> > the new Debian scalapack-doc package.
> > 
> how do i use the scalapack docs if they are a debian package and i use
> redhat? is there a good printable version available like a pdf/ps version
> of the scalapack-slug document at netlib.
>  
> ---------------------
> william.s.yu at ieee.org
>  
> It's easier to fight for one's principles than to live up to them.
>  
> 
> 
> 

-- 
Camm Maguire			     			camm at enhanced.com
==========================================================================
"The earth is but one country, and mankind its citizens."  --  Baha'u'llah




More information about the Beowulf mailing list