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.
! 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 imageSetiap 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.
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# mengompilasi dan menjalankan program dari direktori topik
gfortran -fcoarray=single dasar_coarray.f90 -o dasar_coarray
./dasar_coarrayjumlah 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] : 42Keluaran 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.
# kompilasi tanpa opsi coarray: sintaks kurung siku ditolak kompiler
gfortran dasar_coarray.f90 -o dasar_coarraydasar_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.
# 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_coarrayApabila 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()danthis_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 allberperan sebagai palang pintu yang menjamin penugasan lintas image sudah terlihat sebelum dibaca.- gfortran menolak sintaks coarray tanpa
-fcoarray=singleatau-fcoarray=lib, menjalankan satu image dengansingle, dan membutuhkan runtime OpenCoarrays (caf,cafrun) untuk eksekusi banyak image.
Referensi#
- Learn: tutorial resmi Fortran — fortran-lang — Kumpulan tutorial resmi komunitas Fortran yang menjadi rujukan fitur bahasa pada jalur ini.
- The GNU Fortran Compiler — GNU Project
— Manual gfortran yang merinci opsi
-fcoarraydan dukungan corank pada kompiler yang dipakai di sini. - OpenCoarrays — Sourcery Institute
— Proyek pustaka runtime coarray yang menyediakan perintah
cafdan peluncurcafrununtuk eksekusi banyak image.