| 210 | | === Pseudo-code === |
| 211 | | |
| 212 | | The top-level function is: |
| 213 | | {{{ |
| 214 | | WORK_FETCH::choose_project() |
| 215 | | rr_simulation() |
| 216 | | |
| 217 | | if cuda_work_fetch.nidle |
| 218 | | cpu_work_fetch.shortfall = 0 |
| 219 | | p = cuda_work_fetch.select_project() |
| 220 | | if p |
| 221 | | send_req(p) |
| 222 | | return |
| 223 | | if cpu_work_fetch.nidle |
| 224 | | cuda_work_fetch.shortfall = 0 |
| 225 | | p = cpu_work_fetch.select_project() |
| 226 | | if p |
| 227 | | send_req(p) |
| 228 | | return |
| 229 | | if cuda_work_fetch.shortfall |
| 230 | | p = cuda_work_fetch.select_project() |
| 231 | | if p |
| 232 | | send_req(p) |
| 233 | | return |
| 234 | | if cpu_work_fetch.shortfall |
| 235 | | p = cpu_work_fetch.select_project() |
| 236 | | if p |
| 237 | | send_req(p) |
| 238 | | return |
| 239 | | |
| 240 | | void send_req(p) |
| 241 | | req.cpu_req_seconds = cpu_work_fetch.shortfall |
| 242 | | req.cpu_req_ninstances = cpu_work_fetch.nidle |
| 243 | | req.cuda_req_seconds = cuda_work_fetch.shortfall |
| 244 | | req.cuda_req_ninstances = cuda_work_fetch.nidle |
| 245 | | req.work_req_seconds = max(req.cpu_req_seconds, req.cuda_req_seconds) |
| 246 | | |
| 247 | | }}} |
| 248 | | |
| 249 | | {{{ |
| 250 | | |
| 251 | | for each resource type R |
| 252 | | for each project P |
| 253 | | if P is not backed off for R |
| 254 | | P.R.LTD += share |
| 255 | | for each running job J, project P |
| 256 | | for each resource R used by J |
| 257 | | P.R.LTD -= share*dt |
| 258 | | }}} |
| 259 | | |
| 260 | | === RR simulation === |
| 261 | | |
| 262 | | {{{ |
| 263 | | cpu_work_fetch.rr_init() |
| 264 | | cuda_work_fetch.rr_init() |
| 265 | | |
| 266 | | compute initial assignment of jobs |
| 267 | | cpu_work_fetch.set_nidle(); |
| 268 | | cuda_work_fetch.set_nidle(); |
| 269 | | |
| 270 | | do simulation as current |
| 271 | | on completion of an interval dt |
| 272 | | cpu_work_fetch.accumulate_shortfall(dt) |
| 273 | | cuda_work_fetch.accumulate_shortfall(dt) |
| 274 | | }}} |
| 275 | | |
| 276 | | === Work fetch === |
| 277 | | |
| 278 | | |
| 279 | | === Handling scheduler reply === |
| 280 | | {{{ |
| 281 | | if no jobs returned |
| 282 | | double backoff for each requested PRSC |
| 283 | | else |
| 284 | | clear backoff for the PRSC of each returned job |
| 285 | | }}} |
| | 211 | '''PROJECT* choose_project()''':: choose a project from which to fetch work. |
| | 212 | |
| | 213 | * Do round-robin simulation |
| | 214 | * if a GPU is idle, choose a project to ask for that type of work (using RSC_WORK_FETCH::choose_project()) |
| | 215 | * if a CPU is idle, choose a project to ask for CPU work |
| | 216 | * if GPU has a shortfall, choose a project to ask for GPU work |
| | 217 | * if CPU has a shortfall, choose a project to ask for CPU work |
| | 218 | In the case where a resource type was idle, ask for only that type of work. |
| | 219 | Otherwise ask for all types of work for which there is a shortfall. |