-
Notifications
You must be signed in to change notification settings - Fork 206
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
Fixes grid equality for GPUs #2030
Conversation
|
src/Grids/Grids.jl
Outdated
x1, y1, z1 = nodes((Face, Face, Face), grid1) | ||
x2, y2, z2 = nodes((Face, Face, Face), grid2) | ||
x1, y1, z1 = Adapt.adapt(CPU(), nodes((Face, Face, Face), grid1)) | ||
x2, y2, z2 = Adapt.adapt(CPU(), nodes((Face, Face, Face), grid2)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this does anything. I did a little test and this is what I get:
julia> using Adapt, CUDA, Oceananigans
julia> a = CuArray(rand(3))
3-element CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}:
0.7359732430925523
0.19547988326307286
0.6593710335404803
julia> b = Adapt.adapt(CPU(), a)
3-element CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}:
0.7359732430925523
0.19547988326307286
0.6593710335404803
The reason is because the fallback for Adapt.adapt
is an identity (eg adapt(to, x) = x
). There's no special adapt(to, x)
method for to::Oceananigans.AbstractArchitecture
--- the variable to
is a CUDA-specific object (this function isn't called when we run on the CPU).
What is this code trying to do --- is it converting to Array
? This might be sensible, because a == b
triggers scalar operations on the GPU if one of them is GPU and one is CPU. Otherwise, this should work:
julia> using CUDA
julia> a = 0.0:0.1:0.3
0.0:0.1:0.3
julia> b = Array(a)
4-element Vector{Float64}:
0.0
0.1
0.2
0.3
julia> c = CuArray(a)
4-element CuArray{Float64, 1, CUDA.Mem.DeviceBuffer}:
0.0
0.1
0.2
0.3
julia> a == b
true
julia> CUDA.@allowscalar a == c
true
julia> CUDA.@allowscalar b == c
true
julia> b == c
ERROR: Scalar indexing is disallowed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I again don't have GPU access at this exact moment to test this in more detail, but it seemed to work for me. This is what I got (from my logs):
julia> x1, y1, z1 = Adapt.adapt(CPU(), nodes((Face, Face, Face), grid1))
([0.0, 0.5], [0.0, 0.5], [1.0, 2.0, 3.0])
julia> x1, y1, z1 = nodes((Face, Face, Face), grid1)
([0.0, 0.5], [0.0, 0.5], [Error showing value of type Tuple{SubArray{Float64, 1, OffsetArrays.OffsetVector{Float64, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}}, Tuple{UnitRange{Int64}}, true}, SubArray{Float64, 1, OffsetArrays.OffsetVector{Float64, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}}, Tuple{UnitRange{Int64}}, true}, SubArray{Float64, 1, OffsetArrays.OffsetVector{Float64, CUDA.CuArray{Float64, 1}}, Tuple{UnitRange{Int64}}, true}}:
ERROR: Scalar indexing is disallowed.
Invocation of getindex resulted in scalar indexing of a GPU array.
This is typically caused by calling an iterating implementation of a method.
Such implementations *do not* execute on the GPU, but very slowly on the CPU,
and therefore are only permitted from the REPL for prototyping purposes.
If you did intend to index this array, annotate the caller with @allowscalar.
Stacktrace:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well that sent me on a journey. There is this method:
Oceananigans.jl/src/Architectures.jl
Line 73 in 432fab2
Adapt.adapt_structure(::CPU, a::OffsetGPUArray) = OffsetArray(Array(a.parent), a.offsets...) |
Which I think gets called here. (I have myself to blame for that --- it seems misguided now.)
I think I prefer converting to Array
here rather than using Adapt
(which does basically the same thing for OffsetArray
, but may not work in the future or for other array types). @allowscalar
is also ok but Array
seems better for some reason.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. I'll commit your suggestion and see if tests pass then.
Sorry, let me be more clear:
|
Co-authored-by: Gregory L. Wagner <wagner.greg@gmail.com>
@glwagner for some reason your suggestion using tuples didn't work. I was getting a "scalar indexing disallowed" error on that same line, which was weird. So I changed it to an It's also weird that the test I added (which supposedly tests both CPUs and GPUs) didn't catch that.... not sure why |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I admit I missed the thread a bit with the discussion about Adapt. But from what I see now Adapt isn't involved. Seeing the latest changes in the files I think they make a lot of sense so I'm happy.
For some reason when I tested the code after merging #2028 it didn't really work on my main code for GPUs.
It worked for a MWE when I tested it here but I guess I must have done something wrong? In any case, I apologize!
I also expanded the test to test grids on GPUs (which would have caught this error) so I think this'll help.
Given that we just released a new version, I didn't bump this to 0.63.4 here. But let me know if I should do that.
CC: @navidcy