Skip to content

Metal backend returns float32 while every other backend returns float64 #303

Description

@Ramdam17

The output dtype depends on which backend ran, and therefore on the hardware:

  metric    backend   dtype
  ---------------------------
  pli       metal     float32
  wpli      metal     float32
  accorr    metal     float32
  <all>     numpy     float64
  <all>     numba     float64
  <all>     cuda      float64

run_pairwise_kernel reads the result back as np.float32 (hypyp/sync/kernels/_metal_dispatch.py:163, and identically metal_accorr.py:193), and returns it unchanged. _cuda_dispatch.py is float64 throughout (documented at :40), as are the numpy and numba paths.

Consequences:

  • The same script on an Apple Silicon machine and on a Linux/CUDA machine writes result files of different dtype, which is a reproducibility wart in saved derivatives.
  • Downstream concatenation or stacking silently upcasts, so the precision loss is invisible.
  • BaseMetric.compute's docstring documents the return shape but says nothing about dtype, so there is no stated contract to rely on.

Note the float32 kernels themselves are accurate — measured max absolute deviation vs the float64 NumPy reference is 7.6e-09 (pli), 6.9e-08 (wpli), 5.2e-08 (accorr). The issue is only the inconsistent output contract.

Suggested fix: either cast the Metal result to float64 before returning (cheap, makes the contract uniform) or document the dtype per backend in BaseMetric.compute and sync/README.md. The first option is preferable — a backend switch should not change the dtype of a scientific result.

Activity

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