1 /*
2  * Copyright 2017 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can
5  * be found in the LICENSE file.
6  *
7  */
8 
9 #pragma once
10 
11 //
12 //
13 //
14 
15 #include <CL/opencl.h>
16 
17 #include "suballocator.h"
18 #include "extent_ring.h"
19 
20 //
21 // Legend:
22 //
23 //   p  :  durable
24 //   t  :  ephemeral
25 //   h  :  host
26 //   d  :  device
27 //   r  :  read
28 //   w  :  write
29 //   1  :  once -- e.g. w1 is 'write-once'
30 //   N  :  many -- e.g. rN is 'read-many'
31 //   g  :  ring
32 //   s  :  ring snapshot
33 //
34 // Notes:
35 //
36 //   rw :  for now, read-write implies read-write many
37 //
38 
39 //
40 // DURABLE R/W HOST EXTENT -- STANDARD CACHED MEMORY
41 //
42 
43 struct skc_extent_phrw
44 {
45   void * hrw;
46 };
47 
48 void
49 skc_extent_phrw_alloc(struct skc_runtime     * const runtime,
50                       struct skc_extent_phrw * const extent,
51                       size_t                   const size);
52 
53 void
54 skc_extent_phrw_free(struct skc_runtime     * const runtime,
55                      struct skc_extent_phrw * const extent);
56 
57 //
58 // DURABLE R/W DEVICE EXTENT -- ALLOCATED FROM DEVICE HEAP
59 //
60 
61 struct skc_extent_pdrw
62 {
63   cl_mem drw;
64 };
65 
66 void
67 skc_extent_pdrw_alloc(struct skc_runtime     * const runtime,
68                       struct skc_extent_pdrw * const extent,
69                       size_t                   const size);
70 
71 void
72 skc_extent_pdrw_free(struct skc_runtime     * const runtime,
73                      struct skc_extent_pdrw * const extent);
74 
75 //
76 // EPHEMERAL DEVICE R/W EXTENT -- ALLOCATED QUICKLY FROM A MANAGED RING
77 //
78 
79 struct skc_extent_tdrw
80 {
81   size_t          size;
82   cl_mem          drw;
83   skc_subbuf_id_t id;
84 };
85 
86 void
87 skc_extent_tdrw_alloc(struct skc_runtime     * const runtime,
88                       struct skc_extent_tdrw * const extent,
89                       size_t                   const size);
90 
91 void
92 skc_extent_tdrw_free(struct skc_runtime     * const runtime,
93                      struct skc_extent_tdrw * const extent);
94 
95 void
96 skc_extent_tdrw_zero(struct skc_extent_tdrw * const extent,
97                      cl_command_queue         const cq,
98                      cl_event               * const event);
99 
100 //
101 // DURABLE SMALL EXTENTS BACKING ATOMICS
102 //
103 
104 struct skc_extent_phr_pdrw
105 {
106   size_t size; // must be multiple of words
107   void * hr;
108   cl_mem drw;
109 };
110 
111 void
112 skc_extent_phr_pdrw_alloc(struct skc_runtime         * const runtime,
113                           struct skc_extent_phr_pdrw * const extent,
114                           size_t                       const size);
115 
116 void
117 skc_extent_phr_pdrw_free(struct skc_runtime         * const runtime,
118                          struct skc_extent_phr_pdrw * const extent);
119 
120 void
121 skc_extent_phr_pdrw_read(struct skc_extent_phr_pdrw * const extent,
122                          cl_command_queue             const cq,
123                          cl_event                   * const event);
124 
125 void
126 skc_extent_phr_pdrw_zero(struct skc_extent_phr_pdrw * const extent,
127                          cl_command_queue             const cq,
128                          cl_event                   * const event);
129 
130 //
131 // EPHEMERAL SMALL EXTENTS BACKING ATOMICS
132 //
133 
134 struct skc_extent_thr_tdrw
135 {
136   size_t            size; // must be multiple of words
137 
138   void            * hr;
139   cl_mem            drw;
140 
141   struct {
142     skc_subbuf_id_t hr;
143     skc_subbuf_id_t drw;
144   } id;
145 };
146 
147 void
148 skc_extent_thr_tdrw_alloc(struct skc_runtime         * const runtime,
149                           struct skc_extent_thr_tdrw * const extent,
150                           size_t                       const size);
151 
152 void
153 skc_extent_thr_tdrw_free(struct skc_runtime         * const runtime,
154                          struct skc_extent_thr_tdrw * const extent);
155 
156 void
157 skc_extent_thr_tdrw_read(struct skc_extent_thr_tdrw * const extent,
158                          cl_command_queue             const cq,
159                          cl_event                   * const event);
160 
161 void
162 skc_extent_thr_tdrw_zero(struct skc_extent_thr_tdrw * const extent,
163                          cl_command_queue             const cq,
164                          cl_event                   * const event);
165 
166 //
167 // DURABLE W/1 HOST RING WITH AN EPHEMERAL R/N DEVICE SNAPSHOT
168 //
169 
170 struct skc_extent_phw1g_tdrNs
171 {
172   void * hw1;
173 };
174 
175 struct skc_extent_phw1g_tdrNs_snap
176 {
177   struct skc_extent_ring_snap * snap;
178   cl_mem                        drN;
179   skc_subbuf_id_t               id;
180 };
181 
182 void
183 skc_extent_phw1g_tdrNs_alloc(struct skc_runtime            * const runtime,
184                              struct skc_extent_phw1g_tdrNs * const extent,
185                              size_t                          const size);
186 
187 void
188 skc_extent_phw1g_tdrNs_free(struct skc_runtime            * const runtime,
189                             struct skc_extent_phw1g_tdrNs * const extent);
190 
191 void
192 skc_extent_phw1g_tdrNs_snap_init(struct skc_runtime                 * const runtime,
193                                  struct skc_extent_ring             * const ring,
194                                  struct skc_extent_phw1g_tdrNs_snap * const snap);
195 
196 void
197 skc_extent_phw1g_tdrNs_snap_alloc(struct skc_runtime                 * const runtime,
198                                   struct skc_extent_phw1g_tdrNs      * const extent,
199                                   struct skc_extent_phw1g_tdrNs_snap * const snap,
200                                   cl_command_queue                     const cq,
201                                   cl_event                           * const event);
202 
203 void
204 skc_extent_phw1g_tdrNs_snap_free(struct skc_runtime                 * const runtime,
205                                  struct skc_extent_phw1g_tdrNs_snap * const snap);
206 
207 //
208 // DURABLE R/W HOST RING WITH AN EPHEMERAL R/N DEVICE SNAPSHOT
209 //
210 
211 struct skc_extent_phrwg_tdrNs
212 {
213   void * hrw;
214 };
215 
216 struct skc_extent_phrwg_tdrNs_snap
217 {
218   struct skc_extent_ring_snap * snap;
219   cl_mem                        drN;
220   skc_subbuf_id_t               id;
221 };
222 
223 void
224 skc_extent_phrwg_tdrNs_alloc(struct skc_runtime            * const runtime,
225                              struct skc_extent_phrwg_tdrNs * const extent,
226                              size_t                          const size);
227 
228 void
229 skc_extent_phrwg_tdrNs_free(struct skc_runtime            * const runtime,
230                             struct skc_extent_phrwg_tdrNs * const extent);
231 
232 void
233 skc_extent_phrwg_tdrNs_snap_init(struct skc_runtime                 * const runtime,
234                                  struct skc_extent_ring             * const ring,
235                                  struct skc_extent_phrwg_tdrNs_snap * const snap);
236 
237 void
238 skc_extent_phrwg_tdrNs_snap_alloc(struct skc_runtime                 * const runtime,
239                                   struct skc_extent_phrwg_tdrNs      * const extent,
240                                   struct skc_extent_phrwg_tdrNs_snap * const snap,
241                                   cl_command_queue                     const cq,
242                                   cl_event                           * const event);
243 
244 void
245 skc_extent_phrwg_tdrNs_snap_free(struct skc_runtime                 * const runtime,
246                                  struct skc_extent_phrwg_tdrNs_snap * const snap);
247 
248 //
249 // DURABLE HOST R/W RING WITH AN EPHEMERAL HOST R/1 SNAPSHOT
250 //
251 // Note that because the ring and snapshot are both in host memory and
252 // the snapshot blocks progress until freed we can simply point the
253 // fake ephemeral snapshot at the ring's durable extent.
254 //
255 
256 struct skc_extent_phrwg_thr1s
257 {
258   void * hrw;
259 };
260 
261 struct skc_extent_phrwg_thr1s_snap
262 {
263   struct skc_extent_ring_snap * snap;
264 
265   struct {
266     skc_uint                    lo;
267     skc_uint                    hi;
268   } count;
269 
270   struct {
271     void                      * lo;
272     void                      * hi;
273   } hr1;
274 };
275 
276 void
277 skc_extent_phrwg_thr1s_alloc(struct skc_runtime            * const runtime,
278                              struct skc_extent_phrwg_thr1s * const extent,
279                              size_t                          const size);
280 
281 void
282 skc_extent_phrwg_thr1s_free(struct skc_runtime            * const runtime,
283                             struct skc_extent_phrwg_thr1s * const extent);
284 
285 void
286 skc_extent_phrwg_thr1s_snap_init(struct skc_runtime                 * const runtime,
287                                  struct skc_extent_ring             * const ring,
288                                  struct skc_extent_phrwg_thr1s_snap * const snap);
289 
290 void
291 skc_extent_phrwg_thr1s_snap_alloc(struct skc_runtime                 * const runtime,
292                                   struct skc_extent_phrwg_thr1s      * const extent,
293                                   struct skc_extent_phrwg_thr1s_snap * const snap);
294 
295 void
296 skc_extent_phrwg_thr1s_snap_free(struct skc_runtime                 * const runtime,
297                                  struct skc_extent_phrwg_thr1s_snap * const snap);
298 
299 //
300 // EPHEMERAL MAPPING
301 //
302 // ENTIRE EXTENT   MAPPED TO R/W   HOST MEMORY
303 // ENTIRE EXTENT UNMAPPED TO R/W DEVICE MEMORY
304 //
305 // Note: integrated vs. discrete GPUs will have different
306 // implementations because we don't want a GPU kernel repeatedly
307 // accessing pinned memory.
308 //
309 
310 #if 0
311 struct skc_extent_thrw_tdrw
312 {
313   size_t          size;
314   cl_mem          drw;
315   skc_subbuf_id_t id;
316 };
317 
318 void
319 skc_extent_thrw_tdrw_alloc(struct skc_runtime          * const runtime,
320                            struct skc_extent_thrw_tdrw * const extent,
321                            size_t                        const size);
322 
323 void
324 skc_extent_thrw_tdrw_free(struct skc_runtime          * const runtime,
325                           struct skc_extent_thrw_tdrw * const extent);
326 
327 void *
328 skc_extent_thrw_tdrw_map_size(struct skc_extent_thrw_tdrw * const extent,
329                               size_t                        const size,
330                               cl_command_queue              const cq,
331                               cl_event                    * const event);
332 
333 void *
334 skc_extent_thrw_tdrw_map(struct skc_extent_thrw_tdrw * const extent,
335                          cl_command_queue              const cq,
336                          cl_event                    * const event);
337 
338 void
339 skc_extent_thrw_tdrw_unmap(struct skc_extent_thrw_tdrw * const extent,
340                            void                        * const hrN,
341                            cl_command_queue              const cq,
342                            cl_event                    * const event);
343 #endif
344 
345 //
346 // DURABLE MAPPING
347 //
348 // ENTIRE EXTENT   MAPPED TO R/W   HOST MEMORY
349 // ENTIRE EXTENT UNMAPPED TO R/W DEVICE MEMORY
350 //
351 // Note: integrated vs. discrete GPUs will have different
352 // implementations because we don't want a GPU kernel repeatedly
353 // accessing pinned memory.
354 //
355 
356 struct skc_extent_phrw_pdrw
357 {
358   size_t size;
359   cl_mem drw;
360 };
361 
362 void
363 skc_extent_phrw_pdrw_alloc(struct skc_runtime          * const runtime,
364                            struct skc_extent_phrw_pdrw * const extent,
365                            size_t                        const size);
366 
367 void
368 skc_extent_phrw_pdrw_free(struct skc_runtime          * const runtime,
369                           struct skc_extent_phrw_pdrw * const extent);
370 
371 void *
372 skc_extent_phrw_pdrw_map_size(struct skc_extent_phrw_pdrw * const extent,
373                               size_t                        const size,
374                               cl_command_queue              const cq,
375                               cl_event                    * const event);
376 
377 void *
378 skc_extent_phrw_pdrw_map(struct skc_extent_phrw_pdrw * const extent,
379                          cl_command_queue              const cq,
380                          cl_event                    * const event);
381 
382 void
383 skc_extent_phrw_pdrw_unmap(struct skc_extent_phrw_pdrw * const extent,
384                            void                        * const hrN,
385                            cl_command_queue              const cq,
386                            cl_event                    * const event);
387 
388 //
389 // DURABLE MAPPING
390 //
391 // ENTIRE EXTENT   MAPPED TO R/O   HOST MEMORY
392 // ENTIRE EXTENT UNMAPPED TO W/O DEVICE MEMORY
393 //
394 // Note: integrated vs. discrete GPUs will have different
395 // implementations because we don't want a GPU kernel repeatedly
396 // accessing pinned memory.
397 //
398 
399 struct skc_extent_phrN_pdwN
400 {
401   size_t size;
402   cl_mem dwN;
403 };
404 
405 void
406 skc_extent_phrN_pdwN_alloc(struct skc_runtime          * const runtime,
407                            struct skc_extent_phrN_pdwN * const extent,
408                            size_t                        const size);
409 
410 void
411 skc_extent_phrN_pdwN_free(struct skc_runtime          * const runtime,
412                           struct skc_extent_phrN_pdwN * const extent);
413 
414 void *
415 skc_extent_phrN_pdwN_map_size(struct skc_extent_phrN_pdwN * const extent,
416                               size_t                        const size,
417                               cl_command_queue              const cq,
418                               cl_event                    * const event);
419 
420 void *
421 skc_extent_phrN_pdwN_map(struct skc_extent_phrN_pdwN * const extent,
422                          cl_command_queue              const cq,
423                          cl_event                    * const event);
424 
425 void
426 skc_extent_phrN_pdwN_unmap(struct skc_extent_phrN_pdwN * const extent,
427                            void                        * const hrN,
428                            cl_command_queue              const cq,
429                            cl_event                    * const event);
430 
431 //
432 // DURABLE MAPPING
433 //
434 // ENTIRE EXTENT   MAPPED TO W/O   HOST MEMORY
435 // ENTIRE EXTENT UNMAPPED TO R/O DEVICE MEMORY
436 //
437 // Note: integrated vs. discrete GPUs will have different
438 // implementations because we don't want a GPU kernel repeatedly
439 // accessing pinned memory.
440 //
441 
442 struct skc_extent_phwN_pdrN
443 {
444   size_t size;
445   cl_mem drN;
446 };
447 
448 void
449 skc_extent_phwN_pdrN_alloc(struct skc_runtime          * const runtime,
450                            struct skc_extent_phwN_pdrN * const extent,
451                            size_t                        const size);
452 
453 void
454 skc_extent_phwN_pdrN_free(struct skc_runtime          * const runtime,
455                           struct skc_extent_phwN_pdrN * const extent);
456 
457 void *
458 skc_extent_phwN_pdrN_map_size(struct skc_extent_phwN_pdrN * const extent,
459                               size_t                        const size,
460                               cl_command_queue              const cq,
461                               cl_event                    * const event);
462 
463 void *
464 skc_extent_phwN_pdrN_map(struct skc_extent_phwN_pdrN * const extent,
465                          cl_command_queue              const cq,
466                          cl_event                    * const event);
467 
468 void
469 skc_extent_phwN_pdrN_unmap(struct skc_extent_phwN_pdrN * const extent,
470                            void                        * const hwm,
471                            cl_command_queue              const cq,
472                            cl_event                    * const event);
473 
474 //
475 //
476 //
477