// 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 "str_util.h"
#include "coproc.h"
#ifndef _USING_FCGI_
using std::perror;
#endif
#ifndef _USING_FCGI_
void COPROC::write_xml(MIOFILE& f) {
f.printf(
"\n"
" %s\n"
" %d\n"
"\n",
type, count
);
}
#endif
int COPROC_REQ::parse(MIOFILE& fin) {
char buf[1024];
strcpy(type, "");
count = 0;
while (fin.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;
}
int COPROC::parse(MIOFILE& fin) {
char buf[1024];
strcpy(type, "");
count = 0;
used = 0;
req_secs = 0;
estimated_delay = 0;
req_instances = 0;
while (fin.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_int(buf, "", count)) continue;
if (parse_double(buf, "", req_secs)) continue;
if (parse_double(buf, "", req_instances)) continue;
if (parse_double(buf, "", estimated_delay)) continue;
}
return ERR_XML_PARSE;
}
void COPROCS::summary_string(char* buf, int len) {
char bigbuf[8192], buf2[1024];
strcpy(bigbuf, "");
for (unsigned int i=0; itype, "CUDA")) {
COPROC_CUDA* cp2 = (COPROC_CUDA*) cp;
int mem = (int)(cp2->prop.dtotalGlobalMem/MEGA);
sprintf(buf2, "[CUDA|%s|%d|%dMB|%d]",
cp2->prop.name, cp2->count, mem, cp2->display_driver_version
);
strcat(bigbuf, buf2);
} else if (!strcmp(cp->type, "ATI")){
COPROC_ATI* cp2 =(COPROC_ATI*) cp;
sprintf(buf2,"[CAL|%s|%d|%dMB|%s]",
cp2->name, cp2->count, cp2->attribs.localRAM, cp2->version
);
strcat(bigbuf,buf2);
}
}
bigbuf[len-1] = 0;
strcpy(buf, bigbuf);
}
int COPROCS::parse(MIOFILE& fin) {
char buf[1024];
while (fin.fgets(buf, sizeof(buf))) {
if (match_tag(buf, "")) {
return 0;
}
if (strstr(buf, "")) {
COPROC_CUDA* cc = new COPROC_CUDA;
int retval = cc->parse(fin);
if (!retval) {
coprocs.push_back(cc);
}
}
if (strstr(buf, "")) {
COPROC_ATI* cc = new COPROC_ATI;
int retval = cc->parse(fin);
if (!retval) {
coprocs.push_back(cc);
}
}
}
return ERR_XML_PARSE;
}
void COPROCS::write_xml(MIOFILE& mf) {
#ifndef _USING_FCGI_
mf.printf(" \n");
for (unsigned i=0; iwrite_xml(mf);
}
mf.printf(" \n");
#endif
}
COPROC* COPROCS::lookup(const char* type) {
for (unsigned int i=0; itype)) return cp;
}
return NULL;
}
#ifdef _WIN32
#endif
void COPROC_CUDA::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_CUDA::write_xml(MIOFILE& f) {
f.printf(
"\n"
" %d\n"
" %s\n"
" %f\n"
" %f\n"
" %f\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"
" %u\n"
" %d\n"
" %d\n"
" %d\n"
" %u\n"
" %d\n"
" %d\n"
"\n",
count,
prop.name,
req_secs,
req_instances,
estimated_delay,
display_driver_version,
cuda_version,
(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],
(unsigned int)prop.totalConstMem,
prop.major,
prop.minor,
prop.clockRate,
(unsigned int)prop.textureAlignment,
prop.deviceOverlap,
prop.multiProcessorCount
);
}
#endif
void COPROC_CUDA::clear() {
count = 0;
used = 0;
req_secs = 0;
req_instances = 0;
estimated_delay = -1; // mark as absent
cuda_version = 0;
display_driver_version = 0;
strcpy(prop.name, "");
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_CUDA::parse(MIOFILE& fin) {
char buf[1024], buf2[256];
clear();
while (fin.fgets(buf, sizeof(buf))) {
if (strstr(buf, "")) {
return 0;
}
if (parse_int(buf, "", count)) 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, "", prop.name, sizeof(prop.name))) continue;
if (parse_int(buf, "", display_driver_version)) continue;
if (parse_int(buf, "", cuda_version)) continue;
if (parse_double(buf, "", 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) {
f.printf(
"\n"
);
f.printf(
" %d\n"
" %s\n"
" %f\n"
" %f\n"
" %f\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"
" %s\n",
count,
name,
req_secs,
req_instances,
estimated_delay,
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,
version
);
if (atirt_detected) {
f.printf(" \n");
}
if (amdrt_detected) {
f.printf(" \n");
}
f.printf("\n");
};
#endif
void COPROC_ATI::clear() {
count = 0;
used = 0;
req_secs = 0;
req_instances = 0;
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(MIOFILE& fin) {
char buf[1024];
int n;
clear();
while (fin.fgets(buf, sizeof(buf))) {
if (strstr(buf, "")) return 0;
if (parse_int(buf, "", count)) continue;
if (parse_str(buf, "", name, sizeof(name))) 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, "", 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;
}
if (parse_bool(buf, "amdrt_detected", amdrt_detected)) continue;
if (parse_bool(buf, "atirt_detected", atirt_detected)) continue;
if (parse_str(buf, "", version, sizeof(version))) 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
);
}