Skip to content

Fix expression slices after dropping a dimension - #1254

Open
Arthur031221 wants to merge 3 commits into
NVIDIA:mainfrom
Arthur031221:fix-expression-slice-dropped-dimensions
Open

Arthur031221 wants to merge 3 commits into
NVIDIA:mainfrom
Arthur031221:fix-expression-slice-dropped-dimensions

Conversation

@Arthur031221

Copy link
Copy Markdown
Contributor

Users slicing an expression after dropping an earlier dimension get values from the wrong offset. For a fixed 3 by 5 input, slice<1>(input + 0, {1, 2}, {matxDropDim, matxEnd}) returned 11, 12, 13 instead of 12, 13, 14. Adding a stride to this expression failed to compile.

SliceOp read start offsets and calculated strided output sizes using an output dimension index where it needed an input dimension index. Its strided overload declared a reference member that it could not initialize. The fix stores strides by value and includes them in JIT argument storage, which the generated operator reads.

The new test checks literal values for ordinary and strided expression slices, the downsample wrapper on an expression, a tensor-view control, and JIT execution of both slice expressions. From the worktree, build/test/test_00_operators_slice_test --gtest_brief=1 passed 49 of 49 tests and build-jit/test/test_00_operators_slice_test --gtest_brief=1 passed 61 of 61 tests on an RTX 5090 with CUDA 13.2.51. The slice-stride, slice-and-reduce, slice-and-reshape, and up/downsample targets passed 16 of 16, 48 of 48, 8 of 8, and 96 of 96 tests. The full test suite was not built.

@copy-pr-bot

copy-pr-bot Bot commented Oct 2, 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.

@greptile-apps

greptile-apps Bot commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 5/5

[Medium risk] Fixes slice operator behavior when dropping dimensions.

The PR appears safe to merge, though moving JIT slices may incur repeated compilation and disk-cache growth.

Findings

  1. P2 Moving slices lose kernel reuse ▶

Summary

The PR corrects expression-slice indexing after a dimension is dropped and adds host, CUDA, and JIT regressions. The latest revision moves slice starts and strides into generated JIT constants and distinguishes their cache entries.

  • The indexing and execution-path fixes are covered by focused tests.
  • Encoding each slice position in the JIT identity introduces a non-blocking compilation and cache-growth cost for moving windows.

Reviews (3) · Last reviewed commit: "Restore compile-time JIT slice parameter..."

Comment thread include/matx/operators/slice.h
Comment thread include/matx/operators/slice.h
Comment thread test/00_operators/slice_test.cu
Pass slice starts through runtime JIT storage and version the generated
class name to exclude kernels built with the old indexing. Cover reuse
across start offsets and ordinary CUDA expression assignments.
@cliffburdick

Copy link
Copy Markdown
Collaborator

/build

Comment thread include/matx/operators/slice.h Outdated
#ifdef MATX_EN_JIT
struct JIT_Storage {
typename detail::inner_storage_or_self_t<detail::base_type_t<T>> op_;
cuda::std::array<shape_type, T::Rank()> starts_;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

For the JIT path starts and strides are intentionally encoded in the name so they can be compile-time parameters. What's the reason this is runtime now?

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.

I moved them to runtime storage to avoid cache collisions. That was a broader change than needed: on the upstream header, the class name records dimensions and sizes but omits starts and strides.

The generated slice now uses constexpr starts and strides, with their resolved values in the versioned class name. JIT launch storage now contains the nested operator, replacing the storage layout described in the PR body.

The JIT-enabled slice and slice-stride targets passed 62 and 20 tests locally. The cache regression varies starts on retained and dropped axes and strides for two-element outputs.

@coveralls

Copy link
Copy Markdown

Coverage Status

Coverage is 93.598% — Arthur031221:fix-expression-slice-dropped-dimensions into NVIDIA:main. No base build found for NVIDIA:main.

Comment on lines +89 to +94
for (int i = 0; i < input_rank; i++) {
params_str += std::format("b{}_", starts_[i]);
if constexpr (!cuda::std::is_same_v<StrideType, NoStride>) {
params_str += std::format("t{}_", strides_[i]);
}
}

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.

P2 Moving slices lose kernel reuse

When a JIT workload moves a slice window across an expression, each new start or stride changes the generated class name and cache key. Even if the output shape stays the same, each position needs a separate NVRTC compilation and persistent cubin rather than reusing a kernel with runtime offsets. This can slow repeated windowed slicing and grow the disk cache.

Knowledge Base Used: CUDA and JIT executors

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

This branch has not been deployed

No deployments
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