| 574 | } |
| 575 | |
| 576 | nvinfer1::ILayer* SampleCharRNNLoop::addLSTMLayers(SampleUniquePtr<nvinfer1::INetworkDefinition>& network) |
| 577 | { |
| 578 | nvinfer1::ILayer* dataOut{nullptr}; |
| 579 | |
| 580 | nvinfer1::ITensor* data = network->addInput(mParams.bindingNames.INPUT_BLOB_NAME, nvinfer1::DataType::kFLOAT, |
| 581 | nvinfer1::Dims2(mParams.seqSize, mParams.dataSize)); |
| 582 | ASSERT(data != nullptr); |
| 583 | |
| 584 | nvinfer1::ITensor* hiddenLayers = network->addInput(mParams.bindingNames.HIDDEN_IN_BLOB_NAME, |
| 585 | nvinfer1::DataType::kFLOAT, nvinfer1::Dims2(mParams.layerCount, mParams.hiddenSize)); |
| 586 | ASSERT(hiddenLayers != nullptr); |
| 587 | |
| 588 | nvinfer1::ITensor* cellLayers = network->addInput(mParams.bindingNames.CELL_IN_BLOB_NAME, |
| 589 | nvinfer1::DataType::kFLOAT, nvinfer1::Dims2(mParams.layerCount, mParams.hiddenSize)); |
| 590 | ASSERT(cellLayers != nullptr); |
| 591 | |
| 592 | nvinfer1::ITensor* sequenceSize |
| 593 | = network->addInput(mParams.bindingNames.SEQ_LEN_IN_BLOB_NAME, nvinfer1::DataType::kINT32, nvinfer1::Dims{}); |
| 594 | ASSERT(sequenceSize != nullptr); |
| 595 | |
| 596 | // convert tensorflow weight format to trt weight format |
| 597 | std::array<nvinfer1::Weights, 2> rnnw{ |
| 598 | SampleCharRNNBase::convertRNNWeights(mWeightMap[mParams.weightNames.RNNW_L0_NAME], mParams.dataSize), |
| 599 | SampleCharRNNBase::convertRNNWeights(mWeightMap[mParams.weightNames.RNNW_L1_NAME], mParams.hiddenSize)}; |
| 600 | std::array<nvinfer1::Weights, 2> rnnb{ |
| 601 | SampleCharRNNBase::convertRNNBias(mWeightMap[mParams.weightNames.RNNB_L0_NAME]), |
| 602 | SampleCharRNNBase::convertRNNBias(mWeightMap[mParams.weightNames.RNNB_L1_NAME])}; |
| 603 | |
| 604 | // Store the transformed weights in the weight map so the memory can be properly released later. |
| 605 | mWeightMap["rnnwL0"] = rnnw[0]; |
| 606 | mWeightMap["rnnwL1"] = rnnw[1]; |
| 607 | mWeightMap["rnnbL0"] = rnnb[0]; |
| 608 | mWeightMap["rnnbL1"] = rnnb[1]; |
| 609 | |
| 610 | nvinfer1::ITensor* maxSequenceSize |
| 611 | = network->addConstant(nvinfer1::Dims{}, Weights{DataType::kINT32, &mParams.seqSize, 1})->getOutput(0); |
| 612 | ASSERT(static_cast<size_t>(mParams.layerCount) <= INDICES.size()); |
| 613 | LstmIO lstmNext{data, nullptr, nullptr}; |
| 614 | std::vector<nvinfer1::ITensor*> hiddenOutputs; |
| 615 | std::vector<nvinfer1::ITensor*> cellOutputs; |
| 616 | nvinfer1::Dims2 dimWL0(4 * mParams.hiddenSize, mParams.dataSize); |
| 617 | nvinfer1::Dims2 dimR(4 * mParams.hiddenSize, mParams.hiddenSize); |
| 618 | nvinfer1::Dims dimB{1, {4 * mParams.hiddenSize}}; |
| 619 | nvinfer1::Dims dim0{1, {0}}; |
| 620 | auto extractWeights = [](nvinfer1::Weights weights, Dims start, Dims size) -> nvinfer1::Weights { |
| 621 | const char* data = static_cast<const char*>(weights.values); |
| 622 | int64_t shift = samplesCommon::volume(start); |
| 623 | const int sizeOfElement = samplesCommon::getElementSize(weights.type); |
| 624 | int64_t count = samplesCommon::volume(size); |
| 625 | ASSERT(shift + count <= weights.count); |
| 626 | return nvinfer1::Weights{weights.type, data + shift * sizeOfElement, count}; |
| 627 | }; |
| 628 | for (int i = 0; i < mParams.layerCount; ++i) |
| 629 | { |
| 630 | nvinfer1::Dims dimW = i == 0 ? dimWL0 : dimR; |
| 631 | nvinfer1::ITensor* index |
| 632 | = network->addConstant(nvinfer1::Dims{}, Weights{DataType::kINT32, &INDICES[i], 1})->getOutput(0); |
| 633 | nvinfer1::ITensor* hidden = network->addGather(*hiddenLayers, *index, 0)->getOutput(0); |
nothing calls this directly
no test coverage detected