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 4.7 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. // Copyright 2020 Tencent
  2. // SPDX-License-Identifier: BSD-3-Clause
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <string>
  6. static int copy_param(const char* parampath, FILE* outparamfp, int* total_layer_count, int* total_blob_count)
  7. {
  8. // resolve model namespace from XYZ.param
  9. const char* lastslash = strrchr(parampath, '/');
  10. const char* name = lastslash == NULL ? parampath : lastslash + 1;
  11. const char* dot = strrchr(name, '.');
  12. std::string ns = dot ? std::string(name).substr(0, dot - name) : std::string(name);
  13. FILE* fp = fopen(parampath, "rb");
  14. if (!fp)
  15. {
  16. fprintf(stderr, "fopen %s failed\n", parampath);
  17. return -1;
  18. }
  19. int nscan = 0;
  20. int magic = 0;
  21. nscan = fscanf(fp, "%d", &magic);
  22. if (nscan != 1 || magic != 7767517)
  23. {
  24. fprintf(stderr, "read magic failed %d\n", nscan);
  25. return -1;
  26. }
  27. int layer_count = 0;
  28. int blob_count = 0;
  29. nscan = fscanf(fp, "%d %d", &layer_count, &blob_count);
  30. if (nscan != 2)
  31. {
  32. fprintf(stderr, "read layer_count and blob_count failed %d\n", nscan);
  33. return -1;
  34. }
  35. *total_layer_count += layer_count;
  36. *total_blob_count += blob_count;
  37. char line[1024];
  38. for (int i = 0; i < layer_count; i++)
  39. {
  40. char layer_type[33];
  41. char layer_name[257];
  42. int bottom_count = 0;
  43. int top_count = 0;
  44. nscan = fscanf(fp, "%32s %256s %d %d", layer_type, layer_name, &bottom_count, &top_count);
  45. if (nscan != 4)
  46. {
  47. fprintf(stderr, "read layer params failed %d\n", nscan);
  48. return -1;
  49. }
  50. fprintf(outparamfp, "%-24s %s/%-24s %d %d", layer_type, ns.c_str(), layer_name, bottom_count, top_count);
  51. for (int j = 0; j < bottom_count; j++)
  52. {
  53. char bottom_name[257];
  54. nscan = fscanf(fp, "%256s", bottom_name);
  55. if (nscan != 1)
  56. {
  57. fprintf(stderr, "read bottom_name failed %d\n", nscan);
  58. return -1;
  59. }
  60. fprintf(outparamfp, " %s/%s", ns.c_str(), bottom_name);
  61. }
  62. for (int j = 0; j < top_count; j++)
  63. {
  64. char top_name[257];
  65. nscan = fscanf(fp, "%256s", top_name);
  66. if (nscan != 1)
  67. {
  68. fprintf(stderr, "read top_name failed %d\n", nscan);
  69. return -1;
  70. }
  71. fprintf(outparamfp, " %s/%s", ns.c_str(), top_name);
  72. }
  73. // copy param dict string
  74. char* s = fgets(line, 1024, fp);
  75. if (!s)
  76. {
  77. fprintf(stderr, "read line %s failed\n", parampath);
  78. break;
  79. }
  80. fputs(line, outparamfp);
  81. }
  82. fclose(fp);
  83. return 0;
  84. }
  85. static int copy_bin(const char* binpath, FILE* outbinfp)
  86. {
  87. FILE* fp = fopen(binpath, "rb");
  88. if (!fp)
  89. {
  90. fprintf(stderr, "fopen %s failed\n", binpath);
  91. return -1;
  92. }
  93. fseek(fp, 0, SEEK_END);
  94. int len = (int)ftell(fp);
  95. rewind(fp);
  96. char buffer[4096];
  97. int i = 0;
  98. for (; i + 4095 < len;)
  99. {
  100. size_t nread = fread(buffer, 1, 4096, fp);
  101. size_t nwrite = fwrite(buffer, 1, nread, outbinfp);
  102. i += (int)nwrite;
  103. }
  104. {
  105. size_t nread = fread(buffer, 1, len - i, fp);
  106. size_t nwrite = fwrite(buffer, 1, nread, outbinfp);
  107. i += (int)nwrite;
  108. }
  109. if (i != len)
  110. {
  111. fprintf(stderr, "copy %s incomplete\n", binpath);
  112. }
  113. fclose(fp);
  114. return 0;
  115. }
  116. int main(int argc, char** argv)
  117. {
  118. if (argc < 7 || (argc - 1) % 2 != 0)
  119. {
  120. fprintf(stderr, "Usage: %s [param1] [bin1] [param2] [bin2] ... [outparam] [outbin]\n", argv[0]);
  121. return -1;
  122. }
  123. const char* outparampath = argv[argc - 2];
  124. const char* outbinpath = argv[argc - 1];
  125. FILE* outparamfp = fopen(outparampath, "wb");
  126. FILE* outbinfp = fopen(outbinpath, "wb");
  127. // magic
  128. fprintf(outparamfp, "7767517\n");
  129. // layer count and blob count placeholder
  130. // 99999 is large enough I think --- nihui
  131. fprintf(outparamfp, " \n");
  132. int total_layer_count = 0;
  133. int total_blob_count = 0;
  134. const int model_count = (argc - 3) / 2;
  135. for (int i = 0; i < model_count; i++)
  136. {
  137. const char* parampath = argv[i * 2 + 1];
  138. const char* binpath = argv[i * 2 + 2];
  139. copy_param(parampath, outparamfp, &total_layer_count, &total_blob_count);
  140. copy_bin(binpath, outbinfp);
  141. }
  142. // the real layer count and blob count
  143. rewind(outparamfp);
  144. fprintf(outparamfp, "7767517\n");
  145. fprintf(outparamfp, "%d %d", total_layer_count, total_blob_count);
  146. fclose(outparamfp);
  147. fclose(outbinfp);
  148. return 0;
  149. }