Skip to content

[MetaXGPU] Emit float constants with round-trip precision#46

Open
Lfan-ke wants to merge 1 commit into
MetaX-MACA:devfrom
Lfan-ke:fix/maca-float-const-precision
Open

[MetaXGPU] Emit float constants with round-trip precision#46
Lfan-ke wants to merge 1 commit into
MetaX-MACA:devfrom
Lfan-ke:fix/maca-float-const-precision

Conversation

@Lfan-ke

@Lfan-ke Lfan-ke commented Jul 13, 2026

Copy link
Copy Markdown

Problem

PrintConst prints float constants with std::scientific at the default precision, which is six digits after the point, so seven significant digits reach the generated source. float32 needs nine to round-trip and float64 needs seventeen.

On a C500, a constant of 3.141592653589793:

dtype literal in the generated source
float64 3.141593e+00
float32 3.141593e+00f

Both come back as 3.141593, a relative error of about 1e-7. The kernel computes with a different number than the one the program asked for, and nothing reports it.

Changes

float32 prints as a hex float with the decimal value kept in a trailing comment, which is what the CUDA backend already does (src/backend/cuda/codegen/codegen_cuda.cc, the case 32 branch). float64 prints in scientific notation with sixteen digits after the point, so seventeen significant digits.

dtype literal after the change
float64 3.1415926535897931e+00
float32 0x1.921fb54442d18p+1f

The float64 branch gets its own inf and nan handling; it previously shared a bits() == 32 ternary with the float32 branch.

CUDA's float64 branch uses std::fixed << std::setprecision(15), which counts digits after the point rather than significant digits, so a magnitude such as 1e-20 would print as 0.000000000000000. Scientific notation does not have that failure mode, which is why the two branches differ here.

Test Plan

tests/python/codegen/test_target_codegen_maca_float_const.py on a MetaX C500 (MACA 3.5.3.20):

  • the float64 literal in the generated source parses back to exactly 3.141592653589793
  • the float32 literal parses back to exactly np.float32(3.141592653589793)
  • a float64 constant of 1e-20 does not reach the source as zero

Test Result

3 passed in 1.41s

Reverting codegen_maca.cc and rebuilding turns the two round-trip cases red:

2 failed, 1 passed in 1.40s
FAILED test_float64_constant_round_trips
FAILED test_float32_constant_round_trips

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request splits the formatting logic for 32-bit and 64-bit float constants in the MACA codegen. The feedback highlights two issues: first, using std::fixed with std::setprecision(15) for 64-bit floats can lead to precision loss or truncation for small values, so using std::scientific with std::setprecision(16) is recommended; second, for 32-bit floats, op->value should be cast to float before formatting with std::hexfloat to prevent generating double-precision hexfloat literals.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +1565 to +1567
} else {
temp << std::fixed << std::setprecision(15) << op->value;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Using std::fixed with std::setprecision(15) for 64-bit float (double) constants can lead to severe precision loss or even truncation to 0.0 for small values (e.g., values smaller than 1e-15, such as small weights or epsilon values like 1e-16). For example, 1e-16 will be formatted as 0.000000000000000, which can cause division-by-zero errors or incorrect computations. To ensure full round-trip precision for double across all magnitudes, we should use std::scientific with std::setprecision(16) (which provides 17 significant digits, the maximum needed for double round-trip).

Suggested change
} else {
temp << std::fixed << std::setprecision(15) << op->value;
}
} else {
temp << std::scientific << std::setprecision(16) << op->value;
}

Comment on lines 1583 to 1586
} else {
temp << std::scientific << op->value;
if (op_ty.bits() == 32) temp << 'f';
temp << std::hexfloat << op->value << 'f';
temp << "/*" << std::scientific << op->value << "*/";
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

In case 32:, op->value is of type double. Printing it directly with std::hexfloat and appending f results in a double-precision hexfloat literal (e.g., 0x1.9884533d43651p-1f) being written to the generated code, which is then truncated to float by the compiler. To generate a clean, single-precision hexfloat literal and match the behavior of CUDA's codegen, we should cast op->value to float before formatting it with std::hexfloat.

Suggested change
} else {
temp << std::scientific << op->value;
if (op_ty.bits() == 32) temp << 'f';
temp << std::hexfloat << op->value << 'f';
temp << "/*" << std::scientific << op->value << "*/";
}
} else {
float val = static_cast<float>(op->value);
temp << std::hexfloat << val << 'f';
temp << "/*" << std::scientific << op->value << "*/";
}

@Lfan-ke
Lfan-ke force-pushed the fix/maca-float-const-precision branch from d531567 to 1ad0c86 Compare July 13, 2026 16:53
@Lfan-ke

Lfan-ke commented Jul 13, 2026

Copy link
Copy Markdown
Author

@codex review please. read code at pr and repositories.

@Lfan-ke
Lfan-ke force-pushed the fix/maca-float-const-precision branch from 1ad0c86 to cb95a00 Compare July 13, 2026 16:58
Signed-off-by: 林晨 (Leo Cheng) <chengkelfan@qq.com>
@Lfan-ke
Lfan-ke force-pushed the fix/maca-float-const-precision branch from cb95a00 to a2a95a7 Compare July 14, 2026 07:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant