| 393 | } |
| 394 | |
| 395 | void cg::copy_tensor_value_to_shape(TensorShape& dest, const DeviceTensorND& val) { |
| 396 | constexpr size_t MAX_DT_SIZE = 4; |
| 397 | mgb_assert(val.dtype().size() <= MAX_DT_SIZE); |
| 398 | |
| 399 | mgb_assert( |
| 400 | val.shape().ndim == 1, "shape tensor must be 1-dim, got %s", |
| 401 | val.shape().to_string().c_str()); |
| 402 | mgb_assert(val.comp_node().device_type() == CompNode::DeviceType::CPU); |
| 403 | dest.ndim = val.shape(0); |
| 404 | mgb_assert(dest.ndim <= TensorShape::MAX_NDIM); |
| 405 | auto vptr = val.raw_ptr(); |
| 406 | dt_byte contig[MAX_DT_SIZE * TensorShape::MAX_NDIM]; |
| 407 | if (val.layout().stride[0] != 1) { |
| 408 | auto dst = contig; |
| 409 | auto dst_strd = val.dtype().size(); |
| 410 | auto src = val.raw_ptr(); |
| 411 | auto src_strd = val.layout().stride[0] * dst_strd; |
| 412 | for (size_t i = 0; i < dest.ndim; ++i) { |
| 413 | memcpy(dst, src, dst_strd); |
| 414 | dst += dst_strd; |
| 415 | src += src_strd; |
| 416 | } |
| 417 | vptr = contig; |
| 418 | } |
| 419 | static_cast_dtype_safe(dest.shape, val.dtype(), vptr, dest.ndim); |
| 420 | } |
| 421 | |
| 422 | SymbolVar cg::var_from_tensor_shape( |
| 423 | ComputingGraph& graph, const OperatorNodeConfig& config, const char* opr_name, |