From 16e7fc22b6170855bc49cb15866342dee01202fc Mon Sep 17 00:00:00 2001 From: Mizar Date: Sat, 30 Apr 2022 11:39:46 +0900 Subject: [PATCH] build MacOS & WebAssembly, install CUDA-11.6 + TensorRT8.2.4 (#231) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * - nproc * - YANEURAOU_ENGINE_MATERIAL* ビルドテストの一部省略 * - release build material lv1,lv9 * - pacboy -Syuu * - remove base-devel: from actions * - remove base-devel: * - pacman update * - POPCNT, BSF, BSR の実装パターン追加 * - MacOS * - NuGet packages bump up * - CUDA 11.6 Update 2, TensorRT 8.2 GA Update 3, cuda-nvrtc, remove copy cuda dlls - CUDA gpg-key change cf. https://github.com/NVIDIA/cuda-repo-management/issues/4 * - clang-15 * - DNN_Batch_Size max 1024 * - fp16 * - .gitignore * - badge MacOS, WebAssembly * - WASM port cf. https://github.com/arashigaoka/YaneuraOu.wasm cf. https://github.com/niklasf/stockfish.wasm cf. https://github.com/hi-ogawa/Stockfish * - wasm_build * - github workflows: wasm --- .github/workflows/make-deep-ubuntu.yml | 30 +- .github/workflows/make-macos.yml | 255 ++++ .github/workflows/make-mingw.yml | 5 +- .github/workflows/make-msys2.yml | 7 +- .github/workflows/make-wasm.yml | 50 + .github/workflows/make.yml | 20 +- .github/workflows/ndk.yml | 3 +- .github/workflows/release.yml | 1089 +++++++++++++++-- .gitignore | 10 +- README.md | 2 + "docs/\350\247\243\350\252\254.txt" | 10 +- jni/Android.mk | 2 + script/android_build.sh | 4 +- script/build.sh | 3 +- script/mingw_gcc.sh | 3 +- script/msys2_build.ps1 | 3 +- script/msys2_build.sh | 6 +- script/msys2_build32.sh | 6 +- script/wasm_build.cmd | 5 + script/wasm_build.js | 325 +++++ script/wasm_build.sh | 7 + script/wasm_docker_build.js | 33 + source/Makefile | 66 +- source/YaneuraOu.vcxproj | 40 +- source/book/book.cpp | 24 +- .../YaneuraOu_dlshogi_bridge.cpp | 36 +- source/eval/deep/nn_tensorrt.cpp | 10 + source/eval/deep/nn_types.cpp | 5 + source/eval/deep/nn_types.h | 29 +- source/eval/nnue/evaluate_nnue.cpp | 14 +- source/eval/nnue/layers/affine_transform.h | 15 + source/eval/nnue/nnue_common.h | 6 + source/eval/nnue/nnue_feature_transformer.h | 2 +- source/eval/nnue/wasm_simd.cpp | 95 ++ source/eval/nnue/wasm_simd.h | 13 + source/extra/bitop.h | 48 +- source/main.cpp | 5 + source/misc.cpp | 2 + source/packages.config | 10 +- .../props/YaneuraOuEdition-Deep-ORT-TRT.props | 40 +- .../YaneuraOuEdition-Deep-TensorRT.props | 40 +- source/thread.cpp | 45 +- source/thread.h | 11 +- source/tt.cpp | 9 +- source/usi.cpp | 96 +- source/usi_option.cpp | 40 +- source/wasm_pre.js | 62 + 47 files changed, 2316 insertions(+), 325 deletions(-) create mode 100644 .github/workflows/make-macos.yml create mode 100644 .github/workflows/make-wasm.yml create mode 100644 script/wasm_build.cmd create mode 100755 script/wasm_build.js create mode 100755 script/wasm_build.sh create mode 100755 script/wasm_docker_build.js create mode 100644 source/eval/nnue/wasm_simd.cpp create mode 100644 source/eval/nnue/wasm_simd.h create mode 100644 source/wasm_pre.js diff --git a/.github/workflows/make-deep-ubuntu.yml b/.github/workflows/make-deep-ubuntu.yml index 05d6ba403..78384e683 100644 --- a/.github/workflows/make-deep-ubuntu.yml +++ b/.github/workflows/make-deep-ubuntu.yml @@ -27,6 +27,7 @@ jobs: - clang++-12 - clang++-13 - clang++-14 + - clang++-15 target: - normal archcpu: @@ -100,23 +101,38 @@ jobs: sudo cat /etc/apt/sources.list sudo ls -R /etc/apt/sources.list.d if: ${{ matrix.compiler == 'clang++-14' }} + - name: install clang-15 + # LLVM APT + run: | + # Remove packages that conflict with clang-15 installation + sudo apt remove -y \ + liblldb-10 libomp-10-dev libomp5-10 lldb-10 python3-lldb-10 \ + liblldb-11 libomp-11-dev libomp5-11 lldb-11 python3-lldb-11 \ + liblldb-12 libomp-12-dev libomp5-12 lldb-12 python3-lldb-12 + # install clang-15 + wget https://apt.llvm.org/llvm.sh + sudo bash ./llvm.sh 15 + sudo cat /etc/apt/sources.list + sudo ls -R /etc/apt/sources.list.d + if: ${{ matrix.compiler == 'clang++-15' }} - name: install CUDA, TensorRT - # ここではCUDAアプリケーションの開発環境用に、CUDAドライバーを含まない cuda-minimal-build-11-5 をインストールしている。 - # CUDAアプリケーションの実行環境用にセットアップする場合、 cuda-minimal-build-11-5 の代わりに - # CUDAドライバーを含むメタパッケージ、 cuda-11-5 もしくは cuda をインストールする。 + # ここではCUDAアプリケーションの開発環境用に、CUDAドライバーを含まない cuda-minimal-build-11-6 をインストールしている。 + # CUDAアプリケーションの実行環境用にセットアップする場合、 cuda-minimal-build-11-6 の代わりに + # CUDAドライバーを含むメタパッケージ、 cuda-11-6 もしくは cuda をインストールする。 # https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html#package-manager-metas + # https://github.com/NVIDIA/cuda-repo-management/issues/4 run: | sudo curl "https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/cuda-ubuntu2004.pin" -o /etc/apt/preferences.d/cuda-repository-pin-600 - sudo curl "https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/7fa2af80.pub" -o /usr/share/keyrings/cuda.gpg.asc - echo "deb [signed-by=/usr/share/keyrings/cuda.gpg.asc] https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/ /" | sudo tee /etc/apt/sources.list.d/cuda.list &&\ + sudo curl "https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/cuda-ubuntu2004-keyring.gpg" -o /usr/share/keyrings/cuda-archive-keyring.gpg + echo "deb [signed-by=/usr/share/keyrings/cuda-archive-keyring.gpg] https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/ /" | sudo tee /etc/apt/sources.list.d/cuda-ubuntu2004-x86_64.list &&\ sudo cat /etc/apt/sources.list sudo ls -R /etc/apt/sources.list.d sudo apt update - sudo apt install cuda-minimal-build-11-5 libnvinfer-dev libnvinfer-plugin-dev libnvonnxparsers-dev libnvparsers-dev + sudo apt install cuda-minimal-build-11-6 cuda-nvrtc-dev-11-6 libcublas-11-6 libcublas-dev-11-6 libnvinfer-dev libnvinfer-plugin-dev libnvonnxparsers-dev libnvparsers-dev - name: make - run: ./main/script/build.sh -e ${{ matrix.edition }} -c ${{ matrix.compiler }} -t ${{ matrix.target }} -a ${{ matrix.archcpu }} -x "EXTRA_CPPFLAGS='-I/usr/local/cuda-11.5/include' EXTRA_LDFLAGS='-L/usr/local/cuda-11.5/lib64'" + run: ./main/script/build.sh -e ${{ matrix.edition }} -c ${{ matrix.compiler }} -t ${{ matrix.target }} -a ${{ matrix.archcpu }} -x "EXTRA_CPPFLAGS=-I/usr/local/cuda-11.6/include EXTRA_LDFLAGS=-L/usr/local/cuda-11.6/lib64 EXTRA_LDFLAGS+=-L/usr/local/cuda-11.6/lib64/stubs" - uses: actions/upload-artifact@v2 with: diff --git a/.github/workflows/make-macos.yml b/.github/workflows/make-macos.yml new file mode 100644 index 000000000..14748f550 --- /dev/null +++ b/.github/workflows/make-macos.yml @@ -0,0 +1,255 @@ +# for Linux environment +name: Make CI (for MacOS) + +on: + push: + branches: + - "**" + pull_request: + branches: + - "**" + +jobs: + build-macos: + # macos-11 + # https://docs.github.com/ja/actions/using-github-hosted-runners/about-github-hosted-runners + # https://github.com/actions/virtual-environments/blob/main/images/macos/macos-11-Readme.md + runs-on: macos-11 + + strategy: + matrix: + edition: + - YANEURAOU_ENGINE_NNUE + - "YANEURAOU_ENGINE_NNUE_HALFKP_VM_256X2_32_32,YANEURAOU_ENGINE_NNUE_HALFKPE9,YANEURAOU_ENGINE_NNUE_KP256" + - "YANEURAOU_ENGINE_KPPT,YANEURAOU_ENGINE_KPP_KKPT" + - "YANEURAOU_ENGINE_MATERIAL,YANEURAOU_ENGINE_MATERIAL9" + - "YANEURAOU_MATE_ENGINE,TANUKI_MATE_ENGINE" + - USER_ENGINE + compiler: + - clang++ + - g++-11 + target: + - "normal,tournament" + archcpu: + #- AVX2 + #- SSE42 + - APPLEAVX2 + - APPLESSE42 + - APPLEM1 + exclude: + - compiler: g++-11 + archcpu: APPLEAVX2 + - compiler: g++-11 + archcpu: APPLESSE42 + - compiler: g++-11 + archcpu: APPLEM1 + + steps: + - name: Checkout own repository + uses: actions/checkout@v2 + with: + path: main + + - name: make + uses: actions/github-script@v5 + env: + JOBS: '8' + EDITION: '${{ matrix.edition }}' + COMPILER: '${{ matrix.compiler }}' + TARGET: '${{ matrix.target }}' + CPU: '${{ matrix.archcpu }}' + OS: 'macos11' + with: + script: | + const fs = require('fs'); + const {JOBS, EDITION, COMPILER, TARGET, CPU, OS, EXTRA} = process.env; + const editionh = { + "YANEURAOU_ENGINE_NNUE": "YANEURAOU_ENGINE_NNUE", + "YANEURAOU_ENGINE_NNUE_HALFKP_VM_256X2_32_32": "YANEURAOU_ENGINE_NNUE_HALFKP_VM_256X2_32_32", + "YANEURAOU_ENGINE_NNUE_HALFKPE9": "YANEURAOU_ENGINE_NNUE_HALFKPE9", + "YANEURAOU_ENGINE_NNUE_KP256": "YANEURAOU_ENGINE_NNUE_KP256", + "YANEURAOU_ENGINE_DEEP_TENSOR_RT": "YANEURAOU_ENGINE_DEEP_TENSOR_RT", + "YANEURAOU_ENGINE_KPPT": "YANEURAOU_ENGINE_KPPT", + "YANEURAOU_ENGINE_KPP_KKPT": "YANEURAOU_ENGINE_KPP_KKPT", + "YANEURAOU_ENGINE_MATERIAL": "YANEURAOU_ENGINE_MATERIAL", + "YANEURAOU_ENGINE_MATERIAL2": "YANEURAOU_ENGINE_MATERIAL MATERIAL_LEVEL=2", + "YANEURAOU_ENGINE_MATERIAL3": "YANEURAOU_ENGINE_MATERIAL MATERIAL_LEVEL=3", + "YANEURAOU_ENGINE_MATERIAL4": "YANEURAOU_ENGINE_MATERIAL MATERIAL_LEVEL=4", + "YANEURAOU_ENGINE_MATERIAL5": "YANEURAOU_ENGINE_MATERIAL MATERIAL_LEVEL=5", + "YANEURAOU_ENGINE_MATERIAL6": "YANEURAOU_ENGINE_MATERIAL MATERIAL_LEVEL=6", + "YANEURAOU_ENGINE_MATERIAL7": "YANEURAOU_ENGINE_MATERIAL MATERIAL_LEVEL=7", + "YANEURAOU_ENGINE_MATERIAL8": "YANEURAOU_ENGINE_MATERIAL MATERIAL_LEVEL=8", + "YANEURAOU_ENGINE_MATERIAL9": "YANEURAOU_ENGINE_MATERIAL MATERIAL_LEVEL=9", + "YANEURAOU_ENGINE_MATERIAL10": "YANEURAOU_ENGINE_MATERIAL MATERIAL_LEVEL=10", + "YANEURAOU_MATE_ENGINE": "YANEURAOU_MATE_ENGINE", + "TANUKI_MATE_ENGINE": "TANUKI_MATE_ENGINE", + "USER_ENGINE": "USER_ENGINE", + }; + const dirh = { + "YANEURAOU_ENGINE_NNUE": "NNUE", + "YANEURAOU_ENGINE_NNUE_HALFKP_VM_256X2_32_32": "NNUE_HALFKP_VM", + "YANEURAOU_ENGINE_NNUE_HALFKPE9": "NNUE_HALFKPE9", + "YANEURAOU_ENGINE_NNUE_KP256": "NNUE_KP256", + "YANEURAOU_ENGINE_DEEP_TENSOR_RT": "DEEP_TRT", + "YANEURAOU_ENGINE_KPPT": "KPPT", + "YANEURAOU_ENGINE_KPP_KKPT": "KPP_KKPT", + "YANEURAOU_ENGINE_MATERIAL": "MaterialLv1", + "YANEURAOU_ENGINE_MATERIAL2": "MaterialLv2", + "YANEURAOU_ENGINE_MATERIAL3": "MaterialLv3", + "YANEURAOU_ENGINE_MATERIAL4": "MaterialLv4", + "YANEURAOU_ENGINE_MATERIAL5": "MaterialLv5", + "YANEURAOU_ENGINE_MATERIAL6": "MaterialLv6", + "YANEURAOU_ENGINE_MATERIAL7": "MaterialLv7", + "YANEURAOU_ENGINE_MATERIAL8": "MaterialLv8", + "YANEURAOU_ENGINE_MATERIAL9": "MaterialLv9", + "YANEURAOU_ENGINE_MATERIAL10": "MaterialLv10", + "YANEURAOU_MATE_ENGINE": "YaneuraOu_MATE", + "TANUKI_MATE_ENGINE": "tanuki_MATE", + "USER_ENGINE": "USER", + }; + const fileh = { + "YANEURAOU_ENGINE_NNUE": "YaneuraOu_NNUE", + "YANEURAOU_ENGINE_NNUE_HALFKP_VM_256X2_32_32": "YaneuraOu_NNUE_HALFKP_VM", + "YANEURAOU_ENGINE_NNUE_HALFKPE9": "YaneuraOu_NNUE_HalfKPE9", + "YANEURAOU_ENGINE_NNUE_KP256": "YaneuraOu_NNUE_KP256", + "YANEURAOU_ENGINE_DEEP_TENSOR_RT": "YaneuraOu_Deep_TRT", + "YANEURAOU_ENGINE_KPPT": "YaneuraOu_KPPT", + "YANEURAOU_ENGINE_KPP_KKPT": "YaneuraOu_KPP_KKPT", + "YANEURAOU_ENGINE_MATERIAL": "YaneuraOu_MaterialLv1", + "YANEURAOU_ENGINE_MATERIAL2": "YaneuraOu_MaterialLv2", + "YANEURAOU_ENGINE_MATERIAL3": "YaneuraOu_MaterialLv3", + "YANEURAOU_ENGINE_MATERIAL4": "YaneuraOu_MaterialLv4", + "YANEURAOU_ENGINE_MATERIAL5": "YaneuraOu_MaterialLv5", + "YANEURAOU_ENGINE_MATERIAL6": "YaneuraOu_MaterialLv6", + "YANEURAOU_ENGINE_MATERIAL7": "YaneuraOu_MaterialLv7", + "YANEURAOU_ENGINE_MATERIAL8": "YaneuraOu_MaterialLv8", + "YANEURAOU_ENGINE_MATERIAL9": "YaneuraOu_MaterialLv9", + "YANEURAOU_ENGINE_MATERIAL10": "YaneuraOu_MaterialLv10", + "YANEURAOU_MATE_ENGINE": "YaneuraOu_MATE", + "TANUKI_MATE_ENGINE": "tanuki_MATE", + "USER_ENGINE": "user", + }; + for(let edition of EDITION.split(',')) { + for(let compiler of COMPILER.split(',')) { + for(let target of TARGET.split(',')) { + for(let cpu of CPU.split(',')) { + const builddir = `../build/${OS}/${dirh[edition]}`; + const filename = `${fileh[edition]}-${OS}-${compiler}-${target}-${cpu.toLowerCase()}`; + let log = ''; + await io.mkdirP(`./main/source/${builddir}`); + await exec.exec('nice', `make -j${JOBS} ${target} TARGET_CPU=${cpu} YANEURAOU_EDITION=${editionh[edition]} COMPILER=${compiler} TARGET=${builddir}/${filename}`.split(' '), { + "cwd": "./main/source/", + listeners: { + stdout: (data) => { log += data.toString(); }, + stderr: (data) => { log += data.toString(); }, + } + }); + await exec.exec(`make`, `clean TARGET_CPU=${cpu} YANEURAOU_EDITION=${edition}`.split(' '), {"cwd": "./main/source/"}); + fs.writeFileSync(`./main/source/${builddir}/${filename}.log`, log); + }}}} + + - uses: actions/upload-artifact@v2 + with: + name: build-macos_${{ github.run_number }}_${{ github.sha }} + path: ./main/build/**/**/* + + build-macos-suisho: + # macos-11 + # https://docs.github.com/ja/actions/using-github-hosted-runners/about-github-hosted-runners + # https://github.com/actions/virtual-environments/blob/main/images/macos/macos-11-Readme.md + runs-on: macos-11 + + strategy: + matrix: + edition: + - YANEURAOU_ENGINE_NNUE + compiler: + - clang++ + - g++-11 + target: + - normal + - tournament + archcpu: + #- AVX2 + #- SSE42 + - APPLEAVX2 + - APPLESSE42 + - APPLEM1 + exclude: + - compiler: g++-11 + archcpu: APPLEAVX2 + - compiler: g++-11 + archcpu: APPLESSE42 + - compiler: g++-11 + archcpu: APPLEM1 + + steps: + - name: Checkout own repository + uses: actions/checkout@v2 + with: + path: main + + - name: suisho5 embedded_nnue + run: | + curl -LRo ./main/source/eval/nnue/embedded_nnue.cpp.gz "https://github.com/mizar/YaneuraOu/releases/download/resource/suisho5_20211123.halfkp.nnue.cpp.gz"; + gzip -df ./main/source/eval/nnue/embedded_nnue.cpp.gz; + + - name: make + uses: actions/github-script@v5 + env: + JOBS: '8' + EDITION: '${{ matrix.edition }}' + COMPILER: '${{ matrix.compiler }}' + TARGET: '${{ matrix.target }}' + CPU: '${{ matrix.archcpu }}' + OS: 'macos11' + with: + script: | + const fs = require('fs'); + const {JOBS, EDITION, COMPILER, TARGET, CPU, OS, EXTRA} = process.env; + const editionh = { + "YANEURAOU_ENGINE_NNUE": "YANEURAOU_ENGINE_NNUE", + "YANEURAOU_ENGINE_NNUE_HALFKP_VM_256X2_32_32": "YANEURAOU_ENGINE_NNUE_HALFKP_VM_256X2_32_32", + "YANEURAOU_ENGINE_NNUE_HALFKPE9": "YANEURAOU_ENGINE_NNUE_HALFKPE9", + "YANEURAOU_ENGINE_NNUE_KP256": "YANEURAOU_ENGINE_NNUE_KP256", + }; + const dirh = { + "YANEURAOU_ENGINE_NNUE": "NNUE", + "YANEURAOU_ENGINE_NNUE_HALFKP_VM_256X2_32_32": "NNUE_HALFKP_VM", + "YANEURAOU_ENGINE_NNUE_HALFKPE9": "NNUE_HALFKPE9", + "YANEURAOU_ENGINE_NNUE_KP256": "NNUE_KP256", + }; + const fileh = { + "YANEURAOU_ENGINE_NNUE": "Suisho5_YaneuraOu", + "YANEURAOU_ENGINE_NNUE_HALFKP_VM_256X2_32_32": "YaneuraOu_NNUE_HALFKP_VM", + "YANEURAOU_ENGINE_NNUE_HALFKPE9": "YaneuraOu_NNUE_HalfKPE9", + "YANEURAOU_ENGINE_NNUE_KP256": "YaneuraOu_NNUE_KP256", + }; + for(let edition of EDITION.split(',')) { + for(let compiler of COMPILER.split(',')) { + for(let target of TARGET.split(',')) { + for(let cpu of CPU.split(',')) { + const builddir = `../build/${OS}/${dirh[edition]}`; + const filename = `${fileh[edition]}-${OS}-${compiler}-${target}-${cpu.toLowerCase()}`; + let log = ''; + await io.mkdirP(`./main/source/${builddir}`); + await exec.exec('nice', `make -j${JOBS} ${target} TARGET_CPU=${cpu} YANEURAOU_EDITION=${editionh[edition]} COMPILER=${compiler} TARGET=${builddir}/${filename} EVAL_EMBEDDING=ON EXTRA_CPPFLAGS='-DENGINE_OPTIONS=\\\\\"\\\"option=name=FV_SCALE=type=spin=default=24=min=1=max=128\\;option=name=BookFile=type=combo=default=no_book=var=no_book=var=standard_book.db=var=yaneura_book1.db=var=yaneura_book2.db=var=yaneura_book3.db=var=yaneura_book4.db=var=user_book1.db=var=user_book2.db=var=user_book3.db=var=book.bin\\\\\\\"\"'`.split(' '), { + "cwd": "./main/source/", + listeners: { + stdout: (data) => { log += data.toString(); }, + stderr: (data) => { log += data.toString(); }, + } + }); + await exec.exec(`make`, `clean TARGET_CPU=${cpu} YANEURAOU_EDITION=${edition} EVAL_EMBEDDING=ON`.split(' '), {"cwd": "./main/source/"}); + fs.writeFileSync(`./main/source/${builddir}/${filename}.log`, log); + }}}} + + - name: add resource + run: | + echo 'Suisho5(20211123)-YaneuraOu' > ./main/build/macos11/NNUE/engine_name.txt; + echo 'yaneurao, tayayan' >> ./main/build/macos11/NNUE/engine_name.txt; + + - uses: actions/upload-artifact@v2 + with: + name: build-macos-embed_${{ github.run_number }}_${{ github.sha }} + path: ./main/build/**/**/* diff --git a/.github/workflows/make-mingw.yml b/.github/workflows/make-mingw.yml index 0f5c0e9ba..994d1e8af 100644 --- a/.github/workflows/make-mingw.yml +++ b/.github/workflows/make-mingw.yml @@ -25,7 +25,8 @@ jobs: - YANEURAOU_ENGINE_NNUE_KP256 - YANEURAOU_ENGINE_KPPT - YANEURAOU_ENGINE_KPP_KKPT - - YANEURAOU_ENGINE_MATERIAL* + #- YANEURAOU_ENGINE_MATERIAL* + - "YANEURAOU_ENGINE_MATERIAL,YANEURAOU_ENGINE_MATERIAL9" - YANEURAOU_MATE_ENGINE - TANUKI_MATE_ENGINE - USER_ENGINE @@ -66,6 +67,8 @@ jobs: # There is no machine learning implementation for the following editions - edition: YANEURAOU_ENGINE_MATERIAL* target: evallearn + - edition: "YANEURAOU_ENGINE_MATERIAL,YANEURAOU_ENGINE_MATERIAL9" + target: evallearn - edition: YANEURAOU_MATE_ENGINE target: evallearn - edition: TANUKI_MATE_ENGINE diff --git a/.github/workflows/make-msys2.yml b/.github/workflows/make-msys2.yml index 462df339d..dfb8b138a 100644 --- a/.github/workflows/make-msys2.yml +++ b/.github/workflows/make-msys2.yml @@ -26,7 +26,8 @@ jobs: - YANEURAOU_ENGINE_NNUE_KP256 - YANEURAOU_ENGINE_KPPT - YANEURAOU_ENGINE_KPP_KKPT - - YANEURAOU_ENGINE_MATERIAL* + #- YANEURAOU_ENGINE_MATERIAL* + - "YANEURAOU_ENGINE_MATERIAL,YANEURAOU_ENGINE_MATERIAL9" - YANEURAOU_MATE_ENGINE - TANUKI_MATE_ENGINE - USER_ENGINE @@ -46,6 +47,8 @@ jobs: # There is no machine learning implementation for the following editions - edition: YANEURAOU_ENGINE_MATERIAL* target: evallearn + - edition: "YANEURAOU_ENGINE_MATERIAL,YANEURAOU_ENGINE_MATERIAL9" + target: evallearn - edition: YANEURAOU_MATE_ENGINE target: evallearn - edition: TANUKI_MATE_ENGINE @@ -88,7 +91,7 @@ jobs: C:\msys64\usr\bin\bash.exe -lc 'pacman --needed --noconfirm -Syuu' C:\msys64\usr\bin\bash.exe -lc 'pacman --needed --noconfirm -Syuu' C:\msys64\usr\bin\bash.exe -lc 'pacman --needed --noconfirm -Syuu pactoys' - C:\msys64\usr\bin\bash.exe -lc 'pacboy --needed --noconfirm -Sy clang:m lld:m openblas:x openmp:x toolchain:m base-devel:' + C:\msys64\usr\bin\bash.exe -lc 'pacboy --needed --noconfirm -Syuu clang:m lld:m openblas:x openmp:x toolchain:m' $ErrorActionPreference = 'Stop' - name: make diff --git a/.github/workflows/make-wasm.yml b/.github/workflows/make-wasm.yml new file mode 100644 index 000000000..eefb5b929 --- /dev/null +++ b/.github/workflows/make-wasm.yml @@ -0,0 +1,50 @@ +# for Linux environment +name: Make CI (for WebAssembly) + +on: + push: + branches: + - "**" + pull_request: + branches: + - "**" + +jobs: + build-wasm: + # ubuntu-latest = ubuntu-20.04 + # https://docs.github.com/ja/actions/using-github-hosted-runners/about-github-hosted-runners + # https://github.com/actions/virtual-environments/blob/main/images/linux/Ubuntu2004-README.md + runs-on: ubuntu-20.04 + + strategy: + matrix: + edition: + - halfkp + - halfkp.noeval + - halfkpe9.noeval + - halfkpvm.noeval + - k-p + - k-p.noeval + - material + - material9 + - yaneuraou-mate + - tanuki-mate + + steps: + - name: Checkout own repository + uses: actions/checkout@v2 + with: + path: main + + - name: docker pull + run: | + docker pull emscripten/emsdk:latest + + - name: build wasm + run: | + docker run --rm -v ${PWD}/main:/src emscripten/emsdk:latest node script/wasm_build.js ${{ matrix.edition }} + + - uses: actions/upload-artifact@v2 + with: + name: build-wasm_${{ github.run_number }}_${{ github.sha }} + path: ./main/build/**/**/* diff --git a/.github/workflows/make.yml b/.github/workflows/make.yml index 20c436dd1..e31638a66 100644 --- a/.github/workflows/make.yml +++ b/.github/workflows/make.yml @@ -20,7 +20,8 @@ jobs: matrix: edition: - "YANEURAOU_ENGINE_NNUE,YANEURAOU_ENGINE_NNUE_HALFKP_VM_256X2_32_32,YANEURAOU_ENGINE_NNUE_HALFKPE9,YANEURAOU_ENGINE_NNUE_KP256,YANEURAOU_ENGINE_KPPT,YANEURAOU_ENGINE_KPP_KKPT" - - YANEURAOU_ENGINE_MATERIAL* + #- YANEURAOU_ENGINE_MATERIAL* + - "YANEURAOU_ENGINE_MATERIAL,YANEURAOU_ENGINE_MATERIAL9" - YANEURAOU_MATE_ENGINE - TANUKI_MATE_ENGINE - USER_ENGINE @@ -41,6 +42,8 @@ jobs: # There is no machine learning implementation for the following editions - edition: YANEURAOU_ENGINE_MATERIAL* target: evallearn + - edition: "YANEURAOU_ENGINE_MATERIAL,YANEURAOU_ENGINE_MATERIAL9" + target: evallearn - edition: YANEURAOU_MATE_ENGINE target: evallearn - edition: TANUKI_MATE_ENGINE @@ -170,6 +173,21 @@ jobs: sudo cat /etc/apt/sources.list sudo ls -R /etc/apt/sources.list.d if: ${{ matrix.compiler == 'clang++-14' }} + - name: install clang-15 + # LLVM APT + run: | + # Remove packages that conflict with clang-15 installation + sudo apt remove -y \ + liblldb-10 libomp-10-dev libomp5-10 lldb-10 python3-lldb-10 \ + liblldb-11 libomp-11-dev libomp5-11 lldb-11 python3-lldb-11 \ + liblldb-12 libomp-12-dev libomp5-12 lldb-12 python3-lldb-12 + # install clang-15 + wget https://apt.llvm.org/llvm.sh + sudo bash ./llvm.sh 15 + sudo apt install build-essential libopenblas-dev clang-15 libomp-15-dev + sudo cat /etc/apt/sources.list + sudo ls -R /etc/apt/sources.list.d + if: ${{ matrix.compiler == 'clang++-15' }} - name: install aarch64-linux-gnu-g++ run: | sudo apt update diff --git a/.github/workflows/ndk.yml b/.github/workflows/ndk.yml index 901bea55c..80fc3938d 100644 --- a/.github/workflows/ndk.yml +++ b/.github/workflows/ndk.yml @@ -25,7 +25,8 @@ jobs: - YANEURAOU_ENGINE_NNUE_KP256 - YANEURAOU_ENGINE_KPPT - YANEURAOU_ENGINE_KPP_KKPT - - YANEURAOU_ENGINE_MATERIAL* + #- YANEURAOU_ENGINE_MATERIAL* + - "YANEURAOU_ENGINE_MATERIAL,YANEURAOU_ENGINE_MATERIAL9" - YANEURAOU_MATE_ENGINE - TANUKI_MATE_ENGINE - USER_ENGINE diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e2a2aac4e..ddef4f7f5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -30,7 +30,6 @@ jobs: edition: - "YANEURAOU_ENGINE_NNUE,YANEURAOU_ENGINE_NNUE_HALFKP_VM_256X2_32_32,YANEURAOU_ENGINE_NNUE_HALFKPE9,YANEURAOU_ENGINE_NNUE_KP256" - "YANEURAOU_ENGINE_KPPT,YANEURAOU_ENGINE_KPP_KKPT" - - YANEURAOU_ENGINE_MATERIAL* - YANEURAOU_MATE_ENGINE - TANUKI_MATE_ENGINE - USER_ENGINE @@ -93,19 +92,19 @@ jobs: C:\msys64\usr\bin\bash.exe -lc 'pacman --needed --noconfirm -Syuu' C:\msys64\usr\bin\bash.exe -lc 'pacman --needed --noconfirm -Syuu' C:\msys64\usr\bin\bash.exe -lc 'pacman --needed --noconfirm -Syuu pactoys' - C:\msys64\usr\bin\bash.exe -lc 'pacboy --needed --noconfirm -Sy clang:m lld:m openblas:x openmp:x toolchain:m base-devel:' + C:\msys64\usr\bin\bash.exe -lc 'pacboy --needed --noconfirm -Syuu clang:m lld:m openblas:x openmp:x toolchain:m' $ErrorActionPreference = 'Stop' - name: make run: | $env:PATH+=';C:\msys64'; - .\main\script\msys2_build.ps1 -Edition ${{ matrix.edition }} -Compiler ${{ matrix.compiler }} -Target ${{ matrix.target }} -Cpu ${{ matrix.archcpu }} + main\script\msys2_build.ps1 -Edition ${{ matrix.edition }} -Compiler ${{ matrix.compiler }} -Target ${{ matrix.target }} -Cpu ${{ matrix.archcpu }} shell: pwsh - uses: actions/upload-artifact@v2 with: name: build-windows_${{ github.run_number }}_${{ github.sha }} - path: ./main/build/**/* + path: main/build/**/* build-msys2-material: # windows-latest = windows-2019 => windows-2022 @@ -119,7 +118,6 @@ jobs: target: - normal - tournament - - evallearn - gensfen archcpu: - ZEN3 @@ -130,7 +128,7 @@ jobs: - SSE2 - NO_SSE edition: - - YANEURAOU_ENGINE_MATERIAL* + - "YANEURAOU_ENGINE_MATERIAL,YANEURAOU_ENGINE_MATERIAL9" compiler: - clang++ - g++ @@ -164,6 +162,8 @@ jobs: # There is no machine learning implementation for the following editions - edition: YANEURAOU_ENGINE_MATERIAL* target: evallearn + - edition: "YANEURAOU_ENGINE_MATERIAL,YANEURAOU_ENGINE_MATERIAL9" + target: evallearn - edition: YANEURAOU_MATE_ENGINE target: evallearn - edition: TANUKI_MATE_ENGINE @@ -190,19 +190,19 @@ jobs: C:\msys64\usr\bin\bash.exe -lc 'pacman --needed --noconfirm -Syuu' C:\msys64\usr\bin\bash.exe -lc 'pacman --needed --noconfirm -Syuu' C:\msys64\usr\bin\bash.exe -lc 'pacman --needed --noconfirm -Syuu pactoys' - C:\msys64\usr\bin\bash.exe -lc 'pacboy --needed --noconfirm -Sy clang:m lld:m openblas:x openmp:x toolchain:m base-devel:' + C:\msys64\usr\bin\bash.exe -lc 'pacboy --needed --noconfirm -Syuu clang:m lld:m openblas:x openmp:x toolchain:m' $ErrorActionPreference = 'Stop' - name: make run: | $env:PATH+=';C:\msys64'; - .\main\script\msys2_build.ps1 -Edition ${{ matrix.edition }} -Compiler ${{ matrix.compiler }} -Target ${{ matrix.target }} -Cpu ${{ matrix.archcpu }} + main\script\msys2_build.ps1 -Edition ${{ matrix.edition }} -Compiler ${{ matrix.compiler }} -Target ${{ matrix.target }} -Cpu ${{ matrix.archcpu }} shell: pwsh - uses: actions/upload-artifact@v2 with: name: build-windows-material_${{ github.run_number }}_${{ github.sha }} - path: ./main/build/**/* + path: main/build/**/* build-deep-windows: @@ -239,7 +239,7 @@ jobs: - uses: actions/upload-artifact@v2 with: name: build-deep-windows_${{ github.run_number }}_${{ github.sha }} - path: ./main/build/**/* + path: main/build/**/* build-android-general: @@ -257,7 +257,7 @@ jobs: - YANEURAOU_ENGINE_NNUE_KP256 - YANEURAOU_ENGINE_KPPT - YANEURAOU_ENGINE_KPP_KKPT - - YANEURAOU_ENGINE_MATERIAL* + - "YANEURAOU_ENGINE_MATERIAL,YANEURAOU_ENGINE_MATERIAL9" - YANEURAOU_MATE_ENGINE - TANUKI_MATE_ENGINE - USER_ENGINE @@ -277,13 +277,156 @@ jobs: path: main - name: ndk-build - run: ./main/script/android_build.sh -e ${{ matrix.edition }} + run: main/script/android_build.sh -e ${{ matrix.edition }} - uses: actions/upload-artifact@v2 with: name: build-android_${{ github.run_number }}_${{ github.sha }} - path: ./main/build/**/* + path: main/build/**/* + + build-macos-general: + # macos-11 + # https://docs.github.com/ja/actions/using-github-hosted-runners/about-github-hosted-runners + # https://github.com/actions/virtual-environments/blob/main/images/macos/macos-11-Readme.md + runs-on: macos-11 + + strategy: + matrix: + edition: + - YANEURAOU_ENGINE_NNUE + - "YANEURAOU_ENGINE_NNUE_HALFKP_VM_256X2_32_32,YANEURAOU_ENGINE_NNUE_HALFKPE9,YANEURAOU_ENGINE_NNUE_KP256" + - "YANEURAOU_ENGINE_KPPT,YANEURAOU_ENGINE_KPP_KKPT" + - "YANEURAOU_ENGINE_MATERIAL,YANEURAOU_ENGINE_MATERIAL9" + - "YANEURAOU_MATE_ENGINE,TANUKI_MATE_ENGINE" + #- USER_ENGINE + compiler: + - clang++ + #- g++-11 + target: + - "normal,tournament" + archcpu: + #- AVX2 + #- SSE42 + - APPLEAVX2 + - APPLESSE42 + - APPLEM1 + exclude: + # M1 Mac向けは g++-11 ではビルドしない + - compiler: g++-11 + archcpu: APPLEAVX2 + - compiler: g++-11 + archcpu: APPLESSE42 + - compiler: g++-11 + archcpu: APPLEM1 + steps: + - name: Checkout own repository + uses: actions/checkout@v2 + with: + path: main + + - name: make + uses: actions/github-script@v5 + env: + JOBS: '8' + EDITION: '${{ matrix.edition }}' + COMPILER: '${{ matrix.compiler }}' + TARGET: '${{ matrix.target }}' + CPU: '${{ matrix.archcpu }}' + OS: 'macos11' + with: + script: | + const fs = require('fs'); + const {JOBS, EDITION, COMPILER, TARGET, CPU, OS, EXTRA} = process.env; + const editionh = { + "YANEURAOU_ENGINE_NNUE": "YANEURAOU_ENGINE_NNUE", + "YANEURAOU_ENGINE_NNUE_HALFKP_VM_256X2_32_32": "YANEURAOU_ENGINE_NNUE_HALFKP_VM_256X2_32_32", + "YANEURAOU_ENGINE_NNUE_HALFKPE9": "YANEURAOU_ENGINE_NNUE_HALFKPE9", + "YANEURAOU_ENGINE_NNUE_KP256": "YANEURAOU_ENGINE_NNUE_KP256", + "YANEURAOU_ENGINE_DEEP_TENSOR_RT": "YANEURAOU_ENGINE_DEEP_TENSOR_RT", + "YANEURAOU_ENGINE_KPPT": "YANEURAOU_ENGINE_KPPT", + "YANEURAOU_ENGINE_KPP_KKPT": "YANEURAOU_ENGINE_KPP_KKPT", + "YANEURAOU_ENGINE_MATERIAL": "YANEURAOU_ENGINE_MATERIAL", + "YANEURAOU_ENGINE_MATERIAL2": "YANEURAOU_ENGINE_MATERIAL MATERIAL_LEVEL=2", + "YANEURAOU_ENGINE_MATERIAL3": "YANEURAOU_ENGINE_MATERIAL MATERIAL_LEVEL=3", + "YANEURAOU_ENGINE_MATERIAL4": "YANEURAOU_ENGINE_MATERIAL MATERIAL_LEVEL=4", + "YANEURAOU_ENGINE_MATERIAL5": "YANEURAOU_ENGINE_MATERIAL MATERIAL_LEVEL=5", + "YANEURAOU_ENGINE_MATERIAL6": "YANEURAOU_ENGINE_MATERIAL MATERIAL_LEVEL=6", + "YANEURAOU_ENGINE_MATERIAL7": "YANEURAOU_ENGINE_MATERIAL MATERIAL_LEVEL=7", + "YANEURAOU_ENGINE_MATERIAL8": "YANEURAOU_ENGINE_MATERIAL MATERIAL_LEVEL=8", + "YANEURAOU_ENGINE_MATERIAL9": "YANEURAOU_ENGINE_MATERIAL MATERIAL_LEVEL=9", + "YANEURAOU_ENGINE_MATERIAL10": "YANEURAOU_ENGINE_MATERIAL MATERIAL_LEVEL=10", + "YANEURAOU_MATE_ENGINE": "YANEURAOU_MATE_ENGINE", + "TANUKI_MATE_ENGINE": "TANUKI_MATE_ENGINE", + "USER_ENGINE": "USER_ENGINE", + }; + const dirh = { + "YANEURAOU_ENGINE_NNUE": "NNUE", + "YANEURAOU_ENGINE_NNUE_HALFKP_VM_256X2_32_32": "NNUE_HALFKP_VM", + "YANEURAOU_ENGINE_NNUE_HALFKPE9": "NNUE_HALFKPE9", + "YANEURAOU_ENGINE_NNUE_KP256": "NNUE_KP256", + "YANEURAOU_ENGINE_DEEP_TENSOR_RT": "DEEP_TRT", + "YANEURAOU_ENGINE_KPPT": "KPPT", + "YANEURAOU_ENGINE_KPP_KKPT": "KPP_KKPT", + "YANEURAOU_ENGINE_MATERIAL": "MaterialLv1", + "YANEURAOU_ENGINE_MATERIAL2": "MaterialLv2", + "YANEURAOU_ENGINE_MATERIAL3": "MaterialLv3", + "YANEURAOU_ENGINE_MATERIAL4": "MaterialLv4", + "YANEURAOU_ENGINE_MATERIAL5": "MaterialLv5", + "YANEURAOU_ENGINE_MATERIAL6": "MaterialLv6", + "YANEURAOU_ENGINE_MATERIAL7": "MaterialLv7", + "YANEURAOU_ENGINE_MATERIAL8": "MaterialLv8", + "YANEURAOU_ENGINE_MATERIAL9": "MaterialLv9", + "YANEURAOU_ENGINE_MATERIAL10": "MaterialLv10", + "YANEURAOU_MATE_ENGINE": "YaneuraOu_MATE", + "TANUKI_MATE_ENGINE": "tanuki_MATE", + "USER_ENGINE": "USER", + }; + const fileh = { + "YANEURAOU_ENGINE_NNUE": "YaneuraOu_NNUE", + "YANEURAOU_ENGINE_NNUE_HALFKP_VM_256X2_32_32": "YaneuraOu_NNUE_HALFKP_VM", + "YANEURAOU_ENGINE_NNUE_HALFKPE9": "YaneuraOu_NNUE_HalfKPE9", + "YANEURAOU_ENGINE_NNUE_KP256": "YaneuraOu_NNUE_KP256", + "YANEURAOU_ENGINE_DEEP_TENSOR_RT": "YaneuraOu_Deep_TRT", + "YANEURAOU_ENGINE_KPPT": "YaneuraOu_KPPT", + "YANEURAOU_ENGINE_KPP_KKPT": "YaneuraOu_KPP_KKPT", + "YANEURAOU_ENGINE_MATERIAL": "YaneuraOu_MaterialLv1", + "YANEURAOU_ENGINE_MATERIAL2": "YaneuraOu_MaterialLv2", + "YANEURAOU_ENGINE_MATERIAL3": "YaneuraOu_MaterialLv3", + "YANEURAOU_ENGINE_MATERIAL4": "YaneuraOu_MaterialLv4", + "YANEURAOU_ENGINE_MATERIAL5": "YaneuraOu_MaterialLv5", + "YANEURAOU_ENGINE_MATERIAL6": "YaneuraOu_MaterialLv6", + "YANEURAOU_ENGINE_MATERIAL7": "YaneuraOu_MaterialLv7", + "YANEURAOU_ENGINE_MATERIAL8": "YaneuraOu_MaterialLv8", + "YANEURAOU_ENGINE_MATERIAL9": "YaneuraOu_MaterialLv9", + "YANEURAOU_ENGINE_MATERIAL10": "YaneuraOu_MaterialLv10", + "YANEURAOU_MATE_ENGINE": "YaneuraOu_MATE", + "TANUKI_MATE_ENGINE": "tanuki_MATE", + "USER_ENGINE": "user", + }; + for(let edition of EDITION.split(',')) { + for(let compiler of COMPILER.split(',')) { + for(let target of TARGET.split(',')) { + for(let cpu of CPU.split(',')) { + const builddir = `../build/${OS}/${dirh[edition]}`; + const filename = `${fileh[edition]}-${OS}-${compiler}-${target}-${cpu.toLowerCase()}`; + let log = ''; + await io.mkdirP(`./main/source/${builddir}`); + await exec.exec('nice', `make -j${JOBS} ${target} TARGET_CPU=${cpu} YANEURAOU_EDITION=${editionh[edition]} COMPILER=${compiler} TARGET=${builddir}/${filename}`.split(' '), { + "cwd": "./main/source/", + listeners: { + stdout: (data) => { log += data.toString(); }, + stderr: (data) => { log += data.toString(); }, + } + }); + await exec.exec(`make`, `clean TARGET_CPU=${cpu} YANEURAOU_EDITION=${edition}`.split(' '), {"cwd": "./main/source/"}); + fs.writeFileSync(`./main/source/${builddir}/${filename}.log`, log); + }}}} + + - uses: actions/upload-artifact@v2 + with: + name: build-macos_${{ github.run_number }}_${{ github.sha }} + path: main/build/**/**/* build-msys2-suisho: # windows-latest = windows-2019 => windows-2022 @@ -323,7 +466,7 @@ jobs: C:\msys64\usr\bin\bash.exe -lc 'pacman --needed --noconfirm -Syuu' C:\msys64\usr\bin\bash.exe -lc 'pacman --needed --noconfirm -Syuu' C:\msys64\usr\bin\bash.exe -lc 'pacman --needed --noconfirm -Syuu pactoys' - C:\msys64\usr\bin\bash.exe -lc 'pacboy --needed --noconfirm -Sy clang:m lld:m openblas:x openmp:x toolchain:m base-devel:' + C:\msys64\usr\bin\bash.exe -lc 'pacboy --needed --noconfirm -Syuu clang:m lld:m openblas:x openmp:x toolchain:m' $ErrorActionPreference = 'Stop' - name: suisho5 embedded_nnue @@ -334,19 +477,18 @@ jobs: - name: make run: | $env:PATH+=';C:\msys64'; - .\main\script\msys2_build.ps1 -Edition ${{ matrix.edition }} -Compiler ${{ matrix.compiler }} -Target ${{ matrix.target }} -Cpu ${{ matrix.archcpu }} -Extra 'EVAL_EMBEDDING=ON'; + main\script\msys2_build.ps1 -Edition ${{ matrix.edition }} -Compiler ${{ matrix.compiler }} -Target ${{ matrix.target }} -Cpu ${{ matrix.archcpu }} -Extra 'EVAL_EMBEDDING=ON EXTRA_CPPFLAGS=''-DENGINE_OPTIONS=""\\""option=name=FV_SCALE=type=spin=default=24=min=1=max=128;option=name=BookFile=type=combo=default=no_book=var=no_book=var=standard_book.db=var=yaneura_book1.db=var=yaneura_book2.db=var=yaneura_book3.db=var=yaneura_book4.db=var=user_book1.db=var=user_book2.db=var=user_book3.db=var=book.bin\\""""'''; shell: pwsh - name: add resource run: | - echo 'Suisho5(20211123)-${{ steps.version.outputs.filename }}' > ./main/build/windows/NNUE/engine_name.txt; - echo 'yaneurao, tayayan' >> .\main\build\windows\NNUE\engine_name.txt; - echo 'option name FV_SCALE type spin default 24 min 1 max 128' > ./main/build/windows/NNUE/engine_options.txt; + echo 'Suisho5(20211123)-${{ steps.version.outputs.filename }}' > main/build/windows/NNUE/engine_name.txt; + echo 'yaneurao, tayayan' >> main/build/windows/NNUE/engine_name.txt; - uses: actions/upload-artifact@v2 with: name: build-windows-suisho_${{ github.run_number }}_${{ github.sha }} - path: ./main/build/**/* + path: main/build/**/* build-android-suisho: # ubuntu-latest = ubuntu-20.04 @@ -384,32 +526,221 @@ jobs: gzip -df main/source/eval/nnue/embedded_nnue.cpp.gz; - name: ndk-build - run: ./main/script/android_build.sh -e ${{ matrix.edition }} -x "EVAL_EMBEDDING=ON" + run: main/script/android_build.sh -e ${{ matrix.edition }} -x 'EVAL_EMBEDDING=ON EXTRA_CPPFLAGS=''-DENGINE_OPTIONS="\"option=name=FV_SCALE=type=spin=default=24=min=1=max=128;option=name=BookFile=type=combo=default=no_book=var=no_book=var=standard_book.db=var=yaneura_book1.db=var=yaneura_book2.db=var=yaneura_book3.db=var=yaneura_book4.db=var=user_book1.db=var=user_book2.db=var=user_book3.db=var=book.bin\""''' - name: add resource run: | - echo 'Suisho5(20211123)-${{ steps.version.outputs.filename }}' > ./main/build/android/NNUE/engine_name.txt; - echo 'yaneurao, tayayan' >> ./main/build/android/NNUE/engine_name.txt; - echo 'option name FV_SCALE type spin default 24 min 1 max 128' > ./main/build/android/NNUE/engine_options.txt; + echo 'Suisho5(20211123)-${{ steps.version.outputs.filename }}' > main/build/android/NNUE/engine_name.txt; + echo 'yaneurao, tayayan' >> main/build/android/NNUE/engine_name.txt; - uses: actions/upload-artifact@v2 with: name: build-android-suisho_${{ github.run_number }}_${{ github.sha }} - path: ./main/build/**/* + path: main/build/**/* - release-pkg: - name: Release package - needs: - - build-msys2-general - - build-msys2-material - - build-msys2-suisho - - build-deep-windows - - build-android-general - - build-android-suisho + build-macos-suisho: + # macos-11 + # https://docs.github.com/ja/actions/using-github-hosted-runners/about-github-hosted-runners + # https://github.com/actions/virtual-environments/blob/main/images/macos/macos-11-Readme.md + runs-on: macos-11 + + strategy: + matrix: + edition: + - YANEURAOU_ENGINE_NNUE + compiler: + - clang++ + #- g++-11 + target: + #- normal + - tournament + archcpu: + #- AVX2 + #- SSE42 + - APPLEAVX2 + - APPLESSE42 + - APPLEM1 + exclude: + # M1 Mac向けは g++-11 ではビルドしない + - compiler: g++-11 + archcpu: APPLEAVX2 + - compiler: g++-11 + archcpu: APPLESSE42 + - compiler: g++-11 + archcpu: APPLEM1 + + steps: + - name: Checkout own repository + uses: actions/checkout@v2 + with: + path: main + + - name: suisho5 embedded_nnue + run: | + curl -LRo main/source/eval/nnue/embedded_nnue.cpp.gz https://github.com/mizar/YaneuraOu/releases/download/resource/suisho5_20211123.halfkp.nnue.cpp.gz; + gzip -df main/source/eval/nnue/embedded_nnue.cpp.gz; + + - name: make + uses: actions/github-script@v5 + env: + JOBS: '8' + EDITION: '${{ matrix.edition }}' + COMPILER: '${{ matrix.compiler }}' + TARGET: '${{ matrix.target }}' + CPU: '${{ matrix.archcpu }}' + OS: 'macos11' + with: + script: | + const fs = require('fs'); + const {JOBS, EDITION, COMPILER, TARGET, CPU, OS, EXTRA} = process.env; + const editionh = { + "YANEURAOU_ENGINE_NNUE": "YANEURAOU_ENGINE_NNUE", + "YANEURAOU_ENGINE_NNUE_HALFKP_VM_256X2_32_32": "YANEURAOU_ENGINE_NNUE_HALFKP_VM_256X2_32_32", + "YANEURAOU_ENGINE_NNUE_HALFKPE9": "YANEURAOU_ENGINE_NNUE_HALFKPE9", + "YANEURAOU_ENGINE_NNUE_KP256": "YANEURAOU_ENGINE_NNUE_KP256", + }; + const dirh = { + "YANEURAOU_ENGINE_NNUE": "NNUE", + "YANEURAOU_ENGINE_NNUE_HALFKP_VM_256X2_32_32": "NNUE_HALFKP_VM", + "YANEURAOU_ENGINE_NNUE_HALFKPE9": "NNUE_HALFKPE9", + "YANEURAOU_ENGINE_NNUE_KP256": "NNUE_KP256", + }; + const fileh = { + "YANEURAOU_ENGINE_NNUE": "Suisho5_YaneuraOu", + "YANEURAOU_ENGINE_NNUE_HALFKP_VM_256X2_32_32": "YaneuraOu_NNUE_HALFKP_VM", + "YANEURAOU_ENGINE_NNUE_HALFKPE9": "YaneuraOu_NNUE_HalfKPE9", + "YANEURAOU_ENGINE_NNUE_KP256": "YaneuraOu_NNUE_KP256", + }; + for(let edition of EDITION.split(',')) { + for(let compiler of COMPILER.split(',')) { + for(let target of TARGET.split(',')) { + for(let cpu of CPU.split(',')) { + const builddir = `../build/${OS}/${dirh[edition]}`; + const filename = `${fileh[edition]}-${OS}-${compiler}-${target}-${cpu.toLowerCase()}`; + let log = ''; + await io.mkdirP(`./main/source/${builddir}`); + await exec.exec('nice', `make -j${JOBS} ${target} TARGET_CPU=${cpu} YANEURAOU_EDITION=${editionh[edition]} COMPILER=${compiler} TARGET=${builddir}/${filename} EVAL_EMBEDDING=ON EXTRA_CPPFLAGS='-DENGINE_OPTIONS=\\\\\"\\\"option=name=FV_SCALE=type=spin=default=24=min=1=max=128\\;option=name=BookFile=type=combo=default=no_book=var=no_book=var=standard_book.db=var=yaneura_book1.db=var=yaneura_book2.db=var=yaneura_book3.db=var=yaneura_book4.db=var=user_book1.db=var=user_book2.db=var=user_book3.db=var=book.bin\\\\\\\"\"'`.split(' '), { + "cwd": "./main/source/", + listeners: { + stdout: (data) => { log += data.toString(); }, + stderr: (data) => { log += data.toString(); }, + } + }); + await exec.exec(`make`, `clean TARGET_CPU=${cpu} YANEURAOU_EDITION=${edition} EVAL_EMBEDDING=ON`.split(' '), {"cwd": "./main/source/"}); + fs.writeFileSync(`./main/source/${builddir}/${filename}.log`, log); + }}}} + + - name: add resource + run: | + echo 'Suisho5(20211123)-YaneuraOu' > main/build/macos11/NNUE/engine_name.txt; + echo 'yaneurao, tayayan' >> main/build/macos11/NNUE/engine_name.txt; + + - uses: actions/upload-artifact@v2 + with: + name: build-macos-suisho_${{ github.run_number }}_${{ github.sha }} + path: main/build/**/**/* + + build-wasm: # ubuntu-latest = ubuntu-20.04 # https://docs.github.com/ja/actions/using-github-hosted-runners/about-github-hosted-runners # https://github.com/actions/virtual-environments/blob/main/images/linux/Ubuntu2004-README.md runs-on: ubuntu-20.04 + + strategy: + matrix: + edition: + - halfkp.noeval + - halfkpe9.noeval + - halfkpvm.noeval + - k-p.noeval + - material + - material9 + - yaneuraou-mate + - tanuki-mate + + steps: + - name: Checkout own repository + uses: actions/checkout@v2 + with: + path: main + + - name: docker pull + run: | + docker pull emscripten/emsdk:latest + + - name: build wasm + run: | + docker run --rm -v ${PWD}/main:/src emscripten/emsdk:latest node script/wasm_build.js ${{ matrix.edition }} + + - uses: actions/upload-artifact@v2 + with: + name: build-wasm_${{ github.run_number }}_${{ github.sha }} + path: ./main/build/**/**/* + + build-wasm-suisho: + # ubuntu-latest = ubuntu-20.04 + # https://docs.github.com/ja/actions/using-github-hosted-runners/about-github-hosted-runners + # https://github.com/actions/virtual-environments/blob/main/images/linux/Ubuntu2004-README.md + runs-on: ubuntu-20.04 + + strategy: + matrix: + edition: + - halfkp + + steps: + - name: Checkout own repository + uses: actions/checkout@v2 + with: + path: main + + - name: docker pull + run: | + docker pull emscripten/emsdk:latest + + - name: build wasm + run: | + docker run --rm -v ${PWD}/main:/src emscripten/emsdk:latest node script/wasm_build.js ${{ matrix.edition }} + + - uses: actions/upload-artifact@v2 + with: + name: build-wasm-suisho_${{ github.run_number }}_${{ github.sha }} + path: ./main/build/**/**/* + + build-wasm-suishopetite: + # ubuntu-latest = ubuntu-20.04 + # https://docs.github.com/ja/actions/using-github-hosted-runners/about-github-hosted-runners + # https://github.com/actions/virtual-environments/blob/main/images/linux/Ubuntu2004-README.md + runs-on: ubuntu-20.04 + + strategy: + matrix: + edition: + - k-p + + steps: + - name: Checkout own repository + uses: actions/checkout@v2 + with: + path: main + + - name: docker pull + run: | + docker pull emscripten/emsdk:latest + + - name: build wasm + run: | + docker run --rm -v ${PWD}/main:/src emscripten/emsdk:latest node script/wasm_build.js ${{ matrix.edition }} + + - uses: actions/upload-artifact@v2 + with: + name: build-wasm-suishopetite_${{ github.run_number }}_${{ github.sha }} + path: ./main/build/**/**/* + + archive-msys2-general: + runs-on: ubuntu-20.04 + needs: + - build-msys2-general steps: - name: Set version id: version @@ -425,86 +756,504 @@ jobs: uses: actions/download-artifact@v2 with: name: build-windows_${{ github.run_number }}_${{ github.sha }} - path: release-windows + path: release + - name: copy docs + run: | + cp main/Copying.txt release/windows + cp -r main/docs release/windows + tar -Jcf release/windows/source.tar.xz -C main source + - name: Display structure of downloaded files + run: ls -R release + - name: make build-windows zip/7z + run: | + 7z a -tzip build-windows.zip windows + 7z a -t7z build-windows.7z windows + working-directory: release + - uses: actions/upload-artifact@v2 + with: + name: archive-windows_${{ github.run_number }}_${{ github.sha }} + path: | + release/*.zip + release/*.7z + archive-msys2-material: + runs-on: ubuntu-20.04 + needs: + - build-msys2-material + steps: + - name: Set version + id: version + run: | + REPOSITORY=$(echo ${{ github.repository }} | sed -e "s#.*/##") + VERSION=$(echo ${{ github.ref }} | sed -e "s#refs/tags/##g") + echo ::set-output name=version::$VERSION + echo ::set-output name=filename::$REPOSITORY-$VERSION + - uses: actions/checkout@v2 + with: + path: main - name: Download artifact to get build-windows-material uses: actions/download-artifact@v2 with: name: build-windows-material_${{ github.run_number }}_${{ github.sha }} - path: release-windows-material + path: release + - name: copy docs + run: | + cp main/Copying.txt release/windows + cp -r main/docs release/windows + tar -Jcf release/windows/source.tar.xz -C main source + - name: Display structure of downloaded files + run: ls -R release + - name: make build-windows zip/7z + run: | + 7z a -tzip build-windows-material.zip windows + 7z a -t7z build-windows-material.7z windows + working-directory: release + - uses: actions/upload-artifact@v2 + with: + name: archive-windows-material_${{ github.run_number }}_${{ github.sha }} + path: | + release/*.zip + release/*.7z + archive-msys2-suisho: + runs-on: ubuntu-20.04 + needs: + - build-msys2-suisho + steps: + - name: Set version + id: version + run: | + REPOSITORY=$(echo ${{ github.repository }} | sed -e "s#.*/##") + VERSION=$(echo ${{ github.ref }} | sed -e "s#refs/tags/##g") + echo ::set-output name=version::$VERSION + echo ::set-output name=filename::$REPOSITORY-$VERSION + - uses: actions/checkout@v2 + with: + path: main - name: Download artifact to get build-windows-suisho uses: actions/download-artifact@v2 with: name: build-windows-suisho_${{ github.run_number }}_${{ github.sha }} - path: release-windows-suisho + path: release + - name: copy docs + run: | + cp main/Copying.txt release/windows/NNUE + cp -r main/docs release/windows/NNUE + curl -LRo main/source/eval/nnue/embedded_nnue.cpp.gz https://github.com/mizar/YaneuraOu/releases/download/resource/suisho5_20211123.halfkp.nnue.cpp.gz; + gzip -df main/source/eval/nnue/embedded_nnue.cpp.gz; + tar -Jcf release/windows/NNUE/source.tar.xz -C main source + - name: Display structure of downloaded files + run: ls -R release + - name: make build-windows-suisho zip/7z + run: | + 7z a -tzip ../../build-windows-suisho.zip * + 7z a -t7z ../../build-windows-suisho.7z * + working-directory: release/windows/NNUE + - uses: actions/upload-artifact@v2 + with: + name: archive-windows-suisho_${{ github.run_number }}_${{ github.sha }} + path: | + release/*.zip + release/*.7z + archive-deep-windows: + runs-on: ubuntu-20.04 + needs: + - build-deep-windows + steps: + - name: Set version + id: version + run: | + REPOSITORY=$(echo ${{ github.repository }} | sed -e "s#.*/##") + VERSION=$(echo ${{ github.ref }} | sed -e "s#refs/tags/##g") + echo ::set-output name=version::$VERSION + echo ::set-output name=filename::$REPOSITORY-$VERSION + - uses: actions/checkout@v2 + with: + path: main - name: Download artifact to get build-deep-windows uses: actions/download-artifact@v2 with: name: build-deep-windows_${{ github.run_number }}_${{ github.sha }} - path: release-deep-windows + path: release + - name: copy docs + run: | + cp main/Copying.txt release + cp -r main/docs release + tar -Jcf release/source.tar.xz -C main source + - name: Display structure of downloaded files + run: ls -R release + - name: make build-deep-windows zip/7z + run: | + 7z a -tzip build-deep-windows.zip * + 7z a -t7z build-deep-windows.7z * + working-directory: release + - uses: actions/upload-artifact@v2 + with: + name: archive-deep-windows_${{ github.run_number }}_${{ github.sha }} + path: | + release/*.zip + release/*.7z + archive-android-general: + runs-on: ubuntu-20.04 + needs: + - build-android-general + steps: + - name: Set version + id: version + run: | + REPOSITORY=$(echo ${{ github.repository }} | sed -e "s#.*/##") + VERSION=$(echo ${{ github.ref }} | sed -e "s#refs/tags/##g") + echo ::set-output name=version::$VERSION + echo ::set-output name=filename::$REPOSITORY-$VERSION + - uses: actions/checkout@v2 + with: + path: main - name: Download artifact to get build-android uses: actions/download-artifact@v2 with: name: build-android_${{ github.run_number }}_${{ github.sha }} - path: release-android + path: release + - name: copy docs + run: | + cp main/Copying.txt release/android + cp -r main/docs release/android + tar -Jcf release/android/source.tar.xz -C main source + - name: Display structure of downloaded files + run: ls -R release + - name: make build-android zip/7z + run: | + 7z a -tzip build-android.zip android + 7z a -t7z build-android.7z android + working-directory: release + - uses: actions/upload-artifact@v2 + with: + name: archive-android_${{ github.run_number }}_${{ github.sha }} + path: | + release/*.zip + release/*.7z + archive-android-suisho: + runs-on: ubuntu-20.04 + needs: + - build-android-suisho + steps: + - name: Set version + id: version + run: | + REPOSITORY=$(echo ${{ github.repository }} | sed -e "s#.*/##") + VERSION=$(echo ${{ github.ref }} | sed -e "s#refs/tags/##g") + echo ::set-output name=version::$VERSION + echo ::set-output name=filename::$REPOSITORY-$VERSION + - uses: actions/checkout@v2 + with: + path: main - name: Download artifact to get build-android-suisho uses: actions/download-artifact@v2 with: name: build-android-suisho_${{ github.run_number }}_${{ github.sha }} - path: release-android-suisho + path: release + - name: copy docs + run: | + cp main/Copying.txt release/android/NNUE + cp -r main/docs release/android/NNUE + curl -LRo main/source/eval/nnue/embedded_nnue.cpp.gz https://github.com/mizar/YaneuraOu/releases/download/resource/suisho5_20211123.halfkp.nnue.cpp.gz; + gzip -df main/source/eval/nnue/embedded_nnue.cpp.gz; + tar -Jcf release/android/NNUE/source.tar.xz -C main source - name: Display structure of downloaded files - run: ls -R release-windows release-windows-material release-windows-suisho release-deep-windows release-android release-android-suisho + run: ls -R release + - name: make build-android-suisho zip/7z + run: | + 7z a -tzip ../../build-android-suisho.zip * + 7z a -t7z ../../build-android-suisho.7z * + working-directory: release/android/NNUE + - uses: actions/upload-artifact@v2 + with: + name: archive-android-suisho_${{ github.run_number }}_${{ github.sha }} + path: | + release/*.zip + release/*.7z + archive-macos-general: + runs-on: macos-11 + needs: + - build-macos-general + steps: + - name: Set version + id: version + run: | + REPOSITORY=$(echo ${{ github.repository }} | sed -e "s#.*/##") + VERSION=$(echo ${{ github.ref }} | sed -e "s#refs/tags/##g") + echo ::set-output name=version::$VERSION + echo ::set-output name=filename::$REPOSITORY-$VERSION + - uses: actions/checkout@v2 + with: + path: main + - name: Download artifact to get build-macos + uses: actions/download-artifact@v2 + with: + name: build-macos_${{ github.run_number }}_${{ github.sha }} + path: release + - name: set executable + run: | + find release|grep ++|grep -v \.log|xargs -I _file_ chmod +x _file_ - name: copy docs run: | - cp main/Copying.txt release-windows/windows - cp -r main/source/ release-windows/windows - cp -r main/docs/ release-windows/windows - cp main/Copying.txt release-windows-material/windows - cp -r main/source/ release-windows-material/windows - cp -r main/docs/ release-windows-material/windows - cp main/Copying.txt release-windows-suisho/windows/NNUE - cp -r main/source/ release-windows-suisho/windows/NNUE - cp -r main/docs/ release-windows-suisho/windows/NNUE - cp main/Copying.txt release-deep-windows - cp -r main/source/ release-deep-windows - cp -r main/docs/ release-deep-windows - cp main/Copying.txt release-android/android - cp -r main/source/ release-android/andorid - cp -r main/docs/ release-android/android - cp main/Copying.txt release-android-suisho/android/NNUE - cp -r main/source/ release-android-suisho/android/NNUE - cp -r main/docs/ release-android-suisho/android/NNUE + cp main/Copying.txt release/macos11 + cp -r main/docs release/macos11 + tar -Jcf release/macos11/source.tar.xz -C main source - name: Display structure of downloaded files - run: ls -R release-windows release-windows-material release-windows-suisho release-deep-windows release-android release-android-suisho - - name: make build-windows zip/7z + run: ls -R release + - name: make build-macos .tar.xz run: | - 7z a -tzip build-windows.zip windows - 7z a -t7z build-windows.7z windows - working-directory: release-windows - - name: make build-windows-material zip/7z + tar -Jcf build-macos.tar.xz macos11 + working-directory: release + - uses: actions/upload-artifact@v2 + with: + name: archive-macos_${{ github.run_number }}_${{ github.sha }} + path: | + release/*.tar.xz + archive-macos-suisho: + runs-on: macos-11 + needs: + - build-macos-suisho + steps: + - name: Set version + id: version run: | - 7z a -tzip build-windows-material.zip windows - 7z a -t7z build-windows-material.7z windows - working-directory: release-windows-material - - name: make build-windows-suisho zip/7z + REPOSITORY=$(echo ${{ github.repository }} | sed -e "s#.*/##") + VERSION=$(echo ${{ github.ref }} | sed -e "s#refs/tags/##g") + echo ::set-output name=version::$VERSION + echo ::set-output name=filename::$REPOSITORY-$VERSION + - uses: actions/checkout@v2 + with: + path: main + - name: Download artifact to get build-macos-suisho + uses: actions/download-artifact@v2 + with: + name: build-macos-suisho_${{ github.run_number }}_${{ github.sha }} + path: release + - name: set executable run: | - 7z a -tzip ../../build-windows-suisho.zip * - 7z a -t7z ../../build-windows-suisho.7z * - working-directory: release-windows-suisho/windows/NNUE - - name: make build-deep-windows zip/7z + find release|grep ++|grep -v \.log|xargs -I _file_ chmod +x _file_ + - name: copy docs run: | - 7z a -tzip build-deep-windows.zip Deep-* source docs Copying.txt - 7z a -t7z build-deep-windows.7z Deep-* source docs Copying.txt - working-directory: release-deep-windows - - name: make build-android zip/7z + cp main/Copying.txt release/macos11/NNUE + cp -r main/docs release/macos11/NNUE + curl -LRo main/source/eval/nnue/embedded_nnue.cpp.gz https://github.com/mizar/YaneuraOu/releases/download/resource/suisho5_20211123.halfkp.nnue.cpp.gz; + gzip -df main/source/eval/nnue/embedded_nnue.cpp.gz; + tar -Jcf release/macos11/NNUE/source.tar.xz -C main source + - name: Display structure of downloaded files + run: ls -R release + - name: make build-macos-suisho .tar.xz run: | - 7z a -tzip build-android.zip android - 7z a -t7z build-android.7z android - working-directory: release-android - - name: make build-android-suisho zip/7z + tar -Jcf ../../build-macos-suisho.tar.xz * + working-directory: release/macos11/NNUE + - uses: actions/upload-artifact@v2 + with: + name: archive-macos-suisho_${{ github.run_number }}_${{ github.sha }} + path: | + release/*.tar.xz + archive-wasm: + runs-on: ubuntu-20.04 + needs: + - build-wasm + steps: + - name: Set version + id: version run: | - 7z a -tzip ../../build-android-suisho.zip * - 7z a -t7z ../../build-android-suisho.7z * - working-directory: release-android-suisho/android/NNUE + REPOSITORY=$(echo ${{ github.repository }} | sed -e "s#.*/##") + VERSION=$(echo ${{ github.ref }} | sed -e "s#refs/tags/##g") + echo ::set-output name=version::$VERSION + echo ::set-output name=filename::$REPOSITORY-$VERSION + - uses: actions/checkout@v2 + with: + path: main + - name: Download artifact to get build-wasm + uses: actions/download-artifact@v2 + with: + name: build-wasm_${{ github.run_number }}_${{ github.sha }} + path: release + - name: copy docs + run: | + cp main/Copying.txt release/wasm + cp -r main/docs release/wasm + tar -Jcf release/wasm/source.tar.xz -C main source + - name: Display structure of downloaded files + run: ls -R release + - name: make build-wasm zip/7z + run: | + 7z a -tzip build-wasm.zip wasm + 7z a -t7z build-wasm.7z wasm + working-directory: release + - uses: actions/upload-artifact@v2 + with: + name: archive-wasm_${{ github.run_number }}_${{ github.sha }} + path: | + release/*.zip + release/*.7z + archive-wasm-suisho: + runs-on: ubuntu-20.04 + needs: + - build-wasm-suisho + steps: + - name: Set version + id: version + run: | + REPOSITORY=$(echo ${{ github.repository }} | sed -e "s#.*/##") + VERSION=$(echo ${{ github.ref }} | sed -e "s#refs/tags/##g") + echo ::set-output name=version::$VERSION + echo ::set-output name=filename::$REPOSITORY-$VERSION + - uses: actions/checkout@v2 + with: + path: main + - name: Download artifact to get build-wasm-suisho + uses: actions/download-artifact@v2 + with: + name: build-wasm-suisho_${{ github.run_number }}_${{ github.sha }} + path: release + - name: copy docs + run: | + cp main/Copying.txt release/wasm + cp -r main/docs release/wasm + curl -LRo main/source/eval/nnue/embedded_nnue.cpp.gz https://github.com/mizar/YaneuraOu/releases/download/resource/suisho5_20211123.halfkp.nnue.cpp.gz; + gzip -df main/source/eval/nnue/embedded_nnue.cpp.gz; + tar -Jcf release/wasm/source.tar.xz -C main source + - name: Display structure of downloaded files + run: ls -R release + - name: make build-wasm zip/7z + run: | + 7z a -tzip build-wasm-suisho.zip wasm + 7z a -t7z build-wasm-suisho.7z wasm + working-directory: release + - uses: actions/upload-artifact@v2 + with: + name: archive-wasm-suisho_${{ github.run_number }}_${{ github.sha }} + path: | + release/*.zip + release/*.7z + archive-wasm-suishopetite: + runs-on: ubuntu-20.04 + needs: + - build-wasm-suishopetite + steps: + - name: Set version + id: version + run: | + REPOSITORY=$(echo ${{ github.repository }} | sed -e "s#.*/##") + VERSION=$(echo ${{ github.ref }} | sed -e "s#refs/tags/##g") + echo ::set-output name=version::$VERSION + echo ::set-output name=filename::$REPOSITORY-$VERSION + - uses: actions/checkout@v2 + with: + path: main + - name: Download artifact to get build-wasm-suishopetite + uses: actions/download-artifact@v2 + with: + name: build-wasm-suishopetite_${{ github.run_number }}_${{ github.sha }} + path: release + - name: copy docs + run: | + cp main/Copying.txt release/wasm + cp -r main/docs release/wasm + curl -LRo main/source/eval/nnue/embedded_nnue.cpp.gz https://github.com/mizar/YaneuraOu/releases/download/resource/suishopetite_20211123.k_p.nnue.cpp.gz; + gzip -df main/source/eval/nnue/embedded_nnue.cpp.gz; + tar -Jcf release/wasm/source.tar.xz -C main source + - name: Display structure of downloaded files + run: ls -R release + - name: make build-wasm zip/7z + run: | + 7z a -tzip build-wasm-suishopetite.zip wasm + 7z a -t7z build-wasm-suishopetite.7z wasm + working-directory: release + - uses: actions/upload-artifact@v2 + with: + name: archive-wasm-suishopetite_${{ github.run_number }}_${{ github.sha }} + path: | + release/*.zip + release/*.7z + + release-pkg: + name: Release package + needs: + - archive-msys2-general + - archive-msys2-material + - archive-msys2-suisho + - archive-deep-windows + - archive-android-general + - archive-android-suisho + - archive-macos-general + - archive-macos-suisho + - archive-wasm + - archive-wasm-suisho + - archive-wasm-suishopetite + # ubuntu-latest = ubuntu-20.04 + # https://docs.github.com/ja/actions/using-github-hosted-runners/about-github-hosted-runners + # https://github.com/actions/virtual-environments/blob/main/images/linux/Ubuntu2004-README.md + runs-on: ubuntu-20.04 + steps: + - name: Set version + id: version + run: | + REPOSITORY=$(echo ${{ github.repository }} | sed -e "s#.*/##") + VERSION=$(echo ${{ github.ref }} | sed -e "s#refs/tags/##g") + echo ::set-output name=version::$VERSION + echo ::set-output name=filename::$REPOSITORY-$VERSION + - uses: actions/checkout@v2 + with: + path: main + - name: Download artifact to get build-windows + uses: actions/download-artifact@v2 + with: + name: archive-windows_${{ github.run_number }}_${{ github.sha }} + path: release-windows + - name: Download artifact to get build-windows-material + uses: actions/download-artifact@v2 + with: + name: archive-windows-material_${{ github.run_number }}_${{ github.sha }} + path: release-windows-material + - name: Download artifact to get build-windows-suisho + uses: actions/download-artifact@v2 + with: + name: archive-windows-suisho_${{ github.run_number }}_${{ github.sha }} + path: release-windows-suisho + - name: Download artifact to get build-deep-windows + uses: actions/download-artifact@v2 + with: + name: archive-deep-windows_${{ github.run_number }}_${{ github.sha }} + path: release-deep-windows + - name: Download artifact to get build-android + uses: actions/download-artifact@v2 + with: + name: archive-android_${{ github.run_number }}_${{ github.sha }} + path: release-android + - name: Download artifact to get build-android-suisho + uses: actions/download-artifact@v2 + with: + name: archive-android-suisho_${{ github.run_number }}_${{ github.sha }} + path: release-android-suisho + - name: Download artifact to get build-macos + uses: actions/download-artifact@v2 + with: + name: archive-macos_${{ github.run_number }}_${{ github.sha }} + path: release-macos + - name: Download artifact to get build-macos-suisho + uses: actions/download-artifact@v2 + with: + name: archive-macos-suisho_${{ github.run_number }}_${{ github.sha }} + path: release-macos-suisho + - name: Download artifact to get build-wasm + uses: actions/download-artifact@v2 + with: + name: archive-wasm_${{ github.run_number }}_${{ github.sha }} + path: release-wasm + - name: Download artifact to get build-wasm-suisho + uses: actions/download-artifact@v2 + with: + name: archive-wasm-suisho_${{ github.run_number }}_${{ github.sha }} + path: release-wasm-suisho + - name: Download artifact to get build-wasm-suishopetite + uses: actions/download-artifact@v2 + with: + name: archive-wasm-suishopetite_${{ github.run_number }}_${{ github.sha }} + path: release-wasm-suishopetite + - name: Display structure of downloaded files + run: ls -R release-windows release-windows-material release-windows-suisho release-deep-windows release-android release-android-suisho release-macos-suisho release-macos-suisho release-wasm - name: Archive Size id: archive_size run: | @@ -520,6 +1269,14 @@ jobs: echo ::set-output name=android_7z::$(stat -c%s "release-android/build-android.7z" | awk '{ split( "B KB MB GB TB PB" , v ); s=1; while( $1>1024 ){ $1/=1024; s++ } printf "%.2f %s", $1, v[s] }') echo ::set-output name=android_suisho_zip::$(stat -c%s "release-android-suisho/build-android-suisho.zip" | awk '{ split( "B KB MB GB TB PB" , v ); s=1; while( $1>1024 ){ $1/=1024; s++ } printf "%.2f %s", $1, v[s] }') echo ::set-output name=android_suisho_7z::$(stat -c%s "release-android-suisho/build-android-suisho.7z" | awk '{ split( "B KB MB GB TB PB" , v ); s=1; while( $1>1024 ){ $1/=1024; s++ } printf "%.2f %s", $1, v[s] }') + echo ::set-output name=macos_tar_xz::$(stat -c%s "release-macos/build-macos.tar.xz" | awk '{ split( "B KB MB GB TB PB" , v ); s=1; while( $1>1024 ){ $1/=1024; s++ } printf "%.2f %s", $1, v[s] }') + echo ::set-output name=macos_suisho_tar_xz::$(stat -c%s "release-macos-suisho/build-macos-suisho.tar.xz" | awk '{ split( "B KB MB GB TB PB" , v ); s=1; while( $1>1024 ){ $1/=1024; s++ } printf "%.2f %s", $1, v[s] }') + echo ::set-output name=wasm_zip::$(stat -c%s "release-wasm/build-wasm.zip" | awk '{ split( "B KB MB GB TB PB" , v ); s=1; while( $1>1024 ){ $1/=1024; s++ } printf "%.2f %s", $1, v[s] }') + echo ::set-output name=wasm_7z::$(stat -c%s "release-wasm/build-wasm.7z" | awk '{ split( "B KB MB GB TB PB" , v ); s=1; while( $1>1024 ){ $1/=1024; s++ } printf "%.2f %s", $1, v[s] }') + echo ::set-output name=wasm-suisho_zip::$(stat -c%s "release-wasm-suisho/build-wasm-suisho.zip" | awk '{ split( "B KB MB GB TB PB" , v ); s=1; while( $1>1024 ){ $1/=1024; s++ } printf "%.2f %s", $1, v[s] }') + echo ::set-output name=wasm-suisho_7z::$(stat -c%s "release-wasm-suisho/build-wasm-suisho.7z" | awk '{ split( "B KB MB GB TB PB" , v ); s=1; while( $1>1024 ){ $1/=1024; s++ } printf "%.2f %s", $1, v[s] }') + echo ::set-output name=wasm-suishopetite_zip::$(stat -c%s "release-wasm-suishopetite/build-wasm-suishopetite.zip" | awk '{ split( "B KB MB GB TB PB" , v ); s=1; while( $1>1024 ){ $1/=1024; s++ } printf "%.2f %s", $1, v[s] }') + echo ::set-output name=wasm-suishopetite_7z::$(stat -c%s "release-wasm-suishopetite/build-wasm-suishopetite.7z" | awk '{ split( "B KB MB GB TB PB" , v ); s=1; while( $1>1024 ){ $1/=1024; s++ } printf "%.2f %s", $1, v[s] }') - name: Create release id: create_release uses: actions/create-release@v1 @@ -542,27 +1299,20 @@ jobs: cf. [魚沼産やねうら王できました](http://yaneuraou.yaneu.com/2019/02/12/%e9%ad%9a%e6%b2%bc%e7%94%a3%e3%82%84%e3%81%ad%e3%81%86%e3%82%89%e7%8e%8b%e3%81%a7%e3%81%8d%e3%81%be%e3%81%97%e3%81%9f/) d. HalfKPvm型 cf. [tanuki-denryu2](https://github.com/nodchip/tanuki-/releases/tag/tanuki-denryu2) - 4. MaterialLv1~9 + 4. MaterialLv1, MaterialLv9 a. MaterialLv1 駒得のみ - b. MaterialLv2 駒得+手駒評価 - cf. [【連載】評価関数を作ってみよう!その1](http://yaneuraou.yaneu.com/2020/11/17/make-evaluate-function/) - c. MaterialLv3 +盤上の利きを評価 - cf. [【連載】評価関数を作ってみよう!その2](http://yaneuraou.yaneu.com/2020/11/19/make-evaluate-function-2/) - cf. [【連載】評価関数を作ってみよう!その3](http://yaneuraou.yaneu.com/2020/11/20/make-evaluate-function-3/) - cf. [【連載】評価関数を作ってみよう!その4](http://yaneuraou.yaneu.com/2020/11/23/make-evaluate-function-4/) - d. MaterialLv4 +複数の利きに減衰評価 - cf. [【連載】評価関数を作ってみよう!その5](http://yaneuraou.yaneu.com/2020/11/25/make-evaluate-function-5/) - e. MaterialLv5 +利きの価値合算テーブル - cf. [【連載】評価関数を作ってみよう!その6](http://yaneuraou.yaneu.com/2020/11/26/make-evaluate-function-6/) - f. MaterialLv6 +KKPEE9テーブルに一本化 - cf. [【連載】評価関数を作ってみよう!その7](http://yaneuraou.yaneu.com/2020/11/27/make-evaluate-function-7/) - g. MaterialLv7 +味方・敵の駒の利きによる加減 - cf. [【連載】評価関数を作ってみよう!その8](http://yaneuraou.yaneu.com/2020/11/30/make-evaluate-function-8/) - h. MaterialLv8 +玉近傍への味方駒の利きと駒の有無、玉位置加点 - cf. [【連載】評価関数を作ってみよう!その9](http://yaneuraou.yaneu.com/2020/12/01/make-evaluate-function-9/) - cf. [【連載】評価関数を作ってみよう!その10](http://yaneuraou.yaneu.com/2020/12/02/make-evaluate-function-10/) - i. MaterialLv9 +方角ごとの利き評価 - cf. [【連載】評価関数を作ってみよう!その11](http://yaneuraou.yaneu.com/2020/12/07/make-evaluate-function-11/) + b. MaterialLv9 駒得+手駒評価+盤上の利きを評価+複数の利きに減衰評価+利きの価値合算テーブル+KKPEE9テーブルに一本化+味方・敵の駒の利きによる加減+玉近傍への味方駒の利きと駒の有無、玉位置加点+方角ごとの利き評価 + - [【連載】評価関数を作ってみよう!その1](http://yaneuraou.yaneu.com/2020/11/17/make-evaluate-function/) + - [【連載】評価関数を作ってみよう!その2](http://yaneuraou.yaneu.com/2020/11/19/make-evaluate-function-2/) + - [【連載】評価関数を作ってみよう!その3](http://yaneuraou.yaneu.com/2020/11/20/make-evaluate-function-3/) + - [【連載】評価関数を作ってみよう!その4](http://yaneuraou.yaneu.com/2020/11/23/make-evaluate-function-4/) + - [【連載】評価関数を作ってみよう!その5](http://yaneuraou.yaneu.com/2020/11/25/make-evaluate-function-5/) + - [【連載】評価関数を作ってみよう!その6](http://yaneuraou.yaneu.com/2020/11/26/make-evaluate-function-6/) + - [【連載】評価関数を作ってみよう!その7](http://yaneuraou.yaneu.com/2020/11/27/make-evaluate-function-7/) + - [【連載】評価関数を作ってみよう!その8](http://yaneuraou.yaneu.com/2020/11/30/make-evaluate-function-8/) + - [【連載】評価関数を作ってみよう!その9](http://yaneuraou.yaneu.com/2020/12/01/make-evaluate-function-9/) + - [【連載】評価関数を作ってみよう!その10](http://yaneuraou.yaneu.com/2020/12/02/make-evaluate-function-10/) + - [【連載】評価関数を作ってみよう!その11](http://yaneuraou.yaneu.com/2020/12/07/make-evaluate-function-11/) 5. YaneuraOu詰将棋エンジン cf. [やねうら王詰将棋エンジンを公開しました](http://yaneuraou.yaneu.com/2020/12/29/yaneuraou-mate-solver/) 6. tanuki-詰将棋エンジン @@ -573,10 +1323,18 @@ jobs: - [Suisho5-${{ steps.version.outputs.filename }}-windows.zip](https://github.com/${{ github.repository }}/releases/download/${{ steps.version.outputs.version }}/Suisho5-${{ steps.version.outputs.filename }}-windows.zip) (${{ steps.archive_size.outputs.windows_suisho_zip }}) - [Suisho5-${{ steps.version.outputs.filename }}-windows.7z](https://github.com/${{ github.repository }}/releases/download/${{ steps.version.outputs.version }}/Suisho5-${{ steps.version.outputs.filename }}-windows.7z) (${{ steps.archive_size.outputs.windows_suisho_7z }}) - - 3.のトーナメントWindows版+水匠5(20211123)評価関数 (ZEN2/AVX2/SSE4.2) + - 3.a.のトーナメントWindows版+水匠5(20211123)評価関数 (ZEN2/AVX2/SSE4.2) - [Suisho5-${{ steps.version.outputs.filename }}-android.zip](https://github.com/${{ github.repository }}/releases/download/${{ steps.version.outputs.version }}/Suisho5-${{ steps.version.outputs.filename }}-android.zip) (${{ steps.archive_size.outputs.android_suisho_zip }}) - [Suisho5-${{ steps.version.outputs.filename }}-android.7z](https://github.com/${{ github.repository }}/releases/download/${{ steps.version.outputs.version }}/Suisho5-${{ steps.version.outputs.filename }}-android.7z) (${{ steps.archive_size.outputs.android_suisho_7z }}) - - 3.の実行ファイルAndroid版+水匠5(20211123)評価関数 (arm64-v8a/armeabi-v7a/x86_64/x86) + - 3.a.の実行ファイルAndroid版+水匠5(20211123)評価関数 (arm64-v8a/armeabi-v7a/x86_64/x86) + - [Suisho5-${{ steps.version.outputs.filename }}-macos.tar.xz](https://github.com/${{ github.repository }}/releases/download/${{ steps.version.outputs.version }}/Suisho5-${{ steps.version.outputs.filename }}-macos.tar.xz) (${{ steps.archive_size.outputs.macos_suisho_tar_xz }}) + - 3.a.の実行ファイルMacOS版+水匠5(20211123)評価関数 (AVX2/SSE42/APPLEM1) (testing) + - [Suisho5-${{ steps.version.outputs.filename }}-wasm.zip](https://github.com/${{ github.repository }}/releases/download/${{ steps.version.outputs.version }}/Suisho5-${{ steps.version.outputs.filename }}-wasm.zip) (${{ steps.archive_size.outputs.wasm-suisho_zip }}) + - [Suisho5-${{ steps.version.outputs.filename }}-wasm.7z](https://github.com/${{ github.repository }}/releases/download/${{ steps.version.outputs.version }}/Suisho5-${{ steps.version.outputs.filename }}-wasm.7z) (${{ steps.archive_size.outputs.wasm-suisho_7z }}) + - 3.a.の実行ファイルWebAssembly版+水匠5(20211123)評価関数 (testing) + - [SuishoPetite-${{ steps.version.outputs.filename }}-wasm.zip](https://github.com/${{ github.repository }}/releases/download/${{ steps.version.outputs.version }}/SuishoPetite-${{ steps.version.outputs.filename }}-wasm.zip) (${{ steps.archive_size.outputs.wasm-suishopetite_zip }}) + - [SuishoPetite-${{ steps.version.outputs.filename }}-wasm.7z](https://github.com/${{ github.repository }}/releases/download/${{ steps.version.outputs.version }}/SuishoPetite-${{ steps.version.outputs.filename }}-wasm.7z) (${{ steps.archive_size.outputs.wasm-suishopetite_7z }}) + - 3.c.の実行ファイルWebAssembly版+SuishoPetite(20211123)評価関数 (testing) - [${{ steps.version.outputs.filename }}-windows.zip](https://github.com/${{ github.repository }}/releases/download/${{ steps.version.outputs.version }}/${{ steps.version.outputs.filename }}-windows.zip) (${{ steps.archive_size.outputs.windows_zip }}) - [${{ steps.version.outputs.filename }}-windows.7z](https://github.com/${{ github.repository }}/releases/download/${{ steps.version.outputs.version }}/${{ steps.version.outputs.filename }}-windows.7z) (${{ steps.archive_size.outputs.windows_7z }}) - 1.2.3.5.6.の実行ファイルWindows版 各CPU向け(ZEN3/ZEN2/ZEN1/AVX512VNNI/AVXVNNI/AVX512/AVX2/SSE4.2/SSE4.1/SSSE3/SSE2/32bit環境用) @@ -598,26 +1356,26 @@ jobs: - ORT-DML : Windows 10 DirectML (DML) 対応のGPU向け。(対応環境であればおそらくORT-TRT や TensorRTのが高速) cf. [DirectML の概要](https://docs.microsoft.com/ja-jp/windows/win32/direct3d12/dml-intro) - ORT-TRT : NVIDIA TensorRT 対応のGPU向け。CUDA, cuDNN, TensorRT の導入も必要です。 - - CUDA (開発環境は 11.5.1) + - CUDA (開発環境は 11.6.2) - [Latest CUDA Toolkit Download](https://developer.nvidia.com/cuda-downloads) - [CUDA Toolkit Archive](https://developer.nvidia.com/cuda-toolkit-archive) - [CUDA Installation Guide for Microsoft Windows (CUDAインストール手順, CUDA 最新版)](https://docs.nvidia.com/cuda/cuda-installation-guide-microsoft-windows/index.html) - - CUDA Toolkit 11.5.1 の場合の導入例: - - [Local Installer (2.4GB)](https://developer.download.nvidia.com/compute/cuda/11.5.1/local_installers/cuda_11.5.1_496.13_windows.exe) もしくは [Network Installer (28.7MB)](https://developer.download.nvidia.com/compute/cuda/11.5.1/network_installers/cuda_11.5.1_windows_network.exe) をダウンロード・実行してインストール - - cuDNN (開発環境は v8.2.4 (Archive)) + - CUDA Toolkit 11.6.2 の場合の導入例: + - [Local Installer (2.5GB)](https://developer.download.nvidia.com/compute/cuda/11.6.2/local_installers/cuda_11.6.2_511.65_windows.exe) もしくは [Network Installer (33.6MB)](https://developer.download.nvidia.com/compute/cuda/11.6.2/network_installers/cuda_11.6.2_windows_network.exe) をダウンロード・実行してインストール + - cuDNN (開発環境は [v8.2.4 (Archive)](https://developer.nvidia.com/rdp/cudnn-archive)) - [cuDNN Download](https://developer.nvidia.com/rdp/cudnn-download) (要ログイン) - - [cuDNN Archive](https://developer.nvidia.com/rdp/cudnn-archive) (要ログイン) + - (注: Windows版では現状、v8.3.x 系は非推奨。過去のバージョンは [cuDNN Archive](https://developer.nvidia.com/rdp/cudnn-archive) (要ログイン) を参照。) - [Installing cuDNN On Windows (cuDNNインストール手順)](https://docs.nvidia.com/deeplearning/cudnn/install-guide/index.html#install-windows) - cuDNN v8.2.4 (`cudnn-11.4-windows-x64-x64-v8.2.4.15.zip`) の場合の導入例: - ダウンロードした `cudnn-11.4-windows-x64-x64-v8.2.4.15.zip` を右クリック → 「すべて展開」 → 展開時に展開されたファイルを表示する - `cudnn-11.4-windows-x64-x64-v8.2.4.15/cuda/bin` フォルダ階層を選択して表示 - `cudnn_adv_infer64_8.dll`, `cudnn_cnn_infer64_8.dll`, `cudnn_ops_infer64_8.dll`, `cudnn64_8.dll` (種類: アプリケーション拡張) の4つのファイルを選択し、`YaneuraOu-Deep-ORT-TRT.exe` と同じフォルダにコピー - - TensorRT (開発環境は 8.2.1 GA) + - TensorRT (開発環境は 8.2 GA Update 2) - [NVIDIA TensorRT Download](https://developer.nvidia.com/nvidia-tensorrt-download) (要ログイン) - [Installing TensorRT (TensorRTインストール手順)](https://docs.nvidia.com/deeplearning/tensorrt/install-guide/index.html#installing-zip) - - TensorRT 8.2.1 GA (`TensorRT-8.2.1.8.Windows10.x86_64.cuda-11.4.cudnn8.2.zip`) の場合の導入例: - - ダウンロードした `TensorRT-8.2.1.8.Windows10.x86_64.cuda-11.4.cudnn8.2.zip` を右クリック → 「すべて展開」 → 展開時に展開されたファイルを表示する - - `TensorRT-8.2.1.8/lib` フォルダ階層を選択して表示 + - TensorRT 8.2 GA Update 3 (`TensorRT-8.2.4.2.Windows10.x86_64.cuda-11.4.cudnn8.2.zip`) の場合の導入例: + - ダウンロードした `TensorRT-8.2.4.2.Windows10.x86_64.cuda-11.4.cudnn8.2.zip` を右クリック → 「すべて展開」 → 展開時に展開されたファイルを表示する + - `TensorRT-8.2.4.2/lib` フォルダ階層を選択して表示 - `nvinfer.dll`, `nvinfer_builder_resource.dll`, `nvinfer_plugin.dll`, `nvonnxparser.dll`, `nvparsers.dll` (種類: アプリケーション拡張) の5つのファイルを選択し、`YaneuraOu-Deep-ORT-TRT.exe` と同じフォルダにコピー - [警告: 以下のような変更があった場合は、古いエンジンやプロファイルのキャッシュファイル(`.engine`, `.profile`)をクリーンアップしてください。](https://onnxruntime.ai/docs/execution-providers/TensorRT-ExecutionProvider.html#environment-variables) - モデルの変更(モデルのトポロジー、opsetのバージョン、演算子などに変更があった場合) @@ -628,7 +1386,12 @@ jobs: - ~~TensorRT : NVIDIA TensorRT 対応のGPU向け(ORT無し版)。~~ 現在、TensorRT(ORT無し)版は自動ビルドの対象外です。 - [${{ steps.version.outputs.filename }}-android.zip](https://github.com/${{ github.repository }}/releases/download/${{ steps.version.outputs.version }}/${{ steps.version.outputs.filename }}-android.zip) (${{ steps.archive_size.outputs.android_zip }}) - [${{ steps.version.outputs.filename }}-android.7z](https://github.com/${{ github.repository }}/releases/download/${{ steps.version.outputs.version }}/${{ steps.version.outputs.filename }}-android.7z) (${{ steps.archive_size.outputs.android_7z }}) - - 1.2.3.4.5.の実行ファイルAndroid版 (arm64-v8a/armeabi-v7a/x86_64/x86) + - 1.2.3.4.5.6.の実行ファイルAndroid版 (arm64-v8a/armeabi-v7a/x86_64/x86) + - [${{ steps.version.outputs.filename }}-macos.tar.xz](https://github.com/${{ github.repository }}/releases/download/${{ steps.version.outputs.version }}/${{ steps.version.outputs.filename }}-macos.tar.xz) (${{ steps.archive_size.outputs.macos_tar_xz }}) + - 1.2.3.4.5.6.の実行ファイルMacOS版 (AVX2/SSE42/APPLEM1) (testing) + - [${{ steps.version.outputs.filename }}-wasm.zip](https://github.com/${{ github.repository }}/releases/download/${{ steps.version.outputs.version }}/${{ steps.version.outputs.filename }}-wasm.zip) (${{ steps.archive_size.outputs.wasm_zip }}) + - [${{ steps.version.outputs.filename }}-wasm.7z](https://github.com/${{ github.repository }}/releases/download/${{ steps.version.outputs.version }}/${{ steps.version.outputs.filename }}-wasm.7z) (${{ steps.archive_size.outputs.wasm_7z }}) + - 1.2.3.4.5.6.の実行ファイルWebAssembly版 (testing) 使い方などは添付ファイルの中にある docs @@ -638,7 +1401,7 @@ jobs: # 先行リリースのフラグを付ける(true) prerelease: true - name: Upload release asset build-windows.zip - uses: actions/upload-release-asset@v1.0.1 + uses: actions/upload-release-asset@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: @@ -647,7 +1410,7 @@ jobs: asset_name: ${{ steps.version.outputs.filename }}-windows.zip asset_content_type: application/zip - name: Upload release asset build-windows.7z - uses: actions/upload-release-asset@v1.0.1 + uses: actions/upload-release-asset@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: @@ -656,7 +1419,7 @@ jobs: asset_name: ${{ steps.version.outputs.filename }}-windows.7z asset_content_type: application/octet-stream - name: Upload release asset build-windows-material.zip - uses: actions/upload-release-asset@v1.0.1 + uses: actions/upload-release-asset@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: @@ -665,7 +1428,7 @@ jobs: asset_name: ${{ steps.version.outputs.filename }}-windows-material.zip asset_content_type: application/zip - name: Upload release asset build-windows-material.7z - uses: actions/upload-release-asset@v1.0.1 + uses: actions/upload-release-asset@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: @@ -674,7 +1437,7 @@ jobs: asset_name: ${{ steps.version.outputs.filename }}-windows-material.7z asset_content_type: application/octet-stream - name: Upload release asset build-deep-windows.zip - uses: actions/upload-release-asset@v1.0.1 + uses: actions/upload-release-asset@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: @@ -683,7 +1446,7 @@ jobs: asset_name: ${{ steps.version.outputs.filename }}-deep-windows.zip asset_content_type: application/zip - name: Upload release asset build-deep-windows.7z - uses: actions/upload-release-asset@v1.0.1 + uses: actions/upload-release-asset@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: @@ -692,7 +1455,7 @@ jobs: asset_name: ${{ steps.version.outputs.filename }}-deep-windows.7z asset_content_type: application/octet-stream - name: Upload release asset build-android.zip - uses: actions/upload-release-asset@v1.0.1 + uses: actions/upload-release-asset@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: @@ -701,7 +1464,7 @@ jobs: asset_name: ${{ steps.version.outputs.filename }}-android.zip asset_content_type: application/zip - name: Upload release asset build-android.7z - uses: actions/upload-release-asset@v1.0.1 + uses: actions/upload-release-asset@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: @@ -709,8 +1472,35 @@ jobs: asset_path: release-android/build-android.7z asset_name: ${{ steps.version.outputs.filename }}-android.7z asset_content_type: application/octet-stream + - name: Upload release asset build-macos.tar.xz + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: release-macos/build-macos.tar.xz + asset_name: ${{ steps.version.outputs.filename }}-macos.tar.xz + asset_content_type: application/x-xz + - name: Upload release asset build-wasm.zip + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: release-wasm/build-wasm.zip + asset_name: ${{ steps.version.outputs.filename }}-wasm.zip + asset_content_type: application/zip + - name: Upload release asset build-wasm.7z + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: release-wasm/build-wasm.7z + asset_name: ${{ steps.version.outputs.filename }}-wasm.7z + asset_content_type: application/octet-stream - name: Upload release asset build-windows-suisho.zip - uses: actions/upload-release-asset@v1.0.1 + uses: actions/upload-release-asset@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: @@ -719,7 +1509,7 @@ jobs: asset_name: Suisho5-${{ steps.version.outputs.filename }}-windows.zip asset_content_type: application/zip - name: Upload release asset build-windows-suisho.7z - uses: actions/upload-release-asset@v1.0.1 + uses: actions/upload-release-asset@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: @@ -728,7 +1518,7 @@ jobs: asset_name: Suisho5-${{ steps.version.outputs.filename }}-windows.7z asset_content_type: application/octet-stream - name: Upload release asset build-android-suisho.zip - uses: actions/upload-release-asset@v1.0.1 + uses: actions/upload-release-asset@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: @@ -737,7 +1527,7 @@ jobs: asset_name: Suisho5-${{ steps.version.outputs.filename }}-android.zip asset_content_type: application/zip - name: Upload release asset build-android-suisho.7z - uses: actions/upload-release-asset@v1.0.1 + uses: actions/upload-release-asset@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: @@ -745,3 +1535,48 @@ jobs: asset_path: release-android-suisho/build-android-suisho.7z asset_name: Suisho5-${{ steps.version.outputs.filename }}-android.7z asset_content_type: application/octet-stream + - name: Upload release asset build-macos-suisho.tar.xz + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: release-macos-suisho/build-macos-suisho.tar.xz + asset_name: Suisho5-${{ steps.version.outputs.filename }}-macos.tar.xz + asset_content_type: application/x-xz + - name: Upload release asset build-wasm-suisho.zip + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: release-wasm-suisho/build-wasm-suisho.zip + asset_name: Suisho5-${{ steps.version.outputs.filename }}-wasm.zip + asset_content_type: application/zip + - name: Upload release asset build-android-suisho.7z + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: release-wasm-suisho/build-wasm-suisho.7z + asset_name: Suisho5-${{ steps.version.outputs.filename }}-wasm.7z + asset_content_type: application/octet-stream + - name: Upload release asset build-wasm-suishopetite.zip + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: release-wasm-suishopetite/build-wasm-suishopetite.zip + asset_name: SuishoPetite-${{ steps.version.outputs.filename }}-wasm.zip + asset_content_type: application/zip + - name: Upload release asset build-android-suisho.7z + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: release-wasm-suishopetite/build-wasm-suishopetite.7z + asset_name: SuishoPetite-${{ steps.version.outputs.filename }}-wasm.7z + asset_content_type: application/octet-stream diff --git a/.gitignore b/.gitignore index dfb282255..68b327197 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,7 @@ # added by yaneurao -*.gitattributes +# *.gitattributes # *.gitignore *.bat *.rb @@ -17,6 +17,13 @@ YaneuraOu_backup*.lnk *.vspx *~ ~* +.dl/ +.script/ +.vscode/ +docker/ +*.nnue +*.nnue.* +*.result.txt # embedded_nnue.cpp embedded_nnue.cpp @@ -52,6 +59,7 @@ bld/ [Bb]in/ [Oo]bj/ exe/ +npmpackages/**/lib/* # Visual Studio 2015 cache/options directory .vs/ diff --git a/README.md b/README.md index 158dd56ec..def166bb0 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ [![Make CI (for Ubuntu Linux)](https://github.com/yaneurao/YaneuraOu/actions/workflows/make.yml/badge.svg?event=push)](https://github.com/yaneurao/YaneuraOu/actions/workflows/make.yml) [![Make CI (DeepLearning for Ubuntu Linux)](https://github.com/yaneurao/YaneuraOu/actions/workflows/make-deep-ubuntu.yml/badge.svg?event=push)](https://github.com/yaneurao/YaneuraOu/actions/workflows/make-deep-ubuntu.yml) [![NDK CI (for Android)](https://github.com/yaneurao/YaneuraOu/actions/workflows/ndk.yml/badge.svg?event=push)](https://github.com/yaneurao/YaneuraOu/actions/workflows/ndk.yml) +[![Make CI (for MacOS)](https://github.com/yaneurao/YaneuraOu/actions/workflows/make-macos.yml/badge.svg?event=push)](https://github.com/yaneurao/YaneuraOu/actions/workflows/make-macos.yml) +[![Make CI (for WebAssembly)](https://github.com/yaneurao/YaneuraOu/actions/workflows/make-wasm.yml/badge.svg?event=push)](https://github.com/yaneurao/YaneuraOu/actions/workflows/make-wasm.yml) # About this project diff --git "a/docs/\350\247\243\350\252\254.txt" "b/docs/\350\247\243\350\252\254.txt" index 33fd70d89..05541ad48 100644 --- "a/docs/\350\247\243\350\252\254.txt" +++ "b/docs/\350\247\243\350\252\254.txt" @@ -714,7 +714,7 @@ pactoys入れて、それ使ってインストールすると楽ちんのよう % pacman --needed --noconfirm -Syuu % pacman --needed --noconfirm -Syuu pactoys - % pacboy --needed --noconfirm -Syuu clang:m lld:m openblas:x openmp:x toolchain:m base-devel: + % pacboy --needed --noconfirm -Syuu clang:m lld:m openblas:x openmp:x toolchain:m // :m は32/64bit両方、 :x は64bitのみ、 : はMSYS環境のパッケージという感じの指定です // 例) clangには :m を指定しているので、MSYS2の32bit,64bitの両環境用にclangがインストールされます。 @@ -723,15 +723,15 @@ pactoys入れて、それ使ってインストールすると楽ちんのよう #パッケージのキャッシュを削除 % rm -rf /var/cache/pacman/pkg/* - + # pacman keyのリセット % rm -r /etc/pacman.d/gnupg/ % pacman-key --init % pacman-key --populate msys2 - + # 先にkeyringパッケージを更新 % pacman -S msys2-keyring - + # 他のパッケージ更新 % pacman -Syyu @@ -797,7 +797,7 @@ WindowsのLarge Pageという方法で置換表用のメモリを確保すると 3. ここで適切なユーザーに権限を付与する。 4. OSを再起動する - cf. + cf. Enable the Lock Pages in Memory Option (Windows) https://msdn.microsoft.com/en-us/library/ms190730.aspx diff --git a/jni/Android.mk b/jni/Android.mk index e80016e89..3e0a76af0 100644 --- a/jni/Android.mk +++ b/jni/Android.mk @@ -77,6 +77,8 @@ MATERIAL_LEVEL = 1 EVAL_EMBEDDING = OFF # EVAL_EMBEDDING = ON +CPPFLAGS += $(EXTRA_CPPFLAGS) + ifeq ($(YANEURAOU_EDITION),YANEURAOU_ENGINE_KPPT) CPPFLAGS += -DUSE_MAKEFILE -DYANEURAOU_ENGINE_KPPT ENGINE_NAME := YaneuraOu_KPPT diff --git a/script/android_build.sh b/script/android_build.sh index 351a17f2a..9decef03e 100755 --- a/script/android_build.sh +++ b/script/android_build.sh @@ -1,7 +1,5 @@ #!/bin/bash -JOBS=`grep -c ^processor /proc/cpuinfo 2>/dev/null` - EDITIONS='*' EXTRA='' @@ -100,7 +98,7 @@ for EDITION in ${EDITIONS[@]}; do BUILDDIR=build/android/${DIRSTR[$EDITION]} mkdir -p ${BUILDDIR} ndk-build clean YANEURAOU_EDITION=${EDITIONSTR[$EDITION]} ${EXTRA} - ndk-build -j${JOBS} YANEURAOU_EDITION=${EDITIONSTR[$EDITION]} V=1 ${EXTRA} >& >(tee ${BUILDDIR}/build.log) || exit $? + ndk-build -j$(nproc) YANEURAOU_EDITION=${EDITIONSTR[$EDITION]} V=1 ${EXTRA} >& >(tee ${BUILDDIR}/build.log) || exit $? bash -c "cp libs/**/* ${BUILDDIR}" ndk-build clean YANEURAOU_EDITION=${EDITIONSTR[$EDITION]} ${EXTRA} break diff --git a/script/build.sh b/script/build.sh index 5ad6d8810..61b475f4e 100755 --- a/script/build.sh +++ b/script/build.sh @@ -14,7 +14,6 @@ MAKE=make MAKEFILE=Makefile -JOBS=`grep -c ^processor /proc/cpuinfo 2>/dev/null` ARCHCPUS='*' COMPILERS="clang++,g++" @@ -196,7 +195,7 @@ for COMPILER in ${COMPILERSARR[@]}; do echo "* archcpu: ${ARCHCPU}" TGSTR=${FILESTR[$EDITION]}-${OS}-${CSTR}-${TARGET}-${ARCHCPU} ${MAKE} -f ${MAKEFILE} clean YANEURAOU_EDITION=${EDITIONSTR[$EDITION]} ${EXTRA} - nice ${MAKE} -f ${MAKEFILE} -j${JOBS} ${TARGET} TARGET_CPU=${ARCHCPU} YANEURAOU_EDITION=${EDITIONSTR[$EDITION]} COMPILER=${COMPILER} TARGET=${BUILDDIR}/${TGSTR} ${EXTRA} >& >(tee ${BUILDDIR}/${TGSTR}.log) || exit $? + nice ${MAKE} -f ${MAKEFILE} -j$(nproc) ${TARGET} TARGET_CPU=${ARCHCPU} YANEURAOU_EDITION=${EDITIONSTR[$EDITION]} COMPILER=${COMPILER} TARGET=${BUILDDIR}/${TGSTR} ${EXTRA} >& >(tee ${BUILDDIR}/${TGSTR}.log) || exit $? ${MAKE} -f ${MAKEFILE} clean YANEURAOU_EDITION=${EDITIONSTR[$EDITION]} ${EXTRA} break fi diff --git a/script/mingw_gcc.sh b/script/mingw_gcc.sh index e00fe2648..dbc0b2acf 100755 --- a/script/mingw_gcc.sh +++ b/script/mingw_gcc.sh @@ -14,7 +14,6 @@ MAKE=make MAKEFILE=Makefile -JOBS=`grep -c ^processor /proc/cpuinfo 2>/dev/null` ARCHCPUS='*' COMPILERS="x86_64-w64-mingw32-g++-posix,i686-w64-mingw32-g++-posix" @@ -191,7 +190,7 @@ for COMPILER in ${COMPILERSARR[@]}; do echo "* archcpu: ${ARCHCPU}" TGSTR=${FILESTR[$EDITION]}-windows-${CSTR}-${TARGET}-${ARCHCPU} ${MAKE} -f ${MAKEFILE} clean OS=${OS} YANEURAOU_EDITION=${EDITIONSTR[$EDITION]} ${EXTRA} - nice ${MAKE} -f ${MAKEFILE} -j${JOBS} ${TARGET} OS=${OS} TARGET_CPU=${ARCHCPU} YANEURAOU_EDITION=${EDITIONSTR[$EDITION]} COMPILER=${COMPILER} ${EXTRA} >& >(tee ${BUILDDIR}/${TGSTR}.log) || exit $? + nice ${MAKE} -f ${MAKEFILE} -j$(nproc) ${TARGET} OS=${OS} TARGET_CPU=${ARCHCPU} YANEURAOU_EDITION=${EDITIONSTR[$EDITION]} COMPILER=${COMPILER} ${EXTRA} >& >(tee ${BUILDDIR}/${TGSTR}.log) || exit $? cp YaneuraOu-by-gcc.exe ${BUILDDIR}/${TGSTR}.exe ${MAKE} -f ${MAKEFILE} clean OS=${OS} YANEURAOU_EDITION=${EDITIONSTR[$EDITION]} ${EXTRA} break diff --git a/script/msys2_build.ps1 b/script/msys2_build.ps1 index 6aa958105..44f3b9fec 100644 --- a/script/msys2_build.ps1 +++ b/script/msys2_build.ps1 @@ -8,8 +8,9 @@ <# # MSYS2をインストールしたディレクトリで(もしくはPATH環境変数を設定して)以下を実行: +msys2_shell.cmd -msys2 -defterm -no-start -lc 'pacman --needed --noconfirm -Syuu'; msys2_shell.cmd -msys2 -defterm -no-start -lc 'pacman --needed --noconfirm -Syuu pactoys'; -msys2_shell.cmd -msys2 -defterm -no-start -lc 'pacboy --needed --noconfirm -Syuu clang:m lld:m openblas:x openmp:x toolchain:m base-devel:'; +msys2_shell.cmd -msys2 -defterm -no-start -lc 'pacboy --needed --noconfirm -Syuu clang:m lld:m openblas:x openmp:x toolchain:m'; # MSYS2パッケージの更新、更新出来る項目が無くなるまで繰り返し実行、場合によってはMSYS2の再起動が必要 #> diff --git a/script/msys2_build.sh b/script/msys2_build.sh index a680ea1fe..2f79dad43 100755 --- a/script/msys2_build.sh +++ b/script/msys2_build.sh @@ -2,8 +2,9 @@ # -*- coding: utf-8 -*- # MSYS2 (MinGW 64-bit) 上で Windows バイナリのビルド # ビルド用パッケージの導入 +# $ pacman --needed --noconfirm -Syuu # $ pacman --needed --noconfirm -Syuu pactoys -# $ pacboy --needed --noconfirm -Syuu clang:m lld:m openblas:x openmp:x toolchain:m base-devel: +# $ pacboy --needed --noconfirm -Syuu clang:m lld:m openblas:x openmp:x toolchain:m # MSYS2パッケージの更新、更新出来る項目が無くなるまで繰り返し実行、場合によってはMSYS2の再起動が必要 # $ pacman -Syuu --noconfirm @@ -19,7 +20,6 @@ OS=Windows_NT MAKE=mingw32-make MAKEFILE=Makefile -JOBS=`grep -c ^processor /proc/cpuinfo 2>/dev/null` ARCHCPUS='*' COMPILERS="clang++,g++" @@ -191,7 +191,7 @@ for COMPILER in ${COMPILERSARR[@]}; do echo "* cpu: ${CPU}" TGSTR=${FILESTR[$EDITION]}-msys2-${CSTR}-${TARGET} ${MAKE} -f ${MAKEFILE} clean YANEURAOU_EDITION=${EDITIONSTR[$EDITION]} ${EXTRA} - nice ${MAKE} -f ${MAKEFILE} -j${JOBS} ${TARGET} YANEURAOU_EDITION=${EDITIONSTR[$EDITION]} COMPILER=${COMPILER} TARGET_CPU=${ARCHCPU} ${EXTRA} >& >(tee ${BUILDDIR}/${TGSTR}.log) || exit $? + nice ${MAKE} -f ${MAKEFILE} -j$(nproc) ${TARGET} YANEURAOU_EDITION=${EDITIONSTR[$EDITION]} COMPILER=${COMPILER} TARGET_CPU=${ARCHCPU} ${EXTRA} >& >(tee ${BUILDDIR}/${TGSTR}.log) || exit $? cp YaneuraOu-by-gcc.exe ${BUILDDIR}/${TGSTR}.exe ${MAKE} -f ${MAKEFILE} clean YANEURAOU_EDITION=${EDITIONSTR[$EDITION]} ${EXTRA} set -f diff --git a/script/msys2_build32.sh b/script/msys2_build32.sh index 9b7ed607b..06464fe3e 100755 --- a/script/msys2_build32.sh +++ b/script/msys2_build32.sh @@ -2,8 +2,9 @@ # -*- coding: utf-8 -*- # MSYS2 (MinGW 32-bit) 上で Windows バイナリのビルド # ビルド用パッケージの導入 +# $ pacman --needed --noconfirm -Syuu # $ pacman --needed --noconfirm -Syuu pactoys -# $ pacboy --needed --noconfirm -Syuu clang:m lld:m openblas:x openmp:x toolchain:m base-devel: +# $ pacboy --needed --noconfirm -Syuu clang:m lld:m openblas:x openmp:x toolchain:m # MSYS2パッケージの更新、更新出来る項目が無くなるまで繰り返し実行、場合によってはMSYS2の再起動が必要 # $ pacman -Syuu --noconfirm @@ -19,7 +20,6 @@ OS=Windows_NT MAKE=mingw32-make MAKEFILE=Makefile -JOBS=`grep -c ^processor /proc/cpuinfo 2>/dev/null` COMPILERS="clang++,g++" EDITIONS='*' @@ -166,7 +166,7 @@ for COMPILER in ${COMPILERSARR[@]}; do echo "* target: ${TARGET}" TGSTR=YaneuraOu-${FILESTR[$EDITION]}-msys2-${CSTR}-${TARGET} ${MAKE} -f ${MAKEFILE} clean YANEURAOU_EDITION=${EDITIONSTR[$EDITION]} ${EXTRA} - nice ${MAKE} -f ${MAKEFILE} -j${JOBS} ${TARGET} YANEURAOU_EDITION=${EDITIONSTR[$EDITION]} COMPILER=${COMPILER} TARGET_CPU=NO_SSE ${EXTRA} >& >(tee ${BUILDDIR}/${TGSTR}.log) || exit $? + nice ${MAKE} -f ${MAKEFILE} -j$(nproc) ${TARGET} YANEURAOU_EDITION=${EDITIONSTR[$EDITION]} COMPILER=${COMPILER} TARGET_CPU=NO_SSE ${EXTRA} >& >(tee ${BUILDDIR}/${TGSTR}.log) || exit $? cp YaneuraOu-by-gcc.exe ${BUILDDIR}/${TGSTR}.exe ${MAKE} -f ${MAKEFILE} clean YANEURAOU_EDITION=${EDITIONSTR[$EDITION]} ${EXTRA} set -f diff --git a/script/wasm_build.cmd b/script/wasm_build.cmd new file mode 100644 index 000000000..af6faf7ab --- /dev/null +++ b/script/wasm_build.cmd @@ -0,0 +1,5 @@ +@echo off +cd %~dp0 +cd .. +docker pull emscripten/emsdk:latest +docker run --rm -v %CD%:/src emscripten/emsdk:latest node script/wasm_build.js diff --git a/script/wasm_build.js b/script/wasm_build.js new file mode 100755 index 000000000..541aa3e53 --- /dev/null +++ b/script/wasm_build.js @@ -0,0 +1,325 @@ +#!/usr/bin/env node +const { exec, execSync } = require("child_process"); +const fpath = require("path"); +const fs = require("fs"); +const os = require("os"); +const process = require("process"); +const zlib = require("zlib"); + +const pkgobjs = [ + { + name: "halfkp", + edition: "YANEURAOU_ENGINE_NNUE", + exportname: "YaneuraOu_HalfKP", + extra: "ENGINE_NAME=Suisho5+YaneuraOu EVAL_EMBEDDING=ON EM_INITIAL_MEMORY_SIZE=167772160 EXTRA_CPPFLAGS='-DENGINE_OPTIONS=\\\"\"option=name=FV_SCALE=type=spin=default=24=min=1=max=128\\\"\"'", + evalfile: true, + }, + { + name: "k-p", + edition: "YANEURAOU_ENGINE_NNUE_KP256", + exportname: "YaneuraOu_K_P", + extra: "EVAL_EMBEDDING=ON EM_INITIAL_MEMORY_SIZE=92274688 EXTRA_CPPFLAGS='-DENGINE_OPTIONS=\\\"\"option=name=FV_SCALE=type=spin=default=24=min=1=max=128\\\"\"'", + evalfile: true, + }, + { + name: "halfkp.noeval", + edition: "YANEURAOU_ENGINE_NNUE", + exportname: "YaneuraOu_HalfKP_noeval", + extra: "EM_INITIAL_MEMORY_SIZE=167772160", + evalfile: true, + }, + { + name: "halfkpe9.noeval", + edition: "YANEURAOU_ENGINE_NNUE_HALFKPE9", + exportname: "YaneuraOu_HalfKPE9_noeval", + extra: "EM_INITIAL_MEMORY_SIZE=167772160", + evalfile: true, + }, + { + name: "halfkpvm.noeval", + edition: "YANEURAOU_ENGINE_NNUE_HALFKP_VM_256X2_32_32", + exportname: "YaneuraOu_HalfKPvm_noeval", + extra: "EM_INITIAL_MEMORY_SIZE=167772160", + evalfile: true, + }, + { + name: "k-p.noeval", + edition: "YANEURAOU_ENGINE_NNUE_KP256", + exportname: "YaneuraOu_K_P_noeval", + extra: "EM_INITIAL_MEMORY_SIZE=92274688", + evalfile: true, + }, + { + name: "material", + edition: "YANEURAOU_ENGINE_MATERIAL", + exportname: "YaneuraOu_Material", + extra: "MATERIAL_LEVEL=1 EM_INITIAL_MEMORY_SIZE=92274688", + evalfile: false, + }, + { + name: "material9", + edition: "YANEURAOU_ENGINE_MATERIAL", + exportname: "YaneuraOu_Material9", + extra: "MATERIAL_LEVEL=9 EM_INITIAL_MEMORY_SIZE=402653184", + evalfile: false, + }, + { + name: "yaneuraou-mate", + edition: "YANEURAOU_MATE_ENGINE", + exportname: "YaneuraOu_MATE", + extra: "EM_INITIAL_MEMORY_SIZE=92274688", + evalfile: false, + }, + { + name: "tanuki-mate", + edition: "TANUKI_MATE_ENGINE", + exportname: "tanuki_MATE", + extra: "EM_INITIAL_MEMORY_SIZE=92274688", + evalfile: false, + }, +]; + +const args = process.argv.slice(2); +const pkglist = args.length ? pkgobjs.filter((e) => (args.indexOf(e.name) >= 0)) : pkgobjs; + +if(!fs.existsSync("source/Makefile")) { + console.error("source folder not found"); + process.exit(1); +} + +const cwd = process.cwd(); +const cpus = os.cpus().length; + +(async () => { +for(const pkgobj of pkglist) { + const builddirusi = `build/wasm/${pkgobj.name}/`; + const builddirlib = `build/wasm/${pkgobj.name}/lib/`; + const usijs_copy_dirs = [ + ]; + const dts_copy_dirs = [ + ]; + const lib_copy_dirs = [ + ]; + // embedded_nnue + switch(pkgobj.name) { + case "halfkp": + if (!fs.existsSync(".dl/suisho5_20211123.halfkp.nnue.cpp.gz")) { + execSync("curl --create-dirs -RLo .dl/suisho5_20211123.halfkp.nnue.cpp.gz https://github.com/mizar/YaneuraOu/releases/download/resource/suisho5_20211123.halfkp.nnue.cpp.gz"); + } + execSync("gzip -cd .dl/suisho5_20211123.halfkp.nnue.cpp.gz > source/eval/nnue/embedded_nnue.cpp"); + break; + case "k-p": + if(!fs.existsSync(".dl/suishopetite_20211123.k_p.nnue.cpp.gz")) { + execSync("curl --create-dirs -RLo .dl/suishopetite_20211123.k_p.nnue.cpp.gz https://github.com/mizar/YaneuraOu/releases/download/resource/suishopetite_20211123.k_p.nnue.cpp.gz"); + } + execSync("gzip -cd .dl/suishopetite_20211123.k_p.nnue.cpp.gz > source/eval/nnue/embedded_nnue.cpp"); + break; + } + // mkdir + fs.mkdirSync(fpath.join(cwd, builddirlib), { recursive: true }); + for (const copy_dir of lib_copy_dirs) { + fs.mkdirSync(fpath.join(cwd, copy_dir), { recursive: true }); + } + // rm + for(const libfile of fs.readdirSync(builddirlib)) { + fs.rmSync(fpath.join(builddirlib, libfile), { force: true }); + } + // usi.js + const bpath_usijs = fpath.join(cwd, builddirusi, `usi.${pkgobj.name}.js`); + const bpath_usits = fpath.join(cwd, builddirusi, `usi.${pkgobj.name}.ts`); + fs.writeFileSync(bpath_usijs, `#!/usr/bin/env node +const process = require("process"); +const fs = require("fs"); +const path = require("path"); +const readline = require("readline"); +const YaneuraOu = require("./lib/yaneuraou.${pkgobj.name}"); + +const USI_BOOK_FILE = process.env.USI_BOOK_FILE; +const USI_EVAL_FILE = process.env.USI_EVAL_FILE; + +async function runRepl(yaneuraou) { + const iface = readline.createInterface({ input: process.stdin }); + for await (const command of iface) { + if (command == "quit") { + break; + } + yaneuraou.postMessage(command); + } + yaneuraou.terminate(); +} + +async function main(argv) { + const yaneuraou = await YaneuraOu(); + const FS = yaneuraou.FS; + if (USI_BOOK_FILE) { + const buffer = await fs.promises.readFile(USI_BOOK_FILE); + FS.writeFile(\`/\${path.basename(USI_BOOK_FILE)}\`, buffer); + yaneuraou.postMessage("setoption name BookDir value ."); + yaneuraou.postMessage(\`setoption name BookFile value \${path.basename(USI_BOOK_FILE)}\`); + } + const USE_EVAL_FILE = ${pkgobj.evalfile}; + if (USE_EVAL_FILE && USI_EVAL_FILE) { + const buffer = await fs.promises.readFile(USI_EVAL_FILE); + const filebase = path.basename(USI_EVAL_FILE); + FS.writeFile(\`/\${filebase}\`, buffer); + yaneuraou.postMessage("setoption name EvalDir value ."); + yaneuraou.postMessage(\`setoption name EvalFile value \${filebase}\`); + } + if (argv.length > 0) { + const commands = argv.join(" ").split(" , "); + for (const command of commands) { + yaneuraou.postMessage(command); + } + yaneuraou.terminate(); + return; + } + runRepl(yaneuraou); +} + +if (require.main === module) { + main(process.argv.slice(2)); +} +`); + fs.writeFileSync(bpath_usits, `/// +import process from "process"; +import fs from "fs"; +import path from "path"; +import readline from "readline"; +import YaneuraOu = require("./lib/yaneuraou.${pkgobj.name}"); +import { YaneuraOuModule } from "./lib/yaneuraou.module"; + +const USI_BOOK_FILE = process.env.USI_BOOK_FILE; +const USI_EVAL_FILE = process.env.USI_EVAL_FILE; + +async function runRepl(yaneuraou: YaneuraOuModule) { + const iface = readline.createInterface({ input: process.stdin }); + for await (const command of iface) { + if (command == "quit") { + break; + } + yaneuraou.postMessage(command); + } + yaneuraou.terminate(); +} + +async function main(argv: string[]) { + const yaneuraou: YaneuraOuModule = await YaneuraOu(); + const FS = yaneuraou.FS; + if (USI_BOOK_FILE) { + const buffer = await fs.promises.readFile(USI_BOOK_FILE); + FS.writeFile(\`/\${path.basename(USI_BOOK_FILE)}\`, buffer); + yaneuraou.postMessage("setoption name BookDir value ."); + yaneuraou.postMessage(\`setoption name BookFile value \${path.basename(USI_BOOK_FILE)}\`); + } + const USE_EVAL_FILE = ${pkgobj.evalfile}; + if (USE_EVAL_FILE && USI_EVAL_FILE) { + const buffer = await fs.promises.readFile(USI_EVAL_FILE); + const filebase = path.basename(USI_EVAL_FILE); + FS.writeFile(\`/\${filebase}\`, buffer); + yaneuraou.postMessage("setoption name EvalDir value ."); + yaneuraou.postMessage(\`setoption name EvalFile value \${filebase}\`); + } + if (argv.length > 0) { + const commands = argv.join(" ").split(" , "); + for (const command of commands) { + yaneuraou.postMessage(command); + } + yaneuraou.terminate(); + return; + } + runRepl(yaneuraou); +} + +if (require.main === module) { + main(process.argv.slice(2)); +} +`); + for(const copy_dir of usijs_copy_dirs) { + fs.copyFileSync(bpath_usijs, fpath.join(cwd, copy_dir, `usi.${pkgobj.name}.js`)); + fs.copyFileSync(bpath_usits, fpath.join(cwd, copy_dir, `usi.${pkgobj.name}.ts`)); + } + // .d.ts + const bpath_dts = fpath.join(cwd, builddirlib, `yaneuraou.${pkgobj.name}.d.ts`); + const bpath_module_dts = fpath.join(cwd, builddirlib, `yaneuraou.module.d.ts`); + fs.writeFileSync(bpath_module_dts, `/// + +export interface YaneuraOuModule extends EmscriptenModule +{ + addMessageListener: (listener: (line: string) => void) => void; + removeMessageListener: (listener: (line: string) => void) => void; + postMessage: (command: string) => void; + terminate: () => void; + ccall: typeof ccall; + FS: typeof FS; +} +`); + fs.writeFileSync(bpath_dts, `/// +import { YaneuraOuModule } from "./yaneuraou.module"; + +declare const ${pkgobj.exportname}: EmscriptenModuleFactory; +export = ${pkgobj.exportname}; +`); + for(const copy_dir of dts_copy_dirs) { + fs.copyFileSync(bpath_module_dts, fpath.join(cwd, copy_dir, `yaneuraou.module.d.ts`)); + fs.copyFileSync(bpath_dts, fpath.join(cwd, copy_dir, `yaneuraou.${pkgobj.name}.d.ts`)); + } + // make + await new Promise((resolve) => { + let child = exec( + `make -j${cpus} clean tournament COMPILER=em++ TARGET_CPU=WASM YANEURAOU_EDITION=${pkgobj.edition} TARGET=../${builddirlib}yaneuraou.${pkgobj.name}.js EM_EXPORT_NAME=${pkgobj.exportname} ${pkgobj.extra}`, + { cwd: fpath.join(cwd, "source"), stdio: "inherit" }, + (_error, _stdout, _stderr) => { resolve(); }, + ); + child.stdout.on('data', (data) => { console.log(String(data).trimEnd()); }); + child.stderr.on('data', (data) => { console.error(String(data).trimEnd()); }); + }); + // compress, public copy + for (const fext of ["js", "worker.js", "wasm"]) { + const bfile = `yaneuraou.${pkgobj.name}.${fext}`; + const bfile_br = `yaneuraou.${pkgobj.name}.${fext}.br`; + const bfile_gz = `yaneuraou.${pkgobj.name}.${fext}.gz`; + const bpath = fpath.join(cwd, builddirlib, bfile); + const bpath_br = fpath.join(cwd, builddirlib, bfile_br); + const bpath_gz = fpath.join(cwd, builddirlib, bfile_gz); + const ws_br = fs.createWriteStream(bpath_br); + const ws_gz = fs.createWriteStream(bpath_gz); + if(!fs.existsSync(bpath)) { + console.error(`file not found: ${bpath}`); + process.exit(1); + } + for(const copy_dir of lib_copy_dirs) { + fs.copyFileSync(bpath, fpath.join(cwd, copy_dir, bfile)); + } + const { atime, mtime } = fs.statSync(bpath); + ws_br.on('finish', () => { + fs.utimesSync(bpath_br, atime, mtime); + for(const copy_dir of lib_copy_dirs) { + fs.copyFileSync(bpath_br, fpath.join(cwd, copy_dir, bfile_br)); + fs.utimesSync(fpath.join(cwd, copy_dir, bfile_br), atime, mtime); + } + console.log(`compress finished: ${bpath_br}`); + }); + ws_gz.on('finish', () => { + fs.utimesSync(bpath_gz, atime, mtime); + for(const copy_dir of lib_copy_dirs) { + fs.copyFileSync(bpath_gz, fpath.join(cwd, copy_dir, bfile_gz)); + fs.utimesSync(fpath.join(cwd, copy_dir, bfile_gz), atime, mtime); + } + console.log(`compress finished: ${bpath_gz}`); + }); + // compress + fs.createReadStream(bpath) + .pipe(zlib.createBrotliCompress({ + params: { + [zlib.constants.BROTLI_PARAM_QUALITY]: zlib.constants.BROTLI_MAX_QUALITY, + } + })) + .pipe(ws_br); + fs.createReadStream(bpath) + .pipe(zlib.createGzip({ + level: zlib.constants.Z_MAX_LEVEL, + })) + .pipe(ws_gz); + } +} +})(); diff --git a/script/wasm_build.sh b/script/wasm_build.sh new file mode 100755 index 000000000..9a9fa4c84 --- /dev/null +++ b/script/wasm_build.sh @@ -0,0 +1,7 @@ +#!/bin/bash +pushd `dirname $0` +pushd ../ +docker pull emscripten/emsdk:latest +docker run --rm -v ${PWD}:/src emscripten/emsdk:latest node script/wasm_build.js +popd +popd diff --git a/script/wasm_docker_build.js b/script/wasm_docker_build.js new file mode 100755 index 000000000..ad075a255 --- /dev/null +++ b/script/wasm_docker_build.js @@ -0,0 +1,33 @@ +#!/usr/bin/env node +const { exec } = require("child_process"); +const process = require("process"); +const fs = require("fs"); + +const args = process.argv.slice(2); +const cwd = process.cwd(); + +if(!fs.existsSync("source/Makefile")) { + console.error("source folder not found"); + process.exit(1); +} + +(async () => { + await new Promise((resolve) => { + let child = exec( + `docker pull emscripten/emsdk:latest`, + { cwd: cwd, stdio: "inherit" }, + (_error, _stdout, _stderr) => { resolve(); }, + ); + child.stdout.on('data', (data) => { console.log(String(data).trimEnd()); }); + child.stderr.on('data', (data) => { console.error(String(data).trimEnd()); }); + }); + await new Promise((resolve) => { + let child = exec( + `docker run --rm -v ${cwd}:/src emscripten/emsdk:latest node script/wasm_build.js ${args.join(" ")}`, + { cwd: cwd, stdio: "inherit" }, + (_error, _stdout, _stderr) => { resolve(); }, + ); + child.stdout.on('data', (data) => { console.log(String(data).trimEnd()); }); + child.stderr.on('data', (data) => { console.error(String(data).trimEnd()); }); + }); +})(); diff --git a/source/Makefile b/source/Makefile index 4104a0077..dd26a3085 100644 --- a/source/Makefile +++ b/source/Makefile @@ -62,6 +62,7 @@ TARGET_CPU = AVX2 # -- ARMとか #TARGET_CPU = OTHER #TARGET_CPU = GRAVITON2 +#TARGET_CPU = WASM # デバッガーを使用するか (debugger) @@ -73,6 +74,7 @@ DEBUG = OFF # ※ clangでコンパイルしたほうがgccより数%速いっぽい。 #COMPILER = g++ COMPILER = clang++ +#COMPILER = em++ # エンジンの表示名 (engine displayname) @@ -87,7 +89,7 @@ COMPILER = clang++ # 標準的なコンパイルオプション (standard compile options) -CPPFLAGS = -std=c++17 -fno-exceptions -fno-rtti -Wextra -Ofast -MMD -MP -fpermissive +CPPFLAGS = -std=c++17 -fno-exceptions -fno-rtti -Wextra -MMD -MP -fpermissive WCPPFLAGS = LDFLAGS = $(EXTRA_LDFLAGS) LIBS = @@ -123,6 +125,13 @@ EVAL_EMBEDDING = OFF # ※ ifeq (A,B) は「AとBが等しいならば、以下を実行してください。」という意味。紛らわしいので気をつけよう。 +# em++ では -Ofast の指定は対応していない +ifneq (,$(findstring em++,$(COMPILER))) + CPPFLAGS += -O3 +else + CPPFLAGS += -Ofast +endif + # デバッガーを使わないなら、NDEBUGをdefineする。 ifeq ($(DEBUG),OFF) CPPFLAGS += -DNDEBUG @@ -156,18 +165,42 @@ else # C++17のfilesystem # LDFLAGS += -lstdc++fs - + endif + ifneq (,$(findstring em++,$(COMPILER))) + EM_EXPORT_NAME=YaneuraOu + EM_INITIAL_MEMORY_SIZE=$(shell if [ $(MATERIAL_LEVEL) -ge 5 ]; then echo 385875968; else echo 138412032; fi) + CPPFLAGS += -Wno-unused-parameter + CPPFLAGS += -DUSE_WASM_SIMD -msimd128 + CPPFLAGS += -DUSE_SSE42 -msse4.2 + CPPFLAGS += -march=wasm32 + # CPPFLAGS += -march=corei7 + CPPFLAGS += -s USE_PTHREADS=1 + CPPFLAGS += -s STRICT=1 + LDFLAGS += --pre-js wasm_pre.js + # LDFLAGS += --preload-file eval/nn.bin + LDFLAGS += -s MODULARIZE=1 -s EXPORT_NAME="$(EM_EXPORT_NAME)" -s ENVIRONMENT=web,worker,node + # LDFLAGS += -s PTHREAD_POOL_SIZE=32 + LDFLAGS += -s FILESYSTEM=1 -s EXIT_RUNTIME=0 -s "EXPORTED_RUNTIME_METHODS=['FS','ccall']" + LDFLAGS += -s ALLOW_MEMORY_GROWTH=1 -s INITIAL_MEMORY=$(EM_INITIAL_MEMORY_SIZE) -s MAXIMUM_MEMORY=4294967296 + LDFLAGS += -s TOTAL_STACK=67108864 + LDFLAGS += -s LLD_REPORT_UNDEFINED + # LDFLAGS += -s ALLOW_UNIMPLEMENTED_SYSCALLS + LDFLAGS += -s --closure 1 endif endif TARGETDIR = . -ifeq ($(OS),Windows_NT) - CPPFLAGS += $(WCPPFLAGS) - LDFLAGS += -static -Wl,--stack,25000000 - TARGET = $(TARGETDIR)/YaneuraOu-by-gcc.exe +ifneq (,$(findstring em++,$(COMPILER))) + TARGET = $(TARGETDIR)/yaneuraou.js else - CPPFLAGS += -D_LINUX - TARGET = $(TARGETDIR)/YaneuraOu-by-gcc + ifeq ($(OS),Windows_NT) + CPPFLAGS += $(WCPPFLAGS) + LDFLAGS += -static -Wl,--stack,25000000 + TARGET = $(TARGETDIR)/YaneuraOu-by-gcc.exe + else + CPPFLAGS += -D_LINUX + TARGET = $(TARGETDIR)/YaneuraOu-by-gcc + endif endif # リンク時最適化。 @@ -185,8 +218,11 @@ endif # wstringを使うためにこのシンボル定義が必要。 CPPFLAGS += -DUNICODE +# em++ では strip: -Wl,-s の指定はしない +ifeq (,$(findstring em++,$(COMPILER))) # stripの指示。(実行ファイルのサイズを小さく) LDFLAGS += -Wl,-s +endif # mingw64では-D_WIN64,-D_WIN32は環境に応じて自動で設定されるので指定すべきではない。 # CPPFLAGS += -D_WIN64 @@ -401,6 +437,10 @@ ifneq (,$(findstring YANEURAOU_ENGINE_NNUE,$(YANEURAOU_EDITION))) eval/nnue/features/pe9.cpp \ engine/yaneuraou-engine/yaneuraou-search.cpp + ifneq (,$(findstring em++,$(COMPILER))) + SOURCES += \ + eval/nnue/wasm_simd.cpp + endif ifeq ($(EVAL_EMBEDDING),ON) SOURCES += \ eval/nnue/embedded_nnue.cpp @@ -511,9 +551,13 @@ else ifeq ($(TARGET_CPU),GRAVITON2) # for Amazon Web Servece EC2, the Graviton2 CPU [M6g/M6gd, C6g/C6gd/C6gn, R6g/R6gd, T4g, X2gd] instances # https://github.com/aws/aws-graviton-getting-started/blob/main/c-c++.md CPPFLAGS += -DIS_64BIT -DUSE_NEON -march=armv8.2-a+fp16+rcpc+dotprod+crypto -else ifeq ($(TARGET_CPU),M1) - # for Apple M1 - CPPFLAGS += -DIS_64BIT -DUSE_NEON -march=armv8.5-a+fp16+rcpc+dotprod+crypto -mcpu=apple-m1 +else ifeq ($(TARGET_CPU),APPLEAVX2) + CPPFLAGS += -DIS_64BIT -DUSE_AVX2 -DUSE_BMI2 -target x86_64-apple-macos11 -mbmi -mbmi2 -mavx2 -mpopcnt +else ifeq ($(TARGET_CPU),APPLESSE42) + CPPFLAGS += -DIS_64BIT -DUSE_SSE42 -target x86_64-apple-macos11 +else ifeq ($(TARGET_CPU),APPLEM1) + CPPFLAGS += -DIS_64BIT -DUSE_NEON -target arm64-apple-macos11 +else ifeq ($(TARGET_CPU),WASM) else ifeq ($(TARGET_CPU),OTHER) CPPFLAGS += -DNO_SSE diff --git a/source/YaneuraOu.vcxproj b/source/YaneuraOu.vcxproj index d4167df3b..9f2c7a047 100644 --- a/source/YaneuraOu.vcxproj +++ b/source/YaneuraOu.vcxproj @@ -1,9 +1,9 @@  - - - - + + + + @@ -366,15 +366,15 @@ - + - - + + @@ -388,7 +388,7 @@ - + @@ -401,15 +401,15 @@ - + - - + + @@ -423,7 +423,7 @@ - + @@ -798,14 +798,14 @@ このプロジェクトは、このコンピューター上にない NuGet パッケージを参照しています。それらのパッケージをダウンロードするには、[NuGet パッケージの復元] を使用します。詳細については、http://go.microsoft.com/fwlink/?LinkID=322105 を参照してください。見つからないファイルは {0} です。 - - - - - - - - + + + + + + + + diff --git a/source/book/book.cpp b/source/book/book.cpp index 4a4042203..86a10a8bc 100644 --- a/source/book/book.cpp +++ b/source/book/book.cpp @@ -400,7 +400,7 @@ namespace Book writer.WriteLine("#YANEURAOU-DB2016 1.00"); vector > vectored_book; - + // 重複局面の手数違いを除去するのに用いる。 // 手数違いの重複局面はOptions["IgnoreBookPly"]==trueのときに有害であるため、plyが最小のもの以外を削除する必要がある。 // (Options["BookOnTheFly"]==true かつ Options["IgnoreBookPly"] == true のときに、手数違いのものがヒットするだとか、そういう問題と、 @@ -517,7 +517,7 @@ namespace Book // "no_book"は定跡なしという意味なので定跡の指し手が見つからなかったことにする。 if (pure_book_name == "no_book") return BookMovesPtr(); - + if (pure_book_name == kAperyBookName) { BookMovesPtr pml_entry(new BookMoves()); @@ -644,7 +644,7 @@ namespace Book // // 区間 [s,e) で解を求める。現時点での中間地点がm。 // 解とは、探しているsfen文字列が書いてある行の先頭のファイルポジションのことである。 - // + // // next_sfen()でm以降にある"sfen"で始まる行を読み込んだ時、そのあとのファイルポジションがlast_pos。 s64 s = 0, e = file_size, m , last_pos; @@ -956,9 +956,19 @@ namespace Book , "yaneura_book1.db" , "yaneura_book2.db" , "yaneura_book3.db", "yaneura_book4.db" , "user_book1.db", "user_book2.db", "user_book3.db", "book.bin" }; +#if !defined(__EMSCRIPTEN__) o["BookFile"] << Option(book_list, book_list[1]); - +#else + // WASM では no_book をデフォルトにする + o["BookFile"] << Option(book_list, book_list[0]); +#endif + +#if !defined(__EMSCRIPTEN__) o["BookDir"] << Option("book"); +#else + // WASM + o["BookDir"] << Option("."); +#endif // BookEvalDiff: 定跡の指し手で1番目の候補の指し手と、2番目以降の候補の指し手との評価値の差が、 // この範囲内であれば採用する。(1番目の候補の指し手しか選ばれて欲しくないときは0を指定する) @@ -1045,7 +1055,7 @@ namespace Book // 定跡にhitした。逆順で出力しないと将棋所だと逆順にならないという問題があるので逆順で出力する。 // → 将棋所、updateでMultiPVに対応して改良された //  ShogiGUIでの表示も問題ないようなので正順に変更する。 - + // また、it->size()!=0をチェックしておかないと指し手のない定跡が登録されていたときに困る。 // 1) やねうら標準定跡のように評価値なしの定跡DBにおいては @@ -1075,7 +1085,7 @@ namespace Book // Position::legal()を用いて合法手判定をする時、これが連続王手の千日手を弾かないが、 // 定跡で連続王手の千日手の指し手があると指してしまう。 // これは回避が難しいので、仕様であるものとする。 - // + // // "position"コマンドでも千日手局面は弾かないし、この仕様は仕方ない意味はある。 } else { @@ -1123,7 +1133,7 @@ namespace Book sync_cout << "info" #if !defined(NICONICO) << " multipv " << (i + 1) -#endif +#endif << " score cp " << it.value << " depth " << it.depth << " pv " << pv_string << " (" << fixed << std::setprecision(2) << (100 * it.move_count / double(move_count_total)) << "%" << ")" // 採択確率 diff --git a/source/engine/dlshogi-engine/YaneuraOu_dlshogi_bridge.cpp b/source/engine/dlshogi-engine/YaneuraOu_dlshogi_bridge.cpp index e5b1257bb..8120c9b0c 100644 --- a/source/engine/dlshogi-engine/YaneuraOu_dlshogi_bridge.cpp +++ b/source/engine/dlshogi-engine/YaneuraOu_dlshogi_bridge.cpp @@ -68,7 +68,7 @@ void USI::extra_option(USI::OptionsMap& o) // 引き分けの時の値 : 1000分率で // 引き分けの局面では、この値とみなす。 // root color(探索開始局面の手番)に応じて、2通り。 - + o["DrawValueBlack"] << USI::Option(500, 0, 1000); o["DrawValueWhite"] << USI::Option(500, 0, 1000); @@ -134,24 +134,24 @@ void USI::extra_option(USI::OptionsMap& o) // CPUを使っていることがあるので、default値、ちょっと少なめにしておく。 o["DNN_Batch_Size1"] << USI::Option(32, 1, 1024); #endif - o["DNN_Batch_Size2"] << USI::Option(0, 0, 65536); - o["DNN_Batch_Size3"] << USI::Option(0, 0, 65536); - o["DNN_Batch_Size4"] << USI::Option(0, 0, 65536); - o["DNN_Batch_Size5"] << USI::Option(0, 0, 65536); - o["DNN_Batch_Size6"] << USI::Option(0, 0, 65536); - o["DNN_Batch_Size7"] << USI::Option(0, 0, 65536); - o["DNN_Batch_Size8"] << USI::Option(0, 0, 65536); - o["DNN_Batch_Size9"] << USI::Option(0, 0, 65536); - o["DNN_Batch_Size10"] << USI::Option(0, 0, 65536); - o["DNN_Batch_Size11"] << USI::Option(0, 0, 65536); - o["DNN_Batch_Size12"] << USI::Option(0, 0, 65536); - o["DNN_Batch_Size13"] << USI::Option(0, 0, 65536); - o["DNN_Batch_Size14"] << USI::Option(0, 0, 65536); - o["DNN_Batch_Size15"] << USI::Option(0, 0, 65536); - o["DNN_Batch_Size16"] << USI::Option(0, 0, 65536); + o["DNN_Batch_Size2"] << USI::Option(0, 0, 1024); + o["DNN_Batch_Size3"] << USI::Option(0, 0, 1024); + o["DNN_Batch_Size4"] << USI::Option(0, 0, 1024); + o["DNN_Batch_Size5"] << USI::Option(0, 0, 1024); + o["DNN_Batch_Size6"] << USI::Option(0, 0, 1024); + o["DNN_Batch_Size7"] << USI::Option(0, 0, 1024); + o["DNN_Batch_Size8"] << USI::Option(0, 0, 1024); + o["DNN_Batch_Size9"] << USI::Option(0, 0, 1024); + o["DNN_Batch_Size10"] << USI::Option(0, 0, 1024); + o["DNN_Batch_Size11"] << USI::Option(0, 0, 1024); + o["DNN_Batch_Size12"] << USI::Option(0, 0, 1024); + o["DNN_Batch_Size13"] << USI::Option(0, 0, 1024); + o["DNN_Batch_Size14"] << USI::Option(0, 0, 1024); + o["DNN_Batch_Size15"] << USI::Option(0, 0, 1024); + o["DNN_Batch_Size16"] << USI::Option(0, 0, 1024); #if defined(ORT_MKL) - // nn_onnx_runtime.cpp の NNOnnxRuntime::load() で使用するオプション。 + // nn_onnx_runtime.cpp の NNOnnxRuntime::load() で使用するオプション。 // グラフ全体のスレッド数?(default値1)ORT_MKLでは効果が無いかもしれない。 o["InterOpNumThreads"] << USI::Option(1, 1, 65536); // ノード内の実行並列化の際のスレッド数設定(default値4、NNUE等でのThreads相当) @@ -307,7 +307,7 @@ void MainThread::search() Move move = searcher.UctSearchGenmove(&rootPos, game_root_sfen , moves_from_game_root , ponderMove); // ponder中であれば、呼び出し元で待機しなければならない。 - + // 最大depth深さに到達したときに、ここまで実行が到達するが、 // まだThreads.stopが生じていない。しかし、ponder中や、go infiniteによる探索の場合、 // USI(UCI)プロトコルでは、"stop"や"ponderhit"コマンドをGUIから送られてくるまでbest moveを出力してはならない。 diff --git a/source/eval/deep/nn_tensorrt.cpp b/source/eval/deep/nn_tensorrt.cpp index 6fcc84708..b45285feb 100644 --- a/source/eval/deep/nn_tensorrt.cpp +++ b/source/eval/deep/nn_tensorrt.cpp @@ -194,6 +194,13 @@ namespace Eval::dlshogi config->setFlag(nvinfer1::BuilderFlag::kFP16); } +#if defined(TRT_NN_FP16) + network->getInput(0)->setType(nvinfer1::DataType::kHALF); + network->getInput(1)->setType(nvinfer1::DataType::kHALF); + network->getOutput(0)->setType(nvinfer1::DataType::kHALF); + network->getOutput(1)->setType(nvinfer1::DataType::kHALF); +#endif + ASSERT_LV3(network->getNbInputs() == 2); nvinfer1::Dims inputDims[] = { network->getInput(0)->getDimensions(), network->getInput(1)->getDimensions() }; ASSERT_LV3(inputDims[0].nbDims == 4); @@ -268,6 +275,9 @@ namespace Eval::dlshogi // std::regex_replace(std::string(pciBusId), std::regex("[^A-Za-z0-9._-]"), std::string("_")) + "." + std::to_string(max_batch_size) + "." + "TRT" + std::to_string(getInferLibVersion()) + "." + +#if defined(TRT_NN_FP16) + "FP16." + +#endif "serialized"; sync_cout << "info string serialized filename = " << serialized_filename << sync_endl; diff --git a/source/eval/deep/nn_types.cpp b/source/eval/deep/nn_types.cpp index 08442872b..57ba1976b 100644 --- a/source/eval/deep/nn_types.cpp +++ b/source/eval/deep/nn_types.cpp @@ -28,6 +28,11 @@ namespace Eval::dlshogi PieceType HandPiece2PieceType[HandPieceNum ] = { PAWN , LANCE , KNIGHT , SILVER , GOLD , BISHOP , ROOK }; //int PieceType2HandPiece[PIECE_TYPE_NB] = { 0 , 1 , 2 , 3 , 4 , 6 , 7 , 5 }; +#if defined(TRT_NN_FP16) + const DType dtype_zero = __float2half(0.0f); + const DType dtype_one = __float2half(1.0f); +#endif + #if 0 // dlshogiに忠実に書かれたコード // 入力特徴量を生成する。 diff --git a/source/eval/deep/nn_types.h b/source/eval/deep/nn_types.h index 3dca4e7ca..7adc06cd5 100644 --- a/source/eval/deep/nn_types.h +++ b/source/eval/deep/nn_types.h @@ -6,6 +6,14 @@ #include "../../position.h" +#if defined(TENSOR_RT) +#define TRT_NN_FP16 +#endif + +#if defined(TRT_NN_FP16) +#include +#endif + namespace Eval::dlshogi { // === GPU関連の設定 === @@ -21,7 +29,7 @@ namespace Eval::dlshogi // 歩が先手の手駒に9枚の状況だとして、残り7枚は相手の手駒 or 盤上にあるはずだし、盤上の歩は入力特徴量として持っているので // 駒割自体は正しく計算できるはず。 // MAX_HPAWN_NUMが7だと、手駒を先手が9枚、後手が7枚持っているような状況だと、どちらが数多く持っているのかが判定できないのでまずい。 - + constexpr int MAX_HPAWN_NUM = 8; // 歩の持ち駒の上限 constexpr int MAX_HLANCE_NUM = 4; constexpr int MAX_HKNIGHT_NUM = 4; @@ -93,11 +101,30 @@ namespace Eval::dlshogi constexpr int MAX_MOVE_LABEL_NUM = MOVE_DIRECTION_NUM + HandPieceNum; // 特徴量などに使う型。 + // // 16bitが使えるのは、cuDNNのときだけだが、cuDNNの利用はdlshogiでは廃止する予定らしいので、 // ここでは32bit floatとして扱う。 +#if defined(TRT_NN_FP16) + typedef __half DType; + extern const DType dtype_zero; + extern const DType dtype_one; + inline float to_float(const DType x) { + return __half2float(x); + } + inline DType to_dtype(const float x) { + return __float2half(x); + } +#else typedef float DType; constexpr const DType dtype_zero = 0.0f; // DTypeで 0 を表現する型 constexpr const DType dtype_one = 1.0f; // DTypeで 1 を表現する型 + inline float to_float(const DType x) { + return x; + } + inline float to_dtype(const float x) { + return x; + } +#endif // NNの入力特徴量その1 // ※ dlshogiでは、features1_tという型名。 diff --git a/source/eval/nnue/evaluate_nnue.cpp b/source/eval/nnue/evaluate_nnue.cpp index 7a4d5cc89..82b00074e 100644 --- a/source/eval/nnue/evaluate_nnue.cpp +++ b/source/eval/nnue/evaluate_nnue.cpp @@ -231,14 +231,20 @@ namespace Eval { #endif { const std::string dir_name = Options["EvalDir"]; +#if !defined(__EMSCRIPTEN__) + const std::string file_name = NNUE::kFileName; +#else + // WASM + const std::string file_name = Options["EvalFile"]; +#endif const bool result = [&] { if (dir_name != "") { auto full_dir_name = Path::Combine(Directory::GetCurrentFolder(), dir_name); sync_cout << "info string EvalDirectory = " << full_dir_name << sync_endl; - const std::string file_name = Path::Combine(dir_name, NNUE::kFileName); - std::ifstream stream(file_name, std::ios::binary); - sync_cout << "info string loading eval file : " << file_name << sync_endl; + const std::string file_path = Path::Combine(dir_name, file_name); + std::ifstream stream(file_path, std::ios::binary); + sync_cout << "info string loading eval file : " << file_path << sync_endl; return NNUE::ReadParameters(stream); } @@ -266,7 +272,7 @@ namespace Eval { if (!result) { // 読み込みエラーのとき終了してくれないと困る。 - sync_cout << "Error! : failed to read " << NNUE::kFileName << sync_endl; + sync_cout << "Error! : failed to read " << file_name << sync_endl; Tools::exit(); } } diff --git a/source/eval/nnue/layers/affine_transform.h b/source/eval/nnue/layers/affine_transform.h index 70a43ddeb..537123388 100644 --- a/source/eval/nnue/layers/affine_transform.h +++ b/source/eval/nnue/layers/affine_transform.h @@ -82,6 +82,21 @@ class AffineTransform { const OutputType* Propagate(const TransformedFeatureType* transformed_features, char* buffer) const { const auto input = previous_layer_.Propagate(transformed_features, buffer + kSelfBufferSize); +#if defined(USE_WASM_SIMD) + { + // Simplify variable names (y = Ax + b) + constexpr int n = kInputDimensions; + constexpr int m = kOutputDimensions; + constexpr int n_stride = kPaddedInputDimensions; + auto A = *reinterpret_cast(weights_); + auto x = *reinterpret_cast(input); + auto b = *reinterpret_cast(biases_); + auto y = *reinterpret_cast(buffer); + emscripten_wasm_simd::affine(A, x, b, y); + return y; + } +#endif + #if defined(USE_AVX512) [[maybe_unused]] const __m512i kOnes512 = _mm512_set1_epi16(1); diff --git a/source/eval/nnue/nnue_common.h b/source/eval/nnue/nnue_common.h index 278f68f4a..29199a068 100644 --- a/source/eval/nnue/nnue_common.h +++ b/source/eval/nnue/nnue_common.h @@ -10,6 +10,10 @@ #if defined(EVAL_NNUE) +#if defined(USE_WASM_SIMD) +#include "./wasm_simd.h" +#endif + // HACK: Use _mm256_loadu_si256() instead of _mm256_load_si256. Otherwise a binary // compiled with older g++ crashes because the output memory is not aligned // even though alignas is specified. @@ -67,6 +71,8 @@ namespace Eval::NNUE { #elif defined(USE_NEON) constexpr std::size_t kSimdWidth = 16; + #elif defined(USE_WASM_SIMD) + constexpr std::size_t kSimdWidth = 16; #endif constexpr std::size_t kMaxSimdWidth = 32; diff --git a/source/eval/nnue/nnue_feature_transformer.h b/source/eval/nnue/nnue_feature_transformer.h index 8b97cf857..8828c8ad8 100644 --- a/source/eval/nnue/nnue_feature_transformer.h +++ b/source/eval/nnue/nnue_feature_transformer.h @@ -260,7 +260,7 @@ class FeatureTransformer { for (IndexType i = 1; i < kRefreshTriggers.size(); ++i) { sum += accumulation[perspectives[p]][i][j]; } - output[offset + j] = static_cast(std::max(0, std::min(127, sum))); + output[offset + j] = static_cast(std::clamp(sum, 0, 127)); } #endif } diff --git a/source/eval/nnue/wasm_simd.cpp b/source/eval/nnue/wasm_simd.cpp new file mode 100644 index 000000000..ae15784af --- /dev/null +++ b/source/eval/nnue/wasm_simd.cpp @@ -0,0 +1,95 @@ +#include "wasm_simd.h" +#if defined(USE_WASM_SIMD) +#include + +namespace emscripten_wasm_simd { + +template +void affine(const int8_t A[m][n_stride], const uint8_t x[n], const int32_t b[m], int32_t y[m]) { + // + // Dot product of two SIMD vectors + // + [[maybe_unused]] auto dot_i8x16 = [](__i8x16 a, __i8x16 b) -> __i32x4 { + __i16x8 a_lo = wasm_i16x8_extend_low_i8x16(a); + __i16x8 a_hi = wasm_i16x8_extend_high_i8x16(a); + __i16x8 b_lo = wasm_i16x8_extend_low_i8x16(b); + __i16x8 b_hi = wasm_i16x8_extend_high_i8x16(b); + return wasm_i32x4_add(wasm_i32x4_dot_i16x8(a_lo, b_lo), wasm_i32x4_dot_i16x8(a_hi, b_hi)); + }; + + // (NOT USED) + [[maybe_unused]] auto dot_i16x8 = [](__i16x8 a, __i16x8 b) -> __i32x4 { + __i16x8 c = wasm_i16x8_mul(a, b); + return wasm_i32x4_add(wasm_i32x4_extend_low_i16x8(c), wasm_i32x4_extend_high_i16x8(c)); + }; + + // + // Horizontal sum + // + [[maybe_unused]] auto hadd = [&](__i32x4 x0, __i32x4 x1) -> __i32x4 { + return wasm_i32x4_add(wasm_i32x4_shuffle(x0, x1, 0, 2, 4, 6), wasm_i32x4_shuffle(x0, x1, 1, 3, 5, 7)); + }; + + // (NOT USED) + [[maybe_unused]] auto haddx4 = [&](__i32x4 x0, __i32x4 x1, __i32x4 x2, __i32x4 x3) -> __i32x4 { + return hadd(hadd(x0, x1), hadd(x2, x3)); + }; + + // + // Dot product of two vectors + // + [[maybe_unused]] auto dot = [&](const int8_t* a, const uint8_t* x, const int32_t* b, int32_t* out) { + __i32x4 z = wasm_i32x4_splat(0); + for (int j = 0; j < n; j += 16) { + z = wasm_i32x4_add(z, dot_i8x16(wasm_v128_load(&a[j]), wasm_v128_load(&x[j]))); + } + out[0] = b[0] + z[0] + z[1] + z[2] + z[3]; + }; + + // + // Four dot products (exploting horizontal sum) + // + [[maybe_unused]] auto dot4 = [&](const int8_t* a, const uint8_t* x, const int32_t* b, int32_t* out) { + __i32x4 z0 = wasm_i32x4_splat(0); + __i32x4 z1 = wasm_i32x4_splat(0); + __i32x4 z2 = wasm_i32x4_splat(0); + __i32x4 z3 = wasm_i32x4_splat(0); + for (int j = 0; j < n; j += 16) { + __i8x16 xv = wasm_v128_load(&x[j]); + z0 = wasm_i32x4_add(z0, dot_i8x16(wasm_v128_load(&a[j + 0 * n_stride]), xv)); + z1 = wasm_i32x4_add(z1, dot_i8x16(wasm_v128_load(&a[j + 1 * n_stride]), xv)); + z2 = wasm_i32x4_add(z2, dot_i8x16(wasm_v128_load(&a[j + 2 * n_stride]), xv)); + z3 = wasm_i32x4_add(z3, dot_i8x16(wasm_v128_load(&a[j + 3 * n_stride]), xv)); + } + __i32x4 z = wasm_i32x4_add(wasm_v128_load(&b[0]), haddx4(z0, z1, z2, z3)); + wasm_v128_store(&out[0], z); + }; + + // + // Affine + // + + // 2048x8 + if constexpr (n % 16 == 0 && m % 4 == 0) { + for (int i = 0; i < m; i += 4) { + dot4(&A[i][0], &x[0], &b[i], &y[i]); + } + + // 8x32, 32x1 (it doesn't worth optimizing such small kernels) + } else { + for (int i = 0; i < m; i++) { + y[i] = b[i]; + for (int j = 0; j < n; j++) { + y[i] += A[i][j] * x[j]; + } + } + } +} + +// Explicit instantiation +template void affine< 512, 32, 512>(const int8_t A[32][ 512], const uint8_t x[ 512], const int32_t b[32], int32_t y[32]); +template void affine< 32, 32, 32>(const int8_t A[32][ 32], const uint8_t x[ 32], const int32_t b[32], int32_t y[32]); +template void affine< 32, 1, 32>(const int8_t A[ 1][ 32], const uint8_t x[ 32], const int32_t b[ 1], int32_t y[ 1]); + +} // namespace emscripten_wasm_simd +#endif diff --git a/source/eval/nnue/wasm_simd.h b/source/eval/nnue/wasm_simd.h new file mode 100644 index 000000000..ca8a471d1 --- /dev/null +++ b/source/eval/nnue/wasm_simd.h @@ -0,0 +1,13 @@ +#include "../../config.h" + +#if defined(USE_WASM_SIMD) +#include +#include + +namespace emscripten_wasm_simd { + +template +void affine(const int8_t A[m][n_stride], const uint8_t x[n], const int32_t b[m], int32_t y[m]); + +} // namespace emscripten_wasm_simd +#endif diff --git a/source/extra/bitop.h b/source/extra/bitop.h index 5fc8dba33..bac47fa2a 100644 --- a/source/extra/bitop.h +++ b/source/extra/bitop.h @@ -10,6 +10,7 @@ #if defined(_MSC_VER) #include // _byteswap_uint64 +#include // __popcnt, __popcnt64 #endif // ターゲット環境でSSE,AVX,AVX2が搭載されていない場合はこれらの命令をsoftware emulationにより実行する。 @@ -112,8 +113,20 @@ inline uint64_t PEXT64(uint64_t a, uint64_t b) { return pext(a, b); } // POPCNT(SSE4.2の命令) // ---------------------------- -#if defined (USE_SSE42) +#if defined(_MSC_VER) + +inline s32 POPCNT32(u32 a) { return (s32)__popcnt(a); } +inline s32 POPCNT64(u64 a) { return (s32)__popcnt64(a); } + +#elif defined(__GNUC__) + +inline s32 POPCNT32(u32 a) { return __builtin_popcount(a); } +inline s32 POPCNT64(u64 a) { return __builtin_popcountll(a); } + +#elif defined (USE_SSE42) +// SSE4.2有効でもPOPCNTが無効かもしれない環境のため、実装順位は下げる +// 例: MacOS Apple M1 向けソフトウェアエミュレータ、AMD Bulldozer Family 15h core based CPU など #if defined (IS_64BIT) #define POPCNT32(a) _mm_popcnt_u32(a) #define POPCNT64(a) _mm_popcnt_u64(a) @@ -170,13 +183,40 @@ FORCE_INLINE int MSB32(uint32_t v) { ASSERT_LV3(v != 0); unsigned long index; _B FORCE_INLINE int MSB64(uint64_t v) { ASSERT_LV3(v != 0); return uint32_t(v >> 32) ? 32 + MSB32(uint32_t(v >> 32)) : MSB32(uint32_t(v)); } #endif -#elif defined(__GNUC__) && ( defined(__i386__) || defined(__x86_64__) || defined(__ANDROID__) || defined(__ARM_ARCH) ) +#elif defined(__GNUC__) -FORCE_INLINE int LSB32(const u32 v) { ASSERT_LV3(v != 0); return __builtin_ctzll(v); } +FORCE_INLINE int LSB32(const u32 v) { ASSERT_LV3(v != 0); return __builtin_ctz(v); } FORCE_INLINE int LSB64(const u64 v) { ASSERT_LV3(v != 0); return __builtin_ctzll(v); } -FORCE_INLINE int MSB32(const u32 v) { ASSERT_LV3(v != 0); return 63 ^ __builtin_clzll(v); } +FORCE_INLINE int MSB32(const u32 v) { ASSERT_LV3(v != 0); return 31 ^ __builtin_clz(v); } FORCE_INLINE int MSB64(const u64 v) { ASSERT_LV3(v != 0); return 63 ^ __builtin_clzll(v); } +#else + +// software emulationによるbitscan forward(やや遅い) +FORCE_INLINE s32 LSB32(u32 v) { ASSERT_LV3(v != 0); return POPCNT32((v & (-v)) - 1); } +FORCE_INLINE s32 LSB64(u64 v) { ASSERT_LV3(v != 0); return POPCNT64((v & (-v)) - 1); } + +// software emulationによるbitscan reverse(やや遅い) +FORCE_INLINE s32 MSB32(u32 v) { + ASSERT_LV3(v != 0); + v = v | (v >> 1); + v = v | (v >> 2); + v = v | (v >> 4); + v = v | (v >> 8); + v = v | (v >> 16); + return POPCNT32(v); +} +FORCE_INLINE s32 MSB64(u64 v) { + ASSERT_LV3(v != 0); + v = v | (v >> 1); + v = v | (v >> 2); + v = v | (v >> 4); + v = v | (v >> 8); + v = v | (v >> 16); + v = v | (v >> 32); + return POPCNT64(v); +} + #endif // ---------------------------- diff --git a/source/main.cpp b/source/main.cpp index 78ccc5f12..1168e765b 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -43,6 +43,7 @@ int main(int argc, char* argv[]) //Search::clear(); Eval::init(); +#if !defined(__EMSCRIPTEN__) // USIコマンドの応答部 USI::loop(argc, argv); @@ -50,6 +51,10 @@ int main(int argc, char* argv[]) // 生成して、待機させていたスレッドの停止 Threads.set(0); +#else + // yaneuraOu.wasm + // ここでループしてしまうと、ブラウザのメインスレッドがブロックされてしまうため、コメントアウト +#endif return 0; } diff --git a/source/misc.cpp b/source/misc.cpp index 5a78a0b8f..381e4acc0 100644 --- a/source/misc.cpp +++ b/source/misc.cpp @@ -467,6 +467,8 @@ void* std_aligned_alloc(size_t alignment, size_t size) { return posix_memalign(&mem, alignment, size) ? nullptr : mem; #elif defined(_WIN32) return _mm_malloc(size, alignment); +#elif defined(__EMSCRIPTEN__) + return aligned_alloc(alignment, size); #else return std::aligned_alloc(alignment, size); #endif diff --git a/source/packages.config b/source/packages.config index 97e9aa290..21884161f 100644 --- a/source/packages.config +++ b/source/packages.config @@ -1,9 +1,9 @@  - - - - + + + + - \ No newline at end of file + diff --git a/source/props/YaneuraOuEdition-Deep-ORT-TRT.props b/source/props/YaneuraOuEdition-Deep-ORT-TRT.props index 4a985c612..6a8bb91e1 100644 --- a/source/props/YaneuraOuEdition-Deep-ORT-TRT.props +++ b/source/props/YaneuraOuEdition-Deep-ORT-TRT.props @@ -29,59 +29,35 @@ - + Always false - + Always false - + Always false - + Always false - + Always false - + Always false - + Always false - - Always - false - - - Always - false - - - Always - false - - - Always - false - - - Always - false - - - Always - false - - + Always false diff --git a/source/props/YaneuraOuEdition-Deep-TensorRT.props b/source/props/YaneuraOuEdition-Deep-TensorRT.props index f58f31af2..7602a8b3a 100644 --- a/source/props/YaneuraOuEdition-Deep-TensorRT.props +++ b/source/props/YaneuraOuEdition-Deep-TensorRT.props @@ -9,8 +9,8 @@ $(OutBaseDir)$(YaneuraOuDir)\ $(ProjectName)-$(YaneuraOuTarget) <_PropertySheetDisplayName>YaneuraOuEdition-Deep-TensorRT - $(VC_IncludePath);$(WindowsSDK_IncludePath);C:\TensorRT-8.2.1.8\include;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.5\include - $(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);C:\TensorRT-8.2.1.8\lib;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.5\lib\x64 + $(VC_IncludePath);$(WindowsSDK_IncludePath);C:\TensorRT-8.2.4.2\include;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.6\include + $(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);C:\TensorRT-8.2.4.2\lib;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.6\lib\x64 @@ -29,55 +29,35 @@ - + Always false - + Always false - + Always false - + Always false - + Always false - + Always false - + Always false - - Always - false - - - Always - false - - - Always - false - - - Always - false - - - Always - false - - + Always false diff --git a/source/thread.cpp b/source/thread.cpp index e33d6f5ca..d8f7426cc 100644 --- a/source/thread.cpp +++ b/source/thread.cpp @@ -7,8 +7,22 @@ ThreadPool Threads; // Global object Thread::Thread(size_t n) : idx(n) , stdThread(&Thread::idle_loop, this) { +#if !defined(__EMSCRIPTEN__) // スレッドはsearching == trueで開始するので、このままworkerのほう待機状態にさせておく wait_for_search_finished(); +#else + // yaneuraou.wasm + // wait_for_search_finished すると、ブラウザのメインスレッドをブロックしデッドロックが発生するため、コメントアウト。 + // + // 新しいスレッドが cv を設定するのを待ってから、ブラウザに処理をパスしたいが、 + // 新しいスレッド用のworkerを作成するためには、いったんブラウザに処理をパスする必要がある。 + // + // https://bugzilla.mozilla.org/show_bug.cgi?id=1049079 + // + // threadStarted という変数を設けて全てのスレッドが開始するまでリトライするようにする + // + // 参考:https://github.com/niklasf/stockfish.wasm/blob/a022fa1405458d1bc1ba22fe813bace961859102/src/thread.cpp#L38 +#endif } // std::threadの終了を待つ @@ -92,6 +106,10 @@ void Thread::idle_loop() { { std::unique_lock lk(mutex); searching = false; +#if defined(__EMSCRIPTEN__) + // yaneuraOu.wasm + threadStarted = true; +#endif cv.notify_one(); // 他のスレッドがこのスレッドを待機待ちしてるならそれを起こす cv.wait(lk, [&] { return searching; }); @@ -108,18 +126,37 @@ void Thread::idle_loop() { // スレッド数を変更する。 void ThreadPool::set(size_t requested) { +#if defined(__EMSCRIPTEN__) + // yaneuraou.wasm + // ブラウザのメインスレッドをブロックしないようstockfish.wasmと同様の実装に修正 + if (size() == requested) + return; +#endif + if (size() > 0) { // いったんすべてのスレッドを解体(NUMA対策) main()->wait_for_search_finished(); +#if !defined(__EMSCRIPTEN__) while (size() > 0) delete back(), pop_back(); +#else + // yaneuraou.wasm + while (size() > requested) + delete back(), pop_back(); +#endif } if (requested > 0) { // 要求された数だけのスレッドを生成 +#if !defined(__EMSCRIPTEN__) push_back(new MainThread(0)); while (size() < requested) push_back(new Thread(size())); +#else + // yaneuraou.wasm + while (size() < requested) + push_back(size() ? new Thread(size()) : new MainThread(0)); +#endif clear(); // Reallocate the hash with the new threadpool size @@ -169,7 +206,7 @@ void ThreadPool::start_thinking(const Position& pos, StateListPtr& states , // 初期局面では合法手すべてを生成してそれをrootMovesに設定しておいてやる。 // このとき、歩の不成などの指し手は除く。(そのほうが勝率が上がるので) // また、goコマンドでsearchmovesが指定されているなら、そこに含まれていないものは除く。 - + // あと宣言勝ちできるなら、その指し手を先頭に入れておいてやる。 // (ただし、トライルールのときはMOVE_WINではないので、トライする指し手はsearchmovesに含まれていなければ // 指しては駄目な手なのでrootMovesに追加しない。) @@ -212,11 +249,11 @@ void ThreadPool::start_thinking(const Position& pos, StateListPtr& states , // be deduced from a fen string, so set() clears them and they are set from // setupStates->back() later. The rootState is per thread, earlier states are shared // since they are read-only. - + // Position::set()によってst->previosがクリアされるので事前にコピーして保存する。 // これは、rootStateの役割。これはスレッドごとに持っている。 // cf. Fix incorrect StateInfo : https://github.com/official-stockfish/Stockfish/commit/232c50fed0b80a0f39322a925575f760648ae0a5 - + auto sfen = pos.sfen(); for (Thread* th : *this) { @@ -230,7 +267,7 @@ void ThreadPool::start_thinking(const Position& pos, StateListPtr& states , // 以上の初期化、探索スレッド側でやるべきだと思うが、しかしth->nodesなどはmain threadが探索ノード数の // 出力のために積算するので、main threadが積算する時にはすでに他のスレッドのth->nodesがゼロ初期化されている状態でないと // おかしい値になってしまう。 - // + // // そこで、main threadが開始する時点では、すべてのスレッドのスレッド初期化が完了していることを保証しなければならない。 // ゆえにここに書くしかないのである。 diff --git a/source/thread.h b/source/thread.h index 846067900..7cf24d148 100644 --- a/source/thread.h +++ b/source/thread.h @@ -123,11 +123,16 @@ class Thread // rootDepth : 反復深化の深さ // Lazy SMPなのでスレッドごとにこの変数を保有している。 - // + // // completedDepth : このスレッドに関して、終了した反復深化の深さ // Depth rootDepth, completedDepth; +#if defined(__EMSCRIPTEN__) + // yaneuraou.wasm + std::atomic_bool threadStarted; +#endif + // aspiration searchのrootでの beta - alpha Value rootDelta; @@ -168,7 +173,7 @@ class Thread #endif }; - + // 探索時のmainスレッド(これがmasterであり、これ以外はslaveとみなす) struct MainThread: public Thread @@ -284,7 +289,7 @@ struct ThreadPool: public std::vector // main thread以外の探索スレッドがすべて終了しているか。 // すべて終了していればtrueが返る。 bool search_finished() const; - + private: // 現局面までのStateInfoのlist diff --git a/source/tt.cpp b/source/tt.cpp index 923fb4fe4..a1b796b46 100644 --- a/source/tt.cpp +++ b/source/tt.cpp @@ -133,11 +133,14 @@ void TranspositionTable::clear() auto size = clusterCount * sizeof(Cluster); -#if !defined(EVAL_LEARN) +#if !defined(EVAL_LEARN) && !defined(__EMSCRIPTEN__) // 進捗を表示しながら並列化してゼロクリア // Stockfishのここにあったコードは、独自の置換表を実装した時にも使いたいため、tt.cppに移動させた。 Tools::memclear("USI_Hash" , table, size); #else + // yaneuraou.wasm + // pthread_joinによってブラウザのメインスレッドがブロックされるため、単一スレッドでメモリをクリアする処理に変更 + // LEARN版のときは、 // 単一スレッドでメモリをクリアする。(他のスレッドは仕事をしているので..) // 教師生成を行う時は、対局の最初にスレッドごとのTTに対して、 @@ -270,7 +273,7 @@ int TranspositionTable::hashfull() const // Stockfish11では、1000 Cluster(3000 TTEntry)についてサンプリングするように変更されたが、 // 計測時間がもったいないので、古いコードのままにしておく。 - + int cnt = 0; for (int i = 0; i < 1000 / ClusterSize; ++i) for (int j = 0; j < ClusterSize; ++j) @@ -297,7 +300,7 @@ void TranspositionTable::init_tt_per_thread() // 1スレッドあたりのクラスター数(端数切捨て) // clusterCountは2の倍数でないと駄目なので、端数を切り捨てるためにLSBを0にする。 size_t clusterCountPerThread = (clusterCount / thread_size) & ~(size_t)1; - + ASSERT_LV3((clusterCountPerThread & 1) == 0); // これを、自分が確保したglobalな置換表用メモリから切り分けて割当てる。 diff --git a/source/usi.cpp b/source/usi.cpp index b086f55b9..239a62fa8 100644 --- a/source/usi.cpp +++ b/source/usi.cpp @@ -7,6 +7,11 @@ #include "misc.h" #include "testcmd/unit_test.h" +#if defined(__EMSCRIPTEN__) +// yaneuraou.wasm +#include +#endif + #include #include @@ -145,8 +150,15 @@ namespace USI std::string pv(const Position& pos, Depth depth, Value alpha, Value beta) { std::stringstream ss; - TimePoint elapsed = Time.elapsed() + 1; + TimePoint elapsed = Time.elapsed() + 1; +#if defined(__EMSCRIPTEN__) + // yaneuraou.wasm + // Time.elapsed()が-1を返すことがある + // https://github.com/niklasf/stockfish.wasm/issues/5 + // https://github.com/niklasf/stockfish.wasm/commit/4f591186650ab9729705dc01dec1b2d099cd5e29 + elapsed = std::max(elapsed, TimePoint(1)); +#endif const auto& rootMoves = pos.this_thread()->rootMoves; size_t pvIdx = pos.this_thread()->pvIdx; size_t multiPV = std::min((size_t)Options["MultiPV"], rootMoves.size()); @@ -184,7 +196,7 @@ namespace USI << " seldepth " << rootMoves[i].selDepth #if defined(USE_PIECE_VALUE) << " score " << USI::value(v) -#endif +#endif ; // これが現在探索中の指し手であるなら、それがlowerboundかupperboundかは表示させる @@ -319,6 +331,9 @@ void is_ready(bool skipCorruptCheck) USI::read_engine_options(Path::Combine(Options["EvalDir"], "eval_options.txt")); + // yaneuraou.wasm + // ブラウザのメインスレッドをブロックしないよう、Keep Alive処理をコメントアウト +#if !defined(__EMSCRIPTEN__) // --- Keep Alive的な処理 --- // "isready"を受け取ったあと、"readyok"を返すまで5秒ごとに改行を送るように修正する。(keep alive的な処理) @@ -351,7 +366,7 @@ void is_ready(bool skipCorruptCheck) if (++count >= 50 /* 5秒 */) { count = 0; - sync_cout << sync_endl; // 改行を送信する。 + sync_cout << sync_endl; // 改行を送信する。 // 定跡の読み込み部などで"info string.."で途中経過を出力する場合、 // sync_cout ~ sync_endlを用いて送信しないと、この改行を送るタイミングとかち合うと @@ -366,6 +381,7 @@ void is_ready(bool skipCorruptCheck) Tools::sleep(100); // --- Keep Alive的な処理ここまで --- +#endif // スレッドを先に生成しないとUSI_Hashで確保したメモリクリアの並列化が行われなくて困る。 @@ -574,6 +590,7 @@ void go_cmd(const Position& pos, istringstream& is , StateListPtr& states , bool bool ponderMode = false; auto main_thread = Threads.main(); + if (!states) { // 前回から"position"コマンドを処理せずに再度goが呼び出された。 @@ -608,7 +625,7 @@ void go_cmd(const Position& pos, istringstream& is , StateListPtr& states , bool // エンジンオプションによる探索制限(0なら無制限) // このあと、depthもしくはnodesが指定されていたら、その値で上書きされる。(この値は無視される) - + limits.depth = Options.count("DepthLimit") ? (int)Options["DepthLimit"] : 0; limits.nodes = Options.count("NodesLimit") ? (u64)Options["NodesLimit"] : 0; @@ -797,22 +814,11 @@ void search_cmd(Position& pos, istringstream& is) // -------------------- // USI応答部本体 -void USI::loop(int argc, char* argv[]) +void usi_cmdexec(Position& pos, StateListPtr& states, string& cmd) { - // 探索開始局面(root)を格納するPositionクラス - // "position"コマンドで設定された局面が格納されている。 - Position pos; - - string cmd, token; - - // 局面を遡るためのStateInfoのlist。 - StateListPtr states(new StateList(1)); - - std_input.parse_args(argc,argv); + string token; - do { - cmd = std_input.input(); istringstream is(cmd); token.clear(); // getlineが空を返したときのためのクリア @@ -899,10 +905,10 @@ void USI::loop(int argc, char* argv[]) // そもそもで言うと、"usinewgame"に対してはエンジン側は何ら応答を返さないので、 // GUI側は、エンジン側が処理中なのかどうかが判断できない。 // なのでここで長い時間のかかる処理はすべきではないと思うのだが。 - else if (token == "usinewgame") continue; + else if (token == "usinewgame") return; // 思考エンジンの準備が出来たかの確認 - else if (token == "isready") is_ready_cmd(pos,states); + else if (token == "isready") is_ready_cmd(pos, states); // 以下、デバッグのためのカスタムコマンド(非USIコマンド) // 探索中には使わないようにすべし。 @@ -992,7 +998,7 @@ void USI::loop(int argc, char* argv[]) // この局面での1手詰め判定 else if (token == "mate1") cout << pos.mate1ply() << endl; #endif - + #if defined (ENABLE_TEST_CMD) // テストコマンド else if (token == "test") Test::test_cmd(pos, is); @@ -1051,7 +1057,31 @@ void USI::loop(int argc, char* argv[]) OPTION_FOUND:; } } + } +} + +// USI応答部ループ +void USI::loop(int argc, char* argv[]) +{ + // 探索開始局面(root)を格納するPositionクラス + // "position"コマンドで設定された局面が格納されている。 + Position pos; + + string cmd, token; + + // 局面を遡るためのStateInfoのlist。 + StateListPtr states(new StateList(1)); + std_input.parse_args(argc,argv); + + do + { + cmd = std_input.input(); + usi_cmdexec(pos, states, cmd); + + // quit検知 + istringstream is(cmd); + is >> skipws >> token; } while (token != "quit"); // quitが来た時点ではまだ探索中かも知れないのでmain threadの停止を待つ。 @@ -1267,7 +1297,7 @@ void USI::UnitTest(Test::UnitTester& tester) Move m = USI::to_move(pos,token); if (m == MOVE_NONE) fail = true; - + pos.do_move(m, si[pos.game_ply()]); } @@ -1277,3 +1307,27 @@ void USI::UnitTest(Test::UnitTester& tester) } } + +#if defined(__EMSCRIPTEN__) +// -------------------- +// EMSCRIPTEN support +// -------------------- +static StateListPtr states(new StateList(1)); + +// USI応答部 emscriptenインターフェース +EMSCRIPTEN_KEEPALIVE extern "C" int usi_command(const char *c_cmd) { + std::string cmd(c_cmd); + + static Position pos; + string token; + + for (Thread* th : Threads) { + if (!th->threadStarted) + return 1; + } + + usi_cmdexec(pos, states, cmd); + + return 0; +} +#endif diff --git a/source/usi_option.cpp b/source/usi_option.cpp index 70a8a85ba..cdc3e8ad2 100644 --- a/source/usi_option.cpp +++ b/source/usi_option.cpp @@ -25,11 +25,24 @@ namespace USI { // 前回のOptions["EvalDir"] std::string last_eval_dir; +#if defined(__EMSCRIPTEN__) && defined(EVAL_NNUE) + // WASM NNUE + // 前回のOptions["EvalFile"] + std::string last_eval_file; +#endif + // optionのdefault値を設定する。 void init(OptionsMap& o) { +#if !defined(__EMSCRIPTEN__) // Hash上限。32bitモードなら2GB、64bitモードなら33TB constexpr int MaxHashMB = Is64Bit ? 33554432 : 2048; +#else + // yaneuraou.wasm + // メモリの調整 + // stockfish.wasmの数値を基本的に使用している + constexpr int MaxHashMB = 1024; +#endif // 並列探索するときのスレッド数 // CPUの搭載コア数をデフォルトとすべきかも知れないが余計なお世話のような気もするのでしていない。 @@ -43,7 +56,14 @@ namespace USI { // そもそもで言うとsetoptionに対してそんなに時間のかかることをするとGUI側がtimeoutになる懸念もある。 // Stockfishもこうすべきだと思う。 +#if !defined(__EMSCRIPTEN__) o["Threads"] << Option(4, 1, 512, [](const Option& o) { /* Threads.set(o); */ }); +#else + // yaneuraou.wasm + // スレッド数などの調整 + // stockfish.wasmの数値を基本的に使用している + o["Threads"] << Option(1, 1, 32, [](const Option& o) { /* Threads.set(o); */ }); +#endif #endif #if !defined(TANUKI_MATE_ENGINE) && !defined(YANEURAOU_MATE_ENGINE) @@ -108,8 +128,11 @@ namespace USI { // 評価関数フォルダ。これを変更したとき、評価関数を次のisreadyタイミングで読み直す必要がある。 #if defined(EVAL_EMBEDDING) const char* default_eval_dir = ""; -#else +#elif !defined(__EMSCRIPTEN__) const char* default_eval_dir = "eval"; +#else + // WASM + const char* default_eval_dir = "."; #endif last_eval_dir = default_eval_dir; o["EvalDir"] << Option(default_eval_dir, [](const USI::Option& o) { @@ -120,11 +143,24 @@ namespace USI { load_eval_finished = false; } }); +#if defined(__EMSCRIPTEN__) && defined(EVAL_NNUE) + // WASM NNUE + const char* default_eval_file = "nn.bin"; + last_eval_file = default_eval_file; + o["EvalFile"] << Option(default_eval_file, [](const USI::Option& o) { + if (last_eval_file != string(o)) + { + // 評価関数ファイル名の変更に際して、評価関数ファイルの読み込みフラグをクリアする。 + last_eval_file = string(o); + load_eval_finished = false; + } + }); +#endif #else // TANUKI_MATE_ENGINEのとき - o["USI_Hash"] << Option(4096, 1, MaxHashMB); + o["USI_Hash"] << Option(std::min(4096, MaxHashMB), 1, MaxHashMB); #endif // !defined(TANUKI_MATE_ENGINE) && !defined(YANEURAOU_MATE_ENGINE) diff --git a/source/wasm_pre.js b/source/wasm_pre.js new file mode 100644 index 000000000..b10378d10 --- /dev/null +++ b/source/wasm_pre.js @@ -0,0 +1,62 @@ +(function () { + // Message listeners + + var quit = false; + var listeners = []; + + Module["print"] = function (line) { + if (listeners.length === 0) console.log(line); + else + setTimeout(function () { + for (var i = 0; i < listeners.length; i++) listeners[i](line); + }); + }; + + Module["addMessageListener"] = function (listener) { + listeners.push(listener); + }; + + Module["removeMessageListener"] = function (listener) { + var idx = listeners.indexOf(listener); + if (idx >= 0) listeners.splice(idx, 1); + }; + + Module["terminate"] = function () { + quit = true; + PThread.terminateAllThreads(); + }; + + // Command queue + + var queue = []; + var backoff = 1; + + function poll() { + var command = queue.shift(); + if (quit || command === undefined) return; + + if (command === "quit") return Module["terminate"](); + + var tryLater = Module["ccall"]( + "usi_command", + "number", + ["string"], + [command] + ); + if (tryLater) queue.unshift(command); + backoff = tryLater ? backoff * 2 : 1; + setTimeout(poll, backoff); + } + + Module["postMessage"] = function (command) { + queue.push(command); + }; + + Module["postRun"] = function () { + Module["postMessage"] = function (command) { + queue.push(command); + if (queue.length === 1) poll(); + }; + poll(); + }; +})();