199 lines · plain
1// RUN: mlir-opt %s -convert-vector-to-scf -lower-affine -convert-scf-to-cf -convert-vector-to-llvm="enable-amx" -finalize-memref-to-llvm -convert-func-to-llvm -reconcile-unrealized-casts | \2// RUN: mlir-translate -mlir-to-llvmir | \3// RUN: %lli --entry-function=entry --mattr="+amx-tile,+amx-int8,+amx-bf16" --dlopen=%mlir_c_runner_utils | \4// RUN: FileCheck %s5 6// Note: To run this test, your CPU must support AMX.7 8func.func @print(%arg0: memref<16x4xi32>) {9 %iu = arith.constant -1: i3210 %c0 = arith.constant 0: index11 %c1 = arith.constant 1: index12 %c16 = arith.constant 16: index13 scf.for %i = %c0 to %c16 step %c1 {14 %0 = vector.transfer_read %arg0[%i, %c0], %iu: memref<16x4xi32>, vector<4xi32>15 vector.print %0 : vector<4xi32>16 }17 return18}19 20func.func @kernel1(%arg0: memref<16x16xi8>,21 %arg1: memref<4x16xi8>,22 %arg2: memref<16x4xi32>) {23 %0 = arith.constant 0 : index24 %1 = amx.tile_load %arg0[%0, %0] : memref<16x16xi8> into vector<16x16xi8>25 %2 = amx.tile_load %arg1[%0, %0] : memref<4x16xi8> into vector<4x16xi8>26 %3 = amx.tile_zero : vector<16x4xi32>27 %4 = amx.tile_muli %1, %2, %3 : vector<16x16xi8>, vector<4x16xi8>, vector<16x4xi32>28 amx.tile_store %arg2[%0, %0], %4 : memref<16x4xi32>, vector<16x4xi32>29 return30}31 32func.func @kernel2(%arg0: memref<16x16xi8>,33 %arg1: memref<4x16xi8>,34 %arg2: memref<16x4xi32>) {35 %0 = arith.constant 0 : index36 %1 = amx.tile_load %arg0[%0, %0] : memref<16x16xi8> into vector<16x16xi8>37 %2 = amx.tile_load %arg1[%0, %0] : memref<4x16xi8> into vector<4x16xi8>38 %3 = amx.tile_zero : vector<16x4xi32>39 %4 = amx.tile_muli %1, %2 zext, %3 : vector<16x16xi8>, vector<4x16xi8>, vector<16x4xi32>40 amx.tile_store %arg2[%0, %0], %4 : memref<16x4xi32>, vector<16x4xi32>41 return42}43 44func.func @kernel3(%arg0: memref<16x16xi8>,45 %arg1: memref<4x16xi8>,46 %arg2: memref<16x4xi32>) {47 %0 = arith.constant 0 : index48 %1 = amx.tile_load %arg0[%0, %0] : memref<16x16xi8> into vector<16x16xi8>49 %2 = amx.tile_load %arg1[%0, %0] : memref<4x16xi8> into vector<4x16xi8>50 %3 = amx.tile_zero : vector<16x4xi32>51 %4 = amx.tile_muli %1 zext, %2, %3 : vector<16x16xi8>, vector<4x16xi8>, vector<16x4xi32>52 amx.tile_store %arg2[%0, %0], %4 : memref<16x4xi32>, vector<16x4xi32>53 return54}55 56func.func @kernel4(%arg0: memref<16x16xi8>,57 %arg1: memref<4x16xi8>,58 %arg2: memref<16x4xi32>) {59 %0 = arith.constant 0 : index60 %1 = amx.tile_load %arg0[%0, %0] : memref<16x16xi8> into vector<16x16xi8>61 %2 = amx.tile_load %arg1[%0, %0] : memref<4x16xi8> into vector<4x16xi8>62 %3 = amx.tile_zero : vector<16x4xi32>63 %4 = amx.tile_muli %1 zext, %2 zext, %3 : vector<16x16xi8>, vector<4x16xi8>, vector<16x4xi32>64 amx.tile_store %arg2[%0, %0], %4 : memref<16x4xi32>, vector<16x4xi32>65 return66}67 68func.func @entry() -> i32 {69 %c0 = arith.constant 0: index70 71 // Set up memory.72 %a = memref.alloc() : memref<16x16xi8>73 %b = memref.alloc() : memref<4x16xi8>74 %c = memref.alloc() : memref<16x4xi32>75 76 %0 = arith.constant dense<77 [ [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ],78 [ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 ],79 [ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47 ],80 [ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63 ],81 [ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79 ],82 [ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95 ],83 [ 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111 ],84 [112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127 ],85 [128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143 ],86 [144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159 ],87 [160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175 ],88 [176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191 ],89 [192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207 ],90 [208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223 ],91 [224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239 ],92 [240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 ] ]> : vector<16x16xi8>93 94 %1 = arith.constant dense<95 [ [192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207 ],96 [208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223 ],97 [224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239 ],98 [240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 ] ]> : vector<4x16xi8>99 100 vector.transfer_write %0, %a[%c0, %c0] : vector<16x16xi8>, memref<16x16xi8>101 vector.transfer_write %1, %b[%c0, %c0] : vector<4x16xi8>, memref<4x16xi8>102 103 // Call kernel1 and verify result.104 //105 // CHECK: ( -3320, -2840, -2360, -1880 )106 // CHECK-NEXT: ( -13176, -11672, -10168, -8664 )107 // CHECK-NEXT: ( -23032, -20504, -17976, -15448 )108 // CHECK-NEXT: ( -32888, -29336, -25784, -22232 )109 // CHECK-NEXT: ( -42744, -38168, -33592, -29016 )110 // CHECK-NEXT: ( -52600, -47000, -41400, -35800 )111 // CHECK-NEXT: ( -62456, -55832, -49208, -42584 )112 // CHECK-NEXT: ( -72312, -64664, -57016, -49368 )113 // CHECK-NEXT: ( 75528, 67816, 60104, 52392 )114 // CHECK-NEXT: ( 65672, 58984, 52296, 45608 )115 // CHECK-NEXT: ( 55816, 50152, 44488, 38824 )116 // CHECK-NEXT: ( 45960, 41320, 36680, 32040 )117 // CHECK-NEXT: ( 36104, 32488, 28872, 25256 )118 // CHECK-NEXT: ( 26248, 23656, 21064, 18472 )119 // CHECK-NEXT: ( 16392, 14824, 13256, 11688 )120 // CHECK-NEXT: ( 6536, 5992, 5448, 4904 )121 //122 call @kernel1(%a, %b, %c) : (memref<16x16xi8>, memref<4x16xi8>, memref<16x4xi32>) -> ()123 call @print(%c) : (memref<16x4xi32>) -> ()124 125 // Call kernel2 and verify result.126 //127 // CHECK-NEXT: ( 27400, 27880, 28360, 28840 )128 // CHECK-NEXT: ( 83080, 84584, 86088, 87592 )129 // CHECK-NEXT: ( 138760, 141288, 143816, 146344 )130 // CHECK-NEXT: ( 194440, 197992, 201544, 205096 )131 // CHECK-NEXT: ( 250120, 254696, 259272, 263848 )132 // CHECK-NEXT: ( 305800, 311400, 317000, 322600 )133 // CHECK-NEXT: ( 361480, 368104, 374728, 381352 )134 // CHECK-NEXT: ( 417160, 424808, 432456, 440104 )135 // CHECK-NEXT: ( -418040, -425752, -433464, -441176 )136 // CHECK-NEXT: ( -362360, -369048, -375736, -382424 )137 // CHECK-NEXT: ( -306680, -312344, -318008, -323672 )138 // CHECK-NEXT: ( -251000, -255640, -260280, -264920 )139 // CHECK-NEXT: ( -195320, -198936, -202552, -206168 )140 // CHECK-NEXT: ( -139640, -142232, -144824, -147416 )141 // CHECK-NEXT: ( -83960, -85528, -87096, -88664 )142 // CHECK-NEXT: ( -28280, -28824, -29368, -29912 )143 //144 call @kernel2(%a, %b, %c) : (memref<16x16xi8>, memref<4x16xi8>, memref<16x4xi32>) -> ()145 call @print(%c) : (memref<16x4xi32>) -> ()146 147 // Call kernel3 and verify result.148 //149 // CHECK-NEXT: ( -3320, -2840, -2360, -1880 )150 // CHECK-NEXT: ( -13176, -11672, -10168, -8664 )151 // CHECK-NEXT: ( -23032, -20504, -17976, -15448 )152 // CHECK-NEXT: ( -32888, -29336, -25784, -22232 )153 // CHECK-NEXT: ( -42744, -38168, -33592, -29016 )154 // CHECK-NEXT: ( -52600, -47000, -41400, -35800 )155 // CHECK-NEXT: ( -62456, -55832, -49208, -42584 )156 // CHECK-NEXT: ( -72312, -64664, -57016, -49368 )157 // CHECK-NEXT: ( -82168, -73496, -64824, -56152 )158 // CHECK-NEXT: ( -92024, -82328, -72632, -62936 )159 // CHECK-NEXT: ( -101880, -91160, -80440, -69720 )160 // CHECK-NEXT: ( -111736, -99992, -88248, -76504 )161 // CHECK-NEXT: ( -121592, -108824, -96056, -83288 )162 // CHECK-NEXT: ( -131448, -117656, -103864, -90072 )163 // CHECK-NEXT: ( -141304, -126488, -111672, -96856 )164 // CHECK-NEXT: ( -151160, -135320, -119480, -103640 )165 //166 call @kernel3(%a, %b, %c) : (memref<16x16xi8>, memref<4x16xi8>, memref<16x4xi32>) -> ()167 call @print(%c) : (memref<16x4xi32>) -> ()168 169 // Call kernel4 and verify result.170 //171 // CHECK-NEXT: ( 27400, 27880, 28360, 28840 )172 // CHECK-NEXT: ( 83080, 84584, 86088, 87592 )173 // CHECK-NEXT: ( 138760, 141288, 143816, 146344 )174 // CHECK-NEXT: ( 194440, 197992, 201544, 205096 )175 // CHECK-NEXT: ( 250120, 254696, 259272, 263848 )176 // CHECK-NEXT: ( 305800, 311400, 317000, 322600 )177 // CHECK-NEXT: ( 361480, 368104, 374728, 381352 )178 // CHECK-NEXT: ( 417160, 424808, 432456, 440104 )179 // CHECK-NEXT: ( 472840, 481512, 490184, 498856 )180 // CHECK-NEXT: ( 528520, 538216, 547912, 557608 )181 // CHECK-NEXT: ( 584200, 594920, 605640, 616360 )182 // CHECK-NEXT: ( 639880, 651624, 663368, 675112 )183 // CHECK-NEXT: ( 695560, 708328, 721096, 733864 )184 // CHECK-NEXT: ( 751240, 765032, 778824, 792616 )185 // CHECK-NEXT: ( 806920, 821736, 836552, 851368 )186 // CHECK-NEXT: ( 862600, 878440, 894280, 910120 )187 //188 call @kernel4(%a, %b, %c) : (memref<16x16xi8>, memref<4x16xi8>, memref<16x4xi32>) -> ()189 call @print(%c) : (memref<16x4xi32>) -> ()190 191 // Release resources.192 memref.dealloc %a : memref<16x16xi8>193 memref.dealloc %b : memref<4x16xi8>194 memref.dealloc %c : memref<16x4xi32>195 196 %i0 = arith.constant 0 : i32197 return %i0 : i32198}199