diff --git a/checkin_notes b/checkin_notes index 47f9de599d..0a664840c8 100755 --- a/checkin_notes +++ b/checkin_notes @@ -1365,4 +1365,29 @@ Rom 30 Jan 2007 AdvancedFrame.cpp, .h BOINCBaseFrame.cpp, .h MainDocument.cpp, .h - \ No newline at end of file + +David 30 Jan 2007 + - Support projects that want to specify credit per WU can do so by: + 1) add a x element to your WU template, + or pass an 'additional_xml' argument containing + x to create_work() + (either the function or the program) + 2) change your validator so that compute_granted_credit() + calls get_credit_from_wu(). + This parses the element in the workunit's XML, + and grants that much credit. + - Change the simple validator framework so that an + additional WORKUNIT& is passed to compute_granted_credit(). + + sched/ + handle_request.C + sample_bitwise_validator.C + sample_trivial_validator.C + sched_config.C,h + transitioner.C + validate_util.C,h + validate_util2.C,h + validator_placeholder.C + tools/ + backend_lib.C,h + create_work.C diff --git a/doc/build_server.php b/doc/build_server.php deleted file mode 100644 index 93d0a1e011..0000000000 --- a/doc/build_server.php +++ /dev/null @@ -1,49 +0,0 @@ -Software Prerequisites. - -

Overview

-Download: -
-  wget http://boinc.berkeley.edu/source/boinc-VERSION.tar.gz
-  tar xvzf boinc-VERSION.tar.gz
-  cd boinc-VERSION
-
-Configure: -
-  ./configure
-
-Make: -
-  make
-
-Check: -
-  make check
-
- -

Troubleshooting

-

MySQL

-BOINC gets MySQL compiler and linker flags from a program -called mysql_config which comes with your MySQL distribution. -This sometimes references libraries that are not part of your base system -installation, such as -lnsl or -lnss_files. -You may need to install additional packages -(often you can use something called 'mysql-dev' or 'mysql-devel') -or fiddle with Makefiles. - -

MySQL transactions

-If you get messages such as this: -
-Database error: You have an error in your SQL syntax near 'START TRANSACTION' at line 1 query=START TRANSACTION
-
-then your MySQL server does not support transactions. Either upgrade to MySQL -4.x, or remove <use_transactions/> from config.xml - - -"; - page_tail(); -?> diff --git a/doc/tools_work.php b/doc/tools_work.php index 36b1a823e1..3f7fbf64b8 100644 --- a/doc/tools_work.php +++ b/doc/tools_work.php @@ -63,17 +63,28 @@ A workunit template file has the form [ x ] [ x ] [ x ] + [ X ] "), " The components are: "; list_start(); -list_item(htmlspecialchars(", "), -"Each pair describes an input file -and the way it's referenced."); -list_item(htmlspecialchars(""), -"The command-line arguments to be passed to the main program."); +list_item_func(", ", + "Each pair describes an input file + and the way it's referenced." +); +list_item_func("", + "The command-line arguments to be passed to the main program." +); +list_item_func("", + "The amount of credit to be granted for successful completion + of this workunit. + Use this only if you know in advance + how many FLOPs it will take. + Your validator must + use get_credit_from_wu() as its compute_granted_credit() function." +); list_item("Other elements", "Work unit attributes" ); @@ -192,11 +203,14 @@ create_work [ -max_error_results x ] [ -max_total_results x ] [ -max_success_results x ] + [ -additional_xml 'x' ] infile_1 ... infile_m // input files -The workunit parameters are documented here. The program must be run in the project root directory. +The workunit parameters are documented here. +The -additional_xml argument can be used to supply, for example, +<credit>12.4</credit>.

BOINC's library (backend_lib.C,h) provides the functions: @@ -209,7 +223,8 @@ int create_work( const char** infiles, // array of input file names int ninfiles SCHED_CONFIG&, - const char* command_line = NULL + const char* command_line = NULL, + const char* additional_xml = NULL );

diff --git a/sched/handle_request.C b/sched/handle_request.C index 313983aefe..73cd3bf60c 100644 --- a/sched/handle_request.C +++ b/sched/handle_request.C @@ -585,16 +585,16 @@ int handle_results(SCHEDULER_REQUEST& sreq, SCHEDULER_REPLY& reply) { int retval; RESULT* rp; bool changed_host=false; - + if (sreq.results.size() == 0) return 0; - + // copy reported results to a separate vector, "result_handler", // initially with only the "name" field present // for (i=0; iid = 0; reply.result_acks.push_back(std::string(rp->name)); continue; - } + } } if (srip->server_state == RESULT_SERVER_STATE_UNSENT) { @@ -833,19 +833,6 @@ int handle_results(SCHEDULER_REQUEST& sreq, SCHEDULER_REPLY& reply) { } } // loop over all incoming results - -#if 0 - if (config.use_transactions) { - retval = boinc_db.start_transaction(); - if (retval) { - log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, - "[HOST#%d] result_handler.start_transaction() == %d\n", - reply.host.id, retval - ); - } - } -#endif - // Update the result records // (skip items that we previously marked to skip) // @@ -874,19 +861,6 @@ int handle_results(SCHEDULER_REQUEST& sreq, SCHEDULER_REPLY& reply) { reply.host.id, retval ); } - -#if 0 - if (config.use_transactions) { - retval = boinc_db.commit_transaction(); - if (retval) { - log_messages.printf( - SCHED_MSG_LOG::MSG_CRITICAL, - "[HOST#%d] result_handler.commit_transaction() == %d\n", - reply.host.id, retval - ); - } - } -#endif return 0; } @@ -958,28 +932,26 @@ void warn_user_if_core_client_upgrade_scheduled( ) { int core_ver; - + core_ver = sreq.core_client_major_version*100; core_ver += sreq.core_client_minor_version; - + if (core_ver < config.min_core_client_version_announced) { // time remaining in hours, before upgrade required int remaining = config.min_core_client_upgrade_deadline-time(0); remaining /= 3600; - + if (0 < remaining) { - char msg[512]; int days = remaining / 24; int hours = remaining % 24; - sprintf(msg, "Starting in %d days and %d hours, project will require a minimum " "BOINC core client version of %d.%d.0. You are currently using " "version %d.%d.%d; please upgrade before this time.", days, hours, - config.min_core_client_version_announced / 100, + config.min_core_client_version_announced / 100, config.min_core_client_version_announced % 100, sreq.core_client_major_version, sreq.core_client_minor_version, @@ -1018,10 +990,10 @@ bool unacceptable_os( sreq.host.os_name, sreq.host.os_version ); - if (!strcmp(sreq.host.os_name, "Darwin") && - (!strncmp(sreq.host.os_version, "5.", 2) || + if (!strcmp(sreq.host.os_name, "Darwin") && + (!strncmp(sreq.host.os_version, "5.", 2) || !strncmp(sreq.host.os_version, "6.", 2) - ) + ) ) { log_messages.printf( SCHED_MSG_LOG::MSG_NORMAL, @@ -1040,7 +1012,7 @@ bool unacceptable_os( } #else bool unacceptable_os( - SCHEDULER_REQUEST& , SCHEDULER_REPLY& + SCHEDULER_REQUEST& , SCHEDULER_REPLY& ) { return false; } @@ -1277,7 +1249,7 @@ void process_request( reply.set_delay(DELAY_PLATFORM_UNSUPPORTED); goto leave; } - + handle_global_prefs(sreq, reply); handle_results(sreq, reply); @@ -1344,9 +1316,9 @@ void debug_sched( sprintf(tmpfilename, "sched_reply_%06d_%06d", sreq.hostid, sreq.rpc_seqno); // use _XXXXXX if you want random filenames rather than // deterministic mkstemp(tmpfilename); - + fp=fopen(tmpfilename, "w"); - + if (!fp) { log_messages.printf( SCHED_MSG_LOG::MSG_CRITICAL, @@ -1354,15 +1326,15 @@ void debug_sched( ); return; } - + log_messages.printf( SCHED_MSG_LOG::MSG_DEBUG, "Found %s, so writing %s\n", trigger, tmpfilename ); - + sreply.write(fp); fclose(fp); - + sprintf(tmpfilename, "sched_request_%06d_%06d", sreq.hostid, sreq.rpc_seqno); fp=fopen(tmpfilename, "w"); @@ -1411,7 +1383,7 @@ void handle_request( if (rm && !strcmp(rm, "GET")) { sreply.probable_user_browser=true; } - + log_messages.printf( SCHED_MSG_LOG::MSG_NORMAL, "Incomplete request received %sfrom IP %s, auth %s, platform %s, version %d.%d.%d\n", @@ -1420,7 +1392,7 @@ void handle_request( sreq.core_client_major_version, sreq.core_client_minor_version, sreq.core_client_release ); - + USER_MESSAGE um("Incomplete request received.", "low"); sreply.insert_message(um); sreply.nucleus_only = true; @@ -1443,15 +1415,15 @@ void handle_request( int i; for (i=0; i& results) { - return median_mean_credit(results); +double compute_granted_credit(WORKUNIT& wu, vector& results) { + return median_mean_credit(wu, results); } const char *BOINC_RCSID_7ab2b7189c = "$Id$"; diff --git a/sched/sample_trivial_validator.C b/sched/sample_trivial_validator.C index 4885d564fe..f8272b355c 100644 --- a/sched/sample_trivial_validator.C +++ b/sched/sample_trivial_validator.C @@ -44,8 +44,8 @@ int cleanup_result(RESULT const&, void*) { return 0; } -double compute_granted_credit(vector& results) { - return median_mean_credit(results); +double compute_granted_credit(WORKUNIT& wu, vector& results) { + return median_mean_credit(wu, results); } const char *BOINC_RCSID_f3a7a34795 = "$Id$"; diff --git a/sched/sched_config.C b/sched/sched_config.C index 5de57af475..b73878a8a8 100644 --- a/sched/sched_config.C +++ b/sched/sched_config.C @@ -87,7 +87,6 @@ int SCHED_CONFIG::parse(FILE* f) { else if (xp.parse_bool(tag, "ignore_upload_certificates", ignore_upload_certificates)) continue; else if (xp.parse_bool(tag, "dont_generate_upload_certificates", dont_generate_upload_certificates)) continue; else if (xp.parse_bool(tag, "ignore_delay_bound", ignore_delay_bound)) continue; - else if (xp.parse_bool(tag, "use_transactions", use_transactions)) continue; else if (xp.parse_int(tag, "min_sendwork_interval", min_sendwork_interval)) continue; else if (xp.parse_int(tag, "max_wus_to_send", max_wus_to_send)) continue; else if (xp.parse_int(tag, "daily_result_quota", daily_result_quota)) continue; diff --git a/sched/sched_config.h b/sched/sched_config.h index 69e6cde0b8..1caccecb45 100644 --- a/sched/sched_config.h +++ b/sched/sched_config.h @@ -51,7 +51,6 @@ public: bool ignore_upload_certificates; bool dont_generate_upload_certificates; bool ignore_delay_bound; - bool use_transactions; int daily_result_quota; // max results per host per day int uldl_dir_fanout; // fanout of ul/dl dirs; 0 if none int uldl_dir_levels; diff --git a/sched/transitioner.C b/sched/transitioner.C index 100e3a4078..bc00e38ce2 100644 --- a/sched/transitioner.C +++ b/sched/transitioner.C @@ -487,7 +487,7 @@ int handle_wu( int long_delay = (int)(1.5*wu_item.delay_bound); wu_item.transition_time = (long_delay > ten_days) ? long_delay : ten_days; wu_item.transition_time += time(0); - } + } for (i=0; i& paths) { // - if N==2, return min // - if N>2, toss out min and max, return average of rest // -double median_mean_credit(vector& results) { +double median_mean_credit(WORKUNIT& /*wu*/, vector& results) { int ilow=-1, ihigh=-1; double credit_low = 0, credit_high = 0; int nvalid = 0; @@ -149,6 +149,15 @@ double median_mean_credit(vector& results) { } } +double get_credit_from_wu(WORKUNIT& wu, vector&) { + double x; + if (parse_double(wu.xml_doc, "", x)) { + return x; + } + fprintf(stderr, "ERROR: missing from WU XML\n"); + exit(1); +} + // This function should be called from the validator whenever credit // is granted to a host. It's purpose is to track the average credit // per cpu time for that host. diff --git a/sched/validate_util.h b/sched/validate_util.h index 1cab2884c4..4b021b7901 100644 --- a/sched/validate_util.h +++ b/sched/validate_util.h @@ -27,7 +27,7 @@ extern int get_output_file_path(RESULT const& result, std::string& path); extern int get_output_file_paths(RESULT const& result, std::vector&); -extern double median_mean_credit(std::vector& results); +extern double median_mean_credit(WORKUNIT&, std::vector& results); extern int update_credit_per_cpu_sec( double credit, double cpu_time, double& credit_per_cpu_sec ); diff --git a/sched/validate_util2.C b/sched/validate_util2.C index 0d2939d100..68c09f2f96 100644 --- a/sched/validate_util2.C +++ b/sched/validate_util2.C @@ -125,7 +125,7 @@ int check_set( } } canonicalid = results[i].id; - credit = compute_granted_credit(results); + credit = compute_granted_credit(wu, results); break; } } diff --git a/sched/validate_util2.h b/sched/validate_util2.h index 0eb55afb36..a91aede330 100644 --- a/sched/validate_util2.h +++ b/sched/validate_util2.h @@ -6,6 +6,6 @@ extern int init_result(RESULT const&, void*&); extern int compare_results(RESULT &, void*, RESULT const&, void*, bool&); extern int cleanup_result(RESULT const&, void*); -extern double compute_granted_credit(std::vector& results); +extern double compute_granted_credit(WORKUNIT&, std::vector& results); #endif diff --git a/sched/validator_placeholder.C b/sched/validator_placeholder.C index 010e762342..2caac688f4 100644 --- a/sched/validator_placeholder.C +++ b/sched/validator_placeholder.C @@ -100,8 +100,8 @@ int cleanup_result(RESULT const& /*result*/, void* data) { return 0; } -double compute_granted_credit(vector& results) { - return median_mean_credit(results); +double compute_granted_credit(WORKUNIT& wu, vector& results) { + return median_mean_credit(wu, results); } const char *BOINC_RCSID_7ab2b7189c = "$Id$"; diff --git a/tools/backend_lib.C b/tools/backend_lib.C index a7934bb700..c5c26cb570 100644 --- a/tools/backend_lib.C +++ b/tools/backend_lib.C @@ -166,7 +166,8 @@ static int process_wu_template( const char** infiles, int ninfiles, SCHED_CONFIG& config, - const char* command_line + const char* command_line, + const char* additional_xml ) { char* p; char buf[LARGE_BLOB_SIZE], md5[33], path[256], url[256], top_download_path[256]; @@ -269,6 +270,10 @@ static int process_wu_template( out += "\n\n"; } } else if (match_tag(p, "")) { + if (additional_xml && strlen(additional_xml)) { + out += additional_xml; + out += "\n"; + } out += "\n"; } else if (match_tag(p, "")) { out += "\n"; @@ -486,7 +491,8 @@ int create_work( const char** infiles, int ninfiles, SCHED_CONFIG& config, - const char* command_line + const char* command_line, + const char* additional_xml ) { int retval; char _result_template[LARGE_BLOB_SIZE]; @@ -503,7 +509,7 @@ int create_work( strcpy(wu_template, _wu_template); wu.create_time = time(0); retval = process_wu_template( - wu, wu_template, infiles, ninfiles, config, command_line + wu, wu_template, infiles, ninfiles, config, command_line, additional_xml ); if (retval) { fprintf(stderr, "process_wu_template: %d\n", retval); diff --git a/tools/backend_lib.h b/tools/backend_lib.h index eb40d64a9e..34ad2c191f 100644 --- a/tools/backend_lib.h +++ b/tools/backend_lib.h @@ -56,7 +56,8 @@ extern int create_work( const char** infiles, int ninfiles, SCHED_CONFIG&, - const char* command_line = NULL + const char* command_line = NULL, + const char* additional_xml = NULL ); #endif diff --git a/tools/create_work.C b/tools/create_work.C index 1ff6511eb4..502acce943 100644 --- a/tools/create_work.C +++ b/tools/create_work.C @@ -41,6 +41,7 @@ // [ -max_error_results x ] // [ -max_total_results x ] // [ -max_success_results x ] +// [ -additional_xml x ] // infile1 infile2 ... // @@ -64,13 +65,16 @@ int main(int argc, const char** argv) { char* command_line=NULL; const char** infiles = NULL; int i, ninfiles; - char download_dir[256], db_name[256], db_passwd[256],db_user[256],db_host[256]; + char download_dir[256], db_name[256], db_passwd[256]; + char db_user[256],db_host[256]; char buf[256]; + char additional_xml[256]; SCHED_CONFIG config; strcpy(result_template_file, ""); strcpy(app.name, ""); strcpy(db_passwd, ""); + strcpy(additional_xml, ""); const char* config_dir = "."; i = 1; ninfiles = 0; @@ -128,6 +132,8 @@ int main(int argc, const char** argv) { wu.max_success_results = atoi(argv[++i]); } else if (!strcmp(argv[i], "-command_line")) { command_line= (char *)argv[++i]; + } else if (!strcmp(argv[i], "-additional_xml")) { + strcpy(additional_xml, argv[++i]); } else { if (!strncmp("-",argv[i],1)) { fprintf(stderr, "create_work: bad argument '%s'\n", argv[i]); @@ -192,7 +198,8 @@ int main(int argc, const char** argv) { const_cast(infiles), ninfiles, config, - command_line + command_line, + additional_xml ); if (retval) { fprintf(stderr, "create_work: %d\n", retval);