# tree_d_3d.kernels.fmm_traverse.fmm_traverse_metal

*module*

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

``fmm_traverse_pyccel.py`` next to this file is the CPU version with the same
arguments. The GPU classifies every pair of the frontier in float32 (one thread per
pair: skip, near-field pair, far-field pair, split a, split b, or split a node with
itself). The Apple GPU has no 64-bit atomics for ``counts``, so the host appends the
pairs to ``m2l``, ``p2p`` and ``next_frontier`` from those codes, with the same
semantics as the CPU: appended in pair order (so the lists are identical to the CPU's
unless a pair is within float32 rounding of the ``theta`` criterion), ``counts``
holding the sizes needed, ``counts[3] = -1`` if a buffer is too small.

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

## tree_d_3d.kernels.fmm_traverse.fmm_traverse_metal.fmm_traverse

*function*

```python
def fmm_traverse(node_center: Array, node_half: Array, node_start: Array, node_end: Array, node_child: Array, theta: float, frontier: Array, n_frontier: int, next_frontier: Array, m2l: Array, p2p: Array, counts: Array) -> None
```

One generation of the dual-tree traversal, which fills mutual M2L and P2P lists.

[View source](https://github.com/max-models/tree-d-3d/blob/devel/src/tree_d_3d/kernels/fmm_traverse/fmm_traverse_metal.py#L75-L147)
