Skip to content

Commit

Permalink
Initial multi-device OpenCL support for oclvanitygen and oclvanityminer.
Browse files Browse the repository at this point in the history
  • Loading branch information
samr7 committed Aug 17, 2012
1 parent 53903a7 commit af42e55
Show file tree
Hide file tree
Showing 6 changed files with 307 additions and 61 deletions.
101 changes: 96 additions & 5 deletions oclengine.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
#define round_up_pow2(x, a) (((x) + ((a)-1)) & ~((a)-1))

static void vg_ocl_free_args(vg_ocl_context_t *vocp);
static void *vg_opencl_loop(vg_exec_context_t *arg);


/* OpenCL address searching mode */
Expand Down Expand Up @@ -872,6 +873,7 @@ vg_ocl_init(vg_context_t *vcp, vg_ocl_context_t *vocp, cl_device_id did,

memset(vocp, 0, sizeof(*vocp));
vg_exec_context_init(vcp, &vocp->base);
vocp->base.vxc_threadfunc = vg_opencl_loop;

pthread_mutex_init(&vocp->voc_lock, NULL);
pthread_cond_init(&vocp->voc_wait, NULL);
Expand Down Expand Up @@ -1872,8 +1874,8 @@ vg_opencl_thread(void *arg)
* Address search thread main loop
*/

void *
vg_opencl_loop(void *arg)
static void *
vg_opencl_loop(vg_exec_context_t *arg)
{
vg_ocl_context_t *vocp = (vg_ocl_context_t *) arg;
int i;
Expand Down Expand Up @@ -2397,7 +2399,7 @@ get_platform(int num)
}

void
enumerate_opencl(void)
vg_ocl_enumerate_devices(void)
{
cl_platform_id *pids;
cl_device_id *dids;
Expand All @@ -2420,7 +2422,7 @@ enumerate_opencl(void)
}
}

cl_device_id
static cl_device_id
get_opencl_device(int platformidx, int deviceidx)
{
cl_platform_id pid;
Expand All @@ -2432,7 +2434,6 @@ get_opencl_device(int platformidx, int deviceidx)
if (did)
return did;
}
enumerate_opencl();
return NULL;
}

Expand Down Expand Up @@ -2603,6 +2604,96 @@ vg_ocl_context_new(vg_context_t *vcp,
return NULL;
}

vg_ocl_context_t *
vg_ocl_context_new_from_devstr(vg_context_t *vcp, const char *devstr,
int safemode, int verify)
{
int platformidx, deviceidx;
int worksize = 0, nthreads = 0, nrows = 0, ncols = 0, invsize = 0;

char *dsd, *part, *part2, *save, *param;

dsd = strdup(devstr);
if (!dsd)
return NULL;

save = NULL;
part = strtok_r(dsd, ",", &save);

part2 = strchr(part, ':');
if (!part2) {
fprintf(stderr, "Invalid device specifier '%s'\n", part);
free(dsd);
return NULL;
}

*part2 = '\0';
platformidx = atoi(part);
deviceidx = atoi(part2 + 1);

while ((part = strtok_r(NULL, ",", &save)) != NULL) {
param = strchr(part, '=');
if (!param) {
fprintf(stderr, "Unrecognized parameter '%s'\n", part);
continue;
}

*param = '\0';
param++;

if (!strcmp(part, "grid")) {
ncols = strtol(param, &part2, 0);
if (part2 && *part2 == 'x') {
nrows = strtol(part2+1, NULL, 0);
}
if (!nrows || !ncols) {
fprintf(stderr,
"Invalid grid size '%s'\n", param);
nrows = 0;
ncols = 0;
continue;
}
}

else if (!strcmp(part, "invsize")) {
invsize = atoi(param);
if (!invsize) {
fprintf(stderr,
"Invalid modular inverse size '%s'\n",
param);
continue;
}
if (invsize & (invsize - 1)) {
fprintf(stderr,
"Modular inverse size %d must be "
"a power of 2\n", invsize);
invsize = 0;
continue;
}
}

else if (!strcmp(part, "threads")) {
nthreads = atoi(param);
if (nthreads == 0) {
fprintf(stderr,
"Invalid thread count '%s'\n", optarg);
continue;
}
}

else {
fprintf(stderr, "Unrecognized parameter '%s'\n", part);
}
}

free(dsd);

return vg_ocl_context_new(vcp, platformidx, deviceidx, safemode,
verify, worksize, nthreads, nrows, ncols,
invsize);
}


void
vg_ocl_context_free(vg_ocl_context_t *vocp)
{
Expand Down
6 changes: 5 additions & 1 deletion oclengine.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ extern vg_ocl_context_t *vg_ocl_context_new(
int invsize);
extern void vg_ocl_context_free(vg_ocl_context_t *vocp);

extern void *vg_opencl_loop(void *vocp);
extern vg_ocl_context_t *vg_ocl_context_new_from_devstr(
vg_context_t *vcp, const char *devstr, int safemode, int verify)
;

extern void vg_ocl_enumerate_devices(void);

#endif /* !defined (__VG_OCLENGINE_H__) */
58 changes: 52 additions & 6 deletions oclvanitygen.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ usage(const char *name)
"location or imported into a bitcoin client to spend any balance received on\n"
"the address.\n"
"By default, <pattern> is interpreted as an exact prefix.\n"
"By default, if no device is specified, and the system has exactly one OpenCL\n"
"device, it will be selected automatically, otherwise if the system has\n"
"multiple OpenCL devices and no device is specified, an error will be\n"
"reported. To use multiple devices simultaneously, specify the -D option for\n"
"each device.\n"
"\n"
"Options:\n"
"-v Verbose output\n"
Expand All @@ -58,6 +63,9 @@ usage(const char *name)
"-E <password> Encrypt private keys with <password> (UNSAFE)\n"
"-p <platform> Select OpenCL platform\n"
"-d <device> Select OpenCL device\n"
"-D <devstr> Use OpenCL device, identified by device string\n"
" Form: <platform>:<devicenumber>[,<options>]\n"
" Example: 0:0,grid=1024x1024\n"
"-S Safe mode, disable OpenCL loop unrolling optimizations\n"
"-w <worksize> Set work items per thread in a work unit\n"
"-t <threads> Set target thread count per multiprocessor\n"
Expand All @@ -71,6 +79,8 @@ usage(const char *name)
version, name);
}

#define MAX_DEVS 32

int
main(int argc, char **argv)
{
Expand Down Expand Up @@ -99,9 +109,12 @@ main(int argc, char **argv)
EC_POINT *pubkey_base = NULL;
const char *result_file = NULL;
const char *key_password = NULL;
char *devstrs[MAX_DEVS];
int ndevstrs = 0;
int opened = 0;

while ((opt = getopt(argc, argv,
"vqikNTX:eE:p:P:d:w:t:g:b:VSh?f:o:s:")) != -1) {
"vqikNTX:eE:p:P:d:w:t:g:b:VSh?f:o:s:D:")) != -1) {
switch (opt) {
case 'v':
verbose = 2;
Expand Down Expand Up @@ -188,6 +201,15 @@ main(int argc, char **argv)
case 'S':
safe_mode = 1;
break;
case 'D':
if (ndevstrs >= MAX_DEVS) {
fprintf(stderr,
"Too many OpenCL devices (limit %d)\n",
MAX_DEVS);
return 1;
}
devstrs[ndevstrs++] = optarg;
break;
case 'P': {
if (pubkey_base != NULL) {
fprintf(stderr,
Expand Down Expand Up @@ -338,14 +360,38 @@ main(int argc, char **argv)
fprintf(stderr,
"Regular expressions: %ld\n", vcp->vc_npatterns);

vocp = vg_ocl_context_new(vcp, platformidx, deviceidx,
safe_mode, verify_mode,
worksize, nthreads, nrows, ncols, invsize);
if (!vocp) {
if (ndevstrs) {
for (opt = 0; opt < ndevstrs; opt++) {
vocp = vg_ocl_context_new_from_devstr(vcp, devstrs[opt],
safe_mode,
verify_mode);
if (!vocp) {
fprintf(stderr,
"Could not open device '%s', ignoring\n",
devstrs[opt]);
} else {
opened++;
}
}
} else {
vocp = vg_ocl_context_new(vcp, platformidx, deviceidx,
safe_mode, verify_mode,
worksize, nthreads,
nrows, ncols, invsize);
if (vocp)
opened++;
}

if (!opened) {
vg_ocl_enumerate_devices();
return 1;
}

vg_opencl_loop(vocp);
opt = vg_context_start_threads(vcp);
if (opt)
return 1;

vg_context_wait_for_completion(vcp);
vg_ocl_context_free(vocp);
return 0;
}
Loading

0 comments on commit af42e55

Please sign in to comment.