צורות ופריסה

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

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

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

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

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

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

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

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

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

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

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

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

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

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

פריסה

הפרוטו של Layout מתאר את האופן שבו מערך מיוצג בזיכרון. קובץ ה-proto של 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 primary".

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

פריסת ברירת המחדל לצורות חדשות שנוצרו היא "סדר המאפיינים הוא ראשי לקטן" (דומה לשורה גדולה בדירוג 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 באותה ספרייה כדי לקבל כלים פשוטים יותר ליצירה ולשינוי של צורות ופריסות.