# The Laplacian: Ask Your Neighbors

*Task 1 of 4 · [Reaction–Diffusion](https://gpu.rocks/learn/reaction-diffusion-bc3d0b34.md) · GPU.js Learn*

Diffusion is gossip: every cell drifts toward the average of its neighbors.
The operator that measures "how far am I from my neighbors' average" is the
**Laplacian**, and on a grid it's a five-read gather:
`left + right + up + down − 4·center`. Positive means the neighbors are
higher and stuff will flow in; negative means it flows out.

One wrinkle: simulations hate edges. Instead of clamping like the filters in
**Convolution & Filters**, we **wrap around** — the left neighbor of column 0 is
column 31. The world becomes a torus and every cell has exactly four neighbors,
no special cases.

## Figures

- **five reads, one number — how far am i from my neighbors' average?**

## Goal

**Goal:** complete the gather kernel so it returns the 5-point
Laplacian of `field` with wrap-around edges.

## Requirements

- Wrap all four neighbor indexes — below `0` becomes `size − 1`, past `size − 1` becomes `0`
- Read exactly five cells: the four direct neighbors and the center
- Return `left + right + up + down − 4·center`

## Hint 1 — the wrap is an if

Same trick as clamping, different else:

```js
let xr = this.thread.x + 1;
if (xr > this.constants.size - 1) xr = 0;
```

The starter already wrote `xl` for you — mirror it three times.

## Hint 2 — five reads

The neighbors sit at `field[y][xl]`, `field[y][xr]`,
`field[yd][x]` and `field[yu][x]` — only ever vary
*one* coordinate at a time. The center is `field[y][x]`.

## Hint 3 — the whole return

```js
return field[y][xl] + field[y][xr] + field[yd][x]
  + field[yu][x] - 4 * field[y][x];
```

## Same idea elsewhere

The 5-point Laplacian stencil is the beating heart of PDE solvers on every
platform — heat, waves, pressure projection in fluids. On big CUDA/ROCm clusters the
wrap you just wrote becomes a *halo exchange*: each GPU ships its border rows to
the neighbor that needs them before every step.

## Starter code

```js
// The Laplacian: how far is each cell from its neighbors' average?
// The world is a torus — indexes wrap around the edges.
const gpu = new GPU({ mode });

const laplacian = gpu.createKernel(function (field) {
  const x = this.thread.x;
  const y = this.thread.y;
  let xl = x - 1;
  if (xl < 0) xl = this.constants.size - 1;
  // TODO: wrap xr (right), yu (up) and yd (down) the same way,
  // then return left + right + up + down - 4 * center.
  return 0;
}, { output: [32, 32], constants: { size: 32 } });

const result = await laplacian(field);
console.log('at a bump:', result[16][16]);
```

---

Interactive version: https://gpu.rocks/learn/reaction-diffusion-bc3d0b34/1

[Next task](https://gpu.rocks/learn/reaction-diffusion-bc3d0b34/2.md)
