Skip to content

Add Glushkov regex fast-path to libcudf - #21936

Merged
rapids-bot[bot] merged 97 commits into
rapidsai:mainfrom
lingyany-nv:lingyany/glushkov-nfa
Jul 14, 2026
Merged

Add Glushkov regex fast-path to libcudf#21936
rapids-bot[bot] merged 97 commits into
rapidsai:mainfrom
lingyany-nv:lingyany/glushkov-nfa

Conversation

@lingyany-nv

@lingyany-nv lingyany-nv commented Mar 25, 2026

Copy link
Copy Markdown
Contributor

Description

Add bit-parallel Glushkov NFA regex engine with shared memory optimization

Implement Glushkov's NFA for regex string matching in libcudf: references (1) hyperscan paper (2) HybridSA paper (3) vectorscan repo.
Basically, this is Glushkov's NFA compared with the other popular Thompson's NFA (also used in current libcudf regex). The Glushkov engine represents NFA state as a single uint64_t bitmask (max 64 positions), requiring no global memory per thread. Shared memory is used to hold the static instructions like in the current implementation.

Key changes

  • Two-phase O(n) unanchored search algorithm (glushkov.inl): Phase 1 scans forward, injecting start states each character and recording provisional match ends. Phase 2 rescans only the match region to find the true leftmost start. Each character is processed at most twice.
  • Leftmost-first correctness via priority-kill (glushkov.cuh, glushkov_regcomp.cpp): A runtime glushkov_priority_kill clears lower-priority alternative paths at accept time. A compile-time conflict detector (frontier_has_priority_conflict) conservatively falls back to Thompson when bit-index ordering cannot guarantee Thompson-compatible leftmost-first semantics.
  • Automatic fallback: Patterns with anchors (^, $, \b, \B), >64 positions, match empty top-level expressions, capture group requirements (extract, backref_re), or priority conflicts transparently fall back to Thompson NFA — no user intervention needed.

Limitations

  • does not support capturing groups (e.g. extract, extract_all, findall, replace_with_backrefs)
  • does not support zero-width assertions (empty-matchable) like BOL/EOL/BOW/NBOW
  • max 64 character-consuming positions since we are using uint64_t as state data per row/thread
  • does not support lazy quantifiers
  • empty/degenerate patterns rejected
  • does not support empty-matchable patterns as well as some ambiguous alternation patterns

When above condition is detected, it falls back to use the current Thompson's NFA.

Unit tests + benchmark

  • Priority-kill parity tests: Verify Glushkov matches Thompson for overlapping-prefix alternations (foo|foobar, cat|catch, a|aa) across all 5 operations (contains, count, findall, replace, split)
  • Empty-matchable fallback parity: Confirm nullable patterns (a*, \d*, (ab)?) transparently fall back to Thompson and produce identical results
  • Spark-rapids compatibility: ~60 regex patterns from spark-rapids integration tests validated under both engines via parametrized Python tests
  • Benchmarks: 6–9 patterns per benchmark covering char classes, alternation, bounded repetition, dot wildcards, and late-failure stress patterns
  • Extended more complex regexes in the current split_re/contains/replace_re/count, it showed 1.01-6.62x speedup.

Checklist

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

@lingyany-nv
lingyany-nv requested review from a team as code owners March 25, 2026 21:09
@copy-pr-bot

copy-pr-bot Bot commented Mar 25, 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.

@github-actions github-actions Bot added libcudf Affects libcudf (C++/CUDA) code. Python Affects Python cuDF API. CMake CMake build issue pylibcudf Issues specific to the pylibcudf package labels Mar 25, 2026
@GPUtester GPUtester moved this to In Progress in cuDF Python Mar 25, 2026
@lingyany-nv
lingyany-nv marked this pull request as draft March 25, 2026 21:24
@PointKernel PointKernel added 2 - In Progress Currently a work in progress feature request New feature or request non-breaking Non-breaking change labels Mar 25, 2026
@GregoryKimball GregoryKimball changed the title [draft] Implement Glushkov's NFA into cudf [draft] Implement Glushkov's NFA into cuDF Apr 8, 2026
@davidwendt

Copy link
Copy Markdown
Contributor

/ok to test 41caa42

@davidwendt
davidwendt requested review from PointKernel and davidwendt and removed request for Matt711 and davidwendt July 9, 2026 12:52
@davidwendt

Copy link
Copy Markdown
Contributor

/ok to test cc0e60a

@PointKernel PointKernel left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Some final nitpicks otherwise LGTM

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'm happy with that. As a small suggestion, would it make sense for new headers like glushkov_regcomp.h to use the .hpp extension?

Comment thread cpp/src/strings/regex/glushkov.cuh
*/
void ordered_eps_frontier(int32_t const start,
reprog const& prog,
std::vector<int32_t> const& inst_to_pos,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

probably an overlook.

Comment thread cpp/src/strings/count_matches.hpp
@davidwendt

Copy link
Copy Markdown
Contributor

/ok to test 8eaf307

@bdice bdice 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.

Approving CMake (did not review C++).

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.

I'm favorable towards changing this. If not in this PR, in an immediate follow-up.

@davidwendt

Copy link
Copy Markdown
Contributor

/ok to test 0e54aa9

@davidwendt

Copy link
Copy Markdown
Contributor

/ok to test faf578d

@davidwendt

Copy link
Copy Markdown
Contributor

/merge

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

Labels

3 - Ready for Review Ready for review by team CMake CMake build issue feature request New feature or request libcudf Affects libcudf (C++/CUDA) code. non-breaking Non-breaking change pylibcudf Issues specific to the pylibcudf package Python Affects Python cuDF API.

Projects

Status: Done
Status: Landed

Development

Successfully merging this pull request may close these issues.

9 participants