// This file is part of BOINC.
// http://boinc.berkeley.edu
// Copyright (C) 2008 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 .
// If you change anything, make sure you also change:
// client_types.C (to write and parse it)
// client_state.C (to cross-link objects)
//
#ifndef _CLIENT_TYPES_
#define _CLIENT_TYPES_
#include "cpp.h"
#if !defined(_WIN32) || defined(__CYGWIN32__)
#include
#include
#endif
#include "md5_file.h"
#include "cert_sig.h"
#include "hostinfo.h"
#include "coproc.h"
#include "miofile.h"
#include "common_defs.h"
#include "cc_config.h"
#include "rr_sim.h"
#include "work_fetch.h"
#include "cs_notice.h"
#ifdef SIM
#include "sim.h"
#endif
#define MAX_FILE_INFO_LEN 4096
#define MAX_SIGNATURE_LEN 4096
#define MAX_KEY_LEN 4096
#define MAX_COPROCS_PER_JOB 8
// max # of instances of a GPU that a job can use
extern int rsc_index(const char*);
extern const char* rsc_name(int);
extern COPROCS coprocs;
struct FILE_INFO;
// represents a list of URLs (e.g. to download a file)
// and a current position in that list
//
struct URL_LIST {
std::vector urls;
int start_index;
int current_index;
URL_LIST(){};
void clear() {
urls.clear();
start_index = -1;
current_index = -1;
}
bool empty() {return urls.empty();}
const char* get_init_url();
const char* get_next_url();
const char* get_current_url(FILE_INFO&);
inline void add(std::string url) {
urls.push_back(url);
}
void replace(URL_LIST& ul) {
clear();
for (unsigned int i=0; i proj_feeds;
inline char *get_project_name() {
if (strlen(project_name)) {
return project_name;
} else {
return master_url;
}
}
};
struct PROJECT : PROJ_AM {
// the following items come from the account file
// They are a function only of the user and the project
//
char authenticator[256];
// user's authenticator on this project
std::string project_prefs;
// without the enclosing tags.
// May include elements
// This field is used only briefly: between handling a
// scheduler RPC reply and writing the account file
std::string project_specific_prefs;
// without enclosing tags
// Does not include elements
std::string gui_urls;
// GUI URLs, with enclosing tags
double resource_share;
// project's resource share relative to other projects.
double resource_share_frac;
// fraction of RS of non-suspended, compute-intensive projects
// the following are from the user's project prefs
//
bool no_rsc_pref[MAX_RSC];
// derived from GPU exclusions in cc_config.xml;
// disable work fetch if all instances excluded
//
bool no_rsc_config[MAX_RSC];
// the following are from the project itself
// (or derived from app version list if anonymous platform)
//
bool no_rsc_apps[MAX_RSC];
// the following are from the account manager, if any
//
bool no_rsc_ams[MAX_RSC];
// the following set dynamically
//
bool rsc_defer_sched[MAX_RSC];
// This project has a GPU job for which there's insuff. video RAM.
// Don't fetch more jobs of this type; they might have same problem
char host_venue[256];
// logically, this belongs in the client state file
// rather than the account file.
// But we need it in the latter in order to parse prefs.
bool using_venue_specific_prefs;
// the following items come from client_state.xml
// They may depend on the host as well as user and project
// NOTE: if you add anything, add it to copy_state_fields() also!!!
//
std::vector scheduler_urls;
// where to find scheduling servers
char symstore[256];
// URL of symbol server (Windows)
char user_name[256];
char team_name[256];
char email_hash[MD5_LEN];
char cross_project_id[MD5_LEN];
double cpid_time;
double user_total_credit;
double user_expavg_credit;
double user_create_time;
int userid;
int teamid;
int hostid;
double host_total_credit;
double host_expavg_credit;
double host_create_time;
double ams_resource_share;
// resource share according to AMS; overrides project
// -1 means not specified by AMS
// stuff related to scheduler RPCs and master fetch
//
int rpc_seqno;
int nrpc_failures;
// # of consecutive times we've failed to contact all scheduling servers
int master_fetch_failures;
double min_rpc_time;
// earliest time to contact any server of this project (or zero)
void set_min_rpc_time(double future_time, const char* reason);
double next_rpc_time;
// if nonzero, specifies a time when another scheduler RPC
// should be done (as requested by server).
// An RPC could be done sooner than this.
bool waiting_until_min_rpc_time();
// returns true if min_rpc_time > now
bool master_url_fetch_pending;
// need to fetch and parse the master URL
int sched_rpc_pending;
// we need to do a scheduler RPC, for various possible reasons:
// user request, propagate host CPID, time-based, etc.
// Reasons are enumerated in scheduler_op.h
bool possibly_backed_off;
// we need to call request_work_fetch() when a project
// transitions from being backed off to not.
// This (slightly misnamed) keeps track of whether this
// may still need to be done for given project
bool trickle_up_pending;
// have trickle up to send
double last_rpc_time;
// when last RPC finished
// Other stuff
bool anonymous_platform;
// app_versions.xml file found in project dir;
// use those apps rather then getting from server
bool non_cpu_intensive;
// All this project's apps are non-CPU-intensive.
// Apps can also be individually marked as NCI
bool verify_files_on_app_start;
// Check app version and input files on app startup,
// to make sure they haven't been tampered with.
// This provides only the illusion of security.
bool use_symlinks;
// items send in scheduler replies, requesting that
// various things be sent in the next request
//
int send_time_stats_log;
// if nonzero, send time stats log from that point on
int send_job_log;
// if nonzero, send this project's job log from that point on
bool send_full_workload;
bool suspended_via_gui;
bool dont_request_more_work;
// Return work, but don't request more
// Used for a clean exit to a project,
// or if a user wants to pause doing work for the project
bool attached_via_acct_mgr;
bool detach_when_done;
// when no results for this project, detach it.
bool ended;
// project has ended; advise user to detach
char code_sign_key[MAX_KEY_LEN];
std::vector user_files;
std::vector project_files;
// files not specific to apps or work - e.g. icons
int parse_preferences_for_user_files();
int parse_project_files(XML_PARSER&, bool delete_existing_symlinks);
void write_project_files(MIOFILE&);
void link_project_files(bool recreate_symlink_files);
int write_symlink_for_project_file(FILE_INFO*);
double project_files_downloaded_time;
// when last project file download finished
void update_project_files_downloaded_time();
// called when a project file download finishes.
// If it's the last one, set project_files_downloaded_time to now
double duration_correction_factor;
// Multiply by this when estimating the CPU time of a result
// (based on FLOPs estimated and benchmarks).
// This is dynamically updated in a way that maintains an upper bound.
// it goes down slowly but if a new estimate X is larger,
// the factor is set to X.
//
// Deprecated - current server logic handles this,
// and this should go to 1.
// But we need to keep it around for older projects
void update_duration_correction_factor(ACTIVE_TASK*);
// fields used by CPU scheduler and work fetch
// everything from here on applies only to CPU intensive projects
bool can_request_work();
// not suspended and not deferred and not no more work
bool runnable(int rsc_type);
// has a runnable result using the given resource type
bool downloading();
// has a result in downloading state
bool potentially_runnable();
// runnable or contactable or downloading
bool nearly_runnable();
// runnable or downloading
bool overworked();
// the project has used too much CPU time recently
bool some_download_stalled();
// a download is backed off
bool some_result_suspended();
double last_upload_start;
// the last time an upload was started.
// Used for "work fetch deferral" mechanism:
// don't request work from a project if an upload started
// in last X minutes and is still active
bool uploading();
RR_SIM_PROJECT_STATUS rr_sim_status;
// temps used in CLIENT_STATE::rr_simulation();
struct RESULT *next_runnable_result;
// the next result to run for this project
int nuploading_results;
// number of results in UPLOADING state
// Don't start new results if these exceeds 2*ncpus.
bool too_many_uploading_results;
// stuff for RR sim
//
double rr_sim_cpu_share;
bool rr_sim_active;
// stuff related to work fetch
//
RSC_PROJECT_WORK_FETCH rsc_pwf[MAX_RSC];
PROJECT_WORK_FETCH pwf;
inline void reset() {
for (int i=0; i statistics;
int parse_statistics(MIOFILE&);
int parse_statistics(FILE*);
int write_statistics(MIOFILE&, bool gui_rpc=false);
int write_statistics_file();
void suspend();
void resume();
void abort_not_started();
// abort unstarted jobs
// clear AMS-related fields
inline void detach_ams() {
attached_via_acct_mgr = false;
ams_resource_share = -1;
for (int i=0; i app_files;
int ref_cnt;
char graphics_exec_path[512];
char graphics_exec_file[256];
double max_working_set_size;
// max working set of tasks using this app version.
// unstarted jobs using this app version are assumed
// to use this much RAM,
// so that we don't run a long sequence of jobs,
// each of which turns out not to fit in available RAM
bool missing_coproc;
double missing_coproc_usage;
char missing_coproc_name[256];
bool dont_throttle;
int index; // temp var for make_scheduler_request()
#ifdef SIM
bool dont_use;
#endif
APP_VERSION(){}
~APP_VERSION(){}
int parse(XML_PARSER&);
int write(MIOFILE&, bool write_file_info = true);
bool had_download_failure(int& failnum);
void get_file_errors(std::string&);
void clear_errors();
int api_major_version();
inline bool uses_coproc(int rt) {
return (gpu_usage.rsc_type == rt);
}
inline int rsc_type() {
return gpu_usage.rsc_type;
}
};
struct WORKUNIT {
char name[256];
char app_name[256];
int version_num;
// Deprecated, but need to keep around to let people revert
// to versions before multi-platform support
std::string command_line;
std::vector input_files;
PROJECT* project;
APP* app;
int ref_cnt;
double rsc_fpops_est;
double rsc_fpops_bound;
double rsc_memory_bound;
double rsc_disk_bound;
WORKUNIT(){}
~WORKUNIT(){}
int parse(XML_PARSER&);
int write(MIOFILE&);
bool had_download_failure(int& failnum);
void get_file_errors(std::string&);
void clear_errors();
};
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 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;
#ifdef SIM
double peak_flop_count;
#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; }
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:
// x
// x
// x
// - if called in FILES_DOWNLOADED state:
// x
// - if called in NEW state:
// x for each failed download
// - if called in COMPUTE_DONE state:
// x for each failed upload
//
// - X, 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;
APP* app;
WORKUNIT* wup;
PROJECT* project;
RESULT(){}
~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 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
double estimated_duration();
double estimated_duration_uncorrected();
double estimated_time_remaining();
inline double estimated_flops_remaining() {
return estimated_time_remaining()*avp->flops;
}
inline bool computing_done() {
if (state() >= RESULT_COMPUTE_ERROR) return true;
if (ready_to_report) return true;
return false;
}
bool not_started();
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 int resource_type() {
return avp->gpu_usage.rsc_type;
}
inline bool non_cpu_intensive() {
if (project->non_cpu_intensive) return true;
if (app->non_cpu_intensive) return true;
return false;
}
inline bool dont_throttle() {
if (non_cpu_intensive()) return true;
if (avp->dont_throttle) return true;
return false;
}
// temporaries used in CLIENT_STATE::rr_simulation():
double rrsim_flops_left;
double rrsim_finish_delay;
double rrsim_flops;
bool already_selected;
// used to keep cpu scheduler from scheduling a result twice
// transient; used only within schedule_cpus()
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
// (wait for free GPU RAM)
};
// represents an always/auto/never value, possibly temporarily overridden
struct RUN_MODE {
int perm_mode;
int temp_mode;
double temp_timeout;
RUN_MODE();
void set(int mode, double duration);
int get_perm();
int get_current();
double delay();
};
// a platform supported by the client.
class PLATFORM {
public:
std::string name;
};
#endif