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
641 changes: 641 additions & 0 deletions docs/python-callable-serialization.md

Large diffs are not rendered by default.

13 changes: 10 additions & 3 deletions docs/python-packaging.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,19 @@ Internal coupling: `simpler_setup.toolchain`, `simpler_setup.kernel_compiler`, a

| Category | Packages |
| -------- | -------- |
| `simpler` runtime | No third-party Python deps. Requires platform backend: simulation (`a*sim`) or NPU hardware (`a2a3`/`a5` with CANN toolkit) |
| `simpler_setup` runtime | `torch` (tensor operations in golden scripts, test comparison) |
| `simpler` runtime | `cloudpickle`; platform backend |
| `simpler_setup` runtime | `torch` for golden/test tensor operations |
| Build | `scikit-build-core`, `nanobind`, `cmake` |
| Test | `pytest` (ut-py, st), `googletest` + `ctest` (ut-cpp) |

`pyproject.toml` declares no `[project.dependencies]` — both `torch` and `pytest` are environment prerequisites, not pip-installed transitively. This is intentional: torch's index URL (`--index-url https://download.pytorch.org/whl/cpu`) and hardware-specific builds make automatic resolution impractical.
`pyproject.toml` declares `cloudpickle` as a `[project.dependencies]` runtime
dependency. `torch` and `pytest` remain environment prerequisites, not
pip-installed transitively. This is intentional: torch's index URL
(`--index-url https://download.pytorch.org/whl/cpu`) and hardware-specific
builds make automatic resolution impractical.

The `simpler` runtime also requires a platform backend: simulation (`a*sim`) or
NPU hardware (`a2a3`/`a5` with CANN toolkit).

### `PROJECT_ROOT` resolution

Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ build-backend = "scikit_build_core.build"
name = "simpler"
version = "0.1.0"
requires-python = ">=3.9"
dependencies = ["cloudpickle>=2.2"]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The project targets Python 3.9 and uses PEP 585 generic collections (e.g., dict[int, Any]) in worker.py. Per the general rules, please ensure that from __future__ import annotations is present at the top of all Python files using these type hints to prevent runtime errors when annotations are evaluated at module load time.

References
  1. In Python projects targeting versions earlier than 3.10 (such as Python 3.9), include 'from future import annotations' at the top of files using PEP 604 union type hints (e.g., 'int | None') or PEP 585 generic collections to prevent runtime errors when annotations are evaluated at module load time.


[project.optional-dependencies]
# ``torch>=2.3`` is required by ``simpler_setup.torch_interop`` (uses
Expand Down
33 changes: 33 additions & 0 deletions python/bindings/worker_bind.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ inline void bind_worker(nb::module_ &m) {
// --- WorkerType ---
nb::enum_<WorkerType>(m, "WorkerType").value("NEXT_LEVEL", WorkerType::NEXT_LEVEL).value("SUB", WorkerType::SUB);

nb::class_<ControlResult>(m, "ControlResult")
.def_ro("worker_type", &ControlResult::worker_type)
.def_ro("worker_index", &ControlResult::worker_index)
.def_ro("ok", &ControlResult::ok)
.def_ro("error_message", &ControlResult::error_message);

// --- TaskState ---
nb::enum_<TaskState>(m, "TaskState")
.value("FREE", TaskState::FREE)
Expand Down Expand Up @@ -246,6 +252,33 @@ inline void bind_worker(nb::module_ &m) {
"Best-effort broadcast of CTRL_UNREGISTER to every NEXT_LEVEL child in parallel. "
"Returns a list of per-child error strings (empty on full success)."
)
.def(
"broadcast_control_all",
[](Worker &self, WorkerType worker_type, uint64_t sub_cmd, int32_t cid, nb::object payload,
nb::object timeout_s) {
std::string payload_bytes;
const void *payload_ptr = nullptr;
size_t payload_size = 0;
if (!payload.is_none()) {
Py_buffer view;
if (PyObject_GetBuffer(payload.ptr(), &view, PyBUF_CONTIG_RO) != 0) {
throw nb::python_error();
}
payload_bytes.assign(static_cast<const char *>(view.buf), static_cast<size_t>(view.len));
PyBuffer_Release(&view);
payload_ptr = payload_bytes.data();
payload_size = payload_bytes.size();
}
double timeout_val = timeout_s.is_none() ? -1.0 : nb::cast<double>(timeout_s);
nb::gil_scoped_release release;
return self.broadcast_control_all(worker_type, sub_cmd, cid, payload_ptr, payload_size, timeout_val);
},
nb::arg("worker_type"), nb::arg("sub_cmd"), nb::arg("cid"), nb::arg("payload") = nb::none(),
nb::arg("timeout_s") = nb::none(),
"Broadcast an arbitrary CONTROL_REQUEST to the selected worker pool. "
"If payload is a Python buffer, C++ stages it in POSIX shm and writes the shm name "
"into the mailbox. Returns per-child ControlResult entries."
)
.def(
"control_alloc_domain", &Worker::control_alloc_domain, nb::arg("worker_id"), nb::arg("request_shm_name"),
nb::arg("reply_shm_name"), nb::call_guard<nb::gil_scoped_release>(),
Expand Down
Loading
Loading