(dataId: object)
| 377 | } |
| 378 | |
| 379 | override readSync(dataId: object): BackendValues { |
| 380 | const tensorData = this.tensorMap.get(dataId); |
| 381 | const {values, complexTensorInfos} = tensorData; |
| 382 | |
| 383 | if (values != null || tensorData.dtype === 'string') { |
| 384 | return values; |
| 385 | } |
| 386 | |
| 387 | if (tensorData.dtype === 'complex64') { |
| 388 | const realValues = |
| 389 | this.readSync(complexTensorInfos.real.dataId) as Float32Array; |
| 390 | const imagValues = |
| 391 | this.readSync(complexTensorInfos.imag.dataId) as Float32Array; |
| 392 | const complexVals = util.convertBackendValuesAndArrayBuffer( |
| 393 | backend_util.mergeRealAndImagArrays(realValues, imagValues).buffer, |
| 394 | 'float32'); |
| 395 | this.convertAndCacheOnCPU(dataId, complexVals); |
| 396 | return complexVals; |
| 397 | } |
| 398 | |
| 399 | if (!this.hasReadSyncWarned) { |
| 400 | this.hasReadSyncWarned = true; |
| 401 | console.warn( |
| 402 | `The performance of synchronously reading data from GPU to CPU is ` + |
| 403 | `poor on the webgpu backend, please use asynchronous APIs instead.`); |
| 404 | } |
| 405 | |
| 406 | const alphaModes: GPUCanvasAlphaMode[] = ['opaque', 'premultiplied']; |
| 407 | |
| 408 | const buffer = tensorData.resource as GPUBuffer; |
| 409 | const bufferSize = buffer.size; |
| 410 | util.assert( |
| 411 | bufferSize % 4 === 0, |
| 412 | () => 'Because there is 4 bytes for ' + |
| 413 | 'one pixel, buffer size must be multiple of 4.'); |
| 414 | const pixelsSize = bufferSize / 4; |
| 415 | const valsGPU = new ArrayBuffer(bufferSize); |
| 416 | // TODO: adjust the reading window size according the `bufferSize`. |
| 417 | const canvasWidth = 256, canvasHeight = 256; |
| 418 | const stagingDeviceStorage: OffscreenCanvas[] = |
| 419 | alphaModes.map(_ => new OffscreenCanvas(canvasWidth, canvasHeight)); |
| 420 | const stagingHostStorage = new OffscreenCanvas(canvasWidth, canvasHeight); |
| 421 | |
| 422 | this.endComputePassEncoder(); |
| 423 | stagingDeviceStorage |
| 424 | .map((storage, index) => { |
| 425 | const context = storage.getContext('webgpu'); |
| 426 | // TODO: use rgba8unorm format when this format is supported on Mac. |
| 427 | // https://bugs.chromium.org/p/chromium/issues/detail?id=1298618 |
| 428 | context.configure({ |
| 429 | device: this.device, |
| 430 | format: 'bgra8unorm', |
| 431 | usage: GPUTextureUsage.COPY_DST, |
| 432 | alphaMode: alphaModes[index], |
| 433 | }); |
| 434 | return context.getCurrentTexture(); |
| 435 | }) |
| 436 | .map((texture, index) => { |
no test coverage detected