This patch supports the atomic construct (update) following section 2.17.7 of OpenMP 5.0 standard. Also added tests and verifier for the same.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td | ||
---|---|---|
604 | According to OpenMP 5.0 Spec 2.17.7 at page 239, operator is one of +, *, -, /, .AND., .OR., .EQV., or .NEQV.. I think you referred to C/C++ operator for XOR, SHIFTR and SHIFTL? MAX, MIN is instrinsic procedure name, not operator here. What you plan to do is to use the format x = x max y in MLIR for x = max(x, y) in fortran code, right? If yes, did you miss IAND, IOR, IEOR? I think BINOP is not the right term since MAX and MIN is intrinsic procedure name instead of binary operator. You should give a new name here. | |
mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp | ||
1441 | How do you plan to handle the case x = max(x, max(y), min(z)) in fortran code? To make it as x = x max expr (lowering max(max(y), min(z)) to expr) in MLIR? | |
1482 | In the else branch, the LHS X is also in RHS. isXLHSInRHSPart -> isXInRHSLeft? Or you can give one better name. |
Thanks for the comments @peixin! I have tried to address them all, and will include the comments as mentioned if it is okay with you.
mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td | ||
---|---|---|
604 |
Yes, that is correct.
The AND, OR and XOR are bitwise operations (will mention this as a comment for clarification). As logical values are essentially one-bit integer values, "logical and" is equivalent to "bitwise and for 1-bit integers". So we do not need both the sets AND, OR, XOR and IAND, IOR, IEOR.
I have borrowed the naming from OpenMP IR Builder (link). Although they do not handle MAX, MIN in createAtomicUpdate (link) right now, they have modeled it as a binary operation in llvm::AtomicRMWInst::BinOp (link). This is in line with C/C++, and prevents us from handling Fortran-specific features (intrinsic) in the common dialect. I am open to suggestions on another more appropriate naming though. | |
mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp | ||
1441 | Yes, more or less. The evaluation of the expr_list (e1, e2, ...) in max(x, e1, e2, ... ) is not atomic. Hence, all such operations can be lowered to the following before OpenMPDialect: expr = max(e1, e2... ) x = x max expr // atomic update Let me know if the lowering doesn't seem right and breaks any concurrency related OpenMP guarantees. | |
1482 | Again, this naming is borrowed from OpenMP IRBuilder. I was a little hesitant while using this variable too as the naming was not very clear. What the name is trying to say is "is X an LHS op in the RHS part?". I will put this as a comment here, but I have to agree I could not think of a better name. Any suggestions on this are welcome 😄 |
Except for the variable name isXLHSInRHSPart, LGTM.
mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td | ||
---|---|---|
604 |
| |
604 | The this is fine with me. Thanks for the explanations. | |
mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp | ||
1441 | I think it's viable to do this when lowering from parse-tree to MLIR. | |
1482 | Well. I think the variable name should be changed together with the one in OpenMPIRBuilder since its name is not what it means. Maybe isXBinopExpr? |
Thanks for this patch. Had a quick look. Looks OK. I have a couple of points.
mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp | ||
---|---|---|
1454 | Move to verifier (also)? | |
1466–1469 | Should this be moved to the verifier (also)? | |
mlir/test/Dialect/OpenMP/ops.mlir | ||
538–544 | These could be for integers as well right? Can you add a test for regular integer types also? |
Rebase with main, addressed comments
mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp | ||
---|---|---|
1454 | I believe this cannot be moved to the verifier, as it's value is used in the next line (while making the attribute) | |
1466–1469 | This cannot be moved to the verifier because expr is used in the resolveOperand call later and it cannot be null. | |
mlir/test/Dialect/OpenMP/ops.mlir | ||
538–544 | This was a mistake. It was supposed to be a test for regular integers and I don't think it makes sense to right shift on one-bit integers. I have modified it for i32 now. |
What will prevent the builder from building operations which has the errors that you are catching during parsing?
Thanks for the review @kiranchandramohan.
The BinOp error will be taken care of by the AtomicBinOpKindAttr. An integer value from the allowed ones will be forced because of that constraint.
The other error - about X being in RHS - that is taken care of by design as the in memory structure has X, expr, binOp and isXBinOpExpr. It is not possible to run into that error while building the operation.
Addressed Comments.
mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td | ||
---|---|---|
627 | This is the naming issue from earlier. The name here means "is it of the form X binop expr". The value false implies that it is of the form expr binop X. The previous name for this variable was isXLhsinRhsPart but that was confusing too. This is not a flag for it being a binop expression or not. |
According to OpenMP 5.0 Spec 2.17.7 at page 239, operator is one of +, *, -, /, .AND., .OR., .EQV., or .NEQV.. I think you referred to C/C++ operator for XOR, SHIFTR and SHIFTL?
MAX, MIN is instrinsic procedure name, not operator here. What you plan to do is to use the format x = x max y in MLIR for x = max(x, y) in fortran code, right? If yes, did you miss IAND, IOR, IEOR?
I think BINOP is not the right term since MAX and MIN is intrinsic procedure name instead of binary operator. You should give a new name here.