blob: 71c21c23e2b42b94f901c565a786d3ebdba17cae [file] [log] [blame]
Christophe Favergeona391d772021-02-10 10:56:33 +01001# Web UI for configuration of the CMSIS-DSP Build
2#
3# How to install
4# pip install streamlit
5#
6# How to use
7# streamlit run cmsisconfig.py
8#
9import streamlit as st
10import textwrap
11import re
12
13
14st.set_page_config(page_title="CMSIS-DSP Configuration",layout="wide" )
15
16# Options requiring a special management
17NOTSTANDARD=["allTables","allInterpolations","allFFTs","Float16"]
18
19HELIUM=False
20
21config={}
22
23config["allTables"] = True
24config["allFFTs"] = True
25config["allInterpolations"] = True
26config["MVEI"]=False
27config["MVEF"]=False
28config["NEON"]=False
29config["HELIUM"]=False
30config["Float16"]=True
31config["HOST"]=False
32
33config["COS_F32"]=False
34config["COS_Q31"]=False
35config["COS_Q15"]=False
36config["SIN_F32"]=False
37config["SIN_Q31"]=False
38config["SIN_Q15"]=False
39config["SIN_COS_F32"]=False
40config["SIN_COS_Q31"]=False
41config["LMS_NORM_Q31"]=False
42config["LMS_NORM_Q15"]=False
43config["CMPLX_MAG_Q31"]=False
44config["CMPLX_MAG_Q15"]=False
45
46config["BASICMATH"]=True
47config["COMPLEXMATH"]=True
48config["CONTROLLER"]=True
49config["FASTMATH"]=True
50config["FILTERING"]=True
51config["MATRIX"]=True
52config["STATISTICS"]=True
53config["SUPPORT"]=True
54config["TRANSFORM"]=True
55config["SVM"]=True
56config["BAYES"]=True
57config["DISTANCE"]=True
58config["INTERPOLATION"]=True
Christophe Favergeonaf1c54b2021-02-15 14:15:10 +010059config["QUATERNIONMATH"]=True
Christophe Favergeona391d772021-02-10 10:56:33 +010060
61config["LOOPUNROLL"]=True
62config["ROUNDING"]=False
63config["MATRIXCHECK"]=False
64config["AUTOVECTORIZE"] = False
65
66realname={}
67realname["COS_F32"]="ARM_COS_F32"
68realname["COS_Q31"]="ARM_COS_Q31"
69realname["COS_Q15"]="ARM_COS_Q15"
70realname["SIN_F32"]="ARM_SIN_F32"
71realname["SIN_Q31"]="ARM_SIN_Q31"
72realname["SIN_Q15"]="ARM_SIN_Q15"
73realname["SIN_COS_F32"]="ARM_SIN_COS_F32"
74realname["SIN_COS_Q31"]="ARM_SIN_COS_Q31"
75realname["LMS_NORM_Q31"]="ARM_LMS_NORM_Q31"
76realname["LMS_NORM_Q15"]="ARM_LMS_NORM_Q15"
77realname["CMPLX_MAG_Q31"]="ARM_CMPLX_MAG_Q31"
78realname["CMPLX_MAG_Q15"]="ARM_CMPLX_MAG_Q15"
79
80defaulton={}
81defaulton["LOOPUNROLL"]=True
82defaulton["BASICMATH"]=True
83defaulton["COMPLEXMATH"]=True
84defaulton["CONTROLLER"]=True
85defaulton["FASTMATH"]=True
86defaulton["FILTERING"]=True
87defaulton["MATRIX"]=True
88defaulton["STATISTICS"]=True
89defaulton["SUPPORT"]=True
90defaulton["TRANSFORM"]=True
91defaulton["SVM"]=True
92defaulton["BAYES"]=True
93defaulton["DISTANCE"]=True
94defaulton["INTERPOLATION"]=True
Christophe Favergeonaf1c54b2021-02-15 14:15:10 +010095defaulton["QUATERNIONMATH"]=True
96
Christophe Favergeona391d772021-02-10 10:56:33 +010097
98CFFTSIZE=[16,32,64,128,256,512,1024,2048,4096]
99CFFTDATATYPE=['F64','F32','F16','Q31','Q15']
100
101RFFTFASTSIZE=[32,64,128,256,512,1024,2048,4096]
102RFFTFASTDATATYPE=['F64','F32','F16']
103
104RFFTSIZE=[32,64,128,256,512,1024,2048,4096,8192]
105RFFTDATATYPE=['F32','Q31','Q15']
106
107DCTSIZE=[128,512,2048,8192]
108DCTDATATYPE=['F32','Q31','Q15']
109
110def joinit(iterable, delimiter):
111 # Intersperse a delimiter between element of a list
112 it = iter(iterable)
113 yield next(it)
114 for x in it:
115 yield delimiter
116 yield x
117
118def options(l):
119 return("".join(joinit(l," ")))
120
121def computeCmakeOptions(config):
122 global defaulton
123 cmake={}
124 if not config["allTables"]:
125 cmake["CONFIGTABLE"]=True
126 if config["allInterpolations"]:
127 cmake["ALLFAST"]=True
128 if config["allFFTs"]:
129 cmake["ALLFFT"]=True
130 if config["Float16"]:
131 cmake["FLOAT16"]=True
132 else:
133 cmake["DISABLEFLOAT16"]=True
134
135 for c in config:
136 if not (c in NOTSTANDARD):
137 if c in defaulton:
138 if not config[c]:
139 if c in realname:
140 cmake[realname[c]]=False
141 else:
142 cmake[c]=False
143 else:
144 if config[c]:
145 if c in realname:
146 cmake[realname[c]]=True
147 else:
148 cmake[c]=True
149 return cmake
150
151def removeDuplicates(l):
152 return list(dict.fromkeys(l))
153
154def genCMakeOptions(config):
155 r=[]
156 cmake = computeCmakeOptions(config)
157 for c in cmake:
158 if cmake[c]:
159 r.append("-D%s=ON" % c)
160 else:
161 r.append("-D%s=OFF" % c)
162 return(removeDuplicates(r),cmake)
163
164def test(cmake,s):
165 global defaulton
166 if s in defaulton and not (s in cmake):
167 return True
168 return(s in cmake and cmake[s])
169
170def cfftCF32Config(cmake,size):
171 result=[]
172 if test(cmake,"CFFT_F32_%d" % size):
173 a="-DARM_TABLE_TWIDDLECOEF_F32_%d" % size
174 if HELIUM:
175 b = "-DARM_TABLE_BITREVIDX_FXT_%d" % size
176 else:
177 b = "-DARM_TABLE_BITREVIDX_FLT_%d" % size
178 result=[a,b]
179 return(result)
180
181def cfftCF16Config(cmake,size):
182 result=[]
183 if test(cmake,"CFFT_F16_%d" % size):
184 result =["-DARM_TABLE_TWIDDLECOEF_F16_%d" % size]
185 result.append("-DARM_TABLE_BITREVIDX_FXT_%d" % size)
186 result.append("-DARM_TABLE_BITREVIDX_FLT_%d" % size)
187 return(result)
188
189def cfftCF64Config(cmake,size):
190 result=[]
191 if test(cmake,"CFFT_F64_%d" % size):
192 result =["-DARM_TABLE_TWIDDLECOEF_F64_%d" % size]
193 result.append("-DARM_TABLE_BITREVIDX_FLT64_%d" % size)
194 return(result)
195
196
197def cfftCFixedConfig(cmake,dt,size):
198 result=[]
199 if test(cmake,"CFFT_%s_%d" % (dt,size)):
200 a="-DARM_TABLE_TWIDDLECOEF_%s_%d" % (dt,size)
201 b = "-DARM_TABLE_BITREVIDX_FXT_%d" % size
202 result=[a,b]
203 return(result)
204
205def crfftFastCF64Config(cmake,size):
206 result=[]
207 s1 = size >> 1
208 if test(cmake,"RFFT_FAST_F64_%d" % size):
209 result =[]
210 result.append("-DARM_TABLE_TWIDDLECOEF_F64_%d" % s1)
211 result.append("-DARM_TABLE_BITREVIDX_FLT64_%d" % s1)
212 result.append("-DARM_TABLE_TWIDDLECOEF_RFFT_F64_%d" % size)
213 result.append("-DARM_TABLE_TWIDDLECOEF_F64_%d" % s1)
214
215 return(result)
216
217def crfftFastCF32Config(cmake,size):
218 result=[]
219 s1 = size >> 1
220 if test(cmake,"RFFT_FAST_F32_%d" % size):
221 result =[]
222 result.append("-DARM_TABLE_TWIDDLECOEF_F32_%d" % s1)
223 result.append("-DARM_TABLE_BITREVIDX_FLT_%d" % s1)
224 result.append("-DARM_TABLE_TWIDDLECOEF_RFFT_F32_%d" % size)
225
226 return(result)
227
228def crfftFastCF16Config(cmake,size):
229 result=[]
230 s1 = size >> 1
231 if test(cmake,"RFFT_FAST_F16_%d" % size):
232 result =[]
233 result.append("-DARM_TABLE_TWIDDLECOEF_F16_%d" % s1)
234 result.append("-DARM_TABLE_BITREVIDX_FLT_%d" % s1)
235 result.append("-DARM_TABLE_BITREVIDX_FXT_%d" % s1)
236 result.append("-DARM_TABLE_TWIDDLECOEF_RFFT_F16_%d" % size)
237
238 return(result)
239
240# Deprecated RFFT used in DCT
241def crfftF32Config(cmake,size):
242 result=[]
243 s1 = size >> 1
244 if test(cmake,"RFFT_FAST_F16_%d" % size):
245 result =[]
246 result.append("-DARM_TABLE_REALCOEF_F32")
247 result.append("-ARM_TABLE_BITREV_%d" % s1)
248 result.append("-ARM_TABLE_TWIDDLECOEF_F32_%d" % s1)
249
250 return(result)
251
252
253def crfftFixedConfig(cmake,dt,size):
254 result=[]
255 s1 = size >> 1
256 if test(cmake,"RFFT_%s_%d" % (dt,size)):
257 result =[]
258 result.append("-DARM_TABLE_REALCOEF_%s" % dt)
259 result.append("-DARM_TABLE_TWIDDLECOEF_%s_%d" % (dt,s1))
260 result.append("-DARM_TABLE_BITREVIDX_FXT_%d" % s1)
261
262 return(result)
263
264
265def dctConfig(cmake,dt,size):
266 result=[]
267 if test(cmake,"DCT4_%s_%d" % (dt,size)):
268 result =[]
269 result.append("-DARM_TABLE_DCT4_%s_%d" % (dt,size))
270 result.append("-DARM_TABLE_REALCOEF_F32")
271 result.append("-DARM_TABLE_BITREV_1024" )
272 result.append("-DARM_TABLE_TWIDDLECOEF_%s_4096" % dt)
273
274 return(result)
275
276# Convert cmake options to make flags
277def interpretCmakeOptions(cmake):
278 r=[]
279 if test(cmake,"CONFIGTABLE"):
280 r.append("-DARM_DSP_CONFIG_TABLES")
281 # In Make configuration we build all modules.
282 # So the code for FFT and FAST maths may be included
283 # so we allow the table to be included if they are needed.
284 r.append("-DARM_FAST_ALLOW_TABLES")
285 r.append("-DARM_FFT_ALLOW_TABLES")
286 for size in CFFTSIZE:
287 r += cfftCF32Config(cmake,size)
288 r += cfftCF16Config(cmake,size)
289 r += cfftCF64Config(cmake,size)
290 r += cfftCFixedConfig(cmake,"Q31",size)
291 r += cfftCFixedConfig(cmake,"Q15",size)
292
293 for size in RFFTFASTSIZE:
294 r += crfftFastCF64Config(cmake,size)
295 r += crfftFastCF32Config(cmake,size)
296 r += crfftFastCF16Config(cmake,size)
297
298 for size in RFFTSIZE:
299 r += crfftFixedConfig(cmake,"F32",size)
300 r += crfftFixedConfig(cmake,"Q31",size)
301 r += crfftFixedConfig(cmake,"Q15",size)
302
303 for size in DCTSIZE:
304 r += dctConfig(cmake,"F32",size)
305 r += dctConfig(cmake,"Q31",size)
306 r += dctConfig(cmake,"Q15",size)
307
308
309
310 if test(cmake,"ALLFAST"):
311 r.append("-DARM_ALL_FAST_TABLES")
312 if test(cmake,"ALLFFT"):
313 r.append("-DARM_ALL_FFT_TABLES")
314
315 if test(cmake,"LOOPUNROLL"):
316 r.append("-DARM_MATH_LOOPUNROLL")
317 if test(cmake,"ROUNDING"):
318 r.append("-DARM_MATH_ROUNDING")
319 if test(cmake,"MATRIXCHECK"):
320 r.append("-DARM_MATH_MATRIX_CHECK")
321 if test(cmake,"AUTOVECTORIZE"):
322 r.append("-DARM_MATH_AUTOVECTORIZE")
323 if test(cmake,"DISABLEFLOAT16"):
324 r.append("-DDISABLEFLOAT16")
325 if test(cmake,"NEON"):
326 r.append("-DARM_MATH_NEON")
327 r.append("-DARM_MATH_NEON_EXPERIMENTAL")
328 if test(cmake,"HOST"):
329 r.append("-D__GNUC_PYTHON__")
330
331 if test(cmake,"ARM_COS_F32"):
332 r.append("-DARM_TABLE_SIN_F32")
333 if test(cmake,"ARM_COS_Q31"):
334 r.append("-DARM_TABLE_SIN_Q31")
335 if test(cmake,"ARM_COS_Q15"):
336 r.append("-DARM_TABLE_SIN_Q15")
337
338 if test(cmake,"ARM_SIN_F32"):
339 r.append("-DARM_TABLE_SIN_F32")
340 if test(cmake,"ARM_SIN_Q31"):
341 r.append("-DARM_TABLE_SIN_Q31")
342 if test(cmake,"ARM_SIN_Q15"):
343 r.append("-DARM_TABLE_SIN_Q15")
344
345 if test(cmake,"ARM_SIN_COS_F32"):
346 r.append("-DARM_TABLE_SIN_F32")
347 if test(cmake,"ARM_SIN_COS_Q31"):
348 r.append("-DARM_TABLE_SIN_Q31")
349
350 if test(cmake,"ARM_LMS_NORM_Q31"):
351 r.append("-DARM_TABLE_RECIP_Q31")
352
353 if test(cmake,"ARM_LMS_NORM_Q15"):
354 r.append("-DARM_TABLE_RECIP_Q15")
355
356 if test(cmake,"ARM_CMPLX_MAG_Q31"):
357 r.append("-DARM_TABLE_FAST_SQRT_Q31_MVE")
358
359 if test(cmake,"ARM_CMPLX_MAG_Q15"):
360 r.append("-DARM_TABLE_FAST_SQRT_Q15_MVE")
361
362 if test(cmake,"MVEI"):
363 r.append("-DARM_MATH_MVEI")
364
365 if test(cmake,"MVEF"):
366 r.append("-DARM_MATH_MVEF")
367
368 if test(cmake,"HELIUM") or test(cmake,"MVEF") or test(cmake,"MVEI"):
369 r.append("-IPrivateInclude")
370
371 if test(cmake,"NEON") or test(cmake,"NEONEXPERIMENTAL"):
372 r.append("-IComputeLibrary/Include")
373
374 return (removeDuplicates(r))
375
376def genMakeOptions(config):
377 cmake = computeCmakeOptions(config)
378 r=interpretCmakeOptions(cmake)
379 return(r,cmake)
380
381
382def check(config,s,name=None,comment=None):
383 if comment is not None:
384 st.sidebar.text(comment)
385 if name is None:
386 config[s]=st.sidebar.checkbox(s,value=config[s])
387 else:
388 config[s]=st.sidebar.checkbox(name,value=config[s])
389 return(config[s])
390
391def genconfig(config,transform,sizes,datatypes):
392 global realname
393 for size in sizes:
394 for dt in datatypes:
395 s="%s_%s_%s" % (transform,dt,size)
396 config[s] = False
397 realname[s] = s
398
399def hasDCTF32(config):
400 result=False
401 for size in DCTSIZE:
402 s="DCT4_F32_%s" % size
403 if config[s]:
404 result = True
405 return(result)
406
407def multiselect(config,name,options):
408 default=[]
409 for r in options:
410 if config[r]:
411 default.append(r)
412 result=st.sidebar.multiselect(name,options,default=default)
413 for r in options:
414 config[r] = False
415 for r in result:
416 config[r] = True
417
418def genui(config,transform,sizes,datatypes):
419 keepF32 = True
420 # RFFT F32 is deprecated and needed only for DCT4
421 if transform == "RFFT":
422 keepF32 = hasDCTF32(config)
423 selected=st.sidebar.multiselect("Sizes",sizes)
424 for size in selected:
425 options=[]
426 for dt in datatypes:
427 if dt != "F32" or keepF32:
428 s="%s_%s_%s" % (transform,dt,size)
429 options.append(s)
430 multiselect(config,"Nb = %d" % size,options)
431
432
433def configMake(config):
434 st.sidebar.header('Table Configuration')
435 st.sidebar.info("Several options to include only the tables needed in an app and minimize code size.")
436 if not check(config,"allTables","All tables included"):
437
438 if not check(config,"allFFTs","All FFT tables included"):
439 st.sidebar.markdown("#### CFFT")
440 genui(config,"CFFT",CFFTSIZE,CFFTDATATYPE)
441
442 st.sidebar.info("Following transforms are using the CFFT. You need to enable the needed CFFTs above.")
443
444 st.sidebar.markdown("#### RFFT FAST")
445 genui(config,"RFFT_FAST",RFFTFASTSIZE,RFFTFASTDATATYPE)
446 st.sidebar.markdown("#### DCT4")
447 genui(config,"DCT4",DCTSIZE,DCTDATATYPE)
448 st.sidebar.markdown("#### RFFT")
449 genui(config,"RFFT",RFFTSIZE,RFFTDATATYPE)
450
451
452
453
454 if not check(config,"allInterpolations",'All interpolation tables included'):
455 selected=st.sidebar.multiselect("Functions",["Cosine","Sine","SineCosine","Normalized LMS"])
456 for s in selected:
457 if s == "Cosine":
458 multiselect(config,"Cosine",["COS_F32","COS_Q31","COS_Q15"])
459 if s == "Sine":
460 multiselect(config,"Sine",["SIN_F32","SIN_Q31","SIN_Q15"])
461 if s == "SineCosine":
462 multiselect(config,"SineCosine",["SIN_COS_F32","SIN_COS_Q31"])
463 if s == "Normalized LMS":
464 multiselect(config,"Normalized LMS",["LMS_NORM_Q31","LMS_NORM_Q15"])
465
466 if config["MVEI"]:
467 st.sidebar.markdown("#### Complex Magnitude")
468 multiselect(config,"Complex Magnitude",["CMPLX_MAG_Q31","CMPLX_MAG_Q15"])
469
470
471
472def configCMake(config):
473 multiselect(config,"Folders",["BASICMATH",
474 "COMPLEXMATH",
475 "CONTROLLER",
476 "FASTMATH",
477 "FILTERING",
478 "MATRIX",
479 "STATISTICS",
480 "SUPPORT",
481 "TRANSFORM",
482 "SVM",
483 "BAYES",
484 "DISTANCE",
Christophe Favergeonaf1c54b2021-02-15 14:15:10 +0100485 "INTERPOLATION","QUATERNIONMATH"])
Christophe Favergeona391d772021-02-10 10:56:33 +0100486 configMake(config)
487
488genconfig(config,"CFFT",CFFTSIZE,CFFTDATATYPE)
489genconfig(config,"RFFT_FAST",RFFTFASTSIZE,RFFTFASTDATATYPE)
490genconfig(config,"RFFT",RFFTSIZE,RFFTDATATYPE)
491genconfig(config,"DCT4",DCTSIZE,DCTDATATYPE)
492
493st.title('CMSIS-DSP Configuration')
494
495st.warning("It is a work in progress. Only a small subset of the combinations has been tested.")
496
497st.sidebar.header('Feature Configuration')
498st.sidebar.info("To build on host. All features will be enabled.")
499forHost=check(config,"HOST")
500
501if not forHost:
502 st.sidebar.info("Enable or disable float16 support")
503 check(config,"Float16")
504
505 st.sidebar.info("Some configurations for the CMSIS-DSP code.")
506 check(config,"LOOPUNROLL")
507 st.sidebar.text("Decrease performances when selected:")
508 check(config,"ROUNDING")
509 check(config,"MATRIXCHECK")
510
511 st.sidebar.info("Enable vector code. It is not automatic for Neon. Use of Helium will enable new options to select some interpolation tables.")
512 archi=st.sidebar.selectbox("Vector",('None','Helium','Neon'))
513 if archi == 'Neon':
514 config["NEON"]=True
515 if archi == 'Helium':
516 multiselect(config,"MVE configuration",["MVEI","MVEF"])
517 HELIUM=True
518 if archi != 'None':
519 st.sidebar.info("When autovectorization is on, pure C code will be compiled. The version with C intrinsics won't be compiled.")
520 check(config,"AUTOVECTORIZE")
521
522
523
524st.sidebar.header('Build Method')
525
526st.sidebar.info("With cmake, some folders can be removed from the build.")
527selected=st.sidebar.selectbox('Select', ("Make","Cmake"),index=1)
528
529
530
531if selected == "Make":
532 if not forHost:
533 configMake(config)
534 result,cmake=genMakeOptions(config)
535else:
536 if not forHost:
537 configCMake(config)
538 result,cmake=genCMakeOptions(config)
539
540st.header('Build options for %s command line' % selected)
541
542if selected == "Make":
543 if test(cmake,"FLOAT16"):
544 st.info("Float16 is selected. You may need to pass compiler specific options for the compiler to recognize the float16 type.")
545
546mode=st.selectbox("Mode",["txt","MDK","sh","bat"])
547
548if mode=="txt":
549 st.code(textwrap.fill(options(result)))
550
551if mode=="MDK":
552 opts=options(result)
553 includes=""
554 maybeincludes=re.findall(r'\-I([^\s]+)',opts)
555 # Managed in MDK pack file
556 #if maybeincludes:
557 # includes = maybeincludes
558 # st.text("Following include directories must be added")
559 # st.code(includes)
560 opts=re.sub(r'\-D','',opts)
561 opts=re.sub(r'\-I[^\s]+','',opts)
562 st.text("MDK Preprocessor Symbols ")
563 st.code(opts)
564
565
566if mode=="sh":
567 lines=options(result).split()
568 txt=""
569 for l in lines:
570 txt += " %s \\\n" % l
571 txt += "\n"
572 st.code(txt)
573
574if mode=="bat":
575 lines=options(result).split()
576 txt=""
577 for l in lines:
578 txt += " %s ^\n" % l
579 txt += "\n"
580 st.code(txt)
581