runall.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. import argparse
  2. import pickle
  3. import sys
  4. import subprocess
  5. import os
  6. import colorama
  7. from colorama import init,Fore, Back, Style
  8. parser = argparse.ArgumentParser(description='Parse test description')
  9. parser.add_argument('-avh', nargs='?',type = str, default="C:/Keil_v5/ARM/VHT", help="AVH folder")
  10. parser.add_argument('-d', action='store_true', help="Debug log")
  11. parser.add_argument('-n', action='store_true', help="No force rebuild")
  12. parser.add_argument('-r', action='store_true', help="Raw results only")
  13. parser.add_argument('-c', action='store_true', help="Display cycles (so passing test are displayed)")
  14. args = parser.parse_args()
  15. DEBUG=False
  16. if args.d:
  17. DEBUG=True
  18. init()
  19. sys.path.append("..")
  20. from TestScripts.Parser import TreeElem
  21. ERROR_OCCURED = False
  22. def printTitle(s):
  23. print("\n" + Fore.GREEN + Style.BRIGHT + s + Style.RESET_ALL)
  24. def printSubTitle(s):
  25. print("\n" + Fore.YELLOW + Style.BRIGHT + s + Style.RESET_ALL)
  26. def printError(s):
  27. print("\n" + Fore.RED + Style.BRIGHT + s + Style.RESET_ALL)
  28. # Load Output.pickle files for the test description
  29. def loadRoot(f):
  30. root = None
  31. with open(f,"rb") as inf:
  32. root=pickle.load(inf)
  33. return(root)
  34. # Get test suites from the test descriptions
  35. def getSuites(node,filterList,currentList=[]):
  36. if node.kind==TreeElem.SUITE:
  37. currentList.append(node.data["class"])
  38. if node.kind==TreeElem.GROUP:
  39. if not node.data["class"] in filterList:
  40. for c in node.children:
  41. getSuites(c,filterList,currentList)
  42. class Result:
  43. def __init__(self,msg,error=False):
  44. self._error = error
  45. self._msg = msg
  46. @property
  47. def error(self):
  48. return self._error
  49. @property
  50. def msg(self):
  51. return self._msg
  52. # Run a command and get error or result
  53. # For the test report we don't need the stderr
  54. # in case of error since the test report is giving
  55. # all the details. So, there is an option to
  56. # disable the dump of stderr
  57. def run(*args,mustPrint=False,dumpStdErr=True):
  58. global ERROR_OCCURED
  59. global DEBUG
  60. try:
  61. if DEBUG:
  62. print(" ".join(args))
  63. result=subprocess.run(args,text=True,capture_output=True,timeout=600)
  64. if result.returncode !=0 :
  65. ERROR_OCCURED = True
  66. if dumpStdErr:
  67. return(Result(result.stderr + "\n\nSTDOUT:\n\n" + result.stdout,error=True))
  68. else:
  69. return(Result(result.stdout,error=True))
  70. if mustPrint:
  71. print(result.stdout)
  72. return(Result(result.stdout))
  73. except Exception as e:
  74. printError("Exception occured")
  75. ERROR_OCCURED = True
  76. return(Result(str(e),error=True))
  77. # Configuration file for AVH core
  78. configFiles={
  79. "CS310":"ARM_VHT_Corstone_310_config.txt",
  80. "CS300":"ARM_VHT_Corstone_300_config.txt",
  81. "M55":"ARM_VHT_MPS2_M55_config.txt",
  82. "M33_DSP_FP":"ARM_VHT_MPS2_M33_DSP_FP_config.txt",
  83. "M7DP":"ARM_VHT_MPS2_M7DP_config.txt",
  84. "M4FP":"ARM_VHT_MPS2_M4FP_config.txt",
  85. "M3":"ARM_VHT_MPS2_M3_config.txt",
  86. "M23":"ARM_VHT_MPS2_M23_config.txt",
  87. "M0plus":"ARM_VHT_MPS2_M0plus_config.txt",
  88. }
  89. # Windows executable
  90. # (At some point this script will also support
  91. # unix)
  92. avhExe={
  93. "CS310":"VHT_Corstone_SSE-310.exe",
  94. "CS300":"VHT_Corstone_SSE-300_Ethos-U55.exe",
  95. "M55":"VHT_MPS2_Cortex-M55.exe",
  96. "M33_DSP_FP":"VHT_MPS2_Cortex-M33.exe",
  97. "M7DP":"VHT_MPS2_Cortex-M7.exe",
  98. "M4FP":"VHT_MPS2_Cortex-M4.exe",
  99. "M3":"VHT_MPS2_Cortex-M3.exe",
  100. "M23":"VHT_MPS2_Cortex-M23.exe",
  101. "M0plus":"VHT_MPS2_Cortex-M0plus.exe",
  102. }
  103. AVHROOT = args.avh
  104. # Run AVH
  105. def runAVH(build,core):
  106. axf="out/test/%s/Release/test.axf" % (build,)
  107. elf="out/test/%s/Release/test.elf" % (build,)
  108. app = axf
  109. if os.path.exists(axf):
  110. app = axf
  111. if os.path.exists(elf):
  112. app = elf
  113. config = os.path.join("configs",configFiles[core])
  114. avh = os.path.join(AVHROOT,avhExe[core])
  115. res=run(avh,"-f",config,app)
  116. return(res)
  117. ####################
  118. # Test descriptions to use
  119. tests=["../Output.pickle","../Output_f16.pickle"]
  120. # Test group to avoid
  121. filterList=["NNTests","ExampleTests"]
  122. allSuites=[]
  123. # Load all the test suite to run
  124. for t in tests:
  125. root=loadRoot(t)
  126. suites=[]
  127. getSuites(root,filterList,suites)
  128. allSuites += [(x,t) for x in suites ]
  129. # Test suite and output pickle needed to decode the result
  130. #print(allSuites)
  131. #allSuites=[
  132. #("MFCCQ15","../Output.pickle"),
  133. #("MFCCQ31","../Output.pickle"),
  134. #("SupportTestsF16","../Output_f16.pickle"),
  135. #]
  136. #allSuites=[("ComplexTestsF32","../Output.pickle"),
  137. #("DistanceTestsF32","../Output.pickle"),
  138. #("UnaryTestsF32","../Output.pickle"),
  139. #("QuaternionTestsF32","../Output.pickle"),
  140. #("StatsTestsF32","../Output.pickle")
  141. #]
  142. #allSuites=[
  143. #("TransformCF64","../Output.pickle"),
  144. #("TransformCF32","../Output.pickle"),
  145. #("TransformCQ31","../Output.pickle"),
  146. #("TransformCQ15","../Output.pickle"),
  147. #
  148. #("TransformRF64","../Output.pickle"),
  149. #("TransformRF32","../Output.pickle"),
  150. #("TransformRQ31","../Output.pickle"),
  151. #("TransformRQ15","../Output.pickle"),
  152. #
  153. #("MFCCF32","../Output.pickle"),
  154. #("MFCCQ31","../Output.pickle"),
  155. #("MFCCQ15","../Output.pickle"),
  156. #
  157. #("MFCCF16","../Output_f16.pickle"),
  158. #("TransformCF16","../Output_f16.pickle"),
  159. #("TransformRF16","../Output_f16.pickle")
  160. #]
  161. #allSuites=[("StatsTestsQ7","../Output.pickle")]
  162. allSuites=[
  163. ("InterpolationTestsF32","../Output.pickle"),
  164. ("InterpolationTestsF16","../Output_f16.pickle"),
  165. #("MISCQ15","../Output.pickle"),
  166. #("MISCQ7","../Output.pickle"),
  167. #("FIRF16","../Output_f16.pickle")
  168. ]
  169. # Solution and build file for all
  170. # the tests
  171. # It is a pair : csolution target type and AVH identification
  172. # AVH identification is used to find the executable
  173. # and the configuration file
  174. solutions={
  175. 'test_ac6.csolution.yml':[
  176. # ("VHT-Corstone-310","CS310"),
  177. ("VHT-Corstone-300","CS300"),
  178. # ("VHT-Corstone-300-NOMVE","CS300"),
  179. ("VHT_M33","M33_DSP_FP"),
  180. ("VHT_M7","M7DP"),
  181. ("VHT_M7_UNROLLED","M7DP"),
  182. ("VHT_M4","M4FP"),
  183. # #("VHT_M3","M3"),
  184. # #("VHT_M23","M23"),
  185. ("VHT_M0P","M0plus")
  186. ],
  187. 'test_gcc.csolution.yml':[
  188. #("VHT-Corstone-310","CS310"),
  189. #("VHT_M55","M55"),
  190. ##("VHT_M33","M33_DSP_FP"),
  191. ("VHT_M7","M7DP"),
  192. ("VHT_M7_UNROLLED","M7DP"),
  193. ("VHT_M4","M4FP"),
  194. ##("VHT_M3","M3"),
  195. ##("VHT_M23","M23"),
  196. ("VHT_M0P","M0plus")
  197. ]
  198. }
  199. # Override previous solutions for more restricted testing.
  200. solutions={
  201. 'test_ac6.csolution.yml':[
  202. ("VHT-Corstone-300","CS300"),
  203. ]
  204. }
  205. HTMLHEADER="""<html>
  206. <header>
  207. <title>CMSIS-DSP Test summary</title>
  208. </header>
  209. <body>
  210. """
  211. HTMLFOOTER="""
  212. </body></html>
  213. """
  214. # Run the tests and log the result
  215. # in a summary.html file
  216. with open("summary.html","w") as f:
  217. print(HTMLHEADER,file=f)
  218. for s in solutions:
  219. printTitle("Process solution %s" % s)
  220. res=run("csolution","convert","-s",s)
  221. if res.error:
  222. printError("Error csolution")
  223. print("<p><font color=\"red\">Error converting csolution %s</font></p><PRE>" % s,file=f)
  224. print(res.msg,file=f)
  225. print("</PRE>",file=f)
  226. continue
  227. print("<h1>Solution %s</h1>" % s,file=f)
  228. maxNbBuilds=len(solutions[s])
  229. buildNb=0
  230. for build,core in solutions[s]:
  231. buildNb = buildNb + 1
  232. print("<h2>Core %s</h2>" % build,file=f)
  233. printTitle("Process core %s (%d/%d)" % (build,buildNb,maxNbBuilds))
  234. buildFile="test.Release+%s.cprj" % build
  235. nb = 0
  236. maxNb = len(allSuites)
  237. for s,pickle in allSuites:
  238. nb = nb + 1
  239. printSubTitle("Process suite %s (%d/%d)" % (s,nb,maxNb))
  240. res=run(sys.executable,"../processTests.py","-gen","..","-p","../Patterns","-d","../Parameters","-f",pickle,"-e",s,mustPrint=True)
  241. if res.error:
  242. printError("Error processTests")
  243. print("<p><font color=\"red\">Error generating %s</font></p><PRE>" % s,file=f)
  244. print(res.msg,file=f)
  245. print("</PRE>",file=f)
  246. continue
  247. if nb==1:
  248. # -r is needed for first
  249. # build when we switch
  250. # between different solutions
  251. # (Like one using AC6 and the other
  252. # using gcc)
  253. if args.n:
  254. res=run("cbuild",buildFile)
  255. else:
  256. res=run("cbuild","-r",buildFile)
  257. else:
  258. res=run("cbuild",buildFile)
  259. if res.error:
  260. printError("Error cbuild")
  261. print("<p><font color=\"red\">Error building %s</font></p><PRE>" % s,file=f)
  262. print(res.msg,file=f)
  263. print("</PRE>",file=f)
  264. continue
  265. printSubTitle("Run AVH")
  266. res=runAVH(build,core)
  267. if res.error:
  268. printError("Error running AVH")
  269. print("<p><font color=\"red\">Error running %s</font></p><PRE>" % s,file=f)
  270. print(res.msg,file=f)
  271. print("</PRE>",file=f)
  272. continue
  273. else:
  274. with open("results.txt","w") as o:
  275. print(res.msg,file=o)
  276. # Dump raw result
  277. if args.r:
  278. print(res.msg)
  279. # If raw result, no post processing
  280. if not args.r:
  281. res=run(sys.executable,"../processResult.py","-f",pickle,"-e","-ahtml","-r","results.txt",dumpStdErr=False)
  282. if res.error:
  283. printError("Error processResult")
  284. print("<p><font color=\"red\">Error processing %s result</font></p><PRE>" % s,file=f)
  285. print(res.msg,file=f)
  286. print("</PRE>",file=f)
  287. continue
  288. else:
  289. # When no error the section is
  290. # included in final file on when
  291. # cycles are requested
  292. if args.c:
  293. print(res.msg,file=f)
  294. print(HTMLFOOTER,file=f)
  295. if ERROR_OCCURED:
  296. sys.exit("Error occurred")
  297. else:
  298. sys.exit(0)