Repository navigation
bug: portable DCOPY and SCOPY leave values uncopied for unit strides #15823
Description
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
./reproExpected 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
stdlib-bot commentedon Oct 2, 2026
👋 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.
mantrapatel05 commentedon Oct 3, 2026
@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?
benatsf commentedon Oct 3, 2026
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.