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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,5 @@ result/
# Temp iii config files generated by bbdev script mode
api/iii-config-*.yaml
api/data/

api/steps/ip/scripts/_smoke_out/
2 changes: 1 addition & 1 deletion api/steps/bebop/p2e/03_runworkload_event.step.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
sys.path.insert(0, utils_path)

from utils.event_common import require_chip
from utils.path import bebop_cargo_env, chip_output_root, get_buckyball_path, rtl_dir, log_dir
from utils.path import bebop_cargo_env, chip_output_root, get_buckyball_path, log_dir, rtl_dir
from utils.stream_run import stream_run_logger_async
from utils.event_common import check_result, get_origin_trace_id

Expand Down
41 changes: 19 additions & 22 deletions api/steps/compiler/scripts/build.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,13 @@
from __future__ import annotations

import fcntl
import os
import shlex
import shutil
import subprocess
from pathlib import Path


def _repo(raw: str | Path) -> Path:
root = Path(raw).resolve()
if not root.is_dir():
raise ValueError(f"repo does not exist: {root}")
return root


def _run(
cmd: list[str],
*,
Expand Down Expand Up @@ -48,7 +42,7 @@ def _run(


def compiler_python(repo: str | Path) -> str:
root = _repo(repo)
root = Path(repo).resolve()
candidates = [root / "result" / "bin" / "python3"]
path_python = shutil.which("python3")
if path_python:
Expand All @@ -68,7 +62,7 @@ def compiler_python(repo: str | Path) -> str:
def build_llvm(
repo: str | Path, *, logger: object | None = None, task_scope: str | None = None
) -> Path:
root = _repo(repo)
root = Path(repo).resolve()
buddy = root / "compiler" / "thirdparty" / "buddy-mlir"
llvm_src = buddy / "llvm" / "llvm"
llvm_build = buddy / "llvm" / "build"
Expand All @@ -95,31 +89,34 @@ def build_llvm(
f"-DPython3_EXECUTABLE={python}",
f"-DPython_EXECUTABLE={python}",
]
if not (llvm_build / "build.ninja").is_file():
llvm_build.mkdir(parents=True, exist_ok=True)
with open(llvm_build / ".bbdev.lock", "a+b") as lockf:
fcntl.flock(lockf.fileno(), fcntl.LOCK_EX)
if not (llvm_build / "build.ninja").is_file():
_run(
cmake,
repo=root,
cwd=buddy,
logger=logger,
task_scope=task_scope,
output_prefix="compiler llvm configure",
)
_run(
cmake,
["ninja", "-C", str(llvm_build), "-j", str(os.cpu_count() or 1)],
repo=root,
cwd=buddy,
logger=logger,
task_scope=task_scope,
output_prefix="compiler llvm configure",
output_prefix="compiler llvm build",
)
_run(
["ninja", "-C", str(llvm_build), "-j", str(os.cpu_count() or 1)],
repo=root,
cwd=buddy,
logger=logger,
task_scope=task_scope,
output_prefix="compiler llvm build",
)
mlir_cmake = llvm_build / "lib" / "cmake" / "mlir"
if not mlir_cmake.is_dir():
raise RuntimeError(f"LLVM/MLIR build failed: missing {mlir_cmake}")
return llvm_build


def compiler_build_dir(repo: str | Path, chip: str) -> Path:
return _repo(repo) / "compiler" / "thirdparty" / "buddy-mlir" / "build" / chip
return Path(repo).resolve() / "compiler" / "thirdparty" / "buddy-mlir" / "build" / chip


def build_compiler(
Expand All @@ -129,7 +126,7 @@ def build_compiler(
logger: object | None = None,
task_scope: str | None = None,
) -> Path:
root = _repo(repo)
root = Path(repo).resolve()
if not chip:
raise ValueError("chip is required")
chip_pb = root / "examples" / "chips" / chip / "configs" / "generated" / "chip.pb"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import json
import os
import shlex
import shutil
Expand All @@ -12,14 +13,14 @@
scripts_path = os.path.join(os.path.dirname(__file__), "scripts")
if scripts_path not in sys.path:
sys.path.insert(0, scripts_path)
step_path = os.path.dirname(__file__)
if step_path not in sys.path:
sys.path.insert(0, step_path)
scripts_path = os.path.join(os.path.dirname(__file__), "scripts")
if scripts_path not in sys.path:
sys.path.insert(0, scripts_path)

from utils.event_common import check_result, get_origin_trace_id
from utils.path import get_buckyball_path
from utils.stream_run import stream_run_logger_async
from tapeout import get_tapeout_contract, technology_settings, write_run_tcl
from tapeout import clock_period_ns, get_tapeout_contract, write_run_tcl

config = {
"name": "dc-area",
Expand Down Expand Up @@ -83,30 +84,49 @@ async def handler(input_data: dict, ctx: FlowContext) -> None:
os.makedirs(output_dir, exist_ok=True)
os.makedirs(report_dir, exist_ok=True)
try:
tech = technology_settings()
gman = input_data.get("generate_manifest")
if not isinstance(gman, str) or not gman:
rman = input_data.get("replace_manifest")
if isinstance(rman, str) and os.path.isfile(rman):
with open(rman, encoding="utf-8") as handle:
gman = json.load(handle).get("generate_manifest")
if not isinstance(gman, str) or not os.path.isfile(gman):
raise ValueError("missing generate_manifest with link_dbs")
with open(gman, encoding="utf-8") as handle:
link_dbs = json.load(handle).get("link_dbs")
if not isinstance(link_dbs, list) or not link_dbs:
raise ValueError(f"generate_manifest.link_dbs empty: {gman}")
for path in link_dbs:
if not isinstance(path, str) or not os.path.isfile(path):
raise ValueError(f"sram db missing: {path}")
tech = {
"target_library": contract.target_library,
"synthetic_library": contract.synthetic_library,
"link_library": list(contract.link_library) + list(link_dbs),
"max_cores": contract.max_cores,
}
run_config = write_run_tcl(
os.path.join(analysis_dir, "run.tcl"),
{
"top": top_module,
"source_list": source_list_path,
"output_dir": output_dir,
"report_dir": report_dir,
"clock_port": contract.clock_port,
"clock_period_ns": contract.clock_period_ns,
"sdc": str(contract.constraints_sdc),
**tech,
},
)
except (OSError, ValueError) as exc:
except (OSError, ValueError, json.JSONDecodeError) as exc:
await check_result(ctx, 1, continue_run=False, extra_fields={"task": "dc", "error": str(exc)}, trace_id=origin_tid)
return
script_path = contract.dc_script
dc_log = os.path.join(analysis_dir, "dc_shell.log")
ctx.logger.info(f"Running chip-owned DC synthesis for {contract.chip}, top {top_module}: {script_path}")
result = await stream_run_logger_async(
cmd=(
f"dc_shell -f {shlex.quote(str(script_path))} "
f"set -o pipefail; dc_shell -f {shlex.quote(str(script_path))} "
f"-x {shlex.quote('set RUN_CONFIG ' + '{' + str(run_config) + '}')} "
f"> {shlex.quote(dc_log)} 2>&1"
f"2>&1 | tee {shlex.quote(dc_log)}"
),
logger=ctx.logger,
cwd=os.path.dirname(script_path),
Expand All @@ -123,7 +143,7 @@ async def handler(input_data: dict, ctx: FlowContext) -> None:
"run_config": str(run_config),
"chip": contract.chip,
"tapeout_dir": str(contract.root),
"sram_manifest": (input_data.get("sram_collateral") or {}).get("sram_manifest"),
"replace_manifest": input_data.get("replace_manifest"),
}

if result.returncode == 0 and input_data.get("from_regression_area_power"):
Expand Down Expand Up @@ -153,7 +173,7 @@ async def handler(input_data: dict, ctx: FlowContext) -> None:
trace_id=origin_tid,
)
return
freq = 1000.0 / contract.clock_period_ns
freq = 1000.0 / clock_period_ns(contract)
merge_metrics(get_buckyball_path(), area=area, freq=freq)
extra_fields["area"] = area
extra_fields["freq"] = freq
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
utils_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".."))
if utils_path not in sys.path:
sys.path.insert(0, utils_path)
step_path = os.path.dirname(__file__)
if step_path not in sys.path:
sys.path.insert(0, step_path)
scripts_path = os.path.join(os.path.dirname(__file__), "scripts")
if scripts_path not in sys.path:
sys.path.insert(0, scripts_path)

from utils.event_common import check_result, get_origin_trace_id
from utils.path import get_buckyball_path, workload_build_dir, workload_tests_root
Expand All @@ -23,7 +23,7 @@
"description": "rerun chip-owned simulation and produce activity for PTPX",
"flows": ["dc"],
"triggers": [queue("dc.sim")],
"enqueues": ["dc.power"],
"enqueues": ["pt.run"],
}


Expand Down Expand Up @@ -62,7 +62,7 @@ async def handler(input_data: dict, ctx: FlowContext) -> None:
if not os.path.isfile(explicit_activity):
await check_result(ctx, 1, continue_run=False, extra_fields={"task": "sim", "error": f"activity file does not exist: {explicit_activity}"}, trace_id=origin_tid)
return
await ctx.enqueue({"topic": "dc.power", "data": {**input_data, "activity": explicit_activity, "format": activity_format, "_trace_id": origin_tid}})
await ctx.enqueue({"topic": "pt.run", "data": {**input_data, "activity": explicit_activity, "format": activity_format, "_trace_id": origin_tid}})
return

if shutil.which("bash") is None:
Expand Down Expand Up @@ -157,4 +157,4 @@ async def handler(input_data: dict, ctx: FlowContext) -> None:
trace_id=origin_tid,
)
if result.returncode == 0:
await ctx.enqueue({"topic": "dc.power", "data": {**input_data, "activity": activity_path, "format": activity_format, "strip_path": contract.power_strip_path, "_trace_id": origin_tid}})
await ctx.enqueue({"topic": "pt.run", "data": {**input_data, "activity": activity_path, "format": activity_format, "strip_path": contract.power_strip_path, "_trace_id": origin_tid}})
56 changes: 0 additions & 56 deletions api/steps/dc/scripts/dc.tcl

This file was deleted.

Loading
Loading