This is an archive of the discontinued LLVM Phabricator instance.

[mlir][openacc] Add OpenACC translation to LLVM IR (enter_data op create/copyin)
ClosedPublic

Authored by clementval on Apr 28 2021, 6:10 PM.

Details

Summary

This patch begins to translate acc.enter_data operation to call to tgt runtime call.
It currently only translate create/copyin operands of memref type. This acts as a basis to add support
for FIR types in the Flang/OpenACC support. It follows more or less a similar path than clang
with omp target enter data map directives.
This patch is taking a different approach than D100678 and perform a translation to LLVM IR
and make use of the OpenMPIRBuilder instead of doing a conversion to the LLVMIR dialect.

OpenACC support in Flang will rely on the current OpenMP runtime where 1:1 lowering can be
applied. Some extension will be added where features are not available yet.

Big part of this code will be shared for other standalone data operations in the OpenACC
dialect such as acc.exit_data and acc.update.

It is likely that parts of the lowering can also be shared later with the ops for
standalone data directives in the OpenMP dialect when they are introduced.

This is an initial translation and it probably needs more work.

Diff Detail

Event Timeline

clementval created this revision.Apr 28 2021, 6:10 PM
clementval requested review of this revision.Apr 28 2021, 6:10 PM

Adapt call to builder after change in D101503

Add copyin operand

clementval retitled this revision from [mlir][openacc] Add OpenACC translation to LLVM IR (enter_data op create) to [mlir][openacc] Add OpenACC translation to LLVM IR (enter_data op create/copyin).Apr 29 2021, 6:09 PM
clementval edited the summary of this revision. (Show Details)
clementval updated this revision to Diff 342723.May 4 2021, 7:20 AM

Fix clang-tidy warnings

A few questions.

mlir/lib/Target/LLVMIR/Dialect/OpenACC/OpenACCToLLVMIRTranslation.cpp
114

Is the current assumption that the operands will be of the memref type and later extend it to other types like llvm.pointer?
Would it be simpler to do llvm.pointer first?

114

isa<>?

117

Nit: remove commented code?

173

+1

194

Should there be a check for presence of createOperands here and for copyinoperands below?

mlir/test/Target/LLVMIR/openacc-llvm.mlir
2

Any particular reason we are starting from standard type? Can it just be a llvm.pointer?

clementval marked 4 inline comments as done.

Address some review comments

mlir/lib/Target/LLVMIR/Dialect/OpenACC/OpenACCToLLVMIRTranslation.cpp
114

Yeah I just wanted to start with a type that is close to what the Fortran array will look like. The memref type seems to be quite close to a Fortran array with its descriptor. The idea is of course to handle more types than just memref types.

A simple llvm.pointer is missing the size information needed by the runtime. It likely to work only for pointer to scalar where we can infer the size.

173

I'll prepare a OMPIRBuilder patch for that.

194

We can check if there is any operands but the processOperands function will just return in case there is no operand.

mlir/test/Target/LLVMIR/openacc-llvm.mlir
2

Just to convert memref to LLVM IR dialect.

mlir/lib/Target/LLVMIR/Dialect/OpenACC/OpenACCToLLVMIRTranslation.cpp
114

I was thinking about the Flang flow and what would be available there. I guess there will not be any memrefs and the arrays will be converted to some llvm.ptr. How will we recover the array information there? Do we need to have an FIRToOpenACC/OpenACCToLLVMDialect conversion pass which will add additional information (as attributes) to the llvm.ptr so that we have enough information about the array?

134

Can you add some comments for the code above? Or add a code snippet to what the generated code would look like in LLVM IR.

ftynse requested changes to this revision.May 4 2021, 2:31 PM
ftynse added inline comments.
mlir/lib/Target/LLVMIR/Dialect/OpenACC/OpenACCToLLVMIRTranslation.cpp
42

Please add comments for all top-level entities.

51

Is there a way to create a location from an arbitrary string? If so, we could print mlir::Location to a string stream and use that instead of the default location.

52

Nit: spurious semicolon

112

Nit: expand auto (we generally do this unless the type is long/irrepresentable or obvious from context)

115

This shouldn't just assume every LLVM struct used to be a memref, nothing guarantees that. I also expect the translation to work if the IR haven't ever had memrefs in it, i.e. translation shouldn't be aware of this type. If you really want to work with memrefs, this should start from openacc operations working on memrefs and lower them to openacc operations working on LLVM dialect types.

Also, this variable isn't used.

This revision now requires changes to proceed.May 4 2021, 2:31 PM
ftynse added a comment.May 4 2021, 2:33 PM

I think the layering here is incorrect. It assumes translation has knowledge of higher-level types (memref), which defies the purpose of having LLVM dialect. Translation should only know about LLVM-level dialects.

clementval updated this revision to Diff 342915.May 4 2021, 5:23 PM
clementval marked 4 inline comments as done.

Address some review comments

I think the layering here is incorrect. It assumes translation has knowledge of higher-level types (memref), which defies the purpose of having LLVM dialect. Translation should only know about LLVM-level dialects.

Thanks for the review.

I was also thinking something is odd here. I think a better approach would be to have a conversion that handle higher-level types with their knowledge and convert that to LLVM dialect in a form that is understandable by the translation. Would it makes sense to you?

mlir/lib/Target/LLVMIR/Dialect/OpenACC/OpenACCToLLVMIRTranslation.cpp
51

Yes there is. Just updated the patch to reflect that.

115

That was my understanding. I guess the final for should be a mix between this patch and my first attempt (D100678) where I did a conversion from OpenACC to LLVM dialect types.

Would it make sense to have a conversion that prepare the types from memref or from FIR types for examples and "format" them to LLVM dialect types (ptr + size) that can then be translated here to LLVM IR?

ftynse added a comment.May 5 2021, 1:02 AM

I think the layering here is incorrect. It assumes translation has knowledge of higher-level types (memref), which defies the purpose of having LLVM dialect. Translation should only know about LLVM-level dialects.

Thanks for the review.

I was also thinking something is odd here. I think a better approach would be to have a conversion that handle higher-level types with their knowledge and convert that to LLVM dialect in a form that is understandable by the translation. Would it makes sense to you?

This makes sense to me. OpenMP dialect has a similar approach where it can be expressed on higher-level types and a conversion pass converts those types to LLVM dialect types without otherwise changing the operations. Mind the potential difference in memref representation: if there are memref dialect ops inside OpenACC dialect ops, those would expect memref to be converted to the descriptor structure. If OpenACC converts memref to something different, it would have to recreated the expected descriptor structure at region entry so that other operations could still use it. We do this at function calls for the "bare pointer" convention.

You may also consider having a custom type in the OpenACC dialect that captures the necessary information (pointer + size, from what I understand) and auxiliary operations that "cast" from supported types to this custom type. Such a cast from memref to pointer+size could be then converted to the LLVM dialect by emitting IR that computes the size given the memref descriptor.

ftynse requested changes to this revision.May 5 2021, 1:03 AM

Re-requesting changes to that this disappears from my phabricator "todo" list until there are further comments. It's a shame that phabricator doesn't just let me snooze a review until other people act on it.

This revision now requires changes to proceed.May 5 2021, 1:03 AM

Update code to translate from converted types (D102170)

ftynse added inline comments.May 11 2021, 1:37 AM
mlir/lib/Target/LLVMIR/Dialect/OpenACC/OpenACCToLLVMIRTranslation.cpp
214

Ultra-nit: capitalize the first letter please.

mlir/test/Target/LLVMIR/openacc-llvm.mlir
2

I'd rather start from the LLVM dialect, running two tools makes this more of an integration test than a unit test: we won't know which of the tools is broken just by looking at it. It's okay to also have integration tests, but they shouldn't replace unit tests.

Also, I see quite some LLVM IR instructions being created but not tested. Are those moving to the OpenMPIRBuilder?

clementval marked 4 inline comments as done.

Address review comment.

mlir/test/Target/LLVMIR/openacc-llvm.mlir
2

Makes sense. I have updated the test to run just the translation from LLVM dialect and added the generated instructions as well.

clementval marked an inline comment as done.May 11 2021, 12:08 PM
clementval added inline comments.
mlir/lib/Target/LLVMIR/Dialect/OpenACC/OpenACCToLLVMIRTranslation.cpp
114

As you said, Flang is likely not using memref. The idea is to have a similar conversion where we extract information from the array descriptor and place it into the "Data descriptor". This descriptor is then translated.

Simple llvm.ptr can also be translated but this unlikely to come from a Fortran array at this point. I'll also add llvm.array in follow up patches.

clementval marked an inline comment as done.

Address some more review comments

clementval marked an inline comment as done.May 11 2021, 6:24 PM
ftynse accepted this revision.May 12 2021, 12:15 AM
This revision is now accepted and ready to land.May 12 2021, 12:15 AM
clementval marked an inline comment as done.May 12 2021, 8:40 AM
clementval added inline comments.
mlir/lib/Target/LLVMIR/Dialect/OpenACC/OpenACCToLLVMIRTranslation.cpp
173

I'll do that in a follow up patch since the version in clang cannot be directly done within the OpenMPIRbuilder as is.