Skip to content
This repository was archived by the owner on Aug 15, 2019. It is now read-only.

Commit 7f87d33

Browse files
author
Nikhil Thorat
authored
Vectorize (vec4) matmul and convolutions. (#129)
* vec4 matmul and conv * for conv benchmarks, make input depth 10 * update depth in html to reflect new 10 input depth * checkpointing, pooling ops faster now * add avg pooling benchmark * change conv depth to 16 in benchmark * Add unit tests * fix lint * respond to comments * lint
1 parent a467449 commit 7f87d33

25 files changed

+814
-729
lines changed

demos/benchmarks/benchmark.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export interface BenchmarkRunGroup {
2525
// A transformation of step to the size passed to the benchmark test.
2626
stepToSizeTransformation?: (step: number) => number;
2727
benchmarkRuns: BenchmarkRun[];
28+
params: {};
2829
}
2930

3031
export class BenchmarkRun {
@@ -39,4 +40,7 @@ export class BenchmarkRun {
3940
}
4041
}
4142

42-
export interface BenchmarkTest { (size: number): number; }
43+
export abstract class BenchmarkTest {
44+
constructor(protected params?: {}) {}
45+
abstract run(size: number): number;
46+
}

demos/benchmarks/conv_benchmarks.ts

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/**
2+
* @license
3+
* Copyright 2017 Google Inc. All Rights Reserved.
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
* =============================================================================
16+
*/
17+
18+
import {initializeGPU} from '../../src/math/ndarray';
19+
import {Conv2DProgram} from '../../src/math/webgl/conv_gpu';
20+
import * as gpgpu_math from '../../src/math/webgl/gpgpu_math';
21+
import {TextureManager} from '../../src/math/webgl/texture_manager';
22+
import {Array1D, Array3D, Array4D, conv_util, GPGPUContext} from '../deeplearn';
23+
24+
import {BenchmarkTest} from './benchmark';
25+
26+
const OP_RUNS = 40;
27+
28+
export interface ConvBenchmarkParams {
29+
inDepth: number;
30+
outDepth: number;
31+
filterSize: number;
32+
stride: number;
33+
}
34+
35+
export abstract class ConvBenchmark extends BenchmarkTest {
36+
constructor(protected params: ConvBenchmarkParams) {
37+
super(params);
38+
}
39+
}
40+
41+
export class ConvGPUBenchmark extends ConvBenchmark {
42+
run(size: number): number {
43+
const gpgpu = new GPGPUContext();
44+
const texManager = new TextureManager(gpgpu);
45+
initializeGPU(gpgpu, texManager);
46+
47+
const inDepth = this.params.inDepth;
48+
const inShape: [number, number, number] = [size, size, inDepth];
49+
const outDepth = this.params.outDepth;
50+
const filterSize = this.params.filterSize;
51+
const stride = this.params.stride;
52+
const hasBias = true;
53+
const convInfo = conv_util.computeConvInfo(
54+
inShape, filterSize, filterSize, outDepth, stride, stride, 'same');
55+
const program = new Conv2DProgram(convInfo, hasBias);
56+
const outputShape = program.outputShape as [number, number, number];
57+
const out = Array3D.zeros(outputShape);
58+
const x = Array3D.randUniform(inShape, -1, 1);
59+
const wShape =
60+
conv_util.computeWeightsShape4D(1, outDepth, filterSize, filterSize);
61+
const W = Array4D.randUniform(wShape, -1, 1);
62+
const b = Array1D.randUniform([outDepth], -1, 1);
63+
const inputs = [x, W, b];
64+
const binary = gpgpu_math.compileProgram(gpgpu, program, inputs, out);
65+
66+
const start = performance.now();
67+
for (let i = 0; i < OP_RUNS; i++) {
68+
gpgpu_math.runProgram(binary, inputs, out);
69+
}
70+
out.getValues();
71+
const avgTime = (performance.now() - start) / OP_RUNS;
72+
73+
x.dispose();
74+
W.dispose();
75+
b.dispose();
76+
out.dispose();
77+
texManager.dispose();
78+
gpgpu.deleteProgram(binary.webGLProgram);
79+
gpgpu.dispose();
80+
81+
return avgTime;
82+
}
83+
}

demos/benchmarks/conv_gpu_benchmark.ts

Lines changed: 0 additions & 69 deletions
This file was deleted.

demos/benchmarks/conv_transpose_gpu_benchmark.ts

Lines changed: 0 additions & 64 deletions
This file was deleted.
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/**
2+
* @license
3+
* Copyright 2017 Google Inc. All Rights Reserved.
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
* =============================================================================
16+
*/
17+
18+
import {initializeGPU} from '../../src/math/ndarray';
19+
import {Conv2DDerInputProgram} from '../../src/math/webgl/conv_backprop_gpu';
20+
import * as gpgpu_math from '../../src/math/webgl/gpgpu_math';
21+
import {TextureManager} from '../../src/math/webgl/texture_manager';
22+
import {Array3D, Array4D, conv_util, GPGPUContext} from '../deeplearn';
23+
24+
import {BenchmarkTest} from './benchmark';
25+
26+
const OP_RUNS = 40;
27+
28+
export interface ConvTransposedBenchmarkParams {
29+
inDepth: number;
30+
outDepth: number;
31+
filterSize: number;
32+
stride: number;
33+
}
34+
35+
export abstract class ConvTransposedBenchmark extends BenchmarkTest {
36+
constructor(protected params: ConvTransposedBenchmarkParams) {
37+
super(params);
38+
}
39+
}
40+
41+
export class ConvTransposedGPUBenchmark extends ConvTransposedBenchmark {
42+
run(size: number): number {
43+
const origInputDepth = 1;
44+
const origOutputDepth = 1;
45+
const xShape: [number, number, number] = [size, size, origOutputDepth];
46+
const fieldSize = 11;
47+
const origStride = 1;
48+
const origPad = 1;
49+
50+
const gpgpu = new GPGPUContext();
51+
const texManager = new TextureManager(gpgpu);
52+
initializeGPU(gpgpu, texManager);
53+
gpgpu.enableAutomaticDebugValidation(true);
54+
55+
const convInfo = conv_util.computeConvInfo(
56+
xShape, fieldSize, fieldSize, origOutputDepth, origStride, origStride,
57+
origPad);
58+
const program = new Conv2DDerInputProgram(convInfo);
59+
const outputShape = program.outputShape as [number, number, number];
60+
const out = Array3D.zeros(outputShape);
61+
const x = Array3D.randUniform(xShape, -1, 1);
62+
const wShape = conv_util.computeWeightsShape4D(
63+
origInputDepth, origOutputDepth, fieldSize, fieldSize);
64+
const W = Array4D.randUniform(wShape, -1, 1);
65+
const inputs = [x, W];
66+
const binary = gpgpu_math.compileProgram(gpgpu, program, inputs, out);
67+
const start = performance.now();
68+
for (let i = 0; i < OP_RUNS; i++) {
69+
gpgpu_math.runProgram(binary, inputs, out);
70+
}
71+
out.getValues();
72+
const avgTime = (performance.now() - start) / OP_RUNS;
73+
74+
texManager.dispose();
75+
gpgpu.deleteProgram(binary.webGLProgram);
76+
gpgpu.dispose();
77+
return avgTime;
78+
}
79+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/**
2+
* @license
3+
* Copyright 2017 Google Inc. All Rights Reserved.
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
* =============================================================================
16+
*/
17+
18+
import {initializeGPU} from '../../src/math/ndarray';
19+
import * as gpgpu_math from '../../src/math/webgl/gpgpu_math';
20+
import {LogSumExpProgram} from '../../src/math/webgl/logsumexp_gpu';
21+
import {TextureManager} from '../../src/math/webgl/texture_manager';
22+
// tslint:disable-next-line:max-line-length
23+
import {Array2D, GPGPUContext, NDArray, NDArrayMathCPU, Scalar} from '../deeplearn';
24+
25+
import {BenchmarkTest} from './benchmark';
26+
27+
const CPU_OPS_PER_RUN = 10;
28+
const GPU_OPS_PER_RUN = 10;
29+
30+
export class LogSumExpCPUBenchmark extends BenchmarkTest {
31+
run(size: number): number {
32+
const math = new NDArrayMathCPU();
33+
const a = NDArray.randUniform<Array2D>([size, size], -1, 1);
34+
const start = performance.now();
35+
for (let i = 0; i < CPU_OPS_PER_RUN; i++) {
36+
math.logSumExp(a);
37+
}
38+
const end = performance.now();
39+
return (end - start) / CPU_OPS_PER_RUN;
40+
}
41+
}
42+
43+
export class LogSumExpGPUBenchmark extends BenchmarkTest {
44+
run(size: number): number {
45+
const gpgpu = new GPGPUContext();
46+
const texManager = new TextureManager(gpgpu);
47+
initializeGPU(gpgpu, texManager);
48+
const out = new Scalar({texture: texManager.acquireTexture([1, 1])});
49+
const a = Array2D.randUniform([size, size], -1, 1);
50+
const program = new LogSumExpProgram(a.size);
51+
const binary = gpgpu_math.compileProgram(gpgpu, program, [a], out);
52+
53+
const start = performance.now();
54+
for (let i = 0; i < GPU_OPS_PER_RUN; i++) {
55+
gpgpu_math.runProgram(binary, [a], out);
56+
}
57+
out.getValues();
58+
const avgTime = (performance.now() - start) / GPU_OPS_PER_RUN;
59+
a.dispose();
60+
out.dispose();
61+
texManager.dispose();
62+
gpgpu.deleteProgram(binary.webGLProgram);
63+
gpgpu.dispose();
64+
65+
return avgTime;
66+
}
67+
}

0 commit comments

Comments
 (0)