/* set rsh of hc, fire, and collect lhs responses */ (id<mask) ? PCTFS_rvec_zero(lhs,m) : PCTFS_rvec_set(lhs,1.0,m); PCTFS_gs_gop_hc(PCTFS_gs_handle,lhs,"+\0",edge); /* set lsh of hc, fire, and collect rhs responses */ (id<mask) ? PCTFS_rvec_set(rhs,1.0,m) : PCTFS_rvec_zero(rhs,m); PCTFS_gs_gop_hc(PCTFS_gs_handle,rhs,"+\0",edge); /* count number of dofs I own that have signal and not in sep set */ for (PCTFS_ivec_zero(sum,4),ct=i=0;i<n;i++) { if (!used[i]) { /* number of unmarked dofs on node */ ct++; /* number of dofs to be marked on lhs hc */ if ((id< mask)&&(lhs[i]!=0.0)) sum[0]++; /* number of dofs to be marked on rhs hc */ if ((id>=mask)&&(rhs[i]!=0.0)) sum[1]++; } } /* for the non-symmetric case we need separators of width 2 */ /* so take both sides */ (id<mask) ? (sum[2]=ct) : (sum[3]=ct); PCTFS_giop_hc(sum,w,4,op,edge); ct=0; if (id<mask) { /* mark dofs I own that have signal and not in sep set */ for (i=0;i<n;i++) { if ((!used[i])&&(lhs[i]!=0.0)) { ct++; nfo++; *--iptr = local2global[i]; used[i] =edge; } } /* LSH hc summation of ct should be sum[0] */ } else { /* mark dofs I own that have signal and not in sep set */ for (i=0; i<n; i++) { if ((!used[i])&&(rhs[i]!=0.0)) { ct++; nfo++; *--iptr = local2global[i]; used[i] = edge; } } /* RSH hc summation of ct should be sum[1] */ } if (ct>1) PCTFS_ivec_sort(iptr,ct); lnsep[edge]=ct; nsep[edge] =sum[0]+sum[1]; dir [edge] =BOTH; /* LATER or we can recur on these to order seps at this level */ /* do we need full set of separators for this? */ /* fold rhs hc into lower */ if (id>=mask) id-=mask; }
/**************************************xyt.c***********************************/ static PetscErrorCode det_separators(xyt_ADT xyt_handle) { PetscInt i, ct, id; PetscInt mask, edge, *iptr; PetscInt *dir, *used; PetscInt sum[4], w[4]; PetscScalar rsum[4], rw[4]; PetscInt op[] = {GL_ADD,0}; PetscScalar *lhs, *rhs; PetscInt *nsep, *lnsep, *fo, nfo=0; PCTFS_gs_ADT PCTFS_gs_handle=xyt_handle->mvi->PCTFS_gs_handle; PetscInt *local2global =xyt_handle->mvi->local2global; PetscInt n =xyt_handle->mvi->n; PetscInt m =xyt_handle->mvi->m; PetscInt level =xyt_handle->level; PetscInt shared =0; PetscErrorCode ierr; PetscFunctionBegin; dir = (PetscInt*)malloc(sizeof(PetscInt)*(level+1)); nsep = (PetscInt*)malloc(sizeof(PetscInt)*(level+1)); lnsep= (PetscInt*)malloc(sizeof(PetscInt)*(level+1)); fo = (PetscInt*)malloc(sizeof(PetscInt)*(n+1)); used = (PetscInt*)malloc(sizeof(PetscInt)*n); PCTFS_ivec_zero(dir,level+1); PCTFS_ivec_zero(nsep,level+1); PCTFS_ivec_zero(lnsep,level+1); PCTFS_ivec_set (fo,-1,n+1); PCTFS_ivec_zero(used,n); lhs = (PetscScalar*)malloc(sizeof(PetscScalar)*m); rhs = (PetscScalar*)malloc(sizeof(PetscScalar)*m); /* determine the # of unique dof */ PCTFS_rvec_zero(lhs,m); PCTFS_rvec_set(lhs,1.0,n); PCTFS_gs_gop_hc(PCTFS_gs_handle,lhs,"+\0",level); ierr = PetscInfo(0,"done first PCTFS_gs_gop_hc\n");CHKERRQ(ierr); PCTFS_rvec_zero(rsum,2); for (ct=i=0; i<n; i++) { if (lhs[i]!=0.0) { rsum[0]+=1.0/lhs[i]; rsum[1]+=lhs[i]; } if (lhs[i]!=1.0) shared=1; } PCTFS_grop_hc(rsum,rw,2,op,level); rsum[0]+=0.1; rsum[1]+=0.1; xyt_handle->info->n_global=xyt_handle->info->m_global=(PetscInt) rsum[0]; xyt_handle->mvi->n_global =xyt_handle->mvi->m_global =(PetscInt) rsum[0]; /* determine separator sets top down */ if (shared) { /* solution is to do as in the symmetric shared case but then */ /* pick the sub-hc with the most free dofs and do a mat-vec */ /* and pick up the responses on the other sub-hc from the */ /* initial separator set obtained from the symm. shared case */ SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"shared dof separator determination not ready ... see hmt!!!\n"); for (iptr=fo+n,id=PCTFS_my_id,mask=PCTFS_num_nodes>>1,edge=level; edge>0; edge--,mask>>=1) { /* set rsh of hc, fire, and collect lhs responses */ (id<mask) ? PCTFS_rvec_zero(lhs,m) : PCTFS_rvec_set(lhs,1.0,m); PCTFS_gs_gop_hc(PCTFS_gs_handle,lhs,"+\0",edge); /* set lsh of hc, fire, and collect rhs responses */ (id<mask) ? PCTFS_rvec_set(rhs,1.0,m) : PCTFS_rvec_zero(rhs,m); PCTFS_gs_gop_hc(PCTFS_gs_handle,rhs,"+\0",edge); for (i=0; i<n; i++) { if (id< mask) { if (lhs[i]!=0.0) lhs[i]=1.0; } if (id>=mask) { if (rhs[i]!=0.0) rhs[i]=1.0; } } if (id< mask) PCTFS_gs_gop_hc(PCTFS_gs_handle,lhs,"+\0",edge-1); else PCTFS_gs_gop_hc(PCTFS_gs_handle,rhs,"+\0",edge-1); /* count number of dofs I own that have signal and not in sep set */ PCTFS_rvec_zero(rsum,4); for (PCTFS_ivec_zero(sum,4),ct=i=0;i<n;i++) { if (!used[i]) { /* number of unmarked dofs on node */ ct++; /* number of dofs to be marked on lhs hc */ if (id< mask) { if (lhs[i]!=0.0) { sum[0]++; rsum[0]+=1.0/lhs[i]; } } /* number of dofs to be marked on rhs hc */ if (id>=mask) { if (rhs[i]!=0.0) { sum[1]++; rsum[1]+=1.0/rhs[i]; } } } } /* go for load balance - choose half with most unmarked dofs, bias LHS */ (id<mask) ? (sum[2]=ct) : (sum[3]=ct); (id<mask) ? (rsum[2]=ct) : (rsum[3]=ct); PCTFS_giop_hc(sum,w,4,op,edge); PCTFS_grop_hc(rsum,rw,4,op,edge); rsum[0]+=0.1; rsum[1]+=0.1; rsum[2]+=0.1; rsum[3]+=0.1; if (id<mask) { /* mark dofs I own that have signal and not in sep set */ for (ct=i=0;i<n;i++) { if ((!used[i])&&(lhs[i]!=0.0)) { ct++; nfo++; if (nfo>n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"nfo about to exceed n\n"); *--iptr = local2global[i]; used[i]=edge; } } if (ct>1) PCTFS_ivec_sort(iptr,ct); lnsep[edge]=ct; nsep[edge] =(PetscInt) rsum[0]; dir [edge] =LEFT; } if (id>=mask) { /* mark dofs I own that have signal and not in sep set */ for (ct=i=0;i<n;i++) { if ((!used[i])&&(rhs[i]!=0.0)) { ct++; nfo++; if (nfo>n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"nfo about to exceed n\n"); *--iptr = local2global[i]; used[i] =edge; } } if (ct>1) PCTFS_ivec_sort(iptr,ct); lnsep[edge] = ct; nsep[edge] = (PetscInt) rsum[1]; dir [edge] = RIGHT; } /* LATER or we can recur on these to order seps at this level */ /* do we need full set of separators for this? */ /* fold rhs hc into lower */ if (id>=mask) id-=mask; } } else { for (iptr=fo+n,id=PCTFS_my_id,mask=PCTFS_num_nodes>>1,edge=level;edge>0;edge--,mask>>=1) {
/* set rsh of hc, fire, and collect lhs responses */ (id<mask) ? PCTFS_rvec_zero(lhs,m) : PCTFS_rvec_set(lhs,1.0,m); PCTFS_gs_gop_hc(PCTFS_gs_handle,lhs,"+\0",edge); /* set lsh of hc, fire, and collect rhs responses */ (id<mask) ? PCTFS_rvec_set(rhs,1.0,m) : PCTFS_rvec_zero(rhs,m); PCTFS_gs_gop_hc(PCTFS_gs_handle,rhs,"+\0",edge); /* count number of dofs I own that have signal and not in sep set */ for (PCTFS_ivec_zero(sum,4),ct=i=0;i<n;i++) { if (!used[i]) { /* number of unmarked dofs on node */ ct++; /* number of dofs to be marked on lhs hc */ if ((id< mask)&&(lhs[i]!=0.0)) sum[0]++; /* number of dofs to be marked on rhs hc */ if ((id>=mask)&&(rhs[i]!=0.0)) sum[1]++; } } /* go for load balance - choose half with most unmarked dofs, bias LHS */ (id<mask) ? (sum[2]=ct) : (sum[3]=ct); PCTFS_giop_hc(sum,w,4,op,edge); /* lhs hc wins */ if (sum[2]>=sum[3]) { if (id<mask) { /* mark dofs I own that have signal and not in sep set */ for (ct=i=0;i<n;i++) { if ((!used[i])&&(lhs[i]!=0.0)) { ct++; nfo++; *--iptr = local2global[i]; used[i]=edge; } } if (ct>1) PCTFS_ivec_sort(iptr,ct); lnsep[edge]=ct; } nsep[edge]=sum[0]; dir [edge]=LEFT; } else { /* rhs hc wins */ if (id>=mask) { /* mark dofs I own that have signal and not in sep set */ for (ct=i=0;i<n;i++) { if ((!used[i])&&(rhs[i]!=0.0)) { ct++; nfo++; *--iptr = local2global[i]; used[i]=edge; } } if (ct>1) PCTFS_ivec_sort(iptr,ct); lnsep[edge]=ct; } nsep[edge]=sum[1]; dir [edge]=RIGHT; } /* LATER or we can recur on these to order seps at this level */ /* do we need full set of separators for this? */ /* fold rhs hc into lower */ if (id>=mask) id-=mask; }