Skip to content

Commit

Permalink
Attribute to specify repeat count in ObjFIFO (Xilinx#1530)
Browse files Browse the repository at this point in the history
Co-authored-by: AndraBisca <andrab@amd.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
  • Loading branch information
3 people authored Aug 22, 2024
1 parent 3f05898 commit 0dd1dd6
Show file tree
Hide file tree
Showing 18 changed files with 1,145 additions and 33 deletions.
16 changes: 6 additions & 10 deletions include/aie/Dialect/AIE/IR/AIEOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -1668,7 +1668,9 @@ def AIE_ObjectFifoCreateOp: AIE_Op<"objectfifo", [HasParent<"DeviceOp">, Symbol]
DefaultValuedAttr<BoolAttr, "false">:$plio,
// via_shared_mem==0 means use producer tile's memory module
// via_shared_mem==1 means use consumer tile's memory module
OptionalAttr<AIEI32Attr>:$via_shared_mem
OptionalAttr<AIEI32Attr>:$via_shared_mem,
// memtile_repeat==0 means "do it once" and don't repeat
OptionalAttr<AIEI32Attr>:$memtile_repeat
);

let assemblyFormat = [{
Expand Down Expand Up @@ -1763,16 +1765,10 @@ def AIE_ObjectFifoLinkOp: AIE_Op<"objectfifo.link", [HasParent<"DeviceOp">]> {
let extraClassDeclaration = [{
std::vector<ObjectFifoCreateOp> getInputObjectFifos();
std::vector<ObjectFifoCreateOp> getOutputObjectFifos();

bool isJoin() {
return getFifoIns().size() > 1;
}

bool isDistribute() {
return getFifoOuts().size() > 1;
}

bool isJoin() { return getFifoIns().size() > 1; }
bool isDistribute() { return getFifoOuts().size() > 1; }
std::optional<mlir::Value> getOptionalSharedTile();
std::optional<int> getRepeatCount();
std::vector<int> getJoinTranferLengths();
std::vector<int> getDistributeTranferLengths();
}];
Expand Down
33 changes: 33 additions & 0 deletions lib/Dialect/AIE/IR/AIEDialect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,12 @@ LogicalResult ObjectFifoCreateOp::verify() {
"`via_shared_mem` can only be used in 1-to-1 object FIFOs");
}

if (getMemtileRepeat().has_value()) {
if (!getProducerTileOp().isMemTile())
return emitError("`memtile_repeat` can only be used with a mem tile "
"producer");
}

return success();
}

Expand Down Expand Up @@ -625,6 +631,26 @@ LogicalResult ObjectFifoLinkOp::verify() {
return emitOpError("currently does not support objectFifos with "
"dimensionsFromStreamPerConsumer.");
}

for (auto fifoOut : getOutputObjectFifos()) {
for (auto dims : fifoOut.getDimensionsFromStreamPerConsumer()) {
if (!dims.empty())
return emitOpError("currently does not support objectFifos with "
"dimensionsFromStreamPerConsumer.");
}
}

std::vector<int> repeat_counts;
for (auto fifoOut : getOutputObjectFifos()) {
if (fifoOut.getMemtileRepeat().has_value())
repeat_counts.push_back(fifoOut.getMemtileRepeat().value());
else
repeat_counts.push_back(0);
}
for (auto repeat : repeat_counts)
if (repeat_counts[0] != repeat)
return emitError("repeat counts of output object FIFOs must be equal");

} else {
if (!getSrcOffsets().empty() && !getDstOffsets().empty())
return emitOpError("all offsets should be empty if there is no "
Expand Down Expand Up @@ -732,6 +758,13 @@ std::vector<int> ObjectFifoLinkOp::getDistributeTranferLengths() {
return lengths;
}

std::optional<int> ObjectFifoLinkOp::getRepeatCount() {
for (auto fifoOut : getOutputObjectFifos())
if (fifoOut.getMemtileRepeat().has_value())
return {fifoOut.getMemtileRepeat().value()};
return {};
}

//===----------------------------------------------------------------------===//
// ObjectFifoRegisterExternalBuffersOp
//===----------------------------------------------------------------------===//
Expand Down
48 changes: 29 additions & 19 deletions lib/Dialect/AIE/Transforms/AIEObjectFifoStatefulTransform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,8 @@ struct AIEObjectFifoStatefulTransformPass
of_elem_index++;
}
if (linked) {
if (linkOp->getRepeatCount().has_value())
numElem *= linkOp->getRepeatCount().value() + 1;
if (linkOp->isDistribute())
numElem *= linkOp->getFifoOuts().size();
else if (linkOp->isJoin())
Expand Down Expand Up @@ -692,6 +694,19 @@ struct AIEObjectFifoStatefulTransformPass
int acqNum = 1;
int relNum = 1;

// check for repeat count
int repeatCount = 0;
if (!dims.getValue().empty()) {
auto highestStride = dims.getValue().begin()->getStride() - 1;
if (highestStride == 0) {
repeatCount = dims.getValue().begin()->getSize();
dims = AIE::BDDimLayoutArrayAttr::get(op->getContext(),
dims.getValue().drop_front(1));
}
}
if (op.getMemtileRepeat().has_value())
repeatCount = op.getMemtileRepeat().value();

// search for the buffers/locks (based on if this objFifo has a link)
// identify size difference between input and output memrefs
ObjectFifoCreateOp target = op;
Expand All @@ -704,12 +719,20 @@ struct AIEObjectFifoStatefulTransformPass
auto srcOffsets = linkOp->getSrcOffsets();
auto dstOffsets = linkOp->getDstOffsets();

if (target == op) {
if (linkOp->getRepeatCount().has_value()) {
// +1 for original data movement
acqNum *= linkOp->getRepeatCount().value() + 1;
relNum *= linkOp->getRepeatCount().value() + 1;
}
}

if (linkOp->isJoin()) {
// compute offset and length
isJoin = true;
if (target == op) {
acqNum = linkOp->getFifoIns().size();
relNum = linkOp->getFifoIns().size();
acqNum *= linkOp->getFifoIns().size();
relNum *= linkOp->getFifoIns().size();
} else {
int i = 0;
for (auto fifoIn : linkOp->getInputObjectFifos()) {
Expand All @@ -718,15 +741,14 @@ struct AIEObjectFifoStatefulTransformPass
i++;
}
extraOffset = *getConstantIntValue(srcOffsets[i]);
if (dims.getValue().empty())
lenOut = linkOp->getJoinTranferLengths()[i];
lenOut = linkOp->getJoinTranferLengths()[i];
}
} else if (linkOp->isDistribute()) {
// compute offset and length
isDistribute = true;
if (target == op) {
acqNum = linkOp->getFifoOuts().size();
relNum = linkOp->getFifoOuts().size();
acqNum *= linkOp->getFifoOuts().size();
relNum *= linkOp->getFifoOuts().size();
} else {
int i = 0;
for (auto fifoOut : linkOp->getOutputObjectFifos()) {
Expand All @@ -735,8 +757,7 @@ struct AIEObjectFifoStatefulTransformPass
i++;
}
extraOffset = *getConstantIntValue(dstOffsets[i]);
if (dims.getValue().empty())
lenOut = linkOp->getDistributeTranferLengths()[i];
lenOut = linkOp->getDistributeTranferLengths()[i];
}
} else {
if (target != op) {
Expand Down Expand Up @@ -787,17 +808,6 @@ struct AIEObjectFifoStatefulTransformPass
Block *dmaBlock = builder.createBlock(endBlock);
Block *bdBlock = builder.createBlock(endBlock);

// check for repeat count in objfifo dims
int repeatCount = 0;
if (!dims.getValue().empty()) {
auto highestStride = dims.getValue().begin()->getStride();
if (highestStride == 0) {
repeatCount = dims.getValue().begin()->getSize();
dims = AIE::BDDimLayoutArrayAttr::get(op->getContext(),
dims.getValue().drop_front(1));
}
}

// create DMA channel
builder.setInsertionPointToStart(dmaBlock);
builder.create<DMAStartOp>(builder.getUnknownLoc(), channelDir,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# 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 Advanced Micro Devices, Inc.

# parameters
# -DBOOST_ROOT: Path to Boost install
# -DXRT_INC_DIR: Full path to src/runtime_src/core/include in XRT cloned repo
# -DXRT_LIB_DIR: Path to xrt_coreutil.lib
# -DTARGET_NAME: Target name to be built

# cmake needs this line
cmake_minimum_required(VERSION 3.1)

set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED YES)

find_program(WSL NAMES powershell.exe)

if (NOT WSL)
set(CMAKE_C_COMPILER gcc-13)
set(CMAKE_CXX_COMPILER g++-13)
set(BOOST_ROOT /usr/include/boost CACHE STRING "Path to Boost install")
set(XRT_INC_DIR /opt/xilinx/xrt/include CACHE STRING "Path to XRT cloned repo")
set(XRT_LIB_DIR /opt/xilinx/xrt/lib CACHE STRING "Path to xrt_coreutil.lib")
else()
set(BOOST_ROOT C:/Technical/thirdParty/boost_1_83_0 CACHE STRING "Path to Boost install")
set(XRT_INC_DIR C:/Technical/XRT/src/runtime_src/core/include CACHE STRING "Path to XRT cloned repo")
set(XRT_LIB_DIR C:/Technical/xrtNPUfromDLL CACHE STRING "Path to xrt_coreutil.lib")
endif()

set(TARGET_NAME test CACHE STRING "Target to be built")

SET (ProjectName proj_${TARGET_NAME})
SET (currentTarget ${TARGET_NAME})

if ( WSL )
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR})
endif ()

project(${ProjectName})

# Find packages
find_package(Boost REQUIRED)

add_executable(${currentTarget}
${CMAKE_CURRENT_SOURCE_DIR}/../../../../runtime_lib/test_lib/test_utils.cpp
test.cpp
)

target_compile_definitions(${currentTarget} PUBLIC DISABLE_ABI_CHECK=1)

target_include_directories (${currentTarget} PUBLIC
${XRT_INC_DIR}
${Boost_INCLUDE_DIRS}
${CMAKE_CURRENT_SOURCE_DIR}/../../../../runtime_lib/test_lib
)

target_link_directories(${currentTarget} PUBLIC
${XRT_LIB_DIR}
${Boost_LIBRARY_DIRS}
)

if (NOT WSL)
target_link_libraries(${currentTarget} PUBLIC
xrt_coreutil
boost_program_options
boost_filesystem
)
else()
target_link_libraries(${currentTarget} PUBLIC
xrt_coreutil
)
endif()
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
##===- Makefile -----------------------------------------------------------===##
#
# This file 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
#
##===----------------------------------------------------------------------===##

srcdir := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))

include ${srcdir}/../../../makefile-common

all: build/final.xclbin build/insts.txt

devicename ?= npu
targetname = distribute_repeat
LENGTH ?= 36

build/aie.mlir: ${srcdir}/aie2.py
mkdir -p ${@D}
python3 $< ${LENGTH} ${devicename} ${col} > $@

.PHONY: inst/insts.txt
inst/insts.txt: ${srcdir}/aie2.py
rm -rf inst
mkdir -p inst
python3 $< ${LENGTH} > inst/aie.mlir
pushd inst && aiecc.py --aie-only-generate-npu --npu-insts-name=insts.txt aie.mlir && popd
${powershell} ./build/${targetname}.exe -x build/final.xclbin -i inst/insts.txt -k MLIR_AIE -l ${LENGTH}

build/final.xclbin: build/aie.mlir
mkdir -p ${@D}
cd ${@D} && aiecc.py --aie-generate-cdo --no-compile-host --xclbin-name=${@F} \
--aie-generate-npu --npu-insts-name=insts.txt $(<:%=../%)

${targetname}.exe: ${srcdir}/test.cpp
rm -rf _build
mkdir -p _build
cd _build && ${powershell} cmake ${srcdir} -DTARGET_NAME=${targetname}
cd _build && ${powershell} cmake --build . --config Release
ifeq "${powershell}" "powershell.exe"
cp _build/${targetname}.exe $@
else
cp _build/${targetname} $@
endif

run: ${targetname}.exe build/final.xclbin build/insts.txt
${powershell} ./$< -x build/final.xclbin -i build/insts.txt -k MLIR_AIE -l ${LENGTH}

# Changing variables when we target VCK5000
vck5000: devicename=xcvc1902
vck5000: col=6

vck5000: build/aie.mlir
aiecc.py --link_against_hsa --host-target=x86_64-amd-linux-gnu build/aie.mlir \
-I/opt/xaiengine/include \
-I${srcdir}/../../../../install/runtime_lib/x86_64-hsa/test_lib/include \
-L/opt/xaiengine/lib \
-L/lib/x86_64-linux-gnu/ \
${srcdir}/test_vck5000.cpp \
${srcdir}/../../../../install/runtime_lib/x86_64-hsa/test_lib/src/test_library.cpp \
-Wl,-R/opt/xaiengine/lib \
-Wl,--whole-archive -Wl,--no-whole-archive -lstdc++ -ldl -lelf -o test.elf

run_vck5000:
test.elf

clean:
rm -rf build _build inst ${targetname}.exe
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<!---//===- README.md --------------------------*- Markdown -*-===//
//
// 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
//
// Copyright (C) 2024, Advanced Micro Devices, Inc.
//
//===----------------------------------------------------------------------===//-->

# <ins>Distribute Repeat</ins>

This reference design can be run on a Ryzen™ AI NPU.

TODO

To compile and run the design for NPU:
```
make
make run
```
Loading

0 comments on commit 0dd1dd6

Please sign in to comment.