-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[mlir] Initial patch to add an MPI dialect #68892
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
7b3e9f5
to
a6358c2
Compare
This looks interesting! I'm curious to see how it works in detail. |
The Flang community is also interested in this work. Would you be interested in presenting at our regular calls? We have calls every week (The next occurrences are on Monday 16th and Wednesday 25th). Thanks in advance. |
This looks great, thank you for working on this! |
+1 |
a6358c2
to
855f178
Compare
@fabianmcg @clementval, the next ODM no Nov. 2nd will have a presentation and discussion round on the MPI dialect! |
A RFC on discord would still be appreciated to discuss the advantage of having a MPI dialect. |
5e0ff46
to
4ed4b25
Compare
RFC has been posted here: https://discourse.llvm.org/t/rfc-mpi-dialect/74705 |
+1 |
Thanks for the feedback @fschlimb, I'll see that I get an updated PR ready for review ASAP! |
c9470d7
to
a199f3a
Compare
The failure in |
Will push a fix soon. Thanks for bringing it to our attention. |
cecde9c
to
171caa3
Compare
Thank you @Groverkss for catching these! I've updated the PR to reflect your feedback! |
171caa3
to
fdfa330
Compare
1415888
to
9e697ff
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dropped a bunch of nit comments, the general design makes a lot of sense to me.
One concern I'm having is the restriction to only work with memref types. While I understand that this is easier to work with, some users might not be able to work with memrefs and thus cannot use this dialect. AFAIK, flang doesn't use memrefs, and neither does code that will come from some lower level input (or the LLVM import).
Note that this can also be resolved once this has been landed, though.
I think this is looking good to me, but I don't have the authority to accept this, I think. @kiranchandramohan @rengolin any idea who has the authority?
9e697ff
to
17f7fe0
Compare
17f7fe0
to
958f37a
Compare
This LGTM. Let's wait another week since I expect folks are still returning from vacation. There seems to be enough interest in the MPI Dialect, and I don't see any outstanding concerns, so I'm happy to accept it after a week. Tagging people who initially showed interest to see if there are any outstanding concerns @rengolin @nicolasvasilache @kiranchandramohan @clementval @fschlimb @fabianmcg @sogartar @tschuett @yaochengji |
Could you summarise the answers to the questions in the guidelines on contributing a new dialect in the RFC? Apologies, if this has been done already, then a link will be useful.
Yes, a memref only approach will make it not immediately useful in Flang. But that need not be a blocker. Fortran has co-arrays which can potentially lower to MPI.
Is this still failing? I thought I had fixed in a4deb14. |
958f37a
to
9e28910
Compare
Thank you @kiranchandramohan for your input!
I'll see that I get good answers to these questions, especially in regards to use-case and external support!
I rebased the PR, it seems to all be okay locally |
As @kiranchandramohan said:
Here are our answers as requested:
An MPI dialect will provide first-class message-passing primitives that can be used both as a target by higher-level code generation and as a fixed point for other lower-level efforts such as MPI-level optimizations and rewrites.
As a first implementation milestone, we will introduce ops for blocking communication and a lowering to llvm.
It fits in as a target-able dialect that abstracts away the messy MPI ABI and helps bridge the gap between pointers and MLIR's memref.
The MPI dialect will work as a target for higher-level message-passing abstractions such as the sharding dialect. The lower end of a sharded linalg flow would encompass (with more intermediate steps) (linalg + sharding) -> (scf + memref + MPI) -> (llvm). We have demonstrated this approach by building a stencil compiler on a slightly different higher level message passing abstraction that goes (stencil) -> (stencil + message passing) -> (scf + memref + MPI) -> (llvm).
We are unaware of any other dialect in MLIR filling a similar role to this one.
While we focus on a target dialect for HPC code generation, other groups are interested in exploring a different space, such as MPI-level optimizations or translating point-to-point MPI calls to other forms of communication. We are confident that our abstractions can generalize to these use cases without a significant effort. We have collaborated with Jeff Hammond from the MPI ABI standardization body to ensure that our abstractions are a sensible expression of the MPI Interface.
The proposed MPI dialect makes MLIR accessible to the HPC community and provides MLIR's AI compiler community access to HPC-style distributed computing. MPI is a broadly established communication standard used in HPC and almost uniformly used as its communication abstraction.
HPC DSL developers such as Frank Schlimbach at Intel are actively looking into MLIR, and Renato Golin at Intel agreed to co-maintain the dialect with us. Unlocking access to the MLIR ecosystem through the MPI dialect will ensure they can contribute to this dialect as part of their work, ensuring that the dialect will receive the needed support. |
Thanks for the detailed answer. Could you post a copy of this in the RFC? Also, tag the people whom you have mentioned will help maintain. |
9e28910
to
10c3699
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this effort! Looks like a good start.
Looking forward to the non-blocking PR! Thanks.
def MPI_Retval : MPI_Type<"Retval", "retval"> { | ||
let summary = "MPI function call return value"; | ||
let description = [{ | ||
This type represents a return value from an MPI function vall. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo: vall
-> call
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LG, please rebase and re-run the CI though.
[OpenMPI online documentation](https://www.open-mpi.org/doc/current/). | ||
}]; | ||
|
||
let usePropertiesForAttributes = 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: this is the default.
10c3699
to
a904552
Compare
Thank you @sjw36 and @joker-eph for your reviews, I addressed your feedback in the latest update to this PR |
This reverts commit 2d616ec. Buildbot failures: https://lab.llvm.org/buildbot/#/builders/177/builds/29364
@AntonLydike I reverted this for now #81884 . There seem to be buildbot failures. |
#include "mlir/Dialect/MPI/IR/MPIAttrDefs.cpp.inc" | ||
|
||
#define GET_OP_CLASSES | ||
#include "mlir/Dialect/MPI/IR/MPIOps.cpp.inc" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like these two lines should be removed
Thank you @Groverkss and @joker-eph for the quick revert and tips on how to fix. I have re-opened a PR with the fix incorporated in #81975 |
This patch introduces the new MPI dialect into MLIR. The Message Passing Interface (MPI) is a widely-used standard for distributed programs to exchange data. This PR goes together with a talk later at today's LLVM Dev Meeting.
This is just a first, small patch to get going and add the necessary base files, so that we can add more operations in further patches.
Here's the documentation as generated by
ninja mlir-doc
:'mpi' Dialect
This dialect models the Message Passing Interface (MPI), version
4.0. It is meant to serve as an interfacing dialect that is targeted
by higher-level dialects. The MPI dialect itself can be lowered to
multiple MPI implementations and hide differences in ABI. The dialect
models the functions of the MPI specification as close to 1:1 as possible
while preserving SSA value semantics where it makes sense, and uses
memref
types instead of bare pointers.This dialect is under active development, and while stability is an
eventual goal, it is not guaranteed at this juncture. Given the early
state, it is recommended to inquire further prior to using this dialect.
For an in-depth documentation of the MPI library interface, please refer
to official documentation such as the
OpenMPI online documentation.
[TOC]
Operation definition
mpi.comm_rank
(mpi::CommRankOp)Get the current rank, equivalent to
MPI_Comm_rank(MPI_COMM_WORLD, &rank)
Syntax:
Communicators other than
MPI_COMM_WORLD
are not supported for now.This operation can optionally return an
!mpi.retval
value that can be usedto check for errors.
Results:
retval
rank
mpi.error_class
(mpi::ErrorClassOp)Get the error class from an error code, equivalent to the
MPI_Error_class
functionSyntax:
MPI_Error_class
maps return values from MPI calls to a set of well-knownMPI error classes.
Operands:
val
Results:
errclass
mpi.finalize
(mpi::FinalizeOp)Finalize the MPI library, equivalent to
MPI_Finalize()
Syntax:
This function cleans up the MPI state. Afterwards, no MPI methods may
be invoked (excpet for MPI_Get_version, MPI_Initialized, and MPI_Finalized).
Notably, MPI_Init cannot be called again in the same program.
This operation can optionally return an
!mpi.retval
value that can be usedto check for errors.
Results:
retval
mpi.init
(mpi::InitOp)Initialize the MPI library, equivalent to
MPI_Init(NULL, NULL)
Syntax:
This operation must preceed most MPI calls (except for very few exceptions,
please consult with the MPI specification on these).
Passing &argc, &argv is not supported currently.
This operation can optionally return an
!mpi.retval
value that can be usedto check for errors.
Results:
retval
mpi.recv
(mpi::RecvOp)Equivalent to
MPI_Recv(ptr, size, dtype, dest, tag, MPI_COMM_WORLD, MPI_STATUS_IGNORE)
Syntax:
MPI_Recv performs a blocking receive of
size
elements of typedtype
from rank
dest
. Thetag
value and communicator enables the library todetermine the matching of multiple sends and receives between the same
ranks.
Communicators other than
MPI_COMM_WORLD
are not supprted for now.The MPI_Status is set to
MPI_STATUS_IGNORE
, as the status objectis not yet ported to MLIR.
This operation can optionally return an
!mpi.retval
value that can be usedto check for errors.
Operands:
ref
tag
rank
Results:
retval
mpi.retval_check
(mpi::RetvalCheckOp)Check an MPI return value against an error class
Syntax:
This operation compares MPI status codes to known error class
constants such as
MPI_SUCCESS
, orMPI_ERR_COMM
.Attributes:
errclass
MPI error class name
{{% markdown %}}Enum cases: * MPI_SUCCESS (`MPI_SUCCESS`) * MPI_ERR_ACCESS (`MPI_ERR_ACCESS`) * MPI_ERR_AMODE (`MPI_ERR_AMODE`) * MPI_ERR_ARG (`MPI_ERR_ARG`) * MPI_ERR_ASSERT (`MPI_ERR_ASSERT`) * MPI_ERR_BAD_FILE (`MPI_ERR_BAD_FILE`) * MPI_ERR_BASE (`MPI_ERR_BASE`) * MPI_ERR_BUFFER (`MPI_ERR_BUFFER`) * MPI_ERR_COMM (`MPI_ERR_COMM`) * MPI_ERR_CONVERSION (`MPI_ERR_CONVERSION`) * MPI_ERR_COUNT (`MPI_ERR_COUNT`) * MPI_ERR_DIMS (`MPI_ERR_DIMS`) * MPI_ERR_DISP (`MPI_ERR_DISP`) * MPI_ERR_DUP_DATAREP (`MPI_ERR_DUP_DATAREP`) * MPI_ERR_ERRHANDLER (`MPI_ERR_ERRHANDLER`) * MPI_ERR_FILE (`MPI_ERR_FILE`) * MPI_ERR_FILE_EXISTS (`MPI_ERR_FILE_EXISTS`) * MPI_ERR_FILE_IN_USE (`MPI_ERR_FILE_IN_USE`) * MPI_ERR_GROUP (`MPI_ERR_GROUP`) * MPI_ERR_INFO (`MPI_ERR_INFO`) * MPI_ERR_INFO_KEY (`MPI_ERR_INFO_KEY`) * MPI_ERR_INFO_NOKEY (`MPI_ERR_INFO_NOKEY`) * MPI_ERR_INFO_VALUE (`MPI_ERR_INFO_VALUE`) * MPI_ERR_IN_STATUS (`MPI_ERR_IN_STATUS`) * MPI_ERR_INTERN (`MPI_ERR_INTERN`) * MPI_ERR_IO (`MPI_ERR_IO`) * MPI_ERR_KEYVAL (`MPI_ERR_KEYVAL`) * MPI_ERR_LOCKTYPE (`MPI_ERR_LOCKTYPE`) * MPI_ERR_NAME (`MPI_ERR_NAME`) * MPI_ERR_NO_MEM (`MPI_ERR_NO_MEM`) * MPI_ERR_NO_SPACE (`MPI_ERR_NO_SPACE`) * MPI_ERR_NO_SUCH_FILE (`MPI_ERR_NO_SUCH_FILE`) * MPI_ERR_NOT_SAME (`MPI_ERR_NOT_SAME`) * MPI_ERR_OP (`MPI_ERR_OP`) * MPI_ERR_OTHER (`MPI_ERR_OTHER`) * MPI_ERR_PENDING (`MPI_ERR_PENDING`) * MPI_ERR_PORT (`MPI_ERR_PORT`) * MPI_ERR_PROC_ABORTED (`MPI_ERR_PROC_ABORTED`) * MPI_ERR_QUOTA (`MPI_ERR_QUOTA`) * MPI_ERR_RANK (`MPI_ERR_RANK`) * MPI_ERR_READ_ONLY (`MPI_ERR_READ_ONLY`) * MPI_ERR_REQUEST (`MPI_ERR_REQUEST`) * MPI_ERR_RMA_ATTACH (`MPI_ERR_RMA_ATTACH`) * MPI_ERR_RMA_CONFLICT (`MPI_ERR_RMA_CONFLICT`) * MPI_ERR_RMA_FLAVOR (`MPI_ERR_RMA_FLAVOR`) * MPI_ERR_RMA_RANGE (`MPI_ERR_RMA_RANGE`) * MPI_ERR_RMA_SHARED (`MPI_ERR_RMA_SHARED`) * MPI_ERR_RMA_SYNC (`MPI_ERR_RMA_SYNC`) * MPI_ERR_ROOT (`MPI_ERR_ROOT`) * MPI_ERR_SERVICE (`MPI_ERR_SERVICE`) * MPI_ERR_SESSION (`MPI_ERR_SESSION`) * MPI_ERR_SIZE (`MPI_ERR_SIZE`) * MPI_ERR_SPAWN (`MPI_ERR_SPAWN`) * MPI_ERR_TAG (`MPI_ERR_TAG`) * MPI_ERR_TOPOLOGY (`MPI_ERR_TOPOLOGY`) * MPI_ERR_TRUNCATE (`MPI_ERR_TRUNCATE`) * MPI_ERR_TYPE (`MPI_ERR_TYPE`) * MPI_ERR_UNKNOWN (`MPI_ERR_UNKNOWN`) * MPI_ERR_UNSUPPORTED_DATAREP (`MPI_ERR_UNSUPPORTED_DATAREP`) * MPI_ERR_UNSUPPORTED_OPERATION (`MPI_ERR_UNSUPPORTED_OPERATION`) * MPI_ERR_VALUE_TOO_LARGE (`MPI_ERR_VALUE_TOO_LARGE`) * MPI_ERR_WIN (`MPI_ERR_WIN`) * MPI_ERR_LASTCODE (`MPI_ERR_LASTCODE`){{% /markdown %}}Operands:
val
Results:
res
mpi.send
(mpi::SendOp)Equivalent to
MPI_Send(ptr, size, dtype, dest, tag, MPI_COMM_WORLD)
Syntax:
MPI_Send performs a blocking send of
size
elements of typedtype
to rankdest
. Thetag
value and communicator enables the library to determinethe matching of multiple sends and receives between the same ranks.
Communicators other than
MPI_COMM_WORLD
are not supprted for now.This operation can optionally return an
!mpi.retval
value that can be usedto check for errors.
Operands:
ref
tag
rank
Results:
retval
Attribute definition
MPI_ErrorClassEnumAttr
MPI error class name
Syntax:
Enum cases:
MPI_SUCCESS
)MPI_ERR_ACCESS
)MPI_ERR_AMODE
)Parameters:
::mlir::mpi::MPI_ErrorClassEnum
Type definition
RetvalType
MPI function call return value
Syntax:
!mpi.retval
This type represents a return value from an MPI function vall.
This value can be MPI_SUCCESS, MPI_ERR_IN_STATUS, or any error code.
This return value can be compared agains the known MPI error classes
represented by
#mpi.errclass
using thempi.retval_check
operation.