מה חדש ב-WebGPU (Chrome123)

François Beaufort
François Beaufort

תמיכה בפונקציות מובנות של DP4a ב-WGSL

‫DP4a (Dot Product of 4 Elements and Accumulate) מתייחס לקבוצה של הוראות GPU שנמצאות בשימוש נפוץ בהסקת מסקנות של למידה עמוקה לצורך קוונטיזציה. הוא מבצע ביעילות מכפלות סקלריות של מספרים שלמים בני 8 ביט כדי להאיץ את החישוב של מודלים כאלה שעברו קוונטיזציה של int8. הוא יכול לחסוך (עד 75%) בזיכרון וברוחב הפס של הרשת, ולשפר את הביצועים של כל מודל למידת מכונה בהסקת מסקנות בהשוואה לגרסת f32 שלו. כתוצאה מכך, נעשה בו שימוש נרחב בהרבה מסגרות פופולריות של AI.

אם "packed_4x8_integer_dot_product" WGSL language extension מופיע ב-navigator.gpu.wgslLanguageFeatures, עכשיו אפשר להשתמש בסקלרים של מספרים שלמים בני 32 ביט לאריזת וקטורים של 4 רכיבים של מספרים שלמים בני 8 ביט כקלט להוראות של מכפלה סקלרית בקוד של הצללה ב-WGSL עם הפונקציות המובנות dot4U8Packed ו-dot4I8Packed. אפשר גם להשתמש בהוראות אריזה ופריקה עם וקטורים ארוזים של 4 רכיבים של מספרים שלמים בני 8 ביט עם הפונקציות המובנות pack4xI8,‏ pack4xU8,‏ pack4xI8Clamp,‏ pack4xU8Clamp,‏ unpack4xI8 ו-unpack4xU8 של WGSL.

מומלץ להשתמש בrequires-directive כדי לציין את הפוטנציאל לאי-ניידות באמצעות requires packed_4x8_integer_dot_product; בחלק העליון של קוד ה-shader של WGSL. אפשר לעיין בדוגמה הבאה ובבעיה של גוון:1497.

if (!navigator.gpu.wgslLanguageFeatures.has("packed_4x8_integer_dot_product")) {
  throw new Error(`DP4a built-in functions are not available`);
}

const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();

const shaderModule = device.createShaderModule({ code: `
  requires packed_4x8_integer_dot_product;

  fn main() {
    const result: u32 = dot4U8Packed(0x01020304u, 0x02040405u); // 42
  }`,
});

תודה מיוחדת לצוות הגרפיקה באינטרנט של Intel בשנגחאי על קידום המפרט וההטמעה עד להשלמה!

פרמטרים של מצביעים ללא הגבלה ב-WGSL

"unrestricted_pointer_parameters" תוסף השפה WGSL מרחיב את ההגבלות על האפשרות להעביר מצביעים לפונקציות WGSL:

  • מצביעים לפרמטרים של מרחבי הכתובות storage, uniform ו-workgroup לפונקציות שהמשתמש הצהיר עליהן.

  • העברת מצביעים לחברים במבנה ולאלמנטים במערך לפונקציות שהמשתמש הצהיר עליהן.

מידע נוסף על הנושא

אפשר לזהות את התכונה הזו באמצעות navigator.gpu.wgslLanguageFeatures. מומלץ להשתמש תמיד בהוראת requires כדי לציין את האפשרות לאי-ניידות באמצעות requires unrestricted_pointer_parameters; בחלק העליון של קוד ה-shader של WGSL. אפשר לעיין בדוגמה הבאה, בשינויים במפרט של WGSL ובבעיה tint:2053.

if (!navigator.gpu.wgslLanguageFeatures.has("unrestricted_pointer_parameters")) {
  throw new Error(`Unrestricted pointer parameters are not available`);
}

const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();

const shaderModule = device.createShaderModule({ code: `
  requires unrestricted_pointer_parameters;

  @group(0) @binding(0) var<storage, read_write> S : i32;

  fn func(pointer : ptr<storage, i32, read_write>) {
    *pointer = 42;
  }

  @compute @workgroup_size(1)
  fn main() {
    func(&S);
  }`
});

תחביר נוח לביטול הפניה של קומפוזיציות ב-WGSL

אם "pointer_composite_access" התוסף לשפת WGSL מופיע ב-navigator.gpu.wgslLanguageFeatures, קוד ה-shader של WGSL תומך עכשיו בגישה לרכיבים של סוגי נתונים מורכבים באמצעות אותה תחביר של נקודה (.), בין אם אתם עובדים ישירות עם הנתונים או עם מצביע לנתונים. ככה זה עובד:

  • אם foo הוא מצביע: foo.bar היא דרך נוחה יותר לכתוב (*foo).bar. בדרך כלל צריך להוסיף כוכבית (*) כדי להפוך את המצביע ל'הפניה' שאפשר לבטל את ההפניה שלה, אבל עכשיו המצביעים וההפניות דומים הרבה יותר ואפשר להשתמש בהם לסירוגין.

  • אם foo הוא לא מצביע: האופרטור של הנקודה (.) פועל בדיוק כמו שאתם רגילים לגישה ישירה לחברים.

באופן דומה, אם pa הוא מצביע שמאחסן את כתובת ההתחלה של מערך, השימוש ב-pa[i] נותן לכם גישה ישירה למיקום בזיכרון שבו מאוחסן הרכיב ה-'i של המערך הזה.

מומלץ להשתמש בrequires-directive כדי לציין את הפוטנציאל לאי-ניידות באמצעות requires pointer_composite_access; בחלק העליון של קוד ה-shader של WGSL. אפשר לעיין בדוגמה הבאה ובבעיה tint:2113.

if (!navigator.gpu.wgslLanguageFeatures.has("pointer_composite_access")) {
  throw new Error(`Pointer composite access is not available`);
}

const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();

const shaderModule = device.createShaderModule({ code: `
  requires pointer_composite_access;

  fn main() {
    var a = vec3f();
    let p : ptr<function, vec3f> = &a;
    let r1 = (*p).x; // always valid.
    let r2 = p.x; // requires pointer composite access.
  }`
});

מצב קריאה בלבד נפרד להיבטים של שבלונה ועומק

בעבר, קבצים מצורפים של עומק-סטנסיל לקריאה בלבד במעברי רינדור דרשו ששני ההיבטים (עומק וסטנסיל) יהיו לקריאה בלבד. המגבלה הזו הוסרה. עכשיו אפשר להשתמש בהיבט העומק במצב קריאה בלבד, למשל למעקב אחרי צללים של אנשי קשר, בזמן שמאגר הסטנסיל נכתב כדי לזהות פיקסלים לעיבוד נוסף. לפרטים על הבעיה: dawn:2146

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

הקריאה החוזרת (callback) של שגיאה שלא נתפסה שהוגדרה באמצעות wgpuDeviceSetUncapturedErrorCallback() נקראת עכשיו באופן מיידי כשהשגיאה מתרחשת. זה מה שמפתחים מצפים לו באופן עקבי ורוצים לניפוי באגים. שינוי שחר:173620

השיטה wgpuSurfaceGetPreferredFormat() מתוך webgpu.h API הוטמעה. ראו issue dawn:1362.

המידע הזה כולל רק חלק מהנקודות העיקריות. רשימה מלאה של קומיטים

מה חדש ב-WebGPU

רשימה של כל הנושאים שמופיעים בסדרת המאמרים מה חדש ב-WebGPU.

Chrome 140

‫Chrome 139

‫Chrome 138

Chrome 137

Chrome 136

‫Chrome 135

‫Chrome 134

‫Chrome 133

‫Chrome 132

‫Chrome 131

‫Chrome 130

גרסה Chrome 129

‫Chrome 128

‫Chrome 127

‫Chrome 126

Chrome 125

‫Chrome 124

‫Chrome 123

‫Chrome 122

‫Chrome 121

‫Chrome 120

‫Chrome 119

‫Chrome 118

‫Chrome 117

Chrome 116

‫Chrome 115

‫Chrome 114

‫Chrome 113