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.

test_pipecache.cpp 7.4 kB

9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
9 months ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. // Copyright 2021 Tencent
  2. // SPDX-License-Identifier: BSD-3-Clause
  3. #include "datareader.h"
  4. #include "gpu.h"
  5. #include "mat.h"
  6. #include "net.h"
  7. #include "pipelinecache.h"
  8. #include "testutil.h"
  9. #include "benchmark.h"
  10. #include <cstdio>
  11. #include <vector>
  12. #include <cstring>
  13. class DataReaderFromEmpty : public ncnn::DataReader
  14. {
  15. public:
  16. virtual int scan(const char* format, void* p) const
  17. {
  18. (void)format; // unused
  19. (void)p; // unused
  20. return 0;
  21. }
  22. virtual size_t read(void* buf, size_t size) const
  23. {
  24. memset(buf, 0, size);
  25. return size;
  26. }
  27. };
  28. static int warmup_gpu_pipecache()
  29. {
  30. printf("==================================================\n");
  31. printf(" Warmup: Testing Basic Cache IO \n");
  32. printf("==================================================\n");
  33. ncnn::Net net;
  34. net.opt.use_vulkan_compute = true;
  35. net.load_param_mem("7767517\n2 2\nInput input0 0 1 input0\nSigmoid sigmoid0 1 1 input0 output0");
  36. net.load_model((unsigned char*)"");
  37. ncnn::Mat input0 = RandomMat(224, 224);
  38. ncnn::Mat output0;
  39. {
  40. ncnn::Extractor ex = net.create_extractor();
  41. ex.input("input0", input0);
  42. ex.extract("output0", output0);
  43. }
  44. if (output0.empty())
  45. {
  46. fprintf(stderr, "Warmup failed: initial extraction failed.\n");
  47. return -1;
  48. }
  49. const char* cache_path = "./sigmoid_pipecache.bin";
  50. if (net.opt.pipeline_cache->save_cache(cache_path) != 0)
  51. {
  52. fprintf(stderr, "Warmup failed: could not save pipeline cache to %s\n", cache_path);
  53. return -1;
  54. }
  55. printf("Warmup: Pipeline cache saved successfully.\n");
  56. ncnn::Net net2;
  57. net2.opt.use_vulkan_compute = true;
  58. net2.load_param_mem("7767517\n2 2\nInput input0 0 1 input0\nSigmoid sigmoid0 1 1 input0 output0");
  59. net2.opt.pipeline_cache = new ncnn::PipelineCache(net2.vulkan_device());
  60. if (net2.opt.pipeline_cache->load_cache(cache_path) != 0)
  61. {
  62. fprintf(stderr, "Warmup failed: could not load pipeline cache from %s\n", cache_path);
  63. return -1;
  64. }
  65. printf("Warmup: Pipeline cache loaded successfully.\n");
  66. net2.load_model((unsigned char*)"");
  67. ncnn::Mat output0_2;
  68. {
  69. ncnn::Extractor ex2 = net2.create_extractor();
  70. ex2.input("input0", input0);
  71. ex2.extract("output0", output0_2);
  72. }
  73. if (output0_2.empty())
  74. {
  75. fprintf(stderr, "Warmup failed: extraction after loading cache failed.\n");
  76. return -1;
  77. }
  78. if (CompareMat(output0, output0_2, 0.001) != 0)
  79. {
  80. fprintf(stderr, "Warmup failed: output mismatch after loading cache.\n");
  81. return -1;
  82. }
  83. printf("Warmup PASSED: Outputs are identical.\n");
  84. return 0;
  85. }
  86. static int test_gpu_pipecache_performance()
  87. {
  88. ncnn::Mat output_no_cache;
  89. double time_no_cache = 0;
  90. const char* cache_path = "./mobilenet_pipecache.bin";
  91. DataReaderFromEmpty dr;
  92. ncnn::Mat input = RandomMat(224, 224, 3);
  93. #ifdef __EMSCRIPTEN__
  94. #define MODEL_DIR "/working"
  95. #else
  96. #define MODEL_DIR "../../benchmark"
  97. #endif
  98. // -------------------------------------------------
  99. // 1. Without cache
  100. // -------------------------------------------------
  101. printf("\n==================================================\n");
  102. printf(" Performance Test: Without Pipeline Cache \n");
  103. printf("==================================================\n");
  104. {
  105. ncnn::Net net_no_cache;
  106. net_no_cache.opt.use_vulkan_compute = true;
  107. auto start = ncnn::get_current_time();
  108. net_no_cache.load_param(MODEL_DIR "/mobilenet_v3.param");
  109. net_no_cache.load_model(dr);
  110. auto end = ncnn::get_current_time();
  111. time_no_cache = end - start;
  112. printf("Model loading time without cache: %lf ms\n", time_no_cache);
  113. ncnn::Extractor ex = net_no_cache.create_extractor();
  114. ex.input("data", input);
  115. ex.extract("output", output_no_cache);
  116. if (output_no_cache.empty())
  117. {
  118. fprintf(stderr, "Test failed: extraction without cache failed.\n");
  119. return -1;
  120. }
  121. // save cache
  122. if (net_no_cache.opt.pipeline_cache->save_cache(cache_path) != 0)
  123. {
  124. fprintf(stderr, "Test failed: could not save pipeline cache to %s\n", cache_path);
  125. return -1;
  126. }
  127. printf("Pipeline cache generated and saved to %s\n", cache_path);
  128. }
  129. // -------------------------------------------------
  130. // 2. With Cache
  131. // -------------------------------------------------
  132. ncnn::Mat output_with_cache;
  133. double time_with_cache = 0;
  134. printf("\n==================================================\n");
  135. printf(" Performance Test: With Pipeline Cache \n");
  136. printf("==================================================\n");
  137. {
  138. ncnn::Net net_with_cache;
  139. net_with_cache.opt.use_vulkan_compute = true;
  140. auto start = ncnn::get_current_time();
  141. net_with_cache.load_param(MODEL_DIR "/mobilenet_v3.param"); // after load param vkdev will be create
  142. net_with_cache.opt.pipeline_cache = new ncnn::PipelineCache(net_with_cache.vulkan_device());
  143. // load from cache
  144. if (net_with_cache.opt.pipeline_cache->load_cache(cache_path) != 0)
  145. {
  146. fprintf(stderr, "Test failed: could not load pipeline cache from %s\n", cache_path);
  147. return -1;
  148. }
  149. net_with_cache.load_model(dr);
  150. auto end = ncnn::get_current_time();
  151. time_with_cache = end - start;
  152. printf("Model loading time with cache: %lf ms\n", time_with_cache);
  153. ncnn::Extractor ex2 = net_with_cache.create_extractor();
  154. ex2.input("data", input);
  155. ex2.extract("output", output_with_cache);
  156. if (output_with_cache.empty())
  157. {
  158. fprintf(stderr, "Test failed: extraction with cache failed.\n");
  159. return -1;
  160. }
  161. delete net_with_cache.opt.pipeline_cache; // clean up pipeline cache by hand
  162. }
  163. // -------------------------------------------------
  164. // 3. Verification
  165. // -------------------------------------------------
  166. printf("\n==================================================\n");
  167. printf(" Verification and Summary \n");
  168. printf("==================================================\n");
  169. bool is_output_same = (CompareMat(output_no_cache, output_with_cache, 0.001) == 0);
  170. printf("Output verification: %s\n", (is_output_same ? "SUCCESS" : "FAILURE"));
  171. printf("--------------------------------------------------\n");
  172. printf("Performance Summary:\n");
  173. printf(" - Without Cache: %f ms\n", time_no_cache);
  174. printf(" - With Cache: %f ms\n", time_with_cache);
  175. if (time_no_cache > 0)
  176. {
  177. double speedup = (time_no_cache - time_with_cache) / time_no_cache * 100;
  178. printf(" - Speedup: %f%%\n", speedup);
  179. }
  180. if (!is_output_same)
  181. {
  182. fprintf(stderr, "\nTest FAILED due to output mismatch.\n");
  183. return -1;
  184. }
  185. printf("\nTest PASSED.\n");
  186. return 0;
  187. }
  188. int main()
  189. {
  190. // warming up
  191. if (warmup_gpu_pipecache() != 0)
  192. {
  193. return -1;
  194. }
  195. return test_gpu_pipecache_performance();
  196. }