Skip to content

Add OpSelectBinary, v/m_assign_bslct_masked, v_gather and optimize Boruvka's MST - #244

Open
b08lsoai wants to merge 67 commits into
SparseLinearAlgebra:mainfrom
b08lsoai:develop
Open

b08lsoai wants to merge 67 commits into
SparseLinearAlgebra:mainfrom
b08lsoai:develop

Conversation

@b08lsoai

@b08lsoai b08lsoai commented Aug 27, 2026

Copy link
Copy Markdown

Short description

This PR adds new core operations to the library: the binary selector (OpSelectBinary) and the vector gather (v_gather). Based on the binary selector, masked assignment operations (v_assign_bslct_masked, m_assign_bslct_masked) have been implemented on both CPU and OpenCL backends.

Additionally, Boruvka's MST algorithm has been optimized by offloading heavy host-side loops to the new OpenCL kernels, and critical bugs have been resolved.

List of changes

New operation type

  • Added OpSelectBinary interface and implementation supporting bool(T, T) signatures.
  • Extended OpenCL program builder to handle OpSelectBinary code generation.

New primitives: v_assign_bslct_masked / m_assign_bslct_masked / v_gather

  • Implemented vector and matrix masked assignment operations and vector gather on both CPU and OpenCL backends.
  • Signatures:
    Status exec_v_assign_bslct_masked(
              ref_ptr<Vector>         r,
              ref_ptr<Vector>         mask,
              ref_ptr<Scalar>         mask_value,
              ref_ptr<Scalar>         value,
              ref_ptr<OpBinary>       op_assign,
              ref_ptr<OpSelectBinary> op_select_bin,
              ref_ptr<Descriptor>     desc     = ref_ptr<Descriptor>(),
              ref_ptr<ScheduleTask>*  task_hnd = nullptr);
    
    Status exec_m_assign_bslct_masked(
              ref_ptr<Matrix>         r,
              ref_ptr<Vector>         mask,
              ref_ptr<Scalar>         value,
              ref_ptr<OpBinary>       op_assign,
              ref_ptr<OpSelectBinary> op_select_bin,
              ref_ptr<Descriptor>     desc     = ref_ptr<Descriptor>(),
              ref_ptr<ScheduleTask>*  task_hnd = nullptr);
    
    Status exec_v_gather(
              ref_ptr<Vector>         r,
              ref_ptr<Vector>         source,
              ref_ptr<Vector>         indices,
              ref_ptr<Descriptor>     desc     = ref_ptr<Descriptor>(),
              ref_ptr<ScheduleTask>*  task_hnd = nullptr);
  • Logic:
    • v_assign_bslct_masked: Updates vector elements r[i] = op_assign(r[i], value) only if op_select_bin(mask[i], mask_value) is true.
    • m_assign_bslct_masked: For each matrix element at position [row, col], it updates the element's value as r[row, col] = op_assign(r[row, col], value) only if op_select_bin(mask[row], mask[col]) is true.
    • v_gather: Updates vector elements r[k] = source[indices[k]]

Bug fixes

  • Fixed TScalar<Pair>: added missing override keywords, removed invalid const specifier, and corrected as_pair() to return m_value properly (restoring host<->device scalar readback).
  • Fixed missing T_PAIR type support.
  • Removed legacy needs_pair_override hack that caused macro redefinition conflicts.
  • Added CLProgram initialization on cache miss.
  • Fixed uninitialized n_sort in MtxLoader for weighted matrices (previously caused out-of-bounds access).
  • Fixed OpenCL source generation for Pair operations (IDENTITY_PAIR, MUL_PAIR, MIN_PAIR, SECOND_PAIR, ALWAYS_PAIR).
  • m_extract_row: fixed row vector initialization and moved range bounds calculation directly into the OpenCL kernel.
  • Added --run-cpu mode to the mst utility
  • Fixed MtxLoader::save to preserve matrix weights when writing to file.
  • Fixed cycle formation in MST by adding a directed component merge condition.

Boruvka's MST optimization

  • Step 5a (search min edge): per-component CPU loop with m_extract_row and manual minimum search replaced with a single mxv_masked over the whole matrix, which works only over non-zero elements (nnz instead of $n^2$).
  • Step 5b (update parent): nested $O(n^2)$ loop replaced with union-find via v_gather-based pointer jumping (similar to GxB_Vector_extract_Vector in LAGraph).
  • Step 6 (filter S): CPU $O(n^2)$ loop with get_pair/set_pair replaced with m_assign_bslct_masked.
  • Performance measurements are attached in mst_benchmark.pdf.

Type of changes

  • bug-fix (change which fixes some issue)
  • new-feature (change which proposes new feature or functionality)
  • breaking-change (change which brakes compatibility of api or etc.)

Changes aspect

  • unit-tests for C/C++ code added
  • benchmark for C/C++ code added
  • workflow tests to .github scripts added
  • C bindings to C++ code added
  • Python bindings to C code added
  • documentation to C/C++ code added
  • documentation to Python code added

Testing strategy

Unit Tests

  • Added the files tests/test_v_assign_bslct.cpp, tests/test_m_assign_bslct.cpp, and tests/test_v_gather.cpp: these test the corresponding operations on both CPU and OpenCL backends.
  • All tests pass on both CPU and OpenCL backends.

Background

This PR is based on two PRs:

therain7 and others added 30 commits November 28, 2025 17:17
fix clang tidy code style2

fix algorithm.cpp

cland tidy 3
@b08lsoai b08lsoai changed the title Implement OpSelectBinary and v/m_assign_bslct_masked operations Add OpSelectBinary, v/m_assign_bslct_masked, v_gather and optimize Boruvka MST Sep 16, 2026
@b08lsoai b08lsoai changed the title Add OpSelectBinary, v/m_assign_bslct_masked, v_gather and optimize Boruvka MST Add OpSelectBinary, v/m_assign_bslct_masked, v_gather and optimize Boruvka's MST Sep 16, 2026
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