Skip to content

Add support for assigning values to boolean vectors in Python - #1299

Merged
shi-eric merged 1 commit into
NVIDIA:mainfrom
thomasbbrunner:tbrunner/bool-vec-assign
Mar 18, 2026
Merged

shi-eric merged 1 commit into
NVIDIA:mainfrom
thomasbbrunner:tbrunner/bool-vec-assign

Conversation

@thomasbbrunner

@thomasbbrunner thomasbbrunner commented Mar 17, 2026 •

Copy link
Copy Markdown
Contributor

Description

Currently, attempting to write to a field of a boolean vector within a kernel will lead to the error:

warp._src.codegen.WarpCodegenError: Error while parsing function "assign_bool_vector"

This PR adds support for assigning values to boolean vectors.

Checklist

  • I am familiar with the Contributing Guidelines.
  • New or existing tests cover these changes.
  • The documentation is up to date with these changes.

Test plan

I've added a test to the repo. The test is passing with the changes.

Bug fix

To reproduce this in the current main:

import warp as wp

@wp.kernel
def assign_int_vector():
    v = wp.vector(length=2, dtype=wp.int32)
    v[0] = 1

@wp.kernel
def assign_bool_vector():
    v = wp.vector(length=2, dtype=wp.bool)
    v[0] = True

wp.launch(assign_int_vector, dim=1)
wp.synchronize()

# Raises:
# warp._src.codegen.WarpCodegenError: Error while parsing function "assign_bool_vector"
wp.launch(assign_bool_vector, dim=1)
wp.synchronize()

The compilation of the kernel with the int vector (assign_int_vector) works, but the one with the boolean vector (assign_bool_vector) fails.

Summary by CodeRabbit

  • New Features

    • Support for boolean vector element assignment and mutation, including negative indexing.
  • Tests

    • New test verifying boolean vector assignment and negative-index behavior across device launches.
  • Chores

    • Changelog updated to note the fix for boolean vector element assignment.

@copy-pr-bot

copy-pr-bot Bot commented Mar 17, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@coderabbitai

coderabbitai Bot commented Mar 17, 2026 •

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

â„đïļ Recent review info
⚙ïļ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 5be2b185-37f6-4f14-9cac-8978b55bd2a9

ðŸ“Ĩ Commits

Reviewing files that changed from the base of the PR and between 55bf8f9 and ef09577.

📒 Files selected for processing (2)
  • CHANGELOG.md
  • warp/_src/builtins.py
✅ Files skipped from review due to trivial changes (1)
  • CHANGELOG.md

📝 Walkthrough

Walkthrough

Added two hidden boolean-vector overloads (assign_inplace, assign_copy) in the builtins module to enable element assignment for bool vectors, and added a test (test_bool_vec_assign) verifying element assignment, negative indexing, and kernel/device execution for boolean vector types.

Changes

Cohort / File(s) Summary
Boolean Vector Assignment Implementation
warp/_src/builtins.py
Added two hidden overloads for assign_inplace and assign_copy targeting vector(..., dtype=bool), reusing existing vector_assign_dispatch_func logic and mirroring non-bool overload patterns.
Test Coverage
warp/tests/test_bool.py
Added test_bool_vec_assign to exercise boolean vector element assignment, negative indexing, kernel wrapper execution, and device synchronization; registered test in the TestBool suite.
Changelog
CHANGELOG.md
Added an Unreleased > Fixed entry noting the fix for boolean vector element assignment overloads.

Estimated code review effort

ðŸŽŊ 2 (Simple) | ⏱ïļ ~10 minutes

ðŸšĨ Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠ïļ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and accurately summarizes the main change: adding support for value assignment to boolean vectors in Python kernels, which is the core objective of the PR.

✏ïļ Tip: You can configure your own custom pre-merge checks in the settings.

âœĻ Finishing Touches
🧊 Generate unit tests (beta)
  • Create PR with unit tests
📝 Coding Plan
  • Generate coding plan for human review comments

Comment @coderabbitai help to get the list of available commands and usage tips.

Tip

You can validate your CodeRabbit configuration file in your editor.

If your editor has YAML language server, you can enable auto-completion and validation by adding # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json at the top of your CodeRabbit configuration file.

@thomasbbrunner

Copy link
Copy Markdown
Contributor Author

Also, should I add a changelog entry regarding this?

@greptile-apps

greptile-apps Bot commented Mar 17, 2026 •

Copy link
Copy Markdown

Greptile Summary

This PR fixes a kernel codegen error that occurred when assigning to an element of a boolean vector (e.g., v[0] = True where v is a wp.vector(dtype=wp.bool)). The root cause was that bool is not part of Warp's Scalar type alias, so no assign_inplace or assign_copy builtin overload matched the bool vector type, causing dispatch to fail.

Changes:

  • warp/_src/builtins.py: Adds explicit assign_inplace and assign_copy overloads for vector(length=Any, dtype=bool), reusing the existing shared vector_assign_dispatch_func and vector_assign_copy_value_func. The fix is minimal and mirrors the pattern used for the existing Scalar overloads.
  • warp/tests/test_bool.py: New test covering positive and negative index assignment on a vec3bool vector, exercising both the kernel compilation path and the Python-eval path.
  • warp/tests/test_vec_assign_copy.py: New test verifying copy semantics for bool vectors — that mutating b after b = a does not affect a.
  • CHANGELOG.md: Appropriate entry added with issue link.

Confidence Score: 5/5

  • This PR is safe to merge — it is a narrow, well-tested bug fix with no side effects on existing code paths.
  • The fix follows the exact same pattern already established for Scalar vectors and for quaternion/transformation types. No new logic is introduced; only two new overload registrations that delegate entirely to existing, already-tested dispatch functions. Both assign_inplace (in-place mutation) and assign_copy (copy-on-write) paths are covered by the new tests, and negative indexing is also exercised.
  • No files require special attention.

Important Files Changed

Filename Overview
warp/_src/builtins.py Adds two new add_builtin overloads (assign_inplace and assign_copy) for vector(length=Any, dtype=bool), mirroring the existing Scalar overloads. Since bool is not part of Warp's Scalar type hierarchy, it had no matching overload for index-assignment, causing the codegen error. Both new entries correctly reuse the shared vector_assign_dispatch_func and vector_assign_copy_value_func, keeping the fix minimal.
warp/tests/test_bool.py Adds test_bool_vec_assign covering positive and negative index assignment on a vec3bool vector, exercising both the kernel compilation path (via wp.launch) and the Python-eval path (direct bool_vec_assign() call). Assertion values are correct.
warp/tests/test_vec_assign_copy.py Adds test_bool_vec_assign_copy verifying copy semantics: mutating b after b = a leaves a unchanged. Covers the assign_copy path for bool vectors, which is the other new builtin overload introduced in this PR.
CHANGELOG.md Adds a one-line changelog entry accurately describing the fix and linking the corresponding GitHub issue.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["v[i] = value\n(bool vector)"] --> B{Dispatch lookup\nin builtins}
    B -->|Before PR: no match| C["WarpCodegenError:\nmissing overload"]
    B -->|After PR: match found| D{"enable_vector_component_overwrites?"}
    D -->|False| E["assign_inplace\n(vector dtype=bool)"]
    D -->|True| F["assign_copy\n(vector dtype=bool)"]
    E --> G["vector_assign_dispatch_func\n(shared with Scalar path)"]
    F --> G
    G --> H{Index type}
    H -->|int| I["types_equal check:\nvalue vs vec._wp_scalar_type_"]
    H -->|slice_t| J["type_is_vector check +\nlength compatibility"]
    I --> K["Emit C++/CUDA\nassignment"]
    J --> K
Loading

Last reviewed commit: "Add support for assi..."

Comment thread warp/tests/test_bool.py Outdated
Comment thread warp/tests/test_bool.py Outdated
@thomasbbrunner

Copy link
Copy Markdown
Contributor Author

@shi-eric it would be great if we could add this to the next patch release.

This is my first contribution, so please let me know if there's anything I'm missing here.

@shi-eric shi-eric self-assigned this Mar 17, 2026
@shi-eric shi-eric added this to the 1.12.1 milestone Mar 17, 2026
@shi-eric

Copy link
Copy Markdown
Contributor

Thanks for the contribution! You've done a pretty good job of following project conventions and I appreciated the pull request description. It should be no problem to have this included in v1.12.1.

One thing missing: the assign_copy builtin isn't exercised by any test. It's only hit when wp.config.enable_vector_component_overwrites = True, so without a test for that path, a regression there would go unnoticed.

Here's an example of what that could look like, added to test_bool.py using the save/try/finally pattern:

def test_bool_vec_assign_copy(test, device):
    old_setting = wp.config.enable_vector_component_overwrites

    try:
        wp.config.enable_vector_component_overwrites = True

        @wp.kernel(module="unique")
        def bool_vec_assign_copy_kernel():
            a = vec3bool_type(True, True, True)
            b = a
            b[1] = False

            # a should be unchanged (copy semantics)
            wp.expect_eq(a[0], True)
            wp.expect_eq(a[1], True)
            wp.expect_eq(a[2], True)

            # b should reflect the mutation
            wp.expect_eq(b[0], True)
            wp.expect_eq(b[1], False)
            wp.expect_eq(b[2], True)

        wp.launch(bool_vec_assign_copy_kernel, 1, device=device)
        wp.synchronize_device(device)
    finally:
        wp.config.enable_vector_component_overwrites = old_setting

I verified that this test fails with a clear codegen error (Couldn't find function overload for 'assign_copy') when the assign_copy builtin registration is removed, and passes with it present.

Could you also file a GitHub issue for the original bug (assigning to boolean vector components not working) and associate this PR to it? Then add a changelog entry under the Unreleased section of CHANGELOG.md referencing that issue.

@shi-eric shi-eric left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Just some minor things. As you revise your pull request it would help if you could rebase with main and keep changes limited to one commit for this fix, thanks!

Comment thread warp/tests/test_bool.py Outdated
Comment on lines +204 to +224
@wp.func
def fn():
v = vec3bool_type(True, False, True)

v[0] = False
v[2] = False

wp.expect_eq(v[0], False)
wp.expect_eq(v[1], False)
wp.expect_eq(v[2], False)

v[-1] = True
v[-3] = True

wp.expect_eq(v[-1], True)
wp.expect_eq(v[-2], False)
wp.expect_eq(v[-3], True)

@wp.kernel(module="unique")
def kernel():
fn()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can you move these definitions to the module level and pick descriptive names?

This is a micro-optimization as defining kernels inside functions can result in some extra compilation overhead due to runtime hash changes.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done!

Comment thread warp/tests/test_bool.py Outdated
Signed-off-by: Thomas B. Brunner <thomas.brunner@helsing.ai>
@thomasbbrunner
thomasbbrunner force-pushed the tbrunner/bool-vec-assign branch from 55bf8f9 to ef09577 Compare March 18, 2026 11:32
@thomasbbrunner

Copy link
Copy Markdown
Contributor Author

Thanks for the review!

Could you also file a GitHub issue for the original bug

Done (#1302)

Then add a changelog entry

I've added an entry there.

One thing missing: the assign_copy builtin isn't exercised by any test.

Good point. I thought this was needed for the assignment, but it's not. Should I remove this from this PR, as it is not relevant for fixing the core bug? Still, I've added a test for this in test_vec_assign_copy.py.

I've also rebased onto the latest main and kept the changes to a single commit.

@shi-eric

Copy link
Copy Markdown
Contributor

Thanks for the review!

Could you also file a GitHub issue for the original bug

Done (#1302)

Then add a changelog entry

I've added an entry there.

One thing missing: the assign_copy builtin isn't exercised by any test.

Good point. I thought this was needed for the assignment, but it's not. Should I remove this from this PR, as it is not relevant for fixing the core bug? Still, I've added a test for this in test_vec_assign_copy.py.

I've also rebased onto the latest main and kept the changes to a single commit.

I think it's great to fix both issues at once since they're related. Changes look good, I'll test and merge this today.

@shi-eric

Copy link
Copy Markdown
Contributor

/ok to test ef09577

@shi-eric
shi-eric merged commit 382a50d into NVIDIA:main Mar 18, 2026
19 checks passed
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.

2 participants