| 54 | | The problem with this system is that, for a given app version, |
| 55 | | efficiency can vary widely between hosts. |
| 56 | | In the above example, |
| 57 | | the 10 GFLOPS host would claim 10X as much credit, |
| | 52 | The problem with this system is that, |
| | 53 | for a given app version, efficiency can vary widely between hosts. |
| | 54 | In the above example, the 10 GFLOPS host would claim 10X as much credit, |
| 104 | | == ''A priori'' job size estimates == |
| 105 | | |
| 106 | | If we have an ''a priori'' estimate of job size, |
| 107 | | we can normalize by this to reduce the variance |
| 108 | | of various distributions (see below). |
| 109 | | This makes estimates of the means converge more quickly. |
| 110 | | |
| 111 | | We'll use workunit.rsc_fpops_est as this a priori estimate, |
| 112 | | and denote it E(J). |
| 113 | | |
| 114 | | (''A posteriori'' estimates of job size may exist also, |
| 115 | | e.g., an iteration count reported by the app, |
| 116 | | but aren't cheat-proof; we don't use them.) |
| | 100 | == ''A priori'' job size estimates and bounds == |
| | 101 | |
| | 102 | Projects supply estimates of the FLOPs used by a job |
| | 103 | (wu.rsc_fpops_est) |
| | 104 | and a limit on FLOPS, after which the job will be aborted |
| | 105 | (wu.rsc_fpops_bound). |
| | 106 | |
| | 107 | Previously, inaccuracy of rsc_fpops_est caused problems. |
| | 108 | The new system still uses rsc_fpops_est, |
| | 109 | but its primary purpose is now to indicate the relative size of jobs. |
| | 110 | Averages of job sizes are normalized by rsc_fpops_est, |
| | 111 | and if rsc_fpops_est is correlated with actual size, |
| | 112 | these averages will converge more quickly. |
| | 113 | |
| | 114 | We'll denote workunit.rsc_fpops_est as E(J). |
| | 115 | |
| | 116 | Notes: |
| | 117 | |
| | 118 | * ''A posteriori'' estimates of job size may exist also, |
| | 119 | e.g., an iteration count reported by the app. |
| | 120 | They aren't cheat-proof, and we don't use them. |
| 274 | | For anonymous platform apps, |
| 275 | | since we don't reliably know anything about the devices involved, |
| 276 | | we don't try to estimate PFC. |
| 277 | | |
| 278 | | For each app, we maintain min_avg_pfc(A), |
| 279 | | the average PFC for the most efficient version of A. |
| 280 | | |
| 281 | | The claimed credit for anonymous platform jobs is |
| 282 | | |
| 283 | | claimed_credit^mean^(A)*E(J) |
| 284 | | |
| 285 | | The server maintains host_app_version records for anonymous platform, |
| 286 | | and it keeps track of elapsed time statistics there. |
| 287 | | These have app_version_id = -2 for CPU, -3 for NVIDIA GPU, -4 for ATI. |
| | 284 | For jobs done by anonymous platform apps, |
| | 285 | the server knows the devices involved and can estimate PFC. |
| | 286 | It maintains host_app_version records for anonymous platform, |
| | 287 | and it keeps track of PFC and elapsed time statistics there. |
| | 288 | There are separate records per resource type. |
| | 289 | The app_version_id encodes the app ID and the resource type |
| | 290 | (-2 for CPU, -3 for NVIDIA GPU, -4 for ATI). |
| | 291 | |
| | 292 | If min_avg_pfc(A) is defined and |
| | 293 | PFC^mean^(H, V) is above a sample threshold, |
| | 294 | we normalize PFC by the factor |
| | 295 | |
| | 296 | min_avg_pfc(A)/PFC^mean^(H, V) |
| | 297 | |
| | 298 | Otherwise the claimed PFC is |
| | 299 | |
| | 300 | min_avg_pfc(A)*E(J) |
| | 301 | |
| | 302 | If min_avg_pfc(A) is not defined, the claimed PFC is |
| | 303 | |
| | 304 | wu.rsc_fpops_est |
| | 305 | |
| | 306 | == Summary == |
| | 307 | |
| | 308 | Given a validated job J, we compute |
| | 309 | |
| | 310 | * the "claimed PFC" F |
| | 311 | * a flag "approx" that is true if F |
| | 312 | is an approximation and may not be comparable |
| | 313 | with other instances of the job |
| | 314 | |
| | 315 | The algorithm: |
| | 316 | |
| | 317 | pfc = peak FLOP count(J) |
| | 318 | approx = true; |
| | 319 | if pfc > wu.rsc_fpops_bound |
| | 320 | if min_avg_pfc(A) is defined |
| | 321 | F = min_avg_pfc(A) * E(J) |
| | 322 | else |
| | 323 | F = wu.rsc_fpops_est |
| | 324 | else |
| | 325 | if job is anonymous platform |
| | 326 | hav = host_app_version record |
| | 327 | if min_avg_pfc(A) is defined |
| | 328 | if hav.pfc.n > threshold |
| | 329 | approx = false |
| | 330 | F = min_avg_pfc(A) /hav.pfc.avg |
| | 331 | else |
| | 332 | F = min_avg_pfc(A) * E(J) |
| | 333 | else |
| | 334 | F = wu.rsc_fpops_est |
| | 335 | else |
| | 336 | F = pfc; |
| | 337 | if Scale(V) is defined |
| | 338 | F *= Scale(V) |
| | 339 | if Scale(H, V) is defined and (H,V) is not on scale probation |
| | 340 | F *= Scale(H, V) |
| 291 | | The '''claimed FLOPS''' for a given job J is |
| 292 | | |
| 293 | | F = PFC(J) * S(V) * S(H) |
| 294 | | |
| 295 | | and the claimed credit (in Cobblestones) is |
| 296 | | |
| 297 | | C = F*100/86400e9 |
| 298 | | |
| 299 | | When replication is used, |
| 300 | | We take the set of hosts that |
| 301 | | are not anon platform and not on scale probation (see below). |
| | 344 | The claimed credit of a job (in Cobblestones) is |
| | 345 | |
| | 346 | C = F* 200/86400e9 |
| | 347 | |
| | 348 | If replication is not used, this is the granted credit. |
| | 349 | |
| | 350 | If replication is used, |
| | 351 | we take the set of instances for which approx is false. |
| 310 | | the version normalization mechanism uses the CPU |
| 311 | | version as a "sanity check" to limit the credit granted to GPU jobs |
| 312 | | (or vice versa). |
| 313 | | |
| 314 | | Suppose a project has an app with only a GPU version, |
| 315 | | so there's no CPU version to act as a sanity check. |
| | 363 | the version normalization mechanism figures out |
| | 364 | which version is most efficient and uses that to reduce |
| | 365 | the credit granted to less-efficient versions. |
| | 366 | |
| | 367 | If a project has an app with only a GPU version, |
| | 368 | there's no CPU version for comparison. |