Skip to content
This repository has been archived by the owner on Jan 9, 2021. It is now read-only.

added support to X11_evo algorithm #11

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

pompobit
Copy link

Added support to nicehash sgminer to X11 evo algorithm.
It works with AMD cards, but still seems hard to find a good configuration for newer AMD cards like 480x or 580x.
Example of a coin that uses the X11 evo algorithm: RevolverCoin

nextPerm(algoList, HASH_FUNC_COUNT);
}

sptr = str;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it doesnt make sense to convert int to char string, and later "convert back" to int

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what are you suggesting here, what int conversion are you talking about?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nextPerm return the permutation list into algoList as array of uint8_t,
this array is converted to a human readable string, but is is useless. hash function can use (at line ~183) the integers directly

}


void evocoin_twisted_code(char *result, const char *ntime, char *code)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

void evocoin_twisted_code(char *result, const char *ntime, uint8_t *code)

and move the for-sprintf loop here for result

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as the previous reply, I'm not sure how to change the code

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the human readable string require only here but just for the compiled binary filename.
so only "convert" the array_of_uint to string:

n = sprintf(result, "_%d_", count);
sptr = result + n;
for (j = 0; j < HASH_FUNC_COUNT; j++) {
 ..
}
strcat(sptr, "_"); sptr++;
*sptr = 0;

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried what you suggest but I can't get it working.
If I change getAlgoString in this way:

void getAlgoString(uint8_t *algoList, uint32_t count)
{	
	initPerm(algoList, HASH_FUNC_COUNT);
	int k;
	for (k = 0; k < count; k++) {
		nextPerm(algoList, HASH_FUNC_COUNT);
	}
}

and move the for-loop in evocoin_twisted_code:

getAlgoString(code, count);
char *sptr;
int j;
int n = sprintf(result, "_%d_", count);
sptr = result + n;
for (j = 0; j < HASH_FUNC_COUNT; j++) {
	if (algoList[j] >= 10)
		sprintf(sptr, "%c", 'A' + (code[j] - 10));
	else
		sprintf(sptr, "%u", code[j]);
	sptr++;
}
strcat(sptr, "_"); sptr++;
*sptr = 0;

then I don't need this anymore:

for (i = 0; i < strlen(resultCode); i++) {
	char elem = resultCode[i];
	uint8_t idx;
	if (elem >= 'A')
		idx = elem - 'A' + 10;
	else
		idx = elem - '0';

but I can simply do:

for (i = 0; i < HASH_FUNC_COUNT; i++) {
   uint8_t idx = resultCode[i];
   ...

right?

But in this way I break the build kernel function that also calls evocoin_twisted_code so if I delete the built kernel binaries, they don't get regenerated.
It's the first time that I look at the code of sgminer and I understood the pipeline really partially, sincerely I can't see the advantage in what you are proposing because it seems to me that before or after I still have to convert the integer into string, but I'm sure that is because I can't see exactly what is happening here. I made you collaborator on this repository, if you are willing to make a commit, feel free to push anything, you are more than welcome

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you have to modify the ocl.c code too.

Copy link
Author

@pompobit pompobit Feb 1, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for the help, I managed to get it to work, I'm pushing the changes right now.
I already have modified ocl.c and build_kernel.c like you suggested, but I missed the sgminr.c part and the program crashed.
Unfortunately I'm cross-compiling from an ubuntu virtual machine with no gpu, so I have to debug on windows and I have to say that really I don't like the MinGW gdb!
Thank you again for your time

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you concat the 3 commits to a one-and-only commit and forcepush to this PR?

memcpy(&ctx, &base_contexts, sizeof(base_contexts));

char completeCode[64];
char resultCode[HASH_FUNC_COUNT + 1];

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uint8_t resultCode[HASH_FUNC_COUNT + 1];

out = hashA;
}
else {
if (out == hashA) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need this hashA/hashB swaps, just use one hash[16] variable:

if i == 0
    in=input; size=80;
else 
    in = hash; size = 64;

#include "sph/sph_simd.h"
#include "sph/sph_echo.h"

#define INITIAL_DATE 1462060800

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move this to evocoin.h, so it can be included to build_kernel.c

// start from non-inverted signal
bool curState = false;
int i;
for (i = 0; i < strlen(code); i++) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use HASH_FUNC_COUNT from evocoin.h instead of strlen(code)

};


char *generateSource(const char *code)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const uint8_t *code

@pompobit
Copy link
Author

hi @bitbandi, thank you for your review.
I applied the changes you suggested, except the one I've replied to.
I also pushed some files I forgot to commit and fixed a bug.

ocl.c Outdated
strcat(build_data->binary_filename, "g");

char x11EvoCode[12];
Copy link

@bitbandi bitbandi Feb 1, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uint_8 x11EvoCode[12] = { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 };

initialize the array with 255 values, that 'invalid' value (generator returns 0..15 values)

return result;
}

cl_program build_opencl_kernel(build_kernel_data *data, const char *filename, const char *x11EvoCode)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

x11EvoCode is uint_8 *

ocl.c Outdated
strcat(build_data->binary_filename, "g");

char x11EvoCode[12];
x11EvoCode[0] = 0;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need, we already set values

for (i = 0; i < HASH_FUNC_COUNT; i++) {

// extract index
uint8_t elem = code[i];
Copy link

@bitbandi bitbandi Feb 1, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

 idx = code[i];

no need to convert chars to int

{
int pl;
char *source = file_contents(data->source_filename, &pl);
char *source;
if (strlen(x11EvoCode) > 0) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (x11EvoCode[0] != 255) {

sgminer.c Outdated

evocoin_twisted_code(result, work->pool->swork.ntime, code);

if (strcmp(code, mythr->curSequence) == 0) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

memcmp(code, mythr->curSequence, 12)

sgminer.c Outdated
if (strcmp(code, mythr->curSequence) == 0) {
algoSwitch = false;
} else {
strcpy(mythr->curSequence, code);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

memcpy(mythr->curSequence, code, 12);

miner.h Outdated
@@ -634,6 +634,8 @@ struct thr_info {
int pool_no;
struct timeval last;
struct timeval sick;
char curSequence[12];
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uint8_t curSequence[12];

char s[100];
char *sptr;

void getAlgoString(uint8_t *algoList, uint32_t count)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rename to a better name. call something like getAlgoPerms

int j;
int n = sprintf(result, "_%d_", count);
sptr = result + n;
for (j = 0; j < HASH_FUNC_COUNT; j++) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i got idea, a better "converter" based on bin2hex function from util.c

static const char codes[HASH_FUNC_COUNT] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a' };
for (j = 0; j < HASH_FUNC_COUNT; j++) {
  *s++ = codes[code[j]];
}

Copy link
Author

@pompobit pompobit Feb 1, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I applied this change but now the kernel binary is not saved on disk anymore and it needs to be rebuilt on each new run

Copy link

@bitbandi bitbandi Feb 2, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well, i missed the variable, it need to be *sptr++ = ..., or last char in codes sould be uppercase 'A'

if still wrong, try log the result variable at the end of evocoin_twisted_code. maybe i missed something else, today was a long day :/

Copy link
Author

@pompobit pompobit Feb 2, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well, the variable name was not an issue, even if I had noticed it the code would not have compiled ;)
I also tried to change 'a' with 'A' before writing to you, with the same result.
I just logged the result variable as you suggested and the weird thing seems that the last character, that should be _ because of strcat(sptr, "_");, it is instead a semi-random character, sometimes is _, sometimes is q, sometimes 1 and sometimes is non-ascii..
Your loop seems fine and the post-increment on sptr should work, I can't see why strcat should not work properly anymore after that loop

Copy link
Author

@pompobit pompobit Feb 12, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, I was very busy these days, but I found the issue.
The problem was caused by strcat: it searches for the terminating null-character at the end of the string and then concatenates the two strings overwriting the terminating null-character. Now, with the old code the sprintf added automatically the terminating null-character so strcat worked without issues, but with the new code it needs to be explicitily added or the strcat behaviour is not defined, that's why the random characters instead than the expected "_".
I'm going to squash all the commits and push the new code, I initially manually added a terminating null-character at the end of the for loop to let strcat to do its job, but finally I removed the strcat operation at all and and added the "_" directly, it seems cleaner to me.
I'm pushing the new code in a couple of minutes

@mtamburrano
Copy link

Using this PR to mine RevolverCoin and it works nice, thank you.
FYI I have an AMD 290 Tri-x card and its hashpower is about 4MH/s, not rocket speed but decent, unluckily AMD cards trudge with X11 based algos

@bitbandi
Copy link

bitbandi commented Feb 13, 2018

@pompobit did you benchmark how fast is the getAlgoPerms function, if count is a very big number? (at 2019 jan, count will be 86460336)

hmm, the permutation max count is 39916800 ( =factorial(11) ), an i think we already reached/overflowed once. could you check if it works, if add this line before for loop in getAlgoPerms:

count = count % 39916800;

(If works, add the number as a "define MAX_PERMUTATION 39916800" to evocoin.h, and use this macro in getAlgoPerms.

@pompobit
Copy link
Author

I'm not sure to follow you.
Count holds the days passed since INITIAL_DATE, so it is ~650 today, at 2019 Jan, it will be ~1000 or so.

@bitbandi
Copy link

Ah you're right. it's daily counted. forget my comment about overflow.

But i'm interested in getAlgoPerms func benchmark, if you can measure the speed, it would be good.
(you can use cgtime() and us_tdiff() funcs from util.c to print the elapsed time in getAlgoPerms, no need to commit the code)

@pompobit
Copy link
Author

I did it, but the result time is always 0.000000.
I paste here the code I used to be sure I'm not doing anything wrong:

struct timeval tstart;
struct timeval tend;
double elapsed;
cgtime(&tstart);
getAlgoPerms(code, count);
cgtime(&tend);
elapsed = us_tdiff(&tend, &tstart);
printf("elapsed time: %f",elapsed);

but the ouput is always: elapsed time: 0.000000

I also tried to inspect tstart->usec and tend-usec but they are 0 as well

@pompobit
Copy link
Author

hi @bitbandi,
I tried to fix the benchmark but I still can't figure out why it doesn't work.
I tried different methods to measure the execution time, I tried to benchmark other parts of the code, I rewrote the entire functions being used, I even built the miner directly on windows fearing that the cross-compilation could lead to some issue, but everything didn't work , the elapsed time almost always is 0, I'm going crazy about this. I wrote a standalone program to just debug if it is my pc having some issues, but starting from scratches all the functions I have tried to measure the execution time work, so I suspect that is some compilation option that causes this issue.

ANYWAY, sometimes, at the first run, the benchmark works, and when it happens the measured time is ~970 microseconds, I hope that is enough for you, even if now I'm really curious to know what's wrong with the benchmark stuff

@pompobit
Copy link
Author

hello @bitbandi,
any news? Is there something else I can do to have this pull request merged?

@pompobit
Copy link
Author

pompobit commented May 5, 2018

@bitbandi, any news?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants