| 15 | namespace test { |
| 16 | namespace { |
| 17 | void test_multibatchsize( |
| 18 | Handle* handle_cuda, DType A_dtype, DType B_dtype, DType C_dtype, |
| 19 | const char* algo, const std::vector<matrix_mul::TestArg>& args, |
| 20 | param::MatrixMul::Format format = param::MatrixMul::Format::DEFAULT, |
| 21 | const std::function<bool(const matrix_mul::TestArg&)>& filter = {}) { |
| 22 | Checker<MatrixMulForward> checker(handle_cuda, false); |
| 23 | if (algo) { |
| 24 | checker.set_before_exec_callback(AlgoChecker<MatrixMulForward>(algo)); |
| 25 | } |
| 26 | std::unique_ptr<RNG> rng; |
| 27 | if (A_dtype.enumv() == DTypeEnum::Float32) { |
| 28 | rng = std::make_unique<UniformFloatRNG>(-1, 1); |
| 29 | megdnn_assert( |
| 30 | B_dtype.enumv() == DTypeEnum::Float32 && |
| 31 | C_dtype.enumv() == DTypeEnum::Float32); |
| 32 | } |
| 33 | megdnn_assert(rng != nullptr); |
| 34 | |
| 35 | struct Compare { |
| 36 | bool is_same(dt_float32 expected, dt_float32 actual) const { |
| 37 | return expected == actual; |
| 38 | } |
| 39 | }; |
| 40 | |
| 41 | // copy rhs->lhs, lhs is 8 times of rhs |
| 42 | auto copy = [](SyncedTensor<dt_float32, Compare>& lhs, |
| 43 | SyncedTensor<dt_float32, Compare>& rhs) { |
| 44 | size_t chunk = rhs.layout().span().dist_byte(); |
| 45 | size_t tot = lhs.layout().span().dist_byte(); |
| 46 | megdnn_assert(tot % chunk == 0); |
| 47 | char* pointer_lhs = reinterpret_cast<char*>(lhs.ptr_mutable_host()); |
| 48 | const char* pointer_rhs = reinterpret_cast<const char*>(rhs.ptr_host()); |
| 49 | for (size_t i = 0; i < tot; i += chunk) { |
| 50 | std::memcpy(pointer_lhs + i, pointer_rhs, chunk); |
| 51 | } |
| 52 | }; |
| 53 | using Param = param::MatrixMul; |
| 54 | megdnn_assert(format == Param::Format::DEFAULT); |
| 55 | for (auto&& arg : args) { |
| 56 | megdnn_assert(arg.mask == 0x0); |
| 57 | // make m, n, k big enough |
| 58 | size_t m = arg.m, n = (arg.n << 3), k = (arg.k << 3); |
| 59 | size_t m_prime = (m << 3); |
| 60 | if (filter && filter(arg)) |
| 61 | continue; |
| 62 | TensorShape A{m, k}, B{k, n}, C{m, n}; |
| 63 | TensorShape A_prime{m_prime, k}, C_prime{m_prime, n}; |
| 64 | SyncedTensor<dt_float32, Compare> A_tensor{handle_cuda, {A, A_dtype}}, |
| 65 | B_tensor{handle_cuda, {B, B_dtype}}, |
| 66 | C_tensor{handle_cuda, {C, C_dtype}}, |
| 67 | A_tensor_prime{handle_cuda, {A_prime, A_dtype}}, |
| 68 | C_tensor_prime{handle_cuda, {C_prime, C_dtype}}, |
| 69 | C_tensor_batch{handle_cuda, {C_prime, C_dtype}}; |
| 70 | rng->gen(A_tensor.tensornd_host()); |
| 71 | rng->gen(B_tensor.tensornd_host()); |
| 72 | copy(A_tensor_prime, A_tensor); |
| 73 | |
| 74 | auto opr_reference = handle_cuda->create_operator<MatrixMulForward>(); |
no test coverage detected