Skip to content

[Bug]: M_LOG2E availability depends on build configuration in the FlashMLA extension#53935

Description

@rogeroberg

Your current environment

Environment

  • Windows Server 2025
  • Visual Studio Build Tools with MSVC
  • CUDA/NVCC 13.2
  • Python 3.12
  • PyTorch 2.11.0+cu130
  • SystemPanic/vllm-windows 0.25-based deployment
  • DeepSeek-V4-Flash-0731
  • 4 x H200 NVL GPUs

馃悰 Describe the bug

Background

I encountered this issue while building the vllm-project/FlashMLA fork through SystemPanic/vllm-windows for a deployment on H200 NVL GPUs.

Problem

The vLLM-specific FlashMLA extension uses M_LOG2E in:

csrc/extension/sm90/dense_fp8/softmax.h
csrc/extension/sm90/dense_fp8/pybind.cpp

For example:

const float max_scaled = max(mi) == -INFINITY ? 0.f
                         : max(mi) * (
                               Scale_max ? scale : float(M_LOG2E));

M_LOG2E represents log2(e) and is commonly available in GNU/Linux build environments. Its availability is nevertheless implementation-specific.

With MSVC, the M_* constants are normally exposed only when _USE_MATH_DEFINES is defined before the relevant math header is included. The current source can therefore depend on build flags and translation-unit include order when compiled with NVCC and MSVC.

I understand that native Windows with NVCC and MSVC may not be part of the supported FlashMLA build matrix. However, removing this dependency would be a small cross-platform portability improvement and would not change the existing Linux result.

Tested source-level fix

The FlashMLA extension built successfully after replacing float(M_LOG2E) with the equivalent float literal:

- float(M_LOG2E)
+ 1.4426950408889634f

For the primary file, the tested change was:

diff --git a/csrc/extension/sm90/dense_fp8/softmax.h b/csrc/extension/sm90/dense_fp8/softmax.h
--- a/csrc/extension/sm90/dense_fp8/softmax.h
+++ b/csrc/extension/sm90/dense_fp8/softmax.h
@@
-const float max_scaled = max(mi) == -INFINITY ? 0.f : max(mi) * (Scale_max ? scale : float(M_LOG2E));
+const float max_scaled = max(mi) == -INFINITY ? 0.f : max(mi) * (Scale_max ? scale : 1.4426950408889634f);

The original expression explicitly converts M_LOG2E to a 32-bit float. The replacement literal is also a float because of the f suffix.

Both expressions round to the same IEEE-754 float32 value, so the tested change preserves the numerical result and does not alter the algorithm.

A project-owned named constant could avoid repeating the literal, for example:

inline constexpr float kLog2E = 1.4426950408889634f;

Alternative build-level workaround

The issue can also be avoided in the vLLM CMake integration by defining _USE_MATH_DEFINES for both FlashMLA extension targets:

target_compile_definitions(
    _flashmla_C PRIVATE _USE_MATH_DEFINES=1
)

target_compile_definitions(
    _flashmla_extension_C PRIVATE _USE_MATH_DEFINES=1
)

This is a smaller integration-specific workaround and keeps the existing source unchanged.

Related shared-source occurrences

The same dependency on M_LOG2E also appears in source inherited from deepseek-ai/FlashMLA, including:

csrc/api/dense_decode.h
csrc/sm90/decode/dense/splitkv_mla.cuh
csrc/sm90/decode/sparse_fp8/splitkv_mla.cuh
csrc/smxx/decode/combine/combine.cu
csrc/sm100/prefill/dense/kernel/sm100_fmha_bwd_kernel_tma_warpspecialized.hpp
csrc/sm100/prefill/dense/kernel/sm100_fmha_bwd_mla_kernel_tma_warpspecialized.hpp

Before submitting a new issue...

  • Make sure you already searched for relevant issues, and asked the chatbot living at the bottom right corner of the documentation page, which can answer lots of frequently asked questions.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions