Skip to content

meson build: SSE2/AVX2 Blosc shuffle is never enabled with MSVC (Windows branch is dead code) #866

Open

Description

@d-v-b

🤖 AI text below 🤖

Problem description

In 0.17.0's src/numcodecs/meson.build, the x86_64 SIMD detection uses GCC-style flags:

have_sse2 = cc.has_argument('-msse2')
...
have_avx2 = cc.has_argument('-mavx2')

MSVC doesn't accept -msse2 or -mavx2, so with cl.exe both checks always fail. This line is from the conda-forge win-64 build log:

C compiler for the host machine: cl.exe (msvc 19.44.35229 ...)
...
Compiler for C supports arguments -msse2: NO

As a result, the Windows-specific blocks further down can never run:

if have_sse2
  ...
  blosc_c_args += ['-DSHUFFLE_SSE2_ENABLED', '-msse2']
  if host_machine.system() == 'windows'
    blosc_c_args += ['-D__SSE2__']
  endif
endif

The same applies to the AVX2 block and -D__AVX2__. The Windows build always uses the generic shuffle/bitshuffle code.

This is not a regression from 0.16.x. The old setup.py gated SIMD on cpuinfo.platform.machine() == 'x86_64', which is 'AMD64' on Windows, so SSE2/AVX2 were never enabled there either. It does look like the meson build meant to support SIMD on Windows, since it adds the __SSE2__/__AVX2__ defines for that case.

Expected behaviour

On x86_64 with MSVC:

  • SSE2 is part of the x64 baseline, so have_sse2 can be true without any compiler flag.
  • MSVC allows AVX2 intrinsics without /arch:AVX2, and c-blosc picks the implementation at runtime (__cpuid under _MSC_VER in shuffle.c). So the AVX2 sources can be compiled without a flag as well. /arch:AVX2 should not be used, because it would let the compiler emit AVX2 in the rest of the translation unit.

A possible shape for the fix (untested):

is_msvc = cc.get_argument_syntax() == 'msvc'

if get_option('sse2').disabled() or disable_sse2_env
  have_sse2 = false
else
  have_sse2 = is_msvc or cc.has_argument('-msse2')
endif
# same for avx2

The -msse2/-mavx2 additions to blosc_c_args would then need to be skipped for MSVC, keeping only the -D__SSE2__/-D__AVX2__ defines.

Related: zstd assembly source breaks MSVC builds

Also on x86_64 + MSVC, meson setup currently fails outright:

src\numcodecs\meson.build:96:13: ERROR: No host machine compiler for
'src/numcodecs/../../c-blosc/internal-complibs/zstd-1.5.6/decompress/huf_decompress_amd64.S'

zstd already turns off its assembly paths under MSVC (ZSTD_ASM_SUPPORTED in common/portability_macros.h), so the .S file can be skipped there. conda-forge is currently carrying this patch:

if host_machine.cpu_family() == 'x86_64' and cc.get_argument_syntax() != 'msvc'

See conda-forge/numcodecs-feedstock#126.

Version and installation information

  • numcodecs.__version__: 0.17.0 (sdist from PyPI)
  • Python: 3.12–3.14
  • OS: Windows (win-64, MSVC 19.44 / VS 2022)
  • Installation: conda-forge build (pip install . --no-build-isolation with meson-python)

Activity

  1. d-v-b commented on Sep 29, 2026

    @d-v-b
    ContributorAuthor

    @mkitti does checking / fixing this excite you? otherwise I can handle it

  2. mkitti commented on Sep 29, 2026

    @mkitti
    Contributor

    The numcodecs-feedstock should probably depend on the blosc-feedstock for this:
    https://github.com/conda-forge/blosc-feedstock/blob/main/recipe/bld.bat
    https://github.com/conda-forge/blosc-feedstock/blob/main/recipe/build.sh

    We probably should be building blosc using its native toolchain rather than trying to reinvent it.

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions