test_detector_bench.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <sys/time.h>
  5. #include <fcntl.h>
  6. #include <sys/ioctl.h>
  7. #include <sys/mman.h>
  8. #include <linux/dma-heap.h>
  9. #include <math.h>
  10. #include "detector.h"
  11. static int dma_heap_alloc(size_t size, int *fd) {
  12. char path[64];
  13. snprintf(path, 64, "/dev/dma_heap/reserved");
  14. int heap_fd = open(path, O_RDWR | O_CLOEXEC);
  15. if (heap_fd < 0) {
  16. heap_fd = open("/dev/dma_heap/system-uncached", O_RDWR | O_CLOEXEC);
  17. if (heap_fd < 0) return -1;
  18. }
  19. struct dma_heap_allocation_data d = { .len = size, .fd_flags = O_RDWR | O_CLOEXEC };
  20. int ret = ioctl(heap_fd, DMA_HEAP_IOCTL_ALLOC, &d);
  21. close(heap_fd);
  22. if (ret < 0) return -1;
  23. *fd = d.fd;
  24. return 0;
  25. }
  26. static double get_time_ms(void) {
  27. struct timeval tv;
  28. gettimeofday(&tv, NULL);
  29. return tv.tv_sec * 1000.0 + tv.tv_usec / 1000.0;
  30. }
  31. static int bench_model(const char *model_path, const char *model_name,
  32. int nv12_fd, int src_w, int src_h,
  33. int warmup, int iterations) {
  34. printf("\n=== Benchmark: %s (%s) ===\n", model_name, model_path);
  35. Detector *det = detector_create(model_path, 0.25f, 0.45f);
  36. if (!det) {
  37. printf(" FAILED to create detector\n");
  38. return -1;
  39. }
  40. int mw = detector_get_input_width(det);
  41. int mh = detector_get_input_height(det);
  42. printf(" Model input: %dx%d\n", mw, mh);
  43. DetResult results[MAX_DETECTIONS];
  44. int num_results = 0;
  45. for (int i = 0; i < warmup; i++) {
  46. detector_detect(det, nv12_fd, src_w, src_h, results, &num_results);
  47. }
  48. double t_start = get_time_ms();
  49. int total_detections = 0;
  50. int valid_runs = 0;
  51. for (int i = 0; i < iterations; i++) {
  52. num_results = 0;
  53. int ret = detector_detect(det, nv12_fd, src_w, src_h, results, &num_results);
  54. if (ret == 0) {
  55. total_detections += num_results;
  56. valid_runs++;
  57. }
  58. }
  59. double t_end = get_time_ms();
  60. double elapsed = t_end - t_start;
  61. double avg_ms = valid_runs > 0 ? elapsed / valid_runs : 0;
  62. double fps = avg_ms > 0 ? 1000.0 / avg_ms : 0;
  63. int avg_det = valid_runs > 0 ? total_detections / valid_runs : 0;
  64. printf(" Warmup: %d, Iterations: %d (valid: %d)\n", warmup, iterations, valid_runs);
  65. printf(" Total time: %.1f ms\n", elapsed);
  66. printf(" Avg inference: %.2f ms/frame\n", avg_ms);
  67. printf(" Avg FPS: %.1f\n", fps);
  68. printf(" Avg detections: %d\n", avg_det);
  69. if (valid_runs > 0 && num_results > 0) {
  70. printf(" Last frame detections:\n");
  71. for (int i = 0; i < num_results && i < 10; i++) {
  72. printf(" [%d] label=%d score=%.3f box=[%.1f,%.1f,%.1f,%.1f]\n",
  73. i, results[i].label, results[i].score,
  74. results[i].x1, results[i].y1, results[i].x2, results[i].y2);
  75. }
  76. if (num_results > 10)
  77. printf(" ... and %d more\n", num_results - 10);
  78. }
  79. detector_destroy(det);
  80. return 0;
  81. }
  82. int main(int argc, char **argv) {
  83. const char *model5 = "models/yolov5s.rknn";
  84. const char *model8 = "models/yolov8s.rknn";
  85. int src_w = 1920, src_h = 1080;
  86. int warmup = 5, iterations = 50;
  87. for (int i = 1; i < argc; i++) {
  88. if (strcmp(argv[i], "-w") == 0 && i + 1 < argc) { src_w = atoi(argv[++i]); }
  89. else if (strcmp(argv[i], "-h") == 0 && i + 1 < argc) { src_h = atoi(argv[++i]); }
  90. else if (strcmp(argv[i], "-n") == 0 && i + 1 < argc) { iterations = atoi(argv[++i]); }
  91. else if (strcmp(argv[i], "-m5") == 0 && i + 1 < argc) { model5 = argv[++i]; }
  92. else if (strcmp(argv[i], "-m8") == 0 && i + 1 < argc) { model8 = argv[++i]; }
  93. }
  94. printf("Detector Benchmark: YOLOv5s vs YOLOv8s on RK3588 NPU\n");
  95. printf("Source: %dx%d NV12 (synthetic), Warmup: %d, Iterations: %d\n",
  96. src_w, src_h, warmup, iterations);
  97. size_t nv12_size = src_w * src_h * 3 / 2;
  98. int nv12_fd = -1;
  99. if (dma_heap_alloc(nv12_size, &nv12_fd) < 0) {
  100. printf("ERROR: failed to allocate NV12 buffer\n");
  101. return 1;
  102. }
  103. void *nv12_map = mmap(NULL, nv12_size, PROT_READ | PROT_WRITE,
  104. MAP_SHARED, nv12_fd, 0);
  105. if (nv12_map == MAP_FAILED) {
  106. printf("ERROR: mmap failed\n");
  107. close(nv12_fd);
  108. return 1;
  109. }
  110. memset(nv12_map, 0x80, nv12_size);
  111. uint8_t *y_plane = (uint8_t *)nv12_map;
  112. for (int row = 0; row < src_h; row++) {
  113. for (int col = 0; col < src_w; col++) {
  114. int val = ((row + col) % 200) + 30;
  115. y_plane[row * src_w + col] = (uint8_t)val;
  116. }
  117. }
  118. printf("NV12 buffer ready (%zu bytes)\n", nv12_size);
  119. int ret5 = bench_model(model5, "YOLOv5s", nv12_fd, src_w, src_h, warmup, iterations);
  120. int ret8 = bench_model(model8, "YOLOv8s", nv12_fd, src_w, src_h, warmup, iterations);
  121. printf("\n=== Summary ===\n");
  122. if (ret5 == 0 && ret8 == 0) {
  123. printf("Both models loaded and ran successfully.\n");
  124. printf("See above for per-model latency and FPS comparison.\n");
  125. } else {
  126. if (ret5 < 0) printf("YOLOv5s: FAILED\n");
  127. if (ret8 < 0) printf("YOLOv8s: FAILED\n");
  128. }
  129. munmap(nv12_map, nv12_size);
  130. close(nv12_fd);
  131. return 0;
  132. }