From fcfc5a1d808b83c519cc075a51075fa4fef9dabe Mon Sep 17 00:00:00 2001 From: Erika Hunhoff Date: Mon, 18 May 2026 13:23:27 -0600 Subject: [PATCH 1/5] [AIE] objectfifo: handle ArrayAttr depth in initValues printer printObjectFifoInitValues unconditionally cast $elemNumber to IntegerAttr, which is null when $elemNumber is the ArrayAttr form (per-endpoint depths). The subsequent .getInt() then segfaults during str() of any objectfifo op that has both list-shaped depth AND initValues. The parser already handles both shapes; the printer now mirrors it. Add a roundtrip lit test. Reduced repro (Python): object_fifo("test", memtile, compute, [2, 1], np.ndarray[(16,), np.dtype[np.int32]], initValues=[np.zeros(16, np.int32), np.ones(16, np.int32)]) # str(ctx.module) -> Segmentation fault (was) Co-Authored-By: Claude Opus 4 (1M context) --- lib/Dialect/AIE/IR/AIEDialect.cpp | 12 ++++++++- ...ifo_array_depth_init_values_roundtrip.mlir | 26 +++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 test/dialect/AIE/objectfifo_array_depth_init_values_roundtrip.mlir diff --git a/lib/Dialect/AIE/IR/AIEDialect.cpp b/lib/Dialect/AIE/IR/AIEDialect.cpp index b9a6f92c52c..98e34be71b7 100644 --- a/lib/Dialect/AIE/IR/AIEDialect.cpp +++ b/lib/Dialect/AIE/IR/AIEDialect.cpp @@ -642,7 +642,17 @@ static void printObjectFifoInitValues(OpAsmPrinter &p, ObjectFifoCreateOp op, Attribute initValues) { if (op.getInitValues()) { p << "= ["; - int depth = llvm::dyn_cast(numElem).getInt(); + // `numElem` may be an IntegerAttr (scalar depth) or an ArrayAttr of + // per-endpoint depths; initValues populates the producer side, which + // is the first entry of the ArrayAttr. + int depth; + if (isa(numElem)) { + depth = llvm::dyn_cast( + llvm::dyn_cast(numElem)[0]) + .getInt(); + } else { + depth = llvm::dyn_cast(numElem).getInt(); + } for (int i = 0; i < depth; i++) { p.printStrippedAttrOrType(llvm::dyn_cast(initValues)[i]); if (i < depth - 1) { diff --git a/test/dialect/AIE/objectfifo_array_depth_init_values_roundtrip.mlir b/test/dialect/AIE/objectfifo_array_depth_init_values_roundtrip.mlir new file mode 100644 index 00000000000..9637729c4e9 --- /dev/null +++ b/test/dialect/AIE/objectfifo_array_depth_init_values_roundtrip.mlir @@ -0,0 +1,26 @@ +//===- objectfifo_array_depth_init_values_roundtrip.mlir -------*- MLIR -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// Round-trip an aie.objectfifo with array-valued $elemNumber (per-endpoint +// depths) AND initValues. Verifies printObjectFifoInitValues handles both +// the IntegerAttr (scalar) and ArrayAttr (list) shapes of $elemNumber. + +// RUN: aie-opt --canonicalize %s | FileCheck %s + +// CHECK-LABEL: aie.device(npu2) +// CHECK: aie.objectfifo @of_array_depth(%{{.*}}, {%{{.*}}}, [2 : i32, 1 : i32]) : !aie.objectfifo> = [dense<0> : memref<16xi32>, dense<1> : memref<16xi32>] + +module @objectfifo_array_depth_initvalues_roundtrip { + aie.device(npu2) { + %mem = aie.tile(0, 1) + %compute = aie.tile(0, 2) + aie.objectfifo @of_array_depth(%mem, {%compute}, [2 : i32, 1 : i32]) + : !aie.objectfifo> + = [dense<0> : memref<16xi32>, dense<1> : memref<16xi32>] + } +} From 95660be7e6548b88ec99083f2abc5a291d40da66 Mon Sep 17 00:00:00 2001 From: Erika Hunhoff Date: Mon, 18 May 2026 13:35:28 -0600 Subject: [PATCH 2/5] [IRON] ObjectFifo: expose init_values constructor arg MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plumb init_values through IRON ObjectFifo to the underlying aie.dialects.aie.object_fifo's `initValues` attribute, so designs that want statically-initialized buffers (e.g. weight tensors held on a MemTile, no shim load) can express it at the IRON level rather than dropping to the low-level op. Producer endpoint pinning is the user's responsibility — when no Worker or rt.fill targets the producer, set it explicitly: of = ObjectFifo(ty, depth=2, init_values=[arr0, arr1]) of.prod().endpoint = ObjectFifoEndpoint(AnyMemTile) (The op verifier rejects init_values on shim producers.) Add a unit test that builds an IRON ObjectFifo with init_values, pins the producer to AnyMemTile, and FileChecks the lowered MLIR contains the expected `= [dense<0>..., dense<1>...]` initial values. Co-Authored-By: Claude Opus 4 (1M context) --- python/iron/dataflow/objectfifo.py | 4 ++ test/python/objFifo_iron_init_values.py | 65 +++++++++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 test/python/objFifo_iron_init_values.py diff --git a/python/iron/dataflow/objectfifo.py b/python/iron/dataflow/objectfifo.py index c4ea52ee53c..132ece43c05 100644 --- a/python/iron/dataflow/objectfifo.py +++ b/python/iron/dataflow/objectfifo.py @@ -46,6 +46,7 @@ def __init__( dims_from_stream_per_cons: list[Sequence[int]] | None = None, plio: bool = False, pad_dimensions: list[Sequence[int]] | None = None, + init_values: list[np.ndarray] | None = None, ): """Construct an ObjectFifo. @@ -56,6 +57,7 @@ def __init__( dims_to_stream (list[Sequence[int]] | None, optional): Data layout transformations applied when data is pushed onto the AXI stream, described as pairs of (size, stride) from highest to lowest dimension. Defaults to None. dims_from_stream_per_cons (list[Sequence[int]] | None, optional): List of data layout transformations applied by each consumer when data is read from the AXI stream, described as pairs of (size, stride) from highest to lowest dimension. Defaults to None. plio (bool, optional): Whether the ObjectFifo uses PLIO connections. Defaults to False. + init_values (list[np.ndarray] | None, optional): Per-buffer static initial values for the producer endpoint. One ndarray per producer-side buffer; the producer tile must be able to hold static data at design startup (e.g. a MemTile). Lowers to the ``initValues`` attribute on the underlying ``aie.objectfifo`` op. Defaults to None. Raises: ValueError: If ``depth`` is provided and is less than 1. @@ -79,6 +81,7 @@ def __init__( self._cons: list[ObjectFifoHandle] = [] self._resolving = False self._iter_count: int | None = None + self._init_values: list[np.ndarray] | None = init_values @classmethod def __get_index(cls) -> int: @@ -298,6 +301,7 @@ def resolve( plio=self._plio, padDimensions=self._pad_dimensions, iter_count=self._iter_count, + initValues=self._init_values, ) if isinstance(self._prod.endpoint, ObjectFifoLink): diff --git a/test/python/objFifo_iron_init_values.py b/test/python/objFifo_iron_init_values.py new file mode 100644 index 00000000000..433481083cf --- /dev/null +++ b/test/python/objFifo_iron_init_values.py @@ -0,0 +1,65 @@ +# 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 2026 AMD Inc. + +# RUN: %python %s | FileCheck %s + +import numpy as np + +from aie.iron import ObjectFifo, Program, Runtime, Worker +from aie.iron.controlflow import range_ +from aie.iron.device import NPU1Col1, AnyMemTile +from aie.iron.dataflow.endpoint import ObjectFifoEndpoint + + +# CHECK: aie.objectfifo @of_init({{.*}}) : !aie.objectfifo> = [dense<0> : memref<16xi32>, dense<1> : memref<16xi32>] +def test_objectfifo_init_values(): + """The IRON ObjectFifo `init_values` arg plumbs through to the underlying + `aie.objectfifo` op's `initValues` attribute (one dense attr per + producer-side buffer). The producer endpoint is pinned to AnyMemTile so + the initialized buffers live on a memtile (init_values is rejected by + the op verifier when the producer is a shim). + """ + + dev = NPU1Col1() + tile_ty = np.ndarray[(16,), np.dtype[np.int32]] + + of_init = ObjectFifo( + tile_ty, + depth=2, + name="of_init", + init_values=[ + np.zeros(16, dtype=np.int32), + np.ones(16, dtype=np.int32), + ], + ) + # Pin the producer endpoint to a MemTile (no Worker / no rt.fill). + of_init.prod().endpoint = ObjectFifoEndpoint(AnyMemTile) + + of_out = ObjectFifo(tile_ty, depth=2, name="of_out") + + def consumer_body(of_init_c, of_out_p): + for _ in range_(2): + elem_in = of_init_c.acquire(1) + elem_out = of_out_p.acquire(1) + for i in range_(16): + elem_out[i] = elem_in[i] + of_init_c.release(1) + of_out_p.release(1) + + cons = Worker(consumer_body, fn_args=[of_init.cons(), of_out.prod()]) + + rt = Runtime() + tensor_ty = np.ndarray[(32,), np.dtype[np.int32]] + with rt.sequence(tensor_ty) as a: + rt.start(cons) + rt.drain(of_out.cons(), a, wait=True) + + module = Program(dev, rt).resolve_program() + print(module) + + +if __name__ == "__main__": + test_objectfifo_init_values() From f446ca5814106448bf7a5aae03952a3a1c023d99 Mon Sep 17 00:00:00 2001 From: Erika Hunhoff Date: Mon, 18 May 2026 15:12:52 -0600 Subject: [PATCH 3/5] [AIE] objectfifo: skip source-side locks when iter_count cycles a static-init producer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When an aie.objectfifo has init_values on a MemTile producer with no upstream link and iter_count > 1, the DMA channel's task_count (= iter_count - 1) restarts the BD chain after each pass. The per-BD use_lock acquires/releases consume the source-side lock state during the first pass, and nothing replenishes it (there is no upstream S2MM filling the buffers) — the chain deadlocks on the second pass. For this configuration the locks are not needed for correctness: the static buffers are always available, and back-pressure to the downstream consumer is handled by the DMA stream's flow control. Detect the (MM2S + initValues + iter_count > 1 + no link) case in createBdBlock and omit the lock ops on the source side. Add a lit roundtrip test in bd_chain_on_memtile/ that checks the memtile_dma BD chain has no use_lock ops in this configuration. Verified end-to-end on NPU Strix: prior to this change, a design that cycles a static-init MemTile buffer N times (via iter_count) returns ert_cmd_state.ERT_CMD_STATE_TIMEOUT; with the fix the same design runs to completion and the host receives the cycled data. Co-Authored-By: Claude Opus 4 (1M context) --- .../AIEObjectFifoStatefulTransform.cpp | 13 +++++- ...nit_values_no_link_skips_source_locks.mlir | 45 +++++++++++++++++++ 2 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 test/objectFifo-stateful-transform/bd_chain_on_memtile/init_values_no_link_skips_source_locks.mlir diff --git a/lib/Dialect/AIE/Transforms/AIEObjectFifoStatefulTransform.cpp b/lib/Dialect/AIE/Transforms/AIEObjectFifoStatefulTransform.cpp index 82da661f197..b22a6ad0188 100644 --- a/lib/Dialect/AIE/Transforms/AIEObjectFifoStatefulTransform.cpp +++ b/lib/Dialect/AIE/Transforms/AIEObjectFifoStatefulTransform.cpp @@ -854,7 +854,18 @@ struct AIEObjectFifoStatefulTransformPass int acqMode = 1; int relMode = 1; auto acqLockAction = LockAction::Acquire; - if (state.locksPerFifo[op].size() > 0) { + // Static-init producer cycled via iter_count > 1 with no upstream link: + // skip source-side locks. The BD chain restarts via the channel's + // task_count, but the per-BD lock state never gets replenished (no + // upstream S2MM refills the buffers) so the chain would deadlock on + // the second pass. Back-pressure to the downstream consumer is handled + // by the DMA stream's flow control; source-side locking is unnecessary + // for correctness in this configuration. + bool isCycledStaticInitProducer = + channelDir == DMAChannelDir::MM2S && op.getInitValues().has_value() && + op.getIterCount().has_value() && op.getIterCount().value() > 1 && + !getOptionalLinkOp(op).has_value(); + if (state.locksPerFifo[op].size() > 0 && !isCycledStaticInitProducer) { auto dev = op->getParentOfType(); if (auto &target = dev.getTargetModel(); target.getTargetArch() == AIEArch::AIE1) { diff --git a/test/objectFifo-stateful-transform/bd_chain_on_memtile/init_values_no_link_skips_source_locks.mlir b/test/objectFifo-stateful-transform/bd_chain_on_memtile/init_values_no_link_skips_source_locks.mlir new file mode 100644 index 00000000000..e078e420b06 --- /dev/null +++ b/test/objectFifo-stateful-transform/bd_chain_on_memtile/init_values_no_link_skips_source_locks.mlir @@ -0,0 +1,45 @@ +//===- init_values_no_link_skips_source_locks.mlir -------------*- MLIR -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// An aie.objectfifo with init_values on a MemTile producer and no upstream +// link has no producer to refill the source-side locks between BD-chain +// iterations. The lowering must omit the source-side use_lock ops so the +// chain can be restarted by the channel's task_count (= iter_count - 1) +// without deadlocking on the second pass. The downstream consumer's locks +// are unaffected and the DMA stream provides flow control. + +// RUN: aie-opt --aie-objectFifo-stateful-transform %s | FileCheck %s + +// CHECK-LABEL: module @init_values_no_link_skips_source_locks { +// CHECK: aie.device(npu1_1col) { +// CHECK: %[[MEM_TILE:.*]] = aie.tile(0, 1) +// CHECK: %[[CT:.*]] = aie.tile(0, 2) +// CHECK: %{{.*}} = aie.memtile_dma(%[[MEM_TILE]]) { +// CHECK: %{{.*}} = aie.dma_start(MM2S, 0, ^bb1, ^bb{{[0-9]+}}, repeat_count = 3) +// CHECK-NEXT: ^bb1: +// CHECK-NOT: aie.use_lock +// CHECK: aie.dma_bd +// CHECK-NOT: aie.use_lock +// CHECK: aie.next_bd +// CHECK-NEXT: ^bb2: +// CHECK-NOT: aie.use_lock +// CHECK: aie.dma_bd +// CHECK-NOT: aie.use_lock +// CHECK: aie.next_bd +// CHECK-NEXT: ^bb3: +// CHECK: aie.end + +module @init_values_no_link_skips_source_locks { + aie.device(npu1_1col) { + %mem_tile = aie.tile(0, 1) + %ct = aie.tile(0, 2) + aie.objectfifo @of(%mem_tile, {%ct}, [2 : i32, 1 : i32]) {iter_count = 4 : i32} + : !aie.objectfifo> + = [dense<0> : memref<16xi32>, dense<1> : memref<16xi32>] + } +} From fc6772e6a6ca7e656b920fb0c19232416b70e0b3 Mon Sep 17 00:00:00 2001 From: Erika Hunhoff Date: Mon, 18 May 2026 17:12:25 -0600 Subject: [PATCH 4/5] [IRON] ObjectFifo: always emit ArrayAttr per-handle depths MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `_get_depths()` collapsed all-equal per-handle depths to a single int. The stateful-transform's lowering interprets a single-int elemNumber as "producer depth only" and auto-sizes each consumer-side ping-pong from max-acquire (via findObjectFifoSize), silently dropping below the user's declared depth. For multi-consumer fanout with uneven acquire patterns — one consumer needs to buffer ahead while peers wait on upstream data — this back-pressures the producer DMA and deadlocks at runtime. Fix: delete _get_depths and inline the per-handle list [prod_depth, *cons_depths] at the resolve() call site. Uniform handling for 1-cons and N-cons; lowering always goes through the ArrayAttr branch that honors each declared depth directly. Regression: test/python/objFifo_iron_multi_cons_depth.py — multi-cons fanout with all depths equal must emit [4 : i32, 4 : i32, 4 : i32], not a single 4 : i32. --- python/iron/dataflow/objectfifo.py | 32 +++---- test/python/objFifo_iron_multi_cons_depth.py | 89 ++++++++++++++++++++ 2 files changed, 106 insertions(+), 15 deletions(-) create mode 100644 test/python/objFifo_iron_multi_cons_depth.py diff --git a/python/iron/dataflow/objectfifo.py b/python/iron/dataflow/objectfifo.py index 132ece43c05..5031896bfc2 100644 --- a/python/iron/dataflow/objectfifo.py +++ b/python/iron/dataflow/objectfifo.py @@ -253,20 +253,6 @@ def _cons_tiles_ops(self) -> list[Tile]: ) return [cons.endpoint.tile.op for cons in self._cons] - def _get_depths(self) -> int | list[int]: - if not self._prod: - raise ValueError( - "Cannot return depths since prod ObjectFifoHandle is not created." - ) - if len(self._cons) == 0: - raise ValueError( - "Cannot return depths since no cons ObjectFifoHandles are created." - ) - depths = [self._prod.depth] + [con.depth for con in self._cons] - if len(set(depths)) == 1: - return depths[0] - return depths - def _get_endpoint(self, is_prod: bool) -> list[ObjectFifoEndpoint]: if is_prod: if self._prod: @@ -290,11 +276,27 @@ def resolve( for con in self._cons ] + if not self._prod: + raise ValueError( + f"ObjectFifo {self.name}: producer handle not created." + ) + if len(self._cons) == 0: + raise ValueError( + f"ObjectFifo {self.name}: no consumer handles created." + ) + # Always emit the per-handle ArrayAttr [prod_depth, *cons_depths]. + # Collapsing to a single int when all are equal triggers the + # stateful-transform's auto-minimize path, which sizes each + # consumer's ping-pong from max-acquire instead of honoring the + # declared depth — silently deadlocking multi-consumer fanout + # designs where one consumer must buffer ahead of the others. + depths = [self._prod.depth] + [con.depth for con in self._cons] + self._op = object_fifo( self.name, self._prod_tile_op(), self._cons_tiles_ops(), - self._get_depths(), + depths, np_ndarray_type_to_memref_type(self._obj_type), dimensionsToStream=self._dims_to_stream, dimensionsFromStreamPerConsumer=dims_from_stream_per_cons, diff --git a/test/python/objFifo_iron_multi_cons_depth.py b/test/python/objFifo_iron_multi_cons_depth.py new file mode 100644 index 00000000000..5042c89e272 --- /dev/null +++ b/test/python/objFifo_iron_multi_cons_depth.py @@ -0,0 +1,89 @@ +# 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 2026 AMD Inc. + +# RUN: %python %s | FileCheck %s + +import numpy as np + +from aie.iron import ObjectFifo, Program, Runtime, Worker +from aie.iron.controlflow import range_ +from aie.iron.device import NPU1Col1, Tile + +# Regression for: IRON ObjectFifo collapsed all-equal per-handle depths to a +# single int when emitting `aie.objectfifo`. The `aie-objectFifo-stateful- +# transform` lowering interprets a single-int `elemNumber` as "producer +# depth only" and auto-sizes each consumer-side buffer from max-acquire, +# silently dropping below the user's declared depth. For multi-consumer +# fanout with uneven acquire patterns (one consumer must buffer ahead of a +# peer that's waiting on upstream data), this deadlocks at runtime. +# +# Fix: always emit the per-handle ArrayAttr `[prod_depth, *cons_depths]` +# so the lowering uses each declared depth directly, even when all values +# match. Applies uniformly to every ObjectFifo (1-cons and N-cons). + + +# CHECK-DAG: aie.objectfifo @of_multi({{.*}}, [4 : i32, 4 : i32, 4 : i32]) : !aie.objectfifo> +# CHECK-DAG: aie.objectfifo @of_a_out({{.*}}, [2 : i32, 2 : i32]) : !aie.objectfifo> +# CHECK-DAG: aie.objectfifo @of_b_out({{.*}}, [2 : i32, 2 : i32]) : !aie.objectfifo> +def test_objectfifo_multi_consumer_depth_array(): + """Multi-consumer fanout must emit ArrayAttr depth so the lowering honors + each cons(depth=N), not auto-minimize per consumer from max-acquire. + 1-producer-1-consumer ObjectFifos (of_a_out, of_b_out) also emit + ArrayAttr — uniform handling, no silent collapse.""" + + dev = NPU1Col1() + tile_ty = np.ndarray[(16,), np.dtype[np.int32]] + + of_multi = ObjectFifo(tile_ty, depth=4, name="of_multi") + of_a_out = ObjectFifo(tile_ty, depth=2, name="of_a_out") + of_b_out = ObjectFifo(tile_ty, depth=2, name="of_b_out") + + def prod_body(p): + for _ in range_(4): + p.acquire(1) + p.release(1) + + def cons_a_body(c, p_out): + # max-acquire = 1; pre-fix lowering would shrink to ping-pong=2 + # even though declared depth was 4. + for _ in range_(4): + c.acquire(1) + p_out.acquire(1) + c.release(1) + p_out.release(1) + + def cons_b_body(c, p_out): + for _ in range_(4): + c.acquire(1) + p_out.acquire(1) + c.release(1) + p_out.release(1) + + w_prod = Worker(prod_body, fn_args=[of_multi.prod()], tile=Tile(0, 2)) + w_cons_a = Worker( + cons_a_body, + fn_args=[of_multi.cons(), of_a_out.prod()], + tile=Tile(0, 3), + ) + w_cons_b = Worker( + cons_b_body, + fn_args=[of_multi.cons(), of_b_out.prod()], + tile=Tile(0, 4), + ) + + rt = Runtime() + tensor_ty = np.ndarray[(16,), np.dtype[np.int32]] + with rt.sequence(tensor_ty, tensor_ty) as (out_a, out_b): + rt.start(w_prod, w_cons_a, w_cons_b) + rt.drain(of_a_out.cons(), out_a, wait=True) + rt.drain(of_b_out.cons(), out_b, wait=True) + + module = Program(dev, rt).resolve_program() + print(module) + + +if __name__ == "__main__": + test_objectfifo_multi_consumer_depth_array() From 460f890c423f62dcba49e9f32c3b0972a3a386fb Mon Sep 17 00:00:00 2001 From: Erika Hunhoff Date: Thu, 21 May 2026 14:52:48 -0600 Subject: [PATCH 5/5] vision/{edge,color}_detect: reduce inOF_L2L1 depth to actual L1 ping-pong With the depth-as-minimum contract from this branch, the stateful transform now honors the declared depth instead of silently auto-minimizing equal-depth ObjectFifos to max-acquire. The two vision designs were declaring forward(depth=7) / forward(depth=6) to mirror the upstream memtile depth set by inOF_L3L2.cons(N), but the L1 consumer only ever acquires 1 element at a time, so depth=2 (standard ping-pong) is the correct L1 buffering. The memtile-side allocation is unaffected because the .link makes those buffers shared with the upstream fifo. Without this change the new contract allocates 6-7 cons_buff_* on a single core tile on Strix and aiecc's basic-sequential allocator runs out of memory. --- programming_examples/vision/color_detect/color_detect.py | 2 +- programming_examples/vision/edge_detect/edge_detect.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/programming_examples/vision/color_detect/color_detect.py b/programming_examples/vision/color_detect/color_detect.py index 78e1eba0639..0a3d23cdbad 100644 --- a/programming_examples/vision/color_detect/color_detect.py +++ b/programming_examples/vision/color_detect/color_detect.py @@ -52,7 +52,7 @@ def color_detect(dev, width, height): # AIE-array data movement with object fifos # Input inOF_L3L2 = ObjectFifo(line_bytes_ty, name="inOF_L3L2") - inOF_L2L1 = inOF_L3L2.cons(6).forward(depth=6, name="inOF_L2L1") + inOF_L2L1 = inOF_L3L2.cons(6).forward(depth=2, name="inOF_L2L1") # Output outOF_L1L2 = ObjectFifo(line_bytes_ty, name="outOF_L1L2") diff --git a/programming_examples/vision/edge_detect/edge_detect.py b/programming_examples/vision/edge_detect/edge_detect.py index d4ba9e4d24a..faeebe88d4d 100644 --- a/programming_examples/vision/edge_detect/edge_detect.py +++ b/programming_examples/vision/edge_detect/edge_detect.py @@ -61,7 +61,7 @@ def edge_detect(dev, width, height): # AIE-array data movement with object fifos # Input inOF_L3L2 = ObjectFifo(line_bytes_ty, name="inOF_L3L2") - inOF_L2L1 = inOF_L3L2.cons(7).forward(depth=7, name="inOF_L2L1") + inOF_L2L1 = inOF_L3L2.cons(7).forward(depth=2, name="inOF_L2L1") # Output outOF_L1L2 = ObjectFifo(line_bytes_ty, name="outOF_L1L2")