# tree_d_3d.kernels.fmm_m2l.fmm_m2l_metal

*module*

The Metal version (Apple-silicon GPU, float32) of the ``fmm_m2l`` kernel.

``fmm_m2l_pyccel.py`` next to this file is the CPU version with the same arguments.
One thread per pair adds into zeroed atomic float32 delta arrays (see
:mod:`tree_d_3d.kernels._metal_atomic`); the host adds those to the local expansions in
float64. The shifts sum alternating terms with binomials up to about C(2p, p), so in
float32 the accuracy degrades with the order p (about 1e-4 relative at p = 12); the
per-thread scratch holds orders up to ``TREE_D_3D_MAX_ORDER`` = 64, as on CUDA. The
``inv_re`` and ``inv_im`` scratch arguments of the CPU version are unused.

[View source](https://github.com/max-models/tree-d-3d/blob/devel/src/tree_d_3d/kernels/fmm_m2l/fmm_m2l_metal.py#L1-L1)

## tree_d_3d.kernels.fmm_m2l.fmm_m2l_metal.fmm_m2l

*function*

```python
def fmm_m2l(pairs: Array, count: int, node_center: Array, moment_re: Array, moment_im: Array, binomial: Array, symmetric: int, inv_re: Array, inv_im: Array, local_re: Array, local_im: Array) -> None
```

Add each pair's multipole of one cell to the other's local expansion.

``symmetric`` nonzero truncates by total degree (see the Pyccel version).

[View source](https://github.com/max-models/tree-d-3d/blob/devel/src/tree_d_3d/kernels/fmm_m2l/fmm_m2l_metal.py#L86-L118)
