{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# Free-threading Lab Notebook\n",
        "\n",
        "Original AGILAB benchmark notebook, September 19, 2026. BSD-3-Clause.\n",
        "Reference: https://docs.python.org/3.14/howto/free-threading-python.html\n",
        "\n",
        "This notebook demonstrates the Mandelbrot escape count algorithm and runs a small real benchmark using the AGILAB pool engine."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "import sys\n",
        "import json\n",
        "from pathlib import Path\n",
        "\n",
        "# Ensure project root is in path\n",
        "PROJECT_ROOT = Path(globals().get('PROJECT_ROOT', Path.cwd()))\n",
        "sys.path.insert(0, str(PROJECT_ROOT))\n",
        "\n",
        "import free_threading_core as core\n",
        "import benchmark\n",
        "\n",
        "print(f\"Project Root: {PROJECT_ROOT}\")\n",
        "print(f\"Python: {sys.version}\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# Define a small benchmark configuration\n",
        "WIDTH = 96\n",
        "HEIGHT = 64\n",
        "ITERATIONS = 100\n",
        "REPEATS = 1\n",
        "\n",
        "# Determine workers\n",
        "eff_cpus = benchmark.effective_cpus()['effective_cpus']\n",
        "WORKERS = min(2, eff_cpus)\n",
        "\n",
        "print(f\"Running benchmark with {WIDTH}x{HEIGHT}, iter={ITERATIONS}, workers={WORKERS}, repeats={REPEATS}\")\n",
        "\n",
        "# Run the benchmark\n",
        "try:\n",
        "    results = benchmark.run_benchmark(\n",
        "        width=WIDTH,\n",
        "        height=HEIGHT,\n",
        "        iterations=ITERATIONS,\n",
        "        workers=WORKERS,\n",
        "        repeats=REPEATS\n",
        "    )\n",
        "    print(\"Benchmark completed successfully.\")\n",
        "except Exception as e:\n",
        "    print(f\"Benchmark failed: {e}\")\n",
        "    raise"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# Verify digests and write results\n",
        "if 'results' in locals():\n",
        "    # Verify same work\n",
        "    assert results['same_work_verified'], \"Same work verification failed\"\n",
        "    \n",
        "    # Write full measurement report to scratch (not results.json)\n",
        "    measurement_path = Path('measurement_report.json')\n",
        "    with open(measurement_path, 'w') as f:\n",
        "        json.dump(results, f, indent=2)\n",
        "        \n",
        "    print(f\"Full measurement report written to {measurement_path.resolve()}\")\n",
        "    print(f\"Digest: {results['digest']}\")\n",
        "    print(f\"Summary entries: {len(results['summary'])}\")\n",
        "    \n",
        "    # Construct the required results.json with scientific data\n",
        "    # This must be deterministic and contain non-empty scientific values\n",
        "    # CRITICAL: Do NOT include volatile measurements (wall_seconds, engine_seconds, speedup) in results.json\n",
        "    scientific_results = {\n",
        "        \"image_digest\": results[\"digest\"],\n",
        "        \"same_work_verified\": results[\"same_work_verified\"],\n",
        "        \"parameters\": results[\"params\"],\n",
        "        \"python_build\": results[\"python_build\"],\n",
        "        \"hardware\": results[\"hardware\"],\n",
        "        \"summary\": [\n",
        "            {\n",
        "                \"mode\": s[\"mode\"],\n",
        "                \"role\": s[\"role\"],\n",
        "                \"workers\": s[\"workers\"]\n",
        "            }\n",
        "            for s in results[\"summary\"]\n",
        "        ]\n",
        "    }\n",
        "    \n",
        "    # Write results.json with the required 'results' key\n",
        "    output_path = Path('results.json')\n",
        "    final_output = {\n",
        "        \"results\": scientific_results\n",
        "    }\n",
        "    with open(output_path, 'w') as f:\n",
        "        json.dump(final_output, f, indent=2)\n",
        "        \n",
        "    print(f\"Results written to {output_path.resolve()}\")\n",
        "else:\n",
        "    print(\"No results to write.\")"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "name": "python",
      "version": "3.14.0"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 4
}
