# Do views interfere with thread synchronization?

**URL:** https://discourse.julialang.org/t/do-views-interfere-with-thread-synchronization/75379
**Category:** General Usage
**Tags:** multithreading, views
**Created:** [January 28, 2022, 4:15pm UTC](https://discourse.julialang.org/t/do-views-interfere-with-thread-synchronization/75379 "2022-01-28T16:15:52Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)
#### Post date: [January 28, 2022, 4:15pm UTC](https://discourse.julialang.org/t/do-views-interfere-with-thread-synchronization/75379/1 "2022-01-28T16:15:52Z")

</div>

I have this code which attempts compute a matrix-vector product using submatrices.

```julia
tasks = [];
    for th in 1:length(tbs)
        tb = tbs[th]
        push!(tasks, Threads.@spawn begin 
            mul!(tb.result, tb.kcolumns, tb.uv)
        end);
    end

```

This works fine when materialize the submatrices, i.e. when `tb.kcolumns` is `K[:, colrange]`, but it does not work when I use views, i.e. when `tb.kcolumns` is `view(K, :, colrange)`.

Do views change the thread behavior?

---

<div class="post-metadata">

### Author: ![goerch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerch/32/29122_2.png) [@goerch](https://discourse.julialang.org/u/goerch)
#### Post date: [January 28, 2022, 6:34pm UTC](https://discourse.julialang.org/t/do-views-interfere-with-thread-synchronization/75379/2 "2022-01-28T18:34:26Z")

</div>

> [@PetrKryslUCSD](#):
>
> Do views change the thread behavior?

If they change threading behavior I’d suspect a data race. More information would help to understand that better, of course.

---

<div class="post-metadata">

### Author: ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)
#### Post date: [January 28, 2022, 9:29pm UTC](https://discourse.julialang.org/t/do-views-interfere-with-thread-synchronization/75379/3 "2022-01-28T21:29:50Z")

</div>

Alas, my attempts to construct a MWE have failed to reproduce the behavior (the threads get stuck forever).

---

<div class="post-metadata">

### Author: ![goerch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerch/32/29122_2.png) [@goerch](https://discourse.julialang.org/u/goerch)
#### Post date: [January 28, 2022, 9:35pm UTC](https://discourse.julialang.org/t/do-views-interfere-with-thread-synchronization/75379/4 "2022-01-28T21:35:39Z")

</div>

Which sounds like a problem in itself. Should we have a look?

---

<div class="post-metadata">

### Author: ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)
#### Post date: [January 28, 2022, 9:36pm UTC](https://discourse.julialang.org/t/do-views-interfere-with-thread-synchronization/75379/5 "2022-01-28T21:36:53Z")

</div>

OK. Here is the code of the M(non)WE:

```julia
module example

using LinearAlgebra
using SparseArrays

struct ThreadBuffer{KVT}
    kcolumns::KVT
    uv::SubArray{Float64, 1, Vector{Float64}, Tuple{UnitRange{Int64}}, true} 
    result::Vector{Float64}
end

function parmul!(R, tbs)
    tasks = [];
    for th in 1:length(tbs)
        tb = tbs[th]
        push!(tasks, Threads.@spawn begin 
            mul!(tb.result, tb.kcolumns, tb.uv)
        end);
    end
    Threads.wait(tasks[1]);
    R .= tbs[1].result
    for th in 2:length(tbs)
        Threads.wait(tasks[th]);
        R .+= tbs[th].result
    end
    R
end

function parloop!(N)
    K = sprand(N, N, 0.1)
    U1 = rand(N)
    R = fill(0.0, N)
    nth = Base.Threads.nthreads()
    @info "$nth threads used"
    chunk = Int(floor(N / nth))
    threadbuffs = ThreadBuffer[];
    for th in 1:nth
        colrange = th < nth ? (chunk*(th-1)+1:chunk*(th)+1-1) : (chunk*(th-1)+1:length(U1))
        push!(threadbuffs, ThreadBuffer(view(K, :, colrange), view(U1, colrange), deepcopy(U1)));
        # push!(threadbuffs, ThreadBuffer(K[:, colrange], view(U1, colrange), deepcopy(U1)));
    end

    R .= parmul!(R, threadbuffs)
    @show norm(R - K*U1)
    true 
end

end # module
nothing

using .example; example.parloop!(10000)

```

---

<div class="post-metadata">

### Author: ![goerch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerch/32/29122_2.png) [@goerch](https://discourse.julialang.org/u/goerch)
#### Post date: [January 28, 2022, 9:40pm UTC](https://discourse.julialang.org/t/do-views-interfere-with-thread-synchronization/75379/6 "2022-01-28T21:40:44Z")

</div>

Interesting. Returns immediately for me with

```julia
[ Info: 5 threads used
norm(R - K * U1) = 2.0796050396124542e-11
true

```

on

```julia
julia> versioninfo()
Julia Version 1.8.0-DEV.1309
Commit 89f23325aa (2022-01-13 19:48 UTC)        
Platform Info:
  OS: Windows (x86_64-w64-mingw32)
  CPU: Intel(R) Core(TM) i7-10710U CPU @ 1.10GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-13.0.0 (ORCJIT, skylake)
Environment:
  JULIA_EDITOR = code
  JULIA_NUM_THREADS = 5

```

---

<div class="post-metadata">

### Author: ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)
#### Post date: [January 28, 2022, 9:42pm UTC](https://discourse.julialang.org/t/do-views-interfere-with-thread-synchronization/75379/7 "2022-01-28T21:42:09Z")

</div>

Correct: That is why it is a non-working example.

---

<div class="post-metadata">

### Author: ![goerch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerch/32/29122_2.png) [@goerch](https://discourse.julialang.org/u/goerch)
#### Post date: [January 28, 2022, 10:17pm UTC](https://discourse.julialang.org/t/do-views-interfere-with-thread-synchronization/75379/8 "2022-01-28T22:17:59Z")

</div>

Code looks fine too me. Only thing I’m wondering: why `deepcopy(U1)` instead of `similar(U1)`?
