| 81 | } |
| 82 | |
| 83 | void BF16Backend::onCopyBuffer(const Tensor* srcTensor, const Tensor* dstTensor) const { |
| 84 | auto& ib = srcTensor->buffer(); |
| 85 | auto& ob = dstTensor->buffer(); |
| 86 | if (ib.type.code != halide_type_float) { |
| 87 | CPUBackend::onCopyBuffer(srcTensor, dstTensor); |
| 88 | return; |
| 89 | } |
| 90 | auto source = TensorUtils::getDescribe(srcTensor)->dimensionFormat; |
| 91 | auto dest = TensorUtils::getDescribe(dstTensor)->dimensionFormat; |
| 92 | auto srcType = MNN_FORWARD_CPU; |
| 93 | if (ib.device != 0) { |
| 94 | srcType = MNN_FORWARD_CPU_EXTENSION; |
| 95 | } |
| 96 | auto dstType = MNN_FORWARD_CPU; |
| 97 | if (ob.device != 0) { |
| 98 | dstType = MNN_FORWARD_CPU_EXTENSION; |
| 99 | } |
| 100 | if (srcType == dstType) { |
| 101 | ErrorCode code = ErrorCode::NO_ERROR; |
| 102 | auto tup = CPUTensorConverter::splitDimensions(srcTensor->buffer(), source); |
| 103 | int area = std::get<1>(tup), batch = std::get<0>(tup), channel = std::get<2>(tup); |
| 104 | if (srcType == MNN_FORWARD_CPU) { |
| 105 | code = CPUTensorConverter::convert(srcTensor->host<void>(), dstTensor->host<void>(), source, dest, batch, area, channel, 4, MNNGetCoreFunctions()); |
| 106 | } else { |
| 107 | code = CPUTensorConverter::convert(srcTensor->host<void>(), dstTensor->host<void>(), source, dest, batch, area, channel, 2, mCoreFunctions); |
| 108 | } |
| 109 | MNN_ASSERT(code == ErrorCode::NO_ERROR); |
| 110 | return; |
| 111 | } |
| 112 | // Use CPU Copy to turn save format |
| 113 | std::shared_ptr<Tensor> tempTensor; |
| 114 | if (source != dest) { |
| 115 | if (srcType == MNN_FORWARD_CPU) { |
| 116 | tempTensor.reset(Tensor::create<float>(dstTensor->shape(), nullptr, TensorUtils::getDimType(dstTensor))); |
| 117 | MNNCPUCopyBuffer(srcTensor, tempTensor.get()); |
| 118 | srcTensor = tempTensor.get(); |
| 119 | source = dest; |
| 120 | } else { |
| 121 | tempTensor.reset(Tensor::create<float>(srcTensor->shape(), nullptr, TensorUtils::getDimType(srcTensor)), [dstTensor](void* ptr) { |
| 122 | auto tempT = (Tensor*)ptr; |
| 123 | MNNCPUCopyBuffer(tempT, dstTensor); |
| 124 | delete tempT; |
| 125 | }); |
| 126 | dstTensor = tempTensor.get(); |
| 127 | dest = source; |
| 128 | } |
| 129 | } |
| 130 | //MNN_PRINT("%d, %d - %d, %d\n", source, srcType, dest, dstType); |
| 131 | // The format is the same, just convert fp32-fp16 |
| 132 | const int elemenSize = srcTensor->elementSize(); |
| 133 | // copy and quantize/dequantize data |
| 134 | if (srcType == MNN_FORWARD_CPU) { |
| 135 | const auto src = srcTensor->host<float>(); |
| 136 | auto dst = dstTensor->host<int16_t>(); |
| 137 | BF16Functions::get()->MNNFp32ToLowp(src, dst, elemenSize); |
| 138 | return; |
| 139 | } |
| 140 | if (srcType == MNN_FORWARD_CPU_EXTENSION) { |
no test coverage detected