# Run your own code

> Run a training script from your own directory on a GPU with nodus run, follow it, download its output and read what it cost.

Source: https://nodus-platform-site.pages.dev/docs/getting-started/quickstart/
Build revision: 211ad9f836655b1c3a2668c4693e442471f28614

This page runs a script from your own directory on a GPU, then downloads the file it wrote. It assumes you have [installed the CLI and signed in](https://nodus-platform-site.pages.dev/docs/getting-started/install/). Every command here runs in CI as the `cli/quickstart` example.

1. **Put your code in a directory.** Any directory works; this one holds a small PyTorch training loop that saves its final metrics to `/nodus/outputs/metrics.json`.

   train.py

   ```python
   """Fit a small linear model, print progress and save metrics.json as the declared output "metrics"."""

   import json
   import pathlib

   import torch

   device = "cuda" if torch.cuda.is_available() else "cpu"
   print("device:", torch.cuda.get_device_name() if device == "cuda" else "cpu")

   torch.manual_seed(0)
   x = torch.randn(1024, 16, device=device)
   y = x @ torch.randn(16, 1, device=device)
   w = torch.zeros(16, 1, device=device, requires_grad=True)
   opt = torch.optim.SGD([w], lr=0.1)

   for step in range(200):
       loss = ((x @ w - y) ** 2).mean()
       opt.zero_grad()
       loss.backward()
       opt.step()
       if step % 50 == 0:
           print(f"step {step} loss {loss.item():.4f}")

   print(f"final loss {loss.item():.6f}")
   out = pathlib.Path("/nodus/outputs")
   out.mkdir(parents=True, exist_ok=True)
   (out / "metrics.json").write_text(json.dumps({"final_loss": loss.item(), "steps": 200}))
   ```

2. **Run it.** From that directory:

   Terminal window

   ```sh
   nodus run --name cli-quickstart --gpu L4 --image nodus/pytorch \
     --output metrics=/nodus/outputs/metrics.json -- python train.py
   ```

   Terminal window

   ```console
   job/cli-quickstart created · est. $0.01–0.03 · starts in ~2–4 min (cold) · hold $0.50 · Ctrl+C to cancel, -d to detach
    ✓ Scheduled      l4-24g-x1-us · $0.52/h (rate frozen)
    ✓ Provisioning   1m48s
    ▶ Running
   device: NVIDIA L4
   step 0 loss 15.8732
   ...
   final loss 0.000001
    ✓ Succeeded in 2m31s · $0.02 (boot $0.01 · running $0.01) · kept warm 60 s · nodus describe job/cli-quickstart
   ```

   Before anything is charged you see the estimate and a hold: the most this run can cost before you are asked. `nodus run` then uploads the directory (files listed in `.gitignore` or `.nodusignore` stay local), prints each phase, streams your program’s output on stdout and ends with the cost line. The CLI exits with your command’s exit code, so it works in scripts and CI.

3. **Get the output.** The `--output` flag declared `metrics`; copy it back:

   Terminal window

   ```sh
   nodus cp job/cli-quickstart:outputs/metrics metrics.json
   ```

   The file is checked against its SHA-256 digest and only written when it matches.

## Leave it running

Press **Ctrl+C** during a run and the CLI asks whether to cancel the Job; answer `n` to detach and leave it running. Or start with `-d` to return as soon as the Job exists. A detached Job keeps running:

Terminal window

```sh
nodus get jobs                        # every Job in the project, with phase and cost so far
nodus get jobs --mine -w              # only yours, updating live
nodus logs -f job/cli-quickstart      # stream the output again
nodus describe job/cli-quickstart     # attempts, placement, cost, conditions and events
nodus cancel job/cli-quickstart       # stop it; you pay only for what ran
```

## Control the cost

|Flag|Effect|
|-|-|
|`--max-cost 5`|The Job stops gracefully before it spends more than $5|
|`--timeout 2h`|The Job is stopped after two hours of wall-clock time|
|`--dry-run`|Print the estimate and exit without creating anything|

`nodus billing` shows your balance and this month’s spend; `nodus billing usage --group-by day` breaks it down.

Exit codes

`nodus run` exits with your command’s own exit code. It exits `125` when Nodus could not run the command (an API error or an invalid request), `124` on `--timeout` and `130` when you interrupt it.

## Clean up

Finished Jobs are kept for 30 days so you can read their logs and outputs, then deleted. To delete one now:

Terminal window

```sh
nodus delete job/cli-quickstart
```

## Next steps

* [Nodus for kubectl users](https://nodus-platform-site.pages.dev/docs/getting-started/kubectl-users/): manifests, `apply`, `get -o`, `wait` and `diff`.
* [CLI reference](https://nodus-platform-site.pages.dev/docs/reference/cli/): every command and flag, with tested examples.
