| 89 | } |
| 90 | |
| 91 | std::shared_ptr<DctTestcase> gen_dct_case( |
| 92 | const size_t n, const size_t ic, const size_t ih, const size_t iw, |
| 93 | const size_t oc, Param param, DType dst_dtype, bool correct_result) { |
| 94 | const size_t block = param.dct_block_size; |
| 95 | const int block_c = param.format == Param::Format::NCHW4 ? 4 : 1; |
| 96 | megdnn_assert(oc % block_c == 0, "oc mod block_c must == 0"); |
| 97 | std::shared_ptr<DctTestcase> test_case_ptr = DctTestcase::make(); |
| 98 | DctTestcase& test_case = *test_case_ptr.get(); |
| 99 | UniformIntRNG rng(0, 255); |
| 100 | UniformIntRNG mask_rng(0, 64 / block_c - 1); |
| 101 | const size_t input_elements = n * ic * ih * iw; |
| 102 | const size_t no_mask_oc = ic * block * block; |
| 103 | megdnn_assert(ih % block == 0, "%zu mod %zu == 0", ih, block); |
| 104 | megdnn_assert(iw % block == 0, "%zu mod %zu == 0", iw, block); |
| 105 | std::vector<uint8_t>& inp_vec = test_case.inp_vec; |
| 106 | inp_vec.resize(input_elements); |
| 107 | TensorShape input_shape{n, ic, ih, iw}; |
| 108 | for (auto& elm : inp_vec) { |
| 109 | elm = (uint8_t)rng.gen_single_val(); |
| 110 | } |
| 111 | auto src = TensorND(inp_vec.data(), {input_shape, dtype::Uint8()}); |
| 112 | TensorND mask_offset; |
| 113 | TensorND mask_val; |
| 114 | std::vector<int>& mask_offset_vec = test_case.mask_offset_vec; |
| 115 | std::vector<int>& mask_val_vec = test_case.mask_val_vec; |
| 116 | UniformIntRNG rng_oc(0, oc); |
| 117 | if (param.fastImpl == Param::FastImpl::FIX_32_MASK) { |
| 118 | auto fix_32_mask = get_fix_mask(Param::FastImpl::FIX_32_MASK); |
| 119 | mask_offset_vec = fix_32_mask.mask_offset; |
| 120 | mask_val_vec = fix_32_mask.mask_val; |
| 121 | megdnn_assert(oc == 32, "oc must eq 32"); |
| 122 | } else if (no_mask_oc > oc) { |
| 123 | size_t remain_oc = oc; |
| 124 | mask_offset_vec.resize(ic + 1); |
| 125 | mask_val_vec.resize(oc); |
| 126 | mask_offset_vec[0] = 0; |
| 127 | for (size_t ic_idx = 0; ic_idx < ic; ++ic_idx) { |
| 128 | size_t random_len = (int)rng_oc.gen_single_val() * block_c; |
| 129 | size_t mask_len = (ic_idx == ic - 1) || (remain_oc == 0) |
| 130 | ? remain_oc |
| 131 | : random_len % remain_oc; |
| 132 | megdnn_assert( |
| 133 | mask_len % block_c == 0, |
| 134 | "mask_len mod block_c == 0, but %zu mod %d ", mask_len, block_c); |
| 135 | const size_t oc_idx = mask_offset_vec[ic_idx]; |
| 136 | remain_oc -= mask_len; |
| 137 | mask_offset_vec[ic_idx + 1] = oc_idx + mask_len; |
| 138 | for (size_t mask_idx = 0; mask_idx < mask_len; ++mask_idx) { |
| 139 | mask_val_vec[oc_idx + mask_idx] = (int)mask_rng.gen_single_val(); |
| 140 | } |
| 141 | } |
| 142 | } |
| 143 | mask_offset = TensorND( |
| 144 | mask_offset_vec.data(), {{mask_offset_vec.size()}, dtype::Int32()}); |
| 145 | mask_val = TensorND(mask_val_vec.data(), {{mask_val_vec.size()}, dtype::Int32()}); |
| 146 | if (mask_offset_vec.size() >= 2) { |
| 147 | test_case.testcase_in = { |
| 148 | src, mask_offset, mask_val, {nullptr, {{}, dst_dtype}}}; |
no test coverage detected