Skip to content

Mpi

mpi

t_bool: IntegerType = IntegerType(1, Signedness.SIGNLESS) module-attribute

AnyNumericType = AnyFloat | IntegerType module-attribute

VectorWrappable = RequestType | StatusType | DataType module-attribute

VectorWrappableConstr = base(RequestType) | base(StatusType) | base(DataType) module-attribute

MPI = Dialect('mpi', [CommSizeOp, IsendOp, IrecvOp, TestOp, RecvOp, SendOp, ReduceOp, AllreduceOp, BcastOp, WaitOp, WaitallOp, GetStatusFieldOp, InitOp, FinalizeOp, CommRankOp, UnwrapMemRefOp, GetDtypeOp, AllocateTypeOp, VectorGetOp, NullRequestOp, GatherOp], [OperationType, RequestType, StatusType, DataType, VectorType]) module-attribute

OperationType dataclass

Bases: ParametrizedAttribute, TypeAttribute

This type represents the MPI_Op type.

They are used by the reduction MPI functions

Source code in xdsl/dialects/mpi.py
47
48
49
50
51
52
53
54
55
56
57
@irdl_attr_definition
class OperationType(ParametrizedAttribute, TypeAttribute):
    """
    This type represents the MPI_Op type.

    They are used by the reduction MPI functions
    """

    name = "mpi.operation"

    op_str: StringAttr

name = 'mpi.operation' class-attribute instance-attribute

op_str: StringAttr instance-attribute

MpiOp

A collection of MPI_Op types used for

Source code in xdsl/dialects/mpi.py
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
class MpiOp:
    """
    A collection of MPI_Op types used for
    """

    MPI_MAX = OperationType(StringAttr("MPI_MAX"))
    MPI_MIN = OperationType(StringAttr("MPI_MIN"))
    MPI_SUM = OperationType(StringAttr("MPI_SUM"))
    MPI_PROD = OperationType(StringAttr("MPI_PROD"))
    MPI_LAND = OperationType(StringAttr("MPI_LAND"))
    MPI_BAND = OperationType(StringAttr("MPI_BAND"))
    MPI_LOR = OperationType(StringAttr("MPI_LOR"))
    MPI_BOR = OperationType(StringAttr("MPI_BOR"))
    MPI_LXOR = OperationType(StringAttr("MPI_LXOR"))
    MPI_BXOR = OperationType(StringAttr("MPI_BXOR"))
    MPI_MINLOC = OperationType(StringAttr("MPI_MINLOC"))
    MPI_MAXLOC = OperationType(StringAttr("MPI_MAXLOC"))
    MPI_REPLACE = OperationType(StringAttr("MPI_REPLACE"))
    MPI_NO_OP = OperationType(StringAttr("MPI_NO_OP"))

MPI_MAX = OperationType(StringAttr('MPI_MAX')) class-attribute instance-attribute

MPI_MIN = OperationType(StringAttr('MPI_MIN')) class-attribute instance-attribute

MPI_SUM = OperationType(StringAttr('MPI_SUM')) class-attribute instance-attribute

MPI_PROD = OperationType(StringAttr('MPI_PROD')) class-attribute instance-attribute

MPI_LAND = OperationType(StringAttr('MPI_LAND')) class-attribute instance-attribute

MPI_BAND = OperationType(StringAttr('MPI_BAND')) class-attribute instance-attribute

MPI_LOR = OperationType(StringAttr('MPI_LOR')) class-attribute instance-attribute

MPI_BOR = OperationType(StringAttr('MPI_BOR')) class-attribute instance-attribute

MPI_LXOR = OperationType(StringAttr('MPI_LXOR')) class-attribute instance-attribute

MPI_BXOR = OperationType(StringAttr('MPI_BXOR')) class-attribute instance-attribute

MPI_MINLOC = OperationType(StringAttr('MPI_MINLOC')) class-attribute instance-attribute

MPI_MAXLOC = OperationType(StringAttr('MPI_MAXLOC')) class-attribute instance-attribute

MPI_REPLACE = OperationType(StringAttr('MPI_REPLACE')) class-attribute instance-attribute

MPI_NO_OP = OperationType(StringAttr('MPI_NO_OP')) class-attribute instance-attribute

RequestType dataclass

Bases: ParametrizedAttribute, TypeAttribute

This type represents the MPI_Request type.

They are used by the asynchronous MPI functions

Source code in xdsl/dialects/mpi.py
81
82
83
84
85
86
87
88
89
@irdl_attr_definition
class RequestType(ParametrizedAttribute, TypeAttribute):
    """
    This type represents the MPI_Request type.

    They are used by the asynchronous MPI functions
    """

    name = "mpi.request"

name = 'mpi.request' class-attribute instance-attribute

StatusType dataclass

Bases: ParametrizedAttribute, TypeAttribute

This type represents the MPI_Status type.

It's a struct containing status information for requests.

Source code in xdsl/dialects/mpi.py
 92
 93
 94
 95
 96
 97
 98
 99
100
@irdl_attr_definition
class StatusType(ParametrizedAttribute, TypeAttribute):
    """
    This type represents the MPI_Status type.

    It's a struct containing status information for requests.
    """

    name = "mpi.status"

name = 'mpi.status' class-attribute instance-attribute

DataType dataclass

Bases: ParametrizedAttribute, TypeAttribute

This type represents MPI_Datatype

Source code in xdsl/dialects/mpi.py
103
104
105
106
107
108
109
@irdl_attr_definition
class DataType(ParametrizedAttribute, TypeAttribute):
    """
    This type represents MPI_Datatype
    """

    name = "mpi.datatype"

name = 'mpi.datatype' class-attribute instance-attribute

VectorType dataclass

Bases: ParametrizedAttribute, TypeAttribute, Generic[_VectorT]

This type holds multiple MPI types

Source code in xdsl/dialects/mpi.py
117
118
119
120
121
122
123
124
@irdl_attr_definition
class VectorType(ParametrizedAttribute, TypeAttribute, Generic[_VectorT]):
    """
    This type holds multiple MPI types
    """

    name = "mpi.vector"
    wrapped_type: _VectorT

name = 'mpi.vector' class-attribute instance-attribute

wrapped_type: _VectorT instance-attribute

StatusTypeField

Bases: Enum

This enum lists all fields in the MPI_Status struct

Source code in xdsl/dialects/mpi.py
127
128
129
130
131
132
133
134
class StatusTypeField(Enum):
    """
    This enum lists all fields in the MPI_Status struct
    """

    MPI_SOURCE = "MPI_SOURCE"
    MPI_TAG = "MPI_TAG"
    MPI_ERROR = "MPI_ERROR"

MPI_SOURCE = 'MPI_SOURCE' class-attribute instance-attribute

MPI_TAG = 'MPI_TAG' class-attribute instance-attribute

MPI_ERROR = 'MPI_ERROR' class-attribute instance-attribute

MPIBaseOp dataclass

Bases: IRDLOperation, ABC

Base class for MPI Operations

Source code in xdsl/dialects/mpi.py
137
138
139
140
141
142
class MPIBaseOp(IRDLOperation, ABC):
    """
    Base class for MPI Operations
    """

    pass

ReduceOp

Bases: MPIBaseOp

This wraps the MPI_Reduce function (blocking reduction)

See external documentation.

The MPI_Reduce Function Docs:

int MPI_Reduce(const void sendbuf, void recvbuf, int count, MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm)

sendbuf: address of send buffer (choice)
recvbuf: address of receive buffer (choice)
count: number of elements in send buffer (non-negative integer)
datatype: data type of elements of send buffer (handle)
op: reduce operation (handle)
root: rank of root process (integer)
comm: communicator (handle)
Our Abstraction:
- We omit the possibility of using multiple communicators, defaulting
  to MPI_COMM_WORLD
Source code in xdsl/dialects/mpi.py
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
@irdl_op_definition
class ReduceOp(MPIBaseOp):
    """
    This wraps the MPI_Reduce function (blocking reduction)

    See external [documentation](https://www.mpich.org/static/docs/v4.1/www3/MPI_Reduce.html).

    ## The MPI_Reduce Function Docs:

    int MPI_Reduce(const void *sendbuf, void *recvbuf, int count,
               MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm)

        sendbuf: address of send buffer (choice)
        recvbuf: address of receive buffer (choice)
        count: number of elements in send buffer (non-negative integer)
        datatype: data type of elements of send buffer (handle)
        op: reduce operation (handle)
        root: rank of root process (integer)
        comm: communicator (handle)

    ## Our Abstraction:

        - We omit the possibility of using multiple communicators, defaulting
          to MPI_COMM_WORLD
    """

    name = "mpi.reduce"

    send_buffer = operand_def(Attribute)
    recv_buffer = operand_def(Attribute)
    count = operand_def(i32)
    datatype = operand_def(DataType)
    operationtype = attr_def(OperationType)
    root = operand_def(i32)

    def __init__(
        self,
        send_buffer: SSAValue | Operation,
        recv_buffer: SSAValue | Operation,
        count: SSAValue | Operation,
        datatype: SSAValue | Operation,
        operationtype: OperationType,
        root: SSAValue | Operation,
    ):
        return super().__init__(
            operands=[send_buffer, recv_buffer, count, datatype, root],
            attributes={"operationtype": operationtype},
            result_types=[],
        )

name = 'mpi.reduce' class-attribute instance-attribute

send_buffer = operand_def(Attribute) class-attribute instance-attribute

recv_buffer = operand_def(Attribute) class-attribute instance-attribute

count = operand_def(i32) class-attribute instance-attribute

datatype = operand_def(DataType) class-attribute instance-attribute

operationtype = attr_def(OperationType) class-attribute instance-attribute

root = operand_def(i32) class-attribute instance-attribute

__init__(send_buffer: SSAValue | Operation, recv_buffer: SSAValue | Operation, count: SSAValue | Operation, datatype: SSAValue | Operation, operationtype: OperationType, root: SSAValue | Operation)

Source code in xdsl/dialects/mpi.py
180
181
182
183
184
185
186
187
188
189
190
191
192
193
def __init__(
    self,
    send_buffer: SSAValue | Operation,
    recv_buffer: SSAValue | Operation,
    count: SSAValue | Operation,
    datatype: SSAValue | Operation,
    operationtype: OperationType,
    root: SSAValue | Operation,
):
    return super().__init__(
        operands=[send_buffer, recv_buffer, count, datatype, root],
        attributes={"operationtype": operationtype},
        result_types=[],
    )

AllreduceOp

Bases: MPIBaseOp

This wraps the MPI_Allreduce function (blocking all reduction)

See external documentation.

The MPI_Allreduce Function Docs:

int MPI_Allreduce(const void sendbuf, void recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)

sendbuf: address of send buffer (choice)
recvbuf: address of receive buffer (choice)
count: number of elements in send buffer (non-negative integer)
datatype: data type of elements of send buffer (handle)
op: reduce operation (handle)
comm: communicator (handle)
Our Abstraction:
- We omit the possibility of using multiple communicators, defaulting
  to MPI_COMM_WORLD
Source code in xdsl/dialects/mpi.py
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
@irdl_op_definition
class AllreduceOp(MPIBaseOp):
    """
    This wraps the MPI_Allreduce function (blocking all reduction)

    See external [documentation](https://www.mpich.org/static/docs/v4.1/www3/MPI_Allreduce.html).

    ## The MPI_Allreduce Function Docs:

    int MPI_Allreduce(const void *sendbuf, void *recvbuf, int count,
                  MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)

        sendbuf: address of send buffer (choice)
        recvbuf: address of receive buffer (choice)
        count: number of elements in send buffer (non-negative integer)
        datatype: data type of elements of send buffer (handle)
        op: reduce operation (handle)
        comm: communicator (handle)

    ## Our Abstraction:

        - We omit the possibility of using multiple communicators, defaulting
          to MPI_COMM_WORLD
    """

    name = "mpi.allreduce"

    send_buffer = opt_operand_def(Attribute)
    recv_buffer = operand_def(Attribute)
    count = operand_def(i32)
    datatype = operand_def(DataType)
    operationtype = attr_def(OperationType)

    def __init__(
        self,
        send_buffer: SSAValue | Operation | None,
        recv_buffer: SSAValue | Operation,
        count: SSAValue | Operation,
        datatype: SSAValue | Operation,
        operationtype: OperationType,
    ):
        operands_to_add: Sequence[
            SSAValue | Operation | Sequence[SSAValue | Operation]
        ] = []

        if send_buffer is None:
            operands_to_add = [[], recv_buffer, count, datatype]
        else:
            operands_to_add = [[send_buffer], recv_buffer, count, datatype]

        return super().__init__(
            operands=operands_to_add,
            attributes={"operationtype": operationtype},
            result_types=[],
        )

name = 'mpi.allreduce' class-attribute instance-attribute

send_buffer = opt_operand_def(Attribute) class-attribute instance-attribute

recv_buffer = operand_def(Attribute) class-attribute instance-attribute

count = operand_def(i32) class-attribute instance-attribute

datatype = operand_def(DataType) class-attribute instance-attribute

operationtype = attr_def(OperationType) class-attribute instance-attribute

__init__(send_buffer: SSAValue | Operation | None, recv_buffer: SSAValue | Operation, count: SSAValue | Operation, datatype: SSAValue | Operation, operationtype: OperationType)

Source code in xdsl/dialects/mpi.py
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
def __init__(
    self,
    send_buffer: SSAValue | Operation | None,
    recv_buffer: SSAValue | Operation,
    count: SSAValue | Operation,
    datatype: SSAValue | Operation,
    operationtype: OperationType,
):
    operands_to_add: Sequence[
        SSAValue | Operation | Sequence[SSAValue | Operation]
    ] = []

    if send_buffer is None:
        operands_to_add = [[], recv_buffer, count, datatype]
    else:
        operands_to_add = [[send_buffer], recv_buffer, count, datatype]

    return super().__init__(
        operands=operands_to_add,
        attributes={"operationtype": operationtype},
        result_types=[],
    )

BcastOp

Bases: MPIBaseOp

This wraps the MPI_Bcast function (blocking broadcast)

See external documentation.

The MPI_Bcast Function Docs:

int MPI_Bcast(void *buffer, int count, MPI_Datatype datatype, int root, MPI_Comm comm)

buffer: starting address of buffer (choice)
count: number of elements in send buffer (non-negative integer)
datatype: data type of elements of send buffer (handle)
root: rank of broadcast root (integer)
comm: communicator (handle)
Our Abstraction:
- We omit the possibility of using multiple communicators, defaulting
  to MPI_COMM_WORLD
Source code in xdsl/dialects/mpi.py
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
@irdl_op_definition
class BcastOp(MPIBaseOp):
    """
    This wraps the MPI_Bcast function (blocking broadcast)

    See external [documentation](https://www.mpich.org/static/docs/v4.1/www3/MPI_Bcast.html).

    ## The MPI_Bcast Function Docs:

    int MPI_Bcast(void *buffer, int count, MPI_Datatype datatype, int root,
              MPI_Comm comm)

        buffer: starting address of buffer (choice)
        count: number of elements in send buffer (non-negative integer)
        datatype: data type of elements of send buffer (handle)
        root: rank of broadcast root (integer)
        comm: communicator (handle)

    ## Our Abstraction:

        - We omit the possibility of using multiple communicators, defaulting
          to MPI_COMM_WORLD
    """

    name = "mpi.bcast"

    buffer = operand_def(Attribute)
    count = operand_def(i32)
    datatype = operand_def(DataType)
    root = operand_def(i32)

    def __init__(
        self,
        buffer: SSAValue | Operation,
        count: SSAValue | Operation,
        datatype: SSAValue | Operation,
        root: SSAValue | Operation,
    ):
        return super().__init__(
            operands=[buffer, count, datatype, root],
            result_types=[],
        )

name = 'mpi.bcast' class-attribute instance-attribute

buffer = operand_def(Attribute) class-attribute instance-attribute

count = operand_def(i32) class-attribute instance-attribute

datatype = operand_def(DataType) class-attribute instance-attribute

root = operand_def(i32) class-attribute instance-attribute

__init__(buffer: SSAValue | Operation, count: SSAValue | Operation, datatype: SSAValue | Operation, root: SSAValue | Operation)

Source code in xdsl/dialects/mpi.py
284
285
286
287
288
289
290
291
292
293
294
def __init__(
    self,
    buffer: SSAValue | Operation,
    count: SSAValue | Operation,
    datatype: SSAValue | Operation,
    root: SSAValue | Operation,
):
    return super().__init__(
        operands=[buffer, count, datatype, root],
        result_types=[],
    )

IsendOp

Bases: MPIBaseOp

This wraps the MPI_Isend function (nonblocking send)

See external documentation.

The MPI_Isend Function Docs:

int MPI_Isend(const void buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request request)

- buf: Initial address of send buffer (choice).
- count: Number of elements in send buffer (integer).
- datatype: Datatype of each send buffer element (handle).
- dest: Rank of destination (integer).
- tag: Message tag (integer).
- comm: Communicator (handle).
Our Abstraction:
- We omit the possibility of using multiple communicators, defaulting
  to MPI_COMM_WORLD
Source code in xdsl/dialects/mpi.py
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
@irdl_op_definition
class IsendOp(MPIBaseOp):
    """
    This wraps the MPI_Isend function (nonblocking send)

    See external [documentation](https://www.mpich.org/static/docs/v4.1/www3/MPI_Isend.html).

    ## The MPI_Isend Function Docs:

    int MPI_Isend(const void *buf, int count, MPI_Datatype datatype, int dest,
         int tag, MPI_Comm comm, MPI_Request *request)

        - buf: Initial address of send buffer (choice).
        - count: Number of elements in send buffer (integer).
        - datatype: Datatype of each send buffer element (handle).
        - dest: Rank of destination (integer).
        - tag: Message tag (integer).
        - comm: Communicator (handle).

    ## Our Abstraction:

        - We omit the possibility of using multiple communicators, defaulting
          to MPI_COMM_WORLD
    """

    name = "mpi.isend"

    buffer = operand_def(Attribute)
    count = operand_def(i32)
    datatype = operand_def(DataType)
    dest = operand_def(i32)
    tag = operand_def(i32)
    request = operand_def(RequestType)

    def __init__(
        self,
        buffer: SSAValue | Operation,
        count: SSAValue | Operation,
        datatype: SSAValue | Operation,
        dest: SSAValue | Operation,
        tag: SSAValue | Operation,
        request: SSAValue | Operation,
    ):
        return super().__init__(
            operands=[buffer, count, datatype, dest, tag, request],
            result_types=[],
        )

name = 'mpi.isend' class-attribute instance-attribute

buffer = operand_def(Attribute) class-attribute instance-attribute

count = operand_def(i32) class-attribute instance-attribute

datatype = operand_def(DataType) class-attribute instance-attribute

dest = operand_def(i32) class-attribute instance-attribute

tag = operand_def(i32) class-attribute instance-attribute

request = operand_def(RequestType) class-attribute instance-attribute

__init__(buffer: SSAValue | Operation, count: SSAValue | Operation, datatype: SSAValue | Operation, dest: SSAValue | Operation, tag: SSAValue | Operation, request: SSAValue | Operation)

Source code in xdsl/dialects/mpi.py
331
332
333
334
335
336
337
338
339
340
341
342
343
def __init__(
    self,
    buffer: SSAValue | Operation,
    count: SSAValue | Operation,
    datatype: SSAValue | Operation,
    dest: SSAValue | Operation,
    tag: SSAValue | Operation,
    request: SSAValue | Operation,
):
    return super().__init__(
        operands=[buffer, count, datatype, dest, tag, request],
        result_types=[],
    )

SendOp

Bases: MPIBaseOp

This wraps the MPI_Send function (blocking send)

See external documentation.

The MPI_Send Function Docs:

int MPI_Send(const void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm)

- buf: Initial address of send buffer (choice).
- count: Number of elements in send buffer (non-negative integer).
- datatype: Datatype of each send buffer element (handle).
- dest: Rank of destination (integer).
- tag: Message tag (integer).
- comm: Communicator (handle).
Our Abstraction:
- We omit the possibility of using multiple communicators, defaulting
  to MPI_COMM_WORLD
Source code in xdsl/dialects/mpi.py
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
@irdl_op_definition
class SendOp(MPIBaseOp):
    """
    This wraps the MPI_Send function (blocking send)

    See external [documentation](https://www.mpich.org/static/docs/v4.1/www3/MPI_Send.html).

    ## The MPI_Send Function Docs:

    int MPI_Send(const void *buf, int count, MPI_Datatype datatype, int dest,
             int tag, MPI_Comm comm)

        - buf: Initial address of send buffer (choice).
        - count: Number of elements in send buffer (non-negative integer).
        - datatype: Datatype of each send buffer element (handle).
        - dest: Rank of destination (integer).
        - tag: Message tag (integer).
        - comm: Communicator (handle).

    ## Our Abstraction:

        - We omit the possibility of using multiple communicators, defaulting
          to MPI_COMM_WORLD
    """

    name = "mpi.send"

    buffer = operand_def(Attribute)
    count = operand_def(i32)
    datatype = operand_def(DataType)
    dest = operand_def(i32)
    tag = operand_def(i32)

    def __init__(
        self,
        buffer: SSAValue | Operation,
        count: SSAValue | Operation,
        datatype: SSAValue | Operation,
        dest: SSAValue | Operation,
        tag: SSAValue | Operation,
    ):
        return super().__init__(
            operands=[buffer, count, datatype, dest, tag], result_types=[]
        )

name = 'mpi.send' class-attribute instance-attribute

buffer = operand_def(Attribute) class-attribute instance-attribute

count = operand_def(i32) class-attribute instance-attribute

datatype = operand_def(DataType) class-attribute instance-attribute

dest = operand_def(i32) class-attribute instance-attribute

tag = operand_def(i32) class-attribute instance-attribute

__init__(buffer: SSAValue | Operation, count: SSAValue | Operation, datatype: SSAValue | Operation, dest: SSAValue | Operation, tag: SSAValue | Operation)

Source code in xdsl/dialects/mpi.py
379
380
381
382
383
384
385
386
387
388
389
def __init__(
    self,
    buffer: SSAValue | Operation,
    count: SSAValue | Operation,
    datatype: SSAValue | Operation,
    dest: SSAValue | Operation,
    tag: SSAValue | Operation,
):
    return super().__init__(
        operands=[buffer, count, datatype, dest, tag], result_types=[]
    )

IrecvOp

Bases: MPIBaseOp

This wraps the MPI_Irecv function (nonblocking receive).

See external documentation.

The MPI_Irecv Function Docs:

int MPI_Irecv(void buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Request request)

- buf: Initial address of receive buffer (choice).
- count: Number of elements in receive buffer (integer).
- datatype: Datatype of each receive buffer element (handle).
- source: Rank of source (integer).
- tag: Message tag (integer).
- comm: Communicator (handle).
- request: Communication request (handle).
Our Abstractions:
- We omit the possibility of using multiple communicators, defaulting
  to MPI_COMM_WORLD
Source code in xdsl/dialects/mpi.py
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
@irdl_op_definition
class IrecvOp(MPIBaseOp):
    """
    This wraps the MPI_Irecv function (nonblocking receive).

    See external [documentation](https://www.mpich.org/static/docs/v4.1/www3/MPI_Irecv.html).

    ## The MPI_Irecv Function Docs:

    int MPI_Irecv(void *buf, int count, MPI_Datatype datatype,
            int source, int tag, MPI_Comm comm, MPI_Request *request)

        - buf: Initial address of receive buffer (choice).
        - count: Number of elements in receive buffer (integer).
        - datatype: Datatype of each receive buffer element (handle).
        - source: Rank of source (integer).
        - tag: Message tag (integer).
        - comm: Communicator (handle).
        - request: Communication request (handle).

    ## Our Abstractions:

        - We omit the possibility of using multiple communicators, defaulting
          to MPI_COMM_WORLD
    """

    name = "mpi.irecv"

    buffer = operand_def(Attribute)
    count = operand_def(i32)
    datatype = operand_def(DataType)
    source = operand_def(i32)
    tag = operand_def(i32)
    request = operand_def(RequestType)

    def __init__(
        self,
        buffer: SSAValue | Operation,
        count: SSAValue | Operation,
        datatype: SSAValue | Operation,
        source: SSAValue | Operation,
        tag: SSAValue | Operation,
        request: SSAValue | Operation,
    ):
        return super().__init__(
            operands=[buffer, count, datatype, source, tag, request],
            result_types=[],
        )

name = 'mpi.irecv' class-attribute instance-attribute

buffer = operand_def(Attribute) class-attribute instance-attribute

count = operand_def(i32) class-attribute instance-attribute

datatype = operand_def(DataType) class-attribute instance-attribute

source = operand_def(i32) class-attribute instance-attribute

tag = operand_def(i32) class-attribute instance-attribute

request = operand_def(RequestType) class-attribute instance-attribute

__init__(buffer: SSAValue | Operation, count: SSAValue | Operation, datatype: SSAValue | Operation, source: SSAValue | Operation, tag: SSAValue | Operation, request: SSAValue | Operation)

Source code in xdsl/dialects/mpi.py
427
428
429
430
431
432
433
434
435
436
437
438
439
def __init__(
    self,
    buffer: SSAValue | Operation,
    count: SSAValue | Operation,
    datatype: SSAValue | Operation,
    source: SSAValue | Operation,
    tag: SSAValue | Operation,
    request: SSAValue | Operation,
):
    return super().__init__(
        operands=[buffer, count, datatype, source, tag, request],
        result_types=[],
    )

RecvOp

Bases: MPIBaseOp

This wraps the MPI_Recv function (blocking receive).

See external documentation.

The MPI_Recv Function Docs:

int MPI_Recv(void buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status status)

- buf: Initial address of receive buffer (choice).
- count: Number of elements in receive buffer (integer).
- datatype: Datatype of each receive buffer element (handle).
- source: Rank of source (integer).
- tag: Message tag (integer).
- comm: Communicator (handle).
- status: status object (Status).
Our Abstractions:
- We omit the possibility of using multiple communicators, defaulting
  to MPI_COMM_WORLD
Source code in xdsl/dialects/mpi.py
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
@irdl_op_definition
class RecvOp(MPIBaseOp):
    """
    This wraps the MPI_Recv function (blocking receive).

    See external [documentation](https://www.mpich.org/static/docs/v4.1/www3/MPI_Recv.html).

    ## The MPI_Recv Function Docs:

    int MPI_Recv(void *buf, int count, MPI_Datatype datatype, int source, int tag,
             MPI_Comm comm, MPI_Status *status)

        - buf: Initial address of receive buffer (choice).
        - count: Number of elements in receive buffer (integer).
        - datatype: Datatype of each receive buffer element (handle).
        - source: Rank of source (integer).
        - tag: Message tag (integer).
        - comm: Communicator (handle).
        - status: status object (Status).

    ## Our Abstractions:

        - We omit the possibility of using multiple communicators, defaulting
          to MPI_COMM_WORLD
    """

    name = "mpi.recv"

    buffer = operand_def(Attribute)
    count = operand_def(i32)
    datatype = operand_def(DataType)
    source = operand_def(i32)
    tag = operand_def(i32)

    status = opt_result_def(StatusType)

    def __init__(
        self,
        buffer: SSAValue | Operation,
        count: SSAValue | Operation,
        datatype: SSAValue | Operation,
        source: SSAValue | Operation,
        tag: SSAValue | Operation,
        ignore_status: bool = True,
    ):
        return super().__init__(
            operands=[buffer, count, datatype, source, tag],
            result_types=[[]] if ignore_status else [[StatusType()]],
        )

name = 'mpi.recv' class-attribute instance-attribute

buffer = operand_def(Attribute) class-attribute instance-attribute

count = operand_def(i32) class-attribute instance-attribute

datatype = operand_def(DataType) class-attribute instance-attribute

source = operand_def(i32) class-attribute instance-attribute

tag = operand_def(i32) class-attribute instance-attribute

status = opt_result_def(StatusType) class-attribute instance-attribute

__init__(buffer: SSAValue | Operation, count: SSAValue | Operation, datatype: SSAValue | Operation, source: SSAValue | Operation, tag: SSAValue | Operation, ignore_status: bool = True)

Source code in xdsl/dialects/mpi.py
478
479
480
481
482
483
484
485
486
487
488
489
490
def __init__(
    self,
    buffer: SSAValue | Operation,
    count: SSAValue | Operation,
    datatype: SSAValue | Operation,
    source: SSAValue | Operation,
    tag: SSAValue | Operation,
    ignore_status: bool = True,
):
    return super().__init__(
        operands=[buffer, count, datatype, source, tag],
        result_types=[[]] if ignore_status else [[StatusType()]],
    )

TestOp

Bases: MPIBaseOp

Class for wrapping the MPI_Test function (test for completion of request)

See external documentation.

The MPI_Test Function Docs:

int MPI_Test(MPI_Request request, int flag, MPI_Status *status)

- request: Communication request (handle)
- flag: true if operation completed (logical)
- status: Status object (Status)
Source code in xdsl/dialects/mpi.py
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
@irdl_op_definition
class TestOp(MPIBaseOp):
    """
    Class for wrapping the MPI_Test function (test for completion of request)

    See external [documentation](https://www.mpich.org/static/docs/v4.1/www3/MPI_Test.html).

    ## The MPI_Test Function Docs:

    int MPI_Test(MPI_Request *request, int *flag, MPI_Status *status)

        - request: Communication request (handle)
        - flag: true if operation completed (logical)
        - status: Status object (Status)
    """

    name = "mpi.test"

    request = operand_def(RequestType)

    flag = result_def(t_bool)
    status = result_def(StatusType)

    def __init__(self, request: Operand):
        return super().__init__(operands=[request], result_types=[t_bool, StatusType()])

name = 'mpi.test' class-attribute instance-attribute

request = operand_def(RequestType) class-attribute instance-attribute

flag = result_def(t_bool) class-attribute instance-attribute

status = result_def(StatusType) class-attribute instance-attribute

__init__(request: Operand)

Source code in xdsl/dialects/mpi.py
516
517
def __init__(self, request: Operand):
    return super().__init__(operands=[request], result_types=[t_bool, StatusType()])

WaitOp

Bases: MPIBaseOp

Class for wrapping the MPI_Wait function (blocking wait for request)

See external documentation.

The MPI_Test Function Docs:

int MPI_Wait(MPI_Request request, MPI_Status status)

- request: Request (handle)
- status: Status object (Status)
Source code in xdsl/dialects/mpi.py
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
@irdl_op_definition
class WaitOp(MPIBaseOp):
    """
    Class for wrapping the MPI_Wait function (blocking wait for request)

    See external [documentation](https://www.mpich.org/static/docs/v4.1/www3/MPI_Wait.html).

    ## The MPI_Test Function Docs:

    int MPI_Wait(MPI_Request *request, MPI_Status *status)

        - request: Request (handle)
        - status: Status object (Status)
    """

    name = "mpi.wait"

    request = operand_def(RequestType)
    status = opt_result_def(StatusType)

    def __init__(self, request: Operand, ignore_status: bool = True):
        result_types: list[list[Attribute]] = [[StatusType()]]
        if ignore_status:
            result_types = [[]]

        return super().__init__(operands=[request], result_types=result_types)

name = 'mpi.wait' class-attribute instance-attribute

request = operand_def(RequestType) class-attribute instance-attribute

status = opt_result_def(StatusType) class-attribute instance-attribute

__init__(request: Operand, ignore_status: bool = True)

Source code in xdsl/dialects/mpi.py
540
541
542
543
544
545
def __init__(self, request: Operand, ignore_status: bool = True):
    result_types: list[list[Attribute]] = [[StatusType()]]
    if ignore_status:
        result_types = [[]]

    return super().__init__(operands=[request], result_types=result_types)

WaitallOp

Bases: MPIBaseOp

Class for wrapping the MPI_Waitall function (blocking wait for requests)

See external documentation.

The MPI_Test Function Docs:

int MPI_Waitall(int count, MPI_Request array_of_requests[], MPI_Status *array_of_statuses)

- count: Number of handles
- array_of_requests: Request handles
- array_of_statuses: Status objects
Source code in xdsl/dialects/mpi.py
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
@irdl_op_definition
class WaitallOp(MPIBaseOp):
    """
    Class for wrapping the MPI_Waitall function (blocking wait for requests)

    See external [documentation](https://www.mpich.org/static/docs/v4.1/www3/MPI_Waitall.html).

    ## The MPI_Test Function Docs:

    int MPI_Waitall(int count, MPI_Request array_of_requests[],
                MPI_Status *array_of_statuses)

        - count: Number of handles
        - array_of_requests: Request handles
        - array_of_statuses: Status objects
    """

    name = "mpi.waitall"

    requests = operand_def(VectorType[RequestType])
    count = operand_def(i32)
    statuses = opt_result_def(VectorType[StatusType])

    def __init__(self, requests: Operand, count: Operand, ignore_status: bool = True):
        result_types: list[list[Attribute]] = [[VectorType(StatusType())]]
        if ignore_status:
            result_types = [[]]

        return super().__init__(operands=[requests, count], result_types=result_types)

name = 'mpi.waitall' class-attribute instance-attribute

requests = operand_def(VectorType[RequestType]) class-attribute instance-attribute

count = operand_def(i32) class-attribute instance-attribute

statuses = opt_result_def(VectorType[StatusType]) class-attribute instance-attribute

__init__(requests: Operand, count: Operand, ignore_status: bool = True)

Source code in xdsl/dialects/mpi.py
571
572
573
574
575
576
def __init__(self, requests: Operand, count: Operand, ignore_status: bool = True):
    result_types: list[list[Attribute]] = [[VectorType(StatusType())]]
    if ignore_status:
        result_types = [[]]

    return super().__init__(operands=[requests, count], result_types=result_types)

GetStatusFieldOp

Bases: MPIBaseOp

Accessors for the MPI_Status struct

This allows access to the three integer properties in the struct called - MPI_SOURCE - MPI_TAG - MPI_ERROR

All fields are of type int.

Source code in xdsl/dialects/mpi.py
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
@irdl_op_definition
class GetStatusFieldOp(MPIBaseOp):
    """
    Accessors for the MPI_Status struct

    This allows access to the three integer properties in the struct called
        - MPI_SOURCE
        - MPI_TAG
        - MPI_ERROR

    All fields are of type int.
    """

    name = "mpi.status.get"

    status = operand_def(StatusType)

    field = attr_def(StringAttr)

    result = result_def(i32)

    def __init__(self, status_obj: Operand, field: StatusTypeField):
        return super().__init__(
            operands=[status_obj],
            attributes={"field": StringAttr(field.value)},
            result_types=[i32],
        )

name = 'mpi.status.get' class-attribute instance-attribute

status = operand_def(StatusType) class-attribute instance-attribute

field = attr_def(StringAttr) class-attribute instance-attribute

result = result_def(i32) class-attribute instance-attribute

__init__(status_obj: Operand, field: StatusTypeField)

Source code in xdsl/dialects/mpi.py
600
601
602
603
604
605
def __init__(self, status_obj: Operand, field: StatusTypeField):
    return super().__init__(
        operands=[status_obj],
        attributes={"field": StringAttr(field.value)},
        result_types=[i32],
    )

CommRankOp

Bases: MPIBaseOp

Represents the MPI_Comm_size(MPI_Comm comm, int *rank) function call which returns the rank of the communicator

Currently limited to COMM_WORLD

Source code in xdsl/dialects/mpi.py
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
@irdl_op_definition
class CommRankOp(MPIBaseOp):
    """
    Represents the MPI_Comm_size(MPI_Comm comm, int *rank) function call which returns
    the rank of the communicator

    Currently limited to COMM_WORLD
    """

    name = "mpi.comm.rank"

    rank = result_def(i32)

    def __init__(self):
        return super().__init__(result_types=[i32])

name = 'mpi.comm.rank' class-attribute instance-attribute

rank = result_def(i32) class-attribute instance-attribute

__init__()

Source code in xdsl/dialects/mpi.py
621
622
def __init__(self):
    return super().__init__(result_types=[i32])

CommSizeOp

Bases: MPIBaseOp

Represents the MPI_Comm_size(MPI_Comm comm, int *size) function call which returns the size of the communicator

Currently limited to COMM_WORLD

Source code in xdsl/dialects/mpi.py
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
@irdl_op_definition
class CommSizeOp(MPIBaseOp):
    """
    Represents the MPI_Comm_size(MPI_Comm comm, int *size) function call which returns
    the size of the communicator

    Currently limited to COMM_WORLD
    """

    name = "mpi.comm.size"

    size = result_def(i32)

    def __init__(self):
        return super().__init__(result_types=[i32])

name = 'mpi.comm.size' class-attribute instance-attribute

size = result_def(i32) class-attribute instance-attribute

__init__()

Source code in xdsl/dialects/mpi.py
638
639
def __init__(self):
    return super().__init__(result_types=[i32])

InitOp dataclass

Bases: MPIBaseOp

This represents a bare MPI_Init call with both args being nullptr

Source code in xdsl/dialects/mpi.py
642
643
644
645
646
647
648
@irdl_op_definition
class InitOp(MPIBaseOp):
    """
    This represents a bare MPI_Init call with both args being nullptr
    """

    name = "mpi.init"

name = 'mpi.init' class-attribute instance-attribute

FinalizeOp dataclass

Bases: MPIBaseOp

This represents an MPI_Finalize call with both args being nullptr

Source code in xdsl/dialects/mpi.py
651
652
653
654
655
656
657
@irdl_op_definition
class FinalizeOp(MPIBaseOp):
    """
    This represents an MPI_Finalize call with both args being nullptr
    """

    name = "mpi.finalize"

name = 'mpi.finalize' class-attribute instance-attribute

UnwrapMemRefOp

Bases: MPIBaseOp

This Op can be used as a helper to get memrefs into MPI calls.

It takes any MemRef as input, and returns an llvm.ptr, element count and MPI_Datatype.

Source code in xdsl/dialects/mpi.py
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
@irdl_op_definition
class UnwrapMemRefOp(MPIBaseOp):
    """
    This Op can be used as a helper to get memrefs into MPI calls.

    It takes any MemRef as input, and returns an llvm.ptr, element count and MPI_Datatype.
    """

    name = "mpi.unwrap_memref"

    ref = operand_def(MemRefType[AnyNumericType])

    ptr = result_def(llvm.LLVMPointerType)
    len = result_def(i32)
    type = result_def(DataType)

    def __init__(self, ref: SSAValue | Operation):
        return super().__init__(
            operands=[ref],
            result_types=[llvm.LLVMPointerType(), i32, DataType()],
        )

name = 'mpi.unwrap_memref' class-attribute instance-attribute

ref = operand_def(MemRefType[AnyNumericType]) class-attribute instance-attribute

ptr = result_def(llvm.LLVMPointerType) class-attribute instance-attribute

len = result_def(i32) class-attribute instance-attribute

type = result_def(DataType) class-attribute instance-attribute

__init__(ref: SSAValue | Operation)

Source code in xdsl/dialects/mpi.py
676
677
678
679
680
def __init__(self, ref: SSAValue | Operation):
    return super().__init__(
        operands=[ref],
        result_types=[llvm.LLVMPointerType(), i32, DataType()],
    )

GetDtypeOp

Bases: MPIBaseOp

This op is used to convert MLIR types to MPI_Datatype constants.

So, e.g. if you want to get the MPI_Datatype for an i32 you can use

%dtype = "mpi.get_dtype"() {"dtype" = i32} : () -> mpi.datatype

to get the magic constant. See _MPIToLLVMRewriteBase._translate_to_mpi_type docstring for more detail on which types are supported.

Source code in xdsl/dialects/mpi.py
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
@irdl_op_definition
class GetDtypeOp(MPIBaseOp):
    """
    This op is used to convert MLIR types to MPI_Datatype constants.

    So, e.g. if you want to get the `MPI_Datatype` for an `i32` you can use

        %dtype = "mpi.get_dtype"() {"dtype" = i32} : () -> mpi.datatype

    to get the magic constant. See `_MPIToLLVMRewriteBase._translate_to_mpi_type`
    docstring for more detail on which types are supported.
    """

    name = "mpi.get_dtype"

    dtype = attr_def()

    result = result_def(DataType)

    def __init__(self, dtype: Attribute):
        return super().__init__(result_types=[DataType()], attributes={"dtype": dtype})

name = 'mpi.get_dtype' class-attribute instance-attribute

dtype = attr_def() class-attribute instance-attribute

result = result_def(DataType) class-attribute instance-attribute

__init__(dtype: Attribute)

Source code in xdsl/dialects/mpi.py
702
703
def __init__(self, dtype: Attribute):
    return super().__init__(result_types=[DataType()], attributes={"dtype": dtype})

AllocateTypeOp

Bases: MPIBaseOp

This op is used to allocate a specific MPI dialect type with a set size, returning this in an MPI vector of that type

This is useful as it means we can, in a self contained manner, store things like requests, statuses etc. It accepts the base type that the array will contain, the number of elements and an optional 'bindc_name' which contains the name of the variable that this is allocating

Source code in xdsl/dialects/mpi.py
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
@irdl_op_definition
class AllocateTypeOp(MPIBaseOp):
    """
    This op is used to allocate a specific MPI dialect type with a set size,
    returning this in an MPI vector of that type

    This is useful as it means we can, in a self contained manner, store things like
    requests, statuses etc. It accepts the base type that the array will contain, the
    number of elements and an optional 'bindc_name' which contains the name of the
    variable that this is allocating
    """

    name = "mpi.allocate"

    bindc_name = opt_attr_def(StringAttr)
    dtype = attr_def(VectorWrappableConstr)
    count = operand_def(i32)

    result = result_def(VectorType)

    def __init__(
        self,
        dtype: type[VectorWrappable],
        count: SSAValue | Operation,
        bindc_name: StringAttr | None = None,
    ):
        return super().__init__(
            result_types=[VectorType(dtype())],
            attributes={
                "dtype": dtype(),
                "bindc_name": bindc_name,
            },
            operands=[count],
        )

name = 'mpi.allocate' class-attribute instance-attribute

bindc_name = opt_attr_def(StringAttr) class-attribute instance-attribute

dtype = attr_def(VectorWrappableConstr) class-attribute instance-attribute

count = operand_def(i32) class-attribute instance-attribute

result = result_def(VectorType) class-attribute instance-attribute

__init__(dtype: type[VectorWrappable], count: SSAValue | Operation, bindc_name: StringAttr | None = None)

Source code in xdsl/dialects/mpi.py
726
727
728
729
730
731
732
733
734
735
736
737
738
739
def __init__(
    self,
    dtype: type[VectorWrappable],
    count: SSAValue | Operation,
    bindc_name: StringAttr | None = None,
):
    return super().__init__(
        result_types=[VectorType(dtype())],
        attributes={
            "dtype": dtype(),
            "bindc_name": bindc_name,
        },
        operands=[count],
    )

VectorGetOp

Bases: MPIBaseOp

This op will retrieve an element of an MPI vector, it accepts the vector as an argument and the element index

Source code in xdsl/dialects/mpi.py
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
@irdl_op_definition
class VectorGetOp(MPIBaseOp):
    """
    This op will retrieve an element of an MPI vector, it accepts the vector as
    an argument and the element index
    """

    name = "mpi.vector_get"

    vect = operand_def(VectorType)
    element = operand_def(i32)

    result = result_def(VectorWrappableConstr)

    def __init__(self, vect: SSAValue | Operation, element: SSAValue | Operation):
        ssa_val = SSAValue.get(vect)
        assert isa(ssa_val.type, VectorType[VectorWrappable])

        return super().__init__(
            result_types=[ssa_val.type.wrapped_type], operands=[vect, element]
        )

name = 'mpi.vector_get' class-attribute instance-attribute

vect = operand_def(VectorType) class-attribute instance-attribute

element = operand_def(i32) class-attribute instance-attribute

result = result_def(VectorWrappableConstr) class-attribute instance-attribute

__init__(vect: SSAValue | Operation, element: SSAValue | Operation)

Source code in xdsl/dialects/mpi.py
756
757
758
759
760
761
762
def __init__(self, vect: SSAValue | Operation, element: SSAValue | Operation):
    ssa_val = SSAValue.get(vect)
    assert isa(ssa_val.type, VectorType[VectorWrappable])

    return super().__init__(
        result_types=[ssa_val.type.wrapped_type], operands=[vect, element]
    )

NullRequestOp

Bases: MPIBaseOp

This sets a given request object to the MPI_REQUEST_NULL magic value.

Due to restrictions in the current MPI dialect, we can't return a new request object here. That will be fixed soon though!

Source code in xdsl/dialects/mpi.py
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
@irdl_op_definition
class NullRequestOp(MPIBaseOp):
    """
    This sets a given request object to the MPI_REQUEST_NULL magic
    value.

    Due to restrictions in the current MPI dialect, we can't return a
    new request object here. That will be fixed soon though!
    """

    name = "mpi.request_null"

    request = operand_def(RequestType)

    def __init__(self, req: SSAValue | Operation):
        return super().__init__(operands=[req])

name = 'mpi.request_null' class-attribute instance-attribute

request = operand_def(RequestType) class-attribute instance-attribute

__init__(req: SSAValue | Operation)

Source code in xdsl/dialects/mpi.py
779
780
def __init__(self, req: SSAValue | Operation):
    return super().__init__(operands=[req])

GatherOp

Bases: MPIBaseOp

This is used to gather data into one big buffer.

int MPI_Gather(const void sendbuf, int sendcount, MPI_Datatype sendtype, void recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm)

  • sendbuf, sendcount, sendtype: info on the buffer to be sent
  • recvbuf, recvcount, recvtype: info on the gather buffer
  • root: the rank that receives all the data
  • comm: the communicator to use

Note: recvcount * sizeof(recvtype) == sendcount * sizeof(sendtype) * N where N is the number of nodes participating in the gather.

Note that the data in the recvbuff will not be a nice grid, instead it will contain the sent buffers in order of rank.

Source code in xdsl/dialects/mpi.py
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
@irdl_op_definition
class GatherOp(MPIBaseOp):
    """
    This is used to gather data into one big buffer.

    int MPI_Gather(const void *sendbuf, int sendcount, MPI_Datatype sendtype,
                   void *recvbuf, int recvcount, MPI_Datatype recvtype,
                   int root,
                   MPI_Comm comm)

     - sendbuf, sendcount, sendtype: info on the buffer to be sent
     - recvbuf, recvcount, recvtype: info on the gather buffer
     - root: the rank that receives all the data
     - comm: the communicator to use

    Note: recvcount * sizeof(recvtype) == sendcount * sizeof(sendtype) * N
    where N is the number of nodes participating in the gather.

    Note that the data in the recvbuff will not be a nice grid, instead it will contain
    the sent buffers in order of rank.
    """

    name = "mpi.gather"

    sendbuf = operand_def(llvm.LLVMPointerType)
    sendcount = operand_def(i32)
    sendtype = operand_def(DataType)

    recvbuf = operand_def(llvm.LLVMPointerType)
    recvcount = operand_def(i32)
    recvtype = operand_def(DataType)

    root = operand_def(i32)

    def __init__(
        self,
        sendbuf: SSAValue | Operation,
        sendcount: SSAValue | Operation,
        sendtype: SSAValue | Operation,
        recvbuf: SSAValue | Operation,
        recvcount: SSAValue | Operation,
        recvtype: SSAValue | Operation,
        root: SSAValue | Operation,
    ):
        super().__init__(
            operands=[
                sendbuf,
                sendcount,
                sendtype,
                recvbuf,
                recvcount,
                recvtype,
                root,
            ]
        )

name = 'mpi.gather' class-attribute instance-attribute

sendbuf = operand_def(llvm.LLVMPointerType) class-attribute instance-attribute

sendcount = operand_def(i32) class-attribute instance-attribute

sendtype = operand_def(DataType) class-attribute instance-attribute

recvbuf = operand_def(llvm.LLVMPointerType) class-attribute instance-attribute

recvcount = operand_def(i32) class-attribute instance-attribute

recvtype = operand_def(DataType) class-attribute instance-attribute

root = operand_def(i32) class-attribute instance-attribute

__init__(sendbuf: SSAValue | Operation, sendcount: SSAValue | Operation, sendtype: SSAValue | Operation, recvbuf: SSAValue | Operation, recvcount: SSAValue | Operation, recvtype: SSAValue | Operation, root: SSAValue | Operation)

Source code in xdsl/dialects/mpi.py
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
def __init__(
    self,
    sendbuf: SSAValue | Operation,
    sendcount: SSAValue | Operation,
    sendtype: SSAValue | Operation,
    recvbuf: SSAValue | Operation,
    recvcount: SSAValue | Operation,
    recvtype: SSAValue | Operation,
    root: SSAValue | Operation,
):
    super().__init__(
        operands=[
            sendbuf,
            sendcount,
            sendtype,
            recvbuf,
            recvcount,
            recvtype,
            root,
        ]
    )