Skip to content

Commit

Permalink
Configure AIE using control packets (#1728)
Browse files Browse the repository at this point in the history
Co-authored-by: Jeff Fifield <jeff.fifield@amd.com>
  • Loading branch information
erwei-xilinx and fifield authored Aug 30, 2024
1 parent 0baa629 commit a863d44
Show file tree
Hide file tree
Showing 11 changed files with 1,254 additions and 45 deletions.
2 changes: 1 addition & 1 deletion lib/Dialect/AIEX/IR/AIEXDialect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -641,4 +641,4 @@ LogicalResult AIEX::DMAStartBdChainOp::verify() {
}
}
return success();
}
}
2 changes: 1 addition & 1 deletion lib/Targets/AIETargetNPU.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ xilinx::AIE::AIETranslateToControlPackets(ModuleOp module,
}
return (p % 2) == 0;
};
uint32_t addr = op.getAddress();
uint32_t addr = op.getAddress() & 0xFFFFF;
uint32_t beats = size - 1;
uint32_t opc = op.getOpcode();
uint32_t id = op.getStreamId();
Expand Down
140 changes: 100 additions & 40 deletions python/compiler/txn2mlir.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

import sys
import struct
import argparse
import aie.extras.types as T


def print_none(*args):
Expand Down Expand Up @@ -63,7 +65,7 @@ def parse_txn(data, verbose=False):
_, addr, size = struct.unpack("III", data[i + 4 : i + 16])
print_log(f"addr: {addr:#x}")
print_log(f"size: {size}")
operations.append((opc, addr, data[i + 16 : i + size - 16]))
operations.append((opc, addr, data[i + 16 : i + size]))
i = i + size
elif opc == 0x03:
print_log("opcode: MASKWRITE (0x03)")
Expand Down Expand Up @@ -113,7 +115,7 @@ def parse_txn(data, verbose=False):
return num_cols, operations


def operations_to_mlir(operations, columns=5):
def operations_to_mlir(operations, columns=5, mlir_ctrl_pkt=False):
with Context(), Location.unknown():
module = Module.create()
global_data = []
Expand All @@ -137,49 +139,107 @@ def device_body():
else:
global_data.append(None)

@runtime_sequence()
def sequence():
for op, payload in zip(operations, global_data):
if op[0] == 0x00:
addr = op[1]
value = op[2]
npu_write32(addr, value)
elif op[0] == 0x01:
addr = op[1]
d = memref.get_global(
payload.type_.value, payload.sym_name.value
)
npu_blockwrite(addr, d)
elif op[0] == 0x03:
addr = op[1]
value = op[2]
mask = op[3]
npu_maskwrite32(addr, value, mask)
else:
raise Exception(f"Unhandled op: {op:#x}")
if mlir_ctrl_pkt:
# Runtime sequence arg0 as handle for ctrl packet raw data in host ddr
MAX_CTRL_PKTS_HOST_SIZE = 2048

@runtime_sequence(T.memref(MAX_CTRL_PKTS_HOST_SIZE, T.i32()))
def sequence(arg0):
for op, payload in zip(operations, global_data):
if op[0] == 0x00:
addr = op[1]
value = op[2]
control_packet(
address=addr,
opcode=0,
stream_id=0,
data=np.array([value]).astype(np.int32),
)
elif op[0] == 0x01:
addr = op[1]
data = np.array(payload.initial_value, dtype=np.int32)
# Individual access cannot cross a 128-bit boundary.
num_split_4s = (data.size + 3) // 4
data_split_4 = data
if num_split_4s > 1:
data_split_4 = np.array_split(
data[: (num_split_4s - 1) * 4], num_split_4s
)
data_split_4 = data_split_4.append(
data[(num_split_4s - 1) * 4 :]
)
if num_split_4s == 2:
# Individual access cannot cross a 128-bit boundary.
data_split_4 = [data[:4], data[4:]]
for d_split in data_split_4:
control_packet(
address=addr,
opcode=0,
stream_id=0,
data=d_split,
)
addr = addr + d_split.size * 4
elif op[0] == 0x03:
addr = op[1]
value = op[2]
# mask (op[3]) is ignored, as control packet cannot do masked write
control_packet(
address=addr,
opcode=0,
stream_id=0,
data=np.array([value], dtype=np.int32),
)
else:
raise Exception(f"Unhandled op: {op:#x}")

else:

@runtime_sequence()
def sequence():
for op, payload in zip(operations, global_data):
if op[0] == 0x00:
addr = op[1]
value = op[2]
npu_write32(addr, value)
elif op[0] == 0x01:
addr = op[1]
d = memref.get_global(
payload.type_.value, payload.sym_name.value
)
npu_blockwrite(addr, d)
elif op[0] == 0x03:
addr = op[1]
value = op[2]
mask = op[3]
npu_maskwrite32(addr, value, mask)
else:
raise Exception(f"Unhandled op: {op:#x}")

return module


if __name__ == "__main__":
# Check if command line arguments are provided
if len(sys.argv) == 1:
# Read data from standard input
data = sys.stdin.buffer.read()
# Parse arguments
parser = argparse.ArgumentParser()
parser.add_argument("-file", "-f", type=argparse.FileType("rb"), nargs="*")
parser.add_argument(
"-generate-ctrl-pkt",
dest="mlir_ctrl_pkt",
default=False,
action="store_true",
help="Enable MLIR control packet op generation",
)
args = parser.parse_args()

# Process each file provided as command line argument
operations = []
for f in args.file:
# Read the data from the file
data = f.read()
# Parse the TXN data
columns, operations = parse_txn(data)
else:
# Process each file provided as command line argument
operations = []
for filename in sys.argv[1:]:
# Open the file in binary mode
with open(filename, "rb") as f:
# Read the data from the file
data = f.read()
# Parse the TXN data
columns, ops = parse_txn(data)
operations = operations + ops

module = operations_to_mlir(operations, columns)
columns, ops = parse_txn(data)
operations = operations + ops

module = operations_to_mlir(operations, columns, mlir_ctrl_pkt=args.mlir_ctrl_pkt)

print(str(module))
2 changes: 1 addition & 1 deletion test/npu-xrt/add_one_two_txn/run.lit
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
// RUN: clang %S/test.cpp -o test.exe -std=c++11 -Wall %xrt_flags -lrt -lstdc++ -lboost_program_options -lboost_filesystem
// RUN: %python aiecc.py --xclbin-kernel-name=ADDONE --xclbin-kernel-id=0x901 --xclbin-instance-name=ADDONEINST --no-aiesim --aie-generate-cdo --aie-generate-npu --no-compile-host --xclbin-name=add_one.xclbin --npu-insts-name=add_one_insts.txt %S/aie1.mlir
// RUN: %python aiecc.py --no-aiesim --aie-generate-txn --aie-generate-npu --no-compile-host --npu-insts-name=add_two_insts.txt %S/aie2.mlir
// RUN: %python txn2mlir.py aie2.mlir.prj/txn.bin > add_two_cfg.mlir
// RUN: %python txn2mlir.py -f aie2.mlir.prj/txn.bin > add_two_cfg.mlir
// RUN: aie-translate -aie-npu-instgen -aie-output-binary=true add_two_cfg.mlir -o add_two_cfg.bin
// RUN: %run_on_npu ./test.exe -x add_one.xclbin -i add_one_insts.txt -c add_two_cfg.bin -j add_two_insts.txt | FileCheck %s
// CHECK: PASS!
Loading

0 comments on commit a863d44

Please sign in to comment.