Skip to content

Commit c149fa2

Browse files
committed
Allow scalar iteration in the REPL on 1.9+.
1 parent c015cca commit c149fa2

File tree

1 file changed

+52
-39
lines changed

1 file changed

+52
-39
lines changed

lib/GPUArraysCore/src/GPUArraysCore.jl

Lines changed: 52 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ const AnyGPUArray{T,N} = Union{AbstractGPUArray{T,N}, WrappedGPUArray{T,N}}
2828
const AnyGPUVector{T} = AnyGPUArray{T, 1}
2929
const AnyGPUMatrix{T} = AnyGPUArray{T, 2}
3030

31+
3132
## broadcasting
3233

3334
"""
@@ -38,6 +39,7 @@ this supertype.
3839
"""
3940
abstract type AbstractGPUArrayStyle{N} <: Base.Broadcast.AbstractArrayStyle{N} end
4041

42+
4143
## scalar iteration
4244

4345
export allowscalar, @allowscalar, assertscalar
@@ -48,57 +50,37 @@ export allowscalar, @allowscalar, assertscalar
4850
# XXX: use context variables to inherit the parent task's setting, once available.
4951
const default_scalar_indexing = Ref{Union{Nothing,ScalarIndexing}}(nothing)
5052

51-
"""
52-
allowscalar() do
53-
# code that can use scalar indexing
54-
end
55-
56-
Denote which operations can use scalar indexing.
57-
58-
See also: [`@allowscalar`](@ref).
59-
"""
60-
function allowscalar(f::Base.Callable)
61-
task_local_storage(f, :ScalarIndexing, ScalarAllowed)
62-
end
63-
64-
"""
65-
allowscalar(::Bool)
66-
67-
Calling this with `false` replaces the default warning about scalar indexing
68-
(show once per session) with an error.
69-
70-
Instead of calling this with `true`, the preferred style is to allow this locally.
71-
This can be done with the `allowscalar(::Function)` method (with a `do` block)
72-
or with the [`@allowscalar`](@ref) macro.
73-
74-
Writes to `task_local_storage` for `:ScalarIndexing`. The default is `:ScalarWarn`,
75-
and this function sets `:ScalarAllowed` or `:ScalarDisallowed`.
76-
"""
77-
function allowscalar(allow::Bool=true)
78-
if allow
79-
Base.depwarn("allowscalar([true]) is deprecated, use `allowscalar() do end` or `@allowscalar` to denote exactly which operations can use scalar operations.", :allowscalar)
80-
end
81-
setting = allow ? ScalarAllowed : ScalarDisallowed
82-
task_local_storage(:ScalarIndexing, setting)
83-
default_scalar_indexing[] = setting
84-
return
85-
end
86-
8753
"""
8854
assertscalar(op::String)
8955
9056
Assert that a certain operation `op` performs scalar indexing. If this is not allowed, an
9157
error will be thrown ([`allowscalar`](@ref)).
9258
"""
9359
function assertscalar(op = "operation")
60+
# try to detect the REPL
61+
@static if VERSION >= v"1.10.0-DEV.444" || v"1.9-beta4" <= VERSION < v"1.10-"
62+
if isdefined(Base, :active_repl) && current_task() == Base.active_repl.frontend_task
63+
# we always allow scalar iteration on the REPL's frontend task,
64+
# where we often trigger scalar indexing by displaying GPU objects.
65+
return false
66+
end
67+
default_behavior = ScalarDisallowed
68+
else
69+
# we can't detect the REPL, but it will only be used in interactive sessions,
70+
# so default to allowing scalar indexing there (but warn).
71+
default_behavior = isinteractive() ? ScalarWarn : ScalarDisallowed
72+
end
73+
9474
val = get!(task_local_storage(), :ScalarIndexing) do
95-
something(default_scalar_indexing[], isinteractive() ? ScalarWarn : ScalarDisallowed)
75+
something(default_scalar_indexing[], default_behavior)
9676
end
9777
desc = """Invocation of $op resulted in scalar indexing of a GPU array.
9878
This is typically caused by calling an iterating implementation of a method.
9979
Such implementations *do not* execute on the GPU, but very slowly on the CPU,
100-
and therefore are only permitted from the REPL for prototyping purposes.
101-
If you did intend to index this array, annotate the caller with @allowscalar."""
80+
and therefore should be avoided.
81+
82+
If you want to allow scalar iteration, use `allowscalar` or `@allowscalar`
83+
to enable scalar iteration globally or for the operations in question."""
10284
if val == ScalarDisallowed
10385
error("""Scalar indexing is disallowed.
10486
$desc""")
@@ -120,6 +102,34 @@ macro __tryfinally(ex, fin)
120102
)
121103
end
122104

105+
"""
106+
allowscalar([true])
107+
allowscalar([true]) do
108+
...
109+
end
110+
111+
Use this function to allow or disallow scalar indexing, either globall or for the
112+
duration of the do block.
113+
114+
See also: [`@allowscalar`](@ref).
115+
"""
116+
allowscalar
117+
118+
function allowscalar(f::Base.Callable)
119+
task_local_storage(f, :ScalarIndexing, ScalarAllowed)
120+
end
121+
122+
function allowscalar(allow::Bool=true)
123+
if allow
124+
@warn """It's not recommended to use allowscalar([true]) to allow scalar indexing.
125+
Instead, use `allowscalar() do end` or `@allowscalar` to denote exactly which operations can use scalar operations.""" maxlog=1
126+
end
127+
setting = allow ? ScalarAllowed : ScalarDisallowed
128+
task_local_storage(:ScalarIndexing, setting)
129+
default_scalar_indexing[] = setting
130+
return
131+
end
132+
123133
"""
124134
@allowscalar() begin
125135
# code that can use scalar indexing
@@ -139,6 +149,9 @@ macro allowscalar(ex)
139149
end
140150
end
141151

152+
153+
## other
154+
142155
"""
143156
backend(T::Type)
144157
backend(x)

0 commit comments

Comments
 (0)