- Notifications
You must be signed in to change notification settings - Fork 14.9k
[mlir][python] Add bindings for OpenACC dialect #163620
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
[mlir][python] Add bindings for OpenACC dialect #163620
Conversation
@llvm/pr-subscribers-mlir-openacc @llvm/pr-subscribers-mlir Author: Asher Mancinelli (ashermancinelli) ChangesAdds initial support for Python bindings to the OpenACC dialect.
Full diff: https://github.com/llvm/llvm-project/pull/163620.diff 4 Files Affected:
diff --git a/mlir/python/CMakeLists.txt b/mlir/python/CMakeLists.txt index 9f5246de6bda0..c643d32e22174 100644 --- a/mlir/python/CMakeLists.txt +++ b/mlir/python/CMakeLists.txt @@ -134,6 +134,15 @@ declare_mlir_dialect_python_bindings( dialects/func.py DIALECT_NAME func) +declare_mlir_dialect_python_bindings( + ADD_TO_PARENT MLIRPythonSources.Dialects + ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir" + TD_FILE dialects/OpenACCOps.td + SOURCES + dialects/openacc.py + DIALECT_NAME acc + DEPENDS acc_common_td) + declare_mlir_dialect_python_bindings( ADD_TO_PARENT MLIRPythonSources.Dialects ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir" diff --git a/mlir/python/mlir/dialects/OpenACCOps.td b/mlir/python/mlir/dialects/OpenACCOps.td new file mode 100644 index 0000000000000..69a3002e73b81 --- /dev/null +++ b/mlir/python/mlir/dialects/OpenACCOps.td @@ -0,0 +1,14 @@ +//===-- OpenACCOps.td - Entry point for OpenACCOps bind ------------*- tablegen -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef PYTHON_BINDINGS_OPENACC_OPS +#define PYTHON_BINDINGS_OPENACC_OPS + +include "mlir/Dialect/OpenACC/OpenACCOps.td" + +#endif diff --git a/mlir/python/mlir/dialects/openacc.py b/mlir/python/mlir/dialects/openacc.py new file mode 100644 index 0000000000000..e06830a9c48f3 --- /dev/null +++ b/mlir/python/mlir/dialects/openacc.py @@ -0,0 +1,6 @@ +# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +# See https://llvm.org/LICENSE.txt for license information. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +from ._acc_ops_gen import * + diff --git a/mlir/test/python/dialects/openacc.py b/mlir/test/python/dialects/openacc.py new file mode 100644 index 0000000000000..bd607febe21cc --- /dev/null +++ b/mlir/test/python/dialects/openacc.py @@ -0,0 +1,138 @@ +# RUN: python %s | FileCheck %s +from mlir.ir import ( + Context, + FunctionType, + Location, + Module, + InsertionPoint, + IntegerType, + IndexType, + MemRefType, + F32Type, + Block, + ArrayAttr, + Attribute, + UnitAttr, + StringAttr, + DenseI32ArrayAttr, + ShapedType, +) +from mlir.dialects import openacc, func, arith, memref + + +def run(f): + print("\n// TEST:", f.__name__) + with Context(), Location.unknown(): + f() + return f + + +@run +def testManualReconstructedKernel(): + module = Module.create() + + # Add required module attributes + module.operation.attributes["dlti.dl_spec"] = Attribute.parse("#dlti.dl_spec<>") + module.operation.attributes["gpu.container_module"] = UnitAttr.get() + + i32 = IntegerType.get_signless(32) + i64 = IntegerType.get_signless(64) + f32 = F32Type.get() + dynamic = ShapedType.get_dynamic_size() + memref_f32_1d_any = MemRefType.get([dynamic], f32) + + with InsertionPoint(module.body): + function_type = FunctionType.get( + [memref_f32_1d_any, memref_f32_1d_any, i64], [] + ) + f = func.FuncOp( + type=function_type, + name="memcpy_idiom", + ) + f.attributes["sym_visibility"] = StringAttr.get("public") + + with InsertionPoint(f.add_entry_block()): + c1024 = arith.ConstantOp(i32, 1024) + c128 = arith.ConstantOp(i32, 128) + + parallel_op = openacc.ParallelOp( + asyncOperands=[], + waitOperands=[], + numGangs=[c1024], + numWorkers=[], + vectorLength=[c128], + reductionOperands=[], + privateOperands=[], + firstprivateOperands=[], + dataClauseOperands=[], + ) + + # Set required device_type and segment attributes to satisfy verifier + acc_device_none = ArrayAttr.get([Attribute.parse("#acc.device_type<none>")]) + parallel_op.numGangsDeviceType = acc_device_none + parallel_op.numGangsSegments = DenseI32ArrayAttr.get([1]) + parallel_op.vectorLengthDeviceType = acc_device_none + + parallel_block = Block.create_at_start(parent=parallel_op.region, arg_types=[]) + + with InsertionPoint(parallel_block): + c0 = arith.ConstantOp(i64, 0) + c1 = arith.ConstantOp(i64, 1) + + loop_op = openacc.LoopOp( + results_=[], + lowerbound=[c0], + upperbound=[f.arguments[2]], + step=[c1], + gangOperands=[], + workerNumOperands=[], + vectorOperands=[], + tileOperands=[], + cacheOperands=[], + privateOperands=[], + reductionOperands=[], + firstprivateOperands=[], + ) + + # Set loop attributes: gang and independent on device_type<none> + acc_device_none = ArrayAttr.get([Attribute.parse("#acc.device_type<none>")]) + loop_op.gang = acc_device_none + loop_op.independent = acc_device_none + + loop_block = Block.create_at_start(parent=loop_op.region, arg_types=[i64]) + + with InsertionPoint(loop_block): + idx0 = arith.index_cast( + out=IndexType.get(), in_=loop_block.arguments[0] + ) + val = memref.load(memref=f.arguments[1], indices=[idx0]) + idx1 = arith.index_cast( + out=IndexType.get(), in_=loop_block.arguments[0] + ) + memref.store(value=val, memref=f.arguments[0], indices=[idx1]) + openacc.YieldOp([]) + + openacc.YieldOp([]) + + func.ReturnOp([]) + + print(module) + + # CHECK-LABEL: func.func public @memcpy_idiom + # CHECK-SAME: (%[[ARG0:.*]]: memref<?xf32>, %[[ARG1:.*]]: memref<?xf32>, %[[ARG2:.*]]: i64) { + # CHECK: %[[CONSTANT_0:.*]] = arith.constant 1024 : i32 + # CHECK: %[[CONSTANT_1:.*]] = arith.constant 128 : i32 + # CHECK: acc.parallel num_gangs({%[[CONSTANT_0]] : i32}) vector_length(%[[CONSTANT_1]] : i32) { + # CHECK: %[[CONSTANT_2:.*]] = arith.constant 0 : i64 + # CHECK: %[[CONSTANT_3:.*]] = arith.constant 1 : i64 + # CHECK: acc.loop gang control(%[[VAL_0:.*]] : i64) = (%[[CONSTANT_2]] : i64) to (%[[ARG2]] : i64) step (%[[CONSTANT_3]] : i64) { + # CHECK: %[[INDEX_CAST_0:.*]] = arith.index_cast %[[VAL_0]] : i64 to index + # CHECK: %[[LOAD_0:.*]] = memref.load %[[ARG1]][%[[INDEX_CAST_0]]] : memref<?xf32> + # CHECK: %[[INDEX_CAST_1:.*]] = arith.index_cast %[[VAL_0]] : i64 to index + # CHECK: memref.store %[[LOAD_0]], %[[ARG0]][%[[INDEX_CAST_1]]] : memref<?xf32> + # CHECK: acc.yield + # CHECK: } + # CHECK: acc.yield + # CHECK: } + # CHECK: return + # CHECK: } |
✅ With the latest revision this PR passed the Python code formatter. |
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.
Looks good. I just left minor comments
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.
Thank you Asher!
Also, do you know what is the process of maintaining and testing the bindings? Let's say I update the builders in acc dialect, do I need to do anything special? Will the python tests automatically be exercised when I build MLIR normally?
No, you'll need to enable the python bindings for the tests to run - let's chat offline. I believe the builders should catch big stuff in the usual LLVM CI though. Thanks for the review! |
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/116/builds/19787 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/177/builds/22718 Here is the relevant piece of the build log for the reference
|
Investigating |
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/138/builds/20517 Here is the relevant piece of the build log for the reference
|
This test passed locally because I had a python environment with the `python` command available, but I should have used the `%PYTHON` lit command substitution instead. Fixes buildbot failures from #163620.
We're seeing a build error with this test: exit status 2 |
@cmtice Thanks for reporting! Is there a buildbot or log I can look at? I'm surprised you can't find the |
Adds initial support for Python bindings to the OpenACC dialect.