@@ -7,7 +7,7 @@ import {ProgramInfo, ProgramInputTensorInfoDependency, ProgramUniform} from '../
7
7
8
8
import { createTensorShapeVariables , getMaxComponents , inputVariable , outputVariable , ShaderHelper , UniformsArrayType } from './common' ;
9
9
import { calculateOutputShape , ConvAttributes } from './conv' ;
10
- import { getActivationSnippet } from './fuse-utils' ;
10
+ import { appendActivationUniforms , appendActivationUniformsData , getActivationSnippet } from './fuse-utils' ;
11
11
12
12
/**
13
13
* naive grouped conv implementation, supports 1d/2d conv
@@ -32,10 +32,7 @@ export const createGroupedConvProgramInfo =
32
32
{ type : 'uint32' , data : [ attributes . strides [ 0 ] , attributes . strides [ 1 ] ] } ,
33
33
{ type : 'uint32' , data : [ attributes . pads [ 0 ] , attributes . pads [ 1 ] ] } , { type : 'uint32' , data : outputChannelsPerGroup }
34
34
] ;
35
- if ( attributes . activation === 'Clip' ) {
36
- programUniforms . push (
37
- { type : 'float32' , data : attributes . clipMax ! } , { type : 'float32' , data : attributes . clipMin ! } ) ;
38
- }
35
+ appendActivationUniformsData ( attributes , programUniforms ) ;
39
36
programUniforms . push (
40
37
...createTensorShapeVariables ( xShape ) , ...createTensorShapeVariables ( wShape ) ,
41
38
...createTensorShapeVariables ( outputShape ) ) ;
@@ -61,9 +58,7 @@ export const createGroupedConvProgramInfo =
61
58
{ name : 'strides' , type : 'u32' , length : 2 } , { name : 'pads' , type : 'u32' , length : 2 } ,
62
59
{ name : 'output_channels_per_group' , type : 'u32' }
63
60
] ;
64
- if ( attributes . activation === 'Clip' ) {
65
- uniforms . push ( { name : 'clip_max' , type : 'f32' } , { name : 'clip_min' , type : 'f32' } ) ;
66
- }
61
+ appendActivationUniforms ( attributes , uniforms ) ;
67
62
return `
68
63
${ shaderHelper . registerUniforms ( uniforms ) . declareVariables ( ...inputVars , output ) }
69
64
@@ -132,10 +127,13 @@ export const createGroupedConvVectorizeProgramInfo =
132
127
const outputShapeInShader = [ outputShape [ 0 ] , outputShape [ 1 ] , outputShape [ 2 ] , outputShape [ 3 ] / components ] ;
133
128
134
129
const programUniforms : ProgramUniform [ ] = [
135
- { type : 'uint32' , data : outputSize } , { type : 'int32' , data : attributes . strides } ,
136
- { type : 'int32' , data : attributes . pads } , ...createTensorShapeVariables ( xShape ) ,
137
- ...createTensorShapeVariables ( wShape ) , ...createTensorShapeVariables ( outputShapeInShader )
130
+ { type : 'uint32' , data : outputSize } , { type : 'int32' , data : [ attributes . strides [ 0 ] , attributes . strides [ 1 ] ] } ,
131
+ { type : 'int32' , data : [ attributes . pads [ 0 ] , attributes . pads [ 1 ] ] }
138
132
] ;
133
+ appendActivationUniformsData ( attributes , programUniforms ) ;
134
+ programUniforms . push (
135
+ ...createTensorShapeVariables ( xShape ) , ...createTensorShapeVariables ( wShape ) ,
136
+ ...createTensorShapeVariables ( outputShapeInShader ) ) ;
139
137
const xNumber = ( outputNumber - 1 ) * attributes . strides [ 1 ] + wShape [ 1 ] ;
140
138
const getShaderSource = ( shaderHelper : ShaderHelper ) => {
141
139
const output = outputVariable ( 'output' , inputs [ 0 ] . dataType , outputShapeInShader . length , components ) ;
@@ -147,13 +145,14 @@ export const createGroupedConvVectorizeProgramInfo =
147
145
inputVars . push ( inputVariable ( 'b' , inputs [ 2 ] . dataType , inputs [ 2 ] . dims , components ) ) ;
148
146
}
149
147
const processBias = hasBias ? 'value += b[output_channel];' : '' ;
150
-
148
+ const uniforms : UniformsArrayType = [
149
+ { name : 'output_size' , type : 'u32' } ,
150
+ { name : 'strides' , type : 'i32' , length : 2 } ,
151
+ { name : 'pads' , type : 'i32' , length : 2 } ,
152
+ ] ;
153
+ appendActivationUniforms ( attributes , uniforms ) ;
151
154
return `
152
- ${
153
- shaderHelper . registerUniform ( 'output_size' , 'u32' )
154
- . registerUniform ( 'strides' , 'i32' , 2 )
155
- . registerUniform ( 'pads' , 'i32' , 2 )
156
- . declareVariables ( ...inputVars , output ) }
155
+ ${ shaderHelper . registerUniforms ( uniforms ) . declareVariables ( ...inputVars , output ) }
157
156
${ shaderHelper . mainStart ( ) }
158
157
${ shaderHelper . guardAgainstOutOfBoundsWorkgroupSizes ( 'uniforms.output_size' ) }
159
158
let width0 = uniforms.output_shape[3];
@@ -173,7 +172,7 @@ export const createGroupedConvVectorizeProgramInfo =
173
172
// Use constant instead of uniform can give better performance for w's height/width.
174
173
for (var w_height: u32 = 0u; w_height < ${ wShape [ 0 ] } ; w_height++) {
175
174
let x_height = x_corner.x + i32(w_height);
176
- if (x_height >= 0 || u32(x_height) < uniforms.x_shape[1]) {
175
+ if (x_height >= 0 && u32(x_height) < uniforms.x_shape[1]) {
177
176
for (var i = 0; i < ${ xNumber } ; i++) {
178
177
let x_width = x_corner.y + i;
179
178
if (x_width >= 0 && u32(x_width) < uniforms.x_shape[2]) {
@@ -185,7 +184,7 @@ export const createGroupedConvVectorizeProgramInfo =
185
184
for (var w_width: u32 = 0u; w_width < ${ wShape [ 1 ] } ; w_width++) {
186
185
let w_val = ${ w . get ( 'w_height' , 'w_width' , '0' , 'output_channel' ) } ;
187
186
for (var i = 0u; i < ${ outputNumber } u; i++) {
188
- values[i] = fma(x_vals[i * ${ attributes . strides [ 1 ] } u + w_width], w_val, values[i]);
187
+ values[i] = fma(x_vals[i * u32(uniforms .strides[1]) + w_width], w_val, values[i]);
189
188
}
190
189
}
191
190
}
0 commit comments