<jupyter_start><jupyter_text>Table of Contents 1&nbsp;&nbsp;This is a short demo of Julia1.1&nbsp;&nbsp;Hello world1.2&nbsp;&nbsp;A simple math example1.3&nbsp;&nbsp;Text cells1.4&nbsp;&nbsp;More about the JIT compilation aspect1.4.1&nbsp;&nbsp;Low-level code1.4.2&nbsp;&nbsp;LLVM bytecode1.4.3&nbsp;&nbsp;Native assembly code1.5&nbsp;&nbsp;End of demo  This is a short demo of Julia > To learn more, check the [Julia documentation](https://docs.julialang.org/)!   Hello world<jupyter_code>println("Hello from Julia + Jupyter!")<jupyter_output>Hello from Julia + Jupyter!<jupyter_text>A simple math example$$\text{For } x \in\mathbb{R}^{n,n}, \text{ can we check that } \;\; iFFT(FFT(x)) = x \; ?$$<jupyter_code>x = rand(10, 10)  # uniform in [0,1]^{10,10}
fft(x)
ifft(fft(x))<jupyter_output><empty_output><jupyter_text>It's complex? Let's take its real part!<jupyter_code>res = real(ifft(fft(x)))
res == x<jupyter_output><empty_output><jupyter_text>Still not $= x$ ? Maybe numeric error?<jupyter_code>norm(round.(res - x, 14)) == 0<jupyter_output><empty_output><jupyter_text>Ahh, done!  Text cells And this is the Jupyter notebook!With math inside $$\cos(x)^2 + \sin(x)^2 = 1 ?$$ And text formatted in **Markdown**, *an easy markup language*!- list- list[link](http://exemple.com/) ---- More about the JIT compilation aspectThis part is more technical. For a reference, see [this page on the documentation](https://docs.julialang.org/en/stable/devdocs/reflection/Intermediate-and-compiled-representations-1) or [this StackOverflow question](https://stackoverflow.com/questions/43453944/what-is-the-difference-between-code-native-code-typed-and-code-llvm-in-julia).Let's study a simple numerical function for the example, the [Gauss-Legendre formula](https://en.wikipedia.org/wiki/Gauss%E2%80%93Legendre_algorithm) to compute digits of $\pi$:<jupyter_code>function gauss_legendre(max_step)
    a = 1.0
    b = 1.0 / sqrt(2)
    t = 1.0 / 4.0
    p = 1.0
    for i in 1:max_step
        at = (a + b) / 2.0
        bt = sqrt(a * b)
        tt = t - p*(a-at)^2
        pt = 2.0 * p
        a, b, t, p = at, bt, tt, pt
    end
    return ((a + b)^2) / (4.0 * t)
end<jupyter_output><empty_output><jupyter_text>It is an efficient method with converges very quickly to $\pi$:<jupyter_code>println(gauss_legendre(0))
println(gauss_legendre(1))
println(gauss_legendre(2))
println(gauss_legendre(10))
println(pi)<jupyter_output>2.914213562373095
3.1405792505221686
3.141592646213543
3.141592653589794
π = 3.1415926535897...<jupyter_text>Low-level code Let's explore the code in a low-level format but without optimization, using the [`@code_lowered`](https://docs.julialang.org/en/stable/stdlib/base/Base.@code_lowered) decorator.It's still readable:<jupyter_code>@code_lowered gauss_legendre(10)<jupyter_output><empty_output><jupyter_text>LLVM bytecode Then we can have a look at the [LLVM](http://llvm.org/) [bytecode](https://en.wikipedia.org/wiki/Bytecode), using the [`@code_llvm`](https://docs.julialang.org/en/stable/stdlib/base/Base.@code_llvm) decorator.We see a lot of `i64` tags, they are reference to 64-bits integer.<jupyter_code>@code_llvm gauss_legendre(10)<jupyter_output>define double @julia_gauss_legendre_61242(i64) #0 !dbg !5 {
top:
  %1 = icmp slt i64 %0, 1
  br i1 %1, label %L33, label %if.preheader

if.preheader:                                     ; preds = %top
  br label %if

if:                                               ; preds = %if.preheader, %pass2
  %p.sroa.0.015 = phi i64 [ %17, %pass2 ], [ 4607182418800017408, %if.preheader ]
  %t.sroa.0.014 = phi double [ %15, %pass2 ], [ 2.500000e-01, %if.preheader ]
  %b.sroa.0.013 = phi double [ %10, %pass2 ], [ 0x3FE6A09E667F3BCC, %if.preheader ]
  %a.sroa.0.012 = phi double [ %8, %pass2 ], [ 1.000000e+00, %if.preheader ]
  %"#temp#.011" = phi i64 [ %9, %pass2 ], [ 1, %if.preheader ]
  %2 = fmul double %a.sroa.0.012, %b.sroa.0.013
  %3 = fcmp uge double %2, 0.000000e+00
  br i1 %3, label %pass2, label %fail1

L12.L33_crit_edge:                                ; preds = %pass2
  %phitmp = fmul double %15, 4.000000e+00
  br label %L33

L33:                                              ; preds = %L[...]<jupyter_text>Native assembly code Finally we can look at the assembly native code generated *on the fly* by the JIT compiler of Julia, using the [`@code_native`](https://docs.julialang.org/en/stable/stdlib/base/Base.@code_native) decorator.Such assembly code is hard to write by yourself but one can still understand what it does:<jupyter_code>@code_native gauss_legendre(10)<jupyter_output>.text
Filename: In[21]
	movabsq	$139946325965352, %rcx  # imm = 0x7F47CB0BFA28
	movabsq	$139946325965360, %rdx  # imm = 0x7F47CB0BFA30
Source line: 6
	testq	%rdi, %rdi
	jle	L168
	movabsq	$4607182418800017408, %rax # imm = 0x3FF0000000000000
	movsd	(%rdx), %xmm5           # xmm5 = mem[0],zero
	movsd	(%rcx), %xmm2           # xmm2 = mem[0],zero
	movabsq	$139946325965368, %rcx  # imm = 0x7F47CB0BFA38
	movsd	(%rcx), %xmm1           # xmm1 = mem[0],zero
Source line: 8
	xorps	%xmm3, %xmm3
	movabsq	$139946325965376, %rcx  # imm = 0x7F47CB0BFA40
	movsd	(%rcx), %xmm4           # xmm4 = mem[0],zero
	nop
L80:
	movapd	%xmm5, %xmm6
	mulsd	%xmm2, %xmm6
	ucomisd	%xmm6, %xmm3
	ja	L193
Source line: 7
	addsd	%xmm5, %xmm2
	movapd	%xmm2, %xmm0
	mulsd	%xmm4, %xmm0
Source line: 8
	xorps	%xmm2, %xmm2
	sqrtsd	%xmm6, %xmm2
Source line: 9
	subsd	%xmm0, %xmm5
	mulsd	%xmm5, %xmm5
	movd	%rax, %xmm6
	mulsd	%xmm6, %xmm5
	subsd	%xmm5, %xmm1
Source line: 10
	addsd	%xmm6, %xmm6
	movd	%xmm6, %rax
Source line: 6
	decq	%[...]<jupyter_text>We can see the different steps in Julia's compiler, from a high-level Julia code to a low-level assembly code that is compiled to native code and executed at optimal speed.**All this happens automatically** when using any Julia function:<jupyter_code>@time gauss_legendre(10)<jupyter_output>0.000008 seconds (85 allocations: 6.451 KiB)
{'fraction_non_alphanumeric': 0.13936224059389235, 'fraction_numerical': 0.08554074573983465, 'mean_word_length': 3.9731543624161074, 'pattern_counts': {'":': 0, '<': 36, '<?xml version=': 0, '>': 37, 'https://': 8, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 1, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '10', 'dir': 'jupyter-structured-clean-dedup', 'id': '541184', 'license': 'MIT', 'n_tokens_mistral': 2665, 'n_tokens_neox': 2341, 'n_words': 566, 'path': '2018_06__Julia_my_new_optimization_friend__introduction_for_MATLAB_users__at_IETR_seminar/demo.ipynb', 'repo_name': 'pierre-haessig/slides', 'size': '5927'}