JuliaSIMD / JuliaSIMD/LoopVectorization.jl

Cannot recognize index `i` in `@turbo` over `Vector{DateTime}`

Open
#339 3 comments 0 reactions 0 assignees View on GitHub
Dominant language
Julia
Stars
789
Forks
73
PR merge metrics
No merged PRs in 30d

Description

## Overview

I get this error:

```console
ERROR: UndefVarError: i not defined
Stacktrace:
[1] scale_stamps_turbo(data::Vector{DateTime})
@ Main ./REPL[7]:5
[2] top-level scope
@ REPL[15]:1
```

When running:

```julia
using Dates
using LoopVectorization

function scale_stamps_turbo(data::Vector{Dates.DateTime})
out = similar(data, Float64)
ϕ = (data[lastindex(data)] - data[1]).value
@turbo for i ∈ eachindex(data)
out[i] = (data[i] - data[1]).value / ϕ
end
return out
end
```

**When I do not use** the `@turbo` macro, it works correctly:

```julia
using Dates

function scale_stamps(data::Vector{Dates.DateTime})
out = similar(data, Float64)
ϕ = (data[lastindex(data)] - data[1]).value
for i ∈ eachindex(data)
out[i] = (data[i] - data[1]).value / ϕ
end
return out
end
```

```julia
julia> hcat(mydata, scale_stamps(mydata))
5×2 Matrix{Any}:
1990-01-01T00:00:01 0.0
1990-01-01T00:00:03 0.142857
1990-01-01T00:00:06 0.357143
1990-01-01T00:00:10 0.642857
1990-01-01T00:00:15 1.0
```

## Debugging 1: Correct behavior with `Vector{Int64}`

It looks like this is related to using `Vector{Dates.DateTime}`, the following two functions perform the same operation over vectors of Int, but work correctly:

```julia
using LoopVectorization

function scale(data::Vector{Int64})
out = similar(data, Float64)
ϕ = data[lastindex(data)] - data[1]
for i ∈ eachindex(data)
out[i] = (data[i] - data[1]) / ϕ
end
return out
end

function scale_turbo(data::Vector{Int64})
out = similar(data, Float64)
ϕ = data[lastindex(data)] - data[1]
@turbo for i ∈ eachindex(data)
out[i] = (data[i] - data[1]) / ϕ
end
return out
end
```

Sample Output

```julia
julia> hcat(somedata, scale(somedata), scale_turbo(somedata))
10×3 Matrix{Float64}:
1.0 0.0 0.0
3.0 0.08 0.08
6.0 0.2 0.2
8.0 0.28 0.28
12.0 0.44 0.44
14.0 0.52 0.52
17.0 0.64 0.64
21.0 0.8 0.8
22.0 0.84 0.84
26.0 1.0 1.0
```

Benchmark

```console
julia> @benchmark scale(benchmark_data)
BenchmarkTools.Trial: 10000 samples with 1 evaluation.
Range (min … max): 254.978 μs … 1.789 ms ┊ GC (min … max): 0.00% … 81.20%
Time (median): 255.789 μs ┊ GC (median): 0.00%
Time (mean ± σ): 308.832 μs ± 141.360 μs ┊ GC (mean ± σ): 4.30% ± 8.33%

█▁▂▁ ▆▄ ▁ ▁
█████▆▇▅▅▅▄█▇█████▅▅▄▄▅▄▄▃▃▁▁▁▃▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█ █
255 μs Histogram: log(frequency) by time 941 μs <

Memory estimate: 625.08 KiB, allocs estimate: 2.

julia> @benchmark scale_turbo(benchmark_data)
BenchmarkTools.Trial: 10000 samples with 1 evaluation.
Range (min … max): 59.220 μs … 888.608 μs ┊ GC (min … max): 0.00% … 73.05%
Time (median): 68.954 μs ┊ GC (median): 0.00%
Time (mean ± σ): 79.751 μs ± 76.075 μs ┊ GC (mean ± σ): 11.16% ± 10.52%

█▆▃▁ ▁
████▆▅▄▁▁▁▁▁▄█▅▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█ █
59.2 μs Histogram: log(frequency) by time 705 μs <

Memory estimate: 625.08 KiB, allocs estimate: 2.
```

## Helper Methods for Debugging

My inputs are vectors of strictly increasing values, so here are two functions for generating data:

generate Int64 Vectors / DateTime Vectors

```julia
using Random

function generate_data(N::Int64)
data = Vector{Int64}(undef,N)
v = 0
for i in 1:N
v += rand(1:5, 1)[1]
data[i] = v
end
return data
end

function generate_timestamps(N::Int64)
data = Vector{Dates.DateTime}(undef,N)
v = DateTime(1990, 1, 1, 0, 0, 0)
for i in 1:N
v += Second(i)
data[i] =v
end
return data
end
```

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.