Novidades da WebGPU (Chrome 123)

François Beaufort
François Beaufort

Suporte para funções integradas do DP4a na WGSL

DP4a (produto escalar com quatro elementos e acumulado) é um conjunto de instruções de GPU comumente usadas na inferência de aprendizado profundo para quantização. Ele executa com eficiência produtos de pontos inteiros de 8 bits para acelerar o cálculo desses modelos quantizados int8. Ela pode economizar (até 75%) de memória e largura de banda de rede e melhorar o desempenho de qualquer modelo de machine learning na inferência em comparação com a versão f32. Por isso, atualmente ele é muito usado em muitos frameworks de IA conhecidos.

Quando a extensão de linguagem da WGSL "packed_4x8_integer_dot_product" está presente em navigator.gpu.wgslLanguageFeatures, agora é possível usar escalares de números inteiros de 32 bits empacotando vetores de quatro componentes de números inteiros de 8 bits como entradas para as instruções do produto escalar no código do shader WGSL com as funções integradas dot4U8Packed e dot4I8Packed. Você também pode usar as instruções de empacotamento e descompactação com vetores de quatro componentes compactados de números inteiros de 8 bits com funções integradas da WGSL pack4xI8, pack4xU8, pack4xI8Clamp, pack4xU8Clamp, unpack4xI8 e unpack4xU8.

É recomendável usar uma requer-diretiva para sinalizar o potencial de não portabilidade com requires packed_4x8_integer_dot_product; na parte superior do código de sombreador da WGSL. Confira o exemplo a seguir e a tonalidade do problema: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
  }`,
});

Agradecimentos especiais à equipe de Web Graphics da Intel em Xangai por conduzir essa especificação e implementação até a conclusão!

Parâmetros de ponteiro irrestritos na WGSL

A extensão de linguagem da WGSL "unrestricted_pointer_parameters" reduz as restrições sobre quais ponteiros podem ser transmitidos para funções da WGSL:

  • Ponteiros de parâmetro de espaços de endereçamento storage, uniform e workgroup para funções declaradas pelo usuário.

  • Transmitir ponteiros para estruturar membros e elementos de matriz em funções declaradas pelo usuário.

Confira Ponteiros como parâmetros de função | Tour da WGSL (em inglês) para saber mais sobre o assunto.

Esse recurso pode ser detectado usando navigator.gpu.wgslLanguageFeatures. É recomendável sempre usar uma exige-diretiva para sinalizar o potencial de não portabilidade com requires unrestricted_pointer_parameters; na parte superior do código de sombreador da WGSL. Confira no exemplo a seguir as mudanças na especificação da WGSL e a tonalidade do problema:2053 (links em inglês).

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);
  }`
});

Sintaxe de açúcar para desreferenciar compostos na WGSL

Quando a extensão de linguagem da WGSL "pointer_composite_access" está presente em navigator.gpu.wgslLanguageFeatures, o código de shader da WGSL agora oferece suporte ao acesso a componentes de tipos de dados complexos usando a mesma sintaxe de ponto (.), seja trabalhando diretamente com os dados ou com um ponteiro para eles. Veja como funciona:

  • Se foo for um ponteiro: foo.bar é uma maneira mais conveniente de escrever (*foo).bar. O asterisco (*) normalmente é necessário para transformar o ponteiro em uma "referência" que pode ser desreferenciada, mas agora tanto ponteiros quanto referências são muito mais semelhantes e quase intercambiáveis.

  • Se foo não for um ponteiro: o operador de ponto (.) vai funcionar exatamente como você faz para acessar diretamente os membros.

Da mesma forma, se pa for um ponteiro que armazena o endereço inicial de uma matriz, o uso de pa[i] fornecerá acesso direto ao local da memória em que o elemento 'i'th dessa matriz está armazenado.

É recomendável usar uma requer-diretiva para sinalizar o potencial de não portabilidade com requires pointer_composite_access; na parte superior do código de sombreador da WGSL. Confira o exemplo a seguir e a tonalidade do problema: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.
  }`
});

Estado somente leitura separado para aspectos de estêncil e de profundidade

Antes, os anexos de estêncil de profundidade somente leitura nas passagens de renderização exigiam que os dois aspectos (profundidade e estêncil) fossem somente leitura. Essa limitação foi removida. Agora, é possível usar o aspecto de profundidade no modo somente leitura para rastreamento de sombra de contato, por exemplo, enquanto o buffer de estêncil é criado para identificar pixels para processamento adicional. Consulte o problema dawn:2146 (link em inglês).

Atualizações do amanhecer

O callback de erro não capturado definido com wgpuDeviceSetUncapturedErrorCallback() agora é chamado imediatamente quando o erro acontece. É isso que os desenvolvedores esperam e querem com frequência na depuração. Veja alterar dawn:173620.

O método wgpuSurfaceGetPreferredFormat() da API webgpu.h foi implementado. Consulte o problema dawn:1362 (link em inglês).

Isso cobre apenas alguns dos principais destaques. Confira a lista completa de confirmações (link em inglês).

Novidades da WebGPU

Uma lista de tudo o que foi abordado na série O que há de novo na WebGPU.

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