| 312 | } |
| 313 | |
| 314 | bool pyarr2hval(py::array obj, CompNode cn, DType dtype, HostTensorArgs& ret) { |
| 315 | auto data = obj.cast<py::array>(); |
| 316 | auto strides = data.strides(); |
| 317 | bool need_squeeze = false; |
| 318 | for (size_t i = 0; i < data.ndim(); ++i) { |
| 319 | if (strides[i] == 0) { |
| 320 | need_squeeze = true; |
| 321 | break; |
| 322 | } |
| 323 | } |
| 324 | if (need_squeeze) { |
| 325 | std::vector<size_t> shape; |
| 326 | for (size_t i = 0; i < data.ndim(); ++i) { |
| 327 | shape.push_back(data.shape(i)); |
| 328 | } |
| 329 | data = data.squeeze(); |
| 330 | data.resize(shape); |
| 331 | } |
| 332 | HostTensorND retnd(cn); |
| 333 | retnd = npy::np2tensor(data.ptr(), npy::Meth::copy_into(&retnd), dtype); |
| 334 | if (!dtype.valid()) { |
| 335 | dtype = retnd.dtype(); |
| 336 | } |
| 337 | mgb_assert( |
| 338 | retnd.layout().is_empty() || retnd.layout().is_contiguous(), |
| 339 | "host value should be continuous"); |
| 340 | for (size_t i = 0; i < data.ndim(); ++i) { |
| 341 | ret.shape[ret.shape.ndim++] = data.shape(i); |
| 342 | } |
| 343 | ret.dtype = dtype; |
| 344 | ret.storage = HostStorage::make(retnd.storage()); |
| 345 | return true; |
| 346 | } |
| 347 | |
| 348 | bool pyint2hval(py::int_ obj, CompNode cn, DType dtype, HostTensorArgs& ret) { |
| 349 | if (!dtype.valid()) { |
no test coverage detected