Skip to content

feat: add foundational search utilities and extend bitmask primitives#8

Open
dhalmazna wants to merge 2 commits intofeat/segment-and-hyperpixel-scoringfrom
feat/algorithm-utils
Open

feat: add foundational search utilities and extend bitmask primitives#8
dhalmazna wants to merge 2 commits intofeat/segment-and-hyperpixel-scoringfrom
feat/algorithm-utils

Conversation

@dhalmazna
Copy link
Collaborator

@dhalmazna dhalmazna commented Mar 14, 2026

Context:
This PR establishes the foundational building blocks required for the upcoming algorithms. By extracting shared logic and low-level graph operations into dedicated utility modules, we ensure the main algorithm implementations will remain clean, readable, and highly optimized.

What was added / changed:

  • algorithm/search_helpers.py: Introduced utilities used by the search algorithms:
    • evaluate_masks: A wrapper for batched mask evaluation that now correctly propagates the replacement_image (aligning with our stateless predictor architecture).
    • is_terminal: A fast state-check helper to determine if a search path has reached its maximum depth or exhausted its frontier.
  • algorithm/bitmask_graph.py: Expanded the low-level bitwise operations. Added fast primitives for node mutation (add_node, remove_node, has_node), random selection (pick_random_set_bit), and a random walk sampler (sample_connected_superset) for Monte Carlo rollouts.

Related Task:
XAI-29

@dhalmazna dhalmazna self-assigned this Mar 14, 2026
Copilot AI review requested due to automatic review settings March 14, 2026 12:13
@coderabbitai
Copy link

coderabbitai bot commented Mar 14, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0d598c30-e557-4006-8d01-b31d26cdbd0c

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/algorithm-utils
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@gemini-code-assist
Copy link

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request lays the groundwork for upcoming search algorithms by centralizing common logic and low-level graph operations. It aims to keep the main algorithm implementations clean and optimized by providing dedicated utility modules for tasks such as efficient bitmask manipulation and batched evaluation of segment masks, ensuring a robust and scalable foundation.

Highlights

  • New Search Helper Utilities: Introduced ciao/algorithm/search_helpers.py to house shared functions for Monte Carlo Tree Search (MCTS) and Monte Carlo Graph Search (MCGS) algorithms. This includes evaluate_masks for batched mask evaluation and is_terminal for fast state-checking.
  • Expanded Bitmask Graph Primitives: Enhanced ciao/algorithm/bitmask_graph.py with new low-level bitwise operations. Added functions for node mutation (add_node, remove_node, has_node), random selection (pick_random_set_bit), and a random walk sampler (sample_connected_superset) for Monte Carlo rollouts.
  • Module Export Updates: The ciao/algorithm/__init__.py file was updated to export all newly added utility functions, making them accessible from the top-level ciao.algorithm package.
Changelog
  • ciao/algorithm/init.py
    • Imported new functions from bitmask_graph module: add_node, has_node, mask_to_ids, pick_random_set_bit, remove_node, sample_connected_superset.
    • Imported new functions from search_helpers module: evaluate_masks, is_terminal.
    • Exported all newly imported functions via the __all__ list.
  • ciao/algorithm/bitmask_graph.py
    • Imported the random module.
    • Added mask_to_ids function to convert an integer bitmask to a list of segment indices.
    • Added has_node function to efficiently check if a specific node is present in a bitmask.
    • Added add_node function to set a specific bit in a mask, effectively adding a node.
    • Added remove_node function to clear a specific bit in a mask, effectively removing a node.
    • Added pick_random_set_bit function to select a random set bit from a mask without allocating a list.
    • Added sample_connected_superset function for generating a connected superset via a random walk expansion.
    • Updated the module docstring to reflect its current state as providing primitives.
  • ciao/algorithm/search_helpers.py
    • Created a new file to house shared utilities for MCTS and MCGS algorithms.
    • Imported necessary modules: numpy, torch, get_frontier, iter_bits, ModelPredictor, and calculate_hyperpixel_deltas.
    • Added is_terminal function to determine if a search state is terminal based on maximum depth or an empty frontier.
    • Added evaluate_masks function to compute class score deltas for a list of segment masks in a batched manner, including validation for positive integer masks.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a solid set of foundational utilities for search algorithms and bitmask operations. The new functions are well-documented and the separation into bitmask_graph.py and search_helpers.py is logical. My review focuses on improving consistency, efficiency, documentation accuracy, and robustness. I've suggested a more efficient implementation for mask_to_ids, a correction to a docstring, a robustness improvement for sample_connected_superset, and a change to ensure the new mask_to_ids utility is used consistently.

Copy link

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.

Pull request overview

Adds foundational utilities to support upcoming Monte Carlo search algorithms by centralizing common terminal-state checks, batched mask evaluation, and extending bitmask graph primitives.

Changes:

  • Added ciao/algorithm/search_helpers.py with is_terminal and evaluate_masks for shared MCTS/MCGS logic.
  • Extended ciao/algorithm/bitmask_graph.py with node mutation helpers, random set-bit selection, and a connected-superset sampler.
  • Re-exported the new utilities from ciao/algorithm/__init__.py.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

File Description
ciao/algorithm/search_helpers.py New shared helpers for terminal checks and batched reward evaluation.
ciao/algorithm/bitmask_graph.py New bitmask primitives and sampling utilities for graph-based expansions.
ciao/algorithm/init.py Exposes new utilities at the package level via imports and __all__.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines +97 to +124
def sample_connected_superset(
base_mask: int,
target_length: int,
adj_masks: tuple[int, ...],
used_mask: int,
) -> int:
"""Sample a connected superset via random walk expansion.

IMPORTANT: This is NOT a uniform sampler over all connected supersets.
The distribution is biased towards segments discovered early and
depends on graph topology. This bias is acceptable for Monte Carlo
estimation in the parent algorithm.

Args:
base_mask: Starting set (must be non-empty and connected)
target_length: Desired size of the superset
adj_masks: Adjacency bitmasks for neighbor lookups
used_mask: Global exclusion mask (segments that must not be added)

Returns:
Bitmask of connected superset containing base_mask
"""
mask = base_mask

while mask.bit_count() < target_length:
frontier = get_frontier(mask, adj_masks, used_mask)
if frontier == 0:
break
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This checking would be too computationally expensive. The mask will be always connected because of the way it is created - we always add a neighbor from the frontier.

@dhalmazna dhalmazna force-pushed the feat/algorithm-utils branch from fce3836 to dd0ad92 Compare March 15, 2026 17:21
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