diff --git a/checkin_notes b/checkin_notes index 004762a9be..5bdb400522 100644 --- a/checkin_notes +++ b/checkin_notes @@ -7249,3 +7249,9 @@ David 6 Sept 2008 client/ cpu_sched.C + +David 6 Sept 2008 + - scheduler: fix typos in CUDA parsing + + lib/ + coproc.C diff --git a/lib/coproc.C b/lib/coproc.C index 99c9fb73eb..2dcc3c27c1 100644 --- a/lib/coproc.C +++ b/lib/coproc.C @@ -1,327 +1,327 @@ -// This file is part of BOINC. -// http://boinc.berkeley.edu -// Copyright (C) 2008 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 . - -#include -#include -#include -#ifdef _WIN32 -#else -#ifdef __APPLE__ -// Suppress obsolete warning when building for OS 10.3.9 -#define DLOPEN_NO_WARN -#endif -#include -#endif - -#include "error_numbers.h" -#include "filesys.h" -#include "parse.h" - -#include "coproc.h" - -using std::string; -using std::vector; - -#ifndef _USING_FCGI_ -void COPROC::write_xml(MIOFILE& f) { - f.printf( - "\n" - " %s\n" - " %d\n" - "\n", - type, count - ); -} -#endif - -int COPROC::parse(MIOFILE& fin) { - char buf[1024]; - strcpy(type, ""); - count = 0; - used = 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; - } - return ERR_XML_PARSE; -} - -vector COPROCS::get() { - vector strings; - const char* p = COPROC_CUDA::get(*this); - if (p) strings.push_back(p); - p = COPROC_CELL_SPE::get(*this); - if (p) strings.push_back(p); - return strings; -} - -int COPROCS::parse(FILE* fin) { - char buf[1024]; - - while (fgets(buf, sizeof(buf), fin)) { - 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); - } - } - } - return ERR_XML_PARSE; -} - -COPROC* COPROCS::lookup(char* type) { - for (unsigned int i=0; itype)) return cp; - } - return NULL; -} - -#ifdef _WIN32 - - -#endif - -const char* COPROC_CUDA::get(COPROCS& coprocs) { - int count; - -#ifdef _WIN32 - - typedef int (__stdcall *PCGDC)(int *count); - typedef int (__stdcall *PCGDP)(struct cudaDeviceProp *prop, int device); - - PCGDC __cudaGetDeviceCount = NULL; - PCGDP __cudaGetDeviceProperties = NULL; - - HMODULE cudalib = LoadLibrary("cudart.dll"); - if (!cudalib) { - return "Can't load library cudart.dll"; - } - - __cudaGetDeviceCount = (PCGDC)GetProcAddress( cudalib, "cudaGetDeviceCount" ); - if (!__cudaGetDeviceCount) { - return "Library doesn't have cudaGetDeviceCount()"; - } - - __cudaGetDeviceProperties = (PCGDP)GetProcAddress( cudalib, "cudaGetDeviceProperties" ); - if (!__cudaGetDeviceProperties) { - return "Library doesn't have cudaGetDeviceProperties()"; - } - -#else - void* cudalib; - void (*__cudaGetDeviceCount)(int*); - void (*__cudaGetDeviceProperties)(cudaDeviceProp*, int); - -#ifdef __APPLE__ - cudalib = dlopen("./libcudart.dylib", RTLD_NOW); -#else - cudalib = dlopen("./libcudart.so", RTLD_NOW); -#endif - if (!cudalib) { - return "Can't load library libcudart"; - perror("dlopen"); - } - __cudaGetDeviceCount = (void(*)(int*)) dlsym(cudalib, "cudaGetDeviceCount"); - if(!__cudaGetDeviceCount) { - return "Library doesn't have cudaGetDeviceCount()"; - } - __cudaGetDeviceProperties = (void(*)(cudaDeviceProp*, int)) dlsym( cudalib, "cudaGetDeviceProperties" ); - if (!__cudaGetDeviceProperties) { - return "Library doesn't have cudaGetDeviceProperties()"; - } -#endif - - // NOTE: our design is flawed: - // there's no provision for having two coprocs of type CUDA. - // So on systems with two GPUs (possibly of different hardware type) - // we have to count them as two of the same - // - (*__cudaGetDeviceCount)(&count); - int real_count = 0; - COPROC_CUDA cc, cc2; - for (int i=0; i= 1) { // major == 0 means emulation - cc2 = cc; - real_count++; - } - } - if (real_count) { - COPROC_CUDA* ccp = new COPROC_CUDA; - *ccp = cc2; - ccp->count = real_count; - strcpy(ccp->type, "CUDA"); - coprocs.coprocs.push_back(ccp); - } else { - return "No CUDA devices found"; - } - return "CUDA devices found"; -} - -// add a non-existent CUDA coproc (for debugging) -// -void fake_cuda(COPROCS& coprocs, int count) { - COPROC_CUDA* cc = new COPROC_CUDA; - strcpy(cc->type, "CUDA"); - cc->count = count; - strcpy(cc->prop.name, "CUDA NVIDIA chip"); - cc->prop.totalGlobalMem = 1000; - cc->prop.sharedMemPerBlock = 100; - cc->prop.regsPerBlock = 8; - cc->prop.warpSize = 10; - cc->prop.memPitch = 10; - cc->prop.maxThreadsPerBlock = 20; - cc->prop.maxThreadsDim[0] = 2; - cc->prop.maxThreadsDim[1] = 2; - cc->prop.maxThreadsDim[2] = 2; - cc->prop.maxGridSize[0] = 10; - cc->prop.maxGridSize[1] = 10; - cc->prop.maxGridSize[2] = 10; - cc->prop.totalConstMem = 10; - cc->prop.major = 1; - cc->prop.minor = 1; - cc->prop.clockRate = 10000; - cc->prop.textureAlignment = 1000; - coprocs.coprocs.push_back(cc); -} - -#ifndef _USING_FCGI_ -void COPROC_CUDA::write_xml(MIOFILE& f) { - f.printf( - "\n" - " %d\n" - " %s\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" - "\n", - count, - prop.name, - (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 - ); -} -#endif - -void COPROC_CUDA::clear() { - count = 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.totalConstMem = 0; - prop.major = 0; - prop.minor = 0; - prop.clockRate = 0; - prop.textureAlignment = 0; -} - -int COPROC_CUDA::parse(FILE* fin) { - char buf[1024], buf2[256]; - - clear(); - while (fgets(buf, sizeof(buf), fin)) { - if (strstr(buf, "")) return 0; - if (parse_int(buf, "", count)) continue; - if (parse_str(buf, "", prop.name, sizeof(prop.name))) continue; - if (parse_int(buf, "", (int&)prop.totalGlobalMem)) 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) { - prop.maxThreadsDim[1] = atoi(p); - p = strchr(p, ' '); - if (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) { - prop.maxGridSize[1] = atoi(p); - p = strchr(p, ' '); - if (p) { - prop.maxGridSize[2] = atoi(p); - } - } - 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, "", prop.clockRate)) continue; - if (parse_int(buf, "", (int&)prop.textureAlignment)) continue; - } - return ERR_XML_PARSE; -} - -void COPROC_CUDA::description(char* p) { - sprintf(p, "%s (%d)", prop.name, count); -} - -const char* COPROC_CELL_SPE::get(COPROCS&) { - return NULL; -} +// This file is part of BOINC. +// http://boinc.berkeley.edu +// Copyright (C) 2008 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 . + +#include +#include +#include +#ifdef _WIN32 +#else +#ifdef __APPLE__ +// Suppress obsolete warning when building for OS 10.3.9 +#define DLOPEN_NO_WARN +#endif +#include +#endif + +#include "error_numbers.h" +#include "filesys.h" +#include "parse.h" + +#include "coproc.h" + +using std::string; +using std::vector; + +#ifndef _USING_FCGI_ +void COPROC::write_xml(MIOFILE& f) { + f.printf( + "\n" + " %s\n" + " %d\n" + "\n", + type, count + ); +} +#endif + +int COPROC::parse(MIOFILE& fin) { + char buf[1024]; + strcpy(type, ""); + count = 0; + used = 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; + } + return ERR_XML_PARSE; +} + +vector COPROCS::get() { + vector strings; + const char* p = COPROC_CUDA::get(*this); + if (p) strings.push_back(p); + p = COPROC_CELL_SPE::get(*this); + if (p) strings.push_back(p); + return strings; +} + +int COPROCS::parse(FILE* fin) { + char buf[1024]; + + while (fgets(buf, sizeof(buf), fin)) { + 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); + } + } + } + return ERR_XML_PARSE; +} + +COPROC* COPROCS::lookup(char* type) { + for (unsigned int i=0; itype)) return cp; + } + return NULL; +} + +#ifdef _WIN32 + + +#endif + +const char* COPROC_CUDA::get(COPROCS& coprocs) { + int count; + +#ifdef _WIN32 + + typedef int (__stdcall *PCGDC)(int *count); + typedef int (__stdcall *PCGDP)(struct cudaDeviceProp *prop, int device); + + PCGDC __cudaGetDeviceCount = NULL; + PCGDP __cudaGetDeviceProperties = NULL; + + HMODULE cudalib = LoadLibrary("cudart.dll"); + if (!cudalib) { + return "Can't load library cudart.dll"; + } + + __cudaGetDeviceCount = (PCGDC)GetProcAddress( cudalib, "cudaGetDeviceCount" ); + if (!__cudaGetDeviceCount) { + return "Library doesn't have cudaGetDeviceCount()"; + } + + __cudaGetDeviceProperties = (PCGDP)GetProcAddress( cudalib, "cudaGetDeviceProperties" ); + if (!__cudaGetDeviceProperties) { + return "Library doesn't have cudaGetDeviceProperties()"; + } + +#else + void* cudalib; + void (*__cudaGetDeviceCount)(int*); + void (*__cudaGetDeviceProperties)(cudaDeviceProp*, int); + +#ifdef __APPLE__ + cudalib = dlopen("./libcudart.dylib", RTLD_NOW); +#else + cudalib = dlopen("./libcudart.so", RTLD_NOW); +#endif + if (!cudalib) { + return "Can't load library libcudart"; + perror("dlopen"); + } + __cudaGetDeviceCount = (void(*)(int*)) dlsym(cudalib, "cudaGetDeviceCount"); + if(!__cudaGetDeviceCount) { + return "Library doesn't have cudaGetDeviceCount()"; + } + __cudaGetDeviceProperties = (void(*)(cudaDeviceProp*, int)) dlsym( cudalib, "cudaGetDeviceProperties" ); + if (!__cudaGetDeviceProperties) { + return "Library doesn't have cudaGetDeviceProperties()"; + } +#endif + + // NOTE: our design is flawed: + // there's no provision for having two coprocs of type CUDA. + // So on systems with two GPUs (possibly of different hardware type) + // we have to count them as two of the same + // + (*__cudaGetDeviceCount)(&count); + int real_count = 0; + COPROC_CUDA cc, cc2; + for (int i=0; i= 1) { // major == 0 means emulation + cc2 = cc; + real_count++; + } + } + if (real_count) { + COPROC_CUDA* ccp = new COPROC_CUDA; + *ccp = cc2; + ccp->count = real_count; + strcpy(ccp->type, "CUDA"); + coprocs.coprocs.push_back(ccp); + } else { + return "No CUDA devices found"; + } + return "CUDA devices found"; +} + +// add a non-existent CUDA coproc (for debugging) +// +void fake_cuda(COPROCS& coprocs, int count) { + COPROC_CUDA* cc = new COPROC_CUDA; + strcpy(cc->type, "CUDA"); + cc->count = count; + strcpy(cc->prop.name, "CUDA NVIDIA chip"); + cc->prop.totalGlobalMem = 1000; + cc->prop.sharedMemPerBlock = 100; + cc->prop.regsPerBlock = 8; + cc->prop.warpSize = 10; + cc->prop.memPitch = 10; + cc->prop.maxThreadsPerBlock = 20; + cc->prop.maxThreadsDim[0] = 2; + cc->prop.maxThreadsDim[1] = 2; + cc->prop.maxThreadsDim[2] = 2; + cc->prop.maxGridSize[0] = 10; + cc->prop.maxGridSize[1] = 10; + cc->prop.maxGridSize[2] = 10; + cc->prop.totalConstMem = 10; + cc->prop.major = 1; + cc->prop.minor = 1; + cc->prop.clockRate = 10000; + cc->prop.textureAlignment = 1000; + coprocs.coprocs.push_back(cc); +} + +#ifndef _USING_FCGI_ +void COPROC_CUDA::write_xml(MIOFILE& f) { + f.printf( + "\n" + " %d\n" + " %s\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" + "\n", + count, + prop.name, + (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 + ); +} +#endif + +void COPROC_CUDA::clear() { + count = 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.totalConstMem = 0; + prop.major = 0; + prop.minor = 0; + prop.clockRate = 0; + prop.textureAlignment = 0; +} + +int COPROC_CUDA::parse(FILE* fin) { + char buf[1024], buf2[256]; + + clear(); + while (fgets(buf, sizeof(buf), fin)) { + if (strstr(buf, "")) return 0; + if (parse_int(buf, "", count)) continue; + if (parse_str(buf, "", prop.name, sizeof(prop.name))) continue; + if (parse_int(buf, "", (int&)prop.totalGlobalMem)) 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) { + prop.maxThreadsDim[1] = atoi(p); + p = strchr(p, ' '); + if (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) { + prop.maxGridSize[1] = atoi(p); + p = strchr(p, ' '); + if (p) { + prop.maxGridSize[2] = atoi(p); + } + } + 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, "", prop.clockRate)) continue; + if (parse_int(buf, "", (int&)prop.textureAlignment)) continue; + } + return ERR_XML_PARSE; +} + +void COPROC_CUDA::description(char* p) { + sprintf(p, "%s (%d)", prop.name, count); +} + +const char* COPROC_CELL_SPE::get(COPROCS&) { + return NULL; +}