mirror of
https://github.com/official-stockfish/Stockfish.git
synced 2026-07-22 20:57:10 +00:00
Lichess maintains some patches on top of SF dev to get it working with Emscripten. This PR moves some of these patches into SF and adds WASM to CI. It also adds a few changes in places where the x86 intrinsics don't cleanly map onto WebAssembly SIMD instructions; otherwise, we use Emscripten's x86 compatibility layer and take SSE4.1 code paths.
Summary of the compatibility changes:
- Define `wasm32` and `wasm32-relaxed-simd` targets.
- We don't support wasm without SIMD; it'd be a waste of time.
- Add option to disable TBs
- This is required because `tbprobe.cpp` pulls in `mmap`. This option can be used on any target, of course, but it's only enabled by default for wasm.
- Add compilation job + test to CI
And the changes for performance:
- Disable atomics for shared history on wasm
- Atomics are always `seq_cst` there, which can be quite slow (even on the x86, stores are locked `xchg [mem], reg`)
- Add SSE code path to `get_changed_pieces`, modeled after the AVX2 path
- `_mm_mulhi_epi16` has a complicated emulation sequence, so for the pairwise multiplication, use an approach similar to the NEON impl.
- __int128 is gets lowered to runtime functions on wasm, so use the fallback impl for `mul_hi64`
- V8 does a poor job with the NNZ finding, so use a slightly different sequence there
- Add relaxed simd support for `m128_dpbusd`.
Some local perf figures (single-threaded speedtest):
```
wasm
Nodes/second : 902523
sse4.1
Nodes/second : 1155380
avx512icl
Nodes/second : 1676184
```
Further avenues to explore:
- Optimize for performance under V8's experimental AVX revectorizer (Currently it's about +10% in my testing, but could definittely be more)
- Branch hinting. For example, run bench while collecting branch frequency info, then inject it late in the WASM compilation pipeline. I tried this locally and it didn't help much, but maybe I'm missing something.
- PGO. Gives +1.5% NPS locally, but hard to integrate with WASM compilation wrokflows
closes https://github.com/official-stockfish/Stockfish/pull/6875
No functional change
190 lines
6.7 KiB
YAML
190 lines
6.7 KiB
YAML
name: Stockfish
|
|
on:
|
|
push:
|
|
tags:
|
|
- "*"
|
|
branches:
|
|
- master
|
|
- tools
|
|
- github_ci
|
|
pull_request:
|
|
branches:
|
|
- master
|
|
- tools
|
|
|
|
concurrency:
|
|
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
Prerelease:
|
|
name: Prerelease
|
|
if: github.repository == 'official-stockfish/Stockfish' && (github.ref == 'refs/heads/master' || (startsWith(github.ref_name, 'sf_') && github.ref_type == 'tag'))
|
|
runs-on: ubuntu-latest
|
|
needs: [Matrix, ARMCompilation, UniversalCompilation]
|
|
permissions:
|
|
contents: write # For deleting/creating a prerelease
|
|
steps:
|
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
with:
|
|
persist-credentials: false
|
|
fetch-depth: 0
|
|
|
|
# returns null if no pre-release exists
|
|
- name: Get Commit SHA of Latest Pre-release
|
|
run: |
|
|
# Install required packages
|
|
sudo apt-get update
|
|
sudo apt-get install -y curl jq
|
|
|
|
echo "COMMIT_SHA_TAG=$(jq -r 'map(select(.prerelease)) | first | .tag_name' <<< $(curl -s https://api.github.com/repos/${{ github.repository_owner }}/Stockfish/releases))" >> $GITHUB_ENV
|
|
|
|
# delete old previous pre-release and tag
|
|
- run: gh release delete ${{ env.COMMIT_SHA_TAG }} --cleanup-tag
|
|
if: env.COMMIT_SHA_TAG != 'null'
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
# Make sure that an old ci that still runs on master doesn't recreate a prerelease
|
|
- name: Check Pullable Commits
|
|
id: check_commits
|
|
run: |
|
|
git fetch
|
|
CHANGES=$(git rev-list HEAD..origin/master --count)
|
|
echo "CHANGES=$CHANGES" >> $GITHUB_ENV
|
|
|
|
- name: Get last commit SHA
|
|
id: last_commit
|
|
run: echo "COMMIT_SHA=$(git rev-parse HEAD | cut -c 1-8)" >> $GITHUB_ENV
|
|
|
|
- name: Get commit date
|
|
id: commit_date
|
|
run: echo "COMMIT_DATE=$(git show -s --date=format:'%Y%m%d' --format=%cd HEAD)" >> $GITHUB_ENV
|
|
|
|
- name: Official Release?
|
|
id: official_release
|
|
# Check for "Official release version of Stockfish" in the commit message
|
|
run: |
|
|
if git log -1 --pretty=%B | grep -q "Official release version of Stockfish"; then
|
|
echo "OFFICIAL_RELEASE=true" >> $GITHUB_ENV
|
|
else
|
|
echo "OFFICIAL_RELEASE=false" >> $GITHUB_ENV
|
|
fi
|
|
|
|
# Get recent commits for release body
|
|
- name: Get commits in this push
|
|
id: recent_commits
|
|
run: |
|
|
COMMITS=$(git log \
|
|
--format="- [\`%h\`](https://github.com/${{ github.repository }}/commit/%H) *%s*" \
|
|
${{ github.event.before }}..HEAD)
|
|
echo "COMMITS<<EOF" >> $GITHUB_OUTPUT
|
|
echo "$COMMITS" >> $GITHUB_OUTPUT
|
|
echo "EOF" >> $GITHUB_OUTPUT
|
|
|
|
# Create a new pre-release, the other upload_binaries.yml will upload the binaries
|
|
# to this pre-release.
|
|
- name: Create Prerelease
|
|
if: github.ref_name == 'master' && env.CHANGES == '0' && env.OFFICIAL_RELEASE == 'false'
|
|
uses: softprops/action-gh-release@b4309332981a82ec1c5618f44dd2e27cc8bfbfda # v3.0.0
|
|
with:
|
|
name: Stockfish dev-${{ env.COMMIT_DATE }}-${{ env.COMMIT_SHA }}
|
|
tag_name: stockfish-dev-${{ env.COMMIT_DATE }}-${{ env.COMMIT_SHA }}
|
|
prerelease: true
|
|
body: |
|
|
Precompiled binaries of the latest Stockfish development version, built automatically on every commit.
|
|
|
|
> [!NOTE]
|
|
> For stable, thoroughly tested builds use the [official releases](https://github.com/official-stockfish/Stockfish/releases).
|
|
> Pre-releases may contain bugs.
|
|
|
|
*Some platforms ship a **universal binary** that automatically selects the best
|
|
instruction set for your CPU - no manual selection needed.*
|
|
|
|
---
|
|
|
|
## Commits
|
|
|
|
${{ steps.recent_commits.outputs.COMMITS }}
|
|
|
|
[View all commits →](https://github.com/${{ github.repository }}/commits/master)
|
|
Matrix:
|
|
name: Prepare matrices
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
arm_matrix: ${{ steps.set-arm-matrix.outputs.arm_matrix }}
|
|
universal_matrix: ${{ steps.set-universal-matrix.outputs.universal_matrix }}
|
|
steps:
|
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
with:
|
|
persist-credentials: false
|
|
- id: set-arm-matrix
|
|
run: |
|
|
ARM_MATRIX=$(jq -c '.' .github/ci/arm_matrix.json)
|
|
echo "ARM_MATRIX=$ARM_MATRIX" >> $GITHUB_OUTPUT
|
|
- id: set-universal-matrix
|
|
run: |
|
|
UNIVERSAL_MATRIX=$(jq -c '.' .github/ci/universal_matrix.json)
|
|
echo "UNIVERSAL_MATRIX=$UNIVERSAL_MATRIX" >> $GITHUB_OUTPUT
|
|
# Testing Jobs
|
|
IWYU:
|
|
name: IWYU
|
|
uses: ./.github/workflows/iwyu.yml
|
|
Sanitizers:
|
|
name: Sanitizers
|
|
if: ${{ always() }}
|
|
uses: ./.github/workflows/sanitizers.yml
|
|
Tests:
|
|
name: Tests
|
|
if: ${{ always() }}
|
|
uses: ./.github/workflows/tests.yml
|
|
Matetrack:
|
|
name: Matetrack
|
|
if: ${{ always() }}
|
|
uses: ./.github/workflows/matetrack.yml
|
|
Games:
|
|
name: Games
|
|
if: ${{ always() }}
|
|
uses: ./.github/workflows/games.yml
|
|
CompilerCheck:
|
|
name: Compiler check
|
|
if: ${{ always() }}
|
|
uses: ./.github/workflows/avx2_compilers.yml
|
|
WASMCompilation:
|
|
name: WASM compilation
|
|
if: ${{ always() }}
|
|
uses: ./.github/workflows/wasm_compilation.yml
|
|
# Release Jobs
|
|
ARMCompilation:
|
|
name: Android builds
|
|
needs: [Matrix, Sanitizers, Tests, Matetrack, Games, CompilerCheck]
|
|
uses: ./.github/workflows/arm_compilation.yml
|
|
with:
|
|
matrix: ${{ needs.Matrix.outputs.arm_matrix }}
|
|
UniversalCompilation:
|
|
name: "Universal builds"
|
|
needs: [Matrix, Sanitizers, Tests, Matetrack, Games, CompilerCheck]
|
|
uses: ./.github/workflows/universal_compilation.yml
|
|
ARM_Binaries:
|
|
if: github.repository == 'official-stockfish/Stockfish'
|
|
name: Android uploads
|
|
needs: [Prerelease, Matrix]
|
|
uses: ./.github/workflows/upload_binaries.yml
|
|
with:
|
|
matrix: ${{ needs.Matrix.outputs.arm_matrix }}
|
|
permissions:
|
|
contents: write # For deleting/creating a (pre)release
|
|
secrets:
|
|
token: ${{ secrets.GITHUB_TOKEN }}
|
|
Universal_Binaries:
|
|
if: github.repository == 'official-stockfish/Stockfish'
|
|
name: Universal binaries
|
|
needs: [Prerelease, Matrix]
|
|
uses: ./.github/workflows/upload_binaries.yml
|
|
with:
|
|
matrix: ${{ needs.Matrix.outputs.universal_matrix }}
|
|
permissions:
|
|
contents: write # For deleting/creating a (pre)release
|
|
secrets:
|
|
token: ${{ secrets.GITHUB_TOKEN }}
|