mersenneforum.org

mersenneforum.org (https://www.mersenneforum.org/index.php)
-   GPU Computing (https://www.mersenneforum.org/forumdisplay.php?f=92)
-   -   CUDALucas (a.k.a. MaclucasFFTW/CUDA 2.3/CUFFTW) (https://www.mersenneforum.org/showthread.php?t=12576)

Dubslow 2012-06-04 19:47

[QUOTE=kjaget;301210]You're calling strcpy_s with the wrong arguments. This is a problem on the strcopy call on line 230 specifically, and maybe other places. Note how the strcpy_s fails when the source is too long compared to strncpy[/QUOTE]
[url]http://msdn.microsoft.com/en-us/library/td1esda9(v=vs.80).aspx[/url]
[code]errno_t strcpy_s(
char *[U]strDestination[/U],
size_t [U]numberOfElements[/U],
const char *[U]strSource[/U]
);[/code]
[code]void strcopy(char* dest, char* src, size_t n)
{
#ifdef linux
strncpy(dest, src, n);
#else
strcpy_s([U]dest[/U], [U]n[/U], [U]src[/U]);
#endif
}[/code]

[QUOTE=chris2be8;301231]If code behaves differently on Linux and Windows the first thing to check is that lines end with crlf on Windows and lf on Linux. Try running unix2dos against the config file on Linux and see what happens.

Chris[/QUOTE]
Thanks, that's an excellent suggestion. I'll go do that now.
Edit: Sadly, it still worked fine. I'll run it through the debugger though.
[code]bill@Gravemind:~/CUDALucas∰∂ unix2dos worktodo.txt
unix2dos: converting file worktodo.txt to DOS format ...
bill@Gravemind:~/CUDALucas∰∂ CUDALucas

Starting M25994671 fft length = 1474560[/code]

Redarm 2012-06-05 08:06

got a big performance increase with 2.02. 4.1 with my gtx 680
on a 65xxxxxx exponent
2.01 gives me 7.6ms/iteration
this version 6.6ms/itereation

was that expected???

Dubslow 2012-06-05 09:22

[QUOTE=Redarm;301290]got a big performance increase with 2.02. 4.1 with my gtx 680
on a 65xxxxxx exponent
2.01 gives me 7.6ms/iteration
this version 6.6ms/itereation

was that expected???[/QUOTE]

I didn't change a thing math-wise. Perhaps you chose a better FFT length? Edit: Could be new drivers, the 680 is still rather new. Or, if previously you were using arch>=2.0 but are now using arch=1.3, you might see some performance gains.

PS: Are you in Windows, and if so, does it crash for you like above?

kjaget 2012-06-05 12:07

[QUOTE=Dubslow;301246][url]http://msdn.microsoft.com/en-us/library/td1esda9(v=vs.80).aspx[/url]
[code]errno_t strcpy_s(
char *[U]strDestination[/U],
size_t [U]numberOfElements[/U],
const char *[U]strSource[/U]
);[/code]
[code]void strcopy(char* dest, char* src, size_t n)
{
#ifdef linux
strncpy(dest, src, n);
#else
strcpy_s([U]dest[/U], [U]n[/U], [U]src[/U]);
#endif
}[/code][/QUOTE]

Keep in mind that numberOfElements is the size of the destination buffer, not the number of characters you wish to copy as it is in strncpy().

[QUOTE]If strDestination or strSource is a null pointer, [B]or if the destination string is too smal[/B]l, the invalid parameter handler is invoked as described in Parameter Validation. [/QUOTE]

What is the length of the destination string you're passing in from this call, and how long is the source string :

strcopy(assignment->assignment_key,ptr,1+(strstr(ptr,",")-ptr) ); // copy the comma..

You can add a check in strcopy to see the problem in Linux. Print n and strlen(src) and then dereference a NULL pointer if n is smaller. You'll see a crash in basically the same place as you would on Windows.

Or just use strncpy() in Windows as well as Linux, and add in the dest[n-1] = '\0'; line recommended earlier.

Dubslow 2012-06-05 12:54

1 Attachment(s)
[QUOTE=kjaget;301298]Keep in mind that numberOfElements is the size of the destination buffer, not the number of characters you wish to copy as it is in strncpy().
[/QUOTE]
GAH

Leave it to Microsoft to complicate everything

[code]void strcopy(char* dest, char* src, size_t n)
{
#ifdef linux
strncpy(dest, src, n);
#else
strncpy_s(dest, MAX_LINE_LENGTH+1, src, n);
#endif
}[/code]
[QUOTE=kjaget;301298]
You can add a check in strcopy to see the problem in Linux. Print n and strlen(src) and then dereference a NULL pointer if n is smaller. You'll see a crash in basically the same place as you would on Windows.
[/QUOTE]
Makes sense. Like you pointed out, I was thinking it would stop after n chars.

Btw, sorry about being so snippety in my first reply :razz: For whatever reason in my version of the file that line is 269, not 23x, so I had no idea what you were talking about. Thanks though for the pointer (:lol:! ...On that note, it's quite fun to increment a char pointer named "C"... :smile:)

Okay, let's test this ASAP. I've upped the version to 2.03, pending confirmation of bug destroyed. While this has been going on, I've still been fiddling with the code here and there, in platform-independent manners, and it works here, but of course testing still required.

By the way, if this was in fact the bug, then something like "Test=25994671" should have worked just fine. Did anybody try something like that, or just a valid expo with >=2 commas?

(Again, the included .ini should be shipped with all binaries :smile:)

Edit: ToDo list:
1) Clean up FFT selection. Before the bug was reported I had made some progress in this front, and it should turn out easier than I had first thought.
2) To complement that, get exponent-by-exponent FFT specification ability, again probably via some field in the worktodo.txt line. Any ideas on how to actually do that? (The way Prime95 does it is kind of a pain in the butt to parse.)
3) If anyone would like a different way of determining whether or not there is an assignment key other than by comma count, please let me know.
[SUP][SUP][SUP][SUP][SUP][SUP][SUP][SUP][SUP][SUP][SUP][SUP][SUP][SUP][SUP][COLOR="White"]4) Bit shift? 0_o[/COLOR][/SUP][/SUP][/SUP][/SUP][/SUP][/SUP][/SUP][/SUP][/SUP][/SUP][/SUP][/SUP][/SUP][/SUP][/SUP]

LaurV 2012-06-05 13:15

[QUOTE=Dubslow;301300]
By the way, if this was in fact the bug, then something like "Test=25994671" should have worked just fine. Did anybody try something like that, or just a valid expo with >=2 commas?
[/QUOTE]
Indeed, after reading your post I changed the test file shown in my previous post (edit: post #1360), by eliminating the "N/A," stuff. Here is the result:
[CODE]e:\CudaLucas>cl2024020x64 -d 0

------- DEVICE 0 -------
<snip>

Continuing work from a partial result of M216091 fft length = 12288 iteration = 110001
Iteration 120000 M( 216091 )C, 0x3981b56788b529e2, n = 12288, CUDALucas v2.02 err = 0.00415 (0:03 real, 0.2775 ms/iter, ETA 0:24)
Iteration 130000 M( 216091 )C, 0x80438af231f8fccd, n = 12288, CUDALucas v2.02 err = 0.004822 (0:02 real, 0.2792 ms/iter, ETA 0:22)
Iteration 140000 M( 216091 )C, 0x669382faea06df89, n = 12288, CUDALucas v2.02 err = 0.004822 (0:03 real, 0.2706 ms/iter, ETA 0:18)[/CODE]


edit2: next cosmetic thing would be to use a fixed format (6, 5, even 4 decimals would be enough) for error display, and 4 decimals for ETA. I mean to display the trailing zeroes. It looks ugly (misaligned) when there are trailing zeroes, all row is shifted left. You can do that in v2.03, is not difficult.

Dubslow 2012-06-05 13:45

[QUOTE=LaurV;301303]Indeed, after reading your post I changed the test file shown in my previous post (edit: post #1360), by eliminating the "N/A," stuff. Here is the result:
[CODE]e:\CudaLucas>cl2024020x64 -d 0

------- DEVICE 0 -------
<snip>

Continuing work from a partial result of M216091 fft length = 12288 iteration = 110001
Iteration 120000 M( 216091 )C, 0x3981b56788b529e2, n = 12288, CUDALucas v2.02 err = 0.00415 (0:03 real, 0.2775 ms/iter, ETA 0:24)
Iteration 130000 M( 216091 )C, 0x80438af231f8fccd, n = 12288, CUDALucas v2.02 err = 0.004822 (0:02 real, 0.2792 ms/iter, ETA 0:22)
Iteration 140000 M( 216091 )C, 0x669382faea06df89, n = 12288, CUDALucas v2.02 err = 0.004822 (0:03 real, 0.2706 ms/iter, ETA 0:18)[/CODE]


edit2: next cosmetic thing would be to use a fixed format (6, 5, even 4 decimals would be enough) for error display, and 4 decimals for ETA. I mean to display the trailing zeroes. It looks ugly (misaligned) when there are trailing zeroes, all row is shifted left. You can do that in v2.03, is not difficult.[/QUOTE]
Yick, printf formatting. The current formatter is "%3.4g" for the error; if I understand correctly, "%4.4g" will create a minimum field with of 4, with a maximum width of 4 for g. Will test now, hopefully can edit into previous post.

Edit: Well, that didn't work, but changing from g to f worked, so now the iteration time and round off share the same formatting of "%4.4f". Edited into previous post.
[code]bill@Gravemind:~/CUDALucas∰∂ CUDALucas -t -k -c 200

Continuing work from a partial result of M25994671 fft length = 1474560 iteration = 11819502
Iteration 11819600 M( 25994671 )C, 0xda2bc6c08cb012d2, n = 1474560, CUDALucas v2.03 err = 0.0000 (0:02 real, 10.5765 ms/iter, ETA 41:38:42)
Iteration 11819800 M( 25994671 )C, 0x7a57b790bf30c653, n = 1474560, CUDALucas v2.03 err = 0.0820 (0:02 real, 5.8363 ms/iter, ETA 22:58:49)
Iteration 11820000 M( 25994671 )C, 0x5b7a72e76b58eff7, n = 1474560, CUDALucas v2.03 err = 0.0820 (0:01 real, 5.7476 ms/iter, ETA 22:37:50)
Iteration 11820200 M( 25994671 )C, 0x803f4a72d574de89, n = 1474560, CUDALucas v2.03 err = 0.0820 (0:01 real, 5.7128 ms/iter, ETA 22:29:35)
^C caught. Writing checkpoint.[/code]

Edit3: Well, I missed the ETA portion of your comments. That one's kind of harder, because the number of fields changes. Do you mean that with 25 minutes left, you want it to read "ETA 00:25:42", padded with the zeros? Voilà le current code.
[code]//From apsen
void
print_time_from_seconds (int sec)
{
if (sec > 3600)
{
printf ("%d", sec / 3600);
sec %= 3600;
printf (":%02d", sec / 60);
}
else
printf ("%d", sec / 60);
sec %= 60;
printf (":%02d", sec);
}[/code] And what I think you mean:
[code]printf("%02d", sec / 3600);
sec %= 3600;
printf(":%02d", sec / 60);
printf(":%02d", sec % 60);
/* No ifs, elses, thens, or buts about it */[/code]
Edit2: If anyone else wants cosmetic or or other changes in CUDALucas 2.03, just be sure to request them here before flash comes online and compiles it :smile: (PS Thanks again Mr. Jaget :smile:)

LaurV 2012-06-05 14:45

I may talked to early... I am getting random "caught. Writing checkpoint." without pressing any ctrl c (and the mesage is not "^C caught.", just "caught."), and in case I get it to the end without any interruption, it will always "cannot move tmp workfile to regular workfile" and crash. Subsequent launches can't find worktodo (which is now __woktodo).

Dubslow 2012-06-05 15:01

[QUOTE=LaurV;301311]I may talked to early... I am getting random "caught. Writing checkpoint." without pressing any ctrl c (and the mesage is not "^C caught.", just "caught."), and in case I get it to the end without any interruption, it will always "cannot move tmp workfile to regular workfile" and crash. Subsequent launches can't find worktodo (which is now __woktodo).[/QUOTE]

Sheesh. That's a lot of crap. (That " caught..." is because "^C^C caught..." looked silly to me, but it looks silly now without the ^C...) I don't know what could possibly be signalling the program, but that's what it looks like.

The way CUDALucas (and mfaktc, from which its derived) clear assignments is by writing all the assignments except the one to be cleared to "__worktodo__.tmp", and then overwrite the regular work file with that.
[code] if(remove(filename) != 0)
return CANT_RENAME;
if(rename("__worktodo__.tmp", filename) != 0)
return CANT_RENAME;
return OK;[/code]

[URL="http://pubs.opengroup.org/onlinepubs/009695399/functions/rename.html"]rename()[/URL] is a standard C library function. There's not much I can do to debug it. I hate to say it because it feels like ducking out, but that looks like OS issues...? I dunno. I can't do much about [URL="http://pubs.opengroup.org/onlinepubs/009695399/functions/signal.html"]signal()[/URL] and rename(). The signal() code is identical to previous versions of CUDALucas except for the string printed.
[code]signal (SIGTERM, SetQuitting);
signal (SIGINT, SetQuitting);[/code]

LaurV 2012-06-05 15:08

[QUOTE=Dubslow;301314]
if(rename("__worktodo__.tmp", filename) != 0)
[/QUOTE]
well, the temp file is just "__worktodo.tmp". No "__" at the end. I did not look in the source yet (no time!) but are you sure you use the same name in both directions? :razz:

(don't get me wrong, I really appreciate what you are doing and the fact that you are learning very fast, but if we continue like this, I may put my nose into the source code too, and fix it by myself, maybe I can find some time during the weekend).

Dubslow 2012-06-05 15:10

[QUOTE=LaurV;301315]well, the temp file is just "__worktodo.tmp". No "__" at the end. I did not look in the source yet (no time!) but are you sure you use the same name in both directions? :razz:

(don't get me wrong, I really appreciate what you are doing and the fact that you are learning very fast, but if we continue like this, I may put my nose into the source code too, and fix it by myself, maybe I can find some time during the weekend).[/QUOTE]
Definitely sounds like an OS issue. I really did copy and paste as much of it as possible, only removing the parts referring to bit levels and whatnot. The rest is identical.

The CUDALucas code I have:
[code]/************************************************************************************************************
* Function name : clear_assignment *
* *
* INPUT : char *filename *
* int exponent *
* OUTPUT : *
* *
* 0 - OK *
* 3 - clear_assignment : cannot open file <filename> *
* 4 - clear_assignment : cannot open file "__worktodo__.tmp" *
* 5 - clear_assignment : assignment not found *
* 6 - clear_assignment : cannot rename temporary workfile to regular workfile *
* *
************************************************************************************************************/
enum ASSIGNMENT_ERRORS clear_assignment(char *filename, int exponent)
{
int found = 0;
FILE *f_in, *f_out;
LINE_BUFFER line; // line buffer
char *tail = NULL; // points to tail material in line, if non-null
enum PARSE_WARNINGS value;
unsigned int line_to_drop = UINT_MAX;
unsigned int current_line;
struct ASSIGNMENT assignment; // the found assignment....

f_in = _fopen(filename, "r");
if (NULL == f_in)
return CANT_OPEN_WORKFILE;

f_out = _fopen("__worktodo__.tmp", "w");
if (NULL == f_out)
{
fclose(f_in);
return CANT_OPEN_TEMPFILE;
}

current_line =0;
while (END_OF_FILE != (value = parse_worktodo_line(f_in,&assignment,&line,&tail)) )
{
current_line++;
if (NO_WARNING == value)
{
if( (exponent == assignment.exponent) ) // make final decision
{
if (line_to_drop > current_line)
line_to_drop = current_line;
break;
}
else
{
line_to_drop = current_line+1; // found different assignment, can drop no earlier than next line
}
}
else if ((BLANK_LINE == value) && (UINT_MAX == line_to_drop))
line_to_drop = current_line+1;
}


errno = 0;
if (fseek(f_in,0L,SEEK_SET))
{
fclose(f_in);
f_in = _fopen(filename, "r");
if (NULL == f_in)
{
fclose(f_out);
return CANT_OPEN_WORKFILE;
}
}

found = 0;
current_line = 0;
while (END_OF_FILE != (value = parse_worktodo_line(f_in,&assignment,&line,&tail)) )
{
current_line++;
if ((NO_WARNING != value) || found)
{
if ((found) || (current_line < line_to_drop))
fprintf(f_out, "%s", line);
}
else // assignment on the line, so we may need to print it..
{
found = (exponent == assignment.exponent);
if (!found)
{
fprintf(f_out,"%s",line);
}
else // we have the assignment...
{
// Do nothing; we don't print this to the temp file, 'cause we're trying to delete it :)
}
}
} // while.....
fclose(f_in);
fclose(f_out);
if (!found)
return ASSIGNMENT_NOT_FOUND;
if(remove(filename) != 0)
return CANT_RENAME;
if(rename("__worktodo__.tmp", filename) != 0)
return CANT_RENAME;
return OK;
}[/code]
And the analogous code in mfaktc-0.18:
[code]/************************************************************************************************************
* Function name : clear_assignment *
* *
* INPUT : char *filename *
* unsigned int exponent *
* int bit_min - from old assignment file *
* int bit_max *
* int bit_min_new - new bit_min,what was factored to--if 0,reached bit_max *
* OUTPUT : *
* *
* 0 - OK *
* 3 - clear_assignment : cannot open file <filename> *
* 4 - clear_assignment : cannot open file "__worktodo__.tmp" *
* 5 - clear_assignment : assignment not found *
* 6 - clear_assignment : cannot rename temporary workfile to regular workfile *
* *
* If bit_min_new is zero then the specified assignment will be cleared. If bit_min_new is greater than *
* zero the specified assignment will be modified *
************************************************************************************************************/
enum ASSIGNMENT_ERRORS clear_assignment(char *filename, unsigned int exponent, int bit_min, int bit_max, int bit_min_new)
{
int found = FALSE;
FILE *f_in, *f_out;
LINE_BUFFER line; // line buffer
char *tail = NULL; // points to tail material in line, if non-null
enum PARSE_WARNINGS value;
unsigned int line_to_drop = UINT_MAX;
unsigned int current_line;
struct ASSIGNMENT assignment; // the found assignment....

f_in = fopen(filename, "r");
if (NULL == f_in)
return CANT_OPEN_WORKFILE;

f_out = fopen("__worktodo__.tmp", "w");
if (NULL == f_out)
{
fclose(f_in);
return CANT_OPEN_TEMPFILE;
}

if ((bit_min_new > bit_min) && (bit_min_new < bit_max)) // modify only
line_to_drop = UINT_MAX;
else
{
current_line =0;
while (END_OF_FILE != (value = parse_worktodo_line(f_in,&assignment,&line,&tail)) )
{
current_line++;
if (NO_WARNING == value)
{
if( (exponent == assignment.exponent) && (bit_min == assignment.bit_min) && (bit_max == assignment.bit_max)) // make final decision
{
if (line_to_drop > current_line)
line_to_drop = current_line;
break;
}
else
{
line_to_drop = current_line+1; // found different assignment, can drop no earlier than next line
}
}
else if ((BLANK_LINE == value) && (UINT_MAX == line_to_drop))
line_to_drop = current_line+1;
}
}

errno = 0;
if (fseek(f_in,0L,SEEK_SET))
{
fclose(f_in);
f_in = fopen(filename, "r");
if (NULL == f_in)
{
fclose(f_out);
return CANT_OPEN_WORKFILE;
}
}

found = FALSE;
current_line = 0;
while (END_OF_FILE != (value = parse_worktodo_line(f_in,&assignment,&line,&tail)) )
{
current_line++;
if ((NO_WARNING != value) || found)
{
if ((found) || (current_line < line_to_drop))
fprintf(f_out, "%s", line);
}
else // assignment on the line, so we may need to print it..
{
found =( (exponent == assignment.exponent) && (bit_min == assignment.bit_min) && (bit_max == assignment.bit_max) );
if (!found)
{
fprintf(f_out,"%s",line);
}
else // we have the assignment...
{
if ((bit_min_new > bit_min) && (bit_min_new < bit_max))
{
fprintf(f_out,"Factor=" );
if (strlen(assignment.assignment_key) != 0)
fprintf(f_out,"%s,", assignment.assignment_key);
fprintf(f_out,"%u,%u,%u",exponent, bit_min_new, bit_max);
if (tail != NULL)
fprintf(f_out,"%s",tail);
}
}
}
} // while.....
fclose(f_in);
fclose(f_out);
if (!found)
return ASSIGNMENT_NOT_FOUND;
if(remove(filename) != 0)
return CANT_RENAME;
if(rename("__worktodo__.tmp", filename) != 0)
return CANT_RENAME;
return OK;
}[/code]


All times are UTC. The time now is 23:15.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.