magerton / GenGlobal.jl

Macro generates global, exports get_ and set_ functions

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

GenGlobal

Build Status

Coverage Status

codecov.io

Installing

Clone by running the following, and then package can be imported as usual.

Pkg.clone("https://github.com/magerton/GenGlobal.jl.git", "GenGlobal")

Explanation

@GenGlobal declares expression to be a global variable and generates exported functions set_ and get_ that set the global. Should be used in a module declaration. Thanks to @npfrazier for suggesting how to use global variables in parallel computations.

Example

See example/example.jl and src/TestFunctions/testModule.jl for how to use GenGlobal to (1) update a shared array, (2) compute things based on the values in the Shared Array, and (3) return all the computations. This is useful in problems like dynamic discrete choice models where the inner NFXP loop computes the Emax function / integrated value function in parallel, and the outer loop returns the log-likelihood and its gradient (for which we need the pplus and remote_mapreduce functions).

Other examples

In the module

module mymodule

export dostuff

@GenGlobal myglob1 myglob2

dostuff(i::Int) = myglob1 * i

end
using mymodule

dostuff(1)  # errors out

set_myglob1(1.0)
get_myglob1() == 1.0

dostuff(2) == 2.0
set_myglob1(2.0)
dostuff(4) == 2.0

Example 2

Using @GenGlobal is one way to declare pre-allocated tmpvars for parallel computations. Just make sure to annotate the type of the variables so that the compiler knows what types are being used

module testModule

using GenGlobal
using StatsFuns

@GenGlobal globalx

export pplus, globf

pplus(x...) = broadcast(+, x...)

function globf(i::Int, s::T) where {T}
    y = logsumexp(globalx::Vector{T})
    return (y, fill(y, 2, 2), )
end

end # module end
using Base.Test
using BenchmarkTools
using testModule3

iters = 1:1000

addprocs()
@everywhere begin
    using testModule
    using StatsFuns
    rx = collect(1.:1000.)
    rxmyid = rx * myid()

    # to show that each worker has different variables...
    set_globalx(myid() * collect(1.:1000.))

    function fmyid(i::Int)
        y = logsumexp(rxmyid)
        return (y, fill(y, 2, 2), )
    end
end


# ---------- check on what gets computed ---------

plsemyid = @parallel (pplus) for i=iters
    fmyid(i)
end

gplse = @parallel (pplus) for i=iters
    globf(i, zero(Float64))
end

@show @benchmark mapreduce(fmyid, pplus, iters)

@show @benchmark begin
    @parallel (pplus) for i=iters
        f(i)
    end
end

@show @benchmark begin
    @parallel (pplus) for i=iters
        globf(i, zero(Float64))
    end
end

About

Macro generates global, exports get_ and set_ functions

License:Other


Languages

Language:Julia 100.0%