| 449 | |
| 450 | template <typename T, typename U> |
| 451 | TensorND TensorValueLowbit4(const TensorShape& shape, T dtype, std::vector<U> values) { |
| 452 | TensorLayout layout{shape, dtype}; |
| 453 | auto buf = static_cast<dt_byte*>(malloc(layout.span().dist_byte())); |
| 454 | TensorND tensor{buf, layout}; |
| 455 | megdnn_assert(values.size() == tensor.layout.total_nr_elems()); |
| 456 | auto ptr = tensor.ptr<typename DTypeTrait<T>::ctype>(); |
| 457 | auto dim_in = shape[layout.ndim - 1]; |
| 458 | auto elems = tensor.layout.total_nr_elems(); |
| 459 | auto dim_out = elems / dim_in; |
| 460 | auto stride_out = div_ceil(dim_in, 2_z); |
| 461 | size_t in_offset = 0; |
| 462 | for (size_t i = 0; i < dim_out; ++i) { |
| 463 | for (size_t j = 0; j < dim_in; j += 2) { |
| 464 | U a = values[in_offset + j]; |
| 465 | U b = 0; |
| 466 | if (j + 1 < dim_in) |
| 467 | b = values[in_offset + j + 1]; |
| 468 | megdnn_assert(a >= DTypeTrait<T>::min()); |
| 469 | megdnn_assert(a <= DTypeTrait<T>::max()); |
| 470 | megdnn_assert(b >= DTypeTrait<T>::min()); |
| 471 | megdnn_assert(b <= DTypeTrait<T>::max()); |
| 472 | ptr[j / 2] = (a & 0xF) | (b << 4); |
| 473 | } |
| 474 | in_offset += dim_in; |
| 475 | ptr += stride_out; |
| 476 | } |
| 477 | return tensor; |
| 478 | } |
| 479 | |
| 480 | class Testcase : public SmallVector<TensorND> { |
| 481 | public: |