====================Tensor Operations=======================================
| 604 | |
| 605 | // ====================Tensor Operations======================================= |
| 606 | void CopyDataToFrom(Tensor *dst, const Tensor &src, const size_t num, |
| 607 | const size_t dst_offset, const size_t src_offset) { |
| 608 | auto width = SizeOf(src.data_type()); |
| 609 | CHECK_EQ(width, SizeOf(dst->data_type())); |
| 610 | size_t nBytes = num * width; |
| 611 | auto d_offset = dst_offset * width; |
| 612 | auto s_offset = src_offset * width; |
| 613 | CHECK_GE(src.MemSize(), s_offset + nBytes); |
| 614 | CHECK_GE(dst->MemSize(), d_offset + nBytes); |
| 615 | |
| 616 | Device *dev = nullptr; |
| 617 | CopyDirection direct; |
| 618 | std::shared_ptr<Device> src_dev = src.device(), dst_dev = dst->device(); |
| 619 | if (dst_dev->lang() != src_dev->lang()) { |
| 620 | // let the none cpp device conduct copy op |
| 621 | if (dst_dev->lang() == kCpp) { |
| 622 | dev = src_dev.get(); |
| 623 | direct = kDeviceToHost; |
| 624 | } else if (src_dev->lang() == kCpp) { |
| 625 | dev = dst_dev.get(); |
| 626 | direct = kHostToDevice; |
| 627 | } else { |
| 628 | LOG(FATAL) << "Not support mem copy between Cuda and OpenCL device"; |
| 629 | } |
| 630 | } else { |
| 631 | dev = src_dev.get(); |
| 632 | direct = src_dev->lang() == kCpp ? kHostToHost : kDeviceToDevice; |
| 633 | } |
| 634 | |
| 635 | Tensor &dstRef = *dst; |
| 636 | dev->Exec( |
| 637 | [dev, dstRef, src, nBytes, direct, d_offset, |
| 638 | s_offset](Context *ctx) mutable { |
| 639 | Block *from = src.block(), *to = dstRef.block(); |
| 640 | dev->CopyDataToFrom(to, from, nBytes, direct, (int)d_offset, |
| 641 | (int)s_offset, ctx); |
| 642 | }, |
| 643 | {src.block()}, {dst->block()}, "CopyDataToFrom"); |
| 644 | } |
| 645 | |
| 646 | void RepeatDataToFrom(bool broadcast_flag, const vector<size_t> &repeats, |
| 647 | int axis, Tensor *dst, const Tensor &src, |
no test coverage detected