| 439 | } |
| 440 | |
| 441 | void VulkanBackend::onCopyBuffer(const Tensor* srcTensor, const Tensor* dstTensor) const { |
| 442 | #ifdef MNN_VULKAN_DEBUG |
| 443 | AUTOTIME; |
| 444 | MNN_PRINT("Src: "); |
| 445 | for (int i=0; i<srcTensor->dimensions(); ++i) { |
| 446 | MNN_PRINT("%d , ", srcTensor->length(i)); |
| 447 | } |
| 448 | MNN_PRINT("\n"); |
| 449 | MNN_PRINT("Dst: "); |
| 450 | for (int i=0; i<dstTensor->dimensions(); ++i) { |
| 451 | MNN_PRINT("%d , ", dstTensor->length(i)); |
| 452 | } |
| 453 | MNN_PRINT("\n"); |
| 454 | #endif |
| 455 | |
| 456 | auto calculateCpSize = [this] (const Tensor* tensor) -> size_t { |
| 457 | size_t eleSize = (size_t) tensor->elementSize(); |
| 458 | return (tensor->getType().code == halide_type_float && this->mUseFP16) ? |
| 459 | (eleSize * sizeof(uint16_t)) : |
| 460 | (eleSize * sizeof(float)); |
| 461 | }; |
| 462 | |
| 463 | std::shared_ptr<Tensor> tempTensor; |
| 464 | if (srcTensor->host<float>() != nullptr) { |
| 465 | _finish(); |
| 466 | auto format = TensorUtils::getDescribe(dstTensor)->dimensionFormat; |
| 467 | auto buffer = reinterpret_cast<VulkanBuffer*>(dstTensor->deviceId()); |
| 468 | auto offset = TensorUtils::getDescribeOrigin(dstTensor)->offset; |
| 469 | // host->gpu |
| 470 | if(format != TensorUtils::getDescribe(srcTensor)->dimensionFormat) { |
| 471 | tempTensor.reset(Tensor::create(dstTensor->shape(), dstTensor->getType(), nullptr, _convert(format))); |
| 472 | MNNCPUCopyBuffer(srcTensor, tempTensor.get()); |
| 473 | srcTensor = tempTensor.get(); |
| 474 | } |
| 475 | size_t cpSize = calculateCpSize(srcTensor); |
| 476 | _requireHostBuffer(cpSize); |
| 477 | _copyTensorToBuffer(srcTensor, mHostBuffer.get(), 0, srcTensor->getType().code == halide_type_float && mUseFP16); |
| 478 | auto cmdbuffer = mCmdBufferForCopy; |
| 479 | cmdbuffer->begin(0); |
| 480 | VkBufferCopy bufferCopy; |
| 481 | bufferCopy.size = cpSize; |
| 482 | bufferCopy.dstOffset = offset; |
| 483 | bufferCopy.srcOffset = 0; |
| 484 | vkCmdCopyBuffer(cmdbuffer->get(), mHostBuffer->buffer(), buffer->buffer(), |
| 485 | 1, &bufferCopy); |
| 486 | cmdbuffer->end(); |
| 487 | pushCommand(cmdbuffer->get()); |
| 488 | _finish(); |
| 489 | } else if (dstTensor->host<float>() != nullptr) { |
| 490 | // gpu->host |
| 491 | _finish(); |
| 492 | auto format = TensorUtils::getDescribe(dstTensor)->dimensionFormat; |
| 493 | if (format != TensorUtils::getDescribe(srcTensor)->dimensionFormat) { |
| 494 | tempTensor.reset(Tensor::create(srcTensor->shape(), dstTensor->getType(), nullptr, _convert(TensorUtils::getDescribe(srcTensor)->dimensionFormat)), [dstTensor](void* t) { |
| 495 | Tensor* temp = (Tensor*)t; |
| 496 | MNNCPUCopyBuffer(temp, dstTensor); |
| 497 | delete temp; |
| 498 | }); |
nothing calls this directly
no test coverage detected