Repository navigation
GH-52021: [Ruby] Add support for sliced arrays in MemoryView - #52286
Conversation
|
|
kou
left a comment
There was a problem hiding this comment.
Reviewed before submission by:
- Human
- AI
- Not reviewed
You haven't reviewed this, right? If so, can I open a separated PR that fixes my review comments?
See also: https://arrow.apache.org/docs/dev/developers/overview.html#ai-generated-code
BTW, sliced arrays just weren't supported before. I want to change the PR title to something like "Add support for sliced arrays in MemoryView".
| std::static_pointer_cast<const arrow::FixedWidthType>(array.type()); | ||
| view_->item_size = type->bit_width() / 8; | ||
| const auto byte_offset = | ||
| array_data->offset * std::max<int64_t>(view_->item_size, 1); |
There was a problem hiding this comment.
Is this std::max<int64_t>() for non byte aligned (offset % 8 != 0) boolean array? We should reject the case because we can't represent the case by MemoryView.
There was a problem hiding this comment.
Removed std::max. The byte offset now uses the type’s bit width, and Boolean slices with offset % 8 != 0 are rejected. Added separate tests for byte-aligned export and non-byte-aligned rejection.
| [ | ||
| [Arrow::Int8Array, "c"], | ||
| [Arrow::UInt8Array, "C"], | ||
| [Arrow::Int16Array, "s"], | ||
| [Arrow::UInt16Array, "S"], | ||
| [Arrow::Int32Array, "l"], | ||
| [Arrow::UInt32Array, "L"], | ||
| [Arrow::Int64Array, "q"], | ||
| [Arrow::UInt64Array, "Q"], | ||
| [Arrow::FloatArray, "f"], | ||
| [Arrow::DoubleArray, "d"], | ||
| ].each do |array_class, format| | ||
| test("#{array_class.name}: sliced") do |
There was a problem hiding this comment.
We don't want to define tests dynamically. Could you follow existing style?
We can use the following style here:
sub_test_case("Int8Array") do
test("offset: 0") do
# Existing test("Int8Array") content
end
test("offset: non-0") do
# This PR case
end
end
sub_test_case("Int8Array") do
# ...
end
# ...There was a problem hiding this comment.
Replaced the dynamically generated tests with explicit sub_test_case groups containing offset: 0 and offset: non-0 tests, following your suggested style.
| slices.each do |sliced_array, sliced_values| | ||
| Fiddle::MemoryView.export(sliced_array) do |memory_view| | ||
| assert_equal([ | ||
| format, | ||
| item_size, | ||
| item_size * sliced_values.size, | ||
| sliced_values.pack("#{format}*"), | ||
| ], | ||
| [ | ||
| memory_view.format, | ||
| memory_view.item_size, | ||
| memory_view.byte_size, | ||
| memory_view.to_s, | ||
| ]) | ||
| end |
There was a problem hiding this comment.
We don't want to use each {assert_equal(...)} for easy to debug. If we use the style, we can't run only the target case. We need to run all cases. And all cases aren't executed if one case is failed.
There was a problem hiding this comment.
Removed the assertion loop. Each retained slice case is now a separately named test that can run independently.
| [array.slice(1, 3), values.slice(1, 3)], | ||
| [array.slice(4, 3), values.slice(4, 3)], | ||
| [array.slice(1, 6).slice(2, 3), values.slice(3, 3)], | ||
| [array.slice(4, 0), []], | ||
| [array.slice(8, 0), []], |
There was a problem hiding this comment.
Do we need all cases? We want to remove needless cases as much as possible to focus on only important parts.
There was a problem hiding this comment.
Trimmed the repeated offsets, nested slices, empty slices, and duplicate numeric-type coverage. Kept one sliced case per numeric byte width, one fixed-size binary case, and the Boolean alignment cases.
|
|
|
Updated the title to "Add support for sliced arrays in MemoryView" and addressed the four inline comments in 0638ba3. Rebuilt the extension and ran the complete MemoryView test file: all 29 tests pass. The two new Boolean cases fail against the previous PR implementation and pass with the revision. |
|
I've pushed some commits to use Could you review them before we merge this? |
|
@kou lgtm! |
|
Thanks. Merged. |
Rationale for this change
MemoryView export of
Arrow::PrimitiveArraydidn't support arrays with non-zero offset (sliced arrays). For example, exportingArrow::Int32Array.new([0, 1, 2, 3]).slice(1, 3)returned wrong values because the data pointer was advanced byoffsetbytes instead ofoffset * byte widthbytes.What changes are included in this PR?
offset * bit width / 8as the byte offset of the data pointer. This supports sliced fixed-width arrays.available_pforArrow::PrimitiveArray. It returnsfalsefor arrays that can't be represented by MemoryView: unsupported types and boolean arrays with not byte aligned offset.Are these changes tested?
Ran the complete
test-memory-view.rbfile through the native Ruby/Fiddle interface using Ruby 3.2.3, Fiddle 1.1.8, and Arrow C++/GLib 25.0.1.The original MemoryView implementation in the 25.0.1 release is identical to the current checkout. The extension was rebuilt with this PR's updated
memory-view.cpp.git diff --checkpasses.The full repository test suite and a complete build of the 26.0.0-SNAPSHOT dependencies were not run.
Are there any user-facing changes?
rb_memory_view_available_p()returnsfalsefor unsupported arrays.Was AI used for this PR?
AI assisted with the investigation, implementation, regression tests, validation, and PR description.
PR code and description written by:
Reviewed before submission by: