EXTERN_C_BEGIN void PETSC_STDCALL matpartitioningsetvertexweights_(MatPartitioning *part,const PetscInt weights[],PetscErrorCode *ierr) { PetscInt len; PetscInt *array; *ierr = MatGetLocalSize((*part)->adj,&len,0); if (*ierr) return; *ierr = PetscMalloc(len*sizeof(PetscInt),&array); if (*ierr) return; *ierr = PetscMemcpy(array,weights,len*sizeof(PetscInt));if (*ierr) return; *ierr = MatPartitioningSetVertexWeights(*part,array); }
static PetscErrorCode MatPartitioningApply_Hierarchical(MatPartitioning part,IS *partitioning) { MatPartitioning_Hierarchical *hpart = (MatPartitioning_Hierarchical*)part->data; const PetscInt *fineparts_indices, *coarseparts_indices; PetscInt *parts_indices,i,j,mat_localsize; Mat mat = part->adj,adj,sadj; PetscBool flg; PetscInt bs = 1; MatPartitioning finePart, coarsePart; PetscInt *coarse_vertex_weights = 0; PetscMPIInt size,rank; MPI_Comm comm,scomm; IS destination,fineparts_temp; ISLocalToGlobalMapping mapping; PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscObjectGetComm((PetscObject)part,&comm);CHKERRQ(ierr); ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); ierr = PetscObjectTypeCompare((PetscObject)mat,MATMPIADJ,&flg);CHKERRQ(ierr); if (flg) { adj = mat; ierr = PetscObjectReference((PetscObject)adj);CHKERRQ(ierr); }else { /* bs indicates if the converted matrix is "reduced" from the original and hence the resulting partition results need to be stretched to match the original matrix */ ierr = MatConvert(mat,MATMPIADJ,MAT_INITIAL_MATRIX,&adj);CHKERRQ(ierr); if (adj->rmap->n > 0) bs = mat->rmap->n/adj->rmap->n; } /*local size of mat*/ mat_localsize = adj->rmap->n; /* check parameters */ /* how many small subdomains we want from a given 'big' suddomain */ if(!hpart->Nfineparts) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG," must set number of small subdomains for each big subdomain \n"); if(!hpart->Ncoarseparts && !part->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE," did not either set number of coarse parts or total number of parts \n"); if(part->n && part->n%hpart->Nfineparts!=0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP, " total number of parts %D can not be divided by number of fine parts %D\n",part->n,hpart->Nfineparts); if(part->n){ hpart->Ncoarseparts = part->n/hpart->Nfineparts; }else{ part->n = hpart->Ncoarseparts*hpart->Nfineparts; } /* we do not support this case currently, but this restriction should be * removed in the further * */ if(hpart->Ncoarseparts>size) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP," we do not support number of coarse parts %D > size %D \n",hpart->Ncoarseparts,size); /*create a coarse partitioner */ ierr = MatPartitioningCreate(comm,&coarsePart);CHKERRQ(ierr); /*if did not set partitioning type yet, use parmetis by default */ if(!hpart->coarseparttype){ ierr = MatPartitioningSetType(coarsePart,MATPARTITIONINGPARMETIS);CHKERRQ(ierr); }else{ ierr = MatPartitioningSetType(coarsePart,hpart->coarseparttype);CHKERRQ(ierr); } ierr = MatPartitioningSetAdjacency(coarsePart,adj);CHKERRQ(ierr); ierr = MatPartitioningSetNParts(coarsePart, hpart->Ncoarseparts);CHKERRQ(ierr); /*copy over vertex weights */ if(part->vertex_weights){ ierr = PetscMalloc(sizeof(PetscInt)*mat_localsize,&coarse_vertex_weights);CHKERRQ(ierr); ierr = PetscMemcpy(coarse_vertex_weights,part->vertex_weights,sizeof(PetscInt)*mat_localsize);CHKERRQ(ierr); ierr = MatPartitioningSetVertexWeights(coarsePart,coarse_vertex_weights);CHKERRQ(ierr); } /*It looks nontrivial to support part weights */ /*if(part->part_weights){ ierr = PetscMalloc(sizeof(part->part_weights)*1,&coarse_partition_weights);CHKERRQ(ierr); ierr = PetscMemcpy(coarse_partition_weights,part->part_weights,sizeof(part->part_weights)*1);CHKERRQ(ierr); ierr = MatPartitioningSetPartitionWeights(coarsePart,coarse_partition_weights);CHKERRQ(ierr); }*/ ierr = MatPartitioningApply(coarsePart,&hpart->coarseparts);CHKERRQ(ierr); ierr = MatPartitioningDestroy(&coarsePart);CHKERRQ(ierr); /* In the current implementation, destination should be the same as hpart->coarseparts, * and this interface is preserved to deal with the case hpart->coarseparts>size in the * future. * */ ierr = MatPartitioningHierarchical_DetermineDestination(part,hpart->coarseparts,0,hpart->Ncoarseparts,&destination);CHKERRQ(ierr); /* create a sub-matrix*/ ierr = MatPartitioningHierarchical_AssembleSubdomain(adj,destination,&sadj,&mapping);CHKERRQ(ierr); ierr = ISDestroy(&destination);CHKERRQ(ierr); ierr = PetscObjectGetComm((PetscObject)sadj,&scomm);CHKERRQ(ierr); /*create a fine partitioner */ ierr = MatPartitioningCreate(scomm,&finePart);CHKERRQ(ierr); /*if do not set partitioning type, use parmetis by default */ if(!hpart->fineparttype){ ierr = MatPartitioningSetType(finePart,MATPARTITIONINGPARMETIS);CHKERRQ(ierr); }else{ ierr = MatPartitioningSetType(finePart,hpart->fineparttype);CHKERRQ(ierr); } ierr = MatPartitioningSetAdjacency(finePart,sadj);CHKERRQ(ierr); ierr = MatPartitioningSetNParts(finePart, hpart->Nfineparts);CHKERRQ(ierr); ierr = MatPartitioningApply(finePart,&fineparts_temp);CHKERRQ(ierr); ierr = MatDestroy(&sadj);CHKERRQ(ierr); ierr = MatPartitioningDestroy(&finePart);CHKERRQ(ierr); ierr = MatPartitioningHierarchical_ReassembleFineparts(adj,fineparts_temp,mapping,&hpart->fineparts);CHKERRQ(ierr); ierr = ISDestroy(&fineparts_temp);CHKERRQ(ierr); ierr = ISLocalToGlobalMappingDestroy(&mapping);CHKERRQ(ierr); ierr = ISGetIndices(hpart->fineparts,&fineparts_indices);CHKERRQ(ierr); ierr = ISGetIndices(hpart->coarseparts,&coarseparts_indices);CHKERRQ(ierr); ierr = PetscMalloc1(bs*adj->rmap->n,&parts_indices);CHKERRQ(ierr); for(i=0; i<adj->rmap->n; i++){ for(j=0; j<bs; j++){ parts_indices[bs*i+j] = fineparts_indices[i]+coarseparts_indices[i]*hpart->Nfineparts; } } ierr = ISCreateGeneral(comm,bs*adj->rmap->n,parts_indices,PETSC_OWN_POINTER,partitioning);CHKERRQ(ierr); ierr = MatDestroy(&adj);CHKERRQ(ierr); PetscFunctionReturn(0); }