| 135 | } |
| 136 | |
| 137 | void sparsifyMatMulKernelWeights(nvinfer1::INetworkDefinition& network, std::vector<std::vector<int8_t>>& sparseWeights) |
| 138 | { |
| 139 | using TensorToLayer = std::unordered_map<nvinfer1::ITensor*, nvinfer1::ILayer*>; |
| 140 | using LayerToTensor = std::unordered_map<nvinfer1::ILayer*, nvinfer1::ITensor*>; |
| 141 | |
| 142 | // 1. Collect layers and tensors information from the network. |
| 143 | TensorToLayer matmulI2L; |
| 144 | TensorToLayer constO2L; |
| 145 | TensorToLayer shuffleI2L; |
| 146 | LayerToTensor shuffleL2O; |
| 147 | auto collectMappingInfo = [&](int32_t const idx) |
| 148 | { |
| 149 | ILayer* l = network.getLayer(idx); |
| 150 | switch (l->getType()) |
| 151 | { |
| 152 | case nvinfer1::LayerType::kMATRIX_MULTIPLY: |
| 153 | { |
| 154 | // assume weights on the second input. |
| 155 | matmulI2L.insert({l->getInput(1), l}); |
| 156 | break; |
| 157 | } |
| 158 | case nvinfer1::LayerType::kCONSTANT: |
| 159 | { |
| 160 | DataType const dtype = static_cast<nvinfer1::IConstantLayer*>(l)->getWeights().type; |
| 161 | if (dtype == nvinfer1::DataType::kFLOAT || dtype == nvinfer1::DataType::kHALF) |
| 162 | { |
| 163 | // Sparsify float only. |
| 164 | constO2L.insert({l->getOutput(0), l}); |
| 165 | } |
| 166 | break; |
| 167 | } |
| 168 | case nvinfer1::LayerType::kSHUFFLE: |
| 169 | { |
| 170 | shuffleI2L.insert({l->getInput(0), l}); |
| 171 | shuffleL2O.insert({l, l->getOutput(0)}); |
| 172 | break; |
| 173 | } |
| 174 | default: break; |
| 175 | } |
| 176 | }; |
| 177 | int32_t const nbLayers = network.getNbLayers(); |
| 178 | for (int32_t i = 0; i < nbLayers; ++i) |
| 179 | { |
| 180 | collectMappingInfo(i); |
| 181 | } |
| 182 | if (matmulI2L.size() == 0 || constO2L.size() == 0) |
| 183 | { |
| 184 | // No MatrixMultiply or Constant layer found, no weights to sparsify. |
| 185 | return; |
| 186 | } |
| 187 | |
| 188 | // Helper for analysis |
| 189 | auto isTranspose |
| 190 | = [](nvinfer1::Permutation const& perm) -> bool { return (perm.order[0] == 1 && perm.order[1] == 0); }; |
| 191 | auto is2D = [](nvinfer1::Dims const& dims) -> bool { return dims.nbDims == 2; }; |
| 192 | auto isIdenticalReshape = [](nvinfer1::Dims const& dims) -> bool |
| 193 | { |
| 194 | for (int32_t i = 0; i < dims.nbDims; ++i) |
no test coverage detected