Writing Custom Recipes¶
Create custom recipes for new services or specialized benchmark configurations.
Creating a Service Recipe¶
Step 1: Basic Structure¶
# recipes/services/my_service.yaml
service:
name: my_service
description: "Description of my service"
container:
docker_source: docker://myimage:tag
image_path: $HOME/containers/my_service.sif
resources:
cpus_per_task: 4
mem: "8G"
time: "02:00:00"
partition: cpu
environment:
MY_VAR: "value"
ports:
- 8080
Step 2: Test the Recipe¶
# Validate and run
python main.py --verbose --recipe recipes/services/my_service.yaml
# Check it started
python main.py --status
Step 3: Add Monitoring (Optional)¶
Creating a Client Recipe¶
Step 1: Choose Client Type¶
Use an existing client type or create a new one:
| Type | For Service |
|---|---|
ollama_benchmark |
Ollama LLM |
redis_benchmark |
Redis |
chroma_benchmark |
Chroma |
mysql_benchmark |
MySQL |
Step 2: Define Parameters¶
# recipes/clients/my_benchmark.yaml
client:
name: my_benchmark
type: redis_benchmark # Use existing type
parameters:
clients: 100
requests: 50000
data_size: 512
tests: "SET,GET,HSET,HGET"
output_file: "$HOME/results/my_benchmark.json"
resources:
cpus_per_task: 2
mem: "4G"
time: "00:30:00"
Step 3: Run the Benchmark¶
Advanced: Custom Service Class¶
For completely new services, create a Python class:
Step 1: Create Service Class¶
# src/services/my_service.py
from .base import Service
from ..base import JobFactory
class MyService(Service):
"""My custom service implementation"""
def __init__(self, config: dict):
super().__init__(config)
self.my_option = config.get('my_option', 'default')
def get_service_setup_commands(self):
"""Custom setup commands"""
commands = super().get_service_setup_commands()
commands.extend([
f"export MY_OPTION={self.my_option}",
"mkdir -p $HOME/my_service/data",
])
return commands
def get_container_command(self):
"""Custom container execution"""
return f"""
apptainer exec \\
--bind $HOME/my_service/data:/data \\
{self._resolve_container_path()} \\
my_service_command --port 8080 &
"""
# Register with factory
JobFactory.register_service('my_service', MyService)
Step 2: Register in __init__.py¶
Step 3: Create Recipe¶
# recipes/services/my_service.yaml
service:
name: my_service
my_option: "custom_value"
container:
docker_source: docker://myimage:tag
image_path: $HOME/containers/my_service.sif
resources:
cpus_per_task: 4
mem: "8G"
Recipe Validation¶
Recipes are validated for:
- Required fields:
name,container.docker_source - Valid types: Resource values, partition names
- Path resolution:
$HOME,$SCRATCHvariables - Port conflicts: Unique port assignments
Tips for Custom Recipes¶
Start Simple
Begin with minimal configuration and add options as needed.
Test Locally First
If possible, test container commands locally before deploying.
Use Existing Templates
Copy and modify existing recipes rather than starting from scratch.
Resource Limits
Be mindful of HPC allocation limits when setting resources.
Debugging Recipes¶
# Verbose mode shows generated script
python main.py --verbose --recipe recipes/services/my_service.yaml
# View generated script
cat scripts/service_my_service_*.sh
# Check SLURM logs
ssh meluxina "cat slurm-*.out"
See also: Services Overview | Development Guide