1import os.path 2import itertools 3import Tools 4import random 5import numpy as np 6import scipy 7import scipy.stats 8import math 9 10NBTESTS = 10 11VECDIM = [12,14,20] 12 13def entropyTest(config,nb): 14 DIMS = [3,8,9,12] 15 inputs = [] 16 outputs = [] 17 dims=[NBTESTS] 18 for i in range(0,NBTESTS): 19 vecDim = DIMS[i % len(DIMS)] 20 dims.append(vecDim) 21 v = np.random.rand(vecDim) 22 v = v / np.sum(v) 23 e = scipy.stats.entropy(v) 24 inputs += list(v) 25 outputs.append(e) 26 inputs = np.array(inputs) 27 outputs = np.array(outputs) 28 dims = np.array(dims) 29 config.writeInput(nb, inputs,"Input") 30 config.writeInputS16(nb, dims,"Dims") 31 config.writeReference(nb, outputs,"RefEntropy") 32 33def logsumexpTest(config,nb): 34 DIMS = [3,8,9,12] 35 inputs = [] 36 outputs = [] 37 dims=[NBTESTS] 38 for i in range(0,NBTESTS): 39 vecDim = DIMS[i % len(DIMS)] 40 dims.append(vecDim) 41 v = np.random.rand(vecDim) 42 v = v / np.sum(v) 43 e = scipy.special.logsumexp(v) 44 inputs += list(v) 45 outputs.append(e) 46 inputs = np.array(inputs) 47 outputs = np.array(outputs) 48 dims = np.array(dims) 49 config.writeInput(nb, inputs,"Input") 50 config.writeInputS16(nb, dims,"Dims") 51 config.writeReference(nb, outputs,"RefLogSumExp") 52 53def klTest(config,nb): 54 DIMS = [3,8,9,12] 55 inputsA = [] 56 inputsB = [] 57 outputs = [] 58 vecDim = VECDIM[nb % len(VECDIM)] 59 dims=[NBTESTS] 60 for i in range(0,NBTESTS): 61 vecDim = DIMS[i % len(DIMS)] 62 dims.append(vecDim) 63 va = np.random.rand(vecDim) 64 va = va / np.sum(va) 65 66 vb = np.random.rand(vecDim) 67 vb = vb / np.sum(vb) 68 69 e = scipy.stats.entropy(va,vb) 70 inputsA += list(va) 71 inputsB += list(vb) 72 outputs.append(e) 73 inputsA = np.array(inputsA) 74 inputsB = np.array(inputsB) 75 outputs = np.array(outputs) 76 dims = np.array(dims) 77 config.writeInput(nb, inputsA,"InputA") 78 config.writeInput(nb, inputsB,"InputB") 79 config.writeInputS16(nb, dims,"Dims") 80 config.writeReference(nb, outputs,"RefKL") 81 82def logSumExpDotTest(config,nb): 83 DIMS = [3,8,9,12] 84 inputsA = [] 85 inputsB = [] 86 outputs = [] 87 vecDim = VECDIM[nb % len(VECDIM)] 88 dims=[NBTESTS] 89 for i in range(0,NBTESTS): 90 vecDim = DIMS[i % len(DIMS)] 91 dims.append(vecDim) 92 va = np.random.rand(vecDim) 93 va = va / np.sum(va) 94 95 vb = np.random.rand(vecDim) 96 vb = vb / np.sum(vb) 97 98 d = 0.001 99 # It is a proba so must be in [0,1] 100 # But restricted to ]d,1] so that the log exists 101 va = (1-d)*va + d 102 vb = (1-d)*vb + d 103 e = np.log(np.dot(va,vb)) 104 va = np.log(va) 105 vb = np.log(vb) 106 107 inputsA += list(va) 108 inputsB += list(vb) 109 outputs.append(e) 110 inputsA = np.array(inputsA) 111 inputsB = np.array(inputsB) 112 outputs = np.array(outputs) 113 dims = np.array(dims) 114 config.writeInput(nb, inputsA,"InputA") 115 config.writeInput(nb, inputsB,"InputB") 116 config.writeInputS16(nb, dims,"Dims") 117 config.writeReference(nb, outputs,"RefLogSumExpDot") 118 119def writeF16OnlyTests(config,nb): 120 entropyTest(config,nb) 121 logsumexpTest(config,nb+1) 122 klTest(config,nb+2) 123 logSumExpDotTest(config,nb+3) 124 return(nb+4) 125 126def writeF32OnlyTests(config,nb): 127 entropyTest(config,nb) 128 logsumexpTest(config,nb+1) 129 klTest(config,nb+2) 130 logSumExpDotTest(config,nb+3) 131 return(nb+4) 132 133def writeF64OnlyTests(config,nb): 134 entropyTest(config,nb) 135 logsumexpTest(config,nb+1) 136 klTest(config,nb+2) 137 logSumExpDotTest(config,nb+3) 138 return(nb+4) 139 140# For index in min and max we need to ensure that the difference between values 141# of the input is big enough to be representable on q31, q15 or q7. 142# Otherwise python will compute an index different from the one 143# computed by CMSIS which is normal but then the CMSIS test will fail. 144 145#vfunc = np.vectorize(squarer) 146 147def floatRound(x,f): 148 return(np.round(x * 2**f)/2**f) 149 150# Min / Max tests 151def generateMaxTests(config,nb,format,data): 152 153 154 indexes=[] 155 maxvals=[] 156 157 nbiters = Tools.loopnb(format,Tools.TAILONLY) 158 index=np.argmax(data[0:nbiters]) 159 maxvalue=data[index] 160 161 indexes.append(index) 162 maxvals.append(maxvalue) 163 164 nbiters = Tools.loopnb(format,Tools.BODYONLY) 165 index=np.argmax(data[0:nbiters]) 166 maxvalue=data[index] 167 168 indexes.append(index) 169 maxvals.append(maxvalue) 170 171 nbiters = Tools.loopnb(format,Tools.BODYANDTAIL) 172 index=np.argmax(data[0:nbiters]) 173 maxvalue=data[index] 174 175 indexes.append(index) 176 maxvals.append(maxvalue) 177 178 if format == 7: 179 # Force max at position 280 180 181 nbiters = 280 182 183 data = np.zeros(nbiters) 184 185 data[nbiters-1] = 0.9 186 data[nbiters-2] = 0.8 187 188 index=np.argmax(data[0:nbiters]) 189 maxvalue=data[index] 190 191 indexes.append(index) 192 maxvals.append(maxvalue) 193 194 config.writeInput(nb, data,"InputMaxIndexMax") 195 196 config.writeReference(nb, maxvals,"MaxVals") 197 config.writeInputS16(nb, indexes,"MaxIndexes") 198 return(nb+1) 199 200def generateMinTests(config,nb,format,data): 201 202 203 indexes=[] 204 maxvals=[] 205 206 nbiters = Tools.loopnb(format,Tools.TAILONLY) 207 index=np.argmin(data[0:nbiters]) 208 maxvalue=data[index] 209 210 indexes.append(index) 211 maxvals.append(maxvalue) 212 213 nbiters = Tools.loopnb(format,Tools.BODYONLY) 214 index=np.argmin(data[0:nbiters]) 215 maxvalue=data[index] 216 217 indexes.append(index) 218 maxvals.append(maxvalue) 219 220 nbiters = Tools.loopnb(format,Tools.BODYANDTAIL) 221 index=np.argmin(data[0:nbiters]) 222 maxvalue=data[index] 223 224 indexes.append(index) 225 maxvals.append(maxvalue) 226 227 if format == 7: 228 # Force max at position 280 229 nbiters = 280 230 231 data = 0.9*np.ones(nbiters) 232 233 data[nbiters-1] = 0.0 234 data[nbiters-2] = 0.1 235 236 index=np.argmin(data[0:nbiters]) 237 maxvalue=data[index] 238 239 indexes.append(index) 240 maxvals.append(maxvalue) 241 242 243 config.writeInput(nb, data,"InputMinIndexMax") 244 config.writeReference(nb, maxvals,"MinVals") 245 config.writeInputS16(nb, indexes,"MinIndexes") 246 return(nb+1) 247 248# Min/Max Abs Tests 249def generateMaxAbsTests(config,nb,format,data): 250 data = np.abs(data) 251 252 indexes=[] 253 maxvals=[] 254 255 nbiters = Tools.loopnb(format,Tools.TAILONLY) 256 index=np.argmax(data[0:nbiters]) 257 maxvalue=data[index] 258 259 indexes.append(index) 260 maxvals.append(maxvalue) 261 262 nbiters = Tools.loopnb(format,Tools.BODYONLY) 263 index=np.argmax(data[0:nbiters]) 264 maxvalue=data[index] 265 266 indexes.append(index) 267 maxvals.append(maxvalue) 268 269 nbiters = Tools.loopnb(format,Tools.BODYANDTAIL) 270 index=np.argmax(data[0:nbiters]) 271 maxvalue=data[index] 272 273 indexes.append(index) 274 maxvals.append(maxvalue) 275 276 if format == Tools.Q7 or format == Tools.Q15 or format == Tools.Q31: 277 index=np.argmax(data) 278 maxvalue=data[index] 279 280 indexes.append(index) 281 maxvals.append(maxvalue) 282 283 if format == 7: 284 # Force max at position 280 with a new test 285 286 nbiters = 280 287 288 data = np.zeros(nbiters) 289 290 data[nbiters-1] = 0.9 291 data[nbiters-2] = 0.8 292 293 index=np.argmax(data[0:nbiters]) 294 maxvalue=data[index] 295 296 indexes.append(index) 297 maxvals.append(maxvalue) 298 299 config.writeInput(nb, data,"InputAbsMaxIndexMax") 300 301 302 config.writeReference(nb, maxvals,"AbsMaxVals") 303 config.writeInputS16(nb, indexes,"AbsMaxIndexes") 304 305 return(nb+1) 306 307def generateMinAbsTests(config,nb,format,data): 308 data = np.abs(data) 309 310 indexes=[] 311 maxvals=[] 312 313 nbiters = Tools.loopnb(format,Tools.TAILONLY) 314 index=np.argmin(data[0:nbiters]) 315 maxvalue=data[index] 316 317 indexes.append(index) 318 maxvals.append(maxvalue) 319 320 nbiters = Tools.loopnb(format,Tools.BODYONLY) 321 index=np.argmin(data[0:nbiters]) 322 maxvalue=data[index] 323 324 indexes.append(index) 325 maxvals.append(maxvalue) 326 327 nbiters = Tools.loopnb(format,Tools.BODYANDTAIL) 328 index=np.argmin(data[0:nbiters]) 329 maxvalue=data[index] 330 331 indexes.append(index) 332 maxvals.append(maxvalue) 333 334 if format == 7: 335 # Force max at position 280 336 nbiters = 280 337 338 data = 0.9*np.ones(nbiters) 339 340 data[nbiters-1] = 0.0 341 data[nbiters-2] = 0.1 342 343 index=np.argmin(data[0:nbiters]) 344 maxvalue=data[index] 345 346 indexes.append(index) 347 maxvals.append(maxvalue) 348 349 350 config.writeInput(nb, data,"InputAbsMinIndexMax") 351 config.writeReference(nb, maxvals,"AbsMinVals") 352 config.writeInputS16(nb, indexes,"AbsMinIndexes") 353 return(nb+1) 354 355def averageTest(format,data): 356 return(np.average(data)) 357 358def powerTest(format,data): 359 if format == 31: 360 return(np.dot(data,data) / 2**15) # CMSIS is 2.28 format 361 elif format == 15: 362 return(np.dot(data,data) / 2**33) # CMSIS is 34.30 format 363 elif format == 7: 364 return(np.dot(data,data) / 2**17) # CMSIS is 18.14 format 365 else: 366 return(np.dot(data,data)) 367 368def mseTest(format,data1,data2): 369 nb = len(data1) 370 err = data1 - data2 371 return(np.dot(err,err) / nb) 372 373def rmsTest(format,data): 374 return(math.sqrt(np.dot(data,data)/data.size)) 375 376def stdTest(format,data): 377 return(np.std(data,ddof=1)) 378 379def varTest(format,data): 380 return(np.var(data,ddof=1)) 381 382def generateFuncTests(config,nb,format,data,func,name): 383 384 funcvals=[] 385 386 nbiters = Tools.loopnb(format,Tools.TAILONLY) 387 funcvalue=func(format,data[0:nbiters]) 388 funcvals.append(funcvalue) 389 390 nbiters = Tools.loopnb(format,Tools.BODYONLY) 391 funcvalue=func(format,data[0:nbiters]) 392 funcvals.append(funcvalue) 393 394 nbiters = Tools.loopnb(format,Tools.BODYANDTAIL) 395 funcvalue=func(format,data[0:nbiters]) 396 funcvals.append(funcvalue) 397 398 nbiters = 100 399 funcvalue=func(format,data[0:nbiters]) 400 funcvals.append(funcvalue) 401 402 config.writeReference(nb, funcvals,name) 403 return(nb+1) 404 405def generateOperatorTests(config,nb,format,data1,data2,func,name): 406 407 funcvals=[] 408 409 nbiters = Tools.loopnb(format,Tools.TAILONLY) 410 funcvalue=func(format,data1[0:nbiters],data2[0:nbiters]) 411 funcvals.append(funcvalue) 412 413 nbiters = Tools.loopnb(format,Tools.BODYONLY) 414 funcvalue=func(format,data1[0:nbiters],data2[0:nbiters]) 415 funcvals.append(funcvalue) 416 417 nbiters = Tools.loopnb(format,Tools.BODYANDTAIL) 418 funcvalue=func(format,data1[0:nbiters],data2[0:nbiters]) 419 funcvals.append(funcvalue) 420 421 nbiters = 100 422 funcvalue=func(format,data1[0:nbiters],data2[0:nbiters]) 423 funcvals.append(funcvalue) 424 425 config.writeReference(nb, funcvals,name) 426 return(nb+1) 427 428def generatePowerTests(config,nb,format,data): 429 430 funcvals=[] 431 432 nbiters = Tools.loopnb(format,Tools.TAILONLY) 433 funcvalue=powerTest(format,data[0:nbiters]) 434 funcvals.append(funcvalue) 435 436 nbiters = Tools.loopnb(format,Tools.BODYONLY) 437 funcvalue=powerTest(format,data[0:nbiters]) 438 funcvals.append(funcvalue) 439 440 nbiters = Tools.loopnb(format,Tools.BODYANDTAIL) 441 funcvalue=powerTest(format,data[0:nbiters]) 442 funcvals.append(funcvalue) 443 444 if format==31 or format==15: 445 config.writeReferenceQ63(nb, funcvals,"PowerVals") 446 elif format==7: 447 config.writeReferenceQ31(nb, funcvals,"PowerVals") 448 else: 449 config.writeReference(nb, funcvals,"PowerVals") 450 return(nb+1) 451 452def writeTests(config,nb,format): 453 NBSAMPLES = 300 454 data1=np.random.randn(NBSAMPLES) 455 data2=np.random.randn(NBSAMPLES) 456 457 data1 = Tools.normalize(data1) 458 data2 = np.abs(data1) 459 460 # Force quantization so that computation of indexes 461 # in min/max is coherent between Python and CMSIS. 462 # Otherwise there will be normal differences and the test 463 # will be displayed as failed. 464 if format==31: 465 data1=floatRound(data1,31) 466 467 if format==15: 468 data1=floatRound(data1,15) 469 470 if format==7: 471 data1=floatRound(data1,7) 472 473 config.writeInput(1, data1,"Input") 474 config.writeInput(2, data2,"Input") 475 476 nb=generateMaxTests(config,nb,format,data1) 477 nb=generateFuncTests(config,nb,format,data2,averageTest,"MeanVals") 478 nb=generateMinTests(config,nb,format,data1) 479 nb=generatePowerTests(config,nb,format,data1) 480 nb=generateFuncTests(config,nb,format,data1,rmsTest,"RmsVals") 481 nb=generateFuncTests(config,nb,format,data1,stdTest,"StdVals") 482 nb=generateFuncTests(config,nb,format,data1,varTest,"VarVals") 483 return(nb) 484 485# We don't want to change ID number of existing tests. 486# So new tests have to be added after existing ones 487def writeNewsTests(config,nb,format): 488 NBSAMPLES = 300 489 490 data1=np.random.randn(NBSAMPLES) 491 data1 = Tools.normalize(data1) 492 493 data2=np.random.randn(NBSAMPLES) 494 data2 = Tools.normalize(data2) 495 496 # Add max negative value 497 # to test saturation 498 if format == Tools.Q7: 499 data1 = np.hstack((data1,np.array([-1.0]))) 500 501 if format == Tools.Q15: 502 data1 = np.hstack((data1,np.array([-1.0]))) 503 504 if format == Tools.Q31: 505 data1 = np.hstack((data1,np.array([-1.0]))) 506 507 config.writeInput(1, data1,"InputNew") 508 509 nb=generateMaxAbsTests(config,nb,format,data1) 510 nb=generateMinAbsTests(config,nb,format,data1) 511 512 config.writeInput(2, data2,"InputNew") 513 nb=generateOperatorTests(config,nb,format,data1,data2,mseTest,"MSEVals") 514 515 return(nb) 516 517def writeAccumulateTests(config,nb,format): 518 NBSAMPLES = 300 519 data1=np.random.randn(NBSAMPLES) 520 521 # First value is the number of tests 522 # Other values are the number of samples in each test 523 nbsamples = [4] 524 nbiters = Tools.loopnb(format,Tools.TAILONLY) 525 nbsamples.append(nbiters) 526 527 nbiters = Tools.loopnb(format,Tools.BODYONLY) 528 nbsamples.append(nbiters) 529 530 nbiters = Tools.loopnb(format,Tools.BODYANDTAIL) 531 nbsamples.append(nbiters) 532 533 nbsamples.append(NBSAMPLES) 534 ref=[] 535 536 537 for nb in nbsamples[1:]: 538 t = np.sum(data1[:nb]) 539 ref.append(t) 540 541 config.writeInput(1, data1,"InputAccumulate") 542 config.writeInputS16(1, nbsamples,"InputAccumulateConfig") 543 config.writeReference(1, ref,"RefAccumulate") 544 545 return(nb+1) 546 547 548 549def generateBenchmark(config,format): 550 NBSAMPLES = 256 551 data1=np.random.randn(NBSAMPLES) 552 data2=np.random.randn(NBSAMPLES) 553 554 data1 = Tools.normalize(data1) 555 data2 = np.abs(data1) 556 557 if format==31: 558 data1=floatRound(data1,31) 559 560 if format==15: 561 data1=floatRound(data1,15) 562 563 if format==7: 564 data1=floatRound(data1,7) 565 566 config.writeInput(1, data1,"InputBench") 567 config.writeInput(2, data2,"InputBench") 568 569 570def generatePatterns(): 571 PATTERNDIR = os.path.join("Patterns","DSP","Stats","Stats") 572 PARAMDIR = os.path.join("Parameters","DSP","Stats","Stats") 573 574 configf64=Tools.Config(PATTERNDIR,PARAMDIR,"f64") 575 configf32=Tools.Config(PATTERNDIR,PARAMDIR,"f32") 576 configf16=Tools.Config(PATTERNDIR,PARAMDIR,"f16") 577 configq31=Tools.Config(PATTERNDIR,PARAMDIR,"q31") 578 configq15=Tools.Config(PATTERNDIR,PARAMDIR,"q15") 579 configq7 =Tools.Config(PATTERNDIR,PARAMDIR,"q7") 580 581 configf64.setOverwrite(False) 582 configf32.setOverwrite(False) 583 configf16.setOverwrite(False) 584 configq31.setOverwrite(False) 585 configq15.setOverwrite(False) 586 configq7.setOverwrite(False) 587 588 nb=writeTests(configf32,1,0) 589 nb=writeF32OnlyTests(configf32,22) 590 nb=writeNewsTests(configf32,nb,Tools.F32) 591 nb=writeAccumulateTests(configf32,nb,Tools.F32) 592 593 nb=writeTests(configf64,1,Tools.F64) 594 nb=writeF64OnlyTests(configf64,22) 595 nb=writeNewsTests(configf64,nb,Tools.F64) 596 nb=writeAccumulateTests(configf64,nb,Tools.F64) 597 598 nb=writeTests(configq31,1,31) 599 nb=writeNewsTests(configq31,nb,Tools.Q31) 600 601 nb=writeTests(configq15,1,15) 602 nb=writeNewsTests(configq15,nb,Tools.Q15) 603 604 nb=writeTests(configq7,1,7) 605 nb=writeNewsTests(configq7,nb,Tools.Q7) 606 607 nb=writeTests(configf16,1,16) 608 nb=writeF16OnlyTests(configf16,22) 609 nb=writeNewsTests(configf16,nb,Tools.F16) 610 nb=writeAccumulateTests(configf16,nb,Tools.F16) 611 612 generateBenchmark(configf64, Tools.F64) 613 generateBenchmark(configf32, Tools.F32) 614 generateBenchmark(configf16, Tools.F16) 615 generateBenchmark(configq31, Tools.Q31) 616 generateBenchmark(configq15, Tools.Q15) 617 generateBenchmark(configq7, Tools.Q7) 618 619if __name__ == '__main__': 620 generatePatterns() 621