{ "cells": [ { "cell_type": "markdown", "id": "3b8ae811", "metadata": {}, "source": [ "# Profiling notebook" ] }, { "cell_type": "markdown", "id": "1097bd1e", "metadata": {}, "source": [ "This notebook collects and compares the run time for several notebooks. These notebooks are specified in the `metrics.py`, in the `EXPERIMENT_NOTEBOOKS` variable.\n", "Simply run the whole notebook, and the results will be displayed in tables at the end.\n", "\n", "Each notebook listed in the `EXPERIMENT_NOTEBOOKS` (see `metrics.py`) table must have the `run_experiment()` defined. Optionally, you can define the `close_experiment()` function.\n", "\n", "This profiler will profile the `run_experiment` function, and after that's done, call the `close_experiment` (if it exists). The `close_experiment` function is not mandatory, but if there are any resources that need to be closed, you can implement that here. The profiler measures the times listed in the `METHODS` variable (see `metrics.py`), and the total time." ] }, { "cell_type": "markdown", "id": "13ae83c1", "metadata": {}, "source": [ "After the profiling is done, the notebook generates a file in this directory for each notebook. This file contains the detailed profiling report. For the notebook `.ipynb` it generates `.ipynb.prof` file, which can be opened with snakeviz (`pip install snakeviz`): `snakeviz .ipynb.prof`." ] }, { "cell_type": "markdown", "id": "04139070", "metadata": {}, "source": [ "## Configuration" ] }, { "cell_type": "code", "execution_count": 1, "id": "e2521e52", "metadata": {}, "outputs": [], "source": [ "# `benchmark_mode` sets whether we run the schedules in benchmark mode.\n", "# If it's benchmark mode, we override the reference measurements file\n", "# with the current timing values, and that will be those will be the new reference values.\n", "benchmark_mode = True\n", "profiling_reference_filename = \"profiling_reference_values.pickle\"" ] }, { "cell_type": "code", "execution_count": 2, "id": "90faba6d", "metadata": {}, "outputs": [], "source": [ "# The end result table will display each cell in different colors.\n", "# Each value's \"sigma\" is practically it's measurement error,\n", "# and if the current time is above/below\n", "# the `reference value±sigma*sigma_multiplier_threshold`\n", "# the cell will be displayed in different colors.\n", "sigma_multiplier_threshold = 2.0 # 2.0 is a reasonable value." ] }, { "cell_type": "markdown", "id": "cf4f5061", "metadata": {}, "source": [ "## Loading reference data" ] }, { "cell_type": "code", "execution_count": 3, "id": "758b1d4d", "metadata": {}, "outputs": [], "source": [ "# Reference values for profiling.\n", "# Each notebook has a reference timing value.\n", "import pickle\n", "from os.path import exists\n", "\n", "if not benchmark_mode:\n", " if not exists(profiling_reference_filename):\n", " raise RuntimeError(\n", " f\"Reference file '{profiling_reference_filename}' does not exist! \"\n", " f\"Make sure this file is created by first running the profiling with 'benchmark_mode=True'!\"\n", " )\n", " with open(profiling_reference_filename, \"rb\") as f:\n", " reference = pickle.load(f)" ] }, { "cell_type": "markdown", "id": "5e840374", "metadata": {}, "source": [ "## Running the profiling" ] }, { "cell_type": "code", "execution_count": 4, "id": "109b43ac", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "simple_binned_acquisition: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 10/10 [00:32<00:00, 3.28s/it]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Generated `simple_binned_acquisition.prof` profiling file\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "/home/gabor/projects/quantify-scheduler/quantify_scheduler/backends/circuit_to_device.py:414: RuntimeWarning: Clock 'q0.ro' has conflicting frequency definitions: 7680000000.0 Hz in the schedule and 7600000000.0 Hz in the device config. The clock is set to '7680000000.0'. Ensure the schedule clock resource matches the device config clock frequency or set the clock frequency in the device config to np.NaN to omit this warning.\n", " warnings.warn(\n", "/home/gabor/projects/quantify-scheduler/quantify_scheduler/backends/circuit_to_device.py:414: RuntimeWarning: Clock 'q0.ro' has conflicting frequency definitions: 7700100502.512563 Hz in the schedule and 7600000000.0 Hz in the device config. The clock is set to '7700100502.512563'. Ensure the schedule clock resource matches the device config clock frequency or set the clock frequency in the device config to np.NaN to omit this warning.\n", " warnings.warn(\n", "/home/gabor/projects/quantify-scheduler/quantify_scheduler/backends/circuit_to_device.py:414: RuntimeWarning: Clock 'q0.ro' has conflicting frequency definitions: 7700100502.512563 Hz in the schedule and 7600000000.0 Hz in the device config. The clock is set to '7700100502.512563'. Ensure the schedule clock resource matches the device config clock frequency or set the clock frequency in the device config to np.NaN to omit this warning.\n", " warnings.warn(\n", "/home/gabor/projects/quantify-scheduler/quantify_scheduler/backends/circuit_to_device.py:414: RuntimeWarning: Clock 'q0.ro' has conflicting frequency definitions: 7680000000.0 Hz in the schedule and 7600000000.0 Hz in the device config. The clock is set to '7680000000.0'. Ensure the schedule clock resource matches the device config clock frequency or set the clock frequency in the device config to np.NaN to omit this warning.\n", " warnings.warn(\n", "/home/gabor/projects/quantify-scheduler/quantify_scheduler/backends/circuit_to_device.py:414: RuntimeWarning: Clock 'q0.ro' has conflicting frequency definitions: 7700100502.512563 Hz in the schedule and 7600000000.0 Hz in the device config. The clock is set to '7700100502.512563'. Ensure the schedule clock resource matches the device config clock frequency or set the clock frequency in the device config to np.NaN to omit this warning.\n", " warnings.warn(\n", "/home/gabor/projects/quantify-scheduler/quantify_scheduler/backends/circuit_to_device.py:414: RuntimeWarning: Clock 'q0.ro' has conflicting frequency definitions: 7700100502.512563 Hz in the schedule and 7600000000.0 Hz in the device config. The clock is set to '7700100502.512563'. Ensure the schedule clock resource matches the device config clock frequency or set the clock frequency in the device config to np.NaN to omit this warning.\n", " warnings.warn(\n", "/home/gabor/projects/quantify-scheduler/quantify_scheduler/backends/circuit_to_device.py:414: RuntimeWarning: Clock 'q0.ro' has conflicting frequency definitions: 7680000000.0 Hz in the schedule and 7600000000.0 Hz in the device config. The clock is set to '7680000000.0'. Ensure the schedule clock resource matches the device config clock frequency or set the clock frequency in the device config to np.NaN to omit this warning.\n", " warnings.warn(\n", "/home/gabor/projects/quantify-scheduler/quantify_scheduler/backends/circuit_to_device.py:414: RuntimeWarning: Clock 'q0.ro' has conflicting frequency definitions: 7700100502.512563 Hz in the schedule and 7600000000.0 Hz in the device config. The clock is set to '7700100502.512563'. Ensure the schedule clock resource matches the device config clock frequency or set the clock frequency in the device config to np.NaN to omit this warning.\n", " warnings.warn(\n", "/home/gabor/projects/quantify-scheduler/quantify_scheduler/backends/circuit_to_device.py:414: RuntimeWarning: Clock 'q0.ro' has conflicting frequency definitions: 7700100502.512563 Hz in the schedule and 7600000000.0 Hz in the device config. The clock is set to '7700100502.512563'. Ensure the schedule clock resource matches the device config clock frequency or set the clock frequency in the device config to np.NaN to omit this warning.\n", " warnings.warn(\n", "/home/gabor/projects/quantify-scheduler/quantify_scheduler/backends/circuit_to_device.py:414: RuntimeWarning: Clock 'q0.ro' has conflicting frequency definitions: 7680000000.0 Hz in the schedule and 7600000000.0 Hz in the device config. The clock is set to '7680000000.0'. Ensure the schedule clock resource matches the device config clock frequency or set the clock frequency in the device config to np.NaN to omit this warning.\n", " warnings.warn(\n", "/home/gabor/projects/quantify-scheduler/quantify_scheduler/backends/circuit_to_device.py:414: RuntimeWarning: Clock 'q0.ro' has conflicting frequency definitions: 7700100502.512563 Hz in the schedule and 7600000000.0 Hz in the device config. The clock is set to '7700100502.512563'. Ensure the schedule clock resource matches the device config clock frequency or set the clock frequency in the device config to np.NaN to omit this warning.\n", " warnings.warn(\n", "/home/gabor/projects/quantify-scheduler/quantify_scheduler/backends/circuit_to_device.py:414: RuntimeWarning: Clock 'q0.ro' has conflicting frequency definitions: 7700100502.512563 Hz in the schedule and 7600000000.0 Hz in the device config. The clock is set to '7700100502.512563'. Ensure the schedule clock resource matches the device config clock frequency or set the clock frequency in the device config to np.NaN to omit this warning.\n", " warnings.warn(\n", "/home/gabor/projects/quantify-scheduler/quantify_scheduler/backends/circuit_to_device.py:414: RuntimeWarning: Clock 'q0.ro' has conflicting frequency definitions: 7680000000.0 Hz in the schedule and 7600000000.0 Hz in the device config. The clock is set to '7680000000.0'. Ensure the schedule clock resource matches the device config clock frequency or set the clock frequency in the device config to np.NaN to omit this warning.\n", " warnings.warn(\n", "/home/gabor/projects/quantify-scheduler/quantify_scheduler/backends/circuit_to_device.py:414: RuntimeWarning: Clock 'q0.ro' has conflicting frequency definitions: 7700100502.512563 Hz in the schedule and 7600000000.0 Hz in the device config. The clock is set to '7700100502.512563'. Ensure the schedule clock resource matches the device config clock frequency or set the clock frequency in the device config to np.NaN to omit this warning.\n", " warnings.warn(\n", "/home/gabor/projects/quantify-scheduler/quantify_scheduler/backends/circuit_to_device.py:414: RuntimeWarning: Clock 'q0.ro' has conflicting frequency definitions: 7700100502.512563 Hz in the schedule and 7600000000.0 Hz in the device config. The clock is set to '7700100502.512563'. Ensure the schedule clock resource matches the device config clock frequency or set the clock frequency in the device config to np.NaN to omit this warning.\n", " warnings.warn(\n", "/home/gabor/projects/quantify-scheduler/quantify_scheduler/backends/circuit_to_device.py:414: RuntimeWarning: Clock 'q0.ro' has conflicting frequency definitions: 7680000000.0 Hz in the schedule and 7600000000.0 Hz in the device config. The clock is set to '7680000000.0'. Ensure the schedule clock resource matches the device config clock frequency or set the clock frequency in the device config to np.NaN to omit this warning.\n", " warnings.warn(\n", "/home/gabor/projects/quantify-scheduler/quantify_scheduler/backends/circuit_to_device.py:414: RuntimeWarning: Clock 'q0.ro' has conflicting frequency definitions: 7700100502.512563 Hz in the schedule and 7600000000.0 Hz in the device config. The clock is set to '7700100502.512563'. Ensure the schedule clock resource matches the device config clock frequency or set the clock frequency in the device config to np.NaN to omit this warning.\n", " warnings.warn(\n", "/home/gabor/projects/quantify-scheduler/quantify_scheduler/backends/circuit_to_device.py:414: RuntimeWarning: Clock 'q0.ro' has conflicting frequency definitions: 7700100502.512563 Hz in the schedule and 7600000000.0 Hz in the device config. The clock is set to '7700100502.512563'. Ensure the schedule clock resource matches the device config clock frequency or set the clock frequency in the device config to np.NaN to omit this warning.\n", " warnings.warn(\n", "/home/gabor/projects/quantify-scheduler/quantify_scheduler/backends/circuit_to_device.py:414: RuntimeWarning: Clock 'q0.ro' has conflicting frequency definitions: 7680000000.0 Hz in the schedule and 7600000000.0 Hz in the device config. The clock is set to '7680000000.0'. Ensure the schedule clock resource matches the device config clock frequency or set the clock frequency in the device config to np.NaN to omit this warning.\n", " warnings.warn(\n", "/home/gabor/projects/quantify-scheduler/quantify_scheduler/backends/circuit_to_device.py:414: RuntimeWarning: Clock 'q0.ro' has conflicting frequency definitions: 7700100502.512563 Hz in the schedule and 7600000000.0 Hz in the device config. The clock is set to '7700100502.512563'. Ensure the schedule clock resource matches the device config clock frequency or set the clock frequency in the device config to np.NaN to omit this warning.\n", " warnings.warn(\n", "/home/gabor/projects/quantify-scheduler/quantify_scheduler/backends/circuit_to_device.py:414: RuntimeWarning: Clock 'q0.ro' has conflicting frequency definitions: 7700100502.512563 Hz in the schedule and 7600000000.0 Hz in the device config. The clock is set to '7700100502.512563'. Ensure the schedule clock resource matches the device config clock frequency or set the clock frequency in the device config to np.NaN to omit this warning.\n", " warnings.warn(\n", "/home/gabor/projects/quantify-scheduler/quantify_scheduler/backends/circuit_to_device.py:414: RuntimeWarning: Clock 'q0.ro' has conflicting frequency definitions: 7680000000.0 Hz in the schedule and 7600000000.0 Hz in the device config. The clock is set to '7680000000.0'. Ensure the schedule clock resource matches the device config clock frequency or set the clock frequency in the device config to np.NaN to omit this warning.\n", " warnings.warn(\n", "/home/gabor/projects/quantify-scheduler/quantify_scheduler/backends/circuit_to_device.py:414: RuntimeWarning: Clock 'q0.ro' has conflicting frequency definitions: 7700100502.512563 Hz in the schedule and 7600000000.0 Hz in the device config. The clock is set to '7700100502.512563'. Ensure the schedule clock resource matches the device config clock frequency or set the clock frequency in the device config to np.NaN to omit this warning.\n", " warnings.warn(\n", "/home/gabor/projects/quantify-scheduler/quantify_scheduler/backends/circuit_to_device.py:414: RuntimeWarning: Clock 'q0.ro' has conflicting frequency definitions: 7700100502.512563 Hz in the schedule and 7600000000.0 Hz in the device config. The clock is set to '7700100502.512563'. Ensure the schedule clock resource matches the device config clock frequency or set the clock frequency in the device config to np.NaN to omit this warning.\n", " warnings.warn(\n", "/home/gabor/projects/quantify-scheduler/quantify_scheduler/backends/circuit_to_device.py:414: RuntimeWarning: Clock 'q0.ro' has conflicting frequency definitions: 7680000000.0 Hz in the schedule and 7600000000.0 Hz in the device config. The clock is set to '7680000000.0'. Ensure the schedule clock resource matches the device config clock frequency or set the clock frequency in the device config to np.NaN to omit this warning.\n", " warnings.warn(\n", "/home/gabor/projects/quantify-scheduler/quantify_scheduler/backends/circuit_to_device.py:414: RuntimeWarning: Clock 'q0.ro' has conflicting frequency definitions: 7700100502.512563 Hz in the schedule and 7600000000.0 Hz in the device config. The clock is set to '7700100502.512563'. Ensure the schedule clock resource matches the device config clock frequency or set the clock frequency in the device config to np.NaN to omit this warning.\n", " warnings.warn(\n", "/home/gabor/projects/quantify-scheduler/quantify_scheduler/backends/circuit_to_device.py:414: RuntimeWarning: Clock 'q0.ro' has conflicting frequency definitions: 7700100502.512563 Hz in the schedule and 7600000000.0 Hz in the device config. The clock is set to '7700100502.512563'. Ensure the schedule clock resource matches the device config clock frequency or set the clock frequency in the device config to np.NaN to omit this warning.\n", " warnings.warn(\n", "/home/gabor/projects/quantify-scheduler/quantify_scheduler/backends/circuit_to_device.py:414: RuntimeWarning: Clock 'q0.ro' has conflicting frequency definitions: 7680000000.0 Hz in the schedule and 7600000000.0 Hz in the device config. The clock is set to '7680000000.0'. Ensure the schedule clock resource matches the device config clock frequency or set the clock frequency in the device config to np.NaN to omit this warning.\n", " warnings.warn(\n", "/home/gabor/projects/quantify-scheduler/quantify_scheduler/backends/circuit_to_device.py:414: RuntimeWarning: Clock 'q0.ro' has conflicting frequency definitions: 7700100502.512563 Hz in the schedule and 7600000000.0 Hz in the device config. The clock is set to '7700100502.512563'. Ensure the schedule clock resource matches the device config clock frequency or set the clock frequency in the device config to np.NaN to omit this warning.\n", " warnings.warn(\n", "/home/gabor/projects/quantify-scheduler/quantify_scheduler/backends/circuit_to_device.py:414: RuntimeWarning: Clock 'q0.ro' has conflicting frequency definitions: 7700100502.512563 Hz in the schedule and 7600000000.0 Hz in the device config. The clock is set to '7700100502.512563'. Ensure the schedule clock resource matches the device config clock frequency or set the clock frequency in the device config to np.NaN to omit this warning.\n", " warnings.warn(\n", "resonator_spectroscopy: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 10/10 [00:12<00:00, 1.27s/it]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Generated `resonator_spectroscopy.prof` profiling file\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "random_gates: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 10/10 [00:29<00:00, 2.94s/it]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Generated `random_gates.prof` profiling file\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "loops_with_measurements: 0%| | 0/10 [00:00 (\n", " ref_val + ref_sigma * sigma_multiplier_threshold\n", " ):\n", " return f\"background-color: {red}\"\n", " if (val + sigma * sigma_multiplier_threshold) < (\n", " ref_val - ref_sigma * sigma_multiplier_threshold\n", " ):\n", " return f\"background-color: {green}\"\n", " return \"\"" ] }, { "cell_type": "code", "execution_count": 11, "id": "a6b824c2", "metadata": {}, "outputs": [], "source": [ "style_table = []\n", "\n", "for row_id, (experiment_notebook, times, total_time) in enumerate(measured_data):\n", " row = []\n", " row.append(\"\")\n", " for column_id, time in enumerate(times):\n", " if row_id < len(reference) and column_id < len(reference[row_id][1]):\n", " row.append(diff_to_style(time, reference[row_id][1][column_id]))\n", " else:\n", " row.append(\"\")\n", " if row_id < len(reference):\n", " row.append(diff_to_style(total_time, reference[row_id][2]))\n", " else:\n", " row.append(\"\")\n", " style_table.append(row)" ] }, { "cell_type": "code", "execution_count": 12, "id": "2271fdaf", "metadata": {}, "outputs": [], "source": [ "style_table = np.array(style_table)\n", "style_properties = {\"border\": \"1px solid gray\"}\n", "styles = [\n", " dict(\n", " selector=\"caption\",\n", " props=[(\"text-align\", \"center\"), (\"font-size\", \"200%\"), (\"color\", \"black\")],\n", " )\n", "]" ] }, { "cell_type": "code", "execution_count": 13, "id": "d74afb03", "metadata": {}, "outputs": [], "source": [ "df = pd.DataFrame(table, columns=header)\n", "df = df.style.set_properties(**style_properties).apply(lambda _: style_table, axis=None)\n", "df = df.set_caption(\"Measured times\").set_table_styles(styles)" ] }, { "cell_type": "code", "execution_count": 14, "id": "bb38048d", "metadata": {}, "outputs": [], "source": [ "df_diff = pd.DataFrame(table_diff, columns=header)\n", "df_diff = df_diff.style.set_properties(**style_properties).apply(lambda _: style_table, axis=None)\n", "df_diff = df_diff.set_caption(\"Measured diffs to reference\").set_table_styles(styles)" ] }, { "cell_type": "code", "execution_count": 15, "id": "822cb265", "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Measured times
 compileprepareschedulerunprocessschedule_durationtotal
0simple_binned_acquisition1.3 ± 0.074 s0.091 ± 0.0015 s0.29 ± 0.081 s0.028 ± 0.00029 s0.011 ± 0.00089 s0.0025 ± 2.9e-11 s1.7 ± 0.067 s
1resonator_spectroscopy0.23 ± 0.062 s0.062 ± 0.00072 s0.06 ± 0.054 s0.0013 ± 3.6e-05 s0.01 ± 0.00027 s0.49 ± 9.1e-09 s0.59 ± 0.082 s
2random_gates1.1 ± 0.063 s0.093 ± 0.0013 s0.26 ± 0.0052 s0.00065 ± 8.4e-06 s0.0046 ± 6.3e-05 s0.00026 ± 6.3e-12 s1.4 ± 0.072 s
3loops_with_measurements2.6 ± 0.0096 s0.066 ± 0.00048 s0.042 ± 0.001 s0.00067 ± 3.9e-05 s0.0048 ± 7.3e-05 s20 ± 4.1e-07 s2.7 ± 0.0092 s
4multidim_batched_sweep3.1 ± 0.1 s0.26 ± 0.0028 snan ± nan s0.00081 ± 9.2e-06 s0.0092 ± 0.00027 s0.066 ± 1.3e-09 s3.9 ± 0.09 s
\n" ], "text/plain": [ "" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# If the cell is green (or red), the current time\n", "# is significantly less (or more) than the reference time.\n", "df" ] }, { "cell_type": "code", "execution_count": 16, "id": "f25477aa", "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Measured diffs to reference
 compileprepareschedulerunprocessschedule_durationtotal
0simple_binned_acquisition0 ± 0.074 s0 ± 0.0015 s0 ± 0.081 s0 ± 0.00029 s0 ± 0.00089 s0 ± 2.9e-11 s0 ± 0.067 s
1resonator_spectroscopy0 ± 0.062 s0 ± 0.00072 s0 ± 0.054 s0 ± 3.6e-05 s0 ± 0.00027 s0 ± 9.1e-09 s0 ± 0.082 s
2random_gates0 ± 0.063 s0 ± 0.0013 s0 ± 0.0052 s0 ± 8.4e-06 s0 ± 6.3e-05 s0 ± 6.3e-12 s0 ± 0.072 s
3loops_with_measurements0 ± 0.0096 s0 ± 0.00048 s0 ± 0.001 s0 ± 3.9e-05 s0 ± 7.3e-05 s0 ± 4.1e-07 s0 ± 0.0092 s
4multidim_batched_sweep0 ± 0.1 s0 ± 0.0028 snan ± nan s0 ± 9.2e-06 s0 ± 0.00027 s0 ± 1.3e-09 s0 ± 0.09 s
\n" ], "text/plain": [ "" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# All data is (current_time - reference_time).\n", "# If the cell is green (or red), the current time\n", "# is significantly less (or more) than the reference time.\n", "df_diff" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "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.9.21" } }, "nbformat": 4, "nbformat_minor": 5 }