-
Notifications
You must be signed in to change notification settings - Fork 21
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
Incorrect use of reinterpret #38
Comments
In many ways this is a legacy interface; the But I'm a little confused about the specific location of the failure. Why doesn't reinterpret(BGRA{N0f8}, [0x22, 0x44, 0x88, 0xf0, 0x01, 0x02, 0x03, 0x04]) fail? |
It's also worth pointing out that one of the main things ImageCore did was develop the |
The size is not the issue, the alignment is. That's why the error is |
OK, I just assumed that an I can fix this, so don't sweat it yourself. |
Cool. Thanks. That's what I assumed which is why this is the only package that I didn't open a PR (JuliaLang/julia#21831 (comment)) |
Hmm, quick question: is there any reason we can't require a = Matrix{BGRA{N0f8}}(5,5) to have an alignment of 4 bytes? If we can, then there's a really easy fix here. |
Disallowing constructing a Making the error more conditional is possible but after seeing the users of reinterpret in packages I've confirmed my belief that doing that will just make debugging harder without helping anyone. For users that get the less-aligned array privately (range index of another array for example), they should use other functions for it (I've been using unsafe_load but we could have a better wrapper if needed) which would be faster and well-defined. For users that get the less-aligned array from the user, it'll be better to unconditionally throw the error since otherwise they'll just hit this error at some time when the user passed in an array that isn't well aligned. |
_
_ _ _(_)_ | A fresh approach to technical computing
(_) | (_) (_) | Documentation: https://docs.julialang.org
_ _ _| |_ __ _ | Type "?help" for help.
| | | | | | |/ _` | |
| | |_| | | | (_| | | Version 0.7.0-DEV.258 (2017-05-19 19:17 UTC)
_/ |\__'_|_|_|\__'_| | Commit a72aad4 (0 days old master)
|__/ | x86_64-linux-gnu
julia> using Colors, FixedPointNumbers
julia> a = Matrix{BGRA{N0f8}}(5,5)
5×5 Array{ColorTypes.BGRA{FixedPointNumbers.Normed{UInt8,8}},2}:
BGRA{N0f8}(0.0,0.0,0.0,0.0) BGRA{N0f8}(0.0,0.0,0.0,0.0) BGRA{N0f8}(0.0,0.0,0.0,0.0) BGRA{N0f8}(0.0,0.0,0.0,0.0) BGRA{N0f8}(0.0,0.0,0.0,0.0)
BGRA{N0f8}(0.0,0.0,0.0,0.0) BGRA{N0f8}(0.0,0.0,0.0,0.0) BGRA{N0f8}(0.0,0.0,0.0,0.0) BGRA{N0f8}(0.0,0.0,0.0,0.0) BGRA{N0f8}(0.0,0.0,0.0,0.0)
BGRA{N0f8}(0.0,0.0,0.0,0.0) BGRA{N0f8}(0.0,0.0,0.0,0.0) BGRA{N0f8}(0.0,0.0,0.0,0.0) BGRA{N0f8}(0.0,0.0,0.0,0.0) BGRA{N0f8}(0.0,0.0,0.0,0.0)
BGRA{N0f8}(0.0,0.0,0.0,0.0) BGRA{N0f8}(0.0,0.0,0.0,0.0) BGRA{N0f8}(0.0,0.0,0.0,0.0) BGRA{N0f8}(0.0,0.0,0.0,0.0) BGRA{N0f8}(0.0,0.0,0.0,0.0)
BGRA{N0f8}(0.0,0.0,0.0,0.0) BGRA{N0f8}(0.0,0.0,0.0,0.0) BGRA{N0f8}(0.0,0.0,0.0,0.0) BGRA{N0f8}(0.0,0.0,0.0,0.0) BGRA{N0f8}(0.0,0.0,0.0,0.0)
julia> reinterpret(UInt32, a)
ERROR: ArgumentError: reinterpret from alignment 1 bytes to alignment 4 bytes not allowed
Stacktrace:
[1] reinterpret(::Type{UInt32}, ::Array{ColorTypes.BGRA{FixedPointNumbers.Normed{UInt8,8}},2}, ::Tuple{Int64,Int64}) at ./array.jl:153
[2] reinterpret(::Type{UInt32}, ::Array{ColorTypes.BGRA{FixedPointNumbers.Normed{UInt8,8}},2}) at ./array.jl:139 |
I mean, the pointer is aligned. The type is not and won't be. And for why the error is raised, see the detail below that sentence. |
This takes another step in the direction of discouraging explicit use of reinterpret. This is considerably more careful to check whether the eltype of input arrays matches the eltype of the Colorant before using reinterpret, and consequently is more reliable about falling back to ColorView. It resolves the alignment issue by avoiding calling reinterpret. To simplify the code, this uses triangular dispatch, so this also bumps the minimum required version of Julia.
This takes another step in the direction of discouraging explicit use of reinterpret. This is considerably more careful to check whether the eltype of input arrays matches the eltype of the Colorant before using reinterpret, and consequently is more reliable about falling back to ColorView. It resolves the alignment issue by avoiding calling reinterpret. To simplify the code, this uses triangular dispatch, so this also bumps the minimum required version of Julia.
This takes another step in the direction of discouraging explicit use of reinterpret. This is considerably more careful to check whether the eltype of input arrays matches the eltype of the Colorant before using reinterpret, and consequently is more reliable about falling back to ColorView. It resolves the alignment issue by avoiding calling reinterpret. To simplify the code, this uses triangular dispatch, so this also bumps the minimum required version of Julia.
The corrent code contains invalid use of
reinterpret
to cast an array of less alignment to an array of larger alignment causing test failure after JuliaLang/julia#21831I'm not sure what is the right fix here. If this is a public interface that should be maintained, the reinterpret needs to be done differently. The load cannot be a
getindex(::Array)
, which must have the right alignment, but needs to be constructed from smaller loads or use unaligned load i.e.unsafe_load(::Ptr)
. I put aUnalignedVector
implementation in CRC.jl that is barely good enough for the private usecase in that package but should demonstrate the right way to deal with the alignment issue. I imagine the Array experts here should be able to implement a better interface/more complete array from there if necessary.The text was updated successfully, but these errors were encountered: