about stockfish and logic

Discussion of chess software programming and technical issues.

Moderators: bob, hgm, Harvey Williamson

Forum rules
This textbox is used to restore diagrams posted with the [d] tag before the upgrade.
Uri Blass
Posts: 8586
Joined: Wed Mar 08, 2006 11:37 pm
Location: Tel-Aviv Israel

about stockfish and logic

Post by Uri Blass » Sat Apr 17, 2010 6:53 am

I read the following comment in stockfish(lines 1335-1336 of search.cpp):

// Logically we should return (v + razor_margin(depth)), but
// surprisingly this did slightly weaker in tests.


I see no reason why logically you need to return a different number than the number that you got by search.

It is correct that v is based on search to reduced depth but it is still result based on search.

When you do reductions you do not store different value than the value that you got by search so I see no reason why it should be different for pruning.

I wonder if it is not better to replace
return refinedValue - futility_margin(depth, 0);
by return refinedValue in step 7.

Did you test and find that refinedValue-futility_margin(depth,0) is better?

Uri

zamar
Posts: 613
Joined: Sun Jan 18, 2009 6:03 am

Re: about stockfish and logic

Post by zamar » Sat Apr 17, 2010 10:34 am

Uri Blass wrote:I read the following comment in stockfish(lines 1335-1336 of search.cpp):

// Logically we should return (v + razor_margin(depth)), but
// surprisingly this did slightly weaker in tests.
It was tested and written by me.
I see no reason why logically you need to return a different number than the number that you got by search.
It's a common practice when doing a futility pruning (and there is a good reason for it). IMO razoring is just futility pruning "other way around".

When you do reductions you do not store different value than the value that you got by search so I see no reason why it should be different for pruning.
Reductions are invariant to static value, so this is a completely different thing. For futility pruning/razoring, It's important to understand the interactions through TT and what happens when parent node gets probed from TT with different beta.
I wonder if it is not better to replace
return refinedValue - futility_margin(depth, 0);
by return refinedValue in step 7.

Did you test and find that refinedValue-futility_margin(depth,0) is better?

Uri
No we haven't tested it, but I'd bet that it's not a big deal, hard to measure.

If you have extra time, please test :) If you are interested in this, I can give instructions through pm. Proper testing of the patch will take 24-30h.
Joona Kiiski

Ralph Stoesser
Posts: 408
Joined: Sat Mar 06, 2010 8:28 am

Re: about stockfish and logic

Post by Ralph Stoesser » Sat Apr 17, 2010 3:49 pm

I also have a question regarding step 6: razoring.
In case the razoring conditions are true the qsearch value v is returned. Shouldn't refinedValue be more accurate than v, in case refinedEval would come from a TT entry with depth>0?

mcostalba
Posts: 2684
Joined: Sat Jun 14, 2008 7:17 pm

Re: about stockfish and logic

Post by mcostalba » Sun Apr 18, 2010 5:40 am

Ralph Stoesser wrote:I also have a question regarding step 6: razoring.
In case the razoring conditions are true the qsearch value v is returned. Shouldn't refinedValue be more accurate than v, in case refinedEval would come from a TT entry with depth>0?
Could you please post the code you mean to change and the change you are suggesting ? It is not clear to me from the above what is the idea.

Thanks
Marco

Uri Blass
Posts: 8586
Joined: Wed Mar 08, 2006 11:37 pm
Location: Tel-Aviv Israel

Re: about stockfish and logic

Post by Uri Blass » Sun Apr 18, 2010 6:09 am

mcostalba wrote:
Ralph Stoesser wrote:I also have a question regarding step 6: razoring.
In case the razoring conditions are true the qsearch value v is returned. Shouldn't refinedValue be more accurate than v, in case refinedEval would come from a TT entry with depth>0?
Could you please post the code you mean to change and the change you are suggesting ? It is not clear to me from the above what is the idea.

Thanks
Marco
I understand that the idea is simply to return tranposition table score instead of doing qsearch in case that there is information in the hash.

I guess that the idea is not good because qsearch already call the tranposition table so you earn nothing from it.

Uri

Ralph Stoesser
Posts: 408
Joined: Sat Mar 06, 2010 8:28 am

Re: about stockfish and logic

Post by Ralph Stoesser » Sun Apr 18, 2010 9:32 am

Uri Blass wrote:
mcostalba wrote:
Ralph Stoesser wrote:I also have a question regarding step 6: razoring.
In case the razoring conditions are true the qsearch value v is returned. Shouldn't refinedValue be more accurate than v, in case refinedEval would come from a TT entry with depth>0?
Could you please post the code you mean to change and the change you are suggesting ? It is not clear to me from the above what is the idea.

Thanks
Marco
I understand that the idea is simply to return tranposition table score instead of doing qsearch in case that there is information in the hash.

I guess that the idea is not good because qsearch already call the tranposition table so you earn nothing from it.

Uri
I was thinking about something like this

Code: Select all

    // Step 6. Razoring
    if (    refinedValue < beta - razor_margin&#40;depth&#41;
        &&  ttMove == MOVE_NONE
        &&  ss&#91;ply - 1&#93;.currentMove != MOVE_NULL
        &&  depth < RazorDepth
        && !isCheck
        && !value_is_mate&#40;beta&#41;
        && !pos.has_pawn_on_7th&#40;pos.side_to_move&#40;)))
    &#123;
    	if &#40;refinedValue == ss&#91;ply&#93;.eval&#41; // refinedValue is static eval score
    	&#123;
    		Value rbeta = beta - razor_margin&#40;depth&#41;;
    		Value v = qsearch&#40;pos, ss, rbeta-1, rbeta, Depth&#40;0&#41;, ply, threadID&#41;;
    		if &#40;v < rbeta&#41;
    			// Logically we should return &#40;v + razor_margin&#40;depth&#41;), but
    			// surprisingly this did slightly weaker in tests.
    			return v;
    	&#125;
    	else // refinedValue is TT score
    	&#123;
    		return refinedValue;
    	&#125;
    &#125;
Yes, Uri, qsearch would retrieve the better score from TT.
So we would only save a TT query and a call to qsearch in this case.
It's probably not worth to do so.

mcostalba
Posts: 2684
Joined: Sat Jun 14, 2008 7:17 pm

Re: about stockfish and logic

Post by mcostalba » Sun Apr 18, 2010 9:49 am

Ralph Stoesser wrote: Yes, Uri, qsearch would retrieve the better score from TT.
So we would only save a TT query and a call to qsearch in this case.
It's probably not worth to do so.
I think so too.

Instead a possible optimization that I didn't make because of didn't find a nice way to do it (read "without changing qsearch() call parameters") is to pass the static position evaluation to qsearch when we razor.

IOW we have already called the costly evaluate() few lines before:

Code: Select all

ss&#91;ply&#93;.eval = evaluate&#40;pos, ei, threadID&#41;;
and now we are going to call qsearch that, if doesn't return immediately after a TT hit, is going to call _again_ evaluate() on the same position, but in this case we could "pass" to qsearch the already calculated score and avoid the second redundant call.

Someone has hints (read "a patch") to how to do it ?

Michel
Posts: 2047
Joined: Sun Sep 28, 2008 11:50 pm

Re: about stockfish and logic

Post by Michel » Sun Apr 18, 2010 10:19 am

going to call _again_ evaluate() on the same position,

Isn't this exactly what an evaluation cache is for? So that you don't have to think about such things.

mcostalba
Posts: 2684
Joined: Sat Jun 14, 2008 7:17 pm

Re: about stockfish and logic

Post by mcostalba » Sun Apr 18, 2010 10:26 am

Michel wrote:
going to call _again_ evaluate() on the same position,

Isn't this exactly what an evaluation cache is for? So that you don't have to think about such things.
Do we have an evaluation cache ? :?: :?: :?:


BTW, I _want_ to think about such things because I want to always have very clear the impact of a change against the benefit....if you are suggesting to implement an evaluation cache to optimize the qsearch call in razoring _perhaps_ you don't have clear such cost/benefit relation.

...and I think we all agree that a possible answer like: "but there are other places where an evaluation cache could be useful" has _absolutely_ no meaning as is, i.e. without evidences support (it would be just a no-content discussion like the one on object oriented languages taking place in the main forum)...sorry to point out this obvious point but you know, better safe then sorry :-)

User avatar
michiguel
Posts: 6388
Joined: Thu Mar 09, 2006 7:30 pm
Location: Chicago, Illinois, USA
Contact:

Re: about stockfish and logic

Post by michiguel » Sun Apr 18, 2010 12:25 pm

mcostalba wrote:
Michel wrote:
going to call _again_ evaluate() on the same position,

Isn't this exactly what an evaluation cache is for? So that you don't have to think about such things.
Do we have an evaluation cache ? :?: :?: :?:


BTW, I _want_ to think about such things because I want to always have very clear the impact of a change against the benefit....if you are suggesting to implement an evaluation cache to optimize the qsearch call in razoring _perhaps_ you don't have clear such cost/benefit relation.
You do not need a full blown hash table. You just need to remember one entry with last_eval and last_hashsignature. This approach could also be useful with pawn scores (before even going to a hash pawn table).

Miguel

...and I think we all agree that a possible answer like: "but there are other places where an evaluation cache could be useful" has _absolutely_ no meaning as is, i.e. without evidences support (it would be just a no-content discussion like the one on object oriented languages taking place in the main forum)...sorry to point out this obvious point but you know, better safe then sorry :-)

Post Reply