From 3b3ac51381f09246dcf11501e07d25161035c7f8 Mon Sep 17 00:00:00 2001 From: Daniel Smilkov Date: Wed, 4 Sep 2019 15:45:51 -0400 Subject: [PATCH 1/4] save --- tfjs-core/src/backends/webgl/backend_webgl.ts | 21 ++++++++++---- .../src/backends/webgl/backend_webgl_test.ts | 28 +++++++++++++++++++ tfjs-core/src/ops/image_ops.ts | 4 +-- 3 files changed, 45 insertions(+), 8 deletions(-) diff --git a/tfjs-core/src/backends/webgl/backend_webgl.ts b/tfjs-core/src/backends/webgl/backend_webgl.ts index 128a42feee3..492f3ac6d59 100644 --- a/tfjs-core/src/backends/webgl/backend_webgl.ts +++ b/tfjs-core/src/backends/webgl/backend_webgl.ts @@ -472,12 +472,12 @@ export class MathBackendWebGL implements KernelBackend { } let buffer = null; + let tmpDownloadTarget: TensorHandle; + if (dtype !== 'complex64' && ENV.get('WEBGL_BUFFER_SUPPORTED')) { // Possibly copy the texture into a buffer before inserting a fence. - const tmpTarget = this.decode(dataId); - - dataId = tmpTarget.dataId; - const tmpData = this.texData.get(tmpTarget.dataId); + tmpDownloadTarget = this.decode(dataId); + const tmpData = this.texData.get(tmpDownloadTarget.dataId); buffer = this.gpgpu.createBufferFromTexture( tmpData.texture, ...tex_util.getDenseTexShape(shape)); @@ -503,9 +503,10 @@ export class MathBackendWebGL implements KernelBackend { vals = this.getValuesFromTexture(dataId); } else { const size = util.sizeFromShape(shape); - vals = this.gpgpu.downloadFloat32MatrixFromBuffer(buffer, size); - this.disposeData(dataId); + } + if (tmpDownloadTarget != null) { + this.disposeData(tmpDownloadTarget.dataId); } const dTypeVals = this.convertAndCacheOnCPU(dataId, vals); @@ -690,6 +691,14 @@ export class MathBackendWebGL implements KernelBackend { return this.texData.get(dataId).texture; } + /** + * Returns internal information for the specific data bucket. Used in unit + * tests. + */ + getDataInfo(dataId: DataId): TextureData { + return this.texData.get(dataId); + } + private getCPUBackend(): KernelBackend|null { if (!ENV.getBool('WEBGL_CPU_FORWARD')) { return null; diff --git a/tfjs-core/src/backends/webgl/backend_webgl_test.ts b/tfjs-core/src/backends/webgl/backend_webgl_test.ts index 9033ce93bd7..bdc70b26282 100644 --- a/tfjs-core/src/backends/webgl/backend_webgl_test.ts +++ b/tfjs-core/src/backends/webgl/backend_webgl_test.ts @@ -506,6 +506,34 @@ describeWithFlags('time webgl', WEBGL_ENVS, () => { }); }); +describeWithFlags('caching on cpu', WEBGL_ENVS, () => { + it('caches on cpu after async read', async () => { + const backend = new MathBackendWebGL(null); + tf.registerBackend('cache-on-cpu', () => backend); + tf.setBackend('cache-on-cpu'); + + const t = tf.square(2); + await t.data(); + const info = backend.getDataInfo(t.dataId); + expect(info.values).not.toBe(null); + + tf.removeBackend('cache-on-cpu'); + }); + + it('caches on cpu after sync read', () => { + const backend = new MathBackendWebGL(null); + tf.registerBackend('cache-on-cpu', () => backend); + tf.setBackend('cache-on-cpu'); + + const t = tf.square(2); + t.dataSync(); + const info = backend.getDataInfo(t.dataId); + expect(info.values).not.toBe(null); + + tf.removeBackend('cache-on-cpu'); + }); +}); + describe('WebGL backend has sync init', () => { it('can do matmul without waiting for ready', async () => { tf.registerBackend('my-webgl', () => { diff --git a/tfjs-core/src/ops/image_ops.ts b/tfjs-core/src/ops/image_ops.ts index ba4ee7dceba..27e5eacb8f4 100644 --- a/tfjs-core/src/ops/image_ops.ts +++ b/tfjs-core/src/ops/image_ops.ts @@ -191,8 +191,8 @@ async function nonMaxSuppressionAsync_( iouThreshold = inputs.iouThreshold; scoreThreshold = inputs.scoreThreshold; - const boxesVals = await $boxes.data(); - const scoresVals = await $scores.data(); + const [boxesVals, scoresVals] = + await Promise.all([$boxes.data(), $scores.data()]); const res = nonMaxSuppressionImpl( boxesVals, scoresVals, maxOutputSize, iouThreshold, scoreThreshold); if ($boxes !== boxes) { From 198d4de7a439f8b81a824a35a624ee12e024a47f Mon Sep 17 00:00:00 2001 From: Daniel Smilkov Date: Wed, 4 Sep 2019 15:50:07 -0400 Subject: [PATCH 2/4] save --- tfjs-core/src/backends/webgl/backend_webgl_test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tfjs-core/src/backends/webgl/backend_webgl_test.ts b/tfjs-core/src/backends/webgl/backend_webgl_test.ts index bdc70b26282..5cdd1c2c624 100644 --- a/tfjs-core/src/backends/webgl/backend_webgl_test.ts +++ b/tfjs-core/src/backends/webgl/backend_webgl_test.ts @@ -508,7 +508,7 @@ describeWithFlags('time webgl', WEBGL_ENVS, () => { describeWithFlags('caching on cpu', WEBGL_ENVS, () => { it('caches on cpu after async read', async () => { - const backend = new MathBackendWebGL(null); + const backend = new MathBackendWebGL(); tf.registerBackend('cache-on-cpu', () => backend); tf.setBackend('cache-on-cpu'); @@ -521,7 +521,7 @@ describeWithFlags('caching on cpu', WEBGL_ENVS, () => { }); it('caches on cpu after sync read', () => { - const backend = new MathBackendWebGL(null); + const backend = new MathBackendWebGL(); tf.registerBackend('cache-on-cpu', () => backend); tf.setBackend('cache-on-cpu'); From cb7e60c0d94c23013c4dcc382ddae648355a4e47 Mon Sep 17 00:00:00 2001 From: Daniel Smilkov Date: Wed, 4 Sep 2019 15:56:29 -0400 Subject: [PATCH 3/4] save --- tfjs-core/src/backends/webgl/backend_webgl_test.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tfjs-core/src/backends/webgl/backend_webgl_test.ts b/tfjs-core/src/backends/webgl/backend_webgl_test.ts index 5cdd1c2c624..5b0cc4036b2 100644 --- a/tfjs-core/src/backends/webgl/backend_webgl_test.ts +++ b/tfjs-core/src/backends/webgl/backend_webgl_test.ts @@ -16,7 +16,7 @@ */ import * as tf from '../../index'; -import {describeWithFlags} from '../../jasmine_util'; +import {Constraints, describeWithFlags} from '../../jasmine_util'; import {expectArraysClose, expectArraysEqual} from '../../test_util'; import {decodeString, encodeString} from '../../util'; @@ -506,7 +506,14 @@ describeWithFlags('time webgl', WEBGL_ENVS, () => { }); }); -describeWithFlags('caching on cpu', WEBGL_ENVS, () => { +const WEBGL_WITHOUT_CPU_FORWARD: Constraints = { + predicate: testEnv => { + return testEnv.backendName === 'webgl' && + !testEnv.flags['WEBGL_CPU_FORWARD']; + } +}; + +describeWithFlags('caching on cpu', WEBGL_WITHOUT_CPU_FORWARD, () => { it('caches on cpu after async read', async () => { const backend = new MathBackendWebGL(); tf.registerBackend('cache-on-cpu', () => backend); From c9142bc110836dc9c602bef18f71aac03bf46f31 Mon Sep 17 00:00:00 2001 From: Daniel Smilkov Date: Wed, 4 Sep 2019 16:12:35 -0400 Subject: [PATCH 4/4] save --- .../src/backends/webgl/backend_webgl_test.ts | 29 ++++++++++++------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/tfjs-core/src/backends/webgl/backend_webgl_test.ts b/tfjs-core/src/backends/webgl/backend_webgl_test.ts index 5b0cc4036b2..f12d5a5c270 100644 --- a/tfjs-core/src/backends/webgl/backend_webgl_test.ts +++ b/tfjs-core/src/backends/webgl/backend_webgl_test.ts @@ -16,7 +16,7 @@ */ import * as tf from '../../index'; -import {Constraints, describeWithFlags} from '../../jasmine_util'; +import {describeWithFlags} from '../../jasmine_util'; import {expectArraysClose, expectArraysEqual} from '../../test_util'; import {decodeString, encodeString} from '../../util'; @@ -506,22 +506,25 @@ describeWithFlags('time webgl', WEBGL_ENVS, () => { }); }); -const WEBGL_WITHOUT_CPU_FORWARD: Constraints = { - predicate: testEnv => { - return testEnv.backendName === 'webgl' && - !testEnv.flags['WEBGL_CPU_FORWARD']; - } -}; +describeWithFlags('caching on cpu', WEBGL_ENVS, () => { + beforeAll(() => { + tf.ENV.set('WEBGL_CPU_FORWARD', false); + }); -describeWithFlags('caching on cpu', WEBGL_WITHOUT_CPU_FORWARD, () => { it('caches on cpu after async read', async () => { const backend = new MathBackendWebGL(); tf.registerBackend('cache-on-cpu', () => backend); tf.setBackend('cache-on-cpu'); const t = tf.square(2); - await t.data(); const info = backend.getDataInfo(t.dataId); + + // Make sure the tensor is on the GPU. + expect(info.values == null).toBe(true); + + await t.data(); + + // Make sure the tensor is cached on CPU. expect(info.values).not.toBe(null); tf.removeBackend('cache-on-cpu'); @@ -533,8 +536,14 @@ describeWithFlags('caching on cpu', WEBGL_WITHOUT_CPU_FORWARD, () => { tf.setBackend('cache-on-cpu'); const t = tf.square(2); - t.dataSync(); const info = backend.getDataInfo(t.dataId); + + // Make sure the tensor is on the GPU. + expect(info.values == null).toBe(true); + + t.dataSync(); + + // Make sure the tensor is cached on CPU. expect(info.values).not.toBe(null); tf.removeBackend('cache-on-cpu');