Suy luận kiểu dữ liệu

Ban đầu, StableHLO được tự khởi động từ phương ngữ MHLO và kế thừa phương thức triển khai MHLO cho quá trình suy luận kiểu dữ liệu. Bạn có thể theo dõi tiến trình triển khai trong status.md.

Những nguyên tắc đề xuất dưới đây là nhằm đảm bảo việc triển khai trình xác minh và hàm hình dạng chất lượng cao cho các hoạt động StableHLO.

Đề xuất

Các đề xuất này áp dụng cho cả việc xem lại các phương pháp triển khai hiện có và đạt được các hoạt động mới cho đến khi có mức độ phù hợp toàn diện.

(P1) Sử dụng thông số kỹ thuật StableHLO làm nguồn đáng tin cậy

spec là nguồn đáng tin cậy cho tất cả trình xác minh và hàm hình dạng của hoạt động StableHLO. Bạn cần xem lại các trình xác minh và hàm hình dạng hiện có của mỗi hoạt động để hoàn toàn khớp với thông số kỹ thuật. Xin lưu ý rằng tài liệu thông số kỹ thuật liên tục thay đổi. Trong trường hợp không có thông số kỹ thuật cho một hoạt động, phương thức triển khai XLA nên được sử dụng làm nguồn đáng tin cậy, bao gồm cả xla/service/shape_inference.ccxla/service/hlo_verifier.cc. Việc triển khai XLA không bao gồm tính động không ràng buộc. Vì vậy, đối với động không ràng buộc, chúng ta sẽ áp dụng theo kiến thức thông thường cho đến khi có RFC động.

(P2) Khai thác tối đa ODS

Tệp ODS (như StablehloOps.td) xác định các hoạt động có đặc điểm và loại cho từng toán hạng/thuộc tính/kết quả và sẽ thực hiện việc xác minh. Do đó, bạn KHÔNG cần mã xác minh trong trình xác minh hoặc hàm hình dạng cho các thuộc tính đã được ODS đảm bảo. Xoá mã xác minh nếu mã trùng lặp với ODS, vì mã này sẽ không bao giờ được kích hoạt.

Chúng ta có cần thêm kiểm thử cho những quy tắc ràng buộc trong ODS không? Vui lòng xem phần Thiết lập nguyên tắc kiểm thử.

(P3) Duy trì mã xác minh trong trình xác minh và hàm hình dạng

Cả hai:

  • trình xác minh: do Op::verify() triển khai và
  • các hàm hình dạng: do các InferTypeOpInterface triển khai như Op::inferReturnTypes() hoặc Op::inferReturnTypeComponents

có thể có mã xác minh để kiểm tra toán hạng/thuộc tính/kết quả. Cách phân tách ban đầu có thể như sau: Cho phép trình xác minh kiểm tra toán hạng/thuộc tính, sau đó cho phép các hàm hình dạng chỉ tính toán kiểu kết quả suy luận và kiểm tra khả năng tương thích với các loại kết quả thực. Tuy nhiên, trên thực tế, việc phân tách này có một vài vấn đề:

  • Các hàm build() được tạo tự động có thể gọi hàm hình dạng mà không cần gọi trình xác minh trước. Vì vậy, các dữ liệu đầu vào có liên quan cũng phải được xác minh trong hàm hình dạng.
  • Mã trùng lặp: Ví dụ: Trong trình xác minh, chúng tôi xử lý một số thao tác rồi xác minh một số kết quả trung gian. Sau đó, trong các hàm hình dạng, các kết quả trung gian này rất hữu ích để dự đoán kết quả cuối cùng. Các kết quả trung gian này phải được tính toán hai lần.
  • Gánh nặng bảo trì: Quy trình xác minh một hoạt động có trong hai phương thức khác nhau.

Giải pháp như sau:

  1. Đối với hầu hết các hoạt động không có khu vực (như PadOp): Hãy cố gắng đưa tất cả mã xác minh vào các hàm hình dạng và loại bỏ hoàn toàn trình xác minh. Trong những trường hợp không thể thực hiện việc này do không thể dự đoán các loại dữ liệu trả về (chẳng hạn như với ReshapeOp hoặc BroadcastInDimOp), hãy tạo một trình xác minh để chứa logic xác minh cần thiết. Các hoạt động thường có thể suy luận (chẳng hạn như AddOp) vẫn có thể cần trình xác minh để xác minh thêm, vì các hoạt động này đang xác minh các quy tắc ràng buộc của một kiểu dữ liệu trả về đã cung cấp. Phương thức này không truy cập được trong các phương pháp suy luận kiểu/hình dạng.

  2. Đối với các hoạt động có khu vực (như ReduceOp/IfOp; danh sách đầy đủ là tại đây): Các trình tạo tự động không lấy vùng làm tham số, vì vậy, nếu các trình tạo này liên quan đến dự đoán kiểu, thì hàm hình dạng sẽ được gọi với các vùng trống (xem ví dụ này).

    1. Nếu không cần các khu vực để suy luận kiểu dữ liệu (như ReduceOp), hãy đặt logic xác minh liên quan đến khu vực vào trình xác minh thay vì các hàm hình dạng. Sao chép một số mã nếu không thể tránh khỏi.

    2. Nếu cần có các khu vực để suy luận kiểu dữ liệu (IfOp/CaseOp/MapOp), thì ngoài ra, hàm hình dạng phải xác minh rằng các khu vực đó không được trống một cách rõ ràng, mặc dù ODS có thể đã đảm bảo sự tồn tại trong định nghĩa Op.

(P4) Thiết lập nguyên tắc thử nghiệm

Chúng tôi có cần bổ sung/duy trì thử nghiệm cho việc xác minh thuộc phạm vi áp dụng của ODS không?

Còn chúng tôi thì không. Các bài kiểm thử nên tập trung vào trình xác minh và hàm hình dạng, trong khi chúng tôi cần xem lại hoạt động này để thay đổi ODS.

Tuy nhiên, hãy cẩn thận với các phần bị thiếu: ví dụ: nếu toán tử chứa đặc điểm SameOperandsAndResultShape, chỉ kiểm tra hình dạng chứ không kiểm tra loại phần tử, thì việc xác minh các loại toán hạng/kết quả của phần tử vẫn cần được kiểm thử.

Chúng tôi đặt thử nghiệm cho trình xác minh và suy luận kiểu ở đâu?

ops_stablehlo.mlir chứa các trường hợp hoạt động dương tính và (ít nhất) 1 kết quả kiểm tra âm tính cho mỗi lỗi xác minh. Công cụ này cũng có thể kiểm tra để đảm bảo rằng kiểu dữ liệu trả về theo dự đoán tương thích với (không giống với!) với kiểu kết quả thực.

infer_stablehlo.mlir xác minh sự tồn tại của hàm hình dạng của một op từng dòng bằng hlo_test_infer.get_return_type_components"(%x):... và kiểm tra để đảm bảo rằng kiểu suy ra khớp chính xác như dự kiến. Một xét nghiệm dương tính cho mỗi hoạt động nói chung.

Việc nên làm

Khi triển khai hoặc truy cập lại trình xác minh và/hoặc chức năng hình dạng của một đối tượng:

  1. Đặt tất cả các trường hợp dương tính và âm tính vào ops_stablehlo.mlir.

  2. Thêm một quy trình kiểm thử dương tính duy nhất trong infer_stablehlo.mlir để kiểm thử giao diện.

  3. (Không bắt buộc) Nếu một hoạt động phức tạp và có thể chứa nhiều kiểm thử, hãy cân nhắc thêm một tệp kiểm thử riêng có tên verify_<op_name>.mlir hoặc verify_<your_topic>.mlir trong cùng một thư mục.