Index: c/mpi.c===================================================================--- c/mpi.c (revision 5469)+++ c/mpi.c (working copy)@@ -729,6 +729,13 @@ #include "scalapack.c" #endif+// See the documentation for corresponding function in debug wrapper+// for the purpose of this function (gpaw/mpi/__init__.py)+static PyObject * get_c_object(MPIObject *self, PyObject *args)+{+ return Py_BuildValue("O", self);+}+ // Forward declaration of MPI_Communicator because it needs MPIType // that needs MPI_getattr that needs MPI_Methods that need // MPI_Communicator that need ...@@ -785,6 +792,7 @@ {"diagonalize", (PyCFunction)diagonalize, METH_VARARGS, 0}, {"inverse_cholesky", (PyCFunction)inverse_cholesky, METH_VARARGS, 0}, #endif+ {"get_c_object", (PyCFunction)get_c_object, METH_VARARGS, 0}, {"new_communicator", (PyCFunction)MPICommunicator, METH_VARARGS, "new_communicator(ranks) creates a new communicator."}, {0, 0, 0, 0}Index: gpaw/mpi/__init__.py===================================================================--- gpaw/mpi/__init__.py (revision 5469)+++ gpaw/mpi/__init__.py (working copy)@@ -64,6 +64,9 @@ raise NotImplementedError('Calls to mpi waitall should not happen in ' 'serial mode')+ def get_c_object(self):+ raise NotImplementedError('Should not get c object for serial comm')+ serial_comm = SerialCommunicator() try:@@ -81,9 +84,6 @@ if dry_run_size > 1: world = DryRunCommunicator(dry_run_size)-size = world.size-rank = world.rank-parallel = (size > 1) if debug: class _Communicator:@@ -100,6 +100,8 @@ # No duplicates: for i in range(len(sranks) - 1): assert sranks[i] != sranks[i + 1]+ assert len(ranks) > 0+ comm = self.comm.new_communicator(ranks) if comm is None: # This cpu is not in the new communicator:@@ -220,9 +222,28 @@ nprow=1, npcol=1, mb=32, root=0): return self.comm.inverse_cholesky(a, nprow, npcol, mb, root)+ def get_c_object(self):+ """Return the C-object wrapped by this debug interface.++ Whenever a communicator object is passed to C code, that object+ must be a proper C-object - *not* e.g. this debug wrapper. For+ this reason. The C-communicator object has a get_c_object()+ implementation which returns itself; thus, always call+ comm.get_c_object() and pass the resulting object to the C code.++ XXX Must make a central check somewhere that the C type is+ correct."""+ return self.comm.get_c_object()+ serial_comm = _Communicator(serial_comm)+ world = _Communicator(world)+size = world.size+rank = world.rank+parallel = (size > 1)++ def distribute_cpus(parsize, parsize_bands, nspins, nibzkpts, comm=world): """Distribute k-points/spins to processors.Index: gpaw/blacs.py===================================================================--- gpaw/blacs.py (revision 5471)+++ gpaw/blacs.py (working copy)@@ -83,7 +84,8 @@ raise ValueError('Impossible: %dx%d Blacs grid with %d CPUs' % (nprow, npcol, comm.size)) # This call may also return INACTIVE- context = _gpaw.new_blacs_context(comm, npcol, nprow, order)+ context = _gpaw.new_blacs_context(comm.get_c_object(),+ npcol, nprow, order) self.context = context self.comm = comm@@ -255,7 +263,8 @@ _gpaw.scalapack_redist(self.srcdescriptor.asarray(), self.dstdescriptor.asarray(), src_mn.T, dst_mn.T,- self.supercomm, subN, subM, isreal)+ self.supercomm.get_c_object(),+ subN, subM, isreal) def redistribute(self, src_mn, dst_mn): subM, subN = self.srcdescriptor.gshapeIndex: gpaw/fd_operators.py===================================================================--- gpaw/fd_operators.py (revision 5469)+++ gpaw/fd_operators.py (working copy)@@ -47,7 +47,7 @@ self.shape = tuple(n_c) if gd.comm.size > 1:- comm = gd.comm+ comm = gd.comm.get_c_object() else: comm = None