@@ -67,10 +67,16 @@ function recurrence_matrix(x::Vector_or_SSSet, y::Vector_or_SSSet, metric::Metri
6767 # multiple threads pushing to the same `Array` (`Array`s are not atomic).
6868 rowvals = [Vector {Int} () for _ in 1 : Threads. nthreads ()]
6969 colvals = [Vector {Int} () for _ in 1 : Threads. nthreads ()]
70+ # Channel to manage `Array`s to be used in each iteration
71+ nbuffers = Threads. nthreads ()
72+ threadchannel = Channel {Int} (nbuffers) # for rows and columns
73+ for i in 1 : nbuffers
74+ put! (threadchannel, i)
75+ end
7076
7177 # This is the same logic as the serial function, but parallelized.
7278 Threads. @threads for j in eachindex (y)
73- threadn = Threads . threadid ( )
79+ threadn = take! (threadchannel )
7480 nzcol = 0
7581 for i in eachindex (x)
7682 @inbounds if evaluate (metric, x[i], y[j]) ≤ ( (ε isa Real) ? ε : ε[j] )
@@ -79,9 +85,12 @@ function recurrence_matrix(x::Vector_or_SSSet, y::Vector_or_SSSet, metric::Metri
7985 end
8086 end
8187 append! (colvals[threadn], fill (j, (nzcol,)))
88+ put! (threadchannel, threadn)
8289 end
83- finalrows = vcat (rowvals... ) # merge into one array
84- finalcols = vcat (colvals... ) # merge into one array
90+ close (threadchannel)
91+
92+ finalrows = reduce (vcat, rowvals) # merge into one array
93+ finalcols = reduce (vcat, colvals) # merge into one array
8594 nzvals = fill (true , (length (finalrows),))
8695 return sparse (finalrows, finalcols, nzvals, length (x), length (y))
8796end
@@ -93,10 +102,16 @@ function recurrence_matrix(x::Vector_or_SSSet, metric::Metric, ε, ::Val{true})
93102 # multiple threads pushing to the same `Array` (`Array`s are not atomic).
94103 rowvals = [Vector {Int} () for _ in 1 : Threads. nthreads ()]
95104 colvals = [Vector {Int} () for _ in 1 : Threads. nthreads ()]
105+ # Channel to manage `Array`s to be used in each iteration
106+ nbuffers = Threads. nthreads ()
107+ threadchannel = Channel {Int} (nbuffers) # for rows and columns
108+ for i in 1 : nbuffers
109+ put! (threadchannel, i)
110+ end
96111
97112 # This is the same logic as the serial function, but parallelized.
98113 Threads. @threads for k in partition_indices (length (x))
99- threadn = Threads . threadid ( )
114+ threadn = take! (threadchannel )
100115 for j in k
101116 nzcol = 0
102117 for i in 1 : j
@@ -107,9 +122,12 @@ function recurrence_matrix(x::Vector_or_SSSet, metric::Metric, ε, ::Val{true})
107122 end
108123 append! (colvals[threadn], fill (j, (nzcol,)))
109124 end
125+ put! (threadchannel, threadn)
110126 end
111- finalrows = vcat (rowvals... ) # merge into one array
112- finalcols = vcat (colvals... ) # merge into one array
127+ close (threadchannel)
128+
129+ finalrows = reduce (vcat, rowvals) # merge into one array
130+ finalcols = reduce (vcat, colvals) # merge into one array
113131 nzvals = fill (true , (length (finalrows),))
114132 return Symmetric (sparse (finalrows, finalcols, nzvals, length (x), length (x)), :U )
115133end
0 commit comments