You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

ncnnmerge.cpp 5.4 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. // Tencent is pleased to support the open source community by making ncnn available.
  2. //
  3. // Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
  4. //
  5. // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
  6. // in compliance with the License. You may obtain a copy of the License at
  7. //
  8. // https://opensource.org/licenses/BSD-3-Clause
  9. //
  10. // Unless required by applicable law or agreed to in writing, software distributed
  11. // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  12. // CONDITIONS OF ANY KIND, either express or implied. See the License for the
  13. // specific language governing permissions and limitations under the License.
  14. #include <stdio.h>
  15. #include <string.h>
  16. #include <string>
  17. static int copy_param(const char* parampath, FILE* outparamfp, int* total_layer_count, int* total_blob_count)
  18. {
  19. // resolve model namespace from XYZ.param
  20. const char* lastslash = strrchr(parampath, '/');
  21. const char* name = lastslash == NULL ? parampath : lastslash + 1;
  22. const char* dot = strrchr(name, '.');
  23. std::string ns = dot ? std::string(name).substr(0, dot - name) : std::string(name);
  24. FILE* fp = fopen(parampath, "rb");
  25. if (!fp)
  26. {
  27. fprintf(stderr, "fopen %s failed\n", parampath);
  28. return -1;
  29. }
  30. int nscan = 0;
  31. int magic = 0;
  32. nscan = fscanf(fp, "%d", &magic);
  33. if (nscan != 1 || magic != 7767517)
  34. {
  35. fprintf(stderr, "read magic failed %d\n", nscan);
  36. return -1;
  37. }
  38. int layer_count = 0;
  39. int blob_count = 0;
  40. nscan = fscanf(fp, "%d %d", &layer_count, &blob_count);
  41. if (nscan != 2)
  42. {
  43. fprintf(stderr, "read layer_count and blob_count failed %d\n", nscan);
  44. return -1;
  45. }
  46. *total_layer_count += layer_count;
  47. *total_blob_count += blob_count;
  48. char line[1024];
  49. for (int i = 0; i < layer_count; i++)
  50. {
  51. char layer_type[33];
  52. char layer_name[257];
  53. int bottom_count = 0;
  54. int top_count = 0;
  55. nscan = fscanf(fp, "%32s %256s %d %d", layer_type, layer_name, &bottom_count, &top_count);
  56. if (nscan != 4)
  57. {
  58. fprintf(stderr, "read layer params failed %d\n", nscan);
  59. return -1;
  60. }
  61. fprintf(outparamfp, "%-24s %s/%-24s %d %d", layer_type, ns.c_str(), layer_name, bottom_count, top_count);
  62. for (int j = 0; j < bottom_count; j++)
  63. {
  64. char bottom_name[257];
  65. nscan = fscanf(fp, "%256s", bottom_name);
  66. if (nscan != 1)
  67. {
  68. fprintf(stderr, "read bottom_name failed %d\n", nscan);
  69. return -1;
  70. }
  71. fprintf(outparamfp, " %s/%s", ns.c_str(), bottom_name);
  72. }
  73. for (int j = 0; j < top_count; j++)
  74. {
  75. char top_name[257];
  76. nscan = fscanf(fp, "%256s", top_name);
  77. if (nscan != 1)
  78. {
  79. fprintf(stderr, "read top_name failed %d\n", nscan);
  80. return -1;
  81. }
  82. fprintf(outparamfp, " %s/%s", ns.c_str(), top_name);
  83. }
  84. // copy param dict string
  85. char* s = fgets(line, 1024, fp);
  86. if (!s)
  87. {
  88. fprintf(stderr, "read line %s failed\n", parampath);
  89. break;
  90. }
  91. fputs(line, outparamfp);
  92. }
  93. fclose(fp);
  94. return 0;
  95. }
  96. static int copy_bin(const char* binpath, FILE* outbinfp)
  97. {
  98. FILE* fp = fopen(binpath, "rb");
  99. if (!fp)
  100. {
  101. fprintf(stderr, "fopen %s failed\n", binpath);
  102. return -1;
  103. }
  104. fseek(fp, 0, SEEK_END);
  105. int len = (int)ftell(fp);
  106. rewind(fp);
  107. char buffer[4096];
  108. int i = 0;
  109. for (; i + 4095 < len;)
  110. {
  111. size_t nread = fread(buffer, 1, 4096, fp);
  112. size_t nwrite = fwrite(buffer, 1, nread, outbinfp);
  113. i += (int)nwrite;
  114. }
  115. {
  116. size_t nread = fread(buffer, 1, len - i, fp);
  117. size_t nwrite = fwrite(buffer, 1, nread, outbinfp);
  118. i += (int)nwrite;
  119. }
  120. if (i != len)
  121. {
  122. fprintf(stderr, "copy %s incomplete\n", binpath);
  123. }
  124. fclose(fp);
  125. return 0;
  126. }
  127. int main(int argc, char** argv)
  128. {
  129. if (argc < 7 || (argc - 1) % 2 != 0)
  130. {
  131. fprintf(stderr, "Usage: %s [param1] [bin1] [param2] [bin2] ... [outparam] [outbin]\n", argv[0]);
  132. return -1;
  133. }
  134. const char* outparampath = argv[argc - 2];
  135. const char* outbinpath = argv[argc - 1];
  136. FILE* outparamfp = fopen(outparampath, "wb");
  137. FILE* outbinfp = fopen(outbinpath, "wb");
  138. // magic
  139. fprintf(outparamfp, "7767517\n");
  140. // layer count and blob count placeholder
  141. // 99999 is large enough I think --- nihui
  142. fprintf(outparamfp, " \n");
  143. int total_layer_count = 0;
  144. int total_blob_count = 0;
  145. const int model_count = (argc - 3) / 2;
  146. for (int i = 0; i < model_count; i++)
  147. {
  148. const char* parampath = argv[i * 2 + 1];
  149. const char* binpath = argv[i * 2 + 2];
  150. copy_param(parampath, outparamfp, &total_layer_count, &total_blob_count);
  151. copy_bin(binpath, outbinfp);
  152. }
  153. // the real layer count and blob count
  154. rewind(outparamfp);
  155. fprintf(outparamfp, "7767517\n");
  156. fprintf(outparamfp, "%d %d", total_layer_count, total_blob_count);
  157. fclose(outparamfp);
  158. fclose(outbinfp);
  159. return 0;
  160. }