From 389723dc53eec27d1707eabce33ab9306ec9f8f4 Mon Sep 17 00:00:00 2001 From: abisca Date: Wed, 6 Sep 2023 07:58:03 -0600 Subject: [PATCH 1/9] Add simple test using MLIR generated python bindings. --- test/python/simple.py | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 test/python/simple.py diff --git a/test/python/simple.py b/test/python/simple.py new file mode 100644 index 0000000000..3252751119 --- /dev/null +++ b/test/python/simple.py @@ -0,0 +1,41 @@ +# Copyright (C) 2023, Advanced Micro Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +# module { +# %0 = AIE.tile(1, 4) +# %1 = AIE.buffer(%0) : memref<256xi32> +# %2 = AIE.core(%0) { +# ^bb0(%arg0: index): +# %c14_i32 = arith.constant 14 : i32 +# %c3 = arith.constant 3 : index +# memref.store %c14_i32, %1[%c3] : memref<256xi32> +# AIE.end +# } +#} + +import aie +from aie.mlir.ir import * +from aie.dialects import aie as aiedialect +from aie.mlir.dialects import arith +from aie.mlir.dialects import memref + +with Context() as ctx, Location.unknown(): + aiedialect.register_dialect(ctx) + module = Module.create() + with InsertionPoint(module.body): + int_ty = IntegerType.get_signless(32) + idx_ty = IndexType.get() + memRef_ty = MemRefType.get((256,), int_ty) + + T = aiedialect.TileOp(idx_ty, IntegerAttr.get(int_ty, 1), IntegerAttr.get(int_ty, 4)) + buff = aiedialect.BufferOp(memRef_ty, T) + + C = aiedialect.CoreOp(idx_ty, T) + C.body.blocks.append(idx_ty) + with InsertionPoint(C.body.blocks[0]): + val = arith.ConstantOp(int_ty, IntegerAttr.get(int_ty, 14)) + idx = arith.ConstantOp(idx_ty, IntegerAttr.get(idx_ty, 3)) + memref.StoreOp(val, buff, idx) + aiedialect.EndOp() + +print(module) From cbfe335738d0eb8e4291cc0abb95198ac914fe64 Mon Sep 17 00:00:00 2001 From: abisca Date: Fri, 3 Nov 2023 10:04:20 -0600 Subject: [PATCH 2/9] Add AIE dialect python bindings as well as some util bindings. Add tests. --- include/aie/Dialect/AIE/IR/AIEOps.td | 12 +- .../AIEObjectFifoStatefulTransform.cpp | 6 +- .../AIEX/Transforms/AIECreateCores.cpp | 9 +- python/CMakeLists.txt | 2 + python/dialects/_AIE_syntax.py | 257 ++++++++++++++++++ python/dialects/_AIE_util.py | 169 ++++++++++++ python/dialects/aie.py | 4 +- test/python/aie_ops.py | 184 ++++++++++--- test/python/codeRegion.py | 56 ++++ test/python/core_ext_kernel.py | 63 +++++ test/python/objFifo.py | 46 ++++ test/python/objFifo_link.py | 40 +++ test/python/simple.py | 41 --- test/python/simple_with_bindings.py | 39 +++ 14 files changed, 830 insertions(+), 98 deletions(-) create mode 100644 python/dialects/_AIE_syntax.py create mode 100644 python/dialects/_AIE_util.py create mode 100644 test/python/codeRegion.py create mode 100644 test/python/core_ext_kernel.py create mode 100644 test/python/objFifo.py create mode 100644 test/python/objFifo_link.py delete mode 100644 test/python/simple.py create mode 100644 test/python/simple_with_bindings.py diff --git a/include/aie/Dialect/AIE/IR/AIEOps.td b/include/aie/Dialect/AIE/IR/AIEOps.td index 7305d7a676..c33ee21f41 100644 --- a/include/aie/Dialect/AIE/IR/AIEOps.td +++ b/include/aie/Dialect/AIE/IR/AIEOps.td @@ -304,7 +304,8 @@ def AIE_CoreOp: AIE_Op<"core", [ ]>, Results<(outs Index)> { let arguments = ( ins Index:$tile, - DefaultValuedAttr:$stackSize + DefaultValuedAttr:$stackSize, + OptionalAttr:$link_with ); let summary = "Declare a core module"; let description = [{ @@ -1159,7 +1160,12 @@ def AIE_BufferOp: AIE_Op<"buffer", [ ``` This operation represents a buffer in tile (3, 3) of 256 elements, each a 64-bit integer. }]; - let arguments = (ins Index:$tile); + + let arguments = ( + ins Index:$tile, + OptionalAttr:$sym_name + ); + let results = (outs AnyMemRef:$buffer); let assemblyFormat = [{ `(` $tile `)` attr-dict `:` type($buffer) }]; let hasVerifier = 1; @@ -1213,6 +1219,8 @@ def AIE_ExternalBufferOp: AIE_Op<"external_buffer", []>, Results<(outs AnyMemRef This operation represents an external buffer. }]; + let arguments = (ins OptionalAttr:$sym_name); + let results = (outs AnyMemRef:$buffer); let assemblyFormat = [{ attr-dict `:` type($buffer) }]; diff --git a/lib/Dialect/AIE/Transforms/AIEObjectFifoStatefulTransform.cpp b/lib/Dialect/AIE/Transforms/AIEObjectFifoStatefulTransform.cpp index a7daf18548..a23b54f2b1 100644 --- a/lib/Dialect/AIE/Transforms/AIEObjectFifoStatefulTransform.cpp +++ b/lib/Dialect/AIE/Transforms/AIEObjectFifoStatefulTransform.cpp @@ -409,10 +409,8 @@ struct AIEObjectFifoStatefulTransformPass // if shimTile external buffers are collected from input code // create as many locks as there are external buffers if (!creation_tile.isShimTile()) { - BufferOp buff = builder.create(builder.getUnknownLoc(), - elemType, creation_tile); - buff.getOperation()->setAttr( - mlir::SymbolTable::getSymbolAttrName(), + BufferOp buff = builder.create( + builder.getUnknownLoc(), elemType, creation_tile, builder.getStringAttr(op.name().str() + "_buff_" + std::to_string(of_elem_index))); buffers.push_back(buff); diff --git a/lib/Dialect/AIEX/Transforms/AIECreateCores.cpp b/lib/Dialect/AIEX/Transforms/AIECreateCores.cpp index c72e9c4842..92aff3b0ec 100644 --- a/lib/Dialect/AIEX/Transforms/AIECreateCores.cpp +++ b/lib/Dialect/AIEX/Transforms/AIECreateCores.cpp @@ -123,10 +123,8 @@ struct AIECreateCoresPass : public AIECreateCoresBase { assert(t && "Unsupported type!"); coreBufTypes.push_back({t, i}); - BufferOp buf = - builder.create(builder.getUnknownLoc(), t, tile); - // buf.setAttr("sym_name", - // builder.getStringAttr("test_name")); + BufferOp buf = builder.create(builder.getUnknownLoc(), t, + tile, nullptr); buffers[callOperands[i]] = buf; operand.replaceAllUsesWith(buf.getResult()); } @@ -157,8 +155,7 @@ struct AIECreateCoresPass : public AIECreateCoresBase { Block *currentBlock; if (!cores[tileOp]) { - core = builder.create(builder.getUnknownLoc(), - builder.getIndexType(), tile); + core = builder.create(builder.getUnknownLoc(), tile); Region &r = core.getBody(); currentBlock = builder.createBlock(&r); builder.setInsertionPointToStart(currentBlock); diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index d5f121f9ee..ed0718f250 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -31,6 +31,8 @@ declare_mlir_dialect_python_bindings( TD_FILE dialects/AIEBinding.td SOURCES dialects/aie.py + dialects/_AIE_syntax.py + dialects/_AIE_util.py DIALECT_NAME AIE ) diff --git a/python/dialects/_AIE_syntax.py b/python/dialects/_AIE_syntax.py new file mode 100644 index 0000000000..a1ff8671c2 --- /dev/null +++ b/python/dialects/_AIE_syntax.py @@ -0,0 +1,257 @@ +from ._AIE_ops_gen import * +from ._AIE_util import * +from .._mlir_libs._aieMlir import register_dialect, ObjectFifoType, ObjectFifoSubviewType + + +# Helper function that returns the index of a named objectFifo port. +def objectFifoPortToIndex(port): + port_index = -1 + if (port == "Produce"): + port_index = 0 + elif (port == "Consume"): + port_index = 1 + else: + port_index = -1 + return port_index + + +# Helper function that returns the index of a named WireBundle. +def wireBundleToIndex(port): + port_index = -1 + if (port == "Core"): + port_index = 0 + elif (port == "DMA"): + port_index = 1 + elif (port == "FIFO"): + port_index = 2 + elif (port == "South"): + port_index = 3 + elif (port == "West"): + port_index = 4 + elif (port == "North"): + port_index = 5 + elif (port == "East"): + port_index = 6 + elif (port == "PLIO"): + port_index = 7 + elif (port == "NOC"): + port_index = 8 + elif (port == "Trace"): + port_index = 9 + else: + port_index = -1 + return port_index + + +def dim_tuple_attr_builder(wrap, stepsize): + return Attribute.parse(f"#AIE.DimTuple<{wrap}, {stepsize}>") + + +@register_attribute_builder("AIE_DimTupleArrayAttr") +def dim_tuple_array_attr_builder(tups: List[tuple], context=None): + tups = list(map(lambda t: dim_tuple_attr_builder(*t), tups)) + return Attribute.parse( + f'#AIE', context=context + ) + + +@register_attribute_builder("AIE_DimTupleArrayArrayAttr") +def dim_tuple_array_array_attr_builder(tup_arrs: List[List[tuple]], context=None): + tup_arrs = list(map(dim_tuple_array_attr_builder, tup_arrs)) + return Attribute.parse( + f'#AIE', context=context + ) + + +#### AIE Wrappers #### + + +# Create and print ModuleOp. +def constructAndPrintInModule(f): + with Context() as ctx, Location.unknown(): + register_dialect(ctx) + module = Module.create() + with InsertionPoint(module.body): + f() + print(module) + + +# Create an aie device on specified target architecture. +class Device(DeviceOp): + """Specialize DeviceOp class constructor to take python integers""" + def __init__(self, device): + index = 0 + if (device == "xcvc1902"): + index = 1 + elif (device == "xcve2302"): + index = 2 + elif (device == "xcve2802"): + index = 3 + elif (device == "ipu"): + index = 4 + else: + index = device + iTy = IntegerType.get_signless(32) + intDevice = IntegerAttr.get(iTy, index) + super().__init__(device=intDevice) + + +# Create an aie tile on specified (col, row). +class Tile(TileOp): + """Specialize TileOp class constructor to take python integers""" + def __init__(self, col, row): + idx_ty = IndexType.get() + super().__init__(result=idx_ty, col=col, row=row) + + +# Create an aie core on specified aie tile. +class Core(CoreOp): + """Specialize CoreOp class constructor to take python integers""" + def __init__(self, tile, link_with=None): + idx_ty = IndexType.get() + if (link_with != None): + super().__init__(result=idx_ty, tile=tile, link_with=link_with) + else : + super().__init__(result=idx_ty, tile=tile) + + +# Create an aie buffer of (size x datatype) on given tile. +# size examples: [256], [256, 256], [256, 256,] +class Buffer(BufferOp): + """Specialize BufferOp class constructor to take python integers""" + def __init__(self, tile, size, datatype, name=None): + memRef_ty = MemRefType.get(size, datatype) + if name is None: + super().__init__(buffer=memRef_ty, tile=tile) + else: + super().__init__(buffer=memRef_ty, tile=tile, sym_name=name) + + +# Create an aie external buffer of (size x datatype). +# size examples: [256], [256, 256], [256, 256,] +class ExternalBuffer(ExternalBufferOp): + """Specialize ExternalBufferOp class constructor to take python integers""" + def __init__(self, size, datatype, name=None): + memRef_ty = MemRefType.get(size, datatype) + if name is None: + super().__init__(buffer=memRef_ty) + super().__init__(buffer=memRef_ty, sym_name=name) + + +# Create an aie objectFifo between specified tiles, with given depth and memref datatype. +# depth examples: 2, [2,2,7] +class OrderedObjectBuffer(ObjectFifoCreateOp): + """Specialize ObjectFifoCreateOp class constructor to take python integers""" + def __init__(self, name, tile0, tile1, depth, datatype, dimensionsToStream = [], dimensionsFromStreamPerConsumer = []): + int_ty = IntegerType.get_signless(32) + if isinstance(depth, int): + int_depth = IntegerAttr.get(int_ty, depth) + else: + int_depths = [] + for d in depth: + int_depths.append(IntegerAttr.get(int_ty, d)) + int_depth = ArrayAttr.get(int_depths) + of_Ty = ObjectFifoType.get(datatype) + super().__init__( + sym_name=name, + producerTile=tile0, + consumerTiles=tile1, + elemNumber=int_depth, + elem_type=TypeAttr.get(of_Ty), + dimensionsToStream=dimensionsToStream, + dimensionsFromStreamPerConsumer=dimensionsFromStreamPerConsumer + ) + + +# Create an aie objectFifo link op between specified input and output arrays of objFifos. +class Link(ObjectFifoLinkOp): + """Specialize ObjectFifoLinkOp class constructor to take python integers""" + def __init__(self, ofIns, ofOuts): + ofIns_sym = [] + ofOuts_sym = [] + for o in ofIns: + ofIns_sym.append(FlatSymbolRefAttr.get(o)) + for o in ofOuts: + ofOuts_sym.append(FlatSymbolRefAttr.get(o)) + ofIns_array = ArrayAttr.get(ofIns_sym) + ofOuts_array = ArrayAttr.get(ofOuts_sym) + super().__init__(fifoIns=ofIns_array, fifoOuts=ofOuts_array) + + +# Create an aie objectFifo acquire op of given number of elements with given memref datatype, +# from objFifo with given name. +class Acquire(ObjectFifoAcquireOp): + """Specialize ObjectFifoAcquireOp class constructor to take python integers""" + def __init__(self, of_name, port, num_elem, datatype): + of_sym = FlatSymbolRefAttr.get(of_name) + int_ty = IntegerType.get_signless(32) + int_port = IntegerAttr.get(int_ty, objectFifoPortToIndex(port)) + subview_Ty = ObjectFifoSubviewType.get(datatype) + self.datatype = datatype + super().__init__(subview=subview_Ty, port=int_port, objFifo_name=of_sym, size=num_elem) + + def acquiredElem(self): + objects = [] + if self.size.value == 1: + return SubviewAccess(self.subview, self.size.value - 1, self.datatype) + for i in range(self.size.value): + objects.append(SubviewAccess(self.subview, i, self.datatype)) + return objects + + +# Create an aie objectFifo access op on given subview with given memref datatype, +# at given index. +class SubviewAccess(ObjectFifoSubviewAccessOp): + """Rename ObjectFifoSubviewAccessOp class""" + def __init__(self, subview, index, datatype): + super().__init__(output=datatype, subview=subview, index=index) + + +# Create an aie objectFifo release op of given number of elements from objFifo with given name. +class Release(ObjectFifoReleaseOp): + """Specialize ObjectFifoReleaseOp class constructor to take python integers""" + def __init__(self, of_name, port, num_elem): + of_sym = FlatSymbolRefAttr.get(of_name) + int_ty = IntegerType.get_signless(32) + int_port = IntegerAttr.get(int_ty, objectFifoPortToIndex(port)) + super().__init__(port=int_port, objFifo_name=of_sym, size=num_elem) + + +# Create a flow between source and destination tile ports. +class Flow(FlowOp): + """Specialize FlowOp class constructor to take python integers""" + def __init__(self, source, source_port, source_channel, dest, dest_port, dest_channel): + int_ty = IntegerType.get_signless(32) + sourceBundle = IntegerAttr.get(int_ty, wireBundleToIndex(source_port)) + destBundle = IntegerAttr.get(int_ty, wireBundleToIndex(dest_port)) + super().__init__( + source=source, + sourceBundle=sourceBundle, + sourceChannel=source_channel, + dest=dest, + destBundle=destBundle, + destChannel=dest_channel + ) + + +# Create a packet flow between source and destination tile ports. +class PacketFlow(PacketFlowOp): + """Specialize PacketFlowOp class constructor to take python integers""" + def __init__(self, pkt_id, source, source_port, source_channel, dest, dest_port, dest_channel): + int8_ty = IntegerType.get_signless(8) + int_ty = IntegerType.get_signless(32) + int8_pkt_id = IntegerAttr.get(int8_ty, pkt_id) + sourceBundle = IntegerAttr.get(int_ty, wireBundleToIndex(source_port)) + destBundle = IntegerAttr.get(int_ty, wireBundleToIndex(dest_port)) + super().__init__(ID=int8_pkt_id) + bb = Block.create_at_start(self.ports) + with InsertionPoint(bb): + src = PacketSourceOp(source, sourceBundle, source_channel) + dest = PacketDestOp(dest, destBundle, dest_channel) + end = EndOp() + + +#### Global Wrappers #### +core = region_op(Core, terminator=lambda *args: EndOp()) +device = region_op(Device) +forLoop = region_op(For, terminator=lambda *args: YieldOp([])) diff --git a/python/dialects/_AIE_util.py b/python/dialects/_AIE_util.py new file mode 100644 index 0000000000..c2e32c0e47 --- /dev/null +++ b/python/dialects/_AIE_util.py @@ -0,0 +1,169 @@ +import inspect +from functools import wraps + +from ..ir import * +from ..dialects import arith +from ..dialects import memref +from ..dialects.func import * +from ..dialects.scf import * + + +# Create a signless arith constant of given width (default is i32). +class integerConstant(arith.ConstantOp): + """Specialize ConstantOp class constructor to take python integers""" + def __init__(self, val, width = 32): + if isinstance(width, int): + int_ty = IntegerType.get_signless(width) + else: + int_ty = width + intAttr = IntegerAttr.get(int_ty, val) + super().__init__(result=int_ty, value=intAttr) + + +# Create an index arith constant. +class indexConstant(arith.ConstantOp): + """Specialize ConstantOp class constructor to take python integers""" + def __init__(self, val): + idx_ty = IndexType.get() + idxAttr = IntegerAttr.get(idx_ty, val) + super().__init__(result=idx_ty, value=idxAttr) + + +class AddI(arith.AddIOp): + """Specialize AddIOp class constructor to take python integers""" + def __init__(self, lhs, rhs): + if isinstance(lhs, int): + intLhs = integerConstant(lhs) + else: + intLhs = lhs + intRhs = integerConstant(rhs) + super().__init__(lhs=intLhs, rhs=intRhs) + + +class For(ForOp): + """Specialize ForOp class constructor to take python integers""" + def __init__(self, lowerBound, upperBound, step): + idxLowerBound = indexConstant(lowerBound) + idxUpperBound = indexConstant(upperBound) + idxStep = indexConstant(step) + super().__init__(lower_bound=idxLowerBound, upper_bound=idxUpperBound, step=idxStep) + + +# Wrapper for func FuncOp with "private" visibility. +class privateFunc(FuncOp): + """Specialize FuncOp class constructor to take python integers""" + def __init__(self, name, inputs, outputs = [], visibility = "private"): + super().__init__( + name=name, + type=FunctionType.get(inputs, outputs), + visibility=visibility + ) + + +# Wrapper for func FuncOp with "private" visibility. +class publicFunc(FuncOp): + """Specialize FuncOp class constructor to take python integers""" + def __init__(self, name, callbackFunc, inputs, outputs = [], visibility = "public"): + super().__init__( + name=name, + type=FunctionType.get(inputs, outputs), + visibility=visibility, + body_builder=callbackFunc + ) + + +# Wrapper for func CallOp. +class Call(CallOp): + """Specialize CallOp class constructor to take python integers""" + def __init__(self, calleeOrResults, inputs = [], input_types = []): + attrInputs = [] + for i in inputs: + if isinstance(i, int): + attrInputs.append(integerConstant(i)) + else: + attrInputs.append(i) + if isinstance(calleeOrResults, FuncOp): + super().__init__(calleeOrResults=calleeOrResults, argumentsOrCallee=attrInputs) + else: + super().__init__( + calleeOrResults=input_types, + argumentsOrCallee=FlatSymbolRefAttr.get(calleeOrResults), + arguments=attrInputs + ) + + +class Load(memref.LoadOp): + """Specialize LoadOp class constructor to take python integers""" + def __init__(self, mem, indices): + valueIndices = [] + if isinstance(indices, list): + for i in indices: + valueIndices.append(indexConstant(i)) + else: + valueIndices.append(indexConstant(indices)) + super().__init__(memref=mem, indices=valueIndices) + + +class Store(memref.StoreOp): + """Specialize StoreOp class constructor to take python integers""" + def __init__(self, val, mem, indices): + if isinstance(val, int): + intVal = integerConstant(val) + else: + intVal = val + valueIndices = [] + if isinstance(indices, list): + for i in indices: + valueIndices.append(indexConstant(i)) + else: + valueIndices.append(indexConstant(indices)) + super().__init__(value=intVal, memref=mem, indices=valueIndices) + + +def op_region_builder(op, op_region, terminator=None): + def builder_wrapper(body_builder): + # add a block with block args having types ... + if len(op_region.blocks) == 0: + sig = inspect.signature(body_builder) + types = [p.annotation for p in sig.parameters.values()] + if not ( + len(types) == len(sig.parameters) + and all(isinstance(t, Type) for t in types) + ): + raise ValueError( + f"for {body_builder=} either missing a type annotation or type annotation isn't a mlir type: {sig}" + ) + op_region.blocks.append(*types) + with InsertionPoint(op_region.blocks[0]): + results = body_builder() + if terminator is not None: + res = [] + if isinstance(results, (tuple, list)): + res.extend(results) + elif results is not None: + res.append(results) + terminator(res) + + return op + + return builder_wrapper + + +def region_op(op_constructor, terminator=None): + # the decorator itself + def op_decorator(*args, **kwargs): + op = op_constructor(*args, **kwargs) + op_region = op.regions[0] + + return op_region_builder(op, op_region, terminator) + + # this is like make_maybe_no_args_decorator but a little different because the decorators here + # are already wrapped (or something like that) + @wraps(op_decorator) + def maybe_no_args(*args, **kwargs): + if len(args) == 1 and len(kwargs) == 0 and callable(args[0]): + return op_decorator()(args[0]) + else: + return op_decorator(*args, **kwargs) + + return maybe_no_args diff --git a/python/dialects/aie.py b/python/dialects/aie.py index 107caf8a61..b79637c044 100644 --- a/python/dialects/aie.py +++ b/python/dialects/aie.py @@ -4,4 +4,6 @@ # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception from ._AIE_ops_gen import * -from .._mlir_libs._aieMlir import * \ No newline at end of file +from ._AIE_syntax import * +from ._AIE_util import * +from .._mlir_libs._aieMlir import * diff --git a/test/python/aie_ops.py b/test/python/aie_ops.py index bd19a5a0ba..84aff48859 100644 --- a/test/python/aie_ops.py +++ b/test/python/aie_ops.py @@ -7,8 +7,6 @@ from aie.ir import * from aie.dialects.aie import * -from typing import List - def constructAndPrintInModule(f): with Context() as ctx, Location.unknown(): @@ -24,10 +22,7 @@ def constructAndPrintInModule(f): # CHECK: AIE.tile(0, 0) @constructAndPrintInModule def tileOp(): - iTy = IntegerType.get_signless(32) - row = IntegerAttr.get(iTy, 0) - col = IntegerAttr.get(iTy, 0) - t = TileOp(IndexType.get(), col, row) + t = Tile(col=0, row=0) # CHECK-LABEL: coreOp @@ -37,11 +32,8 @@ def tileOp(): # CHECK: } @constructAndPrintInModule def coreOp(): - iTy = IntegerType.get_signless(32) - row = IntegerAttr.get(iTy, 1) - col = IntegerAttr.get(iTy, 1) - t = TileOp(IndexType.get(), col, row) - c = CoreOp(IndexType.get(), t) + t = Tile(col=1, row=1) + c = Core(t) bb = Block.create_at_start(c.body) with InsertionPoint(bb): EndOp() @@ -54,10 +46,7 @@ def coreOp(): # CHECK: } @constructAndPrintInModule def memOp(): - iTy = IntegerType.get_signless(32) - row = IntegerAttr.get(iTy, 2) - col = IntegerAttr.get(iTy, 2) - t = TileOp(IndexType.get(), col, row) + t = Tile(col=2, row=2) m = MemOp(IndexType.get(), t) bb = Block.create_at_start(m.body) with InsertionPoint(bb): @@ -68,32 +57,28 @@ def memOp(): # CHECK: AIE.device @constructAndPrintInModule def deviceOp(): - iTy = IntegerType.get_signless(32) - i = IntegerAttr.get(iTy, 1) - dev = DeviceOp(IntegerAttr.get(iTy, 1)) + dev = Device("xcvc1902") bb = Block.create_at_start(dev.bodyRegion) with InsertionPoint(bb): EndOp() -def dim_tuple_attr_builder(wrap, stepsize): - return Attribute.parse(f"#AIE.DimTuple<{wrap}, {stepsize}>") - - -@register_attribute_builder("AIE_DimTupleArrayAttr") -def dim_tuple_array_attr_builder(tups: List[tuple], context=None): - tups = list(map(lambda t: dim_tuple_attr_builder(*t), tups)) - return Attribute.parse( - f'#AIE', context=context - ) +# CHECK-LABEL: bufferOp +# CHECK: %[[VAL_0:.*]] = AIE.tile(0, 3) +# CHECK: %[[VAL_1:.*]] = AIE.buffer(%[[VAL_0]]) : memref<12xi32> +@constructAndPrintInModule +def bufferOp(): + iTy = IntegerType.get_signless(32) + t = Tile(col=0, row=3) + b = Buffer(tile=t, size=(12,), datatype=iTy) -@register_attribute_builder("AIE_DimTupleArrayArrayAttr") -def dim_tuple_array_array_attr_builder(tup_arrs: List[List[tuple]], context=None): - tup_arrs = list(map(dim_tuple_array_attr_builder, tup_arrs)) - return Attribute.parse( - f'#AIE', context=context - ) +# CHECK-LABEL: externalBufferOp +# CHECK: %[[VAL_0:.*]] = AIE.external_buffer : memref<12xi32> +@constructAndPrintInModule +def externalBufferOp(): + iTy = IntegerType.get_signless(32) + b = ExternalBuffer(size=(12,), datatype=iTy) # CHECK-LABEL: objFifo @@ -102,19 +87,130 @@ def dim_tuple_array_array_attr_builder(tup_arrs: List[List[tuple]], context=None # CHECK: AIE.objectFifo @of0(%[[VAL0]] toStream [<1, 2>], {%[[VAL1]] fromStream [<1, 2>]}, 2 : i32) : !AIE.objectFifo> @constructAndPrintInModule def objFifo(): - iTy = IntegerType.get_signless(32) - one = IntegerAttr.get(iTy, 1) - dev = DeviceOp(one) + dev = Device("xcvc1902") bb = Block.create_at_start(dev.bodyRegion) with InsertionPoint(bb): - two = IntegerAttr.get(iTy, 2) - six = IntegerAttr.get(iTy, 6) - tile0 = TileOp(IndexType.get(), six, six) - tile1 = TileOp(IndexType.get(), two, two) + tile0 = Tile(col=6, row=6) + tile1 = Tile(col=2, row=2) dtype = F16Type.get() memTy = MemRefType.get((12,), dtype) - ofTy = ObjectFifoType.get(memTy) - ObjectFifoCreateOp( - "of0", tile0, tile1, two, TypeAttr.get(ofTy), [(1, 2)], [[(1, 2)]] + OrderedObjectBuffer( + "of0", tile0, tile1, 2, memTy, [(1, 2)], [[(1, 2)]] ) EndOp() + + +# CHECK-LABEL: objFifoLink +# CHECK: %[[VAL_0:.*]] = AIE.tile(6, 6) +# CHECK: %[[VAL_1:.*]] = AIE.tile(2, 2) +# CHECK: %[[VAL_2:.*]] = AIE.tile(7, 7) +# CHECK: AIE.objectFifo @[[VAL_3:.*]](%[[VAL_0]], {%[[VAL_1]]}, 2 : i32) : !AIE.objectFifo> +# CHECK: AIE.objectFifo @[[VAL_4:.*]](%[[VAL_1]], {%[[VAL_2]]}, 2 : i32) : !AIE.objectFifo> +# CHECK: AIE.objectFifo.link [@[[VAL_3]]] -> [@[[VAL_4]]]() +@constructAndPrintInModule +def objFifoLink(): + dev = Device("xcvc1902") + bb = Block.create_at_start(dev.bodyRegion) + with InsertionPoint(bb): + tile0 = Tile(col=6, row=6) + tile1 = Tile(col=2, row=2) + tile2 = Tile(col=7, row=7) + dtype = F16Type.get() + memTy = MemRefType.get((12,), dtype) + OrderedObjectBuffer("of0", tile0, tile1, 2, memTy) + OrderedObjectBuffer("of1", tile1, tile2, 2, memTy) + Link(["of0"], ["of1"]) + EndOp() + + +# CHECK-LABEL: objFifoAcquire +# CHECK: %[[VAL_0:.*]] = AIE.tile(6, 6) +# CHECK: %[[VAL_1:.*]] = AIE.tile(2, 2) +# CHECK: AIE.objectFifo @[[VAL_2:.*]](%[[VAL_0]], {%[[VAL_1]]}, 2 : i32) : !AIE.objectFifo> +# CHECK: %[[VAL_3:.*]] = AIE.objectFifo.acquire @[[VAL_2]](Consume, 1) : !AIE.objectFifoSubview> +@constructAndPrintInModule +def objFifoAcquire(): + dev = Device("xcvc1902") + bb = Block.create_at_start(dev.bodyRegion) + with InsertionPoint(bb): + tile0 = Tile(col=6, row=6) + tile1 = Tile(col=2, row=2) + dtype = F16Type.get() + memTy = MemRefType.get((12,), dtype) + OrderedObjectBuffer("of0", tile0, tile1, 2, memTy) + C = Core(tile1) + bb = Block.create_at_start(C.body) + with InsertionPoint(bb): + acq = Acquire(of_name="of0", port="Consume", num_elem=1, datatype=memTy) + EndOp() + + +# CHECK-LABEL: objFifoSubviewAccess +# CHECK: %[[VAL_0:.*]] = AIE.tile(6, 6) +# CHECK: %[[VAL_1:.*]] = AIE.tile(2, 2) +# CHECK: AIE.objectFifo @[[VAL_2:.*]](%[[VAL_0]], {%[[VAL_1]]}, 2 : i32) : !AIE.objectFifo> +# CHECK: %[[VAL_3:.*]] = AIE.objectFifo.acquire @[[VAL_2]](Consume, 1) : !AIE.objectFifoSubview> +# CHECK: %[[VAL_4:.*]] = AIE.objectFifo.subview.access %[[VAL_3]][0] : !AIE.objectFifoSubview> -> memref<12xf16> +@constructAndPrintInModule +def objFifoSubviewAccess(): + dev = Device("xcvc1902") + bb = Block.create_at_start(dev.bodyRegion) + with InsertionPoint(bb): + tile0 = Tile(col=6, row=6) + tile1 = Tile(col=2, row=2) + dtype = F16Type.get() + memTy = MemRefType.get((12,), dtype) + OrderedObjectBuffer("of0", tile0, tile1, 2, memTy) + C = Core(tile1) + bb = Block.create_at_start(C.body) + with InsertionPoint(bb): + acq = Acquire(of_name="of0", port="Consume", num_elem=1, datatype=memTy) + subview = SubviewAccess(subview=acq, index=0, datatype=memTy) + EndOp() + + +# CHECK-LABEL: objFifoRelease +# CHECK: %[[VAL_0:.*]] = AIE.tile(6, 6) +# CHECK: %[[VAL_1:.*]] = AIE.tile(2, 2) +# CHECK: AIE.objectFifo @[[VAL_2:.*]](%[[VAL_0]], {%[[VAL_1]]}, 2 : i32) : !AIE.objectFifo> +# CHECK: AIE.objectFifo.release @[[VAL_2]](Produce, 1) +@constructAndPrintInModule +def objFifoRelease(): + dev = Device("xcvc1902") + bb = Block.create_at_start(dev.bodyRegion) + with InsertionPoint(bb): + tile0 = Tile(col=6, row=6) + tile1 = Tile(col=2, row=2) + dtype = F16Type.get() + memTy = MemRefType.get((12,), dtype) + OrderedObjectBuffer("of0", tile0, tile1, 2, memTy) + C = Core(tile0) + bb = Block.create_at_start(C.body) + with InsertionPoint(bb): + acq = Release(of_name="of0", port="Produce", num_elem=1) + EndOp() + + +# CHECK-LABEL: flowOp +# CHECK: %[[VAL_0:.*]] = AIE.tile(0, 0) +# CHECK: %[[VAL_1:.*]] = AIE.tile(0, 2) +# CHECK: AIE.flow(%[[VAL_1]], Trace : 0, %[[VAL_0]], DMA : 1) +@constructAndPrintInModule +def flowOp(): + S = Tile(0, 0) + T = Tile(0, 2) + Flow(T, "Trace", 0, S, "DMA", 1) + + +# CHECK-LABEL: packetFlowOp +# CHECK: %[[VAL_0:.*]] = AIE.tile(0, 0) +# CHECK: %[[VAL_1:.*]] = AIE.tile(0, 2) +# CHECK: AIE.packet_flow(0) { +# CHECK: AIE.packet_source<%[[VAL_1]], Trace : 0> +# CHECK: AIE.packet_dest<%[[VAL_0]], DMA : 1> +# CHECK: } +@constructAndPrintInModule +def packetFlowOp(): + S = Tile(0, 0) + T = Tile(0, 2) + PacketFlow(0, T, "Trace", 0, S, "DMA", 1) diff --git a/test/python/codeRegion.py b/test/python/codeRegion.py new file mode 100644 index 0000000000..1c569caf34 --- /dev/null +++ b/test/python/codeRegion.py @@ -0,0 +1,56 @@ +# Copyright (C) 2023, Advanced Micro Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +# RUN: %python %s | FileCheck %s + +from aie.ir import * +from aie.dialects.aie import * + +# CHECK: module { +# CHECK: AIE.device(xcve2802) { +# CHECK: func.func private @test_func(memref<8x8xi32>) -> i32 +# CHECK: %0 = AIE.tile(0, 2) +# CHECK: %1 = AIE.tile(1, 2) +# CHECK: %2 = AIE.tile(3, 3) +# CHECK: AIE.objectFifo @of0(%0, {%1}, 2 : i32) : !AIE.objectFifo> +# CHECK: AIE.objectFifo @of1(%1, {%2}, 2 : i32) : !AIE.objectFifo> +# CHECK: AIE.objectFifo.link [@of0] -> [@of1]() +# CHECK: %3 = AIE.core(%2) { +# CHECK: %c0 = arith.constant 0 : index +# CHECK: %c10 = arith.constant 10 : index +# CHECK: %c1 = arith.constant 1 : index +# CHECK: scf.for %arg0 = %c0 to %c10 step %c1 { +# CHECK: %4 = AIE.objectFifo.acquire @of1(Consume, 1) : !AIE.objectFifoSubview> +# CHECK: %5 = AIE.objectFifo.subview.access %4[0] : !AIE.objectFifoSubview> -> memref<8x8xi32> +# CHECK: %6 = func.call @test_func(%5) : (memref<8x8xi32>) -> i32 +# CHECK: AIE.objectFifo.release @of1(Consume, 1) +# CHECK: } +# CHECK: AIE.end +# CHECK: } {link_with = "test.o"} +# CHECK: } +# CHECK: } +@constructAndPrintInModule +def codeRegion(): + @device("xcve2802") + def deviceBody(): + int_ty = IntegerType.get_signless(32) + memRef_256_ty = MemRefType.get((256,), int_ty) + memRef_64_ty = MemRefType.get((8,8,), int_ty) + + privateFunc("test_func", inputs = [memRef_64_ty], outputs = [int_ty]) + + S = Tile(0, 2) + M = Tile(1, 2) + T = Tile(3, 3) + + OrderedObjectBuffer("of0", S, M, 2, memRef_256_ty) + OrderedObjectBuffer("of1", M, T, 2, memRef_64_ty) + Link(["of0"], ["of1"]) + + @core(T, "test.o") + def coreBody(): + @forLoop(lowerBound = 0, upperBound = 10, step = 1) + def loopBody(): + elem0 = Acquire("of1", "Consume", 1, memRef_64_ty).acquiredElem() + res = Call("test_func", [elem0], [int_ty]) + Release("of1", "Consume", 1) diff --git a/test/python/core_ext_kernel.py b/test/python/core_ext_kernel.py new file mode 100644 index 0000000000..7b68d22d3d --- /dev/null +++ b/test/python/core_ext_kernel.py @@ -0,0 +1,63 @@ +# Copyright (C) 2023, Advanced Micro Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +# RUN: %python %s | FileCheck %s + +from aie.ir import * +from aie.dialects.func import * +from aie.dialects.scf import * +from aie.dialects.aie import * + +# CHECK: module { +# CHECK: AIE.device(xcve2802) { +# CHECK: func.func private @test_func(memref<8x8xi32>, i32) -> i32 +# CHECK: %0 = AIE.tile(0, 2) +# CHECK: %1 = AIE.tile(1, 2) +# CHECK: %2 = AIE.tile(3, 3) +# CHECK: AIE.objectFifo @of0(%0, {%1}, 2 : i32) : !AIE.objectFifo> +# CHECK: AIE.objectFifo @of1(%1, {%2}, 2 : i32) : !AIE.objectFifo> +# CHECK: AIE.objectFifo.link [@of0] -> [@of1]() +# CHECK: %3 = AIE.core(%2) { +# CHECK: %c0 = arith.constant 0 : index +# CHECK: %c10 = arith.constant 10 : index +# CHECK: %c1 = arith.constant 1 : index +# CHECK: scf.for %arg0 = %c0 to %c10 step %c1 { +# CHECK: %4 = AIE.objectFifo.acquire @of1(Consume, 1) : !AIE.objectFifoSubview> +# CHECK: %5 = AIE.objectFifo.subview.access %4[0] : !AIE.objectFifoSubview> -> memref<8x8xi32> +# CHECK: %c4_i32 = arith.constant 4 : i32 +# CHECK: %6 = func.call @test_func(%5, %c4_i32) : (memref<8x8xi32>, i32) -> i32 +# CHECK: AIE.objectFifo.release @of1(Consume, 1) +# CHECK: } +# CHECK: AIE.end +# CHECK: } {link_with = "test.o"} +# CHECK: } +# CHECK: } +@constructAndPrintInModule +def core_ext_kernel(): + dev = Device("xcve2802") + dev_block = Block.create_at_start(dev.bodyRegion) + with InsertionPoint(dev_block): + int_ty = IntegerType.get_signless(32) + memRef_256_ty = MemRefType.get((256,), int_ty) + memRef_64_ty = MemRefType.get((8,8,), int_ty) + + privateFunc("test_func", inputs = [memRef_64_ty, int_ty], outputs = [int_ty]) + + S = Tile(0, 2) + M = Tile(1, 2) + T = Tile(3, 3) + + OrderedObjectBuffer("of0", S, M, 2, memRef_256_ty) + OrderedObjectBuffer("of1", M, T, 2, memRef_64_ty) + Link(["of0"], ["of1"]) + + C = Core(T, "test.o") + bb = Block.create_at_start(C.body) + with InsertionPoint(bb): + loop = For(lowerBound = 0, upperBound = 10, step = 1) + with InsertionPoint(loop.body): + elem0 = Acquire("of1", "Consume", 1, memRef_64_ty).acquiredElem() + res = Call("test_func", [elem0, integerConstant(4)], [int_ty]) + Release("of1", "Consume", 1) + YieldOp([]) + EndOp() diff --git a/test/python/objFifo.py b/test/python/objFifo.py new file mode 100644 index 0000000000..647c26a50d --- /dev/null +++ b/test/python/objFifo.py @@ -0,0 +1,46 @@ +# Copyright (C) 2023, Advanced Micro Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +# RUN: %python %s | FileCheck %s + +from aie.ir import * +from aie.dialects.aie import * +from aie.dialects.func import * +from aie.dialects.scf import * + +# CHECK: module { +# CHECK: AIE.device(xcve2302) { +# CHECK: %0 = AIE.tile(0, 2) +# CHECK: %1 = AIE.tile(1, 2) +# CHECK: AIE.objectFifo @of0(%0, {%1}, 2 : i32) : !AIE.objectFifo> +# CHECK: %2 = AIE.core(%1) { +# CHECK: %3 = AIE.objectFifo.acquire @of0(Consume, 1) : !AIE.objectFifoSubview> +# CHECK: %4 = AIE.objectFifo.subview.access %3[0] : !AIE.objectFifoSubview> -> memref<256xi32> +# CHECK: %c10_i32 = arith.constant 10 : i32 +# CHECK: %c0 = arith.constant 0 : index +# CHECK: memref.store %c10_i32, %4[%c0] : memref<256xi32> +# CHECK: AIE.objectFifo.release @of0(Consume, 1) +# CHECK: AIE.end +# CHECK: } +# CHECK: } +# CHECK: } +@constructAndPrintInModule +def objFifo_example(): + dev = Device("xcve2302") + dev_block = Block.create_at_start(dev.bodyRegion) + with InsertionPoint(dev_block): + int_ty = IntegerType.get_signless(32) + memRef_ty = MemRefType.get((256,), int_ty) + + S = Tile(0, 2) + T = Tile(1, 2) + + OrderedObjectBuffer("of0", S, T, 2, memRef_ty) + + C = Core(T) + bb = Block.create_at_start(C.body) + with InsertionPoint(bb): + elem0 = Acquire("of0", "Consume", 1, memRef_ty).acquiredElem() + Store(10, elem0, 0) + Release("of0", "Consume", 1) + EndOp() diff --git a/test/python/objFifo_link.py b/test/python/objFifo_link.py new file mode 100644 index 0000000000..b0a2b5c8bf --- /dev/null +++ b/test/python/objFifo_link.py @@ -0,0 +1,40 @@ +# Copyright (C) 2023, Advanced Micro Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +# RUN: %python %s | FileCheck %s + +from aie.ir import * +from aie.dialects.aie import * + +# CHECK: module { +# CHECK: AIE.device(xcve2802) { +# CHECK: %0 = AIE.tile(0, 2) +# CHECK: %1 = AIE.tile(1, 2) +# CHECK: %2 = AIE.tile(2, 2) +# CHECK: %3 = AIE.tile(2, 3) +# CHECK: AIE.objectFifo @of0(%0, {%1}, 2 : i32) : !AIE.objectFifo> +# CHECK: AIE.objectFifo @of1(%1, {%2, %3}, 2 : i32) : !AIE.objectFifo> +# CHECK: AIE.objectFifo.link [@of0] -> [@of1]() +# CHECK: AIE.objectFifo @of2(%1 toStream [<1, 2>], {%2 fromStream [<1, 2>], %3 fromStream [<1, 2>]}, [2 : i32, 2 : i32, 7 : i32]) : !AIE.objectFifo> +# CHECK: } +# CHECK: } +@constructAndPrintInModule +def link_example(): + dev = Device("xcve2802") + dev_block = Block.create_at_start(dev.bodyRegion) + with InsertionPoint(dev_block): + int_ty = IntegerType.get_signless(32) + int_8_ty = IntegerType.get_unsigned(8) + memRef_256_ty = MemRefType.get((256,), int_ty) + memRef_64_ty = MemRefType.get((64,), int_ty) + + S = Tile(0, 2) + M = Tile(1, 2) + T0 = Tile(2, 2) + T1 = Tile(2, 3) + + OrderedObjectBuffer("of0", S, M, 2, memRef_256_ty) + OrderedObjectBuffer("of1", M, [T0, T1], 2, memRef_64_ty) + Link(["of0"], ["of1"]) + + OrderedObjectBuffer("of2", M, [T0, T1], [2,2,7], MemRefType.get((256,), int_8_ty), [(1, 2)], [[(1, 2)], [(1, 2)]]) diff --git a/test/python/simple.py b/test/python/simple.py deleted file mode 100644 index 3252751119..0000000000 --- a/test/python/simple.py +++ /dev/null @@ -1,41 +0,0 @@ -# Copyright (C) 2023, Advanced Micro Devices, Inc. -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -# module { -# %0 = AIE.tile(1, 4) -# %1 = AIE.buffer(%0) : memref<256xi32> -# %2 = AIE.core(%0) { -# ^bb0(%arg0: index): -# %c14_i32 = arith.constant 14 : i32 -# %c3 = arith.constant 3 : index -# memref.store %c14_i32, %1[%c3] : memref<256xi32> -# AIE.end -# } -#} - -import aie -from aie.mlir.ir import * -from aie.dialects import aie as aiedialect -from aie.mlir.dialects import arith -from aie.mlir.dialects import memref - -with Context() as ctx, Location.unknown(): - aiedialect.register_dialect(ctx) - module = Module.create() - with InsertionPoint(module.body): - int_ty = IntegerType.get_signless(32) - idx_ty = IndexType.get() - memRef_ty = MemRefType.get((256,), int_ty) - - T = aiedialect.TileOp(idx_ty, IntegerAttr.get(int_ty, 1), IntegerAttr.get(int_ty, 4)) - buff = aiedialect.BufferOp(memRef_ty, T) - - C = aiedialect.CoreOp(idx_ty, T) - C.body.blocks.append(idx_ty) - with InsertionPoint(C.body.blocks[0]): - val = arith.ConstantOp(int_ty, IntegerAttr.get(int_ty, 14)) - idx = arith.ConstantOp(idx_ty, IntegerAttr.get(idx_ty, 3)) - memref.StoreOp(val, buff, idx) - aiedialect.EndOp() - -print(module) diff --git a/test/python/simple_with_bindings.py b/test/python/simple_with_bindings.py new file mode 100644 index 0000000000..e14597e36f --- /dev/null +++ b/test/python/simple_with_bindings.py @@ -0,0 +1,39 @@ +# Copyright (C) 2023, Advanced Micro Devices, Inc. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +# RUN: %python %s | FileCheck %s + +from aie.ir import * +from aie.dialects.aie import * + +# CHECK: module { +# CHECK: AIE.device(xcve2802) { +# CHECK: %0 = AIE.tile(1, 4) +# CHECK: %1 = AIE.buffer(%0) : memref<256xi32> +# CHECK: %2 = AIE.core(%0) { +# CHECK: %c3 = arith.constant 3 : index +# CHECK: %3 = memref.load %1[%c3] : memref<256xi32> +# CHECK: %c4_i32 = arith.constant 4 : i32 +# CHECK: %4 = arith.addi %3, %c4_i32 : i32 +# CHECK: %c3_0 = arith.constant 3 : index +# CHECK: memref.store %4, %1[%c3_0] : memref<256xi32> +# CHECK: AIE.end +# CHECK: } +# CHECK: } +# CHECK: } +@constructAndPrintInModule +def simple_with_bindings_example(): + dev = Device("xcve2802") + dev_block = Block.create_at_start(dev.bodyRegion) + with InsertionPoint(dev_block): + int_ty = IntegerType.get_signless(32) + T = Tile(1, 4) + buff = Buffer(tile=T, size=(256,), datatype=int_ty) + + C = Core(T) + bb = Block.create_at_start(C.body) + with InsertionPoint(bb): + val = Load(buff, 3) + add = AddI(val, 4) + Store(add, buff, 3) + EndOp() From 494433707d6ed2866e1f039af76bacef416ba30c Mon Sep 17 00:00:00 2001 From: max Date: Mon, 6 Nov 2023 20:51:56 -0600 Subject: [PATCH 3/9] use AIEDevice from enum_gen --- python/CMakeLists.txt | 2 ++ python/dialects/_AIE_syntax.py | 22 ++-------------------- python/dialects/aie.py | 1 + test/python/aie_ops.py | 12 ++++++------ test/python/codeRegion.py | 2 +- test/python/core_ext_kernel.py | 2 +- test/python/objFifo.py | 2 +- test/python/objFifo_link.py | 2 +- test/python/simple_with_bindings.py | 2 +- 9 files changed, 16 insertions(+), 31 deletions(-) diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index ed0718f250..21d025b7cc 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -34,6 +34,8 @@ declare_mlir_dialect_python_bindings( dialects/_AIE_syntax.py dialects/_AIE_util.py DIALECT_NAME AIE + GEN_ENUM_BINDINGS_TD_FILE + "dialects/AIEBinding.td" ) declare_mlir_dialect_python_bindings( diff --git a/python/dialects/_AIE_syntax.py b/python/dialects/_AIE_syntax.py index a1ff8671c2..e35627cb3b 100644 --- a/python/dialects/_AIE_syntax.py +++ b/python/dialects/_AIE_syntax.py @@ -1,11 +1,11 @@ from ._AIE_ops_gen import * +from ._AIE_enum_gen import * from ._AIE_util import * from .._mlir_libs._aieMlir import register_dialect, ObjectFifoType, ObjectFifoSubviewType # Helper function that returns the index of a named objectFifo port. def objectFifoPortToIndex(port): - port_index = -1 if (port == "Produce"): port_index = 0 elif (port == "Consume"): @@ -17,7 +17,6 @@ def objectFifoPortToIndex(port): # Helper function that returns the index of a named WireBundle. def wireBundleToIndex(port): - port_index = -1 if (port == "Core"): port_index = 0 elif (port == "DMA"): @@ -76,24 +75,7 @@ def constructAndPrintInModule(f): print(module) -# Create an aie device on specified target architecture. -class Device(DeviceOp): - """Specialize DeviceOp class constructor to take python integers""" - def __init__(self, device): - index = 0 - if (device == "xcvc1902"): - index = 1 - elif (device == "xcve2302"): - index = 2 - elif (device == "xcve2802"): - index = 3 - elif (device == "ipu"): - index = 4 - else: - index = device - iTy = IntegerType.get_signless(32) - intDevice = IntegerAttr.get(iTy, index) - super().__init__(device=intDevice) +Device = DeviceOp # Create an aie tile on specified (col, row). diff --git a/python/dialects/aie.py b/python/dialects/aie.py index b79637c044..db7344e30b 100644 --- a/python/dialects/aie.py +++ b/python/dialects/aie.py @@ -4,6 +4,7 @@ # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception from ._AIE_ops_gen import * +from ._AIE_enum_gen import * from ._AIE_syntax import * from ._AIE_util import * from .._mlir_libs._aieMlir import * diff --git a/test/python/aie_ops.py b/test/python/aie_ops.py index 84aff48859..7d3386e3d3 100644 --- a/test/python/aie_ops.py +++ b/test/python/aie_ops.py @@ -57,7 +57,7 @@ def memOp(): # CHECK: AIE.device @constructAndPrintInModule def deviceOp(): - dev = Device("xcvc1902") + dev = Device(AIEDevice.xcvc1902) bb = Block.create_at_start(dev.bodyRegion) with InsertionPoint(bb): EndOp() @@ -87,7 +87,7 @@ def externalBufferOp(): # CHECK: AIE.objectFifo @of0(%[[VAL0]] toStream [<1, 2>], {%[[VAL1]] fromStream [<1, 2>]}, 2 : i32) : !AIE.objectFifo> @constructAndPrintInModule def objFifo(): - dev = Device("xcvc1902") + dev = Device(AIEDevice.xcvc1902) bb = Block.create_at_start(dev.bodyRegion) with InsertionPoint(bb): tile0 = Tile(col=6, row=6) @@ -109,7 +109,7 @@ def objFifo(): # CHECK: AIE.objectFifo.link [@[[VAL_3]]] -> [@[[VAL_4]]]() @constructAndPrintInModule def objFifoLink(): - dev = Device("xcvc1902") + dev = Device(AIEDevice.xcvc1902) bb = Block.create_at_start(dev.bodyRegion) with InsertionPoint(bb): tile0 = Tile(col=6, row=6) @@ -130,7 +130,7 @@ def objFifoLink(): # CHECK: %[[VAL_3:.*]] = AIE.objectFifo.acquire @[[VAL_2]](Consume, 1) : !AIE.objectFifoSubview> @constructAndPrintInModule def objFifoAcquire(): - dev = Device("xcvc1902") + dev = Device(AIEDevice.xcvc1902) bb = Block.create_at_start(dev.bodyRegion) with InsertionPoint(bb): tile0 = Tile(col=6, row=6) @@ -153,7 +153,7 @@ def objFifoAcquire(): # CHECK: %[[VAL_4:.*]] = AIE.objectFifo.subview.access %[[VAL_3]][0] : !AIE.objectFifoSubview> -> memref<12xf16> @constructAndPrintInModule def objFifoSubviewAccess(): - dev = Device("xcvc1902") + dev = Device(AIEDevice.xcvc1902) bb = Block.create_at_start(dev.bodyRegion) with InsertionPoint(bb): tile0 = Tile(col=6, row=6) @@ -176,7 +176,7 @@ def objFifoSubviewAccess(): # CHECK: AIE.objectFifo.release @[[VAL_2]](Produce, 1) @constructAndPrintInModule def objFifoRelease(): - dev = Device("xcvc1902") + dev = Device(AIEDevice.xcvc1902) bb = Block.create_at_start(dev.bodyRegion) with InsertionPoint(bb): tile0 = Tile(col=6, row=6) diff --git a/test/python/codeRegion.py b/test/python/codeRegion.py index 1c569caf34..e2d969483f 100644 --- a/test/python/codeRegion.py +++ b/test/python/codeRegion.py @@ -31,7 +31,7 @@ # CHECK: } @constructAndPrintInModule def codeRegion(): - @device("xcve2802") + @device(AIEDevice.xcve2802) def deviceBody(): int_ty = IntegerType.get_signless(32) memRef_256_ty = MemRefType.get((256,), int_ty) diff --git a/test/python/core_ext_kernel.py b/test/python/core_ext_kernel.py index 7b68d22d3d..ff7fd7f0b0 100644 --- a/test/python/core_ext_kernel.py +++ b/test/python/core_ext_kernel.py @@ -34,7 +34,7 @@ # CHECK: } @constructAndPrintInModule def core_ext_kernel(): - dev = Device("xcve2802") + dev = Device(AIEDevice.xcve2802) dev_block = Block.create_at_start(dev.bodyRegion) with InsertionPoint(dev_block): int_ty = IntegerType.get_signless(32) diff --git a/test/python/objFifo.py b/test/python/objFifo.py index 647c26a50d..bb9f2a8aa3 100644 --- a/test/python/objFifo.py +++ b/test/python/objFifo.py @@ -26,7 +26,7 @@ # CHECK: } @constructAndPrintInModule def objFifo_example(): - dev = Device("xcve2302") + dev = Device(AIEDevice.xcve2302) dev_block = Block.create_at_start(dev.bodyRegion) with InsertionPoint(dev_block): int_ty = IntegerType.get_signless(32) diff --git a/test/python/objFifo_link.py b/test/python/objFifo_link.py index b0a2b5c8bf..4d2f02079a 100644 --- a/test/python/objFifo_link.py +++ b/test/python/objFifo_link.py @@ -20,7 +20,7 @@ # CHECK: } @constructAndPrintInModule def link_example(): - dev = Device("xcve2802") + dev = Device(AIEDevice.xcve2802) dev_block = Block.create_at_start(dev.bodyRegion) with InsertionPoint(dev_block): int_ty = IntegerType.get_signless(32) diff --git a/test/python/simple_with_bindings.py b/test/python/simple_with_bindings.py index e14597e36f..c6d90ed47c 100644 --- a/test/python/simple_with_bindings.py +++ b/test/python/simple_with_bindings.py @@ -23,7 +23,7 @@ # CHECK: } @constructAndPrintInModule def simple_with_bindings_example(): - dev = Device("xcve2802") + dev = Device(AIEDevice.xcve2802) dev_block = Block.create_at_start(dev.bodyRegion) with InsertionPoint(dev_block): int_ty = IntegerType.get_signless(32) From c10abfda59d446664d934f93753dd33e5e4c0268 Mon Sep 17 00:00:00 2001 From: max Date: Mon, 6 Nov 2023 21:35:19 -0600 Subject: [PATCH 4/9] use WireBundle and ObjectFifoPort --- python/dialects/_AIE_syntax.py | 97 +++++++--------------------------- test/python/aie_ops.py | 12 ++--- test/python/codeRegion.py | 4 +- test/python/core_ext_kernel.py | 6 +-- test/python/objFifo.py | 4 +- 5 files changed, 33 insertions(+), 90 deletions(-) diff --git a/python/dialects/_AIE_syntax.py b/python/dialects/_AIE_syntax.py index e35627cb3b..4ae4d1eb0b 100644 --- a/python/dialects/_AIE_syntax.py +++ b/python/dialects/_AIE_syntax.py @@ -1,47 +1,11 @@ +from typing import List + from ._AIE_ops_gen import * from ._AIE_enum_gen import * from ._AIE_util import * from .._mlir_libs._aieMlir import register_dialect, ObjectFifoType, ObjectFifoSubviewType -# Helper function that returns the index of a named objectFifo port. -def objectFifoPortToIndex(port): - if (port == "Produce"): - port_index = 0 - elif (port == "Consume"): - port_index = 1 - else: - port_index = -1 - return port_index - - -# Helper function that returns the index of a named WireBundle. -def wireBundleToIndex(port): - if (port == "Core"): - port_index = 0 - elif (port == "DMA"): - port_index = 1 - elif (port == "FIFO"): - port_index = 2 - elif (port == "South"): - port_index = 3 - elif (port == "West"): - port_index = 4 - elif (port == "North"): - port_index = 5 - elif (port == "East"): - port_index = 6 - elif (port == "PLIO"): - port_index = 7 - elif (port == "NOC"): - port_index = 8 - elif (port == "Trace"): - port_index = 9 - else: - port_index = -1 - return port_index - - def dim_tuple_attr_builder(wrap, stepsize): return Attribute.parse(f"#AIE.DimTuple<{wrap}, {stepsize}>") @@ -124,7 +88,12 @@ def __init__(self, size, datatype, name=None): # depth examples: 2, [2,2,7] class OrderedObjectBuffer(ObjectFifoCreateOp): """Specialize ObjectFifoCreateOp class constructor to take python integers""" - def __init__(self, name, tile0, tile1, depth, datatype, dimensionsToStream = [], dimensionsFromStreamPerConsumer = []): + def __init__(self, name, tile0, tile1, depth, datatype, dimensionsToStream=None, + dimensionsFromStreamPerConsumer=None): + if dimensionsFromStreamPerConsumer is None: + dimensionsFromStreamPerConsumer = [] + if dimensionsToStream is None: + dimensionsToStream = [] int_ty = IntegerType.get_signless(32) if isinstance(depth, int): int_depth = IntegerAttr.get(int_ty, depth) @@ -155,9 +124,7 @@ def __init__(self, ofIns, ofOuts): ofIns_sym.append(FlatSymbolRefAttr.get(o)) for o in ofOuts: ofOuts_sym.append(FlatSymbolRefAttr.get(o)) - ofIns_array = ArrayAttr.get(ofIns_sym) - ofOuts_array = ArrayAttr.get(ofOuts_sym) - super().__init__(fifoIns=ofIns_array, fifoOuts=ofOuts_array) + super().__init__(fifoIns=ofIns_sym, fifoOuts=ofOuts_sym) # Create an aie objectFifo acquire op of given number of elements with given memref datatype, @@ -165,53 +132,34 @@ def __init__(self, ofIns, ofOuts): class Acquire(ObjectFifoAcquireOp): """Specialize ObjectFifoAcquireOp class constructor to take python integers""" def __init__(self, of_name, port, num_elem, datatype): - of_sym = FlatSymbolRefAttr.get(of_name) - int_ty = IntegerType.get_signless(32) - int_port = IntegerAttr.get(int_ty, objectFifoPortToIndex(port)) subview_Ty = ObjectFifoSubviewType.get(datatype) self.datatype = datatype - super().__init__(subview=subview_Ty, port=int_port, objFifo_name=of_sym, size=num_elem) + super().__init__(subview=subview_Ty, port=port, objFifo_name=of_name, size=num_elem) def acquiredElem(self): objects = [] if self.size.value == 1: - return SubviewAccess(self.subview, self.size.value - 1, self.datatype) + return SubviewAccess(self.datatype, self.subview, self.size.value - 1) for i in range(self.size.value): - objects.append(SubviewAccess(self.subview, i, self.datatype)) + objects.append(SubviewAccess(self.datatype, self.subview, i)) return objects -# Create an aie objectFifo access op on given subview with given memref datatype, -# at given index. -class SubviewAccess(ObjectFifoSubviewAccessOp): - """Rename ObjectFifoSubviewAccessOp class""" - def __init__(self, subview, index, datatype): - super().__init__(output=datatype, subview=subview, index=index) +SubviewAccess = ObjectFifoSubviewAccessOp - -# Create an aie objectFifo release op of given number of elements from objFifo with given name. -class Release(ObjectFifoReleaseOp): - """Specialize ObjectFifoReleaseOp class constructor to take python integers""" - def __init__(self, of_name, port, num_elem): - of_sym = FlatSymbolRefAttr.get(of_name) - int_ty = IntegerType.get_signless(32) - int_port = IntegerAttr.get(int_ty, objectFifoPortToIndex(port)) - super().__init__(port=int_port, objFifo_name=of_sym, size=num_elem) +Release = ObjectFifoReleaseOp # Create a flow between source and destination tile ports. class Flow(FlowOp): """Specialize FlowOp class constructor to take python integers""" def __init__(self, source, source_port, source_channel, dest, dest_port, dest_channel): - int_ty = IntegerType.get_signless(32) - sourceBundle = IntegerAttr.get(int_ty, wireBundleToIndex(source_port)) - destBundle = IntegerAttr.get(int_ty, wireBundleToIndex(dest_port)) super().__init__( source=source, - sourceBundle=sourceBundle, + sourceBundle=source_port, sourceChannel=source_channel, dest=dest, - destBundle=destBundle, + destBundle=dest_port, destChannel=dest_channel ) @@ -220,20 +168,15 @@ def __init__(self, source, source_port, source_channel, dest, dest_port, dest_ch class PacketFlow(PacketFlowOp): """Specialize PacketFlowOp class constructor to take python integers""" def __init__(self, pkt_id, source, source_port, source_channel, dest, dest_port, dest_channel): - int8_ty = IntegerType.get_signless(8) - int_ty = IntegerType.get_signless(32) - int8_pkt_id = IntegerAttr.get(int8_ty, pkt_id) - sourceBundle = IntegerAttr.get(int_ty, wireBundleToIndex(source_port)) - destBundle = IntegerAttr.get(int_ty, wireBundleToIndex(dest_port)) - super().__init__(ID=int8_pkt_id) + super().__init__(ID=pkt_id) bb = Block.create_at_start(self.ports) with InsertionPoint(bb): - src = PacketSourceOp(source, sourceBundle, source_channel) - dest = PacketDestOp(dest, destBundle, dest_channel) + src = PacketSourceOp(source, source_port, source_channel) + dest = PacketDestOp(dest, dest_port, dest_channel) end = EndOp() #### Global Wrappers #### core = region_op(Core, terminator=lambda *args: EndOp()) device = region_op(Device) -forLoop = region_op(For, terminator=lambda *args: YieldOp([])) +forLoop = region_op(For, terminator=YieldOp) diff --git a/test/python/aie_ops.py b/test/python/aie_ops.py index 7d3386e3d3..15c4d617cd 100644 --- a/test/python/aie_ops.py +++ b/test/python/aie_ops.py @@ -141,7 +141,7 @@ def objFifoAcquire(): C = Core(tile1) bb = Block.create_at_start(C.body) with InsertionPoint(bb): - acq = Acquire(of_name="of0", port="Consume", num_elem=1, datatype=memTy) + acq = Acquire(of_name="of0", port=ObjectFifoPort.Consume, num_elem=1, datatype=memTy) EndOp() @@ -164,8 +164,8 @@ def objFifoSubviewAccess(): C = Core(tile1) bb = Block.create_at_start(C.body) with InsertionPoint(bb): - acq = Acquire(of_name="of0", port="Consume", num_elem=1, datatype=memTy) - subview = SubviewAccess(subview=acq, index=0, datatype=memTy) + acq = Acquire(of_name="of0", port=ObjectFifoPort.Consume, num_elem=1, datatype=memTy) + subview = SubviewAccess(memTy, subview=acq, index=0) EndOp() @@ -187,7 +187,7 @@ def objFifoRelease(): C = Core(tile0) bb = Block.create_at_start(C.body) with InsertionPoint(bb): - acq = Release(of_name="of0", port="Produce", num_elem=1) + acq = Release(ObjectFifoPort.Produce, "of0", 1) EndOp() @@ -199,7 +199,7 @@ def objFifoRelease(): def flowOp(): S = Tile(0, 0) T = Tile(0, 2) - Flow(T, "Trace", 0, S, "DMA", 1) + Flow(T, WireBundle.Trace, 0, S, WireBundle.DMA, 1) # CHECK-LABEL: packetFlowOp @@ -213,4 +213,4 @@ def flowOp(): def packetFlowOp(): S = Tile(0, 0) T = Tile(0, 2) - PacketFlow(0, T, "Trace", 0, S, "DMA", 1) + PacketFlow(0, T, WireBundle.Trace, 0, S, WireBundle.DMA, 1) diff --git a/test/python/codeRegion.py b/test/python/codeRegion.py index e2d969483f..0921ea38b6 100644 --- a/test/python/codeRegion.py +++ b/test/python/codeRegion.py @@ -51,6 +51,6 @@ def deviceBody(): def coreBody(): @forLoop(lowerBound = 0, upperBound = 10, step = 1) def loopBody(): - elem0 = Acquire("of1", "Consume", 1, memRef_64_ty).acquiredElem() + elem0 = Acquire("of1", ObjectFifoPort.Consume, 1, memRef_64_ty).acquiredElem() res = Call("test_func", [elem0], [int_ty]) - Release("of1", "Consume", 1) + Release(ObjectFifoPort.Consume, "of1", 1) diff --git a/test/python/core_ext_kernel.py b/test/python/core_ext_kernel.py index ff7fd7f0b0..bee83ef63f 100644 --- a/test/python/core_ext_kernel.py +++ b/test/python/core_ext_kernel.py @@ -53,11 +53,11 @@ def core_ext_kernel(): C = Core(T, "test.o") bb = Block.create_at_start(C.body) - with InsertionPoint(bb): + with InsertionPoint(bb): loop = For(lowerBound = 0, upperBound = 10, step = 1) with InsertionPoint(loop.body): - elem0 = Acquire("of1", "Consume", 1, memRef_64_ty).acquiredElem() + elem0 = Acquire("of1", ObjectFifoPort.Consume, 1, memRef_64_ty).acquiredElem() res = Call("test_func", [elem0, integerConstant(4)], [int_ty]) - Release("of1", "Consume", 1) + Release(ObjectFifoPort.Consume, "of1", 1) YieldOp([]) EndOp() diff --git a/test/python/objFifo.py b/test/python/objFifo.py index bb9f2a8aa3..8df64100fc 100644 --- a/test/python/objFifo.py +++ b/test/python/objFifo.py @@ -40,7 +40,7 @@ def objFifo_example(): C = Core(T) bb = Block.create_at_start(C.body) with InsertionPoint(bb): - elem0 = Acquire("of0", "Consume", 1, memRef_ty).acquiredElem() + elem0 = Acquire("of0", ObjectFifoPort.Consume, 1, memRef_ty).acquiredElem() Store(10, elem0, 0) - Release("of0", "Consume", 1) + Release(ObjectFifoPort.Consume, "of0", 1) EndOp() From ea1cef1c09fcfcbd8579701f9850b5b4f11d6ae1 Mon Sep 17 00:00:00 2001 From: max Date: Mon, 13 Nov 2023 14:47:43 -0600 Subject: [PATCH 5/9] fix tests --- python/dialects/_AIE_syntax.py | 24 ++++++++++++++++++++++++ test/python/codeRegion.py | 18 +++++++++--------- test/python/core_ext_kernel.py | 18 +++++++++--------- test/python/objFifo.py | 14 +++++++------- test/python/objFifo_link.py | 14 +++++++------- test/python/simple_with_bindings.py | 12 ++++++------ 6 files changed, 62 insertions(+), 38 deletions(-) diff --git a/python/dialects/_AIE_syntax.py b/python/dialects/_AIE_syntax.py index 4ae4d1eb0b..d00745f8c6 100644 --- a/python/dialects/_AIE_syntax.py +++ b/python/dialects/_AIE_syntax.py @@ -26,6 +26,30 @@ def dim_tuple_array_array_attr_builder(tup_arrs: List[List[tuple]], context=None ) +@register_attribute_builder("AIEI1Attr") +def _i1Attr(x, context): + return IntegerAttr.get(IntegerType.get_signless(1, context=context), x) + + +@register_attribute_builder("AIEI8Attr") +def _i8Attr(x, context): + return IntegerAttr.get(IntegerType.get_signless(8, context=context), x) + + +@register_attribute_builder("AIEI16Attr") +def _i16Attr(x, context): + return IntegerAttr.get(IntegerType.get_signless(16, context=context), x) + + +@register_attribute_builder("AIEI32Attr") +def _i32Attr(x, context): + return IntegerAttr.get(IntegerType.get_signless(32, context=context), x) + + +@register_attribute_builder("AIEI64Attr") +def _i64Attr(x, context): + return IntegerAttr.get(IntegerType.get_signless(64, context=context), x) + #### AIE Wrappers #### diff --git a/test/python/codeRegion.py b/test/python/codeRegion.py index 0921ea38b6..4d85491df1 100644 --- a/test/python/codeRegion.py +++ b/test/python/codeRegion.py @@ -9,20 +9,20 @@ # CHECK: module { # CHECK: AIE.device(xcve2802) { # CHECK: func.func private @test_func(memref<8x8xi32>) -> i32 -# CHECK: %0 = AIE.tile(0, 2) -# CHECK: %1 = AIE.tile(1, 2) -# CHECK: %2 = AIE.tile(3, 3) -# CHECK: AIE.objectFifo @of0(%0, {%1}, 2 : i32) : !AIE.objectFifo> -# CHECK: AIE.objectFifo @of1(%1, {%2}, 2 : i32) : !AIE.objectFifo> +# CHECK: %tile_0_2 = AIE.tile(0, 2) +# CHECK: %tile_1_2 = AIE.tile(1, 2) +# CHECK: %tile_3_3 = AIE.tile(3, 3) +# CHECK: AIE.objectFifo @of0(%tile_0_2, {%tile_1_2}, 2 : i32) : !AIE.objectFifo> +# CHECK: AIE.objectFifo @of1(%tile_1_2, {%tile_3_3}, 2 : i32) : !AIE.objectFifo> # CHECK: AIE.objectFifo.link [@of0] -> [@of1]() -# CHECK: %3 = AIE.core(%2) { +# CHECK: %core_3_3 = AIE.core(%tile_3_3) { # CHECK: %c0 = arith.constant 0 : index # CHECK: %c10 = arith.constant 10 : index # CHECK: %c1 = arith.constant 1 : index # CHECK: scf.for %arg0 = %c0 to %c10 step %c1 { -# CHECK: %4 = AIE.objectFifo.acquire @of1(Consume, 1) : !AIE.objectFifoSubview> -# CHECK: %5 = AIE.objectFifo.subview.access %4[0] : !AIE.objectFifoSubview> -> memref<8x8xi32> -# CHECK: %6 = func.call @test_func(%5) : (memref<8x8xi32>) -> i32 +# CHECK: %0 = AIE.objectFifo.acquire @of1(Consume, 1) : !AIE.objectFifoSubview> +# CHECK: %1 = AIE.objectFifo.subview.access %0[0] : !AIE.objectFifoSubview> -> memref<8x8xi32> +# CHECK: %2 = func.call @test_func(%1) : (memref<8x8xi32>) -> i32 # CHECK: AIE.objectFifo.release @of1(Consume, 1) # CHECK: } # CHECK: AIE.end diff --git a/test/python/core_ext_kernel.py b/test/python/core_ext_kernel.py index bee83ef63f..80de397004 100644 --- a/test/python/core_ext_kernel.py +++ b/test/python/core_ext_kernel.py @@ -11,21 +11,21 @@ # CHECK: module { # CHECK: AIE.device(xcve2802) { # CHECK: func.func private @test_func(memref<8x8xi32>, i32) -> i32 -# CHECK: %0 = AIE.tile(0, 2) -# CHECK: %1 = AIE.tile(1, 2) -# CHECK: %2 = AIE.tile(3, 3) -# CHECK: AIE.objectFifo @of0(%0, {%1}, 2 : i32) : !AIE.objectFifo> -# CHECK: AIE.objectFifo @of1(%1, {%2}, 2 : i32) : !AIE.objectFifo> +# CHECK: %tile_0_2 = AIE.tile(0, 2) +# CHECK: %tile_1_2 = AIE.tile(1, 2) +# CHECK: %tile_3_3 = AIE.tile(3, 3) +# CHECK: AIE.objectFifo @of0(%tile_0_2, {%tile_1_2}, 2 : i32) : !AIE.objectFifo> +# CHECK: AIE.objectFifo @of1(%tile_1_2, {%tile_3_3}, 2 : i32) : !AIE.objectFifo> # CHECK: AIE.objectFifo.link [@of0] -> [@of1]() -# CHECK: %3 = AIE.core(%2) { +# CHECK: %core_3_3 = AIE.core(%tile_3_3) { # CHECK: %c0 = arith.constant 0 : index # CHECK: %c10 = arith.constant 10 : index # CHECK: %c1 = arith.constant 1 : index # CHECK: scf.for %arg0 = %c0 to %c10 step %c1 { -# CHECK: %4 = AIE.objectFifo.acquire @of1(Consume, 1) : !AIE.objectFifoSubview> -# CHECK: %5 = AIE.objectFifo.subview.access %4[0] : !AIE.objectFifoSubview> -> memref<8x8xi32> +# CHECK: %0 = AIE.objectFifo.acquire @of1(Consume, 1) : !AIE.objectFifoSubview> +# CHECK: %1 = AIE.objectFifo.subview.access %0[0] : !AIE.objectFifoSubview> -> memref<8x8xi32> # CHECK: %c4_i32 = arith.constant 4 : i32 -# CHECK: %6 = func.call @test_func(%5, %c4_i32) : (memref<8x8xi32>, i32) -> i32 +# CHECK: %2 = func.call @test_func(%1, %c4_i32) : (memref<8x8xi32>, i32) -> i32 # CHECK: AIE.objectFifo.release @of1(Consume, 1) # CHECK: } # CHECK: AIE.end diff --git a/test/python/objFifo.py b/test/python/objFifo.py index 8df64100fc..93cfa04650 100644 --- a/test/python/objFifo.py +++ b/test/python/objFifo.py @@ -10,15 +10,15 @@ # CHECK: module { # CHECK: AIE.device(xcve2302) { -# CHECK: %0 = AIE.tile(0, 2) -# CHECK: %1 = AIE.tile(1, 2) -# CHECK: AIE.objectFifo @of0(%0, {%1}, 2 : i32) : !AIE.objectFifo> -# CHECK: %2 = AIE.core(%1) { -# CHECK: %3 = AIE.objectFifo.acquire @of0(Consume, 1) : !AIE.objectFifoSubview> -# CHECK: %4 = AIE.objectFifo.subview.access %3[0] : !AIE.objectFifoSubview> -> memref<256xi32> +# CHECK: %tile_0_2 = AIE.tile(0, 2) +# CHECK: %tile_1_2 = AIE.tile(1, 2) +# CHECK: AIE.objectFifo @of0(%tile_0_2, {%tile_1_2}, 2 : i32) : !AIE.objectFifo> +# CHECK: %core_1_2 = AIE.core(%tile_1_2) { +# CHECK: %0 = AIE.objectFifo.acquire @of0(Consume, 1) : !AIE.objectFifoSubview> +# CHECK: %1 = AIE.objectFifo.subview.access %0[0] : !AIE.objectFifoSubview> -> memref<256xi32> # CHECK: %c10_i32 = arith.constant 10 : i32 # CHECK: %c0 = arith.constant 0 : index -# CHECK: memref.store %c10_i32, %4[%c0] : memref<256xi32> +# CHECK: memref.store %c10_i32, %1[%c0] : memref<256xi32> # CHECK: AIE.objectFifo.release @of0(Consume, 1) # CHECK: AIE.end # CHECK: } diff --git a/test/python/objFifo_link.py b/test/python/objFifo_link.py index 4d2f02079a..12165cfe27 100644 --- a/test/python/objFifo_link.py +++ b/test/python/objFifo_link.py @@ -8,14 +8,14 @@ # CHECK: module { # CHECK: AIE.device(xcve2802) { -# CHECK: %0 = AIE.tile(0, 2) -# CHECK: %1 = AIE.tile(1, 2) -# CHECK: %2 = AIE.tile(2, 2) -# CHECK: %3 = AIE.tile(2, 3) -# CHECK: AIE.objectFifo @of0(%0, {%1}, 2 : i32) : !AIE.objectFifo> -# CHECK: AIE.objectFifo @of1(%1, {%2, %3}, 2 : i32) : !AIE.objectFifo> +# CHECK: %tile_0_2 = AIE.tile(0, 2) +# CHECK: %tile_1_2 = AIE.tile(1, 2) +# CHECK: %tile_2_2 = AIE.tile(2, 2) +# CHECK: %tile_2_3 = AIE.tile(2, 3) +# CHECK: AIE.objectFifo @of0(%tile_0_2, {%tile_1_2}, 2 : i32) : !AIE.objectFifo> +# CHECK: AIE.objectFifo @of1(%tile_1_2, {%tile_2_2, %tile_2_3}, 2 : i32) : !AIE.objectFifo> # CHECK: AIE.objectFifo.link [@of0] -> [@of1]() -# CHECK: AIE.objectFifo @of2(%1 toStream [<1, 2>], {%2 fromStream [<1, 2>], %3 fromStream [<1, 2>]}, [2 : i32, 2 : i32, 7 : i32]) : !AIE.objectFifo> +# CHECK: AIE.objectFifo @of2(%tile_1_2 toStream [<1, 2>], {%tile_2_2 fromStream [<1, 2>], %tile_2_3 fromStream [<1, 2>]}, [2 : i32, 2 : i32, 7 : i32]) : !AIE.objectFifo> # CHECK: } # CHECK: } @constructAndPrintInModule diff --git a/test/python/simple_with_bindings.py b/test/python/simple_with_bindings.py index c6d90ed47c..05f6edef48 100644 --- a/test/python/simple_with_bindings.py +++ b/test/python/simple_with_bindings.py @@ -8,15 +8,15 @@ # CHECK: module { # CHECK: AIE.device(xcve2802) { -# CHECK: %0 = AIE.tile(1, 4) -# CHECK: %1 = AIE.buffer(%0) : memref<256xi32> -# CHECK: %2 = AIE.core(%0) { +# CHECK: %tile_1_4 = AIE.tile(1, 4) +# CHECK: %buffer_1_4 = AIE.buffer(%tile_1_4) : memref<256xi32> +# CHECK: %core_1_4 = AIE.core(%tile_1_4) { # CHECK: %c3 = arith.constant 3 : index -# CHECK: %3 = memref.load %1[%c3] : memref<256xi32> +# CHECK: %0 = memref.load %buffer_1_4[%c3] : memref<256xi32> # CHECK: %c4_i32 = arith.constant 4 : i32 -# CHECK: %4 = arith.addi %3, %c4_i32 : i32 +# CHECK: %1 = arith.addi %0, %c4_i32 : i32 # CHECK: %c3_0 = arith.constant 3 : index -# CHECK: memref.store %4, %1[%c3_0] : memref<256xi32> +# CHECK: memref.store %1, %buffer_1_4[%c3_0] : memref<256xi32> # CHECK: AIE.end # CHECK: } # CHECK: } From d39087626f4c8cd42e56acf5e37902937ca47f66 Mon Sep 17 00:00:00 2001 From: max Date: Mon, 13 Nov 2023 14:50:49 -0600 Subject: [PATCH 6/9] black/format --- python/dialects/_AIE_syntax.py | 64 +++++++++++++------ python/dialects/_AIE_util.py | 45 ++++++++----- test/python/aie_ops.py | 16 +++-- test/python/aiex_ops.py | 1 + test/python/{codeRegion.py => code_region.py} | 16 +++-- test/python/core_ext_kernel.py | 18 ++++-- test/python/objFifo.py | 4 +- test/python/objFifo_link.py | 10 ++- 8 files changed, 120 insertions(+), 54 deletions(-) rename test/python/{codeRegion.py => code_region.py} (83%) diff --git a/python/dialects/_AIE_syntax.py b/python/dialects/_AIE_syntax.py index d00745f8c6..1e3960fb34 100644 --- a/python/dialects/_AIE_syntax.py +++ b/python/dialects/_AIE_syntax.py @@ -3,7 +3,11 @@ from ._AIE_ops_gen import * from ._AIE_enum_gen import * from ._AIE_util import * -from .._mlir_libs._aieMlir import register_dialect, ObjectFifoType, ObjectFifoSubviewType +from .._mlir_libs._aieMlir import ( + register_dialect, + ObjectFifoType, + ObjectFifoSubviewType, +) def dim_tuple_attr_builder(wrap, stepsize): @@ -50,6 +54,7 @@ def _i32Attr(x, context): def _i64Attr(x, context): return IntegerAttr.get(IntegerType.get_signless(64, context=context), x) + #### AIE Wrappers #### @@ -69,6 +74,7 @@ def constructAndPrintInModule(f): # Create an aie tile on specified (col, row). class Tile(TileOp): """Specialize TileOp class constructor to take python integers""" + def __init__(self, col, row): idx_ty = IndexType.get() super().__init__(result=idx_ty, col=col, row=row) @@ -77,11 +83,12 @@ def __init__(self, col, row): # Create an aie core on specified aie tile. class Core(CoreOp): """Specialize CoreOp class constructor to take python integers""" + def __init__(self, tile, link_with=None): idx_ty = IndexType.get() - if (link_with != None): + if link_with != None: super().__init__(result=idx_ty, tile=tile, link_with=link_with) - else : + else: super().__init__(result=idx_ty, tile=tile) @@ -89,6 +96,7 @@ def __init__(self, tile, link_with=None): # size examples: [256], [256, 256], [256, 256,] class Buffer(BufferOp): """Specialize BufferOp class constructor to take python integers""" + def __init__(self, tile, size, datatype, name=None): memRef_ty = MemRefType.get(size, datatype) if name is None: @@ -101,6 +109,7 @@ def __init__(self, tile, size, datatype, name=None): # size examples: [256], [256, 256], [256, 256,] class ExternalBuffer(ExternalBufferOp): """Specialize ExternalBufferOp class constructor to take python integers""" + def __init__(self, size, datatype, name=None): memRef_ty = MemRefType.get(size, datatype) if name is None: @@ -112,8 +121,17 @@ def __init__(self, size, datatype, name=None): # depth examples: 2, [2,2,7] class OrderedObjectBuffer(ObjectFifoCreateOp): """Specialize ObjectFifoCreateOp class constructor to take python integers""" - def __init__(self, name, tile0, tile1, depth, datatype, dimensionsToStream=None, - dimensionsFromStreamPerConsumer=None): + + def __init__( + self, + name, + tile0, + tile1, + depth, + datatype, + dimensionsToStream=None, + dimensionsFromStreamPerConsumer=None, + ): if dimensionsFromStreamPerConsumer is None: dimensionsFromStreamPerConsumer = [] if dimensionsToStream is None: @@ -128,19 +146,20 @@ def __init__(self, name, tile0, tile1, depth, datatype, dimensionsToStream=None, int_depth = ArrayAttr.get(int_depths) of_Ty = ObjectFifoType.get(datatype) super().__init__( - sym_name=name, - producerTile=tile0, + sym_name=name, + producerTile=tile0, consumerTiles=tile1, - elemNumber=int_depth, - elem_type=TypeAttr.get(of_Ty), - dimensionsToStream=dimensionsToStream, - dimensionsFromStreamPerConsumer=dimensionsFromStreamPerConsumer + elemNumber=int_depth, + elem_type=TypeAttr.get(of_Ty), + dimensionsToStream=dimensionsToStream, + dimensionsFromStreamPerConsumer=dimensionsFromStreamPerConsumer, ) # Create an aie objectFifo link op between specified input and output arrays of objFifos. class Link(ObjectFifoLinkOp): """Specialize ObjectFifoLinkOp class constructor to take python integers""" + def __init__(self, ofIns, ofOuts): ofIns_sym = [] ofOuts_sym = [] @@ -155,10 +174,13 @@ def __init__(self, ofIns, ofOuts): # from objFifo with given name. class Acquire(ObjectFifoAcquireOp): """Specialize ObjectFifoAcquireOp class constructor to take python integers""" + def __init__(self, of_name, port, num_elem, datatype): subview_Ty = ObjectFifoSubviewType.get(datatype) self.datatype = datatype - super().__init__(subview=subview_Ty, port=port, objFifo_name=of_name, size=num_elem) + super().__init__( + subview=subview_Ty, port=port, objFifo_name=of_name, size=num_elem + ) def acquiredElem(self): objects = [] @@ -177,21 +199,27 @@ def acquiredElem(self): # Create a flow between source and destination tile ports. class Flow(FlowOp): """Specialize FlowOp class constructor to take python integers""" - def __init__(self, source, source_port, source_channel, dest, dest_port, dest_channel): + + def __init__( + self, source, source_port, source_channel, dest, dest_port, dest_channel + ): super().__init__( - source=source, + source=source, sourceBundle=source_port, - sourceChannel=source_channel, - dest=dest, + sourceChannel=source_channel, + dest=dest, destBundle=dest_port, - destChannel=dest_channel + destChannel=dest_channel, ) # Create a packet flow between source and destination tile ports. class PacketFlow(PacketFlowOp): """Specialize PacketFlowOp class constructor to take python integers""" - def __init__(self, pkt_id, source, source_port, source_channel, dest, dest_port, dest_channel): + + def __init__( + self, pkt_id, source, source_port, source_channel, dest, dest_port, dest_channel + ): super().__init__(ID=pkt_id) bb = Block.create_at_start(self.ports) with InsertionPoint(bb): diff --git a/python/dialects/_AIE_util.py b/python/dialects/_AIE_util.py index c2e32c0e47..37308753dc 100644 --- a/python/dialects/_AIE_util.py +++ b/python/dialects/_AIE_util.py @@ -11,7 +11,8 @@ # Create a signless arith constant of given width (default is i32). class integerConstant(arith.ConstantOp): """Specialize ConstantOp class constructor to take python integers""" - def __init__(self, val, width = 32): + + def __init__(self, val, width=32): if isinstance(width, int): int_ty = IntegerType.get_signless(width) else: @@ -23,6 +24,7 @@ def __init__(self, val, width = 32): # Create an index arith constant. class indexConstant(arith.ConstantOp): """Specialize ConstantOp class constructor to take python integers""" + def __init__(self, val): idx_ty = IndexType.get() idxAttr = IntegerAttr.get(idx_ty, val) @@ -31,6 +33,7 @@ def __init__(self, val): class AddI(arith.AddIOp): """Specialize AddIOp class constructor to take python integers""" + def __init__(self, lhs, rhs): if isinstance(lhs, int): intLhs = integerConstant(lhs) @@ -42,40 +45,44 @@ def __init__(self, lhs, rhs): class For(ForOp): """Specialize ForOp class constructor to take python integers""" + def __init__(self, lowerBound, upperBound, step): - idxLowerBound = indexConstant(lowerBound) + idxLowerBound = indexConstant(lowerBound) idxUpperBound = indexConstant(upperBound) idxStep = indexConstant(step) - super().__init__(lower_bound=idxLowerBound, upper_bound=idxUpperBound, step=idxStep) + super().__init__( + lower_bound=idxLowerBound, upper_bound=idxUpperBound, step=idxStep + ) # Wrapper for func FuncOp with "private" visibility. class privateFunc(FuncOp): """Specialize FuncOp class constructor to take python integers""" - def __init__(self, name, inputs, outputs = [], visibility = "private"): + + def __init__(self, name, inputs, outputs=[], visibility="private"): super().__init__( - name=name, - type=FunctionType.get(inputs, outputs), - visibility=visibility + name=name, type=FunctionType.get(inputs, outputs), visibility=visibility ) # Wrapper for func FuncOp with "private" visibility. class publicFunc(FuncOp): """Specialize FuncOp class constructor to take python integers""" - def __init__(self, name, callbackFunc, inputs, outputs = [], visibility = "public"): + + def __init__(self, name, callbackFunc, inputs, outputs=[], visibility="public"): super().__init__( - name=name, - type=FunctionType.get(inputs, outputs), - visibility=visibility, - body_builder=callbackFunc + name=name, + type=FunctionType.get(inputs, outputs), + visibility=visibility, + body_builder=callbackFunc, ) # Wrapper for func CallOp. class Call(CallOp): """Specialize CallOp class constructor to take python integers""" - def __init__(self, calleeOrResults, inputs = [], input_types = []): + + def __init__(self, calleeOrResults, inputs=[], input_types=[]): attrInputs = [] for i in inputs: if isinstance(i, int): @@ -83,17 +90,20 @@ def __init__(self, calleeOrResults, inputs = [], input_types = []): else: attrInputs.append(i) if isinstance(calleeOrResults, FuncOp): - super().__init__(calleeOrResults=calleeOrResults, argumentsOrCallee=attrInputs) + super().__init__( + calleeOrResults=calleeOrResults, argumentsOrCallee=attrInputs + ) else: super().__init__( - calleeOrResults=input_types, - argumentsOrCallee=FlatSymbolRefAttr.get(calleeOrResults), - arguments=attrInputs + calleeOrResults=input_types, + argumentsOrCallee=FlatSymbolRefAttr.get(calleeOrResults), + arguments=attrInputs, ) class Load(memref.LoadOp): """Specialize LoadOp class constructor to take python integers""" + def __init__(self, mem, indices): valueIndices = [] if isinstance(indices, list): @@ -106,6 +116,7 @@ def __init__(self, mem, indices): class Store(memref.StoreOp): """Specialize StoreOp class constructor to take python integers""" + def __init__(self, val, mem, indices): if isinstance(val, int): intVal = integerConstant(val) diff --git a/test/python/aie_ops.py b/test/python/aie_ops.py index 15c4d617cd..95822d89e9 100644 --- a/test/python/aie_ops.py +++ b/test/python/aie_ops.py @@ -94,11 +94,9 @@ def objFifo(): tile1 = Tile(col=2, row=2) dtype = F16Type.get() memTy = MemRefType.get((12,), dtype) - OrderedObjectBuffer( - "of0", tile0, tile1, 2, memTy, [(1, 2)], [[(1, 2)]] - ) + OrderedObjectBuffer("of0", tile0, tile1, 2, memTy, [(1, 2)], [[(1, 2)]]) EndOp() - + # CHECK-LABEL: objFifoLink # CHECK: %[[VAL_0:.*]] = AIE.tile(6, 6) @@ -140,8 +138,10 @@ def objFifoAcquire(): OrderedObjectBuffer("of0", tile0, tile1, 2, memTy) C = Core(tile1) bb = Block.create_at_start(C.body) - with InsertionPoint(bb): - acq = Acquire(of_name="of0", port=ObjectFifoPort.Consume, num_elem=1, datatype=memTy) + with InsertionPoint(bb): + acq = Acquire( + of_name="of0", port=ObjectFifoPort.Consume, num_elem=1, datatype=memTy + ) EndOp() @@ -164,7 +164,9 @@ def objFifoSubviewAccess(): C = Core(tile1) bb = Block.create_at_start(C.body) with InsertionPoint(bb): - acq = Acquire(of_name="of0", port=ObjectFifoPort.Consume, num_elem=1, datatype=memTy) + acq = Acquire( + of_name="of0", port=ObjectFifoPort.Consume, num_elem=1, datatype=memTy + ) subview = SubviewAccess(memTy, subview=acq, index=0) EndOp() diff --git a/test/python/aiex_ops.py b/test/python/aiex_ops.py index 0503dc4833..987b59f11a 100644 --- a/test/python/aiex_ops.py +++ b/test/python/aiex_ops.py @@ -9,6 +9,7 @@ from aie.dialects.aiex import * from aie.dialects import arith + def constructAndPrintInModule(f): with Context() as ctx, Location.unknown(): aie.dialects.aiex.register_dialect(ctx) diff --git a/test/python/codeRegion.py b/test/python/code_region.py similarity index 83% rename from test/python/codeRegion.py rename to test/python/code_region.py index 4d85491df1..80e689c2c3 100644 --- a/test/python/codeRegion.py +++ b/test/python/code_region.py @@ -35,9 +35,15 @@ def codeRegion(): def deviceBody(): int_ty = IntegerType.get_signless(32) memRef_256_ty = MemRefType.get((256,), int_ty) - memRef_64_ty = MemRefType.get((8,8,), int_ty) + memRef_64_ty = MemRefType.get( + ( + 8, + 8, + ), + int_ty, + ) - privateFunc("test_func", inputs = [memRef_64_ty], outputs = [int_ty]) + privateFunc("test_func", inputs=[memRef_64_ty], outputs=[int_ty]) S = Tile(0, 2) M = Tile(1, 2) @@ -49,8 +55,10 @@ def deviceBody(): @core(T, "test.o") def coreBody(): - @forLoop(lowerBound = 0, upperBound = 10, step = 1) + @forLoop(lowerBound=0, upperBound=10, step=1) def loopBody(): - elem0 = Acquire("of1", ObjectFifoPort.Consume, 1, memRef_64_ty).acquiredElem() + elem0 = Acquire( + "of1", ObjectFifoPort.Consume, 1, memRef_64_ty + ).acquiredElem() res = Call("test_func", [elem0], [int_ty]) Release(ObjectFifoPort.Consume, "of1", 1) diff --git a/test/python/core_ext_kernel.py b/test/python/core_ext_kernel.py index 80de397004..cc4db59f2a 100644 --- a/test/python/core_ext_kernel.py +++ b/test/python/core_ext_kernel.py @@ -39,9 +39,15 @@ def core_ext_kernel(): with InsertionPoint(dev_block): int_ty = IntegerType.get_signless(32) memRef_256_ty = MemRefType.get((256,), int_ty) - memRef_64_ty = MemRefType.get((8,8,), int_ty) + memRef_64_ty = MemRefType.get( + ( + 8, + 8, + ), + int_ty, + ) - privateFunc("test_func", inputs = [memRef_64_ty, int_ty], outputs = [int_ty]) + privateFunc("test_func", inputs=[memRef_64_ty, int_ty], outputs=[int_ty]) S = Tile(0, 2) M = Tile(1, 2) @@ -54,10 +60,12 @@ def core_ext_kernel(): C = Core(T, "test.o") bb = Block.create_at_start(C.body) with InsertionPoint(bb): - loop = For(lowerBound = 0, upperBound = 10, step = 1) + loop = For(lowerBound=0, upperBound=10, step=1) with InsertionPoint(loop.body): - elem0 = Acquire("of1", ObjectFifoPort.Consume, 1, memRef_64_ty).acquiredElem() + elem0 = Acquire( + "of1", ObjectFifoPort.Consume, 1, memRef_64_ty + ).acquiredElem() res = Call("test_func", [elem0, integerConstant(4)], [int_ty]) Release(ObjectFifoPort.Consume, "of1", 1) YieldOp([]) - EndOp() + EndOp() diff --git a/test/python/objFifo.py b/test/python/objFifo.py index 93cfa04650..61eadd261e 100644 --- a/test/python/objFifo.py +++ b/test/python/objFifo.py @@ -39,8 +39,8 @@ def objFifo_example(): C = Core(T) bb = Block.create_at_start(C.body) - with InsertionPoint(bb): + with InsertionPoint(bb): elem0 = Acquire("of0", ObjectFifoPort.Consume, 1, memRef_ty).acquiredElem() Store(10, elem0, 0) Release(ObjectFifoPort.Consume, "of0", 1) - EndOp() + EndOp() diff --git a/test/python/objFifo_link.py b/test/python/objFifo_link.py index 12165cfe27..5fd02427af 100644 --- a/test/python/objFifo_link.py +++ b/test/python/objFifo_link.py @@ -37,4 +37,12 @@ def link_example(): OrderedObjectBuffer("of1", M, [T0, T1], 2, memRef_64_ty) Link(["of0"], ["of1"]) - OrderedObjectBuffer("of2", M, [T0, T1], [2,2,7], MemRefType.get((256,), int_8_ty), [(1, 2)], [[(1, 2)], [(1, 2)]]) + OrderedObjectBuffer( + "of2", + M, + [T0, T1], + [2, 2, 7], + MemRefType.get((256,), int_8_ty), + [(1, 2)], + [[(1, 2)], [(1, 2)]], + ) From ff0a8082dec8ff126c75c003ae2c9189f4bbd409 Mon Sep 17 00:00:00 2001 From: max Date: Mon, 13 Nov 2023 15:21:19 -0600 Subject: [PATCH 7/9] add ipu examples --- python/CMakeLists.txt | 2 - python/dialects/_AIE_syntax.py | 234 ---------------- python/dialects/_AIE_util.py | 180 ------------ python/dialects/aie.py | 418 +++++++++++++++++++++++++++- python/dialects/aiex.py | 142 ++++++++++ test/python/ipu.py | 483 +++++++++++++++++++++++++++++++++ 6 files changed, 1040 insertions(+), 419 deletions(-) delete mode 100644 python/dialects/_AIE_syntax.py delete mode 100644 python/dialects/_AIE_util.py create mode 100644 test/python/ipu.py diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index 21d025b7cc..f1ce14808b 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -31,8 +31,6 @@ declare_mlir_dialect_python_bindings( TD_FILE dialects/AIEBinding.td SOURCES dialects/aie.py - dialects/_AIE_syntax.py - dialects/_AIE_util.py DIALECT_NAME AIE GEN_ENUM_BINDINGS_TD_FILE "dialects/AIEBinding.td" diff --git a/python/dialects/_AIE_syntax.py b/python/dialects/_AIE_syntax.py deleted file mode 100644 index 1e3960fb34..0000000000 --- a/python/dialects/_AIE_syntax.py +++ /dev/null @@ -1,234 +0,0 @@ -from typing import List - -from ._AIE_ops_gen import * -from ._AIE_enum_gen import * -from ._AIE_util import * -from .._mlir_libs._aieMlir import ( - register_dialect, - ObjectFifoType, - ObjectFifoSubviewType, -) - - -def dim_tuple_attr_builder(wrap, stepsize): - return Attribute.parse(f"#AIE.DimTuple<{wrap}, {stepsize}>") - - -@register_attribute_builder("AIE_DimTupleArrayAttr") -def dim_tuple_array_attr_builder(tups: List[tuple], context=None): - tups = list(map(lambda t: dim_tuple_attr_builder(*t), tups)) - return Attribute.parse( - f'#AIE', context=context - ) - - -@register_attribute_builder("AIE_DimTupleArrayArrayAttr") -def dim_tuple_array_array_attr_builder(tup_arrs: List[List[tuple]], context=None): - tup_arrs = list(map(dim_tuple_array_attr_builder, tup_arrs)) - return Attribute.parse( - f'#AIE', context=context - ) - - -@register_attribute_builder("AIEI1Attr") -def _i1Attr(x, context): - return IntegerAttr.get(IntegerType.get_signless(1, context=context), x) - - -@register_attribute_builder("AIEI8Attr") -def _i8Attr(x, context): - return IntegerAttr.get(IntegerType.get_signless(8, context=context), x) - - -@register_attribute_builder("AIEI16Attr") -def _i16Attr(x, context): - return IntegerAttr.get(IntegerType.get_signless(16, context=context), x) - - -@register_attribute_builder("AIEI32Attr") -def _i32Attr(x, context): - return IntegerAttr.get(IntegerType.get_signless(32, context=context), x) - - -@register_attribute_builder("AIEI64Attr") -def _i64Attr(x, context): - return IntegerAttr.get(IntegerType.get_signless(64, context=context), x) - - -#### AIE Wrappers #### - - -# Create and print ModuleOp. -def constructAndPrintInModule(f): - with Context() as ctx, Location.unknown(): - register_dialect(ctx) - module = Module.create() - with InsertionPoint(module.body): - f() - print(module) - - -Device = DeviceOp - - -# Create an aie tile on specified (col, row). -class Tile(TileOp): - """Specialize TileOp class constructor to take python integers""" - - def __init__(self, col, row): - idx_ty = IndexType.get() - super().__init__(result=idx_ty, col=col, row=row) - - -# Create an aie core on specified aie tile. -class Core(CoreOp): - """Specialize CoreOp class constructor to take python integers""" - - def __init__(self, tile, link_with=None): - idx_ty = IndexType.get() - if link_with != None: - super().__init__(result=idx_ty, tile=tile, link_with=link_with) - else: - super().__init__(result=idx_ty, tile=tile) - - -# Create an aie buffer of (size x datatype) on given tile. -# size examples: [256], [256, 256], [256, 256,] -class Buffer(BufferOp): - """Specialize BufferOp class constructor to take python integers""" - - def __init__(self, tile, size, datatype, name=None): - memRef_ty = MemRefType.get(size, datatype) - if name is None: - super().__init__(buffer=memRef_ty, tile=tile) - else: - super().__init__(buffer=memRef_ty, tile=tile, sym_name=name) - - -# Create an aie external buffer of (size x datatype). -# size examples: [256], [256, 256], [256, 256,] -class ExternalBuffer(ExternalBufferOp): - """Specialize ExternalBufferOp class constructor to take python integers""" - - def __init__(self, size, datatype, name=None): - memRef_ty = MemRefType.get(size, datatype) - if name is None: - super().__init__(buffer=memRef_ty) - super().__init__(buffer=memRef_ty, sym_name=name) - - -# Create an aie objectFifo between specified tiles, with given depth and memref datatype. -# depth examples: 2, [2,2,7] -class OrderedObjectBuffer(ObjectFifoCreateOp): - """Specialize ObjectFifoCreateOp class constructor to take python integers""" - - def __init__( - self, - name, - tile0, - tile1, - depth, - datatype, - dimensionsToStream=None, - dimensionsFromStreamPerConsumer=None, - ): - if dimensionsFromStreamPerConsumer is None: - dimensionsFromStreamPerConsumer = [] - if dimensionsToStream is None: - dimensionsToStream = [] - int_ty = IntegerType.get_signless(32) - if isinstance(depth, int): - int_depth = IntegerAttr.get(int_ty, depth) - else: - int_depths = [] - for d in depth: - int_depths.append(IntegerAttr.get(int_ty, d)) - int_depth = ArrayAttr.get(int_depths) - of_Ty = ObjectFifoType.get(datatype) - super().__init__( - sym_name=name, - producerTile=tile0, - consumerTiles=tile1, - elemNumber=int_depth, - elem_type=TypeAttr.get(of_Ty), - dimensionsToStream=dimensionsToStream, - dimensionsFromStreamPerConsumer=dimensionsFromStreamPerConsumer, - ) - - -# Create an aie objectFifo link op between specified input and output arrays of objFifos. -class Link(ObjectFifoLinkOp): - """Specialize ObjectFifoLinkOp class constructor to take python integers""" - - def __init__(self, ofIns, ofOuts): - ofIns_sym = [] - ofOuts_sym = [] - for o in ofIns: - ofIns_sym.append(FlatSymbolRefAttr.get(o)) - for o in ofOuts: - ofOuts_sym.append(FlatSymbolRefAttr.get(o)) - super().__init__(fifoIns=ofIns_sym, fifoOuts=ofOuts_sym) - - -# Create an aie objectFifo acquire op of given number of elements with given memref datatype, -# from objFifo with given name. -class Acquire(ObjectFifoAcquireOp): - """Specialize ObjectFifoAcquireOp class constructor to take python integers""" - - def __init__(self, of_name, port, num_elem, datatype): - subview_Ty = ObjectFifoSubviewType.get(datatype) - self.datatype = datatype - super().__init__( - subview=subview_Ty, port=port, objFifo_name=of_name, size=num_elem - ) - - def acquiredElem(self): - objects = [] - if self.size.value == 1: - return SubviewAccess(self.datatype, self.subview, self.size.value - 1) - for i in range(self.size.value): - objects.append(SubviewAccess(self.datatype, self.subview, i)) - return objects - - -SubviewAccess = ObjectFifoSubviewAccessOp - -Release = ObjectFifoReleaseOp - - -# Create a flow between source and destination tile ports. -class Flow(FlowOp): - """Specialize FlowOp class constructor to take python integers""" - - def __init__( - self, source, source_port, source_channel, dest, dest_port, dest_channel - ): - super().__init__( - source=source, - sourceBundle=source_port, - sourceChannel=source_channel, - dest=dest, - destBundle=dest_port, - destChannel=dest_channel, - ) - - -# Create a packet flow between source and destination tile ports. -class PacketFlow(PacketFlowOp): - """Specialize PacketFlowOp class constructor to take python integers""" - - def __init__( - self, pkt_id, source, source_port, source_channel, dest, dest_port, dest_channel - ): - super().__init__(ID=pkt_id) - bb = Block.create_at_start(self.ports) - with InsertionPoint(bb): - src = PacketSourceOp(source, source_port, source_channel) - dest = PacketDestOp(dest, dest_port, dest_channel) - end = EndOp() - - -#### Global Wrappers #### -core = region_op(Core, terminator=lambda *args: EndOp()) -device = region_op(Device) -forLoop = region_op(For, terminator=YieldOp) diff --git a/python/dialects/_AIE_util.py b/python/dialects/_AIE_util.py deleted file mode 100644 index 37308753dc..0000000000 --- a/python/dialects/_AIE_util.py +++ /dev/null @@ -1,180 +0,0 @@ -import inspect -from functools import wraps - -from ..ir import * -from ..dialects import arith -from ..dialects import memref -from ..dialects.func import * -from ..dialects.scf import * - - -# Create a signless arith constant of given width (default is i32). -class integerConstant(arith.ConstantOp): - """Specialize ConstantOp class constructor to take python integers""" - - def __init__(self, val, width=32): - if isinstance(width, int): - int_ty = IntegerType.get_signless(width) - else: - int_ty = width - intAttr = IntegerAttr.get(int_ty, val) - super().__init__(result=int_ty, value=intAttr) - - -# Create an index arith constant. -class indexConstant(arith.ConstantOp): - """Specialize ConstantOp class constructor to take python integers""" - - def __init__(self, val): - idx_ty = IndexType.get() - idxAttr = IntegerAttr.get(idx_ty, val) - super().__init__(result=idx_ty, value=idxAttr) - - -class AddI(arith.AddIOp): - """Specialize AddIOp class constructor to take python integers""" - - def __init__(self, lhs, rhs): - if isinstance(lhs, int): - intLhs = integerConstant(lhs) - else: - intLhs = lhs - intRhs = integerConstant(rhs) - super().__init__(lhs=intLhs, rhs=intRhs) - - -class For(ForOp): - """Specialize ForOp class constructor to take python integers""" - - def __init__(self, lowerBound, upperBound, step): - idxLowerBound = indexConstant(lowerBound) - idxUpperBound = indexConstant(upperBound) - idxStep = indexConstant(step) - super().__init__( - lower_bound=idxLowerBound, upper_bound=idxUpperBound, step=idxStep - ) - - -# Wrapper for func FuncOp with "private" visibility. -class privateFunc(FuncOp): - """Specialize FuncOp class constructor to take python integers""" - - def __init__(self, name, inputs, outputs=[], visibility="private"): - super().__init__( - name=name, type=FunctionType.get(inputs, outputs), visibility=visibility - ) - - -# Wrapper for func FuncOp with "private" visibility. -class publicFunc(FuncOp): - """Specialize FuncOp class constructor to take python integers""" - - def __init__(self, name, callbackFunc, inputs, outputs=[], visibility="public"): - super().__init__( - name=name, - type=FunctionType.get(inputs, outputs), - visibility=visibility, - body_builder=callbackFunc, - ) - - -# Wrapper for func CallOp. -class Call(CallOp): - """Specialize CallOp class constructor to take python integers""" - - def __init__(self, calleeOrResults, inputs=[], input_types=[]): - attrInputs = [] - for i in inputs: - if isinstance(i, int): - attrInputs.append(integerConstant(i)) - else: - attrInputs.append(i) - if isinstance(calleeOrResults, FuncOp): - super().__init__( - calleeOrResults=calleeOrResults, argumentsOrCallee=attrInputs - ) - else: - super().__init__( - calleeOrResults=input_types, - argumentsOrCallee=FlatSymbolRefAttr.get(calleeOrResults), - arguments=attrInputs, - ) - - -class Load(memref.LoadOp): - """Specialize LoadOp class constructor to take python integers""" - - def __init__(self, mem, indices): - valueIndices = [] - if isinstance(indices, list): - for i in indices: - valueIndices.append(indexConstant(i)) - else: - valueIndices.append(indexConstant(indices)) - super().__init__(memref=mem, indices=valueIndices) - - -class Store(memref.StoreOp): - """Specialize StoreOp class constructor to take python integers""" - - def __init__(self, val, mem, indices): - if isinstance(val, int): - intVal = integerConstant(val) - else: - intVal = val - valueIndices = [] - if isinstance(indices, list): - for i in indices: - valueIndices.append(indexConstant(i)) - else: - valueIndices.append(indexConstant(indices)) - super().__init__(value=intVal, memref=mem, indices=valueIndices) - - -def op_region_builder(op, op_region, terminator=None): - def builder_wrapper(body_builder): - # add a block with block args having types ... - if len(op_region.blocks) == 0: - sig = inspect.signature(body_builder) - types = [p.annotation for p in sig.parameters.values()] - if not ( - len(types) == len(sig.parameters) - and all(isinstance(t, Type) for t in types) - ): - raise ValueError( - f"for {body_builder=} either missing a type annotation or type annotation isn't a mlir type: {sig}" - ) - op_region.blocks.append(*types) - with InsertionPoint(op_region.blocks[0]): - results = body_builder() - if terminator is not None: - res = [] - if isinstance(results, (tuple, list)): - res.extend(results) - elif results is not None: - res.append(results) - terminator(res) - - return op - - return builder_wrapper - - -def region_op(op_constructor, terminator=None): - # the decorator itself - def op_decorator(*args, **kwargs): - op = op_constructor(*args, **kwargs) - op_region = op.regions[0] - - return op_region_builder(op, op_region, terminator) - - # this is like make_maybe_no_args_decorator but a little different because the decorators here - # are already wrapped (or something like that) - @wraps(op_decorator) - def maybe_no_args(*args, **kwargs): - if len(args) == 1 and len(kwargs) == 0 and callable(args[0]): - return op_decorator()(args[0]) - else: - return op_decorator(*args, **kwargs) - - return maybe_no_args diff --git a/python/dialects/aie.py b/python/dialects/aie.py index db7344e30b..332950615d 100644 --- a/python/dialects/aie.py +++ b/python/dialects/aie.py @@ -3,8 +3,420 @@ # Copyright (C) 2022, Advanced Micro Devices, Inc. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -from ._AIE_ops_gen import * +import inspect +from functools import wraps + from ._AIE_enum_gen import * -from ._AIE_syntax import * -from ._AIE_util import * +from ._AIE_enum_gen import * +from ._AIE_ops_gen import * +from ._AIE_ops_gen import * from .._mlir_libs._aieMlir import * +from .._mlir_libs._aieMlir import ( + register_dialect, + ObjectFifoType, + ObjectFifoSubviewType, +) +from ..dialects import arith +from ..dialects import memref +from ..dialects.func import * +from ..dialects.scf import * +from ..ir import * + + +# Create a signless arith constant of given width (default is i32). +class integerConstant(arith.ConstantOp): + """Specialize ConstantOp class constructor to take python integers""" + + def __init__(self, val, width=32): + if isinstance(width, int): + int_ty = IntegerType.get_signless(width) + else: + int_ty = width + intAttr = IntegerAttr.get(int_ty, val) + super().__init__(result=int_ty, value=intAttr) + + +# Create an index arith constant. +class indexConstant(arith.ConstantOp): + """Specialize ConstantOp class constructor to take python integers""" + + def __init__(self, val): + idx_ty = IndexType.get() + idxAttr = IntegerAttr.get(idx_ty, val) + super().__init__(result=idx_ty, value=idxAttr) + + +class AddI(arith.AddIOp): + """Specialize AddIOp class constructor to take python integers""" + + def __init__(self, lhs, rhs): + if isinstance(lhs, int): + intLhs = integerConstant(lhs) + else: + intLhs = lhs + intRhs = integerConstant(rhs) + super().__init__(lhs=intLhs, rhs=intRhs) + + +class For(ForOp): + """Specialize ForOp class constructor to take python integers""" + + def __init__(self, lowerBound, upperBound, step): + idxLowerBound = indexConstant(lowerBound) + idxUpperBound = indexConstant(upperBound) + idxStep = indexConstant(step) + super().__init__( + lower_bound=idxLowerBound, upper_bound=idxUpperBound, step=idxStep + ) + + +# Wrapper for func FuncOp with "private" visibility. +class privateFunc(FuncOp): + """Specialize FuncOp class constructor to take python integers""" + + def __init__(self, name, inputs, outputs=[], visibility="private"): + super().__init__( + name=name, type=FunctionType.get(inputs, outputs), visibility=visibility + ) + + +# Wrapper for func FuncOp with "private" visibility. +class publicFunc(FuncOp): + """Specialize FuncOp class constructor to take python integers""" + + def __init__(self, name, callbackFunc, inputs, outputs=[], visibility="public"): + super().__init__( + name=name, + type=FunctionType.get(inputs, outputs), + visibility=visibility, + body_builder=callbackFunc, + ) + + +# Wrapper for func CallOp. +class Call(CallOp): + """Specialize CallOp class constructor to take python integers""" + + def __init__(self, calleeOrResults, inputs=[], input_types=[]): + attrInputs = [] + for i in inputs: + if isinstance(i, int): + attrInputs.append(integerConstant(i)) + else: + attrInputs.append(i) + if isinstance(calleeOrResults, FuncOp): + super().__init__( + calleeOrResults=calleeOrResults, argumentsOrCallee=attrInputs + ) + else: + super().__init__( + calleeOrResults=input_types, + argumentsOrCallee=FlatSymbolRefAttr.get(calleeOrResults), + arguments=attrInputs, + ) + + +class Load(memref.LoadOp): + """Specialize LoadOp class constructor to take python integers""" + + def __init__(self, mem, indices): + valueIndices = [] + if isinstance(indices, list): + for i in indices: + valueIndices.append(indexConstant(i)) + else: + valueIndices.append(indexConstant(indices)) + super().__init__(memref=mem, indices=valueIndices) + + +class Store(memref.StoreOp): + """Specialize StoreOp class constructor to take python integers""" + + def __init__(self, val, mem, indices): + if isinstance(val, int): + intVal = integerConstant(val) + else: + intVal = val + valueIndices = [] + if isinstance(indices, list): + for i in indices: + valueIndices.append(indexConstant(i)) + else: + valueIndices.append(indexConstant(indices)) + super().__init__(value=intVal, memref=mem, indices=valueIndices) + + +def op_region_builder(op, op_region, terminator=None): + def builder_wrapper(body_builder): + # add a block with block args having types ... + if len(op_region.blocks) == 0: + sig = inspect.signature(body_builder) + types = [p.annotation for p in sig.parameters.values()] + if not ( + len(types) == len(sig.parameters) + and all(isinstance(t, Type) for t in types) + ): + raise ValueError( + f"for {body_builder=} either missing a type annotation or type annotation isn't a mlir type: {sig}" + ) + op_region.blocks.append(*types) + with InsertionPoint(op_region.blocks[0]): + results = body_builder() + if terminator is not None: + res = [] + if isinstance(results, (tuple, list)): + res.extend(results) + elif results is not None: + res.append(results) + terminator(res) + + return op + + return builder_wrapper + + +def region_op(op_constructor, terminator=None): + # the decorator itself + def op_decorator(*args, **kwargs): + op = op_constructor(*args, **kwargs) + op_region = op.regions[0] + + return op_region_builder(op, op_region, terminator) + + # this is like make_maybe_no_args_decorator but a little different because the decorators here + # are already wrapped (or something like that) + @wraps(op_decorator) + def maybe_no_args(*args, **kwargs): + if len(args) == 1 and len(kwargs) == 0 and callable(args[0]): + return op_decorator()(args[0]) + else: + return op_decorator(*args, **kwargs) + + return maybe_no_args + + +from typing import List + + +def dim_tuple_attr_builder(wrap, stepsize): + return Attribute.parse(f"#AIE.DimTuple<{wrap}, {stepsize}>") + + +@register_attribute_builder("AIE_DimTupleArrayAttr") +def dim_tuple_array_attr_builder(tups: List[tuple], context=None): + tups = list(map(lambda t: dim_tuple_attr_builder(*t), tups)) + return Attribute.parse( + f'#AIE', context=context + ) + + +@register_attribute_builder("AIE_DimTupleArrayArrayAttr") +def dim_tuple_array_array_attr_builder(tup_arrs: List[List[tuple]], context=None): + tup_arrs = list(map(dim_tuple_array_attr_builder, tup_arrs)) + return Attribute.parse( + f'#AIE', context=context + ) + + +@register_attribute_builder("AIEI1Attr") +def _i1Attr(x, context): + return IntegerAttr.get(IntegerType.get_signless(1, context=context), x) + + +@register_attribute_builder("AIEI8Attr") +def _i8Attr(x, context): + return IntegerAttr.get(IntegerType.get_signless(8, context=context), x) + + +@register_attribute_builder("AIEI16Attr") +def _i16Attr(x, context): + return IntegerAttr.get(IntegerType.get_signless(16, context=context), x) + + +@register_attribute_builder("AIEI32Attr") +def _i32Attr(x, context): + return IntegerAttr.get(IntegerType.get_signless(32, context=context), x) + + +@register_attribute_builder("AIEI64Attr") +def _i64Attr(x, context): + return IntegerAttr.get(IntegerType.get_signless(64, context=context), x) + + +#### AIE Wrappers #### + + +# Create and print ModuleOp. +def constructAndPrintInModule(f): + with Context() as ctx, Location.unknown(): + register_dialect(ctx) + module = Module.create() + with InsertionPoint(module.body): + f() + print(module) + + +Device = DeviceOp + + +# Create an aie tile on specified (col, row). +class Tile(TileOp): + """Specialize TileOp class constructor to take python integers""" + + def __init__(self, col, row): + idx_ty = IndexType.get() + super().__init__(result=idx_ty, col=col, row=row) + + +# Create an aie core on specified aie tile. +class Core(CoreOp): + """Specialize CoreOp class constructor to take python integers""" + + def __init__(self, tile, link_with=None): + idx_ty = IndexType.get() + if link_with != None: + super().__init__(result=idx_ty, tile=tile, link_with=link_with) + else: + super().__init__(result=idx_ty, tile=tile) + + +# Create an aie buffer of (size x datatype) on given tile. +# size examples: [256], [256, 256], [256, 256,] +class Buffer(BufferOp): + """Specialize BufferOp class constructor to take python integers""" + + def __init__(self, tile, size, datatype, name=None): + memRef_ty = MemRefType.get(size, datatype) + if name is None: + super().__init__(buffer=memRef_ty, tile=tile) + else: + super().__init__(buffer=memRef_ty, tile=tile, sym_name=name) + + +# Create an aie external buffer of (size x datatype). +# size examples: [256], [256, 256], [256, 256,] +class ExternalBuffer(ExternalBufferOp): + """Specialize ExternalBufferOp class constructor to take python integers""" + + def __init__(self, size, datatype, name=None): + memRef_ty = MemRefType.get(size, datatype) + if name is None: + super().__init__(buffer=memRef_ty) + super().__init__(buffer=memRef_ty, sym_name=name) + + +# Create an aie objectFifo between specified tiles, with given depth and memref datatype. +# depth examples: 2, [2,2,7] +class OrderedObjectBuffer(ObjectFifoCreateOp): + """Specialize ObjectFifoCreateOp class constructor to take python integers""" + + def __init__( + self, + name, + tile0, + tile1, + depth, + datatype, + dimensionsToStream=None, + dimensionsFromStreamPerConsumer=None, + ): + if dimensionsFromStreamPerConsumer is None: + dimensionsFromStreamPerConsumer = [] + if dimensionsToStream is None: + dimensionsToStream = [] + int_ty = IntegerType.get_signless(32) + if isinstance(depth, int): + int_depth = IntegerAttr.get(int_ty, depth) + else: + int_depths = [] + for d in depth: + int_depths.append(IntegerAttr.get(int_ty, d)) + int_depth = ArrayAttr.get(int_depths) + of_Ty = ObjectFifoType.get(datatype) + super().__init__( + sym_name=name, + producerTile=tile0, + consumerTiles=tile1, + elemNumber=int_depth, + elem_type=TypeAttr.get(of_Ty), + dimensionsToStream=dimensionsToStream, + dimensionsFromStreamPerConsumer=dimensionsFromStreamPerConsumer, + ) + + +# Create an aie objectFifo link op between specified input and output arrays of objFifos. +class Link(ObjectFifoLinkOp): + """Specialize ObjectFifoLinkOp class constructor to take python integers""" + + def __init__(self, ofIns, ofOuts): + ofIns_sym = [] + ofOuts_sym = [] + for o in ofIns: + ofIns_sym.append(FlatSymbolRefAttr.get(o)) + for o in ofOuts: + ofOuts_sym.append(FlatSymbolRefAttr.get(o)) + super().__init__(fifoIns=ofIns_sym, fifoOuts=ofOuts_sym) + + +# Create an aie objectFifo acquire op of given number of elements with given memref datatype, +# from objFifo with given name. +class Acquire(ObjectFifoAcquireOp): + """Specialize ObjectFifoAcquireOp class constructor to take python integers""" + + def __init__(self, of_name, port, num_elem, datatype): + subview_Ty = ObjectFifoSubviewType.get(datatype) + self.datatype = datatype + super().__init__( + subview=subview_Ty, port=port, objFifo_name=of_name, size=num_elem + ) + + def acquiredElem(self): + objects = [] + if self.size.value == 1: + return SubviewAccess(self.datatype, self.subview, self.size.value - 1) + for i in range(self.size.value): + objects.append(SubviewAccess(self.datatype, self.subview, i)) + return objects + + +SubviewAccess = ObjectFifoSubviewAccessOp + +Release = ObjectFifoReleaseOp + + +# Create a flow between source and destination tile ports. +class Flow(FlowOp): + """Specialize FlowOp class constructor to take python integers""" + + def __init__( + self, source, source_port, source_channel, dest, dest_port, dest_channel + ): + super().__init__( + source=source, + sourceBundle=source_port, + sourceChannel=source_channel, + dest=dest, + destBundle=dest_port, + destChannel=dest_channel, + ) + + +# Create a packet flow between source and destination tile ports. +class PacketFlow(PacketFlowOp): + """Specialize PacketFlowOp class constructor to take python integers""" + + def __init__( + self, pkt_id, source, source_port, source_channel, dest, dest_port, dest_channel + ): + super().__init__(ID=pkt_id) + bb = Block.create_at_start(self.ports) + with InsertionPoint(bb): + src = PacketSourceOp(source, source_port, source_channel) + dest = PacketDestOp(dest, dest_port, dest_channel) + end = EndOp() + + +#### Global Wrappers #### +core = region_op(Core, terminator=lambda *args: EndOp()) +device = region_op(Device) +forLoop = region_op(For, terminator=YieldOp) diff --git a/python/dialects/aiex.py b/python/dialects/aiex.py index 0eaa84d74c..90faacf1a9 100644 --- a/python/dialects/aiex.py +++ b/python/dialects/aiex.py @@ -5,3 +5,145 @@ from ._AIEX_ops_gen import * from .._mlir_libs._aieMlir import * +from ..ir import * +from ..dialects import arith + + +class IpuSync(IpuSyncOp): + """Rename IpuSyncOp class""" + + def __init__(self, column, row, direction, channel, column_num=1, row_num=1): + super().__init__( + column=column, + row=row, + direction=direction, + channel=channel, + column_num=column_num, + row_num=row_num, + ) + + +class IpuWrite32(IpuWrite32Op): + """Specialize IpuWrite32Op class constructor to take python integers""" + + def __init__(self, column, row, address, value): + uiTy = IntegerType.get_unsigned(32) + intAddr = IntegerAttr.get(uiTy, address) + intValue = IntegerAttr.get(uiTy, value) + super().__init__(column=column, row=row, address=intAddr, value=intValue) + + +class IpuWriteRTP(IpuWriteRTPOp): + """Specialize IpuWriteRTPOp class constructor to take python integers""" + + def __init__(self, name, col, row, index, value): + uiTy = IntegerType.get_unsigned(32) + intCol = IntegerAttr.get(uiTy, col) + intRow = IntegerAttr.get(uiTy, row) + intIndex = IntegerAttr.get(uiTy, index) + super().__init__( + buffer_sym_name=name, col=intCol, row=intRow, index=intIndex, value=value + ) + + +class IpuWriteBdShimTile(IpuWriteBdExShimTileOp): + """Rename IpuWriteBdExShimTileOp class""" + + def __init__( + self, + column, + column_num, + ddr_id, + bd_id, + buffer_length, + buffer_offset, + enable_packet, + out_of_order_id, + packet_id, + packet_type, + d0_wrap, + d0_stepsize, + d1_wrap, + d1_stepsize, + d2_stepsize, + iteration_current, + iteration_wrap, + iteration_stepsize, + next_bd, + use_next_bd, + valid_bd, + lock_rel_val, + lock_rel_id, + lock_acq_enable, + lock_acq_val, + lock_acq_id, + ): + super().__init__( + column=column, + column_num=column_num, + ddr_id=ddr_id, + bd_id=bd_id, + buffer_length=buffer_length, + buffer_offset=buffer_offset, + enable_packet=enable_packet, + out_of_order_id=out_of_order_id, + packet_id=packet_id, + packet_type=packet_type, + d0_wrap=d0_wrap, + d0_stepsize=d0_stepsize, + d1_wrap=d1_wrap, + d1_stepsize=d1_stepsize, + d2_stepsize=d2_stepsize, + iteration_current=iteration_current, + iteration_wrap=iteration_wrap, + iteration_stepsize=iteration_stepsize, + next_bd=next_bd, + use_next_bd=use_next_bd, + valid_bd=valid_bd, + lock_rel_val=lock_rel_val, + lock_rel_id=lock_rel_id, + lock_acq_enable=lock_acq_enable, + lock_acq_val=lock_acq_val, + lock_acq_id=lock_acq_id, + ) + + +class IpuDmaMemcpyNd(IpuDmaMemcpyNdOp): + """Specialize IpuDmaMemcpyNdOp class constructor to take python integers""" + + def __init__( + self, metadata, bd_id, mem, offsets=[0] * 4, lengths=[0] * 4, strides=[0] * 3 + ): + symMetadata = FlatSymbolRefAttr.get(metadata) + iTy = IntegerType.get_signless(32) + x = 0 + y = 0 + intX = arith.ConstantOp(iTy, IntegerAttr.get(iTy, x)) + intY = arith.ConstantOp(iTy, IntegerAttr.get(iTy, y)) + valueOffsets = [] + valueLengths = [] + valueStrides = [] + for i in offsets: + valueOffsets.append(arith.ConstantOp(iTy, IntegerAttr.get(iTy, i))) + for i in lengths: + valueLengths.append(arith.ConstantOp(iTy, IntegerAttr.get(iTy, i))) + for i in strides: + valueStrides.append(arith.ConstantOp(iTy, IntegerAttr.get(iTy, i))) + super().__init__( + metadata=symMetadata, + id=bd_id, + x=intX, + y=intY, + memref=mem, + offset3=valueOffsets[0], + offset2=valueOffsets[1], + offset1=valueOffsets[2], + offset0=valueOffsets[3], + length3=valueLengths[0], + length2=valueLengths[1], + length1=valueLengths[2], + length0=valueLengths[3], + stride3=valueStrides[0], + stride2=valueStrides[1], + stride1=valueStrides[2], + ) diff --git a/test/python/ipu.py b/test/python/ipu.py new file mode 100644 index 0000000000..a015a6d7a2 --- /dev/null +++ b/test/python/ipu.py @@ -0,0 +1,483 @@ +# This file is licensed 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 +# +# (c) Copyright 2023 AMD Inc. + +from aie.ir import * +from aie.dialects.func import * +from aie.dialects.scf import * +from aie.dialects.aie import * +from aie.dialects.aiex import * + + +@constructAndPrintInModule +def my_vector_scalar(): + N = 4095 + n = 1023 + N_div_n = N // n + N_in_bytes = N * 3 + + buffer_depth = 1 + + @device(AIEDevice.ipu) + def deviceBody(): + int32_ty = IntegerType.get_signless(32) + memRef_ty = MemRefType.get((n,), int32_ty) + + scale_int32 = privateFunc("scale_int32", inputs=[memRef_ty, memRef_ty]) + + S = Tile(0, 0) + T = Tile(0, 2) + + OrderedObjectBuffer("in", S, T, buffer_depth, memRef_ty) + OrderedObjectBuffer("out", T, S, buffer_depth, memRef_ty) + + @core(T, "scale.o") + def coreBody(): + # Effective while(1) + @forLoop(lowerBound=0, upperBound=0xFFFFFFFF, step=1) + def loopReps(): + # Number of sub-vector "tile" iterations + @forLoop(lowerBound=0, upperBound=N_div_n, step=1) + def loopTile(): + elemOut = Acquire( + "out", ObjectFifoPort.Produce, 1, memRef_ty + ).acquiredElem() + elemIn = Acquire( + "in", ObjectFifoPort.Consume, 1, memRef_ty + ).acquiredElem() + Call(scale_int32, [elemIn, elemOut]) + Release(ObjectFifoPort.Consume, "in", 1) + Release(ObjectFifoPort.Produce, "out", 1) + + memRef_mem_ty = MemRefType.get((N,), int32_ty) + + @FuncOp.from_py_func(memRef_mem_ty, memRef_mem_ty, memRef_mem_ty) + def sequence(A, B, C): + IpuDmaMemcpyNd(metadata="out", bd_id=0, mem=C, lengths=[1, 1, 1, N]) + IpuDmaMemcpyNd(metadata="in", bd_id=1, mem=A, lengths=[1, 1, 1, N]) + IpuSync(column=0, row=0, direction=0, channel=0) + + +@constructAndPrintInModule +def my_matmul(): + M = 128 + K = 128 + N = 128 + m = 64 + k = 32 + n = 64 + word_size_in = 2 + word_size_out = 2 + + A_sz_in_i32s = M * K * word_size_in // 4 + B_sz_in_i32s = K * N * word_size_in // 4 + C_sz_in_bytes = M * N * word_size_out + C_sz_in_i32s = C_sz_in_bytes // 4 + + M_div_m = M // m + K_div_k = K // k + N_div_n = N // n + tiles = M_div_m * N_div_n + + # Matrix A: MxK, submatrices a: mxk + k_in_i32s = k * word_size_in // 4 + K_in_i32s = K * word_size_in // 4 + + # Matrix B: KxN, submatrices b: kxn + n_in_i32s = n * word_size_in // 4 + N_in_i32s = N * word_size_in // 4 + k_x_N_in_i32s = k * N * word_size_in // 4 + + # Output Matrix C: MxN + n_in_i32s_out = n * word_size_out // 4 + N_in_i32s_out = N * word_size_out // 4 + m_x_N_in_i32s_out = m * N * word_size_out // 4 + + vectorized = True + + @device(AIEDevice.ipu) + def deviceBody(): + in_ty = IntegerType.get_signless(16) + out_ty = IntegerType.get_signless(16) + memRef_A_ty = MemRefType.get( + ( + m, + k, + ), + in_ty, + ) + memRef_B_ty = MemRefType.get( + ( + k, + n, + ), + in_ty, + ) + memRef_C_ty = MemRefType.get( + ( + m, + n, + ), + out_ty, + ) + + zero_scalar = privateFunc("zero_scalar_i16", inputs=[memRef_C_ty]) + zero = privateFunc("zero_i16", inputs=[memRef_C_ty]) + matmul_scalar = privateFunc( + "matmul_scalar_i16_i16", inputs=[memRef_A_ty, memRef_B_ty, memRef_C_ty] + ) + matmul = privateFunc( + "matmul_i16_i16", inputs=[memRef_A_ty, memRef_B_ty, memRef_C_ty] + ) + + S = Tile(0, 0) + M = Tile(0, 1) + T = Tile(0, 2) + + OrderedObjectBuffer("inA", S, T, 2, memRef_A_ty) + OrderedObjectBuffer("inB", S, T, 2, memRef_B_ty) + OrderedObjectBuffer("outC", T, S, 2, memRef_C_ty) + + @core(T, "mm.o") + def coreBody(): + @forLoop(lowerBound=0, upperBound=0xFFFFFFFF, step=1) + def loopReps(): + @forLoop(lowerBound=0, upperBound=tiles, step=1) + def loopTile(): + elemOut = Acquire( + "outC", ObjectFifoPort.Produce, 1, memRef_C_ty + ).acquiredElem() + if vectorized: + Call(zero, [elemOut]) + else: + Call(zero_scalar, [elemOut]) + + @forLoop(lowerBound=0, upperBound=K_div_k, step=1) + def loopK(): + elemInA = Acquire( + "inA", ObjectFifoPort.Consume, 1, memRef_A_ty + ).acquiredElem() + elemInB = Acquire( + "inB", ObjectFifoPort.Consume, 1, memRef_B_ty + ).acquiredElem() + if vectorized: + Call(matmul, [elemInA, elemInB, elemOut]) + else: + Call(matmul_scalar, [elemInA, elemInB, elemOut]) + Release(ObjectFifoPort.Consume, "inA", 1) + Release(ObjectFifoPort.Consume, "inB", 1) + + Release(ObjectFifoPort.Produce, "outC", 1) + + int32_ty = IntegerType.get_signless(32) + memRef_Ain_ty = MemRefType.get((A_sz_in_i32s,), int32_ty) + memRef_Bin_ty = MemRefType.get((B_sz_in_i32s,), int32_ty) + memRef_Cout_ty = MemRefType.get((C_sz_in_i32s,), int32_ty) + + @FuncOp.from_py_func(memRef_Ain_ty, memRef_Bin_ty, memRef_Cout_ty) + def sequence(A, B, C): + # only do 5 tile rows at a time before synchronizing, so we can reuse BDs + rows_per_block = 5 + for tile_row_block in range( + (M_div_m + rows_per_block - 1) // rows_per_block + ): + C_row_offset_in_i32s = ( + tile_row_block * rows_per_block * m * N * word_size_out // 4 + ) + num_tile_rows = min( + [rows_per_block, M_div_m - tile_row_block * rows_per_block] + ) + IpuDmaMemcpyNd( + metadata="outC", + bd_id=0, + mem=C, + offsets=[0, 0, 0, C_row_offset_in_i32s], + lengths=[num_tile_rows, N_div_n, m, n_in_i32s_out], + strides=[m_x_N_in_i32s_out, n_in_i32s_out, N_in_i32s_out], + ) + for tile_row in range(num_tile_rows): + A_row_offset_in_i32s = ( + ((tile_row_block * rows_per_block) + tile_row) + * m + * K + * word_size_in + // 4 + ) + IpuDmaMemcpyNd( + metadata="inA", + bd_id=2 * tile_row + 1, + mem=A, + offsets=[0, 0, 0, A_row_offset_in_i32s], + lengths=[N_div_n, K_div_k, m, k_in_i32s], + strides=[0, k_in_i32s, K_in_i32s], + ) + IpuDmaMemcpyNd( + metadata="inB", + bd_id=2 * tile_row + 2, + mem=B, + lengths=[N_div_n, K_div_k, k, n_in_i32s], + strides=[n_in_i32s, k_x_N_in_i32s, N_in_i32s], + ) + + IpuSync(column=0, row=0, direction=0, channel=0) + + +@constructAndPrintInModule +def edge_detect(): + @device(AIEDevice.ipu) + def deviceBody(): + uint8_ty = IntegerType.get_unsigned(8) + int8_ty = IntegerType.get_signless(8) + int16_ty = IntegerType.get_signless(16) + int32_ty = IntegerType.get_signless(32) + memRef_256_ty = MemRefType.get((256,), uint8_ty) + memRef_64_ty = MemRefType.get((64,), uint8_ty) + memRef_3x3_ty = MemRefType.get( + ( + 3, + 3, + ), + int16_ty, + ) + + rgba2grayLine = privateFunc( + "rgba2grayLine", inputs=[memRef_256_ty, memRef_64_ty, int32_ty] + ) + filter2dLine = privateFunc( + "filter2dLine", + inputs=[ + memRef_64_ty, + memRef_64_ty, + memRef_64_ty, + memRef_64_ty, + int32_ty, + memRef_3x3_ty, + ], + ) + thresholdLine = privateFunc( + "thresholdLine", + inputs=[memRef_64_ty, memRef_64_ty, int32_ty, int16_ty, int16_ty, int8_ty], + ) + gray2rgbaLine = privateFunc( + "gray2rgbaLine", inputs=[memRef_64_ty, memRef_256_ty, int32_ty] + ) + addWeightedLine = privateFunc( + "addWeightedLine", + inputs=[ + memRef_256_ty, + memRef_256_ty, + memRef_256_ty, + int32_ty, + int16_ty, + int16_ty, + int8_ty, + ], + ) + + S = Tile(0, 0) + M = Tile(0, 1) + T2 = Tile(0, 2) + T3 = Tile(0, 3) + T4 = Tile(0, 4) + T5 = Tile(0, 5) + + OrderedObjectBuffer("inOF_L3L2", S, M, 2, memRef_256_ty) + OrderedObjectBuffer("inOF_L2L1", M, [T2, T5], [2, 2, 7], memRef_256_ty) + Link(["inOF_L3L2"], ["inOF_L2L1"]) + + OrderedObjectBuffer("outOF_L2L3", M, S, 2, memRef_256_ty) + OrderedObjectBuffer("outOF_L1L2", T5, M, 2, memRef_256_ty) + Link(["outOF_L1L2"], ["outOF_L2L3"]) + + OrderedObjectBuffer("OF_2to3", T2, T3, 4, memRef_64_ty) + OrderedObjectBuffer("OF_3to4", T3, T4, 2, memRef_64_ty) + OrderedObjectBuffer("OF_4to5", T4, T5, 2, memRef_64_ty) + OrderedObjectBuffer("OF_5to5", T5, T5, 1, memRef_256_ty) + + @core(T2, "rgba2gray.cc.o") + def coreBody(): + @forLoop(lowerBound=0, upperBound=36, step=1) + def loopBody(): + elemIn = Acquire( + "inOF_L2L1", ObjectFifoPort.Consume, 1, memRef_256_ty + ).acquiredElem() + elemOut = Acquire( + "OF_2to3", ObjectFifoPort.Produce, 1, memRef_64_ty + ).acquiredElem() + + Call(rgba2grayLine, [elemIn, elemOut, integerConstant(64)]) + + Release(ObjectFifoPort.Consume, "inOF_L2L1", 1) + Release(ObjectFifoPort.Produce, "OF_2to3", 1) + + @core(T3, "filter2d.cc.o") + def coreBody(): + kernel = memref.AllocOp(memRef_3x3_ty, [], []) + v0 = integerConstant(0, int16_ty) + v1 = integerConstant(4096, int16_ty) + vMinus4 = integerConstant(-16384, int16_ty) + Store(v0, kernel, [0, 0]) + Store(v1, kernel, [0, 1]) + Store(v0, kernel, [0, 2]) + Store(v1, kernel, [1, 0]) + Store(vMinus4, kernel, [1, 1]) + Store(v1, kernel, [1, 2]) + Store(v0, kernel, [2, 0]) + Store(v1, kernel, [2, 1]) + Store(v0, kernel, [2, 2]) + + # Preamble : Top Border + elemsInPre = Acquire( + "OF_2to3", ObjectFifoPort.Consume, 2, memRef_64_ty + ).acquiredElem() + elemPreOut = Acquire( + "OF_3to4", ObjectFifoPort.Produce, 1, memRef_64_ty + ).acquiredElem() + Call( + filter2dLine, + [ + elemsInPre[0], + elemsInPre[0], + elemsInPre[1], + elemPreOut, + integerConstant(64), + kernel, + ], + ) + Release(ObjectFifoPort.Produce, "OF_3to4", 1) + + # Steady State : Middle + @forLoop(lowerBound=1, upperBound=35, step=1) + def loopBody(): + elemsIn = Acquire( + "OF_2to3", ObjectFifoPort.Consume, 3, memRef_64_ty + ).acquiredElem() + elemOut = Acquire( + "OF_3to4", ObjectFifoPort.Produce, 1, memRef_64_ty + ).acquiredElem() + Call( + filter2dLine, + [ + elemsIn[0], + elemsIn[1], + elemsIn[2], + elemOut, + integerConstant(64), + kernel, + ], + ) + Release(ObjectFifoPort.Consume, "OF_2to3", 1) + Release(ObjectFifoPort.Produce, "OF_3to4", 1) + + # Postamble : Bottom Border + elemsInPost = Acquire( + "OF_2to3", ObjectFifoPort.Consume, 2, memRef_64_ty + ).acquiredElem() + elemPostOut = Acquire( + "OF_3to4", ObjectFifoPort.Produce, 1, memRef_64_ty + ).acquiredElem() + Call( + filter2dLine, + [ + elemsInPost[0], + elemsInPost[1], + elemsInPost[1], + elemPostOut, + integerConstant(64), + kernel, + ], + ) + Release(ObjectFifoPort.Consume, "OF_2to3", 2) + Release(ObjectFifoPort.Produce, "OF_3to4", 1) + + @core(T4, "threshold.cc.o") + def coreBody(): + vThr = integerConstant(10, int16_ty) + vMax = integerConstant(255, int16_ty) + vTyp = integerConstant(0, int8_ty) + + @forLoop(lowerBound=0, upperBound=36, step=1) + def loopBody(): + elemIn = Acquire( + "OF_3to4", ObjectFifoPort.Consume, 1, memRef_64_ty + ).acquiredElem() + elemOut = Acquire( + "OF_4to5", ObjectFifoPort.Produce, 1, memRef_64_ty + ).acquiredElem() + + Call( + thresholdLine, + [elemIn, elemOut, integerConstant(64), vThr, vMax, vTyp], + ) + + Release(ObjectFifoPort.Consume, "OF_3to4", 1) + Release(ObjectFifoPort.Produce, "OF_4to5", 1) + + @core(T5, "combined_gray2rgba_addWeighted.a") + def coreBody(): + @forLoop(lowerBound=0, upperBound=36, step=1) + def loopBody(): + elemIn = Acquire( + "OF_4to5", ObjectFifoPort.Consume, 1, memRef_64_ty + ).acquiredElem() + elemOut = Acquire( + "OF_5to5", ObjectFifoPort.Produce, 1, memRef_256_ty + ).acquiredElem() + + Call(gray2rgbaLine, [elemIn, elemOut, integerConstant(64)]) + + Release(ObjectFifoPort.Consume, "OF_4to5", 1) + Release(ObjectFifoPort.Produce, "OF_5to5", 1) + + elemIn1 = Acquire( + "OF_5to5", ObjectFifoPort.Consume, 1, memRef_256_ty + ).acquiredElem() + elemIn2 = Acquire( + "inOF_L2L1", ObjectFifoPort.Consume, 1, memRef_256_ty + ).acquiredElem() + elemOut2 = Acquire( + "outOF_L1L2", ObjectFifoPort.Produce, 1, memRef_256_ty + ).acquiredElem() + + alpha = integerConstant(16384, int16_ty) + beta = integerConstant(16384, int16_ty) + gamma = integerConstant(0, int8_ty) + + Call( + addWeightedLine, + [ + elemIn1, + elemIn2, + elemOut2, + integerConstant(256), + alpha, + beta, + gamma, + ], + ) + + Release(ObjectFifoPort.Consume, "OF_5to5", 1) + Release(ObjectFifoPort.Consume, "inOF_L2L1", 1) + Release(ObjectFifoPort.Produce, "outOF_L1L2", 1) + + memRef_mem_ty = MemRefType.get((2304,), int32_ty) + + @FuncOp.from_py_func(memRef_mem_ty, memRef_mem_ty, memRef_mem_ty) + def sequence(I, B, O): + IpuDmaMemcpyNd( + metadata="outOF_L2L3", + bd_id=0, + mem=O, + lengths=[1, 1, 36, 64], + strides=[0, 0, 64], + ) + IpuDmaMemcpyNd( + metadata="inOF_L3L2", + bd_id=1, + mem=I, + lengths=[1, 1, 36, 64], + strides=[0, 0, 64], + ) + IpuSync(column=0, row=0, direction=0, channel=0) From fe05e593d2371a208273c7ac3b85e03c2ccdf5ee Mon Sep 17 00:00:00 2001 From: max Date: Mon, 13 Nov 2023 16:00:29 -0600 Subject: [PATCH 8/9] failing test --- test/python/ipu.py | 261 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 259 insertions(+), 2 deletions(-) diff --git a/test/python/ipu.py b/test/python/ipu.py index a015a6d7a2..48698d49c4 100644 --- a/test/python/ipu.py +++ b/test/python/ipu.py @@ -4,13 +4,67 @@ # # (c) Copyright 2023 AMD Inc. +# RUN: %python %s | FileCheck %s + +import aie from aie.ir import * from aie.dialects.func import * from aie.dialects.scf import * from aie.dialects.aie import * from aie.dialects.aiex import * - - +from aie.passmanager import PassManager + + +def constructAndPrintInModule(f): + with Context() as ctx, Location.unknown(): + aie.dialects.aie.register_dialect(ctx) + module = Module.create() + print("\nTEST:", f.__name__) + with InsertionPoint(module.body): + f() + pm = PassManager("builtin.module") + pm.add("canonicalize") + pm.run(module.operation) + print(module) + + +# CHECK-LABEL: my_vector_scalar +# CHECK: module { +# CHECK: AIE.device(ipu) { +# CHECK: func.func private @scale_int32(memref<1024xi32>, memref<1024xi32>) +# CHECK: %tile_0_0 = AIE.tile(0, 0) +# CHECK: %tile_0_2 = AIE.tile(0, 2) +# CHECK: AIE.objectFifo @in(%tile_0_0, {%tile_0_2}, 2 : i32) : !AIE.objectFifo> +# CHECK: AIE.objectFifo @out(%tile_0_2, {%tile_0_0}, 2 : i32) : !AIE.objectFifo> +# CHECK: %core_0_2 = AIE.core(%tile_0_2) { +# CHECK: %c4 = arith.constant 4 : index +# CHECK: %c0 = arith.constant 0 : index +# CHECK: %c4294967295 = arith.constant 4294967295 : index +# CHECK: %c1 = arith.constant 1 : index +# CHECK: scf.for %arg0 = %c0 to %c4294967295 step %c1 { +# CHECK: scf.for %arg1 = %c0 to %c4 step %c1 { +# CHECK: %0 = AIE.objectFifo.acquire @out(Produce, 1) : !AIE.objectFifoSubview> +# CHECK: %1 = AIE.objectFifo.subview.access %0[0] : !AIE.objectFifoSubview> -> memref<1024xi32> +# CHECK: %2 = AIE.objectFifo.acquire @in(Consume, 1) : !AIE.objectFifoSubview> +# CHECK: %3 = AIE.objectFifo.subview.access %2[0] : !AIE.objectFifoSubview> -> memref<1024xi32> +# CHECK: func.call @scale_int32(%3, %1) : (memref<1024xi32>, memref<1024xi32>) -> () +# CHECK: AIE.objectFifo.release @in(Consume, 1) +# CHECK: AIE.objectFifo.release @out(Produce, 1) +# CHECK: } +# CHECK: } +# CHECK: AIE.end +# CHECK: } {link_with = "scale.o"} +# CHECK: func.func @sequence(%arg0: memref<4096xi32>, %arg1: memref<4096xi32>, %arg2: memref<4096xi32>) { +# CHECK: %c0_i32 = arith.constant 0 : i32 +# CHECK: %c1_i32 = arith.constant 1 : i32 +# CHECK: %c4096_i32 = arith.constant 4096 : i32 +# CHECK: AIEX.ipu.dma_memcpy_nd(%c0_i32, %c0_i32, %arg2[%c0_i32, %c0_i32, %c0_i32, %c0_i32] [%c1_i32, %c1_i32, %c1_i32, %c4096_i32] [%c0_i32, %c0_i32, %c0_i32]) {id = 0 : i32, metadata = @out} : (i32, i32, memref<4096xi32>, [i32, i32, i32, i32], [i32, i32, i32, i32], [i32, i32, i32]) +# CHECK: AIEX.ipu.dma_memcpy_nd(%c0_i32, %c0_i32, %arg0[%c0_i32, %c0_i32, %c0_i32, %c0_i32] [%c1_i32, %c1_i32, %c1_i32, %c4096_i32] [%c0_i32, %c0_i32, %c0_i32]) {id = 1 : i32, metadata = @in} : (i32, i32, memref<4096xi32>, [i32, i32, i32, i32], [i32, i32, i32, i32], [i32, i32, i32]) +# CHECK: AIEX.ipu.sync {channel = 0 : i32, column = 0 : i32, column_num = 1 : i32, direction = 0 : i32, row = 0 : i32, row_num = 1 : i32} +# CHECK: return +# CHECK: } +# CHECK: } +# CHECK: } @constructAndPrintInModule def my_vector_scalar(): N = 4095 @@ -60,6 +114,62 @@ def sequence(A, B, C): IpuSync(column=0, row=0, direction=0, channel=0) +# CHECK-LABEL: my_matmul +# CHECK: module { +# CHECK: AIE.device(ipu) { +# CHECK: func.func private @zero_scalar_i16(memref<64x64xi16>) +# CHECK: func.func private @zero_i16(memref<64x64xi16>) +# CHECK: func.func private @matmul_scalar_i16_i16(memref<64x32xi16>, memref<32x64xi16>, memref<64x64xi16>) +# CHECK: func.func private @matmul_i16_i16(memref<64x32xi16>, memref<32x64xi16>, memref<64x64xi16>) +# CHECK: %tile_0_0 = AIE.tile(0, 0) +# CHECK: %tile_0_1 = AIE.tile(0, 1) +# CHECK: %tile_0_2 = AIE.tile(0, 2) +# CHECK: AIE.objectFifo @inA(%tile_0_0, {%tile_0_2}, 2 : i32) : !AIE.objectFifo> +# CHECK: AIE.objectFifo @inB(%tile_0_0, {%tile_0_2}, 2 : i32) : !AIE.objectFifo> +# CHECK: AIE.objectFifo @outC(%tile_0_2, {%tile_0_0}, 2 : i32) : !AIE.objectFifo> +# CHECK: %core_0_2 = AIE.core(%tile_0_2) { +# CHECK: %c4 = arith.constant 4 : index +# CHECK: %c0 = arith.constant 0 : index +# CHECK: %c4294967295 = arith.constant 4294967295 : index +# CHECK: %c1 = arith.constant 1 : index +# CHECK: scf.for %arg0 = %c0 to %c4294967295 step %c1 { +# CHECK: scf.for %arg1 = %c0 to %c4 step %c1 { +# CHECK: %0 = AIE.objectFifo.acquire @outC(Produce, 1) : !AIE.objectFifoSubview> +# CHECK: %1 = AIE.objectFifo.subview.access %0[0] : !AIE.objectFifoSubview> -> memref<64x64xi16> +# CHECK: func.call @zero_i16(%1) : (memref<64x64xi16>) -> () +# CHECK: scf.for %arg2 = %c0 to %c4 step %c1 { +# CHECK: %2 = AIE.objectFifo.acquire @inA(Consume, 1) : !AIE.objectFifoSubview> +# CHECK: %3 = AIE.objectFifo.subview.access %2[0] : !AIE.objectFifoSubview> -> memref<64x32xi16> +# CHECK: %4 = AIE.objectFifo.acquire @inB(Consume, 1) : !AIE.objectFifoSubview> +# CHECK: %5 = AIE.objectFifo.subview.access %4[0] : !AIE.objectFifoSubview> -> memref<32x64xi16> +# CHECK: func.call @matmul_i16_i16(%3, %5, %1) : (memref<64x32xi16>, memref<32x64xi16>, memref<64x64xi16>) -> () +# CHECK: AIE.objectFifo.release @inA(Consume, 1) +# CHECK: AIE.objectFifo.release @inB(Consume, 1) +# CHECK: } +# CHECK: AIE.objectFifo.release @outC(Produce, 1) +# CHECK: } +# CHECK: } +# CHECK: AIE.end +# CHECK: } {link_with = "mm.o"} +# CHECK: func.func @sequence(%arg0: memref<8192xi32>, %arg1: memref<8192xi32>, %arg2: memref<8192xi32>) { +# CHECK: %c2048_i32 = arith.constant 2048 : i32 +# CHECK: %c16_i32 = arith.constant 16 : i32 +# CHECK: %c4_i32 = arith.constant 4 : i32 +# CHECK: %c0_i32 = arith.constant 0 : i32 +# CHECK: %c2_i32 = arith.constant 2 : i32 +# CHECK: %c64_i32 = arith.constant 64 : i32 +# CHECK: %c32_i32 = arith.constant 32 : i32 +# CHECK: %c4096_i32 = arith.constant 4096 : i32 +# CHECK: AIEX.ipu.dma_memcpy_nd(%c0_i32, %c0_i32, %arg2[%c0_i32, %c0_i32, %c0_i32, %c0_i32] [%c2_i32, %c2_i32, %c64_i32, %c32_i32] [%c4096_i32, %c32_i32, %c64_i32]) {id = 0 : i32, metadata = @outC} : (i32, i32, memref<8192xi32>, [i32, i32, i32, i32], [i32, i32, i32, i32], [i32, i32, i32]) +# CHECK: AIEX.ipu.dma_memcpy_nd(%c0_i32, %c0_i32, %arg0[%c0_i32, %c0_i32, %c0_i32, %c0_i32] [%c2_i32, %c4_i32, %c64_i32, %c16_i32] [%c0_i32, %c16_i32, %c64_i32]) {id = 1 : i32, metadata = @inA} : (i32, i32, memref<8192xi32>, [i32, i32, i32, i32], [i32, i32, i32, i32], [i32, i32, i32]) +# CHECK: AIEX.ipu.dma_memcpy_nd(%c0_i32, %c0_i32, %arg1[%c0_i32, %c0_i32, %c0_i32, %c0_i32] [%c2_i32, %c4_i32, %c32_i32, %c32_i32] [%c32_i32, %c2048_i32, %c64_i32]) {id = 2 : i32, metadata = @inB} : (i32, i32, memref<8192xi32>, [i32, i32, i32, i32], [i32, i32, i32, i32], [i32, i32, i32]) +# CHECK: AIEX.ipu.dma_memcpy_nd(%c0_i32, %c0_i32, %arg0[%c0_i32, %c0_i32, %c0_i32, %c4096_i32] [%c2_i32, %c4_i32, %c64_i32, %c16_i32] [%c0_i32, %c16_i32, %c64_i32]) {id = 3 : i32, metadata = @inA} : (i32, i32, memref<8192xi32>, [i32, i32, i32, i32], [i32, i32, i32, i32], [i32, i32, i32]) +# CHECK: AIEX.ipu.dma_memcpy_nd(%c0_i32, %c0_i32, %arg1[%c0_i32, %c0_i32, %c0_i32, %c0_i32] [%c2_i32, %c4_i32, %c32_i32, %c32_i32] [%c32_i32, %c2048_i32, %c64_i32]) {id = 4 : i32, metadata = @inB} : (i32, i32, memref<8192xi32>, [i32, i32, i32, i32], [i32, i32, i32, i32], [i32, i32, i32]) +# CHECK: AIEX.ipu.sync {channel = 0 : i32, column = 0 : i32, column_num = 1 : i32, direction = 0 : i32, row = 0 : i32, row_num = 1 : i32} +# CHECK: return +# CHECK: } +# CHECK: } +# CHECK: } @constructAndPrintInModule def my_matmul(): M = 128 @@ -224,6 +334,153 @@ def sequence(A, B, C): IpuSync(column=0, row=0, direction=0, channel=0) +# CHECK-LABEL: edge_detect +# CHECK: module { +# CHECK: AIE.device(ipu) { +# CHECK: func.func private @rgba2grayLine(memref<256xui8>, memref<64xui8>, i32) +# CHECK: func.func private @filter2dLine(memref<64xui8>, memref<64xui8>, memref<64xui8>, memref<64xui8>, i32, memref<3x3xi16>) +# CHECK: func.func private @thresholdLine(memref<64xui8>, memref<64xui8>, i32, i16, i16, i8) +# CHECK: func.func private @gray2rgbaLine(memref<64xui8>, memref<256xui8>, i32) +# CHECK: func.func private @addWeightedLine(memref<256xui8>, memref<256xui8>, memref<256xui8>, i32, i16, i16, i8) +# CHECK: %tile_0_0 = AIE.tile(0, 0) +# CHECK: %tile_0_1 = AIE.tile(0, 1) +# CHECK: %tile_0_2 = AIE.tile(0, 2) +# CHECK: %tile_0_3 = AIE.tile(0, 3) +# CHECK: %tile_0_4 = AIE.tile(0, 4) +# CHECK: %tile_0_5 = AIE.tile(0, 5) +# CHECK: AIE.objectFifo @inOF_L3L2(%tile_0_0, {%tile_0_1}, 2 : i32) : !AIE.objectFifo> +# CHECK: AIE.objectFifo @inOF_L2L1(%tile_0_1, {%tile_0_2, %tile_0_5}, [2 : i32, 2 : i32, 7 : i32]) : !AIE.objectFifo> +# CHECK: AIE.objectFifo.link [@inOF_L3L2] -> [@inOF_L2L1]() +# CHECK: AIE.objectFifo @outOF_L2L3(%tile_0_1, {%tile_0_0}, 2 : i32) : !AIE.objectFifo> +# CHECK: AIE.objectFifo @outOF_L1L2(%tile_0_5, {%tile_0_1}, 2 : i32) : !AIE.objectFifo> +# CHECK: AIE.objectFifo.link [@outOF_L1L2] -> [@outOF_L2L3]() +# CHECK: AIE.objectFifo @OF_2to3(%tile_0_2, {%tile_0_3}, 4 : i32) : !AIE.objectFifo> +# CHECK: AIE.objectFifo @OF_3to4(%tile_0_3, {%tile_0_4}, 2 : i32) : !AIE.objectFifo> +# CHECK: AIE.objectFifo @OF_4to5(%tile_0_4, {%tile_0_5}, 2 : i32) : !AIE.objectFifo> +# CHECK: AIE.objectFifo @OF_5to5(%tile_0_5, {%tile_0_5}, 1 : i32) : !AIE.objectFifo> +# CHECK: %core_0_2 = AIE.core(%tile_0_2) { +# CHECK: %c64_i32 = arith.constant 64 : i32 +# CHECK: %c0 = arith.constant 0 : index +# CHECK: %c36 = arith.constant 36 : index +# CHECK: %c1 = arith.constant 1 : index +# CHECK: scf.for %arg0 = %c0 to %c36 step %c1 { +# CHECK: %0 = AIE.objectFifo.acquire @inOF_L2L1(Consume, 1) : !AIE.objectFifoSubview> +# CHECK: %1 = AIE.objectFifo.subview.access %0[0] : !AIE.objectFifoSubview> -> memref<256xui8> +# CHECK: %2 = AIE.objectFifo.acquire @OF_2to3(Produce, 1) : !AIE.objectFifoSubview> +# CHECK: %3 = AIE.objectFifo.subview.access %2[0] : !AIE.objectFifoSubview> -> memref<64xui8> +# CHECK: func.call @rgba2grayLine(%1, %3, %c64_i32) : (memref<256xui8>, memref<64xui8>, i32) -> () +# CHECK: AIE.objectFifo.release @inOF_L2L1(Consume, 1) +# CHECK: AIE.objectFifo.release @OF_2to3(Produce, 1) +# CHECK: } +# CHECK: AIE.end +# CHECK: } {link_with = "rgba2gray.cc.o"} +# CHECK: %core_0_3 = AIE.core(%tile_0_3) { +# CHECK: %c35 = arith.constant 35 : index +# CHECK: %c64_i32 = arith.constant 64 : i32 +# CHECK: %c2 = arith.constant 2 : index +# CHECK: %c1 = arith.constant 1 : index +# CHECK: %c0 = arith.constant 0 : index +# CHECK: %c-16384_i16 = arith.constant -16384 : i16 +# CHECK: %c4096_i16 = arith.constant 4096 : i16 +# CHECK: %c0_i16 = arith.constant 0 : i16 +# CHECK: %alloc = memref.alloc() : memref<3x3xi16> +# CHECK: memref.store %c0_i16, %alloc[%c0, %c0] : memref<3x3xi16> +# CHECK: memref.store %c4096_i16, %alloc[%c0, %c1] : memref<3x3xi16> +# CHECK: memref.store %c0_i16, %alloc[%c0, %c2] : memref<3x3xi16> +# CHECK: memref.store %c4096_i16, %alloc[%c1, %c0] : memref<3x3xi16> +# CHECK: memref.store %c-16384_i16, %alloc[%c1, %c1] : memref<3x3xi16> +# CHECK: memref.store %c4096_i16, %alloc[%c1, %c2] : memref<3x3xi16> +# CHECK: memref.store %c0_i16, %alloc[%c2, %c0] : memref<3x3xi16> +# CHECK: memref.store %c4096_i16, %alloc[%c2, %c1] : memref<3x3xi16> +# CHECK: memref.store %c0_i16, %alloc[%c2, %c2] : memref<3x3xi16> +# CHECK: %0 = AIE.objectFifo.acquire @OF_2to3(Consume, 2) : !AIE.objectFifoSubview> +# CHECK: %1 = AIE.objectFifo.subview.access %0[0] : !AIE.objectFifoSubview> -> memref<64xui8> +# CHECK: %2 = AIE.objectFifo.subview.access %0[1] : !AIE.objectFifoSubview> -> memref<64xui8> +# CHECK: %3 = AIE.objectFifo.acquire @OF_3to4(Produce, 1) : !AIE.objectFifoSubview> +# CHECK: %4 = AIE.objectFifo.subview.access %3[0] : !AIE.objectFifoSubview> -> memref<64xui8> +# CHECK: func.call @filter2dLine(%1, %1, %2, %4, %c64_i32, %alloc) : (memref<64xui8>, memref<64xui8>, memref<64xui8>, memref<64xui8>, i32, memref<3x3xi16>) -> () +# CHECK: AIE.objectFifo.release @OF_3to4(Produce, 1) +# CHECK: scf.for %arg0 = %c1 to %c35 step %c1 { +# CHECK: %10 = AIE.objectFifo.acquire @OF_2to3(Consume, 3) : !AIE.objectFifoSubview> +# CHECK: %11 = AIE.objectFifo.subview.access %10[0] : !AIE.objectFifoSubview> -> memref<64xui8> +# CHECK: %12 = AIE.objectFifo.subview.access %10[1] : !AIE.objectFifoSubview> -> memref<64xui8> +# CHECK: %13 = AIE.objectFifo.subview.access %10[2] : !AIE.objectFifoSubview> -> memref<64xui8> +# CHECK: %14 = AIE.objectFifo.acquire @OF_3to4(Produce, 1) : !AIE.objectFifoSubview> +# CHECK: %15 = AIE.objectFifo.subview.access %14[0] : !AIE.objectFifoSubview> -> memref<64xui8> +# CHECK: func.call @filter2dLine(%11, %12, %13, %15, %c64_i32, %alloc) : (memref<64xui8>, memref<64xui8>, memref<64xui8>, memref<64xui8>, i32, memref<3x3xi16>) -> () +# CHECK: AIE.objectFifo.release @OF_2to3(Consume, 1) +# CHECK: AIE.objectFifo.release @OF_3to4(Produce, 1) +# CHECK: } +# CHECK: %5 = AIE.objectFifo.acquire @OF_2to3(Consume, 2) : !AIE.objectFifoSubview> +# CHECK: %6 = AIE.objectFifo.subview.access %5[0] : !AIE.objectFifoSubview> -> memref<64xui8> +# CHECK: %7 = AIE.objectFifo.subview.access %5[1] : !AIE.objectFifoSubview> -> memref<64xui8> +# CHECK: %8 = AIE.objectFifo.acquire @OF_3to4(Produce, 1) : !AIE.objectFifoSubview> +# CHECK: %9 = AIE.objectFifo.subview.access %8[0] : !AIE.objectFifoSubview> -> memref<64xui8> +# CHECK: func.call @filter2dLine(%6, %7, %7, %9, %c64_i32, %alloc) : (memref<64xui8>, memref<64xui8>, memref<64xui8>, memref<64xui8>, i32, memref<3x3xi16>) -> () +# CHECK: AIE.objectFifo.release @OF_2to3(Consume, 2) +# CHECK: AIE.objectFifo.release @OF_3to4(Produce, 1) +# CHECK: AIE.end +# CHECK: } {link_with = "filter2d.cc.o"} +# CHECK: %core_0_4 = AIE.core(%tile_0_4) { +# CHECK: %c64_i32 = arith.constant 64 : i32 +# CHECK: %c10_i16 = arith.constant 10 : i16 +# CHECK: %c255_i16 = arith.constant 255 : i16 +# CHECK: %c0_i8 = arith.constant 0 : i8 +# CHECK: %c0 = arith.constant 0 : index +# CHECK: %c36 = arith.constant 36 : index +# CHECK: %c1 = arith.constant 1 : index +# CHECK: scf.for %arg0 = %c0 to %c36 step %c1 { +# CHECK: %0 = AIE.objectFifo.acquire @OF_3to4(Consume, 1) : !AIE.objectFifoSubview> +# CHECK: %1 = AIE.objectFifo.subview.access %0[0] : !AIE.objectFifoSubview> -> memref<64xui8> +# CHECK: %2 = AIE.objectFifo.acquire @OF_4to5(Produce, 1) : !AIE.objectFifoSubview> +# CHECK: %3 = AIE.objectFifo.subview.access %2[0] : !AIE.objectFifoSubview> -> memref<64xui8> +# CHECK: func.call @thresholdLine(%1, %3, %c64_i32, %c10_i16, %c255_i16, %c0_i8) : (memref<64xui8>, memref<64xui8>, i32, i16, i16, i8) -> () +# CHECK: AIE.objectFifo.release @OF_3to4(Consume, 1) +# CHECK: AIE.objectFifo.release @OF_4to5(Produce, 1) +# CHECK: } +# CHECK: AIE.end +# CHECK: } {link_with = "threshold.cc.o"} +# CHECK: %core_0_5 = AIE.core(%tile_0_5) { +# CHECK: %c256_i32 = arith.constant 256 : i32 +# CHECK: %c0_i8 = arith.constant 0 : i8 +# CHECK: %c16384_i16 = arith.constant 16384 : i16 +# CHECK: %c64_i32 = arith.constant 64 : i32 +# CHECK: %c0 = arith.constant 0 : index +# CHECK: %c36 = arith.constant 36 : index +# CHECK: %c1 = arith.constant 1 : index +# CHECK: scf.for %arg0 = %c0 to %c36 step %c1 { +# CHECK: %0 = AIE.objectFifo.acquire @OF_4to5(Consume, 1) : !AIE.objectFifoSubview> +# CHECK: %1 = AIE.objectFifo.subview.access %0[0] : !AIE.objectFifoSubview> -> memref<64xui8> +# CHECK: %2 = AIE.objectFifo.acquire @OF_5to5(Produce, 1) : !AIE.objectFifoSubview> +# CHECK: %3 = AIE.objectFifo.subview.access %2[0] : !AIE.objectFifoSubview> -> memref<256xui8> +# CHECK: func.call @gray2rgbaLine(%1, %3, %c64_i32) : (memref<64xui8>, memref<256xui8>, i32) -> () +# CHECK: AIE.objectFifo.release @OF_4to5(Consume, 1) +# CHECK: AIE.objectFifo.release @OF_5to5(Produce, 1) +# CHECK: %4 = AIE.objectFifo.acquire @OF_5to5(Consume, 1) : !AIE.objectFifoSubview> +# CHECK: %5 = AIE.objectFifo.subview.access %4[0] : !AIE.objectFifoSubview> -> memref<256xui8> +# CHECK: %6 = AIE.objectFifo.acquire @inOF_L2L1(Consume, 1) : !AIE.objectFifoSubview> +# CHECK: %7 = AIE.objectFifo.subview.access %6[0] : !AIE.objectFifoSubview> -> memref<256xui8> +# CHECK: %8 = AIE.objectFifo.acquire @outOF_L1L2(Produce, 1) : !AIE.objectFifoSubview> +# CHECK: %9 = AIE.objectFifo.subview.access %8[0] : !AIE.objectFifoSubview> -> memref<256xui8> +# CHECK: func.call @addWeightedLine(%5, %7, %9, %c256_i32, %c16384_i16, %c16384_i16, %c0_i8) : (memref<256xui8>, memref<256xui8>, memref<256xui8>, i32, i16, i16, i8) -> () +# CHECK: AIE.objectFifo.release @OF_5to5(Consume, 1) +# CHECK: AIE.objectFifo.release @inOF_L2L1(Consume, 1) +# CHECK: AIE.objectFifo.release @outOF_L1L2(Produce, 1) +# CHECK: } +# CHECK: AIE.end +# CHECK: } {link_with = "combined_gray2rgba_addWeighted.a"} +# CHECK: func.func @sequence(%arg0: memref<2304xi32>, %arg1: memref<2304xi32>, %arg2: memref<2304xi32>) { +# CHECK: %c0_i32 = arith.constant 0 : i32 +# CHECK: %c1_i32 = arith.constant 1 : i32 +# CHECK: %c36_i32 = arith.constant 36 : i32 +# CHECK: %c64_i32 = arith.constant 64 : i32 +# CHECK: AIEX.ipu.dma_memcpy_nd(%c0_i32, %c0_i32, %arg2[%c0_i32, %c0_i32, %c0_i32, %c0_i32] [%c1_i32, %c1_i32, %c36_i32, %c64_i32] [%c0_i32, %c0_i32, %c64_i32]) {id = 0 : i32, metadata = @outOF_L2L3} : (i32, i32, memref<2304xi32>, [i32, i32, i32, i32], [i32, i32, i32, i32], [i32, i32, i32]) +# CHECK: AIEX.ipu.dma_memcpy_nd(%c0_i32, %c0_i32, %arg0[%c0_i32, %c0_i32, %c0_i32, %c0_i32] [%c1_i32, %c1_i32, %c36_i32, %c64_i32] [%c0_i32, %c0_i32, %c64_i32]) {id = 1 : i32, metadata = @inOF_L3L2} : (i32, i32, memref<2304xi32>, [i32, i32, i32, i32], [i32, i32, i32, i32], [i32, i32, i32]) +# CHECK: AIEX.ipu.sync {channel = 0 : i32, column = 0 : i32, column_num = 1 : i32, direction = 0 : i32, row = 0 : i32, row_num = 1 : i32} +# CHECK: return +# CHECK: } +# CHECK: } +# CHECK: } @constructAndPrintInModule def edge_detect(): @device(AIEDevice.ipu) From 201a4e5917326f56dc1ac6a3f4b553ca5a7c3bce Mon Sep 17 00:00:00 2001 From: max Date: Mon, 13 Nov 2023 16:03:44 -0600 Subject: [PATCH 9/9] passing test --- test/python/ipu.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/test/python/ipu.py b/test/python/ipu.py index 48698d49c4..e3c3efa09a 100644 --- a/test/python/ipu.py +++ b/test/python/ipu.py @@ -65,14 +65,15 @@ def constructAndPrintInModule(f): # CHECK: } # CHECK: } # CHECK: } + @constructAndPrintInModule def my_vector_scalar(): - N = 4095 - n = 1023 + N = 4096 + n = 1024 N_div_n = N // n N_in_bytes = N * 3 - buffer_depth = 1 + buffer_depth = 2 @device(AIEDevice.ipu) def deviceBody(): @@ -170,6 +171,7 @@ def sequence(A, B, C): # CHECK: } # CHECK: } # CHECK: } + @constructAndPrintInModule def my_matmul(): M = 128 @@ -481,6 +483,7 @@ def sequence(A, B, C): # CHECK: } # CHECK: } # CHECK: } + @constructAndPrintInModule def edge_detect(): @device(AIEDevice.ipu)