שידור

מסמך זה מתאר את הסמנטיקה של שידור XLA.

מה זה שידור?

שידור הוא התהליך של יצירת מערכים עם צורות שונות עם צורות תואמות לפעולות אריתמטיות. הטרמינולוגיה מבוססת על NumPy Broadcasting.

ייתכן שיידרש שידור לפעולות בין מערכים רב-ממדיים של דרגות שונות, או בין מערכים רב-ממדיים עם צורות שונות אך תואמות. ניקח לדוגמה את התוספת X+v שבה X הוא מטריצה (מערך מדירוג 2) ו-v הוא וקטור (מערך של דירוג 1). כדי לבצע הוספה ברמת הרכיב, XLA צריך "לשדר" את הווקטור v לאותו דירוג של המטריצה X, על ידי שכפול של v מספר מסוים של פעמים. האורך של הווקטור צריך להתאים לפחות לאחת ממידות המטריצה.

לדוגמה:

|1 2 3| + |7 8 9|
|4 5 6|

הממדים של המטריצה הם (2,3), וממד הווקטור הוא (3). הווקטור משודר על ידי שכפול שלו בשורות כדי לקבל:

|1 2 3| + |7 8 9| = |8  10 12|
|4 5 6|   |7 8 9|   |11 13 15|

ב-NumPy, הפעולה הזו נקראת broadcasting.

עקרונות

הניסוח של XLA מחמיר ובוטה ככל האפשר, ללא תכונות "קסומות" מרומזות. תכונות כאלה עשויות להקל על ההגדרה של חישובים מסוימים, אבל במחיר של השערות רבות יותר שמוטמעות בקוד המשתמש שיהיה קשה לשנות בטווח הארוך. אם צריך, אפשר להוסיף תכונות קסומות מרומזות ברכיבי wrapper ברמת הלקוח.

בכל הקשור לשידור, XLA דורש מפרטי שידור מפורשים לגבי פעולות בין מערכים בעלי דרגות שונות. היא שונה מ-NumPy, שמסיק את המפרט כשהדבר אפשרי.

שידור מערך בדירוג נמוך יותר למערך בדירוג גבוה יותר

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

|1 2 3| + 7 = |8  9  10|
|4 5 6|       |11 12 13|

את רוב צורכי השידור אפשר לתעד באמצעות שני מימדים ביחס לפעולה בינארית. כאשר לקלטים של הפעולה יש דרגות שונות, הצירוף הזה של השידור מציין אילו מאפיינים במערך higher-rank צריכים להתאים למערך lower-rank.

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

|7 8 9| ==> |7 8 9|
            |7 8 9|

דוגמה מורכבת יותר: כדאי להוסיף וקטור של 3 רכיבים (מאפיין (3)) למטריצה של 3x3 (מימדים (3,3)). בדוגמה הזו יש שתי דרכים לשדר שידור:

(1) ניתן להשתמש במימד שידור של 1. כל רכיב וקטורי הופך לעמודה והווקטור משוכפל בכל שורה במטריצה.

|7 8 9| ==> |7 8 9|
            |7 8 9|
            |7 8 9|

(2) ניתן להשתמש במימד שידור של 0. כל רכיב וקטורי הופך לשורה והווקטור משוכפל לכל עמודה במטריצה.

 |7| ==> |7 7 7|
 |8|     |8 8 8|
 |9|     |9 9 9|

מידות השידור יכולות להיות ttuple, שמתאר כיצד צורת דירוג קטנה יותר משודרת לצורת דירוג גדולה יותר. לדוגמה, בהינתן מטריצה של 2x3x4 ומטריצת 3x4, המשמעות של tuple שידור (1,2) היא להתאים את המטריצה לממדים 1 ו-2 של הקובואיד.

סוג השידור הזה משמש בתפעול הבינארי ב-XlaBuilder, אם מצוין הארגומנט broadcast_dimensions. לדוגמה, ראו XlaBuilder::Add. בקוד המקור XLA, סוג השידור הזה נקרא לפעמים InDim.

הגדרה מנומסת

מאפיין השידור מאפשר התאמה של מערך בדירוג נמוך יותר למערך בדירוג גבוה יותר, על ידי ציון המאפיינים של המערך בדירוג הגבוה יותר שיש להתאים. לדוגמה, עבור מערך עם המאפיינים MxNxPxQ, ניתן להתאים וקטור עם מאפיין T באופן הבא:

          MxNxPxQ

dim 3:          T
dim 2:        T
dim 1:      T
dim 0:    T

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

כדי להתאים מטריצת TxV למערך MxNxPxQ, נעשה שימוש בשני ממדי שידור:

          MxNxPxQ
dim 2,3:      T V
dim 1,2:    T V
dim 0,3:  T     V
etc...

סדר המאפיינים ב-tuple של השידור חייב להיות הסדר שבו המאפיינים של המערך ברמה הנמוכה יותר צפויים להתאים למידות של המערך ברמה הגבוהה יותר. הרכיב הראשון ב-tuple מציין איזה מאפיין במערך מהדירוג הגבוה יותר צריך להתאים למאפיין 0 במערך מהדירוג הנמוך יותר. הרכיב השני ב-tuple מציין איזה מאפיין במערך מהדירוג הגבוה יותר צריך להתאים למאפיין 1 במערך מהדירוג הנמוך יותר, וכן הלאה. הסדר של מידות השידור חייב להיות במגמת עלייה. לדוגמה, לפי הדוגמה הקודמת, לא חוקי להתאים בין V ל-N ול-T ל-P. לא חוקי להתאים בין V ל-N גם לפי החוק.

שידור מערכים בעלי דירוג דומה עם מימדים מנוונים

אחת מהבעיות הבאות היא שידור של שני מערכים בעלי אותו דירוג אבל בעלי גדלים שונים. כמו ב-NumPy, הדבר אפשרי רק כאשר המערכים תואמים. שני מערכים תואמים אם כל המאפיינים שלהם תואמים. יש שני מאפיינים תואמים אם:

  • הם שווים, או
  • אחד מהם הוא 1 (מאפיין "מנוון")

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

דוגמאות:

  1. (2,1) ו-(2,3) לשדר ל-(2,3).
  2. (1,2,5) ו-(7,2,5) לשדר ל-(7,2,5).
  3. (7,2,5) ו-(7,1,5) לשדר ל-(7,2,5).
  4. (7,2,5) ו-(7,2,6) לא תואמות ולא ניתן לשדר אותן.

נוצר מקרה מיוחד, ויש תמיכה גם בו, שבו לכל אחד ממערכי הקלט יש מימד מנוון באינדקס אחר. במקרה הזה, התוצאה היא "פעולה חיצונית": (2,1) ו-(1,3) שידור ל-(2,3). לדוגמאות נוספות, ראו מסמכי התיעוד של NumPy לשידור.

יצירת שידור

שידור של מערך בדירוג נמוך יותר למערך בדירוג גבוה יותר וגם שידור באמצעות מאפיינים מנוונים יכולים להתבצע באותה פעולה בינארית. לדוגמה, אפשר לחבר יחד וקטור בגודל 4 ומטריצה בגודל 1x2, באמצעות ממדי השידור של הערך (0):

|1 2 3 4| + [5 6]    // [5 6] is a 1x2 matrix, not a vector.

תחילה הווקטור משודר בדרגה 2 (מטריצה) באמצעות מאפייני השידור. הערך היחיד (0) במאפייני השידור מציין שמאפיין אפס של הווקטור תואם למאפיין אפס של המטריצה. הפעולה הזו יוצרת מטריצה בגודל 4xM, שבה הערך M נבחר כדי להתאים לגודל המאפיין התואם במערך 1x2. לכן נוצרת מטריצה של 4x2:

|1 1| + [5 6]
|2 2|
|3 3|
|4 4|

לאחר מכן, 'דהייה של שידור מימדים' משדר את המימד אפס במטריצה של 1x2 כך שיתאים לגודל המימד המתאים בצד ימין:

|1 1| + |5 6|     |6  7|
|2 2| + |5 6|  =  |7  8|
|3 3| + |5 6|     |8  9|
|4 4| + |5 6|     |9 10|

דוגמה מורכבת יותר היא מטריצה בגודל 1x2 שנוספה למערך בגודל 4x3x1 תוך שימוש בממדי שידור של (1, 2). קודם כל, מטריצת 1x2 משודרת עד לדירוג 3 באמצעות ממדי השידור כדי לייצר מערך ביניים של Mx1x2, שבו גודל המימד M נקבע על ידי הגודל של האופרנד הגדול יותר (מערך 4x3x1) שיוצר מערך ביניים 4x1x2. ה-M נמצא במאפיין 0 (המאפיין השמאלי ביותר) מפני שהמאפיינים 1 ו-2 ממופים לממדים של המטריצה המקורית בגודל 1x2 כאשר ממדי השידור הם (1, 2). ניתן להוסיף את המערך הביניים הזה למטריצה של 4x3x1 על ידי שידור של ממדים מצומצמים כדי ליצור תוצאה של מערך 4x3x2.