3 # Program for generating DCT butterfly diagrams from yield REMAP schedules
4 # avoids the need to mess about drawing diagrams by hand, getting them wrong,
5 # introducing mistakes (common in academic published papers, sigh)
7 from copy
import deepcopy
8 from collections
import OrderedDict
14 from openpower
.decoder
.isa
.remap_dct_yield
import (reverse_bits
, halfrev2
,
15 iterate_dct_inner_butterfly_indices
,
16 iterate_dct_outer_butterfly_indices
,
19 cwd
= os
.path
.split(os
.path
.abspath(__file__
))[0]
21 def linescale(l1
, l2
, scale
):
24 return l1
[0] - diffx
*scale
, l1
[1] + diffy
*scale
26 def lineoffs(l2
, scale
):
27 return l2
[0] - abs(scale
), l2
[1] + scale
30 def create_idct(fname
, n
, redir
=True):
31 """unsophisticated drawer of an SVG
37 print ("WARNING, no SVG image, not producing image %s" % fname
)
43 print ("transform2", n
)
44 levels
= n
.bit_length() - 1
49 # reference (read/write) the in-place data in *reverse-bit-order*
51 ri
= [ri
[reverse_bits(i
, levels
)] for i
in range(n
)]
53 # pretend we LDed data in half-swapped *and* bit-reversed order as well
54 # TODO: merge these two
55 vec
= [vec
[ri
[i
]] for i
in range(n
)]
56 vec
= halfrev2(vec
, True)
62 dwg
= svgwrite
.Drawing(fname
, profile
='full',
66 dwg
.add(dwg
.rect((0, 0), (width
, height
),
68 stroke
=svgwrite
.rgb(0, 128, 0, '%'),
69 stroke_width
=scale
/5.0))
74 ystep
= height
/(n
+1.0)
80 startline
= (x
-scale
, y
+i
*ystep
+scale
/2)
81 dwg
.add(dwg
.text("%d" % vec
[i
],
95 SVSHAPE0
.lims
= [xdim
, 0b0000010, 0]
96 SVSHAPE0
.submode2
= 0b11
99 SVSHAPE0
.offset
= 0 # experiment with different offset, here
100 SVSHAPE0
.invxyz
= [1,0,1] # inversion if desired
101 # j+halfstep schedule
103 SVSHAPE1
.lims
= [xdim
, 0b0000010, 0]
105 SVSHAPE1
.submode2
= 0b11
107 SVSHAPE1
.offset
= 0 # experiment with different offset, here
108 SVSHAPE1
.invxyz
= [1,0,1] # inversion if desired
110 # enumerate over the iterator function, getting new indices
111 i0
= iterate_dct_outer_butterfly_indices(SVSHAPE0
)
112 i1
= iterate_dct_outer_butterfly_indices(SVSHAPE1
)
113 for k
, ((jl
, jle
), (jh
, jhe
)) in enumerate(zip(i0
, i1
)):
114 print ("itersum jr", jl
, jh
,
115 "end", bin(jle
), bin(jhe
))
120 startline
= (x
, y
+jh
*ystep
)
121 endline
= (x
+xstep
, y
+jl
*ystep
)
122 dwg
.add(dwg
.line(startline
,
124 stroke
=svgwrite
.rgb(255, 16, 16, '%'),
125 stroke_width
=scale
/10.0))
127 dwg
.add(dwg
.text("+",
128 lineoffs(endline
, scale
*0.9),
133 startline
= (x
, y
+i
*ystep
)
134 endline
= (x
+xstep
, y
+i
*ystep
)
135 dwg
.add(dwg
.line(startline
,
137 stroke
=svgwrite
.rgb(16, 255, 16, '%'),
138 stroke_width
=scale
/15.0))
140 if jle
== 0b111: # all loops end
146 startline
= (x
, y
+i
*ystep
)
147 endline
= (x
+xstep
, y
+i
*ystep
)
148 dwg
.add(dwg
.line(startline
,
150 stroke
=svgwrite
.rgb(16, 255, 16, '%'),
151 stroke_width
=scale
/15.0))
160 SVSHAPE0
.lims
= [xdim
, 0b000001, 0]
162 SVSHAPE0
.submode2
= 0b11
164 SVSHAPE0
.offset
= 0 # experiment with different offset, here
165 SVSHAPE0
.invxyz
= [0,0,0] # inversion if desired
166 # j+halfstep schedule
168 SVSHAPE1
.lims
= [xdim
, 0b000001, 0]
170 SVSHAPE1
.submode2
= 0b11
172 SVSHAPE1
.offset
= 0 # experiment with different offset, here
173 SVSHAPE1
.invxyz
= [0,0,0] # inversion if desired
176 SVSHAPE2
.lims
= [xdim
, 0b000001, 0]
178 SVSHAPE2
.submode2
= 0b11
180 SVSHAPE2
.offset
= 0 # experiment with different offset, here
181 SVSHAPE2
.invxyz
= [0,0,0] # inversion if desired
184 SVSHAPE3
.lims
= [xdim
, 0b000001, 0]
186 SVSHAPE3
.submode2
= 0b11
188 SVSHAPE3
.offset
= 0 # experiment with different offset, here
189 SVSHAPE3
.invxyz
= [0,0,0] # inversion if desired
191 # enumerate over the iterator function, getting new indices
192 i0
= iterate_dct_inner_butterfly_indices(SVSHAPE0
)
193 i1
= iterate_dct_inner_butterfly_indices(SVSHAPE1
)
194 i2
= iterate_dct_inner_butterfly_indices(SVSHAPE2
)
195 i3
= iterate_dct_inner_butterfly_indices(SVSHAPE3
)
196 for k
, ((jl
, jle
), (jh
, jhe
), (ci
, cie
), (size
, sze
)) in \
197 enumerate(zip(i0
, i1
, i2
, i3
)):
201 print ("xform2", jl
, jh
, ci
, size
)
203 startline
= (x
, y
+jl
*ystep
)
204 endline
= (x
+xstep
, y
+jh
*ystep
)
205 dwg
.add(dwg
.line(startline
,
207 stroke
=svgwrite
.rgb(255, 16, 16, '%'),
208 stroke_width
=scale
/10.0))
210 dwg
.add(dwg
.text("+",
211 lineoffs(endline
, scale
*0.9),
214 startline
= (x
, y
+jh
*ystep
)
215 endline
= (x
+xstep
, y
+jl
*ystep
)
216 dwg
.add(dwg
.line(startline
,
218 stroke
=svgwrite
.rgb(255, 16, 16, '%'),
219 stroke_width
=scale
/10.0))
221 dwg
.add(dwg
.text("x",
222 lineoffs(endline
, scale
*0.9),
228 startline
= (x
, y
+i
*ystep
)
229 endline
= (x
+xstep
, y
+i
*ystep
)
230 dwg
.add(dwg
.line(startline
,
232 stroke
=svgwrite
.rgb(16, 255, 16, '%'),
233 stroke_width
=scale
/15.0))
235 if jle
== 0b111: # all loops end
238 print("transform2 result", vec
)
243 def create_dct(fname
, n
, redir
=True):
244 """unsophisticated drawer of an SVG
250 print ("WARNING, no SVG image, not producing image %s" % fname
)
256 print ("transform2", n
)
257 levels
= n
.bit_length() - 1
262 # reference (read/write) the in-place data in *reverse-bit-order*
264 ri
= [ri
[reverse_bits(i
, levels
)] for i
in range(n
)]
266 # and pretend we LDed data in half-swapped *and* bit-reversed order as well
267 # TODO: merge these two
268 vec
= halfrev2(vec
, False)
269 vec
= [vec
[ri
[i
]] for i
in range(n
)]
275 dwg
= svgwrite
.Drawing(fname
, profile
='full',
276 size
=(width
, height
))
279 dwg
.add(dwg
.rect((0, 0), (width
, height
),
281 stroke
=svgwrite
.rgb(0, 128, 0, '%'),
282 stroke_width
=scale
/5.0))
294 SVSHAPE0
.lims
= [xdim
, 0b000001, 0]
296 SVSHAPE0
.submode2
= 0b01
298 SVSHAPE0
.offset
= 0 # experiment with different offset, here
299 SVSHAPE0
.invxyz
= [1,0,0] # inversion if desired
300 # j+halfstep schedule
302 SVSHAPE1
.lims
= [xdim
, 0b000001, 0]
304 SVSHAPE1
.submode2
= 0b01
306 SVSHAPE1
.offset
= 0 # experiment with different offset, here
307 SVSHAPE1
.invxyz
= [1,0,0] # inversion if desired
310 SVSHAPE2
.lims
= [xdim
, 0b000001, 0]
312 SVSHAPE2
.submode2
= 0b01
314 SVSHAPE2
.offset
= 0 # experiment with different offset, here
315 SVSHAPE2
.invxyz
= [1,0,0] # inversion if desired
318 SVSHAPE3
.lims
= [xdim
, 0b000001, 0]
320 SVSHAPE3
.submode2
= 0b01
322 SVSHAPE3
.offset
= 0 # experiment with different offset, here
323 SVSHAPE3
.invxyz
= [1,0,0] # inversion if desired
328 ystep
= height
/(n
+1.0)
334 startline
= (x
-scale
, y
+i
*ystep
+scale
/2)
335 dwg
.add(dwg
.text("%d" % vec
[i
],
339 # enumerate over the iterator function, getting new indices
340 i0
= iterate_dct_inner_butterfly_indices(SVSHAPE0
)
341 i1
= iterate_dct_inner_butterfly_indices(SVSHAPE1
)
342 i2
= iterate_dct_inner_butterfly_indices(SVSHAPE2
)
343 i3
= iterate_dct_inner_butterfly_indices(SVSHAPE3
)
344 for k
, ((jl
, jle
), (jh
, jhe
), (ci
, cie
), (size
, sze
)) in \
345 enumerate(zip(i0
, i1
, i2
, i3
)):
349 print ("xform2", jl
, jh
, ci
, size
)
350 coeff
= (math
.cos((ci
+ 0.5) * math
.pi
/ size
) * 2.0)
352 startline
= (x
, y
+jl
*ystep
)
353 endline
= (x
+xstep
, y
+jh
*ystep
)
354 dwg
.add(dwg
.line(startline
,
356 stroke
=svgwrite
.rgb(255, 16, 16, '%'),
357 stroke_width
=scale
/10.0))
359 dwg
.add(dwg
.text("+",
360 lineoffs(endline
, scale
*0.9),
363 startline
= (x
, y
+jh
*ystep
)
364 endline
= (x
+xstep
, y
+jl
*ystep
)
365 dwg
.add(dwg
.line(startline
,
367 stroke
=svgwrite
.rgb(255, 16, 16, '%'),
368 stroke_width
=scale
/10.0))
370 dwg
.add(dwg
.text("x",
371 lineoffs(endline
, scale
*0.9),
377 startline
= (x
, y
+i
*ystep
)
378 endline
= (x
+xstep
, y
+i
*ystep
)
379 dwg
.add(dwg
.line(startline
,
381 stroke
=svgwrite
.rgb(16, 255, 16, '%'),
382 stroke_width
=scale
/15.0))
384 if jle
== 0b111: # all loops end
390 startline
= (x
, y
+i
*ystep
)
391 endline
= (x
+xstep
, y
+i
*ystep
)
392 dwg
.add(dwg
.line(startline
,
394 stroke
=svgwrite
.rgb(16, 255, 16, '%'),
395 stroke_width
=scale
/15.0))
404 SVSHAPE0
.lims
= [xdim
, 0b0000010, 0]
405 SVSHAPE0
.submode2
= 0b100
408 SVSHAPE0
.offset
= 0 # experiment with different offset, here
409 SVSHAPE0
.invxyz
= [0,0,0] # inversion if desired
410 # j+halfstep schedule
412 SVSHAPE1
.lims
= [xdim
, 0b0000010, 0]
414 SVSHAPE1
.submode2
= 0b100
416 SVSHAPE1
.offset
= 0 # experiment with different offset, here
417 SVSHAPE1
.invxyz
= [0,0,0] # inversion if desired
419 # enumerate over the iterator function, getting new indices
420 i0
= iterate_dct_outer_butterfly_indices(SVSHAPE0
)
421 i1
= iterate_dct_outer_butterfly_indices(SVSHAPE1
)
422 for k
, ((jl
, jle
), (jh
, jhe
)) in enumerate(zip(i0
, i1
)):
426 print ("itersum jr", jl
, jh
,
427 "end", bin(jle
), bin(jhe
))
429 startline
= (x
, y
+jh
*ystep
)
430 endline
= (x
+xstep
, y
+jl
*ystep
)
431 dwg
.add(dwg
.line(startline
,
433 stroke
=svgwrite
.rgb(255, 16, 16, '%'),
434 stroke_width
=scale
/10.0))
436 dwg
.add(dwg
.text("+",
437 lineoffs(endline
, scale
*0.9),
442 startline
= (x
, y
+i
*ystep
)
443 endline
= (x
+xstep
, y
+i
*ystep
)
444 dwg
.add(dwg
.line(startline
,
446 stroke
=svgwrite
.rgb(16, 255, 16, '%'),
447 stroke_width
=scale
/15.0))
449 if jle
== 0b111: # all loops end
452 print("transform2 result", vec
)
457 if __name__
== '__main__':
458 create_dct("dct_butterfly_8.svg", 8)
459 create_idct("idct_butterfly_8.svg", 8)
460 create_dct("dct_butterfly_16.svg", 16)
461 create_idct("idct_butterfly_16.svg", 16)