Skip to content

Commit 4ddf987

Browse files
authored
Add python host code for elf test (#2408)
1 parent cc98140 commit 4ddf987

2 files changed

Lines changed: 141 additions & 0 deletions

File tree

test/npu-xrt/add_one_objFifo_elf/run.lit

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,5 @@
1010
// RUN: clang %S/test.cpp -o test.exe -std=c++17 -Wall %xrt_flags -lrt -lstdc++ %test_utils_flags
1111
// RUN: %run_on_npu1% ./test.exe -x aie.xclbin -k MLIR_AIE -i insts.elf
1212
// RUN: %run_on_npu2% ./test.exe -x aie.xclbin -k MLIR_AIE -i insts.elf
13+
// RUN: %run_on_npu1% %python %S/test.py -x aie.xclbin -k MLIR_AIE -i insts.elf
14+
// RUN: %run_on_npu2% %python %S/test.py -x aie.xclbin -k MLIR_AIE -i insts.elf
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
# ===- test.py -------------------------------------------------*- Python -*-===#
2+
#
3+
# This file is licensed under the Apache License v2.0 with LLVM Exceptions.
4+
# See https://llvm.org/LICENSE.txt for license information.
5+
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
#
7+
# Copyright (C) 2025, Advanced Micro Devices, Inc.
8+
#
9+
# ===----------------------------------------------------------------------===#
10+
11+
# This gets launched from run.lit, so disable it with a bogus requires line
12+
# REQUIRES: dont_run
13+
# RUN: echo FAIL | FileCheck %s
14+
# CHECK: PASS
15+
16+
import argparse
17+
import pyxrt as xrt
18+
import numpy as np
19+
import os
20+
import struct
21+
22+
IN_SIZE = 64
23+
OUT_SIZE = 64
24+
25+
26+
def check_file_exists(filepath):
27+
if not os.path.isfile(filepath):
28+
raise FileNotFoundError(f"File not found: {filepath}")
29+
30+
31+
def main():
32+
# Argument parsing
33+
parser = argparse.ArgumentParser(description="PyXRT Test Script")
34+
parser.add_argument("-x", "--xclbin", required=True, help="The input xclbin path")
35+
parser.add_argument(
36+
"-k",
37+
"--kernel",
38+
required=True,
39+
help="The kernel name in the XCLBIN (e.g., PP_PRE_FD)",
40+
)
41+
parser.add_argument(
42+
"-v", "--verbosity", type=int, default=0, help="The verbosity of the output"
43+
)
44+
parser.add_argument(
45+
"-i",
46+
"--instr",
47+
required=True,
48+
help="Path of file containing userspace instructions to be sent to the LX6",
49+
)
50+
args = parser.parse_args()
51+
52+
# Check if files exist
53+
check_file_exists(args.xclbin)
54+
check_file_exists(args.instr)
55+
56+
device = xrt.device(0)
57+
58+
# Load the xclbin
59+
if args.verbosity >= 1:
60+
print(f"Loading xclbin: {args.xclbin}")
61+
xclbin = xrt.xclbin(args.xclbin)
62+
63+
if args.verbosity >= 1:
64+
print(f"Kernel opcode: {args.kernel}")
65+
66+
# Get the kernel from the xclbin
67+
xkernels = xclbin.get_kernels()
68+
xkernel = [k for k in xkernels if args.kernel in k.get_name()][0]
69+
kernel_name = xkernel.get_name()
70+
71+
if args.verbosity >= 1:
72+
print(f"Registering xclbin: {args.xclbin}")
73+
device.register_xclbin(xclbin)
74+
75+
elf = xrt.elf(args.instr)
76+
mod = xrt.module(elf)
77+
78+
# Get a hardware context
79+
if args.verbosity >= 1:
80+
print("Getting hardware context.")
81+
context = xrt.hw_context(device, xclbin.get_uuid())
82+
83+
# Get a kernel handle
84+
if args.verbosity >= 1:
85+
print(f"Getting handle to kernel: {kernel_name}")
86+
kernel = xrt.ext.kernel(context, mod, kernel_name)
87+
88+
# Create buffer objects
89+
bo_inA = xrt.ext.bo(device, IN_SIZE * 4)
90+
bo_inB = xrt.ext.bo(device, IN_SIZE * 4)
91+
bo_out = xrt.ext.bo(device, OUT_SIZE * 4)
92+
93+
if args.verbosity >= 1:
94+
print("Writing data into buffer objects.")
95+
96+
# Fill input buffer A
97+
buf_inA = np.arange(1, IN_SIZE + 1, dtype=np.uint32)
98+
bo_inA.write(buf_inA, 0)
99+
bo_inA.sync(xrt.xclBOSyncDirection.XCL_BO_SYNC_BO_TO_DEVICE)
100+
101+
if args.verbosity >= 1:
102+
print("Running Kernel.")
103+
104+
# Run the kernel
105+
opcode = 3
106+
run = kernel(opcode, 0, 0, bo_inA, bo_inB, bo_out)
107+
r = run.wait()
108+
109+
if r != xrt.ert_cmd_state.ERT_CMD_STATE_COMPLETED:
110+
print(f"Kernel did not complete. Returned status: {r}")
111+
return 1
112+
113+
bo_out.sync(xrt.xclBOSyncDirection.XCL_BO_SYNC_BO_FROM_DEVICE)
114+
115+
# Read output buffer
116+
buf_out = np.ones(OUT_SIZE, dtype=np.uint32)
117+
buf_out = bo_out.read(buf_out.size * buf_out.itemsize, 0).view(dtype=buf_out.dtype)
118+
119+
# Verify output
120+
errors = 0
121+
for i in range(OUT_SIZE):
122+
ref = i + 42
123+
if buf_out[i] != ref:
124+
print(f"Error in output {buf_out[i]} != {ref}")
125+
errors += 1
126+
else:
127+
# print(f"Correct output {buf_out[i]} == {ref}")
128+
pass
129+
130+
if errors == 0:
131+
print("\nPASS!\n")
132+
return 0
133+
else:
134+
print("\nfailed.\n")
135+
return 1
136+
137+
138+
if __name__ == "__main__":
139+
main()

0 commit comments

Comments
 (0)