מה חדש ב-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 נמצא ב-navigator.gpu.wgslLanguageFeatures, אפשר להשתמש עכשיו בסקאלרים שלמים של 32 ביט שמארזים וקטורים של 4 רכיבים של מספרים שלמים של 8 ביט כקלט להוראות של מוצרים של נקודות בקוד ה-WGSL של ה-shader באמצעות הפונקציות המובנות dot4U8Packed ו-dot4I8Packed. אפשר גם להשתמש בהוראות אריזה ופריקה של וקטורים דחוסים של 4 רכיבים של מספרים שלמים של 8 ביט באמצעות פונקציות מובנות של WGSL, pack4xI8, pack4xU8, pack4xI8Clamp, pack4xU8Clamp, unpack4xI8 ו-unpack4xU8.

מומלץ להשתמש בהנחיה של requires כדי לסמן את האפשרות לבעיות בהעברה באמצעות requires packed_4x8_integer_dot_product; בחלק העליון של קוד ה-WGSL של ה-shader. אפשר לעיין בדוגמה הבאה ובבעיה tint: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
  }`,
});

תודה מיוחדת לצוות ה-Web Graphics של Intel בשנגחאי, שהביא את המפרט והיישום הזה עד הסוף!

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

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

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

  • העברת הפניות לחברי מבנה ולרכיבי מערך לפונקציות שהוצהרו על ידי משתמשים.

לקבלת מידע נוסף, כדאי לעיין במאמר Pointers As Function Parameters | סיור ב-WGSL.

אפשר לזהות את התכונה הזו באמצעות navigator.gpu.wgslLanguageFeatures. מומלץ תמיד להשתמש בהנחיה של requires כדי לסמן את האפשרות של אי-ניידות באמצעות requires unrestricted_pointer_parameters; בחלק העליון של קוד ה-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

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

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

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

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

מומלץ להשתמש בהנחיה של requires כדי לסמן את האפשרות לבעיות בהעברה באמצעות requires pointer_composite_access; בחלק העליון של קוד ה-WGSL של ה-shader. אפשר לעיין בדוגמה הבאה ובבעיה 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

עדכונים של Dawn

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

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

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

מה חדש ב-WebGPU

רשימה של כל מה שנדון בסדרה מה חדש ב-WebGPU.

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