Phase 19 / TPU Setup: Provisioning & Runtime Verification
Bootstrap .venv and verify a TPU runtime receipt
Revision v0.7.0 · Updated since your last visit. Review the changes; your progress is saved.
Lesson · about 20 minutes · CPU practice
Create ~/jax-tpu-lab/.venv on the TPU VM, install jax[tpu], run a synchronized pmap runtime contract check, and download the signed JSON receipt before deleting the VM.
Phase study guide: preparation, milestones and project evidence
Before you start
Before this: Select a TPU slice and provision your Cloud TPU VM
Hardware: CPU contract verifier; Cloud TPU VM or Colab TPU for target receipt
Setup help: Python, notebook, or Cloud TPU VM
Use the tested CPU packages (the recorded environment uses Python 3.14.3). Other Python versions and accelerator environments require separate checks. The optional Cloud TPU specialization explains the target-specific execution boundaries. Logical CPU devices practice partitioning; they do not simulate TPU performance.
Download the repository ZIP or use your existing checkout. Extract it and open a terminal in the folder containing requirements-cpu.txt. The beginner ZIP is separate; these lessons use the full repository folder.
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements-cpu.txtpy -3 -m venv .venv
.\.venv\Scripts\python.exe -m pip install -r requirements-cpu.txtAfter activation, run the complete worked example from that same folder:
python phases/19-tpu/02-bootstrap-venv-and-verify-tpu-runtime-receipt/code/main.py.\.venv\Scripts\python.exe phases/19-tpu/02-bootstrap-venv-and-verify-tpu-runtime-receipt/code/main.pyFor an incremental build, create main.py in your own practice folder, append each build block in order, and run python main.py with this environment active. Keep that file separate from the downloaded reference solution.
Download this lesson’s notebook. Open it with a Python kernel using the course environment. Run cells from the top after restarting the kernel; experiments depend on earlier definitions.
For local Jupyter, first install the course requirements using the Local Python steps, then use your environment’s Python to start Jupyter:
python -m pip install jupyterlab
python -m jupyter lab.\.venv\Scripts\python.exe -m pip install jupyterlab
.\.venv\Scripts\python.exe -m jupyter labSelect the downloaded tpu-04.ipynb file in JupyterLab. The notebook contains reference solutions; make your prediction and attempt each practice task before opening them. Restart the kernel before changing logical device setup.
The worked reference for this lesson is CPU-validated. Some references explicitly configure logical CPU devices; setting JAX_PLATFORMS does not adapt them to a TPU. Follow the execution matrix and reviewed multi-host example before attempting a target run.
For accelerator preparation, study TPU setup, observed runtime receipts, checkpointed jobs and precision and retained traces. These target paths remain unqualified on physical TPU hardware until an actual receipt is recorded. Cloud provisioning is optional for CPU learning.
Check: Prints the verified JSON runtime receipt (observed_total: 140.0 on 1 device) and the expected pmap sums for 1-device (140.0), 4-device (10416.0), and 8-device (85344.0) slices.
Revisit the guided CPU setup · Open 19: TPU Setup. Package instructions are CPU instructions; Windows and accelerator environments need their own validation.
What you will be able to do
- Bootstrap
~/jax-tpu-lab/.venvon a Cloud TPU VM and installjax[tpu]from the officiallibtpuwheel index. - Verify
jax.default_backend(),jax.device_count(), and a synchronizedjax.pmapreduction across 1, 4, or 8 chips. - Copy the JSON runtime receipt back to your workstation with
gcloud compute tpus tpu-vm scp. - Delete the Cloud TPU VM and confirm with
gcloud compute tpus tpu-vm listthat zero billable TPU nodes remain.
The problem
After gcloud compute tpus tpu-vm create reports READY, you still cannot trust a benchmark or training job until Python inside your TPU VM's .venv proves it can load libtpu, see all attached TPU chips, execute a synchronized collective across them, and tear down cleanly so nothing keeps billing.
The idea
Bootstrap an isolated ~/jax-tpu-lab/.venv on the TPU VM Linux host with jax[tpu], run a deterministic jax.pmap runtime receipt across all local chips, copy the receipt back to your laptop with gcloud compute tpus tpu-vm scp, and delete the TPU VM (tpu-vm delete + tpu-vm list) whenever your session ends.
Why a synchronized pmap receipt is stronger than import jax
Importing jax on a Cloud TPU VM only proves that the Python package is installed on the Linux host. To prove that libtpu can initialize the attached TPU chips, allocate High Bandwidth Memory (HBM), compile an XLA HLO computation, and synchronize results back to the host, you should run a small jax.pmap reduction across jax.local_devices() and call jax.block_until_ready.
If each device receives a slice of consecutive integers starting at , then across devices the global vector contains , and the exact sum of squares is:
The formula gives an expected value for a chosen device count. Only a receipt that records observed_backend, device_count, and the synchronized result can support a runtime claim. The four-row figure below is a NumPy calculation, not evidence that four TPU devices ran.
1. Bootstrap ~/jax-tpu-lab/.venv and install jax[tpu] over SSH
Use gcloud compute tpus tpu-vm ssh to create a dedicated virtual environment on the TPU VM host and install jax[tpu] plus the course libraries (flax, optax, orbax-checkpoint, numpy, matplotlib).
Create ~/jax-tpu-lab/.venv and install jax[tpu] on the Cloud TPU VM
# Create ~/jax-tpu-lab/.venv and install jax[tpu] on the Cloud TPU VM
gcloud compute tpus tpu-vm ssh "$TPU_NAME" --zone="$ZONE" --command="
set -euo pipefail
mkdir -p ~/jax-tpu-lab
python3 -m venv ~/jax-tpu-lab/.venv
source ~/jax-tpu-lab/.venv/bin/activate
pip install -U pip
pip install 'jax[tpu]' -f https://storage.googleapis.com/jax-releases/libtpu_releases.html
pip install flax optax orbax-checkpoint numpy matplotlib
"Expected:
Installs jax[tpu], libtpu, and the course dependencies inside ~/jax-tpu-lab/.venv on the TPU VM.
2. Run the runtime receipt script, copy the JSON receipt back, and delete the TPU VM
Stage public/exercises/tpu-04.py to the TPU VM, run it inside ~/jax-tpu-lab/.venv, copy the saved receipt back to your workstation, and delete the TPU VM when finished.
Run the runtime receipt verifier on the TPU VM and copy the receipt home
# Run the runtime receipt verifier on the TPU VM and copy the receipt home
gcloud compute tpus tpu-vm scp public/exercises/tpu-04.py "$TPU_NAME":~/jax-tpu-lab/ --zone="$ZONE"
gcloud compute tpus tpu-vm ssh "$TPU_NAME" --zone="$ZONE" \
--command="JAX_PLATFORMS=tpu ~/jax-tpu-lab/.venv/bin/python ~/jax-tpu-lab/tpu-04.py | tee ~/jax-tpu-lab/tpu-receipt.txt"
gcloud compute tpus tpu-vm scp "$TPU_NAME":~/jax-tpu-lab/tpu-receipt.txt ./ --zone="$ZONE"Expected:
Runs tpu-04.py on the TPU VM, writes tpu-receipt.txt, and downloads it to your current directory.
Delete the Cloud TPU VM and verify zero active TPU resources remain
# Delete the Cloud TPU VM and verify zero active TPU resources remain
gcloud compute tpus tpu-vm delete "$TPU_NAME" --zone="$ZONE" --quiet
gcloud compute tpus tpu-vm list --zone="$ZONE"Expected:
Deletes the TPU VM and prints Listed 0 items.
Calculated expectation for four devices (not an observed runtime receipt)
Predict before looking: If four devices each sum a distinct block of eight integers, what cumulative sum of squares should the verifier report?
Read the figure
This analytic illustration computes four eight-value row sums with NumPy. It does not read a TPU execution receipt and does not show observed device participation.
Connect it to the computation
The calculated total is 10416. A runtime claim must instead use the device count and per-device values in a saved receipt; the current local receipt records one CPU device.
Open full-size figureDownload data and provenance
This figure is a calculated expectation. It does not report device execution.
Where to put & run this code: Work in phases/19-tpu/02-bootstrap-venv-and-verify-tpu-runtime-receipt/code/main.py (or downloaded exercises/tpu-04.py / exercises/tpu-04.ipynb) and execute from the repository root with python3 phases/19-tpu/02-bootstrap-venv-and-verify-tpu-runtime-receipt/code/main.py.
1 Define the closed-form sum-of-squares oracle and pmap receipt builder
Create main.py with closed_form_sum_of_squares and build_runtime_receipt.
# Step 1 — Define the closed-form sum-of-squares oracle and pmap receipt builder: Each local device computes the sum of squares of its 8-element row...
# Import hashlib for this computation.
import hashlib
import json
import platform
import jax
import jax.numpy as jnp
import numpy as np
# Function `closed_form_sum_of_squares(num_devices, width)` implementing this stage's computation:
def closed_form_sum_of_squares(num_devices, width=8):
# Evaluate `num_devices) * int(width` and convert the result into Python scalar/collection `n`.
n = int(num_devices) * int(width)
# Return `float((n - 1) * n * (2 * n - 1) // 6)` to the caller.
return float((n - 1) * n * (2 * n - 1) // 6)
# Function `build_runtime_receipt()` implementing this stage's computation:
def build_runtime_receipt():
# Query the active JAX devices into `devices`.
devices = jax.local_devices()
# Run `len` to compute `n_dev`.
n_dev = len(devices)
# Construct and reshape `x` into the target tensor dimensions.
x = jnp.arange(n_dev * 8, dtype=jnp.float32).reshape(n_dev, 8)
# Reduce across the target axis to summarize `per_device`.
per_device = jax.pmap(lambda row: jnp.sum(row * row))(x)
# Synchronize host execution until asynchronous device computation completes.
observed_total = float(jax.block_until_ready(jnp.sum(per_device)))
# Run `closed_form_sum_of_squares` to compute `expected_total`.
expected_total = closed_form_sum_of_squares(n_dev, 8)
# Check which hardware backend (`cpu`, `gpu`, or `tpu`) JAX selected for `payload`.
payload = {
"python": platform.python_version(),
"jax": jax.__version__,
"backend": jax.default_backend(),
"local_device_count": n_dev,
"per_device_sums": [float(v) for v in np.asarray(per_device)],
"observed_total": observed_total,
"expected_total": expected_total,
"verified": bool(np.isclose(observed_total, expected_total)),
}
# Read or serialize artifact data on disk (`payload['receipt_sha256']`).
payload["receipt_sha256"] = hashlib.sha256(
json.dumps(payload, sort_keys=True, separators=(",", ":")).encode()
).hexdigest()[:16]
# Return `payload` to the caller.
return payloadCode building blocks in this step
jnp.arange(n, dtype=...)— Creates a 1-D JAX array of evenly spaced values[0, 1, ..., n-1]on the target device.array.reshape(new_shape)— Reorganizes tensor axes without changing the total element count (array.size).x.sum(axis=...) / x.mean(axis=..., keepdims=...)— Reduces values along the namedaxis(the axis you name is collapsed unlesskeepdims=True).Mesh + PartitionSpec + NamedSharding— Maps logical tensor axes onto physical device mesh axes for SPMD data, tensor, or pipeline parallelism.
Each local device computes the sum of squares of its 8-element row via jax.pmap, and the host verifies the synchronized total against the exact polynomial identity.
2 Verify the active runtime receipt and tabulate multi-chip expectations
Append slice_expectations and the receipt verification assertions to main.py.
# Step 2 — Verify the active runtime receipt and tabulate multi-chip expectations: Knowing the exact expected sum for 1, 4, and 8 devices lets you...
slice_expectations = [
{"slice": "1-device (CPU / v5e-1)", "devices": 1, "expected_sum": closed_form_sum_of_squares(1)},
{"slice": "4-device (v5litepod-4 / v6e-4)", "devices": 4, "expected_sum": closed_form_sum_of_squares(4)},
{"slice": "8-device (v5litepod-8 / v6e-8)", "devices": 8, "expected_sum": closed_form_sum_of_squares(8)},
]
# Run `build_runtime_receipt` to compute `receipt`.
receipt = build_runtime_receipt()
# Assert invariant `receipt["verified"] is True` holds
assert receipt["verified"] is True
# Print the observed values to compare against the expected result.
print("Runtime receipt:", json.dumps(receipt, sort_keys=True))
# Print diagnostic summary of the computed outputs.
print("Expected pmap sums by slice:", {s["slice"]: s["expected_sum"] for s in slice_expectations})Code building blocks in this step
Mesh + PartitionSpec + NamedSharding— Maps logical tensor axes onto physical device mesh axes for SPMD data, tensor, or pipeline parallelism.
Knowing the exact expected sum for 1, 4, and 8 devices lets you immediately spot if a 4-chip or 8-chip TPU VM only initialized a single device.
3 Step 3: Verify invariants on the completed state
Run the final shape and numerical assertions to confirm the state built in Steps 1 and 2.
receipt = build_runtime_receipt()
assert receipt["verified"] is TrueCode building blocks in this step
build_runtime_receipt(...)— Callbuild_runtime_receiptwith your updated parameters or inputs from this lesson's workspace.assert condition— Verify that the observed output shape, status, or numerical value satisfies the contract.
Checking these invariants confirms the computation is ready for the full worked experiment.
View the cumulative build in main.py
These blocks append in order to the same file.
# Step 1 — Define the closed-form sum-of-squares oracle and pmap receipt builder: Each local device computes the sum of squares of its 8-element row...
# Import hashlib for this computation.
import hashlib
import json
import platform
import jax
import jax.numpy as jnp
import numpy as np
# Function `closed_form_sum_of_squares(num_devices, width)` implementing this stage's computation:
def closed_form_sum_of_squares(num_devices, width=8):
# Evaluate `num_devices) * int(width` and convert the result into Python scalar/collection `n`.
n = int(num_devices) * int(width)
# Return `float((n - 1) * n * (2 * n - 1) // 6)` to the caller.
return float((n - 1) * n * (2 * n - 1) // 6)
# Function `build_runtime_receipt()` implementing this stage's computation:
def build_runtime_receipt():
# Query the active JAX devices into `devices`.
devices = jax.local_devices()
# Run `len` to compute `n_dev`.
n_dev = len(devices)
# Construct and reshape `x` into the target tensor dimensions.
x = jnp.arange(n_dev * 8, dtype=jnp.float32).reshape(n_dev, 8)
# Reduce across the target axis to summarize `per_device`.
per_device = jax.pmap(lambda row: jnp.sum(row * row))(x)
# Synchronize host execution until asynchronous device computation completes.
observed_total = float(jax.block_until_ready(jnp.sum(per_device)))
# Run `closed_form_sum_of_squares` to compute `expected_total`.
expected_total = closed_form_sum_of_squares(n_dev, 8)
# Check which hardware backend (`cpu`, `gpu`, or `tpu`) JAX selected for `payload`.
payload = {
"python": platform.python_version(),
"jax": jax.__version__,
"backend": jax.default_backend(),
"local_device_count": n_dev,
"per_device_sums": [float(v) for v in np.asarray(per_device)],
"observed_total": observed_total,
"expected_total": expected_total,
"verified": bool(np.isclose(observed_total, expected_total)),
}
# Read or serialize artifact data on disk (`payload['receipt_sha256']`).
payload["receipt_sha256"] = hashlib.sha256(
json.dumps(payload, sort_keys=True, separators=(",", ":")).encode()
).hexdigest()[:16]
# Return `payload` to the caller.
return payload
# Step 2 — Verify the active runtime receipt and tabulate multi-chip expectations: Knowing the exact expected sum for 1, 4, and 8 devices lets you...
slice_expectations = [
{"slice": "1-device (CPU / v5e-1)", "devices": 1, "expected_sum": closed_form_sum_of_squares(1)},
{"slice": "4-device (v5litepod-4 / v6e-4)", "devices": 4, "expected_sum": closed_form_sum_of_squares(4)},
{"slice": "8-device (v5litepod-8 / v6e-8)", "devices": 8, "expected_sum": closed_form_sum_of_squares(8)},
]
# Run `build_runtime_receipt` to compute `receipt`.
receipt = build_runtime_receipt()
# Assert invariant `receipt["verified"] is True` holds
assert receipt["verified"] is True
# Print the observed values to compare against the expected result.
print("Runtime receipt:", json.dumps(receipt, sort_keys=True))
# Print diagnostic summary of the computed outputs.
print("Expected pmap sums by slice:", {s["slice"]: s["expected_sum"] for s in slice_expectations})
receipt = build_runtime_receipt()
assert receipt["verified"] is TrueRun the example
python3 phases/19-tpu/02-bootstrap-venv-and-verify-tpu-runtime-receipt/code/main.pyAbout this command
This shortcut uses an activated macOS/Linux course environment in the repository folder. For Windows, use the explicit interpreter command in “Setup help” above. The script includes worked examples and reference solutions.
Inspect the complete assembled example
# Step 1 — Define the closed-form sum-of-squares oracle and pmap receipt builder: Each local device computes the sum of squares of its 8-element row...
# Import hashlib for this computation.
import hashlib
import json
import platform
import jax
import jax.numpy as jnp
import numpy as np
# Function `closed_form_sum_of_squares(num_devices, width)` implementing this stage's computation:
def closed_form_sum_of_squares(num_devices, width=8):
# Evaluate `num_devices) * int(width` and convert the result into Python scalar/collection `n`.
n = int(num_devices) * int(width)
# Return `float((n - 1) * n * (2 * n - 1) // 6)` to the caller.
return float((n - 1) * n * (2 * n - 1) // 6)
# Function `build_runtime_receipt()` implementing this stage's computation:
def build_runtime_receipt():
# Query the active JAX devices into `devices`.
devices = jax.local_devices()
# Run `len` to compute `n_dev`.
n_dev = len(devices)
# Construct and reshape `x` into the target tensor dimensions.
x = jnp.arange(n_dev * 8, dtype=jnp.float32).reshape(n_dev, 8)
# Reduce across the target axis to summarize `per_device`.
per_device = jax.pmap(lambda row: jnp.sum(row * row))(x)
# Synchronize host execution until asynchronous device computation completes.
observed_total = float(jax.block_until_ready(jnp.sum(per_device)))
# Run `closed_form_sum_of_squares` to compute `expected_total`.
expected_total = closed_form_sum_of_squares(n_dev, 8)
# Check which hardware backend (`cpu`, `gpu`, or `tpu`) JAX selected for `payload`.
payload = {
"python": platform.python_version(),
"jax": jax.__version__,
"backend": jax.default_backend(),
"local_device_count": n_dev,
"per_device_sums": [float(v) for v in np.asarray(per_device)],
"observed_total": observed_total,
"expected_total": expected_total,
"verified": bool(np.isclose(observed_total, expected_total)),
}
# Read or serialize artifact data on disk (`payload['receipt_sha256']`).
payload["receipt_sha256"] = hashlib.sha256(
json.dumps(payload, sort_keys=True, separators=(",", ":")).encode()
).hexdigest()[:16]
# Return `payload` to the caller.
return payload
# Step 2 — Verify the active runtime receipt and tabulate multi-chip expectations: Knowing the exact expected sum for 1, 4, and 8 devices lets you...
slice_expectations = [
{"slice": "1-device (CPU / v5e-1)", "devices": 1, "expected_sum": closed_form_sum_of_squares(1)},
{"slice": "4-device (v5litepod-4 / v6e-4)", "devices": 4, "expected_sum": closed_form_sum_of_squares(4)},
{"slice": "8-device (v5litepod-8 / v6e-8)", "devices": 8, "expected_sum": closed_form_sum_of_squares(8)},
]
# Run `build_runtime_receipt` to compute `receipt`.
receipt = build_runtime_receipt()
# Assert invariant `receipt["verified"] is True` holds
assert receipt["verified"] is True
# Print the observed values to compare against the expected result.
print("Runtime receipt:", json.dumps(receipt, sort_keys=True))
# Print diagnostic summary of the computed outputs.
print("Expected pmap sums by slice:", {s["slice"]: s["expected_sum"] for s in slice_expectations})Expected result: Prints the verified JSON runtime receipt (observed_total: 140.0 on 1 device) and the expected pmap sums for 1-device (140.0), 4-device (10416.0), and 8-device (85344.0) slices.
Recorded reference execution
Reference output captured from executing the complete lesson script (code/main.py) and its assertions in the course CPU environment.
Runtime receipt: {"backend": "cpu", "expected_total": 140.0, "jax": "0.9.2", "local_device_count": 1, "observed_total": 140.0, "per_device_sums": [140.0], "python": "3.14.3", "receipt_sha256": "8c6bd0cbe29edc78", "verified": true}
Expected pmap sums by slice: {'1-device (CPU / v5e-1)': 140.0, '4-device (v5litepod-4 / v6e-4)': 10416.0, '8-device (v5litepod-8 / v6e-8)': 85344.0}
Runtime receipt: {"backend": "cpu", "expected_total": 140.0, "jax": "0.9.2", "local_device_count": 1, "observed_total": 140.0, "per_device_sums": [140.0], "python": "3.14.3", "receipt_sha256": "8c6bd0cbe29edc78", "verified": true}
Expected pmap sums by slice: {'1-device (CPU / v5e-1)': 140.0, '4-device (v5litepod-4 / v6e-4)': 10416.0, '8-device (v5litepod-8 / v6e-8)': 85344.0}
Per-chip sums on a 4-chip slice: [140.0, 1100.0, 3084.0, 6092.0] Total: 10416.0
Teardown verifier passed for empty and non-empty gcloud list outputs.
4-chip expected sum: 10416.0 8-chip expected sum: 85344.0 receipt hash: 8c6bd0cbe29edc78
Simulated 4-chip TPU check: True Local CPU check: False
Overnight idle cost avoided (USD): 74.4
PASS: tpu-04
Download execution record · The notebook includes executed cells and figure outputs. Compare your run with these values; timings depend on the machine.
Compare per-device row sums on a 4-chip TPU slice
# Experiment — Compare per-device row sums on a 4-chip TPU slice: Inspecting per_device_sums confirms that distinct shards of x...
# Construct and reshape `x4` into the target tensor dimensions.
x4 = jnp.arange(4 * 8, dtype=jnp.float32).reshape(4, 8)
# Reduce along axis=1 to compute `row_sums_4`.
row_sums_4 = [float(v) for v in jnp.sum(x4 * x4, axis=1)]
# Print the observed values to compare against the expected result.
print("Per-chip sums on a 4-chip slice:", row_sums_4, "Total:", sum(row_sums_4))
# Assert that `row_sums_4 == [140.0, 1100.0, 3084.0, 6092.0] and sum(row_sums_4) == 10416.0`.
assert row_sums_4 == [140.0, 1100.0, 3084.0, 6092.0] and sum(row_sums_4) == 10416.0Expected: Chip 0 sums 0^2..7^2 = 140.0, chip 1 sums 8^2..15^2 = 1100.0, chip 2 sums 16^2..23^2 = 3084.0, and chip 3 sums 24^2..31^2 = 6092.0 (total 10416.0).
Inspecting per_device_sums confirms that distinct shards of x were placed and squared on each of the 4 chips.
Verify teardown confirmation logic
# Experiment — Verify teardown confirmation logic: Checking gcloud compute tpus tpu-vm list --zone=$ZONE...
def is_tpu_zone_clean(gcloud_list_json):
# Read or serialize artifact data on disk (`items`).
items = json.loads(gcloud_list_json)
# Return `len(items) == 0` to the caller.
return len(items) == 0
# Assert invariant `is_tpu_zone_clean("[]") is True` holds
assert is_tpu_zone_clean("[]") is True
# Assert invariant `is_tpu_zone_clean('[{"name": "jax-tpu-course"` holds
assert is_tpu_zone_clean('[{"name": "jax-tpu-course", "state": "READY"}]') is False
# Print the observed values to compare against the expected result.
print("Teardown verifier passed for empty and non-empty gcloud list outputs.")Expected: Returns True only when the JSON array from gcloud compute tpus tpu-vm list --format=json is empty ([]).
Checking gcloud compute tpus tpu-vm list --zone=$ZONE --format=json makes teardown verification machine-checkable.
Make it yours
Where to put your code: Append your solution at the bottom of phases/19-tpu/02-bootstrap-venv-and-verify-tpu-runtime-receipt/code/main.py (or inside the Make it yours cell of exercises/tpu-04.ipynb) and run python3 phases/19-tpu/02-bootstrap-venv-and-verify-tpu-runtime-receipt/code/main.py to verify your prediction before opening the reference solution.
Compute closed_form_sum_of_squares(4) and closed_form_sum_of_squares(8), verify that closed_form_sum_of_squares(4) == 10416.0, and assert that receipt['verified'] is True.
Show a writing guide and starter scaffold
How to write this exercise code: step-by-step recipe & starter scaffold
1. Key functions & syntax to use:
closed_form_sum_of_squares(...)— Callclosed_form_sum_of_squareswith your updated parameters or inputs from this lesson's workspace.assert condition— Verify that the observed output shape, status, or numerical value satisfies the contract.
2. Step-by-step implementation plan:
- Run
closed_form_sum_of_squaresto computes8. - Print the observed values to compare against the expected result.
- Assert invariant
s4 == 10416.0 and s8 == 85344.0 and receipt["verified"] is Trueholds
# Exercise solution: Compute closed_form_sum_of_squares(4) and...
s4 = closed_form_sum_of_squares(...) # TODO: compute s4
# Run `closed_form_sum_of_squares` to compute `s8`.
s8 = closed_form_sum_of_squares(...) # TODO: compute s8
# Print the observed values to compare against the expected result.
print("4-chip expected sum:", s4, "8-chip expected sum:", s8, "receipt hash:", receipt["receipt_sha256"])
# Assert invariant `s4 == 10416.0 and s8 == 85344.0 and receipt["verified"] is True` holds
assert s4 # TODO: complete assertion check
Reveal the reference solution
# Exercise solution: Compute closed_form_sum_of_squares(4) and...
s4 = closed_form_sum_of_squares(4)
# Run `closed_form_sum_of_squares` to compute `s8`.
s8 = closed_form_sum_of_squares(8)
# Print the observed values to compare against the expected result.
print("4-chip expected sum:", s4, "8-chip expected sum:", s8, "receipt hash:", receipt["receipt_sha256"])
# Assert invariant `s4 == 10416.0 and s8 == 85344.0 and receipt["verified"] is True` holds
assert s4 == 10416.0 and s8 == 85344.0 and receipt["verified"] is TrueDetect a silent fallback from 4 TPU chips to 1 CPU device
Foundations
Write a check is_four_chip_tpu_receipt(r) that returns True only when r['backend'] == 'tpu', r['local_device_count'] == 4, and r['observed_total'] == 10416.0.
Show a writing guide and starter scaffold
How to write this practice solution: step-by-step recipe & starter scaffold
1. Key functions & syntax to use:
device(...)— Calldevicewith your updated parameters or inputs from this lesson's workspace.is_four_chip_tpu_receipt(...)— Callis_four_chip_tpu_receiptwith your updated parameters or inputs from this lesson's workspace.assert condition— Verify that the observed output shape, status, or numerical value satisfies the contract.
2. Step-by-step implementation plan:
- Detect a silent fallback from 4 TPU chips to 1 CPU device (Foundations): Requiring backend == 'tpu', local_device_count == 4, and the...
- Return
bool(r['backend'] == 'tpu' and r['local_device_count'] == 4 and np.isclose(r['observed_total'], 10416.0))to the caller. - Compute
simulated_tpufrom{"backend": "tpu", "local_device_count": 4, "observe... - Print the observed values to compare against the expected result.
- Assert invariant
is_four_chip_tpu_receipt(simulated_tpu) is Trueholds
# Detect a silent fallback from 4 TPU chips to 1 CPU device (Foundations): Requiring backend == 'tpu', local_device_count == 4, and the...
def is_four_chip_tpu_receipt(r):
# Return `bool(r['backend'] == 'tpu' and r['local_device_count'] == 4 and np.isclose(r['observed_total'], 10416.0))` to the caller.
return bool(r["backend"] = ... # TODO: compute return bool(r["backend"]
# Compute `simulated_tpu` from `{"backend": "tpu", "local_device_count": 4, "observe...`
simulated_tpu = ... # TODO: compute simulated_tpu
# Print the observed values to compare against the expected result.
print("Simulated 4-chip TPU check:", is_four_chip_tpu_receipt(simulated_tpu), "Local CPU check:", is_four_chip_tpu_receipt(receipt))
# Assert invariant `is_four_chip_tpu_receipt(simulated_tpu) is True` holds
assert is_four_chip_tpu_receipt(simulated_tpu) is True # TODO: complete assertion check
Show a hint
Check all three fields in the receipt dictionary.
Reveal reference solution and reasoning
# Detect a silent fallback from 4 TPU chips to 1 CPU device (Foundations): Requiring backend == 'tpu', local_device_count == 4, and the...
def is_four_chip_tpu_receipt(r):
# Return `bool(r['backend'] == 'tpu' and r['local_device_count'] == 4 and np.isclose(r['observed_total'], 10416.0))` to the caller.
return bool(r["backend"] == "tpu" and r["local_device_count"] == 4 and np.isclose(r["observed_total"], 10416.0))
# Compute `simulated_tpu` from `{"backend": "tpu", "local_device_count": 4, "observe...`
simulated_tpu = {"backend": "tpu", "local_device_count": 4, "observed_total": 10416.0}
# Print the observed values to compare against the expected result.
print("Simulated 4-chip TPU check:", is_four_chip_tpu_receipt(simulated_tpu), "Local CPU check:", is_four_chip_tpu_receipt(receipt))
# Assert invariant `is_four_chip_tpu_receipt(simulated_tpu) is True` holds
assert is_four_chip_tpu_receipt(simulated_tpu) is TrueRequiring backend == 'tpu', local_device_count == 4, and the 4-chip pmap total prevents a misconfigured environment from passing as a 4-chip TPU run.
Estimate hourly billing savings from immediate teardown
Transfer / diagnosis
If a 4-chip TPU slice costs USD/hour and your verification + experiment takes hours, compute how many USD you save by deleting the VM immediately instead of leaving it idle overnight for hours.
Show a writing guide and starter scaffold
How to write this practice solution: step-by-step recipe & starter scaffold
1. Key functions & syntax to use:
teardown(...)— Callteardownwith your updated parameters or inputs from this lesson's workspace.round(...)— Callroundwith your updated parameters or inputs from this lesson's workspace.assert condition— Verify that the observed output shape, status, or numerical value satisfies the contract.
2. Step-by-step implementation plan:
- Run
roundto computesaved_usd. - Print the observed values to compare against the expected result.
- Assert invariant
saved_usd == 74.4holds
# Estimate hourly billing savings from immediate teardown (Transfer / diagnosis): Deleting the Cloud TPU VM immediately after copying...
hourly_rate = ... # TODO: compute hourly_rate
# Run `round` to compute `saved_usd`.
saved_usd = round(...) # TODO: compute saved_usd
# Print the observed values to compare against the expected result.
print("Overnight idle cost avoided (USD):", saved_usd)
# Assert invariant `saved_usd == 74.4` holds
assert saved_usd # TODO: complete assertion check
Show a hint
Compare 16.0 * 4.80 against 0.5 * 4.80.
Reveal reference solution and reasoning
# Estimate hourly billing savings from immediate teardown (Transfer / diagnosis): Deleting the Cloud TPU VM immediately after copying...
hourly_rate = 4.80
# Run `round` to compute `saved_usd`.
saved_usd = round((16.0 - 0.5) * hourly_rate, 2)
# Print the observed values to compare against the expected result.
print("Overnight idle cost avoided (USD):", saved_usd)
# Assert invariant `saved_usd == 74.4` holds
assert saved_usd == 74.4Deleting the Cloud TPU VM immediately after copying artifacts back avoids paying for 15.5 idle hours.
Diagnose the result
If pip install 'jax[tpu]' fails to find libtpu, verify that -f https://storage.googleapis.com/jax-releases/libtpu_releases.html was passed to pip install inside the activated ~/jax-tpu-lab/.venv on the Linux TPU VM.
Carry forward
- Always install
jax[tpu]inside an isolated~/jax-tpu-lab/.venvon the TPU VM host. - Verify
backend,local_device_count, and a synchronizedjax.pmapsum-of-squares receipt before starting longer experiments. - Copy your receipt back with
gcloud compute tpus tpu-vm scp, runtpu-vm delete, and confirmtpu-vm listis empty.
Keep your evidence
Keep the JSON runtime receipt (observed_backend, device_count, pmap_sum_of_squares, receipt_sha256) and the 1-chip vs 4-chip vs 8-chip pmap reference values.
Save your modified code, its output, and an explanation of your prediction. Checkpoint answers and exercise evidence are tracked separately.
Saved in this browser. Export or back up your portfolio anytime in My learning.
Verified on local CPU. Stage to a Cloud TPU VM via Cloud TPU setup to record accelerator execution receipts (TODO: add automated Cloud TPU CI execution receipts).
Primary references
Phase 19 Integration Project
Bring this phase together: Inspect CPU device inventory, BF16 storage, and collective participant arithmetic
Checkpoint to prove: Select a single-host TPU topology, provision a Cloud TPU VM (or Colab TPU), bootstrap jax[tpu] in an isolated .venv, verify pmap execution, and confirm clean VM deletion.
Work in projects/tpu-runtime-audit/starter/model.py. Complete stages 1 and 2 for independent calculations and changed-condition diagnosis, then retain the stage 3 evidence with --evidence-dir runs/tpu-runtime-audit. Stage 4 integrates the checks. Learner commands explicitly select the starter; --implementation solution is instructor reference execution. This bounded practice does not certify the entire phase or target hardware.