Inferensi Jenis

StableHLO awalnya di-bootstrap dari dialek MHLO, dan mewarisi implementasi inferensi jenis MHLO. Progres penerapan dilacak di status.md.

Panduan yang diusulkan di bawah ini ditujukan untuk memastikan penerapan pemverifikasi berkualitas tinggi dan fungsi bentuk untuk operasi StableHLO.

Proposal

Proposal ini berlaku untuk meninjau kembali implementasi yang ada dan mencapai operasi baru hingga cakupan yang komprehensif.

(P1) Menggunakan spesifikasi StableHLO sebagai sumber kebenaran

spec adalah sumber kebenaran untuk semua pemverifikasi dan fungsi bentuk operasi StableHLO. Pemverifikasi yang ada dan fungsi bentuk dari setiap operasi perlu ditinjau kembali agar sepenuhnya selaras dengan spesifikasi. Perhatikan bahwa dokumen spesifikasi terus berkembang. Jika spesifikasi untuk operasi tidak tersedia, implementasi XLA harus digunakan sebagai sumber kebenaran, termasuk xla/service/shape_inference.cc dan xla/service/hlo_verifier.cc. Implementasi XLA tidak mencakup dinamisme tak terbatas, jadi untuk dinamisme tak terbatas, kita akan menerapkan akal sehat sampai RFC dinamis tersedia.

(P2) Memaksimalkan ODS

File ODS (seperti StablehloOps.td) menentukan operasi dengan karakteristik dan jenis untuk setiap operand/atribut/hasil, dan akan melakukan verifikasi. Dengan demikian, kode verifikasi TIDAK diperlukan dalam pemverifikasi atau fungsi bentuk untuk properti yang sudah dijamin oleh ODS. Hapus kode verifikasi jika diduplikasi dengan ODS, karena kode tersebut tidak akan pernah dipicu.

Apakah kita perlu menambahkan pengujian untuk batasan dari ODS? Lihat Menetapkan pedoman pengujian.

(P3) Mempertahankan kode verifikasi dalam pemverifikasi dan fungsi bentuk

Keduanya:

  • pemverifikasi: diimplementasikan oleh Op::verify(), dan
  • fungsi bentuk: diimplementasikan oleh InferTypeOpInterface seperti Op::inferReturnTypes() atau Op::inferReturnTypeComponents

mungkin memiliki kode verifikasi untuk memeriksa operand/atribut/results. Pemisahan awal mungkin adalah sebagai berikut: Mengizinkan pemverifikasi memeriksa operand/atribut, lalu mengizinkan fungsi bentuk hanya menghitung jenis hasil yang disimpulkan dan memeriksa kompatibilitas dengan jenis hasil nyata. Namun, pada kenyataannya pemisahan ini memiliki beberapa masalah:

  • Fungsi bentuk dapat dipanggil oleh fungsi build() yang dibuat secara otomatis, tanpa memanggil pemverifikasi terlebih dahulu. Jadi {i>input<i} yang terkait juga harus diverifikasi dalam fungsi bentuk.
  • Kode duplikat: Misalnya, dalam pemverifikasi, kami melakukan beberapa pemrosesan pada operand, lalu memverifikasi beberapa hasil menengah. Kemudian dalam fungsi bentuk, hasil menengah ini berguna untuk menyimpulkan hasil akhir. Hasil menengah ini harus dihitung dua kali.
  • Beban pemeliharaan: Verifikasi operasi terdapat dalam dua metode berbeda.

Solusinya adalah sebagai berikut:

  1. Untuk sebagian besar operasi tanpa region (seperti PadOp): Masukkan semua kode verifikasi ke dalam fungsi bentuk, dan hapus pemverifikasi sepenuhnya.

  2. Untuk operasi dengan region (seperti ReduceOp/IfOp; daftar lengkapnya ada di sini): Builder yang dibuat secara otomatis tidak menggunakan region sebagai parameter, jadi jika builder ini melibatkan inferensi jenis, fungsi bentuk akan dipanggil dengan region kosong (lihat contoh ini).

    1. Jika region tidak diperlukan untuk inferensi jenis (seperti ReduceOp), masukkan logika verifikasi terkait region di pemverifikasi, bukan fungsi bentuk. Buat duplikat beberapa kode jika tidak dapat dihindari.

    2. Jika region diperlukan untuk inferensi jenis (IfOp/CaseOp/MapOp), fungsi bentuk juga harus memverifikasi bahwa region tidak kosong secara eksplisit, meskipun ODS mungkin sudah menjamin keberadaannya dalam definisi Op.

(P4) Membuat pedoman pengujian

Apakah kami perlu menambahkan/mempertahankan pengujian untuk verifikasi yang dicakup oleh ODS?

Kami tidak mengetahuinya. Pengujian harus berfokus pada pemverifikasi dan fungsi bentuk, sedangkan perubahan pada ODS memerlukan peninjauan ulang terhadap operasi ini.

Namun, berhati-hatilah dengan bagian yang hilang: misalnya, jika operasi berisi fitur SameOperandsAndResultShape, yang hanya memeriksa bentuk, tetapi bukan jenis elemen, verifikasi untuk jenis elemen operand/hasil masih memerlukan pengujian.

Di mana kita dapat melakukan pengujian untuk pemverifikasi dan inferensi jenis?

ops_stablehlo.mlir berisi kasus operasi positif, dan (setidaknya) 1 pengujian negatif untuk setiap error verifikasi. Alat ini juga dapat memeriksa apakah jenis nilai yang ditampilkan yang disimpulkan kompatibel dengan (tidak sama dengan) jenis hasil sebenarnya.

infer_stablehlo.mlir memverifikasi keberadaan fungsi bentuk operasi demi baris dengan hlo_test_infer.get_return_type_components"(%x):... dan memeriksa apakah jenis yang disimpulkan cocok persis seperti yang diharapkan. Satu tes positif per operasi secara umum.

Yang harus dilakukan

Saat menerapkan atau meninjau kembali pemverifikasi dan/atau fungsi bentuk operasi:

  1. Masukkan semua kasus positif dan kasus negatif di ops_stablehlo.mlir.

  2. Tambahkan satu pengujian positif di infer_stablehlo.mlir untuk menguji antarmuka.

  3. (Opsional) Jika operasi rumit dan dapat berisi banyak pengujian, pertimbangkan untuk menambahkan file pengujian terpisah bernama verify_<op_name>.mlir atau verify_<your_topic>.mlir dalam folder yang sama.