|
|
@@ -25,6 +25,7 @@
|
|
|
#include <string.h>
|
|
|
#include <stdbool.h>
|
|
|
#include <stdint.h>
|
|
|
+#include <stdio.h>
|
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
|
@@ -286,14 +287,20 @@ extern int gpu_fanpercent(int gpu);
|
|
|
#endif
|
|
|
|
|
|
|
|
|
-#ifdef HAVE_SENSORS
|
|
|
-#include <sensors/sensors.h>
|
|
|
-
|
|
|
-struct opencl_device_data {
|
|
|
- const sensors_chip_name *sensor;
|
|
|
-};
|
|
|
-#endif
|
|
|
-
|
|
|
+void opencl_early_init()
|
|
|
+{
|
|
|
+ static struct opencl_device_data dataarray[MAX_GPUDEVICES];
|
|
|
+ for (int i = 0; i < MAX_GPUDEVICES; ++i)
|
|
|
+ {
|
|
|
+ struct opencl_device_data * const data = &dataarray[i];
|
|
|
+ *data = (struct opencl_device_data){
|
|
|
+ .dynamic = true,
|
|
|
+ };
|
|
|
+ gpus[i] = (struct cgpu_info){
|
|
|
+ .device_data = data,
|
|
|
+ };
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
static
|
|
|
const char *_set_list(char * const arg, const char * const emsg, bool (*set_func)(struct cgpu_info *, const char *))
|
|
|
@@ -326,7 +333,8 @@ bool _set_ ## PNAME (struct cgpu_info * const cgpu, const char * const _val) \
|
|
|
const int v = atoi(_val); \
|
|
|
if (!(VCHECK)) \
|
|
|
return false; \
|
|
|
- cgpu->FIELD = v; \
|
|
|
+ struct opencl_device_data * const data = cgpu->device_data; \
|
|
|
+ data->FIELD = v; \
|
|
|
return true; \
|
|
|
} \
|
|
|
const char *set_ ## PNAME(char *arg) \
|
|
|
@@ -370,7 +378,8 @@ bool _set_kernel(struct cgpu_info * const cgpu, const char * const _val)
|
|
|
const enum cl_kernels kern = select_kernel(_val);
|
|
|
if (kern == KL_NONE)
|
|
|
return false;
|
|
|
- cgpu->kernel = kern;
|
|
|
+ struct opencl_device_data * const data = cgpu->device_data;
|
|
|
+ data->kernel = kern;
|
|
|
return true;
|
|
|
}
|
|
|
const char *set_kernel(char *arg)
|
|
|
@@ -386,6 +395,7 @@ const char *set_kernel(char *arg)
|
|
|
* simple enumeration has failed to match them. */
|
|
|
char *set_gpu_map(char *arg)
|
|
|
{
|
|
|
+ struct opencl_device_data *data;
|
|
|
int val1 = 0, val2 = 0;
|
|
|
char *nextptr;
|
|
|
|
|
|
@@ -397,16 +407,18 @@ char *set_gpu_map(char *arg)
|
|
|
if (val1 < 0 || val1 > MAX_GPUDEVICES || val2 < 0 || val2 > MAX_GPUDEVICES)
|
|
|
return "Invalid value passed to set_gpu_map";
|
|
|
|
|
|
- gpus[val1].virtual_adl = val2;
|
|
|
- gpus[val1].mapped = true;
|
|
|
+ data = gpus[val1].device_data;
|
|
|
+ data->virtual_adl = val2;
|
|
|
+ data->mapped = true;
|
|
|
|
|
|
while ((nextptr = strtok(NULL, ",")) != NULL) {
|
|
|
if (sscanf(nextptr, "%d:%d", &val1, &val2) != 2)
|
|
|
return "Invalid description for map pair";
|
|
|
if (val1 < 0 || val1 > MAX_GPUDEVICES || val2 < 0 || val2 > MAX_GPUDEVICES)
|
|
|
return "Invalid value passed to set_gpu_map";
|
|
|
- gpus[val1].virtual_adl = val2;
|
|
|
- gpus[val1].mapped = true;
|
|
|
+ data = gpus[val1].device_data;
|
|
|
+ data->virtual_adl = val2;
|
|
|
+ data->mapped = true;
|
|
|
}
|
|
|
|
|
|
return NULL;
|
|
|
@@ -419,8 +431,9 @@ bool _set_gpu_engine(struct cgpu_info * const cgpu, const char * const _val)
|
|
|
get_intrange(_val, &val1, &val2);
|
|
|
if (val1 < 0 || val1 > 9999 || val2 < 0 || val2 > 9999)
|
|
|
return false;
|
|
|
- cgpu->min_engine = val1;
|
|
|
- cgpu->gpu_engine = val2;
|
|
|
+ struct opencl_device_data * const data = cgpu->device_data;
|
|
|
+ data->min_engine = val1;
|
|
|
+ data->gpu_engine = val2;
|
|
|
return true;
|
|
|
}
|
|
|
const char *set_gpu_engine(char *arg)
|
|
|
@@ -435,8 +448,9 @@ bool _set_gpu_fan(struct cgpu_info * const cgpu, const char * const _val)
|
|
|
get_intrange(_val, &val1, &val2);
|
|
|
if (val1 < 0 || val1 > 100 || val2 < 0 || val2 > 100)
|
|
|
return false;
|
|
|
- cgpu->min_fan = val1;
|
|
|
- cgpu->gpu_fan = val2;
|
|
|
+ struct opencl_device_data * const data = cgpu->device_data;
|
|
|
+ data->min_fan = val1;
|
|
|
+ data->gpu_fan = val2;
|
|
|
return true;
|
|
|
}
|
|
|
const char *set_gpu_fan(char *arg)
|
|
|
@@ -455,15 +469,16 @@ _SET_INT_LIST(temp_overheat, (v >= 0 && v < 200), adl.overtemp )
|
|
|
static
|
|
|
bool _set_intensity(struct cgpu_info * const cgpu, const char * const _val)
|
|
|
{
|
|
|
+ struct opencl_device_data * const data = cgpu->device_data;
|
|
|
if (!strncasecmp(_val, "d", 1))
|
|
|
- cgpu->dynamic = true;
|
|
|
+ data->dynamic = true;
|
|
|
else
|
|
|
{
|
|
|
const int v = atoi(_val);
|
|
|
if (v < MIN_INTENSITY || v > MAX_GPU_INTENSITY)
|
|
|
return false;
|
|
|
- cgpu->dynamic = false;
|
|
|
- cgpu->intensity = v;
|
|
|
+ data->dynamic = false;
|
|
|
+ data->intensity = v;
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
@@ -473,6 +488,153 @@ const char *set_intensity(char *arg)
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
+void write_config_opencl(FILE * const fcfg)
|
|
|
+{
|
|
|
+ int i;
|
|
|
+#ifdef HAVE_OPENCL
|
|
|
+ if (nDevs) {
|
|
|
+ /* Write GPU device values */
|
|
|
+ fputs(",\n\"intensity\" : \"", fcfg);
|
|
|
+ for(i = 0; i < nDevs; i++)
|
|
|
+ {
|
|
|
+ struct cgpu_info * const cgpu = &gpus[i];
|
|
|
+ struct opencl_device_data * const data = cgpu->device_data;
|
|
|
+ if (i > 0)
|
|
|
+ fputc(',', fcfg);
|
|
|
+ if (data->dynamic)
|
|
|
+ fputc('d', fcfg);
|
|
|
+ else
|
|
|
+ fprintf(fcfg, "%d", data->intensity);
|
|
|
+ }
|
|
|
+ fputs("\",\n\"vectors\" : \"", fcfg);
|
|
|
+ for(i = 0; i < nDevs; i++)
|
|
|
+ {
|
|
|
+ struct cgpu_info * const cgpu = &gpus[i];
|
|
|
+ struct opencl_device_data * const data = cgpu->device_data;
|
|
|
+ fprintf(fcfg, "%s%d", i > 0 ? "," : "",
|
|
|
+ data->vwidth);
|
|
|
+ }
|
|
|
+ fputs("\",\n\"worksize\" : \"", fcfg);
|
|
|
+ for(i = 0; i < nDevs; i++)
|
|
|
+ {
|
|
|
+ struct cgpu_info * const cgpu = &gpus[i];
|
|
|
+ struct opencl_device_data * const data = cgpu->device_data;
|
|
|
+ fprintf(fcfg, "%s%d", i > 0 ? "," : "",
|
|
|
+ (int)data->work_size);
|
|
|
+ }
|
|
|
+ fputs("\",\n\"kernel\" : \"", fcfg);
|
|
|
+ for(i = 0; i < nDevs; i++) {
|
|
|
+ struct cgpu_info * const cgpu = &gpus[i];
|
|
|
+ struct opencl_device_data * const data = cgpu->device_data;
|
|
|
+ fprintf(fcfg, "%s", i > 0 ? "," : "");
|
|
|
+ switch (data->kernel) {
|
|
|
+ case KL_NONE: // Shouldn't happen
|
|
|
+ break;
|
|
|
+ case KL_POCLBM:
|
|
|
+ fprintf(fcfg, "poclbm");
|
|
|
+ break;
|
|
|
+ case KL_PHATK:
|
|
|
+ fprintf(fcfg, "phatk");
|
|
|
+ break;
|
|
|
+ case KL_DIAKGCN:
|
|
|
+ fprintf(fcfg, "diakgcn");
|
|
|
+ break;
|
|
|
+ case KL_DIABLO:
|
|
|
+ fprintf(fcfg, "diablo");
|
|
|
+ break;
|
|
|
+ case KL_SCRYPT:
|
|
|
+ fprintf(fcfg, "scrypt");
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+#ifdef USE_SCRYPT
|
|
|
+ fputs("\",\n\"lookup-gap\" : \"", fcfg);
|
|
|
+ for(i = 0; i < nDevs; i++)
|
|
|
+ {
|
|
|
+ struct cgpu_info * const cgpu = &gpus[i];
|
|
|
+ struct opencl_device_data * const data = cgpu->device_data;
|
|
|
+ fprintf(fcfg, "%s%d", i > 0 ? "," : "",
|
|
|
+ (int)data->opt_lg);
|
|
|
+ }
|
|
|
+ fputs("\",\n\"thread-concurrency\" : \"", fcfg);
|
|
|
+ for(i = 0; i < nDevs; i++)
|
|
|
+ {
|
|
|
+ struct cgpu_info * const cgpu = &gpus[i];
|
|
|
+ struct opencl_device_data * const data = cgpu->device_data;
|
|
|
+ fprintf(fcfg, "%s%d", i > 0 ? "," : "",
|
|
|
+ (int)data->opt_tc);
|
|
|
+ }
|
|
|
+ fputs("\",\n\"shaders\" : \"", fcfg);
|
|
|
+ for(i = 0; i < nDevs; i++)
|
|
|
+ {
|
|
|
+ struct cgpu_info * const cgpu = &gpus[i];
|
|
|
+ struct opencl_device_data * const data = cgpu->device_data;
|
|
|
+ fprintf(fcfg, "%s%d", i > 0 ? "," : "",
|
|
|
+ (int)data->shaders);
|
|
|
+ }
|
|
|
+#endif
|
|
|
+#ifdef HAVE_ADL
|
|
|
+ fputs("\",\n\"gpu-engine\" : \"", fcfg);
|
|
|
+ for(i = 0; i < nDevs; i++)
|
|
|
+ {
|
|
|
+ struct cgpu_info * const cgpu = &gpus[i];
|
|
|
+ struct opencl_device_data * const data = cgpu->device_data;
|
|
|
+ fprintf(fcfg, "%s%d-%d", i > 0 ? "," : "",
|
|
|
+ data->min_engine, data->gpu_engine);
|
|
|
+ }
|
|
|
+ fputs("\",\n\"gpu-fan\" : \"", fcfg);
|
|
|
+ for(i = 0; i < nDevs; i++)
|
|
|
+ {
|
|
|
+ struct cgpu_info * const cgpu = &gpus[i];
|
|
|
+ struct opencl_device_data * const data = cgpu->device_data;
|
|
|
+ fprintf(fcfg, "%s%d-%d", i > 0 ? "," : "",
|
|
|
+ data->min_fan, data->gpu_fan);
|
|
|
+ }
|
|
|
+ fputs("\",\n\"gpu-memclock\" : \"", fcfg);
|
|
|
+ for(i = 0; i < nDevs; i++)
|
|
|
+ {
|
|
|
+ struct cgpu_info * const cgpu = &gpus[i];
|
|
|
+ struct opencl_device_data * const data = cgpu->device_data;
|
|
|
+ fprintf(fcfg, "%s%d", i > 0 ? "," : "", data->gpu_memclock);
|
|
|
+ }
|
|
|
+ fputs("\",\n\"gpu-memdiff\" : \"", fcfg);
|
|
|
+ for(i = 0; i < nDevs; i++)
|
|
|
+ {
|
|
|
+ struct cgpu_info * const cgpu = &gpus[i];
|
|
|
+ struct opencl_device_data * const data = cgpu->device_data;
|
|
|
+ fprintf(fcfg, "%s%d", i > 0 ? "," : "", data->gpu_memdiff);
|
|
|
+ }
|
|
|
+ fputs("\",\n\"gpu-powertune\" : \"", fcfg);
|
|
|
+ for(i = 0; i < nDevs; i++)
|
|
|
+ {
|
|
|
+ struct cgpu_info * const cgpu = &gpus[i];
|
|
|
+ struct opencl_device_data * const data = cgpu->device_data;
|
|
|
+ fprintf(fcfg, "%s%d", i > 0 ? "," : "", data->gpu_powertune);
|
|
|
+ }
|
|
|
+ fputs("\",\n\"gpu-vddc\" : \"", fcfg);
|
|
|
+ for(i = 0; i < nDevs; i++)
|
|
|
+ {
|
|
|
+ struct cgpu_info * const cgpu = &gpus[i];
|
|
|
+ struct opencl_device_data * const data = cgpu->device_data;
|
|
|
+ fprintf(fcfg, "%s%1.3f", i > 0 ? "," : "", data->gpu_vddc);
|
|
|
+ }
|
|
|
+ fputs("\",\n\"temp-overheat\" : \"", fcfg);
|
|
|
+ for(i = 0; i < nDevs; i++)
|
|
|
+ {
|
|
|
+ struct cgpu_info * const cgpu = &gpus[i];
|
|
|
+ struct opencl_device_data * const data = cgpu->device_data;
|
|
|
+ fprintf(fcfg, "%s%d", i > 0 ? "," : "", data->adl.overtemp);
|
|
|
+ }
|
|
|
+#endif
|
|
|
+ fputs("\"", fcfg);
|
|
|
+ }
|
|
|
+#endif
|
|
|
+#ifdef HAVE_ADL
|
|
|
+ if (opt_reorder)
|
|
|
+ fprintf(fcfg, ",\n\"gpu-reorder\" : true");
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
|
|
|
#ifdef HAVE_OPENCL
|
|
|
BFG_REGISTER_DRIVER(opencl_api)
|
|
|
@@ -501,19 +663,20 @@ struct cgpu_info *cpus;
|
|
|
void pause_dynamic_threads(int gpu)
|
|
|
{
|
|
|
struct cgpu_info *cgpu = &gpus[gpu];
|
|
|
+ struct opencl_device_data * const data = cgpu->device_data;
|
|
|
int i;
|
|
|
|
|
|
for (i = 1; i < cgpu->threads; i++) {
|
|
|
struct thr_info *thr;
|
|
|
|
|
|
thr = cgpu->thr[i];
|
|
|
- if (!thr->pause && cgpu->dynamic) {
|
|
|
+ if (!thr->pause && data->dynamic) {
|
|
|
applog(LOG_WARNING, "Disabling extra threads due to dynamic mode.");
|
|
|
applog(LOG_WARNING, "Tune dynamic intensity with --gpu-dyninterval");
|
|
|
}
|
|
|
|
|
|
- thr->pause = cgpu->dynamic;
|
|
|
- if (!cgpu->dynamic && cgpu->deven != DEV_DISABLED)
|
|
|
+ thr->pause = data->dynamic;
|
|
|
+ if (!data->dynamic && cgpu->deven != DEV_DISABLED)
|
|
|
mt_enable(thr);
|
|
|
}
|
|
|
}
|
|
|
@@ -527,6 +690,7 @@ struct device_drv opencl_api;
|
|
|
static
|
|
|
void opencl_wlogprint_status(struct cgpu_info *cgpu)
|
|
|
{
|
|
|
+ struct opencl_device_data * const data = cgpu->device_data;
|
|
|
struct thr_info *thr;
|
|
|
int i;
|
|
|
char checkin[40];
|
|
|
@@ -535,9 +699,9 @@ void opencl_wlogprint_status(struct cgpu_info *cgpu)
|
|
|
char logline[255];
|
|
|
strcpy(logline, ""); // In case it has no data
|
|
|
|
|
|
- tailsprintf(logline, sizeof(logline), "I:%s%d ", (cgpu->dynamic ? "d" : ""), cgpu->intensity);
|
|
|
+ tailsprintf(logline, sizeof(logline), "I:%s%d ", (data->dynamic ? "d" : ""), data->intensity);
|
|
|
#ifdef HAVE_ADL
|
|
|
- if (cgpu->has_adl) {
|
|
|
+ if (data->has_adl) {
|
|
|
int engineclock = 0, memclock = 0, activity = 0, fanspeed = 0, fanpercent = 0, powertune = 0;
|
|
|
float temp = 0, vddc = 0;
|
|
|
|
|
|
@@ -611,7 +775,8 @@ void opencl_tui_wlogprint_choices(struct cgpu_info *cgpu)
|
|
|
{
|
|
|
wlogprint("[I]ntensity [R]estart GPU ");
|
|
|
#ifdef HAVE_ADL
|
|
|
- if (cgpu->has_adl)
|
|
|
+ struct opencl_device_data * const data = cgpu->device_data;
|
|
|
+ if (data->has_adl)
|
|
|
wlogprint("[C]hange settings ");
|
|
|
#endif
|
|
|
}
|
|
|
@@ -619,6 +784,8 @@ void opencl_tui_wlogprint_choices(struct cgpu_info *cgpu)
|
|
|
static
|
|
|
const char *opencl_tui_handle_choice(struct cgpu_info *cgpu, int input)
|
|
|
{
|
|
|
+ struct opencl_device_data * const data = cgpu->device_data;
|
|
|
+
|
|
|
switch (input)
|
|
|
{
|
|
|
case 'i': case 'I':
|
|
|
@@ -638,7 +805,7 @@ const char *opencl_tui_handle_choice(struct cgpu_info *cgpu, int input)
|
|
|
if (!intvar)
|
|
|
return "Invalid intensity\n";
|
|
|
if (!strncasecmp(intvar, "d", 1)) {
|
|
|
- cgpu->dynamic = true;
|
|
|
+ data->dynamic = true;
|
|
|
pause_dynamic_threads(cgpu->device_id);
|
|
|
free(intvar);
|
|
|
return "Dynamic mode enabled\n";
|
|
|
@@ -647,8 +814,8 @@ const char *opencl_tui_handle_choice(struct cgpu_info *cgpu, int input)
|
|
|
free(intvar);
|
|
|
if (intensity < MIN_INTENSITY || intensity > MAX_INTENSITY)
|
|
|
return "Invalid intensity (out of range)\n";
|
|
|
- cgpu->dynamic = false;
|
|
|
- cgpu->intensity = intensity;
|
|
|
+ data->dynamic = false;
|
|
|
+ data->intensity = intensity;
|
|
|
pause_dynamic_threads(cgpu->device_id);
|
|
|
return "Intensity changed\n";
|
|
|
}
|
|
|
@@ -683,8 +850,18 @@ static _clState *clStates[MAX_GPUDEVICES];
|
|
|
#define CL_SET_ARG(var) status |= clSetKernelArg(*kernel, num++, sizeof(var), (void *)&var)
|
|
|
#define CL_SET_VARG(args, var) status |= clSetKernelArg(*kernel, num++, args * sizeof(uint), (void *)var)
|
|
|
|
|
|
-static cl_int queue_poclbm_kernel(_clState *clState, dev_blk_ctx *blk, cl_uint threads)
|
|
|
+static
|
|
|
+struct opencl_work_data *_opencl_work_data(struct work * const work)
|
|
|
{
|
|
|
+ if (work->device_data)
|
|
|
+ return work->device_data;
|
|
|
+ return (work->device_data = calloc(1, sizeof(struct opencl_work_data)));
|
|
|
+}
|
|
|
+
|
|
|
+static
|
|
|
+cl_int queue_poclbm_kernel(_clState * const clState, struct work * const work, const cl_uint threads)
|
|
|
+{
|
|
|
+ struct opencl_work_data * const blk = _opencl_work_data(work);
|
|
|
cl_kernel *kernel = &clState->kernel;
|
|
|
unsigned int num = 0;
|
|
|
cl_int status = 0;
|
|
|
@@ -712,7 +889,7 @@ static cl_int queue_poclbm_kernel(_clState *clState, dev_blk_ctx *blk, cl_uint t
|
|
|
unsigned int i;
|
|
|
|
|
|
for (i = 0; i < vwidth; i++)
|
|
|
- nonces[i] = blk->nonce + (i * threads);
|
|
|
+ nonces[i] = work->blk.nonce + (i * threads);
|
|
|
CL_SET_VARG(vwidth, nonces);
|
|
|
}
|
|
|
|
|
|
@@ -736,9 +913,10 @@ static cl_int queue_poclbm_kernel(_clState *clState, dev_blk_ctx *blk, cl_uint t
|
|
|
return status;
|
|
|
}
|
|
|
|
|
|
-static cl_int queue_phatk_kernel(_clState *clState, dev_blk_ctx *blk,
|
|
|
- __maybe_unused cl_uint threads)
|
|
|
+static
|
|
|
+cl_int queue_phatk_kernel(_clState * const clState, struct work * const work, __maybe_unused const cl_uint threads)
|
|
|
{
|
|
|
+ struct opencl_work_data * const blk = _opencl_work_data(work);
|
|
|
cl_kernel *kernel = &clState->kernel;
|
|
|
cl_uint vwidth = clState->vwidth;
|
|
|
unsigned int i, num = 0;
|
|
|
@@ -763,7 +941,7 @@ static cl_int queue_phatk_kernel(_clState *clState, dev_blk_ctx *blk,
|
|
|
|
|
|
nonces = alloca(sizeof(uint) * vwidth);
|
|
|
for (i = 0; i < vwidth; i++)
|
|
|
- nonces[i] = blk->nonce + i;
|
|
|
+ nonces[i] = work->blk.nonce + i;
|
|
|
CL_SET_VARG(vwidth, nonces);
|
|
|
|
|
|
CL_SET_BLKARG(W16);
|
|
|
@@ -780,9 +958,10 @@ static cl_int queue_phatk_kernel(_clState *clState, dev_blk_ctx *blk,
|
|
|
return status;
|
|
|
}
|
|
|
|
|
|
-static cl_int queue_diakgcn_kernel(_clState *clState, dev_blk_ctx *blk,
|
|
|
- __maybe_unused cl_uint threads)
|
|
|
+static
|
|
|
+cl_int queue_diakgcn_kernel(_clState * const clState, struct work * const work, __maybe_unused const cl_uint threads)
|
|
|
{
|
|
|
+ struct opencl_work_data * const blk = _opencl_work_data(work);
|
|
|
cl_kernel *kernel = &clState->kernel;
|
|
|
unsigned int num = 0;
|
|
|
cl_int status = 0;
|
|
|
@@ -792,7 +971,7 @@ static cl_int queue_diakgcn_kernel(_clState *clState, dev_blk_ctx *blk,
|
|
|
uint *nonces = alloca(sizeof(uint) * vwidth);
|
|
|
unsigned int i;
|
|
|
for (i = 0; i < vwidth; i++)
|
|
|
- nonces[i] = blk->nonce + i;
|
|
|
+ nonces[i] = work->blk.nonce + i;
|
|
|
CL_SET_VARG(vwidth, nonces);
|
|
|
}
|
|
|
|
|
|
@@ -841,8 +1020,10 @@ static cl_int queue_diakgcn_kernel(_clState *clState, dev_blk_ctx *blk,
|
|
|
return status;
|
|
|
}
|
|
|
|
|
|
-static cl_int queue_diablo_kernel(_clState *clState, dev_blk_ctx *blk, cl_uint threads)
|
|
|
+static
|
|
|
+cl_int queue_diablo_kernel(_clState * const clState, struct work * const work, const cl_uint threads)
|
|
|
{
|
|
|
+ struct opencl_work_data * const blk = _opencl_work_data(work);
|
|
|
cl_kernel *kernel = &clState->kernel;
|
|
|
unsigned int num = 0;
|
|
|
cl_int status = 0;
|
|
|
@@ -853,7 +1034,7 @@ static cl_int queue_diablo_kernel(_clState *clState, dev_blk_ctx *blk, cl_uint t
|
|
|
unsigned int i;
|
|
|
|
|
|
for (i = 0; i < vwidth; i++)
|
|
|
- nonces[i] = blk->nonce + (i * threads);
|
|
|
+ nonces[i] = work->blk.nonce + (i * threads);
|
|
|
CL_SET_VARG(vwidth, nonces);
|
|
|
}
|
|
|
|
|
|
@@ -895,16 +1076,17 @@ static cl_int queue_diablo_kernel(_clState *clState, dev_blk_ctx *blk, cl_uint t
|
|
|
}
|
|
|
|
|
|
#ifdef USE_SCRYPT
|
|
|
-static cl_int queue_scrypt_kernel(_clState *clState, dev_blk_ctx *blk, __maybe_unused cl_uint threads)
|
|
|
+static
|
|
|
+cl_int queue_scrypt_kernel(_clState * const clState, struct work * const work, __maybe_unused const cl_uint threads)
|
|
|
{
|
|
|
- unsigned char *midstate = blk->work->midstate;
|
|
|
+ unsigned char *midstate = work->midstate;
|
|
|
cl_kernel *kernel = &clState->kernel;
|
|
|
unsigned int num = 0;
|
|
|
cl_uint le_target;
|
|
|
cl_int status = 0;
|
|
|
|
|
|
- le_target = *(cl_uint *)(blk->work->target + 28);
|
|
|
- clState->cldata = blk->work->data;
|
|
|
+ le_target = *(cl_uint *)(work->target + 28);
|
|
|
+ clState->cldata = work->data;
|
|
|
status = clEnqueueWriteBuffer(clState->commandQueue, clState->CLbuffer0, true, 0, 80, clState->cldata, 0, NULL,NULL);
|
|
|
|
|
|
CL_SET_ARG(clState->CLbuffer0);
|
|
|
@@ -962,6 +1144,8 @@ select_cgpu:
|
|
|
cgpu = tq_pop(mythr->q, NULL);
|
|
|
if (!cgpu)
|
|
|
goto out;
|
|
|
+
|
|
|
+ struct opencl_device_data * const data = cgpu->device_data;
|
|
|
|
|
|
if (clDevicesNum() != nDevs) {
|
|
|
applog(LOG_WARNING, "Hardware not reporting same number of active devices, will not attempt to restart GPU");
|
|
|
@@ -989,7 +1173,7 @@ select_cgpu:
|
|
|
thr = cgpu->thr[i];
|
|
|
thr_id = thr->id;
|
|
|
|
|
|
- virtual_gpu = cgpu->virtual_gpu;
|
|
|
+ virtual_gpu = data->virtual_gpu;
|
|
|
/* Lose this ram cause we may get stuck here! */
|
|
|
//tq_freeze(thr->q);
|
|
|
|
|
|
@@ -1072,7 +1256,6 @@ static int opencl_autodetect()
|
|
|
}
|
|
|
|
|
|
#ifdef HAVE_SENSORS
|
|
|
- struct opencl_device_data *data;
|
|
|
const sensors_chip_name *cn;
|
|
|
int c = 0;
|
|
|
|
|
|
@@ -1086,19 +1269,18 @@ static int opencl_autodetect()
|
|
|
struct cgpu_info *cgpu;
|
|
|
|
|
|
cgpu = &gpus[i];
|
|
|
+ struct opencl_device_data * const data = cgpu->device_data;
|
|
|
+
|
|
|
cgpu->devtype = "GPU";
|
|
|
cgpu->deven = DEV_ENABLED;
|
|
|
cgpu->drv = &opencl_api;
|
|
|
cgpu->device_id = i;
|
|
|
cgpu->threads = opt_g_threads;
|
|
|
- cgpu->virtual_gpu = i;
|
|
|
+ data->virtual_gpu = i;
|
|
|
|
|
|
#ifdef HAVE_SENSORS
|
|
|
cn = (c == -1) ? NULL : sensors_get_detected_chips(&cnm, &c);
|
|
|
- cgpu->device_data = data = malloc(sizeof(*data));
|
|
|
- *data = (struct opencl_device_data){
|
|
|
- .sensor = cn,
|
|
|
- };
|
|
|
+ data->sensor = cn;
|
|
|
#endif
|
|
|
|
|
|
add_cgpu(cgpu);
|
|
|
@@ -1120,6 +1302,15 @@ static void opencl_detect()
|
|
|
|
|
|
static void reinit_opencl_device(struct cgpu_info *gpu)
|
|
|
{
|
|
|
+#ifdef HAVE_ADL
|
|
|
+ struct opencl_device_data * const data = gpu->device_data;
|
|
|
+ if (adl_active && data->has_adl && gpu_activity(gpu->device_id) > 50)
|
|
|
+ {
|
|
|
+ applogr(, LOG_ERR, "%s: Still showing activity (suggests a hard hang); cancelling reinitialise.",
|
|
|
+ gpu->dev_repr);
|
|
|
+ }
|
|
|
+#endif
|
|
|
+
|
|
|
tq_push(control_thr[gpur_thr_id].q, gpu);
|
|
|
}
|
|
|
|
|
|
@@ -1127,8 +1318,8 @@ static void reinit_opencl_device(struct cgpu_info *gpu)
|
|
|
static
|
|
|
bool override_opencl_statline_temp(char *buf, size_t bufsz, struct cgpu_info *gpu, __maybe_unused bool per_processor)
|
|
|
{
|
|
|
+ __maybe_unused struct opencl_device_data * const data = gpu->device_data;
|
|
|
#ifdef HAVE_SENSORS
|
|
|
- struct opencl_device_data *data = gpu->device_data;
|
|
|
if (data->sensor)
|
|
|
{
|
|
|
const sensors_chip_name *cn = data->sensor;
|
|
|
@@ -1151,7 +1342,7 @@ bool override_opencl_statline_temp(char *buf, size_t bufsz, struct cgpu_info *gp
|
|
|
}
|
|
|
#endif
|
|
|
#ifdef HAVE_ADL
|
|
|
- if (gpu->has_adl) {
|
|
|
+ if (data->has_adl) {
|
|
|
int gpuid = gpu->device_id;
|
|
|
gpu_temp(gpuid);
|
|
|
gpu_fanspeed(gpuid);
|
|
|
@@ -1160,9 +1351,31 @@ bool override_opencl_statline_temp(char *buf, size_t bufsz, struct cgpu_info *gp
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
+static
|
|
|
+void opencl_watchdog(struct cgpu_info * const cgpu, __maybe_unused const struct timeval * const tv_now)
|
|
|
+{
|
|
|
+#ifdef HAVE_ADL
|
|
|
+ struct opencl_device_data * const data = cgpu->device_data;
|
|
|
+ const int gpu = cgpu->device_id;
|
|
|
+ enum dev_enable *denable = &cgpu->deven;
|
|
|
+
|
|
|
+ if (adl_active && data->has_adl)
|
|
|
+ gpu_autotune(gpu, denable);
|
|
|
+ if (opt_debug && data->has_adl) {
|
|
|
+ int engineclock = 0, memclock = 0, activity = 0, fanspeed = 0, fanpercent = 0, powertune = 0;
|
|
|
+ float temp = 0, vddc = 0;
|
|
|
+
|
|
|
+ if (gpu_stats(gpu, &temp, &engineclock, &memclock, &vddc, &activity, &fanspeed, &fanpercent, &powertune))
|
|
|
+ applog(LOG_DEBUG, "%.1f C F: %d%%(%dRPM) E: %dMHz M: %dMHz V: %.3fV A: %d%% P: %d%%",
|
|
|
+ temp, fanpercent, fanspeed, engineclock, memclock, vddc, activity, powertune);
|
|
|
+ }
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
static struct api_data*
|
|
|
get_opencl_api_extra_device_status(struct cgpu_info *gpu)
|
|
|
{
|
|
|
+ struct opencl_device_data * const data = gpu->device_data;
|
|
|
struct api_data*root = NULL;
|
|
|
|
|
|
float gt, gv;
|
|
|
@@ -1180,17 +1393,17 @@ get_opencl_api_extra_device_status(struct cgpu_info *gpu)
|
|
|
root = api_add_int(root, "Powertune", &pt, true);
|
|
|
|
|
|
char intensity[20];
|
|
|
- if (gpu->dynamic)
|
|
|
+ if (data->dynamic)
|
|
|
strcpy(intensity, "D");
|
|
|
else
|
|
|
- sprintf(intensity, "%d", gpu->intensity);
|
|
|
+ sprintf(intensity, "%d", data->intensity);
|
|
|
root = api_add_string(root, "Intensity", intensity, true);
|
|
|
|
|
|
return root;
|
|
|
}
|
|
|
|
|
|
struct opencl_thread_data {
|
|
|
- cl_int (*queue_kernel_parameters)(_clState *, dev_blk_ctx *, cl_uint);
|
|
|
+ cl_int (*queue_kernel_parameters)(_clState *, struct work *, cl_uint);
|
|
|
uint32_t *res;
|
|
|
};
|
|
|
|
|
|
@@ -1200,8 +1413,9 @@ static bool opencl_thread_prepare(struct thr_info *thr)
|
|
|
{
|
|
|
char name[256];
|
|
|
struct cgpu_info *cgpu = thr->cgpu;
|
|
|
+ struct opencl_device_data * const data = cgpu->device_data;
|
|
|
int gpu = cgpu->device_id;
|
|
|
- int virtual_gpu = cgpu->virtual_gpu;
|
|
|
+ int virtual_gpu = data->virtual_gpu;
|
|
|
int i = thr->id;
|
|
|
static bool failmessage = false;
|
|
|
int buffersize = opt_scrypt ? SCRYPT_BUFFERSIZE : BUFFERSIZE;
|
|
|
@@ -1340,11 +1554,12 @@ static bool opencl_thread_init(struct thr_info *thr)
|
|
|
static bool opencl_prepare_work(struct thr_info __maybe_unused *thr, struct work *work)
|
|
|
{
|
|
|
#ifdef USE_SCRYPT
|
|
|
- if (opt_scrypt)
|
|
|
- work->blk.work = work;
|
|
|
- else
|
|
|
+ if (!opt_scrypt)
|
|
|
#endif
|
|
|
- precalc_hash(&work->blk, (uint32_t *)(work->midstate), (uint32_t *)(work->data + 64));
|
|
|
+ {
|
|
|
+ struct opencl_work_data * const blk = _opencl_work_data(work);
|
|
|
+ precalc_hash(blk, (uint32_t *)(work->midstate), (uint32_t *)(work->data + 64));
|
|
|
+ }
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
@@ -1356,6 +1571,7 @@ static int64_t opencl_scanhash(struct thr_info *thr, struct work *work,
|
|
|
const int thr_id = thr->id;
|
|
|
struct opencl_thread_data *thrdata = thr->cgpu_data;
|
|
|
struct cgpu_info *gpu = thr->cgpu;
|
|
|
+ struct opencl_device_data * const data = gpu->device_data;
|
|
|
_clState *clState = clStates[thr_id];
|
|
|
const cl_kernel *kernel = &clState->kernel;
|
|
|
const int dynamic_us = opt_dynamic_interval * 1000;
|
|
|
@@ -1368,28 +1584,28 @@ static int64_t opencl_scanhash(struct thr_info *thr, struct work *work,
|
|
|
int buffersize = opt_scrypt ? SCRYPT_BUFFERSIZE : BUFFERSIZE;
|
|
|
|
|
|
/* Windows' timer resolution is only 15ms so oversample 5x */
|
|
|
- if (gpu->dynamic && (++gpu->intervals * dynamic_us) > 70000) {
|
|
|
+ if (data->dynamic && (++data->intervals * dynamic_us) > 70000) {
|
|
|
struct timeval tv_gpuend;
|
|
|
double gpu_us;
|
|
|
|
|
|
cgtime(&tv_gpuend);
|
|
|
- gpu_us = us_tdiff(&tv_gpuend, &gpu->tv_gpustart) / gpu->intervals;
|
|
|
+ gpu_us = us_tdiff(&tv_gpuend, &data->tv_gpustart) / data->intervals;
|
|
|
if (gpu_us > dynamic_us) {
|
|
|
- if (gpu->intensity > MIN_INTENSITY)
|
|
|
- --gpu->intensity;
|
|
|
+ if (data->intensity > MIN_INTENSITY)
|
|
|
+ --data->intensity;
|
|
|
} else if (gpu_us < dynamic_us / 2) {
|
|
|
- if (gpu->intensity < MAX_INTENSITY)
|
|
|
- ++gpu->intensity;
|
|
|
+ if (data->intensity < MAX_INTENSITY)
|
|
|
+ ++data->intensity;
|
|
|
}
|
|
|
- memcpy(&(gpu->tv_gpustart), &tv_gpuend, sizeof(struct timeval));
|
|
|
- gpu->intervals = 0;
|
|
|
+ memcpy(&(data->tv_gpustart), &tv_gpuend, sizeof(struct timeval));
|
|
|
+ data->intervals = 0;
|
|
|
}
|
|
|
|
|
|
- set_threads_hashes(clState->vwidth, &hashes, globalThreads, localThreads[0], &gpu->intensity);
|
|
|
+ set_threads_hashes(clState->vwidth, &hashes, globalThreads, localThreads[0], &data->intensity);
|
|
|
if (hashes > gpu->max_hashes)
|
|
|
gpu->max_hashes = hashes;
|
|
|
|
|
|
- status = thrdata->queue_kernel_parameters(clState, &work->blk, globalThreads[0]);
|
|
|
+ status = thrdata->queue_kernel_parameters(clState, work, globalThreads[0]);
|
|
|
if (unlikely(status != CL_SUCCESS)) {
|
|
|
applog(LOG_ERR, "Error: clSetKernelArg of all params failed.");
|
|
|
return -1;
|
|
|
@@ -1461,6 +1677,7 @@ struct device_drv opencl_api = {
|
|
|
.supported_algos = POW_SHA256D | POW_SCRYPT,
|
|
|
.drv_detect = opencl_detect,
|
|
|
.reinit_device = reinit_opencl_device,
|
|
|
+ .watchdog = opencl_watchdog,
|
|
|
.override_statline_temp2 = override_opencl_statline_temp,
|
|
|
#ifdef HAVE_CURSES
|
|
|
.proc_wlogprint_status = opencl_wlogprint_status,
|