This is an archive of the discontinued LLVM Phabricator instance.

[MLIR][OpenMP] Added omp.atomic.read and omp.atomic.write
ClosedPublic

Authored by shraiysh on Oct 18 2021, 7:17 AM.

Details

Summary

This patch supports the atomic construct (read and write) following
section 2.17.7 of OpenMP 5.0 standard. Also added tests and
verifier for the same.

Diff Detail

Event Timeline

shraiysh created this revision.Oct 18 2021, 7:17 AM
shraiysh requested review of this revision.Oct 18 2021, 7:17 AM
mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
515

Are we taking care of capture ,compare ,fail(seq_cst | acquire | relaxed)
weak
?

Thanks for reviewing this patch @abidmalikwaterloo.

mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
515

I am sorry, I did not understand it correctly. The omp.atomic.capture and omp.atomic.update operations will be released as a separate patch to avoid too many changes in one patch (and ease of review). The restriction on memory ordering clause values is verified in the verifiers for these operations independently. Let me know if this wasn't your concern.

kiranchandramohan requested changes to this revision.Oct 18 2021, 9:07 PM

Thanks @shraiysh for this patch. Have a few comments.

mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
63

Is it possible to autogen this from OMP.td? This capability was introduced as part of https://reviews.llvm.org/D84347.

If you can define ClauseVal entries in llvm/include/llvm/Frontend/OpenMP/OMP.td then these entries will be autogenerated. Example for proc_bind given below.

def OMP_PROC_BIND_master : ClauseVal<"master",2,1> {}
def OMP_PROC_BIND_close : ClauseVal<"close",3,1> {}
def OMP_PROC_BIND_spread : ClauseVal<"spread",4,1> {}
def OMP_PROC_BIND_default : ClauseVal<"default",5,0> {}
def OMP_PROC_BIND_unknown : ClauseVal<"unknown",6,0> { let isDefault = 1; }
def OMPC_ProcBind : Clause<"proc_bind"> {

let clangClass = "OMPProcBindClause";
let flangClass = "OmpProcBindClause";
let enumClauseValue = "ProcBindKind";
let allowedClauseValues = [
  OMP_PROC_BIND_master,
  OMP_PROC_BIND_close,
  OMP_PROC_BIND_spread,
  OMP_PROC_BIND_default,
  OMP_PROC_BIND_unknown
];

}

mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
1285

Consider reducing this to "memory-order must not be acq_rel or release for atomic reads".
Similarly for writes as well.

1323

Is the order of hint and memory_order different from Read?

mlir/test/Dialect/OpenMP/invalid.mlir
379

should we have tests for allowed once clauses?

474

Nit: Add newline

This revision now requires changes to proceed.Oct 18 2021, 9:07 PM
shraiysh updated this revision to Diff 380599.Oct 19 2021, 1:00 AM
shraiysh marked 5 inline comments as done.

Thanks for the review @kiranchandramohan. Addressed comments.

mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
63

I don't think it can be done because in OMP.td, these values are treated like independent clauses. There is no unified "memory ordering" clause in that file. Let me know if I am missing something here.

clementval added inline comments.Oct 19 2021, 1:28 AM
mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
63

You can still define the enum in the file and have it generated for you by the current back-end.

shraiysh updated this revision to Diff 380642.Oct 19 2021, 4:29 AM

Moved Memory Order clause to OMP.td.

Thanks for the suggestion @kiranchandramohan @clementval. Addressed comments

Herald added a project: Restricted Project. · View Herald Transcript
shraiysh updated this revision to Diff 380674.Oct 19 2021, 6:29 AM

Handle build failure and rebase with main

The Synchronization Hint functions have been moved above because they are required in parseClauses. I will add it as an NFC and then rebase here, because right now reviewing this (the way it is showing differences) will be hard.

shraiysh updated this revision to Diff 380718.Oct 19 2021, 9:53 AM

Rebase with main

Herald added projects: Restricted Project, Restricted Project. · View Herald TranscriptOct 19 2021, 9:53 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript
shraiysh marked an inline comment as done.Oct 19 2021, 9:54 AM

Hi all, the NFC has been merged, and the build is passing. This is ready for review now.

The patch looks OK. I just wanted to discuss the syntax also. Would any of the following be better?

%8 = omp.atomic.read %addr : memref<i32> -> i32 hint(speculative, contended) memory_order(seq_cst)
%8 = omp.atomic.read %addr hint(speculative, contended) memory_order(seq_cst) : memref<i32> -> i32
%8 = omp.atomic.read %addr {hint(speculative, contended) memory_order(seq_cst)} : memref<i32> -> i32

Hi @kiranchandramohan. Thanks for the review.

%8 = omp.atomic.read %addr : memref<i32> -> i32 hint(speculative, contended) memory_order(seq_cst)

This cannot be done because the statement ends at optional clauses. This is dangerous in the following situation where parser will try to match return as a clause instead of a new instruction. I had first actually tried it this way. Let me know if there is something that can be done to avoid this problem with this syntax.

%8 = omp.atomic.read %addr : memref<i32> -> i32 memory_order(seq_cst)
return

We can try one of remaining two. I do not have a preference between these three:

%8 = omp.atomic.read %addr hint(speculative, contended) memory_order(seq_cst) : memref<i32> -> i32
%8 = omp.atomic.read %addr {hint(speculative, contended) memory_order(seq_cst)} : memref<i32> -> i32
%8 = omp.atomic.read hint(speculative, contended) memory_order(seq_cst) %addr : memref<i32> -> i32 // current syntax

LGTM.

My preference is the following one. If you agree then please make the change, otherwise, you can keep it as is. Also, wait a couple of days to see whether others have comments.

%8 = omp.atomic.read %addr hint(speculative, contended) memory_order(seq_cst) : memref<i32> -> i32
This revision is now accepted and ready to land.Oct 22 2021, 3:58 AM

LGTM.

My preference is the following one. If you agree then please make the change, otherwise, you can keep it as is. Also, wait a couple of days to see whether others have comments.

%8 = omp.atomic.read %addr hint(speculative, contended) memory_order(seq_cst) : memref<i32> -> i32

Sure, will wait for other's comments. Meanwhile, I will update it with this syntax.

shraiysh updated this revision to Diff 381772.Oct 23 2021, 11:25 PM

Rebase with main, updated syntax.

peixin added inline comments.Oct 24 2021, 6:37 PM
clang/lib/CodeGen/CGStmtOpenMP.cpp
5993

The memory_order clause in clang side is not handled in this patch. Maybe leaving the error is better since users will know it is not supported yet in clang.

mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
513

How do you plan to handle synchronization between the threads if there is no region in atomic read op? Will there be one implicit kmpc_flush function call before !$omp end atomic? If yes, it is easier to find to location of emiting kmpc_flush if we have one region here. Please let me know if I am wrong.

mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
1246

Please also check OpenMP 5.1 Spec. It seems that acq_rel is allowed if read clause is specified.

peixin added inline comments.Oct 24 2021, 6:40 PM
clang/lib/CodeGen/CGStmtOpenMP.cpp
5993

The memory_order clause in clang side is not handled in this patch. Maybe leaving the error is better since users will know it is not supported yet in clang.

Sorry. Please ignore this comment.

Thanks for the review @peixin.

mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
513

Yes - there will be a kmpc_flush call, but OpenMP Dialect does not have to worry about that. OpenMP IR Builder takes care of flushes in the function createAtomicRead.

mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
1246

Thanks for this observation, I will update it with the 5.1 standard.

shraiysh added inline comments.Oct 25 2021, 4:28 AM
mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
1246

Just to be clear, the OpenMP 5.1 specification changes atomic by a considerable amount (especially it breaks capture into two sub-constructs (coming as a separate patch)) and AFAIK we are targeting OpenMP 5.0. So, do I still update it to the 5.1 standard (this will affect further implementation of atomic construct)?

shraiysh updated this revision to Diff 382537.Oct 27 2021, 12:32 AM

Rebase with main