Merged the training data generator and the machine learning logic from YaneuraOu.

This commit is contained in:
Hisayori Noda
2019-06-18 08:48:05 +09:00
parent 87445881ec
commit bcd6985871
37 changed files with 6306 additions and 139 deletions

View File

@@ -24,11 +24,13 @@
#include <algorithm>
#include <cassert>
#include <chrono>
#include <functional>
#include <ostream>
#include <string>
#include <vector>
#include "types.h"
#include "thread_win32_osx.h"
const std::string engine_info(bool to_uci = false);
void prefetch(void* addr);
@@ -98,8 +100,20 @@ public:
/// Output values only have 1/8th of their bits set on average.
template<typename T> T sparse_rand()
{ return T(rand64() & rand64() & rand64()); }
// 0からn-1までの乱数を返す。(一様分布ではないが現実的にはこれで十分)
uint64_t rand(uint64_t n) { return rand<uint64_t>() % n; }
// 内部で使用している乱数seedを返す。
uint64_t get_seed() const { return s; }
};
// 乱数のseedを表示する。(デバッグ用)
inline std::ostream& operator<<(std::ostream& os, PRNG& prng)
{
os << "PRNG::seed = " << std::hex << prng.get_seed() << std::dec;
return os;
}
/// Under Windows it is not possible for a process to run on more than one
/// logical processor group. This usually means to be limited to use max 64
@@ -114,6 +128,9 @@ namespace WinProcGroup {
// 指定されたミリ秒だけsleepする。
extern void sleep(int ms);
// 現在時刻を文字列化したもを返す。(評価関数の学習時などにログ出力のために用いる)
std::string now_string();
// 途中での終了処理のためのwrapper
static void my_exit()
{
@@ -121,6 +138,54 @@ static void my_exit()
exit(EXIT_FAILURE);
}
// msys2、Windows Subsystem for Linuxなどのgcc/clangでコンパイルした場合、
// C++のstd::ifstreamで::read()は、一発で2GB以上のファイルの読み書きが出来ないのでそのためのwrapperである。
//
// read_file_to_memory()の引数のcallback_funcは、ファイルがオープン出来た時点でそのファイルサイズを引数として
// callbackされるので、バッファを確保して、その先頭ポインタを返す関数を渡すと、そこに読み込んでくれる。
// これらの関数は、ファイルが見つからないときなどエラーの際には非0を返す。
//
// また、callbackされた関数のなかでバッファが確保できなかった場合や、想定していたファイルサイズと異なった場合は、
// nullptrを返せば良い。このとき、read_file_to_memory()は、読み込みを中断し、エラーリターンする。
int read_file_to_memory(std::string filename, std::function<void* (uint64_t)> callback_func);
int write_memory_to_file(std::string filename, void* ptr, uint64_t size);
// --------------------
// PRNGのasync版
// --------------------
// PRNGのasync版
struct AsyncPRNG
{
AsyncPRNG(uint64_t seed) : prng(seed) { assert(seed); }
// [ASYNC] 乱数を一つ取り出す。
template<typename T> T rand() {
std::unique_lock<Mutex> lk(mutex);
return prng.rand<T>();
}
// [ASYNC] 0からn-1までの乱数を返す。(一様分布ではないが現実的にはこれで十分)
uint64_t rand(uint64_t n) {
std::unique_lock<Mutex> lk(mutex);
return prng.rand(n);
}
// 内部で使用している乱数seedを返す。
uint64_t get_seed() const { return prng.get_seed(); }
protected:
Mutex mutex;
PRNG prng;
};
// 乱数のseedを表示する。(デバッグ用)
inline std::ostream& operator<<(std::ostream& os, AsyncPRNG& prng)
{
os << "AsyncPRNG::seed = " << std::hex << prng.get_seed() << std::dec;
return os;
}
// --------------------
// Math
// --------------------
@@ -176,4 +241,39 @@ struct Path
extern void* aligned_malloc(size_t size, size_t align);
static void aligned_free(void* ptr) { _mm_free(ptr); }
// alignasを指定しているのにnewのときに無視されるSTLのコンテナがメモリ確保するときに無視するので、
// そのために用いるカスタムアロケーター。
template <typename T>
class AlignedAllocator {
public:
using value_type = T;
AlignedAllocator() {}
AlignedAllocator(const AlignedAllocator&) {}
AlignedAllocator(AlignedAllocator&&) {}
template <typename U> AlignedAllocator(const AlignedAllocator<U>&) {}
T* allocate(std::size_t n) { return (T*)aligned_malloc(n * sizeof(T), alignof(T)); }
void deallocate(T* p, std::size_t n) { aligned_free(p); }
};
// --------------------
// Dependency Wrapper
// --------------------
namespace Dependency
{
// Linux環境ではgetline()したときにテキストファイルが'\r\n'だと
// '\r'が末尾に残るのでこの'\r'を除去するためにwrapperを書く。
// そのため、fstreamに対してgetline()を呼び出すときは、
// std::getline()ではなく単にgetline()と書いて、この関数を使うべき。
extern bool getline(std::ifstream& fs, std::string& s);
// フォルダを作成する。
// カレントフォルダ相対で指定する。dir_nameに日本語は使っていないものとする。
// 成功すれば0、失敗すれば非0が返る。
extern int mkdir(std::string dir_name);
}
#endif // #ifndef MISC_H_INCLUDED