Asynchronously storing results

I’ve been experimenting with the @sync and @async macros and I need some advice.
Basically, I have some (nested) embarrassingly parallel loops. The issue is, I want to store the calculations from each function call asynchronously. But I’m having some trouble on the storing part.

The following code should exemplify this:

function sleep_ij(i,j)
	res = i^2+j
	sleep(0.1*res)
	return res
end

@time begin
	res = Vector{Float64}(undef, 5)
	res_arr = fill(res, 2)
	@sync for i in 1:2
		@async res_arr[i] = [sleep_ij(i,j) for j in 1:5]
	end
	println(res_arr)
end
# Slow but correct results
# Array{Float64,1}[[2.0, 3.0, 4.0, 5.0, 6.0], [5.0, 6.0, 7.0, 8.0, 9.0]]
#  3.577137 seconds (122.19 k allocations: 6.380 MiB)

@time begin
	res = Vector{Float64}(undef, 5)
	res_arr = fill(res, 2)
	@sync for i in 1:2
		for j in 1:5
			@async res_arr[i][j] = sleep_ij(i,j)
		end
	end
	println(res_arr)
end
# Fast but wrong results
# Array{Float64,1}[[5.0, 6.0, 7.0, 8.0, 9.0], [5.0, 6.0, 7.0, 8.0, 9.0]]
#  0.912431 seconds (12.53 k allocations: 698.873 KiB)

@time begin
	res_arr = []
	@sync for i in 1:2
		for j in 1:5
			@async push!(res_arr, sleep_ij(i,j))
		end
	end
	println(res_arr)
end
# Fast but won't keep order (which is a must)
# Any[2, 3, 4, 5, 5, 6, 6, 7, 8, 9]
#  0.910911 seconds (12.21 k allocations: 684.984 KiB)

Is there any way I can achieve the fastest speeds shown above and at the same time fill my resulting array with the correct values?

Part of the problem is that you should not use fill to create an array of arrays. Each sub-array is a reference to the others. That is why the results are identical in each sub-array.

Is this what you are looking for?

function sleep_ij(i,j)
	res = i^2+j
	sleep(0.1*res)
	return res
end

@time begin
	res_arr = [Vector{Float64}(undef, 5) for _ in 1:2]
	@sync for i in 1:2
		for j in 1:5
			@async res_arr[i][j] = sleep_ij(i,j)
		end
	end
	println(res_arr)
end

Results:

Array{Float64,1}[[2.0, 3.0, 4.0, 5.0, 6.0], [5.0, 6.0, 7.0, 8.0, 9.0]]
  0.922813 seconds (56.22 k allocations: 2.803 MiB)
3 Likes

Oh that went straight over my head when trying to solve this.
Thank you very much @Christopher_Fisher!

1 Like