Mengapa perlu menjembatani

Membingkai pembagian kerja jujur: NumPy tetap untuk orkestrasi, kernel berpindah ke Mojo.

Daftar isi

Program numerik yang nyata jarang ditulis sepenuhnya dalam satu bahasa. Topik ini menguraikan pembagian kerja yang jujur antara Python dan Mojo, yaitu bagian mana yang tetap berjalan di atas NumPy dan bagian mana yang berpindah ke Mojo, beserta mekanisme yang menghubungkan keduanya. Setelah topik ini dibaca, rancangan program campuran dapat disusun dengan pertimbangan yang matang, mulai dari penempatan kernel sampai keputusan mengurangi persilangan antara kedua sisi.

Pembagian kerja yang jujur#

Ekosistem Python memuat pustaka numerik yang matang, dan menulis ulang semuanya di Mojo bukanlah tujuan bahasa ini. Panduan resmi Mojo menyatakan hal tersebut secara langsung, yaitu ekosistem Python memuat banyak pustaka yang berguna, sehingga pustaka yang sudah ada sebaiknya diimpor dan dipanggil, bukan ditulis ulang. Interoperabilitas (interoperability), yakni kemampuan dua bahasa bekerja pada satu program yang sama, menjadi fondasi modul ini. Pemanggilan kode Python dari Mojo berjalan di atas CPython yang sudah ada, sehingga kode Python lama tidak perlu diubah sedikit pun.

Pembagian kerja yang sehat menempatkan setiap tugas pada sisi yang paling cocok. NumPy tetap bertugas merapikan data, menghitung statistik ringkas, dan menyiapkan visualisasi, sedangkan Mojo mengerjakan kernel, yaitu perhitungan inti yang dipanggil berulang kali pada data besar. Tabel berikut merangkum pembagian tersebut.

TugasSisi pelaksanaAlasan
Memuat data dari berkas dan merapikannyaPython dan NumPypembaca berbagai format sudah tersedia
Statistik ringkas dan pemeriksaan hasilPython dan NumPyAPI ringkas dan cukup cepat untuk orkestrasi
Kernel yang dipanggil berulang kaliMojoalur kontrol ketat, SIMD, dan model memori yang terukur
Visualisasi dan pelaporanPythonpustaka visualisasi hidup di ekosistem Python
Python + NumPymemuat dan merapikan datastatistik ringkasvisualisasi dan pelaporanruntime CPythonMojokernel angka murniSIMD dan alur kontrol ketatmemori tanpa salinan tak perluruntime Mojobatas interoparray NumPydipinjam sebagai Spanhasil kembali sebagaiarray NumPy
Pembagian kerja di sekitar batas interop

Diagram di atas menempatkan kedua runtime berdampingan dengan satu batas di tengahnya. Data mengalir dari NumPy ke Mojo sebagai peminjaman buffer, sedangkan hasil kembali dalam bentuk yang langsung dipahami NumPy. Batas itu perlu dilalui sesedikit mungkin, karena setiap persilangan menimbulkan biaya pembungkusan nilai di kedua arah.

Pembagian ini juga berarti sebagian besar kode tetap berupa Python. Kode penghubung yang menyusun panggilan dan menata hasil, sering disebut glue code, tetap ditulis di Python tanpa kehilangan apa pun. Yang berpindah hanyalah bagian yang memang mahal pada setiap iterasi perulangannya, dan bagian itu biasanya kecil dibandingkan keseluruhan program. Dengan demikian, migrasi berlangsung bertahap, satu kernel demi satu kernel, tanpa mengorbankan kode yang sudah teruji.

Dua runtime dalam satu proses#

Mekanisme di balik batas tersebut mudah dinyatakan, tetapi konsekuensinya perlu dipahami. Mojo tidak membawa interpreter Python buatannya, yaitu program yang membaca dan mengeksekusi kode Python, melainkan memuat CPython yang disediakan oleh lingkungan tempat program dijalankan. Versi Python dan paket yang terpasang di lingkungan itu menentukan apa yang dapat diimpor dari Mojo. Dokumentasi resmi menyarankan pengelolaan lingkungan dengan pixi atau uv agar versi Python dan paketnya konsisten, misalnya pixi add "python==3.11" untuk mengunci versi Python dan pixi add numpy untuk menambahkan NumPy pada proyek pixi.

Konsekuensi kedua menyangkut perilaku program. Satu proses Mojo menampung dua runtime sekaligus, yaitu runtime Mojo yang menggerakkan kernel dan CPython yang menggerakkan paket Python. Kedua runtime berbagi nilai melalui pembungkusan, sehingga nilai yang melintas batas dibungkus atau dibongkar pada setiap persilangan. Biaya itu kecil bila panggilan dilakukan sekali saja, tetapi membengkak apabila persilangan terjadi di dalam perulangan yang rapat. Pola yang tepat menyiapkan data sekali, menghitung seluruh kernel di Mojo, lalu mengembalikan hasil sekali saja.

Program pertama di sekitar batas#

Program berikut menampilkan kedua sisi batas dalam satu berkas utuh. NumPy menyediakan data dan satu statistik ringkas, sedangkan perulangan penjumlahan kuadrat dihitung sepenuhnya oleh Mojo tanpa menyentuh Python. Simpan kode berikut sebagai pembagian-kerja.mojo di folder kerja.

mojo pembagian-kerja.mojo
from std.python import Python

def main() raises:
    var np = Python.import_module("numpy")

    # orkestrasi data tetap di sisi NumPy
    var data = np.arange(1, 11)
    print(data)
    print(data.mean())

    # kernel numerik berpindah ke Mojo
    var total = 0.0
    for i in range(10):
        var x = Float64(i + 1)
        total += x * x
    print(total)
bash
# jalankan program pembagian kerja
mojo run pembagian-kerja.mojo
text Keluaran
[ 1  2  3  4  5  6  7  8  9 10]
5.5
385.0

Ketiga baris keluaran berasal dari dua sisi yang berbeda. Baris pertama dan kedua dicetak oleh NumPy, yaitu isi array dari 1 sampai 10 beserta rata-ratanya sebesar 5.5, sehingga orkestrasi data berjalan sepenuhnya di sisi Python. Baris ketiga sebesar 385.0 dihasilkan perulangan Mojo yang menjumlahkan kuadrat bilangan tersebut, dan perulangan itu tidak memanggil Python sama sekali. Kata kunci raises pada main wajib ada karena Python.import_module dapat menghasilkan error. Pola inilah yang dipakai sepanjang modul, yaitu persilangan batas dijaga sesedikit mungkin agar kernel berjalan murni di Mojo.

Ringkasan#

  • NumPy dipertahankan untuk orkestrasi, statistik ringkas, dan visualisasi, sedangkan kernel yang dipanggil berulang kali berpindah ke Mojo.
  • Menulis ulang seluruh pustaka Python di Mojo bukan tujuan bahasa tersebut, karena jembatan resminya mengimpor pustaka Python apa adanya.
  • Mojo memuat CPython dari lingkungan tempat program dijalankan, sehingga paket yang tersedia bagi Mojo ditentukan oleh lingkungan Python tersebut.
  • Program campuran yang sehat meminimalkan persilangan batas, yaitu data disiapkan sekali, kernel dihitung sepenuhnya di Mojo, dan hasil dikembalikan sekali.

Referensi#