| 187 | |
| 188 | template <typename T> |
| 189 | void run_multinomial_without_replacement(Handle* handle) { |
| 190 | using ctype = typename DTypeTrait<T>::ctype; |
| 191 | |
| 192 | size_t num_groups = 2; |
| 193 | size_t num_samples = 1; |
| 194 | size_t len_probs = 4; |
| 195 | bool replacement = false; |
| 196 | size_t total_count = 10000; |
| 197 | |
| 198 | TensorLayout ly_probs{TensorShape{num_groups, len_probs}, T()}; |
| 199 | Tensor<ctype> probs(handle, ly_probs); |
| 200 | auto probs_ptr = probs.ptr(); |
| 201 | probs_ptr[0] = 1; |
| 202 | probs_ptr[1] = 2; |
| 203 | probs_ptr[2] = 3; |
| 204 | probs_ptr[3] = 4; |
| 205 | probs_ptr[4] = 0; |
| 206 | probs_ptr[5] = 7; |
| 207 | probs_ptr[6] = 2; |
| 208 | probs_ptr[7] = 1; |
| 209 | |
| 210 | std::vector<float> norm_probs; |
| 211 | for (size_t i = 0; i < 8; ++i) { |
| 212 | norm_probs.push_back(probs_ptr[i] / 10); |
| 213 | } |
| 214 | |
| 215 | auto opr = handle->create_operator<MultinomialRNG>(); |
| 216 | opr->param().num_samples = num_samples; |
| 217 | opr->param().replacement = replacement; |
| 218 | std::vector<float> sample_probs(num_groups * len_probs, 0); |
| 219 | for (size_t i = 0; i < total_count; ++i) { |
| 220 | TensorLayout ly_out{TensorShape{num_groups, num_samples}, dtype::Int32()}; |
| 221 | Tensor<dt_int32> out(handle, ly_out); |
| 222 | opr->exec(probs.tensornd(), out.tensornd(), {}); |
| 223 | auto ptr = out.ptr(); |
| 224 | sample_probs[ptr[0]] += 1; |
| 225 | sample_probs[len_probs + ptr[1]] += 1; |
| 226 | } |
| 227 | |
| 228 | for (size_t i = 0; i < num_groups * len_probs; ++i) { |
| 229 | sample_probs[i] /= total_count * num_samples; |
| 230 | } |
| 231 | |
| 232 | for (size_t i = 0; i < num_groups * len_probs; ++i) { |
| 233 | ASSERT_LE(std::abs(sample_probs[i] - norm_probs[i]), 1e-2); |
| 234 | } |
| 235 | } |
| 236 | |
| 237 | template <typename dtype> |
| 238 | void run_beta(Handle* handle) { |