| 151 | } |
| 152 | |
| 153 | int main(int argc, const char* argv[]) { |
| 154 | if (argc < 6) { |
| 155 | MNN_PRINT("This tool generates offline caches for the QNN backend."); |
| 156 | MNN_PRINT("Usage: %s <qnnSDKPath> <socId> <hexagonArch> <srcMNNPath> <outputDir> [totalShapeNum] [inputShape1] [inputShape2] ...\n", argv[0]); |
| 157 | MNN_PRINT(" <qnnSDKPath> : Path to the QNN SDK directory.\n"); |
| 158 | MNN_PRINT(" <socId> : Target SoC ID.\n"); |
| 159 | MNN_PRINT(" Common SoCs: 8Gen2 -> 43, 8Gen3 -> 57, 8 Elite -> 69. For others, please refer to Qualcomm's documentation.\n"); |
| 160 | MNN_PRINT(" <hexagonArch> : Hexagon architecture version. This tool requires v73 or higher for weight sharing.\n"); |
| 161 | MNN_PRINT(" Common Archs: 8Gen2 -> 73, 8Gen3 -> 75, 8 Elite -> 79. For others, please refer to Qualcomm's documentation.\n"); |
| 162 | MNN_PRINT(" <srcMNNPath> : Path to the source MNN model file.\n"); |
| 163 | MNN_PRINT(" <outputDir> : Directory to save the generated files, including a MNN model file with the suffix '.mnn' and a QNN serialized artifact with the suffix '.bin'.\n"); |
| 164 | MNN_PRINT(" [<totalShapeNum>] : Optional. Number of dynamic input shape configurations.\n"); |
| 165 | MNN_PRINT(" [<inputShapeN>] : Optional. Input shape configuration. Can be a shape string or a path to a .mnn file.\n"); |
| 166 | MNN_PRINT(" Shape string format for multiple inputs: dim1xdim2_dim3xdim4. Example: 1x3x512x512_1x256\n"); |
| 167 | MNN_PRINT("Examples:\n"); |
| 168 | MNN_PRINT(" 1. Use default shape from the MNN model:\n"); |
| 169 | MNN_PRINT(" %s /path/to/qnn/sdk 57 75 /path/to/model.mnn /path/to/output\n", argv[0]); |
| 170 | MNN_PRINT(" 2. Specify two dynamic input shapes:\n"); |
| 171 | MNN_PRINT(" %s /path/to/qnn/sdk 57 75 /path/to/model.mnn /path/to/output 2 1x3x512x512_1x256 1x3x256x256_1x128\n", argv[0]); |
| 172 | MNN_PRINT(" %s /path/to/qnn/sdk 57 75 /path/to/model.mnn /path/to/output 2 input_0.mnn input_1.mnn\n", argv[0]); |
| 173 | |
| 174 | return 1; |
| 175 | } |
| 176 | |
| 177 | if (!checkSystem()) { |
| 178 | return -1; |
| 179 | } |
| 180 | |
| 181 | std::string qnnSdkPath = argv[1]; |
| 182 | int socId = std::stoi(std::string(argv[2])); |
| 183 | int hexagonArch = std::stoi(std::string(argv[3])); |
| 184 | const char* srcMNNPath = argv[4]; |
| 185 | std::string modelBaseName = [](const std::string& path) { |
| 186 | std::string filename = path; |
| 187 | auto pos = path.find_last_of("/\\"); |
| 188 | if (pos != std::string::npos) { |
| 189 | filename = path.substr(pos + 1); |
| 190 | } |
| 191 | pos = filename.find_last_of('.'); |
| 192 | if (pos != std::string::npos) { |
| 193 | return filename.substr(0, pos); |
| 194 | } |
| 195 | return filename; |
| 196 | }(srcMNNPath); |
| 197 | std::string modelSignature = "_" + std::to_string(socId) + "_" + std::to_string(hexagonArch); |
| 198 | std::string outputDir = argv[5]; |
| 199 | std::string dstMNNPath = MNNFilePathConcat(outputDir, modelBaseName + modelSignature + ".mnn"); |
| 200 | |
| 201 | std::vector<std::string> inputNames; |
| 202 | std::vector<std::string> outputNames; |
| 203 | std::vector<MNN::Express::VARP> inputs; |
| 204 | std::vector<MNN::Express::VARP> outputs; |
| 205 | std::vector<std::vector<std::vector<int>>> inputShapeLists; |
| 206 | bool hasInputsVarp = false; |
| 207 | std::vector<std::vector<MNN::Express::VARP>> inputsVarpList; |
| 208 | |
| 209 | int totalShapeType = 1; |
| 210 | if(argc > 6) { |
nothing calls this directly
no test coverage detected