1 // ============================================================================= 2 // === GPUQREngine/Source/BucketList_FillWorkQueue.cpp ========================= 3 // ============================================================================= 4 // 5 // FillWorkQueue is responsible for filling the work queue with items and 6 // resolving generic TaskType entries on the bundles into concrete tasks 7 // to be performed by the GPU. 8 // 9 // This function should not be called for a particular front if we are at 10 // risk of exceeding the work queue. The caller is responsible for this. 11 // The maximum number of tasks that can be placed in the queue is equal 12 // to (# row tiles) * (# col tiles) / applyGranularity, for any one front. 13 // 14 // ============================================================================= 15 16 #include "GPUQREngine_BucketList.hpp" 17 18 19 // FillWorkQueue is responsible for filling the work queue with items and 20 // resolving generic TaskType entries on the bundles into concrete tasks 21 // to be performed by the GPU. FillWorkQueue(TaskDescriptor * queue,Int * queueIndex)22Int BucketList::FillWorkQueue 23 ( 24 TaskDescriptor *queue, // The list of work items for the GPU 25 Int *queueIndex // The current index into the queue 26 ) 27 { 28 // Copy-in the current index 29 Int qindex = *queueIndex; 30 31 // Create and typecast object members to local variables. 32 int fm = (int) front->fm; 33 int fn = (int) front->fn; 34 int numColTiles = (int) this->numColTiles; 35 36 // For all bundles the bucket list is currently tracking: 37 for (int i = 0; i < numBundles; i++) 38 { 39 LLBundle& bundle = Bundles[i]; 40 TaskType type = bundle.CurrentTask; 41 int nativeBucket = (int) bundle.NativeBucket; 42 43 // Configure for block task construction. 44 int start = nativeBucket; 45 46 // If the task type is a factorize: 47 switch(type) 48 { 49 case TASKTYPE_GenericFactorize: 50 { 51 // General task configuration. 52 TaskDescriptor task; 53 bundle.gpuPack(&task); 54 task.F = gpuF; 55 task.fn = fn; 56 task.fm = fm; 57 58 // Set launch characteristics. 59 int vtOwner = nativeBucket; 60 task.extra[4] = TILESIZE * vtOwner; 61 62 // Resolve the generic type to a specific type. 63 64 // See if we need to consider edge cases. 65 int lastColumn = (TILESIZE * vtOwner) + 31; 66 bool isInternal = IsInternal(bundle, lastColumn); 67 68 switch(bundle.Count) 69 { 70 case 3: 71 task.Type = (isInternal ? TASKTYPE_FactorizeVT_3x1 72 : TASKTYPE_FactorizeVT_3x1e); 73 break; 74 case 2: 75 task.Type = (isInternal ? TASKTYPE_FactorizeVT_2x1 76 : TASKTYPE_FactorizeVT_2x1e); 77 break; 78 case 1: 79 task.Type = (isInternal ? TASKTYPE_FactorizeVT_1x1 80 : TASKTYPE_FactorizeVT_1x1e); 81 break; 82 } 83 84 // Add the task to the queue. 85 queue[qindex++] = task; 86 87 break; 88 } 89 90 #ifdef GPUQRENGINE_PIPELINING 91 case TASKTYPE_GenericApplyFactorize: 92 { 93 // General task configuration. 94 TaskDescriptor task; 95 bundle.gpuPack(&task); 96 task.F = gpuF; 97 task.fn = fn; 98 task.fm = fm; 99 100 // Set launch characteristics. 101 int vtOwner = nativeBucket - 1; 102 int from = nativeBucket; 103 int to = MIN(nativeBucket + 1, numColTiles); 104 task.extra[4] = TILESIZE * vtOwner; 105 task.extra[5] = TILESIZE * from; 106 task.extra[6] = TILESIZE * to; 107 108 // Resolve the generic type to a specific type. 109 int factorizeCount = bundle.Count; 110 switch(bundle.ApplyCount) 111 { 112 case 3: 113 switch(factorizeCount) 114 { 115 case 3: 116 task.Type = TASKTYPE_Apply3_Factorize3; 117 break; 118 case 2: 119 task.Type = TASKTYPE_Apply3_Factorize2; 120 break; 121 // case 1: never happens 122 } 123 break; 124 case 2: 125 switch(factorizeCount) 126 { 127 case 3: 128 task.Type = TASKTYPE_Apply2_Factorize3; 129 break; 130 case 2: 131 task.Type = TASKTYPE_Apply2_Factorize2; 132 break; 133 case 1: 134 task.Type = TASKTYPE_Apply2_Factorize1; 135 break; 136 } 137 break; 138 // case 1: never happens. We never have an apply-factorize 139 // with one tile. A one-tile apply is considered a phantom 140 // bundle. We avoid the bogus rearrange. 141 } 142 143 // Add the task to the queue. 144 queue[qindex++] = task; 145 146 // Configure parameters to build the rest of the applies. 147 start++; 148 type = TASKTYPE_GenericApply; 149 150 // INTENTIONALLY FALL THROUGH TO BUILD THE APPLIES 151 } 152 #endif 153 154 case TASKTYPE_GenericApply: 155 { 156 for( ; start < numBuckets; start += ApplyGranularity) 157 { 158 // General task configuration. 159 TaskDescriptor task; 160 bundle.gpuPack(&task); 161 task.F = gpuF; 162 task.fn = fn; 163 task.fm = fm; 164 165 // Set launch characteristics. 166 int vtOwner = nativeBucket - 1; 167 int from = start; 168 int to = MIN(start + ApplyGranularity, numColTiles); 169 task.extra[4] = TILESIZE * vtOwner; 170 task.extra[5] = TILESIZE * from; 171 task.extra[6] = TILESIZE * to; 172 173 // Resolve the generic type to a specific type. 174 switch(bundle.ApplyCount) 175 { 176 case 3: task.Type = TASKTYPE_Apply3; break; 177 case 2: task.Type = TASKTYPE_Apply2; break; 178 case 1: task.Type = TASKTYPE_Apply1; break; 179 } 180 181 // Add the task to the queue. 182 queue[qindex++] = task; 183 } 184 185 break; 186 } 187 default: break; // DEAD: no default case is ever used. 188 } 189 } 190 191 // Compute the number of tasks we just built. 192 Int numTasks = qindex - *queueIndex; 193 194 // Copy-out the current index 195 *queueIndex = qindex; 196 197 return numTasks; 198 } 199