1#------------------------------------------------------------------------------
2
3cdef extern from "Python.h":
4    enum: Py_LT
5    enum: Py_LE
6    enum: Py_EQ
7    enum: Py_NE
8    enum: Py_GT
9    enum: Py_GE
10
11#------------------------------------------------------------------------------
12
13cdef enum PyMPI_OBJECT_FLAGS:
14    PyMPI_OWNED = 1<<1
15
16#------------------------------------------------------------------------------
17# Status
18
19cdef extern from * nogil:
20    int PyMPI_Status_get_source(MPI_Status*, int*)
21    int PyMPI_Status_set_source(MPI_Status*, int)
22    int PyMPI_Status_get_tag(MPI_Status*, int*)
23    int PyMPI_Status_set_tag(MPI_Status*, int)
24    int PyMPI_Status_get_error(MPI_Status*, int*)
25    int PyMPI_Status_set_error(MPI_Status*, int)
26
27cdef inline MPI_Status *arg_Status(object status):
28    if status is None: return MPI_STATUS_IGNORE
29    return &((<Status>status).ob_mpi)
30
31#------------------------------------------------------------------------------
32# Datatype
33
34cdef inline int builtin_Datatype(MPI_Datatype ob):
35    cdef int ni = 0, na = 0, nt = 0, combiner = MPI_UNDEFINED
36    if ob == MPI_DATATYPE_NULL: return 1
37    cdef int ierr = MPI_Type_get_envelope(ob, &ni, &na, &nt, &combiner)
38    if ierr != MPI_SUCCESS: return 0 # XXX
39    return (combiner == MPI_COMBINER_NAMED       or
40            combiner == MPI_COMBINER_F90_INTEGER or
41            combiner == MPI_COMBINER_F90_REAL    or
42            combiner == MPI_COMBINER_F90_COMPLEX)
43
44cdef inline Datatype new_Datatype(MPI_Datatype ob):
45    cdef Datatype datatype = Datatype.__new__(Datatype)
46    datatype.ob_mpi = ob
47    return datatype
48
49cdef inline Datatype ref_Datatype(MPI_Datatype ob):
50    cdef Datatype datatype = Datatype.__new__(Datatype)
51    datatype.ob_mpi = ob
52    return datatype
53
54cdef inline int del_Datatype(MPI_Datatype* ob):
55    if ob    == NULL                        : return 0
56    if ob[0] == MPI_DATATYPE_NULL           : return 0
57    if ob[0] == MPI_UB                      : return 0
58    if ob[0] == MPI_LB                      : return 0
59    if ob[0] == MPI_PACKED                  : return 0
60    if ob[0] == MPI_BYTE                    : return 0
61    if ob[0] == MPI_AINT                    : return 0
62    if ob[0] == MPI_OFFSET                  : return 0
63    if ob[0] == MPI_COUNT                   : return 0
64    if ob[0] == MPI_CHAR                    : return 0
65    if ob[0] == MPI_WCHAR                   : return 0
66    if ob[0] == MPI_SIGNED_CHAR             : return 0
67    if ob[0] == MPI_SHORT                   : return 0
68    if ob[0] == MPI_INT                     : return 0
69    if ob[0] == MPI_LONG                    : return 0
70    if ob[0] == MPI_LONG_LONG               : return 0
71    if ob[0] == MPI_UNSIGNED_CHAR           : return 0
72    if ob[0] == MPI_UNSIGNED_SHORT          : return 0
73    if ob[0] == MPI_UNSIGNED                : return 0
74    if ob[0] == MPI_UNSIGNED_LONG           : return 0
75    if ob[0] == MPI_UNSIGNED_LONG_LONG      : return 0
76    if ob[0] == MPI_FLOAT                   : return 0
77    if ob[0] == MPI_DOUBLE                  : return 0
78    if ob[0] == MPI_LONG_DOUBLE             : return 0
79    if ob[0] == MPI_C_BOOL                  : return 0
80    if ob[0] == MPI_INT8_T                  : return 0
81    if ob[0] == MPI_INT16_T                 : return 0
82    if ob[0] == MPI_INT32_T                 : return 0
83    if ob[0] == MPI_INT64_T                 : return 0
84    if ob[0] == MPI_UINT8_T                 : return 0
85    if ob[0] == MPI_UINT16_T                : return 0
86    if ob[0] == MPI_UINT32_T                : return 0
87    if ob[0] == MPI_UINT64_T                : return 0
88    if ob[0] == MPI_C_COMPLEX               : return 0
89    if ob[0] == MPI_C_FLOAT_COMPLEX         : return 0
90    if ob[0] == MPI_C_DOUBLE_COMPLEX        : return 0
91    if ob[0] == MPI_C_LONG_DOUBLE_COMPLEX   : return 0
92    if ob[0] == MPI_CXX_BOOL                : return 0
93    if ob[0] == MPI_CXX_FLOAT_COMPLEX       : return 0
94    if ob[0] == MPI_CXX_DOUBLE_COMPLEX      : return 0
95    if ob[0] == MPI_CXX_LONG_DOUBLE_COMPLEX : return 0
96    if ob[0] == MPI_SHORT_INT               : return 0
97    if ob[0] == MPI_2INT                    : return 0
98    if ob[0] == MPI_LONG_INT                : return 0
99    if ob[0] == MPI_FLOAT_INT               : return 0
100    if ob[0] == MPI_DOUBLE_INT              : return 0
101    if ob[0] == MPI_LONG_DOUBLE_INT         : return 0
102    if ob[0] == MPI_CHARACTER               : return 0
103    if ob[0] == MPI_LOGICAL                 : return 0
104    if ob[0] == MPI_INTEGER                 : return 0
105    if ob[0] == MPI_REAL                    : return 0
106    if ob[0] == MPI_DOUBLE_PRECISION        : return 0
107    if ob[0] == MPI_COMPLEX                 : return 0
108    if ob[0] == MPI_DOUBLE_COMPLEX          : return 0
109    if ob[0] == MPI_LOGICAL1                : return 0
110    if ob[0] == MPI_LOGICAL2                : return 0
111    if ob[0] == MPI_LOGICAL4                : return 0
112    if ob[0] == MPI_LOGICAL8                : return 0
113    if ob[0] == MPI_INTEGER1                : return 0
114    if ob[0] == MPI_INTEGER2                : return 0
115    if ob[0] == MPI_INTEGER4                : return 0
116    if ob[0] == MPI_INTEGER8                : return 0
117    if ob[0] == MPI_INTEGER16               : return 0
118    if ob[0] == MPI_REAL2                   : return 0
119    if ob[0] == MPI_REAL4                   : return 0
120    if ob[0] == MPI_REAL8                   : return 0
121    if ob[0] == MPI_REAL16                  : return 0
122    if ob[0] == MPI_COMPLEX4                : return 0
123    if ob[0] == MPI_COMPLEX8                : return 0
124    if ob[0] == MPI_COMPLEX16               : return 0
125    if ob[0] == MPI_COMPLEX32               : return 0
126    #
127    if not mpi_active(): return 0
128    if builtin_Datatype(ob[0]): return 0
129    #
130    return MPI_Type_free(ob)
131
132#------------------------------------------------------------------------------
133# Request
134
135include "reqimpl.pxi"
136
137cdef inline Request new_Request(MPI_Request ob):
138    cdef Request request = Request.__new__(Request)
139    request.ob_mpi = ob
140    return request
141
142cdef inline int del_Request(MPI_Request* ob):
143    if ob    == NULL             : return 0
144    if ob[0] == MPI_REQUEST_NULL : return 0
145    #
146    if not mpi_active(): return 0
147    return MPI_Request_free(ob)
148
149#------------------------------------------------------------------------------
150# Message
151
152cdef inline Message new_Message(MPI_Message ob):
153    cdef Message message = Message.__new__(Message)
154    message.ob_mpi = ob
155    return message
156
157cdef inline int del_Message(MPI_Message* ob):
158    if ob    == NULL                : return 0
159    if ob[0] == MPI_MESSAGE_NULL    : return 0
160    if ob[0] == MPI_MESSAGE_NO_PROC : return 0
161    #
162    if not mpi_active(): return 0
163    # ob[0] = MPI_MESSAGE_NULL
164    return 0
165
166#------------------------------------------------------------------------------
167# Op
168
169include "opimpl.pxi"
170
171cdef inline Op new_Op(MPI_Op ob):
172    cdef Op op = Op.__new__(Op)
173    op.ob_mpi = ob
174    if   ob == MPI_OP_NULL : op.ob_func = NULL
175    elif ob == MPI_MAX     : op.ob_func = _op_MAX
176    elif ob == MPI_MIN     : op.ob_func = _op_MIN
177    elif ob == MPI_SUM     : op.ob_func = _op_SUM
178    elif ob == MPI_PROD    : op.ob_func = _op_PROD
179    elif ob == MPI_LAND    : op.ob_func = _op_LAND
180    elif ob == MPI_BAND    : op.ob_func = _op_BAND
181    elif ob == MPI_LOR     : op.ob_func = _op_LOR
182    elif ob == MPI_BOR     : op.ob_func = _op_BOR
183    elif ob == MPI_LXOR    : op.ob_func = _op_LXOR
184    elif ob == MPI_BXOR    : op.ob_func = _op_BXOR
185    elif ob == MPI_MAXLOC  : op.ob_func = _op_MAXLOC
186    elif ob == MPI_MINLOC  : op.ob_func = _op_MINLOC
187    elif ob == MPI_REPLACE : op.ob_func = _op_REPLACE
188    elif ob == MPI_NO_OP   : op.ob_func = _op_NO_OP
189    return op
190
191cdef inline int del_Op(MPI_Op* ob):
192    if ob    == NULL        : return 0
193    if ob[0] == MPI_OP_NULL : return 0
194    if ob[0] == MPI_MAX     : return 0
195    if ob[0] == MPI_MIN     : return 0
196    if ob[0] == MPI_SUM     : return 0
197    if ob[0] == MPI_PROD    : return 0
198    if ob[0] == MPI_LAND    : return 0
199    if ob[0] == MPI_BAND    : return 0
200    if ob[0] == MPI_LOR     : return 0
201    if ob[0] == MPI_BOR     : return 0
202    if ob[0] == MPI_LXOR    : return 0
203    if ob[0] == MPI_BXOR    : return 0
204    if ob[0] == MPI_MAXLOC  : return 0
205    if ob[0] == MPI_MINLOC  : return 0
206    if ob[0] == MPI_REPLACE : return 0
207    if ob[0] == MPI_NO_OP   : return 0
208    #
209    if not mpi_active(): return 0
210    return MPI_Op_free(ob)
211
212#------------------------------------------------------------------------------
213# Info
214
215cdef inline Info new_Info(MPI_Info ob):
216    cdef Info info = Info.__new__(Info)
217    info.ob_mpi = ob
218    return info
219
220cdef inline int del_Info(MPI_Info* ob):
221    if ob    == NULL          : return 0
222    if ob[0] == MPI_INFO_NULL : return 0
223    if ob[0] == MPI_INFO_ENV  : return 0
224    #
225    if not mpi_active(): return 0
226    return MPI_Info_free(ob)
227
228cdef inline MPI_Info arg_Info(object info):
229    if info is None: return MPI_INFO_NULL
230    return (<Info>info).ob_mpi
231
232#------------------------------------------------------------------------------
233# Group
234
235cdef inline Group new_Group(MPI_Group ob):
236    cdef Group group = Group.__new__(Group)
237    group.ob_mpi = ob
238    return group
239
240
241cdef inline int del_Group(MPI_Group* ob):
242    if ob    == NULL            : return 0
243    if ob[0] == MPI_GROUP_NULL  : return 0
244    if ob[0] == MPI_GROUP_EMPTY : return 0
245    #
246    if not mpi_active(): return 0
247    return MPI_Group_free(ob)
248
249#------------------------------------------------------------------------------
250# Comm
251
252include "commimpl.pxi"
253
254cdef inline Comm new_Comm(MPI_Comm ob):
255    cdef Comm comm = Comm.__new__(Comm)
256    comm.ob_mpi = ob
257    return comm
258
259cdef inline Intracomm new_Intracomm(MPI_Comm ob):
260    cdef Intracomm comm = Intracomm.__new__(Intracomm)
261    comm.ob_mpi = ob
262    return comm
263
264cdef inline Intercomm new_Intercomm(MPI_Comm ob):
265    cdef Intercomm comm = Intercomm.__new__(Intercomm)
266    comm.ob_mpi = ob
267    return comm
268
269cdef inline int del_Comm(MPI_Comm* ob):
270    if ob    == NULL           : return 0
271    if ob[0] == MPI_COMM_NULL  : return 0
272    if ob[0] == MPI_COMM_SELF  : return 0
273    if ob[0] == MPI_COMM_WORLD : return 0
274    #
275    if not mpi_active(): return 0
276    return MPI_Comm_free(ob)
277
278#------------------------------------------------------------------------------
279# Win
280
281include "winimpl.pxi"
282
283cdef inline Win new_Win(MPI_Win ob):
284    cdef Win win = Win.__new__(Win)
285    win.ob_mpi = ob
286    return win
287
288cdef inline int del_Win(MPI_Win* ob):
289    if ob    == NULL         : return 0
290    if ob[0] == MPI_WIN_NULL : return 0
291    #
292    if not mpi_active(): return 0
293    return MPI_Win_free(ob)
294
295#------------------------------------------------------------------------------
296# File
297
298include "drepimpl.pxi"
299
300cdef inline File new_File(MPI_File ob):
301    cdef File file = File.__new__(File)
302    file.ob_mpi = ob
303    return file
304
305cdef inline int del_File(MPI_File* ob):
306    if ob    == NULL          : return 0
307    if ob[0] == MPI_FILE_NULL : return 0
308    #
309    if not mpi_active(): return 0
310    return MPI_File_close(ob)
311
312#------------------------------------------------------------------------------
313# Errhandler
314
315cdef inline Errhandler new_Errhandler(MPI_Errhandler ob):
316    cdef Errhandler errhandler = Errhandler.__new__(Errhandler)
317    errhandler.ob_mpi = ob
318    return errhandler
319
320cdef inline int del_Errhandler(MPI_Errhandler* ob):
321    if ob    == NULL                 : return 0
322    if ob[0] == MPI_ERRHANDLER_NULL  : return 0
323    if ob[0] == MPI_ERRORS_RETURN    : return 0
324    if ob[0] == MPI_ERRORS_ARE_FATAL : return 0
325    #
326    if not mpi_active(): return 0
327    return MPI_Errhandler_free(ob)
328
329#------------------------------------------------------------------------------
330