[cig-commits] r7215 - cs/pythia/trunk/mpi

leif at geodynamics.org leif at geodynamics.org
Wed Jun 13 13:52:06 PDT 2007


Author: leif
Date: 2007-06-13 13:52:06 -0700 (Wed, 13 Jun 2007)
New Revision: 7215

Modified:
   cs/pythia/trunk/mpi/Communicator.py
   cs/pythia/trunk/mpi/_mpi.c
   cs/pythia/trunk/mpi/_mpi.pxd
   cs/pythia/trunk/mpi/_mpi.pyx
   cs/pythia/trunk/mpi/cmpi.pxd
   cs/pythia/trunk/mpi/pympi.h
Log:
Handle the case where MPI_Comm_create() returns MPI_COMM_NULL exactly
as the original Aivazis code did.


Modified: cs/pythia/trunk/mpi/Communicator.py
===================================================================
--- cs/pythia/trunk/mpi/Communicator.py	2007-06-13 20:26:23 UTC (rev 7214)
+++ cs/pythia/trunk/mpi/Communicator.py	2007-06-13 20:52:06 UTC (rev 7215)
@@ -39,16 +39,20 @@
 
 
     def include(self, included):
-        from mpi import MPI_Comm_create
+        from mpi import MPI_Comm_create, MPI_COMM_NULL
         grp = self.group().include(included)
         handle = MPI_Comm_create(self._handle, grp.handle())
+        if handle is MPI_COMM_NULL:
+            return None
         return Communicator(handle)
 
 
     def exclude(self, excluded):
-        from mpi import MPI_Comm_create
+        from mpi import MPI_Comm_create, MPI_COMM_NULL
         grp = self.group().exclude(excluded)
         handle = MPI_Comm_create(self._handle, grp.handle())
+        if handle is MPI_COMM_NULL:
+            return None
         return Communicator(handle)
 
 

Modified: cs/pythia/trunk/mpi/_mpi.c
===================================================================
--- cs/pythia/trunk/mpi/_mpi.c	2007-06-13 20:26:23 UTC (rev 7214)
+++ cs/pythia/trunk/mpi/_mpi.c	2007-06-13 20:52:06 UTC (rev 7215)
@@ -1,4 +1,4 @@
-/* Generated by Pyrex 0.9.5.1a on Mon Jun 11 16:42:28 2007 */
+/* Generated by Pyrex 0.9.5.1a on Wed Jun 13 13:36:59 2007 */
 
 #include "Python.h"
 #include "structmember.h"
@@ -49,18 +49,23 @@
 struct __pyx_obj_4_mpi_MPI_Comm {
   PyObject_HEAD
   MPI_Comm comm;
+  int permanent;
 };
 
 
 struct __pyx_obj_4_mpi_MPI_Group {
   PyObject_HEAD
   MPI_Group group;
+  int permanent;
 };
 
 static PyTypeObject *__pyx_ptype_4_mpi_MPI_Comm = 0;
 static PyTypeObject *__pyx_ptype_4_mpi_MPI_Group = 0;
 static char (__pyx_v_4_mpi_cstring[1024]);
-static PyObject *(__pyx_f_4_mpi__newWorld(void)); /*proto*/
+static PyObject *(__pyx_f_4_mpi_permanentCommObj(MPI_Comm )); /*proto*/
+static PyObject *(__pyx_f_4_mpi_permanentGroupObj(MPI_Group )); /*proto*/
+static PyObject *(__pyx_f_4_mpi_getCommObj(MPI_Comm )); /*proto*/
+static PyObject *(__pyx_f_4_mpi_getGroupObj(MPI_Group )); /*proto*/
 
 
 /* Implementation of _mpi */
@@ -68,6 +73,10 @@
 
 static PyObject *__pyx_n_cmpi;
 static PyObject *__pyx_n_MPI_COMM_WORLD;
+static PyObject *__pyx_n_MPI_COMM_NULL;
+static PyObject *__pyx_n_MPI_COMM_SELF;
+static PyObject *__pyx_n_MPI_GROUP_NULL;
+static PyObject *__pyx_n_MPI_GROUP_EMPTY;
 static PyObject *__pyx_n_MPI_Error;
 static PyObject *__pyx_n_MPI_Barrier;
 static PyObject *__pyx_n_MPI_Comm_create;
@@ -92,6 +101,9 @@
   /* "/home/leif/dv/pythia/mpi/_mpi.pyx":12 */
   ((struct __pyx_obj_4_mpi_MPI_Comm *)__pyx_v_self)->comm = MPI_COMM_NULL;
 
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":13 */
+  ((struct __pyx_obj_4_mpi_MPI_Comm *)__pyx_v_self)->permanent = 0;
+
   __pyx_r = 0;
   Py_DECREF(__pyx_v_self);
   return __pyx_r;
@@ -106,40 +118,40 @@
   PyObject *__pyx_4 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":16 */
-  __pyx_1 = (((struct __pyx_obj_4_mpi_MPI_Comm *)__pyx_v_self)->comm != MPI_COMM_WORLD);
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":17 */
+  __pyx_1 = ((struct __pyx_obj_4_mpi_MPI_Comm *)__pyx_v_self)->permanent;
   if (__pyx_1) {
-    __pyx_1 = (((struct __pyx_obj_4_mpi_MPI_Comm *)__pyx_v_self)->comm != MPI_COMM_NULL);
-  }
-  if (__pyx_1) {
 
-    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":17 */
-    __pyx_v_error = MPI_Comm_free((&((struct __pyx_obj_4_mpi_MPI_Comm *)__pyx_v_self)->comm));
-
     /* "/home/leif/dv/pythia/mpi/_mpi.pyx":18 */
-    __pyx_1 = (__pyx_v_error != MPI_SUCCESS);
-    if (__pyx_1) {
-
-      /* "/home/leif/dv/pythia/mpi/_mpi.pyx":20 */
-      __pyx_2 = __Pyx_GetName(__pyx_m, __pyx_n_MPI_Error); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; goto __pyx_L1;}
-      __pyx_3 = PyInt_FromLong(__pyx_v_error); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; goto __pyx_L1;}
-      __pyx_4 = PyTuple_New(1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; goto __pyx_L1;}
-      PyTuple_SET_ITEM(__pyx_4, 0, __pyx_3);
-      __pyx_3 = 0;
-      __pyx_3 = PyObject_CallObject(__pyx_2, __pyx_4); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; goto __pyx_L1;}
-      Py_DECREF(__pyx_2); __pyx_2 = 0;
-      Py_DECREF(__pyx_4); __pyx_4 = 0;
-      __Pyx_Raise(__pyx_3, 0, 0);
-      Py_DECREF(__pyx_3); __pyx_3 = 0;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; goto __pyx_L1;}
-      goto __pyx_L3;
-    }
-    __pyx_L3:;
+    goto __pyx_L0;
     goto __pyx_L2;
   }
   __pyx_L2:;
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":21 */
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":19 */
+  __pyx_v_error = MPI_Comm_free((&((struct __pyx_obj_4_mpi_MPI_Comm *)__pyx_v_self)->comm));
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":20 */
+  __pyx_1 = (__pyx_v_error != MPI_SUCCESS);
+  if (__pyx_1) {
+
+    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":22 */
+    __pyx_2 = __Pyx_GetName(__pyx_m, __pyx_n_MPI_Error); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; goto __pyx_L1;}
+    __pyx_3 = PyInt_FromLong(__pyx_v_error); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; goto __pyx_L1;}
+    __pyx_4 = PyTuple_New(1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; goto __pyx_L1;}
+    PyTuple_SET_ITEM(__pyx_4, 0, __pyx_3);
+    __pyx_3 = 0;
+    __pyx_3 = PyObject_CallObject(__pyx_2, __pyx_4); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; goto __pyx_L1;}
+    Py_DECREF(__pyx_2); __pyx_2 = 0;
+    Py_DECREF(__pyx_4); __pyx_4 = 0;
+    __Pyx_Raise(__pyx_3, 0, 0);
+    Py_DECREF(__pyx_3); __pyx_3 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; goto __pyx_L1;}
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":23 */
   goto __pyx_L0;
 
   goto __pyx_L0;
@@ -159,9 +171,12 @@
   if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "", __pyx_argnames)) return -1;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":27 */
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":29 */
   ((struct __pyx_obj_4_mpi_MPI_Group *)__pyx_v_self)->group = MPI_GROUP_NULL;
 
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":30 */
+  ((struct __pyx_obj_4_mpi_MPI_Group *)__pyx_v_self)->permanent = 0;
+
   __pyx_r = 0;
   Py_DECREF(__pyx_v_self);
   return __pyx_r;
@@ -176,37 +191,40 @@
   PyObject *__pyx_4 = 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":31 */
-  __pyx_1 = (((struct __pyx_obj_4_mpi_MPI_Group *)__pyx_v_self)->group != MPI_GROUP_NULL);
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":34 */
+  __pyx_1 = ((struct __pyx_obj_4_mpi_MPI_Group *)__pyx_v_self)->permanent;
   if (__pyx_1) {
 
-    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":32 */
-    __pyx_v_error = MPI_Group_free((&((struct __pyx_obj_4_mpi_MPI_Group *)__pyx_v_self)->group));
-
-    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":33 */
-    __pyx_1 = (__pyx_v_error != MPI_SUCCESS);
-    if (__pyx_1) {
-
-      /* "/home/leif/dv/pythia/mpi/_mpi.pyx":34 */
-      __pyx_2 = __Pyx_GetName(__pyx_m, __pyx_n_MPI_Error); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 34; goto __pyx_L1;}
-      __pyx_3 = PyInt_FromLong(__pyx_v_error); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 34; goto __pyx_L1;}
-      __pyx_4 = PyTuple_New(1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 34; goto __pyx_L1;}
-      PyTuple_SET_ITEM(__pyx_4, 0, __pyx_3);
-      __pyx_3 = 0;
-      __pyx_3 = PyObject_CallObject(__pyx_2, __pyx_4); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 34; goto __pyx_L1;}
-      Py_DECREF(__pyx_2); __pyx_2 = 0;
-      Py_DECREF(__pyx_4); __pyx_4 = 0;
-      __Pyx_Raise(__pyx_3, 0, 0);
-      Py_DECREF(__pyx_3); __pyx_3 = 0;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 34; goto __pyx_L1;}
-      goto __pyx_L3;
-    }
-    __pyx_L3:;
+    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":35 */
+    goto __pyx_L0;
     goto __pyx_L2;
   }
   __pyx_L2:;
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":35 */
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":36 */
+  __pyx_v_error = MPI_Group_free((&((struct __pyx_obj_4_mpi_MPI_Group *)__pyx_v_self)->group));
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":37 */
+  __pyx_1 = (__pyx_v_error != MPI_SUCCESS);
+  if (__pyx_1) {
+
+    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":38 */
+    __pyx_2 = __Pyx_GetName(__pyx_m, __pyx_n_MPI_Error); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; goto __pyx_L1;}
+    __pyx_3 = PyInt_FromLong(__pyx_v_error); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; goto __pyx_L1;}
+    __pyx_4 = PyTuple_New(1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; goto __pyx_L1;}
+    PyTuple_SET_ITEM(__pyx_4, 0, __pyx_3);
+    __pyx_3 = 0;
+    __pyx_3 = PyObject_CallObject(__pyx_2, __pyx_4); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; goto __pyx_L1;}
+    Py_DECREF(__pyx_2); __pyx_2 = 0;
+    Py_DECREF(__pyx_4); __pyx_4 = 0;
+    __Pyx_Raise(__pyx_3, 0, 0);
+    Py_DECREF(__pyx_3); __pyx_3 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; goto __pyx_L1;}
+    goto __pyx_L3;
+  }
+  __pyx_L3:;
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":39 */
   goto __pyx_L0;
 
   goto __pyx_L0;
@@ -219,38 +237,198 @@
   Py_DECREF(__pyx_v_self);
 }
 
-static PyObject *__pyx_f_4_mpi__newWorld(void) {
-  struct __pyx_obj_4_mpi_MPI_Comm *__pyx_v_world;
+static PyObject *__pyx_f_4_mpi_permanentCommObj(MPI_Comm __pyx_v_comm) {
+  struct __pyx_obj_4_mpi_MPI_Comm *__pyx_v_obj;
   PyObject *__pyx_r;
   PyObject *__pyx_1 = 0;
-  __pyx_v_world = ((struct __pyx_obj_4_mpi_MPI_Comm *)Py_None); Py_INCREF(Py_None);
+  __pyx_v_obj = ((struct __pyx_obj_4_mpi_MPI_Comm *)Py_None); Py_INCREF(Py_None);
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":40 */
-  __pyx_1 = PyObject_CallObject(((PyObject*)__pyx_ptype_4_mpi_MPI_Comm), 0); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 40; goto __pyx_L1;}
-  if (!__Pyx_TypeTest(__pyx_1, __pyx_ptype_4_mpi_MPI_Comm)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 40; goto __pyx_L1;}
-  Py_DECREF(((PyObject *)__pyx_v_world));
-  __pyx_v_world = ((struct __pyx_obj_4_mpi_MPI_Comm *)__pyx_1);
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":44 */
+  __pyx_1 = PyObject_CallObject(((PyObject*)__pyx_ptype_4_mpi_MPI_Comm), 0); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 44; goto __pyx_L1;}
+  if (!__Pyx_TypeTest(__pyx_1, __pyx_ptype_4_mpi_MPI_Comm)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 44; goto __pyx_L1;}
+  Py_DECREF(((PyObject *)__pyx_v_obj));
+  __pyx_v_obj = ((struct __pyx_obj_4_mpi_MPI_Comm *)__pyx_1);
   __pyx_1 = 0;
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":41 */
-  __pyx_v_world->comm = MPI_COMM_WORLD;
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":45 */
+  __pyx_v_obj->comm = __pyx_v_comm;
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":42 */
-  Py_INCREF(((PyObject *)__pyx_v_world));
-  __pyx_r = ((PyObject *)__pyx_v_world);
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":46 */
+  __pyx_v_obj->permanent = 1;
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":47 */
+  Py_INCREF(((PyObject *)__pyx_v_obj));
+  __pyx_r = ((PyObject *)__pyx_v_obj);
   goto __pyx_L0;
 
   __pyx_r = Py_None; Py_INCREF(Py_None);
   goto __pyx_L0;
   __pyx_L1:;
   Py_XDECREF(__pyx_1);
-  __Pyx_AddTraceback("_mpi._newWorld");
+  __Pyx_AddTraceback("_mpi.permanentCommObj");
   __pyx_r = 0;
   __pyx_L0:;
-  Py_DECREF(__pyx_v_world);
+  Py_DECREF(__pyx_v_obj);
   return __pyx_r;
 }
 
+static PyObject *__pyx_f_4_mpi_permanentGroupObj(MPI_Group __pyx_v_group) {
+  struct __pyx_obj_4_mpi_MPI_Group *__pyx_v_obj;
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  __pyx_v_obj = ((struct __pyx_obj_4_mpi_MPI_Group *)Py_None); Py_INCREF(Py_None);
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":51 */
+  __pyx_1 = PyObject_CallObject(((PyObject*)__pyx_ptype_4_mpi_MPI_Group), 0); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 51; goto __pyx_L1;}
+  if (!__Pyx_TypeTest(__pyx_1, __pyx_ptype_4_mpi_MPI_Group)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 51; goto __pyx_L1;}
+  Py_DECREF(((PyObject *)__pyx_v_obj));
+  __pyx_v_obj = ((struct __pyx_obj_4_mpi_MPI_Group *)__pyx_1);
+  __pyx_1 = 0;
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":52 */
+  __pyx_v_obj->group = __pyx_v_group;
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":53 */
+  __pyx_v_obj->permanent = 1;
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":54 */
+  Py_INCREF(((PyObject *)__pyx_v_obj));
+  __pyx_r = ((PyObject *)__pyx_v_obj);
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("_mpi.permanentGroupObj");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_obj);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_4_mpi_getCommObj(MPI_Comm __pyx_v_comm) {
+  struct __pyx_obj_4_mpi_MPI_Comm *__pyx_v_obj;
+  PyObject *__pyx_r;
+  int __pyx_1;
+  PyObject *__pyx_2 = 0;
+  __pyx_v_obj = ((struct __pyx_obj_4_mpi_MPI_Comm *)Py_None); Py_INCREF(Py_None);
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":67 */
+  __pyx_1 = (__pyx_v_comm == MPI_COMM_WORLD);
+  if (__pyx_1) {
+
+    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":68 */
+    __pyx_2 = __Pyx_GetName(__pyx_m, __pyx_n_MPI_COMM_WORLD); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 68; goto __pyx_L1;}
+    __pyx_r = __pyx_2;
+    __pyx_2 = 0;
+    goto __pyx_L0;
+    goto __pyx_L2;
+  }
+  __pyx_1 = (__pyx_v_comm == MPI_COMM_NULL);
+  if (__pyx_1) {
+
+    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":70 */
+    __pyx_2 = __Pyx_GetName(__pyx_m, __pyx_n_MPI_COMM_NULL); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; goto __pyx_L1;}
+    __pyx_r = __pyx_2;
+    __pyx_2 = 0;
+    goto __pyx_L0;
+    goto __pyx_L2;
+  }
+  __pyx_1 = (__pyx_v_comm == MPI_COMM_SELF);
+  if (__pyx_1) {
+
+    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":72 */
+    __pyx_2 = __Pyx_GetName(__pyx_m, __pyx_n_MPI_COMM_SELF); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; goto __pyx_L1;}
+    __pyx_r = __pyx_2;
+    __pyx_2 = 0;
+    goto __pyx_L0;
+    goto __pyx_L2;
+  }
+  __pyx_L2:;
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":73 */
+  __pyx_2 = PyObject_CallObject(((PyObject*)__pyx_ptype_4_mpi_MPI_Comm), 0); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 73; goto __pyx_L1;}
+  if (!__Pyx_TypeTest(__pyx_2, __pyx_ptype_4_mpi_MPI_Comm)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 73; goto __pyx_L1;}
+  Py_DECREF(((PyObject *)__pyx_v_obj));
+  __pyx_v_obj = ((struct __pyx_obj_4_mpi_MPI_Comm *)__pyx_2);
+  __pyx_2 = 0;
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":74 */
+  __pyx_v_obj->comm = __pyx_v_comm;
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":75 */
+  Py_INCREF(((PyObject *)__pyx_v_obj));
+  __pyx_r = ((PyObject *)__pyx_v_obj);
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_2);
+  __Pyx_AddTraceback("_mpi.getCommObj");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_obj);
+  return __pyx_r;
+}
+
+static PyObject *__pyx_f_4_mpi_getGroupObj(MPI_Group __pyx_v_group) {
+  struct __pyx_obj_4_mpi_MPI_Group *__pyx_v_obj;
+  PyObject *__pyx_r;
+  int __pyx_1;
+  PyObject *__pyx_2 = 0;
+  __pyx_v_obj = ((struct __pyx_obj_4_mpi_MPI_Group *)Py_None); Py_INCREF(Py_None);
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":79 */
+  __pyx_1 = (__pyx_v_group == MPI_GROUP_NULL);
+  if (__pyx_1) {
+
+    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":80 */
+    __pyx_2 = __Pyx_GetName(__pyx_m, __pyx_n_MPI_GROUP_NULL); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 80; goto __pyx_L1;}
+    __pyx_r = __pyx_2;
+    __pyx_2 = 0;
+    goto __pyx_L0;
+    goto __pyx_L2;
+  }
+  __pyx_1 = (__pyx_v_group == MPI_GROUP_EMPTY);
+  if (__pyx_1) {
+
+    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":82 */
+    __pyx_2 = __Pyx_GetName(__pyx_m, __pyx_n_MPI_GROUP_EMPTY); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 82; goto __pyx_L1;}
+    __pyx_r = __pyx_2;
+    __pyx_2 = 0;
+    goto __pyx_L0;
+    goto __pyx_L2;
+  }
+  __pyx_L2:;
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":83 */
+  __pyx_2 = PyObject_CallObject(((PyObject*)__pyx_ptype_4_mpi_MPI_Group), 0); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 83; goto __pyx_L1;}
+  if (!__Pyx_TypeTest(__pyx_2, __pyx_ptype_4_mpi_MPI_Group)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 83; goto __pyx_L1;}
+  Py_DECREF(((PyObject *)__pyx_v_obj));
+  __pyx_v_obj = ((struct __pyx_obj_4_mpi_MPI_Group *)__pyx_2);
+  __pyx_2 = 0;
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":84 */
+  __pyx_v_obj->group = __pyx_v_group;
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":85 */
+  Py_INCREF(((PyObject *)__pyx_v_obj));
+  __pyx_r = ((PyObject *)__pyx_v_obj);
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_2);
+  __Pyx_AddTraceback("_mpi.getGroupObj");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_obj);
+  return __pyx_r;
+}
+
 static PyObject *__pyx_n_args;
 
 static PyObject *__pyx_f_4_mpi_9MPI_Error___str__(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
@@ -266,17 +444,17 @@
   if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "O", __pyx_argnames, &__pyx_v_self)) return 0;
   Py_INCREF(__pyx_v_self);
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":49 */
-  __pyx_1 = __Pyx_GetName(__pyx_m, __pyx_n_MPI_Error_string); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 49; goto __pyx_L1;}
-  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_n_args); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 49; goto __pyx_L1;}
-  __pyx_3 = PyInt_FromLong(0); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 49; goto __pyx_L1;}
-  __pyx_4 = PyObject_GetItem(__pyx_2, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 49; goto __pyx_L1;}
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":90 */
+  __pyx_1 = __Pyx_GetName(__pyx_m, __pyx_n_MPI_Error_string); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; goto __pyx_L1;}
+  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_n_args); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; goto __pyx_L1;}
+  __pyx_3 = PyInt_FromLong(0); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; goto __pyx_L1;}
+  __pyx_4 = PyObject_GetItem(__pyx_2, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; goto __pyx_L1;}
   Py_DECREF(__pyx_2); __pyx_2 = 0;
   Py_DECREF(__pyx_3); __pyx_3 = 0;
-  __pyx_2 = PyTuple_New(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 49; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; goto __pyx_L1;}
   PyTuple_SET_ITEM(__pyx_2, 0, __pyx_4);
   __pyx_4 = 0;
-  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 49; goto __pyx_L1;}
+  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
   Py_DECREF(__pyx_2); __pyx_2 = 0;
   __pyx_r = __pyx_3;
@@ -309,32 +487,32 @@
   static char *__pyx_argnames[] = {"comm",0};
   if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "O", __pyx_argnames, &__pyx_v_comm)) return 0;
   Py_INCREF(__pyx_v_comm);
-  if (!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_comm), __pyx_ptype_4_mpi_MPI_Comm, 1, "comm")) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 52; goto __pyx_L1;}
+  if (!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_comm), __pyx_ptype_4_mpi_MPI_Comm, 1, "comm")) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; goto __pyx_L1;}
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":54 */
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":95 */
   __pyx_v_error = MPI_Barrier(__pyx_v_comm->comm);
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":55 */
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":96 */
   __pyx_1 = (__pyx_v_error != MPI_SUCCESS);
   if (__pyx_1) {
 
-    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":56 */
-    __pyx_2 = __Pyx_GetName(__pyx_m, __pyx_n_MPI_Error); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 56; goto __pyx_L1;}
-    __pyx_3 = PyInt_FromLong(__pyx_v_error); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 56; goto __pyx_L1;}
-    __pyx_4 = PyTuple_New(1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 56; goto __pyx_L1;}
+    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":97 */
+    __pyx_2 = __Pyx_GetName(__pyx_m, __pyx_n_MPI_Error); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 97; goto __pyx_L1;}
+    __pyx_3 = PyInt_FromLong(__pyx_v_error); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 97; goto __pyx_L1;}
+    __pyx_4 = PyTuple_New(1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 97; goto __pyx_L1;}
     PyTuple_SET_ITEM(__pyx_4, 0, __pyx_3);
     __pyx_3 = 0;
-    __pyx_3 = PyObject_CallObject(__pyx_2, __pyx_4); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 56; goto __pyx_L1;}
+    __pyx_3 = PyObject_CallObject(__pyx_2, __pyx_4); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 97; goto __pyx_L1;}
     Py_DECREF(__pyx_2); __pyx_2 = 0;
     Py_DECREF(__pyx_4); __pyx_4 = 0;
     __Pyx_Raise(__pyx_3, 0, 0);
     Py_DECREF(__pyx_3); __pyx_3 = 0;
-    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 56; goto __pyx_L1;}
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 97; goto __pyx_L1;}
     goto __pyx_L2;
   }
   __pyx_L2:;
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":57 */
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":98 */
   __pyx_r = Py_None; Py_INCREF(Py_None);
   goto __pyx_L0;
 
@@ -356,65 +534,57 @@
   struct __pyx_obj_4_mpi_MPI_Comm *__pyx_v_comm = 0;
   struct __pyx_obj_4_mpi_MPI_Group *__pyx_v_group = 0;
   int __pyx_v_error;
-  struct __pyx_obj_4_mpi_MPI_Comm *__pyx_v_comm_out;
+  MPI_Comm __pyx_v_comm_out;
   PyObject *__pyx_r;
-  PyObject *__pyx_1 = 0;
-  int __pyx_2;
+  int __pyx_1;
+  PyObject *__pyx_2 = 0;
   PyObject *__pyx_3 = 0;
   PyObject *__pyx_4 = 0;
   static char *__pyx_argnames[] = {"comm","group",0};
   if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "OO", __pyx_argnames, &__pyx_v_comm, &__pyx_v_group)) return 0;
   Py_INCREF(__pyx_v_comm);
   Py_INCREF(__pyx_v_group);
-  __pyx_v_comm_out = ((struct __pyx_obj_4_mpi_MPI_Comm *)Py_None); Py_INCREF(Py_None);
-  if (!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_comm), __pyx_ptype_4_mpi_MPI_Comm, 1, "comm")) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; goto __pyx_L1;}
-  if (!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_group), __pyx_ptype_4_mpi_MPI_Group, 1, "group")) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; goto __pyx_L1;}
+  if (!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_comm), __pyx_ptype_4_mpi_MPI_Comm, 1, "comm")) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; goto __pyx_L1;}
+  if (!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_group), __pyx_ptype_4_mpi_MPI_Group, 1, "group")) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; goto __pyx_L1;}
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":63 */
-  __pyx_1 = PyObject_CallObject(((PyObject*)__pyx_ptype_4_mpi_MPI_Comm), 0); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; goto __pyx_L1;}
-  if (!__Pyx_TypeTest(__pyx_1, __pyx_ptype_4_mpi_MPI_Comm)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; goto __pyx_L1;}
-  Py_DECREF(((PyObject *)__pyx_v_comm_out));
-  __pyx_v_comm_out = ((struct __pyx_obj_4_mpi_MPI_Comm *)__pyx_1);
-  __pyx_1 = 0;
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":104 */
+  __pyx_v_error = MPI_Comm_create(__pyx_v_comm->comm,__pyx_v_group->group,(&__pyx_v_comm_out));
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":64 */
-  __pyx_v_error = MPI_Comm_create(__pyx_v_comm->comm,__pyx_v_group->group,(&__pyx_v_comm_out->comm));
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":105 */
+  __pyx_1 = (__pyx_v_error != MPI_SUCCESS);
+  if (__pyx_1) {
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":65 */
-  __pyx_2 = (__pyx_v_error != MPI_SUCCESS);
-  if (__pyx_2) {
-
-    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":66 */
-    __pyx_1 = __Pyx_GetName(__pyx_m, __pyx_n_MPI_Error); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; goto __pyx_L1;}
-    __pyx_3 = PyInt_FromLong(__pyx_v_error); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; goto __pyx_L1;}
-    __pyx_4 = PyTuple_New(1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; goto __pyx_L1;}
+    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":106 */
+    __pyx_2 = __Pyx_GetName(__pyx_m, __pyx_n_MPI_Error); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 106; goto __pyx_L1;}
+    __pyx_3 = PyInt_FromLong(__pyx_v_error); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 106; goto __pyx_L1;}
+    __pyx_4 = PyTuple_New(1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 106; goto __pyx_L1;}
     PyTuple_SET_ITEM(__pyx_4, 0, __pyx_3);
     __pyx_3 = 0;
-    __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_4); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; goto __pyx_L1;}
-    Py_DECREF(__pyx_1); __pyx_1 = 0;
+    __pyx_3 = PyObject_CallObject(__pyx_2, __pyx_4); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 106; goto __pyx_L1;}
+    Py_DECREF(__pyx_2); __pyx_2 = 0;
     Py_DECREF(__pyx_4); __pyx_4 = 0;
     __Pyx_Raise(__pyx_3, 0, 0);
     Py_DECREF(__pyx_3); __pyx_3 = 0;
-    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; goto __pyx_L1;}
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 106; goto __pyx_L1;}
     goto __pyx_L2;
   }
   __pyx_L2:;
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":67 */
-  Py_INCREF(((PyObject *)__pyx_v_comm_out));
-  __pyx_r = ((PyObject *)__pyx_v_comm_out);
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":107 */
+  __pyx_2 = __pyx_f_4_mpi_getCommObj(__pyx_v_comm_out); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 107; goto __pyx_L1;}
+  __pyx_r = __pyx_2;
+  __pyx_2 = 0;
   goto __pyx_L0;
 
   __pyx_r = Py_None; Py_INCREF(Py_None);
   goto __pyx_L0;
   __pyx_L1:;
-  Py_XDECREF(__pyx_1);
+  Py_XDECREF(__pyx_2);
   Py_XDECREF(__pyx_3);
   Py_XDECREF(__pyx_4);
   __Pyx_AddTraceback("_mpi.MPI_Comm_create");
   __pyx_r = 0;
   __pyx_L0:;
-  Py_DECREF(__pyx_v_comm_out);
   Py_DECREF(__pyx_v_comm);
   Py_DECREF(__pyx_v_group);
   return __pyx_r;
@@ -423,7 +593,7 @@
 static PyObject *__pyx_f_4_mpi_MPI_Comm_group(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static PyObject *__pyx_f_4_mpi_MPI_Comm_group(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   struct __pyx_obj_4_mpi_MPI_Comm *__pyx_v_comm = 0;
-  struct __pyx_obj_4_mpi_MPI_Group *__pyx_v_group;
+  MPI_Group __pyx_v_group;
   PyObject *__pyx_v_error;
   PyObject *__pyx_r;
   PyObject *__pyx_1 = 0;
@@ -433,48 +603,41 @@
   static char *__pyx_argnames[] = {"comm",0};
   if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "O", __pyx_argnames, &__pyx_v_comm)) return 0;
   Py_INCREF(__pyx_v_comm);
-  __pyx_v_group = ((struct __pyx_obj_4_mpi_MPI_Group *)Py_None); Py_INCREF(Py_None);
   __pyx_v_error = Py_None; Py_INCREF(Py_None);
-  if (!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_comm), __pyx_ptype_4_mpi_MPI_Comm, 1, "comm")) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; goto __pyx_L1;}
+  if (!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_comm), __pyx_ptype_4_mpi_MPI_Comm, 1, "comm")) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; goto __pyx_L1;}
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":72 */
-  __pyx_1 = PyObject_CallObject(((PyObject*)__pyx_ptype_4_mpi_MPI_Group), 0); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; goto __pyx_L1;}
-  if (!__Pyx_TypeTest(__pyx_1, __pyx_ptype_4_mpi_MPI_Group)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; goto __pyx_L1;}
-  Py_DECREF(((PyObject *)__pyx_v_group));
-  __pyx_v_group = ((struct __pyx_obj_4_mpi_MPI_Group *)__pyx_1);
-  __pyx_1 = 0;
-
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":73 */
-  __pyx_1 = PyInt_FromLong(MPI_Comm_group(__pyx_v_comm->comm,(&__pyx_v_group->group))); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 73; goto __pyx_L1;}
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":112 */
+  __pyx_1 = PyInt_FromLong(MPI_Comm_group(__pyx_v_comm->comm,(&__pyx_v_group))); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 112; goto __pyx_L1;}
   Py_DECREF(__pyx_v_error);
   __pyx_v_error = __pyx_1;
   __pyx_1 = 0;
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":74 */
-  __pyx_1 = PyInt_FromLong(MPI_SUCCESS); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; goto __pyx_L1;}
-  if (PyObject_Cmp(__pyx_v_error, __pyx_1, &__pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; goto __pyx_L1;}
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":113 */
+  __pyx_1 = PyInt_FromLong(MPI_SUCCESS); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; goto __pyx_L1;}
+  if (PyObject_Cmp(__pyx_v_error, __pyx_1, &__pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; goto __pyx_L1;}
   __pyx_2 = __pyx_2 != 0;
   Py_DECREF(__pyx_1); __pyx_1 = 0;
   if (__pyx_2) {
 
-    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":75 */
-    __pyx_1 = __Pyx_GetName(__pyx_m, __pyx_n_MPI_Error); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 75; goto __pyx_L1;}
-    __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 75; goto __pyx_L1;}
+    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":114 */
+    __pyx_1 = __Pyx_GetName(__pyx_m, __pyx_n_MPI_Error); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; goto __pyx_L1;}
+    __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; goto __pyx_L1;}
     Py_INCREF(__pyx_v_error);
     PyTuple_SET_ITEM(__pyx_3, 0, __pyx_v_error);
-    __pyx_4 = PyObject_CallObject(__pyx_1, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 75; goto __pyx_L1;}
+    __pyx_4 = PyObject_CallObject(__pyx_1, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; goto __pyx_L1;}
     Py_DECREF(__pyx_1); __pyx_1 = 0;
     Py_DECREF(__pyx_3); __pyx_3 = 0;
     __Pyx_Raise(__pyx_4, 0, 0);
     Py_DECREF(__pyx_4); __pyx_4 = 0;
-    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 75; goto __pyx_L1;}
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; goto __pyx_L1;}
     goto __pyx_L2;
   }
   __pyx_L2:;
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":76 */
-  Py_INCREF(((PyObject *)__pyx_v_group));
-  __pyx_r = ((PyObject *)__pyx_v_group);
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":115 */
+  __pyx_1 = __pyx_f_4_mpi_getGroupObj(__pyx_v_group); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 115; goto __pyx_L1;}
+  __pyx_r = __pyx_1;
+  __pyx_1 = 0;
   goto __pyx_L0;
 
   __pyx_r = Py_None; Py_INCREF(Py_None);
@@ -486,7 +649,6 @@
   __Pyx_AddTraceback("_mpi.MPI_Comm_group");
   __pyx_r = 0;
   __pyx_L0:;
-  Py_DECREF(__pyx_v_group);
   Py_DECREF(__pyx_v_error);
   Py_DECREF(__pyx_v_comm);
   return __pyx_r;
@@ -505,33 +667,33 @@
   static char *__pyx_argnames[] = {"comm",0};
   if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "O", __pyx_argnames, &__pyx_v_comm)) return 0;
   Py_INCREF(__pyx_v_comm);
-  if (!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_comm), __pyx_ptype_4_mpi_MPI_Comm, 1, "comm")) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; goto __pyx_L1;}
+  if (!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_comm), __pyx_ptype_4_mpi_MPI_Comm, 1, "comm")) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; goto __pyx_L1;}
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":82 */
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":121 */
   __pyx_v_error = MPI_Comm_rank(__pyx_v_comm->comm,(&__pyx_v_rank));
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":83 */
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":122 */
   __pyx_1 = (__pyx_v_error != MPI_SUCCESS);
   if (__pyx_1) {
 
-    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":84 */
-    __pyx_2 = __Pyx_GetName(__pyx_m, __pyx_n_MPI_Error); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; goto __pyx_L1;}
-    __pyx_3 = PyInt_FromLong(__pyx_v_error); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; goto __pyx_L1;}
-    __pyx_4 = PyTuple_New(1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; goto __pyx_L1;}
+    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":123 */
+    __pyx_2 = __Pyx_GetName(__pyx_m, __pyx_n_MPI_Error); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; goto __pyx_L1;}
+    __pyx_3 = PyInt_FromLong(__pyx_v_error); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; goto __pyx_L1;}
+    __pyx_4 = PyTuple_New(1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; goto __pyx_L1;}
     PyTuple_SET_ITEM(__pyx_4, 0, __pyx_3);
     __pyx_3 = 0;
-    __pyx_3 = PyObject_CallObject(__pyx_2, __pyx_4); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; goto __pyx_L1;}
+    __pyx_3 = PyObject_CallObject(__pyx_2, __pyx_4); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; goto __pyx_L1;}
     Py_DECREF(__pyx_2); __pyx_2 = 0;
     Py_DECREF(__pyx_4); __pyx_4 = 0;
     __Pyx_Raise(__pyx_3, 0, 0);
     Py_DECREF(__pyx_3); __pyx_3 = 0;
-    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; goto __pyx_L1;}
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; goto __pyx_L1;}
     goto __pyx_L2;
   }
   __pyx_L2:;
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":85 */
-  __pyx_2 = PyInt_FromLong(__pyx_v_rank); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 85; goto __pyx_L1;}
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":124 */
+  __pyx_2 = PyInt_FromLong(__pyx_v_rank); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 124; goto __pyx_L1;}
   __pyx_r = __pyx_2;
   __pyx_2 = 0;
   goto __pyx_L0;
@@ -562,33 +724,33 @@
   static char *__pyx_argnames[] = {"comm",0};
   if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "O", __pyx_argnames, &__pyx_v_comm)) return 0;
   Py_INCREF(__pyx_v_comm);
-  if (!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_comm), __pyx_ptype_4_mpi_MPI_Comm, 1, "comm")) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 88; goto __pyx_L1;}
+  if (!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_comm), __pyx_ptype_4_mpi_MPI_Comm, 1, "comm")) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; goto __pyx_L1;}
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":91 */
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":130 */
   __pyx_v_error = MPI_Comm_size(__pyx_v_comm->comm,(&__pyx_v_size));
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":92 */
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":131 */
   __pyx_1 = (__pyx_v_error != MPI_SUCCESS);
   if (__pyx_1) {
 
-    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":93 */
-    __pyx_2 = __Pyx_GetName(__pyx_m, __pyx_n_MPI_Error); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; goto __pyx_L1;}
-    __pyx_3 = PyInt_FromLong(__pyx_v_error); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; goto __pyx_L1;}
-    __pyx_4 = PyTuple_New(1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; goto __pyx_L1;}
+    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":132 */
+    __pyx_2 = __Pyx_GetName(__pyx_m, __pyx_n_MPI_Error); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; goto __pyx_L1;}
+    __pyx_3 = PyInt_FromLong(__pyx_v_error); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; goto __pyx_L1;}
+    __pyx_4 = PyTuple_New(1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; goto __pyx_L1;}
     PyTuple_SET_ITEM(__pyx_4, 0, __pyx_3);
     __pyx_3 = 0;
-    __pyx_3 = PyObject_CallObject(__pyx_2, __pyx_4); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; goto __pyx_L1;}
+    __pyx_3 = PyObject_CallObject(__pyx_2, __pyx_4); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; goto __pyx_L1;}
     Py_DECREF(__pyx_2); __pyx_2 = 0;
     Py_DECREF(__pyx_4); __pyx_4 = 0;
     __Pyx_Raise(__pyx_3, 0, 0);
     Py_DECREF(__pyx_3); __pyx_3 = 0;
-    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; goto __pyx_L1;}
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; goto __pyx_L1;}
     goto __pyx_L2;
   }
   __pyx_L2:;
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":94 */
-  __pyx_2 = PyInt_FromLong(__pyx_v_size); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 94; goto __pyx_L1;}
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":133 */
+  __pyx_2 = PyInt_FromLong(__pyx_v_size); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 133; goto __pyx_L1;}
   __pyx_r = __pyx_2;
   __pyx_2 = 0;
   goto __pyx_L0;
@@ -627,55 +789,55 @@
   if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "i", __pyx_argnames, &__pyx_v_errorcode)) return 0;
   __pyx_v_string = Py_None; Py_INCREF(Py_None);
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":102 */
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":141 */
   __pyx_v_error = MPI_Error_string(__pyx_v_errorcode,__pyx_v_4_mpi_cstring,(&__pyx_v_resultlen));
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":103 */
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":142 */
   __pyx_1 = (__pyx_v_error != MPI_SUCCESS);
   if (__pyx_1) {
 
-    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":104 */
-    __pyx_2 = __Pyx_GetName(__pyx_m, __pyx_n_MPI_Error); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; goto __pyx_L1;}
-    __pyx_3 = PyInt_FromLong(__pyx_v_error); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; goto __pyx_L1;}
-    __pyx_4 = PyTuple_New(1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; goto __pyx_L1;}
+    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":143 */
+    __pyx_2 = __Pyx_GetName(__pyx_m, __pyx_n_MPI_Error); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; goto __pyx_L1;}
+    __pyx_3 = PyInt_FromLong(__pyx_v_error); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; goto __pyx_L1;}
+    __pyx_4 = PyTuple_New(1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; goto __pyx_L1;}
     PyTuple_SET_ITEM(__pyx_4, 0, __pyx_3);
     __pyx_3 = 0;
-    __pyx_3 = PyObject_CallObject(__pyx_2, __pyx_4); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; goto __pyx_L1;}
+    __pyx_3 = PyObject_CallObject(__pyx_2, __pyx_4); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; goto __pyx_L1;}
     Py_DECREF(__pyx_2); __pyx_2 = 0;
     Py_DECREF(__pyx_4); __pyx_4 = 0;
     __Pyx_Raise(__pyx_3, 0, 0);
     Py_DECREF(__pyx_3); __pyx_3 = 0;
-    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; goto __pyx_L1;}
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; goto __pyx_L1;}
     goto __pyx_L2;
   }
   __pyx_L2:;
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":105 */
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":144 */
   __pyx_1 = (__pyx_v_resultlen >= 1024);
   if (__pyx_1) {
 
-    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":106 */
-    __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_RuntimeError); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 106; goto __pyx_L1;}
-    __pyx_4 = PyTuple_New(1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 106; goto __pyx_L1;}
+    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":145 */
+    __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_RuntimeError); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 145; goto __pyx_L1;}
+    __pyx_4 = PyTuple_New(1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 145; goto __pyx_L1;}
     Py_INCREF(__pyx_k2p);
     PyTuple_SET_ITEM(__pyx_4, 0, __pyx_k2p);
-    __pyx_3 = PyObject_CallObject(__pyx_2, __pyx_4); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 106; goto __pyx_L1;}
+    __pyx_3 = PyObject_CallObject(__pyx_2, __pyx_4); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 145; goto __pyx_L1;}
     Py_DECREF(__pyx_2); __pyx_2 = 0;
     Py_DECREF(__pyx_4); __pyx_4 = 0;
     __Pyx_Raise(__pyx_3, 0, 0);
     Py_DECREF(__pyx_3); __pyx_3 = 0;
-    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 106; goto __pyx_L1;}
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 145; goto __pyx_L1;}
     goto __pyx_L3;
   }
   __pyx_L3:;
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":107 */
-  __pyx_2 = PyString_FromString(__pyx_v_4_mpi_cstring); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 107; goto __pyx_L1;}
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":146 */
+  __pyx_2 = PyString_FromString(__pyx_v_4_mpi_cstring); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 146; goto __pyx_L1;}
   Py_DECREF(__pyx_v_string);
   __pyx_v_string = __pyx_2;
   __pyx_2 = 0;
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":108 */
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":147 */
   Py_INCREF(__pyx_v_string);
   __pyx_r = __pyx_v_string;
   goto __pyx_L0;
@@ -702,7 +864,7 @@
   int __pyx_v_error;
   int __pyx_v_n;
   int (*__pyx_v_ranks);
-  struct __pyx_obj_4_mpi_MPI_Group *__pyx_v_group_out;
+  MPI_Group __pyx_v_group_out;
   PyObject *__pyx_v_i;
   PyObject *__pyx_r;
   PyObject *__pyx_1 = 0;
@@ -715,76 +877,69 @@
   if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "OO", __pyx_argnames, &__pyx_v_group, &__pyx_v_members)) return 0;
   Py_INCREF(__pyx_v_group);
   Py_INCREF(__pyx_v_members);
-  __pyx_v_group_out = ((struct __pyx_obj_4_mpi_MPI_Group *)Py_None); Py_INCREF(Py_None);
   __pyx_v_i = Py_None; Py_INCREF(Py_None);
-  if (!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_group), __pyx_ptype_4_mpi_MPI_Group, 1, "group")) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 111; goto __pyx_L1;}
+  if (!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_group), __pyx_ptype_4_mpi_MPI_Group, 1, "group")) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 150; goto __pyx_L1;}
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":117 */
-  __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_len); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; goto __pyx_L1;}
-  __pyx_2 = PyTuple_New(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; goto __pyx_L1;}
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":156 */
+  __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_len); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; goto __pyx_L1;}
   Py_INCREF(__pyx_v_members);
   PyTuple_SET_ITEM(__pyx_2, 0, __pyx_v_members);
-  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; goto __pyx_L1;}
+  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
   Py_DECREF(__pyx_2); __pyx_2 = 0;
-  __pyx_4 = PyInt_AsLong(__pyx_3); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; goto __pyx_L1;}
+  __pyx_4 = PyInt_AsLong(__pyx_3); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; goto __pyx_L1;}
   Py_DECREF(__pyx_3); __pyx_3 = 0;
   __pyx_v_n = __pyx_4;
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":118 */
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":157 */
   __pyx_v_ranks = ((int (*))malloc((__pyx_v_n * (sizeof(int )))));
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":119 */
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":158 */
   for (__pyx_5 = 0; __pyx_5 < __pyx_v_n; ++__pyx_5) {
-    __pyx_1 = PyInt_FromLong(__pyx_5); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 119; goto __pyx_L1;}
+    __pyx_1 = PyInt_FromLong(__pyx_5); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 158; goto __pyx_L1;}
     Py_DECREF(__pyx_v_i);
     __pyx_v_i = __pyx_1;
     __pyx_1 = 0;
 
-    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":120 */
-    __pyx_2 = PyObject_GetItem(__pyx_v_members, __pyx_v_i); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; goto __pyx_L1;}
-    __pyx_4 = PyInt_AsLong(__pyx_2); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; goto __pyx_L1;}
+    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":159 */
+    __pyx_2 = PyObject_GetItem(__pyx_v_members, __pyx_v_i); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; goto __pyx_L1;}
+    __pyx_4 = PyInt_AsLong(__pyx_2); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; goto __pyx_L1;}
     Py_DECREF(__pyx_2); __pyx_2 = 0;
-    __pyx_6 = PyInt_AsLong(__pyx_v_i); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; goto __pyx_L1;}
+    __pyx_6 = PyInt_AsLong(__pyx_v_i); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; goto __pyx_L1;}
     (__pyx_v_ranks[__pyx_6]) = __pyx_4;
   }
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":122 */
-  __pyx_3 = PyObject_CallObject(((PyObject*)__pyx_ptype_4_mpi_MPI_Group), 0); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 122; goto __pyx_L1;}
-  if (!__Pyx_TypeTest(__pyx_3, __pyx_ptype_4_mpi_MPI_Group)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 122; goto __pyx_L1;}
-  Py_DECREF(((PyObject *)__pyx_v_group_out));
-  __pyx_v_group_out = ((struct __pyx_obj_4_mpi_MPI_Group *)__pyx_3);
-  __pyx_3 = 0;
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":161 */
+  __pyx_v_error = MPI_Group_excl(__pyx_v_group->group,__pyx_v_n,__pyx_v_ranks,(&__pyx_v_group_out));
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":124 */
-  __pyx_v_error = MPI_Group_excl(__pyx_v_group->group,__pyx_v_n,__pyx_v_ranks,(&__pyx_v_group_out->group));
-
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":126 */
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":163 */
   free(__pyx_v_ranks);
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":128 */
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":165 */
   __pyx_4 = (__pyx_v_error != MPI_SUCCESS);
   if (__pyx_4) {
 
-    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":129 */
-    __pyx_1 = __Pyx_GetName(__pyx_m, __pyx_n_MPI_Error); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 129; goto __pyx_L1;}
-    __pyx_2 = PyInt_FromLong(__pyx_v_error); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 129; goto __pyx_L1;}
-    __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 129; goto __pyx_L1;}
-    PyTuple_SET_ITEM(__pyx_3, 0, __pyx_2);
-    __pyx_2 = 0;
-    __pyx_2 = PyObject_CallObject(__pyx_1, __pyx_3); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 129; goto __pyx_L1;}
-    Py_DECREF(__pyx_1); __pyx_1 = 0;
+    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":166 */
+    __pyx_3 = __Pyx_GetName(__pyx_m, __pyx_n_MPI_Error); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 166; goto __pyx_L1;}
+    __pyx_1 = PyInt_FromLong(__pyx_v_error); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 166; goto __pyx_L1;}
+    __pyx_2 = PyTuple_New(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 166; goto __pyx_L1;}
+    PyTuple_SET_ITEM(__pyx_2, 0, __pyx_1);
+    __pyx_1 = 0;
+    __pyx_1 = PyObject_CallObject(__pyx_3, __pyx_2); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 166; goto __pyx_L1;}
     Py_DECREF(__pyx_3); __pyx_3 = 0;
-    __Pyx_Raise(__pyx_2, 0, 0);
     Py_DECREF(__pyx_2); __pyx_2 = 0;
-    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 129; goto __pyx_L1;}
+    __Pyx_Raise(__pyx_1, 0, 0);
+    Py_DECREF(__pyx_1); __pyx_1 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 166; goto __pyx_L1;}
     goto __pyx_L4;
   }
   __pyx_L4:;
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":131 */
-  Py_INCREF(((PyObject *)__pyx_v_group_out));
-  __pyx_r = ((PyObject *)__pyx_v_group_out);
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":168 */
+  __pyx_3 = __pyx_f_4_mpi_getGroupObj(__pyx_v_group_out); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 168; goto __pyx_L1;}
+  __pyx_r = __pyx_3;
+  __pyx_3 = 0;
   goto __pyx_L0;
 
   __pyx_r = Py_None; Py_INCREF(Py_None);
@@ -796,7 +951,6 @@
   __Pyx_AddTraceback("_mpi.MPI_Group_excl");
   __pyx_r = 0;
   __pyx_L0:;
-  Py_DECREF(__pyx_v_group_out);
   Py_DECREF(__pyx_v_i);
   Py_DECREF(__pyx_v_group);
   Py_DECREF(__pyx_v_members);
@@ -810,7 +964,7 @@
   int __pyx_v_error;
   int __pyx_v_n;
   int (*__pyx_v_ranks);
-  struct __pyx_obj_4_mpi_MPI_Group *__pyx_v_group_out;
+  MPI_Group __pyx_v_group_out;
   PyObject *__pyx_v_i;
   PyObject *__pyx_r;
   PyObject *__pyx_1 = 0;
@@ -823,76 +977,69 @@
   if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "OO", __pyx_argnames, &__pyx_v_group, &__pyx_v_members)) return 0;
   Py_INCREF(__pyx_v_group);
   Py_INCREF(__pyx_v_members);
-  __pyx_v_group_out = ((struct __pyx_obj_4_mpi_MPI_Group *)Py_None); Py_INCREF(Py_None);
   __pyx_v_i = Py_None; Py_INCREF(Py_None);
-  if (!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_group), __pyx_ptype_4_mpi_MPI_Group, 1, "group")) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 134; goto __pyx_L1;}
+  if (!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_group), __pyx_ptype_4_mpi_MPI_Group, 1, "group")) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 171; goto __pyx_L1;}
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":140 */
-  __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_len); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 140; goto __pyx_L1;}
-  __pyx_2 = PyTuple_New(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 140; goto __pyx_L1;}
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":177 */
+  __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_len); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 177; goto __pyx_L1;}
+  __pyx_2 = PyTuple_New(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 177; goto __pyx_L1;}
   Py_INCREF(__pyx_v_members);
   PyTuple_SET_ITEM(__pyx_2, 0, __pyx_v_members);
-  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 140; goto __pyx_L1;}
+  __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 177; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
   Py_DECREF(__pyx_2); __pyx_2 = 0;
-  __pyx_4 = PyInt_AsLong(__pyx_3); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 140; goto __pyx_L1;}
+  __pyx_4 = PyInt_AsLong(__pyx_3); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 177; goto __pyx_L1;}
   Py_DECREF(__pyx_3); __pyx_3 = 0;
   __pyx_v_n = __pyx_4;
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":141 */
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":178 */
   __pyx_v_ranks = ((int (*))malloc((__pyx_v_n * (sizeof(int )))));
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":142 */
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":179 */
   for (__pyx_5 = 0; __pyx_5 < __pyx_v_n; ++__pyx_5) {
-    __pyx_1 = PyInt_FromLong(__pyx_5); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 142; goto __pyx_L1;}
+    __pyx_1 = PyInt_FromLong(__pyx_5); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 179; goto __pyx_L1;}
     Py_DECREF(__pyx_v_i);
     __pyx_v_i = __pyx_1;
     __pyx_1 = 0;
 
-    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":143 */
-    __pyx_2 = PyObject_GetItem(__pyx_v_members, __pyx_v_i); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; goto __pyx_L1;}
-    __pyx_4 = PyInt_AsLong(__pyx_2); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; goto __pyx_L1;}
+    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":180 */
+    __pyx_2 = PyObject_GetItem(__pyx_v_members, __pyx_v_i); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 180; goto __pyx_L1;}
+    __pyx_4 = PyInt_AsLong(__pyx_2); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 180; goto __pyx_L1;}
     Py_DECREF(__pyx_2); __pyx_2 = 0;
-    __pyx_6 = PyInt_AsLong(__pyx_v_i); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; goto __pyx_L1;}
+    __pyx_6 = PyInt_AsLong(__pyx_v_i); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 180; goto __pyx_L1;}
     (__pyx_v_ranks[__pyx_6]) = __pyx_4;
   }
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":145 */
-  __pyx_3 = PyObject_CallObject(((PyObject*)__pyx_ptype_4_mpi_MPI_Group), 0); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 145; goto __pyx_L1;}
-  if (!__Pyx_TypeTest(__pyx_3, __pyx_ptype_4_mpi_MPI_Group)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 145; goto __pyx_L1;}
-  Py_DECREF(((PyObject *)__pyx_v_group_out));
-  __pyx_v_group_out = ((struct __pyx_obj_4_mpi_MPI_Group *)__pyx_3);
-  __pyx_3 = 0;
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":182 */
+  __pyx_v_error = MPI_Group_incl(__pyx_v_group->group,__pyx_v_n,__pyx_v_ranks,(&__pyx_v_group_out));
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":147 */
-  __pyx_v_error = MPI_Group_incl(__pyx_v_group->group,__pyx_v_n,__pyx_v_ranks,(&__pyx_v_group_out->group));
-
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":149 */
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":184 */
   free(__pyx_v_ranks);
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":151 */
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":186 */
   __pyx_4 = (__pyx_v_error != MPI_SUCCESS);
   if (__pyx_4) {
 
-    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":152 */
-    __pyx_1 = __Pyx_GetName(__pyx_m, __pyx_n_MPI_Error); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 152; goto __pyx_L1;}
-    __pyx_2 = PyInt_FromLong(__pyx_v_error); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 152; goto __pyx_L1;}
-    __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 152; goto __pyx_L1;}
-    PyTuple_SET_ITEM(__pyx_3, 0, __pyx_2);
-    __pyx_2 = 0;
-    __pyx_2 = PyObject_CallObject(__pyx_1, __pyx_3); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 152; goto __pyx_L1;}
-    Py_DECREF(__pyx_1); __pyx_1 = 0;
+    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":187 */
+    __pyx_3 = __Pyx_GetName(__pyx_m, __pyx_n_MPI_Error); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; goto __pyx_L1;}
+    __pyx_1 = PyInt_FromLong(__pyx_v_error); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; goto __pyx_L1;}
+    __pyx_2 = PyTuple_New(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; goto __pyx_L1;}
+    PyTuple_SET_ITEM(__pyx_2, 0, __pyx_1);
+    __pyx_1 = 0;
+    __pyx_1 = PyObject_CallObject(__pyx_3, __pyx_2); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; goto __pyx_L1;}
     Py_DECREF(__pyx_3); __pyx_3 = 0;
-    __Pyx_Raise(__pyx_2, 0, 0);
     Py_DECREF(__pyx_2); __pyx_2 = 0;
-    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 152; goto __pyx_L1;}
+    __Pyx_Raise(__pyx_1, 0, 0);
+    Py_DECREF(__pyx_1); __pyx_1 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; goto __pyx_L1;}
     goto __pyx_L4;
   }
   __pyx_L4:;
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":154 */
-  Py_INCREF(((PyObject *)__pyx_v_group_out));
-  __pyx_r = ((PyObject *)__pyx_v_group_out);
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":189 */
+  __pyx_3 = __pyx_f_4_mpi_getGroupObj(__pyx_v_group_out); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 189; goto __pyx_L1;}
+  __pyx_r = __pyx_3;
+  __pyx_3 = 0;
   goto __pyx_L0;
 
   __pyx_r = Py_None; Py_INCREF(Py_None);
@@ -904,7 +1051,6 @@
   __Pyx_AddTraceback("_mpi.MPI_Group_incl");
   __pyx_r = 0;
   __pyx_L0:;
-  Py_DECREF(__pyx_v_group_out);
   Py_DECREF(__pyx_v_i);
   Py_DECREF(__pyx_v_group);
   Py_DECREF(__pyx_v_members);
@@ -924,33 +1070,33 @@
   static char *__pyx_argnames[] = {"group",0};
   if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "O", __pyx_argnames, &__pyx_v_group)) return 0;
   Py_INCREF(__pyx_v_group);
-  if (!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_group), __pyx_ptype_4_mpi_MPI_Group, 1, "group")) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; goto __pyx_L1;}
+  if (!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_group), __pyx_ptype_4_mpi_MPI_Group, 1, "group")) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 192; goto __pyx_L1;}
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":160 */
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":195 */
   __pyx_v_error = MPI_Group_rank(__pyx_v_group->group,(&__pyx_v_rank));
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":161 */
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":196 */
   __pyx_1 = (__pyx_v_error != MPI_SUCCESS);
   if (__pyx_1) {
 
-    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":162 */
-    __pyx_2 = __Pyx_GetName(__pyx_m, __pyx_n_MPI_Error); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; goto __pyx_L1;}
-    __pyx_3 = PyInt_FromLong(__pyx_v_error); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; goto __pyx_L1;}
-    __pyx_4 = PyTuple_New(1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; goto __pyx_L1;}
+    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":197 */
+    __pyx_2 = __Pyx_GetName(__pyx_m, __pyx_n_MPI_Error); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 197; goto __pyx_L1;}
+    __pyx_3 = PyInt_FromLong(__pyx_v_error); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 197; goto __pyx_L1;}
+    __pyx_4 = PyTuple_New(1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 197; goto __pyx_L1;}
     PyTuple_SET_ITEM(__pyx_4, 0, __pyx_3);
     __pyx_3 = 0;
-    __pyx_3 = PyObject_CallObject(__pyx_2, __pyx_4); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; goto __pyx_L1;}
+    __pyx_3 = PyObject_CallObject(__pyx_2, __pyx_4); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 197; goto __pyx_L1;}
     Py_DECREF(__pyx_2); __pyx_2 = 0;
     Py_DECREF(__pyx_4); __pyx_4 = 0;
     __Pyx_Raise(__pyx_3, 0, 0);
     Py_DECREF(__pyx_3); __pyx_3 = 0;
-    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; goto __pyx_L1;}
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 197; goto __pyx_L1;}
     goto __pyx_L2;
   }
   __pyx_L2:;
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":163 */
-  __pyx_2 = PyInt_FromLong(__pyx_v_rank); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 163; goto __pyx_L1;}
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":198 */
+  __pyx_2 = PyInt_FromLong(__pyx_v_rank); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 198; goto __pyx_L1;}
   __pyx_r = __pyx_2;
   __pyx_2 = 0;
   goto __pyx_L0;
@@ -981,33 +1127,33 @@
   static char *__pyx_argnames[] = {"group",0};
   if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "O", __pyx_argnames, &__pyx_v_group)) return 0;
   Py_INCREF(__pyx_v_group);
-  if (!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_group), __pyx_ptype_4_mpi_MPI_Group, 1, "group")) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 166; goto __pyx_L1;}
+  if (!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_group), __pyx_ptype_4_mpi_MPI_Group, 1, "group")) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 201; goto __pyx_L1;}
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":169 */
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":204 */
   __pyx_v_error = MPI_Group_size(__pyx_v_group->group,(&__pyx_v_size));
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":170 */
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":205 */
   __pyx_1 = (__pyx_v_error != MPI_SUCCESS);
   if (__pyx_1) {
 
-    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":171 */
-    __pyx_2 = __Pyx_GetName(__pyx_m, __pyx_n_MPI_Error); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 171; goto __pyx_L1;}
-    __pyx_3 = PyInt_FromLong(__pyx_v_error); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 171; goto __pyx_L1;}
-    __pyx_4 = PyTuple_New(1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 171; goto __pyx_L1;}
+    /* "/home/leif/dv/pythia/mpi/_mpi.pyx":206 */
+    __pyx_2 = __Pyx_GetName(__pyx_m, __pyx_n_MPI_Error); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 206; goto __pyx_L1;}
+    __pyx_3 = PyInt_FromLong(__pyx_v_error); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 206; goto __pyx_L1;}
+    __pyx_4 = PyTuple_New(1); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 206; goto __pyx_L1;}
     PyTuple_SET_ITEM(__pyx_4, 0, __pyx_3);
     __pyx_3 = 0;
-    __pyx_3 = PyObject_CallObject(__pyx_2, __pyx_4); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 171; goto __pyx_L1;}
+    __pyx_3 = PyObject_CallObject(__pyx_2, __pyx_4); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 206; goto __pyx_L1;}
     Py_DECREF(__pyx_2); __pyx_2 = 0;
     Py_DECREF(__pyx_4); __pyx_4 = 0;
     __Pyx_Raise(__pyx_3, 0, 0);
     Py_DECREF(__pyx_3); __pyx_3 = 0;
-    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 171; goto __pyx_L1;}
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 206; goto __pyx_L1;}
     goto __pyx_L2;
   }
   __pyx_L2:;
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":172 */
-  __pyx_2 = PyInt_FromLong(__pyx_v_size); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 172; goto __pyx_L1;}
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":207 */
+  __pyx_2 = PyInt_FromLong(__pyx_v_size); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 207; goto __pyx_L1;}
   __pyx_r = __pyx_2;
   __pyx_2 = 0;
   goto __pyx_L0;
@@ -1028,6 +1174,8 @@
 static __Pyx_InternTabEntry __pyx_intern_tab[] = {
   {&__pyx_n_EnvironmentError, "EnvironmentError"},
   {&__pyx_n_MPI_Barrier, "MPI_Barrier"},
+  {&__pyx_n_MPI_COMM_NULL, "MPI_COMM_NULL"},
+  {&__pyx_n_MPI_COMM_SELF, "MPI_COMM_SELF"},
   {&__pyx_n_MPI_COMM_WORLD, "MPI_COMM_WORLD"},
   {&__pyx_n_MPI_Comm_create, "MPI_Comm_create"},
   {&__pyx_n_MPI_Comm_group, "MPI_Comm_group"},
@@ -1035,6 +1183,8 @@
   {&__pyx_n_MPI_Comm_size, "MPI_Comm_size"},
   {&__pyx_n_MPI_Error, "MPI_Error"},
   {&__pyx_n_MPI_Error_string, "MPI_Error_string"},
+  {&__pyx_n_MPI_GROUP_EMPTY, "MPI_GROUP_EMPTY"},
+  {&__pyx_n_MPI_GROUP_NULL, "MPI_GROUP_NULL"},
   {&__pyx_n_MPI_Group_excl, "MPI_Group_excl"},
   {&__pyx_n_MPI_Group_incl, "MPI_Group_incl"},
   {&__pyx_n_MPI_Group_rank, "MPI_Group_rank"},
@@ -1377,35 +1527,55 @@
   if (PyType_Ready(&__pyx_type_4_mpi_MPI_Comm) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 9; goto __pyx_L1;}
   if (PyObject_SetAttrString(__pyx_m, "MPI_Comm", (PyObject *)&__pyx_type_4_mpi_MPI_Comm) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 9; goto __pyx_L1;}
   __pyx_ptype_4_mpi_MPI_Comm = &__pyx_type_4_mpi_MPI_Comm;
-  if (PyType_Ready(&__pyx_type_4_mpi_MPI_Group) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; goto __pyx_L1;}
-  if (PyObject_SetAttrString(__pyx_m, "MPI_Group", (PyObject *)&__pyx_type_4_mpi_MPI_Group) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; goto __pyx_L1;}
+  if (PyType_Ready(&__pyx_type_4_mpi_MPI_Group) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; goto __pyx_L1;}
+  if (PyObject_SetAttrString(__pyx_m, "MPI_Group", (PyObject *)&__pyx_type_4_mpi_MPI_Group) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; goto __pyx_L1;}
   __pyx_ptype_4_mpi_MPI_Group = &__pyx_type_4_mpi_MPI_Group;
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":44 */
-  __pyx_1 = __pyx_f_4_mpi__newWorld(); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 44; goto __pyx_L1;}
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_MPI_COMM_WORLD, __pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 44; goto __pyx_L1;}
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":57 */
+  __pyx_1 = __pyx_f_4_mpi_permanentCommObj(MPI_COMM_WORLD); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 57; goto __pyx_L1;}
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_MPI_COMM_WORLD, __pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 57; goto __pyx_L1;}
   Py_DECREF(__pyx_1); __pyx_1 = 0;
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":47 */
-  __pyx_1 = PyDict_New(); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; goto __pyx_L1;}
-  __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_EnvironmentError); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; goto __pyx_L1;}
-  __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; goto __pyx_L1;}
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":58 */
+  __pyx_1 = __pyx_f_4_mpi_permanentCommObj(MPI_COMM_NULL); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; goto __pyx_L1;}
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_MPI_COMM_NULL, __pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":59 */
+  __pyx_1 = __pyx_f_4_mpi_permanentCommObj(MPI_COMM_SELF); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 59; goto __pyx_L1;}
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_MPI_COMM_SELF, __pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 59; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":61 */
+  __pyx_1 = __pyx_f_4_mpi_permanentGroupObj(MPI_GROUP_NULL); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; goto __pyx_L1;}
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_MPI_GROUP_NULL, __pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":62 */
+  __pyx_1 = __pyx_f_4_mpi_permanentGroupObj(MPI_GROUP_EMPTY); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; goto __pyx_L1;}
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_MPI_GROUP_EMPTY, __pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":88 */
+  __pyx_1 = PyDict_New(); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 88; goto __pyx_L1;}
+  __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_EnvironmentError); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 88; goto __pyx_L1;}
+  __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 88; goto __pyx_L1;}
   PyTuple_SET_ITEM(__pyx_3, 0, __pyx_2);
   __pyx_2 = 0;
-  __pyx_2 = __Pyx_CreateClass(__pyx_3, __pyx_1, __pyx_n_MPI_Error, "_mpi"); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; goto __pyx_L1;}
+  __pyx_2 = __Pyx_CreateClass(__pyx_3, __pyx_1, __pyx_n_MPI_Error, "_mpi"); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 88; goto __pyx_L1;}
   Py_DECREF(__pyx_3); __pyx_3 = 0;
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":48 */
-  __pyx_3 = PyCFunction_New(&__pyx_mdef_4_mpi_9MPI_Error___str__, 0); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 48; goto __pyx_L1;}
-  __pyx_4 = PyMethod_New(__pyx_3, 0, __pyx_2); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 48; goto __pyx_L1;}
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":89 */
+  __pyx_3 = PyCFunction_New(&__pyx_mdef_4_mpi_9MPI_Error___str__, 0); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 89; goto __pyx_L1;}
+  __pyx_4 = PyMethod_New(__pyx_3, 0, __pyx_2); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 89; goto __pyx_L1;}
   Py_DECREF(__pyx_3); __pyx_3 = 0;
-  if (PyObject_SetAttr(__pyx_2, __pyx_n___str__, __pyx_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 48; goto __pyx_L1;}
+  if (PyObject_SetAttr(__pyx_2, __pyx_n___str__, __pyx_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 89; goto __pyx_L1;}
   Py_DECREF(__pyx_4); __pyx_4 = 0;
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_MPI_Error, __pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; goto __pyx_L1;}
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_MPI_Error, __pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 88; goto __pyx_L1;}
   Py_DECREF(__pyx_2); __pyx_2 = 0;
   Py_DECREF(__pyx_1); __pyx_1 = 0;
 
-  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":166 */
+  /* "/home/leif/dv/pythia/mpi/_mpi.pyx":201 */
   return;
   __pyx_L1:;
   Py_XDECREF(__pyx_1);

Modified: cs/pythia/trunk/mpi/_mpi.pxd
===================================================================
--- cs/pythia/trunk/mpi/_mpi.pxd	2007-06-13 20:26:23 UTC (rev 7214)
+++ cs/pythia/trunk/mpi/_mpi.pxd	2007-06-13 20:52:06 UTC (rev 7215)
@@ -7,11 +7,13 @@
 cdef class MPI_Comm:
 
     cdef cmpi.MPI_Comm comm
+    cdef int permanent
 
 
 cdef class MPI_Group:
 
     cdef cmpi.MPI_Group group
+    cdef int permanent
 
 
 # end of file

Modified: cs/pythia/trunk/mpi/_mpi.pyx
===================================================================
--- cs/pythia/trunk/mpi/_mpi.pyx	2007-06-13 20:26:23 UTC (rev 7214)
+++ cs/pythia/trunk/mpi/_mpi.pyx	2007-06-13 20:52:06 UTC (rev 7215)
@@ -10,14 +10,16 @@
 
     def __init__(MPI_Comm self):
         self.comm = cmpi.MPI_COMM_NULL
+        self.permanent = 0
 
     def __dealloc__(MPI_Comm self):
         cdef int error
-        if self.comm != cmpi.MPI_COMM_WORLD and self.comm != cmpi.MPI_COMM_NULL:
-            error = cmpi.MPI_Comm_free(&self.comm)
-            if error != cmpi.MPI_SUCCESS:
-                # Will anyone hear our cries?
-                raise MPI_Error(error)
+        if self.permanent:
+            return
+        error = cmpi.MPI_Comm_free(&self.comm)
+        if error != cmpi.MPI_SUCCESS:
+            # Will anyone hear our cries?
+            raise MPI_Error(error)
         return
 
 
@@ -25,25 +27,64 @@
 
     def __init__(MPI_Group self):
         self.group = cmpi.MPI_GROUP_NULL
+        self.permanent = 0
 
     def __dealloc__(MPI_Group self):
         cdef int error
-        if self.group != cmpi.MPI_GROUP_NULL:
-            error = cmpi.MPI_Group_free(&self.group)
-            if error != cmpi.MPI_SUCCESS:
-                raise MPI_Error(error)
+        if self.permanent:
+            return
+        error = cmpi.MPI_Group_free(&self.group)
+        if error != cmpi.MPI_SUCCESS:
+            raise MPI_Error(error)
         return
 
 
-cdef _newWorld():
-    cdef MPI_Comm world
-    world = MPI_Comm()
-    world.comm = cmpi.MPI_COMM_WORLD
-    return world
+cdef permanentCommObj(cmpi.MPI_Comm comm):
+    cdef MPI_Comm obj
+    obj = MPI_Comm()
+    obj.comm = comm
+    obj.permanent = 1
+    return obj
 
-MPI_COMM_WORLD = _newWorld()
+cdef permanentGroupObj(cmpi.MPI_Group group):
+    cdef MPI_Group obj
+    obj = MPI_Group()
+    obj.group = group
+    obj.permanent = 1
+    return obj
 
 
+MPI_COMM_WORLD  = permanentCommObj(cmpi.MPI_COMM_WORLD)
+MPI_COMM_NULL   = permanentCommObj(cmpi.MPI_COMM_NULL)
+MPI_COMM_SELF   = permanentCommObj(cmpi.MPI_COMM_SELF)
+
+MPI_GROUP_NULL  = permanentGroupObj(cmpi.MPI_GROUP_NULL)
+MPI_GROUP_EMPTY = permanentGroupObj(cmpi.MPI_GROUP_EMPTY)
+
+
+cdef getCommObj(cmpi.MPI_Comm comm):
+    cdef MPI_Comm obj
+    if comm == cmpi.MPI_COMM_WORLD:
+        return MPI_COMM_WORLD
+    elif comm == cmpi.MPI_COMM_NULL:
+        return MPI_COMM_NULL
+    elif comm == cmpi.MPI_COMM_SELF:
+        return MPI_COMM_SELF
+    obj = MPI_Comm()
+    obj.comm = comm
+    return obj
+
+cdef getGroupObj(cmpi.MPI_Group group):
+    cdef MPI_Group obj
+    if group == cmpi.MPI_GROUP_NULL:
+        return MPI_GROUP_NULL
+    elif group == cmpi.MPI_GROUP_EMPTY:
+        return MPI_GROUP_EMPTY
+    obj = MPI_Group()
+    obj.group = group
+    return obj
+
+
 class MPI_Error(EnvironmentError):
     def __str__(self):
         return MPI_Error_string(self.args[0])
@@ -59,21 +100,19 @@
 
 def MPI_Comm_create(MPI_Comm comm, MPI_Group group):
     cdef int error
-    cdef MPI_Comm comm_out
-    comm_out = MPI_Comm()
-    error = cmpi.MPI_Comm_create(comm.comm, group.group, &comm_out.comm)
+    cdef cmpi.MPI_Comm comm_out
+    error = cmpi.MPI_Comm_create(comm.comm, group.group, &comm_out)
     if error != cmpi.MPI_SUCCESS:
         raise MPI_Error(error)
-    return comm_out
+    return getCommObj(comm_out)
 
 
 def MPI_Comm_group(MPI_Comm comm):
-    cdef MPI_Group group
-    group = MPI_Group()
-    error = cmpi.MPI_Comm_group(comm.comm, &group.group)
+    cdef cmpi.MPI_Group group
+    error = cmpi.MPI_Comm_group(comm.comm, &group)
     if error != cmpi.MPI_SUCCESS:
         raise MPI_Error(error)
-    return group
+    return getGroupObj(group)
 
 
 def MPI_Comm_rank(MPI_Comm comm):
@@ -112,46 +151,42 @@
     cdef int error
     cdef int n
     cdef int *ranks
-    cdef MPI_Group group_out
+    cdef cmpi.MPI_Group group_out
     
     n = len(members)
     ranks = <int *>malloc(n * sizeof(int))
     for i from 0 <= i < n:
         ranks[i] = members[i]
 
-    group_out = MPI_Group()
-
-    error = cmpi.MPI_Group_excl(group.group, n, ranks, &group_out.group)
+    error = cmpi.MPI_Group_excl(group.group, n, ranks, &group_out)
     
     free(ranks)
     
     if error != cmpi.MPI_SUCCESS:
         raise MPI_Error(error)
     
-    return group_out
+    return getGroupObj(group_out)
 
 
 def MPI_Group_incl(MPI_Group group, members):
     cdef int error
     cdef int n
     cdef int *ranks
-    cdef MPI_Group group_out
+    cdef cmpi.MPI_Group group_out
     
     n = len(members)
     ranks = <int *>malloc(n * sizeof(int))
     for i from 0 <= i < n:
         ranks[i] = members[i]
 
-    group_out = MPI_Group()
-
-    error = cmpi.MPI_Group_incl(group.group, n, ranks, &group_out.group)
+    error = cmpi.MPI_Group_incl(group.group, n, ranks, &group_out)
     
     free(ranks)
     
     if error != cmpi.MPI_SUCCESS:
         raise MPI_Error(error)
     
-    return group_out
+    return getGroupObj(group_out)
 
 
 def MPI_Group_rank(MPI_Group group):

Modified: cs/pythia/trunk/mpi/cmpi.pxd
===================================================================
--- cs/pythia/trunk/mpi/cmpi.pxd	2007-06-13 20:26:23 UTC (rev 7214)
+++ cs/pythia/trunk/mpi/cmpi.pxd	2007-06-13 20:52:06 UTC (rev 7215)
@@ -9,12 +9,14 @@
         pass
     ctypedef MPI_Comm_Imp *MPI_Comm
     MPI_Comm MPI_COMM_NULL
+    MPI_Comm MPI_COMM_SELF
     MPI_Comm MPI_COMM_WORLD
 
     ctypedef struct MPI_Group_Imp:
         pass
     ctypedef MPI_Group_Imp *MPI_Group
     MPI_Group MPI_GROUP_NULL
+    MPI_Group MPI_GROUP_EMPTY
 
     int MPI_Init(int *, char ***)
     int MPI_Finalize()

Modified: cs/pythia/trunk/mpi/pympi.h
===================================================================
--- cs/pythia/trunk/mpi/pympi.h	2007-06-13 20:26:23 UTC (rev 7214)
+++ cs/pythia/trunk/mpi/pympi.h	2007-06-13 20:52:06 UTC (rev 7215)
@@ -24,11 +24,13 @@
     typedef struct {
         PyObject_HEAD
         MPI_Comm comm;
+        int permanent;
     } PyMPICommObject;
 
     typedef struct {
         PyObject_HEAD
         MPI_Group group;
+        int permanent;
     } PyMPIGroupObject;
 
 #ifdef __cplusplus



More information about the cig-commits mailing list