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.3 kB

11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  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. }
  162. // -------------------------------------------------
  163. // 3. Verification
  164. // -------------------------------------------------
  165. printf("\n==================================================\n");
  166. printf(" Verification and Summary \n");
  167. printf("==================================================\n");
  168. bool is_output_same = (CompareMat(output_no_cache, output_with_cache, 0.001) == 0);
  169. printf("Output verification: %s\n", (is_output_same ? "SUCCESS" : "FAILURE"));
  170. printf("--------------------------------------------------\n");
  171. printf("Performance Summary:\n");
  172. printf(" - Without Cache: %f ms\n", time_no_cache);
  173. printf(" - With Cache: %f ms\n", time_with_cache);
  174. if (time_no_cache > 0)
  175. {
  176. double speedup = (time_no_cache - time_with_cache) / time_no_cache * 100;
  177. printf(" - Speedup: %f%%\n", speedup);
  178. }
  179. if (!is_output_same)
  180. {
  181. fprintf(stderr, "\nTest FAILED due to output mismatch.\n");
  182. return -1;
  183. }
  184. printf("\nTest PASSED.\n");
  185. return 0;
  186. }
  187. int main()
  188. {
  189. // warming up
  190. if (warmup_gpu_pipecache() != 0)
  191. {
  192. return -1;
  193. }
  194. return test_gpu_pipecache_performance();
  195. }