Skip to content

bug: portable DCOPY and SCOPY leave values uncopied for unit strides #15823

Open

Description

@benatsf

Description

The portable C implementations of dcopy and scopy leave destination elements unchanged for a contiguous copy of 14 or more elements. With N=14, both routines copy the first seven elements and leave the remaining seven at their original values.

In both *_ndarray.c files, the unit-stride branch repeats the seven-element unrolled body without advancing ix or iy. The ordinary C entry points delegate to that branch. The JavaScript ndarray implementations advance the indices correctly.

This was reproduced by compiling the portable C sources directly on Linux x86_64 with GCC 14.2.0. The default Linux native manifest selects Fortran, so this report does not claim that the default Linux addon, Windows or WebAssembly execution was tested.

Reproduction

From a checkout at 758379dcbf0a76a9cc3f907c87e6edc3d6c4e2c1, save the following as repro.c:

#include <stdio.h>
#include "stdlib/blas/base/dcopy.h"
#include "stdlib/blas/base/scopy.h"

int main( void ) {
    double x[14], y[14];
    float sx[14], sy[14];
    int i;
    for ( i = 0; i < 14; i++ ) {
        x[i] = (double)( i + 1 );
        sx[i] = (float)( i + 1 );
        y[i] = -1.0;
        sy[i] = -1.0f;
    }
    c_dcopy( 14, x, 1, y, 1 );
    c_scopy( 14, sx, 1, sy, 1 );
    printf( "DCOPY:" );
    for ( i = 0; i < 14; i++ ) printf( " %.0f", y[i] );
    printf( "\nSCOPY:" );
    for ( i = 0; i < 14; i++ ) printf( " %.0f", (double)sy[i] );
    printf( "\n" );
    return 0;
}

Compile the actual portable kernels and their stride-offset helper:

gcc -std=c99 -Wall -Wextra -Werror -O2 -Ilib/node_modules/@stdlib/blas/base/dcopy/include -Ilib/node_modules/@stdlib/blas/base/scopy/include -Ilib/node_modules/@stdlib/blas/base/shared/include -Ilib/node_modules/@stdlib/blas/base/diagonal-types/include -Ilib/node_modules/@stdlib/blas/base/layouts/include -Ilib/node_modules/@stdlib/blas/base/matrix-orientations/include -Ilib/node_modules/@stdlib/blas/base/matrix-triangles/include -Ilib/node_modules/@stdlib/blas/base/operation-sides/include -Ilib/node_modules/@stdlib/blas/base/transpose-operations/include -Ilib/node_modules/@stdlib/strided/base/stride2offset/include repro.c lib/node_modules/@stdlib/blas/base/dcopy/src/dcopy.c lib/node_modules/@stdlib/blas/base/dcopy/src/dcopy_ndarray.c lib/node_modules/@stdlib/blas/base/scopy/src/scopy.c lib/node_modules/@stdlib/blas/base/scopy/src/scopy_ndarray.c lib/node_modules/@stdlib/strided/base/stride2offset/src/main.c -o repro
./repro

Expected Results

DCOPY: 1 2 3 4 5 6 7 8 9 10 11 12 13 14
SCOPY: 1 2 3 4 5 6 7 8 9 10 11 12 13 14

Actual Results

DCOPY: 1 2 3 4 5 6 7 -1 -1 -1 -1 -1 -1 -1
SCOPY: 1 2 3 4 5 6 7 -1 -1 -1 -1 -1 -1 -1

Additional direct portable-kernel checks reproduced the same failure at lengths 15, 16, 21 and 28, with nonzero offsets. Signed, nonunit and broadcast-stride control copies preserved the expected results and guards.

Version and Environment

  • stdlib develop: 758379dcbf0a76a9cc3f907c87e6edc3d6c4e2c1
  • Actual execution: portable LP64 C kernels, Linux x86_64, GCC 14.2.0
  • Browser / Node.js runtime: not used for this reproduction

Related Issues and Questions

No existing report or overlapping source fix was found in the completed issue and all-state PR searches. Is one related correction across both portable real-copy routines, with regressions that explicitly exercise the portable backend, the preferred scope?

Checklist and AI Disclosure

  • The Code of Conduct was read and applied by Codex under the account owner's authorization.
  • Existing issues and pull requests were searched, including their relevant discussions and changed files.

OpenAI Codex prepared this report and reproduction, inspected the existing source and actually compiled and executed the commands above under benatsf's authorization. No applicant manual authorship, personal review or personal understanding is claimed. This is a bug report; a fix PR will wait for maintainer feedback as required by the contributing guide.

Activity

  1. stdlib-bot commented on Oct 2, 2026

    @stdlib-bot
    Contributor

    👋 Hi there! 👋

    And thank you for opening your first issue! We will get back to you shortly. 🏃 💨

    If you have any further questions while waiting for a response, please join our Zulip community to chat with project maintainers and other community members.

  2. mantrapatel05 commented on Oct 3, 2026

    @mantrapatel05
    Contributor

    @benatsf Hey, I'd like to take this one. Looks like the unit-stride unrolled loop in dcopy_ndarray.c and scopy_ndarray.c never advances ix/iy after each block, so anything past the first 7 elements gets skipped for N >= 14. Fix should just be ix += M; iy += M; like in dswap.

    Happy to send a PR with tests once you give the go-ahead. Would you prefer one PR for both or one per package?

  3. benatsf commented on Oct 3, 2026

    @benatsf
    Author

    Thanks, @mantrapatel05, please go ahead. I'd prefer one PR covering both DCOPY and SCOPY, since they share the same defect, with regression tests covering multiple unrolled blocks and nonzero offsets.

    I'm the issue reporter, so the maintainers have the final say on PR scope and acceptance.

  4. added
    BugSomething isn't working.
    BLASIssue or pull request related to Basic Linear Algebra Subprograms (BLAS).
    CIssue involves or relates to C.
    priority: HighHigh priority concern or feature request.
    on Oct 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    BLASIssue or pull request related to Basic Linear Algebra Subprograms (BLAS).BugSomething isn't working.CIssue involves or relates to C.priority: HighHigh priority concern or feature request.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions