# IteraGPU Lab v1

Original resources, version of September 24, 2026, for preparing a reproducible GPU experiment. The memory notebook and its companion run a small synthetic network `Linear → GELU → Linear`. They do not download any model or dataset. This network is neither an LLM, nor a training run, nor a benchmark representative of the GPUs offered for rent.

## Contents

- `mesure-memoire.ipynb`: standalone notebook, code included, cells with no saved outputs.
- `mesure_memoire.py`: same arithmetic and same measurement protocol, usable from the command line.
- `protocole-qualite.md`: business protocol to be completed before comparing time and cost.
- `resultats-bruts.csv`: blank grid, one row to fill in per actual run.
- `calcul_forfaits.py`: full package calculation, with no external dependency.
- `tarifs-forfaits.csv`: 45 IteraGPU rates, 15 models × 3 durations, snapshot of September 24, 2026.
- `LICENSE.txt`: MIT license for the code, the notebook and the original documents.
- `MANIFEST.json`: exhaustive list of the nine archive members, sizes and SHA-256 of the eight content files. The manifest declares itself without a hash in order to avoid a self-referential hash.

The `iteragpu-lab-v1.zip` archive contains these nine files under a single folder. It contains no GPU result, no Python environment, no driver and no credentials. Extract the files into a fresh directory. The notebook can also be downloaded on its own: it does not import the companion script.

## Prerequisites and limitations

The arithmetic and package calculations use only Python 3.10 or later and its standard library. The notebook requires a tool capable of opening a Python notebook; no Jupyter server is provided. Measurement additionally requires an existing PyTorch installation compatible with the GPU, the driver and its CUDA or ROCm runtime. No command in the folder installs these components.

Choose an explicit device, for example `cuda:0`. PyTorch's ROCm backend also reuses this interface name; that does not prove the compatibility of a particular AMD installation. Without a loadable PyTorch or an accessible GPU, `measure` exits with code 2 and a clear message. It writes no fake measurement and does not fall back to the CPU. `environment` is a diagnostic: valid output may report a GPU as unavailable.

## 1. Estimate weights, without a GPU

```console
python mesure_memoire.py estimate --parameters 7000000000 --bits 16 --reserve-gib 4
```

This calculation takes a number of parameters and a storage width. It rounds bits up to the next whole number of bytes, then converts to GiB (`2**30` bytes). A decimal GB represents `10**9` bytes. The 4 GiB is a hypothesis chosen in this example, not a measured reserve. The result does not automatically include activations, KV cache, quantization metadata, gradients, optimizer states or libraries. It does not predict whether a real model fits on a card.

## 2. Check the existing environment

```console
python mesure_memoire.py environment --device cuda:0
```

Retain Python, PyTorch version, CUDA/HIP build version, the GPU actually visible and the memory reported by the runtime. The driver must be recorded separately with the vendor's tool. The script collects neither environment variables nor personal data. The version of the runtime embedded in PyTorch is not the driver version.

## 3. Perform an explicitly bounded measurement

Start small, in a fresh process:

```console
python mesure_memoire.py measure --device cuda:0 --batch 1 --context 16 --width 64 --dtype float32 --warmup 1 --repeats 2 --output mesures-petit-essai.json
```

To then explore the MLP dimensions, an example of a larger command is:

```console
python mesure_memoire.py measure --device cuda:0 --batch 2 --context 128 --width 1024 --dtype float32 --warmup 3 --repeats 5 --output mesures.json
```

Increase one dimension at a time and monitor available memory. The second command is a proposed configuration, not a guaranteed capacity or a published result. `context` here means the number of positions in the input `[batch, context, width]`, without an attention mechanism or KV cache. Weights and inputs share the requested dtype; no autocast, gradients, optimizer, quantization, or distribution across GPUs. `float16` and `bfloat16` depend on the actual installation and are not validated by a float32 run alone.

The JSON contains `environment`, `configuration`, `synthetic_model`, and `phases`. The file must have a new name; the script refuses to overwrite an existing result.

| Phase | Scope |
| --- | --- |
| `model_load` | Construction and CPU initialization of the model, transfer to the chosen GPU. The time includes this CPU preparation; memory counters cover only the GPU. |
| `inputs` | Creation of synthetic inputs on that GPU. |
| `cold_forward` | First pass of the model after initializing the device, generator, and inputs. This is not a cold start of the machine or driver. |
| `warmup` | Set of warmup passes; this time is not mixed with the following repetitions. |
| `warm_forward` | One row per repetition after warmup. |

Each phase synchronizes the device before and after the operation, records baselines, then resets peaks. Outputs are still present at the end-of-phase reading; they are freed before the next pass. Weights and inputs persist between passes. The allocator cache is retained. Times include Python overhead and synchronization: these are not isolated kernel times.

`allocated` is part of `reserved`, so they are not added together. `peak_allocated_bytes` and `peak_reserved_bytes` are two distinct maxima: they are not subtracted to compute a cache. Compare baselines, ends, and absolute peaks separately. The counters cover only the PyTorch allocator of this process on the chosen GPU, not all GPU memory, the driver, or other processes. Any other GPU is not measured. Values also depend on the allocator and software: keep the environment with the results.

## 4. Linking quality and cost

Read `protocole-qualite.md`, set the useful work and the threshold before the run, then fill `resultats-bruts.csv` with the actual observations. This bundle provides no classification corpus or quality measurement.

```console
python calcul_forfaits.py --gpu b200 --days 7 --lots 2
```

The price of a B200 lot already includes two GPUs. Two lots give four GPUs, but the lot price is multiplied by only two. The rates are those of the IteraGPU catalog on the day of this snapshot: whole units in USD cents, durations of 3, 7, or 30 days, with no conversion or hourly proration. The CSV proves neither current availability nor reservation. Check the displayed offer before any purchase decision.

The `--accepted-results` option intentionally has no default value. Add it only with the positive integer number of distinct useful units actually accepted. The unit cost uses the price of the whole package. Repetitions of the same benchmark are not new useful corpora. Without a denominator provided, the unit cost remains `null`; zero is rejected.

## Validation of this version

The arithmetic, rates, and absence of pre-filled outputs are verified with Python 3.12.14 and its standard library. This environment does not contain PyTorch: the absence guard is therefore actually tested. No installation was performed.

A bounded functional run was also executed on September 24, 2026 on a **local GeForce RTX 5070**, driver 610.62, Python 3.14.6, PyTorch 2.11.0+cu128, CUDA 12.8: batch 1, context 16, width 64, float32, one warmup and two repetitions. It validates the execution of the script's six phase rows on this single case. It validates neither the performance of the catalog GPUs, nor a rented machine, nor an LLM, nor ROCm, nor the other precisions. The measurements from this run are not pre-filled in the distributed files. The notebook keeps all its outputs empty.

## Primary technical sources

Documentation consulted on September 24, 2026. These references explain the APIs; the PyTorch version actually executed is given above, distinct from that of the documentation pages.

- [PyTorch: CUDA memory management](https://docs.pytorch.org/docs/2.14/notes/cuda.html#memory-management)
- [PyTorch: HIP/ROCm semantics](https://docs.pytorch.org/docs/2.14/notes/hip.html)
- [PyTorch: device synchronization](https://docs.pytorch.org/docs/2.14/generated/torch.cuda.synchronize.html)
- [PyTorch: resetting peak stats](https://docs.pytorch.org/docs/2.14/generated/torch.cuda.memory.reset_peak_memory_stats.html)
- [PyTorch: allocated memory](https://docs.pytorch.org/docs/2.14/generated/torch.cuda.memory.memory_allocated.html) and [reserved memory](https://docs.pytorch.org/docs/2.14/generated/torch.cuda.memory.memory_reserved.html)
- [PyTorch: max allocated](https://docs.pytorch.org/docs/2.14/generated/torch.cuda.memory.max_memory_allocated.html) and [max reserved](https://docs.pytorch.org/docs/2.14/generated/torch.cuda.memory.max_memory_reserved.html)
- [Python: decimal arithmetic](https://docs.python.org/3/library/decimal.html) and [CSV files](https://docs.python.org/3/library/csv.html)

## License

The original creations in this folder are distributed under the MIT license, reproduced in `LICENSE.txt`. Keep the notice when redistributing. Python, PyTorch, and the other tools mentioned are not distributed with the archive and retain their respective licenses.
