Halide 19.0.0
Halide compiler and libraries
Loading...
Searching...
No Matches
gpu_object_lifetime_tracker.h
Go to the documentation of this file.
1#ifndef GPU_OBJECT_LIFETIME_H
2#define GPU_OBJECT_LIFETIME_H
3
4#include <array>
5#include <stdio.h>
6#include <string.h>
7
8namespace Halide {
9namespace Internal {
10
12 struct ObjectType {
13 const char *const created;
14 const char *const destroyed;
15 bool const is_global;
16 int total_created;
17 int live_count;
18
19 ObjectType(const char *created, const char *destroyed, bool is_global = false)
20 : created(created), destroyed(destroyed),
21 is_global(is_global), total_created(0), live_count(0) {
22 }
23 };
24
25 std::array<ObjectType, 22> object_types = {{
26 {"Caching compiled kernel:", "Releasing cached compilation:"},
27
28 // OpenCL objects
29 {"clCreateContext", "clReleaseContext", true},
30 {"clCreateCommandQueue", "clReleaseCommandQueue", true},
31 // This handles both "clCreateProgramWithSource" and
32 // "clCreateProgramWithBinary".
33 {"clCreateBuffer", "clReleaseMemObject"},
34 {"clCreateKernel", "clReleaseKernel"},
35
36 // CUDA objects
37 {"cuCtxCreate", "cuCtxDestroy", true},
38 {"cuMemAlloc", "cuMemFree"},
39
40 // Metal objects
41 {"Allocating: MTLCreateSystemDefaultDevice", "Releasing: MTLCreateSystemDefaultDevice", true},
42 {"Allocating: new_command_queue", "Releasing: new_command_queue"},
43
44 // Hexagon objects
45 {"halide_remote_load_library", "halide_remote_release_library"},
46 {"ion_alloc", "ion_free"},
47
48 // Vulkan objects
49 {"vk_create_context", "vk_destroy_context", true},
50 {"vk_create_command_pool", "vk_destroy_command_pool"},
51 {"vk_create_command_buffer", "vk_destroy_command_buffer"},
52 {"vk_create_pipeline_layout", "vk_destroy_pipeline_layout"},
53 {"vk_create_compute_pipeline", "vk_destroy_compute_pipeline"},
54 {"vk_create_descriptor_pool", "vk_destroy_descriptor_pool"},
55 {"Vulkan: Allocated memory for device region", "Vulkan: Deallocated memory for device region"},
56 {"Vulkan: Created buffer", "Vulkan: Destroyed buffer"},
57
58 // WebGPU objects
59 {"wgpuCreateInstance", "wgpuInstanceRelease", true},
60 {"wgpuDeviceCreateBuffer", "wgpuBufferRelease"},
61 {"wgpuDeviceCreateComputePipeline", "wgpuComputePipelineRelease"},
62 }};
63
64public:
65 // Parse a line of output from gpu_debug and update object counts.
66 void record_gpu_debug(const char *str) {
67 for (auto &o : object_types) {
68 if (strstr(str, o.created)) {
69 o.total_created++;
70 o.live_count++;
71 } else if (strstr(str, o.destroyed)) {
72 o.live_count--;
73 }
74 }
75 }
76
77 // Check that there are no live objects remaining, and we created at least one object.
78 int validate_gpu_object_lifetime(bool allow_globals, bool allow_none, int max_globals) {
79 int total = 0;
80 for (auto &o : object_types) {
81 if (o.live_count != 0 &&
82 !(allow_globals && o.is_global)) {
83 printf("Error! %d objects created by %s still live\n",
84 o.live_count, o.created);
85 return 1;
86 }
87 if (o.is_global && o.total_created > max_globals) {
88 printf("Error! %d global objects created by %s, max is %d\n",
89 o.total_created, o.created, max_globals);
90 return 1;
91 }
92
93 total += o.total_created;
94 }
95 if (!allow_none && total == 0) {
96 printf("Error! No objects created. Ensure gpu_debug is set, ");
97 printf("and record_gpu_debug is called from halide_print.\n");
98 return 1;
99 }
100 return 0;
101 }
102};
103
104} // namespace Internal
105} // namespace Halide
106
107#endif
int validate_gpu_object_lifetime(bool allow_globals, bool allow_none, int max_globals)
This file defines the class FunctionDAG, which is our representation of a Halide pipeline,...
@ Internal
Not visible externally, similar to 'static' linkage in C.
const char * strstr(const char *, const char *)