2008-08-06 18:36:30 +00:00
|
|
|
// This file is part of BOINC.
|
2008-03-20 03:13:30 +00:00
|
|
|
// http://boinc.berkeley.edu
|
|
|
|
// Copyright (C) 2008 University of California
|
|
|
|
//
|
2008-08-06 18:36:30 +00:00
|
|
|
// 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.
|
2008-03-20 03:13:30 +00:00
|
|
|
//
|
2008-08-06 18:36:30 +00:00
|
|
|
// BOINC is distributed in the hope that it will be useful,
|
2008-03-20 03:13:30 +00:00
|
|
|
// 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.
|
|
|
|
//
|
2008-08-06 18:36:30 +00:00
|
|
|
// You should have received a copy of the GNU Lesser General Public License
|
|
|
|
// along with BOINC. If not, see <http://www.gnu.org/licenses/>.
|
2008-03-20 03:13:30 +00:00
|
|
|
//
|
|
|
|
|
|
|
|
// Replace the following with your own code.
|
|
|
|
// WARNING: after doing this, you must prevent this file from
|
|
|
|
// being overwritten the next time you update BOINC source code.
|
|
|
|
// You can either:
|
|
|
|
// 1) write-protect this file, or
|
|
|
|
// 2) put this in a differently-named file and change the Makefile.am
|
2008-12-10 19:14:13 +00:00
|
|
|
// (and write-protect that)
|
2008-03-20 03:13:30 +00:00
|
|
|
// In either case, put your version under source-code control, e.g. SVN
|
|
|
|
|
2008-12-19 21:27:02 +00:00
|
|
|
#include "str_util.h"
|
2008-05-06 19:53:49 +00:00
|
|
|
#include "sched_config.h"
|
2008-03-27 18:25:29 +00:00
|
|
|
#include "sched_msgs.h"
|
2009-06-01 22:15:14 +00:00
|
|
|
#include "sched_send.h"
|
2008-03-20 03:13:30 +00:00
|
|
|
|
2009-06-01 22:15:14 +00:00
|
|
|
#include "sched_plan.h"
|
2008-03-27 18:25:29 +00:00
|
|
|
|
2009-01-20 21:31:13 +00:00
|
|
|
int app_plan(SCHEDULER_REQUEST& sreq, char* plan_class, HOST_USAGE& hu) {
|
2008-03-27 18:25:29 +00:00
|
|
|
if (!strcmp(plan_class, "mt")) {
|
|
|
|
// the following is for an app that can use anywhere
|
|
|
|
// from 1 to 64 threads, can control this exactly,
|
|
|
|
// and whose speedup is .95N
|
2009-01-22 19:51:04 +00:00
|
|
|
// (on a uniprocessor, we'll use a sequential app if one is available)
|
2008-03-27 18:25:29 +00:00
|
|
|
//
|
2009-06-01 22:15:14 +00:00
|
|
|
int nthreads;
|
2008-03-27 18:25:29 +00:00
|
|
|
|
2009-06-01 22:15:14 +00:00
|
|
|
nthreads = effective_ncpus();
|
2008-03-27 18:25:29 +00:00
|
|
|
if (nthreads > 64) nthreads = 64;
|
|
|
|
hu.avg_ncpus = nthreads;
|
|
|
|
hu.max_ncpus = nthreads;
|
|
|
|
sprintf(hu.cmdline, "--nthreads %d", nthreads);
|
|
|
|
hu.flops = 0.95*sreq.host.p_fpops*nthreads;
|
2009-01-10 00:43:33 +00:00
|
|
|
if (config.debug_version_select) {
|
2009-01-15 20:23:20 +00:00
|
|
|
log_messages.printf(MSG_NORMAL,
|
|
|
|
"[version] Multi-thread app estimate %.2f GFLOPS\n",
|
2009-01-10 00:43:33 +00:00
|
|
|
hu.flops/1e9
|
|
|
|
);
|
|
|
|
}
|
2009-01-20 21:31:13 +00:00
|
|
|
return 0;
|
2008-03-28 18:00:27 +00:00
|
|
|
} else if (!strcmp(plan_class, "cuda")) {
|
2009-01-12 05:28:36 +00:00
|
|
|
// the following is for an app that uses a CUDA GPU
|
|
|
|
//
|
|
|
|
COPROC_CUDA* cp = (COPROC_CUDA*)sreq.coprocs.lookup("CUDA");
|
|
|
|
if (!cp) {
|
|
|
|
if (config.debug_version_select) {
|
2009-01-15 20:23:20 +00:00
|
|
|
log_messages.printf(MSG_NORMAL,
|
|
|
|
"[version] Host lacks CUDA coprocessor for plan class cuda\n"
|
2009-01-12 05:28:36 +00:00
|
|
|
);
|
|
|
|
}
|
2009-02-17 03:16:25 +00:00
|
|
|
return PLAN_REJECT_CUDA_NO_DEVICE;
|
2009-01-12 05:28:36 +00:00
|
|
|
}
|
|
|
|
int v = (cp->prop.major)*100 + cp->prop.minor;
|
2009-01-21 17:36:26 +00:00
|
|
|
if (v < 100) {
|
2009-01-15 20:23:20 +00:00
|
|
|
if (config.debug_version_select) {
|
|
|
|
log_messages.printf(MSG_NORMAL,
|
2009-01-21 17:36:26 +00:00
|
|
|
"[version] CUDA version %d < 1.0\n", v
|
2009-01-15 20:23:20 +00:00
|
|
|
);
|
|
|
|
}
|
2009-02-17 03:16:25 +00:00
|
|
|
return PLAN_REJECT_CUDA_VERSION;
|
2009-01-12 05:28:36 +00:00
|
|
|
}
|
2008-12-10 19:14:13 +00:00
|
|
|
|
2009-05-28 16:37:26 +00:00
|
|
|
if (cp->drvVersion && cp->drvVersion < PLAN_CUDA_MIN_DRIVER_VERSION) {
|
2009-02-17 03:16:25 +00:00
|
|
|
if (config.debug_version_select) {
|
|
|
|
log_messages.printf(MSG_NORMAL,
|
2009-05-28 16:37:26 +00:00
|
|
|
"[version] NVIDIA driver version %d < PLAN_CUDA_MIN_DRIVER_VERSION\n",
|
2009-02-17 03:16:25 +00:00
|
|
|
cp->drvVersion
|
|
|
|
);
|
|
|
|
}
|
|
|
|
return PLAN_REJECT_NVIDIA_DRIVER_VERSION;
|
|
|
|
}
|
|
|
|
|
2009-05-28 16:37:26 +00:00
|
|
|
if (cp->prop.dtotalGlobalMem < PLAN_CUDA_MIN_RAM) {
|
2009-01-15 20:23:20 +00:00
|
|
|
if (config.debug_version_select) {
|
|
|
|
log_messages.printf(MSG_NORMAL,
|
2009-05-28 16:37:26 +00:00
|
|
|
"[version] CUDA mem %d < %d\n",
|
|
|
|
cp->prop.dtotalGlobalMem, PLAN_CUDA_MIN_RAM
|
2009-01-15 20:23:20 +00:00
|
|
|
);
|
|
|
|
}
|
2009-02-17 03:16:25 +00:00
|
|
|
return PLAN_REJECT_CUDA_MEM;
|
2009-01-12 05:28:36 +00:00
|
|
|
}
|
|
|
|
hu.flops = cp->flops_estimate();
|
2008-12-08 19:39:19 +00:00
|
|
|
|
2009-01-15 23:44:58 +00:00
|
|
|
#if 0 // THIS PROBLEM HAS BEEN FIXED IN THE SETI@HOME APP
|
2009-01-12 05:28:36 +00:00
|
|
|
// On Windows, slower GPUs sometimes get a blue screen of death
|
|
|
|
//
|
|
|
|
if (strstr(sreq.host.os_name, "Windows") && hu.flops < 60e9) {
|
|
|
|
if (config.debug_version_select) {
|
2009-01-15 20:23:20 +00:00
|
|
|
log_messages.printf(MSG_NORMAL,
|
|
|
|
"[version] Not sending CUDA job to Win host with slow GPU (%.1f GFLOPS)\n",
|
2009-01-12 05:28:36 +00:00
|
|
|
hu.flops/1e9
|
|
|
|
);
|
2008-03-28 18:00:27 +00:00
|
|
|
}
|
2009-02-17 03:16:25 +00:00
|
|
|
return PLAN_REJECT_CUDA_SPEED;
|
2008-03-28 18:00:27 +00:00
|
|
|
}
|
2009-01-15 23:44:58 +00:00
|
|
|
#endif
|
2009-01-12 05:28:36 +00:00
|
|
|
|
|
|
|
// assume we'll need 0.5% as many CPU FLOPS as GPU FLOPS
|
|
|
|
// to keep the GPU fed.
|
|
|
|
//
|
2009-01-13 01:02:30 +00:00
|
|
|
double x = (hu.flops*0.005)/sreq.host.p_fpops;
|
2009-01-12 05:28:36 +00:00
|
|
|
hu.avg_ncpus = x;
|
|
|
|
hu.max_ncpus = x;
|
|
|
|
|
2009-03-05 00:10:16 +00:00
|
|
|
hu.ncudas = 1;
|
|
|
|
|
2008-05-06 19:53:49 +00:00
|
|
|
if (config.debug_version_select) {
|
2009-01-15 20:23:20 +00:00
|
|
|
log_messages.printf(MSG_NORMAL,
|
|
|
|
"[version] CUDA app estimated %.2f GFLOPS (clock %d count %d)\n",
|
2009-01-12 05:28:36 +00:00
|
|
|
hu.flops/1e9, cp->prop.clockRate,
|
|
|
|
cp->prop.multiProcessorCount
|
2008-05-06 19:53:49 +00:00
|
|
|
);
|
|
|
|
}
|
2009-01-20 21:31:13 +00:00
|
|
|
return 0;
|
2009-01-22 19:51:04 +00:00
|
|
|
} else if (!strcmp(plan_class, "nci")) {
|
|
|
|
// The following is for a non-CPU-intensive application.
|
|
|
|
// Say that we'll use 1% of a CPU.
|
|
|
|
// This will cause the client (6.7+) to run it at non-idle priority
|
|
|
|
//
|
|
|
|
hu.avg_ncpus = .01;
|
|
|
|
hu.max_ncpus = .01;
|
2009-01-23 23:04:33 +00:00
|
|
|
hu.flops = sreq.host.p_fpops*1.01;
|
|
|
|
// The *1.01 is needed to ensure that we'll send this app
|
|
|
|
// version rather than a non-plan-class one
|
2009-01-23 19:36:17 +00:00
|
|
|
return 0;
|
2008-03-27 18:25:29 +00:00
|
|
|
}
|
|
|
|
log_messages.printf(MSG_CRITICAL,
|
|
|
|
"Unknown plan class: %s\n", plan_class
|
|
|
|
);
|
2009-01-23 19:36:17 +00:00
|
|
|
return PLAN_REJECT_UNKNOWN;
|
2008-03-20 03:13:30 +00:00
|
|
|
}
|
2009-06-01 22:15:14 +00:00
|
|
|
|
|
|
|
bool app_plan_uses_gpu(const char* plan_class) {
|
|
|
|
if (!strcmp(plan_class, "cuda")) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|