שידור

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

מהו שידור?

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

ייתכן שיהיה צורך בשידור בפעולות בין מערכים רב-ממדיים של דרגות שונות, או בין מערכים רב-ממדיים עם צורות שונות אך תואמות. נשתמש לחבר 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, הפעולה הזו נקראת שידור.

עקרונות

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

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

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

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

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

את רוב צורכי השידור אפשר להקליט על ידי שימוש בצמד של מימדים בפעולה בינארית. כאשר לערכי הקלט לפעולה יש דרגות שונות, כוונון השידור הזה מציין אילו מאפיינים במערך high-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|

מידות השידור יכולות להיות מגשים המתארים כיצד צורת דירוג קטנה יותר משודרת לצורת דרגה גדולה יותר. לדוגמה, בהינתן קובואיד של 2x3x4 ומטריצה של 3x4, המשמעות של משולש משדר (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 (מאפיין "degenerate")

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

דוגמאות:

  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|

לאחר מכן, 'degenerate שידור מימדים' משדר את מימד אפס של מטריצה 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.