Environment
- MS-MPI version: 10.1.12498.52 (also reproduces on 8.1.12438.1084)
- OS: Windows 10 Pro 10.0.19045
- Compiler: MinGW GCC (g++ -std=c++17 -O2), linked directly against msmpi.dll
Summary
A MPI_Alltoallw call using a 4-level nested derived datatype -- MPI_Type_indexed wrapping
MPI_Type_create_resized wrapping MPI_Type_indexed wrapping MPI_Type_create_resized wrapping
MPI_DOUBLE -- produces incorrect results only at comm_size == 8. It is clean at 4, 5, 6, and 7
processes. Depending on the data size, the failure manifests as either:
- silently wrong values delivered to the receive buffer (small buffers, no error), or
- an access violation crash (0xc0000005) partway through the same MPI_Alltoallw call (larger buffers).
Confirmed this is MS-MPI-specific: the identical standalone reproduction is clean on Linux at every
process count 4-8 (Open MPI 4.1.2, kernel 5.15.0-187-generic, built with mpicxx/mpirun).
Minimal reproduction
Attached: msmpi_repro_3981.cpp (~150 lines, no dependencies beyond mpi.h).
Build (Windows/MinGW):
g++ -std=c++17 -O2 -I"C:\Program Files (x86)\Microsoft SDKs\MPI\Include" msmpi_repro_3981.cpp -o msmpi_repro_3981.exe "C:/Windows/System32/msmpi.dll" -lwsock32 -lws2_32 -lcrypt32 -lwintrust -lshlwapi
Run (silent-corruption variant, n=12):
mpiexec -n 4 msmpi_repro_3981.exe 12 # PASS
mpiexec -n 8 msmpi_repro_3981.exe 12 # FAIL -- wrong values, no crash
Run (crash variant, n=70):
mpiexec -n 4 msmpi_repro_3981.exe 70 # PASS
mpiexec -n 8 msmpi_repro_3981.exe 70 # crashes (access violation)
Expected: PASS at every process count, matching the independently-computed expected values in the repro.
Actual: PASS at 4, 5, 6, 7; FAIL or crash at exactly 8.
The repro builds the send/receive derived types per-rank from a small index permutation, mirroring
a real internal use case (a distributed permutation x dense matrix multiply). A purely
synthetic/uniform version of the same nesting depth (regular block patterns, no permutation-driven
scatter) did NOT reproduce it in our testing, so the exact irregular block/displacement pattern
appears to matter. Happy to provide more detail if useful.
msmpi_repro_3981.cpp
Environment
Summary
A MPI_Alltoallw call using a 4-level nested derived datatype -- MPI_Type_indexed wrapping
MPI_Type_create_resized wrapping MPI_Type_indexed wrapping MPI_Type_create_resized wrapping
MPI_DOUBLE -- produces incorrect results only at comm_size == 8. It is clean at 4, 5, 6, and 7
processes. Depending on the data size, the failure manifests as either:
Confirmed this is MS-MPI-specific: the identical standalone reproduction is clean on Linux at every
process count 4-8 (Open MPI 4.1.2, kernel 5.15.0-187-generic, built with mpicxx/mpirun).
Minimal reproduction
Attached: msmpi_repro_3981.cpp (~150 lines, no dependencies beyond mpi.h).
Build (Windows/MinGW):
g++ -std=c++17 -O2 -I"C:\Program Files (x86)\Microsoft SDKs\MPI\Include" msmpi_repro_3981.cpp -o msmpi_repro_3981.exe "C:/Windows/System32/msmpi.dll" -lwsock32 -lws2_32 -lcrypt32 -lwintrust -lshlwapi
Run (silent-corruption variant, n=12):
mpiexec -n 4 msmpi_repro_3981.exe 12 # PASS
mpiexec -n 8 msmpi_repro_3981.exe 12 # FAIL -- wrong values, no crash
Run (crash variant, n=70):
mpiexec -n 4 msmpi_repro_3981.exe 70 # PASS
mpiexec -n 8 msmpi_repro_3981.exe 70 # crashes (access violation)
Expected: PASS at every process count, matching the independently-computed expected values in the repro.
Actual: PASS at 4, 5, 6, 7; FAIL or crash at exactly 8.
The repro builds the send/receive derived types per-rank from a small index permutation, mirroring
a real internal use case (a distributed permutation x dense matrix multiply). A purely
synthetic/uniform version of the same nesting depth (regular block patterns, no permutation-driven
scatter) did NOT reproduce it in our testing, so the exact irregular block/displacement pattern
appears to matter. Happy to provide more detail if useful.
msmpi_repro_3981.cpp