| 22 | namespace nvcaffeparser1 |
| 23 | { |
| 24 | ILayer* parsePReLU(INetworkDefinition& network, const trtcaffe::LayerParameter& msg, CaffeWeightFactory& weightFactory, |
| 25 | BlobNameToTensor& tensors) |
| 26 | { |
| 27 | // Caffe stores the slopes as weights rather than as a tensor, and only supports different slopes |
| 28 | // per channel |
| 29 | if (!checkBlobs(msg, 1, 1)) |
| 30 | { |
| 31 | return nullptr; |
| 32 | } |
| 33 | |
| 34 | const trtcaffe::PReLUParameter& p = msg.prelu_param(); |
| 35 | bool channelShared = p.has_channel_shared() ? p.channel_shared() : false; |
| 36 | auto inputDims = tensors[msg.bottom(0)]->getDimensions(); |
| 37 | if (inputDims.nbDims < 2) |
| 38 | { |
| 39 | return nullptr; |
| 40 | } |
| 41 | |
| 42 | int nWeights = channelShared ? 1 : inputDims.d[0]; // Caffe treats second input dimension as channels |
| 43 | Dims slopesDims{inputDims.nbDims, {}}; |
| 44 | std::fill(slopesDims.d, slopesDims.d + slopesDims.nbDims, 1); |
| 45 | slopesDims.d[0] = nWeights; |
| 46 | |
| 47 | Weights w = weightFactory.isInitialized() ? weightFactory(msg.name(), WeightType::kGENERIC) : |
| 48 | weightFactory.allocateWeights(nWeights, std::uniform_real_distribution<float>(0.F, 1.F)); |
| 49 | auto constLayer = network.addConstant(slopesDims, w); |
| 50 | return network.addParametricReLU(*tensors[msg.bottom(0)], *constLayer->getOutput(0)); |
| 51 | } |
| 52 | } //namespace nvcaffeparser1 |
nothing calls this directly
no test coverage detected