1a5eb4965SSatish Balay #ifdef PETSC_RCS_HEADER 2*d132466eSBarry Smith static char vcid[] = "$Id: mpidense.c,v 1.111 1999/03/25 21:23:03 balay Exp bsmith $"; 38965ea79SLois Curfman McInnes #endif 48965ea79SLois Curfman McInnes 5ed3cc1f0SBarry Smith /* 6ed3cc1f0SBarry Smith Basic functions for basic parallel dense matrices. 7ed3cc1f0SBarry Smith */ 8ed3cc1f0SBarry Smith 970f55243SBarry Smith #include "src/mat/impls/dense/mpi/mpidense.h" 10f5eb4b81SSatish Balay #include "src/vec/vecimpl.h" 118965ea79SLois Curfman McInnes 127ef1d9bdSSatish Balay extern int MatSetUpMultiply_MPIDense(Mat); 137ef1d9bdSSatish Balay 145615d1e5SSatish Balay #undef __FUNC__ 155615d1e5SSatish Balay #define __FUNC__ "MatSetValues_MPIDense" 168f6be9afSLois Curfman McInnes int MatSetValues_MPIDense(Mat mat,int m,int *idxm,int n,int *idxn,Scalar *v,InsertMode addv) 178965ea79SLois Curfman McInnes { 1839b7565bSBarry Smith Mat_MPIDense *A = (Mat_MPIDense *) mat->data; 1939b7565bSBarry Smith int ierr, i, j, rstart = A->rstart, rend = A->rend, row; 2039b7565bSBarry Smith int roworiented = A->roworiented; 218965ea79SLois Curfman McInnes 223a40ed3dSBarry Smith PetscFunctionBegin; 238965ea79SLois Curfman McInnes for ( i=0; i<m; i++ ) { 245ef9f2a5SBarry Smith if (idxm[i] < 0) continue; 25a8c6a408SBarry Smith if (idxm[i] >= A->M) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large"); 268965ea79SLois Curfman McInnes if (idxm[i] >= rstart && idxm[i] < rend) { 278965ea79SLois Curfman McInnes row = idxm[i] - rstart; 2839b7565bSBarry Smith if (roworiented) { 2939b7565bSBarry Smith ierr = MatSetValues(A->A,1,&row,n,idxn,v+i*n,addv); CHKERRQ(ierr); 303a40ed3dSBarry Smith } else { 318965ea79SLois Curfman McInnes for ( j=0; j<n; j++ ) { 325ef9f2a5SBarry Smith if (idxn[j] < 0) continue; 33a8c6a408SBarry Smith if (idxn[j] >= A->N) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large"); 3439b7565bSBarry Smith ierr = MatSetValues(A->A,1,&row,1,&idxn[j],v+i+j*m,addv); CHKERRQ(ierr); 3539b7565bSBarry Smith } 368965ea79SLois Curfman McInnes } 373a40ed3dSBarry Smith } else { 383782ba37SSatish Balay if ( !A->donotstash) { 3939b7565bSBarry Smith if (roworiented) { 408798bf22SSatish Balay ierr = MatStashValuesRow_Private(&mat->stash,idxm[i],n,idxn,v+i*n); CHKERRQ(ierr); 41d36fbae8SSatish Balay } else { 428798bf22SSatish Balay ierr = MatStashValuesCol_Private(&mat->stash,idxm[i],n,idxn,v+i,m);CHKERRQ(ierr); 4339b7565bSBarry Smith } 44b49de8d1SLois Curfman McInnes } 45b49de8d1SLois Curfman McInnes } 463782ba37SSatish Balay } 473a40ed3dSBarry Smith PetscFunctionReturn(0); 48b49de8d1SLois Curfman McInnes } 49b49de8d1SLois Curfman McInnes 505615d1e5SSatish Balay #undef __FUNC__ 515615d1e5SSatish Balay #define __FUNC__ "MatGetValues_MPIDense" 528f6be9afSLois Curfman McInnes int MatGetValues_MPIDense(Mat mat,int m,int *idxm,int n,int *idxn,Scalar *v) 53b49de8d1SLois Curfman McInnes { 54b49de8d1SLois Curfman McInnes Mat_MPIDense *mdn = (Mat_MPIDense *) mat->data; 55b49de8d1SLois Curfman McInnes int ierr, i, j, rstart = mdn->rstart, rend = mdn->rend, row; 56b49de8d1SLois Curfman McInnes 573a40ed3dSBarry Smith PetscFunctionBegin; 58b49de8d1SLois Curfman McInnes for ( i=0; i<m; i++ ) { 59a8c6a408SBarry Smith if (idxm[i] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative row"); 60a8c6a408SBarry Smith if (idxm[i] >= mdn->M) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large"); 61b49de8d1SLois Curfman McInnes if (idxm[i] >= rstart && idxm[i] < rend) { 62b49de8d1SLois Curfman McInnes row = idxm[i] - rstart; 63b49de8d1SLois Curfman McInnes for ( j=0; j<n; j++ ) { 64a8c6a408SBarry Smith if (idxn[j] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative column"); 65a8c6a408SBarry Smith if (idxn[j] >= mdn->N) { 66a8c6a408SBarry Smith SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large"); 67a8c6a408SBarry Smith } 68b49de8d1SLois Curfman McInnes ierr = MatGetValues(mdn->A,1,&row,1,&idxn[j],v+i*n+j); CHKERRQ(ierr); 69b49de8d1SLois Curfman McInnes } 70a8c6a408SBarry Smith } else { 71a8c6a408SBarry Smith SETERRQ(PETSC_ERR_SUP,0,"Only local values currently supported"); 728965ea79SLois Curfman McInnes } 738965ea79SLois Curfman McInnes } 743a40ed3dSBarry Smith PetscFunctionReturn(0); 758965ea79SLois Curfman McInnes } 768965ea79SLois Curfman McInnes 775615d1e5SSatish Balay #undef __FUNC__ 785615d1e5SSatish Balay #define __FUNC__ "MatGetArray_MPIDense" 798f6be9afSLois Curfman McInnes int MatGetArray_MPIDense(Mat A,Scalar **array) 80ff14e315SSatish Balay { 81ff14e315SSatish Balay Mat_MPIDense *a = (Mat_MPIDense *) A->data; 82ff14e315SSatish Balay int ierr; 83ff14e315SSatish Balay 843a40ed3dSBarry Smith PetscFunctionBegin; 85ff14e315SSatish Balay ierr = MatGetArray(a->A,array); CHKERRQ(ierr); 863a40ed3dSBarry Smith PetscFunctionReturn(0); 87ff14e315SSatish Balay } 88ff14e315SSatish Balay 895615d1e5SSatish Balay #undef __FUNC__ 905615d1e5SSatish Balay #define __FUNC__ "MatRestoreArray_MPIDense" 918f6be9afSLois Curfman McInnes int MatRestoreArray_MPIDense(Mat A,Scalar **array) 92ff14e315SSatish Balay { 933a40ed3dSBarry Smith PetscFunctionBegin; 943a40ed3dSBarry Smith PetscFunctionReturn(0); 95ff14e315SSatish Balay } 96ff14e315SSatish Balay 975615d1e5SSatish Balay #undef __FUNC__ 985615d1e5SSatish Balay #define __FUNC__ "MatAssemblyBegin_MPIDense" 998f6be9afSLois Curfman McInnes int MatAssemblyBegin_MPIDense(Mat mat,MatAssemblyType mode) 1008965ea79SLois Curfman McInnes { 10139ddd567SLois Curfman McInnes Mat_MPIDense *mdn = (Mat_MPIDense *) mat->data; 1028965ea79SLois Curfman McInnes MPI_Comm comm = mat->comm; 103d36fbae8SSatish Balay int ierr,nstash,reallocs; 1048965ea79SLois Curfman McInnes InsertMode addv; 1058965ea79SLois Curfman McInnes 1063a40ed3dSBarry Smith PetscFunctionBegin; 1078965ea79SLois Curfman McInnes /* make sure all processors are either in INSERTMODE or ADDMODE */ 108ca161407SBarry Smith ierr = MPI_Allreduce(&mat->insertmode,&addv,1,MPI_INT,MPI_BOR,comm);CHKERRQ(ierr); 1097056b6fcSBarry Smith if (addv == (ADD_VALUES|INSERT_VALUES)) { 110a8c6a408SBarry Smith SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Cannot mix adds/inserts on different procs"); 1118965ea79SLois Curfman McInnes } 112e0fa3b82SLois Curfman McInnes mat->insertmode = addv; /* in case this processor had no cache */ 1138965ea79SLois Curfman McInnes 1148798bf22SSatish Balay ierr = MatStashScatterBegin_Private(&mat->stash,mdn->rowners); CHKERRQ(ierr); 1158798bf22SSatish Balay ierr = MatStashGetInfo_Private(&mat->stash,&nstash,&reallocs); CHKERRQ(ierr); 116d36fbae8SSatish Balay PLogInfo(mdn->A,"MatAssemblyBegin_MPIDense:Stash has %d entries, uses %d mallocs.\n", 117d36fbae8SSatish Balay nstash,reallocs); 1183a40ed3dSBarry Smith PetscFunctionReturn(0); 1198965ea79SLois Curfman McInnes } 1208965ea79SLois Curfman McInnes 1215615d1e5SSatish Balay #undef __FUNC__ 1225615d1e5SSatish Balay #define __FUNC__ "MatAssemblyEnd_MPIDense" 1238f6be9afSLois Curfman McInnes int MatAssemblyEnd_MPIDense(Mat mat,MatAssemblyType mode) 1248965ea79SLois Curfman McInnes { 12539ddd567SLois Curfman McInnes Mat_MPIDense *mdn=(Mat_MPIDense*)mat->data; 1267ef1d9bdSSatish Balay int i,n,ierr,*row,*col,flg,j,rstart,ncols; 1277ef1d9bdSSatish Balay Scalar *val; 128e0fa3b82SLois Curfman McInnes InsertMode addv=mat->insertmode; 1298965ea79SLois Curfman McInnes 1303a40ed3dSBarry Smith PetscFunctionBegin; 1318965ea79SLois Curfman McInnes /* wait on receives */ 1327ef1d9bdSSatish Balay while (1) { 1338798bf22SSatish Balay ierr = MatStashScatterGetMesg_Private(&mat->stash,&n,&row,&col,&val,&flg); CHKERRQ(ierr); 1347ef1d9bdSSatish Balay if (!flg) break; 1358965ea79SLois Curfman McInnes 1367ef1d9bdSSatish Balay for ( i=0; i<n; ) { 1377ef1d9bdSSatish Balay /* Now identify the consecutive vals belonging to the same row */ 1387ef1d9bdSSatish Balay for ( j=i,rstart=row[j]; j<n; j++ ) { if (row[j] != rstart) break; } 1397ef1d9bdSSatish Balay if (j < n) ncols = j-i; 1407ef1d9bdSSatish Balay else ncols = n-i; 1417ef1d9bdSSatish Balay /* Now assemble all these values with a single function call */ 1427ef1d9bdSSatish Balay ierr = MatSetValues_MPIDense(mat,1,row+i,ncols,col+i,val+i,addv); CHKERRQ(ierr); 1437ef1d9bdSSatish Balay i = j; 1448965ea79SLois Curfman McInnes } 1457ef1d9bdSSatish Balay } 1468798bf22SSatish Balay ierr = MatStashScatterEnd_Private(&mat->stash); CHKERRQ(ierr); 1478965ea79SLois Curfman McInnes 14839ddd567SLois Curfman McInnes ierr = MatAssemblyBegin(mdn->A,mode); CHKERRQ(ierr); 14939ddd567SLois Curfman McInnes ierr = MatAssemblyEnd(mdn->A,mode); CHKERRQ(ierr); 1508965ea79SLois Curfman McInnes 1516d4a8577SBarry Smith if (!mat->was_assembled && mode == MAT_FINAL_ASSEMBLY) { 15239ddd567SLois Curfman McInnes ierr = MatSetUpMultiply_MPIDense(mat); CHKERRQ(ierr); 1538965ea79SLois Curfman McInnes } 1543a40ed3dSBarry Smith PetscFunctionReturn(0); 1558965ea79SLois Curfman McInnes } 1568965ea79SLois Curfman McInnes 1575615d1e5SSatish Balay #undef __FUNC__ 1585615d1e5SSatish Balay #define __FUNC__ "MatZeroEntries_MPIDense" 1598f6be9afSLois Curfman McInnes int MatZeroEntries_MPIDense(Mat A) 1608965ea79SLois Curfman McInnes { 1613a40ed3dSBarry Smith int ierr; 16239ddd567SLois Curfman McInnes Mat_MPIDense *l = (Mat_MPIDense *) A->data; 1633a40ed3dSBarry Smith 1643a40ed3dSBarry Smith PetscFunctionBegin; 1653a40ed3dSBarry Smith ierr = MatZeroEntries(l->A);CHKERRQ(ierr); 1663a40ed3dSBarry Smith PetscFunctionReturn(0); 1678965ea79SLois Curfman McInnes } 1688965ea79SLois Curfman McInnes 1695615d1e5SSatish Balay #undef __FUNC__ 1705615d1e5SSatish Balay #define __FUNC__ "MatGetBlockSize_MPIDense" 1718f6be9afSLois Curfman McInnes int MatGetBlockSize_MPIDense(Mat A,int *bs) 1724e220ebcSLois Curfman McInnes { 1733a40ed3dSBarry Smith PetscFunctionBegin; 1744e220ebcSLois Curfman McInnes *bs = 1; 1753a40ed3dSBarry Smith PetscFunctionReturn(0); 1764e220ebcSLois Curfman McInnes } 1774e220ebcSLois Curfman McInnes 1788965ea79SLois Curfman McInnes /* the code does not do the diagonal entries correctly unless the 1798965ea79SLois Curfman McInnes matrix is square and the column and row owerships are identical. 1808965ea79SLois Curfman McInnes This is a BUG. The only way to fix it seems to be to access 1813501a2bdSLois Curfman McInnes mdn->A and mdn->B directly and not through the MatZeroRows() 1828965ea79SLois Curfman McInnes routine. 1838965ea79SLois Curfman McInnes */ 1845615d1e5SSatish Balay #undef __FUNC__ 1855615d1e5SSatish Balay #define __FUNC__ "MatZeroRows_MPIDense" 1868f6be9afSLois Curfman McInnes int MatZeroRows_MPIDense(Mat A,IS is,Scalar *diag) 1878965ea79SLois Curfman McInnes { 18839ddd567SLois Curfman McInnes Mat_MPIDense *l = (Mat_MPIDense *) A->data; 1898965ea79SLois Curfman McInnes int i,ierr,N, *rows,*owners = l->rowners,size = l->size; 1908965ea79SLois Curfman McInnes int *procs,*nprocs,j,found,idx,nsends,*work; 1918965ea79SLois Curfman McInnes int nmax,*svalues,*starts,*owner,nrecvs,rank = l->rank; 1928965ea79SLois Curfman McInnes int *rvalues,tag = A->tag,count,base,slen,n,*source; 1938965ea79SLois Curfman McInnes int *lens,imdex,*lrows,*values; 1948965ea79SLois Curfman McInnes MPI_Comm comm = A->comm; 1958965ea79SLois Curfman McInnes MPI_Request *send_waits,*recv_waits; 1968965ea79SLois Curfman McInnes MPI_Status recv_status,*send_status; 1978965ea79SLois Curfman McInnes IS istmp; 1988965ea79SLois Curfman McInnes 1993a40ed3dSBarry Smith PetscFunctionBegin; 20077c4ece6SBarry Smith ierr = ISGetSize(is,&N); CHKERRQ(ierr); 2018965ea79SLois Curfman McInnes ierr = ISGetIndices(is,&rows); CHKERRQ(ierr); 2028965ea79SLois Curfman McInnes 2038965ea79SLois Curfman McInnes /* first count number of contributors to each processor */ 2040452661fSBarry Smith nprocs = (int *) PetscMalloc( 2*size*sizeof(int) ); CHKPTRQ(nprocs); 205cddf8d76SBarry Smith PetscMemzero(nprocs,2*size*sizeof(int)); procs = nprocs + size; 2060452661fSBarry Smith owner = (int *) PetscMalloc((N+1)*sizeof(int)); CHKPTRQ(owner); /* see note*/ 2078965ea79SLois Curfman McInnes for ( i=0; i<N; i++ ) { 2088965ea79SLois Curfman McInnes idx = rows[i]; 2098965ea79SLois Curfman McInnes found = 0; 2108965ea79SLois Curfman McInnes for ( j=0; j<size; j++ ) { 2118965ea79SLois Curfman McInnes if (idx >= owners[j] && idx < owners[j+1]) { 2128965ea79SLois Curfman McInnes nprocs[j]++; procs[j] = 1; owner[i] = j; found = 1; break; 2138965ea79SLois Curfman McInnes } 2148965ea79SLois Curfman McInnes } 215a8c6a408SBarry Smith if (!found) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Index out of range"); 2168965ea79SLois Curfman McInnes } 2178965ea79SLois Curfman McInnes nsends = 0; for ( i=0; i<size; i++ ) { nsends += procs[i];} 2188965ea79SLois Curfman McInnes 2198965ea79SLois Curfman McInnes /* inform other processors of number of messages and max length*/ 2200452661fSBarry Smith work = (int *) PetscMalloc( size*sizeof(int) ); CHKPTRQ(work); 221ca161407SBarry Smith ierr = MPI_Allreduce( procs, work,size,MPI_INT,MPI_SUM,comm);CHKERRQ(ierr); 2228965ea79SLois Curfman McInnes nrecvs = work[rank]; 223ca161407SBarry Smith ierr = MPI_Allreduce( nprocs, work,size,MPI_INT,MPI_MAX,comm);CHKERRQ(ierr); 2248965ea79SLois Curfman McInnes nmax = work[rank]; 2250452661fSBarry Smith PetscFree(work); 2268965ea79SLois Curfman McInnes 2278965ea79SLois Curfman McInnes /* post receives: */ 2283a40ed3dSBarry Smith rvalues = (int *) PetscMalloc((nrecvs+1)*(nmax+1)*sizeof(int));CHKPTRQ(rvalues); 2293a40ed3dSBarry Smith recv_waits = (MPI_Request *) PetscMalloc((nrecvs+1)*sizeof(MPI_Request));CHKPTRQ(recv_waits); 2308965ea79SLois Curfman McInnes for ( i=0; i<nrecvs; i++ ) { 231ca161407SBarry Smith ierr = MPI_Irecv(rvalues+nmax*i,nmax,MPI_INT,MPI_ANY_SOURCE,tag,comm,recv_waits+i);CHKERRQ(ierr); 2328965ea79SLois Curfman McInnes } 2338965ea79SLois Curfman McInnes 2348965ea79SLois Curfman McInnes /* do sends: 2358965ea79SLois Curfman McInnes 1) starts[i] gives the starting index in svalues for stuff going to 2368965ea79SLois Curfman McInnes the ith processor 2378965ea79SLois Curfman McInnes */ 2380452661fSBarry Smith svalues = (int *) PetscMalloc( (N+1)*sizeof(int) ); CHKPTRQ(svalues); 2397056b6fcSBarry Smith send_waits = (MPI_Request *) PetscMalloc((nsends+1)*sizeof(MPI_Request));CHKPTRQ(send_waits); 2400452661fSBarry Smith starts = (int *) PetscMalloc( (size+1)*sizeof(int) ); CHKPTRQ(starts); 2418965ea79SLois Curfman McInnes starts[0] = 0; 2428965ea79SLois Curfman McInnes for ( i=1; i<size; i++ ) { starts[i] = starts[i-1] + nprocs[i-1];} 2438965ea79SLois Curfman McInnes for ( i=0; i<N; i++ ) { 2448965ea79SLois Curfman McInnes svalues[starts[owner[i]]++] = rows[i]; 2458965ea79SLois Curfman McInnes } 2468965ea79SLois Curfman McInnes ISRestoreIndices(is,&rows); 2478965ea79SLois Curfman McInnes 2488965ea79SLois Curfman McInnes starts[0] = 0; 2498965ea79SLois Curfman McInnes for ( i=1; i<size+1; i++ ) { starts[i] = starts[i-1] + nprocs[i-1];} 2508965ea79SLois Curfman McInnes count = 0; 2518965ea79SLois Curfman McInnes for ( i=0; i<size; i++ ) { 2528965ea79SLois Curfman McInnes if (procs[i]) { 253ca161407SBarry Smith ierr = MPI_Isend(svalues+starts[i],nprocs[i],MPI_INT,i,tag,comm,send_waits+count++);CHKERRQ(ierr); 2548965ea79SLois Curfman McInnes } 2558965ea79SLois Curfman McInnes } 2560452661fSBarry Smith PetscFree(starts); 2578965ea79SLois Curfman McInnes 2588965ea79SLois Curfman McInnes base = owners[rank]; 2598965ea79SLois Curfman McInnes 2608965ea79SLois Curfman McInnes /* wait on receives */ 2610452661fSBarry Smith lens = (int *) PetscMalloc( 2*(nrecvs+1)*sizeof(int) ); CHKPTRQ(lens); 2628965ea79SLois Curfman McInnes source = lens + nrecvs; 2638965ea79SLois Curfman McInnes count = nrecvs; slen = 0; 2648965ea79SLois Curfman McInnes while (count) { 265ca161407SBarry Smith ierr = MPI_Waitany(nrecvs,recv_waits,&imdex,&recv_status);CHKERRQ(ierr); 2668965ea79SLois Curfman McInnes /* unpack receives into our local space */ 267ca161407SBarry Smith ierr = MPI_Get_count(&recv_status,MPI_INT,&n);CHKERRQ(ierr); 2688965ea79SLois Curfman McInnes source[imdex] = recv_status.MPI_SOURCE; 2698965ea79SLois Curfman McInnes lens[imdex] = n; 2708965ea79SLois Curfman McInnes slen += n; 2718965ea79SLois Curfman McInnes count--; 2728965ea79SLois Curfman McInnes } 2730452661fSBarry Smith PetscFree(recv_waits); 2748965ea79SLois Curfman McInnes 2758965ea79SLois Curfman McInnes /* move the data into the send scatter */ 2760452661fSBarry Smith lrows = (int *) PetscMalloc( (slen+1)*sizeof(int) ); CHKPTRQ(lrows); 2778965ea79SLois Curfman McInnes count = 0; 2788965ea79SLois Curfman McInnes for ( i=0; i<nrecvs; i++ ) { 2798965ea79SLois Curfman McInnes values = rvalues + i*nmax; 2808965ea79SLois Curfman McInnes for ( j=0; j<lens[i]; j++ ) { 2818965ea79SLois Curfman McInnes lrows[count++] = values[j] - base; 2828965ea79SLois Curfman McInnes } 2838965ea79SLois Curfman McInnes } 2840452661fSBarry Smith PetscFree(rvalues); PetscFree(lens); 2850452661fSBarry Smith PetscFree(owner); PetscFree(nprocs); 2868965ea79SLois Curfman McInnes 2878965ea79SLois Curfman McInnes /* actually zap the local rows */ 288029af93fSBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,slen,lrows,&istmp);CHKERRQ(ierr); 2898965ea79SLois Curfman McInnes PLogObjectParent(A,istmp); 2900452661fSBarry Smith PetscFree(lrows); 2918965ea79SLois Curfman McInnes ierr = MatZeroRows(l->A,istmp,diag); CHKERRQ(ierr); 2928965ea79SLois Curfman McInnes ierr = ISDestroy(istmp); CHKERRQ(ierr); 2938965ea79SLois Curfman McInnes 2948965ea79SLois Curfman McInnes /* wait on sends */ 2958965ea79SLois Curfman McInnes if (nsends) { 2967056b6fcSBarry Smith send_status = (MPI_Status *) PetscMalloc(nsends*sizeof(MPI_Status));CHKPTRQ(send_status); 297ca161407SBarry Smith ierr = MPI_Waitall(nsends,send_waits,send_status);CHKERRQ(ierr); 2980452661fSBarry Smith PetscFree(send_status); 2998965ea79SLois Curfman McInnes } 3000452661fSBarry Smith PetscFree(send_waits); PetscFree(svalues); 3018965ea79SLois Curfman McInnes 3023a40ed3dSBarry Smith PetscFunctionReturn(0); 3038965ea79SLois Curfman McInnes } 3048965ea79SLois Curfman McInnes 3055615d1e5SSatish Balay #undef __FUNC__ 3065615d1e5SSatish Balay #define __FUNC__ "MatMult_MPIDense" 3078f6be9afSLois Curfman McInnes int MatMult_MPIDense(Mat mat,Vec xx,Vec yy) 3088965ea79SLois Curfman McInnes { 30939ddd567SLois Curfman McInnes Mat_MPIDense *mdn = (Mat_MPIDense *) mat->data; 3108965ea79SLois Curfman McInnes int ierr; 311c456f294SBarry Smith 3123a40ed3dSBarry Smith PetscFunctionBegin; 31343a90d84SBarry Smith ierr = VecScatterBegin(xx,mdn->lvec,INSERT_VALUES,SCATTER_FORWARD,mdn->Mvctx);CHKERRQ(ierr); 31443a90d84SBarry Smith ierr = VecScatterEnd(xx,mdn->lvec,INSERT_VALUES,SCATTER_FORWARD,mdn->Mvctx);CHKERRQ(ierr); 31544cd7ae7SLois Curfman McInnes ierr = MatMult_SeqDense(mdn->A,mdn->lvec,yy); CHKERRQ(ierr); 3163a40ed3dSBarry Smith PetscFunctionReturn(0); 3178965ea79SLois Curfman McInnes } 3188965ea79SLois Curfman McInnes 3195615d1e5SSatish Balay #undef __FUNC__ 3205615d1e5SSatish Balay #define __FUNC__ "MatMultAdd_MPIDense" 3218f6be9afSLois Curfman McInnes int MatMultAdd_MPIDense(Mat mat,Vec xx,Vec yy,Vec zz) 3228965ea79SLois Curfman McInnes { 32339ddd567SLois Curfman McInnes Mat_MPIDense *mdn = (Mat_MPIDense *) mat->data; 3248965ea79SLois Curfman McInnes int ierr; 325c456f294SBarry Smith 3263a40ed3dSBarry Smith PetscFunctionBegin; 32743a90d84SBarry Smith ierr = VecScatterBegin(xx,mdn->lvec,INSERT_VALUES,SCATTER_FORWARD,mdn->Mvctx);CHKERRQ(ierr); 32843a90d84SBarry Smith ierr = VecScatterEnd(xx,mdn->lvec,INSERT_VALUES,SCATTER_FORWARD,mdn->Mvctx);CHKERRQ(ierr); 32944cd7ae7SLois Curfman McInnes ierr = MatMultAdd_SeqDense(mdn->A,mdn->lvec,yy,zz); CHKERRQ(ierr); 3303a40ed3dSBarry Smith PetscFunctionReturn(0); 3318965ea79SLois Curfman McInnes } 3328965ea79SLois Curfman McInnes 3335615d1e5SSatish Balay #undef __FUNC__ 3345615d1e5SSatish Balay #define __FUNC__ "MatMultTrans_MPIDense" 3358f6be9afSLois Curfman McInnes int MatMultTrans_MPIDense(Mat A,Vec xx,Vec yy) 336096963f5SLois Curfman McInnes { 337096963f5SLois Curfman McInnes Mat_MPIDense *a = (Mat_MPIDense *) A->data; 338096963f5SLois Curfman McInnes int ierr; 3393501a2bdSLois Curfman McInnes Scalar zero = 0.0; 340096963f5SLois Curfman McInnes 3413a40ed3dSBarry Smith PetscFunctionBegin; 3423501a2bdSLois Curfman McInnes ierr = VecSet(&zero,yy); CHKERRQ(ierr); 34344cd7ae7SLois Curfman McInnes ierr = MatMultTrans_SeqDense(a->A,xx,a->lvec); CHKERRQ(ierr); 344537820f0SBarry Smith ierr = VecScatterBegin(a->lvec,yy,ADD_VALUES,SCATTER_REVERSE,a->Mvctx); CHKERRQ(ierr); 345537820f0SBarry Smith ierr = VecScatterEnd(a->lvec,yy,ADD_VALUES,SCATTER_REVERSE,a->Mvctx); CHKERRQ(ierr); 3463a40ed3dSBarry Smith PetscFunctionReturn(0); 347096963f5SLois Curfman McInnes } 348096963f5SLois Curfman McInnes 3495615d1e5SSatish Balay #undef __FUNC__ 3505615d1e5SSatish Balay #define __FUNC__ "MatMultTransAdd_MPIDense" 3518f6be9afSLois Curfman McInnes int MatMultTransAdd_MPIDense(Mat A,Vec xx,Vec yy,Vec zz) 352096963f5SLois Curfman McInnes { 353096963f5SLois Curfman McInnes Mat_MPIDense *a = (Mat_MPIDense *) A->data; 354096963f5SLois Curfman McInnes int ierr; 355096963f5SLois Curfman McInnes 3563a40ed3dSBarry Smith PetscFunctionBegin; 3573501a2bdSLois Curfman McInnes ierr = VecCopy(yy,zz); CHKERRQ(ierr); 35844cd7ae7SLois Curfman McInnes ierr = MatMultTrans_SeqDense(a->A,xx,a->lvec); CHKERRQ(ierr); 359537820f0SBarry Smith ierr = VecScatterBegin(a->lvec,zz,ADD_VALUES,SCATTER_REVERSE,a->Mvctx); CHKERRQ(ierr); 360537820f0SBarry Smith ierr = VecScatterEnd(a->lvec,zz,ADD_VALUES,SCATTER_REVERSE,a->Mvctx); CHKERRQ(ierr); 3613a40ed3dSBarry Smith PetscFunctionReturn(0); 362096963f5SLois Curfman McInnes } 363096963f5SLois Curfman McInnes 3645615d1e5SSatish Balay #undef __FUNC__ 3655615d1e5SSatish Balay #define __FUNC__ "MatGetDiagonal_MPIDense" 3668f6be9afSLois Curfman McInnes int MatGetDiagonal_MPIDense(Mat A,Vec v) 3678965ea79SLois Curfman McInnes { 36839ddd567SLois Curfman McInnes Mat_MPIDense *a = (Mat_MPIDense *) A->data; 369096963f5SLois Curfman McInnes Mat_SeqDense *aloc = (Mat_SeqDense *) a->A->data; 37044cd7ae7SLois Curfman McInnes int ierr, len, i, n, m = a->m, radd; 37144cd7ae7SLois Curfman McInnes Scalar *x, zero = 0.0; 372ed3cc1f0SBarry Smith 3733a40ed3dSBarry Smith PetscFunctionBegin; 37444cd7ae7SLois Curfman McInnes VecSet(&zero,v); 375096963f5SLois Curfman McInnes ierr = VecGetArray(v,&x); CHKERRQ(ierr); 376096963f5SLois Curfman McInnes ierr = VecGetSize(v,&n); CHKERRQ(ierr); 377a8c6a408SBarry Smith if (n != a->M) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Nonconforming mat and vec"); 37844cd7ae7SLois Curfman McInnes len = PetscMin(aloc->m,aloc->n); 3797ddc982cSLois Curfman McInnes radd = a->rstart*m; 38044cd7ae7SLois Curfman McInnes for ( i=0; i<len; i++ ) { 381096963f5SLois Curfman McInnes x[i] = aloc->v[radd + i*m + i]; 382096963f5SLois Curfman McInnes } 3833a40ed3dSBarry Smith PetscFunctionReturn(0); 3848965ea79SLois Curfman McInnes } 3858965ea79SLois Curfman McInnes 3865615d1e5SSatish Balay #undef __FUNC__ 3875615d1e5SSatish Balay #define __FUNC__ "MatDestroy_MPIDense" 388e1311b90SBarry Smith int MatDestroy_MPIDense(Mat mat) 3898965ea79SLois Curfman McInnes { 3903501a2bdSLois Curfman McInnes Mat_MPIDense *mdn = (Mat_MPIDense *) mat->data; 3918965ea79SLois Curfman McInnes int ierr; 392ed3cc1f0SBarry Smith 3933a40ed3dSBarry Smith PetscFunctionBegin; 39494d884c6SBarry Smith if (--mat->refct > 0) PetscFunctionReturn(0); 39594d884c6SBarry Smith 39694d884c6SBarry Smith if (mat->mapping) { 39794d884c6SBarry Smith ierr = ISLocalToGlobalMappingDestroy(mat->mapping); CHKERRQ(ierr); 39894d884c6SBarry Smith } 39994d884c6SBarry Smith if (mat->bmapping) { 40094d884c6SBarry Smith ierr = ISLocalToGlobalMappingDestroy(mat->bmapping); CHKERRQ(ierr); 40194d884c6SBarry Smith } 4023a40ed3dSBarry Smith #if defined(USE_PETSC_LOG) 403e1311b90SBarry Smith PLogObjectState((PetscObject)mat,"Rows=%d, Cols=%d",mdn->M,mdn->N); 4048965ea79SLois Curfman McInnes #endif 4058798bf22SSatish Balay ierr = MatStashDestroy_Private(&mat->stash); CHKERRQ(ierr); 4060452661fSBarry Smith PetscFree(mdn->rowners); 4073501a2bdSLois Curfman McInnes ierr = MatDestroy(mdn->A); CHKERRQ(ierr); 4083501a2bdSLois Curfman McInnes if (mdn->lvec) VecDestroy(mdn->lvec); 4093501a2bdSLois Curfman McInnes if (mdn->Mvctx) VecScatterDestroy(mdn->Mvctx); 410622d7880SLois Curfman McInnes if (mdn->factor) { 411622d7880SLois Curfman McInnes if (mdn->factor->temp) PetscFree(mdn->factor->temp); 412622d7880SLois Curfman McInnes if (mdn->factor->tag) PetscFree(mdn->factor->tag); 413622d7880SLois Curfman McInnes if (mdn->factor->pivots) PetscFree(mdn->factor->pivots); 414622d7880SLois Curfman McInnes PetscFree(mdn->factor); 415622d7880SLois Curfman McInnes } 4160452661fSBarry Smith PetscFree(mdn); 41761b13de0SBarry Smith if (mat->rmap) { 41861b13de0SBarry Smith ierr = MapDestroy(mat->rmap);CHKERRQ(ierr); 41961b13de0SBarry Smith } 42061b13de0SBarry Smith if (mat->cmap) { 42161b13de0SBarry Smith ierr = MapDestroy(mat->cmap);CHKERRQ(ierr); 42290f02eecSBarry Smith } 4238965ea79SLois Curfman McInnes PLogObjectDestroy(mat); 4240452661fSBarry Smith PetscHeaderDestroy(mat); 4253a40ed3dSBarry Smith PetscFunctionReturn(0); 4268965ea79SLois Curfman McInnes } 42739ddd567SLois Curfman McInnes 4285615d1e5SSatish Balay #undef __FUNC__ 4295615d1e5SSatish Balay #define __FUNC__ "MatView_MPIDense_Binary" 43039ddd567SLois Curfman McInnes static int MatView_MPIDense_Binary(Mat mat,Viewer viewer) 4318965ea79SLois Curfman McInnes { 43239ddd567SLois Curfman McInnes Mat_MPIDense *mdn = (Mat_MPIDense *) mat->data; 4338965ea79SLois Curfman McInnes int ierr; 4347056b6fcSBarry Smith 4353a40ed3dSBarry Smith PetscFunctionBegin; 43639ddd567SLois Curfman McInnes if (mdn->size == 1) { 43739ddd567SLois Curfman McInnes ierr = MatView(mdn->A,viewer); CHKERRQ(ierr); 4388965ea79SLois Curfman McInnes } 439a8c6a408SBarry Smith else SETERRQ(PETSC_ERR_SUP,0,"Only uniprocessor output supported"); 4403a40ed3dSBarry Smith PetscFunctionReturn(0); 4418965ea79SLois Curfman McInnes } 4428965ea79SLois Curfman McInnes 4435615d1e5SSatish Balay #undef __FUNC__ 4445615d1e5SSatish Balay #define __FUNC__ "MatView_MPIDense_ASCII" 44539ddd567SLois Curfman McInnes static int MatView_MPIDense_ASCII(Mat mat,Viewer viewer) 4468965ea79SLois Curfman McInnes { 44739ddd567SLois Curfman McInnes Mat_MPIDense *mdn = (Mat_MPIDense *) mat->data; 44877ed5343SBarry Smith int ierr, format, size = mdn->size, rank = mdn->rank; 4498965ea79SLois Curfman McInnes FILE *fd; 45019bcc07fSBarry Smith ViewerType vtype; 4518965ea79SLois Curfman McInnes 4523a40ed3dSBarry Smith PetscFunctionBegin; 4533a40ed3dSBarry Smith ierr = ViewerGetType(viewer,&vtype);CHKERRQ(ierr); 45490ace30eSBarry Smith ierr = ViewerASCIIGetPointer(viewer,&fd); CHKERRQ(ierr); 45590ace30eSBarry Smith ierr = ViewerGetFormat(viewer,&format); 456639f9d9dSBarry Smith if (format == VIEWER_FORMAT_ASCII_INFO_LONG) { 4574e220ebcSLois Curfman McInnes MatInfo info; 4584e220ebcSLois Curfman McInnes ierr = MatGetInfo(mat,MAT_LOCAL,&info); 45977c4ece6SBarry Smith PetscSequentialPhaseBegin(mat->comm,1); 4604e220ebcSLois Curfman McInnes fprintf(fd," [%d] local rows %d nz %d nz alloced %d mem %d \n",rank,mdn->m, 4614e220ebcSLois Curfman McInnes (int)info.nz_used,(int)info.nz_allocated,(int)info.memory); 462096963f5SLois Curfman McInnes fflush(fd); 46377c4ece6SBarry Smith PetscSequentialPhaseEnd(mat->comm,1); 4643501a2bdSLois Curfman McInnes ierr = VecScatterView(mdn->Mvctx,viewer); CHKERRQ(ierr); 4653a40ed3dSBarry Smith PetscFunctionReturn(0); 46696f6c058SBarry Smith } else if (format == VIEWER_FORMAT_ASCII_INFO) { 4673a40ed3dSBarry Smith PetscFunctionReturn(0); 4688965ea79SLois Curfman McInnes } 46977ed5343SBarry Smith 4708965ea79SLois Curfman McInnes if (size == 1) { 47139ddd567SLois Curfman McInnes ierr = MatView(mdn->A,viewer); CHKERRQ(ierr); 4723a40ed3dSBarry Smith } else { 4738965ea79SLois Curfman McInnes /* assemble the entire matrix onto first processor. */ 4748965ea79SLois Curfman McInnes Mat A; 47539ddd567SLois Curfman McInnes int M = mdn->M, N = mdn->N,m,row,i, nz, *cols; 47639ddd567SLois Curfman McInnes Scalar *vals; 47739ddd567SLois Curfman McInnes Mat_SeqDense *Amdn = (Mat_SeqDense*) mdn->A->data; 4788965ea79SLois Curfman McInnes 4798965ea79SLois Curfman McInnes if (!rank) { 4800513a670SBarry Smith ierr = MatCreateMPIDense(mat->comm,M,N,M,N,PETSC_NULL,&A); CHKERRQ(ierr); 4813a40ed3dSBarry Smith } else { 4820513a670SBarry Smith ierr = MatCreateMPIDense(mat->comm,0,N,M,N,PETSC_NULL,&A); CHKERRQ(ierr); 4838965ea79SLois Curfman McInnes } 4848965ea79SLois Curfman McInnes PLogObjectParent(mat,A); 4858965ea79SLois Curfman McInnes 48639ddd567SLois Curfman McInnes /* Copy the matrix ... This isn't the most efficient means, 48739ddd567SLois Curfman McInnes but it's quick for now */ 48839ddd567SLois Curfman McInnes row = mdn->rstart; m = Amdn->m; 4898965ea79SLois Curfman McInnes for ( i=0; i<m; i++ ) { 49039ddd567SLois Curfman McInnes ierr = MatGetRow(mat,row,&nz,&cols,&vals); CHKERRQ(ierr); 49139ddd567SLois Curfman McInnes ierr = MatSetValues(A,1,&row,nz,cols,vals,INSERT_VALUES); CHKERRQ(ierr); 49239ddd567SLois Curfman McInnes ierr = MatRestoreRow(mat,row,&nz,&cols,&vals); CHKERRQ(ierr); 49339ddd567SLois Curfman McInnes row++; 4948965ea79SLois Curfman McInnes } 4958965ea79SLois Curfman McInnes 4966d4a8577SBarry Smith ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 4976d4a8577SBarry Smith ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 4988965ea79SLois Curfman McInnes if (!rank) { 49939ddd567SLois Curfman McInnes ierr = MatView(((Mat_MPIDense*)(A->data))->A,viewer); CHKERRQ(ierr); 5008965ea79SLois Curfman McInnes } 5018965ea79SLois Curfman McInnes ierr = MatDestroy(A); CHKERRQ(ierr); 5028965ea79SLois Curfman McInnes } 5033a40ed3dSBarry Smith PetscFunctionReturn(0); 5048965ea79SLois Curfman McInnes } 5058965ea79SLois Curfman McInnes 5065615d1e5SSatish Balay #undef __FUNC__ 5075615d1e5SSatish Balay #define __FUNC__ "MatView_MPIDense" 508e1311b90SBarry Smith int MatView_MPIDense(Mat mat,Viewer viewer) 5098965ea79SLois Curfman McInnes { 51039ddd567SLois Curfman McInnes int ierr; 511bcd2baecSBarry Smith ViewerType vtype; 5128965ea79SLois Curfman McInnes 513bcd2baecSBarry Smith ierr = ViewerGetType(viewer,&vtype); CHKERRQ(ierr); 5143f1db9ecSBarry Smith if (PetscTypeCompare(vtype,ASCII_VIEWER)) { 51539ddd567SLois Curfman McInnes ierr = MatView_MPIDense_ASCII(mat,viewer); CHKERRQ(ierr); 5163f1db9ecSBarry Smith } else if (PetscTypeCompare(vtype,BINARY_VIEWER)) { 5173a40ed3dSBarry Smith ierr = MatView_MPIDense_Binary(mat,viewer);CHKERRQ(ierr); 5185cd90555SBarry Smith } else { 5195cd90555SBarry Smith SETERRQ(1,1,"Viewer type not supported by PETSc object"); 5208965ea79SLois Curfman McInnes } 5213a40ed3dSBarry Smith PetscFunctionReturn(0); 5228965ea79SLois Curfman McInnes } 5238965ea79SLois Curfman McInnes 5245615d1e5SSatish Balay #undef __FUNC__ 5255615d1e5SSatish Balay #define __FUNC__ "MatGetInfo_MPIDense" 5268f6be9afSLois Curfman McInnes int MatGetInfo_MPIDense(Mat A,MatInfoType flag,MatInfo *info) 5278965ea79SLois Curfman McInnes { 5283501a2bdSLois Curfman McInnes Mat_MPIDense *mat = (Mat_MPIDense *) A->data; 5293501a2bdSLois Curfman McInnes Mat mdn = mat->A; 5304e220ebcSLois Curfman McInnes int ierr; 5314e220ebcSLois Curfman McInnes double isend[5], irecv[5]; 5328965ea79SLois Curfman McInnes 5333a40ed3dSBarry Smith PetscFunctionBegin; 5344e220ebcSLois Curfman McInnes info->rows_global = (double)mat->M; 5354e220ebcSLois Curfman McInnes info->columns_global = (double)mat->N; 5364e220ebcSLois Curfman McInnes info->rows_local = (double)mat->m; 5374e220ebcSLois Curfman McInnes info->columns_local = (double)mat->N; 5384e220ebcSLois Curfman McInnes info->block_size = 1.0; 5394e220ebcSLois Curfman McInnes ierr = MatGetInfo(mdn,MAT_LOCAL,info); CHKERRQ(ierr); 5404e220ebcSLois Curfman McInnes isend[0] = info->nz_used; isend[1] = info->nz_allocated; isend[2] = info->nz_unneeded; 5414e220ebcSLois Curfman McInnes isend[3] = info->memory; isend[4] = info->mallocs; 5428965ea79SLois Curfman McInnes if (flag == MAT_LOCAL) { 5434e220ebcSLois Curfman McInnes info->nz_used = isend[0]; 5444e220ebcSLois Curfman McInnes info->nz_allocated = isend[1]; 5454e220ebcSLois Curfman McInnes info->nz_unneeded = isend[2]; 5464e220ebcSLois Curfman McInnes info->memory = isend[3]; 5474e220ebcSLois Curfman McInnes info->mallocs = isend[4]; 5488965ea79SLois Curfman McInnes } else if (flag == MAT_GLOBAL_MAX) { 549f7cdd7c9SBarry Smith ierr = MPI_Allreduce(isend,irecv,5,MPI_DOUBLE,MPI_MAX,A->comm);CHKERRQ(ierr); 5504e220ebcSLois Curfman McInnes info->nz_used = irecv[0]; 5514e220ebcSLois Curfman McInnes info->nz_allocated = irecv[1]; 5524e220ebcSLois Curfman McInnes info->nz_unneeded = irecv[2]; 5534e220ebcSLois Curfman McInnes info->memory = irecv[3]; 5544e220ebcSLois Curfman McInnes info->mallocs = irecv[4]; 5558965ea79SLois Curfman McInnes } else if (flag == MAT_GLOBAL_SUM) { 556f7cdd7c9SBarry Smith ierr = MPI_Allreduce(isend,irecv,5,MPI_DOUBLE,MPI_SUM,A->comm);CHKERRQ(ierr); 5574e220ebcSLois Curfman McInnes info->nz_used = irecv[0]; 5584e220ebcSLois Curfman McInnes info->nz_allocated = irecv[1]; 5594e220ebcSLois Curfman McInnes info->nz_unneeded = irecv[2]; 5604e220ebcSLois Curfman McInnes info->memory = irecv[3]; 5614e220ebcSLois Curfman McInnes info->mallocs = irecv[4]; 5628965ea79SLois Curfman McInnes } 5634e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; /* no parallel LU/ILU/Cholesky */ 5644e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 5654e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 5663a40ed3dSBarry Smith PetscFunctionReturn(0); 5678965ea79SLois Curfman McInnes } 5688965ea79SLois Curfman McInnes 5698c469469SLois Curfman McInnes /* extern int MatLUFactorSymbolic_MPIDense(Mat,IS,IS,double,Mat*); 5708aaee692SLois Curfman McInnes extern int MatLUFactorNumeric_MPIDense(Mat,Mat*); 5718aaee692SLois Curfman McInnes extern int MatLUFactor_MPIDense(Mat,IS,IS,double); 5728aaee692SLois Curfman McInnes extern int MatSolve_MPIDense(Mat,Vec,Vec); 5738c469469SLois Curfman McInnes extern int MatSolveAdd_MPIDense(Mat,Vec,Vec,Vec); 5748aaee692SLois Curfman McInnes extern int MatSolveTrans_MPIDense(Mat,Vec,Vec); 5758aaee692SLois Curfman McInnes extern int MatSolveTransAdd_MPIDense(Mat,Vec,Vec,Vec); */ 5768aaee692SLois Curfman McInnes 5775615d1e5SSatish Balay #undef __FUNC__ 5785615d1e5SSatish Balay #define __FUNC__ "MatSetOption_MPIDense" 5798f6be9afSLois Curfman McInnes int MatSetOption_MPIDense(Mat A,MatOption op) 5808965ea79SLois Curfman McInnes { 58139ddd567SLois Curfman McInnes Mat_MPIDense *a = (Mat_MPIDense *) A->data; 5828965ea79SLois Curfman McInnes 5833a40ed3dSBarry Smith PetscFunctionBegin; 5846d4a8577SBarry Smith if (op == MAT_NO_NEW_NONZERO_LOCATIONS || 5856d4a8577SBarry Smith op == MAT_YES_NEW_NONZERO_LOCATIONS || 5864787f768SSatish Balay op == MAT_NEW_NONZERO_LOCATION_ERR || 5874787f768SSatish Balay op == MAT_NEW_NONZERO_ALLOCATION_ERR || 588219d9a1aSLois Curfman McInnes op == MAT_COLUMNS_SORTED || 589219d9a1aSLois Curfman McInnes op == MAT_COLUMNS_UNSORTED) { 590b1fbbac0SLois Curfman McInnes MatSetOption(a->A,op); 591b1fbbac0SLois Curfman McInnes } else if (op == MAT_ROW_ORIENTED) { 592aeafbbfcSLois Curfman McInnes a->roworiented = 1; 5938965ea79SLois Curfman McInnes MatSetOption(a->A,op); 594b1fbbac0SLois Curfman McInnes } else if (op == MAT_ROWS_SORTED || 595219d9a1aSLois Curfman McInnes op == MAT_ROWS_UNSORTED || 5966d4a8577SBarry Smith op == MAT_SYMMETRIC || 5976d4a8577SBarry Smith op == MAT_STRUCTURALLY_SYMMETRIC || 598b51ba29fSSatish Balay op == MAT_YES_NEW_DIAGONALS || 599b51ba29fSSatish Balay op == MAT_USE_HASH_TABLE) { 600981c4779SBarry Smith PLogInfo(A,"MatSetOption_MPIDense:Option ignored\n"); 6013a40ed3dSBarry Smith } else if (op == MAT_COLUMN_ORIENTED) { 6023a40ed3dSBarry Smith a->roworiented = 0; MatSetOption(a->A,op); 6033782ba37SSatish Balay } else if (op == MAT_IGNORE_OFF_PROC_ENTRIES) { 6043782ba37SSatish Balay a->donotstash = 1; 6053a40ed3dSBarry Smith } else if (op == MAT_NO_NEW_DIAGONALS) { 6063a40ed3dSBarry Smith SETERRQ(PETSC_ERR_SUP,0,"MAT_NO_NEW_DIAGONALS"); 6073a40ed3dSBarry Smith } else { 6083a40ed3dSBarry Smith SETERRQ(PETSC_ERR_SUP,0,"unknown option"); 6093a40ed3dSBarry Smith } 6103a40ed3dSBarry Smith PetscFunctionReturn(0); 6118965ea79SLois Curfman McInnes } 6128965ea79SLois Curfman McInnes 6135615d1e5SSatish Balay #undef __FUNC__ 6145615d1e5SSatish Balay #define __FUNC__ "MatGetSize_MPIDense" 6158f6be9afSLois Curfman McInnes int MatGetSize_MPIDense(Mat A,int *m,int *n) 6168965ea79SLois Curfman McInnes { 6173501a2bdSLois Curfman McInnes Mat_MPIDense *mat = (Mat_MPIDense *) A->data; 6183a40ed3dSBarry Smith 6193a40ed3dSBarry Smith PetscFunctionBegin; 6208965ea79SLois Curfman McInnes *m = mat->M; *n = mat->N; 6213a40ed3dSBarry Smith PetscFunctionReturn(0); 6228965ea79SLois Curfman McInnes } 6238965ea79SLois Curfman McInnes 6245615d1e5SSatish Balay #undef __FUNC__ 6255615d1e5SSatish Balay #define __FUNC__ "MatGetLocalSize_MPIDense" 6268f6be9afSLois Curfman McInnes int MatGetLocalSize_MPIDense(Mat A,int *m,int *n) 6278965ea79SLois Curfman McInnes { 6283501a2bdSLois Curfman McInnes Mat_MPIDense *mat = (Mat_MPIDense *) A->data; 6293a40ed3dSBarry Smith 6303a40ed3dSBarry Smith PetscFunctionBegin; 6318965ea79SLois Curfman McInnes *m = mat->m; *n = mat->N; 6323a40ed3dSBarry Smith PetscFunctionReturn(0); 6338965ea79SLois Curfman McInnes } 6348965ea79SLois Curfman McInnes 6355615d1e5SSatish Balay #undef __FUNC__ 6365615d1e5SSatish Balay #define __FUNC__ "MatGetOwnershipRange_MPIDense" 6378f6be9afSLois Curfman McInnes int MatGetOwnershipRange_MPIDense(Mat A,int *m,int *n) 6388965ea79SLois Curfman McInnes { 6393501a2bdSLois Curfman McInnes Mat_MPIDense *mat = (Mat_MPIDense *) A->data; 6403a40ed3dSBarry Smith 6413a40ed3dSBarry Smith PetscFunctionBegin; 6428965ea79SLois Curfman McInnes *m = mat->rstart; *n = mat->rend; 6433a40ed3dSBarry Smith PetscFunctionReturn(0); 6448965ea79SLois Curfman McInnes } 6458965ea79SLois Curfman McInnes 6465615d1e5SSatish Balay #undef __FUNC__ 6475615d1e5SSatish Balay #define __FUNC__ "MatGetRow_MPIDense" 6488f6be9afSLois Curfman McInnes int MatGetRow_MPIDense(Mat A,int row,int *nz,int **idx,Scalar **v) 6498965ea79SLois Curfman McInnes { 6503501a2bdSLois Curfman McInnes Mat_MPIDense *mat = (Mat_MPIDense *) A->data; 6513a40ed3dSBarry Smith int lrow, rstart = mat->rstart, rend = mat->rend,ierr; 6528965ea79SLois Curfman McInnes 6533a40ed3dSBarry Smith PetscFunctionBegin; 654a8c6a408SBarry Smith if (row < rstart || row >= rend) SETERRQ(PETSC_ERR_SUP,0,"only local rows") 6558965ea79SLois Curfman McInnes lrow = row - rstart; 6563a40ed3dSBarry Smith ierr = MatGetRow(mat->A,lrow,nz,idx,v);CHKERRQ(ierr); 6573a40ed3dSBarry Smith PetscFunctionReturn(0); 6588965ea79SLois Curfman McInnes } 6598965ea79SLois Curfman McInnes 6605615d1e5SSatish Balay #undef __FUNC__ 6615615d1e5SSatish Balay #define __FUNC__ "MatRestoreRow_MPIDense" 6628f6be9afSLois Curfman McInnes int MatRestoreRow_MPIDense(Mat mat,int row,int *nz,int **idx,Scalar **v) 6638965ea79SLois Curfman McInnes { 6643a40ed3dSBarry Smith PetscFunctionBegin; 6650452661fSBarry Smith if (idx) PetscFree(*idx); 6660452661fSBarry Smith if (v) PetscFree(*v); 6673a40ed3dSBarry Smith PetscFunctionReturn(0); 6688965ea79SLois Curfman McInnes } 6698965ea79SLois Curfman McInnes 6705615d1e5SSatish Balay #undef __FUNC__ 6715615d1e5SSatish Balay #define __FUNC__ "MatNorm_MPIDense" 6728f6be9afSLois Curfman McInnes int MatNorm_MPIDense(Mat A,NormType type,double *norm) 673096963f5SLois Curfman McInnes { 6743501a2bdSLois Curfman McInnes Mat_MPIDense *mdn = (Mat_MPIDense *) A->data; 6753501a2bdSLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*) mdn->A->data; 6763501a2bdSLois Curfman McInnes int ierr, i, j; 6773501a2bdSLois Curfman McInnes double sum = 0.0; 6783501a2bdSLois Curfman McInnes Scalar *v = mat->v; 6793501a2bdSLois Curfman McInnes 6803a40ed3dSBarry Smith PetscFunctionBegin; 6813501a2bdSLois Curfman McInnes if (mdn->size == 1) { 6823501a2bdSLois Curfman McInnes ierr = MatNorm(mdn->A,type,norm); CHKERRQ(ierr); 6833501a2bdSLois Curfman McInnes } else { 6843501a2bdSLois Curfman McInnes if (type == NORM_FROBENIUS) { 6853501a2bdSLois Curfman McInnes for (i=0; i<mat->n*mat->m; i++ ) { 6863a40ed3dSBarry Smith #if defined(USE_PETSC_COMPLEX) 687e20fef11SSatish Balay sum += PetscReal(PetscConj(*v)*(*v)); v++; 6883501a2bdSLois Curfman McInnes #else 6893501a2bdSLois Curfman McInnes sum += (*v)*(*v); v++; 6903501a2bdSLois Curfman McInnes #endif 6913501a2bdSLois Curfman McInnes } 692ca161407SBarry Smith ierr = MPI_Allreduce(&sum,norm,1,MPI_DOUBLE,MPI_SUM,A->comm);CHKERRQ(ierr); 6933501a2bdSLois Curfman McInnes *norm = sqrt(*norm); 6943501a2bdSLois Curfman McInnes PLogFlops(2*mat->n*mat->m); 6953a40ed3dSBarry Smith } else if (type == NORM_1) { 6963501a2bdSLois Curfman McInnes double *tmp, *tmp2; 6970452661fSBarry Smith tmp = (double *) PetscMalloc( 2*mdn->N*sizeof(double) ); CHKPTRQ(tmp); 6983501a2bdSLois Curfman McInnes tmp2 = tmp + mdn->N; 699cddf8d76SBarry Smith PetscMemzero(tmp,2*mdn->N*sizeof(double)); 700096963f5SLois Curfman McInnes *norm = 0.0; 7013501a2bdSLois Curfman McInnes v = mat->v; 7023501a2bdSLois Curfman McInnes for ( j=0; j<mat->n; j++ ) { 7033501a2bdSLois Curfman McInnes for ( i=0; i<mat->m; i++ ) { 70467e560aaSBarry Smith tmp[j] += PetscAbsScalar(*v); v++; 7053501a2bdSLois Curfman McInnes } 7063501a2bdSLois Curfman McInnes } 707ca161407SBarry Smith ierr = MPI_Allreduce(tmp,tmp2,mdn->N,MPI_DOUBLE,MPI_SUM,A->comm);CHKERRQ(ierr); 7083501a2bdSLois Curfman McInnes for ( j=0; j<mdn->N; j++ ) { 7093501a2bdSLois Curfman McInnes if (tmp2[j] > *norm) *norm = tmp2[j]; 7103501a2bdSLois Curfman McInnes } 7110452661fSBarry Smith PetscFree(tmp); 7123501a2bdSLois Curfman McInnes PLogFlops(mat->n*mat->m); 7133a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { /* max row norm */ 7143501a2bdSLois Curfman McInnes double ntemp; 7153501a2bdSLois Curfman McInnes ierr = MatNorm(mdn->A,type,&ntemp); CHKERRQ(ierr); 716ca161407SBarry Smith ierr = MPI_Allreduce(&ntemp,norm,1,MPI_DOUBLE,MPI_MAX,A->comm);CHKERRQ(ierr); 7173a40ed3dSBarry Smith } else { 718a8c6a408SBarry Smith SETERRQ(PETSC_ERR_SUP,0,"No support for two norm"); 7193501a2bdSLois Curfman McInnes } 7203501a2bdSLois Curfman McInnes } 7213a40ed3dSBarry Smith PetscFunctionReturn(0); 7223501a2bdSLois Curfman McInnes } 7233501a2bdSLois Curfman McInnes 7245615d1e5SSatish Balay #undef __FUNC__ 7255615d1e5SSatish Balay #define __FUNC__ "MatTranspose_MPIDense" 7268f6be9afSLois Curfman McInnes int MatTranspose_MPIDense(Mat A,Mat *matout) 7273501a2bdSLois Curfman McInnes { 7283501a2bdSLois Curfman McInnes Mat_MPIDense *a = (Mat_MPIDense *) A->data; 7293501a2bdSLois Curfman McInnes Mat_SeqDense *Aloc = (Mat_SeqDense *) a->A->data; 7303501a2bdSLois Curfman McInnes Mat B; 7313501a2bdSLois Curfman McInnes int M = a->M, N = a->N, m, n, *rwork, rstart = a->rstart; 7323501a2bdSLois Curfman McInnes int j, i, ierr; 7333501a2bdSLois Curfman McInnes Scalar *v; 7343501a2bdSLois Curfman McInnes 7353a40ed3dSBarry Smith PetscFunctionBegin; 7367056b6fcSBarry Smith if (matout == PETSC_NULL && M != N) { 737a8c6a408SBarry Smith SETERRQ(PETSC_ERR_SUP,0,"Supports square matrix only in-place"); 7387056b6fcSBarry Smith } 7397056b6fcSBarry Smith ierr = MatCreateMPIDense(A->comm,PETSC_DECIDE,PETSC_DECIDE,N,M,PETSC_NULL,&B);CHKERRQ(ierr); 7403501a2bdSLois Curfman McInnes 7413501a2bdSLois Curfman McInnes m = Aloc->m; n = Aloc->n; v = Aloc->v; 7420452661fSBarry Smith rwork = (int *) PetscMalloc(n*sizeof(int)); CHKPTRQ(rwork); 7433501a2bdSLois Curfman McInnes for ( j=0; j<n; j++ ) { 7443501a2bdSLois Curfman McInnes for (i=0; i<m; i++) rwork[i] = rstart + i; 7453501a2bdSLois Curfman McInnes ierr = MatSetValues(B,1,&j,m,rwork,v,INSERT_VALUES); CHKERRQ(ierr); 7463501a2bdSLois Curfman McInnes v += m; 7473501a2bdSLois Curfman McInnes } 7480452661fSBarry Smith PetscFree(rwork); 7496d4a8577SBarry Smith ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 7506d4a8577SBarry Smith ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 7513638b69dSLois Curfman McInnes if (matout != PETSC_NULL) { 7523501a2bdSLois Curfman McInnes *matout = B; 7533501a2bdSLois Curfman McInnes } else { 754f830108cSBarry Smith PetscOps *Abops; 75509dc0095SBarry Smith MatOps Aops; 756f830108cSBarry Smith 7573501a2bdSLois Curfman McInnes /* This isn't really an in-place transpose, but free data struct from a */ 7580452661fSBarry Smith PetscFree(a->rowners); 7593501a2bdSLois Curfman McInnes ierr = MatDestroy(a->A); CHKERRQ(ierr); 7603501a2bdSLois Curfman McInnes if (a->lvec) VecDestroy(a->lvec); 7613501a2bdSLois Curfman McInnes if (a->Mvctx) VecScatterDestroy(a->Mvctx); 7620452661fSBarry Smith PetscFree(a); 763f830108cSBarry Smith 764f830108cSBarry Smith /* 765f830108cSBarry Smith This is horrible, horrible code. We need to keep the 766f830108cSBarry Smith A pointers for the bops and ops but copy everything 767f830108cSBarry Smith else from C. 768f830108cSBarry Smith */ 769f830108cSBarry Smith Abops = A->bops; 770f830108cSBarry Smith Aops = A->ops; 771f09e8eb9SSatish Balay PetscMemcpy(A,B,sizeof(struct _p_Mat)); 772f830108cSBarry Smith A->bops = Abops; 773f830108cSBarry Smith A->ops = Aops; 774f830108cSBarry Smith 7750452661fSBarry Smith PetscHeaderDestroy(B); 7763501a2bdSLois Curfman McInnes } 7773a40ed3dSBarry Smith PetscFunctionReturn(0); 778096963f5SLois Curfman McInnes } 779096963f5SLois Curfman McInnes 780eadb2fb4SBarry Smith #include "pinclude/blaslapack.h" 7815615d1e5SSatish Balay #undef __FUNC__ 7825615d1e5SSatish Balay #define __FUNC__ "MatScale_MPIDense" 7838f6be9afSLois Curfman McInnes int MatScale_MPIDense(Scalar *alpha,Mat inA) 78444cd7ae7SLois Curfman McInnes { 78544cd7ae7SLois Curfman McInnes Mat_MPIDense *A = (Mat_MPIDense *) inA->data; 78644cd7ae7SLois Curfman McInnes Mat_SeqDense *a = (Mat_SeqDense *) A->A->data; 78744cd7ae7SLois Curfman McInnes int one = 1, nz; 78844cd7ae7SLois Curfman McInnes 7893a40ed3dSBarry Smith PetscFunctionBegin; 79044cd7ae7SLois Curfman McInnes nz = a->m*a->n; 79144cd7ae7SLois Curfman McInnes BLscal_( &nz, alpha, a->v, &one ); 79244cd7ae7SLois Curfman McInnes PLogFlops(nz); 7933a40ed3dSBarry Smith PetscFunctionReturn(0); 79444cd7ae7SLois Curfman McInnes } 79544cd7ae7SLois Curfman McInnes 7965609ef8eSBarry Smith static int MatDuplicate_MPIDense(Mat,MatDuplicateOption,Mat *); 7977b2a1423SBarry Smith extern int MatGetSubMatrices_MPIDense(Mat,int,IS *,IS *,MatReuse,Mat **); 7988965ea79SLois Curfman McInnes 7998965ea79SLois Curfman McInnes /* -------------------------------------------------------------------*/ 80009dc0095SBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_MPIDense, 80109dc0095SBarry Smith MatGetRow_MPIDense, 80209dc0095SBarry Smith MatRestoreRow_MPIDense, 80309dc0095SBarry Smith MatMult_MPIDense, 80409dc0095SBarry Smith MatMultAdd_MPIDense, 80509dc0095SBarry Smith MatMultTrans_MPIDense, 80609dc0095SBarry Smith MatMultTransAdd_MPIDense, 8078965ea79SLois Curfman McInnes 0, 80809dc0095SBarry Smith 0, 80909dc0095SBarry Smith 0, 81009dc0095SBarry Smith 0, 81109dc0095SBarry Smith 0, 81209dc0095SBarry Smith 0, 81309dc0095SBarry Smith 0, 81409dc0095SBarry Smith MatTranspose_MPIDense, 81509dc0095SBarry Smith MatGetInfo_MPIDense,0, 81609dc0095SBarry Smith MatGetDiagonal_MPIDense, 81709dc0095SBarry Smith 0, 81809dc0095SBarry Smith MatNorm_MPIDense, 81909dc0095SBarry Smith MatAssemblyBegin_MPIDense, 82009dc0095SBarry Smith MatAssemblyEnd_MPIDense, 82109dc0095SBarry Smith 0, 82209dc0095SBarry Smith MatSetOption_MPIDense, 82309dc0095SBarry Smith MatZeroEntries_MPIDense, 82409dc0095SBarry Smith MatZeroRows_MPIDense, 82509dc0095SBarry Smith 0, 82609dc0095SBarry Smith 0, 82709dc0095SBarry Smith 0, 82809dc0095SBarry Smith 0, 82909dc0095SBarry Smith MatGetSize_MPIDense, 83009dc0095SBarry Smith MatGetLocalSize_MPIDense, 83139ddd567SLois Curfman McInnes MatGetOwnershipRange_MPIDense, 83209dc0095SBarry Smith 0, 83309dc0095SBarry Smith 0, 83409dc0095SBarry Smith MatGetArray_MPIDense, 83509dc0095SBarry Smith MatRestoreArray_MPIDense, 8365609ef8eSBarry Smith MatDuplicate_MPIDense, 83709dc0095SBarry Smith 0, 83809dc0095SBarry Smith 0, 83909dc0095SBarry Smith 0, 84009dc0095SBarry Smith 0, 84109dc0095SBarry Smith 0, 8422ce60cd0SSatish Balay MatGetSubMatrices_MPIDense, 84309dc0095SBarry Smith 0, 84409dc0095SBarry Smith MatGetValues_MPIDense, 84509dc0095SBarry Smith 0, 84609dc0095SBarry Smith 0, 84709dc0095SBarry Smith MatScale_MPIDense, 84809dc0095SBarry Smith 0, 84909dc0095SBarry Smith 0, 85009dc0095SBarry Smith 0, 85109dc0095SBarry Smith MatGetBlockSize_MPIDense, 85209dc0095SBarry Smith 0, 85309dc0095SBarry Smith 0, 85409dc0095SBarry Smith 0, 85509dc0095SBarry Smith 0, 85609dc0095SBarry Smith 0, 85709dc0095SBarry Smith 0, 85809dc0095SBarry Smith 0, 85909dc0095SBarry Smith 0, 86009dc0095SBarry Smith 0, 86109dc0095SBarry Smith 0, 86209dc0095SBarry Smith 0, 86309dc0095SBarry Smith 0, 86409dc0095SBarry Smith MatGetMaps_Petsc}; 8658965ea79SLois Curfman McInnes 8665615d1e5SSatish Balay #undef __FUNC__ 8675615d1e5SSatish Balay #define __FUNC__ "MatCreateMPIDense" 8688965ea79SLois Curfman McInnes /*@C 86939ddd567SLois Curfman McInnes MatCreateMPIDense - Creates a sparse parallel matrix in dense format. 8708965ea79SLois Curfman McInnes 871db81eaa0SLois Curfman McInnes Collective on MPI_Comm 872db81eaa0SLois Curfman McInnes 8738965ea79SLois Curfman McInnes Input Parameters: 874db81eaa0SLois Curfman McInnes + comm - MPI communicator 8758965ea79SLois Curfman McInnes . m - number of local rows (or PETSC_DECIDE to have calculated if M is given) 876db81eaa0SLois Curfman McInnes . n - number of local columns (or PETSC_DECIDE to have calculated if N is given) 8778965ea79SLois Curfman McInnes . M - number of global rows (or PETSC_DECIDE to have calculated if m is given) 878db81eaa0SLois Curfman McInnes . N - number of global columns (or PETSC_DECIDE to have calculated if n is given) 879db81eaa0SLois Curfman McInnes - data - optional location of matrix data. Set data=PETSC_NULL for PETSc 880dfc5480cSLois Curfman McInnes to control all matrix memory allocation. 8818965ea79SLois Curfman McInnes 8828965ea79SLois Curfman McInnes Output Parameter: 883477f1c0bSLois Curfman McInnes . A - the matrix 8848965ea79SLois Curfman McInnes 885b259b22eSLois Curfman McInnes Notes: 88639ddd567SLois Curfman McInnes The dense format is fully compatible with standard Fortran 77 88739ddd567SLois Curfman McInnes storage by columns. 8888965ea79SLois Curfman McInnes 88918f449edSLois Curfman McInnes The data input variable is intended primarily for Fortran programmers 89018f449edSLois Curfman McInnes who wish to allocate their own matrix memory space. Most users should 891b4fd4287SBarry Smith set data=PETSC_NULL. 89218f449edSLois Curfman McInnes 8938965ea79SLois Curfman McInnes The user MUST specify either the local or global matrix dimensions 8948965ea79SLois Curfman McInnes (possibly both). 8958965ea79SLois Curfman McInnes 8963501a2bdSLois Curfman McInnes Currently, the only parallel dense matrix decomposition is by rows, 8973501a2bdSLois Curfman McInnes so that n=N and each submatrix owns all of the global columns. 8983501a2bdSLois Curfman McInnes 899027ccd11SLois Curfman McInnes Level: intermediate 900027ccd11SLois Curfman McInnes 90139ddd567SLois Curfman McInnes .keywords: matrix, dense, parallel 9028965ea79SLois Curfman McInnes 90339ddd567SLois Curfman McInnes .seealso: MatCreate(), MatCreateSeqDense(), MatSetValues() 9048965ea79SLois Curfman McInnes @*/ 905477f1c0bSLois Curfman McInnes int MatCreateMPIDense(MPI_Comm comm,int m,int n,int M,int N,Scalar *data,Mat *A) 9068965ea79SLois Curfman McInnes { 9078965ea79SLois Curfman McInnes Mat mat; 90839ddd567SLois Curfman McInnes Mat_MPIDense *a; 90925cdf11fSBarry Smith int ierr, i,flg; 9108965ea79SLois Curfman McInnes 9113a40ed3dSBarry Smith PetscFunctionBegin; 912ed2daf61SLois Curfman McInnes /* Note: For now, when data is specified above, this assumes the user correctly 913ed2daf61SLois Curfman McInnes allocates the local dense storage space. We should add error checking. */ 91418f449edSLois Curfman McInnes 915477f1c0bSLois Curfman McInnes *A = 0; 9163f1db9ecSBarry Smith PetscHeaderCreate(mat,_p_Mat,struct _MatOps,MAT_COOKIE,MATMPIDENSE,"Mat",comm,MatDestroy,MatView); 9178965ea79SLois Curfman McInnes PLogObjectCreate(mat); 9180452661fSBarry Smith mat->data = (void *) (a = PetscNew(Mat_MPIDense)); CHKPTRQ(a); 91909dc0095SBarry Smith PetscMemcpy(mat->ops,&MatOps_Values,sizeof(struct _MatOps)); 920e1311b90SBarry Smith mat->ops->destroy = MatDestroy_MPIDense; 921e1311b90SBarry Smith mat->ops->view = MatView_MPIDense; 9228965ea79SLois Curfman McInnes mat->factor = 0; 92390f02eecSBarry Smith mat->mapping = 0; 9248965ea79SLois Curfman McInnes 925622d7880SLois Curfman McInnes a->factor = 0; 926e0fa3b82SLois Curfman McInnes mat->insertmode = NOT_SET_VALUES; 927*d132466eSBarry Smith ierr = MPI_Comm_rank(comm,&a->rank);CHKERRQ(ierr); 928*d132466eSBarry Smith ierr = MPI_Comm_size(comm,&a->size);CHKERRQ(ierr); 9298965ea79SLois Curfman McInnes 93096f6c058SBarry Smith ierr = PetscSplitOwnership(comm,&m,&M);CHKERRQ(ierr); 93139ddd567SLois Curfman McInnes 932c7fcc2eaSBarry Smith /* 933c7fcc2eaSBarry Smith The computation of n is wrong below, n should represent the number of local 934c7fcc2eaSBarry Smith rows in the right (column vector) 935c7fcc2eaSBarry Smith */ 936c7fcc2eaSBarry Smith 93739ddd567SLois Curfman McInnes /* each row stores all columns */ 93839ddd567SLois Curfman McInnes if (N == PETSC_DECIDE) N = n; 939d7e8b826SBarry Smith if (n == PETSC_DECIDE) {n = N/a->size + ((N % a->size) > a->rank);} 940a8c6a408SBarry Smith /* if (n != N) SETERRQ(PETSC_ERR_SUP,0,"For now, only n=N is supported"); */ 941aca0ad90SLois Curfman McInnes a->N = mat->N = N; 942aca0ad90SLois Curfman McInnes a->M = mat->M = M; 943aca0ad90SLois Curfman McInnes a->m = mat->m = m; 944aca0ad90SLois Curfman McInnes a->n = mat->n = n; 9458965ea79SLois Curfman McInnes 946c7fcc2eaSBarry Smith /* the information in the maps duplicates the information computed below, eventually 947c7fcc2eaSBarry Smith we should remove the duplicate information that is not contained in the maps */ 948488ecbafSBarry Smith ierr = MapCreateMPI(comm,m,M,&mat->rmap);CHKERRQ(ierr); 94996f6c058SBarry Smith ierr = MapCreateMPI(comm,PETSC_DECIDE,N,&mat->cmap);CHKERRQ(ierr); 950c7fcc2eaSBarry Smith 9518965ea79SLois Curfman McInnes /* build local table of row and column ownerships */ 952d7e8b826SBarry Smith a->rowners = (int *) PetscMalloc(2*(a->size+2)*sizeof(int)); CHKPTRQ(a->rowners); 953d7e8b826SBarry Smith a->cowners = a->rowners + a->size + 1; 954f09e8eb9SSatish Balay PLogObjectMemory(mat,2*(a->size+2)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_MPIDense)); 955ca161407SBarry Smith ierr = MPI_Allgather(&m,1,MPI_INT,a->rowners+1,1,MPI_INT,comm);CHKERRQ(ierr); 9568965ea79SLois Curfman McInnes a->rowners[0] = 0; 9578965ea79SLois Curfman McInnes for ( i=2; i<=a->size; i++ ) { 9588965ea79SLois Curfman McInnes a->rowners[i] += a->rowners[i-1]; 9598965ea79SLois Curfman McInnes } 9608965ea79SLois Curfman McInnes a->rstart = a->rowners[a->rank]; 9618965ea79SLois Curfman McInnes a->rend = a->rowners[a->rank+1]; 962ca161407SBarry Smith ierr = MPI_Allgather(&n,1,MPI_INT,a->cowners+1,1,MPI_INT,comm);CHKERRQ(ierr); 963d7e8b826SBarry Smith a->cowners[0] = 0; 964d7e8b826SBarry Smith for ( i=2; i<=a->size; i++ ) { 965d7e8b826SBarry Smith a->cowners[i] += a->cowners[i-1]; 966d7e8b826SBarry Smith } 9678965ea79SLois Curfman McInnes 968029af93fSBarry Smith ierr = MatCreateSeqDense(PETSC_COMM_SELF,m,N,data,&a->A); CHKERRQ(ierr); 9698965ea79SLois Curfman McInnes PLogObjectParent(mat,a->A); 9708965ea79SLois Curfman McInnes 9718965ea79SLois Curfman McInnes /* build cache for off array entries formed */ 9723782ba37SSatish Balay a->donotstash = 0; 9738798bf22SSatish Balay ierr = MatStashCreate_Private(comm,1,&mat->stash); CHKERRQ(ierr); 9748965ea79SLois Curfman McInnes 9758965ea79SLois Curfman McInnes /* stuff used for matrix vector multiply */ 9768965ea79SLois Curfman McInnes a->lvec = 0; 9778965ea79SLois Curfman McInnes a->Mvctx = 0; 97839b7565bSBarry Smith a->roworiented = 1; 9798965ea79SLois Curfman McInnes 980477f1c0bSLois Curfman McInnes *A = mat; 98125cdf11fSBarry Smith ierr = OptionsHasName(PETSC_NULL,"-help",&flg); CHKERRQ(ierr); 98225cdf11fSBarry Smith if (flg) { 9838c469469SLois Curfman McInnes ierr = MatPrintHelp(mat); CHKERRQ(ierr); 9848c469469SLois Curfman McInnes } 9853a40ed3dSBarry Smith PetscFunctionReturn(0); 9868965ea79SLois Curfman McInnes } 9878965ea79SLois Curfman McInnes 9885615d1e5SSatish Balay #undef __FUNC__ 9895609ef8eSBarry Smith #define __FUNC__ "MatDuplicate_MPIDense" 9905609ef8eSBarry Smith static int MatDuplicate_MPIDense(Mat A,MatDuplicateOption cpvalues,Mat *newmat) 9918965ea79SLois Curfman McInnes { 9928965ea79SLois Curfman McInnes Mat mat; 9933501a2bdSLois Curfman McInnes Mat_MPIDense *a,*oldmat = (Mat_MPIDense *) A->data; 99439ddd567SLois Curfman McInnes int ierr; 9952ba99913SLois Curfman McInnes FactorCtx *factor; 9968965ea79SLois Curfman McInnes 9973a40ed3dSBarry Smith PetscFunctionBegin; 9988965ea79SLois Curfman McInnes *newmat = 0; 9993f1db9ecSBarry Smith PetscHeaderCreate(mat,_p_Mat,struct _MatOps,MAT_COOKIE,MATMPIDENSE,"Mat",A->comm,MatDestroy,MatView); 10008965ea79SLois Curfman McInnes PLogObjectCreate(mat); 10010452661fSBarry Smith mat->data = (void *) (a = PetscNew(Mat_MPIDense)); CHKPTRQ(a); 100209dc0095SBarry Smith PetscMemcpy(mat->ops,&MatOps_Values,sizeof(struct _MatOps)); 1003e1311b90SBarry Smith mat->ops->destroy = MatDestroy_MPIDense; 1004e1311b90SBarry Smith mat->ops->view = MatView_MPIDense; 10053501a2bdSLois Curfman McInnes mat->factor = A->factor; 1006c456f294SBarry Smith mat->assembled = PETSC_TRUE; 10078965ea79SLois Curfman McInnes 100844cd7ae7SLois Curfman McInnes a->m = mat->m = oldmat->m; 100944cd7ae7SLois Curfman McInnes a->n = mat->n = oldmat->n; 101044cd7ae7SLois Curfman McInnes a->M = mat->M = oldmat->M; 101144cd7ae7SLois Curfman McInnes a->N = mat->N = oldmat->N; 10122ba99913SLois Curfman McInnes if (oldmat->factor) { 10132ba99913SLois Curfman McInnes a->factor = (FactorCtx *) (factor = PetscNew(FactorCtx)); CHKPTRQ(factor); 10142ba99913SLois Curfman McInnes /* copy factor contents ... add this code! */ 10152ba99913SLois Curfman McInnes } else a->factor = 0; 10168965ea79SLois Curfman McInnes 10178965ea79SLois Curfman McInnes a->rstart = oldmat->rstart; 10188965ea79SLois Curfman McInnes a->rend = oldmat->rend; 10198965ea79SLois Curfman McInnes a->size = oldmat->size; 10208965ea79SLois Curfman McInnes a->rank = oldmat->rank; 1021e0fa3b82SLois Curfman McInnes mat->insertmode = NOT_SET_VALUES; 10223782ba37SSatish Balay a->donotstash = oldmat->donotstash; 10230452661fSBarry Smith a->rowners = (int *) PetscMalloc((a->size+1)*sizeof(int)); CHKPTRQ(a->rowners); 1024f09e8eb9SSatish Balay PLogObjectMemory(mat,(a->size+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_MPIDense)); 10258965ea79SLois Curfman McInnes PetscMemcpy(a->rowners,oldmat->rowners,(a->size+1)*sizeof(int)); 10268798bf22SSatish Balay ierr = MatStashCreate_Private(A->comm,1,&mat->stash); CHKERRQ(ierr); 10278965ea79SLois Curfman McInnes 10288965ea79SLois Curfman McInnes ierr = VecDuplicate(oldmat->lvec,&a->lvec); CHKERRQ(ierr); 10298965ea79SLois Curfman McInnes PLogObjectParent(mat,a->lvec); 103055659b69SBarry Smith ierr = VecScatterCopy(oldmat->Mvctx,&a->Mvctx); CHKERRQ(ierr); 10318965ea79SLois Curfman McInnes PLogObjectParent(mat,a->Mvctx); 10325609ef8eSBarry Smith ierr = MatDuplicate(oldmat->A,cpvalues,&a->A); CHKERRQ(ierr); 10338965ea79SLois Curfman McInnes PLogObjectParent(mat,a->A); 10348965ea79SLois Curfman McInnes *newmat = mat; 10353a40ed3dSBarry Smith PetscFunctionReturn(0); 10368965ea79SLois Curfman McInnes } 10378965ea79SLois Curfman McInnes 103877c4ece6SBarry Smith #include "sys.h" 10398965ea79SLois Curfman McInnes 10405615d1e5SSatish Balay #undef __FUNC__ 10415615d1e5SSatish Balay #define __FUNC__ "MatLoad_MPIDense_DenseInFile" 104290ace30eSBarry Smith int MatLoad_MPIDense_DenseInFile(MPI_Comm comm,int fd,int M, int N, Mat *newmat) 104390ace30eSBarry Smith { 104440011551SBarry Smith int *rowners, i,size,rank,m,ierr,nz,j; 104590ace30eSBarry Smith Scalar *array,*vals,*vals_ptr; 104690ace30eSBarry Smith MPI_Status status; 104790ace30eSBarry Smith 10483a40ed3dSBarry Smith PetscFunctionBegin; 1049*d132466eSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 1050*d132466eSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 105190ace30eSBarry Smith 105290ace30eSBarry Smith /* determine ownership of all rows */ 105390ace30eSBarry Smith m = M/size + ((M % size) > rank); 105490ace30eSBarry Smith rowners = (int *) PetscMalloc((size+2)*sizeof(int)); CHKPTRQ(rowners); 1055ca161407SBarry Smith ierr = MPI_Allgather(&m,1,MPI_INT,rowners+1,1,MPI_INT,comm);CHKERRQ(ierr); 105690ace30eSBarry Smith rowners[0] = 0; 105790ace30eSBarry Smith for ( i=2; i<=size; i++ ) { 105890ace30eSBarry Smith rowners[i] += rowners[i-1]; 105990ace30eSBarry Smith } 106090ace30eSBarry Smith 106190ace30eSBarry Smith ierr = MatCreateMPIDense(comm,m,PETSC_DECIDE,M,N,PETSC_NULL,newmat);CHKERRQ(ierr); 106290ace30eSBarry Smith ierr = MatGetArray(*newmat,&array); CHKERRQ(ierr); 106390ace30eSBarry Smith 106490ace30eSBarry Smith if (!rank) { 106590ace30eSBarry Smith vals = (Scalar *) PetscMalloc( m*N*sizeof(Scalar) ); CHKPTRQ(vals); 106690ace30eSBarry Smith 106790ace30eSBarry Smith /* read in my part of the matrix numerical values */ 10680752156aSBarry Smith ierr = PetscBinaryRead(fd,vals,m*N,PETSC_SCALAR); CHKERRQ(ierr); 106990ace30eSBarry Smith 107090ace30eSBarry Smith /* insert into matrix-by row (this is why cannot directly read into array */ 107190ace30eSBarry Smith vals_ptr = vals; 107290ace30eSBarry Smith for ( i=0; i<m; i++ ) { 107390ace30eSBarry Smith for ( j=0; j<N; j++ ) { 107490ace30eSBarry Smith array[i + j*m] = *vals_ptr++; 107590ace30eSBarry Smith } 107690ace30eSBarry Smith } 107790ace30eSBarry Smith 107890ace30eSBarry Smith /* read in other processors and ship out */ 107990ace30eSBarry Smith for ( i=1; i<size; i++ ) { 108090ace30eSBarry Smith nz = (rowners[i+1] - rowners[i])*N; 10810752156aSBarry Smith ierr = PetscBinaryRead(fd,vals,nz,PETSC_SCALAR); CHKERRQ(ierr); 1082ca161407SBarry Smith ierr = MPI_Send(vals,nz,MPIU_SCALAR,i,(*newmat)->tag,comm);CHKERRQ(ierr); 108390ace30eSBarry Smith } 10843a40ed3dSBarry Smith } else { 108590ace30eSBarry Smith /* receive numeric values */ 108690ace30eSBarry Smith vals = (Scalar*) PetscMalloc( m*N*sizeof(Scalar) ); CHKPTRQ(vals); 108790ace30eSBarry Smith 108890ace30eSBarry Smith /* receive message of values*/ 1089ca161407SBarry Smith ierr = MPI_Recv(vals,m*N,MPIU_SCALAR,0,(*newmat)->tag,comm,&status);CHKERRQ(ierr); 109090ace30eSBarry Smith 109190ace30eSBarry Smith /* insert into matrix-by row (this is why cannot directly read into array */ 109290ace30eSBarry Smith vals_ptr = vals; 109390ace30eSBarry Smith for ( i=0; i<m; i++ ) { 109490ace30eSBarry Smith for ( j=0; j<N; j++ ) { 109590ace30eSBarry Smith array[i + j*m] = *vals_ptr++; 109690ace30eSBarry Smith } 109790ace30eSBarry Smith } 109890ace30eSBarry Smith } 109990ace30eSBarry Smith PetscFree(rowners); 110090ace30eSBarry Smith PetscFree(vals); 11016d4a8577SBarry Smith ierr = MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 11026d4a8577SBarry Smith ierr = MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 11033a40ed3dSBarry Smith PetscFunctionReturn(0); 110490ace30eSBarry Smith } 110590ace30eSBarry Smith 110690ace30eSBarry Smith 11075615d1e5SSatish Balay #undef __FUNC__ 11085615d1e5SSatish Balay #define __FUNC__ "MatLoad_MPIDense" 110919bcc07fSBarry Smith int MatLoad_MPIDense(Viewer viewer,MatType type,Mat *newmat) 11108965ea79SLois Curfman McInnes { 11118965ea79SLois Curfman McInnes Mat A; 11128965ea79SLois Curfman McInnes Scalar *vals,*svals; 111319bcc07fSBarry Smith MPI_Comm comm = ((PetscObject)viewer)->comm; 11148965ea79SLois Curfman McInnes MPI_Status status; 11158965ea79SLois Curfman McInnes int header[4],rank,size,*rowlengths = 0,M,N,m,*rowners,maxnz,*cols; 11168965ea79SLois Curfman McInnes int *ourlens,*sndcounts = 0,*procsnz = 0, *offlens,jj,*mycols,*smycols; 111719bcc07fSBarry Smith int tag = ((PetscObject)viewer)->tag; 11183a40ed3dSBarry Smith int i, nz, ierr, j,rstart, rend, fd; 11198965ea79SLois Curfman McInnes 11203a40ed3dSBarry Smith PetscFunctionBegin; 1121*d132466eSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 1122*d132466eSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 11238965ea79SLois Curfman McInnes if (!rank) { 112490ace30eSBarry Smith ierr = ViewerBinaryGetDescriptor(viewer,&fd); CHKERRQ(ierr); 11250752156aSBarry Smith ierr = PetscBinaryRead(fd,(char *)header,4,PETSC_INT); CHKERRQ(ierr); 1126a8c6a408SBarry Smith if (header[0] != MAT_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,0,"not matrix object"); 11278965ea79SLois Curfman McInnes } 11288965ea79SLois Curfman McInnes 1129ca161407SBarry Smith ierr = MPI_Bcast(header+1,3,MPI_INT,0,comm);CHKERRQ(ierr); 113090ace30eSBarry Smith M = header[1]; N = header[2]; nz = header[3]; 113190ace30eSBarry Smith 113290ace30eSBarry Smith /* 113390ace30eSBarry Smith Handle case where matrix is stored on disk as a dense matrix 113490ace30eSBarry Smith */ 113590ace30eSBarry Smith if (nz == MATRIX_BINARY_FORMAT_DENSE) { 11363a40ed3dSBarry Smith ierr = MatLoad_MPIDense_DenseInFile(comm,fd,M,N,newmat);CHKERRQ(ierr); 11373a40ed3dSBarry Smith PetscFunctionReturn(0); 113890ace30eSBarry Smith } 113990ace30eSBarry Smith 11408965ea79SLois Curfman McInnes /* determine ownership of all rows */ 11418965ea79SLois Curfman McInnes m = M/size + ((M % size) > rank); 11420452661fSBarry Smith rowners = (int *) PetscMalloc((size+2)*sizeof(int)); CHKPTRQ(rowners); 1143ca161407SBarry Smith ierr = MPI_Allgather(&m,1,MPI_INT,rowners+1,1,MPI_INT,comm);CHKERRQ(ierr); 11448965ea79SLois Curfman McInnes rowners[0] = 0; 11458965ea79SLois Curfman McInnes for ( i=2; i<=size; i++ ) { 11468965ea79SLois Curfman McInnes rowners[i] += rowners[i-1]; 11478965ea79SLois Curfman McInnes } 11488965ea79SLois Curfman McInnes rstart = rowners[rank]; 11498965ea79SLois Curfman McInnes rend = rowners[rank+1]; 11508965ea79SLois Curfman McInnes 11518965ea79SLois Curfman McInnes /* distribute row lengths to all processors */ 11520452661fSBarry Smith ourlens = (int*) PetscMalloc( 2*(rend-rstart)*sizeof(int) ); CHKPTRQ(ourlens); 11538965ea79SLois Curfman McInnes offlens = ourlens + (rend-rstart); 11548965ea79SLois Curfman McInnes if (!rank) { 11550452661fSBarry Smith rowlengths = (int*) PetscMalloc( M*sizeof(int) ); CHKPTRQ(rowlengths); 11560752156aSBarry Smith ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT); CHKERRQ(ierr); 11570452661fSBarry Smith sndcounts = (int*) PetscMalloc( size*sizeof(int) ); CHKPTRQ(sndcounts); 11588965ea79SLois Curfman McInnes for ( i=0; i<size; i++ ) sndcounts[i] = rowners[i+1] - rowners[i]; 1159ca161407SBarry Smith ierr = MPI_Scatterv(rowlengths,sndcounts,rowners,MPI_INT,ourlens,rend-rstart,MPI_INT,0,comm);CHKERRQ(ierr); 11600452661fSBarry Smith PetscFree(sndcounts); 1161ca161407SBarry Smith } else { 1162ca161407SBarry Smith ierr = MPI_Scatterv(0,0,0,MPI_INT,ourlens,rend-rstart,MPI_INT, 0,comm);CHKERRQ(ierr); 11638965ea79SLois Curfman McInnes } 11648965ea79SLois Curfman McInnes 11658965ea79SLois Curfman McInnes if (!rank) { 11668965ea79SLois Curfman McInnes /* calculate the number of nonzeros on each processor */ 11670452661fSBarry Smith procsnz = (int*) PetscMalloc( size*sizeof(int) ); CHKPTRQ(procsnz); 1168cddf8d76SBarry Smith PetscMemzero(procsnz,size*sizeof(int)); 11698965ea79SLois Curfman McInnes for ( i=0; i<size; i++ ) { 11708965ea79SLois Curfman McInnes for ( j=rowners[i]; j< rowners[i+1]; j++ ) { 11718965ea79SLois Curfman McInnes procsnz[i] += rowlengths[j]; 11728965ea79SLois Curfman McInnes } 11738965ea79SLois Curfman McInnes } 11740452661fSBarry Smith PetscFree(rowlengths); 11758965ea79SLois Curfman McInnes 11768965ea79SLois Curfman McInnes /* determine max buffer needed and allocate it */ 11778965ea79SLois Curfman McInnes maxnz = 0; 11788965ea79SLois Curfman McInnes for ( i=0; i<size; i++ ) { 11790452661fSBarry Smith maxnz = PetscMax(maxnz,procsnz[i]); 11808965ea79SLois Curfman McInnes } 11810452661fSBarry Smith cols = (int *) PetscMalloc( maxnz*sizeof(int) ); CHKPTRQ(cols); 11828965ea79SLois Curfman McInnes 11838965ea79SLois Curfman McInnes /* read in my part of the matrix column indices */ 11848965ea79SLois Curfman McInnes nz = procsnz[0]; 11850452661fSBarry Smith mycols = (int *) PetscMalloc( nz*sizeof(int) ); CHKPTRQ(mycols); 11860752156aSBarry Smith ierr = PetscBinaryRead(fd,mycols,nz,PETSC_INT); CHKERRQ(ierr); 11878965ea79SLois Curfman McInnes 11888965ea79SLois Curfman McInnes /* read in every one elses and ship off */ 11898965ea79SLois Curfman McInnes for ( i=1; i<size; i++ ) { 11908965ea79SLois Curfman McInnes nz = procsnz[i]; 11910752156aSBarry Smith ierr = PetscBinaryRead(fd,cols,nz,PETSC_INT); CHKERRQ(ierr); 1192ca161407SBarry Smith ierr = MPI_Send(cols,nz,MPI_INT,i,tag,comm);CHKERRQ(ierr); 11938965ea79SLois Curfman McInnes } 11940452661fSBarry Smith PetscFree(cols); 11953a40ed3dSBarry Smith } else { 11968965ea79SLois Curfman McInnes /* determine buffer space needed for message */ 11978965ea79SLois Curfman McInnes nz = 0; 11988965ea79SLois Curfman McInnes for ( i=0; i<m; i++ ) { 11998965ea79SLois Curfman McInnes nz += ourlens[i]; 12008965ea79SLois Curfman McInnes } 12010452661fSBarry Smith mycols = (int*) PetscMalloc( nz*sizeof(int) ); CHKPTRQ(mycols); 12028965ea79SLois Curfman McInnes 12038965ea79SLois Curfman McInnes /* receive message of column indices*/ 1204ca161407SBarry Smith ierr = MPI_Recv(mycols,nz,MPI_INT,0,tag,comm,&status);CHKERRQ(ierr); 1205ca161407SBarry Smith ierr = MPI_Get_count(&status,MPI_INT,&maxnz);CHKERRQ(ierr); 1206a8c6a408SBarry Smith if (maxnz != nz) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,0,"something is wrong with file"); 12078965ea79SLois Curfman McInnes } 12088965ea79SLois Curfman McInnes 12098965ea79SLois Curfman McInnes /* loop over local rows, determining number of off diagonal entries */ 1210cddf8d76SBarry Smith PetscMemzero(offlens,m*sizeof(int)); 12118965ea79SLois Curfman McInnes jj = 0; 12128965ea79SLois Curfman McInnes for ( i=0; i<m; i++ ) { 12138965ea79SLois Curfman McInnes for ( j=0; j<ourlens[i]; j++ ) { 12148965ea79SLois Curfman McInnes if (mycols[jj] < rstart || mycols[jj] >= rend) offlens[i]++; 12158965ea79SLois Curfman McInnes jj++; 12168965ea79SLois Curfman McInnes } 12178965ea79SLois Curfman McInnes } 12188965ea79SLois Curfman McInnes 12198965ea79SLois Curfman McInnes /* create our matrix */ 12208965ea79SLois Curfman McInnes for ( i=0; i<m; i++ ) { 12218965ea79SLois Curfman McInnes ourlens[i] -= offlens[i]; 12228965ea79SLois Curfman McInnes } 1223b4fd4287SBarry Smith ierr = MatCreateMPIDense(comm,m,PETSC_DECIDE,M,N,PETSC_NULL,newmat);CHKERRQ(ierr); 12248965ea79SLois Curfman McInnes A = *newmat; 12258965ea79SLois Curfman McInnes for ( i=0; i<m; i++ ) { 12268965ea79SLois Curfman McInnes ourlens[i] += offlens[i]; 12278965ea79SLois Curfman McInnes } 12288965ea79SLois Curfman McInnes 12298965ea79SLois Curfman McInnes if (!rank) { 12300452661fSBarry Smith vals = (Scalar *) PetscMalloc( maxnz*sizeof(Scalar) ); CHKPTRQ(vals); 12318965ea79SLois Curfman McInnes 12328965ea79SLois Curfman McInnes /* read in my part of the matrix numerical values */ 12338965ea79SLois Curfman McInnes nz = procsnz[0]; 12340752156aSBarry Smith ierr = PetscBinaryRead(fd,vals,nz,PETSC_SCALAR); CHKERRQ(ierr); 12358965ea79SLois Curfman McInnes 12368965ea79SLois Curfman McInnes /* insert into matrix */ 12378965ea79SLois Curfman McInnes jj = rstart; 12388965ea79SLois Curfman McInnes smycols = mycols; 12398965ea79SLois Curfman McInnes svals = vals; 12408965ea79SLois Curfman McInnes for ( i=0; i<m; i++ ) { 12418965ea79SLois Curfman McInnes ierr = MatSetValues(A,1,&jj,ourlens[i],smycols,svals,INSERT_VALUES);CHKERRQ(ierr); 12428965ea79SLois Curfman McInnes smycols += ourlens[i]; 12438965ea79SLois Curfman McInnes svals += ourlens[i]; 12448965ea79SLois Curfman McInnes jj++; 12458965ea79SLois Curfman McInnes } 12468965ea79SLois Curfman McInnes 12478965ea79SLois Curfman McInnes /* read in other processors and ship out */ 12488965ea79SLois Curfman McInnes for ( i=1; i<size; i++ ) { 12498965ea79SLois Curfman McInnes nz = procsnz[i]; 12500752156aSBarry Smith ierr = PetscBinaryRead(fd,vals,nz,PETSC_SCALAR); CHKERRQ(ierr); 1251ca161407SBarry Smith ierr = MPI_Send(vals,nz,MPIU_SCALAR,i,A->tag,comm);CHKERRQ(ierr); 12528965ea79SLois Curfman McInnes } 12530452661fSBarry Smith PetscFree(procsnz); 12543a40ed3dSBarry Smith } else { 12558965ea79SLois Curfman McInnes /* receive numeric values */ 12560452661fSBarry Smith vals = (Scalar*) PetscMalloc( nz*sizeof(Scalar) ); CHKPTRQ(vals); 12578965ea79SLois Curfman McInnes 12588965ea79SLois Curfman McInnes /* receive message of values*/ 1259ca161407SBarry Smith ierr = MPI_Recv(vals,nz,MPIU_SCALAR,0,A->tag,comm,&status);CHKERRQ(ierr); 1260ca161407SBarry Smith ierr = MPI_Get_count(&status,MPIU_SCALAR,&maxnz);CHKERRQ(ierr); 1261a8c6a408SBarry Smith if (maxnz != nz) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,0,"something is wrong with file"); 12628965ea79SLois Curfman McInnes 12638965ea79SLois Curfman McInnes /* insert into matrix */ 12648965ea79SLois Curfman McInnes jj = rstart; 12658965ea79SLois Curfman McInnes smycols = mycols; 12668965ea79SLois Curfman McInnes svals = vals; 12678965ea79SLois Curfman McInnes for ( i=0; i<m; i++ ) { 12688965ea79SLois Curfman McInnes ierr = MatSetValues(A,1,&jj,ourlens[i],smycols,svals,INSERT_VALUES);CHKERRQ(ierr); 12698965ea79SLois Curfman McInnes smycols += ourlens[i]; 12708965ea79SLois Curfman McInnes svals += ourlens[i]; 12718965ea79SLois Curfman McInnes jj++; 12728965ea79SLois Curfman McInnes } 12738965ea79SLois Curfman McInnes } 12740452661fSBarry Smith PetscFree(ourlens); PetscFree(vals); PetscFree(mycols); PetscFree(rowners); 12758965ea79SLois Curfman McInnes 12766d4a8577SBarry Smith ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 12776d4a8577SBarry Smith ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 12783a40ed3dSBarry Smith PetscFunctionReturn(0); 12798965ea79SLois Curfman McInnes } 128090ace30eSBarry Smith 128190ace30eSBarry Smith 128290ace30eSBarry Smith 128390ace30eSBarry Smith 128490ace30eSBarry Smith 1285