|
| 1 | +/** |
| 2 | + * @file stack dynamic inputs |
| 3 | + * @description stack inputs X supports no more than 15 tensors, eg. [a1, a2, a3, a4, ... , a15] |
| 4 | + * @detail https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/fluid/operators/stack_op.h#L56 |
| 5 | + * @detail https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/stack_cn.html#stack |
| 6 | + */ |
| 7 | + |
| 8 | +/* eslint-disable max-lines */ |
| 9 | +function mainFunc( |
| 10 | + { out, ...inputs }, |
| 11 | + attrs |
| 12 | +) { |
| 13 | + const origin_tensor = inputs['origin']; |
| 14 | + const { |
| 15 | + width_shape, |
| 16 | + height_shape, |
| 17 | + channel, |
| 18 | + total_shape, |
| 19 | + length_unformatted_shape |
| 20 | + } = origin_tensor; |
| 21 | + const batch = total_shape / (width_shape * height_shape * channel); |
| 22 | + |
| 23 | + const tensor_shape = [batch, channel, height_shape, width_shape]; |
| 24 | + const origin_shape = tensor_shape.slice(length_unformatted_shape); |
| 25 | + |
| 26 | + const inputs_num = Object.keys(inputs).length; |
| 27 | + |
| 28 | + const axis = attrs.axis < 0 ? attrs.axis + origin_shape.length + 1 : attrs.axis; |
| 29 | + |
| 30 | + let pre = 1; |
| 31 | + let post = 1; |
| 32 | + for (let index = 0; index < axis; index++) { |
| 33 | + pre *= origin_shape[index]; |
| 34 | + } |
| 35 | + for (let index = axis; index < origin_shape.length; index++) { |
| 36 | + post *= origin_shape[index]; |
| 37 | + } |
| 38 | + |
| 39 | + const out_total_shape = out.total_shape; |
| 40 | + |
| 41 | + const pre_every_num = out_total_shape / pre; |
| 42 | + |
| 43 | + let getMultiInputsValue = ''; |
| 44 | + getMultiInputsValue = Array.from(Array(inputs_num).keys()).reduce((acc, cur) => { |
| 45 | + return acc + (cur === 0 |
| 46 | + ? ` |
| 47 | + if (i == 0) { |
| 48 | + ivec4 co = getTensorPosFromArrayIndex_origin(j); |
| 49 | + o = getValueFromTensorPos_origin(co.r, co.g, co.b, co.a); |
| 50 | + }` |
| 51 | + : ` |
| 52 | + else if (i == ${cur}) { |
| 53 | + ivec4 co = getTensorPosFromArrayIndex_origin_${cur}(j); |
| 54 | + o = getValueFromTensorPos_origin_${cur}(co.r, co.g, co.b, co.a); |
| 55 | + }`); |
| 56 | + }, getMultiInputsValue); |
| 57 | + |
| 58 | + |
| 59 | + return ` |
| 60 | + // start函数 |
| 61 | + void main(void) { |
| 62 | + ivec4 oPos = getOutputTensorPos(); |
| 63 | + // 输出坐标转换为输入坐标 |
| 64 | + int sumVal = oPos.a |
| 65 | + + oPos.b * ${out.width_shape} |
| 66 | + + oPos.g * ${out.height_shape} * ${out.width_shape} |
| 67 | + + oPos.r * ${out.channel} * ${out.width_shape} * ${out.height_shape}; |
| 68 | +
|
| 69 | + int index = sumVal % ${pre_every_num}; |
| 70 | +
|
| 71 | + int layer = sumVal / ${pre_every_num}; |
| 72 | +
|
| 73 | + int i = index / ${post}; |
| 74 | + int j = index % ${post} + layer * ${post}; |
| 75 | +
|
| 76 | + |
| 77 | + float o = 0.0; |
| 78 | + ${getMultiInputsValue} |
| 79 | + setOutput(float(o)); |
| 80 | + } |
| 81 | + `; |
| 82 | +} |
| 83 | +export default { |
| 84 | + mainFunc, |
| 85 | + textureFuncConf: { |
| 86 | + '@all': ['getValueFromTensorPos', 'getTensorPosFromArrayIndex'] |
| 87 | + } |
| 88 | +}; |
0 commit comments