| 22 | namespace nvcaffeparser1 |
| 23 | { |
| 24 | ILayer* parseReduction(INetworkDefinition& network, const trtcaffe::LayerParameter& msg, CaffeWeightFactory& weightFactory, BlobNameToTensor& tensors) |
| 25 | { |
| 26 | // The first axis to reduce to a scalar -- may be negative to index from the |
| 27 | // end (e.g., -1 for the last axis). |
| 28 | // (Currently, only reduction along ALL "tail" axes is supported; reduction |
| 29 | // of axis M through N, where N < num_axes - 1, is unsupported.) |
| 30 | // Suppose we have an n-axis bottom Blob with shape: |
| 31 | // (d0, d1, d2, ..., d(m-1), dm, d(m+1), ..., d(n-1)). |
| 32 | // If axis == m, the output Blob will have shape |
| 33 | // (d0, d1, d2, ..., d(m-1)), |
| 34 | // and the ReductionOp operation is performed (d0 * d1 * d2 * ... * d(m-1)) |
| 35 | // times, each including (dm * d(m+1) * ... * d(n-1)) individual data. |
| 36 | // If axis == 0 (the default), the output Blob always has the empty shape |
| 37 | // (count 1), performing reduction across the entire input -- |
| 38 | // often useful for creating new loss functions. |
| 39 | if (!checkBlobs(msg, 1, 1)) |
| 40 | { |
| 41 | return nullptr; |
| 42 | } |
| 43 | |
| 44 | // operation == 1 is SUM -> ReduceOperation::kSUM |
| 45 | const int SUM = 1; |
| 46 | // operation == 2 is ASUM -> UnaryOperation::kABS and ReduceOperation::kSUM |
| 47 | const int ASUM = 2; |
| 48 | // operation == 3 is SUMSQ -> ElementWiseOperation::kPROD and ReduceOperation::kSUM |
| 49 | const int SUMSQ = 3; |
| 50 | // operation == 4 is MEAN -> ReduceOperation::kAVG |
| 51 | const int MEAN = 4; |
| 52 | |
| 53 | const trtcaffe::ReductionParameter& p = msg.reduction_param(); |
| 54 | bool hasOperation = p.has_operation(); // optional parameter |
| 55 | bool hasAxis = p.has_axis(); // optional parameter |
| 56 | bool hasCoeff = p.has_coeff(); // optional parameter |
| 57 | int operation = hasOperation ? p.operation() : SUM; // default is SUM |
| 58 | int axis = hasAxis ? p.axis() : 0; // default is 0 |
| 59 | axis = (axis < 0) ? 4 + axis : axis; // axis negative number correction |
| 60 | float coeff = hasCoeff ? p.coeff() : 1.0; // default is 1 |
| 61 | |
| 62 | // With implicit batch dimensions: |
| 63 | // acceptable axis values: 1, 2, 3, -1, -2, -3 |
| 64 | // unacceptable axis values: 0 and anything else |
| 65 | // acceptable corrected axis values: 1, 2, 3 |
| 66 | // unacceptable corrected axis values: 0 and anything else |
| 67 | // |
| 68 | // With implicit batch dimensions: |
| 69 | // acceptable axis values: 1, 2, 3, 0, -1, -2, -3 |
| 70 | // unacceptable axis values: anything else |
| 71 | // acceptable corrected axis values: 0, 1, 2, 3 |
| 72 | // unacceptable corrected axis values: 0 |
| 73 | // |
| 74 | // protect against "garbage" input arguments |
| 75 | if (axis < 0 || axis > 3) |
| 76 | { |
| 77 | std::cout << "Caffe Parser: Invalid axis in reduction layer - can only reduce NCHW input." << std::endl; |
| 78 | return nullptr; |
| 79 | } |
| 80 | if (network.hasImplicitBatchDimension() && axis == 0) |
| 81 | { |
nothing calls this directly
no test coverage detected