-chlo-legalize-to-stablehlo
העברה של פעולות מ-CHLO אל StableHLO ופעולות Shape
-shape-legalize-to-stablehlo
הוספת פעולות שקשורות לצורות ל-StableHLO.
העברה ניסיונית שמכשירה פעולות שקשורות לצורה לפעולות StableHLO.
שילוב של חישובי צורה ונתונים באמצעות העברה אופציונלית יאפשר למערכת האקולוגית של StableHLO להשתמש בצינורות עיבוד הנתונים של הקומפילציה שמשתמשים בפעולות StableHLO כדי ליצור מודל של דינמיות.
-stablehlo-canonicalize-dynamism
מבצע קנוניזציה של פעולות דינמיות של StableHLO לפעולות סטטיות.
מחליף אופרטורים דינמיים של StableHLO כמו DynamicReshapeOp עם המקבילים הסטטיים המתאימים כמו DynamicReshapeOp ל-ReshapeOp או DynamicBroadcastInDim ל-BroadcastInDim אם כל האלמנטים הדינמיים של האופרטורים האלה הם קבועים בפועל.
%c = stablehlo.constant dense<16> : tensor<1xi32>
%0 = stablehlo.dynamic_broadcast_in_dim %cst, %c, dims = [] : (tensor<f32>, tensor<1xi32>) -> tensor<16xf32>
==>
%0 = stablehlo.broadcast_in_dim %cst, dims = [] : (tensor<f32>) -> tensor<16xf32>
-stablehlo-check-shape-assertions
_Check stablehlo.custom_call @shapeassertion ops.
אימות של קריאות מותאמות אישית של shape_assertion.
טענות לגבי צורות מאמתות אילוצים על מאפיינים דינמיים ב-StableHLO.
לדוגמה, אם צריך לאכוף במסגרת מגבלה של DimA < 2, אפשר להפיק את ה-IR הבא:
%dimA = <get_dimension_size or input arg> : tensor<i32>
%c2 = stablehlo.constant dense<2> : tensor<i32>
%is_lt = stablehlo.compare LT %dimA, %c2 : tensor<i1>
stablehlo.custom_call @shape_assertion(%is_lt) { error_message = "DimA must be less than 2" }
אחרי ההעברה, אם הצורות נכונות, התו stablehlo.custom_call
יוסר.
אפשרויות
-enable-shape-assertions : Whether shape assertions may generate errors.
-stablehlo-compatibility-expander
הרחבת התאימות לפעולות של StableHLO.
בגרסאות האחרונות, פעולות StableHLO מקבלות עדכונים או שנוספות פעולות חדשות. הכרטיס הזה, שמופעל בהסכמה, מרחיב את התאימות לדורות קודמים עם גרסאות ישנות יותר של StableHLO על ידי פירוק של פעולות חדשות יותר של StableHLO לפעולות מקבילות שנתמכות על ידי הגרסאות הישנות יותר האלה.
למה צריך להביע הסכמה כדי להשתמש בכרטיס הזה?
לפעמים, שיפורים בפעולות של StableHLO משמשים כדי לפשט מאוד את הטיפול בדפוסים נפוצים מסוימים במערכת האקולוגית של OpenXLA. זה כולל דברים כמו TanOp, שיש לו תמיכה גבוהה במסגרת ובקומפיילר, וגם מימדים של אצווה של gather/scatter, שאפשר לייצג באמצעות פרוסות, אבל זה מקשה מאוד על חלוקת הנתונים. בקטגוריה הזו של תכונות חדשות, אנחנו לא מציעים שדרוג אוטומטי לאחור, כי הוא עלול לגרום לאובדן של מידע חשוב שמשמש לאופטימיזציות הבאות. אפשר להשתמש בשלב הזה כדי להרחיב את הפעולות האלה על סמך גרסת יעד, כדי למקסם את התאימות על חשבון קומפילציה פחות אופטימלית.
func.func @tan_op_non_complex(%arg0: tensor<4xf64>) -> tensor<4xf64> {
%1 = stablehlo.tan %arg0 : tensor<4xf64>
func.return %1 : tensor<4xf64>
}
==>
func.func @tan_op_non_complex(%arg0: tensor<4xf64>) -> tensor<4xf64> {
%0 = stablehlo.sine %arg0 : tensor<4xf64>
%1 = stablehlo.cosine %arg0 : tensor<4xf64>
%2 = stablehlo.divide %0, %1 : tensor<4xf64>
return %2 : tensor<4xf64>
}
אפשרויות
-target : The target version. Must be a version of the form #.#.#.
-stablehlo-complex-math-expander
רכיב להרחבת פעולות מתמטיות מורכבות ב-StableHLO.
פעולות מתמטיות מרוכבות של StableHLO הן פירוקים באמצעות פעולות מתמטיות ממשיות של StableHLO.
ההצהרה הזו מבוססת על ההנחה שלא קיימת חומרה שתומכת במספרים מרוכבים או בפעולות מתמטיות מרוכבות באופן מובנה. המשמעות היא שמנגנוני הגיבוי בפעולות מתמטיות מורכבות שהקומפיילרים עשויים להטמיע הם מיותרים. הפעלת השלב הזה תגרום להרחבה של כל הפעולות המתמטיות המורכבות ב-StableHLO.
func.func @sqrt_op_complex(%arg0: tensor<4xcomplex<f64>>) -> tensor<4xcomplex<f64>> {
%1 = stablehlo.sqrt %arg0 : tensor<4xcomplex<f64>>
func.return %1 : tensor<4xcomplex<f64>>
}
==>
func.func @sqrt_op_complex(%arg0: tensor<4xcomplex<f64>>) -> tensor<4xcomplex<f64>> {
TBD
return %2 : tensor<4xcomplex<f64>>
}
-stablehlo-convert-to-signless
Pass to transform the IR to be on signless integers.
-stablehlo-legalize-composite-to-call
מחליף פעולות מורכבות בקריאה לפירוק שלהן.
החלפת פעולות מורכבות בקריאה לפירוק שלהן, למשל:
stablehlo.composite "my_namespace.my_op" %arg0, %arg1 {
decomposition = @bar,
version = 1,
composite_attributes = {
"my_attribute": "my_value"
}
}
התוצאה תהיה:
func.call @bar(%arg0, %arg1)
אפשר להחריג קבוצת משנה של רכיבים מהטרנספורמציה הזו באמצעות הדגל except, למשל:
stablehlo-opt --stablehlo-legalize-composite-to-call=except='foo.baz,foo.qux'
אפשרויות
-except : Names of composites that should not be replaced with calls.
-stablehlo-legalize-deprecated-ops
הפיכת פעולות שהוצאו משימוש לפעולות נתמכות.
ב-RFC (#2283) בנושא הוצאה משימוש של Opset ב-StableHLO גרסה 1.0 מוצע להסיר כמה פעולות מיותרות. המעבר הזה עוזר להעריך את ההשפעה של ההסרות האלה בצינורות שונים של קומפילציה, על ידי הפיכתן לחוקיות בהשוואה למקבילות שלהן שנתמכות לטווח ארוך.
אפשרויות
-fail-on-unused : Fail on (mostly) unused ops that are deprecated without any fallback.
-stablehlo-legalize-qdq-to-quantized-op
מיזוג (de-quantize, floating-point operation and quantize) pattern into StableHLO quantized operation
התבנית Fuse (de-quantize, floating-point operation and quantize) into StableHLO quantized operation הערה: הפעולה לא מוחקת אף פעולה קיימת. לדוגמה, התוכנית הבאה
func.func @add(%arg0: tensor<16x16x!quant.uniform<ui8:f32, 34.0:16>>) -> tensor<16x16x!quant.uniform<ui8:f32, 34.0:16>> {
%0 = stablehlo.uniform_dequantize %arg0 : (tensor<16x16x!quant.uniform<ui8:f32, 34.0:16>>) -> tensor<16x16xf32>
%1 = stablehlo.abs %0 : tensor<16x16xf32>
%2 = stablehlo.uniform_quantize %1 : (tensor<16x16xf32>) -> tensor<16x16x!quant.uniform<ui8:f32, 34.0:16>>
func.return %2 : tensor<16x16x!quant.uniform<ui8:f32, 34.0:16>>
}
התוצאה תהיה:
func.func @add(%arg0: tensor<16x16x!quant.uniform<u8:f32, 3.400000e+01:16>>) -> tensor<16x16x!quant.uniform<u8:f32, 3.400000e+01:16>> {
%0 = stablehlo.uniform_dequantize %arg0 : (tensor<16x16x!quant.uniform<u8:f32, 3.400000e+01:16>>) -> tensor<16x16xf32>
%1 = stablehlo.abs %0 : tensor<16x16xf32>
%2 = stablehlo.abs %arg0 : tensor<16x16x!quant.uniform<u8:f32, 3.400000e+01:16>>
%3 = stablehlo.uniform_quantize %1 : (tensor<16x16xf32>) -> tensor<16x16x!quant.uniform<u8:f32, 3.400000e+01:16>>
return %2 : tensor<16x16x!quant.uniform<u8:f32, 3.400000e+01:16>>
}
-stablehlo-legalize-quant-to-math
המרת פעולות כמותיות מ-StableHLO לפעולות מתמטיות פרימיטיביות של StableHLO.
המרת תוכניות StableHLO באמצעות סוגי UniformQuantized לפעולות מתמטיות של מספרים שלמים ששקולות מבחינה סמנטית.
func.func @add(%arg0: tensor<!quant.uniform<i8:f32,1.0:0>>, %arg1: tensor<!quant.uniform<i8:f32,2.0:1>>) -> tensor<!quant.uniform<i8:f32,3.0:2>> {
%0 = "stablehlo.add"(%arg0, %arg1) : (tensor<!quant.uniform<i8:f32,1.0:0>>, tensor<!quant.uniform<i8:f32,2.0:1>>) -> tensor<!quant.uniform<i8:f32,3.0:2>>
func.return %0 : tensor<!quant.uniform<i8:f32,3.0:2>>
}
התוצאה תהיה:
func.func @add(%arg0: tensor<i8>, %arg1: tensor<i8>) -> tensor<i8> {
%0 = stablehlo.convert %arg0 : (tensor<i8>) -> tensor<f32>
%cst = stablehlo.constant dense<0.333333343> : tensor<f32>
%1 = chlo.broadcast_multiply %0, %cst : (tensor<f32>, tensor<f32>) -> tensor<f32>
%cst_0 = stablehlo.constant dense<2.000000e+00> : tensor<f32>
%2 = chlo.broadcast_add %1, %cst_0 : (tensor<f32>, tensor<f32>) -> tensor<f32>
%3 = stablehlo.round_nearest_even %2 : tensor<f32>
%4 = stablehlo.convert %3 : (tensor<f32>) -> tensor<i32>
%5 = stablehlo.convert %arg1 : (tensor<i8>) -> tensor<f32>
%cst_1 = stablehlo.constant dense<0.666666686> : tensor<f32>
%6 = chlo.broadcast_multiply %5, %cst_1 : (tensor<f32>, tensor<f32>) -> tensor<f32>
%cst_2 = stablehlo.constant dense<1.33333337> : tensor<f32>
%7 = chlo.broadcast_add %6, %cst_2 : (tensor<f32>, tensor<f32>) -> tensor<f32>
%8 = stablehlo.round_nearest_even %7 : tensor<f32>
%9 = stablehlo.convert %8 : (tensor<f32>) -> tensor<i32>
%c = stablehlo.constant dense<2> : tensor<i32>
%10 = chlo.broadcast_add %4, %9 : (tensor<i32>, tensor<i32>) -> tensor<i32>
%11 = chlo.broadcast_subtract %10, %c : (tensor<i32>, tensor<i32>) -> tensor<i32>
%c_3 = stablehlo.constant dense<-128> : tensor<i32>
%c_4 = stablehlo.constant dense<127> : tensor<i32>
%12 = stablehlo.clamp %c_3, %11, %c_4 : tensor<i32>
%13 = stablehlo.convert %12 : (tensor<i32>) -> tensor<i8>
return %13 : tensor<i8>
}
-stablehlo-legalize-quantized-op-to-qdq
פירוק של פעולת StableHLO כמותית לתבנית (ביטול הכמותיות, פעולה בנקודה צפה וכימות).
פירוק של תוכניות StableHLO שעברו קוונטיזציה באמצעות פעולות קוונטיזציה/דה-קוונטיזציה אחידות. לדוגמה, התוכנית הבאה
func.func @add(%arg0: tensor<!quant.uniform<i8:f32,1.0:0>>, %arg1: tensor<!quant.uniform<i8:f32,2.0:1>>) -> tensor<!quant.uniform<i8:f32,3.0:2>> {
%0 = "stablehlo.add"(%arg0, %arg1) : (tensor<!quant.uniform<i8:f32,1.0:0>>, tensor<!quant.uniform<i8:f32,2.0:1>>) -> tensor<!quant.uniform<i8:f32,3.0:2>>
func.return %0 : tensor<!quant.uniform<i8:f32,3.0:2>>
}
התוצאה תהיה:
func.func @add(%arg0: tensor<!quant.uniform<i8:f32, 1.000000e+00>>, %arg1: tensor<!quant.uniform<i8:f32, 2.000000e+00:1>>) -> tensor<!quant.uniform<i8:f32, 3.000000e+00:2>> {
%0 = stablehlo.uniform_dequantize %arg0 : (tensor<!quant.uniform<i8:f32, 1.000000e+00>>) -> tensor<f32>
%1 = stablehlo.uniform_dequantize %arg1 : (tensor<!quant.uniform<i8:f32, 2.000000e+00:1>>) -> tensor<f32>
%2 = stablehlo.add %0, %1 : tensor<f32>
%3 = stablehlo.uniform_quantize %2 : (tensor<f32>) -> tensor<!quant.uniform<i8:f32, 3.000000e+00:2>>
return %3 : tensor<!quant.uniform<i8:f32, 3.000000e+00:2>>
}
-stablehlo-legalize-to-vhlo
הפיכת StableHLO ל-VHLO.
הפיכת StableHLO לחוקי לגרסה האחרונה של אופרציות ב-VHLO. אחר כך אפשר להוריד את הגרסה של האופרטורים האלה לגרסאות ישנות יותר של VHLO כדי לשמור על תאימות קדימה באמצעות VhloToVersionPass.
stablehlo.exponential %[[ARG0]] <{result_accuracy = DEFAULT}> : tensor<f32>
# ====>
"vhlo.exponential_v2"(%[[ARG0]]) <{result_accuracy = #vhlo.DEFAULT_v1}> : !vhlo.tensor_v1<!vhlo.f32_v1>
לפרטים מלאים על השימוש ב-VHLO כדי לשמור על תאימות קדימה ואחורה, אפשר לעיין במאמר vhlo.md > The VHLO dialect
אפשרויות
-allow-other-dialects : Allow serialization to use other (potentially unstable) dialects, inserts unrealized casts between dialects.
-stablehlo-refine-arguments
משפר את צורות הארגומנטים של הפונקציה הראשית.
משנה את הארגומנטים של הפונקציה הראשית באמצעות חתימת סוג הקלט.
עוטף את הארגומנטים ב-custom_call @stablehlo.shape_refinement_operand_wrapper
כדי לשמור על תקינות ה-IR לפני הפעלת שיפור הצורה.
func.func public @main(%arg0: tensor<?xf32>) -> tensor<?xf32> {
...
}
==>
func.func public @main(%arg0: tensor<16xf32>) -> tensor<?xf32> {
%c = stablehlo.constant dense<16> : tensor<1xi64>
%0 = stablehlo.custom_call @stablehlo.shape_refinement_operand_wrapper(%arg0, %c) {...}
: (tensor<16xf32>, tensor<1xi64>) -> tensor<?xf32>
...
}
אפשר להשתמש ב-refinedTypesOption כדי לציין רשימה של סוגים מפורטים.
אפשר לציין את זה ב-MLIR באמצעות --types='tensor<...>,tensor<...>', או להעביר את זה לשיטה ליצירת כרטיס. ברשימת סוגי ההגדרה המדויקת צריך לציין את הסוג של כל ארגומנט בשיטה main שמוגדרת בצורה מדויקת.
אפשרויות
-types : The new types to be used for the main function's arguments, specified as an MLIR TypeRange 'tensor<1x2xf32>, ...'
-stablehlo-refine-shapes
משפר את הצורות בתוכנית StableHLO.
הסבר על תוכנית StableHLO שמשפרת צורות בתוך פעולות.
תרחיש השימוש העיקרי בכרטיס הזה הוא התמחות בתוכניות דינמיות בצורות שונות, לצורות סטטיות. אם לתוכנית StableHLO עם צורות דינמיות יש את המבנה הנכון, עדכון סוגי הארגומנטים שלה מצורות דינמיות לצורות סטטיות והרצת השלב הזה יפיצו צורות סטטיות בכל התוכנית.
בשלב הזה, המערכת מסירה את custom_call @shape_refinement_operand_wrapper על ידי החלפת השימוש בתוצאה באופרנד ישירות, ומפיצה צורות סטטיות בכל התוכנית.
%c = stablehlo.constant dense<16> : tensor<1xi64>
%0 = stablehlo.custom_call @stablehlo.shape_refinement_operand_wrapper(%arg0, %c) {...}
: (tensor<16xf32>, tensor<1xi64>) -> tensor<?xf32>
%1 = stablehlo.add %0, %0 : tensor<?xf32>
==>
%1 = stablehlo.add %arg0, %arg0 : tensor<16xf32>
מודולים שאפשר להשתמש בהם לשיפור הצורה צריכים לכלול את המאפיינים הבאים:
- כל הצורות הדינמיות תלויות רק בצורות הקלט (אין תלות של הצורה בתוכן של מערך הקלט). אנחנו מתייחסים לפעולות שתלויות באופן טרנזיטיבי רק בצורות הקלט (לדוגמה, כפי שמוצג ב-
stablehlo.get_dimension_size) או בקבועים גלובליים כמו הערכים שנפתרו של מספרים שלמים סמליים (כלומר, טנסור: A = 5), כאל פעולות dimension. אפשר לפתור את כל הערכים של המאפיינים באמצעות קיפול קבוע בין פרוצדורות. - פונקציות ביניים יכולות לקבל מספר ארגומנטים של טוקנים (מהסוג !stablehlo.token) בתחילת רשימת הארגומנטים, ואחריהם כמה ארגומנטים קבועים גלובליים שהם סקלרים של מספרים שלמים קבועים, כמו הערכים שפוענחו של מספרים שלמים סמליים (כלומר, tensor
: A = 5). - יכול להיות שפונקציות ביניים מסוימות יחזירו חישובים על קבועים גלובליים, כלומר
floordivעל ערכי symint. הפונקציות האלה מסומנות בכך שהן מחזירות רק ערכים קבועים אחרי שיפור. הפונקציות האלה מוטמעות. - כל הקריאות לפונקציה יחידה מסתיימות באותם צורות של ארגומנטים, ולא מתבצעות קריאות לפונקציות רקורסיביות או קורקורסיביות.
-stablehlo-wrap-in-composite
עוטף אופרטור StableHLO שאינו מורכב באופרטור מורכב.
עוטף פעולות StableHLO בפעולות stablehlo.composite.
לדוגמה, נניח שיש לנו תוכנית StableHLO פשוטה:
func.func @main(%arg0 : tensor<2xf32>, %arg1 : tensor<2xf32>) -> tensor<2xf32> {
%0 = stablehlo.add %arg0, %arg1 : tensor<2xf32>
return %0 : tensor<2xf32>
}
החלת הכרטיס הזה כדי לעטוף פעולות של stablehlo.add תביא לתוכנית הבאה:
func.func @main(%arg0: tensor<2xf32>, %arg1: tensor<2xf32>) -> tensor<2xf32> {
%0 = stablehlo.composite "stablehlo.add" %arg0, %arg1 {decomposition = @stablehlo.add.impl} : (tensor<2xf32>, tensor<2xf32>) -> tensor<2xf32>
return %0 : tensor<2xf32>
}
func.func private @stablehlo.add.impl(%arg0: tensor<2xf32>, %arg1: tensor<2xf32>) -> tensor<2xf32> {
%0 = stablehlo.add %arg0, %arg1 : tensor<2xf32>
return %0 : tensor<2xf32>
}
הערות:
- המאפיין
nameשל פעולתstablehlo.compositeשנוצרה תמיד יהיה זהה לשם הפעולה המקורית שעברה עטיפה (לדוגמה, אם עוטפים פעולתstablehlo.add, הפעולה המורכבת תיקרא גם"stablehlo.add"). - הפונקציה הפרטית שמכילה את הפעולה המקורית (שמופנית אליה באמצעות מאפיין
decompositionשל הפעולהstablehlo.composite) תקבל שם לפי התבנית<op_name>.impl[.N], כאשר<op_name>הוא השם של הפעולה המקורית ו-Nהוא מזהה ייחודי מספרי שנוצר כדי למנוע התנגשויות בשמות בתוך המודול.
אפשר להשתמש בכרטיס הזה בשתי דרכים שונות:
מצב 1: שימוש בשורת הפקודה
המצב הזה מיועד לניפוי באגים או לבדיקות, כי הוא מציע שליטה מינימלית במאפיינים של פעולות stablehlo.composite שנוצרו.
הוא עוטף את כל המקרים של פעולות שצוינו באמצעות האפשרויות op-names (רשימה של שמות פעולות שמופרדים בפסיקים). המאפיינים של פעולת stablehlo.composite החדשה יהיו זהים למאפיינים של הפעולה המקורית.
דוגמה לשימוש:
stablehlo-opt input.mlir --stablehlo-wrap-in-composite=op-names='stablehlo.add,stablehlo.mul' -o output.mlir
מצב 2: גלישת טקסט בכל המודול באופן פרוגרמטי עם טיפול מותאם אישית במאפיינים
במצב הזה, המודול כולו עטוף בשיטה פרוגרמטית, כך שאתם יכולים לשלוט באופן מדויק באילו פעולות לעטוף ובאילו מאפיינים להשתמש.
אפשר לעשות את זה באמצעות ה-API createStablehloWrapInCompositePass, שמקבל את CompositeAttributeProviderMap כארגומנט.
CompositeAttributeProviderMap הוא מיפוי שמגדיר אילו פעולות צריכות להיכלל בעטיפה ואיך המאפיינים שלהן צריכים להיות מטופלים. הסמנטיקה שלו היא כזו:
- Keys (mlir::TypeID):
TypeIDof an MLIR operation. אם הפעולהTypeIDתואמת למפתח במפה, היא הופכת למועמדת לעטיפה. - ערכים (פונקציות Lambda): פונקציית Lambda מסוג
std::function<std::optional<NamedAttrList>(Operation*)>. הפונקציה הזו מוחלת על כל פעולה אפשרית.- קלט:
mlir::Operation*, שהוא מופע של סוג הפעולה שמתאים למקשTypeID. - ערך מוחזר:
std::optional<NamedAttrList>.- אם פונקציית ה-lambda מחזירה
NamedAttrList(עטוף ב-std::optional), הפעולה עטופה בפעולהstablehlo::composite, והמאפיינים שמוחזרים משמשים להגדרת המאפיינים של הרכיב המורכב. - אם פונקציית ה-lambda מחזירה
std::nullopt, הפעולה לא עטופה. כך אפשר להגדיר גלישת טקסט סלקטיבית על סמך קריטריונים מותאמים אישית.
- אם פונקציית ה-lambda מחזירה
- קלט:
דוגמה (C++):
stablehlo::CompositeAttributeProviderMap compositeAttributeProviderMap;
compositeAttributeProviderMap[mlir::TypeID::get<mlir::stablehlo::AddOp>()] =
[](mlir::Operation* op) -> std::optional<mlir::NamedAttrList> {
// Custom logic to determine if and how to wrap the operation.
// Example: Only wrap if it's on a specific type.
if (mlir::isa<mlir::Float32Type>(op->getOperand(0).getType())) {
return mlir::NamedAttrList(op->getAttrs());
}
return std::nullopt; // Do not wrap.
};
pm.addPass(createStablehloWrapInCompositePass(compositeAttributeProviderMap, compositeVersion));
if (mlir::failed(pm.run(module))) {
return;
}
אפשרויות
-op-names : The names of the ops to wrap.
-version : The version number of the composite op.
-vhlo-legalize-to-stablehlo
הפיכת VHLO ל-StableHLO.
-vhlo-to-version
המרת גרסאות של VHLO לצורך תאימות
מבצע המרה בין גרסאות של VHLO לשדרוג או להורדה של IR כדי לשמור על תאימות קדימה ואחורה.
"vhlo.exponential_v2"(%[[ARG0]]) <{result_accuracy = DEFAULT}>
# ==( -target=1.0.0 )==>
"vhlo.exponential_v1"(%[[ARG0]])
# ==( -target=1.9.0 )==>
"vhlo.exponential_v2"(%[[ARG0]]) <{result_accuracy = DEFAULT}>
לפרטים מלאים על השימוש ב-VHLO כדי לשמור על תאימות קדימה ואחורה, אפשר לעיין במאמר vhlo.md > The VHLO dialect
אפשרויות
-target : The target version. Must be a version of the form #.#.# .