// This file is part of BOINC. // http://boinc.berkeley.edu // Copyright (C) 2007 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 defined(_WIN32) && !defined(__STDWX_H__) #include "boinc_win.h" #elif defined(_WIN32) && defined(__STDWX_H__) #include "stdwx.h" #else #ifdef _USING_FCGI_ #include "boinc_fcgi.h" #else #include #endif #include #include #endif #ifdef _WIN32 #include "win_util.h" #endif #include "error_numbers.h" #include "filesys.h" #include "parse.h" #include "util.h" #include "coproc.h" #ifndef _USING_FCGI_ 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, "")) { if (!strlen(type)) return ERR_XML_PARSE; return 0; } if (parse_str(buf, "", type, sizeof(type))) continue; if (parse_double(buf, "", count)) continue; } return ERR_XML_PARSE; } #ifndef _USING_FCGI_ void COPROC::write_xml(MIOFILE& f) { f.printf( "\n" " %s\n" " %d\n" "\n", type, count ); //TODO: Add opencl_prop } void COPROC::write_request(MIOFILE& f) { f.printf( " %f\n" " %f\n" " %f\n", req_secs, req_instances, estimated_delay ); } int COPROC::parse(XML_PARSER& xp) { //TODO: Parse opencl_prop char buf[256]; strcpy(type, ""); clear(); for (int i=0; i")) { return 0; } if (match_tag(buf, "")) { retval = nvidia.parse(xp); if (retval) { nvidia.clear(); } else { coprocs[n_rsc++] = nvidia; } continue; } if (match_tag(buf, "")) { retval = ati.parse(xp); if (retval) { ati.clear(); } else { coprocs[n_rsc++] = ati; } continue; } } return ERR_XML_PARSE; } void COPROCS::write_xml(MIOFILE& mf, bool include_request) { #ifndef _USING_FCGI_ //TODO: Write coprocs[0] through coprocs[n_rsc] mf.printf(" \n"); if (nvidia.count) { nvidia.write_xml(mf, include_request); } if (ati.count) { ati.write_xml(mf, include_request); } mf.printf(" \n"); #endif } void COPROC_NVIDIA::description(char* buf) { char vers[256]; if (display_driver_version) { sprintf(vers, "%d", display_driver_version); } else { strcpy(vers, "unknown"); } sprintf(buf, "%s (driver version %s, CUDA version %d, compute capability %d.%d, %.0fMB, %.0f GFLOPS peak)", prop.name, vers, cuda_version, prop.major, prop.minor, prop.totalGlobalMem/(1024.*1024.), peak_flops/1e9 ); } #ifndef _USING_FCGI_ void COPROC_NVIDIA::write_xml(MIOFILE& f, bool include_request) { //TODO: Add opencl_prop f.printf( "\n" " %d\n" " %s\n", count, prop.name ); if (have_cuda) { f.printf("\n"); } if (have_cal) { f.printf("\n"); } if (have_opencl) { f.printf("\n"); } if (include_request) { write_request(f); } f.printf( " %f\n" " %d\n" " %d\n" " %d\n" " %u\n" " %u\n" " %d\n" " %d\n" " %u\n" " %d\n" " %d %d %d\n" " %d %d %d\n" " %d\n" " %u\n" " %d\n" " %d\n" " %u\n" " %d\n" " %d\n" "\n", peak_flops, cuda_version, display_driver_version, prop.deviceHandle, (unsigned int)prop.totalGlobalMem, (unsigned int)prop.sharedMemPerBlock, prop.regsPerBlock, prop.warpSize, (unsigned int)prop.memPitch, prop.maxThreadsPerBlock, prop.maxThreadsDim[0], prop.maxThreadsDim[1], prop.maxThreadsDim[2], prop.maxGridSize[0], prop.maxGridSize[1], prop.maxGridSize[2], prop.clockRate, (unsigned int)prop.totalConstMem, prop.major, prop.minor, (unsigned int)prop.textureAlignment, prop.deviceOverlap, prop.multiProcessorCount ); } #endif void COPROC_NVIDIA::clear() { COPROC::clear(); strcpy(type, "NVIDIA"); estimated_delay = -1; // mark as absent cuda_version = 0; display_driver_version = 0; strcpy(prop.name, ""); prop.deviceHandle = 0; prop.totalGlobalMem = 0; prop.sharedMemPerBlock = 0; prop.regsPerBlock = 0; prop.warpSize = 0; prop.memPitch = 0; prop.maxThreadsPerBlock = 0; prop.maxThreadsDim[0] = 0; prop.maxThreadsDim[1] = 0; prop.maxThreadsDim[2] = 0; prop.maxGridSize[0] = 0; prop.maxGridSize[1] = 0; prop.maxGridSize[2] = 0; prop.clockRate = 0; prop.totalConstMem = 0; prop.major = 0; prop.minor = 0; prop.textureAlignment = 0; prop.deviceOverlap = 0; prop.multiProcessorCount = 0; } int COPROC_NVIDIA::parse(XML_PARSER& xp) { //TODO: Parse opencl_prop char buf[1024], buf2[256]; clear(); MIOFILE& in = *(xp.f); while (in.fgets(buf, sizeof(buf))) { if (strstr(buf, "")) { 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)) { 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))) { // can't use sscanf here (FCGI) // prop.maxThreadsDim[0] = atoi(buf2); char* p = strchr(buf2, ' '); if (p) { p++; prop.maxThreadsDim[1] = atoi(p); p = strchr(p, ' '); if (p) { p++; prop.maxThreadsDim[2] = atoi(p); } } continue; } if (parse_str(buf, "", buf2, sizeof(buf2))) { prop.maxGridSize[0] = atoi(buf2); char* p = strchr(buf2, ' '); if (p) { p++; prop.maxGridSize[1] = atoi(p); p = strchr(p, ' '); if (p) { p++; prop.maxGridSize[2] = atoi(p); } } 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; } return ERR_XML_PARSE; } ////////////////// ATI STARTS HERE ///////////////// #ifndef _USING_FCGI_ void COPROC_ATI::write_xml(MIOFILE& f, bool include_request) { //TODO: Add opencl_prop f.printf( "\n" " %d\n" " %s\n", count, name ); if (have_cuda) { f.printf("\n"); } if (have_cal) { f.printf("\n"); } if (have_opencl) { f.printf("\n"); } if (include_request) { write_request(f); } f.printf( " %f\n" " %s\n" " %d\n" " %d\n" " %d\n" " %d\n" " %u\n" " %d\n" " %d\n" " %d\n" " %d\n" " %d\n" " %d\n" " %d\n" " %d\n" " %d\n", peak_flops, version, attribs.target, attribs.localRAM, attribs.uncachedRemoteRAM, attribs.cachedRemoteRAM, attribs.engineClock, attribs.memoryClock, attribs.wavefrontSize, attribs.numberOfSIMD, attribs.doublePrecision, attribs.pitch_alignment, attribs.surface_alignment, info.maxResource1DWidth, info.maxResource2DWidth, info.maxResource2DHeight ); if (atirt_detected) { f.printf(" \n"); } if (amdrt_detected) { f.printf(" \n"); } f.printf("\n"); }; #endif void COPROC_ATI::clear() { COPROC::clear(); strcpy(type, "ATI"); estimated_delay = -1; strcpy(name, ""); strcpy(version, ""); atirt_detected = false; amdrt_detected = false; memset(&attribs, 0, sizeof(attribs)); memset(&info, 0, sizeof(info)); } int COPROC_ATI::parse(XML_PARSER& xp) { //TODO: Parse opencl_prop char buf[1024]; int n; clear(); MIOFILE& in = *(xp.f); while (in.fgets(buf, sizeof(buf))) { if (strstr(buf, "")) { int major, minor, release; sscanf(version, "%d.%d.%d", &major, &minor, &release); version_num = major*1000000 + minor*1000 + release; 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_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 (parse_int(buf, "", n)) { attribs.target = (CALtarget)n; continue; } if (parse_int(buf, "", n)) { attribs.localRAM = n; continue; } if (parse_int(buf, "", n)) { attribs.uncachedRemoteRAM = n; continue; } if (parse_int(buf, "", n)) { attribs.cachedRemoteRAM = n; continue; } if (parse_int(buf, "", n)) { attribs.engineClock = n; continue; } if (parse_int(buf, "", n)) { attribs.memoryClock = n; continue; } if (parse_int(buf, "", n)) { attribs.wavefrontSize = n; continue; } if (parse_int(buf, "" , n)) { attribs.numberOfSIMD = n; continue; } if (parse_int(buf, "", n)) { attribs.doublePrecision = n?CAL_TRUE:CAL_FALSE; continue; } if (parse_int(buf, "", n)) { attribs.pitch_alignment = n; continue; } if (parse_int(buf, "", n)) { attribs.surface_alignment = n; continue; } if (parse_int(buf, "", n)) { info.maxResource1DWidth = n; continue; } if (parse_int(buf, "", n)) { info.maxResource2DWidth = n; continue; } if (parse_int(buf, "", n)) { info.maxResource2DHeight = n; continue; } } return ERR_XML_PARSE; } void COPROC_ATI::description(char* buf) { sprintf(buf, "%s (CAL version %s, %.0fMB, %.0f GFLOPS peak)", name, version, attribs.localRAM/1024.*1024., peak_flops/1.e9 ); }