es-ude / es-ude/OnDeviceTraining

build: FP contraction diverges host vs MCU — decide global -ffp-contract policy

Open
#349 0 comments 0 reactions 0 assignees View on GitHub
enhancement
Dominant language
C
Stars
1
Forks
3
Avg merge
1d 1h
Merged PRs (30d)
8

Description

## Verified finding (2026-07-13)

GCC **ignores** `#pragma STDC FP_CONTRACT` (long-standing, gcc PR 20785). Empirically verified against our toolchain: arm-none-eabi-gcc 10.3 at `-O2 -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16` emits `vfma.f32` for `acc + x[i]*y[i]` loops and `a + t*c` expressions **despite** the pragma at the top of the TU; `-ffp-contract=off` eliminates all fused ops (2 → 0 in the probe).

## Why this is invisible today — and why it bites at hardware bring-up

- x86-64 CI **cannot** contract: the baseline ISA has no FMA instruction without `-mfma`, so GCC's default `-ffp-contract=fast` has nothing to fuse. All host tests stay green.
- The `c-arm-cross-compile` job is compile-only — it never runs a test.
- Cortex-M4F/M7 have VFMA. Every MAC loop in the framework (Conv1d kernels, Matmul, Sum, the funnel epilogues, the upcoming PointwiseFused primitives) will round **differently on the MCU than on the host** under the default flags.

Consequence: the entire host-validated bit-trajectory story (bit-parity examples, gold suites, #300 sweeps) does **not** transfer to on-device runs. The divergence surfaces only when real hardware training is compared against host references — with no obvious cause.

## Decision needed (options)

1. **Global `-ffp-contract=off`** for all framework libs (and the arm toolchain file): determinism host==MCU, measurable slowdown on M4F/M7 (every MAC pays separate mul+add).
2. **Documented divergence**: keep `fast` on ARM for speed, declare host↔MCU bit-parity out of scope (float-twin = sanity, not gate — consistent with the memory-over-accuracy vision, but weakens every future on-device debugging session).
3. **Per-lib policy**: `off` where rounding order is a documented contract (PointwiseFused does this already — see the PR-B plan), `fast` for throughput-critical kernels, with the divergence stated in docs/conventions.

Option 3 is the pragmatic start; the real decision point is first hardware bring-up.

## Precedent

The PR-B plan (`PointwiseFused`) already binds `target_compile_options( PRIVATE -ffp-contract=off)` per-lib and demotes the pragma to documentation/Clang-backup — that is the template for whichever scope is chosen.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Contributor guide

Open the contributing guide

Research direction

Start by reading the PR-B PointwiseFused plan and the ARM toolchain file, then review the existing c-arm-cross-compile job and its FP contraction probe. Compare the three proposed scopes; done means the project has a chosen -ffp-contract policy, matching build settings, and documented host-versus-MCU rounding expectations.

Written by the indexing model from the issue text.

Assessment

Tech stack
c, cmake
Domain
build-system, embedded-iot, performance
Issue type
Refactor
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.