more GAHP code

This commit is contained in:
David Anderson 2013-01-02 12:31:14 -08:00 committed by Oliver Bock
parent 9209a887cc
commit 18d0f1f4d9
6 changed files with 362 additions and 3 deletions

View File

@ -7989,3 +7989,10 @@ David 29 Dec 2012
client/
gui_rpc_server_ops.cpp
David 29 Dec 2012
- Condor: initial checkin of BOINC GAHP framework
samples/condor/
boinc_gahp.cpp
Makefile

View File

@ -22,7 +22,6 @@
#else
#include "config.h"
#include <string>
#include <set>
#endif
#include "parse.h"
@ -38,7 +37,6 @@
using std::vector;
using std::string;
using std::set;
using std::deque;
NOTICES notices;

View File

@ -179,6 +179,14 @@ $earth = array(
$astro_phys_chem = array(
tra("Astronomy, Physics, and Chemistry"),
array(
array(
"Asteroids@home",
"http://asteroidsathome.net/boinc/",
"Charles University in Prague",
"Astrophysics",
"The aim of the project is to derive shapes and spin for a significant part of the asteroid population. As input data, we use any asteroid photometry that is available. The results are asteroid convex shape models with the direction of the spin axis and the rotation period.",
"asteroids_logo.jpg"
),
array(
"Constellation",
"http://aerospaceresearch.net/constellation/",
@ -471,7 +479,7 @@ $math = array(
"Chess960@home",
"http://www.chess960athome.org/alpha/",
tra("Chess-960.org"),
tra("Game-playing"),
tra("Game study"),
tra("This project studies Chess 960, a variant of orthodox chess. In classical chess the starting position of the game never changes. In Chess 960, just before the start of every game, the initial configuration of the chess pieces is determined randomly."),
"chess960athome.jpg"
),

4
samples/condor/Makefile Normal file
View File

@ -0,0 +1,4 @@
all: boinc_gahp
boinc_gahp: boinc_gahp.cpp
g++ -lpthread -o boinc_gahp boinc_gahp.cpp

View File

@ -0,0 +1,269 @@
// This file is part of BOINC.
// http://boinc.berkeley.edu
// Copyright (C) 2012 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/>.
// BOINC GAHP (Grid ASCII Helper Protocol) daemon
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <map>
#include <set>
#include <string>
#include <vector>
using std::map;
using std::pair;
using std::set;
using std::string;
using std::vector;
bool async_mode = true;
// represents a command.
// if out is NULL the command is in progress;
// otherwise it's the output
//
struct COMMAND {
char* in;
char* out;
};
typedef map<int, COMMAND*> COMMANDS;
COMMANDS commands;
struct INFILE {
char src_path[256];
char dst_path[256];
};
struct JOB {
char job_name[256];
vector<string> args;
vector<INFILE> infiles;
bool all_output_files;
vector<string> outfiles;
};
struct SUBMIT_REQ {
char batch_name[256];
char app_name[256];
vector<JOB> jobs;
};
void compute_md5(string& path) {
}
// Get a list of the input files used by the batch.
// Get their MD5s.
// See if they're already on the server.
// If not, upload them.
//
int process_input_files(SUBMIT_REQ& req) {
unsigned int i, j;
// get the set of source paths w/o dups
//
set<string> files;
for (i=0; i<req.jobs.size(); i++) {
JOB& job = req.jobs[i];
for (j=0; j<job.infiles.size(); j++) {
INFILE infile = job.infiles[j];
files.insert(infile.src_path);
}
}
// compute the MD5s of these files
//
map<string, string> md5s;
set<string>::iterator iter = files.begin();
while (iter != files.end()) {
string s = *iter;
compute_md5(s);
iter++;
}
}
int parse_boinc_submit(COMMAND& c, char* p, SUBMIT_REQ& req) {
strcpy(req.batch_name, strtok_r(NULL, " ", &p));
strcpy(req.app_name, strtok_r(NULL, " ", &p));
int njobs = atoi(strtok_r(NULL, " ", &p));
for (int i=0; i<njobs; i++) {
JOB job;
strcpy(job.job_name, strtok_r(NULL, " ", &p));
int nargs = atoi(strtok_r(NULL, " ", &p));
for (int j=0; j<nargs; j++) {
string arg = strtok_r(NULL, " ", &p);
job.args.push_back(arg);
}
int ninfiles = atoi(strtok_r(NULL, " ", &p));
for (int j=0; j<ninfiles; j++) {
INFILE infile;
strcpy(infile.src_path, strtok_r(NULL, " ", &p));
strcpy(infile.dst_path, strtok_r(NULL, " ", &p));
job.infiles.push_back(infile);
}
char* q = strtok_r(NULL, " ", &p);
if (!strcmp(q, "ALL")) {
job.all_output_files = true;
} else {
job.all_output_files = false;
int noutfiles = atoi(q);
for (int j=0; j<noutfiles; j++) {
string outfile = strtok_r(NULL, " ", &p);
job.outfiles.push_back(outfile);
}
}
req.jobs.push_back(job);
}
return 0;
}
int submit_jobs(SUBMIT_REQ req) {
return 0;
}
void handle_boinc_submit(COMMAND& c, char* p) {
SUBMIT_REQ req;
int retval;
retval = parse_boinc_submit(c, p, req);
process_input_files(req);
submit_jobs(req);
}
void* handle_command_aux(void* q) {
COMMAND &c = *((COMMAND*)q);
char *p;
strtok_r(c.in, " ", &p);
char* cmd = strtok_r(NULL, " ", &p);
char* id = strtok_r(NULL, " ", &p);
if (!strcmp(cmd, "BOINC_SUBMIT")) {
handle_boinc_submit(c, p);
} else {
sleep(10);
char buf[256];
sprintf(buf, "handled command %s", c.in);
c.out = strdup(buf);
}
return NULL;
}
int handle_command(COMMAND& c) {
char cmd[256];
int id;
// Handle synchronous commands
//
sscanf(c.in, "%s", cmd);
if (!strcmp(cmd, "VERSION")) {
printf("1.0\n");
} else if (!strcmp(cmd, "QUIT")) {
exit(0);
} else if (!strcmp(cmd, "RESULTS")) {
sscanf(c.in, "%s %d", cmd, &id);
COMMANDS::iterator i = commands.find(id);
if (i == commands.end()) {
printf("command %d not found\n", id);
return 0;
}
COMMAND *c2 = i->second;
if (c2->out) {
printf("command %d result: %s\n", id, c2->out);
free(c2->out);
free(c2->in);
free(c2);
commands.erase(i);
} else {
printf("command %d not finished\n", id);
}
return 0;
} else {
// Handle asynchronous commands
//
int n = sscanf(c.in, "%s %d", cmd, &id);
if (n != 2) {
fprintf(stderr, "invalid command: %s\n", c.in);
return -1;
}
COMMAND *cp = new COMMAND;
cp->in = c.in;
cp->out = NULL;
printf("inserting cmd %d\n", id);
commands.insert(pair<int, COMMAND*>(id, cp));
if (async_mode) {
pthread_t thread_handle;
pthread_attr_t thread_attrs;
pthread_attr_init(&thread_attrs);
pthread_attr_setstacksize(&thread_attrs, 32768);
int retval = pthread_create(
&thread_handle, &thread_attrs, &handle_command_aux, cp
);
if (retval) {
fprintf(stderr, "can't create thread\n");
return -1;
}
} else {
handle_command_aux(cp);
}
}
return 0;
}
// read a line from stdin (possibly very long).
// Return it in a malloc'd buffer
//
char* get_cmd() {
static const int buf_inc = 16384;
char* p = (char*)malloc(buf_inc);
if (!p) return NULL;
int len = 0;
int buf_size = buf_inc;
while (1) {
char c = fgetc(stdin);
if (c == EOF) {
return NULL;
}
if (c == '\n') {
p[len] = 0;
return p;
}
p[len++] = c;
if (len == buf_size) {
p = (char*)realloc(p, len+buf_inc);
buf_size += buf_inc;
}
}
}
int main() {
char* p;
int retval;
while (1) {
p = get_cmd();
if (p == NULL) break;
COMMAND c;
c.in = p;
retval = handle_command(c);
if (retval) break;
}
}

73
samples/condor/curl.cpp Normal file
View File

@ -0,0 +1,73 @@
// This file is part of BOINC.
// http://boinc.berkeley.edu
// Copyright (C) 2012 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/>.
#include <curl/curl.h>
#include <stdio.h>
int do_http_post(const char* url) {
CURL *curl;
CURLcode res;
struct curl_httppost *formpost=NULL;
struct curl_httppost *lastptr=NULL;
struct curl_slist *headerlist=NULL;
curl = curl_easy_init();
if (!curl) {
return -1;
}
curl_formadd(&formpost, &lastptr,
CURLFORM_COPYNAME, "sendfile",
CURLFORM_FILE, "curl.cpp",
CURLFORM_END
);
curl_formadd(&formpost, &lastptr,
CURLFORM_COPYNAME, "filename",
CURLFORM_COPYCONTENTS, "curl.cpp",
CURLFORM_END
);
curl_formadd(&formpost, &lastptr,
CURLFORM_COPYNAME, "sendfile2",
CURLFORM_FILE, "boinc_gahp.cpp",
CURLFORM_END
);
curl_formadd(&formpost, &lastptr,
CURLFORM_COPYNAME, "filename2",
CURLFORM_COPYCONTENTS, "boinc_gahp.cpp",
CURLFORM_END
);
headerlist = curl_slist_append(headerlist, "Expect:");
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_USERAGENT, "BOINC Condor adapter");
curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
res = curl_easy_perform(curl);
if (res != CURLE_OK) {
fprintf(stderr, "CURL error: %s\n", curl_easy_strerror(res));
}
curl_easy_cleanup(curl);
curl_formfree(formpost);
curl_slist_free_all(headerlist);
return 0;
}
int main() {
do_http_post("http://isaac.ssl.berkeley.edu/foobar.php");
}