Pemilihan proyek

Memilih lingkup proyek akhir: sebuah custom op atau pustaka kernel tensor kecil.

Daftar isi

Modul Pengerjaan proyek menutup jalur ini dengan pekerjaan nyata, dan topik ini menetapkan langkah pertamanya, yaitu pemilihan lingkup proyek. Lingkup yang ditetapkan di muka menentukan bentuk API, cara pemeriksaan kebenaran, dan cara pengukuran kinerja pada langkah-langkah sesudahnya. Topik ini membahas dua bentuk proyek yang lazim untuk Mojo, kriteria yang memisahkan lingkup yang sehat dari lingkup yang menumpuk kerumitan, serta keputusan proyek yang dipakai sepanjang modul ini. Pada akhir topik, kernel pertama proyek sudah berjalan dan keluarannya dapat diperiksa ulang.

Dua bentuk proyek yang lazim#

Proyek penutup untuk bahasa dengan inti komputasi cepat lazimnya berupa salah satu dari dua bentuk. Bentuk pertama adalah custom op, yaitu operasi kustom yang didaftarkan ke graf eksekusi platform MAX sehingga dapat dipanggil dari alur kerja pemodelan yang lebih besar. Bentuk kedua adalah pustaka kernel kecil, yaitu kumpulan fungsi komputasi yang berdiri sendiri hanya dengan Mojo dan dipanggil langsung dari program penggunanya. Keduanya menghasilkan kode komputasi yang sama tujuannya, tetapi lingkungan kerja yang dituntut keduanya berbeda.

AspekCustom opPustaka kernel kecil
InfrastrukturPlatform MAX beserta graf eksekusinyaBerkas .mojo dan perintah mojo run
Pengukuran kinerjaMelalui alur eksekusi platformLangsung dengan pengukur waktu Mojo
Lingkup kodeKontrak op beserta pendaftarannyaFungsi kernel dan program ujinya
Cocok untukIntegrasi ke alur pemodelanBelajar desain API dan pengukuran

Custom op menuntut pemahaman platform MAX yang berada di luar bahasa Mojo itu sendiri, sehingga pengerjaannya menyertakan konfigurasi yang tidak muncul pada kode kernelnya. Pustaka kernel kecil menyisakan pekerjaan inti yang sama, yaitu penulisan kernel, desain API, dan pengukuran, tanpa lapisan infrastruktur tambahan. Untuk proyek penutup jalur ini, bentuk kedua yang dipilih karena seluruh perkakasnya sudah tersedia di mesin pengerjaan dan setiap keputusan desainnya dapat diuji dengan mojo run.

Kriteria lingkup yang sehat#

Lingkup yang sehat memenuhi empat kriteria yang saling menguatkan. Kriteria tersebut menjadi alat penilaian sebelum satu baris kernel ditulis, karena lingkup yang keliru baru terasa mahal ketika pemeriksaan dan pengukuran sudah berjalan.

  1. Satu sasaran komputasi per kernel. Kernel menerima data numerik yang siap hitung dan mengembalikan hasil perhitungannya, tanpa pembacaan berkas dan tanpa pencetakan di dalam body-nya.
  2. Data satu dimensi dan kontigu. Buffer satu dimensi yang tersusun berurutan di memori cocok dengan tipe Span dan jembatan NumPy yang digunakan modul ini, sehingga struktur data yang lebih rumit tidak perlu ditangani sejak awal.
  3. Hasil yang deterministik. Kernel yang sama pada data yang sama wajib menghasilkan nilai yang sama, sehingga kebenarannya dapat diperiksa lewat perbandingan langsung dan bukan lewat pengamatan kasar.
  4. Baseline pembanding yang tersedia. Baseline adalah titik pembanding kinerja yang sudah mapan, dan NumPy tersedia sebagai baseline untuk komputasi array numerik pada banyak mesin.

Dengan keempat kriteria itu, proyek modul ini ditetapkan sebagai pustaka kernel statistik kecil untuk data nilai ujian. Pustakanya berisi tiga kernel, yaitu jumlah untuk menjumlahkan seluruh nilai, rata_kuadrat untuk rata-rata kuadrat yang menjadi bahan perhitungan varians, dan skala untuk mengalikan seluruh elemen dalam satu buffer. Ranah nilai ujian dipilih karena netral, angkanya mudah dihitung ulang dengan tangan, dan rentang nilainya wajar untuk data pecahan maupun bulat. Data sasarannya sepuluh nilai ujian dengan rentang 0 sampai 100, cukup kecil untuk diperiksa dan cukup besar untuk menguji pola perulangan vektor.

Kernel pertama#

Program pertama proyek memuat kernel jumlah dalam bentuk paling konkret, yaitu tipe tetap Float64 dan lebar vektor tetap empat. Konkret pada draf pertama bukan kelemahan, melainkan cara menjaga kebenaran: kesalahan desain terlihat pada satu kasus sebelum parameter compile-time ditambahkan.

mojo jumlah-awal.mojo
# Draf pertama pustaka statistik: kernel jumlah untuk nilai ujian
comptime LEBAR = 4

def jumlah(data: List[Float64]) -> Float64:
    var total: Float64 = 0.0
    var i = 0
    while i + LEBAR <= len(data):
        var potongan = SIMD[DType.float64, LEBAR](
            data[i], data[i + 1], data[i + 2], data[i + 3]
        )
        total += potongan.reduce_add()
        i += LEBAR
    while i < len(data):
        total += data[i]
        i += 1
    return total

def main():
    var nilai: List[Float64] = [
        80.0, 75.0, 90.0, 85.0, 70.0, 88.0, 92.0, 79.0, 81.0, 65.0
    ]
    print(jumlah(nilai))
bash
# jalankan draf pertama kernel jumlah
mojo run jumlah-awal.mojo
text Keluaran
805.0

Keluaran 805.0 adalah jumlah sepuluh nilai ujian pada main, dan angka itu dapat dihitung ulang dengan tangan sebagai pemeriksaan pertama. Kernel jumlah memakai pola dua fase yang lazim untuk perulangan SIMD, yaitu fase potongan penuh dengan kondisi i + LEBAR <= len(data) dan fase ekor skalar untuk sisa elemen. Konstanta comptime LEBAR = 4 memberi nama lebar pada satu tempat sehingga perubahan lebar cukup dilakukan sekali. Kernel menerima List[Float64] tanpa kata kunci konvensi argumen apa pun, yang berarti datanya dipinjam secara baca saja sesuai konvensi bawaan bahasa ini.

Draf ini sengaja belum berparameter dtype maupun lebar dan belum memakai tampilan buffer, sehingga desain API-nya masih dapat diubah tanpa menyentuh logika perhitungannya. Pola perhitungan yang sudah benar pada satu tipe menjadi acuan ketika versi terparameternya ditulis, karena perubahan yang tersisa hanya pada signature dan cara memuat data ke vektor.

Kesalahan umum#

  • Menggabungkan pembacaan data dan komputasi dalam satu kernel. Kernel yang membaca berkas atau mencetak di dalam body-nya tidak dapat diukur terpisah, karena waktu pembacaan bercampur dengan waktu perhitungan. Perbaikannya adalah menyerahkan data siap hitung ke kernel dan menangani masukan serta keluaran di luar kernel.
  • Memilih sasaran yang hasilnya tidak deterministik. Kernel dengan urutan penjumlahan yang berubah-ubah menyulitkan pemeriksaan kebenaran, karena hasilnya tidak dapat dibandingkan dengan nilai yang dihitung ulang. Perbaikannya adalah memulai dari kernel reduksi dengan urutan penjumlahan yang tetap.
  • Merencanakan data multidimensi sejak awal. Struktur bertingkat menambah kerumitan pengindeksan sebelum inti komputasinya teruji. Perbaikannya adalah menuntaskan data satu dimensi kontigu terlebih dahulu, karena struktur lebih tinggi dapat dibangun di atasnya sesudahnya.

Ringkasan#

  • Lingkup proyek akhir ditetapkan sebagai pustaka kernel kecil yang berdiri sendiri hanya dengan Mojo, bukan custom op yang menuntut platform MAX.
  • Empat kriteria lingkup yang sehat: satu sasaran komputasi per kernel, data satu dimensi kontigu, hasil deterministik, dan baseline pembanding yang tersedia.
  • Proyek modul ini adalah pustaka statistik untuk data nilai ujian dengan kernel jumlah, rata_kuadrat, dan skala.
  • Draf pertama jumlah memakai pola dua fase potongan SIMD dan ekor skalar dengan lebar tetap empat, dan keluarannya 805.0 terverifikasi.

Referensi#