I don't believe in compiler bugs, but ...

Discussion of chess software programming and technical issues.

Moderator: Ras

Chan Rasjid
Posts: 588
Joined: Thu Mar 09, 2006 4:47 pm
Location: Singapore

I don't believe in compiler bugs, but ...

Post by Chan Rasjid »

Hello,

I don't think I could recall any bug which I encountered in the past which could be attributed to the gcc compliler. I don't believe much in compiler bugs. But I could not see any bug in the codes below.

Code: Select all

    /* In root search; after generate root move list.
     Initialize root moves list  */
    for (move = list; move->move; ++move) {
        ...
        move->score = EVAL_SCORE_BASE;
        ...

        makemove(move->move, side);

        /* now move validated */

        assert(move->score > EVAL_SCORE_BASE - INFI
                && move->score < EVAL_SCORE_BASE + INFI);/* assert clears */

        if (currstack->fifty < 100) {
            for (i = 4; i <= currstack->fifty; i += 2) {
                if (currstack->hash ^ (currstack - i)->hash);
                else { /* repetition */
                    move->flag |= rmFlagDraw;
                    move->eval = -INFI; // no eval
                    move->score = EXACT_SCORE_BASE; /* A == draw */
                    if (IS_MOVE_EQ(searchInfo->bestmove, move->move)) {
                        matesearch = 0;
                        if (searchInfo->score < -1) {
                            /* retain bestmove */
                            searchInfo->score = 1;
                            pBestmove = move;
                        } else {
                            searchInfo->bestmove = pv[0][0] = 0;
                        }
                        best = -INFI;
                        alpha = MAX(-INFI, searchInfo->score - v112Pawn);
                        beta = MIN(INFI, searchInfo->score + v112Pawn);
                        sendlog("!!! best score cancelled - draw\n");
                    }
                    i = 0;
                    unmake(move->move, side);
                }
            }
            
            if (i == 0){
                assert(0);
                continue;
            }
        } else {
            move->flag |= rmFlagDraw;
            move->eval = -INFI;
            move->score = EXACT_SCORE_BASE; // == draw
            if (IS_MOVE_EQ(searchInfo->bestmove, move->move)) {
                matesearch = 0;
                if (searchInfo->score < -1) {
                    /* retain bestmove */
                    searchInfo->score = 1;
                    pBestmove = move;
                } else {
                    searchInfo->bestmove = pv[0][0] = 0;
                }
                best = -INFI;
                alpha = MAX(-INFI, searchInfo->score - v112Pawn);
                beta = MIN(INFI, searchInfo->score + v112Pawn);
                sendlog("!!! best score cancelled - draw\n");
            }
            unmake(move->move, side);
            continue;
        }

        assert(move->score > EVAL_SCORE_BASE - INFI
                && move->score < EVAL_SCORE_BASE + INFI); /* B _fail  */


The first assert was cleared; the assert B was triggered with:
1) currstack->fifty == 3.
2) move->score == EXACT_SCORE_BASE;
Only line that sets it is line A within the repetition loop.

Hopefully, I did not miss something glaringly obvious.


Best Regards,
Rasjid.
kbhearn
Posts: 411
Joined: Thu Dec 30, 2010 4:48 am

Re: I don't believe in compiler bugs, but ...

Post by kbhearn »

for clarity, what is EXACT_SCORE_BASE vs EVAL_SCORE_BASE? (i'm having a hard time imagining why EXACT_SCORE_BASE is not between -inf and +inf for you (or if it is outside that range intentionally, why it's asserted as impossible)
Chan Rasjid
Posts: 588
Joined: Thu Mar 09, 2006 4:47 pm
Location: Singapore

Re: I don't believe in compiler bugs, but ...

Post by Chan Rasjid »

kbhearn wrote:for clarity, what is EXACT_SCORE_BASE vs EVAL_SCORE_BASE? (i'm having a hard time imagining why EXACT_SCORE_BASE is not between -inf and +inf for you (or if it is outside that range intentionally, why it's asserted as impossible)
Sorry.

#define INF 8000
const u32 EXACT_SCORE_BASE = 0x80000000u;
const u32 EVAL_SCORE_BASE = 8 * INFI;

The code is actually doing the initial ordering using eval() from a base of EVAL_SCORE_BASE. It is intended that after the first root iteration, there may be some exact scores that would be scored from EXACT_SCORE_BASE. Repetition would be scored this way.

Rasjid.
kbhearn
Posts: 411
Joined: Thu Dec 30, 2010 4:48 am

Re: I don't believe in compiler bugs, but ...

Post by kbhearn »

when you catch a repetition it appears you unmake the move but then stay in the repetition loop starting with i = 0. This would cause a loop until (i assume) unmake takes the currstack->fifty below where the repetition occurs (say it occurs at i=4), then currstack->fifty = 3, move->score = EXACT_SCORE_BASE, and i = 4 to skip the i==0 condition and assert B should trigger essentially any time a repetition is found...
Sven
Posts: 4052
Joined: Thu May 15, 2008 9:57 pm
Location: Berlin, Germany
Full name: Sven Schüle

Re: I don't believe in compiler bugs, but ...

Post by Sven »

Chan Rasjid wrote:
kbhearn wrote:for clarity, what is EXACT_SCORE_BASE vs EVAL_SCORE_BASE? (i'm having a hard time imagining why EXACT_SCORE_BASE is not between -inf and +inf for you (or if it is outside that range intentionally, why it's asserted as impossible)
Sorry.

#define INF 8000
const u32 EXACT_SCORE_BASE = 0x80000000u;
const u32 EVAL_SCORE_BASE = 8 * INFI;

The code is actually doing the initial ordering using eval() from a base of EVAL_SCORE_BASE. It is intended that after the first root iteration, there may be some exact scores that would be scored from EXACT_SCORE_BASE. Repetition would be scored this way.

Rasjid.
Then which value of move->score triggers your assertion?

Perhaps you need to write something like a RANGE_ASSERT() macro that prints more information before firing the assertion.

Code: Select all

#ifdef USE_RANGE_ASSERT
#define RANGE_ASSERT(expr, minval, maxval) \
if ((expr) < (minval) || (expr) > (maxval)) {\
    printf("### error: expression "%s" out of range: value=%d, min=%d, max=%d\n", #expr, (expr), (minval), (maxval));\
    assert((expr) >= (minval) && (expr) <= (maxval));\
}
#else
#define RANGE_ASSERT(expr, minval, maxval) \
    assert((expr) >= (minval) && (expr) <= (maxval))
#endif /* USE_RANGE_ASSERT */
If you have the source of the function that is called by assert() then you can also set a breakpoint and inspect your variables. To avoid such trouble of setting breakpoints in external library code I usually define my own ASSERT() macro.

Sven
Chan Rasjid
Posts: 588
Joined: Thu Mar 09, 2006 4:47 pm
Location: Singapore

Re: I don't believe in compiler bugs, but ...

Post by Chan Rasjid »

kbhearn wrote:when you catch a repetition it appears you unmake the move but then stay in the repetition loop starting with i = 0. This would cause a loop until (i assume) unmake takes the currstack->fifty below where the repetition occurs (say it occurs at i=4), then currstack->fifty = 3, move->score = EXACT_SCORE_BASE, and i = 4 to skip the i==0 condition and assert B should trigger essentially any time a repetition is found...
You are right. Now everything runs smoothly.

I wanted to break and continue with the next move and used unmake() with continue; but notice it was within the repetition loop. So I did the i = 0,... and meant to break from the repetition loop. I forgot to add the break... and also failed to see it...

Should I say it is excusable...

Thanks,
Rasjid.