| 30 | } |
| 31 | |
| 32 | shared_ptr<Tensor> createAndRun(int timesteps, int batch, int inDim, int stateDim, bool bidirectional, float *input, |
| 33 | float *weights, float *initH, float *initC, vector<int> lengths, |
| 34 | Tensor::DimensionType dimType = Tensor::CAFFE) { |
| 35 | auto creator = MNNGetExtraRuntimeCreator((MNNForwardType)0); |
| 36 | std::shared_ptr<Runtime> runtime; |
| 37 | Backend::Info info; |
| 38 | info.type = (MNNForwardType)0; |
| 39 | runtime.reset(creator->onCreate(info)); |
| 40 | auto backend = shared_ptr<CPUBackend>((CPUBackend *)(runtime->onCreate())); |
| 41 | |
| 42 | auto inTensor = createTensorFromData(vector<int>{batch, timesteps, inDim}, input, dimType, backend.get()); |
| 43 | |
| 44 | vector<shared_ptr<Tensor>> weightTensors = {}; |
| 45 | vector<shared_ptr<Tensor>> initHs = {}; |
| 46 | vector<shared_ptr<Tensor>> initCs = {}; |
| 47 | int offside = 0; |
| 48 | int s_offside = 0; |
| 49 | for (int i = 0; i < (bidirectional ? 2 : 1); i++) { |
| 50 | // Wi, Wn, Wf, Wo |
| 51 | for (int j = 0; j < 4; j++) { |
| 52 | weightTensors.push_back( |
| 53 | createTensorFromData(vector<int>{inDim, stateDim}, weights + offside, dimType, backend.get())); |
| 54 | offside += stateDim * inDim; |
| 55 | } |
| 56 | // Ui, Un, Uf, Uo |
| 57 | for (int j = 0; j < 4; j++) { |
| 58 | weightTensors.push_back( |
| 59 | createTensorFromData(vector<int>{stateDim, stateDim}, weights + offside, dimType, backend.get())); |
| 60 | offside += stateDim * stateDim; |
| 61 | } |
| 62 | // Bi, Bn, Bf, Bo |
| 63 | for (int j = 0; j < 4; j++) { |
| 64 | weightTensors.push_back( |
| 65 | createTensorFromData(vector<int>{stateDim}, weights + offside, dimType, backend.get())); |
| 66 | |
| 67 | offside += stateDim; |
| 68 | } |
| 69 | |
| 70 | if (initH) { |
| 71 | initHs.push_back( |
| 72 | createTensorFromData(vector<int>{batch, stateDim}, initH + s_offside, dimType, backend.get())); |
| 73 | } |
| 74 | if (initC) { |
| 75 | initCs.push_back( |
| 76 | createTensorFromData(vector<int>{batch, stateDim}, initC + s_offside, dimType, backend.get())); |
| 77 | } |
| 78 | s_offside += batch * stateDim; |
| 79 | } |
| 80 | |
| 81 | auto blstm = BlstmComputer(inDim, stateDim, bidirectional, backend.get()); |
| 82 | blstm.importWeights(weightTensors); |
| 83 | blstm.onResize(timesteps, batch); |
| 84 | blstm.onExecute(inTensor.get(), lengths, initHs, initCs); |
| 85 | |
| 86 | backend->onReleaseBuffer(inTensor.get(), Backend::DYNAMIC); |
| 87 | for (int i = 0; i < weightTensors.size(); i++) { |
| 88 | backend->onReleaseBuffer(weightTensors[i].get(), Backend::DYNAMIC); |
| 89 | } |
no test coverage detected