blob: 0c525ec8cf68e2d4dd38d4a032115f54afc76349 [file] [log] [blame]
Christophe Favergeonaefd2772020-01-08 09:01:17 +01001import numpy as np
2import math
3import argparse
Christophe Favergeond5e0a042020-01-10 14:31:14 +01004import sys
5
6sys.path.append("PatternGeneration")
7
8import Tools
Christophe Favergeonaefd2772020-01-08 09:01:17 +01009
10parser = argparse.ArgumentParser(description='Generate C arrays')
11parser.add_argument('-f', nargs='?',type = str, default="../Source/CommonTables/arm_mve_tables.c", help="C File path")
12parser.add_argument('-he', nargs='?',type = str, default="../Include/arm_mve_tables.h", help="H File path")
13
14args = parser.parse_args()
15
16COLLIM = 80
17
Christophe Favergeond5e0a042020-01-10 14:31:14 +010018condition="""#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_%s_%d) || defined(ARM_TABLE_TWIDDLECOEF_%s_%d)
Christophe Favergeonaefd2772020-01-08 09:01:17 +010019"""
20
Christophe Favergeond5e0a042020-01-10 14:31:14 +010021F32 = 1
Christophe Favergeon890f7602020-04-14 09:47:39 +020022F16 = 2
23Q31 = 3
24Q15 = 4
25Q7 = 5
Christophe Favergeond5e0a042020-01-10 14:31:14 +010026
Christophe Favergeonaefd2772020-01-08 09:01:17 +010027def printCUInt32Array(f,name,arr):
28 nb = 0
29 print("uint32_t %s[%d]={" % (name,len(arr)),file=f)
30
31 for d in arr:
32 val = "%d," % d
33 nb = nb + len(val)
34 if nb > COLLIM:
35 print("",file=f)
36 nb = len(val)
37 print(val,end="",file=f)
38
39 print("};\n",file=f)
40
41def printCFloat32Array(f,name,arr):
42 nb = 0
43 print("float32_t %s[%d]={" % (name,len(arr)),file=f)
44
45 for d in arr:
46 val = "%.20ff," % d
47 nb = nb + len(val)
48 if nb > COLLIM:
49 print("",file=f)
50 nb = len(val)
51 print(val,end="",file=f)
52
53 print("};\n",file=f)
54
Christophe Favergeon890f7602020-04-14 09:47:39 +020055def printCFloat16Array(f,name,arr):
56 nb = 0
57 print("float16_t %s[%d]={" % (name,len(arr)),file=f)
58
59 for d in arr:
60 val = "(float16_t)%.20ff," % d
61 nb = nb + len(val)
62 if nb > COLLIM:
63 print("",file=f)
64 nb = len(val)
65 print(val,end="",file=f)
66
67 print("};\n",file=f)
68
Christophe Favergeond5e0a042020-01-10 14:31:14 +010069def printCQ31Array(f,name,arr):
70 nb = 0
71 print("q31_t %s[%d]={" % (name,len(arr)),file=f)
72
73 for d in arr:
74 val = "%s," % Tools.to_q31(d)
75 nb = nb + len(val)
76 if nb > COLLIM:
77 print("",file=f)
78 nb = len(val)
79 print(val,end="",file=f)
80
81 print("};\n",file=f)
82
83def printCQ15Array(f,name,arr):
84 nb = 0
85 print("q15_t %s[%d]={" % (name,len(arr)),file=f)
86
87 for d in arr:
88 val = "%s," % Tools.to_q15(d)
89 nb = nb + len(val)
90 if nb > COLLIM:
91 print("",file=f)
92 nb = len(val)
93 print(val,end="",file=f)
94
95 print("};\n",file=f)
96
97def printCQ7Array(f,name,arr):
98 nb = 0
99 print("q7_t %s[%d]={" % (name,len(arr)),file=f)
100
101 for d in arr:
102 val = "%s," % Tools.to_q7(d)
103 nb = nb + len(val)
104 if nb > COLLIM:
105 print("",file=f)
106 nb = len(val)
107 print(val,end="",file=f)
108
109 print("};\n",file=f)
110
Christophe Favergeonaefd2772020-01-08 09:01:17 +0100111def printHUInt32Array(f,name,arr):
112 print("extern uint32_t %s[%d];" % (name,len(arr)),file=f)
113
114def printHFloat32Array(f,name,arr):
115 print("extern float32_t %s[%d];" % (name,len(arr)),file=f)
116
Christophe Favergeon890f7602020-04-14 09:47:39 +0200117def printHFloat16Array(f,name,arr):
118 print("extern float16_t %s[%d];" % (name,len(arr)),file=f)
119
Christophe Favergeond5e0a042020-01-10 14:31:14 +0100120def printHQ31Array(f,name,arr):
121 print("extern q31_t %s[%d];" % (name,len(arr)),file=f)
122
123def printHQ15Array(f,name,arr):
124 print("extern q15_t %s[%d];" % (name,len(arr)),file=f)
125
126def printHQ7Array(f,name,arr):
127 print("extern q7_t %s[%d];" % (name,len(arr)),file=f)
128
Christophe Favergeonaefd2772020-01-08 09:01:17 +0100129def twiddle(n):
130 a=2.0*math.pi*np.linspace(0,n,num=n,endpoint=False)/n
131 c=np.cos(a)
132 s=np.sin(a)
133
134 r = np.empty((c.size + s.size,), dtype=c.dtype)
135 r[0::2] = c
136 r[1::2] = s
137 return(r)
138
Christophe Favergeond5e0a042020-01-10 14:31:14 +0100139def reorderTwiddle(theType,conjugate,f,h,n):
Christophe Favergeonaefd2772020-01-08 09:01:17 +0100140 numStages = 6
141 coefs= twiddle(n)
142
143
144 if n == 4096:
145 numStages = 6
146 arraySize = 1364
147
148 if n == 1024:
149 numStages = 5
150 arraySize = 340
151
152 if n == 256:
153 numStages = 4
154 arraySize = 84
155
156 if n == 64:
157 numStages = 3
158 arraySize = 20
159
160 if n == 16:
161 numStages = 2
162 arraySize = 4
163
164 incr = 1
165 nbOfElt = n
166
167 maxNb = 0
168
169 tab1 = np.zeros(2*arraySize)
170 tab2 = np.zeros(2*arraySize)
171 tab3 = np.zeros(2*arraySize)
172
173 tab1Index=0
174 tab2Index=0
175 tab3Index=0
176
177 tab1Offset = np.zeros(numStages)
178 tab2Offset = np.zeros(numStages)
179 tab3Offset = np.zeros(numStages)
180
181
182
183 for stage in range(0,numStages-1):
184 nbOfElt = nbOfElt >> 2
185 pVectCoef1 = 0
186 pVectCoef2 = 0
187 pVectCoef3 = 0
188
189 tab1Offset[stage] = tab1Index
190 tab2Offset[stage] = tab2Index
191 tab3Offset[stage] = tab3Index
192
193 for i in range(0,nbOfElt):
Christophe Favergeond5e0a042020-01-10 14:31:14 +0100194 tab1[tab1Index] = coefs[pVectCoef1]
195 if not conjugate:
196 tab1[tab1Index + 1] = coefs[pVectCoef1 + 1]
197 else:
198 tab1[tab1Index + 1] = -coefs[pVectCoef1 + 1]
Christophe Favergeonaefd2772020-01-08 09:01:17 +0100199 tab1Index = tab1Index + 2
200 pVectCoef1 = pVectCoef1 + (incr * 1 * 2)
201
Christophe Favergeond5e0a042020-01-10 14:31:14 +0100202 tab2[tab2Index] = coefs[pVectCoef2]
203 if not conjugate:
204 tab2[tab2Index + 1] = coefs[pVectCoef2 + 1]
205 else:
206 tab2[tab2Index + 1] = -coefs[pVectCoef2 + 1]
Christophe Favergeonaefd2772020-01-08 09:01:17 +0100207 tab2Index = tab2Index + 2
208 pVectCoef2 = pVectCoef2 + (incr * 2 * 2)
209
Christophe Favergeond5e0a042020-01-10 14:31:14 +0100210 tab3[tab3Index] = coefs[pVectCoef3]
211 if not conjugate:
212 tab3[tab3Index + 1] = coefs[pVectCoef3 + 1]
213 else:
214 tab3[tab3Index + 1] = -coefs[pVectCoef3 + 1]
Christophe Favergeonaefd2772020-01-08 09:01:17 +0100215 tab3Index = tab3Index + 2
216 pVectCoef3 = pVectCoef3 + (incr * 3 * 2)
217
218 maxNb = maxNb + 1
219
220 incr = 4 * incr
221
Christophe Favergeond5e0a042020-01-10 14:31:14 +0100222 # F32 SECTION FOR THIS FFT LENGTH
223 if theType == F32:
224 print(condition % ("F32",n, "F32",n << 1),file=f)
225 print(condition % ("F32",n, "F32",n << 1),file=h)
226 printCUInt32Array(f,"rearranged_twiddle_tab_stride1_arr_%d_f32" % n,list(tab1Offset))
227 printHUInt32Array(h,"rearranged_twiddle_tab_stride1_arr_%d_f32" % n,list(tab1Offset))
Christophe Favergeonaefd2772020-01-08 09:01:17 +0100228
Christophe Favergeond5e0a042020-01-10 14:31:14 +0100229 printCUInt32Array(f,"rearranged_twiddle_tab_stride2_arr_%d_f32" % n,list(tab2Offset))
230 printHUInt32Array(h,"rearranged_twiddle_tab_stride2_arr_%d_f32" % n,list(tab2Offset))
231
232 printCUInt32Array(f,"rearranged_twiddle_tab_stride3_arr_%d_f32" % n,list(tab3Offset))
233 printHUInt32Array(h,"rearranged_twiddle_tab_stride3_arr_%d_f32" % n,list(tab3Offset))
234
235 printCFloat32Array(f,"rearranged_twiddle_stride1_%d_f32" % n,list(tab1))
236 printHFloat32Array(h,"rearranged_twiddle_stride1_%d_f32" % n,list(tab1))
237
238 printCFloat32Array(f,"rearranged_twiddle_stride2_%d_f32" % n,list(tab2))
239 printHFloat32Array(h,"rearranged_twiddle_stride2_%d_f32" % n,list(tab2))
240
241 printCFloat32Array(f,"rearranged_twiddle_stride3_%d_f32" % n,list(tab3))
242 printHFloat32Array(h,"rearranged_twiddle_stride3_%d_f32" % n,list(tab3))
243 print("#endif\n",file=f)
244 print("#endif\n",file=h)
Christophe Favergeonaefd2772020-01-08 09:01:17 +0100245
Christophe Favergeon890f7602020-04-14 09:47:39 +0200246 # F16 SECTION FOR THIS FFT LENGTH
247 if theType == F16:
248 print(condition % ("F16",n, "F16",n << 1),file=f)
249 print(condition % ("F16",n, "F16",n << 1),file=h)
250 printCUInt32Array(f,"rearranged_twiddle_tab_stride1_arr_%d_f16" % n,list(tab1Offset))
251 printHUInt32Array(h,"rearranged_twiddle_tab_stride1_arr_%d_f16" % n,list(tab1Offset))
252
253 printCUInt32Array(f,"rearranged_twiddle_tab_stride2_arr_%d_f16" % n,list(tab2Offset))
254 printHUInt32Array(h,"rearranged_twiddle_tab_stride2_arr_%d_f16" % n,list(tab2Offset))
255
256 printCUInt32Array(f,"rearranged_twiddle_tab_stride3_arr_%d_f16" % n,list(tab3Offset))
257 printHUInt32Array(h,"rearranged_twiddle_tab_stride3_arr_%d_f16" % n,list(tab3Offset))
258
259 printCFloat16Array(f,"rearranged_twiddle_stride1_%d_f16" % n,list(tab1))
260 printHFloat16Array(h,"rearranged_twiddle_stride1_%d_f16" % n,list(tab1))
261
262 printCFloat16Array(f,"rearranged_twiddle_stride2_%d_f16" % n,list(tab2))
263 printHFloat16Array(h,"rearranged_twiddle_stride2_%d_f16" % n,list(tab2))
264
265 printCFloat16Array(f,"rearranged_twiddle_stride3_%d_f16" % n,list(tab3))
266 printHFloat16Array(h,"rearranged_twiddle_stride3_%d_f16" % n,list(tab3))
267 print("#endif\n",file=f)
268 print("#endif\n",file=h)
269
Christophe Favergeond5e0a042020-01-10 14:31:14 +0100270 # Q31 SECTION FOR THIS FFT LENGTH
271 if theType == Q31:
272 print(condition % ("Q31",n, "Q31",n << 1),file=f)
273 print(condition % ("Q31",n, "Q31",n << 1),file=h)
274 printCUInt32Array(f,"rearranged_twiddle_tab_stride1_arr_%d_q31" % n,list(tab1Offset))
275 printHUInt32Array(h,"rearranged_twiddle_tab_stride1_arr_%d_q31" % n,list(tab1Offset))
276
277 printCUInt32Array(f,"rearranged_twiddle_tab_stride2_arr_%d_q31" % n,list(tab2Offset))
278 printHUInt32Array(h,"rearranged_twiddle_tab_stride2_arr_%d_q31" % n,list(tab2Offset))
279
280 printCUInt32Array(f,"rearranged_twiddle_tab_stride3_arr_%d_q31" % n,list(tab3Offset))
281 printHUInt32Array(h,"rearranged_twiddle_tab_stride3_arr_%d_q31" % n,list(tab3Offset))
282
283 printCQ31Array(f,"rearranged_twiddle_stride1_%d_q31" % n,list(tab1))
284 printHQ31Array(h,"rearranged_twiddle_stride1_%d_q31" % n,list(tab1))
285
286 printCQ31Array(f,"rearranged_twiddle_stride2_%d_q31" % n,list(tab2))
287 printHQ31Array(h,"rearranged_twiddle_stride2_%d_q31" % n,list(tab2))
288
289 printCQ31Array(f,"rearranged_twiddle_stride3_%d_q31" % n,list(tab3))
290 printHQ31Array(h,"rearranged_twiddle_stride3_%d_q31" % n,list(tab3))
291 print("#endif\n",file=f)
292 print("#endif\n",file=h)
Christophe Favergeonaefd2772020-01-08 09:01:17 +0100293
Christophe Favergeond5e0a042020-01-10 14:31:14 +0100294 # Q15 SECTION FOR THIS FFT LENGTH
295 if theType == Q15:
296 print(condition % ("Q15",n, "Q15",n << 1),file=f)
297 print(condition % ("Q15",n, "Q15",n << 1),file=h)
298 printCUInt32Array(f,"rearranged_twiddle_tab_stride1_arr_%d_q15" % n,list(tab1Offset))
299 printHUInt32Array(h,"rearranged_twiddle_tab_stride1_arr_%d_q15" % n,list(tab1Offset))
300
301 printCUInt32Array(f,"rearranged_twiddle_tab_stride2_arr_%d_q15" % n,list(tab2Offset))
302 printHUInt32Array(h,"rearranged_twiddle_tab_stride2_arr_%d_q15" % n,list(tab2Offset))
303
304 printCUInt32Array(f,"rearranged_twiddle_tab_stride3_arr_%d_q15" % n,list(tab3Offset))
305 printHUInt32Array(h,"rearranged_twiddle_tab_stride3_arr_%d_q15" % n,list(tab3Offset))
306
307 printCQ15Array(f,"rearranged_twiddle_stride1_%d_q15" % n,list(tab1))
308 printHQ15Array(h,"rearranged_twiddle_stride1_%d_q15" % n,list(tab1))
309
310 printCQ15Array(f,"rearranged_twiddle_stride2_%d_q15" % n,list(tab2))
311 printHQ15Array(h,"rearranged_twiddle_stride2_%d_q15" % n,list(tab2))
312
313 printCQ15Array(f,"rearranged_twiddle_stride3_%d_q15" % n,list(tab3))
314 printHQ15Array(h,"rearranged_twiddle_stride3_%d_q15" % n,list(tab3))
315 print("#endif\n",file=f)
316 print("#endif\n",file=h)
Christophe Favergeonaefd2772020-01-08 09:01:17 +0100317
Christophe Favergeonaefd2772020-01-08 09:01:17 +0100318
319
320
321#test = twiddle(16)
322#printCFloat32Array("Test",list(test))
323
324cheader="""/* ----------------------------------------------------------------------
325 * Project: CMSIS DSP Library
326 * Title: arm_mve_tables.c
327 * Description: common tables like fft twiddle factors, Bitreverse, reciprocal etc
328 * used for MVE implementation only
329 *
Christophe Favergeon890f7602020-04-14 09:47:39 +0200330 * $Date: 14. April 2020
Christophe Favergeonaefd2772020-01-08 09:01:17 +0100331 *
332 * Target Processor: Cortex-M cores
333 * -------------------------------------------------------------------- */
334/*
335 * Copyright (C) 2010-2020 ARM Limited or its affiliates. All rights reserved.
336 *
337 * SPDX-License-Identifier: Apache-2.0
338 *
339 * Licensed under the Apache License, Version 2.0 (the License); you may
340 * not use this file except in compliance with the License.
341 * You may obtain a copy of the License at
342 *
343 * www.apache.org/licenses/LICENSE-2.0
344 *
345 * Unless required by applicable law or agreed to in writing, software
346 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
347 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
348 * See the License for the specific language governing permissions and
349 * limitations under the License.
350 */
351
Christophe Favergeonaefd2772020-01-08 09:01:17 +0100352 """
353
Christophe Favergeond5e0a042020-01-10 14:31:14 +0100354cifdeMVEF="""#include "arm_math.h"
355
356#if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
357
358#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_ALLOW_TABLES)
359"""
360
361cfooterMVEF="""
Christophe Favergeonaefd2772020-01-08 09:01:17 +0100362
363#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_ALLOW_TABLES) */
364#endif /* defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) */
365"""
366
Christophe Favergeond5e0a042020-01-10 14:31:14 +0100367cifdeMVEI="""#include "arm_math.h"
368
369#if defined(ARM_MATH_MVEI)
370
371#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_ALLOW_TABLES)
372"""
373
374cfooterMVEI="""
375
376#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_ALLOW_TABLES) */
377#endif /* defined(ARM_MATH_MVEI) */
378"""
379
Christophe Favergeonaefd2772020-01-08 09:01:17 +0100380hheader="""/* ----------------------------------------------------------------------
381 * Project: CMSIS DSP Library
382 * Title: arm_mve_tables.h
383 * Description: common tables like fft twiddle factors, Bitreverse, reciprocal etc
384 * used for MVE implementation only
385 *
Christophe Favergeon890f7602020-04-14 09:47:39 +0200386 * $Date: 14. April 2020
Christophe Favergeonaefd2772020-01-08 09:01:17 +0100387 *
388 * Target Processor: Cortex-M cores
389 * -------------------------------------------------------------------- */
390/*
391 * Copyright (C) 2010-2020 ARM Limited or its affiliates. All rights reserved.
392 *
393 * SPDX-License-Identifier: Apache-2.0
394 *
395 * Licensed under the Apache License, Version 2.0 (the License); you may
396 * not use this file except in compliance with the License.
397 * You may obtain a copy of the License at
398 *
399 * www.apache.org/licenses/LICENSE-2.0
400 *
401 * Unless required by applicable law or agreed to in writing, software
402 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
403 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
404 * See the License for the specific language governing permissions and
405 * limitations under the License.
406 */
407
408 #ifndef _ARM_MVE_TABLES_H
409 #define _ARM_MVE_TABLES_H
410
411 #include "arm_math.h"
412
Christophe Favergeond5e0a042020-01-10 14:31:14 +0100413
Christophe Favergeonaefd2772020-01-08 09:01:17 +0100414
415
416 """
417
Christophe Favergeond5e0a042020-01-10 14:31:14 +0100418hifdefMVEF="""
419#if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
420
421#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_ALLOW_TABLES)
422"""
423
424hfooterMVEF="""
Christophe Favergeonaefd2772020-01-08 09:01:17 +0100425#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_ALLOW_TABLES) */
426
427#endif /* defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) */
428
Christophe Favergeond5e0a042020-01-10 14:31:14 +0100429"""
430
431hifdefMVEI="""
432#if defined(ARM_MATH_MVEI)
433
434#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_ALLOW_TABLES)
435"""
436
437hfooterMVEI="""
438#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_ALLOW_TABLES) */
439
440#endif /* defined(ARM_MATH_MVEI) */
441
442"""
443
444hfooter="""
Christophe Favergeonaefd2772020-01-08 09:01:17 +0100445#endif /*_ARM_MVE_TABLES_H*/
446"""
447
Christophe Favergeond5e0a042020-01-10 14:31:14 +0100448
449
Christophe Favergeonaefd2772020-01-08 09:01:17 +0100450with open(args.f,'w') as f:
451 with open(args.he,'w') as h:
452 print(cheader,file=f)
453 print(hheader,file=h)
454
Christophe Favergeond5e0a042020-01-10 14:31:14 +0100455
456 print(cifdeMVEF,file=f)
457 print(hifdefMVEF,file=h)
458 reorderTwiddle(F32,False,f,h,16)
459 reorderTwiddle(F32,False,f,h,64)
460 reorderTwiddle(F32,False,f,h,256)
461 reorderTwiddle(F32,False,f,h,1024)
462 reorderTwiddle(F32,False,f,h,4096)
463 print(cfooterMVEF,file=f)
464 print(hfooterMVEF,file=h)
Christophe Favergeonaefd2772020-01-08 09:01:17 +0100465
Christophe Favergeon890f7602020-04-14 09:47:39 +0200466 print(cifdeMVEF,file=f)
467 print(hifdefMVEF,file=h)
468 reorderTwiddle(F16,False,f,h,16)
469 reorderTwiddle(F16,False,f,h,64)
470 reorderTwiddle(F16,False,f,h,256)
471 reorderTwiddle(F16,False,f,h,1024)
472 reorderTwiddle(F16,False,f,h,4096)
473 print(cfooterMVEF,file=f)
474 print(hfooterMVEF,file=h)
475
Christophe Favergeond5e0a042020-01-10 14:31:14 +0100476 print(cifdeMVEI,file=f)
477 print(hifdefMVEI,file=h)
478 reorderTwiddle(Q31,True,f,h,16)
479 reorderTwiddle(Q31,True,f,h,64)
480 reorderTwiddle(Q31,True,f,h,256)
481 reorderTwiddle(Q31,True,f,h,1024)
482 reorderTwiddle(Q31,True,f,h,4096)
483 print(cfooterMVEI,file=f)
484 print(hfooterMVEI,file=h)
485
486 print(cifdeMVEI,file=f)
487 print(hifdefMVEI,file=h)
488 reorderTwiddle(Q15,True,f,h,16)
489 reorderTwiddle(Q15,True,f,h,64)
490 reorderTwiddle(Q15,True,f,h,256)
491 reorderTwiddle(Q15,True,f,h,1024)
492 reorderTwiddle(Q15,True,f,h,4096)
493 print(cfooterMVEI,file=f)
494 print(hfooterMVEI,file=h)
495
496 print(cifdeMVEI,file=f)
497 print(hifdefMVEI,file=h)
498 reorderTwiddle(Q7,True,f,h,16)
499 reorderTwiddle(Q7,True,f,h,64)
500 reorderTwiddle(Q7,True,f,h,256)
501 reorderTwiddle(Q7,True,f,h,1024)
502 reorderTwiddle(Q7,True,f,h,4096)
503 print(cfooterMVEI,file=f)
504 print(hfooterMVEI,file=h)
505
Christophe Favergeonaefd2772020-01-08 09:01:17 +0100506 print(hfooter,file=h)