forked from tensorflow/tfjs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathresize_bilinear_gpu.ts
85 lines (71 loc) · 3.06 KB
/
resize_bilinear_gpu.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/**
* @license
* Copyright 2017 Google LLC. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================================
*/
import {GPGPUProgram} from './gpgpu_math';
export class ResizeBilinearProgram implements GPGPUProgram {
variableNames = ['A'];
outputShape: number[] = [];
userCode: string;
constructor(
inputShape: [number, number, number, number], newHeight: number,
newWidth: number, alignCorners: boolean, halfPixelCenters: boolean) {
const [batch, oldHeight, oldWidth, depth] = inputShape;
this.outputShape = [batch, newHeight, newWidth, depth];
const effectiveInSize: [number, number] = [
(alignCorners && newHeight > 1) ? oldHeight - 1 : oldHeight,
(alignCorners && newWidth > 1) ? oldWidth - 1 : oldWidth
];
const effectiveOutSize: [number, number] = [
(alignCorners && newHeight > 1) ? newHeight - 1 : newHeight,
(alignCorners && newWidth > 1) ? newWidth - 1 : newWidth
];
let sourceFracIndexRC: string;
if (halfPixelCenters) {
sourceFracIndexRC =
`(vec2(yRC) + vec2(0.5)) * effectiveInputOverOutputRatioRC` +
` - vec2(0.5)`;
} else {
sourceFracIndexRC = `vec2(yRC) * effectiveInputOverOutputRatioRC`;
}
this.userCode = `
const vec2 effectiveInputOverOutputRatioRC = vec2(
${effectiveInSize[0] / effectiveOutSize[0]},
${effectiveInSize[1] / effectiveOutSize[1]});
const vec2 inputShapeRC = vec2(${oldHeight}.0, ${oldWidth}.0);
void main() {
ivec4 coords = getOutputCoords();
int b = coords[0];
int d = coords[3];
ivec2 yRC = coords.yz;
// Fractional source index.
vec2 sourceFracIndexRC = ${sourceFracIndexRC};
// Compute the four integer indices.
ivec2 sourceFloorRC = ivec2(max(sourceFracIndexRC, vec2(0.0)));
ivec2 sourceCeilRC = ivec2(
min(inputShapeRC - 1.0, ceil(sourceFracIndexRC)));
float topLeft = getA(b, sourceFloorRC.x, sourceFloorRC.y, d);
float bottomLeft = getA(b, sourceCeilRC.x, sourceFloorRC.y, d);
float topRight = getA(b, sourceFloorRC.x, sourceCeilRC.y, d);
float bottomRight = getA(b, sourceCeilRC.x, sourceCeilRC.y, d);
vec2 fracRC = sourceFracIndexRC - vec2(sourceFloorRC);
float top = topLeft + (topRight - topLeft) * fracRC.y;
float bottom = bottomLeft + (bottomRight - bottomLeft) * fracRC.y;
float newValue = top + (bottom - top) * fracRC.x;
setOutput(newValue);
}
`;
}
}