Tools.py 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494
  1. import os.path
  2. import struct
  3. import numpy as np
  4. def createMissingDir(destPath):
  5. theDir=os.path.normpath(destPath)
  6. if not os.path.exists(theDir):
  7. os.makedirs(theDir)
  8. # Pack an array of boolean into uint32
  9. def packset(a):
  10. b = np.packbits(a)
  11. newSize = int(np.ceil(b.shape[0] / 4.0)) * 4
  12. c = np.copy(b)
  13. c.resize(newSize)
  14. #print(c)
  15. vecSize = round(newSize/4)
  16. c=c.reshape(vecSize,4)
  17. #print(c)
  18. r = np.zeros(vecSize)
  19. result = []
  20. for i in range(0,vecSize):
  21. #print(c[i,:])
  22. #print("%X %X %X %X" % (c[i,0],c[i,1],c[i,2],c[i,3]))
  23. d = (c[i,0] << 24) | (c[i,1] << 16) | (c[i,2] << 8) | c[i,3]
  24. result.append(d)
  25. return(result)
  26. def float_to_hex(f):
  27. """ Convert and x86 float to an ARM unsigned long int.
  28. Args:
  29. f (float): value to be converted
  30. Raises:
  31. Nothing
  32. Returns:
  33. str : representation of the hex value
  34. """
  35. return hex(struct.unpack('<I', struct.pack('<f', f))[0])
  36. def to_q31(v):
  37. r = int(round(v * 2**31))
  38. if (r > 0x07FFFFFFF):
  39. r = 0x07FFFFFFF
  40. if (r < -0x080000000):
  41. r = -0x080000000
  42. return ("0x%s" % format(struct.unpack('<I', struct.pack('<i', r))[0],'08X'))
  43. def to_q15(v):
  44. r = int(round(v * 2**15))
  45. if (r > 0x07FFF):
  46. r = 0x07FFF
  47. if (r < -0x08000):
  48. r = -0x08000
  49. return ("0x%s" % format(struct.unpack('<H', struct.pack('<h', r))[0],'04X'))
  50. def to_q7(v):
  51. r = int(round(v * 2**7))
  52. if (r > 0x07F):
  53. r = 0x07F
  54. if (r < -0x080):
  55. r = -0x080
  56. return ("0x%s" % format(struct.unpack('<B', struct.pack('<b', r))[0],'02X'))
  57. def s8(r):
  58. return ("0x%s" % format(struct.unpack('<B', struct.pack('<b', r))[0],'02X'))
  59. def s16(r):
  60. return ("0x%s" % format(struct.unpack('<H', struct.pack('<h', r))[0],'04X'))
  61. def s32(r):
  62. return ("0x%s" % format(struct.unpack('<I', struct.pack('<i', r))[0],'08X'))
  63. def u32(r):
  64. return ("0x%s" % format(struct.unpack('<I', struct.pack('<i', r))[0],'08X'))
  65. class Config:
  66. def __init__(self,patternDir,paramDir,ext):
  67. self._patternDir = "%s%s" % (patternDir,ext.upper())
  68. self._paramDir = "%s%s" % (paramDir,ext.upper())
  69. self._ext = ext
  70. createMissingDir(self._patternDir)
  71. createMissingDir(self._paramDir)
  72. def inputP(self,i,name=None):
  73. """ Path to a reference pattern from the ID
  74. Args:
  75. i (int): ID to the reference pattern
  76. Raises:
  77. Nothing
  78. Returns:
  79. str : path to the file where to generate the pattern data
  80. """
  81. if name:
  82. return(os.path.join(self._patternDir,"%s%d_%s.txt" % (name,i,self._ext)))
  83. else:
  84. return(os.path.join(self._patternDir,"Input%d_%s.txt" % (i,self._ext)))
  85. def inputS16P(self,i,name=None):
  86. """ Path to a reference pattern from the ID
  87. Args:
  88. i (int): ID to the reference pattern
  89. Raises:
  90. Nothing
  91. Returns:
  92. str : path to the file where to generate the pattern data
  93. """
  94. if name:
  95. return(os.path.join(self._patternDir,"%s%d_%s.txt" % (name,i,"s16")))
  96. else:
  97. return(os.path.join(self._patternDir,"Input%d_%s.txt" % (i,"s16")))
  98. def inputU32P(self,i,name=None):
  99. """ Path to a reference pattern from the ID
  100. Args:
  101. i (int): ID to the reference pattern
  102. Raises:
  103. Nothing
  104. Returns:
  105. str : path to the file where to generate the pattern data
  106. """
  107. if name:
  108. return(os.path.join(self._patternDir,"%s%d_%s.txt" % (name,i,"u32")))
  109. else:
  110. return(os.path.join(self._patternDir,"Input%d_%s.txt" % (i,"u32")))
  111. def refP(self,i,name=None):
  112. """ Path to a reference pattern from the ID
  113. Args:
  114. i (int): ID to the reference pattern
  115. Raises:
  116. Nothing
  117. Returns:
  118. str : path to the file where to generate the pattern data
  119. """
  120. if name:
  121. return(os.path.join(self._patternDir,"%s%d_%s.txt" % (name,i,self._ext)))
  122. else:
  123. return(os.path.join(self._patternDir,"Reference%d_%s.txt" % (i,self._ext)))
  124. def refS8P(self,i,name=None):
  125. """ Path to a reference pattern from the ID
  126. Args:
  127. i (int): ID to the reference pattern
  128. Raises:
  129. Nothing
  130. Returns:
  131. str : path to the file where to generate the pattern data
  132. """
  133. if name:
  134. return(os.path.join(self._patternDir,"%s%d_%s.txt" % (name,i,"s8")))
  135. else:
  136. return(os.path.join(self._patternDir,"Reference%d_%s.txt" % (i,"s8")))
  137. def refS16P(self,i,name=None):
  138. """ Path to a reference pattern from the ID
  139. Args:
  140. i (int): ID to the reference pattern
  141. Raises:
  142. Nothing
  143. Returns:
  144. str : path to the file where to generate the pattern data
  145. """
  146. if name:
  147. return(os.path.join(self._patternDir,"%s%d_%s.txt" % (name,i,"s16")))
  148. else:
  149. return(os.path.join(self._patternDir,"Reference%d_%s.txt" % (i,"s16")))
  150. def refS32P(self,i,name=None):
  151. """ Path to a reference pattern from the ID
  152. Args:
  153. i (int): ID to the reference pattern
  154. Raises:
  155. Nothing
  156. Returns:
  157. str : path to the file where to generate the pattern data
  158. """
  159. if name:
  160. return(os.path.join(self._patternDir,"%s%d_%s.txt" % (name,i,"s32")))
  161. else:
  162. return(os.path.join(self._patternDir,"Reference%d_%s.txt" % (i,"s32")))
  163. def refF32P(self,i,name=None):
  164. """ Path to a reference pattern from the ID
  165. Args:
  166. i (int): ID to the reference pattern
  167. Raises:
  168. Nothing
  169. Returns:
  170. str : path to the file where to generate the pattern data
  171. """
  172. if name:
  173. return(os.path.join(self._patternDir,"%s%d_%s.txt" % (name,i,"f32")))
  174. else:
  175. return(os.path.join(self._patternDir,"Reference%d_%s.txt" % (i,"f32")))
  176. def paramP(self,i,name=None):
  177. """ Path to a parameters from the ID
  178. Args:
  179. i (int): ID to the params
  180. Raises:
  181. Nothing
  182. Returns:
  183. str : path to the file where to generate the pattern data
  184. """
  185. if name:
  186. return(os.path.join(self._paramDir,"%s%d.txt" % (name,i)))
  187. else:
  188. return(os.path.join(self._paramDir,"Params%d.txt" % i))
  189. def _writeVectorF32(self,i,data):
  190. """ Write pattern data
  191. The format is recognized by the text framework script.
  192. First line is the sample width (B,H or W for 8,16 or 32 bits)
  193. Second line is number of samples
  194. Other lines are hexadecimal representation of the samples in format
  195. which can be read on big endian ARM.
  196. Args:
  197. j (int): ID of pattern file
  198. data (array): Vector containing the data
  199. Raises:
  200. Nothing
  201. Returns:
  202. Nothing
  203. """
  204. with open(i,"w") as f:
  205. # Write sample dimension nb sample header
  206. #np.savetxt(i, data, newline="\n", header="W\n%d" % len(data),comments ="" )
  207. f.write("W\n%d\n" % len(data))
  208. for v in data:
  209. f.write("// %f\n" % v)
  210. f.write("%s\n" % float_to_hex(v))
  211. def _writeVectorQ31(self,i,data):
  212. """ Write pattern data
  213. The format is recognized by the text framework script.
  214. First line is the sample width (B,H or W for 8,16 or 32 bits)
  215. Second line is number of samples
  216. Other lines are hexadecimal representation of the samples in format
  217. which can be read on big endian ARM.
  218. Args:
  219. j (int): ID of pattern file
  220. data (array): Vector containing the data
  221. Raises:
  222. Nothing
  223. Returns:
  224. Nothing
  225. """
  226. with open(i,"w") as f:
  227. # Write sample dimension nb sample header
  228. #np.savetxt(i, data, newline="\n", header="W\n%d" % len(data),comments ="" )
  229. f.write("W\n%d\n" % len(data))
  230. for v in data:
  231. f.write("// %f\n" % v)
  232. f.write("%s\n" % to_q31(v))
  233. def _writeVectorQ15(self,i,data):
  234. """ Write pattern data
  235. The format is recognized by the text framework script.
  236. First line is the sample width (B,H or W for 8,16 or 32 bits)
  237. Second line is number of samples
  238. Other lines are hexadecimal representation of the samples in format
  239. which can be read on big endian ARM.
  240. Args:
  241. j (int): ID of pattern file
  242. data (array): Vector containing the data
  243. Raises:
  244. Nothing
  245. Returns:
  246. Nothing
  247. """
  248. with open(i,"w") as f:
  249. # Write sample dimension nb sample header
  250. #np.savetxt(i, data, newline="\n", header="W\n%d" % len(data),comments ="" )
  251. f.write("H\n%d\n" % len(data))
  252. for v in data:
  253. f.write("// %f\n" % v)
  254. f.write("%s\n" % to_q15(v))
  255. def _writeVectorS16(self,i,data):
  256. """ Write pattern data
  257. The format is recognized by the text framework script.
  258. First line is the sample width (B,H or W for 8,16 or 32 bits)
  259. Second line is number of samples
  260. Other lines are hexadecimal representation of the samples in format
  261. which can be read on big endian ARM.
  262. Args:
  263. j (int): ID of pattern file
  264. data (array): Vector containing the data
  265. Raises:
  266. Nothing
  267. Returns:
  268. Nothing
  269. """
  270. with open(i,"w") as f:
  271. # Write sample dimension nb sample header
  272. #np.savetxt(i, data, newline="\n", header="W\n%d" % len(data),comments ="" )
  273. f.write("H\n%d\n" % len(data))
  274. for v in data:
  275. f.write("// %d\n" % v)
  276. f.write("%s\n" % s16(v))
  277. def _writeVectorS32(self,i,data):
  278. """ Write pattern data
  279. The format is recognized by the text framework script.
  280. First line is the sample width (B,H or W for 8,16 or 32 bits)
  281. Second line is number of samples
  282. Other lines are hexadecimal representation of the samples in format
  283. which can be read on big endian ARM.
  284. Args:
  285. j (int): ID of pattern file
  286. data (array): Vector containing the data
  287. Raises:
  288. Nothing
  289. Returns:
  290. Nothing
  291. """
  292. with open(i,"w") as f:
  293. # Write sample dimension nb sample header
  294. #np.savetxt(i, data, newline="\n", header="W\n%d" % len(data),comments ="" )
  295. f.write("W\n%d\n" % len(data))
  296. for v in data:
  297. f.write("// %d\n" % v)
  298. f.write("%s\n" % s32(v))
  299. def _writeVectorU32(self,i,data):
  300. """ Write pattern data
  301. The format is recognized by the text framework script.
  302. First line is the sample width (B,H or W for 8,16 or 32 bits)
  303. Second line is number of samples
  304. Other lines are hexadecimal representation of the samples in format
  305. which can be read on big endian ARM.
  306. Args:
  307. j (int): ID of pattern file
  308. data (array): Vector containing the data
  309. Raises:
  310. Nothing
  311. Returns:
  312. Nothing
  313. """
  314. with open(i,"w") as f:
  315. # Write sample dimension nb sample header
  316. #np.savetxt(i, data, newline="\n", header="W\n%d" % len(data),comments ="" )
  317. f.write("W\n%d\n" % len(data))
  318. for v in data:
  319. f.write("// %s\n" % u32(v))
  320. f.write("%s\n" % u32(v))
  321. def _writeVectorQ7(self,i,data):
  322. """ Write pattern data
  323. The format is recognized by the text framework script.
  324. First line is the sample width (B,H or W for 8,16 or 32 bits)
  325. Second line is number of samples
  326. Other lines are hexadecimal representation of the samples in format
  327. which can be read on big endian ARM.
  328. Args:
  329. j (int): ID of pattern file
  330. data (array): Vector containing the data
  331. Raises:
  332. Nothing
  333. Returns:
  334. Nothing
  335. """
  336. with open(i,"w") as f:
  337. # Write sample dimension nb sample header
  338. #np.savetxt(i, data, newline="\n", header="W\n%d" % len(data),comments ="" )
  339. f.write("B\n%d\n" % len(data))
  340. for v in data:
  341. f.write("// %f\n" % v)
  342. f.write("%s\n" % to_q7(v))
  343. def _writeVectorS8(self,i,data):
  344. """ Write pattern data
  345. The format is recognized by the text framework script.
  346. First line is the sample width (B,H or W for 8,16 or 32 bits)
  347. Second line is number of samples
  348. Other lines are hexadecimal representation of the samples in format
  349. which can be read on big endian ARM.
  350. Args:
  351. j (int): ID of pattern file
  352. data (array): Vector containing the data
  353. Raises:
  354. Nothing
  355. Returns:
  356. Nothing
  357. """
  358. with open(i,"w") as f:
  359. # Write sample dimension nb sample header
  360. #np.savetxt(i, data, newline="\n", header="W\n%d" % len(data),comments ="" )
  361. f.write("B\n%d\n" % len(data))
  362. for v in data:
  363. f.write("// %d\n" % v)
  364. f.write("%s\n" % s8(v))
  365. def writeReference(self,j,data,name=None):
  366. if (self._ext == "f32"):
  367. self._writeVectorF32(self.refP(j,name),data)
  368. if (self._ext == "q31"):
  369. self._writeVectorQ31(self.refP(j,name),data)
  370. if (self._ext == "q15"):
  371. self._writeVectorQ15(self.refP(j,name),data)
  372. if (self._ext == "q7"):
  373. self._writeVectorQ7(self.refP(j,name),data)
  374. if (self._ext == "u32"):
  375. self._writeVectorU32(self.refP(j,name),data)
  376. if (self._ext == "s8"):
  377. self._writeVectorS8(self.refP(j,name),data)
  378. def writeReferenceS8(self,j,data,name=None):
  379. self._writeVectorS8(self.refS8P(j,name),data)
  380. def writeReferenceS16(self,j,data,name=None):
  381. self._writeVectorS16(self.refS16P(j,name),data)
  382. def writeReferenceS32(self,j,data,name=None):
  383. self._writeVectorS32(self.refS32P(j,name),data)
  384. def writeReferenceF32(self,j,data,name=None):
  385. self._writeVectorF32(self.refF32P(j,name),data)
  386. def writeInput(self,j,data,name=None):
  387. if (self._ext == "f32"):
  388. self._writeVectorF32(self.inputP(j,name),data)
  389. if (self._ext == "q31"):
  390. self._writeVectorQ31(self.inputP(j,name),data)
  391. if (self._ext == "q15"):
  392. self._writeVectorQ15(self.inputP(j,name),data)
  393. if (self._ext == "q7"):
  394. self._writeVectorQ7(self.inputP(j,name),data)
  395. if (self._ext == "u32"):
  396. self._writeVectorU32(self.inputP(j,name),data)
  397. if (self._ext == "s8"):
  398. self._writeVectorS8(self.inputP(j,name),data)
  399. def writeInputS16(self,j,data,name=None):
  400. self._writeVectorS16(self.inputS16P(j,name),data)
  401. def writeInputU32(self,j,data,name=None):
  402. self._writeVectorU32(self.inputU32P(j,name),data)
  403. def writeParam(self,j,data,name=None):
  404. """ Write pattern data
  405. The format is recognized by the text framework script.
  406. First line is the sample width (B,H or W for 8,16 or 32 bits)
  407. Second line is number of samples
  408. Other lines are hexadecimal representation of the samples in format
  409. which can be read on big endian ARM.
  410. Args:
  411. j (int): ID of parameter file
  412. data (array): Vector containing the data
  413. Raises:
  414. Nothing
  415. Returns:
  416. Nothing
  417. """
  418. i=self.paramP(j,name)
  419. with open(i,"w") as f:
  420. # Write sample dimension nb sample header
  421. #np.savetxt(i, data, newline="\n", header="W\n%d" % len(data),comments ="" )
  422. f.write("%d\n" % len(data))
  423. for v in data:
  424. f.write("%d\n" % v)