Repository: JuliaGPU/KernelAbstractions.jl (julia)

Issue:
`StackOverflowError` on `get_backend(::UnitRange)`
MRE:

```
julia> using KernelAbstractions # v0.9.34

julia> get_backend(1:3)
ERROR: StackOverflowError:
Stacktrace:
 [1] get_backend(A::UnitRange{Int64}) (repeats 79984 times)
   @ KernelAbstractions C:\Users\konin_bt\.julia\packages\KernelAbstractions\sWSE0\src\KernelAbstractions.jl:519
```

I can imagine that trying to obtain the backend of an `UnitRange` is not a useful thing to do, but this probably still isn't desirable behavior.

This issue looks similar to https://github.com/JuliaGPU/KernelAbstractions.jl/issues/366.

Pull request description:
Prevent the `get_backend` methods from overflowing the stack/recurring without bound.

Hoping this doesn't cause inference issues due to deeper call stacks.

Fixes #588

Patch:
diff --git a/src/KernelAbstractions.jl b/src/KernelAbstractions.jl
index ae258a56..15757e3a 100644
--- a/src/KernelAbstractions.jl
+++ b/src/KernelAbstractions.jl
@@ -511,7 +511,13 @@ Get a [`Backend`](@ref) instance suitable for array `A`.
 function get_backend end
 
 # Should cover SubArray, ReshapedArray, ReinterpretArray, Hermitian, AbstractTriangular, etc.:
-get_backend(A::AbstractArray) = get_backend(parent(A))
+function get_backend(A::AbstractArray)
+    P = parent(A)
+    if P isa typeof(A)
+        throw(ArgumentError("Implement `KernelAbstractions.get_backend(::$(typeof(A)))`"))
+    end
+    return get_backend(P)
+end
 
 # Define:
 #   adapt_storage(::Backend, a::Array) = adapt(BackendArray, a)


Test patch:
diff --git a/test/test.jl b/test/test.jl
index 0ac7df17..640b32c0 100644
--- a/test/test.jl
+++ b/test/test.jl
@@ -7,6 +7,9 @@ using Adapt
 
 identity(x) = x
 
+struct UnknownAbstractVector <: AbstractVector{Float32}  # issue #588
+end
+
 function unittest_testsuite(Backend, backend_str, backend_mod, BackendArrayT; skip_tests = Set{String}())
     @conditional_testset "partition" skip_tests begin
         backend = Backend()
@@ -80,6 +83,7 @@ function unittest_testsuite(Backend, backend_str, backend_mod, BackendArrayT; sk
         @test @inferred(KernelAbstractions.get_backend(view(A, 2:4, 1:3))) isa backendT
         @test @inferred(KernelAbstractions.get_backend(Diagonal(x))) isa backendT
         @test @inferred(KernelAbstractions.get_backend(Tridiagonal(A))) isa backendT
+        @test_throws ArgumentError KernelAbstractions.get_backend(UnknownAbstractVector())  # issue #588
     end
 
     @conditional_testset "sparse" skip_tests begin