| 67 | } // namespace |
| 68 | |
| 69 | Result<DLManagedTensor*> ExportArray(const std::shared_ptr<Array>& arr) { |
| 70 | // Define DLDevice struct and check if array type is supported |
| 71 | // by the DLPack protocol at the same time. Raise TypeError if not. |
| 72 | // Supported data types: int, uint, float with no validity buffer. |
| 73 | ARROW_ASSIGN_OR_RAISE(auto device, ExportDevice(arr)) |
| 74 | |
| 75 | // Define the DLDataType struct |
| 76 | const DataType& type = *arr->type(); |
| 77 | std::shared_ptr<ArrayData> data = arr->data(); |
| 78 | ARROW_ASSIGN_OR_RAISE(auto dlpack_type, GetDLDataType(type)); |
| 79 | |
| 80 | // Create ManagerCtx that will serve as the owner of the DLManagedTensor |
| 81 | auto ctx = std::make_unique<ManagerCtx>(); |
| 82 | |
| 83 | // Define the data pointer to the DLTensor |
| 84 | // If array is of length 0, data pointer should be NULL |
| 85 | if (arr->length() == 0) { |
| 86 | ctx->tensor.dl_tensor.data = NULL; |
| 87 | } else { |
| 88 | const auto data_offset = data->offset * type.byte_width(); |
| 89 | ctx->tensor.dl_tensor.data = |
| 90 | const_cast<uint8_t*>(data->buffers[1]->data() + data_offset); |
| 91 | } |
| 92 | |
| 93 | ctx->tensor.dl_tensor.device = device; |
| 94 | ctx->tensor.dl_tensor.ndim = 1; |
| 95 | ctx->tensor.dl_tensor.dtype = dlpack_type; |
| 96 | ctx->tensor.dl_tensor.shape = const_cast<int64_t*>(&data->length); |
| 97 | ctx->tensor.dl_tensor.strides = NULL; |
| 98 | ctx->tensor.dl_tensor.byte_offset = 0; |
| 99 | |
| 100 | ctx->array = std::move(data); |
| 101 | ctx->tensor.manager_ctx = ctx.get(); |
| 102 | ctx->tensor.deleter = [](struct DLManagedTensor* self) { |
| 103 | delete reinterpret_cast<ManagerCtx*>(self->manager_ctx); |
| 104 | }; |
| 105 | return &ctx.release()->tensor; |
| 106 | } |
| 107 | |
| 108 | Result<DLDevice> ExportDevice(const std::shared_ptr<Array>& arr) { |
| 109 | // Check if array is supported by the DLPack protocol. |