צורות ופריסה

פרוטו XLA Shape (xla_data.proto) מתאר את הדירוג, הגודל וסוג הנתונים של מערך N-ממדי (מערך בקיצור).

טרמינולוגיה, סימון ומוסכמות

  • הדירוג של מערך שווה למספר הממדים. הדירוג האמיתי של מערך הוא מספר המאפיינים שגודלם גדול מ-1.

  • המאפיינים ממוספרים מ-0 עד N-1 עבור מערך ממדי N. מספרי המאפיינים הם תוויות שרירותיות לנוחותכם. הסדר של מספרי המאפיינים האלה לא מרמז על סדר משני/גדול מסוים בפריסה של הצורה. הפריסה נקבעת באמצעות הפרוטוקול Layout.

  • לפי המוסכמה, המאפיינים מוצגים בסדר הולך וגדל של מספר מאפיינים. לדוגמה, עבור מערך תלת-ממדי בגודל [A x B x C], למאפיין 0 יש את הגודל A, למאפיין 1 יש גודל B ולמאפיין 2 יש הגודל C.

    כלים מסוימים ב- XLA תומכים גם בהוספה לאינדקס שלילית דמוית Python: מאפיין -1 הוא המאפיין האחרון (שווה ל-N-1 למערך ממדי N). לדוגמה, למערך התלת-ממדי שתואר למעלה, למאפיין 1 יש גודל C, למאפיין 2 יש גודל B וכן הלאה.

  • מערכים של שניים, שלושה וארבעת הממדים מכילים בדרך כלל אותיות ספציפיות שמשויכות למאפיינים. לדוגמה, למערך דו-ממדי:

    • מאפיין 0: y
    • מאפיין 1: x

    למערך תלת-ממדי:

    • מאפיין 0: z
    • מאפיין 1: y
    • מאפיין 2: x

    למערך 4D:

    • מאפיין 0: p
    • מאפיין 1: z
    • מאפיין 2: y
    • מאפיין 3: x
  • פונקציות ב-XA API שמקבלות מאפיינים משתמשות בסדר הולך וגדל של מספר מאפיינים. הוא תואם לסדר שבו נעשה שימוש כשמעבירים מאפיינים כ-initializer_list. למשל,

    ShapeUtil::MakeShape(F32, {A, B, C, D})

    תיצור צורה שמערך גודל המאפיינים שלה מורכב מהרצף [A, B, C, D].

פריסה

הפרוטו של Layout מתאר את האופן שבו מערך מיוצג בזיכרון. פרוטו Layout כולל את השדות הבאים:

message Layout {
  repeated int64 minor_to_major = 1;
  repeated int64 padded_dimensions = 2;
  optional PaddingValue padding_value = 3;
}

סידור מידות קטנות לגדולות

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

דוגמה למערך הדו-ממדי הבא בגודל [2 x 3]:

a b c
d e f

במקרה הזה המידה 0 היא גודל 2, והמאפיין 1 הוא מידה 3. אם השדה minor_to_major בפריסה הוא [0, 1], המאפיין 0 הוא המאפיין המשני ביותר והמאפיין 1 הוא המאפיין הכי גדול. הפריסה הזו תואמת לפריסה הבאה בזיכרון לינארי:

a d b e c f

סדר המידות המזערי לגדול של 0 עד N-1 דומה לעמודה גדולה (בדירוג 2). בהנחה שסדר המימדים מונוטווני, אנחנו עשויים להתייחס לפריסה הזו בקוד פשוט "dim 0 הוא יכולת".

מצד שני, אם השדה minor_to_major בפריסה הוא [1, 0], הפריסה בזיכרון הלינארי היא:

a b c d e f

סדר ממדים משני לגדול מ-N-1 עד 0 עבור מערך ממדי N מקביל לשורה-גדול (בדירוג 2). בהנחה של סדר מונוטוני של מאפיינים, דרך נוספת להתייחס לפריסה הזו בקוד היא פשוט "dim 0 is major".

סידור ברירת מחדל מקטן לגדול

פריסת ברירת המחדל לצורות חדשות שנוצרו היא "סדר המאפיינים הוא גדול לקטן" (בדומה לשורה גדולה בדירוג 2).

מרווח

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

לדוגמה, בהינתן מערך [2 x 3] שהוגדר למעלה, אם padded_dimensions הוא [3, 5], אז מאפיין 0 מתווסף לרוחב של 3 ומאפיין 1 מתווסף לרוחב של 5. הפריסה בזיכרון לינארי (בהנחה שערך המרווח הפנימי הוא 0 ובפריסה גדולה של עמודות) היא:

a d 0 b e 0 c f 0 0 0 0 0 0 0

היא מקבילה לפריסה של המערך הבא עם אותו סדר מאפיין מקטן לגדול:

a b c 0 0
d e f 0 0
0 0 0 0 0

הוספה לאינדקס למערכים

המחלקה IndexUtil ב-index_util.h מספקת כלים להמרה בין אינדקסים רב-ממדיים לבין אינדקסים ליניאריים בהינתן צורה ופריסה. אינדקסים רב-ממדיים כוללים אינדקס int64 לכל מאפיין. אינדקסים לינאריים הם ערך int64 יחיד שמתווסף למאגר הזמני שמכיל את המערך. אפשר לעיין ב-shape_util.h וב-layout_util.h באותה ספרייה כדי לקבל כלים פשוטים יותר ליצירה ולטיפול בצורות ופריסות.