Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions src/dvsim/flow/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -458,11 +458,20 @@ def gen_results(self, results: Sequence[CompletedJobStatus]) -> None:
all_flow_results: Mapping[str, FlowResults] = {}

for item in self.cfgs:
project = item.name
item_results = [r for r in results if r.project == project]
item_results = [
res
for res in results
if res.block.name == item.name and res.block.variant == item.variant
]

flow_results: FlowResults = item._gen_json_results(item_results)
all_flow_results[project] = flow_results

# Convert to lowercase to match filename
block_result_index = (
f"{item.name}_{item.variant}" if item.variant else item.name
).lower()

all_flow_results[block_result_index] = flow_results

# Write results to the report area.
gen_block_report(
Expand Down Expand Up @@ -498,7 +507,6 @@ def gen_results(self, results: Sequence[CompletedJobStatus]) -> None:
url=self.revision,
),
timestamp=timestamp,
report_index={item.name: f"{item.name}.html" for item in self.cfgs},
flow_results=all_flow_results,
report_path=reports_dir,
)
Expand Down
31 changes: 17 additions & 14 deletions src/dvsim/job/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from pydantic import BaseModel, ConfigDict

from dvsim.launcher.base import ErrorMessage, Launcher
from dvsim.report.data import IPMeta, ToolMeta

__all__ = (
"CompletedJobStatus",
Expand All @@ -28,8 +29,6 @@ class WorkspaceConfig(BaseModel):

model_config = ConfigDict(frozen=True, extra="forbid")

project: str
"""Name of the project"""
timestamp: str
"""Time stamp of the run."""

Expand All @@ -46,32 +45,31 @@ class JobSpec(BaseModel):

model_config = ConfigDict(frozen=True, extra="forbid")

name: str
"""Name of the job"""

job_type: str
"""Deployment type"""

target: str
"""run phase [build, run, ...]"""
flow: str
"""Name of the flow config (e.g. tl_agent)"""
tool: str
"""EDA tool used"""

name: str
"""Name of the job"""
seed: int | None
"""Seed if there is one."""

full_name: str
"""Full name disambiguates across multiple cfg being run (example:
'aes:default', 'uart:default' builds.
"""

qual_name: str
"""Qualified name disambiguates the instance name with other instances
of the same class (example: 'uart_smoke' reseeded multiple times
needs to be disambiguated using the index -> '0.uart_smoke'.
"""

block: IPMeta
"""IP block metadata."""
tool: ToolMeta
"""Tool used in the simulation run."""
workspace_cfg: WorkspaceConfig
"""Workspace configuration."""

Expand Down Expand Up @@ -119,15 +117,20 @@ class CompletedJobStatus(BaseModel):

model_config = ConfigDict(frozen=True, extra="forbid")

project: str
"""Name of the project"""
job_type: str
"""Deployment type"""
name: str
"""Name of the job"""
job_type: str
"""Deployment type"""
seed: int | None
"""Seed if there is one."""

block: IPMeta
"""IP block metadata."""
tool: ToolMeta
"""Tool used in the simulation run."""
workspace_cfg: WorkspaceConfig
"""Workspace configuration."""

full_name: str
"""Full name disambiguates across multiple cfg being run (example:
'aes:default', 'uart:default' builds.
Expand Down
39 changes: 23 additions & 16 deletions src/dvsim/job/deploy.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from dvsim.job.time import JobTime
from dvsim.launcher.base import Launcher
from dvsim.logging import log
from dvsim.report.data import IPMeta, ToolMeta
from dvsim.tool.utils import get_sim_tool_plugin
from dvsim.utils import (
clean_odirs,
Expand Down Expand Up @@ -101,40 +102,46 @@ def __init__(self, sim_cfg: "SimCfg") -> None:
# Construct the job's command.
self.cmd = self._construct_cmd()

self.workspace_cfg = WorkspaceConfig(
project=sim_cfg.name,
project_root=sim_cfg.proj_root,
scratch_root=Path(sim_cfg.scratch_root),
scratch_path=Path(sim_cfg.scratch_path),
timestamp=sim_cfg.args.timestamp,
)

def get_job_spec(self) -> "JobSpec":
"""Get the job spec for this deployment."""
return JobSpec(
name=self.name,
job_type=self.__class__.__name__,
target=self.target,
flow=self.flow,
tool=self.sim_cfg.tool,
name=self.name,
seed=getattr(self, "seed", None),
full_name=self.full_name,
qual_name=self.qual_name,
workspace_cfg=self.workspace_cfg,
block=IPMeta(
name=self.sim_cfg.name,
variant=self.sim_cfg.variant,
commit=self.sim_cfg.revision,
branch=self.sim_cfg.branch,
url="",
),
tool=ToolMeta(
name=self.sim_cfg.tool,
version="",
),
workspace_cfg=WorkspaceConfig(
timestamp=self.sim_cfg.args.timestamp,
project_root=self.sim_cfg.proj_root,
scratch_root=Path(self.sim_cfg.scratch_root),
scratch_path=Path(self.sim_cfg.scratch_path),
),
dependencies=[d.full_name for d in self.dependencies],
needs_all_dependencies_passing=self.needs_all_dependencies_passing,
weight=self.weight,
timeout_mins=self.get_timeout_mins(),
cmd=self.cmd,
exports=self.exports,
dry_run=self.dry_run,
interactive=self.sim_cfg.interactive,
gui=self.gui,
needs_all_dependencies_passing=self.needs_all_dependencies_passing,
pre_launch=self.pre_launch(),
post_finish=self.post_finish(),
odir=self.odir,
links=self.sim_cfg.links,
log_path=Path(f"{self.odir}/{self.target}.log"),
links=self.sim_cfg.links,
pre_launch=self.pre_launch(),
post_finish=self.post_finish(),
pass_patterns=self.pass_patterns,
fail_patterns=self.fail_patterns,
)
Expand Down
4 changes: 2 additions & 2 deletions src/dvsim/launcher/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ def __init__(self, job_spec: "JobSpec") -> None:
Launcher.workspace_prepared = True

# One-time preparation of the workspace, specific to the cfg.
project = workspace_cfg.project
project = job_spec.block.name
if project not in Launcher.workspace_prepared_for_cfg:
self.prepare_workspace_for_cfg(workspace_cfg)
Launcher.workspace_prepared_for_cfg.add(project)
Expand Down Expand Up @@ -339,7 +339,7 @@ def _find_patterns(patterns: Sequence[str], line: str) -> Sequence[str] | None:
# since it is devoid of the delays incurred due to infrastructure and
# setup overhead.

plugin = get_sim_tool_plugin(tool=self.job_spec.tool)
plugin = get_sim_tool_plugin(tool=self.job_spec.tool.name)

try:
time, unit = plugin.get_job_runtime(log_text=lines)
Expand Down
4 changes: 2 additions & 2 deletions src/dvsim/launcher/lsf.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,10 +214,10 @@ def _do_launch(self) -> None:
job_array += "%100"

# TODO: This needs to be moved to a HJson.
if self.job_spec.tool == "vcs":
if self.job_spec.tool.name == "vcs":
job_rusage = "'rusage[vcssim=1,vcssim_dynamic=1:duration=1]'"

elif self.job_spec.tool == "xcelium":
elif self.job_spec.tool.name == "xcelium":
job_rusage = "'rusage[xcelium=1,xcelium_dynamic=1:duration=1]'"

else:
Expand Down
2 changes: 1 addition & 1 deletion src/dvsim/launcher/nc.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def create_run_sh(self, full_path, cmd) -> None:
pathlib.Path(run_file).chmod(0o755)

def get_submit_cmd(self):
exetool = self.job_spec.tool
exetool = self.job_spec.tool.name
job_name = self.job_spec.full_name
cmd = self.job_spec.cmd
odir = self.job_spec.odir
Expand Down
3 changes: 0 additions & 3 deletions src/dvsim/report/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,6 @@ class ResultsSummary(BaseModel):
flow_results: Mapping[str, FlowResults]
"""Flow results."""

report_index: Mapping[str, Path]
"""Index of the IP block reports."""

report_path: Path
"""Path to the report JSON file."""

Expand Down
12 changes: 9 additions & 3 deletions src/dvsim/report/generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,21 @@ def gen_block_report(results: FlowResults, path: Path) -> None:
path: output directory path

"""
log.debug("generating report '%s'", results.block.name)
file_name = (
f"{results.block.name}_{results.block.variant}"
if results.block.variant
else results.block.name
)

log.debug("generating report '%s'", file_name)

path.mkdir(parents=True, exist_ok=True)

# Save the JSON version
(path / f"{results.block.name}.json").write_text(results.model_dump_json())
(path / f"{file_name}.json").write_text(results.model_dump_json())

# Generate HTML report
(path / f"{results.block.name}.html").write_text(
(path / f"{file_name}.html").write_text(
render_template(
path="reports/block_report.html",
data={"results": results},
Expand Down
20 changes: 11 additions & 9 deletions src/dvsim/scheduler.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,18 +237,20 @@ def on_signal(signal_received: int, _: FrameType | None) -> None:

results.append(
CompletedJobStatus(
project=job_spec.workspace_cfg.project,
job_type=job_spec.job_type,
name=job_spec.name,
job_type=job_spec.job_type,
seed=job_spec.seed,
block=job_spec.block,
tool=job_spec.tool,
workspace_cfg=job_spec.workspace_cfg,
full_name=name,
qual_name=job_spec.qual_name,
target=job_spec.target,
status=status,
fail_msg=launcher.fail_msg,
log_path=job_spec.log_path,
job_runtime=launcher.job_runtime.with_unit("s").get()[0],
simulated_time=launcher.simulated_time.with_unit("us").get()[0],
log_path=job_spec.log_path,
status=status,
fail_msg=launcher.fail_msg,
)
)

Expand All @@ -263,7 +265,7 @@ def add_to_scheduled(self, jobs: Mapping[str, JobSpec]) -> None:
"""
for full_name, job_spec in jobs.items():
target_dict = self._scheduled.setdefault(job_spec.target, {})
cfg_list = target_dict.setdefault(job_spec.flow, [])
cfg_list = target_dict.setdefault(job_spec.block.name, [])

if job_spec not in cfg_list:
cfg_list.append(full_name)
Expand All @@ -272,7 +274,7 @@ def _unschedule_item(self, job_name: str) -> None:
"""Remove deploy item from the schedule."""
job = self._jobs[job_name]
target_dict = self._scheduled[job.target]
cfg_list = target_dict.get(job.flow)
cfg_list = target_dict.get(job.block.name)

if cfg_list is not None:
with contextlib.suppress(ValueError):
Expand All @@ -281,7 +283,7 @@ def _unschedule_item(self, job_name: str) -> None:
# When all items in _scheduled[target][cfg] are finally removed,
# the cfg key is deleted.
if not cfg_list:
del target_dict[job.flow]
del target_dict[job.block.name]

def _enqueue_successors(self, job_name: str | None = None) -> None:
"""Move an item's successors from _scheduled to _queued.
Expand Down Expand Up @@ -363,7 +365,7 @@ def _get_successors(self, job_name: str | None = None) -> Sequence[str]:
if target is None:
return []

cfgs = {job.flow}
cfgs = {job.block.name}

# Find item's successors that can be enqueued. We assume here that
# only the immediately succeeding target can be enqueued at this
Expand Down
6 changes: 3 additions & 3 deletions src/dvsim/templates/reports/summary_report.html
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ <h2>Simulation Results: {{ top.name }}</h2>
sha: {{ top.commit[:7] }}
</a>
<a class="badge text-bg-secondary link-underline link-underline-opacity-0"
href="report.json">json</a>
href="index.json">json</a>
<span class="badge text-bg-secondary">
Branch: {{ top.branch }}
</span>
Expand All @@ -105,8 +105,8 @@ <h2>Simulation Results: {{ top.name }}</h2>
{% set flow = summary.flow_results[block_name] %}
<tr>
<td>
<a href="{{ summary.report_index[block_name] }}">
{{ block_name }}
<a href="{{ block_name }}.html">
{{ block_name | upper }}
</a>
</td>
<td>{{ flow.passed }}</td>
Expand Down
Loading