@distributed macro in Float64 instead of Float32

I have the following code in Julia 1.1:

using Pkg; Pkg.activate(".")
using Distributed
using Distributions
addprocs(3, exeflags="--project=.")
@everywhere using Distributions

samples=map(x->sample(1:5,5),1:5)
prop=(@distributed (+) for  j=1:length(samples)
    Int32.(samples[j].==samples[j]')
end) / length(samples)

How can I ensure that prop comes in Float32 format? Specifying Int32 inside of the loop isn’t enough. I tried

prop=Float32.((@distributed (+) for  j=1:length(samples)
    Int32.(samples[j].==samples[j]')
end) / length(samples))

but it doesn’t work… I get the error syntax: expected ")".

I think that the simplest way to achieve what you want is the following:

prop = (@distributed (+) for  j=1:length(samples)
        Int32.(samples[j].==samples[j]')
        end) / Float32(length(samples))

which yields:

5×5 Array{Float32,2}:
 1.0  0.2  0.0  0.2  0.4
 0.2  1.0  0.2  0.2  0.4
 0.0  0.2  1.0  0.0  0.0
 0.2  0.2  0.0  1.0  0.0
 0.4  0.4  0.0  0.0  1.0



For a more detailed answer, the solution you tried is essentially equivalent to:

julia> num = @distributed (+) for  j=1:length(samples)
           Int32.(samples[j].==samples[j]')
       end
5×5 Array{Int32,2}:
 5  1  0  1  2
 1  5  1  1  2
 0  1  5  0  0
 1  1  0  5  0
 2  2  0  0  5

julia> prop=Float32.(num / length(samples))
5×5 Array{Float32,2}:
 1.0  0.2  0.0  0.2  0.4
 0.2  1.0  0.2  0.2  0.4
 0.0  0.2  1.0  0.0  0.0
 0.2  0.2  0.0  1.0  0.0
 0.4  0.4  0.0  0.0  1.0

This does work, but:

  • num is an array of Int32 and length(samples) is an Int64 so that their quotient is promoted to Float64 by default, and then converted manually back to Float32. This is a bit wasteful IMHO (but it probably does not really matter; it’s more a question of principles)

  • if you put this computation in one expression (like you tried) instead of splitting it into two (like I did above), you get a syntax error because the parser gets confused between macro call syntax (@mymacro arg1 arg2) and function call syntax (myfunction(arg1, arg2)). Everything could be made to work in one expression by using explicit parentheses for the macro call as well:

prop = Float32.(
         @distributed(+, for  j=1:length(samples)
                           Int32.(samples[j].==samples[j]')
                         end) / length(samples))
2 Likes

Thank you! I just misplaced the Float32 then :slight_smile: Your detailed explanation is also a treasure! In my original version, I had the 2 codes separated: one for the sum and one for the division. I tried to combine both and that’s what motivated my question :slight_smile: You last post explains the expected ")" I got :wink: