-
Notifications
You must be signed in to change notification settings - Fork 3.7k
ARROW-17584: [Go] Use unsafe.Slice from Go 1.17 #14026
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
@tschaub you're going to have to update the github workflows to run using go1.17 instead of go1.16 for this to work. |
f549088
to
9978861
Compare
Thanks, @zeroshade. Updated. |
sigh It looks like the issue is that we actually sometimes call this with a 0 length slice and my suggestion of avoiding the Can you try shifting back to grabbing the slice header of the incoming slice and then using the |
Will do. It feels like the length may then need adjusting (in cases where the slice is not aligned to the start of the array). But I may be thinking about it wrong. |
9978861
to
b4f9eaa
Compare
@zeroshade - I updated things to use the |
@tschaub I figured out the issue. If you look at the original versions, we ensured that the capacity was Essentially instead of this: return unsafe.Slice((*int32)(unsafe.Pointer(h.Data)), len(b)/Int32SizeBytes) Do this: return unsafe.Slice((*int32)(unsafe.Pointer(h.Data)), cap(b)/Int32SizeBytes)[:len(b)/Int32SizeBytes] Note the usage of |
b4f9eaa
to
4fc2e1f
Compare
Thanks for digging into this, @zeroshade. I pushed a commit that doesn't make use of func bytesToUint64V1(b []byte) []uint64 {
if len(b) == 0 {
return nil
}
return unsafe.Slice((*uint64)(unsafe.Pointer(&b[0])), cap(b)/uint64SizeBytes)[:len(b)/uint64SizeBytes]
}
func bytesToUint64V2(b []byte) []uint64 {
h := (*reflect.SliceHeader)(unsafe.Pointer(&b))
return unsafe.Slice((*uint64)(unsafe.Pointer(h.Data)), cap(b)/uint64SizeBytes)[:len(b)/uint64SizeBytes]
} Maybe you'd only notice the difference if you were passing zero length slices with non-zero capacity. Let me know if you think V2 above would be preferable. |
@tschaub the V2 version is preferable and should solve your unit test issues |
4fc2e1f
to
5b90c88
Compare
Thanks, @zeroshade. I pushed an updated commit with the V2 flavor. I have been running |
@tschaub Not quite, notice the difference in the error messages and the fact that several of the versions of the tests succeeded. It looks like this is an interesting checkptr error, i'll try to take a look at it and see what i can figure out. |
Ah, i see the issue. Stay with me here.... The CI runs our tests using the My preferred solution would this: func CountSetBits(buf []byte, offset, n int) int {
if offset > 0 {
return countSetBitsWithOffset(buf, offset, n)
}
count := 0
uint64Bytes := n / uint64SizeBits * 8
if uint64Bytes > 0 { // <-- add this check to wrap the bytesToUint64 call so we don't call it with less than 8 bytes
for _, v := range bytesToUint64(buf[:uint64Bytes]) {
count += bits.OnesCount64(v)
}
}
... Adding that |
5b90c88
to
b3ae260
Compare
Thanks for the explanation, @zeroshade. Latest commit adds that condition to |
Wow it really doesn't like you 😦 I'll see if i can dig into these failures. |
@tschaub looks like a similar issue in I guess the solution is just to push the condition down into if h.Cap < uint64SizeBytes {
return nil
} there instead of the if you added to |
if h.Cap < uint64SizeBytes {
return nil
} This would only work where Would a check for |
sure, |
b3ae260
to
1d5220f
Compare
Ok, let's see what's next. |
woohoo, the integration test failure is not related to this change and is being tracked by a different PR. so this looks good. When you're ready make this an actual (instead of draft) PR and i'll give it a last lookover. |
@zeroshade - Thank you for your work on this. I appreciate all the digging you did to resolve the issues. I fear that it might not be achievable to use TinyGo to build WASM binaries using arrow. I've found additional incompatibilities in github.com/apache/thrift - where TinyGo's implementation of the net package doesn't cover all thrift's usage. So if you feel like the change in this branch is not the direction you want to go, or if you think it may introduce additional issues, please don't feel pressured to merge it in. I'd be happy to be able to build small WASM binaries that used arrow, but I'm not 100% sure it will be possible. |
@tschaub any particular reason you're using TinyGo over just using go's
Sure it won't be as small as TinyGo might be able to create, but the arrow.wasm this created was only around 8M uncompressed. Compressing with |
@zeroshade - Yeah, I'll stick with the |
Closing because it has been untouched for a while, in case it's still relevant feel free to reopen and move it forward 👍 |
The current use of
reflect.SliceHeader
fields makes the code less portable than it could be. For example, it is not possible to build with TinyGo where the slice header fields have different types.This change proposes using
unsafe.Slice
from Go 1.17 as an alternative.The tests are still failing for me, so I'm guessing that the changes aren't yet entirely correct. I'll open as a draft PR in hopes of working out any issues.
cc @zeroshade