Phase 16 / Workload operations
Capacity, utilization, and operating cost
Revision v0.7.0 · Updated since your last visit. Review the changes; your progress is saved.
Lesson · about 90 minutes · CPU practice
Measure end-to-end local service time at more than one workload length. Compute offered load, worker reserve and illustrative cost with consistent units.
Phase study guide: preparation, milestones and project evidence
Before you start
Before this: Changes, rollback, and artifact provenance
Hardware: CPU
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/16-operations/05-capacity-utilization-and-operating-cost/code/main.py.\.venv\Scripts\python.exe phases/16-operations/05-capacity-utilization-and-operating-cost/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 operations-05.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: Three actual local durations feed a first-order plan whose arrival rate, worker count, reserve and price are explicitly hypothetical. No hardware utilization or cloud-cost claim is inferred from CPU timings.
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
- Measure end-to-end local service time at more than one workload length.
- Compute offered load, worker reserve and illustrative cost with consistent units.
- Identify assumptions that prevent a CPU fixture from establishing accelerator fleet capacity.
The problem
A short local training job finishes quickly. How many workers would a stream of jobs require, and what can this measurement actually tell us about cost? We will measure complete CPU jobs of several lengths, separate update work from startup overhead and apply transparent capacity arithmetic to explicitly hypothetical arrival rates and prices.
The idea
Operating cost depends on resource allocation, runtime and the billing model. A workload's fraction of time in useful updates is not the same as device utilization. Keep cost accounting and performance measurements explicit.
Account for billed time as well as useful work
A job may spend time provisioning, loading, compiling, updating and shutting down. For short jobs, fixed startup costs can dominate even if the update loop is efficient. Reusing a warm service changes that tradeoff but introduces its own allocation costs.
Track the resource count and billed interval under the actual pricing assumptions. If a rate is hypothetical, label the resulting cost as modeled. A duration multiplied by an assumed price is not an invoice.
The timing panels compare different intervals. Their ratios can describe job-level busy fraction, but they do not measure accelerator instruction or memory utilization. Choose the metric that answers the operational question before optimizing it.
Measure the service boundary you intend to provision
We run jobs with , and updates in fresh child processes. Supervisor wall time includes imports, runtime startup, compilation, updates, logs and checkpoints. If a production worker stays warm across many jobs, this measurement overstates repeated startup cost; if production adds queueing or remote data, it understates those delays. Write the boundary alongside the number. We use the maximum of these three local observations as an illustrative conservative input, not a statistical tail estimate.
Convert seconds into worker demand
Let be arrivals per hour, seconds per job and workers, each running one job at a time. Offered demand is worker-hours per hour. Nominal load is this demand divided by . The units cancel to a fraction. A load above one means average demand exceeds nominal capacity under the model; a load below one does not guarantee a latency target.
State the reserve rather than hiding it
For reserve fraction , require nominal load no greater than . The smallest integer worker count in this simple model is the ceiling below, with at least one worker in our function. For -second jobs arriving times an hour, demand is worker-hours per hour. A % reserve requires at least workers; four workers would run at nominal load .
A cost number needs a declared price model
We use an invented planning rate of currency units per worker-hour, explicitly not a current cloud price. Reserving two workers for an hour costs under that model, whether busy or idle. A job’s active-time cost is for hourly rate , but dividing the reserved hourly bill by actual completed jobs can produce a different cost per completion. Include idle capacity, failed attempts, storage and transfer charges when those belong to the real budget.
Do not confuse duty fraction with hardware utilization
The worker records seconds inside synchronized compiled updates. Dividing their sum by job wall time is an application duty fraction. A small value in a tiny job mostly reflects startup and operational overhead. It does not measure CPU core occupancy, accelerator compute utilization, memory-bandwidth pressure or scheduler allocation. Those require their own target-specific measurements. Increasing update count can amortize startup without making each update intrinsically faster.
Capacity is a distribution, not just a mean
Real arrivals can burst, job durations can vary, failures consume retries, and a worker may be unavailable. Three short measurements cannot estimate a high percentile reliably. Retain individual timings, choose a larger representative study on the actual target, and test the queue/latency objective before buying capacity. The local examples execute real jobs; all arrival, reserve and price scenarios remain labeled assumptions.
Short jobs spend time outside the update loop
Predict before looking: Will doubling the number of updates double total process time?
Read the figure
The horizontal categories in both panels are actual jobs with , and updates. The upper panel shows complete supervisor wall time in seconds. The lower panel shows the sum of synchronized update times in seconds. The panels use separate linear vertical scales, so compare their labeled numerical values rather than bar heights across panels. The labels retain the actual measurements from this run.
Connect it to the computation
The lower-panel values are much smaller than the complete-job values because startup, compilation, logging and checkpoint writes are outside the update timer. Calculate each pair’s ratio from its labels to see how much of the short job is spent in measured updates. The ratio can be large for such small workloads. Host scheduling and filesystem work vary, so close wall-time values need not increase monotonically with update count. This figure explains timing boundaries and startup amortization; it does not measure hardware utilization or prove scaling on an accelerator.
Open full-size figureDownload data and provenance
The notebook contains the data experiment, plotting code, and recorded figure output. Rerun it to test your changes.
Where to put & run this code: Work in phases/16-operations/05-capacity-utilization-and-operating-cost/code/main.py (or downloaded exercises/operations-05.py / exercises/operations-05.ipynb) and execute from the repository root with python3 phases/16-operations/05-capacity-utilization-and-operating-cost/code/main.py.
1 Create the local artifact helpers
Create main.py with this block. Run python3 main.py in the CPU course environment.
# Step 1: Create the local artifact helpers
"""Bounded local JAX subprocess supervisor and lifecycle verifier."""
from pathlib import Path
import hashlib
import json
import math
import os
import subprocess
import sys
import tempfile
import time
def digest(value):
return hashlib.sha256(json.dumps(value, sort_keys=True, separators=(',', ':'), allow_nan=False).encode()).hexdigest()
def atomic_json(path, value):
"""Replace one local JSON file only after its bytes have been flushed."""
path = Path(path)
path.parent.mkdir(parents=True, exist_ok=True)
fd, temporary = tempfile.mkstemp(prefix=path.name+'.', suffix='.tmp', dir=path.parent)
# Run the boundary check and catch the expected exception:
try:
# Enter `os.fdopen(fd, 'w')` context block:
with os.fdopen(fd, 'w') as stream:
json.dump(value, stream, sort_keys=True, allow_nan=False)
stream.flush()
os.fsync(stream.fileno())
os.replace(temporary, path)
finally:
if os.path.exists(temporary):
os.unlink(temporary)Code building blocks in this step
digest(...)— Calldigestwith your updated parameters or inputs from this lesson's workspace.hashlib.sha256(...)— Callhashlib.sha256with your updated parameters or inputs from this lesson's workspace.
The only filesystem writes are to the caller-selected run directory. Stable JSON encoding makes hashes reproducible.
2 Define the supervised worker
Append this block to main.py. Run python3 main.py in the CPU course environment.
# This file is materialized only inside the caller-owned temporary run folder.
WORKER = r'''
import hashlib, json, os, sys, time
from pathlib import Path
import jax
import jax.numpy as jnp
import numpy as np
root = Path(sys.argv[1])
cfg = json.loads((root/'config.json').read_text())
worker_hash = hashlib.sha256(Path(__file__).read_bytes()).hexdigest()
def emit(event, **fields):
print(json.dumps(dict(event=event, monotonic_s=time.monotonic(), **fields)), flush=True)
def digest(value):
return hashlib.sha256(json.dumps(value,sort_keys=True,separators=(',', ':'),allow_nan=False).encode()).hexdigest()
def write_checkpoint(state):
target = root/'checkpoint.json'
temporary = root/'checkpoint.pending'
with temporary.open('w') as stream:
json.dump(dict(state,checksum=digest(state)),stream,sort_keys=True,allow_nan=False)
stream.flush()
os.fsync(stream.fileno())
os.replace(temporary,target)
emit('checkpoint',step=state['step'],state_hash=digest(state))
try:
emit('started',pid=os.getpid(),backend=jax.default_backend(),device_count=jax.device_count())
if jax.default_backend() != cfg['backend'] or jax.device_count() < cfg['min_devices']:
raise ValueError('runtime backend/device contract failed')
x = jnp.linspace(-1.,1.,64)
y = 2*x+1
data_hash = digest(dict(x=np.asarray(x).tolist(),y=np.asarray(y).tolist()))
training = {name:cfg[name] for name in ('seed','learning_rate','momentum','batch_size')}
config_hash = digest(training)
if cfg['resume']:
saved = json.loads((root/'checkpoint.json').read_text())
checksum = saved.pop('checksum',None)
if checksum != digest(saved) or saved.get('worker_hash') != worker_hash:
raise ValueError('checkpoint checksum/source mismatch')
if saved['schema_version'] != 1 or saved['config_hash'] != config_hash or saved['data_hash'] != data_hash:
raise ValueError('checkpoint provenance mismatch')
state = saved
step = saved['step']
params=jnp.array(saved['params'])
velocity=jnp.array(saved['velocity'])
key=jnp.array(saved['key'],dtype=jnp.uint32)
if not isinstance(step,int) or isinstance(step,bool) or step < 0 or step > cfg['steps'] or params.shape != (2,) or velocity.shape != (2,) or key.shape != (2,):
raise ValueError('invalid checkpoint state shape or step')
if not bool(jnp.all(jnp.isfinite(params))) or not bool(jnp.all(jnp.isfinite(velocity))):
raise ValueError('nonfinite checkpoint state')
emit('restored',step=step,state_hash=digest(saved))
else:
step=0
params=jnp.zeros(2)
velocity=jnp.zeros(2)
key=jax.random.PRNGKey(cfg['seed'])
def update(params,velocity,key):
key, sample = jax.random.split(key)
indices=jax.random.choice(sample,64,(cfg['batch_size'],),replace=False)
objective=lambda p:jnp.mean((p[0]*x[indices]+p[1]-y[indices])**2)
loss, grad=jax.value_and_grad(objective)(params)
velocity=cfg['momentum']*velocity+grad
params=params-cfg['learning_rate']*velocity
return params,velocity,key,loss
compiled=jax.jit(update)
# Compile and synchronize once without consuming actual training state.
begin=time.perf_counter()
warm=compiled(params,velocity,key)
jax.block_until_ready(warm)
emit('ready',compile_warmup_s=time.perf_counter()-begin,step=step)
while step < cfg['steps']:
if cfg.get('stall_at') == step:
emit('stall_injected',step=step)
time.sleep(cfg.get('stall_seconds',10.))
begin=time.perf_counter()
params,velocity,key,loss=compiled(params,velocity,key)
jax.block_until_ready((params,velocity,key,loss))
elapsed=time.perf_counter()-begin
step+=1
state=dict(schema_version=1,worker_hash=worker_hash,step=step,params=np.asarray(params).tolist(),velocity=np.asarray(velocity).tolist(),key=np.asarray(key).tolist(),config_hash=config_hash,data_hash=data_hash)
emit('progress',step=step,loss=float(loss),examples=cfg['batch_size'],update_s=elapsed,state_hash=digest(state))
if step % cfg['checkpoint_every'] == 0 or step == cfg['steps']:
write_checkpoint(state)
if cfg.get('fail_after') == step:
raise RuntimeError('controlled failure after update')
write_checkpoint(state)
emit('completed',step=step,state_hash=digest(state))
except Exception as error:
emit('failed',kind=type(error).__name__,message=str(error))
raise SystemExit(23)
'''Code building blocks in this step
jnp.linspace(start, stop, num)— Createsnumevenly spaced float points across the closed interval[start, stop].jnp.array(values, dtype=...)— Constructs an immutable device-backed JAX array from Python/NumPy values.jnp.zeros / jnp.ones(shape, dtype=...)— Allocates a tensor of the givenshapeinitialized with constants.x.sum(axis=...) / x.mean(axis=..., keepdims=...)— Reduces values along the namedaxis(the axis you name is collapsed unlesskeepdims=True).
The string is a real Python program launched in a separate process. It emits structured events, synchronizes JAX updates and preserves complete state.
3 Add bounded launch and result collection
Append this block to main.py. Run python3 main.py in the CPU course environment.
# Step 3 — Add bounded launch and result collection: The supervisor owns the child handle, captures its output and...
def default_config(**changes):
cfg=dict(seed=3,learning_rate=.04,momentum=.8,batch_size=8,steps=8,
checkpoint_every=2,backend='cpu',min_devices=1,resume=False,
fail_after=None,stall_at=None,stall_seconds=10.)
# Update state in place with the new values.
cfg.update(changes)
for name in ('steps','checkpoint_every','batch_size','min_devices'):
# Guard input contract (`not isinstance(cfg[name], int) or isinstance(cfg[name], bool) or cfg[name] < 1`) and fail fast if violated.
if not isinstance(cfg[name],int) or isinstance(cfg[name],bool) or cfg[name] < 1:
raise ValueError(name+' must be a positive integer')
# Guard input contract (`cfg['batch_size'] > 64 or not 0 <= cfg['momentum'] < 1 or (not 0 < cfg['learning_rate'] < 1)`) and fail fast if violated.
if cfg['batch_size'] > 64 or not 0 <= cfg['momentum'] < 1 or not 0 < cfg['learning_rate'] < 1:
raise ValueError('invalid training configuration')
return cfg
def launch(root, config=None, timeout=10.):
root=Path(root)
root.mkdir(parents=True,exist_ok=True)
cfg=default_config(**(config or {}))
# Guard input contract (`timeout <= 0`) and fail fast if violated.
if timeout <= 0:
raise ValueError('timeout must be positive')
atomic_json(root/'config.json',cfg)
worker=root/'worker.py'
worker.write_text(WORKER)
# Configure environment variable before initializing the runtime.
env=dict(os.environ,JAX_PLATFORMS=cfg['backend'],PYTHONUNBUFFERED='1')
started=time.perf_counter()
process=subprocess.Popen([sys.executable,str(worker),str(root)],stdout=subprocess.PIPE,stderr=subprocess.PIPE,text=True,env=env)
timed_out=False
try:
stdout,stderr=process.communicate(timeout=timeout)
except subprocess.TimeoutExpired:
timed_out=True
process.terminate()
try:
stdout,stderr=process.communicate(timeout=1.)
except subprocess.TimeoutExpired:
process.kill()
stdout,stderr=process.communicate(timeout=1.)
wall=time.perf_counter()-started
events=[]
malformed=[]
for line in stdout.splitlines():
if not line.strip():
continue
try:
event=json.loads(line)
if not isinstance(event,dict) or 'event' not in event:
raise ValueError('not an event')
events.append(event)
except (ValueError,TypeError):
malformed.append(line)
status='timed_out' if timed_out else 'completed' if process.returncode == 0 and not malformed and events and events[-1]['event']=='completed' else 'failed'
# Compute deterministic cryptographic digest `result` for provenance verification.
result=dict(status=status,returncode=process.returncode,wall_s=wall,events=events,stderr=stderr,
worker_hash=hashlib.sha256(WORKER.encode()).hexdigest(),config=cfg,malformed_stdout=malformed)
atomic_json(root/'run.json',result)
return resultCode building blocks in this step
default_config(...)— Calldefault_configwith your updated parameters or inputs from this lesson's workspace.cfg.update(...)— Callcfg.updatewith your updated parameters or inputs from this lesson's workspace.
The supervisor owns the child handle, captures its output and always waits for termination after a timeout.
4 Add metric summaries and capacity arithmetic
Append this block to main.py. Run python3 main.py in the CPU course environment.
# Step 4 — Add metric summaries and capacity arithmetic: Keep measured quantities separate from invented planning inputs...
def summarize(result):
updates=[e for e in result['events'] if e['event']=='progress']
checkpoints=[e['step'] for e in result['events'] if e['event']=='checkpoint']
count=sum(e['examples'] for e in updates)
update_s=sum(e['update_s'] for e in updates)
latest=max((e['step'] for e in updates),default=0)
checkpoint=max(checkpoints,default=0)
return dict(status=result['status'],updates=len(updates),examples=count,last_step=latest,checkpoint_step=checkpoint,
uncheckpointed_updates=max(0,latest-checkpoint),update_s=update_s,
update_examples_per_s=count/update_s if update_s else 0.,
job_examples_per_s=count/result['wall_s'] if result['wall_s'] else 0.,
update_duty_fraction=update_s/result['wall_s'] if result['wall_s'] else 0.)
def capacity(measured_job_s, arrivals_per_hour, workers, hourly_rate, reserve_fraction=.25):
"""Illustrative one-job-per-worker plan; inputs are not cloud price discovery."""
values=[measured_job_s,arrivals_per_hour,hourly_rate,reserve_fraction]
# Guard input contract (`any((not math.isfinite(x) for x in values)) or measured_job_s <= 0 or arrivals_per_hour < 0 or (hourly_rate < 0)`) and fail fast if violated.
if any(not math.isfinite(x) for x in values) or measured_job_s <= 0 or arrivals_per_hour < 0 or hourly_rate < 0:
raise ValueError('invalid finite capacity inputs')
# Guard input contract (`not isinstance(workers, int) or isinstance(workers, bool) or workers < 1 or (not 0 <= reserve_fraction < 1)`) and fail fast if violated.
if not isinstance(workers,int) or isinstance(workers,bool) or workers < 1 or not 0 <= reserve_fraction < 1:
raise ValueError('invalid workers or reserve')
offered=arrivals_per_hour*measured_job_s/3600
load=offered/workers
required=max(1,math.ceil(offered/(1-reserve_fraction)))
return dict(offered_worker_hours_per_hour=offered,load_fraction=load,
minimum_workers_with_reserve=required,hourly_budget=workers*hourly_rate,
hypothetical_cost_per_job=measured_job_s*hourly_rate/3600,
within_reserve=load <= 1-reserve_fraction)Code building blocks in this step
summarize(...)— Callsummarizewith your updated parameters or inputs from this lesson's workspace.sum(...)— Callsumwith your updated parameters or inputs from this lesson's workspace.
Keep measured quantities separate from invented planning inputs and validate the units.
5 Measure jobs before evaluating assumptions
Append this block to main.py. Run python3 main.py in the CPU course environment.
# Step 5 — Measure jobs before evaluating assumptions: Every duration comes from a completed child; arrival and price...
samples=[]
# Create an isolated temporary directory to run and inspect artifacts safely:
with tempfile.TemporaryDirectory(prefix='ops-capacity-') as folder:
for steps in [8,32,64]:
run=launch(Path(folder)/str(steps),dict(steps=steps))
assert run['status']=='completed'
samples.append((steps,run,summarize(run)))
measured=max(run['wall_s'] for _,run,_ in samples)
plan=capacity(measured_job_s=measured,arrivals_per_hour=600,workers=2,hourly_rate=1.5,reserve_fraction=.25)
assert plan['hourly_budget']==3.
print('measured local job seconds:',[r['wall_s'] for _,r,_ in samples])
print('illustrative capacity plan:',plan)
print('assumptions: 600 arrivals/hour, 2 workers, hypothetical 1.50 per worker-hour, 25% reserve')Code building blocks in this step
tempfile.TemporaryDirectory(...)— Calltempfile.TemporaryDirectorywith your updated parameters or inputs from this lesson's workspace.launch(...)— Calllaunchwith 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.
Every duration comes from a completed child; arrival and price inputs are labeled hypothetical.
View the cumulative build in main.py
These blocks append in order to the same file.
# Step 1: Create the local artifact helpers
"""Bounded local JAX subprocess supervisor and lifecycle verifier."""
from pathlib import Path
import hashlib
import json
import math
import os
import subprocess
import sys
import tempfile
import time
def digest(value):
return hashlib.sha256(json.dumps(value, sort_keys=True, separators=(',', ':'), allow_nan=False).encode()).hexdigest()
def atomic_json(path, value):
"""Replace one local JSON file only after its bytes have been flushed."""
path = Path(path)
path.parent.mkdir(parents=True, exist_ok=True)
fd, temporary = tempfile.mkstemp(prefix=path.name+'.', suffix='.tmp', dir=path.parent)
# Run the boundary check and catch the expected exception:
try:
# Enter `os.fdopen(fd, 'w')` context block:
with os.fdopen(fd, 'w') as stream:
json.dump(value, stream, sort_keys=True, allow_nan=False)
stream.flush()
os.fsync(stream.fileno())
os.replace(temporary, path)
finally:
if os.path.exists(temporary):
os.unlink(temporary)
# This file is materialized only inside the caller-owned temporary run folder.
WORKER = r'''
import hashlib, json, os, sys, time
from pathlib import Path
import jax
import jax.numpy as jnp
import numpy as np
root = Path(sys.argv[1])
cfg = json.loads((root/'config.json').read_text())
worker_hash = hashlib.sha256(Path(__file__).read_bytes()).hexdigest()
def emit(event, **fields):
print(json.dumps(dict(event=event, monotonic_s=time.monotonic(), **fields)), flush=True)
def digest(value):
return hashlib.sha256(json.dumps(value,sort_keys=True,separators=(',', ':'),allow_nan=False).encode()).hexdigest()
def write_checkpoint(state):
target = root/'checkpoint.json'
temporary = root/'checkpoint.pending'
with temporary.open('w') as stream:
json.dump(dict(state,checksum=digest(state)),stream,sort_keys=True,allow_nan=False)
stream.flush()
os.fsync(stream.fileno())
os.replace(temporary,target)
emit('checkpoint',step=state['step'],state_hash=digest(state))
try:
emit('started',pid=os.getpid(),backend=jax.default_backend(),device_count=jax.device_count())
if jax.default_backend() != cfg['backend'] or jax.device_count() < cfg['min_devices']:
raise ValueError('runtime backend/device contract failed')
x = jnp.linspace(-1.,1.,64)
y = 2*x+1
data_hash = digest(dict(x=np.asarray(x).tolist(),y=np.asarray(y).tolist()))
training = {name:cfg[name] for name in ('seed','learning_rate','momentum','batch_size')}
config_hash = digest(training)
if cfg['resume']:
saved = json.loads((root/'checkpoint.json').read_text())
checksum = saved.pop('checksum',None)
if checksum != digest(saved) or saved.get('worker_hash') != worker_hash:
raise ValueError('checkpoint checksum/source mismatch')
if saved['schema_version'] != 1 or saved['config_hash'] != config_hash or saved['data_hash'] != data_hash:
raise ValueError('checkpoint provenance mismatch')
state = saved
step = saved['step']
params=jnp.array(saved['params'])
velocity=jnp.array(saved['velocity'])
key=jnp.array(saved['key'],dtype=jnp.uint32)
if not isinstance(step,int) or isinstance(step,bool) or step < 0 or step > cfg['steps'] or params.shape != (2,) or velocity.shape != (2,) or key.shape != (2,):
raise ValueError('invalid checkpoint state shape or step')
if not bool(jnp.all(jnp.isfinite(params))) or not bool(jnp.all(jnp.isfinite(velocity))):
raise ValueError('nonfinite checkpoint state')
emit('restored',step=step,state_hash=digest(saved))
else:
step=0
params=jnp.zeros(2)
velocity=jnp.zeros(2)
key=jax.random.PRNGKey(cfg['seed'])
def update(params,velocity,key):
key, sample = jax.random.split(key)
indices=jax.random.choice(sample,64,(cfg['batch_size'],),replace=False)
objective=lambda p:jnp.mean((p[0]*x[indices]+p[1]-y[indices])**2)
loss, grad=jax.value_and_grad(objective)(params)
velocity=cfg['momentum']*velocity+grad
params=params-cfg['learning_rate']*velocity
return params,velocity,key,loss
compiled=jax.jit(update)
# Compile and synchronize once without consuming actual training state.
begin=time.perf_counter()
warm=compiled(params,velocity,key)
jax.block_until_ready(warm)
emit('ready',compile_warmup_s=time.perf_counter()-begin,step=step)
while step < cfg['steps']:
if cfg.get('stall_at') == step:
emit('stall_injected',step=step)
time.sleep(cfg.get('stall_seconds',10.))
begin=time.perf_counter()
params,velocity,key,loss=compiled(params,velocity,key)
jax.block_until_ready((params,velocity,key,loss))
elapsed=time.perf_counter()-begin
step+=1
state=dict(schema_version=1,worker_hash=worker_hash,step=step,params=np.asarray(params).tolist(),velocity=np.asarray(velocity).tolist(),key=np.asarray(key).tolist(),config_hash=config_hash,data_hash=data_hash)
emit('progress',step=step,loss=float(loss),examples=cfg['batch_size'],update_s=elapsed,state_hash=digest(state))
if step % cfg['checkpoint_every'] == 0 or step == cfg['steps']:
write_checkpoint(state)
if cfg.get('fail_after') == step:
raise RuntimeError('controlled failure after update')
write_checkpoint(state)
emit('completed',step=step,state_hash=digest(state))
except Exception as error:
emit('failed',kind=type(error).__name__,message=str(error))
raise SystemExit(23)
'''
# Step 3 — Add bounded launch and result collection: The supervisor owns the child handle, captures its output and...
def default_config(**changes):
cfg=dict(seed=3,learning_rate=.04,momentum=.8,batch_size=8,steps=8,
checkpoint_every=2,backend='cpu',min_devices=1,resume=False,
fail_after=None,stall_at=None,stall_seconds=10.)
# Update state in place with the new values.
cfg.update(changes)
for name in ('steps','checkpoint_every','batch_size','min_devices'):
# Guard input contract (`not isinstance(cfg[name], int) or isinstance(cfg[name], bool) or cfg[name] < 1`) and fail fast if violated.
if not isinstance(cfg[name],int) or isinstance(cfg[name],bool) or cfg[name] < 1:
raise ValueError(name+' must be a positive integer')
# Guard input contract (`cfg['batch_size'] > 64 or not 0 <= cfg['momentum'] < 1 or (not 0 < cfg['learning_rate'] < 1)`) and fail fast if violated.
if cfg['batch_size'] > 64 or not 0 <= cfg['momentum'] < 1 or not 0 < cfg['learning_rate'] < 1:
raise ValueError('invalid training configuration')
return cfg
def launch(root, config=None, timeout=10.):
root=Path(root)
root.mkdir(parents=True,exist_ok=True)
cfg=default_config(**(config or {}))
# Guard input contract (`timeout <= 0`) and fail fast if violated.
if timeout <= 0:
raise ValueError('timeout must be positive')
atomic_json(root/'config.json',cfg)
worker=root/'worker.py'
worker.write_text(WORKER)
# Configure environment variable before initializing the runtime.
env=dict(os.environ,JAX_PLATFORMS=cfg['backend'],PYTHONUNBUFFERED='1')
started=time.perf_counter()
process=subprocess.Popen([sys.executable,str(worker),str(root)],stdout=subprocess.PIPE,stderr=subprocess.PIPE,text=True,env=env)
timed_out=False
try:
stdout,stderr=process.communicate(timeout=timeout)
except subprocess.TimeoutExpired:
timed_out=True
process.terminate()
try:
stdout,stderr=process.communicate(timeout=1.)
except subprocess.TimeoutExpired:
process.kill()
stdout,stderr=process.communicate(timeout=1.)
wall=time.perf_counter()-started
events=[]
malformed=[]
for line in stdout.splitlines():
if not line.strip():
continue
try:
event=json.loads(line)
if not isinstance(event,dict) or 'event' not in event:
raise ValueError('not an event')
events.append(event)
except (ValueError,TypeError):
malformed.append(line)
status='timed_out' if timed_out else 'completed' if process.returncode == 0 and not malformed and events and events[-1]['event']=='completed' else 'failed'
# Compute deterministic cryptographic digest `result` for provenance verification.
result=dict(status=status,returncode=process.returncode,wall_s=wall,events=events,stderr=stderr,
worker_hash=hashlib.sha256(WORKER.encode()).hexdigest(),config=cfg,malformed_stdout=malformed)
atomic_json(root/'run.json',result)
return result
# Step 4 — Add metric summaries and capacity arithmetic: Keep measured quantities separate from invented planning inputs...
def summarize(result):
updates=[e for e in result['events'] if e['event']=='progress']
checkpoints=[e['step'] for e in result['events'] if e['event']=='checkpoint']
count=sum(e['examples'] for e in updates)
update_s=sum(e['update_s'] for e in updates)
latest=max((e['step'] for e in updates),default=0)
checkpoint=max(checkpoints,default=0)
return dict(status=result['status'],updates=len(updates),examples=count,last_step=latest,checkpoint_step=checkpoint,
uncheckpointed_updates=max(0,latest-checkpoint),update_s=update_s,
update_examples_per_s=count/update_s if update_s else 0.,
job_examples_per_s=count/result['wall_s'] if result['wall_s'] else 0.,
update_duty_fraction=update_s/result['wall_s'] if result['wall_s'] else 0.)
def capacity(measured_job_s, arrivals_per_hour, workers, hourly_rate, reserve_fraction=.25):
"""Illustrative one-job-per-worker plan; inputs are not cloud price discovery."""
values=[measured_job_s,arrivals_per_hour,hourly_rate,reserve_fraction]
# Guard input contract (`any((not math.isfinite(x) for x in values)) or measured_job_s <= 0 or arrivals_per_hour < 0 or (hourly_rate < 0)`) and fail fast if violated.
if any(not math.isfinite(x) for x in values) or measured_job_s <= 0 or arrivals_per_hour < 0 or hourly_rate < 0:
raise ValueError('invalid finite capacity inputs')
# Guard input contract (`not isinstance(workers, int) or isinstance(workers, bool) or workers < 1 or (not 0 <= reserve_fraction < 1)`) and fail fast if violated.
if not isinstance(workers,int) or isinstance(workers,bool) or workers < 1 or not 0 <= reserve_fraction < 1:
raise ValueError('invalid workers or reserve')
offered=arrivals_per_hour*measured_job_s/3600
load=offered/workers
required=max(1,math.ceil(offered/(1-reserve_fraction)))
return dict(offered_worker_hours_per_hour=offered,load_fraction=load,
minimum_workers_with_reserve=required,hourly_budget=workers*hourly_rate,
hypothetical_cost_per_job=measured_job_s*hourly_rate/3600,
within_reserve=load <= 1-reserve_fraction)
# Step 5 — Measure jobs before evaluating assumptions: Every duration comes from a completed child; arrival and price...
samples=[]
# Create an isolated temporary directory to run and inspect artifacts safely:
with tempfile.TemporaryDirectory(prefix='ops-capacity-') as folder:
for steps in [8,32,64]:
run=launch(Path(folder)/str(steps),dict(steps=steps))
assert run['status']=='completed'
samples.append((steps,run,summarize(run)))
measured=max(run['wall_s'] for _,run,_ in samples)
plan=capacity(measured_job_s=measured,arrivals_per_hour=600,workers=2,hourly_rate=1.5,reserve_fraction=.25)
assert plan['hourly_budget']==3.
print('measured local job seconds:',[r['wall_s'] for _,r,_ in samples])
print('illustrative capacity plan:',plan)
print('assumptions: 600 arrivals/hour, 2 workers, hypothetical 1.50 per worker-hour, 25% reserve')Run the example
python3 phases/16-operations/05-capacity-utilization-and-operating-cost/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
# Complete runnable example (operations-05)
"""Bounded local JAX subprocess supervisor and lifecycle verifier."""
from pathlib import Path
import hashlib
import json
import math
import os
import subprocess
import sys
import tempfile
import time
def digest(value):
return hashlib.sha256(json.dumps(value, sort_keys=True, separators=(',', ':'), allow_nan=False).encode()).hexdigest()
def atomic_json(path, value):
"""Replace one local JSON file only after its bytes have been flushed."""
path = Path(path)
path.parent.mkdir(parents=True, exist_ok=True)
fd, temporary = tempfile.mkstemp(prefix=path.name+'.', suffix='.tmp', dir=path.parent)
# Run the boundary check and catch the expected exception:
try:
# Enter `os.fdopen(fd, 'w')` context block:
with os.fdopen(fd, 'w') as stream:
json.dump(value, stream, sort_keys=True, allow_nan=False)
stream.flush()
os.fsync(stream.fileno())
os.replace(temporary, path)
finally:
if os.path.exists(temporary):
os.unlink(temporary)
# This file is materialized only inside the caller-owned temporary run folder.
WORKER = r'''
import hashlib, json, os, sys, time
from pathlib import Path
import jax
import jax.numpy as jnp
import numpy as np
root = Path(sys.argv[1])
cfg = json.loads((root/'config.json').read_text())
worker_hash = hashlib.sha256(Path(__file__).read_bytes()).hexdigest()
def emit(event, **fields):
print(json.dumps(dict(event=event, monotonic_s=time.monotonic(), **fields)), flush=True)
def digest(value):
return hashlib.sha256(json.dumps(value,sort_keys=True,separators=(',', ':'),allow_nan=False).encode()).hexdigest()
def write_checkpoint(state):
target = root/'checkpoint.json'
temporary = root/'checkpoint.pending'
with temporary.open('w') as stream:
json.dump(dict(state,checksum=digest(state)),stream,sort_keys=True,allow_nan=False)
stream.flush()
os.fsync(stream.fileno())
os.replace(temporary,target)
emit('checkpoint',step=state['step'],state_hash=digest(state))
try:
emit('started',pid=os.getpid(),backend=jax.default_backend(),device_count=jax.device_count())
if jax.default_backend() != cfg['backend'] or jax.device_count() < cfg['min_devices']:
raise ValueError('runtime backend/device contract failed')
x = jnp.linspace(-1.,1.,64)
y = 2*x+1
data_hash = digest(dict(x=np.asarray(x).tolist(),y=np.asarray(y).tolist()))
training = {name:cfg[name] for name in ('seed','learning_rate','momentum','batch_size')}
config_hash = digest(training)
if cfg['resume']:
saved = json.loads((root/'checkpoint.json').read_text())
checksum = saved.pop('checksum',None)
if checksum != digest(saved) or saved.get('worker_hash') != worker_hash:
raise ValueError('checkpoint checksum/source mismatch')
if saved['schema_version'] != 1 or saved['config_hash'] != config_hash or saved['data_hash'] != data_hash:
raise ValueError('checkpoint provenance mismatch')
state = saved
step = saved['step']
params=jnp.array(saved['params'])
velocity=jnp.array(saved['velocity'])
key=jnp.array(saved['key'],dtype=jnp.uint32)
if not isinstance(step,int) or isinstance(step,bool) or step < 0 or step > cfg['steps'] or params.shape != (2,) or velocity.shape != (2,) or key.shape != (2,):
raise ValueError('invalid checkpoint state shape or step')
if not bool(jnp.all(jnp.isfinite(params))) or not bool(jnp.all(jnp.isfinite(velocity))):
raise ValueError('nonfinite checkpoint state')
emit('restored',step=step,state_hash=digest(saved))
else:
step=0
params=jnp.zeros(2)
velocity=jnp.zeros(2)
key=jax.random.PRNGKey(cfg['seed'])
def update(params,velocity,key):
key, sample = jax.random.split(key)
indices=jax.random.choice(sample,64,(cfg['batch_size'],),replace=False)
objective=lambda p:jnp.mean((p[0]*x[indices]+p[1]-y[indices])**2)
loss, grad=jax.value_and_grad(objective)(params)
velocity=cfg['momentum']*velocity+grad
params=params-cfg['learning_rate']*velocity
return params,velocity,key,loss
compiled=jax.jit(update)
# Compile and synchronize once without consuming actual training state.
begin=time.perf_counter()
warm=compiled(params,velocity,key)
jax.block_until_ready(warm)
emit('ready',compile_warmup_s=time.perf_counter()-begin,step=step)
while step < cfg['steps']:
if cfg.get('stall_at') == step:
emit('stall_injected',step=step)
time.sleep(cfg.get('stall_seconds',10.))
begin=time.perf_counter()
params,velocity,key,loss=compiled(params,velocity,key)
jax.block_until_ready((params,velocity,key,loss))
elapsed=time.perf_counter()-begin
step+=1
state=dict(schema_version=1,worker_hash=worker_hash,step=step,params=np.asarray(params).tolist(),velocity=np.asarray(velocity).tolist(),key=np.asarray(key).tolist(),config_hash=config_hash,data_hash=data_hash)
emit('progress',step=step,loss=float(loss),examples=cfg['batch_size'],update_s=elapsed,state_hash=digest(state))
if step % cfg['checkpoint_every'] == 0 or step == cfg['steps']:
write_checkpoint(state)
if cfg.get('fail_after') == step:
raise RuntimeError('controlled failure after update')
write_checkpoint(state)
emit('completed',step=step,state_hash=digest(state))
except Exception as error:
emit('failed',kind=type(error).__name__,message=str(error))
raise SystemExit(23)
'''
# Step 3 — Add bounded launch and result collection: The supervisor owns the child handle, captures its output and...
def default_config(**changes):
cfg=dict(seed=3,learning_rate=.04,momentum=.8,batch_size=8,steps=8,
checkpoint_every=2,backend='cpu',min_devices=1,resume=False,
fail_after=None,stall_at=None,stall_seconds=10.)
# Update state in place with the new values.
cfg.update(changes)
for name in ('steps','checkpoint_every','batch_size','min_devices'):
# Guard input contract (`not isinstance(cfg[name], int) or isinstance(cfg[name], bool) or cfg[name] < 1`) and fail fast if violated.
if not isinstance(cfg[name],int) or isinstance(cfg[name],bool) or cfg[name] < 1:
raise ValueError(name+' must be a positive integer')
# Guard input contract (`cfg['batch_size'] > 64 or not 0 <= cfg['momentum'] < 1 or (not 0 < cfg['learning_rate'] < 1)`) and fail fast if violated.
if cfg['batch_size'] > 64 or not 0 <= cfg['momentum'] < 1 or not 0 < cfg['learning_rate'] < 1:
raise ValueError('invalid training configuration')
return cfg
def launch(root, config=None, timeout=10.):
root=Path(root)
root.mkdir(parents=True,exist_ok=True)
cfg=default_config(**(config or {}))
# Guard input contract (`timeout <= 0`) and fail fast if violated.
if timeout <= 0:
raise ValueError('timeout must be positive')
atomic_json(root/'config.json',cfg)
worker=root/'worker.py'
worker.write_text(WORKER)
# Configure environment variable before initializing the runtime.
env=dict(os.environ,JAX_PLATFORMS=cfg['backend'],PYTHONUNBUFFERED='1')
started=time.perf_counter()
process=subprocess.Popen([sys.executable,str(worker),str(root)],stdout=subprocess.PIPE,stderr=subprocess.PIPE,text=True,env=env)
timed_out=False
try:
stdout,stderr=process.communicate(timeout=timeout)
except subprocess.TimeoutExpired:
timed_out=True
process.terminate()
try:
stdout,stderr=process.communicate(timeout=1.)
except subprocess.TimeoutExpired:
process.kill()
stdout,stderr=process.communicate(timeout=1.)
wall=time.perf_counter()-started
events=[]
malformed=[]
for line in stdout.splitlines():
if not line.strip():
continue
try:
event=json.loads(line)
if not isinstance(event,dict) or 'event' not in event:
raise ValueError('not an event')
events.append(event)
except (ValueError,TypeError):
malformed.append(line)
status='timed_out' if timed_out else 'completed' if process.returncode == 0 and not malformed and events and events[-1]['event']=='completed' else 'failed'
# Compute deterministic cryptographic digest `result` for provenance verification.
result=dict(status=status,returncode=process.returncode,wall_s=wall,events=events,stderr=stderr,
worker_hash=hashlib.sha256(WORKER.encode()).hexdigest(),config=cfg,malformed_stdout=malformed)
atomic_json(root/'run.json',result)
return result
# Step 4 — Add metric summaries and capacity arithmetic: Keep measured quantities separate from invented planning inputs...
def summarize(result):
updates=[e for e in result['events'] if e['event']=='progress']
checkpoints=[e['step'] for e in result['events'] if e['event']=='checkpoint']
count=sum(e['examples'] for e in updates)
update_s=sum(e['update_s'] for e in updates)
latest=max((e['step'] for e in updates),default=0)
checkpoint=max(checkpoints,default=0)
return dict(status=result['status'],updates=len(updates),examples=count,last_step=latest,checkpoint_step=checkpoint,
uncheckpointed_updates=max(0,latest-checkpoint),update_s=update_s,
update_examples_per_s=count/update_s if update_s else 0.,
job_examples_per_s=count/result['wall_s'] if result['wall_s'] else 0.,
update_duty_fraction=update_s/result['wall_s'] if result['wall_s'] else 0.)
def capacity(measured_job_s, arrivals_per_hour, workers, hourly_rate, reserve_fraction=.25):
"""Illustrative one-job-per-worker plan; inputs are not cloud price discovery."""
values=[measured_job_s,arrivals_per_hour,hourly_rate,reserve_fraction]
# Guard input contract (`any((not math.isfinite(x) for x in values)) or measured_job_s <= 0 or arrivals_per_hour < 0 or (hourly_rate < 0)`) and fail fast if violated.
if any(not math.isfinite(x) for x in values) or measured_job_s <= 0 or arrivals_per_hour < 0 or hourly_rate < 0:
raise ValueError('invalid finite capacity inputs')
# Guard input contract (`not isinstance(workers, int) or isinstance(workers, bool) or workers < 1 or (not 0 <= reserve_fraction < 1)`) and fail fast if violated.
if not isinstance(workers,int) or isinstance(workers,bool) or workers < 1 or not 0 <= reserve_fraction < 1:
raise ValueError('invalid workers or reserve')
offered=arrivals_per_hour*measured_job_s/3600
load=offered/workers
required=max(1,math.ceil(offered/(1-reserve_fraction)))
return dict(offered_worker_hours_per_hour=offered,load_fraction=load,
minimum_workers_with_reserve=required,hourly_budget=workers*hourly_rate,
hypothetical_cost_per_job=measured_job_s*hourly_rate/3600,
within_reserve=load <= 1-reserve_fraction)
# Step 5 — Measure jobs before evaluating assumptions: Every duration comes from a completed child; arrival and price...
samples=[]
# Create an isolated temporary directory to run and inspect artifacts safely:
with tempfile.TemporaryDirectory(prefix='ops-capacity-') as folder:
for steps in [8,32,64]:
run=launch(Path(folder)/str(steps),dict(steps=steps))
assert run['status']=='completed'
samples.append((steps,run,summarize(run)))
measured=max(run['wall_s'] for _,run,_ in samples)
plan=capacity(measured_job_s=measured,arrivals_per_hour=600,workers=2,hourly_rate=1.5,reserve_fraction=.25)
assert plan['hourly_budget']==3.
print('measured local job seconds:',[r['wall_s'] for _,r,_ in samples])
print('illustrative capacity plan:',plan)
print('assumptions: 600 arrivals/hour, 2 workers, hypothetical 1.50 per worker-hour, 25% reserve')Expected result: Three actual local durations feed a first-order plan whose arrival rate, worker count, reserve and price are explicitly hypothetical. No hardware utilization or cloud-cost claim is inferred from CPU timings.
Recorded reference execution
Reference output captured from executing the complete lesson script (code/main.py) and its assertions in the course CPU environment.
measured local job seconds: [0.543132500257343, 0.5599589156918228, 0.5557856247760355]
illustrative capacity plan: {'offered_worker_hours_per_hour': 0.09332648594863713, 'load_fraction': 0.046663242974318564, 'minimum_workers_with_reserve': 1, 'hourly_budget': 3.0, 'hypothetical_cost_per_job': 0.0002333162148715928, 'within_reserve': True}
assumptions: 600 arrivals/hour, 2 workers, hypothetical 1.50 per worker-hour, 25% reserve
measured local job seconds: [0.6144686662591994, 0.5638747080229223, 0.5770753328688443]
illustrative capacity plan: {'offered_worker_hours_per_hour': 0.10241144437653323, 'load_fraction': 0.05120572218826661, 'minimum_workers_with_reserve': 1, 'hourly_budget': 3.0, 'hypothetical_cost_per_job': 0.00025602861094133306, 'within_reserve': True}
assumptions: 600 arrivals/hour, 2 workers, hypothetical 1.50 per worker-hour, 25% reserve
nominal load at two demand scenarios: 0.05120572218826661 0.10241144437653323
required workers under changed hypothetical reserve: 1
PASS: operations-05
Download execution record · The notebook includes executed cells and figure outputs. Compare your run with these values; timings depend on the machine.
Check units with known arithmetic
# Experiment — Check units with known arithmetic: This independent arithmetic checks the calculator without...
known=capacity(90.,80.,4,2.,.25)
assert known['offered_worker_hours_per_hour']==2.
assert known['load_fraction']==.5
assert known['minimum_workers_with_reserve']==3
assert known['hypothetical_cost_per_job']==.05
assert known['hourly_budget']==8.Expected: Demand, load, reserve and cost match a hand calculation.
This independent arithmetic checks the calculator without treating invented inputs as measured infrastructure.
Double the arrivals without changing the job
# Experiment — Double the arrivals without changing the job: Demand changes the required capacity; it does not automatically...
one=capacity(measured,600,2,1.5,.25)
two=capacity(measured,1200,2,1.5,.25)
assert abs(two['load_fraction']-2*one['load_fraction'])<1e-12
assert two['hypothetical_cost_per_job']==one['hypothetical_cost_per_job']
print('nominal load at two demand scenarios:',one['load_fraction'],two['load_fraction'])Expected: Nominal load doubles while per-job active-time cost stays fixed under the same simple model.
Demand changes the required capacity; it does not automatically make each job faster or slower in a model without contention.
Make it yours
Where to put your code: Append your solution at the bottom of phases/16-operations/05-capacity-utilization-and-operating-cost/code/main.py (or inside the Make it yours cell of exercises/operations-05.ipynb) and run python3 phases/16-operations/05-capacity-utilization-and-operating-cost/code/main.py to verify your prediction before opening the reference solution.
Using the measured service-time input, calculate the minimum worker count for arrivals per hour with % reserve, then independently verify that the chosen count satisfies the load bound.
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:
capacity(...)— Callcapacitywith 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:
- Set up the changed input or configuration parameters requested in the prompt.
- Run the target function or transformation and assert that the output matches your prediction.
# Exercise solution: Using the measured service-time input, calculate the minimum worker...
changed = capacity(...) # TODO: compute changed
required = ... # TODO: compute required
demand = ... # TODO: compute demand
assert demand/required # TODO: complete assertion check
if required>1: assert demand/(required-1) > .6
print('required workers under changed hypothetical reserve:',required)
Reveal the reference solution
# Exercise solution: Using the measured service-time input, calculate the minimum worker...
changed=capacity(measured,1200,2,1.5,.4)
required=changed['minimum_workers_with_reserve']
demand=1200*measured/3600
assert demand/required <= .6 + 1e-12
if required>1: assert demand/(required-1) > .6
print('required workers under changed hypothetical reserve:',required)Account for failed attempts
Transfer / diagnosis
Assume completed jobs require equal-duration attempts. Compare active-time cost per attempt with active-time cost per completion.
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:
attempts(...)— Callattemptswith your updated parameters or inputs from this lesson's workspace.abs(...)— Callabswith 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:
- Set up the changed input or configuration parameters requested in the prompt.
- Run the target function or transformation and assert that the output matches your prediction.
# Account for failed attempts (Transfer / diagnosis): Failure overhead belongs in the budget even when it does not...
per_attempt = ... # TODO: compute per_attempt
per_completion = ... # TODO: compute per_completion
assert abs(per_completion-1.25*per_attempt) # TODO: complete assertion check
Show a hint
Every attempt consumes resources under this hypothetical model.
Reveal reference solution and reasoning
# Account for failed attempts (Transfer / diagnosis): Failure overhead belongs in the budget even when it does not...
per_attempt=measured*1.5/3600
per_completion=125*per_attempt/100
assert abs(per_completion-1.25*per_attempt)<1e-12Failure overhead belongs in the budget even when it does not count as successful throughput.
Reject impossible capacity inputs
Transfer / diagnosis
Try a full reserve, zero workers and a nonfinite measured duration.
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:
inputs(...)— Callinputswith your updated parameters or inputs from this lesson's workspace.inputs.update(...)— Callinputs.updatewith your updated parameters or inputs from this lesson's workspace.
2. Step-by-step implementation plan:
- Run the boundary check and catch the expected exception:
# Reject impossible capacity inputs (Transfer / diagnosis): Input validation makes the assumptions visible and prevents...
for change in [dict(reserve_fraction=1.),dict(workers=0),dict(measured_job_s=float('nan'))]:
inputs = dict(...) # TODO: compute inputs
inputs.update(change)
# Run the boundary check and catch the expected exception:
try:capacity(**inputs)
except ValueError:pass
else:raise AssertionError('invalid plan accepted')
Show a hint
A plan should not silently divide by zero or emit a meaningless worker count.
Reveal reference solution and reasoning
# Reject impossible capacity inputs (Transfer / diagnosis): Input validation makes the assumptions visible and prevents...
for change in [dict(reserve_fraction=1.),dict(workers=0),dict(measured_job_s=float('nan'))]:
inputs=dict(measured_job_s=measured,arrivals_per_hour=600,workers=2,hourly_rate=1.5)
inputs.update(change)
# Run the boundary check and catch the expected exception:
try:capacity(**inputs)
except ValueError:pass
else:raise AssertionError('invalid plan accepted')Input validation makes the assumptions visible and prevents numeric output from looking authoritative when the inputs are invalid.
Diagnose the result
If estimated cost is unexpectedly low, check seconds-to-hours conversion, idle reserved capacity and repeated failed attempts. If worker count looks sufficient but latency is poor, inspect burstiness and service-time variation. If longer jobs look faster per example, separate startup amortization from changes in the compiled update itself.
Carry forward
- Carry units and assumptions through every capacity calculation.
- Measured local duration can inform a bounded model without pretending to establish fleet performance.
Keep your evidence
Keep measured job/update samples and independent unit calculations. Label demand, reserve and price assumptions as hypothetical before deriving a resource plan.
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).