Files
project_6/cccl_upstream/ci/compile_time/analytics.ipynb
muh-bot 2a7ca101d7 feat(cccl): integrate missing CCCL directories — python/, ci/, .agent/, docs/, test/
Sparse-checkout from NVIDIA/cccl main branch to complete cccl_upstream:

Added:
- python/cuda_cccl/ (226 files) — Python bindings for device-level algorithms
  Critical for muh toolchain: cuda.compute.reduce_into, scan, radix_sort, etc.
  Includes 204 .py files with full test coverage for all 27 algorithms
- ci/ (163 files) — Build/test infrastructure
  build_cub.sh, test_cub.sh, build_and_test_targets.sh, matrix.yaml
  Directly maps to our [INFRA-CI] and [INFRA-BUILD] items
- .agent/skills/ (7 files) — NVIDIA's own agent skills for CCCL
  cccl-style/SKILL.md, cccl-test/SKILL.md, sass-diff/SKILL.md
- docs/ (491 files) — Official CCCL documentation
  CI references, CMake guides, Python compute docs, libcudacxx PTX docs
- test/ (12 files) — Top-level integration tests (cuda_smoke, stdpar)
- Root configs: .clang-format, .clang-tidy, CONTRIBUTING.md, pyproject.toml
- CLAUDE.md symlink → AGENTS.md (NVIDIA's standard)

cccl_upstream now mirrors full NVIDIA/cccl structure:
  Before: 42M (cub + thrust + libcudacxx + cudax + c + examples + benchmarks)
  After:  53M (+python +ci +docs +.agent +test +configs)

This completes the CCCL base needed for:
- [muh-bench] items: ci/util/build_and_test_targets.sh for targeted builds
- [CCCL-verify] items: python/cuda_cccl/tests/ as reference implementations
- [CCCL-test] items: ci/test_cub.sh, ci/test_thrust.sh
- Agent workflow: .agent/skills/ for consistent style and test patterns
2026-08-07 02:34:33 +00:00

334 lines
11 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"id": "903704f7",
"metadata": {},
"source": [
"# Compile-Time Analytics\n",
"\n",
"This notebook helps you:\n",
"\n",
"1. Run `ci/build_compile_time_bench.sh` from the repo root.\n",
"2. Load and inspect an all-header processing CSV.\n",
"3. Explore high-impact headers by TU coverage and average processing time.\n",
"4. Build combined ranking scores to identify optimization targets.\n",
"\n",
"Expected CSV columns include:\n",
"- `header_path`\n",
"- `include_tu_count`\n",
"- `avg_process_time_s`\n",
"- `total_process_time_s`\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ad58db28",
"metadata": {},
"outputs": [],
"source": [
"%pip install pandas matplotlib plotly nbformat"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "16ba6808",
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"import shlex\n",
"import sys\n",
"from pathlib import Path\n",
"\n",
"import pandas as pd\n",
"\n",
"pd.set_option(\"display.max_colwidth\", 160)\n",
"pd.set_option(\"display.width\", 200)\n",
"pd.set_option(\"display.max_columns\", 20)\n",
"\n",
"REPO_ROOT = Path.cwd()\n",
"while REPO_ROOT != REPO_ROOT.parent and not (REPO_ROOT / \".git\").exists():\n",
" REPO_ROOT = REPO_ROOT.parent\n",
"\n",
"if not (REPO_ROOT / \".git\").exists():\n",
" raise RuntimeError(\n",
" \"Could not locate repo root (.git). Start notebook from inside the CCCL repo.\"\n",
" )\n",
"\n",
"print(f\"Repo root: {REPO_ROOT}\")\n",
"print(f\"Python executable: {sys.executable}\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "373652c8",
"metadata": {},
"outputs": [],
"source": [
"# --- Run build_compile_time_bench.sh (file-processing mode) ---\n",
"import subprocess\n",
"from pathlib import Path\n",
"\n",
"if \"REPO_ROOT\" not in globals():\n",
" REPO_ROOT = Path.cwd()\n",
" while REPO_ROOT != REPO_ROOT.parent and not (REPO_ROOT / \".git\").exists():\n",
" REPO_ROOT = REPO_ROOT.parent\n",
"\n",
"output_csv = Path(os.environ.get(\"COMPILE_TIME_CSV\", \"/tmp/compile_time.csv\"))\n",
"cmd = [\n",
" \"bash\",\n",
" str(REPO_ROOT / \"ci\" / \"build_compile_time_bench.sh\"),\n",
" *shlex.split(os.environ.get(\"COMPILE_TIME_BUILD_ARGS\", \"\")),\n",
" \"--\",\n",
" \"-f\",\n",
" \"file-processing\",\n",
" \"-e\",\n",
" \"-n\",\n",
" os.environ.get(\"COMPILE_TIME_TOP_N\", \"5000\"),\n",
" \"--sort\",\n",
" \"total\",\n",
" \"--output-csv\",\n",
" str(output_csv),\n",
"]\n",
"\n",
"print(\"Command:\")\n",
"print(\" \" + \" \".join(shlex.quote(x) for x in cmd))\n",
"\n",
"subprocess.run(cmd, cwd=REPO_ROOT, check=True)\n",
"print(f\"\\nWrote: {output_csv}\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "12ad4c5c",
"metadata": {},
"outputs": [],
"source": [
"# --- Load CSV ---\n",
"csv_path = Path(os.environ.get(\"COMPILE_TIME_CSV\", \"/tmp/compile_time.csv\"))\n",
"if not csv_path.exists():\n",
" raise FileNotFoundError(f\"Missing CSV: {csv_path}. Run the script first.\")\n",
"\n",
"df = pd.read_csv(csv_path)\n",
"\n",
"event_summary_cols = {\n",
" \"event_name\",\n",
" \"event_key\",\n",
" \"root_tu_count\",\n",
" \"selected_avg_per_root_tu_s\",\n",
" \"selected_total_s\",\n",
"}\n",
"required_cols = [\n",
" \"header_path\",\n",
" \"include_tu_count\",\n",
" \"avg_process_time_s\",\n",
" \"total_process_time_s\",\n",
"]\n",
"\n",
"if event_summary_cols.issubset(df.columns):\n",
" df[\"header_path\"] = df[\"event_key\"]\n",
" df[\"include_tu_count\"] = df[\"root_tu_count\"]\n",
" if (\n",
" \"avg_inclusive_per_root_tu_s\" in df.columns\n",
" and \"total_inclusive_s\" in df.columns\n",
" ):\n",
" df[\"avg_process_time_s\"] = df[\"avg_inclusive_per_root_tu_s\"]\n",
" df[\"total_process_time_s\"] = df[\"total_inclusive_s\"]\n",
" else:\n",
" df[\"avg_process_time_s\"] = df[\"selected_avg_per_root_tu_s\"]\n",
" df[\"total_process_time_s\"] = df[\"selected_total_s\"]\n",
"\n",
"missing = [c for c in required_cols if c not in df.columns]\n",
"if missing:\n",
" raise ValueError(\n",
" f\"CSV is not all-header processing output. Missing columns: {missing}. \"\n",
" \"Run the script cell above to regenerate /tmp/compile_time.csv.\"\n",
" )\n",
"\n",
"for col in [\"include_tu_count\", \"avg_process_time_s\", \"total_process_time_s\"]:\n",
" df[col] = pd.to_numeric(df[col], errors=\"coerce\").fillna(0)\n",
"\n",
"print(f\"Rows: {len(df):,}\")\n",
"print(f\"Columns: {list(df.columns)}\")\n",
"df.head(5)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1a9b36a8",
"metadata": {},
"outputs": [],
"source": [
"# --- Quick top-N views ---\n",
"TOP_N = 5\n",
"\n",
"print(\"Top by avg_process_time_s\")\n",
"display(\n",
" df.nlargest(TOP_N, \"avg_process_time_s\")[\n",
" [\n",
" \"header_path\",\n",
" \"avg_process_time_s\",\n",
" \"include_tu_count\",\n",
" \"total_process_time_s\",\n",
" ]\n",
" ]\n",
")\n",
"\n",
"print(\"\\nTop by include_tu_count\")\n",
"display(\n",
" df.nlargest(TOP_N, \"include_tu_count\")[\n",
" [\n",
" \"header_path\",\n",
" \"include_tu_count\",\n",
" \"avg_process_time_s\",\n",
" \"total_process_time_s\",\n",
" ]\n",
" ]\n",
")\n",
"\n",
"print(\"\\nTop by impact score (include_tu_count * avg_process_time_s)\")\n",
"df_score = df.copy()\n",
"df_score[\"impact_score\"] = df_score[\"include_tu_count\"] * df_score[\"avg_process_time_s\"]\n",
"display(\n",
" df_score.nlargest(TOP_N, \"impact_score\")[\n",
" [\n",
" \"header_path\",\n",
" \"impact_score\",\n",
" \"include_tu_count\",\n",
" \"avg_process_time_s\",\n",
" \"total_process_time_s\",\n",
" ]\n",
" ]\n",
")"
]
},
{
"cell_type": "markdown",
"id": "174eabd4",
"metadata": {},
"source": [
"### How to read this plot\n",
"\n",
"- Each point is one header seen in all-mode profiling.\n",
"- **X axis (`include_tu_count`)**: how many generated public-header TUs include this header at least once.\n",
"- **Y axis (`avg_process_time_s`)**: average time spent processing that header per including TU.\n",
"- Headers near the **upper-right** are usually the best optimization candidates because they are both widespread and expensive per include."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9ddc0725",
"metadata": {},
"outputs": [],
"source": [
"# --- Interactive scatter (hover shows header name) ---\n",
"\n",
"import plotly.express as px\n",
"\n",
"plot_df = df.copy()\n",
"\n",
"total_headers = len(plot_df)\n",
"total_public_headers = int(plot_df[\"include_tu_count\"].max())\n",
"\n",
"fig = px.scatter(\n",
" plot_df,\n",
" x=\"include_tu_count\",\n",
" y=\"avg_process_time_s\",\n",
" hover_name=\"header_path\",\n",
" hover_data={\n",
" \"include_tu_count\": True,\n",
" \"avg_process_time_s\": \":.6f\",\n",
" \"total_process_time_s\": \":.3f\",\n",
" \"header_path\": False,\n",
" },\n",
" opacity=0.6,\n",
" title=(\n",
" f\"Header include count vs avg processing time ({total_headers:,} total headers; \"\n",
" f\"coverage measured across {total_public_headers} public headers)\"\n",
" ),\n",
")\n",
"\n",
"fig.update_layout(\n",
" xaxis_title=(\n",
" \"TU coverage: number of public headers that include this header \"\n",
" f\"(out of {total_public_headers})\"\n",
" ),\n",
" yaxis_title=\"Average processing time per including TU (seconds)\",\n",
" height=900,\n",
")\n",
"fig.show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f429b934",
"metadata": {},
"outputs": [],
"source": [
"# --- Optional: run ctadvisor and parse expensive headers ---\n",
"run_ctadvisor = os.environ.get(\"COMPILE_TIME_RUN_CTADVISOR\") == \"1\"\n",
"CTADVISOR_ENTRIES = 10\n",
"CTADVISOR_THREADS = os.cpu_count() or 8\n",
"\n",
"trace_root = (\n",
" REPO_ROOT\n",
" / \"build\"\n",
" / os.environ.get(\"CCCL_BUILD_INFIX\", \"cuda13.1-gcc14\")\n",
" / os.environ.get(\"CCCL_COMPILE_TIME_PRESET\", \"all-dev\")\n",
" / \"compile_time\"\n",
" / \"raw_traces\"\n",
")\n",
"ctadvisor_cmd = [\n",
" \"ctadvisor\",\n",
" \"--trace-file-path\",\n",
" str(trace_root),\n",
" \"--header-advisor-entries\",\n",
" str(CTADVISOR_ENTRIES),\n",
" \"--thread-number\",\n",
" str(CTADVISOR_THREADS),\n",
"]\n",
"\n",
"if run_ctadvisor:\n",
" print(\"Command:\")\n",
" print(\" \" + \" \".join(shlex.quote(x) for x in ctadvisor_cmd))\n",
"\n",
" result = subprocess.run(\n",
" ctadvisor_cmd, cwd=REPO_ROOT, check=True, capture_output=True, text=True\n",
" )\n",
" print(result.stdout)\n",
"else:\n",
" print(\"Skipping ctadvisor. Set COMPILE_TIME_RUN_CTADVISOR=1 to run it.\")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "cccl",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.3"
}
},
"nbformat": 4,
"nbformat_minor": 5
}