Permalink
Browse files

Initial multi-device OpenCL support for oclvanitygen and oclvanityminer.

  • Loading branch information...
1 parent 53903a7 commit af42e55a228c1bb7a81aa8cc7b2e971236eee110 @samr7 committed Aug 17, 2012
Showing with 307 additions and 61 deletions.
  1. +96 −5 oclengine.c
  2. +5 −1 oclengine.h
  3. +52 −6 oclvanitygen.c
  4. +55 −17 oclvanityminer.c
  5. +57 −13 pattern.c
  6. +42 −19 pattern.h
View
@@ -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 */
@@ -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);
@@ -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;
@@ -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;
@@ -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;
@@ -2432,7 +2434,6 @@ get_opencl_device(int platformidx, int deviceidx)
if (did)
return did;
}
- enumerate_opencl();
return NULL;
}
@@ -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)
{
View
@@ -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__) */
View
@@ -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"
@@ -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"
@@ -71,6 +79,8 @@ usage(const char *name)
version, name);
}
+#define MAX_DEVS 32
+
int
main(int argc, char **argv)
{
@@ -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;
@@ -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,
@@ -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;
}
Oops, something went wrong.

0 comments on commit af42e55

Please sign in to comment.