From ef0d63f4512e49db65c558a3621aed069fb9245e Mon Sep 17 00:00:00 2001 From: Christophe Favergeon Date: Mon, 14 Feb 2022 09:49:28 +0100 Subject: [PATCH] CMSIS-DSP: SDF Improvements Improvement to the SDF memory optimization using graph coloring. --- SDFTools/examples/example1/test.dot | 14 +- SDFTools/examples/example1/test.pdf | Bin 21227 -> 21247 bytes SDFTools/examples/example2/test.dot | 104 ++++++---- SDFTools/examples/example2/test.pdf | Bin 30081 -> 30082 bytes SDFTools/examples/example3/test.dot | 70 +++++-- SDFTools/examples/example3/test.pdf | Bin 32621 -> 32622 bytes SDFTools/examples/example4/test.dot | 70 +++++-- SDFTools/examples/example4/test.pdf | Bin 32621 -> 32622 bytes SDFTools/examples/example5/test.dot | 38 +++- SDFTools/examples/example5/test.pdf | Bin 29469 -> 29648 bytes SDFTools/examples/example6/test.dot | 30 ++- SDFTools/examples/example6/test.pdf | Bin 25379 -> 25373 bytes SDFTools/sdf/schedule/config.py | 3 + SDFTools/sdf/schedule/description.py | 242 ++++++++++++------------ SDFTools/sdf/templates/dot_template.dot | 14 ++ 15 files changed, 378 insertions(+), 207 deletions(-) diff --git a/SDFTools/examples/example1/test.dot b/SDFTools/examples/example1/test.dot index 8a8797ef..4dff5dc5 100755 --- a/SDFTools/examples/example1/test.dot +++ b/SDFTools/examples/example1/test.dot @@ -31,9 +31,17 @@ source [label=< -source:i -> filter:i [headlabel=<7>,taillabel=<5>,label="f32(11)"] - -filter:i -> sink:i [headlabel=<5>,taillabel=<5>,label="f32(5)"] +source:i -> filter:i [headlabel=< +
7 +
>,taillabel=< +
5 +
>,label="f32(11)"] + +filter:i -> sink:i [headlabel=< +
5 +
>,taillabel=< +
5 +
>,label="f32(5)"] } diff --git a/SDFTools/examples/example1/test.pdf b/SDFTools/examples/example1/test.pdf index b3c1f0122e7e83f14363613c6c90f2558aeab5a0..821662125bd0b35b9546c238f3d5ac107d619ab1 100755 GIT binary patch delta 728 zcmaF8l=1&k#tFXlLB9DShCF+phyR!%qqbGJS}0yyafz40g5vCIhr92b>>Y9(|J2Um zd9!X>?6wRO$?89X_WQq|RowFYaJI$ojty01EcS2jx9BEX!Zf)~{p!Ic&reT6^mtxY*P=UTZpVsP2L#KUJhf!)?OPc$ zYuk?JUU(+aKP^|4jUfAG7S7<}qb*X=-n%_HEzl zziTg-yl3kS-J-zgdV9(i-t!ah$`&bK*db@sv*7H{*-md1hX| z?AKE+oCuo9>M&EOu>8b}lRLQ^rX=eY#W3hPrk>VVd9F_QfZ7hh19iU)83WG!*Ja33 z+v~y_vipYg>f@mSySR>J7*1-|s(4?=XuXkb30G=fN^wb1YGN*km7kQwWujo90HPHX z6im!ED>60uiy8yPKtLf+feXwqFfcWrygg98-qZ+9#>l|X5>vIAg)y2s0|N_7b2Kra zPE%7%F>^}{F$+rru$URbNrsk|hUk_U8JJn3Yc?{lFq%9$$e+`~fJ;@?)!&T^0J4Q0 A)Bpeg delta 683 zcmeyrl=1aa#tFXllYISU40+n#{}i=TYv(LWdj7bpMN4sO*6BM9%t<$OS))obukMdm zXSVLRo4V3%@<#P-kInn*C0oAL{AF+t=UDCT{2~1R+*iNv&WUHLYH3w$=@$@KXdu8U zA(2?iobG?~wWv&g+YakroHBbIPVG~8=44kup1l=zENsqO ze)ps6Zhbn*`jRv0&7$XDd$_Nkx0ZaK-LchV>X~*IqiNe+{oa;L-8*r&r}VD~=ZSlw z??+xYFR#BoEjBmk!@@KV9)5x3`mZ`0Ee#j1pRp^ldHSidd+Js`YQ6G6ICIvP*Vl|p z{p}9_-Lvv}$FKWmUVnIOD=wUDdBV=>lvzn`?6#cKOP(J})RLL^n>)&Mqq^Q2_1vrC z($&WV*YkLwD1rMN|^aKdYo+WM&bR=rzh9xgY2cX`L+1MfDfguD$^yC>rLw7h+a zgD^U!aqr|a(NE;z+AA#3iRW7V5?KKyG{BcI>(aerm7@k`qa^Jgtl$ag%yEH=p%GBsDYG|Th00Ihm3S3}@fq|*%TSTmbDE6iEO8 diff --git a/SDFTools/examples/example2/test.dot b/SDFTools/examples/example2/test.dot index dc3a90e0..6bb73e30 100755 --- a/SDFTools/examples/example2/test.dot +++ b/SDFTools/examples/example2/test.dot @@ -23,13 +23,13 @@ arm_add_f321 [label=< arm_add_f32
(CMSIS-DSP) o - + ib - - ->]; + + +>]; arm_scale_f321 [label=< @@ -39,13 +39,13 @@ arm_scale_f321 [label=< arm_scale_f32
(CMSIS-DSP) o - + ib - - ->]; + + +>]; arm_scale_f322 [label=< @@ -55,13 +55,13 @@ arm_scale_f322 [label=< arm_scale_f32
(CMSIS-DSP) o - + ib - - ->]; + + +>]; audioWin [label=< @@ -99,7 +99,8 @@ toMono [label=< - + + @@ -107,7 +108,6 @@ toMono [label=<
toMono
(Unzip)
o1
o2
>]; - srcDelay [label=< @@ -116,26 +116,62 @@ srcDelay [label=<
>]; -src:i -> srcDelay:i [taillabel=<320>] - -srcDelay:i -> toMono:i [headlabel=<320>,label="f32(330)"] - - -toMono:o1 -> arm_scale_f321:ia [headlabel=<160>,taillabel=<160>,label="f32(160)"] - -toMono:o2 -> arm_scale_f322:ia [headlabel=<160>,taillabel=<160>,label="f32(160)"] - -arm_scale_f321:o -> arm_add_f321:ia [headlabel=<160>,taillabel=<160>,label="f32(160)"] - -arm_scale_f322:o -> arm_add_f321:ib [headlabel=<160>,taillabel=<160>,label="f32(160)"] - -arm_add_f321:o -> audioWin:i [headlabel=<320>,taillabel=<160>,label="f32(320)"] - -audioWin:i -> mfcc:i [headlabel=<640>,taillabel=<640>,label="f32(640)"] - -mfcc:i -> mfccWind:i [headlabel=<250>,taillabel=<10>,label="f32(250)"] - -mfccWind:i -> TFLite:i [headlabel=<500>,taillabel=<500>,label="f32(500)"] +src:i -> srcDelay:i [taillabel=< +
320 +
>] + +srcDelay:i -> toMono:i [headlabel=< +
320 +
>,label="f32(330)"] + + +toMono:o1 -> arm_scale_f321:ia [headlabel=< +
160 +
>,taillabel=< +
160 +
>,label="f32(160)"] + +toMono:o2 -> arm_scale_f322:ia [headlabel=< +
160 +
>,taillabel=< +
160 +
>,label="f32(160)"] + +arm_scale_f321:o -> arm_add_f321:ia [headlabel=< +
160 +
>,taillabel=< +
160 +
>,label="f32(160)"] + +arm_scale_f322:o -> arm_add_f321:ib [headlabel=< +
160 +
>,taillabel=< +
160 +
>,label="f32(160)"] + +arm_add_f321:o -> audioWin:i [headlabel=< +
320 +
>,taillabel=< +
160 +
>,label="f32(320)"] + +audioWin:i -> mfcc:i [headlabel=< +
640 +
>,taillabel=< +
640 +
>,label="f32(640)"] + +mfcc:i -> mfccWind:i [headlabel=< +
250 +
>,taillabel=< +
10 +
>,label="f32(250)"] + +mfccWind:i -> TFLite:i [headlabel=< +
500 +
>,taillabel=< +
500 +
>,label="f32(500)"] HALF [label=< diff --git a/SDFTools/examples/example2/test.pdf b/SDFTools/examples/example2/test.pdf index 38415ac6d67e0a2b789a887163456fa21d6763a9..485a0e51aef60b2068a0697c23bd462ea2287287 100755 GIT binary patch delta 1941 zcmZXOc{tRI8pqLOEg{ApV#Zj)j4@+ELiT;%%Q*)_#=Z>0_(ha8#z@x4k*$dk#}cC< zJCRA2NDim$Wf@sJ=id7~_j#`S{`Gx6@B4k;PuwbV{3>&%1MtH~qG!2gVGa1@7W~_&x7r=u-ya(O=CZ%PT)=q!)b~>? z4tI#|(4zg^8y^4iT-fZex~`n~(WR-XQK_kLIvu^fzRKvIJZAVu*ZEUE2p-j&1mlXRM-F<&5U^Z?4Pnmb`=d*t18g6Nu!;J?a(RQ6tjE(tbXHh*U*J;k z7#UE$D97>bMd=-;6(meaSec+^jH{i&MY6wMb!B+ZYv$;QxCObyMhV`Vg}tM(rGkBv z6!n;?TT)Gq_-g0M$oD4`Lj*UwQFBb~uNrk)@#~X#WO_xvj`l|wrI-l~fp z^>-~*k!6LNDGgO(dDjlaG(?Ba89}|y6#&1Rd6^`-e!0pIF8IpdYuta$gA@N)Z$AmU zadTzc#wQfAVV@uQxn04O;CRIUe*;!`HuG<9#+PKGYn8 zZ$6rDh)LwFonc~IP+fKf{Y)Fw7mS-{vX;eOfwH0%4#*B`PSFr(nlMo;oM_*}4p6p2 zD+P{+qv;@_MV~D!=coz1P_ff!;kvtiR5e;Cpi8ew3e>z(#Z+V77}@{@O6`9?4z%e8 zRmj2V&fCaEUF{&LBV_;+_Vva<78Th zNW7)S{*p1V6q$y#MkjBU?B@fFkRpv@6GBzQU&9aCO3(i3?@j=(_lzcQkA3WfM$1Il z*u!S^xjEjFHfi7abCzpvDDN}nT1Lev1x<@6I*R#o#8Kjk`oV8~pKq7Mi{E1L-tx1~ zL_HDP(@BrF?qC<#Ku(_3-L_Cec=(6K!ph9P$&NF>ZV|m)+R*o`&gvVGlsMS{_Aa@) zK<>icdDZb8b7oO4ZaWti3nT6JrM}F9#g^Dzou6&u|MvKkSva5jkwit^;wH5yf@ zB^l-WAYVw6N}M}j$&B+1nf&nTEOtMQ;u|iD+e4=@=0|Gg zZW%3w<91K;&1k@!M4OC+kf@u6E>cEDgqhw_PLZRJh8`P8&tJHlFRGTO<860=2y7&$ z;(r=0V0RCxtAGzz_Et~20^8+hm67BL>y|o!zGa@RV3Vs+Ca%R<80RgO(qG+>(CO@~>33_pe(^SY|**02EP0$kt|b-LdZxDji?y`YL!HT3#&DL zI0P_t06f?#KsTy+UX&Lbe0xcVo;ze~9mACSE%#;shG+L4h2x>21vz08N1|Yqg^|*~ z_)SVWp_ZghX#IvjcW(?1NYda8?1N1@UGVW|HqA=J_T2>!1o0;8t-e}Whk3PF|+ Pw`5o2gh2Ey4LJV>t?qmv delta 1940 zcmZXOcQ_l08pdf;v5Ke_dykGt#7IPGjaXGwwbceqsaf=pOIsz@b14oXv3t~})G10u zgisAhj9N89)og`JYt$a++- zqvSoAuktg;``f$ZnFrh z#1R;{ffguF9mjLzDnB3DZPb4WL)osF83pV|Se8YMo*6wF2Y+c@&HtgGhx&3)C#8;^ z<7TO~;$Hau-FrB$oHloa8~nPn<)Tsiyv1Y{N>NQpWSKV<=g4_#d5gC!WOh1d9sgN8 z>~_7JH!@p!LXYqO;82#*uNE|yx&5q{*wS{(Y9qdq8g_pcf) zulnS8%dc?^;(d3fQEEy1y;Uu-e*>LJ!(|gq#3pTFFVgz0~M6I9C)C$a)HzNLv9t>S`6Zb9#TR9}_|eg7;m0D0E{SbrJ2I zm(APK%WPjKzP`wTfVl!=^0_$HQggq~J6$ftf2arv#ttHo?#Mkfrnmpo7zK7ue_M?YQRtea|&}M+L1sk(>aJmEjs@K)t{2v0ZZZ z{X7Y?KMamhS~`_^q&pT3>K|)9yG7F7^uRm@#ik+$nx@ob=^jM&W7TBQo9eXW^G8cX6|}v0HLuDuoK?xl&wK^Xqg908!yZtJN$}kF`@6(1a+h{)t#v2u#sp%uP1!j%u5!g zgK@z|Jo=~5yB|EsL(?LHcBs#bQ4IsTGla+O0qTHLn+XeXVp-4Ehx8F2@n(Rk$JkSq zYBXdV52Je`S10O~tdTHtHeS?Km}(`!ob~1}Ig6z+o6^hyk`DuBNQI>6**49%w1V4i z${>TZgy}2F=y%USqH;2_*1DXVYM_x&;}<21jYP&$TQ|%XS)u+(H3r-(7%yw7fomI9 zlBs{zUu0W2>dQ4I0|4Ne+E|udFe425E8#UuvVC)GI)PK-B<|EzW+FKR>Z{H+d?~q1 z+05M_WtToy7)p28j~eo^%Xq=etwNnwVg-Ooc~fgtZHys&LDUSs(sGi`dCY^<8xou^ z^1u3`?co}z!Az{9B2x%`Z|tmZYi-d|=rvdeDK+W!L@`rHzMZ8Xo^&U{RB$%{+@kJ1yu>8nS{+Jg&oJM z_^j>Ix_#hyQZQTS0#G@r0`W(tV-rlA!4X@>+OUmEU)x)6m*Z5O`0;XG%4LK;3$jU5 zXK(OI$Ew5r#UIF#1I@Wy71iRg_rtdI)be^dD9s2QXc zIYLj9&RXx`#;8oAYY27Jro}zLxvrSk1qI0FMZ8_bf=Gwe*0}@Cf|-)F1Lyu zn@Dj6x`)3FIBU(nchD?iJ-FhfS`9WbKg&W|t|CV|2VF5Jo`C6afmfB`JDESYTkpr? zweU7i5pxP4|J{-uO%l1s(ed&dVUPB%=}FUhnL1Txp{I5aSmCj8y@q|om($;O`U83> z7+a7uKOIT#mMRM!qW`YyWLl9Cg4k1#J`}D>3F=17$v+Hc&lSyF0@QE(#94LBzD^#9BB|2OGxh(w+YBK6?^HxQ|>4arm_mult_f32
(CMSIS-DSP)
- + - - -
o
ib
>]; + + +>]; audioOverlap [label=< @@ -82,21 +82,53 @@ toReal [label=< -src:i -> audioWin:i [headlabel=<128>,taillabel=<192>,label="f32(256)"] - -audioWin:i -> arm_mult_f321:ia [headlabel=<256>,taillabel=<256>,label="f32(256)"] - -arm_mult_f321:o -> toCmplx:i [headlabel=<256>,taillabel=<256>,label="f32(256)"] - -toCmplx:i -> cfft:i [headlabel=<512>,taillabel=<512>,label="f32(512)"] - -cfft:i -> icfft:i [headlabel=<512>,taillabel=<512>,label="f32(512)"] - -icfft:i -> toReal:i [headlabel=<512>,taillabel=<512>,label="f32(512)"] - -toReal:i -> audioOverlap:i [headlabel=<256>,taillabel=<256>,label="f32(256)"] - -audioOverlap:i -> sink:i [headlabel=<192>,taillabel=<128>,label="f32(256)"] +src:i -> audioWin:i [headlabel=< +
128 +
>,taillabel=< +
192 +
>,label="f32(256)"] + +audioWin:i -> arm_mult_f321:ia [headlabel=< +
256 +
>,taillabel=< +
256 +
>,label="f32(256)"] + +arm_mult_f321:o -> toCmplx:i [headlabel=< +
256 +
>,taillabel=< +
256 +
>,label="f32(256)"] + +toCmplx:i -> cfft:i [headlabel=< +
512 +
>,taillabel=< +
512 +
>,label="f32(512)"] + +cfft:i -> icfft:i [headlabel=< +
512 +
>,taillabel=< +
512 +
>,label="f32(512)"] + +icfft:i -> toReal:i [headlabel=< +
512 +
>,taillabel=< +
512 +
>,label="f32(512)"] + +toReal:i -> audioOverlap:i [headlabel=< +
256 +
>,taillabel=< +
256 +
>,label="f32(256)"] + +audioOverlap:i -> sink:i [headlabel=< +
192 +
>,taillabel=< +
128 +
>,label="f32(256)"] HANN [label=< diff --git a/SDFTools/examples/example3/test.pdf b/SDFTools/examples/example3/test.pdf index c4360537e8b96c65b5dcac19c38091fc4f424224..5c1db1b78648b7209530165a1885fffd8f51cbd2 100755 GIT binary patch delta 1591 zcmZXOc{tPw7{?ooaV{o9DjHXWGWU$!>kgwvVUQkHa)ljNiTUM%D{pCRvzega>t5JGaFL<7S!bhWuxjsBzvIO^)YU>U?~x zDEYKozN_6DO5pqSVn?LiSa&XqMntBjoikzYUiBUoT2SzZ#xyzAhgCC3s;qZA z_Ysw+AQC!@F*0rCAQ`T#N@usuQOtd8_yFeGw^sSBd*+yvLdw&W$Q3U_NsX$PwElPT2K<(qO*=@>&ON8SblLzE0E zI2?`f7*z&6TtDPHyDCJr)H+j~sA(IFDx-VGJ`PvC(v>k|02(OSf?kVdR2u0;#Xh*q z)OMycax6V0_;JWZL->>U!+t<$OhMZ>aZMEs`Lw!xrK+Q$HFCqZsY=z^e>`xRp|Ndt zo-{^^iY1G_&P)-XY-wP{Nenq_c8b%!WUs%GBmg=^jY0QV%J~D1u{@?-O|GjMq9PGm znAXsy*sJ40D(<6e+cra1p{}!T2MmcBzAxw}yu%`bWv1?OrPy=%z-9 zB)eW|UKg@LR;rH!h`=5c+Y;LL-Dz!~um^%ZP_fgihe>#ii) z^$~=nE_ABW_Ga{3^?Oy$(<8?vEQB*mMyDIaKz?&o4U(S=bYBr|A5J-!h}n7dt;Ivx z1Y6&j@`<@ciw?fT&-S(Jlb&_nr7EaF&lCeiY^U1t;3p;C0t5Ldf z*x{I|SpoNGZqY3jLH^b`emGyB2bEsQNd?0}=;x2YvDaV*aKt|Y4}nYkyC9GlEFtGK zRSUrGanMLCazBm5;rDO|B%XlUqoENvJYk=PN9^N}DCB>=xc^^5BT?vm$0!6Ivo{ch TLZEUK04Fi5gr=sIleNU(9-Y+I delta 1590 zcmZXOdpOez7{`wgCLCldh6yRLnX$Po4e9 zI+U0zVQsTF=7S++^8~Pj>2#AGA*_X%^cx_vS;9;mlQ!R>j3Uf5p>B7sSa;}ld^>-< zc>K`4q2ZLac{qR(>v(g|M`UvC#dv@@r+EMK1uxh&6GJJq{xq1U7KpWtxtr4@f z^k0c}P=7F8sO$%ydg(S?oN#ToD1Ve#(XE~1{A%w5`FtQk0@Xfrr>fM!<5n#17=tSe&CD1;LOn(|~k|}1;_F}oE>g&{_R4>7bJ$VW4%?MyX zG|xq`*(v9^WL4NGtEI_#TgS^^9*dU^hCl6^`E+#R7%9_Eh6EDbI;qzkHV5FmdaZQ%%G=?oYx_Oq*YwZ&1vbkXIqY z0dLKSk}xuN;tF@Qr-En1&w(TsskKc~df?W?WW}+CA_Pw*-g-&Uv03#K;JFEoP%nFz zQV}^cV+p&VSJYtq5oQR+>Pg=NP4yR#vtq1;(A5uu!IR`$MZ5dQb3F70)i>^<1 zuKz_YD~j6bwD1ahlxhdqUvjw}Qo*k;^F#LHM*j5e{Bah(%e#L`Ww!tnh_{BklOi-g zEa!jJ$f=Tvy1iANd1wYb}xG2HBVQs})}P<^eb;_t5T zKU~PrDy}K0rAvIBljx{wf YsDpu;ni|Mt2w)|s1yWWvvoZ($4L%pzkN^Mx diff --git a/SDFTools/examples/example4/test.dot b/SDFTools/examples/example4/test.dot index 4c072ec7..87632a28 100755 --- a/SDFTools/examples/example4/test.dot +++ b/SDFTools/examples/example4/test.dot @@ -16,13 +16,13 @@ arm_mult_f321 [label=< - + - - -
arm_mult_f32
(CMSIS-DSP)
o
ib
>]; + + +>]; audioOverlap [label=< @@ -82,21 +82,53 @@ toReal [label=< -src:i -> audioWin:i [headlabel=<128>,taillabel=<192>,label="f32(256)"] - -audioWin:i -> arm_mult_f321:ia [headlabel=<256>,taillabel=<256>,label="f32(256)"] - -arm_mult_f321:o -> toCmplx:i [headlabel=<256>,taillabel=<256>,label="f32(256)"] - -toCmplx:i -> cfft:i [headlabel=<512>,taillabel=<512>,label="f32(512)"] - -cfft:i -> icfft:i [headlabel=<512>,taillabel=<512>,label="f32(512)"] - -icfft:i -> toReal:i [headlabel=<512>,taillabel=<512>,label="f32(512)"] - -toReal:i -> audioOverlap:i [headlabel=<256>,taillabel=<256>,label="f32(256)"] - -audioOverlap:i -> sink:i [headlabel=<192>,taillabel=<128>,label="f32(256)"] +src:i -> audioWin:i [headlabel=< +
128 +
>,taillabel=< +
192 +
>,label="f32(256)"] + +audioWin:i -> arm_mult_f321:ia [headlabel=< +
256 +
>,taillabel=< +
256 +
>,label="f32(256)"] + +arm_mult_f321:o -> toCmplx:i [headlabel=< +
256 +
>,taillabel=< +
256 +
>,label="f32(256)"] + +toCmplx:i -> cfft:i [headlabel=< +
512 +
>,taillabel=< +
512 +
>,label="f32(512)"] + +cfft:i -> icfft:i [headlabel=< +
512 +
>,taillabel=< +
512 +
>,label="f32(512)"] + +icfft:i -> toReal:i [headlabel=< +
512 +
>,taillabel=< +
512 +
>,label="f32(512)"] + +toReal:i -> audioOverlap:i [headlabel=< +
256 +
>,taillabel=< +
256 +
>,label="f32(256)"] + +audioOverlap:i -> sink:i [headlabel=< +
192 +
>,taillabel=< +
128 +
>,label="f32(256)"] HANN [label=< diff --git a/SDFTools/examples/example4/test.pdf b/SDFTools/examples/example4/test.pdf index c4360537e8b96c65b5dcac19c38091fc4f424224..5c1db1b78648b7209530165a1885fffd8f51cbd2 100755 GIT binary patch delta 1591 zcmZXOc{tPw7{?ooaV{o9DjHXWGWU$!>kgwvVUQkHa)ljNiTUM%D{pCRvzega>t5JGaFL<7S!bhWuxjsBzvIO^)YU>U?~x zDEYKozN_6DO5pqSVn?LiSa&XqMntBjoikzYUiBUoT2SzZ#xyzAhgCC3s;qZA z_Ysw+AQC!@F*0rCAQ`T#N@usuQOtd8_yFeGw^sSBd*+yvLdw&W$Q3U_NsX$PwElPT2K<(qO*=@>&ON8SblLzE0E zI2?`f7*z&6TtDPHyDCJr)H+j~sA(IFDx-VGJ`PvC(v>k|02(OSf?kVdR2u0;#Xh*q z)OMycax6V0_;JWZL->>U!+t<$OhMZ>aZMEs`Lw!xrK+Q$HFCqZsY=z^e>`xRp|Ndt zo-{^^iY1G_&P)-XY-wP{Nenq_c8b%!WUs%GBmg=^jY0QV%J~D1u{@?-O|GjMq9PGm znAXsy*sJ40D(<6e+cra1p{}!T2MmcBzAxw}yu%`bWv1?OrPy=%z-9 zB)eW|UKg@LR;rH!h`=5c+Y;LL-Dz!~um^%ZP_fgihe>#ii) z^$~=nE_ABW_Ga{3^?Oy$(<8?vEQB*mMyDIaKz?&o4U(S=bYBr|A5J-!h}n7dt;Ivx z1Y6&j@`<@ciw?fT&-S(Jlb&_nr7EaF&lCeiY^U1t;3p;C0t5Ldf z*x{I|SpoNGZqY3jLH^b`emGyB2bEsQNd?0}=;x2YvDaV*aKt|Y4}nYkyC9GlEFtGK zRSUrGanMLCazBm5;rDO|B%XlUqoENvJYk=PN9^N}DCB>=xc^^5BT?vm$0!6Ivo{ch TLZEUK04Fi5gr=sIleNU(9-Y+I delta 1590 zcmZXOdpOez7{`wgCLCldh6yRLnX$Po4e9 zI+U0zVQsTF=7S++^8~Pj>2#AGA*_X%^cx_vS;9;mlQ!R>j3Uf5p>B7sSa;}ld^>-< zc>K`4q2ZLac{qR(>v(g|M`UvC#dv@@r+EMK1uxh&6GJJq{xq1U7KpWtxtr4@f z^k0c}P=7F8sO$%ydg(S?oN#ToD1Ve#(XE~1{A%w5`FtQk0@Xfrr>fM!<5n#17=tSe&CD1;LOn(|~k|}1;_F}oE>g&{_R4>7bJ$VW4%?MyX zG|xq`*(v9^WL4NGtEI_#TgS^^9*dU^hCl6^`E+#R7%9_Eh6EDbI;qzkHV5FmdaZQ%%G=?oYx_Oq*YwZ&1vbkXIqY z0dLKSk}xuN;tF@Qr-En1&w(TsskKc~df?W?WW}+CA_Pw*-g-&Uv03#K;JFEoP%nFz zQV}^cV+p&VSJYtq5oQR+>Pg=NP4yR#vtq1;(A5uu!IR`$MZ5dQb3F70)i>^<1 zuKz_YD~j6bwD1ahlxhdqUvjw}Qo*k;^F#LHM*j5e{Bah(%e#L`Ww!tnh_{BklOi-g zEa!jJ$f=Tvy1iANd1wYb}xG2HBVQs})}P<^eb;_t5T zKU~PrDy}K0rAvIBljx{wf YsDpu;ni|Mt2w)|s1yWWvvoZ($4L%pzkN^Mx diff --git a/SDFTools/examples/example5/test.dot b/SDFTools/examples/example5/test.dot index 2bbf4bd7..b28b8dee 100755 --- a/SDFTools/examples/example5/test.dot +++ b/SDFTools/examples/example5/test.dot @@ -52,15 +52,35 @@ toMono [label=< -src:i -> toMono:i [headlabel=<384>,taillabel=<384>,label="q15(384)"] - -toMono:i -> audioWin:i [headlabel=<768>,taillabel=<192>,label="q15(768)"] - -audioWin:i -> mfcc:i [headlabel=<1024>,taillabel=<1024>,label="q15(1024)"] - -mfcc:i -> mfccWin:i [headlabel=<377>,taillabel=<13>,label="q15(377)"] - -mfccWin:i -> sink:i [headlabel=<754>,taillabel=<754>,label="q15(754)"] +src:i -> toMono:i [headlabel=< +
384 +
>,taillabel=< +
384 +
>,label="q15(384)"] + +toMono:i -> audioWin:i [headlabel=< +
768 +
>,taillabel=< +
192 +
>,label="q15(768)"] + +audioWin:i -> mfcc:i [headlabel=< +
1024 +
>,taillabel=< +
1024 +
>,label="q15(1024)"] + +mfcc:i -> mfccWin:i [headlabel=< +
377 +
>,taillabel=< +
13 +
>,label="q15(377)"] + +mfccWin:i -> sink:i [headlabel=< +
754 +
>,taillabel=< +
754 +
>,label="q15(754)"] } diff --git a/SDFTools/examples/example5/test.pdf b/SDFTools/examples/example5/test.pdf index bac671a5d9a4dcc477d1ae4b5ec9d26089540c6a..ce5864fb507ed9942f67991c5f2bc005f86441a8 100755 GIT binary patch delta 28177 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 a{}+#wlP__=MG2Xcj{}*8Mp{J%`9A=bj|h(d delta 27983 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
  • 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 audioWin:i [headlabel=<128>,taillabel=<192>,label="f32(256)"] - -audioWin:i -> mfcc:i [headlabel=<256>,taillabel=<256>,label="f32(256)"] - -mfcc:i -> mfccWin:i [headlabel=<13>,taillabel=<13>,label="f32(13)"] - -mfccWin:i -> sink:i [headlabel=<13>,taillabel=<26>,label="f32(26)"] +src:i -> audioWin:i [headlabel=< +
    128 +
    >,taillabel=< +
    192 +
    >,label="f32(256)"] + +audioWin:i -> mfcc:i [headlabel=< +
    256 +
    >,taillabel=< +
    256 +
    >,label="f32(256)"] + +mfcc:i -> mfccWin:i [headlabel=< +
    13 +
    >,taillabel=< +
    13 +
    >,label="f32(13)"] + +mfccWin:i -> sink:i [headlabel=< +
    13 +
    >,taillabel=< +
    26 +
    >,label="f32(26)"] } diff --git a/SDFTools/examples/example6/test.pdf b/SDFTools/examples/example6/test.pdf index dcf9b4c8bcc1a503a6c56e2d89671ddd79561b20..f4c0c35b90ee2a751b462e044568fbe758ae32a7 100755 GIT binary patch delta 928 zcmZ2{jB)NU#tDA)-uc3Y0>|I~)~wmW|GFy8rY@$NVPz2i1rM29a;x?&Fi{9n+-GNe zFJ*FD&LyRmMHY`M{>=FK-{#*%*2VMt-=Do0YVh4(c1HZC`<*rNyFPmh*BF?~vJ__t zbf*U|TAA`o;>@FKb99&MzdQSJP4f+_PtAti*{AlkOyHhzbC30|*Ut6&&1q%V=ib(4 z&#AZ4_;&2;lsDqj7yZ3=#(&-M1@#mDKGREAkL6#+E^p+rCap|)v;G?9E$NTs-Y!0u zbNTqxl0|E3)}P&Y*dnK7dGQj)>emW4TVEg9Q;^%eeRHXt(jfu0>&}U8UcV2|vDP^} z?|RV=rCe@}3f^T)?iS9qa{9fF^?SWrQQ-8qeTyf_n5vs-&f2NS)_>sE!k}7(0Ar_5 zij!ttpIx}-uqgYQn=0RCrb_be|GKy`hJTU!w13a@ZvU-NG8Or}?}&-v3CC?KZt*ml zPu}Wj^~ok7BDe9dSjGym`Po`UeG#=QRfB#Ot3P>Sle} z4|`i5dbX^UK2#_Ba>A|ymFBX}z8MK7E_qu!w2Z#w)GxI!y6iVU=#%D^#>SA@C6U@z zrWc=fb)*zV{eKpaAriXz;xDfQ78Xhy-r5~?SoNd4RB3NZqs&EdMfn%5JR%b;rFjx= zr74K9E@)|HxN`WFep}W?k+_igI^5MQ^7qb!@ru2Eby=p&fgxhr_OiSN(??+<3nsZ| zsVS|En|N1d#bKRecaIewJzkj6l5o1bi}AtUrC;Osh)VoOFtpe{Nv=|xD{{q-sQ1p_ zrKNx0-#7U;lRTsGW@+XFaiRta1|Xo2r@#ef7#Nsanos_as8(-oiY8@bVr*c6CT3t@ zX<&vfW@u=HZmf~9sWG}wRV7>9h*YmIbNvbOO#QswLS&_xdssP)F=?9Vn5A&|ycY!Tne&LSm{hK!F z$(K)R-Sc@b&vCX|>lc34J}~^c=5VF>^2W-$6WzC1_r%-b{B z`(mDLRC}^UW%A>1d;EA8{tK8~eY}3FMt9-q(9ZRJ!M&Es)~0Gs0bAS$oD@ zb;I@7KSwM*%@{GM>)^5jw>^H9zPtMPRHqp8`Tb?HA08K8syM$)beUN*k4o>Q+0!aa zn|T6l&I`9a6}-{s@KpBxsv~E;^(+%q*sPeJANm^i>zcNd zP`&J_3XOlIYo`Z3Xlr{dl*iq~@HhUL@pQ&wW_64F8dj># z{FXJHy<{4+Sy0JUMwu?>AZiC`vTMSj)hCM^m!Mroo?8ADWfw{ zUbjtulyz>Cbz^i7_G0X1g(~;*CkG zbsQACLwsGLjP^xrYgS;)_BZddw(DCrv8nflCWpcsk?Zvze>sHnO<+EA`nr3?GFDb` znVMJsn5Gpzy)yYLlRTs4W>Mw?aiV4l1|Xo2r@#ef7#LU>7*Bqcs8(-bh$dxZVr*!F zCT3t@X=sElW@u=HZmf~9sR_DXpqQBjnqDIl149F_m^s2tKtW?;422fPm=3fwwVZq` Q$&b^}h)Y$~)!&T^01-=wMgRZ+ diff --git a/SDFTools/sdf/schedule/config.py b/SDFTools/sdf/schedule/config.py index ae47021a..1a7afc6d 100755 --- a/SDFTools/sdf/schedule/config.py +++ b/SDFTools/sdf/schedule/config.py @@ -68,6 +68,9 @@ class Configuration: # True for an horizontal graphviz layout self.horizontal = True + # Display FIFO buffers in graph instead of datatype + self.displayFIFOBuf = False + @property def debug(self): return (self.debugLimit > 0) diff --git a/SDFTools/sdf/schedule/description.py b/SDFTools/sdf/schedule/description.py index 3e14729f..c276fbaf 100755 --- a/SDFTools/sdf/schedule/description.py +++ b/SDFTools/sdf/schedule/description.py @@ -40,6 +40,9 @@ from sdf.schedule.node import * from sdf.schedule.config import * from sdf.schedule.types import * +# To debug graph coloring for memory optimization +#import matplotlib.pyplot as plt + class IncompatibleIO(Exception): pass @@ -67,16 +70,14 @@ class FIFODesc: def __init__(self,fifoid): # The FIFO is in fact just an array self.isArray=False - # Max distance between a write and a read to the FIFO - # If it is 1, data written to FIFO - # is immediately read so buffer can be reused - self.distance=1 # FIFO length self.length=0 # FIFO type self.theType=None # Buffer used by FIFO self.buffer=None + # Used for plot in graphviz + self.bufferID=-1 self._fifoID=fifoid # Source IO self.src = None @@ -84,15 +85,16 @@ class FIFODesc: self.dst = None # FIFO delay self.delay=0 - # Can use a shared buffer ? - self.isShared = False - - self._writeTime= 0 - # Track when FIFO is used - # For allocation of shared buffers we need - # to know when 2 buffers are used at same time - self._timeOfUse=[] + # Used for liveliness analysis + # To share buffers between FIFO in memory optimization + # mode, we need to know when a FIFO is in use. + # We compute the maximum extent : so the biggest interval + # and not a disconnected union of intervals + # This could be improved. We could use + # a disjoint union of intervals but they should be mapped + # to the same node in the interference graph + self._liveInterval=(-1,-1) # shared buffer number not yet allocated self.sharedNB=-1 @@ -110,36 +112,31 @@ class FIFODesc: return(self.delay>0) def dump(self): - shared=0 - if self.isShared: - shared=1 - print("array %d dist %d len %d %s id %d src %s:%s dst %s:%s shared:%d" % + + print("array %d len %d %s id %d src %s:%s dst %s:%s " % (self.isArray, - self.distance, self.length, self.theType.ctype, self.fifoID, self.src.owner.nodeID, self.src.name, self.dst.owner.nodeID, - self.dst.name, - shared)) + self.dst.name)) @property def fifoID(self): return self._fifoID def recordWrite(self,theTime): - self._timeOfUse.append(theTime) - if self._writeTime == 0: - self._writeTime = theTime + start,stop=self._liveInterval + if start==-1: + self._liveInterval=(theTime,stop) def recordRead(self,theTime): - self._timeOfUse.append(theTime) - delta = theTime - self._writeTime - self._writeTime = 0 - if delta > self.distance: - self.distance = delta + start,stop=self._liveInterval + if (theTime > stop): + self._liveInterval=(start,theTime) + def analyzeStep(vec,allFIFOs,theTime): """Analyze an evolution step to know which FIFOs are read and written to""" @@ -209,7 +206,7 @@ class Graph(): return(res) - def initializeFIFODescriptions(self,config,allFIFOs, fifoLengths): + def initializeFIFODescriptions(self,config,allFIFOs, fifoLengths,maxTime): """Initialize FIFOs datastructure""" for fifo in allFIFOs: edge = self._sortedEdges[fifo.fifoID] @@ -218,113 +215,126 @@ class Graph(): fifo.src=src fifo.dst=dst fifo.delay=self.getDelay(edge) + # When a FIFO is working as an array then its buffer may + # potentially be shared with other FIFOs workign as arrays if src.nbSamples == dst.nbSamples: if fifo.delay==0: fifo.isArray = True - if fifo.distance==1: - if fifo.delay==0: - fifo.isShared = True fifo.theType = src.theType #fifo.dump() - # When we have bufA -> Node -> bufB then - # bufA and bufB can't share the same memory. - # For the allocation of shared buffer we scan all times - # of use and for each time we look at the FIFOs which - # can be potentially shared. + bufferID=0 + allBuffers=[] - # For each time of use, record the potentially shareable fifos - # which are used - fifoForTime={} - for fifo in allFIFOs: - if fifo.isShared: - for t in fifo._timeOfUse: - if t in fifoForTime: - fifoForTime[t].append(fifo) - else: - fifoForTime[t]=[fifo] - - # If several shareable FIFOs are used at same time, they - # must be assigned to different shared buffers if possible - usedAtSameTime={} - for t in sorted(fifoForTime.keys()): - if len(fifoForTime[t])>2: - # This case is not managed in this version. - # It could occur with quadripoles for instance - for fifo in fifoForTime[t]: - fifo.isShared=False - elif len(fifoForTime[t])==2: - # 2 FIFOs are used at the same time - fifoA = fifoForTime[t][0] - fifoB = fifoForTime[t][1] - if fifoA.sharedNB >= 0 and fifoA.sharedNB == fifoB.sharedNB: - # Those FIFOs are already both assigned to a buffer - # and we can't reassign and they use the same buffer - # So we can't consistently associate shared buffers to those - # FIFOs - fifoA.isShared=False - fifoB.isShared=False - else: - # The 2 FIFOs were never associated with a shared buffer - if fifoA.sharedNB < 0 and fifoB.sharedNB < 0: - fifoA.sharedNB=0 - fifoB.sharedNB=1 - # One FIFO is associated, so we associate the other one - # to the other shared buffer - elif fifoA.sharedNB < 0: - fifoA.sharedNB = 1 - fifoB.sharedNB - else: - fifoB.sharedNB = 1 - fifoA.sharedNB - else: - fifoA = fifoForTime[t][0] - if fifoA.sharedNB < 0: - fifoA.sharedNB = 0 - + # Compute a graph describing when FIFOs are used at the same time + # The use graph coloring to allocate buffer to those FIFOs. + # Then size the buffer based on the longest FIFO using it + if config.memoryOptimization: + G = nx.Graph() + + for fifo in allFIFOs: + if fifo.isArray: + G.add_node(fifo) + + # Create the interference graph + + # Dictionary of active FIFOs at a given time. + # The time is a scheduling step + active={} + currentTime=0 + while currentTime<=maxTime: + # Remove fifo no more active. + # Thei stop time < currenTime + toDelete=[] + for k in active: + start,stop=k._liveInterval + if stop node -> dst + # At time t, node will read for src and the stop time + # will be currentTime t. + # And it will write to dst and the start time will be + # currentTime + # So, src and dst are both live at this time. + # Which means the condition on the stop time must be + # stop >= currentTime and not a strict comparison + if start<=currentTime and stop >= currentTime: + if not (fifo in active): + for k in active: + G.add_edge(k,fifo) + active[fifo]=True + + currentTime = currentTime + 1 + + # To debug and display the graph + if False: + labels={} + for n in G.nodes: + labels[n]="%s -> %s" % (n.src.owner.nodeName,n.dst.owner.nodeName) + + pos = nx.spring_layout(G, seed=3113794652) + subax1 = plt.subplot(121) + nx.draw_networkx_edges(G, pos, width=1.0, alpha=0.5) + + nx.draw_networkx_labels(G, pos, labels, font_size=10) + plt.show() + quit() + + # Graph coloring + d = nx.coloring.greedy_color(G, strategy="largest_first") + + # Allocate the colors (buffer ID) to the FIFO + # and keep track of the max color number + # Since other buffers (for real FIFOs) will have their + # numbering start after this one. + for fifo in d: + fifo.sharedNB=d[fifo] + bufferID=max(bufferID,fifo.sharedNB) - # Now we create buffers - maxSharedA=0 - maxSharedB=0 - allBuffers=[] - for fifo in allFIFOs: - lengthInBytes = fifo.theType.bytes * fifo.length - if fifo.isShared: - if fifo.sharedNB == 0: - if lengthInBytes > maxSharedA: - maxSharedA = lengthInBytes - if fifo.sharedNB == 1: - if lengthInBytes > maxSharedB: - maxSharedB = lengthInBytes - bufferID=0 - sharedA=None - sharedB=None - if maxSharedA > 0 and config.memoryOptimization: - # Create the shared buffer if memory optimization on - sharedA = FifoBuffer(bufferID,CType(UINT8),maxSharedA) - allBuffers.append(sharedA) - bufferID = bufferID + 1 - - if maxSharedB > 0 and config.memoryOptimization: - # Create the shared buffer if memory optimization on - sharedB = FifoBuffer(bufferID,CType(UINT8),maxSharedB) - allBuffers.append(sharedB) - bufferID = bufferID + 1 + + # Compute the max size for each shared buffer + maxSizes={} + for fifo in d: + lengthInBytes = fifo.theType.bytes * fifo.length + if fifo.sharedNB in maxSizes: + maxSizes[fifo.sharedNB] = max(maxSizes[fifo.sharedNB],lengthInBytes) + else: + maxSizes[fifo.sharedNB]=lengthInBytes + + # Create the buffers + for theID in maxSizes: + sharedA = FifoBuffer(theID,CType(UINT8),maxSizes[theID]) + allBuffers.append(sharedA) for fifo in allFIFOs: # Use shared buffer if memory optimization - if fifo.isShared and config.memoryOptimization: - if fifo.sharedNB == 0: - fifo.buffer=sharedA - else: - fifo.buffer=sharedB + if fifo.isArray and config.memoryOptimization: + fifo.buffer=allBuffers[fifo.sharedNB] + fifo.bufferID=fifo.sharedNB + # Create a new buffer for a real FIFO + # Use bufferID which is starting after the numbers allocated + # to shared buffers else: buf = FifoBuffer(bufferID,fifo.theType,fifo.length) allBuffers.append(buf) fifo.buffer=buf + fifo.bufferID = bufferID bufferID = bufferID + 1 + # Compute the total memory used in bytes self._totalMemory = 0 for buf in allBuffers: self._totalMemory = self._totalMemory + buf._theType.bytes * buf._length @@ -529,7 +539,7 @@ class Graph(): fifoMax=np.floor(bMax).astype(np.int32) - allBuffers=self.initializeFIFODescriptions(config,allFIFOs,fifoMax) + allBuffers=self.initializeFIFODescriptions(config,allFIFOs,fifoMax,evolutionTime) self._allFIFOs = allFIFOs self._allBuffers = allBuffers return(Schedule(self,self._sortedNodes,self._sortedEdges,schedule)) diff --git a/SDFTools/sdf/templates/dot_template.dot b/SDFTools/sdf/templates/dot_template.dot index ce22313e..abfa5a74 100755 --- a/SDFTools/sdf/templates/dot_template.dot +++ b/SDFTools/sdf/templates/dot_template.dot @@ -115,10 +115,23 @@ digraph structs {
    {{fifos[id].src.nbSamples}}
    >] +{% if config.displayFIFOBuf %} +{{delayBoxID(id)}}:i -> {{io(fifos[id].dst.owner,fifos[id].dst)}} [headlabel=< +
    {{fifos[id].dst.nbSamples}} +
    >,label="buf{{fifos[id].bufferID}}"] +{% else %} {{delayBoxID(id)}}:i -> {{io(fifos[id].dst.owner,fifos[id].dst)}} [headlabel=<
    {{fifos[id].dst.nbSamples}}
    >,label="{{fifos[id].theType.graphViztype}}({{fifos[id].length}})"] +{% endif %} +{% else %} +{% if config.displayFIFOBuf %} +{{io(fifos[id].src.owner,fifos[id].src)}} -> {{io(fifos[id].dst.owner,fifos[id].dst)}} [headlabel=< +
    {{fifos[id].dst.nbSamples}} +
    >,taillabel=< +
    {{fifos[id].src.nbSamples}} +
    >,label="buf{{fifos[id].bufferID}}"] {% else %} {{io(fifos[id].src.owner,fifos[id].src)}} -> {{io(fifos[id].dst.owner,fifos[id].dst)}} [headlabel=<
    {{fifos[id].dst.nbSamples}} @@ -126,6 +139,7 @@ digraph structs {
    {{fifos[id].src.nbSamples}}
    >,label="{{fifos[id].theType.graphViztype}}({{fifos[id].length}})"] {% endif %} +{% endif %} {% endfor %} {% for c in constObjs %}