diff --git a/cpp/command/analysis.cpp b/cpp/command/analysis.cpp index ef629b8f9..502fb5bb0 100644 --- a/cpp/command/analysis.cpp +++ b/cpp/command/analysis.cpp @@ -35,6 +35,7 @@ struct AnalyzeRequest { bool includeMovesOwnershipStdev; bool includePolicy; bool includePVVisits; + bool includeQValues; bool reportDuringSearch; double reportDuringSearchEvery; @@ -238,6 +239,7 @@ int MainCmds::analysis(const vector& args) { "includeOwnershipStdev", "includePolicy", "includePVVisits", + "includeQValues", "reportDuringSearchEvery", "firstReportDuringSearchAfter", "priority", @@ -323,6 +325,7 @@ int MainCmds::analysis(const vector& args) { request->includeOwnership,request->includeOwnershipStdev, request->includeMovesOwnership,request->includeMovesOwnershipStdev, request->includePVVisits, + request->includeQValues, ret ); @@ -610,6 +613,7 @@ int MainCmds::analysis(const vector& args) { rbase.includeMovesOwnershipStdev = false; rbase.includePolicy = false; rbase.includePVVisits = false; + rbase.includeQValues = false; rbase.reportDuringSearch = false; rbase.reportDuringSearchEvery = 1e30; rbase.firstReportDuringSearchAfter = 1e30; @@ -1019,6 +1023,11 @@ int MainCmds::analysis(const vector& args) { if(!suc) continue; } + if(input.find("includeQValues") != input.end()) { + bool suc = parseBoolean(input, "includeQValues", rbase.includeQValues, "Must be a boolean"); + if(!suc) + continue; + } if(input.find("reportDuringSearchEvery") != input.end()) { bool suc = parseDouble(input, "reportDuringSearchEvery", rbase.reportDuringSearchEvery, 0.001, 1000000.0, "Must be number of seconds from 0.001 to 1000000.0"); if(!suc) @@ -1163,6 +1172,7 @@ int MainCmds::analysis(const vector& args) { newRequest->includeMovesOwnershipStdev = rbase.includeMovesOwnershipStdev; newRequest->includePolicy = rbase.includePolicy; newRequest->includePVVisits = rbase.includePVVisits; + newRequest->includeQValues = rbase.includeQValues; newRequest->reportDuringSearch = rbase.reportDuringSearch; newRequest->reportDuringSearchEvery = rbase.reportDuringSearchEvery; newRequest->firstReportDuringSearchAfter = rbase.firstReportDuringSearchAfter; diff --git a/cpp/command/contribute.cpp b/cpp/command/contribute.cpp index 526c57b0d..a21073b34 100644 --- a/cpp/command/contribute.cpp +++ b/cpp/command/contribute.cpp @@ -261,7 +261,7 @@ static void runAndUploadSingleGame( // Usual analysis response fields ret["turnNumber"] = hist.moveHistory.size(); - search->getAnalysisJson(perspective,analysisPVLen,preventEncore,true,alwaysIncludeOwnership,false,false,false,false,ret); + search->getAnalysisJson(perspective,analysisPVLen,preventEncore,true,alwaysIncludeOwnership,false,false,false,false,false,ret); std::cout << ret.dump() + "\n" << std::flush; // no endl due to race conditions } diff --git a/cpp/command/evalsgf.cpp b/cpp/command/evalsgf.cpp index c29c05ed8..7d228b334 100644 --- a/cpp/command/evalsgf.cpp +++ b/cpp/command/evalsgf.cpp @@ -641,6 +641,7 @@ int MainCmds::evalsgf(const vector& args) { bool includeMovesOwnership = false; bool includeMovesOwnershipStdev = false; bool includePVVisits = true; + bool includeQValues = true; nlohmann::json ret; bool suc = search->getAnalysisJson( perspective, @@ -652,6 +653,7 @@ int MainCmds::evalsgf(const vector& args) { includeMovesOwnership, includeMovesOwnershipStdev, includePVVisits, + includeQValues, ret ); if(suc) { diff --git a/cpp/command/gtp.cpp b/cpp/command/gtp.cpp index 1a9169ea1..96b815f90 100644 --- a/cpp/command/gtp.cpp +++ b/cpp/command/gtp.cpp @@ -1656,6 +1656,47 @@ struct GTPEngine { out << endl; } out << endl; + + + if(nnOutput->whiteQWinloss != NULL) { + out << "whiteQWinloss" << endl; + for(int y = 0; ynnXLen); + if(nnOutput->policyProbs[pos] < 0) + out << " NAN "; + else + out << Global::strprintf("%7.4f ", nnOutput->whiteQWinloss[pos]); + } + out << endl; + } + int pos = NNPos::locToPos(Board::PASS_LOC,board.x_size,nnOutput->nnXLen,nnOutput->nnYLen); + if(nnOutput->policyProbs[pos] < 0) + out << " NAN "; + else + out << Global::strprintf("%7.4f ", nnOutput->whiteQWinloss[pos]); + out << endl; + } + if(nnOutput->whiteQScore != NULL) { + out << "whiteQScore" << endl; + for(int y = 0; ynnXLen); + if(nnOutput->policyProbs[pos] < 0) + out << " NAN "; + else + out << Global::strprintf("%6.1f ", nnOutput->whiteQScore[pos]); + } + out << endl; + } + int pos = NNPos::locToPos(Board::PASS_LOC,board.x_size,nnOutput->nnXLen,nnOutput->nnYLen); + if(nnOutput->policyProbs[pos] < 0) + out << " NAN "; + else + out << Global::strprintf("%6.1f ", nnOutput->whiteQScore[pos]); + out << endl; + } + } } diff --git a/cpp/neuralnet/cudabackend.cpp b/cpp/neuralnet/cudabackend.cpp index 959a73d87..09eb5bd0d 100644 --- a/cpp/neuralnet/cudabackend.cpp +++ b/cpp/neuralnet/cudabackend.cpp @@ -2787,6 +2787,26 @@ void NeuralNet::getOutput( SymmetryHelpers::copyOutputsWithSymmetry(ownershipSrcBuf, output->whiteOwnerMap, 1, nnYLen, nnXLen, inputBufs[row]->symmetry); } + if(output->whiteQWinloss != NULL || output->whiteQScore != NULL) { + testAssert(numPolicyChannels == 4 && modelVersion >= 16 && output->whiteQWinloss != NULL && output->whiteQScore != NULL); + if(gpuHandle->usingNHWC) { + for(int i = 0; iwhiteQWinloss, 1, nnYLen, nnXLen, inputBufs[row]->symmetry); + for(int i = 0; iwhiteQScore, 1, nnYLen, nnXLen, inputBufs[row]->symmetry); + output->whiteQWinloss[nnXLen*nnYLen] = policyPassSrcBuf[2]; + output->whiteQScore[nnXLen*nnYLen] = policyPassSrcBuf[3]; + } + else { + SymmetryHelpers::copyOutputsWithSymmetry(policySrcBuf+nnXLen*nnYLen*2, output->whiteQWinloss, 1, nnYLen, nnXLen, inputBufs[row]->symmetry); + SymmetryHelpers::copyOutputsWithSymmetry(policySrcBuf+nnXLen*nnYLen*3, output->whiteQScore, 1, nnYLen, nnXLen, inputBufs[row]->symmetry); + output->whiteQWinloss[nnXLen*nnYLen] = policyPassSrcBuf[2]; + output->whiteQScore[nnXLen*nnYLen] = policyPassSrcBuf[3]; + } + } + if(modelVersion >= 9) { int numScoreValueChannels = gpuHandle->model->numScoreValueChannels; assert(numScoreValueChannels == 6); diff --git a/cpp/neuralnet/metalbackend.cpp b/cpp/neuralnet/metalbackend.cpp index 2127493f3..699b63a8a 100644 --- a/cpp/neuralnet/metalbackend.cpp +++ b/cpp/neuralnet/metalbackend.cpp @@ -797,6 +797,8 @@ void MetalProcess::processPolicy( const ComputeHandle* gpuHandle, NNResultBuf* inputBuf, size_t row) { + const int nnXLen = gpuHandle->nnXLen; + const int nnYLen = gpuHandle->nnYLen; auto& buffers = *inputBuffers; float* targetBuffer = &buffers.policyResults[row * buffers.singlePolicyResultElts * buffers.policyResultChannels]; const auto symmetry = inputBuf->symmetry; @@ -810,8 +812,19 @@ void MetalProcess::processPolicy( targetBuffer = &buffers.policyProbsBuffer[row * buffers.singlePolicyResultElts]; } - SymmetryHelpers::copyOutputsWithSymmetry( - targetBuffer, currentOutput->policyProbs, 1, gpuHandle->nnYLen, gpuHandle->nnXLen, symmetry); + SymmetryHelpers::copyOutputsWithSymmetry(targetBuffer, currentOutput->policyProbs, 1, nnYLen, nnXLen, symmetry); + + if(currentOutput->whiteQWinloss != NULL || currentOutput->whiteQScore != NULL) { + targetBuffer = &buffers.policyResults[row * buffers.singlePolicyResultElts * buffers.policyResultChannels]; + + SymmetryHelpers::copyOutputsWithSymmetry( + targetBuffer + (buffers.singlePolicyResultElts * 2), currentOutput->whiteQWinloss, 1, nnYLen, nnXLen, symmetry); + SymmetryHelpers::copyOutputsWithSymmetry( + targetBuffer + (buffers.singlePolicyResultElts * 3), currentOutput->whiteQScore, 1, nnYLen, nnXLen, symmetry); + + currentOutput->whiteQWinloss[nnXLen * nnYLen] = buffers.policyPassResults[row * buffers.policyResultChannels + 2]; + currentOutput->whiteQScore[nnXLen * nnYLen] = buffers.policyPassResults[row * buffers.policyResultChannels + 3]; + } } void MetalProcess::processValue( diff --git a/cpp/neuralnet/nneval.cpp b/cpp/neuralnet/nneval.cpp index 2698c5c62..012519cbf 100644 --- a/cpp/neuralnet/nneval.cpp +++ b/cpp/neuralnet/nneval.cpp @@ -66,6 +66,7 @@ NNEvaluator::NNEvaluator( const vector& gpuIdxByServerThr, const string& rSeed, bool doRandomize, + bool useQValues, int defaultSymmetry ) :modelName(mName), @@ -77,6 +78,7 @@ NNEvaluator::NNEvaluator( inputsUseNHWC(iUseNHWC), usingFP16Mode(useFP16Mode), usingNHWCMode(useNHWCMode), + usingQValues(useQValues), numThreads(numThr), gpuIdxByServerThread(gpuIdxByServerThr), randSeed(rSeed), @@ -123,6 +125,9 @@ NNEvaluator::NNEvaluator( Global::intToString(nnXLen) + " * " + Global::intToString(nnYLen) + (requireExactNNLen ? " exactly" : " allowing smaller boards") ); + logger->write( + "Enable raw NN Q values: " + Global::boolToString(usingQValues) + ); } if(nnCacheSizePowerOfTwo >= 0) @@ -518,6 +523,16 @@ void NNEvaluator::serve( else { resultBuf->result->whiteOwnerMap = NULL; } + if(usingQValues && modelVersion >= 16) { + float* whiteQWinloss = new float[nnXLen*nnYLen+1]; + float* whiteQScore = new float[nnXLen*nnYLen+1]; + for(int i = 0; iresult->whiteQWinloss = whiteQWinloss; + resultBuf->result->whiteQScore = whiteQScore; + } //These aren't really probabilities. Win/Loss/NoResult will get softmaxed later double whiteWinProb = 0.0 + rand.nextGaussian() * 0.20; @@ -552,6 +567,15 @@ void NNEvaluator::serve( emptyOutput->whiteOwnerMap = new float[nnXLen*nnYLen]; else emptyOutput->whiteOwnerMap = NULL; + + if(usingQValues && modelVersion >= 16) { + emptyOutput->whiteQWinloss = new float[nnXLen*nnYLen+1]; + emptyOutput->whiteQScore = new float[nnXLen*nnYLen+1]; + } + else { + emptyOutput->whiteQWinloss = NULL; + emptyOutput->whiteQScore = NULL; + } outputBuf.push_back(emptyOutput); } @@ -852,6 +876,18 @@ void NNEvaluator::evaluate( buf.result->policyOptimismUsed = (float)resultWithoutOwnerMap->policyOptimismUsed; buf.result->nnXLen = resultWithoutOwnerMap->nnXLen; buf.result->nnYLen = resultWithoutOwnerMap->nnYLen; + if(resultWithoutOwnerMap->whiteQWinloss != NULL) { + assert(buf.result->whiteQWinloss != NULL); + assert(resultWithoutOwnerMap->nnXLen == nnXLen); + assert(resultWithoutOwnerMap->nnYLen == nnYLen); + std::copy(resultWithoutOwnerMap->whiteQWinloss, resultWithoutOwnerMap->whiteQWinloss + (nnXLen*nnYLen+1), buf.result->whiteQWinloss); + } + if(resultWithoutOwnerMap->whiteQScore != NULL) { + assert(buf.result->whiteQScore != NULL); + assert(resultWithoutOwnerMap->nnXLen == nnXLen); + assert(resultWithoutOwnerMap->nnYLen == nnYLen); + std::copy(resultWithoutOwnerMap->whiteQScore, resultWithoutOwnerMap->whiteQScore + (nnXLen*nnYLen+1), buf.result->whiteQScore); + } assert(buf.result->whiteOwnerMap != NULL); } else { @@ -1126,6 +1162,31 @@ void NNEvaluator::evaluate( else { throw StringError("NNEval value postprocessing not implemented for model version"); } + + //Postprocess q values + if(buf.result->whiteQWinloss != NULL || buf.result->whiteQScore != NULL) { + if(!(buf.result->whiteQWinloss != NULL && buf.result->whiteQScore != NULL)) { + throw StringError("NNEval qvalue postprocessing found ony one of winloss and score"); + } + for(int pos = 0; poswhiteQWinloss[pos] = 0.0f; + buf.result->whiteQScore[pos] = 0.0f; + } + else { + //Similarly as mentioned above, the result we get back from the net is actually not from white's perspective, + //but from the player to move, so we need to flip it to make it white at the same time as we tanh it. + if(nextPlayer == P_WHITE) { + buf.result->whiteQWinloss[pos] = tanh(buf.result->whiteQWinloss[pos]); + buf.result->whiteQScore[pos] = (float)(buf.result->whiteQScore[pos] * postProcessParams.scoreMeanMultiplier); + } + else { + buf.result->whiteQWinloss[pos] = -tanh(buf.result->whiteQWinloss[pos]); + buf.result->whiteQScore[pos] = -(float)(buf.result->whiteQScore[pos] * postProcessParams.scoreMeanMultiplier); + } + } + } + } } //Postprocess ownermap @@ -1151,7 +1212,6 @@ void NNEvaluator::evaluate( } } - //And record the nnHash in the result and put it into the table buf.result->nnHash = nnHash; if(nnCacheTable != NULL) diff --git a/cpp/neuralnet/nneval.h b/cpp/neuralnet/nneval.h index 04ff7506b..d0091b0cd 100644 --- a/cpp/neuralnet/nneval.h +++ b/cpp/neuralnet/nneval.h @@ -100,6 +100,7 @@ class NNEvaluator { const std::vector& gpuIdxByServerThread, const std::string& randSeed, bool doRandomize, + bool useQValues, int defaultSymmetry ); ~NNEvaluator(); @@ -217,6 +218,8 @@ class NNEvaluator { const bool inputsUseNHWC; const enabled_t usingFP16Mode; const enabled_t usingNHWCMode; + const bool usingQValues; + int numThreads; std::vector gpuIdxByServerThread; const std::string randSeed; diff --git a/cpp/neuralnet/nninputs.cpp b/cpp/neuralnet/nninputs.cpp index 9287658f0..56064c850 100644 --- a/cpp/neuralnet/nninputs.cpp +++ b/cpp/neuralnet/nninputs.cpp @@ -317,7 +317,7 @@ void NNInputs::fillScoring( NNOutput::NNOutput() - :whiteOwnerMap(NULL),noisedPolicyProbs(NULL) + :whiteQWinloss(NULL),whiteQScore(NULL),whiteOwnerMap(NULL),noisedPolicyProbs(NULL) {} NNOutput::NNOutput(const NNOutput& other) { nnHash = other.nnHash; @@ -333,6 +333,20 @@ NNOutput::NNOutput(const NNOutput& other) { nnXLen = other.nnXLen; nnYLen = other.nnYLen; + + if(other.whiteQWinloss != NULL) { + whiteQWinloss = new float[nnXLen * nnYLen]; + std::copy(other.whiteQWinloss, other.whiteQWinloss + nnXLen * nnYLen, whiteQWinloss); + } + else + whiteQWinloss = NULL; + if(other.whiteQScore != NULL) { + whiteQScore = new float[nnXLen * nnYLen]; + std::copy(other.whiteQScore, other.whiteQScore + nnXLen * nnYLen, whiteQScore); + } + else + whiteQScore = NULL; + if(other.whiteOwnerMap != NULL) { whiteOwnerMap = new float[nnXLen * nnYLen]; std::copy(other.whiteOwnerMap, other.whiteOwnerMap + nnXLen * nnYLen, whiteOwnerMap); @@ -395,6 +409,50 @@ NNOutput::NNOutput(const vector>& others) { nnXLen = others[0]->nnXLen; nnYLen = others[0]->nnYLen; + { + float whiteQWinlossCount = 0.0f; + whiteQWinloss = NULL; + for(int i = 0; i 0); + for(int pos = 0; pos 0); + for(int pos = 0; pos Setup::initializeNNEvaluators( cfg.contains("nnRandomize") ? cfg.getBool("nnRandomize") : true; + bool enableQValues = cfg.getBool("enableQValues"); + string nnRandSeed; if(setupFor == SETUP_FOR_DISTRIBUTED) nnRandSeed = Global::uint64ToString(seedRand.nextUInt64()); @@ -324,6 +326,7 @@ vector Setup::initializeNNEvaluators( gpuIdxByServerThread, nnRandSeed, (forcedSymmetry >= 0 ? false : nnRandomize), + enableQValues, defaultSymmetry ); diff --git a/cpp/search/search.h b/cpp/search/search.h index f327112ee..869a42e23 100644 --- a/cpp/search/search.h +++ b/cpp/search/search.h @@ -401,8 +401,15 @@ struct Search { //Fill json with analysis engine format information about search results bool getAnalysisJson( const Player perspective, - int analysisPVLen, bool preventEncore, bool includePolicy, - bool includeOwnership, bool includeOwnershipStdev, bool includeMovesOwnership, bool includeMovesOwnershipStdev, bool includePVVisits, + int analysisPVLen, + bool preventEncore, + bool includePolicy, + bool includeOwnership, + bool includeOwnershipStdev, + bool includeMovesOwnership, + bool includeMovesOwnershipStdev, + bool includePVVisits, + bool includeQValues, nlohmann::json& ret ) const; diff --git a/cpp/search/searchresults.cpp b/cpp/search/searchresults.cpp index e3b183e8a..445f02db7 100644 --- a/cpp/search/searchresults.cpp +++ b/cpp/search/searchresults.cpp @@ -1998,6 +1998,7 @@ bool Search::getAnalysisJson( bool includeMovesOwnership, bool includeMovesOwnershipStdev, bool includePVVisits, + bool includeQValues, json& ret ) const { vector buf; @@ -2129,6 +2130,33 @@ bool Search::getAnalysisJson( rootInfo["rawStWrError"] = Global::roundDynamic(nnOutput->shorttermWinlossError * 0.5,OUTPUT_PRECISION); rootInfo["rawStScoreError"] = Global::roundDynamic(nnOutput->shorttermScoreError,OUTPUT_PRECISION); rootInfo["rawVarTimeLeft"] = Global::roundDynamic(nnOutput->varTimeLeft,OUTPUT_PRECISION); + + if(includeQValues && nnOutput->whiteQWinloss != NULL) { + json thisSideQWinloss = json::array(); + json thisSideQScore = json::array(); + for(int y = 0; y < board.y_size; y++) { + for(int x = 0; x < board.x_size; x++) { + int pos = NNPos::xyToPos(x, y, nnXLen); + if(nnOutput->policyProbs[pos] < 0) { + thisSideQWinloss.push_back(nullptr); + thisSideQScore.push_back(nullptr); + } + else { + thisSideQWinloss.push_back(Global::roundDynamic(nnOutput->whiteQWinloss[pos]*flipFactor,OUTPUT_PRECISION)); + thisSideQScore.push_back(Global::roundDynamic(nnOutput->whiteQScore[pos]*flipFactor,OUTPUT_PRECISION)); + } + } + } + int pos = NNPos::locToPos(Board::PASS_LOC, board.x_size, nnXLen, nnYLen); + if(nnOutput->policyProbs[pos] < 0) { + thisSideQWinloss.push_back(nullptr); + thisSideQScore.push_back(nullptr); + } + else{ + thisSideQWinloss.push_back(Global::roundDynamic(nnOutput->whiteQWinloss[pos]*flipFactor,OUTPUT_PRECISION)); + thisSideQScore.push_back(Global::roundDynamic(nnOutput->whiteQScore[pos]*flipFactor,OUTPUT_PRECISION)); + } + } } if(humanOutput != NULL) { rootInfo["humanWinrate"] = Global::roundDynamic(0.5 + 0.5*(humanOutput->whiteWinProb - humanOutput->whiteLossProb)*flipFactor,OUTPUT_PRECISION); @@ -2175,8 +2203,8 @@ bool Search::getAnalysisJson( } } - int passPos = NNPos::locToPos(Board::PASS_LOC, board.x_size, nnXLen, nnYLen); - policy.push_back(Global::roundDynamic(policyProbs[passPos],OUTPUT_PRECISION)); + int pos = NNPos::locToPos(Board::PASS_LOC, board.x_size, nnXLen, nnYLen); + policy.push_back(Global::roundDynamic(policyProbs[pos],OUTPUT_PRECISION)); ret["policy"] = policy; } @@ -2189,8 +2217,8 @@ bool Search::getAnalysisJson( policy.push_back(Global::roundDynamic(policyProbs[pos],OUTPUT_PRECISION)); } } - int passPos = NNPos::locToPos(Board::PASS_LOC, board.x_size, nnXLen, nnYLen); - policy.push_back(Global::roundDynamic(policyProbs[passPos],OUTPUT_PRECISION)); + int pos = NNPos::locToPos(Board::PASS_LOC, board.x_size, nnXLen, nnYLen); + policy.push_back(Global::roundDynamic(policyProbs[pos],OUTPUT_PRECISION)); ret["humanPolicy"] = policy; } } diff --git a/cpp/tests/testsearchcommon.cpp b/cpp/tests/testsearchcommon.cpp index e5bc10d6e..d65d99f87 100644 --- a/cpp/tests/testsearchcommon.cpp +++ b/cpp/tests/testsearchcommon.cpp @@ -206,6 +206,7 @@ NNEvaluator* TestSearchCommon::startNNEval( const string homeDataDirOverride = ""; int numNNServerThreadsPerModel = 1; bool nnRandomize = false; + bool enableQValues = true; string nnRandSeed = "runSearchTestsRandSeed"+seed; if(defaultSymmetry == -1) { @@ -236,6 +237,7 @@ NNEvaluator* TestSearchCommon::startNNEval( gpuIdxByServerThread, nnRandSeed, nnRandomize, + enableQValues, defaultSymmetry ); diff --git a/cpp/tests/testsearchnonn.cpp b/cpp/tests/testsearchnonn.cpp index 862bce25c..ff23dbe43 100644 --- a/cpp/tests/testsearchnonn.cpp +++ b/cpp/tests/testsearchnonn.cpp @@ -674,9 +674,10 @@ xx......x bool includeMovesOwnership = false; bool includeMovesOwnershipStdev = false; bool includePVVisits = false; + bool includeQValues = false; bool suc = search->getAnalysisJson( perspective, analysisPVLen, preventEncore, - includePolicy, includeOwnership, includeOwnershipStdev, includeMovesOwnership, includeMovesOwnershipStdev, includePVVisits, + includePolicy, includeOwnership, includeOwnershipStdev, includeMovesOwnership, includeMovesOwnershipStdev, includePVVisits, includeQValues, json ); testAssert(suc); @@ -750,9 +751,10 @@ xx......x bool includeMovesOwnership = false; bool includeMovesOwnershipStdev = false; bool includePVVisits = false; + bool includeQValues = false; bool suc = search->getAnalysisJson( perspective, analysisPVLen, preventEncore, - includePolicy, includeOwnership, includeOwnershipStdev, includeMovesOwnership, includeMovesOwnershipStdev, includePVVisits, + includePolicy, includeOwnership, includeOwnershipStdev, includeMovesOwnership, includeMovesOwnershipStdev, includePVVisits, includeQValues, json ); testAssert(suc); @@ -826,9 +828,10 @@ xx......x bool includeMovesOwnership = false; bool includeMovesOwnershipStdev = false; bool includePVVisits = false; + bool includeQValues = false; bool suc = search->getAnalysisJson( perspective, analysisPVLen, preventEncore, - includePolicy, includeOwnership, includeOwnershipStdev, includeMovesOwnership, includeMovesOwnershipStdev, includePVVisits, + includePolicy, includeOwnership, includeOwnershipStdev, includeMovesOwnership, includeMovesOwnershipStdev, includePVVisits, includeQValues, json ); testAssert(suc); @@ -1216,9 +1219,10 @@ ooooo.oooooooo bool includeMovesOwnership = false; bool includeMovesOwnershipStdev = false; bool includePVVisits = true; + bool includeQValues = false; bool suc = search->getAnalysisJson( perspective, analysisPVLen, preventEncore, - includePolicy, includeOwnership, includeOwnershipStdev, includeMovesOwnership, includeMovesOwnershipStdev, includePVVisits, + includePolicy, includeOwnership, includeOwnershipStdev, includeMovesOwnership, includeMovesOwnershipStdev, includePVVisits, includeQValues, json ); testAssert(suc); @@ -1269,9 +1273,10 @@ ooooo.oooooooo bool includeMovesOwnership = true; bool includeMovesOwnershipStdev = true; bool includePVVisits = false; + bool includeQValues = false; bool suc = search->getAnalysisJson( perspective, analysisPVLen, preventEncore, - includePolicy, includeOwnership, includeOwnershipStdev, includeMovesOwnership, includeMovesOwnershipStdev, includePVVisits, + includePolicy, includeOwnership, includeOwnershipStdev, includeMovesOwnership, includeMovesOwnershipStdev, includePVVisits, includeQValues, json ); testAssert(suc); @@ -1323,9 +1328,10 @@ ooooo.oooooooo bool includeMovesOwnership = true; bool includeMovesOwnershipStdev = true; bool includePVVisits = false; + bool includeQValues = false; bool suc = search->getAnalysisJson( perspective, analysisPVLen, preventEncore, - includePolicy, includeOwnership, includeOwnershipStdev, includeMovesOwnership, includeMovesOwnershipStdev, includePVVisits, + includePolicy, includeOwnership, includeOwnershipStdev, includeMovesOwnership, includeMovesOwnershipStdev, includePVVisits, includeQValues, json ); testAssert(suc); @@ -1375,9 +1381,10 @@ xxxxxxxxx bool includeMovesOwnership = false; bool includeMovesOwnershipStdev = false; bool includePVVisits = false; + bool includeQValues = false; bool suc = search->getAnalysisJson( perspective, analysisPVLen, preventEncore, - includePolicy, includeOwnership, includeOwnershipStdev, includeMovesOwnership, includeMovesOwnershipStdev, includePVVisits, + includePolicy, includeOwnership, includeOwnershipStdev, includeMovesOwnership, includeMovesOwnershipStdev, includePVVisits, includeQValues, json ); testAssert(suc); @@ -1446,9 +1453,10 @@ xxxxxxxxx bool includeMovesOwnership = false; bool includeMovesOwnershipStdev = false; bool includePVVisits = true; + bool includeQValues = false; suc = search->getAnalysisJson( perspective, analysisPVLen, preventEncore, - includePolicy, includeOwnership, includeOwnershipStdev, includeMovesOwnership, includeMovesOwnershipStdev, includePVVisits, + includePolicy, includeOwnership, includeOwnershipStdev, includeMovesOwnership, includeMovesOwnershipStdev, includePVVisits, includeQValues, json ); cout << "getAnalysisJson success: " << suc << endl; @@ -1736,9 +1744,10 @@ oo..o..oo bool includeMovesOwnership = false; bool includeMovesOwnershipStdev = false; bool includePVVisits = false; + bool includeQValues = false; bool suc = search->getAnalysisJson( perspective, analysisPVLen, preventEncore, - includePolicy, includeOwnership, includeOwnershipStdev, includeMovesOwnership, includeMovesOwnershipStdev, includePVVisits, + includePolicy, includeOwnership, includeOwnershipStdev, includeMovesOwnership, includeMovesOwnershipStdev, includePVVisits, includeQValues, json ); testAssert(suc); @@ -1802,9 +1811,10 @@ oo..o..oo bool includeMovesOwnership = false; bool includeMovesOwnershipStdev = false; bool includePVVisits = false; + bool includeQValues = false; bool suc = search->getAnalysisJson( perspective, analysisPVLen, preventEncore, - includePolicy, includeOwnership, includeOwnershipStdev, includeMovesOwnership, includeMovesOwnershipStdev, includePVVisits, + includePolicy, includeOwnership, includeOwnershipStdev, includeMovesOwnership, includeMovesOwnershipStdev, includePVVisits, includeQValues, json ); testAssert(suc); @@ -1848,9 +1858,10 @@ oo..o..oo bool includeMovesOwnership = false; bool includeMovesOwnershipStdev = false; bool includePVVisits = false; + bool includeQValues = false; bool suc = search->getAnalysisJson( perspective, analysisPVLen, preventEncore, - includePolicy, includeOwnership, includeOwnershipStdev, includeMovesOwnership, includeMovesOwnershipStdev, includePVVisits, + includePolicy, includeOwnership, includeOwnershipStdev, includeMovesOwnership, includeMovesOwnershipStdev, includePVVisits, includeQValues, json ); testAssert(suc); diff --git a/cpp/tests/testtrainingwrite.cpp b/cpp/tests/testtrainingwrite.cpp index f93809d9d..830da5fb4 100644 --- a/cpp/tests/testtrainingwrite.cpp +++ b/cpp/tests/testtrainingwrite.cpp @@ -27,6 +27,7 @@ static NNEvaluator* startNNEval( bool openCLReTunePerBoardSize = false; int numNNServerThreadsPerModel = 1; bool nnRandomize = false; + bool enableQValues = true; string expectedSha256 = ""; NNEvaluator* nnEval = new NNEvaluator( @@ -51,6 +52,7 @@ static NNEvaluator* startNNEval( gpuIdxByServerThread, seed, nnRandomize, + enableQValues, defaultSymmetry );