File: result.h

package info (click to toggle)
boinc 8.0.4%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 106,832 kB
  • sloc: cpp: 167,537; php: 111,699; pascal: 56,262; ansic: 49,284; xml: 18,762; python: 7,938; javascript: 6,538; sh: 5,719; makefile: 2,183; java: 2,041; objc: 1,867; perl: 1,843; sql: 830; lisp: 47; csh: 30
file content (269 lines) | stat: -rw-r--r-- 8,716 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
// This file is part of BOINC.
// http://boinc.berkeley.edu
// Copyright (C) 2022 University of California
//
// BOINC is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// BOINC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with BOINC.  If not, see <http://www.gnu.org/licenses/>.

#ifndef BOINC_RESULT_H
#define BOINC_RESULT_H

#include "project.h"

struct RESULT {
    char name[256];
    char wu_name[256];
    double received_time;   // when we got this from server
    double report_deadline;
    int version_num;        // identifies the app used
    char plan_class[64];
    char platform[256];
    APP_VERSION* avp;
    std::vector<FILE_REF> output_files;
    bool ready_to_report;
        // we're ready to report this result to the server;
        // either computation is done and all the files have been uploaded
        // or there was an error
    double completed_time;
        // time when ready_to_report was set
    bool got_server_ack;
        // we've received the ack for this result from the server
    double final_cpu_time;
    double final_elapsed_time;
    double final_peak_working_set_size;
    double final_peak_swap_size;
    double final_peak_disk_usage;
    double final_bytes_sent;
    double final_bytes_received;
#ifdef SIM
    double peak_flop_count;
    double sim_flops_left;
#endif

    // the following are nonzero if reported by app
    double fpops_per_cpu_sec;
    double fpops_cumulative;
    double intops_per_cpu_sec;
    double intops_cumulative;

    int _state;
        // state of this result: see lib/result_state.h
    inline int state() { return _state; }
    inline void set_ready_to_report() {
        ready_to_report = true;
    }
    void set_state(int, const char*);
    int exit_status;
        // return value from the application
    std::string stderr_out;
        // the concatenation of:
        //
        // - if report_result_error() is called for this result:
        //   <message>x</message>
        //   <exit_status>x</exit_status>
        //   <signal>x</signal>
        //   - if called in FILES_DOWNLOADED state:
        //     <couldnt_start>x</couldnt_start>
        //   - if called in NEW state:
        //     <download_error>x</download_error> for each failed download
        //   - if called in COMPUTE_DONE state:
        //     <upload_error>x</upload_error> for each failed upload
        //
        // - <stderr_txt>X</stderr_txt>, where X is the app's stderr output
    bool suspended_via_gui;
    bool coproc_missing;
        // a coproc needed by this job is missing
        // (e.g. because user removed their GPU board).
    bool report_immediately;
    bool not_started;   // temp for CPU sched

    std::string name_md5;   // see sort_results();
    int index;              // index in results vector

    APP* app;
    WORKUNIT* wup;
    PROJECT* project;

    RESULT(){
        clear();
    }
    ~RESULT(){}
    void clear();
    int parse_server(XML_PARSER&);
    int parse_state(XML_PARSER&);
    int parse_name(XML_PARSER&, const char* end_tag);
    int write(MIOFILE&, bool to_server);
    int write_gui(MIOFILE&, bool check_resources = false);
    bool is_upload_done();    // files uploaded?
    void clear_uploaded_flags();
    FILE_REF* lookup_file(FILE_INFO*);
    FILE_INFO* lookup_file_logical(const char*);
    void abort_inactive(int);
        // abort the result if it hasn't started computing yet
        // Called only for results with no active task
        // (otherwise you need to abort the active task)
    void append_log_record();

    // stuff related to CPU scheduling

    bool is_not_started();
    double estimated_runtime();
    double estimated_runtime_uncorrected();
    double estimated_runtime_remaining();
    inline double estimated_flops_remaining() {
#ifdef SIM
        return sim_flops_left;
#else
        return estimated_runtime_remaining()*avp->flops;
#endif
    }

    inline bool computing_done() {
        if (state() >= RESULT_COMPUTE_ERROR) return true;
        if (ready_to_report) return true;
        return false;
    }
    bool runnable();
        // downloaded, not finished, not suspended, project not suspended
    bool nearly_runnable();
        // downloading or downloaded,
        // not finished, suspended, project not suspended
    bool downloading();
        // downloading, not downloaded, not suspended, project not suspended
    bool some_download_stalled();
        // some input or app file is downloading, and backed off
        // i.e. it may be a long time before we can run this result
    inline bool uses_coprocs() {
        return (avp->gpu_usage.rsc_type != 0);
    }
    inline bool uses_gpu() {
        int rt = avp->gpu_usage.rsc_type;
        if (!rt) return false;
        if (coprocs.coprocs[rt].non_gpu) return false;
        return true;
    }
    inline int resource_type() {
        return avp->gpu_usage.rsc_type;
    }
    inline bool non_cpu_intensive() {
        if (project->non_cpu_intensive) return true;
        return app->non_cpu_intensive;
    }
    inline bool sporadic() {
        return app->sporadic;
    }
    inline bool always_run() {
        return non_cpu_intensive() || sporadic();
    }
    inline bool dont_throttle() {
        if (non_cpu_intensive()) return true;
        if (avp->dont_throttle) return true;
        return false;
    }
    // make a string describing resource usage
    inline void rsc_string(char* buf, int len) {
        if (avp->gpu_usage.rsc_type) {
            snprintf(buf, len,
                "%.2f CPU + %.2f %s",
                avp->avg_ncpus, avp->gpu_usage.usage,
                rsc_name_long(avp->gpu_usage.rsc_type)
            );
        } else {
            snprintf(buf, len, "%.2f CPU", avp->avg_ncpus);
        }
    }


    // temporaries used in CLIENT_STATE::rr_simulation():
    double rrsim_flops_left;
    double rrsim_finish_delay;
    double rrsim_flops;
    bool rrsim_done;

    bool already_selected;
        // used to keep cpu scheduler from scheduling a result twice
        // transient; used only within schedule_cpus()
        // also used in round-robin simulation
    double computation_deadline();
        // report deadline - prefs.work_buf_min - time slice
    bool rr_sim_misses_deadline;

    // temporaries used in enforce_schedule():
    bool unfinished_time_slice;
    int seqno;

    bool edf_scheduled;
        // temporary used to tell GUI that this result is deadline-scheduled

    int coproc_indices[MAX_COPROCS_PER_JOB];
        // keep track of coprocessor reservations
    char resources[256];
        // textual description of resources used
    double schedule_backoff;
        // don't try to schedule until this time
        // (because the app called boinc_temporary_exit())
    char schedule_backoff_reason[256];
};

#define CONCURRENT_LIMIT_APP        1
#define CONCURRENT_LIMIT_PROJECT    2

// are we at or beyond a max_concurrent limit for this job?
//
inline int max_concurrent_exceeded(RESULT* rp) {
    APP* app = rp->app;
    if (app->max_concurrent) {
        if (app->app_n_concurrent >= app->max_concurrent) {
            return CONCURRENT_LIMIT_APP;
        }
    }
    PROJECT* p = rp->project;
    if (p->app_configs.project_max_concurrent) {
        if (p->proj_n_concurrent >= p->app_configs.project_max_concurrent) {
            return CONCURRENT_LIMIT_PROJECT;
        }
    }
    return 0;
}

// we're about to run this job.
// increment counters for enforcing max_concurrent prefs
// Used in RR simulation (RR_SIM::activate())
// and in job scheduling (enforce_run_list())
//
inline void max_concurrent_inc(RESULT* rp) {
    rp->app->app_n_concurrent++;
    rp->project->proj_n_concurrent++;
}

// a completed result, for which the RESULT record no longer exists.
// We keep an in-memory log of these.
// Keep this consistent with lib/gui_rpc_client.h
//
struct OLD_RESULT {
    char project_url[256];
    char result_name[256];
    char app_name[256];
    int exit_status;
    double elapsed_time;
    double cpu_time;
    double completed_time;
    double create_time;     // when this record was created
};

extern std::deque<OLD_RESULT> old_results;

void add_old_result(RESULT&);
extern void print_old_results(MIOFILE&);

#endif