BTW, can anyone explain why it segfaults if one continues increasing the 
number of procs available:

feldt:~/tmp$ julia03 -p 32 test_pfind_colwise.jl
0.05507445327586207
feldt:~/tmp$ julia03 -p 64 test_pfind_colwise.jl
0.035827345999999996
/Users/feldt/feldt/bin/julia03: line 2: 68828 Segmentation fault: 11 
 
/Applications/Julia-0.3.0-prerelease-3e6a6c7bd8.app/Contents/Resources/julia/bin/julia
 
$1 $2 $3 $4 $5 $6 $7 $8 $9

Still a speedup though but not useable if it segfaults... ;)

Cheers,

/Robert

Den måndagen den 7:e juli 2014 kl. 09:40:40 UTC+2 skrev Robert Feldt:
>
> If someone else needs something like this I ended up copying and modifying 
> pmap to suit my needs. I'm sure it can be simplified and shortened but it 
> works.
> Example code below and I get healthy speedups all the way up to 20 procs:
>
> feldt:~/tmp$ julia03 test_pfind_colwise.jl
> 0.5952118622068966
> feldt:~/tmp$ julia03 -p 2 test_pfind_colwise.jl
> 0.3214775730689655
> feldt:~/tmp$ julia03 -p 4 test_pfind_colwise.jl
> 0.1769931201724138
> feldt:~/tmp$ julia03 -p 8 test_pfind_colwise.jl
> 0.10350024568965517
> feldt:~/tmp$ julia03 -p 16 test_pfind_colwise.jl
> 0.07088396200000001
> feldt:~/tmp$ julia03 -p 32 test_pfind_colwise.jl
> 0.05338699896551725
>
> Julia sure is great! :)
>
> Cheers,
>
> Robert
>
> N = 100
> Rows = 3
> MaxValue = 10
>
> @everywhere function fake_slow_condition(x)
>   sleep(0.01)
>   sum(x) == 30 ? x : false # Return x iff it fulfills the poperty
> end
>
> # Similar to Base.findfirst(predicate, A) but process the array "A" 
> columnwise in parallel
> # and opt out of further processing if found. Returns both the index at 
> which found
> # as well as the result returned.
> @everywhere function pfind_colwise(predicate, A)
>   np = nprocs()  # determine the number of processes available
>   n = size(A, 2)
>   i = 1
>   results = Any[false for i in 1:n]
>   found = false
>   wasfound(idx) = found = true
>   isfound() = found
>   # function to produce the next work item from the queue.
>   # in this case it's just an index to a column.
>   nextidx() = (idx=i; i+=1; idx)
>   @sync begin
>     for p=1:np
>       if p != myid() || np == 1
>         @async begin
>           while true
>             idx = nextidx()
>             if idx > n
>               break
>             end
>             results[idx] = remotecall_fetch(p, predicate, A[:,idx])
>             if isfound()
>               break # Someone else already found it
>             end
>             if results[idx] != false
>               wasfound(idx)
>               break # We found it
>             end
>           end
>         end
>       end
>     end
>   end
>   fidx = findfirst((r)->(r != false), results)
>   (fidx, (fidx != 0 ? results[fidx] : nothing))
> end
>
> Reps = 30
> times = zeros(Reps)
>
> for rep in 1:Reps
>   array = ifloor(MaxValue * rand(Rows, N))
>
>   # We will be looking for the first column that sums to 30. Make sure it 
> exists.
>   suma = sum(array, 1)
>   i = findfirst(suma, 30)
>   if i == 0
>     # Put it somewhere around the middle
>     i = ifloor(rand(0.45N:0.55*N))
>     array[:,i] = MaxValue * ones(Int64, Rows, 1)
>   end
>
>   tic()
>     idx, res = pfind_colwise(fake_slow_condition, array)
>   times[rep] = toq()
> end
>
> println(mean(times[2:Reps]))
>

Reply via email to