felipecrv commented on code in PR #41477:
URL: https://github.com/apache/arrow/pull/41477#discussion_r1600264211
##########
cpp/src/arrow/c/bridge.cc:
##########
@@ -1868,24 +1868,15 @@ struct ArrayImporter {
template <typename OffsetType>
Status ImportStringValuesBuffer(int32_t offsets_buffer_id, int32_t buffer_id,
int64_t byte_width = 1) {
- if (device_type_ == DeviceAllocationType::kCPU) {
- auto offsets = data_->GetValues<OffsetType>(offsets_buffer_id);
- // Compute visible size of buffer
- int64_t buffer_size =
- (c_struct_->length > 0) ? byte_width * offsets[c_struct_->length] :
0;
- return ImportBuffer(buffer_id, buffer_size);
- }
-
- // we only need the value of the last offset so let's just copy that
- // one value from device to host.
- auto single_value_buf =
- SliceBuffer(data_->buffers[offsets_buffer_id],
- c_struct_->length * sizeof(OffsetType),
sizeof(OffsetType));
- ARROW_ASSIGN_OR_RAISE(
- auto cpubuf, Buffer::ViewOrCopy(single_value_buf,
default_cpu_memory_manager()));
- auto offsets = cpubuf->data_as<OffsetType>();
+ int64_t last_offset_value_offset =
+ c_struct_->length * sizeof(OffsetType) + c_struct_->offset;
+ OffsetType last_offset_value;
+ RETURN_NOT_OK(MemoryManager::CopyBufferSlice(
+ data_->buffers[offsets_buffer_id], last_offset_value_offset,
sizeof(OffsetType),
+ reinterpret_cast<uint8_t*>(&last_offset_value)));
+
// Compute visible size of buffer
- int64_t buffer_size = (c_struct_->length > 0) ? byte_width * offsets[0] :
0;
+ int64_t buffer_size = (c_struct_->length > 0) ? byte_width *
last_offset_value : 0;
Review Comment:
You can guard all the slicing in a block after the length check to avoid
potentially slicing an empty buffer or slicing unnecessarily because the length
of the array is `0`.
```cpp
int64_t buffer_size = 0;
if (c_struct_->length > 0) {
// ...
}
return ImportBuffer(buffer_id, buffer_size);
```
##########
cpp/src/arrow/device.cc:
##########
@@ -116,6 +116,34 @@ Result<std::shared_ptr<Buffer>> MemoryManager::ViewBuffer(
" on ", to->device()->ToString(), " not
supported");
}
+Status MemoryManager::CopyBufferSlice(const std::shared_ptr<Buffer>& buf,
int64_t offset,
+ int64_t length, uint8_t* out_data) {
+ if (ARROW_PREDICT_TRUE(buf->is_cpu())) {
+ int64_t test;
+ memcpy(&test, buf->data() + offset, static_cast<size_t>(length));
+
Review Comment:
✂️
##########
cpp/src/arrow/c/bridge.cc:
##########
@@ -1868,24 +1868,15 @@ struct ArrayImporter {
template <typename OffsetType>
Status ImportStringValuesBuffer(int32_t offsets_buffer_id, int32_t buffer_id,
int64_t byte_width = 1) {
- if (device_type_ == DeviceAllocationType::kCPU) {
- auto offsets = data_->GetValues<OffsetType>(offsets_buffer_id);
- // Compute visible size of buffer
- int64_t buffer_size =
- (c_struct_->length > 0) ? byte_width * offsets[c_struct_->length] :
0;
- return ImportBuffer(buffer_id, buffer_size);
- }
-
- // we only need the value of the last offset so let's just copy that
- // one value from device to host.
- auto single_value_buf =
- SliceBuffer(data_->buffers[offsets_buffer_id],
- c_struct_->length * sizeof(OffsetType),
sizeof(OffsetType));
- ARROW_ASSIGN_OR_RAISE(
- auto cpubuf, Buffer::ViewOrCopy(single_value_buf,
default_cpu_memory_manager()));
- auto offsets = cpubuf->data_as<OffsetType>();
+ int64_t last_offset_value_offset =
+ c_struct_->length * sizeof(OffsetType) + c_struct_->offset;
Review Comment:
Yes. The offset of the ArrowArray should be applied when reading the
`Buffer` of the array.
But the formula is different because the array offset is in number of
values, not in the number of bytes.
`(c_struct_->offset + c_struct_->length) * sizeof(OffsetType)`
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]