From 0e766731ec08a495e0e8f7a482ed7020dd0abfa3 Mon Sep 17 00:00:00 2001 From: "Stefan J. Wernli" Date: Tue, 9 Jun 2020 20:16:13 -0700 Subject: [PATCH 1/5] Initial similator fixes --- src/Simulation/Native/CMakeLists.txt | 3 +- src/Simulation/Native/codegen/codegen_fma.py | 436 ++++++++++++++++++ .../Native/codegen/codegen_test.cpp | 127 +++++ src/Simulation/Native/codegen/generate.ps1 | 21 + src/Simulation/Native/codegen/generate.sh | 28 ++ src/Simulation/Native/src/config.hpp | 50 ++ .../Native/src/external/avx/kernel1.hpp | 6 +- .../Native/src/external/avx/kernel2.hpp | 6 +- .../Native/src/external/avx/kernel3.hpp | 6 +- .../Native/src/external/avx/kernel4.hpp | 6 +- .../Native/src/external/avx/kernel5.hpp | 6 +- .../Native/src/external/avx/kernel6.hpp | 6 +- .../Native/src/external/avx/kernel7.hpp | 6 +- .../Native/src/external/avx2/kernel1.hpp | 6 +- .../Native/src/external/avx2/kernel2.hpp | 6 +- .../Native/src/external/avx2/kernel3.hpp | 6 +- .../Native/src/external/avx2/kernel4.hpp | 6 +- .../Native/src/external/avx2/kernel5.hpp | 6 +- .../Native/src/external/avx2/kernel6.hpp | 6 +- .../Native/src/external/avx2/kernel7.hpp | 6 +- .../Native/src/external/cintrin.hpp | 5 +- src/Simulation/Native/src/external/fused.hpp | 65 ++- src/Simulation/Native/src/external/fusion.hpp | 15 +- .../Native/src/external/nointrin/kernel1.hpp | 6 +- .../Native/src/external/nointrin/kernel2.hpp | 6 +- .../Native/src/external/nointrin/kernel3.hpp | 6 +- .../Native/src/external/nointrin/kernel4.hpp | 6 +- .../Native/src/external/nointrin/kernel5.hpp | 6 +- .../Native/src/external/nointrin/kernel6.hpp | 6 +- .../Native/src/external/nointrin/kernel7.hpp | 6 +- .../Native/src/simulator/kernels.hpp | 4 +- src/Simulation/Native/src/version.hpp | 11 + src/Simulation/Native/win10/vcomp140.dll | Bin 155296 -> 0 bytes 33 files changed, 827 insertions(+), 64 deletions(-) create mode 100644 src/Simulation/Native/codegen/codegen_fma.py create mode 100644 src/Simulation/Native/codegen/codegen_test.cpp create mode 100644 src/Simulation/Native/codegen/generate.ps1 create mode 100644 src/Simulation/Native/codegen/generate.sh create mode 100644 src/Simulation/Native/src/config.hpp create mode 100644 src/Simulation/Native/src/version.hpp delete mode 100644 src/Simulation/Native/win10/vcomp140.dll diff --git a/src/Simulation/Native/CMakeLists.txt b/src/Simulation/Native/CMakeLists.txt index 0d5e14a053c..80dbd645d8d 100644 --- a/src/Simulation/Native/CMakeLists.txt +++ b/src/Simulation/Native/CMakeLists.txt @@ -24,7 +24,8 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) ADD_DEFINITIONS(-D_SCL_SECURE_NO_WARNINGS) # Configuration options (choose one to turn on) -option(BUILD_SHARED_LIBS "Build shared libraries" OFF) +# @@@DBW: This should default to on +option(BUILD_SHARED_LIBS "Build shared libraries" ON) option(ENABLE_OPENMP "Enable OpenMP Parallelization" ON) option(USE_SINGLE_PRECISION "Use single-precision floating point operations" OFF) option(HAVE_INTRINSICS "Have AVX intrinsics" OFF) diff --git a/src/Simulation/Native/codegen/codegen_fma.py b/src/Simulation/Native/codegen/codegen_fma.py new file mode 100644 index 00000000000..df55312f6c4 --- /dev/null +++ b/src/Simulation/Native/codegen/codegen_fma.py @@ -0,0 +1,436 @@ +#!/usr/bin/env python3 +# (C) 2018 ETH Zurich, ITP, Thomas Häner and Damian Steiger +# Code generator for n-qubit gate + +import sys + + +def avx_type(complex_avx_len): + if complex_avx_len == 2: + return "__m256d" + elif complex_avx_len == 4: + return "__m512d" + elif complex_avx_len == 1: + return "std::complex" + else: + raise Exception("Unknown avx type.") + + +def avx_prefix(complex_avx_len): + if complex_avx_len == 2: + return "_mm256" + elif complex_avx_len == 4: + return "_mm512" + else: + raise Exception("Unknown avx type.") + + +def generate_kernel_core(N, n, kernelarray, blocks, only_one_matrix, unroll_loops, avx_len): + indent = 1 + + kernelarray.append("// (C) 2018 ETH Zurich, ITP, Thomas Häner and Damian Steiger\n\ntemplate \ninline void kernel_core(V& psi, std::size_t I") + for i in range(n): + kernelarray.append(", std::size_t d" + str(i)) + + kernelarray.append(", M const& m") + if not only_one_matrix: + kernelarray.append(", M const& mt") + kernelarray.append(")\n{\n") + + indices = [""]*N + for num in range(N): + tmp = "I" + for b in range(n): + if (num>>b) & 1: + tmp = tmp + " + d"+str(b) + indices[num] = tmp + + add = ["\t" + avx_type(avx_len) + " v[" + str(int(N/blocks)) + "];\n"] + for b in range(blocks): + if avx_len == 4: + x4 = "x4" + else: + x4 = "" + for num in range(int(N/blocks)*b, int(N/blocks)*(b+1)): + add.append("\n\tv[" + str(int(num % (N/blocks))) + "] = ") + if avx_len > 1: + add.append("load1" + x4 + "(&") + add.append("psi[" + indices[num] + "]") + if avx_len > 1: + add.append(")") + add.append(";") + add.append("\n") + if b == 0: + add.append("\n\t" + avx_type(avx_len) + " tmp[" + str(int(N/avx_len)) + "] = {") + for i in range(int(N/avx_len)): + if avx_len > 1: + add.append(avx_prefix(avx_len) + "_setzero_pd(), ") + else: + add.append("0., ") + add[-1] = add[-1][:-2] + "};\n" + + if unroll_loops: + inline_FMAs = False + miniblocks = N/avx_len/4 + miniblocks = max(miniblocks, 1) + for mb in range(int(miniblocks)): + for rb in range(int(N/avx_len/miniblocks)): + r = int(mb*N/avx_len/miniblocks) + rb + add.append("\n\ttmp[" + str(r) + "] = ") + + for i in range(int(N/blocks)): + if not inline_FMAs or avx_len == 1: + add.append("fma(v[" + str(i) + "], m[" + str(b*int(N/blocks)*int(N/avx_len)+r*int(N/blocks)+i) +"], ") + if not only_one_matrix: + add.append("mt[" + str(b*int(N/blocks)*int(N/avx_len)+i+r*int(N/blocks)) +"], ") + else: + add.append(avx_prefix(avx_len) + "_fmadd_pd(v[" + str(i) + "], m[" + str(b*int(N/blocks)*int(N/avx_len)+r*int(N/blocks)+i) +"], ") + add.append("tmp[" + str(r) + "]") + add.append(")"*int(N/blocks)+";") + + if inline_FMAs and not only_one_matrix and not avx_len == 1: + for rb in range(int(N/avx_len/miniblocks)): + r = int(mb*N/avx_len/miniblocks) + rb + add.append("\n\ttmp[" + str(r) + "] = ") + for i in range(int(N/blocks)): + add.append(avx_prefix(avx_len) + "_fmadd_pd(" + avx_prefix(avx_len) + "_permute_pd(v[" + str(i) + "], 5), mt[" + str(b*int(N/blocks)*int(N/avx_len)+r*int(N/blocks)+i) +"], ") + add.append("tmp[" + str(r) + "]") + add.append(")"*int(N/blocks)+";") + + if inline_FMAs and only_one_matrix and avx_len > 1: + raise Exception("Not implemented yet!") + + for rb in range(int(N/avx_len/miniblocks)): + r = int(mb*N/avx_len/miniblocks) + rb + if b == blocks-1: + add.append("\n\t") + if avx_len > 1: + add.append("store(") + for i in range(avx_len): + if avx_len > 1: + add.append("(double*)&") + add.append("psi[" + indices[avx_len*r+avx_len-i-1] + "], ") + if avx_len == 1: + add[-1] = add[-1][:-2] + " = " + add.append("tmp[" + str(r) + "]);") + if avx_len == 1: + add[-1] = add[-1][:-2] + ";" + else: + add.append("\tfor (unsigned i = 0; i < " + str(int(N/avx_len)) + "; ++i){\n\t\ttmp[i] = ") + for i in range(int(N/blocks)): + add.append("fma(v[" + str(i) + "], m[" + str(b*int(N/blocks)*int(N/avx_len)) + " + i * "+str(int(N/blocks)) + " + " + str(i) +"], ") + if not only_one_matrix: + add.append("mt[" + str(b*int(N/blocks)*int(N/avx_len)) + " + i * " + str(int(N/blocks)) + " + " + str(i) +"], ") + add.append("tmp[i]") + add.append(")"*int(N/blocks)+";") + add.append("\n\t}\n") + if b == blocks-1: + for r in range(int(N/avx_len)): + add.append("\n\t") + if avx_len > 1: + add.append("store(") + for i in range(avx_len): + if avx_len > 1: + add.append("(double*)&") + add.append("psi[" + indices[avx_len*r+avx_len-i-1] + "], ") + if avx_len == 1: + add[-1] = add[-1][:-2] + " = " + add.append("tmp[" + str(r) + "]);") + if avx_len == 1: + add[-1] = add[-1][:-2] + ";" + + add.append("\n") + kernelarray.append("".join(add)) + add=[""] + kernelarray.append("".join(add)) + kernelarray.append("\n}\n\n") + +def generate_kernel(n, blocks, only_one_matrix, unroll_loops, avx_len): + kernel = "" + + N = 1<\n" + kernel = kernel + "void kernel(V& psi" + for i in range(n-1,-1,-1): + kernel = kernel + ", unsigned id"+str(i) + kernel = kernel + ", M const& matrix, std::size_t ctrlmask)\n{\n std::size_t n = psi.size();\n" + + for i in idx: + kernel = kernel + "\tstd::size_t d"+str(i)+" = 1ULL << id"+str(i)+";\n" + + kernel += ("\tauto m = matrix;\n" + "\tstd::size_t dsorted[] = {") + add = ["d0"] + for i in range(1,n): + add.append(", d" + str(i)) + add.append("};\n") + add.append("\tpermute_qubits_and_matrix(dsorted, " + str(n) + ", m);\n") + kernel += "".join(add) + + if False: + add = ["\n\t" + avx_type(avx_len) + " mm[] = {"] + for b in range(blocks): + for r in range(int(N/avx_len)): + for c in range(int(N/blocks)): + add.append("loada") + if only_one_matrix: + add[-1] = add[-1]+"b" + add.append("(") + for i in range(avx_len): + add.append("&m["+str(avx_len*r+i)+"]["+str(c+b*int(N/blocks))+"], ") + add[-1] = add[-1][:-2] + "), " + add[-1] = add[-1][:-2] + "};\n" + else: + add = ["\n\t" + avx_type(avx_len) + " mm[" + str(N*int(N/avx_len)) + "];"] + add.append("\n\tfor (unsigned b = 0; b < " + str(blocks) + "; ++b){" + "\n\t\tfor (unsigned r = 0; r < " + str(int(N/avx_len)) + "; ++r){" + "\n\t\t\tfor (unsigned c = 0; c < " + str(int(N/blocks)) + "; ++c){" + "\n\t\t\t\tmm[b*"+str(int(N/avx_len)*int(N/blocks))+"+r*"+str(int(N/blocks))+"+c]" + " = ") + if avx_len > 1: + add.append("loada") + if only_one_matrix: + add[-1] = add[-1]+"b" + add.append("(") + for i in range(avx_len): + add.append("&m["+str(avx_len)+"*r+"+str(i)+"][c+b*"+str(int(N/blocks))+"], ") + add[-1] = add[-1][:-2] + ");" + else: + add.append("m[r][c+b*"+str(int(N/blocks))+"];") + add.append("\n\t\t\t}\n\t\t}\n\t}\n") + kernelarray.append("".join(add)) + + if False: + add = ["\n\t" + avx_type(avx_len) + " mmt[] = {"] + for b in range(blocks): + for r in range(int(N/avx_len)): + for c in range(int(N/blocks)): + add.append("loadbm") + add.append("(") + for i in range(avx_len): + add.append("&m["+str(avx_len*r+i)+"]["+str(c+b*int(N/blocks))+"], ") + add[-1] = add[-1][:-2] + "), " + add[-1] = add[-1][:-2] + "};\n" + else: + add = ["\n\t" + avx_type(avx_len) + " mmt[" + str(N*int(N/avx_len)) + "];"] + add.append("\n\tfor (unsigned b = 0; b < " + str(blocks) + "; ++b){" + "\n\t\tfor (unsigned r = 0; r < " + str(int(N/avx_len)) + "; ++r){" + "\n\t\t\tfor (unsigned c = 0; c < " + str(int(N/blocks)) + "; ++c){" + "\n\t\t\t\tmmt[b*"+str(int(N/avx_len)*int(N/blocks))+"+r*"+str(int(N/blocks))+"+c]" + " = loadbm(") + for i in range(avx_len): + add.append("&m["+str(avx_len)+"*r+"+str(i)+"][c+b*"+str(int(N/blocks))+"], ") + add[-1] = add[-1][:-2] + ");\n\t\t\t}\n\t\t}\n\t}\n" + + if only_one_matrix: + add = [] + + add.append("\n\n") + kernelarray.append("".join(add)) + + nc = len(idx)-1 + add = [] + indent = 1 + kernelarray.append("#ifndef _MSC_VER\n") + kernelarray.append("\t"*indent + "if (ctrlmask == 0){\n") + indent += 1 + kernelarray.append("\t"*indent + "//@@@DBW Was missing parallel directive\n") + kernelarray.append("\t"*indent + "#pragma omp parallel for collapse(LOOP_COLLAPSE"+str(n)+") schedule(static)\n" + "\t"*indent + "for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){\n") + indent = indent + 1 + for i in range(1,nc+1): + kernelarray.append("\t"*indent + "for (std::size_t i"+str(i)+" = 0; i"+str(i)+" < dsorted["+str(i-1) + "]; i"+str(i)+" += 2 * dsorted["+str(i)+"]){\n") + indent = indent + 1 + + kernelarray.append("\t"*indent + "for (std::size_t i"+str(nc+1)+" = 0; i"+str(nc+1)+" < dsorted["+str(nc)+"]; ++i"+str(nc+1)+"){\n") + indent = indent + 1 + + # inner-most loop: call kernel core + + + kernelarray.append("\t"*indent + "kernel_core(psi, i0") + add = [] + for i in range(n): + add.append(" + i"+str(i+1)) + kernelarray.append("".join(add)) + for i in range(n): + kernelarray.append(", dsorted[" + str(n-1-i) + "]") + + if only_one_matrix: + kernelarray.append(", mm);\n") + else: + kernelarray.append(", mm, mmt);\n") + + #end for(s) and if + add = [""]*indent + for i in range(indent-1,0,-1): + add[indent-1-i] = "\t"*i+"}\n" + kernelarray.append("".join(add)) + + # if controlmask != 0 + indent = 1 + kernelarray.append("\t"*indent + "else{\n") + indent += 1 + kernelarray.append("\t"*indent + "//@@@DBW Was missing parallel directive\n") + kernelarray.append("\t"*indent + "#pragma omp parallel for collapse(LOOP_COLLAPSE"+str(n)+") schedule(static)\n" + "\t"*indent + "for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){\n") + indent = indent + 1 + for i in range(1,nc+1): + kernelarray.append("\t"*indent + "for (std::size_t i"+str(i)+" = 0; i"+str(i)+" < dsorted["+str(i-1) + "]; i"+str(i)+" += 2 * dsorted["+str(i)+"]){\n") + indent = indent + 1 + + kernelarray.append("\t"*indent + "for (std::size_t i"+str(nc+1)+" = 0; i"+str(nc+1)+" < dsorted["+str(nc)+"]; ++i"+str(nc+1)+"){\n") + indent = indent + 1 + + # inner-most loop: call kernel core + + kernelarray.append("\t"*indent + "if (((i0") + add = [] + for i in range(n): + add.append(" + i"+str(i+1)) + kernelarray.append("".join(add)) + kernelarray.append(")&ctrlmask) == ctrlmask)\n") + kernelarray.append("\t"*(indent+1) + "kernel_core(psi, i0") + add = [] + for i in range(n): + add.append(" + i"+str(i+1)) + kernelarray.append("".join(add)) + for i in range(n): + kernelarray.append(", dsorted[" + str(n-1-i) + "]") + + if only_one_matrix: + kernelarray.append(", mm);\n") + else: + kernelarray.append(", mm, mmt);\n") + + #end for(s) and if + add = [""]*indent + for i in range(indent-1,0,-1): + add[indent-1-i] = "\t"*i+"}\n" + kernelarray.append("".join(add)) + + +################ @@@DBW: Start of _MSC_VER code block ################## + kernelarray.append("#else\n") + kernelarray.append(" std::intptr_t zero = 0;\n") + kernelarray.append(" std::intptr_t dmask = dsorted[0]"); + for i in range(n-1): kernelarray.append(" + dsorted["+str(i+1)+"]") + kernelarray.append( ";\n") + kernelarray.append("\n"); + kernelarray.append(" if (ctrlmask == 0){\n") + kernelarray.append(" #pragma omp parallel for schedule(static)\n") + kernelarray.append(" for (std::intptr_t i = 0; i < static_cast(n); ++i)\n") + kernelarray.append(" if ((i & dmask) == zero)\n") + kernelarray.append(" kernel_core(psi, i") + for i in range(n): kernelarray.append(", dsorted[" + str(n-1-i) + "]") + if only_one_matrix: kernelarray.append(", mm);\n") + else: kernelarray.append(", mm, mmt);\n") + # if controlmask != 0 + kernelarray.append(" } else {\n") + kernelarray.append(" #pragma omp parallel for schedule(static)\n") + kernelarray.append(" for (std::intptr_t i = 0; i < static_cast(n); ++i)\n") + kernelarray.append(" if ((i & ctrlmask) == ctrlmask && (i & dmask) == zero)\n") + kernelarray.append(" kernel_core(psi, i") + for i in range(n): kernelarray.append(", dsorted[" + str(n-1-i) + "]") + if only_one_matrix: kernelarray.append(", mm);\n") + else: kernelarray.append(", mm, mmt);\n") + kernelarray.append(" }\n") + kernelarray.append("#endif\n") + + kernelarray.append("}\n") + kernel = "".join([kernel,"".join(kernelarray)]) + return kernel + +def generate_includes(N): + return "#include \n#include \n#include \n#include \n#include \n#include \n" + \ + "#include \"alignedallocator.hpp\"\n#include \"timing.hpp\"\n#include \"cintrin.hpp\"\n" + \ + "#include \n#include \n\n" + \ + "#include \"util/par_for.hpp\"\n" + \ + "using namespace std;\n#define LOOP_COLLAPSE" + str(N) + " " + str(N+1) + "\n" + +def generate_main(n): + N = str(1 << n) + text = "using rowtype = vector,aligned_allocator,64>>;\nusing matrixtype = vector;\n\nint main(int argc, char *argv[]){" + text = text + "\n\tassert(argc > "+str(1+n)+");" + text = text + "\n\tsize_t N = 1ULL << atoi(argv[1]);" + for i in range(n): + text = text + "\n\tunsigned i" + str(i) + " = atoi(argv[" + str(i+2) + "]);" + + text = text + "\n\tmatrixtype m("+N+", rowtype("+N+"));"; + text = text + "\n\tfor (unsigned i = 0; i < "+N+"; ++i)\n\t\tfor (unsigned j = 0; j < "+N+"; ++j)\n\t\t\tm[i][j] = drand48();\n" + + text = text + "\n\tTimer t;\n\tfor (unsigned threads = 1; threads <= 24; ++threads){" + text = text + "\n\t\tomp_set_num_threads(threads);" + text = text + "\n\t\trowtype psi(N);\n\t\t#pragma omp parallel\n\t\t{\n\t\t\t#pragma omp for schedule(static)\n\t\t\tfor (size_t i = 0; i < psi.size(); ++i)\n\t\t\t\tpsi[i] = drand48();\n" + text = text + "\n\t\t\t#pragma omp single\n\t\t\tt.start();" + text = text + "\n\t\t\tkernel(psi, N" + for i in range(n): + text = text + ", i" + str(i) + text = text + ", m, 0);" + text = text + "\n\t\t\t#pragma omp waitall\n\t\t\t#pragma omp single\n\t\t\t{ cout << \"threads: \" << threads << \", time:\" << t.stop()*1.e-6 << \"\\n\"; }" + text = text + "\n\t\t}" # end for + text = text + "\n\t}" # end for + text = text + "\n\n}" # end main + return text + + +##################################################### +# MAIN # +##################################################### + +if len(sys.argv) < 2: + print("Generates the code for an n-qubit gate.\nUsage:\n./codegen_fma.py [n_qubits] {n_blocks} {only one matrix?} {unroll loops?} {none|avx2|avx512}\n\n") + exit() + +n = int(sys.argv[1]) # number of qubits + +try: # number of blocks + blocks = int(sys.argv[2]) +except Exception: + blocks = 1 + +try: + only_one_matrix = int(sys.argv[3]) +except Exception: + only_one_matrix = False + +try: + unroll_loops = int(sys.argv[4]) +except Exception: + unroll_loops = False + +try: + avx = str(sys.argv[5]) + if avx == "avx512": + avx = 4 + elif avx == "avx2" or avx == "avx": + avx = 2 + elif avx == "none": + avx = 1 + only_one_matrix = True + else: + raise RuntimeError("Unknown avx type: {}".format(avx)) +except IndexError: + avx = 2 + +while (1 << n)/blocks < 1: + blocks = int(blocks/2) + +if (1 << n) < avx: + avx = int(avx/2) + +kernel = generate_kernel(n, blocks, only_one_matrix, unroll_loops, avx) # generate code for n-qubit gate + +# if user wants a main (for testing) generate as well: +for a in sys.argv: + if str(a) == "gen_main": + kernel = generate_includes(n) + kernel + generate_main(n) + +print(kernel) diff --git a/src/Simulation/Native/codegen/codegen_test.cpp b/src/Simulation/Native/codegen/codegen_test.cpp new file mode 100644 index 00000000000..1ff778ce96d --- /dev/null +++ b/src/Simulation/Native/codegen/codegen_test.cpp @@ -0,0 +1,127 @@ +#include +#include +#include +#include +#include +#include +#include "alignedalloc.hpp" +//#include "timing.hpp" +#include "cintrin.hpp" +#include +#include + +#include "util/par_for.hpp" +using namespace std; +#define LOOP_COLLAPSE1 2 +// (C) 2018 ETH Zurich, ITP, Thomas H�ner and Damian Steiger + +template +inline void kernel_core(V& psi, std::size_t I, std::size_t d0, M const& m) +{ + std::complex v[2]; + + v[0] = psi[I]; + v[1] = psi[I + d0]; + + std::complex tmp[2] = {0., 0.}; + + tmp[0] = fma(v[0], m[0], fma(v[1], m[1], tmp[0])); + tmp[1] = fma(v[0], m[2], fma(v[1], m[3], tmp[1])); + psi[I] = tmp[0]; + psi[I + d0] = tmp[1]; + +} + +// bit indices id[.] are given from high to low (e.g. control first for CNOT) +template +void kernel(V& psi, unsigned id0, M const& matrix, std::size_t ctrlmask) +{ + std::size_t n = psi.size(); + std::size_t d0 = 1ULL << id0; + auto m = matrix; + std::size_t dsorted[] = {d0}; + permute_qubits_and_matrix(dsorted, 1, m); + + std::complex mm[4]; + for (unsigned b = 0; b < 1; ++b){ + for (unsigned r = 0; r < 2; ++r){ + for (unsigned c = 0; c < 2; ++c){ + mm[b*4+r*2+c] = m[r][c+b*2]; + } + } + } + + +#ifndef _MSC_VER + if (ctrlmask == 0){ + #pragma omp parallel for collapse(LOOP_COLLAPSE1) schedule(static) + for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ + for (std::size_t i1 = 0; i1 < dsorted[0]; ++i1){ + kernel_core(psi, i0 + i1, dsorted[0], mm); + } + } + } + else{ + #pragma omp parallel for collapse(LOOP_COLLAPSE1) schedule(static) + for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ + for (std::size_t i1 = 0; i1 < dsorted[0]; ++i1){ + if (((i0 + i1)&ctrlmask) == ctrlmask) + kernel_core(psi, i0 + i1, dsorted[0], mm); + } + } + } +#else + intptr_t zero = 0; + intptr_t dmask = dsorted[0]; + + if (ctrlmask == 0){ + auto thrdFnc= [&](size_t dsorted[],intptr_t& dmask, intptr_t& zero,V &psi,M const& m) { + return [&](unsigned i) { + if ((i & dmask) == zero) + kernel_core(psi, i, dsorted[0], m); + }; + }; + pl::async_par_for(0,n,thrdFnc(dsorted,dmask,zero,psi,m)); + } else { + auto thrdFnc= [&](size_t dsorted[],size_t& ctrlmask,intptr_t& dmask, intptr_t& zero,V &psi,M const& m) { + return [&](unsigned i) { + if ((i & ctrlmask) == ctrlmask && (i & dmask) == zero) + kernel_core(psi, i, dsorted[0], m); + }; + }; + pl::async_par_for(0,n,thrdFnc(dsorted,ctrlmask,dmask,zero,psi,m)); + } +#endif +} +using rowtype = vector,AlignedAlloc,64>>; +using matrixtype = vector; + +int main(int argc, char *argv[]){ + assert(argc > 2); + size_t N = 1ULL << atoi(argv[1]); + unsigned i0 = atoi(argv[2]); + matrixtype m(2, rowtype(2)); + for (unsigned i = 0; i < 2; ++i) + for (unsigned j = 0; j < 2; ++j) + m[i][j] = drand48(); + + Timer t; + for (unsigned threads = 1; threads <= 24; ++threads){ + omp_set_num_threads(threads); + rowtype psi(N); + #pragma omp parallel + { + #pragma omp for schedule(static) + for (size_t i = 0; i < psi.size(); ++i) + psi[i] = drand48(); + + #pragma omp single + t.start(); + kernel(psi, N, i0, m, 0); + #pragma omp waitall + #pragma omp single + { cout << "threads: " << threads << ", time:" << t.stop()*1.e-6 << "\n"; } + } + } + +} diff --git a/src/Simulation/Native/codegen/generate.ps1 b/src/Simulation/Native/codegen/generate.ps1 new file mode 100644 index 00000000000..1cc506d187b --- /dev/null +++ b/src/Simulation/Native/codegen/generate.ps1 @@ -0,0 +1,21 @@ +# onematrix[i] determines whether to use a single gate matrix for the i-qubit gate kernel +# instead of using two matrices (which allows to reduce the number of operations +# by pre-computation) +$onematrix=(0,0,0,0,0,0,1,1) # g++ best + +# unroll[i] determines whether to unroll loops +$unroll=(1,1,1,1,1,1,0,0) # g++ best + +# register length to use: can be none, avx2, or avx512 +# avx=avx2 + +# blocking: must be a power of two and at most 2^k for a k-qubit gate +$b=(0,2,4,8,16,16,16,32) # gcc & icc best + +foreach ($i in 1..7) { + "Generating $i kernel with $b[$i] blocks." + python codegen_fma.py $i $b[$i] $onematrix[$i] $unroll[$i] none > nointrin/kernel$i.hpp + python codegen_fma.py $i $b[$i] $onematrix[$i] $unroll[$i] avx > avx/kernel$i.hpp + python codegen_fma.py $i $b[$i] $onematrix[$i] $unroll[$i] avx2 > avx2/kernel$i.hpp + python codegen_fma.py $i $b[$i] $onematrix[$i] $unroll[$i] avx512 > avx512/kernel$i.hpp +} \ No newline at end of file diff --git a/src/Simulation/Native/codegen/generate.sh b/src/Simulation/Native/codegen/generate.sh new file mode 100644 index 00000000000..2ec0557d571 --- /dev/null +++ b/src/Simulation/Native/codegen/generate.sh @@ -0,0 +1,28 @@ +#!/bin/bash +# (C) 2018 ETH Zurich, ITP, Thomas Häner and Damian Steiger + +# onematrix[i] determines whether to use a single gate matrix for the i-qubit gate kernel +# instead of using two matrices (which allows to reduce the number of operations +# by pre-computation) +onematrix=(0 0 0 0 0 0 1 1) # g++ best +#onematrix=(0 0 1 0 0 0 1 1) # icc best + +# unroll[i] determines whether to unroll loops +unroll=(1 1 1 1 1 1 0 0) # g++ best +#unroll=(1 1 1 0 0 1 0 0) # icc best +#unroll=(0 0 0 0 0 0 0 0) + +# register length to use: can be none, avx2, or avx512 +avx=avx2 + +# blocking: must be a power of two and at most 2^k for a k-qubit gate +b=(0 2 4 8 16 16 16 32) # gcc & icc best + +for i in {1..7} +do + echo "Generating $i kernel with ${b[$i]} blocks." + ./codegen_fma.py $i ${b[$i]} ${onematrix[$i]} ${unroll[$i]} none > ../nointrin/kernel${i}.hpp + ./codegen_fma.py $i ${b[$i]} ${onematrix[$i]} ${unroll[$i]} avx > ../avx/kernel${i}.hpp + ./codegen_fma.py $i ${b[$i]} ${onematrix[$i]} ${unroll[$i]} avx2 > ../avx2/kernel${i}.hpp + ./codegen_fma.py $i ${b[$i]} ${onematrix[$i]} ${unroll[$i]} avx512 > ../avx512/kernel${i}.hpp +done diff --git a/src/Simulation/Native/src/config.hpp b/src/Simulation/Native/src/config.hpp new file mode 100644 index 00000000000..363baa4d241 --- /dev/null +++ b/src/Simulation/Native/src/config.hpp @@ -0,0 +1,50 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#pragma once + +#include + +// check if we want to force single precision +/* #undef USE_SINGLE_PRECISION */ + +// check if we have AVX intrinsics +/* #undef HAVE_INTRINSICS */ + +// check if we have AVX-512 intrinsics +/* #undef HAVE_AVX512 */ + +// check if we want to use fused kernels +#define USE_GATE_FUSION + +#define BUILD_SHARED_LIBS + + +#if defined (_MSC_VER) && defined (BUILD_SHARED_LIBS) + +#ifdef BUILD_DLL +#define MICROSOFT_QUANTUM_DECL __declspec(dllexport) +#else +#define MICROSOFT_QUANTUM_DECL __declspec(dllimport) +#endif +#define MICROSOFT_QUANTUM_DECL_IMPORT __declspec(dllimport) +#else +#define MICROSOFT_QUANTUM_DECL +#define MICROSOFT_QUANTUM_DECL_IMPORT +#endif + +#ifdef HAVE_INTRINSICS +#ifdef HAVE_AVX512 +#define SIMULATOR SimulatorAVX512 +#else +#ifdef HAVE_FMA +#define SIMULATOR SimulatorAVX2 +#else +#define SIMULATOR SimulatorAVX +#endif +#endif +#else +#define SIMULATOR SimulatorGeneric +#endif + + diff --git a/src/Simulation/Native/src/external/avx/kernel1.hpp b/src/Simulation/Native/src/external/avx/kernel1.hpp index eac0cf47ea4..c10e4581a8f 100644 --- a/src/Simulation/Native/src/external/avx/kernel1.hpp +++ b/src/Simulation/Native/src/external/avx/kernel1.hpp @@ -49,7 +49,8 @@ void kernel(V& psi, unsigned id0, M const& matrix, std::size_t ctrlmask) #ifndef _MSC_VER if (ctrlmask == 0){ - #pragma omp for collapse(LOOP_COLLAPSE1) schedule(static) + //@@@DBW Was missing parallel directive + #pragma omp parallel for collapse(LOOP_COLLAPSE1) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; ++i1){ kernel_core(psi, i0 + i1, dsorted[0], mm, mmt); @@ -57,7 +58,8 @@ void kernel(V& psi, unsigned id0, M const& matrix, std::size_t ctrlmask) } } else{ - #pragma omp for collapse(LOOP_COLLAPSE1) schedule(static) + //@@@DBW Was missing parallel directive + #pragma omp parallel for collapse(LOOP_COLLAPSE1) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; ++i1){ if (((i0 + i1)&ctrlmask) == ctrlmask) diff --git a/src/Simulation/Native/src/external/avx/kernel2.hpp b/src/Simulation/Native/src/external/avx/kernel2.hpp index 24f6c8ee13d..bc2d09cafa6 100644 --- a/src/Simulation/Native/src/external/avx/kernel2.hpp +++ b/src/Simulation/Native/src/external/avx/kernel2.hpp @@ -63,7 +63,8 @@ void kernel(V& psi, unsigned id1, unsigned id0, M const& matrix, std::size_t ctr #ifndef _MSC_VER if (ctrlmask == 0){ - #pragma omp for collapse(LOOP_COLLAPSE2) schedule(static) + //@@@DBW Was missing parallel directive + #pragma omp parallel for collapse(LOOP_COLLAPSE2) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ for (std::size_t i2 = 0; i2 < dsorted[1]; ++i2){ @@ -73,7 +74,8 @@ void kernel(V& psi, unsigned id1, unsigned id0, M const& matrix, std::size_t ctr } } else{ - #pragma omp for collapse(LOOP_COLLAPSE2) schedule(static) + //@@@DBW Was missing parallel directive + #pragma omp parallel for collapse(LOOP_COLLAPSE2) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ for (std::size_t i2 = 0; i2 < dsorted[1]; ++i2){ diff --git a/src/Simulation/Native/src/external/avx/kernel3.hpp b/src/Simulation/Native/src/external/avx/kernel3.hpp index a63dbc28693..6970e8b3684 100644 --- a/src/Simulation/Native/src/external/avx/kernel3.hpp +++ b/src/Simulation/Native/src/external/avx/kernel3.hpp @@ -102,7 +102,8 @@ void kernel(V& psi, unsigned id2, unsigned id1, unsigned id0, M const& matrix, s #ifndef _MSC_VER if (ctrlmask == 0){ - #pragma omp for collapse(LOOP_COLLAPSE3) schedule(static) + //@@@DBW Was missing parallel directive + #pragma omp parallel for collapse(LOOP_COLLAPSE3) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ for (std::size_t i2 = 0; i2 < dsorted[1]; i2 += 2 * dsorted[2]){ @@ -114,7 +115,8 @@ void kernel(V& psi, unsigned id2, unsigned id1, unsigned id0, M const& matrix, s } } else{ - #pragma omp for collapse(LOOP_COLLAPSE3) schedule(static) + //@@@DBW Was missing parallel directive + #pragma omp parallel for collapse(LOOP_COLLAPSE3) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ for (std::size_t i2 = 0; i2 < dsorted[1]; i2 += 2 * dsorted[2]){ diff --git a/src/Simulation/Native/src/external/avx/kernel4.hpp b/src/Simulation/Native/src/external/avx/kernel4.hpp index 92f573a0255..2c3ff29c724 100644 --- a/src/Simulation/Native/src/external/avx/kernel4.hpp +++ b/src/Simulation/Native/src/external/avx/kernel4.hpp @@ -227,7 +227,8 @@ void kernel(V& psi, unsigned id3, unsigned id2, unsigned id1, unsigned id0, M co #ifndef _MSC_VER if (ctrlmask == 0){ - #pragma omp for collapse(LOOP_COLLAPSE4) schedule(static) + //@@@DBW Was missing parallel directive + #pragma omp parallel for collapse(LOOP_COLLAPSE4) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ for (std::size_t i2 = 0; i2 < dsorted[1]; i2 += 2 * dsorted[2]){ @@ -241,7 +242,8 @@ void kernel(V& psi, unsigned id3, unsigned id2, unsigned id1, unsigned id0, M co } } else{ - #pragma omp for collapse(LOOP_COLLAPSE4) schedule(static) + //@@@DBW Was missing parallel directive + #pragma omp parallel for collapse(LOOP_COLLAPSE4) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ for (std::size_t i2 = 0; i2 < dsorted[1]; i2 += 2 * dsorted[2]){ diff --git a/src/Simulation/Native/src/external/avx/kernel5.hpp b/src/Simulation/Native/src/external/avx/kernel5.hpp index 0cdba4b89c5..99b462f45ec 100644 --- a/src/Simulation/Native/src/external/avx/kernel5.hpp +++ b/src/Simulation/Native/src/external/avx/kernel5.hpp @@ -380,7 +380,8 @@ void kernel(V& psi, unsigned id4, unsigned id3, unsigned id2, unsigned id1, unsi #ifndef _MSC_VER if (ctrlmask == 0){ - #pragma omp for collapse(LOOP_COLLAPSE5) schedule(static) + //@@@DBW Was missing parallel directive + #pragma omp parallel for collapse(LOOP_COLLAPSE5) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ for (std::size_t i2 = 0; i2 < dsorted[1]; i2 += 2 * dsorted[2]){ @@ -396,7 +397,8 @@ void kernel(V& psi, unsigned id4, unsigned id3, unsigned id2, unsigned id1, unsi } } else{ - #pragma omp for collapse(LOOP_COLLAPSE5) schedule(static) + //@@@DBW Was missing parallel directive + #pragma omp parallel for collapse(LOOP_COLLAPSE5) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ for (std::size_t i2 = 0; i2 < dsorted[1]; i2 += 2 * dsorted[2]){ diff --git a/src/Simulation/Native/src/external/avx/kernel6.hpp b/src/Simulation/Native/src/external/avx/kernel6.hpp index 343c6e3154c..4b2312853ee 100644 --- a/src/Simulation/Native/src/external/avx/kernel6.hpp +++ b/src/Simulation/Native/src/external/avx/kernel6.hpp @@ -212,7 +212,8 @@ void kernel(V& psi, unsigned id5, unsigned id4, unsigned id3, unsigned id2, unsi #ifndef _MSC_VER if (ctrlmask == 0){ - #pragma omp for collapse(LOOP_COLLAPSE6) schedule(static) + //@@@DBW Was missing parallel directive + #pragma omp parallel for collapse(LOOP_COLLAPSE6) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ for (std::size_t i2 = 0; i2 < dsorted[1]; i2 += 2 * dsorted[2]){ @@ -230,7 +231,8 @@ void kernel(V& psi, unsigned id5, unsigned id4, unsigned id3, unsigned id2, unsi } } else{ - #pragma omp for collapse(LOOP_COLLAPSE6) schedule(static) + //@@@DBW Was missing parallel directive + #pragma omp parallel for collapse(LOOP_COLLAPSE6) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ for (std::size_t i2 = 0; i2 < dsorted[1]; i2 += 2 * dsorted[2]){ diff --git a/src/Simulation/Native/src/external/avx/kernel7.hpp b/src/Simulation/Native/src/external/avx/kernel7.hpp index ecd0f45f3cf..70e722552a3 100644 --- a/src/Simulation/Native/src/external/avx/kernel7.hpp +++ b/src/Simulation/Native/src/external/avx/kernel7.hpp @@ -389,7 +389,8 @@ void kernel(V& psi, unsigned id6, unsigned id5, unsigned id4, unsigned id3, unsi #ifndef _MSC_VER if (ctrlmask == 0){ - #pragma omp for collapse(LOOP_COLLAPSE7) schedule(static) + //@@@DBW Was missing parallel directive + #pragma omp parallel for collapse(LOOP_COLLAPSE7) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ for (std::size_t i2 = 0; i2 < dsorted[1]; i2 += 2 * dsorted[2]){ @@ -409,7 +410,8 @@ void kernel(V& psi, unsigned id6, unsigned id5, unsigned id4, unsigned id3, unsi } } else{ - #pragma omp for collapse(LOOP_COLLAPSE7) schedule(static) + //@@@DBW Was missing parallel directive + #pragma omp parallel for collapse(LOOP_COLLAPSE7) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ for (std::size_t i2 = 0; i2 < dsorted[1]; i2 += 2 * dsorted[2]){ diff --git a/src/Simulation/Native/src/external/avx2/kernel1.hpp b/src/Simulation/Native/src/external/avx2/kernel1.hpp index eac0cf47ea4..c10e4581a8f 100644 --- a/src/Simulation/Native/src/external/avx2/kernel1.hpp +++ b/src/Simulation/Native/src/external/avx2/kernel1.hpp @@ -49,7 +49,8 @@ void kernel(V& psi, unsigned id0, M const& matrix, std::size_t ctrlmask) #ifndef _MSC_VER if (ctrlmask == 0){ - #pragma omp for collapse(LOOP_COLLAPSE1) schedule(static) + //@@@DBW Was missing parallel directive + #pragma omp parallel for collapse(LOOP_COLLAPSE1) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; ++i1){ kernel_core(psi, i0 + i1, dsorted[0], mm, mmt); @@ -57,7 +58,8 @@ void kernel(V& psi, unsigned id0, M const& matrix, std::size_t ctrlmask) } } else{ - #pragma omp for collapse(LOOP_COLLAPSE1) schedule(static) + //@@@DBW Was missing parallel directive + #pragma omp parallel for collapse(LOOP_COLLAPSE1) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; ++i1){ if (((i0 + i1)&ctrlmask) == ctrlmask) diff --git a/src/Simulation/Native/src/external/avx2/kernel2.hpp b/src/Simulation/Native/src/external/avx2/kernel2.hpp index 24f6c8ee13d..bc2d09cafa6 100644 --- a/src/Simulation/Native/src/external/avx2/kernel2.hpp +++ b/src/Simulation/Native/src/external/avx2/kernel2.hpp @@ -63,7 +63,8 @@ void kernel(V& psi, unsigned id1, unsigned id0, M const& matrix, std::size_t ctr #ifndef _MSC_VER if (ctrlmask == 0){ - #pragma omp for collapse(LOOP_COLLAPSE2) schedule(static) + //@@@DBW Was missing parallel directive + #pragma omp parallel for collapse(LOOP_COLLAPSE2) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ for (std::size_t i2 = 0; i2 < dsorted[1]; ++i2){ @@ -73,7 +74,8 @@ void kernel(V& psi, unsigned id1, unsigned id0, M const& matrix, std::size_t ctr } } else{ - #pragma omp for collapse(LOOP_COLLAPSE2) schedule(static) + //@@@DBW Was missing parallel directive + #pragma omp parallel for collapse(LOOP_COLLAPSE2) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ for (std::size_t i2 = 0; i2 < dsorted[1]; ++i2){ diff --git a/src/Simulation/Native/src/external/avx2/kernel3.hpp b/src/Simulation/Native/src/external/avx2/kernel3.hpp index a63dbc28693..6970e8b3684 100644 --- a/src/Simulation/Native/src/external/avx2/kernel3.hpp +++ b/src/Simulation/Native/src/external/avx2/kernel3.hpp @@ -102,7 +102,8 @@ void kernel(V& psi, unsigned id2, unsigned id1, unsigned id0, M const& matrix, s #ifndef _MSC_VER if (ctrlmask == 0){ - #pragma omp for collapse(LOOP_COLLAPSE3) schedule(static) + //@@@DBW Was missing parallel directive + #pragma omp parallel for collapse(LOOP_COLLAPSE3) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ for (std::size_t i2 = 0; i2 < dsorted[1]; i2 += 2 * dsorted[2]){ @@ -114,7 +115,8 @@ void kernel(V& psi, unsigned id2, unsigned id1, unsigned id0, M const& matrix, s } } else{ - #pragma omp for collapse(LOOP_COLLAPSE3) schedule(static) + //@@@DBW Was missing parallel directive + #pragma omp parallel for collapse(LOOP_COLLAPSE3) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ for (std::size_t i2 = 0; i2 < dsorted[1]; i2 += 2 * dsorted[2]){ diff --git a/src/Simulation/Native/src/external/avx2/kernel4.hpp b/src/Simulation/Native/src/external/avx2/kernel4.hpp index 92f573a0255..2c3ff29c724 100644 --- a/src/Simulation/Native/src/external/avx2/kernel4.hpp +++ b/src/Simulation/Native/src/external/avx2/kernel4.hpp @@ -227,7 +227,8 @@ void kernel(V& psi, unsigned id3, unsigned id2, unsigned id1, unsigned id0, M co #ifndef _MSC_VER if (ctrlmask == 0){ - #pragma omp for collapse(LOOP_COLLAPSE4) schedule(static) + //@@@DBW Was missing parallel directive + #pragma omp parallel for collapse(LOOP_COLLAPSE4) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ for (std::size_t i2 = 0; i2 < dsorted[1]; i2 += 2 * dsorted[2]){ @@ -241,7 +242,8 @@ void kernel(V& psi, unsigned id3, unsigned id2, unsigned id1, unsigned id0, M co } } else{ - #pragma omp for collapse(LOOP_COLLAPSE4) schedule(static) + //@@@DBW Was missing parallel directive + #pragma omp parallel for collapse(LOOP_COLLAPSE4) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ for (std::size_t i2 = 0; i2 < dsorted[1]; i2 += 2 * dsorted[2]){ diff --git a/src/Simulation/Native/src/external/avx2/kernel5.hpp b/src/Simulation/Native/src/external/avx2/kernel5.hpp index 0cdba4b89c5..99b462f45ec 100644 --- a/src/Simulation/Native/src/external/avx2/kernel5.hpp +++ b/src/Simulation/Native/src/external/avx2/kernel5.hpp @@ -380,7 +380,8 @@ void kernel(V& psi, unsigned id4, unsigned id3, unsigned id2, unsigned id1, unsi #ifndef _MSC_VER if (ctrlmask == 0){ - #pragma omp for collapse(LOOP_COLLAPSE5) schedule(static) + //@@@DBW Was missing parallel directive + #pragma omp parallel for collapse(LOOP_COLLAPSE5) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ for (std::size_t i2 = 0; i2 < dsorted[1]; i2 += 2 * dsorted[2]){ @@ -396,7 +397,8 @@ void kernel(V& psi, unsigned id4, unsigned id3, unsigned id2, unsigned id1, unsi } } else{ - #pragma omp for collapse(LOOP_COLLAPSE5) schedule(static) + //@@@DBW Was missing parallel directive + #pragma omp parallel for collapse(LOOP_COLLAPSE5) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ for (std::size_t i2 = 0; i2 < dsorted[1]; i2 += 2 * dsorted[2]){ diff --git a/src/Simulation/Native/src/external/avx2/kernel6.hpp b/src/Simulation/Native/src/external/avx2/kernel6.hpp index 343c6e3154c..4b2312853ee 100644 --- a/src/Simulation/Native/src/external/avx2/kernel6.hpp +++ b/src/Simulation/Native/src/external/avx2/kernel6.hpp @@ -212,7 +212,8 @@ void kernel(V& psi, unsigned id5, unsigned id4, unsigned id3, unsigned id2, unsi #ifndef _MSC_VER if (ctrlmask == 0){ - #pragma omp for collapse(LOOP_COLLAPSE6) schedule(static) + //@@@DBW Was missing parallel directive + #pragma omp parallel for collapse(LOOP_COLLAPSE6) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ for (std::size_t i2 = 0; i2 < dsorted[1]; i2 += 2 * dsorted[2]){ @@ -230,7 +231,8 @@ void kernel(V& psi, unsigned id5, unsigned id4, unsigned id3, unsigned id2, unsi } } else{ - #pragma omp for collapse(LOOP_COLLAPSE6) schedule(static) + //@@@DBW Was missing parallel directive + #pragma omp parallel for collapse(LOOP_COLLAPSE6) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ for (std::size_t i2 = 0; i2 < dsorted[1]; i2 += 2 * dsorted[2]){ diff --git a/src/Simulation/Native/src/external/avx2/kernel7.hpp b/src/Simulation/Native/src/external/avx2/kernel7.hpp index ecd0f45f3cf..70e722552a3 100644 --- a/src/Simulation/Native/src/external/avx2/kernel7.hpp +++ b/src/Simulation/Native/src/external/avx2/kernel7.hpp @@ -389,7 +389,8 @@ void kernel(V& psi, unsigned id6, unsigned id5, unsigned id4, unsigned id3, unsi #ifndef _MSC_VER if (ctrlmask == 0){ - #pragma omp for collapse(LOOP_COLLAPSE7) schedule(static) + //@@@DBW Was missing parallel directive + #pragma omp parallel for collapse(LOOP_COLLAPSE7) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ for (std::size_t i2 = 0; i2 < dsorted[1]; i2 += 2 * dsorted[2]){ @@ -409,7 +410,8 @@ void kernel(V& psi, unsigned id6, unsigned id5, unsigned id4, unsigned id3, unsi } } else{ - #pragma omp for collapse(LOOP_COLLAPSE7) schedule(static) + //@@@DBW Was missing parallel directive + #pragma omp parallel for collapse(LOOP_COLLAPSE7) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ for (std::size_t i2 = 0; i2 < dsorted[1]; i2 += 2 * dsorted[2]){ diff --git a/src/Simulation/Native/src/external/cintrin.hpp b/src/Simulation/Native/src/external/cintrin.hpp index 8034408c1e8..80323fe43f4 100644 --- a/src/Simulation/Native/src/external/cintrin.hpp +++ b/src/Simulation/Native/src/external/cintrin.hpp @@ -35,7 +35,10 @@ inline void permute_qubits_and_matrix(I *delta_list, unsigned n, M & matrix){ } inline std::complex fma(std::complex const& c1, std::complex const& c2, std::complex const& a){ - return c1*c2 + a; + //@@@DBW: Expanded complex FMA to hard coded access (much faster) + double r = (c1._Val[0] * c2._Val[0] - c1._Val[1] * c2._Val[1]) + a._Val[0]; + double i = (c1._Val[0] * c2._Val[1] + c1._Val[1] * c2._Val[0]) + a._Val[1]; + return std::complex(r, i); } inline __m256d fma(__m256d const& c1, __m256d const& c2, __m256d const& a){ diff --git a/src/Simulation/Native/src/external/fused.hpp b/src/Simulation/Native/src/external/fused.hpp index 6c1137ceb3b..4a18ba7b5ae 100644 --- a/src/Simulation/Native/src/external/fused.hpp +++ b/src/Simulation/Native/src/external/fused.hpp @@ -15,7 +15,7 @@ #ifdef HAVE_FMA #include "external/avx2/kernels.hpp" #else -#include "external/avx2/kernels.hpp" +#include "external/avx/kernels.hpp" //@@@DBW: This was mistakenly avx2 #endif #endif #endif @@ -30,7 +30,11 @@ namespace SIMULATOR class Fused { public: - Fused() {} + Fused() { + wfnCapacity = 0u; //@@@DBW used to optimize runtime parameters + maxFusedSpan =-1; //@@@DBW determine span to use at runtime + maxFusedDepth = 99; //@@@DBW determine max depth to use at runtime + } inline void reset() { @@ -48,7 +52,7 @@ class Fused Fusion::IndexVector qs, cs; fusedgates.perform_fusion(m, qs, cs); - + std::size_t cmask = 0; for (auto c : cs) cmask |= (1ull << c); @@ -71,7 +75,7 @@ class Fused ::kernel(wfn, qs[4], qs[3], qs[2], qs[1], qs[0], m, cmask); break; } - + fusedgates = Fusion(); } @@ -98,20 +102,42 @@ class Fused template void apply_controlled(std::vector& wfn, M const& mat, std::vector const& cs, unsigned q) { - if (fusedgates.num_qubits()+fusedgates.num_controls()+cs.size()>8 || fusedgates.size() > 15) - flush(wfn); - Fusion newgates = fusedgates; - newgates.insert(convertMatrix(mat), std::vector(1, q), cs); - - if (newgates.num_qubits() > 4) - { - flush(wfn); - fusedgates.insert(convertMatrix(mat), std::vector(1, q), cs); - } - else - fusedgates = newgates; + //@@@DBW Major runtime logic change here + + // Have to update capacity as the WFN grows + if (wfnCapacity != wfn.capacity()) { + wfnCapacity = wfn.capacity(); + char* envNT = NULL; + size_t len; +#ifdef _MSC_VER + errno_t err = _dupenv_s(&envNT, &len, "OMP_NUM_THREADS"); +#else + envNT = getenv("OMP_NUM_THREADS"); +#endif + if (envNT == NULL) { // If the user didn't force the number of threads, make an intelligent guess + int nMaxThrds = 4; + if (wfnCapacity < 1ul << 20) nMaxThrds = 3; + int nProcs = omp_get_num_procs(); + if (nProcs < 3) nMaxThrds = nProcs; + omp_set_num_threads(nMaxThrds); + } + + // This is now pretty much unlimited, could be set in the future + maxFusedDepth = 99; + + // Default for large problems (optimized with benchmarks) + maxFusedSpan = 3; + + // Reduce size for small problems (optimized with benchmarks) + if (wfnCapacity < 1ul << 20) maxFusedSpan = 2; + } + + // New rules of when to stop fusing + Fusion::IndexVector qs = std::vector(1, q); + if (fusedgates.predict(qs, cs) > maxFusedSpan || fusedgates.size() >= maxFusedDepth) flush(wfn); + fusedgates.insert(convertMatrix(mat), qs, cs); } - + template void apply(std::vector& wfn, M const& mat, unsigned q) { @@ -120,6 +146,11 @@ class Fused } private: mutable Fusion fusedgates; + + //@@@DBW: New runtime optimizatin settings + mutable size_t wfnCapacity; + mutable int maxFusedSpan; + mutable int maxFusedDepth; }; diff --git a/src/Simulation/Native/src/external/fusion.hpp b/src/Simulation/Native/src/external/fusion.hpp index 2e6b4bdb50d..ccfcb62e6d9 100644 --- a/src/Simulation/Native/src/external/fusion.hpp +++ b/src/Simulation/Native/src/external/fusion.hpp @@ -58,6 +58,18 @@ class Fusion{ handle_controls(empty_matrix, empty_vec, {}); // remove all current control qubits (this is a GLOBAL factor) } + + //@@@DBW: This saves a class instance create/destroy on every gate insert + // Need a quick way to decide if we're going to grow too wide + int predict(IndexVector index_list, IndexVector const& ctrl_list = {}) { + int cnt = num_qubits() + num_controls(); + for (auto idx : index_list) + if (set_.count(idx) == 0 && ctrl_set_.count(idx) == 0) cnt++; + for (auto idx : ctrl_list) + if (set_.count(idx) == 0 && ctrl_set_.count(idx) == 0) cnt++; + return cnt; + } + void insert(Matrix matrix, IndexVector index_list, IndexVector const& ctrl_list = {}){ for (auto idx : index_list) set_.emplace(idx); @@ -97,7 +109,8 @@ class Fusion{ for (unsigned i = 0; i < idx.size(); ++i) idx2mat[i] = static_cast(((std::equal_range(index_list.begin(), index_list.end(), idx[i])).first - index_list.begin())); - for (std::size_t k = 0; k < (1ULL< oldcol(1ULL< const& wfn, std::vector chunks; -#pragma omp parallel +//@@@DBW remove nested parallel omp directive { #pragma omp single chunks = split_interval_in_chunks(max, omp_get_num_threads()); @@ -446,7 +446,7 @@ bool istensorproduct(std::vector const& wfn, std::size_t compl_st = compl_bits.to_ullong(); std::atomic go(true); -#pragma omp parallel +//@@@DBW remove nested omp parallel { int thread_id = omp_get_thread_num(); if (thread_id < chunks.size() - 1) diff --git a/src/Simulation/Native/src/version.hpp b/src/Simulation/Native/src/version.hpp new file mode 100644 index 00000000000..b55afdfd213 --- /dev/null +++ b/src/Simulation/Native/src/version.hpp @@ -0,0 +1,11 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#pragma once + +/* #undef MICROSOFT_QUANTUM_SIMULATOR_VERSION */ +/* #undef MICROSOFT_QUANTUM_SIMULATOR_VERSION_MAJOR */ +/* #undef MICROSOFT_QUANTUM_SIMULATOR_VERSION_MINOR */ +/* #undef MICROSOFT_QUANTUM_SIMULATOR_VERSION_PATCH */ +/* #undef MICROSOFT_QUANTUM_SIMULATOR_VERSION_STRING */ +#define MICROSOFT_QUANTUM_SIMULATOR_YEAR "2020" diff --git a/src/Simulation/Native/win10/vcomp140.dll b/src/Simulation/Native/win10/vcomp140.dll deleted file mode 100644 index 872663e58d4e89f42a2c7f9c3e3977b5751d5d32..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 155296 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 z zs(5Erwp_V1Ay=W=DO1vNtq;sL{O%9G80Qm*grsONLcvxjn5F#%V2M$B+T%bVC6L_ zVO1nyVu=;B7Yp6m+ccGq+F$%N{L1QPVjILEsIGeoPw3eYvnR!j-})&M$q&#;^0$#b zYdbqrRfQLl!~wjh3KG}9k_ak+wu#zTpc+db$=_b3 z{z7;jq-Vb`lB}-<)$bEF1BoAr4vAnH9(D-yE&+N%{Ak8qnvI+xfCdp(k^o*#1)rmK zb!$dJ`1rq}VAm;%U(#+)+Nti@Nk0fipwHo^l$$k-WtGuMt9946FUAV4?kin!j70`3 zw@)&M$93jnP!VR~v1+M_*zH3MhSTp2ADb1)^{a~~cm5rTWy>c;Zjt%UO=JO-E%&UN z;paEPJg;B@xE{T4g(o(YTEiFnIm4O>Y}|^{aIW9mAxlrj5;@}GiC6%=b#RFeUskD; z!QU0s5quFV2r3D4%aDx~;sZR1_e5XVMy4)4{5Fh`*Wqp;0jYKeF?xKwyZSRQcY|*Ey)(lBV;E7V;1x=rid6*o!Bps z!WxG!n=>F?a2taj5LSpBz9 z>+VYRVUY*Io8&L%{Aqc0zI)2@8scjRvowqUS&$NdQ&Tr3KD{~oQMW< zspk`#_(7U!&WG%x{oeM)c_AFuxS? z&5CzdL9!80Ak!=`#;k}^8I;H;;ZD;G6nhR6%Q@uu>nGU;!IE}N%HIorr11a!3?sq` z{>Wzvh5rwK`}~o!@CGw5`VNeT0qoY(?l&P|L7#V0iQbu z!pALgrtrzb8}OmNO!z$X=GW1upMMna^9g<}f)LFm2i4o)7qBaWBj7wHD+nTBs*F)v zECb8J?=lZ5rA)m6QOPobID>AvJLU}6M*}qTgQkH~e2B{8?^(5te*U5vjI;)oBQ3m(s4C404ZhEN&dK|-uv|HzTFZ!Ej*!=B7;`&>b7YCAPu zmEF{ERW8KOJfcIg)qXWNO0@cpbgOM>bx^dr zv56)l^yF%`wm_{0JA4JA#pwUZ7NeKVK&Y~Ic<{+voa~$F_9o{TK6qY)7Dn^_AeN^w z*C3^n@(a~|j#*9-R#s^Ruk9-2yJ3Ph?Ok=bAEB6j z-i4L$cUW}h3jB5lI9Sl>S1lD$+n|88rLCO8a!hJDXmsrmrW`Rx-bXAi#)624dAF@} z2cvQxjfSD9O(Ct06+-xis-iw*hP`qWqwuQR5Gti7ZuEP1t(+O)Z%>cfs?G(_kTp(K z)54~q2cPT9Ik*0+g_W zVd^0K2TPOV;H)dcl0hh1u|igs{=*c8ORN%>0c<{hZgo(Jp=2D)`OqABmn06xtXLkI zN4lvVc7V@VKxPBP`OHc)=s1PBZ0ba!K{FFLhl^ojd*$tXFda zd}oR$$C~yEM!=~B(+7?ugdOyB3p??BKeh^Vuew~OIKUqW`?mN^KYtbTKGhuXzRse- zA=2Y9S>GyK+f=!$JZiH9tZ`ND^?To3aR8n!>Dg9w>QXscAwm?aufpQ@nAE8&!WgVt z0eTF@`$r!o(8|3a6s8$i&b0_SF=eZuQ;-<>9`#Vr2ja1ULcImiGKeM5fyF+M-#1M! z@*R={S5dt5ODPdf#UM1`3#&Z}SMhHCrU*dDLChj#xc( zK&WGeXfD zpe{QR>^exGK#mZ2c+oLXdpm7hh>mDM<-3B`*8;^DvGY*LNM_xUMl6YoAod}{6$g<< z+=#LqOVO8rSH)slDB8x9dwUJ3_Azb=s(!~ja0?Us7^aix69Y-L;9F9(!L2M_^>faq zScUiq#vd+kQ zpAeklA>k2+w-Nqw&}d(Xe;DG2FiKn%K&*T82UJUt!#L&UQaZ11NYTNx?^{rZfd- zoP>hH5ea#RFA_G`?eIq~hCi~uFETa59oU}Q31XaRPt}}7_QIL?+hE2SQ^HTF+`-mtAx?;iT8jNLO>JwST9CFk&9Lt`yxVr zHWJCua1aLaH7WfgLO0MBgA9*EdcO*Pgo{r>~ z=nr4WQ!)ha0L2FcODU2Ci=;;jP+`=58r7REDXsX{SM76n1801IOp;QTtXbGu8KECS zga;bujCj^g%>mrV5KM-3`S~IQ?ass^+uq26=rp(XAolwt<5!A+*|LYtCUqf9K1^Ee zlOaHUbqNAxb6DF{Cs4t+QP`z`5{SqJn;aDJwOmAe=@jt=y@9{mwI2>jhf5)TgYm0j zQ3?xDn1>WXDk8q77qwoEh%fX2A9$9IDNXM8$uHbZvVEbTOM3_b8#1pRg_)QuI!)(W z$!)?$MG`WvDJXtBF<9A-O;;V-{e$49?a!iq^jQkSx!!F=NFx4mmxz>+8sli3?%H$) z`4|~ORcVFtw}SW-{J0Fkk2-=M|5K#YpfyJO?~TszX;pjE4)}?n+GP(J-u0;cPar0( z7Qw>7!V%&#S2<<%>LOWPHBMf;%7gb(;X_YBle$6_KNrc_LStRx>?#VQL->H?De@gp8pf2?Ygczo}06H;tsb9Q_QN%1^ zI5=ViFF7zIYqA}HXkQ5l80eS12aTk=l;__kU^Eg8BL-?-8qD<+MM%B41{OS~GU(25 zk`|~HZe@9qY1LS<5&8a#aTG@&0tl`rD9Z9u5kOE`+FId30Kpy?f!?J(Z$tO{^g@AD z>D;Uh34Q&I=XdR(Rvi_^_A_Ov6UCPnMb3cfUZj@EUE${j}@s?70Vt73ocR z2K*lZKDBRz?s|wS0aCey6!+P(TEg?s0f43sZvQUINHgLo!As(h>fe5REjdUqq1mrW z!nE*$tnT|7x1W!keLzy>ZRzsEb(emcffH1a&n>OX1d_~uKx=_h2JOvlIw(D2U-EXU zkBy%4l$%H0%K4ncAPpM?#n}E(;h8 zf4vn&;oSSNG9XyJaSPT5wFh1mTRk$Qh5CQ4a!Zj3i#FGyRB}$A9N&N+@S^mRgJ|qI zy6dB1fQ(p7%ti3UjV}qu{ZorxB;91p)3UKN=*^P&{SD>2^b}U2Kk!^VScK~L;S&=2 z=YJE4*y$Jx57|gnAU3J8NRK0MH7&p-zYSB~@4)BqxulXjy6YK~l4i$_GHEPk;YXz# z?BClDOvmW1C-DW&=-Dw=Z2vCOC`)Xa58*e}0i}n*GExm4DaOlh>!e{YRPy{wfF|r505HbvdokEx*PL1o zWm=9&dvCb7Z=4;Aa+?gLkHU#zfCo*sT^pW)*H0*ta-IKLJ5{mMNmY=DN=-ik;iAl^ z-M5_-q!8Q4#%dDedP)ItuT|^u6Y2f??SElF`0)82@aZJNFRxGIHzDT z3}bDwFc}aa$4rn0r#&t*`^7{F`$&vl%NC_co zH^{FRmQ934ZNsbP(Qe1CqvQa0F-G`VV1L?3dMipTUY%(q;dK-oWNxyQQt%w)Enjt_ zrL^G7Ob!~B5`y6o%c2Si|}_B;3>68VAVS3n!SL;C@GD{y@io~T9r_v`5;tp~x@(^lOi!FC9O{dQ;{!CpLpV86^F*s>JCqC={L3cReNAJNWj z&LG--LQMW;qLpCzy-(~1AX=SYolm~go!V0Ds!t3JNb8ei^9=cBvV9Z15R{U?7TcLq z8^nje6? z2pKy|Y>)Ux8T$r$Q4mjl%`4gTnm*)Tq}L8XueVzJ(JOX;2E9H||1EmGe*7Eg6;kKN z1-;Jvoaj}RqF2lR3cZB>Dr)JYm!ZGT8Qe#&e^P(_8iRU<{(AU(8MJy7g7$C7)-%1| zK&!O=`lz>`{#uOyxc^Q4)f4X{n4!Opn?m8WuM6S93SXm{f$QMj9h=*pDCK@pnw8ZL@D>8_Y`V+?$=v>cOe7@n{llWK?ms|?i2rOp0fML;e9;$c-bmPG9ux1i?c zJcFS9u(D*sJdv+AgKwns7=DSbUi=bY$K#jydR|EkPlB^`WfmwwJAR;`5Y!9S)~S}3 zI{yUvlS_Zj1ADiCy<3RAb!r}x%$BqxDk)-MwzNK2#LEjZHC9a@r{OtGar&=)oc=?K z(^8`%9to+^Q0=r)C9xpRKv^{^6fGYc)H~|rGMow{yeH5@7O@1G2!Sc|L280yjy49= zmXBiaTaX4T9~+7?EJ?4YNC8V-&;GizVs)e2ML~ocmb;;^sA%H>)LYloK@CS(DA-dz zDo8M(w5aCxx)QA5`cNYlWrY~jO>hj5YjAe1+<|h9&dzn710t2gTC~-`dW*nX+R_1% z3zQEteyv;D5(g)eTsRR?Yc_DRqyJcS4Y*En;lnS<#U%WaTomD#$taur*Y?jpBQ*ahF-7CKz3*UnhIzNHIx7?n zjtk+`5t*B-qCs2F{hPDqapc38 zvn}!|jZgjwBoJA72505T9Uu=}o&DgP*Ov!!Wz;1-o6ZEe3c5L+{t#2mC)Q|9XEd;a z8?T=pzYbg@zLw*c_<9+BiLYbvOME>i&DR_T#*RtY@e@A3%HZs2A#gSX&W6BQTI;8f zKO#*0I)`1>>QNLVZ}_&cFLe=&-61OzRL&VWbW+J1cgUmUO3L7}hv zf8+H(JzlR%jo0h4$7@h?-T!CC>-Avo`u{gx|6d!g4J$)hpEX{uk4x+Sx$!z>u_xD$ zqISNR=I|%Pf51D_7l?5Y-VpyGe2y>tiYDzRE=Z&Rr|dQ3JlO0QPv zi8yg&E*zLxpIeJ@9`Vok+qa@P32%&lfxYmNw|M@O*qj%l$fP_VU5h- z`HlEOtG9mLwMG;X3rCmn{M+$?j))X^xcGpXI_qIp=0xuK= zqwE(>EitRjSkS-{UeZs4b+sDZl}7+6GDx-Opbp)24H6Jv;A@KU{4altmIm6@{7>wQoXcGgkR9R~(jq zH;N^ug`)n#1+Dg{@CDV+LLeoe;_#ObPz8XT325{1J3Ix1)(E#Oq=ip_w?Ba=z_MQe zSek0A>rNomE#>5IG&Vx|?FFhDIxW-Z<9gRr}po zniWuIVf{Fo-+Bjub{b6!rT~YMfU()!H3F53>U7ufPelZQ4V!Ta@FlPB%e%%GM{~snNpfmOXIbFWcGPL)}gECaktPA#W!l@hCBjmAt0S zDn_r0K3+&1MI53th?9g7gDB1}6>Gz^XA4Wa>BBtufi<5KqZg5@th(e#UD=qhOIklz zdlQK`^eLAqEta~n;z$C2!Z=|V%lQkBp)y4OM<-XZ=#sAzh=2HsDXm{g>xXIxsYkKM zkvbI;FG8d})VWI25mz`*HobRDoQRe36_c()KrG@J#8DPFlD!P_qg*wP@R78u4Zyj~ z`V~H175S^o-^E^Z!1B?1_;ierLp662>yWj(E>L!5df)2ErI+O8mFfsSZP60cARx(p2*-bM7NPs$C`NC*u4iH zP{=2A8zQpm5EzAUp2MYv7l%R9Fp3waeE_6(d>d)Dfpc?E8_1K}jPEhcT1bICr9iSy zDZ3b9)FB>^*yZQViQK@%4x|-FY&4Yz8=UfsG$fZhgXZ$vs@+HC+jnSXN7I9i1;^dbZK}rw*GQ9?YZTI$- z)MZ5Ar$TC6&A|>Eb)h2_`iT>>i?H{gpl#|XfH$>HbyFM@w8Ynkg5Lk90aqgs-GJqJ z3jfsJ5W9Bz!b6kMpy_bMjQy>KjzV{Fqy4`~wm%R00PR20*M6)?_G`Z;-uv3WVk6OA zd-$1j`>&w(-Od6=a7#FkJ*c}@ zip=K%b{O8J?MVbvTt-;er-{D13J6go(XRb8&SHJ8?*fD_1+L)qN6MekACF6$--Z#> z@q5@>BM`plZ_e>sTl{M=Eav|KiB!AM!%>T3)G|PMmCC;kgN(`-C(DPk%U7JVe2~gN zoGdRrn*>mj4ZtD*3{ZbAm7hf`Q=4-h>-j>U|Jn0d=)VG!iRjS3{5sKoEB`5`eEs@w3r<`)p}f(4WYtEb@E@H*|M%Gt))0gN@K>q) z>xk|V?Jr4{UzA;5K1ul?m47%@esHS%#O(6s6U!Uzr}DE<9_?@5UbpX%LBXTH&7wg3 zZztd{%6A~6HlnY5uTlQ@+2z-qq`XSyU&q$4Wc`{^eo=OLxqo?a7-o0e8X1Hz*D_pe z63xGgAT@o5Fi8@|N8iu#>XY)=W^_pCC6eLw#+_{oy-Y0(0hu2ClH#%t@xr^QA1SJ@ST&_ zFaZ3s0N>AZv5fjy4~|BQ;lZfoLs82WR7;bn1>Z$27l~TT1JyDB{80vc+F=^+>B+31 zGjSf8ap2depioqR^Rs(I4X+|icm4D)Cs1kt`1Y>z40b(8fDR()=saTAeFDUsED!^h zpJ0@)rt<%Z@)M|hxhOyCRLbWX<(*XiMwHK`@)lA4PapJe!T|N3PW-jvPAiap-ytHs zHS#e|R*&Xy`4s@>0U+PCZ!|zYi+9W;vp{A@Po_Rf%TGV}y_xXm68v8w?g;P+Igvbu9tw~n1;}p^$p0pgqK{SzkQbZ`WF|c9jypi`h`?CC!5JLb zT-rt(q0C_5XrTMmGk_f=*xX9{e=)HG88oEouC4D4M23OjpAGmS+)aXg0gtgBoXr-) zqfw1UQ}_Hwshan3br)4bS&VubL_Oacu$~mrzotGM6^9zJasPz+E~5Gt8THXIBe*h& z+T|4WeRyb~c70uagSr@cFtK+h=7riw0xY`l7QE`N$G#5WK==b5dNjdXMesU~0iNj6 z3kAI3zW@(CoZyWoc*_W$=;G%Jc*o!Ung$PqUxAPpP;3{G7F`|^V~re1V1GycYnT~o zXHX5ew@-BXO-R9ggeR%w6yWz}!oP#yuNTMo0zP&6ZwdI5{&o0TCj21;e|8E!b^6cY z*VSFGzcVnAgnz{&jX`9iRD>YI=H((!*8E|^oSZ_bJJT|oS&`j(0MoYrHK$VHNWx~Q}3 z&nMP-iuK)aVtq6;ZiXXW%N6zAkZRwrkcRVr2dIns*eTX`^NICQ`=(QUkKrg{&>ig) zxu|`Yi8`GF)Hy(XIgv3*0VfV(6+!&1X~jAMp6GfoA1$K{j{HgR@a?Bj=LM(}F^(n3 zLp*Fnn(lfE?w4#Ho^pM22C9$R_+6^+j~`QgPU}(d5Oq=;uN8HU%c}E~>$_o~`iO_0 z<7^`>AnLmz)xN(WO?SoMTltsUck@8?QTv*yzBfKfwNK=u_AL^1hO+9+iXZN~Pl$1B zkNboc+%679?{+Z0&>8f8mAO&+wvPU;p)aw_7r{+>wt-A>Ol+|ldJwAXkpZC`^$Zq4*cVbgwc@9s~iB;DO)Y|C%0pu@ji0vxXeiTx=U#3}L$ z<9zvX6$tDHwkbmn?;> zyJY?mT|@gQ!NtnO7-l`9x8OV%ENy&T<9%mQEVQ5$P)qO0vv5-M%dZjp1sQZmWE{xlX{IUJhWBDwnRa-RjA1O&f;>q6zUtqHSrdJ zXNzl{Nc_kg0Y`Uflh72ZU(0z2=cB|rXTg_v(tghEYkoj?7Ifn@A>JE5V!=t0%3sY0 zd<-0yyW?)GJM~Iad*OL^L}j0N#&H6X5wx~%mFWO)I|G2ueQ0WQE|%|F2C?`DHr&JX zX6Bl~U+`x5Vk43$>Q^rVYEPilMmLD0mZ}SEIKK!kd*2YEn)dtu0M;P>nb8@#U-hW0 z0CyBv@WsEj9+&dgI}=u%=t5gB5nV8QV*!;}l`L}_l|eSu0g$$IW|0XcJlb{1jHjnF zCV{8(B3o&q&^x8}`)1QUbipz-PU<3vA5de|3SR=C7yCetd$539SreTN!~2HbkU9Y; z$2i3qPaiiOks6I9jqTceIQ3}9s)XIqcZKk`k6M@EEk&(K8I+}T?C0*6HxF+K30V1(JjdTYTz)0eek0OS6#fz33`K=OCAExd`0%pV)75L> z;;~=cjK<@@JW!VChfDn!|1eF(^fk9ar{H+GeoAEwwP(4_M4>m^wR7Q6OI)oiAA)l} zLDy8HZODY(!fFL0F}{$lZQxz<1}AzGY>AuUmBE>7y6X`_JVk;-nDZf+=RedWho1UA z2DaKE#(tAz^ZKvU!!8xq85_5@M{!C%Tw;h9sm~#L*e|&cwt|QknKuYQMNrSU?5dis zLaw2!k8mFVU9{B}Xs|=DaA&A*9?-*L`vj@+M|MDwNm30fwk-VNEIhOe2Iu%JV0|JUWT4k`!s+^wX@d>MI2c^bAC7z);QUTif$-UW~X9uCqHAk*M}32-=c z5xlu9JRW~baFrKvC)uTNczzVT845UpH|U#6OCIHmfWoUq^{JzDsayzc{Td4rA? zO6%L}WE>+Mt(-p7hXP~&%Ytzm;{6lYm0@ViiICTZJx+OENVN8O>s~Ym0mOq z{J=8RAM8YL++uz>gKfV=dx>px&F{L;ezpfz^Z4wfb50R2N zPDcdU%p?-6i6OYcHm3o*C1;Z|p0tL z&EW;00ps?ODXQFoN7?K;DFAK**P}!-=A|SDf@5E)0+5&te;$kKS9_*yBC5*CfiOkw1 zV~vl$PJOgDT}^k6COX_c47gR?q=U)K5{zpUc3&&iD%f`ARH&dwI@-ddP(A(HCNF{6FD8@!FJKl z)^vz&7?Y;As~FxNFenD9KR_C5%_~Gw5siBDO*dxGkJ4eA&)l0PI58J7baZa0(Y^4l zJ@-draE|7m6A;&&(YWj;F?teMKv70*moaav^gU7$V3hW86GeRi1iJxuQxHo%lpG$Z$GtmO zo+iQyK|y7!g^EH~zX$jeLCHdVcH`zuqMjSdQY9RyIod)jse~{zx+7IW^>W>1+eSi? zx}N$YkdtP|4-^VQfR26;AR`{K2;v;Zc%yJ#cj6E5 zBds|+PYl9#-?B8F$#9?}DA6c+16emT2Y1ul^F<&eux0RGkWo@LN{;lvOz@9S;L=|- z1N$3k_|PnMO6i=);ZW4TwoWZbwRn9+s>Lg@2qQ3|!7QI8vua1hXa#8@#L&u{34=AS z5T5Xv3V%R`eSd%=rt&8~2%xYY&eV#~V!#7?>lWY%@ykrjKMkKTTjDM8UYi`f+gxXD zjb3lZQglpreN6NK0=ckk+sZLwUjumWWA+Hq&|L=vwMZ9<4C^R^XUzwa$<(kir}!OZ zdzbYcTssE^YsLYa(IIm2JJ@&^wLgK3b%^nV^&_JviD0a>buHR}+H;LiLIelmeEq%Y zaKag|OJ00zBszz*eh;Dw>-^r9C0B@;!qp{6iyCwS%=N&`q7Bx zXbX#XI6FT^2IxW|1J^Nrn1aQi2%RXvUYz)|cQ1adm>{%7!c4gp5sA^N0-XCNoJawj zdl-N#WLz71VvJ3o=O5z>MUhvzjdxt^YvKVn5}Yi4$jwUdToQ1yk~rH)(yQx$J{m72 zeN{2ZkK4lR(R+wV6mHtH8?X1!tMZEbrWWBJ1(F9yW@iXg5ZJr9m23niUfVb2+DxD$ zA|VmBG#P2+r%wH&!}UZA>BckAcK~kH25K;((HoFN=0ED!>crw~H zKKYbFm)dqA(lAhZm^#9Y*V$0LTDgHSa1-)IF`+*2QFq-9<}v;vStX>Hsxi2um*}or zC>_k1NX|1HfCU{?L&I-%2xBtZhjX0~-fvveQdm^dA;9Xci2~dlaYLI=_)vW_ukWkP zDn7qJwUy{%4ncbq=sMC*UN!2&y5sx2$*`r1!zf zpiU_CK*k(fo|V295Us{#UAT_99oPQhXkaY_5vbyIjw*g-kl$QdRs4_cfUQnyIs_bL zeh(usAmxg}Qg4Z*V9+!nY~8AJ{};9p9Ax)_x!Bn8g@ay{C-9=I_yR{Rh$}krIK&)2 z1D|nK8E6)?z5*Lf-`x~jx^h)`%}P`4;yVvT!1F1eGy^cU&qVVzJZTlrh@LSN0sF)r z#FOtqGTq843uh!wcP3+R4nE`DE+5Xh=d->**!~W>T{&odouaZaYT-0fJh*jN%PWw9 zn~_^@?YtCSA9F+u?gOUxuXnr>-Hhfo2#s^$og)*ji2WIT)J-_&=ze^ z-Q4z#rzNMfPKG{Sb9g^SyQ-2{6-n%TM6MH|wD2!L9$90ugN2m3NNf>uUh^x7|5P&DcqAAy$eZVivVm2ukz@E?Ga>W}Hi%bbe_ z;jiPKoQ;@LLHA{hzwYbkjBGNF;X3Ie$Jm;~PBN#t{nL7=1K~O`0o6dsUxIX}C9Evm zn{ynubwmoZCJY*Frqcmb8(RcnY}Y&Uz;|qf4cp;53BSYmBf>JF4z0}un55a~kCwZ& z7k^Ei0W18NT?(1U0aAsyOzCfyNS=S~e2fT9-4S~$Li?dvpw2>wk_BZj2N9~HX#wD2 z#Ay)nS4A2^cswA3+5)mo@kyIYZK;JTp*vhD(-p(#V*(#>kX`Wg8tp z21eSNuL!Fpv_A>0f1Y0M!TP{XZ3NnrjBCcxno-KG#Q=$^Ptdb(y_uv{F-(KHrrpxR zaa;g!#U3mLwcv6eT%~2SH!9Zv660&Bewjk9JNyW@k^JpU*+6NgNX`Zm)M^60$Ob{| zJsQqR(L>f)m0FHnBju${vDNkf?7PeKc7%$l<)yfgpyyb_R_q$v-|%_as^M~ToDS+} zc<)d{{Fa8!D=d3(UlCjD4C>QZ;^jbbIScCLOxRxmwY)mje}Ee>0(v0|01_Aiy?-9J zD&Tf`3b!DnMj(g7|Gyczmrg_uM-8l6kQ5edqVqLVFcD6p5AoB`Do3!a+!+}zH{4r* z(=B8jJ9K0vS5KUSN5-u_Y4cl5_hBZEg9*G37;%gCny7TGJY$Ba(SNK5N4-qC#{sacaY(m0!E!hiTi5h#y()(Z#Y9?*Y)s|iW?bv&3Sb|ST zS~pmmKbnTz$S2a~!P*@0ZD|Ax(k(FcbDB>BBEm%C=4Qv*!6?#fU3*&d?q=Mz)Pjv` zpBPV=kN-l+wPz{05o&i(@I61|s8 z>q4GG%6n46!goe(+pO(K88RW>X;Ul5DRiYdnL6++3jZ(Elhl|1>)sLvBll^$Eq0VH%jjW=qg z_to%3rFS&&>n#qSt@K_T9+nBo8<6FDf zr!FtW6`gpRmAFn?KeN2GViu&C8yykn)t1T5h|^aJ4%u<`aH3dUUX-|yP9f$-XBC4SPVZ1<*vaI~-$jELp-SG~Vw8`V(6ciJsPE6TA z>1E~9BNvJ9-!Z<6+0;wtrvcsqfD>b#SX045<789h18Kcnu3*!7BYd~$#38BiW$`de zYJ>q}+Oz^npObO@*ZFSC4W@*t^QZWeT?oh{2C6qvj<1&)Unix% z4o-b7tW&fa&J1%B!KuOU_Gohp5Q zlX#dJzS-LvUI?8KK1b=jMQWsOqx9BFP4s~4s>~o>=R z-wNk!C?j<5~prd4ikgFO{1JY>7Yb_UKF13n@b zUp%RJadmM|_tqhi(?ik9BH_Xn>PBvULo0{#6bi%1qPG`?qAv(7gqFDBX%&7<-0*-M z>e^_K5jS5Ed9Bo>k?~H8+_)<;4EX?1ZhjpZwa?&}B)fRKW(A{^l_t}QQMh?9t|2cj z22SODgYtGDFK{N?y_9VA=jpogZ@jY`vW!tL6{ElunY28X5o9-An?Mr?1Pb7u5KJeE zaY)rcL&ud^zABd{ z&WK>oy7)R3Ty2e@ua;8BMR^uoR%5>jFYwQ>+TGfH2pX1!kqy3|$CND&QcBoa&2eP| zAWPC27Joj|N1Q z+%}vG*>Hs?-0Ls3L}1`;Yc?Y@uGv~EilPeEP&D|}{1iQrCpr#)i~)1AJ@H zyN~1?bL;KeI0S+x@{H$31WconxR!(NaJI6%8b{YsS7<2ngoiSnI0Kbr_UIMWVqB+V z2$IvylrBv2={Pgr0D8#y58>%TH^ZFg3~dG$MUwRX)FtS>7JT6|CT}9OLhKwDz7p)b zoJf5p{TWJsionkBg(U|Q=f5b-nX^RTWnu(zMWPIO#1(r2?0%c!4z=)D@%JqJwE%JN z+mR+#JGF@Jm38r{Mfe#it)E&{hX;G}jH0zeTc`TWB#!-;d9vGqgVv<(i(49v(Gnb>%hiY>OZShUx+ zQZfTr9|R|n49970)vB$n_IYi!t+rMJzA_1U5MF_(1h5jo#~H>4Xiazs^Z%}WW|BbZ zy}#f6{ryPhoPG9l?X}lld%bq-`(W{5q4l3)EzQcG$R?mKLb+S`=jRC$AY8T<*dl0d zUJLdK-4BVh3y*h4H92INhgkX|{!HI9#aGS!Kj#a%A%q%49&(erHm91EURzKZwsE69 z|0|j2*1J0WnPq0t|cy%r@%&h9Uqsg)e+44O%WX=nyuS7&7Cj{MX0y+AL>PTiy z%#GO`=R@2|`|PRNpZj9T4B$20l5mL*w~9hxl0g@+l#ALP=P)7l2l>H z^I6yt)zT@OKlh7rnsx?Y4Qzfff;=gxw4A3c`vu0Wkx;!?rl)i5@-?ahvb3zFKo80H;*GxkJ4uY3*HSu+T(w zD7P470M?VRhi!=7dJ?(eG10xma9(wkg4N4Y5DlIMvzPBdFefsH*zi!y=ain zzPR^9^zek`2pYD@#y!~_%AyJx=Ld|>L}KiIMRo0%$B0etM74cX{}Kgdj2Op@v)t* z6?+q(3XbA?$pweC?jQ;Ei(%lgkgN9fw&IGB)@oNmo)-H&yR>`T*+;1SimH6=#U@`# zWAb@P@OgG?(TC;9vs1hG_v+zs)l$_^@|7f#ag{~|F&@?)r4_PT9~+a1<)w};?cUqu z>k>LDU#%t@lGm!TZ)^8f$k&6Jud3pfq{I_iEJaIss9!?Qd8NNCRT9u7W#F8ewoxkl4_w}7wDHsJt*ks1O2){Ka~dh?LGzl0QW}FZ$p}J zf~QBn4GR637{N!-FX@gZHuyXn!lgdX)~b^Hj{;~*^CNao`!YzKJvBI>{iWA$WT z)+G;!txk0C38*w5LIyN-F)E27BIAW!rreR9LBas*+*|WeWPB)gzP}ufK&zR}z92i$ zW- zP*1t))D8a!8G-c5)Wxb^o3Honz7p&i8I2sbxUxz9wiyZSSGuPpIxeix9 z={j6>?ttG$$3*(ILy&wHj|o+4);a z6!9}S>jg1XgPb^Y&&H))@@EVmJZ3jCzn28~vC(D?q}^yrozI6Wg3$vK2~Bp+p}gnG zJHJkecUIwPT)N+~II_Y5W%WFWpaKNh=ZuIReT-Qnbqhy9-IG<_*1&`@*ymq^#Rj3> zm3B=ZyMc2Gy$pF0%L~l8*-oXJxp4Y~>L2z|fA-f=#%F8{a4;4SC3mqVlx!D&Idq6a z(M4>y1K~2qOt<-MW}Iy017c-x#W*k&_4Gw@*x}Fi@JRD55I5V;YG{w&==8~q3aby- zh0+G@O2!m^U5bj*cX;X_j3V>+YN#Z^{0EKQ!ZFHn90S4fJ`o>a&lFw=0(>QmN{m9>2zJ{({;u9*TX>t|yWluv%+3 z#IE7I`mo$qFU{-HyeF|td`718j7?8)(KdfcLkM_H1}?!xUHoP(zDm`u& zD<=$J_k>EiLM3lwocZHSe+gbc&7L0_?n{dd4Sgo2L7jIeQzL?lSlMlQ$wtF}pM9GD zNA@b4FWtadLb9)3@XVY?Ab?F%0 z^cxQ;kok=5eC`PL?!qM1FUXJ(ThL&B6Zh9F8^*mBLECoSwvoci_8Zo?S;1DMMx^io zl+4(A++QpfGv7`=(nfhjs+FR-qvO``oR&fEEGTcJ{g41(^!SJ7OZM5 zdjSv{ITSKyY|p+dc4scj?(85Xu{*o#>a5*aH-rqoMB@{jKMAPqFdweYT97UA)jvw* z=5iW`W?^^itM4GYxmbDw9bF>j_Y{KcH-%$`_b{x&BqzY=+(?#8nDKUi$E}zmwtmbmLK6YIxoqz8o=dy69QD z;+NntExI9^v5cFpSHx?`eZwMSvu;zxDP2!@>&CdvIC^22S2pfDHxPMr?@YaOBlSg| zRbr`3T|nP$RcH!kSp1y8+ARkCOhMUp_~@C?8O6=1?-_gMG8A`ob?{n-i|L|ek-Baa zR@c6`o@@Svqf5GI+Rp?;Z7P`>bg4u%rRc^P}_m?mp5WCyVV+gB`iE(xnI=gu$JzohpICEjI7%(v-a`8=j;p{QhcOTBtY6w6A zm;&9|quM6kxswR%{<^>!QbP4|vVrTvJTq~^>D6A?V!i<^fZG|~x`<2J&ez>Eyd`i( zPHL2SAGNFdky>*uq^i1`TrGj&v@j0?yb4!YgZR^u1$|V&jsB3wy1)cu7Kgo`h=KyF zpxXhrxVM6ZtRJR8))j*@%_B;0q}BKsk@mt(ZsJvFHJ7QEigOeDo%uUuP~m*tsOZj| z?&K`D#AsqwAd0PGWvHOyVi#gKKDu5_e?A23X^s@=8uR16*Q`@>!VQH7ZJIW52~fQ7 z)8EU=+UAdYot~lL5`^ov4$NzoeiHY67(G0E`Jj5SqG(!`5W#?=anU2geA-nFO+Le) zuv_xcY%FA)$^M1_h2<6z-;}3uZz5<%w4pdwZvIR@#K%2Ink+}So%wEKtGS$NV_0R$ zzHgCCW!qxjHlUtGef6l0%NWhM1HRA9erLC0V8Szh@j7z3@mppE7==Bo)^yRrhZVgU zWxhn4$`$uYQZRn|6d2J5npZaNeKvmRT)UTxH?3j}bj{zDDl)&KrYby1G)cS0Ds&k` z6A#ja3N4*3@=~h|@%2=pSxHltWvZx!tp@%b-9m8O6Ewi&Pcn9WBV;QY<}bfAa-NJy zj#5*tbLv8&QMW3=zR;)@R4qzQCQ{aWsrkkZYrU6;raddz7by}A{UGgyK?HGBs-)y^ znO5xuT%fKmE;s+d=B1Kp@LI)C`Hi5{@7Z|IB|cB`t_zJ|LHs%=5(KJ&Ub12ZeMKLS z34Di)SC}xSUDFq#Rq&Wguke>I%MD*8en z&Cf7%Ec1bJu(i|oIWOY*2JaU6Pzj`?d&k$iDW`K3?%i22 zc6VrES8!VjH6rSeT@*xPIyY{g&-II8O)5ccn5p1Uu%tuZc9g7IEd-O*)gFwGtPGYA z_Bavk96K!;ho-#$nl_~LN{?}TY4=+!OL|O>M z{Vk^(*j5tz2G%G;=o=WiHa0EIic0YRGO$Qh|Dd?@Q;kbwTxv`s7i+gC7HbjicHGgB z85c2+IwSA@yKzbUs_e{!&&YIs06_JUZ2%N)nXDj;$3<793>rjXkq zm3pkA3)B@FDe)TN%7N3V+x9(-?lUE)a88X|-X!SMv z5JpT298 zPwv{?w3|B5D145x(zR8pl-0EjaBy_(D^}McL!}ds0jyNMJPCAld_)wige&boM`ZUT z$5=F7qVwm1xic*b?OMn9t8kcing!=j{51QR<9$3kPc4&T&y+Ifom>V#>a}TvO0w7z z=4Il>hw+jhgy4F%cQ0c16;`5&5rLuiX|d%D!TB?U6i!=6GcuD3h2?xzTpw z7AT%U*>Q718(>Fmx#mPaSi-rE6#y0EW}u_~x(PZb%?=U}NY&!xtG6jPGt;N(Z<(nM zbPKcdQP1n11Iy1e_h44%gEg9fkT#0#SyJpLbYqY;s=gsbmK!z2ZPY2w>gZKD{4^^T z4X1RzJgZvUB91wwP#bnSKV0;GQI*jJjye5x=O@3(+q!S5j9bn7@1PYq-v>!ubANFI z={-Bo+Fre{ySi~noy%Xh(3YISH(f?1{{gN+;Xy5fr|9Wc|C*OoiB}}t1GagV-m9l8 zD4Yua0rO0;gDb}Z$L{C>w}uV{xa}jDnM{qVqwc{3evofXTX14RYVR}``)rM< zUZyRxEw(k*4Nh;QYD5I~#lC36=XY$8>rGc6C^@-I^ssZ;B|1WbHMtjE_0*mSpc}5I zH>3^*F`^u?CU^R@$l&V6E9!=)hMZ`q%T3u%_|mjJ3SP>$2HtI}xoR0uvmLWw5-2|} zi1yIevqxE6E|IY6!;p?#wra0J+mg*IhPKSfEs-!4seGQM$P-&QkP^SjRYy#~b61&O zzqR+e{lEM9dW3#SJ#mz31mS0j1cdu+sTQz)yK(gA&=3&;9gZMJJ#zD17wh%;JASid z#?T$Vk%HLeC61zB`PZ_yH9kI|;Ly8D^!i&CTmM-t=AFJ&52bv0?RA>J?v`Ai@s@a6 z-DI}wia|L5nqlKzh3Sw6?(VUHupvb;f z5ua^}k%w_K7@OS|pO6v97nOnXx~ED?k2i3V|<`(n=Jd5)6fewDDJUc)CJ}R*5CkgfQ?K0Qd6{Hi2f+N-13Xf4y-wq zfCh397F#bQIw!Z#$3CMMfzC*8EFSvDo6_m(msS56!1D@V;Y-W5N3WcsJ=6#vZrg#J z>j_w#FgMz^rLjtyRgLjE5l|Mj@uJ(>&2QZf$93ftVn0O&%TkZukPC8;T{A1UPRt}N z26(`FtQ#u8cbtJ_qTB)b$?{u}0t69w$n)#3zB%L~+C zYSUs1=*Csf>hjX?4SwS)TuaT|I|loDyIN-FPQfMZ=DWt$kFQN#>+3ZWM;&4TJ>J%l zb6p+?>$jnGIy{sNf~qP5g!Q+&C&8ZhNWMq(xh%OAfs*C(Qt95eDg z2pgfzas*?UP?IBJ}=FY_sF0Y8}t?DsV!+=^d5W8%3_Wn z)yeTy}xacaoZtKDr?Jlgd2}pfP5izpdY{n=dgX9>~ zPf+XfrFUrUW~u%~oWyGH^0eM2x3Xq6l6dj$9t)3_ra)E-Yn4}X4Fz++W)_jIn1D#&_v_14Wkk);(UwMbKnHpt~b zY`eMUZn<yskx8_}oudu#vaww&+VdLtOCOJcYQtbWBdfCog^L&`eAxScfEQgdca9}2voNF&|?r5-Mu^sYsRGs7F)K!nNl8hBIMMnAkSEzZ_dMSHTQ_c1; z!v6%BrUcXNzLwmao|{(c@uJUv%KXM1NBGfW^Y*|w@3S7?hwXoje>n6yI#p5ti{Jp( zla3DS6;M0gupU`zj$PK{cpmpykC#v*c4YI;k6)V}yCD<{e5@z-<@IjEtc{mm5$HGa zFp7U)MD@}9S|${VuX;L?fgVPsJ<@<&vZleu0`l8X&2I?V8iU66Yb3W>3F|McO+K8+ zzsfOFN?)mX`qSGVF03$;mRJKAtMkIB!p@GjgFhgBbBta&FLIx8Drg zIg`bU@JCf2s3LBloGeFNMEtU!rDyuznA&f*)EDRZpWE2T3 zmKa)D1H^=Em6^H-)CY|;kHgAKjH&BoVN{lJ!hVBQSP6kk_-#$uB`C|!w#9UjIlKHG zQJt{5r^>2@fGGww$YP?0TTDX^PfPw6qxe0{b?S@%i-Lu4;v%qIm@z&9LRH=@!*Y|d z0JY@c95zwQoP|qD#tP>(6IoCj_M~`0BfvV&u#BVD6>Ir!=Uaic*%8x-QFnUsMo=Lzl{kzo+WlDB6R>-a*0GMevWDkPh=> zha(6%C!-9;D&a`p@mjL?)+%a(eG$81kp({u z8=>4X*ohyY2GLgmm^QNoj!*F+s2(ij5jy2kZP!bf9&Q?1%w=Vw5xiQ-?0KtlF;{m@ z6;%g!B--^O9SF&PD*5-BLZ zB^BgLNsLx~KnX#Jl@~Mivh|SrgMNg*i_ltiAeLz}&urvSJ12LBXc3mvoj?b&DEe|o z@?J`Eri;(($f_(RkVgre=!57j8vOCAbG>zUCt3oH$Q5{M@Eh$dfdmtSkw>YLQ3XU1 z@_|&0`j))? z064+W;IcNF|7ks=nJS!!;E6M$TBqrv%_z=9^r!7Ye_C)bA#*9*gLD?Cwe?^RE}lWHvLI zPJPi$YJ{V7x3q7iqFrzE6?ci8<7d%8{OwjH>Qgg-6M=*x9rDv<_Uyf57vX_@}H(-auC1TrF*vN zV;l6^M0n|dSI}}s4)6oquH|3kbRzt>zm{$>DJ?-|CBhG zM?tXGL7UK@ad$_yn7QLU0U>5nXee59{_zhAMO$1%?&?v6nkj_4WHG)BG8m=NQ&`Hd zh;yg(oLbEj1^tL1b^l$}vNKDqM&MQp|F6<#)`G!WFjx!mZ@IFb9XB-zp!=Yl zdT2oX|7BiBJ*g*8k-aYARDwt!J&i6Nvc=NrIiHsz&A;F zmIU5Pg-3acXT|>T{G^rcHp^hdSmw8?gB6tzl&Qd+xGa*jUxW_*a%z^ai9;6{p{53X zUmNkg?v#YB5{DPZWAH`pLT#`%Wwkk3v<`9aTohgpU_J1o$znYq8-Llj+dPnq&W(Hx z^0hC(hvE1NA2R#eBbV`o+J~+^liJOCUV9wL3v+Yw!WUQp(DH6l6Fqn>BHMn0fg)^= zF&M}*@A(Jb0P0|V7>X{8(|^OKyZy$YP<+O|Q4$_?FC05DyyhDB_dYo>k5yT;9qV%rEd}X$`KfQEjBo0hZYp0UpvVMC;cp`Rwips={V_(DQ*-dovW1VI4z1WUa2N ziIJu9R!SqXd_sofEk3XFG7O*5#>ACuThlJ_H#^&dWgT-@Kcs+@;`ZgDzmYLj&%+;i z07h%25Fjc6L|cPpN9V47S!K2`gbkzb1P`ucmkS~&(QPUI#Mp^;KK={zA5bPaJKn)F z?BfskF)tTs3d@6DqUQn`-=WWpb4SW4qwQHHa2%jg&(3?+9!e}~1XGmkT>d56m z6io4=^y4%;l4i|s^|x1~+8arG2oOcmqMEcGijGIJ1M6pd)mr;^=YdMg7RWe259(uQ0+ei?&-$;if%wSg`89ieAu0Y6%z@>LXdHLgrQ1zrVt$RX8QSJ;LN*~3MCg6l3}vcXSHDEFM1{e+l7KCxBiQw z|J3;;Oj*3}AW}mmEh~DDCv`~!W8KcP=}_ZS_+riH^VE+})`}|NtY5|Rom8Mv{f;xkx1MwoKwD_Qsx2P7O|81Z(M~o|JRTw^? zl-@z8kVs)%U;S+E>cT>*P8HU}(B!OkS!(8%h>s)HxL znkT;s_uQ8`PNaZ(L2)|x2-HfSR(Vi(TbEERs^h@5!c?0=C7sSDHMoO_Pa_*qg}SLN zDc(X^*!THb3Xap6!%{gL7u~yqqsz~r)1o{3E?%GAnT~xUio5*+-7u_|@udi6IQjPhX^(7*+IWx9jt%NfF97}mX_Zr`U~e%6J!H` zT~-E2x9sAPLF#_aO&N>HtXoOn-i1O*)=*Gp0*&Ap@ke*S8KkD+OG_9CbIRxR2X0`3 zke+AQ%;Y8>q5#Dm4}xpDr^~V&_=#jA;L*u^mA)u}WqdW6-zy_?yr2zf#NW`g2!GS} zt-b%-6Pa()zth-zJOjXB&$gN)WcV0*yeJUt-##;YTL0dO)Dixa8NauV5=NyxR&?v- z^u*vpf2uQ9^yO1i5m1P81o54(Q=c$=6GV|}kTDm8M-e0>hZrG_Vm=#QXUs8?htznu zhM2>}W6W^|f6XIZeFCyyz9F5py(YAi+TzRa$yOLI?3qZfq79=t9qpiEZFsKc(p}o{ zpo>@}Zf&^F&3h^DrM!E2_wruJdnNA+d0&Wpk)$QMt%cNs%9Z4WH96>M$Kjh*pDT1> z?|lB;+TWo{7fGPb)8qMJkvq)IlmdVQ`WtinT`~9{W7P#tbLW>X@4O zYRoS1qRk6mR~jGi95 zPY{tPR*OGen0FC)WV;!aKQYlJn|UT8}ddNx)KGZHQSf+cR$E}ph! zABnx23PrQan4`RmmMD1wf(YTXln_FX*NW$Y$bR9@%-wEgOr#JZ;afr}B`<$O093Yt z9Adb;L^v3An&iQ4>ckK^sfZOaNHGYFEd9Yu zVoXmSu|2AXxO{8;&i7M=J$ZRySM?A#uS4FiTP09R4Q^4tIchdAS`-hBw$w~P!!L~? z*z6Mo5x|0Y%yK975PLRNfL3?R@?lhisO^+WRQMg79XQT&Hx7M3g!ja+Ga@{u&ayAQ z(~YoRjKmZz^VF z7q+C+TrWL8ES~R^%*Q*kWQ60cY*0^=Ao32;9&9FViEXJlN!FR+SjVZGUg=uE(R((n#T-wOlAO+7Ci@~hOZAL*+0b($ zBmSDZ_BhGrC2YJcjt&wf6iifA&Kz+(zsQx?4zP_D+!gCWdR{a&rAFdS3W z8?u}%?X?;@i-s%~qzf%#mIcY46r}&7g(kYW1|@4y=B4ftqi9j+j}jH_GH0R#!?F*F zpNJ1Ont$OvIRnfL#V2iLwv3O0#(LjtGEvjYwHmY(IX>IRY^J5r3q%<+Dl zc|@q?cvBwWU>wczFqntudC+4~)y3GI&Xg@yg-z<61=@=(Y9C?uNTNr{nRfX-$iKB( zF(_rOlb@YB+?Og@V9gZ}SVG)feiQTm3PMVteYQ8qJ%<&z$|3P9pBnah%a`VcuYkhm z36b}E8kQFa;+46+RYzr0s~Y87Gbmtd^*Q}#jSkp$Wb!QQ7P9ZfRK5Y1IA?{eH(2s< zva4rd&LWdc4H3_1>CvU7(5rV7l* z`l{M2`uJCa#|PZuE+g)mL18 zmzJ`%Pt1h1w{_I3f^|Yx3LrDAVsk4G$h#29NFUZZ!7~x!-Yfigb?flkZ%(~|; zd$|DI#AJ(`=(4zpz=+Ihu5FM#OJpz@2npA)P#Ao)>0BQPt6+R$UNI5GBWMuu9x%S2 zK0Y$oUx!E~g)IfS&DDH{skjx^U6ghi`$w!Zji!ni@eC&>UULhmdb@%zLo@mBBxB4C z(Y=M-a~k91+ZDMeSo>DweBF51OD~a!{Kb&{b4wt0yWPxZVaQ&02xH--n@}gxe7Si) z+n`8Pe64frV7GFYuK5dj5Ibl!tFsSZmk03)`XUc{z15NQN}pxbIwno3FCGw6x{?$B*>50SdMx)mk-9O%!NIHBap9YOx#umMEzprE$ zp3N@etoYlmA{@Azc%Y&fZ$dO0!B*!H~aW>CoalM=lJo)9ekB>eQgc#Lm}>Q zZ<>@rDj|>eiLV=5Iu8VF&HjnvL5)+gFMs>&xZN4M{*@XZVT~PJ1D1N$0;)ugGB%5A ztVS>!TRS7ICDVq;Av)>9TFkGZDvm{}Q$xv0NGN~oyVb3=czcN&41p6%eI0Tcf}f*Jul#f9!`Orvvdk&H(Zg`uXnw8T-2cGWh~4b=9#v zcv!85J?(!&+96~)4bn=;gDlc2gcPJ5fRDx&&k3LQlZ0TMr@d;3k-*-^LZSu&`k#bD zL_j=n4womDbqH2$j)81GqR%SKY4Y`;)K)7cFt!JTBNU9Sr{q)Pgy2cyV+U9BCHCi` z_A|?a%>H}h{qdE#-ZfhSMyrya1*y2RJ61DJ78_tY8FSc`xXqFwzO;!yG$bGjd78A< zgVp=PQp&u?58PZNfKY06W^iY~czvFuGTi9VD(w;ZD@(62P_sdnUb6s!$6JZ9d2<#| z-ekpnA}j7n^p*bugc1kFGyOTIgHN+y0xO56PPce`NUAL8l^i3CL~r6F2iNvy05(_$ zVDAI4djQzhEWrAJC6G&Q23r6wr|g|`fW*R9IXgftk-4vzXo+eW)^COd57fS+)xF9( z_4U4EG$Mvx!A*fg^<|&Z{YE!GUIBI|0Ifeyu*dko@9Fkyb4&rLU&1(OFWi6cEY6JD z3(wy>n_mLp9_H9*bvJIunNJ}CSDnhN=yV7{^l+Nd6Yp`YTg_T8h4lE3OK*`Ml~*(x zwvCt+-)q*-5)$$YDeIF9xL5z0UKol@!<%SqI$%j%KVyR(96#Z?jl+A(WYqqvnT$+<-qL~;Y?`0NYPPM<_1<*0es8Lzvkqqb; zXT=^;DZo#P>4}uv=V?O!3tv*6dXPimHPWC~a}QmYMvG`P+aSAjZmd?y5kErO=`?EM z(iQ5DJ*1xc>OJ5#cEJJv)vB$O+Ef#Svj})z*J|Hm(pb8J5*hUUxA-6pn17wwj}L?V zB*dHg@ZnPIhBEjdd#%@xa?UTY|Fs&CYy?W)Wm*5~@Cg*jj@7>39dk(uY;Uyq@}*rYx#!vWw~q|87xbm-0`g5#c3{!z9RRNmi?7`(7iwX2zWSHqSm|Q}52+ zy>QunMaBM#E3QSw$_G%fM?lxpP%-`go{HT&iwTVv&ZU|EBP#aE3$F?T;x= zDN;@NpVTihtw5`+uq!lp6V?0VQuozAlMdZfgENvsNuxJ*ceP;T6&VUuQG-u$KY5zS zaI)lSxes(a0S;z%nBTl2=ok_9x@H0-MbV~DWjTr6)&Y4Cl5EkY|8Ydg3#h{9Ie}2A zCSbfbkR;8kvFH&y==(k`K$ZdYs3${@=KEuR@1sW|H$Isj!QUTd=>7C)DfCDcNOqI1 z=#h}r^}I+tpx)hz9xV=dwq)p0u#XVpEH^1;s8Cp_5X)7l5YjJ2g@gu)t@uD1 z6#k}K64g=%HeYw1hW3OWt{Fgh|-eXO@fUfLJnAN)|5n zmcvU@)~8C$B&4_xFH&vgP!U+(mcHC<^~EBBhX3IjQ2y(((VP3ZjCdW8Uj|JCLP7`5RFrKyY4(yc9nrt0yp zEt+<|)=QJHu^f=Q;#VMGR=w`|V zH)c<7O*!qQ(y2NO$3@f;Dh|a~*lW`(hOR&+ z!P06>hT(e^+p`>;qqu{xn#%&Un(e0!PGJ4*ww(5#c>uS?$;JBSy*;v1=KX&G?*&*1 z4}|w!&j~{BfDQAPbo!J*iDH_4z1@iewl(byd-LM<;du@I3ndf|wv24<+m;T3WvD9{ z?YC|5vtkM0)2f#=1wAc6?MraAgoWIr)t(D1{Bb#37nUtPpeV&;7@kyUw&3qOg2KMz@k!DM9&RdB#s3cAs zTvA(H39gV6UK#@u+>ppLDe<6qLwxP4H#LC|A(3M%<2TF%-(>1Hotl_9UE(vROMK*X ziT6sPrPC3cvr=ROZp)g-d<2Vu2VP>Gi2kbBGcGy|S^oF*MK~ckR`RSHb}{aWq*v%*QrU7v@*3Sc{tf94n^6;h_hkb4R)mNpgkS?2%lV!c72cHiq2H)6!WS}2#i?S> z4sLR7Gs!ec%H{JNjvd~;)yL%`oI99^ji#OIu-kE_YOP7CdE1&KVR8J_WGTx4+!6-s z6~z8}{~gE7P{NdMoUfh+@x%p;L8mzj$>zaTi$+RpYrquaijx>OIk+r5 z>ML$8d|tI=>Au9KM>MRK?U2}baDSYq&_pteoxtxX#cdF7Qr@;w9<)*>lk&QivdT)~ zUb(_{E9G`8rJR%oE9E9D#Y@TyR?1u}MJMGMD`lFMaw{q8td#SulqIA*Yo!!fDJw|% zy_I59DMmGLA@MOQ@gt$Mh9P8##QUwpomQf#@8XOQ22K%bfmdc_(YUy6M5Oev3(e*CL+ke8qYz1vldJj+t}i)iAug znm_uxdX_*xX4HBXCc<1U&v9cR&s09fs^C%UP1clDE^lv|$3b@9N+ATieQdowz?(GH zEw6_0B(G+%RsB=)JlcAGR-Oy2XR)3%bJVjUTF4s(zF%wlSKk#38E#sr$0AUPyO%(9 zdyo`ZzAJ9OaUcM%U~H=}y5WR!%r$XV_TL44EJu}qQ#q;#>I96f6~_A0`>DJ%7fx%@ zK?vU9vUKtgxrxKd?atUJfG9^Y4l0oWul)`xb6m@>&^?Dwc2GIhqvB_m&}Yk|Lg-xh zj(%^7Oi8nh#htP0?ekIT_om>^kya!r5VP?Z)-x6fK|7fN3A$J@e8gAf6Vy@=b|ggc zYDPg!dF%y{(x;0K^2Ioeahft^!$o3%>%@w`;bw3*w_xL@#db{@ z=J?bCAfz5tbE#+Cn?s?R|EU|tP|3Cr!c^-0nL3_~i4#!G_XlyaM^BHxyqp_`^yppX zlhXw0_p@hmN{E~f#Lq103g>&eB4gM76NF9`to=-W9BX^{Dcg=d9Qa5bdNf2~TT0Y-+=eHpsHPw0N4$M0eUob&vy$*Hr=Co)yN$Zw`63;xVxu>aGraxayAM#X6S z+gUj|lg7gXSzjdGe3~@$h}pdB#@n1Z$u%TqV>V+CvvQo|X)N2&(=~31TKUb0q<0a1?Of=$!Qm=XcIhbft`v~^=YO<4l zBR}SXv*o$yZY$|~k`yFKd%-bOy3+&i(pu*@!6hH5L1t7cu|~4#4cNAx$PgJH`B_x` z9G@U#2o}b2s?G8*%XuZ-HNv7E;Q1;AQ?M4mf)nb0fpkML$K3jM2N%nJ#*e zM@US8mO(+hNYc|q&r?1_(lA@W zF(W1QFb;%I5Sn|B|9+sQCs0a8`vWRPJ0?9^aJ=Oef+6( zQuwB_aVZuS{z-;r{(-M28~W0JVok_$P*FcB;&WYum2iq_O)!4lXwhT@<8z(nk7S>- z78Q7UowCT8r_dAoKZF7Pb8j8(eF10H=ZmX>4<652jhwEdN9$`IkQl9T3|H^ZGwRzFyShH#)tS_GCMinkg4;m5Jrdh-h+1 z*ey43ogue#+2wXFB3dSp@nAg@ANQ<0xOjL`9tQL9Qy%o_Z-%zi6foq%8H(4AUrs~!e%MGqnisAf`y&fXm zJ#(#>dP>?dtG*FVJ~hbdq4a;K)$P!B6=bK5tlS{Q9`Oz7-8p6#4Nt@j4cgLUrvC>m^F?tGkI`3H{N7H<9&$TrWa}|FHNR&(bg0S=r%W(|XPx1Me z1u6DK6U+-)cm(4bgE`NPcj#&ruE7nE%4OeXZtMwVPoLTBgc$Lk+S_*QVB_8Zsy&n- zXo$*S`7pvPo9|)X6tkJV@-v&6;yZ^}>pOA-;yJ-l58>&u9F-TdGxGqMMd(p#vQp&` zUpmbeDdhLEX|wIh>)xSs(5KW@E_G4UbVzy#BbnuDI9Vr4%(fsj>PwWb9CvMIMCFLQ zZ9a2`?3-47&^=`e1Hi6_30g}Y`ER8J-h$a&3t;%qI~(U+BKJ3d%S%UPQxC4>bs47g z?a2*n?tRHKNv*@bP^ zXgj+R$mzWu`b1VmUn%NipJTVDmidkt3u?bzZhu*Y0UptQ{M-^=Imfxmde?%7g0pk|_qiT1~B0rsGrXy-ycwH+;BQyQEpW z?-G@|yXZyoe4;IwG!uarUoLOuSF7owHENnP=5aWBkbR=#3G#&|7CyyKaNFLXEkVoQ zYoo-Zze|aG_gLe-Xt9tg<6nXg9%=__<7She z-@<(Ld*iN8v>V&`*C?X|F5^b1^!bImRbOu;P338mZ||$L`I7%F-ZxUulujMm09Fk(`spSUKLKqj$JjE~EhV`{@v#MeDxHsf?Z`G%{&3j+pAZ@iZ@7z6UJY%QKq#aV` z-sdvd-JDDnO_JIUr3%OK3ljhI54?W5pnZL!3hXA~TT=4V8xzgPT;skid5^iKOyzg| zzC(W)r)M6f?4eb_*{xD1sBAa#vTbeK`h9!XZlZ$1km|l`iYRT?@7wTnKMtSqs|*e| zr{=%Gr?rksm3Mw)^O3%Jet?FH=BxAtj)n4@n%~iU>}&0$Pgn2~} z@9~i1chaBbcmItJ^}hecaX*yzWAoSZ575kS8qiaL>TB{jwV>!l`Q28v{j%od?xM5g z<;dj5=50r(Tqz?s3Nm`(dK7*{E@mW!KYdu?<5oVKe=L&xeGtgRUd-aBRFEqXJk>|b*UTuTl$E{@G>m}`tYu_kosj2`Z~JZFvn(krX? z9;@Tsr~GWig`h6b?XUap-c-PR9?7frg0?QFnzFSc_3#Bj&*xh7V{kp2y`q7D80PBV zied~s?LTE1V4O47XKiW(%ZOJrn73rVzb@a|#M#Wng+Z|hcrP><6`OoY@=YZC$qq7! zH4EG)b)}1b@kN;uq()keGEg=oUU3Cy;+u=z)HBaS{E{wONv^W(Y`?d0A9G1Xmu+io zuH8Q^(zf)QzUt#cBiuw@(Gj0jC{{9VyhymfY2JDQ-mI6ph|iuaeo^%9w%nx`r)N9U zvk40DxibA*GkC61aH7sX^~$-1{X})BbcUU;DQCLKML7vo&!O82b+i0-VN$JtUZ`-Y z8BA7)BR(R1V#m>(e7;;?ITDO{heM`FtqjM#@9`vvP*d#X3sW6hgo}8i&mbNtV(WNe z`DfI};W=nCqZ5&&pp&qZ&z^`ba^?gR`vzTOgk6(Ep606C^|%O5JfBq+uNg#y!RbRI zLl{-d;6k8UH&}^DYl>$|GoHgscVxlIIj!WdifSYp5s7JpUMpSX{(?Gro+12N?rgiK zbtw^IK3n>8fk6S^GBCK`>NhH^+rMY|3&{wvc6Vd#UMkk^UlU9B%vo1_G6ulmt+81+ z{NUYF;Be$rIF$ag9}ed$INXwf!!0MnL5tqY6iAE}1&gWLi&)6Ft z`Mx;DVX!H0u|!I4%G2XD#aAl8bS>pxB@530jLr>A!nx|(jw#64xD1V8gH7q8+{*`m zXO12BGzFeI0ndk*0Ul&c$T<4JQ~BM051x~7MER@KFQGT)%V%Zb^A#BQ44y3H3%~(Y zz>@&>?iQZ7IJOI(RM-v*R$%)cBs2tga*c7bYjRlw$b%}yUg2rcqFWV!B=(%=MAa1S zMNPuva#$G}DOhI#2W3kGz;Vit9>2f%@F3cUHQpk?k;RO8y*!q(;ZY9(@?{~&8#4AG9~B4A(dJToIHGQ3;QU&`!lWFQ5j}=I;~ryqR(%I~ zDZ$@@h)hHADfe;q%~0^UhW|6fPodKC=-%8gw$|naL{dXlr#|%fOUrW+Y)@X{1M+Z)Xhl*9{qthw)Tt3OBi%?K}_c#I_La^v}O99$@8pFS$2XpkF! zy}m)Ji1iCGB4nhC_7ZDH1cY)++0S8{#FJ#ac^9>FVaLO&ku&Lpd4<(TayfY_jDNCg zJ$_Jd?mgmTeh^F?9~5NI3dO#A@M@#LoV8}b)M@eA>FK%45v#TKcA(ySdRC8rYPnm& zePKTaNzOC(Q5Vl>AiB*7?V2P<7`~g7YP61tBugq$?2js3Z1l?Uy!3_clgc|8>_{}wSGhy&r$}xjBK9R5-#43Q4ufo9tRE?ZVvvJ~*K9LmeXq!pK^I_t z#)HamM!Jdb#KmS=Rd_zH%1^CJ7wsqoPXk=4_1%L>;U3X7uvhZl;xk@1H}|H~aDO?* z3a5&mO82kKbYDTOI$WW>x{)qlD)+vRLG%>4T01c8$4cwung_-MfFdc#AiuO!IkoqRJVs)Fp0 zIp$%(ICoC+KB*w^P6_?9g2IE|3;WQUO}2l3>GRKDv{UZU+6Zo&Yl#J?i&y7xvxOS1 zH6ybA)OB)O69fz~HDOTNkdIGQ|YwvS3M5A{Y!!`i=Gbx5tRT@R~8oVphJ z(5D=~!W^|nP<|s}j}zEHh^A`iGk~Mb{BnWx^$rKwQwXHyDzVQ{(?*SYbP*Bb$odmd zQl_;}44kEVLh}$OxakPfpOu6bnZJ8f0HpeJb*4Whsxt*F;KAlB>PsCk)5uGa6>n5B zCfQ~-nukfUTFQE1X7>D(5GucpycJ&yu(mVN9Y3!stTO;21{vE zY#veZ(3qXKm=lRTgJ|#{j|eQf(nZx%g#4Qy@@`Emcg7&EeivdQJX+ttg~~JFa=KPDgqu$er8snWHP$Uh5VE? z^fb*3m#x_tuXI)K&D8>pmaeD`U6JUH+UzyE&y|B)N9iwZQUm$ zlBi!r(V+bq{hx@xP)0S*3}3#c5oMICI9KVS8Z$bmMoTBBT&1=8lRYgzm~HQiaT*@ zxOml(95?5(G5mV@MNPCdq7{lmLdxmOUys{Ye#<&w6?u#b9;j?|Kk_{_W*60y$ zWH=xjoyrHRb8MX9)|q3BjlJ6@woUvre~VlYbRSKxNxVvTa*RFR2`xZuH$d?AB%I;F zzWleWXM5PGtxFBHUh?Eam-Wn&@#XK5XNEeWikG+L#Yjw&E{2P7DGQJCdDe#uW=KM0 zgfD+jYAAILlg^|HCG)Di(m4j0lam`BtA6vs!_==$`k&HLgQFY0sXVJ8Z~2Voebha@ zr^y@sA`4SobW#_!IQ~p(4(q`i-TxZN2YD+?$CtaTIkBK@K{hqi%Cea(YnqCyvGw)U zzQts0WtjVA#+vyXnT58ERq*u^fuHR&CAB z%;z#QCsys3sfnh%j4P#PB|m!18##koMyCqMotc%7$5@mFGOesZt^4>a21i|V0FL+n zH$c7={lKaH`RroDUd*y^HVF;T{>(aPQY&IDM%3wZ`_dL`7d!sA8WOlD10$9Bo0Z1JIxL35#(U4eI{=v!IErI_66WnXd1C5E6Iq-&0B zmdCZ#M*)AxcwbqSNoZrfmiu1uk_xlq>(lA9pvItcQq;3&X@QP#KMx&{XHV7D(gm)_ zl<0I@&D(w=6#McAc7TN~bi`j`QV-{Tf(MqpsX9(IsC5_t57#>To?NM=#ulX-E7LoP zrN-$S81`NuFw6|txV)TtGeZn z5&10*VP%Byp?PfQ5`o-*SvP4jD1=!^6<3F0Ldp72(?Inl` zR08dz4jru|ED~xTeW;s?E76C#_?>T-h(V9F31n#hhd-4j=Z_X6770a=E*d4{>rCaC zJ+j$~eo8E{D&fLvimU0Ev6IL9RUg+iq}c>@coR#*1(W7QCO%v@`7^&O6!UhN&kqrv zm;;%)52j4meTcx9NTe1y=|<;aazR`L6o%vCIHhqZ1og)(qNF`fl-Az-XQ*n28c| z>jtE4LgTaxmH-#Wm^T={lDK_Lm^|Z<0@>Q?@q)}mT<$U-astwduL}Zr1qK3WIoYyp zdVwPRpShP=BQ>%d=y{`eugr_!_3>J?dq3YJe~Gr)2;%QI0$&&QK$nUpE1?0BuiO2` z76CryR^XTUl%3Id_=EfYWe^9}Agyxas%n$P!tYJD8}n|F?4_#p$^1nLVSWZHoI0E3 z^pKpf4bIDIB<35uTBVUoeJn@dJqr-#O@6+(8z3N;5?F{V2BYFlS$!4PGv&9*Dcz}x zI)%m!{7>PgON=ovn|GWCOBCP+Qp~NjU&ri(U3KNC!}G*8;AMvwDj`)D?0)PYM9~PwpMS$ zxs-49)-%C5sVT@Qgec}{H#8`~miv?q2+tss2r(u|ZklC!0C3-e3Kg&5+Jxd2<|E92 zHn~NcEL%}@{jC5^0)t!3rBS$Ww{#YRr2_Mi2u+N_Ypj$sQRpSwcxsX*_7J{N&xlP$ z>W18tra4RP)QBN23sUijYCWEYhwk2adLG)j_cT285L5PYVoVJ)*WZ6Kqx>@UoWv-D z0DZ%;c;zDVb_zw^tj)f{sj$T}KlV;P&m8amf9IJCA-%{rP8e2$XZAH{zEpP-@2ucr z9bpz7VLiOgIMg9eEHW^5cBJ=Y43#jUhz#-8)Yk)o$WYIb$haQw3JjagUr|I6GYG%= zkd((YF+p8*@+`-}xu6b<{ZHwlF+6d0*=j!9CEs>%MEE5Qs59W!foH%L|L}4wpTY%@ zS96W(@+pz))WzBZ3t{e%@ zVPp~LpigX`MGw7i0iK-{_l<`e6t5z5JafbwHqEUL!S5^HIK;j%P!Xo}*EI2~BF6M9T{&a>h}x$(R5 z8HdWYzXqG#z>VUF4_pk``YG`BG`M8T3%FkU5#OV_J(r}sOwxl^QXWaUnWP_ENp_O# znI!Cmq@a@|XC~$vchSrT z`$-@2Z4H_9JkqIM>PnaenZ#TY%{_SnPmz16rlP?D*Hau6BrDI(r=0Q}a7Fb3drzaQ z??oNFvR`ry+uEFk)H5*=zLLo8ZaC`m`1SIOO<*Fz&OsGUTk3rE;N~tJdCyB>Q^bQC zX@tDzreLb%{d4(Q^&a6%auV-3R=LOL;801@5LFR|sO3@Jog2N|n}c+g^mTiMMXqED z1Ep|fq+mTGKT&-l!BPUQb1N6hk1;H!SEh6soUeXAWelI&H?e`kT+F8mD~qfE=rOSP zJeM(RVJ6!wRgZ3*37S`$s6~(%BcHQjcL)DxqRdV%Ak`H0*E0Fsvx(L$g&Yb(+vN2?We%3E4qKC`3-quD^%VgmJDUI$f@0##k`A!Y)+6&2iYCV<-EFT z!^-M(np5ks{H>6d(&`!8UZ;idq@IK~%>GH{)TkE6%aRDoP#WF)ntAXOYJibSIpuAi zytT-XyfP$YU9$YGzHz28|H^kdm*2#>L3);ajs(kI=n?tExxyNbq)}Ql11PV4^AiZu z&Bc>ZA9B3KtP?)Mk6AU(>~}LTZ`EUti|H1ng@%ajl2JHL5{T3SInP~&C1bOwiKKe@ zZhE$YvQekqeD6A;_)g-HsE_GMms8(B_GMFg(uF4_g%$HnkBxkSUa|*qp`_f)k`Q|#&F~g;m0E8H7oY#jwg3%HWbJaT+cquJTugl}aB#sP(QYXfs2sO2)P&6n~r9#nT4mHF)mSZSUswV?tzVEx& zyH8G3|NVd8z4y8IdA@HYYyHk|y=#2;T5IpU*4lg9W!b52l-1_uq=>*-r3CBAkn2@NMm}OPR? zyk!fH8{8GZ8!L`Q&aJ3i56iBRb6+2}Q<%V}p=gC3-k};|XCE!s!x4i$LDGH#V6fd| zWAVH9VROIC9o|F6MVg*?f2Rn3oCW&>*k8cD2Ft-dY6Vy?u*JYtfbn2;@LLTS2v!5O z0PH336Zbb9w%ctDi*hinX$@ZmMuxAz#C5vxykL{Vc0XC?$q!fBjWMaTo5CF)mLEMA z-uDqDhd@!*(X(OAGXereSVzwN_3&J4NMNoQ-%N~d2H}zK4h0V17!Ni(EOCr)L7oub z0`y}tmnCZp$+A>!DZihh;O)9xUWB|Rf6DqWmIvaoD2MGlVRnI~vpb5?fqWw%AxWP` zawtRJx-6y`C_GP97mkOSHFRd&)f@8suw9lT?7fPZc1Mr?qNkm`O|9`$BzuYt?6!-L~pSJ}{Vx?NNNgX1KLJ zV%j4G*5dg=JKW3+2Lz7+ynPe0w}%VegE78`=^$jm-J9%j9XQ0{kU@(Og+EfqBB@(ask_nfwU=R0 zv0SK5y{Jx@hE`ZZZ?=I>jf(u+08jMvZf7Zb;THl z_R&Iy6|QNe&>%yoZ9+>7DFq9g0infbUqr1)Dsi;)L^X4ei`2BLL|s^b9>V2fdzv2& zZx#Z(8|*Bwi@~l3yA$kmu=~I+2U`kO3pO8Y0oWq28n9Qv!bu7D!~KZk;q+V&@PV@k zG#aRR$oo6P@?n;*e0HCg!)Et+o7d<4VdPb_`@Dg5hCVOQ1F&*-pV#Au@W!iw=MUbI+rU29ba+q8i3&S)2`rIgR$9nvScqK~T9rdbIf7Mr!=I= zxsWC&vi=%d*Wq0~@7EhN`DNfw-0Cpzh13~bupUW_#kkXgemi zW%BIu2)KNzubp-kjx>zNCRrWvUFlsQg~4!14bN|eTg$Vf;U_$z0UbI!2!6tox8c^V z+5XT>y|BxkhGyzXnPjby;@1bU9K}yTZ25Q^QiGjq3lo#@)aVJgUt+nRf@kOUI2x`M zYw8D=C>8I$x1lI<+OM+572ujYegdxP;|JiHJ%+LTSM$f$nQHQ(9mChMEN5sdvf;|f zscCZbT(hQoT0yfo-J+{$MOG6S`nt+0vg*Sd7`vKOWI4tFH>=39i2-h2k!2bKjk6s* z-{AQ81WU5^cmRcIVJIh@FF$?(R8#)`cY^uusO2k8^)kWNwFNXq2kB^P3vkkn#TZ^o0Jn0fWk=xIpuZJL zoF`^c0zQZ$n=3CfJMpnNaJHgsxLR>E`!yhe2Qb-#Cimc8?r#~+jZv}eemG{V0w|%9 z`8R-K)~Lo0_@GP8lMi_BXiz^i>~<$u zaOp7&JaAZ*|CL7h9!^_eLJ8vthY@BF&LmtAuq$B{;SjcdT|Afz|o^q)EFFf z6L3^b!BKjHQ;Lqd8Pew9Xwgx^{#;It4hOrHxl(j=f#7&`0;dR_{LbKLyMUwW3XTpP zMK^E?(9w4XhwA}Wg-$#=rRWqyfTKqTpX=t7=#-+P>IqH(I;H4v(O{M6#G|7@rwAP_ zI(l>zG2nQi6O4`uodR_9=qP)E6O2wiIz{Mc(b1!$>Wx%|v=2C5{m?HK98G_4iUxqA z8wieK5IEdmuwI{nqxuXSEjmR*(MbR&KM5Rl3OMn@!NJ$Jb1HP=#a}p$5RZ-;9W6S_ zvET%wQzSYW@Qcd=TYydxI;H3+vcXZIlaEd*I*M`VhfY2^rRXTeqaQl?=#-+P$U#4J z^3f?pM==5Y(8))q6dlDx^g|~f9UVHspMz6?4mSxYIvRAe=y**=ijEE)FP*!L4j276#kKsD#jQdUugJPJ{>G(Q z^WJN~KiFi6<-yqlntFWq>ge#alFXZFTOVhL>Nt2Nx%s-JldkLk^8WnXY4u;XM|tvp ztQu-6CU!sl-Qm+CZTAgp>)FZQ)TG-d-qq*F4v0E*_&QWxvB1Aj9=2oiB=<)1gU`%? zeN9KEH@A5_>F{Fjt&#AYBn&>kU5{OJ>X(E;H@9s0^tf%f`Lp5m_MPjyefR4Y^A^M} zZYk!`$ac=pF6-xSAFydn4~q^vdVZ!GdQ)S)`JF!a+Wf*&jr*u3(2tS>quVY$K5*Kl z(5U+fjW=BjQgq#)QThAAEaySmIvX228GWs#;sQ?XD`qqtoX|UcM9a@zJ?^T^d;@-K z{j|9%>Fcp4Hr9I-HQ&cy?lLAl(mmY`wH@5HS@2dfRYt>?m(DG2@$>1y!+!4-fG2T-?e+WWF21k`XsnX{)nQ}DEI&O^FFJXs2 z^Q(@K+duUfRPf42Uv*m8;O|y2_VT`2;Ugx?(qAf84RD{3y&hJ^?(EppH9K$WSM`L` zqdM=LeQVZgdG~HHskR$$yj}QJ)7y?uQkBiacYggeB=@JoCr#qY`=nl5=RI!nys^EY z1tq_JFzu5HyR8Ek+wanF!*;dsI(z=;mC0$s29KECr*ElOT@MPWx4YNL(y_}O?_bI9 z9Nhb^u;t~L@iEOFY`4Z%rfAcDi`Dr!+l{|AOBgU~n#ah4RkO0km4&xD+oK?4wYmHR zZ?U(atmN#&{@Pb}c7)6RD*D2!X{L9^x!jk<_qUllTLvd~nb`ZY^=I0J-0hu~X4j~q z-GJW*I3Dy~cIC0p^v6ptjPDZJaGRfJ53j(jOV6EoHRs0ZTfJs#Q~R&|Y{ZV)T^*W^ z?KW8f+X6hAN4caA+?M!c^X$fd{q}m@Pxt@2<5IDISUXML&W?Pm;$Ift`rb{RTy?S6 z$oK8*jvO%DY0r(|lU-Woq^@W?>e|um&-RT-#*^j!s-c?K+t2m?v(PJQMfJdCTdd!0 zlYPFiRn&+jzcg&&apd^s^OvrUJKo`(ZU5_E<*z#aP2sOSysaL#zQ|H|c79_Y z@%z^KNrMy*e_d8K;z~0<oAU=Z?$mB&w&ld03m^6H8~-x>n}@+R^^R08vQ_AZ zR@jd|>>WDy<%v}bZ8En{dT&0%FRW-pwy$5S=>s<^{_-s4f+rsTJ+ZiKWZqT9@5@h@ z9PK|_(f_AGr56vpj%zcu*wn3Cv}vakF>c>;M?LRqqbID@oal1S?}ta#jnjsFGdu9} zt8Np{WQ;qOvu4ll6MC60zE30R+D8{Z9X)39{S^v`R!ftd>rMLs^Y z%y;M#A<*vmj|;t=I_8|a9eVEIt;W3bz}wsB4E_Dt__-$^eml5tYtx|K4@0dXT~6^^ zRbQ)apWO-Fxy?V|$8X1cds;}J=(F?1_=7!5OU@71RTpj>-sQyB9|x3-wpq1m33o7J zaL}9sQB@tT^^GaJG4^O9kC#@t-J(Wb-F#(I^d0%i4J)#_ysr0MFl{b)(M3hM*@28? zSKEUfX1(5$pP#lZ}P^+g{>}Le?KVmP(}Ai%M-H} z*fnyyvF)dC{dYL2HqYDA>5tHWrOP(mzAbxqq4K=OWI{nlNL{vKrK)`E&Eu`M1_gGE zIhI*EJnavQ!WDh0D@>29yVJLza}&jtO_?*o_g-^2Yw9{ny`uBYzGZ!P{NC%ei)HJL zF$eBk*<#)M&%`f3f3oLHqu^l|xoOU8A7tMhW}#iP_+Up_SL?j7ryBWf==j%(>vMLt`8hNs`sL-(=5yh} zbMw2C{#@4gNW$U7%~!9_y7fo9;)GQF;{D&8avXW-;5OisMp~7BmqfcyYw|d{+ci)d|+bG(x@e_~863%MmW;Ox)j<@8Y*@*>iZzQ@O_hb`lNVd?+~g+W6{L zL09gKUEccPC99-98Nay|Ztwm{%gbkOnzVfPTlX{bnmRV$dcMhSx1Y_9_@1)Zee&@S zJ#O~2T6NOo=F$0m9<i@y&a4y9r6d-*&h(Y@F)Oos?H%*dE}0HD1phVP-d(jL;qJ|(mix?_Enaa+ov_sV-l09&HcpLNHSmld z=~%q3%lX-vlgs08UpaZq_x1>jj&7N@-BVdD(ss3L(Mw>py#84CPYpR+w^ck)PuK;zfoV-{dM-F z`IYta_K)V0@BMhQ*M@X?;o8;R7G#yg&VMuTSk|eFhl@kgldcUsHF#J1NADa*C-gbu zeq-;FU8{PPuT?#Kd2{TPBun2lt#9FmAux*B`-gNL&~f~|z;AyI>b?4WZmZQV)@L1m zd3f1FkCB1*hkn0uZl&d`CwZ5?KlllM=G68XYQb~Wg*3l1Ti3}hV-}AXa;Me&|FdjqWS)T%_jL@pPOBfuj%6W(+$7;h_h*5nB8yswMxuWa_|n-6t08J ztT>rj9ZqKMz{xCJITMS9oQb73XCn9GOy%u4Q!Ab`wT|G-tow3iHlJ~3wj(%m+icFf z&Q#94Za!yjw}!K@+s0Wa4saIsXE{rI9cSrK!C5+*%jAx(GP$##OkOWcW>s&H%*sVA zvvSRoS-TdnB<1|Z` z!+G?XIljmgD}c?t9$0LSXz@gch~t|pSiHWg0~VW*6m zWSB0-MTFfJV!Chw6aDM~@zM(|=GO=;hHXzggm@TnR5`}!Oa6GfgW(5)#q?IfkpXru$az5ur0u@CcYLB%ex*d=Jy>~ z47VFBmhTK$lwSdha#v6a>L;>ScWy-bFs@ffFD^YH9nq&BIG8pX@bk$8N8%`t>=iCi zQ9dF)S>!3cN~MxT<22dqK7Bf29^sdS`GkuJmlLieTu)d;SWH+#c#%*?_=HeTSVdS( z_=b=h$I4|!C?~WfR1i85x)OR3`Va;Xb|sY34<{Z?7)uyWs3y!I%p+V(xSX(nu!yjP zP)7Q_N?b=+MyMyOCgjGm`pO9vgkFS7!eGKULN%d=a5-TCVIg4=VKJeWu!OLb@G7B> zu#8YoSWPI;VdeEAR1!+*!}dT8>Oe&pPpBr$BV0~cM0kYo6ya4uJ)!FamadYpUv@ed zGbWvj%}(J4rX+K*so7ljj1gSFge(qZ$q8_a4{{OlkU+RhBoH>8{bC0S;$?^epb*~> z9@5FqAQlDvu6s%%7n6{|g{U(CCvZ`ae^mBpE+l(6*DpoQ^-jv-dW{*!g{LHm2}7Lh zgp3IoFGKtRz7Rht6%f)Gf#VINk%ECC9h{KBw6ZgC`U4E4nU#{3n1bUE8c2T(GRVW& z8}l>pkQmTASTr#)t&@{mPY}~Zo(!gyR}2_0{4oIxdUFvGozv1fXJ(27oPKcko(>qp zjS(>xI2LjsxXFOATq^j0u3%&w0oadA5GQb0ykuZ3T^7HFvve{c4Hkl>mkz1c_(5`% ze#QsBQhriwDc@`;MU5ZEkAn2E{M{ktM8Fu}sKXE#(Gihj38Sc}v zHSt+_vOy25L9lXVK`GLpUMXT-Fd{4G7=s@x?}wqJ^4Incfl{JT5#sL{_-hS1O$K*@ zQGL({|5|ZgVi*kPW$?j}EOZ1H!F7f*rh%IYf09XoqvFT)2mSv41~uUIw?7}4J7a%; zm;K!*0-hlFPk+o;utu5i=lE#Gh5w!P?w z9Y5~e_0#U+J$rxNxBtK|+JlDe?yn z9UPsU>$$kPx!3n-(9qMXQR5~}y_+@nY0=WRm7jlWWt+C`0@`=z7}%+Em##s)5S);h zl$=#KE6_He_i0Kg&O#H2I4u|EKH!e>(sFY5j+U zhJ|4_P4FBKNwkDKSdfp8?gremOpFZ8Bhx;u5s!AJ^vh0i>wV}3Q`-AYVh&=F~6E) zg8c~Zfbecd>T}6ZoADnh)5p`pxJi%(9*Hc_h##bedSUlb!^FOd_j#;s);`iwN!bBU z;c_6{hy8z)ST?+i9nG~9>!^m7mc)$$cR2X^QSR8Mu{IyqCFbz)^lNJ%8On)0Y7C^E z2yV{*WP0ovGmWB7@MzWUr8UPKd%`#ffukVSR5BlGK=PN4n-mu3HXXorAD!7FC2K&! zXqdM_W8~k@*dJxMBmjZKvNJML(z8?vNuv^mr$pi`1e+_y^di$oWQ|A|Jz`=?SO)w` zN*LWQB`IsfnDlPA?}N=pW4P$Bm;`mdtc(%q!$pZ1_=)~wAWBNFgtU~{G0|a>;TT6W zd2IYw5PA_R2}go1{NOHLMZqVEJvEH$MSPUl>w1dw&gjMDvEsZla&y?$f%CkQf&C6z zER$rGe!%Ae$GLOK%>RJHDt9e;{s$c9qie|*eZar^fbTS^9e&pb9OtIdm@*LO!0{*c znl?>v)*7)7PFn-wj5YH|1!qJ5kPMzrr5>Nc`9mwiy(93Z@G%+Paz;$FmYodb;zaRsBCk~pprpa~?7Z5K^2aYshE2;xq}Rm7c% z#}UW13N-P=am@xzDseYPIW=+Ixq&8!czs4W4RKs6L6b+E?caedO2iv7F}Iw!C-DN} zUc?KDHzHm{yfN{vvzfk|5HBWqQ{r0U-o#6YHzQt3ygBi!#H9rj9r2bVFC*?tTu;0e z@oM6J#JR6o`C1c~6YoG=K^)h-(YO*1WR&wF-if#mah|x6xIjFRcrfu`;vvK%h=&nZ z5yyUrCXP7vS2Xd&doaqS5|1RVCLTpRhj>ro8sgC1MUzLoH}QPp(zv;t_yCd@5Xbd7 zG=;=JVU#N(&dwgt|A|i_xt6$$27nUcCd982Hzi(1+>E$1zMB)TCbEqYElEaWmo?;+DkoiCYmbAZ|^(h`23rEpd0^ zrNp}sFC#vRcr|euU7*PeSbfci!^RqM9?6op4{AR}!}+ z9!%VwxQcie;;F=CbU~Rz+=_S}acknsiMtaoB;JL%mblD|^_NoOR>XD0t%>WU_{6z& zRNtm7zJj^;bDL(OdDL!$v6uuP;uaUwN&zHgzFOb43S@rSQbLZ>j!)EWCoaHE}OV-j&IflAL(3BoAhCl_Vz~FY$0D zS4%vCagD^I8PAuvitz&CW|J5%BJNIHOPuWj;9%YaSNS=(=S&b$x^Iu5mFXn7A4P-n zuMF9hCeHAn!Fe2pEF8|Wq8SErOlVRe1Vh{j2ImdX;QRoZbV@g!xSF_{ z!sDzY8k|=~gY%MTGU*;VlN(EXoQODci3VpM(cs({nh{VVG&m=WCeu(KR<6MGvAMf+gjH2+PD7{RW%|nw- z>1I*>IFE*AIOT)0Q)qDJ4$UY!4rvB`FnJpJ52yN}o<~7=ocBXb;2av$6sCgp!MVkL zu>XS@Y#)AHsQ3UE`d~Zpm!= z03JUne{AP|P&(;;6Wcp-Nq^YxF+Zt(*#7+>v~)j<{Q&F7cFwT=fcz6N6`Vnp#s}0} zO}oK<;s>#$dSN&}h$XeV98oVde4?oL8jk(TI6U?=z1S>&cf)bReuwpt%AF?G zGsaL)oEbN67i?WC#-K;+r+!dcshwkgMJ~+?V82B!<&XUrkIRR8!2WF9eiFrc*OUwU zxp6tMzZ-Mx_q93eA5y(=959xriO0VteHH%N@Y#urSHwXm^JAJj}J9hr2o|JEGWH1Rm~GU%C&N0D3~%AbuVVTS&~ z_EFW857(S#V#*#6x#`_r*S!0`D^Mal}kk$X61@D^cz;Leui?gazz`J1KV3o zzN}n54CR)}B^@s|-i8{LGYzgGYI-iqKitrMSpG4FaX`wyW<13FYuX#jKg=-RvHWYw zi)*XcdPBgief(KDq$A795o0JP(|@F)9kP5>206vYtpiHygv&`T^&e>+(2T+tl3cpJDJDLPl0ou^@YT}gh9xDWB)hzAnCLOg=_N#b$DcM(q|evo($@r%Ush_5HUocLDag~V?Y zFDCvK@e<-X;#Z0POuUTv8RFH%?+};&#Po54xGQmdbp#q8;@24E0*N0ZF0GR`As#{U z6yh9>htj%e9LYzMTv|76Mm&||sl?@Ue5{G*kUW~W7p3n{Jdfm=#1$0ZhWK)lFD70{ zd;{@f;@gOq5SPyHSBd{b@-pK4h!;?Kq;=P7lIM{;mE;|X%Xc&VOY4xXR9;(>yOLbG z&+wu6tx4`f@+{&x6yKG2Aj!8Ak035xA9zvtIwX%Hd2iyk`i+IZeYE_9@trd^yRN5HBR&hj<{RryyQTa_PR?mGt9B@)D9uXYD|ew;}me zlIIZDki0YTGLlav9!&Y$6ECFj0`Y1JKbyF`m>u7KQhW;Embfd)*(@2yU8VHBN$x}P z;lxWx-jsMC$=NI#JeNg$KFQ^jpD*z^lBW?*B|eS#ata?rJcr~niRY2Li^NGjow$+r<0NnS#{KkP4ASbFn_ z$5VMb5O*c{7sTTzz7ugDk`IvLliZnjAjt<3k08FBcpULBiKh}@Lp+Cgp(LmD>k-c* zc^q*y$z6yqCpnu{fPFMyv-)-=c_GPX5HBYF9q|(4qPQhefHOW`TM`oyo2{2StB#6Ke*@inV|JL1(OpGaKVrxHwD{xb_dhq#*J z2NHKBxrTTS$vYAEA$czGWKuDE$E9%SpbPcoFf>iI-7&&54(gd<5~U#K%bCiJKCyCVrQ= zd>_+)K5!>@*4AGTJ@0b zw^L|!O5!7Ebw}bOX;nqyqiFR+;-g`<-#GozFcW9Yan8e-kAYbTV?Oo+InI_E%W<~T zm`k(WQvMT+>WlM%Y*sMIXg-knFn2V_r4(>o$`48}rO(!3q}4iHx5D`c+)vL8o0m$2 z6mU;`5GkHyY7$0FMALAnp$C>f; z57Ji~+9i`qt8h|&xSQL!d^PQyg`a3>hiqO3TfY<@=V5TSx-n0JV^*7gD6btK_oy3( zXU}4z56iFScr!lSaQqlgHMASX(_rtsaeC>7Z6pt+DM;RANDMHP5x>_yJhil zcHB7q><{GQjMBsT_7o$I>mQg3Gi*I-gh8Kd{ZLwUX6vkehSgTK4vqSj+9#W5t!Y0J zm&PH+(UtPUdDzj0_Q>REunx)$TMwxzA6u`f>6dK%vgSE=whm=1$Mmt^GQ;M#rB!WQ zFUI<_cMM<%w%(RtXuoVdP+HAq>+3i!Ncv*y9X0)xacT9Pt-t%h47xOKvvo9lR)ZO~ z?lsELKiK+GP5GtuAIS%~AB-N7{@6O%D8o3;))%E!bzEP^^+##79p5*D>vT2!k*yO- ztLiAn^(QGe= zI6S6bGaj(@yqfZ`^=4^T1HM-W+k2uxUyMt;9XL4Ou@xa{#E`hu<0UTjNVZ-r?UG>o zB-m4UtbT00ucka~J*TGsFkVw1#?h7H<2tCc+d^7j#wV*JIa^1NQownAJSRyhAjkC@ zV>xnTIciiYk+iN*!*M+wpZbyVlll)nTZDTWn1ro!{QZ2${4+uC9}Ca?jnAKKT~Ep# z>x=DGDlKwc_r<4vr1D@HFa$euv-R2j5)6VOS@EXKL^&nrv0$}0MhOilw*65 zcE7M^NBp3TNaF|FFQ7J@zgg>HuCacM{f+C(*7wIjDVSmF@HORO>jpTUuo0$)vmPXI zDL&(=hVn3uPlz(Zc&1@|U_8rk{$%U^HThFC0{#0B_>|hb`UAP#Abu}h7?Y38AYnh? zyCh)jYWwOx;5Er{b$@T>{Q0jp1mg%fM!fx!u|6F)74k-Mm1Fn?LwIjK@s{wHsj(b` z1{;NkpL#=h=C7;aA67sN5MLt~c}@8KqPg^eywt$I`5Mg$183on8n~ET^#ZMk;Jmez zei>s??eN^w4|w?pTw#dJ^#6W}+d_5Q(_j{4&EQHb$N_GBRzj9dJ4@5~?`9!t@`ubt)Q|jmK4QT%>xGEAUAq<`s(KGyjL7w~T#8tFcZxQqD{}fRpD_)OW7dUkT zqGC_ajflb1oW4WUF25;a>8o!GMZS6DCdATB%FT#S4iUL;_HIF*Kktk05fzt0wjvgc zHQR=$PCh1L(Y9IJk!yXLipO8yY`Tc~=kJNAY!&tc%7X*ei5UNw+ksrscc_TE)cqo= zl=Xi^e_dgYh{_9>L@e0eb|?Cm@(V=t%6%-Na(oZ5eZ)8VR>WYe^F&ma z-WIXwO^2V+zx4h*5tXy=ix~Vz=Y8m}mM;`hasPpc1(Un(M}N(wg(7lK9*9_Qu*(7T zFB*_9V!@XCB5JjPzlhO|Imhq;~L@b@-ehl+dT@^$uwM`LG z<1>e$?{*P&&KH^dVYP_rwGEDo`UnjbG5FLl5etImil|(+T|~vT3nHpat3~vx=TU<3 z^5K)hh}vgKBI*v!5|Nv*MMP+SA{G=>h^Tg`CyvKOX`MvW?D$kf?#>huRWH|xsD6D^ z#G;2~BI@_soWy)IU-*j{-=dF*1qU)kRP#$k)E5?u==JWph)Vt~!x5gpV*KDKAtI_Z zNh0b;&k(UF{5!@iPl%}f=?@W=eQZx*Jk=FHhLOER4E|0nqOyD;) z5xIW#PGkJ|&K()njT4bOn8k4@>g`{PsLZT?2IE6N5>fSbu!!-^ zCW)x)x{_h=J`pu-Z;DuI|AzVBs(%*amww$v#DdVlB5JNp6j43o8xix*?GaJm_L_(V zQ>#T(>1;~H{KwT7QEBEYqGEPu5rfU6MAYRB5>bCIRYZ0791%4IvqV%>EEQ4NWuu7t z&v%Ka+Id98`1==_-1eS`THgv06=AY-n166z1;as}A}ZtjMdW%1iC7vGEn-2_!6K?n zM~bMro+D!LrdcA!tCxyc(0YT2Fg}Q=U3y5wBL19+`dha}RF8iuV!ZsVhy@F6&SQC0 zj_x9==lO`J;5v$^9Mw(4(lh-;dBjH^aL} zMJzJAD5A>qu87*UdJ(;ZcOt68ZN=-aqEL4cb)9@fRJ80MVy){lD7R=9c*d@I3LeN0I!-hXTsS2|BeC8;-@Fp8Yat zjlZYYn8de1r}tkkp4VfgYxw1W3i7agMK{O*~%)zjQ{Sl<_{OB8}JYJj2*xFwkIENVg21N&E-5R zM?HS_DG6E$ac@K*e-#m1q&34Q4RQzioG@~XVv3< z_iY>^lfMrdJ^a||pr2ast+pK5*UH3~4^R1Ra;eM9pw%5s2gV0G^YQg3E}nbNmj7bY zq~v*)LlTEri*cj2q$ZMynfwdOnD@x6D{$%X%>cjnvges0E3o37in zpz3YV5}TOgD_S?<9c?E>lx4mQN{>4x-*>7ZzdWk%%SXn(~Wn8(;NW?!a5!Gy5vSrX~L_W#g6sF`j% z%?G{9v8xU`=~3dH*H^)h%u1WwZ;395>Bp7t`c=0lg+&(prW?=dSAU}5oiFuo_Uf(+ z|I7VtzdRXKhyPYcz216m1HNO&&ToG!ZpxcEY)klJsw2O~?os6DU$){K3|i)_|Dy%p z;qx}>8#lZ0{Vg)A24wj2vENU8)6SzA-*;WYS>ItTcxCe=_9bDie1~5@vH3aKi(fBm zKHWCJn!h|@!LI)E-T7};4O!X9?@`dmw^QmoND_Fbq(0Z`uJGq=+b6o^H)+A=4#^43 z8`GBGzHv+R$iZEBk8$&Fj%=(C`qRC0n=4UWd6#*algg5vdDmfc%AYJ~#}6Af{@Ln9 zL40w+JbjmlPJFYt%}?w8)`j2O(PYqXM>_GxPd?T?s&wbSuhV>LzccOmy?a{r%j(^U zkDZyfq3Vu~-{aCW1^>B@GzDtj)TKKbMZSH5gt#PeB;XEZJu*O|XJ^H$$ub%XfraWi$N z*0<(YTWim+o8E;#H~3IR(FQO6>*s?T$6pTOJL*@=u=_#I-}yCvSCc%Rf4;O~rM+VZ z{u{e>pU(31=Qr%>6q&K46@NF5pSZ+4kPk3j^GCDt*1Xk#`GcPI>%>PK8BjguUy4&H4OC8IDHV*ou zZj!>Ax4+WXF2}zaf3{lTevSV#XvXQDUqq!e;Tvt$MCJ@O=abWaxailq5pVmf)3vQf zI`VHcV-u&l`0xplcaA6a`6Gz6zczf{xV649T|4r*L63AB%3AW<8`aYvD{9FP8~j_= z+=fbiaqQ1e#(4Sh+^OCfb9d^4THH;r@th{`+xJ->S>|3Hw0ZZh9;1DD{wwRokv2&_ z{HLwf9dx#NAJpB-<6*bh_WX=Ai)!VAE_|oa*Yvl)_U3bo7W^>dR0qDKupyV$BY^k3 zP;Ygf(2<|jazY)&z;^s|S;Dpn=eqEBpC2Be_|}$xEnk_a_JJ4T4L`35+}oMoIJw2I z?K-sLP5$`n>%i%a_y=;YRVPk$;Z+y*hnsVO{GE~U%?>T}@emi&qIsU^L~ zx$^o{yWfL)d-C^|OvpYN|01YIAI*g?hP??Ib9LkjWVRJ{)a$5ss82ZphMR}TeK|S zP#zS}wN;)zv^zhf$Mf%2JZ;I}kB^!*rDrqVe?r*Z&^j%6S#L+VSMz9o@Y&1t{BxrC zh+)?!e5wlP8=a2%DBGNPkDZS%6-miR5uzQV)*#G9cQjfkKpy|Y|FQ&bmz04L~MU+ z-K7gP z^Lv7o`&^px6@N|m{IB`J{G)+4JB>LW!w;;o{q8HXXx?_?hBKF^Me%zF9<8IktmLit zmpP0+5zad|x%ZV@s~|pf>QKi<#~bsLv#!VR-!$iazY7_$rut1#8+p0Ocae?w8`-&& zdT#B-TR%*CryS9XZ~gSz0gF2!{34I?slKUx{G|0a^2#kc^UpI5`USiU=KpDa#!Kf3 zfA0monN0o%8yWW^>;N9>>SR{~KXuWSw)1cg@H z0{9pBciPqLjiA%!np)OH*`cqPkoJgaqs?XQFbNh9O`TK-BHbVu3e z!PHkmntSO+S=uWhYEG(U$iP>E`}z?0eVbcO4E|pU*V-wT z%zyGy@Jk)#vgXQ5!DQ|IUgr+I6s{}!|Iu{YOM%Ugy%gSS=htaHv4EFCi@T+fuf1Lhm-1x}z3aRbUb(JZaPVcdAapFB z*!MxTaKTkMPj;bN==>foq<*OuHdl_a+w*<3uyVHSx%TU7A*yJL{`Z;H!k$Iiea*9~ z1=pDg@Lw%BS>znzdRGg-9oR8(S=VZzVEt5CR7;SHrdqIYjn~L5s)gVwvbW|{FN6lY zKk4Ir_k~bpJ~?D)=?h_!%zx332VMw=pXlU`x4sbOcKT`5<`pl5lJz;c(Q{r1b&h>w zFQ4#2_+eAP{hPyI2x-}}LnjBk5W2g3mUXV%3t`^7kfZv57s9?<-KY38eIZy)TA7yP z_(D+U+I*@rc_FyOSJaEIcrG087&hv~o##SANp7=^=bj5LqYu^_eek&uO7)ZBWhxz7dn;j#{E#y%HbHtsX>Ny2mC+o&!xdiQ-UBsa1d zR1*4JxTT#_JfPikAvjSs{#BFb!s2ahQh#)ME?Cryi_bNGF1+z;5s>`+nefoLw0Q8t zXTpZNPYw^i`b-$8_{ul$#4};xs~*Sp?R_R_Kaq_x|Nfb<`BanggjLUkKjU(h=jT5Y z;?3h^12oTs&ZAUa{~Y^FxZ8Kq-epP81U4V~On5i-=LgvwD&cddZ9VQx ztP+OB4+=PwRwaCM_Sx}Y%H!)wVZMCWg~szh9+>MG zm|H14?RMha;Ot5v!tz$-yb+Z`b;~tF&wN%X9L({3?a{YV=_nx0y3U4>Af@{?I#0&JBV^ZG=EVBhhR`7aMt2*JLxt!6tb1oMNHi##?} z2&*0Lw+LBXA#5-!9-Q%2h2U6}=TMYaA;g?n8~AE+h0wlvZm}w}LTE0#Jn6^O3ZZgq+una(8=H z2oL&4XeKyU2-md3ZF|^M2o7E{_^%Muo(CtJy(kx=i>Gw0dQvWA6$@Sdx?3*nkMbY> z>}t8tAa~tXi?ijzAf3mX#z)JA7JqgRj{3P=xVN`r_@p1og{7anC+zvITv%2nh*WNX^T$p~jzT2Gf<-&x_(AgI0<$|p38`Zqza-mN1 z?4b<@mkTE@z5RAipK_tgY3sT}Bg%!QJp$&{70LzslJ@XlE_|>3bN1X;(i`5++6YR~i2F?RVIlus{_c=EmJwGRQ{e6PUKBGEV*0@EwvlC=Yl zGHWqG<9up|X1RVS$JkgVzgj7?um!Lz_hI+|qwxPJt_DkE29t!423maLO~nm`W7r>l z4TYnK&vti%=di-zX{#FfK=8q*%!fkg-tZ(~BpmrcM)H2ZBOqQlq!Ud~ff=VC4xxKN z8Zlzbnsj?X*nW^M#zcc}&&0P-N;_n5KLH+D$tM}w2DT{NH-URnaQ_MJ24P>P!1ZZd zfyNY2ir$EB!uZE2oEo*j7`l* zNk~>@qzp@e7gHwpkBm-8AD#`bro>i;=?#S(@kuo78~7%Gq0~QA;2#TNupIv>9}wev zFaKjcZQxCd?cfiMzgRNyC$tvaJL65Yhsj5%Tg}t-=wW ztP4!F)AgaaP6V9BiQomnC@pnJ3PA+_Fow*XA~eS)#NoOm?rSf(E#pd#%Fv6GWOd*- zemJxWWK|?Xc{Mu!8;o4RzMJ}C(#45v|EQKQK8f)SQo#1o8-XN`|7WP6?=P27`cmxD z4>)`hS%VrXAcXHEi(EoU4&ULefP9{n2nREHVG?{~)Jy;QP$A;>QnX9J;gU|Djx+@}K4K zZD%pwKgEX+K>ug?(ElulPf7pB`0&x`|0stOpePR>%MiXSEpn-yOQ=;de-&XoA$*fs z4Bxk3c)ye(ma-;aACJn*3DtiwJLQxq^sjMAW75=Z0+jv8Wb@#fs_0)%Fv^!Fb69gJS)M4;zsT zC(43hGVUsDdiIBpY-J_Ddu4CRI2Fo8-gI16LgMHYs0E%AG^jV`KXKy3QFy|Z+>#FO-+p27o@Q!2)6V9ToiBi_snrkd`Wnsc^?YRW6d=?nSGO*na9Go@P#8}It}Z8(=KYtE6%|F<;YMT1VsU}G&grvMAi zsjWiI>T3=4g?zETZq}R|l)(+cxj{HL2S!@aVL%y+Akhh$3 zZA*FETXObU=A3=98D}40%Gv9noDOo%Ar@?aCFkH!S7)oXiD&WaLi{=qAL@`n@x}7k zL3!#zd7xY%Ymgz9M=SHN0>O__+C6 za_(6%oO?ht=PrxlY^co#Lw~Q)AH)v;9ZLGMl5tjvAa}xcV+HL75cF2lZt&Q_vBl$R zW5(G)*`U=zUqKyPgO05@hqk0+(a#qAY&eI$%+Jl&3d-`7v(a1WEK6(JHulAM*z@Ps z7{0qAi{Y&FmO4?YGEt%ox;y9A+=_FKRdLP%y*X#74@;5tW2}=~eN)a#_9bTmIu+x< zeVEMLgfkDouW!L`cnNSFC|{kn7Alz>#_mw?6WeAT&N>6yCcI==o?)gojfeVJnsAn~ z6)YacMJtAtbJl$!tk@QyJwTiFfHv#Vwx%t(wYA|IC2!#x1r&0PWa~Hwy+T)43$2dy z&zVD7@WNrcEE5q9Zs>xR>zKy4ICe9 zI6iQk`a&BN%j5{@I6yj()}op+$p+Qs233V|eeQ>Ikw@SzEw%^OAs~XQD~seT)fVxM za7?+_jZOeSK&TSEdvlGWzmCVY7vsz@L zvPWIfcp;6ajn2aR?!mr*@f6L+!dyGUaesl8!Z7_ffqp0Q3>gnbq=iKi*L%(+7+(DP_6$%x$ z5jB<<<7PnH70+k(pfd$$ciu+r=2xe`CxovL;a#9yj{WNHu-40U7NurdslIqoLU}8t zyfYrc`{u#gQ{JroTe5N78rp7K3#Gl$*e=DZuZLp;Rw^?K!{SL{22^w0PO!mJy}Yft zda?FgJt%X%3`38Jm)buY%c@{3tAz1GZy3weFlLDL1^wA&$kmqd79VXd_T?Ps4pwRl zZhp{bWv~BsRe6a*C<8dh1fT z)Frdj+xd##!YT0>O(f%(6TnFiCAY2jXO%37lAw3m57Nmjn;x!Ntcs_6~@FL&} zC_^c5FDQco%Af+Sz%+oXfh!>0Qt-H*=?KwLo#vkJiYXecjW5ug&R2CS+# zgzW`+;BSzj)x&Q+U_SVJ0m9@o7mQ)RD!~?kZ4Jkl2ip&9D%i^`vPz&-%` z8myv9#(9J747NAeWUv#!&Ih|5>|U^?U>|^e4Oa0C!h`J$wl~;husLAA1X}=hC)g8U zZ-K1@D}OHI8h~vJwg=cx!DfKX1G^gRPOvAy-U3?*R{jFQgKZ182iQ-+js-gt>=Lj$ zz@7$s53C-nyjsRJ0ow)a0I;LMP6N9N?9X6tf-M944y@Bl8P^gl4^{;>1#Ax3e6Z`m z7K1$nRtL5Uto)UX^8l*^8xA%OY#P|9VE;#ZR{~E}*Y(deWhjY~lw2t()467qGDjgH zR0?s;Q`a>$aw}<8sWjhfyk;6zMB}4UNs}~?CKV+rG=6K}b1p*9`@G-xJ-_FBf4}e6 z_Fre6efF^S+H3E#&)Vngg^&-S96~jOmk>Tf5dRAEVF+pvW^8YaNr|d4?K%pIHOe@3mkh zAFb!>V7izdrVopkhL{mNmzs)A!;G=%*bK}BGlh2nn)9AdSivHrH9W7F1#i=|g(o!V zd7cBjfz%P6WjMn#3m13`pc_2DSpbV}?(mdsF+9=m#Jpe^r#J7(i!VHdLC^03;i*P2 zJWD`(9m6pf^Eq}7Xa&u}))q6@c7e}wIe0O=f`jS7mmRwKzd$1pvtRuYvtOc!*{}Y&JGf;E#n0<5SG5hAuV|M4h#EZcQ zpfmU;z&k8FHk=U<<;A3XEMbIs`FMLpFb6uxpnKB;qUiin@R30}!^0cCBNze3iqG{8 zj*Rf{K7eBT#D;nyvlRfJ9{e4@muP%@T@nfp4F2M5dk6L!SsGbCa>#t_SegU_<8%$nI25ub8nB($Phj^nC=xt?v1}fa0P)&{Im@ z(XRzZlIdM=blhE6p4fh=C!a&sfp^%a#LQnV;2r&%Wn}0tnGlCPQDD}Go;UG-CV~QR zV*t4?UYgKQj{DNc1I?%qL|+nPNZd@~ArcEnJWFC7iOnQ_BT*E!E&Rrkh?5uy z>;35GPadx#F@?lD5-*cjM`9<5gN2CesU%J#aTbY-No10^mc*?jvPsM%@id87Nqj_N z6N#N9N|NOsOCnC91&MAX@+t>^?8)--j}K9-!Wbc5Ogs3RE4WI*UG!JMIg!lpNTvmS zNu(d~WnSPG3fiJC@|p%iPsOmK#E}()PRG7eX2Q3C!6t?U(_I5XeZpX6ptBdx$s1yY znnn78Tb50zZy1KP3A@5rPUl~P)eE}@_|VP$y%^46c9Fr%0JB&o9cw3ISp@{s!P5xx zu!ZrKEZS! z%NTEZII`oAI1Gsxwh}WB4vU~$^G;)>!meHcOpuEc&sfh{5(riwzE1o@$cfIhjDqP1 ztWi@e(X6D;$Bi*8P0$t%zWw+@6bpJV9V-3n*N`!NUYQB8ZWMNA#15FOrqJ9-IwRJB z&VX4>M0Hwk8YFJh81o z6htJx1HBdya<&kix`XVCLYL z$E5RP8=<;H(&t6c8LnZBAR8t<1Up8?;RzSCEe54w4->5@x>GC+Um-lj(ds7!DD=`u zdZ>3SR>#Yg7uOj^CR3ll$OvW#YAQ{1#xgW2fDsmo7%pCn0OZ8riYbW%!$=!U4}~1% zc(iv&cz`Q*g{T4gCbe^HINdS^&SwZY(qRlCTb~R1@8x3~u!P|SEr!kqp=<2Id?JHM zEdpLD;vpS0_3>fwzLu;ETH_t&Lw5)Z;I-a&%!1zgSVR!6K$5Yb`+7l7=<#91uxN@E z^e(FaMg$Y}2}pkpk7EyWRDu!AJLYLJ=GRjmbkZI^qzzYW=EZ=TghevEc@@j!)r8N% zu-TT5_LjCf+L}JW!SI$f0n#p*g+V3fIaxaL&q$*5$sR~{Gw6a35tnE&UMobPyb*=v z3pp}_&Aq~zkqp%Fk(Um34DoEk!h#~hts+B-uY-p&8L)zQ2Ay#UU@#-Sg6D-sL%lI< zt}v+LZ@ci2{^h~Kgq`V(kbqE7KC+1Lo-9F|2=X9|VFh{#ASi>#liIjm4#<;jEhb#tUi&;loUmeGNysD z=}0ZY_6XYcd5omoVGlNn=6fXM6!j_xCf#|9;viU1GNJ-%o>o zrO7hFUzT4^KBDuzX@30QVT$y?{<-}4|MYo&Il579;PO_iAmm}Piu5aH5ZHa)UnKBh zMEXUfT+GSq%vKZW{cpA3?~6n16dC9*aSipizu%|%pLE7+iMJ2k*Uvv7Feo@AG%S26 z44jcs(J`^`)C&Df&CD$`Jp=i=0FGrIuGzQgcU%4 z1GEQ!fVC(N;BE-XKqDW4J0y*K5EMpY*a6^E0ZSnq0~+BS2o*phyd(#E0f0vS8z)D> z7QScT7X_#-5AXE@+63@8gfT#u03IBTVdH^j1L}`~asq7#cn5+z(8vd3=2$2*(8w2} z5_}^NjeH~yC_$NlW&^fBH~=*Ar^p(IVd+34zluO*f=2!orr=+J_{h&*UjPkziLk^e1RwSvVW*}NeAv^3!9FBjy%08#G{SIWvc7*3XoO8B zFs4HK2xZM+H3Dckz>DStjZoMUbO!ja&kBRRTfDpw;#LHW@Fj#Ih=aB;T0uZM2K$Pz zOAwHJkZ;O9T<~K-bQ~Fm(vEKqFt83lJKBMm{xW;1k1>GvH1L zC=T+I`Gcg956uUXM*b>l5K#Ka&t(w=6h97-OY$oKTSyxDyCDA<6d(D!ARie-BVU-E z5Kz8sz^5dQd}EaCi8#nFW<3NH2l>n7k$mJU(@fH>fV05Q29?1b(2u130Y5`P*LDIP zhr3pkFY@!e!6rBhf`Ty8D6EyMzS^@q)C=T)i;({L#qLDvPy(>W@KOu?v za8LLG+758)0)hrN3Cs!t%F7e*Xdvh-#5o4IE(pV>0i6gKAA(^PK(7TH97^a6!U~VmbT#1MC^9~v9Z4f!tt}*t{K2l1H1Y+L zh$iC$&L(N(1Gb5zlK^j$H1Y!*3Tp%M?7e&&@*X{vHBmX?p)kGZRlUGdA z$d6ATj^IlHI+C;}U@A!$0S<~M;{f`RbU5H2BwYrr{7TZuXDZ0G`-F=y?g?y`5kOAbu^N#V!~RfJRud8^+L=Fm3_{ z?SXa$Iv5a7A#E&R76fbHR{%bR-~jY^S={V4%- z+7JB~;yVMLgWwPJML@j+(EWf$zN9*bARUPB0LX+82mCm|6bOkxvjI5}HUnJ*SPUTv z=w?7R8_JC00NQehx+ejur4r>=2dpG%g!*Y<=OMl!;7JIm{3U?a>4cmS9w+G%K!Xgz zRu}@F%_3x80k|ZasG|>{MjqHeND~Jvf`Duk!Vd*t>tWx<8gSb&s3)YK1o#6&GSDW+p$$u+?H~?9a|mc&WC0jK(oDdy zWkkKGfcqezI0pbrAtb}K2oIkn;;;b^mXkD~a0O9LDZtospaT#eVcta;?}0}61j1UN z8vy+-5q0qgyl@%jQNX_l81x75fer@T2m$508L$Qd(vv%Y)|F6~*Wj-WxC;WZAt`|O zuD~1);@1KSUM1q&0`7x=;v4`hCHV*+ku<_l*FbKN<`}?b5KvpM0K8a*Vb3AWD!|ek zV84JyNVy4ppb7SB0h&V?473H{uxgk`0X-aWIRupN3P7n_1dXr|0g&<6sN3BnWzOyIKtKSAK-h4`-t9Y)v!0mW|x zbbCX{4Pi9|G)5yVe@nDc1>l5cB91CxJ_Jw61C;*__`d_1w-f1G0G@+@^zb5}^G70mg!-SMy&=9KU`q#F4|FTw z$W9_JIl%i6s^HpMz|~*DuNmk#zE7zX+X z0!vkO$zXQACW+p0*CJdA0rBGi zn;{^XcLEy29uzLbF#!yPzyvxRP)rf}6VQVJZ$qd8`VOE7l_-N0;6##E1+<2M(&r&b zCj&kw=^`Zxws0cU3DR)~^qB5cjO$Xc%le=@z;8eZ zf!YFm0}7T2AsA%E1)OOFJm6acvLL7ey%sPRf+x^_0Vx9Euf=0$P8#_Ko$g~lWPGv5K!II0jU-sV~B%r1_Z=60h|i~#dikW1_7m+ z1Xu(C@ey7pX%kBdwgtj?*yn-vy*!41;xqtGwSqbU-xIJHf&tHhy%I^@CbypKvx6SKu81{?I%b3 ztQw$R2+>|WL?cA|?+}d;?XyEPLbQJk(FoE0G(;mrd(#k&5bY5|G(xmL4ABVDzAr>0 zMEkH1jS%g5LNr3OrwP#r(S9RDBSial5RGsfNuzx_MI?>=_6K{6;2agEMpA%ofB?OI z!r*Za;}!5%0VV>j24n-40+s;6v;*x|iUa8NBlht$4Zs%@f@qXpQF$cT4&Y1uhEM$s zAO8&>RJhNNNFT(Bbvg^6+nerR%sc^Xt#J1tyr2rs_qsmLT>$G8=s6$bA%N}ZImFPr z5mE$u7%76fa6r6G$py3I?M1MGeF^rk_rM1JS^^>N z0#bUoY33X0?1PNV#>Yp zaeF6q3@R=I+pitGZ)C$8S+H$0ds=f zECJDP3hZ5>@MPHg&2K%@LDv!Q8$&tbkedZuNn9HTM_@IfYhQkgaLYh?2 z1peFgs2K5HJzc1a5>IQ8Pbqqb9(q3;s_9?7s!w(x4OD*g-Z#|eke*W^gu&lX9?t`g z(DwxC5YGonMum1jH9_C7q{C4Nk0SIL9ix7UdISHhbK;QU6gUp$^+kHGTP!@~j2}-eZW$<^!n)L#k*ORPX$H(nRmHLwO?(dUst6?=6AT{_R}R_ujl= z*A+isRNH}aMtLBsgk&;M&YEx*y*Dlt(n8;I3xF@O@ypjcMP#4Q7aoyz6K`w$E7DXW zbpgE%5xut&Nj8j^8(}AicR(Tzlb1ItEqX_!FYhmsC+e$2EPm~XRkBDB-JM{=&`kKF_-&elBrWg(Bpc+siwf>q+ z=ohLp`o1NDm%8pRssBDTLLz94^MFz#jfagZP!sg#PS_O!N2tFMe6$mg&<6f_Bq#lU zBPXPJNIFC>M3Nyi5VaL*4Fv*<0Fe@%xVd6-f3PQSlhKvo8Q zyAidjAEZmv7ajHFhRSL9OF9Evq5s{||0?7(K{dHdDm)an! zjM5{digX%%k&>_ge?>M(&VT)<2eTdis7tguU*?1bBIZ?ub>jEj-gXJ;PLJJ1Jp~;_ zKpoIHi*%KsP^; z<@IYH`s;ZSZ{$UiK&hBPA4fBL24L?It^e52V^fi~BD;gigk*{A4l&5jujKds{$)TjZDiAl*(=Hc<@KxmB2rX?SzQ3s%$HXR ze))Rmf_S~hThz;m^#3f~*^n+VgW~HxvX_MIB4%5}9gqjq9Lb<(Y#`*o@Atp zq=;&WMnE)ELpAPgNBL#!naiPeG=dp5VKe#C`FHeb;MqW5Y4_wv$QZKy|KI;h;8zKF z!g?EUN>VFQD^sgeu{6;%sWiDXJk2o8B#oWP&4iQT@GK30h*6u`0G^7ish!<%scEWY zeCsraG`BR*H2<{lw3xKGw8XTew3IY<8aJ&dtt71?tun1Ttv0P8ttqWFtuqZv7fqK+ zr>3i>`p6UMS;ps8yap{TaN$Dx+>~wB=QF=*wMS5j=b$V@jLwZws zYkFromLZxUl_8fw%}~w2GYm6KGORNkGTbseGyF5cGh#BJz;UqlOo8WH95;?9$Db3< ziQ&X?5;;kn6b_ri~TfTpOOnzd1NAhHoqyqGhehou0XZGu)w;&t-!w^rXaB(rGQ&dQczh? zThLU{Ss+>{SEyQOSZH17R_I?CQ_6ECg93fgs?&C|i!L$~I(M zv)$PK>=wCQ{7ViQ)5ySQ&Up8sU@I0wV)N9siL4es-Qd8pa=e-1BuZ7Txk1BX!j;)bJ27; zXm3MkYd2`;7--`ZXx|cO+gfPX&U8^|QB`P7YiLP-XvM^glnic0Nk(NxZAMc@XNG8| zT&8NKVWxGaTc&?zOlD$c3g~D_W@Tn=W>aQorf8O2mTHz^mUWg}mVZ`ER$^947B>s( z&xUnpsDCwRUn^)H(mNb<&H?l-9CR%S^sESUtQz#I6?97q^a=-^asYh_&xp%N%3x;{ zWmIHTXEbEAW?-38nbb@?(XBTBxWLIZ5WVdExIZ`>)96ZM)$05fvCp;%ECn<-WQ@m!N!hg{Fx@Z7lEq+E7xQEo+Ub#6m$Yc7^2l}F9P^Gxy_@;vjx z^WyT7^4NJrc@=rpc@253d04(wJ~bcDH_3O%_skE^kIPTWXXh8?SL9dcH{`eGV+B$L z)B?P~q`;xTvmm@6t{|y^T~Jg|QBYmbP|#X{6-pIS3-LmeLWe@n!tlbl!lXiWVNqd4 zVRd0cVJp(dBD6||+C_>@W#eoUwgcOf9nOwpC$ZV=B6bD4n%%%|Wn&yE4wZv*OgIkE zhr^-&CPCjVf__^KeYTZ@r9v9j@LUF<7HZZBb#owlSse7UBHRYQ+! zfIim>y$;J4g?h?CO;w?;hEQ8;sIME;*dOW~1GP?sdZ$3mxls2KsC^~WzZN9W1TyFZ zDTsm`yQYoSl7rkX&1 zbb!8?l*&%6O~<&RpkH#JVXB~GhM;BETsP1&f6%lT(6vO+Hb{c^V^0Twy}meWda{Vv zUEvaa53{$dNV)8O4AzZ9R|2tyH~c_k8@CnO>xFwco5gAWsd15p`qSFZ?v z*n`Ln3#Ccnl88A-W{@M@CnPM?hc*@;gE-p72h;%PWBy+XpN4(6u#*pWkM`nVBpKr_%Y)YDr4hlafl@%W>EOUZ`d5~ySn zGD3E992{vA@d?D?*iiF;aDO_3YT;x_wREzdVxVnkp<%A8XQg3fWNAj5fGZO<8Z%&x zoal_G0B<_ZqKxY;VTv#&$f67dg`kKFuqf~ZDg2P+qKrMqN;_5hJ_Rd&7_W6xR+l5NV9s*D$QTZF@`tMK>wgVXcP%Xf!2_MG*su2;&MMQUysN zS)t*+9W`SX$Xunp7MK{k+i%~KtkFlV@^nZ+Sx63-jT^44+xfuJDqOt96nufb4_a8YT_o~p>l2S88{HXuCC>d?~l>4*uJfBZ_ zyn5Mtp@%vve~!%e4Ov!kWS;2G(T~n^i|2ZeICLX$?oiT;VwU_2BCQu#iWna z@Yuh_SSaI4M5mYU))p{xK6I*6fL|yW$6kiakY=cj)4-S^LuNpu;o9UO9>3;qDO(>y zMp|US-&o{-X_y|)-t<~9(4%tnB5`4(=XWJ{R9}3$sVRMk@F=&6Y4;~R-f+@CboSv@ zrTfa96O6Jy80yKsRLJ{U5cEh4e_t}TKDcw%zIl7BE0s4Koj*~xY!_|jfuT1{^t26r zyl$V9E}wohwlr@4jPWTKZ-w1m{mOjH^G9tpFAIEIgr+DZXSzNTe5ihT^iMS-?xON} zKOWoEI}0c0>eQ#Nq-ENbx!jbc`OjDzG$y3|-Cca+JNoEDCq>6hTD7yRZKYY1;kY}? zS9~lvwe--13IT`#)6uC|X49ZsTAly3pA4Qskub4=Eaa>YPXM^^Tf?LKiu+yzBY6qm{N|Sw1AIi+V*knJVc(1U9y}XT$dS2|i z@^y38hR%F{wzg)IO@QR2HJ>ud(nc%gr)Eq~q8|8kSlW2m{79eob!qF?YQu|R0)3(> znMNr`-=(VB1m}&{R-Mk>n%X zd`7MIv~Rq4)yZD*>w@h=7G58}W<^BP6|-n*51PuAq8m;dy_`GFZ(;2HaOs4?s+^>? zLR0p{=6m8S;ZiVo>4d=(_tH_3=S?VSeT0R3@MdV@Vmnke>}*r_p^TChgwc&Q3QZh) zF~zzEKbi)vh7?awW_*tga|{cE`5FvX0lop=@PY!WX(ZD>3|^G;hySFZ{a16VBaHd(qi~;cg?*k>s@dKsr{L+M?}b%e`|u{{#~xX!hWaVY zHS#C5*xJoMpPV4yyY;q5fcG;?0~0 zi`DnzAGVjZ>8D?Dw|rEXZ``2jzeheRgAw8KVPx|2?|R7$_Pr>NvC)=m))~rHM=TUR z?dP~9<4Ay3-6)A4JD8IiqqLkK569+gzrd%MB@FZ5Zk_;|vVFfrv%jsfao5unEmSmw0SS`B)iOa-2FDA%*oBUMVY1jPc>9_-7%WQBkpKNosX~K-Z zZp*s$odK%t4VulfV$OW41y;-&x56#>$6&<_|C$verjV$^p#B1>_P1XG;FM-GeYJ{J z;oC5iV(sIBZzZ)txi%edJtA9dr)u0c&zJad?X?CiO}T1?LrR>|qC8_Q+taCBmjlnj z&y*bNj6H6{=$QV-boJGzgGUBj%Q!&Q_#)wO(dD|vvspEz;jg$uQUxWAY${wnqET&77-EG8xs_zY+*}^-7qGO@^7vR+aEGNG`YnBz%=5Pa zud-9s&sM5QNz%9OefTN$i?oUu-7xvXGR0YEZasBrs*c$$=YB;`*5mO`1)HrJXY+L} z#=MgnA&)J3thZ3*z@776fo)aP|V{g1-lJx<`t@hxn=bFRQTz9yxOy0sCZ7sN< z<7S$lI5R`PMMG<3rs=>y~f5Lv_2DmN`23$`EH$wKC#yix((cwRLzyGhS z_hC+Oas5N<9g|lCX^whY*7)qw-nq&S`8OWR*^eLk?pD?<+k7TY9rkw6UFTgRY?4Qt z?I=ib$5raEpr++z%^L;{?T{2oY28qzcui;g`h#sB{l=(&TmC9h;ms@iG|o9?r>k4O zSl$$?UR+pRWG0l_l^ML#@4o6IE2pA_>KCe3niKO9=FD>({9I7|YhY3m9=g7LK7R1a zs(X8mHYx2{)mbCcE_%`_#POJA(qU_C)=b}F6DRp{_dLHX5r{EyE4wJ&IT24MuwmNfB!})OG*cekY1@2o$w-UHqV|6;wRx{WYcZ?NYW9-o42tFlmh5+1)LZumgvm*bu8 z^|wziSW>b1vYc7$jC|V&w~vElH0l2_R{t;EyMwHy_H4Z1E@+|u`1P^;=!Z9A=h{(< zHJM8nh76X;y>WK=wi3-d(y5z6mXx>(T(hUjIP87A%%suvOrhJpF;5jJ33+E?+BQ`; zPo=zTJiAR?xN?hiW2@7M$8&ObJb$$%@NV3>m&t7+TI&Q~Z=XDVT=>_|-=4?p)g00> zs4=`$&i>%mAaTa75{}UUKaERsCEqM@pCOyFi8`Zkki2$R6>U}&%~*{gQTZm^_~$xt znfmkMURzu5myCRCziIU)J+;MYYpVJyHSyMMW<38mClk{#xzznUB_0>UV0j<7`zXTaWix@W$nR=99e#uTBXoi=W688TKwpseC`{ z+(hRS#ev2fI8k25LOC*-zEllv1fBUVQ^sGL!2ST!B4Lip8L=m|4Q%^Lx`*B(OR6FI|-&+JxL6P#a>;ue4HG(`XI*xSr;V5u1YusS(d8fvz`JH}T(a{_qoU5M6@{c(_^~(6#igjD%#vGj=_u74f zhK1c_jimbh+djGtAH9?IC@5l#Fg0VjecO;VlJ)k@2L*l$iFQjxA$MdTXlh8=IUzx=sC{pR6aEpA)Vu6(=uO~b7TpYFe5 zlGllnThsEUFMiXwUF|-`x?MNh$IbWCd>zL!tve%T-zuN*p*X0d#xkk(kBQpN3x%df zJqY%-rDhsV>6*JXBS5kJ7{e)}=HjZ*MeV7VL*8tftv2uCX}$Rqmj*bUTei&N=82(- z52_D(6x&Q(r?mgYhr{K8U#E;d?Qm?>EuYLpQKqPq@L`uY%k#cRN5|@)eZO*ZP3~y{ zZAmL{y zXr=_eklKFSh86UF!d55u6Uk48Ju7Ru8KR`*i?hay^>jla3XP@Qg|n1Db;}w(o>G1Z ztVYls+E64y&jf1x*P7^b1^)kLQ6rveMH4utmt*E5H(VKp+fy&qc1j*LdwVY zgq^(|aD6&gZ_36`M|UO2gl&Rsogz1Y_E+tXd;J+7jsY4Bo!-mNMD zMOyW@tf#8tDlkWabrQv%b&|eoy;N8qqY+Q8Xf&DuEb$s?(}*Wm+TDl$Aq&3M>+hJU ztvdMN^0GUr7oLsSQR8%Q*T^f5`d^&ObEOJjUwKuf;&kDBM0v

;?Adb)cUv{#kb9 zF-pd+6`M|_tH0bdHTJXe;Mi^Lj`b##G3PG}9(+6hX2k2-rAGT(Z%ml4QFCRX`1@7& zv?UiYrG=Ug2{~m33HWu|&EFK=pr+LDz9QXH`ljG=!OKP$?u>gh&pq1g=YbDZn@w7kD9vm-By&sUoH^rz4)73d9UTjh?<TpEDX{DJkG}?dIu#Zk!FvJ*>fOCGi}cw8{n5Y;G;l-SqKOy3*05+Y z4|l@n@{eKBgulA{`waL`!2To)Cd?)HYf}O^)~9<5vS1Qzu|Xg&z^VP>i8FULdpfXsrz5lYI+FRiXD(Q zuUp#k{K2c#I;Q%_{1=0d%YAYdyK{C-#C7WO^e>eUYadQ2_>y!ft!x*)z)Hh)lH0u< zt-*EPAGYbFt}={T{J34OC2!xV*NC3I>zrWYjw`2fYh1;1 z9yv;Ax=c)KOxfeQwKRKv==dF5S&d>5tOt5)st&KdCA2lMq;cOGx1u}yUedlK&)m8) zv(Y}bz4msXj;urY2eUINVy}Nz?V7hxw0wsnSM=hCrVl?&?sx6eKluH0(z=>?(;f1y z6yHx6TykiNwUGDwn3U8-f^Q5HNt@oyOnV9lEt3?}sq2ESi4?->?ou=WDa0riZC zl^1>9Ar0IbVCChX9=2El{aq6TkZXbfxF$fK%WeI_kQ$?zUmKdklCsl1-FCuF>9E=8 z$w99dIOLRw7|ILToL+rl@Yu%&L6@a#C0Y&7?-ePkG`dR}PBXi`VMwgc`c=uEhMZ-~M4wGI ze*g8E+5#y>I~Uc|WsC;tDJN|f*S55nZ(s9Z`H|%bqaRE!-n^)3!<@D9Z5*xn&y%KV z6zI5JIywD^_U)sB#>GbpcNng!IT)w@$=+qVlHP<1Mxj2dolYMZnmU0^J0V7wY%Uv9Pc();scTpzC4(rjmgXXS3KZ(ew~@Y~}e-^O!$;+MDF zYnlDZW>S`nYG&3-zqpqhm&AA+(OP@o^?-YMw5sZdmXHgo+tjz27|c2Mbe+Y9i((2$C`$E5krF(e7)jimG;5r`K+PuMTF@JD_!OjtP!0q|RFxZ*>wI>9B zl0FlUKa2`b6^h@3$0y_Q+q+lhGzDRvh|l0>CqR+a`LpcM;Ozt7O#%OvfDm}?yLWhm zravO;zZ%Th;?^vBTijn%H52eDcvQOXT0r-y^9>Rp?_-d84miTS7)k zgLACB=IvUh-?;q}yN5mX-m%wg_sW{s!Aa-n9-8XYJ1;P9g{=8;c1Dx<)v4t(v(wrG z9(tFL)63Yih`u&yQGRvt$BCU!)TdAbQjW~u;2#>6b&`3( zL|7z~GFf#xYle)SuSCUByH8KItsWCLVx?tP)C-fz^t20$9G4_qQ1I5@lTcsR-q|M0 z**Ed&^^85$?-qHRK3h2G!20PT(IU4*iX#<=pY`%O-umeBXrZ(9rhiDPzI#H~YTomi z;(*qZ=rZB)gVXs?FcKii!TomUoNsSVs!Lm2y zzrVbt)qQ&`CPW)2M0KSM^IBK7>`2$nuM;<(Y&n)PRA@))OuId23dFsBF5ss9ZA)El z&)OmuGsh~-zG7D2FnjyN>6=$>JUC7|5YLWayu5h7$Vysuj^t#a%8i^7*CE^LQtVR0 zXe%Q2w@np&P20Vyl3ss!h>n7#&QtGwsaJO?Ua)&8yjpyM5$j+~*T|Bn_@&$q(sxe0>BG3M~ay>S$)$i4$XHQZ#irMI{ zExQ}>{`13orKjhXV2h?)%$9i1_N;oC8zSlD@b255A$!kqU_tKPJn^CvC%R%CxO+7} znQG)n2henC{TwC^{aO(6sWWr5vr?>di2Nh*t<)7ll$M;^XBw#i!=~R{+&n1y&aO>w zpS4y{H*#1qvv8J-Rrg()pdc(^$mj!4ySt6h5{8U2uoML-g8i2;SQKLs3BGDb!72ue zq7F+#sxZ!t2Q49!UOQi0kOJ;6zpj4>Q6D(CN2ovGCf+{6it@_17XA2k+WXr9Dk?X= zE;xBIIxcKoUI_!IxUQ>%rxrG}1y zp|*w@Ze{Qnom$x}$?LF6vlP7Y=JO}yV)2uC6LNt*vKYYqHjTH02#-Sb zU_uUuy1W&|6@SaEg9<*LxOGtIxpnx}^%>nR;Glf{r{ldng|iigltvHRIEC8$O=i!h zFRKHRgP6`zcQeE>*1E4PEBt4xdtAEk!s~q0$?3jo3tLAxO%$RjnvRy=rEo(`X6p(s ze10)*G4z9H;#z0(!T0S-3`LKcJ>HpjF9LT}VWn9PsebcmX8iT?@t)dlo>pycGZVDe zj%9lJZTEuWX~4oypu=Ll1~d_gnqRw?c5Y#j5w!v%iPF*mt#<+qP`7IIXqLUS#`; zL{Yt_m@!4K_g&6|cIZ=m>Hc>E4Le%miI(Rkdrdm>2z zcT2*Hy8kMV!)zO38fxy~qy-;1K%WWv3-eHiU*@4se{~)@=w;&EA&r+CQf9<26*NAW z#!(78`Zlxb6YcCx;l}JAUtB{*;YZJ3^1TvR|LIk0OxYjYLld5Lm9_*qyNasKWm!mn zJ>|5y>Z7Oh#;7V26Vv^V+(-U&?^--kFJ-*TZ0372smj9g)t6Vd8LV6|V@%uL*jd{h zu|mV4BR^@y#?v2U9}jx|$BoZdmtkSEaf|Werrm52%-Fqc{-n|q--VurAJ(2V@%y|& ztsf^|Y}Gll#ADw>SCiKtZtV3<+Wa$c$?C_KW=U*UX*6mcHEXH&!R1OJ7Y?MQPW!TY zr_jMvmfq0l4X{9 z<>n|;yM~0W$@|iV`Qo?FFtumbdoTaAcca$mKa>jRA1`=hF>Q~-()*m6OY@!uJaIjD z>j_@*z3Qdi*CFML=Da>Qc9fx3=}k9b&G$pt4tjO(#U_rqdvulFSkcpU`VVh=Y}-dkGqb&>B)_m&oP_@6oY|I2|Y zlM*ew{K87fDF3p{+%=b3%PHa9qQJF`InG-{&iYXU&o*m3)|$EW>5lKrB|&GI57+5G z)UEs@K>Ve?w2jHk5>wszON>9rWEF@}RBsJ;^Hww}^4AxtonL3SuwnaB>2Ib-huk>F z;EYiD+`e~VQ^UprsmL6o`yV9R#Lm$o2Tz(j>2dQ`gUR(lInT69YVDR+E|p3;cXmp` zD2b-m`HCgF%K2WKcWZu~ZmVTRzbrAfxXA5%(Ee99Hwpc*)AZoW*pe3=yImi}U4o~D znWp0mWV?>NotdX)lwW=6_F#+qVhaOqiM0!=c~4w0DCy(-&1pIlwiu|-n6UR~`-th8 zJKl87m3wiQKTwSZNsa8~Wf^+r!MXEwvPCQM&pWMtRXtM1xYYHRHT?m{t^c7zH_S9( zFAH+$CPo)n)u;V$jV`}QyYF)TzjBm;M|eD+Z@s;)Av&L}4<0goRF&=d&V8n}^Dyy* zQ?4_zLQ=L~T@jEOxO>eFqa$TLl6&zpXCF00vVzPe!MfH~+VTkh`LQVnU608Q`j$GW zG%cK^q@qBdJ?iC#$@8ukp577oq;j8_z`_Z#d;Z8hwV>`}J9{)MJZIKrtK-Y!E-o=! z)3J1ckDAK&_N~ei_OflG+p6`%&FiMMXUlKjcu_CrffUzUB+X}aUb*T!?wAoV+t?lF zmtLwZ*>NLh55vfIsK1Ye{ndmQ8rO~p6ssD4A61Usv%XzFlwWWJwpeTA>!oXJw68VaUp#ASr~S$GuRpQl&*Sms>G7p_{HecX>fL9{ zMgP5h_Rdbcy?uHHR{9#|G)vfgp{Hw3Q^O|_Q}%JcPT8qWye}0}?cm#=urm<8ZRj1; zd&B{wAs~!By0ygwA161IfBT1S0&(31-3)z_fiv+bJ@=aMBwih#jEj>A!1_D7SA@-@ zN=hUluS1-zc~XJS>i4=0#vsC~-I>v;vj9lO<~ zO!KP*%${C)Blw86aJL@!kY;kmvKX7^l1?#_U5am~{g_quymsMJzo|=w{i^pn@4WI5 z>rDH$Ws}#%TM}2=&z~+@>L{OTptpYA9ix28>h&vk4!J4!cFenl!legJ&p&zkL|bOT zy;+6Jtg1I~S|zun?rN!hdZ#Y#+1VCt(XnZqp(2M>Z*X)5XPZ1Zc|U#nw8P{7uv*uQ z2}X{1V4df5vt1#gs($a78)^(m$SDR9{)M4Z)k+bFpUhWfFKlJ&Vlgo$6eoalLeQDZq z=(P5hN#HE=33}cKUeDW!|D%%zVs&ePX-)6dEfz%^m+xNg09UOczbt6reV40(RDzBi z&5=(k*#33@)7dvRXg!_g_^$KXplRxAZxX&q+2Zkyy%G=@OpC9<<8R{eRd{@{(C~r! zE_jgQ@p0*^{x1p(+|Syi%m0wAy)HK^D+FJiHf4vN*{*NBH6O+t@Cgo?caHb(PS3^%sXb1=|B#mfw4>;b2jw`*t&uV+%#c|Qw{YHS@lGSp2@Ij8TvJ?3meN7ai`Pe!v}N6Uf8 z?Yj$iUdc5!t4*0ZD|(*L(c!n+9O_COG{6yIX?N6%X8aBs@}EErYpv{Hsl}J__;9Q=^@kY^X4;ly(zh^)^f1R G_`d+o5e*vv From 3b18a071df23651ca9a007a3d441ce00171145ae Mon Sep 17 00:00:00 2001 From: "Stefan J. Wernli" Date: Tue, 9 Jun 2020 21:11:57 -0700 Subject: [PATCH 2/5] Switching to multiplatform usage of std::complex --- src/Simulation/Native/src/external/cintrin.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Simulation/Native/src/external/cintrin.hpp b/src/Simulation/Native/src/external/cintrin.hpp index 80323fe43f4..e400e8b20df 100644 --- a/src/Simulation/Native/src/external/cintrin.hpp +++ b/src/Simulation/Native/src/external/cintrin.hpp @@ -36,8 +36,8 @@ inline void permute_qubits_and_matrix(I *delta_list, unsigned n, M & matrix){ inline std::complex fma(std::complex const& c1, std::complex const& c2, std::complex const& a){ //@@@DBW: Expanded complex FMA to hard coded access (much faster) - double r = (c1._Val[0] * c2._Val[0] - c1._Val[1] * c2._Val[1]) + a._Val[0]; - double i = (c1._Val[0] * c2._Val[1] + c1._Val[1] * c2._Val[0]) + a._Val[1]; + double r = (c1.real() * c2.real() - c1.imag() * c2.imag()) + a.real(); + double i = (c1.real() * c2.imag() + c1.imag() * c2.real()) + a.imag(); return std::complex(r, i); } From 4fc81b71132a96f67e51d000208083c3790a2657 Mon Sep 17 00:00:00 2001 From: "Stefan J. Wernli" Date: Tue, 9 Jun 2020 21:24:46 -0700 Subject: [PATCH 3/5] Updating comments --- src/Simulation/Native/CMakeLists.txt | 1 - src/Simulation/Native/codegen/codegen_fma.py | 4 +--- src/Simulation/Native/src/external/avx/kernel1.hpp | 2 -- src/Simulation/Native/src/external/avx/kernel2.hpp | 2 -- src/Simulation/Native/src/external/avx/kernel3.hpp | 2 -- src/Simulation/Native/src/external/avx/kernel4.hpp | 2 -- src/Simulation/Native/src/external/avx/kernel5.hpp | 2 -- src/Simulation/Native/src/external/avx/kernel6.hpp | 2 -- src/Simulation/Native/src/external/avx/kernel7.hpp | 2 -- src/Simulation/Native/src/external/avx2/kernel1.hpp | 2 -- src/Simulation/Native/src/external/avx2/kernel2.hpp | 2 -- src/Simulation/Native/src/external/avx2/kernel3.hpp | 2 -- src/Simulation/Native/src/external/avx2/kernel4.hpp | 2 -- src/Simulation/Native/src/external/avx2/kernel5.hpp | 2 -- src/Simulation/Native/src/external/avx2/kernel6.hpp | 2 -- src/Simulation/Native/src/external/avx2/kernel7.hpp | 2 -- src/Simulation/Native/src/external/cintrin.hpp | 2 +- src/Simulation/Native/src/external/fused.hpp | 12 ++++++------ src/Simulation/Native/src/external/fusion.hpp | 2 +- .../Native/src/external/nointrin/kernel1.hpp | 2 -- .../Native/src/external/nointrin/kernel2.hpp | 2 -- .../Native/src/external/nointrin/kernel3.hpp | 2 -- .../Native/src/external/nointrin/kernel4.hpp | 2 -- .../Native/src/external/nointrin/kernel5.hpp | 2 -- .../Native/src/external/nointrin/kernel6.hpp | 2 -- .../Native/src/external/nointrin/kernel7.hpp | 2 -- src/Simulation/Native/src/simulator/kernels.hpp | 4 ++-- 27 files changed, 11 insertions(+), 56 deletions(-) diff --git a/src/Simulation/Native/CMakeLists.txt b/src/Simulation/Native/CMakeLists.txt index 80dbd645d8d..fd2d668f1c9 100644 --- a/src/Simulation/Native/CMakeLists.txt +++ b/src/Simulation/Native/CMakeLists.txt @@ -24,7 +24,6 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) ADD_DEFINITIONS(-D_SCL_SECURE_NO_WARNINGS) # Configuration options (choose one to turn on) -# @@@DBW: This should default to on option(BUILD_SHARED_LIBS "Build shared libraries" ON) option(ENABLE_OPENMP "Enable OpenMP Parallelization" ON) option(USE_SINGLE_PRECISION "Use single-precision floating point operations" OFF) diff --git a/src/Simulation/Native/codegen/codegen_fma.py b/src/Simulation/Native/codegen/codegen_fma.py index df55312f6c4..d54638b81ba 100644 --- a/src/Simulation/Native/codegen/codegen_fma.py +++ b/src/Simulation/Native/codegen/codegen_fma.py @@ -243,7 +243,6 @@ def generate_kernel(n, blocks, only_one_matrix, unroll_loops, avx_len): kernelarray.append("#ifndef _MSC_VER\n") kernelarray.append("\t"*indent + "if (ctrlmask == 0){\n") indent += 1 - kernelarray.append("\t"*indent + "//@@@DBW Was missing parallel directive\n") kernelarray.append("\t"*indent + "#pragma omp parallel for collapse(LOOP_COLLAPSE"+str(n)+") schedule(static)\n" + "\t"*indent + "for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){\n") indent = indent + 1 for i in range(1,nc+1): @@ -279,7 +278,6 @@ def generate_kernel(n, blocks, only_one_matrix, unroll_loops, avx_len): indent = 1 kernelarray.append("\t"*indent + "else{\n") indent += 1 - kernelarray.append("\t"*indent + "//@@@DBW Was missing parallel directive\n") kernelarray.append("\t"*indent + "#pragma omp parallel for collapse(LOOP_COLLAPSE"+str(n)+") schedule(static)\n" + "\t"*indent + "for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){\n") indent = indent + 1 for i in range(1,nc+1): @@ -317,7 +315,7 @@ def generate_kernel(n, blocks, only_one_matrix, unroll_loops, avx_len): kernelarray.append("".join(add)) -################ @@@DBW: Start of _MSC_VER code block ################## +################ Start of _MSC_VER code block ################## kernelarray.append("#else\n") kernelarray.append(" std::intptr_t zero = 0;\n") kernelarray.append(" std::intptr_t dmask = dsorted[0]"); diff --git a/src/Simulation/Native/src/external/avx/kernel1.hpp b/src/Simulation/Native/src/external/avx/kernel1.hpp index c10e4581a8f..2bdcb04aea3 100644 --- a/src/Simulation/Native/src/external/avx/kernel1.hpp +++ b/src/Simulation/Native/src/external/avx/kernel1.hpp @@ -49,7 +49,6 @@ void kernel(V& psi, unsigned id0, M const& matrix, std::size_t ctrlmask) #ifndef _MSC_VER if (ctrlmask == 0){ - //@@@DBW Was missing parallel directive #pragma omp parallel for collapse(LOOP_COLLAPSE1) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; ++i1){ @@ -58,7 +57,6 @@ void kernel(V& psi, unsigned id0, M const& matrix, std::size_t ctrlmask) } } else{ - //@@@DBW Was missing parallel directive #pragma omp parallel for collapse(LOOP_COLLAPSE1) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; ++i1){ diff --git a/src/Simulation/Native/src/external/avx/kernel2.hpp b/src/Simulation/Native/src/external/avx/kernel2.hpp index bc2d09cafa6..8012bf3638d 100644 --- a/src/Simulation/Native/src/external/avx/kernel2.hpp +++ b/src/Simulation/Native/src/external/avx/kernel2.hpp @@ -63,7 +63,6 @@ void kernel(V& psi, unsigned id1, unsigned id0, M const& matrix, std::size_t ctr #ifndef _MSC_VER if (ctrlmask == 0){ - //@@@DBW Was missing parallel directive #pragma omp parallel for collapse(LOOP_COLLAPSE2) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ @@ -74,7 +73,6 @@ void kernel(V& psi, unsigned id1, unsigned id0, M const& matrix, std::size_t ctr } } else{ - //@@@DBW Was missing parallel directive #pragma omp parallel for collapse(LOOP_COLLAPSE2) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ diff --git a/src/Simulation/Native/src/external/avx/kernel3.hpp b/src/Simulation/Native/src/external/avx/kernel3.hpp index 6970e8b3684..bc7037c6004 100644 --- a/src/Simulation/Native/src/external/avx/kernel3.hpp +++ b/src/Simulation/Native/src/external/avx/kernel3.hpp @@ -102,7 +102,6 @@ void kernel(V& psi, unsigned id2, unsigned id1, unsigned id0, M const& matrix, s #ifndef _MSC_VER if (ctrlmask == 0){ - //@@@DBW Was missing parallel directive #pragma omp parallel for collapse(LOOP_COLLAPSE3) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ @@ -115,7 +114,6 @@ void kernel(V& psi, unsigned id2, unsigned id1, unsigned id0, M const& matrix, s } } else{ - //@@@DBW Was missing parallel directive #pragma omp parallel for collapse(LOOP_COLLAPSE3) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ diff --git a/src/Simulation/Native/src/external/avx/kernel4.hpp b/src/Simulation/Native/src/external/avx/kernel4.hpp index 2c3ff29c724..e20a190af5c 100644 --- a/src/Simulation/Native/src/external/avx/kernel4.hpp +++ b/src/Simulation/Native/src/external/avx/kernel4.hpp @@ -227,7 +227,6 @@ void kernel(V& psi, unsigned id3, unsigned id2, unsigned id1, unsigned id0, M co #ifndef _MSC_VER if (ctrlmask == 0){ - //@@@DBW Was missing parallel directive #pragma omp parallel for collapse(LOOP_COLLAPSE4) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ @@ -242,7 +241,6 @@ void kernel(V& psi, unsigned id3, unsigned id2, unsigned id1, unsigned id0, M co } } else{ - //@@@DBW Was missing parallel directive #pragma omp parallel for collapse(LOOP_COLLAPSE4) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ diff --git a/src/Simulation/Native/src/external/avx/kernel5.hpp b/src/Simulation/Native/src/external/avx/kernel5.hpp index 99b462f45ec..8cf84656e68 100644 --- a/src/Simulation/Native/src/external/avx/kernel5.hpp +++ b/src/Simulation/Native/src/external/avx/kernel5.hpp @@ -380,7 +380,6 @@ void kernel(V& psi, unsigned id4, unsigned id3, unsigned id2, unsigned id1, unsi #ifndef _MSC_VER if (ctrlmask == 0){ - //@@@DBW Was missing parallel directive #pragma omp parallel for collapse(LOOP_COLLAPSE5) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ @@ -397,7 +396,6 @@ void kernel(V& psi, unsigned id4, unsigned id3, unsigned id2, unsigned id1, unsi } } else{ - //@@@DBW Was missing parallel directive #pragma omp parallel for collapse(LOOP_COLLAPSE5) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ diff --git a/src/Simulation/Native/src/external/avx/kernel6.hpp b/src/Simulation/Native/src/external/avx/kernel6.hpp index 4b2312853ee..087c4e83473 100644 --- a/src/Simulation/Native/src/external/avx/kernel6.hpp +++ b/src/Simulation/Native/src/external/avx/kernel6.hpp @@ -212,7 +212,6 @@ void kernel(V& psi, unsigned id5, unsigned id4, unsigned id3, unsigned id2, unsi #ifndef _MSC_VER if (ctrlmask == 0){ - //@@@DBW Was missing parallel directive #pragma omp parallel for collapse(LOOP_COLLAPSE6) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ @@ -231,7 +230,6 @@ void kernel(V& psi, unsigned id5, unsigned id4, unsigned id3, unsigned id2, unsi } } else{ - //@@@DBW Was missing parallel directive #pragma omp parallel for collapse(LOOP_COLLAPSE6) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ diff --git a/src/Simulation/Native/src/external/avx/kernel7.hpp b/src/Simulation/Native/src/external/avx/kernel7.hpp index 70e722552a3..197e800b208 100644 --- a/src/Simulation/Native/src/external/avx/kernel7.hpp +++ b/src/Simulation/Native/src/external/avx/kernel7.hpp @@ -389,7 +389,6 @@ void kernel(V& psi, unsigned id6, unsigned id5, unsigned id4, unsigned id3, unsi #ifndef _MSC_VER if (ctrlmask == 0){ - //@@@DBW Was missing parallel directive #pragma omp parallel for collapse(LOOP_COLLAPSE7) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ @@ -410,7 +409,6 @@ void kernel(V& psi, unsigned id6, unsigned id5, unsigned id4, unsigned id3, unsi } } else{ - //@@@DBW Was missing parallel directive #pragma omp parallel for collapse(LOOP_COLLAPSE7) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ diff --git a/src/Simulation/Native/src/external/avx2/kernel1.hpp b/src/Simulation/Native/src/external/avx2/kernel1.hpp index c10e4581a8f..2bdcb04aea3 100644 --- a/src/Simulation/Native/src/external/avx2/kernel1.hpp +++ b/src/Simulation/Native/src/external/avx2/kernel1.hpp @@ -49,7 +49,6 @@ void kernel(V& psi, unsigned id0, M const& matrix, std::size_t ctrlmask) #ifndef _MSC_VER if (ctrlmask == 0){ - //@@@DBW Was missing parallel directive #pragma omp parallel for collapse(LOOP_COLLAPSE1) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; ++i1){ @@ -58,7 +57,6 @@ void kernel(V& psi, unsigned id0, M const& matrix, std::size_t ctrlmask) } } else{ - //@@@DBW Was missing parallel directive #pragma omp parallel for collapse(LOOP_COLLAPSE1) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; ++i1){ diff --git a/src/Simulation/Native/src/external/avx2/kernel2.hpp b/src/Simulation/Native/src/external/avx2/kernel2.hpp index bc2d09cafa6..8012bf3638d 100644 --- a/src/Simulation/Native/src/external/avx2/kernel2.hpp +++ b/src/Simulation/Native/src/external/avx2/kernel2.hpp @@ -63,7 +63,6 @@ void kernel(V& psi, unsigned id1, unsigned id0, M const& matrix, std::size_t ctr #ifndef _MSC_VER if (ctrlmask == 0){ - //@@@DBW Was missing parallel directive #pragma omp parallel for collapse(LOOP_COLLAPSE2) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ @@ -74,7 +73,6 @@ void kernel(V& psi, unsigned id1, unsigned id0, M const& matrix, std::size_t ctr } } else{ - //@@@DBW Was missing parallel directive #pragma omp parallel for collapse(LOOP_COLLAPSE2) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ diff --git a/src/Simulation/Native/src/external/avx2/kernel3.hpp b/src/Simulation/Native/src/external/avx2/kernel3.hpp index 6970e8b3684..bc7037c6004 100644 --- a/src/Simulation/Native/src/external/avx2/kernel3.hpp +++ b/src/Simulation/Native/src/external/avx2/kernel3.hpp @@ -102,7 +102,6 @@ void kernel(V& psi, unsigned id2, unsigned id1, unsigned id0, M const& matrix, s #ifndef _MSC_VER if (ctrlmask == 0){ - //@@@DBW Was missing parallel directive #pragma omp parallel for collapse(LOOP_COLLAPSE3) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ @@ -115,7 +114,6 @@ void kernel(V& psi, unsigned id2, unsigned id1, unsigned id0, M const& matrix, s } } else{ - //@@@DBW Was missing parallel directive #pragma omp parallel for collapse(LOOP_COLLAPSE3) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ diff --git a/src/Simulation/Native/src/external/avx2/kernel4.hpp b/src/Simulation/Native/src/external/avx2/kernel4.hpp index 2c3ff29c724..e20a190af5c 100644 --- a/src/Simulation/Native/src/external/avx2/kernel4.hpp +++ b/src/Simulation/Native/src/external/avx2/kernel4.hpp @@ -227,7 +227,6 @@ void kernel(V& psi, unsigned id3, unsigned id2, unsigned id1, unsigned id0, M co #ifndef _MSC_VER if (ctrlmask == 0){ - //@@@DBW Was missing parallel directive #pragma omp parallel for collapse(LOOP_COLLAPSE4) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ @@ -242,7 +241,6 @@ void kernel(V& psi, unsigned id3, unsigned id2, unsigned id1, unsigned id0, M co } } else{ - //@@@DBW Was missing parallel directive #pragma omp parallel for collapse(LOOP_COLLAPSE4) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ diff --git a/src/Simulation/Native/src/external/avx2/kernel5.hpp b/src/Simulation/Native/src/external/avx2/kernel5.hpp index 99b462f45ec..8cf84656e68 100644 --- a/src/Simulation/Native/src/external/avx2/kernel5.hpp +++ b/src/Simulation/Native/src/external/avx2/kernel5.hpp @@ -380,7 +380,6 @@ void kernel(V& psi, unsigned id4, unsigned id3, unsigned id2, unsigned id1, unsi #ifndef _MSC_VER if (ctrlmask == 0){ - //@@@DBW Was missing parallel directive #pragma omp parallel for collapse(LOOP_COLLAPSE5) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ @@ -397,7 +396,6 @@ void kernel(V& psi, unsigned id4, unsigned id3, unsigned id2, unsigned id1, unsi } } else{ - //@@@DBW Was missing parallel directive #pragma omp parallel for collapse(LOOP_COLLAPSE5) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ diff --git a/src/Simulation/Native/src/external/avx2/kernel6.hpp b/src/Simulation/Native/src/external/avx2/kernel6.hpp index 4b2312853ee..087c4e83473 100644 --- a/src/Simulation/Native/src/external/avx2/kernel6.hpp +++ b/src/Simulation/Native/src/external/avx2/kernel6.hpp @@ -212,7 +212,6 @@ void kernel(V& psi, unsigned id5, unsigned id4, unsigned id3, unsigned id2, unsi #ifndef _MSC_VER if (ctrlmask == 0){ - //@@@DBW Was missing parallel directive #pragma omp parallel for collapse(LOOP_COLLAPSE6) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ @@ -231,7 +230,6 @@ void kernel(V& psi, unsigned id5, unsigned id4, unsigned id3, unsigned id2, unsi } } else{ - //@@@DBW Was missing parallel directive #pragma omp parallel for collapse(LOOP_COLLAPSE6) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ diff --git a/src/Simulation/Native/src/external/avx2/kernel7.hpp b/src/Simulation/Native/src/external/avx2/kernel7.hpp index 70e722552a3..197e800b208 100644 --- a/src/Simulation/Native/src/external/avx2/kernel7.hpp +++ b/src/Simulation/Native/src/external/avx2/kernel7.hpp @@ -389,7 +389,6 @@ void kernel(V& psi, unsigned id6, unsigned id5, unsigned id4, unsigned id3, unsi #ifndef _MSC_VER if (ctrlmask == 0){ - //@@@DBW Was missing parallel directive #pragma omp parallel for collapse(LOOP_COLLAPSE7) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ @@ -410,7 +409,6 @@ void kernel(V& psi, unsigned id6, unsigned id5, unsigned id4, unsigned id3, unsi } } else{ - //@@@DBW Was missing parallel directive #pragma omp parallel for collapse(LOOP_COLLAPSE7) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ diff --git a/src/Simulation/Native/src/external/cintrin.hpp b/src/Simulation/Native/src/external/cintrin.hpp index e400e8b20df..b0eab16a79c 100644 --- a/src/Simulation/Native/src/external/cintrin.hpp +++ b/src/Simulation/Native/src/external/cintrin.hpp @@ -35,7 +35,7 @@ inline void permute_qubits_and_matrix(I *delta_list, unsigned n, M & matrix){ } inline std::complex fma(std::complex const& c1, std::complex const& c2, std::complex const& a){ - //@@@DBW: Expanded complex FMA to hard coded access (much faster) + // Expanded complex FMA to hard coded access (much faster) double r = (c1.real() * c2.real() - c1.imag() * c2.imag()) + a.real(); double i = (c1.real() * c2.imag() + c1.imag() * c2.real()) + a.imag(); return std::complex(r, i); diff --git a/src/Simulation/Native/src/external/fused.hpp b/src/Simulation/Native/src/external/fused.hpp index 4a18ba7b5ae..235cf8ed15c 100644 --- a/src/Simulation/Native/src/external/fused.hpp +++ b/src/Simulation/Native/src/external/fused.hpp @@ -15,7 +15,7 @@ #ifdef HAVE_FMA #include "external/avx2/kernels.hpp" #else -#include "external/avx/kernels.hpp" //@@@DBW: This was mistakenly avx2 +#include "external/avx/kernels.hpp" #endif #endif #endif @@ -31,9 +31,9 @@ class Fused { public: Fused() { - wfnCapacity = 0u; //@@@DBW used to optimize runtime parameters - maxFusedSpan =-1; //@@@DBW determine span to use at runtime - maxFusedDepth = 99; //@@@DBW determine max depth to use at runtime + wfnCapacity = 0u; // used to optimize runtime parameters + maxFusedSpan =-1; // determine span to use at runtime + maxFusedDepth = 99; // determine max depth to use at runtime } inline void reset() @@ -102,7 +102,7 @@ class Fused template void apply_controlled(std::vector& wfn, M const& mat, std::vector const& cs, unsigned q) { - //@@@DBW Major runtime logic change here + // Major runtime logic change here // Have to update capacity as the WFN grows if (wfnCapacity != wfn.capacity()) { @@ -147,7 +147,7 @@ class Fused private: mutable Fusion fusedgates; - //@@@DBW: New runtime optimizatin settings + //: New runtime optimizatin settings mutable size_t wfnCapacity; mutable int maxFusedSpan; mutable int maxFusedDepth; diff --git a/src/Simulation/Native/src/external/fusion.hpp b/src/Simulation/Native/src/external/fusion.hpp index ccfcb62e6d9..f3224f79212 100644 --- a/src/Simulation/Native/src/external/fusion.hpp +++ b/src/Simulation/Native/src/external/fusion.hpp @@ -59,7 +59,7 @@ class Fusion{ } - //@@@DBW: This saves a class instance create/destroy on every gate insert + // This saves a class instance create/destroy on every gate insert // Need a quick way to decide if we're going to grow too wide int predict(IndexVector index_list, IndexVector const& ctrl_list = {}) { int cnt = num_qubits() + num_controls(); diff --git a/src/Simulation/Native/src/external/nointrin/kernel1.hpp b/src/Simulation/Native/src/external/nointrin/kernel1.hpp index c479348a552..53840cd0904 100644 --- a/src/Simulation/Native/src/external/nointrin/kernel1.hpp +++ b/src/Simulation/Native/src/external/nointrin/kernel1.hpp @@ -43,7 +43,6 @@ void kernel(V& psi, unsigned id0, M const& matrix, std::size_t ctrlmask) #ifndef _MSC_VER if (ctrlmask == 0){ - //@@@DBW Was missing parallel directive #pragma omp parallel for collapse(LOOP_COLLAPSE1) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; ++i1){ @@ -52,7 +51,6 @@ void kernel(V& psi, unsigned id0, M const& matrix, std::size_t ctrlmask) } } else{ - //@@@DBW Was missing parallel directive #pragma omp parallel for collapse(LOOP_COLLAPSE1) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; ++i1){ diff --git a/src/Simulation/Native/src/external/nointrin/kernel2.hpp b/src/Simulation/Native/src/external/nointrin/kernel2.hpp index 14b4a2393b4..7ad58accb47 100644 --- a/src/Simulation/Native/src/external/nointrin/kernel2.hpp +++ b/src/Simulation/Native/src/external/nointrin/kernel2.hpp @@ -64,7 +64,6 @@ void kernel(V& psi, unsigned id1, unsigned id0, M const& matrix, std::size_t ctr #ifndef _MSC_VER if (ctrlmask == 0){ - //@@@DBW Was missing parallel directive #pragma omp parallel for collapse(LOOP_COLLAPSE2) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ @@ -75,7 +74,6 @@ void kernel(V& psi, unsigned id1, unsigned id0, M const& matrix, std::size_t ctr } } else{ - //@@@DBW Was missing parallel directive #pragma omp parallel for collapse(LOOP_COLLAPSE2) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ diff --git a/src/Simulation/Native/src/external/nointrin/kernel3.hpp b/src/Simulation/Native/src/external/nointrin/kernel3.hpp index 78a6b91273f..6b714eb0df8 100644 --- a/src/Simulation/Native/src/external/nointrin/kernel3.hpp +++ b/src/Simulation/Native/src/external/nointrin/kernel3.hpp @@ -129,7 +129,6 @@ void kernel(V& psi, unsigned id2, unsigned id1, unsigned id0, M const& matrix, s #ifndef _MSC_VER if (ctrlmask == 0){ - //@@@DBW Was missing parallel directive #pragma omp parallel for collapse(LOOP_COLLAPSE3) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ @@ -142,7 +141,6 @@ void kernel(V& psi, unsigned id2, unsigned id1, unsigned id0, M const& matrix, s } } else{ - //@@@DBW Was missing parallel directive #pragma omp parallel for collapse(LOOP_COLLAPSE3) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ diff --git a/src/Simulation/Native/src/external/nointrin/kernel4.hpp b/src/Simulation/Native/src/external/nointrin/kernel4.hpp index c48470bed0a..f8b38ec3a92 100644 --- a/src/Simulation/Native/src/external/nointrin/kernel4.hpp +++ b/src/Simulation/Native/src/external/nointrin/kernel4.hpp @@ -354,7 +354,6 @@ void kernel(V& psi, unsigned id3, unsigned id2, unsigned id1, unsigned id0, M co #ifndef _MSC_VER if (ctrlmask == 0){ - //@@@DBW Was missing parallel directive #pragma omp parallel for collapse(LOOP_COLLAPSE4) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ @@ -369,7 +368,6 @@ void kernel(V& psi, unsigned id3, unsigned id2, unsigned id1, unsigned id0, M co } } else{ - //@@@DBW Was missing parallel directive #pragma omp parallel for collapse(LOOP_COLLAPSE4) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ diff --git a/src/Simulation/Native/src/external/nointrin/kernel5.hpp b/src/Simulation/Native/src/external/nointrin/kernel5.hpp index 9c36553492a..59094e29042 100644 --- a/src/Simulation/Native/src/external/nointrin/kernel5.hpp +++ b/src/Simulation/Native/src/external/nointrin/kernel5.hpp @@ -643,7 +643,6 @@ void kernel(V& psi, unsigned id4, unsigned id3, unsigned id2, unsigned id1, unsi #ifndef _MSC_VER if (ctrlmask == 0){ - //@@@DBW Was missing parallel directive #pragma omp parallel for collapse(LOOP_COLLAPSE5) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ @@ -660,7 +659,6 @@ void kernel(V& psi, unsigned id4, unsigned id3, unsigned id2, unsigned id1, unsi } } else{ - //@@@DBW Was missing parallel directive #pragma omp parallel for collapse(LOOP_COLLAPSE5) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ diff --git a/src/Simulation/Native/src/external/nointrin/kernel6.hpp b/src/Simulation/Native/src/external/nointrin/kernel6.hpp index 222b7de1648..0fe55f34878 100644 --- a/src/Simulation/Native/src/external/nointrin/kernel6.hpp +++ b/src/Simulation/Native/src/external/nointrin/kernel6.hpp @@ -244,7 +244,6 @@ void kernel(V& psi, unsigned id5, unsigned id4, unsigned id3, unsigned id2, unsi #ifndef _MSC_VER if (ctrlmask == 0){ - //@@@DBW Was missing parallel directive #pragma omp parallel for collapse(LOOP_COLLAPSE6) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ @@ -263,7 +262,6 @@ void kernel(V& psi, unsigned id5, unsigned id4, unsigned id3, unsigned id2, unsi } } else{ - //@@@DBW Was missing parallel directive #pragma omp parallel for collapse(LOOP_COLLAPSE6) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ diff --git a/src/Simulation/Native/src/external/nointrin/kernel7.hpp b/src/Simulation/Native/src/external/nointrin/kernel7.hpp index 82f26c1ba3b..2a3809b134f 100644 --- a/src/Simulation/Native/src/external/nointrin/kernel7.hpp +++ b/src/Simulation/Native/src/external/nointrin/kernel7.hpp @@ -453,7 +453,6 @@ void kernel(V& psi, unsigned id6, unsigned id5, unsigned id4, unsigned id3, unsi #ifndef _MSC_VER if (ctrlmask == 0){ - //@@@DBW Was missing parallel directive #pragma omp parallel for collapse(LOOP_COLLAPSE7) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ @@ -474,7 +473,6 @@ void kernel(V& psi, unsigned id6, unsigned id5, unsigned id4, unsigned id3, unsi } } else{ - //@@@DBW Was missing parallel directive #pragma omp parallel for collapse(LOOP_COLLAPSE7) schedule(static) for (std::size_t i0 = 0; i0 < n; i0 += 2 * dsorted[0]){ for (std::size_t i1 = 0; i1 < dsorted[0]; i1 += 2 * dsorted[1]){ diff --git a/src/Simulation/Native/src/simulator/kernels.hpp b/src/Simulation/Native/src/simulator/kernels.hpp index a8e0cf6aaaf..13f49fe14ef 100644 --- a/src/Simulation/Native/src/simulator/kernels.hpp +++ b/src/Simulation/Native/src/simulator/kernels.hpp @@ -398,7 +398,7 @@ void subsytemwavefunction_by_pivot(std::vector const& wfn, std::vector chunks; -//@@@DBW remove nested parallel omp directive +// remove nested parallel omp directive { #pragma omp single chunks = split_interval_in_chunks(max, omp_get_num_threads()); @@ -446,7 +446,7 @@ bool istensorproduct(std::vector const& wfn, std::size_t compl_st = compl_bits.to_ullong(); std::atomic go(true); -//@@@DBW remove nested omp parallel +// remove nested omp parallel { int thread_id = omp_get_thread_num(); if (thread_id < chunks.size() - 1) From 7a480928aafd1c95be93a410afc4620744403c9b Mon Sep 17 00:00:00 2001 From: "Stefan J. Wernli" Date: Tue, 9 Jun 2020 23:03:00 -0700 Subject: [PATCH 4/5] A few more comment cleanup --- src/Simulation/Native/src/simulator/kernels.hpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Simulation/Native/src/simulator/kernels.hpp b/src/Simulation/Native/src/simulator/kernels.hpp index 13f49fe14ef..21447c5b535 100644 --- a/src/Simulation/Native/src/simulator/kernels.hpp +++ b/src/Simulation/Native/src/simulator/kernels.hpp @@ -398,7 +398,6 @@ void subsytemwavefunction_by_pivot(std::vector const& wfn, std::vector chunks; -// remove nested parallel omp directive { #pragma omp single chunks = split_interval_in_chunks(max, omp_get_num_threads()); @@ -446,7 +445,6 @@ bool istensorproduct(std::vector const& wfn, std::size_t compl_st = compl_bits.to_ullong(); std::atomic go(true); -// remove nested omp parallel { int thread_id = omp_get_thread_num(); if (thread_id < chunks.size() - 1) From 3cb95740bdbc88566aad51c65fbb84642d8fd8dd Mon Sep 17 00:00:00 2001 From: "Stefan J. Wernli" Date: Wed, 10 Jun 2020 00:04:16 -0700 Subject: [PATCH 5/5] Putting back vcomp140.dll --- src/Simulation/Native/win10/vcomp140.dll | Bin 0 -> 155296 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/Simulation/Native/win10/vcomp140.dll diff --git a/src/Simulation/Native/win10/vcomp140.dll b/src/Simulation/Native/win10/vcomp140.dll new file mode 100644 index 0000000000000000000000000000000000000000..872663e58d4e89f42a2c7f9c3e3977b5751d5d32 GIT binary patch literal 155296 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 z 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

;?Adb)cUv{#kb9 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 G_`d+o5e*vv literal 0 HcmV?d00001