diff -r 6eca3ecc3deb src/sys/threadcomm/interface/dlregisthreadcomm.c --- a/src/sys/threadcomm/interface/dlregisthreadcomm.c Mon Jul 16 18:15:42 2012 -0500 +++ b/src/sys/threadcomm/interface/dlregisthreadcomm.c Tue Jul 17 03:07:30 2012 -0500 @@ -2,6 +2,7 @@ static PetscBool PetscThreadCommPackageInitialized = PETSC_FALSE; +PETSC_EXTERN PetscErrorCode PetscThreadCommDetach(MPI_Comm); #undef __FUNCT__ #define __FUNCT__ "PetscThreadCommFinalizePackage" /*@C @@ -16,18 +17,12 @@ PetscErrorCode PetscThreadCommFinalizePackage(void) { PetscErrorCode ierr; - MPI_Comm comm; PetscFunctionBegin; ierr = PetscThreadCommRegisterDestroy();CHKERRQ(ierr); -#if !defined(PETSC_HAVE_MPIUNI) - comm = PETSC_COMM_WORLD; /* Release reference from PetscThreadCommInitialize */ - ierr = PetscCommDestroy(&comm);CHKERRQ(ierr); -#endif - - comm = PETSC_COMM_SELF; /* Release reference from PetscThreadCommInitialize */ - ierr = PetscCommDestroy(&comm);CHKERRQ(ierr); + ierr = PetscThreadCommDetach(PETSC_COMM_WORLD);CHKERRQ(ierr); + ierr = PetscThreadCommDetach(PETSC_COMM_SELF);CHKERRQ(ierr); ierr = MPI_Keyval_free(&Petsc_ThreadComm_keyval);CHKERRQ(ierr); PetscThreadCommPackageInitialized = PETSC_FALSE; diff -r 6eca3ecc3deb src/sys/threadcomm/interface/threadcomm.c --- a/src/sys/threadcomm/interface/threadcomm.c Mon Jul 16 18:15:42 2012 -0500 +++ b/src/sys/threadcomm/interface/threadcomm.c Tue Jul 17 03:07:30 2012 -0500 @@ -116,7 +116,7 @@ *tcomm = PETSC_NULL; ierr = PetscNew(struct _p_PetscThreadComm,&tcommout);CHKERRQ(ierr); - tcommout->refct = 1; + tcommout->refct = 0; tcommout->nworkThreads = -1; tcommout->affinities = PETSC_NULL; ierr = PetscNew(struct _PetscThreadCommOps,&tcommout->ops);CHKERRQ(ierr); @@ -139,33 +139,34 @@ .seealso: PetscThreadCommCreate() */ -PetscErrorCode PetscThreadCommDestroy(PetscThreadComm tcomm) +PetscErrorCode PetscThreadCommDestroy(PetscThreadComm *tcomm) { PetscErrorCode ierr; PetscInt i; PetscFunctionBegin; - if (!tcomm || --tcomm->refct > 0) PetscFunctionReturn(0); - - /* Destroy the implementation specific data struct */ - if(tcomm->ops->destroy) { - (*tcomm->ops->destroy)(tcomm); - } - - ierr = PetscFree(tcomm->affinities);CHKERRQ(ierr); - ierr = PetscFree(tcomm->ops);CHKERRQ(ierr); - for(i=0;irefct) { + /* Destroy the implementation specific data struct */ + if((*tcomm)->ops->destroy) { + (*(*tcomm)->ops->destroy)(*tcomm); + } + ierr = PetscFree((*tcomm)->affinities);CHKERRQ(ierr); + ierr = PetscFree((*tcomm)->ops);CHKERRQ(ierr); + for(i=0;ijobs[i]->job_status); + free(PetscJobQueue->jobs[i]->job_status); #else - ierr = PetscFree(PetscJobQueue->jobs[i]->job_status);CHKERRQ(ierr); + ierr = PetscFree(PetscJobQueue->jobs[i]->job_status);CHKERRQ(ierr); #endif - ierr = PetscFree(PetscJobQueue->jobs[i]);CHKERRQ(ierr); + ierr = PetscFree(PetscJobQueue->jobs[i]);CHKERRQ(ierr); + } + ierr = PetscFree(PetscJobQueue);CHKERRQ(ierr); + ierr = PetscThreadCommReductionDestroy((*tcomm)->red);CHKERRQ(ierr); + ierr = PetscFree((*tcomm));CHKERRQ(ierr); } - ierr = PetscFree(PetscJobQueue);CHKERRQ(ierr); - ierr = PetscThreadCommReductionDestroy(tcomm->red);CHKERRQ(ierr); - ierr = PetscFree(tcomm);CHKERRQ(ierr); + *tcomm = PETSC_NULL; PetscFunctionReturn(0); } @@ -646,6 +647,7 @@ PetscFunctionReturn(0); } + EXTERN_C_BEGIN #undef __FUNCT__ #define __FUNCT__ "Petsc_DelThreadComm" @@ -665,7 +667,7 @@ PetscFunctionBegin; ierr = MPI_Attr_get(comm,keyval,(PetscThreadComm*)&tcomm,&flg);CHKERRQ(ierr); if(flg) { - ierr = PetscThreadCommDestroy((PetscThreadComm)tcomm);CHKERRQ(ierr); + ierr = PetscThreadCommDestroy((PetscThreadComm*)&tcomm);CHKERRQ(ierr); ierr = PetscInfo1(0,"Deleting thread communicator data in an MPI_Comm %ld\n",(long)comm);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr); } PetscFunctionReturn(0); @@ -673,6 +675,60 @@ EXTERN_C_END #undef __FUNCT__ +#define __FUNCT__ "PetscThreadCommDetach" +PetscErrorCode PetscThreadCommDetach(MPI_Comm comm) +{ + PetscErrorCode ierr; + MPI_Comm icomm=comm; + PetscMPIInt flg; + void *ptr; + + PetscFunctionBegin; + ierr = MPI_Attr_get(comm,Petsc_InnerComm_keyval,&ptr,&flg);CHKERRQ(ierr); + if(flg) { + ierr = PetscMemcpy(&icomm,&ptr,sizeof(MPI_Comm));CHKERRQ(ierr); + ierr = MPI_Attr_get(icomm,Petsc_ThreadComm_keyval,&ptr,&flg);CHKERRQ(ierr); + if(flg) { + ierr = PetscThreadCommDestroy((PetscThreadComm*)&ptr);CHKERRQ(ierr); + ierr = MPI_Attr_delete(icomm,Petsc_ThreadComm_keyval);CHKERRQ(ierr); + /* Release reference from PetscThreadCommInitialize */ + ierr = PetscCommDestroy(&comm);CHKERRQ(ierr); + } + } + PetscFunctionReturn(0); +} + +#undef __FUNCT__ +#define __FUNCT__ "PetscThreadCommAttach" +PetscErrorCode PetscThreadCommAttach(MPI_Comm comm,PetscThreadComm tcomm) +{ + PetscErrorCode ierr; + MPI_Comm icomm; + PetscMPIInt flg,flg1,flg2; + void *ptr; + PetscCommCounter *counter; + + PetscFunctionBegin; + ierr = MPI_Attr_get(comm,Petsc_Counter_keyval,&counter,&flg);CHKERRQ(ierr); + if(!flg) { /* Communicator not initialized yet */ + ierr = PetscCommDuplicate(comm,&icomm,PETSC_NULL);CHKERRQ(ierr); + tcomm->refct++; + ierr = MPI_Attr_put(icomm,Petsc_ThreadComm_keyval,tcomm);CHKERRQ(ierr); + } else { + ierr = MPI_Attr_get(comm,Petsc_InnerComm_keyval,&ptr,&flg1);CHKERRQ(ierr); + if(flg1) { + ierr = PetscMemcpy(&ptr,&icomm,sizeof(MPI_Comm));CHKERRQ(ierr); + ierr = MPI_Attr_get(icomm,Petsc_ThreadComm_keyval,&ptr,&flg2);CHKERRQ(ierr); + if(!flg2) { + tcomm->refct++; + ierr = MPI_Attr_put(icomm,Petsc_ThreadComm_keyval,tcomm);CHKERRQ(ierr); + } + } + } + PetscFunctionReturn(0); +} + +#undef __FUNCT__ #define __FUNCT__ "PetscThreadCommInitialize" /* PetscThreadCommInitialize - Initializes the thread communicator object @@ -684,7 +740,6 @@ { PetscErrorCode ierr; PetscThreadComm tcomm; - MPI_Comm icomm; PetscInt i,j; PetscFunctionBegin; @@ -708,17 +763,9 @@ PetscJobQueue->kernel_ctr = 0; tcomm->job_ctr = 0; - /* PETSC_COMM_SELF = PETSC_COMM_WORLD for MPIUNI */ -#if !defined(PETSC_HAVE_MPIUNI) - ierr = PetscCommDuplicate(PETSC_COMM_WORLD,&icomm,PETSC_NULL);CHKERRQ(ierr); - ierr = MPI_Attr_put(icomm,Petsc_ThreadComm_keyval,(void*)tcomm);CHKERRQ(ierr); - tcomm->refct++; /* Share the threadcomm with PETSC_COMM_SELF */ -#endif - - ierr = PetscCommDuplicate(PETSC_COMM_SELF,&icomm,PETSC_NULL);CHKERRQ(ierr); - ierr = MPI_Attr_put(icomm,Petsc_ThreadComm_keyval,(void*)tcomm);CHKERRQ(ierr); - /* This routine leaves extra references to the inner comms. They are released in PetscThreadCommFinalizePackage(). */ + ierr = PetscThreadCommAttach(PETSC_COMM_WORLD,tcomm);CHKERRQ(ierr); + ierr = PetscThreadCommAttach(PETSC_COMM_SELF,tcomm);CHKERRQ(ierr); ierr = PetscThreadCommSetType(tcomm,NOTHREAD);CHKERRQ(ierr); ierr = PetscThreadCommReductionCreate(tcomm,&tcomm->red);CHKERRQ(ierr);