| 78 | } |
| 79 | |
| 80 | int main(int argc, char **argv) |
| 81 | { |
| 82 | size_t M = 4; |
| 83 | size_t N = 4; |
| 84 | size_t K = 4; |
| 85 | |
| 86 | // Parse args |
| 87 | if (argc < 3) /* case default matrix sizes */ |
| 88 | { |
| 89 | // Print help |
| 90 | std::cout << "Usage: ./build/neon_gemm_qasymm8 M N K\n"; |
| 91 | std::cout << "Too few or no inputs provided. Using default M=4, N=4, K=4\n\n"; |
| 92 | } |
| 93 | else /* case M N K arguments provided */ |
| 94 | { |
| 95 | M = strtol(argv[1], nullptr, 10); |
| 96 | N = strtol(argv[2], nullptr, 10); |
| 97 | K = strtol(argv[3], nullptr, 10); |
| 98 | } |
| 99 | |
| 100 | /*** Floating point matrix multiplication ***/ |
| 101 | |
| 102 | // Initialise input matrices |
| 103 | NEGEMM fgemm{}; |
| 104 | |
| 105 | Tensor src1; |
| 106 | Tensor src2; |
| 107 | Tensor dst; |
| 108 | src1.allocator()->init(TensorInfo(TensorShape(K, M), 1, DataType::F32)); |
| 109 | src2.allocator()->init(TensorInfo(TensorShape(N, K), 1, DataType::F32)); |
| 110 | dst.allocator()->init(TensorInfo(TensorShape(N, M), 1, DataType::F32)); |
| 111 | fgemm.configure(&src1, &src2, nullptr, &dst, 1, 0); |
| 112 | |
| 113 | // Allocate matrices |
| 114 | src1.allocator()->allocate(); |
| 115 | src2.allocator()->allocate(); |
| 116 | dst.allocator()->allocate(); |
| 117 | |
| 118 | float min1 = 0.0f; |
| 119 | float max1 = 1.0f; |
| 120 | fill_random_tensor(src1, 0, min1, max1); |
| 121 | |
| 122 | float min2 = -1.0f; |
| 123 | float max2 = 2.0f; |
| 124 | fill_random_tensor(src2, 1, min2, max2); |
| 125 | |
| 126 | // Run single precision gemm and print result |
| 127 | fgemm.run(); |
| 128 | |
| 129 | #if ARM_COMPUTE_DEBUG_ENABLED |
| 130 | std::cout << "# F32 GEMM result:\n"; |
| 131 | std::cout << "src1=[ \n"; |
| 132 | src1.print(std::cout); |
| 133 | std::cout << "] \n"; |
| 134 | std::cout << "src2=[ \n"; |
| 135 | src2.print(std::cout); |
| 136 | std::cout << "] \n"; |
| 137 | std::cout << "dst=[ \n"; |
nothing calls this directly
no test coverage detected