~ubuntu-branches/ubuntu/precise/boinc/precise

« back to all changes in this revision

Viewing changes to sched/sched_types.h

Tags: 6.12.8+dfsg-1
* New upstream release.
* Simplified debian/rules

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// This file is part of BOINC.
 
2
// http://boinc.berkeley.edu
 
3
// Copyright (C) 2008 University of California
 
4
//
 
5
// BOINC is free software; you can redistribute it and/or modify it
 
6
// under the terms of the GNU Lesser General Public License
 
7
// as published by the Free Software Foundation,
 
8
// either version 3 of the License, or (at your option) any later version.
 
9
//
 
10
// BOINC is distributed in the hope that it will be useful,
 
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
13
// See the GNU Lesser General Public License for more details.
 
14
//
 
15
// You should have received a copy of the GNU Lesser General Public License
 
16
// along with BOINC.  If not, see <http://www.gnu.org/licenses/>.
 
17
 
 
18
#ifndef _SERVER_TYPES_
 
19
#define _SERVER_TYPES_
 
20
 
 
21
#include <cstdio>
 
22
#include <vector>
 
23
 
 
24
#include "boinc_db.h"
 
25
#include "common_defs.h"
 
26
#include "md5_file.h"
 
27
#include "coproc.h"
 
28
 
 
29
#include "edf_sim.h"
 
30
 
 
31
// for projects that support work filtering by app,
 
32
// this records an app for which the user will accept work
 
33
//
 
34
struct APP_INFO {
 
35
        int appid;
 
36
        int work_available;
 
37
};
 
38
 
 
39
// represents a resource (disk etc.) that the client may not have enough of
 
40
//
 
41
struct RESOURCE {
 
42
    bool insufficient;
 
43
    double needed;      // the min extra amount needed
 
44
 
 
45
    inline void set_insufficient(double x) {
 
46
        insufficient = true;
 
47
        if (needed) {
 
48
            if (x < needed) needed = x;
 
49
        } else {
 
50
            needed = x;
 
51
        }
 
52
    }
 
53
};
 
54
 
 
55
// message intended for human eyes
 
56
//
 
57
struct USER_MESSAGE {
 
58
    std::string message;
 
59
    std::string priority;
 
60
    USER_MESSAGE(const char* m, const char*p);
 
61
};
 
62
 
 
63
struct HOST_USAGE {
 
64
    double ncudas;
 
65
    double natis;
 
66
    double gpu_ram;
 
67
    double avg_ncpus;
 
68
    double max_ncpus;
 
69
    double projected_flops;
 
70
        // the scheduler's best estimate of wu.rsc_fpops_est/elapsed_time.
 
71
        // Taken from host_app_version elapsed time statistics if available,
 
72
        // else on estimate provided by app_plan()
 
73
    double peak_flops;
 
74
        // stored in result.estimated_flops, and used for credit calculations
 
75
    char cmdline[256];
 
76
 
 
77
    HOST_USAGE() {
 
78
        ncudas = 0;
 
79
        natis = 0;
 
80
        gpu_ram = 0;
 
81
        avg_ncpus = 1;
 
82
        max_ncpus = 1;
 
83
        projected_flops = 0;
 
84
        peak_flops = 0;
 
85
        strcpy(cmdline, "");
 
86
    }
 
87
    void sequential_app(double x) {
 
88
        ncudas = 0;
 
89
        natis = 0;
 
90
        gpu_ram = 0;
 
91
        avg_ncpus = 1;
 
92
        max_ncpus = 1;
 
93
        if (x <= 0) x = 1e9;
 
94
        projected_flops = x;
 
95
        peak_flops = x;
 
96
        strcpy(cmdline, "");
 
97
    }
 
98
    inline int resource_type() {
 
99
        if (ncudas) {
 
100
            return ANON_PLATFORM_NVIDIA;
 
101
        } else if (natis) {
 
102
            return ANON_PLATFORM_ATI;
 
103
        }
 
104
        return ANON_PLATFORM_CPU;
 
105
    }
 
106
    inline const char* resource_name() {
 
107
        if (ncudas) {
 
108
            return "nvidia GPU";
 
109
        } else if (natis) {
 
110
            return "ATI GPU";
 
111
        }
 
112
        return "CPU";
 
113
    }
 
114
    inline bool uses_gpu() {
 
115
        if (ncudas) return true;
 
116
        if (natis) return true;
 
117
        return false;
 
118
    }
 
119
};
 
120
 
 
121
// a description of a sticky file on host.
 
122
//
 
123
struct FILE_INFO {
 
124
    char name[256];
 
125
 
 
126
    int parse(FILE*);
 
127
};
 
128
 
 
129
struct MSG_FROM_HOST_DESC {
 
130
    char variety[256];
 
131
    std::string msg_text;
 
132
    int parse(FILE*);
 
133
};
 
134
 
 
135
// an app version from an anonymous-platform client
 
136
// (starting with 6.11, ALL clients send these)
 
137
//
 
138
struct CLIENT_APP_VERSION {
 
139
    char app_name[256];
 
140
    char platform[256];
 
141
    int version_num;
 
142
    char plan_class[256];
 
143
    HOST_USAGE host_usage;
 
144
    double rsc_fpops_scale;
 
145
        // multiply wu.rsc_fpops_est and rsc_fpops_limit
 
146
        // by this amount when send to client,
 
147
        // to reflect the discrepancy between how fast the client
 
148
        // thinks the app is versus how fast we think it is
 
149
    APP* app;
 
150
        // if NULL, this record is a place-holder,
 
151
        // used to preserve array indices
 
152
 
 
153
    int parse(FILE*);
 
154
};
 
155
 
 
156
// keep track of the best app_version for each app for this host
 
157
//
 
158
struct BEST_APP_VERSION {
 
159
    int appid;
 
160
    bool for_64b_jobs;
 
161
        // maintain this separately for jobs that need > 2GB RAM,
 
162
        // in which case we can't use 32-bit apps
 
163
 
 
164
    bool present;
 
165
        // false means there's no usable version for this app
 
166
 
 
167
    CLIENT_APP_VERSION* cavp;
 
168
        // populated if anonymous platform
 
169
 
 
170
    APP_VERSION* avp;
 
171
        // populated otherwise
 
172
 
 
173
    HOST_USAGE host_usage;
 
174
        // populated in either case
 
175
 
 
176
    bool reliable;
 
177
    bool trusted;
 
178
 
 
179
    DB_HOST_APP_VERSION* host_app_version();
 
180
        // get the HOST_APP_VERSION, if any
 
181
        
 
182
    BEST_APP_VERSION() {
 
183
        present = false;
 
184
        cavp = NULL;
 
185
        avp = NULL;
 
186
    }
 
187
};
 
188
 
 
189
// subset of global prefs used by scheduler
 
190
//
 
191
struct GLOBAL_PREFS {
 
192
    double mod_time;
 
193
    double disk_max_used_gb;
 
194
    double disk_max_used_pct;
 
195
    double disk_min_free_gb;
 
196
    double work_buf_min_days;
 
197
    double ram_max_used_busy_frac;
 
198
    double ram_max_used_idle_frac;
 
199
    double max_ncpus_pct;
 
200
 
 
201
    void parse(const char* buf, const char* venue);
 
202
    void defaults();
 
203
    inline double work_buf_min() {return work_buf_min_days*86400;}
 
204
};
 
205
 
 
206
struct GUI_URLS {
 
207
    char* text;
 
208
    void init();
 
209
    void get_gui_urls(USER& user, HOST& host, TEAM& team, char*);
 
210
};
 
211
 
 
212
struct PROJECT_FILES {
 
213
    char* text;
 
214
    void init();
 
215
};
 
216
 
 
217
// Represents a result from this project that the client has.
 
218
// The request message has a list of these.
 
219
// The reply message may include a list of those to be aborted
 
220
// or aborted if not started
 
221
//
 
222
struct OTHER_RESULT {
 
223
    char name[256];
 
224
    int app_version;    // index into CLIENT_APP_VERSION array
 
225
    char plan_class[64];
 
226
    bool have_plan_class;
 
227
    bool abort;
 
228
    bool abort_if_not_started;
 
229
    int reason;     // see codes below
 
230
 
 
231
    int parse(FILE*);
 
232
};
 
233
 
 
234
#define ABORT_REASON_NOT_FOUND      1
 
235
#define ABORT_REASON_WU_CANCELLED   2
 
236
#define ABORT_REASON_ASSIMILATED    3
 
237
#define ABORT_REASON_TIMED_OUT      4
 
238
 
 
239
struct CLIENT_PLATFORM {
 
240
    char name[256];
 
241
    int parse(FILE*);
 
242
};
 
243
 
 
244
struct PLATFORM_LIST {
 
245
    std::vector<PLATFORM*> list;
 
246
};
 
247
 
 
248
struct SCHEDULER_REQUEST {
 
249
    char authenticator[256];
 
250
    CLIENT_PLATFORM platform;
 
251
    std::vector<CLIENT_PLATFORM> alt_platforms;
 
252
    PLATFORM_LIST platforms;
 
253
    char cross_project_id[256];
 
254
    int hostid;                 // zero if first RPC
 
255
    int core_client_major_version;
 
256
    int core_client_minor_version;
 
257
    int core_client_release;
 
258
    int core_client_version;    // 10000*major + 100*minor + release
 
259
    int rpc_seqno;
 
260
    double work_req_seconds;
 
261
                // in "normalized CPU seconds" (see work_req.php)
 
262
    double cpu_req_secs;
 
263
    double cpu_req_instances;
 
264
    double resource_share_fraction;
 
265
        // this project's fraction of total resource share
 
266
    double rrs_fraction;
 
267
        // ... of runnable resource share
 
268
    double prrs_fraction;
 
269
        // ... of potentially runnable resource share
 
270
    double cpu_estimated_delay;
 
271
        // currently queued jobs saturate the CPU for this long;
 
272
        // used for crude deadline check
 
273
    double duration_correction_factor;
 
274
    char global_prefs_xml[BLOB_SIZE];
 
275
    char working_global_prefs_xml[BLOB_SIZE];
 
276
    char code_sign_key[4096];
 
277
 
 
278
    std::vector<CLIENT_APP_VERSION> client_app_versions;
 
279
    GLOBAL_PREFS global_prefs;
 
280
    char global_prefs_source_email_hash[MD5_LEN];
 
281
 
 
282
    HOST host;      // request message is parsed into here.
 
283
                    // does NOT contain the full host record.
 
284
    COPROCS coprocs;
 
285
    std::vector<RESULT> results;
 
286
        // completed results being reported
 
287
    std::vector<MSG_FROM_HOST_DESC> msgs_from_host;
 
288
    std::vector<FILE_INFO> file_infos;
 
289
        // sticky files reported by host for locality scheduling
 
290
    std::vector<FILE_INFO> file_delete_candidates;
 
291
        // sticky files reported by host, deletion candidates
 
292
    std::vector<FILE_INFO> files_not_needed;
 
293
        // sticky files reported by host, no longer needed
 
294
    std::vector<OTHER_RESULT> other_results;
 
295
        // in-progress results from this project
 
296
    std::vector<IP_RESULT> ip_results;
 
297
        // in-progress results from all projects
 
298
    bool have_other_results_list;
 
299
    bool have_ip_results_list;
 
300
    bool have_time_stats_log;
 
301
    bool client_cap_plan_class;
 
302
    int sandbox;
 
303
        // whether client uses account-based sandbox.  -1 = don't know
 
304
    int allow_multiple_clients;
 
305
        // whether client allows multiple clients per host, -1 don't know
 
306
    bool using_weak_auth;
 
307
        // Request uses weak authenticator.
 
308
        // Don't modify user prefs or CPID
 
309
    int last_rpc_dayofyear;
 
310
    int current_rpc_dayofyear;
 
311
 
 
312
    SCHEDULER_REQUEST();
 
313
    ~SCHEDULER_REQUEST();
 
314
    const char* parse(FILE*);
 
315
    int write(FILE*); // write request info to file: not complete
 
316
};
 
317
 
 
318
// keep track of bottleneck disk preference
 
319
//
 
320
struct DISK_LIMITS {
 
321
    double max_used;
 
322
    double max_frac;
 
323
    double min_free;
 
324
};
 
325
 
 
326
// summary of a client's request for work, and our response to it
 
327
// Note: this is zeroed out in SCHEDULER_REPLY constructor
 
328
//
 
329
struct WORK_REQ {
 
330
    bool anonymous_platform;
 
331
 
 
332
    // Flags used by old-style scheduling,
 
333
    // while making multiple passes through the work array
 
334
    bool infeasible_only;
 
335
    bool reliable_only;
 
336
    bool user_apps_only;
 
337
    bool beta_only;
 
338
 
 
339
    bool resend_lost_results;
 
340
        // this is set if the request is reporting a result
 
341
        // that was previously reported.
 
342
        // This is evidence that the earlier reply was not received
 
343
        // by the client.  It may have contained results,
 
344
        // so check and resend just in case.
 
345
 
 
346
    // user preferences
 
347
    bool no_cuda;
 
348
    bool no_ati;
 
349
    bool no_cpu;
 
350
        bool allow_non_preferred_apps;
 
351
        bool allow_beta_work;
 
352
        std::vector<APP_INFO> preferred_apps;
 
353
 
 
354
    bool has_reliable_version;
 
355
        // whether the host has a reliable app version
 
356
 
 
357
    int effective_ncpus;
 
358
    int effective_ngpus;
 
359
 
 
360
    // 6.7+ clients send separate requests for different resource types:
 
361
    //
 
362
    double cpu_req_secs;        // instance-seconds requested
 
363
    double cpu_req_instances;   // number of idle instances, use if possible
 
364
    double cuda_req_secs;
 
365
    double cuda_req_instances;
 
366
    double ati_req_secs;
 
367
    double ati_req_instances;
 
368
    inline bool need_cpu() {
 
369
        return (cpu_req_secs>0) || (cpu_req_instances>0);
 
370
    }
 
371
    inline bool need_cuda() {
 
372
        return (cuda_req_secs>0) || (cuda_req_instances>0);
 
373
    }
 
374
    inline bool need_ati() {
 
375
        return (ati_req_secs>0) || (ati_req_instances>0);
 
376
    }
 
377
    inline void clear_cpu_req() {
 
378
        cpu_req_secs = 0;
 
379
        cpu_req_instances = 0;
 
380
    }
 
381
    inline void clear_gpu_req() {
 
382
        cuda_req_secs = 0;
 
383
        cuda_req_instances = 0;
 
384
        ati_req_secs = 0;
 
385
        ati_req_instances = 0;
 
386
    }
 
387
 
 
388
    // older clients send send a single number, the requested duration of jobs
 
389
    //
 
390
    double seconds_to_fill;
 
391
 
 
392
    // true if new-type request, which has resource-specific requests
 
393
    //
 
394
    bool rsc_spec_request;
 
395
 
 
396
    double disk_available;
 
397
    double ram, usable_ram;
 
398
    double running_frac;
 
399
    int njobs_sent;
 
400
 
 
401
    // The following keep track of the "easiest" job that was rejected
 
402
    // by EDF simulation.
 
403
    // Any jobs harder than this can be rejected without doing the simulation.
 
404
    //
 
405
    double edf_reject_min_cpu;
 
406
    int edf_reject_max_delay_bound;
 
407
    bool have_edf_reject;
 
408
    void edf_reject(double cpu, int delay_bound) {
 
409
        if (have_edf_reject) {
 
410
            if (cpu < edf_reject_min_cpu) edf_reject_min_cpu = cpu;
 
411
            if (delay_bound> edf_reject_max_delay_bound) edf_reject_max_delay_bound = delay_bound;
 
412
        } else {
 
413
            edf_reject_min_cpu = cpu;
 
414
            edf_reject_max_delay_bound = delay_bound;
 
415
            have_edf_reject = true;
 
416
        }
 
417
    }
 
418
    bool edf_reject_test(double cpu, int delay_bound) {
 
419
        if (!have_edf_reject) return false;
 
420
        if (cpu < edf_reject_min_cpu) return false;
 
421
        if (delay_bound > edf_reject_max_delay_bound) return false;
 
422
        return true;
 
423
    }
 
424
 
 
425
    RESOURCE disk;
 
426
    RESOURCE mem;
 
427
    RESOURCE speed;
 
428
    RESOURCE bandwidth;
 
429
 
 
430
    std::vector<USER_MESSAGE> no_work_messages;
 
431
    std::vector<BEST_APP_VERSION*> best_app_versions;
 
432
    std::vector<BEST_APP_VERSION*> all_best_app_versions;
 
433
    std::vector<DB_HOST_APP_VERSION> host_app_versions;
 
434
    std::vector<DB_HOST_APP_VERSION> host_app_versions_orig;
 
435
 
 
436
    // various reasons for not sending jobs (used to explain why)
 
437
    //
 
438
    bool no_allowed_apps_available;
 
439
    bool hr_reject_temp;
 
440
    bool hr_reject_perm;
 
441
    bool outdated_client;
 
442
    bool no_cuda_prefs;
 
443
    bool no_ati_prefs;
 
444
    bool no_cpu_prefs;
 
445
    bool max_jobs_on_host_exceeded;
 
446
    bool max_jobs_on_host_cpu_exceeded;
 
447
    bool max_jobs_on_host_gpu_exceeded;
 
448
    bool no_jobs_available;     // project has no work right now
 
449
    int max_jobs_per_rpc;
 
450
    void update_for_result(double seconds_filled);
 
451
    void add_no_work_message(const char*);
 
452
    void get_job_limits();
 
453
 
 
454
    ~WORK_REQ() {
 
455
        for (unsigned int i=0; i<all_best_app_versions.size(); i++) {
 
456
            delete all_best_app_versions[i];
 
457
        }
 
458
    }
 
459
};
 
460
 
 
461
// NOTE: if any field requires initialization,
 
462
// you must do it in the constructor.  Nothing is zeroed by default.
 
463
//
 
464
struct SCHEDULER_REPLY {
 
465
    WORK_REQ wreq;
 
466
    DISK_LIMITS disk_limits;
 
467
    double request_delay;       // don't request again until this time elapses
 
468
    std::vector<USER_MESSAGE> messages;
 
469
    int hostid;
 
470
        // nonzero only if a new host record was created.
 
471
        // this tells client to reset rpc_seqno
 
472
    int lockfile_fd; // file descriptor of lockfile, or -1 if no lock.
 
473
    bool send_global_prefs;
 
474
    bool nucleus_only;          // send only message
 
475
    USER user;
 
476
    char email_hash[MD5_LEN];
 
477
    HOST host;                  // after validation, contains full host rec
 
478
    TEAM team;
 
479
    std::vector<APP> apps;
 
480
    std::vector<APP_VERSION> app_versions;
 
481
    std::vector<WORKUNIT>wus;
 
482
    std::vector<RESULT>results;
 
483
    std::vector<std::string>result_acks;
 
484
    std::vector<std::string>result_aborts;
 
485
    std::vector<std::string>result_abort_if_not_starteds;
 
486
    std::vector<MSG_TO_HOST>msgs_to_host;
 
487
    std::vector<FILE_INFO>file_deletes;
 
488
    char code_sign_key[4096];
 
489
    char code_sign_key_signature[4096];
 
490
    bool send_msg_ack;
 
491
    bool project_is_down;
 
492
 
 
493
    SCHEDULER_REPLY();
 
494
    ~SCHEDULER_REPLY();
 
495
    int write(FILE*, SCHEDULER_REQUEST&);
 
496
    void insert_app_unique(APP&);
 
497
    void insert_app_version_unique(APP_VERSION&);
 
498
    void insert_workunit_unique(WORKUNIT&);
 
499
    void insert_result(RESULT&);
 
500
    void insert_message(const char* msg, const char* prio);
 
501
    void insert_message(USER_MESSAGE&);
 
502
    void set_delay(double);
 
503
};
 
504
 
 
505
extern SCHEDULER_REQUEST* g_request;
 
506
extern SCHEDULER_REPLY* g_reply;
 
507
extern WORK_REQ* g_wreq;
 
508
 
 
509
static inline void add_no_work_message(const char* m) {
 
510
    g_wreq->add_no_work_message(m);
 
511
}
 
512
 
 
513
extern void get_weak_auth(USER&, char*);
 
514
extern void get_rss_auth(USER&, char*);
 
515
extern void read_host_app_versions();
 
516
extern DB_HOST_APP_VERSION* get_host_app_version(int gavid);
 
517
extern void write_host_app_versions();
 
518
 
 
519
extern DB_HOST_APP_VERSION* gavid_to_havp(int gavid);
 
520
extern DB_HOST_APP_VERSION* quota_exceeded_version();
 
521
 
 
522
#endif