|
1 |
| - |
| 1 | +# device properties |
2 | 2 |
|
3 | 3 | """
|
4 | 4 | Hardware threads of device
|
5 | 5 | """
|
6 |
| -threads(device) = 0 |
7 |
| - |
8 |
| -""" |
9 |
| -Blocks that group together hardware threads |
10 |
| -""" |
11 |
| -blocks(device) = 1 |
12 |
| -""" |
13 |
| -Global memory, e.g. VRAM or RAM of device |
14 |
| -""" |
15 |
| -global_memory(device) = 0 |
16 |
| - |
17 |
| -""" |
18 |
| -Free global memory. Isn't supported for AMD cards right now, in which case it returns NaN, |
19 |
| -so don't rely on the output of this function. |
20 |
| -""" |
21 |
| -free_global_memory(device) = NaN |
22 |
| - |
23 |
| -""" |
24 |
| -Block local memory |
25 |
| -""" |
26 |
| -local_memory(device) = 0 |
27 |
| - |
28 |
| -""" |
29 |
| -Hardware name of a device |
30 |
| -""" |
31 |
| -name(device) = "Undefined" |
32 |
| - |
33 |
| -""" |
34 |
| -Summarizes all features of a device and prints it to `io` |
35 |
| -""" |
36 |
| -function device_summary(io::IO, device) |
37 |
| - println(io, "Device: ", name(device)) |
38 |
| - for (n, f) in (:threads => threads, :blocks => blocks) |
39 |
| - @printf(io, "%19s: %s\n", string(n), string(f(device))) |
40 |
| - end |
41 |
| - for (n, f) in (:global_memory => global_memory, :free_global_memory => free_global_memory, :local_memory => local_memory) |
42 |
| - @printf(io, "%19s: %f mb\n", string(n), f(device) / 10^6) |
43 |
| - end |
44 |
| - return |
45 |
| -end |
46 |
| - |
47 |
| -################################ |
48 |
| -# Device selection functions for e.g. devices(filterfuncs) |
49 |
| -""" |
50 |
| -Returns true if `device` is a gpu |
51 |
| -""" |
52 |
| -is_gpu(device) = false |
53 |
| - |
54 |
| -""" |
55 |
| -Returns true if `device` is a cpu |
56 |
| -""" |
57 |
| -is_cpu(device) = false |
58 |
| - |
59 |
| -""" |
60 |
| -Checks a device for a certain attribute and returns true if it has at least `value`. |
61 |
| -Can be used with e.g. `threads`, `blocks`, `global_memory`, `local_memory` |
62 |
| -""" |
63 |
| -has_atleast(device, attribute, value) = attribute(ctx_or_device) >= value |
64 |
| - |
65 |
| - |
66 |
| -################################# |
67 |
| -# Context filter functions |
68 |
| -# Works for context objects as well but is overloaded in the backends |
69 |
| -is_opencl(ctx::Symbol) = ctx == :opencl |
70 |
| -is_cudanative(ctx::Symbol) = ctx == :cudanative |
71 |
| -is_julia(ctx::Symbol) = ctx == :threaded |
72 |
| -is_opengl(ctx::Symbol) = ctx == :opengl |
73 |
| - |
74 |
| -is_opencl(ctx) = false |
75 |
| -is_cudanative(ctx) = false |
76 |
| -is_julia(ctx) = false |
77 |
| -is_opengl(ctx) = false |
78 |
| - |
79 |
| -supports_double(ctx) = false |
80 |
| - |
81 |
| - |
82 |
| - |
83 |
| -#= |
84 |
| -Functions to select contexts |
85 |
| -=# |
86 |
| - |
87 |
| -""" |
88 |
| -Creates a new context from `device` without caching the resulting context. |
89 |
| -""" |
90 |
| -function new_context(device) |
91 |
| - error("Device $device not supported") |
92 |
| -end |
93 |
| - |
94 |
| -""" |
95 |
| -Destroys context, freeing all it's resources. |
96 |
| -""" |
97 |
| -function destroy!(context) |
98 |
| - error("Device $context not supported") |
99 |
| -end |
100 |
| - |
101 |
| -""" |
102 |
| -Resets a context freeing all resources and creating a new context. |
103 |
| -""" |
104 |
| -function reset!(context) |
105 |
| - error("Context $context not supported") |
106 |
| -end |
107 |
| - |
108 |
| - |
109 |
| -""" |
110 |
| -Creates a temporary context for `device` and executes `f(context)` while this context is active. |
111 |
| -Context gets destroyed afterwards. Note, that creating a temporary context is expensive. |
112 |
| -""" |
113 |
| -function on_device(f, device = current_device()) |
114 |
| - ctx = new_context(device) |
115 |
| - try |
116 |
| - f(ctx) |
117 |
| - finally |
118 |
| - destroy!(ctx) |
119 |
| - end |
120 |
| - return |
121 |
| -end |
122 |
| - |
123 |
| -const filterfuncs = """ |
124 |
| -Device can be filtered by passing `filter_funcs`, e.g. : |
125 |
| -`is_gpu`, `is_cpu`, `(dev)-> has_atleast(dev, threads, 512)` |
126 |
| -""" |
127 |
| - |
128 |
| -""" |
129 |
| -Returns all devices for the current backend. |
130 |
| -$filterfuncs |
131 |
| -""" |
132 |
| -function available_devices(filter_funcs...) |
133 |
| - result = [] |
134 |
| - for device in current_backend().devices() |
135 |
| - if all(f-> f(device), filter_funcs) |
136 |
| - push!(result, device) |
137 |
| - end |
138 |
| - end |
139 |
| - result |
140 |
| -end |
141 |
| - |
142 |
| - |
143 |
| -""" |
144 |
| -Returns all devices from `backends = active_backends()`. |
145 |
| -$filterfuncs |
146 |
| -""" |
147 |
| -function all_devices(filter_funcs...; backends = active_backends()) |
148 |
| - result = [] |
149 |
| - for Module in backends |
150 |
| - for device in Module.devices() |
151 |
| - if all(f-> f(device), filter_funcs) |
152 |
| - push!(result, device) |
153 |
| - end |
154 |
| - end |
155 |
| - end |
156 |
| - result |
157 |
| -end |
158 |
| - |
159 |
| - |
160 |
| -""" |
161 |
| -Iterates through all available devices and calls `f(context)` after initializing the standard context for that device. |
162 |
| -""" |
163 |
| -function forall_devices(func, filterfuncs...) |
164 |
| - for device in all_devices(filterfuncs...) |
165 |
| - ctx = init(device) |
166 |
| - func(ctx) |
167 |
| - end |
168 |
| -end |
| 6 | +threads(device) = error("Not implemented") # COV_EXCL_LINE |
0 commit comments