1# ----------------------------------------------------------------------------- 2 3cdef dict datarep_registry = {} 4 5@cython.final 6@cython.internal 7cdef class _p_datarep: 8 9 cdef object read_fn 10 cdef object write_fn 11 cdef object extent_fn 12 13 def __cinit__(self, read_fn, write_fn, extent_fn): 14 self.read_fn = read_fn 15 self.write_fn = write_fn 16 self.extent_fn = extent_fn 17 18 cdef int read(self, 19 void *userbuf, 20 MPI_Datatype datatype, 21 int count, 22 void *filebuf, 23 MPI_Offset position, 24 ) except -1: 25 cdef MPI_Aint lb=0, extent=0 26 cdef int ierr = MPI_Type_get_extent(datatype, &lb, &extent) 27 if ierr != MPI_SUCCESS: return ierr 28 cdef MPI_Aint ulen = <MPI_Aint>(position+count) * extent 29 cdef MPI_Aint flen = <MPI_Aint>PY_SSIZE_T_MAX # XXX 30 cdef object ubuf = tomemory(userbuf, ulen) 31 cdef object fbuf = tomemory(filebuf, flen) 32 cdef Datatype dtype = Datatype.__new__(Datatype) 33 dtype.ob_mpi = datatype 34 try: self.read_fn(ubuf, dtype, count, fbuf, position) 35 finally: dtype.ob_mpi = MPI_DATATYPE_NULL 36 return MPI_SUCCESS 37 38 cdef int write(self, 39 void *userbuf, 40 MPI_Datatype datatype, 41 int count, 42 void *filebuf, 43 MPI_Offset position, 44 ) except -1: 45 cdef MPI_Aint lb=0, extent=0 46 cdef int ierr = MPI_Type_get_extent(datatype, &lb, &extent) 47 if ierr != MPI_SUCCESS: return ierr 48 cdef MPI_Aint ulen = <MPI_Aint>(position+count) * extent 49 cdef MPI_Aint flen = <MPI_Aint>PY_SSIZE_T_MAX # XXX 50 cdef object ubuf = tomemory(userbuf, ulen) 51 cdef object fbuf = tomemory(filebuf, flen) 52 cdef Datatype dtype = Datatype.__new__(Datatype) 53 dtype.ob_mpi = datatype 54 try: self.write_fn(ubuf, dtype, count, fbuf, position) 55 finally: dtype.ob_mpi = MPI_DATATYPE_NULL 56 return MPI_SUCCESS 57 58 cdef int extent(self, 59 MPI_Datatype datatype, 60 MPI_Aint *file_extent, 61 ) except -1: 62 cdef Datatype dtype = Datatype.__new__(Datatype) 63 dtype.ob_mpi = datatype 64 try: file_extent[0] = self.extent_fn(dtype) 65 finally: dtype.ob_mpi = MPI_DATATYPE_NULL 66 return MPI_SUCCESS 67 68# --- 69 70cdef int datarep_read( 71 void *userbuf, 72 MPI_Datatype datatype, 73 int count, 74 void *filebuf, 75 MPI_Offset position, 76 void *extra_state, 77 ) except MPI_ERR_UNKNOWN with gil: 78 cdef _p_datarep state = <_p_datarep>extra_state 79 cdef int ierr = MPI_SUCCESS 80 cdef object exc 81 try: 82 state.read(userbuf, datatype, count, filebuf, position) 83 except MPIException as exc: 84 print_traceback() 85 ierr = exc.Get_error_code() 86 except: 87 print_traceback() 88 ierr = MPI_ERR_OTHER 89 return ierr 90 91cdef int datarep_write( 92 void *userbuf, 93 MPI_Datatype datatype, 94 int count, 95 void *filebuf, 96 MPI_Offset position, 97 void *extra_state, 98 ) except MPI_ERR_UNKNOWN with gil: 99 cdef _p_datarep state = <_p_datarep>extra_state 100 cdef int ierr = MPI_SUCCESS 101 cdef object exc 102 try: 103 state.write(userbuf, datatype, count, filebuf, position) 104 except MPIException as exc: 105 print_traceback() 106 ierr = exc.Get_error_code() 107 except: 108 print_traceback() 109 ierr = MPI_ERR_OTHER 110 return ierr 111 112cdef int datarep_extent( 113 MPI_Datatype datatype, 114 MPI_Aint *file_extent, 115 void *extra_state, 116 ) except MPI_ERR_UNKNOWN with gil: 117 cdef _p_datarep state = <_p_datarep>extra_state 118 cdef int ierr = MPI_SUCCESS 119 cdef object exc 120 try: 121 state.extent(datatype, file_extent) 122 except MPIException as exc: 123 print_traceback() 124 ierr = exc.Get_error_code() 125 except: 126 print_traceback() 127 ierr = MPI_ERR_OTHER 128 return ierr 129 130# --- 131 132@cython.callspec("MPIAPI") 133cdef int datarep_read_fn( 134 void *userbuf, 135 MPI_Datatype datatype, 136 int count, 137 void *filebuf, 138 MPI_Offset position, 139 void *extra_state 140 ) nogil: 141 if extra_state == NULL: 142 return MPI_ERR_INTERN 143 if not Py_IsInitialized(): 144 return MPI_ERR_INTERN 145 return datarep_read(userbuf, datatype, count, 146 filebuf, position, extra_state) 147 148@cython.callspec("MPIAPI") 149cdef int datarep_write_fn( 150 void *userbuf, 151 MPI_Datatype datatype, 152 int count, 153 void *filebuf, 154 MPI_Offset position, 155 void *extra_state 156 ) nogil: 157 if extra_state == NULL: 158 return MPI_ERR_INTERN 159 if not Py_IsInitialized(): 160 return MPI_ERR_INTERN 161 return datarep_write(userbuf, datatype, count, 162 filebuf, position, extra_state) 163 164@cython.callspec("MPIAPI") 165cdef int datarep_extent_fn( 166 MPI_Datatype datatype, 167 MPI_Aint *file_extent, 168 void *extra_state 169 ) nogil: 170 if extra_state == NULL: 171 return MPI_ERR_INTERN 172 if not Py_IsInitialized(): 173 return MPI_ERR_INTERN 174 return datarep_extent(datatype, file_extent, extra_state) 175 176# ----------------------------------------------------------------------------- 177