Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
195 changes: 195 additions & 0 deletions src/python/pybind11/pyxrt.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -1186,3 +1186,198 @@ class ext:
shared: _ext_access_mode
process: _ext_access_mode
hybrid: _ext_access_mode


class graph:
"""Represents an AIE graph execution object."""

class access_mode(IntEnum):
"""Graph access mode."""
exclusive: graph.access_mode
primary: graph.access_mode
shared: graph.access_mode

# Class-level enum value aliases
exclusive: access_mode
primary: access_mode
shared: access_mode

@overload
def __init__(self, ctx: hw_context, name: str) -> None:
"""Create a graph from a hardware context and graph name.

Args:
ctx: The hardware context.
name: Name of the graph.
"""
...

@overload
def __init__(self, ctx: hw_context, name: str, mode: access_mode) -> None:
"""Create a graph with an explicit access mode.

Args:
ctx: The hardware context.
name: Name of the graph.
mode: Access mode (exclusive, primary, or shared).
"""
...

def reset(self) -> None:
"""Reset the graph by disabling tiles and enabling tile reset."""
...

def get_timestamp(self) -> int:
"""Get the current graph timestamp in AIE cycles.

Returns:
Timestamp in AIE cycles.
"""
...

def gmio_bank_id(self, gmio_name: str) -> int:
"""Get the memory bank index for a named GMIO port.

Args:
gmio_name: GMIO port name.

Returns:
Memory bank group ID.
"""
...

def run(self, iterations: int = 0) -> None:
"""Start graph execution.

Args:
iterations: Number of iterations (0 = run forever).
"""
...

@overload
def wait(self, timeout_ms: SupportsInt) -> None:
"""Wait for graph completion or until timeout.

Args:
timeout_ms: Timeout in milliseconds.
"""
...

@overload
def wait(self, cycles: SupportsInt = 0) -> None:
"""Wait for the given AIE cycles then suspend the graph.

Args:
cycles: AIE cycles to wait (0 = block until done).
"""
...

def suspend(self) -> None:
"""Suspend a running graph."""
...

def resume(self) -> None:
"""Resume a suspended graph."""
...

def end(self, cycles: SupportsInt = 0) -> None:
"""Wait for the given AIE cycles then terminate the graph.

Args:
cycles: AIE cycles to wait (0 = block until done).
"""
...

def update(self, port_name: str, data: ReadableBuffer) -> None:
"""Update a runtime parameter port.

Args:
port_name: Hierarchical RTP port name.
data: Data to write (any buffer protocol object: bytes, bytearray, memoryview, numpy array, etc.).
"""
...

def read(self, port_name: str, size: SupportsInt) -> NDArrayInt8:
"""Read a runtime parameter port.

Args:
port_name: Hierarchical RTP port name.
size: Number of bytes to read.

Returns:
NumPy array containing the read data.
"""
...


class _aie_bo(bo):
"""AIE buffer object supporting GMIO synchronous transfers."""

@overload
def __init__(
self, device: device, size: SupportsInt, flags: bo.flags, group: SupportsInt
) -> None:
"""Create a buffer object with specified properties.

Args:
device: The device to allocate the buffer on.
size: Size of the buffer in bytes.
flags: Buffer creation flags.
group: Memory bank group ID.
"""
...

@overload
def __init__(
self, ctx: hw_context, size: SupportsInt, flags: bo.flags, group: SupportsInt
) -> None:
"""Create a buffer object with specified properties in a hardware context.

Args:
ctx: The hardware context to allocate the buffer in.
size: Size of the buffer in bytes.
flags: Buffer creation flags.
group: Memory bank group ID.
"""
...

@overload
def __init__(self, ctx: hw_context, size: SupportsInt, group: SupportsInt) -> None:
"""Create a buffer object with default flags in a hardware context.

Args:
ctx: The hardware context to allocate the buffer in.
size: Size of the buffer in bytes.
group: Memory bank group ID.
"""
...

@overload
def sync(
self, port: str, direction: xclBOSyncDirection, size: SupportsInt, offset: SupportsInt
) -> None:
"""Synchronize buffer data with a named GMIO port.

Args:
port: GMIO port name.
direction: Direction of synchronization.
size: Number of bytes to sync.
offset: Offset in the buffer.
"""
...

@overload
def sync(self, port: str, direction: xclBOSyncDirection) -> None:
"""Sync entire buffer content with a named GMIO port.

Args:
port: GMIO port name.
direction: Direction of synchronization.
"""
...


class aie:
"""AIE-specific XRT functionality."""

bo = _aie_bo
117 changes: 117 additions & 0 deletions src/python/pybind11/src/pyxrt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "xrt/xrt_device.h"
#include "xrt/xrt_kernel.h"
#include "xrt/xrt_bo.h"
#include "xrt/xrt_graph.h"
#include "xrt/experimental/xrt_module.h"
#include "xrt/experimental/xrt_message.h"
#include "xrt/experimental/xrt_system.h"
Expand Down Expand Up @@ -746,4 +747,120 @@ PYBIND11_MODULE(pyxrt, m) {
}), py::arg("timeout"),
"Wait for the specified timeout for the runlist to complete");

/*
*
* xrt::graph
*
*/

py::class_<xrt::graph> pygraph(m, "graph", "Represents an AIE graph execution object");

py::enum_<xrt::graph::access_mode>(pygraph, "access_mode", "Graph access mode")
.value("exclusive", xrt::graph::access_mode::exclusive)
.value("primary", xrt::graph::access_mode::primary)
.value("shared", xrt::graph::access_mode::shared)
.export_values();

pygraph
.def(py::init([](const xrt::hw_context& ctx, const std::string& name) {
py::gil_scoped_release release;
return new xrt::graph(ctx, name);
}),
py::arg("ctx"), py::arg("name"),
"Create a graph from a hardware context and graph name.")
.def(py::init([](const xrt::hw_context& ctx, const std::string& name,
xrt::graph::access_mode mode) {
py::gil_scoped_release release;
return new xrt::graph(ctx, name, mode);
}),
py::arg("ctx"), py::arg("name"), py::arg("mode"),
"Create a graph with an explicit access mode.")
.def("reset", [](xrt::graph& g) {
py::gil_scoped_release release;
g.reset();
}, "Reset the graph by disabling tiles and enabling tile reset.")
.def("get_timestamp", &xrt::graph::get_timestamp,
"Get the current graph timestamp in AIE cycles.")
.def("gmio_bank_id", &xrt::graph::gmio_bank_id, py::arg("gmio_name"),
"Get the memory bank index for a named GMIO port.")
.def("run", [](xrt::graph& g, uint32_t iterations) {
py::gil_scoped_release release;
g.run(iterations);
}, py::arg("iterations") = 0,
"Start graph execution.")
.def("wait", [](xrt::graph& g, std::chrono::milliseconds timeout_ms) {
py::gil_scoped_release release;
g.wait(timeout_ms);
}, py::arg("timeout_ms"),
"Wait for graph completion or until timeout.")
.def("wait", [](xrt::graph& g, uint64_t cycles) {
py::gil_scoped_release release;
g.wait(cycles);
}, py::arg("cycles") = 0,
"Wait for the given AIE cycles then suspend the graph.")
.def("suspend", [](xrt::graph& g) {
py::gil_scoped_release release;
g.suspend();
}, "Suspend a running graph.")
.def("resume", [](xrt::graph& g) {
py::gil_scoped_release release;
g.resume();
}, "Resume a suspended graph.")
.def("end", [](xrt::graph& g, uint64_t cycles) {
py::gil_scoped_release release;
g.end(cycles);
}, py::arg("cycles") = 0,
"Wait for the given AIE cycles then terminate the graph.")
.def("update", [](xrt::graph& g, const std::string& port_name, py::buffer data) {
py::buffer_info info = data.request();
g.update(port_name, info.ptr, static_cast<size_t>(info.itemsize * info.size));
}, py::arg("port_name"), py::arg("data"),
"Update a runtime parameter port.")
.def("read", [](xrt::graph& g, const std::string& port_name, size_t size) {
py::array_t<char> result(size);
py::buffer_info info = result.request();
g.read(port_name, info.ptr, size);
return result;
}, py::arg("port_name"), py::arg("size"),
"Read a runtime parameter port.");

/*
*
* xrt::aie::bo
*
*/

py::module_ aie = m.def_submodule("aie", "AIE-specific XRT functionality.");

py::class_<xrt::aie::bo, xrt::bo> pyaiebo(aie, "bo",
"AIE buffer object supporting GMIO synchronous transfers.");

pyaiebo
.def(py::init([](xrt::device& d, size_t sz, xrt::bo::flags flags, xrt::memory_group grp) {
return new xrt::aie::bo(d, sz, flags, grp);
}),
py::arg("device"), py::arg("size"), py::arg("flags"), py::arg("group"),
"Create a buffer object on a device with the requested size, flags, and memory group.")
.def(py::init([](xrt::hw_context& ctx, size_t sz, xrt::bo::flags flags, xrt::memory_group grp) {
return new xrt::aie::bo(ctx, sz, flags, grp);
}),
py::arg("ctx"), py::arg("size"), py::arg("flags"), py::arg("group"),
"Create a buffer object in a hardware context with the requested size, flags, and memory group.")
.def(py::init([](xrt::hw_context& ctx, size_t sz, xrt::memory_group grp) {
return new xrt::aie::bo(ctx, sz, grp);
}),
py::arg("ctx"), py::arg("size"), py::arg("group"),
"Create a buffer object in a hardware context using default flags.")
.def("sync", [](xrt::aie::bo& b, const std::string& port,
xclBOSyncDirection dir, size_t sz, size_t offset) {
py::gil_scoped_release release;
b.sync(port, dir, sz, offset);
}, py::arg("port"), py::arg("direction"), py::arg("size"), py::arg("offset"),
"Synchronize buffer data with a named GMIO port.")
.def("sync", [](xrt::aie::bo& b, const std::string& port, xclBOSyncDirection dir) {
py::gil_scoped_release release;
b.sync(port, dir);
}, py::arg("port"), py::arg("direction"),
"Sync entire buffer content with a named GMIO port.");

}
Loading
Loading