StableHLO awalnya di-bootstrap dari dialek MHLO, dan mewarisi implementasi MHLO dari inferensi jenis. Kemajuan implementasi dilacak di status.md.
Panduan yang diusulkan di bawah ini dimaksudkan 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 komprehensif.
(P1) Menggunakan spesifikasi StableHLO sebagai sumber kebenaran
spec adalah sumber tepercaya untuk semua pemverifikasi dan fungsi bentuk operasi StableHLO. Pemverifikasi dan fungsi bentuk yang ada dari setiap operasi perlu ditinjau kembali agar sepenuhnya selaras dengan spesifikasi. Perlu diperhatikan 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 tanpa batas, kami 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, TIDAK diperlukan kode verifikasi 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 pada pemverifikasi dan fungsi bentuk
Keduanya:
- pemverifikasi: diterapkan oleh
Op::verify()
, dan - fungsi bentuk: diimplementasikan oleh
InferTypeOpInterface
sepertiOp::inferReturnTypes()
atauOp::inferReturnTypeComponents
mungkin memiliki kode verifikasi untuk memeriksa operand/atribut/hasil. Pemisahan awal mungkin adalah sebagai berikut: Biarkan pemverifikasi memeriksa operand/atribut, lalu biarkan fungsi bentuk hanya menghitung jenis hasil yang ditentukan dan memeriksa kompatibilitasnya terhadap jenis hasil yang sebenarnya. Namun, pada kenyataannya pembagian ini memiliki beberapa masalah:
- Fungsi bentuk dapat dipanggil oleh fungsi
build()
yang dibuat secara otomatis, tanpa memanggil pemverifikasi terlebih dahulu. Jadi input terkait juga harus diverifikasi dalam fungsi bentuk. - Kode duplikat: Misalnya, dalam pemverifikasi, kami melakukan beberapa pemrosesan pada operand, lalu memverifikasi beberapa hasil perantara. Kemudian, hasil menengah ini berguna untuk menyimpulkan hasil akhir dalam fungsi bentuk. Hasil menengah ini harus dihitung dua kali.
- Beban pemeliharaan: Verifikasi pengoperasian dilakukan dalam dua metode yang berbeda.
Solusinya adalah sebagai berikut:
Untuk sebagian besar operasi tanpa region (seperti
PadOp
): Coba masukkan semua kode verifikasi ke dalam fungsi bentuk, dan hapus pemverifikasi sepenuhnya. Jika hal ini tidak memungkinkan karena tidak dapat menyimpulkan jenis nilai yang ditampilkan (seperti denganReshapeOp
atauBroadcastInDimOp
), buat pemverifikasi untuk berisi logika verifikasi yang diperlukan. Operasi yang biasanya dapat disimpulkan, sepertiAddOp
, mungkin masih memerlukan pemverifikasi untuk melakukan verifikasi tambahan, karena memverifikasi batasan dari jenis nilai yang ditampilkan yang disediakan, yang tidak dapat diakses dalam metode inferensi jenis/bentuk.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).Jika region tidak diperlukan untuk inferensi jenis (seperti
ReduceOp
), masukkan logika verifikasi terkait region dalam pemverifikasi, bukan fungsi bentuk. Buat duplikat beberapa kode jika tidak dapat dihindari.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) Menetapkan pedoman pengujian
Apakah kami perlu menambahkan/mempertahankan pengujian untuk verifikasi yang dicakup oleh ODS?
Kami tidak tahu. Pengujian harus berfokus pada pemverifikasi dan fungsi bentuk, sedangkan perubahan pada ODS memerlukan peninjauan kembali terhadap operasi ini.
Namun, berhati-hatilah dengan bagian yang hilang: misalnya, jika op berisi
fitur SameOperandsAndResultShape
, yang hanya memeriksa bentuk, bukan jenis
elemen, verifikasi untuk jenis elemen operand/hasil masih memerlukan
pengujian.
Di mana kita melakukan pengujian untuk pemverifikasi dan inferensi jenis?
ops_stablehlo.mlir berisi kasus positif dari operasi, 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 dari operasi demi baris dengan hlo_test_infer.get_return_type_components"(%x):...
dan memeriksa apakah jenis yang disimpulkan sama 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:
Masukkan semua kasus positif dan kasus negatif di ops_stablehlo.mlir.
Tambahkan satu uji positif di infer_stablehlo.mlir untuk menguji antarmuka.
(Opsional) Jika operasi rumit dan dapat berisi banyak pengujian, pertimbangkan untuk menambahkan file pengujian terpisah bernama
verify_<op_name>.mlir
atauverify_<your_topic>.mlir
dalam folder yang sama.