From a2f6b62d972a969412cd71139515adcea387db8b Mon Sep 17 00:00:00 2001 From: David Anderson Date: Thu, 15 Sep 2011 04:24:40 +0000 Subject: [PATCH] - lib: parse in coproc XML - lib: do coproc XML parsing using new XML parser svn path=/trunk/boinc/; revision=24215 --- checkin_notes | 8 ++ lib/coproc.cpp | 220 ++++++++++++++++++++++++++----------------------- lib/coproc.h | 3 +- lib/parse.cpp | 74 ++++++++++++++++- lib/parse.h | 29 +++++-- 5 files changed, 219 insertions(+), 115 deletions(-) diff --git a/checkin_notes b/checkin_notes index dd6ccd8e8f..4c7b0da72d 100644 --- a/checkin_notes +++ b/checkin_notes @@ -6065,3 +6065,11 @@ David 14 Sept 2011 lib/ coproc.cpp + +David 14 Sept 2011 + - lib: parse in coproc XML + - lib: do coproc XML parsing using new XML parser + + lib/ + parse.cpp,h + coproc.cpp,h diff --git a/lib/coproc.cpp b/lib/coproc.cpp index b4043c34f4..2d2b6f3380 100644 --- a/lib/coproc.cpp +++ b/lib/coproc.cpp @@ -56,17 +56,15 @@ using std::perror; #endif int COPROC_REQ::parse(XML_PARSER& xp) { - char buf[1024]; strcpy(type, ""); count = 0; - MIOFILE& in = *(xp.f); - while (in.fgets(buf, sizeof(buf))) { - if (match_tag(buf, "")) { + while (!xp.get_tag()) { + if (xp.match_tag("/coproc")) { if (!strlen(type)) return ERR_XML_PARSE; return 0; } - if (parse_str(buf, "", type, sizeof(type))) continue; - if (parse_double(buf, "", count)) continue; + if (xp.parse_str("type", type, sizeof(type))) continue; + if (xp.parse_double("count", count)) continue; } return ERR_XML_PARSE; } @@ -167,57 +165,79 @@ int COPROC::parse(XML_PARSER& xp) { #endif int COPROC::parse_opencl(XML_PARSER& xp) { - char buf[1024]; int n; + unsigned long ul; + unsigned long long ull; - MIOFILE& in = *(xp.f); - while (in.fgets(buf, sizeof(buf))) { - if (match_tag(buf, "")) { + while (!xp.get_tag()) { + if (xp.match_tag("/coproc_opencl")) { return 0; } - if (parse_str(buf, "", opencl_prop.name, sizeof(opencl_prop.name))) continue; - if (parse_str(buf, "", opencl_prop.vendor, sizeof(opencl_prop.vendor))) continue; - if (parse_double(buf, "", peak_flops)) continue; - if (parse_int(buf, "", n)) { + if (xp.parse_str("name", opencl_prop.name, sizeof(opencl_prop.name))) continue; + if (xp.parse_str("vendor", opencl_prop.vendor, sizeof(opencl_prop.vendor))) continue; + if (xp.parse_double("peak_flops", peak_flops)) continue; + if (xp.parse_int("available", n)) { opencl_prop.available = n; continue; } - if (parse_cl_ulong(buf, "", opencl_prop.hp_fp_config)) continue; - if (parse_cl_ulong(buf, "", opencl_prop.sp_fp_config)) continue; - if (parse_cl_ulong(buf, "", opencl_prop.dp_fp_config)) continue; - if (parse_int(buf, "", n)) { + if (xp.parse_ulonglong("hp_fp_config", ull)) { + opencl_prop.hp_fp_config = ull; + continue; + } + if (xp.parse_ulonglong("sp_fp_config", ull)) { + opencl_prop.sp_fp_config = ull; + continue; + } + if (xp.parse_ulonglong("dp_fp_config", ull)) { + opencl_prop.dp_fp_config = ull; + continue; + } + if (xp.parse_int("little_endian", n)) { opencl_prop.little_endian = n; continue; } - if (parse_cl_ulong(buf, "", opencl_prop.exec_capab)) continue; - if (parse_str(buf, "", - opencl_prop.extensions, - sizeof(opencl_prop.extensions))) { + if (xp.parse_ulonglong("exec_capabilities", ull)) { + opencl_prop.exec_capab = ull; continue; } - if (parse_cl_ulong(buf, "", opencl_prop.global_RAM)) continue; - if (parse_cl_ulong(buf, "", opencl_prop.local_RAM)) continue; - if (parse_int(buf, "", n)) { + if (xp.parse_str("extensions", + opencl_prop.extensions, + sizeof(opencl_prop.extensions) + )) { + continue; + } + if (xp.parse_ulonglong("global_RAM", ull)) { + opencl_prop.global_RAM = ull; + continue; + } + if (xp.parse_ulonglong("local_RAM", ull)) { + opencl_prop.local_RAM = ull; + continue; + } + if (xp.parse_int("max_clock_freq", n)) { opencl_prop.max_clock_freq = n; continue; } - if (parse_int(buf, "", n)) { + if (xp.parse_int("max_cores", n)) { opencl_prop.max_cores = n; continue; } - if (parse_str(buf, "", - opencl_prop.openCL_platform_version, - sizeof(opencl_prop.openCL_platform_version))) { + if (xp.parse_str("openCL_platform_version", + opencl_prop.openCL_platform_version, + sizeof(opencl_prop.openCL_platform_version) + )) { continue; } - if (parse_str(buf, "", - opencl_prop.openCL_device_version, - sizeof(opencl_prop.openCL_device_version))) { + if (xp.parse_str("openCL_device_version", + opencl_prop.openCL_device_version, + sizeof(opencl_prop.openCL_device_version) + )) { continue; } - if (parse_str(buf, "", - opencl_prop.openCL_driver_version, - sizeof(opencl_prop.openCL_driver_version))) { + if (xp.parse_str("openCL_driver_version", + opencl_prop.openCL_driver_version, + sizeof(opencl_prop.openCL_driver_version) + )) { continue; } } @@ -314,13 +334,11 @@ void COPROC_NVIDIA::write_xml(MIOFILE& f, bool include_request) { " %s\n" " %f\n" " %d\n" - " %d\n" " %d\n", count, prop.name, available_ram, have_cuda ? 1 : 0, - have_cal ? 1 : 0, have_opencl ? 1 : 0 ); if (include_request) { @@ -405,40 +423,39 @@ void COPROC_NVIDIA::clear() { } int COPROC_NVIDIA::parse(XML_PARSER& xp) { - char buf[1024], buf2[256]; + char buf2[256]; int retval; clear(); - MIOFILE& in = *(xp.f); - while (in.fgets(buf, sizeof(buf))) { - if (strstr(buf, "")) { + while (!xp.get_tag()) { + if (xp.match_tag("/coproc_cuda")) { if (!peak_flops) { set_peak_flops(); } return 0; } - if (parse_int(buf, "", count)) continue; - if (parse_double(buf, "", peak_flops)) continue; - if (parse_bool(buf, "have_cuda", have_cuda)) continue; - if (parse_bool(buf, "have_cal", have_cal)) continue; - if (parse_bool(buf, "have_opencl", have_opencl)) continue; - if (parse_double(buf, "", req_secs)) continue; - if (parse_double(buf, "", req_instances)) continue; - if (parse_double(buf, "", estimated_delay)) continue; - if (parse_int(buf, "", cuda_version)) continue; - if (parse_int(buf, "", display_driver_version)) continue; - if (parse_str(buf, "", prop.name, sizeof(prop.name))) continue; - if (parse_int(buf, "", prop.deviceHandle)) continue; - if (parse_double(buf, "", prop.dtotalGlobalMem)) { + if (xp.parse_int("count", count)) continue; + if (xp.parse_double("peak_flops", peak_flops)) continue; + if (xp.parse_bool("have_cuda", have_cuda)) continue; + if (xp.parse_bool("have_opencl", have_opencl)) continue; + if (xp.parse_double("available_ram", available_ram)) continue; + if (xp.parse_double("req_secs", req_secs)) continue; + if (xp.parse_double("req_instances", req_instances)) continue; + if (xp.parse_double("estimated_delay", estimated_delay)) continue; + if (xp.parse_int("cudaVersion", cuda_version)) continue; + if (xp.parse_int("drvVersion", display_driver_version)) continue; + if (xp.parse_str("name", prop.name, sizeof(prop.name))) continue; + if (xp.parse_int("deviceHandle", prop.deviceHandle)) continue; + if (xp.parse_double("totalGlobalMem", prop.dtotalGlobalMem)) { prop.totalGlobalMem = (int)prop.dtotalGlobalMem; continue; } - if (parse_int(buf, "", (int&)prop.sharedMemPerBlock)) continue; - if (parse_int(buf, "", prop.regsPerBlock)) continue; - if (parse_int(buf, "", prop.warpSize)) continue; - if (parse_int(buf, "", (int&)prop.memPitch)) continue; - if (parse_int(buf, "", prop.maxThreadsPerBlock)) continue; - if (parse_str(buf, "", buf2, sizeof(buf2))) { + if (xp.parse_int("sharedMemPerBlock", (int&)prop.sharedMemPerBlock)) continue; + if (xp.parse_int("regsPerBlock", prop.regsPerBlock)) continue; + if (xp.parse_int("warpSize", prop.warpSize)) continue; + if (xp.parse_int("memPitch", (int&)prop.memPitch)) continue; + if (xp.parse_int("maxThreadsPerBlock", prop.maxThreadsPerBlock)) continue; + if (xp.parse_str("maxThreadsDim", buf2, sizeof(buf2))) { // can't use sscanf here (FCGI) // prop.maxThreadsDim[0] = atoi(buf2); @@ -454,7 +471,7 @@ int COPROC_NVIDIA::parse(XML_PARSER& xp) { } continue; } - if (parse_str(buf, "", buf2, sizeof(buf2))) { + if (xp.parse_str("maxGridSize", buf2, sizeof(buf2))) { prop.maxGridSize[0] = atoi(buf2); char* p = strchr(buf2, ' '); if (p) { @@ -468,14 +485,14 @@ int COPROC_NVIDIA::parse(XML_PARSER& xp) { } continue; } - if (parse_int(buf, "", prop.clockRate)) continue; - if (parse_int(buf, "", (int&)prop.totalConstMem)) continue; - if (parse_int(buf, "", prop.major)) continue; - if (parse_int(buf, "", prop.minor)) continue; - if (parse_int(buf, "", (int&)prop.textureAlignment)) continue; - if (parse_int(buf, "", prop.deviceOverlap)) continue; - if (parse_int(buf, "", prop.multiProcessorCount)) continue; - if (match_tag(buf, "")) { + if (xp.parse_int("clockRate", prop.clockRate)) continue; + if (xp.parse_int("totalConstMem", (int&)prop.totalConstMem)) continue; + if (xp.parse_int("major", prop.major)) continue; + if (xp.parse_int("minor", prop.minor)) continue; + if (xp.parse_int("textureAlignment", (int&)prop.textureAlignment)) continue; + if (xp.parse_int("deviceOverlap", prop.deviceOverlap)) continue; + if (xp.parse_int("multiProcessorCount", prop.multiProcessorCount)) continue; + if (xp.match_tag("coproc_opencl")) { retval = parse_opencl(xp); if (retval) return retval; continue; @@ -493,13 +510,11 @@ void COPROC_ATI::write_xml(MIOFILE& f, bool include_request) { " %d\n" " %s\n" " %f\n" - " %d\n" " %d\n" " %d\n", count, name, available_ram, - have_cuda ? 1 : 0, have_cal ? 1 : 0, have_opencl ? 1 : 0 ); @@ -570,15 +585,12 @@ void COPROC_ATI::clear() { } int COPROC_ATI::parse(XML_PARSER& xp) { - char buf[1024]; - int n; - int retval; + int n, retval; clear(); - MIOFILE& in = *(xp.f); - while (in.fgets(buf, sizeof(buf))) { - if (strstr(buf, "")) { + while (!xp.get_tag()) { + if (xp.match_tag("/coproc_ati")) { int major, minor, release; sscanf(version, "%d.%d.%d", &major, &minor, &release); version_num = major*1000000 + minor*1000 + release; @@ -588,76 +600,76 @@ int COPROC_ATI::parse(XML_PARSER& xp) { } return 0; } - if (parse_int(buf, "", count)) continue; - if (parse_double(buf, "", peak_flops)) continue; - if (parse_bool(buf, "have_cuda", have_cuda)) continue; - if (parse_bool(buf, "have_cal", have_cal)) continue; - if (parse_bool(buf, "have_opencl", have_opencl)) continue; - if (parse_double(buf, "", req_secs)) continue; - if (parse_double(buf, "", req_instances)) continue; - if (parse_double(buf, "", estimated_delay)) continue; - if (parse_str(buf, "", name, sizeof(name))) continue; - if (parse_str(buf, "", version, sizeof(version))) continue; - if (parse_bool(buf, "amdrt_detected", amdrt_detected)) continue; - if (parse_bool(buf, "atirt_detected", atirt_detected)) continue; + if (xp.parse_int("count", count)) continue; + if (xp.parse_double("peak_flops", peak_flops)) continue; + if (xp.parse_bool("have_cal", have_cal)) continue; + if (xp.parse_bool("have_opencl", have_opencl)) continue; + if (xp.parse_double("available_ram", available_ram)) continue; + if (xp.parse_double("req_secs", req_secs)) continue; + if (xp.parse_double("req_instances", req_instances)) continue; + if (xp.parse_double("estimated_delay", estimated_delay)) continue; + if (xp.parse_str("name", name, sizeof(name))) continue; + if (xp.parse_str("CALVersion", version, sizeof(version))) continue; + if (xp.parse_bool("amdrt_detected", amdrt_detected)) continue; + if (xp.parse_bool("atirt_detected", atirt_detected)) continue; - if (parse_int(buf, "", n)) { + if (xp.parse_int("target", n)) { attribs.target = (CALtarget)n; continue; } - if (parse_int(buf, "", n)) { + if (xp.parse_int("localRAM", n)) { attribs.localRAM = n; continue; } - if (parse_int(buf, "", n)) { + if (xp.parse_int("uncachedRemoteRAM", n)) { attribs.uncachedRemoteRAM = n; continue; } - if (parse_int(buf, "", n)) { + if (xp.parse_int("cachedRemoteRAM", n)) { attribs.cachedRemoteRAM = n; continue; } - if (parse_int(buf, "", n)) { + if (xp.parse_int("engineClock", n)) { attribs.engineClock = n; continue; } - if (parse_int(buf, "", n)) { + if (xp.parse_int("memoryClock", n)) { attribs.memoryClock = n; continue; } - if (parse_int(buf, "", n)) { + if (xp.parse_int("wavefrontSize", n)) { attribs.wavefrontSize = n; continue; } - if (parse_int(buf, "" , n)) { + if (xp.parse_int("numberOfSIMD" , n)) { attribs.numberOfSIMD = n; continue; } - if (parse_int(buf, "", n)) { + if (xp.parse_int("doublePrecision", n)) { attribs.doublePrecision = n?CAL_TRUE:CAL_FALSE; continue; } - if (parse_int(buf, "", n)) { + if (xp.parse_int("pitch_alignment", n)) { attribs.pitch_alignment = n; continue; } - if (parse_int(buf, "", n)) { + if (xp.parse_int("surface_alignment", n)) { attribs.surface_alignment = n; continue; } - if (parse_int(buf, "", n)) { + if (xp.parse_int("maxResource1DWidth", n)) { info.maxResource1DWidth = n; continue; } - if (parse_int(buf, "", n)) { + if (xp.parse_int("maxResource2DWidth", n)) { info.maxResource2DWidth = n; continue; } - if (parse_int(buf, "", n)) { + if (xp.parse_int("maxResource2DHeight", n)) { info.maxResource2DHeight = n; continue; } - if (match_tag(buf, "")) { + if (xp.match_tag("coproc_opencl")) { retval = parse_opencl(xp); if (retval) return retval; continue; diff --git a/lib/coproc.h b/lib/coproc.h index 3b625d8f02..269423dd6d 100644 --- a/lib/coproc.h +++ b/lib/coproc.h @@ -134,6 +134,7 @@ struct COPROC { bool have_cuda; // True if this GPU supports CUDA on this computer bool have_cal; // True if this GPU supports CAL on this computer bool have_opencl; // True if this GPU supports openCL on this computer + double available_ram; // the following are used in both client and server for work-fetch info // @@ -160,7 +161,6 @@ struct COPROC { int opencl_device_count; bool running_graphics_app[MAX_COPROC_INSTANCES]; // is this GPU running a graphics app (NVIDIA only) - double available_ram; double available_ram_temp[MAX_COPROC_INSTANCES]; // used during job scheduling @@ -185,6 +185,7 @@ struct COPROC { have_cuda = false; have_cal = false; have_opencl = false; + available_ram = -1; req_secs = 0; req_instances = 0; opencl_device_count = 0; diff --git a/lib/parse.cpp b/lib/parse.cpp index 8aefef7514..6e03ae0f54 100644 --- a/lib/parse.cpp +++ b/lib/parse.cpp @@ -752,7 +752,7 @@ bool XML_PARSER::parse_int(const char* start_tag, int& i) { } errno = 0; int val = strtol(buf, &end, 0); - if (errno == ERANGE) return false; + if (errno) return false; if (end != buf+strlen(buf)) return false; eof = get(tag, sizeof(tag), is_tag); @@ -785,7 +785,79 @@ bool XML_PARSER::parse_double(const char* start_tag, double& x) { return false; } } + errno = 0; double val = strtod(buf, &end); + if (errno) return false; + if (end != buf+strlen(buf)) return false; + + eof = get(tag, sizeof(tag), is_tag); + if (eof) return false; + if (!is_tag) return false; + if (strcmp(tag, end_tag)) return false; + x = val; + return true; +} + +// Same, for unsigned long +// +bool XML_PARSER::parse_ulong(const char* start_tag, unsigned long& x) { + char buf[256], *end; + bool eof; + char end_tag[256], tag[256]; + + if (strcmp(parsed_tag, start_tag)) return false; + + end_tag[0] = '/'; + strcpy(end_tag+1, start_tag); + + eof = get(buf, sizeof(buf), is_tag); + if (eof) return false; + if (is_tag) { + if (!strcmp(buf, end_tag)) { + x = 0; // treat as 0 + return true; + } else { + return false; + } + } + errno = 0; + unsigned long val = strtoul(buf, &end, 0); + if (errno) return false; + if (end != buf+strlen(buf)) return false; + + eof = get(tag, sizeof(tag), is_tag); + if (eof) return false; + if (!is_tag) return false; + if (strcmp(tag, end_tag)) return false; + x = val; + return true; +} + +// Same, for unsigned long long +// +bool XML_PARSER::parse_ulonglong(const char* start_tag, unsigned long long& x) { + char buf[256], *end; + bool eof; + char end_tag[256], tag[256]; + + if (strcmp(parsed_tag, start_tag)) return false; + + end_tag[0] = '/'; + strcpy(end_tag+1, start_tag); + + eof = get(buf, sizeof(buf), is_tag); + if (eof) return false; + if (is_tag) { + if (!strcmp(buf, end_tag)) { + x = 0; // treat as 0 + return true; + } else { + return false; + } + } + errno = 0; + unsigned long long val = boinc_strtoull(buf, &end, 0); + if (errno) return false; if (end != buf+strlen(buf)) return false; eof = get(tag, sizeof(tag), is_tag); diff --git a/lib/parse.h b/lib/parse.h index 2abbc80246..03de65d662 100644 --- a/lib/parse.h +++ b/lib/parse.h @@ -51,6 +51,8 @@ public: bool parse_string(const char*, std::string&); bool parse_int(const char*, int&); bool parse_double(const char*, double&); + bool parse_ulong(const char*, unsigned long&); + bool parse_ulonglong(const char*, unsigned long long&); bool parse_bool(const char*, bool&); int element_contents(const char*, char*, int); int copy_element(std::string&); @@ -109,8 +111,9 @@ inline unsigned long long boinc_strtoull(const char *s, char **, int) { inline bool parse_int(const char* buf, const char* tag, int& x) { const char* p = strstr(buf, tag); if (!p) return false; + errno = 0; int y = strtol(p+strlen(tag), 0, 0); // this parses 0xabcd correctly - if (errno == ERANGE) return false; + if (errno) return false; x = y; return true; } @@ -121,7 +124,9 @@ inline bool parse_double(const char* buf, const char* tag, double& x) { double y; const char* p = strstr(buf, tag); if (!p) return false; - y = atof(p+strlen(tag)); + errno = 0; + y = strtod(p+strlen(tag), NULL); + if (errno) return false; if (!boinc_is_finite(y)) { return false; } @@ -129,28 +134,34 @@ inline bool parse_double(const char* buf, const char* tag, double& x) { return true; } +#if 0 // Same, for unsigned long // inline bool parse_ulong(const char* buf, const char* tag, unsigned long& x) { const char* p = strstr(buf, tag); if (!p) return false; - unsigned long y = strtoul(p+strlen(tag), NULL, 0); // this parses 0xabcd correctly - if (errno == ERANGE) return false; + errno = 0; + unsigned long y = strtoul(p+strlen(tag), NULL, 0); + if (errno) return false; x = y; return true; } // Same, for unsigned long long // -inline bool parse_cl_ulong(const char* buf, const char* tag, cl_ulong& x) { +inline bool parse_ulonglong( + const char* buf, const char* tag, unsigned long long& x +) { const char* p = strstr(buf, tag); if (!p) return false; - unsigned long long y = boinc_strtoull(p+strlen(tag), NULL, 0); // this parses 0xabcd correctly - if (errno == ERANGE) return false; + errno = 0; + unsigned long long y = boinc_strtoull(p+strlen(tag), NULL, 0); + if (errno) return false; x = y; return true; - } - +} +#endif + extern bool parse(char* , char* ); extern bool parse_str(const char*, const char*, char*, int); extern bool parse_str(const char* buf, const char* tag, std::string& dest);