From 1b4c95e988aa2d0c5d7f6cf87750ea4214dc8171 Mon Sep 17 00:00:00 2001 From: couturie Date: Thu, 25 Apr 2013 16:53:32 +0200 Subject: [PATCH] add ch4 --- BookGPU/BookGPU.tex | 1 + BookGPU/Chapters/chapter12/ch12.aux | 152 +- BookGPU/Chapters/chapter16/ch16.aux | 134 +- BookGPU/Chapters/chapter17/ch17.aux | 142 +- BookGPU/Chapters/chapter18/ch18.aux | 80 +- BookGPU/Chapters/chapter4/biblio4.bib | 8 + BookGPU/Chapters/chapter4/ch4.tex | 389 + .../Chapters/chapter4/code/convoGene3Reg8.cu | 31 + .../Chapters/chapter4/code/convoGene3Reg8.cu~ | 31 + BookGPU/Chapters/chapter4/code/convoGene8r.cu | 18 + .../Chapters/chapter4/code/convoGene8r.cu~ | 18 + .../Chapters/chapter4/code/convoGene8x8pL3.cu | 62 + .../chapter4/code/convoGene8x8pL3.cu~ | 62 + .../Chapters/chapter4/code/convoGeneReg1.cu~ | 25 + .../Chapters/chapter4/code/convoGeneSh1.cu | 69 + .../Chapters/chapter4/code/convoGeneSh1.cu~ | 69 + BookGPU/Chapters/chapter4/code/convoGeneSh1~ | 73 + BookGPU/Chapters/chapter4/code/convoSepSh.cu | 6 + BookGPU/Chapters/chapter4/code/convoSepSh.cu~ | 6 + BookGPU/Chapters/chapter4/code/convoSepShH.cu | 58 + .../Chapters/chapter4/code/convoSepShH.cu~ | 59 + BookGPU/Chapters/chapter4/code/convoSepShV.cu | 57 + .../Chapters/chapter4/code/convoSepShV.cu~ | 56 + .../chapter4/code/levelines_kernels.cu | 3793 +++ .../Chapters/chapter4/code/maskInSymbol.cu | 9 + .../Chapters/chapter4/code/maskInSymbol.cu~ | 9 + BookGPU/Chapters/chapter4/img/convo1.png | Bin 0 -> 174459 bytes .../Chapters/chapter4/img/convoOverlap1.png | Bin 0 -> 18976 bytes .../Chapters/chapter4/img/convoOverlap2.png | Bin 0 -> 31328 bytes BookGPU/Chapters/chapter4/img/convoShMem.png | Bin 0 -> 184261 bytes BookGPU/Chapters/chapter4/img/convos.svg | 20238 ++++++++++++++++ BookGPU/Chapters/chapter4/img/kernLeft.png | Bin 0 -> 1571 bytes BookGPU/Chapters/chapter4/img/kernRight.png | Bin 0 -> 1566 bytes BookGPU/Chapters/chapter6/ch6.aux | 210 +- BookGPU/Makefile | 1 + 35 files changed, 25507 insertions(+), 359 deletions(-) create mode 100644 BookGPU/Chapters/chapter4/biblio4.bib create mode 100644 BookGPU/Chapters/chapter4/ch4.tex create mode 100755 BookGPU/Chapters/chapter4/code/convoGene3Reg8.cu create mode 100755 BookGPU/Chapters/chapter4/code/convoGene3Reg8.cu~ create mode 100644 BookGPU/Chapters/chapter4/code/convoGene8r.cu create mode 100644 BookGPU/Chapters/chapter4/code/convoGene8r.cu~ create mode 100644 BookGPU/Chapters/chapter4/code/convoGene8x8pL3.cu create mode 100644 BookGPU/Chapters/chapter4/code/convoGene8x8pL3.cu~ create mode 100755 BookGPU/Chapters/chapter4/code/convoGeneReg1.cu~ create mode 100644 BookGPU/Chapters/chapter4/code/convoGeneSh1.cu create mode 100644 BookGPU/Chapters/chapter4/code/convoGeneSh1.cu~ create mode 100644 BookGPU/Chapters/chapter4/code/convoGeneSh1~ create mode 100644 BookGPU/Chapters/chapter4/code/convoSepSh.cu create mode 100644 BookGPU/Chapters/chapter4/code/convoSepSh.cu~ create mode 100644 BookGPU/Chapters/chapter4/code/convoSepShH.cu create mode 100644 BookGPU/Chapters/chapter4/code/convoSepShH.cu~ create mode 100644 BookGPU/Chapters/chapter4/code/convoSepShV.cu create mode 100644 BookGPU/Chapters/chapter4/code/convoSepShV.cu~ create mode 100644 BookGPU/Chapters/chapter4/code/levelines_kernels.cu create mode 100644 BookGPU/Chapters/chapter4/code/maskInSymbol.cu create mode 100644 BookGPU/Chapters/chapter4/code/maskInSymbol.cu~ create mode 100644 BookGPU/Chapters/chapter4/img/convo1.png create mode 100644 BookGPU/Chapters/chapter4/img/convoOverlap1.png create mode 100644 BookGPU/Chapters/chapter4/img/convoOverlap2.png create mode 100644 BookGPU/Chapters/chapter4/img/convoShMem.png create mode 100644 BookGPU/Chapters/chapter4/img/convos.svg create mode 100755 BookGPU/Chapters/chapter4/img/kernLeft.png create mode 100755 BookGPU/Chapters/chapter4/img/kernRight.png diff --git a/BookGPU/BookGPU.tex b/BookGPU/BookGPU.tex index eaa9c44..e236ce8 100755 --- a/BookGPU/BookGPU.tex +++ b/BookGPU/BookGPU.tex @@ -182,6 +182,7 @@ \include{Chapters/chapter2/ch2} \part{Image processing} \include{Chapters/chapter3/ch3} +\include{Chapters/chapter4/ch4} \part{Software development} \include{Chapters/chapter5/ch5}% lib HeatSolution0.049307.pdf HeatSolution0.pdf ... \include{Chapters/chapter6/ch6} diff --git a/BookGPU/Chapters/chapter12/ch12.aux b/BookGPU/Chapters/chapter12/ch12.aux index f4f6c5c..86728f0 100644 --- a/BookGPU/Chapters/chapter12/ch12.aux +++ b/BookGPU/Chapters/chapter12/ch12.aux @@ -3,81 +3,81 @@ \@writefile{toc}{\author{Rapha\IeC {\"e}l Couturier}{}} \@writefile{toc}{\author{Jacques Bahi}{}} \@writefile{loa}{\addvspace {10\p@ }} -\@writefile{toc}{\contentsline {chapter}{\numberline {12}Solving sparse linear systems with GMRES and CG methods on GPU clusters}{295}} +\@writefile{toc}{\contentsline {chapter}{\numberline {13}Solving sparse linear systems with GMRES and CG methods on GPU clusters}{313}} \@writefile{lof}{\addvspace {10\p@ }} \@writefile{lot}{\addvspace {10\p@ }} -\newlabel{ch12}{{12}{295}} -\@writefile{toc}{\contentsline {section}{\numberline {12.1}Introduction}{295}} -\newlabel{ch12:sec:01}{{12.1}{295}} -\@writefile{toc}{\contentsline {section}{\numberline {12.2}Krylov iterative methods}{296}} -\newlabel{ch12:sec:02}{{12.2}{296}} -\newlabel{ch12:eq:01}{{12.1}{296}} -\newlabel{ch12:eq:02}{{12.2}{296}} -\newlabel{ch12:eq:03}{{12.3}{296}} -\newlabel{ch12:eq:11}{{12.4}{297}} -\@writefile{toc}{\contentsline {subsection}{\numberline {12.2.1}CG method}{297}} -\newlabel{ch12:sec:02.01}{{12.2.1}{297}} -\newlabel{ch12:eq:04}{{12.5}{297}} -\newlabel{ch12:eq:05}{{12.6}{297}} -\newlabel{ch12:eq:06}{{12.7}{297}} -\newlabel{ch12:eq:07}{{12.8}{297}} -\newlabel{ch12:eq:08}{{12.9}{297}} -\newlabel{ch12:eq:09}{{12.10}{297}} -\@writefile{loa}{\contentsline {algocf}{\numberline {14}{\ignorespaces Left-preconditioned CG method\relax }}{298}} -\newlabel{ch12:alg:01}{{14}{298}} -\newlabel{ch12:eq:10}{{12.11}{298}} -\@writefile{toc}{\contentsline {subsection}{\numberline {12.2.2}GMRES method}{299}} -\newlabel{ch12:sec:02.02}{{12.2.2}{299}} -\newlabel{ch12:eq:12}{{12.12}{299}} -\newlabel{ch12:eq:13}{{12.13}{299}} -\newlabel{ch12:eq:14}{{12.14}{299}} -\newlabel{ch12:eq:15}{{12.15}{299}} -\newlabel{ch12:eq:16}{{12.16}{299}} -\newlabel{ch12:eq:17}{{12.17}{299}} -\newlabel{ch12:eq:18}{{12.18}{299}} -\newlabel{ch12:eq:19}{{12.19}{299}} -\@writefile{loa}{\contentsline {algocf}{\numberline {15}{\ignorespaces Left-preconditioned GMRES method with restarts\relax }}{300}} -\newlabel{ch12:alg:02}{{15}{300}} -\@writefile{toc}{\contentsline {section}{\numberline {12.3}Parallel implementation on a GPU cluster}{301}} -\newlabel{ch12:sec:03}{{12.3}{301}} -\@writefile{toc}{\contentsline {subsection}{\numberline {12.3.1}Data partitioning}{301}} -\newlabel{ch12:sec:03.01}{{12.3.1}{301}} -\@writefile{lof}{\contentsline {figure}{\numberline {12.1}{\ignorespaces A data partitioning of the sparse matrix $A$, the solution vector $x$ and the right-hand side $b$ into four portions.\relax }}{302}} -\newlabel{ch12:fig:01}{{12.1}{302}} -\@writefile{toc}{\contentsline {subsection}{\numberline {12.3.2}GPU computing}{302}} -\newlabel{ch12:sec:03.02}{{12.3.2}{302}} -\@writefile{toc}{\contentsline {subsection}{\numberline {12.3.3}Data communications}{303}} -\newlabel{ch12:sec:03.03}{{12.3.3}{303}} -\@writefile{lof}{\contentsline {figure}{\numberline {12.2}{\ignorespaces Data exchanges between \textit {Node 1} and its neighbors \textit {Node 0}, \textit {Node 2} and \textit {Node 3}.\relax }}{304}} -\newlabel{ch12:fig:02}{{12.2}{304}} -\@writefile{lof}{\contentsline {figure}{\numberline {12.3}{\ignorespaces Columns reordering of a sparse sub-matrix.\relax }}{305}} -\newlabel{ch12:fig:03}{{12.3}{305}} -\@writefile{toc}{\contentsline {section}{\numberline {12.4}Experimental results}{306}} -\newlabel{ch12:sec:04}{{12.4}{306}} -\@writefile{lof}{\contentsline {figure}{\numberline {12.4}{\ignorespaces General scheme of the GPU cluster of tests composed of six machines, each with two GPUs.\relax }}{306}} -\newlabel{ch12:fig:04}{{12.4}{306}} -\@writefile{lof}{\contentsline {figure}{\numberline {12.5}{\ignorespaces Sketches of sparse matrices chosen from the Davis collection.\relax }}{307}} -\newlabel{ch12:fig:05}{{12.5}{307}} -\@writefile{lot}{\contentsline {table}{\numberline {12.1}{\ignorespaces Main characteristics of sparse matrices chosen from the Davis collection.\relax }}{307}} -\newlabel{ch12:tab:01}{{12.1}{307}} -\@writefile{lot}{\contentsline {table}{\numberline {12.2}{\ignorespaces Performances of the parallel CG method on a cluster of 24 CPU cores vs. on a cluster of 12 GPUs.\relax }}{308}} -\newlabel{ch12:tab:02}{{12.2}{308}} -\@writefile{lot}{\contentsline {table}{\numberline {12.3}{\ignorespaces Performances of the parallel GMRES method on a cluster 24 CPU cores vs. on cluster of 12 GPUs.\relax }}{308}} -\newlabel{ch12:tab:03}{{12.3}{308}} -\newlabel{ch12:eq:20}{{12.20}{309}} -\@writefile{lof}{\contentsline {figure}{\numberline {12.6}{\ignorespaces Parallel generation of a large sparse matrix by four computing nodes.\relax }}{310}} -\newlabel{ch12:fig:06}{{12.6}{310}} -\@writefile{lot}{\contentsline {table}{\numberline {12.4}{\ignorespaces Main characteristics of sparse banded matrices generated from those of the Davis collection.\relax }}{310}} -\newlabel{ch12:tab:04}{{12.4}{310}} -\@writefile{lot}{\contentsline {table}{\numberline {12.5}{\ignorespaces Performances of the parallel CG method for solving linear systems associated to sparse banded matrices on a cluster of 24 CPU cores vs. on a cluster of 12 GPUs.\relax }}{311}} -\newlabel{ch12:tab:05}{{12.5}{311}} -\@writefile{toc}{\contentsline {section}{\numberline {12.5}Conclusion}{311}} -\newlabel{ch12:sec:05}{{12.5}{311}} -\@writefile{lot}{\contentsline {table}{\numberline {12.6}{\ignorespaces Performances of the parallel GMRES method for solving linear systems associated to sparse banded matrices on a cluster of 24 CPU cores vs. on a cluster of 12 GPUs.\relax }}{312}} -\newlabel{ch12:tab:06}{{12.6}{312}} -\@writefile{toc}{\contentsline {section}{Bibliography}{312}} +\newlabel{ch12}{{13}{313}} +\@writefile{toc}{\contentsline {section}{\numberline {13.1}Introduction}{313}} +\newlabel{ch12:sec:01}{{13.1}{313}} +\@writefile{toc}{\contentsline {section}{\numberline {13.2}Krylov iterative methods}{314}} +\newlabel{ch12:sec:02}{{13.2}{314}} +\newlabel{ch12:eq:01}{{13.1}{314}} +\newlabel{ch12:eq:02}{{13.2}{314}} +\newlabel{ch12:eq:03}{{13.3}{314}} +\newlabel{ch12:eq:11}{{13.4}{315}} +\@writefile{toc}{\contentsline {subsection}{\numberline {13.2.1}CG method}{315}} +\newlabel{ch12:sec:02.01}{{13.2.1}{315}} +\newlabel{ch12:eq:04}{{13.5}{315}} +\newlabel{ch12:eq:05}{{13.6}{315}} +\newlabel{ch12:eq:06}{{13.7}{315}} +\newlabel{ch12:eq:07}{{13.8}{315}} +\newlabel{ch12:eq:08}{{13.9}{315}} +\newlabel{ch12:eq:09}{{13.10}{315}} +\@writefile{loa}{\contentsline {algocf}{\numberline {15}{\ignorespaces Left-preconditioned CG method\relax }}{316}} +\newlabel{ch12:alg:01}{{15}{316}} +\newlabel{ch12:eq:10}{{13.11}{316}} +\@writefile{toc}{\contentsline {subsection}{\numberline {13.2.2}GMRES method}{317}} +\newlabel{ch12:sec:02.02}{{13.2.2}{317}} +\newlabel{ch12:eq:12}{{13.12}{317}} +\newlabel{ch12:eq:13}{{13.13}{317}} +\newlabel{ch12:eq:14}{{13.14}{317}} +\newlabel{ch12:eq:15}{{13.15}{317}} +\newlabel{ch12:eq:16}{{13.16}{317}} +\newlabel{ch12:eq:17}{{13.17}{317}} +\newlabel{ch12:eq:18}{{13.18}{317}} +\newlabel{ch12:eq:19}{{13.19}{317}} +\@writefile{loa}{\contentsline {algocf}{\numberline {16}{\ignorespaces Left-preconditioned GMRES method with restarts\relax }}{318}} +\newlabel{ch12:alg:02}{{16}{318}} +\@writefile{toc}{\contentsline {section}{\numberline {13.3}Parallel implementation on a GPU cluster}{319}} +\newlabel{ch12:sec:03}{{13.3}{319}} +\@writefile{toc}{\contentsline {subsection}{\numberline {13.3.1}Data partitioning}{319}} +\newlabel{ch12:sec:03.01}{{13.3.1}{319}} +\@writefile{lof}{\contentsline {figure}{\numberline {13.1}{\ignorespaces A data partitioning of the sparse matrix $A$, the solution vector $x$ and the right-hand side $b$ into four portions.\relax }}{320}} +\newlabel{ch12:fig:01}{{13.1}{320}} +\@writefile{toc}{\contentsline {subsection}{\numberline {13.3.2}GPU computing}{320}} +\newlabel{ch12:sec:03.02}{{13.3.2}{320}} +\@writefile{toc}{\contentsline {subsection}{\numberline {13.3.3}Data communications}{321}} +\newlabel{ch12:sec:03.03}{{13.3.3}{321}} +\@writefile{lof}{\contentsline {figure}{\numberline {13.2}{\ignorespaces Data exchanges between \textit {Node 1} and its neighbors \textit {Node 0}, \textit {Node 2} and \textit {Node 3}.\relax }}{322}} +\newlabel{ch12:fig:02}{{13.2}{322}} +\@writefile{lof}{\contentsline {figure}{\numberline {13.3}{\ignorespaces Columns reordering of a sparse sub-matrix.\relax }}{323}} +\newlabel{ch12:fig:03}{{13.3}{323}} +\@writefile{toc}{\contentsline {section}{\numberline {13.4}Experimental results}{324}} +\newlabel{ch12:sec:04}{{13.4}{324}} +\@writefile{lof}{\contentsline {figure}{\numberline {13.4}{\ignorespaces General scheme of the GPU cluster of tests composed of six machines, each with two GPUs.\relax }}{324}} +\newlabel{ch12:fig:04}{{13.4}{324}} +\@writefile{lof}{\contentsline {figure}{\numberline {13.5}{\ignorespaces Sketches of sparse matrices chosen from the Davis collection.\relax }}{325}} +\newlabel{ch12:fig:05}{{13.5}{325}} +\@writefile{lot}{\contentsline {table}{\numberline {13.1}{\ignorespaces Main characteristics of sparse matrices chosen from the Davis collection.\relax }}{325}} +\newlabel{ch12:tab:01}{{13.1}{325}} +\@writefile{lot}{\contentsline {table}{\numberline {13.2}{\ignorespaces Performances of the parallel CG method on a cluster of 24 CPU cores vs. on a cluster of 12 GPUs.\relax }}{326}} +\newlabel{ch12:tab:02}{{13.2}{326}} +\@writefile{lot}{\contentsline {table}{\numberline {13.3}{\ignorespaces Performances of the parallel GMRES method on a cluster 24 CPU cores vs. on cluster of 12 GPUs.\relax }}{326}} +\newlabel{ch12:tab:03}{{13.3}{326}} +\newlabel{ch12:eq:20}{{13.20}{327}} +\@writefile{lof}{\contentsline {figure}{\numberline {13.6}{\ignorespaces Parallel generation of a large sparse matrix by four computing nodes.\relax }}{328}} +\newlabel{ch12:fig:06}{{13.6}{328}} +\@writefile{lot}{\contentsline {table}{\numberline {13.4}{\ignorespaces Main characteristics of sparse banded matrices generated from those of the Davis collection.\relax }}{328}} +\newlabel{ch12:tab:04}{{13.4}{328}} +\@writefile{lot}{\contentsline {table}{\numberline {13.5}{\ignorespaces Performances of the parallel CG method for solving linear systems associated to sparse banded matrices on a cluster of 24 CPU cores vs. on a cluster of 12 GPUs.\relax }}{329}} +\newlabel{ch12:tab:05}{{13.5}{329}} +\@writefile{toc}{\contentsline {section}{\numberline {13.5}Conclusion}{329}} +\newlabel{ch12:sec:05}{{13.5}{329}} +\@writefile{lot}{\contentsline {table}{\numberline {13.6}{\ignorespaces Performances of the parallel GMRES method for solving linear systems associated to sparse banded matrices on a cluster of 24 CPU cores vs. on a cluster of 12 GPUs.\relax }}{330}} +\newlabel{ch12:tab:06}{{13.6}{330}} +\@writefile{toc}{\contentsline {section}{Bibliography}{330}} \@setckpt{Chapters/chapter12/ch12}{ -\setcounter{page}{314} +\setcounter{page}{332} \setcounter{equation}{22} \setcounter{enumi}{2} \setcounter{enumii}{0} @@ -86,7 +86,7 @@ \setcounter{footnote}{0} \setcounter{mpfootnote}{0} \setcounter{part}{5} -\setcounter{chapter}{12} +\setcounter{chapter}{13} \setcounter{section}{5} \setcounter{subsection}{0} \setcounter{subsubsection}{0} @@ -103,9 +103,9 @@ \setcounter{lstnumber}{50} \setcounter{ContinuedFloat}{0} \setcounter{AlgoLine}{29} -\setcounter{algocfline}{15} -\setcounter{algocfproc}{15} -\setcounter{algocf}{15} +\setcounter{algocfline}{16} +\setcounter{algocfproc}{16} +\setcounter{algocf}{16} \setcounter{nprt@mantissa@digitsbefore}{0} \setcounter{nprt@mantissa@digitsafter}{0} \setcounter{nprt@exponent@digitsbefore}{0} diff --git a/BookGPU/Chapters/chapter16/ch16.aux b/BookGPU/Chapters/chapter16/ch16.aux index 401fa90..879a4c2 100644 --- a/BookGPU/Chapters/chapter16/ch16.aux +++ b/BookGPU/Chapters/chapter16/ch16.aux @@ -4,72 +4,72 @@ \@writefile{toc}{\author{H. Wang}{}} \@writefile{toc}{\author{H. Yu}{}} \@writefile{loa}{\addvspace {10\p@ }} -\@writefile{toc}{\contentsline {chapter}{\numberline {16}GPU-Accelerated Envelope-Following Method}{379}} +\@writefile{toc}{\contentsline {chapter}{\numberline {17}GPU-Accelerated Envelope-Following Method}{397}} \@writefile{lof}{\addvspace {10\p@ }} \@writefile{lot}{\addvspace {10\p@ }} -\@writefile{toc}{\contentsline {section}{\numberline {16.1}Introduction}{379}} -\newlabel{fig:ef1}{{16.1(a)}{381}} -\newlabel{sub@fig:ef1}{{(a)}{381}} -\newlabel{fig:ef2}{{16.1(b)}{381}} -\newlabel{sub@fig:ef2}{{(b)}{381}} -\@writefile{lof}{\contentsline {figure}{\numberline {16.1}{\ignorespaces Transient envelope-following analysis. (Both two figures reflect backward-Euler style envelope-following.)\relax }}{381}} -\@writefile{lof}{\contentsline {subfigure}{\numberline{(a)}{\ignorespaces {Illustration of one envelope skip.}}}{381}} -\@writefile{lof}{\contentsline {subfigure}{\numberline{(b)}{\ignorespaces {The envelope changes in a slow time scale.}}}{381}} -\newlabel{fig:ef_intro}{{16.1}{381}} -\@writefile{toc}{\contentsline {section}{\numberline {16.2}The envelope-following method in a nutshell}{382}} -\newlabel{sec:ef}{{16.2}{382}} -\newlabel{eq:dae}{{16.1}{382}} -\newlabel{eq:Newton}{{16.2}{383}} -\newlabel{eq:A}{{16.3}{383}} -\@writefile{toc}{\contentsline {section}{\numberline {16.3}New parallel envelope-following method}{384}} -\newlabel{sec:gmres}{{16.3}{384}} -\@writefile{toc}{\contentsline {subsection}{\numberline {16.3.1}GMRES solver for Newton update equation}{384}} -\@writefile{lof}{\contentsline {figure}{\numberline {16.2}{\ignorespaces The flow of envelope-following method.\relax }}{385}} -\newlabel{fig:ef_flow}{{16.2}{385}} -\@writefile{loa}{\contentsline {algocf}{\numberline {19}{\ignorespaces Standard GMRES algorithm.\relax }}{386}} -\newlabel{alg:GMRES}{{19}{386}} -\newlabel{line:mvp}{{5}{386}} -\newlabel{line:newnorm}{{11}{386}} -\@writefile{toc}{\contentsline {subsection}{\numberline {16.3.2}Parallelization on GPU platforms}{386}} -\newlabel{sec:gpu}{{16.3.2}{386}} -\@writefile{lof}{\contentsline {figure}{\numberline {16.3}{\ignorespaces GPU parallel solver for envelope-following update.\relax }}{387}} -\newlabel{fig:gmres}{{16.3}{387}} -\@writefile{toc}{\contentsline {subsection}{\numberline {16.3.3}Gear-2 based sensitivity calculation}{388}} -\newlabel{sec:gear}{{16.3.3}{388}} -\newlabel{eq:BE}{{16.4}{388}} -\newlabel{eq:sens1}{{16.5}{388}} -\newlabel{eq:Gear_t2}{{16.6}{389}} -\newlabel{eq:sens2}{{16.7}{389}} -\newlabel{eq:Gear_t3}{{16.8}{389}} -\newlabel{eq:sensM}{{16.9}{389}} -\@writefile{loa}{\contentsline {algocf}{\numberline {20}{\ignorespaces The matrix-free method for Krylov subspace construction.\relax }}{390}} -\newlabel{alg:mf_Gear}{{20}{390}} -\newlabel{line:mf_Gear_loop}{{4}{390}} -\newlabel{line:shift}{{8}{390}} -\@writefile{toc}{\contentsline {section}{\numberline {16.4}Numerical examples}{390}} -\newlabel{sec:exp}{{16.4}{390}} -\@writefile{lof}{\contentsline {figure}{\numberline {16.4}{\ignorespaces Diagram of a zero-voltage quasi-resonant flyback converter.\relax }}{391}} -\newlabel{fig:flyback}{{16.4}{391}} -\@writefile{lof}{\contentsline {figure}{\numberline {16.5}{\ignorespaces Illustration of power/ground network model.\relax }}{391}} -\newlabel{fig:pg}{{16.5}{391}} -\newlabel{fig:flybackWhole}{{16.6(a)}{392}} -\newlabel{sub@fig:flybackWhole}{{(a)}{392}} -\newlabel{fig:flybackZoom}{{16.6(b)}{392}} -\newlabel{sub@fig:flybackZoom}{{(b)}{392}} -\@writefile{lof}{\contentsline {figure}{\numberline {16.6}{\ignorespaces Flyback converter solution calculated by envelope-following. The red curve is traditional SPICE simulation result, and the back curve is the envelope-following output with simulation points marked.\relax }}{392}} -\@writefile{lof}{\contentsline {subfigure}{\numberline{(a)}{\ignorespaces {The whole plot}}}{392}} -\@writefile{lof}{\contentsline {subfigure}{\numberline{(b)}{\ignorespaces {Detail of one EF simulation period}}}{392}} -\newlabel{fig:flyback_wave}{{16.6}{392}} -\@writefile{lof}{\contentsline {figure}{\numberline {16.7}{\ignorespaces Buck converter solution calculated by envelope-following.\relax }}{393}} -\newlabel{fig:buck_wave}{{16.7}{393}} -\@writefile{lot}{\contentsline {table}{\numberline {16.1}{\ignorespaces CPU and GPU time comparisons (in seconds) for solving Newton update equation with the proposed Gear-2 sensitivity. \relax }}{393}} -\newlabel{table:circuit}{{16.1}{393}} -\@writefile{toc}{\contentsline {section}{\numberline {16.5}Summary}{394}} -\newlabel{sec:summary}{{16.5}{394}} -\@writefile{toc}{\contentsline {section}{\numberline {16.6}Glossary}{394}} -\@writefile{toc}{\contentsline {section}{Bibliography}{394}} +\@writefile{toc}{\contentsline {section}{\numberline {17.1}Introduction}{397}} +\newlabel{fig:ef1}{{17.1(a)}{399}} +\newlabel{sub@fig:ef1}{{(a)}{399}} +\newlabel{fig:ef2}{{17.1(b)}{399}} +\newlabel{sub@fig:ef2}{{(b)}{399}} +\@writefile{lof}{\contentsline {figure}{\numberline {17.1}{\ignorespaces Transient envelope-following analysis. (Both two figures reflect backward-Euler style envelope-following.)\relax }}{399}} +\@writefile{lof}{\contentsline {subfigure}{\numberline{(a)}{\ignorespaces {Illustration of one envelope skip.}}}{399}} +\@writefile{lof}{\contentsline {subfigure}{\numberline{(b)}{\ignorespaces {The envelope changes in a slow time scale.}}}{399}} +\newlabel{fig:ef_intro}{{17.1}{399}} +\@writefile{toc}{\contentsline {section}{\numberline {17.2}The envelope-following method in a nutshell}{400}} +\newlabel{sec:ef}{{17.2}{400}} +\newlabel{eq:dae}{{17.1}{400}} +\newlabel{eq:Newton}{{17.2}{401}} +\newlabel{eq:A}{{17.3}{401}} +\@writefile{toc}{\contentsline {section}{\numberline {17.3}New parallel envelope-following method}{402}} +\newlabel{sec:gmres}{{17.3}{402}} +\@writefile{toc}{\contentsline {subsection}{\numberline {17.3.1}GMRES solver for Newton update equation}{402}} +\@writefile{lof}{\contentsline {figure}{\numberline {17.2}{\ignorespaces The flow of envelope-following method.\relax }}{403}} +\newlabel{fig:ef_flow}{{17.2}{403}} +\@writefile{loa}{\contentsline {algocf}{\numberline {20}{\ignorespaces Standard GMRES algorithm.\relax }}{404}} +\newlabel{alg:GMRES}{{20}{404}} +\newlabel{line:mvp}{{5}{404}} +\newlabel{line:newnorm}{{11}{404}} +\@writefile{toc}{\contentsline {subsection}{\numberline {17.3.2}Parallelization on GPU platforms}{404}} +\newlabel{sec:gpu}{{17.3.2}{404}} +\@writefile{lof}{\contentsline {figure}{\numberline {17.3}{\ignorespaces GPU parallel solver for envelope-following update.\relax }}{405}} +\newlabel{fig:gmres}{{17.3}{405}} +\@writefile{toc}{\contentsline {subsection}{\numberline {17.3.3}Gear-2 based sensitivity calculation}{406}} +\newlabel{sec:gear}{{17.3.3}{406}} +\newlabel{eq:BE}{{17.4}{406}} +\newlabel{eq:sens1}{{17.5}{406}} +\newlabel{eq:Gear_t2}{{17.6}{407}} +\newlabel{eq:sens2}{{17.7}{407}} +\newlabel{eq:Gear_t3}{{17.8}{407}} +\newlabel{eq:sensM}{{17.9}{407}} +\@writefile{loa}{\contentsline {algocf}{\numberline {21}{\ignorespaces The matrix-free method for Krylov subspace construction.\relax }}{408}} +\newlabel{alg:mf_Gear}{{21}{408}} +\newlabel{line:mf_Gear_loop}{{4}{408}} +\newlabel{line:shift}{{8}{408}} +\@writefile{toc}{\contentsline {section}{\numberline {17.4}Numerical examples}{408}} +\newlabel{sec:exp}{{17.4}{408}} +\@writefile{lof}{\contentsline {figure}{\numberline {17.4}{\ignorespaces Diagram of a zero-voltage quasi-resonant flyback converter.\relax }}{409}} +\newlabel{fig:flyback}{{17.4}{409}} +\@writefile{lof}{\contentsline {figure}{\numberline {17.5}{\ignorespaces Illustration of power/ground network model.\relax }}{409}} +\newlabel{fig:pg}{{17.5}{409}} +\newlabel{fig:flybackWhole}{{17.6(a)}{410}} +\newlabel{sub@fig:flybackWhole}{{(a)}{410}} +\newlabel{fig:flybackZoom}{{17.6(b)}{410}} +\newlabel{sub@fig:flybackZoom}{{(b)}{410}} +\@writefile{lof}{\contentsline {figure}{\numberline {17.6}{\ignorespaces Flyback converter solution calculated by envelope-following. The red curve is traditional SPICE simulation result, and the back curve is the envelope-following output with simulation points marked.\relax }}{410}} +\@writefile{lof}{\contentsline {subfigure}{\numberline{(a)}{\ignorespaces {The whole plot}}}{410}} +\@writefile{lof}{\contentsline {subfigure}{\numberline{(b)}{\ignorespaces {Detail of one EF simulation period}}}{410}} +\newlabel{fig:flyback_wave}{{17.6}{410}} +\@writefile{lof}{\contentsline {figure}{\numberline {17.7}{\ignorespaces Buck converter solution calculated by envelope-following.\relax }}{411}} +\newlabel{fig:buck_wave}{{17.7}{411}} +\@writefile{lot}{\contentsline {table}{\numberline {17.1}{\ignorespaces CPU and GPU time comparisons (in seconds) for solving Newton update equation with the proposed Gear-2 sensitivity. \relax }}{411}} +\newlabel{table:circuit}{{17.1}{411}} +\@writefile{toc}{\contentsline {section}{\numberline {17.5}Summary}{412}} +\newlabel{sec:summary}{{17.5}{412}} +\@writefile{toc}{\contentsline {section}{\numberline {17.6}Glossary}{412}} +\@writefile{toc}{\contentsline {section}{Bibliography}{412}} \@setckpt{Chapters/chapter16/ch16}{ -\setcounter{page}{396} +\setcounter{page}{414} \setcounter{equation}{9} \setcounter{enumi}{2} \setcounter{enumii}{0} @@ -78,7 +78,7 @@ \setcounter{footnote}{0} \setcounter{mpfootnote}{0} \setcounter{part}{5} -\setcounter{chapter}{16} +\setcounter{chapter}{17} \setcounter{section}{6} \setcounter{subsection}{0} \setcounter{subsubsection}{0} @@ -95,9 +95,9 @@ \setcounter{lstnumber}{9} \setcounter{ContinuedFloat}{0} \setcounter{AlgoLine}{8} -\setcounter{algocfline}{20} -\setcounter{algocfproc}{20} -\setcounter{algocf}{20} +\setcounter{algocfline}{21} +\setcounter{algocfproc}{21} +\setcounter{algocf}{21} \setcounter{nprt@mantissa@digitsbefore}{0} \setcounter{nprt@mantissa@digitsafter}{0} \setcounter{nprt@exponent@digitsbefore}{0} diff --git a/BookGPU/Chapters/chapter17/ch17.aux b/BookGPU/Chapters/chapter17/ch17.aux index 4f932bd..1236656 100644 --- a/BookGPU/Chapters/chapter17/ch17.aux +++ b/BookGPU/Chapters/chapter17/ch17.aux @@ -6,76 +6,76 @@ \@writefile{toc}{\author{B\IeC {\'e}n\IeC {\'e}dicte Herrmann}{}} \@writefile{toc}{\author{Laurent Philippe}{}} \@writefile{loa}{\addvspace {10\p@ }} -\@writefile{toc}{\contentsline {chapter}{\numberline {17}Implementing Multi-Agent Systems on GPU}{399}} +\@writefile{toc}{\contentsline {chapter}{\numberline {18}Implementing Multi-Agent Systems on GPU}{417}} \@writefile{lof}{\addvspace {10\p@ }} \@writefile{lot}{\addvspace {10\p@ }} -\newlabel{chapter17}{{17}{400}} -\@writefile{toc}{\contentsline {section}{\numberline {17.1}Introduction}{400}} -\newlabel{ch17:intro}{{17.1}{400}} -\@writefile{toc}{\contentsline {section}{\numberline {17.2}Running Agent-Based Simulations}{401}} -\newlabel{ch17:ABM}{{17.2}{401}} -\@writefile{toc}{\contentsline {subsection}{\numberline {17.2.1}Multi-agent systems and parallelism}{401}} -\@writefile{toc}{\contentsline {subsection}{\numberline {17.2.2}MAS Implementation on GPU}{403}} -\newlabel{ch17:subsec:gpu}{{17.2.2}{403}} -\@writefile{toc}{\contentsline {section}{\numberline {17.3}A first practical example}{404}} -\newlabel{ch17:sec:1stmodel}{{17.3}{404}} -\@writefile{toc}{\contentsline {subsection}{\numberline {17.3.1}The Collembola model}{404}} -\newlabel{ch17:subsec:collembolamodel}{{17.3.1}{404}} -\@writefile{lof}{\contentsline {figure}{\numberline {17.1}{\ignorespaces Evolution algorithm of Collembola model\relax }}{405}} -\newlabel{ch17:fig:collem_algorithm}{{17.1}{405}} -\@writefile{toc}{\contentsline {subsection}{\numberline {17.3.2}Collembola Implementation}{405}} -\newlabel{ch17:listing:collembola-diffuse}{{17.1}{406}} -\@writefile{lol}{\contentsline {lstlisting}{\numberline {17.1}Collembola OpenCL Diffusion kernel}{406}} -\newlabel{ch17:listing:collembola-reduc}{{17.2}{406}} -\@writefile{lol}{\contentsline {lstlisting}{\numberline {17.2}Collembola OpenCL reduction kernel}{406}} -\@writefile{toc}{\contentsline {subsection}{\numberline {17.3.3}Collembola performance}{407}} -\@writefile{lof}{\contentsline {figure}{\numberline {17.2}{\ignorespaces Performance of the Collembola model on CPU and GPU\relax }}{408}} -\newlabel{ch17:fig:mior_perfs_collem}{{17.2}{408}} -\@writefile{toc}{\contentsline {section}{\numberline {17.4}Second example}{408}} -\newlabel{ch17:sec:2ndmodel}{{17.4}{408}} -\@writefile{toc}{\contentsline {subsection}{\numberline {17.4.1}The MIOR model}{408}} -\newlabel{ch17:subsec:miormodel}{{17.4.1}{408}} -\@writefile{loa}{\contentsline {algocf}{\numberline {21}{\ignorespaces Evolution step of each Meta-Mior (microbial colony) agent\relax }}{409}} -\newlabel{ch17:seqalgo}{{21}{409}} -\@writefile{toc}{\contentsline {subsection}{\numberline {17.4.2}MIOR Implementation}{409}} -\@writefile{lof}{\contentsline {figure}{\numberline {17.3}{\ignorespaces Execution distribution retained on GPU\relax }}{410}} -\newlabel{ch17:fig:gpu_distribution}{{17.3}{410}} -\@writefile{toc}{\contentsline {subsubsection}{\numberline {17.4.2.1}Execution mapping on GPU}{410}} -\@writefile{toc}{\contentsline {subsubsection}{\numberline {17.4.2.2}Data structures translation}{411}} -\newlabel{ch17:subsec:datastructures}{{17.4.2.2}{411}} -\newlabel{ch17:listing:mior_data_structures}{{17.3}{411}} -\@writefile{lol}{\contentsline {lstlisting}{\numberline {17.3}Main data structures used in a MIOR simulation}{411}} -\@writefile{lof}{\contentsline {figure}{\numberline {17.4}{\ignorespaces Compact representation of the topology of a MIOR simulation\relax }}{412}} -\newlabel{ch17:fig:csr_representation}{{17.4}{412}} -\@writefile{toc}{\contentsline {subsubsection}{\numberline {17.4.2.3}Critical resources access management}{412}} -\newlabel{ch17:subsec:concurrency}{{17.4.2.3}{412}} -\newlabel{ch17:listing:mior_kernels}{{17.4}{413}} -\@writefile{lol}{\contentsline {lstlisting}{\numberline {17.4}Main MIOR kernel}{413}} -\newlabel{ch17:fig:mior_launcher}{{17.5}{414}} -\@writefile{lol}{\contentsline {lstlisting}{\numberline {17.5}MIOR simulation launcher}{414}} -\@writefile{toc}{\contentsline {subsubsection}{\numberline {17.4.2.4}Termination detection}{414}} -\@writefile{toc}{\contentsline {subsection}{\numberline {17.4.3}Performance of MIOR implementations}{415}} -\newlabel{ch17:subsec:miorexperiments}{{17.4.3}{415}} -\@writefile{lof}{\contentsline {figure}{\numberline {17.5}{\ignorespaces CPU and GPU performance on a Tesla C1060 node\relax }}{416}} -\newlabel{ch17:fig:mior_perfs_tesla}{{17.5}{416}} -\@writefile{lof}{\contentsline {figure}{\numberline {17.6}{\ignorespaces CPU and GPU performance on a personal computer with a Geforce 8800GT\relax }}{417}} -\newlabel{ch17:fig:mior_perfs_8800gt}{{17.6}{417}} -\@writefile{toc}{\contentsline {section}{\numberline {17.5}Analysis and recommendations}{417}} -\newlabel{ch17:analysis}{{17.5}{417}} -\@writefile{lof}{\contentsline {figure}{\numberline {17.7}{\ignorespaces Execution time of one multi-simulation kernel on the Tesla platform\relax }}{418}} -\newlabel{ch17:fig:monokernel_graph}{{17.7}{418}} -\@writefile{lof}{\contentsline {figure}{\numberline {17.8}{\ignorespaces Total execution time for 1000 simulations on the Tesla platform, while varying the number of simulations for each kernel\relax }}{418}} -\newlabel{ch17:fig:multikernel_graph}{{17.8}{418}} -\@writefile{toc}{\contentsline {subsection}{\numberline {17.5.1}Analysis}{418}} -\@writefile{toc}{\contentsline {subsection}{\numberline {17.5.2}MAS execution workflow}{419}} -\@writefile{toc}{\contentsline {subsection}{\numberline {17.5.3}Implementation challenges}{420}} -\@writefile{toc}{\contentsline {subsection}{\numberline {17.5.4}MCSMA}{420}} -\newlabel{ch17:Mcsma}{{17.5.4}{420}} -\@writefile{toc}{\contentsline {section}{\numberline {17.6}Conclusion}{421}} -\newlabel{ch17:conclusion}{{17.6}{421}} -\@writefile{toc}{\contentsline {section}{Bibliography}{422}} +\newlabel{chapter17}{{18}{418}} +\@writefile{toc}{\contentsline {section}{\numberline {18.1}Introduction}{418}} +\newlabel{ch17:intro}{{18.1}{418}} +\@writefile{toc}{\contentsline {section}{\numberline {18.2}Running Agent-Based Simulations}{419}} +\newlabel{ch17:ABM}{{18.2}{419}} +\@writefile{toc}{\contentsline {subsection}{\numberline {18.2.1}Multi-agent systems and parallelism}{419}} +\@writefile{toc}{\contentsline {subsection}{\numberline {18.2.2}MAS Implementation on GPU}{421}} +\newlabel{ch17:subsec:gpu}{{18.2.2}{421}} +\@writefile{toc}{\contentsline {section}{\numberline {18.3}A first practical example}{422}} +\newlabel{ch17:sec:1stmodel}{{18.3}{422}} +\@writefile{toc}{\contentsline {subsection}{\numberline {18.3.1}The Collembola model}{422}} +\newlabel{ch17:subsec:collembolamodel}{{18.3.1}{422}} +\@writefile{lof}{\contentsline {figure}{\numberline {18.1}{\ignorespaces Evolution algorithm of Collembola model\relax }}{423}} +\newlabel{ch17:fig:collem_algorithm}{{18.1}{423}} +\@writefile{toc}{\contentsline {subsection}{\numberline {18.3.2}Collembola Implementation}{423}} +\newlabel{ch17:listing:collembola-diffuse}{{18.1}{424}} +\@writefile{lol}{\contentsline {lstlisting}{\numberline {18.1}Collembola OpenCL Diffusion kernel}{424}} +\newlabel{ch17:listing:collembola-reduc}{{18.2}{424}} +\@writefile{lol}{\contentsline {lstlisting}{\numberline {18.2}Collembola OpenCL reduction kernel}{424}} +\@writefile{toc}{\contentsline {subsection}{\numberline {18.3.3}Collembola performance}{425}} +\@writefile{lof}{\contentsline {figure}{\numberline {18.2}{\ignorespaces Performance of the Collembola model on CPU and GPU\relax }}{426}} +\newlabel{ch17:fig:mior_perfs_collem}{{18.2}{426}} +\@writefile{toc}{\contentsline {section}{\numberline {18.4}Second example}{426}} +\newlabel{ch17:sec:2ndmodel}{{18.4}{426}} +\@writefile{toc}{\contentsline {subsection}{\numberline {18.4.1}The MIOR model}{426}} +\newlabel{ch17:subsec:miormodel}{{18.4.1}{426}} +\@writefile{loa}{\contentsline {algocf}{\numberline {22}{\ignorespaces Evolution step of each Meta-Mior (microbial colony) agent\relax }}{427}} +\newlabel{ch17:seqalgo}{{22}{427}} +\@writefile{toc}{\contentsline {subsection}{\numberline {18.4.2}MIOR Implementation}{427}} +\@writefile{lof}{\contentsline {figure}{\numberline {18.3}{\ignorespaces Execution distribution retained on GPU\relax }}{428}} +\newlabel{ch17:fig:gpu_distribution}{{18.3}{428}} +\@writefile{toc}{\contentsline {subsubsection}{\numberline {18.4.2.1}Execution mapping on GPU}{428}} +\@writefile{toc}{\contentsline {subsubsection}{\numberline {18.4.2.2}Data structures translation}{429}} +\newlabel{ch17:subsec:datastructures}{{18.4.2.2}{429}} +\newlabel{ch17:listing:mior_data_structures}{{18.3}{429}} +\@writefile{lol}{\contentsline {lstlisting}{\numberline {18.3}Main data structures used in a MIOR simulation}{429}} +\@writefile{lof}{\contentsline {figure}{\numberline {18.4}{\ignorespaces Compact representation of the topology of a MIOR simulation\relax }}{430}} +\newlabel{ch17:fig:csr_representation}{{18.4}{430}} +\@writefile{toc}{\contentsline {subsubsection}{\numberline {18.4.2.3}Critical resources access management}{430}} +\newlabel{ch17:subsec:concurrency}{{18.4.2.3}{430}} +\newlabel{ch17:listing:mior_kernels}{{18.4}{431}} +\@writefile{lol}{\contentsline {lstlisting}{\numberline {18.4}Main MIOR kernel}{431}} +\newlabel{ch17:fig:mior_launcher}{{18.5}{432}} +\@writefile{lol}{\contentsline {lstlisting}{\numberline {18.5}MIOR simulation launcher}{432}} +\@writefile{toc}{\contentsline {subsubsection}{\numberline {18.4.2.4}Termination detection}{432}} +\@writefile{toc}{\contentsline {subsection}{\numberline {18.4.3}Performance of MIOR implementations}{433}} +\newlabel{ch17:subsec:miorexperiments}{{18.4.3}{433}} +\@writefile{lof}{\contentsline {figure}{\numberline {18.5}{\ignorespaces CPU and GPU performance on a Tesla C1060 node\relax }}{434}} +\newlabel{ch17:fig:mior_perfs_tesla}{{18.5}{434}} +\@writefile{lof}{\contentsline {figure}{\numberline {18.6}{\ignorespaces CPU and GPU performance on a personal computer with a Geforce 8800GT\relax }}{435}} +\newlabel{ch17:fig:mior_perfs_8800gt}{{18.6}{435}} +\@writefile{toc}{\contentsline {section}{\numberline {18.5}Analysis and recommendations}{435}} +\newlabel{ch17:analysis}{{18.5}{435}} +\@writefile{lof}{\contentsline {figure}{\numberline {18.7}{\ignorespaces Execution time of one multi-simulation kernel on the Tesla platform\relax }}{436}} +\newlabel{ch17:fig:monokernel_graph}{{18.7}{436}} +\@writefile{lof}{\contentsline {figure}{\numberline {18.8}{\ignorespaces Total execution time for 1000 simulations on the Tesla platform, while varying the number of simulations for each kernel\relax }}{436}} +\newlabel{ch17:fig:multikernel_graph}{{18.8}{436}} +\@writefile{toc}{\contentsline {subsection}{\numberline {18.5.1}Analysis}{436}} +\@writefile{toc}{\contentsline {subsection}{\numberline {18.5.2}MAS execution workflow}{437}} +\@writefile{toc}{\contentsline {subsection}{\numberline {18.5.3}Implementation challenges}{438}} +\@writefile{toc}{\contentsline {subsection}{\numberline {18.5.4}MCSMA}{438}} +\newlabel{ch17:Mcsma}{{18.5.4}{438}} +\@writefile{toc}{\contentsline {section}{\numberline {18.6}Conclusion}{439}} +\newlabel{ch17:conclusion}{{18.6}{439}} +\@writefile{toc}{\contentsline {section}{Bibliography}{440}} \@setckpt{Chapters/chapter17/ch17}{ -\setcounter{page}{426} +\setcounter{page}{444} \setcounter{equation}{0} \setcounter{enumi}{3} \setcounter{enumii}{0} @@ -84,7 +84,7 @@ \setcounter{footnote}{1} \setcounter{mpfootnote}{0} \setcounter{part}{6} -\setcounter{chapter}{17} +\setcounter{chapter}{18} \setcounter{section}{6} \setcounter{subsection}{0} \setcounter{subsubsection}{0} @@ -101,9 +101,9 @@ \setcounter{lstnumber}{21} \setcounter{ContinuedFloat}{0} \setcounter{AlgoLine}{17} -\setcounter{algocfline}{21} -\setcounter{algocfproc}{21} -\setcounter{algocf}{21} +\setcounter{algocfline}{22} +\setcounter{algocfproc}{22} +\setcounter{algocf}{22} \setcounter{nprt@mantissa@digitsbefore}{0} \setcounter{nprt@mantissa@digitsafter}{0} \setcounter{nprt@exponent@digitsbefore}{0} diff --git a/BookGPU/Chapters/chapter18/ch18.aux b/BookGPU/Chapters/chapter18/ch18.aux index cc03727..74a1231 100644 --- a/BookGPU/Chapters/chapter18/ch18.aux +++ b/BookGPU/Chapters/chapter18/ch18.aux @@ -2,45 +2,45 @@ \@writefile{toc}{\author{Rapha\IeC {\"e}l Couturier}{}} \@writefile{toc}{\author{Christophe Guyeux}{}} \@writefile{loa}{\addvspace {10\p@ }} -\@writefile{toc}{\contentsline {chapter}{\numberline {18}Pseudorandom Number Generator on GPU}{427}} +\@writefile{toc}{\contentsline {chapter}{\numberline {19}Pseudorandom Number Generator on GPU}{445}} \@writefile{lof}{\addvspace {10\p@ }} \@writefile{lot}{\addvspace {10\p@ }} -\newlabel{chapter18}{{18}{427}} -\@writefile{toc}{\contentsline {section}{\numberline {18.1}Introduction}{427}} -\@writefile{toc}{\contentsline {section}{\numberline {18.2}Basic Remindees}{429}} -\newlabel{section:BASIC RECALLS}{{18.2}{429}} -\@writefile{toc}{\contentsline {subsection}{\numberline {18.2.1}A Short Presentation of Chaos}{429}} -\@writefile{toc}{\contentsline {subsection}{\numberline {18.2.2}On Devaney's Definition of Chaos}{429}} -\newlabel{sec:dev}{{18.2.2}{429}} -\newlabel{Devaney}{{18.1}{429}} -\@writefile{toc}{\contentsline {subsection}{\numberline {18.2.3}Chaotic iterations}{430}} -\newlabel{subsection:Chaotic iterations}{{18.2.3}{430}} -\newlabel{Chaotic iterations}{{2}{430}} -\newlabel{eq:generalIC}{{18.4}{431}} -\newlabel{equation Oplus}{{18.5}{431}} -\@writefile{toc}{\contentsline {section}{\numberline {18.3}Toward Efficiency and Improvement for CI PRNG}{431}} -\newlabel{sec:efficient PRNG}{{18.3}{431}} -\@writefile{toc}{\contentsline {subsection}{\numberline {18.3.1}First Efficient Implementation of a PRNG based on Chaotic Iterations}{431}} -\newlabel{algo:seqCIPRNG}{{18.1}{431}} -\@writefile{lol}{\contentsline {lstlisting}{\numberline {18.1}C code of the sequential PRNG based on chaotic iterations}{431}} -\@writefile{toc}{\contentsline {subsection}{\numberline {18.3.2}Efficient PRNGs based on Chaotic Iterations on GPU}{432}} -\newlabel{sec:efficient PRNG gpu}{{18.3.2}{432}} -\@writefile{toc}{\contentsline {subsection}{\numberline {18.3.3}Naive Version for GPU}{432}} -\@writefile{loa}{\contentsline {algocf}{\numberline {22}{\ignorespaces Main kernel of the GPU ``naive'' version of the PRNG based on chaotic iterations\relax }}{433}} -\newlabel{algo:gpu_kernel}{{22}{433}} -\@writefile{toc}{\contentsline {subsection}{\numberline {18.3.4}Improved Version for GPU}{433}} -\newlabel{IR}{{23}{434}} -\@writefile{loa}{\contentsline {algocf}{\numberline {23}{\ignorespaces Main kernel for the chaotic iterations based PRNG GPU efficient version\relax }}{434}} -\newlabel{algo:gpu_kernel2}{{23}{434}} -\@writefile{toc}{\contentsline {subsection}{\numberline {18.3.5}Chaos Evaluation of the Improved Version}{434}} -\@writefile{toc}{\contentsline {section}{\numberline {18.4}Experiments}{435}} -\newlabel{sec:experiments}{{18.4}{435}} -\@writefile{toc}{\contentsline {section}{\numberline {18.5}Summary}{435}} -\@writefile{lof}{\contentsline {figure}{\numberline {18.1}{\ignorespaces Quantity of pseudorandom numbers generated per second with the xorlike-based PRNG\relax }}{436}} -\newlabel{fig:time_xorlike_gpu}{{18.1}{436}} -\@writefile{toc}{\contentsline {section}{Bibliography}{437}} +\newlabel{chapter18}{{19}{445}} +\@writefile{toc}{\contentsline {section}{\numberline {19.1}Introduction}{445}} +\@writefile{toc}{\contentsline {section}{\numberline {19.2}Basic Remindees}{447}} +\newlabel{section:BASIC RECALLS}{{19.2}{447}} +\@writefile{toc}{\contentsline {subsection}{\numberline {19.2.1}A Short Presentation of Chaos}{447}} +\@writefile{toc}{\contentsline {subsection}{\numberline {19.2.2}On Devaney's Definition of Chaos}{447}} +\newlabel{sec:dev}{{19.2.2}{447}} +\newlabel{Devaney}{{19.1}{447}} +\@writefile{toc}{\contentsline {subsection}{\numberline {19.2.3}Chaotic iterations}{448}} +\newlabel{subsection:Chaotic iterations}{{19.2.3}{448}} +\newlabel{Chaotic iterations}{{2}{448}} +\newlabel{eq:generalIC}{{19.4}{449}} +\newlabel{equation Oplus}{{19.5}{449}} +\@writefile{toc}{\contentsline {section}{\numberline {19.3}Toward Efficiency and Improvement for CI PRNG}{449}} +\newlabel{sec:efficient PRNG}{{19.3}{449}} +\@writefile{toc}{\contentsline {subsection}{\numberline {19.3.1}First Efficient Implementation of a PRNG based on Chaotic Iterations}{449}} +\newlabel{algo:seqCIPRNG}{{19.1}{449}} +\@writefile{lol}{\contentsline {lstlisting}{\numberline {19.1}C code of the sequential PRNG based on chaotic iterations}{449}} +\@writefile{toc}{\contentsline {subsection}{\numberline {19.3.2}Efficient PRNGs based on Chaotic Iterations on GPU}{450}} +\newlabel{sec:efficient PRNG gpu}{{19.3.2}{450}} +\@writefile{toc}{\contentsline {subsection}{\numberline {19.3.3}Naive Version for GPU}{450}} +\@writefile{loa}{\contentsline {algocf}{\numberline {23}{\ignorespaces Main kernel of the GPU ``naive'' version of the PRNG based on chaotic iterations\relax }}{451}} +\newlabel{algo:gpu_kernel}{{23}{451}} +\@writefile{toc}{\contentsline {subsection}{\numberline {19.3.4}Improved Version for GPU}{451}} +\newlabel{IR}{{24}{452}} +\@writefile{loa}{\contentsline {algocf}{\numberline {24}{\ignorespaces Main kernel for the chaotic iterations based PRNG GPU efficient version\relax }}{452}} +\newlabel{algo:gpu_kernel2}{{24}{452}} +\@writefile{toc}{\contentsline {subsection}{\numberline {19.3.5}Chaos Evaluation of the Improved Version}{452}} +\@writefile{toc}{\contentsline {section}{\numberline {19.4}Experiments}{453}} +\newlabel{sec:experiments}{{19.4}{453}} +\@writefile{toc}{\contentsline {section}{\numberline {19.5}Summary}{453}} +\@writefile{lof}{\contentsline {figure}{\numberline {19.1}{\ignorespaces Quantity of pseudorandom numbers generated per second with the xorlike-based PRNG\relax }}{454}} +\newlabel{fig:time_xorlike_gpu}{{19.1}{454}} +\@writefile{toc}{\contentsline {section}{Bibliography}{455}} \@setckpt{Chapters/chapter18/ch18}{ -\setcounter{page}{439} +\setcounter{page}{457} \setcounter{equation}{5} \setcounter{enumi}{3} \setcounter{enumii}{0} @@ -49,7 +49,7 @@ \setcounter{footnote}{2} \setcounter{mpfootnote}{0} \setcounter{part}{6} -\setcounter{chapter}{18} +\setcounter{chapter}{19} \setcounter{section}{5} \setcounter{subsection}{0} \setcounter{subsubsection}{0} @@ -66,9 +66,9 @@ \setcounter{lstnumber}{15} \setcounter{ContinuedFloat}{0} \setcounter{AlgoLine}{14} -\setcounter{algocfline}{23} -\setcounter{algocfproc}{23} -\setcounter{algocf}{23} +\setcounter{algocfline}{24} +\setcounter{algocfproc}{24} +\setcounter{algocf}{24} \setcounter{nprt@mantissa@digitsbefore}{0} \setcounter{nprt@mantissa@digitsafter}{0} \setcounter{nprt@exponent@digitsbefore}{0} diff --git a/BookGPU/Chapters/chapter4/biblio4.bib b/BookGPU/Chapters/chapter4/biblio4.bib new file mode 100644 index 0000000..14e5ef7 --- /dev/null +++ b/BookGPU/Chapters/chapter4/biblio4.bib @@ -0,0 +1,8 @@ +@unpublished{convolutionsoup, + title = {Convolution Soup}, + author = {Stam, Joe}, + abstract = {Graphics processors can be easily programmed to provide significant acceleration in many common parallel tasks. However, with additional architecture knowledge and understanding of optimization strategies, a savvy programmer can unleash the full potential of the GPU's massive memory bandwidth and ensure the processing resources are utilized to their fullest extent. In this talk, we'll explore several different approaches to a very simple but ubiquitous image processing algorithm, the convolution. A naive approach shows the detrimental impact of poorly written code, a simple approach achieves decent results with little effort or code complexity, and a few highly optimized techniques realize the GPUs full power for the most demanding tasks. The techniques explored in this simple but illustrative example will serve as a base for understanding the optimization strategies to apply towards more complex algorithms.}, + year = {2010}, + month ={8}, + pdf = {http://fr.slideshare.net/NVIDIA/1412-gtc09}, +} \ No newline at end of file diff --git a/BookGPU/Chapters/chapter4/ch4.tex b/BookGPU/Chapters/chapter4/ch4.tex new file mode 100644 index 0000000..ea473a1 --- /dev/null +++ b/BookGPU/Chapters/chapter4/ch4.tex @@ -0,0 +1,389 @@ +\chapterauthor{Gilles Perrot}{FEMTO-ST Institute} + +%\newcommand{\kl}{\includegraphics[scale=0.6]{Chapters/chapter4/img/kernLeft.png}~} +%\newcommand{\kr}{\includegraphics[scale=0.6]{Chapters/chapter4/img/kernRight.png}} + +%% \lstset{ +%% language=C, +%% columns=fixed, +%% basicstyle=\footnotesize\ttfamily, +%% numbers=left, +%% firstnumber=1, +%% numberstyle=\tiny, +%% stepnumber=5, +%% numbersep=5pt, +%% tabsize=3, +%% extendedchars=true, +%% breaklines=true, +%% keywordstyle=\textbf, +%% frame=single, +%% % keywordstyle=[1]\textbf, +%% %identifierstyle=\textbf, +%% commentstyle=\color{white}\textbf, +%% stringstyle=\color{white}\ttfamily, +%% % xleftmargin=17pt, +%% % framexleftmargin=17pt, +%% % framexrightmargin=5pt, +%% % framexbottommargin=4pt, +%% backgroundcolor=\color{lightgray}, +%% } + + +\chapter{Implementing an efficient convolution \index{Convolution} operation on GPU} +\section{Overview} +In this chapter, after dealing with GPU median filter implementations, +we propose to explore how convolutions can be implemented on modern +GPUs. Widely used in digital image processing filters, the \emph{convolution +operation} basically consists in taking the sum of products of elements +from two 2-D functions, letting one of the two functions move over +every element of the other, producing a third function that is typically +viewed as a modified version of one of the original functions. To +begin with, we shall examine non-separable or generic convolutions, +before adressing the matter of separable convolutions. We shall refer +to $I$ as an H x L pixel gray-level image, and to $I(x,y)$ as the gray-level +value of each pixel of coordinates $(x,y)$. +%dire qqs mots sur le filtrage IIR/FIR ? + + +\section{Definition} +Within a digital image $I$, the convolution operation is performed between +image $I$ and convolution mask \emph{h} (To avoid confusion with other +GPU functions referred to as kernels, we shall use\emph{ convolution +mask} instead of \emph{convolution kernel}) is defined by: +\begin{equation} +I'(x, y) = \left(I * h\right) = \sum_{i < H} \sum_{j < L}I(x-j, y-j).h(j,i) +\label{convoDef} +\end{equation} +While processing an image, function \emph{h} is bounded by a square +window of size \emph{k = 2r + 1}, i.e an uneven number, to ensure +there is a center. We shall also point out that, as stated earlier, +the square shape is no limiting factor to the process, as any shape +can be inscribed into a square. In the case of a more complex shape, +the remaining space is filled by null values (padding). + + +\section{Implementation} +The basic principle of computing a convolution between one $I$ picture +and one \emph{h} convolution mask defined on domain $\Omega$ is given +by algorithm \ref{algo_genconv} and illustrated by Figure \ref{fig:convoPrinciple}, which mainly shows how gray-level values of the center pixel's neighborhood are combined with the convolution mask values to compute the output value. +For more readability, only part of the connecting lines are shown. + \begin{figure} +\centering + \includegraphics[width=11cm]{Chapters/chapter4/img/convo1.png} + \caption{Principle of a generic convolution implementation. The center pixel is represented with a black background and the pixels of its neighborhood are denoted $I_{p,q}$ where $(p,q)$ is the relative position of the neighbor pixel. Elements $h_{t,u}$ are the values of the convolution mask.} + \label{fig:convoPrinciple} +\end{figure} +\begin{algorithm} +\caption{generic convolution} +\label{algo_genconv} + \ForEach{pixel at position $(x, y)$}{ + Read all gray-level values $I(x, y)$ in the neighborhood\\\; + Compute the weighted sum \( I_\Omega = \sum_{(j,i) \in \Omega}I(x-j, y-j).h(j,i) \)\\\; + Normalize $I'(x, y)$ value\\\; + Outputs the new gray-level value + } +\end{algorithm} + +The gray-level value of each pixel of output image $I'$ is the weighted +sum of pixels included in the neighborhood defined by $\Omega$ around +the corresponding pixel in the input image. It has to be noted that, +in case the sum $S$ of all coefficients in the mask is not 1, the original +brightness of the image will be altered and a normalization stage +has to take place, as, for example, in the case of an 8-bit coded +image: +\begin{enumerate} +\item if $S \ge 0$ then $I' = I_\Omega / S$ +\item if $S = 0$ then $I' = I_\Omega + 128$ +\item if $S < 0$ then $I' = I_\Omega + 255$ +\end{enumerate} +In case one, normalizing means performing a division operation for +each pixel, which will be quite time-costly when performed on a GPU. A simple work-around is to normalize mask values before using them in GPU kernels. + + +\subsection{First test implementation} +This first implementation consists of a rather naive application to +convolutions of the tuning recipes applied to median filters in the +previous chapter, as a reminder : texture memory used with incoming +data, pinned memory with output data, optimized use of registers +while processing data and multiple output per thread\index{Multiple output per thread}. +One signifcant difference lies in the fact +that the median filter uses only one parameter, the size of the window mask, +which can be hard-coded, while a convolution mask requires referring to several; hard-coding +its elements would lead to severe lack of flexibility (one function +per filter, no external settings) so we will just use it as a starting +point in our approach. + +Let us assume that we are planning to implement the convolution defined by the following $3\times 3$ mask (low-pass filter or averaging filter): +$$h=\begin{bmatrix}1&1&1\\1&1&1\\1&1&1\end{bmatrix}$$ +The kernel code presented in Listing \ref{lst:convoGene3Reg8} implements the convolution operation and applies all above optimizations except, for clarity reasons, multiple output per thread. +In the particular case of a generic convolution, it is important to note how mask coefficients are applied to image pixels in order to fit the definition of equation \ref{convoDef}: if the coordinates of the center pixel had been set to (0,0), then the pixel of coordinates $(i,j)$ would have been multiplied by the element $(-i,-j)$ of the mask, which, transposed in our kernel code, leads to multiply the $p^{th}$ pixel of the window by the $(n-p)^{th}$ element of the convolution mask. + +\lstinputlisting[label={lst:convoGene3Reg8},caption=Generic CUDA kernel achieving a convolution operation with hard-coded mask values]{Chapters/chapter4/code/convoGene3Reg8.cu} + +Table \ref{tab:convoNonSepReg1} shows kernel timings and throughput values for such a low-pass filter extended to $5\times 5$ and $7\times 7$ masks applied on 8-bit coded gray-level +images of sizes $512\times 512$, $1024\times 1024$, $2048\times 2048$, $4096\times 4096$ and run on a C2070 card with $32\times 8$ thread blocks. +As a reminder, Table \ref{tab:memcpy1} details the data transfer costs that helped computing throughput values. + + +\begin{table}[h] +\centering +{\normalsize +\begin{tabular}{|c||r|r|r|r|r|r|} +\hline +\textbf{Mask size$\rightarrow$}&\multicolumn{2}{|c|}{\textbf{3x3}}&\multicolumn{2}{|c|}{\textbf{5x5}}&\multicolumn{2}{|c|}{\textbf{7x7}}\\ +\textbf{Image size$\downarrow$}&time (ms)&TP&time (ms)&TP&time (ms)&TP\\\hline\hline +$\mathbf{512\times 512}$ &0.077&1165 &0.209&559 &0.407 &472 \\\hline +$\mathbf{1024\times 1024}$&0.297&1432 &0.820&836 &1.603 &515 \\\hline +$\mathbf{2048\times 2048}$&1.178&1549 &\bf 3.265&\bf 875 &6.398&529 \\\hline +$\mathbf{4096\times 4096}$&4.700&1585 &13.05&533 &25.56&533 \\\hline +\end{tabular} +} +\caption{Timings ($time$) and throughput values ($TP$ in Mpix/s) of one register-only non separable convolution kernel, for small mask sizes of $3\times 3$, $5\times 5$ and $7\times 7$ pixels, on a C2070 card (fermi architecture). Data transfer duration are those of Table \ref{tab:memcpy1}.} +\label{tab:convoNonSepReg1} +\end{table} + +\begin{table}[h] +\centering +{\normalsize +\begin{tabular}{|c||r|r|r|r|r|r|} +\hline +\textbf{Mask size$\rightarrow$}&\multicolumn{2}{|c|}{\textbf{3x3}}&\multicolumn{2}{|c|}{\textbf{5x5}}&\multicolumn{2}{|c|}{\textbf{7x7}}\\ +\textbf{Image size$\downarrow$}&time (ms)&TP&time (ms)&TP&time(ms)&TP\\\hline\hline +$\mathbf{512\times 512}$ &0.060&1186 &0.148&848 &0.280&594 \\\hline +$\mathbf{1024\times 1024}$&0.209&1407 &0.556&960 &1.080&649 \\\hline +$\mathbf{2048\times 2048}$&0.801&1092 &\bf 2.189&\bf 802 &4.278&573 \\\hline +$\mathbf{4096\times 4096}$&3.171&1075 &8.720&793 &17.076&569 \\\hline +\end{tabular} +} +\caption{Timings ($time$) and throughput values ($TP$ in Mpix/s) of one register-only non separable convolution kernel, for small mask sizes of $3\times 3$, $5\times 5$ and $7\times 7$ pixels, on a GTX280 (GT200 architecture). Data transfer duration are those of Table \ref{tab:memcpy1}.} +\label{tab:convoNonSepReg3} +\end{table} + +\begin{table}[h] +\centering +{\normalsize +\begin{tabular}{|c||r|r|} +\hline +\shortstack{\textbf{GPU card$\rightarrow$}\\\textbf{Image size$\downarrow$}}&\textbf{C2070}&\textbf{GTX280}\\\hline\hline +$\mathbf{512\times 512}$ &0.148 &0.161 \\\hline +$\mathbf{1024\times 1024}$&0.435 &0.536 \\\hline +$\mathbf{2048\times 2048}$&1.530 &3.039 \\\hline +$\mathbf{4096\times 4096}$&5.882 &12.431 \\\hline +\end{tabular} +} +\caption{Time cost of data transfers between CPU and GPU memories, on C2070 and GTX280 cards (in milliseconds).} +\label{tab:memcpy1} +\end{table} + +Table \ref{tab:convoNonSepReg3} shows timings and global throughput values achieved by those convolution masks on an Nvidia GT200 Tesla architecture (GTX480 card) with $16x8$ thread blocks. This measurement has been done in order to make a relevant comparison with a reference given by Nvidia in \cite{convolutionsoup} where they state that their fastest kernel achieves a $5\times5$ convolution of an 8-bit $2048\times 2048$ pixelimage in $1.4~ms$, which lead to a throughput value of 945~Mpix/s. +Our current value of 802~Mpix/s, though not unsatisfactory, remains lower to the one reached by the manufacturer'own coding. +Tested in the same conditions, the newer Fermi architecture of +Nvidia's GPUs proved slower (3.3 ms, see Table \ref{tab:convoNonSepReg1}) due to the lower maximum +register count allowed (63, against 128 for Tesla GT200). + +It is interesting to note that, as long as each thread processes one single pixel, kernel execution time is ruled in proportion +with the number of pixels in the image multiplied by that of the mask. +The slope in this first implementaion is $3.14.10^{-8}~ms/pix$ on C2070. + +\subsection{Using parameterizable masks} + +To further improve the above implementation, it becomes necessary +to free ourselves from the hard-coding constraint. To achieve this, +as was the case with input image storing, several memory options are +available, but, since the amount of data involved in processing a +mask is quite small and constant, we considered it relevant to copy data +into \emph{symbol memory}. Listing \ref{lst:symbolmem} details the process, involving +the Cuda function \emph{CudaMemCopyToSymbol()}. + +\lstinputlisting[label={lst:symbolmem},caption=code snippet showing how to setup a mask in GPU symbol memory]{Chapters/chapter4/code/maskInSymbol.cu} + +In parallel, giving up the register-only constraint allows a more +conventional coding practice (loops). Listing \ref{lst:convoGene8r} presents +a generic convolution kernel, whose code immediately +appears both simple and concise. Its global time +performance, however, is comparatively lower than the register-only +process, due to the use of constant memory and of the \emph{r} parameter +(radius of the mask). The average slope amounts to $3.81~ms/pix$ on C2070, +which means a time-cost increase of around $20~\%$. + +\lstinputlisting[label={lst:convoGene8r},caption=Generic CUDA kernel achieving a convolution operation with the mask in symbol memory and its radius passed as a parameter]{Chapters/chapter4/code/convoGene8r.cu} + +\subsection{Increasing the number of pixels processed by each thread} +Much in the same way as we did with the Median Filter, we shall now +attempt to reduce the average latency due to writes into global memory +by having each thread process more than one output value. As the basic +structure of the above GPU kernel uses only 14 registers per thread, regardless +of the size of the convolution mask, one can envisage processing 2 +or more pixels per thread while keeping safely within the 63-per-thread +rule. + +However, when doing so, \textit{eg} processing what we shall call a \textit{packet} of pixels, window mask overlapping has to be taken into account +to avoid multiple texture fetches of each pixel's gray-level value, while benefiting from the 2-D cache. +In that case, both mask size and pixel packet shape determine the number of texture fetches to be performed for each pixel value. +Figure \ref{fig:convoOverlap1} illustrates two different situations: on top, a mask of radius 1 ($3\times 3$) applied to a packet of 8 pixels in row; at bottom, a mask of radius 2 ($5\times 5$). +The dark gray pixels are the center pixels (pixels of the packet), while light gray pixels belong to the halo around the packet. The number in each pixel box corresponds to the convolution count in which it is involved. +There would be little interest in using different \textit{packet} shapes, as the final global memory writes would not be coalescent; generating multiple latencies. + \begin{figure} +\centering + \subfigure[$3\times 3$ mask: there are 18 center pixels (out of 30) involved in 3 computations.]{ \includegraphics[width=5.8cm]{Chapters/chapter4/img/convoOverlap1.png}}\\ + \subfigure[$5\times 5$ mask: only 20 center pixels (out of 60), involved in 5 computations.]{ \includegraphics[width=7cm]{Chapters/chapter4/img/convoOverlap2.png}} + \caption{Mask window overlapping when processing 8 pixels per thread. Top: $3\times 3$ mask. Bottom: $5\times 5$ mask.} + \label{fig:convoOverlap1} +\end{figure} + +Altough we actually wrote GPU kernels able to process 2, 4, 8 and 16 pixels per thread, only the one that processes 8 pixels per thread is presented below, as it proved to be the fastest one. Listing \ref{lst:convoGene8x8pL3} reproduce the source code of the kernel for $3\times 3$ masks. +The bottom line is that each thread is associated with one base pixel of coordinates $(x,y)$ which is the first of the packet to be processed, the last one being $(x+7,y)$. +\lstinputlisting[label={lst:convoGene8x8pL3},caption=CUDA kernel achieving a $3\times 3$ convolution operation with the mask in symbol memory and direct data fetches in texture memory]{Chapters/chapter4/code/convoGene8x8pL3.cu} + +In this particular case of a $3\times 3$ mask, each pixel value is used in 3 different convolution sums, except pixels located near both ends of the packet, whose values are used in fewer sums. +The general rule, when performing a $n\times n$ convolution (radius $k$) by 8-pixel packets is that each of the $(8-2k).(2k+1)$ \textit{center} pixels of the halo is used in $k$ sums, while the $4k.(2k+1)$ remaining pixels, located around the ends of the packet are used in fewer sums, from $k-1$ to $1$ ($2.(2k+1)$ pixels each). +\begin{table}[h] +\centering +{\normalsize +\begin{tabular}{|c||r|r|r|r|r|r|} +\hline +\textbf{Mask size$\rightarrow$}&\multicolumn{2}{|c|}{\textbf{3x3}}&\multicolumn{2}{|c|}{\textbf{5x5}}&\multicolumn{2}{|c|}{\textbf{7x7}}\\ +\textbf{Image size$\downarrow$}&time (ms)&TP&time (ms)&TP&time (ms)&TP\\\hline\hline +$\mathbf{512\times 512}$ &0.036&1425 &0.069&1208 &0.110&1016 \\\hline +$\mathbf{1024\times 1024}$&0.128&1862 &0.253&1524 &0.413&1237 \\\hline +$\mathbf{2048\times 2048}$&0.495&2071 &\bf 0.987&1666 &1.615&1334 \\\hline +$\mathbf{4096\times 4096}$&1.964&2138 &3.926&1711 &6.416&1364 \\\hline +\end{tabular} +} +\caption{Timings ($time$) and throughput values ($TP$ in Mpix/s) of our generic fixed mask size convolution kernel run on a C2070 card. Data transfer durations are those of Table \ref{tab:memcpy1}.} +\label{tab:convoGene8x8p} +\end{table} + +Timing results and throughput values are shown in Table \ref{tab:convoGene8x8p}, and show that this solution now outperforms Nvidia references. +It is important to remember that the above kernels have been optimized for the Fermi architecture, unlike those mentioned earlier, which were more efficient on the GT200 architecture. +However, our technique requires to write one kernel per mask size, which can be seen as a major constraint. To make it easier to use this method, we shall propose a kernel code generator that will be available in the near future. + +\subsection{Using shared memory to store prefetched data\index{Prefetching}.} + \index{memory~hierarchy!shared~memory} +A more convenient way of coding a convolution kernel is to use shared memory to perform a prefetching stage of the whole halo before computing the convolution sums. +This proves to be quite efficient and more versatile, but it obviously generates some overhead as: +\begin{itemize} +\item Each pixel value has to be read at least twice, first from texture memory into shared memory and then one or several more times from shared memory to be used in convolution computations. +\item Reducing the number of times a single pixel value is read from shared memory is bound to generate bank conflicts, hence once again performance loss. +\end{itemize} + \begin{figure} +\centering + \includegraphics[width=12cm]{Chapters/chapter4/img/convoShMem.png} + \caption{Organization of the prefetching stage of data, for a $5\times 5$ mask and a thread block size of $8\times 4$. Threads in both top corners of the top figure are identified either by a circle or by a star symbol. The image tile, loaded into shared memory includes the pixels to be updated by the threads of the block, as well as its 2-pixel wide halo. Here, circle and star symbols in the image tile show which pixels are actually loaded into one shared memory vector by its corresponding thread. } + \label{fig:ShMem1} +\end{figure} +Still, we also implemented this method, in a similar manner as Nvidia did in its SDK sample code. +Some improvement has been obtained by increasing the number of pixels processed by each thread, to an optimum 8 pixels per thread. +The principle is to prefetch all pixel values involved in the computations performed by all threads of a block, including 8 pixels per thread plus the halo of radius $r$ (the radius of the convolution mask). As this obviously represents more values than the thread count in one block, some threads have to load more than one value. +The general organization is reproduced in Figure \ref{fig:ShMem1} for $5\times 5$ mask and a $8\times 4$ thread block, while Listing \ref{lst:convoGeneSh1} gives the details of the implementation with its two distinct code blocks: preload in shared memory (Lines 20 to 42) and convolution computations (Lines 45 to 57). +Table \ref{tab:convoGeneSh1} details timing results of this implementation ($16\times 8$ threads/block), up to $13\times 13$ masks, that will serve as a reference in the next section, devoted to separable convolution. +\begin{table}[h] +\centering +{\normalsize +\begin{tabular}{|c||r|r|r|r|r|r|} +\hline +\shortstack{\textbf{Mask size$\rightarrow$}\\\textbf{Image size$\downarrow$}}&\textbf{3x3}&\textbf{5x5}&\textbf{7x7}&\textbf{9x9}&\textbf{11x11}&\textbf{13x13}\\\hline\hline +$\mathbf{512\times 512}$ &0.040 &0.075 &0.141 &0.243&0.314&0.402\\\hline +$\mathbf{1024\times 1024}$&0.141 &0.307 &0.524 &0.917&1.192&1.535\\\hline +$\mathbf{2048\times 2048}$&0.543 &\bf 1.115&2.048 &3.598&4.678&6.037\\\hline +$\mathbf{4096\times 4096}$&2.146 &4.364 &8.156 &14.341&18.652&24.020\\\hline +\end{tabular} +} +\caption{Performances, in milliseconds, of our generic 8 pixels per thread kernel using shared memory, run on a C2070 card.} +\label{tab:convoGeneSh1} +\end{table} +\begin{table}[h] +\centering +{\normalsize +\begin{tabular}{|c||r|r|r|r|r|r|} +\hline +\shortstack{\textbf{Mask size$\rightarrow$}\\\textbf{Image size$\downarrow$}}&\textbf{3x3}&\textbf{5x5}&\textbf{7x7}&\textbf{9x9}&\textbf{11x11}&\textbf{13x13}\\\hline\hline +$\mathbf{512\times 512}$ &1394 &1176 &907 &670&567&477\\\hline +$\mathbf{1024\times 1024}$&1820 &1413 &1093 &776&644&532\\\hline +$\mathbf{2048\times 2048}$&2023 &\bf 1586 &1172 &818&676&554\\\hline +$\mathbf{4096\times 4096}$&2090 &1637 &1195 &830&684&561\\\hline +\end{tabular} +} +\caption{Throughput values, in MegaPixel per second, of our generic 8 pixels per thread kernel using shared memory, run on a C2070 card. Data transfer durations are those of Table \ref{tab:memcpy1}.} +\label{tab:convoGeneSh2} +\end{table} +\lstinputlisting[label={lst:convoGeneSh1},caption=CUDA kernel achieving a generic convolution operation after a preloading of data in shared memory.]{Chapters/chapter4/code/convoGeneSh1.cu} + +\section{Separable convolution} +A convolution operation is said separable when its masks $h$ is the product of 2 vectors $h_v$ and $h_h$, as is the case in the following example: +$$h = h_v \times h_h = \begin{bmatrix}1\\2\\1\end{bmatrix} \times \begin{bmatrix}-1&2&-1\end{bmatrix} = \begin{bmatrix} +-1&2&-1\\ +-2&4&-2\\ +-1&2&-1 +\end{bmatrix}$$ +Such a mask allows to replace a generic 2-D convolution operation by two consecutive stages of a 1-D convolution operation: a vertical of mask $h_v$ and a horizontal of mask $h_h$. +This saves a lot of arithmetic operations, as a generic $n\times n$ convolution applied on a $H\times L$ image basically represents $H.L.n^2$ multiplications and as many additions, while two consecutive $n\times 1$ convolutions only represents $2.H.L.n$ of each, \textit{eg} 60\% operations are saved per pixel of the image for a $5\times 5$ mask.\\ +However, beside reducing the operation count, performing a separable convolution also means writing an intermediate image into global memory. +CPU implementations of separable convolutions often use a single function to perform both 1-D convolution stages. To do so, this function reads the input image and actually ouputs the transposed filtered image. +Applying that principle to GPUs is not efficient, as outputting the transposed image means non-coalescent writes into global memory, generating severe performance loss. Hence the idea of developing two different kernels, one for each of both vertical and horizontal convolutions. + +Here, the use of Shared memory is the best choice, as there is no overlapping between neighbor windows and thus no possible optimization. +Moreover, to ensure efficiency, it is important to read the input image from texture memory, which implies an internal GPU data copy between both 1-D convolution stages. +Which, even if it is faster than CPU/GPU data transfer, makes separable convolutions slower than generic convolutions for small mask sizes. On C2070, the lower limit is $7\times 7$ pixels ($9\times 9$ for $512\times 512$ images). + +Both vertical and horizontal kernels feature similar runtimes: Table \ref{tab:convoSepSh1} only contains their average execution time, including the internal data copy stage, while Table \ref{tab:convoSepSh2} shows the achieved global throughput values. Timings of the data copy stage are given in Table \ref{tab:cpyToArray}. +Listings \ref{lst:convoSepShV} and \ref{lst:convoSepShH} detail the implementation of both 1-D kernels, while Listing \ref{lst:convoSepSh} shows how to use them in addition with the data copy function in order to achieve a whole separable convolution. The shared memory size is dynamically passed as a parameter at kernel call time. Its expression is given in the comment line before its declaration. +\begin{table}[h] +\centering +{\normalsize +\begin{tabular}{|c||r|} +\hline +\textbf{Image size}&\textbf{C2070}\\\hline\hline +$\mathbf{512\times 512}$ &0.029 \\\hline +$\mathbf{1024\times 1024}$&0.101 \\\hline +$\mathbf{2048\times 2048}$&0.387 \\\hline +$\mathbf{4096\times 4096}$&1.533 \\\hline +\end{tabular} +} +\caption{Time cost of data copy between the vertical and the horizontal 1-D convolution stages, on a C2070 cards (in milliseconds).} +\label{tab:cpyToArray} +\end{table} +\begin{table}[h] +\centering +{\normalsize +\begin{tabular}{|c||r|r|r|r|r|r|} +\hline +\shortstack{\textbf{Mask size$\rightarrow$}\\\textbf{Image size$\downarrow$}}&\textbf{3x3}&\textbf{5x5}&\textbf{7x7}&\textbf{9x9}&\textbf{11x11}&\textbf{13x13}\\\hline\hline +$\mathbf{512\times 512}$ &0.080 &0.087 &0.095 &\bf 0.108&\bf 0.115&\bf 0.126\\\hline +$\mathbf{1024\times 1024}$&0.306 &0.333 &\bf 0.333 &\bf 0.378&\bf 0.404&\bf 0.468\\\hline +$\mathbf{2048\times 2048}$&1.094 &1.191 &\bf 1.260 &\bf 1.444&\bf 1.545&\bf 1.722\\\hline +$\mathbf{4096\times 4096}$&4.262 &4.631 &\bf 5.000 &\bf 5.676&\bf 6.105&\bf 6.736\\\hline +\end{tabular}} +\caption{Performances, in milliseconds, of our generic 8 pixels per thread 1-D convolution kernels using shared memory, run on a C2070 card. Timings include data copy. Bold values correspond to situations where separable-convolution kernels run faster than non separable ones.} +\label{tab:convoSepSh1} +\end{table} +\begin{table}[h] +\centering +{\normalsize +\begin{tabular}{|c||r|r|r|r|r|r|} +\hline +\shortstack{\textbf{Mask size$\rightarrow$}\\\textbf{Image size$\downarrow$}}&\textbf{3x3}&\textbf{5x5}&\textbf{7x7}&\textbf{9x9}&\textbf{11x11}&\textbf{13x13}\\\hline\hline +$\mathbf{512\times 512}$ &1150 &1116 &1079 &\bf 1024&\bf 997 &\bf 957\\\hline +$\mathbf{1024\times 1024}$&1415 &1365 &\bf 1365 &\bf 1290&\bf 1250&\bf 1169\\\hline +$\mathbf{2048\times 2048}$&1598 &1541 &\bf 1503 &\bf 1410&\bf 1364&\bf 1290\\\hline +$\mathbf{4096\times 4096}$&1654 &1596 &\bf 1542 &\bf 1452&\bf 1400&\bf 1330\\\hline +\end{tabular} +} +\caption{Throughput values, in MegaPixel per second, of our generic 8 pixels per thread 1-D convolution kernel using shared memory, run on a C2070 card. Data transfer durations are those of Table \ref{tab:memcpy1}.} +\label{tab:convoSepSh2} +\end{table} + +\lstinputlisting[label={lst:convoSepSh},caption=data copy between the calls to 1-D convolution kernels achieving a 2-D separable convolution operation.]{Chapters/chapter4/code/convoSepSh.cu} +\lstinputlisting[label={lst:convoSepShV},caption=CUDA kernel achieving a horizontal 1-D convolution operation after a preloading \index{Prefetching} of data in shared memory.]{Chapters/chapter4/code/convoSepShV.cu} +\lstinputlisting[label={lst:convoSepShH},caption=CUDA kernel achieving a vertical 1-D convolution operation after a preloading of data in shared memory.]{Chapters/chapter4/code/convoSepShH.cu} + +\section{Conclusion} +Extensively detailing the various techniques that may be applied when designing a median or a convolution operation on GPU has enabled us determine that: +\begin{itemize} +\item the use of registers with direct data fetching from texture often allows kernels to run faster than those which use the more conventionnal way of prefetching data from texture memory and storing them into shared memory. +\item increasing the pixel count processed by each thread brings important speedups. In this case, if neighboring windows overlap, optimized direct data fetching from texture will likely outperform the shared memory prefetching technique. That is the case for generic convolution kernels. +\item coding such optimized data fetching is not straightforward. Consequently, we are planning to provide a kernel code generator that will make our kernels more accessible by GPU users. +\end{itemize} +The presented kernels, optimized for a C2070 card, achieve up to 2138~Mpix/s including data transfers, which comes close to the absolute maximum throughput value allowed by the Fermi architecture. The next GPU generation (Kepler) may allow us not only to benefit from new dynamic parallelism capability to increase kernel paralelism level, but also to take advantage of an increase of the register count allowed per thread block which would allow us, for example, to extend our register-only median filter technique to larger mask sizes. + +\putbib[Chapters/chapter4/biblio4] diff --git a/BookGPU/Chapters/chapter4/code/convoGene3Reg8.cu b/BookGPU/Chapters/chapter4/code/convoGene3Reg8.cu new file mode 100755 index 0000000..ba5ea2e --- /dev/null +++ b/BookGPU/Chapters/chapter4/code/convoGene3Reg8.cu @@ -0,0 +1,31 @@ +__global__ void kernel_convoGene3Reg8( unsigned char *output, int j_dim) +{ + float outval0=0.0 ; + float n0,n1,n2,n3,n4,n5,n6,n7,n8 ; + // convolution mask values + n0 = (1.0/9) ; + n1 = (1.0/9) ; + n2 = (1.0/9) ; + n3 = (1.0/9) ; + n4 = (1.0/9) ; + n5 = (1.0/9) ; + n6 = (1.0/9) ; + n7 = (1.0/9) ; + n8 = (1.0/9) ; + + // absolute base point coordinates + int j = __mul24(blockIdx.x, blockDim.x) + threadIdx.x ; + int i = __mul24(blockIdx.y, blockDim.y) + threadIdx.y ; + // weighted sum + outval0 = n8*tex2D(tex_img_inc, j-1, i-1 ) + + n7*tex2D(tex_img_inc, j , i-1 ) + + n6*tex2D(tex_img_inc, j+1, i-1 ) + + n5*tex2D(tex_img_inc, j-1, i ) + + n4*tex2D(tex_img_inc, j , i ) + + n3*tex2D(tex_img_inc, j+1, i ) + + n2*tex2D(tex_img_inc, j-1, i+1 ) + + n1*tex2D(tex_img_inc, j , i+1 ) + + n0*tex2D(tex_img_inc, j+1, i+1 ) ; + + output[ __mul24(i, j_dim) + j ] = (unsigned char) outval0 ; +} diff --git a/BookGPU/Chapters/chapter4/code/convoGene3Reg8.cu~ b/BookGPU/Chapters/chapter4/code/convoGene3Reg8.cu~ new file mode 100755 index 0000000..255feb5 --- /dev/null +++ b/BookGPU/Chapters/chapter4/code/convoGene3Reg8.cu~ @@ -0,0 +1,31 @@ +__global__ void kernel_convoGene3Reg8( unsigned char *output, int i_dim, int j_dim) +{ + float outval0=0.0 ; + float n0,n1,n2,n3,n4,n5,n6,n7,n8 ; + // convolution mask values + n0 = (1.0/9) ; + n1 = (1.0/9) ; + n2 = (1.0/9) ; + n3 = (1.0/9) ; + n4 = (1.0/9) ; + n5 = (1.0/9) ; + n6 = (1.0/9) ; + n7 = (1.0/9) ; + n8 = (1.0/9) ; + + // absolute base point coordinates + int j = __mul24(blockIdx.x, blockDim.x) + threadIdx.x ; + int i = __mul24(blockIdx.y, blockDim.y) + threadIdx.y ; + // weighted sum + outval0 = n8*tex2D(tex_img_inc, j-1, i-1 ) + + n7*tex2D(tex_img_inc, j , i-1 ) + + n6*tex2D(tex_img_inc, j+1, i-1 ) + + n5*tex2D(tex_img_inc, j-1, i ) + + n4*tex2D(tex_img_inc, j , i ) + + n3*tex2D(tex_img_inc, j+1, i ) + + n2*tex2D(tex_img_inc, j-1, i+1 ) + + n1*tex2D(tex_img_inc, j , i+1 ) + + n0*tex2D(tex_img_inc, j+1, i+1 ) ; + + output[ __mul24(i, j_dim) + j ] = (unsigned char) outval0 ; +} diff --git a/BookGPU/Chapters/chapter4/code/convoGene8r.cu b/BookGPU/Chapters/chapter4/code/convoGene8r.cu new file mode 100644 index 0000000..349a9eb --- /dev/null +++ b/BookGPU/Chapters/chapter4/code/convoGene8r.cu @@ -0,0 +1,18 @@ +__global__ void kernel_convoGene8r( unsigned char *output, int j_dim, int r) +{ + int ic, jc ; + int k=2*r+1 ; + float outval0=0.0 ; + + // absolute coordinates of base point + int j = __umul24( blockIdx.x, blockDim.x ) + threadIdx.x ; + int i = __umul24( blockIdx.y, blockDim.y) + threadIdx.y ; + + // convolution computation + for (ic=-r ; ic<=r ; ic++) + for(jc=-r ; jc<=r ; jc++) + outval0 += mask[ __umul24(ic,k)+jc+r ] + *tex2D(tex_img_inc, j+jc, i+ic) ; + + output[ __umul24(i, j_dim) + j ] = outval0 ; +} diff --git a/BookGPU/Chapters/chapter4/code/convoGene8r.cu~ b/BookGPU/Chapters/chapter4/code/convoGene8r.cu~ new file mode 100644 index 0000000..612e09f --- /dev/null +++ b/BookGPU/Chapters/chapter4/code/convoGene8r.cu~ @@ -0,0 +1,18 @@ +__global__ void kernel_convoGene8r( unsigned char *output, int j_dim, int r) +{ + int ic, jc ; + int L=2*r+1 ; + float outval0=0.0 ; + + // absolute coordinates of base point + int j = __umul24( blockIdx.x, blockDim.x ) + threadIdx.x ; + int i = __umul24( blockIdx.y, blockDim.y) + threadIdx.y ; + + // convolution computation + for (ic=-r ; ic<=r ; ic++) + for(jc=-r ; jc<=r ; jc++) + outval0 += masque[ __umul24(ic,L)+jc+r ] + *tex2D(tex_img_inc, j+jc, i+ic) ; + + output[ __umul24(i, j_dim) + j ] = outval0 ; +} diff --git a/BookGPU/Chapters/chapter4/code/convoGene8x8pL3.cu b/BookGPU/Chapters/chapter4/code/convoGene8x8pL3.cu new file mode 100644 index 0000000..ce619d7 --- /dev/null +++ b/BookGPU/Chapters/chapter4/code/convoGene8x8pL3.cu @@ -0,0 +1,62 @@ +__global__ void kernel_convoGene8x8pL3( unsigned char *output, int j_dim ) +{ + int ic, jc ; + const int k=3 ; + unsigned char pix ; + float outval0=0.0, outval1=0.0, outval2=0.0, outval3=0.0 ; + float outval4=0.0, outval5=0.0, outval6=0.0, outval7=0.0 ; + + // coordonnees absolues du point de base en haut a gauche + int j = ( __umul24( blockIdx.x, blockDim.x) + threadIdx.x)<< 3 ; + int i = ( __umul24( blockIdx.y, blockDim.y) + threadIdx.y) ; + + // center pixels + for (ic=0 ; ic ((2*r+1)*(2*r+1))>>1 ) break ; + } + output[ __mul24(i, j_dim) +j ] = ic ; +} diff --git a/BookGPU/Chapters/chapter4/code/convoGeneSh1.cu b/BookGPU/Chapters/chapter4/code/convoGeneSh1.cu new file mode 100644 index 0000000..53d9ba4 --- /dev/null +++ b/BookGPU/Chapters/chapter4/code/convoGeneSh1.cu @@ -0,0 +1,69 @@ +__global__ void kernel_convoNonSepSh_8p(unsigned char *output, int j_dim, int r) +{ + int ic, jc; + int k = 2*r+1 ; + float outval0=0.0, outval1=0.0, outval2=0.0, outval3=0.0, outval4=0.0, outval5=0.0, outval6=0.0, outval7=0.0 ; + int bdimX = blockDim.x<<3 ; + int tidX = threadIdx.x<<3 ; + + // absolute coordinates of packet's base point + int j = (__umul24(blockIdx.x,blockDim.x) + threadIdx.x) << 3 ; + int i = __umul24( blockIdx.y, blockDim.y) + threadIdx.y ; + int j0= __umul24(blockIdx.x,blockDim.x)<<3 ; // block's base point + int idx = __umul24(i,j_dim) + j ; // absolute index + int idrow = threadIdx.y*(bdimX+k-1) ; // line's offset in sh mem + + // shared memory declaration + extern __shared__ unsigned char roi8p[]; + + // top left + for (int p=0; p<8; p++) + roi8p[ idrow + tidX +p ] = tex2D(tex_img_inc, j-r+p , i-r) ; + + // top right + if ( threadIdx.x < r ) + { + roi8p[ idrow + bdimX + threadIdx.x ] = tex2D( tex_img_inc, j0-r +bdimX+threadIdx.x , i-r ) ; + roi8p[ idrow + bdimX + threadIdx.x +r ] = tex2D( tex_img_inc, j0 +bdimX+threadIdx.x , i-r ) ; + } + // bottom left + if ( threadIdx.y < k-1 ) + { + idrow = (threadIdx.y+blockDim.y)*(bdimX+k-1) ; + for (int p=0; p<8; p++) + roi8p[ idrow + tidX +p ] = tex2D( tex_img_inc, j-r+p , i+blockDim.y-r ) ; + // bottom right + if ( threadIdx.x < r ) + { + roi8p[ idrow + bdimX +threadIdx.x ] = tex2D( tex_img_inc, j0-r +bdimX +threadIdx.x, i+blockDim.y-r ) ; + roi8p[ idrow + bdimX +threadIdx.x +r] = tex2D( tex_img_inc, j0 +bdimX +threadIdx.x, i+blockDim.y-r ) ; + } + } + __syncthreads(); + + // computations + for (ic=0 ; ic global mem + output[ idx++ ] = outval0 ; + output[ idx++ ] = outval1 ; + output[ idx++ ] = outval2 ; + output[ idx++ ] = outval3 ; + output[ idx++ ] = outval4 ; + output[ idx++ ] = outval5 ; + output[ idx++ ] = outval6 ; + output[ idx++ ] = outval7 ; +} diff --git a/BookGPU/Chapters/chapter4/code/convoGeneSh1.cu~ b/BookGPU/Chapters/chapter4/code/convoGeneSh1.cu~ new file mode 100644 index 0000000..46e2120 --- /dev/null +++ b/BookGPU/Chapters/chapter4/code/convoGeneSh1.cu~ @@ -0,0 +1,69 @@ +__global__ void kernel_convoNonSepSh_8p(unsigned char *output, int j_dim, int r) +{ + int ic, jc; + int k = 2*r+1 ; + float outval0=0.0, outval1=0.0, outval2=0.0, outval3=0.0, outval4=0.0, outval5=0.0, outval6=0.0, outval7=0.0 ; + int bdimX = blockDim.x<<3 ; + int tidX = threadIdx.x<<3 ; + + // absolute coordinates of packet's base point + int j = (__umul24(blockIdx.x,blockDim.x) + threadIdx.x) << 3 ; + int i = __umul24( blockIdx.y, blockDim.y) + threadIdx.y ; + int j0= __umul24(blockIdx.x,blockDim.x)<<3 ; // block's base point + int idx = __umul24(i,j_dim) + j ; // absolute index + int idrow = threadIdx.y*(bdimX+k-1) ; // line's offset in sh mem + + // shared memory declaration + extern __shared__ unsigned char roi8p[]; + + // top left + for (int p=0; p<8; p++) + roi8p[ idrow + tidX +p ] = tex2D(tex_img_inc, j-r+p , i-r) ; + + // top right + if ( threadIdx.x < r ) + { + roi8p[ idrow + bdimX + threadIdx.x ] = tex2D( tex_img_inc, j0-r +bdimX+threadIdx.x , i-r ) ; + roi8p[ idrow + bdimX + threadIdx.x +r ] = tex2D( tex_img_inc, j0 +bdimX+threadIdx.x , i-r ) ; + } + // bottom left + if ( threadIdx.y < k-1 ) + { + idrow = (threadIdx.y+blockDim.y)*(bdimX+k-1) ; + for (int p=0; p<8; p++) + roi8p[ idrow + tidX +p ] = tex2D( tex_img_inc, j-r+p , i+blockDim.y-r ) ; + // bottom right + if ( threadIdx.x < r ) + { + roi8p[ idrow + bdimX +threadIdx.x ] = tex2D( tex_img_inc, j0-r +bdimX +threadIdx.x, i+blockDim.y-r ) ; + roi8p[ idrow + bdimX +threadIdx.x +r] = tex2D( tex_img_inc, j0 +bdimX +threadIdx.x, i+blockDim.y-r ) ; + } + } + __syncthreads(); + + // computations + for (ic=0 ; ic global mem + output[ idx ] = outval0 ; + output[ idx+1 ] = outval1 ; + output[ idx+2 ] = outval2 ; + output[ idx+3 ] = outval3 ; + output[ idx+4 ] = outval4 ; + output[ idx+5 ] = outval5 ; + output[ idx+6 ] = outval6 ; + output[ idx+7 ] = outval7 ; +} diff --git a/BookGPU/Chapters/chapter4/code/convoGeneSh1~ b/BookGPU/Chapters/chapter4/code/convoGeneSh1~ new file mode 100644 index 0000000..386b586 --- /dev/null +++ b/BookGPU/Chapters/chapter4/code/convoGeneSh1~ @@ -0,0 +1,73 @@ +__global__ void kernel_convoNonSepSh_8p(unsigned char *output, int i_dim, int j_dim, int r) +{ + int idb, ic, jc; + int L = 2*r+1 ; + float outval0=0.0, outval1=0.0, outval2=0.0, outval3=0.0, outval4=0.0, outval5=0.0, outval6=0.0, outval7=0.0 ; + int bdimX = blockDim.x<<3 ; + int tidX = threadIdx.x<<3 ; + + // coordonnees absolues du point de base + int j = (__umul24(blockIdx.x,blockDim.x) + threadIdx.x)<<3 ; + int i = __umul24( blockIdx.y, blockDim.y) + threadIdx.y ; + int j0= __umul24(blockIdx.x,blockDim.x)<<3 ; + + int idx = __umul24(i,j_dim) + j ; // indice dans l'image + + + // chargement en smem + int idrow = threadIdx.y*(bdimX+L-1) ; + + extern __shared__ unsigned char roi8p[]; + + // bloc 0 (en haut à gauche) + for (int p=0; p<8; p++) + roi8p[ idrow + tidX +p ] = tex2D(tex_img_inc, j-r+p , i-r) ; + + // bloc 1 (en haut à droite)... + if ( threadIdx.x < r ) //...ou plutot ce qu'il en manque + { + roi8p[ idrow + bdimX + threadIdx.x ] = tex2D( tex_img_inc, j0-r +bdimX+threadIdx.x , i-r ) ; + roi8p[ idrow + bdimX + threadIdx.x +r ] = tex2D( tex_img_inc, j0 +bdimX+threadIdx.x , i-r ) ; + } + // bloc 2 ( en bas à gauche) + if ( threadIdx.y < L-1 ) + { + idrow = (threadIdx.y+blockDim.y)*(bdimX+L-1) ; + for (int p=0; p<8; p++) + roi8p[ idrow + tidX +p ] = tex2D( tex_img_inc, j-r+p , i+blockDim.y-r ) ; + + //bloc 4 ( en bas à doite )... + if ( threadIdx.x < r ) //...ou ce qu'il en manque + { + roi8p[ idrow + bdimX +threadIdx.x ] = tex2D( tex_img_inc, j0-r +bdimX +threadIdx.x, i+blockDim.y-r ) ; + roi8p[ idrow + bdimX +threadIdx.x +r] = tex2D( tex_img_inc, j0 +bdimX +threadIdx.x, i+blockDim.y-r ) ; + } + } + __syncthreads(); + + // calculs de convolution + for (ic=0 ; ic global mem + output[ idx ] = outval0 ; + output[ idx+1 ] = outval1 ; + output[ idx+2 ] = outval2 ; + output[ idx+3 ] = outval3 ; + output[ idx+4 ] = outval4 ; + output[ idx+5 ] = outval5 ; + output[ idx+6 ] = outval6 ; + output[ idx+7 ] = outval7 ; +} diff --git a/BookGPU/Chapters/chapter4/code/convoSepSh.cu b/BookGPU/Chapters/chapter4/code/convoSepSh.cu new file mode 100644 index 0000000..2688ecd --- /dev/null +++ b/BookGPU/Chapters/chapter4/code/convoSepSh.cu @@ -0,0 +1,6 @@ +dimGrid = dim3( (L/dimBlock.x)/8, H/dimBlock.y, 1 ) ; + +kernel_convoSepShx8pV<<< dimGrid, dimBlock, 8*dimBlock.x*(dimBlock.y+2*r)*sizeof(char) >>>(d_outc, L, r ); +cudaMemcpyToArray( array_img_inc, 0, 0, d_outc, H*L*sizeof(char) , cudaMemcpyDeviceToDevice) ; +kernel_convoSepShx8pH<<< dimGrid, dimBlock, 8*(dimBlock.x+2*r)*dimBLock.y*sizeof(char) >>>(d_outc, L, r ); + \ No newline at end of file diff --git a/BookGPU/Chapters/chapter4/code/convoSepSh.cu~ b/BookGPU/Chapters/chapter4/code/convoSepSh.cu~ new file mode 100644 index 0000000..1d87e39 --- /dev/null +++ b/BookGPU/Chapters/chapter4/code/convoSepSh.cu~ @@ -0,0 +1,6 @@ +dimGrid = dim3( (L/dimBlock.x)/8, H/dimBlock.y, 1 ) ; + +kernel_convoSepShx8pV<<< dimGrid, dimBlock, 8*dimBlock.x*(dimBlock.y+2*r)*sizeof(char) >>>(d_outc, H, L, r ); +cudaMemcpyToArray( array_img_inc, 0, 0, d_outc, H*L*sizeof(char) , cudaMemcpyDeviceToDevice) ; +kernel_convoSepShx8pH<<< dimGrid, dimBlock, 8*(dimBlock.x+2*r)*dimBLock.y*sizeof(char) >>>(d_outc, L, H, r ); + \ No newline at end of file diff --git a/BookGPU/Chapters/chapter4/code/convoSepShH.cu b/BookGPU/Chapters/chapter4/code/convoSepShH.cu new file mode 100644 index 0000000..19f533e --- /dev/null +++ b/BookGPU/Chapters/chapter4/code/convoSepShH.cu @@ -0,0 +1,58 @@ +__global__ void kernel_convoSepShx8pH(unsigned char *output, int j_dim, int r) +{ + int ic, jc, p; + int k = 2*r+1 ; + float outval0=0.0, outval1=0.0, outval2=0.0, outval3=0.0 ; + float outval4=0.0, outval5=0.0, outval6=0.0, outval7=0.0 ; + int bdimX = blockDim.x<<3 ; // all packets width + int tidX = threadIdx.x<<3 ; // one packet offset + + // absolute coordinates of one packet base point + int j = (__umul24(blockIdx.x,blockDim.x) + threadIdx.x)<<3 ; + int i = __umul24( blockIdx.y, blockDim.y) + threadIdx.y ; + int j0= __umul24(blockIdx.x,blockDim.x)<<3 ; + // absolute index in the image + int idx = __umul24(i,j_dim) + j ; + + // offset of one ROI row in shared memory + int idrow = threadIdx.y*(bdimX+k-1) ; + + extern __shared__ unsigned char roi8p[]; + + // top left block + for (p=0; p<8; p++) + roi8p[ idrow + tidX +p ] = tex2D(tex_img_inc, j-r+p , i) ; + // top right block + if ( threadIdx.x < r ) + { + roi8p[ idrow + bdimX + threadIdx.x ] = tex2D( tex_img_inc, j0-r +bdimX+threadIdx.x , i ) ; + roi8p[ idrow + bdimX + threadIdx.x +r ] = tex2D( tex_img_inc, j0 +bdimX+threadIdx.x , i ) ; + } + + __syncthreads(); + + // horizontal convolution + for (jc=0 ; jc global mem + output[ idx++ ] = outval0 ; + output[ idx++ ] = outval1 ; + output[ idx++ ] = outval2 ; + output[ idx++ ] = outval3 ; + output[ idx++ ] = outval4 ; + output[ idx++ ] = outval5 ; + output[ idx++ ] = outval6 ; + output[ idx++ ] = outval7 ; +} diff --git a/BookGPU/Chapters/chapter4/code/convoSepShH.cu~ b/BookGPU/Chapters/chapter4/code/convoSepShH.cu~ new file mode 100644 index 0000000..8f3e73d --- /dev/null +++ b/BookGPU/Chapters/chapter4/code/convoSepShH.cu~ @@ -0,0 +1,59 @@ +__global__ void kernel_convoSepShx8pH(unsigned char *output, int j_dim, int r) +{ + int ic, jc, p; + int k = 2*r+1 ; + float outval0=0.0, outval1=0.0, outval2=0.0, outval3=0.0, outval4=0.0, outval5=0.0, outval6=0.0, outval7=0.0 ; + int bdimX = blockDim.x<<3 ; + int tidX = threadIdx.x<<3 ; + + // coordonnees absolues du point de base + int j = (__umul24(blockIdx.x,blockDim.x) + threadIdx.x)<<3 ; + int i = __umul24( blockIdx.y, blockDim.y) + threadIdx.y ; + int j0= __umul24(blockIdx.x,blockDim.x)<<3 ; + int idx = __umul24(i,j_dim) + j ; // indice dans l'image + + + // chargement en smem + int idrow = threadIdx.y*(bdimX+k-1) ; + + extern __shared__ unsigned char roi8p[]; + + // bloc 0 (a gauche) + for (p=0; p<8; p++) + roi8p[ idrow + tidX +p ] = tex2D(tex_img_inc, j-r+p , i) ; + + // a droite + if ( threadIdx.x < r ) //...ou plutot ce qu'il en manque + { + roi8p[ idrow + bdimX + threadIdx.x ] = tex2D( tex_img_inc, j0-r +bdimX+threadIdx.x , i ) ; + roi8p[ idrow + bdimX + threadIdx.x +r ] = tex2D( tex_img_inc, j0 +bdimX+threadIdx.x , i ) ; + } + + __syncthreads(); + + // calculs de convolution + // passe horizontale + for (jc=0 ; jc global mem + output[ idx ] = outval0 ; + output[ idx+1 ] = outval1 ; + output[ idx+2 ] = outval2 ; + output[ idx+3 ] = outval3 ; + output[ idx+4 ] = outval4 ; + output[ idx+5 ] = outval5 ; + output[ idx+6 ] = outval6 ; + output[ idx+7 ] = outval7 ; +} diff --git a/BookGPU/Chapters/chapter4/code/convoSepShV.cu b/BookGPU/Chapters/chapter4/code/convoSepShV.cu new file mode 100644 index 0000000..a8bf71e --- /dev/null +++ b/BookGPU/Chapters/chapter4/code/convoSepShV.cu @@ -0,0 +1,57 @@ +__global__ void kernel_convoSepShx8pV(unsigned char *output, int j_dim, int r) +{ + int ic, jc, p; + int k = 2*r+1 ; + float outval0=0.0, outval1=0.0, outval2=0.0, outval3=0.0 ; + float outval4=0.0, outval5=0.0, outval6=0.0, outval7=0.0 ; + int bdimX = blockDim.x<<3 ; // all packets width + int tidX = threadIdx.x<<3 ; // one packet offset + + // absolute coordinates of the base point + int j = (__umul24(blockIdx.x,blockDim.x) + threadIdx.x)<<3 ; + int i = __umul24( blockIdx.y, blockDim.y) + threadIdx.y ; + // absolute index in the image + int idx = __umul24(i,j_dim) + j ; + // offset of one ROI row in shared memory + int idrow = threadIdx.y*bdimX ; + + extern __shared__ unsigned char roi8p[]; + + // top block + for (p=0; p<8; p++) + roi8p[ idrow + tidX +p ] = tex2D(tex_img_inc, j+p , i-r) ; + + // bottom block + if ( threadIdx.y < k-1 ) + { + idrow = (threadIdx.y+blockDim.y)*bdimX ; + for (int p=0; p<8; p++) + roi8p[ idrow + tidX +p ] = tex2D( tex_img_inc, j+p , i+blockDim.y-r ) ; + } + __syncthreads(); + + // vertical convolution + for (ic=0 ; ic global mem + output[ idx++ ] = outval0 ; + output[ idx++ ] = outval1 ; + output[ idx++ ] = outval2 ; + output[ idx++ ] = outval3 ; + output[ idx++ ] = outval4 ; + output[ idx++ ] = outval5 ; + output[ idx++ ] = outval6 ; + output[ idx++ ] = outval7 ; +} diff --git a/BookGPU/Chapters/chapter4/code/convoSepShV.cu~ b/BookGPU/Chapters/chapter4/code/convoSepShV.cu~ new file mode 100644 index 0000000..4437a56 --- /dev/null +++ b/BookGPU/Chapters/chapter4/code/convoSepShV.cu~ @@ -0,0 +1,56 @@ +__global__ void kernel_convoSepShx8pV(unsigned char *output, int j_dim, int r) +{ + int ic, jc, p; + int k = 2*r+1 ; + float outval0=0.0, outval1=0.0, outval2=0.0, outval3=0.0, outval4=0.0, outval5=0.0, outval6=0.0, outval7=0.0 ; + int bdimX = blockDim.x<<3 ; + int tidX = threadIdx.x<<3 ; + + // absolute coordinates of the base point + int j = (__umul24(blockIdx.x,blockDim.x) + threadIdx.x)<<3 ; + int i = __umul24( blockIdx.y, blockDim.y) + threadIdx.y ; + // absolute index in the image + int idx = __umul24(i,j_dim) + j ; + // offset of one ROI row in shared memory + int idrow = threadIdx.y*bdimX ; + + extern __shared__ unsigned char roi8p[]; + + // top block + for (p=0; p<8; p++) + roi8p[ idrow + tidX +p ] = tex2D(tex_img_inc, j+p , i-r) ; + + // bottom block + if ( threadIdx.y < k-1 ) + { + idrow = (threadIdx.y+blockDim.y)*bdimX ; + for (int p=0; p<8; p++) + roi8p[ idrow + tidX +p ] = tex2D( tex_img_inc, j+p , i+blockDim.y-r ) ; + } + __syncthreads(); + + // vertical convolution + for (ic=0 ; ic global mem + output[ idx++ ] = outval0 ; + output[ idx++ ] = outval1 ; + output[ idx++ ] = outval2 ; + output[ idx++ ] = outval3 ; + output[ idx++ ] = outval4 ; + output[ idx++ ] = outval5 ; + output[ idx++ ] = outval6 ; + output[ idx++ ] = outval7 ; +} diff --git a/BookGPU/Chapters/chapter4/code/levelines_kernels.cu b/BookGPU/Chapters/chapter4/code/levelines_kernels.cu new file mode 100644 index 0000000..2c80950 --- /dev/null +++ b/BookGPU/Chapters/chapter4/code/levelines_kernels.cu @@ -0,0 +1,3793 @@ +#define PI 3.1415926 + +__constant__ float masque[256] ; +/* noyau gaussien 3x3 *//* +__constant__ float noyau[] = {1.0/16,2.0/16,1.0/16, + 2.0/16,4.0/16,2.0/16, + 1.0/16,2.0/16,1.0/16} ; + __constant__ int rnoyau = 1 ;*/ + +/* noyau gaussien 5x5 *//* +__constant__ int noyau[] = {1,4,6,4,1, 4,16,24,16,4, 6,24,36,24,6, 4,16,24,16,4, 1,4,6,4,1} ; +__constant__ int sumNoyau = 256 ; +__constant__ int rnoyau = 2 ; +__constant__ int NNoyau = 25 ; + */ +/* noyau 5x5*/ +__constant__ float noyau[] = {1.0/25,1.0/25,1.0/25,1.0/25,1.0/25, + 1.0/25,1.0/25,1.0/25,1.0/25,1.0/25, + 1.0/25,1.0/25,1.0/25,1.0/25,1.0/25, + 1.0/25,1.0/25,1.0/25,1.0/25,1.0/25, + 1.0/25,1.0/25,1.0/25,1.0/25,1.0/25} ; +__constant__ int rnoyau = 2 ; + +/* noyau 7x7 *//* +__device__ __constant__ float noyau[] = {1.0/49,1.0/49,1.0/49,1.0/49,1.0/49,1.0/49,1.0/49, + 1.0/49,1.0/49,1.0/49,1.0/49,1.0/49,1.0/49,1.0/49, + 1.0/49,1.0/49,1.0/49,1.0/49,1.0/49,1.0/49,1.0/49, + 1.0/49,1.0/49,1.0/49,1.0/49,1.0/49,1.0/49,1.0/49, + 1.0/49,1.0/49,1.0/49,1.0/49,1.0/49,1.0/49,1.0/49, + 1.0/49,1.0/49,1.0/49,1.0/49,1.0/49,1.0/49,1.0/49, + 1.0/49,1.0/49,1.0/49,1.0/49,1.0/49,1.0/49,1.0/49} ; +__device__ __constant__ int rnoyau = 3 ; + */ +//__device__ __constant__ int NNoyau = 49 ; + +__device__ __constant__ int noyauH[] = {1,1,1,1,1,1,1} ; +__device__ __constant__ int sumNoyauH = 7 ; +__device__ __constant__ int rnoyauH = 3 ; +// average 7x7 +/* +__device__ __constant__ int noyauV[] = {1,1,1,1,1,1,1} ; +__device__ __constant__ int sumNoyauV = 7 ; +__device__ __constant__ int rnoyauV = 3 ; +*/ +// gaussian 5x5 +__device__ __constant__ int noyauV[] = {1,4,6,4,1} ; +__device__ __constant__ int rnoyauV = 2 ; +__constant__ int sumKV = 16 ; +//__device__ __constant__ int noyauV[] = {1,1,1} ; +//__constant__ int sumNoyauV = 16 ; + +// declarations des textures +texture tex_img_in ; +texture tex_img_ins ; +texture tex_img_inc ; +texture tex_img_estim ; +texture tex_noyau ; +texture tex_noyauConvof ; +texture tex_noyauConvos ; +texture tex_kern ; + + +/*************************************************************** + * kernel identite pour mesures de debit max effectif possible + ***************************************************************/ +__global__ void kernel_ident( unsigned short*output, int i_dim, int j_dim) +{ + // coordonnees absolues du point de base + int j = __mul24(blockIdx.x,blockDim.x) + threadIdx.x ; + int i = __mul24( blockIdx.y, blockDim.y) + threadIdx.y ; + int idx = __mul24(i, j_dim) + j ; // indice dans l'image + + output[ idx ] = tex2D(tex_img_ins, j, i) ; + +} + +__global__ void kernel_ident2p( unsigned short *output, int i_dim, int j_dim) +{ + // coordonnees absolues du point de base + int j = __umul24(__umul24(blockIdx.x,blockDim.x) + threadIdx.x,2) ; + int i = __umul24( blockIdx.y, blockDim.y) + threadIdx.y ; + + output[ __umul24(i, j_dim) + j ] = tex2D(tex_img_inc, j, i) ; + output[ __umul24(i, j_dim) + j +1 ] = tex2D(tex_img_inc, j+1, i) ; + +} + + +__global__ void kernel_ident( unsigned char *output, int i_dim, int j_dim) +{ + // coordonnees absolues du point de base + int j = __mul24(blockIdx.x,blockDim.x) + threadIdx.x ; + int i = __mul24( blockIdx.y, blockDim.y) + threadIdx.y ; + + output[ __umul24(i, j_dim) + j ] = tex2D(tex_img_inc, j, i) ; + +} + +__global__ void kernel_ident2p( unsigned char *output, int i_dim, int j_dim) +{ + // coordonnees absolues du point de base + int j = __umul24(__umul24(blockIdx.x,blockDim.x) + threadIdx.x,2) ; + int i = __umul24( blockIdx.y, blockDim.y) + threadIdx.y ; + + output[ __umul24(i, j_dim) + j ] = tex2D(tex_img_inc, j, i) ; + output[ __umul24(i, j_dim) + j +1 ] = tex2D(tex_img_inc, j+1, i) ; + +} + +/** + * + * \brief calcule l'estimation initiale + * \author zulu - AND + * + * \param[in] L Largeur de l'image + * \param[in] i_dim Hauteur de l'image + * \param[in] j_dim coté de la fenêtre de moyenneage + * + * \param[out] output Image estimee initiale + * + * Version texture : l'img originale est supposée en texture. + * L'estimation réalisée correspond a un moyenneur de 'rayon' r + * Execution sur des blocs de threads 2D et une grille 2D + * selon les dimensions de l'image. + * + */ + +__global__ void kernel_moyenne_shtex( unsigned int *output, unsigned int i_dim, unsigned int j_dim, unsigned int r) +{ + int idl, idc ; + //coordonnées ds le bloc + int ib = threadIdx.y ; + int jb = threadIdx.x ; + int idb_row = __mul24(ib,blockDim.x) + jb ; // indice dans le bloc + + // coordonnees absolues du point + int j = __mul24(blockIdx.x,blockDim.x) + jb ; + int i = __mul24(blockIdx.y,blockDim.y) + ib ; + int idx = __mul24(i,j_dim) + j ; // indice dans l'image + int off = __mul24(r,blockDim.x) ; // offset du bloc dans le buffer en sh mem + + + extern __shared__ unsigned int shmem[] ; + volatile unsigned int * buffer = shmem ; + volatile unsigned int * bufferV = &buffer[ blockDim.x*blockDim.y + 2*off ] ; + + + /*********************************************************************************** + * PASSE HORIZONTALE + ***********************************************************************************/ + // charge les pixels de la bande au dessus du bloc + if(ib=(blockDim.y-r)) + { + buffer[ idb_row + 2*off ] = 0 ; + for (idc=j-r ; idc<=j+r ; idc++ ) + buffer[ idb_row + 2*off ] += tex2D(tex_img_in, idc, i+r) ; + } + + // charge les pixels du bloc + buffer[ idb_row + off ] = 0 ; + for (idc=j-r ; idc<=j+r ; idc++ ) + buffer[ idb_row + off ] += tex2D(tex_img_in, idc, i) ; + + __syncthreads() ; + /***************************************************************************** + * PASSE VERTICALE + *****************************************************************************/ + bufferV[ idb_row ] = 0 ; + for (idl=0 ; idl<=2*r ; idl++ ) + bufferV[ idb_row ] += buffer[ (ib+idl)*blockDim.x + jb ] ; + + __syncthreads() ; + + output[idx] = bufferV[ idb_row ]/((2*r+1)*(2*r+1)) ; //pas juste sur les bords, mais c'est pô grave ! + +} + +/** + * + * \brief calcule la convolution avec un noyau carre + * \author zulu - AND + * + * \param[in] L Largeur de l'image + * \param[in] i_dim Hauteur de l'image + * \param[in] j_dim coté de la fenêtre de moyenneage + * + * \param[out] output Image estimee initiale + * + * Version texture : l'img originale est supposée en texture. + * Execution sur des blocs de threads 2D et une grille 2D + * correspondant aux dimensions de l'image. + * + */ + +// convolution non separable +// image en texture et noyau en mem constante +__global__ void kernel_convoGene8( unsigned char *output, int i_dim, int j_dim) +{ + int ic, jc ; + int r = 2 ; + int L=5 ; + float outval0=0.0 ; + + // coordonnees absolues du point de base + int j = __mul24(blockIdx.x,blockDim.x) + threadIdx.x ; + int i = __mul24( blockIdx.y, blockDim.y) + threadIdx.y ; + + for (ic=0 ; ic masque[ __mul24(ic,L)+jc ]*tex2D(tex_img_inc, j-r+jc, i-r+ic) + for (ic=1 ; ic masque[ __mul24(ic,L)+jc ]*tex2D(tex_img_inc, j-r+jc, i-r+ic) + for (ic=1 ; ic masque[ __mul24(ic,L)+jc ]*tex2D(tex_img_inc, j-r+jc, i-r+ic) + for (ic=0 ; ic masque[ __mul24(ic,L)+jc ]*tex2D(tex_img_inc, j-r+jc, i-r+ic) + for (ic=0 ; ic masque[ __mul24(ic,L)+jc ]*tex2D(tex_img_inc, j-r+jc, i-r+ic) + for (ic=1 ; ic global mem + output[ idx ] = outval0 ; + +} + +__global__ void kernel_convoNonSepSh_2p(unsigned short *output, int i_dim, int j_dim) +{ + int idb, ic, jc ; + int L = 2*rnoyau+1 ; + float outval0=0.0, outval1=0.0 ; + int bdimX = blockDim.x<<1 ; + int tidX = threadIdx.x<<1 ; + + // coordonnees absolues du point de base + int j = __mul24(__mul24(blockIdx.x,blockDim.x) + threadIdx.x,2) ; + int i = __mul24( blockIdx.y, blockDim.y) + threadIdx.y ; + int idx = __mul24(i,j_dim) + j ; // indice dans l'image + + // chargement en smem + int idrow = threadIdx.y*(bdimX+L-1) ; + + extern __shared__ int roi[]; + + // bloc 0 (en haut à gauche) + roi[ idrow + tidX ] = tex2D(tex_img_ins, j-rnoyau, i-rnoyau) ; + roi[ idrow + tidX +1] = tex2D(tex_img_ins, j-rnoyau+1, i-rnoyau) ; + + // bloc 1 (en haut à droite)... + if ( threadIdx.x < rnoyau ) //...ou plutot ce qu'il en manque + { + roi[ idrow + tidX+bdimX ] = tex2D( tex_img_ins, j+bdimX-rnoyau, i-rnoyau ) ; + roi[ idrow + tidX+bdimX +1] = tex2D( tex_img_ins, j+bdimX-rnoyau+1, i-rnoyau ) ; + } + + // bloc 2 ( en bas à gauche) + if ( threadIdx.y < L-1 ) + { + idrow = (threadIdx.y+blockDim.y)*(bdimX+L-1) ; + roi[ idrow + tidX ] = tex2D( tex_img_ins, j-rnoyau, i+blockDim.y-rnoyau ) ; + roi[ idrow + tidX +1] = tex2D( tex_img_ins, j-rnoyau+1, i+blockDim.y-rnoyau ) ; + //bloc 4 ( en bas à doite )... + + if ( 2*threadIdx.x < L-1 ) //...ou ce qu'il en manque + { + roi[ idrow + tidX+bdimX ] = tex2D( tex_img_ins, j+bdimX-rnoyau, i+blockDim.y-rnoyau ) ; + roi[ idrow + tidX+bdimX +1] = tex2D( tex_img_ins, j+bdimX-rnoyau+1, i+blockDim.y-rnoyau ) ; + } + } + __syncthreads(); + + // calculs de convolution + for (ic=0 ; ic global mem + output[ idx ] = outval0 ; + output[ idx+1 ] = outval1 ; +} + +__global__ void kernel_convoNonSepSh_2p(unsigned char *output, int i_dim, int j_dim, int r) +{ + int idb, ic, jc ; + int L = 2*r+1 ; + float outval0=0.0, outval1=0.0 ; + int bdimX = blockDim.x<<1 ; + int tidX = threadIdx.x<<1 ; + + // coordonnees absolues du point de base + int j = __umul24(__mul24(blockIdx.x,blockDim.x) + threadIdx.x,2) ; + int i = __umul24( blockIdx.y, blockDim.y) + threadIdx.y ; + int idx = __umul24(i,j_dim) + j ; // indice dans l'image + + // chargement en smem + int idrow = threadIdx.y*(bdimX+L-1) ; + + extern __shared__ int roi[]; + + // bloc 0 (en haut à gauche) + roi[ idrow + tidX ] = tex2D( tex_img_inc, j-r , i-r) ; + roi[ idrow + tidX +1 ] = tex2D( tex_img_inc, j-r+1, i-r) ; + + // bloc 1 (en haut à droite)... + if ( threadIdx.x < r ) //...ou plutot ce qu'il en manque + { + roi[ idrow + bdimX + tidX ] = tex2D( tex_img_inc, j+bdimX-r , i-r ) ; + roi[ idrow + bdimX + tidX +1 ] = tex2D( tex_img_inc, j+bdimX-r+1, i-r ) ; + } + + // bloc 2 ( en bas à gauche) + if ( threadIdx.y < L-1 ) + { + idrow = (threadIdx.y+blockDim.y)*(bdimX+L-1) ; + roi[ idrow + tidX ] = tex2D( tex_img_inc, j-r, i+blockDim.y-r ) ; + roi[ idrow + tidX +1] = tex2D( tex_img_inc, j-r+1, i+blockDim.y-r ) ; + //bloc 4 ( en bas à doite )... + + if ( threadIdx.x < r ) //...ou ce qu'il en manque + { + roi[ idrow + tidX+bdimX ] = tex2D( tex_img_inc, j+bdimX-r , i+blockDim.y-r ) ; + roi[ idrow + tidX+bdimX +1] = tex2D( tex_img_inc, j+bdimX-r+1, i+blockDim.y-r ) ; + } + } + __syncthreads(); + + // calculs de convolution + for (ic=0 ; ic global mem + output[ idx ] = outval0 ; + output[ idx+1 ] = outval1 ; +} + +//4 pixels en ligne par thread +__global__ void kernel_convoNonSepSh_4p(unsigned char *output, int i_dim, int j_dim, int r) +{ + int idb, ic, jc ; + int L = 2*r+1 ; + float outval0=0.0, outval1=0.0, outval2=0.0, outval3=0.0 ; + int bdimX = blockDim.x<<2 ; + int tidX = threadIdx.x<<2 ; + + // coordonnees absolues du point de base + int j = (__umul24(blockIdx.x,blockDim.x) + threadIdx.x)<<2 ; + int i = __umul24( blockIdx.y, blockDim.y) + threadIdx.y ; + int j0= __umul24(blockIdx.x,blockDim.x)<<2 ; + + int idx = __umul24(i,j_dim) + j ; // indice dans l'image + + + // chargement en smem + int idrow = threadIdx.y*(bdimX+L-1) ; + + extern __shared__ unsigned char roi4p[]; + + // bloc 0 (en haut à gauche) + roi4p[ idrow + tidX ] = tex2D(tex_img_inc, j-r , i-r) ; + roi4p[ idrow + tidX +1] = tex2D(tex_img_inc, j-r+1, i-r) ; + roi4p[ idrow + tidX +2] = tex2D(tex_img_inc, j-r+2, i-r) ; + roi4p[ idrow + tidX +3] = tex2D(tex_img_inc, j-r+3, i-r) ; + + // bloc 1 (en haut à droite)... + if ( threadIdx.x < r ) //...ou plutot ce qu'il en manque + { + roi4p[ idrow + bdimX + threadIdx.x ] = tex2D( tex_img_inc, j0-r +bdimX+threadIdx.x , i-r ) ; + roi4p[ idrow + bdimX + threadIdx.x +r ] = tex2D( tex_img_inc, j0 +bdimX+threadIdx.x , i-r ) ; + } + // bloc 2 ( en bas à gauche) + if ( threadIdx.y < L-1 ) + { + idrow = (threadIdx.y+blockDim.y)*(bdimX+L-1) ; + roi4p[ idrow + tidX ] = tex2D( tex_img_inc, j-r , i+blockDim.y-r ) ; + roi4p[ idrow + tidX +1] = tex2D( tex_img_inc, j-r+1, i+blockDim.y-r ) ; + roi4p[ idrow + tidX +2] = tex2D( tex_img_inc, j-r+2, i+blockDim.y-r ) ; + roi4p[ idrow + tidX +3] = tex2D( tex_img_inc, j-r+3, i+blockDim.y-r ) ; + + //bloc 4 ( en bas à doite )... + if ( threadIdx.x < r ) //...ou ce qu'il en manque + { + roi4p[ idrow + bdimX +threadIdx.x ] = tex2D( tex_img_inc, j0-r +bdimX +threadIdx.x, i+blockDim.y-r ) ; + roi4p[ idrow + bdimX +threadIdx.x +r] = tex2D( tex_img_inc, j0 +bdimX +threadIdx.x, i+blockDim.y-r ) ; + } + } + __syncthreads(); + + // calculs de convolution + for (ic=0 ; ic global mem + output[ idx ] = outval0 ; + output[ idx+1 ] = outval1 ; + output[ idx+2 ] = outval2 ; + output[ idx+3 ] = outval3 ; +} + + +//4 pixels en carre par thread +__global__ void kernel_convoNonSepSh_4pcarre(unsigned char *output, int i_dim, int j_dim, int r) +{ + int idb, ic, jc ; + int L = 2*r+1 ; + float outval0=0.0, outval1=0.0, outval2=0.0, outval3=0.0 ; + int bdimX = blockDim.x<<1 ; + int tidX = threadIdx.x<<1 ; + int bdimY = blockDim.y<<1 ; + int tidY = threadIdx.y<<1 ; + + // coordonnees absolues du point de base + int j = (__umul24(blockIdx.x,blockDim.x) + threadIdx.x)<<1 ; + int i = (__umul24( blockIdx.y, blockDim.y) + threadIdx.y)<<1 ; + int j0= __umul24(blockIdx.x,blockDim.x)<<1 ; + int i0= __umul24(blockIdx.y,blockDim.y)<<1 ; + + int idx = __umul24(i,j_dim) + j ; // indice dans l'image + + + // chargement en smem + int idrowBase = tidY*(bdimX+L-1) ; + int idrowSecond = (tidY+1)*(bdimX+L-1) ; + + + extern __shared__ unsigned char roi4p2[]; + + // bloc 0 (en haut à gauche) + roi4p2[ idrowBase + tidX ] = tex2D(tex_img_inc, j-r , i-r ) ; + roi4p2[ idrowBase + tidX +1] = tex2D(tex_img_inc, j-r+1, i-r ) ; + roi4p2[ idrowSecond+ tidX ] = tex2D(tex_img_inc, j-r , i-r+1) ; + roi4p2[ idrowSecond+ tidX +1] = tex2D(tex_img_inc, j-r+1, i-r+1) ; + + // bloc 1 (en haut à droite)... + if ( threadIdx.x < r ) //...ou plutot ce qu'il en manque + { + roi4p2[ idrowBase + bdimX + threadIdx.x ] = tex2D( tex_img_inc, j0-r +bdimX+threadIdx.x , i-r ) ; + roi4p2[ idrowBase + bdimX + threadIdx.x +r ] = tex2D( tex_img_inc, j0 +bdimX+threadIdx.x , i-r ) ; + roi4p2[ idrowSecond + bdimX + threadIdx.x ] = tex2D( tex_img_inc, j0-r +bdimX+threadIdx.x , i-r+1 ) ; + roi4p2[ idrowSecond + bdimX + threadIdx.x +r ] = tex2D( tex_img_inc, j0 +bdimX+threadIdx.x , i-r+1 ) ; + } + // bloc 2 ( en bas à gauche) + if ( threadIdx.y < L-1 ) + { + idrowBase = (bdimY + threadIdx.y)*(bdimX+L-1) ; + roi4p2[ idrowBase + tidX ] = tex2D( tex_img_inc, j-r , i0-r +bdimY +threadIdx.y ) ; + roi4p2[ idrowBase + tidX +1] = tex2D( tex_img_inc, j-r+1, i0-r +bdimY +threadIdx.y ) ; + + //bloc 4 ( en bas à doite )... + if ( threadIdx.x < r ) //...ou ce qu'il en manque + { + roi4p2[ idrowBase + bdimX + threadIdx.x ] = tex2D( tex_img_inc, j0-r +bdimX +threadIdx.x , i0-r +bdimY +threadIdx.y ) ; + roi4p2[ idrowBase + bdimX + threadIdx.x +r ] = tex2D( tex_img_inc, j0 +bdimX +threadIdx.x , i0-r +bdimY +threadIdx.y ) ; + } + } + __syncthreads(); + + // calculs de convolution + for (ic=0 ; ic global mem + output[ idx ] = outval0 ; + output[ idx+1 ] = outval1 ; + output[ idx+j_dim ] = outval2 ; + output[ idx+j_dim+1 ] = outval3 ; +} + + +//8 pixels en ligne par thread +__global__ void kernel_convoNonSepSh_8p(unsigned char *output, int i_dim, int j_dim, int r) +{ + int idb, ic, jc; + int L = 2*r+1 ; + float outval0=0.0, outval1=0.0, outval2=0.0, outval3=0.0, outval4=0.0, outval5=0.0, outval6=0.0, outval7=0.0 ; + int bdimX = blockDim.x<<3 ; + int tidX = threadIdx.x<<3 ; + + // coordonnees absolues du point de base + int j = (__umul24(blockIdx.x,blockDim.x) + threadIdx.x)<<3 ; + int i = __umul24( blockIdx.y, blockDim.y) + threadIdx.y ; + int j0= __umul24(blockIdx.x,blockDim.x)<<3 ; + + int idx = __umul24(i,j_dim) + j ; // indice dans l'image + + + // chargement en smem + int idrow = threadIdx.y*(bdimX+L-1) ; + + extern __shared__ unsigned char roi8p[]; + + // bloc 0 (en haut à gauche) + for (int p=0; p<8; p++) + roi8p[ idrow + tidX +p ] = tex2D(tex_img_inc, j-r+p , i-r) ; + + // bloc 1 (en haut à droite)... + if ( threadIdx.x < r ) //...ou plutot ce qu'il en manque + { + roi8p[ idrow + bdimX + threadIdx.x ] = tex2D( tex_img_inc, j0-r +bdimX+threadIdx.x , i-r ) ; + roi8p[ idrow + bdimX + threadIdx.x +r ] = tex2D( tex_img_inc, j0 +bdimX+threadIdx.x , i-r ) ; + } + // bloc 2 ( en bas à gauche) + if ( threadIdx.y < L-1 ) + { + idrow = (threadIdx.y+blockDim.y)*(bdimX+L-1) ; + for (int p=0; p<8; p++) + roi8p[ idrow + tidX +p ] = tex2D( tex_img_inc, j-r+p , i+blockDim.y-r ) ; + + //bloc 4 ( en bas à doite )... + if ( threadIdx.x < r ) //...ou ce qu'il en manque + { + roi8p[ idrow + bdimX +threadIdx.x ] = tex2D( tex_img_inc, j0-r +bdimX +threadIdx.x, i+blockDim.y-r ) ; + roi8p[ idrow + bdimX +threadIdx.x +r] = tex2D( tex_img_inc, j0 +bdimX +threadIdx.x, i+blockDim.y-r ) ; + } + } + __syncthreads(); + + // calculs de convolution + for (ic=0 ; ic global mem + output[ idx ] = outval0 ; + output[ idx+1 ] = outval1 ; + output[ idx+2 ] = outval2 ; + output[ idx+3 ] = outval3 ; + output[ idx+4 ] = outval4 ; + output[ idx+5 ] = outval5 ; + output[ idx+6 ] = outval6 ; + output[ idx+7 ] = outval7 ; +} + + +//16 pixels en ligne par thread +__global__ void kernel_convoNonSepSh_16p(unsigned char *output, int i_dim, int j_dim, int r) +{ + int idb, ic, jc; + int L = 2*r+1 ; + float outval0=0.0, outval1=0.0, outval2=0.0, outval3=0.0, outval4=0.0, outval5=0.0, outval6=0.0, outval7=0.0 ; + float outval8=0.0, outval9=0.0, outval10=0.0, outval11=0.0, outval12=0.0, outval13=0.0, outval14=0.0, outval15=0.0 ; + int bdimX = blockDim.x<<4 ; + int tidX = threadIdx.x<<4 ; + + // coordonnees absolues du point de base + int j = (__umul24(blockIdx.x,blockDim.x) + threadIdx.x)<<4 ; + int i = __umul24( blockIdx.y, blockDim.y) + threadIdx.y ; + int j0= __umul24(blockIdx.x,blockDim.x)<<4 ; + + int idx = __umul24(i,j_dim) + j ; // indice dans l'image + + + // chargement en smem + int idrow = threadIdx.y*(bdimX+L-1) ; + + extern __shared__ unsigned char roi16p[]; + + // bloc 0 (en haut à gauche) + for (int p=0; p<16; p++) + roi16p[ idrow + tidX +p ] = tex2D(tex_img_inc, j-r+p , i-r) ; + + // bloc 1 (en haut à droite)... + if ( threadIdx.x < r ) //...ou plutot ce qu'il en manque + { + roi16p[ idrow + bdimX + threadIdx.x ] = tex2D( tex_img_inc, j0-r +bdimX+threadIdx.x , i-r ) ; + roi16p[ idrow + bdimX + threadIdx.x +r ] = tex2D( tex_img_inc, j0 +bdimX+threadIdx.x , i-r ) ; + } + // bloc 2 ( en bas à gauche) + if ( threadIdx.y < L-1 ) + { + idrow = (threadIdx.y+blockDim.y)*(bdimX+L-1) ; + for (int p=0; p<16; p++) + roi16p[ idrow + tidX +p ] = tex2D( tex_img_inc, j-r+p , i+blockDim.y-r ) ; + + //bloc 4 ( en bas à doite )... + if ( threadIdx.x < r ) //...ou ce qu'il en manque + { + roi16p[ idrow + bdimX +threadIdx.x ] = tex2D( tex_img_inc, j0-r +bdimX +threadIdx.x, i+blockDim.y-r ) ; + roi16p[ idrow + bdimX +threadIdx.x +r] = tex2D( tex_img_inc, j0 +bdimX +threadIdx.x, i+blockDim.y-r ) ; + } + } + __syncthreads(); + + // calculs de convolution + for (ic=0 ; ic global mem + output[ idx ] = outval0 ; + output[ idx+1 ] = outval1 ; + output[ idx+2 ] = outval2 ; + output[ idx+3 ] = outval3 ; + output[ idx+4 ] = outval4 ; + output[ idx+5 ] = outval5 ; + output[ idx+6 ] = outval6 ; + output[ idx+7 ] = outval7 ; + output[ idx+8 ] = outval8 ; + output[ idx+9 ] = outval9 ; + output[ idx+10 ] = outval10 ; + output[ idx+11 ] = outval11 ; + output[ idx+12 ] = outval12 ; + output[ idx+13 ] = outval13 ; + output[ idx+14 ] = outval14 ; + output[ idx+15 ] = outval15 ; +} + + + +// convolution non separable +// image en texture et noyau en mem constante +// fetch direct des pixels +// 2 pixels traités par thread => meilleur débit +__global__ void kernel_convoNonSep_2p( int *output, int i_dim, int j_dim) +{ + int idb, ic, jc ; + int r = rnoyau ; + int L = 2*r+1 ; + int N = L*L ; + float outval0=0, outval1=0 ; + + // coordonnees absolues du point de base + int j = __mul24(__mul24(blockIdx.x,blockDim.x) + threadIdx.x, 2) ; + int i = __mul24( blockIdx.y, blockDim.y) + threadIdx.y ; + int idx = __mul24(i, j_dim) + j ; // indice dans l'image + + #pragma unroll + for (idb=0 ; idb< N ; idb++) + { + ic = i-r + idb/L ; + jc = j-r + idb - (idb/L)*L ; + outval0 += ( noyau[ idb ]*tex2D(tex_img_in, jc, ic)) ; + outval1 += ( noyau[ idb ]*tex2D(tex_img_in, jc+1, ic)) ; + } + + output[ idx ] = outval0 ; + output[ idx+1 ] = outval1 ; + + +} + + +// convolution non separable +// image en texture et noyau en mem constante +// fetch direct des pixels +// 2 pixels traités par thread => meilleur débit +__global__ void kernel_convoNonSep_2p_s( unsigned short*output, int i_dim, int j_dim) +{ + int idb, ic, jc ; + int r = rnoyau ; + int L = 2*r+1 ; + int N = L*L ; + float outval0=0, outval1=0 ; + + // coordonnees absolues du point de base + int j = __mul24(__mul24(blockIdx.x,blockDim.x) + threadIdx.x, 2) ; + int i = __mul24( blockIdx.y, blockDim.y) + threadIdx.y ; + int idx = __mul24(i, j_dim) + j ; // indice dans l'image + + #pragma unroll + for (idb=0 ; idb< N ; idb++) + { + ic = i-r + idb/L ; + jc = j-r + idb - (idb/L)*L ; + outval0 += ( noyau[ idb ]*tex2D(tex_img_ins, jc, ic)) ; + outval1 += ( noyau[ idb ]*tex2D(tex_img_ins, jc+1, ic)) ; + } + + output[ idx ] = outval0 ; + output[ idx+1 ] = outval1 ; + +} + + + +// convolution separable +// image en texture et noyau en mem constante +__global__ void kernel_convoSep8V( unsigned char *output, int i_dim, int j_dim, int r) +{ + int ic ; + int L=2*r+1 ; + float outval0=0.0 ; + + // coordonnees absolues du point de base + int j = __mul24( blockIdx.x, blockDim.x ) + threadIdx.x ; + int i = __mul24( blockIdx.y, blockDim.y ) + threadIdx.y ; + + //vertical + for (ic=0 ; ic global mem + output[ idx ] = outval0 ; + output[ idx+1 ] = outval1 ; + output[ idx+2 ] = outval2 ; + output[ idx+3 ] = outval3 ; + output[ idx+4 ] = outval4 ; + output[ idx+5 ] = outval5 ; + output[ idx+6 ] = outval6 ; + output[ idx+7 ] = outval7 ; +} + +__global__ void kernel_convoSepShx8pH(unsigned char *output, int i_dim, int j_dim, int r) +{ + int idb, ic, jc, p; + int L = 2*r+1 ; + float outval0=0.0, outval1=0.0, outval2=0.0, outval3=0.0, outval4=0.0, outval5=0.0, outval6=0.0, outval7=0.0 ; + int bdimX = blockDim.x<<3 ; + int tidX = threadIdx.x<<3 ; + + // coordonnees absolues du point de base + int j = (__umul24(blockIdx.x,blockDim.x) + threadIdx.x)<<3 ; + int i = __umul24( blockIdx.y, blockDim.y) + threadIdx.y ; + int j0= __umul24(blockIdx.x,blockDim.x)<<3 ; + int idx = __umul24(i,j_dim) + j ; // indice dans l'image + + + // chargement en smem + int idrow = threadIdx.y*(bdimX+L-1) ; + + extern __shared__ unsigned char roi8p[]; + + // bloc 0 (a gauche) + for (p=0; p<8; p++) + roi8p[ idrow + tidX +p ] = tex2D(tex_img_inc, j-r+p , i) ; + + // a droite + if ( threadIdx.x < r ) //...ou plutot ce qu'il en manque + { + roi8p[ idrow + bdimX + threadIdx.x ] = tex2D( tex_img_inc, j0-r +bdimX+threadIdx.x , i ) ; + roi8p[ idrow + bdimX + threadIdx.x +r ] = tex2D( tex_img_inc, j0 +bdimX+threadIdx.x , i ) ; + } + + __syncthreads(); + + // calculs de convolution + // passe horizontale + for (jc=0 ; jc global mem + output[ idx ] = outval0 ; + output[ idx+1 ] = outval1 ; + output[ idx+2 ] = outval2 ; + output[ idx+3 ] = outval3 ; + output[ idx+4 ] = outval4 ; + output[ idx+5 ] = outval5 ; + output[ idx+6 ] = outval6 ; + output[ idx+7 ] = outval7 ; +} + + +/************************************************************************************************* + *********************************************************************************************** + + FIN DES kERNELS de CONVOLUTION + + *********************************************************************************************** + *************************************************************************************************/ +// kernel de la libjacket +// Exchange trick: Morgan McGuire, ShaderX 2008 +#define s2(a,b) { float tmp = a; a = min(a,b); b = max(tmp,b); } +#define mn3(a,b,c) s2(a,b); s2(a,c); +#define mx3(a,b,c) s2(b,c); s2(a,c); + +#define mnmx3(a,b,c) mx3(a,b,c); s2(a,b); // 3 exchanges +#define mnmx4(a,b,c,d) s2(a,b); s2(c,d); s2(a,c); s2(b,d); // 4 exchanges +#define mnmx5(a,b,c,d,e) s2(a,b); s2(c,d); mn3(a,c,e); mx3(b,d,e); // 6 exchanges +#define mnmx6(a,b,c,d,e,f) s2(a,d); s2(b,e); s2(c,f); mn3(a,b,c); mx3(d,e,f); // 7 exchanges + +#define IN(X,Y) ((0 <= (X) && (X) < nx && 0 <= (Y) && (Y) < ny) ? d_in[(Y)*nx+(X)] : 0) + +__global__ static void kernel_medjacket(int nx, int ny, unsigned short*d_out, unsigned short*d_in) +{ + int x = __mul24(blockIdx.x , blockDim.x) + threadIdx.x; + int y = __mul24(blockIdx.y , blockDim.y) + threadIdx.y; + + // pull top six from image + float v[6] = { IN(x-1, y-1), IN(x , y-1), IN(x+1, y-1), + IN(x-1, y ), IN(x , y ), IN(x+1, y ) }; + + // with each pass, remove min and max values and add new value + mnmx6(v[0], v[1], v[2], v[3], v[4], v[5]); + v[5] = IN(x-1, y+1); // add new contestant + mnmx5(v[1], v[2], v[3], v[4], v[5]); + v[5] = IN(x , y+1); // add new contestant + mnmx4(v[2], v[3], v[4], v[5]); + v[5] = IN(x+1, y+1); // add last contenstant + mnmx3(v[3], v[4], v[5]); + + // pick the middle one + d_out[y*nx + x] = v[4]; +} + + +/*************************************************************** + * fonction de tri de 2 valeurs entieres (min en premier) + ***************************************************************/ +__device__ inline void s(int* a, int* b) +{ + + int tmp ; + if (*a > *b) + { + tmp = *b ; + *b = *a ; + *a = tmp ; + } +} + +__device__ inline void s(unsigned short * a, unsigned short* b) +{ + + unsigned short tmp ; + if (*a > *b) + { + tmp = *b ; + *b = *a ; + *a = tmp ; + } +} + +__device__ inline void s(unsigned char * a, unsigned char * b) +{ + + unsigned short tmp ; + if (*a > *b) + { + tmp = *b ; + *b = *a ; + *a = tmp ; + } +} + +/*************************************************************** + * fonction de min-max d'un tableau de n valeurs entieres + ***************************************************************/ +__device__ void minmaxN(unsigned short* v, int n) +{ + for (int i=1; i< n; i++) + s( v, v+i) ; + for (int i=n-2; i>0; i--) + s( v+i, v+n-1) ; +} + +/*************************************************************** + * fonction de tri naif d'un tableau de n valeurs entieres + ***************************************************************/ +__device__ void bubTriN(int * v, int n) +{ + for (int i=0; i< n-1; i++) + for (int j=i+1; j ((2*r+1)*(2*r+1))>>1 ) break ; + } + + output[ __mul24(i, j_dim) +j ] = ic ; +} + +__global__ void kernel_medianRSH( unsigned short * output, int i_dim, int j_dim, int r) +{ + // coordonnees absolues du point + int j = __mul24(blockIdx.x,blockDim.x) + threadIdx.x ; + int i = __mul24(blockIdx.y,blockDim.y) + threadIdx.y ; + unsigned short cpt ; + unsigned short ic, jc ; + + // chargement en smem + int idrow = threadIdx.y*(blockDim.x+2*r) ; + + extern __shared__ int medRoi[]; + + // bloc 0 (en haut à gauche) + medRoi[ idrow + threadIdx.x ] = tex2D(tex_img_ins, j-r, i-r) ; + // bloc 1 (en haut à droite)... + if ( threadIdx.x < 2*r ) //...ou plutot ce qu'il en manque + medRoi[ idrow + threadIdx.x + blockDim.x ] = tex2D( tex_img_ins, j+blockDim.x-r, i-r ) ; + // bloc 2 ( en bas à gauche) + if ( threadIdx.y < 2*r ) + { + idrow = (threadIdx.y+blockDim.y)*(blockDim.x+2*r) ; + medRoi[ idrow + threadIdx.x ] = tex2D( tex_img_ins, j-r, i+blockDim.y-r ) ; + //bloc 4 ( en bas à doite )... + if ( threadIdx.x < 2*r ) //...ou ce qu'il en manque + medRoi[ idrow + threadIdx.x + blockDim.x ] = tex2D( tex_img_ins, j+blockDim.x-r, i+blockDim.y-r ) ; + } + __syncthreads(); + + int hist[256] ; + for (ic =0; ic<256; ic++) hist[ic]=0; // init histogramme + + //generation histogramme + for(ic=0; ic<=2*r; ic++ ) + for(jc=0; jc<=2*r; jc++) + hist[medRoi[(threadIdx.y+ic)*(blockDim.x+2*r)+ (threadIdx.x+jc)]]++ ; + + //parcours histogramme + cpt = 0 ; + for(ic=0; ic<256; ic++) + { + cpt += hist[ic] ; + //selection de la valeur du percentile (ici 50%=SUM/2) + if ( cpt > (((2*r+1)*(2*r+1))>>1) ) break ; + } + + output[ __mul24(i, j_dim) +j ] = ic ; +} + + +__global__ void kernel_median5_2pix( unsigned short*output, int i_dim, int j_dim) +{ + + // coordonnees absolues du point + int j = __mul24(__mul24(blockIdx.x,blockDim.x) + threadIdx.x,2) ; + int i = __mul24(blockIdx.y,blockDim.y) + threadIdx.y ; + + /************************************************************************** + * tri(s) + **************************************************************************/ + int a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13 ; + int b7, b8, b9, b10, b11, b12, b13 ; + + /******************************************************************************** + * les 14 premieres valeurs (suffisant pour median 5x5 par forgetfull selection) + ********************************************************************************/ + //premiere ligne + a0 = tex2D(tex_img_ins, j-1, i-2) ; + a1 = tex2D(tex_img_ins, j , i-2) ; + a2 = tex2D(tex_img_ins, j+1, i-2) ; + a3 = tex2D(tex_img_ins, j+2, i-2) ; + //deuxieme ligne + a4 = tex2D(tex_img_ins, j-1, i-1) ; + a5 = tex2D(tex_img_ins, j , i-1) ; + a6 = tex2D(tex_img_ins, j+1, i-1) ; + a7 = tex2D(tex_img_ins, j+2, i-1) ; + //troisieme ligne + a8 = tex2D(tex_img_ins, j-1, i) ; + a9 = tex2D(tex_img_ins, j , i) ; + a10 = tex2D(tex_img_ins, j+1, i) ; + a11 = tex2D(tex_img_ins, j+2, i) ; + //les 2 premiers de la 4eme ligne + a12 = tex2D(tex_img_ins, j-1, i+1) ; + a13 = tex2D(tex_img_ins, j , i+1) ; + + //min max aux extremites + minmax14(&a0,&a1,&a2,&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13); + + //chargement valeurs suivante (15) + a13 = tex2D(tex_img_ins, j+1, i+1); + //minmax aux extremites + minmax13(&a1,&a2,&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13); + + //chargement valeur suivante (16) + a13 = tex2D(tex_img_ins, j+2, i+1); + //minmax aux extremites + minmax12(&a2,&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13); + + //chargement valeur suivante (17) + a13 = tex2D(tex_img_ins, j-1, i+2); + //minmax aux extremites + minmax11(&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13); + + //chargement valeur suivante (18) + a13 = tex2D(tex_img_ins, j , i+2); + //minmax aux extremites + minmax10(&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13); + + //chargement valeur suivante (19) + a13 = tex2D(tex_img_ins, j+1, i+2); + //minmax aux extremites + minmax9(&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13); + + //chargement valeur suivante (20) + a13 = tex2D(tex_img_ins, j+2, i+2); + //minmax aux extmites + minmax8(&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13); + + // fin des pixels voisins communs deux pixels centraux + b7=a7; b8=a8; b9=a9; b10=a10; b11=a11; b12=a12; b13=a13; + + //chargement valeur suivante (21) + a13 = tex2D(tex_img_ins, j-2, i-2); + b13 = tex2D(tex_img_ins, j+3, i-2); + //minmax aux extremites + minmax7(&a7,&a8,&a9,&a10,&a11,&a12,&a13); + minmax7(&b7,&b8,&b9,&b10,&b11,&b12,&b13); + + //chargement valeur suivante (22) + a13 = tex2D(tex_img_ins, j-2, i-1); + b13 = tex2D(tex_img_ins, j+3, i-1); + //minmax aux extremites + minmax6(&a8,&a9,&a10,&a11,&a12,&a13); + minmax6(&b8,&b9,&b10,&b11,&b12,&b13); + + //chargement valeur suivante (23) + a13 = tex2D(tex_img_ins, j-2, i ); + b13 = tex2D(tex_img_ins, j+3, i ); + //minmax aux extremites + minmax5(&a9,&a10,&a11,&a12,&a13); + minmax5(&b9,&b10,&b11,&b12,&b13); + + //chargement valeur suivante (24) + a13 = tex2D(tex_img_ins, j-2, i+1); + b13 = tex2D(tex_img_ins, j+3, i+1); + //minmax aux extremites + minmax4(&a10,&a11,&a12,&a13); + minmax4(&b10,&b11,&b12,&b13); + + //chargement valeur suivante (25) + a13 = tex2D(tex_img_ins, j-2, i+2); + b13 = tex2D(tex_img_ins, j+3, i+2); + //minmax aux extremites + minmax3(&a11,&a12,&a13); + minmax3(&b11,&b12,&b13); + + //median au milieu ! + output[ __mul24(i, j_dim) +j ] = a12 ; + output[ __mul24(i, j_dim) +j+1 ] = b12 ; + +} + + +__global__ void kernel_median5_2pix( unsigned char *output, int i_dim, int j_dim) +{ + + // coordonnees absolues du point + int j = __mul24(__mul24(blockIdx.x,blockDim.x) + threadIdx.x,2) ; + int i = __mul24(blockIdx.y,blockDim.y) + threadIdx.y ; + + /************************************************************************** + * tri(s) + **************************************************************************/ + int a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13 ; + int b7, b8, b9, b10, b11, b12, b13 ; + + /******************************************************************************** + * les 14 premieres valeurs (suffisant pour median 5x5 par forgetfull selection) + ********************************************************************************/ + //premiere ligne + a0 = tex2D(tex_img_inc, j-1, i-2) ; + a1 = tex2D(tex_img_inc, j , i-2) ; + a2 = tex2D(tex_img_inc, j+1, i-2) ; + a3 = tex2D(tex_img_inc, j+2, i-2) ; + //deuxieme ligne + a4 = tex2D(tex_img_inc, j-1, i-1) ; + a5 = tex2D(tex_img_inc, j , i-1) ; + a6 = tex2D(tex_img_inc, j+1, i-1) ; + a7 = tex2D(tex_img_inc, j+2, i-1) ; + //troisieme ligne + a8 = tex2D(tex_img_inc, j-1, i) ; + a9 = tex2D(tex_img_inc, j , i) ; + a10 = tex2D(tex_img_inc, j+1, i) ; + a11 = tex2D(tex_img_inc, j+2, i) ; + //les 2 premiers de la 4eme ligne + a12 = tex2D(tex_img_inc, j-1, i+1) ; + a13 = tex2D(tex_img_inc, j , i+1) ; + + //min max aux extremites + minmax14(&a0,&a1,&a2,&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13); + + //chargement valeurs suivante (15) + a13 = tex2D(tex_img_inc, j+1, i+1); + //minmax aux extremites + minmax13(&a1,&a2,&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13); + + //chargement valeur suivante (16) + a13 = tex2D(tex_img_inc, j+2, i+1); + //minmax aux extremites + minmax12(&a2,&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13); + + //chargement valeur suivante (17) + a13 = tex2D(tex_img_inc, j-1, i+2); + //minmax aux extremites + minmax11(&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13); + + //chargement valeur suivante (18) + a13 = tex2D(tex_img_inc, j , i+2); + //minmax aux extremites + minmax10(&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13); + + //chargement valeur suivante (19) + a13 = tex2D(tex_img_inc, j+1, i+2); + //minmax aux extremites + minmax9(&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13); + + //chargement valeur suivante (20) + a13 = tex2D(tex_img_inc, j+2, i+2); + //minmax aux extmites + minmax8(&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13); + + // fin des pixels voisins communs deux pixels centraux + b7=a7; b8=a8; b9=a9; b10=a10; b11=a11; b12=a12; b13=a13; + + //chargement valeur suivante (21) + a13 = tex2D(tex_img_inc, j-2, i-2); + b13 = tex2D(tex_img_inc, j+3, i-2); + //minmax aux extremites + minmax7(&a7,&a8,&a9,&a10,&a11,&a12,&a13); + minmax7(&b7,&b8,&b9,&b10,&b11,&b12,&b13); + + //chargement valeur suivante (22) + a13 = tex2D(tex_img_inc, j-2, i-1); + b13 = tex2D(tex_img_inc, j+3, i-1); + //minmax aux extremites + minmax6(&a8,&a9,&a10,&a11,&a12,&a13); + minmax6(&b8,&b9,&b10,&b11,&b12,&b13); + + //chargement valeur suivante (23) + a13 = tex2D(tex_img_inc, j-2, i ); + b13 = tex2D(tex_img_inc, j+3, i ); + //minmax aux extremites + minmax5(&a9,&a10,&a11,&a12,&a13); + minmax5(&b9,&b10,&b11,&b12,&b13); + + //chargement valeur suivante (24) + a13 = tex2D(tex_img_inc, j-2, i+1); + b13 = tex2D(tex_img_inc, j+3, i+1); + //minmax aux extremites + minmax4(&a10,&a11,&a12,&a13); + minmax4(&b10,&b11,&b12,&b13); + + //chargement valeur suivante (25) + a13 = tex2D(tex_img_inc, j-2, i+2); + b13 = tex2D(tex_img_inc, j+3, i+2); + //minmax aux extremites + minmax3(&a11,&a12,&a13); + minmax3(&b11,&b12,&b13); + + //median au milieu ! + output[ __mul24(i, j_dim) +j ] = a12 ; + output[ __mul24(i, j_dim) +j+1 ] = b12 ; + +} + + +__global__ void kernel_median7( unsigned short*output, int i_dim, int j_dim) +{ + + // coordonnees absolues du point + int j = __mul24(blockIdx.x,blockDim.x) + threadIdx.x ; + int i = __mul24(blockIdx.y,blockDim.y) + threadIdx.y ; + + /************************************************************************** + * tri(s) + **************************************************************************/ + int a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20,a21,a22,a23,a24,a25 ; + + /**************************************** + * les 26 premieres valeurs + ****************************************/ + //premiere ligne + a0 = tex2D(tex_img_ins, j-2, i-3) ; + a1 = tex2D(tex_img_ins, j-1, i-3) ; + a2 = tex2D(tex_img_ins, j , i-3) ; + a3 = tex2D(tex_img_ins, j+1, i-3) ; + a4 = tex2D(tex_img_ins, j+2, i-3) ; + a5 = tex2D(tex_img_ins, j+3, i-3) ; + //deuxieme ligne + a6 = tex2D(tex_img_ins, j-2, i-2) ; + a7 = tex2D(tex_img_ins, j-1, i-2) ; + a8 = tex2D(tex_img_ins, j , i-2) ; + a9 = tex2D(tex_img_ins, j+1, i-2) ; + a10 = tex2D(tex_img_ins, j+2, i-2) ; + a11 = tex2D(tex_img_ins, j+3, i-2) ; + //troisieme ligne + a12 = tex2D(tex_img_ins, j-2, i-1) ; + a13 = tex2D(tex_img_ins, j-1, i-1) ; + a14 = tex2D(tex_img_ins, j , i-1) ; + a15 = tex2D(tex_img_ins, j+1, i-1) ; + a16 = tex2D(tex_img_ins, j+2, i-1) ; + a17 = tex2D(tex_img_ins, j+3, i-1) ; + //quatrieme ligne + a18 = tex2D(tex_img_ins, j-2, i ) ; + a19 = tex2D(tex_img_ins, j-1, i ) ; + a20 = tex2D(tex_img_ins, j , i ) ; + a21 = tex2D(tex_img_ins, j+1, i ) ; + a22 = tex2D(tex_img_ins, j+2, i ) ; + a23 = tex2D(tex_img_ins, j+3, i ) ; + //cinquieme ligne + a24 = tex2D(tex_img_ins, j-2, i+1) ; + a25 = tex2D(tex_img_ins, j-1, i+1) ; + + //min max aux extremites + minmax26(&a0,&a1,&a2,&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeurs suivante (26) + a25 = tex2D(tex_img_ins, j , i+1); + //minmax aux extremites + minmax25(&a1,&a2,&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeur suivante (27) + a25 = tex2D(tex_img_ins, j+1, i+1); + //minmax aux extremites + minmax24(&a2,&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeur suivante (28) + a25 = tex2D(tex_img_ins, j+2, i+1); + //minmax aux extremites + minmax23(&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeur suivante (29) + a25 = tex2D(tex_img_ins, j+3, i+1); + //minmax aux extremites + minmax22(&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeur suivante (30) + a25 = tex2D(tex_img_ins, j-2, i+2); + //minmax aux extremites + minmax21(&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeur suivante (31) + a25 = tex2D(tex_img_ins, j-1, i+2); + //minmax aux extmites + minmax20(&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeur suivante (32) + a25 = tex2D(tex_img_ins, j , i+2); + //minmax aux extmites + minmax19(&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeur suivante (33) + a25 = tex2D(tex_img_ins, j+1, i+2); + //minmax aux extmites + minmax18(&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeur suivante (34) + a25 = tex2D(tex_img_ins, j+2, i+2); + //minmax aux extmites + minmax17(&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeur suivante (35) + a25 = tex2D(tex_img_ins, j+3, i+2); + //minmax aux extmites + minmax16(&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeur suivante (36) + a25 = tex2D(tex_img_ins, j-2, i+3); + //minmax aux extmites + minmax15(&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeur suivante (37) + a25 = tex2D(tex_img_ins, j-1, i+3); + //minmax aux extmites + + minmax14(&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + //chargement valeur suivante (38) + a25 = tex2D(tex_img_ins, j , i+3); + //minmax aux extmites + minmax13(&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeur suivante (39) + a25 = tex2D(tex_img_ins, j+1, i+3); + //minmax aux extmites + minmax12(&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeur suivante (40) + a25 = tex2D(tex_img_ins, j+2, i+3); + //minmax aux extmites + minmax11(&a15, &a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeur suivante (41) + a25 = tex2D(tex_img_ins, j+3, i+3); + //minmax aux extmites + minmax10(&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeurs suivantes + a25 = tex2D(tex_img_ins, j-3, i+3); + //minmax aux extremites + minmax9(&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeurs suivantes + a25 = tex2D(tex_img_ins, j-3, i+2); + //minmax aux extremites + minmax8(&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeurs suivantes + a25 = tex2D(tex_img_ins, j-3, i+1); + //minmax aux extremites + minmax7(&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeurs suivantes + a25 = tex2D(tex_img_ins, j-3, i); + //minmax aux extremites + minmax6(&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeurs suivantes + a25 = tex2D(tex_img_ins, j-3, i-1); + //minmax aux extremites + minmax5(&a21,&a22,&a23,&a24,&a25); + + //chargement valeurs suivantes + a25 = tex2D(tex_img_ins, j-3, i-2); + //minmax aux extremites + minmax4(&a22,&a23,&a24,&a25); + + //chargement valeurs suivantes + a25 = tex2D(tex_img_ins, j-3, i-3); + //minmax aux extremites + minmax3(&a23,&a24,&a25); + + //medians au milieu ! + output[ __mul24(i, j_dim) +j ] = a24 ; + +} + + + +__global__ void kernel_median7_2pix( unsigned short*output, int i_dim, int j_dim) +{ + + // coordonnees absolues du point + int j = __mul24(__mul24(blockIdx.x,blockDim.x) + threadIdx.x,2) ; + int i = __mul24(blockIdx.y,blockDim.y) + threadIdx.y ; + + /************************************************************************** + * tri(s) + **************************************************************************/ + int a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20,a21,a22,a23,a24,a25 ; + int b17,b18,b19,b20,b21,b22,b23,b24,b25; + + /**************************************** + * les 26 premieres valeurs + ****************************************/ + //premiere ligne + a0 = tex2D(tex_img_ins, j-2, i-3) ; + a1 = tex2D(tex_img_ins, j-1, i-3) ; + a2 = tex2D(tex_img_ins, j , i-3) ; + a3 = tex2D(tex_img_ins, j+1, i-3) ; + a4 = tex2D(tex_img_ins, j+2, i-3) ; + a5 = tex2D(tex_img_ins, j+3, i-3) ; + //deuxieme ligne + a6 = tex2D(tex_img_ins, j-2, i-2) ; + a7 = tex2D(tex_img_ins, j-1, i-2) ; + a8 = tex2D(tex_img_ins, j , i-2) ; + a9 = tex2D(tex_img_ins, j+1, i-2) ; + a10 = tex2D(tex_img_ins, j+2, i-2) ; + a11 = tex2D(tex_img_ins, j+3, i-2) ; + //troisieme ligne + a12 = tex2D(tex_img_ins, j-2, i-1) ; + a13 = tex2D(tex_img_ins, j-1, i-1) ; + a14 = tex2D(tex_img_ins, j , i-1) ; + a15 = tex2D(tex_img_ins, j+1, i-1) ; + a16 = tex2D(tex_img_ins, j+2, i-1) ; + a17 = tex2D(tex_img_ins, j+3, i-1) ; + //quatrieme ligne + a18 = tex2D(tex_img_ins, j-2, i ) ; + a19 = tex2D(tex_img_ins, j-1, i ) ; + a20 = tex2D(tex_img_ins, j , i ) ; + a21 = tex2D(tex_img_ins, j+1, i ) ; + a22 = tex2D(tex_img_ins, j+2, i ) ; + a23 = tex2D(tex_img_ins, j+3, i ) ; + //cinquieme ligne + a24 = tex2D(tex_img_ins, j-2, i+1) ; + a25 = tex2D(tex_img_ins, j-1, i+1) ; + + //min max aux extremites + minmax26(&a0,&a1,&a2,&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeurs suivante (26) + a25 = tex2D(tex_img_ins, j , i+1); + //minmax aux extremites + minmax25(&a1,&a2,&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeur suivante (27) + a25 = tex2D(tex_img_ins, j+1, i+1); + //minmax aux extremites + minmax24(&a2,&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeur suivante (28) + a25 = tex2D(tex_img_ins, j+2, i+1); + //minmax aux extremites + minmax23(&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeur suivante (29) + a25 = tex2D(tex_img_ins, j+3, i+1); + //minmax aux extremites + minmax22(&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeur suivante (30) + a25 = tex2D(tex_img_ins, j-2, i+2); + //minmax aux extremites + minmax21(&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeur suivante (31) + a25 = tex2D(tex_img_ins, j-1, i+2); + //minmax aux extmites + minmax20(&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeur suivante (32) + a25 = tex2D(tex_img_ins, j , i+2); + //minmax aux extmites + minmax19(&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeur suivante (33) + a25 = tex2D(tex_img_ins, j+1, i+2); + //minmax aux extmites + minmax18(&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeur suivante (34) + a25 = tex2D(tex_img_ins, j+2, i+2); + //minmax aux extmites + minmax17(&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeur suivante (35) + a25 = tex2D(tex_img_ins, j+3, i+2); + //minmax aux extmites + minmax16(&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeur suivante (36) + a25 = tex2D(tex_img_ins, j-2, i+3); + //minmax aux extmites + minmax15(&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeur suivante (37) + a25 = tex2D(tex_img_ins, j-1, i+3); + //minmax aux extmites + + minmax14(&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + //chargement valeur suivante (38) + a25 = tex2D(tex_img_ins, j , i+3); + //minmax aux extmites + minmax13(&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeur suivante (39) + a25 = tex2D(tex_img_ins, j+1, i+3); + //minmax aux extmites + minmax12(&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeur suivante (40) + a25 = tex2D(tex_img_ins, j+2, i+3); + //minmax aux extmites + minmax11(&a15, &a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeur suivante (41) + a25 = tex2D(tex_img_ins, j+3, i+3); + //minmax aux extmites + minmax10(&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + // fin des pixels voisins communs deux pixels centraux + b17=a17; b18=a18; b19=a19; b20=a20; b21=a21; b22=a22; b23=a23; b24=a24; b25=a25; + + //chargement valeurs suivantes + a25 = tex2D(tex_img_ins, j-3, i+3); + b25 = tex2D(tex_img_ins, j+4, i+3); + //minmax aux extremites + minmax9(&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + minmax9(&b17,&b18,&b19,&b20,&b21,&b22,&b23,&b24,&b25); + + //chargement valeurs suivantes + a25 = tex2D(tex_img_ins, j-3, i+2); + b25 = tex2D(tex_img_ins, j+4, i+2); + //minmax aux extremites + minmax8(&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + minmax8(&b18,&b19,&b20,&b21,&b22,&b23,&b24,&b25); + + //chargement valeurs suivantes + a25 = tex2D(tex_img_ins, j-3, i+1); + b25 = tex2D(tex_img_ins, j+4, i+1); + //minmax aux extremites + minmax7(&a19,&a20,&a21,&a22,&a23,&a24,&a25); + minmax7(&b19,&b20,&b21,&b22,&b23,&b24,&b25); + + //chargement valeurs suivantes + a25 = tex2D(tex_img_ins, j-3, i); + b25 = tex2D(tex_img_ins, j+4, i); + //minmax aux extremites + minmax6(&a20,&a21,&a22,&a23,&a24,&a25); + minmax6(&b20,&b21,&b22,&b23,&b24,&b25); + + //chargement valeurs suivantes + a25 = tex2D(tex_img_ins, j-3, i-1); + b25 = tex2D(tex_img_ins, j+4, i-1); + //minmax aux extremites + minmax5(&a21,&a22,&a23,&a24,&a25); + minmax5(&b21,&b22,&b23,&b24,&b25); + + //chargement valeurs suivantes + a25 = tex2D(tex_img_ins, j-3, i-2); + b25 = tex2D(tex_img_ins, j+4, i-2); + //minmax aux extremites + minmax4(&a22,&a23,&a24,&a25); + minmax4(&b22,&b23,&b24,&b25); + + //chargement valeurs suivantes + a25 = tex2D(tex_img_ins, j-3, i-3); + b25 = tex2D(tex_img_ins, j+4, i-3); + //minmax aux extremites + minmax3(&a23,&a24,&a25); + minmax3(&b23,&b24,&b25); + + //medians au milieu ! + output[ __mul24(i, j_dim) +j ] = a24 ; + output[ __mul24(i, j_dim) +j+1 ] = b24 ; + +} + + +__global__ void kernel_median7_2pix( unsigned char *output, int i_dim, int j_dim) +{ + + // coordonnees absolues du point + int j = __mul24(__mul24(blockIdx.x,blockDim.x) + threadIdx.x,2) ; + int i = __mul24(blockIdx.y,blockDim.y) + threadIdx.y ; + + /************************************************************************** + * tri(s) + **************************************************************************/ + int a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20,a21,a22,a23,a24,a25 ; + int b17,b18,b19,b20,b21,b22,b23,b24,b25; + + /**************************************** + * les 26 premieres valeurs + ****************************************/ + //premiere ligne + a0 = tex2D(tex_img_inc, j-2, i-3) ; + a1 = tex2D(tex_img_inc, j-1, i-3) ; + a2 = tex2D(tex_img_inc, j , i-3) ; + a3 = tex2D(tex_img_inc, j+1, i-3) ; + a4 = tex2D(tex_img_inc, j+2, i-3) ; + a5 = tex2D(tex_img_inc, j+3, i-3) ; + //deuxieme ligne + a6 = tex2D(tex_img_inc, j-2, i-2) ; + a7 = tex2D(tex_img_inc, j-1, i-2) ; + a8 = tex2D(tex_img_inc, j , i-2) ; + a9 = tex2D(tex_img_inc, j+1, i-2) ; + a10 = tex2D(tex_img_inc, j+2, i-2) ; + a11 = tex2D(tex_img_inc, j+3, i-2) ; + //troisieme ligne + a12 = tex2D(tex_img_inc, j-2, i-1) ; + a13 = tex2D(tex_img_inc, j-1, i-1) ; + a14 = tex2D(tex_img_inc, j , i-1) ; + a15 = tex2D(tex_img_inc, j+1, i-1) ; + a16 = tex2D(tex_img_inc, j+2, i-1) ; + a17 = tex2D(tex_img_inc, j+3, i-1) ; + //quatrieme ligne + a18 = tex2D(tex_img_inc, j-2, i ) ; + a19 = tex2D(tex_img_inc, j-1, i ) ; + a20 = tex2D(tex_img_inc, j , i ) ; + a21 = tex2D(tex_img_inc, j+1, i ) ; + a22 = tex2D(tex_img_inc, j+2, i ) ; + a23 = tex2D(tex_img_inc, j+3, i ) ; + //cinquieme ligne + a24 = tex2D(tex_img_inc, j-2, i+1) ; + a25 = tex2D(tex_img_inc, j-1, i+1) ; + + //min max aux extremites + minmax26(&a0,&a1,&a2,&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeurs suivante (26) + a25 = tex2D(tex_img_inc, j , i+1); + //minmax aux extremites + minmax25(&a1,&a2,&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeur suivante (27) + a25 = tex2D(tex_img_inc, j+1, i+1); + //minmax aux extremites + minmax24(&a2,&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeur suivante (28) + a25 = tex2D(tex_img_inc, j+2, i+1); + //minmax aux extremites + minmax23(&a3,&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeur suivante (29) + a25 = tex2D(tex_img_inc, j+3, i+1); + //minmax aux extremites + minmax22(&a4,&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeur suivante (30) + a25 = tex2D(tex_img_inc, j-2, i+2); + //minmax aux extremites + minmax21(&a5,&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeur suivante (31) + a25 = tex2D(tex_img_inc, j-1, i+2); + //minmax aux extmites + minmax20(&a6,&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeur suivante (32) + a25 = tex2D(tex_img_inc, j , i+2); + //minmax aux extmites + minmax19(&a7,&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeur suivante (33) + a25 = tex2D(tex_img_inc, j+1, i+2); + //minmax aux extmites + minmax18(&a8,&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeur suivante (34) + a25 = tex2D(tex_img_inc, j+2, i+2); + //minmax aux extmites + minmax17(&a9,&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeur suivante (35) + a25 = tex2D(tex_img_inc, j+3, i+2); + //minmax aux extmites + minmax16(&a10,&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeur suivante (36) + a25 = tex2D(tex_img_inc, j-2, i+3); + //minmax aux extmites + minmax15(&a11,&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeur suivante (37) + a25 = tex2D(tex_img_inc, j-1, i+3); + //minmax aux extmites + + minmax14(&a12,&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + //chargement valeur suivante (38) + a25 = tex2D(tex_img_inc, j , i+3); + //minmax aux extmites + minmax13(&a13,&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeur suivante (39) + a25 = tex2D(tex_img_inc, j+1, i+3); + //minmax aux extmites + minmax12(&a14,&a15,&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeur suivante (40) + a25 = tex2D(tex_img_inc, j+2, i+3); + //minmax aux extmites + minmax11(&a15, &a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + //chargement valeur suivante (41) + a25 = tex2D(tex_img_inc, j+3, i+3); + //minmax aux extmites + minmax10(&a16,&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + + // fin des pixels voisins communs deux pixels centraux + b17=a17; b18=a18; b19=a19; b20=a20; b21=a21; b22=a22; b23=a23; b24=a24; b25=a25; + + //chargement valeurs suivantes + a25 = tex2D(tex_img_inc, j-3, i+3); + b25 = tex2D(tex_img_inc, j+4, i+3); + //minmax aux extremites + minmax9(&a17,&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + minmax9(&b17,&b18,&b19,&b20,&b21,&b22,&b23,&b24,&b25); + + //chargement valeurs suivantes + a25 = tex2D(tex_img_inc, j-3, i+2); + b25 = tex2D(tex_img_inc, j+4, i+2); + //minmax aux extremites + minmax8(&a18,&a19,&a20,&a21,&a22,&a23,&a24,&a25); + minmax8(&b18,&b19,&b20,&b21,&b22,&b23,&b24,&b25); + + //chargement valeurs suivantes + a25 = tex2D(tex_img_inc, j-3, i+1); + b25 = tex2D(tex_img_inc, j+4, i+1); + //minmax aux extremites + minmax7(&a19,&a20,&a21,&a22,&a23,&a24,&a25); + minmax7(&b19,&b20,&b21,&b22,&b23,&b24,&b25); + + //chargement valeurs suivantes + a25 = tex2D(tex_img_inc, j-3, i); + b25 = tex2D(tex_img_inc, j+4, i); + //minmax aux extremites + minmax6(&a20,&a21,&a22,&a23,&a24,&a25); + minmax6(&b20,&b21,&b22,&b23,&b24,&b25); + + //chargement valeurs suivantes + a25 = tex2D(tex_img_inc, j-3, i-1); + b25 = tex2D(tex_img_inc, j+4, i-1); + //minmax aux extremites + minmax5(&a21,&a22,&a23,&a24,&a25); + minmax5(&b21,&b22,&b23,&b24,&b25); + + //chargement valeurs suivantes + a25 = tex2D(tex_img_inc, j-3, i-2); + b25 = tex2D(tex_img_inc, j+4, i-2); + //minmax aux extremites + minmax4(&a22,&a23,&a24,&a25); + minmax4(&b22,&b23,&b24,&b25); + + //chargement valeurs suivantes + a25 = tex2D(tex_img_inc, j-3, i-3); + b25 = tex2D(tex_img_inc, j+4, i-3); + //minmax aux extremites + minmax3(&a23,&a24,&a25); + minmax3(&b23,&b24,&b25); + + //medians au milieu ! + output[ __mul24(i, j_dim) +j ] = a24 ; + output[ __mul24(i, j_dim) +j+1 ] = b24 ; + +} + + + +/***************************************************************************** + * median generic shared mem + forgetfull + *****************************************************************************/ +__global__ void kernel_medianForgetRSH( unsigned short * output, int i_dim, int j_dim, int r) +{ + // coordonnees absolues du point + int j = __mul24(blockIdx.x,blockDim.x) + threadIdx.x ; + int i = __mul24(blockIdx.y,blockDim.y) + threadIdx.y ; + unsigned short ic, jc ; + unsigned short Nreg = ((2*r+1)*(2*r+1))/2 + 2 ; + + int bdimX = blockDim.x; //<<1 ; // pour le cas à 2 pixels par thread + int tidX = threadIdx.x; //<<1 ; + + // chargement en smem + int idrow = threadIdx.y*(blockDim.x+2*r) ; + + extern __shared__ int medRoi[]; + + // bloc 0 (en haut à gauche) + medRoi[ idrow + threadIdx.x ] = tex2D(tex_img_ins, j-r, i-r) ; + // bloc 1 (en haut à droite)... + if ( threadIdx.x < 2*r ) //...ou plutot ce qu'il en manque + medRoi[ idrow + threadIdx.x + blockDim.x ] = tex2D( tex_img_ins, j+blockDim.x-r, i-r ) ; + // bloc 2 ( en bas à gauche) + if ( threadIdx.y < 2*r ) + { + idrow = (threadIdx.y+blockDim.y)*(blockDim.x+2*r) ; + medRoi[ idrow + threadIdx.x ] = tex2D( tex_img_ins, j-r, i+blockDim.y-r ) ; + //bloc 4 ( en bas à doite )... + if ( threadIdx.x < 2*r ) //...ou ce qu'il en manque + medRoi[ idrow + threadIdx.x + blockDim.x ] = tex2D( tex_img_ins, j+blockDim.x-r, i+blockDim.y-r ) ; + } + __syncthreads() ; + + // remplissage du vecteur de tri minmax + unsigned short vect[8066] ; + int Freg=Nreg ; + for (ic=0; ic<2*r+1; ic++) + { + for (jc=0; jc<2*r+1; jc++) + { + if ( ic*(2*r+1)+jc < Nreg ) + { + vect[ ic*(2*r+1)+jc ] = medRoi[ (threadIdx.y+ic)*(bdimX+2*r)+ (tidX+jc) ] ; + } else + { + minmaxN(vect, Freg--) ; + vect[ Nreg-1 ] = medRoi[ (threadIdx.y+ic)*(bdimX+2*r)+ (tidX+jc) ] ; + } + } + } + minmax3(&vect[Nreg-3], &vect[Nreg-2], &vect[Nreg-1]) + + //medRoi[ (threadIdx.y+ic)*(bdimX+L-1)+ (tidX+jc) ] + + output[ __mul24(i, j_dim) +j ] = vect[ Nreg-2 ]; +} + + +/***************************************************************************** + * median generic shared mem + forgetfull + *****************************************************************************/ +__global__ void kernel_medianForgetR( unsigned short * output, int i_dim, int j_dim, int r) +{ + // coordonnees absolues du point + int j = __mul24(blockIdx.x,blockDim.x) + threadIdx.x ; + int i = __mul24(blockIdx.y,blockDim.y) + threadIdx.y ; + unsigned short ic, jc ; + unsigned short Nreg = ((2*r+1)*(2*r+1))/2 + 2 ; + + // remplissage du vecteur de tri minmax + unsigned short vect[8066] ; + int Freg=Nreg ; + for (ic=0; ic<2*r+1; ic++) + { + for (jc=0; jc<2*r+1; jc++) + { + if ( ic*(2*r+1)+jc < Nreg ) + { + vect[ ic*(2*r+1)+jc ] = tex2D(tex_img_ins, j-r+jc, i-r+ic) ; + } else + { + minmaxN(vect, Freg--) ; + vect[ Nreg-1 ] = tex2D(tex_img_ins, j-r+jc, i-r+ic) ; + } + } + } + minmax3(&vect[Nreg-3], &vect[Nreg-2], &vect[Nreg-1]) + + //medRoi[ (threadIdx.y+ic)*(bdimX+L-1)+ (tidX+jc) ] + + output[ __mul24(i, j_dim) +j ] = vect[ Nreg-2 ]; +} + + + +/********************************************************************************** + * MEDIAN PSEUDO-SEPARABLE POUR GRANDS NOYAUX + **********************************************************************************/ +__global__ void kernel_medianSepR( unsigned short *output, int i_dim, int j_dim, int r) +{ + + int idc, val, min, max, inf, egal, sup, mxinf, minsup, estim ; + + //coordonnées ds le bloc + int ib = threadIdx.y ; + int jb = threadIdx.x ; + //int idx_h = __mul24(ib+r,blockDim.x) + jb ; // index pixel deans shmem (bloc+halo) + //int offset = __mul24(blockDim.x,r) ; + + // coordonnees absolues du point + int j = __mul24(blockIdx.x,blockDim.x) + jb ; + int i = __mul24(blockIdx.y,blockDim.y) + ib ; + + extern __shared__ int buff[] ; + /*********************************************************************************** + * CHARGEMENT DATA EN SHARED MEM + ***********************************************************************************/ + for (idc = 0 ; idc < (2*(blockDim.y+r)-1)/blockDim.y; idc++) + { + if (idc*blockDim.y +ib < i_dim) + buff[ (idc*blockDim.y +ib)*blockDim.x + jb ] = tex2D(tex_img_ins, j, i-r+ idc*blockDim.y) ; + } + + __syncthreads() ; + /********************************************************************************************** + * TRI VERTICAL par algo TORBEN MOGENSEN + * (a little bit slow but saves memory => faster !) + **********************************************************************************************/ + min = max = buff[ ib*blockDim.x +jb] ; + + for (idc= 0 ; idc< 2*r+1 ; idc++ ) + { + val = buff[ __mul24(ib+idc, blockDim.x) +jb ] ; + if ( val < min ) min = val ; + if ( val > max ) max = val ; + } + + while (1) + { + estim = (min+max)/2 ; + inf = sup = egal = 0 ; + mxinf = min ; + minsup= max ; + for (idc =0; idc< 2*r+1 ; idc++) + { + val = buff[ __mul24(ib+idc, blockDim.x) +jb ] ; + if( val < estim ) + { + inf++; + if( val > mxinf) mxinf = val ; + } else if (val > estim) + { + sup++; + if( val < minsup) minsup = val ; + } else egal++ ; + } + if ( (inf <= (r+1))&&(sup <=(r+1)) ) break ; + else if (inf>sup) max = mxinf ; + else min = minsup ; + } + + if ( inf >= r+1 ) val = mxinf ; + else if (inf+egal >= r+1) val = estim ; + else val = minsup ; + + output[ __mul24(j, i_dim) +i ] = val ; +} + + +/** + * + * correction de staircase + */ +__global__ void kernel_staircase_reduc3(unsigned int * img_out, unsigned int L, unsigned int H) +{ + // coordonnees du point dans le bloc + //unsigned int iib = threadIdx.x ; + //unsigned int jib = threadIdx.y ; + // coordonnees du point dans l'image + unsigned int y = blockIdx.y*blockDim.y + threadIdx.y; + unsigned int x = blockIdx.x*blockDim.x + threadIdx.x; + + int a, b, c, d, e, f, g, h, i ; // gl des voisins + float wa, wb, wc, wd, we, wf, wg, wh, wi ; // poids + float S1, S2, S11, S22, S12, S0, Sx, Sx1, Sx2 ; + float c1,c2 ; + + // chargement des valeurs GL des pixels du voisinage + a = tex2D(tex_img_estim, x-1, y-1) ; + b = tex2D(tex_img_estim, x , y-1) ; + c = tex2D(tex_img_estim, x+1, y-1) ; + d = tex2D(tex_img_estim, x-1, y ) ; + e = tex2D(tex_img_estim, x , y ) ; + f = tex2D(tex_img_estim, x+1, y ) ; + g = tex2D(tex_img_estim, x-1, y+1) ; + h = tex2D(tex_img_estim, x , y+1) ; + i = tex2D(tex_img_estim, x+1, y+1) ; + + wa = tex1D(tex_noyau, abs(a-e)) ; + wb = tex1D(tex_noyau, abs(b-e)) ; + wc = tex1D(tex_noyau, abs(c-e)) ; + wd = tex1D(tex_noyau, abs(d-e)) ; + we = 1 ; + wf = tex1D(tex_noyau, abs(f-e)) ; + wg = tex1D(tex_noyau, abs(g-e)) ; + wh = tex1D(tex_noyau, abs(h-e)) ; + wi = tex1D(tex_noyau, abs(i-e)) ; + + + //construction des elements du systeme lineaire + S0 = wa+wb+wc+wd+we+wf+wg+wh+wi ; + S1 = wc+wf+wi-wa-wd-wg ; + S2 = wg+wh+wi-wa-wb-wc ; + Sx = wa*a + wb*b + wc*c + wd*d + we*e + wf*f + wg*g + wh*h + wi*i ; + Sx1 = wc*c + wf*f + wi*i - wa*a - wd*d - wg*g ; + Sx2 = wg*g + wh*h + wi*i - wa*a - wb*b - wc*c ; + S11 = wc+wf+wi+wa+wd+wg ; + S22 = wg+wh+wi+wa+wb+wc ; + S12 = wa + wi -wc -wg ; + + c1 = S22*(S11*Sx-S1*Sx1) + S12*(S1*Sx2-S12*Sx) + S2*(S12*Sx1-S11*Sx2) ; + c2 = S22*(S11*S0-S1*S1) + S12*(S2*S1-S12*S0) + S2*(S1*S12-S2*S11) ; + img_out[y*L + x] = c1/c2 ; +} + + diff --git a/BookGPU/Chapters/chapter4/code/maskInSymbol.cu b/BookGPU/Chapters/chapter4/code/maskInSymbol.cu new file mode 100644 index 0000000..02d06ee --- /dev/null +++ b/BookGPU/Chapters/chapter4/code/maskInSymbol.cu @@ -0,0 +1,9 @@ +// on GPU side +__device__ __constant__ float d_mask[256] ; +// on CPU side +float * h_mask = new float[(2*r+1)*(2*r+1)] ; +for (int i=0; i<(2*r+1)*(2*r+1); i++) + h_mask[i]= 1.0/((2*r+1)*(2*r+1)) ; + +cudaMemcpyToSymbol( d_mask, h_mask, + (2*r+1)*(2*r+1)*sizeof(float), 0) ; diff --git a/BookGPU/Chapters/chapter4/code/maskInSymbol.cu~ b/BookGPU/Chapters/chapter4/code/maskInSymbol.cu~ new file mode 100644 index 0000000..19606b5 --- /dev/null +++ b/BookGPU/Chapters/chapter4/code/maskInSymbol.cu~ @@ -0,0 +1,9 @@ +// on GPU side + + +// on CPU side +float * h_noyauConvof = new float[(2*r+1)*(2*r+1)] ; +for (int i=0; i<(2*r+1)*(2*r+1); i++) + h_noyauConvof[i]= 1.0/((2*r+1)*(2*r+1)) ; + +cudaMemcpyToSymbol( masque, h_noyauConvof, (2*r+1)*(2*r+1)*sizeof(float), 0) ; diff --git a/BookGPU/Chapters/chapter4/img/convo1.png b/BookGPU/Chapters/chapter4/img/convo1.png new file mode 100644 index 0000000000000000000000000000000000000000..7edf4d74c08d9ce03f980fcc5c32c91a5c6d364a GIT binary patch literal 174459 zcmeFZXH=Eh7A<(R%239#1W{D56a+z_P*9R!LPaD>js}uMB}zsuwIu2xNk)*Ilqgxt zLIeaP3kay>EJ-rFxerkH_8Z-=yGQ@&9-|r7y?Qw3`}Vi@+H=i0*V^Zitn~TK8yGiG zD3r|-7tYF4DC^EqC_ksJUyE1vtNyhc|M#=SX$gh(_;FaT^B4a8%gqa_78DBi0rKCf z+ficHcyX7dxQgXvGd)Y2tLC~C8yg$$8>U7U*RS5x{6&o_#95N>3=*73)KANFsVoeP#+pDHVCtjF3iV@@IWMot6mXoaG($&|qZ=F{? zwe;$jL4!lWOMj)jZi?QyX6f&Nq1Wh^{$^n3D!25v@ZJpHy)G981T-bbBNF#5z4+a_ z*7bDp@~8NYtM{&6dR9e@&M?D|B}un?X_j5;p6%>RGNyBuS^9UZzpN+hPT_dJU0^Tfr=!#XXYXrOSPs>A6`@a!CRU6{#3>}R!n%E38 z)WTAipXww%`#H{7cGqbMYnjp02;o;s2_8w9wN#6x5uLPA% zRkp9o6Sw>2we)XTp>qU2eO{EVBH-jef+dhfA^>TO;9YE*Ygb5&|DhEG*X%4{&2uF27PCA}G2di;}z;^o~#pLR6scB{y=1nH^| zYAMncaq2!?dN7x)NRA?d$*qlZJJ_;C%Pv;;yG0oA2yR^(NaB$qcC+FHiG!@!`%8Xe z)xUApi27Ax2TOpQx!<|X7mw^Kk(Ais8yqEfz&oAI_T|97&3*nl7pThA4?KdBkq=no zSZxc)i{3i-4$m?jjp;b-(ZpVs$?u#@UVWm|&SK&HfrGsDU~iDFbEUsuaMZT)KN#|# z>K6W?$f_9PHp8|nxUWK7V)S&}A;tzlhVs(XVGl+5y6jkes?GC23%MA5w}{wkjh`u$ z7p?N{c;?s5$Me`-aBRa^ml*%e;{^ia(zr9hv*F;N|{j^o&aryB!5$Cbv&X=u&AI!}(6jt0_voWxj;U##@Yd>Yjz!;mVCXd9sb!u{Oi4jrPO&WuDcKE3yrm zO|r^&s2j`SN(xroc3lDbqaV*~RW#?GdCR=;xH~MRY3*LjNPpH)gO;3xxSY;A_g%d$ zxi+HX&$f1cf4fyiQc|+D`aF-o8FFIjo&+dun@P zs@_vK&l5jB8E3UvW3n$Oc1Kh?FO1oKz0bfQ%&?h}FV?&v&w{(jtZ?4E=h;KQy)nNd zY?5<_azw^Ip79NK!}a+{W;|KMeoob7es;35)qXhSr!4~ega=-n0pK(~Sqk>>jR^K; z>t+-GGh0vaT`%^Osti3*=D7@LW*2xbo;l~m6q1>lIoHYKT!JTiy4U*Cvw;gsAOG%` z(;&64*YDV;EBE#|O?}Ot8!fYF)b;NS8FtYB_a471xu?qK+f9^ydU@Rf(a?2|dG3mu znq|+@MHG}T?}%)F=TX*E6TqKzRd>(5!pCqWPT_Y!fqXaQO$(;GjMK`G3HHTC zD)nnHXj)bo<~w0W2!3(-Y4qz>XMqFf+*OkPh1Oc1qMn(q%w|)gDgK|9wxd- z`pGmbEmxsle^OS(s&#uFkF*!-fB*8Pe;@tQn=E-;t2P7)TIiV~{(MEV5N3Ld^OKbb z`!Jh=v5ef~*=E?o@)Pp~1oNZbrFVwU%DOAnlHJyy zQYf0C#&!LjdkMLB{*NY3$JrlT!eEi)$5I&gHZ(J;O_1CgHWYJwwPJp?xbNhR7+~LQ z3;0R9`Sow(^r~~cZH3MN(9znK@4=@fG4}dgY}b0*-PDGUQKva|<|brbW$5V0SGpt3bTGRyQi8 zDS`SYdqJu$)0o(8qdL`VRW6kdT}K;jyF&;b3?Un6-2Qrhmza}-r@*(rNN$;JTXb@o zZEovw)1JH5IzMFNj~SB+IKrwuQ|*65@59qz%W4Udr+Q<;LSw?5a?BemXM=D4{Y&GGm=H4R>z;xK$=)YBFEx^{!<94nz0~m*pEFwo zSr+@9=Tpe-r`o+L|GvNR=&f)6;62YvEvmXjC$m2U3m)wbwvayd`R3c@NvjZOcQ?-N z^jk)8GpDhj>2~HtmBws?o{!H2@$OPuD(m^{fam+Ek@m8sdCO|GGjbY_WJW3zTAUlR zz{0bXaO&y<>aNuB>GBF8PvrG$4s!tLNZO;a+*`MG=!dFuZFbTpy&w~%xB)J%GSj%` zLg&Scozn7cjCMdh-?C7aeEZ2{jiKMqJYbP{uz9yq_5i>kDJjXftR*|C=fQ4MmF$5K z^=u_B8{h7T&=d9tB{Dx;k^vib=cL&(LE z9>?M}eqhbLL}v`B_?myGTwSuPX5|1&L@!8%=;SFq27=l6|EAAYS?r9@XG z=DT-UI9xGF_2pjr)qg8a&itJq>HQ*Si<^G z0!NGhBT9ymCWvC8z7P5~0$Y*QpHDJ(m;eL_u5~joPKU zJ_LA^P@Qh9bnm*M@v4^dpe7i2pu}-7I8a6DM8b}<1x!5D7U(I za9Br91iN4I&@>w|t5Hh+F~V26D#OA+5$7k{oULS*pH|_5dgCgsqr7FVRccg6ZF>>r zggS1i(f)HX$4r{i=Q`NLN}fx26OLtNYx;1n^?M{^C9&n4AiJw2YG?kTl5v*ZJT}G( z)EX^&z7G4g+1A~nHm_H$YSu6DD<%sjn z1U@pF-TcmTZx8{^!K|hAqvQmbUUuIhK5~Wnuyu5!@;#H~g}pLgYvNkfkeHzux!d@~ zDeI;iF&S2NON$V`yWg~^hhD-j*<-sGvzRCsSIeN+@&hMsY>7W~*!9~qi+BCIY?H|4 zm-|yp72ON;Jj`N*?Z$hIGwPI#X403gc2eB3_}VywL|0T}@Y;sR971qu=Fi67ZhEy+6_%Nd)cZMs8jDn33t(@?vdr(HJmB^UJ!N<=3<+TM7M zVd?!nenkdybmG)9u2A<2kL56ZY}tNooZrm8uIK%e18Hx!2q%^-Z;X@TR+HDp<5}F=DmEet7Wwxq zM^tRQsV14_i`4$M3M2Z+rR$%J!K($)Uk5FZHyfw9?-4XN(OF&=j#wy;gfBBJ8@KNR?!rT}NllI(#%%7ev%gmw~r8aOC8K?)y0|du51}L@GICbSt~bg!r#E^R@3pf? z;^xEolhN$1M57V41u^s(NlobOgUw}KL1tRG$lStYVP$oc!=<}Nd(QFcwxx#@*1B6kV~7IH=9&26l_sZLPW=w-;zR!vPrLzF8lMB?dGE; zY~*6=m>q70+7D&V;l?SoVmqZmMFh_?+3Jv8omL@~0Qw?0^s0RnLacjktTN@Z*dIfw zW!#NWBNih?3}hNaDfH3)2Atx2}nf1ypv# zMtX7xOP~4CV$+5gJ3jf@LS~85^n~BrQVPygF5WNOtzlUu&Y+llC9zLqe7e$EG^@?Y zUbj2K<5&}W;ZzaNaz=jcEnWKTA(I*=7veGpEW{j{RtXt-Fumr;jq2wtyR_(vHtKdG zpuQw!`0Nc|<)2^2uxYOlpD^B$v*I-=T&Q!c`c__WWo~NZhKY&h`CCi-$t6Da64|e5 z5>8`!+G&dmvni2$%UjJ?AsUGB&vCnJWn5Vwa$6^otpZjy=U?&kkz$fZoONX!rrt7Z z70dm5IR$dL&nyke1KGFQ-zBxLTum{ZPWFTRIK(h(?O z*4kYltGDvjS=g|z4WB+G-bmS&<@{-BrpSHHIauc;)$zYx^Zk7BxP)uOZQhc`6>E@^ zQ&_qqQbL}tC?fUf(wN}sM!Bs#t>Ux)*SfNBvMIOovn{&ysv^WEMqq(ZS<>_?D_|p( zx=#4HM!Zi{O{>N$X+g?-#-l-M$6j$L3tp5LTbZY zwIok@l)sjmwR;vHq{iGghQiw|BZ3xPmWSeKh)-ngM-LCC6GCHM<&t5djzof_w&z9N z-^kEa!WKpz;;3P5EP=$hn9x$<@D%M(e=ZXyN+9uomk3qVaYo0DE0Z0N80z?=5h8&t z$T(G^)AgTXW@nL-RK@DDATehrPm$60#)b1grayO!`eVnxC>w+C8KMj8i$V$K#PeMz zQ;VIQh8uKTXP#AQywzIm##8W=EzIFapErgy9Ll?$Z>cH&+x-F1}KPZ)>yVfFGUm=k`%YgOdr=rl_!cAMqBT$s+Y9Wx)w z?(Xsqo6})}RWgHZ`ZCob`QjrQiFh4<+5PnK`Yf}ynQrfcQp7mBcAu~!m0N1)d19>v|y)?#?3ctcAc=ZoWFhk{CTGlH|>rWZ?}{YEag!U78263 z@$~h5UP{|#E_E?G@0$*^3_IDJ^I%kDZgZS$v7M+>mb~<{C5P*NNx#DgUCF*8-R>#P zVLN5+S6}YVwTmrW_xEi(s$cOzxp1Z~`1ZF)wnzt;>5BRHR<_kbRy&??dioz$rFwdL?y>xMD!YR!nc5v{Z*ALhZ>#9j>s}|0 zfly8o4l%Q#%9nm+r2J>_;GbVyeLITumm=yk@UnQc!&}Dh>G}(PzCMG4gE!2~Qkc~X zb`CmhV&r4jp8A`CfVp1B`zM+OKT0`MKFFQl>kDh;sH8u)F+&$Ay9y~x ze`dV*GIN{5SUGetJMT7GI`JJmTEXBY4PMacv1Qjsz7)_sIs-Cn!{P;98^{2#DZ>b$H zos8Ag;%mkV#;YYIsM?D&4YqS5#gfuBPhlOfNx&jZAMdM6AUv!!&sKs8E7NQGgTClx z^T6YiFb(pDK0W2VKKlBnt+gqOAvUc6AT`|JquLE4E-XaYLq$JfQGIpuDz&zlvoBBP z`)F8$VTN&P$w6X6^iLkr1X4MDzsKBxtX>u?7g-H8>RVtf6*sEEhsR(6Y3qffc!3%W z1n6x@(Jr~cNbamS6u3B%;w(kga2P3?Muyfh4}527Y1!ectQGf}KkSI^MQTT&QE~|^ zY&rZ2=qDz@VN)*boSF1ZBmHybK;3NgdYI#(h7Yb;wzJrNf3vQvVk9#UGcn=(G&%4g zv(u}A^=4%WDFuOKkLwm2s3a+sL4OlP&r^C@7IDktJ9dDoL~Sp>zm&tBQ|dt>NL}vdY#W03xijPYeRTY>h(M> z#r!VCP`3z@yJFq-*w2MsI?}bfZR%W8Q~X$QHhfL|ECFWV2YNF0<7e){9bkC{ooPUZXDiv~AtNF*sq8W|a>si{>X z2|4G%&z(+LoJnbzKjQ$LH;0hZ@z=DDD=et#OWv0>s$n_P8>0^p!dmtWq*Yeb#$C3k zmSEEzD?iQyCMGR9-9dP);B<#KG3_^UzuHF(0%EH-m=w0O%-4v`UtYVJar^;iZ*Bq+ zr!d~n~ShhqIVk8`{<57vR z405Y#?WcGQjyp>UAR%?ELfAhznwLl^Bwk_;5kF%gIJvmc zwp%o7vemvDInjvhZO6G@T-wt(vr*5ttQG3wFks0%TN^uwr7qabZ#E!5f7y)b`|Pv*0u_v6U+!>$ zz2n^98+j5ftq#4gh5*ySQU;u`x1Rq5lTvH)sj!VHaUP(v>X^s6D=X)w$B4gpSmV_n zZacV2u~E_h-&lCj=^>lKAka>$L!!(`uB3h<2>#ta8Ar?2SLzO(dv;fJ>djU?7+(`3 zCRr_hm>Hj^>+8kDP=G8QO-bor^9#uf6AEJ!hv;@v=Bi?za9q=;(0xN^!A4C1%#Z)WtT z=_5nd=<5GIqqnAaG~t}EWL3qrbc?zk}aLP<$6}yJ!0vK*cEDV(*T?Ne$9yy=7sMM!4mTSIs3xNHi15}%>P-)eS_}e z3VF+-BuimscW!83h%z48!Z{!^n4*?Pwsby!~w}%HdV!pU?rpJ(Lf;e(_byd}q2zGfo@zxPf zn~ntSdBX~!{zMY%3!zAX**y_%=2KrEBApH$YNrtfio#uFAY&9Gh}YWRj$d)3&J>0W z-|rQ{-q)$$?OIi_+EQ_2RcBU}W&xchGU(y+!lXV&EA`aMov(A|-LLwiZBc?P#OJci z34WgZ@oJ$$CfXykgy8a~4VpIPAcXzxC=S;71-{rqCoab$DC|}?J=U#{)T6oKBRv)( z$%27fCv=x6LTQEjCDaPfOHVkvs1nd{KU^SqHF|;x&wYgTX}R zoqWN>?i!(GZtdsC$tk9M_>{l)-kiBei>Mwb@!Z5Mnof1yrKMFYjn0en7GO@@uzqi= zsV(Rm!UilJn{-~BoNj6;@B>vyY1z1xz{{~uB;1+B3bg(rDG%f07Tm^{h1Jm2kEuAF zo}WK&)!dQ%>NEn&LOD~-a@sed%s+yY^TN7KJ0Ckw`#YB)ihO7o(?Bri!|xCGP*Db2 z*j%Pa=E_A6fpzdDsWKJswMp~}a~Lg|L%QYSUAj#aZc`T)64mX>EbR92IOkbqr3c64 z^#DnkgpQ3?F3wewWIaCxG#&L#abOKw7>^kP-AaCzKwAviy{>Ww`%z3Bl>d`3JJnPj ziARsZv$+ZJg0w(<5Ha!3f~&G7C~>h7A!Y$&;U6cH;8VJUqfYeEk0PE%Ebei%CKylw)-D zDQ~;T(-uYce->2DpHX&b*&Sjb#fV2Lm`F0~G}4|`Tf1eCidca`RRqxif}`&bSfJ9F zk}*k}26i`GwpPo2(6==o(|f$d^0L38(d$0@$XS=<#10ML%7!RXKx7NCl&97zKV>WN zIds|l?_bzxBt^@%)7L7L=Ad3Nk#j%o-PfFD2Cqk*xsb4k`C(`6Yx~1{xH#_s z;qn1xroQ5CWG9$OoX(Rr&i?0_9n=5$lQ!)M=n<1jR7%i=>oPGy7zFBnRxB8>L*eTZz!%5TXZ1% z(mycXZ1Amt5)Q|pzLmDNp^*6 zI`!Xq?DoenSR~}=2uH()QlR;m*nB*otBZl~x9Yuk;Hk7N{K&FEp6bLV;^6(AHWkXQ zaw?VJeJsEh3&*(+M=LwNK4j*GuG7Uvt%P(Af!q|};#wTLUWCPY0w+{dKh#!F%W7$+_el29$5zk`ovjI5@Ihw^ z2bq|(D{t;nf1^E5e*%;vC1n!O#U??rYkEdf{^BKwars3DO#d|6C7z;gm^V0PWm-H7 zxbOPr#-lap&|h7~QwXXIgOr$B)Ed5_A_nb5=rjZ~Rj2y7#PpzA+tx3r=H zGDbwj^!xLoR8U9Z%h8u4QU~nIq3;5SksP+r8%AWm-)>rifr=UXxo5lk4)+R)C36zm ziO7D@)D7wRl~GV;SA33PW`2HtYJ)?4qN?usD_l*tiuYPfclvje+AXWU1{GF5tEy6$ z^Vf~q@40gasAO>tocBB|c!-3<#{sxmn@v#V2@rL(+afykg?qABeK!#RM30by1C1>& z&LWo6Gc%7lBonC)e?yTJMr%kf7sCsJpyvfZ3uCqApmiDnOMcH_=M!rZRht? zMd^eB)1*a4{s~65ny~*!3%tZbu5$Y%jyTOt&2)pN2B2@}(G3^9h8USJ8VthQZygJr zw6q-p7pedtj3R>hV2UjRLZHVrx(lhsZe^q~Npt~vnR@7QG=g7+nN;4hzyH0_0$mb% z!0U;2LJW^XpOGX>EWnGG;1i&a7;R9pS)>U~IYnz?1oeKMj2$oP(Rb<4ae%o*#%a{s z0p)n9B&7tgNjL#r!wW;h=Ge2aX9ZcKX}}aO&AXv?qQ8L$#3#v18WS1lKhB4xCF2#eGi?x!%gsyEYQRV42~zzUcPvkHku8J z#N|`zIAj3}M`nJCGbNA8<2+p^`1Q~2snB7|(4_c$=b9Xd`4Si!{p|?;PCT*{8HgOT z{T8%5!^WDo%tvVz{ofK z38YG*J=@ek%uM2+O|*;4u}F|bo%@kh$i+!x{<6PkR5+_7#;Ya$Fi%oy4j(e*K& z&{u5>iXU}+Srat>S>9Ldd|k3_Oofql-GJhU5QXFRWN_tLb)O|B(%2dcP$cvZ!De&G zs#mgh;SbMecO}(e-{eIV~L~PQQ}<#m!8;jq=X19>rE=0?HzISdwBSF}2V0p@y;MAAJKC`a`_XoBwk>R_HfYvI%84M$ zrJhf~gax;XPF*2B7z@l5CvTg=*%sf~b+=TMl@6a&S64^LBoOVW&xsRLm!J%&^9C?J zcV1i|ZBT2Wj7XLivt}9wDV_N-7=%uysAby*(_39%uOznE=l2}u+!mppaANp_YbHB; z_4V|`GUUeun_tYD6Za%@E3{IxbU#}09<)#y1;PPRw}jGJsauA@vmwl=`_Jvt@BgcA ziN@NiNIFo5}_S+-2(Owy6A?@i> z<-RCdzH_-ocl$D_Kf}IIWk%tD-nKW&ADrX67?~O8g>L5xk~Lw`WICa(Si^aKLa^iU znNdKi{PZS*5bWpfWM#HF&638llGG#)Gf-se_EnY{6ZPud5pLY2g>z+vme~yLh=Q?< z6h|(^mILX1Sw<+`%kHbqZXoAOe_1D{!YqTvEx?#I8G{|sf>Xs}p)@TxT<8ofh-S+@ zj^kC+^;reJkmvqBv??XL_cb~dR^nm#E2^MoauKZqj~-E!Oy58Loyd7}xX}7Uu+x}1 zX>f$;*-@`<#>KObJcR6qBK8*-Ni7_9YK$nlovcZ#*>BrVWdQhnohkwm;!ic4raPy{ zW5hy;Ch{soLZ`8Q;&FoFvL2*ie?9Dn7o`hbW((+qOO%0=nUOs{po5pn&OgNi1u=sz^WL$e+V~vrY|!}(w`VwhXl91R^Kh^aJyi{ z!>oh!Uy_zBv4Yzp-{vrH@4;C^Nq_88?x3BpVI1|e$vZ$Ah5Fmce)eXQ0j+%<-;4^w zC>a2RuyYVGEk_79pt)%%dvyZIxR=QBi%cx;gF%p*UThUdlst~>6ZU;@wTcySD}P}N ze*9=VTNg?9{@n+q0)5D=_9di9!`hOdNgkIBNI1Sk(yNWuhW>T}mFPd_;`#M;^Y;py zf}^B{GaAL?c!=yV<}kDcR)BHr0f5`Wppsn5$#c#>hJ=OU4X?I;7v}O{`SaifI=Wx! zPIYpu=eX!+g|GW3m3gOw{__MqlzPuu0SO{7!X(Uy*OhH!m z${*V(3ZdnCHBbViXTBeeaW9ge9hQI{R|}yN1*RZnYiqmqGL6B&%in<0N1krwdY6rj z6ZyHhxOD5-U0mpQ?TW)9Xq1$c7`EhO@DGpN9v>-Y?#I$rL1b=TiX95&W(51WReQ2} zdJF(`w)MABR9#y`dHu+!Avr`|ULGyoTctA3%KfHVIo>Vc#h2wfwv+v`_;TU-WFix~tDMc#@Ua}FI^*J~=jx22-G+>T|?_6{9 zG{QJCSu=O$!(M@#uVoo2u|k`7AFD+|odDq?D4f<+R$9vEIAh7m!eW3}Si7Wv@YtKs z%*U1p!ejX9#WViaT$_{)8#it~xY{MYCfh>4JXr8DIyIQz)Kmir8JY>t!|5Z{L31qpYkf;M8 zc;Ujw^cyt_N=ka{G%1IjQ;6DM_{Ct`t^lF24@Z+myu=n_HFK?ZUHX}#I6Ph>(*WBs z3bL|MKgvN)?#VkZ<`gm)6Mc36K8FA!oqXbt=;(NpQ3{!rrdPKj|D8h?vI?hwfQikRG_@SdxHo*1o1=}!$0mAf z&NDlFzXLtT5oRK`IF|+kD7Hb{S<^JDS#~9W5WDdjXV3nrmTqv>Lpf3983+rRzPbY( z92YA^XA?nE!$BBo0w-^a1fH%mnO}>79jN}PYASW45*rnqTLlVGKZ7eD(%5Jj7#`o#d*v>Nl-AhnIq10}{BuEE_ zhwqyhXsluE?&|7;WqR!Cddi31ri=vCzgZUj($G@v}i)O|N9gkD7}Aq zZipRA&R!VhIZT`PGul&Rn}1%jMuN(n_x-e0&&N0V&1i){Jf+muD%grJZ68_M!7hx@ zFs~&TcJDSy^5o#;tbwtznQb*C?eD+;=DYg$&nM6y8LylY%CD`W68rLcaUZmPO;d)^ zzX)Q;L_$ClA>g2N&gAnexuD}_Wbkuuk@lhpg2CePX;~EUtX`upXp1e^Xd5% z_5Ar$&zl-YjvnPV@3>II>sf|+)1~v2xzo*=Ccac^1iDQOz#Tc**&nm$>g)F-LDi!h zEFSJutZtd#1Mg+zy#p)s`x(^Dp0J3YKVSCs=1ysg0arISUtiy-7cc(cH~#efFYPq@ zNmE}Rp9@suV?lw(O!^oWJ%nwB6jW6MdUqCcv9n*03gqM68!6A>#K6dJ*pU_}@T-oV zUh219Z1-DCl{GYiQQ3P2OYicoUAyWtnVsk4&>=2+?OFsmHRNLdd1)0X(bx%2v0&9r zsk&~UppiLN{ehkqA5c?^?C8)5x%F;WUrkKqwnDvP&%J>{R`Jipq_?Z4Xr0gm!>Zdg z_7}k3Cm`U4(7RhkwXsiNBbf=Ei-KG@zx$Z6Y?f(DZM4+xnp+&KhYm>y3JOMF4_|8p z+|_cL)|7(8M1nNKsG))} zMLny+?hP~LOTy(CX@a$&K-@qP)iG67RXcba=m7d-uqmT#CEe`1DGRW(hH)@%dq?cV z2~Dk(2JF@E+T8w<$X+q>moL`=`@>AM9VdK$`|UR$EM|4J{J(qk^+~{W6ZUBW(p$X% zC#PhBQqmC;tJ;>9>8%c9QXYE*OFiw-Tw}&9GP9durpn z8TkyZcrfs29nNYtLCXI50XQ577Z;@NqtxcbNd;2`Qw|D3{mu=R$ zn!LQc^`8cI=$J|32>K{85M#(&`(6ZF)vMZ}(Rcix?K12~j#LL$mX*~&H(BAeKI9?Z zf1iVyJO@7NA1ociQqn)cu>_p!4<8GX0!HWSRfZ;k1*;tkDsReknzw6#uf=#&&wX@k zZ1a-mK%sny+_~n8f`Woij%DvP51WBc&#Y@$%~c?zO}d8 zj?wIG3dN8=rkA1^eusq|&q!_lDW<#p!v`N0F6{yhg8N_jeA8@(wIr(HP&|A5_}8~L zJT;}IJz0A37$dWe1*R=RHQVCrAQmF{jp|hv&uKeNM>VD2hy;$lEpaIwvCFU5Pif%v zDvnG|J%Sw=8ykB8v%clw8T>)O0N?S4+rMlk_Nj$Xh`GR?`bjJYGFSf@YGvu`_HFNr zBR~=_ep9jJ!)!l(`}Jd2d61%(7PmxGp>rWhnSvgBg_U4ec_Q0hj+_0QX%fV8NKjDK z3fXh?16wnWgsmQ$%=_kXnj}I$ZcRf0sm|LXOaPU2pG8vyCdSDUhdD1a-V7|gmD@t4 zyE&Wp%}jD1liL>C3MPSd`^oN(?KGz6`L>oLsN7ms-luoZ>yn!=PS(}BRoed;kTW+= zZOSxBfZ|l>vv;2EWFX;Ek16E=^U9AG`X&dwQ(=|c=j!QMk2sVnj`bk`hyLB1>8>Eh zWd7ajsZ?s>T~tqM?YiyrTlu5U&_HEDOGy`BNCEx zN-cvgqMa*Upf9*-r5C{5!UC}Ohq(9}X||AnfH<)AKD6q}A#q9-PfNn1O}2{hCOO3l zJy3?2C+c&0PNi5J-7!QK{;Ko(rLZMyOu3$Si)ogUgHqzA%^Nnz%gR1Jefl)ro;`^l zKgx!AAsX)g`KOAuO%F%4>uf^2Z{!_^!*=M*@Cgg6eA%aR

S_ z4>o5V-y0*3ju+LsBz0xX*wMXF@;ESX)Dij`Hg$r7^aS&I^h>iMzIxEMcm%&k%kXZH zt>gQ=#2JZfxkDikzAC?WI=;i;dQK$g1kIl z$Le-fgzSD?9C0QzjUlLlmQe+c-La69rtoWFrt4l_KW~(0)vtubd~;=gxZTe)HwL%u zgv#L8dH-wqQ{FQSTDPB7W+LMq5*5`#(_ebB#PX4dT0Vf=+(nF!o{7oSqq{OJ1rR`p zz21%1ylm8OV!#ZvfbCgb7zq03xi;_ou=Q-FOmUYo8Z2~kt3@Se;@gHX9 z5}07poEdmT*A=9)%R*=@ICxL~XelS7$n6)duCAL_l%4b*@_9?x&wY0{a=&& z|6VVEoXg}@Oy*%42{0V+C5Q8=nSuO9dgaQ&(vvvyR*%Y_R1vM!5)x}S83g@~9nq#O zIjZd-)J8?F^k8-;2dl8c`RF{)fsH^bJw3)1eyp&CT*Df* z&Up0r)Za$uXK7{Saind-t^Q?EXnfR+i;EL&VDf#AMLLHBY=zP(y*(pI3kRph%1fs4Vm!nP~RXO6z~-~vDY z33@Q2(a!xZX^9O%EKhv7x785I1KTFQG81k)iDi;2M3}suEz8u`PeAR~ug7lAfz_8d z0+yU%H(^M^+1jWs-nZ4Zd+!NUJLA=}lKI2J!cuU$qQ_Hs=p&e~@rq3R0-b*HHQ_CN z4Jl?G3|wj~OT4Allq7sjn-G%l;mRwKg#QCoHHe~9Af!H{qobQv68-}C)4nSLd$tt) z^N$LIeiE8ccO&0Feh#*YKnn$idDo`uN*cAckDyc`D(~QsS1|Q$lvp879rgRxTkMM5aRk za{7_Vp324I8{_sq_=vBwTIWE1M=6K z5fKr!QIZTsbF;&RMgS*-BxQ?D>7ke&_%3zOU&*jUj0)1z6~IjuPoKUE8l$%|n})l| zbM&G}EvKXNoPPlaY8B<>ui-hqT;R^`_>GtkC{pKYaQpKY8Z~gAfCWeRY&zj-%Tpn% z4lcX?0*DAAFZCT9okWq<6ft@vIT&^7u>U@ymj>1Y8aXdsx>O4>3+iFI64Hi0ksKxu^^2XVLw>Hfm3&W%X$O2kc04t1IcqpSh)G$E1acW0j=&1 z(q*q~$Mm58s<5wKzg)j{YXbrx9_6qe4Dw}HzE+Cp;+zFmqE~Ej+AB{h<&Do0*v3kb z4U&hL(}0$G`3}8)%8*BI&Qe^iTS4RX16=EXnDpDWT`ec-7!G#~NmuhT{V6N7Iy@S1 z`|Ee?DJ%5FsI(6Z7=uZE##m13g4LnkDMf$|k5!oode%!+EDrj|{r&gp6?q`Lov4d# z73gr_H)*P6MDA*!snqopSyd#91{5K~fk1KCr}cTo?NzV_=olDc&`P*-8LM1Q0xrYf z30V5d-MA5V7q7?YL<_;^-*Dddkhu2qt2nK)sVA1)|M>f zF%mz%`cO>pH4lGo&G@@_R|B;uiof&mDUjX^oa2rjs}yU~S3h^|0i*$plXn5j+WO{M z>6%rPxkfnOtP*GwdlX#p+V<%V1_nuLrdeAuW+75_i>8!u zS_t3lkHMn_m7EZHn$+h&n;UiUiVtcOwulQ~Q9>jWVdn^nauHSgI)CftL+UP3x zdMm$Ks|Iv0p_OzycIXLJ@Rn6nC}C#M18S*>UfSsP_k-4)NFX3!)aP~+eQ~JA!x(a& zX@c73WMeyzI=<}u%tV54-!JgJJpuJ8C`>)|ls|;_Pet%v0!}2h!Q2CcZIWS_!n56X z=*SUy8PVzI$@xFjFp(FDO+z$c9~dgh=9}4Qg$CH2*kg0DfIOBs@Gg>YzVa0(f3r+S zax$!m_V~)@%+AjK5gkt~62vZpBc0MerOxtbn7G{HC7;R=!~*1AVkE zjOAZ%vL8J7j*(%<4nsgK$pg}v@Z5S)n63gs^jhq20eh4J75?RyUuXvBa$^4D4%sFR z@rs-ohIOTkDH_?;LW4XYetn;_(_lrgmUPcl=h_U{1G^@W4GredC28ikwt~WQeDgl!h8gl73mS6)>9S%$zb+xJjM9zf%p^i1J>-*HL7oN&;<}J@ z6brN!8(a6Qf(E^`y<>A#1)1?T4<9)o>nZ*);ZwJD?)>vbQ>BdSE#36RZEpi+Cgb04 zkDb-nkXOt;n>Vv&^kvWE!d-)TTEjBYV@p~*w8qkfk(gsPz5&k3iET@H4HgVskHg1$@mxQHlPUa#O%hG;KEvkhRK zZ!?pK3P38lUEw0UAGjeYI0+gE_$LXJ^vJr1?ASXR>{!@KJBIIaeY;9G$7&Z2;7bH& z@~giY{edtj|9oeIGX|UaBN&b)4wFn9t0QIzxrUXj@%lLYM2P@`fw9!P3J0%{<^T$3qm8!qNBh z2rXi~62x4pdtk-m;G;%GN0)*Mtsp3^c2}SK&6N|yqv6V{c6LHM#y?R!iHRQg$JM)` zwq3ihEUIJo@84$>woXLD%rO*@>Q~6xp3O)fYAMnoLZm?U&VF*JuGE*4pyyOBaZZVh zGkx`SEeu7Y1z4(eIAk+{)=2i_#~c2=h9|y+h6RT7tUH<=BM2GAB;47zfB$Ke5?>K= z2Fb2IhWtR5@Y}a<%WqaRPMf`ETFHF^mp!Ui!M`1F#TR8O29 z9W^Ij4auD822ZkGXkbRk*a=0yCjwKKgRcI>k%|!E32+T!9j`wNPvIr9Cxpwsu;ZU~ zbai_X`3*QsCBV59cqjScJG;EaF&$MoIl21V_`(JbZf;U?`t>hDk~cFxCnOn+NwgVl zSDdT|50d$SXR~6V*K(6t+Zj_6hcu_&4ql3L0{;-Lu#X&{=d&JAA%y^xqSOBm3IXBP zph7MO3{YA}zPsUps-pd1OD?HKoDA;=4JC3KG1oY_XwO&x`3eo=Xor=tgsfeWfQHAg z1Ol#4pY9agvqgeh+%9Klm-7{}=OoBT^m6r_DI$df0}uw4mB=f95@1VU8N`*adtK9NzGiA%$8P^3POh}gg44;k*kBTQ{Pb?Ow1 z%^3a)7?^l7P0>d`a&@gn2Yiw+60_~u^$k`2?i+~*A&4JX(Q9_iV!=rTaBasZiEvXYoTt)&(B*(44ixR>{(xHelEZ0%`YxE zhbwGxheFA?Th>_(@|1v%->KmIlhhqtYR?ftQ6lXX^ocXc2{eM2garH z;x&n66Lio|I+Ln94uG8_u`E;wk>7&D*f`no+}zxJWhK7LU?pTFz=?>J#lHX_FddYX ztY(H3(kJ>VpOtvCB_R3z&xYrJm2jsR$Yg9GG6orzz)E+KKILSF5x60mcurtLULqDj zmxa0cIH1%3ZHFLS-YaBu;U3`B^UUqruX3yh4Lv4N`}E~hCa{7piLuT_2lNi0Kpgr( zM4RiAH51VPCw>x=_Hmhz9!)bzc%bp6i?5?^h{7nRJpo5ijxz! z0=H1URMw|x^GFc)2nBV0h|7BCGvVLu@~O|`F2{s^cZ5;f2c;zVbvDjDMA$}Ywla|e z9@Del^}b3Yv#Tk0A|O)xs-xV9O^L}bX&<>jQ}Fl>h?6k!7=i36lf0rQg(n|POA3r~ihH z-e{Z|?>WOZJ2~wC_Ny%DJ?K*WMZ!fnIWHqFD*3;!K2JH4Mp$Xsl_mlqxa^xStyW|vPTmIU!3^5K`K*R>Y3?XCzx;utmgo6_HfqbkCn{Q zhn;kio@k7vf=IT%01ELc z*l_5ixavWm1B{#i{OgzKN_&ZOHHsd)j-CTFWzd?Q@uz6Wt;PQ2Z;`pj9z~Szf+;3Cjjt zU)TG|ldA&TC=}oAuzYd2#Qu)2jNTUbQ*?YnewWPhy4iyrGLMKO~Rx}mh-;94;alw~CtXrWQ3p5QWt4yxKf{KMu z8BHm%+`tTyJb{WkX_JwthSf|8X9DFf6W-^e1XtMBO<%~o-hq??p{qKrb6F)|I@f^E z>Sm1<_yj^utA%ljBJ;q?iADk;3N<|ZBvb^L0U&Dwinu`ZN`3z_R{V*nIfOshpHLV{Ep-JtnXK;aXdGCa$|AYnURaAn&S1dwV{ek8SAj9Op?W%RR*|s4tD`%K3aa^ zy8a;#_DwttQiJqeU}eJyC5GJztC;uHo};#J&i1dlvx_-O3O;CbpO6c|qnX7kd+)=P zfcXSaVplg8e=Sm-e98+jRK-&Z9f;Zr0G?rXDnpG$cx+QslR$PSwwV?T{>QIzrE1vf zNhznvaMee)NClILn}WPquz1XW3fj)wm{Zc(nW*KYt6R z$LwhKa3Ei*0B6K)n?gXN-NW(#StqRk@Mwg-d2_JL`lc2zG?Kr7e9?1kPoP;NZcl#f?x> zm^U=l#&b$82EmSE$ouP=9R*=#B*z59Wq_*QtTf^pn((ct>;SDDozwAs@Y`Q402)!W zrr5lqq4Uj#c=9h6YVa#)XHW9!HK6p6AxID%os)t) zH%SwqxP0i&8P5a0|oR$J9l z!`Z{!gSPGfB7j1T5CLo@>(;HKO~^UHe<2V703XH8=QhbhkdVkH=asgG^{1h-nOW@Q z9djLXqB{nvM`aQUfRrv4wy7y;#n`0d=?>{-*eavJ2Ot&u>eYUFxn*{rZ)sUsJhf3& zXh4%dwF5ruxlh3_Y#!PmBQYu#S>*~tZLQ(r;*!^}05T#>o2kEPfZL`0ZS`NucCdtS zlKDwW_66v=6vKiARMtRo%PIPis0}oDz@Wb}g_bCr(QKw1dp`B=>Os3f6%Ndwo)Wc#GcM)Ie!Ake@(l9*tM%yl>o-aTVs@J#A{Q3 zz@lE61B8_Azjwk6*)8>RbKZCR8+vb171eXZLzD zmE)C3`IAkDk}Af9+aCA;o+74pzWFFxJyYQG5W=w>bHj=Nfg|ycps@x|>j1MR1cJCX zfcuj*E|acvJ5C#F_4we~w(bj}mNgPDF{HQD`=~0EfMrz7MtCuFPf!0_L=O4DsYQpu%xtlw_VC>KAcN&w=&6rui;S6>;XOVw_zFFjq0Xr{bXel0kXsBpH`fv5?T4ZhH-W=v?t%qRe+{%(N5PjZN16{% zl4mAI#1_b@Sw?UDwPS!9BnFL!)OfnC5Y1_{j-^m}{Ytig6ea_%r9M2o=!l3{lLPzM z5-b&iF)*Ap1M^6IjRO*>*q|vo{R*UE>WI_IB{6;s$zhy8G(S9iFAQ4-lkncltRRk& zcxdnmL?={})&oAmrc2BH>{V!r%1G1>X#`*=bE$3HR2NG2-U@R1&0r!}6K|jth-Ej= zOLqVM!GO6|Si6Ve_@SAx=JBN~SBO0M3^Rl+XzIb!BfxBdsYC&FgNEQQv=R$nE6ZRy z+3!)6r@hANse-bc`89$-mzuq}G>7t|+1S~Q-e-P0Lt0AY53P)w2q=sGP8U#&OYH0T zR{h`f+#-MM)Cq{lcpoIGLt0h*-&70m8N=`%ZDM3inM1e0jne}UVyX-jzP1Rf)2c^_ zh9?(^XJ}09oND0i<*veN{(t zJFGh8utN4?T!RGppIZo*7|Zlqh~H4Vef##O3y36|Syry^u776%i_$hUYzOf$@9;pJ z`1wBS-Os?d5-(kv4zcPRr3v+s5_`bIX)HT4@B~HzKE1DP`1MQP8@k9;AMm7tB31X z`JsDvhGX=h;VM7$ss1;WjI#8F;}}yyW?G2{VlT@iRLTs6$8bkx=Od=Fo5+H1a3Rv% zX|PG3KVeB{xeHEUFcewy3{+B2Uc=Z=(}sv3OeJ9E=nCG{cSnOBLkkJXggRyp)cWcm zM}cSp+YYYA(uN{S0~=yrA9`UBSbhcdPdd`3epa3?P>jF-ZsmV-3QP1<@JSh@8^lW4 zgo?f#1q2TRe|>+ab=VjJ;?3YSqSENE_PqcVMAtr;Qj`E~KI%qTNCezE=Kx`I=vtB5 z>p#5{q@+h1PVL$A52V(ZPElXK>IN4N4Gp2*S3+d~i60(Bo9ZnMpYSD-d{*o5$8B~( z^{gynvOpI|)I<_CAPP@v4&te8{|1w#$Bi2msB6^G9lm5tY&`}T<7QLPdYyGB_UQi3 z&0Zb*+ct!KhIvS!zNnH7xBfBB(Gm5p3wYee(x%(=dprT1TGrfae|mNMcC2L;F{%fU zTyixb{TC;4SWtQ4|u*Zx`xsWbI^o_UJ*YAggz#5H`j)oV7HUq090nRM@e| zGicu-W!Dd9k}GdI%suJ)!I|fuq~dW8R2wiYhzarYcWa3WG+&+3R8pvd6+fxE9hM0% zQoPVU42M?gQ@Dfl$!S1466=bs`vFSKoUntq?Zf^xrQ=}KTS?oouD!ioHs#-~Fy4+{ zR=`(kat^%e;m!9^fnQU3zGmAtSL5VL^fmoa_O8Xw&-N7!$`rXYbqL0odVPESLP34=u zetvQ2m(c1QaFXD17)eZ!lt(D#SR9}SfD#$T9|B?sZv?dIO?(DwinGIDE5)1!t*C>T z)U}xHfUHH)q9#kL$WQn)@cp|F9ylJZJ)2Sy%AS8nc7;Qeg;#+gyNbJkVTu4^ihrD7 zc$aCVOYeB7I7i3Y`C#TZ{g^iQ&g7QD4z#Csna&C^D@};KKN{!jwIeg;_hamtRgD0& zfHQ!k)6fDm6@dm2|NBp~$b}0G?e7QU4)7nClIMz|n(u9d; zAo&8yyVG0vnY(8yM?PO&6m1YB>h#7A)sWn7BKtP4jF~Oooy*hBAa6m7IydlmYdlKYl%_Rr8$@*|& za^$Bf9?SVXzkDh!d>$pEqfX{E#>sz7&wc&=d4q%se+!eP#!~r6r5v}fR#n7q=PC^? z?YsHWMGdjuBe6p4`93ed&-QNv%!)$mlR!S625#ewcc!K|+J$$;q2%wEeoC!k&oUAZ0IL zf-ipu$U+@;cJ7B?PCq@&II?fwz9R=>e8{We>#HrRz6Kr=+IbHiJSdaB6ZTcCdV=mR zLjg*ZS&wO8#-^G**$Yrf@$I>Y)_=K*8rM5_mi$uiX;uy3N|brO`QGlp&TFxAMn(^Q zo*_AUWTyMFD0i3QTK15QhPl&!KY`rf&=PKTepr{C6fR$NkT z9^;FtrtaOWK^BM);jH-uRr#7}Yp>pQMu(7X5_J}}xQ&bkj4!xc1u0`_@T6gNPm$WYOmYiepr@=Nr*5Jmcc zX2c!BE?imMoP9k(SZe1J>v}niw-}_=`;F@IQY(ml$_M0UJRrRLH&uCnW*7El!>B`u z^7H*1zhDv`#t9PY;c~3%@!If9tV2cNiJ1jGcaQF&ItSq!nINlB;#GU0M!7+Xs;(|8 zknNk`g@BL)%m`^Y06&wt1PXLl`=CyzqPAt1rGq_*D_Sk-;B!`a4w|o9AkH5le`X)T zCnB47$}WM85;K&xe$myD2g%_H(qj(-oHQYHJY2xPhfif*P@>|%M6;5XRa!O%%Rht4k2DDe zL7qVlE&PO(c-y|SWyYQ7UFN3*8DsFnjRJD2s;Xz(2Xca<8=nq{$zJ^TUkFYE;s$+A z)(UUgq6B?mf1hl2XMK_Rb@5dTNOVfS8ai1 zELJX9+sGG)5Pf4RNnq*s^XWOC2n+LG5*1vTzak7`_MQ=L8vZQY=!NBy7JrepI5QY zo=y5h#h|!|3mzo^An>K$=D375IvCDcuu3UV{G5|Rwx~gmuBIT=v7I;58~d8x2Bt0V zb6OM%CXklfKMo_%6{~03S*XXVG4Rdp_O#qv!MSMBtvHkH@)cn$Zl&QEPY!qnedvi= z07`4h%X{!N12(5;M0$6`lUE6AI5WRjo`Fxz`8QJ_GL$3fQGaKxF#oA^g@v6z@*8X# z1P&x8C%3DVJ1&bpWm=pS8Qtg-lqC0Ck6&Qult>GIGwgY_Mt(LqpX0StlTNK7n+<>| zvy!mO-%nni2X1`4)w1BLs+!#X{XaKtmE=8j>{y6^dTazbzCUQoylsqoT#)w&NX{fj zD?A7v)E_+%JcFgn6)rfiR?3*EeK3nT_!`~yIlJp$B)ii=cNs8dK-k1OQCf$bhT1_s z9nS{TxT1=JNDG!kE#E%|oxHYsLVkMJ9SW5dpEpaIZ?@#u{&HQ}U=AL`<+S#zsf!#S!ZWwWyPmqLO1RYjE6?(wW(y- zdp(HxQJ5r%-9`X1U_$A$BRasbormX% zFLVG=q*A0^L(Icn9*P$Lf&_HMK0(FD$aYGI(;VPmBwqk^ZH805v~!%&vn_{yHxPhD z%n45KC>k4?@N7NX!h9qE!eE@vl+eO!@e=<;r*5{0#!YhBhm<={l=t}mI4Y<4yV(4? zgKsG-D{Eh7Tj{umGNT19c~B}5Fo7NPCiMjAafQ|$@;t;ZccdqaEBkDtp2FwMrup;d zt6@}%Ug$c8HAWq^PGw~!;kM-9Q%}_YCUhVh8SzRk<+19AC};sxLl}W&sOr3J5>}4k z;kE)!WlHh@1gubCUcB2l$)aVj?C4!TQl2|yQ= zEg3kw!E!thMXfXO?&Radp(wAcD*jq`@V!cTO^o+$c>Ky`|5*-ioprc_Es7RMDnrtSYmf}=q)*L zuI$JT9CpGWjYoDT#MmXsNMSmL)-tbn46JC^G^ zEO#8zRoo@eK;!;~a#UG!a^t2sK__U>=uC2yPsvK3g{1^XhwjDq#nwm^H>QsfpOFiy zb#AY8_p;`9eHnr#{U$X==P;#6#R3&8(YoFd@P4V>0EbU$(s68ka(m{oG$?|Xg~nZw zSS%Pm9{asjWH6p|CgYAwP2`$Qm3qY*urW5#SP|v|NGa?8#mNZWT%>xtYeg7?@dLGlWJP_djBgY zi2{i&TRsYVrSt4QUsJl(Qsn+X75ypo&dBWCgHq^_H#znR@y1Gi>M0*fp0SoM)jHHw zQf~)p#HY3M3`|#vM6N?o`lU0Wl9g_^j5T)X(T@<4r=q5(_fQ#2dNp!C+`DaW`8LDy z9^Sz5`(Zf(2R9cL?r2R->3NsOI)8p|W*gUx1}@^F$A(ThUU`cMRZ9YsgW^rSqi8~O zWg2$avtGG$i7g}Xab!Ce9MQj!6q zdN7Cmr9XBW9v}%M(b&b3ZVs^6wg6^+qgyF7L0#*qcp!HCI%DBwkgT0fSZ^WhZFo4yRA~XX~X|DH8e=od>t8tV6JOR0$ncYeTBJy!su!Ow|xY#mc&M?l2=lQjFD&18j zc`zX^JlnTxz(?xqqk4V8@-2Bnj4Z!TeQd!&)j@wawjN5^dDJ&DPiB1hT)p1)VI4cK z7dF_V^&mPb$KJ)ufC(puCqP91^DHO`R?_NfV53?+A>5!!*A(r+xiV^o7N3 zD`j#FLpVYK39F@?jxrHPFka@cZE%X5xFl}ZX0mf4BHeiB;aMzJ-?6rv)!L=&YNy*6 z<+LtXCW^NAvWwmuXQ76o@Ml4}&vLTnZ7S0e`sF{a+yRg<2F!E+z$q|9RgaHPD;QmJ z)Bd=0Bge3K?=lE7A+Uo}rnF`|*brpqHG8|bvtW6JUb_W}tsep3+Qb`M4R#$Tbr0mv zrBK37>f`bdR+Q(Z7O$<2ttqJh;tub*!u#iCc0>>Oy?qfa>T1uutxU_K)qmjxrqusO z^7Cr3yP1!ch1ZO`+UL%7v|#$a5g=qK?Fv*Ad1ltDF|DI>f%7&ffv%@q704wui4#oi z1Q4r6YDer0XtO3=BQkGk0w0Da)7cUGaJp|^_N^BUUO687tR*cOU5#z75%PBhsNIpQ zfdWHnY|!xHwL)J{=Wq6wUY?$1(-uk`>pUbcUyA(K=MV5m=4qsz(Ic}X%~k=;gwvKd z)wm324cS8AZa#SB1{C3ISQz{Fs3FB;l5|tD!2&3K=hm%bwF-DE+`YM3wfW0}WjCt` zr*w7q_4vN>%QY63?|?KnPCwhB-w+Qb5|NWD-=7&C9BT15XfxlOh%&VayK!0piI)Ii zk97?}67&fvJnw_04KRk@rB*%1@*sx2{sy=K&dEQL$(_=_)Hy7V(cK~33H zc}*g!hlcyN2jOHqpp$k+%zw5$5Go?c&@=TvMUiNZ6=bF=9B}F+s7G*|DLet`2|I$& zHd3ep%A7LH{Yg1}$OT$N-Z<|1h8fcW>GsUB5Wx$On*z01$AAC_cJaB%vhw%P(wRaU z)c@Q4-o1McXbjH%cs1wcTS&41ZIfJ(1hi1CU(p?*iV8SD%ViFIB?uWpFEPK$AQGkP z++o&huSW5Ni52-=ly4q{grRsOU+S@|m_v^}b7|-rs6$AG-_{MKgQ)Sl)3mweHUkrWAE(?E!b~#on`Jp6E zMwpp=`%oxd9w>t30szHjU`dG74>^qGBaqah1bn9_oC@~wiNJYGDuhHs9ELu3l6ek!?Af4GQx`D zgb&?KJ_ng)JU~Punz6x%PRK~z4v~tHzjH?%zz?R-!c<8^_w0Ky&<)82B#&fL$cyKa z$C3mK5)xl)wxihogMe`{|G6wm8n0fxYQmlW2zVe7I6`Ihwr$(`Xpq5pNd}(DyQB;K zb)F*j{|%qFo_fc5IdMJ~Ta00ptH*ak$@21=(k&DTBnL|pJmgKt3j&{8(F|R=Gliwl zgN!tga;ajiU|Y24n58uI$2cZ%F&WBX8~QtE!ax>`s$rEO1&Kx_Ik=sRF)S=b*UFm9DMJE_bsWs2m?YSXVCVP*qy{FMNhes{ z3n1t&?=Xm=^KF_O#4E5G!K2^a4NCbDAovxBFTKDqN(V`jE~%eve1qy4A~uc4TG@*= z!5qgU#2$STmMsbTUO21kU+OggSFD)u=;jg5FzSC^`(=P-QIpCO^0GlV05Iz&L+JuGS6u}ZIm>(CBfpI5JB1sSKSOy zCHzp|saqC9z#mwe2|OA7ZGpfA$l^)sVZeNhGjg5cRPUQ$4+NshOf98>x=~CWIzaRP zs26V`#-Xk;%d-R;A*NxO(?<;59uaWu-LU>fF!RhV^`ui7k(T@CJs0;boBiYo22%Q5 zjm0fVaLpPSic>?)6arFD=yMM4ObaNzPuMP?@ipGChPl4z)3^By=iiK3v#M#h zyO-%NnGluYyA15zw-0^ECiK#C4dRqS|HbJ=QyfV&;0)3J%%$I*fc;WX2sxl@`au;? zl|c(~p(nv0=yuTvKz?v5`ws>U@iB7H`@M8uI2r54SB%DdYu?0Q=HunfKgQ`JOA>3C z723P028J^jgSiLNsE>I5XZ1QQK!^*bva;|kMnC0%%jm=HAzM>=KUq7eZ6;R}!vC`pd*ZUGY}WGSWdLw3117~9^Yd zIEBxE6yC9FF()jg@d{YQ*vTkDDRUDGjoWY7%K4_zt0BB}d}ouvw*azHRa9#2-QeKk zfk5EfNK^c`IZg}c9|Ya#fJg|M-Vdj;`0N0B8jkiead*eFeG3Z4$L3@}{Z4^1-Zo&{ z=*I(tOiAuSF=ym*S!;)bdx}~wJP?Etz zclNzNFx1*;`%i3PX9>wNgFKktn+iI7RDVA>TiT?lI|8*jnFkSqIQ|)hSFvBh{QQP% zn>ky4B$9JtRikc7x*+@h+;Fey#cN#$U?HT?7i{#7)o_(WAqJO|o8FGCWP~`%A z*(kx8gh*6-6H0*q$4T2#p@4^S$o1K*tm@eA+9@t{{=+?5%a$*XM!02lJ5v9mYQlm*fa^V`h_55yqh4W}q zoC>+}DL1_oS?Z^}I0TR8C7pK(!P-k~d|Njr7!Lyxj%qwCEIbUPT~?s_jRtn-sDsQ2 zVk}5jPZoTCX2YwbG5!96x@pI~d#T#_=by2j++=hQj8Y0Rfxz&ksmBInW_kAlOpjKH zl)qA@yR+E)HsrJ2nTCjNwq}%~)eggSV{^y_GCg7k5g}2KXw}&rbEIur%J~5s0#3Ng z14Xd-XY0OMSSdk8=exWEa2ShxEj0I9sDg<5gOJRsq*+-H3m(rO$sZsCl?uPz@Pi(wnH_X(H z#vg||m_lzpNkP|O-V<7%7>u!=n|w4aLIh2}+hy+XU%=$;2Mr_Z!=L*7@{f?matf1! z^rmT@U!Lp(#j1&CM;c`!alkXEfPX>2a11z)GHaoucs4l*_|!wBaJnx`-z*6KKB59U zhjYlHv7Ipjco(GkFlmP-mW@FfrpSw7)wj4q8|FE9zT5gah&PI5I zsWaT3&IcX`r9Lq*5{+RfB@s3~dzS04l!6R9B-e`7CUsKj z0=oouTn%sQvqNN6!cxTeG0a>u>NXbc6>&JK(uQs)1TZt&!!Mx!FJI&W($69<#6NJ`#lRJ?N z4VbCI*ZgOY8CX5r;T*;=tTGiiJj9ls2@)Idh2N5-=kepmOLjx#zvDADF(Lj_yH2^k zv{rU~YNSP48r0(F@D?ND#!rZZKZhgeaz}PSlT1mTybW1HS%}KR(V{xA0d5Is^Rl12 z{(~%U!C4_9z5jH)oQE+C$T|2Xmt;#?V;JP*1j3&s4_s#Uq_z znDVATU9@vuva>B907c*J-;q1+0-cu5lqpkq*(>eP1Vc)PpRR3V+wzy>%>Za{B%#s) zP0cp{nGMgevP7YKsV2RoV-3%K{?EkOG2@}AOcBI}Ab%0comNy`6XCvu4T=H62SL7+ z01mp{c|U^g6w5&%;P-r}FaA(iSV~snhkNWruy{ZYQdy5zDq~4QWwIBQ5usir5%KBy z^&1iIN0+Q%Q8J@&4dM(?X|MZR%8hl7k13Ku5wpW+qVow6g=@4h1SMe;=-uQ3!6;Af zML?fnLHSaTlSxc)tOWWuJ`^f_h>`qKkKqbFOB)*z)jvwl+}v0&bQNieqKvd@uZD<| z0`-m{A_F|{8Kz&O2V^#I&#E7@SLyyL3YSO0Ao%HX7V;UIN zkAc}Nd5JilP?owx=*!w7$07rAA4nh=oJ{cw0XruRgCRWV-i(eCxU~CkurjCvu2{Sw>}1GFu@pXAIGPDuVT zsAnhZUS32l^Swl49*4S{paEG1Qa`BgkyJQxqyi1a{0%SiFMvQ`miVK4#QIn>!GW-d)YFwJRJ}@$;l`$*bit!n z`}^qCVC;*NEMvQP2tP#HEwLqGv1ej#XCUcsU0;oOsfc5}e83n@t zu#q56h8f4&Zr6%hY2%@ap?g>d%zwPP21du52X}x(vM@L9K=0<}sR~$={sG0j8urch zcA((g&b_xC20G&L?5lKTXu8Ne0Xz*4I|&r%ZUJ1q zM%;(jojZ5L;1h=mh}zw}NK;tcYn%u4C|d%Gu>O8@xztON0yYH!t&{$c9O%t_tRako z79^#BEqqI;Wo=HZUglFt7lc0A{(86K;x#J~T5-X0Rn-&u%RN5mPHJG?jJ!M+4d1|>deSmEdS(_2)#sKgoPxFg;P2kY(K~A6wDX)c?K;IE4S2FE}Ral4clhy z^Zn0`q6O2$SZ(jdF^FQ0{ig{V=(j&u^>AcO{~%6_ntlOg|BGhDGKc<%Tg6@Q7Xk7+hJ6 zHi8hW;>X#yt>_`Rt)u;LPUneU^u1LSr!UG^OoyD9&+NfM#9ubbEdA)bO|H(W)I&Ip zB7mMUn-?i_v1xq9@sI*VNxwVB-X%S9)$wK5`)J54Z6jyVC8r=6TEAZf=Ls#P4R9GJ zCowu-xHck4Yhn@iI{_$^xtr(%F2qR}hP2P-hwr^Sm${IGe}ik)p)-l+&ymvYMM)j0 zb4?T`J^>7;lEThF1+Zr?xKyvdh(H8I3_9%oK|=5$$Dye}z72Y~uoF90_&?M9}$YjiO^QtF|w#tItD4W}vudnE&bv&&@f zb5mFe&Rk(%zMPK`S!#}P2K-uD#`(A)#=uJ6KcC}g{ORnSqp~IQjtklzO8g#26uwjjS9!Ww5^2~Zs zv@=p1C`C@@tyShXPhLHK(|`!uL_HC2sT9H1Lq$m~E9Wp9n8(-!8mH(j(gf5$MAh z>8!vWLViB`))9CnZA6aY%wun`X^mQ`G>^q&!Pa8A7xV!#yTAzeY{NBDaF(R;C%(hU zf`?EE`50+=M*wc2vh#}ScNOAq$XpDG4bR&Kn`Xofg>}tj@!51H%`qoJn&H6k9!Q;f zg4fwl>yvI#lF+s#%m%m+hm3^;SVOr6)sE!D<+7$9pIIAHFe8_+UIrDeh#>ci1xHK) z5pCT>{85I@Wh$7l&^O>~W$ZC}qh>4G2x3?R(+iOsibVb{jUFml-J<5<#8Xs#X z*2O54$rnxCRzVt2C`O1Gp5?ss9iw}&cOwIFMTnVf;4~nqLB=wPP1Ni6Umc>q?XjUoDp`9Khg?(&Vzy9ShOu2Um5xa+r_m0@$z3gYDb9_Xf zuaTssmd4SyQM7)zB_UyeFA89N6t+Vq!ggc=l;vmOPbu#gSn7ARXKJL{V&ZO8S%5U4 z9gc4`?u~w0wX=o6WvP=XOkv!9_F%N$v<6PMb(kbC_t1M*Mw1<0f99 zX2;3AyoF=7R1YeC;<5TERfm8gaxR7RV$K`zo$7De&$y?b*>X_(nAWFLzD5<>C*K^g zt|6R0gx>%qfA>Q7uM=*RdLWO$2ThRT(nP zSOZkC1}rU1A8T4@Z&$m{G|osXd~?xUfguF^K^$94xBp${a%9ApqYq_$IK>7smr@A3 zm=lJ8fBJ+N7pRDUtX)*gioi~onu~Urz^wgoDA~NDTzZYatDLwal{3Nc~2YH8q)_xS_3-J z>^U)gK3$0Om)X^*cbyBoIFK;Z_iqxhQMAxwJC})^&j}%`>1cKrb;{Z+%jbk9wZMU(s?eRPKc!dx7hst$w2k1o}jC>z?@iLIu{3spOXg&9t$8pJ0e;*aM#(_ISB?zN=ga;{!jr=t_wPme&R3&k$Z?TChU^n46b~EJtgKoLw?#rY{Lf*y)&HPV&UdwoiXEExn$UHG4QWfEf zit@21#hF`ch^`r?$qk`%$FwxAMwEC5-SSDR7}qX+kNqL;)kWr3#$Rv1Js|wWn6Vl$ z^~ophF*J240)jwma>o-)L%1EL2rYblFwE%y^4vihZ}egmp#bMHVYqnJ$uEzOSLHZo z;*{WMtaL-8Ly`rr4N>}2#E)VSCC_LePZ!(puRD#K_)(^o6BR`KBF+^>9Lhl|_vf+; zG-VGwO0@p?R|`;s6#au_p2D$e2Pi_3;KMp+N>c&&1-~Lc^gk5(h^kb6r>P5>=0QL& z6Vf#im%r`v`t0q-)W#A}{g{NJwSOkF$$)9SIV%Lkhjz?`Z|s)=6yiW&R}(b3E{;NU z_5mtVBmDh^53*2G=91=V651m33~@+zW6zdcrj!E+W)Cprw+807+eIB3b~n=M3h!#^>7x+B+6YE(8x7n1VKRhrf~=7m`BCutTd*Y~8vSok=>ryzVc*pHG)8`f=s* zW%m1$sQ(Elf}Z0MT7qUA%g6ur>gC_MohhIguH0ceqM`A@F#?NvDO>~BjR9pp_UrBM zN8@Bl2j@zS;tZ5^3~JU!&G_{IvNEVF`qR;v-*c9P3<7J`)cwmHWvw491@8XIQ1)ch9 z1)n-JlHRmXZOiJqg%^Hn$*Iy+$ne)ms|vEP#Zi&nk5S0%Y)$D`%pWHh7~ObcfLP6) zKU&KJVIxz!h2Oa)U5d1waL`4@DR%AJj9vL8(PoXBDs&hGf?BGXdYOpT9FkLj zqH$b>fJyY?2&FQ3GqUypS?oo#{7v_gWGZhrL3?{%r#Gk-eAe**tO(Z!*nU6;}Js9a}`_bEr^ zIovi&N!8@gnI2d$=!~$*pSsNg@3b*%D|DP9kY2w8; z&}dRu4A_bDzusph{R*iI*;A)ZZ4*hBW7ht7GZ`&Po%aKcLEbWSZU4FTIJZzn3MdT} z#v0J7qVD+n>2;;p%inBVyY_hwh1&h^OSWnT$^5enP9}oPfFCheTl&*6aP~6)WSzP( z@x__%=E`A$W2H(dnI9ndEv5_|yP+!j1w3QsOT15NX{=^cA8vFjo*_TCi!+ngXnEn( z+Bt8xeem|NSU210%4f66SLUg!fW#<;0E*=Y8(vwtD|Y~u0RO}{1@qJ3I*r3=y;G_)n;vCVv?{h;pKS1 z?(;&m@~0scPyx-$%KNYIBZTchEdQhcTPaaMtQ-Cn7SziS{rn7`9bNqo#TZeF$TlfV zg#lhBl#(EUj)3H56lxI$OdpE72%RImAjq}yJBH37-J=A=VU1_^S)921LG!x4bw0Zp z0H@IXU6=8G@Uu*tIu-X|ioItED&rpK&C`A_3&#zq%gU0z`wW2!7a7cNL;oQJX_8yd zZwxLjiD-~x|9v;CajOC}sfdBf#j8i?&)?C-Qn!%#D`eDR5*br{^Y;x0*Mq}wB~cZc zOgdQZ80X(#xrG4)>2il40*fG;@7Mq5S3u7xEBJrC9}saC4jv()4>^JU{w7=I{Czi> z5)9U7YcPeEa^TxAi98QrgYW}+rvA9x#^+E9a1gcg2uLXscsN1wir%}ugM$5(j>?&i3L3LZ_ z>E)GXiJ1PgdQ7^PK1r!%2HoxPSFc~gVkuwX#qH;FHn0SD{$&jFO56@W2EoqBdEasb z63}R;HlINO`c!b@$b<3&RYt^oG zI00nMVj*<|0^-}+Se(uLCXVJdbpJCYqtNB7z7ddN{Tx{<_#RgK9gI?vPyjBaoj&MJ z7kbZgZC^xQnhJfziI%(!%-{Y@!yqa)Fj4)mhR=_ByBLQG8W>RjrHSQvUbZF5xZ2fc z6`M1`U*r~b*k#_mcdz+;`a*80)8hk9l`yXz5@1Ru2jiiTCJtcesUoanuvE-k@?8aZ z*&Zadyi0S2N}0qd|Lo^mfMu)#kRomc*!fsm=?_jfpc6?+ie@F?iE3W3ZmaKL{IP?U?~yHil7V*cH`seBSwiGM)OgX%=00rOGeKMMWvAwfQBBrlFM z-tg`67i{9>C?paQ%qa1^6p)Y6L8tMdODEGM;E=rlZb2t!R6VsY7gxCLgrk`dJw_!u zCez`9+dN>BT40NK;^%-=nHUNo?R24>4OG2EBrj38V2TbU6sj%ENO>${qNvJINJj%> zIoDj8Z|k#83p6fdks+j}7@Q;S1&IsP3eTnkW1jda{1;c>aYxM(y(5B8wg)!+Oa4P9 zep#WeX^Jj^nE9xz3xGX(j<5^Ax9j*CgECGG`4l7pBSN0P6dJ)Zbb_Pps%pqpQb_?q zmpM-&fi4&lIaHJ+u|>X<21uDd3CBi3x3Dc<{QZ1^6F^=%){cUYD17vCjqt8r_a^of zT%^*;1!YrM28BDdLMST*y0`zTLzqii2~)6&F<6F0p3dZ${NY1lfSczs*wUc;|5A^O z{;%mdmyXp8)AGHG)gL(=fB%H?sC1Wfp0Guc$4tWiPt7xfmQM!AbYb^;*IapjF@RPR zKk~Gf_(cGshBz$-AmIO$9FdE035R@%_r;2pN&>h4T;ChvkG7~vgvq{>-G85_8AtbO zL-a^zs!lEiGRim$EgEl3{VgKeNn#K4CXV`1B?D>m1wP0y){Km-SiCqC0}L@@Er98% zGi|=mbsPBf$jB<36^z9jy*wRWht*@p>V z$wl=n%s+IJ34GN{6t2w!#t@B$l2mVCRrNy$MnG$jdx5fiToh-Gy+pT;#4s}?!h*r$ zaSyM{UyDvC9@T<5)iDw$%Wu!$4 zL^^pQBqT&S%Mx{xdb05mto2PGEIwl73d_AYAHnZEbP=lKLC759bz_e z#6fHJqT%-Fel)oxyNSbs?RudW=0I>~cJwWgznTdBllQ{yJ}SOO&Cp;mlfLrudNgkOTzfDYY?PN1d6Q7 zX`tdzfe;J4xWb?a=aEz;;@Nh}dUS8N+}N?aVL z%B;m)h}Csnd+6|C(aExj?RB$l3*w!!qE*Uuu)5IS4e_xHX~2#L#Pfo3WON!ZhvtOL z4sRnZDfyWOncx+0a%kf^zpxrK=@iUIrv|&fwc>{#4u-)xPXXC%j6;nb-)!%AselWJ zQIRE6i*PJkpWS=0&*VlJP!_nb#gNTSQ7u|&4{b~6!+0Cm!XY2ZoUFR@bZ`wM_JgRS zq1q48bJ$Gy!L>u627Qha3T_lh8cjX4UXu(EW72cm_78v=xgaQ1$Z3aJM;!8MN}5Gu z1E`Ab7$FS3>A*#!pi=<@`)KF-`gOWsEh)t`rybB3?d%`Gb%S-GqX4O5>k{i&%+4N( z=7~(`!XMr|W5K`~##!&$bxCi~U6Zhf9Q;sVp!=$Lq@@a+hzFG6_WUr_)hQVMPV@6Dd(TE6tH$PQ1R_fK&pgp5!i@5BAdzrT72kvlP@ zD95t$^a#{NWnhFCw*i3oogGP1b&g4spJ3t^_SNh z+Gfr_xOd5#>Dnw)yg%l2I-dU~&2~34;!KQ=-nR-fXX(blqkXZNEqf}=B|AqXOwOEn z%6NA&9RhWQE0A^dvt?%jS<(`L7%XPh@?f`Q7z`f&KEh)$;6W|F7+?$Z2c&FnAFtk(mk zj1UP_aEHqKYnJ^|gp^F{2(K^`fn({>(I-=(E1u?(SYq-RFvTd0$4^Y#!si@nUUK^c z3i62H-Qwa_t)Dithp)w;$4}VU{5vM_*WTX$2*`YbraAw9ZM z;ygS&yx?HfE$8Jy#W!y*a6%QZ)2faINVJJ4|6CS`Sm^(L2$r_&9Y{z>@Q1+m$dAbH z7zBRa55xl(V81Ca7$4UB+0byWZH|tPjwe9bdhpL;!(W$8pMvWBvFTS)(U*-@78aWc zHbk&L2OmGbNYy5_#LqbHm4)=nw-E?n8;su6A1%Q96C27>v^T?4DrBLlrdEdq?-gto zH#W%rQ`2axug^u)zr=;Eye11e*F&i2Q0?&(K3CbcL3A^H`t*a}@wINzb$&v{M; z-w#zGPDXoJIq>$whu1jBG`-t))fCKp16%-W2 zwQ85ms~;*cVSGOzDwlJ`vEK7IIPBV0ics$w+wILK&F75-K^QalW5He$di!6E%*|R;QBrBR?5U}# z-@&{#wY8-*xqSQfZ6~UYl3Hu_$2Nnem#?xR#_AFltSKx|kPgl~e5qzDCtSU=XU~>7 zc5Kb)pFiJQTCn*p5Z%5#EFxk$YLE3v++GhJtV9X3c+nyjS65d&37JLHQ_|AHb8@&8 zgCzFI%3f9-NbTzF_4!~~Te}AjKR%unmvI4VxW__DJJ(rST0TopXH@Iy=`C}$KD*(H z*LcoZ;n`EGs;W+Uxf(WjwY{yVV22cOpOw{?(b3V65|fYR<(I0ew0|}>hKGmms~BwC zvuHYO+3OINA#T9M#f5lZnX_lNfz?t*(o46WhK}{QbCXjfY4owCCPCY2 z|Ibwk`q^gv@+D*RDf;?1VVEj>Eyl@;*-VEH?7w>QAJ|Rnu~)v#u*AinyFHb{X0w0) zbPUdTRxdV4eZ|{aPD@HkK0DXC3?WgKQ*u}Cwi85x7=Hc8s{4m*d3pK#)*KjD_F@)c z<33q`=FFMdbLVpQySx=g^R``l#q(7-Hps->{Gy+q-)SdQ`(3|(@72+Huw?B`v%}Yy z+zvzIF#CpFeK}*%y0gzRGERVOzv|^x0KTX0`*)G1_L1S=_wVO7AC!=g*n*k#s-VCS zFR?mzZgp?}kt0X2ioJr!VbzA_W1G3TxqEI*L}kOs z=uS?&0?(_N4xz8U zAGep6m0d(&U4VprX>*RQsVFDL@;WIgE=Y0R6B9c_(mFdjUPFCk-B8G$sbFknZT%d2 zI?SH6lAjR+Gczk;w9$1esw{B5BbpsKCnpJ1QTVmU&vs7_k6XUJSHJ>(k=VXx(W2F> zH)ki#PZd9q_<6mwG&jmsF|7~YS53CyIcTKiye%%~zO{UY!&1S+*Q;vLm&Rwf>gxxU zyfOi&rB^fWtpxre)htXG|M>P5UrbbT@=|Q>8twFEhkONBY~fnG`1z~ox%VGDIO5B{ z!(AcjB~UF9$jX^dx9zdUjXSHBhVPGv#)+TUUlu@*I)f$QbcixexwStEXUyCEmqajz zap>{h6DQU|tM?BaSu5psI>Frk>PNn3XocDP9IxPDZaOIv@X0Jxhx?E**FH7nBI=jp zSf`f7UtPFh!D~2+w_r(ICFxKes(C914q|_4*RflSh!PWM?2e|Gl-#;zwGVvybI7hl z;5v0eAe`Ny6PGSuK90hB--e^Qy1HAS%sK48WeV05yZbyvSfIMm;=O=mv26t72~Th_ z5T2c`V-lcIPQ0A$D6De&%i}31I+jU3e6v+ZNNBLYb@TwHr?zb_Z0LrF^YoW=+zv{` zIGO!Eve>>r4=tORj$IPvwLkLHQ6^bId!``Iv(6Js^ijROmuiZcxL-$84U%-#)hixr zj`ySa5f%T?)4VeyGxPR?2j&%0v9YmhJbt)!CP@^xsDybe41RgD0kcj+(W7x!>SmW| z8`tFn*?jx--m1uw4e;EbR7t_pJ9q9}bYkL;;jcJ|D-X5bZ6IW=Tikg?Ma%Jm?CjNI zVqzOc*oH<%3{jaZhkbYRzLa#7aN!JPWww&4Dvy>HvpXF3G4CHkSqDOKL(~Sg;9b(L~A$;h2AuwprPU66M#Cwwm-3V z>aS~TJhhd-s-oiZ@UTPqr%#+mHkhVrKhjNKg54_B^mpbM15cd7p;f$)pgRz5bP#^7s1EQ#Y!SykK*G?mi;!W zn4O)TmwqR(ko?*b9=5x|7liS|L|w>uKmidQ0!X`bm*ZG z2+PRO9uAZX--G>%f}eOcY$)_Tgy=&FfJE*352G=tuyy+Hv|e{dZ@ZGFraSt035VX< z7@bL%!V?pPv3fm$S3&E9SqBnPN=~Z*Fd`56jk6hbwRHrKY9T10a0!=FOIL zhsPL8xcq|(3a^n!`xux|^Lg#~Whjvg;GJ({PpahPuN|JgW zx~+Urmewe99WS4Ln!{saYRZpTsfh9Oc6PJ?!51`8u|Qe9udlDPzE;f!=}b$(C&=vC zGX*fkO+u)K1F>R4P;njCS=JSrE(?~wRu1q* z5Xb4XWp(w-RP17{_yQ&6Bg;0(aIT_VtTq;TnwEB` zI60?LyY_S^%Hz+6uL~f=o~71hWHXnv%V`@GdCXEoWYc48gU+&F7YB_jKr?52N2SRj zn+pxnGl#y|w|_jtu4ZJ2Lm@F2s)<2&*TGpA?Clx3202cnCd&dhYo8%mCloL}j?q;bWTpy`c08hY{pI;x+I2Uls#Dvqf) zq{4aQ?5S|KT*9-Sru6F&N6A4Oj9=Xxr^+z)+i8}ya<;aj}ONi+wQ zW!BKI2OACB|RH-&VO{Ci=0pPh;SEd-cM~1uLr--9ECse?@y+o7$tFvq}zrOw0J7@@MH~ z?2QXFpQfNe`w?-E&tsam402zR?h37EU^~w@5Xa7D4V6VDR-JmE`G-Ufd)(K+P3`tu zYUnkN9q55i?zQXJeePOxG&OCBOEE@GB4}UbcWlL5Yy|FNA~*}wA}{}hj-=+0>}M%k z@o$eEM$0QIsM$#p(UDk&a%{7_M?cj(T|-sMwVGGoba(Xxo&A2wqvW4royPpe$7jC} zty} zBJ%sUiy(8LQdS*{(7Uqo@(8=x+c7AP+x`1m>q+hJrixFWjQv*BpbGc3kaijU(l*kc zYccM8W5b7G@x#8Y;~DKHyoG~Dd6|uH5|vpew_Rzlg$w_Hv&yA6tH#F0k}P;RpYEQD z;AIpqg|7n|YK;?6S-g3=d-v`GwhIqz4fgU{n4%qj`fzhW?wZ-yj&I+PwEz984Oru9 z30&O+pOMvbhI1DrYYsP6jGwD6sY&~PeIgxp;Bv;&l3VGa*VUic%#0eu9332#a3aQu z{e{g2zR3?C&a|+w5ReVOIp%s1F~)b-t#xd5?Z6q7?iKDAw$Nq1orNwGZM<=9?!?}m z^knSXr;@yaf?2pDNl(7_M)5S(y-BRb(hH6J?Hk=sCc0lyQQW*Y#=v7YR4agY;9nAU z`#8c;lG^bN!sFr&MVk18mzbQ~^kzyOsv}&)0_=wG5D~Y1d)3&?@Vgpu`8W&sq~X(@ z1ISHCYQJ)2re~2$zhXpxZKKJ@+yf3qM!Xnb>esK9FX7_4iCHOM9mcl~CmH8o{Rsj1 z_l5>ui!}6^Ah`sPa7RC)Ter~DHN0?q@v&g#u;+(^B#_Gf?$%RTkq8sGOoRYFY6cY$H$|A(pXj_Y}U-+wnGq(MkZODTo6hL)y6 zic;EBQ-ijK>a-|I!%8&JPAW9C&@fW8q!OV;MN6rE*Ryjz-^b5i=S1)KYdoL#^S-a^ zy06gHOrJE9VpfY|=!3&0kI`jVLfD$GUb zqN5Mxj_t+Ck27YM#xy6&O`s|Vq`imR_>)iVTv;mOG-Rn9i`bHg6B?4AJJynFao83x z!Ew193yxm?)hZ)rXkM-0z*77GG3icKm04EQ*k0^lqA!R|-S4--zsfu-s?i+hLS&Xs zO7jcU=o!9S%_#0?&RlV2+NsjEteBDAa32W{WFS(kz|UH(ztuq!`#!^^)WN`DQ-MWwfi-x-nePJw=K<@@{rS^WATI-}>%HNTkuL>w z+I&8K{K&j{a|DtCsw-nnevcnN=H9V`mb}51-Wk9&{~%x>2}h-_n#6W9{@%Tv_|JjS z(OhrAOlGP6N3<#-$UN{fS81!B=K=xzyy86k{C3LJQ4W%4yu6+Rth43XjwR}W*4<4R z`Vlx!0VuBBk}|G%8lTUD8Q0J6kHHm#qpB6UV*L${md(+vOABWWfr#KJEl&Eed-rY`V3#p^@h8DG`~&F2POrC4C4~&mrA|I2c$O*`!c#RVFAMy#`zjI>b zpt^fkU=!bB93lch80ZeBEc(?BRGD8Qy<%VKIWOUGz?O@^C*W_%s+~Wb*E!nS)fI)w zN~V>*ECvP!(ic>7+sP_McdZ)GhcO>ueMqX5ahN^N*V1^1S2QdoD(|dwg}RE1u?;B{qNqZsglXLlI3Z+>>f+bu&>rdPX?kiC3(I-H$cL_pKmR#yf?5i= zebj{u_27Ph%y3sEcj3Up$wsPm8s$(i(-q|5GEjBmwJG=p1dtkOVrC}!g_D!h z1nhRY#;z`&&}R64;lT33#pLdJ$XQ;1$;xs?S^%=;tkKsfN81~cjvL6tx@|hTx|&de zX|psbV7w%azc<9Xb$7RHh>m(MjnIpX$yr&v{_=$j>u~=p?Cde}`6N{;GgCL#;RB8O-%fl`2-fhG$Ma9I_ z!8YI@Bv`kLir(gY!CO?5{ysV?%&&n%55>%Sd}C4uuYQU~MlIH-C@^KmJS;8XoA;44 ziiwZ<`TANym`=ZL-IW*DuV0^lJF48XG1q{J+1Uo*^0v_fF)?d7WZXlz-lpC})PM=j z?h0RUh#|l=dZu)|m)FtXeag*vcRA2S>S1Sm-pNvJ!;zD$>ZEXjM&P*EE`3!Om$8st zs{wU9Crt;|$NP-wa-t7`M=ej~_4Q|YRrBuMv2sek z&jRQY5^<9{wJaW3 z_Z~nVxMSx|iB<*ry?YB$^CONNH!!$UR%W=X`onDb4+LhwYw4w>n}FlRJQKw-N8P)t zc<)H+e#@o>%$DXN#vYRU_I&|(V#uW=D5#ap+CDlB&_WYeh#ZbYF07Z~`I8O~f(X+Q zaD85l*io;zha78X6crWQ4$aKWcw;QD)zaTTyEN6`6cAQm%g!@KAYDg(Bs zcrMn6nYQv*voK=El^18_I5DL>3YGeW8M|z>{x#V1qsn{+CrH=HCBVlx3XgQB^rB22 z!{n=0@o=~fh|g2ym6V))yWod#fO6ZOGvmPn76_z@WTf%-P{?V{)E1YOb$p8+fM6*P z)@OM=ia~$bPz#h8iT=3gpbr2C8BHpGZk3 zpE@|C?6r_Cx4vCjdG77PVE|mDrDv24r9PM8-nTfTtgvf~qXSS!)l!>D+*ueJXW+HDel8H;1B?`6k)Bag zFe?10kI*Yc zB;40)U%grnz5v*}CNxr#9o^m0=;}W@X;8G!t&gK)5qMemcW;@+O;tdPU?D+EN2hHA zpc|{H`t@EuAm2cME3*@j$fF*zzs7JBKLr;C~+&N}0 zu1moDdZf$)Knuxujj#eMTD_R}2jt~Bs3hj@1<&sU%7DiU>_a)}nL|K;yyDy^8my-# z>z_K`;yr+UKZhaD#Ur*uP<@3#Rluh7r%5-nX&A@Z@f~6#-@osynDGU6Yph?QYi}<= z(v&q<2=sNjuQJ>Bpv5Tym?CNp;P%3T3^96IT}NkK&_o!Qaz<-SeLW5I*mdCB^5X`; z{ms3!SPI4QW6XdUW;h-o>Ez&010FU$C1u~x0@9dAZvhB`MLsxgf&|Y{$pUi^9-yCA zC0AhRtQ@xJs&ql^jrvIP0sJeBC6s4mcrdeMpGKclTMNkYT^a{63y@#gAXjfI6O54w z`YQtv>iETGe-!6PS%o2O%zOX{3qgEa>ei8q7n6><0*inhd}cJy;LUk~RTsDIJHkGC zgB9aTty0+L3mdoRDMbk_j%N(+a?|{U`EXXC^NSzgtcl1S*C6EoSYMS%vguwSAr(*0 zUm*rvPUv@{LthcMP7F5VMx+*{F?uX4-6w2p_(;fbz{B+OlRe%4bhm4+p3{T$bZQ)> zQn{?(u^8+O_G+j)HiAVog`hHTjqmH%uZztegiZ68X8rtmdOth{j+b0Js;{lxeEVRl zB7*i~_kqw7&J7#VwH8PV>cJ~@D5&Uu$e#n_G%P#%<3}uVo|A#+P8opK1vL3kfO+$l zEiVP6gs0g%!Mp(zj=cJ8hyl}Y;;&q>=~(Ch+G`uF#s9_;18};t1`Ew91We9azFwdv z;INqp`bMv3|CyV#LH&PKVIi%t5Ay_Ut9Vx1J% zSSS`%90(Dr`u}crS`sB$fk~4n`_G7q4M!aGaQhRH(r{T=EHAR{6 zc>$XuD=#G#tT-x%NV5&zk0VT)-?AbdhLGW<{qY%o^(2S7f)X4=&o^@a{Q0vB`ANvr z9Gr&7D#Ir%@#wC8+#1>z%!OaUbWYcr%n-Cl+?ZYWQ}^DxI|T)d0I}MPFmJfkQ||?` z-6nhcM~@zvNKUFc%F4>d6lSI=1uGH*!0s+EfbL6w{nRh1Hs>H4{rhAa2ggO21J(5O zn6L})-P?dL3$)|T(1QpYh<*tX0BA-sIW?7_auPz?YLc||YxeTp34Eq?p|g*{MB(h& zvqhEJSH#b4r*tT7!9N~bcp{r`gds$k&+c3Ca~CsOe7SjPV6>S1`|<2A4-@yWbpKOb ztwhigSF}^d3XoI*GKSsT$UFhfb9?2H^&w~7gqNH0!r$K?y%#DEUs_%~3nms-(N1VO zGan$gLd!-=dXkRhuc`dRpEt7U&+QYke5|l1uYK9?l+g!&L0m7_Sqr{i5IzqePBuQ+ zhLgHtmXmLqlv2=67B@3vEs;}5J&D@I4(vGA{{<1D>qv(XFpW#Dr$#xHjOe&fikzq8 z2G|`ZKinATN9SU>@_61!NCHc?%q|cdCiH@GRHQ-9C!dApoY>FiLMI5KFtNgsP_=f!uW8&&1HCA)!_&^ zjt>LOfRmf=r$=As?+IutaWE$~^~7eb3xf#*2jO_Ty8xwX{*7@|VV+nV59We%Na9Lr z&ZT$}m|iYLhyD;k{B}5~1i~)&B??Aj$t4+`2;J3V zOY%+tFX>p(Y#^umJ5I4AVgh7uD1=isa?# zIpZ0-fvgnsI`9;SlIgvmdVu!a)&_YCW9zBblK@a_;B>)@tl_Z-4VjnyxdG~&7lgXB z!Be<<>@R2Pc@&TUIQVY#n&LEPQk<(9(RY1O35jRhKc=^57lVs#ea6~o!0WN&?*U#H z0xuR-4EhF%7`q)8DmGtb60I0ZDBu9)69xvxRpSFFuU0{WMKx8x`v=-8j`Fb)+kWSw&25bCxDo)(g#+J_#e z4h(K{O4~=ydT05w=o?foxPnEgqjY1z4^$;5a=3m@hS@ubNJcV*KOzd}_4xz@R2=5o zmyD6PDZoAHa4T@!*_iXp${EEN%`IK+!%i+vPU8MYpa5a*uFe9$#Duj>`Bv>F1k7p` zOa?=7`iJ!03@zoyn4PZ0=8Y3bsJvh%wHa(Tx2M^4%QHICb;jMX%#0PJC$z zUXnmo+s@eFg10sID0pGtt28C9>bd88-!nGwRzsn;BD8~9QE_n+UoC1zF|_;tg$80Z zn!kdV9!}LkF7}Vo-vK74h*NDSsx>pSvIZ=czFOGwhiHZ(T-0=SZXuINKHM=HMBX!p zlL+A@nQF`M`qHv8a#(m@eB}w+w+@m*TN^(=KcJKkTnv(Bp*q3*9MK_Hlm&KMEY}A( z3c5lxOyqkmBD;65M{c-zxd%r$hjmgM|GzZ1n8#-}MOZlQ7d^^4&f8>sK9i6wJ%^#1dW^)P3^bV;pUe zz7t_dvpExTcmfd{>sp>c)YLIpe+WUP_{^%BJSS=77WOAv&@?0IZ*?y>_ku#~YVZyJ zAOUSQuLd6H4k10tN1c{UXP{+c@VnECRAR=LZ7jeE$}8`&E}p=q)&3Sru!}S?9u_-u z*2m{kRCJ`8tx}n(SU1T3snC3O>~P!u9@u;gzTJ2;&F|aR?$T7CI@hPGK<3um-K4$8 z;;GBSKoef*xTRaik@NY^P27n=!ftGQ?eG<2(8ba{kN8oQuCU`0XF%s!8*Eyy6mU(R zMU7P*U#gSV50Og*l__F!jT7*IyMuN~g0!jm-fnZv<@Yajv3+^QCrSvY&# z-F+fz;l{d9O1`1|=g&VYEVnW^5cD>0VcbqZ#? z_1BdN?8}Y$w9!Rl8X2vYNMvYUSU~=1^#g@jAY-R+1HenA`PNIX%3aYx($pjO<>FBg zngCf&O26zjB{N+KBB*904o#NKxj9i%9%^l&1vfE?DM1{_A~6p%9Fi9;EqeP`S9uox z0&4ew(ae=x9nAy;R;H^vHf-G*%>`z7^Y|#%9>lC6`gfYnjR*8g%-^!QnBA0!M4Cus z6B%A+!{ePBu$uHYh|-V*GdTxWqqTgKv19vAX=(48m~eP|jP+J@ehx%-GC=Gq_3yB- z#L}bWEMCj9@AOCatF&oii#uD*AG=ebOg9wcZP>uc8H@G?orBrHChq+;7yGb^mevwm z7w9(}Kz_Z*D%1~F!Y zo`aG=WXiUuPWAklBOp4?WU49ihjVClgWS+*ItUR=TaB*~)Ezf{=#l&(mCV=;0$2&- zP$8rd;9Claa{U9##g_q{oe7eDJe|CN7#J}fRHrVb_t^SgS(=rqpd9zvZx$3tTT;Ot5&^rkh}`h!Vh;E=|e?r z{j|^YgdVysxdv=ayg5Zkr+I$iOy_Jy?{$QuR*3;Q*RKTpUQe&6N*}YED4c8J;3AtIxD|b;%66 zq8&FY&E(`s2srOHK8Te)H&!MwS=M8*&-t2aD^IqTo1^)Vz*L+1pzhhZn2- zQ?VaEe#HFUruq2~XEP+Iub)1aNW3#|4r-^_KNv`J*XQ<|z)*eBnTK|kIB0=*kv#?l z1>q?>I5`oqEkGbB#`ot1hw+ zIA7lT?w!QY_`*&eoDKVj)O)d(1v@k^Hu>^W`zuKd4i0`grL=JE!ySgV-Q7Z^$>Ps% zwv@w+ov@-)RfD)n1iGTn?d*VCBQJK|eCh{y(+FLDE}N1h5+i~4t1bn;^1HNd{rcxf zxU;17QG}4ntF>>WS}!6qs;!XU^KXy8Z~U zVM=0?8e=MaHw^ysp08=#-Kwg<#_!>>{iF8|T?<9<)9Ft-bLPxs)6O)bUYZ1vQ*RcM zWiS08C0yU5v8wAq05OY`)$wW#D|bjpu&CMkkaxQ(2bmxAUfYPkUUnDnS3H!iA4cd* zX>-xB99mb@;g8(^^^C%XsPrgQ!aYBHBerx+`zt*C^KIJ=u4DJ!bx-%pBy>rfXWO<- zSUA`R0G-u%ZhCrML7`6E?XoiOnpG?&!~LD|FlNd-xLbML$*edZ5Jkn)yITdCZd|_( zA`N0@{0Fq*wxdN+4y-T|f;am{+p1q2>Skt~#Emj{MhpSL1><2yvX&+WR58ody)jz2 z9?h99UX_4de9;P=xk>In{3g|UlYx)VqxRr5Fonj2_&{yY9Q^_cEq(IyycGLWZrI4p!lFa?>_K zkzWTFLIHmD-@ku*z`j#&a`p@kYjwl4cSN41&D&q@^|By07@bvq`h**&tQW<>Kn6D(Ukh>Km|xtEc-{Y~X(X^X4Yy)^a1eNX&vf7@tWt;=IqL@iEJ4Hg zLM4Jz`~;)dk82;pOUkeU^3S=Hzn%B}VN1Qt(etwMIo#1nEvZsNOhhfSc4 zC?P1)j~|W`nHcjOoD=YRFnwmt0`4IY6`^~dS2HcU!_##S||Qg$<9PuuNC-+ zw&!1=MhAa+G57w`9#K(dfQ zcO}IVbx2r2Iy_<$OT{1}dF1Hwh8qqFW&YK8A0XMR_0Q6x`nc{Q-h$$S^yqZ&7MdqO zF4!*HhQwW?1%bC-64N{ZU3;X@ojLa;9drnc+QJIls^6VvHNhF z`)2T=0QXW7Sp$C!u1UCZCI4ssewf4o&}LK~58s^i!4PtSRpgA(*7^4J>x2GV=Rtsz zz~X=#9Ib-!8yPRKL}Muq78BT|!QnqM7lf0U`2haX{3-JZXL2x4%c>hzEj zwY4)8q0tg|ibN;^1P1D|OS+1GY?Tu2TkW%WOLGGqnJth9z;7ldgBOs^=cDl z)NJ>Ka=)T>uUz&;)7;wDt|Oq4id{JeH< z`08WE#*W3S1JJT~_7>GAlvNrVGw^O6`%dx_)Rj^dxN#c-0wuLY}dBJL4(>;p}M24Uk%9ku(<&AqiPcEzf`D(%W1(q}tr8QqG8Q6aIOdwZ!? zPu()HX=#GcJ2GGLb~1hr>ZkD6Yt-VAmE%XpO^7(Huh7iY^rC>q_gB}#2!Z+mI6FtMqA4wS%=46^VhMEwDuz^)Ur!0-s zR}EElRYC6kaD2Il3*;Df_WjFf zx@^F>ro1@P^TG!75t%b(>Q)1GZ3Z;NxG@x`iOmtzRk`nf_E)=2d!!oU1(o=74dv@k zd~hzj7P#F1_uD>w>ksUNOGQ6dQ-35ZfC7&!%?2;;Lv5a?_*7ymCVPwp3UhPUKmr18 z=kNIPVs*Y;&~nRepokLwKQ9Ua9>)q-$oo>(Xq^BQvuBEjmLYU>{%a;Zh!(Eyt{Cc42Ky%lX zN1N1HND+oE(kz49&;%h*iHeI$PDlq<`Mo8r0a%sGw*Bj43Y*?E#J30$lE(=h00bJO zRITrV`kFM8V26=E`nT}NA)7r9GKGOU4nRqGUKs~(l#=Skht!kK1v!%_iS~pP5q`w=^ zlWRdWClK6OeQ)8Y0<)JKCxNixUTy_OJSsZ+JYu(+o*JaraEZNq?OHT+F8Ji@piGRt zP9NSKk4&4Hv$4ud?!^fN-%52+K{C&<{W)zjbN`U|~#y z=t&e+-I;1n26jZaRWEkfuK5b#VRrj1g$H0jvPqdv7*TK3@-eL|jfvfuf5d>tbQ#wV znN4XuPdW?w`nV_-R;&W*uG!Of~r9-3X(sVT6z_j7Xe#n@LCOV3uNp#2nt z;7!nrC_6f4H?y$B^KGQH5(#mms=V(l^5!nS85TIlpT}qvJpFwwC8c53aHljNEMy%` zSa}9<5sB|-IiP%1K^I(e>*WpeZ-&9(z3uJI_mrerx!+wvLThjqR7sMv0M*L>tyD;V z(fFqaY8#9W7+(@bu<{M%C3!tXL%9#Fc3)fLTWaH>0fYzbp#o^tYiIn2^)e_LgnuH? zaf&=3joddJ!7T&t<@nSf=V6E+xap};QM|{$z1{BQfh+}SFhciz&Nw~Nq?d!95>a?b z4!^{CzxIF22R}S|>=+FNQgRvJ32xM=;h-{;`1p7=dFbmTC{HQOxA84Vkf^+s)blR47Rii4!Sozdp#N;)ASa_>fb{CNbF|N4cCQ^5x`mSM{P zwvHie0?a#PH>fa6)5xq7P$!|pB@|_@elJuTD8@`ox_5@)hfy~>kXr+3a5;nx3zKb| zKceY+N0`HxH`ee_emXTAAUhzB9KG$BaSoB3?g!Ys8~pD*PfkoI8yR(lc%YDjQNjjf z+`H7&)tolas_@a*nNWh5l-WjR$TpHZN1o6KNdZNSxLxmI#5vn~EHsvQ*J~p?cg66M zy^hvtc}=hnEVQ-jYCI@P2J)M+p3+;1q{NdxB2a@%@f?wh{oh?*y?Rw8I2d3d!37j+ znd6;kRp_ZE)`yh-d+CxViC~$L2T`@dIr{6_m6&P_=P}ict$#=7u%HN#A+HY6ngD&> z4oWs-7`TJSppdyLZ5;^6A4jyfAM zZ-clPj>8xS6Y>B84J`Tl%j{_XsF<vPXkhT%_QDkw_4pQpoyS2vKzmwR&rJia z%fZE^#Cu||lVTsh~m#Ynmq6G@#WMM+el9!DKbM`>t zGWEnxL7&}6XeVM1ERe^_E=5*YB-EKj?gIxLkNNKX+RaYntUn#Xi%##Q&VozOysQh4z8nH*g@W!{}@>Xc4*m# za4=nvddN(w{NI3~i3^mlbU`2GRnVMkTQBRwk0+$KSlkf;_HATra|}!ThM?Js{-&~& zJ!UavWC`nfp#i{tga#|gZ+Du!VDb0B^C+z~i)p!N9jzrJbM+-NbdZc98ISbpM=j;@ zp=8aiTeoO}QgCdcCYs{<$<}c`%E5?MC5j5sNOBwJXW?x>Qg8!}*`$MlkzY`d9ywPn zAaM%T@Hb%R?j8dsAGEMeL&RwiYI>T+_h^hNPf}~KKB%?475nh zkiE)Te!i+v|M@7{kyd*`3aP?-hM1qH3)(L${8>rKHh+4=&+92ex+}!RZ)23p#R&2g z8>K-iz`ZFla2c(^2%*sa>DAtkYGe=P&ZBnUTBZ|2ZMvI$f~3pJ$}+C>eK2(f8X#C+ z8~pbf-Voj7l?Q``!*kFBP;p2Z|2&lYFHOi^D&L;Dqxem%i1iy0DF@ww08>F%`2W9r zmxd3|1SvSld1Pg`0<-N{t)^DbOJCJMHXX&}qcQ;vL$ zs<_C#g-^9K5U&0&MEx*&ck2C7XgG+B5}lmtGn#5)8)<8qYJ@1jK#Y=GNv}#VHMxXf_F~szNtoEe!C&lCpYi?Xf`z@a{?sfIH7747AMjTM?#-bH+p>3hbIsK!JfB6Xm}Kwy!& z005lH*ZX9_MJ2*5;R2NWCfh%!QT_&(?We>`Y@{7nrkfb8c9W)Vq_{7RFJCkGY{(pb zf+|mpZJw>F>3!!b`hj@C7}>=a=N9@g=x-HJdubb=!TV@kwC#bml%R2ls2k9NwfZ6q zyFLR%-le9hot=}D;0nm#_mh!utXRF{$0euMH(3$rUQeAo|y-;s88-p z7Yq`NvA&gcu(f)DCPXysM_P2c5nqfoXUKy6$27Z@1CaF-gRn-a^7uuWEh+K8Te5R= zX(%P7rFSYTO}{#bpd*}y!gt#6m_;RyB)*?+eeLb5Zu>+uYk_Fm%`f)x@yhT4*g+q< zC8UC4y{!12n%kW9xpi32U%rq>tGi$0DW4WE9_ObNu*bpWV9IbgD_;BFwz=ZGb|-_V z@Wl7amA{_I{hE9-a&ykqOEF#WKw*l{9yVDWk;Be(pQ z7f|2V0D3bsJQ|f6guKqb_hq8MLHM)+c{d~Ic=tY_03tC#Ipq{-9S_C^Jsq0v#|)>SK~xAW=K+daOAW8pS(;Iv0ChAI&n&K}g#QpPC=ENS(t zaOrwsN+qqz9D)RAa^JNmI^<6KDa+QPiPWDs`S!i0d&^k!u5tV<<%kd$CtgJB&>#az ze?6fW3P)vw)(8p(<)F0g%IV3H&4Wo@>CYT+_JS8b53MNcmMs}YMa0L3G{D3EECwAe#{OO3sczz6>~E9b z5PxuaopNaHjGMaNt8Ifborf<5XPK@}FRqJu|HeWkQiMTg@~~HHH%{AgY30=b|FB`sA&I$(7Ic zMzYWv#SEzeppvG(!3Bp z(&QoW_Mo+z^OrPX9bg)gg=SP%i<}SqKhOGkFP_vBl-FULW7%ovHgK##`_2qdSjm*w>?{!`4|g zT(ytcAxg~`GerHK|GjX+x5{9K@{jQvZ4QzWKFzbg_wT>-=9)>+&>IK)pW`?CVRzMl zfR3ic@sOU(%uH@D6nAq{mC+rDOx!Z%w~kPuwops=S4*`%yWJt~1`A?Bb}yM{PPB;R z(-gJr(Iby4p47IU+klp!1;*e5I9zrO#59zyY-lJ#o8H*$ByvGE20Aq5ScACG4u+=y z3<^?Ncv+@-!yhx%h#Pb+U(sI*jEdB2Ve8$MHO3xfOFkh}dV={lFYgxMQ=&F67{)$6 z*%;!ON)$$>U+y=ylV(zcgw0$FP=> zXOxv~P78do%k!r_>C@2C8hRHDsnl3cL(|@$yr>q>e0%j^t_x$^9_O78!|V>gk&pWu z{2>|0KxaI~9i8OxnNl+jNQ}CvO3y;|$fCj>X}=CcjjIgi9ej0wTer01Bq+W)iwpG&`bO_OG}&4q60 z5us~+>keZ@qsm)l1;JV$=+~?no>eHlcTQL~PVSHFTO06gYzqF8AaiJIB%RM<_zz=T zT$KMG3yN6I%oY7+VO52w#NxyB9<0jjA$!L*agaA=)?k&1>%-xen3k2;`10j8OXrpK zJ&WkoIsPfF@8B^n-V!JRP82Z6a;d6GZ#W=AnTX19&Q1K4YQ-VWRI^9O?n@ChI0|0g z3#5E})E1!83a(q~zw$#2if~bkP*PlkBZGfcU!EIY{L1=3%aFJ4IW<~(o=~dFyb&jA z(T~&SziPzG$qQ#BmF1IE?5nTe!L7Ro3X^a6rIp+~d~)RX}Y2wfn#~9t1yM{-A;;Yf_#ZVLM%*sf9cRdMWgURos^@R9O#gcUy zuc==s;pF(bwGT4TZ;vgbDsPJJ9$Z)(65?#8aaDWB+i440VDX!)R(_L#js_y%+>(Ez zJg+V*3PVDRe6LaqsU84)gv2a8*M134NI4KvtD)XVk0k%T`tIkm-kWDEvf5i zX-pZd_pSatyy75c3rA}w49*zJU15g?bwVohrg$Hg13M^lsX3#(Ar?;mUVV2IxpNbo zqs=YQouaAa@&E2!1Eb~*?9K*UWS468sAcvmETz;L{AkEb+4EXG4je1D7$1m^bSB3I7#7v;IK(9n8tUDgWPAQ9Je$TF+p=p1( z8a&Zm1~zz9Uq4+%O_Bq(7W~u3-dVsh2Ca5Z%q+6nK+nRN?E|qc0M@=2=w#^px#LE@`3^;kyXQ@TV$*-|_c@O}3yNcP7M>tK; zUHZR+((}E~>)>=_R<%8c=*6gNBytLDC_%Y;qzztekV39m^XN{El~Dao^xsq@<#*`F z_Z#8N5>gk!8&|D4*4uo7LTfrIPVIYKyF1$qP5pS0ZY#eE^j*WrDW?sMV(tI??T1t$ z<#}rn7On+w)V$7_`K{l4Er3oVHU=igw6wbMQ%3*UczWleV5eJ5!=n!yKv4{qIdiV#u@q&4VSNY* zmvnTyE=i$#c|3SF?jS2pR0x}py#W2c+HFH3@3x35agH_z_EHzYE-yK-PEP` z5Dw8iZf261IR0N8mR&;*Z#`rwq!0e4Qt)<45e7#HXfzFP_ZwunBz)=`*eirdMn5H3 zP2y~$A?}5_g->IUF|Ahn&OyEvUi0_7*ckDI7+$5ypBNRDOahC!db_Xks3@Hm9LH>c z=Nq~ThbtdB!U&SNC}`0i$|!jmxlS=mM}wT-VpMd#)OXSvVOeEV)YKe;5Ayx_^+iLN zpY;N*coCIpAeFzhq+P<-5UX0XQ>X6Hq;I>K==qSDm#HSt*=$*p{(+&k@x6n}YDWaZ z>FFjCa&p(yC^`O{Bgn2~I36o`w!^=toAIzdZ}BCd#KbNH@;(r_=My)?$HxCIbR1ZBQ$B5>c$+Wy(S`)C znmF^Lj>j|S6jkQ^57n3T%{%^0mOQtU1N{qXj4znxKyA6}lF#R7YY6d$8pi|;{C7%9 zj{iwPzaFGzj-1J_<>cfhFpKgtXb@cO51$I`TnwaP6%y(k--o<_m~jwI(nek{k&ISC z*?lbsm1G5<_LGrzTd-I$D0ExOt4Aej!F^T|`9>c*`~aoTPK z_JskzHZ0+Xdz_3TL0i>3$-Cda*+a|&BY6t$bn)~)tXXm| zt*xCY;x|RDr~$}dL#iXJH^a z#BUE#Qbjx4>#F1-x-cpv5Y1jQFt-J~15GJ$s0B#oWcDJ><(lcx#1$o z-U_WTZpHMmyH!og?LmK}``}%0P9!-K14@wgfC2~p{`q}B*M?<_CV{#4AHgF8eTMdH zItn~$pn@ERw?P5m7iS$t=s{;1U!IO+64$t&TQ9y z!^X@C&f(24OJ97u^bwBs_RhDkP^J&Y#t9`k96t$`h^Cw`Y0H1oUYoxp_VNg{&P(fS@+q_-+>{o|-1%fG7TE;mI;NUj zihoDd5M|>2RK&gp6`bY7hT}ttBb%7@vyh&S&dx8`3|)}Qy$rPHy@KQ3*5001SlIb( zY0-@vHy{kvgYQjlOTg|Y(vX^?SI7#LGN1_#_a3Me;F-GtIF)7F^YzG@1cR^C*VWN| z#C31(Klgh*INO%BW_w;)idtfW6aU5qMazR;UQ$plcwm0dqsriKj2{>F+&U;iA&vr` zx%$`eA}FNs@iDvx@V+QDXoro(@gJMKkDrOSJN|AnN05<*M_ zp!Qlk{hiTy(68=dV;{IOnZZCgdHG3<1NaoF^!HBN7Jy}#Q6bdXlM20jM&(C|ovn|1 zPO)f0JL1{h%>;XZ#y4-IM~Re;Zn3Qbwj@N84?ieM2=t|ZhXlWVQ!s8hwey73`xgGb z99TL-Uf&_dZ~;w>(u0AJx{yh354XNVvz-QXe)jv)vl1i2nYpNjgw{{oXa3Bjuidh& zs?s+iL~+cSam!3pKe_75E`r#MgXJ}3nt`bT>~$5%Pslx?kn(g7mt-Y?8wS+GLJ*K! z#V#TPGsU^`$qFXO`gl z0!XE2ANS6okrB_H?|#^W*qtSeVPly9aADV_ZB0kfh~pSeMkbpNu9pu@G>)B}ohH-Q zZvX2-PTEwGo&wUEydWMQ;ZN5;&3r()u+v#V^}8d*r%p2L4O2}a)&5L7Wwki&@T-(} zc|+S9D1Qwz+)WSYW-o0!{kZn-B33j;`7nKg+_VOG`4|W1`XmSqkX%4`WAkna9nX(p z`3k@8a6t7RWaWzQLB0#YXXD7TYuCv!4c`{zH^kl8T<`D;Gt8VGfIIvPXcS#PSU@BQ z&!ZO@C{<4-yoXm(l2zC+Pt?TTNf5o=MgG%HursdRJ+50Jjt6*)=JNE%GcANe88ymF zPDzQx44{ory+4PKXs(xx>MuCZ5vY#P3^<5O85^8H|JS(%FPM-vKlH$L%H8DoQ@A|8 zmoN_vN=srdE^!r--^3JOl9K8wOeY>|fzsvz>4m3ie=Ow863%kVF|o5jacXa1`JRTWgga|Le>kLiBhF?_ z^gKa3vuu;Y_D6^wZuQ-ytlKTj7b2zKT!=aJ%m(s!I6yiXlB8*rL5M+pR~q-+ z36d8|2$Z3ZOx*U!$gtsmi4Ppoz7o6|oU@ce8K*w}@KLmWMvoU_iGJ|YTjVWI_8hqI z*dpMEl%3%rKfgbht%v;HL7VGQ(f@>*8a2l0Ek3$`KB94q$_DeXJPoyMcUI|mqMy;3 zbxnMLww9KtGn3s5FPw#7kds;mQD@*)HE*C%8$4Ilza`(eqGwIes!su;{ITaKf9YyC zPtvK`p1MSHHQz~TZ`S_X2BHO)crbwp>H69v;z3%9mx8W%Rn%?Rb403-ins3b1C$r; zon}7h-Z%d=@6CP<4Ak>X2ZVUIAYOX$LZhUttPU1sxBwIfG<|s%2n)np#!H=M#17K& z&8rjkNlFs7ia1JvH-t4W3ycIIYu+IsFk|xc3<@F{kI&)7F6@rqvHZrbuqNq~G7uFF z(Nw~#i5XijDvBQ9a6!L#GgP8Jy@#e94+|EZy~Jb4X| z{XwAxi@DUs!}L5Gtjxt9vEAL!X6_7+3HyD{u^N1&Ed{6UI#7^{Kledhh`jFo=hwa{ z9D#{jFE1@JMqisxxq3AU%CoH9SGl(k;fGwkFr5c~vd{0)bUjekbGjb7VonxuV@IS2_Q9kNnjF+9 zp|(N$fQx}l5boX2ti>_fb33?!dIX>^m#;cn0$`G^xQkwMv;`@liK}P)wiXX9icJqp z(lO2xymI||3?lIW9NZZ%^xP0tRaVg{VIlVbgwS&=rF`aaA0GJ z55R=zAIF0H?;lL;`|6Eo7{R%PrCUH)_+?%oUgU}EvA-=S*ZoVQ_t&1J4CKt%=xZ15 zNxl8lnAmhADkev&hLqn%uzV%%jR(qR)dVFN04na2z4vKCynSz!% z2Vgr^IJK|{eOrcZ5>4A1B)Ey=tMs)=MeO^dw3F^o4E0^(dbi3+Itc4ePfjABA&YJM zIhip1KKKfDRJ&Sj6RIY>xKKR|9kR)^wF+bxB2QcC+zRCOrs)h&kpq?9X{*L=qg)+ zF!s>9l-zuLhr#9(qmxerY%(c ze%JOBXF$aek2Td@@A?t*ASXY0PDD~T)4!K zjhwBh_6BWrQACD~a>a1`7)}Heu z^4{mPjC110WM*FK8jIs*29%&2lsdzZjH<%P|MILbS^=O@5K&CNd2|1(`;CSeM_LDk zc|@fJt{=Ie!=#wGZs!@~!5lK8Q~U|2%8HQRUAQzUR}lek>H&0+tM-jUQnI)wsV$&a z-*dYVKj}ZZK(m4F47!3ZI4{r7%}reYu!1hMzW;g_mH?*K>v!_HUA}cI4rkDfY1a=W zO?NXH!X?FddVTHn86!H{-L#*o4b0yC z!|da{iK$g|ktM`G=M_k+JN+IrM}a>P0nzIPF1fRf*1?cCyl&XhgQsoT2S$d+~dM-gi9aYo`6Jh9Kk@a2NAhO4VR)?`itOcc@YIh4bz{4@Z%e444`1Z&^1|7Sk#lL@L?!Wm*W<-wW z+z+ShhY#P~74LF_-STGPvyNI_7ft^YE4@uyv?$Cno0D8fJ%@XJcDs2)=-Mtk8XjH z))$mUTRVpA0x(PBT-xB#V9a=4mC-u%DQb-9v!G>o=+uJ>^rk{UM=gsZncW^}Z#aYA z842m6jP_>OmA(EjqO!VUq)K<(rhEfZC9oVOrQ{66QT^ppRHGp;E59-vLhb z{>Og~S!JbLNg7rXp{yd2BqJ(K$|!XZ*(mI9q>TOez{!i!YPYyrD^ya1sj$)W%i!1$Ci1&>33qrSPc3=sw!33!O1QXRW^^yk zciSN@T&(pO^M07$GPd5n;@n3cG`c6%9z$|EPUw%)C+@gnTzziBYiN6M=QT{V4PWviiBEZrk<%4_2yIYgq(o4|mU%(PUwPhrH)m z{lrh0Fh~_oj_!(m`lHa@SMGISU9;tKzX%)-+<#k2Ug}aK#1H#@L3%vr=1(Gj_)gMYqxAnc!ldY zpvY{W`-i0NpE<85v}`#4ZatsIY~IwaFaP5LkkKGCuD{6UcQ8#QRO_jT4PQjj@u2+F zYSHZNtEJz%O_wFii)md^HMyQ*R@`#3M~Go#ZJl55C{-BZ+wQ$aji#-inunwE zPB4~Wodj6fU^`gue>n8pLd;UI;JQ6K;H17jmnn+%a&JeG-xR_%-7GMGml&|zxlI5n zg>G;LH90SmTm|C#ucrMxFP35=RqVNG6p7%$Nr+;J$mMh&F2NoIpF!bbGY!7(WZmw2Kt=a z_Y><*jDvby2>J5&y9a4?XG}^QUgTcvkJkqvEL3Yp>Mm`Wau%xfl<2>>y-#>Z|392g zgS64e-h_R}%5zj2L$glo1tR)bpg>_pt z{9Jb#D`3ljjjRBM9!&yzI1e9~v%Z0E-@^~Ep&cFD$+7hyY~D|`Mz^wm|Mjl(BEt7D zgh9VnXPe%FpxC7>k@719X) ztP$)@GI;syN1ndU5`u02hDakfkVY_WkR;MbfeHM)2-jtxsA+lFIfj+10&s;@2n~HJ zw|aHVDY77>be|b07^@odcX>v=tpdD2go#3hQ5mzUP?XPw-BazIA(1=RQsXjn%Wv=& zUjk;w@^3RHzSN9Oiv~oa4`xwk@pC0Pv9{eHKy%g?#Fq(MB77h{@`q`0r3g74MxRF< zDmc#C0xV>w6wmLA~;(p_DKPxLU_JT7Z0EUNTB_Ne#LrbHn_qFC@taG3axos z9@;CS%*D7|K9ojJU`p~yS-i!2t?;w9vqrEcsrrQL>Y9qw+>VtR`~kdbt2G4K?yTrJ zN_sSJ`~HIgfuHWLRlsE42F3$hhfO}Wwh|m5RF5sdvpe88C%k=oLv|j>egM6=cblOR zBR(2!a#|j8A8`!{lOQJp`zY+Vy+3;imX}LVdhmz@tYA~L!VKGCvVbbjs=5P9SiWJW z+)~L{3>gMtF2$T6E-9JSNTb6gf=9%uKvY5D^T^CqkcqJ9!=NVk?HZV@M-x+sZURX} zp)$4?V{O6(8_7Dd>i2Ia!s8X6!F}t*3d6c>LbYr24sRAT-(s-d$>i}u)%TY(fx0P3f34p@p!i5Wj!;6kU|BoNgl-g~F z-vinNxnWeFZrbPNp_zdFuLkUBnp;6@BYGE9m2PT@#c?1h66Utg>g(#F`KLCc$$N## zQzRlv1Jp$%g5rso+B0BTb{IoMLgzt9=+_hb zVbTwZDk0Y=*aA4U^0#m9`G7C&h#jy-SEaDmK06-rH6mSgPQ%DjQ}31yr-#`ytD}iu zU<>;6!n+8eO~aTh)(tmx5h7{;3*LWk@Ou9x62dK;-PlOdGv>QkzW>|$+gRAJSyuMx zVPA-kja1-rPEcsKZzP^QFetf08rKns8TQ@Y3ZJTa4O;KBXxUPy{^eM!Z9DUYn8AV$ zTNp3|FC<q%tf8S$KQP1zbNEloA`P>pcHRBnDeHs{shbegLTtKyF()j&anSl=BJ85KNcP?b4X10 zzk7;LLzCoT`uPOQM=8n!@c^*x#19qjAE=r16v%WUbu;tIe+eW`<%Qe0JHNM~n9xYiwj~tYBu=dL{0p_-Rjm&cMA&X*s>y-kF}kKt@{aGvJYhEZ-BGz&?KpL`x_#4c8XNPv2i(EjsjP9zL}i_2Rt{)1|BJoEN=q4Rp93~4 zdq&BnE>Z$JxRzrm1@x>-{3ly<#B(^E-N)Eh6+)W5A(DES|1c`)NTSo+HcigcYXk(^ z$BOWQg_ftKC3fy?9_l`E^=ifSl+yRjjAR9yMPnyuM|%VNV*jyDVvecV0vyP0yEirABH^B zz--53ARk)yke3Mwjo4I(&_d*JgjbloCu6jV?h5woEy{-;;DGyM?sQT8JbrlnN%4Zo zxvcDLO$&>Zz@w!>ptpgzi3N@%SuRq}lP3;!rPwSa3pX|t4&Wsq+Y;g+&~RKbsyEQz z!jcfMQEzW+RtJ_T5@oZ*z|7Rt0YrtinO{K9zG17a!R~7D=ASO$r6^|I0l50DX=oR+ zGPYq6`;su3;{aI#D(ZgkLRhTZ`C6Jxycb+~_c|a_NwxJ$Nz?+@OF&EWg31(|0X5PA zo;$5u1qvR2Z7oU-II&#yokQ*zSfZhr-E}(EZ?9`uMx9K9G2v7jyxS*cF$QmHZ@=V4 zmET-ts=9w{_%xJu>m}yBmQ$TbswpcLw*_e5GjzMezv{|Lq1v31gokW?4Tg0y&u&_7 z)(Bonq6cMgy55iHX4pvdORH?Czf3S&(Lw4a?~sT|R!jM{WcKiC|ofyF}1A2$sW;0{FnS)1$dN=vx3{q6<2C{`urw z2YmS-Uo)uW!KLd&qaDH#2q1$+$Hmk(9*YoT328<$V48SCy_ik7-(&k91l zM8p?Tx>MPq(1=RBaofe|H|93v>4hWJ;4%bt)#l{p7IlQKao@Q5a`@eB0QJ}HQWCFNKHkE5ow=y>v5WxIArtUn02N#)oZa7!y#!F+VHZUS8lA+LlKMjD+De zMskc=skB;xItCIB7%#WP;wxX^KLb^-yFVTNIWQ1(G$mJtgRox)x0KVf6LkIZIsK`? zyQAP@8N?iIW2m|k7p=;TK*ovs)LG>cr65IHA}fHmvBz`W#}L^Z$5}7581_Q{KO4cI zI)Jy^-`Z_Z^{IVn$7Pa_#hbp;FnqMJ$v$-(#ORTGbNQO={up!u*Iy0K0xBjZ@x1Xi za24bxc%iQRC(mH0yaZ$L+lj-WC%xZ&1UtBy!d0hFCk|;t4pdjLLxY`ooN;hopRup( zf8L!K_zk&?z7Ms$jGWY|ZdpK8-eFj0$YmisHl9fOB(ly&I?W{{w^UO(UlT z@WL6e1T)oNFIUKTT$VT~AqLl0UI78+9$TSPz1)pzr%s$Y#TIX%)MIlfIB`*~DT zMGs)AHvVTIk+_7!PsK?ST|P`2;H#uAcM@BX?d5BPSn#vgCq zMAT=)M08ZrgR2t8R{7e&Zl{k=RL( zNDFJJy86r_;adWt$vp=%b1O-vpSB8;{CHokrSe5bJnClYc~btOi$s55=sCLHhZsb{ zY!{lb$ouz`D=Gw0(#<~b{j;{vb)(6?g9q85#v*o*=4;wv-a**N!4G8*LN%`jv4jcY zUdKAB^rO_wtZR$%^gY#L7DyaBLwc zvN`KuJr*fj8V8v_Cp;Wap14DNS87|DQDLWJ7^cJ8-ta$d$%XZ?@@LW~+F=*^nORzWN@TI@nE~d$8*Lez)`bhR@z0=S3y%*U)%q zXd3x;edtEj_K_(UAWEI*cEW$9}z#XNrJq@2aOUm!2g+UZZLw%k=AcJuyr z##u!eV(VN$QjJ!!-$(-AKtx$NwmyotbhGQ{?Ldw(M2p*Ui!gXFl^_7HHY<5B*m-~( zev%bVe$;!&vhfp^ZorjFb6EE6KG@2RWAJ!s18bWO-rX#3?8l|H<6AH)(?8qW9<+`pT@7b32%ttrj@<7?^Bus>V z>!ReMxW0|Ku*6KyLH@Vi@bZq1L^*j6ImuG%4F4{R$dLg@QsIfwfz(JgK}TVsfN3_9a6D3m#HVO@3^o(~_s^Jg%7lhY;Vz;l49KytCU6$MbWs zv-6wl2|E>G_SEV4W`nL5fZ?r@h2H(#J~~3ec?xh9CHT)Nzo48UT%f~JmTsB-8W=zW zSnPq>DitM$1Hur&%ta_5_V3swmkUT-Oym8wj?`#29Lv;m5NM*w@$b3+>;3oZmNpo? zsbZ#9Gr#p4*5@C*W^M98z)Nrh@Ht8llf(t!5MF{C;a*b%m-)Yw?rzF19H+w_-fVE+ znzk40#!H`-CkeD8&(hhs(BwQOcQuF;j7b<@zmk39z~nmZa0kMFJ1b(5b`T^ zN*}>mH^Tu@efPH7l z2dQ^FR7t&D2DV$n^Q~^U0Lm zBg`&$x**zhW|9?@8~`i`vFyL(xD_H=p-sDVZ?!O;X5Kt+%s8bH?4BCgFYsE^PK$k| z|1gIe=?T;LF|Q3~x_>zQ4hQfqkRr&bnG0c+(=sf6Yd+pcxNk^*-ueP}l2GbQ75tC`k`8g)!uhYwyxa<*Lf3fw@f->sw6bjG0*5961Mqn9 zt|5rdp9vLP?H~qg*k<~032vaoMlL7Zr zBfB($#YrRN&7=VGtg0WI0#|5f!zQw3R=Zk+VY})Xk+h2CJ(JIUDFM8DNqml~M`PQE z2Y9{SFq=#IEjm&iO>{w!!MeG>-e+|~kh*s5NcIP^1)H9{?l&0w5L+&?!iym|r@?8# z+Wu=rTaMnK0UT#pub-n{#!VYl>~Jh$^;#fPA=e&FwdyoFQ@c@ zKBC_Pdd0)|LKOR_;=pV9UHHKYd#m=^RZgAc0!{P%UDh>pYzhma!4W7fEJCV*E)PvXks7*?@>lGW6i6DEl|65Y;jf`+;x zetNA7ql5D$yuxc*@1@F-J9*5%%NiIl^_;UmeaZzhW;m$KPPGhAiWzL z;$Ru`Kqr(by_V8w(|W)5N!A|A4VMuKFy|kd`Gv^3MXQU3ff(!6_r&Sk&Xe z=Wj+(B;;UC=btM{FSsrV3ANrLml#Goc-sN)4?MPoRlA-k z2Ys-rh4F%w;|AL^zix4?yi$q5Il*)%-GPbMfp>&v_;_M7k+m&~xwi=9a_x3Pa99n<4$O|n4zb+8|qGZ{56Rc|xf!)@n)`_JW zL0DRd4FSgy0X-iOQI;K*SshcY>nR0wD@Z4qwb4U9=ly0P zaq&jrj=Q(`G-#x8krS<^B;Su)ACftQBFGgyNi#0=R&&qyJg?S7^JSY_Jl(f3HyxH_ zry1QIePO2yE`&6HEq9lxn)_Yf8`!@y_iX7k$y1${1%>6Ri)Rnu!?LaxJvD|G5%MpI zv}(&Czwq!zKb>n0+om3(W-IzU?)Eg(`97v0Oq0aZbR%*)EBDVNn(*bd{dEmcB5Z4=P!o`y<$kyS$L$)VMwg2g4_X%`5S>4`182F zYk&l$@ZvKmg5~(z`O1~j4zX+CC`E|rIlvE+NmlHD+Wh1(%yf5sKf5$Z0QKx3l2G%H zlHk|(Jzd2^9FAtyU_X3RYr@ckqnaU5m!~wfReTk17gJ!c_h0d z&l95z*I2I(71Llh6RI5}UuBw@(hMg@OQ&63Pd#Fq6fc`2X>9XG);buqF)_>R?^aJ^ z3%Z1X1{R;J3*aUBVW?w{_RdXZ?^J(ZpM{$$+cq9ux_(}(WUG91{noIPCd zDgp#?xUwFwUJDAP%;^G%R1@25zPt&_kaQmy8?$%Q_xieOJ6x4^5X`x0(9ei%aY3(M z!&OUDHtJ&+axbX|4o!$J&AXOjsIW5{)O}$0g0>&z9IZ)OTuYVH2-YXH=t{VEh^f~n zFgdXKt!!=gU9EAbTrnlG0vNTh-{TV|HyrX~UJ-cI82Rnbsit94!X3jR6Pxf2FV8`f zc_BkMEKERQIhG+FZI`JSXF{0~ypxzX z*7Sv-ficmvQZa5WHWs-~q~wbIfX9gAi#o7lW6%V%!zMpQ0PhA9QdU;gplSn=Q zFdifMZ?fBcF_gc}*?1A?$Tkj11(53I9zyp67$HXWD+YxCHR^kRO@VR}q(U!AIb8ks zj}o#J?cwf^BfpS#2tG7-cw?06-@%meDTTxPLItmQfAfZcM zM4e3xA|&pWqar|4+y^cSnD>O;O1eS(O@f)vfIlh=_5*Hcxl*|g7Q6)pl2`u61+Xh0 zE!sOjHG&lu{jkUGkKDBUQ!$k4=f+;py zz{JO{<&>FO_tZB zHc|Kn0D+m_*MJ2!Z1eG2n4kXyUNYkDHKl-I0E#v5qM!3KAh+9VkHr!67JHjDar$0} zs+*^>k7Bq(9_XH8Y&}AM3lv@)TkwY;qK`+Px!}sJvG!PBAMDFr{&eMI%mC4?^tT4jSx^2p1X!v1V zT!($Zu?Fx;!9VC=?s(6= zK{)`!o3^QF)z)Vi00ZTDRuXp7*GyGtM?0AWNPN`&W~C%3Vf#VEfr`aw{;E5%i3dTH z;AyNdDZh?cCRoM9H1yZ6>)vLL+u>6Q(?LyaX?yjXFLwk{7<<@cvs%Y8QzMDS@6(Ae zI4m@@ggUT6p674ySdQ^@kbB#Y;H`L9Q9MT{}aS;)uX!;opwrtk(a-C^Zy#tQK zKFgI6jG@x^U@G9kj@_9arPF`Ri>~d*>b=Ors*c~5A?qpJ4i2;d46VDnAJ_3w?)&G< zDIOZ! zLq-7aXa;+U4Rp`AEwu^u3#2@K531+HP=2N3l@XZTp=AX7#9;VH_HQV({vj5mv>)E{ zYuUfulRz0U5JekJ1xM`}_eE`JN^fCgyb3k!rj0(cy^xPU*ide>WaP?@9k#?x0r1ct z`tc{J({Z%hNT~J}$#j#h(GiJ@DZDV>yXu)!j}=#>jnCYlevb{{T}etf<$8iVo1xW9 zT1>2DaEE7=P48VW8FCtXZK5b$a!zFJ9g8?~rhxP80k=6+{U_D6OE}0cxk}&Z3q4rI z#9=<9x5IqZ=10+&9Eu%ZRg&&I)^y!Jn>w|yBc+$7T_E2as>N5`I6>>%%|Jpg(2|RI zuZ(q+w07phO!>YS_OPApqkqomcTb%<(8_%3vy`&VeYl_Dm zCS!}^nxdOa-fvAZDL@yo4emfEZ=;d$rC*|o>zB$h{sYdz1kQvIB7aS*Es-oZx@9LD{b zHFu4NI!onn>@FbWNEsQn?W8t0VVTZtq*08j`4lqt2~-s{e#Zipr&ttrJV=BCnnE_> zJy0$kk!ihknNv>dfF>X1)03lfSUz~uHmi2Yz~GZ5JdYlt2HW%J`#p)>s*hqEPQ|nd zYFu>G^@#%SrVpG?QsLXL41vwR#65*!Fh;p@i$)`h)SPzu5Hv~!- zZY*i)8mQg<{X^8VMOv5Tn@x{IJCNI>74-C~6xX1Ww*;RugL{93Ez$E)iu4afyIu?3(&p~aXe^fp~3LVsmi~?5a=}Kd`aLim1k;mx1q}7&>tVLSouNKp$ z*)v8r?KKIcSAC}Wa7O0LH*w8w7_U?gIX?6-MuEJMU4E3cDlYkSJ1LxO`FiB^P-N2$1_RG$@N6@d6rI+nl;`#|S-+_= zJ?x%o>ua67tWO&2d$#mw$$5n}Nj0D9R2_P-%iZ@SO`5rCqg~kxT7sLq{#vVtKFpJx zw%y<8uBO$WXa=MNav57J5A$L_{dr8_KPnb38;nm8))=X#%>tMs?$8PoSbe1m%pPp1 zi+X8AJb{`5q9T!#b8DZr(Cl^;PVexpVjkg|TznkU|LI()AsfwBbUa10#?k3YgC^PhuD z=A_M=ZCUoR>?QBzUOY1$9D8$wo*3QcOZMebnqszN_Bm?#LD%rcy+EGdufqPY`Po!* zKTeA?lI%Ix(;01&$Mm3_QDmHu%=Te8^6S~_3c7?pX6o&&OCKmHc?&iYPcNSt9P2}W z=Kuvqy5iOl$UCK5Tgu(-+l#~F{WfzEhXWPiOe4u$g2 z;Ux#2sY?>mmF>@MPC?{xKiNujC6G*Q&#lSA<0|Mik}nag#n*rD@Lpp3b3uGm)Thrd~cWc*j=8G z#PSERZ3`y-!_xL#!9MyX+WFaw?O4tb9m&OSU-i8Gj$mf9p*jJG-q9> zXrogaA@rTYerBIvT*+ghFnKdKobk^qXN=NKV^fbcy3H`|$rmkMq-f&CekKY`;(QG) zxeIAVeBFD>=l%CoM$bRbT)@~`SS-A847xBQ0`bXk6?7r6X_t3V-OI~4SOkG`-U%K*^ z`H+^i2JBfIeUUOB;jv&wwqfe1=4n)qWTn!incgp#SN%pmcF&`VOttO#tzNh)HedOD zm(rHu&b#+YHyxVZOywR`u_9t{%sUD zw`+YOSKkZwboi&Q37~A&RkfsC_VZ%WkMoa<@TjWi5IexOEVh`ruWNn{9=2@fTev>j zHEFd^g5RzLT|oTzRVWovzlq=YKwP=tPhZ^q4`+RlSwDEBsFyy*T*IEzbvm6z7B?k6 zR6)IKetXXg^^ZmrH=X205sn#4rfwA~PnWk>^5OH8-IVFWJv)-D&07!kAV!LP7$Cfj z?!Mkn+-#9SAP3*CU{fI=LxXejOVbO5q7~7k$df7d#XVXjfLHiJPQ3RH?$=P@)oH7d7fI|5Dv~lX-efyxH(za-#x^hjf!m zOicV;e2m7N(w((m7D~(4o@`dKqujqtnPEE2+`wG^gZziSclXhOCF8W$G9sVJxGU~} zlZl;ie)w(qPW^RH_{x_qAlHrZO^Su}emo%tJ6WRQb_mG5mXce~dWh+DKwKR89&KcX zD$`l1EasKf$DqDbAO63^fYsFu7P<8tb6cC_xjZ)e_sxh-dMip%TD_@Zbf3*f2QDR* z)hdEJ7W3|2l%(Autf+Zq;@*X$B>DpWtBd1c9f*HEr_BU)o%+~ktwE?Jf8ehH>H>2j z`54|fR}%;)lhth}cbgEG%=&GoH`n-e5trTP&&%(5O)(c7Z;dulV>4AKR8$Cm+Ihu} zQ{EL;>B0GFZZxS?9(QDNw{IZjI=dfkn(Ze2SQYdiOEIf7o-TmX4g`5h6Y< zZ)SI<9NpVf%R#drC2r zdr;h8axu9Y6@j4~g+f*HFQ|3laM0h=EfW>$#X7!=SE{CBQ_0t^O?eGp!oJYI1X|qQ z9Y`z$6JDcp2P84)9_retWGv-ax7+E$a*>F3bZ>-*@X^b}uScOKaZ{V`+}DaLz=6~X z;<1%NAzwov9aHiHmk0X$KjfTweltT`bqe5nfzSNkCyGQI%Y1~zE-pWtZ-8R6`MAL; z1P1)E9_*a=mSb!m&r)|5Xj*-G?ZD{{+K9Y{jo*U&)8RMNBXZ>^xm$!gz5H(Z_tkW$ z$rb9*tCH4O=+4=ZuBC-8Hg*l1Y$@GFxz9Zpc*Oc^Pi)L4^4byxoMae!NoUVLLn7zo zm)*QNU;CQWnIfreJFu6X&>tP+zxxTTQ+b`37Gv_~s^_-%YWjlNA z7A??kGXmV1mAwB>I)xmKYDV%+@8Q{(Bew)~hP{nfACW0hC{y^_rPn!6(cqwY` zq6=pV|4lIY4l}OQ87BSbrib2jtz{PRTU-`f=pWQDvRAG?ySHhPS&GYcv7Pq!lY>;o z7P)fvU6M_c!R3c@UhJ}_OxyIF*j&Q@V_VNMci*ROcb7irxWQ7AuY30{#CUPvf4BNj z=R8MG#yBNsRZ8y;cV6A}E*1~-RxYXvr6q&aVx#DB!(#c)NaneZwCvw0sfx60u15-{ z^|tA(a;^>8BIC*q>p!%nCa?sSGG4aVf~E);;MK&F^^I5RakE;EMi)vI^$d|CBH;bv1=O3EeKA5zJyT*aBXb5A5WiMlgyVCqnFnHl}XX-*Mm z+QcM|+MTJ}edboD_u>C8n&@rfqB*i}(b9w2o}8t@|89+xdpFA=lCt=@5ecfc`GKU; zRpUi5CT7=#>{(h^iWXaGWuJsKGmyNNU&RHJarafc-Pb_#Ay?=OPDvMX^Y_zdwrnvZ zj=|l`rM@HxJh_i)^=n&=aX^TqBCy`wcaz5+9Sa%pNI~x%O%GY-x@a4B7LM$C-OhGZ zyy+9utd|DUY7#A5Vq87RT4}s%*KK>Yxws<|{gc#O3H7S-Mm^1?1S$ME>h2H;?-&b~ zDoDG#)k8k~9f9XW3X~81?Mk*^sHnJ)@!l2HLrwe>V#U&Fbg7iag!pU0sa3?rESRfF zwJu=o-7i?*rf(L`xQ#Bm42?{#HySxw+~eT^E`0+7gBxS}{lG@EF}n75yLI7gr+0Bo zyq?wTfelw3KTdz9n#-v)b}1cq&Q_w0tn8_C_~;>5{-rC?!1j}w@gmoEmLgv|{l@3r zvS)?=tV^!nxoLU0qx(zYC9A}c>q~cH`4+8WyRJI0x_@?+yWdQSIE@tPLO)x@)X5mD z&a1T&`B-Rq*g$palhY`g@8jnu_2_VZ{|+cus&y|$>0(;L`6=OhWA7O#XPjjKB8cR_ z>=!F)ps+W-0s`Knser;W3EFR#trZ)<0Sz#K$&2EoEHl zS!QmSw3~VMR*b40rSvm@-)?iKB-VyBqK9TXJ0uc|cqmg{G8)Jj$4a{jVmuTk9~BL3QYK1rqjlrZmV=qeVK{I?Q} zU8)QMuN7(mwz~UrDOqa@U=_mQt@~y)lXh>It&CB%q3DM@%oh94_YSb`v7)pc9F*~k zaTW6n95wDK(*5hRKAJqqEpN|i;5uVg?q%J~wDherScu4WX=^k;#?q2N;&lEio5OCE zuPtTtQ^WnuC0bYb#ZX$xBl=o+Yo|W_Bk7k$Wn2h1(be&oJWU@3e5q|yvp^-0X zI~59V9b@B~cN5@2Gs!ytIAm9zb8fq9f$Q)|61|FH=j0^tzM%;HHxuE^$VInVfG-d; z!F&NxBjTIYw_;SjtTPIWprMnYlH>`Kqs@pFU|l(Ng<5$nY=Z2qppPY~#A zy^8lCRRG(W}3@a?5tms(R`5%t3R~6?xgA z^e~Fzt1h)Cg-OFZ&&aACvw~QJemKOsK%@G{Cr6bObmC@sWL|Okkr3tYMBjZ$cJ$MlLTC}ZXMS^wH!8^ zLRo$Y{_U0z9knuRLh3gyjI)8h(x9)@r3v|;;Rb`}tJkb?!dmE$)xN&cm6OfKgH}DL zo*%Wh{aO(N27GLSs#m)5!;((7j>|*|ItC0ngIi1*OfgYRI0rzvzcAkOWqoQ2UaLn- z*kC;L1c9#e>O_O<%JXT!K^2i5UV<+j(Y)*1)bDy3Ihz(KB$(rHXFFzHjYJ86I#)UL z&{8KT;+}Yp@`vh7J@vAo!GA4nq?me{ZaPG-r;VKK3Gdxo>EF$)_GBVy_(3=6ivMUL z871!+b!vzA00{}^ZyAR^@iwBn1q`<2JE@Qjuw@m*hRmTe_R;I01x<(a<)KrZLwyg4lWw`fcl3pm@oXkM(QVp2 zLH_A8eoFr9sE#|j7MIU`>f&iR>ai3&bUr$)>HlYC#$&)5S`-T9f)_5WMCj6d=zIOE zE}l}xj9-@jH)`%j|J@YDFI{^6lKut1OIi2WQW}Qkzj#tD+H$+EOA@y{2{mtOZSop?JYxPfo`eHF4WG(wB)l}mGg zs)w}fsF?Uml;W5+`-W_5;WzFxrBvCTcy;GvJ=SszW(PH1sYI_FB;U9ELvnH|tR)If z&o*rh{yEK)wE3YnF@9TVeVjMgM%9+G ziQM7e>UWg7Si-2%Ol<8cW_rwPd`f=sF*S>-Pfbu~T&J`se{lSyM4<%e4pP`+fhhxOY}!Lp|zFEp4JuUj{$^6!dlfcWffFUT*jj<>I@L%m3p7bjuemDipeN}OxE9lpu*kn<3EfzN9A(34183wP%6DBbDp zEP>^Wd#?Q9#Bb1!CqlXCJ|byc#mhSmAEJlEA0FHVJ|2j0E#9I0+}@WT_DLD{BQ8iw@FTA`L4a={ABsOS9i+&?aLUSmIa&=p;vX$ z4A|&Qb{r$ibBo)^vnmezOkUqVgogHz@T4+p4oTW!=9TNFDA6;p?kw(f(kq>YO<^>Y zhI?36>Rg_O`(yHziNWw*U}C>os}~dwtkl^F16+Sh5S>P=VIRKhYKg(}?b>|u*3AKM zz{o$#fNG1t#0`1xej;ppN}!IYe=c*j zO>c~u$m#8qkI?>m$nGpH`(>-VoSYoX2W@>~_!glK68=q5EwB#W!eZaLIW;*giU^sS zL-%jwW>1TFDh}q0j&Vy#NXThHut|TK3)nJkQ_RGI(qOx z(Nej%g#3K3hu$gxBN3FnHQ!#XmR|oyA?d`18xva}#Uz&x4_;OHMlbg(^fzPPSjga% zW9W1pJmE}f**MGNAl{!hGs61p{gNyB)t?!Wxxw1kz}vdH*3^Sc*qx>CTAEW?hk|~! z@7y^d_)VogeR>D3X3)Pz3_T^$U1mCtZP0WrEoXL*Zrjttk#xX(CXqH`;qEJ>@Zm&a zOc-kdYuWMUeoMOP=^!BmeoD*ps`s`_07322A$|dUsBp*!xH;uxH@D~1P}H|4qAO`o zt9Z(KjGMO?+aJEQW;@9779cPH?u!@GyH8j%LhE>J!=>j6cp@<%`jBg)Vq9#e53^D0 zuNAw&+`IrnK9ReTpaYPqK!tm8Jm}10I0wGEBeWmVLpJ;hambXgz#U3ZJ5(dD;7Te1 zn{n4@g_h(4D~MYEIrnc^nHoV8zdYp<|KI7+dU)x;U1S;DX&)iK!_OrIAZ6q!(<^Y{ z^YHH~Kc=K}2~g`+Zog*Ct4R%vMiYhsBoF)@RmgJ%29n>WE5G+LgLnTUMOFKbT1+VqqY zStsRfS_pX#@nS{0&bJ_pfKR3u|K@YXF>zef)qi5z%Uo^n8X#u`6$H+f{(zBxqxyWK zU1=V#F23lo-Zy{-X0TmqujAH@N%m`t1KHpuGA5MT9*nX>^U9V$W_lhJSf? zT-o5ZwWdnblpg7A)vqTuj)yC+$n5=TN0A{lk{1u_5QB-kul1Mm!+NA3PzmnddM`(z z9XbDO<=~fmk+o+X_8rgoz7sgDkc>?D+}u?HxP~uQBXB!I-iuT6_Fo^8nOS8WdelMh z)7HzXDDZ*JIuW|Cq|F=yL?~0Ae-PI$EGXDDoL#sJPGsyRHgg&%H3pm0R?IVI28g~L z7S-Qi(BNx#AT+pjQzAc9qu=LwaNe}4BhUKe{ zL#5gadcuz{7UA2A^G;+PIq?C%#i7N>l5jed17xXu1r)Z=+lIW?d8KH?;DMCfAz%UE z|DogSb$|gMbhLsG0MFl=5b=b!H&;t~!0Qoy!Dh|pcgW!iz4jwB6VCuHU&d22;wOK~ zScM0o59CP-jsmVt6tIkwUwrWrVJz;|pbx_qX2frq1jt%TZTrsul(c`seE!It!N z+2BgtTYHM4V9ATFV_s|r{9>L99WR>AjyCb~`_Vh_it1|G?Q5hX!+

^*V}rn*2v!Tx@my!`bAQPpj%%CWswZa3%*ttwT9&A1>#Bf2_JZtn5pG&% zJ%6UT?z}YzAJ_hO;)$Y4O2u_mILf_P1J?sJ`EK9YnoSWK&un{sx#K?Z?aq;f{)+zt9I2rMIVccl!v|xe>m6eOf{ZoObx%`@fl}^;`}Z6 zxA*uyVopqa*Kd1s5od^?aCNpfh)~sc&YVG(hi=;fhJRO~TMAjOWTePsS;n|_oGpT# zUe!tqByD1T!4od&|AOL{Q0^NM(ZdAPS0ki??*F5P8b`JEFH-69zG(8gg}0P3L76_* z(@53nedA4;=6l3fzvwt4V^+%Y|4KAbm>vc%r95qTEfNGE?!d3^<0Q}7KNTN*t8d6=w}y;DZKQNFdJSM}${aZbAMi!QrlQB`6Z4 z;gy^@d?!mxRaNz~ki5qRWtX0)Q>G!FT|lX?zy$IN`jIvmu3%a>0H^04(H6HuCQApC zZ_VO_5v-|*PqVOKFp`!i!`gs^tG{)C_`k&y_p_r|ru%P8@nF*l_jBP#5 zT4>gf<4;OU{6%Ca#L$??jc|6xH?ySrk?&q&N1fP*25$g*A4_=ibA)FUtPdluBC)S9 zCZ`>_3Te&E?xcf}>owxXXI3JDBjd%w1OA}yAaX_|E|U1%;t{>H0Lt;b6pD&pkA)@8 z?YNhB?3H!(UG6b$EY#s0<$+}92DBW$DlCu4<`gxi1=0o9*cJYX3Utof z$qkd|wqhuLmev;bTiVUfRCutVB>3xd8h~I`%bv- zxG=;r_tA-?#35QBq|D!VC>KI!*mima13(~ zV+OptFH~;u>-?>E>k94z9B}lHS3_D)i0+*b z9uG)Y@T}VzpkUJ?3mZb^u+lA^@i5JP2)oPz$imUq-5a_yROt&W@q2&&fg&aQuQc%5 zMU<$KrJzpyc_riX!ro^hPP-%Acg_Ms3%H9`L_~f8FCM}G!{df7@Y8tc+G2DSg5jgy z_Gr#GdQTpeF6m*~Jh^)cE@3;+)+*XsU9Hau+oYC&dv~CyKH^orjY<{X|7yRaS?{xt z2Dd~@Vczlr(_UyQbmD7a#$N~M1+F6B(GClON$u+NH82&fG`P3QnWOLmzlex*G%XxX zHSdoe-0-TnY6^+piX0FT3bD*a!Zg9qqO;)Q3P}7dA#Xs)O6gp{3eMYV3m)+MUOSb5 zld%<W%!!sZ2LiaS!I`NZNY} z;AUw+gh5o~byKQXVh?lce?WP>EE*CG7R;&Yzb8z6{`4!~Dpdw<_y&Gh*r0jx!uHNO zB2oFy^=%@8H37Uef6X&fD|7j&0b8Denw(W2!hxHlmYI{BY83;l@gCj|UCWd<+(!CN zqg3-QJ+gsVJAkdqgh{%Dl+*=SE8ZRJMU2|I!}tc^i}!mOBX6fs+U=g7{P+j6w)!bo zcS0dR)Q5+`y3}R>uzpnyqIGKanJd`9rP)<-1O`sX8fSY$>0rxBSIwTsFpgKE58{b> zpx5tRTTLE}e=!96*nks8_64K#J;)IVMSq4K(BA`B0AfZgti1KichttL5AcDmu1*)4 zu6*+s*WP+L5nr;guVCs@{|X8!z)=t@u0XZ2ZKT@z;}+st&cL+rZG%2Ci5RM-so_@f zJyrPU1RO0;JhzKXOK#tO5vKzJ)@y_{Jy9}F$6x*Z?nJIw-2MAnz*vZIh}M!&WWq~0 z03~1x<9V*+-Te*sGJ}Fe?h1UYQn}scqqJ(9UWZ(|>W0~49$g=7x>SE2yV4-FDSFxD za`^|a+Hxl=k<2(o$~(FS#8h%$zwXj&uw{A_QOgqLQqSzeG1pA{u`2e!-)H5%Cv|*@ zo+#tsQbQPlYmZSJCy0r$ks^AB56e7|^+f!YJaqHE1im~>ispLQ)PiGOCm{wosQWX` z7&=tqX~;Sh{5p2em7Ta;VYDhT|1Jmf6rE7)aZudJSfwHMR8sHe{XcNX;a7ICx^Ukb z#Ss2&D};9Xm$H8umpBMP@B!W-R|`r(f#==`c*mpv;rjbI&*#;FwI-TCgZ!F8zrmYU zr8mt83yn+r@1IF-_xXJdj$uvj7r zn73oIj`)H0Dts9@zK4s-7oqj~jViR(m4>tN2M_lvbQk>ADnn0FtRU@u-ny!RM!V3I zw2xCjJ{XU~uMY<|1h}5zAL1738 zp21W`r+G;9)FPXQ-;sCbB%VFh%lNG*17(c6a{q^@_YTLh|NqC0Qd&aFijt9)ghZra zM9I7|GAbF_k-bYr8AxR2vLD&soO*LXf3 z>p56-*-VncW#+xLy02<=+QeFMjMGMM)SSCZWcB`tJ5Ly0Gc%|D?XsC2 zr5cq;$#Nq1y_lQGwnEyPI?UHsOj)k$qS=6SFCDqYi`EKhY^{an<4wbw#u(x(NN)TFSAgF0 zs|pddHk}1`h`-L(`DwO>gqjekVdmkcY);8>OgQ}f^Nk|b4buECLwg-o+#l$g>yjmrp1#oXx<;ISO;Klh`Z2szs= zS+&^Y&!-6SJ>%>Ns45P?(sVkaHdnvsK2Ee?BI|my;Yq2Hct^s<%7C&0UgfrYumy`FrC4rd>I{;Ob%$<1*ffke06{$))aME-AalR+ zoM}&obxb1~Ui)6R5rv4cN%W0HjH#z^+?wKZA#V2;inT(#c(`TaKCX|@KV{VSx$&Z0 zN7tk4vr=D+K6v$gzd!*!FdP*sJhhgJGp4hl`X2k0IdXZeQ$$x| zEam!!Lm{2BN0XoaOrM(T^BeYC?aOzY9xwH>;b&&o^kP764O^{(fW-{7=rQd<4S)2ujQ4R};o32DZ|0AJr&!{qx;2DhqDo8{DG$ zM=yFQ2Ypc-cfW(zpsK+g7!ehqT z+Y4vbrDE&ASlYONq-?Z^S5QshM$p!`JVvWewSKgav8STval3tISHeK;lItcqzDQz|3>evJp&Uw1EL~e^8UJg{nnTB z!AB*fbeUC*P3<6k!X?tWufgdL;}867%;toq{L4Ga9VpEdLA{{W2qAA{6a>nFmKpn2 zgkV1i&|cYcOfeX6D7t`@2(_o(c9GC8AJbyflmH(hCWTfa2 zU>7vu*d&yjSKGQPJX{F+t8OQc0&(ms+Ni}H&F!kq!^I7_r>)Y<;*m0jA2G|g+DDkW z4r&x%u!x!O^Qr2BnQJfH+}HxaDgJ6UC#qb~SKv^*-cDxPS!Vw=?cAPkSCUSnN(@k8 z=8$ncTyWRJ3HbHSrL|1DK#j8>TH4V9e2mp@e@;_InIGNB?4tHlcw*qs992?{M^4NT zgE5!H*T|sb)v%N)Cbf#6$ ze9qy%dAz^8+NH@_I9czhTA4?Cn#H3WggFtN@!#Lwl6iwTCyt@`X8~FP$KGKGxl}d% z8A36I3*ljENXjv&jbT9_nhs@v%-mO#rG$(`F|iBMzqs+=(@fI?%GROS`*ywZf`!*ddDboGj}*E)QWp~h zJu39Da-aSQk@Dri3GdKy$SdS-%nN>7Wq08mo2V`GkaV%5xkkU_zLz?lB7Vn;;P5U^ zs;!%Ogu|OQ^H?uar}~Qd&IBfY_{!kQ?z%~LvnSQKXyF;N;`YXiv7JI<9_@{ZM+%q0 zESfnN#u!?efu6Zx<{Te0D_(eU_hiJpV%@h43b_l_>J`4mlnqVRAu+3UjhY2V6;OaI zuFY3*x@d}LLiuCh@w-SVKIWiPDqcA8f^P6B+(xHW3J>WoG_+I)!sS)e)JE0Fl;n`%+%GoL)c~E>Jldxh1c~ayc>NcmCGOET(1m8t>tY zJae--B1x^FKLsQikM_>ntNNSoI6)(0W~M|hFe^pL9Qj1cGvT9qR0og6tH-qYTT6LX zD5@KKsfH;{xAyJeeJtLzk(W|wxl{fw>=SCtU zBMShF;Ic{il9qE8hnW<1kz2ptCUV7i0QW`MpWvdu@wqSY6w)hDlPRc3aPTKb#>5cq zezoj;PwI5=>__z2gk0**a!&#ppq_-Do}Rj;Q6|7dQX}jq7Jo1{9m?56(A)sY1%wkW zX==U!hWDWnYCN%0pyl!C@z2K}(@6Tj{~74?q4Mzp732JZ4skd?#>WrjFMR|w(kwkD zl;}1bbIpG#?H@)3jG31>G~)8Y+cGn<)_gtp;zaPWuf5{UlY>#aob*L@zHg4 z-0X->&|=p3{&{XT(Cu=Je+1pe(P_KQ zw5lnm$FS{BWrm5!&i5C0J}is)+47TDHTJ2e@XvxHuBQ-ll{Zsl{mqMUYEQq2ne#S# zy#vGV@Y){#k$Y12WqFBqv&|q*w}Q^ zrT^B3keD6uyS>LH3;F#YJsrpeT|&C=tA4hKCr|QE1&6iq-{Qc;hS6 zIRK>M-AA)tAtS>n} zc$tpPQumZN+@2nK6Q%O_+t-~dULD``Dm|qDT$ti*YDoSvH#H?n06cx8U#c&$U$|g5 z!fC=I>&-7BCKgW1$SePi;@1RnI-*haJU44%1unYa=D@MR=ss^c~OF!Zf9dqY(TI`uij0jy`NBx>c7|KM1S)*j#i_4 z{^psr729o=%VLWtEdW ziK}9#g~vN;!Fe{ZWhfTUY6s2UDQ}T1?4xk;kE3Bw@$9{7X1sBNvXZga-2YMB+eYhK z<&#@NOwFVQ)}D)5n^W#7^|Li?eg^luk!gx`Dyxk9!IvE_@A+mVA&oVDmzH- z(u*NR2NFb8Z?I$q#)*yu1*0C)N`bczvh^(}-Vs|ysBP{$i(7

?JO4X~)eSW`Uvj;%qlG=cT*;aLtoQ#YN#}7PF@)6@bFRp8)Do8rl`#7Lk>7Vr6xgE>RVPgK2=g1%QWACqqTTEO~R`zV@{v~TzC7z!20S)J6 z+=UwJ88}Xfk(N)n6UqLJjv|yIF?x>uasDd5Lk?&g6$$87UlUutUoN6*^b~p`x_jqF zn-Bb5Kfj4Xv@m(X=*I+IY$sR0+Y_sWXO-1LV&#xGPM$hF%T1eerHc;b)!nAblB3t zDaX@855jXLlVfUM#&ufv)AqBt#* z5Jcc!i2>!e>cDB#K=a2UVX0l}g)AHGt1l97xF9~X(-M^)@qHwFU2o$;$mppg)ET1s zbmIW6^MKuAKMPcQI+ zs4qa8bD0WZB1kh&l) z_-BE#5a!9TZ_Gwk{31tVE@}j(kl%TW@J!#m^>x8=T8e4e$8wvb%)83<#%*E`vR@?i zewsZuZl$AfJ&XMLUIzf`bOWb$l7{3yB5wn=u0%jv_yEhz(48u4PBe#j#l!!W2<)(- zUFmMTU_amTh|Tny!#t0f^YJOUf%M9O5xE_cNj7G0H#cqB%Qo>T=%e)0=fl(x>%|IO z@Ys6z*fXyTxOoPA_9wp?yJEXt4#N5C{*^l46VmkOWY##_lp-%=2HjLWr_A@MZfdZ_ zY>sA1UzH{Xh$uM3Yz+#8Am<+z?Ls&iYcOBYJP77OC#xPi*?l($onZ@U=Sb%rXO#b@&_ixGCLDgXo{qH(SKD;_QXv5L&JAGaSMAi0S&}m0VFb5?G>s>7)LJIcKRVMgXlb5(rB_00Lx+|YdkAw6|xJ#y8nVXLfZqV zCmMWIT&xwsJg*^Qi8*Sc9~>&@xo{Yq<6y~PeP0W1O}?hN3(15?3x#g`!UC8{2PiTe zm^4D9M>9+8c1FC@ML9+6mp^}ijbz#9w%#`jQ)wb@GR;jW#fZ3U8vpv9#yH7PoQfI8 z$Tco4J>SBeUdw_Y2Z&Ro?*&G0k)Ze=&K%_>;v_^W z{%V%ajphvPiE|YfLsvNH?qy=7UxL z@%>4bH{3h98?Wr3q@s=Km<$bPpKF$hzn0`b>&B5dGCn_kz`h1Q!%O*935(jD7&g;|WAP$?QWRzLBp41^Ei zULRWCuAJg$C*A<2suWO%;qT<+ z@9wpq9wS|*6f~NF4HmNrI3^AS?LyFD5yuB-}PJAdSDUtr2zw#>RsDqd*E`soc z<5px9-BJuR25tOZK%*PlEC2{t zgvmm(Cx5X=3HmZ|O&{<~{W?KoOH-ftri8NZXPun~!?gn%?fD8nI;zFeR4aVfX(}&C z^ZiWnOVWPswrQV&Jcnj`XFL0_#{xr(X`)8E)AnuOD9Eu}e^70*EDsKlrxf$+lFj}4 zuHJi{=y(2?aglfA0gQmxr$m8P3UVtZdou~0f4hM!CulO0vnjM@-2Av*1yg3Fa1!&z zJ}K+K*7P*;c=yZv*Z*4Qhmi3?KRBMK<@?#|2$xBa=$$*qs!P;h4s%u-&IWBxuk zI40v`48+i&p*ED$&fXx{W?^c87>=G-jL|HZ<-!okWyw0UT<+P|&b@zsa@T6iaMrVD z&)#rmp=-?fbfP|=vySh1)moQqngOo&QBN({U0m85rkAbr>W%H#+%HJp8*@2#acxGV zPfmirY7Orx_S%VW7_~7`I>OPRO2!Jp9Ff<_XM`=uOb_Mw2=FTOQJioRQlhrIUuUfF^o>Cbmjh+x56hT@Y9AVIOD%J* zw%xia4|x?D{O{Z$1b&F1d5;mPt8_7hWC410n#n5iy}LqTU;YYY$7|`3W;1viZz-9~ z6(+pwMbCeI>g?srr2*@)?sOM`!@k-X&&M1F3+Yp9m_Ny5r4pJFN@Ln^^cNRP_-$^T zads}Y3b~7zJd`v{z4h}4NHh$dPHkgiTexdx?=0Bp4L zR}MqZW|GI&F_cuFt-Ppd>Nh%uNyGZ{MG>0U*|7&xQ5CNZK~Y}-!-l?H9|ASDEN^`b zU=ktQ6YG`tH)DPlc#zVI-S_U?DP6Pk3u!rr#@sPNczdK{*JrgwwuSbHdpSXSR#|rM zu0c8SvpqYiDi@tDI4I$Ll1JkhNwOPX-OqnDzOh=n-XbgMiovLXJ<^tB$W>&QP4s>Xyi;HSJEF2-NBJ^Cs6l1hg#jrSogt3Ny; zCMq4}47!3`ecJ6sTt`@prM@4@CzBmtWL@Xta*&#${Mb9D>&sYed70_iriF}|rUI!t z0SvZfdq{ErfuNjIf{$8sjSG%hU+%JO_qu{SQuz5nT6wBhWbfjcFUS3U>O6Bi7A@|a z)V0WZ%-NaQQgb31PoKIn2jir8^r%^bQ-WV^i(qtv7VeE`z$_)+rTQ2_ z#p%6}d{09ncY5^`$O)aR<V@z6k;9IfB>yl@6`c*F*LQsbJCbx zypXNwEkBP-nKWjTkB;7QzCE7gyqfo0)elOhk|p8e$IIVy2gPLrVklE|yX)`&IV;CW zYwi4w?b`{$Kd<#WdU|9NitU?GD&i)W74aaZT>hz;y$+9^@TR*_JPHZga4#_!yY(FT z<|iWmgTCJ`WbSRXiQj{-pCbc$c6i>ERBkC6_+MX)s`JX~Q;?~_lo9n`Bo8E(4GD!7HO-X?O^JH%E-lNvhR#F(P zR^L^;j|e2S@_q}wV40%D#gWS82}j|UBssZ<$&^IwTxlfcE`8B&$ym&_^UCh>k}!vk zZr}0a-Bs*tY-6kyItkMwf6<~gXOCTZCa^A6>M2J`LxlwL=yg?mR8)rrZ9NVtLauVC z>?fBG#*fm23n^$_AEBf#rTIz`l>OuP1786?f6exM-v-}M_9l($!V<#Tv=~EeH!6sL>zMdDUey*gwdF0T{(etEL{ok9yMQgBvZtGtC%xn_-5rcJB z@-h2Q4?|AwwMLH;co!P-<){N(Tn2%^$%G04gA3NDA#t#hP!Za{-w&Ma^7{LC?>?8P zoyJVM0iUO zwkGB=XRXtnk2E{hmt*bOd$54!M6w0&S;;rb@e>?d74|Hyw`<#?*8UA?VNDe~6VrQW zz6M!C9Wna4^wBy_P%DiCilm}9rN?Z0N?4VaYiesjJnYoz##Le^V}zkwWAS-54qcyn z!Oa-T#VyTGsx8k+(Dewc?|X|PpDeVl%gfFEu007{JD*U_5(_a@mYBM0I6}gc$FM%d zYNh*e{ajr8xu!3{G=6(fctm|BBwjH85WOTU3w>4U$!tEfI* zf8}A`S*_X6-+%E*DtS(`{R4R^h@75jd3kv7Fdlx8sP}(s^mB$9XGh&e!3?&ZNFlxN z`W$lJGLWohIjs8oZy;uI=yan8znHDbipMhysAYB?jK$5>TX}at2aCE*U(+f5ii%DY zQQk90__sU*yw_o{llT_umY?~#x&4v1oq+j&KHVs`t(>Sm@oMra56KmL+z^$K=w2_u z*#Tt}p=-S@&=Gq7{#8^_d5gy}m6musmNH*VLS<{PTvyiX`Ah`~#cp||&tiiys+2l` zj!7U~fbDK&|0c9})x+#tcY~teCnpCu0Vp-Tm)6h{s#^F>UXxh%2@B_5Ona^r!v0G- zBSSUr%d>vfjX>#~63*b?c+SN2abv<=y$v>}{(g;8B#*L&GI4TFj<$d$f6>Kljk)V6 z5(#O{T5-WW0pf%j{BwSWhimT?k9<~FR~*d3oXkbVBP zW0O<|vr9cfq(4RFwIEs}P>7fw-ykQar>o0McVb~54vfo4h01%Bh5McOkP>Y(a37qK z6evMifjr;$5xbfi8V2!a?Y!H`(-4(zIwI48Op-#3h$j;Je7d28RR-d|0NH?{aw>Kj z@!C7s9iXK-CHvhLm0q5_Va&7*1ad)aI(kee`{r>J~bOC!K7LVcZ3aRN_l6KO_qq;l@3_rE zaO=2A1t4RZd-)sU#M3D+c9ik^7+-S`IPtERUYD0kPP09Vb%paVi6P9ndbv6? z_Dk+5nkl>5sv>e%LE`Bn#7?}PE+lFhB&uo+U&q?JpO{*Syhpp>A%AX{bvw`wU6cPW6|$mT;R@F%q1TTGqdorP_7Q>^q4eKwH)@Mq-SsKDF7 z5UnzmK0@~B76ZKqA#DaSR)QR5%07cPfDewzEwzSzgiQX+S3uFB#Yh zX$SG#2s`w;LG_g9Lgaq62G(u<1n+)T5xW{n;r+v+enVG8 zWeA1QuCNAQCG8?pqgS%rTwcC+78F;$DC~H)TUX&amo|xx=9ml)-5O@begB=iM`3RN zSFXDLuUy4E1`rH1;5=>w7htyB0SwJ+v%%o!*I<>U;NZ>;9Te)@Y>x-Jw9%UN+Ur{z zGX-!>&cD2K@1BlZ2-27fF>*pWcw2F$t+xt-K#tn5V*HXEG|P?=J2CQ|1={PhZfJC- z5+*(G;q-X&r8Y1$)J3=>JxFjNPYS>}HFRW7Jad4%#>;G_a3h5RiTs0_v_rab*a930 zpth3X9Wb_MPRAdD5*dR%ui^YDI&nAQlj;bz=P)el0}xlbcugcoJEfqojj%0*JslFV zOJkaUhL$nC5D_KKpXDq*T@5&U=`ydqN$JbpO%s9%e4iCaeGFlCRE+21Y#GBmNVBsl zbDTR~y(w)?ajUlIztHazGI!7Sfx@+0WSU7Wy{4c5gB_j}pT+%d&^}|DxA-VbW;IYd z!%95oXn`XCcRwkfbh%aE(&*$I#)Qu+K%Y32v?NValc09heH;7w7cmXvGsHz_I?dN0 zjVw_V7vDs#2iX+&&D`iB*X+xx)!b~)t54?XrtrVPgqZ&F@}WbAcrk*u(|Z_m<+(&E zb{R0e0k+`^IXfXrU^(Ggl5LQO@k}Q$((W=&JSSE^CPv0H@G-75K$^`fAyM@DMqHU7 zKmWk$e4jav7z3}_b`o!db_Ai;h2|eXpLT``rgfF1F!0R@}&kw>3_TqaetF+tKv#!icA_;CsTEi!W zYu9;{n~bS$vo};}wdecE1)LR_qIsyk)Vp~fNuD>$vVp&E05QjVT^TcvO;WJeBy2ED zB|B^UD^sr5=%2o-O#$=WZzp!AM^RBq0A(>y2wCACdoLtlBn%aa2Rr37|Le;b7%T7W zd=%FdDP(%fMLxAeoIL)3p^%1+oX88J#~SK8uMP8Cdyog8(DyLVrpQ{%|q{wko7adqWv_%^uaqvT$Y5`3tME~coUMS zKGfH9$;y6{NHVqo1>MlTjx#P5p^Og)mWi88W8}CsKU7L^8WIiS&B@*bOeZ4b;5fXY zV>QF6G#i_ZEfs_^X*p_syz?!XZ)z6zG(xSQC|9$16=F8DG2!SZL~(eOIsaDi^pwF3 zY=+f95ZSn=+TE(4&AJRQcWnrVdjTTbrGMksc!;a<5vr~GM8AExnu7RZSJz{N$qiSd z=gObjcv+9)=06fHglrNUnz+Ze9xCz0FNp}}V~)eyz?a|yRv4vHp(`<bhMf(QVXG=rh z^LU)qB@5pl5Vjq{A%L%fD9hpdJKD;nQNg3uUw3M29RsRKNKA-_OKf(ZaFAL_xK7>J z4W}6BQTexkPdbgBVYTWu4#)e*KUMU}%o+DMN?1{gZN}CU;Wx&FsmLeGi4uJHg|C7l zCKzbc;_DKNfPmJl3LKv(JwZp?3J4QFX|yb(6a=KS+(TPW#9Ff)wPxO9c#|HX=WrW8 zgq#78EOA9c5|`^_noxH3{Q0Md93w&|2q9B+bO3qD#}<)d#Kd?tpPH9AHh1^mM?8|G z%5=(eLd6fJF238gJQxEHYK`t`@u33d1|(1TV@M%SX%(TfCg#QACB z4lxyQ8{5&wG5b+&DXADV41eI2aowwuurlJa#s|^M@SduLjf8KbdcF#l4pjWZ#%qB1 z--5@XDwqVf@CiaYFtMq=ba zyPhRIsQ+z}5fHS&=)I279?$uk=~29@RjK3=my78;ROIF-siLSuzn}BB)o!nGlWx@} zLV}V5O4YazjU z9cApzvg<=n`j<*C4;Up3lBJcdUE{`L`HT7on8OidPtES%njhh-bt#R?^i_X$}Mw z(5)zV+>9@Df~-(}EFqHS-Im*d^?4s)D8;aW7>FAmLfidpa0mObhlJ%CQd1&~=GVR) zd=mYuFE|Kwgx-JDO zSg4U7;ii!+zi({>WyE*530-&;W@csMLKrun#NAR~Ur?%W>6kggd&LK=83pew z;6zPrw6S4T>bxyXwj8;+wck@6T4vI$K)!XX9Q`8YluotYqtTs*6-Z+V!aD7YT+=(% zFMi?K(f2B{*-gQPN+NQbdiy#<*lhKslih8@$<@;IrRPXC3uUzW0|Nu+It!!m=M8Z3;rbsWPH}m^fR9*$L{;UZiJ54x z2_*yWO}E{4S`74%6@6EGj2?XkfpE{@xnJM>1nk5OxQagFGz47}jfpd;=;l4I*`N~y zo-u$94vVIV;krZ#V&_-;W}uqt#S~ZKdRo8z4O^V($q<{w#YGIsA*N1HvIO#S!NlD@ zD~lm$yTKvd@M@WWY7KmkVV{`C)GK#9KjO*b?D7YxR0uZ{QZH1B*;cN5=;& zE|8ILy2~nmqf8{+SJ?9Ja00Qw9EGo?MA@?M#EC=#o?BOM0nO-!PH**q7siGX&T?Ys zqSiup9fs*GcTlm=2;D`SRsh#J;fjQX8TA7N=Fl9$4VhQ9=I+C_hNjO9Rx|8;!OOMz z+t0maGYL|HI(x{+3j>Kjm5*H!uMx!k$_1ex2oNYo!xa0fQaof&a-y~8f7aXDvwJ~T-uuf( z-Qep&Sg~ty$@oZlPY*6|9PNU~8RvGf+yL%5I@AY!Kb|95r~tEY61|tM?-ns?1fye+ znxP#50XiW?LPhf3t_sj>b6l7jbZ9A%Jo<|0&7t8cgmqO%?;ScqBKm1P_z$jkdt3w_ z40gz6;q;uMB-#}sP>S%x$H@6qnh(XsJs{+jc(&`)M5aT@ja0#3uG2r15k@n_S;0b2 z{~EwM)5Adsl)fgF974wef13kO-$2iN&a;n_3v!~OVbC{i_^}||i5q)`Neej&NX||l zn`9-KqSASV&9K&ToS#4IwA9d27vVh}ZW=^H;}D(C0yPo054S{>b>df=67){1best% zykb!jm(_E^Xf=gV=6?q6aV~Y^%zNY;G~8F^BL{SQH^J2qrX3K)e~p)4OaA_6x<-5f zu!4=AALh}BR=%#y6J#Th6%Mpy$AIsx8FTAEco@oYadp(Q5VDE2d7t%;vBT#XVK5#> zc*czMHb#H6ax$fz=B(+Uz5qCT?7d6-g!pkr_b$tDaYa!~QYeQEGxX0_hm%?B_&U6) z47NUAf4@#5t-d&PT(iA`>j7Nk=~n=B?;p8XCWbz(wiMef;Q0=V0%&>w*Gn;-~Mwy zH&Sg1)@KQSJqY)-vAr^`4?*-EvF$mw?tC#h7bEue=iS={P2XYiF1?PjV+J^WF2I3xSLP3Df7Awzt6``vhKQCI8HsGjS^hMZ`trTBmnGQbHmES)_ES|30Va@X9_e zQLZD53v$&`f$byJAKNsGf=y4C4%zo7-yK&ctgmFA*CgN^j#& z=;~8z%&CYBtu@VT^%?5z7)UbSThU$B^U>Scy9H#l6?>X%e>G*ttMob9?ASu~2^>m> zLl*_ZBO`}JGT1mcCfpCd*|5nx31veEX|3W&^EKD==g)`p@-?i-TaPBi5x^ERom7J# zQ4*n>_`gq^KExR2SIydQt5itkLzAc3emmH8d`wDb?#r(aZ6%|sB)MA2$)A==j#N|0 z0WybFrM6W^t045DdA&)=H4gM{9O>%1K6>epDf6V!E zQNZ79&vPcMQHAX0UJUFQjYS#Czf;<2^c|Cq!GN(5I2}Clz2-ijwey|_753dOk_(QT zd6jD;cf6$=hBFC^-qR!VPfv6N1CVv+EKkdBF&{H%InfRBYWoS}II zdG9v(aZ1HT4zjhg(0bl>JfO?DCu}3REIGMWyFE(&8sp(TKQ+5N=_`NytROFWp9#Hk zE1Y~$fA=4Z*rDw7advi2Th9Mg<9_Yh({(2=hU?A0ZzEl1gUdIkJy)(&UdkcRGb9~Q z$~6sj@bjcEm6274qth*VSO5kEi2NTKl@{ZjP%Y!?2 zH0}(eC+pAndr7FbM{qgtSH7FV%y!p)S^7olDSvXLb}98IA*MZhX3(>Xcdfm&?j*$S zqpu9*<^9*4Y{I#l<7V;f`~vJjhAuWJ1A#^s=87W!remljeJ2Zv>Sc7+D@)Bsx?^kc z+BOD8v_2UK3h!_H`B9Z+ZL@m{{9P`KYf?H zicx1fNt>N>fa*-~_a_v|&n?@@(l%Oan=?l(oMlWM1U8 zjZf+P3cVtOU}dpxy>oLp6JEn0}| zRY{ZVX=sw#mzW8f;9n_Ig$@u2Wm&y{B$S%tI!#yg8O^ICf0!)<&>#4TO08&&NF$Pn z43v;?Ok^yQwQI=lc`R+HND#US zt{n6btO%UnH30(j?Jw z7^z(Us%E`%XPXKWtGsyHj3w?y*0v-du$j;0Y<7IAwx83oX}M&clJ?|DwZxI<{2`o~ z8$8bunim?`9K7?d8xqN7G+m!ZJZ*wbY^S9iKq|wJlm~~XJWWS{KN$XEC#!x?`StIk ztEi-a9au9J%&_|Jwf_!0TM{5c{p!JS{xbTK7g^ycX_a(A&O#_fwX*f~NH3}7ZiqWk z8*RC%PA=O~vdun3F_>~Vpw3vHTl{0KI1NC~hV`-&fiIBujl&wW43J*S_4XQwa9HHL zU->M;2Qh$fr5qQ7rWi+YGcVg}$!p@~IK_fjJDD9T5<^EFd!?64_m2oy2QrQ%ZYQf< zeUV&i_aWZvQc}wo#cP|AE{|!^Ux9FX8~d@HQ-V1WghtMseVB4AbO+rdW zCZ15MM1^w5c3C`+S%P2j?|j;fOs2~D^V@))tqq+_6yYK~jRd|-X{`Ad4B8by9+bxw z&wLHgz#Ygy^o<<^SP!J1L-8MvXmWmvF)Yq+wj?}7s#=!3WFvyJ%!uMUdjnmzrOjBl z>}K{GLUNa+?JQ4bSw1JP?TX&=L%O$&1`@F|)L!Quy)p47Y267Uu`S>^m9RPkgu?KE zQGB;#5$Zli#4RsJMG0T30hvFlC-b_xle4w86|_Y~Y*8{=kv#eN-U<&k;iHVlh!Qh2 zb2q(@R3jOkI?8C{b%!%8mqzBfd3n=oCiQ^5Lp8kZ>z_+UM$8FZl2vKL{I5^`pw7WN@E^U1d)IOPr;^Z z>wcF5|2-Q_8r&!T*PvbC|80yRdG7P_Yg9rM414WtHr~x16|&=^rjMcO`C;L%K(b0W zrO|Fuy&95!?D9pEh!RqJ=gA|_8d`f87c}K3Y=cZcc@Ksi+_=kO!I>a(R`9vgOf(FRWmY>Ep=N$h7!?nADJWrvG*@$&p6 zA0Jl|}^)mJWmjP3=Ce9`~_aBFe~DgkKuLNQh|p+V8dL z5m68Fo_$wSLjWi14k{}5@3sEhSj>#^@=paT7e#$`1PtbO{NYh}Nh-U-xHGJ{`liyS zEB(*QCX@hWv`EE1@~dUrZCF&>?QhrH8oIYB*Efc1x{B+nmS_wOA`P!XeY`e=wW1?+ zItyql%vSHJUg7c*m}g^Pc=PPa+m&^cEPI|sD7RWiY&c|Q-&9mobsVuhPUn!O3C zg3ub=tbn3}z;BFuF_W;!)CCJ_e6pqM@on+ohRzn?GRb&K5qW!9Sw~}UOUlY75LH-d zA1nesayn7f%Br%Gvh!(CMk*L=n>MDPq*P9R-u_qic;65ZG$06zQ2-*wR4k7>jel)* zYH91_8$!WVn)d;z6|@E))AeyIILOu!bGZeSg6Dp=-p03HcW{z3CzviT);)W4hRO)H zC9suEp31ER&W*agY)ywX;oox(IOgMb4m_wVrsNP+YvbYt`MkF}(k?-%i$YTm$=>Hk zj)Hv!A7rRsxCqImkom?+^OFYHC@&4)pl8vWth0PV=JU1dPh?~2*SH)QaML2kByOe_ zva4Z{hM4GR0&6pj2(Nabo|`D2oQrCebsF6TV{M*8(*KlA>-k78pbVTXXgD+&dCB&V zNIsG(-apvGxO?}-!K#N3X9gq3;GH5T0_{}|gfNE0o$wapEC>}U)z_8;7*vBXJP6|(JW`xDXU%Xi!^0AF}jAz;othkvl zfaioieAvIVSPtWPhsCF90<-k$Nu8MYG!HOUgr={449ZRzi=T3imY_Mxf2WJz8xE0?v} zW$0tJU@Q3!c(j}FD-px0y?~yPQI9sd?cL);Vi_w zPa?_5*N&qVGpR-(BDxJ~q!nBvXsbarcS3~dGGX9zq=-Lw@9{5k^Q;RDX;FsGdb!1` z^Hu9jxEVj{CT|QT;&+=98i2B&g942ZJ!QzP@)M>c0HH+e4KAC9U%%?EA4Ql*rCdzc zXPgeM@X(PBGYY&B4gx`AewjS0u2uu|?p3W^+@7O3!sml8pc(K9j*_6XA~^J zldgMDsG5i-h*5rN?)N!@f1SArZ1J1dg`B;MZ$a^X z9^3$Ga=C7nHs+mQVwc=-su3><`pSx$$xbK~e+YEjkfRME-dI+#rWG;^cCO zkP`kc3x^0jh3c!M#)~-ilXO2oM~Iz6`9OIp(_VKj2hCXZ)CjAV*{enL)x z%QXD);~xT~IPmu9gb5Q~X{kiZ>4A71S0GoUM3dQH4M%2I-7XmuI8XGxa45{xh=E{m z7@tCz(f@0Q(hpQFMO4vvZ#u^JsOwJtP22YHOA?~=rR)pIsn=PiLQnoSCXwVPHXfxm zb=qRg5EemZjh4Pc;#__l&_lDrH+AVrPTo%!zjG?*#%Kg6t((PAi(Q3p0$v&VJ$sZu zz!KwqPk5DGFl8l58=nfuNwp>R{b@?*&TQd$aSURR%ZS0m*7U`bhR_C4MT3B(odoWT zkGBwUo40ON%lc?QP9vEA)p!0bq4UHz4?>HAvV{S#EmECuhyqOf;x31flqo(-O)V|x zY{>1-dU|@4i-|G!5jhf#Cpi`yk0*xJJL;wC-0Y$kgHyIssxts*+xxwn^pE|Y7631F zGe|2yyx@WGY5sl5-@<|%HBwRi2^-rEoqv7iLl#7E6NCXD0|$k67 z_3TiuJ6(w}Nln5_JAyInAHq^QHRF3vLOmu%lk9#{o`a^B-$rGF5o4GYwO5WxNN)9{ z{I$K6-q#J6E*^O(z{NwWm?-2VL zk}>~{x*A->BJPB}bsx`DWC=h=HvIS35~)z+xE)-PdPwa~cxm@@zEN9Pz2gT;P{Jsh z`RqJ3@%WYoZck&2ucZ1CQ>oyf8gwgp7^{P={OK`VM9ktA522_Q`OR_r-|m)@3#hZW zEQ?s2{grK{jJNpt^+%(s_tj1_lFL#>cWCQNyWCCvW!cXcd?QC7WPSf(_OGKB6B|5v zx%%wL$AWI$4-QVl3-GnOrg=b)?=q|2*|Pyv*9Nfz#>A;w#YIeMr;xo07ol=!s;FNZ zjD`9y=VawbpDZ*!$q>vpUXC`AEbYGcLiK+g&}no));%TkzR05t{}&-LJwq~0)4+nT zlDKz=)(8M@-ViKe!!1dZ8sat4gdpU(W6?%fV6*2L-}4^R7JX@GVH*58<;BejlWNWz zec4|(^<SpFmkK41BQv-xF+Jl2V4Jfpol&=5kXQ`Gv z7x&h$DysSTk}Rpo?!ImiW#8@hV;%V@((mQN*fwT=p89=F4Ka#`h*2*z3+@<*R%Ada z3_er}NuF@J&r7p2o7?`_DNm zQNS>lM%MqcXQ(D{VB290d2d>o_obHC=BaNJ%F7AjvlE{OzWKb4E724mnwyK)Wayv_ zCEO=&d+%P~fZoM?-Funo36HXxnq3%ASngv$=NkxDFIs{TW8@h8Is9MYWx{$dAgEfh ztu1Dk@Ee_!xyZ}N>RdW;xa;|f967dY*QSf@5!IaRs?@&gmiJAf9t^fr2m2O=9-{sd zShtWKQu`lT(DjU9S~l#bAAmP&UL+rY=v#~b)#8fshjxY8273l^4zMkLecS3uQKCs& zPdO#6_awl8V&y~Y;~g@s@2;$H=nm-u7qhkg&aB@4e&JDavu5RQKQ;Lua!afaliV8Slx z`@iOVv@?C%NzwzqazC+ zzfLX~VT`E6AnT>*%WQ=J$Bq5}qw2cjsqXvt*Gef#r8H2d(vVby%(@+Epu|zhR%Z6z zr^T^zH-u0rd-QaQpY0htsm|FbRd(+-W&dh7&fX65 zJujrb|J+FvUGi%m+c9baA$2fHU!%Udh@nh#y%SpCotu-qWt7VZrC0c);cWmzeSQ1kbqjB#`EH?1eSL2%xVxw4 zW>i%F|K8>Ct{6^-Ju5UDSKomD@v@f@o1(v)YeU1co+iJM(IFwp`%EyuyyjOd^TXIK z!R@pv*5d0UjvS0dt*gWBcuX33f;r~;%$Kvw?WT+{j=q`Rx3B|(Em;2+3wHpq;ClH} z36=H#P$Zqq9{T0bu3vt`r>Mi6+H45u~w?-!W(`t`}=;v6p)NQl@vh{^uJM{ zXgI@bX?}^W<8zhZz@s^g*;Q_Q=3Q?R)o4_i=bHXI6jp_^l#bml zqGj;LKOVa^w;{i}CbiU;t%G(TUSVcD5bW{Uk2N{Vru?O9v`*5N(k%|@TWBuct4Up1 z6!cDoR`OaZuzvcHnU&#X#%v;kAr-#x1Ku4AS?KyJ{_aV~2&?}gPpl7|^lMy4tB&>E zN@gbZXO$$Et~b09Kh16z&74!E1@#N0avtyLo#pHqj=9HyCPZgkyY+OvXlb>8+FC-) zZFT60z8y_J@+(&^9hEgKX1w;~jre;bmn^g~S9EoCH(p&7QVpS(fzZ zxq7^^^48;2efCzuSim-|?2OFh)!+WT$p+umf6l4XHpop{u5w#`w)1T4Zpx$^U+_)l znxy_ox`OnN7Ya(x|9-ow7)CRvS4v=>m3&DO zLzj^u*YAoOManRhIh=NeE-0e*QGVE5hi5iSYfh?K^EkMc74C==EJ*qHFC~Cc?y`gk3ZzPksU2f^#sW-Q6N!A9i68+c4teu#0q<4Xvhy2nZ4GG~D z7{H6$xJaHWFz^RXT5t!d$RS815xCPC`VTH^(arlB*S7=nqDV-X z3wot$cod9`yeBClaHH|usMd08o2luCd&e$ay2Ne88TKR}1iO|&g)x+6ETf?MWrJW9 z7N1;*H<2u?_QI(^K!Lp-0L7~gb1x8~JLUz+xFvKt#~U!T+KecRuio9@f3O&WJ_jTJ zgm>eq!I=wd@M;k>7-1&218P1wq&m{Sp*CLPrbQd8w5`3zsNg7#+o;x8x~i4BYK7vW zvJMf=rK9J0&*{qOi0`-+`uYzK@42P3LLZsG(l*d@DGvTjo1eQ&+dmh0k<8^H#w!U- zB`7H5yPWxjOF_9T15LGP`78EQ$BqTWq=ZGiy9)Jk^R8nuX^J7eEVP(yl=F1=Tde~u9&94Yorh`OmD%kJTTV5o zX64Fw&db-38t7kT`MMV}xHpg(kOt%EYOgnZt9y$nj4CKNWbg$>1|VTuf%9jCITAW5 ze^BS%fMI=sy!;h??xAV^ly+V!<5lua^bED&`GDy==)A-EC;7vJO<4RR#Fo@vMM;^n zf?QFAu|v`>0={Y>BRL$qJ`Up}b?5=z(D92Dt$mL|;2k_l*FhRaLQ}T~NLUqtgc3#< z7Pge=%R}wYbW$VInCY8$Q&#%fuI@7F`uv9rl!KhoYrUd>k@w&JOrLI=+~tQ%E9Fk4 zEPqN^dU>8h@aOKNT}k~Oyw8@oEzM8JIk^6=UgO+Sn&`ytLkpK>?I5Y+*+)mk1MK9R z^X}ZIz%8H~{0GQawBAc|K;cj{*;R_>eSGFz&{(pCiKpU;<<+rm@?E(z;KZ{JEAbcD;4SwLW*rAwT< zw)Pq*BS^h_y5s~V&F4w!G75v?)^^>1PyPAtdIOJ2wOcnk+FY^i?467rGe5qa*J7!v ztAqfnPq&72$hYdLa_6Gx%Jr}#v zw{6A2*j=>GvTld3u@e9%G;%A!!Lip`c<2f1de2mj&tl7U)~Vi)>G-4D&dHS7V)uaK zx*2^UwCisEuiJ@TRI#I!Hv$#EK(%Q}ybt6ZOZ=+s){%ewEetsY0}s_-Su zf)ClmRh1*tezL>)SCJ#+#v8PROj`?h|K9Q0JS0(Lzzf~@!!44~xcq2#9Dc}+Nr*}I zhFQaA(w74l?`$QewQ>_@r@yaHct$2~=vI=8D*niAUxkkn+fj9RO+*$hR%NJU;n^ko z1B#s=04pjwsCMDPX4ffTTnntwELFi!%c8VPRCMPqN<&Air?dXv&_|bc&{~#ywbj(E zxx1P2UE}D1(|_g%Tim_0x}GbJR=Wys-n`-KrW>0)&$2FlvhDEdTc=Y+xK^J^<;x3f z^z_WI_HD8D9CEN7GHuy)pMGNJmCxK7r;`7SWck)tkr$p+ zcY-xK(oh-U9(&O7ga5tv7aWRv+yz?}Z{ql{CDNam(xMLU-@XuoJH3C+kpPBQ1;~#p z1O$f6!6u8m>jw!5WA+p;eTeW`R(f`?Cr7Ch?a#|wT7neH10q)3={DKNXYD;s?Np+&V zqxAifpgEu_vn7X>(8;8E3=y*ISBt-7mzP((aaGEIHO_OgAjd71I>pOGi+b8Gn zUBqMx^Xc5~`3KDTMWdcd4cAPqGafVNS@*I{9I%bvN_^Q&nT))-5E1OfK|TrvVG4y6 zf*#kLbNt&dKzJyO!Oj#~z?Q5OcY=$$^(1vplww8g+)jByr6vR(eI&cw_@U4X{biSa z-etz_6$w7(!(tfs;17fG9*@c_sXroftxDTor%9GkSKjGD#;<+bL4xJwbuT2c5ud2h z^Ee^lJ7`1%9h!!R>FLWaU%o7yh*ouZ(`*z6!HGVX zlSIXSpERaf%et2_)C(Kwar_0#iK+Nw_NwtrXNm(S{SWaEv6#MA`NBiyn#kyMZ>Ekg zC68rlAKl>Fr>gl$mV9068m48s1`F9aLU!B3q02>sUpwR1wY zE$?2zPrN0DiBU&lfEZ*wwS%%&x${2b(#r6*po%=@N46*Z9F?i;6FZ%vkF5U8majq^ zs5)^mwk$ki{$lU?#WR!T+ml*42pjfO#%?>-O*pHZU;T@G>m*kbqg#v$PE0G-fZrV| znOI9c_x={Rr-q@Jh!S|UV`J%7BA%s_&Fwrb<$VY{adwGe!h=88O48#SHJHCQ(xtfd z@)#9=OuPEHXf3RUGW1t|!_q{Pa;MQr!SmFA<(~PH-^D>}VPoB3Y}&T%O-*aARYZUV zxveTx@e{kjTBj=1$ceYqk@%P9{E#{Kbwh$FUw9=k`}w0YYpIx8V2AZE$0^(Cg*I+-^Sj$Nnm14BO}}&t zLQs6W+GJ9{5b>VVaAUF@N2xyVv(HujvTTMM>5BR8B@5>U3yUe|Cd$L~K3LB~H$<}8 ziOjWROr^QQt`Tw~5WGPuU3nf-q010uRb8Xj@j?25lnPm0g$a1RtvPVufc!m%+-3y@ z!O6A}kAQ4a;$^y)HE9EY#8CvK6nG6ngZdJq1`lc8XRl_b$6`!#%yGkB1#>I%M#Vhp zTON3Gnr^a({`@7hDP1(EY7sjZszCsp6q zZDSVbfxq)*nWx5T!kDEFzlv4k0vRhE=)G0ct zi%#V6+*le$EYqkzuQje_D;6mEdlh}oZ$gQwW2wz=o4~9mY&cIfeYwbzsZV`*-uKSr z>H15=8P>CAy-!)Et}=>tQ8wF1tA>6XI6&E7$~^;D2?~YBh}=5<>z2mTXf%?(`gcJm zZLh1VBRw4CbJNYY4JtqW%9PQe`6e=_d%hjXM&Gl1|(l zqbfJQJ4G|KQ~LFY;-xd@J;Eng0Kjf3aA)X#X-MUuvk>}&-E#{&=IU7-jz7uHLkX0} z_$udxb9mN(CrzYaZRu6wJ8gUq?N44JPp=JSC0F}Fr87I}{@6iQbBhfNA9!aln$5NO zT~F0-XVG1H|Kmq_UYrLR17$u|(L-Y!C_h`$hZkaV<$@OO6JZM49Qzyu2V68>Pk!&8 zIXEjl9Q108311F$QHd%2;Bmju)(RA}1wMi^k%$VZzwqX3vHOtMPLo zR*%&=GMhdMaI_2XPG>oJD@@i_HO`ArRu$%hHHeqpw6JBHp(+zFFf%iYzI%=QwsJca z6@}2xI8NH|l}ZwohC%|rg#ahCaQ0bH{$1A2tJI*vEO?hHSA3M_*gh-2adG>(o8R+8 znBA=T>r2P{Y?cmQ|D~p%eg1vqd`mUe3GE z4CQI)=rqpxS*LJ}uBQ(W%QWi^lKPW}hwGO9SzOAlG_#K;Z=}tyI4U5W@nBkt_ZTiZ z+2sBx46&$gmUNCgsPgVxuGnr&j!x?;CgGfqA5#PCl+_%q2$vlWK z!=ZZeU(dGxJWnyc?9J7p5TZ9u4AW?NRf^5$ll#xx?eX)`qiRRpE^pDwB}#LNIn&-X zgd*qY9mX#!v$bg<{2cT-;RA22qAZFH)YEf0cFc@A2&d$z>4Sdi) z>_tMv$O|of>uvN%zll{$kJ8k=KD~-8_x9)D^jWF)?z;<=-^?&#N|J8*N=b@1x;Ff& z{#k4CeKOdl^e0y?d?nexUupN6r2sNF{_kztAVg_>;H(TeK={A^ULj-M^P%HkAtcns z)>jn7&|TCn<(J+;p57t8r|b8B3G!33a=linu=10o&JLba^|^%U3-{IL6nZuFf`-UR zk!#-EZBJ*lsltVuDda1FnAg zP&sI{WyEJKxNyo~?ehr#lBs50Y&)yN0+w*S^`(<~_nET9?AMRCxn_Rn`Y6*TQOfoD z`wj0UHYj(xhSW-K$U8$E92$JeLvD)KX-4F8O!~ViR{ggr(nerT^IC%Z0ChA748VVK zoj!|UAzIU`aBOFXndl3Y%J&r5CXP^^EGr%NOQ$h^XC1TmxGKa}u{TF(RroQ}>pyOl z9dIvM-X37e^Jhh=CuL&k?3F?ds46A3PpLir@zHl9<^#XW<|KOKGdk6I3d1| zd*P8N*A_gKjIOFN%Q}1G)~#!x6__9hh}0KhoZecd@4{ixKzg?7aGH9n0!RH3SI3IYhd{6|;!-q-M=D8_rv%;t}| z$7lvpA}7UuNz*s5s9If8+(ofv_N%WFcMoO?t_-&z^jYlmOk52Ju>%ukF2=6=2n<<@ z%Eph$_ru=q5EgdO9Ii(Kbgc1T-`-Zi#}Jn2!E64&mdH9?O|2MC49m&9K%HMg2OZck z&Xm~9`>YZe#XiK{uK9zB(H=}NRF6_yV0C=PsN%+E(ccEXf1I_nwF}%9MTU?Uh~j=Q z0TNx18S%H-QMivX8)x7v-`R5CQp?;Zf%1WXqdVw5%k&--f|5JcGafO=DGuA|Y{V6# zxZ9V~7^aUqWJ1zbWyyw|R9z6$h)^V|#W9awCir24wRtS>kdbTsE!c=K_pG4;X|M)Ph8Pe8?p zawi|}^y*Si;)v7Oig+WjJ*)5%8a(am$rESCrcK27_&70my$0UA^_}FN$MEdO7NUcD z$RNq`&N-tBby~J^ry@(L#o&7Ob_?P})rtDzvhb*g12eWqv*-PP9lGU7y%5B->A!43 ze!6kX-DKhRptSUmijjo8ya3MV#mkmS{9W1_4FMI>gyKG@Ax^URIVH~geTA``uyZtN zSjp?IN0Yi6S$UL7VVPY~I-a>!KK{L0XQw;wSE#K`IX7eX{4~3F-1~aZYiM2eTG=QuJL5h(V}xkQJVFqX@7X> z{=_AYQ)UiZ<984P8+g7BIg?ChKN@BdWOErZ8|UcEz`^{$1v;sYjU6_-+a za{oDkhri&Vk(jwBAMKA8E#ifOh zkY_gDXWAz9%Mm6lv+E8eAG2pAigr_sgazWT94j&wfQdvL3Wf+ij-E$Q?tgbrojb)r zmOj9(m!jqDf6hJ0L~ERtUTAOe>*5Z2ZgHkh0@IY)KS^vQ^4FHKtTGN}9euQslahCL-*h}W-hiEiDP<;JAoz7kq zjXe=?*}GH!rX0~GwR5@izf5=!B@%MYU!1qmRaj;-+>>S0X(BACi!ybnrwt8yCZdTe z9y?yh~L)GzV%fChirdUi*e;d>hyzl&Y9Ze5>KtckJlz2ddd z7)t`{Hq|M{>yTbU2vfLH>v`D4(%oJF zf>(VjOko5B*n0>}3^Y{tnb|@b(=et-!Oiuc>lh$=Y-H&0f7*} z>&^DBwDGsJ`0!dg#Kcr!Bm|-ObYyKgV=-cQFN2Elz@Ws33~l>INl9SjEs~6+eP*R$ zDs&nCA=w?LIdKty@otRh#L%{EAO=b4=|?VJ+=d(PMr33FWbF^1KK(qH@AFnDJ#;&3 zDO%&I4>dc9Y7#)+ueH!j_cR2ht>5JtMq4O7Frs3e=tV}aut=- z+Qxd~dPd@$7KmV|zdvBbL^-yXJEr7pDILaoBewJGcty>q6 zl3u_CM&fJOzyyQGKUH`1DMY4*pihM^9Y%+3?dWMxkc=~LCH@u_ueFGK{WbiJoM+GT zipBD;G7N#yhmKv^&CLJQI{EG<+zqZk+muzc41y#9hd{?c@N*z^ zj*@v`2kyEgxq*bhz-Q08-+i6R4s!e})IGc?^t+$pr+3jU`C8yC@*z&KO=;&_0e~+z z&=0^6ABHT9Y`8aJH1P`Y!nP{j^yXKt>7%*nVno~wTlRw& zbMBu_v!`_@5|*yO(o>-ETYs-?8}sv96t_!8LW34J6D#E%XDu0hlJ99$&V+nMO3GN{ z(hRjWGXuAf(Detn@Xf?!{hAIKL_Cd8)fU0(3If4zb}VlGSL9@Jd%Gcdz?hbgGQdZM zT~+NMzy1s3EONP+mYX-=nb>1ilhcdWRZ>>wz)yRRi;6Esavd>c@Q1n3uM1ik->anb zm5&@ThUEla>mV#wjzGEob)Rn3K9eJb9ByZ*?C@!QiIX)8`3U80SL$SVmvD@xK1f*| zkzle-D4tn}u7&XV^yR>kQWL`Gl1`G%Y1#(5D^awCvW4*CEaf8h2}(E9GJP|AhAw-{ zf^%pLpF}eF*FVlA>+D`cbc00RMS3S;qsiU9A+u%o?qzMW-BSCo#g{9pP|4;3^=~_P z)o)OC%iq1x`~Yd(`P1Fe@I~!Zm$!x0sT)$zGU04g1XaA?ag`RZC;dTfdk7CEz{C}n zxs+|&I7srUJ|3I?AJ>Oc1%pp2;i&%aa-Jgu9ktNHfsG~hIm4hjdR=pc5LdiE@xHa# zyD-^x%JnlQS);XabE|RJEp!{%9Zv7i?7{l!Dgw=oVO45c-j|8TYB>F~E5DzaGFmb} zu4n%v!MHy8!cs<`kYr>-|vE(S>Ic|zrTM4Kfk%l zvOH<;-x4^bZ^XoeeEM`62Q?})R@{1Id%mY+)**4j1!2{@bWD7af>QOmZn(xt^IBf( z(T@UHtC>1!3hs_K3zK)@j8hfjmV@Ir=|QjV4VozVIR$E^f)GR|3f?Za&Bb$;Gorw zboTaPSvmM}3rVQ=4Y)urM`l|@WTcGu)pEiX?iEal?58qMR{c8|0jJqOh%cP`Oa)8z zb)WSmMB_;@ppCAp>Z{O$pd}N2?&^FWf}?Dj(cQm9j#J;wtE{v2Af;v^*L#oeFgN~h za4Ua+N&g)enUkYTKN3+^dx00$`}05oZfDY+3&B(J@Q~?hwR?WcRevW6!#ud4IIljE z{p1Of$9waW)LS$$O~5>^v%6bnPH6S&YyN^B6@%t_+Q7iU&^E!ubx-0+W>V5205!{n z6oTRPvs(;vh8Rt%4DlyEQ3jPSVAzs06gN@z#w3zVl zh17QS_;*@-AbXxpl1jGFn|sIZ z-A=#1f~ox)spx^won?2pr!_X}K<+C0TmW9r@+W}xsukX0=0yh+<@=e8>EoYGIKa{Ym2t?15RxnQh+WD*U)ub>GB%r<&6lfDb)I>XteqVLyis( z5PB^ly_-ULhERXsm9SW;FgInwBkUXobV6>j*>T5?9f$PvV!qlp?*cS?Qht0jxGvtN zmL?~&zFu+zOCMi(Hdj z#QJl&mV8(!8k(9WF1Oa;QVoMlaXkh@_hfQc;e1($?SyTa)eqUv0&Cq1w}^^zgQX6t zwX*+Hu^l@~Q! zdH{jmYNVC+1rsaIc0peE)unkXa*Jn5@?`zk+_*|(TAIU@5b3KMY6v#$5!e>tM>(ah zABr9YrhtYpDkDEVR8vC^pRdyC1PKY9#g|Zti@a}f>+D!t1c(^q;F82{@Brcq3f7~v za(-_|wgwT`?RjDMx^xtJtKThcCyL+WLWTNJH1HvQ8K^b*NtY*-wGWs~t`{#}kQJ}7 zF$FHCU;3jak#{P9Qq~?KgV?Ff^RnufsMVL*vB}O_c?Qr1!D%O$#sXTJ}>)k#%qD$GPiF(?~u) zx$jE|DK>MRYwnL3vnOb6Qu}U}Cs{6`D+W}=vAn;EIxr+N?Cwxt7v+gE&A?uz7$s~? zGQ*|6ZYP`$IiQBvlc$K=4gOO>X!PKl$c{Qx^eO3tg)1pMGO{m}QAg&qJIlmjrGl}2 zB4uD%cV}liKqW><$eZtPg7iMzS%r-cr?l_c)pGlT#GPN{Sk&J8Fa|AO7Kr7DeXQu> zUV=9xFK*oYesBgi1Zzw5=@Q%m@M^lA*XGj{|25efUK(~Xd0@AZ)bPs4BY1q|O$TLw zAv`6|KDn?24Ux_z@;Q@MJ}L7yKh1*Hh&n{2iEP=z2D2RJgW3PUAr^PWb)55LV*?)_ zxaL@7>D3xu!}oBPC@dLhy?Y6L`;xMt9u%fY85vUhxTmAL*Q)D!^KXB62W>b^_#SWj zh1CLIzmE@khMV%LljVW%rJp(0`FP6ni3xS^wW z?esZ3)Ox0#BQtE)YvUoKwXT!FjAf20dpbC#FjO)|E1I@OIRxGuS#T%B26*OGG#z44 zCm!4*E-t37l%_tW;M}j3ck$7%cx(^E0;CBV3H~$*Jl4Zz1zF{B zJ^ZxQqOQ@2&d$4ksTYO;#eAq=dX_&eHT5-GE*s&BnviUbtw+PAO9BI?oX?5w(4 z%{hIaz9@&YXYW>L1f1y1h?R4%_mea+hLPI#{`>}P?6x#JqLyak_Wl z7yZMu>ZJaYEX!EzWa%emp9L)@#Db1auHiT!jg&7qsfVbGzJL+*b?rnBA#k>?T)o=D z7beq(%G<5)afD26FxA=l0O`0M@g|pSk#RT;2OqULrK1xFSw@b>)hi;B(cC19t}-qJ z4j#sc!ogqA%fa3(LM}l})W1df`TXP(nf?ML=G1iUg?S`4%gUcPkK-aGJ4-EA?kjh) zhZMQrJuZWwCmW)Uh6MOL)`q619oLzMp%%r$_GXE**2T}oGVE15tI<@)G^VvwwN<9E z@2&kfca>5TczVD(_R`a@TMWt z^`P&Z90HD7)4WITc`PCa2G6N*lAyk>=}yvcfZJgAK~Z7f;pT(-qucuLch{aOjG9Oi zt;(}i(A&-%X-ob%wYqvmZdvsj>z{`s>!sa8sbP#+fEjJwn3gje-Iu?>X24pr|LGB$ zqIUfo!jIK$*`e5=s(*BUIe!7YvQTb+@-Zu^=JoSO?#J3g@TT5o-k=L9fB(Sw&)?k@ zo~vLihcmQ3&HKxxr)#Y4v&mJP$~yPos=VTCmNOCi-Z`!c;i2`(xyE|m4vsHd*fIf0 zNjm_we6GP9w!jKT-s+kXY-Bcaft>PU4O@(Rgc4oM#8f5Q6n5-LYKml3c%v{1#uX_J5zdl5QW`m$=?nVKJTAo!l>GBz9vD>y6=b?>tGa z$Ktzo?b4kXb39fp3vy)Ms<)E*BL_NOpz(>kT|tV~%Xb|HX-7T{waAQvl#C=oiW4 z={OIt|1x-nulk(laJt&%BxQrpwkLG<22+2p$g)Tk+KG0#$HN5Sdthg1!|8etTFWD* zIHAfmx|RN9craVmN<%U^Bg6IJ%Ye0)JoQ~wf+X#8yLT&^dGNRv*|5xLHKvd1Mwbip z-07(=%U2Wzj8wBj-MMNjYb_14XS4_r%@ya?nIS+UB| z!X+D3Pb%2rTW$o%yr}Q}_+ied)@!D*vC-xt<>ByBY+M-DTO&EAqUH>)HV}Ghx)$GS zJxYB^$XWI7Vi{!|v#%(WTUMIi+mcOL`L(f(oiIPxW3fF)lIyzHs%o>5(y_r3H=92^ z)yb3Jt-G+X7;lUZ!~a5Is-2A}g_3d<0lJa*m}Y!y))d_PoSggSy*DPy%PsJIy{Qcz`cM}&6TjnQ&sKOqdwxH z)AF4J9&(lb>E1>Wn-Cx#`%R2dR<<^lky9yZ%nM%f&{cJEl0dk}RanroWS&g)gv)E* z*zTV$xUtgIPkhxqe7M{!#StGRAz=~ut!!*;%uG&m;$C*jFRlOhvHhDwCmGD~3V@!# z5N_gyJM;O)g3}aRl1Hv?g6E@q{Nr)O68$Vq58K5o26yj;XTgI%)*oI|(%hrAR)}xcAo!FPAHx$N@ zQ=w)eGfnlLbWKge$B%TV21sB;Sa?hUGt5yr`u~VC>Yj&&o(UZ~*U`Xgc$yc0Ms>4>Do*N(5$m?0ZI%s5nJWn>yHEL)xi z0|o~1HPi(jJ=k3>vEdAzmAuU^P1b1t|BbIU&4%AIcj&r<6>pCd;@m@uN&ScM1C5-j zuO)m8d)F^%x4-$F&$ z@m;uRziuzZ)e_GgDZBu1Z_kNQwH2S{WpUZx7fba4W zMX$gRn$uiQjrN3So0n*xH(Jx);Dr{fn|CLMc`iD1wxauu~ciS7Pj3^A;Y1_VG~vbj6VvRhhcoP@A+Qf(197=LslfX zgGq*tTr144UcY`#EDWb^-@Xok2}MjSBQZY85(^UtJDH_QI;czqTRC-B@Mi1?mi#k& zfX@dAimpu_<^*ewM8kYdjyz29X2^aZ)|{w3wiCnCftr^|jCMF}zd<0-`HhNOx3XjY zN+N&?GlSyfd||e!kS$d^rPk`@*4&`Y_)JPdLfMwZl>7J7)P@bGu&LjE@VHa>jmLqtZ6cE`FatnC|r}o zBayD#GAefeGdl-Iu5=!(%gl`G%DGY9^c9(!ndP}_w8JUgX?aF_3;w}ggX!rpNl2zk@fFmn?BE8o1tmkx)328* z-oCwDW%}x3gx;c*dM;iv+40JiE17ULSylVnkDQ)jB$^1@{_0QQZzrZGVPclhR%04<(YccHrIi zx>R&^KB+Q_uPl#>YXa1j^V@S6 zzTsC@0xPQ$bq`q1$&j`*dd20s`F1S6ziZ=ke$8Yf7i2B^d>dC;UW;+pL5z4tKb;VJ zCQ26kC{A^LwK-IZlJ|nl^AfXI_eB8Xh8f+rsaw~S#&PSp+v$t^o0L7r)gDbmrC;$i zpz3SZdkdRVq(s09K==^)hkHkQJfktxMIMd-fO-5(_NqJA;nKkAw&~!(b!c?}g`Xuy zPq1-MbnfyD0u~Nc0ZCTDko?m865$k#QSfRwZ+q(%eOnVy?x7li3Cf#WJ2memY@WD9 z;wF5`5H*L1o_~5D#Vq|#LK)tnotcu(O2C$%0|p^4kzFGnix7g_x1rHo3pP{QoLa{* zv?+KgWkbXJwY$aYoIyz>-wel~jPQW{0;FDJhka*z29OZ4#aRuC!vW?wx0t=3u zogg!%V7BQ?%tGJvhHUVz*Fae(0WYrn8>;CXixxf2PZ|nj>u=E0JO8S-=SiQjs!Gn&n35u){0=!bQCqLxiVlH;)ffz(&9f08(+0|~ zlWYM)OnUDgu+mPc77-OCbC^BH>-1yX<8YVgd9+!}s5=TA%!_dscsh~YBbM>%1BURu z6EkN{&V~+s7VJRaL}(3SBSGLMVly^w0hY!agWqB zX))5kx*>;%4*1L!Rgv-utUwBW5KJ6GO9Hm5 z-fjQ!(tIqu8+a4hKi-?$laZYKVrHZy484B&dpVLdY1jL4b6rD&r$n3>SyhsTPHt)v zRiVfey&>&5^<+RQ5OwUA<05A2BA?tR2^DP^fuf5W6s= z(b4I5h{kme2PhV-0Xy9p((Z}$+WWEXd4bDCI%tJgeuORXfB-GOmgqc=E>bPuFVfc1 zN3dk}=ZU$)-TqN=Jy^8Tdoptp@82iL0S+8|WpljYxIv&L=HqsXS3I6>uQfj2iKDx^B(+$}#mn1RXCD)+7Vv{NcgwQwFJ+QFn z*(gm%?2?MCfR1DApHoeZ$@>~s^v%~UG?;u*iQTL2o2W_54t0E;RRx-!jaVk z8LSaV1sJqkMac|k38xWabFO2xeaB3z-^s@pfaSm)$EMb#^Bq?FnQ={_MH8@`lKJIt zcwTOwcXnPA!X@(>@)R&JjSf4%dku;H*A#<2g~>%z{{*fbn?Le>Vj~$<0Y~}iX54z) z2*G_QlM@v|S2eUWnJK3{IY)E%-|l`Jl$C>@4F?037EzxoL!!_DHD{4zP$Rm&DNLjH z;%6ZyG#qp{#8%AU;Als;Ll(>nwA6}MfK4GBy$n4N8#G8TTC#B1)i#PWQIA>v^gXXV z0}GeN7k>v)iyVBagl(p%uWf_vU?70|Fu_&$CvW#`-_CjP;6Xvf&>sh8aBm$9S>3xM zy2=k%;ir97&lsD4+~Bjw%iMmN0e@*Fef`+-FcY~v{F~6R+E~Qep<;L2b*IfT6YoBzx>8pw2zS^jf< z*@k{;&1K;;5_|_)oO&HyjvVppIH)EivLbx4udgkdWC$lkh^r^U*xMd6Zgg0|!E3*t z#873SVe~85g|(jbA&@C!L)|owcuErcQ)$xcIY-l=(cU~v3Wy48oyXb-w{qBcR^U83 z4WzC`-z`&Q9Oa_>bL%zHoI}pJSNI+XUH&KJfz>XO)9zoftwWU}Z+}%#!*<1r747^Q zi|#9B_wwiAJ0b!vN#zNz#w5S5?Ng~&u?xb5y2{53kiif}J*#SOg#S=t39=}zbo=oK zjVV}rsR0%hn!!EOuLD*|1H5!Msz{4!d-Umccxk71aL+iV>JF)j%6eNU-bCul$5zW| zgy3E=-f`A2w!P|MKbG>YGt=g$#NWTaDRG?%3QQAyeu^TdVjWI@m>Ac#^hg+-sd0O? zh1cC5Tq0E1GL6_#6I1(0S!aJ2Xb=c0>ow2b+b@8Ie#NR)Y(&Moci%m(D5NHrT4#Ti z=8hKg~_;NL;tGv?1dtUvi_X>6IShidh>4`-fC zt{l+4P=Lx}(~cdB>E7B`u#uu*TA+xjt#q#JX?|;kndOj^xksR3+pU}bu|@&&*s#?{ zo|S=6Z3I~ZScL2Z3UW@+3_ws3PV8^_uhV30uRBp}L$V$bxQZqb=&*Zs#|?jSppHfz zvxIL}pQ}m!B}vM)wiZ=koe99(kO5}|9hQ$cCU35qmgGIgI%=ZSpg{QU-?@C8!YnvL zog>=)L-ckMb8NHITULQP$BotGlruk`;d?MG`Uq98!RgiEn;3$+#F=D&Jq20^<~Rk- zoV<|(1q10yhz%rWWa4cR^BcA?f+XF;3v(A{yvhW4pa)562P(wq4a^ACJmr`jybnEW zV~682d&?=%zf0$WG<$x>;i8!fb-r0vfMNhOwL_3{_2Le5swH zG^hiwq6;#Hp|N1oJZ3ajVM9$3045j1NBnC1bJ%x=d4-ak3V`t)6MrP9Av5gG^42Vm zk#k?UU_t zAR+Z8GwG?RznUCna9#rqlWxQ{se)li*v4qhU_cL;jWfUlQHieYBN^8koT=8^rw|Pn0)&y6a8@RrtZ!=aPOt6g9l&pPcDI0t zHUCm3hTt~U%G4Msk6-2pU-?oqhw)+-3JXD51yYsB`~MF;r1BibtB^=Y-pcUJgpXD4 zJN8i#u-nBFn9zV6`;u70LH|k!vXAC~i5`vUETIMiU+?Iqjq)C=F>w`WG(g58yb8aa zEzHE_Ok!)+*4BC1r)L1XW`RW}nTL{bnZoSoE5YN`Sk!SHQ#w@ie$5Y@kAzs=Tt9i3 z+70Ays}1tw%JBmZQz+-_rM#rye2SLz|G|-H-Z4EL(T`< zmU{-)TUt+gxj4O}{j{lSSPctwi@d$-H*Or1c#^Ya;NO+uJ-D8h!8uLk5dFDCByKt^ zg;LY(+%eV3?<9oAPC#vV*}iNiuuk%Gr86pqh~QUgbLq@^s3gLf+N}9&Cn)lUVvULy z^(jA1nSsB5|Aw3L(aoY@tRgG?5cwkaG0=p$$zf&X>xuJA>VjoIY7+_WoQ$_h@k2Kg6DNd79) zsEkd9u69?xdxxmR{xt)F|9Zj?ki3UNC(vF<_gC}aL2kkPzeWL0f6SDW^Oszqa3GV- zdza37AkqUpA+WY=6|s|~s&4CgwjAbO#ERNZC(W<9v} zh0Ta0UXG<~m&!>FN*9JbR)vYAK!ds*%_xacpa5q1vXm@o@BjB*m&z@aH*HLvF97p} z&o61;OW#Cj6V(AnpD-KWhbUJ8AvnAH!>Yz}0G(YxC}U;4CuY=mN%G63^pia(1@?iI zO-%5{4DSf`1Ir03mJD?x?mv0562JH>XdHAdI0A4iZd&JcdHaVR;3W37YElOq<9z3y zHQo8scT_*6zA?Gz`DI4Vl)?e%^>n=2v~uem8%lhANjN#w#l|MR@;iu%+(>a-<%Jk7 zPU3ykfu(4x5R#rz>wG|KeNFf|y2e<{^ z8QLkiZ;C_Qsjs^{NwuWyUGwWHBgrX_jk@RCYC)L<^_7JnNs>?YHsTYcp3P!~g)Tt{ zMkDii^|)VKG&v;?zlpu0V)P5B=8j#v9Gbr_9Ei`uFrsmH>UE)czrZ3M(x~r%@`eaI z;G%Z*`Ptu6wf}^l80)DnzkNpkYqzB0>^GkCzhD;20Tbt6TB&PDY8d}@t}ja;^T_`? z|T;;aFzUu$;l{ zh;7!=#nysesSUBb+ z69D6un7ihx5_>dsJFaXB%+D61Y}zrS-!{W}Dw&N#i!ZTXi*KZ1tn*mR$(XJ!{=1kT zdb|`32y%Jg(6Sq8mFHi!2#Dz>c!i%`hTzUJ4Ap16n=c!J+fzm{J?S%DY2XqBo$d;B z2z`@3kjVv4oFu_G9!x_O|I{iv2bCas1>pI}9r3JTgx{HeQ#$^|s;lC0@3ckH4Ut2XU)|`jy^Y$E02&^{!`~{_zt{oEw1{Oh$PsDP3)GB*kbCUH(~YON_Ae7U`7;mTqXgNWG9X zPh|3yPK9&u=5;(dDQ>lNsF7H=j~-f&%}HWiTD0~M8yj?Un}QsW^bZ->hTJ|s7-KH@vuA!HSE zMU7;2p?kB4@l$)>BJiCH1dq`_BfbU$5|@6$9MTeh1t6U6gjp=Od~oedtIgC=Qwy$+2=Vvl`ciQT1Uq`^#KR}zl5S$H z5e6@1UD)wadKsuNyGx=&do$aYU#|%xbU(=~*}zWRWx2oj(9^PKXRRpo2gDvWyT`5q zw!|1A$7-k9p_|IbZO9HyzV1+MgE(Qy^2jQNaht;On#kw4uZurEu$E5PWeLr=JvC7z zKC-u$uzV>z=ewg(te}h7F?dm4i10P((IqdVMRJ>|u!@Pk_J6#+c{rBs8b11>qQO*= zNJXPWR1`u9Nu`gXGDjq1<}z1AGUOwXsSL@SdCE{45g9UO$dJq=^R&s#yS6VH1;_kG>hb)M&SUMe&T+A%g>$-Co@@wqqAbxLqQ_m%OAP$`d5|0&m@ zc>44SjCU}eU(3KCR7Iz*qEeeC>h^-D>>odlD=+@uOdRDRq`#_*M^s%FN&*-XcViaObh{aT?0^0^7Bi94S=Tjv0d& zZ={(X5Y*v#tWq3f%Oop1BF`|s&aFzr#fjp?7k6Uk(>pfz-cIB44eA>Zc|(vG-tyH=CnPq z+|M3T63+%lHSS|2+qw1~^VfFE_&STYpvG*)`=8WQ$`4XpE!KOl8e8jI%Of%PnnCCC zWv@c}QR8sN$xD5+$%%=mq7pweKPm!Q#VNy(m6OwjM^TSIxo^OU5e^m8N!(&${#Div z-5(f(f`g62eTOw&fGV*joL6k#=RU((dWQRXAI-wO`+U@rz~kxDr*qjwEP6ZLTo0{o zqZ_MUY~c&YX{QUbn-`fW%nAsE9b>xciEB;Y~u4T9Q3)uuW}o$Q>gMM6aee9Xp15nS;#OBw6#3j|wzl+ro?Ownvh%!*SKm&@ zlmfO(=7Xo&5+vjIip2wu>wr5KuWb5%3C5ixE37r`wmN& zxLX2Qv)5@_^741I=-^WR7WHb@Cy$G@lk$rYG%vK4ENU>D1SW}FcCA3O-g8^ddS)%1 zBveUGDFx3_n*Bg#k0)IGT1Gj#jZ)+{w^7Dj=E~81tHw&|D|{5JmlAR|;a?ADg{eM5E9{0}kP^T*Og9`t<^ zSiQDkR?_XCz}{^Nd`ZJW%mHPm`3ButTp2r$pE6=_>!4Mr7v!h@(4Ev}Y2PAzJDFbS zQj#n+DRpsY;is4$T0I=7vbBESHeSa76&I#bo4d)49xQ9K%Bghz7OMHmz?YR2)!h}< z(^*t=2r-e8$Ve8M6_i`8JO6N$`VU322H3f*cvf|7){Mvf38FMPYu&FN3!?d2f$YJf zG`c5G{klyl`6{%FVl=>se0m*-O|qW$f4F%>xUD@!B;1)RtM7tP(1} zHj5(`XZ%yX=WJ}yN*OO#8AmQHir309d&*HuQSyLc#3spW&T2&myL|jwp8Lj5&y&+l zbOEM@pz>nRf20Vy4ivnp=G4^G2Pn_TqkYY8I*8gIdT)&wQw2umZBnG~+44$!-FWuE zD)LlB22WF{SP%_x`_I&$b(D_*p?pvQ?)P zo7Z%vQ9k)S+E&bcg4)k*?oDu)fyY4^9LMjU_L?Bz0IOIi?!KVlsh0XO&5pq+nviQ5 z3$C$2Vu`!ud)~zcZK8Q?vc6@z`{kFaQsi7-bEW2^yZl0qY43I)`?`Mv*+c^`{A;2q zLT4F-qpeRcu+n$-?XHfGF3R3pb9};@;(som(FD`uhS@d28Wn8Rq|NN$9{eQIp)Q5BtP+w5o z*}lzelwi7<<1y5moxv?={go^1%=LfhUcJ3GTdh)VP1)|wvDSdqhLe&eHD%9Px>lup zPeaeyo_9;^!)=zYYh1nzougD7{z9J4>*9MgKp)pw`3!{JxOVgWUHIC|RMqLAS@R!O zH!GfZPh`9fQm#;@C^M{XSAG@lonv+D-S7RcM1YDR-AvJGqXZT`t@DE$$ZH%Vl)hK; zRdHjRP`sqfv(z+e-Ky&hycT)zS%Y6%IOKcElRB47r5#V-Hf%3==21XD!!4hpGN)hY=Vy9CP^dN!c@r{#B%$GUs+XnmoOX1!ftq ztLnSz)@nDBmi>(N(#P@H-^T_CP?Vm!s~JCDi|4I5-d9=^Z9s`cthK7Ad62a;E{L+k z={Cf$l6J;^_#khxU=S|RmrXeIa)dMFs3q@zBQiROU%c4eo#F4#Y*=l0uKlsd;ltZS zL{wS1phvmSX#Ihy?OFm5eUOS=Pb7~W69VVMc!*adT*6){9V=wy!yzm~q9Y&{@FN%A zk)y|(q`>#koh6jA+ul8ro=6M;B0P?WV7&K6xB8^hD&4T4jG9P#9xFqYa(aYo`mr?b z=lPTznx+&jwKZ*PV$ebf7lu0CO)8&}d9ryZBaOrukmF@OFG~PP7qH30l>pQAo+-=6 z-iHIS+|~NJy1+EmBVV(H#9=_s{#xrhpaXngGuRU^)4$vDuIqWSE4O^AGPCJe@hU)0 znU_-PO7ltN$`Uh=d&%FsOnG@s23JNiLK-KnuHWCl%y@X!JsR+?cFiJgQ3`ynym48B zH!t#DsG@+HPNB&TM4G&TT2@o#X2r1k@>_f zs|zJ7#+t6pmUysiRo_L8f(_LB)RZ@F|B6R9*6T@Vk)J1V!7}R?4`pp!kb&{=qfc$8 z`S>XdF{h0Vx{Xd=kJ_J1y`F;O8!(VJ;EcrGsfRR_S7#ZX2dZ#po&7}QrM$FsbcOHh z>gtgFKRP=iZTvZSo^4#kFz#76Slu!5dHfY>7$+`_6nE3?gF& zPxj30EYI%UABLjFTVpEW0aWKpN=v{8GFGvA5u5IoSk@$ z>b9O6^!nT#D&r;e0qtbB`{r6&V>m)Fb8Tuyhse$~bgH>$%8#8Fn| z^W+huT>@0tDS7{AmpyJP0m!h?>*ZQL14g%~Q1|GXcD>y5+#X*8A|6s2UWRd#zZ+Uc z-e1C-tcVdSo)yc*Ov>kP{dnr- zRj;eg!A+|h{GaCygUiXW+rQsM+eV=g{Or@ipQ|>rD(~ToTQR0j$=I=x(kZ>a$wui( z?=Bgy6Ual!lC@Fu4&$TD&l>)Ftz6XmY@{5av`sC$x_B7uC+9v(=ErRa9 z)Mthg2fdVaC>0maQ8!@$^-`TXr`Wu%GxoIC-vxdA9jIkvUr|v}x@EUKru}|9v6(es zvn%tn)b4b=I2M@@jr1MBJegXlyi_yXB9WD`lknid^89aj=-G|agoz*b0D{3?2FR{3 z8tUi`R17Wzds0t!$+yEX=$3)zaqFY%Ms zH3Ng^&TGm>(10}#{TKGe+c#HW^W;Lmz2n-fv29w2};K4qgJ#C7{5^MOk>a^YF&fw94cbTNmXErc|Eh z+9~SKczX7fuiz$`vC(yS!vVf%Uw~~voxoNIMZp=qZEU=BFWKwm5tVW}ieIR^%XXX# z18Ntkm)GI9Ya6gKyX)Q>?R5+N8>@Q;kS6L1acoQ{$S6oAH&6O_o}E^Du8hy}yVLi$ zN!v;BxR0$8N_k@TaW#+La0nNEZ;cz3=}PF|;->z8j;6AjTCm=2bkPwBqI@$;KwNCl z^jE14qxkC{EE*D9&(n3beH1)uOg-C5)YJG)fiH|^XV`y2e}*z7iWL=Wp+z`|p+sqx z^0L=FTvz^sj9!CBcDsW`OzVTcdqQHoUYrI8QsNXPdHB|`GYqWz;+$fs7lCZ*Pw*t5 zdhVB$NMn$p7c`0~7kD{Y+*!IQ3v1oU)3VhZnZT>+SN(|$<6sZvgIocU%%6;`$ zvs-v%-GhEV&;BUF2CZjaUY_|l#yJobLi645(5R?w0G8VYwAIuA#!~Wgux2M1o_l?( zukS>29H)V-F~`Ac46tMPDiDb#I6!8M2cwtZzI@!q#wK?LDg7a@f8!I( zAJ40l*HM1beX{<_<4L(ye&Qop7fu%HIdK#g@EQ2(VlRSCf>U4duS)wWxcw&HWBP1| zvgZFhvy5UWeW%}lOJjUvph__9E%wqUOh><~({H(lUvE@OyEAPMt@B@;Of6hSyW_JKtKCk?KDq+fB%Mr zKPX$79g4O_Mn4?3=_luUkd5 zo^VpYfP<6h4!Yl*Sl!XF4N`ETLPy8-Gd%R*povp)b~YQ(S0emO)h>eMb`4`@b{nn@ z*1swvXsP*J?ESY%`+*N(%(V7_cMo_?9&vF_EP_LkwzBRGV2LU!RK_;7Bqb$(t330ABR&!F;tc)&?JQP2XEcJO;#U$B_Ect*&H;N zAuKZ2;2;h!Xk=i)wTRXz?Z(NeDS0H)#K^&@h8OadPH>S%=H_<)O zG_ka_gdx7f-wOoKO_+HgZxh=uo$|{@oET*hgHU+ErtJXkMFiN0v=|!m0FizOUC?kK zx2w*aux-4u4!Vqf%QkRa(43NeSgZ||qk~o>&I@RnkNEBBrp*UI=&gbz)8mcqD-9R; zf(kDU4-HGQ8M%%=z=A<^1j5`B8rN%vhAjd|cr&E=dVyizrbw;myzY52nQm;W{jMEGO>vYc%L~=R#s$ybGfo;;cl#8D0Hs2j}nJy#^?}Azd*E}odPNg;K zV?&6VNnmwBhDsCptUIZ`!bA1JFOsP>Y8HFkkK-{&9RMS9X%*iO(O1J zAk7podeNJ-6OUj5H2fYC&T$O2Bi%nt&3sTb=))OXb4P{{{ ziYMB|TC#>=h%#0*>dZ{a9`o;c&#epeG*)_pspBdv!%hR!#e{+%)X$v? zY@$f~f0FdwiY$8l`kzaeJm=;dpgGwtE!~lNmdvbHaAZG`ST9l(PL1Ybm3!i8m2^6JvW2gV{$&dU zTrjif@^@W`x!}KL*91u2yD&Y%N9I@?2_XlfPIZlCDJ%C+_J_R7!)#$ zdtFWEBagko3~<=i_<#5yzk;4#pVX_Eg=(qYjSxocKrnuo^X8@#Ps75LK@uVK5vR(8 zgw^0+7#JDfLp#B?WA50oV`H#<;X1JY(IBxLgyI}N26%zYz{iOZ3!0-K%lEb=P&LX0 z1cQ$}`M3a%-5R5ySpbd2vglPIK?WvIvJhC|I`N+D`w~Xp5KiL|raX9d0kt9gFX z%&aNB#bz%+NnSbT=RJQB5f()0A=JZP_3gct@R^9qQSt0gE>FAa?G>~0^ZM{QLNt+& zieSgVMOA+XVxNimhY!brvZF~s$ol8mb=#y~H`;P>aaqC#aOa*qnZLSdvD!YPpK&o3 zrD~wV7h(z0osp7~!c_h!8O_4?iCGjzOnI9a{e;yGnF|UH*XElYz1$uoBhJX(vD@Dk z=F3e<%7S)qi*f^mg_tqblmm074Mao%e={Gstg5bGNJ1kr+Tw!NkD%js2%b+^}xDE}__p`FHv>(nQ?36*CO(ylonZg0! zsQpN|memFsT?nqcyBu--LfII@v3hQ1Tp!1V_t2pY@Xip)2}BIqPvR|r^C1B*EEj?7* z=$jn0*6zb}EIr7@ydSb*^0543NyyK=ssK)gD*zHk+8w)dvTcVjGu>Bxo-VggR z;uolYOh||YgS6m2nSDJ`EkK2^l(34FhsQ_M;1NjG(U18^MGv3n!wi%(LU5YfxN&3C zA+2xOV0A$;9ku@HBWG=bW)VFod=<`~eTSpsGmaryME0+A=}#(nc3d#Na-pfSjIo7? zRa};6kVLE85%%mb0Z95u3q8?X)Eu-Xy9RyiTIRHXy*Obs;9CKv3<@U;|5-x=gCCIg ztGuozuL?>BI}@IPbtCOX4>3RKVX=_tkt5x3nU^;);YZ(&sgEbZIZ!S0P4(khx>tUEO#O22b7^-MGP5yfkM5?mnq{ znwD=@ZEfuscCOq*14JdzXJG4qPf?$?4Zn|JM@^1#7Zh-e@a`A=(A|h-E8kgQd)B5dfQU}St zVJW13aia+4g{Pax*qbgMPm3cAHYD)uY;qE(`O@Kl^ZuneGcz+Xil!a!UHVPmAjA*a z$Z4D^wCP`uKIt3ZwuFNKYs$5V;$?@E9}4#DI=Zjg?}SP7hm=M*86fnd%p!jK;A@&P zEp#Vb1wo?LA?Ju_YreyMc-F-U+vIzZW3GmB(0*&Q4QRf;Rg*ZSi*IfFIlKk^J6N)M zC1!l~_sDfq3i3i=^@w%j*Q=Teb@MVsbx8YaWvRu*mbe3Mz59mOB6z^dw}1Nj3OqTP zq73!mKYWKWzC9H&F%|TFs-CXrq2X$0V~ft)!zi_HTu`pBho8|H93m3}H%^9mdeWmc zyJ6I1FOuIT*qEZ2yIAgH+KcK0a^$w3(MEf=ZQDkGAMgJBm&-@>kX!Qd8UbBu{z zh|XB23*c)_dgNi6NEnyvLDgxKIlsS;QK?<5{<4=50-pNJMGsJMPksmAb!N<;@9(wtmxB21H)VN5dNc~ zu@(nw#i~_$l_A2=P2jxEV?vwoN9C zs|Y=2IrrxVQH|xbA$KBXUzwY_QG*D z_}|4lOz0H{WN7SbJj`x*>!6V1UMQ?Nck)UDVQe zG%hk2Sx~GU(Qk2~@jG(sD;q)lsFd%ZMAD2sOS5$pUQt@N_~redL!@VnbiWZlkjCh} zl<)c0^rNpQn7|r+k*XHU%w}b0UlozMxZVQy3GuS?mtM-lH-24e{!O|fm6ZdU`{K`q zH4Kk#ys-yG=B*7;LF+NK9Q|J^X>!WXoa@JMvE7{bc`maWitu1={=L_P$(5Nj`FA|;!v}}mi(8cWaNcOD%Itu zCtm%_l;@q>u&}XsG|O@SP3)S=jjpXIGepW|xkjAK`!%rVP@Z0RH)NSwxHSgt>WRaJ zsU5bi?&j8IzeNUJ{x}rr?R*uaVp-?buxhU3T=X4z#oLUfnv^4R>0#OX;_m(YX}CI$ z-~PW^fY(r#s&zPJyOzwF7X!9wGauspD9o|037#zwSQ(6q0=*!up_MturzR)mG&RGY z^8KqwN_xoT+PfyPd5JAFgk0v;wtgx*hQZKM{eth&2X{zcKzd9Dj}BQQO+xjZr`{jH zh)_6=_5xC!vRh1y{WysZp{5~ggbr_|qt_&;8hT|w_**H#Hy(QhS339SIZmg_H@~c? zu1?b!#K4u@E5x$RdselzrKRAD*{PAMxO&E>rbGoB>+3ITWeq)Kp+%wN9g_V%JasTr zC=tb?2RtYC>e2N}nmj`yb6-ykNwkqp>zzHVZ!!>X^DJYekN8OV!&Z5py1?V0pg+wGAGH{GUg^DGBR7Or zV)knK)2U_1sNs>U_6{3$d)&pzqsT_v)Gtiu3W+1Vcj@a@LX&~mdxf{<<%-|IQkD5A zn4w$?k#;TSHLUQEb%bPExpLY7+S}Jc=VV9Z6t6Jq?sD77CAy8@J*2*43vpPCj5ME^ zLK11%t##^cpgweyr0G%A!gX>$HPbTkd|z!t12Mz@Q>4cXNT$+{>F4bRZMeLs#uOC} z^oxAYKFK7eWN2vUztZH)pFc;Qrd_iAyZf)rt#-+0kueH>unJNC6)bY)h5*Bv3&*$N zg%NvnxgnH2iJKmVe}kZn&8!US-R&a^EZFSMQGBvukh-N z*x07Sif&$-fk7FninCgjlB}x}F8-X0&<@XKJ1Z&qH6K0DWZaEJd2w#b1r-&&oEQQ} zyVmkPHn?`J>F`|g1%3UPW~C!8E-nmf)(o6Cu0KEJaQ>&sWr@WirBZ8S9V)KABa~g< zlU4!xz*7_B<8P3JZ1i}5VqLS?=}K90J>XeVl7%$nr)lQvUEtbt=`e_}{W`^(tn=tU zg{(0}S^nAq1m_S5`&7#-iVsjPYG}R6l5OODkuOm=Uu(<7E>DG9(1|-XHYW7Jy!|!t zG-b@>%@%-#CxXin!Q8AYT~s4VmSuiQ@nxtK@OypJfeJb;W~XS0JoxnZG~Y5?sU78u znrTDYTdeFa`@s=F1DPv1UD4k*{KV9Hernidv`kY2LHoe_bMmnQjuF@0(zFD!v$Foo z&z)9PecbG)dMvF4GUgM2a!aNFnVL@(uI=McrD`yG6s}Y1!}c?K*%fTvx|Lj8dbRUF zYRJ@PA&zyNh7GP*$|iVH;(ov8gU$g`G}H?5e_RbyR`Ses&hr8L4jl?iVQKq{9rMaO z;x}gxV2t4ghi_Q|B9t(BicQ=7P1!B3tFRasve;Y}W`tqd`RuA%Yz{>E-ObmdRNoOi zs_vM>6hUXm+@-wl*wDBmLWUb3tP~m;f;GnK5_a+w>Q&8pR zR4|BNN9Q~Xz@E3&)zuvQ`}PsD1d&SbA)@idQWfgC{~*<|ctO(OCjB~njq)sAX5Hhj z1s%Kl`yasYgs(*#wV*B%bn}|p@RoBxhf%WJ<+X!l0_LO{2L;q-7*q&duiDa`5wt$a zd1^DvJFs4|J?mnF;%O@BA6y({**em-puwo$}@4qD;WN4vP?R!MfwZZKZENny2^S040jk>Z*S17L#Ep z3i_QMyt)~ooM@LsTGrlhN4)+)AZ)WImFZZFQ~PfP{LBbL?FdG1T0?CK%y;2E((5 z#k&dzN0l2{V}pMcd^x`4jI&b;OBYsdZZjW|BS-WRyp;}lKbo_^XahLt$8^0QAkG#z zj6F%&a=j*64yM9)c&E@kwSC8qlQBMCpPCi;z=-{%J-R~Ia9dIu-Oca8-2f}6i~e2d zP|%NhFmS?7;*ok^X8fpdjuX?a$>w?6!QS4u@}iHr7r1)L(rLBb97^*x7I-Upbs(6y=LRqGP^AAH`ulLe2mSsw?k zDc?H2S#*yv%BhvWjrOZg!>WW1h~Ds1|AthZ5o;5tvELj!Q_HZP1&}ohc?N(PA2Izn{`A?h&}cDZeeEj-gBFa7Xoo1_mdzp z`yxEtGAG;^_keyEt-gMUoZFvXe6|d}b2XCfLF>$C^aMTan>{=J~P~kzF$#;1DP3ZGO4rH~L&w$CzaW_w{X?&qo zuOeEmD)RQn5jR^uYIGcswvI`~1vB=;bK8`o-t9~1GIzsTfNJB=M{z^eVxO7sr`v!r zyD)YAQf1UUQkg>kH6!(ynPDcIctf~-{fh}B+JUz00Y!HfVol3}yx0fD4b_&M&`Fg( z^@kw{!_d4AWgnw_*X826%3euSanukmfxcEiR7uM6vOPnwL6a11%9y9N+62v*>4EC$ z99Ip|9edtShzX4yD?AXXF1&2NyQ56&wt(v%Jp{c=6 z@V*Q$uD6N)z;sVqUfM*FK@&_9mpEMZxl za_fyW044(LK?f@yri$+Ku5*E9ej@+$PdXrc?vvMm_s9-DzSG&ao%gGP^xyl=)6-K! zq&$64vkamr6@eqy_qdl9*bWkQL%&j2NEgUlp6y^T`II;dW99s5dt2oDe*WyjB(*HZ zLX$J3FAs#rz5YcV*zLYUKtyEr()11bJuTzqMA=3=Hu(F`8b%dD99!MkLS&QbN9js! znjULp)oJD3`5?A>IB+=ez?#@$@oquGnp6bVgBeW5tV!xvBTn)#sHjig2vEH8b|y7_=l& z{NSy8Fo0$aPFsMFPnIPsoFnc^@O)ykru6mp5)=o}S&dMp9U({oAivz}tzGQ2*^_x& zgAhNjl`4@8veW#U`;lq#oTx^;=1PgmNh~}lgSC_|@KFWk@b16thWE#>2Z)VyPaZB; z;EqVy3!5KfvUM4m#nW4NlWwUJ|d7!31OF)r0icg_CP+r$rSEkm(yj$vd;r> zP>PaDnM=oI%(m(7+O=y7vs*6Wf+om4E>s`kdvDx`xgEL+?ZjRj8V3hRoFjpjbLxWu zBQXIF}t1sTgRjXb=GE= zcTFMgdDE0(3Yo_QBpVj~KIvG5&c*4DQx`4-CVuqx@fotyKdX}xqOY${s3hsS1p>XITrwL`1$yFO@Hz0w^jMj|=g@yto zbFZQ-k=Lx|$)UYP+v%v@SGNtD3;X`)9|uV!WIXQ2F}4ec%y{P;y7;F%v>5I{1*Q-3 z@q-gedY@T#Ha5nYYB~U@Z_rYWYJ})ihKJ1-W`WH`KYMn3aO0QSej6~2a!^MItKpO& zyfbE6X#?^iEj_3piAn^NHBJxeaN@v*i7IxV`l0|1>mq3bJ$N4}BM} z(PuVf=LDRRbjM+*VU)lLprq*J^!Zp_QBh|)z)RJUouPJAd9cVRY|3{yiUdAcyGWhY z#LP?%gCj_apENy1(lNaXT1r*n#+SQ*$CLRjB6XRCuyxrh-%2w) z;cXXjvSB^+448G1r=E~t2)@PZ!2{v>@cvEA6imh`YMu(h^)LhUZusA*7{Ui4O;dfx z$;Fj!_=PiR+7^wU~IA4O1%9maNYlVZ!>W@Xm-o>f5(6=wzOmn_|7&TuB!5{A?QF@@H^iEh;neRL=O2{2gEuSOT5k<+g7Vsa1ivkCC#mS;6 z5Qmbjjwi1W)Hjhh;IFkwY1lso6pq7WqP-o}+k5a~Xy@`kQ9!&o0J(YFV&Y4;RH59u zodhsBXs`x96GO5X-fIqMkxCT$5R&p}S=9_q-kR-w!p0qWHU(=8j~~+ReN~8K=-+!1 zn?Y^B|IY`IK4AOlyvU&Sh?GYyyW9ufXW;Zp#bR%k?&iT$gHR z?fC@-t8N8miy`|$;ZX)~RCO>U4!Rr&1mGt`)*E1tWNK?|?Oi}XT_Do!@|&}dP%o-r zKg!IYAGG2xXl_1u(20Ok;LM6bZ798|e$)B$eY1f>!^3R?qOjQrTQc)o(v7*Fs^dko zcO*DVzLEKN6}JA{t_d-)znPZyc}@Bwn#hfIKzugfoX}?1SPxMM3rKIIpS~;DbReHd!f* ze-87j5RJX?Ja+;=&k7{2LU8OSCIDd6m_8{vf;;+%i&;P&ZWJ}dosRTsqDQ2vDsT^N2c7=SPz>VRkZNrlrE@fdtUuH*C0piw&5)IsPiQlu< zV@wge4=-n>K6$bU(b$d9t0Xr)nRbY=(gF&}p8ZO6MwG9!5A1en#tID>$#|LD-$pRI z5yY5~FsRiBT-k0uC!S8V(c0{b$x(PS0xyJBhetFermnw|T@G2_7@`R*D{80QKktV+ z@comse7g|Y&_pG7?~A>y?~`8 z6Dw~GB*gnf=_7TAc!w970poDXLR9xe_;>7>W)02VN@7N7X!v5>mY6$1!hrl@74!nh z=|*DkLIzj8T|nU6<8B8>$8I=I2#>&`ga*pkH$=4yEFOm!1G$LTD}{L4Lj2N+Ly@?p z1AQNsh;{g#oYiKK&Y;zZOu{4Cx(oxPK(GJQp1C!ck~^gK$r$25TmttQxeT8yGH=A; z!&NMg(OaNhK<2IDSwa3XL?R>r9iQ(=0bAJ(+071+@Tw9n;7EXg`j~}OR8-(zy@$5l zu7vo=gYD0{Mo0b0Kuj_XQ9~ol_~R%eRRzD9&me}S>u^ioCb^Hxt|?mbq}N$(@{FdA z>&y;x`w#Cy(Rgv&cx^&Xj#{>BSU!7lRcc0t3gG))*1Wc6t&V`73v=iB2>w)3!~N5g zkDvcSR>Uy#8Npgx$wu6TSpytcbs5lg&}i%X7XUufIv55sdewovw_iP z{B|1Kc{Akujt!#SMQHv=*2MfLWWqpUAi-mvnVHdTE3gGiodTD8C z{j0qg2#~UBbFQmh8p;Cn3Sy6s<8IG_py9goe5jt3wF-73E~!m7fp(flg-W;vLniYc zgO2VX*P)c+$5{?G2&hVZ#G9;c`ke6BfFhvl(B_o(nWHLF?3Zd7>6M<}~y578CXZ@|khWG`#qDk@+w( zW7s!X`Mc%7qnC*bQV>J*0+Y|Zd{O3M+}DF)jroLFJ!-n*6^#j`pucY2G)QeKx1>)tM1Uq zRxn#Xkm=e<|3m;hY^K$_KUv`Hl&4bsg{;Bys;ZoXM=ChF#C{PKH%V!rSU_#|4;u2( z!wCHUWk|LOG%5{4i%m$>#l)JUhoRj_GA>NGBR?!^TC^IvHw*x>6vK!zM5__YMI7{V zg7q6%^Aq6I2n;GFsdQZuMMVAs3x_`KW&>=Vz9oqy&#mfNG9(4u77Th2yYaVV?K zCN+RRx$C_{=Pq?i0qi-B}AIV`dv}T_IYoQm!!L<8SWLHDNThTZDak_FSbW};~kVIi-;p-^> zkH?yWWMBZyW#aCaCto2IE%u+ zC#TiC+eBxclSR=0FE0w=JS%Y#M4B)}M0b~h=8oCIdh;M|T8HV8bHGEy;QEQQ;9^qC zX!+8gcxi)z94J|?A)|Kc+7Lx~nV4 zdRYS=YcwTGlWB(*b;#T)NW8+M-rndey)(?tq58v+mGwqeKtfa@%}0^M9o$#MtqmZ= zuuYgh;G0_`&&5`GT?~&eTFw6WLz7{c*_w=E4T(G``5xdtC-z4e0$Yw0wDI#ZqaCpw z{yLbG79EoqXMKjgq%rx*1yPNQ0BxW2R$ZpvWHzp637Na1PoKt+66G0Z?uSnRTt~wH=4E7pxqYqMnt$ zMC(jYVf6~b7itlgjazM1!*4W1UNNuDAq7+@4H+qbBD6&ry_j7ik-#Y0 z?_du8meg`);USCm*Q=&pWZ1Y~O1?~H zIB+$E`Nc!cw$l36K&Dw^J=%`$R;D?;Hm_^$0&Aa^w}^`HGw_k$72v0BljgU3j9TI~ zK#TS2PEmk^f=(T?^unvQim>?Bs3R8Ih0X_Fh{?;z#_r&tagvRjUz}g#cx8aOq2tA|k$o(uD1Kt#gtq#AQ%iEtA z&_&s^(jY%}@Jf+`2nhx;g-{ijvTK;WL1dh$fJOLOI>!smOcFz-AX-CpT&9|@lhwao z#(1RXWsG0>f%D-<({+oL`#Aw5eptOH{E<#17I@!8vm;WXm|LL z)BtNq)q4rN@ey|FQb)5fl>}bO-^f`xI@P4#-%%p{PYKO+N%WqVibXs_BE_kq0tG5KTldccG0Pvs@c)VfF*D zB%bXBgxlD=xSPq?@C(N|dU;3CC<8884ah4WYPUMP{y@QOG%T#?S3PIRc8T+1y&H2{ zjQJ_>{Vu~kZXM9KTZt*wd~+=cm)u5E3rF_tJ;PYPt4?ZqSFqQ+v0sv^+ZqkZAl z;JN8psv1#Nwx&4$LyZ-FB!<&{q_sc%^1$DB8_|OFsKrLn4+%}qXG>;@p;vd;7l3=e zhVD(XS~baVaHq4+I&iz^!zA(GmphkJaA}K& z>$HY;A3(O8&x>NZrIaeEdDF^uZWzryUVq{Ix85ep?Rz66)s-9y{r<_hjZr>k4rZ+b z&c8$S{YWR=Y%k!e67x6Tt5Q?6&x={Wax-kpbkGH*t5`&uwL>c zqp~{AF*bpu)E6Xl?wR=;e`C$T^)n8?Csy~00)56;Kx%g>9rOMWi=hX5B6XpVvo-66 zTX)ry5q?9w$Iy~L(j$4@M|&Qf{9S=(*F~pI%834@^a{bkn+PzQDht&||NR8nXvKAI zHnNfVgjzm867mt$qo&Zdv2#b--a!UA&>#;@H+~+cEIl#@Km2YLxHkX-t z^v~CmVn0Llf0K2s8B7S2z#@~>WTJvuYGykqVVT0LA`CFG#36r$s7v?5))_kA3DmY2 zuOKj2_ec$mv)*T()U|!6oHDz79!xI2Vzq`a@gm%+oNu=GdX#f8fZ*Wfm~=n!fxS%9 z3u6nvclaMuX{>ChGDp1WLOK-(ZTRuMNe&SC*?U>NP?1K^Fu+K`*>zP|Lu*v-Ij8M@ zqOat)^mRs`7r7=657uZkBmAya)IA>}^n8R)HP)FM6MVPWHQ~U5PYeMXT%gsWjc{@l z!!VoS73jvYu?YTxp$NT&Svo!ksh8Pi_~Sb4s@Ow&Kr|WmDfy~>F@-3vBsp2X@ZB9q zT+h<{s6}87EG(a9#M!`lFUI@h%)32OZU${8cT46}xXKA$~aRF++NMVsrYe%j$*dBC4j z#C!FI-C1W^4L{t7kNAKnw$gpNx7DJgsI7cDIGSWeHXI|xZ!164Xv$B^c5d<=44_6^ zudK%iP+@gS5(3*cM&OVjELdn&q`WA?Bd4@1W%78%7Ow!APg z@unPlK`ZQr#_VL{7Bm30^yI0ulWP$Y^JbteG^8^j51!AnV`a>($zSj$GZBwypP$VP zee4|7glGNz=C*xf(Z4lV;p%v)$%F;R-?*u?8gJi;Tja*86j0-HF_F zQ$7@Lt^4=3sC#a)QaEwrGoZ-{oHx-|r?@NJXz21Vy{*4Fa}Nc#SQnQ2RM<+nIALVW zWqpwMIf?!R@RK)EFnAduCoD(8pgd@yI?TL)uhqQJta;damjn$N79+~oV#fyb`p2QD z*|So6=diWMVR0^+cd3>WN3|OYgX#ldwo}^_dBZkGA@grWtaKAP{sY%S7u09wPp0^l zsd4|Qjc%62P16KMYG=A^>;&1uN9Tt!Cr;F$e7DB%Mjc(Wi{&-7%Xk5V6nE!EZFipoM4DW7JP?_YfXZIAhS_GaG&&Y_P~M|y0`EfIM8RzMrlmcm#LVYBHbe-cT?Mzo76;tJJiDyG$}_qoB~T0hb=;X zng{^3kkWMMkDKk~GS9n%ZJaX@qEd+JE*xlVCdO^iy}C87ms&KX9xSNUlGy!pbH~zD z?%$w@EAwKF8FdSTY>f3Jfk)Z*!64BiAE$jY4O~zftG+=92aagYxU6Tuk_$J}!U)KAl`TDSKTrRwv_I*OmzPYxhtYGVtiBl4@Na&L7# z*pu^#MFOJRgTwQ<*{zXb ztp|^}J$1#s8JV|EHTC0b(-PFiXi7z(7m zfobrQ+slBX^LniNy9*qf8^@3ctBs4~1DVLWJPpp=;8$-!oWOF2qD~#g5k_BmKkg_8 ztRcy`q^SHw(yL7D4q5#>j}v+~oH5%=z3O=XT{`HBAom)BpimrTsm(bQH zKs2zp3PoJ<(QUs_Cz45Fz%|yvj(Kmv7idfJ&_Z}7xaaXyKygmm>)(o>2X{rBntKYo zDg9e-FxTnLs6}dj1=Q}6tUAj%G@y1O;hXfhC32mO}nVChqd30WRf@-SlIjJMs_r1Z9d;IS|vqTIC7!ZF1BtB}kx?koB{O>m8rd`RrkEt{wFM%_lgg!GpGB=TV2>nJ^ z-eeRGX1Av>c3_x?QDVNd@bAWfC%^5AM?Oo&lUQbT9_Cwcpm z1E#pCR8)cd5Ec7Q5y9(269h_CH^>z0~0U zKYyYX`ICc zx14@AKXz5LHtteT-HOGsO% zIav>zegB`|)Bn9wSpx*mlQ{W5U;l3}_y6(!Z7po*$wQS3XD*eVOHlp48hg)pxSQy0 z9IHp7MG(D(s2i(Bjf6z+T`UQ!N4G>-f=HAQef1DT7pt$bk!Z2Fl@RQzLA2GvVwL~q zzJJf}d0zhK1+Vt|nK^Uj%yq7F&5TqVq4fIp=zA2b+yc9egVp$R^pmPRsc9d>*44Ri zq(pV%=l+8Sd+|=|sJsciy^gA% ztX#sWRvBOXPiHs8|2hZb`*$w@i_8_PT9zF@<9jZZCn&uTVfYEoWK zkEckLOoJDW?lw6JH>$*T&xI##5>cG?(k{aHe`DG>T;?o6^Z&5~@!N9ce;4%s(*i>N zM&bXbJ;^HnOF|N3WbSo39f>+mv&WA&ok^ zI35xnng5Li<5vGaX0IZ>mbm}3Izu|6xJ;_bkc7C3^%j6CeHiCY?w{n@6lkI{^KuPW z>tO3}ttT(yS|n?f5+>ZF@A(nQ@sk>xH5{nw_mI(|or6@7TK#LF_eL7( z2&XDFGZGnIj0O8aM`tbk@>C-IBR{CCIh1_t+(7A~l5kzcInQsotuXZLHYzPa&lrLw zkAj8nKCm15JPin$OVRli2&WMbT++(k8 zGIZi>aOZ3&F!1~+@+l2|*{EmhvoJ8rM{0fzH~M4tiq;F3=(D?yhT>z{kLOf2o{!vy z!i2s?*pkkbTGRyLElo%J@k?{Ku1^ELa#WOM7Q;UHRif=EUNet4!yG_43-VyWj;^W# zsu^@U<9x{te!D6FDb+mX9kLcDMSAwxdk(;1JmwNb;y_FMPu!$zmlTvpI!&wQ{qZf* zjXVpiBvMGiEG?mTn!-I8cI!Vs`hq~ldVo&FS_KG1taf&nV2;i_*6c8!0vx@gXwOIvr- z?BVIU@wO;Uma~WljiZKXM*td9td19&jCd>XXjl$I_K@ENH(Ah-54uj1umi8&y@9bM z{`wK2JL@Gbdh!erCB$C43y!R*QlN^CLV^mS2Rg3L_z7L2;$H=>^g%vAj|F zsB4wVmQ;-MtfEh=sG_`5!Zhe&1~+5N&U$3w2{ z1_2KQZy%wzZ5FvT9DoTcQCY*=2=cLX;L z-UARjQktZ-7yUw4I#)~@QO6)ng6J{`qT-fAh=E=t!}B#;ub_kVr@%!akdpY;KIk^1 z1W$&On8l{)7l3M1@c!M~vUTTE=^K70s5Ah7I1=V2qjiK}U1)pK1fqygyA$Ca@^lM%g zGBlpa`T&+N{l^9cQc#R(B#dl}HRR=8zOM+g#dGn+W50gG*%RqK*v%`Ba}@{i4*~A? z76$wzhPPc%UZ_6J0((vBTB(F7??=?}tf9k`?lq*Cnqr)-opRY3&zfQ9gu1N-qG|Khy{+=(jR3Uv=FPN|JxfQ#rt!X~hW zyyUF4Nyl571C`?6(UhcD95wbj1Cv`TxM<9UD|GkTHuZTPFw1F{*b9?mu;w7^Z&9)kx#+dY(M>gCSj-!`OFXh}}Na>foptwNP9rlJI%3?UIvE_dw5v@~Z0@ zr1w>98)1#Uk#746&R~YcV3U3DUt%IBUEJ8|2zpF*5~A=G>4l?;PV-?e^I6XN{Rd zjY;?Nx=TBuk(S_eB%$%vjoR52>Wlw^yPWwIe)y<|um&!^n4;=3-7JCxDK7=)uc26C z#@pLGn%Mbtl`p!KBY{+InviDty9k{U1y$OE8RW zljr%!g%#Xx=FD_zf7qfCwEHgfhRKE97Vb(A{b2Uy4wAk%JcGgWyR~k1^nn;obq0GF z6$Sq2(?;3gg?$943c7#8or}1}PtL8^9g<5ldBkqEji!187w17K>jFh+153XFh zEP3rp>e>lHxXV^#ozA<3U$`{Pg;I>ijM*=%BZe$n33de#;(BCqR`AQLk9L7~y{sX! z_^uEspL(QWvb+x-)<(#RQX-nPvukCm^%W4j1I1ogL&0gB1OX`Qeh66d)}Pv6Fp&=7 zTY&y{0uSb5_%}Wqhf}-L5j6hbG%1Sbree_AR;~yO8#adFla!F;Th&>tnrM6JUjQeQ z2={V;Aj`N{FJH4Vy0QJ6CrnA~l6}Qqe5IZ1b!LUiBW|s7r+I!nG^w&6acK*kX}gaN z7w6+mBRXxB%&wcZ_S6DQt4b;euQ0%YU!{sMf!FNc*rR|ZgU-iys!N^!@oRau-js;I zT+I7%v=U$dwRnp{Cy2z_9a+SL2wK?|z`22wGIL#Vw}CLi}MO=%8 z>k7?cjO&p$B*?X+2F^tmCT*jF!CsktNUEZliT2{VVH8oU2U#R8&XAFbvBSsdZsj%W zh3Bk3?~zh<^-s^c+H{%rBvLwX%j%2e*iKJH2=t04o<2n~wU(TO7B`LEjGM z!O-|DSX<{-c@mjLc_v;4QKS3E8CdV-ZXOmsA#~3zk%SfYmLz=v^lo-9V$AQe-*6V0ZCPd(N%yFq542EM1ed8J8jZ+00Jtp-LLk;!_A#+DWjwY?tq&z%wyx7?&u`dUz_GsIi=auH{(+ifsd zKV0v6deuP3{p3_O)?fNY8BiTuodh=DS5hCE9^~8D-V|gAeM0=gvh>%|)=-H$Y;{AX zt%~x|;UUVEmWna`yGY`6a-~1~$DKu}xhHrd+#l3q*Xg$UU4ZooStG2b@u?q-F3F#&J|BsNybfOXwc2jXq>*)LWP~7!se*@k-=JSLI9qo@B{lGkX$orDiZSu;uEp zb?;2L1ewbqZ$bcrcbGKKCUZrg65JYQN#WydOWvP?G zienO77elaAlPK}(p>Jq8@@DOtmkZb|vyg1XrbhjXQIC7xf-_}sp)dWKW1C#M=X5O6 zSe@WBqhpzJ@MlF90q6C?VF!p9epI(%bKKb~->9d;W?v;mwPlX+d&-)4wRB1Wb74yW zNAD}ICXCco@&JW6;K{|&$ zC$#V-Voz|18HzGV3~NYR=*7Ip-J2+@ z*BBc1{k~Id+f4MKJ|+42hfdutBDI1C&i_o@47~B3B6%~UK(}dZ)4_IG-=Xj}USj>h zVp_#&NmQK4&<1KILA#6}^+>~d5kqyZ5L&PDy?TlejwqNWI_~K7VVCZxVTZtQ)Nmdn z%F=Y`F#x75Q4Uy0NEJ85ghxm#K&F4SJw#W#xWD`PRph+mzVuc{+h5FV!X(qqppXk( z4@q{qph9^JuH1+6fDd>}lf6*BF{9iB0D+N`uT~bZfx0%hq78)=|B9kb4&h6=R^73R zgO(L=(AlM)OU|VUUS-elYiPbxic-6k8>&k4F)Rc43A9cMt*ewyg71)W=GrvfI(gVO zDh3H6_W>@QZyU0iZ9?P{*8Kk@BGqj4!P0+@%xJ|{F)2+wCQO)iV3T_@av}HSrBTk6 zJtx~vR{}g-py@mZxvoYfIK7`fd68>?=#utSfTy}?EJ>P5-h#Cb5 zlXjYJu`-t}opvI-ZGL47ld&?7JbeLtkOm*7yhExsc+qLEsYXS{O6o!eaJ@W#4X@#) zD=PqC$T2qCf$+~s-lPO3)h*A5!Pn*CGqy30BI9Vfp%N@P4SyWH7eBck>EgI8@2485 zM;Q}?MuoY`tD;^{-J__n;E(>Y{$yl}xS`=~0SztN$EHWSX>Zg>%7&`?N{BT80m*Kg zjV`OF&y~FRxbvUZ9b)8<`~^l1$8XPlYCaFJ5L*8rgTSHqD%KCc-`WVbL7|CjMVq`J zjzwG>FZldJBWOfz#$visWfyr5rIRzn$KwXcqEL>hhikS`x zM1`6Tm6I%pecp{26j;ASOZ5cD#YNDux$Ly!g=?*MQ%`$b@aO)ybIt`P*dBl($InH{ zYiRHf+oeWH57C~Xiv_>&0~<8knaU$F2oCD$8vCfW(Q(dnd(!hU^b}RZwXlkBs^O{Y zlF|rW%*Ae-FnYT@#-DXdiw)Jr?2`k(=)-n{EBqnNiasE|B2OW?xk%ur%jYqndww87 z$o&D^4@s9O=NN|b|>|zt)Z4*I2^x66RL+dtO$%0$pzw*A zvd1RM!1f#u3$W$0xsoVC@g$#ls#^Ep!6~azTAj3w{WvzsyQaPQnPBt34VIOp(SEO3@OdKvE zyzTn1=QWK5G5zVZW{EvZknJe;%EWhzPKR8x5b$m&Cq#lP`ClsCq^foDA0#fqFoPOub)pg7=~8J{=g~P(I)osOpdP?*{`?RariP+=g_}% zYnpelR(|5|FiFj`wp-*gd2W*v{YN ze<$3`9E;728uN{uIM>{Hk1|Y?>U{mNIaJyFnKf|&8jx{4CZ!CQyZL(53g-z%7ErcW z=QDYd7Y485#S*xFqTlg5kpv|a*gT-Vt*l8s!l`!xQ{hs^-VFYUKK93NSVu5|klAZR zzukKl7!3iV09%q!vafEE^t60zA-V9KUEIcZ*%ngEl=MZRup0^t!FP1Q)awB&lLt(T zIR5Z?s^G}A@3$3s7{6z#YM*eNIP^q*`4hASfWl{%aF+pn5wbl2IaKvt2A@b$K|D{W zrorycws=!zk^2cg-TK1mHY(Yf=A|P5RbHo2$Y&a#>%)bLkg>4Q&W8i9RNrS>qrftV zxQWujt>1<+L@5fRG_;W4%zGxz=gK>6c0RJ3u?wjvW8ISOQ>Uugsv64F(1w3AdzJ)O zNuh&Cq>#Jv6ge9OQ1C@62ycMBdm=|liX%wRXVCVN87y89EOp()$>Df+qR(CaPportBea{(3Eu5QLBZm zvEoV*cb&IDsKcKJ8Z@1GB{X2Uvbx=8Jz4c3xXS`~r`{o^`QdOiD_>F0Woi?`?%%-u z6>ac=Xar@SGNe>|Gxm*9?SYaE)ipdx1dW}|ub)~c-Ksa@FUeZPFF7;Q)h@2Zmb%E3 zUGn%?yau~4q=<4TD5nv`A%JQK;oTkW34n3-sKtzR)9oMjMC;G$!4v7Uj z{>XD(8%oW(JL$GhS&lk|_quNu>~as@i_cixVZdD2EZPiYnMX(;{ZW99rj}a0hvyq) zN2~4xE~fLde`(XhDv8j!hL52mEIkSQ5f2ZcoYQ3Bq_w^d){|0r{^L)sY3~quh9+li z@8o!$K5CqJ20Gqs?D&eVC3zu)=E<2zUgO<&>hTa(VOyGa>Q*By)UDZlNUgB|{wP)W zVO8Z+xX0rP8@wWz@=|q4g;!p^SlCCjV%qr^zlmwRU<94r5^gA=(U)xLA_ez%>(1>v)jL>syhBki=G(!_PHwe)boS39RCs%0FR9)2VX)B+|A`_A6G(r z)mQazmleXzIf5_AV@n#=wRpN#P=j5Ato%RTJl^V>*KRl-Uq1A49jnoK(uI1nn;*6( z0tZ7PHrwn6sfd!epQ$~5A1S;TzUP*$4{dlukf!+$Kh=`kG!^hB{xhO@pQi7IZcPG$ zMjKb|TVW1BdooB2RjZnG*EUxu0Nb!SK= zyt<>zK~@J8Pwqbt(0GfF3$XB!>KQmx*sEdkBf>xPCuCV_2^Lprd$E_r!J$xa0s1c6 z?qR9ZKPKCrv{g#gq>{dPo|_zbn>e0!0tITcqm8Vnm8TimaOWLrhjbceLJ>!%Q;|po0=A2cHg}6u#CoIrJ4$m=W$|L0) z=6c$8eucRZ?tN9P%|TBJPPUjn=Q4a-^xITKWY+n=#J=ez;0df~PLVysI%$;D)HIo= zsaS2Ic-0$%y$2U4(_bU4U@ig9NhX}w8N_EUkg4iP;O~UJsqBM28rqlrO}DHHtNVT- zRa~!U$}ACGFOAXjV1!&JLz&Qj>^Q#sKlcj3i}o0<1L z7}@j_lQNUbd?LnZ@_&EbP}UeM&$CChR4QxrdSs9T7Yu4_3i)Ta&6`a(j#T)M4z*(F zG6EvICXXa6Bo*^J_uG-sK0L9s^{p_7< zNMW%p#lAW|^)SB-qrFu0igZx9)ch{v&2T0PP2|o0;_;oqCyQ#DRUp_WeXa1mFT~(E zR;u=Rs8CyasG&7w%_N`e$0?-QE0egrvq^wzX;rh41RERsZf_xQfRkH^m4#*4_50Ck zkA|p(N|0hYxFv;wkcaQ3ZG1V(bFK48Z7P%WX-c3I@%if~Ur*YscVVD8juWR$FWbA4 zac3)&qXyaQmDvhD$AKDd+z_uerf=%pMgL+QY_H!FZ$o^A3NY_&;u>w^ifa8Hd}3a;i$#Q z10shdVKc%qc0dEk6#9yjZGhP)uCv&w&GQb{axm7Yg1&xU8L#hc&`d6Nb`ZXip2=J| z%7<#tlRYaOJ265GUO-5$r%<@Zcn<)%q z6EeOf^_qW?dn5lu70|6IqI5yG)tHdp6^Bv{druo|Q{fZRD2p=74RHf2{ zU*t@IPo%x^#D1LpKW$0P{*}o2*JEB#!ca;2fvv`r)rf8S<#Go<6c%Yz3o7UE(Jxhx zgzso&8izV$1!x2GBMq&AroDkYdcNV9Bg^g}hWOJk>r6V4<*yxtc95-2RT2W{heD!+H1 z4~`R3SwzsBm}kVjjo!D$wa~l4m#hq?LThF1M_RG3ZsV)iJcICepge21hiUzcgNvi_ zscx_7C>diCCjyV0}=!AEHAPAwEqAu;#V>{ST%`QcHAvp ztCB$sqqm``>EiO*%CG0?`vapTku;^!#9|*q&+qPMqe`*XdR$+GBm0Lv3C|4gz~32~ zviZDbidqn4ILdWB%8DZBP^1rgf_n!32{`2}KRc-B8iW~J`ME$B;U+?vsiA}yHY1J) zN>CVbK$1i)F_WI6z~I%>-r1kD!ReXck@Lo%9irM5v#lRz`lDQQlTe0hHQ}^BTOJi| zea8|@`RT#!<3(>;^InXgM=T&eunXm@TR66!3x@6>QXm3AoX6i6CdK*mZXv`BDpAth zM0C(8;bWs*y|& zj3e1;?G2WbdI zP(`MhR^dtQbOk75d(G&2u4G*Vs;O}3{+&Q$ozUS;lSBIrlr7Og{7P_UE!;Y=0XqrgQA~V`Wdgl&t0vX z#i1P|zguFM25rlycF6SZA+%#iInro$&Etfx)+n3q`&^${Bfk`LyfN`dgzzwGI&B(n z8e?KhV8FFSyIMkf0bAb34oGPO56|88)wcVwk;Y2X@jr3IUhPaYmO(#8c-o`i8B10?y> z(+haKnHNuf8Kb|VieXz?~!|bK1#tMZqgJ>eaMuNi`+;aEUBqmrPg@;qI#Ta*n~YcUmCcH(@i_o z;3)+T%ttfiC9Z$eK_(i>bv$#J#H#7w-j2nfB1RxY(x4=--0hUYL2+OCsbU6Mi6Mi| zSZ}oC{naBPIqp^;EJ6ep;P&U?Fc8y6I9beI}SSb{Y zVfnFQr_l;KE6s#{JXbNtDQat%Z7QT1Ep0xJiE39ec6v8njR|jnhZh2`Yb&3GQZFHI zq(QyGJ|* zY2Du??vKaB&4{xX%99lGosSh1gw_dAXyry4GB$i`u%ZYX!Cqmp(`K_jv0y>FZeR01 zZnBQGL#FW=K|7wQ4JCzl&JBd3lQk2mUbhhr*=K{ZjOI^YR*IPh$oqUkj(-2Ak5dEH zF_|Uv`Of0wM)7MHivo(}wnybc&Oy35-<^lwT0l3Yt8kanOExNLzFFodORS1yvTa2^ zd(1Rc_Ca403LN9-VeMx4g$M&{es$Sn6K~E!O04C@5!-rOGq#$7=bn*x_rY^e~`H+tYN;Tf} zAK~wTn@wiTP8D+VbfF=g!fR;l|e@g0OFNDy5t_)~Ax zxCyaaP9vv9@y19fW38=0g<_?aY4DBt@4@GJQh?mD%%LuD8)4F^cI8@XKjY02TZ($l zR=`OTay=rBwKyVE;%F7;AC;Eoe|0x!p>QHRJj-XallokM9cY~3f0r|O z27ZaCZiq+NBqCKK(!0Br)3eOft_=)9-hv%?oLqfZ{+`7$Qe9x7Y7-j$!bJc!1X*T0;iAKsq& z70SFp_AlePQH%-a<4ZB$x?}+@>TKhI+H0=THbKHYc1+$Rh@lKJ3EvKLv#i1Fd8qhO z@-F808eh!f5{ITvwI_=N>-EHTLa_}YZM#qiQU9ySA0HPPhxTOFa6@~!aaX7)DS~DF z@q|bMZz7qHUH2s_UB^0H=$$-$_H_KE@>qQMI>4ODB9&fA4K0yt4R#p)Wi^5Ate8?Q zoekz5Sh%L`5MkMain7Mp>ub4H$l=I|EM^i-X&`~ItHVY;__}yf^HqukX3qRiRavBm zsEE~2mvpdXK|w+_#S3yGDLG7Cw-piNIZuJg`!)L!Z>@2CS`;o8 zAoFXX5GvTAW~lqBye89(A-LxC1%zR3?5}us>MfO?7q||9BoH9S+{4j7+L=|8%?QwM zL_|JW)O73zij5irY3pA(KtdTB7XA9ND%X~Ae+Bv~CRJ2M7Yo^dlGPCHjHKgR^!1+J z`xnYZzb!JZCuVYlj|S>Mni(BQ{61H2o}w10e>^K=P*q~3bGpv+pfW8iF5sGvu1PbV zZP9fR*aKDGN10Ghh$P7)I;AaI&&rVC44X@Njiz#p`u%TWDylI3BwodSM zZ3p3D#xDyrA|IBluFuvh)nt-4*_Q%25c6Ku6lKE6ffh{SRiYk<*K*PnICte^>Dd$e z_h&wMJPo`?mMW^sb%+KmlQAs!*9Zo}H%_*V0;*;^4IEjLNzHiJl7_P7{u~w~)tn&+ zH{7%&q`90}#t|=M-SP8^eb{9{+*Q7bB4vR#FD4al|11jf-(+FiF~ZvkAF~iyszUNw zGTeyO-7?6a`W{sp)gbR;Nfb<&TzZ12_5#@1EY)`>zbbAeS6(5q0f z2#O6}nf_0Ii`z7iAUIq?TP4COq>haBV}!k~$aR5#rX%PZ?+=Nw1NMr-iNl00dW`jw)zb~mUjMM>7K_3m!6BbHqFSIa@2h#k+x3Mo zY6T2-*LADN^&YMZjol5zm(a|V7;5G^!Mz*J+OP{uWk7906a1*6A$Oegzx?ZIuYv<& za%Ew-+VZbLlB6drNAYtFMq zCT|!|4Y_|}B_W|Y*M9WCOm@&r38__e1=?!UBb(%a{Cpt~QsO%r2%v8#B*c(j-yoDG z!+R(0IH#W5XBjDs?pUDe+!YG~#Q)W7Ke5~wtQTy;u(o2*-wn7NAYUUH$2MV;ZQlQl zU}s66R*lu`M%d^0i{yk%p5)9Gx=Ik*v%H#09>Gilf9fXXg6*zpB~%%!1<50@k^Uw6 zbwfU_C!Aa_AXF|p3Gf}NJcgQxyIYs+o>`xHa^I7`;poL$nkc|7UZU`o%4quH)t3cB zfrFVh4Tf7OgG;|P_j2kqD|)EWBY-8= zK=MA2px5x7yhI;L_=m5-OTiDt z#W_f|^OrN-ZP+WiFmA={#iK<+-Gn&mh*XI>sOT zk6*n;Ud3k$1QQE5#EapE(4O3TlEB+1G_eA=EJ+Ie@bt4EkpIn)*Af(UK6!AA@?w8= z?TUso+vWv7o#3!Pz6q6Fe9`3qS&)J{{N+xkNxqs?O`AML)z@G(9N9;_P1&3VQzdeU zi7IhLTmGWly7m0aDr#fQbO8#LYBtpJ)xwoRnvL7IQa2!7Gx2hya;~eFiY-Rj@Sn_V zZV>!L;Y0jW4G^N^E@muk=>CHiRmSN{&}M>rCf1ys0H}rTsqv@;rXdY$ zPp&mFLt)Ip{7s@N@>}kUWuotn1os>o&*o5S!_~bmCZM_7t@)W>G9P2Y^*X{cmdCpQ zQMo$9ovsj866Q#K>MvV(4^OCT5`pCjnXRvbr{N+yNJ;vJT<**nB#4pkQ@8VG#g9h1 zP2IrdqJ!PEjkodAh-maS&El43!Mylg%cn#MB#Ya6DCF1$B$o5V6EX*%*^S!OGE5Tx z(c<1pc#66h+vI`dUzy!6Xz+jWm+uac!*$(0iHBcsp4{+ZEFD5tQxuTm$S!~5eBbi@ zXOofNw;dFG)ZMY9C_PYU?w+D6Up=T^N@9H}m-@UBz2E&%WH(20j1aPT2$ACoru|L9 zsWD)cbdj)a?Xa@}>9KqBnUEH#FMG+X!1Tmrvw$|w9pWD;OjD>$PZ}iNa79~LXo$!j zLvd=T%dCT9m`YoiE5&Naj)gG-q2#gV>@C$6MZH z6Aw-|XU=oeHy+g!t~um?+*RSc(s@)(KD!}le=c3hcGN+7>z0@d$FQ|@eCv5<2>4k5 zY04x!tk-K`)n7MLg8=T$U1fZoLwHXYWQh3%BW4?e-_wV!A(|p z+R4yS%$D-L^+Gi9R_1$^7p&>_Jo>lFUy2%W6@7k|d!?Jot@+KMf!E5z_}-@Cg9tT5 z-1bw#5awA&(Hj22IQGp?3Qkcj7eOF`O{MKxHJ5AR3khv0foJmd-D|5;Z>*#$IA=Vs zj~KTT2PXGR`=#*4>yJU&!b1630mGWc#EZW`AdX7G@QlXmR+>!;le;MUBJJ^L+I}^| zW5G_lqx6A-WP}iQ!)pch;e==3WMg$26&t}_7j5??xRxH7FR*L;xX#u>EqUvg=vW+! z+!dW?YGY}#|M{ZS@zeA_G*%k76x1v*J3{p~<0GWUZcVQ~mY^Vhy&>N7WJ5w;>3>KS zv}$8&rAHkd?!x*ukL4C5i%NfAzyI^bfs4%1)PVD)iCK;>7hP{uW>=#U#<2M1Pqe^t&8I&FKh?xk=0zqB#QD7NfWoE`YIddIJHo7FF4@2++z zWdJGGKT$w!bXfMe@?H!sG~`iBT^&MGD!qfA zuq8x|>b{`YCy-$ZFoeq7T zS^Mn$8iK$7xrPJ( zrdsyXg8y8xdxm^{4gR=a)Axh_ziut9W`~8v_5kzGCFc}TNBAOzy@aa$D=R~Lr+2mn zSWZq(Y$ldwc6#ru4cM$~jbb;2D6z2aVj;!FUOUIFPq;W!{c~A9+49D6^1p(#CPlJp zB4l(6RbvfgwHw8Y^%`ww`TR)*k)&yIc5ZI5OXG(ot_ovec6KLmZmtR^g>vf+4(kl^ zG>pX$WFySmB3MmR%)h8V%$~)u!F~Gm3i9if$Nz}lN@892PA0JZyt}n0l`SgM{ z-`45m6eo(MOGCw~*DlYB`0U==we5^>g zhh@Qtk}z$^;7ogT-P^l@f^NtyyNZc;PHyfL2R=InBndx1zpQP7k)fe3XS6jRHB(qv zn7S_)ds$f-R?E|vwgp{#``2@Ri;P@cq)9zd##fft*XKWxYj+Ezx};}j>TgX}tlY5GWkz6PxmTL7B=w}v6~+?f~2$G-@W$! zrr!NBJowAAK>zti*WfQ445$qF`rU@8|LqsB8ryDcZ7u1XFX-@jou59d?s&g@dv9778}=yv>zX=sa3fa4bF5t=H&e2OXum= zVW?+q{k5S%yxowCo}NBDGSZAjTbz}Z^$9okyOJ>qDyj#sP#}Dr;jgr+}FU6Sy*Q4!vqLr1EI?EF5w>+_GuoScx+QT6J>qMXo} znBVV`d5_#h2j2d2xPnWy-P3 zu%M@>N6f;4H6Rb#-+#+;!Pnc17vg;TZRq$3htct!p_oB1tLz6BBY;S~TQr zn$tZ}bo7FP8cEk4tZi&86b)(D&sevkJv}^x2L=YHg`B_MW>z-7HM2hHJV!uDMRn=I z<*}$JT}ab&9UVIPv@jKImrsJ5rO!*2BHqH=srLU1FtN2TGfOHe`ZhSIe0*}EchnoO zxKT2tOu9B%=Bcv4fwn!`HNYHVOUuOu zf6{TUi!*pLt9Nw#wpVh7WE~xO#!9T3bn_nb^CO=>$A;rFUTX6pNh-v4ds-~3{>^t0 z4|TarjbihkrKM2|ZIN@L@N zucxOjn#%|pQRVsZn)}Jv)L=&=Ihx)1V%t}A+L}-L#f$l1!Ogqu>>;J4e3{D3Y4YE7 zot>jFZDGrONf3cR7}MaLRxG{*5(U?IHN>+qYFaXquT?6%kAEZo%j0p7P%XQYz+uBL?5U zzZ~y8>;IKR2Z_AyOGLNWn1SVGjypHp*EFVdk9HSU?Ia{5=I7_PTbXknKYsiac8Q9|y!-L!%Sbk@KZXUDwu7wP zu>%?tMO0qCd@3e(iM<+q|M~Ohn$_;n8)GGAw@t;NQ(wqLC5uLN8PW~%-P<{)~yZY5LI+Q z`45nqIywDIY`8544FF&UD^sJy^6wtb2Oo>E;!EcwKf0DQ`q7Cyu2ridEX>UKV@}0- zO@vtbYJ-gg3*TZr$e{_z?aNepTmI%178W*b5gz9N&>GG+!1rc5%$xliM1?iKwB(CW zmQYipFflRl_Bg z9k9{V)NH7xT43L) zlPIl{5!^yTnaU(&dg8O1=EJ!@&}SuC)0t1oe*Ab!?tgoFy6!`Be&C3CaA^?dWfk@l z^_^O5qUi(Ir1%Hn7qV52gy+N^7(mAIS`$R2rZQk@*?Yab;>LUg$07FFunE)ohv{|Gl(5AyfM+g0y_~6jf(^J1L0wN+i zD3iZ`|N4c549SV+-RI@yowa-L;DKhTwb*y%*P5D@exV&fE&4Is@3hNoC8{32D!=_P zR^0ZxFSM%==$Mz!KQJk+sG4D*OF84s_v*Vy68KimW~$mpyW@S6Y|XMi)6+lHdoj>` zaSq**OdIe9S`i;LVUbP&tUop`p)s|ZJ$ub5r-z3}U|=BDx#g!Wk4?LA$1w|dy_%F1 z?pE~)n`4Dm7NIH&8Lh{@;zY<6VDQ3lp5CxIj{}~HtE)hW$nh`BC2}du9f_c)v1>)Q za}yJv&H3$1A%^&KN6ae$oC=GIF6FxYv)n9Oq76#=l37sjO4#ImO=eOW8S)8yx@kJm zY0CF6U+{{oq^!(&G@89{eWZ7{1( z?$ce$$TkTT6_w_HGP1G`Za%a~6&3QP5IPmy*p1=54<}nSbV$^b;1^!vwn4hOy6;ID zmihm{m>3Xpz~2!=6W5pIi7pHrg6^=otr|yoMX#GE0NOivr(R37T8)>6R%}&kkYfuRyr8SU?6BCM{_1p*x8@yS zE6_rKuj|#P3+(Lv4V0bm8EVDm6w~auZ1fq*SxT~_GHTjg`2__78AmBMb7te+Ht&gu zXltDrGXY{MkvFKCHaWPvSB@6x7pXswIPVXGRrdsFpS3M(Zf%{_m^voIC8WOT??5Qt z<`6?9dirwX*A%P@U~2is7WTy>9?OzgZnMFUg~zFFt*yHH`X7UX2`9qOC@CqIx3(CW znVDx3X{NV`%#DqI6cpGIC&i{`Wf1^1%Qt9C3=V!R#Lj(1rL>c8rM3HNP+_Ek%?A>%Ix>3 zsFzZ*pZi8f@r>zmo~iu+p2l0rZ0IFzGNYP$Aw*b(B zv-B017?k*b#Hs%}(5Ro!eX+cByX(J*0rS}1wZ-)9mM})9M~`Ac_hVyX`p5iM40M=z z%!g}__LlhF4q40wGo$m+($JiNZ7P)vjJ+mXm{mj}fWHT+m2@>XcMoX&*nbMB_Tj?^ z?~6ww&e;YCAPX^!L+k72j_bp9K;3?2XQ!s5d;%Cnp-}JpR_1|4ny#$-;L>(?3<#rD zd_Yal|EswW-q_eU-A@xu0lWaMCn+UmVr8Xr!64|g8Ru}2`3WTZ$-k{7Of`cfN;q3L zg3b6E8d`@&^8qYrtyfl7YVtanFg<+uwl7sqv)tYvjv7?TLlzbUKYujX3D9r*KM~Nn zF5jC7SJ|rA5{Ze8rJ$o*BCkPT1$C%zV1Qvr)$g`TY!4hod#c?2De35RZEruWfn{c5 zV^hwMJUcrx&EN*GotIa3{dqdolAoDfMk|;6r8#ZnJ;P91f~V^}9g$RM!2ryAkGhr( z8pbD_rT|}+wygNiK3|6Fd#$W2Sy}NZ0(xjuJ&|ZTG@v$UwSiRCjP&$2Lt0KNh9VPR zZZkWt=QTO6WtD*G0iBR_-X*N1fyQaP4p8CAm&cV|o`(e>*A%t1I%;cc0|oPd^1f74 zOFz2$A{V3urga6=3d;aUb#!z*;pNTfl0`MZXJQz=y#u?-b_mY-s!C03o?er&mDLh# z3ztm8?c2A<-L|UA%c8Cq+b*>JGRss*OA9!ZZf$F8X>GmF%xtDOsZgki4P;kAXy@bL zJ9icv8=Lisib%Owo_9s+Hhk2;95YHP9zA;0+o8KY^ZNDcm+I;=8X8n^Ms5%hg+)Y2 zDl3zH`t+%sYF$xD>Cf*s8303|wWsX`kaBX3x_K{OzWmWf3QIOyeX^+s;0po^+qb^1 zq2UUw9)L3*KE8uW%oVR*uhsN4V>7dQ!vYRIK52J%A+mr^02o^A)S=PQEko6Z+ya7v zD_dJe*48(Zdi)x7@3FHhIGttI?JGI>r|juida9n^Xyrp^`ILiN81((?%fnQ6t1NmJ4I85&^u1L-PRot=EviHL;sl z?io`06shCxTz_%r68LI{P20F_c6z$M*ZGpypg^F@2uM-r%1bIW$G2%{ zXy6@;8XFtoYI{dV%jXY|K;0u16qa~vj^vtyN)Ff<8GQjhtdU!L7}o(@D$Hf|_rI>* z{=^Q@SO!1xnSiRfz5Tz|M9!|=4>xihp@P+!AgW+tk@dN!edQ9Z-1+u@!I?C9S|jL3x6z2KsrND(?KmY051c5O1@A< zW^XYAR^_^*AlN1NM?4&iZJfXX!K?#ame2A4N#gJCudlBUHps6@X*C5<3qZXM+}-0q z=)Yhf1^k8H7#bg+?cl8FB1BtWQ9(gN)41WN_xKJlo%>*+LBG$ckF8rf0Dt8Jn5XXU z)JPP352MGy^SF;h4c_~_U|R;X#mL+|5ELIMLF9`U2u4P!s=8v@gTq5kkk-)4MG`_l zCn_l^HFtFlEnMj4`uJP|)C8yme+(c*T3((3T%)j-WC!PhRdCOMK)~gH-2xZ*%aZfmMr$AOmOaS+yvrYtZu(6BFPn zhJF3|L-FHJ@F7gh&EstHZOSxn+_=#_Fd*UL!q3FSL@9Ac+s#c-OH1osQ}gifooNN_ zk&%(`Z{JLAYpVju11m<84U~nHlvLi>hP{*1D`n->HheU!6BuO_l$3Z!=flHMlx{XQ zd2H;ox4(b?4n=txlo)WQJ2!9uEy0HXp9ieeW;nP{g6$o_?9c^0n4Fv};ZhUDFf=)- z4FCweHYFniKcS1fEmG%JRaKR#ZbxS)tY`vYMx{18PiznJby0wblE(vp%syva~Dp;~_emLZs`;E%$tCWBU(;GY^AXNK$p>H)cXrAjphxlz0xa38 zZ&_GafZ==(Ny4n0d6$)y000yyD=glN7caVdd!Lz_J_5R;?kiZ|-TgI2m5YmuiJAFT zmy>o*BrL+gFmx>pVzgP;qYR=qH!Z=+CqENu=8((wC8WVK*W)eg23V|NFTv;Wq@!{FMZev0r% zI8R|;rPpBdZWoL|MQ0IdN;ZV?{$efo1W8cp#g2V6(+523R(t=O+}mcb9dHT=;Gq@b zW?HLTTa+RUif;TOudlE7_Nw{3CfL@|@rE5IeCm~~OeGxbcN#L#un-Ikmyi9(PZy92 zS4da9l=vkpwQ~#^lUBk#XuukCY=5exgo?2~aMhGW-EvH5YHG?@x>H5X*vDi8p0~uh zyb>F2)8D__u2lhKW19Piho-J9O@#}tCmSWcLdw~bkzb}i2x06KM`$Cf(|B1|n{KAR zA&4{1{OU91W=oAV;Oh*?owlOHN-ij0&-3f(~k9EHHWJg>;5_;J{&H>p! zkX`rV$G_=muyZhn55H1Uy6;G{!tJmotH>4>kz>>4^IgxO~`Ps=p6PP5g z-@IWRJy~;$nz$bj5|WmjdRA%b`NG>R`4OzWBvh7yTvnR49*wJN~yyND6w41D&Z^i-C75y?lAoK|E{n zut>M@%WbG&mX_h$U{GK3b7iyVqxQZSPb?9!3TwHQe?ji1Uo4$1h6)QaqEUTYGKK-N z?#62pV4m6Z=PThN!}?k>z(-!v`|b%d5uqXGU7-z1_z9Xboq_3Yyps9C5Y*Gi0N3!1IZn1?#L4hlJ|F~ z(G@SIS2=x{p#^Y4J$HA_4Lccm`BabvLw0w@Mn`kUHtu;S9UUE&Q{H+q0cQ%47S+dt435Iv+o1DxpF7Ghp z!uU{cbTYL4<|#k1wAnj20O1}`MuMTTx%fpMV`js20t{xL*?KS-vR(Kx%GtAb{WXOJ zxYT!OXi`8pfh!FYiHEGL16n9KSy{b_atG%sZ43g!z{|8~)?PrZ!ZFJ-%v@2C7#ace zURY09IgB|Dem)?qy-VQ3SI=N)p>Ko61bY(NZhk(eR*5z=LAb`}5eCoz!CAOLNC=(k zIW&OgCl7>C1{B~-Kp*V?(yPRmV2nfzT?3{89)OYtD0ikz?J9NNGvl5s3HrNxdlb;_ zv$KPt>Gt;a+K)6PMNMv1={DlQ#A4to{l4QnfZUs$Uz1=o2d;{wq$DV)m$*+?d0Mbmg`T z(3<^^%a<|Q)6^7?Lb%d&;5WS@M>pzx?IR^D0?aGHyLlY_0+2forULY#s`b!WO=~*$ zd&4K`85n-sJ^oh5?3$Wcf+zbx`%|N?BI&ALLu(8ae^6Au1egtw3jX` zXJ}+3wN43Ea+C3sSvXU)w1X4s{lLvYpb{i>Nr6dgU|>)#LcR(k=spmgb9+a*sx0NK zD_5z2F`5>k;N!TWt06}&ts+Jnl^d@ri)*aNx+=r)k+kQ$a{>8MnCJnJQ5bB zftJ(Xe+ys-24_6;kA|1_dPYaTjBQAw5L)3Kw;00w!31&0HkOfT4IF%HWtDTRkbO|8 zi$sBQh+(SG3ZXCzK;xh0 z=4(Jm0E64__>otlC1BK@EfWD21z7YjUWe~-b&|q1uFkT#Rx$^-EhtG{b#ib>Z?b<9 z%WFmU!1n|69Pwx>%JC^uIYYzL#TIThwqQ8Q-NVDpz&0=gXv2bNKr04DMjL_ere>OD z29fdL&|oa^u?^spp92GL0DbR|2x%js{*tbABe<-ye*?wZSms05)%D#|4}hW3mCE;dV^u@~wOOBQx`b6Ozf9 zuyE4yOYUnHV_RYCX)JJNRhvuv(t-ZC$gK{xA)9scFpKKearp0_uTV~$=0T~rnvxO; zkX4MQbr1XVEil%=ewfI_(&LQ&1+pA`FYxk;97tGrc_V=*ubB1(!z`|-OSP=aDi@8$ z3_Y_lT0bL@nL0J`px2<8Lb-9_XaJGRbv-bh$TGvvwVV(b9UEI&TLX2i|5vLJ_Fc8W zFvzm=K^-jU;skeU3I4|wFhyYK+m+ZMOwKxV*R|sKdk8=zBr0G#z>?vDaW$+P&|Mat zYRyP&hFj2<%}4S-fiH$xtBQ%J7Yu;=;BZH8%Ez@nLqng;%j1Af4h_Y$(p8J^KFBUO zOF)%f1A&zNZt|m58Brt)wl34W#~eb>$QXt~CC0|y_y~6o07EY-suQF|@#7nOwc?Rd zZed{|eTi$oIUXL~!-o%53;*?PQK&?ftc0ycl0XV*oH7IGwyfo5L5sdRs!7_^^mjI? z$rDTgQ<~GW5T5mCfoi@oLw4`~bB4vk6qR9X#)y&Ss>YJrQ*}S{^Oe?A7YzfLV= z!7Q8$5&9S-B0D>}{MJMKpd6hVky();=7mlHQFI*n#(06g;klng$J(+t*QX#V_wL=j zF5!RFpx*9vxm0P#d!4($5j{HpR}(T~KKQV8+w*je4mipiv_Elq?^}D98ukXt8a@39o$1mi~j|xdp4Ag|a$HQ|wnAyoY@sex} zfimqXSMFp)CXkpv8;)i-Lt#f8S65dJ<47e;oZpT2ws7}~%^kRcS{uDD^#Cp;%lb_P zsC^;Y5S*UzQOl9}(TRzm3Cj?4WvM#pm6^TnFF$EhJ z@GIa}5PU*$;&;+UzVP7+`ml_lwUq2^%fSutwKs5)*lH1F&^8*DU>svpW~db+73HhJ zSyo(F*lv=gZBxW>?N6E*s71hf;)Dd&BfLE)S%#r9h7OoUa@^2@=-8xYr+;D|u||oe zEe#!AT1tvR=U6~*?%iu8`4}^TlG1P@8{nt9x>~|-x$j+Fm>FD|Rprj##H=}W6&2nb zs-%E-%kS@wx58_IAIJ0+7jX0Fs~Otc+qbaYWB!j%fc$1byRo8!c3}=)3UekX1Smb$ z{jrXU!k;&uPvyR=4_q1@9WAwAA%Q*wHWa`wAfGPK%jA@mz0U-Y(11xVWVoWEqH4`~ z^zu|OX%y%dm}uC5DJ%*hM8m*|0s{)#X0AaS*}-IqYwy$)*mtbp;{aI#atiDX9O_^H z`ueG0>EKGhJOoSxym}nlp>JeV;Bn#zO}3Dbg9Sz?FcSqO06YQp_3KkfNu2)`DSM5f zK&93`;8g*f0(b-1DQBsJ%D;+2ur8l;EybyVE(f#Ix6Zm?Vqx#7)Nz9n)ZgmpI)Dbe z8sv5v7^MCoAv%8Ddf8c7K~pe?#2D+sFo{`q!{qNE4OU(4d2j0e#|g`{iVC+$Q75>& zuk))1t}ZJnk%s$CqvkxY=fL>1cuNJ98Im@dE`_bjs`B!;^N@IQJwws3EzFw zE+GjBCxo@a45BgdrJdQv{}J|rydtDsK+fa-oARoWB<|d=!=)oR>>S%63C9Qg zP<=3Tgig2X@jYkbLSQYmJr3SLkmOnQ6s#~5ASMs?)0b8kMzmmlO@a)?j4})hc`z9V zC_@<2Oy@Px_APu8d-aM`Dwz76xjD=H2{>e6S;IQBZKtq%_`?g?n@wz`xj&s5tjYoi#4c6Myw7-3AW z^mLQX1wYl7ju2a+h87AQl{d&SOnf9etqit#FjMUVtZQ|3Jh&h5LjY^Zsi~LG$Ecb7 z9pG+(%m5$&YhGF(DS$IF>2=|ONs|>j7g?X8Z6M|d?Ebr;Q$A1<08)xOcYgf-{RIjO zW_iynE!jZptyw>ZHvG%q;q3ST97V!{kw6%TogVFBB4m3@U7+2P0s=ljuYwHK)!G>3Ui3gbsiBoCJJE?8xtL}BI!SB^>VL7udt zJiQ%`tL=O==Xfn=Z^O!qD#@lU;3r)hxSrrh#`N9lQ1xGlhh*bi*;0J$KRPZlkdg-n2j&yy z-yr?>U|!~N>A}~iC~3%y!B(%2mto|Ze7sQ0K!(Z)TpCCLSVS!ArSDF*Ff2nL^5Cu0jd^^OV&wtN=cy30)gjng7sl4xM~OT{}ws<-g-e7r-(==FeVrD zjBgR10}c@P$rL@X$b`0QvHw@3P3L?!5@W}{d6N<_?+V+DB_kt)8O%Kk>z{f)$?X z0ScV{Ds8yRt%OZI2d0>-Piv%TT@c9*F(5=?51kK3jKE02>@y4`OmCa|K{NysL(qGK zj^@MeEi}QMfevehX>58oHkyn6;IaW-tU7|}?KtdwFttHXg+WLo~6H<5B=lHl)nU_)~Tu{2&DP%$)IlSvS;k_Res?qG)T;98M!RZ@Tj<^r?Xe&;`m zvq1o9;l#Ukc}88d@D{`l4W%R{+QFe9z#Md>e!qu^8iGS%BV=>^L9!?HlA+?7)urO^ArKgy=drP0(bn ze`Kd(FNUcR3>k1z}Z)k{$jxLLukuZ3CC-JYylP3+p+CvSZ;bX7zhhV1RT3Tm$p2{PUGA+C) zAj?I%KO*NO*&%S31_)rcInG}z>T3D(bGH`>EW+twNlhb+w=t%9n~`grA#o>_Ri&7e zl&|X>b|i`0zs&_e`hLFr?Mb&SVW3wZDDpmMW+!mnSJ7bN&ME+ z-r4HjeFKAoN?KY$^)oNY10dHhIB>U08b*cukW+>To>nO)@csdpXm#kbo2rDXdr?i{1{u))g?z1IsKh=BkJZPJw!ssqR&;vUKoX z$&)PWS2i~ZDN4gZ)I$w&(@D^F%+DtaOiL=Ns@};fN+IWoWlf#}mkdG!_aj&j^sTL} z|6(;mCo!EI;Lw3gQ5>JmGp#sXfKB)Fy@VmYM`y$>4rDMY1fpOKX+Th^D1;4&25WHj z&1lrcuV23of%BW7?*U*z{Qy_of%xur_j968G_1cFLFNFyalptCMt&w{W^O-L!d{Knvbs=>LeVK$rv*Q_*V*?in9%hoQi&JU4N6 z0BWPoxEUZBtG~_~RacDDNm{tS0J9{d5lAL9>S}M-pQ`p)Eu^Ue{~KS8#1fJNr|<~L z53oylC!IftUhIhuJuV-)%6I{61opW@aI3N&LM9pUKlTxP#F(%mC=gE&XLg6{YCwDH zA%jtf&-NZO>1k?a&Z&GRD~k`5Y)0XHUg1d~8>c}`f-ZCxOePP~VqpmhIc)*#63WWT z(o_E+jp7W+JIrGUz-KYx5lTt&@A<=@I1L`cRPki9f_?Sjtb*W~meN{-6rD$dU6-&F z3{`=uW02Mz5Olypmp}@IaIoA2r_wbq_x1X49(KXVjmJ5mA?j)+mfvHnBcD}H(|ITD z6B7{t+(_>XcyIUO5eLUw#ArZkOnV5UecBJ*^>;UwzbJ^`$`o zzsHu~In$80*Y5Fu+a$5|&A)e=J(>w=Tn;l63}2(7N`egCprUuc0wk~C@t<&L%#y4U z00KC;xF7|mi^nWA8m>Lps&c*UTQ6p5Y1!Ws3W<~8;9!@mwepwamL&qF_P`*BPtYJ& z`~m{%VIGdj*_o<>mW88)al^?(qU57f^@`NNsU-K<eAn?bJSGavXC$;Bn!QkE2 zR>=u}x}>ns8Y1Svjv&eK-?85)duauI0z5NoAarj{_8Fmd+w9Crz!)ElomErGK1?T^ zu@gR!Eh;JL>+bfhpYe;){6?Im-o?DRvhuUMJm$}zKfhYuuWE*JOQQ7eWjJlR%csZmpJ=mhP6&y?TMw41p>H5~IP0$wd@(LjnT&>}|rW z;R-QPWT?iDSYBTiuZQjO;h)kl8se(~L=EjH%iA2>nv`i&Kqlw>f<3r|$bspxZ4UXJ@ux75GsICTsNe6p}RVt?lc*N7k0(*Cq+yavFYK;B9ZSP z@C~bF2c#1;4e%kN5m*{Yt*`&h(mzssv+Y5}#R;V~K7<>zKXNmcfFK_DqNZlapc3W( zC3*l&eIhzz1$jW(NVcBA!M~voq)MH4?n9S`JAtQ4Ft)|o0eI?7KG?YS+}wx<4?aLt z_xr0fc||y?AhsaqsteO}@LFN^Jy6qPBzmIOLB0WFutflz1xV2*!;&YQ@26oNmjKHe z6M=x-9xnFAM1=}D>r>2wQ-U4l!BcUhzW-Q3dL z48sZ(h#`lcCqR)uje9?34=)>o$)lZ2HYD20PpFJd#KJP_-cAFV#p<3A7O(GVqj@0` z3_SfKH1$Z#`bSS>3vBU{eWmm zaAj{>;e9JFC$|7gG4MuK28F2JPhsByK*l__mZ`iJsAOhi!-4rJiHtX)pa%3pg#QA2 z{{*-JD(hZX>#Yq40gTKOguL}A|X&8 z2Dl(f*;+ZOr&(31A2LiFYtfkf-BwD6=(HHQp!T12H24Wp7WC3jD28j?XofVuq zB7}!YhBq8xFa<3NVnlf`#Oq+@=n>j&exUAq(=MRwMe0NRDc%33rfC9nfS5W;1}RV* z6tFL1+S>7!q$UW-B%2nt8&;3+V3M+Dt;WyHSJL+6z{$L6N&NrcLyi=6HGyNm7K(xm zv{R?5nc(JTw{E(V>K2S-#!kKQ&j4NoHyD%@EeP<$(lIBgw&w&}QeJLyY92nP$F#Kv z{(s=#l!DpcB>$Agms;~^ETh||?TjD>p6yivK95!txjgvrSTJwO|C{HogzKY{WP!2x zF%QI{b1n{Qc1yfYN&;?1fYEn;x}bATf3Zz;fmNF-7i&2FNro{S>$ohd|5WadPfee| z7lmJ;YM!{h^*d=#8ET8nhD5L?bm9~5)HOlz{jt7*iDRKm{X+1}pLS3B1rsE21xy8{u(3!-f=99nIZflEQe&iL;J zZw8Ff{=X4#`#%rJ{XgHK{g(q)z8}5ytN!I6w095Lt6qDfur+@? z$3X~_1TEfwqK=lTRhu4D$KB-^_ZK|`@7oW)@k3ZE{1ZJ=-M@zD>E$m5YMZ@$$u6OY zmTUdk^tB)IS!&X4q%m*sdB4~84EHWE`bbGO6Dyy^&AWz3=oB87UNNY_d;jAV3UTIz zLePXEOd<#K#$^!5W8YfODwRIILd!B4R3TnzuxO7}xIvkGpSK7D5=G*zeU}DZ$#5kTO-8n|4(xas7*WkL~f_uBF8U*>0e(=%Qgc>dhASo7_BdOf(#t@)=o zFA2=AR2L0z<#ZP=P%dXw`dox;*Rbfmk|rWE~jzVORWfF&ncU+T)m&Mst2PG9+#X6mjBj-q>%~Yz~gi4*rhaI zvFT#(n}=P~#53=^uK#g_0c6QDoKf$6mxk?{tDc?snQ;bV7uU?k2=Dw6q9b~7rTB=H z^_eN@;K-nhCggpWLLV-`1-wSZvz51aP6HRmecykBM{>^Q# zhh0e2K4M#cdPb);UsE^%>#{$Z*T;A2i|tnt|C-wym*N9rg7@#Wj>}h+r1{|Xi~IS zTABUYna0~OvyWW{Ik+NI@Lb7Elivbqk3d;Ap?kc;aS%&e&7z^wi9Z4^wV7f4anH zVC}U}>jeJOOXpuE^?dLW2CD;W0tiJUGq|7flVd*ABsmBuAfZrpWhAxd%VC#OgLl^n z9{H=oa|yLZC)6bum(F+dt~*nB6^K&gURLlJzpJm7T_;+8!;(Sq8v^O(-@oZOs=7u33MK zmwAO}n!Qhit!$2S0jo?c_ri(2deMDR zQs^CzM4uOZr%$#=F1x=w4nrX}<_)jDEtW}Cx?SY{Cu&h{EkBpDj!!RJ^e(dZIa-$C z3%e|;a3KtbWVzs_GRbw?;eEtc?;3Hg$ZwMGy&}sZDz1u^9vI+y2oKrS^ZF2;(szeF zB|aY^2$3+OkwNWOBaoZcbmQj4UL3tVC`5-#u;<&V_c^$4Woze;P27ZoC_xFtdfl zjzxRTUE%0?HCvnQ6t(vABQ1s~y)q3Lw|$x>uCi1A#?)6u?pV$om?Ax(aFJ6 zszwq&Z|JqcctCkxG-|igbQ0;aCFH9s1_n`y3711#O;=z zNc>Z`Q~x{DOd~b>Ki;5{Yp~9*I%}emN%L7msWyGF+umKe(VXut00VBS^ZD|G*t0a& zTDO8TPM`ex!`gb%0tZq4N!K$ur=uZFLPTGe{d?^A~6 z^xv|Y*4g6Q*iH@HiR)+lSeHZvl58~^?GO7G46gWn@O5eTO1Xja}dD$Ba5Z^hJJ zDyqq$g#jy6<1AcFzY&?vWM25(RD3t@FlEI}EvX|lZ==U=S|ok?VPgBuz~vfRYkFpG zrZ^PAMDCR?_D7WbfW6-Q(Bky_xj&ky{8!uO4w5kP3%WNPEghbdBM&peG`|@fjW-2h zh=;=4RzFS){U&P9`GlRR5s7HaVLva=G@@a=(;9r@B_SsI8LC>1JolNW4!hFRGfrjv zXQ`xo0%Kjcme{}T`&eD+71tt|$Eh99;1{Z>)hS$2kE{7JrMB7N<=s(QA@;WSKxLcm zquB@TSBfP22bvKBc-5EP0FHh9G(NlD-##+38`p*d9vSA-r5FZTPo0@X^(C*Q7rZyZ zZM>+_=R^R@i1rY6JS1xKO6z4JFAB@5gKMHHkB~|h({nZL`DL8BE1u7AIXf1rcxLE^ zuO|GRf7G_i^aJNYy4>o8TPI`N?pZ#IY(7h@ftqE&u7Ht&8qd|@v%iID-%@hQqsvB- zd<$YaUFoMc`MPCx*zXf($a?_UXO&5@)R;EB%O#C^{ikEEQ=?Y&#n}8-S#(DVYTh;1+|Oq; zH$QK4jFX~I=lHYhj(B~#9QKyCFKXUT>N$(lU4OrwZga)!!bIquA@3ELXm;$jZC;#e z5syl#A8V@_Xxx=#Yw@u|2>bkRgTrN@3w z{5NZydITQtxCyg`90aoK@&&=gW$r#^leHb9-|pBKe#5yfQV|Q;wKx1uu%{m3vUPC; zI_-qeUw4b`;%{9rOxSYAwVEVG3$=ITTRow>>LHxQ#*0K1&u!he=laLN#X-Mf@F*35 z%-EqbugYg>%IxC&s%ht)C(SAY8{0UAn|~WkeV*}`;jLb&$mCq(Btc6}Kl3fwI zCW}IFbq9J0bXuxKbeU53CIZuZd`?Al`kkfCOVD>i=dY-0A;H6FSxi>A=8q_PjSlcB zV5C^*8YI&%yxg1upFh3z(dJZ?M9Lb=Unc#f38M5PmEU`=WnSVS(uXv4^ta^SxeYut zq<>TXu&2aXa6@%cSOELElPJR@q_}5PbcYW?-aWds?6gOXzZ&AA z;`%)uJ{lSd&jy=glWkVB?F6$~BVyhPHil=k4%{cp_R)A@d(TnI?R)H(W?Ty&ipQJ< zb#(OFth4H6^#xYup?rrvfvT!@t#bPBjnSr98L#n~m%HAGi<>6<1u+VB>c*F!uqh&~ w(q&6>{rs+pGdhI%1uHa^j^(JUUdmP`Hq`KGY)8XybHYMO$ctw`d;9+X0#*0O!2kdN literal 0 HcmV?d00001 diff --git a/BookGPU/Chapters/chapter4/img/convoOverlap2.png b/BookGPU/Chapters/chapter4/img/convoOverlap2.png new file mode 100644 index 0000000000000000000000000000000000000000..606a4bcd68b07f3809741a9a3ab274ad54669555 GIT binary patch literal 31328 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 X=@GhNVJF330AEIiW`|xI*#G`NKCf@e literal 0 HcmV?d00001 diff --git a/BookGPU/Chapters/chapter4/img/convoShMem.png b/BookGPU/Chapters/chapter4/img/convoShMem.png new file mode 100644 index 0000000000000000000000000000000000000000..1c48504bb29fd2b9ff76edc64ff20024f8b0d98c GIT binary patch literal 184261 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 e^|O@gWOgCVXP;>BuI^Nn!_3Iiuuk9U+5Z5R0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + I0,0 + + + + + + + + + + i + j + + + + + i + j + + + I-2,-2 + I-2,-1 + I-2,0 + I-2,1 + I-2,2 + I-1,-2 + I-1,-1 + I-1,0 + I-1,1 + I-1,2 + I0,-2 + I0,-1 + I0,1 + I0,2 + I1,-2 + I1,-1 + I1,0 + I1,1 + I1,2 + I2,-2 + I2,-1 + I2,0 + I2,1 + I2,2 + + + + + + + + + + + + + + + + + + + + + + + + + + h-2,-2 + h-2,-1 + h-2,0 + h-2,1 + h-2,2 + h-1,-2 + h-1,-1 + h-1,0 + h-1,1 + h-1,2 + h0,-2 + h0,-1 + h0,0 + h0,1 + h0,2 + h1,-2 + h1,-1 + h1,0 + h1,1 + h1,2 + h2,-2 + h2,-1 + h2,0 + h2,1 + h2,2 + + + + + + neighborhood window + convolution mask + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + blockDim.x = 8 + + + + + blockDim.y = 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Region of interest (ROI): width = 8x8+2x2 = 68 pixels + + + + ROI height = 8 + + + idrow = 0 + + idrow = 68 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Thread block + thread (0,0) + thread (7,0) + + Image tile + + + bdimX = 64 + + + + + r = 2 + + r = 2 + 3 + 3 + 3 + 3 + 3 + 3 + 3 + 3 + 3 + 3 + 3 + 3 + 3 + 3 + 3 + 3 + 3 + 3 + 2 + 1 + 2 + 1 + 2 + 1 + 2 + 2 + 2 + 1 + 1 + 1 + (x,y) + + (x+7,y) + + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 3 + 3 + 3 + 3 + 3 + 3 + 3 + 3 + 3 + 3 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + (x,y) + + (x+7,y) + + + + + diff --git a/BookGPU/Chapters/chapter4/img/kernLeft.png b/BookGPU/Chapters/chapter4/img/kernLeft.png new file mode 100755 index 0000000000000000000000000000000000000000..ae5d0caed240f08a0320138d0ad99be90df9dd67 GIT binary patch literal 1571 zcmV+;2Hg3HP)nD+DVb@paCC+)M@`eDJg^F1$A84uGxafv8?iKrXAEcIz7C!SkKoKiN2~D- zY^^x@9+u2D$f(#3Z?DMt7cRnzBsu%yLj1kL^mCkoof3FP#di493eP|B`L?6kf*HpL z@L&bz0lW_jlL~e?uE+Kco+m^ja%d9I9{3<0syO-+-rLX7OvAhw7vtX*nA`A1j3&t0 z8K>h{6`sxbB=$}!*h}!`0girxH(*ZZ`^*5y2#&!m6_BlB?_QlGXDL38M=MOf6~A#~ z2|OcsJ#L+bqgB&-&u0L$8{RGEiY}Oq_!yp_RIr2bO>C<$-GtYnB=GEx_lWtli)RBq zip5Xsy>|d+IX;VjRA7FIH)DQ+oSm=^cU5>E#}~1G(g$b-J|~)rE~dM2>W(^^E=a+V zq7|L&0NIXj;qW9md*VFNvUkaONHhTB2|WLu2X7qU==zy(Gzew^&cwYHITQE{mL(PJ zAbd^tJlNo8I1zIbc*gK{^?7gtpT>SO_IEpA_7R=d<_gSuybHS~$Qc!#=xr6AZMXuj zNcsTngHH``bU)rX8;+*J9ENLk&pHi$C_1E(1Uch)zxq7*nCKvvBo*vcxNd->TSccm zYmQ)^Xe92gfNa4fcxjTHmH3iqD!Q2N5n0|Y2|V+0nrOOej=q8ek{nrAf%ywQj71qR zEvT*$V-nxRYm#|R8Q|zccwQ#cs0e?juD^-B`HH4#w)S~`)>bKHT>O4aU037WrfKfW z)z8s$g`{~$*nnQ2GUfmj3X;xow6sn68Wj=(Jw zC$+V#?p_=(r(u}W6Y<9i&o*%(DeFLY87>>(=r=ent#B>4m7cog+x56hQamLNRL>F- zR2R?V_=LO*O8bk@zUJso9FbPI7ThXvcvyqGMc#4CE@D7`tirQd9I!4(Vp=VR^qQla z@$$67wcrlHj|RY9hm}dPb`>4(M1|*(-nVqt?@#ua4i#N*&C#`ZQCi_zaBJ1?e{9EB zGhNDaI!nDG*;Eu(wD{yyYNNVvc78iJGS02_T@)R7W zo`c?=Ubr6I2u>3Jt~3?u3z>y$G3_l5h5H5BdkukSr1x#VzYotvLn&MfZWM3v|5p&s z7)Ie*Ov`blr-JN151FT5*nj#^3)h01C(?tzO1jlN4WP^y2QSss_5v11Y65F{`So zh23TuTs_zu3sOqArIdE*HV`V@j@MF3r>2zF={69iePP`pJWFr|CU=9U!F1^mrsr`~w;VN?{9*{y;PnCigpIoZ^>z!M6?hQ)A_epO zvf$_(Y}AdwO~CyPF|FXf!ffmi2=!~cU&B*jK7NBWgLo$5fr6vun1%i@M@?{(8(Y$n zg0QD?7)A%k8r#^i=N5QA!$tUEPyi=mCcZ2%J%vL%?Wh%8AAX0o3UG_$Y;^q~VY|u+ z%QrPV1Go#*f_VCHTFsU|crC;kST7`SO>m=dFrFyD{SVh-+aO_^;X*7fFujOlv04Dn zXdHqk+c>%gKMD!l5Ws%pCJ4CWQ!mf&(h z=Pzu7tFW}d^c;@F*Z`jK@-gCt0?!w?3|oc-ZV2EsIWZWhfm& z|CZ0OYlH-@39c6>;`IXDV*C}G2MOB|f0v(kbxcpn8Dhj4wHGJJ&$^PM3+o(p60S$i zpym|d25={K4+`J}In(^Oz_bvj>(KeDg`)%UXd6d&V7HLK4FTK^*I`)!@CEz|;{$kB z#|*q&;8}{Rv2~E6?Qwk@NAu)_XIx0&n&39T@9|y%?&x5qy>OrUI^=?2o(=JbHja)A z4O|o4SUD|kwPjt}C8jNLYmKOmZ<{raj>0D`crNMDowc)^Ij!5`wf{CN@)ttm$#?7)fnZ1d)@2y4O0v)Gs^Qv+%aw z=xwO(Ia1*r9FH*pJfj=;dZ)m%LN1j>RemPpwgOKj7Zqk;Os8Qc%9ZiDc1$JL^iC0z zO(ywJ{%RXR_u$7t0h=gySW1pQl+S(NI_eb6`tsqil-e$qGt8(i_P+R6n}E&1PC+~y z$W7pqqfc>GD@P*@vljlST+&%0AAm(MZ9JlgnJC zcF!`oP8U_!-46G*3D`XBAH*}RvE7y0J^!D9^@$%lHY86&_)IDB>Y^i z_Lm&ZUKvL#1GFdp*=7s61KR`ztPg)yZlJy=k2-X`f!bi&OK#eh9Nlge>Y(2R<|lZ# z4a|dr<}a~^+%PQ-4t*?7W33*s{vxO-ERPHRZ5WRB z9`Sn@pq?tgyeuatVKe;luZrq;mdk@lp}%vG&wq7HFX5n$-MauavjxoSjZb~YXD3_m zY}A718@c(oSu{_B>B<&Nui=PJJ1RjP+XVA%akCqOnwZ{g@T|Z;ti)K`2=mNnazt^fc4 literal 0 HcmV?d00001 diff --git a/BookGPU/Chapters/chapter6/ch6.aux b/BookGPU/Chapters/chapter6/ch6.aux index 7d02f32..78457db 100644 --- a/BookGPU/Chapters/chapter6/ch6.aux +++ b/BookGPU/Chapters/chapter6/ch6.aux @@ -3,110 +3,110 @@ \@writefile{toc}{\author{Stephane Vialle}{}} \@writefile{toc}{\author{Jens Gustedt}{}} \@writefile{loa}{\addvspace {10\p@ }} -\@writefile{toc}{\contentsline {chapter}{\numberline {6}Development methodologies for GPU and cluster of GPUs}{89}} +\@writefile{toc}{\contentsline {chapter}{\numberline {7}Development methodologies for GPU and cluster of GPUs}{107}} \@writefile{lof}{\addvspace {10\p@ }} \@writefile{lot}{\addvspace {10\p@ }} -\@writefile{toc}{\contentsline {section}{\numberline {6.1}Introduction}{90}} -\newlabel{ch6:intro}{{6.1}{90}} -\@writefile{toc}{\contentsline {section}{\numberline {6.2}General scheme of synchronous code with computation/communication overlapping in GPU clusters}{90}} -\newlabel{ch6:part1}{{6.2}{90}} -\@writefile{toc}{\contentsline {subsection}{\numberline {6.2.1}Synchronous parallel algorithms on GPU clusters}{90}} -\@writefile{lof}{\contentsline {figure}{\numberline {6.1}{\ignorespaces Native overlap of internode CPU communications with GPU computations.\relax }}{92}} -\newlabel{fig:ch6p1overlapnative}{{6.1}{92}} -\@writefile{toc}{\contentsline {subsection}{\numberline {6.2.2}Native overlap of CPU communications and GPU computations}{92}} -\newlabel{algo:ch6p1overlapnative}{{6.1}{93}} -\@writefile{lol}{\contentsline {lstlisting}{\numberline {6.1}Generic scheme implicitly overlapping MPI communications with CUDA GPU computations}{93}} -\@writefile{lof}{\contentsline {figure}{\numberline {6.2}{\ignorespaces Overlap of internode CPU communications with a sequence of CPU/GPU data transfers and GPU computations.\relax }}{94}} -\newlabel{fig:ch6p1overlapseqsequence}{{6.2}{94}} -\@writefile{toc}{\contentsline {subsection}{\numberline {6.2.3}Overlapping with sequences of transfers and computations}{94}} -\newlabel{algo:ch6p1overlapseqsequence}{{6.2}{95}} -\@writefile{lol}{\contentsline {lstlisting}{\numberline {6.2}Generic scheme explicitly overlapping MPI communications with sequences of CUDA CPU/GPU transfers and CUDA GPU computations}{95}} -\@writefile{lof}{\contentsline {figure}{\numberline {6.3}{\ignorespaces Overlap of internode CPU communications with a streamed sequence of CPU/GPU data transfers and GPU computations.\relax }}{97}} -\newlabel{fig:ch6p1overlapstreamsequence}{{6.3}{97}} -\newlabel{algo:ch6p1overlapstreamsequence}{{6.3}{97}} -\@writefile{lol}{\contentsline {lstlisting}{\numberline {6.3}Generic scheme explicitly overlapping MPI communications with streamed sequences of CUDA CPU/GPU transfers and CUDA GPU computations}{97}} -\@writefile{toc}{\contentsline {subsection}{\numberline {6.2.4}Interleaved communications-transfers-computations overlapping}{99}} -\@writefile{lof}{\contentsline {figure}{\numberline {6.4}{\ignorespaces Complete overlap of internode CPU communications, CPU/GPU data transfers and GPU computations, interleaving computation-communication iterations\relax }}{100}} -\newlabel{fig:ch6p1overlapinterleaved}{{6.4}{100}} -\newlabel{algo:ch6p1overlapinterleaved}{{6.4}{100}} -\@writefile{lol}{\contentsline {lstlisting}{\numberline {6.4}Generic scheme explicitly overlapping MPI communications, CUDA CPU/GPU transfers and CUDA GPU computations, interleaving computation-communication iterations}{100}} -\@writefile{toc}{\contentsline {subsection}{\numberline {6.2.5}Experimental validation}{102}} -\newlabel{ch6:p1expes}{{6.2.5}{102}} -\newlabel{ch6:p1block-cyclic}{{6.2.5}{102}} -\@writefile{lof}{\contentsline {figure}{\numberline {6.5}{\ignorespaces Experimental performances of different synchronous algorithms computing a dense matrix product\relax }}{103}} -\newlabel{fig:ch6p1syncexpematrixprod}{{6.5}{103}} -\@writefile{toc}{\contentsline {section}{\numberline {6.3}General scheme of asynchronous parallel code with computation/communication overlapping}{104}} -\newlabel{ch6:part2}{{6.3}{104}} -\@writefile{loa}{\contentsline {algocf}{\numberline {3}{\ignorespaces Synchronous iterative scheme\relax }}{104}} -\newlabel{algo:ch6p2sync}{{3}{104}} -\@writefile{loa}{\contentsline {algocf}{\numberline {4}{\ignorespaces Asynchronous iterative scheme\relax }}{105}} -\newlabel{algo:ch6p2async}{{4}{105}} -\@writefile{toc}{\contentsline {subsection}{\numberline {6.3.1}A basic asynchronous scheme}{106}} -\newlabel{ch6:p2BasicAsync}{{6.3.1}{106}} -\newlabel{algo:ch6p2BasicAsync}{{6.5}{106}} -\@writefile{lol}{\contentsline {lstlisting}{\numberline {6.5}Initialization of the basic asynchronous scheme}{106}} -\newlabel{algo:ch6p2BasicAsyncComp}{{6.6}{107}} -\@writefile{lol}{\contentsline {lstlisting}{\numberline {6.6}Computing function in the basic asynchronous scheme}{107}} -\newlabel{algo:ch6p2BasicAsyncSendings}{{6.7}{109}} -\@writefile{lol}{\contentsline {lstlisting}{\numberline {6.7}Sending function in the basic asynchronous scheme}{109}} -\newlabel{algo:ch6p2BasicAsyncReceptions}{{6.8}{109}} -\@writefile{lol}{\contentsline {lstlisting}{\numberline {6.8}Reception function in the basic asynchronous scheme}{109}} -\@writefile{toc}{\contentsline {subsection}{\numberline {6.3.2}Synchronization of the asynchronous scheme}{111}} -\newlabel{ch6:p2SsyncOverAsync}{{6.3.2}{111}} -\newlabel{algo:ch6p2Sync}{{6.9}{111}} -\@writefile{lol}{\contentsline {lstlisting}{\numberline {6.9}Initialization of the synchronized scheme}{111}} -\newlabel{algo:ch6p2SyncComp}{{6.10}{112}} -\@writefile{lol}{\contentsline {lstlisting}{\numberline {6.10}Computing function in the synchronized scheme}{112}} -\newlabel{algo:ch6p2SyncReceptions}{{6.11}{114}} -\@writefile{lol}{\contentsline {lstlisting}{\numberline {6.11}Reception function in the synchronized scheme}{114}} -\@writefile{toc}{\contentsline {subsection}{\numberline {6.3.3}Asynchronous scheme using MPI, OpenMP and CUDA}{115}} -\newlabel{ch6:p2GPUAsync}{{6.3.3}{115}} -\newlabel{algo:ch6p2AsyncSyncComp}{{6.12}{116}} -\@writefile{lol}{\contentsline {lstlisting}{\numberline {6.12}Computing function in the final asynchronous scheme}{116}} -\newlabel{algo:ch6p2syncGPU}{{6.13}{117}} -\@writefile{lol}{\contentsline {lstlisting}{\numberline {6.13}Computing function in the final asynchronous scheme}{117}} -\newlabel{algo:ch6p2FullOverAsyncMain}{{6.14}{120}} -\@writefile{lol}{\contentsline {lstlisting}{\numberline {6.14}Initialization of the main process of complete overlap with asynchronism}{120}} -\newlabel{algo:ch6p2FullOverAsyncComp1}{{6.15}{121}} -\@writefile{lol}{\contentsline {lstlisting}{\numberline {6.15}Computing function in the final asynchronous scheme with CPU/GPU overlap}{121}} -\newlabel{algo:ch6p2FullOverAsyncComp2}{{6.16}{122}} -\@writefile{lol}{\contentsline {lstlisting}{\numberline {6.16}Auxiliary computing function in the final asynchronous scheme with CPU/GPU overlap}{122}} -\@writefile{toc}{\contentsline {subsection}{\numberline {6.3.4}Experimental validation}{123}} -\newlabel{sec:ch6p2expes}{{6.3.4}{123}} -\@writefile{lof}{\contentsline {figure}{\numberline {6.6}{\ignorespaces Computation times of the test application in synchronous and asynchronous modes.\relax }}{124}} -\newlabel{fig:ch6p2syncasync}{{6.6}{124}} -\@writefile{lof}{\contentsline {figure}{\numberline {6.7}{\ignorespaces Computation times with or without overlap of Jacobian updatings in asynchronous mode.\relax }}{125}} -\newlabel{fig:ch6p2aux}{{6.7}{125}} -\@writefile{toc}{\contentsline {section}{\numberline {6.4}Perspective: A unifying programming model}{126}} -\newlabel{sec:ch6p3unify}{{6.4}{126}} -\@writefile{toc}{\contentsline {subsection}{\numberline {6.4.1}Resources}{126}} -\newlabel{sec:ch6p3resources}{{6.4.1}{126}} -\newlabel{algo:ch6p3ORWLresources}{{6.17}{127}} -\@writefile{lol}{\contentsline {lstlisting}{\numberline {6.17}Declaration of ORWL resources for a block-cyclic matrix multiplication}{127}} -\@writefile{toc}{\contentsline {subsection}{\numberline {6.4.2}Control}{127}} -\newlabel{sec:ch6p3ORWLcontrol}{{6.4.2}{127}} -\@writefile{toc}{\contentsline {subsection}{\numberline {6.4.3}Example: block-cyclic matrix multiplication (MM)}{128}} -\newlabel{sec:ch6p3ORWLMM}{{6.4.3}{128}} -\newlabel{algo:ch6p3ORWLBCCMM}{{6.18}{128}} -\@writefile{lol}{\contentsline {lstlisting}{\numberline {6.18}Block-cyclic matrix multiplication, high level per task view}{128}} -\newlabel{algo:ch6p3ORWLlcopy}{{6.19}{129}} -\@writefile{lol}{\contentsline {lstlisting}{\numberline {6.19}An iterative local copy operation}{129}} -\newlabel{algo:ch6p3ORWLrcopy}{{6.20}{129}} -\@writefile{lol}{\contentsline {lstlisting}{\numberline {6.20}An iterative remote copy operation as part of a block cyclic matrix multiplication task}{129}} -\newlabel{algo:ch6p3ORWLtrans}{{6.21}{129}} -\@writefile{lol}{\contentsline {lstlisting}{\numberline {6.21}An iterative GPU transfer and compute operation as part of a block cyclic matrix multiplication task}{129}} -\newlabel{algo:ch6p3ORWLdecl}{{6.22}{130}} -\@writefile{lol}{\contentsline {lstlisting}{\numberline {6.22}Dynamic declaration of handles to represent the resources}{130}} -\newlabel{algo:ch6p3ORWLinit}{{6.23}{130}} -\@writefile{lol}{\contentsline {lstlisting}{\numberline {6.23}Dynamic initialization of access mode and priorities}{130}} -\@writefile{toc}{\contentsline {subsection}{\numberline {6.4.4}Tasks and operations}{131}} -\newlabel{sec:ch6p3tasks}{{6.4.4}{131}} -\@writefile{toc}{\contentsline {section}{\numberline {6.5}Conclusion}{132}} -\newlabel{ch6:conclu}{{6.5}{132}} -\@writefile{toc}{\contentsline {section}{\numberline {6.6}Glossary}{132}} -\@writefile{toc}{\contentsline {section}{Bibliography}{133}} +\@writefile{toc}{\contentsline {section}{\numberline {7.1}Introduction}{108}} +\newlabel{ch6:intro}{{7.1}{108}} +\@writefile{toc}{\contentsline {section}{\numberline {7.2}General scheme of synchronous code with computation/communication overlapping in GPU clusters}{108}} +\newlabel{ch6:part1}{{7.2}{108}} +\@writefile{toc}{\contentsline {subsection}{\numberline {7.2.1}Synchronous parallel algorithms on GPU clusters}{108}} +\@writefile{lof}{\contentsline {figure}{\numberline {7.1}{\ignorespaces Native overlap of internode CPU communications with GPU computations.\relax }}{110}} +\newlabel{fig:ch6p1overlapnative}{{7.1}{110}} +\@writefile{toc}{\contentsline {subsection}{\numberline {7.2.2}Native overlap of CPU communications and GPU computations}{110}} +\newlabel{algo:ch6p1overlapnative}{{7.1}{111}} +\@writefile{lol}{\contentsline {lstlisting}{\numberline {7.1}Generic scheme implicitly overlapping MPI communications with CUDA GPU computations}{111}} +\@writefile{lof}{\contentsline {figure}{\numberline {7.2}{\ignorespaces Overlap of internode CPU communications with a sequence of CPU/GPU data transfers and GPU computations.\relax }}{112}} +\newlabel{fig:ch6p1overlapseqsequence}{{7.2}{112}} +\@writefile{toc}{\contentsline {subsection}{\numberline {7.2.3}Overlapping with sequences of transfers and computations}{112}} +\newlabel{algo:ch6p1overlapseqsequence}{{7.2}{113}} +\@writefile{lol}{\contentsline {lstlisting}{\numberline {7.2}Generic scheme explicitly overlapping MPI communications with sequences of CUDA CPU/GPU transfers and CUDA GPU computations}{113}} +\@writefile{lof}{\contentsline {figure}{\numberline {7.3}{\ignorespaces Overlap of internode CPU communications with a streamed sequence of CPU/GPU data transfers and GPU computations.\relax }}{115}} +\newlabel{fig:ch6p1overlapstreamsequence}{{7.3}{115}} +\newlabel{algo:ch6p1overlapstreamsequence}{{7.3}{115}} +\@writefile{lol}{\contentsline {lstlisting}{\numberline {7.3}Generic scheme explicitly overlapping MPI communications with streamed sequences of CUDA CPU/GPU transfers and CUDA GPU computations}{115}} +\@writefile{toc}{\contentsline {subsection}{\numberline {7.2.4}Interleaved communications-transfers-computations overlapping}{117}} +\@writefile{lof}{\contentsline {figure}{\numberline {7.4}{\ignorespaces Complete overlap of internode CPU communications, CPU/GPU data transfers and GPU computations, interleaving computation-communication iterations\relax }}{118}} +\newlabel{fig:ch6p1overlapinterleaved}{{7.4}{118}} +\newlabel{algo:ch6p1overlapinterleaved}{{7.4}{118}} +\@writefile{lol}{\contentsline {lstlisting}{\numberline {7.4}Generic scheme explicitly overlapping MPI communications, CUDA CPU/GPU transfers and CUDA GPU computations, interleaving computation-communication iterations}{118}} +\@writefile{toc}{\contentsline {subsection}{\numberline {7.2.5}Experimental validation}{120}} +\newlabel{ch6:p1expes}{{7.2.5}{120}} +\newlabel{ch6:p1block-cyclic}{{7.2.5}{120}} +\@writefile{lof}{\contentsline {figure}{\numberline {7.5}{\ignorespaces Experimental performances of different synchronous algorithms computing a dense matrix product\relax }}{121}} +\newlabel{fig:ch6p1syncexpematrixprod}{{7.5}{121}} +\@writefile{toc}{\contentsline {section}{\numberline {7.3}General scheme of asynchronous parallel code with computation/communication overlapping}{122}} +\newlabel{ch6:part2}{{7.3}{122}} +\@writefile{loa}{\contentsline {algocf}{\numberline {4}{\ignorespaces Synchronous iterative scheme\relax }}{122}} +\newlabel{algo:ch6p2sync}{{4}{122}} +\@writefile{loa}{\contentsline {algocf}{\numberline {5}{\ignorespaces Asynchronous iterative scheme\relax }}{123}} +\newlabel{algo:ch6p2async}{{5}{123}} +\@writefile{toc}{\contentsline {subsection}{\numberline {7.3.1}A basic asynchronous scheme}{124}} +\newlabel{ch6:p2BasicAsync}{{7.3.1}{124}} +\newlabel{algo:ch6p2BasicAsync}{{7.5}{124}} +\@writefile{lol}{\contentsline {lstlisting}{\numberline {7.5}Initialization of the basic asynchronous scheme}{124}} +\newlabel{algo:ch6p2BasicAsyncComp}{{7.6}{125}} +\@writefile{lol}{\contentsline {lstlisting}{\numberline {7.6}Computing function in the basic asynchronous scheme}{125}} +\newlabel{algo:ch6p2BasicAsyncSendings}{{7.7}{127}} +\@writefile{lol}{\contentsline {lstlisting}{\numberline {7.7}Sending function in the basic asynchronous scheme}{127}} +\newlabel{algo:ch6p2BasicAsyncReceptions}{{7.8}{127}} +\@writefile{lol}{\contentsline {lstlisting}{\numberline {7.8}Reception function in the basic asynchronous scheme}{127}} +\@writefile{toc}{\contentsline {subsection}{\numberline {7.3.2}Synchronization of the asynchronous scheme}{129}} +\newlabel{ch6:p2SsyncOverAsync}{{7.3.2}{129}} +\newlabel{algo:ch6p2Sync}{{7.9}{129}} +\@writefile{lol}{\contentsline {lstlisting}{\numberline {7.9}Initialization of the synchronized scheme}{129}} +\newlabel{algo:ch6p2SyncComp}{{7.10}{130}} +\@writefile{lol}{\contentsline {lstlisting}{\numberline {7.10}Computing function in the synchronized scheme}{130}} +\newlabel{algo:ch6p2SyncReceptions}{{7.11}{132}} +\@writefile{lol}{\contentsline {lstlisting}{\numberline {7.11}Reception function in the synchronized scheme}{132}} +\@writefile{toc}{\contentsline {subsection}{\numberline {7.3.3}Asynchronous scheme using MPI, OpenMP and CUDA}{133}} +\newlabel{ch6:p2GPUAsync}{{7.3.3}{133}} +\newlabel{algo:ch6p2AsyncSyncComp}{{7.12}{134}} +\@writefile{lol}{\contentsline {lstlisting}{\numberline {7.12}Computing function in the final asynchronous scheme}{134}} +\newlabel{algo:ch6p2syncGPU}{{7.13}{135}} +\@writefile{lol}{\contentsline {lstlisting}{\numberline {7.13}Computing function in the final asynchronous scheme}{135}} +\newlabel{algo:ch6p2FullOverAsyncMain}{{7.14}{138}} +\@writefile{lol}{\contentsline {lstlisting}{\numberline {7.14}Initialization of the main process of complete overlap with asynchronism}{138}} +\newlabel{algo:ch6p2FullOverAsyncComp1}{{7.15}{139}} +\@writefile{lol}{\contentsline {lstlisting}{\numberline {7.15}Computing function in the final asynchronous scheme with CPU/GPU overlap}{139}} +\newlabel{algo:ch6p2FullOverAsyncComp2}{{7.16}{140}} +\@writefile{lol}{\contentsline {lstlisting}{\numberline {7.16}Auxiliary computing function in the final asynchronous scheme with CPU/GPU overlap}{140}} +\@writefile{toc}{\contentsline {subsection}{\numberline {7.3.4}Experimental validation}{141}} +\newlabel{sec:ch6p2expes}{{7.3.4}{141}} +\@writefile{lof}{\contentsline {figure}{\numberline {7.6}{\ignorespaces Computation times of the test application in synchronous and asynchronous modes.\relax }}{142}} +\newlabel{fig:ch6p2syncasync}{{7.6}{142}} +\@writefile{lof}{\contentsline {figure}{\numberline {7.7}{\ignorespaces Computation times with or without overlap of Jacobian updatings in asynchronous mode.\relax }}{143}} +\newlabel{fig:ch6p2aux}{{7.7}{143}} +\@writefile{toc}{\contentsline {section}{\numberline {7.4}Perspective: A unifying programming model}{144}} +\newlabel{sec:ch6p3unify}{{7.4}{144}} +\@writefile{toc}{\contentsline {subsection}{\numberline {7.4.1}Resources}{144}} +\newlabel{sec:ch6p3resources}{{7.4.1}{144}} +\newlabel{algo:ch6p3ORWLresources}{{7.17}{145}} +\@writefile{lol}{\contentsline {lstlisting}{\numberline {7.17}Declaration of ORWL resources for a block-cyclic matrix multiplication}{145}} +\@writefile{toc}{\contentsline {subsection}{\numberline {7.4.2}Control}{145}} +\newlabel{sec:ch6p3ORWLcontrol}{{7.4.2}{145}} +\@writefile{toc}{\contentsline {subsection}{\numberline {7.4.3}Example: block-cyclic matrix multiplication (MM)}{146}} +\newlabel{sec:ch6p3ORWLMM}{{7.4.3}{146}} +\newlabel{algo:ch6p3ORWLBCCMM}{{7.18}{146}} +\@writefile{lol}{\contentsline {lstlisting}{\numberline {7.18}Block-cyclic matrix multiplication, high level per task view}{146}} +\newlabel{algo:ch6p3ORWLlcopy}{{7.19}{147}} +\@writefile{lol}{\contentsline {lstlisting}{\numberline {7.19}An iterative local copy operation}{147}} +\newlabel{algo:ch6p3ORWLrcopy}{{7.20}{147}} +\@writefile{lol}{\contentsline {lstlisting}{\numberline {7.20}An iterative remote copy operation as part of a block cyclic matrix multiplication task}{147}} +\newlabel{algo:ch6p3ORWLtrans}{{7.21}{147}} +\@writefile{lol}{\contentsline {lstlisting}{\numberline {7.21}An iterative GPU transfer and compute operation as part of a block cyclic matrix multiplication task}{147}} +\newlabel{algo:ch6p3ORWLdecl}{{7.22}{148}} +\@writefile{lol}{\contentsline {lstlisting}{\numberline {7.22}Dynamic declaration of handles to represent the resources}{148}} +\newlabel{algo:ch6p3ORWLinit}{{7.23}{148}} +\@writefile{lol}{\contentsline {lstlisting}{\numberline {7.23}Dynamic initialization of access mode and priorities}{148}} +\@writefile{toc}{\contentsline {subsection}{\numberline {7.4.4}Tasks and operations}{149}} +\newlabel{sec:ch6p3tasks}{{7.4.4}{149}} +\@writefile{toc}{\contentsline {section}{\numberline {7.5}Conclusion}{150}} +\newlabel{ch6:conclu}{{7.5}{150}} +\@writefile{toc}{\contentsline {section}{\numberline {7.6}Glossary}{150}} +\@writefile{toc}{\contentsline {section}{Bibliography}{151}} \@setckpt{Chapters/chapter6/ch6}{ -\setcounter{page}{135} +\setcounter{page}{153} \setcounter{equation}{0} \setcounter{enumi}{4} \setcounter{enumii}{0} @@ -115,7 +115,7 @@ \setcounter{footnote}{0} \setcounter{mpfootnote}{0} \setcounter{part}{3} -\setcounter{chapter}{6} +\setcounter{chapter}{7} \setcounter{section}{6} \setcounter{subsection}{0} \setcounter{subsubsection}{0} @@ -132,9 +132,9 @@ \setcounter{lstnumber}{17} \setcounter{ContinuedFloat}{0} \setcounter{AlgoLine}{6} -\setcounter{algocfline}{4} -\setcounter{algocfproc}{4} -\setcounter{algocf}{4} +\setcounter{algocfline}{5} +\setcounter{algocfproc}{5} +\setcounter{algocf}{5} \setcounter{nprt@mantissa@digitsbefore}{0} \setcounter{nprt@mantissa@digitsafter}{0} \setcounter{nprt@exponent@digitsbefore}{0} diff --git a/BookGPU/Makefile b/BookGPU/Makefile index 847d098..e6e4e03 100644 --- a/BookGPU/Makefile +++ b/BookGPU/Makefile @@ -23,6 +23,7 @@ all: bibtex bu16 bibtex bu17 bibtex bu18 + bibtex bu19 makeindex ${BOOK}.idx pdflatex ${BOOK} -- 2.39.5