From de0de43b0a7ec6367ff7a34ee80b16a7eec962b2 Mon Sep 17 00:00:00 2001 From: chengduoZH Date: Sun, 7 Jan 2018 18:20:39 +0800 Subject: [PATCH 1/6] add double buffering design doc --- doc/design/Double_Buffering.md | 85 ++++++++++++++++++ doc/design/images/buffering_cpu_gpu_async.png | Bin 0 -> 35678 bytes doc/design/images/buffering_cpu_gpu_sync.png | Bin 0 -> 40081 bytes 3 files changed, 85 insertions(+) create mode 100644 doc/design/Double_Buffering.md create mode 100644 doc/design/images/buffering_cpu_gpu_async.png create mode 100644 doc/design/images/buffering_cpu_gpu_sync.png diff --git a/doc/design/Double_Buffering.md b/doc/design/Double_Buffering.md new file mode 100644 index 00000000000000..141a8a438494c4 --- /dev/null +++ b/doc/design/Double_Buffering.md @@ -0,0 +1,85 @@ +# Double Buffering + +## Background + +In general, the model training is divided into two steps: data preparation and model calculation. Because training a deep learning model needs a lot of computing resources. If using CPU, it will take a long time to complete an iteration. Training a good model usually takes tens of thousands of iterations. Obviously, this is unacceptable. Therefore, in the case of conditions, we will generally choose the accelerator (e.g. GPU) for model training. But using accelerator for training model brings a new problem. Because our training data is in CPU, before the accelerator training model, it need to wait for the data to be copied from the CPU side to the accelerator. So the time to train the model on the accelerator is the sum of the time of loading the data, the time of data transfer, and the time of the accelerator calculation. Therefore, although the accelerator's computation speed is very fast, sometimes the data transfer time is very long, which may cause the accelerator training model to be slower than the direct CPU training model. + +## Problem +The data transfer between host and device is synchronized, by default. A time line for the execution of traing model on GPU is shown in the following diagram. This is just a schematic. + +![image](./images/buffering_cpu_gpu_sync.png) + +Obviously, the overlap between data transfers and other operations is zeros. +In depth analysis, we will find that data transfers and other operations can be overlapped. The GPU provided by NVIDIA generally has two engines: a copy engine and a computing engine. Therefore, this design document hopes to make full use of this characteristic to maximize the overlap of data transfers and other operations, and reduce data transfer delay in turn. + +## Solution +### Basic Strategy +#### Producer-Consumer +A feasible way is to adopt [producer-consumer](https://en.wikipedia.org/wiki/Producer–consumer_problem) model. The producer and the consumer share a common, fixed-size buffer used as a queue. Sometimes, the buffer's memory has up limit. The producer's job is to generate data, put it into the buffer, and start again. At the same time, the consumer is consuming the data, one piece at a time. The problem is to make sure that the producer won't try to add data into the buffer if it's full or it's memory is beyond the upper limit and that the consumer won't try to remove data from an empty buffer. +Caffe2 uses this way in [`PrefetchOperator`](https://github.com/caffe2/caffe2/blob/01827c153db96349745a544148c1ff0386c5ef9e/caffe2/operators/prefetch_op.h#L42). + +#### Staging area +Another feasible way is to adopt [staging area](https://en.wikipedia.org/wiki/Staging_(data)). Staging area is an intermediate storage area used for data processing during the [extract, transform and load (ETL)](https://en.wikipedia.org/wiki/Extract,_transform,_load) process. The data staging area sits between the data source(s) and the data target(s), which are often data warehouses, data marts, or other data repositories. +The staging area has fixed-size buffer and two methods, `put` and `get`. `put` and `get` access buffer in a thread safe way. The operation of `put` includes copying a data from CPU to GPU and putting data into buffer, and `get` removes a data from buffer. +When the program runs, the staging area should be warmed up. First, the `put` is called to put some data in the staging area in advance. After that, the `get` is called every time when the model is calculated, and a data is extracted from the staging area. At the same time, `put` is called, and a data is placed in the staging area. Because the data transfer is used asynchronous, so the `put` method will back immediately. +For single GPU, the program only has one staging area, this is very simple. For multiple GPU, the program have multiple staging area, and the number of staging area equals to the number of GPU. If model training uses data parallelism, assuming that there is a n fast GPU, `put` divides the data evenly into n portions and copys to the corresponding staging area. + +The following C++ programs shows the structure of buffer: +``` +using MetaType = LoDTensor; +using BufferElement = std::vector; + +class Buffer { + private: + std::size_t capacity_; + std::size_t bytes_limit_; + std::size_t current_bytes_; + std::mutex mu_; + std::condition_variable empty_cond_var_; + std::condition_variable full_cond_var_; + std::map> buf_; + + public: + void Put(BufferElement* tuple) {...} + void Get(BufferElement* tuple) {...} + size_t Size() {...} + void Clear() {...} +}; + +``` + +**Take the [recognize_digits_mlp](https://github.com/PaddlePaddle/Paddle/blob/develop/python/paddle/v2/fluid/tests/book/test_recognize_digits_mlp.py) as an example to show the model definition after using the staging area mechanism.** + +``` +image = fluid.layers.data(name='x', shape=[784], dtype='float32') +label = fluid.layers.data(name='y', shape=[1], dtype='int64') + +stage = fluid.staging(input=[image, label]) +stage_program = fluid.default_main_program().clone() +image, label = stage_out = fluid.unstaging(stage) + +y_predict = fluid.layers.fc(input=image, size=1, act=None) +cost = fluid.layers.square_error_cost(input=y_predict, label=label) +avg_cost = fluid.layers.mean(x=cost) +... +place = fluid.CUDAPlace(0) +exe = fluid.Executor(place) +feeder = fluid.DataFeeder(feed_list=[image, label], place=place) +exe.run(fluid.default_startup_program()) + +buffer_size = 2 +for pass_id in range(5): + for i in range(buffer_size): + exe.run(fluid.stage_program) + for data in train_reader(): + exe.run(fluid.default_main_program(), + feed=feeder.feed(data)) + for i in range(buffer_size): + exe.run(fluid.default_main_program()) +``` + + +## Reference +[Staging area](https://en.wikipedia.org/wiki/Staging_(data)) +[Producer-Consumer](https://en.wikipedia.org/wiki/Producer–consumer_problem) +[How to Overlap Data Transfers in CUDA C/C++](https://devblogs.nvidia.com/parallelforall/how-overlap-data-transfers-cuda-cc/) diff --git a/doc/design/images/buffering_cpu_gpu_async.png b/doc/design/images/buffering_cpu_gpu_async.png new file mode 100644 index 0000000000000000000000000000000000000000..9ad2f77fcf6611589b126ffc613458e16ec4c57c GIT binary patch literal 35678 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 XJ~@j50{`VV;2%j*IgyIb2LAsKWk;0x literal 0 HcmV?d00001 diff --git a/doc/design/images/buffering_cpu_gpu_sync.png b/doc/design/images/buffering_cpu_gpu_sync.png new file mode 100644 index 0000000000000000000000000000000000000000..4286518e0305fb7ce6175c8681ccf9803957568b GIT binary patch literal 40081 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ºwe7P$41BR$)UsnM zkDk+X5g!u6Bj9cU+6cqo-k-<5T+`0Y5}7zO&SN7S1Av?nq3t;H8QS7jE=ADb@@i+C znt2IVqQsfqNHmu_TmWJOnGoa2Vw2%D{l%=A6{itt>a{{i`l6lfXbp>I zDysu7gHnYpw-+CD&8bXHBE_0rq&}9NnOsk0yzkE=x9-M<%D{aGy7;*&WHC zwd;7*tX^us;I65uEt80ejWu|Ed9D`So@3U3UXYzi3I4&&aP*nQOo^T)%W8kl!Wf%? zUa*84XSU)N>k6b2dHso}&i8SiV(uD6n5I)D zh<)YjJO(Yg(ztzY1auJ>7Z*@x#e$SZpB$C(YPEs*^?GByY{3!GACb;V2xHflDmXa! zlVov7XV@+=Q?n=&$<060(Pe3sWvM``TT#&YA@yEE^Ahp&@0bws&=C_wc+LcXN<-?OeVnL~~PI7dWH%zh;Q8z_b#?Mg)CF9hHxtz^V>f zDrsOT-7Qk-j_CJ%RO9n6JY>`LS3h!2T4a`bl7k*{ax*_q_PP(%(^%n`jp~rfzidnM z@9$>+r{VG6r^F~MkOILuJF-HC!dGQ-ZFR#V01>cdY+@ky;^r`u{U&$U;66vtc6uWH z@WnIsYHvYq)40J7wd;dS(z>`{;9x!S=|5m44nr+E359o$vg6e zfQ2NAXR?ViJd_I*cDFc@MZ0Uddbwdo7wRtP{>} zl3g2zP_SKitSb^~f~rayrfWMp1g|(ioVb-(Jl(ZqW{_h;~izVPTCd+ME*RTQweCathKY#vYvRdW3zu(Q=KHKOK zid?L>paz(cu|98MfEM%VrsL84hGGuDBn13~jGJ3SSFdf2xSZet;Ft24ltB7oVPRPg z+c`1(c0U;kxzQ`dpoubKHIL$lL4LP9!+-F&-Q{-rNzJ9n26QDMM{WLia}wWw(y?~; zn$=P0aHjUU_FL=z;8BscHJr8?8o({&w)kBEQ*|J5&w)bSqzbzs6_77AMg%u&_-YY= z+NJh3_J!y-3S>J;S&0IN2&e0napp1S^|ah}+wE#>T-?V76SmUiK#gg?LU#+jzOd*> zo`(TFh8uvPnV@FXHbYsU4*k{x+IjQ=a@1(2VX_p-(rT?9H~OjU?9lO(ZH9OzFv9kiZI@nq3FMh2BbFt z6bfr9C*t9jh$hrBoO9+-iLJVI7j&I(UF0~C}%LSfJ2#6gIi#5dDVIAeX)EE`8CaA zv0UL0z}p~oP4@RYsCVIRnO%0hJ|J@qC}^N%V^g|H9J6Z2SCDE;}EoR#Pku0l+eui1e4JJ7}FSdKM^k3_z2TzaXM)DlE zmnI7TuCaN$aOL;w%3RZKsV?+dS^@!h=zkAFf9=T?dKn;}mJ}`@!uaq1pm&H$Pq#RF zyo}7iD}CF_p^O9Yx~0$?OvX44X?D*~J6>1+LBRi~heZKFT4sh^ZUho=JeJNygN6%? z`rql5zIa#O952D-iVT5Q&`r!h9NPlf4fz8s!}JC+pfjl~y{{C+bT)`8{ST^9S_yDR zKt*yA5IC}eXka$y1;{f-V;S6T9Jf79cEBXo$N_8|CpF+hPoSC4*1c)(FYo|-eWEB7 zB_eQEhr9SMNFx}>be{plG1v_6C9HbGO8ZW4h_2G&2r`d{{lYO^qcod9(a4Mz-b@(jO zBt6)H0R0polMFJ)4ga1MjWDf>`i+;y{QhEFsKM6O_WNwx-QAt4!C|w}ND>jPYOQs~ zBe2y1Uyn=!ufY@NLRBwU*SngL^RaLjyMz?=^v_O)9|GmJk z>-q84sbH?gWt6YV<*aEpBUUC?DA@{U`|#-}0**n82>=qC<|ll_C1HMjJ=8JIF6(%F zL`S$zD1S!<2DL$sit!-8B61906Lp30qBrh++aunRLP4RGhT4jRrnBX4Hjdy86c%7Y=Fpw%$;<4Wv_QG>882W0Gk2Tw^2q{lzf-Hb8f=`+9N`4w%i*=Ry$^lNnRB z!NI|pGv-#Z9$!K2STaceyf`S(h1RS?JOhxhR!*79U6R zqN9mAfu8If(WDw6owct-`F*kf4h<|PDUj>ELMa>*ve-aonXe;w-DiOdwyMoY5j%AOhX2{X!$q85B)`c0j!rw-5q&7uK^qW^#1vO zi7!lpL#DZOhqRL5J*={1=P_|@Pav|>cXzPKdU!dOj3-?uw3n5QESYqS@3S~PudI69 zYLM)EL%dDu1?157fi}h%WYxAHxJvr#`mlijNHpqyjEBHZVrbY$*SzyeV6!Ginvw)u zES=?exoN8D)U4mVD7hgY-#xwyjEw0_L6u=JeQP<=KRud6m?M?ZQ$|0>pxy zdY$zE%L2@j;an>AtJmv~i02PP`Wl(c$(lL}yGKqzF$`u5^|%IDf|(ek-@G&ciHw?& zSV<01%l3Q2;-VsJ{3%WV_Q9mrhiEcW5`TGTH_lDr`i>D0eEE-u28s!!CP^YihI7t` z+8GF$w$XG>CGdfm&gq1H*`<$wK^Hfg%7(K$>IG&Mg4tf94MZ+8UF!h2wPP%~CX)Lm zX|IA&uTSK3waoyi--O&sm3S-`zkmsdr3AX*G4+2s41zErDj?KW#PDjlozJqs$8%01 z!S7V0-?NC52U~?1t|fcgpp0~!h~wHR$yi@sNGvwXv?Sz@Q{N1p6+EUOc3duZf;Gi_ z{s-(jN{~E6CUE^TARC!LKAsduGGA#{P%Kj>5)~B{s+6x#b33Z)7t7@FaHnI*dRxG8 zXO>`cG<}%~2sfzInZ*n)^(EsZ@wiFyCoZBHOu8n68J{4~Z70A$akIxD zKPh->HYD@FgGP1oQt8Jf{U?ADTK|31$$^Mi=*~oc{#Jcp_})Jelw*e!pfTJ5B9DjS zL6@)s!JW(FyooXgp|n?!RrNjD75>=&yi;pffOdlA7RKu?{?{-43F) z=Dy4`t+%G&HI-2U2}2C;aL7vGIIO=s&_ot-`3yjh%P6I>=9WWN3dVsP0T%kj{)GL0 z$v-0|`gdN*b-nCDy-jZG?G4wxHc8hKRZ{a2*I$%C?$1O~{5J7d zoD9$gefafDz(^{BW0uMR-}-3p3%A>K%q&PPbaie&;pM63Xsx5eP z%WJm_2z)~i4u@$O=jZ2>fRxF^Txs>YsCFLUTJhD@Oh&FXS;lRShOf?l5gJ9GqljOh zcE8%nQuLo9lL=PSo>uM)U{Vwqj2nIi)Oz#?TwkVS#P;g#Net}rf}eN{}=Y6!*naqO4 z4XeD7v{`$Ly;n2_51dMJOEUKsgSt)6#qrg>EG&S;0%11*{4x(aE12Yxf}C4+OqF<; z$_$&rnH^6UrfZraD@ID;x!w$&?Ej$e@U?i=T)9KNymgaQ{3;FMJdtsnQa%MxwFz>~|Rsp9U%OB@{9 zpV^jEN370LinGG7gZ;y1ErJI0;^K?m#D^|9VT0*28{4BOqKoM%sTK?0n~u#3GgD}p zQVL1wt`&?`H!0VW^}3d04~LTlqm1Z4o;$t>B@<1r&VZj~Rp=i!STNEW$Xr|5k%*mb_v3Q!|I9?%R-9&g z40Zp||2lxXyRf&s&vpXkvbjlfKQ~H0xV7~5bZZ_#Dwaa>Q2S%0)9trGW3$YAZ0F#= zzMUhLwKhL-F|-!(!ER{cW#uuib5>xn_DAdvt=jPXlw`vABYiAf18t?i?|Q8U*2%Iw z=>+qNewe(`=7GZTbefwFB5R*(q=r%&V#+Ph^5@PNFLV^E!#XUY$+&V)y%4#pOT0a@ zsY`Eo;2%5`>a>r60hKAVnVhWbAFnmfL&RBp9(78N#=?#Wj)%3j{x`|ow_Z6@v&){c z5UOqAm<|E0*}e^im5y`e8bU9lO)g_J=Minc@@_8Nforj8d4V9?$A=W-`3~Ky$B7YaX^nz%TgTUn-znuuN3!6bv`sG*gc@eDeTRsC}1>$>oOGcItR-V^%I* zsqOW8mHQ+y^J2F%dN%(e|LG~6#m%u!8#LPJ*_>uDoPc#d*0Bzme6yE3c~SYSqa+-9 zT$5djVLEm-x}@;vqdZ}MTymQX));&P!3Mb!5nt1?uMHZAaay$l!+m}(H4JK1+;6@% zIFX;p#Lun08jw(n&+FzeqJ%;Cp~~>Rh5GP8-S|TsUM-E_XI}-a{7-_>^^+mQvQKg! zOM@saWdwkxuIWb=C?dgMl%HY0`@az-#QDQL-ezY+J}AKyJEC8|c6l$cv-()J>qcR> zld;RS>r+t2k7g}Qz+YIb{wje%Ry??8`!T~f$z4e!f$;rDy=U=Z2JHv*v^Zv0;V)sI z&0^oc-C;pYd<&?m-@Jnu@wEO>p4pDtz*`BKte2pDQ=%>(H1I)mU-?TjC=<>~JgvZa zJ$R|=F5`<@GLlv*DK%#t@Q2QHFJE2+pKhXQmU%or_qErmxmhBA%3v;M%y_`HOn?^k zhT;$}SzGz_W$`D$jTOe})cy|ZwBYvr!{p;B zi42#Aa2R&vdmNrFCpSCV_l@gC*~^ld9Qn_`VFlGjGMI&NWE@`XdOIH~8dkrj?69N~ znon-O?7dSq`;ZV)SbiS)(05o7LUD|+W8N!|WuGXT90sJZb7q`D5sa!eaTkSdM$sX{ zq!28U@b!?lXK5~9TOtsaR6UEFqSUnao&8V=u)mh%(o?ou zJ4g$yX0Tz&>>r$hmGZ?noh(1Vf9$up5)Im$46SUPAD6c&APg)BmnxAcBYK(^ zyGux5%eN|TLz{Bq@f(h3vwN*NT8<^qdJq0qmA~RX!DOlu`ewl3smWzy0qnaj5GP1y%4wQaPgKUxK1T3%%`VT@w@%AG;i%Z(X<<@aPmQA+O1kPpF&o2OwgnL~dk=@rTsKQF ze>DuXX;L3gUqzQs=C7c6H90v#oBs(5%B8}6hXxn*2F{tpr=amgc7?rZcWb2%iGhAs zJ3jEwd~NAjUoQ9WKKar=@{D4n`ck2a4;M2P%(myRFO_4sJlR$i5hAS&kW%eTSlNpO zh6d~^xW4EUqfr?P7*-nEFkJ1k#^?F`lI_(MR~ z8EaA%a;>ffWgjn2sVrkN7BvfofQrBR4?n(Z?89xZ8yZKlSQ@|J{#Spowc-_5?FH)K zBoC>Ch04^L9$jNaoV_oKi_aTds!A*R5)xpyTCao3k^QZtwqYZwNG#7bt16UUx5uw7 zOj_N}Vc0||yz-#_(}bTRn;(HBsoUib!JR1U;FCP-VC_eT8UJk8lvL(RSNpPo-nR%y zdXu$?`guW~6J?aUHqKT^J3MvyAsPG3NAH%`NKg+G%X_=iN{Eo;!!Dt>=zEH3Glzfa zw@VP-^gF=OI}s zmbESY=`|f!F3oFvzU`Rv|4cPhWm3jM`fS|`KiXI{MzO}c+^D|wT$L=f#4=mb{q5qn zVIJ@DbEA#&*0V=&jVV1#;*Ywp{({GX(Rw9BQ$mDa{0jMZccs0DtjnG%6n5&P#{k>nt5<*y!q7-l&hftK>e;bdMsqf9<-S1PaTb8BO8BKbEFYmBpB=4xiGd*CbRe<68 zI>lff^1fc(i%-69G4`=u?+9n)4y&iJG4UMO{|=I5tVV!%o$g?Az1{NJYq!!VHm&f$Ir`apX(g>7tCr zZ2HjWzY&J7e78)Ac$g4`p1o^eppQl?mCBG7XN)y3h(TOqhZ{4+T)C;$u(fjqRST=+ zktytdl}_Voes0#oP#&K@v~7YhtZzW5t<)Z1}hD5Bz^APQb>G=6{%kqTNJgIBKs_wn;Q7OJzOo zI`TUGHH#fWkE*dKYzB%ygqP-YoFU+UZ7kug=Z7TKCgSr0{rs6ou+MDZCmhM@Quuwd zsl0w)r4$bJqd#52`wsNiwZpn$^1g9;i7M$S4yQ`FdVz<>MM=%;Vd%T_{*qy0ka(O( znt~pYki5Ktprga>NkI;@L%`R&Y1|W{kE5wLVx!H4uDC5}IA<5)R&yLtc&M3*`Foh5 zU1}{TxM9>1w`YE3w=ycl8g-Amyxsh6e06Hw(TD`?P7y&sbu?Cw2m8P6Qv0SY*xucK zCE%K`gy|{)f4bGU21(_>a-|mf?Mu5F0`$kJd#X!6vm3UdFltf!5rT}m-qs_Q!!?{J z53zBo!6n~l@tZ@63#Y->A9pfX@;ysgw}KDbN8AODRGz(BWc4ShJMF{g2RTk>s^ycO zM2(ixA(~zL9jGm{Q2Ax@NMmuiomZVpAT8n1OVOW^jRqMrNK1h?dVjPUj9uBtS@5=U z(oUxHKXI%vAsh%kZ^@RKhXGdB3#FS9)FmT3A@$092qoOS$NYdEwqJ&rYMMKuu*YHe zxjZqr<%C3$&}_}53E$U}-?CRec9ntr0h>doNKwq#&V7dM z5!NES7+FP;4bwxZNTusw@JqCcOtvcRuRn01zfYshRdk5u0v@XkAZ5l3CK>c*@j*Lh z`wcmfsy~SzPU|{4!cO$iN%TgDN7jnm)(Vi0tP+}BmHL`4?naHv$09a=wCF^IO^$Wo zJoMkElx;9TRLKYg*`>KIh;`|*718nvAU;#^(n#F?uAg~V;X(m1+TYC?*e9cc#_sw> zAe8Mf%b!kK)Mb|EY905Gm?a`SmGk}tZs2)?J>`puY;IVyw4!1_c>!i!ui%Y@=eF!v zRU-%Q(RlGxqcLJ$KTCRasu|;nDi^mNi%TRPr{PD?xhEhuno^-4Li1ILY|i#=`$ARe zY&I5Ce}Cckb~9Sd5#4MSPeNRdJnHR5YHnxXLr&g2T{QfaoUg3jGxVO zi>4AMe`rcJX}uCU^q`m-B+(9V2QAB<-=L1K&6=(@1}Mc&t<1E1SN1>2R_I^0Y+EuC z1Y$3$^=BW373)Lg)T$(BJzqupwUS%?T#3Wo9>|f5YwVPf)UZ@CsPU|g&&uppywm<0 z-08ig(?IxnKldWZti71RfP1#6O`1xM*nl5H7x^0YwmOAaBZZ^!o+Rw`_SGUbJ2R<%P%Dz*9+<>QGV{;&DnCQ&J6!ZXG5}#stXZM z2T^p?#qfTHU~#hn^U}mTp0@KyqGpVfb|>B*4z-`y&ZED1-CV(ZZar6hqxtrJKGgpN`|WLr;qHDGXh3AbME0Ew(nD z%V0kS3!666^hnc_XxNIn4G4&X0%UsTG0KsfnvXDSs;%&hw>E4^Oq-D zV`mW5(mBgXkdI`f##!XLUfj3Twu3D} zqEUV6iOK7*5VL7=@%Qmvqw?e>)L1gB@0_sgRxB|Q2Vx=TQYLR*w@SWN#NMeZ=hGnq zlHHhAcBXEg4Ü|Jd?YBHe%FZ~6NMm!AH(wyqu!1HlS4+V0H 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 Date: Mon, 8 Jan 2018 18:00:36 +0800 Subject: [PATCH 2/6] refine doc --- doc/design/Double_Buffering.md | 52 +++++++++++++------ doc/design/images/buffering_cpu_gpu_sync.png | Bin 40081 -> 37349 bytes 2 files changed, 35 insertions(+), 17 deletions(-) diff --git a/doc/design/Double_Buffering.md b/doc/design/Double_Buffering.md index 141a8a438494c4..46ca1e27b19005 100644 --- a/doc/design/Double_Buffering.md +++ b/doc/design/Double_Buffering.md @@ -2,27 +2,30 @@ ## Background -In general, the model training is divided into two steps: data preparation and model calculation. Because training a deep learning model needs a lot of computing resources. If using CPU, it will take a long time to complete an iteration. Training a good model usually takes tens of thousands of iterations. Obviously, this is unacceptable. Therefore, in the case of conditions, we will generally choose the accelerator (e.g. GPU) for model training. But using accelerator for training model brings a new problem. Because our training data is in CPU, before the accelerator training model, it need to wait for the data to be copied from the CPU side to the accelerator. So the time to train the model on the accelerator is the sum of the time of loading the data, the time of data transfer, and the time of the accelerator calculation. Therefore, although the accelerator's computation speed is very fast, sometimes the data transfer time is very long, which may cause the accelerator training model to be slower than the direct CPU training model. +In general, the model training is divided into two steps: data preparation and model calculation. Because training a deep learning model needs a lot of computing resources. If using CPU, it will take a long time to complete an iteration. Training a good model usually takes tens of thousands of iterations. Obviously, this is unacceptable. Therefore, we usually choose the accelerator (e.g. GPU) for model training. But using accelerator for training model brings a new problem. Because our training data is in CPU, before the accelerator training model, it need to wait for the data to be copied from the CPU side to the accelerator. So the time to train the model on the accelerator is the sum of the time of loading the data, the time of data transfer, and the time of the accelerator calculation. Therefore, although the accelerator's computation speed is very fast, sometimes the data transfer time is very long, which may cause the accelerator training model to be slower than the direct CPU training model. ## Problem -The data transfer between host and device is synchronized, by default. A time line for the execution of traing model on GPU is shown in the following diagram. This is just a schematic. +The data transfer between host and device is synchronized, by default. If the accelerator is `GPU`, a time line for the execution of traing model on `GPU` is shown in the following diagram. This is just a schematic. -![image](./images/buffering_cpu_gpu_sync.png) +


-Obviously, the overlap between data transfers and other operations is zeros. -In depth analysis, we will find that data transfers and other operations can be overlapped. The GPU provided by NVIDIA generally has two engines: a copy engine and a computing engine. Therefore, this design document hopes to make full use of this characteristic to maximize the overlap of data transfers and other operations, and reduce data transfer delay in turn. +In the schematic we assume that the time required for loadding data, data transfer, and kernel execution are approximately the same. Obviously, the overlap of loading data, data transfer and kernel execution is zeros. +In depth analysis, we will find these stages can be overlapped. In general, the GPU provided by NVIDIA generally has two engines: a copy engine and a computing engine, some device has three engines, two copy engines, one for host-to-device transfers and another for device-to-host transfers, as well as a single kernel engine. To overlap them, We need to use the [stream mechanism](https://devblogs.nvidia.com/parallelforall/gpu-pro-tip-cuda-7-streams-simplify-concurrency/) provided by CUDA. If data transfer and kernel execution are in different streams, and the kernel will not use the data being transferred, then data transfer and kernel execution can be done at the same time on GPU. +Therefore, this design document hopes to make full use of this characteristic to maximize the overlap of data transfers and other operations, and reduce data transfer delay in turn. ## Solution ### Basic Strategy #### Producer-Consumer A feasible way is to adopt [producer-consumer](https://en.wikipedia.org/wiki/Producer–consumer_problem) model. The producer and the consumer share a common, fixed-size buffer used as a queue. Sometimes, the buffer's memory has up limit. The producer's job is to generate data, put it into the buffer, and start again. At the same time, the consumer is consuming the data, one piece at a time. The problem is to make sure that the producer won't try to add data into the buffer if it's full or it's memory is beyond the upper limit and that the consumer won't try to remove data from an empty buffer. -Caffe2 uses this way in [`PrefetchOperator`](https://github.com/caffe2/caffe2/blob/01827c153db96349745a544148c1ff0386c5ef9e/caffe2/operators/prefetch_op.h#L42). +Caffe2 uses this way in [`PrefetchOperator`](https://github.com/caffe2/caffe2/blob/01827c153db96349745a544148c1ff0386c5ef9e/caffe2/operators/prefetch_op.h#L42). +For fluid, data loadding is done in python, so the python side can adopt producer-consumer model to load data. [This is what fuild is currently using](https://github.com/PaddlePaddle/Paddle/blob/ce6dad3b35c85d133e7c35249cced9df4dc0f05e/python/paddle/v2/reader/decorator.py#L165). #### Staging area Another feasible way is to adopt [staging area](https://en.wikipedia.org/wiki/Staging_(data)). Staging area is an intermediate storage area used for data processing during the [extract, transform and load (ETL)](https://en.wikipedia.org/wiki/Extract,_transform,_load) process. The data staging area sits between the data source(s) and the data target(s), which are often data warehouses, data marts, or other data repositories. -The staging area has fixed-size buffer and two methods, `put` and `get`. `put` and `get` access buffer in a thread safe way. The operation of `put` includes copying a data from CPU to GPU and putting data into buffer, and `get` removes a data from buffer. -When the program runs, the staging area should be warmed up. First, the `put` is called to put some data in the staging area in advance. After that, the `get` is called every time when the model is calculated, and a data is extracted from the staging area. At the same time, `put` is called, and a data is placed in the staging area. Because the data transfer is used asynchronous, so the `put` method will back immediately. -For single GPU, the program only has one staging area, this is very simple. For multiple GPU, the program have multiple staging area, and the number of staging area equals to the number of GPU. If model training uses data parallelism, assuming that there is a n fast GPU, `put` divides the data evenly into n portions and copys to the corresponding staging area. +The staging area has one fixed-size buffer and two methods, `put` and `get`. `put` and `get` access buffer in a thread safe way. The operation of `put` includes copying a data from data set(on CPU side) to GPU and putting data into buffer, and `get` removes a data from the buffer. +When the program runs, the staging area should be warmed up. First, the `put` is called to put some data in the staging area in advance. After that, the `get` is called every time when the model is calculated, and a data is extracted from the staging area. At the same time, `put` is called, meanwhile a new data is copied from the data set to the stage area. Because the operation of data transfer is asynchronous, so the `put` method will back immediately. +This strategy can be used to overlap data transfer between host and device and kernel execution. + The following C++ programs shows the structure of buffer: ``` @@ -37,7 +40,7 @@ class Buffer { std::mutex mu_; std::condition_variable empty_cond_var_; std::condition_variable full_cond_var_; - std::map> buf_; + std::deque buf_; public: void Put(BufferElement* tuple) {...} @@ -46,6 +49,16 @@ class Buffer { void Clear() {...} }; +Buffer* GetBuffer(const platform::Place place, const size_t capacity, + const size_t bytes_limit) { + static std::map buffering; + + if (buffering.count(place)) { + buffering[place] = new Buffer( + capacity, bytes_limit); + } + return buffering[place]; +} ``` **Take the [recognize_digits_mlp](https://github.com/PaddlePaddle/Paddle/blob/develop/python/paddle/v2/fluid/tests/book/test_recognize_digits_mlp.py) as an example to show the model definition after using the staging area mechanism.** @@ -56,26 +69,31 @@ label = fluid.layers.data(name='y', shape=[1], dtype='int64') stage = fluid.staging(input=[image, label]) stage_program = fluid.default_main_program().clone() + image, label = stage_out = fluid.unstaging(stage) y_predict = fluid.layers.fc(input=image, size=1, act=None) cost = fluid.layers.square_error_cost(input=y_predict, label=label) avg_cost = fluid.layers.mean(x=cost) + ... place = fluid.CUDAPlace(0) -exe = fluid.Executor(place) -feeder = fluid.DataFeeder(feed_list=[image, label], place=place) -exe.run(fluid.default_startup_program()) +... buffer_size = 2 + +# warm up staging area +for i in range(buffer_size): + data = next(train_reader()) + exe.run(fluid.stage_program, feed=feeder.feed(data)) + for pass_id in range(5): - for i in range(buffer_size): - exe.run(fluid.stage_program) for data in train_reader(): exe.run(fluid.default_main_program(), feed=feeder.feed(data)) - for i in range(buffer_size): - exe.run(fluid.default_main_program()) + +for i in range(buffer_size): + exe.run(fluid.default_main_program()) ``` diff --git a/doc/design/images/buffering_cpu_gpu_sync.png b/doc/design/images/buffering_cpu_gpu_sync.png index 4286518e0305fb7ce6175c8681ccf9803957568b..2acd98d1ce9076daa3212957b7d995ed00e8daf4 100644 GIT binary patch delta 33785 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%0Dqn)>%9aC}dBaBGKG{k^})0W6+l!dg)g_L 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%0D0@IR_WB@oBVdh= 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 Wrui>p#7_z_0D-5gpUXO@geCyU*mdpz From 4515f341c18f9f445e0d00782044cfcec6429548 Mon Sep 17 00:00:00 2001 From: chengduoZH Date: Wed, 10 Jan 2018 15:43:18 +0800 Subject: [PATCH 3/6] double_buffer -> concurrent_data_transfer_and_kernel_execution --- doc/design/Double_Buffering.md | 103 ------------------ ...rent_data_transfer_and_kernel_execution.md | 97 +++++++++++++++++ doc/design/images/buffering_cpu_gpu_async.png | Bin 35678 -> 0 bytes doc/design/images/buffering_cpu_gpu_sync.png | Bin 37349 -> 0 bytes doc/design/images/gpu_async.png | Bin 0 -> 26536 bytes doc/design/images/gpu_sync.png | Bin 0 -> 26105 bytes 6 files changed, 97 insertions(+), 103 deletions(-) delete mode 100644 doc/design/Double_Buffering.md create mode 100644 doc/design/concurrent_data_transfer_and_kernel_execution.md delete mode 100644 doc/design/images/buffering_cpu_gpu_async.png delete mode 100644 doc/design/images/buffering_cpu_gpu_sync.png create mode 100644 doc/design/images/gpu_async.png create mode 100644 doc/design/images/gpu_sync.png diff --git a/doc/design/Double_Buffering.md b/doc/design/Double_Buffering.md deleted file mode 100644 index 46ca1e27b19005..00000000000000 --- a/doc/design/Double_Buffering.md +++ /dev/null @@ -1,103 +0,0 @@ -# Double Buffering - -## Background - -In general, the model training is divided into two steps: data preparation and model calculation. Because training a deep learning model needs a lot of computing resources. If using CPU, it will take a long time to complete an iteration. Training a good model usually takes tens of thousands of iterations. Obviously, this is unacceptable. Therefore, we usually choose the accelerator (e.g. GPU) for model training. But using accelerator for training model brings a new problem. Because our training data is in CPU, before the accelerator training model, it need to wait for the data to be copied from the CPU side to the accelerator. So the time to train the model on the accelerator is the sum of the time of loading the data, the time of data transfer, and the time of the accelerator calculation. Therefore, although the accelerator's computation speed is very fast, sometimes the data transfer time is very long, which may cause the accelerator training model to be slower than the direct CPU training model. - -## Problem -The data transfer between host and device is synchronized, by default. If the accelerator is `GPU`, a time line for the execution of traing model on `GPU` is shown in the following diagram. This is just a schematic. - -


- -In the schematic we assume that the time required for loadding data, data transfer, and kernel execution are approximately the same. Obviously, the overlap of loading data, data transfer and kernel execution is zeros. -In depth analysis, we will find these stages can be overlapped. In general, the GPU provided by NVIDIA generally has two engines: a copy engine and a computing engine, some device has three engines, two copy engines, one for host-to-device transfers and another for device-to-host transfers, as well as a single kernel engine. To overlap them, We need to use the [stream mechanism](https://devblogs.nvidia.com/parallelforall/gpu-pro-tip-cuda-7-streams-simplify-concurrency/) provided by CUDA. If data transfer and kernel execution are in different streams, and the kernel will not use the data being transferred, then data transfer and kernel execution can be done at the same time on GPU. -Therefore, this design document hopes to make full use of this characteristic to maximize the overlap of data transfers and other operations, and reduce data transfer delay in turn. - -## Solution -### Basic Strategy -#### Producer-Consumer -A feasible way is to adopt [producer-consumer](https://en.wikipedia.org/wiki/Producer–consumer_problem) model. The producer and the consumer share a common, fixed-size buffer used as a queue. Sometimes, the buffer's memory has up limit. The producer's job is to generate data, put it into the buffer, and start again. At the same time, the consumer is consuming the data, one piece at a time. The problem is to make sure that the producer won't try to add data into the buffer if it's full or it's memory is beyond the upper limit and that the consumer won't try to remove data from an empty buffer. -Caffe2 uses this way in [`PrefetchOperator`](https://github.com/caffe2/caffe2/blob/01827c153db96349745a544148c1ff0386c5ef9e/caffe2/operators/prefetch_op.h#L42). -For fluid, data loadding is done in python, so the python side can adopt producer-consumer model to load data. [This is what fuild is currently using](https://github.com/PaddlePaddle/Paddle/blob/ce6dad3b35c85d133e7c35249cced9df4dc0f05e/python/paddle/v2/reader/decorator.py#L165). - -#### Staging area -Another feasible way is to adopt [staging area](https://en.wikipedia.org/wiki/Staging_(data)). Staging area is an intermediate storage area used for data processing during the [extract, transform and load (ETL)](https://en.wikipedia.org/wiki/Extract,_transform,_load) process. The data staging area sits between the data source(s) and the data target(s), which are often data warehouses, data marts, or other data repositories. -The staging area has one fixed-size buffer and two methods, `put` and `get`. `put` and `get` access buffer in a thread safe way. The operation of `put` includes copying a data from data set(on CPU side) to GPU and putting data into buffer, and `get` removes a data from the buffer. -When the program runs, the staging area should be warmed up. First, the `put` is called to put some data in the staging area in advance. After that, the `get` is called every time when the model is calculated, and a data is extracted from the staging area. At the same time, `put` is called, meanwhile a new data is copied from the data set to the stage area. Because the operation of data transfer is asynchronous, so the `put` method will back immediately. -This strategy can be used to overlap data transfer between host and device and kernel execution. - - -The following C++ programs shows the structure of buffer: -``` -using MetaType = LoDTensor; -using BufferElement = std::vector; - -class Buffer { - private: - std::size_t capacity_; - std::size_t bytes_limit_; - std::size_t current_bytes_; - std::mutex mu_; - std::condition_variable empty_cond_var_; - std::condition_variable full_cond_var_; - std::deque buf_; - - public: - void Put(BufferElement* tuple) {...} - void Get(BufferElement* tuple) {...} - size_t Size() {...} - void Clear() {...} -}; - -Buffer* GetBuffer(const platform::Place place, const size_t capacity, - const size_t bytes_limit) { - static std::map buffering; - - if (buffering.count(place)) { - buffering[place] = new Buffer( - capacity, bytes_limit); - } - return buffering[place]; -} -``` - -**Take the [recognize_digits_mlp](https://github.com/PaddlePaddle/Paddle/blob/develop/python/paddle/v2/fluid/tests/book/test_recognize_digits_mlp.py) as an example to show the model definition after using the staging area mechanism.** - -``` -image = fluid.layers.data(name='x', shape=[784], dtype='float32') -label = fluid.layers.data(name='y', shape=[1], dtype='int64') - -stage = fluid.staging(input=[image, label]) -stage_program = fluid.default_main_program().clone() - -image, label = stage_out = fluid.unstaging(stage) - -y_predict = fluid.layers.fc(input=image, size=1, act=None) -cost = fluid.layers.square_error_cost(input=y_predict, label=label) -avg_cost = fluid.layers.mean(x=cost) - -... -place = fluid.CUDAPlace(0) -... - -buffer_size = 2 - -# warm up staging area -for i in range(buffer_size): - data = next(train_reader()) - exe.run(fluid.stage_program, feed=feeder.feed(data)) - -for pass_id in range(5): - for data in train_reader(): - exe.run(fluid.default_main_program(), - feed=feeder.feed(data)) - -for i in range(buffer_size): - exe.run(fluid.default_main_program()) -``` - - -## Reference -[Staging area](https://en.wikipedia.org/wiki/Staging_(data)) -[Producer-Consumer](https://en.wikipedia.org/wiki/Producer–consumer_problem) -[How to Overlap Data Transfers in CUDA C/C++](https://devblogs.nvidia.com/parallelforall/how-overlap-data-transfers-cuda-cc/) diff --git a/doc/design/concurrent_data_transfer_and_kernel_execution.md b/doc/design/concurrent_data_transfer_and_kernel_execution.md new file mode 100644 index 00000000000000..a6eea326ac1a39 --- /dev/null +++ b/doc/design/concurrent_data_transfer_and_kernel_execution.md @@ -0,0 +1,97 @@ +# Design Doc: Concurrent data transfer and kernel execution. +Training deep learning model on GPU involves three stages: loading data from disk, copying the data from the CPU side to the GPU side, and executing training program on GPU. We need an efficient mechanism to take full use of hardware resources to make those stages executed concurrently. At present, Fluid uses producer-consumer mechanism at the python side to load data from disk. So this design doc mainly solves the time overlap of data transfer and kernel execution. + +## Challenge + +The data transfer between CPU and GPU is synchronized, by default. A timeline for the execution of training model on `GPU` is shown in the following diagram. + +


+ +In the schematic, we assume that the time required for data transfer and kernel execution is approximately the same. Obviously, the overlap of these operations is zeros. Our target is making use of the hardware resource to parallel data transfer and kernel execution. Just like the following schematic shows. + +


+ +## Solution +One feasible method is to use [staging area](https://en.wikipedia.org/wiki/Staging_(data)). A staging area is an intermediate storage area used for data processing during the [extract, transform and load (ETL)](https://en.wikipedia.org/wiki/Extract,_transform,_load) process. The data staging area sits between the data source(s) and the data target(s), which are often data warehouses, data marts, or other data repositories. +The staging area has one fixed-size buffer and two methods, `put` and `get`. `put` and `get` access buffer in a thread-safe way. The operation of `put` puts data into the buffer, and `get` removes a data from the buffer. When the program runs, the staging area should be warmed up. At first, `put` is called to put some data in the staging area. After that, `get` is called when the kernel begins executing, and one data is extracted from the staging area. At the same time, `put` is called and a new data is copied from CPU side to the staging area. Because the operation of data transfer is asynchronous, so the `put` method will return immediately. + +The GPU provided by NVIDIA generally has two engines: a copy engine and a computing engine. To make two engines working at the same time, we need to use the [stream mechanism](https://devblogs.nvidia.com/parallelforall/gpu-pro-tip-cuda-7-streams-simplify-concurrency/) provided by CUDA. As long as data transfer and kernel execution are in different streams and the kernel does not use the data being transferred, the data transfer and kernel execution can be done at the same time on GPU. + +To support the above description, we need to define a new class: `Channel`. Here, we borrow the concept of [`Channel`](https://www.golang-book.com/books/intro/10#section2) in the go language. + +``` +template +class Channel { + private: + using ChannelElement = std::vector; + + std::size_t capacity_; + std::size_t bytes_limit_; + std::size_t current_bytes_; + std::mutex mu_; + std::condition_variable empty_cond_var_; + std::condition_variable full_cond_var_; + std::deque channel_; + + public: + explicit Channel(std::size_t capacity, std::size_t bytes_limit); + + void Put(ChannelElement* buffer_element) { ... } + void Get(ChannelElement* buffer_element) { ... } + size_t Size() { ... } + void Clear() { ... } +}; +}; +``` + +**Take the [recognize_digits_mlp](https://github.com/PaddlePaddle/Paddle/blob/develop/python/paddle/v2/fluid/tests/book/test_recognize_digits_mlp.py) as an example to show the model definition after using the staging area mechanism.** + +``` +... +concurrent_program = Program() +with program(concurrent_program): + image = data_layer(...) + label = data_layer(...) + places = get_places() + channel_list = create_channel_list(name="data_buffer") + with parallel.for(places) as for_loop: + cur_channel = create_channel(channel_list, for_loop.i, channel_size=2) + # if channel_list has the specific channel, + # this function will return it directly. + send_to_channel(input=[for_loop.input(image), + for_loop.input(label)], out=cur_channel) + +main_program = Program() +with program(main_program): + places = get_places() + channel_list = create_channel_list(name="data_buffer") + with parallel.for(places) as for_loop: + cur_channel = get_channel(channel_list, for_loop.i) + image, label = receive_from_channel(input=cur_channel) + + y_predict = fluid.layers.fc(input=image, size=1, act=None) + cost = fluid.layers.square_error_cost(input=y_predict, label=label) + avg_cost = fluid.layers.mean(x=cost) + .... + +for i in range(buffer_size): + data = next(train_reader()) + executor.run(concurrent_program, feed=feeder.feed(data)) + +for pass_id in range(PASS): + for data in train_reader(): + executor.run(concurrent_program, feed=[...]) + executor.run(main_program, fetch=[...]) + +for i in range(buffer_size): + executor.run(main_program, fetch=[...]) + +``` +In Python code, we define two `program`, `concurrent_program` used to send data into `Channel` and `main_program` used to get data from the `Channel` and execute training. If you're familiar with [`Goroutine`](https://www.golang-book.com/books/intro/10#section1) in the go language, you'll find that `main_program` and `concurrent_program` just like two `Goroutine`. + + + +## Reference +[Staging area](https://en.wikipedia.org/wiki/Staging_(data)) +[Producer-Consumer](https://en.wikipedia.org/wiki/Producer–consumer_problem) +[How to Overlap Data Transfers in CUDA C/C++](https://devblogs.nvidia.com/parallelforall/how-overlap-data-transfers-cuda-cc/) diff --git a/doc/design/images/buffering_cpu_gpu_async.png b/doc/design/images/buffering_cpu_gpu_async.png deleted file mode 100644 index 9ad2f77fcf6611589b126ffc613458e16ec4c57c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35678 zcmeFYQ*>qRwl*4@72CG03M)>2-007u;VnW{m06_gde-A)_eSTY~-}VClz@VE73d(*H z6vUUcvoSCJn^%~1ai0ZD@ZNRiDZ;1<8m^{ZP%3@G5sSNx*ISYglw zzc7ffunHgY7F7QEuy$&o`xgA1oU(9GEK2Ji04?WK8(bS~5APiI6UiTG$<4`t{ObuM z2nIP&00vh#0kQ8|V~+tsq(_MS08r!rz+lu)6j1Tg{E4 zx3hb(o%c>-bnPOEO67z6r4ykWHA25H+t1cLM6}48boU`%dE?v$8N0B*b;H7 z!w|F@oBO(3WfKyQ-_f-rcG~}Fl|qhhH0$M)egbO_h7KUj8oY-D!%#*tf?(L^5~XLJ zAiE8HHchXkrE^OzjcOzsH6VKPl&njTYnxDL3p{AU!nVL>HbxqFfCj;!VS1SDS9i!x zA#*FqOUDYM#}UG1$CTqI>WPP%=NcTj1R)%&H}QL|NNz(c-y`2KH#Io@(#EP zKg4%Hw4`XW0q$*L9*@TeAka;jkS2WR)k%q8qo7Z+ABGxKo+f_Oh=93$*`bvO z*KE+ZL3nv|Y6oy^3mNzdUKfjmv~%DYd=5pKF%G(e%9wPKfYv*wL3`QIjL7zT@J6@P zxqFbll5HVwfn}%KfcN|&lMJLGVEe+W55~(8}%BU z{6J4<8Q~{SwvHK0|4Fuvu)gHi{8h_L4R;2~E4F!zpLa#?%gpkx5k!Ei2hHavm);nU zM#O=9>z1^i0POMnhR19;67W7mG5}efF9kF1u#F3t08x%r!aW|vaAz-XI*9s&pu;M4ekV*!dXz^XBK7W8=3fc;s>Wq?@xB#Tf^KAcr(*Z||3 zpUHC5GL5Ls(1k3?ZMFh(sfO=OP8T@`SP@!Dm%hU}N6EQv772|6^GMZ6R8pEhv- zO9|W00yRNwfhy-WpW-n=a)WA*Sm$q@Mmt0RqgRdaJ<{1vBHE7()DKmGBJD%fBT?Z{ z@@LU2x2dSqU0VdWM=+r^kI~`Q;lW|e-NId6 z3{VVU4C7=QjHoe<{A}=%l zfdVN$G7dO?CSD@`fwGYbzJ$DZv81nLOs@DlN5QZ0F7%)Xei2fAmK}f{(w!NQamWm$ zCL|?Ele8(8t@dLfMR>&uv(RJSIjoY**(9?LGYm8Hxs*BFqMhS{WBEDbQsvT2MZBaU z?rB3pcfH|0V5AGPEX)GTSj-z{Clifn^k1{TZWoYEtbTEqb7b{TT~CQGs8u>@lxn9| zoE41EXjOWCec_M~JQ^M|P@404Qg(071#d^qBr%01*b&Oa<) zFrUGiU6_ZT%dFhU@?PK{=$ghK*U9a6^?wKw39=0ug-M0Y#3;rD#Y918L0@Alz-Yxf zKwm)DW+O;pPccZcU^t=|mO7K1kt~(0OvyI7H{!0PF-rdl@iUF|ifm4@#Za2%fq9b6 zn*O3%M6%?y?AA51=Xlyt9c{V49&1*s(NE< z6xV3`z*}r^2KbF|$M(o}%MRHfT}WqIRz{bE$v0w>0n&4E?38^j%ig+< zBd3}0!i_XtX8nnXaHct9qX}+S2`^Oh`EKH`-!*=n=S`N`D8ZVObI`lmU*oT&w#UBt z?R2Y79v!sUjW)^1Ysim$&&Y2nsE|05v6rEe!P<1ap>(bM1^lbApmP#pvS=KAIAU}) zQFuapgtJF^+xT+Qz}#?h_#8P2G7NN$V}b+A4lJ;{N3&V%JYqG0+t6jUnUE3njre%j zd9-rmgPzOjzMCV={?Wc-j3vEQ?|cTR(@%SU>t^w0dH-Zgo3Yc__rUKAIyP_^dIj}} zhEi>|anaj$?aRoI2$D`THPi%@4o%F)x_Yr%6I;0pnRh-GR%I-nw>RA0>6e zdduRdU{lMGyHQy`ox#E|mw%Jqt znq#b^@iETviL?2s)|wA%2e`Q~U#`T5V(O(5CtDlTUZp%G_I1ZeBh_<*6ocVW z(P`xD3=ZFI>^2pSi`N@eEgz%@GdsMDj+5_eyN&76Zn&JE+YX+P&@||<+YddihDZh_ z#uLxz*fgtK?H-+5H{csr8rd`*o0flV%}y_KCYdYFp3$a*p{`1dL0n$cH)gAxbemA>dy^U{}r(@CTb1k7@odS~6&j4v(c_4o0rOcd)AI zL*%#i22<_zXW5icbRl-nfs`Fyw!7ae#09)i@cVL7R_%2(IMx|jBrt)1dB^7%^m=W> zjJKo)FU!oL)^rwq@nA-ieSv%lZiZU0ge-as{3u-fvhDP*b@}%|-R_SSpZqm!Ktw@W z0n&xP|B;^}DL^nkbNN)m|6=3s&HsJYHogGB-L(A1v47^lO#V~$%dC?LA9d*WA^0vM>)Gg{ZIaUV5?eL-(#nU zM5D62Ki-FihpShrhJTXjPo!}u0r$kl#-iZTF@2oYPF_w4!mH90*3}`GtJQzMZ@>K| z;qtVXSYANYDu=t!=6WNJr_74STlimg_TT)-<~JZX`22J}Z(dI4a|^^i93D4jqsa`| zCv;@wyn6TZ)#ed$O$-;BRv}?w)6`vt>q5(whLPw7!LkS}Hfcy=bu1nW-tEPWjg43O z))PgZ39EwDKkG-=I4CwI;_K5vrhZQVq?)|JrStJ@@v^<6u=E1G$rOHGULJX>+rxQe zKmdqiV}CBpJ1H5Ny2VeK-D+D~TQyt)0)iMo!yA07X8$JNKl(%fPzxvpc0!d2aB9(m zlF^BDu5vKnJui+kf0*+T{7Q}c^R;lk_eVih=i5X~{Djd$OSEp)qzLhR@B*19@1rj}{z^lOitklNALWJtCyl?$BU` z%#{D5C&}^w268%p(5g3!Pv{rL^UN#fs`*tcPbT_fNouCXP{NY$0AilJ>FXcOGV42# zlPE|gm$UTfX%yG_)V#U*-fXeFnw*^jBies=O8=J*6}9=S@mIAirM56zEXrz@$BS~H z1aQ&_PiF9B&n%UjmCuF-{#h26LV&H)bB~WM`BIDs>MQb05qNxBH)*_{Ee#VWf2~@i z3Yd9Mv^k?flMDUY8s)R*8ZevZQAP%&xw%kJH_M0b5KFX)x0I7nmp)#W0`MX^w|YD& z_qtllcaTDp|8KSLst1C5v(8LSRX496o0t&M(7>LZ9=axVRBYeUC|67Y{q28k8u$+l zZrzNzp*lL?gT2>}PFK%%7tnCDlfl;-(W1fbLc7`&ZJH~ zh3(5)!7fih!)A$ICF_f6w*r`Uz8(gADai=jaJOr@y1y5AzrC;ugJ@OODiOk5fxITBZ&HJk*4~_8I`hToIT>o z_0%<0%r%8OT5T_VcCUMnK}E)RE9c;KPXVHfTzDjzxWtPDO0iZpu%?OR|fQVNMNDcl*Ml{ohgv6{3b3ARnfeU8Se3Lwi29{h8=Es zbVU0+IFW36Ac(;d?VZs58{&D~u&z>p7 zr{P7pOqe7>{DS1~1V1U5y5&r$yWC6epppyPLpBk7v3?}B_T%tUZVw4g_yoU-dGGXF{MOLZ9n0y*EmCml=A1Wejy~L$4M`M5rYo9ICnGqbRJhIgLLj?6 z2t?-_;1v^iK3M}H#d`aD(A70`P-7z1GyO}1>jq?#Ib=nXXN<0br>*^y(*drp&J_zZ zpR>kC^A6v=gaa;ifI1XhC{yQ?e5yTiTjQ}xxd7N3sh@=vAO~}xQ-j$KcMfo`e zl)b|zxX^8T$l%Git<82;TV}FkEC7Ks1>Le^*r9}_~lLlXb12)U?DbT^Kg1jg6u`?J}5Efxt5~IyXi{v@bMT6qVpb9 z=t6tP=8|QzB^6;mHMDoG`1`I&K={ST&4RSRwqEZEvHK`uA8oq7(ZU+t@wSO~xikr- zeVO?{dd*}~dhXPbI6{-o=vM<~Z-BF${+EoU^XKM~Nt_wi3qK`6;liOcpLDt?Wme+> zZ@=(bxNQAffX7gpC~pF@k$Cfef+Rmm)eGI3W#d|bSTK2LOG2V zJL0fgGtProZXQn75%2P_3ryaCVP_w%2&K6Fr1)U z#(9b88*h)mw~Gz~CItDmchggi%#dwA+C#g}J0qJr(ZRIeKQQ z0;E?1?#Dm6D$vNF2RlN%4uB6EJi%{U(Y9iPCU2mF`whoy$LP#)!-~+f1y3euV3Re( z`m&!+5T70+#a<5XhGs{UB^Y>)+x9&A3i#=vl(r6;Ixe-Jp$J9VBX%FJMxN@{8fZ<} z+(8M6gj4U}vpxplL&VOVh`Dd*!_Mxg1nNco zA;vTJjC(~t9B=kNnNmD*jK8@B?RYBN!aWKKis{LON-SH}$!Ab(&P;&;(rz&bvwD14 zc;B0!u+hi;t)+SVyJfK3zoyX-g)bj2{hGy=Yw*0%gL4A(K+-u&DQ)i0ikinpx+^UGX>%B19q-Vg#Jhn=79q%Y1(3gZJ zv`GU4Tl%=3T5Xy+v;?m;kQ{c}P)?75!R4haBBd$55iXy~Mj*p1%H{&uqO}4ow&v3t zzQ5JyTMKc@gt{gYP2Vs#BIpYPGUc6fkuBQUA(TsZ4OHIFtkJlEVg#1+;p`$Ym8MjJb1da>NtJJ5*`BCYey99son zgnnO$uqGP4+{lTbm9~n*BZtfMV1tTWQZn)qy~k5NmU!YL6u5A6;|Z=W0#Bd15j4lh zy8y&@^5ZHp$w_tgOoO;ZI-MNo*ZB0%;sPc33&}6IkWTrpM3Hw@3k}%2r;7n;8gf0L z4B(Ehq*&`1a z7Y%1yWb1-CqLF=jf;oKDY7u47UJ$KsuyyBVvtR5Nv^aJc5J71Bj;s&1rmk7YBb(81 zz=e7X6}ieU6es2tJw@8wgb)^y&^|ToNz!rqKsp;8FfCo@J@7~~Bm^;2AlWpHXc0-9 zy^QI%gExa=E5d}o(*bNH@_V^EDP%eGhv)73RJ!_uInCk;2c$$g zs>UzhOJtLM&Xbvp>&!MBW~7!mm4DZZE^+*)FCk&~{efqdx|7^HX+`S$1UrXcH100( z>pH6GzVyTHLv4G1U5-5yV~r{qU5yI{gvJwGoD+<_669Qth+xq0q7?Z`i53y=qcl-$ zZL>$tkne{o9n|EizBD>~$Ieg~%!NAz@y}G71?S#&P`HsK#z*6Z~{_E&`>9k}+zA;J`gB z``c(Qdv0EGu*b#5)QOrPeLekWkP>#=dR;DFY;=kL@$Eig!PfR(t`2pD2Gui^wWP)O zl=hit@op9;NFvD_kqys-4kI>wH?2q;h;U;*r*ik>S?2Ubfg4R?KcSi2?F}I(r^G9{ zZ9;i|SS5PkemNoPRPkrli31N%J1gOw1?88Q%H+tJlKaG=qrtU%J-` ziQj73q(2O&Ml`(9+fk*J){9Fx>;2SkF`U_-qGo+FxoDqPW0mRKeDUdczN2AQIN9tv zFu?wmm$`KKM7TLdMFwIM*vlQ~P|%lI*@+R*m9oC*3&>=Y>xsI5WJFfc-+d7p=lH7hsov&o$#D5)-9d+oPYN;E}GR4?3k?#F; z2fmV^BXRa5T@)rfz01mVG)O4iGsB`d+oO4d7-CwHn>AXF00NE_Dcwl)NPMIO@49*- zvbq8Ksj-L(TJwQ~#HJ?RZF9bJHaxPzBX&QYA$TLHQ5SkI1|1eJpo^>-SqUw-MP7DV zk>*$*0$KA}yMPX3kmn+h1J&o}WDcA1OuU*v0F`3oTR$R|4;Bfs%#|BOZ_|ZK40_cj z4Kng+jsY$&A?PUG@VuoHK$PLSx`o4ltPCqlne0^8iQNlY@3rN2d96V8ADY#CTYjh-XfRI)~q)6i`US zG^6DVnn>g#aA4XYO`!XCjYRpmZWs6>^|ckN)reO%wM;6s^w4tqWOC_QX}M<>k2Krf zA56$H%uRe13UDXTe_}tA;6ZZ&MwR+27pkY0B^>$bt7RVkx*_&{XKvm(VF9qWH(G$6 zQs358?ghCB3nCGgsO1L9WIUmuus@l3Av<+96iXy)4U(9U5G0k#%Au(!O;hcBp_QL@ zdTIdz4z8>+K-0LIlmDqPk^ipLa7kndKZvV34*ObLcrV&&m^_Z*93o(mPF#m%qypC$ z=r3oM@nTQH)9=tqG9Oaz3#UmepBq`|^p+uc)QpR* zFfeblOaL{XYy+eF+IeLwo>lcI`31@zN{+A~qR39YK5fl19~zVGra%8Dc%58}8mtU9 z8c}KcCJK3jLA1bFn=%5iUUq&n#*hq}^7!Kj1wD+fXWY;eoRAs^j%dN7t<5wGGLO~A zK4Y)d!D4;S@^(sKWVK;zwVrxhriHTKR2%Uhn0rFibb44ycbFBuRCwNw@l2? zAiatm;K>aW*1?)czg4SReb0eXPteM2%6p8f3dMrTum`f*2Le}V3HzwTZ$u5Dv4?Z2 z8cW6{^45viqmwuadvDptpVfBu=-_t2&v!S5!FP7zx3+1L!t}tu`h`B`ptB5ZBxr_< zjjuWHc=BqLgYfFK3Em{d9I6Fdwa*k;_gJarnGE_ts1OiTG83AQ_bL7ZDZcbm~B$DWUttsCq$!om7cE3;5uijGndtmUD+Y5zu!2!cA}(Z+^e zd=&)HdfsA9f2q4uq;W9-B#=kLrK5J_jq()tT5UVZCAA( zK*v5N8kW`QY|nNRXw>UGb44P1JRjD`M9h*t9*AknQF3*RJxYKs=d`kO~a~n|0lS zRVSpG-5L>XL0O++e`U8tl-jBimGd5M@R|n8F~S2`b6ve?wTpJ=q!9*iHEh|atb>tJ z0s0B7OC4L;&91QlRC9xW)P@7RhG-O0u%+hCes>B}ib!P1D3LA;UsY(#^Eo>`iEg+ukg0cZxT{5;uY1W0iD9*m)}jv;ah zE?7DI;X?V^(tg9CR$nA*hx~I_FDaL;R=!Pu>tfRz(K|z(`zd>-t(J_jr+6(!mXb#} zr^*GuyK34FURKm?ci$FICXI)VA7 zuhb`F{oOJ7n$?5Y{oQmbOF*U33MU8_t00R;y#eN0RC;o%T%8S@+eJ3HKw!!A_3rcN zcCv$U88-~7*XxR}<}XmysUCabo4qX%PYdZ#@v+tDAjv<*lzMf|HW zOi)pLB#JliUBlam-Vk>~0lp0-p@bZzLNSL5$>u#FbB40NXO=^tu_d0=n;=PFu!CIO zFJ!6aRqNzCJdKKujhjCgO$~=CwnyAlm6%2l^}}pXlWyk?v3=cLxe3Q%PqabTDzE$+ zle9Bc71E4;O5HLMowLB@Oitm@L2zkqRwOe~S-Dl^W@@1(Y{`U-e}d$2&^bjy3Qh8Y zwmEhV!;D3bsyuNV`AWza;1I2}FG;IdYLu_l9bG1}GU3}qO#Rl+e-e~_AsW44jd-Ao z2RELwyUf)@bq;v=cyDczzmC;23ZEE7-P7S(NvMBm41spg`E7%T9HEwn`FvTzw71!M zLs7)zWMXJ*j^Xfm-OV6_J$eAA-^&oc^6C{gC1SU?7h%nq@wvl`#*R^ZYB$VF9Culx zjWF2G^Q+4-rmCJ=-qVR|>;;7FOv@nsW_tG!XSt}3WWRXYtd-N5hq_!`+xz7!#0VN)e@1IrjlIdlIo}OihB-R z^N9E}oQS%PqHe#&C?hbu8-u_|1Za&}enB=&IuoMZdpGe!+I+3v)h8px`E6_3)^8c$Ztj-QX?j%8Aa=&gqswS#}nw3p0N z1xQCHIdvR}0Sgq3O}^#2j?9&wym$rWc!oyZ5eWBI54W%8P{T~VxJYK2KI%9@oT_FL zpLmM`zL_Vyj#ut0l3I}mL&kXn=Fk$*TbEIMhOzVdKr;6BfOJLucvMsKP<@$+qMQCBKB09K~@)h{|M|I>-ObOHbUdq6O*}If0N2Xpd)u1 zhkl2&Z!y})Azmnaxb7VqK2dDmYL@!zgiH` z8t8=d%w%q{X9O{Zt+>ao2`qu7aSmabH1QyNw{1(pY?Mgjr7UaJTyj<&T`v(7k69?*r zC~A+@qH!Bgzw9Jouf{ybHji+}#*s(A0-x}K?K>SBm@f%7pEHPGDWCIo%tPVfi`RBI zrakeSl!rwF4ET3E;*uFTpC`}aegxoZ6m34&kscgZRo11gAL|3Q7 zDZqC3hYA}?2#$OqU0ni97BgazD|C^EBty+T#ifW`(P+Ju2Fnq0-DJ6f#}SXsF5kn& z>fE&_|5A-2U~oHWRPdOj03b(6e5E$D5yMeW%lN_PJBhJS_7`;_H_M)j$%qBNMP4>9 z{|Ck^y92~BVYI8B=_ zx_{g$X6CAmm%;Irya`!;Z$F{S+0t5|5$Fu&A~IFuBlmAdfw8^wNxEs1>(S_&wC#*t zIDRTA7p>2n9efA8v@fiAlRTq?Y;{(?mo4~vj@T8%KdIGjacWyRzQ1FJU6Bm4Il|$# z7p?JpizxU5TVpq^_p==fSK!2*+$NWX9cW=rT(iT$K=M~uRM5mnGWHfjC7*8Y0)}KlQuJmy{CHmBata*@#F)EVDI5_!)e?Z|+80o|O95D`Rr5D0JR<|AeVAg5w4`NN^~JMk*kOw}=01 zH0h3?t(Hl&6&{tgC7{>2LTU`g--9q&8IaF0IT=~Xc;08bQ8pDQP(4F*J7JkR*3dP9 z{}X=27XdR_!fbvb?psF}%PIQWR0Bu7QV#mqyfa@I9H0C5SW60I?80)JR8f!RA65OQ zefdw@yes*0;Laug)AfG=83=yj5Y{g9s>J`f>pv!qX%wFj0w$JZw7*lE|0HGmgb*yk z%0QJ0{af7s|7QLzr2o%KW@@uWB`ulYrUu#NKG~R>?Goct-w!~II$x~Pt%;ard$ELS&Bre5|GdLgU4u z+1}rfCwltYKa+fJ2Fy>>6HJBok7nnKiTa7$3Gz+m`6CIS@+ZLS^q8sZ`p*c5*{V;V z5ev-N>7PlO)O>t(lrsSnWd3O1SwX)6K)O0cen3*GCnB2Nu`wo>KASPAE|bg@$IXBaH+l{ke{35percgFNb=3c3UuWrH=R? z_nBn{Q)bNWAm;;zUhw}jkG4>sP`z#$; zmd_f%Yk}?T9p(h$qr?k=ygm({7yM!-MYb}KP||08SC0oV+Onh!5r!|hlDv_dd%%a# z(nJ@#tOf;^>bYE0%;&3T#?4VViG)bSr`}< zBz~iNS%axNngx!;4Aq3~e-ZZLoWOYn8btD@{)tK-x2D+Ut8)I!HIxlggI{-^VE4Tq z0d#LYntJ9&^$en_ayE)d;;*@#Z_B6A*{tz)TBHX<5udMy8u!Eh1ztHPnF6y6TJ@Dh z)PQWOLWOKS1=sZCi>OqTs{IBasPyk8W)yM^$>U(eIxIFlh^V6+Yc?hoLnuaHAuZgwo)uRXC!oNnHw%f;6ZF$aI zX_RVyt``3!S*-|pkD|`F`mYS`PW998K6~6R{SCIXga|?GDv5!$NC6V)B=&wImOZDP?={4K zP)l%sDE)Ar0Hy`iTTlq!rscGbHSonoXB_>keMrF#I^f>p8|8| zM`E|m&sgaB&u9Bg5dP(Avnn7ijcl#FNZZ@mrmE%1ZjV;bc=YtA>)oB1EthAr)!0m? z0Ls-G=cD3Xhj!jxN3@ufdAVH6qNCv*IOWk|9b=z{-HQ0`kGE+^jeqhn(utxbOBW>W zDHub-LCP&toRF_jpJ>RT%(j^Ag#o7o2AZD5JuRA-I;AazNmggM~WHfjvK;PUN zsZvQ_t6188^(@^kh@bqcEgS^}0w-K`bw;H>sJ;hGcc3k3XV>u~HBlQxGV^NzkOMDb z0hy6`elm3Iqa%!y<&ysD@)u2!F=mNw#po|O+E+z0dm|&PmK*)D9$Qw#<^nqMkrS`a z>F8%vXrBpp9sQZ?0;Zd~XC>gTSPVX}PEUFijG#u6E1VgSI=Mm?<>-Ul!A}!+87tNk z{+GCdKuXYTOS8op)cw0+n%E;_V; z!}uC~ck?!?HvKC$^W2*O@o=rdnX;*LmIQ>>xAifq6e}<*_+! zvQ}w3Nu@5Y%T)E;W67O4IYYW$^mhgmCCJ#)cpYIb+G_#w^9`+C4aCn$fa+uc_Fzwg>UNy4EIn3hSKTmh)8_of2ErT_bQfksrctlvN(dw7j;M!aXM{tQFU& zDf`KOrybZR>>os58iR9+(c=>{6ucBF$3(R8gHMJfnu+2kV@Kc)c{)#=h#QupY0px+ zsO*rJgS<@``U7$m4LQ-Et16owL0qJ-RJqXb?=+n8%@v>M5)D4v8dNKLbxcwzpYNpQ z=POs(l2BE93zKQkR4ADcugB*Ewfpbv%S$TIvK2UG1H6PmU#T+x<&2sFed>K#t>mho zwL)9TBPL?g{NhOnWKz)Dy{885y7Gdfqm~(lYS{c@i(VyRR zZ1=?Ysa6%-=4hVz=zHe8TzM%&w}&Jmcvya22u~}WPccX2Gs`xJMI9^D5Y#Kw?Yp@x z+_ytS=(eL9vxUpKFsqmeHzN>QED+S?`RZ-eIE+$4qi`-eXT}jnqkLli$%Ft_P(WA{ z>0_eH!-gRc*SxofxeyeL5GjL`bJ%lPZqiOq-`LYtH;$W%9ruVnrSKVyPrH&IL)mMr za{8rG$8Ij+KLaGNj9Pt(#vIjq zxcvHnHrBvaWjmi59UuJ{JrVHgT_UFDYj0!9;ILAZD4bDQrS`9!+0``z+7+L+WgE{u z`Y(v14BBRh4jZ?>a!72sXHIT>3JKX;X!O1}7^1Rbf+JxQMIm~OfKIdIYv)RT$aHkP z`yKesD)e^B=tOxbZZqsFw~xhOo9)L@!Y*o2?c{{7`dv-w)wp^v z3`Xsb75xx;$qSCX!8_L5;Ccc5;k5(di1pUy$)~RyAM_qw09UJMYkC!39U$_uN)iSd z&3c>sJ1MxG*0tC;>a3Pa2Q(}7z4ZgrBZV>~VTi4nDs`&TwhZt6XefyUg4SK@JnsEs z$4qLhfoQb+LF(;O*bmV-r4}Cs-9Xqpc0v-h$9x~%F1lFd5!aR!Fe{;N!^>WdhHVfP zrF13ZSPS8?oqWZueM85v;#D3$#AfQ%*(_VzQM5VoTE@1^o|P8LB|p2HK*&YLK>3N% z%8T1y+BsjW1HVZ@0vYExLieU>e_L0bxgV)ODeHau%CJzC1Ut+p?lEv$qIX$Xv&ZPk z0eBy8N4%;d#lH$sw(T6TQ{^d@P%jC)LRf)e`ucLp9R{<3uq16^ETc5?jem?KLc|i0 zy24DBR;%h~Myr{ak7s_6PBP731~Ur|$YP|3w|vZC*`^d>5ijASl#}#*tJdx=VMgGU zQlv$T$}iN*3#ae3F;O_H2{1)e2!DVbN1*5YPUSwI0>U&S6vn25)1K6*?e<5_Q+Kd+ zPv`pkGB;!t39*h3DhO}*0cmG;oNlZb_meP)|K7$-BW3qy0-@NNIEZRL-mu>A=(z9? z2y)TzkDiMr_n0;QON1R})Iymv5nJ0QxhnA>Rn@?+H@`z#=QJcH5+O z{8S?90?8isfw4n$Npb*(g{G_H`%KT+ze)F7+WHRT0>VPkrdXqXJMmyDr<}D{*3H%DK~1Epi6V7*UvYF4 zT&6s}*y;v}%|Jf-&7hmo(Y|>QOi%1CT2JAk-FZE9Glr@!^0KWAEY0w;-2y>nToTOR zIRxMp0V~%PeAOz#Zdmawm#ATPhfkLNWdYfIdPK!t+R^deL`V?xBRw7(s(!_3r{#f%r3l75-Y^ z)@iv=G4SQahEht)$($#NO0-#R^-*#)jb?z|kIm}^jDf}PZf7jD_Mk8`j=ySkz9<%r zHtAw^KHTPUN_#u`?A0K~F%^Px^a#Vlb8aaR76W^=QD)UoN*WFjroEvvi8A{&zxmCo zeJ)02l~@`_%3@V^%fGEURd=`{>AZW{*E@`Jguf~cB&XUt3j(C{h9>oUrS?nfQD}Vq zj{5@;A;Rg2`O~jv>et-<@w?qGoo~*F?2UF+O9jC0_gP{fe)$rP2_^FjOICBHz|o&B zm|H%J-4*u7cj<7B&GNZUMDaV(8T zc)akNTHh)iW)tFyt^I9Az_9DE){o=a6QU_vD`IR6A{XT_%H6(nmfs{TxsWKzf%_R8S z)o8e=#B;`>jqED1mWh0?k;ut zLHzs$CFK=|B*#Rj;V_o9n-SAoV-&z-Uob@%E3{kXs1~NN4p*|~6Ymf=D@!sUOP^Xm>%~cr?zn3K`;EO?omrG~}RuQKf=T{`i6{Tgqf$a7- zgykNDfQC240znK0IhIeQEP+(fhNF`l2yM4krkAln3(z6~>P8Xr^ACDeUOj9I7mx<= zeV}dwoM@u$YW0-akvcdY{boDkR8!e>6slYQuVM=6vnT5`Q>&mb%%!SfwkV5*W2@7- zw_1OnQWUjexog=@g*?2~21nhk=cU(6Xbh8}D>qYfmTDa_L%}R+KsAHi!zc`n2%>Z_ zvetG5KO>;1(%Sk(o<^wN+)#f)?*uNscw(#XCkh$b^yO?BwWahy7<^TH&hwpPRBHLN zE!U?EltCR}_g*^Q_^T!)-r}mWr(C`~b2DN9j&S!1v$yLqetCE|A+j}Oa~9bV3DOU% zjaI(bDR9pDG%+NG6FVi?cFQObR+iT7>9=g#)ahJfti70DW#xRPc@ zp0BOFS4po`mQdLW!`*m0c!82128rxTH8itJ5i~7L5W`up{4l8u3#wh@Tm9y~Haz}K zN{Thw^$zT%AMV9FNVAzM2n*r#8z0sH0kWlH44~=b7&-eMCWF zKWfuJcw9X$EWVH1lRIMe0v}GTAn42&T9)2p?@O1WGL`%QcoC0ZbV2wOa4OLD@samL zM!6&z#SY0nTU+8>jI#2i%Z-%bhfHZ=SnAwGO_8Qg)5mNC22-4+{kjXv0V8&+-6|mx zZ}HFHZL1^GySwtult#w81bNt@>Ly036`q1f7o;KbpFPj=7&UQ&8ssse%AUhWY~@VU z^Zr?>{gKPK2sbwk;pa5_3hIG6 zHD8>zNxe|ohQrv-#2O($TGz)h?#KK;;dacvw1>=AaDMTKt!`J+-jPm_S4l%{J%FZr6Jp%7F#TjKo1W)ElDbz!A^QX$B zX5uSF10hd=%(_H2bXy2(1(y%_jIpLF2}g)&jw#Jad6W$TrLj(qOLuVA@v#$s;nbWP zps$Ny22rLmQxmH-TE?q8Dx6f2s+f2(cPv~QILzRQH@36Vr&6ZYvG!=Qh0~<#yFbp) zJL543VFMwrgp+LAI_tvGA^tHy~@t=g&p zAk?g>Zx;a`QB84nXfs#FU^VhVB*?t*gixm_DdvWLc+Bfe6VyI-`OGZt2KzlqG+$u- ztPi+N{}8*NYGPknmjs!T6>-%XA3-a=-7c%c2|~fHcFH^Km*}NT)WQVJalI1a&lpd_ ziu>7CYZBsbzvd)s?J|2h)~O3e8-*W|k7mI(c^We_T2-+Ine~#l#ymZTmEv+5Q|Sj_ zhL1)dk|+l^dFwOzWgZOMtNra8yThhW6YVDBm;Ps;LzBMysNUDnAaSm_p8EES)NLy|&CtKcr#2zUiI;&)%PrYgU@DX@)ihpCh zYk4+ny6!)qwYpbqPW;Sse*$gq+i2EJx0qiUqgcTd-k4eBnF6LebBar-b&5u$$sH=~=P0DkA+wX8Y&JtoTPal-t`s@q`WofHrDzAra z>LCwt4u_Zzf;J1H2y5Q#uaP&Af*{EcUT+cZEE)C1ai1oa-;|W}`BGKBPY6TXQ$+gY z|0(P%pyEolu7d;#5G=SufZ*;P+}+*18+Qrr79h9>cXxLW5ZpVsyUX91dGpzuc|Yqe z7JXOKx9U`#s#E9ey&J#!Rh8!v!O`)&EaSPt26xn@{0oh-VufvU+Bct@ElHDzmf^>A zfvX`|Bf{j#vN@-&p*U=2gEzs51cAF0@)&+UVHWC)-oo&{wn>~uDBi9Ho9e$9Tx&E} zYicB)!vMN+0@98qCLeDl^F(og%ZPJ&43O0h9`MaxtquW({Ubp4nI;J3!f+lw*Szk?M+nS3nk=MbxKS%40>t=7-fI9dmE%#<|^O{qc9JUREW`-C? z3pdA&q3&C#anu@I3~B5(^&WwUp!I^Ey$2^+i+gf_`e_49F!hO3HoGMW?cS*s{>92R z_5EPit8}$vKoKJTQxn4kc4w)|=zGE^2vA?laXuW*vVQN&U1CGLoqQBR(QawU+v-Xc z)d|NK$1QrS?MGFCx`UDzRd|uLCYU%R+t&zXFB`&!a`$DlVnxJ<@LN*P2)(h%yWN^) zE{-a`?^-K^9ZC@k{{m(lBnaMj<{zkB@>Vf{v@>M!IH)m@-#0@d^LYT9#fB8idqq(+ z=)v*6ntzuA9}gK6e4*U1DigI^5$6pAQ@hB$@(LL{rgGw!>aQP0zm>6-Ej+EFF|>2P z<>%+$R*GzT1k|=12?8pvQM)g?YK;gDg^#`L)0o56e{vnlf521&`he;qu<#BsB01K4 zB%xDBCo5^8CWDC?W788rSHx9ig45jrQYiWr>rR&h;6u5r!>p0zYzv!N+fAypI8-Ty z0~SX;zZbYd$}61x(+$4#f145h`>;R@>30*NGE&O)ZRP7XG6WQRE8Q&`DqEDl((@ z<_-VGZ!G}V4<|Dl$EE6d>aQ=MXb|HSs}Gyyt{%ibkA(UD1fnP$eY8LBr(oB$Rh~+l z9Z{bSN(YQR!@4XOJ|3;ni9KP`2s{VBpA|bDfm+XC89cEtU~?4c{FZz@fM;}dCX|kq zXJ_gIC8}5O-s#g8;8p)&JlFO%H7fXdGCax(RnJ9+&;+HTM`~tG-`h{Q-=p^w2kW34v zX(ihVSHKY1Qk})aj{thKa^PW{l`Zb0%^gbE=Xu2?or!qR)bu|}a#Wn^_ zfFo_=NaC?Zri`j1WFn9L5e=IwMe=VV1o$XY^M#6kXSlq`+8GO?{~nxl)9$xe_8S?} z*T3S3exsJArI8%uYTl_2U@cECRU`C_N`~2_Fz#YggO4o{$0dx9f4?~sq@TT&Yp)Ts z4LH_xm=*nb|w@_JpUmRc>Jz5LP5cL$p3Ujk=ra_*cppAv|K%TDMn7mDKS1JWfcp1#uf zZ!v^V&Hd8%LZwUm(yorf!uO5-MQY46{R?d0CsXYRkD0FQjSB`v^SMTDK*Pbr@!uB> zPbd}mN49*N%Np4pe72>YZbOKEG+V3pXIEvv@rlAClUz|a`Rvo7n2m4 z&f()h|5voT$44?sN?6~pU)!O2;@`4227W}~wLfb|GJjL1A1X#NA;5L_{N-OXS)C_N zgGiA?Cw}a7zTC*|91eq{v)bs&pp{au`OW)g3}+k6Bv;|35kS*`nbgPd1Ly|8V6@<) z6fgjmgQb(`6A?a@9w#)sVs_sZ$fkwky#(cnER2%#&`8T<#92#FjD#~szi+^dkVo0Z zXZ>c(*>$zNcwJtSRxGCT7iQsqS3&JuA=oH(Pp-=vuj7S8af(Vu95kUhaE) zY6gdzyS-vhpTReU6yu_Ls7L)jJoKt5lC;L`A9{Qp(!Cox%&<02ml#Gd~MU zInBqFx6-f1bJOa+$&DqjKpbj=5=7ImgJ_168^zZ{ogGCCsaReH2ek5%^t zJR;=Y=WE)!gM}8Jo}W>1ao=T3yyRb8nCb3L zWC)X?S|B1I)TU5u`JhgD3(M6%*G!lKJ`3p4*?S;s1|k5ga*PP2d&&y`Q-RI z`1wY%?}yPTOXjymlj73SO1JEDJhQc-5{{biYw{C3z{$OD9HYVLQSV_ZnV!o6djRx5H+;F2JhfX4n ztZo{|@g+VlW_J5(f9C(I1)&Dj4c7CB<#36QNWUOqW>(U4-AckAr-2$|hFi%Nf)amU zow_r@bNaIZxYDGky$eop{9B9u8dnv$u2HRvL>hIgv~Aw@M9nP=J#*R}4j1d$l0=po zlRv1XfB)YH`Cn#HyGN54<{7!255AYr???dv6>2MSWa9r{35qfp|5;)iuuKC@QX0Cl z@9Xoe7NBv>qx4_QfxjB}f2KuI`j=V3s?;D{6t%4RIb%IN!htBfLJaj3uJHPR{~#~% z1u|T)8LSgAyu8-#nV10rV;3DS*O*59f1chZ*qqkS2Cjz+ z2?>E!QM$v>DQ$K>1vGH$Hgnd9K7i4~J#*u~Ok$hGV+gf8xE?f+1WWM*?lzzhaakq2 z58`4vZP!oYuFdlQEG4=?S9o*RySy`^BBbl`0ZkQF&QVYLC|Un>&LzG{;fVKaCc>PLlx(3M~|vFAQu* z?T;l9KI_NQ&jvf5+O6a7>d?QzQ+{tb;Jcjk25cy0gaBZ)0T(VO4UM#H39pB{`{r(z z??91a9&LlRC#m@38kpt@mXFD8SYBTzLPbTzh-RI8zwxhW)g}Cv)1gOLUWZQov2op3 zUFwMKAV7;grQiK)SLQbQf;{hjU~^N&5d%Fx1fde|V^~P~CoFa4V@mo8m;|mL;IC?HZC;TG^phI&gOm4kbKkO4TdpT;wyjRsWNl`nCKXCR)7b zVahBE+bl5S3LhQ@>%#|P3JNivi789cIw*XdI7bB7w{NM6=fNxR_2K+7A2WC>YXm3Z zzwMk463x#w{|Eh*3WNnjXb!*%_TgOl%o0OD_q>iH(#6F^o$W!mUZpx@|I5p7As|Ke zQPlnnZfB)<&Sxfme!Wr0g(|~jX47|4($e*|4%-*oqZ-vlZ$E$jTz5?5bq28&YEJ(T zz6`eTLByBU&^@qxO(k@IX|^i;@7=+`fOx6F7U4SBVYv|~E+rLSqyJp*b?>m^ILUV~ zgX^9kv_s@`Cxo}p176XGvPgu3v%#UEgp7>JfwkV<(PHiSR=j*F5XAkDbKZ}e!GHsW zRvX;O-N~#$Fy{%D3n@UyWTVmMOdUYPAsEVejh}zys1B$7sVS+%Q>@_$!n9}W- zds3)*aBvWmuH=vK&kuN@P%tFc@P~$m7F@HDm20QZhu@)jpFQOJ}{-ZVe8(?1{}E;cq>Mw6s4g41CO?&10{gn-B8ld|&F>AHTgFI&Xs z=06*gSFI~Yuxg1rL#|K;fkb>k%{fkJJ5|G^!{MstDNZ_z-`gq|d*?rhBmIK5S)-l! zrPcH9pXYP-7gaE*t-QwWpO+NB7P8+sA+97F_%5+5)1zmigqJ#unk$?`7*Ud@fw%4%gT^qwWlYwS+QS7JMr+eO_}N5>-?~y98UW0 zp^Qb&zma$uZ4Pf??jC7i14Hl#XA{Wb0WX^qIWWD|1Qk_O*^tHenS^`%$xeg z4+jt2qr3WZN%L!leN8>&@->zJK8h@abK@e%G6OqXQ+wAAk#8UIdGFsZS=leY;d8GO zT-q}KwLH^8`wKs#6xmFXvBl4mX>Oc>t*G!80w_|C_G*O*xr=}hr>hV|>jw9iapkbU zNW}f`W3m6$0k_~T+uOd)Q!;LnvBI3F-W|SL$cV!+8{pG)*FAwoaxku*UvUa(8T${{AA=qf$QoyN zoSlL8^7gK$#=_b4pJm5ZH%XPt;K|dhHH$rDUOfQ^+wt+r?8P@ag)>x^5fKsg`_ts6 zo`>wVKdOzzO;?}XtS#|40Fi*zRx(CLh2dSWr!UlcHhxP|i_J(34TYD-JM%PSCt%l27PGVGh)cu_?rPrdi=Y!Db{Q3DC#c39rZ zL_2bKD}4SoU1BmsT|rrd^;-0BLiha0da4PeuWvALdQFVI!ue*t?y{!?YH{|x(p%S< z?jG~t?Dlj1&TbNZ({sKHu1;3F7fU?)j!^f4F)XJ06v`^l%yn|(@})n=Y9&r&kZ&jC zfiF3i`2>mdI?8x&z|?n379GdSsJm)$NHN~l@})|a-7KWt-37iDE?g{g*X7@l?r4oN7+r~SwmHIPKHmC#=k65Q0SB&b*kA3Qr={f=zbywfyijG^~ zNM0psp=e~K_|LE3!LM6Zk^@&(pr$( z^(BhLY_*K0#2ZN(iidLVc$xb?@*9F$^CM=5rU>4HUHF@MHWg+3PCJ2ZQ6u9gypyRQ>A~V}AZX=`KC60CpHG)`BKd1$C70PF+MaxUd z&A&fqueg7x@A0Z7K6`LJ6d`sejE*q=xn0iXXm_3Mb1>r&BR`%Rv~MP~VcYpk;h&cE znZG1r%oy~2@Moc%cUeVROx6S2v%8Mxsx#O$Es_yL9V~Ax^Ir?fX>8^MB%l-L0SgA0 z&~r4q@;mXd26w#|YmXT%p! zqb(iR{kH7U2|oChjF1bIQW(?1=w(Sf=r+QDq?UIZpuaI^{u+QPPut_HtY&Op@RZhj zmfsDQSg&9hNrHK8gZ-tYnwOu$8+;eI8=y|o zge&^=s!WMPu$e^g5kx#5@NcMbI8^6;G~JtAD+o9!gJtL}yV| zlLvXDRWvp#^n~OCIx_DaIVM4iLi^Lo<{q;??pP`_(fo_?+mqBbnKl?qqq&2Rd!l?u z;ECZHf;(?VfT)k_b#;3(OTEivPacj4dB_rf_SBoTF^ARBtNW@E2+RMheBZe$?FE0i zqI%%#Jxd)93l0ki={NR$(>yqRuS;I{zDr_T&D?W2bnXdLtV@Kj_D~eHu>iL!T=-bm8YvzlRz?7-u@1RZqlC zy!Mrb1_*=-AHM>f{D_0`Xrcea33PiP-S?QR-_(HSAMX4I2@T z81Qnqqkvk1$hz+Ab0-C2beCN~mQ1&W_tV}Bf^9y+Z+7JMBCh(kwJ z(EER?#P1TJk;Oxb_z0hK#AQ{E$saAZt3Aoq_OO1|++lGvaeO-O*RqM(3zGCb4E-h) z>}z%nLO2;;e-6hv95W-ZrKOMZHbl`%=L@Cm&#yA`6oI%vJH%rwb0^v9Y#`)W>Nhy? zCO}#1VRX1{NCNbtp!%H&^LKoB>|}XqMqg=%V{vT zSO0ns->MX4R-Rio39S8?S+BJt9Z>Tu`aHccSP2vhJeLlTP2&Yh1&pMBF!!?j;cW*C zJ^a}*W}_LSa4dYXxAyeKuN#OQSb6tY5wKwVFuF>c(pt`b63V$fnlBBKj=jdLgug8D z;qXPOT1H-f25{jvowBKeig{W{xg|1GazEfu4I5=%AQ@#kT;ltmAB-7VxSP-ru5HD{ zP+SYmW4??W(w?qRm1)(zM?g-mGa`F(YV){OgX}+zvaYu%C~~le6HQ^sUGYW zgA<%XC!DP_I8To`Y8KA2zYLf1*kBA&y7uxkK6(zY+wEe9vo>-Qpc&x`d8K=N3w#0G zba*ktSH2!5n6dvT&2gV1YzExt3oX7F-A%ud75~*w(yh?Jijp^Yc#{A#aW_qjE!=WP z^Ss$e-f2|6*m(duXWLzpL%>9_ghi)4#K1=)#e-GB1qKN!={xEJ(2qcp$6Und|psjya)5P(MANX9*s;+Kay+UlaC;vZ<}g-Pa`j= zj*S@ml~avQcQZ`M49DkjXZJ)a20O|$R@ug`m~idX?4-K7f!JtdUyFQCna=(7*YLSK z+^aXHsul5$j?dFc>v=>nsqo7pkNxy>Zu>XCjZ9Lz3Lj*C-?i2|E6e-1UWe%2IFQb( z`j)bfOrvNVd)CiHNAp_0-=%r*DM8Hdjn48g%GJtir@(Q^cS26X^GR2`TblE0fk(12 zHx1_v3xa_J`^ z`TE-9cyj_gOjs-S8YY~C8)8weVlag=id;xz8`epa$vW>&R$JM$9(6=+QHZN;KN{t2 zf70tkL!F&QX+y=*Ys7jac}a=J#S8%w?OVy%!#{we&(KU=PnL4k0R70)}`ywyF}oB)ilSKz5mR|)kD z-;27S;Q42%Krw7H69p!@J(2imE;FoSH_JBbsGa1UqF;9w<_fH5fzj-+6tiM_Ed|r2L zU(b-dSd_z!jDZcYfV7+4r@rSEBQB6umw7&h3SHKSCJCsVhf%z@O{~KpnfE`e-Uzzs zDnc4kPs`T*bSr(yCes!_^gR1VAzNRXF#CQ+-9?NT~dV#6|NrMkyG_HglZNPz2} z_^h>iGEdqpO{ua<+PO5J_4S&!WyvToFDf)e@_|4|HL<1W6G;hNun67YQfr8d{(yRi+Iu)B1+5lDbl1;N$DNq?mQd87w!72Z z)G{~UL%{Sv!m)Ar(Eol?BfP7`4xt%`btW(7X=266(_0+0pp}19gPrQm!)`tBxztDj zN|S=Hp1Qw(m0GW7bI$ZI`430yCgfmIQUeFkXuzx(=$9uRj4F5;{Q> zu%c@yEhE;cB!1rEqpxGc#r0dsG`!H0GNoR{6B z8azkUJ8wcAKdeh9Kk}EsVhNUDlLjbMKh>kD{%KdDeQmzaZBDz2s?c`M}?SFUj>F^^q zsh#GU93nwIT05Z^Jm0QOzt9wzDuq+Kn_mQzW>Atg)ivd)gM-x2#)L~Y4MHUY@t2eY z0Yc$!gQqrv{Ol0Pa`2G0o>23;+ge*m3cRINhDnW43#K-z*EHyRQmiV4_e4?0wJhCJ zrwkn0qS^thC`_`EFq6^p7*L<_rfy3V(WghuSl!IcT(#Y?#R9&wnzGu-22W*ctB+g! zm|(>11FN>^!X-=*YevF_eXYbnGO1+7wRt^$bA?e|Bb>%4TNGJ^gA{BaVVxI)K3Mfs zzdB@hWx`RDtK71;)jH_ZpG-hD{a{JWKS&sHoK5Kp!H$`i|=h{Su4!IT?)J0N`xVx3NQoad*d< z-ctMW(qhH(%$@{Enjf#{I!u7!VqXO#=$Nm!4!V-QMxAPwTVp~ka5|3o)>%Gp+Xu=; z9-1&TT6Dwu1gBS_jvVK1STlT`S#Yso-q=2jSTMe)DZCM@>C=mWYyO0gr5+JCrL*Gn zPAwXRWKH6wr65@>pzo&>6E5!;Pi3Aw;iiK}Qqu3hRSQN)bna9>sFo>W!V!y&RGB;> zc~e#t#~3qK2}VScRPb#{G@7>E>k*6WugthIeP!KzDC>%C>!yl!L)T-hxF&oioiE#4 zM}s}H_d|}Yb|Ro}*3Q69t7ilSVCt(R*dgd3-gOH(?m3UH#a0_50ktIBR%8kJ{OYOd zE&Q}2gO=1@?wwC-KPX;jiIpvGB>*r@OTTx<&|T=bs&9-kWDp@c(<+kN+sN{G9L`PX z$2Q&^n0_cPVq57AX{f@=u~=Vws&P8nM{9VVKyusO=4gL!64UppS}dEOD>3ggD;6XIWo~yy!y_9sJ*C<g8Z8A0evhsF4@yR1Vm3{eCEk2)^++SL4)(=xgr?T!tayM)M>o-XYnknsr zVb4w%pu{sTQ8ZkUD7@|zx~y#S%7BZ>nTc|E_?7k}lhLAvbX9j%uU-P)rTPCO~2 z+xPQDe#OAv)D46WZRePnsRL!`{mHLlIa9~(Cgvu_QSKR^c)t`j?!)BK59?krQ+71e zE4L|Qj_MrSt&?sOX%zW32&1cm7Fr-46hm9W=fzbM z;&_TAvQMXu*_6#!n7?;qXGt5fHpW4c+3e^Dmbf+v@%b1qZ;{=T`n^$|@`qwsEh6l! zh+I_xH`3H6(!PDUXLl(&QI4~3M5Hj#iA0zMAvxziVQ$$NAV2sAY`GEf;pX;VW{{EK zt0-l5IquS4aCQxG}?BZi3K{p34$A9YF zL5}%~wkq6}x!*CX)P`~(O|lS^!Gm!^0)a*hfp!M#w>HeA#nS)!97cB)pxo+tab8UE zqwecnyByc2N0TgRH!uWNyR4Ke==Czl(eS*0$M9*Tifau=A3!OvUMMhktn@1}swEU1 z!!d~NW4v^nv`?Cqn<<9Rlkc<`cCPmFtAa-4XWO#!AH(uDd(wm!P^xv$71>i=#4E94 z0TQ%&%pZzJ?Bx;ZaZ>7EZ>+O>*Eq+e+=8L61@*@j%f4Y(Wh%`@8`-)p(>MXeuEhi> zV~m9xj6>nGEhanb`*BFty71nmYxC#;u(Yr7FF9&ykDBC8dyB<3&F}V#&~lcENpgI8 z!rb)@t=A3LP9?FC2Cc)thBTheBI(B+Ki$^lm7fYOSs3K`bt1;WIphg_UgtS0G;Ena z>u%)l`6kE>%ZZrOZjE`q#A{s! zzR8<|P5C_p-?7wrwrt{{;?JyGr(xOCk{6=d)z&NV;kNg>fxiOK z*6-D9&$%ke=~x1u7c}J}aXtz{f-iQ+BvR|-HC4)yjD9TbJkpI5n&Qt|O3)SULZow8 zOQQsI+?EVG4cm{dTbs}1fcn|!aN+F>I2UBi!|VV|y%Dd2A>&Qyl@!)Hh$9>u)y1iB zYt@4LquX%{JM`&~CV^(GoQCGcrmPZ4$<=CN0U}&M2S%*e9MTgQy%rmjj{U0^23hJs zW~{N|OXO`~W~_FePOaskU1Utz5f??}T@f+BD;v9N4xD6d_EA6NUKT#O$&8>~`3AS= z6FSlDyNb|*4-qDo(*>uQrF|rg^dER8hwtx&Lzs6*&U1S2%_ob+&LvYK`zT_;VzhVKOzr#4*OPauLzi$49`mPaqA21wi8DP}a93z{!}F#D$2-^NKiH2>#dL7w zb(dok8(OgDb%#j{sIRUl8Yryaj23W1WCZc9(Ji4Xr>Jb!NKXX+7IH4LXJY&5wgN^vQ}aOCF^;*? zJInh-d9mfg1#Dx>)oy#)ZbXZ9#!!R9rT5~@wt!0#0R-$HgA5^^4P(w4VGiw4C~kcJ z&?0HLCTgOKQqB)dRdI$h^zia~K(BtFjzpXVIL+qGA-P02o^W2gSLvBi>FJpOjRFq@ z+68U8AJ1=ijc}0;ELbg8aVq(Fpof?8mN7K0-7uM@d25k=wkPg7Q}LHPvY{<6JNtp* zzgn%DiEhJ4H;WCpdPRmC)tWeE@AMvCK+i#(B!;#tU)@H1w10>&Q16(OSL~W~{3@l& zobR?UP`gbcK@&1##pZNj%)~GAgiP8!?du|kmHFs}^cixOfHk$Y=2N?K$@#%23*8v5 z@u)XJ8^qiouvr2dIc$0&gAkaEz_dM-lbD>|SMlXtTimpDU*$GaS9cmE>&#AGQS0L& zwGF(Kd6?za(dtcPz%@bRJw!X#HRcD*IR|xOdeFQZBkoUEMCVH1`xxET!7<$5&hkSC zF1^3uwOsJQc1ogy@9or~Ku!O#D>Ri@ID!lFy})a_KaUuK75(!*Wh#|tKst~(wmmREmxWnKu~1g_vj09?N25OA^|1^ zjm&csPEItv&w8=Nnv>ALICcdTxk+kAvgU|WhM~|RRH&+D59P|VyM#1~hxgsm+g<*E zsrUio3b9R@o?&9L-_7m3kJ&CqpQANXh`?k#^({C>Jwt4vDF|=W!k|U*ejH^VN%;#7 z5)3~pwEWttCZ2uwP84=$%fj+r3Klf93t%abXf#W8iJ~R!p;qdWQl@GI^kOC@_(*6~ z;D}senUr{31K%->C9vyYIV5HmiY|HNsjtBC4k|1y{MqpP$-J&9K&vA-BqZ-W$rJ5zvG0H>x63sVr#5&)BK9*ABKGWs z80(-TP^{)K9FBcXPCo9YX>xWQ`=&Z#{Bi5^W4w6P3618eY!Cm(>t-DIN?S)PhL+XP z%v5n>wvlL7!~srtsKm(1qnHr9Rhf>))|<3l6Zd9%tF+J3ZXYYYF*ghjtGeUt%HG)J zi6QJrOY7w9C>V7ljRO;ijG&cH9w4fy<}(d#WHVQg2|9-cmAMG9VFr?FmXp2Lh4TDP z%S^m`x$%&4s~z%5Abqt%sgxU<`lc(SPm`LDQYx#S4KN0V*>X=OPeqpKCmmB5>lq#j z8idyg%VRG$`0>$Y*{IuC1`tCT9=G6q}vRgj{LGd ze(Ifb{X{)2YCD5HR}tXxFtJF?))YhE;*P5)qMfACNxp71UtGkl%T!LuC=Y_>$p`SA z9cA0KWv0aNB16_IFA{srXox{!NcB}xNkqa7-y+q8b=?C^++TcdX|UPFAU~o+LgQ+h zB8Z9jG40GGPR#9wJwGlVP5F8rR>HyGueoPqF@S1?L%`af1Ce$UmuK`86fm|>#ASjn z6Bz@0q;}$29fV>BZPIj3yYn9;R!nHAcPgcBk#Q>e18>;pJ%f=O!(P`$*i_a`1zeEW zm>Q&iZ&R{Sf|C4mr}OPAO5#ynB_S2gsfM2&kWKgm1Vs!a*M0ofN2z~ltN9`x;}t(& z-;Ej5UfOu1z%Wv*!EX>zcwN=f}FYMW2n8&v#fu8om$3hQJtGy%J)R zfYegk!@UpjVa0}Q2ckm|%Q*z){X@Rsk8@`TpAq0aieZS5s+kUm<9L1~kOM2WHB za$Z^5q>2SdA>{cfBk4!NyvK0LgK*08>-BL|#z7)Hv^M8-e|eUeiKHB?zEjT(QmzFs zwwalnOid=*69@cGDj+D&TNGrutn5IA)Jj$H#lc10x z^tWGS^)+~U2Ey9V-FuQb|0Euhb2)mHqSgNaYc)Qank(FJxCkIq5jN^vW>jhm9cQ&W zYRAqA8`vTIHOmMcq&K^`{h$!pxtsOvGYK}MBPWHEQ_(yVVdYB!(L;C+;D-3I8KltD zv0st4dSH*WC;yvY|!f#cwnhXx!ZIc;pDbZedP zsW-t>UCrd~g^@5U%5i3yG3tdI_vfp1M*Tb-O3*G)0|ej^r+}ET{OL70|Au@6H+6F* zg(aEG7)DQ{K+VS{g5#wDUjXk$x^SxV<>|6XceE4Dc;J2iVP*Sq0U4xrp6H~p9=Ci8GpDTKG3lZrAugeomAsoOUqwq_3_M;jjZaGTHxke1$;2=#S6}9} z?G!LAOD#R$ennf_4<2&Nck{6C(5s(&B?KAaI?G57;0GBid#qD^;=Dp4HLm!aOS|)3 z$$d?Zwyybwus3)WL*fKIs_*5Nm}C1Bf70~K=(RUt#cG-sv^D0KvD9iKgoNmzmY{*^5-kBD(wC6bFOD28`{(1p|QBkGt&7kSI+?FqAXkZhJ>0h!6kq`P6vxK4L((A9lS@yeNT zdD&XC;-|9Vh>QnT15gWbkfM!$D&MyhHk8Z`i9ro^wBsOs?RC!U{w8A#=)gsK=R~3` zD~p3&{BlB(PAgB&c`#!ySJ0;O3$h3FI7(L3qGb7SZwEwQ9 z1fwGUFpy9!8!~0`v|)DW@lh`UDc*j#nHe}M@^qBV`|zWf1&xPWPtvB}4>%!YS+BTx z?grR~OHdQdwcRFp0-fua(8nj2`!>UdP0y8K6&Sb~QcVOlh;v+OQ4@l2#GY>ASj0Ex zNwcMsP3VF~`~#?Ey-o}x^ zZgCdY8xPSkWng6m_DcmuPpG-%V6|S0SX!4Kr6b`cBu(#lZ$^psVIuP$&whl1-tax( zW5UM@5~F0J;KPY;q77DYFd&2Zwb*0|V}$w>4=VhMH$SJ=q8_>m}eR!TOaL z%&;T!KCyj!2C;t}eYY=}8k=vGKA7a51qvh2;)GA9#x#lAA`q}u)=@E}^S+HbVbk*H z<9aDjGM9=`Ct<5Y8`R}pyI5Ze@10){7otL2=M=rA6&bhO>S)E7nNLcUwXR&GSrd_2 z@V>jZ%|J!Pi}+yl8E%6tcSU%*8c?H_$DIiilMm&T*BW_6)SbET>*!Fk;>t>a7$=B7G zxT{ExR@$2{S!s8JPyI9gjkuh}t-yoav+sUfd}^aZP-v~$G^WpoZs+~9LPm$5vZ2zU z^GLW#8zxg&8aG$$yKdv4VeXT221wez)jzjhHW;9jbSF<)`(rYScw6 zo5R=u=h%x>lz%ylBf|HO3 zwmgmk+y>_ueWaRvMS;rVHppUZ{GG%m|DCgQSkM&~PVV(FJU99tfl|h6K`EE&x8my) zK8frFFf#`6-4Z`O-_|quTau>BrM)n&jju({*)9#qs)WN0**DZ6?7YHkgW?XUG_Up7 zYcdZ`*E$G**T)ftXt0`+*{2Z-88rTTIOqOq`;;~7J|M#0Nbz0k$LIS={gng0g452y zzQ@zSWl(kbbP*H!7BKSc2j7PZS(!S5UX0PCyg_82FFuXyC-vIE!D;Qxd9kQ5K~9&B z$avG=p6~_Q333tbRQ*}h^@D2*dTv|8d*ObZndRXOCDCq($Sf+3xN@>MVpSDtrEA{r zx#i10tV=@>7wZ8*Zj$9^355thGdmW0Cy3$-gKDb4Um49PqE*`AXJx{lMCWU^h>KIm zRe4SLKtBsjB~PaG=)ms%{h3Nm%Kt@9?broD+XI9`=yn#XiZ0ZaB?cv)7bp-3GlHVz zSV3M=vX!oq2?`!E7m%bU2KBfvm`Z!fbpaE-g7z=_@U&XRhIZxXk*6GFtJ9=)%!#vR zG4QtKGvQR`NfNg%RksSRN+Ol-X2+6#277*;T=&)RdZA7b1k30#0&(n7tP8ufWIka%%6U8KGx0ztar?xW<>Z8TnW^xeH?uW)Q6NzjA9^L#`%|p5T3qu$Z-J=iDglL0YS85*jKR&?QuwOf~sth}NsYwQ|&liXcb8VZYqBR!MgRSKxB21W<`nL#*c` z7rk;uH+?b97n;`my5cvu!~Y&W|1jMou6}9BwPNF?qGLrxP+xx##fVW&0Gf}Sd}5t^ z@NV06O{mRi7JSy<&E+g=2AvzyKWt-SWKm>HJIG$y%^dR7wpSa8XbMaJ!Q%N?e zz(QTHBsMP##4S|v@iBg}DR)6}wm!_IH?_8w4kU)%EWDYPErpJP**P!koXRc^_oN^> zp54SX49}OlCtTCObK(7Pb6N2Yr!vicFcAK%qc7aZRgh>?wyM-LboHM05qIe(Zf;rS z4yuC?z`;T7OeW~({G6B!Wpgj#-v^f87m5Y61?$;y=$$(4Rk{2(QornvU}MCDl;hwb zd423N0>7sNH5=s!uW(dNDhw=5o+4FOCR?Uz?~>T0mE@$DAgTYLZabG>Ms+a9jfqMq zAYdo>SXy5u43V|$T4Y@BPPL+<-4VU%nUaTLO#ThrO;q~~9&5to5uOEVFL5`M@8byf z`tBzY*KR!gYZp4rciapZP4`OC8P>jD@_#h(#~6HI$~peMgf)u*I;S_<86L#3y>Dmz zK=7Z-i3G75oC4hYOymAIc40`@_XOeV<0*OLPn%)CL^SB?zMrL$OGhpY7b-kBhb34W zYJU4yTJa+aE%ZAR+ko@eccPYIyBdAn%*fHTsBk|le!#`1ea0$0J6x=kYCEO=z!tP` z_Z~^=i&y|m|L6eNx9FiDcCjIo4Bs4mg_h__?Sie5NGC)Q?)TM;(w>?A_*7NfwVWdi zYf_;Z@KRi?CG4wnrH{tm+Z^ePJoaaPn%GZ}QXvWw)z3SM1$VD@^A0!qiy3S3&i{F3V*VANGew{jmLQpGs63^%57gs$Cwrd z%e*a>oQ7ufe2=X2vtf?&9$YQ0KG-n-8j=6~M=B9`&l*2Xb{r6r$i7>D9Y{9pMZv^` z!FWgd88g_LeA%#EYxD3cTG89%e%lQh{H{j`(zL%Z(toubY%M_&&e)jugW%-J|1r`3cr#CA;jyN7(S*j}Rn+F$S41|DhKjfAqlzvY+4Ed;IsCQ0k!f4AJXCqM<1NYT<8t z`F$Z1jM@0Y^AR8AuSfmepxq^bhwJsi#QMKK@PAnCUpGx{;)a9;D=ocad XJ~@j50{`VV;2%j*IgyIb2LAsKWk;0x diff --git a/doc/design/images/buffering_cpu_gpu_sync.png b/doc/design/images/buffering_cpu_gpu_sync.png deleted file mode 100644 index 2acd98d1ce9076daa3212957b7d995ed00e8daf4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 37349 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
Js@k)0l# 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 IP|x@O1Kv+LBme*a diff --git a/doc/design/images/gpu_async.png b/doc/design/images/gpu_async.png new file mode 100644 index 0000000000000000000000000000000000000000..c224ac5e1525814ee626b513bea3c447bcd03b5b GIT binary patch literal 26536 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 B`b7W$ literal 0 HcmV?d00001 diff --git a/doc/design/images/gpu_sync.png b/doc/design/images/gpu_sync.png new file mode 100644 index 0000000000000000000000000000000000000000..aa7e4be4897296fec4aa6f392adc977e94d393ee GIT binary patch literal 26105 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 literal 0 HcmV?d00001 From 47bf1cb85b71182b2443d749785b90681ec97f6c Mon Sep 17 00:00:00 2001 From: chengduoZH Date: Thu, 11 Jan 2018 10:11:47 +0800 Subject: [PATCH 4/6] refine python code --- .../concurrent_data_transfer_and_kernel_execution.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/design/concurrent_data_transfer_and_kernel_execution.md b/doc/design/concurrent_data_transfer_and_kernel_execution.md index a6eea326ac1a39..bb3a29f00760ba 100644 --- a/doc/design/concurrent_data_transfer_and_kernel_execution.md +++ b/doc/design/concurrent_data_transfer_and_kernel_execution.md @@ -50,15 +50,15 @@ class Channel { ... concurrent_program = Program() with program(concurrent_program): - image = data_layer(...) - label = data_layer(...) + image = fluid.layers.data_layer(...) + label = fluid.layers.data_layer(...) places = get_places() channel_list = create_channel_list(name="data_buffer") with parallel.for(places) as for_loop: - cur_channel = create_channel(channel_list, for_loop.i, channel_size=2) + cur_channel = fluid.layers.create_channel(channel_list, for_loop.i, channel_size=2) # if channel_list has the specific channel, # this function will return it directly. - send_to_channel(input=[for_loop.input(image), + fluid.layers.send_to_channel(input=[for_loop.input(image), for_loop.input(label)], out=cur_channel) main_program = Program() @@ -66,8 +66,8 @@ with program(main_program): places = get_places() channel_list = create_channel_list(name="data_buffer") with parallel.for(places) as for_loop: - cur_channel = get_channel(channel_list, for_loop.i) - image, label = receive_from_channel(input=cur_channel) + cur_channel = fluid.layers.get_channel(channel_list, for_loop.i) + image, label = fluid.layers.receive_from_channel(input=cur_channel) y_predict = fluid.layers.fc(input=image, size=1, act=None) cost = fluid.layers.square_error_cost(input=y_predict, label=label) From 877e14b77733d7919a5ff354a617e3c5c3eff19a Mon Sep 17 00:00:00 2001 From: chengduoZH Date: Tue, 16 Jan 2018 19:43:48 +0800 Subject: [PATCH 5/6] refine this doc --- ...rent_data_transfer_and_kernel_execution.md | 38 +++++++++---------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/doc/design/concurrent_data_transfer_and_kernel_execution.md b/doc/design/concurrent_data_transfer_and_kernel_execution.md index bb3a29f00760ba..7f956eae8de76d 100644 --- a/doc/design/concurrent_data_transfer_and_kernel_execution.md +++ b/doc/design/concurrent_data_transfer_and_kernel_execution.md @@ -48,32 +48,27 @@ class Channel { ``` ... -concurrent_program = Program() -with program(concurrent_program): +chan_list_name = "chan_list" +with fluid.go(concurrent_program, chan_list_name): image = fluid.layers.data_layer(...) label = fluid.layers.data_layer(...) - places = get_places() - channel_list = create_channel_list(name="data_buffer") + chan_list = fluid.channel_list.make(type=var.CHANNEL_LIST, name=chan_list_name) + places = get_places() with parallel.for(places) as for_loop: - cur_channel = fluid.layers.create_channel(channel_list, for_loop.i, channel_size=2) - # if channel_list has the specific channel, - # this function will return it directly. - fluid.layers.send_to_channel(input=[for_loop.input(image), - for_loop.input(label)], out=cur_channel) - -main_program = Program() -with program(main_program): - places = get_places() - channel_list = create_channel_list(name="data_buffer") + chan = fluid.channel_list.get_channel(chan_list, type=var.CHANNELTYPE,name="chan_{}".format(for_loop.i)) + fluid.channle.send(chan, data=[for_loop.input(image), for_loop.input(label)]) + +with fluid.go(main_program, chan_list_name): + chan_list = fluid.channel_list.make(type=var.CHANNEL_LIST, name=chan_list_name) + places = get_places() with parallel.for(places) as for_loop: - cur_channel = fluid.layers.get_channel(channel_list, for_loop.i) - image, label = fluid.layers.receive_from_channel(input=cur_channel) - + chan = fluid.channel_list.get_channel(chan_list, type=var.CHANNELTYPE,name="chan_{}".format(for_loop.i)) + image, label = fluid.channel.recv(chan) y_predict = fluid.layers.fc(input=image, size=1, act=None) cost = fluid.layers.square_error_cost(input=y_predict, label=label) - avg_cost = fluid.layers.mean(x=cost) - .... - + avg_cost = fluid.layers.mean(x=cost) + ... + for i in range(buffer_size): data = next(train_reader()) executor.run(concurrent_program, feed=feeder.feed(data)) @@ -89,6 +84,9 @@ for i in range(buffer_size): ``` In Python code, we define two `program`, `concurrent_program` used to send data into `Channel` and `main_program` used to get data from the `Channel` and execute training. If you're familiar with [`Goroutine`](https://www.golang-book.com/books/intro/10#section1) in the go language, you'll find that `main_program` and `concurrent_program` just like two `Goroutine`. +In `concurrent_program`, `fluid.channel_list.make` gets a `chan_list` according to the `chan_list_name`. `fluid.channel_list.make` creates a `global_variable` and puts it into `concurrent_program.global_block`. And then `places = fluid.get_places()` gets all available device on the current machine. The `places` is used in `parallel.for`. In `parallel.for`, according to `name="chan_{}".format(for_loop.i)`, `fluid.channel_list.get_channel` gets a `chan` from `chan_list`. After that, `fluid.channle.send` sends `image` and `label` to this `channel`. + +In `main_program`, roughly similar to the `concurrent_program`, the difference is that `main_program` gets `image` and `label` from `chan` by `fluid.channle.recv`. The names of `chan_list` in `concurrent_program` and `main_program` are the same, so the two `chan_list` are the same variable at the c++ side. ## Reference From d5c22cd0c70bd7f02bbc141003b77c7d2026d4bd Mon Sep 17 00:00:00 2001 From: chengduoZH Date: Wed, 17 Jan 2018 00:15:52 +0800 Subject: [PATCH 6/6] use chan_list_config --- ...rent_data_transfer_and_kernel_execution.md | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/doc/design/concurrent_data_transfer_and_kernel_execution.md b/doc/design/concurrent_data_transfer_and_kernel_execution.md index 7f956eae8de76d..0369ab4540690a 100644 --- a/doc/design/concurrent_data_transfer_and_kernel_execution.md +++ b/doc/design/concurrent_data_transfer_and_kernel_execution.md @@ -23,7 +23,6 @@ To support the above description, we need to define a new class: `Channel`. Here template class Channel { private: - using ChannelElement = std::vector; std::size_t capacity_; std::size_t bytes_limit_; @@ -31,13 +30,13 @@ class Channel { std::mutex mu_; std::condition_variable empty_cond_var_; std::condition_variable full_cond_var_; - std::deque channel_; + std::deque channel_; public: explicit Channel(std::size_t capacity, std::size_t bytes_limit); - void Put(ChannelElement* buffer_element) { ... } - void Get(ChannelElement* buffer_element) { ... } + void Put(T* buffer_element) { ... } + void Get(T* buffer_element) { ... } size_t Size() { ... } void Clear() { ... } }; @@ -48,21 +47,20 @@ class Channel { ``` ... -chan_list_name = "chan_list" -with fluid.go(concurrent_program, chan_list_name): +chan_list_config = fluid.channel_list.config(name="chan_list", type=var.CHANNEL_LIST) + +with fluid.go(concurrent_program, chan_list_config) as go: image = fluid.layers.data_layer(...) label = fluid.layers.data_layer(...) - chan_list = fluid.channel_list.make(type=var.CHANNEL_LIST, name=chan_list_name) places = get_places() with parallel.for(places) as for_loop: - chan = fluid.channel_list.get_channel(chan_list, type=var.CHANNELTYPE,name="chan_{}".format(for_loop.i)) + chan = fluid.channel_list.get_channel(go.chan_list, type=var.CHANNELTYPE,name="chan_{}".format(for_loop.i)) fluid.channle.send(chan, data=[for_loop.input(image), for_loop.input(label)]) -with fluid.go(main_program, chan_list_name): - chan_list = fluid.channel_list.make(type=var.CHANNEL_LIST, name=chan_list_name) +with fluid.go(main_program, chan_list_config) as go: places = get_places() with parallel.for(places) as for_loop: - chan = fluid.channel_list.get_channel(chan_list, type=var.CHANNELTYPE,name="chan_{}".format(for_loop.i)) + chan = fluid.channel_list.get_channel(go.chan_list, type=var.CHANNELTYPE,name="chan_{}".format(for_loop.i)) image, label = fluid.channel.recv(chan) y_predict = fluid.layers.fc(input=image, size=1, act=None) cost = fluid.layers.square_error_cost(input=y_predict, label=label) @@ -84,9 +82,9 @@ for i in range(buffer_size): ``` In Python code, we define two `program`, `concurrent_program` used to send data into `Channel` and `main_program` used to get data from the `Channel` and execute training. If you're familiar with [`Goroutine`](https://www.golang-book.com/books/intro/10#section1) in the go language, you'll find that `main_program` and `concurrent_program` just like two `Goroutine`. -In `concurrent_program`, `fluid.channel_list.make` gets a `chan_list` according to the `chan_list_name`. `fluid.channel_list.make` creates a `global_variable` and puts it into `concurrent_program.global_block`. And then `places = fluid.get_places()` gets all available device on the current machine. The `places` is used in `parallel.for`. In `parallel.for`, according to `name="chan_{}".format(for_loop.i)`, `fluid.channel_list.get_channel` gets a `chan` from `chan_list`. After that, `fluid.channle.send` sends `image` and `label` to this `channel`. +In `concurrent_program`, `fluid.go`'s inputs are `program` and `chan_list_config`/`chan_config`. According to `chan_list_config`/`chan_config`, `fluid.go` calls `fluid.channel_list.make`/`fluid.channel.make` to get `chan_list`/`channel`. `fluid.channel_list.make`/ `fluid.channel.make` creates a `global_variable` and puts it into `program.global_block`. And then `places = fluid.get_places()` gets all available device on the current machine. The `places` is used in `parallel.for`. In `parallel.for`, according to `name="chan_{}".format(for_loop.i)`, `fluid.channel_list.get_channel` gets a `chan` from `chan_list`. After that, `fluid.channle.send` sends `image` and `label` to this `channel`. -In `main_program`, roughly similar to the `concurrent_program`, the difference is that `main_program` gets `image` and `label` from `chan` by `fluid.channle.recv`. The names of `chan_list` in `concurrent_program` and `main_program` are the same, so the two `chan_list` are the same variable at the c++ side. +In `main_program`, roughly similar to the `concurrent_program`, the difference is that `main_program` gets `image` and `label` from `chan` by calling `fluid.channle.recv`. The configs of `chan_list` in `concurrent_program` and `main_program` are the same, so this two `chan_list` are the same variable at the c++ side. ## Reference