Tools.py 17 KB

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