Passed
Pull Request — master (#6672)
by David
14:02 queued 05:26
created

get_gpu_list()   D

Complexity

Conditions 15
Paths 242

Size

Total Lines 70
Code Lines 47

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 15
eloc 47
nc 242
nop 1
dl 0
loc 70
rs 4.5583
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
// This file is part of BOINC.
4
// http://boinc.berkeley.edu
5
// Copyright (C) 2011 University of California
6
//
7
// BOINC is free software; you can redistribute it and/or modify it
8
// under the terms of the GNU Lesser General Public License
9
// as published by the Free Software Foundation,
10
// either version 3 of the License, or (at your option) any later version.
11
//
12
// BOINC is distributed in the hope that it will be useful,
13
// but WITHOUT ANY WARRANTY; without even the implied warranty of
14
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
// See the GNU Lesser General Public License for more details.
16
//
17
// You should have received a copy of the GNU Lesser General Public License
18
// along with BOINC.  If not, see <http://www.gnu.org/licenses/>.
19
20
// generate a page of the best-performing GPU models.
21
//
22
// "best-performing" is defined as minimizing the average of
23
//
24
// elapsed_time(J)/rsc_fpops_est(J)
25
// over completed jobs J currently in the DB
26
//
27
// TODO: this is fantastically inefficient
0 ignored issues
show
Coding Style Best Practice introduced by
Comments for TODO tasks are often forgotten in the code; it might be better to use a dedicated issue tracker.
Loading history...
28
29
require_once("../inc/util.inc");
30
31
// strip leading AMD, NVIDIA, etc.
32
// This avoids showing the same model twice
33
//
34
function strip_vendor($model) {
35
    foreach (array("AMD ", "NVIDIA ", "ATI ", "Intel(R) ") as $maker) {
36
        $n = strlen($maker);
37
        if (substr($model, 0, $n) == $maker) {
38
            return substr($model, $n);
39
        }
40
    }
41
    return $model;
42
}
43
44
// given a host.misc field,
45
// extract the GPU model name for the given vendor
46
//
47
function get_gpu_model($x, $vendor) {
48
    if (empty($x->gpus)) return null;
49
    foreach ($x->gpus as $gpu) {
50
        if ($gpu->type == $vendor) {
51
            return $gpu->model;
52
        }
53
    }
54
    return null;
55
}
56
57
function add_model($model, $r, $wu, &$models) {
58
    if (array_key_exists($model, $models)) {
59
        $models[$model]->count++;
60
        $models[$model]->time += $r->elapsed_time/$wu->rsc_fpops_est;
61
    } else {
62
        $x = new StdClass;
63
        $x->count = 1;
64
        $x->time = $r->elapsed_time/$wu->rsc_fpops_est;
65
        $models[$model] = $x;
66
    }
67
}
68
69
// return a data structure containing GPU usage info for a vendor
70
// $x->total: combined list
71
// $x->windows
72
// $x->linux
73
// $x->mac
74
//
75
// vendor is nvidia, amd, intel, or apple
76
77
function get_gpu_list($vendor) {
78
79
    // plan class names contain:
80
    // nvidia
81
    // amd or ati
82
    // intel
83
    // apple
84
85
    $clause = "plan_class like '%$vendor%'";
86
    if ($vendor == 'amd') {
87
        $clause .= " or plan_class like '%ati%'";
88
    }
89
    $avs = BoincAppVersion::enum($clause);
90
    if (count($avs) == 0) {
91
        $x = new StdClass;
92
        $x->total = array();
93
        return $x;
94
    }
95
96
    $av_ids = [];
97
    foreach($avs as $av) {
98
        $av_ids[] = $av->id;
99
    }
100
    if ($vendor == "nvidia") {
101
        $av_ids[] = ANON_PLATFORM_NVIDIA;
102
    } else if ($vendor == "amd") {
103
        $av_ids[] = ANON_PLATFORM_ATI;
104
    } else if ($vendor == "intel") {
105
        $av_ids[] = ANON_PLATFORM_INTEL_GPU;
106
    } else if ($vendor == "apple") {
107
        $av_ids[] = ANON_PLATFORM_APPLE_GPU;
108
    }
109
110
    $av_ids = implode(',', $av_ids);
111
112
    $t = time() - 30*86400;
113
    //echo "start enum $vendor $av_ids\n";
114
    $results = BoincResult::enum(
115
        "app_version_id in ($av_ids) and create_time > $t and elapsed_time>100 limit 2000"
116
    );
117
    //echo "end enum\n";
118
    $total = array();
119
    $win = array();
120
    $linux = array();
121
    $mac = array();
122
    foreach ($results as $r) {
123
        $h = BoincHost::lookup_id($r->hostid);
124
        if (!$h) continue;
125
        $wu = BoincWorkunit::lookup_id($r->workunitid);
126
        if (!$wu) continue;
127
        $model = get_gpu_model(json_decode($h->misc), $vendor);
128
        if (!$model) continue;
129
        add_model($model, $r, $wu, $total);
130
        if (strstr($h->os_name, "Windows")) {
131
            add_model($model, $r, $wu, $win);
132
        }
133
        if (strstr($h->os_name, "Linux")) {
134
            add_model($model, $r, $wu, $linux);
135
        }
136
        if (strstr($h->os_name, "Darwin")) {
137
            add_model($model, $r, $wu, $mac);
138
        }
139
140
    }
141
    $x = new StdClass;
142
    $x->total = $total;
143
    $x->win = $win;
144
    $x->linux = $linux;
145
    $x->mac = $mac;
146
    return $x;
147
}
148
149
function get_gpu_lists() {
150
    $x = new StdClass;
151
    $x->cuda = get_gpu_list("nvidia");
152
    $x->ati = get_gpu_list("amd");
153
    $x->intel_gpu = get_gpu_list("intel");
154
    $x->apple_gpu = get_gpu_list("apple");
155
    $x->time = time();
156
    return $x;
157
}
158
159
function gpucmp($x1, $x2) {
160
    return $x1->avg_time > $x2->avg_time;
161
}
162
163
function show_list($models, $name) {
164
    echo "<td><h2>$name</h2>\n";
165
    if (!count($models)) {
166
        echo tra("No GPU tasks reported")."</td>\n";
167
        return;
168
    }
169
    $max_count = 0;
170
    foreach ($models as $model=>$x) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space before "=>"; 0 found
Loading history...
Coding Style introduced by
Expected 1 space after "=>"; 0 found
Loading history...
171
        if ($x->count > $max_count) $max_count = $x->count;
172
        $x->avg_time = $x->time/$x->count;
173
    }
174
    $min_time = 1e9;
175
    foreach ($models as $model=>$x) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space before "=>"; 0 found
Loading history...
Coding Style introduced by
Expected 1 space after "=>"; 0 found
Loading history...
176
        if ($x->count < $max_count/10) continue;
177
        if ($x->avg_time < $min_time) $min_time = $x->avg_time;
178
    }
179
    uasort($models, 'gpucmp');
180
    echo "<ol>\n";
181
    foreach ($models as $model=>$x) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space before "=>"; 0 found
Loading history...
Coding Style introduced by
Expected 1 space after "=>"; 0 found
Loading history...
182
        if ($x->count < $max_count/10) continue;
183
        $s = number_format($min_time/$x->avg_time, 3);
184
        echo "<li>($s)  $model\n";
185
    }
186
    echo "</ol></td>\n";
187
}
188
189
function show_vendor($vendor, $x) {
190
    echo "<h2>$vendor</h2>\n";
191
    if (!count($x->total)) {
192
        echo tra("No GPU tasks reported");
193
        return;
194
    }
195
    $have_win = count($x->win)>0;
196
    $have_mac = count($x->mac)>0;
197
    $have_linux = count($x->linux)>0;
198
    $n = 0;
199
    if ($have_win) $n++;
200
    if ($have_mac) $n++;
201
    if ($have_linux) $n++;
202
    $show_total = $n>1;
203
    start_table();
204
    echo "<tr>";
205
    if ($show_total) {
206
        show_list($x->total, "Total");
207
    }
208
    show_list($x->win, "Windows");
209
    show_list($x->linux, "Linux");
210
    show_list($x->mac, "Mac");
211
    echo "</tr></table>\n";
212
}
213
214
$d = get_cached_data(86400);
215
$data = FALSE;
216
if ($d) {
217
    $data = unserialize($d);
218
}
219
220
if (!$data) {
221
    $data = get_gpu_lists();
222
    set_cached_data(86400, serialize($data));
223
}
224
225
page_head(tra("Top GPU models"));
226
echo tra("The following lists show the most productive GPU models on different platforms.  Relative speeds, measured by average elapsed time of tasks, are shown in parentheses.");
227
show_vendor("NVIDIA", $data->cuda);
228
show_vendor("ATI/AMD", $data->ati);
229
show_vendor("Intel", $data->intel_gpu);
230
show_vendor("Apple", $data->apple_gpu);
231
echo "<p>Generated ".time_str($data->time);
232
page_tail();
233
234
?>
235