From 192ddc5eabea7742c8e2b5da8e1ef5fe408c8878 Mon Sep 17 00:00:00 2001 From: Raph Levien Date: Sat, 30 May 2020 15:37:34 -0700 Subject: [PATCH] Parallel merge The fancy stuff :) --- piet-gpu/shader/coarse.comp | 82 ++++++++++++++++++++++++++++-------- piet-gpu/shader/coarse.spv | Bin 46048 -> 49012 bytes 2 files changed, 65 insertions(+), 17 deletions(-) diff --git a/piet-gpu/shader/coarse.comp b/piet-gpu/shader/coarse.comp index 082d902..78c758b 100644 --- a/piet-gpu/shader/coarse.comp +++ b/piet-gpu/shader/coarse.comp @@ -30,9 +30,16 @@ layout(set = 0, binding = 3) buffer PtclBuf { #define N_RINGBUF 512 +#define LG_N_PART_READ 8 +#define N_PART_READ (1 << LG_N_PART_READ) + shared uint sh_elements[N_RINGBUF]; shared float sh_right_edge[N_RINGBUF]; +// Number of elements in the partition; prefix sum. +shared uint sh_part_count[N_PART_READ]; +shared uint sh_part_elements[N_PART_READ]; + shared uint sh_bitmaps[N_SLICE][N_TILE]; shared uint sh_backdrop[N_SLICE][N_TILE]; shared uint sh_bd_sign[N_SLICE]; @@ -89,7 +96,7 @@ void main() { // invocations within the workgroup. We'll use variables to abstract. uint bin_ix = N_TILE_X * gl_WorkGroupID.y + gl_WorkGroupID.x; uint partition_ix = 0; - uint my_n_elements = n_elements; + uint n_partitions = (n_elements + N_TILE - 1) / N_TILE; // Top left coordinates of this bin. vec2 xy0 = vec2(N_TILE_X * TILE_WIDTH_PX * gl_WorkGroupID.x, N_TILE_Y * TILE_HEIGHT_PX * gl_WorkGroupID.y); uint th_ix = gl_LocalInvocationID.x; @@ -107,8 +114,14 @@ void main() { SegmentRef last_chunk_segs = SegmentRef(0); alloc_chunk_remaining = 0; - uint wr_ix = 0; + // I'm sure we can figure out how to do this with at least one fewer register... + // Items up to rd_ix have been read from sh_elements uint rd_ix = 0; + // Items up to wr_ix have been written into sh_elements + uint wr_ix = 0; + // Items between part_start_ix and ready_ix are ready to be transferred from sh_part_elements + uint part_start_ix = 0; + uint ready_ix = 0; if (th_ix < N_SLICE) { sh_bd_sign[th_ix] = 0; } @@ -122,21 +135,58 @@ void main() { sh_is_segment[th_ix] = 0; } - while (wr_ix - rd_ix <= N_TILE && partition_ix * N_TILE < my_n_elements) { - uint in_ix = (partition_ix * N_TILE + bin_ix) * 2; - uint chunk_n = bins[in_ix]; - uint elements_ref = bins[in_ix + 1]; - BinInstanceRef inst_ref = BinInstanceRef(elements_ref); - if (th_ix < chunk_n) { - BinInstance inst = BinInstance_read(BinInstance_index(inst_ref, th_ix)); - uint wr_el_ix = (wr_ix + th_ix) % N_RINGBUF; + // parallel read of input partitions + do { + if (ready_ix == wr_ix && partition_ix < n_partitions) { + part_start_ix = ready_ix; + uint count = 0; + if (th_ix < N_PART_READ && partition_ix + th_ix < n_partitions) { + uint in_ix = ((partition_ix + th_ix) * N_TILE + bin_ix) * 2; + count = bins[in_ix]; + sh_part_elements[th_ix] = bins[in_ix + 1]; + } + // prefix sum of counts + for (uint i = 0; i < LG_N_PART_READ; i++) { + if (th_ix < N_PART_READ) { + sh_part_count[th_ix] = count; + } + barrier(); + if (th_ix < N_PART_READ) { + if (th_ix >= (1 << i)) { + count += sh_part_count[th_ix - (1 << i)]; + } + } + barrier(); + } + if (th_ix < N_PART_READ) { + sh_part_count[th_ix] = part_start_ix + count; + } + barrier(); + ready_ix = sh_part_count[N_PART_READ - 1]; + partition_ix += N_PART_READ; + } + // use binary search to find element to read + uint ix = rd_ix + th_ix; + if (ix >= wr_ix && ix < ready_ix) { + uint part_ix = 0; + for (uint i = 0; i < LG_N_PART_READ; i++) { + uint probe = part_ix + ((N_PART_READ / 2) >> i); + if (ix >= sh_part_count[probe - 1]) { + part_ix = probe; + } + } + ix -= part_ix > 0 ? sh_part_count[part_ix - 1] : part_start_ix; + BinInstanceRef inst_ref = BinInstanceRef(sh_part_elements[part_ix]); + BinInstance inst = BinInstance_read(BinInstance_index(inst_ref, ix)); + uint wr_el_ix = (rd_ix + th_ix) % N_RINGBUF; sh_elements[wr_el_ix] = inst.element_ix; sh_right_edge[wr_el_ix] = inst.right_edge; } - wr_ix += chunk_n; - partition_ix++; - } - barrier(); + barrier(); + + wr_ix = min(rd_ix + N_TILE, ready_ix); + } while (wr_ix - rd_ix < N_TILE && (wr_ix < ready_ix || partition_ix < n_partitions)); + // We've done the merge and filled the buffer. @@ -475,9 +525,7 @@ void main() { barrier(); rd_ix += N_TILE; - // The second disjunct is there as a strange workaround on Nvidia. If it is - // removed, then the kernel fails with ERROR_DEVICE_LOST. - if (rd_ix >= wr_ix || bin_ix == ~0) break; + if (rd_ix >= ready_ix && partition_ix >= n_partitions) break; } Cmd_End_write(cmd_ref); } diff --git a/piet-gpu/shader/coarse.spv b/piet-gpu/shader/coarse.spv index a3dd59ec043b0771053ede1211b7504eb3bf7e93..252ff10d8b2b61be2b6d1649e52ed678ea539a04 100644 GIT binary patch literal 49012 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 laAV}(t-b}WmY6>V+eSSxe*#u_UL4D literal 46048 zcmb822b^71^|nu#nI!byTS7_bz4snUfY3XWHc1AOOh^Gjk={j`^eT!VC{hFg5knCX zMMdn20wM@Dq<6mOx%a%2JvaLM`(54c_kGveYp-3-KIfj9jBRtRJfN!jRRj6YG?1T# ztGQ6BYTl}UqaHSVzv1gln?81(jW%9S`vO&)Rl~MmHK6JMw^JsK>Yl9rt+}e|$CQO= zufDJ%0gY*C<3E_I#~|(1Jk_w_ox}Ftd)V-uJI73!(m8GV%!yr{6T2sOb&l6Ll=W@5AoDRtyUwXyqsFc_ZTi$1W2Ub?XAW!6SbzO3 zY1>xKPur;^)xr1{s^jc8eQM9qU1i42oVELzo%4Wd5xDXDv_UgZZGMusJb60@a@T=0 z>Cdq&R4oplBiC+o?I(s~e(Y`sJj%vv|mh~nW6q|)pGbZbL?NOShsDC$Sj-v zsQW4N91Nd5H_bfN{Iuq&UgqhT)SPek_Ho@~r%wQPume`1o*j3N5%i{3j$vimWDG;< z_R~jA?;6`2LSwGg{mdT2eAOCo`)c@hP9HVC+@uLmcjR2Hj(@YC1*>)Xw9QpDN4_ml znsdH(5od!wac1wO|0|ODaLLvAEKqIoAL9HkF*Yt@Y|$r%WBR`$G{>`fZ;bxcR^T1F zC+{|S+VoMA$8Yfu;n(pZHV^*ON}?V9V*UTqI< zw4?6eKRZzuO&iybnxC$TU6Z;dPw(vJYH<&$yDz79kDoBTvuo`5#&th`H4LqY(Pt70 zJ!#QvTeXXE8fRDkYB%tXlg9S$RcK=ms{5He2OZTOaL(c#C(M|9GyxlaYJN(;;qcy= zVCPiL&$O=b$G39-yDaH@u>NkJ?{4EKsX)h*YJ`1 zDaWklm`9HqbM)A$JyWzhX7xG8ykvD4dL46)5!VSd1~7ZPs{d`Y-Sudj*TNyh&Ug<6 zXS_!=``oW*Vt3Tsv;7bw5i~-cW7l z%Kz7f|DPMgu^ijmM_Y9qxH*<3tCQ>g_G>(U{0}`g9sk>=%q7@Z;}eTMPwMS+q3ZPX z>1O+1y40`OJEs@{z% zE`Zm5jXf#%!!2nlkGE(|AJ2@g$zywcJS%4Q-Uk+`E{4}}`VM1u66Lh0ZkwDmps3i`{Kt^}J%2j5?=ryezNV$Yb)F_U^9`niyDtu^oA z?bWsT;ZdIv9o2O;pV&RA+kyJ6dVxl$99hHo<3=mHw3>EeWj^Q>mEND-d5cT_gO&OH^5Uz9k(78ynppg>fUF=9cDC+ zKF?xxKcn*82sYN;4Ye8T0Wh(AJZr>$q{)5MYw#zUe8VPht9}G%&R<*gJUBVM*z~J& zYOh{t^4_?AYx3T>Z!~!wx4n9&$v2{E^!rhh`^eYGc`i0q`dtc~ewPE!o{RQsaFh4; zJEX~b`(3lid;49l$?JaGs!ibOXBasB?9ue=9p8v1@9pP+ChzU%&?fKgr?bg>$2Ydg zd&hSayxDJibsl)isHvm87rEY-wD7B2_?P)uhYWUZQ)zA@GblBwrU%AGnck%WG`;7P5}GNz?s0fI;s=l+k1`_ z*Pfc6$({9+Jd@^pt2+&ivx3^WIJx$9zE1-m#l6V3@-yM(9Gu;U53DYR*Jqe#4ri2a zbGj#wZ?qp!UEX3Z?>*OGEBW1U_Ce!2hv$m#gT_znJg8^t(Zik zPtEcFRR3;XEY)YK%+{{f{V@QoyU`c#e!#YA+$-2qwppUq@|D6h8r0O77}D`6q@I@zja4t2 zIc^Sb4%7Qg|7vS^c5HLx%|3Q$v|~=Zk=C(xueId;ml9h#O9PV z#&Rec<4X#SoJKXZ@~ba;TQv!tHzAF7lfk8f^KzWp*uL>kLMy*p8|MuD8s970t8>A# z$Iww-0B286o7g?3E91PVsZAO+?Pz*wudadnZYcI^`^0FkZh#*@srimo|63b;RPSEB z3qG^3KiJ^0w^fh9$2RtVTlJK*ZPj4-@!aX0o7Kgf{^Iq;Q=52mFqd>g-(Fn%90+diwYKUA z^}7FV@bLsS&a?(zzkyE{*LmC|o;u1V4ci^PwvOui;Ko(zb5w1A60Lb%^sk=RKB0Lb z*Dj41FBU#+Twb+Lj$eHGS97CJ=gr#0qPhELe*Jlxi?g{eh?e`)(zf$#LeRF1wt6fp zfu~IE8QoR$jo{O|j%n<4V{a#SQx$uEm)eJmyS^89RC}XMpTK3@cz|?X+N&ec@Tp_9 zRh{tkI{`eq-;U~Jc+ZUKowLvRj_M4w*6ZQ|w7%Cxdvz&VxvwvS&)z5P)fMpB-$B}| zD_iW>!<%RK%*On@0%txOV|cU0_pLs>qk3Q8KJ(LFeSnsSWasb`dCPNizy1xaer{&A z;N>A`y8&pfYrbQ-2bMyc+%s7@T{Q9>j9!j;tp`=XP$ia(~R*!WV%z;@0QD(k=F7TlgS2-(~Bc>+pT1kG-Q>1@7FI zKI`=HX|L96;TyN`P5bbUYIk_+*!S<_!@JEsyrViC-n!3v3ZG$|Q+G0ErVvzByRuvJ zeRO5GpJAMtYTTy4?TzoHD{0^pKDbF6{9YcM%Xsz9~5`i%ACuWrYuS;+YKhV@x_bN#xV|}_*nr9O=``b&Q=Yswgk4hsRvP(q}@E!a^tK3 zw;wgjVEBC0YQ`|`Le$N^+8aMRHm2GN%*`UyX`A+oqNy+3@M&xOj4|z(LbJU;cQhBr zXD-g6xi}yCs+)`Rp=LXC@#lbvH3)1hHFI%()7F@_U#U?y$8P%}wa*}IL&3IJ)7KX} zwpW+0MeRI<^H|gvSGZsL?K6Bcu(`_Z%bzzH&%U;%9zao(Z&P#agUNl{+NPg2=VB*n z?HS9?U^RV=zZ-Sp?+!M;nzlV^oAWXpEH_U4_XO*&&HneIc0U+Ln=$sIj{p8({ngxi z2T%{9^rP5^Kj*Ly^|Uz%Y#VL%aWJ)g7)zUd96=rbBfQc+tiG86t%HzqfP%F>cpA?HkO+E;uvcE)onkc;Eqe}ghF#Z z)lMn2k+pVap{4Kh(9-w$VEa~co-d%Dr!I3-yO%yst&cYQxsclYY^zP5OR4p7jf`^{ zwSCBqt=pL!J9$3`F5|ri_v}i%Pry9BHsbZe(RiMP#^1Q+o)PjLYVKJl@2>gan$N7c>zw$v zp$&vPZ@F(eZ{8o}#<`E$F{(Lla_^C9+Gl~y%d^BdxnCN``=VUGpHbUJ%{X%JjfwLQ zuyI`9Sm--BwNu^k9^F^zvP*#6Ya?U346-FR}} z4H-}WPO$qu{v&Ify8d$C8|iPnt{Ruu$V9Y({hD*F-UIiO{LX@}RqzYpg9?5Le8rmE z{#AJAl=IfJz5MU+)sCLLSNMByKHG@)@;u*VgwPrM*9VvD)AM=7H;<{#SvYTJUjj{@bvd&oh$h)JFdH*Ubg| z8K1T2-D|;TQTK~ysbv#dLmN3zvBRqBeH6o(qvyWwoIMA^A8z5kQ;ywpc2>b{@B8G~ z<-RX2x$lch?)&0!?@hiZ4!6DUiNn30`Hr~cz8enL-*>{{-bZ~G9IoAWz$Nz`aJc89 zlM=4K?|Mt_``VKGzP9APuMPKk&-b+9vxx6I+Hmc@qYbw|-_eF^_Z@AxcHhyK+;^_w z-gkWO8m_I-gmCyjq|DC+I{aD zyZQUxwdB5YExGSpOWuzgLCJmJT5{jDmVBNT?t9nLKDdRi+`@g|TKfB*wdB5IE%}%h z?mO1lhcaH@v4(rz`;Il-?=rq$4R?NgzZ$N;?^eV0zo~`$ZZ&rOeYYB}zwcJVJr8`h z8a@=e?^eV8&gi?HThuOB2_f8VEu>+k#2lKVb2Tz}uEhU@S9)NsEi4J!Ch z?1KyL_if*&^54euhvV^GYPk9NE;U@c?^45U@4M7+^YLA3$$gI+ZhpQ;4L82;QNxYz zJ5>4hJSF*k;eLwWA$*?Nnr9}auljbapNWtB0l42&)YI-ku~olH8}X}eO^?b!q|Mq z{61Jcah?RXj{gT}>WT9d*f{Em^Fy%u2*&F7@~6SZRySXtBh}K+Ghn}amGkuzxVrv6 zXUgOMGjQwpo<&nnUOxxBF6wFb9JsZgU!bXi`8&f^)eh+TV=MQM=XV>{W4^}Jl`6JwT+RVr2Y_;r-7r<)i`z5g2i2wYJR^GXU;wW8^<~Ll=?Hu#}sw*k=ySFv`c$y zZT{D}($)`bZ0mRFvyHl);zxT&ZMQZj-y_UL(a&~bWBUCj{SB;b*2bKNdR|Im&R5&5 zGoJau#>l)Z09JEe>{mWF#aQ+$PTNJnwhdnl+?<>Kjk#GI?mG%NR?+ z%NR?;eea>4He;w|%#P2ztdqwwU}I(vE(=zBj)};esX5P?GslTs`vTz6~0^-;g4z7Ey|t9#yi9jp!ZVpF(& z>KVgkVD(vy-}Uibfm-_60<5+@PYJ&B-V*HlU9V|v@!JZl%^1F4kjJ(S*ci!UTdC`oO!g}-ryamZKF*e-vpUFSS}?9tKv+{qAtE{g(H; zBjD<}9~=ojlww z7!P(m!zX~9o6JQwTundYX;X{;QDCp9_#X{d%lWBI&Hjf_yAQ18E7#oX^aaK` zPMqVx_7y%8Uhbb0;QFX%|C|U`&;B_Mtdfc3XFla=eBZJTWf^o2UEYYHB|p@l!|jt0-KK)fLoq+o+9qC7f3@joLk< zpRwRK)au5%hFZ;gf#<`GU^UMiuNz~! z?l+-ni{F=OKj)+LyBS^EeB57c_hqo-T(yp&Ju$ulwl9B1T*kNsP1_mdY>cmhjiYYP zH&Cl3&TZiTl=IinwZ-rD+OIX|JJ7Wy=dXj!c{PeLv?s9+OKurKZ&j_bMynSZPo4XF>1BM`5`#{m2>?xy0-ZJsP?nJ z((lLU+S1=MVB4zO-&53TIb(hTo54{+nF$LD#l@t>;C=s$wh-l+Tg6WDg?PkY&){mL^>)`|TB zxa|K$_#ldUd|m>Vw6&^~4_lPW*EG1JSjm?c88B=OBH~1Gmqz-Mnb(X*VC(w(7}iez4=r{44<1 zPd)7x1e>q6_$>rh&pi4wR5ka})x>jOUP)~~Lzsufu$=*SUj2Eh+~=2Nuq_VWf?8d> zKYvxryet7$Yd!CmMAK%Q8;C7Wo29^MGmF?6@6zbnY~%e~o;J%AZOVCE7G0Zd?xKx6 zZI&zAJX!R!Ji0d9JV+b4*m>%Ki=Fpi_hGK<%%64gUWs;&G3&iDymgPQf~KBzTNP|O z^{m?vu)6D(>v1UD>v14O`()P4XXDkt+RSw@wLJN(0e1e9&zkVoeAYr!Pd;mdZKs}m z)&Z-R`K${!AJ0zh$!9&VHuLdk?(*cb0eEte&xY{Ud^SQ;Pd*!iZKs}mHUX=b`D_YL zKH8JdW?*gR^@9BJHlJ@*$GWO`Roj~oqF=w1*~4?GYp>j(Vl#E1#2^(?WyJFc&Qn`i9qXtvc)d)f{MyZ+&Og3DNY!4peg?TKYO?Pig;8VB>0Y4GyGMOUxs|#>{u-POzH3M^MYX7mTF# zUSRDz=+V?;D1Nk$t?kyv_SvxuY>f0Z4(yoI*Lbj6-q%b3+eY1IC;2Ffec89zSkBc^ zV8;@EG}yB@dwwEZAN8D%lfbTp=cD%Q@5x|o$+HJMxZqR3?zilZW58Kc+v=}R#x)hJ zk8{{fEl-})!DZev;O3q6Iu@>vdh$LFY=4ehd-6UWtSx!Z1ebZA059`C5uUtltG_cFVrwXHgYh&%cIF0&riXZJ~)OPE{IumS+@Uy`7mwj+H zSRZxwf&5g8vF%How&#F-<_|v??w-qguJgcZS94~^=X|*R=Uw6jVExp69`I**p9e2O z+(vwG+Fl602tD7Az5v(P`+?7i+8wuZV6N6_dl9(o_hPu3&qJA4wQ^n^bJ|}5F27G+ z3Rkmlzju5Q?8iCNb{R#@JjBLv4_yu}?`c=SXSLkZu0&H$-&cXldA%C0=Dg61vF-sILvBv@g4d@c zk8gq1a{b*0wvD=TEx(guU-m6d?EAsx_4jRfxlbN|tCiQ^gK+c7_4g21KlNOH-vKYd zb!L3+>F;51dHsDCu5YeC?aqU9Vy@O{`v|z~_j_=)Tz}fs%6WFo^6WEf<9Qv;0_XlL ze-!S%%l>~1tfrsqs7=jyW2nu~I{7^gcJ4ASPk_~upEfnykEFK!XzCZLIe)hDeRR(w z`+c&;w);Wd&f5L+L+Ym~ezgCnwp%B!AA^mN{qYP~Ex#8ae~Mx(a}uZRPr$Yf|0&pa z`B~?m!98d7(-yyH!P>%q4mQsAoFksk&w&TgPCY)q0ITQc1iu6uNBtSb>fZkqSUr3H z*I>28_zl>(%NqO^tfrrHsZGtfa^4)Tb=v<9Y@TWVd$3y8P@7u07S3DR{}Jr`g#QU{ zpBeWH;O8m&nU7o_@r%^1xv^gYo13-k{4(`lD1NlRQroT5*Q;P-WS##CR?9le|4cEK zvBj->FR@<3R*vI!xUuu|n!kaa6ZNdc-@)p4*7u5kfQ_T>`Ts9!Kb}e2{z*|Y7jgQ2 z16=m~Z+O}Fn{fM9Pv38W)${uiZ-b4ap1FSq?A&WhU+;p|!`}m!`{#YQnts_oYOXbC;FGD^N z1HrbaMxd3 z;;ao;&-t?s*x2gs?e(brIPcolrKmY(apJ5Gw*Rby+_{afwcL5Pt##UN0Cs*d_6@;m zxjwb2m22s|r~SrY=fb}I_ZafnHUYa9UuW)p7T*-C=H768n}hv0K5d&()XY(wI9q^? zllk2etX9tNR&eK6TiR_6RuA6>Y>tVuEm%#zYXTl zY`b%9w{~p(d2ZMNte@?~$!Qqa*x|c^9c!Lfb_4soqMx?-?GDx!z6aPi*>A(agJ`E7 zpFP3qd0yEIY#epRxC^yf{6~P*@+`9tSS{DhzF;-m?oBOE+x@_5;roM~`|O1S!1}1W z7Y?HK<9um5kfP>%iJjNXpL*gR0xtVG6ke|JVQ@A5vc_s@e>m8A%l*KkFD+2=H)rn1vbXrRrA^z4^|sT zagOApD8@3jIAiJtn@eIH1vXaBz@x#tbFHXnEhmE2GY^x%#!+`X6R6eF$7Hbc9Nq(V zuY^wl+a}Ln$AFzv_0t)XW1I?(o;;?Zsb`N)2OC>G`)~$WJ#CH!tK}R$4s3qv?yZ^B zew;UL$5YgtH*s=40c_4$OS$V4Uu(H*XIpFAI+hc`&av|+KMAaseWXpT+z+l@`u-ev z{(_$ZUXYS!lT*R{De76H)4;aV7VUJf`gQg5!O38?^m8V-{9UuN;M-Bs&)HzL3pqOy z^BnCIZHaR(*gY1X^T7J4=Xcc37gG)-mUDUrSS>L=4_3>Wbs_jreAVOg1+cp9FQAsk zb`e-DxnB%cJBt|k9kWZ|>W%)<<+dNf8hsI*pDkVnmix0s{}#mM;B~0gZF?!Tn)nK8 zfBu#@SHTnKO0Yb?t9CWmcQNXDhP?)??)}UCc^%k~`%~Ms6gBsl*na$XFE@Z^v91~a zjqs%@neUsxYQFo(oO}tcUcNWG8LplLmt$MP_`w)}3^ zcft0(D#aMuGvAMZTj%?GXzKZWm04h8sJq`EqxR!|*Y+qy&HXOUx;+l|T1#I~fbFYX z|L?=qA7RaW#(WZNJ9W?6#I?@*-XDPN*K13E`!uf~QYSBco}#FkmpFMn4KDNg5xh08 zAET*z9k_l!0joVj$-Mj&Y%Fc&n!c=)>(9XEV*dJ@hq?ZoI=SleEafj0a}{Tep9BA= zz3>ZkZSnhM?bo^&eub{>p?ZFQ4YsYidHj|-d1(6$hBr#eVHS{k{Nh?e|4A_4NA^xa{}OaDCL%@5|uK zqy5VDEBm#7xocw{u1BuV{EkL!*7{yo`&y^3SHbDa96ekAil!c)*J>Zee%j3K6>4?c_`c&G;Q0&wPw;}2+)w@m?oUzAz5flc?X-E{J&!p5 z2CLi0o78gqxB%PRVEfhf7PZ`ekHO_zy#v0O+BVvpqs6G5PwV9QF4(-1!+T&g|J{vo zwW-;DVQSkiO0DgE>U-%Uu|9y1j8CZLuBrXb1@`wBZ4>`CGiV}+%VQe|F5jii z4Oeq6yq4z!`|(`XHZNs6_l(g`TiR_6)@Drihdj1zz{bqAxGmf>M?F5rqw=1~3 zmUe@y1TkeBPY@apC{|{z7wpUx-k!-M0Rol3Myc6|ClS&6!|7AMrCi z^)o0+r}00eT%Ats^{<}xI}G4==i#}=c7&_tzM@Ud^TPPHH(uJG1@`YoEkl6eR$UR_c^`@zm(#$tp0L+wEMSpF0bvG zPkEX1mGJU=$W?IXJbUSCu$tdRvPRdyZKusXub@^-j@N?K@*U+mu$noYPfpi^&DnpK zVtcthws-tDf}LA!H&Dy9U54#TVB2cDiCUiTG&h5*V)kaJgr`0$0mA zeHHA-wbyowHj3*cPMq7o#>rZI4Sp*nYa!Ps zZ{L9HpLvt(llb2R`}b6wn>)dBZO+@>VB2cDi&~y}y9eyN*+!f5<{UU)$DR1!0%u+P z8!qzF*EaeNA=bCSIaBTj%k%F^9sqBFkGlEXN3E8A9s(Ob^Yk6~gOtpxTp#_t&pZq! zOvB&5FZW%z{+U;~K3S(n!1h^w|N9iaD^|4R?X3k?^|1OUCKMIy>qpF_Z zfBbtl+8zhXGuPh-UyqM%v?bn?U^UwqSDtu30PCyGxbn37Avk$F1(s{`?}Gmb>=Fdv6we^3xz1T1>vG*)|Mc;9u=ld?f4~P&(&sjKJes z!~R@tmzO!u1uvfw+TgB5o)OyNYUMLR2i$hr?9;zlsFoc2gVpkkFaWG(PCg?H1e!fWV$_f0pNwm9u;a?wECJU)Ya`c3f1eSS1eebU zOTqQeyvg-R{AIv-M)2=I%C$Lf%Ykj{y!kgF<(aqT!Ooj)v^j6if#Y@DiN7K^>*76J zUi#Wb-yy_W37qrVzcDHIydI2gW$-4{>gF?uS}pyo3ND`!hQR&1l$lq#KF*^*uN(?C zhVx>Kxv5u!tLNWYtq#7K>qb58)&Ltf^Doy=yU*Wif{kmx#%1ZMwczUUSsQGOtchG7 z{e6~L7o79kzojWpto6aU_xN`;0^1gkl3#+4`DMqqul8CRZmn}Cyt zf3s7rZ8&{w26ha#^Y3@clgH-Zlku^Qwv2lVaPAN3e@is=obg+M)yn(I*6_5mKe>M5 z@>wEht##sWgP&(#__px!p0XWWO+VvlQxn_H>$|*cK#i`TRF2pI% z_F-@}V|upl2KM8bp>0=+nsLQB+xGz9gr7O>4wk2n;o$OI+7qspKK2Itu@7x~Q4Xfq zhd6OYfQ=*fJlzLwUvkfteZih9BiPZG!S{pPMn7$7cK|r&$^Kxuc^^n^o9vN;z@8ua zXmbwD)x69v@eTo-hcUdq<)yD};(KV}YYuX4EJ<}3*tIZ@YwnIcQcCr9|`lKEkN-z zA7xYW8%RAr#r_wh&i_Bctzeq>@^7^82U_?eE&PdsKMnp-&2!Fu4Q{{XJ>Yh@`eWqk ze*8K`E%yL(Qp>^}vo<#!~02DXj5>;5eD z&nfN&*TX*L`X%Nsz>Y65e+gEL{a0Y~jQ!VOwesrWT`!~3Z`zBniyq?~IC$9FieH*OJxUQ)@ws*m0-1p&X?@^NP2jIljp0*!?wHepF zA&>22a2fYgxY{R_#QhAMxZ2Z}TSMdjo5#5BF?nolVAnF&T02}V_71RX5_^BRTCT+b zVB4tYS{w+Ti<0YKu3uu#4R$>ea~`-_?DK-1*VyNStEJER!M0IPp9_HP^Eui%PPu-G zxggj%P0WShYOya2c5Y%{1g@4o7X{l!J$)_)w$EH^a{Y|iI9F=BXU^i_oH@(T&+-&M z%ThdZmZDyc;+eAobXj*8o2ydiS{z2Z^4i>^g^y_A2ej}* zTX<&+A6xKl@KH6-`s@lfuku>m4NX1Q>h55*T&w1+mNgg-R?D@zCs?h#R`-HuFKJKP zy}{btOO9P0+dkkj?!Iuf@><;wp19i6c7L!o<2r}(*bW4jaSwv4&0-#MtsV?dTzc}A8woDsj)JR|*Xn3^;%ZOZF<@=R zb#KUH>jIZ?$HCRg=YjF?#MPd*6TsSx>mHNGb~MHW1kLI%NZ~OY@f!pt@fM&$AZm0XMkM)#6Aw} z_!Ikhu$t{>QlCJveXbq3KDHmsemfDY-7`d-Go(MZH7I^oqj-i4rCy!l8L}pI=J#{7 zQ!lUKQ_$3N4W9~DGmq@?)8JWK?HSYQU~T3kPEPaEb{&eJwJ6DHZLm45OYONfkor8@ zd9EeLv*7xbIi8KCo^#_Iu$ueYcRjX07q0F;Gp5}47v^$4cmZm4bCoAopPe?K_*svV zT-OJi>xR_kx-j)6v@3JH5UyXD>le_}lj}ubwdA@G{ujg5&DEH4b2XPs!G1?nH&=Ob z9gMyS#m`2R%YRPp){I7zmo2xP9`T4*# z;8p6r%vGLTz3**7@v|8vxo!?N*Da~d)o0N!(XPz(`bHmpbG-pgJ-OZpR!go+66Yqk zy15!tZm#BXGuY=~b#s*`*R9ZZp!nIAVy;_LZ&%}OsJEw>_l^zR{JFy|#MlmA&goat z)N_s83f>-{{G9G9a`ujDw?C&>lwdUG3=k>R6`*U7xH#ha~(9~TE?~A_&tEKNh zfYY}z?ORR1^!+@z?E8;!wOPc=p7;~ozMZeMdjU;7eZ2@yU&gR6HT}wW=&ti&6h8-3 zT<86%52^7%)Q3`B=fkP9&My(CT<1T-ZBx$u%V_FZ=f8l}vd+d(%NSk(t7V;E1*?_o z{8za7w661O=-M*=*TEUTaU8#ze(CRT;IhBJ!_~6R{{a7!Vt-lZ1Hk{P^{n$7aJBUP zZ*clHrhTjFm%iTwmwmqlSDQurtn=G&`!3h{9W?dy^)5Jl8N--^DE$eIywT%5Euv*snW3XCtotyWz zPvGWL_VX#4ddB`4IAb@4V^?eVRkMFiwT!(3tX7V_KiquEeg>eaXY2#P8M`qYyPAHj>pqQG zevY9y_9@g;DUNqKb@tobv{f(rod-=lTpDhSa{iVPlljwU%bI758^DcG&fkV;>Y2Zdz-s0E zZ4A%+X?Hwoez!^NP2jDuH$_v={@V^_o1Y6Q&fodeU#RitsV|~9f0s}@e?Hr8LmcNXW7-yOn{vLkLsQRuZ4Xv+ zzRc4YYL1~l+74i~%)yRewdQ@O`S(J0f}4;1sM~gK>YdTG<@sk9uv+d1!@yY=3?6aTKeA)oc@h#|7!ZB|NYe|>Hh$*+LJ~92g1{TIsSvt zwWa@q!D{LM5ODf8uKla&m;Mh`r=(UJI8}Us2;PQeR2&TDY1z*TP8Rl-I&2xNXX7VKkb0u7xpRwOk9v zP|IA51*>H)y1;79YoYl(Iu33=Wk2K5)HC)8;EdfEj$KW^^wkY6`#K7)mVNK_el*;^ z+;?Sv6VbJ$ze(WqXB_)e(=Yu^2ABQyz}03E+c@?&1#W-NPubrw=-SfXRB-w;j{T|W z*SfaX6U)yvl-wt-t+9PxM{#X$pw8N!K%DYEaazHBW<9gujeAYab1qJU+ebNu>1gVi zj~QV5&c6dZ4z7>-dyHo$wI6@KP22GlHFFi)*L~PO2R@nN8s+boo(flYE!{h(fSn`9 zr7by}4p#G7aRPp4fYtPM%yNBuu$={VOxhg3T$}CA0qd{rY-)M#L+8rzv5mI$eI7V{ z8~=Q`nlbE09^VUU-&_};hpRcR)0qeFBVPckUq~^AbF1d>`DNa$%l)wjJ~vVP+(>b5 zzeJsVa1H+MgXD1u{9;OePw`T)nse-$eG%-(HPdz(Ma{V4tl1Ud)-}5dO+9ONCD?IX zPOVLB-&a!{Q{q}DziYwz>uc`v*siZ_nZq04YS&THk6Qe11lwQc_a?BK`z*Pr#s5oS z`*bfkuQ!9$8t<5?^FGh_7PnCR+)VMB^g8@tNfcC+0W6>duQ}xf5(Z>W)?JSpOewC4u7r