test2DMatrixMultiplication.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  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 i4swizzle = i4.swizzle;
  14. var i4check = i4.check;
  15. var f4 = stdlib.SIMD.Float32x4;
  16. var f4equal = f4.equal;
  17. var f4lessThan = f4.lessThan;
  18. var f4splat = f4.splat;
  19. var f4store = f4.store;
  20. var f4load = f4.load;
  21. var f4check = f4.check;
  22. var f4abs = f4.abs;
  23. var f4add = f4.add;
  24. var f4sub = f4.sub;
  25. var Float32Heap = new stdlib.Float32Array(buffer);
  26. var Int32Heap = new stdlib.Int32Array(buffer);
  27. var BLOCK_SIZE = 4;
  28. function matrixMultiplication(aIndex, bIndex, cIndex) {
  29. aIndex = aIndex | 0;
  30. bIndex = bIndex | 0;
  31. cIndex = cIndex | 0;
  32. var i = 0, j = 0, dim1 = 0, dim2 = 0, intersectionNum = 0, matrixSize = 0;
  33. var newPiece = f4(0.0, 0.0, 0.0, 0.0), cPiece = f4(0.0, 0.0, 0.0, 0.0);
  34. //array dimensions don't match
  35. if ((Int32Heap[aIndex + 1 << 2 >> 2] | 0) != (Int32Heap[bIndex << 2 >> 2] | 0)) {
  36. return -1;
  37. }
  38. dim1 = Int32Heap[aIndex << 2 >> 2] | 0;
  39. dim2 = Int32Heap[bIndex + 1 << 2 >> 2] | 0;
  40. intersectionNum = Int32Heap[bIndex << 2 >> 2] | 0;
  41. matrixSize = imul(dim1, dim2);
  42. Int32Heap[cIndex << 2 >> 2] = dim1;
  43. Int32Heap[cIndex + 1 << 2 >> 2] = dim2;
  44. while ((i|0) < (matrixSize|0)) {
  45. cPiece = f4(0.0, 0.0, 0.0, 0.0);
  46. j = 0;
  47. while ((j|0) < (intersectionNum|0)) {
  48. newPiece = f4(toF(getIntersectionPiece(aIndex, bIndex, dim2, i, 0, j)),
  49. toF(getIntersectionPiece(aIndex, bIndex, dim2, i, 1, j)),
  50. toF(getIntersectionPiece(aIndex, bIndex, dim2, i, 2, j)),
  51. toF(getIntersectionPiece(aIndex, bIndex, dim2, i, 3, j)));
  52. cPiece = f4add(cPiece, newPiece);
  53. j = (j + 1)|0;
  54. }
  55. f4store(Float32Heap, cIndex + 2 + i << 2 >> 2, cPiece);
  56. i = (i + BLOCK_SIZE)|0;
  57. }
  58. return 0;
  59. }
  60. function getIntersectionPiece(aIndex, bIndex, dim2, resultBlock, resultIndex, intersectionNum) {
  61. aIndex = aIndex | 0;
  62. bIndex = bIndex | 0;
  63. dim2 = dim2 | 0;
  64. resultBlock = resultBlock | 0;
  65. resultIndex = resultIndex | 0;
  66. intersectionNum = intersectionNum | 0;
  67. var aElem = 0.0, bElem = 0.0, cElem = 0.0;
  68. aElem = +toF(getElement(aIndex, ((resultBlock | 0) / (dim2 | 0))|0, intersectionNum));
  69. bElem = +toF(getElement(bIndex, intersectionNum, (resultBlock + resultIndex)|0));
  70. //return toF(getElement(aIndex, ((resultBlock|0) / (dim2|0)), intersectionNum));
  71. return toF(aElem * bElem);
  72. }
  73. function getElement(start, row, column) {
  74. start = start | 0;
  75. row = row | 0;
  76. column = column | 0;
  77. var dim1 = 0, dim2 = 0;
  78. dim2 = Int32Heap[start << 2 >> 2] | 0;
  79. dim1 = Int32Heap[start + 1 << 2 >> 2] | 0;
  80. //return toF(Float32Heap[(602 + imul(row, dim1) + column) << 2 >> 2]);
  81. return toF(Float32Heap[(start + 2 + imul(row, dim1) + column) << 2 >> 2]);
  82. }
  83. function new2DMatrix(startIndex, dim1, dim2) {
  84. startIndex = startIndex | 0;
  85. dim1 = dim1 | 0;
  86. dim2 = dim2 | 0;
  87. var i = 0, matrixSize = 0;
  88. matrixSize = imul(dim1, dim2);
  89. Int32Heap[startIndex << 2 >> 2] = dim1;
  90. Int32Heap[startIndex + 1 << 2 >> 2] = dim2;
  91. for (i = 0; (i|0) < ((matrixSize - BLOCK_SIZE)|0); i = (i + BLOCK_SIZE)|0) {
  92. f4store(Float32Heap, startIndex + 2 + i << 2 >> 2, f4(toF((i + 1)|0), toF((i + 2)|0), toF((i + 3)|0), toF((i + 4)|0)));
  93. }
  94. for (; (i|0) < (matrixSize|0); i = (i + 1)|0) {
  95. Float32Heap[(startIndex + 2 + i) << 2 >> 2] = toF((i + 1)|0);
  96. }
  97. return (startIndex + 2 + i) | 0;
  98. }
  99. return {
  100. new2DMatrix: new2DMatrix,
  101. matrixMultiplication: matrixMultiplication
  102. };
  103. }
  104. function verify_results(type, results_ex, buffer, count)
  105. {
  106. var i4;
  107. for (var i = 0, idx = 0; i < count/* * 16*/; i += 4)
  108. {
  109. i4 = type.load(buffer, i);
  110. equalSimd(results_ex[idx++], i4, type, "Matrix Mul" );
  111. }
  112. }
  113. var buffer = new ArrayBuffer(16 * 1024 * 1024);
  114. var m = asmModule(this, null, buffer);
  115. m.new2DMatrix(0, 4, 8);
  116. m.new2DMatrix(200, 8, 12);
  117. m.new2DMatrix(400, 4, 4);
  118. m.new2DMatrix(600, 4, 4);
  119. m.matrixMultiplication(0, 200, 800);
  120. m.matrixMultiplication(400, 600, 1000);
  121. exp_results1 = [
  122. SIMD.Float32x4(2052,2088,2124,2160),
  123. SIMD.Float32x4(2196,2232,2268,2304),
  124. SIMD.Float32x4(2340,2376,2412,2448),
  125. SIMD.Float32x4(4452,4536,4620,4704),
  126. SIMD.Float32x4(4788,4872,4956,5040),
  127. SIMD.Float32x4(5124,5208,5292,5376),
  128. SIMD.Float32x4(6645,6762,6879,6996),
  129. SIMD.Float32x4(7113,7230,7347,7464),
  130. SIMD.Float32x4(7581,7698,7815,7932),
  131. SIMD.Float32x4(8355,8490,8625,8760),
  132. SIMD.Float32x4(8895,9030,9165,9300),
  133. SIMD.Float32x4(9435,9570,9705,9840),
  134. ];
  135. exp_results2 = [
  136. SIMD.Float32x4(90,100,110,120),
  137. SIMD.Float32x4(170,188,206,224),
  138. SIMD.Float32x4(211,230,249,268),
  139. SIMD.Float32x4(169,182,195,208),
  140. ];
  141. var values = new Float32Array(buffer);
  142. verify_results(SIMD.Float32x4, exp_results1, values.subarray(800 + 2), 12 * 4);
  143. verify_results(SIMD.Float32x4, exp_results2, values.subarray(1000 + 2), 4 * 4);
  144. print("PASS");