ניב VHLO

מה זה ניב VHLO?

דיאלקט VHLO (הגרסה היציבה של הגרסה היציבה) משמש לעריכה בסדרה וליציבות. הוא מספק תמונת מצב של הניב StableHLO בנקודת זמן נתונה, באמצעות גרסאות שונות של התוכנה.

VHLO הוא דיאלקט של הוספה בלבד שיש לו פעולות, סוגים ומאפיינים בגרסאות. כלומר, אחרי שמוסיפים פיצ'ר לדיאלקט, אי אפשר לשנות אותה בשום צורה שמשפיעה על הסמנטיקה.

כדי לבצע שינויים בפעולה, בסוג או במאפיין, צריך להוסיף גרסה חדשה לדיאלקט. לדוגמה, אם מוסיפים my_op היפותטי ל-StableHLO ב-0.9.0 אבל משנים אותו ב-0.11.0, יתקבלו הערכים הבאים ב-VHLO:

// This represents the StableHLO version of the op from 0.9.0 -> 0.10.0
// Both the lower and the upper bound of versions are inclusive
def VHLO_MyOpV1 : VHLO_Op<"my_op_v1", "0.9.0", "0.10.0"> {
  let arguments = (ins
    VHLO_AnyType:$operand
  );
  let results = (outs VHLO_AnyType:$result);
}

// This represents the StableHLO version of the op from 0.11.0 -> current
def VHLO_MyOpV2 : VHLO_Op<"my_op_v2", "0.11.0", "current"> {
  let arguments = (ins
    VHLO_AnyType:$operand,
    VHLO_AnyAttr:$attr  // New attribute added to StableHLO in 0.11.0
  );
  let results = (outs VHLO_AnyType:$result);
}

בדיאלקט StableHLO קיימת רק הגרסה העדכנית ביותר של הפעולות. בדוגמה הנוכחית, בדיאלקט של StableHLO בגרסה 0.11.0 יהיו רק StableHLO_MyOp עם operand ו-attr, ו-VHLO מתעד כל שלב בהתפתחות של הפעולה.

למה VHLO שימושי?

הדיאלקט של הגרסה מאפשרת לנו להתמקד בגרסאות קודמות של אותה פעולה. המדד הזה כולל תאימות קדימה ואחורה בהמרות בין פעולות בדיאלקט של VHLO.

תאימות העברה: תאימות העברה מתאפשרת על ידי המרה ל-VHLO ושדרוג לאחור של הפעולות לגרסת יעד. אם אפשר לשדרג כל פעולה/סוג/פרמטר בתוכנית VHLO לגרסת היעד, מובטח שתהיה אפשרות לבצע פעולת deserial SDK וניתן להמיר אותו לגרסה StableHLO של לקוח עם גרסה שהיא גדולה יותר מגרסת היעד או שווה לה, כי ל-VHLO יש תמונת מצב של אותה המצב באותו הזמן.

תמונת תאימות קדימה

המרת השדרוג לאחור תיכשל אם ייעשה שימוש בפעולות או בתכונות שלא קיימות בגרסה הקודמת של הממשק. כלומר, התאימות להעברה מתגלה אצל המפיק ולא בזמן הריצה.

תאימות לאחור: כדי לספק תאימות לאחור, משדרגים את פעולות VHLO לגרסה האחרונה שלהן (במקרה הצורך), ואז ממירים את הפעולה חזרה ל-StableHLO. את כל התוכנות של VHLO בחלון התאימות אפשר לשדרג ל-StableHLO, כלומר גרסאות שונות של צרכנים יכולות לבצע פעולת deserialize של אותו מטען ייעודי (payload) של VHLO מגרסה קודמת.

תמונה של תאימות לאחור

חשוב מכך, VHLO מופשט מאחורי עריכה בהמשכים. כלומר, המסגרות של למידת המכונה (יצרנים) צריכות לטרגט רק פעולות של StableHLO, וקצוות עורפיים (צרכנים) של מהדרים צריכים לתמוך רק בגרסה העדכנית ביותר, שהיא קבוצת ההפעלה של StableHLO. ההמרות ל-VHLO וממנו מתבצעות באמצעות מכונות שמתוחזקות במאגר הנתונים היציב של StableHLO.

גרסאות של פורמט MLIR Bytecode

כדי לשמור על תאימות להעברה, לגרסאות של StableHLO משויכות גרסה של פורמט MLIR Bytecode. בנוסף, בגרסה האחרונה של StableHLO ייעשה שימוש בגרסה האחרונה של פורמט MLIR Bytecode. כשמצטברת כמות גדולה של גרסאות של פורמט MLIR Bytecode, הגרסה הבאה של StableHLO תגדיל את הגרסה המשנית ותעדכן את Version.cpp כדי להשתמש בגרסה האחרונה של פורמט MLIR Bytecode.

במאמר bytecode.md תוכלו לקרוא פרטים נוספים על פורמט MLIR Bytecode ועל הנימוק לשימוש בו ב-StableHLO.

הוספת שינויים לא תואמים

כל השינויים שיש להם השלכות על תאימות חייבים לעבור את תהליך ה-RFC. האיסור הזה כולל הוספה, הוצאה משימוש או שינוי שם של תכונה. אחרי שה-RFC יאושר, תוכלו להיעזר בהנחיות הבאות לתרומות:

העברת מספר הגרסה ב-Version.h

לפני עדכון הפעולות, המאפיינים, הסוגים או ההמרות של VHLO, יש להגדיל את מספר הגרסה המשנית ב-Version.h. תכונות חדשות של VHLO שיתווספו יתווספו לגרסה הזו. לדוגמה, אחרי הקפצת 0.10.0 --> 0.11.0, פעולה חדשה ב-VhloOps.td תעשה זאת:

VHLO_Op<"abs_v2", "0.11.0", "current">

הוספת ההמרות הנדרשות של VHLO והטמעתן

הקוד המדויק שנדרש לשילוב תכונה חדשה ישתנה, אבל ברוב המקרים יש לשנות את הגורמים הבאים:

דוגמה אחרונה לשליחת בקשה שקשורה לתאימות הייתה הוספה של שני סוגי FP8, וההטמעה שלהם ב-VHLO ב-#1379.

הוספה / עדכון של בדיקות יחידה

הגורם האחראי לשינוי לא תואם אחראי לבדיקות היחידה החיוביות והשליליות של התכונה, וגם לבדיקות של יחידות התאימות.

הבדיקה של יחידת התאימות כוללת עדכון של stablehlo_legalize_to_vhlo.mlir כדי להבטיח שהלוך ושוב ב-StableHLO עם הגרסה האחרונה של VHLO, ושצריך לבצע בדיקות תאימות נוספות קדימה או אחורה.

הנה כמה דוגמאות:

הוספת בדיקת גרסה בסידרה

אחרי שמוסיפים נקודת בדיקה ל-stablehlo_legalize_to_vhlo.mlir, צריך ליצור עותק בגרסת גרסה של הקובץ בשם stablehlo_legalize_to_vhlo.0_X_0.mlir, יחד עם גרסת bytecode של הקובץ שצוין עם התוסף .0_X_0.mlir.bc. כדאי להוסיף שורות מתאימות של FileCheck לבדיקת תאימות קדימה ואחורה.

$ export TARGET_VERSION=0.X.0
$ export TARGET_FILENAME=${TARGET_VERSION//./_}
$ cp stablehlo/tests/stablehlo_legalize_to_vhlo.mlir stablehlo/tests/stablehlo_legalize_to_vhlo.$TARGET_FILENAME.mlir
$ build/bin/stablehlo-translate --serialize --target=$TARGET_VERSION --strip-debuginfo stablehlo/tests/stablehlo_legalize_to_vhlo.$TARGET_FILENAME.mlir > stablehlo/tests/stablehlo_legalize_to_vhlo.$TARGET_FILENAME.mlir.bc

# Replace RUN commands in stablehlo/tests/stablehlo_legalize_to_vhlo.0_X_0.mlir with the following for 0.X.0:
// RUN: stablehlo-opt --mlir-print-op-generic %s.bc | FileCheck %s
// RUN: stablehlo-translate --deserialize %s.bc | stablehlo-translate --serialize --target=0.X.0 | stablehlo-opt --mlir-print-op-generic | FileCheck %s
// RUN: diff <(stablehlo-translate --deserialize %s.bc | stablehlo-opt) <(stablehlo-opt --strip-debuginfo %s)
// RUN: diff %s.bc <(stablehlo-translate --serialize --target=0.X.0 --strip-debuginfo %s)

דוגמה לבדיקת גרסאות ב-#1430.