From 0b89a054157be6dac68533d1f1e27c27aeb08eae Mon Sep 17 00:00:00 2001 From: Dmitri Smirnov Date: Thu, 23 Jul 2026 10:57:11 -0400 Subject: [PATCH 1/5] docs: add docs/plan.md --- docs/plan.md | 642 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 642 insertions(+) create mode 100644 docs/plan.md diff --git a/docs/plan.md b/docs/plan.md new file mode 100644 index 0000000..cc2d9fc --- /dev/null +++ b/docs/plan.md @@ -0,0 +1,642 @@ +# Adaptive Bayesian CPU/GPU Dispatch Study + +## Status + +This document is the canonical plan for the adaptive scheduling R&D study. Keep implementation +decisions, acceptance criteria, and future revisions synchronized with this file. + +## 1. Goal and research hypothesis + +The study will determine whether a small, continuously updated probabilistic performance model can +increase the stable throughput of a Geant4-like simulation job running on an exclusively allocated +multi-CPU, multi-GPU node. + +The operational goal is: + +> Maximize stable simulation throughput by dynamically batching and routing semantically +> GPU-eligible work across the CPU worker pool and available GPUs, while bounding event-tail +> latency, queue growth, memory risk, correctness risk, and scheduler overhead. + +CPU and GPU saturation are diagnostics and desirable consequences, not the objective itself. +Maximizing utilization without constraints can create an unstable GPU queue, retain event state for +too long, and increase memory pressure. The current Simload comparison demonstrates this tradeoff: +asynchronous execution reaches roughly 87% CPU/GPU timeline occupancy and 0.60 events/s, but its +deferred collection also produces an approximately 27-second p95 event residence. The study must +therefore optimize constrained throughput, not utilization at any cost. + +The primary hypothesis is that a dynamic linear Kalman filter, initialized from Bayesian regression +priors, can: + +1. start from deliberately weak priors learned from Simload and compatible historical jobs; +2. calibrate itself from measurements produced by the current job; +3. explicitly track uncertainty and performance drift; +4. drive a constrained earliest-finish scheduler; and +5. safely collect additional information through conservative online exploration. + +The study remains application-neutral at its interfaces. Its main application mapping is a +Geant4-style multithreaded process in which independent event workers generate baskets of +GPU-eligible tracks. The HPC batch scheduler and inter-node placement are outside the first study; +the adaptive scheduler operates inside one allocated job. + +## 2. Important correction to the current Simload interpretation + +The current `simload` workflow models CPU work and GPU work as mandatory, complementary stages of an +event. Its sampled `cpu_fraction` and `gpu_fraction` are workload-generation inputs, not observed +evidence that a payload should be routed to one resource or the other. + +Consequently: + +- the existing data can compare synchronization policies and measure overlap, queueing, waiting, + makespan, and event residence; +- it cannot train a valid CPU-versus-GPU routing model for interchangeable work; +- `cpu_fraction` must not be used as a routing target or predictive input; and +- the routing study must introduce a common payload with semantically equivalent CPU and GPU + implementations. + +The existing synchronization experiment and output schema should remain supported. The new routing +workflow will be opt-in and will generate decision-level and completion-level records in addition +to event summaries. + +## 3. What is predicted and what is decided + +### 3.1 Hard application rules + +The learned model will not determine whether arbitrary physics code is GPU-compatible. A backend +adapter must declare: + +- whether a payload kind is CPU-only or CPU/GPU eligible; +- which CPU and GPU implementations are semantically equivalent; +- resource and memory invariants that must never be violated; and +- how equivalence and physics correctness are validated. + +Only payloads with verified alternative implementations enter the learned routing action space. + +### 3.2 Bayesian prediction targets + +For an eligible payload basket \(i\), resource \(r\), and decision-time context \(x_i\), maintain +posterior predictive distributions for: + +\[ +p(T_{\mathrm{cpu},i} \mid x_i, D_t) +\] + +\[ +p(T_{\mathrm{gpu-compute},i,r} \mid x_i, D_t) +\] + +\[ +p(T_{\mathrm{h2d},i,r}, T_{\mathrm{d2h},i,r} \mid x_i, D_t) +\] + +\[ +p(M_{\mathrm{gpu-peak},i,r} \mid x_i, D_t) +\] + +These distributions provide: + +- expected CPU service time and uncertainty; +- expected GPU transfer and compute time and uncertainty; +- GPU memory quantiles and probability of exceeding the safe allocation; +- batch-size response, including the crossover point and diminishing returns; +- the posterior probability that a particular GPU placement finishes before CPU execution; and +- an out-of-distribution or insufficient-evidence indication. + +Queue delay is not trained as if it were an intrinsic payload property. The controller derives +expected queue delay from the queued work and predicted service distributions. This avoids teaching +the performance model policy-dependent behavior. + +### 3.3 Scheduling decisions + +The controller combines predictions with current resource and event state to choose: + +- execute on the CPU worker pool; +- dispatch the current basket to GPU \(j\); +- temporarily accumulate more compatible items for a larger GPU basket; or +- fall back to the configured static safe policy. + +The model does not directly predict a global CPU/GPU percentage. The observed distribution emerges +from individual constrained decisions and changes with workload composition, queue state, batch +efficiency, and hardware performance. + +A direct best-action classifier is also deliberately avoided. The current Simload CPU/GPU fractions +are generated workload assumptions, not counterfactual routing labels, and a classifier trained on +them would become invalid as queues, devices, batch formation, and scheduling policies change. + +## 4. Bayesian performance model with online Kalman updates + +The performance model has two connected stages. Before a job, Bayesian linear regression turns +simulator measurements and compatible historical data into deliberately broad priors. During the +job, a linear Kalman filter updates those priors after each valid completion and allows selected +run- and device-specific coefficients to evolve. These are not competing model choices: the +Bayesian regression establishes the initial uncertainty, while the Kalman formulation provides the +sequential, drift-aware update used by the scheduler. + +### 4.1 Observation model + +Each positive timing or memory target is modeled in log space: + +\[ +y_t = \log z_t = \phi(x_t)^\mathsf{T}\theta_t + v_t, +\qquad +v_t \sim \mathcal{N}(0, R_t) +\] + +where: + +- \(z_t\) is a measured service time, transfer time, or memory peak; +- \(\phi(x_t)\) is a bounded feature basis computed from decision-time information; +- \(\theta_t\) contains performance coefficients; and +- \(R_t\) is observation-noise variance for the applicable payload/resource model. + +The feature basis should initially include: + +- intercept; +- workload-kind indicators; +- `log1p(item_count)`; +- `log1p(input_bytes)` and `log1p(output_bytes)`; +- `log1p(working_set_bytes)`; +- bounded application-provided complexity features; +- batch-size linear and hinge terms for saturation behavior; +- active CPU workers or per-device in-flight work; +- recent resource-load summaries; and +- interactions selected in advance, such as workload kind by batch size. + +Nonlinear behavior is represented through transformed features while the model remains linear in +its parameters. An extended or unscented Kalman filter is therefore not required for the first +study. + +### 4.2 Prior construction with Bayesian regression + +Use Bayesian linear regression with a Normal-Inverse-Gamma prior for each prediction target and +payload/resource class: + +\[ +\theta \mid \sigma^2 \sim \mathcal{N}(m_0, \sigma^2 P_0) +\] + +\[ +\sigma^2 \sim \operatorname{InvGamma}(a_0, b_0) +\] + +This stage supplies: + +- a prior coefficient mean \(m_0\); +- conditional coefficient covariance scale \(P_0\); +- an observation-noise estimate; +- posterior predictive Student-t intervals; and +- a compact set of sufficient statistics that can be persisted without retaining every raw event. + +At deployment, the regression posterior initializes the Kalman coefficient mean and covariance; +its posterior noise estimate initializes the observation-noise model. Batch regression remains the +reference calculation for validating the sequential implementation. + +Simulator data must become a weak prior rather than being pooled equally with real measurements. +Cap the simulated contribution at 20 real-equivalent observations per payload/resource model and +inflate its covariance. Real-job measurements should be able to override simulator assumptions +quickly. + +A compatible historical-job posterior may refine the shared prior, but compatibility must be keyed +by: + +- payload-schema and workload-kind versions; +- CPU and GPU hardware classes; +- kernel/backend version; +- geometry and physics configuration; +- compiler, driver, and numerical runtime versions; and +- model feature-schema version. + +Incompatible configurations start a new model lineage or fall back to a broader hardware/workload +prior. + +Maintain separate compact model states for CPU service, GPU compute, each transfer direction, and +peak memory. Partially pool structural coefficients where payload kinds, resource classes, and +hardware classes have a defensible common relationship. Identical GPUs share a hardware-level base +model but retain their own run- and device-specific calibration state. + +### 4.3 Online Kalman filtering + +Online operation uses a linear Kalman-filter interpretation of sequential Bayes: + +\[ +\theta_t = F_t\theta_{t-1} + w_t, +\qquad +w_t \sim \mathcal{N}(0, Q_t) +\] + +For the initial implementation, \(F_t = I\). The predicted coefficient distribution is: + +\[ +m_t^- = m_{t-1} +\] + +\[ +P_t^- = P_{t-1} + Q_t +\] + +Given feature vector \(\phi_t\) and completed measurement \(y_t\): + +\[ +S_t = \phi_t^\mathsf{T}P_t^-\phi_t + R_t +\] + +\[ +K_t = P_t^-\phi_t S_t^{-1} +\] + +\[ +m_t = m_t^- + K_t(y_t - \phi_t^\mathsf{T}m_t^-) +\] + +\[ +P_t = (I - K_t\phi_t^\mathsf{T})P_t^- +\] + +The resulting posterior \(\mathcal{N}(m_t, P_t)\) becomes the prior for the next observation. +With \(Q_t=0\) and known \(R_t\), this is mathematically equivalent to sequential Gaussian +Bayesian linear regression and recursive least squares. For scheduling, combine parameter +uncertainty \(\phi_t^\mathsf{T}P_t\phi_t\) with observation noise \(R_t\), then transform predictive +samples from log space back to physical time or memory units. This preserves the asymmetric +uncertainty that matters for finish-time and memory-risk decisions. + +The first implementation should use NumPy operations on these small state vectors and matrices; it +does not require a heavyweight probabilistic framework. + +### 4.4 Structural and calibration parameters + +Partition the coefficients conceptually into: + +\[ +\theta_t = +\begin{bmatrix} +\theta_{\mathrm{structural},t} \\ +\theta_{\mathrm{calibration},t} +\end{bmatrix} +\] + +Structural coefficients describe relationships such as scaling with payload size, transfer volume, +and batch size. Calibration coefficients describe the current run or device, including speed +offset, contention sensitivity, thermal effects, and other short-term changes. + +Configure block-diagonal process noise: + +\[ +Q = +\begin{bmatrix} +Q_{\mathrm{structural}} & 0 \\ +0 & Q_{\mathrm{calibration}} +\end{bmatrix} +\] + +with: + +- near-zero process noise for shared structural coefficients; +- small process noise for stable device-class coefficients; and +- larger process noise for run- and device-specific calibration coefficients. + +This preserves knowledge learned across jobs while allowing current performance to move. Initial +values of \(Q\) should be derived from repeated-run variance in the simulator and calibration data, +then tuned only on training scenarios. + +### 4.5 Observation noise and robust updates + +Observation noise is initially estimated by the Normal-Inverse-Gamma regression. During operation: + +- update \(R\) from a bounded exponentially weighted innovation statistic; +- maintain separate noise estimates by target, workload kind, and resource class; +- apply an innovation gate before updating; +- classify initialization, telemetry failure, allocation retry, and preemption measurements + separately from normal service observations; and +- use Student-t-inspired robust weighting or a variance-inflated Kalman update for valid but + extreme observations. + +Discarding an observation should require an explicit invalid-measurement reason. Slow but valid +payloads must remain in the dataset because they are important to scheduling. + +### 4.6 Drift and posterior reuse + +Track normalized innovation: + +\[ +\eta_t = \frac{y_t-\phi_t^\mathsf{T}m_t^-}{\sqrt{S_t}} +\] + +Use sustained innovation bias, interval-coverage degradation, or a version change to identify +drift. On drift: + +- increase process noise for the affected calibration block; +- reset an affected device- or run-specific intercept when necessary; +- retain compatible structural coefficients; +- stop exploratory decisions if calibration becomes unreliable; and +- use the static baseline until uncertainty returns to a safe range. + +Do not carry an increasingly concentrated posterior forward indefinitely without process noise or +covariance inflation. That would make the model overconfident and unable to adapt. + +### 4.7 Delayed and out-of-order outcomes + +Decisions and completions are asynchronous. Every observation must retain decision time, execution +start time, completion time, model version, and the exact feature vector used for prediction. + +- Structural updates with zero process noise are order-insensitive. +- Device calibration updates should be applied per device in execution-time order. +- Late observations produced under an older model remain valid measurements, but must update the + applicable payload/resource state rather than being treated as if generated by the newest + decision context. + +## 5. Scheduler and conservative exploration + +### 5.1 Constrained earliest-finish controller + +At every scheduling point: + +1. Build candidate CPU, GPU-device, and short accumulation actions. +2. Remove semantically ineligible actions. +3. Remove actions whose posterior memory quantile exceeds allocatable memory after reserved + headroom. +4. Predict the queued service ahead of the payload on each resource. +5. Sample or integrate transfer and service distributions. +6. Include batch accumulation time and the age of the oldest contributing event. +7. Remove actions predicted to violate event-tail, queue, or outstanding-state constraints. +8. Choose the action with the earliest constrained finish. +9. Use the static safe policy if no adaptive candidate passes all checks, predictive uncertainty is + extreme, or required telemetry is stale. + +For identical GPUs, shared coefficients provide the base model while per-device Kalman calibration +and queue state distinguish devices. + +### 5.2 Budgeted Thompson sampling + +Online exploration is necessary because deterministic historical routing only observes the selected +backend. Use conservative posterior sampling: + +- obtain candidate-action probabilities from 64 posterior draws; +- sample among actions that pass hard eligibility, memory, and tail constraints; +- record the normalized action propensity after safety filtering; +- allow a non-baseline action only if pessimistic cumulative predicted performance remains at least + 95% of the static baseline; +- stop exploration when the budget is exhausted, telemetry is stale, or drift is active; and +- never explore semantically unvalidated implementations. + +The Kalman posterior provides the parameter distribution used for Thompson sampling: + +\[ +\tilde{\theta}_t \sim \mathcal{N}(m_t, P_t) +\] + +Observation-noise samples are included when comparing predicted realized completion times. Memory +constraints use conservative posterior quantiles rather than an optimistic Thompson sample. + +Action propensities must be logged so new policies can be evaluated from historical decisions using +inverse-propensity and doubly robust estimators. + +## 6. Runtime interfaces and telemetry + +### 6.1 Public records + +Define application-neutral records: + +`PayloadDescriptor` + +- job, run, event, payload, and workload-kind identifiers; +- item count; +- input, output, and working-set bytes; +- bounded complexity features; +- contributing event identifiers and oldest-event age; +- eligible backends; +- validation and schema versions. + +`ResourceSnapshot` + +- active and free CPU workers; +- CPU queue and estimated queued work; +- per-GPU queue and in-flight work; +- per-GPU free and reserved memory; +- recent CPU/GPU utilization summaries; +- telemetry timestamp and freshness. + +`DispatchDecision` + +- selected action: CPU, GPU device, accumulate, or baseline fallback; +- basket membership; +- baseline action; +- predictive means and required quantiles; +- action propensity and exploration-budget state; +- model, policy, and feature-schema versions; +- complete decision-time feature vector. + +`DispatchOutcome` + +- queue, transfer, service, and completion times; +- peak device memory; +- device and CPU worker identity; +- completion, retry, and error status; +- event-completion contribution; +- validation status; +- measurement-quality classification. + +### 6.2 Runtime contract + +Expose: + +```text +decide(payloads, resource_snapshot) -> DispatchDecision +observe(dispatch_outcome) -> ModelUpdate +snapshot() -> ModelSnapshot +restore(model_snapshot) +``` + +`observe()` performs the Kalman/Bayesian update immediately after a valid completion. Persist the +job-local model state and validated training statistics periodically. At successful job completion, +promote only compatible, validated structural information into the shared prior; keep transient +run- and device-calibration state local to the job. + +### 6.3 Measurements from real jobs + +Measure intrinsic components separately: + +- CPU execution start/end and process/thread CPU time; +- GPU queue entry, device start, and device completion; +- H2D and D2H bytes and elapsed times; +- kernel/transport-loop service time; +- allocator or pool high-water memory for each basket; +- outstanding events and oldest-event age; +- per-device queue and active basket population; and +- event completion and reduction times. + +Sample coarse device utilization, memory utilization, and process CPU state at approximately +200 ms for evaluation and load context. Do not substitute device-wide sampled utilization for +per-payload service measurements. + +Every trace must include a run manifest containing hardware, software, geometry, physics, +configuration, random seed, static baseline, policy version, and model lineage. + +## 7. Simload implementation study + +Keep the existing synchronization modes intact and introduce a routing-study workflow containing: + +- multiple event-producing CPU workers; +- one FIFO execution queue and stream per allocated GPU for the first implementation; +- a shared stream of generic GPU-eligible baskets associated with independent events; +- equivalent CPU and GPU implementations of the same synthetic operation; +- workload size expressed through operations, items, and bytes rather than a target duration; +- configurable arrival processes, batch formation, maximum batch age, memory capacity, and + backpressure; +- policy plug-ins for static baselines, adaptive scheduling, and an oracle; +- transient device slowdowns and controlled workload drift; +- decision, outcome, telemetry, manifest, and event-summary outputs; and +- a deterministic analytic/mock backend for tests plus an optional NumPy/PyTorch hardware backend. + +The simulator scenario matrix will cover: + +- balanced, CPU-heavy, GPU-heavy, bursty, and heavy-tailed workloads; +- compute-bound, transfer-bound, and memory-bound payload kinds; +- small and large basket regimes around the CPU/GPU crossover; +- one large shower among many small events; +- different CPU-worker-to-GPU ratios; +- one through several identical GPUs; +- GPU memory pressure and queue backpressure; +- temporary GPU slowdown and recovery, plus thermal or background-load drift; +- cold start, warmed shared prior, misleading simulator prior, and OOD payloads; and +- synchronization and event-tail behavior. + +Simulated counterfactual CPU/GPU executions may be paired for prior construction and oracle +evaluation. Real production operation will observe only the chosen action except for guarded +exploration. + +## 8. Evaluation + +### 8.1 Baselines + +Compare against: + +- CPU-only execution; +- always-GPU for eligible payloads; +- fixed GPU batch thresholds; +- round-robin GPU selection; +- shortest-queue GPU selection; +- static earliest-finish estimates; +- existing blocking, event-barrier, and async synchronization modes where comparable; and +- a simulator oracle with access to true service distributions. + +Tune static policies and Kalman hyperparameters only on training scenarios, then freeze them before +held-out evaluation. + +### 8.2 Prediction metrics + +Evaluate: + +- MAE and relative error for service and transfer times; +- log-space error; +- 50%, 90%, and 95% predictive interval coverage; +- memory-quantile exceedance rate; +- normalized innovation mean, variance, and autocorrelation; +- convergence after cold start; +- adaptation time after drift; +- OOD detection and fallback frequency; and +- simulator-prior versus real-measurement influence over time. + +### 8.3 Scheduling metrics + +Evaluate: + +- completed events and eligible items per second; +- makespan; +- p50, p95, and p99 event residence; +- CPU/GPU busy intervals and sampled hardware utilization; +- queue delay and queue-growth slope; +- outstanding events and retained event state; +- peak host and device memory; +- exploration regret and conservative-budget consumption; +- OOM, retry, failure, and correctness counts; and +- telemetry, inference, and scheduling overhead. + +Use complete jobs or scenarios as train/test units rather than randomly splitting event rows. +Repeat scenarios with paired seeds and report paired confidence intervals. + +### 8.4 First-study acceptance criteria + +The adaptive policy must achieve: + +- at least 10% throughput improvement over the best frozen static safe policy; +- a paired confidence interval for throughput gain that excludes zero; +- p95 and p99 event residence within 10% of the static baseline; +- no positive queue-growth trend in the final measurement window; +- no OOM or CPU/GPU correctness failures; +- model, telemetry, and controller overhead below 1% of job CPU time; and +- calibrated predictive intervals sufficient for the configured safety quantiles. + +## 9. Deployment stages + +1. Extend Simload with routable equivalent payloads, resource pools, and normalized telemetry. +2. Fit weak simulator priors with Bayesian regression. +3. Validate zero-process-noise Kalman updates against the corresponding batch posterior. +4. Add drift-aware device calibration and constrained earliest-finish scheduling. +5. Evaluate static, adaptive, exploratory, and oracle policies on held-out simulator scenarios. +6. Instrument real jobs and run the model in shadow mode. +7. Enable guarded exploration while retaining static routing. +8. Enable adaptive exploitation on a small canary job set. +9. Persist compatible historical structural posteriors as shared priors. +10. Expand use only after prediction calibration and scheduling constraints remain stable. + +## 10. Required tests + +### Bayesian and Kalman model + +- With \(Q=0\) and known \(R\), sequential Kalman updates match batch Bayesian linear regression. +- Posterior covariance contracts with repeated informative observations. +- Unobserved feature directions retain uncertainty. +- Simulator-prior covariance inflation gives real measurements the configured influence. +- Calibration coefficients adapt under drift while structural coefficients remain stable. +- Innovation gating prevents invalid telemetry from corrupting the posterior. +- Snapshot and restore reproduce identical predictions and updates. +- Log transformations and inverse predictions remain finite for boundary inputs. + +### Scheduler + +- Ineligible actions are never selected. +- Conservative memory quantiles prevent over-capacity dispatch. +- Queue-aware earliest finish distributes work across identical GPUs correctly. +- A slowed GPU loses work and recovers after its calibration posterior catches up. +- Event-tail and outstanding-state constraints override utilization gains. +- Exploration never exceeds its performance budget. +- Missing or stale telemetry triggers the static fallback. +- Logged propensities correspond to the safety-filtered action distribution. + +### Integration and study + +- Existing Simload modes and CSV interpretation remain compatible. +- Paired synthetic CPU/GPU payloads perform equivalent work. +- Multi-worker, multi-GPU traces preserve decision/outcome referential integrity. +- Delayed completions update the correct resource model. +- Run manifests and model lineages prevent incompatible posterior reuse. +- Deterministic analytic scenarios reproduce expected oracle and baseline rankings. + +## 11. Assumptions and boundaries + +- The allocated job owns its CPU cores and several identical GPUs. +- Geant4 event workers execute independent events; eligible track baskets are the primary + application analogy. +- CPU-only physics remains outside the learned routing action space. +- Equivalent CPU/GPU implementations exist for every explored action. +- Energy optimization, heterogeneous GPU types, shared nodes, and inter-node scheduling are later + extensions. +- Simulator evidence bootstraps priors and tests control logic; real-job measurements determine + operational performance. + +## 12. Related work informing the design + +- Geant4 uses master-worker event-level parallelism: + [Geant4 multithreading documentation](https://geant4.web.cern.ch/documentation/pipelines/master/bftd_html/ForToolkitDeveloper/OOAnalysisDesign/Multithreading/mt.html). +- AdePT's asynchronous design uses shared buffering and a dedicated GPU transport thread, motivating + basket-level scheduling and per-event lifetime constraints: + [AdePT asynchronous workflow paper](https://wrap.warwick.ac.uk/id/eprint/199489/1/epjconf_chep2025_01081.pdf). +- StarPU demonstrates runtime-calibrated per-architecture performance models feeding + earliest-finish scheduling: + [StarPU paper](https://onlinelibrary.wiley.com/doi/pdf/10.1002/cpe.1631). +- Lotaru demonstrates Bayesian linear runtime estimation and uncertainty for heterogeneous + scientific workflows: + [Lotaru paper](https://eprints.gla.ac.uk/305425/). +- Conservative contextual bandits motivate bounded online exploration against a safe baseline: + [Conservative Contextual Linear Bandits](https://arxiv.org/abs/1611.06426). +- Logged action propensities support counterfactual policy assessment: + [Doubly Robust Policy Evaluation and Learning](https://www.microsoft.com/en-us/research/publication/doubly-robust-policy-evaluation-and-learning-2/). From da0e5d1db9755fed2e213ca929f214679b6bde7b Mon Sep 17 00:00:00 2001 From: Dmitri Smirnov Date: Thu, 23 Jul 2026 15:02:47 -0400 Subject: [PATCH 2/5] docs: update plan.md --- docs/plan.md | 324 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 237 insertions(+), 87 deletions(-) diff --git a/docs/plan.md b/docs/plan.md index cc2d9fc..d70a3e4 100644 --- a/docs/plan.md +++ b/docs/plan.md @@ -73,33 +73,125 @@ Only payloads with verified alternative implementations enter the learned routin ### 3.2 Bayesian prediction targets -For an eligible payload basket \(i\), resource \(r\), and decision-time context \(x_i\), maintain -posterior predictive distributions for: - -\[ -p(T_{\mathrm{cpu},i} \mid x_i, D_t) -\] - -\[ -p(T_{\mathrm{gpu-compute},i,r} \mid x_i, D_t) -\] - -\[ -p(T_{\mathrm{h2d},i,r}, T_{\mathrm{d2h},i,r} \mid x_i, D_t) -\] - -\[ -p(M_{\mathrm{gpu-peak},i,r} \mid x_i, D_t) -\] - -These distributions provide: - -- expected CPU service time and uncertainty; -- expected GPU transfer and compute time and uncertainty; -- GPU memory quantiles and probability of exceeding the safe allocation; -- batch-size response, including the crossover point and diminishing returns; -- the posterior probability that a particular GPU placement finishes before CPU execution; and -- an out-of-distribution or insufficient-evidence indication. +Let $i$ identify a candidate basket, $d$ identify a scheduling decision made at wall-clock time +$\tau_d$, and $r$ identify a candidate execution resource. Let $b_i$ be the basket's immutable +descriptor and $s_{\tau_d}$ the fresh `ResourceSnapshot`. The **decision-time context** + +$$ +x_{i,r}^{(d)} = g(b_i, r, s_{\tau_d}) +$$ + +is the frozen, target-specific feature vector available before an action is selected. It can contain +the workload kind, item count, byte volumes, bounded complexity and batch features, event age, and +applicable active-load covariates. It must not contain the selected action's outcome or telemetry +observed later. The complete resource snapshot remains available to the controller; in particular, +queued work is used to derive queue delay rather than being learned as an intrinsic basket property. + +Let + +$$ +D_{\tau_d} += +\left\{ +\left(x_e, a_e, o_e\right) +: +o_e\text{ was validated and incorporated by }\operatorname{observe}\text{ before }\tau_d +\right\} +$$ + +be the accumulated real-job evidence available to the model at that decision. Here $a_e$ is the +selected action and $o_e$ its measured `DispatchOutcome`; simulator and compatible historical +evidence are represented by the prior. In-flight, rejected, or not-yet-incorporated outcomes are +not in $D_{\tau_d}$. Thus, $x_{i,r}^{(d)}$ is the **current prediction query**, whereas +$D_{\tau_d}$ is the **past evidence already used to fit the posterior**. These are the precise +forms of the earlier shorthand $x_i$ and $D_t$. + +Maintain four named posterior predictive distributions: + +$$ +\mathcal{P}_{i,d}^{\mathrm{cpu}} +:= +p\!\left( +T_{\mathrm{cpu},i} +\mid x_{i,\mathrm{cpu}}^{(d)}, D_{\tau_d} +\right) +$$ + +$$ +\mathcal{P}_{i,r,d}^{\mathrm{compute}} +:= +p\!\left( +T_{\mathrm{gpu-compute},i,r} +\mid x_{i,r}^{(d)}, D_{\tau_d} +\right) +$$ + +$$ +\mathcal{P}_{i,r,d}^{\mathrm{transfer}} +:= +p\!\left( +T_{\mathrm{h2d},i,r} +\mid x_{i,r}^{(d)}, D_{\tau_d} +\right) +\times +p\!\left( +T_{\mathrm{d2h},i,r} +\mid x_{i,r}^{(d)}, D_{\tau_d} +\right) +$$ + +$$ +\mathcal{P}_{i,r,d}^{\mathrm{memory}} +:= +p\!\left( +M_{\mathrm{gpu-peak},i,r} +\mid x_{i,r}^{(d)}, D_{\tau_d} +\right) +$$ + +The direct posterior summaries map to those names as follows: + +- $\mathcal{P}^{\mathrm{cpu}}$ supplies CPU service-time means, intervals, and quantiles. +- $\mathcal{P}^{\mathrm{compute}}$ supplies GPU compute-time means, intervals, and quantiles; + $\mathcal{P}^{\mathrm{transfer}}$ supplies the corresponding H2D and D2H summaries. Samples from + all three GPU components form the total GPU service-time distribution. +- $\mathcal{P}^{\mathrm{memory}}$ supplies peak-memory quantiles and the probability of exceeding + the safe allocation. + +Other scheduler quantities are **derived from**, rather than additional members of, the four +named distributions: + +- Batch-size response, crossover, and diminishing returns come from reevaluating the named + distributions for alternative candidate basket sizes. +- CPU-versus-GPU finish probabilities also include accumulation and predicted queued service. For + example, relative to $\tau_d$, + + $$ + F_{i,\mathrm{cpu}}^{(d)} + = + W_{\mathrm{cpu}}^{(d)} + T_{\mathrm{cpu},i} + $$ + + $$ + F_{i,r}^{(d)} + = + A_{i,r}^{(d)} + W_r^{(d)} + + T_{\mathrm{h2d},i,r} + + T_{\mathrm{gpu-compute},i,r} + + T_{\mathrm{d2h},i,r}, + $$ + + where $A_{i,r}^{(d)}$ is any proposed accumulation delay and $W_r^{(d)}$ is the delay derived + from work already admitted ahead of the basket. The controller compares samples to estimate + $\Pr(F_{i,r}^{(d)} < F_{i,\mathrm{cpu}}^{(d)})$. +- Out-of-distribution or insufficient-evidence status is a feature-support and uncertainty + diagnostic, not a fifth predictive distribution. + +The initial implementation maintains separate H2D and D2H model states and constructs +$\mathcal{P}^{\mathrm{transfer}}$ using conditionally independent residual draws given the frozen +context and current model state. If paired measurements show material residual covariance, the +transfer model must represent it explicitly. Finish-time comparisons must likewise record the +dependence assumptions used to compose their posterior samples. Queue delay is not trained as if it were an intrinsic payload property. The controller derives expected queue delay from the queued work and predicted service distributions. This avoids teaching @@ -107,10 +199,44 @@ the performance model policy-dependent behavior. ### 3.3 Scheduling decisions +A scheduling decision applies only to uncommitted eligible work. It occurs after one or more +compatible candidate baskets have been formed and a fresh resource snapshot has been captured, +immediately before the selected basket would be admitted to the CPU worker queue or a particular +GPU's FIFO queue. At that point the controller takes a consistent model version, freezes and logs +$x_{i,r}^{(d)}$ for every candidate resource, runs inference, filters and scores the actions, and +commits a `DispatchDecision`. + +The controller is invoked when: + +1. an event worker emits eligible items that create or change a ready basket; +2. compatible items arrive for a basket being accumulated; +3. an accumulation deadline, oldest-event limit, or backpressure limit requires reconsideration; + or +4. a completion releases capacity and, after any valid model update, pending work can usefully be + reconsidered. + +Choosing `accumulate` is nonterminal: it must establish a mandatory reconsideration deadline, and +the held work re-enters the controller on a compatible arrival, that deadline, or a useful capacity +change. A completion with no ready or held work updates telemetry and possibly the model, but does +not create a scheduling decision. Already admitted or running work is not migrated in the first +study. + +After a selected implementation completes, processing is ordered as: record and validate the +`DispatchOutcome`, call `observe()` for a valid measurement, commit the applicable parameter +update, capture a fresh resource snapshot, and then reconsider pending work. Consequently, a +completion can affect only later scheduling decisions. Event start, GPU start, and whole-event +merge are not model-update points. + +In the new routing workflow, the initial decision boundary occurs when an event worker exposes a +semantically equivalent CPU/GPU payload—analogous to the end of the current basket-forming CPU +phase, but not determined by the sampled `dispatch_fraction`. It need not occur exactly once per +event: one event may emit several baskets, while one accumulated basket may contain items from +several events. + The controller combines predictions with current resource and event state to choose: - execute on the CPU worker pool; -- dispatch the current basket to GPU \(j\); +- dispatch the current basket to GPU $j$; - temporarily accumulate more compatible items for a larger GPU basket; or - fall back to the configured static safe policy. @@ -122,6 +248,25 @@ A direct best-action classifier is also deliberately avoided. The current Simloa are generated workload assumptions, not counterfactual routing labels, and a classifier trained on them would become invalid as queues, devices, batch formation, and scheduling policies change. +### 3.4 Single-event decision and learning loop + +The following planned-workflow diagram extends the notebook's left-to-right CPU/GPU timeline +vocabulary. It follows one eligible basket while showing the earlier completion that supplied the +current posterior and a later event that reuses the same scheduling pipeline. + +[![Planned single-event adaptive dispatch and learning loop](figures/adaptive-dispatch-event-loop.svg)](figures/adaptive-dispatch-event-loop.svg) + +*Figure 1. Inference is a read-only use of the posterior and resource state at a scheduling point. +Dispatch changes admission, queue, and in-flight state but not model parameters. `observe()` updates +the applicable parameters only after a valid selected-backend payload completion; event merge does +not gate learning.* + +The event labels illustrate causality, not serialized execution. Events and payload completions are +asynchronous, so a later basket uses whichever committed model version exists when it captures its +snapshot; it does not wait for event $e$ to finish. Only the selected backend produces an outcome. +The [figure-generation source](figures/render_adaptive_dispatch_architecture.py) uses the same blue +CPU and orange GPU colors as the existing notebook visualization. + ## 4. Bayesian performance model with online Kalman updates The performance model has two connected stages. Before a job, Bayesian linear regression turns @@ -133,20 +278,24 @@ sequential, drift-aware update used by the scheduler. ### 4.1 Observation model +Let $k$ index valid outcome measurements in the order accepted by the applicable model state. This +is distinct from decision index $d$ because decisions and completions are asynchronous. At update +$k$, $x_k$ is the exact target-specific context frozen and logged at the originating decision; it +must not be recomputed from the resource state observed at completion. + Each positive timing or memory target is modeled in log space: -\[ -y_t = \log z_t = \phi(x_t)^\mathsf{T}\theta_t + v_t, -\qquad -v_t \sim \mathcal{N}(0, R_t) -\] +$$ +y_k = \log z_k = \phi(x_k)^\mathsf{T}\theta_k + v_k, \qquad +v_k \sim \mathcal{N}(0, R_k) +$$ where: -- \(z_t\) is a measured service time, transfer time, or memory peak; -- \(\phi(x_t)\) is a bounded feature basis computed from decision-time information; -- \(\theta_t\) contains performance coefficients; and -- \(R_t\) is observation-noise variance for the applicable payload/resource model. +- $z_k$ is a measured service time, transfer time, or memory peak; +- $\phi(x_k)$ is a bounded feature basis computed from decision-time information; +- $\theta_k$ contains performance coefficients; and +- $R_k$ is observation-noise variance for the applicable payload/resource model. The feature basis should initially include: @@ -170,18 +319,18 @@ study. Use Bayesian linear regression with a Normal-Inverse-Gamma prior for each prediction target and payload/resource class: -\[ +$$ \theta \mid \sigma^2 \sim \mathcal{N}(m_0, \sigma^2 P_0) -\] +$$ -\[ +$$ \sigma^2 \sim \operatorname{InvGamma}(a_0, b_0) -\] +$$ This stage supplies: -- a prior coefficient mean \(m_0\); -- conditional coefficient covariance scale \(P_0\); +- a prior coefficient mean $m_0$; +- conditional coefficient covariance scale $P_0$; - an observation-noise estimate; - posterior predictive Student-t intervals; and - a compact set of sufficient statistics that can be persisted without retaining every raw event. @@ -217,44 +366,44 @@ model but retain their own run- and device-specific calibration state. Online operation uses a linear Kalman-filter interpretation of sequential Bayes: -\[ -\theta_t = F_t\theta_{t-1} + w_t, +$$ +\theta_k = F_k\theta_{k-1} + w_k, \qquad -w_t \sim \mathcal{N}(0, Q_t) -\] +w_k \sim \mathcal{N}(0, Q_k) +$$ -For the initial implementation, \(F_t = I\). The predicted coefficient distribution is: +For the initial implementation, $F_k = I$. The predicted coefficient distribution is: -\[ -m_t^- = m_{t-1} -\] +$$ +m_k^- = m_{k-1} +$$ -\[ -P_t^- = P_{t-1} + Q_t -\] +$$ +P_k^- = P_{k-1} + Q_k +$$ -Given feature vector \(\phi_t\) and completed measurement \(y_t\): +Given feature vector $\phi_k$ and completed measurement $y_k$: -\[ -S_t = \phi_t^\mathsf{T}P_t^-\phi_t + R_t -\] +$$ +S_k = \phi_k^\mathsf{T}P_k^-\phi_k + R_k +$$ -\[ -K_t = P_t^-\phi_t S_t^{-1} -\] +$$ +K_k = P_k^-\phi_k S_k^{-1} +$$ -\[ -m_t = m_t^- + K_t(y_t - \phi_t^\mathsf{T}m_t^-) -\] +$$ +m_k = m_k^- + K_k(y_k - \phi_k^\mathsf{T}m_k^-) +$$ -\[ -P_t = (I - K_t\phi_t^\mathsf{T})P_t^- -\] +$$ +P_k = (I - K_k\phi_k^\mathsf{T})P_k^- +$$ -The resulting posterior \(\mathcal{N}(m_t, P_t)\) becomes the prior for the next observation. -With \(Q_t=0\) and known \(R_t\), this is mathematically equivalent to sequential Gaussian +The resulting posterior $\mathcal{N}(m_k, P_k)$ becomes the prior for the next observation. +With $Q_k=0$ and known $R_k$, this is mathematically equivalent to sequential Gaussian Bayesian linear regression and recursive least squares. For scheduling, combine parameter -uncertainty \(\phi_t^\mathsf{T}P_t\phi_t\) with observation noise \(R_t\), then transform predictive +uncertainty $\phi_k^\mathsf{T}P_k\phi_k$ with observation noise $R_k$, then transform predictive samples from log space back to physical time or memory units. This preserves the asymmetric uncertainty that matters for finish-time and memory-risk decisions. @@ -265,13 +414,13 @@ does not require a heavyweight probabilistic framework. Partition the coefficients conceptually into: -\[ -\theta_t = +$$ +\theta_k = \begin{bmatrix} -\theta_{\mathrm{structural},t} \\ -\theta_{\mathrm{calibration},t} +\theta_{\mathrm{structural},k} \\ +\theta_{\mathrm{calibration},k} \end{bmatrix} -\] +$$ Structural coefficients describe relationships such as scaling with payload size, transfer volume, and batch size. Calibration coefficients describe the current run or device, including speed @@ -279,13 +428,13 @@ offset, contention sensitivity, thermal effects, and other short-term changes. Configure block-diagonal process noise: -\[ +$$ Q = \begin{bmatrix} Q_{\mathrm{structural}} & 0 \\ 0 & Q_{\mathrm{calibration}} \end{bmatrix} -\] +$$ with: @@ -294,14 +443,14 @@ with: - larger process noise for run- and device-specific calibration coefficients. This preserves knowledge learned across jobs while allowing current performance to move. Initial -values of \(Q\) should be derived from repeated-run variance in the simulator and calibration data, +values of $Q$ should be derived from repeated-run variance in the simulator and calibration data, then tuned only on training scenarios. ### 4.5 Observation noise and robust updates Observation noise is initially estimated by the Normal-Inverse-Gamma regression. During operation: -- update \(R\) from a bounded exponentially weighted innovation statistic; +- update $R$ from a bounded exponentially weighted innovation statistic; - maintain separate noise estimates by target, workload kind, and resource class; - apply an innovation gate before updating; - classify initialization, telemetry failure, allocation retry, and preemption measurements @@ -316,9 +465,9 @@ payloads must remain in the dataset because they are important to scheduling. Track normalized innovation: -\[ -\eta_t = \frac{y_t-\phi_t^\mathsf{T}m_t^-}{\sqrt{S_t}} -\] +$$ +\eta_k = \frac{y_k-\phi_k^\mathsf{T}m_k^-}{\sqrt{S_k}} +$$ Use sustained innovation bias, interval-coverage degradation, or a version change to identify drift. On drift: @@ -377,11 +526,12 @@ backend. Use conservative posterior sampling: - stop exploration when the budget is exhausted, telemetry is stale, or drift is active; and - never explore semantically unvalidated implementations. -The Kalman posterior provides the parameter distribution used for Thompson sampling: +Let $k(d)$ be the latest committed model-update index when decision $d$ captures its snapshot. +That Kalman posterior provides the parameter distribution used for Thompson sampling: -\[ -\tilde{\theta}_t \sim \mathcal{N}(m_t, P_t) -\] +$$ +\tilde{\theta}^{(d)} \sim \mathcal{N}\left(m_{k(d)}, P_{k(d)}\right) +$$ Observation-noise samples are included when comparing predicted realized completion times. Memory constraints use conservative posterior quantiles rather than an optimistic Thompson sample. @@ -582,7 +732,7 @@ The adaptive policy must achieve: ### Bayesian and Kalman model -- With \(Q=0\) and known \(R\), sequential Kalman updates match batch Bayesian linear regression. +- With $Q=0$ and known $R$, sequential Kalman updates match batch Bayesian linear regression. - Posterior covariance contracts with repeated informative observations. - Unobserved feature directions retain uncertainty. - Simulator-prior covariance inflation gives real measurements the configured influence. From 6fc07afe9957b3d5d063c5aaf2bcb5b11662cc0e Mon Sep 17 00:00:00 2001 From: Dmitri Smirnov Date: Thu, 23 Jul 2026 17:42:30 -0400 Subject: [PATCH 3/5] docs: update readme --- README.md | 127 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 83 insertions(+), 44 deletions(-) diff --git a/README.md b/README.md index e9d95b7..eef0ae4 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,19 @@ The benchmark runs real, time-bounded NumPy and PyTorch workloads. It is useful scheduling experiments, but it is not a physics simulation or a predictive model of a particular Geant4 application. +## Planned adaptive dispatch study + +The current benchmark measures fixed CPU/GPU stage synchronization; it does not yet perform learned +routing. The planned R&D extension adds a decision-time Bayesian performance model that routes +semantically equivalent payload baskets to the CPU pool or an eligible GPU, then learns from valid +completion measurements. The diagram follows one basket through prediction, dispatch, completion, +and the posterior update available to later decisions. + +[![Planned single-event adaptive dispatch and learning loop](docs/figures/adaptive-dispatch-event-loop.svg)](docs/plan.md#34-single-event-decision-and-learning-loop) + +See the [adaptive Bayesian CPU/GPU dispatch study plan](docs/plan.md) for the precise scheduling +points, prediction targets, safety constraints, and evaluation criteria. + ## Quick start ### Install and check the GPU @@ -42,7 +55,7 @@ This command has one input and two forms of output: workload, measured phase timings, queue/wait durations, and timeline offsets. With this configuration, Simload generates 20 events with a nominal mean work budget of 3 seconds -per event. The event manager runs the CPU part sequentially, while the event's post-dispatch CPU +per event. The event manager runs the CPU part sequentially, while the event's CPU continuation work is allowed to overlap its GPU work. Because this is a real compute workload, expect the example to take tens of seconds or longer, depending on the CPU, GPU, and numerical libraries. @@ -86,13 +99,13 @@ Interpret these values as follows: - `event_size_s` is a nominal work budget, not a measured runtime. It is divided into requested CPU and GPU work. -- `runtime_s` is event residence time: CPU-pre start through final merge. It is not the sum of CPU - and GPU runtimes, because the stages may overlap. +- `runtime_s` is event residence time: the start of basket-forming CPU work through completion of + event integration. It is not the sum of CPU and GPU runtimes, because the stages may overlap. - `gpu_queue_delay_s` reveals backlog at the single GPU worker. `gpu_wait_runtime_s` measures time spent at an explicit synchronization point. - `end_offset_s.max()` is the measured workload makespan from the simulation timing origin through - the final merge. It excludes event sampling before that origin and DataFrame, terminal, and CSV - processing afterward. + final event integration. It excludes event sampling before that origin and DataFrame, terminal, + and CSV processing afterward. For a visual comparison, open [the analysis notebook](notebooks/simload.ipynb): @@ -111,27 +124,46 @@ fig, ax, timeline = plot_run_timeline(df, "quickstart_event_barrier") The notebook combines runs and draws CPU/GPU busy intervals, which makes overlap and idle gaps much easier to see. +## Event-phase terminology + +The documentation uses the following domain-facing names. The existing `cpu_pre_*`, `cpu_post_*`, +and `merge_*` field names remain unchanged for compatibility with current CSVs, Python code, and +notebooks. + +| Preferred term | Existing fields | Definition and Geant4 analogy | +| --- | --- | --- | +| **Basket-forming CPU phase** | `cpu_pre_*` | CPU event work performed until a GPU-eligible basket is ready to submit. In the Geant4 analogy, this covers particle transport up to the point at which optical photons have been generated and collected into a dispatchable basket. | +| **CPU continuation phase** | `cpu_post_*` | CPU event work that remains after the basket is submitted. In the Geant4 analogy, this is follow-up transport of the remaining non-optical particles and other CPU-only event work. It can overlap GPU execution when the synchronization mode permits. | +| **GPU synchronization wait** | `gpu_wait_*` | Time during which the event manager or result collector explicitly waits for the selected GPU result. Its position relative to CPU continuation depends on the synchronization mode. | +| **Event integration phase** | `merge_*` | Reduction and bookkeeping that combine the completed CPU and GPU contributions into the event result. It begins after any required GPU wait and is measured separately from CPU continuation. | + +At the application level, CPU continuation, a possible GPU wait, and event integration together +form the broader **post-dispatch completion stage**. They remain separate phases in this study +because their ordering and timings are essential to explaining overlap and event residence. The +current synthetic benchmark does not transport particles or form a real optical-photon basket; the +mapping above defines the intended Geant4 interpretation of its synthetic phases. + +See the [editable general CPU/GPU event-phase diagram](docs/figures/cpu-gpu-event-phases.md) for a +plain-text view of the phase ordering and CPU/GPU worker lanes. + ## Compare the synchronization policies The three bundled mode configurations use the same default workload and seed, so they are a useful first comparison: ```bash -uv run simload --config config/mode_blocking.json \ - --out simload_runs/comparison/blocking.csv -uv run simload --config config/mode_event_barrier.json \ - --out simload_runs/comparison/event_barrier.csv -uv run simload --config config/mode_async.json \ - --out simload_runs/comparison/async.csv +uv run simload --config config/mode_blocking.json --out simload_runs/comparison/blocking.csv +uv run simload --config config/mode_event_barrier.json --out simload_runs/comparison/event_barrier.csv +uv run simload --config config/mode_async.json --out simload_runs/comparison/async.csv ``` The output directory is created automatically. These paths keep the bundled example CSVs untouched. | Mode | Event ordering | Overlap | What to look for | | --- | --- | --- | --- | -| `blocking` | CPU pre → submit GPU → wait → CPU post → merge | None by design | The wait exposes essentially the full GPU stage; queue delay should remain small. | -| `event_barrier` | CPU pre → submit GPU → CPU post → wait → merge | Within the current event | CPU-post work hides part of the GPU runtime; the wait records only the remaining GPU time. | -| `async` | CPU pre → submit GPU → CPU post → later CPU events → collect/merge | Within and across events | CPU progress can continue, but GPU queue delay can grow when submissions outpace the worker. | +| `blocking` | basket-forming CPU → submit GPU → wait → CPU continuation → event integration | None by design | The wait exposes essentially the full GPU stage; queue delay should remain small. | +| `event_barrier` | basket-forming CPU → submit GPU → CPU continuation → wait → event integration | Within the current event | CPU continuation hides part of the GPU runtime; the wait records only the remaining GPU time. | +| `async` | basket-forming CPU → submit GPU → CPU continuation → later CPU events → collect/integrate | Within and across events | CPU progress can continue, but GPU queue delay can grow when submissions outpace the worker. | All GPU tasks still execute in submission order on one worker and one CUDA stream. `async` pipelines events; it does not run multiple GPU stages concurrently. @@ -143,29 +175,45 @@ distribution. ## What the experiment models -The component topology is fixed; the synchronization mode determines the ordering of CPU post, GPU -waits, later CPU events, and merge: +The component topology is fixed; the synchronization mode determines the ordering and overlap of +CPU continuation, GPU waits, later CPU events, and event integration: -```text -CPU event manager: sample -> CPU pre -> submit -> policy-dependent CPU post / wait / merge - | -FIFO CUDA worker: +-> GPU stage -> result -``` +![General CPU/GPU event phases](docs/figures/event_timeline.svg) + +The figure is qualitative: horizontal widths do not encode durations. Its hand-offs illustrate the +blocking-style sequence; event-barrier and asynchronous modes use the same phases but can overlap +them. See the [phase definitions and rendering instructions](docs/figures/cpu-gpu-event-phases.md) +or edit the [Typst source](docs/figures/event_timeline.typ) directly. + +The figure uses application-level names while retaining explicit mappings to the current CSV +schema: + +- **Basket-forming CPU phase** (`cpu_pre_*`) performs CPU transport until GPU-eligible work has + been collected for submission. +- **GPU basket-processing phase** (`gpu_*`) processes the submitted compatible work on the GPU. +- **CPU continuation phase** (`cpu_post_*`) resumes or completes CPU-side work after submission. +- **Event integration** (`merge_*`) combines CPU and GPU results and completes required + event-level bookkeeping or synchronization. + +Both CPU phases are deliberately shown on the same CPU event-worker lane. Their separate colored +bands identify their positions relative to GPU submission and completion, not different CPU +resources. The synthetic workload is constructed in four steps: 1. Sample `event_size_s` from a fixed, uniform, or Gaussian distribution. 2. Sample `cpu_fraction` from a Beta distribution and set `gpu_fraction = 1 - cpu_fraction`. -3. Split the requested CPU work around a sampled dispatch point into `cpu_pre_work_s` and - `cpu_post_work_s`. +3. Split the requested CPU work around a sampled dispatch point into synthetic basket-forming work + (`cpu_pre_work_s`) and CPU continuation work (`cpu_post_work_s`). 4. Scale the CPU/GPU matrix dimensions, nominal GPU allocation, and transfer volumes from the sampled work. -The CPU manager executes time-bounded NumPy matrix multiplications for the pre- and post-dispatch -phases. A dedicated local thread executes the GPU stage with PyTorch, including synthetic -host-to-device transfer, device allocation, matrix multiplication, device-to-host transfer, and -synchronization. A small final delay represents event reduction/bookkeeping. +The CPU manager executes time-bounded NumPy matrix multiplications for the synthetic +basket-forming and CPU continuation phases. A dedicated local thread executes the GPU stage with +PyTorch, including synthetic host-to-device transfer, device allocation, matrix multiplication, +device-to-host transfer, and synchronization. A small final delay represents event integration +through reduction/bookkeeping. There is no external event-arrival clock, batching model, or synthetic resource pool. CPU events are started sequentially by one Python event-manager thread, although the NumPy BLAS implementation may @@ -179,7 +227,7 @@ columns fall into four useful groups: | Group | Representative columns | Meaning | | --- | --- | --- | | Sampled workload | `event_size_s`, `cpu_fraction`, `gpu_fraction`, `dispatch_fraction` | Nominal event composition chosen before execution. | -| Requested payload | `cpu_pre_work_s`, `gpu_work_s`, `cpu_post_work_s`, matrix sizes, `gpu_memory_mb`, `h2d_mb`, `d2h_mb` | Work targets and synthetic resource sizes. These are not observed utilization or bandwidth. | +| Requested payload | `cpu_pre_work_s`, `gpu_work_s`, `cpu_post_work_s`, matrix sizes, `gpu_memory_mb`, `h2d_mb`, `d2h_mb` | Requested basket-forming, GPU, and CPU-continuation work plus synthetic resource sizes. These are not observed utilization or bandwidth. | | Measured durations | `runtime_s`, `cpu_*_runtime_s`, `gpu_runtime_s`, `gpu_queue_delay_s`, `gpu_wait_runtime_s`, `merge_runtime_s` | Wall-clock phase and event durations measured with `time.perf_counter()`. | | Timeline | raw `*_time` columns and corresponding `*_time_offset_s` columns | Stage boundaries for reconstructing overlap within one run. | @@ -192,12 +240,12 @@ retains a fallback so it can also visualize those older artifacts. | Column | Interpretation | | --- | --- | | `event_size_s` | Requested total work budget. By construction, `cpu_work_s + gpu_work_s = event_size_s`. | -| `cpu_runtime_s` | Measured CPU busy time: `cpu_pre_runtime_s + cpu_post_runtime_s`. | +| `cpu_runtime_s` | Measured basket-forming plus CPU-continuation busy time: `cpu_pre_runtime_s + cpu_post_runtime_s`. | | `gpu_runtime_s` | Worker start to GPU completion, including allocation, transfers, matrix work, and synchronization. | | `gpu_queue_delay_s` | Time from local submission to worker start. It measures FIFO backlog and thread scheduling, not CUDA kernel-queue latency. | | `gpu_wait_runtime_s` | Time spent in the explicit wait performed by the event manager or result collector. | -| `merge_runtime_s` | Final synthetic reduction delay and its small Python overhead. | -| `runtime_s` | CPU-pre start to merge completion for the event. In `async`, this can include substantial deferred completion time. | +| `merge_runtime_s` | Event-integration time: the final synthetic reduction delay and its small Python overhead. It excludes explicit GPU waiting. | +| `runtime_s` | Basket-forming CPU start to event-integration completion. In `async`, this can include substantial deferred completion time. | | `start_offset_s`, `end_offset_s` | Event start and completion relative to the simulation timing origin. | The raw timestamp columns—such as `gpu_submit_time`, `gpu_start_time`, and `merge_end_time`—use an @@ -209,7 +257,7 @@ A few distinctions matter when interpreting a run: - In `blocking` mode, `cpu_end_time - cpu_start_time` spans the intervening GPU wait. Use `cpu_runtime_s` or the separate CPU phase intervals for actual CPU busy time. -- In `event_barrier` mode, CPU post and GPU runtime can overlap, so adding their durations +- In `event_barrier` mode, CPU continuation and GPU runtime can overlap, so adding their durations overestimates elapsed time. - In `async` mode, a near-zero `gpu_wait_runtime_s` can simply mean the GPU result was already ready when it was collected. It does not imply that the event completed immediately. @@ -248,7 +296,8 @@ The notebook: - loads and combines the CSVs, using each filename stem as the run label; - writes the combined table to `simload_analysis/combined.csv`; -- displays separate CPU-pre and CPU-post intervals for current local outputs; and +- displays separate basket-forming and CPU-continuation intervals (`cpu_pre_*` and `cpu_post_*`) for + current local outputs; and - falls back to a whole-CPU interval when reading outputs from the earlier schema. To save the displayed timeline, pass `outdir=outdir` to `plot_run_timeline` in the final cell. @@ -319,7 +368,7 @@ uv run simload --config config/my_experiment.json --out simload_runs/my_experime | `gpu_mode` | unset | Explicit `blocking`, `event_barrier`, or `async` policy. | | `gpu_async` | `false` | Legacy policy flag used only when `gpu_mode` is absent. | | `async_merge_ready` | `false` | If `true`, merge already-complete async events between CPU events instead of deferring all collection. Use a JSON boolean, not a string. | -| `reduce_work_s` | `0.01` | Synthetic event reduction delay. | +| `reduce_work_s` | `0.01` | Synthetic event-integration delay for reduction/bookkeeping. | | `num_cpus_per_event` | `1.0` | Resource-request metadata in local output; not enforced. | | `num_gpus_per_event` | `1.0` | Resource-request metadata in local output; not enforced. | @@ -437,13 +486,3 @@ part of the experiment, but it is not a drop-in equivalent of the local model: The Ray CSV does not expose scheduler queue delay or explicit wait duration. Do not pass `config/mode_event_barrier.json` to `simload-ray`; that implementation does not interpret `gpu_mode`. Also use a separate output filename when comparing the two implementations. - -## Repository layout - -```text -teerex/simload.py main local CPU/GPU experiment -teerex/simload_ray.py earlier Ray-scheduled variant -teerex/analysis.py CSV loading and plotting helpers -config/ workload and synchronization examples -notebooks/simload.ipynb interactive comparison notebook -``` From a77f59daac7b51a4e243d437c502e94559701b88 Mon Sep 17 00:00:00 2001 From: Dmitri Smirnov Date: Thu, 23 Jul 2026 20:45:01 -0400 Subject: [PATCH 4/5] chore: update notebooks/simload.ipynb --- notebooks/simload.ipynb | 38 +++++++++++--------------------------- 1 file changed, 11 insertions(+), 27 deletions(-) diff --git a/notebooks/simload.ipynb b/notebooks/simload.ipynb index 6d2d5e2..d3a1ca2 100644 --- a/notebooks/simload.ipynb +++ b/notebooks/simload.ipynb @@ -10,7 +10,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 2, "id": "bb28123a", "metadata": {}, "outputs": [], @@ -43,7 +43,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 3, "id": "05e6c1fd", "metadata": {}, "outputs": [ @@ -55,7 +55,7 @@ " PosixPath('../simload_runs/comparison/event_barrier.csv')]" ] }, - "execution_count": 2, + "execution_count": 3, "metadata": {}, "output_type": "execute_result" } @@ -82,14 +82,6 @@ "csv_files" ] }, - { - "cell_type": "code", - "execution_count": null, - "id": "552c3cbb-c79f-4e25-9dec-baa722123e70", - "metadata": {}, - "outputs": [], - "source": [] - }, { "cell_type": "markdown", "id": "c68cfa8a", @@ -100,7 +92,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 4, "id": "e880379c", "metadata": {}, "outputs": [ @@ -328,7 +320,7 @@ "[5 rows x 64 columns]" ] }, - "execution_count": 5, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } @@ -344,7 +336,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 5, "id": "6537a544", "metadata": {}, "outputs": [ @@ -374,7 +366,7 @@ " dtype='str')" ] }, - "execution_count": 6, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } @@ -395,7 +387,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 6, "id": "0f6a6127-1147-4cd8-bc4e-ee9e0accb16b", "metadata": {}, "outputs": [], @@ -527,13 +519,13 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 7, "id": "0e7d57af", "metadata": {}, "outputs": [ { "data": { - "image/png": "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mqYyMzNVrVq1G7ajCHKdvFO2KlSowIcWbi8sLIx5inKBuYrygHmK8oK5ivKAeQpXKM6JDFykBQAAAAAAPAJFEAAAAAAA4BEoglzH399fkydPlr+/v6ujAIVinqK8YK6iPGCeorxgrqI8YJ7C3fF0GAAAAAAA4BE4EwQAAAAAAHgEiiAAAAAAAMAjUAQBAAAAAAAegSIIAAAAAADwCBRBAAAAAACAR6AIAgAAAAAAPAJFEAAAAAAA4BEoggAAAAAAAI9AEQQAAAAAAHgEiiAAAAAAAMAjUAQBAAAAAAAegSIIAAAAAADwCBRBAAAAAACAR6AIAgAAAAAAPAJFEAAAysgDDzyghg0bujqGpkyZIsMwXB0DxTB48GCFhIS4OoZTJCcnyzAMLV261CXjG4ahKVOmWF8vXbpUhmEoOTnZJXkAAK5BEQQAgBJYt26dzS9SKJ69e/dq4MCBqlGjhvz9/VWpUiW1b99eS5YsUW5urrWdYRjWP15eXqpWrZo6duyorVu32vRnGIZGjRpV4FgrV66UYRj5tpGkH3/8UYZhaMeOHdZlWVlZmj9/vu69915VrFhRfn5+qlatmrp3767333/fJl/eL/J5f7y9vXXrrbfqoYce0t69e/O1+8c//lFgxn/84x837S/g7733nubOnevqGAAAFIgiCAAAJbBu3TpNnTrV1TEc8re//U2XLl0qs/H+9a9/qVmzZtqyZYsGDBig1157TS+99JICAwM1dOhQzZw506Z9hw4d9M477+jtt9/WX//6V/3www9q27atPv/8c4ezrF27VlFRUWrevLkk6cyZM7rnnnv09NNPKyQkRH/729/0xhtv6KmnntKFCxf06KOPavr06fn66d+/v9555x0tXrxYjz76qDZv3qy7777bphDiqQorgsTExOjSpUt67LHHyj5UAR577DFdunRJMTExro4CAChDPq4OAAAAnOfKlSuyWCzy8/PLt+7ChQsKDg6Wj4+PfHyc90+AixcvKigoqMB13333nf7617+qZcuWWrdunUJDQ63rnnnmGe3atUv79u2z2SY+Pl4DBw60vn7ooYd0++23a+7cuercubNDWdetW6fOnTtbLwd67LHHlJSUpI8//li9evWyaTtp0iTt2rVLhw8fztfPnXfeaZPxnnvuUffu3bVo0SK98cYbDmW8WRmGoYCAAFfHsPL29pa3t7erYwAAyhhnggAA3Mpvv/2mIUOGqEqVKvL391eDBg20ePFi6/rff/9dPj4+BZ6NcfjwYRmGoQULFliXpaWl6ZlnnrFehhEXF6eZM2fKYrFY21x76cKbb76p2rVry9/fX82bN9fOnTut7QYPHqyFCxdKsr1so6R2796tVq1aKTAwUDVr1tTrr79usz47O1svvfSSmjZtqgoVKig4OFj33XeftmzZYtPu2txz58615j5w4ID1vh8HDhzQo48+qooVK+ree++VVPg9QZYvX66mTZsqMDBQlSpVUr9+/XTy5EmbNnn3Ndm9e7dat26toKAgPf/884Xu69SpU2UYht59912bAkieZs2aafDgwTc8Xo0aNVJERIR++eWXG7YrSlpamrZv364uXbpIkr799ltt2LBBTz75ZL4CyLX5BgwYUGTfbdu2lSSHMxbm2LFj6tSpk4KDg1WtWjVNmzZNpmla12/durXAS4AKug/H6dOn9fjjj6t69ery9/dX1apV1aNHD+ulOYMGDVJERIRycnLy5ejYsaPq1q1baM4HHnhAa9eu1fHjx62fj9jY2EKz5N3z5MSJE+ratatCQkJ0yy23WD9nP/74o9q2bavg4GDFxMTovffeyzdmcT7jBSnoniCxsbHq2rWrvvnmG7Vo0UIBAQGqVauWli1b5rRxAQCuxZkgAAC38fvvv+vuu++23u8hMjJSn3/+uYYOHaqMjAw988wzqlKliu6//3599NFHmjx5ss32H374oby9vfXII49IunqGwv3336/ffvtNw4cP16233qrt27dr0qRJSklJyXfK/nvvvafMzEwNHz5chmFo1qxZ6tWrl44dOyZfX18NHz5cp06d0qZNm/TOO+/YtY/nz5/Xgw8+qD59+qh///766KOP9P/+3/+Tn5+fhgwZIknKyMjQv/71L/Xv319PPPGEMjMz9dZbb6lTp07asWOHmjRpYtPnkiVLdPnyZT355JPW+23keeSRR1SnTh1Nnz7d5pfm673yyit68cUX1adPHw0bNkxnzpzR/Pnz1bp1ayUlJSk8PNza9uzZs+rcubP69eungQMHqkqVKgX2efHiRX355Zdq3bq1br31VruOV94xO3/+vOLi4uzuQ5I2bNggwzDUsWNHSdKaNWskyeaMDnsdPXpUklS5cmWH+7pebm6u/vKXv+juu+/WrFmztH79ek2ePFlXrlzRtGnTStxf7969tX//fj311FOKjY1VamqqNm3apBMnTig2NlaPPfaYli1bpg0bNqhr167W7U6fPq3Nmzfn+9xd64UXXlB6erp+/fVX/fOf/5SkIm/smpubq86dO6t169aaNWuW3n33XY0aNUrBwcF64YUXNGDAAPXq1Uuvv/66EhIS1LJlS9WsWVNSyT/jxXHkyBE9/PDDGjp0qAYNGqTFixdr8ODBatq0qRo0aFBq4wIAyogJAICbGDp0qFm1alXzjz/+sFner18/s0KFCubFixdN0zTNN954w5Rk/vjjjzbt6tevb7Zt29b6+u9//7sZHBxs/vTTTzbtJk6caHp7e5snTpwwTdM0f/nlF1OSWblyZfPcuXPWdv/+979NSeaaNWusy0aOHGna++Pz/vvvNyWZs2fPti7LysoymzRpYkZFRZnZ2dmmaZrmlStXzKysLJttz58/b1apUsUcMmSIdVle7rCwMDM1NdWm/eTJk01JZv/+/fPlyFuXJzk52fT29jZfeeUVm3Y//vij6ePjY7M8bx9ef/31Ivf3+++/NyWZo0ePLrJtHknm0KFDzTNnzpipqanmf//7X7Ndu3b5jpskc+TIkQX2sWLFClOSuWXLFpvljz32mHn//fdbXz/00EOmJDMtLc2m3aVLl8wzZ85Y/5w/f966Lu+YT5061Txz5ox5+vRpc+vWreYdd9xhSjI//vhjm3avvvpqgRlfffVVU5L5yy+/3PB4DBo0yJRkPvXUU9ZlFovF7NKli+nn52eeOXPGNE3T3LJlS4H7nJdjyZIlpmlenUc3ymWappmbm2tWr17d7Nu3r83yOXPmmIZhmMeOHbth5i5dupgxMTH5ll+f5dr9mz59unXZ+fPnzcDAQNMwDPODDz6wLj906JApyZw8ebJ1WXE/46Zp5tt2yZIl+d6DmJgYU5L5n//8x7osNTXV9Pf3N8eNG2fXuAAA98LlMAAAt2Capj7++GN169ZNpmnqjz/+sP7p1KmT0tPTtWfPHklSr1695OPjow8//NC6/b59+3TgwAH17dvXumzFihW67777VLFiRZv+2rdvr9zcXP3nP/+xydC3b19VrFjR+vq+++6TdPVSBGfx8fHR8OHDra/9/Pw0fPhwpaamavfu3ZKu3qsg754eFotF586d05UrV9SsWTPrMbhW7969FRkZWeB4f/3rX4vMtGrVKlksFvXp08fmOEVHR6tOnTr5LsPx9/fX448/XmS/GRkZklTgZTA38tZbbykyMlJRUVG66667tG3bNo0dO1bPPPNMifq5lsVi0fr1662Xwlyb7/ozFV5//XVFRkZa/+RdRnStyZMnKzIyUtHR0XrggQd09OhRzZw5s9DLahx17ZNw8s6Uys7O1hdffFGifgIDA+Xn56etW7fq/PnzBbbx8vLSgAED9OmnnyozM9O6/N1331WrVq2sZ2E407Bhw6x/Dw8PV926dRUcHKw+ffpYl9etW1fh4eE2n8eSfsaLo379+tbPviRFRkaqbt26pT4uAKBscDkMAMAtnDlzRmlpaXrzzTf15ptvFtgmNTVVkhQREaF27drpo48+0t///ndJVy+F8fHxsfkl9Oeff9YPP/xQaIEgr78811+ykVcQKeyXRXtUq1ZNwcHBNsvi4+MlXb1nwt133y1JevvttzV79mwdOnTI5t4MBf0CeqNfSovzC+vPP/8s0zRVp06dAtf7+vravL7lllsKvPHq9cLCwiTJ5hfp4ujRo4dGjRolwzAUGhqqBg0a5DtmxXHtfU927typM2fO2BRB8oozf/75pypUqGBd3rt3bzVs2FCSNG7cOJtH5OZ58skn9cgjj8jLy0vh4eFq0KCB/P39HcpYGC8vL9WqVctm2bVzpiT8/f01c+ZMjRs3TlWqVNHdd9+trl27KiEhQdHR0dZ2CQkJmjlzplavXq2EhAQdPnxYu3fvznf/GmcICAjI9xmtUKGCqlevnu/4VKhQwebzWNLPeHEUdOlWxYoVS31cAEDZoAgCAHALeTcTHDhwoAYNGlRgm9tvv9369379+unxxx/X3r171aRJE3300Udq166dIiIibPrs0KGDnnvuuQL7y/tFMk9hT4owb3AvjdKwfPlyDR48WD179tT48eMVFRUlb29vzZgxw3rviWsFBgYW2teN1uWxWCwyDEOff/55gcfg+jMlitOnJMXFxcnHx0c//vhjsdrnqV69utq3b3/DNv7+/oU+5vfixYuSZPMkknXr1ik2Nlb169e3LqtXr56kq2cR3XPPPdblNWrUUI0aNSTJ+j/916tTp84NM+aNXZKMjiismFJQAeeZZ55Rt27d9Mknn2jDhg168cUXNWPGDG3evFl33HGHpKtnQzRt2lTLly9XQkKCli9fLj8/P5szM5ylsM9dcT6PJf2MO5KntMcFAJQNiiAAALcQGRmp0NBQ5ebmFvkLsCT17NlTw4cPt14S89NPP2nSpEk2bWrXrq0///yzWP0Vlz1Pg7nWqVOnrI+qzfPTTz9JkvUpGitXrlStWrW0atUqm/FudENKR9SuXVumaapmzZpO/eUtKChIbdu21ebNm3Xy5ElrYcEZYmJiCnx0rSTr8piYGOuytWvX6sEHH7Rp17VrVyUmJurdd9+1KYI4Q2RkpIKCgm6YMSgoyKZoVxiLxaJjx47ZvDfXz5m8s5bS0tJstj1+/HiBfdauXVvjxo3TuHHj9PPPP6tJkyaaPXu2li9fbm2TkJCgsWPHKiUlRe+99566dOlic7lYYRz9jJREaXzG3XlcAIDjuCcIAMAteHt7q3fv3vr444+1b9++fOvPnDlj8zo8PFydOnXSRx99pA8++EB+fn7q2bOnTZs+ffpYH4N6vbS0NF25cqXEOfOKF9f/sllcV65c0RtvvGF9nZ2drTfeeEORkZFq2rSppP/7n+hr/+f5v//9r7799lu7xixKr1695O3tralTp+Y768U0TZ09e9buvidPnizTNPXYY4/pzz//zLd+9+7devvtt0vc74MPPqjvvvvOeh+VPGlpaXr33XfVpEkT6+Udv//+u/bs2WNzKYwk3XPPPerQoYPefPNN/fvf/y5wHHvPAvL29lbHjh21Zs0anThxwmbdiRMntGbNGnXs2LHQsw6ud+1jn03T1IIFC+Tr66t27dpJulrw8fb2zncvitdee83m9cWLF3X58mWbZbVr11ZoaKiysrJslvfv31+GYWj06NE6duxYsZ+iExwcrPT09GK1dVRpfMbdeVwAgOM4EwQA4DYSExO1ZcsW3XXXXXriiSdUv359nTt3Tnv27NEXX3yhc+fO2bTv27evBg4cqNdee02dOnWyeYyrJI0fP16ffvqpunbtan3E5YULF/Tjjz9q5cqVSk5OLtb/xF8rr1Dx9NNPq1OnTvL29la/fv2KvX21atU0c+ZMJScnKz4+Xh9++KH27t2rN99803rvja5du2rVqlV66KGH1KVLF/3yyy96/fXXVb9+/QILCY6qXbu2Xn75ZU2aNEnJycnq2bOnQkND9csvv2j16tV68skn9eyzz9rVd6tWrbRw4UKNGDFC9erV02OPPaY6deooMzNTW7du1aeffqqXX365xP1OnDhRK1asUOvWrTV8+HDVq1dPp06d0tKlS5WSkqIlS5ZY265bt04BAQFq06ZNvn6WL1+uv/zlL+rZs6c6d+6s9u3bq2LFijp9+rS++OIL/ec//1Hnzp3t2vfp06fr7rvv1p133qknn3xSsbGxSk5O1ptvvinDMDR9+vRi9RMQEKD169dr0KBBuuuuu/T5559r7dq1ev755633pKhQoYIeeeQRzZ8/X4ZhqHbt2vrss8/y3Zvip59+Urt27dSnTx/Vr19fPj4+Wr16tX7//fd88zgyMlJ/+ctftGLFCoWHh+crIhWmadOm+vDDDzV27Fg1b95cISEh6tatW7G2LanS+Iy787gAACdwyTNpAAAoxO+//26OHDnSrFGjhunr62tGR0eb7dq1M9988818bTMyMszAwEBTkrl8+fIC+8vMzDQnTZpkxsXFmX5+fmZERITZqlUr8x//+If1kbQ3epyprnus5pUrV8ynnnrKjIyMNA3DKNHjcu+//36zQYMG5q5du8yWLVuaAQEBZkxMjLlgwQKbdhaLxZw+fboZExNj+vv7m3fccYf52WefmYMGDbJ59OiNcuc9BjfvEaoFrbvexx9/bN57771mcHCwGRwcbNarV88cOXKkefjw4Xz7UFK7d+82H330UbNatWqmr6+vWbFiRbNdu3bm22+/bebm5lrb6QaPvr3er7/+ag4bNsy85ZZbTB8fH7NSpUpm165dze+++86m3cMPP2w++OCDhfZz6dIlc+7cuWbLli3NsLAw08fHx4yOjja7du1qvvvuu+aVK1esbYt69O31Dh48aPbt29eMiooyfXx8zKioKLNfv37mwYMHi7X9oEGDzODgYPPo0aNmx44dzaCgILNKlSrm5MmTbY6baZrmmTNnzN69e5tBQUFmxYoVzeHDh5v79u2zeSztH3/8YY4cOdKsV6+eGRwcbFaoUMG86667zI8++qjA8T/66CNTkvnkk08WK69pmuaff/5pPvroo2Z4eLgpyTpnC3tEbnBwcL4+CptnMTExZpcuXWyWFeczbprFf0Tu9f3n5bn28colGRcA4F4M0yzju70BAACUkStXrqhy5cqaMWOGRowY4eo45c6///1v9ezZU//5z39sHhsLAEB5xT1BAADATevcuXMaM2aMHnroIVdHKZf+93//V7Vq1dK9997r6igAADgF9wQB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bPrp0KGDEhISZJqmfvnlF7322mtq27at1q5dq86dOzuUsbxbt26dFi5cWGAh5NKlS/LxcY9/Krr6cwEAuHm4x082AAAgSfLy8lJAQIBLxv7ll1/Ur18/xcTEaPPmzapatap13ciRI3XkyBGtXbvWZptbbrlFAwcOtL5OSEhQXFyc/vnPfzpcBFm3bp3uuecehYeHS5LGjBmjDRs2aO7cuRo9erRN23Hjxunnn3/Wpk2b8vUTHx9vk/Ghhx7S7bffrrlz53p8EeRGXDUPC+LKzwUA4ObC5TAAAI/wxx9/qE+fPgoLC1PlypU1evRoXb58ucjtjh07pkceeUSVKlVSUFCQ7r777nyFAEm6fPmypkyZovj4eAUEBKhq1arq1auXjh49WmjfpmnqySeflJ+fn1atWiWp4HsfPPDAA2rYsKEOHDigNm3aKCgoSLfccotmzZqVr8/jx4+re/fuCg4OVlRUlLVwUJzLOWbNmqU///xTb731lk0BJE9cXFy+4sP1oqOjddttt+mXX365YbuiWCwWrV+/Xl26dJEknTx5Uv/617/0l7/8pdAMderU0YgRI4rsu1GjRoqIiHA4Y2GKmmt594cp6BKg6+/DkZmZqWeeeUaxsbHy9/dXVFSUOnTooD179kiSJk+eLF9fX505cyZfX08++aTCw8MLneeDBw/WwoULrePm/SksS949T3766ScNHDhQFSpUUGRkpF588UWZpqmTJ0+qR48eCgsLU3R0tGbPnp1vzKysLE2ePFlxcXHy9/dXjRo19Nxzz+W7jOl6jn4u7B0XAHDz4UwQAIBH6NOnj2JjYzVjxgx99913mjdvns6fP69ly5YVus3vv/+uVq1a6eLFi3r66adVuXJlvf322+revbtWrlyphx56SJKUm5urrl276ssvv1S/fv00evRoZWZmatOmTdq3b59q166dr+/c3FwNGTJEH374oVavXm39Zb8w58+f11/+8hf16tVLffr00cqVKzVhwgQ1atTIejbDhQsX1LZtW6WkpGj06NGKjo7We++9py1bthTrGK1Zs0a1atVSq1atitW+IDk5OTp58qQqV65sdx+StHPnTp05c0YPPvigJOnzzz9Xbm6uzRkd9jp//rzOnz+vuLg4h/sqiD1zrTB//etftXLlSo0aNUr169fX2bNn9c033+jgwYO688479dhjj2natGn6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8ApXHwV61YsvvihJVr9IFtW3b1/t3LlTO3bssEzLzc3Vq6++qvj4eLVs2VKSdM899+jXX3/VSy+9VGwbJZ2p0atXLy1fvlzr1q3Tn/70J5nNZrtqKqp379768ccf9cknn1imXbp0Sa+99ppN60+bNk0hISEaM2aMfv7552Lzjxw5on/9618VztW3b1+dOnWq2FM4Ll++rNdff13R0dFq3769pN+fLrNx48ZiT8tp0KCBRo0apbVr15Z4nKXKnRXTt29fffXVV0pNTbWanp2drWXLlum6665TTEyMTdsqb6yFh4crMjJS//vf/6yWe/nll61eFxYWKicnx2padHS0YmNjiz3atU+fPoqMjNTs2bO1bds2m88CuXpZUNGGjDMMGTJEP/74Y4nj8eLFi8rNza1W+wUAuCfOBAEAeIVjx47prrvu0h133KEdO3Zo6dKl+uMf/2h1aUVRTzzxhN577z316dNHEyZMUO3atfXWW2/p2LFj+vDDD+Xj8/v/JSQnJ+vtt9/WpEmTtHPnTnXr1k25ubnatGmTxo4dqwEDBhTb9sCBA7V48WIlJycrPDxcr7zySqVrfPjhh/XSSy9p2LBhevTRR1WvXj0tW7bMchlHef8L3qRJE7377ruWR6AmJyerdevWys/P15dffqkVK1Zo5MiRFc710EMP6c0339S9996rUaNGqV27djpz5oz+85//aN++fXr77bcVEBAgSfriiy907ty5Eh8ZPH/+fB07dkyPPPKIli9frv79+ys6Olq//vqrtm/frlWrVqlZs2YVzif9/l6vWLFCN998sx5++GE1b95cP/30k5YsWaLMzEwtXrzY5m3ZMtbGjBmjlJQUjRkzRh07dtT//vc/ff/991bbOX/+vOrXr6/BgwcrKSlJoaGh2rRpk3bt2qUXXnjBall/f3/dd999eumll+Tr66thw4bZlLVDhw6SpAkTJqh3797y9fXVfffdZ3OtFfGnP/1J77//vv7v//5Pn332mW688UYVFhbq4MGDev/997V+/Xp17Nix2uwXAOCmXPhkGgAAnO7qYz2/++47Y/DgwUZYWJhRq1YtY/z48cbFixetli36WE7DMIwjR44YgwcPNiIiIoygoCCjU6dOxurVq4vtJy8vz/jrX/9qNGrUyPD39zdiYmKMwYMHG0eOHDEMw/oRudd6+eWXDUnGlClTDMMo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r79emzZtstpuZmam+vXrp+DgYDVq1EjvvvtusWOdnZ2tMWPGKCoqSuHh4erRo4f27t1b6rFyVtaSjm2jRo0kSe3atZPJZNKtt95aYqbSxvX69evVokULhYaG6o477lBmZmapdUnSvn371KdPH4WGhqpu3br605/+pF9//dUyf926dbrpppsUERGhOnXq6M4777Qac5J06tQpDRs2TLVr11ZISIg6duyor7/+2mqZd955R/Hx8apZs6buu+8+nT9/vtRMV2v55JNP1LJlSwUGBurkyZMlnuk1cOBAjRw50uqYPv/88xo1apTCwsLUoEEDvfrqq2UegzVr1igwMFA33HCDZdpvv/2m4cOHKyoqSsHBwUpISNDixYst81u1aqXY2FitXLmyzG0DADwHTRAAgEf517/+pS5duujBBx9UZmamMjMzFRcXV+KyeXl5WrBggZYvX65169Zp69atuvvuu7VmzRqtWbNG77zzjl555RV98MEHlnXGjx+vHTt2aPny5frmm29077336o477tDhw4dL3MeHH36of/7zn3rllVd0+PBhffzxx2rTpk2ZNcycOVNDhgzRN998o759+2r48OGW/2n+8ccfdfPNNyswMFBbtmxRamqqRo0apStXrkiSli1bpqeeekrPPfecDhw4oOeff15PPvmk3nrrrVKP1zPPPKP69esrMzNTu3btKjXXP/7xDyUlJSktLU1PPvmkFixYoE8++UTvv/++Dh06pGXLlll++b+6ncWLF5e5XXu2ceHCBfXt21ebN29WWlqa7rjjDvXv318nT560bDc5OVk//fSTtm7dqg8//FCvvvqqsrKyrPZ97733KisrS2vXrlVqaqrat2+vnj17lvq/+s7KWtKx3blzpyRp06ZNyszM1EcffVTq+1JUXl6e/vGPf+idd97R//73P508eVJTpkwpdfns7Gz16NFD7dq10+7du7Vu3Tr9/PPPGjJkiGWZ3NxcTZo0Sbt379bmzZvl4+Oju+++23JmxoULF3TLLbfoxx9/1CeffKK9e/dq2rRpVmduHDlyRB9//LFWr16t1atXa9u2bUpJSSm3ltmzZ+v111/X/v37FR0dbfNxeOGFF9SxY0elpaVp7Nix+vOf/6xDhw6Vuvznn3+uDh06WE178skn9d1332nt2rU6cOCAFi1apMjISKtlOnXqpM8//9zmXAAAN2cAAOBhbrnlFuPRRx+1mvbZZ58ZkozffvvNMAzDWLx4sSHJyMjIsCzz8MMPGzVq1DDOnz9vmda7d2/j4YcfNgzDME6cOGH4+voaP/74o9W2e/bsaUyfPr3ELC+88IKRmJho5Ofnlzi/YcOGxj//+U/La0nG3/72N8vrCxcuGJKMtWvXGoZhGNOnTzcaNWpU6vaaNGlivPvuu1bTnn32WaNLly4lLm8YhvHPf/7TaNiwodW0osewYcOGxsCBA62WeeSRR4wePXoYZrO5xO1KMlauXFnqfh21DcMwjFatWhkvvviiYRiGceDAAUOSsWvXLsv8w4cPG5Isx/rzzz83wsPDjUuXLlltp0mTJsYrr7xSZVkNo+Rje+zYMUOSkZaWVua2bBnXCxcuNOrWrVvqNp599lnj9ttvt5r2ww8/GJKMQ4cOlbjOL7/8Ykgyvv32W8MwDOOVV14xwsLCjDNnzpS4/NNPP23UqFHDOHfunGXa1KlTjc6dO5ea62ot6enpVtNL+vkeMGCAMWLECMvrhg0bGvfff7/ltdlsNqKjo41FixaVur8BAwYYo0aNsprWv39/44EHHih1HcMwjIkTJxq33nprmcsAADwHZ4IAAKqtGjVqqEmTJpbXdevWVXx8vEJDQ62mXT2D4Ntvv1VhYaESExMVGhpq+bNt27ZilwZcde+99+rixYtq3LixHnzwQa1cudJy1kZp2rZta/l7SEiIwsPDLRnS09PVrVs3+fv7F1svNzdXR44c0ejRo63y/f3vfy81X0V07NjR6vXIkSOVnp6uZs2aacKECdqwYUOFt2nPNi5cuKApU6aoRYsWioiIUGhoqA4cOGA5u+LQoUPy8/NT+/btLes0bdpUtWrVsrzeu3evLly4oDp16lgdq2PHjpV6rJyR9aqix7Yyio7revXqFTsL5lp79+7VZ599ZnUcmjdvLkmWY3H48GENGzZMjRs3Vnh4uOUMmKt1pKenq127dqpdu3ap+4mPj7e6z0x5uaTf73ly7c9DRVy7nslkUkxMTJn7u3jxooKCgqym/fnPf9by5ct13XXXadq0afryyy+LrRccHKy8vDy7MgIA3I+fqwMAAOAsRRsJJpOpxGnXnvLv6+ur1NRU+fr6Wi13bePkWnFxcTp06JA2bdqkjRs3auzYsZo7d662bdtWYiOjtFxXMwQHB5daz4ULFyRJr732mjp37mw1r2hee4SEhFi9bt++vY4dO6a1a9dq06ZNGjJkiHr16mV1+VB57NnGlClTtHHjRv3jH/9Q06ZNFRwcrMGDB1fohqIXLlxQvXr1SryfS0RERJVnLXpsK6Ok8WMYRqnLX7hwQf3799fs2bOLzatXr54kqX///mrYsKFee+01xcbGymw2q3Xr1pY6yhqXZeUq70anwcHBxW766uPjU6yegoKCSu8vMjJSv/32m9W0Pn366MSJE1qzZo02btyonj17aty4cfrHP/5hWebs2bOKiooqsw4AgOegCQIA8DgBAQFWNzN1lHbt2qmwsFBZWVnq1q2bzesFBwerf//+6t+/v8aNG6fmzZvr22+/tTpTwVZt27bVW2+9pYKCgmK/5NWtW1exsbE6evSohg8fXuFt2yM8PFxDhw7V0KFDNXjwYN1xxx06e/asateuLX9/f5veh4puY/v27Ro5cqTuvvtuSb//En/8+HHL/GbNmunKlStKS0uz3OMhIyPD6hfc9u3b6/Tp0/Lz87PpcajOylqagIAASXLKOC6qffv2+vDDDxUfHy8/v+Jf/c6cOaNDhw7ptddes4z7L774wmqZtm3b6vXXX7ccC2eKioqyutFrYWGh9u3bp+7du1dqu+3atdPSpUtL3N+IESM0YsQIdevWTVOnTrVqguzbt6/UG9cCADwPl8MAADxOfHy8vv76ax0/fly//vqrwx6rmZiYqOHDhys5OVkfffSRjh07pp07d2rWrFn69NNPS1xnyZIleuONN7Rv3z4dPXpUS5cuVXBwsBo2bGhXhvHjx+vcuXO67777tHv3bh0+fFjvvPOO5YaPM2fO1KxZs7RgwQJ9//33+vbbb7V48WLNmzfP7rpLM2/ePL333ns6ePCgvv/+e61YsUIxMTGWMyni4+O1efNmnT59utj/sFdmGwkJCfroo4+Unp6uvXv36o9//KPVe9y8eXP16tVLDz30kHbu3Km0tDQ99NBDVmcV9OrVS126dNHAgQO1YcMGHT9+XF9++aX++te/avfu3VWWtTTR0dEKDg623KQ0Jyen3HXsNW7cOJ09e1bDhg3Trl27dOTIEa1fv14PPPCACgsLVatWLdWpU0evvvqqMjIytGXLFk2aNMlqG8OGDVNMTIwGDhyo7du36+jRo/rwww+1Y8cOh+ft0aOHPv30U3366ac6ePCg/vznP1uejlMZvXv31v79+63G6lNPPaX//ve/ysjI0P79+7V69Wq1aNHCMj8vL0+pqam6/fbbK71/AIB7oAkCAPA4U6ZMka+vr1q2bKmoqKhi91+ojMWLFys5OVmTJ09Ws2bNNHDgQO3atUsNGjQocfmIiAi99tpruvHGG9W2bVtt2rRJq1atUp06dezaf506dbRlyxbL0zg6dOig1157zXJWyJgxY/T6669r8eLFatOmjW655RYtWbLE8shVRwoLC9OcOXPUsWNHXX/99Tp+/LjWrFkjH5/fvz688MIL2rhxo+Li4tSuXTuHbWPevHmqVauWunbtqv79+6t3797Fzqp5++23VbduXd188826++679eCDDyosLMxyzweTyaQ1a9bo5ptv1gMPPKDExETdd999OnHihOrWrVulWUvi5+enBQsW6JVXXlFsbKwGDBhQ7jr2io2N1fbt21VYWKjbb79dbdq00WOPPaaIiAj5+PjIx8dHy5cvV2pqqlq3bq2JEydq7ty5VtsICAjQhg0bFB0drb59+6pNmzZKSUlxyGVYRY0aNUojRoxQcnKybrnlFjVu3LjSZ4FIUps2bdS+fXu9//77lmkBAQGaPn262rZtq5tvvlm+vr5avny5Zf5///tfNWjQoEJnhgEA3JvJKOsiUgAAAA9w6tQpxcXFadOmTerZs6er48BNffrpp5o6dar27dtnaW6V5YYbbtCECRP0xz/+sQrSAQCqAvcEAQAAHufq2TJt2rRRZmampk2bpvj4eN18882ujgY31q9fPx0+fFg//vij4uLiylz2119/1aBBgzRs2LAqSgcAqAqcCQIAADzO+vXrNXnyZB09elRhYWHq2rWr5s+fb/e9WAAAgHegCQIAAAAAALwCN0YFAAAAAABegSYIAAAAAADwCjRBAAAAAACAV6AJAgAAAAAAvAJNEAAAAAAA4BVoggAAAAAAAK9AEwQAAAAAAHgFmiAAAAAAAMAr/H/JXZ//fx9YTgAAAABJRU5ErkJggg==", + "image/png": "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Nc2hQ4daHj/99NOmJPOLL76wLEtLSzNr1aplRkdHm1lZWaZpmuby5ctNSeaCBQty9Z+dnW2apmn+/PPPpiRz3rx5ZmZmptm/f38zMDDQ3Lx5s9X627dvNyWZ27dvtyy77777TEnmqlWrLMvS09PNqKgos0+fPpZl8+fPNyWZH374oWXZ1atXzfr16+dq81YpKSmmJLNnz575rnOrmjVrmp06dTLPnz9vnj9/3vz222/NAQMGmJLMJ5980mq9rl275tnGnj17TEnmihUrrJa/8MILZs2aNS2Px48fb0oyDxw4YLVeenq6pf/z58+bv//+u9XzkswRI0aY58+fN5OSksxvvvnGfOCBB0xJ5vz5863WGzNmTJ4Z165dW+j+M82iz7WcuXDrmHNyTJs2zfK4fPny+ebK0bp1a/Ouu+6yWvbBBx8UKfOYMWPM/L4O3polZ3yPP/64Zdn169fNatWqmYZhmPHx8Zblly5dMgMDA63eT2+99Zbp5eVl9X4yTdN85ZVXTEnmzp07LctufS/a874oTr8AgLKP02EAAB5hzJgxVo+ffPJJSTeuO5GfjRs3qlWrVrr33nsty4KDg/X444/r5MmTOnz4sCTp/fffV3h4uKXNm918eoF043/oH3nkEX300UfauHGj5aKfhQkODrY6CsLPz0+tWrXSiRMnLMs2bdqk2267TT169LAsCwgI0GOPPVZo+6mpqZKkkJCQIuXJsWXLFkVERCgiIkJNmzbV2rVrNWTIEM2ZM6dY7dxq48aNVkfH5OQLDg7OtV5O/xEREapZs2autt544w1FREQoMjJSd911l3bu3KkJEybo6aeftitjfmyZa/kJCwvTN998o7Nnz+a7TlxcnL755hurU6/WrFmj6tWr67777it2n4UZOXKk5e/e3t5q0aKFTNPUiBEjrHLXq1fPan6uXbtWDRo0UP369fX7779b/nTo0EGSinzE0s2K8r5wRr8AgNKL02EAAB6hbt26Vo/r1KkjLy8vnTx5Mt9tTp06pbvuuivX8gYNGlieb9y4sY4fP6569eoV6U4as2fP1h9//KFPPvlE999/f5HzV6tWLVdBpUKFCvruu++s8tapUyfXekU57SM0NFTSjWtQFMddd92lv/3tbzIMQ+XKlVODBg0sFzItjpsznzt3Tvv379fMmTMty3KKM3/88YfVdvfcc4/lYqjz5s3Tzp07c7Xds2dPjR07VoZhKCQkRI0aNVJQUJBdGQtiy1zLz9y5czV06FBVr15dzZs310MPPaS4uDjVrl3bsk7//v319NNPa82aNXrxxReVkpKijz76SOPHjy9y5uKoUaOG1ePy5csrICBA4eHhuZZfuHDB8vinn37SkSNHFBERkWe7SUlJxc5SlPeFM/oFAJReFEEAAB7JGT8Oi6Jz587atGmT5s6dq/vvv7/Id7zw9vbOc7lpmg7JFRoaqqpVq+rgwYPF2i48PFwdO3YscJ2AgABdvXo1z+euXLliWSfHJ598ooCAALVv396yrH79+pKkgwcPqmnTppblERERlv5Xr16dZx/VqlUrNKO/v3+xMhbHrXMtv7mXlZWVa1m/fv3Utm1brV+/Xlu2bNG8efM0Z84cffDBB5ZrXlSoUEHdunWzFEHWrVun9PR0h1w/JS95zcWizM/s7Gw1adJECxYsyHPd6tWrOyRLSfQLACi9KIIAADzCTz/9pFq1alkeHzt2TNnZ2YqOjs53m5o1a+qHH37Itfzo0aOW56Ub/9P/zTffKDMzU76+vgXmuPvuu/XEE0+oW7dueuSRR7R+/foiHUFSFDVr1tThw4dlmqbVD+1jx44Vaftu3brptdde01dffaXWrVs7JNPNufKSs39vPo3l448/Vvv27RUYGGhZ1qVLF3l7e2vNmjUaNGiQw7LdnDGv1zq/jAUpbK5VqFBBkpScnGy13alTp/Jsr0qVKho9erRGjx6tpKQk3XnnnXrppZesbu8bFxennj17as+ePVqzZo3uuOMONWrUqNCsJVkMrFOnjr799ls98MADHtEvAMA9cU0QAIBHyLkVaI7FixdLktUPyVs99NBD2r17t7766ivLssuXL+u1115TdHS0GjZsKEnq06ePfv/9dy1ZsiRXG3kdqdGxY0e9++672rRpk4YMGaLs7GybxnSrzp0769dff9V///tfy7Jr167pX//6V5G2f/bZZxUUFKSRI0fqt99+y/X88ePH9c9//rPYuR566CGdOXMm11040tPT9frrrysyMlJ33nmnpBt3l9m6dWuuu+XUqFFDw4cP1yeffJLnfpbsOyrmoYce0tdff619+/ZZLU9OTtaaNWvUrFkzRUVFFamtwuZaaGiowsPD9b///c9qvZdfftnqcVZWllJSUqyWRUZGqmrVqrlu7dqlSxeFh4drzpw5+vzzz4t8FEjOaUG3FmScoV+/fvr111/znI9Xr17V5cuXy1S/AAD3xJEgAACP8PPPP6tHjx7605/+pK+++kqrV6/Wn//8Z6tTK241ZcoUvfPOO+rSpYueeuopVaxYUW+++aZ+/vlnvf/++/LyuvF/CXFxcVq1apUmTJig3bt3q23btrp8+bI+/fRTjR49Wj179szVdq9evbRixQrFxcUpNDRUr776qt1jHDVqlJYsWaKBAwdq3LhxqlKlitasWWM5jaOw/wWvU6eO3n77bcstUOPi4tS4cWNlZGRo165dWrt2rYYNG1bsXI8//riWL1+uRx55RMOHD9cdd9yhCxcu6L333tPBgwe1atUq+fn5SZK+/PJLpaam5nnL4IULF+rnn3/Wk08+qXfffVfdu3dXZGSkfv/9d+3cuVMbNmxQvXr1ip1PuvFar127Vu3atdOoUaNUv359nT17VitXrlRiYqJWrFhR5LaKMtdGjhyp+Ph4jRw5Ui1atND//vc//fjjj1btpKWlqVq1aurbt6+aNm2q4OBgffrpp9qzZ4/mz59vta6vr68GDBigJUuWyNvbWwMHDixS1ubNm0uSnnrqKXXu3Fne3t4aMGBAkcdaHEOGDNG///1vPfHEE9q+fbvuueceZWVl6ejRo/r3v/+tzZs3q0WLFmWmXwCAm3LhnWkAAHC6nNt6Hj582Ozbt68ZEhJiVqhQwRw7dqx59epVq3VvvS2naZrm8ePHzb59+5phYWFmQECA2apVK/Ojjz7K1c+VK1fM559/3qxVq5bp6+trRkVFmX379jWPHz9umqb1LXJv9vLLL5uSzGeeecY0zfxvBdqoUaNcfQ4dOtTqNrKmaZonTpwwu3btagYGBpoRERHmxIkTzffff9+UZH799ddF2mc//vij+dhjj5nR0dGmn5+fGRISYt5zzz3m4sWLzWvXrlntr/xufXurS5cumePHj7fsn9DQULN9+/bmJ598YrXeM888YzZs2DDfdq5fv26uWLHC7NChg1mxYkXTx8fHDA8PNx944AHzlVdeyfWaqoBb397qzJkz5siRI83bbrvN9PHxMStWrGh269atyPutOHPtypUr5ogRI8zy5cubISEhZr9+/cykpCSr29Kmp6ebkyZNMps2bWqGhISYQUFBZtOmTc2XX345z/53795tSjI7depUpLym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Zs2St7e3fv31V0nS/fffr8aNG+vw4cNq3769ypUrp9tuu01z587Nte21a9c0ffp0xcbGKiAgQFWqVFHv3r11/PjxfMd09epVzZ49W/Xr19ff//73PE9RGTJkiFq1alXgvunQoYMk6eeffy5wvcJ89tlnSk9PV5cuXSRJr7zyihITE7Vw4cJcBRBJMgxDAwcOVMuWLQtt21EZ87NlyxY1a9ZMAQEBatiwoT744AOr56dPn57n/s3rOhx79+5V586dFR4ersDAQNWqVUvDhw+XdOPInejoaPXs2TNXW9euXVP58uU1atSofHMahqHLly/rzTfftJwyNGzYsHyz5FzzZMeOHWrRooUCAwPVpEkTy7U7PvjgAzVp0kQBAQFq3rx5nvP66NGj6tu3rypWrKiAgAC1aNFC//3vf/PNmOPWa4KcPHlShmHo73//u1577TXVqVNH/v7+atmypfbs2eOwfgEAno0iCAAAkvbs2aNdu3ZpwIABWrRokZ544gl99tlnuv/++3XlyhXLetOnT9eMGTPUvn17LVmyRM8//7xq1Kih/fv3S5L69u2rwMBArVmzJlcfa9as0f3336/bbrvNsuzSpUv605/+pKZNm2r+/PmqX7++Jk+erE8++cSyTlZWlrp166YZM2aoefPmmj9/vsaNG6eUlBQdPHgw3zF9+eWXunjxov785z/bdQRATqGlUqVKNrchSRs3blTz5s1VuXJlSdKGDRsUGBio3r1729WuIzPm5aefflL//v3VpUsXzZ49Wz4+PnrkkUcsha/iSEpKUqdOnXTy5ElNmTJFixcv1qBBg/T1119LulHEGDx4sD755BNdvHjRatsNGzYoNTVVgwcPzrf9t956S/7+/mrbtq3eeustvfXWWwUWTSTp2LFj+vOf/6zu3btr9uzZunTpkrp37641a9Zo/PjxGjx4sGbMmKHjx4+rX79+VqewHDp0SHfffbeOHDmiKVOmaP78+QoKClKvXr20fv36Yu8fSXr77bc1b948jRo1Sn/729908uRJ9e7d2+o6Ms7oFwDgIUwAAGBeuXIl17KvvvrKlGSuWrXKsqxp06Zm165dC2xr4MCBZtWqVc2srCzLsv3795uSzBUrVliW3XfffbnaT09PN6Oiosw+ffpYli1fvtyUZC5YsCBXX9nZ2fnm+Oc//2lKMtevX19g3hzbt283JZnLly83z58/b549e9b8+OOPzejoaNMwDHPPnj1W661duzbPdsaMGWPm9RWjRo0a5rRp0yyPK1SoYDZr1izXeqmpqeb58+ctf/744w/LcytWrDAlmZ9++ql5/vx585dffjHfffdds1KlSmZgYKB55swZq/VyMt+qa9euZs2aNQvdJzVr1jQlme+//75lWUpKilmlShXzjjvusCybNm1anmPOyfHzzz+bpmma69evLzCXaZrmDz/8YEoyly1bZrW8R48eZnR0dIGvuWmaZlBQkDl06NBCs9w8vl27dlmWbd682ZRkBgYGmqdOnbIsf/XVV01J5vbt2y3LHnjgAbNJkybmtWvXLMuys7PNNm3amHXr1rUsy5kzN287dOhQq9fg559/NiWZlSpVMi9evGhZ/p///MeUZG7YsKHY/QIAcCuOBAEAQLK67kRmZqYuXLigmJgYhYWFWY7ykKSwsDAdOnRIP/30U75txcXF6ezZs9q+fbtl2Zo1axQYGKg+ffpYrRscHGz1P/t+fn5q1aqV1d1Y3n//fYWHh+vJJ5/M1Vd+d2GRpNTUVElSSEhIvuvkZfjw4YqIiFDVqlXVtWtXy+kVOdfgsMXBgwd1+vRpde3a1SpfcHBwrnWHDBmiiIgIy5/JkyfnWqdjx46KiIhQ9erVNWDAAAUHB2v9+vVWR9k4StWqVfXwww9bHoeGhiouLk4JCQk6d+5csdoKCwuTJH300UdWRzbcLDY2VnfddZfV0UQXL17UJ598okGDBhX4mtuiYcOGat26teXxXXfdJenGKUY1atTItTxnbl68eFHbtm1Tv379lJaWpt9//12///67Lly4oM6dO+unn36ynPpVHP3791eFChUsj9u2bVsi/QIAPANFEAAAdOP6GS+++KKqV68uf39/hYeHKyIiQsnJyUpJSbGsN3PmTCUnJys2NlZNmjTRpEmT9N1331m19eCDD6pKlSqWH7HZ2dl655131LNnz1wFiWrVquX6UVuhQgVdunTJ8vj48eOqV69erguYFiY0NFSSlJaWVqztXnzxRW3dulXbtm3Td999p7Nnz2rIkCHFauNWH3/8sSpXrmxVSAkJCdEff/yRa92ZM2dq69atBZ5usnTpUm3dulXbt2/X4cOHdeLECXXu3LlYmYpaTIiJicm1bmxsrCTlumZMYe677z716dNHM2bMUHh4uHr27KkVK1YoPT3dar24uDjt3LlTp06dkiStXbtWmZmZdr8Oebm50CFJ5cuXlyRVr149z+U5c/PYsWMyTVMvvPCCVdEqIiJC06ZNk3Tj9B978+QURJzdLwDAM3B3GAAAJD355JNasWKFnn76abVu3Vrly5eXYRgaMGCA1TUQ2rVrp+PHj+s///mPtmzZotdff13/+Mc/9Morr2jkyJGSbtyF489//rP+9a9/6eWXX9bOnTt19uzZPK/lkN+1OkzTtHtMORcb/f7773PdLrUgTZo0UceOHfN9PiAgQNKNwlFerly5Ylknx8aNG/WnP/3JqphQv359ffvtt8rMzLS6U8jtt99eaMZWrVoVeGSKLRntkV9BJSsrK9d669at09dff60NGzZo8+bNGj58uObPn6+vv/7acmTMgAEDNH78eK1Zs0bPPfecVq9erRYtWqhevXoOy5wjvzlY2NzMeV8888wz+RagYmJiHJbH2f0CADwDRRAAACStW7dOQ4cO1fz58y3Lrl27puTk5FzrVqxYUY8++qgeffRR/fHHH2rXrp2mT59uKYJIN/4nf/78+dqwYYM++eQTRUREFPtIhRx16tTRN998k6tYUJh7771XFSpU0DvvvKPnnnvOYbdHrVmzpiTphx9+yPP5H374wbKOJCUnJ2vXrl0aO3as1XrdunXT119/rfXr16tfv34OyZZXxpzTKW72448/qnHjxkVqK+fIg5sLHT/++KMkWe5uknO0QnJysuWUF0mWIzludffdd+vuu+/WSy+9pLfffluDBg3Su+++a5lDFStWVNeuXbVmzRoNGjRIO3fu1MKFC4uU19Gny+Sndu3akm7c6ragollZ6RcAUDZwOgwAALrxv8+3Hn2xePHiXP+Tf+HCBavHwcHBiomJyXU6w+23367bb79dr7/+ut5//30NGDCg2Kez5OjTp49+//13LVmyJNdzBR0xUq5cOU2ePFlHjhzR5MmT81x39erV2r17d7HyVKlSRc2aNdPq1atzFYn27dunr7/+2nIbXOnG7WUlqVOnTlbr/t///Z8qV66s8ePHW4oKN7PnaJjmzZsrMjJSr7/+eq7X5sMPP9Svv/5qlbEgZ8+etbrjSGpqqlatWqVmzZopKipK0o1ClST973//s6yXcy2Vm126dCnXuJo1ayZJuXIOGTJEhw8f1qRJk+Tt7a0BAwYUKW9QUFCexTtHi4yM1P33369XX31ViYmJuZ4/f/58meoXAFA2cCQIAAC6cVTCW2+9pfLly6thw4b66quv9Omnn+a65WrDhg11//33q3nz5qpYsaL27t2rdevW5TrKQbpxNMgzzzwjSQXe1rQwcXFxWrVqlSZMmKDdu3erbdu2unz5sj799FONHj1aPXv2zHfbSZMm6dChQ5o/f762b9+uvn37KioqSufOndOHH36o3bt3a9euXcXOtGDBAnXu3FnNmjXTsGHDVLVqVR05ckSvvfaaqlSpoqlTp1rW/fjjj3XvvfdarimRo2LFilq/fr26d++upk2basCAAWrZsqV8fX31yy+/aO3atZJyXyOiKPz8/PT3v/9dQ4cOVcuWLdW/f39VqlRJCQkJWr58uW6//XY9/vjjRWorNjZWI0aM0J49e1S5cmUtX75cv/32m1asWGFZp1OnTqpRo4ZGjBhhKVosX75cEREROn36tGW9N998Uy+//LIefvhh1alTR2lpafrXv/6l0NBQPfTQQ1b9du3aVZUqVdLatWvVpUsXRUZGFilv8+bN9emnn2rBggWqWrWqatWqZbmoqaMtXbpU9957r5o0aaLHHntMtWvX1m+//aavvvpKZ86c0bffflum+gUAlAEuuisNAABu5dKlS+ajjz5qhoeHm8HBwWbnzp3No0ePmjVr1rS63ejf/vY3s1WrVmZYWJgZGBho1q9f33zppZfMjIyMXG0mJiaa3t7eZmxsbJ593nfffWajRo1yLb/11qGmeeMWvs8//7xZq1Yt09fX14yKijL79u1rHj9+vEjjW7dundmpUyezYsWKpo+Pj1mlShWzf//+5o4dOyzrFHbr21t9/fXXZrdu3cwKFSqYPj4+5m233WaOHDnScpta07xx29LIyEhz7ty5+baTmJhoTpo0yWzYsKEZGBho+vv7m7Vr1zbj4uLM//3vf1brFnbr21t98sknZvv27c3Q0FDT19fXrFWrljlhwgTz0qVLRdq+Zs2aZteuXc3Nmzebt99+u+nv72/Wr18/z320b98+86677jL9/PzMGjVqmAsWLMh1W9r9+/ebAwcONGvUqGH6+/ubkZGRZrdu3cy9e/fm2f/o0aNNSebbb79dpLymaZpHjx4127VrZwYGBpqSLPM3v1vk5nXLZ0nmmDFjrJbl3MJ23rx5VsuPHz9uxsXFmVFRUaav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rVurVq1akor/Hi+KY8eOqW/fvhoxYoSGDh2q5cuXa9iwYWrevLkaNWrktH4BACXEBADATYwYMcKsUqWK+fvvv1stHzBggFm+fHnzypUrpmma5quvvmpKMr///nur9Ro2bGh26NDB8vivf/2rGRQUZP74449W602ZMsX09vY2T58+bZqmaf7888+mJLNSpUrmxYsXLev95z//MSWZGzZssCwbM2aMaes/n/fdd58pyZw/f75lWXp6utmsWTMzMjLSzMjIME3TNK9fv26mp6dbbXvp0iWzcuXK5vDhwy3LcnKHhoaaSUlJVutPmzbNlGQOHDgwV46c53KcPHnS9Pb2Nl966SWr9b7//nvTx8fHannOGF555ZVCx/vtt9+aksxx48YVum4OSeaIESPM8+fPm0lJSeY333xjPvDAA7n2myRzzJgxebaxdu1aU5K5fft2q+VDhgwx77vvPsvjhx9+2JRkJicnW6139epV8/z585Y/ly5dsjyXs89nzJhhnj9/3jx37py5Y8cO84477jAlme+//77VevPmzcsz47x580xJ5s8//1zg/hg6dKgpyXzyyScty7Kzs82uXbuafn5+5vnz503TNM3t27fnOeacHCtWrDBN88Y8KiiXaZpmVlaWWa1aNbN///5WyxcsWGAahmGeOHGiwMxdu3Y1a9asmWv5rVluHt+sWbMsyy5dumQGBgaahmGY7777rmX50aNHTUnmtGnTLMuK+h43TTPXtitWrMj1GtSsWdOUZP7vf/+zLEtKSjL9/f3NiRMn2tQvAMC9cDoMAMAtmKap999/X927d5dpmvr9998tfzp37qyUlBTt379fktS7d2/5+Pjovffes2x/8OBBHT58WP3797csW7t2rdq2basKFSpYtdexY0dlZWXpf//7n1WG/v37q0KFCpbHbdu2lXTjVARH8fHx0ahRoyyP/fz8NGrUKCUlJWnfvn2SblyrIOeaHtnZ2bp48aKuX7+uFi1aWPbBzfr06aOIiIg8+3viiScKzfTBBx8oOztb/fr1s9pPUVFRqlu3bq7TcPz9/fXoo48W2m5qaqok5XkaTEHeeOMNRUREKDIyUnfddZd27typCRMm6Omnny5WOzfLzs7Wpk2bLKfC3Jzv1iMVXnnlFUVERFj+5JxGdLNp06YpIiJCUVFRuv/++3X8+HHNmTMn39Nq7HXznXByjpTKyMjQp59+Wqx2AgMD5efnpx07dujSpUt5ruPl5aVBgwbpv//9r9LS0izL16xZo/+vvfuOjqrO/z/+uumdUBJCFkyAJIQuXbBSBBVZAiplcQMIwlmChaq4q4IFggrLosiKBXBRURRUEOmCrg0IiQILSAuIBoNgaAECmfv7w1/my6QnM5mZOM/HOZzD3PL5vO6dz8wk79z53C5dulivwnCkkSNHWv8fHh6uJk2aKDg4WAMGDLAub9KkicLDw21ejxV9jZdHs2bNrK99SYqIiFCTJk2qvF8AgHPwdRgAgFs4ceKEcnJytGDBAi1YsKDYbbKzsyVJderUUffu3fXee+/p6aeflvT7V2F8fHxsfgndv3+/vv/++xILBAXtFSj8lY2CgkhJvyxWRnR0tIKDg22WJSQkSPp9zoTrrrtOkrR48WLNmjVLe/futZmbobhfQEv7pbQ8v7Du379fpmkqPj6+2PW+vr42j//0pz8VO/FqYWFhYZJk84t0efTt21djx46VYRgKDQ1V8+bNi5yz8rh63pNt27bpxIkTNkWQguLMuXPnVKNGDevyu+66Sy1atJAkTZgwweYWuQVGjRqle+65R15eXgoPD1fz5s3l7+9vV8aSeHl5qVGjRjbLrh4zFeHv76+ZM2dqwoQJqlu3rq677jrdeeedSk5OVlRUlHW75ORkzZw5UytWrFBycrL27duntLS0IvPXOEJAQECR12iNGjVUv379IuenRo0aNq/Hir7Gy6O4r27VrFmzyvsFADgHRRAAgFsomEzw3nvv1dChQ4vdplWrVtb/Dxo0SMOHD1dGRoauvfZavffee+revbvq1Klj0+att96qyZMnF9tewS+SBUq6U4RZylwaVWHJkiUaNmyYkpKSNGnSJEVGRsrb21szZsywzj1xtcDAwBLbKm1dAYvFIsMw9OmnnxZ7DgpfKVGeNiUpLi5OPj4+2rlzZ7m2L1C/fn316NGj1G38/f1LvM1vbm6uJNnciWT16tWKjY1Vs2bNrMsSExMl/X4V0fXXX29d3qBBAzVo0ECSrH/pLyw+Pr7UjAV9VySjPUoqphRXwHn44YfVp08fffjhh1q7dq0ef/xxzZgxQ5s2bVKbNm0k/X41RLt27bRkyRIlJydryZIl8vPzs7kyw1FKet2V5/VY0de4PXmqul8AgHNQBAEAuIWIiAiFhoYqPz+/zF+AJSkpKUmjR4+2fiXmhx9+0JQpU2y2ady4sc6dO1eu9sqrMneDudrPP/9svVVtgR9++EGSrHfReP/999WoUSMtX77cpr/SJqS0R+PGjWWapho2bOjQX96CgoLUrVs3bdq0ST/++KO1sOAIMTExxd66VpJ1eUxMjHXZJ598ojvuuMNmuzvvvFOpqal66623bIogjhAREaGgoKBSMwYFBdkU7UpisVh06NAhm+em8JgpuGopJyfHZt8jR44U22bjxo01YcIETZgwQfv379e1116rWbNmacmSJdZtkpOTNX78eGVlZentt99W7969bb4uVhJ7XyMVURWvcXfuFwBgP+YEAQC4BW9vb91111364IMPtGvXriLrT5w4YfM4PDxcvXr10nvvvaelS5fKz89PSUlJNtsMGDDAehvUwnJycnTlypUK5ywoXhT+ZbO8rly5oldeecX6OC8vT6+88ooiIiLUrl07Sf/3l+ir//L87bff6uuvv65Un2Xp37+/vL29NW3atCJXvZimqZMnT1a67SeffFKmaeqvf/2rzp07V2R9WlqaFi9eXOF277jjDn3zzTfWeVQK5OTk6K233tK1115r/XrHL7/8oh07dth8FUaSrr/+et16661asGCBPvroo2L7qexVQN7e3urZs6dWrlypo0eP2qw7evSoVq5cqZ49e5Z41UFhV9/22TRNvfTSS/L19VX37t0l/V7w8fb2LjIXxcsvv2zzODc3VxcvXrRZ1rhxY4WGhurSpUs2ywcPHizDMPTQQw/p0KFD5b6LTnBwsE6fPl2ube1VFa9xd+4XAGA/rgQBALiN1NRUffbZZ+rUqZPuv/9+NWvWTKdOndKOHTu0YcMGnTp1ymb7gQMH6t5779XLL7+sXr162dzGVZImTZqkjz/+WHfeeaf1Fpfnz5/Xzp079f777yszM7Ncf4m/WkGh4sEHH1SvXr3k7e2tQYMGlXv/6OhozZw5U5mZmUpISNC7776rjIwMLViwwDr3xp133qnly5erX79+6t27tw4fPqx///vfatasWbGFBHs1btxYzzzzjKZMmaLMzEwlJSUpNDRUhw8f1ooVKzRq1ChNnDixUm136dJF8+bN05gxY5SYmKi//vWvio+P19mzZ7V582Z9/PHHeuaZZyrc7qOPPqply5bppptu0ujRo5WYmKiff/5ZixYtUlZWlhYuXGjddvXq1QoICFDXrl2LtLNkyRLddtttSkpK0u23364ePXqoZs2aOn78uDZs2KDPP/9ct99+e6WOffr06bruuuvUtm1bjRo1SrGxscrMzNSCBQtkGIamT59ernYCAgK0Zs0aDR06VJ06ddKnn36qTz75RI899ph1TooaNWronnvu0YsvvijDMNS4cWOtWrWqyNwUP/zwg7p3764BAwaoWbNm8vHx0YoVK/TLL78UGccRERG67bbbtGzZMoWHhxcpIpWkXbt2evfddzV+/Hh16NBBISEh6tOnT7n2raiqeI27c78AAAdwyT1pAAAowS+//GKmpKSYDRo0MH19fc2oqCize/fu5oIFC4pse+bMGTMwMNCUZC5ZsqTY9s6ePWtOmTLFjIuLM/38/Mw6deqYXbp0MV944QXrLWlLu52pCt1W88qVK+YDDzxgRkREmIZhVOh2uTfffLPZvHlzc/v27Wbnzp3NgIAAMyYmxnzppZdstrNYLOb06dPNmJgY09/f32zTpo25atUqc+jQoTa3Hi0td8FtcAtuoVrcusI++OAD84YbbjCDg4PN4OBgMzEx0UxJSTH37dtX5BgqKi0tzfzLX/5iRkdHm76+vmbNmjXN7t27m4sXLzbz8/Ot26mUW98WduzYMXPkyJHmn/70J9PHx8esVauWeeedd5rffPONzXZ33323eccdd5TYzoULF8w5c+aYnTt3NsPCwkwfHx8zKirKvPPOO8233nrLvHLlinXbsm59W9iePXvMgQMHmpGRkaaPj48ZGRlpDho0yNyzZ0+59h86dKgZHBxsHjx40OzZs6cZFBRk1q1b13zyySdtzptpmuaJEyfMu+66ywwKCjJr1qxpjh492ty1a5fNbWl//fVXMyUlxUxMTDSDg4PNGjVqmJ06dTLfe++9Yvt/7733TEnmqFGjypXXNE3z3Llz5l/+8hczPDzclGQdsyXdIjc4OLhIGyWNs5iYGLN37942y8rzGjfN8t8it3D7BXmuvr1yRfoFALgXwzSdPNsbAACAk1y5ckW1a9fWjBkzNGbMGFfHqXY++ugjJSUl6fPPP7e5bSwAANUVc4IAAIA/rFOnTmncuHHq16+fq6NUS6+++qoaNWqkG264wdVRAABwCOYEAQDATqdOnVJeXl6J6729va1zN8C5IiMjNXXqVFfHqHaWLl2q77//Xp988on+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qampSk1NVevWrfXf//5XH3/8serUqSPp9ytWlixZotWrV6tly5Z65513NHXqVOu+3t7eOnnypJKTk5WQkKABAwbo9ttv17Rp02z6GDFihPLy8qp8QtQCPk7pBQAAAAAANxHi7/6/CterV08vvfSSXnrppRK3yczMLLOdhIQELV++vEJ9x8bGWuf7GDx4cInbJSUlKSkpyWbZ/fffL0ny8/PTO++8U2ZfP/30k2rXrq2+fftWKGNluf8zDwAAAACAA+2a1svVETxebm6usrKylJqaqtGjR8vPz88p/fJ1GAAAAAAA4FTPPfecEhMTFRUVpSlTpjitX4ogAAAAAADAqaZOnarLly9r48aNCgkJcVq/FEEAAAAAAIBHoAgCAAAAAAA8AkUQAAAAAADgESiCAAAAAAAAj8AtcgEAAAAAnmV6fef299gx5/aHElEEAQAAAAB4lryzrk4AF+HrMAAAAAAAwEZmZqYMw1BGRoarozgURRAAAAAAANzM8ePH9dBDDykuLk4BAQGqW7eurr/+es2fP1+5ubnW7WJjY2UYhgzDUHBwsNq2batly5ZZ1w8bNkxJSUlF2t+8ebMMw1BOTo4TjsZ9UAQBAAAAAMCNHDp0SG3atNG6des0ffp0paen6+uvv9bkyZO1atUqbdiwwWb7p556SllZWUpPT1eHDh00cOBAffXVVy5K794oggAAAAAA4EbGjBkjHx8fbd++XQMGDFDTpk3VqFEj9e3bV5988on69Oljs31oaKiioqKUkJCgefPmKTAwUCtXrnRIlr1796pLly4KCAhQixYttGXLFuu6RYsWKTw83Gb7Dz/8UIZhWB9/99136tq1q0JDQxUWFqZ27dpp+/btOn/+vMLCwvT+++8X2T84OFhnz1bNvC0UQQAAAAAAcBMnT57UunXrlJKSouDg4GK3ubrIUJiPj498fX2Vl5fnkDyTJk3ShAkTlJ6ers6dO6tPnz46efJkufcfMmSI6tevr23btiktLU2PPvqofH19FRwcrEGDBmnhwoU22y9cuFB33323QkNDHZK/MIogAAAAAAC4iQMHDsg0TTVp0sRmeZ06dRQSEqKQkBA98sgjxe6bl5enGTNm6PTp0+rWrZtD8owdO1Z33XWXmjZtqvnz56tGjRp6/fXXy73/0aNH1aNHDyUmJio+Pl733HOPWrduLUkaOXKk1q5d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hKhDhw7asGGDTbtZWVnq3bu3AgMD1bBhQ7399ttFznVOTo5GjhypiIgIhYWFqVu3bvruu+9KPFdVlbW4c9uwYUNJUps2bWQYhm655ZZiM5U0rteuXaumTZsqJCREt912m7Kysko8LknatWuXbr/9doWEhKhu3br661//ql9//dW6fs2aNbrhhhsUHh6u2rVr684777QZc5J07NgxDR48WLVq1VJwcLDat2+vb7/91mab//znP4qNjVWNGjU0aNAgnT17tsRMBcfy8ccfq1mzZvL399fRo0eLvdIrKSlJw4YNszmn06dP13333afQ0FBdc801WrBgQannYPXq1fL399d1111nXfbbb79pyJAhioiIUGBgoOLj47Vw4ULr+ubNmys6OlorVqwotW0AQPVBEQQAUK3861//UufOnXX//fcrKytLWVlZatCgQbHb5ubmau7cuVq6dKnWrFmjzZs3q1+/flq9erVWr16t//znP3rllVf0/vvvW/cZO3asvv76ay1dulTff/+97rnnHt12223av39/sX188MEH+uc//6lXXnlF+/fv14cffqiWLVuWegzTpk3TgAED9P333+uOO+7QkCFDrH9p/umnn3TTTTfJ399fmzZtUlpamu677z5duXJFkvTWW2/piSee0LPPPqs9e/Zo+vTpevzxx7V48eISz9dTTz2l+vXrKysrS9u2bSsx1wsvvKDWrVsrPT1djz/+uObOnauPP/5Y7733nvbt26e33nrL+st/QTsLFy4std3KtHHu3Dndcccd2rhxo9LT03XbbbepT58+Onr0qLXd5ORk/fzzz9q8ebM++OADLViwQNnZ2TZ933PPPcrOztann36qtLQ0tW3bVt27dy/xr/pVlbW4c7t161ZJ0oYNG5SVlaXly5eX+LwUlpubqxdeeEH/+c9/9Pnnn+vo0aOaOHFiidvn5OSoW7duatOmjbZv3641a9bol19+0YABA6zbnD9/XuPHj9f27du1ceNGeXl5qV+/ftYrM86dO6ebb75ZP/30kz7++GN99913mjx5ss2VGwcPHtSHH36oVatWadWqVdqyZYtSU1PLPJaZM2fqtdde0+7duxUZGVnu8zBr1iy1b99e6enpGjNmjP72t79p3759JW7/xRdfqF27djbLHn/8cf3vf//Tp59+qj179mj+/PmqU6eOzTYdO3bUF198Ue5cAAA3ZwIAUM3cfPPN5kMPPWSz7LPPPjMlmb/99ptpmqa5cOFCU5J54MAB6zajR482g4KCzLNnz1qX9erVyxw9erRpmqZ55MgR09vb2/zpp59s2u7evbs5ZcqUYrPMmjXLTEhIMPPy8opdHxMTY/7zn/+0PpZk/uMf/7A+PnfunCnJ/PTTT03TNM0pU6aYDRs2LLG9xo0bm2+//bbNsqefftrs3Llzsdubpmn+85//NGNiYmyWFT6HMTExZlJSks02DzzwgNmtWzfTYrEU264kc8WKFSX266g2TNM0mzdvbr744oumaZrmnj17TEnmtm3brOv3799vSrKe6y+++MIMCwszL168aNNO48aNzVdeecVpWU2z+HN7+PBhU5KZnp5ealvlGdfz5s0z69atW2IbTz/9tNmzZ0+bZT/++KMpydy3b1+x+5w4ccKUZO7cudM0TdN85ZVXzNDQUPPkyZPFbv/kk0+aQUFB5pkzZ6zLJk2aZHbq1KnEXAXHkpGRYbO8uNd33759zaFDh1ofx8TEmPfee6/1scViMSMjI8358+eX2F/fvn3N++67z2ZZnz59zOHDh5e4j2ma5rhx48xbbrml1G0AANUHV4IAAP6wgoKC1LhxY+vjunXrKjY2ViEhITbLCq4g2Llzp/Lz85WQkKCQkBDrvy1bthT5akCBe+65RxcuXFCjRo10//33a8WKFdarNkrSqlUr6/+Dg4MVFhZmzZCRkaEbb7xRvr6+RfY7f/68Dh48qBEjRtjke+aZZ0rMVxHt27e3eTxs2DBlZGSoSZMmevDBB7Vu3boKt1mZNs6dO6eJEyeqadOmCg8PV0hIiPbs2WO9umLfvn3y8fFR27ZtrfvExcWpZs2a1sffffedzp07p9q1a9ucq8OHD5d4rqoia4HC59Yehcd1vXr1ilwFc7XvvvtOn332mc15SExMlCTrudi/f78GDx6sRo0aKSwszHoFTMFxZGRkqE2bNqpVq1aJ/cTGxtrMM1NWLun3OU+ufj1UxNX7GYahqKioUvu7cOGCAgICbJb97W9/09KlS3Xttddq8uTJ+uqrr4rsFxgYqNzc3EplBAC4Hx9XBwAAoKoULiQYhlHssqsv+ff29lZaWpq8vb1ttru6cHK1Bg0aaN++fdqwYYPWr1+vMWPG6Pnnn9eWLVuKLWSUlKsgQ2BgYInHc+7cOUnSq6++qk6dOtmsK5y3MoKDg20et23bVocPH9ann36qDRs2aMCAAerRo4fN14fKUpk2Jk6cqPXr1+uFF15QXFycAgMDdffdd1doQtFz586pXr16xc7nEh4e7vSshc+tPYobP6Zplrj9uXPn1KdPH82cObPIunr16kmS+vTpo5iYGL366quKjo6WxWJRixYtrMdR2rgsLVdZE50GBgYWmfTVy8uryPFcvnzZ7v7q1Kmj3377zWbZ7bffriNHjmj16tVav369unfvrpSUFL3wwgvWbU6dOqWIiIhSjwMAUH1QBAEAVDt+fn42k5k6Sps2bZSfn6/s7GzdeOON5d4vMDBQffr0UZ8+fZSSkqLExETt3LnT5kqF8mrVqpUWL16sy5cvF/klr27duoqOjtahQ4c0ZMiQCrddGWFhYRo4cKAGDhyou+++W7fddptOnTqlWrVqydfXt1zPQ0Xb+PLLLzVs2DD169dP0u+/xGdmZlrXN2nSRFeuXFF6erp1jocDBw7Y/ILbtm1bHT9+XD4+PuW6HWpVZS2Jn5+fJFXJOC6sbdu2+uCDDxQbGysfn6I/+p08eVL79u3Tq6++ah33//3vf222adWqlV577TXruahKERERNhO95ufna9euXeratatd7bZp00ZLliwptr+hQ4dq6NChuvHGGzVp0iSbIsiuXbtKnLgWAFD98HUYAEC1Exsbq2+//VaZmZn69ddfHXZbzYSEBA0ZMkTJyclavny5Dh8+rK1bt2rGjBn65JNPit1n0aJFev3117Vr1y4dOnRIS5YsUWBgoGJiYiqVYezYsTpz5owGDRqk7du3a//+/frPf/5jnfBx2rRpmjFjhubOnasffvhBO3fu1MKFCzV79uxKH3dJZs+erXfeeUd79+7VDz/8oGXLlikqKsp6JUVsbKw2btyo48ePF/kLuz1txMfHa/ny5crIyNB3332nv/zlLzbPcWJionr06KFRo0Zp69atSk9P16hRo2yuKujRo4c6d+6spKQkrVu3TpmZmfrqq6/097//Xdu3b3da1pJERkYqMDDQOknp6dOny9ynslJSUnTq1CkNHjxY27Zt08GDB7V27VoNHz5c+fn5qlmzpmrXrq0FCxbowIED2rRpk8aPH2/TxuDBgxUVFaWkpCR9+eWXOnTokD744AN9/fXXDs/brVs3ffLJJ/rkk0+0d+9e/e1vf7PeHccevXr10u7du23G6hNPPKGPPvpIBw4c0O7du7Vq1So1bdrUuj43N1dpaWnq2bOn3f0DANwDRRAAQLUzceJEeXt7q1mzZoqIiCgy/4I9Fi5cqOTkZE2YMEFNmjRRUlKStm3bpmuuuabY7cPDw/Xqq6/q+uuvV6tWrbRhwwatXLlStWvXrlT/tWvX1qZNm6x342jXrp1effVV61UhI0eO1GuvvaaFCxeqZcuWuvnmm7Vo0SLrLVcdKTQ0VM8995zat2+vDh06KDMzU6tXr5aX1+8/PsyaNUvr169XgwYN1KZNG4e1MXv2bNWsWVNdunRRnz591KtXryJX1bz55puqW7eubrrpJvXr10/333+/QkNDrXM+GIah1atX66abbtLw4cOVkJCgQYMG6ciRI6pbt65TsxbHx8dHc+fO1SuvvKLo6Gj17du3zH0qKzo6Wl9++aXy8/PVs2dPtWzZUg8//LDCw8Pl5eUlLy8vLV26VGlpaWrRooXGjRun559/3qYNPz8/rVu3TpGRkbrjjjvUsmVLpaamOuRrWIXdd999Gjp0qJKTk3XzzTerUaNGdl8FIkktW7ZU27Zt9d5771mX+fn5acqUKWrVqpVuuukmeXt7a+nSpdb1H330ka655poKXRkGAHBvhlnal0gBAACqgWPHjqlBgwbasGGDunfv7uo4cFOffPKJJk2apF27dlmLW6W57rrr9OCDD+ovf/mLE9IBAJyBOUEAAEC1U3C1TMuWLZWVlaXJkycrNjZWN910k6ujwY317t1b+/fv108//aQGDRqUuu2vv/6q/v37a/DgwU5KBwBwBq4EAQAA1c7atWs1YcIEHTp0SKGhoerSpYvmzJlT6blYAACAZ6AIAgAAAAAAPAITowIAAAAAAI9AEQQAAAAAAHgEiiAAAAAAAMAjUAQBAAAAAAAegSIIAAAAAADwCBRBAAAAAACAR6AIAgAAAAAAPAJFEAAAAAAA4BH+H43Vn/8L3f2AAAAAAElFTkSuQmCC", "text/plain": [ "
" ] @@ -544,17 +536,9 @@ ], "source": [ "#fig, axes, run_timelines = plot_run_timeline(df, [\"mode_async\", \"mode_blocking\"])\n", - "fig, axes, run_timelines = plot_run_timeline(df, [\"async\", \"event_barrier\", \"blocking\"])\n", + "fig, axes, run_timelines = plot_run_timeline(df, [\"blocking\", \"async\", \"event_barrier\"])\n", "# fig, ax, run_timeline = plot_run_timeline(df, \"mode_async\")" ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "80a5dc64-90d2-4bfa-8a20-b78085b34c5d", - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { From b00f28ab9aa00115a192b7d5d0738ccd61c92259 Mon Sep 17 00:00:00 2001 From: Dmitri Smirnov Date: Fri, 24 Jul 2026 09:33:32 -0400 Subject: [PATCH 5/5] docs: add figures --- docs/figures/adaptive-dispatch-event-loop.svg | 737 +++++++++++++++++ docs/figures/event_timeline.svg | 745 ++++++++++++++++++ docs/figures/event_timeline.typ | 168 ++++ 3 files changed, 1650 insertions(+) create mode 100644 docs/figures/adaptive-dispatch-event-loop.svg create mode 100644 docs/figures/event_timeline.svg create mode 100644 docs/figures/event_timeline.typ diff --git a/docs/figures/adaptive-dispatch-event-loop.svg b/docs/figures/adaptive-dispatch-event-loop.svg new file mode 100644 index 0000000..156ac76 --- /dev/null +++ b/docs/figures/adaptive-dispatch-event-loop.svg @@ -0,0 +1,737 @@ + + + + + + + + Planned per-basket CPU/GPU dispatch pipeline showing decision-time posterior inference and completion-time parameter updates. + image/svg+xml + + + Teerex adaptive-dispatch architecture renderer + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Planned adaptive dispatch: one basket from prediction to learning + + + Time and causality flow left to right; neighboring events may overlap. + + + earlier completion + + + basket ready + + + payload complete + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Blue and orange execution lanes match the CPU/GPU timeline colors in notebooks/simload.ipynb. + + + Earlier event or payload + valid completion + + + Event e: CPU work emits + eligible basket i + + + Event e+1 or another worker + may emit the next basket + + + Merge payload result + into event e + + + Current posterior states + CPU service · GPU compute + H2D/D2H · peak memory + model version v + + + Scheduling point d + freeze decision context x + and log the model version + + + Posterior predictive inference + CPU service · GPU compute + H2D/D2H · peak memory + (read-only model use) + + + Controller + eligibility + safety filters + queue-aware finish time / exploration + + + Dispatch + Decision + + + Fresh ResourceSnapshot + queues · in-flight work + free memory · oldest-event age + + + CPU worker queue → + equivalent CPU implementation + + + GPU j FIFO queue → H2D → + compute → D2H + + + Accumulate + hold until a required trigger + + + Static safe fallback + routes to CPU or GPU + + + DispatchOutcome + selected-backend timing, + transfer, and memory + + + Validate + classify measurement → observe() + update applicable parameters after valid payload completion + + + + + + validate, then observe() + + + + + + CPU + + + + + + GPU j + + + + + + accumulate + + + + + + fallback + + + + + + payload result + + + + + + valid completion only + + + + + + commit model version v + 1 + for later scheduling points + + + + + + compatible arrival · max age/deadline · useful capacity release + + + + + + same pipeline; uses the latest committed version at its snapshot + + + + + + admission changes queue / in-flight state, + not model parameters + + + + + + + + + diff --git a/docs/figures/event_timeline.svg b/docs/figures/event_timeline.svg new file mode 100644 index 0000000..c994907 --- /dev/null +++ b/docs/figures/event_timeline.svg @@ -0,0 +1,745 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/figures/event_timeline.typ b/docs/figures/event_timeline.typ new file mode 100644 index 0000000..d65675c --- /dev/null +++ b/docs/figures/event_timeline.typ @@ -0,0 +1,168 @@ +#import "@preview/cetz:0.4.2": canvas, draw + +#set page(width: auto, height: auto, margin: 6pt, fill: rgb("#FFFFFF")) +#set text(font: "DejaVu Sans Mono") + +#let ink = rgb("#0B1F33") +#let muted = rgb("#526579") +#let navy = rgb("#19324D") +#let lane-fill = rgb("#EEF3F7") +#let lane-rule = rgb("#B8C4D0") +#let cpu-fill = rgb("#A9D8F5") +#let cpu-border = rgb("#1E78B4") +#let gpu-fill = rgb("#FFAD33") +#let gpu-border = rgb("#C86500") +#let integration-fill = rgb("#B7EFC5") +#let integration-border = rgb("#168044") +#let boundary = rgb("#2457D6") + +#canvas({ + import draw: * + + let lane(y0, y1, label) = { + rect( + (0.3, y0), + (27.7, y1), + fill: lane-fill, + stroke: (paint: lane-rule, thickness: 0.7pt), + radius: 0.18, + ) + rect( + (0.3, y0), + (4.2, y1), + fill: navy, + stroke: none, + radius: (west: 0.18, rest: 0), + ) + content( + (2.25, (y0 + y1) / 2), + align(center, text(size: 11.5pt, weight: "bold", fill: white)[#label]), + ) + } + + let phase( + x0, + x1, + y0, + y1, + fill-color, + border-color, + label, + text-size: 11pt, + ) = { + rect( + (x0, y0), + (x1, y1), + fill: fill-color, + stroke: (paint: border-color, thickness: 1.25pt), + radius: 0.18, + ) + content( + ((x0 + x1) / 2, (y0 + y1) / 2), + align(center, text(size: text-size, weight: "bold", fill: ink)[#label]), + ) + } + + // Title and qualitative time axis. + content( + (14.0, 8.0), + text(size: 17pt, weight: "bold", fill: ink)[General CPU/GPU event phases], + ) + line( + (4.35, 6.15), + (27.75, 6.15), + stroke: (paint: muted, thickness: 1.1pt), + mark: (end: ">"), + ) + content( + (16.0, 6.5), + text(size: 9.5pt, weight: "semibold", fill: muted)[relative time / phase order], + ) + + // Worker lanes. + lane(3.55, 5.2, [CPU event-worker #linebreak() lane]) + lane(1.55, 3.2, [GPU worker #linebreak() lane]) + + // Event boundaries. These delimit one event but do not define a clock scale. + line( + (4.35, 0.95), + (4.35, 6.85), + stroke: (paint: boundary, thickness: 2pt), + ) + line( + (27.25, 0.95), + (27.25, 6.85), + stroke: (paint: boundary, thickness: 2pt), + ) + content( + (4.35, 7.05), + text(size: 10pt, weight: "bold", fill: boundary)[EVENT START], + ) + content( + (27.25, 7.05), + text(size: 10pt, weight: "bold", fill: boundary)[EVENT COMPLETE], + ) + + // Phase bars. Both CPU phases intentionally share one vertical level. + phase( + 4.55, + 12.95, + 3.82, + 4.93, + cpu-fill, + cpu-border, + [Basket-forming CPU phase], + ) + phase( + 12.95, + 20.15, + 1.82, + 2.93, + gpu-fill, + gpu-border, + [GPU basket-processing phase], + ) + phase( + 20.15, + 23.65, + 3.82, + 4.93, + cpu-fill, + cpu-border, + [CPU continuation #linebreak() phase], + text-size: 10pt, + ) + phase( + 23.85, + 27.05, + 3.82, + 4.93, + integration-fill, + integration-border, + [Event #linebreak() integration], + text-size: 10pt, + ) + + // Submission and completion hand-offs in the blocking-style sequence. + line( + (12.95, 3.82), + (12.95, 2.93), + stroke: (paint: gpu-border, thickness: 1.1pt), + mark: (end: ">"), + ) + line( + (20.15, 2.93), + (20.15, 3.82), + stroke: (paint: cpu-border, thickness: 1.1pt), + mark: (end: ">"), + ) + + content( + (16.0, 0.55), + text( + size: 9.5pt, + style: "italic", + fill: muted, + )[Qualitative ordering only — horizontal widths do not encode durations.], + ) +})