diff --git a/algorithm.c b/algorithm.c index c823d1c5..b39b0bc3 100644 --- a/algorithm.c +++ b/algorithm.c @@ -8,30 +8,185 @@ */ #include "algorithm.h" +#include "sha2.h" +#include "ocl.h" + +#include "scrypt.h" +#include "animecoin.h" +#include "inkcoin.h" +#include "quarkcoin.h" +#include "qubitcoin.h" +#include "sifcoin.h" +#include "darkcoin.h" +#include "myriadcoin-groestl.h" +#include "fuguecoin.h" +#include "groestlcoin.h" +#include "twecoin.h" +#include "marucoin.h" #include #include -void set_algorithm(algorithm_t* algo, const char* newname) { - strncpy(algo->name, newname, sizeof(algo->name)); - algo->name[sizeof(algo->name) - 1] = '\0'; +void gen_hash(const unsigned char *data, unsigned int len, unsigned char *hash) +{ + unsigned char hash1[32]; + + sha256(data, len, hash1); + sha256(hash1, 32, hash); +} + +#define CL_SET_BLKARG(blkvar) status |= clSetKernelArg(*kernel, num++, sizeof(uint), (void *)&blk->blkvar) +#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_scrypt_kernel(struct __clState *clState, struct _dev_blk_ctx *blk, __maybe_unused cl_uint threads) +{ + unsigned char *midstate = blk->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->device_target + 28); + memcpy(clState->cldata, blk->work->data, 80); + status = clEnqueueWriteBuffer(clState->commandQueue, clState->CLbuffer0, true, 0, 80, clState->cldata, 0, NULL,NULL); + + CL_SET_ARG(clState->CLbuffer0); + CL_SET_ARG(clState->outputBuffer); + CL_SET_ARG(clState->padbuffer8); + CL_SET_VARG(4, &midstate[0]); + CL_SET_VARG(4, &midstate[16]); + CL_SET_ARG(le_target); + + return status; +} + +static cl_int queue_sph_kernel(struct __clState *clState, struct _dev_blk_ctx *blk, __maybe_unused cl_uint threads) +{ + cl_kernel *kernel = &clState->kernel; + unsigned int num = 0; + cl_ulong le_target; + cl_int status = 0; + + le_target = *(cl_ulong *)(blk->work->device_target + 24); + flip80(clState->cldata, blk->work->data); + status = clEnqueueWriteBuffer(clState->commandQueue, clState->CLbuffer0, true, 0, 80, clState->cldata, 0, NULL,NULL); + + CL_SET_ARG(clState->CLbuffer0); + CL_SET_ARG(clState->outputBuffer); + CL_SET_ARG(le_target); + + return status; +} + +typedef struct _algorithm_settings_t { + const char *name; /* Human-readable identifier */ + double diff_multiplier1; + double diff_multiplier2; + unsigned long long diff_nonce; + unsigned long long diff_numerator; + void (*regenhash)(struct work *); + cl_int (*queue_kernel)(struct __clState *, struct _dev_blk_ctx *, cl_uint); + void (*gen_hash)(const unsigned char *, unsigned int, unsigned char *); +} algorithm_settings_t; - if ((strcmp(algo->name, "adaptive-n-factor") == 0) || - (strcmp(algo->name, "adaptive-nfactor") == 0) || - (strcmp(algo->name, "nscrypt") == 0) ) { - set_algorithm_nfactor(algo, 11); - } else { - set_algorithm_nfactor(algo, 10); +static algorithm_settings_t algos[] = { + // kernels starting from this will have difficulty calculated by using litecoin algorithm +#define A_SCRYPT(a) \ + { a, 1, 65536, 0x0000ffff00000000ULL, 0xFFFFFFFFULL, scrypt_regenhash, queue_scrypt_kernel, gen_hash} + A_SCRYPT( "ckolivas" ), + A_SCRYPT( "alexkarnew" ), + A_SCRYPT( "alexkarnold" ), + A_SCRYPT( "bufius" ), + A_SCRYPT( "psw" ), + A_SCRYPT( "zuikkis" ), +#undef A_SCRYPT + + // kernels starting from this will have difficulty calculated by using quarkcoin algorithm +#define A_QUARK(a, b) \ + { a, 256, 256, 0x000000ffff000000ULL, 0xFFFFFFULL, b, queue_sph_kernel, gen_hash} + A_QUARK( "quarkcoin", quarkcoin_regenhash), + A_QUARK( "qubitcoin", qubitcoin_regenhash), + A_QUARK( "animecoin", animecoin_regenhash), + A_QUARK( "sifcoin", sifcoin_regenhash), +#undef A_QUARK + + // kernels starting from this will have difficulty calculated by using bitcoin algorithm +#define A_DARK(a, b) \ + { a, 1, 1, 0x00000000ffff0000ULL, 0xFFFFULL, b, queue_sph_kernel, gen_hash} + A_DARK( "darkcoin", darkcoin_regenhash), + A_DARK( "inkcoin", inkcoin_regenhash), + A_DARK( "myriadcoin-groestl", myriadcoin_groestl_regenhash), + A_DARK( "marucoin", marucoin_regenhash), +#undef A_DARK + + { "twecoin", 1, 1, 0x00000000ffff0000ULL, 0xFFFFULL, twecoin_regenhash, queue_sph_kernel, sha256}, + + // kernels starting from this will have difficulty calculated by using fuguecoin algorithm +#define A_FUGUE(a, b) \ + { a, 1, 256, 0x00000000ffff0000ULL, 0xFFFFULL, b, queue_sph_kernel, sha256} + A_FUGUE( "fuguecoin", fuguecoin_regenhash), + A_FUGUE( "groestlcoin", groestlcoin_regenhash), +#undef A_FUGUE + + // Terminator (do not remove) + { NULL, 0, 0, 0, 0, NULL, NULL, NULL} +}; + +void copy_algorithm_settings(algorithm_t* dest, const char* algo) { + algorithm_settings_t* src; + + // Find algorithm settings and copy + for (src = algos; src->name; src++) { + if (strcmp(src->name, algo) == 0) { + strcpy(dest->name, src->name); + + dest->diff_multiplier1 = src->diff_multiplier1; + dest->diff_multiplier2 = src->diff_multiplier2; + dest->diff_nonce = src->diff_nonce; + dest->diff_numerator = src->diff_numerator; + dest->regenhash = src->regenhash; + dest->queue_kernel = src->queue_kernel; + dest->gen_hash = src->gen_hash; + break; + } } - return; + // if not found + if (src->name == NULL) { + applog(LOG_WARNING, "Algorithm %s not found, using %s.", algo, algos->name); + copy_algorithm_settings(dest, algos->name); + } +} + +void set_algorithm(algorithm_t* algo, const char* newname_alias) { + const char* newname; + uint8_t nfactor = 10; + + // scrypt is default ckolivas kernel + if (strcmp(newname_alias, "scrypt") == 0) + newname = "ckolivas"; + // Adaptive N-factor Scrypt is default ckolivas kernel with nfactor 11 + else if ((strcmp(newname_alias, "adaptive-n-factor") == 0) || + (strcmp(newname_alias, "adaptive-nfactor") == 0) || + (strcmp(newname_alias, "nscrypt") == 0) || + (strcmp(newname_alias, "adaptive-nscrypt") == 0) || + (strcmp(newname_alias, "adaptive-n-scrypt") == 0)) { + newname = "ckolivas"; + nfactor = 11; + // Not an alias + } else + newname = newname_alias; + + copy_algorithm_settings(algo, newname); + + // Doesn't matter for non-scrypt algorithms + set_algorithm_nfactor(algo, nfactor); } void set_algorithm_nfactor(algorithm_t* algo, const uint8_t nfactor) { algo->nfactor = nfactor; algo->n = (1 << nfactor); - - return; } bool cmp_algorithm(algorithm_t* algo1, algorithm_t* algo2) { diff --git a/algorithm.h b/algorithm.h index 3d5f973e..dbf30751 100644 --- a/algorithm.h +++ b/algorithm.h @@ -1,9 +1,21 @@ #ifndef ALGORITHM_H #define ALGORITHM_H +#ifdef __APPLE_CC__ +#include +#else +#include +#endif + #include #include +extern void gen_hash(const unsigned char *data, unsigned int len, unsigned char *hash); + +struct __clState; +struct _dev_blk_ctx; +struct work; + /* Describes the Scrypt parameters and hashing functions used to mine * a specific coin. */ @@ -11,6 +23,13 @@ typedef struct _algorithm_t { char name[20]; /* Human-readable identifier */ uint32_t n; /* N (CPU/Memory tradeoff parameter) */ uint8_t nfactor; /* Factor of N above (n = 2^nfactor) */ + double diff_multiplier1; + double diff_multiplier2; + unsigned long long diff_nonce; + unsigned long long diff_numerator; + void (*regenhash)(struct work *); + cl_int (*queue_kernel)(struct __clState *, struct _dev_blk_ctx *, cl_uint); + void (*gen_hash)(const unsigned char *, unsigned int, unsigned char *); } algorithm_t; /* Set default parameters based on name. */ diff --git a/api.c b/api.c index 9038ed41..d9eeeb7e 100644 --- a/api.c +++ b/api.c @@ -2707,7 +2707,7 @@ static void devdetails(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __m root = api_add_string(root, "Name", cgpu->drv->name, false); root = api_add_int(root, "ID", &(cgpu->device_id), false); root = api_add_string(root, "Driver", cgpu->drv->dname, false); - root = api_add_const(root, "Kernel", cgpu->kernelname ? cgpu->kernelname : BLANK, false); + root = api_add_const(root, "Kernel", cgpu->algorithm.name, false); root = api_add_const(root, "Model", cgpu->name ? cgpu->name : BLANK, false); root = api_add_const(root, "Device Path", cgpu->device_path ? cgpu->device_path : BLANK, false); diff --git a/darkcoin.c b/darkcoin.c index d8ad6122..45529b3c 100644 --- a/darkcoin.c +++ b/darkcoin.c @@ -62,17 +62,17 @@ typedef struct { sph_echo512_context echo1; } Xhash_context_holder; -Xhash_context_holder base_contexts; +static Xhash_context_holder base_contexts; -void init_Xhash_contexts() +static void init_Xhash_contexts() { - sph_blake512_init(&base_contexts.blake1); - sph_bmw512_init(&base_contexts.bmw1); - sph_groestl512_init(&base_contexts.groestl1); - sph_skein512_init(&base_contexts.skein1); - sph_jh512_init(&base_contexts.jh1); - sph_keccak512_init(&base_contexts.keccak1); + sph_blake512_init(&base_contexts.blake1); + sph_bmw512_init(&base_contexts.bmw1); + sph_groestl512_init(&base_contexts.groestl1); + sph_skein512_init(&base_contexts.skein1); + sph_jh512_init(&base_contexts.jh1); + sph_keccak512_init(&base_contexts.keccak1); sph_luffa512_init(&base_contexts.luffa1); sph_cubehash512_init(&base_contexts.cubehash1); sph_shavite512_init(&base_contexts.shavite1); @@ -94,48 +94,48 @@ be32enc_vect(uint32_t *dst, const uint32_t *src, uint32_t len) } -inline void xhash(void *state, const void *input) +static inline void xhash(void *state, const void *input) { init_Xhash_contexts(); - + Xhash_context_holder ctx; - - uint32_t hashA[16], hashB[16]; + + uint32_t hashA[16], hashB[16]; //blake-bmw-groestl-sken-jh-meccak-luffa-cubehash-shivite-simd-echo memcpy(&ctx, &base_contexts, sizeof(base_contexts)); - + sph_blake512 (&ctx.blake1, input, 80); - sph_blake512_close (&ctx.blake1, hashA); + sph_blake512_close (&ctx.blake1, hashA); - sph_bmw512 (&ctx.bmw1, hashA, 64); - sph_bmw512_close(&ctx.bmw1, hashB); - - sph_groestl512 (&ctx.groestl1, hashB, 64); + sph_bmw512 (&ctx.bmw1, hashA, 64); + sph_bmw512_close(&ctx.bmw1, hashB); + + sph_groestl512 (&ctx.groestl1, hashB, 64); sph_groestl512_close(&ctx.groestl1, hashA); - - sph_skein512 (&ctx.skein1, hashA, 64); - sph_skein512_close(&ctx.skein1, hashB); - - sph_jh512 (&ctx.jh1, hashB, 64); + + sph_skein512 (&ctx.skein1, hashA, 64); + sph_skein512_close(&ctx.skein1, hashB); + + sph_jh512 (&ctx.jh1, hashB, 64); sph_jh512_close(&ctx.jh1, hashA); - - sph_keccak512 (&ctx.keccak1, hashA, 64); + + sph_keccak512 (&ctx.keccak1, hashA, 64); sph_keccak512_close(&ctx.keccak1, hashB); - + sph_luffa512 (&ctx.luffa1, hashB, 64); - sph_luffa512_close (&ctx.luffa1, hashA); - - sph_cubehash512 (&ctx.cubehash1, hashA, 64); - sph_cubehash512_close(&ctx.cubehash1, hashB); - - sph_shavite512 (&ctx.shavite1, hashB, 64); - sph_shavite512_close(&ctx.shavite1, hashA); - - sph_simd512 (&ctx.simd1, hashA, 64); - sph_simd512_close(&ctx.simd1, hashB); - - sph_echo512 (&ctx.echo1, hashB, 64); - sph_echo512_close(&ctx.echo1, hashA); + sph_luffa512_close (&ctx.luffa1, hashA); + + sph_cubehash512 (&ctx.cubehash1, hashA, 64); + sph_cubehash512_close(&ctx.cubehash1, hashB); + + sph_shavite512 (&ctx.shavite1, hashB, 64); + sph_shavite512_close(&ctx.shavite1, hashA); + + sph_simd512 (&ctx.simd1, hashA, 64); + sph_simd512_close(&ctx.simd1, hashB); + + sph_echo512 (&ctx.echo1, hashB, 64); + sph_echo512_close(&ctx.echo1, hashA); memcpy(state, hashA, 32); diff --git a/driver-opencl.c b/driver-opencl.c index 48dcf0cd..29a9fb02 100644 --- a/driver-opencl.c +++ b/driver-opencl.c @@ -48,7 +48,6 @@ extern bool opt_loginput; extern char *opt_kernel_path; extern int gpur_thr_id; extern bool opt_noadl; -extern enum diff_calc_mode dm_mode; extern void *miner_thread(void *userdata); extern int dev_from_id(int thr_id); @@ -195,39 +194,6 @@ char *set_thread_concurrency(char *arg) return NULL; } -char *set_kernel(char *arg) -{ - char *nextptr; - int i, device = 0; - - nextptr = strtok(arg, ","); - if (nextptr == NULL) - return "Invalid parameters for set kernel"; - - if (gpus[device].kernelname != NULL) - free(gpus[device].kernelname); - gpus[device].kernelname = strdup(nextptr); - device++; - - while ((nextptr = strtok(NULL, ",")) != NULL) { - if (gpus[device].kernelname != NULL) - free(gpus[device].kernelname); - gpus[device].kernelname = strdup(nextptr); - device++; - } - - /* If only one kernel name provided, use same for all GPUs. */ - if (device == 1) { - for (i = device; i < MAX_GPUDEVICES; i++) { - if (gpus[i].kernelname != NULL) - free(gpus[i].kernelname); - gpus[i].kernelname = strdup(gpus[0].kernelname); - } - } - - return NULL; -} - #ifdef HAVE_ADL /* This function allows us to map an adl device to an opencl device for when * simple enumeration has failed to match them. */ @@ -997,52 +963,6 @@ void manage_gpu(void) static _clState *clStates[MAX_GPUDEVICES]; -#define CL_SET_BLKARG(blkvar) status |= clSetKernelArg(*kernel, num++, sizeof(uint), (void *)&blk->blkvar) -#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_scrypt_kernel(_clState *clState, dev_blk_ctx *blk, __maybe_unused cl_uint threads) -{ - unsigned char *midstate = blk->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->device_target + 28); - memcpy(clState->cldata, blk->work->data, 80); - status = clEnqueueWriteBuffer(clState->commandQueue, clState->CLbuffer0, true, 0, 80, clState->cldata, 0, NULL,NULL); - - CL_SET_ARG(clState->CLbuffer0); - CL_SET_ARG(clState->outputBuffer); - CL_SET_ARG(clState->padbuffer8); - CL_SET_VARG(4, &midstate[0]); - CL_SET_VARG(4, &midstate[16]); - CL_SET_ARG(le_target); - - return status; -} - -static cl_int queue_sph_kernel(_clState *clState, dev_blk_ctx *blk, __maybe_unused cl_uint threads) -{ - unsigned char *midstate = blk->work->midstate; - cl_kernel *kernel = &clState->kernel; - unsigned int num = 0; - cl_ulong le_target; - cl_int status = 0; - - le_target = *(cl_ulong *)(blk->work->device_target + 24); - flip80(clState->cldata, blk->work->data); - status = clEnqueueWriteBuffer(clState->commandQueue, clState->CLbuffer0, true, 0, 80, clState->cldata, 0, NULL,NULL); - - CL_SET_ARG(clState->CLbuffer0); - CL_SET_ARG(clState->outputBuffer); - CL_SET_ARG(le_target); - - return status; -} - - static void set_threads_hashes(unsigned int vectors, unsigned int compute_shaders, int64_t *hashes, size_t *globalThreads, unsigned int minthreads, __maybe_unused int *intensity, __maybe_unused int *xintensity, __maybe_unused int *rawintensity) { @@ -1270,6 +1190,7 @@ static bool opencl_thread_prepare(struct thr_info *thr) char name[256]; struct timeval now; struct cgpu_info *cgpu = thr->cgpu; + struct opencl_thread_data *thrdata = (struct opencl_thread_data *)thr->cgpu_data; int gpu = cgpu->device_id; int virtual_gpu = cgpu->virtual_gpu; int i = thr->id; @@ -1285,6 +1206,9 @@ static bool opencl_thread_prepare(struct thr_info *thr) strcpy(name, ""); applog(LOG_INFO, "Init GPU thread %i GPU %i virtual GPU %i", i, gpu, virtual_gpu); + if (thrdata) + thrdata->queue_kernel_parameters = cgpu->algorithm.queue_kernel; + clStates[i] = initCl(virtual_gpu, name, sizeof(name), &cgpu->algorithm); if (!clStates[i]) { #ifdef HAVE_CURSES @@ -1314,8 +1238,6 @@ static bool opencl_thread_prepare(struct thr_info *thr) } if (!cgpu->name) cgpu->name = strdup(name); - if (!cgpu->kernelname) - cgpu->kernelname = strdup("ckolivas"); applog(LOG_INFO, "initCl() finished. Found %s", name); cgtime(&now); @@ -1341,7 +1263,6 @@ static bool opencl_thread_init(struct thr_info *thr) } thrdata->queue_kernel_parameters = gpu->algorithm.queue_kernel; - thrdata->res = (uint32_t *)calloc(buffersize, 1); if (!thrdata->res) { diff --git a/driver-opencl.h b/driver-opencl.h index e921a82c..6c5b2009 100644 --- a/driver-opencl.h +++ b/driver-opencl.h @@ -24,7 +24,6 @@ extern char *set_worksize(char *arg); extern char *set_shaders(char *arg); extern char *set_lookup_gap(char *arg); extern char *set_thread_concurrency(char *arg); -extern char *set_kernel(char *arg); void manage_gpu(void); extern void pause_dynamic_threads(int gpu); diff --git a/inkcoin.c b/inkcoin.c index d4252f3d..011f7af9 100644 --- a/inkcoin.c +++ b/inkcoin.c @@ -31,9 +31,52 @@ #include #include - +#include "sph/sph_blake.h" +#include "sph/sph_bmw.h" +#include "sph/sph_groestl.h" +#include "sph/sph_jh.h" +#include "sph/sph_keccak.h" +#include "sph/sph_skein.h" +#include "sph/sph_luffa.h" +#include "sph/sph_cubehash.h" +#include "sph/sph_shavite.h" +#include "sph/sph_simd.h" +#include "sph/sph_echo.h" #include "sph/sph_shavite.h" +/* Move init out of loop, so init once externally, and then use one single memcpy with that bigger memory block */ +typedef struct { + sph_blake512_context blake1; + sph_bmw512_context bmw1; + sph_groestl512_context groestl1; + sph_skein512_context skein1; + sph_jh512_context jh1; + sph_keccak512_context keccak1; + sph_luffa512_context luffa1; + sph_cubehash512_context cubehash1; + sph_shavite512_context shavite1; + sph_simd512_context simd1; + sph_echo512_context echo1; +} Xhash_context_holder; + +static Xhash_context_holder base_contexts; + + +static void init_Xhash_contexts() +{ + sph_blake512_init(&base_contexts.blake1); + sph_bmw512_init(&base_contexts.bmw1); + sph_groestl512_init(&base_contexts.groestl1); + sph_skein512_init(&base_contexts.skein1); + sph_jh512_init(&base_contexts.jh1); + sph_keccak512_init(&base_contexts.keccak1); + sph_luffa512_init(&base_contexts.luffa1); + sph_cubehash512_init(&base_contexts.cubehash1); + sph_shavite512_init(&base_contexts.shavite1); + sph_simd512_init(&base_contexts.simd1); + sph_echo512_init(&base_contexts.echo1); +} + /* * Encode a length len/4 vector of (uint32_t) into a length len vector of * (unsigned char) in big-endian form. Assumes len is a multiple of 4. @@ -102,6 +145,53 @@ void inkcoin_regenhash(struct work *work) inkhash(ohash, data); } +static inline void xhash(void *state, const void *input) +{ + init_Xhash_contexts(); + + Xhash_context_holder ctx; + + uint32_t hashA[16], hashB[16]; + //blake-bmw-groestl-sken-jh-meccak-luffa-cubehash-shivite-simd-echo + memcpy(&ctx, &base_contexts, sizeof(base_contexts)); + + sph_blake512 (&ctx.blake1, input, 80); + sph_blake512_close (&ctx.blake1, hashA); + + sph_bmw512 (&ctx.bmw1, hashA, 64); + sph_bmw512_close(&ctx.bmw1, hashB); + + sph_groestl512 (&ctx.groestl1, hashB, 64); + sph_groestl512_close(&ctx.groestl1, hashA); + + sph_skein512 (&ctx.skein1, hashA, 64); + sph_skein512_close(&ctx.skein1, hashB); + + sph_jh512 (&ctx.jh1, hashB, 64); + sph_jh512_close(&ctx.jh1, hashA); + + sph_keccak512 (&ctx.keccak1, hashA, 64); + sph_keccak512_close(&ctx.keccak1, hashB); + + sph_luffa512 (&ctx.luffa1, hashB, 64); + sph_luffa512_close (&ctx.luffa1, hashA); + + sph_cubehash512 (&ctx.cubehash1, hashA, 64); + sph_cubehash512_close(&ctx.cubehash1, hashB); + + sph_shavite512 (&ctx.shavite1, hashB, 64); + sph_shavite512_close(&ctx.shavite1, hashA); + + sph_simd512 (&ctx.simd1, hashA, 64); + sph_simd512_close(&ctx.simd1, hashB); + + sph_echo512 (&ctx.echo1, hashB, 64); + sph_echo512_close(&ctx.echo1, hashA); + + memcpy(state, hashA, 32); + +} + bool scanhash_inkcoin(struct thr_info *thr, const unsigned char __maybe_unused *pmidstate, unsigned char *pdata, unsigned char __maybe_unused *phash1, unsigned char __maybe_unused *phash, const unsigned char *ptarget, diff --git a/miner.h b/miner.h index 8775e801..820ce269 100644 --- a/miner.h +++ b/miner.h @@ -462,7 +462,6 @@ struct cgpu_info { int64_t max_hashes; - char *kernelname; /* Human-readable kernel name. */ bool mapped; int virtual_gpu; int virtual_adl; @@ -1029,7 +1028,7 @@ extern pthread_cond_t restart_cond; extern void clear_stratum_shares(struct pool *pool); extern void clear_pool_work(struct pool *pool); -extern void set_target(unsigned char *dest_target, double diff); +extern void set_target(unsigned char *dest_target, double diff, double diff_multiplier2); extern int restart_wait(struct thr_info *thr, unsigned int mstime); extern void kill_work(void); @@ -1109,7 +1108,7 @@ extern double best_diff; extern struct timeval block_timeval; extern char *workpadding; -typedef struct { +typedef struct _dev_blk_ctx { cl_uint ctx_a; cl_uint ctx_b; cl_uint ctx_c; cl_uint ctx_d; cl_uint ctx_e; cl_uint ctx_f; cl_uint ctx_g; cl_uint ctx_h; cl_uint cty_a; cl_uint cty_b; cl_uint cty_c; cl_uint cty_d; diff --git a/ocl.c b/ocl.c index 55df413c..738ef56b 100644 --- a/ocl.c +++ b/ocl.c @@ -405,20 +405,15 @@ _clState *initCl(unsigned int gpu, char *name, size_t nameSize, algorithm_t *alg /* Create binary filename based on parameters passed to opencl * compiler to ensure we only load a binary that matches what * would have otherwise created. The filename is: - * name + kernelname + g + lg + lookup_gap + tc + thread_concurrency + nf + nfactor + w + work_size + l + sizeof(long) + .bin + * name + g + lg + lookup_gap + tc + thread_concurrency + nf + nfactor + w + work_size + l + sizeof(long) + .bin */ char binaryfilename[255]; char filename[255]; char strbuf[32]; - if (cgpu->kernelname == NULL) { - applog(LOG_INFO, "No kernel specified, defaulting to ckolivas"); - cgpu->kernelname = strdup("ckolivas"); - } - - sprintf(strbuf, "%s.cl", cgpu->kernelname); + sprintf(strbuf, "%s.cl", cgpu->algorithm.name); strcpy(filename, strbuf); - strcpy(binaryfilename, cgpu->kernelname); + strcpy(binaryfilename, cgpu->algorithm.name); /* For some reason 2 vectors is still better even if the card says * otherwise, and many cards lie about their max so use 256 as max @@ -452,12 +447,12 @@ _clState *initCl(unsigned int gpu, char *name, size_t nameSize, algorithm_t *alg } else cgpu->lookup_gap = cgpu->opt_lg; - if ((strcmp(cgpu->kernelname, "zuikkis") == 0) && (cgpu->lookup_gap != 2)) { + if ((strcmp(cgpu->algorithm.name, "zuikkis") == 0) && (cgpu->lookup_gap != 2)) { applog(LOG_WARNING, "Kernel zuikkis only supports lookup-gap = 2 (currently %d), forcing.", cgpu->lookup_gap); cgpu->lookup_gap = 2; } - if ((strcmp(cgpu->kernelname, "bufius") == 0) && ((cgpu->lookup_gap != 2) && (cgpu->lookup_gap != 4) && (cgpu->lookup_gap != 8))) { + if ((strcmp(cgpu->algorithm.name, "bufius") == 0) && ((cgpu->lookup_gap != 2) && (cgpu->lookup_gap != 4) && (cgpu->lookup_gap != 8))) { applog(LOG_WARNING, "Kernel bufius only supports lookup-gap of 2, 4 or 8 (currently %d), forcing to 2", cgpu->lookup_gap); cgpu->lookup_gap = 2; } diff --git a/ocl.h b/ocl.h index 9754865b..e641d803 100644 --- a/ocl.h +++ b/ocl.h @@ -12,7 +12,7 @@ #include "miner.h" -typedef struct { +typedef struct __clState { cl_context context; cl_kernel kernel; cl_command_queue commandQueue; diff --git a/qubitcoin.h b/qubitcoin.h index a46a0e85..bc727e4a 100644 --- a/qubitcoin.h +++ b/qubitcoin.h @@ -1,5 +1,5 @@ -#ifndef SCRYPT_H -#define SCRYPT_H +#ifndef QUBITCOIN_H +#define QUBITCOIN_H #include "miner.h" @@ -7,4 +7,4 @@ extern int qubitcoin_test(unsigned char *pdata, const unsigned char *ptarget, uint32_t nonce); extern void qubitcoin_regenhash(struct work *work); -#endif /* SCRYPT_H */ +#endif /* QUBITCOIN_H */ diff --git a/scrypt.c b/scrypt.c index 08c3fa03..ab34b64a 100644 --- a/scrypt.c +++ b/scrypt.c @@ -404,7 +404,7 @@ static void scrypt_n_1_1_256_sp(const uint32_t* input, char* scratchpad, uint32_ PBKDF2_SHA256_80_128_32(input, X, ostate); } -void scrypt_regenhash(struct work *work, uint32_t n) +void scrypt_regenhash(struct work *work) { uint32_t data[20]; char *scratchbuf; @@ -414,8 +414,8 @@ void scrypt_regenhash(struct work *work, uint32_t n) be32enc_vect(data, (const uint32_t *)work->data, 19); data[19] = htobe32(*nonce); - scratchbuf = (char *)alloca(n * 128 + 512); - scrypt_n_1_1_256_sp(data, scratchbuf, ohash, n); + scratchbuf = (char *)alloca(work->pool->algorithm.n * 128 + 512); + scrypt_n_1_1_256_sp(data, scratchbuf, ohash, work->pool->algorithm.n); flip32(ohash, ohash); } diff --git a/scrypt.h b/scrypt.h index 6382ae86..d967f541 100644 --- a/scrypt.h +++ b/scrypt.h @@ -5,6 +5,6 @@ /* extern int scrypt_test(unsigned char *pdata, const unsigned char *ptarget, */ /* uint32_t nonce); */ -extern void scrypt_regenhash(struct work *work, uint32_t n); +extern void scrypt_regenhash(struct work *work); #endif /* SCRYPT_H */ diff --git a/sgminer.c b/sgminer.c index 6c075a3e..5a5fe998 100644 --- a/sgminer.c +++ b/sgminer.c @@ -56,8 +56,6 @@ char *curly = ":D"; #include "bench_block.h" #include "algorithm.h" -#include "scrypt.h" -#include "darkcoin.h" #include "pool.h" #if defined(unix) || defined(__APPLE__) @@ -159,7 +157,7 @@ int opt_tcp_keepalive = 30; #else int opt_tcp_keepalive; #endif -double opt_diff_mult = 1.0; +double opt_diff_mult = 0.0; char *opt_kernel_path; char *sgminer_path; @@ -315,10 +313,6 @@ struct schedtime schedstart; struct schedtime schedstop; bool sched_paused; -#define DM_SELECT(x, y, z) (dm_mode == DM_BITCOIN ? x : (dm_mode == DM_QUARKCOIN ? y : z)) - -enum diff_calc_mode dm_mode = DM_LITECOIN; - static bool time_before(struct tm *tm1, struct tm *tm2) { if (tm1->tm_hour < tm2->tm_hour) @@ -1293,9 +1287,6 @@ static struct opt_table opt_config_table[] = { OPT_WITH_ARG("--kernel-path|-K", opt_set_charp, opt_show_charp, &opt_kernel_path, "Specify a path to where kernel files are"), - OPT_WITH_ARG("--kernel|-k", - set_kernel, NULL, NULL, - "Override kernel to use - one value or comma separated"), OPT_WITHOUT_ARG("--load-balance", set_loadbalance, &pool_strategy, "Change multipool strategy from failover to quota based balance"), @@ -1736,7 +1727,6 @@ void free_work(struct work *w) free(w); } -static void gen_hash(unsigned char *data, unsigned char *hash, size_t len); static void calc_diff(struct work *work, double known); char *workpadding = "000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000"; @@ -1783,7 +1773,7 @@ static bool __build_gbt_txns(struct pool *pool, json_t *res_val) if (unlikely(!hex2bin(txn_bin, txn, txn_len / 2))) quit(1, "Failed to hex2bin txn_bin"); - gen_hash(txn_bin, pool->txn_hashes + (32 * i), txn_len / 2); + gen_hash(txn_bin, txn_len / 2, pool->txn_hashes + (32 * i)); free(txn_bin); } out: @@ -1799,7 +1789,7 @@ static unsigned char *__gbt_merkleroot(struct pool *pool) if (unlikely(!merkle_hash)) quit(1, "Failed to calloc merkle_hash in __gbt_merkleroot"); - gen_hash(pool->coinbase, merkle_hash, pool->coinbase_len); + gen_hash(pool->coinbase, pool->coinbase_len, merkle_hash); if (pool->gbt_txns) memcpy(merkle_hash + 32, pool->txn_hashes, pool->gbt_txns * 32); @@ -1813,7 +1803,7 @@ static unsigned char *__gbt_merkleroot(struct pool *pool) for (i = 0; i < txns; i += 2){ unsigned char hashout[32]; - gen_hash(merkle_hash + (i * 32), hashout, 64); + gen_hash(merkle_hash + (i * 32), 64, hashout); memcpy(merkle_hash + (i / 2 * 32), hashout, 32); } txns /= 2; @@ -2679,7 +2669,7 @@ static void show_hash(struct work *work, char *hashshow) char diffdisp[16], wdiffdisp[16]; unsigned long h32; uint32_t *hash32; - int intdiff, ofs; + int ofs; swab256(rhash, work->hash); for (ofs = 0; ofs <= 28; ofs ++) { @@ -2688,7 +2678,6 @@ static void show_hash(struct work *work, char *hashshow) } hash32 = (uint32_t *)(rhash + ofs); h32 = be32toh(*hash32); - intdiff = round(work->work_difficulty); suffix_string_double(work->share_diff, diffdisp, sizeof (diffdisp), 0); suffix_string_double(work->work_difficulty, wdiffdisp, sizeof (wdiffdisp), 0); snprintf(hashshow, 64, "%08lx Diff %s/%s%s", h32, diffdisp, wdiffdisp, @@ -3094,14 +3083,13 @@ static void calc_diff(struct work *work, double known) { struct sgminer_pool_stats *pool_stats = &(work->pool->sgminer_pool_stats); double difficulty; - uint64_t uintdiff; if (known) work->work_difficulty = known; else { double d64, dcut64; - d64 = (double) DM_SELECT(1, 256, 65536) * truediffone; + d64 = work->pool->algorithm.diff_multiplier2 * truediffone; dcut64 = le256todouble(work->target); if (unlikely(!dcut64)) @@ -3731,7 +3719,7 @@ static double share_diff(const struct work *work) double d64, s64; double ret; - d64 = (double) DM_SELECT(1, 256, 65536) * truediffone; + d64 = work->pool->algorithm.diff_multiplier2 * truediffone; s64 = le256todouble(work->hash); if (unlikely(!s64)) s64 = 0; @@ -4054,7 +4042,7 @@ static void set_blockdiff(const struct work *work) uint8_t pow = work->data[72]; int powdiff = (8 * (0x1d - 3)) - (8 * (pow - 3)); uint32_t diff32 = be32toh(*((uint32_t *)(work->data + 72))) & 0x00FFFFFF; - double numerator = DM_SELECT(0xFFFFULL, 0xFFFFFFULL, 0xFFFFFFFFULL) << powdiff; + double numerator = work->pool->algorithm.diff_numerator << powdiff; double ddiff = numerator / (double)diff32; if (unlikely(current_diff != ddiff)) { @@ -4373,10 +4361,10 @@ void write_config(FILE *fcfg) fprintf(fcfg, "%s%d", i > 0 ? "," : "", (int)gpus[i].work_size); - fputs("\",\n\"kernel\" : \"", fcfg); + fputs("\",\n\"algorithm\" : \"", fcfg); for(i = 0; i < nDevs; i++) { fprintf(fcfg, "%s", i > 0 ? "," : ""); - fprintf(fcfg, "%s", gpus[i].kernelname); + fprintf(fcfg, "%s", gpus[i].algorithm.name); } fputs("\",\n\"lookup-gap\" : \"", fcfg); @@ -5947,15 +5935,7 @@ out_unlock: return work; } -static void gen_hash(unsigned char *data, unsigned char *hash, size_t len) -{ - unsigned char hash1[32]; - - sha256(data, len, hash1); - sha256(hash1, 32, hash); -} - -void set_target(unsigned char *dest_target, double diff) +void set_target(unsigned char *dest_target, double diff, double diff_multiplier2) { unsigned char target[32]; uint64_t *data64, h64; @@ -5968,7 +5948,7 @@ void set_target(unsigned char *dest_target, double diff) } // FIXME: is target set right? - d64 = (double) DM_SELECT(1, 256, 65536) * truediffone; + d64 = diff_multiplier2 * truediffone; d64 /= diff; dcut64 = d64 / bits192; @@ -6031,14 +6011,11 @@ static void gen_stratum_work(struct pool *pool, struct work *work) cg_dwlock(&pool->data_lock); /* Generate merkle root */ - if (gpus[0].kernel == KL_FUGUECOIN || gpus[0].kernel == KL_GROESTLCOIN || gpus[0].kernel == KL_TWECOIN) - sha256(pool->coinbase, pool->swork.cb_len, merkle_root); - else - gen_hash(pool->coinbase, merkle_root, pool->swork.cb_len); + pool->algorithm.gen_hash(pool->coinbase, pool->swork.cb_len, merkle_root); memcpy(merkle_sha, merkle_root, 32); for (i = 0; i < pool->swork.merkles; i++) { memcpy(merkle_sha + 32, pool->swork.merkle_bin[i], 32); - gen_hash(merkle_sha, merkle_root, 64); + gen_hash(merkle_sha, 64, merkle_root); memcpy(merkle_sha, merkle_root, 32); } data32 = (uint32_t *)merkle_sha; @@ -6073,7 +6050,7 @@ static void gen_stratum_work(struct pool *pool, struct work *work) } calc_midstate(work); - set_target(work->target, work->sdiff); + set_target(work->target, work->sdiff, pool->algorithm.diff_multiplier2); local_work++; work->pool = pool; @@ -6236,7 +6213,7 @@ static void rebuild_nonce(struct work *work, uint32_t nonce) *work_nonce = htole32(nonce); - work->pool->algorithm.regenhash(work, work->pool->algorithm.n); + work->pool->algorithm.regenhash(work); } /* For testing a nonce against diff 1 */ @@ -6257,7 +6234,7 @@ bool test_nonce_diff(struct work *work, uint32_t nonce, double diff) uint64_t *hash64 = (uint64_t *)(work->hash + 24), diff64; rebuild_nonce(work, nonce); - diff64 = DM_SELECT(0x00000000ffff0000ULL, 0x000000ffff000000ULL, 0x0000ffff00000000ULL); + diff64 = work->pool->algorithm.diff_nonce; diff64 /= diff; return (le64toh(*hash64) <= diff64); @@ -6266,11 +6243,11 @@ bool test_nonce_diff(struct work *work, uint32_t nonce, double diff) static void update_work_stats(struct thr_info *thr, struct work *work) { double test_diff = current_diff; - test_diff *= DM_SELECT(1, 256, 65536); + test_diff *= work->pool->algorithm.diff_multiplier2; work->share_diff = share_diff(work); - test_diff *= DM_SELECT(1, 256, 65536); + test_diff *= work->pool->algorithm.diff_multiplier2; if (unlikely(work->share_diff >= test_diff)) { work->block = true; @@ -6425,7 +6402,7 @@ static void hash_sole_work(struct thr_info *mythr) work->device_diff = MIN(drv->working_diff, work->work_difficulty); } else if (drv->working_diff > work->work_difficulty) drv->working_diff = work->work_difficulty; - set_target(work->device_target, work->device_diff); + set_target(work->device_target, work->device_diff, work->pool->algorithm.diff_multiplier2); do { cgtime(&tv_start); diff --git a/sph/groestl.c b/sph/groestl.c index 3e83961d..fe4e84fd 100644 --- a/sph/groestl.c +++ b/sph/groestl.c @@ -5,7 +5,7 @@ * ==========================(LICENSE BEGIN)============================ * * Copyright (c) 2007-2010 Projet RNRT SAPHIR - * + * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including @@ -13,10 +13,10 @@ * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. @@ -2809,7 +2809,6 @@ static void groestl_small_close(sph_groestl_small_context *sc, unsigned ub, unsigned n, void *dst, size_t out_len) { - unsigned char *buf; unsigned char pad[72]; size_t u, ptr, pad_len; #if SPH_64 @@ -2820,7 +2819,6 @@ groestl_small_close(sph_groestl_small_context *sc, unsigned z; DECL_STATE_SMALL - buf = sc->buf; ptr = sc->ptr; z = 0x80 >> n; pad[0] = ((ub & -z) | z) & 0xFF; @@ -2945,7 +2943,6 @@ static void groestl_big_close(sph_groestl_big_context *sc, unsigned ub, unsigned n, void *dst, size_t out_len) { - unsigned char *buf; unsigned char pad[136]; size_t ptr, pad_len, u; #if SPH_64 @@ -2956,7 +2953,6 @@ groestl_big_close(sph_groestl_big_context *sc, unsigned z; DECL_STATE_BIG - buf = sc->buf; ptr = sc->ptr; z = 0x80 >> n; pad[0] = ((ub & -z) | z) & 0xFF; diff --git a/util.c b/util.c index 9084dbfe..1c3c2c85 100644 --- a/util.c +++ b/util.c @@ -1643,7 +1643,11 @@ static bool parse_diff(struct pool *pool, json_t *val) { double old_diff, diff; - diff = json_number_value(json_array_get(val, 0)) * opt_diff_mult; + if (opt_diff_mult == 0.0) + diff = json_number_value(json_array_get(val, 0)) * pool->algorithm.diff_multiplier1; + else + diff = json_number_value(json_array_get(val, 0)) * opt_diff_mult; + if (diff == 0) return false; diff --git a/winbuild/sgminer.vcxproj b/winbuild/sgminer.vcxproj index 66971119..005c480a 100644 --- a/winbuild/sgminer.vcxproj +++ b/winbuild/sgminer.vcxproj @@ -301,4 +301,4 @@ exit 0 - \ No newline at end of file +