From e4fad3175b69daf62f16041313739f2a885120ff Mon Sep 17 00:00:00 2001 From: "Shahneous Bari, Md Abdullah" Date: Fri, 15 May 2026 22:47:07 +0000 Subject: [PATCH] [Test][Integration] Add 4K and 1K OV FA tests with array_length. Add a performance report on BMG B580. --- .../Performance_report_flash_attention_fwd.md | 82 ++++ ...h_attention_fwd_ov_with_arrray_len_1k.mlir | 375 +++++++++++++++++ ...h_attention_fwd_ov_with_arrray_len_4k.mlir | 378 ++++++++++++++++++ .../Dialect/XeGPU/median_tflops.png | Bin 0 -> 120421 bytes 4 files changed, 835 insertions(+) create mode 100644 test/Integration/Dialect/XeGPU/Performance_report_flash_attention_fwd.md create mode 100644 test/Integration/Dialect/XeGPU/WG/flash_attention_fwd_ov_with_arrray_len_1k.mlir create mode 100644 test/Integration/Dialect/XeGPU/WG/flash_attention_fwd_ov_with_arrray_len_4k.mlir create mode 100644 test/Integration/Dialect/XeGPU/median_tflops.png diff --git a/test/Integration/Dialect/XeGPU/Performance_report_flash_attention_fwd.md b/test/Integration/Dialect/XeGPU/Performance_report_flash_attention_fwd.md new file mode 100644 index 000000000..db8d1e3b7 --- /dev/null +++ b/test/Integration/Dialect/XeGPU/Performance_report_flash_attention_fwd.md @@ -0,0 +1,82 @@ +# Flash Attention Performance study on BMG B580 + +**Workload:** Flash attention forward pass with 4K sequence length. + +### Machine-specific information: +----------------------------- +**Machine:** `BMG B580` + +**EU count:** `320` + +**L3 cache size:** `18874368 Byte (18 MB)` + + +### Workload-specific information: +----------------------------- +**Input range:** Random number between `-1.0` and `1.0` + +**Sequence length (N_CTX):** `4096` + +**D_HEAD:** `64` + +**ZxH:** `16` + +**Per-WG data:** `128x64` + + +Here we show the performance of Flash Attention FWD pass. We applied different optimizations to get to the peak TFLOPS (~65 TFLOPS). + +## Summary (sorted by peak TFLOPS) + +| Configuration | Min (ms) | Max TFLOPS | Max (ms) | Min TFLOPS | Median (ms) | Med TFLOPS | Speedup vs. baseline (peak) | +| --------------------------------------------- | ----------: | ---------: | -------: | ---------: | ----------: | ---------: | --------------------------: | +| No optimization | 3.38499 | 20.30 | 3.53527 | 19.44 | 3.45207 | 19.91 | 1.00x | +| Prefetch | 3.59164 | 19.13 | 3.74275 | 18.36 | 3.67276 | 18.71 | 0.94x | +| Prefetch + large load | 3.21131 | 21.40 | 3.25822 | 21.09 | 3.22556 | 21.30 | 1.05x | +| Prefetch + large load + tree reduction | 2.34510 | 29.30 | 2.40729 | 28.55 | 2.35352 | 29.20 | 1.44x | +| Prefetch + large load + tree reduction + exp2 | 1.09959 | 62.50 | 1.21368 | 56.62 | 1.16766 | 58.85 | 3.08x | +| + reduction intrinsics (without prefetch) | 1.08566 | 63.30 | 1.18102 | 58.19 | 1.13948 | 60.31 | 3.12x | +| + reduction intrinsics (with prefetch) | 1.09845 | 62.56 | 1.21503 | 56.56 | 1.16178 | 59.15 | 3.08x | +| + old SG-to-WI (without prefetch) | 1.08046 | 63.60 | 1.18321 | 58.08 | 1.13318 | 60.64 | 3.13x | +| + old SG-to-WI (with prefetch) | **1.05778** | **64.97** | 1.17510 | 58.48 | 1.12393 | 61.14 | **3.20x** | + + | + +## Median TFLOPS comparison + +![Median TFLOPS per configuration](median_tflops.png) + +## Optimization details + +Each optimization below is layered on top of the previous row in the summary table; the `+` rows inherit every preceding stage. + +- **Prefetch** — `xegpu.prefetch_nd` issued one `K`/`V` tile ahead of the matching `load_nd` with `l1/l2/l3 = cached` hints. Warms the cache for the next `scf.for` iteration so the consumer load hits in L1/L2 instead of waiting on DRAM. On its own it adds address-generation overhead and can evict reused tiles, which is why this row is slower than the no-opt baseline. +- **Large load** — widens `xegpu.load_nd` by using `array_length > 1` on the tensor descriptor so the same message fetches multiple adjacent 2-D blocks in one transaction. Cuts the number of load messages and header instructions per byte, making prefetch and load profitable. +- **Tree reduction** — lowers the softmax `max` and `sum` reductions from a linear shuffle chain (O(SG) serial dependency) to a log-depth tree using `xegpu.reduce` / subgroup shuffles. Shortens the critical path inside the flash-attention inner loop, which is reduction-heavy. +- **`exp2`** — rewrites the softmax `math.exp(x)` as `math.exp2(x · log2(e))` and folds the `log2(e) = 1.4427` factor into the pre-softmax scale constant (so `sm_scale_gpu = sm_scale · log2(e)`). Xe cores have a native `exp2` op; `exp` expands to a polynomial fall-back. This step alone roughly doubles end-to-end TFLOPS because `exp` sits on the critical path and is evaluated once per `(row, col)` of the attention matrix. We enable `exp2` by enabling `fastmath` on `math.exp`, which in turn gets converted to `math.exp2` multiplied by the factor by the `math-to-xevm pass`. +- **Reduction intrinsics** — lowers `vector.multi_reduction` onto dedicated subgroup reduction intrinsics instead of a software shuffle tree. Replaces multiple `xegpu.reduce` + shuffle sequences with a single hardware reduction, shaving ~1% and mostly improving consistency (tighter stddev). +- **Old SG-to-WI pass** — opts out of the new upstream subgroup-to-work-item distribution and uses the legacy path. For this kernel the old pass produces better register allocation / fewer spills, recovering another ~4% at peak and giving the fastest absolute run (1.058 ms). +- **"With prefetch" vs. "without prefetch" (final rows)** — toggles `xegpu.prefetch_nd` on top of the fully-optimized pipeline (tree reduction + exp2 + intrinsics + old SG-to-WI are always on). Once the load path is already saturated by wide loads and the reduction path by intrinsics, prefetch no longer helps and sometimes mildly hurts by adding address-gen work. + +## Key observations + +- **Prefetch alone hurts** (19.13 vs. 20.30 TFLOPS). It only pays off when paired with wider loads or tree reduction. +- **Tree reduction** is the first meaningful jump: 21.40 -> 29.30 TFLOPS (~1.37x on top of prefetch + large-load). +- **`exp2` is the single biggest win**: 29.30 -> 62.50 TFLOPS (~2.13x step-up). Using base-2 exp eliminates the `log(e)` scaling and maps directly to hardware `exp2` instructions. +- **Reduction intrinsics** add a small gain (~1%). Marginal on top of `exp2`. + - "with prefetch" / "without prefetch" refers to whether prefetch is enabled on top of the named optimization; all other stages (tree reduction, exp2, etc.) remain enabled. +- **Old SG-to-WI pass** gives another ~4% at peak and lands the fastest absolute result (1.058 ms). +- **Prefetch is neutral-to-slightly-hurtful once fully optimized.** In the final stages, disabling prefetch changes peak TFLOPS by <2% and sometimes lowers stddev (more consistent runs). +- **Peak measured: 64.97 TFLOPS** on BMG B580. diff --git a/test/Integration/Dialect/XeGPU/WG/flash_attention_fwd_ov_with_arrray_len_1k.mlir b/test/Integration/Dialect/XeGPU/WG/flash_attention_fwd_ov_with_arrray_len_1k.mlir new file mode 100644 index 000000000..967ca57a4 --- /dev/null +++ b/test/Integration/Dialect/XeGPU/WG/flash_attention_fwd_ov_with_arrray_len_1k.mlir @@ -0,0 +1,375 @@ +// RUN: imex-opt %s --gpu-lower-to-xevm-pipeline="xegpu-op-level=workgroup igc-cmd-options=-ze-opt-large-register-file" \ +// RUN: | mlir-runner \ +// RUN: --shared-libs=%mlir_levelzero_runtime \ +// RUN: --shared-libs=%mlir_runner_utils \ +// RUN: --shared-libs=%mlir_c_runner_utils \ +// RUN: --shared-libs=%irunner_utils \ +// RUN: --entry-point-result=void \ +// RUN: | FileCheck %s + +#q = #xegpu.layout +#q_load = #xegpu.layout +#q_ord = #xegpu.layout +#t_ord = #xegpu.layout +#q_s1 = #xegpu.slice<#q_ord, dims = [1]> +#t_s0 = #xegpu.slice<#t_ord, dims = [0]> +#pf = #xegpu.layout +#kv_load = #xegpu.layout +#kv = #xegpu.layout +#kv_ord = #xegpu.layout + +module @fragment_name attributes {gpu.container_module} { + func.func @entry(%arg0: memref<16x1024x64xf16>, %arg1: memref<16x1024x64xf16>, %arg2: memref<16x1024x64xf16>, %arg3: memref<16x1024x64xf16>) attributes {gc.num_kernels = 1 : i32} { + %c1 = arith.constant 1 : index + %c128 = arith.constant 128 : index + %c16 = arith.constant 16 : index + %c8 = arith.constant 8 : index + gpu.launch_func @entry_kernel::@entry_kernel blocks in (%c16, %c8, %c1) threads in (%c128, %c1, %c1) args(%arg0 : memref<16x1024x64xf16>, %arg1 : memref<16x1024x64xf16>, %arg2 : memref<16x1024x64xf16>, %arg3 : memref<16x1024x64xf16>) + return + } + gpu.module @entry_kernel [#xevm.target, #xevm.target] { + gpu.func @entry_kernel(%Q: memref<16x1024x64xf16>, %K: memref<16x1024x64xf16>, %V: memref<16x1024x64xf16>, %Out: memref<16x1024x64xf16>) kernel attributes {known_block_size = array} { + %c2 = arith.constant 2 : index + %c64 = arith.constant 64 : index + %c1024 = arith.constant 1024 : index + %l_i_init = arith.constant dense<0.000000e+00> : vector<128xf32> + // -inf constant for max reduction init + %m_i_init = arith.constant dense<0xFF800000> : vector<128xf32> + // constant scale propagated from OV (sm_scale folded with log2(e) for exp-via-exp2) + %qk_scale = arith.constant dense<0.350097656> : vector<128x64xf32> + %zero_acc = arith.constant dense<0.000000e+00> : vector<128x64xf32> + %c0 = arith.constant 0 : index + %block_id_x = gpu.block_id x + %block_id_y = gpu.block_id y + + // Load Q tile + %q_base_buffer, %q_offset, %q_sizes:3, %q_strides:3 = memref.extract_strided_metadata %Q : memref<16x1024x64xf16> -> memref, index, index, index, index, index, index, index + %c65536 = arith.constant 65536 : index + %q_offset_bh = arith.muli %block_id_x, %c65536 overflow : index + %c8192 = arith.constant 8192 : index + %q_offset_row = arith.muli %block_id_y, %c8192 overflow : index + %q_offset_base = arith.addi %q_offset_bh, %q_offset_row : index + %q_intptr = memref.extract_aligned_pointer_as_index %q_base_buffer : memref -> index + %q_offset_bytes = arith.muli %q_offset_base, %c2 : index + %q_ptr_offset = arith.addi %q_intptr, %q_offset_bytes : index + %q_ptr_i64 = arith.index_cast %q_ptr_offset : index to i64 + %q_load_tile = xegpu.create_nd_tdesc %q_ptr_i64, shape : [128, 64], strides : [64, 1] : i64 -> !xegpu.tensor_desc<128x64xf16, #xegpu.block_tdesc_attr, #q_load> + %q_value = xegpu.load_nd %q_load_tile[0, 0] <{layout = #q_load}> : !xegpu.tensor_desc<128x64xf16, #xegpu.block_tdesc_attr, #q_load> -> vector<128x64xf16> + + // Prefetch first K tile (iteration 0) + %k_base_buffer, %k_offset_meta, %k_sizes:3, %k_strides:3 = memref.extract_strided_metadata %K : memref<16x1024x64xf16> -> memref, index, index, index, index, index, index, index + %k_intptr = memref.extract_aligned_pointer_as_index %k_base_buffer : memref -> index + %c65536_kv = arith.constant 65536 : index + %kv_offset_bh = arith.muli %block_id_x, %c65536_kv overflow : index + %kv_offset_bytes_bh = arith.muli %kv_offset_bh, %c2 : index + %k_prefetch0_ptr = arith.addi %k_intptr, %kv_offset_bytes_bh : index + %k_prefetch0_ptr_i64 = arith.index_cast %k_prefetch0_ptr : index to i64 + %k_prefetch0_tile = xegpu.create_nd_tdesc %k_prefetch0_ptr_i64, shape : [64, 64], strides : [64, 1] : i64 -> !xegpu.tensor_desc<64x64xf16, #xegpu.block_tdesc_attr, #pf> + xegpu.prefetch_nd %k_prefetch0_tile[0, 0] <{l1_hint = #xegpu.cache_hint, l2_hint = #xegpu.cache_hint, l3_hint = #xegpu.cache_hint, layout = #pf}> : !xegpu.tensor_desc<64x64xf16, #xegpu.block_tdesc_attr, #pf> + + // Prefetch first V tile (iteration 0) + %v_base_buffer, %v_offset_meta, %v_sizes:3, %v_strides:3 = memref.extract_strided_metadata %V : memref<16x1024x64xf16> -> memref, index, index, index, index, index, index, index + %v_intptr = memref.extract_aligned_pointer_as_index %v_base_buffer : memref -> index + %v_prefetch0_ptr = arith.addi %v_intptr, %kv_offset_bytes_bh : index + %v_prefetch0_ptr_i64 = arith.index_cast %v_prefetch0_ptr : index to i64 + %v_prefetch0_tile = xegpu.create_nd_tdesc %v_prefetch0_ptr_i64, shape : [64, 64], strides : [64, 1] : i64 -> !xegpu.tensor_desc<64x64xf16, #xegpu.block_tdesc_attr, #pf> + xegpu.prefetch_nd %v_prefetch0_tile[0, 0] <{l1_hint = #xegpu.cache_hint, l2_hint = #xegpu.cache_hint, l3_hint = #xegpu.cache_hint, layout = #pf}> : !xegpu.tensor_desc<64x64xf16, #xegpu.block_tdesc_attr, #pf> + + // Main loop over K and V tiles + %result:3 = scf.for %k_offset = %c0 to %c1024 step %c64 iter_args(%acc_in = %zero_acc, %m_i_in = %m_i_init, %l_i_in = %l_i_init) -> (vector<128x64xf32>, vector<128xf32>, vector<128xf32>) { + // Prefetch next-iteration K tile + %k_next_offset = arith.addi %k_offset, %c64 : index + %c65536_next = arith.constant 65536 : index + %kv_next_offset_bh = arith.muli %block_id_x, %c65536_next overflow : index + %c64_stride = arith.constant 64 : index + %k_next_offset_row = arith.muli %k_next_offset, %c64_stride overflow : index + %k_next_offset_base = arith.addi %kv_next_offset_bh, %k_next_offset_row : index + %k_next_offset_bytes = arith.muli %k_next_offset_base, %c2 : index + %k_prefetch_ptr = arith.addi %k_intptr, %k_next_offset_bytes : index + %k_prefetch_ptr_i64 = arith.index_cast %k_prefetch_ptr : index to i64 + %k_prefetch_tile = xegpu.create_nd_tdesc %k_prefetch_ptr_i64, shape : [64, 64], strides : [64, 1] : i64 -> !xegpu.tensor_desc<64x64xf16, #xegpu.block_tdesc_attr, #pf> + xegpu.prefetch_nd %k_prefetch_tile[0, 0] <{l1_hint = #xegpu.cache_hint, l2_hint = #xegpu.cache_hint, l3_hint = #xegpu.cache_hint, layout = #pf}> : !xegpu.tensor_desc<64x64xf16, #xegpu.block_tdesc_attr, #pf> + + // Prefetch next-iteration V tile + %v_prefetch_ptr = arith.addi %v_intptr, %k_next_offset_bytes : index + %v_prefetch_ptr_i64 = arith.index_cast %v_prefetch_ptr : index to i64 + %v_prefetch_tile = xegpu.create_nd_tdesc %v_prefetch_ptr_i64, shape : [64, 64], strides : [64, 1] : i64 -> !xegpu.tensor_desc<64x64xf16, #xegpu.block_tdesc_attr, #pf> + xegpu.prefetch_nd %v_prefetch_tile[0, 0] <{l1_hint = #xegpu.cache_hint, l2_hint = #xegpu.cache_hint, l3_hint = #xegpu.cache_hint, layout = #pf}> : !xegpu.tensor_desc<64x64xf16, #xegpu.block_tdesc_attr, #pf> + + // Load K tile (current iteration) + %c65536_curr = arith.constant 65536 : index + %kv_curr_offset_bh = arith.muli %block_id_x, %c65536_curr overflow : index + %c64_stride_curr = arith.constant 64 : index + %k_curr_offset_row = arith.muli %k_offset, %c64_stride_curr overflow : index + %k_curr_offset_base = arith.addi %kv_curr_offset_bh, %k_curr_offset_row : index + %k_curr_offset_bytes = arith.muli %k_curr_offset_base, %c2 : index + %k_ptr_offset = arith.addi %k_intptr, %k_curr_offset_bytes : index + %k_ptr_i64 = arith.index_cast %k_ptr_offset : index to i64 + %k_tile = xegpu.create_nd_tdesc %k_ptr_i64, shape : [64, 64], strides : [64, 1] : i64 -> !xegpu.tensor_desc<64x64xf16, #xegpu.block_tdesc_attr, #kv_ord> + %k_value = xegpu.load_nd %k_tile[0, 0] <{layout = #kv_ord}> : !xegpu.tensor_desc<64x64xf16, #xegpu.block_tdesc_attr, #kv_ord> -> vector<64x64xf16> + + // Load V tile (current iteration) + %v_ptr_offset = arith.addi %v_intptr, %k_curr_offset_bytes : index + %v_ptr_i64 = arith.index_cast %v_ptr_offset : index to i64 + %v_load_tile = xegpu.create_nd_tdesc %v_ptr_i64, shape : [64, 64], strides : [64, 1] : i64 -> !xegpu.tensor_desc<64x64xf16, #xegpu.block_tdesc_attr, #kv_load> + %v_value = xegpu.load_nd %v_load_tile[0, 0] <{layout = #kv_load}> : !xegpu.tensor_desc<64x64xf16, #xegpu.block_tdesc_attr, #kv_load> -> vector<64x64xf16> + + // Compute Q * K^T + %k_value_t = vector.transpose %k_value, [1, 0] : vector<64x64xf16> to vector<64x64xf16> + %qk_out = xegpu.dpas %q_value, %k_value_t, %zero_acc {layout_a = #q, layout_b = #kv, layout_cd = #q} : vector<128x64xf16>, vector<64x64xf16>, vector<128x64xf32> -> vector<128x64xf32> + %qk_scaled = arith.mulf %qk_out, %qk_scale : vector<128x64xf32> + + // Online softmax: compute row-wise max + %qk_row_max = vector.multi_reduction , %qk_scaled, %m_i_init[1] : vector<128x64xf32> to vector<128xf32> + %m_ij = arith.maximumf %m_i_in, %qk_row_max : vector<128xf32> + + // Center by m_ij and compute exp + %m_ij_broadcasted_t = vector.broadcast %m_ij : vector<128xf32> to vector<64x128xf32> + %m_ij_broadcasted = vector.transpose %m_ij_broadcasted_t, [1, 0] : vector<64x128xf32> to vector<128x64xf32> + %qk_centered = arith.subf %qk_scaled, %m_ij_broadcasted : vector<128x64xf32> + %p_out = math.exp %qk_centered fastmath : vector<128x64xf32> + + // Sum exp values + %l_ij = vector.multi_reduction , %p_out, %l_i_init [1] : vector<128x64xf32> to vector<128xf32> + + // Update running statistics + %m_diff = arith.subf %m_i_in, %m_ij : vector<128xf32> + %alpha = math.exp %m_diff fastmath : vector<128xf32> + %l_i_scaled = arith.mulf %l_i_in, %alpha : vector<128xf32> + %l_i_new = arith.addf %l_i_scaled, %l_ij : vector<128xf32> + + // Scale previous accumulator by alpha + %alpha_broadcasted_t = vector.broadcast %alpha : vector<128xf32> to vector<64x128xf32> + %alpha_broadcasted = vector.transpose %alpha_broadcasted_t, [1, 0] : vector<64x128xf32> to vector<128x64xf32> + %acc_scaled = arith.mulf %acc_in, %alpha_broadcasted : vector<128x64xf32> + + // Convert P to f16 for DPAS + %p_out_f16 = arith.truncf %p_out : vector<128x64xf32> to vector<128x64xf16> + + // Compute P * V and add to scaled accumulator + %pv_out = xegpu.dpas %p_out_f16, %v_value, %acc_scaled {layout_a = #q, layout_b = #kv, layout_cd = #q} : vector<128x64xf16>, vector<64x64xf16>, vector<128x64xf32> -> vector<128x64xf32> + + scf.yield %pv_out, %m_ij, %l_i_new : vector<128x64xf32>, vector<128xf32>, vector<128xf32> + } + + // Normalize output by l_i + %l_i_broadcasted_t = vector.broadcast %result#2 : vector<128xf32> to vector<64x128xf32> + %l_i_broadcasted = vector.transpose %l_i_broadcasted_t, [1, 0] : vector<64x128xf32> to vector<128x64xf32> + %out_normalized = arith.divf %result#0, %l_i_broadcasted : vector<128x64xf32> + %out_f16 = arith.truncf %out_normalized : vector<128x64xf32> to vector<128x64xf16> + + // Store output + %o_base_buffer, %o_offset_meta, %o_sizes:3, %o_strides:3 = memref.extract_strided_metadata %Out : memref<16x1024x64xf16> -> memref, index, index, index, index, index, index, index + %o_intptr = memref.extract_aligned_pointer_as_index %o_base_buffer : memref -> index + %o_ptr_offset = arith.addi %o_intptr, %q_offset_bytes : index + %o_ptr_i64 = arith.index_cast %o_ptr_offset : index to i64 + %o_tile = xegpu.create_nd_tdesc %o_ptr_i64, shape : [128, 64], strides : [64, 1] : i64 -> !xegpu.tensor_desc<128x64xf16, #xegpu.block_tdesc_attr, #q> + xegpu.store_nd %out_f16, %o_tile[0, 0] <{layout = #q}> : vector<128x64xf16>, !xegpu.tensor_desc<128x64xf16, #xegpu.block_tdesc_attr, #q> + gpu.return + } + } + func.func @gpu_impl(%arg0: memref<16x1024x64xf16>, %arg1: memref<16x1024x64xf16>, %arg2: memref<16x1024x64xf16>, %arg3: memref<16x1024x64xf16>) -> memref<16x1024x64xf16> { + // Allocate GPU buffers + %memref = gpu.alloc () : memref<16x1024x64xf16> + %memref_0 = gpu.alloc () : memref<16x1024x64xf16> + %memref_1 = gpu.alloc () : memref<16x1024x64xf16> + %memref_2 = gpu.alloc () : memref<16x1024x64xf16> + + // Copy from CPU to GPU + gpu.memcpy %memref, %arg0 : memref<16x1024x64xf16>, memref<16x1024x64xf16> + gpu.memcpy %memref_0, %arg1 : memref<16x1024x64xf16>, memref<16x1024x64xf16> + gpu.memcpy %memref_1, %arg2 : memref<16x1024x64xf16>, memref<16x1024x64xf16> + + // Call the entry function which launches the kernel + call @entry(%memref, %memref_0, %memref_1, %memref_2) : (memref<16x1024x64xf16>, memref<16x1024x64xf16>, memref<16x1024x64xf16>, memref<16x1024x64xf16>) -> () + + // Wait for GPU to finish + gpu.wait + + // Copy output back to CPU + gpu.memcpy %arg3, %memref_2 : memref<16x1024x64xf16>, memref<16x1024x64xf16> + + // Cleanup GPU buffers + gpu.dealloc %memref : memref<16x1024x64xf16> + gpu.dealloc %memref_0 : memref<16x1024x64xf16> + gpu.dealloc %memref_1 : memref<16x1024x64xf16> + gpu.dealloc %memref_2 : memref<16x1024x64xf16> + return %arg3 : memref<16x1024x64xf16> + } + func.func @cpu_impl(%arg0: memref<16x1024x64xf16>, %arg1: memref<16x1024x64xf16>, %arg2: memref<16x1024x64xf16>, %arg3: memref<16x1024x64xf16>, %arg4: f32) -> memref<16x1024x64xf16> { + %cst = arith.constant 0xFF800000 : f32 + %c0 = arith.constant 0 : index + %c1 = arith.constant 1 : index + %c16 = arith.constant 16 : index + %c1024 = arith.constant 1024 : index + %c64 = arith.constant 64 : index + %cst_0 = arith.constant 0.000000e+00 : f32 + + // Buffer for QK intermediate results + %alloc = memref.alloc(%c1024, %c1024) : memref + + // Iterate over all batch*head combinations + scf.for %arg5 = %c0 to %c16 step %c1 { + // Reset buffer + scf.for %arg6 = %c0 to %c1024 step %c1 { + scf.for %arg7 = %c0 to %c1024 step %c1 { + memref.store %cst_0, %alloc[%arg6, %arg7] : memref + } + } + + // Compute P = Q*K^T + scf.for %arg6 = %c0 to %c1024 step %c1 { + scf.for %arg7 = %c0 to %c1024 step %c1 { + %0 = scf.for %arg8 = %c0 to %c64 step %c1 iter_args(%arg9 = %cst_0) -> (f32) { + %2 = memref.load %arg0[%arg5, %arg6, %arg8] : memref<16x1024x64xf16> + %3 = memref.load %arg1[%arg5, %arg7, %arg8] : memref<16x1024x64xf16> + %4 = arith.extf %2 : f16 to f32 + %5 = arith.extf %3 : f16 to f32 + %6 = arith.mulf %4, %5 : f32 + %7 = arith.addf %arg9, %6 : f32 + scf.yield %7 : f32 + } + // Scale by sm_scale + %1 = arith.mulf %0, %arg4 : f32 + memref.store %1, %alloc[%arg6, %arg7] : memref + } + } + + // Compute softmax + scf.for %arg6 = %c0 to %c1024 step %c1 { + // Max reduce + %0 = scf.for %arg7 = %c0 to %c1024 step %c1 iter_args(%arg8 = %cst) -> (f32) { + %2 = memref.load %alloc[%arg6, %arg7] : memref + %3 = arith.maximumf %arg8, %2 : f32 + scf.yield %3 : f32 + } + // Center by max and exp + scf.for %arg7 = %c0 to %c1024 step %c1 { + %2 = memref.load %alloc[%arg6, %arg7] : memref + %3 = arith.subf %2, %0 : f32 + %4 = math.exp %3 : f32 + memref.store %4, %alloc[%arg6, %arg7] : memref + } + // Take sum of row + %1 = scf.for %arg7 = %c0 to %c1024 step %c1 iter_args(%arg8 = %cst_0) -> (f32) { + %2 = memref.load %alloc[%arg6, %arg7] : memref + %3 = arith.addf %arg8, %2 : f32 + scf.yield %3 : f32 + } + // Divide by sum + scf.for %arg7 = %c0 to %c1024 step %c1 { + %2 = memref.load %alloc[%arg6, %arg7] : memref + %3 = arith.divf %2, %1 : f32 + memref.store %3, %alloc[%arg6, %arg7] : memref + } + } + + // Compute P*V + scf.for %arg6 = %c0 to %c1024 step %c1 { + scf.for %arg7 = %c0 to %c64 step %c1 { + %0 = scf.for %arg8 = %c0 to %c1024 step %c1 iter_args(%arg9 = %cst_0) -> (f32) { + %2 = memref.load %alloc[%arg6, %arg8] : memref + %3 = memref.load %arg2[%arg5, %arg8, %arg7] : memref<16x1024x64xf16> + %4 = arith.extf %3 : f16 to f32 + %5 = arith.mulf %2, %4 : f32 + %6 = arith.addf %5, %arg9 : f32 + scf.yield %6 : f32 + } + %1 = arith.truncf %0 : f32 to f16 + memref.store %1, %arg3[%arg5, %arg6, %arg7] : memref<16x1024x64xf16> + } + } + } + memref.dealloc %alloc : memref + return %arg3 : memref<16x1024x64xf16> + } + func.func @init_3d_memref_to_const_f16(%arg0: memref<16x1024x64xf16>, %arg1: f16) { + %c0 = arith.constant 0 : index + %c1 = arith.constant 1 : index + %c16 = arith.constant 16 : index + %c1024 = arith.constant 1024 : index + %c64 = arith.constant 64 : index + scf.for %arg2 = %c0 to %c16 step %c1 { + scf.for %arg3 = %c0 to %c1024 step %c1 { + scf.for %arg4 = %c0 to %c64 step %c1 { + memref.store %arg1, %arg0[%arg2, %arg3, %arg4] : memref<16x1024x64xf16> + } + } + } + return + } + func.func @main() attributes {llvm.emit_c_interface} { + %c0 = arith.constant 0 : index + %c1 = arith.constant 1 : index + %c16 = arith.constant 16 : index + %c1024 = arith.constant 1024 : index + %c64 = arith.constant 64 : index + %cst = arith.constant 0.000000e+00 : f16 + %cst_0 = arith.constant 0.350097656 : f32 // Match the hardcoded scale in the kernel + + // Random number generator parameters + %cst_1 = arith.constant -1.000000e+00 : f32 + %cst_2 = arith.constant 1.000000e+00 : f32 + %false = arith.constant false + + // Allocate Q, K, V, O buffers + %alloc = memref.alloc() : memref<16x1024x64xf16> + %alloc_3 = memref.alloc() : memref<16x1024x64xf16> + %alloc_4 = memref.alloc() : memref<16x1024x64xf16> + %alloc_5 = memref.alloc() : memref<16x1024x64xf16> + %alloc_6 = memref.alloc() : memref<16x1024x64xf16> + %alloc_7 = memref.alloc() : memref<16x1024x64xf32> + + // Initialize Q, K, V with random numbers in range [-1, 1] + %cast = memref.cast %alloc : memref<16x1024x64xf16> to memref<*xf16> + %cast_8 = memref.cast %alloc_3 : memref<16x1024x64xf16> to memref<*xf16> + %cast_9 = memref.cast %alloc_4 : memref<16x1024x64xf16> to memref<*xf16> + call @fillResource1DRandomF16(%cast, %cst_1, %cst_2, %false) : (memref<*xf16>, f32, f32, i1) -> () + call @fillResource1DRandomF16(%cast_8, %cst_1, %cst_2, %false) : (memref<*xf16>, f32, f32, i1) -> () + call @fillResource1DRandomF16(%cast_9, %cst_1, %cst_2, %false) : (memref<*xf16>, f32, f32, i1) -> () + + // Initialize output buffers to 0.0 + call @init_3d_memref_to_const_f16(%alloc_5, %cst) : (memref<16x1024x64xf16>, f16) -> () + call @init_3d_memref_to_const_f16(%alloc_6, %cst) : (memref<16x1024x64xf16>, f16) -> () + + // Run GPU version + %0 = call @gpu_impl(%alloc, %alloc_3, %alloc_4, %alloc_5) : (memref<16x1024x64xf16>, memref<16x1024x64xf16>, memref<16x1024x64xf16>, memref<16x1024x64xf16>) -> memref<16x1024x64xf16> + + // Run CPU reference version + %1 = call @cpu_impl(%alloc, %alloc_3, %alloc_4, %alloc_6, %cst_0) : (memref<16x1024x64xf16>, memref<16x1024x64xf16>, memref<16x1024x64xf16>, memref<16x1024x64xf16>, f32) -> memref<16x1024x64xf16> + + // Convert CPU output to f32 for comparison + scf.for %arg0 = %c0 to %c16 step %c1 { + scf.for %arg1 = %c0 to %c1024 step %c1 { + scf.for %arg2 = %c0 to %c64 step %c1 { + %2 = memref.load %alloc_6[%arg0, %arg1, %arg2] : memref<16x1024x64xf16> + %3 = arith.extf %2 : f16 to f32 + memref.store %3, %alloc_7[%arg0, %arg1, %arg2] : memref<16x1024x64xf32> + } + } + } + + // Compare results + %cast_10 = memref.cast %0 : memref<16x1024x64xf16> to memref<*xf16> + %cast_11 = memref.cast %alloc_7 : memref<16x1024x64xf32> to memref<*xf32> + // CHECK: [ALLCLOSE: TRUE] + call @printAllcloseF16(%cast_10, %cast_11) : (memref<*xf16>, memref<*xf32>) -> () + + // Cleanup + memref.dealloc %alloc : memref<16x1024x64xf16> + memref.dealloc %alloc_3 : memref<16x1024x64xf16> + memref.dealloc %alloc_4 : memref<16x1024x64xf16> + memref.dealloc %alloc_5 : memref<16x1024x64xf16> + memref.dealloc %alloc_6 : memref<16x1024x64xf16> + memref.dealloc %alloc_7 : memref<16x1024x64xf32> + return + } + + // Helper function declarations + func.func private @printMemrefF16(memref<*xf16>) attributes {llvm.emit_c_interface} + func.func private @printMemrefF32(memref<*xf32>) attributes {llvm.emit_c_interface} + func.func private @printAllcloseF16(memref<*xf16>, memref<*xf32>) attributes {llvm.emit_c_interface} + func.func private @fillResource1DRandomF16(memref<*xf16>, f32, f32, i1) attributes {llvm.emit_c_interface} + func.func private @fillResource1DF16(memref<*xf16>, f32) attributes {llvm.emit_c_interface} + func.func private @fillResource1DF32(memref<*xf32>, f32) attributes {llvm.emit_c_interface} +} diff --git a/test/Integration/Dialect/XeGPU/WG/flash_attention_fwd_ov_with_arrray_len_4k.mlir b/test/Integration/Dialect/XeGPU/WG/flash_attention_fwd_ov_with_arrray_len_4k.mlir new file mode 100644 index 000000000..260821f53 --- /dev/null +++ b/test/Integration/Dialect/XeGPU/WG/flash_attention_fwd_ov_with_arrray_len_4k.mlir @@ -0,0 +1,378 @@ +// RUN: imex-opt %s --gpu-lower-to-xevm-pipeline="xegpu-op-level=workgroup igc-cmd-options=-ze-opt-large-register-file" \ +// RUN: | mlir-runner \ +// RUN: --shared-libs=%mlir_levelzero_runtime \ +// RUN: --shared-libs=%mlir_runner_utils \ +// RUN: --shared-libs=%mlir_c_runner_utils \ +// RUN: --shared-libs=%irunner_utils \ +// RUN: --entry-point-result=void \ +// RUN: | FileCheck %s + + +#q = #xegpu.layout +#q_load = #xegpu.layout +#q_ord = #xegpu.layout +#t_ord = #xegpu.layout +#q_s1 = #xegpu.slice<#q_ord, dims = [1]> +#t_s0 = #xegpu.slice<#t_ord, dims = [0]> +#pf = #xegpu.layout +#kv_load = #xegpu.layout +#kv = #xegpu.layout +#kv_ord = #xegpu.layout + +module @fragment_name attributes {gpu.container_module} { + func.func @entry(%arg0: memref<16x4096x64xf16>, %arg1: memref<16x4096x64xf16>, %arg2: memref<16x4096x64xf16>, %arg3: memref<16x4096x64xf16>) attributes {gc.num_kernels = 1 : i32} { + %c1 = arith.constant 1 : index + %c128 = arith.constant 128 : index + %c16 = arith.constant 16 : index + %c32 = arith.constant 32 : index + gpu.launch_func @entry_kernel::@entry_kernel blocks in (%c16, %c32, %c1) threads in (%c128, %c1, %c1) args(%arg0 : memref<16x4096x64xf16>, %arg1 : memref<16x4096x64xf16>, %arg2 : memref<16x4096x64xf16>, %arg3 : memref<16x4096x64xf16>) + return + } + gpu.module @entry_kernel [#xevm.target, #xevm.target] { + gpu.func @entry_kernel(%Q: memref<16x4096x64xf16>, %K: memref<16x4096x64xf16>, %V: memref<16x4096x64xf16>, %Out: memref<16x4096x64xf16>) kernel attributes {known_block_size = array} { + %c2 = arith.constant 2 : index + %c64 = arith.constant 64 : index + %c4096 = arith.constant 4096 : index + %l_i_init = arith.constant dense<0.000000e+00> : vector<128xf32> + // -inf constant for max reduction init + %m_i_init = arith.constant dense<0xFF800000> : vector<128xf32> + // constant scale propagated from OV (sm_scale folded with log2(e) for exp-via-exp2) + %qk_scale = arith.constant dense<0.350097656> : vector<128x64xf32> + %zero_acc = arith.constant dense<0.000000e+00> : vector<128x64xf32> + %c0 = arith.constant 0 : index + %block_id_x = gpu.block_id x + %block_id_y = gpu.block_id y + + // Load Q tile + %q_base_buffer, %q_offset, %q_sizes:3, %q_strides:3 = memref.extract_strided_metadata %Q : memref<16x4096x64xf16> -> memref, index, index, index, index, index, index, index + %c262144 = arith.constant 262144 : index + %q_offset_bh = arith.muli %block_id_x, %c262144 overflow : index + %c8192 = arith.constant 8192 : index + %q_offset_row = arith.muli %block_id_y, %c8192 overflow : index + %q_offset_base = arith.addi %q_offset_bh, %q_offset_row : index + %q_intptr = memref.extract_aligned_pointer_as_index %q_base_buffer : memref -> index + %q_offset_bytes = arith.muli %q_offset_base, %c2 : index + %q_ptr_offset = arith.addi %q_intptr, %q_offset_bytes : index + %q_ptr_i64 = arith.index_cast %q_ptr_offset : index to i64 + %q_tile = xegpu.create_nd_tdesc %q_ptr_i64, shape : [128, 64], strides : [64, 1] : i64 -> !xegpu.tensor_desc<128x64xf16, #xegpu.block_tdesc_attr, #q> + %q_load_tile = xegpu.create_nd_tdesc %q_ptr_i64, shape : [128, 64], strides : [64, 1] : i64 -> !xegpu.tensor_desc<128x64xf16, #xegpu.block_tdesc_attr, #q_load> + %q_value = xegpu.load_nd %q_load_tile[0, 0] <{layout = #q_load}> : !xegpu.tensor_desc<128x64xf16, #xegpu.block_tdesc_attr, #q_load> -> vector<128x64xf16> + + // Prefetch first K tile (iteration 0) + %k_base_buffer, %k_offset_meta, %k_sizes:3, %k_strides:3 = memref.extract_strided_metadata %K : memref<16x4096x64xf16> -> memref, index, index, index, index, index, index, index + %k_intptr = memref.extract_aligned_pointer_as_index %k_base_buffer : memref -> index + %c262144_kv = arith.constant 262144 : index + %kv_offset_bh = arith.muli %block_id_x, %c262144_kv overflow : index + %kv_offset_bytes_bh = arith.muli %kv_offset_bh, %c2 : index + %k_prefetch0_ptr = arith.addi %k_intptr, %kv_offset_bytes_bh : index + %k_prefetch0_ptr_i64 = arith.index_cast %k_prefetch0_ptr : index to i64 + %k_prefetch0_tile = xegpu.create_nd_tdesc %k_prefetch0_ptr_i64, shape : [64, 64], strides : [64, 1] : i64 -> !xegpu.tensor_desc<64x64xf16, #xegpu.block_tdesc_attr, #pf> + xegpu.prefetch_nd %k_prefetch0_tile[0, 0] <{l1_hint = #xegpu.cache_hint, l2_hint = #xegpu.cache_hint, l3_hint = #xegpu.cache_hint, layout = #pf}> : !xegpu.tensor_desc<64x64xf16, #xegpu.block_tdesc_attr, #pf> + + // Prefetch first V tile (iteration 0) + %v_base_buffer, %v_offset_meta, %v_sizes:3, %v_strides:3 = memref.extract_strided_metadata %V : memref<16x4096x64xf16> -> memref, index, index, index, index, index, index, index + %v_intptr = memref.extract_aligned_pointer_as_index %v_base_buffer : memref -> index + %v_prefetch0_ptr = arith.addi %v_intptr, %kv_offset_bytes_bh : index + %v_prefetch0_ptr_i64 = arith.index_cast %v_prefetch0_ptr : index to i64 + %v_prefetch0_tile = xegpu.create_nd_tdesc %v_prefetch0_ptr_i64, shape : [64, 64], strides : [64, 1] : i64 -> !xegpu.tensor_desc<64x64xf16, #xegpu.block_tdesc_attr, #pf> + xegpu.prefetch_nd %v_prefetch0_tile[0, 0] <{l1_hint = #xegpu.cache_hint, l2_hint = #xegpu.cache_hint, l3_hint = #xegpu.cache_hint, layout = #pf}> : !xegpu.tensor_desc<64x64xf16, #xegpu.block_tdesc_attr, #pf> + + // Main loop over K and V tiles + %result:3 = scf.for %k_offset = %c0 to %c4096 step %c64 iter_args(%acc_in = %zero_acc, %m_i_in = %m_i_init, %l_i_in = %l_i_init) -> (vector<128x64xf32>, vector<128xf32>, vector<128xf32>) { + // Prefetch next-iteration K tile + %k_next_offset = arith.addi %k_offset, %c64 : index + %c262144_next = arith.constant 262144 : index + %kv_next_offset_bh = arith.muli %block_id_x, %c262144_next overflow : index + %c64_stride = arith.constant 64 : index + %k_next_offset_row = arith.muli %k_next_offset, %c64_stride overflow : index + %k_next_offset_base = arith.addi %kv_next_offset_bh, %k_next_offset_row : index + %k_next_offset_bytes = arith.muli %k_next_offset_base, %c2 : index + %k_prefetch_ptr = arith.addi %k_intptr, %k_next_offset_bytes : index + %k_prefetch_ptr_i64 = arith.index_cast %k_prefetch_ptr : index to i64 + %k_prefetch_tile = xegpu.create_nd_tdesc %k_prefetch_ptr_i64, shape : [64, 64], strides : [64, 1] : i64 -> !xegpu.tensor_desc<64x64xf16, #xegpu.block_tdesc_attr, #pf> + xegpu.prefetch_nd %k_prefetch_tile[0, 0] <{l1_hint = #xegpu.cache_hint, l2_hint = #xegpu.cache_hint, l3_hint = #xegpu.cache_hint, layout = #pf}> : !xegpu.tensor_desc<64x64xf16, #xegpu.block_tdesc_attr, #pf> + + // Prefetch next-iteration V tile + %v_prefetch_ptr = arith.addi %v_intptr, %k_next_offset_bytes : index + %v_prefetch_ptr_i64 = arith.index_cast %v_prefetch_ptr : index to i64 + %v_prefetch_tile = xegpu.create_nd_tdesc %v_prefetch_ptr_i64, shape : [64, 64], strides : [64, 1] : i64 -> !xegpu.tensor_desc<64x64xf16, #xegpu.block_tdesc_attr, #pf> + xegpu.prefetch_nd %v_prefetch_tile[0, 0] <{l1_hint = #xegpu.cache_hint, l2_hint = #xegpu.cache_hint, l3_hint = #xegpu.cache_hint, layout = #pf}> : !xegpu.tensor_desc<64x64xf16, #xegpu.block_tdesc_attr, #pf> + + // Load K tile (current iteration) + %c262144_curr = arith.constant 262144 : index + %kv_curr_offset_bh = arith.muli %block_id_x, %c262144_curr overflow : index + %c64_stride_curr = arith.constant 64 : index + %k_curr_offset_row = arith.muli %k_offset, %c64_stride_curr overflow : index + %k_curr_offset_base = arith.addi %kv_curr_offset_bh, %k_curr_offset_row : index + %k_curr_offset_bytes = arith.muli %k_curr_offset_base, %c2 : index + %k_ptr_offset = arith.addi %k_intptr, %k_curr_offset_bytes : index + %k_ptr_i64 = arith.index_cast %k_ptr_offset : index to i64 + %k_tile = xegpu.create_nd_tdesc %k_ptr_i64, shape : [64, 64], strides : [64, 1] : i64 -> !xegpu.tensor_desc<64x64xf16, #xegpu.block_tdesc_attr, #kv_ord> + %k_value = xegpu.load_nd %k_tile[0, 0] <{layout = #kv_ord}> : !xegpu.tensor_desc<64x64xf16, #xegpu.block_tdesc_attr, #kv_ord> -> vector<64x64xf16> + + // Load V tile (current iteration) + %v_ptr_offset = arith.addi %v_intptr, %k_curr_offset_bytes : index + %v_ptr_i64 = arith.index_cast %v_ptr_offset : index to i64 + %v_tile_unused = xegpu.create_nd_tdesc %v_ptr_i64, shape : [64, 64], strides : [64, 1] : i64 -> !xegpu.tensor_desc<64x64xf16, #xegpu.block_tdesc_attr, #kv> + %v_load_tile = xegpu.create_nd_tdesc %v_ptr_i64, shape : [64, 64], strides : [64, 1] : i64 -> !xegpu.tensor_desc<64x64xf16, #xegpu.block_tdesc_attr, #kv_load> + %v_value = xegpu.load_nd %v_load_tile[0, 0] <{layout = #kv_load}> : !xegpu.tensor_desc<64x64xf16, #xegpu.block_tdesc_attr, #kv_load> -> vector<64x64xf16> + + // Compute Q * K^T + %k_value_t = vector.transpose %k_value, [1, 0] : vector<64x64xf16> to vector<64x64xf16> + %qk_out = xegpu.dpas %q_value, %k_value_t, %zero_acc {layout_a = #q, layout_b = #kv, layout_cd = #q} : vector<128x64xf16>, vector<64x64xf16>, vector<128x64xf32> -> vector<128x64xf32> + %qk_scaled = arith.mulf %qk_out, %qk_scale : vector<128x64xf32> + + // Online softmax: compute row-wise max + %qk_row_max = vector.multi_reduction , %qk_scaled, %m_i_init [1] : vector<128x64xf32> to vector<128xf32> + %m_ij = arith.maximumf %m_i_in, %qk_row_max : vector<128xf32> + + // Center by m_ij and compute exp + %m_ij_broadcasted_t = vector.broadcast %m_ij : vector<128xf32> to vector<64x128xf32> + %m_ij_broadcasted = vector.transpose %m_ij_broadcasted_t, [1, 0] : vector<64x128xf32> to vector<128x64xf32> + %qk_centered = arith.subf %qk_scaled, %m_ij_broadcasted : vector<128x64xf32> + %p_out = math.exp %qk_centered fastmath : vector<128x64xf32> + + // Sum exp values + %l_ij = vector.multi_reduction , %p_out, %l_i_init [1] : vector<128x64xf32> to vector<128xf32> + + // Update running statistics + %m_diff = arith.subf %m_i_in, %m_ij : vector<128xf32> + %alpha = math.exp %m_diff fastmath : vector<128xf32> + %l_i_scaled = arith.mulf %l_i_in, %alpha : vector<128xf32> + %l_i_new = arith.addf %l_i_scaled, %l_ij : vector<128xf32> + + // Scale previous accumulator by alpha + %alpha_broadcasted_t = vector.broadcast %alpha : vector<128xf32> to vector<64x128xf32> + %alpha_broadcasted = vector.transpose %alpha_broadcasted_t, [1, 0] : vector<64x128xf32> to vector<128x64xf32> + %acc_scaled = arith.mulf %acc_in, %alpha_broadcasted : vector<128x64xf32> + + // Convert P to f16 for DPAS + %p_out_f16 = arith.truncf %p_out : vector<128x64xf32> to vector<128x64xf16> + + // Compute P * V and add to scaled accumulator + %pv_out = xegpu.dpas %p_out_f16, %v_value, %acc_scaled {layout_a = #q, layout_b = #kv, layout_cd = #q} : vector<128x64xf16>, vector<64x64xf16>, vector<128x64xf32> -> vector<128x64xf32> + + scf.yield %pv_out, %m_ij, %l_i_new : vector<128x64xf32>, vector<128xf32>, vector<128xf32> + } + + // Normalize output by l_i + %l_i_broadcasted_t = vector.broadcast %result#2 : vector<128xf32> to vector<64x128xf32> + %l_i_broadcasted = vector.transpose %l_i_broadcasted_t, [1, 0] : vector<64x128xf32> to vector<128x64xf32> + %out_normalized = arith.divf %result#0, %l_i_broadcasted : vector<128x64xf32> + %out_f16 = arith.truncf %out_normalized : vector<128x64xf32> to vector<128x64xf16> + + // Store output + %o_base_buffer, %o_offset_meta, %o_sizes:3, %o_strides:3 = memref.extract_strided_metadata %Out : memref<16x4096x64xf16> -> memref, index, index, index, index, index, index, index + %o_intptr = memref.extract_aligned_pointer_as_index %o_base_buffer : memref -> index + %o_ptr_offset = arith.addi %o_intptr, %q_offset_bytes : index + %o_ptr_i64 = arith.index_cast %o_ptr_offset : index to i64 + %o_tile = xegpu.create_nd_tdesc %o_ptr_i64, shape : [128, 64], strides : [64, 1] : i64 -> !xegpu.tensor_desc<128x64xf16, #xegpu.block_tdesc_attr, #q> + xegpu.store_nd %out_f16, %o_tile[0, 0] <{layout = #q}> : vector<128x64xf16>, !xegpu.tensor_desc<128x64xf16, #xegpu.block_tdesc_attr, #q> + gpu.return + } +} + func.func @gpu_impl(%arg0: memref<16x4096x64xf16>, %arg1: memref<16x4096x64xf16>, %arg2: memref<16x4096x64xf16>, %arg3: memref<16x4096x64xf16>) -> memref<16x4096x64xf16> { + // Allocate GPU buffers + %memref = gpu.alloc () : memref<16x4096x64xf16> + %memref_0 = gpu.alloc () : memref<16x4096x64xf16> + %memref_1 = gpu.alloc () : memref<16x4096x64xf16> + %memref_2 = gpu.alloc () : memref<16x4096x64xf16> + + // Copy from CPU to GPU + gpu.memcpy %memref, %arg0 : memref<16x4096x64xf16>, memref<16x4096x64xf16> + gpu.memcpy %memref_0, %arg1 : memref<16x4096x64xf16>, memref<16x4096x64xf16> + gpu.memcpy %memref_1, %arg2 : memref<16x4096x64xf16>, memref<16x4096x64xf16> + + // Call the entry function which launches the kernel + call @entry(%memref, %memref_0, %memref_1, %memref_2) : (memref<16x4096x64xf16>, memref<16x4096x64xf16>, memref<16x4096x64xf16>, memref<16x4096x64xf16>) -> () + + // Wait for GPU to finish + gpu.wait + + // Copy output back to CPU + gpu.memcpy %arg3, %memref_2 : memref<16x4096x64xf16>, memref<16x4096x64xf16> + + // Cleanup GPU buffers + gpu.dealloc %memref : memref<16x4096x64xf16> + gpu.dealloc %memref_0 : memref<16x4096x64xf16> + gpu.dealloc %memref_1 : memref<16x4096x64xf16> + gpu.dealloc %memref_2 : memref<16x4096x64xf16> + return %arg3 : memref<16x4096x64xf16> + } + func.func @cpu_impl(%arg0: memref<16x4096x64xf16>, %arg1: memref<16x4096x64xf16>, %arg2: memref<16x4096x64xf16>, %arg3: memref<16x4096x64xf16>, %arg4: f32) -> memref<16x4096x64xf16> { + %cst = arith.constant 0xFF800000 : f32 + %c0 = arith.constant 0 : index + %c1 = arith.constant 1 : index + %c16 = arith.constant 16 : index + %c4096 = arith.constant 4096 : index + %c64 = arith.constant 64 : index + %cst_0 = arith.constant 0.000000e+00 : f32 + + // Buffer for QK intermediate results + %alloc = memref.alloc(%c4096, %c4096) : memref + + // Iterate over all batch*head combinations + scf.for %arg5 = %c0 to %c16 step %c1 { + // Reset buffer + scf.for %arg6 = %c0 to %c4096 step %c1 { + scf.for %arg7 = %c0 to %c4096 step %c1 { + memref.store %cst_0, %alloc[%arg6, %arg7] : memref + } + } + + // Compute P = Q*K^T + scf.for %arg6 = %c0 to %c4096 step %c1 { + scf.for %arg7 = %c0 to %c4096 step %c1 { + %0 = scf.for %arg8 = %c0 to %c64 step %c1 iter_args(%arg9 = %cst_0) -> (f32) { + %2 = memref.load %arg0[%arg5, %arg6, %arg8] : memref<16x4096x64xf16> + %3 = memref.load %arg1[%arg5, %arg7, %arg8] : memref<16x4096x64xf16> + %4 = arith.extf %2 : f16 to f32 + %5 = arith.extf %3 : f16 to f32 + %6 = arith.mulf %4, %5 : f32 + %7 = arith.addf %arg9, %6 : f32 + scf.yield %7 : f32 + } + // Scale by sm_scale + %1 = arith.mulf %0, %arg4 : f32 + memref.store %1, %alloc[%arg6, %arg7] : memref + } + } + + // Compute softmax + scf.for %arg6 = %c0 to %c4096 step %c1 { + // Max reduce + %0 = scf.for %arg7 = %c0 to %c4096 step %c1 iter_args(%arg8 = %cst) -> (f32) { + %2 = memref.load %alloc[%arg6, %arg7] : memref + %3 = arith.maximumf %arg8, %2 : f32 + scf.yield %3 : f32 + } + // Center by max and exp + scf.for %arg7 = %c0 to %c4096 step %c1 { + %2 = memref.load %alloc[%arg6, %arg7] : memref + %3 = arith.subf %2, %0 : f32 + %4 = math.exp%3 : f32 + memref.store %4, %alloc[%arg6, %arg7] : memref + } + // Take sum of row + %1 = scf.for %arg7 = %c0 to %c4096 step %c1 iter_args(%arg8 = %cst_0) -> (f32) { + %2 = memref.load %alloc[%arg6, %arg7] : memref + %3 = arith.addf %arg8, %2 : f32 + scf.yield %3 : f32 + } + // Divide by sum + scf.for %arg7 = %c0 to %c4096 step %c1 { + %2 = memref.load %alloc[%arg6, %arg7] : memref + %3 = arith.divf %2, %1 : f32 + memref.store %3, %alloc[%arg6, %arg7] : memref + } + } + + // Compute P*V + scf.for %arg6 = %c0 to %c4096 step %c1 { + scf.for %arg7 = %c0 to %c64 step %c1 { + %0 = scf.for %arg8 = %c0 to %c4096 step %c1 iter_args(%arg9 = %cst_0) -> (f32) { + %2 = memref.load %alloc[%arg6, %arg8] : memref + %3 = memref.load %arg2[%arg5, %arg8, %arg7] : memref<16x4096x64xf16> + %4 = arith.extf %3 : f16 to f32 + %5 = arith.mulf %2, %4 : f32 + %6 = arith.addf %5, %arg9 : f32 + scf.yield %6 : f32 + } + %1 = arith.truncf %0 : f32 to f16 + memref.store %1, %arg3[%arg5, %arg6, %arg7] : memref<16x4096x64xf16> + } + } + } + memref.dealloc %alloc : memref + return %arg3 : memref<16x4096x64xf16> + } + func.func @init_3d_memref_to_const_f16(%arg0: memref<16x4096x64xf16>, %arg1: f16) { + %c0 = arith.constant 0 : index + %c1 = arith.constant 1 : index + %c16 = arith.constant 16 : index + %c4096 = arith.constant 4096 : index + %c64 = arith.constant 64 : index + scf.for %arg2 = %c0 to %c16 step %c1 { + scf.for %arg3 = %c0 to %c4096 step %c1 { + scf.for %arg4 = %c0 to %c64 step %c1 { + memref.store %arg1, %arg0[%arg2, %arg3, %arg4] : memref<16x4096x64xf16> + } + } + } + return + } + func.func @main() attributes {llvm.emit_c_interface} { + %c0 = arith.constant 0 : index + %c1 = arith.constant 1 : index + %c16 = arith.constant 16 : index + %c4096 = arith.constant 4096 : index + %c64 = arith.constant 64 : index + %cst = arith.constant 0.000000e+00 : f16 + %cst_0 = arith.constant 0.350097656 : f32 // Match the hardcoded scale in the kernel + + // Random number generator parameters + %cst_1 = arith.constant -1.000000e+00 : f32 + %cst_2 = arith.constant 1.000000e+00 : f32 + %false = arith.constant false + + // Allocate Q, K, V, O buffers + %alloc = memref.alloc() : memref<16x4096x64xf16> + %alloc_3 = memref.alloc() : memref<16x4096x64xf16> + %alloc_4 = memref.alloc() : memref<16x4096x64xf16> + %alloc_5 = memref.alloc() : memref<16x4096x64xf16> + %alloc_6 = memref.alloc() : memref<16x4096x64xf16> + %alloc_7 = memref.alloc() : memref<16x4096x64xf32> + + // Initialize Q, K, V with random numbers in range [-1, 1] + %cast = memref.cast %alloc : memref<16x4096x64xf16> to memref<*xf16> + %cast_8 = memref.cast %alloc_3 : memref<16x4096x64xf16> to memref<*xf16> + %cast_9 = memref.cast %alloc_4 : memref<16x4096x64xf16> to memref<*xf16> + call @fillResource1DRandomF16(%cast, %cst_1, %cst_2, %false) : (memref<*xf16>, f32, f32, i1) -> () + call @fillResource1DRandomF16(%cast_8, %cst_1, %cst_2, %false) : (memref<*xf16>, f32, f32, i1) -> () + call @fillResource1DRandomF16(%cast_9, %cst_1, %cst_2, %false) : (memref<*xf16>, f32, f32, i1) -> () + + // Initialize output buffers to 0.0 + call @init_3d_memref_to_const_f16(%alloc_5, %cst) : (memref<16x4096x64xf16>, f16) -> () + call @init_3d_memref_to_const_f16(%alloc_6, %cst) : (memref<16x4096x64xf16>, f16) -> () + + // Run GPU version + %0 = call @gpu_impl(%alloc, %alloc_3, %alloc_4, %alloc_5) : (memref<16x4096x64xf16>, memref<16x4096x64xf16>, memref<16x4096x64xf16>, memref<16x4096x64xf16>) -> memref<16x4096x64xf16> + + // Run CPU reference version + %1 = call @cpu_impl(%alloc, %alloc_3, %alloc_4, %alloc_6, %cst_0) : (memref<16x4096x64xf16>, memref<16x4096x64xf16>, memref<16x4096x64xf16>, memref<16x4096x64xf16>, f32) -> memref<16x4096x64xf16> + + // Convert CPU output to f32 for comparison + scf.for %arg0 = %c0 to %c16 step %c1 { + scf.for %arg1 = %c0 to %c4096 step %c1 { + scf.for %arg2 = %c0 to %c64 step %c1 { + %2 = memref.load %alloc_6[%arg0, %arg1, %arg2] : memref<16x4096x64xf16> + %3 = arith.extf %2 : f16 to f32 + memref.store %3, %alloc_7[%arg0, %arg1, %arg2] : memref<16x4096x64xf32> + } + } + } + + // Compare results + %cast_10 = memref.cast %0 : memref<16x4096x64xf16> to memref<*xf16> + %cast_11 = memref.cast %alloc_7 : memref<16x4096x64xf32> to memref<*xf32> + // CHECK: [ALLCLOSE: TRUE] + call @printAllcloseF16(%cast_10, %cast_11) : (memref<*xf16>, memref<*xf32>) -> () + + // Cleanup + memref.dealloc %alloc : memref<16x4096x64xf16> + memref.dealloc %alloc_3 : memref<16x4096x64xf16> + memref.dealloc %alloc_4 : memref<16x4096x64xf16> + memref.dealloc %alloc_5 : memref<16x4096x64xf16> + memref.dealloc %alloc_6 : memref<16x4096x64xf16> + memref.dealloc %alloc_7 : memref<16x4096x64xf32> + return + } + + // Helper function declarations + func.func private @printMemrefF16(memref<*xf16>) attributes {llvm.emit_c_interface} + func.func private @printMemrefF32(memref<*xf32>) attributes {llvm.emit_c_interface} + func.func private @printAllcloseF16(memref<*xf16>, memref<*xf32>) attributes {llvm.emit_c_interface} + func.func private @fillResource1DRandomF16(memref<*xf16>, f32, f32, i1) attributes {llvm.emit_c_interface} + func.func private @fillResource1DF16(memref<*xf16>, f32) attributes {llvm.emit_c_interface} + func.func private @fillResource1DF32(memref<*xf32>, f32) attributes {llvm.emit_c_interface} +} diff --git a/test/Integration/Dialect/XeGPU/median_tflops.png b/test/Integration/Dialect/XeGPU/median_tflops.png new file mode 100644 index 0000000000000000000000000000000000000000..e6fae5f5da41b33d934b87702d571b40f0b717bc GIT binary patch literal 120421 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%0D=Qdqz4 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�cCO1F3KL5eZujE0m)g}dm%I6>NaIc2q&0CvIf9G67+g85ctDaeA<$KSm zspo&VWnMkK$j>5Zaby# zYtfCFACSsZvfBQwp#2v&{(m}2|M81|9IRIAmG8avHtV?m{tdpXA|k#CS^hx~@2u?S)8Ffs_7C%H?Ywac1wIReq))|M)k5`kA#Wa_ZFKIf2*@{-t50w(SMU)02O9a!&UySO5Mb_%Bfk5 zrT_o(k0w^vlwe)k&)<0SQ>D7(;auN;zAY=h1*acx{Zq9{kAA!PY4Yv6{@oVd4BVHH zweChI@`FXzp)OVB=Z7txU#HfgIsfHLH8J){2bSf(wq9KMEj0hkeT=qbZ-igVDbFSf zNB<|A?QgOh>Ov6mn5(`RdkABbY1_j;tJ(*#2d5E0FRJ&X+rE_ol<%)6>H=KL4)~^A zrRQc83O!ER6WunM@bw=( zvD$Yh0=s1DJYCT}gF#oVqJ)pE)x53D$dL+%J- z5I-Nm;9v!!`j=`(mh+;6b${*BM}<#;ey%D=M!47NA~qudM#DW3f+Xhm2NDxcA)1~= zD{q_C>Jn3~Vjwui{lncpL%fpZpy@0?!3`0t#qRmhoYbA-f(?FtnZkz-R9YNr*X8iP z7!U0DxCk1PI5LB$$cLd|hW0%OrM+!OzbQzHWk?8vs>OmP4XV~)Xo%Sgqbuuq28xEE zZBZce&v5fA+CB+cxzg@=-3PnoLZm?_!QlMx?bS{ZPu|Trsq%FmT%ti#hsdnz0IyO~ z#C6eipJPlDE+m>=yPoW-y|Qwy6Su^h$%*VyVQZ?-=T}Dr{%6HYGz7%1Aq#Qq5^D^W z*RH_9NtD&R*MU4%8|&cYJTcu{Y~l~r-jwoMOit;TA7H5m>um5#u*}h-nU~K3juq}T zgf>amyOriaKZa#7c-n&5vo-FaFdk@ogr!0dl3Kf_+ z@r@S`VB z#zBV@@D-tVyIJ`_TyOZ1+o&zwo%f8`nD?HBLZ(hYy34`lo3UdF`D!NE4iuGU9WQ@n z{|7jnShS(AOb491jL)hdgAF^4UvXuYpCw=uI^Qh5!XwtJmev9 zj~c4i5ONp33iiuwU0Dh@mOcl{*&zCaexE*llV#W^v~ToWcGEBi$fA4?-?wSE?U*sT zLcPMFh&tdD!!Q~x_g)bRTa_tOM3Mp|pCSE4UvE}1@K;R`Ql_D&H9 zikvt)omp@0n-+frz#S_#m0-U(an;}IfhZVO-;&J3yu@vEkod3n6|ZXgKV^lGUBup% zt08us_&QmA*&wHb%V0TmBtifnSm_EwW)^edj6^*RlqincB(bUyhwjoA_`B^Lp=B*GoP~e+UHsEAXxjxAJOp_#)4R z*$?;h+{B(Pn5oSC{BhdGCfZTM>8Rl{wx3t?W_H=_ORWZb!Hg9r6w%s(>5Je4P{v*- z;)<+NhD$XTm-mD^ftByh!YD{(BfEAXi2Gv=CIjT#C14O@KhMytZK5x{7Wlt-HMOJi&Dz+~F4NZMrQ zsP3?^ot&J+mmliYDx$s&pA5h1u*En8zl5M^L)mI@83S&H&IK(|2Xb`svm z%Q2<_DypH4w6v-#3QoNjYA-o&AnhjJx0-kJ&Yq3Cny4(cRJjQGF%>}8G)x~*lbH%Z zqKOPC7)(_se` zSQb{4_hg8HQ}uG*Wk^wP_{1_}LC=t_<>IrLA+xwSV?K}t_e=keaWiJ%#Z#&bJP-eU z?a@_^HR4*^Tr-dfCJR-G`-mp$3bW4`gh-A77)l+i2FXbb>2;W2tX;_XZ$=EEM(F!& zBlLRzbTI}UVV)HQW@@`uG%#=d9B`o_kqkT9%#cjMDuDy5u%{3tKuH05VbOMcvzWMv zU-`_g%!#0<6YbLP-W@ZcvH9o4E&xcdwCnYI4OgjkvabIg&#<0plU$+?#29$EZj8C~ z3`|t)#b{(^={t=1>cs~psS=yhp>>RET8?d)?Jf#1>CwfG(cwVmR&Ku(Ob4 zYz*ChlyBimu_2^cAOLGd?~LdK%+dIaLtHdDQM|+*L;b|;Jb?lbz zucYxwphYo^;Ad%kMkHfjo*G=SM$>mIKQS}h-s#dVDjr9lkhFnGx16)GvLxNb!4PLn zQ56W#K~MIVJ`{_1*qNBM=i+TBGe_JE*4}c|Q@2RX4oQOi5O;x9Aa1-Mg=+h#`dMv? zDzc*La>$7_7q<5O6{INO+ZIt!ix&15+P3buIHTWcNS12ON2ad=*ht5(oamqtxiGk( z!55p_HEO75kM5Ee*3)6~RuSL{!BQx2n6>ap#5(ugL1lm2s7B1|fZWxyZ5&b-ev-Rq zJLPa4+k^8g@2)k}`Rg*BfJdJ;+!kGnf5zeq!oy-_D~l09ewl8x?0EKT`KLKjWD(My zL-D&RJ3K9Y$KX^X@U}3VxaoqZHHL+>eL_^^avXlP5p6WShD|f|29Z{Jye`Vq=WAUvqe#*uE8fr~^A!EqZ2oG=;9jHXPrVFl({gvJ21Zg2lz_phd~f zc-vPIc9V(fQk01IDiEUyCQ}gSVO^*fHJ{SAg?4uh@EnCAcJ@IEKV~5{gfI?oSKP8e zp<9VLo>*>>kVhPw+geN(K!kj7rByHj3?_-o3R>oVon=x(7#PQtl}ac1!gr(NG0(e= zX&U`lOhI5q$xMk6P{DI2JZa!)RzmPSdZgng1SN`rOdsV!zO zK$fELM5ig*NKkVQdzjT8fwOU=m5j`{6?v`ahv%9smX$S_;uix(*q%l~U01gbWjtE8 zh_X@;^!~(Lkz`_d6nyC!#i2~JsS|BWQrLV;)vhAeDWwnZ9beF1QZ`_;D}F_t9J@vqLhvw!n8+TCI)KSC>G-AP5dXu6 zyP-uix;sM~6)h;=O zBxMN|un-#5y&F>DcynC%`^MA|Dww*Nd3p81V^UVZ2!K_-(I)l&_LmdSuza;9b*b?B z#CFf}%WbV)&)diDNb6E9Fe@gt${!E(2LFs%zU!DGgY4*;Cdp6zedxJz={3>0u4uLB z1oPe3Mf0g2;Dk2APs!O?zwSf^JnATCJ&Oyf$(k7gX3#hreK>^ir}D4V*%`9JFC?-{ zXP3F&#eQF7V$5tr@&^2$d2%5XKu&iEw3_=&Ip{G4f{BZh5W)uxBF8jdKweaYO*tcy zb2;;bpNN9Be!9G$%9#q+kzgZyf0QYEGmS}}VnRoUxSTSK(_cUkC`dd)_Y+y>LtI#2 zI)l3;;~%Q@b)I$j1mdqee!_$*3IcmH1X;PV-roFYZPiQ7k9j@fjMEM0W1a;7vm>}x(u6bTHLzQco|&H9gV-U9mLl7Y?oZ{dsNX;-t+YT*A|}_n zpp-ohAp|mw{5qcq=@cal+H6a;Ws{|-qPluSc;<@`3OTL}RSU-8o%cz^??gLXTy2gX zKORyNg+H}KRQ8rUKvvcM+B=)yCyo6=O@gq=a$|$5CrDAO>}cxOuNtCkXdSZfBn<;h zS&!?sXyK<6W-O>2-MFL$PG3zPXq^<(Q$oZbIOSqkAPJhFBbzAb|8{Kka1V`r+VgBq zP6kz0F)gR~k_yW=^HtJ>ZU&z>Zeu?e&rxQf{3_cKbDv+{7I5K}$Z5ueCzZJD_-~$hhZI#}B?FL1tpY`lH4j?a+UsWc4jp%|ENpCx2&jpWM zb{AzTjID1ppN+NgS@wH^&;=ETJxNsPQ4i6>p9b3EDf++s-RQjcF#wjc=g!qzRP!4& z8q=Q|Oi6Jy!QSe5H{K3GC}`paBF3+j8=YFUHHMn)vnL6lq=tBc5IVv>HGJOx>hKC; zrE1A9|2BGNRRXL9tF9CBj?NkDv0kNAW8!9wb^n$XVv`q3w$-RTt)mG#Dme110JnzzM3vfgqA1sS$y~ zonh}ApMO4twYbLXC_bPGw0PIeNpl13T%?ynA4T!YCo!a*ADr&r&$UgkypuAgI>ZQ# zl5Ry;U*aB~og}{5iSF2FshF9tm8gL-fHD4w)`Vfkcl5YfRy1i zUD*wB`RdiMo4qe%48h1993h=rXcm7i1L^`1qY>AHog@ebVlIAx*r*`twep>APA40y zYM3-;j(JZHKnJ?r`(U3(y-W7l_n`#;c{~&trzwGy&=&igh z=H57Y*+lfr&saoA8tv4|D?B2u?(trA%_1Xcmc_gQ*i)*F37@ynQ=!+=W=)HJJA*y7 za;sdTE5syyozqjBAFT4Lw?dz{plX2C)M<`6Ou3j}&OjjzL3bmPq$nd}D6Hs{GANBf z;ib$nF;P$|sL)Cl`@wzWIc>f0L3@OHsm1V}L)L1y=q1ZqMjvmPyL^<{#;u?HU*61x z7lmntUdXM4v+LH{cn*$?bKH=6*EZ>oZEbUV8t-)8ZQ<;!O_4Ev%yoN&2x3jl2y>Az~@(lwtt@ApkBSjK%C8q zIFM0o+ayHVPmc1iG0yQGY94tdeEyad!%Q8f#!Sodu9cJT@_yl5dZqZl;9w13-PX2S zv#aEMOtFh7IrKCnHm0QRw@I=4Bb2DL1+El34ZBVWD=oPO`Z5zfrq8>J-3ut3UWGvZ zk(CY_)fQulC{E1@fiJ*i6bd>-jTzpb-o{?Iw~s)iu%5oYn*Cs+BPfnIP-FkI3i6WW z%7p}#Q<%u&B2rdfEpz0V5&-wJGRmW@P#(`JgA?Xjo z4xv{C@1ip8$Ym7gefsoSvvuog*dv%QOIP3ZJFZBND)T|Y+Y~z(y5Adk24~j=n+ia{{J5jd_a7I zdJ*oRGdGUTYEG}Dui8%`MwGL5tp^GdqrrkF+W?n9L^X!2qX)R!hs8<6Q@vJv#IRsjpIc}cmDBl(fz0c-3@xoT&!G8 zD<;M^?1ApQYc_k8eG;x4zD7@+?rhV>`G`Y;!QpxBr@n}*(#-JsvAvc$J#0)PLblv% zQa(FvX^Z7mb2HyAJUJ$H>#kOQ`Mt< z-qr+!u1fy|TByX-gi1KVyPK%pX?2)#jYpNUj32 zq2k9My0&`iv9(EyyV&nF6D|wlW(G#XyXfAmzO3bf%g0kvkkP4O*nb8TyHIz1a_=j1 zKW2U2xoekW%Yzy@mb_?5D54{U`z`U!Osz`N{EjrE^(JV=ou<7Yk(zVyAP0n!wpr{n zX4`(hSr9Hyu`nr!H=fY8hHRdab{#kXRK01R>+~=zaclyhr5s&Rrer?n;31c(osyEf zi0>#K<|)}CZzn^YLI^<-rGD5k&f4@@(I}2BR+yS9&#c}Zx3hx_pK+`iVyfB2ku1fj zhHS3~T)B~sC029VCVE(RnHX~Nk0gncU{9kb>A=gWcI;rZ#4Zz^68nXp~p5BavBAYQeN>gtfFdflkUmTR^oG%OP?7|K-a3!i9a!~hVt7QMF zomkDc*sR$pu=O{^*-gf=Geme^Xyb*b#0!(XH#55aDz3t$)GR`^h*pJXizu0lm<=5L z=*(PncwKtUC(b;0`g8^4YV&P+B61AuTH8JERDS-*eR|Qs$BLe{it<@P9v??tMi>xJ zBqG6bc2SL`(o*fNd;IwEalm=Fy3~^|Kz&0PgXTMWd!CCkv&N-N0R`pZzJR0D#Umtx zQbzQyDZYyk6U%ZS8~`jsv&;kgnSjk@ajK*&_Q8_H((&=?&`_nKIln5rIyyXRN& zX=2J3%HZfj?GLxzc!b4`dn{|$|Crv+ua*M#W!1`UJj%+67{$gJA>ZHUoq z9|h<@gh%4KwQHNc*N%L(eYc^*p14C3?|xnf6B%H{aOyBCs{x2xf|}gtYRHpX;%bF&rw$#`0b_!AtFAnJk$K*D!rPc)badpVaY3U4IRD#-&eDCd7iiBL zPp1owWjhS6(pBilkM#O&{&drGy=_w7KT2-BHPvBM^cH+E-8MAYp*klZvqL|N@T9Y= znhscYpFfgrv_FTE^CX^dv7i0ez#%}H5X147ZaebukbRoLL)_eAZogD0WDlr}=Ln)r zDbE-YpdXiQjhfe$tEy^Ewg0gFoOZOygIm?J9=6skLT_)`=Qn=uq*3Pcitg$_c{Bss zB$WwImv9!>RweG&0o0Cy)(bFz(T|OXCVW*myW-F;E*~>z9=Kh$S*BxP z+Gkel>`v-k{rt%$aq{CCWXR}}z6yU2C3v5JfeJ3&X{lNnCT-h)l{feRWRFic4#-lR zKS+GCYIqxAGGp|qPGrx;vI`Pn4WOm4hXGqe_%2!(im9AeE-AC!1ujJ2(w`zjd^fsG zx~#z37=h1ngslhG9jDYlfmvxAZ)7xd(m`2k9KJt~5=>@7Frjm4(cZtvt7{uypZ-e( zVDLbf9?@Onod@kYlqW2?9zU>vw6qHEEq)(42GXQs1|p1e;&Nc!1F($(r^Iw3D|Kd4 z-T?w@(<0UZiPM$jB2ImE#gGjhlqlu~a(#$BHG<44mn;z#CjGf{)s<@dLSC>W5^Es= zZm8@=KbS>P4}$X$SrW?n^_xGo@~9WarDd^ZoNt~N_bw6pWcln|vH)z<#i9kqb@Eo1 zFwO^tJ+ecU^$|KOh4ZKJ5DOg&uB%w$gV~08{{b6Qh!gTlC}WpFzXkVF<#omWc}c!J z)ZDR*X`ix3nJA~Z^Kwu;UN3JxS2Zd1-GnO+J1gQpdenw4a&GCmU%braFT3fvCjyXtUwGtPC)Y`nYJi@!bv{%BT+DvAPAI8C6eLn|f*)B{&qN|VtL*(` zj`2DBzIcru;p6xKaLL^25AqKigDqJX$5A)wC$ zMStWsXmQ5mIl`hAMm(( zD@CYaQ!-i zI*c3+{=`16NMukJs-)1ph`y*I9}h}-%>O_9F0)_IMOJKjQC{7drD zbWbUMUtXu-bE`L({E9dCes;1w%jgt$&u1JfTt)O!#GP2Z=a>*^pY0L03-&}K4o_{w z+LvvwX0CW7+Ec`jqH8!j0QO1cU$$x^RqCz%O^vw#O29Snr{?E3idkSpj*^ikY_1Cz zdrpg>ke0uUYr*?m``hkODV_LQhjdidHXbnGv_@XvA3yF&S0RRmcShlGtIp!!2ea$! zuuQXyd8KYK2xRs@o}ri5ON+1DTq_B==kGpx^J<{Vkc8berA_UjXITm*tcH1=QnfXh(?Xxyx0)7d+MgZoSja$>IBSH|CX>d z|NV2;gKKger!6i9!bN0fH=K#m7Hd6IRiOkQCmM5sd-Ok64-wo}8$C{`TvUDwq4 z`)?5qJo=eQy=z@jR8mu&CyYVQpP41KV_on}T?%zM&5Qbkg3CTJtll?3I zthwobzUwWoO0ReIHj4B=y*E0qUOKn-&yU@5&H!hH|K6o5jLj;a-sFu{H5w*OQ*Z4W z?YKefLS4hvKcDczlx=mJ55R8u$FFyKrG2=^5iF2S>*<7rg;iDH(w{fG#SV}Ed~oVt zjvScW@yFYNAm1~+Q58TS=big6#UI}BJ1Y(k575(rTq<3OJh^{Wb;f*R`QJatk1z56@`$asXd$0J4E6H==^Nin&L5V0phUhvC7-o$#oBGg?Ot!PFYwbe zwDYW+dwF^Ar{V|SuPA5n(PJx4K;;Jv*Sb<=+8`4%=Zs4JeZ)rXXWK2`Etb2tCZLcL zaYF0y-%dnW`(c-gtiA711}iBH9ru;*%h*=8;k$>Yzlk>@X4O=(&9V+%Fn#UppHCos zMhOqD7eecXZau85_dR^^x0nT?Ke3c&|4dq*?e9TEsyBI~UBasx7LJ93Q_`!pMjG&! zQxME#Ri4zD^3pfooYviE%syJUx{ zG2gO;ouoOCJH6WN$I<%n7!0fbMCSiL{bQ{|l^T+Tk>SIm)Q3hmMsCz)pyKe zN(+F)qM)nug;(5(E5ScQM_knYNyzHe%gmaYT3cWC?isa#y3MrNT3NO2KL5g%QI|@- z=%#uwgIY{?E(|8>Ad40nRFfV?Td$0|N7uIvz`v-S!M8VHWW{E0T6f_=@#|8WxPSGt zq*(@Am*0)o4L@1-YcoZ%dErC!&E#Kz_0~oU%5R`AYjel3+x+O4yLJ?dTr>QVQAP9K zC+SRbd=Vcm9oM^8uNbI@yXcrtqd2?d30oL7dC&-`gJ~JCJHEUs2` zG55EJ8hbr?!k$;tAwz2ID2$Fur8JQOlNphyH8YxY+N8<`dYB1F8QFF|{Nv(?nXl;~ zq(o(qf7!cl_sY1H`WMjzZWGVv5Yy_%DXV zeIP=eksbEzi0AnsuT9E)BI7!+y!H9lp}^-pq3@&&>OXxXJRmV*#9}1nm3g)@f5`5+ z{Cwusob&=jy zAzDkC#<46pMT*Q@Y6=sROO%bXh4{IGMtd~wtYF+a76ekr|FGAV(nLQ~~hw0WI`j&Dg)5(3|PN z0~6C}Z0^%Q4FY}Z-)_=+Krbkj0nyQV*rAke*^^6EX44Ubk97dD@p|7YYsJ%neehlq zVLP^uU&j2A#|H*%)d5c`D)dPp|J;X7Ds1wc_eYC9dp+L-)*~$*eRbxgeqZ;znrXQg zNvx2Dq!oC!E2@992fbv)2pehdJt`XJ!0DF7ZuFOXGjA|tuw1$KC=};t1|qZbMNLcA&K(EebFxo6chLJ)w2Iph zuin6Tjf)qUE&5u1vA~Hi1{{v6WQ~IpVnTzdj;x%itDJsd!2ml$dcxF<(Pcm&Gp-dp zp-&|y*?H*z%!-344Zh4E0V1_^j`NBHN8GYShes|e4069LuhnP?m_O7J6a;vvevJ{kFrfuOi%yr{OAc~%U~BJ_TvKOd$Qy@>Y!BBSK5LNhls ze_LuYkGfgYrlv>LzVYv$o_x+p@_hGrRZjLeH#dceYqY00>-!5k!E-fTUc~dqDMT$i zC`LYfG8q)H8$4!LRs-_;&cnb+KXYc_(Q&>E5%hKGs$3c#S(AJ&g?WNppF{4U95KeW zRyxQMjdlVXt8`lB`fj%C8VKI!6vzp4|@#s@10Og#6 zo~Ws+E&&wgi*;a&yj_A_O>pgoJ!a}jGNz1!>v|Q}ww5hh%7#MzkX8#;G8W^K$~A#P z5N8*!0smEo$|+w&X&|I!z>F!Q)rKM!vpl!155rluZpr~=aQn!4wm`~kIF$Vd5_=)b z2_WbkOZgV2`Q zk+0P1`}J(|BEa$eCI+n;P)AS>WoRu=sCaH{Y)oDRKV*B_nm3CbPWt)6Mj7}ZnWxEG ziu%}t9XNb=8Lo$r6~uWNru5)vFWS7OprxNQ#Nkc>tZ%nxL_I!)*r`1F7{Urc26d7V zMNv=pHYsnPj({A=`#uv1#J>haYFInb3!%aZg_DEu`Y}Pwhyi7&PGu7XVBq z!vJ6+!$Zfz_x>^#YUGhSw{JIAh!*F>`Ww(<6&zZTLZc5Uh5K~x+(Q41<1dEW+CK8@ zGPNSt#RUp;NM@)VkLCXZKF_lXW)8x9XD;WZyV~gwe4t9Pn<}CY$=S@@UKs zq9E~X5pQnL*zJs+GTM7Xt)akp@Zv=X*)9hBG-DQ4j;gpJi8+f* z>Yy9Ryj$MbwQI>k-0l#6jX%HaY!Pew9zPZd?+_H#F-(w|g77q%k;=pvVTaIlF+JUQ zD?17UZ-;%Of_NVf$y{20^rY?(#1*#`N6$YfaRReKv`#~d5PKsbzEBcA0QEhJaaFw6 zP7g01pt7neDk6xY_L;4`Kg;DSP7RV*{;W}1gHgO*<_ile2z{Es!n zGDV>I8f;6Xwz7>Y)6&EfiOTafi+%`N86OLZY#0m*U5L;9VA0plO_0GEmERpr(nb%^ zx;Xh9J5p+5G$dgZ#R7u|kqnGV^KqIyBO4=G`NX0SgXc4g8dDLdTq>@Zd{0&CA1T4$ zY-HeWUJRD`kn>hg<=z*_n2=%Hx}=GncgB;YFXv71Y8!pva^aIFt?F07R&nWuYuv^$ z_lSVGd&|7A?9{!*GjM%CU|kSItE|EyJ4c*iR=!BC_-owSqFlR30oezuIEx zF57RwM@?_!G3Epn9LV{;J#=o;qW1l~-p36Y*SSja zS`>FLV}(;DMM9*Av zf_6Y8Te2>QRZ&81lt_o-blclcjN8(wSFN#iian@fhw)4u_P4YyUtnpe3P37G|5!!$ zZ`eu}pA)a8_+?>*EX-xj2Bf<-!|g)CAI-xp@147#)u5_{9d$Qu`7(e_c_jl8GO6I$ zRLr(FbTu@VKyY`H3Bax7-5u`hFvLY)F%`R6-gv!_U*SF0)6jT(eHM&}`mD)-f-I(M z8Oxv3&M2Ae)4RNDSd(NeO=Ao-xTZC!dw$2jInGC=TD5I_QPHxMl@#rNqx6>NEoy*L z;NHM#{O&=}F9GyRuB)w0m?M|e^@07(ua1QX62wjfbKy9f#&w$*XOeURpE-(`EB8?d zcJ-@Doz6~Ep~u`WmP?Jv1X=1%8njkNzH(zE zhq*?q8iM7JI8Lu@*s%)CPOV!bWsAU~uNBBoMYoj8I$F_qaCC`tgD{4zKgMJ7YRzAM zQI_4YA*#DKckUFMl7_fAlTb1Xfj~;XD_yo_cblPpOroelXrR7q?_bvtUDvm}0j4d+`t_a*DrFXBD=J(~;ka6$czekn3 z>-J&!om>++{mbe$sjLv6^&CBFlu*S}rX@8}f4=UHPyC+1p*Bg`Atj$39m23O)+A9I ztUSH&yHS}e!C*$iALmBOXYzGg?k0Wt$7HLojtP_j-gQM zwuP9Ythx+%Ad6C&s9Q$Sw~4RM13F65cfYZ0Q~S73C7?E z#l3snS42ie-X7amAUuC{hVNoKDUPiZhpC6r52?@V5tNpLHBR{OVM0{Y% zfB(e`HL_CR%_@qpIu4PtsIH@L*<5*3Z8oJn;ZlVipH5j>sUk7B^n~F@oBDjAz(~e{ z;{BMC+%8ym*qzp!-52h;@@UB9ef!%E3e#*D{PxWo>#{k>`8G5x2Em_mz^7XE^N#<3 z;FIDggc?+gWaJ{#Iqo7ONW-ZMX3aXq(N(H{cg-`18Wa<1owE>k-dnhb>TUyj(geRx ziv5r;W?51)`qAulF;?-{INmAFu(7P^Awh|AjST1+>**OA>k^&Uf`2w+rTyj)U~hIDBD{ z+Gwp-9szBe|9VN(6<1#IpcSgwT^VqR$sf5z1eDS%qnp|PzE4q%{hC@6Yxvx!+SY6k zx5no13TZa4rnS-apII`;23m-gSch!cviJROk1^%bQp`ltBvnZNqE~QD4PSb&{DtJ$ zdUP9;UjS^XDON2Cx;77zoFb?CJokXpu&?brhupkVm}F`()cZo~;n%YrKl(+QH>M|$ z=R~|I7P%8jZZTj3b%64*@A{H+n^LnGqGt%=uyg3IlEWppA`#e?+boOeHKk|Tm3|{Q zR8rH6kc*W8Y)8ZXMjTW_fh)$bk}xCe0RN4GG-v28?_U8Mh8x6%eeCPlP5%!zZNMw; z|A$r~f8v2x1XEf6%!6A-Yuvg|yWQh=clJ$c8(J;w^_*>8@*L-92Tjds`3>7yv}KRG zNAaTSyrJ5FebjD-)MT=Afzlb?jZoK|R}FPMtMWR0RdY>!?^O0c%+7Z=uQ^m~9vRUK z?_0Kp0V<5;kZa$&Hp9b1jSd}O@Ksw&+KJvyL04@bm<^j)xcn&&mpUOnE(MUNT%b_3 z>Lj1L1=(#Td*>Dm1^^UG24?2X=nh%KkWO|%Xt;Dn+NXi97bbb^`D4SzosezQA$JXS zT{8uIMMD3mCbJt2^?IzFQ?xq5{xDMBrH2i3QoZawCoY~kWqm??hfVMMIGWF|b91?= z)A@`?~j`;fsfnA5U0!|A8in@uI8|e~^Mi zCVfdYHM7ruOn$3dm!;+K1WsRxwMv9iB4QYgpsKt~GKu|*l63k8*qlPCDSea70U<<* ze>8LkO4pj%kwX`=YloIz86}Du7~ZO#Q9-TGmyEjkc`v$Hki)>%K?xrr5P^ndv7u{e zHNWt+zPc+~pC6|b`+1bX#Sgyk9@q9?_qin+8s}&8DNt^wZr(9}WhK62cB|#cOowYH z+k_l0IswN?bT;kNO8dV^d{%{UEUtV!IJQEp_c+;nJ^r`oypat=9P7Hb6D_^$Js`~n z(9p*QJac2inGG%O18tA>IP2qZxPR{93hpq%u-zRj`Yn7rp6*wLrs52Lzv~z`TXe%P z=*CLJ0_}(XOTBU9m8^xP?e2f0h`>(r`DJuy(jj@1tv45}$HW5#X3)o`j*&@DDoIKQ zslZf2yo1*!-+&;y@k%y5O2UDm^Ox`2Q`gBRN5##l5cZ-rxQ7r>>7>B?HzIr>V5g`CcwT$dlcA?lCA9?D%XSK9k^gbdO ztj+jfApeTXG3GT!5Jll6Z4gv}jNGVo2Ba6FMp_HXAQ$_K&szI=C6bw9B z+9=cpkbGQ{cikR}^V`OT-KI9=p~UCiK~!i!RN3D_598G(v>d0dUq5{H>#}J;4K$+( z?^P^^BB*Jy-{s`8g9qotZ$(o%L+CYdJ{$I&y<=wQdw5^Wgy8@i6ZAopPplHh?cOH$|?Yo<`X|*LX^5kXvNXdph zch>Ga*#0j1`V*ZthFd$(HmoADN<$gP$h}VE9(vB|Ymz(n!jrVaaT6V4wY*UQh?qjM z-nAY@tbRoDEfLL};>~hi1&FIG2&HZsNM4uKA7aEw zdJ_9?;)2WbS!+cZ^Kly;g}+X0VEl#kMqe23+h`slru|W0nKT?3>zZ4blC~&iJoSsiPB{5nN__aY~?R9={&$SXuPkBGw z2X?n^r=S7**>rv4^L{?1)(_^LrA4exf)@OZvUDX>%CXSJ7>xSk4MfmbPQppM=Dd`3 zC+tLPkLOenjoL#nE)-jVq&*(Fb-~beZZg=TX)b?zzP%jq14r8{Ub5DW{xu@sWxkG_ zFx4sv^-oS0X>M?E73&+*cRfx2!h4dq}V5eH# z{-RVpSx3T&c!11G+F0mff=r100w;WZehFx3AQ;s^57#M6swo+U|KBh}UHzw0ugQKq z6uOD*O%l^xdKwW8U1oQf#5?cu+_I<42^xJsfi|MR9UOJ`M4ISMP-Oxwvy!E8bIX;wG6UPQc`7f(0K+6Zw z(p>Zyy zD_hQr*TB;BP~YPxPoBK8*${U7qcI^|G}O{#3Knvlr3#a&I%5~F&1>voZ&}8=Wd#c$ zC!<8UdVJ)8XuHL8oe{F!`+dRJpcM1eD%a;RQk#jxu2|cHsp7H})ZbL0kX%inc^@!G z+8~j>0kh%_)uw(`MKswQ0`nkbo%mA-u0bWdjUs0D0u@JwG0d*Tm4d6T*S3bCgStZY z+sU>z!gLn%mKxDB-AlFwa}2(qEU*EthX9m)7F9H6SS#Z# zQI&#+M0nOBTm8;rBSyU|*d4?c+p1s+n`#)UQ zy4E_^d7cYH;LGvN@^fUWyL3#*F2cPN`(>2FT)W&} z_;l+@S!p%(By}E|f30|CQ7?*o)rH56W20TUW}<$g+QC{$M@M zi5AwQ`{O3&9hV*aH{;5axow1dVfU4>;L5mOdhtoyY=x-0W9?Ff%Mq(htN+n%&>>h0 z|E`SHHcotSe*B76g4p=yumA0j?R19Xi3$}>MOcppK(o@TYz%1`7`tCIqMQ;AY!#i3u zpAh+1I$q|6a|*?{%eA}){TGbU*e1>m8=cWGG;c-=UY=I)>_^X1zV#6NaHN@89feq9 z-P*e4eV72=3LV!x>NYDByySCb&^ta5+%$c&j(55h#;sG?b)qf2D-&yEC9%y;> zrRn!C*5m)kiM(ovOPrhn?``{^8L!_Nk(Tof`bMUG{K5V-J=Unvo9E9?3PCTe zGeSyU>R&j^f8mLmW(}@-PED!yvGrw_q}RD?+#s))%KV_L15ZY`S5gS$n?=(2Zz;9K z!do zZ5X?^2jB34G?^+y6}tWeE?Yf53BE`?<+5*{PL^zUsHi4BTix zdG7X~1YePlGMh63VochbhCq+DkAj*bADuYRbn9)-?2&YKz#CMO%iMSm*$k{yN8(C= z=gi-9c1@rC?_GAuBSpY87!6{82P0EpcM4gw*&z|(AhU+#@N`Iobu$@CSL2$7lb{FS zI$-2);w7|7fnuV!H21sL1EXE7I#u|enBj!YcXYfEG~c)nxg!Qzg9dpOgEUu(TI}G^ zpM?CO(>`e}b1$-lg$hHBAn z#)U<~jXN=Vd4NdZX>lNGS)1~S&@9*x+MZRU^`yXE_2&`vgc=6Ztr228SUu=W%))ZW zj$~La48cffFR;jjlmyuW51cmVbLi0J(t;PSv!f$@E6~y^Gt;BH4+Zvt_RS@8A#;gE zu*^W3GZpXu5u{g9>uR?Mni=1UzSr@BrjOm2MEtC$hez5b_-_h-#tQH3> zk~cA<)AID3e^P8M=qPU{J(n^-?vCZK06^dCUJOb|Bu9)MIXOB{Oc>a=_Q~?N(2$T$ z#mp^zeQ@)d(n&&lQGST|O-rA%7pO7C^MTjV57-~t<0f(TrN9NbYz=tQ5n$Q%mFh+r z%qIUyoN9pEo>LSnT)6xQr0GCZdFWY-AG1X`>Nt%a`a9`O;|!63$lHSJ+9?bCkHp^z~O z77zPjG87~>x$hG@Tm1!N8`I*C6i+DH%98({SqE>`Vb zPd*7aL*_`)>5O>vXw3VIYVL6_yYeQ=Ksy?p{#TUCPmV(=;tdGEcK!NwLH{#XfNZhH z`cVN$0cO2STBFPdk%va`sB4e}7TN))gzr6i%bqu-hJk27RTDwQH1gRu+=Tk#$oC=y zYL*HlQE@YieFgP&eeaVep)JU=60;m(ZVue5-{zU z=2YFn!;=wfUM7r^IkjNh3tCY1vJWI($N5fVUitd4tRs2PfJo?PAAHU(rZm&&(W4PH z9%ho2Xq200zs=4TPkFjZ&Up1O-?aXmMIncqV(^F&?c<$S zuUe(Cb+C}_1erkIw~CLV)36S!P4qNkuOvcIx-9pxApsW~k=>B26ArTrg}P`9pfw3k zk2h>z%o40B^)hw8f?Ua|GRIW<8*hsS6)RPG#*Y$&SO6-P>vI_Xk?@i!ZL7luYsBfc zW!YUsrN0BH2>uK{6+z!cK$GQ#sY}KHed8a+X!LbJ1Da$!Lrx71rQ<8@2ecCX&CEPg zrb+~Ywk^isxEVbIM)F+Ni-?a|%J1|YX_icQ(@=zs{)5 zOg>?0uP_AsKG!rRxe@gEYSpT3zw7s1yg1-YqeQ~55U_;P!Mrh!hUUNhHhNw<b9;Q%gUpqB_3H4Q>QSERNdJ$lM%n%=F|F#G$ zQ#vcSV7LD`)tgD$!tLhhR~EB9IMWOfa6Nzid_*{KwoJ2=lMH5oym$6DmcXXP%URP= zY#j;Pyas_yKBHW%UCz`Z8JbGlh>tUkjv>JiI}1rtWXPj*@VQBuURLjJJT$cHQBf^g zx2B?tn?PFAZ}Maff{>(6^fUZOsT!wmyogHr!o`b`w2k2kUZZu>rJ0NOFy+R5R^SV< zr_0P$FoRS|_j!A}u}XXqVsloSf9X3CIZGhJec$(;zrMfb^3U}r#FSFXf)NqVr;m7}AdG>Y+=WJT%);oEfQw{9G}V5Au} zm3N6%t>#wkp&h@Ae=sHp8aDcz=LvQ3{=MF$X;a-Lb3IOV#MVGG>XI#CehelgzL|ad z{vI(q`qnLJk#h+$rxIjd7^7UBN^z`CWbAaC==!ZagKse2p@F-eKV2K3O^j{sq#ohYgS&UkAcWYXbRBq<`@fL#Euh@MJi!I)uISURem z+1sY^64N)$hU}Y7VCNKQB@^5*1QW6`IfGb2((as;5sbA4lfVWaJxTXYU0_lty|xws zzhDY0T}Y1ldY7|X#>80MR@YQGet^e3agXRh|DpTbZZi*JG1KFt14#>o!$kg|fg%V3 z>-HuuRsurf>iGo?q_& z=F1QEr24QK_wkgku6PRi7q!5!vJ!)yvH;4UxS2RxkghF#?;0hmiKhD>uOoctd+jl zuveajvD(01$&Abh+oGa%+(lSvt$3dw1NiiAV8zL$P25vNc@NssX z%?z@@yjrq;+MTy9&$w~rA;p_CNQI^JI?lf;x9rBYz58{^1V{h>-CgDDi|>TGk|xE;ZGf%(tYOpin@H zl4_)Eiszo+^v)*f-n?;RfOT#nAl1RC(e8~A$M_Y;G;1H;{Zyc~DXO0n(&62?6KLb`&fZ8395QQ>-`WT39ZfYDZ*V zfOCns!|<(9ysNI^RlZ2-R6L)9Py&=7?eqn-&pXF>wiH(}veC)2W~rb~Bfq_to~};1 zSl?jtoH?C)^w`BgG>j7VCY!1w;sp}*UnkYV7u%3e5{DIs_fITldW~tt`~W%}w0z5k z{>l6uMecXzG&YKLoR)b_;~~rFUonn>pdtq1l&6+otlRD}%?()+(}3C1Ye zi@0ey$=Ma0`8hn8h`@@EXQz=A3hyNGTsK0k>%|ivKYo;jIHLELUlcNUl?*Cc)pA<# zl{>Sqluuk$tskbOpp$4lJ%Z+k($`5%4oX%``AHnBm6lUZlXD;a$flwT*Af{OHORp< zg9KSdp`wPbtdM~yC|@LtLKx@zmYnr>>itNDs)(gn$UTNG$|OTPQ}0u7n^|1j({*+$ z-INp(O*6e!cnDhujyqq26yG&yE+vZ$!lA=+w1bDtFkP@{(SY&en{w{DzULH*g6uGv z#xDe`(DXKspFK=p{;|3UE7+XUdD2-pCVr}yLv@)6NzzSIs|KB+?HE;|zw^U=eO3%U-!Mz{Q@1;9?r+RGd#LB% zvCuZRQnr*_oI|!}->t1a{a>^Up0kaoA`r88{yi{Im+1)G9asBfqbkmA_s3dONyIOs38|); zdXCr%1!oFMPy0!=pi)z<8e!5vTy5>Nfq2)P|Z54B>z-0yr6tp zn<@uC8Of||f7jYmQKLAnH!ViRucu>rZ@3k~R&te5$NQWLvp16Si;qggCsvQLw(dMt zgC&&69SB`7GBY#isJ7d-)8rrtm5Oo-<+PC2WZoy8?Y6yUU?XF{`i)_R?p~w_=v}p! zucs3ERW|gP+XKDM^r}B{Of4BKLkLrSMuXoX?6v9O!Ru1g2l0I_I7*?#X_FFTwq19S zO^Ws#tXlU6G8#UfX{oZC}iT8Htx8nA|Wm=YBenWOhN?30b z=7WtChRA*6`fQr!k$33Op5O zjN5oQ(hel?!qRTWSyRiwrqY)1qnJx|Ic`sY04UICtu@R)<(%bF9$-gCtPo}h2q_f6 zfW$8>*Y#w!5omZH`Rv=b@x_a2!X_}xaH>dJEa=yhv=A5{Qbr~mD7^SGE2|2;XmK2+ zA#IYJL$a@d`IQK-oR-@NFbxkrg0Lk+@y^|E0fes(uwfbI<9m`y$OwG&$p8;3^h-$< zM9|b>`t61?4TYbB*pN zp+hv4lkwBSY0)>6C?K$DC??J01uQC zQ@k-*I|7D1cwo9S1ZtWa%3e+840Ez=9NEDZV)6RZ?pssu?DO*S&$r`xB=sTP6}}L# zh3m5|ka|{>mMl@&ob~Bz7yG1tjQfx?7aO`n6!uHdt+Ht0=Lu#7#VwO3UOFGk%vrp7$8e6?vSV+U8-Oq=TllF&u}yVvm2hkqxm=H{H>1!j;b z*w1eGDJy=^n4TwX`%Z@BNRzfJ%q6WQa~^NB5fnVc8FIeJ7o>;*C#{;i67enO0KX1! zg+*u$0HBhWjXIIaTWAdlVGAcV`8VZu{E=0JPbh)a@V$fQ;jbS>Ad`U!t``%LsfzEh zQ~}m%6&3+})et)^j2o&|A97{l4bqT2EVDx+HVdsgz#(uNn;s>i_r)ro$<`>(JR`ct zh{H1;aG}ecEhk=Sw>Nl{L$3(d9^>hS8wd~%0}VEo%(NzzWR&pv&hRK*=L*B$Aq*}Bb7R~=3S1&4#XUnNAvOjZD_8Y6&g3AvVGAgx1e6l30->^Z z(d!lp_o^uY%)zSQB@<{VBwp-tbL~ zMvvanA=z->GuMWXz1Piwa1Mb=h9I&q;L+73=DYS?$zoaK=JuQe20K{v)1g*X`+9f9 z^TR*1vi3de$EiiJ*}rM`?mnr$dC7{HkXtKOPBYi*ueYo^pqA;*#Yc~w>9s@mn_tDC zC4F}s^e>5YE29q_?RENppp&*pdUFU(FWdb(37%LT=D$g(DmD?oGw67vpuMGbk;DuQ zivKi@1ep>p4y+(YeTke4uu&H`W=`5V^F9a4JIZs3=$fuLK*i$U%(h)suH{gF@W}wP_rpaWvYenk;TQ(*7j&zaN`82H-sQ8id=?90WV6MKuj6MZJ+bQ zBIH6FV-hDRQb@5~f6qttp7Ao71nLi}?UuJqI}rtZ7Y;BzQ)1J(c*J*-t#^=1zU1P} z7OD)8E;8pehyl+aA8^PN}THO zYcmMDq_DnYd_^9I_*s>7NMw340?_r^3IG+6X#i?SqXr00b-ICV0NETx?Y6fuleS~) zFLT#P)n%A^o%Q{-e~q5rTHHS6D5OTWQhn){6s$`&Cd^E+kcn94tLtVns%U%l$+xWf zdf8lpiiU7;%j_oRB+48)xa9nLrBBP5>_rMpnf`O7KqLHcRGo|BO(9KMIfc+9Sso1O zyL(IK(KCxpzIRS+|C0|e&u~*pIA>aaOiM)oD0L}q2yn5hXq}ILxEcIRxL=r<$a*1O z36;xr>h=Vu)j3bdD?6eR@ZWsrzo5hhB)qipg0%WB^p4?N~N|J+0E_UU5A`Jv*gPM8zPLf6l`Z7Gy%#G zZ3SFpP24#i`7n?VCt}-rBWRtlOMUZCV`3t^Nd_D}snw`qLzz$|AP7`6u@m*brKGgG4IG{sIU zL6!X8g)H%zl*2l&W1l%8=@B(A7*a-XzgX=zU}@2M7|g((`(w z=|{CNg_X&c*d6g4-ADbzO4@IwA{9&?nFOfeXxsNKwsDx-S8{JPt?Dcgy(hKd;CV;V3NcTME}%pCls7E)x!~?)zCWY2#cRs` ztnxJCoXEXcQW`uxAqLa(I}kK*Z>Mq}UH{!`lEC}t)!S&fZ)JOGuYNjS0bkn$0N-_Y z%+;VU*t%`oY6y}T2^iUQG)!$M4(lB782}H62;{I8a~6Un?yMyzp1gijPHbhxx%E5Z zDrQorE`Hv<69t1xlCsO|;I{e$6aS;@ukR3J+C8T!UTLF9Z(huQMNWa8QLu;7nG|~m zhwaJPIXN|tnFnxt6YImYj{=jC201n_87Ps+u6Nve&vF)UfwDz4@y&~B zN^!*KiihWX^wuO6fagh>T>V09kvkKuz9)Olhe=Lf+M_MFQ z)3mq()Q0>=lUy;uB``z)l?v)C!V1uJp}X>Q9*~~-Ha^-;vO+`(+`22CUH#hn$=pEl z@SOuKN0$`wvpsM|-~tC?%_-jtf=skfIb|G@d#+U;jfR8JT_1(aZ6a+qP-!j;EOVl- z^Co?=(Y4^Sli8uRPtLXJ{q6HqfzANZ2VtiHR*;#!9An_>g3EpVY{xBLg|Pt65XnI= zF2BS&%k0l$0$c9b-2or2?-pM??NN@Kw=*KDs!Zskf3GGPKY1Kx4pJM0hP$^s28b>q zb3rpW-9&Q4VT1Z~Bd0uVa50dGAUwr>9n*5cYMDcfa6{r91(l>9z@)-i>5dp5Ho=iP zRXwJVUlA88p{N3dyYetf$z^Y^OxN~)FS@n*x%c9z-5s|*6EZ8YYbp^NdbDw){sTJE zoRyc!DegKK9oFzpjFpCmahf?)f*w=NiU|vh_dLRA)#F#auiv{@lYuaTjM8nz*@3Dok|#Dqved3@i@In-FIj-acuS3y-y+h>|IY}CjX_)AFe6sG>Ud&$_R z#%^yTp$8Z53hWul7kH#96_pO;8aaP>5hGv2IDrn7v>k#~WO~Il*0vma;%Ceah}r?m z_rMMV&T7f@XbNfRd)lRAg#m!OdCGd;M?JT!a$eKG~20ae6~qs84>oK3)dUto9 zmEl3d6Av6q+(5JYQlbU7{r;HNIj9Lg zI1{-*%?l3I%4iL^q<*;No-<_dey&w3je~6wfut`HTi(d|7^Eq%FE7n6PoTnKr~2(+ZZ_r z6bkRU@#MdAu3xTQ`t$Ix4Jo`ZEibj)`s03a+if~oTq}S4`rrQe)GvZW)#_8LBZflf z4BPfI^G~5A($IbY>9=_qoBP~Q9j{r!*R5#wAM93NXPs8MlENqL*28}r=bEoHtpvg zy#@A0>I2t8&UXH_{4bn&(shpAywavZl-CwVY80BMerlUtG(SUUZFx0N_RmbkjB<0< z@ZLufJ?-(FEi*^{*G6dg@(15pFFyYH8UwStoIF40-0oCYZ??&hEirSKxlS238x^xe z$$#_v3ume8tfSDI-A}N#pUyukRX@|Mrj6b;u9S zbbI_o;@iXb)vC&E{$0=_w|5K{C9%EwceR5V%SnHT%KzWMvwTJrrZ1Al;P8^aWbvjC zYs-ZU(`~QzoHw{f&uw!a?V9#8hIP(=W>}}J06LWE5SZ*iO2eS_;De=t6hJD9AkP6w z5w3F0nwD=vL1A;uZhqR=a;eS@s%{wTuJ@WD$1`T;SSZ zLUG)o^jSwS))Vvxmmw%1E#DPV>yKwhI(7oWnx;|!SC$bDP*Qd{I-Ar1dxB#s1LEzI zfy_2jkw!9O5DPK1pbuYPU@C&pARaJ_5X_*T=2i_lWm)0U$7VzZKS>2}PuwLL#)E`+ z()w4%nAU8%0@H2dl;xHzV;$u)HJ2>9(%mJZ=ICL40$-PSn)us3@T*AXGyZT?0TmCf z#KNR@-qfy`q*eNU)US|K?Yp!lgz`$X>|?L-;`-oQs}kKO|YCK?zA$!8dUM1-K9=UybuN@#orptBV!Ee z!`+kuMJUW%&>vi9vE~tSoL_M}noT?n8pu~g_71?@0!g2I0)WJT{XLnfG;PM)(Wkx0 zlbkh#G|pdbCiodv8j1ttEk`X+H3O5AK8AnQP_c@mKPQxNAU;=Ma9)HT-9{1Pv+%@w zI`}z%C^IFFTar|;oZ7izFUJl-#PUyw7hILHO?n~p^bh5J##bVU2_?efCu6Owpv=RX z*zjO%KDqmXZ(o;UdKQ-7e&Db_veW~y?)fWkK)V&}ffBSb{&6ko5IhV&=-d4dyJYXV zTUv^5DUx6h2(t&un>;H|y~2o_Uq$U3Gm4Z*?hYb4X3VF}?^h5XQt1^61CFy`;HJoy!Z$cAJ92+4!R=u$XwvB6(NgpAwY~5=5=Fw(s zojKqAlbCjCwNot){V`+A`yZTo9$y5iX7N%WGSI~HvrngRnhaObK4~5!(#2s^=<%%R zgOvFy_dM3Gzs6^XKb|#=gvK`t+u5yEJgEGX=_d^8k(DVr0(?~`Q`m@v9bxtwXi2y+ z49Hl@+cXk1Z{@e;=xVGPR6?t;64tC0=;5weyVeixBI^26^(T7GIx}-cY^9~x%!-77 z_lm3+q3Q_h{SY`5GWu$Wni1@MLH2Kgq}`HE&SdRl+z*)aX>W!YPN! z6s)%6rkG%}%dEMaCpBEl4z|~;TQ`|T`*JPJQ|M*=a{_m$Dw`bVrZH+weBDFX^{9fw zOTR7Kxc_+dKd8oD5iY+eX!@getDtz;I4BW@%XIB%tM0gJHsI%(T$~JL;;Oi)KxqURQ4+9t4}xX>>9^sX;DfqFiL^p$A+qmg(&!F8gJ zO#8vJP5Q7PY7i`{ZbmCoo9?IJxMemugj@nht!5+e=K#=xPn|n@Wm8CN>Qc{BS*O1V z)}A_le*41Rv3qDdDl6!B9L^k^Hk`L5mI#DMVVNMe{r;v}y;X=BpTbX*<|=$#-Y{JD zqj7yR3g1KZC3is^ZT_!4nx-iFZbk9HN!umbiPWmm}lz9cNQ9E?UuHu#jc;Y(SCgkz%sZS#NP2guZTizCqOE@9fgKw5noE`}!R^bB*D51ZZz|`W+0hj;mSvG6ZF8}Q z$hblP=rAv(yV#f0n>6uIQha9vs{rv^w#6KN72zwR^wtWf=b4{8Hf&f!3MS(KNIk3Rn zoAT)gGkEG>n87C;uN1M4o2NZ}IyrRqxJySaV_hXZG~NTb2Am5GykI$|W?eo>yvi`3 zch(py5Sd~|&s(}>!gWyfd5%(ni>H?(t{rlq;>wYt-iNm+Bj8LS4q88GjUi*GO7J@? zfuIaCQk%w3Jklzvf=c>A8;=e#Fe4|8(Te8D;>s^gHcWB@a;>_ChGXR|XbT1(ZNBz3 zw|X4<=JHDOZ@pI7xJRAplH+Dl>il=z-lbD15X+d;v}G(3IswUq@`-Frj571nkLSb- z85Lxd-cr%!y*V6_LY2jh_;URC-)g-tr|0H9Q%*YL*WbiMg(xPJa&Q?4IE^EmDxYc6 z27iS6e!erW<3>by_A(WI@gB?)+1>1twW;v$Vur91C8NyCp zAvr~UPP#g9_zkc>F-w$?59?`Xmzi~Fzl%spA?|Wey2LF?6ec1E!aT7ol=8;*Ha9#p z6wbW(&jB?{vLJt1JSxPPfssD{vSiMHGUh4=_n!xuc zS7zO4ar{{;Iu3-Amf7kM!8q;waO&+>tk$tor8my?#3L9d2>@85$&(KRU4|4FQ3^Ar zja(7S=b7|W;2>h>@%-Y zvWOOV$OCtElpca`#PB4ARV=QJ4_9nt%BRfH6Ym;9aRow#=)+V1S9Ypc(5T$YB87+X zvW6oJ;n%9eZe)j3^Hv~l4U+t*wix2@hL5vlCnb^FJPt2hGBhA>{qG_ea zvrf~g#Q|T#a=Xs%&2$%U@KsX=wei;~6MSzXB+4b(<(RH-n{pv<+=NN+fFygOT}iIy z^CaoYg|Dkh?`~+NGw#&K&qo^nqcV*xjuj4>Lh;@9)B4>306*zc^1*hHJqzm$vBObp zXRoE5q(4OSD%^Wv*o6zy4!2K!I3c=>HL4IEHl*~tXC>ck2CVlJgI+QaAt@-<~P;rJ7w3|Gfn)>T@yu zX>WSnNKz^Ii_PfRxz9Y#m6T)Se==8a7(^)0$Q@bzE z$XjYLS(|OxW?$na*tW?uYH=lFg|xnHwdL|lUaqxtTYj4}X8kMARIiB+YYlOLWsBy; zwBD~!unfhFBlMa3oYM14-;1pnWk_5_<}6%Vv#SanzRI~P=Wft^lHUD6yn^arG0@oczgjiQNf5JcI>yK{=oHRSwNs#o7 zPex6~HWz)!*V1Pa5YV5fxE}P2Z^5BO`}gDd@bEK!BjL&71ajhyy|T;r*~k6F$lRbs zYO%7L!|L@bdMh;APU?0f+Vc}A!(T?BeF(RYe0Xj_{RrYv<~%J2=35R@ch+*yy}y>; z?E$1QE-E8NeIX>&r{vk^!ld<+<0wFRfJgnPxq z-rmg15N)8Cp^|r0P>8iVlY$}?Vdu|x6P+GKhQc-B`JaT;?Q^Wg<(cT>`1}^-CyWi> zik@@oyS%HpnrNr&QfrT!o7)rRf|k2_E;*S}qzoTHBwO@*d>v{xu|RQBFL97mcCuix zfYRRQ-iY;qj8COkiL{uhdVh`@G*-Q;f*7x?K*SK*?^J)p2>v;z z4&!3F;ru?8nN!LfN!H$&{V>Q;X3qU{22{AcNEa0Poh>@X`tp)!A3y%x(Zeb#mQlStaHBk~@PHcpWfq|jli zqjXV4kJ`Wgnt^(UY>=p7Z0Im6^%k51i4suCuMs9;lFxT_79$`6lxUIros7O2Jnaj8 z^@7oMN3BNr+U99N)8kCJMrmk@5}3iwN~FHmAq(L3(t8e>jLLD_TiUaSoJGmxx}xxJ z)Y87MpvwG{TH4O(`Tv1hx+U(n_BUF#Y86{>wz5j)M4KcVxO^&;>cQZe72GUrLB^_} zl|s41?`msL%$oE!s!EZZLqR77fi!1m133ZW~pNmX`Pq2e+2WmbJ5sDy<8=)(;mCU(@etg?>63G`R7_#0a%S4|A_#|dKpAoGQN1) zF3xeoNt3RauTIO^&9P4%&(!V*SAtwbY=j0hN|G73?Xss`UZR7=iJ zJbNlo#H1uO(r?bA2-68{-sU5E^Im)~MsOD+riw-&{L9NGB4cDjV_{1lsz zdIKJ{HRS&Y&8rv{NcAWT8XAmM2mCtr-I;{D9v|}ZYU`}!i(4-?X{>!|McH_dzmP(I zwJ<#pq%rbR_Y4^?@C#I7>59Szm6_YZ*`u4^p=<2jyERyf{SijVZTL>6w^m$ds%ncp zhmQtKdCNj21<-&p3S~}4Ym99Ap`bvucmAy@2CJWK4_@!7>fI%DR6mOqw?Z1^G&%aF z$C;j*GN${%M>bu+^_{UF#u#SI#sw~H;HdmAm%|~{Dk%W&jycyT!*4Xr{z(I!fBFXv z^ljByCW|Yt%)2ou;Q_wI?@~fXSr@aUM1O!U?D(we{$W>1R5&Vch{`=DXEW4?*hL*= z^af%M+PIlkDzh0bG%)MwViJ1n<|~dHmu%KPF!|(!o^qIQS`yrK6FRy?jBWadmFlFC zBNdFHl7_M*pd7RQ_LFQv?a>>fxV8oe5*{Rpmx-!dnD9CujB*J43$GIzur)$ZPd3F$ z`_sMOO_`>=iVmtp(S<;@5yn-|Ag)waU?6rlcMNF+XkELZZf#FcZ1YGe$n;%O0O59m z!#;z7P~pIZt0(jsC^jUu-%&^|;k{Q;u5rR-p4<~?vsEW8EiIy&;&G8UdTdLU^ca00 zW~t)H3yyDHl$2jI>&Zd9Ygo(9468%kPq)T(F402_AjA|C4H9&j<3sOO z{5om>8TetYH5~}f!VeU})as`Yk7bp(tG>a@R1@8yjG&e;qstrF@Ll1jPd7Q=#FP(+ zPR3_hC$2sWx#1Ve055|tIMEAzK}`NA5x^U;m;0?}b0#{k#KoN(dl)dK!R3=VkwTH+ zxw(e)C5KfUxF3nQc~1cA7k=f6nVbBXn($#a+I1B|YENq2*yX>^Z8UaMy-EGcU?!Z^ zy4gMJPe7D`P5d>XK}l)?Y0~J& zvuE$GjfTUG+)*5L#2$v_tmAyLmBA~UX$JA?y&MnZK4Qp3CGs|bn@&zJ9X`BeO}n6Q9Flqn|9< z+^F-w6G?iv^hmcu-_z4GSvYF(^07_Hc0?l#e@W(#3t3KzO}q=KhkF>g4BkbHq-=;1 zlVb!57QH2lNqFF5L;fX0d#V(}ktMT!p z-j5N4N>r1C*4K$AM2)fLm?OZ;4G@qHi{6-bnfs(3%H=hG`mp9_r;f|?Ya2ktJ_XUZ zOgsQ=Q4RPAOXYVKbO(!5f!V+0B%g1OHq=g-re_;Vma`zEpQz+6wR#*8zxz5K6dPDv z(qWK_5)L36zr%{Jj{fhLrHuyH6c`TMhlAMZ3JgxsF9sPfwSqTK1+ABB<|cuk2ND2e zND%11IPDV4@Ef)md*3N}YViE@W}=lAQSi%`G8@a6 zi&!4Vg-qQo!#S9IlACyTf&GW=4Sd%5%xLs;=EP8Az2Njjp7m+kY$85m4CK-yuXNhe zc{P*d1H?XxhbeSZA#Bp$;G%EhKYZeo$x{#mIbYZXqFfi>WuWmfmmE(&(HrX$acmF^ z^zY0-by_B$aZVO-gMY#Y=@ye%P-EW2W+wx;b+R6+6@|1rs$S7JKTT=wi&I5Z4Ty1E3Q&n z$QcM@Ep(={_(1jQ)hmd8prnV;r4cF*Vr8fvZZb=!W5?R43Iqh~m*DgL@JjQ+@8;W= zSL$=!^7d6Y6$9u}zuTzh zwDQe>z1L8!#PVTqJKY*-cR$ZxUdiFY;1>)22hw zY*1v3<8pr!ipo|MQ0WGVRmcf(+M?3G?#(GS`i8>KbMUv)nx=Mt$JaY_TlZ~TnOkZ_ z%0OfRp+oEM_b=VS!8L`B1A3WDAx7UVXEe>42>D18Q=X$j)ap7vttrj4Kgd4)`!}|R z!gjQ&orA+K-kW~>EuH<}=`gEg0(Y2B+cIOl|6w>hb=AuEsY@IzEQ(6=?hUKi{G4L# z?qB+wD%H-4>*rCYp`rdNrFyDf{(dd|YV>W`X48R#cMr5MdhKVXI>5Yqf$Yka2&Ix&*rBQ zp(f2O&D*?iKN4x!y#KtbY9EwOZfUZ>?W;>$epU}eDzH1=W_4IlbxfyU6^fc4eS6hx zu&QLtaFx4T|M<4=ABhUfK&`^O+TI#JJ}I{XzRBNz{pa6bGG}mT&5OIQ4GDXia?Rrg zKSZUCy>j*z^#!geE0NxJnv z96V|r!}s;No$fs;YQaf|$!kq2Pj}R>R$xhzj|%dZf>mawfkkp;E|91d@S5=?Ebsex3!JwR$8H-uRXF5V>5b;ZY}ywG_9pj zT#eK{6P@lIrJE6b@0HWUE$SC)|M5oT0e}6Hl56482aa#hfwJ2fU{ND}gh%=(hlbi~ z@S$&R96+mqpJr|Jk2kVlhV_Ff-yf*rlA@y0pT8ecNlEe4dc}&b`fC^3#BR@X_*MH* zbalATS5^P=EC)S^ROLPPx;-W1#@q$%I&`=%>qoQO(;8otEdToL18SE4z?%(6xViMx zY0<)nT8O9QTI+AOQua`^owWIxPpxTu`_xc!eTY#VmWVw@xc%O5-5)RTj}NG4@ZT(o zzkbgOpBmif{8!J7oSWTMZ9g&PKVGvukY2Zwl9J>*RH|1m_>WIPZ~c!)=crV^9ncsa zF*0nv2u8ua?sgIJ)(2|+^tt@?q5l`ZciDeLnI(}tR=0lHlhn|-`oCQMz0EAzcDlN^ z|Ks<`t118WwBp|%J(<-aK=%Lm=mSm5w$IdF?6G5TY~+&MfA)@gHUIH^TpAqE`1$Xj zs!1HVPk+(N$LA#AwxfQ%di^+nJhkYr)*Q4dV(q_wbV_gJIp#P%eQ>@aAL3Hk9}uiX zi%1^$7E-ePbVOgt=KJTyUJ|`I`3Ms(bm)ME=XjTG)&n#&O~9``do}r0rRCdgEnZZf z_pd0{ypMY`AGT%rud7u@{vUroW<$rD@qK^%eV1ep`RMXr|2e4rb^ZRgzt7zQVtbUH z8G4rObX6WwjX2Z!@u^X@;xwu)CmLNAS5`P<0v9{wH2Rd8?V^tO`_H7o<-Ts+NRUSS zAPbVNe6zr_t=)wKrW!y~hsE`f&Z{NbGu2wP4gju@;|_z`GyHt>K9?eqpLBt?A8h-e zpOiMtBqn7ph;Ff2o2C%&vPSZjCTVjc)>Jt&MwkEbq1%l5e8~{&$+@8mo?B8`G`$HT zV@sKV9ug10RlMB+1|M&C)&~r@R(W#;$$$Bn;b1^Cfy|g=4jyrkDX%MAvk8BL6Rd2jzIV4Tai0XXq!4AeB| zokfl1fB0|!ItG<0RZQt~(I)SLOQPFp{Jtn>cVVV=l4bSQ*R5F`%#d>=QB3SJq>vbe zCCRn@zs&RKmgZ=Li_J(9G9FZ0YNg>=Hr*$Cownft6%v*W?UNlpL@wj^14;KyX;?41 zXHZC2&R&1zw@Vb20bCbp_e72qug&)gio>I;=Y#+ZCNSHEEXriW2ur;6Xq?P>+q%!C zAs{#yc^n|Wc|0>cr?fT z@ZN79_m>`}LE(;#91n(}^(T4AvykJ-Eo;53KL0FvH(oT+Gt=n;U|!a4*v<}pVJ3!Y zeKuLc?_*J-2ANqS6wp3)+U{Zr$j9)p*a7?M#Vy*dZ(KCDh1}#XL9! zz&oiB-9AChi02Wvh@lR-o;ZA-<0%5sD0&w0K&tT!_Gl3U8SwE&R_72JBUpz=$3LQZ z-`E&etKO};bxTU@O$pEa$T2pDs=TD$07r{O5jGk=DS&Es#kFDXsk5EC8U zfmL@Cjx9`{xWwTr>ZwW4F;p5yO9)`63-h&y?bA;PwK)xFPK?ACfKD{&Ieu(2Pt$Zb{$ULOja3T$qwerjn7 z5${^3O&j@xDffROwc$ZL9>>A`iG#Mmbc(0R_4HI?p%Gd@^z>>s!HQ&m8R^A5c|} zUX@3%+_a1VvKG9q3Y{4y-`uGRWV*$R?O)zqg2eX3_)s&H4kNkOmRr@+bUJq)1#`v> z%aDo7^9C5?URAaVb2vsxV7n|-J+$oF^C71N&}R$jx^Ev#FdlwmS60d8g2Zu+dDHCQ zK+4J|si&7=jGOuLrDv0gGKB1HQI9%b{9IcL65C0{T3S? zeV-XO7{Ih$|220stw^U=`|?Byk{j!L6+zCp|sB`L#&* z2JPET-9WEAA7{chlS+%c4-ehthu3EtJ-s{e8P|+ByYp#=zkPo`Jw#8f;+PvzQO7x- zbS8ygBJLdK$IXHt{wDp(6?6gxVA#v_`#TyUVAg7*p<#$r)Qkz4a%Yrt<2h1-L3z7? z&DI>WK0=f30VpJ=7H+y*jznJDZ^$w3Qepb#*%1k;LPTtr6X;SHGbH@$il*7RbYA59 z@TV4&qbx@71WTaagLYru8IaxUKBZqa%lvw*xh>hva{;(jVch}Azuwp_?LwC02j$WC zdKU+3%>?52jIKU^YDsSyZN|xZ?(K2LkqUj013ru1{fkQHKql1;oXi0sMsp}mQ2%0j zE@&FrNyT@CZ(H~Nnj5*;nYQFZaO4E21|!z2?e}{6+qr3TE)TCaL9Q0@8FW=&_;ivC ze8@X}Wxv~37q5Z=1&Ixkwlzu1#AzfXXQrW{OMFL=v#nZs<1gI*bjJFFGE{UgEjHi~ zPp+sHWDNVrAt|g@&qH*Vd%Qm%GU>9DS9;q8MV+kMemH3Bt06IS_Tw}D5OBC&!%jlLrG00hjDYMfivW<6$>oz<^`05SwkN^W}Zv4HsyOGkLtj zlayQcnY;-7tg$CEezfc(li_i_Id;Uy{t3{6zFPMMhAY3^n#6(EW5B?Hp6WsH`gdsY zTN6(hH1aG^LCSt2?Fri0^`X9w3>LALi=j z)_K0;X;?h72o*Y`4sXEA=gs|lIbMFQEmtcP+LQUYro^@`s4M5Dho>g4p#LC&4EB%{ zL=FSaLsgF(euOP6a;!u;s_%+ep9ev~XJZlD%)Q3>)r)o=0NObUtcLCCj$7WVJ=N1} zfZoFFGu@4fIY%VlGB$(zt+lmDTC48e$Ba5W)UGH25}$FLL=K>-gcIYuzvgy=0klYe ziD-&BXuY)x-X|v|e!JcI-rz8w&Nmy5D+V1u%vav7Z|yU3!Ghemn;KX2Wur=vhd5(< zu{e1aVN{y$+^7z?{mbg@yDfY<6kDkPnU+?qn#1eXecbDNd?|THjiqv(E3Stn{DA`+ z1z??o29ZvJ&a5dG73XX)LEqFbQ7?AY}kP zcJUow45~eah%*TEcaOyU?b@ah5Ek}ufb6D9cGB0aw*|+L7BQKYO;r0hC^T;DWH6DDJt?ioPkxlJJnl5gJ!pqa;2RV5zljS<|71}GSM-k;zH)GyKzRR zweHd5@!(FZjZ0Z$2pdnUa7dT`x}?bYKbBqp*D~$D|NfEMji%-^&gwWUx*E=XO7gdn zqaMM=CuYj&qn!K|)t{=h>(t4NWw3ZItI+et6w@hF{02=4v#9SefRprtLqo+kjTwC+ zl`B=-a%0K^$&~Aivc8Xch+HH(-ddsUCv~|(@#XfE(5LBCnH~D7nE|spnU~-aKbJi4Wi2ColS$~0(RR+_)UJ^%Cf-bN zvmn*X%*i;qx>-AB47f5?9AY>YIiT{ zT>X_P&ISb!M}_23V@aHo0d~u>LkH0tm-1E07lsButGU0Jhg(2S^#n722zGZ#I0MrNQHL=^4Y< znm*xdG(t;YO22q`lzI>Q{&X}0V06$df8}sx{-wON?;|XD&XTRuDNgO;1G9P}C1fHu zCS`S3CTdZWJqdTd$ir(%>Nd=$*W>JGJ`N?CiKyTuIfCLf)H6SM{*{@OWOR48@C44` zvX23|v1eJG(73A!C(kG}bgGRS9eej~4gp{YmiI|UH4P523sSmF%qpsQp9s9Euc zH%jV4t9$mfRTbqxk$vyXk+`&X4lS5j9DchEmW8me>*1%wg3!SZ84ALELLGhx&3R~9 z5RE_Ng|4{rd|wCem)?>Fu_WXS&Brs~)!Xo@?rb!|@O%3_nyz7vd49y9c0ft@D!#Jj zYJ%EL3J>HZIt{R{XV|-w?5}wj3Bk{^_os{b<_0Z#liOaEfRCg(q+k>}jW*mcmhRYd zwp)!#@wl~(-Jv&Ix4y?%2L4T$L>{|!8VSveB%fWoW)e0xYSmR&pYM?lVMQWv)1HfO zXLRSCb%eDa6Cc`W>TS=KLpErABn|DEKWu;R)WMy2ic8bf=S?UtRC65~&I_LNIPU$u zgndsLeEOT`Z7M6ZA`;-C!-sF0knCKTI)l%D%=s~)7)8m(8&f*6c30~7(9duDJ%Cd{ z&3RAm-5Gw`x!Gqooxi)1>S<~3;cy!_YQ^)$W$PqsjRIT1o}C12ROI8GXjD| z7th=9$vtz5+i80a1UgcuH!(VpixZH(iP1$lu}z&0PxDs^~7_VRg0qWy@$gNcLE z7kc+Zuf7LUu(gZ{Bj@z4NWamz^!%FJU=#A1le0BSN=7xoYr`Dw7Uma{Ya|4Y9mQ5I zOOTo-797XP`7orfGDL@o=zJsoAiBm+&d%5jm)@_FO{{j8F6MYeVcdV@!}61f!9@^6 zj*_7t#k5E=L6$x-P}5j{#n%f2g(D=wZArAi!Ip&fiYfh8*vFtGKR&=JIDjQ$fi|N$ z4q_yf!=v~?V{jxToeIhhd)ux$;s6TMCHjd8J%2$|5Ws^<-Z6>IvH|$u9Qc%*Gn5{| zk?PrSdEcq%=;Bzs;-o}_DJBIotyFQm_xydxcI z*u!!2FWdCo&sMgj88Q6145fee{CNQf`=cE(ASy8*<2z)t9EVCljbz{?m}}4c;?JKS zWp6mIzx;C$4cn)=6E~7+9pecUQB8d_AIfgET)a30X2mHN7sa?`RHk52eJ=iH9QO9) z#W^1bO!U^3iWD#PtV%-=}oP6ll7q;cA-Gy56(tPEKexDU2y=Ri10bUw+Zn)D-8B1hDCSoAy)1 z)BG0A8tBCUL8ERR`EBoIBMnM(crB-Ss^-jYVh_t_Il+Yq2AOhm9^-AtaOd5SVoq`{ z1^@)BRINIStm#(weKGfX^diAzL7cynj$7F%(#(8fi~ff94-UG$AFp^iI^|pXZV4E@ zo)O)jT(CRHA$17!Agrmd&^WaRv&F2=PTwf0-K(i%yxRn|Ta@uev*1LBo3@;df?ZgI zIn2Bm4!4=oU;@3+(eP~MHZYif>GNZT!j#~P;*|ej5a3`N>K zFOhkJ<5rdyPcn`JA=vk7Zs4u37X=X|$c0-PpSt{MHx+8?CcSl24Ex^oC#WZ)JwBzP zs&kYV#fp`rFPPj$DskVzZ(=#}&rv8>SJUruuj7lP@r8G~r60x99xkoioCRBf!+)IY zdmiQC7cZt=40VR<+_;DRp%WSsor(5l5Xxc}zT^AjagYuqNFQgz(I`1b+zgc41Cvew zOL@o?0k`);tK}eC!r--S?5P0omYEc>q&WBWR0}>#tpRiUB45xUEn1YFGL{-jPJDUv zrC(q5ae8~={JTwKq2S04CP|51xL2W(RbypH9X6P@)`zfZ0;3NDWQ!EUJM!DSklQzS z$DEwk>yAk265cI+dHmo`6cZuAp;j+7+qS)RZeHq>!JTq0ecaUX=1wkl7uiN*<5sY* zA;!g{Y`6#GEG_?0H+i|q7f#sq7}qH}Y|T(Y+8yG``y%A%wkA7tXA;iuV0<)Z_Pv;x zj!-l0yRV#jvb|;Vm`fjG+b(`@w6Ou^;W zEj6w+t$-l4=U$c*PZ#T+h}usPd_u2t=XmUyb|cf==IJ?Q$p-dT6P{2!^L#GeJ4kto zQti52>byRn?j1av?x+SX+Kqp&ln@=cRISg76bPsfI4B}dIulev?(uj-7dxZp14VBz zX?e!8_%ln+wp{&UTIklYx-ezoJ%g9zO(CCn^U1GLsf8EPZXQQtd&NwxT^NBqd4C+@ z=y2~4i2!0*(Z=%R-cU@YeeT|9^!8OpEcr(f2$Em5iopnRCoXP1=9~p&soS{mESBn> zx+8j7r#U{a9?vGL+qCH%(x3_Lu54={5WeS7V62aqhH;1-qnIy$j~ zJ5d&gWj6FE8gB)5U$<7R$&i^dgK|h(Qu04{Yt|Ww?1<+dXP@l3@a2X!rhaR%HuIzm zT9+Cwiv1Qbmp(u92niugXh_~e?a}h$!fDx3{wpWpdD}2Z z@59g?4-Sqt)Yud)qHv-LTfaJ=i`>%j*l0^zV^rnrPCjI07FvJQ(ZBRXvN z{n#(}m-`P~f5}&lGV{#yJrJv%Lx3%m!mr-pt5cg15R;TLPL)4^-$Y+la znM6@x`i`CW(4DctTrITo&+lJvfBdm~#<^C4r~AcqSC>mKikNTCVL1hgz=a-geue9D8I;1 z%>KssZ%~il*5_rFJm?=@vL|8sY)rU=-FRAaBmUsw>8PeoEez`B`3Kh$M|Z2$pOP=^ z2x_Mw_~sXL>UR(LvT;rl2H(F$nOl^g7L*m;fk2#uPe%e}C)+jAU=vs=!*<9%vr4rZ z?OWzwpi^EVL(lE3+sIt7B@tZt@!5>~Ets}Q$Bu@4MLy7Ht3C*jbRp{FhUH_FGq z(izaEe7U1Bk36E)!9ApymZ3S%c5wvntlqP`_)+=ZUrCO80@g@Fcam6#8nErJSow_^ zWi&|`xZ3ZrK{dD;R(c0cqj;)L7%;}ynXHj7F@Y%sNeqw6-l}EYcSLY5`nl8GGnY_! z_kcgYyy4c{;w)Tg)xB@y-BaEkldtKhs*CB})m$?*+gy1srua(u<;=iI9HcHRei;A? zN9Ke52M$zg#Bs~;fU2+ylzA8=^Vm#imUc*}0F*Zv6ST?a+X8Gm!$$_B^e5XzT&7b* z5%{4SmsvT1eX9%i6k;%4pz+o{LJ4y?cnP?h8z1i`qCGyHH_=z1GV+La4O4;B$&nP< z1iZ@iw&2GT1{9pVTT(O}cgomUhy*>Gkjj{nii*|9lbnIPoXu6SG_HNUVT1WlUfP{a z9pFdqMHpOY$|%OA5kkjssbWnJZSby;OGn~>Anw-BDy7-J1p}QDFs1klO2T{`KN@fL zTTZMW4;?B)JgZRywcCto)w`I5aj%+5F68AMQI}}mKa-nT z5=^`o;`mO3n{AhEEO|`CIV79q8V7E@aiqY2nUWuQ)NtaeImweig;88)(Xsy;tVGFL zV1L`N7wsTFvDdEOi9Sg?AFg$5qC99R5wWoKxu6WB&#MJ0~8UQv)2^_Jfwq#eA*n zr^!cK(4Z^oYagxHeRtuArlRoSv{}~Ho_HPGC0e;rDW_l1CXEd8v2!AHxzNTb*fU6v zY_Sy45aQ7sGx)rnXn&64M}hr?#Do$UB-8#KHGBPDR#ESn*k*RyBK1f8swXOk_|NSi zM;lX9N1D53UD{c7S=C_ckg%)JM5Ihma0;i<;-4_~d&rEPrf~eSJ$=8JWvo4B z!Kq#53#alnOHaCVV~EVHsWm)6bzMy1mGm_}dD241fUL_tOPpB&Osy$CWw8pQBU1%! zYlaV1=k5FI311hS*agZp>}zo&zrSwQtrul;_@*g>%F?;Qu2?KGWF%zukE09q>)F8~ zqbMBgxnr#RDnS3e8Ga`J943WPGlsYg+FyYJ>shlV<6G{t2%l;Z%QtMU{i;>W^kydv z5Z1$+E2%6g5X9fQ!1uj?8JNduvp-9{W@AF&kjSH%x=VG!i-o3xlgiH=A|xaM+syPv z26ndGNc`8D;sW%cws z3_=2GK}gsm%0VImhGOf&#OO|B;1>ky%wWs2hTH{m)PUZ*87mv~L!QpJE9LF!X-JEX zF$*bi$nEE`x!tl2($E@7bMFu8-@ch|<+vq|2BVu^m!7=n9ezJG(2Df8CZ>zGU53Kf zo;1nZ=MML?t1YCyT5r6O7jG_(6r6{a?_Zzhz(ZFXo;7g{8LN%hC0d?IQ^C0g-t->q zX|szNe4L#7iII^#*~@)&Uou+N2R}&|TQ$Bou~{5OBJabv-(z{e>n>1&T^Lbc@d3br+N=%mJKFJ}G zR<~EJ5-IR-_u)M^-)Wfrp@oGz5bx5EHP7h8L)Tk_jZT4d<6kcKmsz(vz0R60AxTO& zr&5J`2oyky%>I+Jk#!ZjM6yrE^(so%HtYJvt90#I`xKIwE1?aABSRMqT7_{rrHhed zeLOqD9zxb-m3_UgCzjpZR;$P%M8|RZRLkpfk8aOBx!1wL-y1_=;m6qfRh_SDjT^U3 zv5QQJAz{1j+!@>WGhkvSgv&2qeWKRNXFF4OYJy)gNM_rLl$hw!E_W5FZ9OE*O5Y5? z0;9^2Y=kkc4et2#=dl^TeK=#rt=29F)lYAm?e3a8cdno)(4RB-oDbhV@rDRoKPFL% zlcRevad~tCJKTrP?Y6SS!+dY&DCVnN`;LMFB2huXdT0m@I#Z?$9F$rRrvZF@2;=ia z&hze>3HV6l@8{8nEr2#*PM}|VE*J8dXWH1TWjtAiaYgqgarhuwaz*tQM~A=`80)7P zD3C0eH4cYH_0>p}Nm0)}3X-T=Sb5m`S)_0h*zqYuI-LBa%a=dkz3NPym;ec0dZoa* zNZ?CMsU%{OSZuPuWZsFPxp`&lDQ^C_i`#U-j{~* z*J5A`lF($2oOCE@M4~@H@w_O9z|5}E>nGtqgQtgVp5a@U=gwp3gs(BuS9^cI_s7C_ z#Sx5whR$!ovJ_?hc1F-q}|0(O5ep@(Sn~$BR*PdTH?eu zKyL;-x%pO_r^1zupOydgh2Z;qBprMwcGXL+(c4=_%ZCfqOjfot=5ZU0P;7*qRrvKf z+S=me<)E-f-))Pk*X4eoS*a#^6Nvm$9M;F9>-?Wg%B3WLg1KU-?G!XqL@ne^7n&{ zCPCDQZC++n`-d=;Q0JmdrhM<%@d&&WDCoERQ<|n|Kbg<`br>*~B-euFGPB1}BJrT_ zW9$yo%VaScbdQ>z&KBs95;-9dKJQwPJ55dfZ~|#k^$m|Rk<45OlphwI&0>c@Ne?h!%Pg4$P5InG4thK1F zN#jaTPQ~+UaxJa$KCb3WhB1qv!6cE>&60XLrjmfJ-b{87o~Eck z5{E4{n3I{T-CS#y@hX$F+6W{ zqsl)_9HW1(N5WT7GnA-QD&JG2+dd6up;vF)mLbk)PS=$Oe~|n^_jLe{fDfg%LF5qD zdJ|-E5MS{)^6CnXK>pWv?;QwyX)GHa8)n3Z3VEa^)H@C}II8yAoGul!IZ&)2pwGPs8!s^zxo=J6-&_`1Sw$n&%@rTc!`xk9Gb;d``Q?D;A|MShx2-tS0&* literal 0 HcmV?d00001