Skip to content
2 changes: 2 additions & 0 deletions net_maestro/core/admin/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from .event_record import EventRecordAdmin
from .model_file import ModelFileAdmin
from .model_record import ModelRecordAdmin
from .phold_simulation_config import PHOLDSimulationConfigAdmin
from .phold_simulation_lp_record import PHOLDSimulationLpRecordAdmin
from .run import RunAdmin
from .simulation_file import SimulationFileAdmin
Expand All @@ -16,6 +17,7 @@
"EventRecordAdmin",
"ModelFileAdmin",
"ModelRecordAdmin",
"PHOLDSimulationConfigAdmin",
"PHOLDSimulationLpRecordAdmin",
"RunAdmin",
"SimulationFileAdmin",
Expand Down
13 changes: 13 additions & 0 deletions net_maestro/core/admin/phold_simulation_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from __future__ import annotations

from django.contrib import admin

from net_maestro.core.models import PHOLDSimulationConfig


@admin.register(PHOLDSimulationConfig)
class PHOLDSimulationConfigAdmin(admin.ModelAdmin):
list_select_related = ["run"]
list_display = ["id", "run", "synch", "nlp", "remote", "mean", "lookahead"]
list_filter = ["synch", "stagger"]
search_fields = ["run__name"]
10 changes: 10 additions & 0 deletions net_maestro/core/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@


class RunStatus(models.TextChoices):
SAVED = "saved"
PENDING = "pending"
RUNNING = "running"
COMPLETED = "completed"
Expand All @@ -24,3 +25,12 @@ class ModelType(models.TextChoices):

class TrafficType(models.TextChoices):
UNIFORM = "uniform"


class SynchProtocol(models.IntegerChoices):
SEQUENTIAL = 1, "Sequential"
CONSERVATIVE = 2, "Conservative"
OPTIMISTIC = 3, "Optimistic"
OPTIMISTIC_DEBUG = 4, "Optimistic Debug"
OPTIMISTIC_REALTIME = 5, "Optimistic Realtime"
REVERSE_HANDLER_CHECK = 6, "Reverse Handler Check"
143 changes: 66 additions & 77 deletions net_maestro/core/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,96 +2,85 @@

from __future__ import annotations

from typing import Any

from django import forms
from django.core.validators import MaxValueValidator, MinValueValidator

from .models import PHOLDSimulationConfig


class PHOLDSimulationForm(forms.ModelForm):
"""Form for PHOLD simulation parameters.

class PHOLDSimulationForm(forms.Form):
"""Form for PHOLD simulation parameters."""
A ModelForm bound to PHOLDSimulationConfig so field validators are not duplicated
between the model and a plain Form.
"""

# Simulation Model section
# run_identifier maps to Run.name, not a PHOLDSimulationConfig field,
# so it must be declared explicitly.
run_identifier = forms.CharField(
label="Run Identifier",
max_length=200,
required=True,
widget=forms.TextInput(attrs={"class": "input input-bordered w-full"}),
)

# Engine Parameters
synch = forms.ChoiceField(
label="Synchronization Protocol",
choices=[
(1, "Sequential"),
(2, "Conservative"),
(3, "Optimistic"),
(4, "Optimistic Debug"),
(5, "Optimistic Realtime"),
(6, "Reverse Handler Check"),
],
initial=3,
widget=forms.Select(attrs={"class": "select select-bordered w-full"}),
)

avl_size = forms.IntegerField(
label="AVL Tree Size",
initial=18,
validators=[MinValueValidator(10), MaxValueValidator(24)],
widget=forms.NumberInput(attrs={"class": "input input-bordered w-full"}),
)

# Model Parameters
nlp = forms.IntegerField(
label="LPs per Processor",
initial=8,
validators=[MinValueValidator(1)],
widget=forms.NumberInput(attrs={"class": "input input-bordered w-full"}),
)

remote = forms.FloatField(
label="Remote Event Rate",
initial=0.25,
validators=[MinValueValidator(0.0), MaxValueValidator(1.0)],
widget=forms.NumberInput(attrs={"class": "input input-bordered w-full", "step": "0.01"}),
)

mean = forms.FloatField(
label="Mean Timestamp",
initial=1.0,
validators=[MinValueValidator(0.1)],
widget=forms.NumberInput(attrs={"class": "input input-bordered w-full", "step": "0.1"}),
)

mult = forms.FloatField(
label="Memory Multiplier",
initial=1.4,
validators=[MinValueValidator(1.0)],
widget=forms.NumberInput(attrs={"class": "input input-bordered w-full", "step": "0.1"}),
)

lookahead = forms.FloatField(
label="Lookahead",
initial=1.0,
validators=[MinValueValidator(0.1)],
widget=forms.NumberInput(attrs={"class": "input input-bordered w-full", "step": "0.1"}),
)

start_events = forms.IntegerField(
label="Start Events per LP",
initial=1,
validators=[MinValueValidator(1)],
widget=forms.NumberInput(attrs={"class": "input input-bordered w-full"}),
)

memory = forms.IntegerField(
label="Additional Memory Buffers",
initial=100,
validators=[MinValueValidator(0)],
widget=forms.NumberInput(attrs={"class": "input input-bordered w-full"}),
)

stagger = forms.ChoiceField(
# Rendered as a Select (Yes/No) rather than the default checkbox widget.
stagger = forms.TypedChoiceField(
label="Stagger Events",
choices=[(0, "No"), (1, "Yes")],
coerce=lambda value: str(value) == "1",
initial=0,
widget=forms.Select(attrs={"class": "select select-bordered w-full"}),
)

class Meta:
model = PHOLDSimulationConfig
fields = [
"synch",
"avl_size",
"nlp",
"remote",
"mean",
"mult",
"lookahead",
"start_events",
"memory",
"stagger",
]
labels = {
"synch": "Synchronization Protocol",
"avl_size": "AVL Tree Size",
"nlp": "LPs per Processor",
"remote": "Remote Event Rate",
"mean": "Mean Timestamp",
"mult": "Memory Multiplier",
"start_events": "Start Events per LP",
"memory": "Additional Memory Buffers",
}
widgets = {
"synch": forms.Select(attrs={"class": "select select-bordered w-full"}),
"avl_size": forms.NumberInput(attrs={"class": "input input-bordered w-full"}),
"nlp": forms.NumberInput(attrs={"class": "input input-bordered w-full"}),
"remote": forms.NumberInput(
attrs={"class": "input input-bordered w-full", "step": "0.01"}
),
"mean": forms.NumberInput(
attrs={"class": "input input-bordered w-full", "step": "0.1"}
),
"mult": forms.NumberInput(
attrs={"class": "input input-bordered w-full", "step": "0.1"}
),
"lookahead": forms.NumberInput(
attrs={"class": "input input-bordered w-full", "step": "0.1"}
),
"start_events": forms.NumberInput(attrs={"class": "input input-bordered w-full"}),
"memory": forms.NumberInput(attrs={"class": "input input-bordered w-full"}),
}

def __init__(self, *args: Any, **kwargs: Any) -> None:
super().__init__(*args, **kwargs)
# model_to_dict() surfaces the model's boolean value for stagger,
# but the widget's choices are keyed by 0/1.
if "stagger" in self.initial:
self.initial["stagger"] = int(bool(self.initial["stagger"]))
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
# Generated by Django 6.0.6 on 2026-07-07 14:07
from __future__ import annotations

import django.core.validators
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):
dependencies = [
("core", "0009_pholdsimulationlprecord"),
]

operations = [
migrations.AlterField(
model_name="run",
name="status",
field=models.CharField(
choices=[
("saved", "Saved"),
("pending", "Pending"),
("running", "Running"),
("completed", "Completed"),
("failed", "Failed"),
("cancelled", "Cancelled"),
],
default="saved",
max_length=20,
),
),
migrations.CreateModel(
name="PHOLDSimulationConfig",
fields=[
(
"id",
models.BigAutoField(
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
),
),
(
"synch",
models.IntegerField(
choices=[
(1, "Sequential"),
(2, "Conservative"),
(3, "Optimistic"),
(4, "Optimistic Debug"),
(5, "Optimistic Realtime"),
(6, "Reverse Handler Check"),
],
default=3,
verbose_name="Synchronization protocol",
),
),
(
"avl_size",
models.IntegerField(
default=18,
validators=[
django.core.validators.MinValueValidator(10),
django.core.validators.MaxValueValidator(24),
],
verbose_name="AVL tree size",
),
),
(
"nlp",
models.IntegerField(
default=8,
validators=[django.core.validators.MinValueValidator(1)],
verbose_name="LPs per processor",
),
),
(
"remote",
models.FloatField(
default=0.25,
validators=[
django.core.validators.MinValueValidator(0.0),
django.core.validators.MaxValueValidator(1.0),
],
verbose_name="Remote event rate",
),
),
(
"mean",
models.FloatField(
default=1.0,
validators=[django.core.validators.MinValueValidator(0.1)],
verbose_name="Mean timestamp",
),
),
(
"mult",
models.FloatField(
default=1.4,
validators=[django.core.validators.MinValueValidator(1.0)],
verbose_name="Memory multiplier",
),
),
(
"lookahead",
models.FloatField(
default=1.0, validators=[django.core.validators.MinValueValidator(0.1)]
),
),
(
"start_events",
models.IntegerField(
default=1,
validators=[django.core.validators.MinValueValidator(1)],
verbose_name="Start events per LP",
),
),
(
"memory",
models.IntegerField(
default=100,
validators=[django.core.validators.MinValueValidator(0)],
verbose_name="Additional memory buffers",
),
),
("stagger", models.BooleanField(default=False)),
(
"run",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="phold_configs",
to="core.run",
),
),
],
),
]
2 changes: 2 additions & 0 deletions net_maestro/core/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from .event_record import EventRecord
from .model_file import ModelFile
from .model_record import ModelRecord
from .phold_simulation_config import PHOLDSimulationConfig
from .run import Run
from .simulation_base_record import SimulationBaseRecord
from .simulation_file import SimulationFile
Expand All @@ -16,6 +17,7 @@
"EventRecord",
"ModelFile",
"ModelRecord",
"PHOLDSimulationConfig",
"PHOLDSimulationLpRecord",
"Run",
"SimulationBaseRecord",
Expand Down
Loading