| 126 | } |
| 127 | |
| 128 | void test_matmul() { |
| 129 | assert(float8e5m2_to_float(float_to_float8e5m2(1.0f)) == 1.0f); |
| 130 | assert(float8e5m2_to_float(float_to_float8e5m2(-1.5f)) == -1.5f); |
| 131 | assert(float8e5m2_to_float(float_to_float8e5m2(0.109375)) == 0.109375); |
| 132 | std::vector<float> x{ |
| 133 | 2.0624e-01, 1.6975e+00, 8.4918e-01, -1.7186e-01, |
| 134 | -9.0164e-01, 6.1108e-01, 2.2116e-01, 1.0412e+00, |
| 135 | -1.6616e-03, 8.2840e-01, 2.2667e-01, -1.3993e+00, |
| 136 | 4.1013e-01, -1.2223e+00, 2.2723e-01, 6.3558e-01 |
| 137 | }; |
| 138 | std::vector<float> w_f32{ |
| 139 | // row 1 |
| 140 | -1.1210, -0.0235, -1.3527, 0.6300, 0.2566, -0.4517, -0.3528, 0.4422, |
| 141 | -0.4032, -1.0949, -0.7834, 1.1425, 0.6263, -0.3680, 0.3226, -0.2984, |
| 142 | // row 2 |
| 143 | 0.1176, -1.1462, -0.8181, -2.0047, 0.0932, 1.4665, -0.8682, -0.8490, |
| 144 | -1.3017, -1.0068, -0.2890, 0.0167, 1.1607, 0.7196, 1.7701, 0.2891 |
| 145 | }; |
| 146 | std::vector<f16_t> w_f16 = float_array_to_half(w_f32); |
| 147 | std::vector<f8e5m2_t> w_f8e5m2 = float_array_to_float8e5m2(w_f32); |
| 148 | { |
| 149 | std::vector<float> xout(2); |
| 150 | matmul_unscaled(xout.data(), x.data(), {Quant::F32, {16, 2}, w_f32.data(), 16*2*sizeof(float)}); |
| 151 | assertArrayEquals(xout, { |
| 152 | -3.7454, -3.2738 |
| 153 | }, "matmul_f32", 1e-4); |
| 154 | } |
| 155 | { |
| 156 | std::vector<float> xout(2); |
| 157 | matmul_unscaled(xout.data(), x.data(), {Quant::F16, {16, 2}, w_f16.data(), 16*2*sizeof(f16_t)}); |
| 158 | assertArrayEquals(xout, { |
| 159 | -3.7454, -3.2738 |
| 160 | }, "matmul_f16", 1e-3); |
| 161 | } |
| 162 | { |
| 163 | std::vector<float> xout(2); |
| 164 | matmul_unscaled(xout.data(), x.data(), {Quant::F8E5M2, {16, 2}, w_f8e5m2.data(), 16*2*sizeof(f8e5m2_t)}); |
| 165 | assertArrayEquals(xout, { |
| 166 | -3.7454, -3.2738 |
| 167 | }, "matmul_f8e5m2", 3.78e-1); |
| 168 | std::vector<float> xout_roundtrip(2); |
| 169 | std::vector<float> w8_roundtrip; |
| 170 | for (size_t i = 0; i < w_f8e5m2.size(); i++) { |
| 171 | w8_roundtrip.push_back(float8e5m2_to_float(w_f8e5m2[i])); |
| 172 | } |
| 173 | matmul_unscaled(xout_roundtrip.data(), x.data(), {Quant::F8E5M2, {16, 2}, w8_roundtrip.data(), 16*2*sizeof(f8e5m2_t)}); |
| 174 | assertArrayEquals(xout_roundtrip, xout, "matmul_f8e5m2_roundtrip"); |
| 175 | } |
| 176 | std::vector<float> x8_roundtrip; |
| 177 | for (size_t i = 0; i < x.size(); i++) { |
| 178 | x8_roundtrip.push_back(float8e5m2_to_float(float_to_float8e5m2(x[i]))); |
| 179 | } |
| 180 | assertArrayEquals(x8_roundtrip, { |
| 181 | 2.1875e-01, 1.7500e+00, 8.7500e-01, -1.5625e-01, |
| 182 | -8.7500e-01, 6.2500e-01, 2.1875e-01, 1.0000e+00, |
| 183 | -1.7090e-03, 8.7500e-01, 2.1875e-01, -1.5000e+00, |
| 184 | 4.3750e-01, -1.2500e+00, 2.1875e-01, 6.2500e-01 |
| 185 | }, "x_float8e5m2_roundtrip"); |
no test coverage detected