{ "cells": [ { "cell_type": "markdown", "id": "title", "metadata": {}, "source": [ "# ClusterFinder — CPU vs CUDA\n", "\n", "Two finders over the same frames and the same pedestal:\n", "\n", "| | |\n", "|---|---|\n", "| **`ClusterFinderMT`** + `ClusterCollector` | multithreaded CPU baseline |\n", "| **`ClusterFinderCUDA.find_clusters_batched`** | batched across CUDA streams, over a pinned input buffer, so H2D / kernel / D2H overlap |\n", "\n", "**Part 1** times them. **Part 2** compares what they found." ] }, { "cell_type": "code", "execution_count": 1, "id": "imports", "metadata": {}, "outputs": [], "source": [ "import sys; sys.path.append('/home/ferjao_k/aare/build')\n", "\n", "import time\n", "from pathlib import Path\n", "\n", "import boost_histogram as bh\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "from tqdm import tqdm\n", "\n", "from aare import (File, ClusterFinderMT, ClusterCollector, ClusterFinderCUDA)" ] }, { "cell_type": "markdown", "id": "md-config", "metadata": {}, "source": [ "## Configuration" ] }, { "cell_type": "code", "execution_count": 2, "id": "config", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Image size: (400, 400) cluster (3, 3)\n", "Pedestal frames: 1000\n", "Data frames: 100000 of 100000 in file\n" ] } ], "source": [ "base = Path('/mnt/sls_det_storage/moench_data/2603_MaxIVBeamtime/2026032408/process/xrf/')\n", "f = File(base / 'Cu_factor_10_data_master_0.json')\n", "pd = File(base / 'Cu_factor_10_pedestal_master_0.json')\n", "\n", "n_frames_pd = 1000 # pedestal frames, taken from the head of the file\n", "N = 100000 # data frames, read after those\n", "cluster_size = (3, 3)\n", "rows, cols = f.rows, f.cols\n", "image_size = (rows, cols)\n", "\n", "N_SIGMA = 5\n", "N_STREAMS = 4 # H2D / kernel / D2H overlap\n", "BATCH_SIZE = 2000 # frames per find_clusters_batched call\n", "\n", "# CPU workers. ClusterFinderMT gives each thread its own ClusterFinder with its\n", "# own pedestal, and data frames are handed out round-robin -- so at high thread\n", "# counts each pedestal tracks on only 1/n of the frames while the CUDA finder's\n", "# single pedestal sees all of them, and the cluster counts drift apart. Keep it\n", "# low when comparing counts; raise it to measure CPU throughput.\n", "N_THREADS = 24\n", "\n", "# Fixed per-frame output slot the kernel writes into, copied WHOLE on every D2H.\n", "# Too low does not error -- it TRUNCATES. The CUDA cell prints the peak actually\n", "# reached, which is how you size this for a new dataset.\n", "CAP = 3000\n", "\n", "capacity = 10_000 # initial ClusterVector capacity, CPU side\n", "N_BINS = 200\n", "E_MIN, E_MAX = -2, 4000 # spectrum range, ADU\n", "\n", "print(f'Image size: {image_size} cluster {cluster_size}')\n", "print(f'Pedestal frames: {n_frames_pd}')\n", "print(f'Data frames: {N} of {f.total_frames} in file')" ] }, { "cell_type": "markdown", "id": "md-build", "metadata": {}, "source": [ "## Build the two finders" ] }, { "cell_type": "code", "execution_count": 3, "id": "build", "metadata": {}, "outputs": [], "source": [ "cf_cpu = ClusterFinderMT(image_size, cluster_size, n_sigma=N_SIGMA,\n", " capacity=capacity, n_threads=N_THREADS)\n", "sink = ClusterCollector(cf_cpu)\n", "\n", "cf_cuda = ClusterFinderCUDA(image_size, cluster_size, n_sigma=N_SIGMA,\n", " max_clusters_per_frame=CAP, n_streams=N_STREAMS, \n", " time_kernels=False, algorithm=\"fixed_window\")" ] }, { "cell_type": "markdown", "id": "md-ped", "metadata": {}, "source": [ "## Pedestal\n", "\n", "Identical frames into both, so the implementation is the only thing that differs." ] }, { "cell_type": "code", "execution_count": 4, "id": "train", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Pedestal (1000 frames): 1.34s\n" ] } ], "source": [ "pd.seek(0)\n", "t0 = time.perf_counter()\n", "for _ in range(n_frames_pd):\n", " pd_img = pd.read_frame()\n", " cf_cpu.push_pedestal_frame(pd_img.copy())\n", " cf_cuda.push_pedestal_frame(pd_img.copy())\n", "print(f'Pedestal ({n_frames_pd} frames): {time.perf_counter() - t0:.2f}s')" ] }, { "cell_type": "markdown", "id": "md-io", "metadata": {}, "source": [ "## Read the data frames\n", "\n", "Kept out of both timing loops: the two finders run over the same in-memory array." ] }, { "cell_type": "code", "execution_count": 5, "id": "io", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Reading 100000 frames: 82.39s (1,214 FPS, 32.00 GB at 0.39 GB/s)\n" ] } ], "source": [ "f.seek(0)\n", "t0 = time.perf_counter()\n", "data = f.read_n(N)\n", "t_io = time.perf_counter() - t0\n", "gb = f.bytes_per_frame * N / 1e9\n", "print(f'Reading {N} frames: {t_io:.2f}s ({N / t_io:,.0f} FPS, '\n", " f'{gb:.2f} GB at {gb / t_io:.2f} GB/s)')" ] }, { "cell_type": "markdown", "id": "md-cpu", "metadata": {}, "source": [ "## 1 — CPU, multithreaded" ] }, { "cell_type": "code", "execution_count": 6, "id": "cpu", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████████████████████████████████████████████| 100000/100000 [00:23<00:00, 4191.14it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "CPU MT (24 threads): 23.86s 4,190 FPS 233,099,227 clusters (2331.0/frame)\n" ] } ], "source": [ "t0 = time.perf_counter()\n", "# Pass the frame number: find_clusters(frame) defaults it to 0, and every\n", "# resulting cluster is then stamped frame 0. Part 2 groups by it.\n", "for i, frame in enumerate(tqdm(data)):\n", " cf_cpu.find_clusters(frame, i)\n", "t_cpu = time.perf_counter() - t0\n", "\n", "cf_cpu.stop(); sink.stop()\n", "clusters_cpu = sink.steal_clusters()\n", "\n", "hist_cpu = bh.Histogram(bh.axis.Regular(N_BINS, E_MIN, E_MAX))\n", "n_clusters_cpu = 0\n", "for cv in clusters_cpu:\n", " hist_cpu.fill(cv.sum())\n", " n_clusters_cpu += cv.size\n", "\n", "print(f'CPU MT ({N_THREADS} threads): {t_cpu:.2f}s {N / t_cpu:,.0f} FPS '\n", " f'{n_clusters_cpu:,} clusters ({n_clusters_cpu / N:.1f}/frame)')" ] }, { "cell_type": "markdown", "id": "md-cuda", "metadata": {}, "source": [ "## 2 — CUDA, batched + multi-streamed\n", "\n", "`register_input_buffer` page-locks the input once so H2D runs at full DMA\n", "bandwidth instead of through the driver's staging buffer. It is paid once,\n", "outside the loop, and released when the dataset is done." ] }, { "cell_type": "code", "execution_count": null, "id": "cuda", "metadata": {}, "outputs": [], "source": [ "t0 = time.perf_counter()\n", "cf_cuda.register_input_buffer(data)\n", "t_pin = time.perf_counter() - t0\n", "\n", "clusters_cuda = []\n", "t0 = time.perf_counter()\n", "for start in range(0, N, BATCH_SIZE):\n", " stop = min(start + BATCH_SIZE, N)\n", " clusters_cuda.extend(\n", " cf_cuda.find_clusters_batched(data[start:stop], first_frame=start))\n", "t_cuda = time.perf_counter() - t0\n", "\n", "cf_cuda.unregister_input_buffer()\n", "\n", "hist_cuda = bh.Histogram(bh.axis.Regular(N_BINS, E_MIN, E_MAX))\n", "energies = [np.asarray(cv.sum()).ravel() for cv in clusters_cuda if cv.size > 0]\n", "if energies:\n", " hist_cuda.fill(np.concatenate(energies))\n", "n_clusters_cuda = sum(cv.size for cv in clusters_cuda)\n", "\n", "print(f'CUDA batched: {t_cuda:.2f}s {N / t_cuda:,.0f} FPS '\n", " f'{n_clusters_cuda:,} clusters ({n_clusters_cuda / N:.1f}/frame)')\n", "print(f' input pinned in {t_pin:.2f}s, once, outside the loop')\n", "print(f' vs CPU: {t_cpu / t_cuda:.2f}x')\n", "\n", "# One ClusterVector per frame, so this IS the per-frame maximum.\n", "peak = max((cv.size for cv in clusters_cuda), default=0)\n", "print(f' peak clusters in one frame: {peak:,} of CAP {CAP:,}')\n", "if peak >= CAP:\n", " print(' !! CAP REACHED -- clusters were dropped; raise CAP and re-run.')" ] }, { "cell_type": "markdown", "id": "md-summary", "metadata": {}, "source": [ "## Summary" ] }, { "cell_type": "code", "execution_count": 8, "id": "summary", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " s FPS us/frame clusters\n", "CPU MT (24 thr) 23.86 4,190 238.6 233,099,227\n", "CUDA batched 3.34 29,926 33.4 233,093,554\n", "\n", "speedup: 7.14x\n" ] } ], "source": [ "print(f'{\"\":<22} {\"s\":>7} {\"FPS\":>10} {\"us/frame\":>10} {\"clusters\":>13}')\n", "for name, t, n in (('CPU MT (%d thr)' % N_THREADS, t_cpu, n_clusters_cpu),\n", " ('CUDA batched', t_cuda, n_clusters_cuda)):\n", " print(f'{name:<22} {t:7.2f} {N / t:10,.0f} {t * 1e6 / N:10.1f} {n:>13,}')\n", "print(f'\\nspeedup: {t_cpu / t_cuda:.2f}x')" ] }, { "cell_type": "markdown", "id": "md-part2", "metadata": {}, "source": [ "# Part 2 — Where the two disagree\n", "\n", "The two implementations are not bit-identical by construction: the CUDA finder\n", "updates its pedestal once per frame, the CPU finder per pixel, so once the\n", "pedestals drift apart a few pixels land on opposite sides of the threshold.\n", "\n", "Three views, cheapest first: the **spectra**, the **cluster sets**, and **where\n", "in the run** the difference accumulates." ] }, { "cell_type": "markdown", "id": "md-spec", "metadata": {}, "source": [ "## Spectra\n", "\n", "Both curves should lie on top of each other; the ratio panel is the sensitive\n", "view." ] }, { "cell_type": "code", "execution_count": 9, "id": "spectra", "metadata": {}, "outputs": [ { "data": { "image/png": "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b8uy5NChQ7J9+3bzuEqVKkXeF0EeAAAAikVPhN0B3sknn0xuRghBnvPzu1SpUuZWAz39PhW16SYDrwAAAKBY3H3wtAYPQPG4v0fF6dtKkAcAAICwoAkhYI/vEUEeAAAAADgIQR4AAACQoC688EJ58803Y52MhPG///1PmjVrZkbtjCSCPAAAAEiijwx61113yamnniolSpSQ6tWrS/fu3eWTTz7xbFOrVi3TjE4X7TPVuHFjeeGFFzzPjxw5Us4888w8+9YBafQ1ixcvDnr8tm3bmm0ef/zxPM917drVPKf7//PPP808aklJSZ60+C+6XWECDn3vffr0MY93795t8qF+/frmPdaoUUPuvvtuSU9P93ndpZdeap4rWbKkGQHyuuuuk7///tvzvE450LlzZ6lataonP++8807Zt29fyPQcPXrUHL98+fJy/PHHm+P89ddfPtusXLlSOnToYKYZ0EF+brnlFjlw4IDPNp988om0bt1aTjzxRJO++++/XzIzM4MetyDvW/O+f//+Urt2bTM4Sp06dWTEiBFmHj236dOnB/1c3CNmduvWzTyOdGBNkAcAAICEpSfvZ511lnz66afyxBNPyI8//igfffSRtGvXTu644w6fbUePHi1btmyRH374QXr27CkDBgyQ2bNnhyUdGghNmzbNZ50GTpou91D6us2mTZvMek3Hv//9b2nUqJG5717+85//FPiYEyZMkBtuuMEEje7j6fLUU0+ZfNCgRfNCgxtvmjdvvfWW/PrrrzJnzhz5/fff5corr/Q8r/vr0aOHvPfee7Ju3Tqzn0WLFpn8CmXQoEEyd+5cmTVrlnzxxRcmeNOgSEe4dKfv4osvltNOO02++eYbk7Y1a9ZIv379PPvQz6Zr164myPz+++/NvjQdDzzwQNDjBnvfN910k2ebX375xdS+aWCvx3zmmWfk+eefl6FDh3q26d27t89noUunTp2kTZs2ZqRMN83z5557TiLKQh7p6emWZo3e2kV2dra1Z88ecwvy22ko3+S3k1G+ye9EKN+HDh2yfv75Z+vw4cNWvOnSpYt1yimnWAcOHMjznL43t5o1a1rPPPOMz/N169a1+vTpY+6PGDHCatq0acB96HnlZ599FjQNbdq0sW677Tbr5JNPtr744gvP+kcffdTq3r272a/uX/P72LFjnvPBYMcsiB07dlgul8v6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AAA4CDV5AFBMk7MvM7eDyEkAAGADBHkAHKVH5uPm9sMoHnNy9hXmliAPAADYAUEeAEf5XarFOgkAAAAxRZAHAMV0heuz3HtdyEsAABBzBHkAHOWF5LFRD7hGJb+SM23Dw9P+WZmcJjJ0c9TSAAAA4EaQB8BRznP9GPVjZuhPqaVz9OXKyoh6GgAAANwI8gCgmJpnTje360bl1h6+dBF5CgAAYoYgDwDC7eZPyVMAABAzTIYOAAAAAIke5K1cuVJ+/PGffi/z5s2Tnj17ytChQyUjg74oABLcwZ05CwAAQLwEebfeequsW7fO3P/jjz+kT58+ctxxx8nbb78t9913X7jTCAC2l5GVLfWGfWiWjCfqmwUAACBugjwN8M4880xzXwO7Cy+8UN58802ZPn26zJkzJ9xpBIACG5/dyyzRlJrskrTkf35OrageHQAAIAwDr1iWJdnZ2eb+okWLpFu3buZ+9erVZedOmigBiJ2Xsy81t9FsU7BmdGefxxkjonhwAACAcNTktWjRQh555BF57bXX5PPPP5dLLrnErN+wYYNUqlSpKLsEAAAAAMSqJu+ZZ56Ra6+9Vt59910ZNmyYnHbaaWb9f//7X2ndunU40gUARXJ10oLce7lz1gEAACSYIgV5TZs29Rld0+3JJ5+UlBSm3gMQO8OSZuTee4aPAQAAJKQiNdc89dRTZdeuXXnWHzlyROrVqxeOdAEAAAAAiqBI1W5//vmnZGVl5Vl/9OhR+euvv4qySwBwjPaZz5rbpbFOCAAASEiFCvLee+89z/2PP/5YypQp43msQd8nn3witWvXDm8KASDObJOTY50EAACQwAoV5PXs2dPculwu6du3r89zqampUqtWLXn66afDm0IAAAAAQGSCPPfceFpb991330n58uUL83IASAhvJI/MvccInwAAIE765Ol8eABgR6utnCldWsYwDU1d62N4dAAAkOiKPN+B9r/TZfv27Z4aPrepU6eGI20AUGjXZOXUoq0j7wAAQIIqUpA3atQoGT16tLRo0UKqVKli+ugBAAAAAOI0yHv++edl+vTpct1114U/RQBQDJUk7xyeAAAAiaRIQV5GRoa0bt06/KkBgGL6JGVg7r1ryUsAAJCQkoryoptuuknefPPN8KcGAAAAABD9IO/IkSMybtw4adOmjdx1110yePBgn6WglixZIt27d5eq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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fig, (ax_spec, ax_ratio) = plt.subplots(\n", " 2, 1, figsize=(9, 6.5), sharex=True, gridspec_kw={'height_ratios': [3, 1]})\n", "\n", "edges = hist_cpu.axes[0].edges\n", "cpu_vals, cuda_vals = hist_cpu.values(), hist_cuda.values()\n", "\n", "ax_spec.stairs(cpu_vals, edges, label=f'CPU MT ({n_clusters_cpu:,})',\n", " color='C0', linewidth=1.4)\n", "ax_spec.stairs(cuda_vals, edges, label=f'CUDA ({n_clusters_cuda:,})',\n", " color='C1', linestyle='--', linewidth=1.4)\n", "ax_spec.set_ylabel('Counts')\n", "ax_spec.set_title(f'Cluster energy spectrum — {N:,} frames')\n", "ax_spec.legend()\n", "ax_spec.grid(alpha=0.2)\n", "\n", "with np.errstate(divide='ignore', invalid='ignore'):\n", " ratio = np.where(cpu_vals > 0, cuda_vals / cpu_vals, np.nan)\n", "ax_ratio.stairs(ratio, edges, color='C1', linewidth=1.2)\n", "ax_ratio.axhline(1.0, color='gray', linewidth=0.5)\n", "ax_ratio.set_ylabel('CUDA / CPU')\n", "ax_ratio.set_xlabel('Energy [ADU]')\n", "ax_ratio.set_ylim(0.9, 1.1)\n", "ax_ratio.grid(alpha=0.3)\n", "\n", "plt.tight_layout()\n", "plt.show()" ] }, { "cell_type": "markdown", "id": "md-sets", "metadata": {}, "source": [ "## Cluster sets\n", "\n", "Every cluster is keyed by `(frame, x, y)`, so the two results can be differenced\n", "directly — no per-frame Python loop.\n", "\n", "A cluster whose centre moved by one pixel was *relabelled*, not gained or lost,\n", "so those are counted separately from genuine adds and drops." ] }, { "cell_type": "code", "execution_count": 10, "id": "sets", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CPU 233,099,227 clusters\n", "CUDA 233,093,554 clusters net -5,673 (0.0024%)\n", "\n", "exact-position mismatches CPU-only 135,742 CUDA-only 130,069\n", " of which shifted by 1 px 104,347 104,198\n", " genuine add / drop 31,395 25,871\n", "\n", "frames touched by a genuine difference: 41,569 of 100,000\n", "[40.6s]\n" ] } ], "source": [ "def cluster_keys(vectors):\n", " \"\"\"One int64 key per cluster: frame * rows*cols + y * cols + x.\n", "\n", " Centres are unique within a frame, so keys are globally unique and the sets\n", " below need only a sort, never a np.unique.\n", " \"\"\"\n", " n = len(vectors)\n", " sizes = np.fromiter((cv.size for cv in vectors), np.int64, n)\n", " frames = np.repeat(\n", " np.fromiter((cv.frame_number for cv in vectors), np.int64, n), sizes)\n", " xy = [np.asarray(cv) for cv in vectors if cv.size]\n", " if not xy:\n", " return np.empty(0, np.int64), frames\n", " x = np.concatenate([v['x'] for v in xy]).astype(np.int64)\n", " y = np.concatenate([v['y'] for v in xy]).astype(np.int64)\n", " return frames * (rows * cols) + y * cols + x, frames\n", "\n", "\n", "t0 = time.perf_counter()\n", "k_cpu, fr_cpu = cluster_keys(clusters_cpu)\n", "k_cuda, fr_cuda = cluster_keys(clusters_cuda)\n", "\n", "# Sort ONCE. np.setdiff1d and np.isin each re-sort their argument on every call,\n", "# and the shift check below calls one eight times per direction -- about twenty\n", "# sorts of a 27-million-element array. Two sorts plus binary search instead.\n", "s_cpu = np.sort(k_cpu)\n", "s_cuda = np.sort(k_cuda)\n", "\n", "\n", "def present_in(vals, sorted_keys):\n", " \"\"\"Which of `vals` appear in an already-sorted key array.\"\"\"\n", " if sorted_keys.size == 0:\n", " return np.zeros(vals.size, dtype=bool)\n", " i = np.searchsorted(sorted_keys, vals)\n", " np.clip(i, 0, sorted_keys.size - 1, out=i)\n", " return sorted_keys[i] == vals\n", "\n", "\n", "cpu_only = s_cpu[~present_in(s_cpu, s_cuda)]\n", "cuda_only = s_cuda[~present_in(s_cuda, s_cpu)]\n", "\n", "\n", "def drop_shifted(only, sorted_other):\n", " \"\"\"Drop mismatches that have a counterpart within 1 px in the other set.\"\"\"\n", " keep = np.ones(only.size, dtype=bool)\n", " for dy in (-1, 0, 1):\n", " for dx in (-1, 0, 1):\n", " if dx or dy:\n", " keep &= ~present_in(only + dy * cols + dx, sorted_other)\n", " return only[keep]\n", "\n", "\n", "cpu_real = drop_shifted(cpu_only, s_cuda)\n", "cuda_real = drop_shifted(cuda_only, s_cpu)\n", "touched = np.unique(np.concatenate([cpu_real, cuda_real]) // (rows * cols)).size\n", "\n", "print(f'CPU {k_cpu.size:>12,} clusters')\n", "print(f'CUDA {k_cuda.size:>12,} clusters net {k_cuda.size - k_cpu.size:+,}'\n", " f' ({abs(k_cuda.size - k_cpu.size) / k_cpu.size:.4%})')\n", "print()\n", "print(f'exact-position mismatches CPU-only {cpu_only.size:>8,} '\n", " f'CUDA-only {cuda_only.size:>8,}')\n", "print(f' of which shifted by 1 px {cpu_only.size - cpu_real.size:>17,} '\n", " f'{cuda_only.size - cuda_real.size:>17,}')\n", "print(f' genuine add / drop {cpu_real.size:>17,} {cuda_real.size:>17,}')\n", "print(f'\\nframes touched by a genuine difference: {touched:,} of {N:,}')\n", "print(f'[{time.perf_counter() - t0:.1f}s]')" ] }, { "cell_type": "markdown", "id": "md-drift", "metadata": {}, "source": [ "## Where in the run it accumulates\n", "\n", "Cumulative `CUDA − CPU` against frame index. A curve that rises and then flattens\n", "means the two pedestals settled into agreement and the difference is a start-up\n", "transient; a steadily sloping line would mean a persistent per-frame bias." ] }, { "cell_type": "code", "execution_count": 11, "id": "drift", "metadata": {}, "outputs": [ { "data": { "image/png": "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jz92WZYzZ06Xxzdv3kSqVKkSOWciIpLcqSZPREQkDlKnTo08efK43Bo0aIAePXqgb9++yJEjBxo1amTSTpgwAffeey/Sp0+PggULonv37rh8+XLEumbOnIksWbLg+++/R+nSpZEuXTo88cQTuHLlCj755BMUKVIEWbNmxf/93//hzp07LkHkgAEDkD9/frPuatWqYcWKFfo+RUSSOdXkiYiI+BCDsm7dumH16tVwOBxmWWhoKCZNmmSCtX379pkgj8HZlClTIl539epVk2bOnDm4dOkSHnvsMXNj8Ldw4UL8888/ePzxx1GrVi089dRT5jXPPPMM9u/fb16TL18+fPvtt6aGcceOHShZsqS+VxGRZCrEYR+BRERExOs+ebNmzUKaNGkiljVr1gynTp3ChQsXsGXLlhhf//XXX5tA8PTp0xE1eQzY2KevePHiZlnXrl3x2Wef4cSJE8iQIYNZxgCOgeK0adOwd+9eE8gdPnzYBHi2hg0bomrVqhg9erS+TRGRZEo1eSIiInFQr149TJ06NeIxm0u2bdsWVapUiZJ2+fLlJujatWsXLl68iNu3b+P69eumOSZfR2yiaQd4lDt3bhPQ2QGevezkyZPm/ubNm01NYalSpVze68aNG8iePbu+UxGRZExBnoiISBwwOCtRooTH5c4OHDiA5s2bm5q5N954A9myZcOqVavQpUsX3Lp1KyJdypQpXV7H0To9LQsPDzf3+T9FihTYtGmT+e/MOTAUEZHkR0GeiIhIAtq4caOpuRs/frzpm0dfffVVvNd7//33m0FYWLNXu3ZtH+RURESChUbXFBERSUBsgskgb/LkyWbwFPazY5+6+GIzzXbt2qFjx46YN2+eGdBlw4YNePPNN81ALSIiknwpyBMREUlAFStWNFMoMPgqX748Zs+ejTFjxvhk3Zynj0Fev379zNQLrVq1wvr16800DSIiknxpdE0REREREZEgopo8ERERERGRIKIgT0REREREJIgoyBMREREREQkiCvJERERERESCiII8ERERERGRIKIgT0REREREJIgoyBMREREREQkiCvJERERERESCiII8ERERERGRIKIgT0REREREJIgoyBMREREREQkiCvJEREREREQQPP4fDMtW8Qx8sIoAAAAASUVORK5CYII=", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "first half: -2,032 second half: -3,641\n" ] } ], "source": [ "cnt_cpu = np.bincount(fr_cpu, minlength=N)\n", "cnt_cuda = np.bincount(fr_cuda, minlength=N)\n", "cum = np.cumsum(cnt_cuda.astype(np.int64) - cnt_cpu.astype(np.int64))\n", "\n", "fig, ax = plt.subplots(figsize=(9, 3.6))\n", "ax.plot(cum, color='C1', linewidth=1.2)\n", "ax.axhline(0, color='gray', linewidth=0.5)\n", "ax.set_xlabel('Frame')\n", "ax.set_ylabel('cumulative CUDA - CPU')\n", "ax.set_title(f'Cluster-count difference accumulating over {N:,} frames '\n", " f'(final {cum[-1]:+,})')\n", "ax.grid(alpha=0.25)\n", "plt.tight_layout()\n", "plt.show()\n", "\n", "half = N // 2\n", "print(f'first half: {cum[half - 1]:+,} second half: {cum[-1] - cum[half - 1]:+,}')" ] } ], "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.11.15" } }, "nbformat": 4, "nbformat_minor": 5 }