# Two Machines, Two Answers

*Task 3 of 4 · [Measuring Speed Honestly](https://gpu.rocks/learn/measuring-speed-honestly-b9188894.md) · GPU.js Learn*

JavaScript numbers are 64-bit floats — about 16 significant digits. GPU shaders
compute in **32-bit floats** — about 7. Run the *same* arithmetic on
both machines and the answers drift apart, a little more with every operation.

The kernel below adds 1,000 fractions per thread; a plain JavaScript loop computes the
identical sum in float64. The two results will disagree somewhere around the sixth decimal
place — which means `===` is the wrong question. The right question is:
**are they within a tolerance that matters for your problem?**

## Goal

**Goal:** finish the kernel — each thread sums
`1 / (k + this.thread.x)` for `k = 1…1000` — then fix the final
comparison to use a tolerance instead of `===`.

## Requirements

- Kernel: accumulate `1 / (k + this.thread.x)` over `k = 1…1000` in a loop
- Keep the float64 reference sum for thread 0 (already wired up)
- Log the verdict with a tolerance: `Math.abs(result[0] - ref) < 1e-3`, not `===`

## Hint 1 — loops inside kernels

Fixed-bound loops are fine in kernel code:

```js
for (let k = 1; k <= 1000; k++) {
  sum += 1 / (k + this.thread.x);
}
```

## Hint 2 — the tolerant verdict

Replace the `===` comparison in the last line with
`Math.abs(result[0] - ref) < 1e-3`. Exact equality across float32 and
float64 is a coin you will almost never win.

## Same idea elsewhere

float32-by-default is universal shader behavior — and production GPU code often
trades away *more* precision on purpose: CUDA's `--use_fast_math`, TF32
on tensor cores, half-precision inference. That's why numerical toolkits ship
`allclose`-style comparisons, and why this course's tests use
`assertClose` instead of `==`.

## Starter code

```js
// Same math, two machines: your GPU adds in float32, JavaScript in float64.
const gpu = new GPU({ mode });

const partialSums = gpu.createKernel(function () {
  let sum = 0;
  // TODO: add up 1 / (k + this.thread.x) for k = 1 ... 1000
  sum = 1 / (1 + this.thread.x);
  return sum;
}, { output: [64] });

const result = await partialSums();

// The same sum for thread 0, computed in float64 JavaScript:
let ref = 0;
for (let k = 1; k <= 1000; k++) ref += 1 / k;

console.log('kernel says:', result[0]);
console.log('js says:    ', ref);
console.log('difference:', Math.abs(result[0] - ref));
// TODO: '===' is the wrong question — compare with a tolerance instead:
console.log('close enough:', result[0] === ref);
```

---

Interactive version: https://gpu.rocks/learn/measuring-speed-honestly-b9188894/3

[Previous task](https://gpu.rocks/learn/measuring-speed-honestly-b9188894/2.md) · [Next task](https://gpu.rocks/learn/measuring-speed-honestly-b9188894/4.md)
