Files
aare/python/tests/ClusterFinderCUDA.ipynb
T
kferjaoui f4bbbc9c76 Fix cluster loss on ClusterFinderMT shutdown
collect() cached queue emptiness across sweeps, so a worker's last
write could land after the final sweep but before shutdown was
observed, stranding that frame's clusters. Read the stop flags before
sweeping instead: once workers are joined, a sweep that moves nothing
proves the queues are drained.

Found via ClusterFinderCUDA.ipynb's drift plot, which jumped by one
frame's worth of clusters at the very end.
2026-09-03 17:26:47 +02:00

597 lines
109 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"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: 50000 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 = 50000 # 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)"
]
},
{
"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): 2.01s\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 50000 frames: 31.25s (1,600 FPS, 16.00 GB at 0.51 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%|███████████████████████████████████████| 50000/50000 [00:12<00:00, 3977.38it/s]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"CPU MT (24 threads): 12.58s 3,976 FPS 116,015,414 clusters (2320.3/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": 7,
"id": "cuda",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"CUDA batched: 1.87s 26,720 FPS 116,013,348 clusters (2320.3/frame)\n",
" input pinned in 0.53s, once, outside the loop\n",
" vs CPU: 6.72x\n",
" peak clusters in one frame: 2,524 of CAP 3,000\n"
]
}
],
"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) 12.58 3,976 251.5 116,015,414\n",
"CUDA batched 1.87 26,720 37.4 116,013,348\n",
"\n",
"speedup: 6.72x\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":
"iVBORw0KGgoAAAANSUhEUgAAA3kAAAKACAYAAAAhGrGwAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAgv1JREFUeJzt3QeYE1XXwPGTbTQBQRFBqgVQUETFgg1EaaJgbyiIICioyPupFBUBEStiAztYQNQXUWwIqCi+iCCIFFFEURCRLh2WbOZ7zt1NSLLZ3exukplM/r/nmU0ymSQ3N5PsnDm3eCzLsgQAAAAA4AppdhcAAAAAABA7BHkAAAAA4CIEeQAAAADgIgR5AAAAAOAiBHkAAAAA4CIEeQAAAADgIgR5AAAAAOAiBHkAAAAA4CIEeQAAAADgIgR5ABxr8eLFcuONN0r9+vWlbNmyctBBB8lJJ50kjz76qGzZsiWwXcuWLc0SL2PGjJHx48fH7fmRPNgXDvjjjz/E4/FEXCZNmpSv7n7//Xe59NJL5eCDDzbf5QsuuEAWLlwYdd0X5/H6+ieeeKL53ahZs6b069dPdu7cmW87Xaf36Ta6rT4mUtkL8swzz8jRRx8tWVlZ5n3/+++/UT8WAOIpI67PDgAl9NJLL8mtt94qDRs2lLvuukuOO+442b9/v3z//ffy/PPPy7fffitTpkxJ2IH9oYceKt26dUvI68G52Bfyu+222+Taa68NWXfMMceE3N64caOcffbZUqVKFXn11VdNQDVy5Ehzcmb+/Pnme16Y4jx+woQJ0qVLF+nRo4c8+eSTsmLFCrnnnnvkp59+kunTp4c8rwaN+viHH35YGjRoIBMnTpRrrrlGfD5fvvcUbtGiRXL77beb1+natatkZGRIxYoVC30MACSMBQAOM2fOHCs9Pd1q166dtXfv3nz379u3z/rggw8Ct88991yzxEvjxo1j/vw+n8/avXu3lSySqazxVJx9ITs729q/f7/lVqtWrbL0MOKxxx4rctu77rrLyszMtP7444/Aum3btlmHHnqodeWVV8bs8V6v16pRo4bVpk2bkMdPmDDBlPWTTz4JrPv444/NuokTJ4Zse8EFF1g1a9Y0z1WYN9980zz+u+++K7L8u3btKnIbAIglmmsCcJyHHnrINH168cUXpUyZMvnu16ZRF198cYGPnzVrlnm8XkZqXhbc9FKbgF199dWmuZa+VvXq1aV169bmLL2qV6+eLFu2TL766qtAUzRd57d9+3b5v//7P9OkVMt1xBFHmOZfu3btCnltfVzfvn1NFvLYY481r/Xaa68VWg9vv/22nHHGGVKhQgXTPK1t27byww8/hGyj2UW9b+XKldKhQwdzvXbt2vKf//xH9u3bF7Jtdna2PPjgg9KoUSPz+tWqVTPNYTVLEkzfX8eOHeW9996TZs2amazJ0KFDzX1aF23atJHy5cubx/fp00c+/vjjkPoePny4yWqsWbMm33vq3r27HHLIIbJ3794C33dRn0lwGTWbe8IJJ5gyHnnkkfL000/ne75oPyPN3mjzO22yV65cOdMs8PTTT5epU6cWuS/497k33njD1L2+hpZdP5cHHnjA3BdO90Ndr/tl+Pv66KOPTN1rOXR/0dv+x+ht3SdOPfVUk9lOBvo5nXfeeVK3bt3AukqVKplM2ocffiherzcmj587d66sW7fO7NfBrrjiCvPdCM7+63Vdp/cF08f+/fff8t133xVYHs0garZQnXbaaeZz9Gf69b4mTZrI119/LS1atDDfFd3v/d9p/f7UqFEj8NkOGDAg377o/17//PPP5nuvn7c+RjOO/vd51llnmfWagYz0W/LPP/9Ir169pFatWma/1/1fv8fhdT127Fhp2rSpeT3NROrvw6BBgwr9PAA4H801AThKTk6OfPHFF3LyySebYCXeNDDS19R+fnXq1JFNmzbJnDlzAn1r9EDw8ssvl8qVK5umesofeO7evVvOPfdc+euvv8xBkQYbGgTcf//9smTJEpk5c2bIwf37778vs2fPNvcffvjhcthhhxUa6N57773mgFMvNUB77LHHTJO1efPmmearftqMVYPem266yQQYenCpgZaWWV/LH8B06tTJvP7dd99tDj7//PNPGTJkiDko1WBBDzr9tK/T8uXLzWvrwaEeTOrBs75fva4Hhlr+t956ywSvwfTAcsSIEfLCCy+YoNJP+1FqfyfdXoOykn4mfhr0abCmQZTWpzbTu+OOO0xdaVBX3M9ID6zffPNNU4/Dhg0zB8ZaD/4grLB9wW/gwIEmMNdgPi0trdDPuCA//vijeZ7Bgweb19IDcw1mdN3nn38eOAmiTRA1IFy1alXIZ5doGnho3Wpgr31mdf8KPgmzZ88e+e233+SSSy7J91j9PPR+Dew1WImkOI9funRpYH2wzMxME7z471d6XYMsLXf4c/rv1+9JJPr5676v+/e4cePMc+tJDz/9rmgQqHWhn5fuC+rXX381+7fut/o90iDukUceMd9p/d0Lpt9r/dx79+5tmqxrU1LdB/SkxeTJk83nrwGcnpjQfVcDS/3d9Ad4ehJAX1f39aOOOso0cdfy6v6sZVb6fdRm8drk9vHHHzfb64kJbdoKIMnFNC8IAKX0zz//mCZQV199ddSPCW+u+eWXX5rn0MtIzcvGjRtnbm/atMncHj16dIma6I0cOdJKS0uz5s+fH7L+v//9b76mYXq7cuXK1pYtW4p8P6tXr7YyMjKs2267LWT9jh07rMMPPzykeVrXrl3Nc7/zzjsh23bo0MFq2LBh4PZbb71ltps8eXLIdlp2XT9mzJjAurp165rmsr/88ku+JnMej8datmxZyPq2bdvmq28t12GHHWaa1vo98sgjpr70cyhItJ+JllHLsmjRonxN7SpVqhRoHhftZ/T111+b24MHDy7RvuDf584555x89w0ZMsTcF073Q10fXB/6vsqVK2f99ddfgXX6HnU7bYYY3Ozv/fffN+unTp1q2eHvv/+2evbsafa92bNnmyaRp59+uinTSy+9FNhu7dq1Zp1+FuG0qaTep020C1Kcx48YMcLcXrduXb5ttQlngwYNArePOeYYs+9Gel/6HA899FCh79//+YXvW7p/6PrPP/+8yCbb2pz3q6++Mtv/+OOP+b7Xwd9X3bZatWpm/cKFCwPrN2/ebL6v/fv3D6zr1auXddBBB1l//vlnyGs+/vjj5vH+73Dfvn2tgw8+uNByAkhOKd1cU892X3TRRaZJkJ4V1bPsxaXHbnr2S88g6hldzTzoWTsAzle1alVzhlszZKNGjTJNITXjFS1tQqdnz7V5nzaB8i/avCpSc1FtbqYDRxTls88+M89zww03hDyvZr80KxX+vPpa+lsWno3QTF1wWbX5oW4X/Jxads2ChT+nPj48s6LNFPX9BmcRlQ5UEU4zahs2bJB3333X3NZ61ezfhRdeGNLctTSfSePGjU0zs2A6WIZmOvyjLkb7GX366afmUpuflsZll10mpaVl1eaefpptUppx1aZ/4euDP+dIgt93cZfCaPNBbVKtzR216aDWvf5f1Wam2gQx/PGRmqxGc19JHl/QttFuF22Z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/v33X2ozjvM9b968mfp1eZ0ffPDBcvjhh5cqsCTIAwAAQKn5A7zDDjtMypcvT7YpDkG0Zkk1y8NI7O6sc8uyZPfu3bJhwwZzu0aNGiV+LoI8AAAAlIoeCPsDvEMOOYTajAOCvNSo83LlyplLDfT0+1TSppsMvAIAAIBS8ffB0wwegNLxf49K07eVIA8AAAAxQTNCwBnfI4I8AAAAAHARgjwAAAAgRZ1zzjkyceJEu4uRMj766CNp1qyZGbUzngjyAAAAIKk+Muhtt90mRx55pJQpU0Zq164tF110kXz++eeBberVq2ea0emifaaaNGkiL7zwQuD+Bx54QE488cR8z60D0uhjZs2aVeDrt2zZ0mzz8MMP57uvQ4cO5j59/j/++EPS0tIC5Yi06HbFCTj0vV999dWBdS+++KIpT6VKlczzRZoSY8SIEdKiRQtTDzrcf0HGjx8vJ5xwgpQtW9ZMCdC3b99Cy7Nv3z7zORx66KFSoUIFufjii+Wvv/4q9mt7ItTL888/H/VgK+3btzePef/990v0vpVOu1CrVq18ddixY0ezLt6BNUEeAAAAUpYGTieffLJ88cUX8uijj8qSJUtk2rRp0qpVK+nTp0/ItsOGDZN169bJ4sWLpXPnztK7d295++23Y1IODSzHjRsXsu7vv/825fIPpa/b6Dotgy7/+c9/pHHjxoHbuvzf//1f1K/59NNPy4033mgCRz8dwr9du3YyaNCgAh+nE4RfccUVcssttxS4zahRo2Tw4MEyYMAAWbZsmQmY27ZtW2h5+vXrJ1OmTJFJkybJN998Izt37jRBkY5wWZzXVlqXwfXStWtXicbo0aML7BMX7Wurm266yQS4kWidP/PMMxJPTKEAAACAlHXrrbeag/p58+aZ7JGfBk/du3cP2bZixYomI6UefPBBeeedd0y256qrrip1OTSY0ef73//+J2eeeWYgE9amTRtZvXq1ua3D6QdPkn3QQQdJRkZGoEzFsWnTJpk5c6Y8+eST+QItVVjmcejQoYHyRbJ161a599575cMPP5TWrVuH1GlBtm3bJq+88oq88cYbcv7555t1b775pglstZz+ALGo1w6fULw4fvzxRxOczp8/P+IcddG+9tixY0327v7775dPP/003/2aobz99tvl999/N9njeCCTBwAAgJS0ZcsWk7XTjF1wgOdXVJM8bYZY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a6Vhw4ZmnZYz3LJly+Syyy6TevXqmfKOHj064nOvXbtWunTpIocccoiUL19eTjzxRFmwwD9FUWRfffWVnHzyyVK2bFlTr88//3yxX3vs2LFywgknSKVKlcxyxhlnyKefflro637zzTdy5plnmrKWK1fOBL5PPukfaTu/SZMmmdfv3LlzyHqv1yv33nuvHHPMMeY963sYNmxYyGd43333yYABAxwZWBPkAXC11t6nzVKQNp550jFtjsjwageWh45IaBkBAPb5448/TDCimbBHH31UlixZItOmTZNWrVpJnz59SvSc7dq1M0GWPrcGJfpcd9xxh3Ts2NEED8FWr14t3377rfTt21deeeWVEr3enDlz5Ndff5UrrrgisG7fvn1SrVo1E/g1bdo04uN2795tgpeHH35YDj/88IjbbN261QRNGrDqe/npp5/kiSeekIMPPrjA8qxatUo6dOggZ599tvzwww8yaNAguf3222Xy5MnFeu1atWqZ+7///nuznHfeedKpUycTIBakQoUKpi6//vprWb58uQnUdHnxxRfzbfvnn3/K//3f/5lyhnvkkUfkhRdekKeeesq8Z903HnvsMXnmmWcC21x44YWybds2+eyzz8Rp6JMHIKVl68+gJZLlX5GTbW+BAAAJdeutt5pMzrx580yA4Ne4cWPp3r17iZ5Ts4H+wOWII46Qk046SU4//XRp3bq1jB8/Xnr06BHYdty4cSb4u+WWW+TUU081Ga3gckRDs1GaDdSsmZ9myDRAUZpFLKi5oS5KM1KRaLCjmU0tZ/BzF0azdnXq1Alk54499lgTpD3++OMmexfta2s2NdiIESNMdk8znvr5RNKsWTOzBJdVm1TOnj1bbr755sD6nJwcue6662To0KHmvn///TfkeTTwvvjii02wqlnW+vXry1tvvWXeh5+u1/t1ffv27cVJyOQBSGknecdLE++bIvdtzF3O/j+RFrfbXSwAQAJs2bLFZO00YxcpsCosW1VcmoXSjFpwHy7LskzwpE0htVlhgwYN5J133in2c2vW6pRTTpF4mDp1qnluzRIedthhJoB66aWXCn2MBkgadAZr27atCZD2799fonJoUKbB7K5du0yzzWj98MMPJtN57rnnhqzXppea6bzpppsiPu6ss84y2d0VK1aY2z/++KNpCqpBXTANzDVIdBoyeQBcbWlGl7xr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yPfjBkHHbfn+T5Ti84nwOtpg00n7ebTlKFWQ9+uvv8qrr74qr732msmM6SAoxbFz505ZuXJlyBQJixYtMpOr6yia2ixz7dq18vrrr5v7dT68Z5991syTp6N56kAsGli+9VbYATgSN9+Rk5SmM3BJOn4XNN9RccpR1GsETy/BfEDuGoI/lSZSL+4AAcFS+fMq6reksLn77MRomvYqbNTpVFfY1CeJUppRPIMHdQo/0E+1AVGKOyVJCsooSTvQd955xwRXc+fOlZycHHnyySele/fuctBBBxXruXT6g1atWgVua/CmunbtKuPHjzf97FavXh24v379+vLJJ5/InXfeaSZi18nQn376aaZPSBQ3z3dU3B/HWP24lCYg5J939DjotHckzmgOaviMgNhMpB78fXJS8G+3RA39H02mrqA5EOM17YEbpVpQG88gb968efLyyy/L22+/bQZA6dKli7z77rtSq1YtOf/884sd4KmWLVuajrsF0UAv3LnnnisLFy4s9mshRjgQs+/HpaiDaiaGh90KG248URM7I7E4KE0MshbJ83+7NJk6Wp7AjiCvRYsWctttt5lgr2HDCANIALD3oDq4/16k+QXDOW3OH7jnIDSagxonzAnmNuHz7SXiO85BaWLwW518mdaSntTiZDoSHeSdd955ponmhg0b5Prrrzf975wylCiQksKbmQT33ytsIItIB+FkAVFa4f3DCgviEtVsKpXY2Zybg1Jn44RK/JFpRTIHeTqK5Zo1a2TcuHFyyy23mL55V111lbmPYM+laIaTvGd2izrrG35mkY76iKWigjiyEolpzm1HZg/OCuQ4oZIYRX2vCLTh9IFXdH65+++/3ywzZswwI2vqJJidOnWSyy+/3CwnnXRS/EqLxKIZTmqOMuaGg0OnjwTrdsm0r7hVPDN7fL+cpbBAju+i/aIJtIszqA4QpRJPoXDBBReYRadOePPNN03A98gjj5jRNuEiNMNJvX86bhjF080jwQKxHv20uPh+OQuBXHJ/PjT1RJyUejJ0nXFdB2TRhVEvk0w0/bY4o+ROxWnqmawjIXKCAggVyww93y+kmng1uSRIhxOCPJ/PZ6Y1eO+99+SPP/4wffF07jptpqmDsdBUM8kUNgGxIgMCAO5Qmgw9/bOR6ujbCDcHeTqf3cUXX2wmI2/atKkcf/zxZt3y5culW7duJvB7//3341taxB5nYxGNZO+jB6S60mTo6Z+NVMf/O7g5yNMM3tdffy2ff/65tGrVKuS+L774Qjp37iyvv/663HDDDfEoJwC7uKGPHoDSZ+78834BANwT5L311lsyaNCgfAGefw69AQMGyIQJEwjyALdxSx89AAVn6IOz82TuACB1grzFixfLo48+WuD97du3l6effjpW5QIAAInI0EfKzpO5A4DUCPK2bNki1atXL/B+vU+nU4DDMb8RACA4Qx8+NyYjKwNIdlv4TYs6yNP573Ti84Kkp6eL1+uN1UeDeGF+I7gRo/8BJcfIgQDchN+04o+uqaNolilTJuL9+/bti/apYDea4SBefXnsQh8ioOTs/v4CQCzxm1a8IK9r165FbsPImkAKKKovj104eQEAAFC8IG/cuHHRbgoglfryAAAAwFHS7C4AAAAAAMCGTJ7Oj+fxePKtr1y5sjRs2FD69OkjtWvXjmHRAAAAAABxC/JOPPHEiOv//fdf+eSTT+TZZ5+Vb775psDtAAAAAAAOCvKefPLJQu/XTN6gQYNMwAcAccWUCQAAAKUP8orSq1cvadu2bayeDrHCwTDciCkTAAAA4h/klStXTvbu3Rurp0OscDAMt2LKBAAAgPgGedOnT5cGDRrE6ukQSxwMAwAAACkj6iBv6tSpEddv27ZN5s+fL6+88oqMHz8+lmUDkAx0QvTg+fJ0svTgufQAAADgzCCvc+fOEddXrFhRGjVqZAK8K664IpZlA+B0GtCFB3wAAABIjiDP5/PFtyQAkk94xi44owcAAABbpNnzsgAAAAAAW4O8L774Qo477jjZvn17xH55jRs3ltmzZ8e6fABwYDoQzRTqQrNQAACA0jfXHD16tPTs2VMqVaqU777KlSubefJGjRolZ599drRPiXhgXjykwnQguoT3BwQAAEDxMnk//vijtGvXrsD727RpIwsWLIj26RDvA2E/DobhxulAdGEETwAAgNJl8tavXy+ZmZkF3p+RkSEbN26M9ukQT8yLBwAAAKSsqIO8I444QpYsWSJHH310xPsXL14sNWrUiGXZEA2aZwIAAAAoSXPNDh06yP333y979+7Nd9+ePXtkyJAh0rFjx2ifDrFC80wAAAAAJcnk3XvvvfLee+9JgwYNpG/fvtKwYUPxeDyyfPlyee655yQnJ0cGDx4c7dMhlmieCQAAAKC4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",
"text/plain": [
"<Figure size 900x650 with 2 Axes>"
]
},
"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 116,015,414 clusters\n",
"CUDA 116,013,348 clusters net -2,066 (0.0018%)\n",
"\n",
"exact-position mismatches CPU-only 67,148 CUDA-only 65,082\n",
" of which shifted by 1 px 52,084 51,984\n",
" genuine add / drop 15,064 13,098\n",
"\n",
"frames touched by a genuine difference: 20,426 of 50,000\n",
"[34.1s]\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":
"iVBORw0KGgoAAAANSUhEUgAAA3kAAAFeCAYAAAA4xtZyAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAai9JREFUeJzt3Qd0FFUfBfCb0HvvvStSlKIiKB1BRRFEbCAKKiCKFFFAqVIU4UNQQFQQRMWKiJUqCCJFQEABpffee8l+575xsiWbZJNs2HZ/52yyOzs7+3bmTfnPa1EOh8MBERERERERCQvRgU6AiIiIiIiI+I+CPBERERERkTCiIE9ERERERCSMKMgTEREREREJIwryREREREREwoiCPBERERERkTCiIE9ERERERCSMKMgTEREREREJIwryREREREREwoiCPAl769atwxNPPIFSpUohY8aMyJo1K6pVq4Y33ngDx44di52vXr165pFaxo8fjw8//DDVlh+K/LVOoqKiMHDgwNjXXCan7dixw22+V155BcWLF0fatGmRM2dOM+3SpUvo1KkTChUqhDRp0uDGG29McXok9HnmKV+dO3fOfO6XX36J8158+VLclSxZ0qwnzwf3U09nzpzBCy+8gMKFC5vjO/ffGTNm+LxKk/L51atXo1GjRuYcwuNHy5YtsW3bNq/zjhs3Dtdddx0yZMhgzj2DBg3C5cuXfUrT/PnzUaNGDWTJksX87m+++QaRhOuJ627EiBFu0z/77DPccMMNyJQpk1kva9euNfsanwfr8YBOnTqFoUOHmuuLggULmvxTuXJlvP7667hw4YLPy5k3bx5q1aqFzJkzI2/evGjfvj0OHTrkdd4NGzagdevWyJcvn8mD3Ke6dOkSZz6Hw4EpU6bg5ptvNvkte/bs5vpo1qxZsfMcP37c5PdIy4dhwSESxiZNmuRImzat44YbbnC88847joULFzrmzJnjGDZsmKNUqVKOFi1axM5bt25d80gtTENqLj8U+Wud8FA2YMCA2NeHDh1yLFu2zHHhwoXYad98842Zr1+/fo4lS5Y4Vq5caaaPGTPGTB83bpzjt99+c6xbty7F6ZHQ55mnfHX48OF4P+stX0pcJUqUcNSuXdusK9fHtm3b4szbuHFjR86cOR0TJ050LFiwwNGxY0ez/j/++GOfVq2vn9+4caMjW7Zsjttvv93x/fffO7766itz/CpcuLDZrq5ee+01R1RUlKNPnz7mnPPGG2840qdP73jqqacSTU9MTIwjd+7cjltvvdUxb94887uPHTsWUdmEx+T8+fM7zpw5EzuN6zhdunSO5s2bO3755RezXs6ePevYvXu3eR6sxwNav369I2/evI7u3bs7Zs2a5Zg/f75j4MCBjowZMzoaNmxotnli+Jt5LXPfffeZa5jp06c7ihQp4qhUqVKc4wnzcaZMmRxNmjRxfPnll+az06ZNM9/v6ZlnnnFkyJDB8fLLL5v89tNPPzlGjhzp+OSTT9zmY3rLli3ruHjxYrLWgQSGgjwJW7xgT5MmjaNp06ZeL6p4sOIBN5SDPJ4czp075whVqRXkecMLL8538OBBt+m8qOMJ0Z948SGhLTWCPLFcunTJcfny5QSDvLvvvjvR1cVgi+va84KUgRuDrytXrvjt861btzYX6idPnoydtmPHDhN49O7dO3bakSNHzMX7008/7bbMoUOHmsDvr7/+SjBNe/bsMWl6/fXXI/I4w3zB4IVBhyvemON6+eyzzwKSrpTs0wxWXQNWG4MpLvfXX39NdBk1a9Z0VKxY0W2/Wbp0qfn8+PHj3fJEoUKFzP6TWPA4c+ZMn9fpgQMHTJDp680TCQ4K8iRs3XPPPeagtGvXLp/m9wzyeAeWB0D+d7V9+3YzfcqUKbHTtm7d6mjTpo05uPKOLe9CNmjQwLFmzZrYixZ+xvXBaTZeOPTs2dNRsmRJc9HAC4xu3brFOTHwc88++6xjwoQJjuuuu87My+fxYXA7aNAgMy/v1vEOcb169czJwXb+/HlzQnX97i5dujiOHz/u00mOv+Pxxx+Pfc31wnl5N7FTp06OPHnymO+9//77HXv37nX7XELrxBuuJwZlXF6WLFkcd955p2Pz5s1x0mangdsqvu/i/J7TXLcrT5As/a1ataq5aOPd/latWplt7Yp5hsHqokWLHLVq1TIBI/NCcrYr77ZyW3EZVapUccyePTvOOmCJwkMPPWTyGPNasWLFHG3btnW7kbF//35zkcmLJX4vv593YhO6sLbNmDHDXOQWLFjQ/G6m56WXXvJ6kfL777+b/Yzbg/mrdOnS5vclJb32dvDkuQ3t7ciLF66XG2+8MTZ99nriZ/g6c+bM5qLILq113Vbebiow/3rmPW+lw507d3Zcf/31Ju/ly5fPUb9+fcfixYvjHBs8H/b+4e032flnxYoVjjp16phtz1oGw4cPd1y9etUtTRs2bDDbhvMw4OB++t1333k9TnnDi0kel7JmzWqWwfzKz9vWrl1rlvX+++/H+ewPP/xg3nO9MfbPP/84Hn74YbMuuG257t9++223z9nHUebtHj16mH2AwQ7zRUqDPB4L+Fs88zWDNn6n63EuJZ/n+1xfLPXwxNKScuXKxb5mCQs/61m6tG/fPjOdwV58vB2T7Hxpv/fHH3+Y4xCPR9xHifmcxxzOy32C/7nPMQh1Zec/liTZx1GWTnJ/5P7N4waD2Rw5cphl89jFgNzz5uiQIUMcFSpUMNuc+bB9+/ZxSjP5Hczb/A6mift9y5YtEw1MWULKNLoGw9x/PNeLvR97O37Y+efHH3903HTTTeb7md4PPvjAbT5f9mlbaty44TnD202G+AJ/HhM8lS9f3hwTbB9++KGZl6V3ieG1AM8NvmrWrJkpyZbQkTbQ1UVFUsPVq1exYMECVK9eHcWKFUv1lXzXXXeZ72Q7P7b5OnLkCH777TecOHHCvD9z5kw88MADyJEjh2mHRqwnb7fhqVu3Lvbs2YO+ffuiSpUq+Ouvv9C/f3+sX7/e1MN3bXPAevG//vqreZ/1+/Pnz+81TVeuXEGzZs3MvGxz0qBBAzPt999/x65du3DbbbeZ+vgtWrQwbUD69OmD22+/3bRhHDBgAJYtW2YedjqTqmPHjrj77rvxySefYPfu3XjxxRfx2GOPme2S2Drxxk4r1yt/e82aNbF06VLzGxPD73rnnXfwwQcf4KeffjLfWbRoUTRt2hRDhgzBwoULY9NVpkwZ8/+ZZ54xbaief/5503aC7TcHDx5s1tuff/6JAgUKxC5///795rf17t0bw4YNQ3R0dJK36/fff4+VK1ea72CbDeal+++/H5s3b0bp0qXNPPzeOnXqmPYYnK9cuXLmu7/99lvTtpDr78CBA6Z9BdPA7+Lv4XZ87bXXTFswtr9IyL///mvyM/MM22hs2rTJ/P4VK1bEriP6+eef0bx5c1x//fUYPXq0yfdc/pw5c2Ln8SW9ScVlMq/269fPbEe2dWLbKE5jPub653p96aWXcM8992D79u2mDU9K2e13uW9wv2NbLuYrtrPh9/I/23UyfzFfdejQwewDxHYxCeE2e/TRR9GzZ0+zfC6Xv4ftxNq1a2fm4XpjfuI2mTBhgtnvP/30U3Tt2tWn9C9atAiNGzc2+ZD7Adc99ztuQy6nTZs2qFq1Km666SaTR5h+V9wX+J3MG/T333+bfYHbfdSoUWadME9wf+Hxj7/DFX8P2xNNnDjR5M34jlu2xYsXI1u2bKbNEvMN08M8yXazru2OmP/YxtYVf6P9PtMYH18/v3XrVpw/fz52uue8c+fONelkmz5+htjmyhXzBvcD+31vmF+4DZifn3vuOTzyyCNx9hG+99BDD5n2iWfPnjXTuN9VqFDBTM+dO7fJK8wjPEZyO/F7Pb+Hy2HbwzVr1pjjE88NPNZw+tNPP22OT9zvmQd79OhhPhcTE4P77rvPnFN4rOO62blzp9nWzP+rVq0y+xrTw2M/zyeTJ0827bn27t1r9g3u92xTFh8eB5k3KlasGDvt1VdfNce0Z5991uzf9evXN23HEjtOcH96+eWXzbH6/fffN3mobNmyuOOOO3zep1OTfTxlO8OE2HkmvvzH86DrfkO8HuGxl8dtHjN4TOJ+yu1J3N48L3B/5vH7rbfeMueqEiVKmLZ7XHeebR25Prgf87rGbtMuQS7QUaZIamDVAmZv3s30VXJL8lg9h6/ZjiA5VRN5dy46OjpOqQPr0nO5vINu42veZfWljQbvnHP+9957L955WP+e87DNiCtW3+B0tmlMbkkeSxlc8Ts4nXeLk1Ndk3dl+fm33nrLbTrvjCdWkud6x5fV6Vwx7byL64p34TnvqFGj3Kaz/Qfv6LtWz2L67bvjKdmuBQoUcJw6dcotD/PzrndvWQrDO/ied81dsbSBpRM7d+50m/7mm2/GuUOeGJZmshTDvuP8559/xr5XpkwZ82BJcHx8SW9SS/K4/nln27P0iaXorqUEdhvMb7/91i8leZ5YlY/rhm1qWErtS3XN+EryOG358uVu87JqFkuqbS+++KLX6n6cx5eSPLbxYmnq6dOn3X4D2/QULVo0tmrX2LFjzfJYQm7j8YYltSzZcf1efs61+iJ17drVlJzYxyj7OHrHHXc4fMVjx+TJk02+43Z89NFHzTIee+wxt/lYgua6jjxLzdj2OiG+ft6uFvfpp5/GmZfz8D1+htjujuvKG5a6sOQvIfb5hVX5vO0n/fv3dySG25UlczyuuR4v7fz33HPPuc3PtumcPnr0aLfpLC2vVq1a7Gv+fs7H0jZXPMa5Vhu0j3HcN5OKpWpsYuHJzkdffPGF2/T4SvKYB12PgTxOsVTRW2lsYvt0apTk8VjKY5nn93jDKpLeSoeJNTZYoup5POBxl+cp1qhhe1PWqGGbOvsYyfMw58uePbvZj6dOnWrOYax9w+l9+/aN811z58417/FcLKFBvWuKpBDvnLK0ZOTIkeaOGO+M8o6nr7777jtUqlTJ9OrGu2v248477zR30jx76WOJXK5cuWJf846d6+fs7/7xxx/NneUnn3wy0TuJ7KXLFXvl4t0/3s1MrnvvvdfttX0Xknd+k4OlbcQSD1e82+1v3CZc9yydc123vNvLO+2e24Tbg9slJduVd6dZcmHj3Wfe0bbXF0sGWRrz4IMPJlgyxO/lsnjH1vV77RJPLiMh7C2Q65S/laUm6dKlMyVItHHjRvP/n3/+MaUbvDPOPOaNr+lNKq7PIkWKxL5mSYx9l9m1hMCentz85g1LodjzHH8zS3+4briP2OslubiuWVLhub+4pp3rkvnJtYSDHn744USXzxKf5cuXm5JzlhLbuH3btm1r7uCzFMfev1h65NrrLUv6Ll68aHopJpZa8XezpJnr3DWfsWSA77PGgKtWrVr5vD5Y6s7vYokLS46mT59uSiz5n8dXVwn1rOhLr4tJ+byv86Y0TQnxth5ZAsWSa5ZSMV/ywe3M7e4tb7KE25W9r7D0zXO6ax7ksYUlOCz9dd3m3CeZh+1jGl+nT5/elAhOnTo13h5Ivdm3b1+ipby+YBpYymzjPlu+fPk4xwN/7tPxnYs9saST24C1jFjC6Kv48o7rdPs7WTLPklieC1grhaX3W7ZsMTVrXOdjz59ffPGFqTHAcxhLgFljhtcyzFeu7O3CUlkJDQryJCyxegovPlhVK7XxAMuTAi/eWcWOJwxe1LLa0unTpxP9/MGDB00VSZ5cXB+84OcNRFZ98qz244oBpuvnWC2ODh8+bC70WTUqPkePHjUnNs+LcP4mnrT5fnLlyZPH7bVd7YjVnpLDTqvncplOf+M24bpnoOW5XXjxmtg2Sc529fxd9jqz1xe7seZFBKuZJpb22bNnx/leu0qQ5/e64kmdVawYELB6Jy/aWIX066+/Nu/baWHeooTS4mt6k3NTxRUvJhOanpQuyhPCi57OnTvjlltuwVdffWXyAdcNq0ElN0/7uu3t/O9aRdjmbZq3bcE85y2f2tW37H2d65E3aKZNm2a2HzHgYxBq5yHOy4tYDhPgmc/s6py+7CNJwRsu5Bo8cr15O0bZ1fA884QnXz9vb5/45uXx0q6+xnmZ53iTw9u8iaUpMd7WI2/KvP3226YaJqvMsooe8yaP697yZlL2Idf9h8cWVtXjdM/tzirH9jbnOYnVPRkUsIolX/PBKoGJYXrju3Hk733K3/t0w4YN3daJtxusDDIZePFcxusGX/JDYvnPdRn2vLwecWXfXOQwIPaNSb5mtddbb73VbV7eEOR2Z1VfV/Z2SenxTq4dtcmTsMQ71DzgsjSLd6mTc6FpH9B4B9uVt4tk1mPnnTK7lOPzzz83Y+qw/QHvFCYWkLIdA9suxPd+QnfzeEHvmkb7oo0n+CVLlpg7dvEFejwh8GKNF+2ugR4vCHnSZpsO1xOk57qglASCSWGnld/negJnOv2N65zrmW1PvLUb85zm7Q5rUrdrYngiZ75mfk4s7SwF4rhM3tj5I76SXd5JZ3Bnl96R3bbUZueVhNLia3pd9zPX9ZpQMJpc/K6TJ0/Gme7Ld7EUiaWFvNPtypcbOf7APM+LbE++5H9e0PEYwLZanri9PfMjS9F4d59tzVgawgtf19/N5dmlgLyI94Zjw/mzBMuqMQe3YxnbvbGUkccF13Z1bPNKLPlMiK+fZ4DCfdme7orTWIJm52O7LR6nM3iw2UFQYmlKjOd6ZH5mCRvblbH9mY37k+s4sP7APMJ8yLZ13rjWRODNIj54o4Bt9XhDgG0qeVOCbQcT+g5/p/ta7dPvvvuu22c9j/EM8Ph9zMs8xvp6XWLnGeYp+yaKjdNc8xSP/QmNE2nvP8zPbOvq7fjhbV8je7sk9dwlgaOSPAlbbCDMg9VTTz1lgi1vA64yQIoPBw8llsa4YqcRCWGVEA66zZO9fdfM211EG6ttsOobT54cANfzYacjPvwe1/nti3j7blxCg40zELZPdq54V5NVfez37fXhuS4YFHhW6UiK+NaJN7z7SR9//LHbdLv6iT9xmzDvsFqKt23i2alCfMtIyXb1xJMyAy9efCcUlPB72VCfF6bevjehIM++gPQMYnnx4pnHuXwGsN4C/6SkN779LKF9M7n4XbwJ45pm3jRgZz6J4brxXC9MMzsv8GeJdXy4LrldPe+u+zLwN6teM+BgiaxrungDiPs+Lza5TW1NmjQxVWLZAQsfDGBcq4WylgT3R1ad5EWlt3zmrSQlJViySK6lDqwuyuMPj1euWEWQ+dw1yPLG188zAGQVRa4/14t4dmDFauTsrMTGUiCuL8/jLl8zD7EqnD9xmTxWeeZNVgO0S2L9hccW7i9crrdtzs5fPPFmANcjq+CS6znRGw6CzuPmteDrPu0r/v74jvHMKwzw7E7heGPYV9wXWZLOfdV1m7Lk0e4sxzVP83fxBrcrvmY+cd1/WPWX1TU9j38//PCDqe7r2SGMXe3Ws8q4BC+V5EnYYk9uvEPHnqLYyyarZfCgxeCOFyeTJk0yd8B48vaG1QAbNWqE4cOHmzvXPCizeoVddc31pMD2ImzHxjtjrMrCgzinu95ZZWDAC7LPPvvM9JbICwFO491NXmSw/Un37t3NRRMvvnhSYE+F7OUqsYsVb3hRxgs09sLGEwEvyrhcVsVjWwveTWVve6zGwfYcPNjXrl07tndN9rLHO/U2PmcvZ+yxkRecvNhkFSH2cJhc8a0Tb3jhyXXEXt0YgPIkyl7FPvroI/gb1wPbk7BEg3eh+b28UGZJCEtHmUbmp4SkxnZl9SL2mMbPMW+xBIGlO7zxwECMd9JZXZclMOz5jlWGeeHBYJ/tQHjyZslyfHeQ+RnmdeYZ5gFWOWJQzZ7qPPGijfsOLxr4+1jiw9/G6mJ2IO5LenlnmqV+bN/HtPOCmhfE7JHV35iH+b2s+sebP7xgZRXrxHrqsy9w2RMr1wvzP/cpppclViwJsvE38Vgxa9Ysc5OEv413vpMa1HvLTwyqefOG38sSEd7gYO+nlFC1bOJxjPs7jwO9evUyxyn2rsnAkaVZriVEvDBnGx1uP64bXkR67uesesdty9Ia7gv8fQyA2O6HAbprT6xJwd/EYyzbh3E9shSZNwp4nGDbYbaJtXFd8Dfx+3n8Yv7ib2FJEy+IXXviZJ7i/sxjot0GOSmfZy+urNnAfMC8zH2Kx0JuW+7LNm5v3uTjsZLPedxiSShrdrA6pb8vkLl9eIxhm3A7n7H9JmuW+LsHRJ4zuG9zn+3WrZsJPHiMYGk9g122n2SQwWMMtz+3IY8LXFd2jQaeUxPCQIj5m9VdE+qF0x983adT6tChQ2a/4/mD24Wv+bDxeOx6TLaPFTxm29i+jnmV1xm8puHnmQ95DWO3lbWDZJauc9/msYh5nDe2mCd5TmcbaRuPA9yeXCbXA9Pw5ZdfmuPzm2++GadXYgaVvHnjy01OCRKB7vlFJLWxhy/2nle8eHHTCxV7HOPYOeylzLXXP28977EHqgceeMD0ysVeLdm726pVq9x61+Tg2hwniGNEcdns2ZBjnP3vf/9zG0yXYxaxZzWOS+Q5Jhx7QnvllVdixx7id1WuXNnRvXt308ui53hqvmKPYvyd7EWOy2UPW+zxkAPFu87DcdCYHo6pxl4KOXaQ5zh5HB+JvXVxvCP2CsZ1xXUbX++anr1KeuutNKF14s2JEyccTz75pOk5jGOhcXygTZs2+b13TRt7+LvlllvM+/zN7E2yXbt2Jg94jnPmTUq3q+e6pb///tuMZcVtyWUyXzP/uY6Tx9/4/PPPm/HWuE2Zf6tXr+7o16+f1/HuXDFvcPw0rl+OG8XxtFavXh1nbEhib28cO4m/iz0Kcv3wtyU1vRwj7rbbbjPrmWP7cVtxrLb4xsnz5G39xddLIXuRYw9+7H2PPViyJ1lfetdk/u/Vq5dJHz/LXgfZ86O3z86bN88cY7hOfB0nz5O35XKcvEaNGpnv5zbt0KGD+T2ePZ8mNk6enZ/Z46a3sRjtMfDsMcnYq543/B3cH+3xGJlfuB1fe+21RHtFjA/zFHs35DhtXKY95iF7bvQcN5DYWyjzOudn/uKx11svmOPGjTPpYI/Cyfk8cb9n2pgm9krIXim3bNnidV72asneNO08z7zkOeZccnrX9Dx+EXub5dh5uXLlMsdS9k7JvOLrsTkpx0b2Psmeeu3xQ3m+47mPvVb++++/sduQvUby+7kPcN9nPnft6TY+XJ/sRfbzzz9PUe+a3o4Tnuf4pOzTKeld0057fA/P5XLsQe6bnubMmWOm2/s/z0W8/vDE644RI0aY3jQTOqcTxxFmL+TMO3b+53nPE3vf5Trx7JlVglsU/wQ60BQREZGkY4kzS59YKml3oCFxsQSDHXGxVE2Cm917p2eVw0jAGjKsccR2lp69nQYSazGxVJpjvbK0UEKDqmuKiIiEAFYlY1sxVm1mWzJeCLLtFatiKcCLn93RhWfbYwlOrFrMqoUMyF07/4oErPbKpibBFOARe1tmb6EK8EKLSvJERERC5OKXbcvYBoolHWwDzHZebB+V0t4rRYIJA3K2A42vzbxcOxyChW1w2RbQH2MYyrWjIE9ERERERCSMaAgFERERERGRMKIgT0REREREJIwoyBMREREREQkj6l0zFXDA43379pmBKNUYXkRERERE/NVj8OnTp01vy9HR8ZfXKchLBQzwihUrlhqLFhERERGRCLd7924ULVo03vcV5KUCluDZKz979uwIhpJFdoGbK1euBCN+EeUh0TFIgo3OYaI8JDoGOZ06dcoUJtnxRnwU5KUCu4omA7xgCfI4phLToiBPlIdExyAJJTqHifKQ6BgUV2JNwlSsIyIiIiIiEkYU5ImIiIiIiIQRBXkiIiIiIiJhREGeiIiIiIhIGFGQJyIiIiIiEkYU5CVg/PjxKFWqFDJmzIjq1avj119/vXZbRkREREREJBkU5MXjs88+wwsvvIB+/fphzZo1uP3229GsWTPs2rUrOetZRERERETkmlCQF4/Ro0ejQ4cO6NixI66//nqMGTPGDDw4YcKEa7NlREREREREkkFBnheXLl3CH3/8gSZNmrhN5+vffvsNISfmCqIungYObwauXol/vkvngO+6AztD8DeKiIiIiIiR1vonro4cOYKrV6+iQIECbtP5+sCBA3FW1sWLF83DdurUKfM/JibGPALNsf5L5JnV2fk6XRYg//XA0X+B3KURtW+N+wdWTUZM52VAvuuufWIlKDEfOxyOoMjPEnqUf0T5R3QMklAVE2TXQL6mQ0FeAqKiotxecwN7TqPhw4dj0KBBcabPmDEDmTJlQqBFXTiBqMxPITrmMqIvHAcuA9jLd4oA+/i/eNwPTRhh/l3JVxExWQtd6yRLkGHev3LlCtKmTet1HxBR/hEdfyRY6Rwm4ZR/zp8/79N8UQ6mXOJU18ycOTO++OIL3H///bHTu3XrhrVr12LRokWJluSx/d7x48eRPXv2oIj4mZZcuXIh2nEV2Pgtog5vhqNSSyDmKqLfrQNHVDQcXVaYkr3oIbnjLqP1NOC6exj5BuQ3SBDloWjV8hblH9HxR0KHzmESTvmHcQbTcvLkyQTjDJXkeZE+fXozZMLcuXPdgjy+vu++++LMnyFDBvPwxIwQDJmBeOfBSk9aoEpra5r95sCT5nns61ePAhu+AmY+Hfv56C/aAekyA11XWv8zxw0EJbw581Bw5GkJLco/ovwjOgZJqIoKomsgX9OgIC8ePXr0QNu2bVGjRg3UqlULkyZNMsMndOrUCWEvTVqgahvrcfAvYMJt1vTL54D/3eCcj8Eg5xURERERkaChK/R4tGnTBkePHsXgwYOxf/9+VKpUCT/88ANKlCiBiFLgBlPSh3/nAR+3cn9vSB7g1SNAmnSBSp2IiIiIiHhQkJeALl26mIcAKNcI6P43cPYwcPk8MKWptVqG5LX+NxwA1OwAZMyh1SUiIiIiEkCBr1gqoSNHEaDwjUCJWkCb6e7vzR8EjCgOjL6B3RAFKoUiIiIiIhFPQZ4kz/XNrWqcHE+vRG3n9FN7gEE5gX/nas2KiIiIiASAgjxJmQIVgSd+sAK+Nh87p3/8AHDxjNauiIiIiMg1piBP/Of6e4D+x4Fsha3X7zfU2hURERERucYU5Imfc1Q08Pwa6/nhTcDaT9RGT0RERETkGlKQJ/6XLiNQ/L+x9b7pbLXRG5gD2Pdf8CciIiIiIqlGQZ6kjid/BG591n3apHrAiV1a4yIiIiIiqUhBnqSepsOsDlnuf9c5bUxlq1SPj4XDtfZFRERERPxMQZ6kvqoPAS9ujTt90QjgtYLaAiIiIiIifqQgT66NLHmtUr3qT7hPv3IeOL5DW0FERERExE8U5Mm11XyMFezxUeoOa9pbVYEfX9KWEBERERHxAwV5EjhtZzmfL58ILBwGXL2iLSIiIiIikgIK8iSwY+r12OR8veh1YEgeYNR12ioiIiIiIsmkIE8CK3shq+qmq9P7gS3zrEHUD20Ezh+3psdc1cDqIiIiIiKJSJvYDCLXBAO90weB8bcC548B01vFP+9LO4EM2YDoNNo4IiIiIiIeVJInwSNbAaD3tsTne70EMDg3cPn8tUiViIiIiEhIUZAnwSUqCnh5F3D3KODl3UDv7UDFFt7nHVpQ1TdFRERERDyouqYEn4w5gJodna8fnOr+/rZFwLR7reeDcgKNBgJ1ul/bNIqIiIiIBCmV5EnoKV0XaDTI+XreQJXoiYiIiIj8R0GehKY6LwD9/+t10y7Ru3o5kCkSEREREQkKCvIktMfZ6zDX+XpIXuD8iUCmSEREREQk4BTkSWgrdjPQ/C33njf/VxnYvlhVOEVEREQkIqnjFQl91dsDF08Dc16xXp/cBUxtbj3PUxbovAxIk87quVNEREREJMypJE/Cw23PAX33xZ1+dAvwWj6rzd7AHMDZo873HI5rmkQRERERkWtBJXkSPtJnAQaeBGKuApfPWb1urnzffZ6RpeN+7qUdQKZc1yyZIiIiIiKpSSV5En6i0wAZslkDqj+/Fnj0q4Tnf70k8M8cleyJiIiISFhQSZ6Et9ylrAdL+C6dBRa9ASwdE3e+T1o7n/fZYwWJIiIiIiIhSEGeRFZ1zsaDrIeNJXiuAR4NL2r9v/kZoOlwq2RQREQkpa5cstqJF65mDQE0JI/zPU7bt9p63v0vIMd/5yIRkWRQdU2JbOWbWKV8ffbGfW/Fu8Dg3FaHLWzn54mDrx/bFrfdn4iIiKuYGGDVFCvAIwZzrgGePc32vxusc8/+dVqPIpIsKskToQxZrWDv+E7grSpx1wmDPXr1qNWpy4ji7J7T+f73Pa3/eSsARzZbzx/53AoCf3rZOV++64Auv2s4BxGRcMebg3ZNkB9fTN4NwXdvB2p2tNqYJwd7kT53DMjiEVCKSNhTkCfiKlcJK9ij88eBZe8Ai0c63/e88+rJDvDokwfjvn94k3WHtvFg4KsOQLbCQLc/gbTptR1ERELV1Svezw9dlgNZ87sHeA99CuxbAyx+w7ox+PQv1s3DDNmBi6eAf+cA33R2zs/P2p/vfwzYMh8o0wBIk8gl3O6VwAeNnK/zXQ9cOGGNH9v+O6t0MeaKzj8iYSrK4dBgYf526tQp5MiRAydPnkT27NkRaDExMTh27Bhy586N6GjV0E2yM4eBN8vGnX7dPcCDH1lt+rbMS9lGSpMBeOWgM7jM/F/JYZBQHhLlH9HxJwHf9wJWvpf4KkpKx14M7OxaIt6UbQw89qX7NJbanT1i3Zxc/7nvm+zx74BStztfb/8VOPovUONJhAOdwySc8o+vcYZK8kQSkzWfVbp35SIwpRkQnQ6o0x2o0NR6/7EEhmjgnVLXA8K7dwD7/4w739WL1oDtrthOkNVIk4L3bHinVuP+iYhcO74EeL3+TVrPzaymycf/KgEnd8d9f8tcq90ej/f3vg189qj35ZS8Hdjxa8LfNfUe79PZ9vyWZ3xPs4gEDZXkpQKV5EmCVXr++hpY/wVw33hgzUfAfJfePj3d3gto+Kr3907sAsZUBlpPBbLkA/asBOYNiDufXf00jO5iSWhR/pGwzT8sNRtZxvm6/3Hnjb1fRwHzB1tBGMdszeRxIy+51UGzFgDO/FfzIzGux/+9q4FN3wMV77Pa+lH19sAfHya+nDuHA7d2Dtn25EGdhyToxQRZ/vE1zvA5yBs8eLDX6fySChUqoEmTJkHxw4OBgjxJsgungI2zgVldrJLCmMvO92o+BVRrBxTy6BBmUn333tjikzkv0ONvYHY34M9PgdL1gHazQvoAJ6FF+UfCNv+81xDYu8qvN9V8wku3bb8AH7WI+16bj4Hr4ymZ8+bEbuCTNsChv4AClax2eqf3Axe8/Jbn1wC5SyPUBHUekqAXE+5B3k033eR1+okTJ7B3717ccMMN+Pnnn5E/f35EOgV5kmKsGvpaPPsSG80f3eKfldxhHjDjYeDsYev104uAwjcG/QFOQovyj4Rd/jl/wuph+fWSzmn3jAFqPHHt07LiPaua/h0v+ne5Zw4Bb5aLO33AiZAr0QvKPCQhIybcg7yE7N+/H4888gjKlCmD99/XmGEK8sQvjm4FxlVLfL5XDlsn3PVfAtfdDWTMDswfAtz4CPB+Q6sjl6R4fDZQ6g63geJjOszD6YM7kO2GxohmlaN1XwDfdLLu+JrPfAfkLQ9kK+B9mes+B75+yuqs5qGPk5YeCXnBdoKU0BJ0+efPz4CZT4d84OMzXiZu/Bb4vJ17DZO730SoCLo8JCElJpKDPFq6dCnatm2Lbdu2IdIpyBO/unLJOYCuKwZMrT8E0qRL+PPs/IVt9yq1BJoMAY5tB/7+Bpg3MHU2VK8twOGNQLFbra65j+8A3qrqfL9ya6vHNkcMULJO6qRBgkqwnSAltAQ8/6z+CChSzeo0ZWKduNUYb3sOaPIawp7nkAzX3wu0mGDVPGEnYWkzIFgFPA9JSIuJ9CBvx44dqFSpEs6cOYNIpyBPUtX+dUCOoikfZmHpWGDuq0COYkD3DcCls8Cwwrim2Oi/+Vv+W97hf4CFQ60g9uHPgOyFgEIuAaYERLCdICW0XLP8c/kCsPA14LdxVq/JZRsBP7wIrJjkff6mI4ANXwMd5oRvKZ6vVTgz5wGe+BHIWRz45yegRB2rZ+ogoWOQhFP+ueZB3qxZs9CvXz9s2LABkU5BnoQ0dsntEYDFrP0UJzMWR64Zd1nvFa4GPPI5kC4TcO6I1XHMineBNdMT7j7c28VBkepA+x+AdBnjvsflskpoYgHtxTPA4c3A+w0S+F3XqEMECfoTpISWVM8/MVeBDV9ZVcp99dxqII9Lr5qRJL7aJd6O+VHRQJa8CDQdgySc8o/fgzwu0Bt+wcqVK9GzZ0907NjRBHqRTkGeROwBjqWMv48Hmo+1evNkN9/1+1qBHO90s6ro2LgduySqfj+riid7fPvySSu4fGCKdZF15F/g7Rq+LafLciD/dUn/fgmPE+TJvVaJg+cNhY3fWWOMdZgLFLs5UKkLX7zMmPMKsOxtoOdmIFvB4Mo/s18A/piS+Hwci67qQ4lXkY8UbJv9dUff5g1wm8WgOQZJSIoJ9yCPPyoqnh2U05955hmMGTMG6dLp4KcgT8JNqh3g7FJDf+Iddo4byGCw8gPArGedHcTYyjQA2s70/3dL8JwgGdCxOvKOJXHHFOMF5+qp1o2IxEp8OYYYxxe7d2zqpjdc8RJjwRBrzDjbq0eBNGmdr3nz5/J5YNUHwMr/Om9r8CpwR6/Uyz9nj1rjlVZr615NvcVEK7/YY46y1sLTC/3zneG8jY9tAy6fAz68ByhwA7Bzqfs8GXNawy+kywwsHgkc3gTUexk4+DdQ4jarg7CClVMtEAy2i3QJLTHhHuQtWrTI63QuvFy5csiaNWvyUxtmFORJuEnVA9yhTcD4W7y/99Cn1hAPvuC81/1XndTTjy8DyyfEnV6xBfDg1CQkVoIi//C0NchjYGkGDuzM59Te5JUW+6JeH6B2N6skWVJ284aDg+cuBfw7F/j4gQTn8Wv+Yd7h8DRXL8V9r/tfVntnSblfXgd+GZb8zz/Bdn21wvYiXUJLTKS3yZOkr/xIzZwSeq5pHmI7vOg0QPoszmnsoXPPKmBWV6Dbn1aVuyP/ABP+uwhg20G2IUxO1az737WqYPkDD6fXskrSiV1AtsJAzOWgDjz8mn9Y+sbSNX+7tYtV1dgX8bXvZC+DadJHTiccrvvnlx3cBwX3ps104LPHnK85qDZLgBIRU/dlXN67DukemITojNmSl0b2Mnx8u1XC9O1zcd+v1RW4c2jyli2pV2Oj5z/xD82TBLoOknDKP34P8s6dO4cXX3wR33zzDS5fvoxGjRph7NixyJs38A1qg42CPAk3wXaAc+sNj+1jGBQmxYndwJhK1nO7d1Eui9U62RV4Yhe0/Hyp292nz3kV+G2scxgJBqKJrSseftlbXUIXMfYhmp1D/PSSszqbN0VvBh6cZvUqGm75h4NPv14iaZ+pcDfQeop71+57/rA66LmjN1C3t3v7qjcrAGcOJD1trP65dIxzWBJ2SlT+TkSEncuAKU3jf/+ByVb1aTOOZsH4t+MjX1jDFLCTjoS29X3jrVI410HH7Zsr/NzZI0Desu6f+foZYN2MuMvqsRF4+2bg1s5AA/UnkKp43OJxk/sJx3blfrf5R6t9bKm61g0S3iSY2tz754vXsnrvTOYNlKA9h0lIiAn3II8B3vjx4/Hoo48iY8aM+PTTT1GvXj188cUX/kx3WFCQJ+Em2A5wfuGtyl981T7PHQPeKOV9Of2PAWcPA6MqxH2vykNAy3fjT8NrBYArF7x3TMD0XTwFjCiOJLvteWtMxHDKP+83Bvas8F6i9tdM4AuXktxGA4E63eE3LAWa3ATYs9L3z6T9r2T1ynnr/4vbgCx5EDQY7LJtVN0XrY6RkotjcLJEOSnjxm36wb0atreSUY5F91VH4N858S+H7Wp5c8azSneNDkCtZ62Omdj2bmTpuJ9Vb7vBi6W70+6Lm6+o9/ZkDR8UlucwuWZiwj3IK1OmDIYOHYqHHrKqNa1YsQK1a9fGhQsXkCZNEu+ihzkFeRJugu0A5zdDCwOXz8ad3vR1K/hi5wvlm1rjPiXXkz8D+a8HVrxnldrd9Kg1dh/H4mKPg65eWG+NMzX6BuDUHt96HV01BTh3FLh60f09jhNYIYESFtvYm6yLqm7rgFxeSk8unga2LgRK1LaCFPZmun0RUK29e+cZqZ1/XKt8PbsCyFPWvQSX3bozSE7Nng9Zmjo4heNTPrUgblDFQabzVQDSZwUG57Km9dljDb7tTzzd8zcMK+TeJo2dYbDTDNszi+OOL8kBwb/tCtTs6L00maUzadP7npZDG4EDG4AqrROe7/J5xJw7juMnTyHP5Hja7vqqSA2rtOiphVapoQS377oDqyZ7fy+JQXrYnsPkmogJ9yAvffr02L59O4oUKRI7LVOmTPjnn39QrFgx/6Q6TCjIk3ATbAe4a3YhEZ8XNjire3qW6nFcqK+fBtZ/nrz0NBwAzB/kPq3DPOs/g5iiCQwXsW0RMO1eL92+P2wFZCyR4jLsEsPlk4AfX3TOW6Yh8NAnwKG/rECEVajYSUV8fLzQSnH+2fU7MPnOoOiKPdbVK9Y6tTsOeXqRs9OOkYmMn8Z8wgCVnQ5tmQfM6Rf/OGNZ88ff1pMBOKvAFagY9z1+huuNVSlZHY7bc8nopP1G9oZ47rgVEHkr9bbd9Bhw3ztILbH55+gqRG9dANz8NPB2Eksf7Y5eJDR5lv7WfgFo7HGcjNRzmKS6mHAP8lhad+DAAeTL5xwAM1u2bFi3bh1KlQqOA2fJkiWxc+dOt2kvvfQSRowYEft6165dePbZZ7FgwQITpD7yyCN48803TRBrW79+Pbp27WpKK7lBOTzEq6++Gu8QEp4U5Em4CbYDXKphEGSXpHhioFWspvtF/hCX6ndd/3BvC+TrgMEMGFdPAxa/Efe9dFmAe0YnrWMYz3SlJl+CvLNHEIMoHDvvcM8/DFCGF0288xvXbcKeLRsPRkjgEB4cYLvHJuv1aD+Mz3hLZ6DZf+ezj1vHrcrIAJ2BOqsWu5bMJbT9UjqMSVI6PfLn8efwZuCd/8Y0bP8DULK29XzHUquaX/FbrFJqemknkCmBIFVCg+dNp1s6WZ331HzK6lk3gZoFEXMOk1QREwnj5DVr1gwZMjgbsM+ePRsNGjRAlizOXvC+/vprBDLI69ChA5566qnYaRzawR7e4erVq7jxxhtNoDpq1CgcPXoUjz/+OFq2bIlx48bFrrjy5cujfv36ZmB3llS2b98eAwYMMAO++0JBnoSbYDvApapT+60L8pK3W2N17V4OVHkwyQM4G1vmA9NbOi+GXcdlY5sxth2zsdOOJf/zT5shBka8AD76r2/z9zsIDE1GD3bsuCK7yxhjrv6cAcx8Jvbl0Q4rkatIWSv//D7R6kTGU9MRwE8vO6srsvoiB7o/uiW4SvGSa/vi+DuWIJa2tfvWKoH7uFXqpsXOX6y+ufxd4Ib7nR32sPdJ3njwVONJq2OTlu/FHVA+FUXU8UcS7315RDy1x3KXAZ5f7fUt5SFJibAP8hjo+FKSNWWKS9fkAQjyXnjhBfPw5scff8Q999yD3bt3o3Bh68JkxowZ5rcdOnTIrKgJEyagT58+OHjwYGxAy5JABoF79uzxaR0oyJNwE2wHuLBlB4UcJiJXSf8s07XjCXaIwcHB961xvu8aOHEAcQZfG2fHbSf462igYBWgXCNgwWtWpx32hRVL1zZ+awXDZRsBp/YBo6+PkxRHrecQtcy6oRbocbMCxlvJWaelQEGP6r+7VwAfNPZtmQm1G2UJM4O3NR8DtzxtbX+2t0usvR8vDXb8Clw8Y1WTi0oDDDiGQNDxR9ywDbFdSuutnTJ7zVUekjA+BkXkOHkM8i5evIhLly6ZdoKtW7c2vYLaVTH79++PWbNm4c8//4z9zPHjx81GY/VNlt61a9fOrDTOZ1uzZg2qVauGbdu2ea2ayu/kw3Xl8/u57GAZJ49pyZUrV1BkTgk9ykNhWO2J1ZviG1vv6iVELR4JBzvZyOqlhO/IP4iObwD7JHDU7g5Hg1cR9VYlRDEwTEBM/+OIOJfPWwF4WqvULOr7Hoj6b4xHR5U2cLSY6Jz3wklEv2HdGIh5bCZQuh7ChY4/4k3Uz33h4BA4xW5B1BftEHVqLxxZ8sHBsfWUhySMj0GMM5iWxII837pG+6+q419//YVy5cqZtmyeY+ht2bIFlSpVCuiP79atmwnG+MPZno4lcuws5v33rZ7A2KawQAH3CxbOyyCQ79nzMFh0ZX+G73kL8oYPH45Bg+I2AGaGuHLlCoIhc54+fRqM54Mhc0roUR4KV/917+9N1c4AO2A85qX0JjovMjQYgWwL/qtaGY/jj/yMq7nLIubyReR/19k5yNlavXG++n9VOY8fB9r9aqoNZvzzQ1wq0xTpt81B1iVWF/znqj2Dc7f19p6OiPFf+7paryBThvxwpMuMC5Ufi7tOum51Pg+j9aXjj3hVs5fzebvFyPt2GUSdPYyowblwvko7nL1jgPKQhOUxiGnxhc9B3kcffYS3334by5cvj/MeqzU++eSTpprkY489Bn8aOHCg1wDK1cqVK1GjRg107+4cF6lKlSomgHvggQfw+uuvI08eqyMCb9UtudFcp3vOYxd2xldVk8Fkjx494pTk8fuDpSSPaQ+WOxASepSHJI46zyCmzjPW4PAc+N0RE1uS5ChRB462M5EjOm1s/jlXrRMyrfsQjpd3I1N0WngtQ2z4IjLzf8nKiGlgtYFmGda1a/0VAhpZgbVZTxFCxx9JqkzrpplHzKtHTY/HykOSEsGWf9KmTevfIO+DDz5Ar169vI6Jx2m9e/c2QaC/gzz2cmmPzRcfz5I326233mr+s5SRQV7BggXjBKksbbt8+XJsaR3nsUv1bGyvR56lgK5BrmuHNDZmhGDIDMTMGUzpkdCjPCRe5SkdpzMP3g7zvCV27rYXkfGe4ToGiY4/kjq6/A6Mt677bNFLxwC39+QFmc5hEjbXQL6mwecgb/PmzbFBkzc1a9bExo0b4W958+Y1j+RgWzoqVMjqMaxWrVpmQPf9+/fHTpszZ44J0KpXrx47T9++fU27PrstH+dhRy3xBZMiIiIiEkD5r7duNJ0+AIyqYE1bMMR6RGKbXol4PoejZ8+eNdUQE6ofyrZ5gbJs2TL873//w9q1a007vM8//9yMb3fvvfeiePHiZp4mTZqgYsWKaNu2rQkA58+fb0onOeSCXa2S4+Yx6GOPmxs2bMDMmTMxbNgwUx3T13HyRERERCQAONwNew12ET04l2mzx/9Y/ZE2i0QEn4M8drjy22+/xfv+kiVLzDyBwsDss88+Q7169Uwgx540Gbx9+umnbtVKv//+e2TMmBG1a9fGgw8+iBYtWpjB0G3sknTu3LlmuAS28+vSpYsJ8Fzb3ImIiIhIkOJN+Zd2eH/v267AUZdOikTClM9DKLzxxhvmwaEG2KmJKw5J0LBhQ9Muj49Ip3HyJNwE2xgxElqUf0T5RwLm66eBdZ/Fnf7iViBL8poDSWSJCbJrIF/jDJ/b5LHnSg4mzrZrjRo1wnXXXWeqL7Id3rx580zJmGvvliIiIiIiAdVyEmJaTLQu0k/9jehpza3pI8s453luNZCtEHByN3DhFFCkuumsRSSU+RzkpUuXznRAwnZvn3zyCRYvXmyGFihfvrzpzITDJ3AeEREREZGgU7IO0Pk3YMJt7tPHVYs7L9v1qS8GiYQgjxjEqUqmiIiIiISkAjcAz68Bxt6U8HyDclr/yzYGWr0PZPrvtUg4BnkiIiIiIiEtd2mg6x/Aqb1AwcpWRyy7fweqPgysngbMH+Scd8tc4PUSVkcumXIFMtUiSaIgT0REREQiS96y1oMy5waK1bSe394DyF4YmPmM+/yvlwT67AEyZLv2aRVJBrUqFRERERGxVX3IGlidj/r9nOtleFHgzxnA8GLAuWNaXxLUFOSJiIiIiHhTtzfQd5/zNUv4Lp4C3iil9SXhG+QtXboUFy9e9F9qRERERESCSfos3qcPzGE9PnsM8G3YaZHQCPKaNWuGvXv3+i81IiIiIiLBpt8B63/O4kChG93f2zjb6o3z0rmAJE3E7x2vcJw8EREREZGwli6T1UaPYmKA398B5rziPs+wQs55RAJMbfJERERERHy+eo4GbnvOCuj6HweeW+18b9azWo8S+kHeu+++iwIFCvgvNSIiIiIioRTw5SkDtJluvV4zHZg7INCpEklZkPfII48gS5Z4GqOKiIiIiESC65s7ny8dY3XIomZNEkCqrikiIiIiklJPLXB/feRfrVMJGAV5IiIiIiIpVaQ68OJW5+t3amqdSsAoyBMRERER8YcseYHe2+OOpXfmsNavhGaQd/XqVXzzzTf+WpyIiIiISOjJnBuo1dV92ptlgS3zA5UiiUApDvI2bdqE3r17o3DhwnjwwQf9kyoRERERkVB151Cgw1z3adNbAvvWBCpFEmGSFeSdPXsWkydPRu3atXHDDTdg9erVGDp0KPbt2+f/FIqIiIiIhJpiN1tj6fX8xzltxqOBTJFEkCQFecuWLUOHDh1QsGBBvP3222jZsiWioqIwduxYdOzYEXnz5k29lIqIiIiIhJpsBYCXd1nPT+0FLp0NdIokAvgc5FWsWBEPP/ywGfx8+fLlpvSuZ8+eJsgTEREREZF4ZMzhfD6ssFaTBE+Qt2XLFtxxxx2oX78+rr/++tRNlYiIiIhIOHlmsfM5e9z88J5ApkbCnM9B3vbt21GhQgV07twZRYsWRa9evbBmzRqV5ImIiIiIJKZQVffXO34FPm6t9SaBDfKKFCmCfv36mRK9jz76CAcOHDAdr1y5cgUffvgh/vnHpVGpiIiIiIi4G3ACePAj5+t/5wCHNmktSXD0rtmgQQNMnz7d9KbJDlgWLFiA6667DlWqVPF/CkVEREREwgH7sqh4L9DvoHPa+FuAVVMCmSoJQykaJy9nzpzo0qULVq1aZTpiqVevnv9SJiIiIiISjtJldG+j990LgMMRyBRJmEmb1A+cPHkSc+fOxY4dO0x7vNKlS6Nhw4a48cYbzVAKIiIiIiLiQxu9Vw4Br+W3Xg/KCWQvCvT4S6tOrm2QxyqaXbt2xalTp9ym58iRAxMnTkSbNm1SniIRERERkUiQNgNw3zvArGet16f2APvXAYXUBEquUXVNVsd84okn0KJFC9Or5vnz53Hu3DlTVbN58+Zo27Yt1q5dm8LkiIiIiIhEkJseA7qucr5+93bg7JFApkgiKcgbN26cCfDYk2bVqlWRIUMGZMyYEdWqVcO0adNw7733qrqmiIiIiEhS5S0HvHrU+XpkGSDmqtajpH6Qt3TpUjzzzDPxvt+pUycsWbIk+SkREREREYlUadICz7vUihucO5CpkUgJ8jhcQvny5eN9n+/t3bvXX+kSEREREYksuUsBd492vl44PJCpkUgI8tj+jtUz48PqmxcuXPBXukREREREIk/NDsCt/3XEsmgEcPDvQKdIwr13zZ9//tn0pOnNiRMn/JUmEREREZHIdedQ4Pd3rOcTagEDTwY6RRLOQd7jjz+e4PscN09ERERERFKA19SvHgGG5LVeLx0LZMwBVGtnvSfiryAvJibG11lFRERERCQl0qQDClcD9q0G5r5qTVsxCei8VOtV/NcmT0RERERErqEnfnB/fXADcOWiNoH4rySPY+F5wzZ6FSpUwHXXXefrokREREREJDHpMgH9jwGHN1tt8+i1/GqjJ/4L8rp16+Z1+pkzZ0xVzrvuuguffPIJsmXL5usiRUREREQkIdFpgAIVgZ6bgVEVrGnnjwOZcmm9Scqrax4/ftzr4+LFi/j999+xa9cuDBo0yNfFiYiIiIiIr7IVBErUsZ6/XpIdZmjdSeq1yYuOjkbNmjUxatQozJ49O6WLExERERERbxoNdD7/d47WkaR+xytly5bFnj17/LU4ERERERFxVawmUKSG9XzZ21o3kvpB3tatW1G0aFF/LU5ERERERDx1mGv93/Er8O88rR9JnSDP4XBg9erV6NmzJ5o3b57SxYmIiIiISHyiefn+34DoH7cCNnkMsyCSlCAvV65cyJ07d5xHhgwZTJu8IkWKYOBAl3rCIiIiIiLif31cmkjNeBg4tk1rWZI3hMKYMWO8Ts+ePbsZI+/666/3dVEiIiIiIpJcGbICLd8Dvn7Kej32JqD/8f9K+USSEOQ9/vjjWl8iIiIiIsGgyoNApVbA4NzW6+FFgX77Ap0qCRI+h/v79u1Dr169cOrUqTjvnTx5Ei+++CIOHjyI1DJ06FDcdtttyJw5M3LmzOl1Ho7Vx3aBWbJkQd68efH888/j0qVLbvOsX78edevWRaZMmUwV08GDB5t2ha4WLVqE6tWrI2PGjChdujQmTpyYar9LRERERCTZA6U/9rX1/PJZYP86rUhJWpA3evRoE+CxeqanHDly4PTp02ae1MJgrXXr1ujcubPX969evYq7774bZ8+exZIlSzBjxgx89dVXpkMYG9PfuHFjFC5cGCtXrsS4cePw5ptvuqV7+/btuOuuu3D77bdjzZo16Nu3rwkWuSwRERERkaBStqHz+bu3AzuWBDI1EmpB3k8//YR27drF+z7f++6775BaBg0ahO7du6Ny5cpe358zZw7+/vtvTJ8+HTfddBMaNWpkBmh/7733YksfP/74Y1y4cAEffvghKlWqhJYtW5ogjkGeXZrHUrvixYubNohsZ9ixY0c8+eSTJhgUEREREQk6A044n394dyBTIqEW5LGEi8FPfDhG3o4dOxAoy5YtM4EbS+lsd955Jy5evIg//vgjdh5W1WSPoK7zsCqqnXbO06RJE7dlc55Vq1bh8uXL1+z3iIiIiIj4JCoKeHm38/XAHMAWjaEXyXzueIVt2BgIxRfo8T3OEygHDhxAgQIF4gz7kD59evOePU/JkiXd5rE/w/dKlSrldTl8feXKFRw5cgSFChWK890MJPmw2SWHMTEx5hFoTANLKoMhLRKalIdE+Ud0/JFQFTHnsPRZEVWxBaL+/sZ6Pb0VYtjjpoRV/vE1HT4Hebfccgs++ugj3HHHHV7fnzZtGm6++WbfU8ibDAMHmmqYCWHbuRo1avi0vCjexfDAjeI63XMeu5pmUudxNXz4cK+/4/jx4yY4DIbMwDaT/B3R6lpXlIdExyAJITqHifJQEjQYhdxb5iH60hnz8uTmJbiar6IyURgdg5gWvwZ57FmTnZawkxX2pGmXdrFHzTfeeMO0c2O7uKTo2rUrHnrooQTn8Sx5i0/BggWxfPnyOEEWq1jaaeU8dqme7dChQ+Z/YvOkTZsWefLk8frdffr0QY8ePdxK8ooVK2ZKEr11VBOIzMkAlekJhswpoUd5SJR/RMcfCVURdw5jtc3BuczTXJ81V2lemOUfxiQ+zefrAuvXr4933nkH3bp1w//+9z8TvPAHc/iEdOnSmZ4qGzRokKREcpgDPvyhVq1aZpiF/fv3x1apZNDJ9nccDsGehx2tsKdOVuO052E7PjuY5DyzZ892WzbnYWkif6c3/A7Xdn42ZoRgyAzEbRVM6ZHQozwkyj+i44+Eqog7h716FBhiFU5ELxsH1O4W6BSFtKggyj++piFJKX3mmWewdetW09PkI488Ykrh2IPlli1b4h3awF84Bt7atWvNfw6XwOd8nDljFUezs5SKFSuibdu2ZuiD+fPnm9LHp556KrY0jWlmMNa+fXts2LABM2fOxLBhw0wpnF0Vs1OnTti5c6eZtnHjRkyePBkffPCBWZaIiIiISNBLk9YZ2K39NNCpkQCIcniOBB6kGJhNnTo1zvSFCxeiXr165jkDwC5dumDBggWmExgGdQxIXUvZOBj6s88+ixUrVphiVwZ1/fv3d2tvx8HQOVzDX3/9ZUr5XnrpJTOfr1hdk9VaWcoZLNU1jx07hty5cwfFHQgJPcpDovwjOv5IqIrYcxgv8QfldA6xEE/fEhJa+cfXOCNkgrxQoiBPwk2wHeAktCj/iPKP6BgUIBxKwdZjI5DdOdSYhOY5zNc4I/ApFRERERER/2s+1vl8anOt4QiiIE9EREREJBxVfxzIU856fnQLcNG37vcl9CnIExEREREJV8+tcj6f1iKQKZFgD/JOnDiB999/34wPxzqqtHr1auzdu9ff6RMRERERkZRoN8v6v3cVsGCo1mUE8HmcPNu6devQqFEj0+Bvx44dZogCNkTkcAQcemDatGmpk1IREREREUm6ErWdzxe/AVRrB+QspjUZxpJcksfx4zicwb///ouMGTPGTm/WrBkWL17s7/SJiIiIiEhKpEkHDDzpfD2mktZnmEtykLdy5UozKLqnIkWK4MCBA/5Kl4iIiIiI+FOrD5zPv+midRvGkhzksfSO4zN42rx5M/Lly+evdImIiIiIiD9VfsD5fO3HwOXzWr9hKslB3n333YfBgwfj8uXL5nVUVBR27dqFl19+Ga1atUqNNIqIiIiIiD+4VtscWhCY9azWaxhKcpD35ptv4vDhw8ifPz/Onz+PunXromzZssiWLRuGDlVvPSIiIiIiQa2ry7AKa6YDVy4FMjUSDL1rZs+eHUuWLMGCBQvMsAkxMTGoVq2a6XFTRERERESCXN5yQJ+9wPAi1utJdYEuywKdKglkkMdhE0qWLIkGDRqYh4iIiIiIhJgMWYHHvwOm3gMc+hu4fAFI5+w5XyKsumbp0qVRp04dvPvuu7EDoYuIiIiISIgpdbvz+dACwMAcwIjigUyRBCrIW7VqFWrVqoXXXnsNhQsXNh2xfPHFF7h48aK/0iQiIiIiItfCA1PcX184CfzwotZ9pAV5bH83cuRI06Pmjz/+aDpg4bh5/P/kk0+mTipFRERERMT/KrUEemwEnpzjnLZiktZ0pAV5Ng6dUL9+fbz33nuYN2+eqcY5depU/6ZORERERERSV/bCQPFb3IdX+OV1rfVIDPJ2796NN954AzfeeCNq1qyJLFmy4O233/Zv6kRERERE5Nq5/79SvF+GAZfOac1HSpA3adIkMzZeqVKlTMndgw8+iK1bt5phFTp37pw6qRQRERERkdRXtY3z+bBCWuOREuQNGTIEN998s+mA5a+//kLfvn3NkAoiIiIiIhIGHpjsfM4eNx2OQKZGrsU4eexwhe3xREREREQkDFVqBcx+Abh4yno9KCfQdx+QPkugUyb+DPLWrVuHSpUqITo6GuvXr09w3ipVqvj63SIiIiIiEoz67AbGVgOObbVeDysM9DsApMsU6JSJv4I8dq5y4MABM0wCn7Mkz+FSbGu/5v+rV6/6skgREREREQlmz68GfhkB/DLcej20INBnD5AhW6BTJv4I8rZv3458+fLFPhcRERERkQhQ72Wgwl3Au7dbr4cXBR6eAVRoFuiUSUo7XilRokRsO7ydO3eiSJEiZprrg9P4noiIiIiIhJFCVYAGrzpff/oQMH9IIFMk/u5dkwOgHzt2LM70kydPmvdERERERCTM3NELePWI8/Wvo9TrZjgFeXbbO09Hjx41A6KLiIiIiEgYSpMOGHgSyJCDUQHwds1Ap0hSOoRCy5YtzX8GeO3bt0eGDBli32NnK+yB87bbbvN1cSIiIiIiEopu6wosHAoc/Re4eAbIkDXQKZLkluTlyJHDPFiSly1bttjXfBQsWBBPP/00pk+f7uviREREREQkFNXt7Xw+vAhw1qUap4RWSd6UKVPM/5IlS6JXr16qmikiIiIiEqkemAx8+aT1fGQZYMAJVvkLdKokuW3yBgwYoABPRERERCSSVWrl/vrghkClRFJSkufqyy+/xOeff45du3bh0qVLbu+tXr06OYsUEREREZFQwk5YPnsM2DgbmFgHePJnoPitgU6VJKckb+zYsXjiiSeQP39+rFmzBjfffDPy5MmDbdu2oVkzDYooIiIiIhIxGg5wPp98ZyBTIikJ8saPH49Jkybh7bffRvr06dG7d2/MnTsXzz//vBkrT0REREREIkTeckB/lzG0fx0dyNRIcoM8VtG0h0rIlCkTTp8+bZ63bdsWn376aVIXJyIiIiIioSw6jfP5/EGBTIkkN8jjcAkc+JxKlCiB33//3Tzfvn27GV5BREREREQisH2e7fA/gUyJJCfIa9CgAWbPnm2ed+jQAd27d0fjxo3Rpk0b3H///VqpIiIiIiKRqOjN1v8pTQOdkoiX5N412R4vJibGPO/UqRNy586NJUuWoHnz5ua1iIiIiIhEoIdnACNLA+eOAhdOARmzBzpFESvJQV50dLR52B588EHzEBERERGRCJYlj/P5b+OABv0CmZqI5lOQt27dOp8XWKVKlZSkR0REREREQhXHyuNQCovfUJAX7EHejTfeiKioqEQ7VuE8V69e9VfaREREREQkFNvl0ZlDQNb8gUxNxPIpyGPPmSIiIiIiIglis67q7YE/PgQWjwTuGqkVFqxBHodKEBERERERSdTtvawgb8UkoOnrVuAnwd3xyrRp0xJ8v127dilJj4iIiIiIhLKcxZzP//wUuOnRQKYmIiU5yOvWrZvb68uXL+PcuXNInz49MmfOrCBPRERERCTSPbUAeK8BMKuL9ei9HcicO9CpihhJLjs9fvy42+PMmTPYvHkz6tSpg08//TR1UikiIiIiIqGjSHX311ObAxdPByo1EccvFWTLlSuHESNGxCnlExERERGRCHXXm87nBzcAw4sCc14NZIoiht9aQaZJkwb79u3z1+JERERERCSU3fwU0P8YUKCyc9pvY4HjO4BEhmaTa9wm79tvv3V7zbHz9u/fj7fffhu1a9dOYXJERERERCRsRKcBOv0KvFkeOHvImvZWVeD2nkDD/oFOXdhKckleixYt3B4tW7bEwIEDUaVKFUyePDl1Uglg6NChuO2220znLjlz5ox3MHbPx8SJE93mWb9+PerWrYtMmTKhSJEiGDx4cJxB3hctWoTq1asjY8aMKF26dJxliIiIiIiIj6KigBf/Bao+7Jz26yjg2+e1CoOlJC8mJgaBcOnSJbRu3Rq1atXCBx98EO98U6ZMQdOmTWNf58iRI/b5qVOn0LhxY9SvXx8rV67EP//8g/bt2yNLlizo2bNn7MDvd911F5566ilMnz4dS5cuRZcuXZAvXz60atUqlX+liIiIiEiYajEBaD4WeC2f9Xr1VOCeMRpHLxiCvEAZNGiQ+f/hhx8mOB9L+QoWLOj1vY8//hgXLlwwy8iQIQMqVapkAr3Ro0ejR48esSV/xYsXx5gxY8xnrr/+eqxatQpvvvmmgjwRERERkZSU6KVNDww8CQz8ryBm6f+sqpsS2CCPVRu//PJLLFy4EIcOHYpTsvf1118jkLp27YqOHTuiVKlS6NChA55++mlER1u1UpctW2aqajLAs915553o06cPduzYYT7DeZo0aeK2TM7D0kOOCZguXbo433nx4kXzcC0xJK6bQJV8umIauN2CIS0SmpSHRPlHdPyRUKVzWJBqPg7Rs58D5g+G49fRcPTeYbXfCzIxQXYd7Ws6kjUY+qRJk0yVxwIFCpjSr2AxZMgQNGzY0LS3mz9/vqmCeeTIEbzyyivm/QMHDqBkyZJun+FvsN9jkMf/9jTXea5cuWKWVahQoTjfO3z48NiSRlccR5CfC4bMcPr0aZNB7YBXRHlIdAySUKBzmCgPhakSdyEvnjNPoy6dwak/v8XlEnURbGKC7DqaaUmVII/t1Fhax3ZrKcUOW7wFR67Ydq5GjRo+Lc8O5ujGG280/9mxiut0z6DU7nTFdbov87hiSSCre7qW5BUrVgy5cuVC9uzZEQyZk2lneoIhc0roUR4S5R/R8UdClc5hwSvm5T2IHlHUPM8x+0nE9D+OYBMTZNfRadOmTZ0gjx2ZsMdJf1WtfOihhxKcx7PkLSluvfVWE3AdPHjQlMaxrR5L6lyxyinZpXfxzcMVmidPHq/fw+qfrlVAbcwIwZAZiJkzmNIjoUd5SJR/RMcfCVU6hwWpjNmscfQG5zYvo/evAYpUR7CJCqLraF/TkDa5pW8cLoHVIlMib9685pFa1qxZY4ZBsIdcYM+cffv2NT11pk+f3kybM2cOChcuHBtMcp7Zs2e7LYfzsDTRW3s8ERERERFJJrbDq3gf8Pcs4L2GwMATWpV+kORwlMMYsK1Z/vz5UblyZVSrVs3tkVp27dqFtWvXmv9Xr141z/k4c+aMeZ+B2XvvvYcNGzZg69ateP/999GvXz/T8YpdyvbII4+Y5xw2gfPNnDkTw4YNi+1Zkzp16oSdO3eaaRs3bjTBLDtd6dWrV6r9NhERERGRiNXCHpPaAVywOjCUlElySR4DpD/++AOPPfbYNe14pX///pg6dWrs65tuusn8Zy+f9erVM6Vs48ePN8EZ686ySinb4z377LNuVU3nzp1rprFkjnVrOb9rezp2vvLDDz+ge/fueOedd0wp39ixYzV8goiIiIhIakifGShQCTi4ARhTCXh5l9ZzCkU57F5FfMSBw3/++WfUqVMnpd8dttgOkAHlyZMng6bjlWPHjiF37txBUZdYQo/ykCj/iI4/Eqp0DgsRu1cCHzSynjPIy/jfOHoBFhNk19G+xhlJTil7jQyGwEVERERERMJEsZrO5yOKA1cDPwxZKEtykDdq1Cj07t3bDB4uIiIiIiLiFz02OZ8P8d6rvaRSmzy2xTt37hzKlCmDzJkzx+lxksWZIiIiIiIiSZK9EHD3aOB7Z38Zco2CvDFjxiTzq0RERERERBJQs4MzyLt6GUijIcyuSZD3+OOPJ+uLREREREREEpWtMHB6HzAkLzDwpFbYtQjyOE5dQooXL56cdIiIiIiIiACNBwFfP2WtiYE5gAEngGs0bFvEBnklS5ZMcGw8DlQuIiIiIiKSLFUeBP75CdjwlfV63gCg8WCtzNQM8tasWeP2+vLly2ba6NGjMXTo0KQuTkRERERExN0Dk4GYK8Dfs4ClbwH1+gLpMmotpVaQV7Vq1TjTatSogcKFC2PkyJFo2bJlUhcpIiIiIiLirvVUYFBO6/m3zwGt3tMa8pHfhm0vX748Vq5c6a/FiYiIiIhIJHNtIrb+c2DRyECmJryDvFOnTrk9Tp48iU2bNuHVV19FuXLlUieVIiIiIiISefodcD5f+BoQo/4/UqW6Zs6cOeN0vOJwOFCsWDHMmDEjqYsTERERERHxLl0m4JEvgE9aW6+ntwTazdLa8neQt2DBArcgLzo6Gvny5UPZsmWRNm2SFyciIiIiIhK/8k2AJ34EpjQDtv0CHN8B5CqpNZaAJEdl9erVS+pHREREREREkq/Ebc7nb1XVIOn+bpM3fPhwTJ48Oc50Tnv99deTujgREREREZHEvbjN+fzwZq0xfwZ57777Lq677ro402+44QZMnDgxqYsTERERERFJXJY8zufv3Axcuai15q8g78CBAyhUqFCc6WyXt3///qQuTkRERERExDcvbHA+f6+h1pq/gjz2orl06dI40zmNA6KLiIiIiIikipzFgMe+sp4fXK8hFfzV8UrHjh3xwgsv4PLly2jQoIGZNn/+fPTu3Rs9e/ZM6uJERERERER8V7YRkKcscHQLMDg3MOCE+8DpkvQgj8HcsWPH0KVLF1y6dMlMy5gxI1566SX06dNHq1RERERERFLXXSOBj+63ng/Kqd42U1pdk2PksRfNw4cP4/fff8eff/5pgr7+/fsndVEiIiIiIiJJV6YB0GiQ8/WhTVqLKQnybFmzZkXNmjVRqVIlZMiQIbmLERERERERSbo6LzgHRR9/C3Dwb63FlAZ5IiIiIiIiAdVxgfP5hFrAhNqBTE3QUJAnIiIiIiKhO3beSzudrw+6DLEQwRTkiYiIiIhI6Mrk0fHKL68j0inIExERERGR0FfhLuv/L8OAgTkQyRTkiYiIiIhI6GvzsfvrBUMRqRTkiYiIiIhI6IuOdq+2ufgNRCoFeSIiIiIiEj4GnHA+37oQkUhBnoiIiIiIhI+oKKDpf52vfNQCiLmKSKMgT0REREREwstNjzmfD86NSKMgT0REREREwkuGrECLiYhUCvJERERERCT83Piw8/nO3xBJFOSJiIiIiEh4uvkZ6//8wYgkCvJERERERCQ81elu/d+1LKI6YFGQJyIiIiIi4Sl7Iefz2d0QKRTkiYiIiIhI+Gr1gfV//ReIFAryREREREQkfN3Q0vp/5QJw3mWg9DCmIE9ERERERMJXdDSQPpv1/MA6RAIFeSIiIiIiEt5aT7H+T22OSKAgT0REREREwlvecs7nF88g3CnIExERERGR8JarJJA2k/V8eBEgJgbhTEGeiIiIiIiEv+fXOJ8PzgVcPo9wpSBPREREREQiY8y8B6c5Xw8tGLYlegryREREREQkMlS8DyhRx/n6xxcRjhTkiYiIiIhI5Hjie6DdLOv5yveBPasQbhTkiYiIiIhIZCldz/n8/YYINyER5O3YsQMdOnRAqVKlkClTJpQpUwYDBgzApUuX3ObbtWsXmjdvjixZsiBv3rx4/vnn48yzfv161K1b1yynSJEiGDx4MBwOh9s8ixYtQvXq1ZExY0aULl0aEydOvCa/U0RERERErpGXdzufr/pvHL0wkRYhYNOmTYiJicG7776LsmXLYsOGDXjqqadw9uxZvPnmm2aeq1ev4u6770a+fPmwZMkSHD16FI8//rgJ4MaNG2fmOXXqFBo3boz69etj5cqV+Oeff9C+fXsTFPbs2dPMs337dtx1111m+dOnT8fSpUvRpUsXs9xWrVoFdD2IiIiIiIifZMwOFKgMHFwPfPcCUL09EBUVFqs3yuFZjBUiRo4ciQkTJmDbtm3m9Y8//oh77rkHu3fvRuHChc20GTNmmCDu0KFDyJ49u5m/T58+OHjwIDJkyGDmGTFihAkC9+zZg6ioKLz00kv49ttvsXHjxtjv6tSpE/78808sW7bMp7QxmMyRIwdOnjxpvjfQGCAfO3YMuXPnRnR0SBTeSpBRHhLlH9HxR0KVzmGSoKtXgCF5rOd3vAg0eCWo84+vcUbgU5pM/GFc2TYGYJUqVYoN8OjOO+/ExYsX8ccff8TOw6qadoBnz7Nv3z5TJdSep0mTJm7fxXlWrVqFy5cvX4NfJiIiIiIi10SatM5OWBaPtIK+MBAS1TU9bd261ZS+jRo1KnbagQMHUKBAAbf5cuXKhfTp05v37HlKlizpNo/9Gb7HNn/elsPXV65cwZEjR1CoUKE46WEgyYdrhG1H/nwEGtPAAttgSIuEJuUhUf4RHX8kVOkcJokqeYez5GtIHsT02gJkzhOU+cfXdAQ0yBs4cCAGDRqU4DxsO1ejRo3Y1yx1a9q0KVq3bo2OHTu6zcvqlp64UVyne85j11ZN6jyuhg8f7vV3HD9+3ASHwZAZTp8+bX5HMBQzS+hRHhLlH9HxR0KVzmHiiyxVn0CmP63OV6LfLIsjXbcGZf5hWoI+yOvatSseeuihBOdxLXljgMdOU2rVqoVJkya5zVewYEEsX748TpDFKpZ2yRznsUv1bGyvR4nNkzZtWuTJ8199XQ9s59ejRw+3krxixYqZksRgaZPHAJXpCYbMKaFHeUiUf0THHwlVOoeJT+4dBce5vYj6d455mXvfQqBSq6DLP4xJfJoPAcRhDvjwxd69e02Ax6ENpkyZEmclM/AbOnQo9u/fH1ulcs6cOab9HT9jz9O3b18zrAKrcdrzsB2fHUxyntmzZ7stm/OwNDFdunRe08bvcG3nZ2MagyEzEDNnMKVHQo/ykCj/iI4/Eqp0DhOfPPoF8PtE4KeXEP11R6BK66DLP76mIfAp9QFL8OrVq2dKxzhkwuHDh01pm2uJGztLqVixItq2bYs1a9Zg/vz56NWrlxkKwS5Ne+SRR0wwxh43OQzDzJkzMWzYMFMKZ1fFZE+aO3fuNNPYw+bkyZPxwQcfmGWJiIiIiEgYu7WT8/mvoxGqQqLjFZakbdmyxTyKFi3qtb1cmjRp8P3335sx7WrXrm0GO2dQZ4+jR+xudO7cuXj22WdNyRyLXRnMuVa1ZOcrP/zwA7p374533nnHlPKNHTtWY+SJiIiIiESC0vWAbb8A8wcBOYsDheoh1ITsOHnBTOPkSbgJtjFiJLQo/4jyj+gYJCHF4QAG5Yx9eaz9UuQsXjEoroHCfpw8ERERERERv4uKAl6xOmek3B/WDrmVrCBPRERERETEVdoMwIvWMAqhKCTa5ImIiIiIiFxTWfLCUfF+nMtRFplCbNUryBMREREREfHC8cBknD92LOSCPFXXFBERERERCSMK8kRERERERMKIgjwREREREZEwoiBPREREREQkjCjIExERERERCSMK8kRERERERMKIgjwREREREZEwoiBPREREREQkjCjIExERERERCSNpA52AcORwOMz/U6dOIRjExMTg9OnTSJs2LaKjFdeL8pDoGCShQ+cwUR4SHYOc7PjCjjfioyAvFTCgomLFiqXG4kVEREREJMLjjRw5csT7fpQjsTBQknXXcd++fciWLRuioqKCIuJnwLl7925kz5490MmREKQ8JMo/ouOPhCqdwySc8g9DNwZ4hQsXTrCGnkryUgFXeNGiRRFsmDGDIXNK6FIeEuUf0fFHQpXOYRIu+SehEjybGmiJiIiIiIiEEQV5IiIiIiIiYURBXgTIkCEDBgwYYP6LKA+JjkESSnQOE+Uh0TEo6dTxioiIiIiISBhRSZ6IiIiIiEgYUZAnIiIiIiISRhTkiYiIiIiIhBEFeRFg/PjxKFWqFDJmzIjq1avj119/DXSSJJUtXrwYzZs3NwNlRkVF4ZtvvokzkObAgQPN+5kyZUK9evXw119/uc1z8eJFPPfcc8ibNy+yZMmCe++9F3v27HGb5/jx42jbtq0Zr4UPPj9x4oTbPLt27TJp4TK4rOeffx6XLl1KxV8vKTV8+HDUrFkT2bJlQ/78+dGiRQts3rzZbR7lIYnPhAkTUKVKldgxpWrVqoUff/xReUeSfTzieeyFF15QHhKf8PomKirK7VGwYMHIyz8OCWszZsxwpEuXzvHee+85/v77b0e3bt0cWbJkcezcuTPQSZNU9MMPPzj69evn+OqrrxzczWfOnOn2/ogRIxzZsmUz769fv97Rpk0bR6FChRynTp2KnadTp06OIkWKOObOnetYvXq1o379+o6qVas6rly5EjtP06ZNHZUqVXL89ttv5sHn99xzT+z7nJfT+Fkug8sqXLiwo2vXrtr+QezOO+90TJkyxbFhwwbH2rVrHXfffbejePHijjNnzsTOozwk8fn2228d33//vWPz5s3m0bdvX3MeYn5S3pGkWLFihaNkyZKOKlWqmOsXHX/EFwMGDHDccMMNjv3798c+Dh06FHH5R0FemLv55ptNRnV13XXXOV5++eWApUmuLc8gLyYmxlGwYEFzkLNduHDBkSNHDsfEiRPN6xMnTpiLMt4ksO3du9cRHR3t+Omnn8xr3jTgsn///ffYeZYtW2ambdq0KTbY5Gf4Wdunn37qyJAhg+PkyZOp/MvFX3hy5HZdtGiRea08JEmVK1cux/vvv6+8Iz47ffq0o1y5cubCuG7durFBno4/4kuQV7VqVa/vRVL+UXXNMMbi4D/++ANNmjRxm87Xv/32W8DSJYG1fft2HDhwwC1fcByqunXrxuYL5pvLly+7zcNqDZUqVYqdZ9myZaZ6wi233BI7z6233mqmuc7Dz/CztjvvvNNUg+B3SGg4efKk+Z87d27zX3lIfHX16lXMmDEDZ8+eNdU2lXfEV88++yzuvvtuNGrUyG268pD44t9//zXXHmyu9NBDD2Hbtm0Rl3/Spvo3SMAcOXLEnGALFCjgNp2vmcElMtnb3lu+2LlzZ+w86dOnR65cueLMY3+e/9leyxOnuc7j+T1cJpetPBgaWBjco0cP1KlTx5ysSHlIErN+/XoT1F24cAFZs2bFzJkzUbFixdiLHx1/JCG8MbB69WqsXLkyzns6/khiGHhNmzYN5cuXx8GDB/Haa6/htttuM+3uIin/KMiLAGxw6nnR5jlNIk9y8oXnPN7mT848Ery6du2KdevWYcmSJXHeUx6S+FSoUAFr1641nRB89dVXePzxx7Fo0SLlHUnU7t270a1bN8yZM8d0GBcfHX8kPs2aNYt9XrlyZXPDqUyZMpg6daopbYuU/KPqmmGMvfikSZMmzt2CQ4cOxbmzIJHD7mEqoXzBeVjdlz1HJTQP75B5Onz4sNs8nt/DZbIahPJg8GPPYt9++y0WLlyIokWLxk5XHpLE8E512bJlUaNGDdM7YtWqVfHWW28p70iiWI2N5xr2Bp42bVrz4A2CsWPHmuf2uUPnMPFVlixZTLDHKpyRdP5SkBfmJ1keJOfOnes2na9ZbC2RifXTeeBxzRc8mPEkaucL5pt06dK5zbN//35s2LAhdh7eGWNbrRUrVsTOs3z5cjPNdR5+hp+18e4s67/zOyQ48S4jS/C+/vprLFiwwOQZV8pDkpw8xXYoyjuSmIYNG5rqviwJth+8WfDoo4+a56VLl9Y5TJLk4sWL2LhxIwoVKhRZx6BU79pFgmIIhQ8++MD0BPTCCy+YIRR27NihLRPmvZKtWbPGPLibjx492jy3h85gr1LsSerrr7823Qc//PDDXrsPLlq0qGPevHmm698GDRp47T6YXVuzRyk+Kleu7LX74IYNG5plcFlcpoZQCG6dO3c2+eOXX35x64L63LlzsfMoD0l8+vTp41i8eLFj+/btjnXr1pkhFNjD3Jw5c5R3JFlce9fU8UcS07NnT3P+2rZtm+n9ktclHDLBvvaNlPOXgrwI8M477zhKlCjhSJ8+vaNatWqx3aBL+Fq4cKEJ7jwfjz/+eGwXwuximN0IsyvfO+64wxzoXJ0/f94ciHLnzu3IlCmTOXDt2rXLbZ6jR486Hn30UXPw5IPPjx8/7jYPA0uOs8ZlcFlcJrsrluDlLe/wwbHzbMpDEp8nn3wy9pyTL18+c4FjB3jKO+KPIE/HH0mIPe5dunTpzLh0LVu2dPz1118Rl3+i+Cf1ywtFRERERETkWlCbPBERERERkTCiIE9ERERERCSMKMgTEREREREJIwryREREREREwoiCPBERERERkTCiIE9ERERERCSMKMgTEREREREJIwryREREREREwoiCPBERERERkTCiIE9ERCSJ2rdvj6ioqDiPLVu2aF2KiEjApQ10AkREREJR06ZNMWXKFLdp+fLlc3t96dIlpE+f/hqnTEREIp1K8kRERJIhQ4YMKFiwoNujYcOG6Nq1K3r06IG8efOicePGZt7Ro0ejcuXKyJIlC4oVK4YuXbrgzJkzscv68MMPkTNnTnz33XeoUKECMmfOjAceeABnz57F1KlTUbJkSeTKlQvPPfccrl696hZE9u7dG0WKFDHLvuWWW/DLL79oe4qIRDiV5ImIiPgRg7LOnTtj6dKlcDgcZlp0dDTGjh1rgrXt27ebII/B2fjx42M/d+7cOTPPjBkzcPr0abRs2dI8GPz98MMP2LZtG1q1aoU6deqgTZs25jNPPPEEduzYYT5TuHBhzJw505Qwrl+/HuXKldN2FRGJUFEO+wwkIiIiPrfJmz59OjJmzBg7rVmzZjh8+DBOnjyJNWvWJPj5L774wgSCR44ciS3JY8DGNn1lypQx0zp16oSPPvoIBw8eRNasWc00BnAMFCdOnIitW7eaQG7Pnj0mwLM1atQIN998M4YNG6atKSISoVSSJyIikgz169fHhAkTYl+zuuTDDz+MGjVqxJl34cKFJuj6+++/cerUKVy5cgUXLlww1TH5OWIVTTvAowIFCpiAzg7w7GmHDh0yz1evXm1KCsuXL+/2XRcvXkSePHm0TUVEIpiCPBERkWRgcFa2bFmv013t3LkTd911lymZGzJkCHLnzo0lS5agQ4cOuHz5cux86dKlc/sce+v0Ni0mJsY85/80adLgjz/+MP9duQaGIiISeRTkiYiIpKJVq1aZkrtRo0aZtnn0+eefp3i5N910k+mEhSV7t99+ux9SKiIi4UK9a4qIiKQiVsFkkDdu3DjTeQrb2bFNXUqxmuajjz6Kdu3a4euvvzYduqxcuRKvv/666ahFREQil4I8ERGRVHTjjTeaIRQYfFWqVAkff/wxhg8f7pdlc5w+Bnk9e/Y0Qy/ce++9WL58uRmmQUREIpd61xQREREREQkjKskTEREREREJIwryREREREREwoiCPBERERERkTCiIE9ERERERCSMKMgTEREREREJIwryREREREREwoiCPBERERERkTCiIE9ERERERCSMKMgTEREREREJIwryREREREREwoiCPBERERERkTCiIE9ERERERATh4/8iP+7Jqb/ssQAAAABJRU5ErkJggg==",
"text/plain": [
"<Figure size 900x360 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"first half: -468 second half: -1,598\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
}