test2DMatrixMultiplication.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. this.WScript.LoadScriptFile("..\\UnitTestFramework\\SimdJsHelpers.js");
  6. function asmModule(stdlib, imports, buffer) {
  7. "use asm";
  8. var log = stdlib.Math.log;
  9. var toF = stdlib.Math.fround;
  10. var imul = stdlib.Math.imul;
  11. var i4 = stdlib.SIMD.Int32x4;
  12. var i4store = i4.store;
  13. var i4load = i4.load
  14. var i4swizzle = i4.swizzle;
  15. var i4check = i4.check;
  16. var i4add = i4.add;
  17. var i4sub = i4.sub;
  18. var i4lessThan = i4.lessThan;
  19. var i4splat = i4.splat;
  20. var f4 = stdlib.SIMD.Float32x4;
  21. var f4equal = f4.equal;
  22. var f4lessThan = f4.lessThan;
  23. var f4splat = f4.splat;
  24. var f4store = f4.store;
  25. var f4load = f4.load;
  26. var f4check = f4.check;
  27. var f4abs = f4.abs;
  28. var f4add = f4.add;
  29. var f4sub = f4.sub;
  30. var Float32Heap = new stdlib.Float32Array(buffer);
  31. var Int32Heap = new stdlib.Int32Array(buffer);
  32. var BLOCK_SIZE = 4;
  33. function matrixMultiplication(aIndex, bIndex, cIndex) {
  34. aIndex = aIndex|0;
  35. bIndex = bIndex|0;
  36. cIndex = cIndex|0;
  37. var i = 0, j = 0, dim1 = 0, dim2 = 0, intersectionNum = 0, matrixSize = 0;
  38. var newPiece = i4(0, 0, 0, 0), cPiece = i4(0, 0, 0, 0);
  39. //array dimensions don't match
  40. if((Int32Heap[aIndex + 1 << 2 >> 2]|0) != (Int32Heap[bIndex << 2 >> 2]|0)) {
  41. return -1;
  42. }
  43. dim1 = Int32Heap[aIndex << 2 >> 2]|0;
  44. dim2 = Int32Heap[bIndex + 1 << 2 >> 2]|0;
  45. intersectionNum = Int32Heap[bIndex << 2 >> 2]|0;
  46. matrixSize = imul(dim1, dim2);
  47. Int32Heap[cIndex << 2 >> 2] = dim1;
  48. Int32Heap[cIndex + 1 << 2 >> 2] = dim2;
  49. while((i|0) < (matrixSize|0)) {
  50. cPiece = i4(0, 0, 0, 0);
  51. j = 0;
  52. while( (j|0) < (intersectionNum|0)) {
  53. newPiece = i4((getIntersectionPiece(aIndex, bIndex, dim2, i, 0, j)|0),
  54. (getIntersectionPiece(aIndex, bIndex, dim2, i, 1, j)|0),
  55. (getIntersectionPiece(aIndex, bIndex, dim2, i, 2, j)|0),
  56. (getIntersectionPiece(aIndex, bIndex, dim2, i, 3, j)|0));
  57. cPiece = i4add(cPiece, newPiece);
  58. j = (j + 1)|0;
  59. }
  60. i4store(Int32Heap, cIndex + 2 + i << 2 >> 2, cPiece);
  61. i = (i + BLOCK_SIZE)|0;
  62. }
  63. return 0;
  64. }
  65. function getIntersectionPiece(aIndex, bIndex, dim2, resultBlock, resultIndex, intersectionNum) {
  66. aIndex = aIndex|0;
  67. bIndex = bIndex|0;
  68. dim2 = dim2|0;
  69. resultBlock = resultBlock|0;
  70. resultIndex = resultIndex|0;
  71. intersectionNum = intersectionNum|0;
  72. var aElem = 0, bElem = 0, cElem = 0;
  73. aElem = (getElement(aIndex, ((resultBlock|0) / (dim2|0))|0, intersectionNum))|0;
  74. bElem = (getElement(bIndex, intersectionNum, (resultBlock + resultIndex)|0))|0;
  75. return (aElem * bElem)|0;
  76. }
  77. function getElement(start, row, column) {
  78. start = start|0;
  79. row = row|0;
  80. column = column|0;
  81. var dim1 = 0, dim2 = 0;
  82. dim2 = Int32Heap[start << 2 >> 2]|0;
  83. dim1 = Int32Heap[start + 1 << 2 >> 2]|0;
  84. return (Int32Heap[(start + 2 + imul(row, dim1) + column) << 2 >> 2])|0;
  85. }
  86. function new2DMatrix(startIndex, dim1, dim2) {
  87. startIndex = startIndex|0;
  88. dim1 = dim1|0;
  89. dim2 = dim2|0;
  90. var i = 0, matrixSize = 0;
  91. matrixSize = imul(dim1, dim2);
  92. Int32Heap[startIndex << 2 >> 2] = dim1;
  93. Int32Heap[startIndex + 1 << 2 >> 2] = dim2;
  94. for(i = 0; (i|0) < ((matrixSize - BLOCK_SIZE)|0); i = (i + BLOCK_SIZE)|0) {
  95. i4store(Int32Heap, startIndex + 2 + i << 2 >> 2, i4((i+1), (i+2), (i+3), (i+4)));
  96. }
  97. for(; (i|0) < (matrixSize|0); i = (i + 1)|0) {
  98. Int32Heap[(startIndex + 2 + i) << 2 >> 2] = (i+1)|0;
  99. }
  100. return (startIndex + 2 + i)|0;
  101. }
  102. return {new2DMatrix: new2DMatrix,
  103. matrixMultiplication:matrixMultiplication};
  104. }
  105. ////////////////////////////////////////////////////////////////
  106. //Call GEN_BASELINE() to generate baseline data and initialize RESULTS with it.
  107. ///////////////////////////////////////////////////////////////
  108. function GEN_BASELINE(buffer, start) {
  109. var IntHeap32 = new Int32Array(buffer);
  110. var FloatHeap32 = new Float32Array(buffer);
  111. var i4;
  112. var dim1 = IntHeap32[start];
  113. var dim2 = IntHeap32[start + 1];
  114. print("[");
  115. for (var i = 0; i < Math.imul(dim1, dim2) ; i += 4) {
  116. i4 = SIMD.Int32x4.load(IntHeap32, i + start + 2);
  117. print(i4.toString()+",");
  118. }
  119. print("]");
  120. }
  121. function verify2DMatrix(buffer, start, results) {
  122. var IntHeap32 = new Int32Array(buffer);
  123. var FloatHeap32 = new Float32Array(buffer);
  124. var i4;
  125. var dim1 = IntHeap32[start];
  126. var dim2 = IntHeap32[start + 1];
  127. for (var i = 0, rslt_idx = 0; i < Math.imul(dim1, dim2) ; i += 4) {
  128. i4 = SIMD.Int32x4.load(IntHeap32, i + start + 2);
  129. equalSimd(results[rslt_idx++], i4, SIMD.Int32x4, "2d Matrix Addition");
  130. }
  131. }
  132. var buffer = new ArrayBuffer(16 * 1024 * 1024);
  133. var m = asmModule(this, null, buffer);
  134. print("2D Matrix Multiplication");
  135. m.new2DMatrix(0, 4, 8);
  136. m.new2DMatrix(200, 8, 12);
  137. m.new2DMatrix(400, 4, 4);
  138. m.new2DMatrix(600, 4, 4);
  139. m.matrixMultiplication(0, 200, 800);
  140. m.matrixMultiplication(400, 600, 1000);
  141. // GEN_BASELINE(buffer, 800);
  142. var RESULTS =[
  143. SIMD.Int32x4(2052, 2088, 2124, 2160),
  144. SIMD.Int32x4(2196, 2232, 2268, 2304),
  145. SIMD.Int32x4(2340, 2376, 2412, 2448),
  146. SIMD.Int32x4(4452, 4536, 4620, 4704),
  147. SIMD.Int32x4(4788, 4872, 4956, 5040),
  148. SIMD.Int32x4(5124, 5208, 5292, 5376),
  149. SIMD.Int32x4(6645, 6762, 6879, 6996),
  150. SIMD.Int32x4(7113, 7230, 7347, 7464),
  151. SIMD.Int32x4(7581, 7698, 7815, 7932),
  152. SIMD.Int32x4(8355, 8490, 8625, 8760),
  153. SIMD.Int32x4(8895, 9030, 9165, 9300),
  154. SIMD.Int32x4(9435, 9570, 9705, 9840),
  155. ];
  156. verify2DMatrix(buffer, 800, RESULTS);
  157. // GEN_BASELINE(buffer, 1000);
  158. var RESULTS =[
  159. SIMD.Int32x4(90, 100, 110, 120),
  160. SIMD.Int32x4(170, 188, 206, 224),
  161. SIMD.Int32x4(211, 230, 249, 268),
  162. SIMD.Int32x4(169, 182, 195, 208),
  163. ]
  164. verify2DMatrix(buffer, 1000, RESULTS);
  165. print("PASS");