Asli https://blog.devel.faith/posts/seluler-automata-on-gpu-julia/

Dalam postingan kali ini, kita akan belajar tentang pemrograman GPU dasar & Julia dengan mengkode Game of Life Conway. Anda mungkin ingin mencoba mencari “Conway’s Game of Life” di Google ;).

Apa itu hidup? Tl; versi dr

Untuk setiap iterasi

  • Kurangnya populasi: setiap sel dengan kurang dari 2 tetangganya akan mati
  • Populasi berlebih: sel mana pun yang memiliki lebih dari 3 tetangga akan mati
  • Reproduksi: sel mana pun yang memiliki 3 tetangga pasti akan hidup

Penerapan

Dasar

Menulis kode untuk aturan tersebut cukup sepele. Untuk setiap sel, periksa tetangganya, lalu lakukan sesuatu. Namun, dalam tutorial ini, kami ingin membawa semua logika ke GPU. Banyak operasi pada matriks dapat dilakukan secara efisien secara paralel di GPU. Jadi, daripada menulis simulasi naif dalam CUDA atau OpenCL tingkat rendah, kita bisa memanfaatkan beberapa kode tingkat tinggi dengan berpikir dalam perspektif aljabar linier.

Lilitan

Anda dapat menganggap konvolusi sebagai jendela yang sedang berjalan, ketika kernel (filter) berjalan di suatu wilayah, ia akan menerapkan beberapa jenis fungsi dan membuat nilai baru. Ini banyak digunakan dalam pemrosesan gambar.

Bagaimana cara ini membuat simulasi kita lebih cepat?

Operasi ini tersedia untuk digunakan di sebagian besar perpustakaan aljabar linier. Kita hanya perlu menemukan perpustakaan GPU yang mendukung konvolusi 2D dan kernel yang menghitung jumlah tetangga di sekitar sel.

Jika Anda tidak tahu

Perkalian polinominal di SMA memerlukan operasi sekitar n² (untuk setiap suku, kalikan dengan semua suku dari polinomial lain). Bisakah kita melakukannya dengan lebih baik? Sebenarnya, Anda hanya perlu sekitar n log n operasi dengan fft. Baru-baru ini, sebuah penelitian menunjukkan bahwa kita juga bisa melakukan perkalian bilangan bulat di O(n log n). Tl;dr: konvolusi cenderung lebih cepat daripada loop for biasa.

Kode

using ArrayFire
using LinearAlgebra
let
    kernel = convert(Array{Float32}, [1 1 1; 1 0 1; 1 1 1]) |> AFArray
    state = rand(Bool, 30, 30) .+ Float32(.0) |> AFArray
    step = 30
    for i = 1:step
        nb = convolve2(state, kernel, UInt32(0), UInt32(0))
        a = (nb == 2)
        b = (nb == 3)
        state = ((state .* a .+ b) > 0) + Float32(0)
        save_image(string(i, ".tiff"), state)
    end
end

Untuk memberi gif: convert -scale 2000% -delay 20 -loop 0 *.tiff image.gif