| 94 | | if (!strcmp(plan_class, "cuda")) { |
| 95 | | COPROC_CUDA* cp = (COPROC_CUDA*)sreq.coprocs.lookup("CUDA"); |
| 96 | | if (!cp) { |
| 97 | | if (config.debug_version_select) { |
| 98 | | log_messages.printf(MSG_NORMAL, |
| 99 | | "[version] Host lacks CUDA coprocessor for plan class cuda\n" |
| 100 | | ); |
| 101 | | } |
| 102 | | add_no_work_message("Your computer has no NVIDIA GPU"); |
| | 113 | if (!strcmp(plan_class, "cuda23")) { |
| | 114 | if (!cuda_check(c, hu, |
| | 115 | 100, // minimum compute capability (1.0) |
| | 116 | 200, // max compute capability (2.0) |
| | 117 | 2030, // min CUDA version (2.3) |
| | 118 | 19500, // min display driver version (195.00) |
| | 119 | 384*MEGA, // min video RAM |
| | 120 | 1., // # of GPUs used (may be fractional, or an integer > 1) |
| | 121 | .01, // fraction of FLOPS done by the CPU |
| | 122 | .21 // estimated GPU efficiency (actual/peak FLOPS) |
| | 123 | )) { |
| 106 | | Check the compute capability (1.0 or better): |
| | 128 | |
| | 129 | To define a new ATI/CAL plan class, add a new clause |
| | 130 | to '''app_plan_ati()'''. |
| | 131 | For example: |
| | 132 | {{{ |
| | 133 | if (!strcmp(plan_class, "ati14")) { |
| | 134 | if (!ati_check(c, hu, |
| | 135 | 1004000, // min display driver version (10.4) |
| | 136 | false, // require libraries named "ati", not "amd" |
| | 137 | 384*MEGA, // min video RAM |
| | 138 | 1., // # of GPUs used (may be fractional, or an integer > 1) |
| | 139 | .01, // fraction of FLOPS done by the CPU |
| | 140 | .21 // estimated GPU efficiency (actual/peak FLOPS) |
| | 141 | )) { |
| | 142 | return false; |
| | 143 | } |
| | 144 | } |
| | 145 | }}} |
| | 146 | |
| | 147 | To define a new OpenCL plan class, add a new clause to |
| | 148 | '''app_plan_opencl()'''. |
| | 149 | For example: |
| 109 | | int v = (cp->prop.major)*100 + cp->prop.minor; |
| 110 | | if (v < 100) { |
| 111 | | if (config.debug_version_select) { |
| 112 | | log_messages.printf(MSG_NORMAL, |
| 113 | | "[version] CUDA version %d < 1.0\n", v |
| 114 | | ); |
| 115 | | } |
| 116 | | add_no_work_message( |
| 117 | | "Your NVIDIA GPU lacks the needed compute capability" |
| 118 | | ); |
| 119 | | } |
| | 152 | if (!strcmp(plan_class, "opencl_nvidia_101")) { |
| | 153 | return opencl_check( |
| | 154 | c, hu, |
| | 155 | 101, // OpenCL version (1.1) |
| | 156 | 256*MEGA, // min video RAM |
| | 157 | 1, // # of GPUs used |
| | 158 | .1, // fraction of FLOPS done by the CPU |
| | 159 | .21 // estimated GPU efficiency (actual/peak FLOPS) |
| | 160 | ); |
| | 161 | } |
| 121 | | Check the CUDA runtime version. |
| 122 | | As of client version 6.10, all clients report the CUDA runtime version (cp->cuda_version); use that if it's present. |
| 123 | | In 6.8 and earlier, the CUDA runtime version isn't reported. |
| 124 | | Windows clients report the driver version, from which the CUDA version can be inferred; |
| 125 | | Linux clients don't return the driver version, so we don't know what the CUDA version is. |
| 126 | | |
| 127 | | {{{ |
| 128 | | // for CUDA 2.3, we need to check the CUDA RT version. |
| 129 | | // Old BOINC clients report display driver version; |
| 130 | | // newer ones report CUDA RT version |
| 131 | | // |
| 132 | | if (!strcmp(plan_class, "cuda23")) { |
| 133 | | if (cp->cuda_version) { |
| 134 | | if (cp->cuda_version < 2030) { |
| 135 | | add_no_work_message("CUDA version 2.3 needed"); |
| 136 | | return false; |
| 137 | | } |
| 138 | | } else if (cp->display_driver_version) { |
| 139 | | if (cp->display_driver_version < PLAN_CUDA23_MIN_DRIVER_VERSION) { |
| 140 | | sprintf(buf, "NVIDIA display driver %d or later needed", |
| 141 | | PLAN_CUDA23_MIN_DRIVER_VERSION |
| 142 | | ); |
| 143 | | } |
| 144 | | } else { |
| 145 | | add_no_work_message("CUDA version 2.3 needed"); |
| 146 | | return false; |
| 147 | | } |
| 148 | | }}} |
| 149 | | Check for the amount of video RAM: |
| 150 | | |
| 151 | | {{{ |
| 152 | | if (cp->prop.dtotalGlobalMem < PLAN_CUDA_MIN_RAM) { |
| 153 | | if (config.debug_version_select) { |
| 154 | | log_messages.printf(MSG_NORMAL, |
| 155 | | "[version] CUDA mem %d < %d\n", |
| 156 | | cp->prop.dtotalGlobalMem, PLAN_CUDA_MIN_RAM |
| 157 | | ); |
| 158 | | } |
| 159 | | sprintf(buf, |
| 160 | | "Your NVIDIA GPU has insufficient memory (need %.0fMB)", |
| 161 | | PLAN_CUDA_MIN_RAM |
| 162 | | ); |
| 163 | | add_no_work_message(buf); |
| 164 | | return false; |
| 165 | | } |
| 166 | | }}} |
| 167 | | Estimate the FLOPS: |
| 168 | | |
| 169 | | {{{ |
| 170 | | hu.flops = cp->flops_estimate(); |
| 171 | | }}} |
| 172 | | Estimate its CPU usage: |
| 173 | | |
| 174 | | {{{ |
| 175 | | // assume we'll need 0.5% as many CPU FLOPS as GPU FLOPS |
| 176 | | // to keep the GPU fed. |
| 177 | | // |
| 178 | | double x = (hu.flops*0.005)/sreq.host.p_fpops; |
| 179 | | hu.avg_ncpus = x; |
| 180 | | hu.max_ncpus = x; |
| 181 | | }}} |
| 182 | | Indicate the number of GPUs used. Typically this will be 1. |
| 183 | | If your application uses only a fraction X<1 of the CPU processors, |
| 184 | | and a fraction Y<1 of video RAM, reports the number of GPUs as min(X, Y). |
| 185 | | In this case BOINC will attempt to run multiple jobs per GPU is possible. |
| 186 | | |
| 187 | | {{{ |
| 188 | | hu.ncudas = 1; |
| 189 | | }}} |
| 190 | | Return true to indicate that the application can be run on the host: |
| 191 | | |
| 192 | | {{{ |
| 193 | | return true; |
| 194 | | }}} |