usiReporter.cc
Go to the documentation of this file.
00001 /* usiReporter.cc
00002  */
00003 #include "osl/search/usiReporter.h"
00004 #include "osl/record/usi.h"
00005 #include "osl/misc/lightMutex.h"
00006 #include "osl/misc/milliSeconds.h"
00007 #include "osl/oslConfig.h"
00008 #include <iostream>
00009 
00010 void osl::search::
00011 UsiReporter::newDepth(std::ostream& os, int depth)
00012 {
00013   if (OslConfig::usiModeInSilent())
00014     return;
00015   os << "info depth " << depth << "\n";
00016 }
00017 void osl::search::
00018 UsiReporter::showPV(std::ostream& os, int depth, size_t node_count, double elapsed, int value, Move cur, const Move *first, const Move *last, bool ignore_silent)
00019 {
00020   if (OslConfig::usiModeInSilent() && ! ignore_silent)
00021     return;
00022   int seldepth = last-first;
00023   if (last == first || *first != cur)
00024     ++seldepth;
00025   if (ignore_silent)
00026     std::cerr << "info depth " << depth << " seldepth " << seldepth
00027               << " time " << static_cast<int>(elapsed*1000) << " score cp " << value
00028               << " nodes " << node_count
00029               << " nps " << static_cast<int>(node_count/elapsed)
00030               << " pv " << record::usi::show(cur) << "\n";
00031   os << "info depth " << depth << " seldepth " << seldepth
00032      << " time " << static_cast<int>(elapsed*1000) << " score cp " << value
00033      << " nodes " << node_count << " nps " << static_cast<int>(node_count/elapsed);
00034   os << " pv " << record::usi::show(cur);
00035   if (first != last) {
00036     if (cur == *first)
00037       ++first;
00038     while (first != last) {
00039       os << ' ' << record::usi::show(*first++);
00040     }
00041   }
00042   os << "\n";
00043 }
00044 
00045 void osl::search::
00046 UsiReporter::showPVExtended(std::ostream& os, int depth, size_t node_count, double elapsed, int value, Move cur, const Move *first, const Move *last, const bool *tfirst, const bool *tlast)
00047 {
00048   if (OslConfig::usiModeInSilent())
00049     return;
00050   int seldepth = last-first;
00051   assert(seldepth == tlast-tfirst);
00052   if (last - first && *first != cur)
00053     ++seldepth;
00054   os << "info depth " << depth << " seldepth " << seldepth
00055      << " time " << static_cast<int>(elapsed*1000) << " score cp " << value
00056      << " nodes " << node_count << " nps " << static_cast<int>(node_count/elapsed);
00057   os << " pv " << record::usi::show(cur);
00058   if (first != last) {
00059     if (cur == *first)
00060       ++first, ++tfirst;
00061     while (first != last) {
00062       os << ' ' << record::usi::show(*first++);
00063       if (tfirst != tlast && *tfirst++)
00064         os << "(^)";
00065     }
00066   }
00067   os << "\n";
00068 }
00069 
00070 static osl::misc::LightMutex usi_root_move_mutex;
00071 void osl::search::
00072 UsiReporter::rootMove(std::ostream& os, Move cur, bool allow_frequent_display)
00073 {
00074   if (OslConfig::usiModeInSilent())
00075     return;
00076   static MilliSeconds prev;
00077   if (! allow_frequent_display) 
00078   {
00079     MilliSeconds now = MilliSeconds::now();
00080     {
00081       SCOPED_LOCK(lk, usi_root_move_mutex);
00082       if ((now - prev).toSeconds() < 0.5)
00083         return;
00084       prev = now;
00085     }
00086   }
00087   os << "info currmove " << record::usi::show(cur) << "\n";
00088 }
00089 
00090 void osl::search::
00091 UsiReporter::timeInfo(std::ostream& os, size_t node_count, double elapsed)
00092 {
00093   if (OslConfig::usiModeInSilent())
00094     return;
00095   os << "info time " << static_cast<int>(elapsed*1000)
00096      << " nodes " << node_count << " nps " << static_cast<int>(node_count/elapsed) << "\n";
00097   os << std::flush;
00098 }
00099 
00100 void osl::search::
00101 UsiReporter::hashInfo(std::ostream& os, double ratio)
00102 {
00103   if (OslConfig::usiModeInSilent())
00104     return;
00105   os << "info hashfull " << static_cast<int>(ratio*1000) << "\n";
00106   os << std::flush;
00107 }
00108 
00109 
00110 
00111 osl::search::
00112 UsiMonitor::UsiMonitor(bool ex, std::ostream& o, double s)
00113   : silent_period(s), extended(ex), os(o), udp_socket(0), udp_endpoint(0),
00114     client_id("")
00115 {
00116 }
00117 
00118 osl::search::
00119 UsiMonitor::~UsiMonitor()
00120 {
00121 }
00122 
00123 void osl::search::
00124 UsiMonitor::showDeferred(bool forced)
00125 {
00126   if ((!forced && depth0.elapsedSeconds() < silent_period)
00127       || deferred.empty())
00128     return;
00129   os << deferred << std::flush;
00130   if (udp_socket) {
00131     if (client_id != "")
00132       deferred = client_id + " " + deferred;
00133     boost::system::error_code ignored_error;
00134     udp_socket->send_to(boost::asio::buffer(deferred.c_str(), deferred.length()),
00135                         *udp_endpoint,
00136                         0, ignored_error);
00137   }
00138   deferred.clear();
00139 }
00140 
00141 void osl::search::
00142 UsiMonitor::newDepth(int depth)
00143 {
00144   last_root_move = Move();
00145   if (depth == 0) {
00146     depth0 = MilliSeconds::now();
00147     return;
00148   }
00149   if (depth0.elapsedSeconds() >= silent_period) {
00150     showDeferred();
00151     UsiReporter::newDepth(os, depth);
00152   }
00153 }
00154 
00155 void osl::search::
00156 UsiMonitor::showPV(int depth, size_t node_count, double elapsed, int value, Move cur, const Move *first, const Move *last,
00157                    const bool *threatmate_first, const bool *threatmate_last)
00158 {
00159   const bool defer = depth0.elapsedSeconds() < silent_period;
00160   std::ostringstream ss;
00161   if (extended)
00162     UsiReporter::showPVExtended(ss, depth, node_count, elapsed, value, cur, first, last, 
00163                                 threatmate_first, threatmate_last);
00164   else
00165     UsiReporter::showPV(ss, depth, node_count, elapsed, value, cur, first, last);
00166   if (defer)
00167     deferred = ss.str();
00168   else {
00169     std::string msg = ss.str();
00170     os << msg << std::flush;
00171     if (udp_socket) {
00172       if (client_id != "")
00173         msg = client_id + " " + msg;
00174       boost::system::error_code ignored_error;
00175       udp_socket->send_to(boost::asio::buffer(msg.c_str(), msg.length()),
00176                           *udp_endpoint, 0,
00177                           ignored_error);
00178     }
00179     deferred.clear();           // msg sent was newer than deferred
00180   }
00181 }
00182 
00183 void osl::search::UsiMonitor::
00184 showFailLow(int depth, size_t node_count, double elapsed, int value, Move cur)
00185 {
00186   showPV(depth, node_count, elapsed, value, cur, 0, 0, 0, 0);
00187 }
00188 
00189 void osl::search::
00190 UsiMonitor::rootMove(Move cur)
00191 {
00192   showDeferred();
00193   last_root_move = cur;
00194 }
00195 
00196 void osl::search::
00197 UsiMonitor::rootFirstMove(Move cur)
00198 {
00199   showDeferred();
00200   last_root_move = cur;
00201   UsiReporter::rootMove(os, cur, true);
00202 }
00203 
00204 void osl::search::
00205 UsiMonitor::timeInfo(size_t node_count, double elapsed)
00206 {
00207   showDeferred();
00208   {
00209     std::ostringstream ss;
00210     UsiReporter::timeInfo(ss, node_count, elapsed);
00211     std::string msg = ss.str();
00212     os << msg << std::flush;
00213     if (udp_socket) {
00214       if (client_id != "")
00215         msg = client_id + " " + msg;
00216       boost::system::error_code ignored_error;
00217       udp_socket->send_to(boost::asio::buffer(msg.c_str(), msg.length()),
00218                           *udp_endpoint, 0,
00219                           ignored_error);
00220     }    
00221   }
00222   UsiReporter::rootMove(os, last_root_move);
00223 }
00224 
00225 void osl::search::
00226 UsiMonitor::hashInfo(double ratio)
00227 {
00228   showDeferred();
00229   UsiReporter::hashInfo(os, ratio);
00230 }
00231 
00232 void osl::search::
00233 UsiMonitor::rootForcedMove(Move the_move)
00234 {
00235   if (OslConfig::usiModeInSilent())
00236     return;
00237   showDeferred();
00238   os << "info string forced move at the root: "
00239      << record::usi::show(the_move) << "\n";
00240   os << std::flush;
00241 }
00242 
00243 void osl::search::
00244 UsiMonitor::rootLossByCheckmate()
00245 {
00246   if (OslConfig::usiModeInSilent())
00247     return;
00248   deferred.clear();
00249   os << "info string loss by checkmate\n";
00250   os << std::flush;
00251 }
00252 
00253 void osl::search::
00254 UsiMonitor::setUdpLogging(std::string& udp_client_id,
00255                           boost::asio::ip::udp::socket *s,
00256                           boost::asio::ip::udp::endpoint *e)
00257 {
00258   client_id = udp_client_id;
00259   udp_socket = s;
00260   udp_endpoint = e;
00261 }
00262 
00263 void osl::search::
00264 UsiMonitor::searchFinished()
00265 {
00266   showDeferred(true);
00267 }
00268 
00269 // ;;; Local Variables:
00270 // ;;; mode:c++
00271 // ;;; c-basic-offset:2
00272 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines