Dasar-dasar coarray

Image, deklarasi coarray dengan codim, dan pernyataan sync sebagai model paralelisme SPMD bawaan bahasa.

Daftar isi

Coarray adalah model paralelisme yang menjadi bagian bahasa Fortran sejak standar 2008, berbentuk data array yang dapat diakses lintas salinan program dengan sintaks tanda kurung siku. Topik ini membahas model eksekusinya yang disebut SPMD, deklarasi coarray dengan codimension, fungsi this_image() dan num_images(), sinkronisasi dengan sync all, serta cara mengompilasi dan menjalankannya pada gfortran. Setelah topik ini selesai dibaca, program coarray sederhana dapat ditulis, dikompilasi, dan dijalankan, lengkap dengan pemahaman mengapa keluarannya hanya menampilkan satu image pada lingkungan contoh modul ini.

Model SPMD dan image#

Coarray mengikuti model SPMD (single program, multiple data), yaitu satu sumber program yang sama dijalankan secara serentak sebagai beberapa salinan, dan setiap salinan bekerja pada data miliknya sendiri. Setiap salinan itu disebut image, yang merupakan unit eksekusi coarray dengan nomor berurutan mulai dari satu. Fungsi num_images() mengembalikan jumlah image yang berjalan, sedangkan this_image() mengembalikan nomor image yang sedang mengeksekusi pernyataan tersebut.

Karena satu sumber program dipakai bersama, percabangan berdasarkan this_image() menjadi cara baku untuk memberi tugas yang berbeda pada setiap image. Model SPMD berbeda dari model thread pada OpenMP yang dibahas pada topik Direktif OpenMP di modul ini, karena antar-image tidak berbagi memori yang sama dan setiap image memiliki ruang data tersendiri. Komunikasi antar image dilakukan secara eksplisit melalui rujukan coarray, yang dibahas lebih rinci pada topik Komunikasi coarray.

Deklarasi coarray dengan codimension#

Sebuah variabel menjadi coarray apabila deklarasinya diakhiri spesifikasi dalam tanda kurung siku. Pada integer :: kode[*], bagian [*] disebut codimension, yaitu dimensi tambahan yang tersebar di seluruh image, sedangkan tanda bintang menyatakan batas atas yang ditentukan oleh jumlah image pada saat program berjalan. Variabel tanpa kurung siku tetap merupakan variabel lokal, dan setiap image memiliki salinan pribadinya masing-masing.

fortran Contoh: variabel lokal, coarray skalar, dan coarray array
! tidak-dijalankan
integer :: kode            ! variabel lokal milik setiap image
integer :: kode_co[*]      ! coarray skalar, satu nilai per image
real    :: potongan(4)[*]  ! coarray array, empat elemen per image

Setiap image selalu dapat membaca dan menulis salinan lokalnya dengan nama variabel biasa, sedangkan salinan milik image lain dirujuk dengan nomor image di dalam kurung siku, misalnya kode[1]. gfortran saat ini mendukung corank satu, yaitu coarray dengan satu codimension, sehingga bentuk [*] yang dipakai pada seluruh contoh modul ini sudah mencakup dukungan yang tersedia.

Program dasar_coarray#

Program berikut menampilkan identitas image, menugaskan nilai ke salinan lokal, menyinkronkan seluruh image, lalu membaca salinan milik image 1 melalui rujukan jarak jauh (remote reference). Program dikompilasi dengan -fcoarray=single dan dijalankan dari direktori topik, dan blok di bawahnya adalah keluaran asli dari eksekusi tersebut.

fortran dasar_coarray.f90
program dasar_coarray
  implicit none
  integer :: kode[*]
  integer :: nilai(4)[*]
  integer :: i

  print '(A, I0)', 'jumlah image (num_images())   : ', num_images()
  print '(A, I0)', 'nomor image ini (this_image()): ', this_image()

  kode = 42 * this_image()
  nilai = [(this_image() * 10 + i, i = 1, 4)]
  sync all

  print '(A, I0)  ', 'kode salinan image ini        : ', kode
  print '(A, 4I4) ', 'nilai salinan image ini       : ', nilai
  print '(A, I0)  ', 'kode image 1 lewat kode[1]    : ', kode[1]
end program dasar_coarray
bash
# mengompilasi dan menjalankan program dari direktori topik
gfortran -fcoarray=single dasar_coarray.f90 -o dasar_coarray
./dasar_coarray
text Keluaran
jumlah image (num_images())   : 1
nomor image ini (this_image()): 1
kode salinan image ini        : 42
nilai salinan image ini       :   11  12  13  14
kode image 1 lewat kode[1]    : 42

Keluaran di atas menampilkan num_images() bernilai 1 karena gfortran menjalankan program ini sebagai satu image tunggal. Penugasan kode = 42 * this_image() menghasilkan 42 pada image 1, perulangan implisit di dalam [(this_image() * 10 + i, i = 1, 4)] mengisi nilai dengan 11 sampai 14, dan rujukan kode[1] membaca salinan image 1 yang pada eksekusi ini sama dengan salinan lokal. Semua konstruksi coarray tetap tereksekusi sungguhan, hanya saja jumlahnya satu image.

Sinkronisasi dengan sync all#

Pernyataan sync all menyinkronkan seluruh image, dan perilakunya mirip palang pintu (barrier), yaitu image yang lebih dulu mencapai pernyataan tersebut menunggu hingga semua image lain mencapainya juga. Sinkronisasi itu menjamin bahwa penugasan yang dilakukan sebelum sync all sudah selesai dan terlihat oleh rujukan jarak jauh yang dieksekusi sesudahnya. Tanpa palang pintu, satu image dapat membaca variabel milik image lain pada saat nilainya belum ditulis, dan hasilnya menjadi tidak dapat diprediksi.

Pada eksekusi satu image, sync all tidak mengubah apa pun secara kasat mata karena hanya ada satu peserta, tetapi pernyataannya tetap wajib ditulis agar program tetap benar ketika dijalankan dengan banyak image. Kebiasaan yang baik adalah menempatkan sync all pada titik yang sama di seluruh image, sebagaimana dilakukan program di atas, supaya urutan penulisan dan pembacaan lintas image selalu terjaga.

Mengompilasi dan menjalankan dengan gfortran#

Opsi -fcoarray pada gfortran menerima tiga nilai, yaitu none, single, dan lib. Nilai bawaannya adalah none, sehingga sintaks kurung siku ditolak apabila opsi itu tidak diberikan, sebagaimana diperlihatkan eksekusi berikut.

bash
# kompilasi tanpa opsi coarray: sintaks kurung siku ditolak kompiler
gfortran dasar_coarray.f90 -o dasar_coarray
text Keluaran
dasar_coarray.f90:3:19:

    3 |   integer :: kode[*]
      |                   1
Fatal Error: Coarrays disabled at (1), use ‘-fcoarray=’ to enable
compilation terminated.

Opsi -fcoarray=single mengaktifkan sintaks coarray dengan satu image, dan inilah yang dipakai pada seluruh contoh modul ini sehingga num_images() selalu bernilai 1. Opsi -fcoarray=lib menautkan program ke pustaka runtime coarray yang mendukung banyak image, tetapi runtime itu tidak disertakan gfortran, sehingga penautan gagal bila pustakanya belum terpasang.

bash
# tidak-dijalankan
# membangun dan menjalankan dua image membutuhkan OpenCoarrays (caf, cafrun)
# yang tidak terpasang pada sandbox contoh
caf dasar_coarray.f90 -o dasar_coarray
cafrun -np 2 ./dasar_coarray

Apabila OpenCoarrays terpasang, cafrun -np 2 meluncurkan program sebagai dua image, sehingga num_images() bernilai 2, this_image() bernilai berbeda pada setiap salinan, dan urutan cetakan antar image tidak dapat dipastikan lebih dahulu.

Ringkasan#

  • Coarray mengikuti model SPMD, yaitu satu sumber program yang dijalankan sebagai banyak image, dengan num_images() dan this_image() sebagai sarana mengenali jumlah dan nomor image.
  • Tanda kurung siku pada deklarasi menyatakan codimension, salinan lokal diakses dengan nama variabel biasa, dan salinan image lain dirujuk dengan kode[1].
  • sync all berperan sebagai palang pintu yang menjamin penugasan lintas image sudah terlihat sebelum dibaca.
  • gfortran menolak sintaks coarray tanpa -fcoarray=single atau -fcoarray=lib, menjalankan satu image dengan single, dan membutuhkan runtime OpenCoarrays (caf, cafrun) untuk eksekusi banyak image.

Referensi#