Skip to content

Commit c648782

Browse files
committed
Add demos
1 parent 62fe102 commit c648782

7 files changed

Lines changed: 343 additions & 19 deletions

File tree

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#!/usr/bin/env python3
2+
"""GPU benchmark script for testing PyTorch CUDA capabilities.
3+
4+
Used by ``demo-gpu-dbg.yml``.
5+
"""
6+
7+
import sys
8+
import time
9+
import torch
10+
11+
12+
def main():
13+
print(f'PyTorch version: {torch.__version__}')
14+
print(f'CUDA available: {torch.cuda.is_available()}')
15+
16+
if not torch.cuda.is_available():
17+
print('ERROR: CUDA not available!')
18+
sys.exit(1)
19+
20+
# Get GPU information
21+
device = torch.cuda.get_device_properties(0)
22+
print(f'GPU: {device.name}')
23+
print(f'Memory: {device.total_memory / 1e9:.1f} GB')
24+
print(f'CUDA version: {torch.version.cuda}')
25+
26+
# Matrix multiplication benchmark
27+
print('\nRunning matrix multiplication benchmark...')
28+
size = 8192
29+
x = torch.randn(size, size, dtype=torch.float32).cuda()
30+
torch.cuda.synchronize()
31+
32+
# Warmup
33+
print(' Warming up...')
34+
for _ in range(3):
35+
_ = torch.matmul(x, x.T)
36+
torch.cuda.synchronize()
37+
38+
# Benchmark
39+
print(' Running benchmark...')
40+
start = time.time()
41+
y = torch.matmul(x, x.T)
42+
torch.cuda.synchronize()
43+
elapsed = time.time() - start
44+
45+
gflops = (2 * size**3) / (elapsed * 1e9)
46+
print(f' Matrix size: {size}x{size}')
47+
print(f' Time: {elapsed:.3f} seconds')
48+
print(f' Performance: {gflops:.1f} GFLOPS')
49+
print(f' Memory used: {torch.cuda.max_memory_allocated()/1e9:.2f} GB')
50+
51+
# Quick training simulation
52+
print('\nSimulating model training...')
53+
model = torch.nn.Sequential(
54+
torch.nn.Linear(1024, 512),
55+
torch.nn.ReLU(),
56+
torch.nn.Linear(512, 256),
57+
torch.nn.ReLU(),
58+
torch.nn.Linear(256, 10)
59+
).cuda()
60+
61+
optimizer = torch.optim.Adam(model.parameters())
62+
data = torch.randn(32, 1024).cuda()
63+
64+
for i in range(10):
65+
output = model(data)
66+
loss = output.sum()
67+
loss.backward()
68+
optimizer.step()
69+
optimizer.zero_grad()
70+
if i == 0 or i == 9:
71+
print(f' Iteration {i+1}: loss = {loss.item():.4f}')
72+
73+
print('\nGPU workload completed successfully!')
74+
return 0
75+
76+
77+
if __name__ == '__main__':
78+
sys.exit(main())
Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,17 @@
11
name: Demo – minimal EC2 GPU runner
22
on:
33
workflow_dispatch:
4+
workflow_call: # Tested by `demos.yml`
5+
permissions:
6+
id-token: write # Required for AWS OIDC authentication
7+
contents: read # Required for actions/checkout
48
jobs:
5-
placeholder:
6-
runs-on: ubuntu-latest
9+
ec2:
10+
# To use from another repo: Open-Athena/ec2-gha/.github/workflows/runner.yml
11+
uses: ./.github/workflows/runner.yml
12+
secrets: inherit
13+
gpu-test:
14+
needs: ec2
15+
runs-on: ${{ needs.ec2.outputs.id }}
716
steps:
8-
- run: echo "Placeholder workflow – being developed in \#2 / rw/hooks branch"
17+
- run: nvidia-smi # Verify GPU is available

.github/workflows/demo-archs.yml

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,70 @@
11
name: Demo – 2 GPU instances with different architectures
22
on:
33
workflow_dispatch:
4+
workflow_call: # Tested by `demos.yml`
5+
permissions:
6+
id-token: write # Required for AWS OIDC authentication
7+
contents: read # Required for actions/checkout
48
jobs:
5-
placeholder:
6-
runs-on: ubuntu-latest
9+
# Launch EC2 runners for each instance type
10+
g4dn:
11+
name: Launch g4dn
12+
uses: ./.github/workflows/runner.yml
13+
with:
14+
ec2_instance_type: g4dn.xlarge
15+
secrets: inherit
16+
g4ad:
17+
name: Launch g4ad
18+
uses: ./.github/workflows/runner.yml
19+
with:
20+
ec2_instance_type: g4ad.xlarge
21+
secrets: inherit
22+
23+
# Run jobs directly on launched instances
24+
test-g4dn:
25+
needs: g4dn
26+
if: needs.g4dn.outputs.id != ''
27+
name: Test g4dn
28+
runs-on: ${{ needs.g4dn.outputs.id }}
729
steps:
8-
- run: echo "Placeholder workflow – being developed in \#2 / rw/hooks branch"
30+
- name: GPU test on g4dn.xlarge
31+
run: nvidia-smi # Verify GPU is available
32+
test-g4ad:
33+
needs: g4ad
34+
if: needs.g4ad.outputs.id != ''
35+
name: Test g4ad
36+
runs-on: ${{ needs.g4ad.outputs.id }}
37+
steps:
38+
- name: GPU test on g4ad.xlarge
39+
run: |
40+
lspci | grep -i "vga\|display\|3d\|amd"
41+
42+
# Use a `matrix` to run jobs on multiple instances
43+
test-matrix:
44+
needs: [g4dn, g4ad]
45+
if: always() && (needs.g4dn.outputs.id != '' || needs.g4ad.outputs.id != '')
46+
name: Test ${{ matrix.instance }} (matrix)
47+
continue-on-error: true
48+
strategy:
49+
matrix:
50+
include:
51+
- instance: g4dn
52+
runner: ${{ needs.g4dn.outputs.id }}
53+
- instance: g4ad
54+
runner: ${{ needs.g4ad.outputs.id }}
55+
fail-fast: false
56+
runs-on: ${{ matrix.runner }}
57+
steps:
58+
- name: Matrix GPU test on ${{ matrix.instance }}.xlarge
59+
run: |
60+
echo "Running on ${{ matrix.instance }}.xlarge"
61+
echo "Instance type: $(curl -s http://169.254.169.254/latest/meta-data/instance-type)"
62+
63+
# Check GPU based on instance type
64+
if [[ "${{ matrix.instance }}" == "g4dn" ]]; then
65+
echo "Testing NVIDIA GPU..."
66+
nvidia-smi
67+
elif [[ "${{ matrix.instance }}" == "g4ad" ]]; then
68+
echo "Testing AMD GPU..."
69+
lspci | grep -i "vga\|display\|3d\|amd"
70+
fi

.github/workflows/demo-gpu-dbg.yml

Lines changed: 69 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,74 @@
11
name: Demo – toy GPU workload, optional sleep (for debugging)
22
on:
33
workflow_dispatch:
4+
inputs:
5+
sleep:
6+
description: "Sleep for this many seconds before completing job (optional, helps keep instance alive for SSH access and debugging)"
7+
required: false
8+
type: number
9+
default: 0
10+
ssh_pubkey:
11+
description: "Add this SSH public key to instance's `~/.ssh/authorized_keys` (optional, for debugging)"
12+
required: false
13+
type: string
14+
workflow_call: # Tested by `demos.yml`
15+
inputs:
16+
sleep:
17+
required: false
18+
type: number
19+
default: 0
20+
ssh_pubkey:
21+
required: false
22+
type: string
23+
24+
permissions:
25+
id-token: write # Required for AWS OIDC authentication
26+
contents: read # Required for actions/checkout
27+
428
jobs:
5-
placeholder:
6-
runs-on: ubuntu-latest
29+
ec2:
30+
uses: ./.github/workflows/runner.yml
31+
secrets: inherit
32+
with:
33+
ssh_pubkey: ${{ inputs.ssh_pubkey }}
34+
35+
gpu-workload:
36+
needs: ec2
37+
runs-on: ${{ needs.ec2.outputs.id }}
738
steps:
8-
- run: echo "Placeholder workflow – being developed in \#2 / rw/hooks branch"
39+
- uses: actions/checkout@v4
40+
41+
- name: System info
42+
run: |
43+
echo "=== System Info ==="
44+
uname -a
45+
lscpu | grep "Model name" || true
46+
free -h
47+
48+
echo -e "\n=== GPU Info ==="
49+
nvidia-smi --query-gpu=name,memory.total,driver_version --format=csv
50+
51+
- name: Install PyTorch with CUDA support
52+
run: |
53+
echo "=== Installing PyTorch with CUDA support ==="
54+
# Install python3-venv if not available
55+
sudo apt-get update && sudo apt-get install -y python3-venv
56+
# Use system Python3 and create a virtual environment to avoid pip root warning
57+
python3 --version
58+
python3 -m venv /tmp/venv
59+
source /tmp/venv/bin/activate
60+
pip install torch --index-url https://download.pytorch.org/whl/cu121
61+
echo "PyTorch installed successfully"
62+
63+
- name: Run PyTorch GPU benchmark
64+
run: |
65+
echo "=== PyTorch GPU Benchmark ==="
66+
source /tmp/venv/bin/activate
67+
python .github/test-scripts/gpu-benchmark.py
68+
69+
- name: Sleep (${{ inputs.sleep }}s)
70+
if: ${{ inputs.sleep > 0 }}
71+
run: |
72+
echo "Sleeping for ${{ inputs.sleep }} seconds (useful for SSH debugging)..."
73+
echo "Instance will remain available at the IP shown in the GitHub Actions log"
74+
sleep ${{ inputs.sleep }}

.github/workflows/demo-job-seq.yml

Lines changed: 71 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,76 @@
11
name: Demo – multiple jobs on one EC2 instance, in sequence
2+
# Tests that multiple jobs can run sequentially on the same EC2 instance
23
on:
34
workflow_dispatch:
5+
inputs:
6+
sleep:
7+
description: "Sleep this many seconds at the end of the `prepare`, `train`, and `eval` jobs (optional, for SSH access and debugging)"
8+
required: false
9+
type: number
10+
default: 0
11+
workflow_call: # Tested by `demos.yml`
12+
inputs:
13+
sleep:
14+
required: false
15+
type: number
16+
default: 0
17+
18+
permissions:
19+
id-token: write
20+
contents: read
21+
422
jobs:
5-
placeholder:
6-
runs-on: ubuntu-latest
23+
ec2:
24+
uses: ./.github/workflows/runner.yml
25+
secrets: inherit
26+
27+
prepare:
28+
needs: ec2
29+
runs-on: ${{ needs.ec2.outputs.id }}
30+
outputs:
31+
gpu-uuid: ${{ steps.gpu-info.outputs.uuid }}
732
steps:
8-
- run: echo "Placeholder workflow – being developed in \#2 / rw/hooks branch"
33+
- name: Get GPU info
34+
id: gpu-info
35+
run: |
36+
echo "=== Preparing GPU environment ==="
37+
nvidia-smi
38+
uuid=$(nvidia-smi --query-gpu=gpu_uuid --format=csv,noheader)
39+
echo "uuid=$uuid" >> $GITHUB_OUTPUT
40+
echo "GPU UUID: $uuid"
41+
42+
- name: Sleep (${{ inputs.sleep }}s)
43+
if: ${{ inputs.sleep > 0 }}
44+
run: sleep ${{ inputs.sleep }}
45+
46+
train:
47+
needs: [ec2, prepare]
48+
runs-on: ${{ needs.ec2.outputs.id }}
49+
steps:
50+
- name: Verify same GPU
51+
run: |
52+
echo "=== Training model on GPU ==="
53+
current_uuid=$(nvidia-smi --query-gpu=gpu_uuid --format=csv,noheader)
54+
if [[ "$current_uuid" == "${{ needs.prepare.outputs.gpu-uuid }}" ]]; then
55+
echo "✅ Confirmed: Using same GPU as preparation job"
56+
else
57+
echo "❌ ERROR: Different GPU!"
58+
exit 1
59+
fi
60+
61+
- name: Sleep (${{ inputs.sleep }}s)
62+
if: ${{ inputs.sleep > 0 }}
63+
run: sleep ${{ inputs.sleep }}
64+
65+
eval:
66+
needs: [ec2, train]
67+
runs-on: ${{ needs.ec2.outputs.id }}
68+
steps:
69+
- name: Final validation
70+
run: |
71+
echo "=== Evaluation complete ==="
72+
nvidia-smi
73+
74+
- name: Sleep (${{ inputs.sleep }}s)
75+
if: ${{ inputs.sleep > 0 }}
76+
run: sleep ${{ inputs.sleep }}
Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,35 @@
11
name: Demo – matrix on single runner
22
on:
33
workflow_dispatch:
4+
workflow_call: # Tested by `demos.yml`
5+
permissions:
6+
id-token: write # Required for AWS OIDC authentication
7+
contents: read # Required for actions/checkout
48
jobs:
5-
placeholder:
6-
runs-on: ubuntu-latest
9+
ec2:
10+
uses: ./.github/workflows/runner.yml
11+
secrets: inherit
12+
test-matrix:
13+
needs: ec2
14+
runs-on: ${{ needs.ec2.outputs.id }}
15+
name: Test on ${{ matrix.os }}
16+
strategy:
17+
matrix:
18+
os: [ubuntu-20.04, ubuntu-22.04, ubuntu-24.04]
719
steps:
8-
- run: echo "Placeholder workflow – being developed in \#2 / rw/hooks branch"
20+
- name: Test on ${{ matrix.os }}
21+
run: |
22+
echo "Testing on ${{ matrix.os }}"
23+
echo "Runner: $(hostname)"
24+
echo "Time: $(date)"
25+
echo "Simulating work..."
26+
sleep 10
27+
echo "Done!"
28+
- name: Show system info
29+
run: |
30+
echo "=== System Information ==="
31+
uname -a
32+
echo "=== CPU Info ==="
33+
lscpu | head -10
34+
echo "=== Memory Info ==="
35+
free -h

.github/workflows/demos.yml

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,22 @@
11
name: Run All Demos
22
on:
33
workflow_dispatch:
4+
permissions:
5+
id-token: write
6+
contents: read
47
jobs:
5-
placeholder:
6-
runs-on: ubuntu-latest
7-
steps:
8-
- run: echo "Placeholder workflow – being developed in \#2 / rw/hooks branch"
8+
demo-00-minimal:
9+
uses: ./.github/workflows/demo-00-minimal.yml
10+
secrets: inherit
11+
demo-job-seq:
12+
uses: ./.github/workflows/demo-job-seq.yml
13+
secrets: inherit
14+
demo-gpu-dbg:
15+
uses: ./.github/workflows/demo-gpu-dbg.yml
16+
secrets: inherit
17+
demo-archs:
18+
uses: ./.github/workflows/demo-archs.yml
19+
secrets: inherit
20+
demo-matrix-wide:
21+
uses: ./.github/workflows/demo-matrix-wide.yml
22+
secrets: inherit

0 commit comments

Comments
 (0)