By: Makie Blog
Re-posted from: https://blog.makie.org/blogposts/v0.21
Updates in Makie version v0.21
By: Makie Blog
Re-posted from: https://blog.makie.org/blogposts/v0.21
Updates in Makie version v0.21
Re-posted from: https://bkamins.github.io/julialang/2024/05/24/probability.html
I have been writing my blog for over 4 years now (without missing a single week).
My first post was on May 10, 2020, you can find it here.
There is a small change in how I distribute my content. Starting from last week I made the repository of my blog public,
so if you find any mistake please do not hesitate to open a Pull Request here.
To celebrate this I decided to go back to my favorite topic – mathematical puzzles.
Today I use a classic coin-tossing game example
The post was written under Julia 1.10.1 and StatsBase.jl 0.34.4, and FreqTables.jl 0.4.6, BenchmarkTools.jl 1.5.0.
Assume Alice and Bob toss a fair coin. Alice wins if after tossing a head (H) tail (T) is tossed, that is we see a HT sequence.
Bob wins if two consecutive heads are tossed, that is we see a HH sequence.
The questions are:
HT was tossed?HH was tossed?Let us try to answer these questions using Julia.
This code simulates the situation when Alice and Bob play together:
function both()
a = rand(('H', 'T'))
while true
b = rand(('H', 'T'))
if a == 'T'
a = b
else
return b == 'H' ? "Bob" : "Alice"
end
end
end
The both function returns "Bob" if Bob wins, and "Alice" otherwise.
From the code it should be already clear that both players have the same probability of winning.
The only way to terminate the simulation is return b == 'H' ? "Bob" : "Alice" and this condition is symmetric
with respect to Alice and Bob. Let us confirm this by running a simulation:
julia> using FreqTables, Random
julia> Random.seed!(1234);
julia> freqtable([both() for _ in 1:100_000_000])
2-element Named Vector{Int64}
Dim1 │
──────┼─────────
A │ 50000012
B │ 49999988
Indeed, the number of times Alice and Bob win seem to be the same.
Now let us check how long, on the average, Alice has to wait to see the HT sequence. Here is Alice’s simulator:
function alice()
a = rand(('H', 'T'))
i = 1
while true
b = rand(('H', 'T'))
i += 1
a == 'H' && b == 'T' && return i
a = b
end
end
Let us check it:
julia> using StatsBase
julia> describe([alice() for _ in 1:100_000_000])
Summary Stats:
Length: 100000000
Missing Count: 0
Mean: 3.999890
Std. Deviation: 2.000032
Minimum: 2.000000
1st Quartile: 2.000000
Median: 3.000000
3rd Quartile: 5.000000
Maximum: 31.000000
Type: Int64
So it seems that, in expectation, Alice finishes her game in 4 tosses.
Can we expect the same for Ben (as we remember – if they play together they have the same chances of finishing first)?
Let us see.
Now let us check how long, on the average, Bob has to wait to see the HH sequence. Here is Bob’s simulator:
function bob()
a = rand(('H', 'T'))
i = 1
while true
b = rand(('H', 'T'))
i += 1
a == 'H' && b == 'H' && return i
a = b
end
end
Let us check it:
julia> describe([bob() for _ in 1:100_000_000])
Summary Stats:
Length: 100000000
Missing Count: 0
Mean: 5.999915
Std. Deviation: 4.690177
Minimum: 2.000000
1st Quartile: 2.000000
Median: 5.000000
3rd Quartile: 8.000000
Maximum: 87.000000
Type: Int64
To our surprise, Bob needs 6 coin tosses, on the average, to see HH.
What is the reason of this difference? Assume we have just tossed H. Start with Bob. If we hit H we finish. If we hit T we then need to wait till we see H again to be able to consider finishing.
However, if we are Alice if we hit T we finish, but if we hit H we do not have to wait for anything – we are already in a state that gives us a chance to finish the game in the next step.
The difference between joint games and separate games is a bit surprising and I hope you found it interesting if you have not seen this puzzle before.
Today I have approached this problem using simulation. However, it is easy to write down a Markov chain representation of all three scenarios and solve them analytically.
I encourage you to try doing this exercise.
PS.
In the code I use the rand(('H', 'T')) form to generate randomness. It is much faster than e.g. writing rand(["H", "T"]) (which would be a first instinct), for two reasons:
Char instead of String is a more lightweight option;Tuple instead of Vector avoids allocations.Let us see a comparison of timing (I cut out the histograms from the output):
julia> using BenchmarkTools
julia> @benchmark rand(('H', 'T'))
BenchmarkTools.Trial: 10000 samples with 1000 evaluations.
Range (min … max): 1.900 ns … 233.700 ns ┊ GC (min … max): 0.00% … 0.00%
Time (median): 2.500 ns ┊ GC (median): 0.00%
Time (mean ± σ): 3.316 ns ± 2.772 ns ┊ GC (mean ± σ): 0.00% ± 0.00%
Memory estimate: 0 bytes, allocs estimate: 0.
julia> @benchmark rand(["H", "T"])
BenchmarkTools.Trial: 10000 samples with 999 evaluations.
Range (min … max): 15.816 ns … 2.086 μs ┊ GC (min … max): 0.00% … 96.30%
Time (median): 19.019 ns ┊ GC (median): 0.00%
Time (mean ± σ): 23.041 ns ± 60.335 ns ┊ GC (mean ± σ): 9.44% ± 3.63%
Memory estimate: 64 bytes, allocs estimate: 1.
In this case we could also just use rand(Bool) (as the coin is fair and has only two states):
julia> @benchmark rand(Bool)
BenchmarkTools.Trial: 10000 samples with 1000 evaluations.
Range (min … max): 1.700 ns … 131.000 ns ┊ GC (min … max): 0.00% … 0.00%
Time (median): 3.200 ns ┊ GC (median): 0.00%
Time (mean ± σ): 3.218 ns ± 2.112 ns ┊ GC (mean ± σ): 0.00% ± 0.00%
Memory estimate: 0 bytes, allocs estimate: 0.
but as you can see rand(('H', 'T')) has a similar speed and leads to a much more readable code.
By: Tim Besard
Re-posted from: https://juliagpu.org/post/2024-05-24-oneapi_1.5/index.html
oneAPI.jl v1.5 is a significant release that brings many new features, from extended hardware support to greatly improved wrappers of the oneMLK math library.
In oneAPI.jl v1.5 we introduce support for the Intel Ponte Vecchio (PVC) architecture, which empowers the Xe HPC GPUs as found in the Aurora supercomputer:
julia> oneAPI.versioninfo()
Binary dependencies:
- NEO: 24.13.29138+0
- libigc: 1.0.16510+0
- gmmlib: 22.3.18+0
- SPIRV_LLVM_Translator_unified: 0.4.0+0
- SPIRV_Tools: 2023.2.0+0Toolchain:
- Julia: 1.10.3
- LLVM: 15.0.71 driver:
- 00000000-0000-0000-17d2-6b1e010371d2 (v1.3.29138, API v1.3.0)16 devices:
- Intel(R) Data Center GPU Max 1550
- Intel(R) Data Center GPU Max 1550
- Intel(R) Data Center GPU Max 1550
- Intel(R) Data Center GPU Max 1550
- Intel(R) Data Center GPU Max 1550
- Intel(R) Data Center GPU Max 1550
- Intel(R) Data Center GPU Max 1550
- Intel(R) Data Center GPU Max 1550
- Intel(R) Data Center GPU Max 1550
- Intel(R) Data Center GPU Max 1550
- Intel(R) Data Center GPU Max 1550
- Intel(R) Data Center GPU Max 1550
- Intel(R) Data Center GPU Max 1550
- Intel(R) Data Center GPU Max 1550
- Intel(R) Data Center GPU Max 1550
- Intel(R) Data Center GPU Max 1550
Apart from a handful of MKL-related issues, oneAPI.jl is fully functional on PVC, and passes all tests.
Thanks to the work of @amontoison, oneAPI.jl now provides greatly improved wrappers of the oneMKL library. This includes support for:
LAPACK: geqrf(_batched), orgqr(_batched), ormqr, potrf(_batched), potrs(_batched), getrf(_batched), getri(_batched), gebrd, gesvd, syevd, heevd, sygvd, hegvd
Sparse arrays: sparse_gemm, sparse_gemv, sparse_symv, sparse_trmv, sparse_trsv, sparse_optimize_gemv, sparse_optimize_trsv
Where possible, these functions are integrated with standard library interfaces, e.g., making it possible to simply call eigen, or to multiply two oneSparseMatrixCSRs.
There have of course been many other changes and improvements in oneAPI.jl v1.5. For a full list, please refer to the release notes, but some highlights include:
a new launch configuration heuristic that should generally improve performance;
broadcast now preserves the buffer type (host, device, or shared);
support for very large arrays that exceed the default device memory limit;
several toolchain bumps, with v1.5 using oneAPI 2024.1.0 with driver 24.13.29138.7;
minimal support for native Windows (next to WSL, which is fully supported).