มีอะไรใหม่ใน WebGPU (Chrome 123)

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 โดยใช้ฟังก์ชันในตัว dot4U8Packed และ dot4I8Packed ได้แล้ว นอกจากนี้ คุณยังใช้คำสั่งการแพ็กและการแกะแพ็กกับเวกเตอร์ 4 องค์ประกอบแบบแพ็กของจำนวนเต็ม 8 บิตด้วยฟังก์ชันในตัวของ WGSL อย่าง pack4xI8, pack4xU8, pack4xI8Clamp, pack4xU8Clamp, unpack4xI8 และ unpack4xU8 ได้ด้วย

เราขอแนะนำให้ใช้คําสั่ง requires เพื่อบ่งบอกถึงโอกาสที่โค้ดจะไม่สามารถพอร์ตได้โดยใช้ requires packed_4x8_integer_dot_product; ที่ด้านบนของโค้ด Shader WGSL ดูตัวอย่างต่อไปนี้และ issue 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
  }`,
});

ขอขอบคุณเป็นพิเศษสำหรับทีมกราฟิกเว็บของ Intel ในเซี่ยงไฮ้ที่ขับเคลื่อนข้อกำหนดและการใช้งานนี้จนเสร็จสมบูรณ์

พารามิเตอร์พอยน์เตอร์ที่ไม่มีข้อจำกัดใน WGSL

"unrestricted_pointer_parameters" ส่วนขยายภาษา WGSL ลดความเข้มงวดในการส่งผ่านพอยน์เตอร์ไปยังฟังก์ชัน WGSL ดังนี้

  • ตัวชี้พารามิเตอร์ของ storage, uniform และ workgroup จะระบุพื้นที่ที่อยู่ของฟังก์ชันที่ผู้ใช้ประกาศ

  • การส่งตัวชี้ไปยังสมาชิกโครงสร้างและองค์ประกอบอาร์เรย์ไปยังฟังก์ชันที่ผู้ใช้ประกาศ

ดูข้อมูลเพิ่มเติมเกี่ยวกับเรื่องนี้ได้ที่ Pointers As Function Parameters | Tour of WGSL

ฟีเจอร์นี้สามารถตรวจหาได้โดยใช้ navigator.gpu.wgslLanguageFeatures เราขอแนะนำให้ใช้คําสั่ง requires เสมอเพื่อบ่งบอกถึงโอกาสที่โค้ดจะไม่สามารถพอร์ตได้โดยใช้ requires unrestricted_pointer_parameters; ที่ด้านบนของโค้ด Shader WGSL ดูตัวอย่างต่อไปนี้ การเปลี่ยนแปลงข้อกำหนด WGSL และ issue 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 เพื่อบ่งบอกถึงโอกาสที่โค้ดจะไม่สามารถพอร์ตได้โดยใช้ requires pointer_composite_access; ที่ด้านบนของโค้ด Shader WGSL ดูตัวอย่างต่อไปนี้และ issue 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.
  }`
});

สถานะอ่านอย่างเดียวแยกต่างหากสำหรับแสตนซิลและมิติความลึก

ก่อนหน้านี้ ไฟล์แนบเชิงลึกระดับความลึกแบบอ่านอย่างเดียวในพาสการแสดงผลจะต้องเป็นแบบอ่านอย่างเดียวทั้ง 2 ด้าน (ความลึกและสเตนซิล) แต่เราได้ยกเลิกข้อจำกัดนี้แล้ว ตอนนี้คุณใช้แง่มุมความลึกในรูปแบบอ่านอย่างเดียวได้แล้ว เช่น สำหรับการแรเงาเงาสะท้อนจากวัตถุ ในขณะที่มีการเขียนบัฟเฟอร์สเตนซิลเพื่อระบุพิกเซลสำหรับการประมวลผลเพิ่มเติม ดู issue dawn:2146

การอัปเดต Dawn

ตอนนี้ระบบจะเรียกใช้การเรียกกลับข้อผิดพลาดที่ไม่ได้บันทึกไว้ซึ่งตั้งค่าด้วย wgpuDeviceSetUncapturedErrorCallback() ทันทีที่เกิดข้อผิดพลาด ซึ่งเป็นสิ่งที่นักพัฒนาแอปคาดหวังและต้องการสำหรับการแก้ไขข้อบกพร่องเสมอ ดู change dawn:173620

มีการใช้เมธอด wgpuSurfaceGetPreferredFormat() จาก webgpu.h API ดูปัญหา 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