Skip to content

fix: strip MLIR %alloc names from VHLS csim output and handle ap_int in nanobind wrapper#554

Open
sunwookim028 wants to merge 4 commits into
cornell-zhang:mainfrom
sunwookim028:fix/vhls-mlir-percent-alloc-csim
Open

fix: strip MLIR %alloc names from VHLS csim output and handle ap_int in nanobind wrapper#554
sunwookim028 wants to merge 4 commits into
cornell-zhang:mainfrom
sunwookim028:fix/vhls-mlir-percent-alloc-csim

Conversation

@sunwookim028
Copy link
Copy Markdown
Contributor

Problem

When running test_three_level_systolic_csim, the Vitis HLS C++ emitter generates kernel.cpp containing raw MLIR SSA names like %alloc[1] — invalid C++ identifiers. This causes g++ to fail with:

error: expected unqualified-id before '%' token
  int16_t %alloc[1];

A secondary issue: [parse_cpp_function()](cci:1://file:///home/sk3463/main/projects/allo/allo/backend/ip.py:30:0-112:17) in ip.py used \w+ to match C++ types, which stops at <, so ap_int<8> was misread (only 8 was captured as the type name), producing invalid generated nanobind wrapper code.

Fix

vitis.py: Add re.sub(r'%(\w)', r'\1', hls_code) at the start of [postprocess_hls_code()](cci:1://file:///home/sk3463/main/projects/allo/allo/backend/vitis.py:377:0-429:18). The MLIR % sigil always precedes a word character; the C++ modulo operator does not. Safe substitution.

ip.py: Broaden type-matching regex to handle ap_int<N>/ap_uint<N> types. Add [resolve_nb_type()](cci:1://file:///home/sk3463/main/projects/allo/allo/backend/ip.py:16:0-27:19) to map HLS types to int{N}_t for the nanobind interface, with reinterpret_cast back to the HLS type when calling the kernel.

Testing

tests/test_systolic_array.py::test_three_level_systolic_csim now passes. This test only runs when Vitis HLS is available, which is why it was not caught by upstream CI.

@chhzh123
Copy link
Copy Markdown
Member

chhzh123 commented Mar 5, 2026

Can you add test cases for this?

@chhzh123 chhzh123 requested a review from Copilot March 5, 2026 19:09
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@sunwookim028
Copy link
Copy Markdown
Contributor Author

Black formatting fixed. Added unit tests in tests/test_backend_utils.py covering %alloc stripping (including modulo-operator preservation) and ap_int<N>/ap_uint<N> → stdint type mapping. 9 tests, all passing.

sunwookim028 and others added 4 commits April 30, 2026 22:58
…n nanobind wrapper

The VHLS C++ emitter emits raw MLIR SSA value names (e.g. %alloc, %alloc1)
into the generated kernel.cpp. These are illegal C++ identifiers and cause
g++ to fail with 'expected unqualified-id before % token' when IPModule
compiles the csim nanobind wrapper.
Fix 1 (vitis.py): Add re.sub(r'%(\w)', r'\1', hls_code) at the start of
postprocess_hls_code() to strip the MLIR % sigil from all identifiers.
The C++ modulo operator is always followed by a non-word character so this
substitution is safe.
Fix 2 (ip.py): Update parse_cpp_function() to handle ap_int<N>/ap_uint<N>
type names (old regex stopped at '<'). Add resolve_nb_type() to map HLS
types to nanobind-compatible stdint types (int8_t, uint16_t, etc.) in the
generated nanobind wrapper, with reinterpret_cast back to the HLS type when
calling the kernel.
Fixes test_three_level_systolic_csim which was the only failing test.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add 3 new tests to test_backend_utils.py:
- test_postprocess_realistic_mlir_snippet: the exact MLIR-emitted C++ pattern
  (int16_t %alloc[4][4]) that originally broke g++, with a C++ modulo on the
  same code path to verify selective stripping
- test_parse_cpp_function_plain_types: regression guard ensuring the broadened
  _TYPE_TOKEN regex did not break plain-type parsing (int8_t, float, int)
- test_generate_nanobind_wrapper_uses_stdint_for_ap_int: integration test that
  constructs an IPModule from a tempfile and verifies the generated wrapper uses
  int8_t/uint16_t in the nb::ndarray<> signature while keeping ap_int<N> in
  the reinterpret_cast body

All 12 tests pass (up from 9).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@sunwookim028 sunwookim028 force-pushed the fix/vhls-mlir-percent-alloc-csim branch from 9479101 to fb475cb Compare May 1, 2026 02:58
@sunwookim028
Copy link
Copy Markdown
Contributor Author

Rebased onto current main (no longer behind). Test coverage in tests/test_backend_utils.py now at 12 cases covering %alloc stripping, modulo-operator preservation, and ap_int<N>/ap_uint<N> → stdint resolution. Ready for another look @chhzh123.

@sunwookim028
Copy link
Copy Markdown
Contributor Author

Hi @chhzh123! Just a gentle ping — it's been about 9 days since the last update. CI is green and all requested tests are in place (12 cases in tests/test_backend_utils.py covering %alloc stripping and ap_int<N>/ap_uint<N> resolution). Ready for review whenever you have a moment, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants