Tools.py 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589
  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 inputQ31P(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,"q31")))
  119. else:
  120. return(os.path.join(self._patternDir,"Input%d_%s.txt" % (i,"q31")))
  121. def inputQ15P(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,"q15")))
  132. else:
  133. return(os.path.join(self._patternDir,"Input%d_%s.txt" % (i,"q15")))
  134. def inputQ7P(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,"q7")))
  145. else:
  146. return(os.path.join(self._patternDir,"Input%d_%s.txt" % (i,"q7")))
  147. def inputU32P(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,"u32")))
  158. else:
  159. return(os.path.join(self._patternDir,"Input%d_%s.txt" % (i,"u32")))
  160. def refP(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,self._ext)))
  171. else:
  172. return(os.path.join(self._patternDir,"Reference%d_%s.txt" % (i,self._ext)))
  173. def refS8P(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,"s8")))
  184. else:
  185. return(os.path.join(self._patternDir,"Reference%d_%s.txt" % (i,"s8")))
  186. def refS16P(self,i,name=None):
  187. """ Path to a reference pattern from the ID
  188. Args:
  189. i (int): ID to the reference pattern
  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._patternDir,"%s%d_%s.txt" % (name,i,"s16")))
  197. else:
  198. return(os.path.join(self._patternDir,"Reference%d_%s.txt" % (i,"s16")))
  199. def refS32P(self,i,name=None):
  200. """ Path to a reference pattern from the ID
  201. Args:
  202. i (int): ID to the reference pattern
  203. Raises:
  204. Nothing
  205. Returns:
  206. str : path to the file where to generate the pattern data
  207. """
  208. if name:
  209. return(os.path.join(self._patternDir,"%s%d_%s.txt" % (name,i,"s32")))
  210. else:
  211. return(os.path.join(self._patternDir,"Reference%d_%s.txt" % (i,"s32")))
  212. def refF32P(self,i,name=None):
  213. """ Path to a reference pattern from the ID
  214. Args:
  215. i (int): ID to the reference pattern
  216. Raises:
  217. Nothing
  218. Returns:
  219. str : path to the file where to generate the pattern data
  220. """
  221. if name:
  222. return(os.path.join(self._patternDir,"%s%d_%s.txt" % (name,i,"f32")))
  223. else:
  224. return(os.path.join(self._patternDir,"Reference%d_%s.txt" % (i,"f32")))
  225. def paramP(self,i,name=None):
  226. """ Path to a parameters from the ID
  227. Args:
  228. i (int): ID to the params
  229. Raises:
  230. Nothing
  231. Returns:
  232. str : path to the file where to generate the pattern data
  233. """
  234. if name:
  235. return(os.path.join(self._paramDir,"%s%d.txt" % (name,i)))
  236. else:
  237. return(os.path.join(self._paramDir,"Params%d.txt" % i))
  238. def _writeVectorF64(self,i,data):
  239. """ Write pattern data
  240. The format is recognized by the text framework script.
  241. First line is the sample width (B,H or W,D for 8,16,32 or 64 bits)
  242. Second line is number of samples
  243. Other lines are hexadecimal representation of the samples in format
  244. which can be read on big endian ARM.
  245. Args:
  246. j (int): ID of pattern file
  247. data (array): Vector containing the data
  248. Raises:
  249. Nothing
  250. Returns:
  251. Nothing
  252. """
  253. with open(i,"w") as f:
  254. # Write sample dimension nb sample header
  255. #np.savetxt(i, data, newline="\n", header="W\n%d" % len(data),comments ="" )
  256. f.write("D\n%d\n" % len(data))
  257. for v in data:
  258. f.write("// %f\n" % v)
  259. f.write("%s\n" % float64_to_hex(v))
  260. def _writeVectorF32(self,i,data):
  261. """ Write pattern data
  262. The format is recognized by the text framework script.
  263. First line is the sample width (B,H or W for 8,16 or 32 bits)
  264. Second line is number of samples
  265. Other lines are hexadecimal representation of the samples in format
  266. which can be read on big endian ARM.
  267. Args:
  268. j (int): ID of pattern file
  269. data (array): Vector containing the data
  270. Raises:
  271. Nothing
  272. Returns:
  273. Nothing
  274. """
  275. with open(i,"w") as f:
  276. # Write sample dimension nb sample header
  277. #np.savetxt(i, data, newline="\n", header="W\n%d" % len(data),comments ="" )
  278. f.write("W\n%d\n" % len(data))
  279. for v in data:
  280. f.write("// %f\n" % v)
  281. f.write("%s\n" % float_to_hex(v))
  282. def _writeVectorQ31(self,i,data):
  283. """ Write pattern data
  284. The format is recognized by the text framework script.
  285. First line is the sample width (B,H or W for 8,16 or 32 bits)
  286. Second line is number of samples
  287. Other lines are hexadecimal representation of the samples in format
  288. which can be read on big endian ARM.
  289. Args:
  290. j (int): ID of pattern file
  291. data (array): Vector containing the data
  292. Raises:
  293. Nothing
  294. Returns:
  295. Nothing
  296. """
  297. with open(i,"w") as f:
  298. # Write sample dimension nb sample header
  299. #np.savetxt(i, data, newline="\n", header="W\n%d" % len(data),comments ="" )
  300. f.write("W\n%d\n" % len(data))
  301. for v in data:
  302. f.write("// %f\n" % v)
  303. f.write("%s\n" % to_q31(v))
  304. def _writeVectorQ15(self,i,data):
  305. """ Write pattern data
  306. The format is recognized by the text framework script.
  307. First line is the sample width (B,H or W for 8,16 or 32 bits)
  308. Second line is number of samples
  309. Other lines are hexadecimal representation of the samples in format
  310. which can be read on big endian ARM.
  311. Args:
  312. j (int): ID of pattern file
  313. data (array): Vector containing the data
  314. Raises:
  315. Nothing
  316. Returns:
  317. Nothing
  318. """
  319. with open(i,"w") as f:
  320. # Write sample dimension nb sample header
  321. #np.savetxt(i, data, newline="\n", header="W\n%d" % len(data),comments ="" )
  322. f.write("H\n%d\n" % len(data))
  323. for v in data:
  324. f.write("// %f\n" % v)
  325. f.write("%s\n" % to_q15(v))
  326. def _writeVectorS16(self,i,data):
  327. """ Write pattern data
  328. The format is recognized by the text framework script.
  329. First line is the sample width (B,H or W for 8,16 or 32 bits)
  330. Second line is number of samples
  331. Other lines are hexadecimal representation of the samples in format
  332. which can be read on big endian ARM.
  333. Args:
  334. j (int): ID of pattern file
  335. data (array): Vector containing the data
  336. Raises:
  337. Nothing
  338. Returns:
  339. Nothing
  340. """
  341. with open(i,"w") as f:
  342. # Write sample dimension nb sample header
  343. #np.savetxt(i, data, newline="\n", header="W\n%d" % len(data),comments ="" )
  344. f.write("H\n%d\n" % len(data))
  345. for v in data:
  346. f.write("// %d\n" % v)
  347. f.write("%s\n" % s16(v))
  348. def _writeVectorS32(self,i,data):
  349. """ Write pattern data
  350. The format is recognized by the text framework script.
  351. First line is the sample width (B,H or W for 8,16 or 32 bits)
  352. Second line is number of samples
  353. Other lines are hexadecimal representation of the samples in format
  354. which can be read on big endian ARM.
  355. Args:
  356. j (int): ID of pattern file
  357. data (array): Vector containing the data
  358. Raises:
  359. Nothing
  360. Returns:
  361. Nothing
  362. """
  363. with open(i,"w") as f:
  364. # Write sample dimension nb sample header
  365. #np.savetxt(i, data, newline="\n", header="W\n%d" % len(data),comments ="" )
  366. f.write("W\n%d\n" % len(data))
  367. for v in data:
  368. f.write("// %d\n" % v)
  369. f.write("%s\n" % s32(v))
  370. def _writeVectorU32(self,i,data):
  371. """ Write pattern data
  372. The format is recognized by the text framework script.
  373. First line is the sample width (B,H or W for 8,16 or 32 bits)
  374. Second line is number of samples
  375. Other lines are hexadecimal representation of the samples in format
  376. which can be read on big endian ARM.
  377. Args:
  378. j (int): ID of pattern file
  379. data (array): Vector containing the data
  380. Raises:
  381. Nothing
  382. Returns:
  383. Nothing
  384. """
  385. with open(i,"w") as f:
  386. # Write sample dimension nb sample header
  387. #np.savetxt(i, data, newline="\n", header="W\n%d" % len(data),comments ="" )
  388. f.write("W\n%d\n" % len(data))
  389. for v in data:
  390. f.write("// %s\n" % u32(v))
  391. f.write("%s\n" % u32(v))
  392. def _writeVectorQ7(self,i,data):
  393. """ Write pattern data
  394. The format is recognized by the text framework script.
  395. First line is the sample width (B,H or W for 8,16 or 32 bits)
  396. Second line is number of samples
  397. Other lines are hexadecimal representation of the samples in format
  398. which can be read on big endian ARM.
  399. Args:
  400. j (int): ID of pattern file
  401. data (array): Vector containing the data
  402. Raises:
  403. Nothing
  404. Returns:
  405. Nothing
  406. """
  407. with open(i,"w") as f:
  408. # Write sample dimension nb sample header
  409. #np.savetxt(i, data, newline="\n", header="W\n%d" % len(data),comments ="" )
  410. f.write("B\n%d\n" % len(data))
  411. for v in data:
  412. f.write("// %f\n" % v)
  413. f.write("%s\n" % to_q7(v))
  414. def _writeVectorS8(self,i,data):
  415. """ Write pattern data
  416. The format is recognized by the text framework script.
  417. First line is the sample width (B,H or W for 8,16 or 32 bits)
  418. Second line is number of samples
  419. Other lines are hexadecimal representation of the samples in format
  420. which can be read on big endian ARM.
  421. Args:
  422. j (int): ID of pattern file
  423. data (array): Vector containing the data
  424. Raises:
  425. Nothing
  426. Returns:
  427. Nothing
  428. """
  429. with open(i,"w") as f:
  430. # Write sample dimension nb sample header
  431. #np.savetxt(i, data, newline="\n", header="W\n%d" % len(data),comments ="" )
  432. f.write("B\n%d\n" % len(data))
  433. for v in data:
  434. f.write("// %d\n" % v)
  435. f.write("%s\n" % s8(v))
  436. def writeReference(self,j,data,name=None):
  437. if (self._ext == "f64"):
  438. self._writeVectorF64(self.refP(j,name),data)
  439. if (self._ext == "f32"):
  440. self._writeVectorF32(self.refP(j,name),data)
  441. if (self._ext == "q31"):
  442. self._writeVectorQ31(self.refP(j,name),data)
  443. if (self._ext == "q15"):
  444. self._writeVectorQ15(self.refP(j,name),data)
  445. if (self._ext == "q7"):
  446. self._writeVectorQ7(self.refP(j,name),data)
  447. if (self._ext == "u32"):
  448. self._writeVectorU32(self.refP(j,name),data)
  449. if (self._ext == "s8"):
  450. self._writeVectorS8(self.refP(j,name),data)
  451. def writeReferenceS8(self,j,data,name=None):
  452. self._writeVectorS8(self.refS8P(j,name),data)
  453. def writeReferenceS16(self,j,data,name=None):
  454. self._writeVectorS16(self.refS16P(j,name),data)
  455. def writeReferenceS32(self,j,data,name=None):
  456. self._writeVectorS32(self.refS32P(j,name),data)
  457. def writeReferenceF32(self,j,data,name=None):
  458. self._writeVectorF32(self.refF32P(j,name),data)
  459. def writeInput(self,j,data,name=None):
  460. if (self._ext == "f64"):
  461. self._writeVectorF64(self.inputP(j,name),data)
  462. if (self._ext == "f32"):
  463. self._writeVectorF32(self.inputP(j,name),data)
  464. if (self._ext == "q31"):
  465. self._writeVectorQ31(self.inputP(j,name),data)
  466. if (self._ext == "q15"):
  467. self._writeVectorQ15(self.inputP(j,name),data)
  468. if (self._ext == "q7"):
  469. self._writeVectorQ7(self.inputP(j,name),data)
  470. if (self._ext == "u32"):
  471. self._writeVectorU32(self.inputP(j,name),data)
  472. if (self._ext == "s8"):
  473. self._writeVectorS8(self.inputP(j,name),data)
  474. def writeInputQ31(self,j,data,name=None):
  475. self._writeVectorQ31(self.inputQ31P(j,name),data)
  476. def writeInputQ15(self,j,data,name=None):
  477. self._writeVectorQ15(self.inputQ15P(j,name),data)
  478. def writeInputQ7(self,j,data,name=None):
  479. self._writeVectorQ7(self.inputQ7P(j,name),data)
  480. def writeInputS16(self,j,data,name=None):
  481. self._writeVectorS16(self.inputS16P(j,name),data)
  482. def writeInputU32(self,j,data,name=None):
  483. self._writeVectorU32(self.inputU32P(j,name),data)
  484. def writeParam(self,j,data,name=None):
  485. """ Write pattern data
  486. The format is recognized by the text framework script.
  487. First line is the sample width (B,H or W for 8,16 or 32 bits)
  488. Second line is number of samples
  489. Other lines are hexadecimal representation of the samples in format
  490. which can be read on big endian ARM.
  491. Args:
  492. j (int): ID of parameter file
  493. data (array): Vector containing the data
  494. Raises:
  495. Nothing
  496. Returns:
  497. Nothing
  498. """
  499. i=self.paramP(j,name)
  500. with open(i,"w") as f:
  501. # Write sample dimension nb sample header
  502. #np.savetxt(i, data, newline="\n", header="W\n%d" % len(data),comments ="" )
  503. f.write("%d\n" % len(data))
  504. for v in data:
  505. f.write("%d\n" % v)