Rules that use scalar indexing are not GPU-compatible
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Aptitud para principiantes
- 35/100
- Tipo de issue
- Error
- Claridad
- Bastante claro
- Estado de actividad
- Estancado
- Stack tecnológico
- julia
- Área
- backend, performance
Línea de trabajo
Empieza por src/rulesets/LinearAlgebra/norm.jl, alrededor de la implementación de _normInf_back, y ejecuta el CUDA MWE con la indexación escalar deshabilitada. Busca en los rulesets casos similares de indexación escalar y compara los enfoques propuestos de @allowscalar y size-1 view. Se considera terminado cuando las reglas afectadas funcionan con GPU arrays sin provocar el error de indexación escalar.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Some rules use scalar indexing, breaking GPU compatibility, e.g., https://github.com/JuliaDiff/ChainRules.jl/blob/3b3791f10bc88c41f004fbb9eb229745d1764593/src/rulesets/LinearAlgebra/norm.jl#L187
One solution would be to use @allowscalar from GPUArrays, but one concern about adding that dependency is the loading time (h/t @mcabbott).
Another is to be clever and replace all scalar indexing by size-1 views, such as:
@inbounds @views ∂x[yind:yind] .= sign.(x[yind:yind]) .* Δu
For people unfamiliar with GPU programming and @allowscalar: The reason scalar setindex/getindex is disallowed for GPU arrays is that sequential processing of GPU arrays from loopy CPU code defeats the purpose of using the GPU and leads to terrible performance. However, scalar setindex/getindex is of course legitimate in cases like the above, where you're not in a loop and only intend to set or retrieve that single element in the array. @allowscalar from GPUArrays is how you indicate that an exception should be made in any given instance, e.g.,
@inbounds @allowscalar ∂x[yind] = sign(x[yind]) * Δu
See https://cuda.juliagpu.org/stable/usage/workflow/#UsageWorkflowScalar for more about this mechanism
MWE:
using ChainRules
using CUDA
using LinearAlgebra
CUDA.allowscalar(false)
x = CUDA.ones(3)
nx, pb = ChainRules.rrule(norm, x, Inf)
ChainRules.unthunk(pb(1f0)[2])
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:
[1] error(s::String)
@ Base ./error.jl:33
[2] assertscalar(op::String)
@ GPUArrays ~/.julia/packages/GPUArrays/Zecv7/src/host/indexing.jl:53
[3] getindex
@ ~/.julia/packages/GPUArrays/Zecv7/src/host/indexing.jl:86 [inlined]
[4] findprev(testf::ChainRules.var"#1770#1771"{Float32}, A::CuArray{Float32, 1, CUDA.Mem.DeviceBuffer}, start::Int64)
@ Base ./array.jl:2151
[5] findlast
@ ./array.jl:2199 [inlined]
[6] _normInf_back(x::CuArray{Float32, 1, CUDA.Mem.DeviceBuffer}, y::Float32, Δy::Float32)
@ ChainRules ~/.julia/packages/ChainRules/SrdPq/src/rulesets/LinearAlgebra/norm.jl:185
[7] (::ChainRules.var"#1742#1746"{Float32, CuArray{Float32, 1, CUDA.Mem.DeviceBuffer}, Float64, Float32})()
@ ChainRules ~/.julia/packages/ChainRules/SrdPq/src/rulesets/LinearAlgebra/norm.jl:49
[8] unthunk
@ ~/.julia/packages/ChainRulesCore/RbX5a/src/tangent_types/thunks.jl:195 [inlined]
[9] unthunk(x::ChainRulesCore.InplaceableThunk{ChainRulesCore.Thunk{ChainRules.var"#1742#1746"{Float32, CuArray{Float32, 1, CUDA.Mem.DeviceBuffer}, Float64, Float32}}, ChainRules.var"#1741#1745"{Float32, CuArray{Float32, 1, CUDA.Mem.DeviceBuffer}, Float64, Float32}})
@ ChainRulesCore ~/.julia/packages/ChainRulesCore/RbX5a/src/tangent_types/thunks.jl:222
[10] top-level scope
@ REPL[329]:1
[11] top-level scope
- Lenguaje dominante
- Julia
- Estrellas
- 475
- Forks
- 98
- Métricas de merge de PR
- Sin PR fusionados en 30 d
Preparar el entorno
Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de JuliaDiff/ChainRules.jl
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
JuliaDiff/ChainRules.jl#844 ·
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 55/100
JuliaDiff/ChainRules.jl#818 ·
-
refactoring
Dificultad 4/5 3-5 días Aptitud para principiantes 35/100
JuliaDiff/ChainRules.jl#815 ·
-
bug
Dificultad 3/5 1-2 días Aptitud para principiantes 45/100
JuliaDiff/ChainRules.jl#810 ·
-
stack overflow issueAbierto
Dificultad 4/5 3-5 días Aptitud para principiantes 30/100
JuliaDiff/ChainRules.jl#809 ·
Todos los issues de JuliaDiff/ChainRules.jl
Issues similares
-
Dificultad 2/5 Menos de una hora Aptitud para principiantes 78/100
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
CliMA/ClimaAtmos.jl#4891 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
tagbot-manual
Dificultad 1/5 Menos de una hora Aptitud para principiantes 75/100
tshort/StaticCompiler.jl#191 ·
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
SciML/SciMLSensitivity.jl#1703 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
JuliaGPU/GPUCompiler.jl#1008 ·
Los mantenedores suelen responder en 1 día