Skip to content

Commit 7f3b23a

Browse files
authored
Merge pull request #231 from JingyuanZhang/master
fix(core): support old model json without dataLayout
2 parents 7052a88 + 94a84a4 commit 7f3b23a

File tree

5 files changed

+60
-6
lines changed

5 files changed

+60
-6
lines changed

packages/paddlejs-core/src/commons/interface.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ export interface ModelVar {
3232

3333
export interface Model {
3434
chunkNum?: number;
35+
dataLayout?: string;
3536
ops: ModelOp[];
3637
vars: ModelVar[];
3738
multiOutputs?: ModelVar[]

packages/paddlejs-core/src/opFactory/opDataBuilder.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
import { ModelVar, OpExecutor, OpInputs, OpOutputs, AttrsData, BufferType, OpUniform } from '../commons/interface';
1+
import {
2+
ModelVar, Model, OpExecutor, OpInputs, OpOutputs,
3+
AttrsData, BufferType, OpUniform
4+
} from '../commons/interface';
25
import { GLOBALS } from '../globals';
36
import Tensor from './tensor';
47
import opBehaviors from './opBehaviors';
@@ -21,14 +24,15 @@ export default class OpData {
2124
outputTensors: Tensor[] = [];
2225
fShaderParams: object[] = [];
2326
vars: ModelVar[] = [];
27+
dataLayout: string = '';
2428
iLayer: number = 0;
2529
program: string[] = [];
2630
tensorData: ModelVar[] = [];
2731
isFinalOp: boolean = false;
2832
modelName: string;
2933
bufferType: BufferType = BufferType.FrameBuffer;
3034

31-
constructor(op: OpExecutor, iLayer: number, vars: ModelVar[], isFinalOp: boolean, modelName: string) {
35+
constructor(op: OpExecutor, iLayer: number, model: Model, isFinalOp: boolean, modelName: string) {
3236
const {
3337
type,
3438
inputs,
@@ -46,7 +50,8 @@ export default class OpData {
4650
this.realName = type;
4751
this.isPackedOp = isPacked;
4852
this.bufferType = bufferType;
49-
this.vars = vars;
53+
this.vars = model.vars;
54+
this.dataLayout = model.dataLayout || '';
5055
this.iLayer = iLayer;
5156
this.isFinalOp = isFinalOp;
5257
this.input = inputs;
@@ -221,7 +226,8 @@ export default class OpData {
221226
interpType: data.interpType || 'NEAREST',
222227
isPacked: this.isPackedOp || data.packed || false,
223228
binding: index,
224-
noLayout: GLOBALS.backendInstance?.noLayout
229+
noLayout: GLOBALS.backendInstance?.noLayout,
230+
dataLayout: this.dataLayout
225231
});
226232
if (tensorName === 'out') {
227233
this.outputTensors.push(tensor);

packages/paddlejs-core/src/opFactory/tensor.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ interface TensorParams {
1515
isPacked?: boolean;
1616
binding?: number;
1717
noLayout?: boolean;
18+
dataLayout?: string;
1819
}
1920

2021
export default class Tensor {
@@ -30,6 +31,7 @@ export default class Tensor {
3031
data: Float32Array | number[] | Uint8Array | null = null;
3132
persistable: boolean = false;
3233
interpType: string = 'NEAREST';
34+
dataLayout: string = '';
3335

3436
constructor(opts: TensorParams) {
3537
this.opts = opts;
@@ -41,6 +43,8 @@ export default class Tensor {
4143
this.interpType = opts.interpType || 'NEAREST';
4244
// 设置 tensorId
4345
this.tensorId = opts.type;
46+
// set dataLayout
47+
this.dataLayout = opts.dataLayout;
4448
// 保留 model 原生 shape 长度
4549
this.unformattedShapeLength = opts.shape.length;
4650
// tensor的形状
@@ -61,7 +65,7 @@ export default class Tensor {
6165
this.exceedMax = exceedMax;
6266
// tensor数据
6367
if (opts.data && opts.data.length) {
64-
this.data = new Float32Array(opts.data);
68+
this.data = Utils.genTensorData(opts.data, this.dataLayout, shape, this.isPacked);
6569
opts.data = null;
6670
}
6771
}

packages/paddlejs-core/src/opFactory/utils.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,3 +127,46 @@ export function packOpData(opData, packedName) {
127127
}
128128
return packedOpData;
129129
}
130+
131+
132+
/**
133+
* 将nchw排布数据转为nhwc排布数据
134+
* @param {Array} data tensor data
135+
* @param {Array} shape nchw
136+
* @returns {Array} nhwc data
137+
*/
138+
function nchw2nhwc(data: number[] | Float32Array, shape: number[]): number[] | Float32Array {
139+
const [N, C, H, W] = shape;
140+
const HXW = H * W;
141+
const CXHXW = C * H * W;
142+
const nhwcData: number[] | Float32Array = [];
143+
for (let n = 0; n < N; n++) {
144+
for (let h = 0; h < H; h++) {
145+
for (let w = 0; w < W; w++) {
146+
for (let c = 0; c < C; c++) {
147+
nhwcData.push(data[n * CXHXW + c * HXW + h * W + w]);
148+
}
149+
}
150+
}
151+
}
152+
return nhwcData;
153+
}
154+
155+
/**
156+
* 生成 tensor data,如果数据排布为 nhwc 则直接返回 Float32Array,否则进行排布变换
157+
* @param {Array} data tensor data
158+
* @param {string} dataLayout layout
159+
* @param {Array} shape nchw
160+
* @param {boolean} isPacked
161+
* @returns {Float32Array} nhwc data
162+
*/
163+
export function genTensorData(data: number[] | Float32Array, dataLayout: string, shape: number[], isPacked: boolean) {
164+
if (dataLayout === 'nhwc') {
165+
return new Float32Array(data);
166+
}
167+
const nhwcData: Float32Array | number[] = nchw2nhwc(
168+
data,
169+
[shape[0], shape[1] * (isPacked ? 4 : 1), shape[2], shape[3]]
170+
);
171+
return new Float32Array(nhwcData);
172+
}

packages/paddlejs-core/src/runner.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ export default class Runner {
7575
const opData = new OpData(
7676
op,
7777
iLayer,
78-
this.model.vars,
78+
this.model,
7979
isFinalOp,
8080
this.modelName
8181
);

0 commit comments

Comments
 (0)