Public
Edited
Apr 12, 2023
1 star
Insert cell
Insert cell
Insert cell
adapter.limits.maxBufferSize
Insert cell
Insert cell
device.limits
Insert cell
device.limits.maxBufferSize
Insert cell
shaderModule = device.createShaderModule({
code: `
struct array_f32 {
data: array<f32>,
}

@group(0) @binding(0) var<storage, read> x : array_f32;
@group(0) @binding(1) var<storage, read> y : array_f32;
@group(0) @binding(2) var<storage, read_write> z : array_f32;

@compute @workgroup_size(64)
fn main(@builtin(global_invocation_id) global_id : vec3<u32>) {
// Guard against out-of-bounds work group sizes
var idx = global_id.x;
z.data[idx] = x.data[idx] + y.data[idx];
}
`
});
Insert cell
Insert cell
{
console.clear()

const n = 1000000
const x = new Float32Array(n)
const y = new Float32Array(n)
const z = new Float32Array(n)

for(let i = 0; i < n; i++){
x[i] = i
y[i] = i
}

const xBuffer = device.createBuffer({
mappedAtCreation: true,
size: x.byteLength,
usage: GPUBufferUsage.STORAGE
})

new Float32Array(xBuffer.getMappedRange()).set(x)
xBuffer.unmap()

const yBuffer = device.createBuffer({
mappedAtCreation: true,
size: y.byteLength,
usage: GPUBufferUsage.STORAGE
})
new Float32Array(yBuffer.getMappedRange()).set(y)
yBuffer.unmap()

const resultBuffer = device.createBuffer({
size: y.byteLength,
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC
})



const computePipeline = device.createComputePipeline({
layout: 'auto',
compute: {
module: shaderModule,
entryPoint: "main"
}
});

const bindGroup = device.createBindGroup({
layout: computePipeline.getBindGroupLayout(0),
entries: [
{
binding: 0,
resource: {
buffer: xBuffer
}
},
{
binding: 1,
resource: {
buffer: yBuffer
}
},
{
binding: 2,
resource: {
buffer: resultBuffer
}
}
]
});


const commandEncoder = device.createCommandEncoder();
const passEncoder = commandEncoder.beginComputePass();
passEncoder.setPipeline(computePipeline);
passEncoder.setBindGroup(0, bindGroup);
passEncoder.dispatchWorkgroups(Math.ceil(n/64), 1);
passEncoder.end();

const gpuReadBuffer = device.createBuffer({
size: x.byteLength,
usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
});
// Encode commands for copying buffer to buffer.
commandEncoder.copyBufferToBuffer(
resultBuffer /* source buffer */,
0 /* source offset */,
gpuReadBuffer /* destination buffer */,
0 /* destination offset */,
x.byteLength /* size */
);
// Submit GPU commands.
const gpuCommands = commandEncoder.finish();
device.queue.submit([gpuCommands]);

await gpuReadBuffer.mapAsync(GPUMapMode.READ);
const arrayBuffer = gpuReadBuffer.getMappedRange();
return new Float32Array(arrayBuffer);
}
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more