Skip to content

TensorNHWC::inverse device path diverges from host path when strides are not w-multiples #3519

Description

@VaggelisGian

Description

TensorNHWC::inverse(LongIndex) (include/cutlass/layout/tensor.h ~lines 158-188) computes different results on device and host whenever stride_h or stride_n is not a multiple of stride_w.

The device branch computes

c = int(index % static_cast<int>(stride_[0]));   // provisional, before any division
...
fast_divmod(n, tmp, index, stride_[2], hw_mul, hw_shr);
fast_divmod(h, w, tmp,  stride_[1], w_mul, w_shr);
fast_divmod(w, tmp, w,  stride_[0], c_mul, c_shr);   // final remainder -> tmp, discarded

The channel coordinate is taken from the pre-division remainder expression and never updated; the actual post-divide residual lands in tmp and is thrown away. The host branch derives c = residual % stride_[0] from the final residual, which is the correct inverse of the packed/strided forward mapping.

Simulating the verbatim device branch with cutlass's own find_divisor/fast_divmod for strides (6, 15, 45) and index = 15 gives (n=0, h=1, w=0, c=3) where the host path returns (n=0, h=1, w=0, c=0). The only in-tree caller (test/unit/layout/tensor_nhwc.cu) uses packed strides where both paths agree, so the divergence has gone unnoticed. Minor adjacent note: find_divisor also assumes positive strides.

Suggested fix

Set c from the final fast_divmod remainder (the value currently discarded into tmp), matching the host branch.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions