b85f5b4b731bd17f292e36bf766561a91dc77cbc
[charm.git] / src / arch / cuda / hybridAPI / wrqueue.h
1 /*
2  * wrqueue.h
3  *
4  * by Lukasz Wesolowski
5  * 04.12.2008
6  *
7  * a simple FIFO queue for GPU work requests
8  *
9  */
10
11 #ifndef __WR_QUEUE_H__
12 #define __WR_QUEUE_H__
13
14 /* number of work requests the queue is initialized to handle */
15 #define QUEUE_SIZE_INIT 10
16
17 /* if the queue is filled, it will be expanded by this many additional 
18    units */ 
19 #define QUEUE_EXPANSION_SIZE 10
20
21 /* struct workRequest
22  * 
23  * purpose:  
24  * structure for holding information about work requests on the GPU
25  *
26  * usage model: 
27  * 1. declare a pointer to a workRequest 
28  * 2. allocate dynamic memory for the work request
29  * 3. call setupMemory to copy over the data to the GPU 
30  * 4. enqueue the work request by using addWorkRequest
31  */
32
33 typedef struct workRequest {
34
35   /* parameters for kernel execution */
36
37   dim3 dimGrid; 
38   dim3 dimBlock; 
39   int smemSize;
40   
41   /* pointers to queues and their lengths on the device(gpu) and
42      host(cpu)  */
43
44   void *readWriteDevicePtr;
45   void *readWriteHostPtr; 
46   int readWriteLen; 
47
48   void *readOnlyDevicePtr; 
49   void *readOnlyHostPtr; 
50   int readOnlyLen; 
51
52   void *writeOnlyDevicePtr;
53   void *writeOnlyHostPtr; 
54   int writeOnlyLen; 
55
56   /* to be called after the kernel finishes executing on the GPU */ 
57
58   void (*callbackFn)(); 
59
60   /* to select the correct kernel in the switch statement */
61
62   int switchNo; 
63
64   /* event which will be polled to check if kernel has finished
65      execution */
66
67   cudaEvent_t completionEvent;  
68
69   /* flags */
70
71   int executing; 
72
73 } workRequest; 
74
75
76 /* struct workRequestQueue 
77  *
78  * purpose: container/mechanism for GPU work requests 
79  *
80  * usage model: 
81  * 1. declare a workRequestQueue
82  * 2. call init to allocate memory for the queue and initialize
83  *    bookkeeping variables
84  * 3. call enqueue for each request which needs to be 
85  *    executed on the GPU
86  * 4. in the hybrid API gpuProgressFn will execute periodically to
87  *    handle the details of executing the work request on the GPU
88  *             
89  * implementation notes: 
90  * the queue is implemented using a circular array; if the array fills
91  * up, requests are transferred to a queue having additional
92  * QUEUE_EXPANSION_SIZE slots, and the memory for the old queue is freed
93  */
94
95 typedef struct {
96
97   /* array of requests */
98   workRequest* requests; 
99
100   /* array index for the logically first item in the queue */
101   int head; 
102
103   /* array index for the last item in the queue */ 
104   int tail; 
105
106   /* number of work requests in the queue */
107   int size; 
108
109   /* size of the array of work requests */ 
110   int capacity; 
111
112 } workRequestQueue; 
113
114 /* init_wrqueue
115  *
116  * allocate memory for the queue and initialize bookkeeping variables
117  *
118  */
119 void init_wrqueue(workRequestQueue *q); 
120
121 /* enqueue
122  *
123  * add a work request to the queue to be later executed on the GPU
124  *
125  */
126
127 void enqueue(workRequestQueue *q, workRequest *wr); 
128
129 /* dequeue
130  *
131  * delete the head entry in the queue
132  * assumes memory buffers have previously been freed or will be reused
133  *
134  */
135 void dequeue(workRequestQueue *q); 
136
137 /* delete_wrqueue
138  *
139  * if queue is nonempty, return -1  
140  * if queue is empty, delete the queue, freeing dynamically allocated 
141  * memory, and return 0
142  *
143  *
144  */
145
146 int delete_wrqueue(workRequestQueue *q); 
147
148 /* head
149  * 
150  * returns the first element in the queue 
151  *
152  */
153
154 workRequest * head(workRequestQueue *q);
155
156 /*
157  * isEmpty
158  *
159  * returns:
160  * 1 if queue has no pending requests stored
161  * 0 otherwise
162  */
163
164 int isEmpty(workRequestQueue *q);
165
166 #endif