Skip to content

Commit 5030ad7

Browse files
committed
Reduce is_good_array with LoopVectorization.jl
1 parent c696f9f commit 5030ad7

File tree

1 file changed

+5
-34
lines changed

1 file changed

+5
-34
lines changed

src/Utils.jl

Lines changed: 5 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -76,41 +76,12 @@ end
7676
# Fastest way to check for NaN in an array.
7777
# Thanks @mikmore https://discourse.julialang.org/t/fastest-way-to-check-for-inf-or-nan-in-an-array/76954/33?u=milescranmer
7878
is_bad_array(x) = !is_good_array(x)
79-
function is_good_array_mix(x::AbstractArray{T}) where {T}
80-
n = length(x)
81-
n == 0 && return true
82-
n <= 256 && return isfinite(sum(xi -> xi * zero(typeof(xi)), x))
83-
return _is_good_array(x, Val(8))
84-
end
85-
86-
function _is_good_array(x::AbstractArray{T}, ::Val{unroll}) where {T,unroll}
87-
isempty(x) && return true
88-
_zero = zero(T)
89-
90-
# Vectorized segment
91-
vectorized_segment = eachindex(x)[begin:unroll:(end - unroll + 1)]
92-
empty_vectorized_segment = isempty(vectorized_segment)
93-
if !empty_vectorized_segment
94-
mask = ntuple(i -> _zero, Val(unroll))
95-
cumulator = mask
96-
for i in vectorized_segment
97-
batch = ntuple(j -> @inbounds(x[i + (j - 1)]), Val(unroll))
98-
cumulator = muladd.(mask, batch, cumulator)
99-
end
100-
cumulator == mask || return false
101-
end
102-
103-
# Tail
104-
tail_segment = if empty_vectorized_segment
105-
firstindex(x):lastindex(x)
106-
else
107-
(vectorized_segment[end] + unroll):lastindex(x)
108-
end
109-
scalar_cumulator = _zero
110-
for i in tail_segment
111-
scalar_cumulator = muladd(_zero, @inbounds(x[i]), scalar_cumulator)
79+
function is_good_array(x::AbstractArray{T}) where {T}
80+
cumulator = zero(T)
81+
@turbo for i in eachindex(x)
82+
cumulator += x[i] * 0
11283
end
113-
return scalar_cumulator == _zero
84+
return cumulator == 0
11485
end
11586

11687
isgood(x::T) where {T<:Number} = !(isnan(x) || !isfinite(x))

0 commit comments

Comments
 (0)