Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
6c6d985
Initial plan
Copilot Jan 24, 2026
0786d8c
Implement neural network infrastructure for MCTS
Copilot Jan 24, 2026
4de5a4d
Address code review issues
Copilot Jan 24, 2026
1f471ef
Implement full policy tables with 1858 move mappings
Copilot Jan 25, 2026
a3973d6
Implement full position encoder with 8-position history and canonical…
Copilot Jan 25, 2026
d382173
Implement Metal/MPSGraph backend for transformer neural network infer…
Copilot Jan 25, 2026
6fe652c
Add Metal backend documentation and fix memory management
Copilot Jan 25, 2026
6dc2713
Implement Metal/MPSGraph transformer backend for NN inference
Copilot Jan 25, 2026
d3d1b38
Complete MCTS integration with neural network backend
Copilot Jan 25, 2026
68cc845
Address code review: Extract magic numbers to named constants
Copilot Jan 25, 2026
05311a1
Complete verification tests with all 15 benchmark positions and updat…
Copilot Jan 26, 2026
bfb3fcf
Merge main into copilot/implement-lc0-neural-network-inference-again
NripeshN Jan 26, 2026
b3f7f9f
Fix PR review issues: remove build artifacts and map knight promotion…
Copilot Jan 26, 2026
7106b13
Update Elo tournament workflow to support manual trigger with optiona…
NripeshN Jan 26, 2026
686ed6c
Enhance CI workflows by adding dependency installation steps for macO…
NripeshN Jan 26, 2026
9000926
Refactor MCTS source files in CMakeLists.txt by removing unused files
NripeshN Jan 26, 2026
74b84d3
Enhance CMake configuration and CI workflows for protobuf and absl in…
NripeshN Jan 26, 2026
e0a6f37
Update CMake and CI workflows to improve absl library handling
NripeshN Jan 26, 2026
6593b74
Fix critical bugs: recalculate max_score after NN blending and use re…
Copilot Jan 26, 2026
c63ee6c
Fix castling plane order consistency and invalid move policy index
Copilot Jan 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 46 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ jobs:
echo ""
echo "Available Metal devices:"
system_profiler SPDisplaysDataType | grep -A 5 "Metal" || echo "Metal info not available in CI"
echo ""
echo "Installing dependencies..."
brew install protobuf zlib abseil

- name: Setup environment (Ubuntu)
if: runner.os == 'Linux'
Expand All @@ -99,6 +102,10 @@ jobs:
else
echo "No NVIDIA GPU detected (nvidia-smi not found)"
fi
echo ""
echo "Installing dependencies..."
sudo apt-get update
sudo apt-get install -y libprotobuf-dev protobuf-compiler zlib1g-dev
shell: bash

- name: Setup environment (Windows)
Expand All @@ -118,6 +125,16 @@ jobs:
}
shell: pwsh

- name: Install dependencies (Windows)
if: runner.os == 'Windows'
run: |
# Install vcpkg and protobuf
git clone https://github.com/Microsoft/vcpkg.git C:\vcpkg
C:\vcpkg\bootstrap-vcpkg.bat
C:\vcpkg\vcpkg install protobuf:x64-windows zlib:x64-windows
echo "CMAKE_TOOLCHAIN_FILE=C:\vcpkg\scripts\buildsystems\vcpkg.cmake" >> $env:GITHUB_ENV
shell: pwsh

- name: Download NNUE files
run: |
mkdir -p src
Expand All @@ -135,7 +152,8 @@ jobs:
restore-keys: |
${{ runner.os }}-${{ matrix.os }}-cmake-

- name: Configure CMake
- name: Configure CMake (Unix)
if: runner.os != 'Windows'
run: |
cmake -S . -B build \
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \
Expand All @@ -144,6 +162,17 @@ jobs:
-DBUILD_TESTS=ON
shell: bash

- name: Configure CMake (Windows)
if: runner.os == 'Windows'
run: |
cmake -S . -B build `
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} `
-DUSE_METAL=${{ matrix.use_metal }} `
-DUSE_CUDA=${{ matrix.use_cuda }} `
-DBUILD_TESTS=ON `
-DCMAKE_TOOLCHAIN_FILE=C:\vcpkg\scripts\buildsystems\vcpkg.cmake
shell: pwsh

- name: Build (Unix)
if: runner.os != 'Windows'
run: |
Expand Down Expand Up @@ -246,6 +275,12 @@ jobs:
nvcc --version
shell: bash

- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y libprotobuf-dev protobuf-compiler zlib1g-dev
shell: bash

- name: Download NNUE files
run: |
mkdir -p src
Expand Down Expand Up @@ -354,6 +389,10 @@ jobs:
with:
submodules: recursive

- name: Install dependencies
run: brew install protobuf zlib abseil
shell: bash

- name: Download NNUE files
run: |
mkdir -p src
Expand Down Expand Up @@ -412,6 +451,12 @@ jobs:
method: "network"
sub-packages: '["nvcc", "cudart", "cudart-dev"]'

- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y libprotobuf-dev protobuf-compiler zlib1g-dev
shell: bash

- name: Download NNUE files
run: |
mkdir -p src
Expand Down
23 changes: 12 additions & 11 deletions .github/workflows/elo-tournament.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
name: Elo Tournament

on:
pull_request:
branches: [main]
types: [opened, synchronize, reopened]
workflow_dispatch: # Allow manual trigger
workflow_dispatch: # Manual trigger only
inputs:
pr_number:
description: "PR number to run tournament on (leave empty for current branch)"
required: false
default: ""
games_per_match:
description: "Number of games per match (should be even for color swap)"
required: false
Expand All @@ -15,9 +16,9 @@ on:
required: false
default: "600+0.1"

# Cancel in-progress runs for the same PR when a new push occurs
# Cancel in-progress runs when a new run is triggered
concurrency:
group: elo-tournament-${{ github.event.pull_request.number || github.run_id }}
group: elo-tournament-${{ github.event.inputs.pr_number || github.run_id }}
cancel-in-progress: true

env:
Expand All @@ -43,7 +44,7 @@ jobs:

- name: Install build dependencies
run: |
brew install cmake ninja meson qt@6 coreutils
brew install cmake ninja meson qt@6 coreutils protobuf zlib abseil
pip3 install meson ninja chess
# coreutils provides gtimeout which we alias to timeout
echo "alias timeout=gtimeout" >> ~/.bashrc
Expand Down Expand Up @@ -942,20 +943,20 @@ jobs:
cat results/pr_comment.md

- name: Find existing comment
if: github.event_name == 'pull_request'
if: github.event.inputs.pr_number != ''
uses: peter-evans/find-comment@v3
id: find-comment
with:
issue-number: ${{ github.event.pull_request.number }}
issue-number: ${{ github.event.inputs.pr_number }}
comment-author: "github-actions[bot]"
body-includes: "🏆 MetalFish Elo Tournament Results"

- name: Post or update PR comment
if: github.event_name == 'pull_request'
if: github.event.inputs.pr_number != ''
uses: peter-evans/create-or-update-comment@v4
with:
comment-id: ${{ steps.find-comment.outputs.comment-id }}
issue-number: ${{ github.event.pull_request.number }}
issue-number: ${{ github.event.inputs.pr_number }}
body-path: ${{ steps.aggregate.outputs.comment_file }}
edit-mode: replace

Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -391,4 +391,6 @@ TSWLatexianTemp*
#*Notes.bib
*.pyc
.DS_Store
_codeql_build_dir/
_codeql_detected_source_root
networks/BT4-1024x15x32h-swa-6147500.pb
120 changes: 107 additions & 13 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -275,13 +275,59 @@ endif()
# mcts/hybrid commands - apple_silicon_mcts: Apple Silicon specific
# optimizations
set(MCTS_SOURCES
src/mcts/position_adapter.cpp src/mcts/position_classifier.cpp
src/mcts/ab_integration.cpp src/mcts/thread_safe_mcts.cpp
src/mcts/parallel_hybrid_search.cpp src/mcts/apple_silicon_mcts.cpp)
src/mcts/position_classifier.cpp
src/mcts/ab_integration.cpp
src/mcts/thread_safe_mcts.cpp
src/mcts/nn_mcts_evaluator.cpp
src/mcts/position_adapter.cpp
src/mcts/parallel_hybrid_search.cpp
src/mcts/apple_silicon_mcts.cpp)

# Find protobuf (minimum version 3.0) - must be before NN_SOURCES
find_package(Protobuf 3.0 REQUIRED)
include_directories(${Protobuf_INCLUDE_DIRS})

# Generate protobuf files from .proto definition
# This ensures compatibility with the installed protobuf version
set(PROTO_FILE ${CMAKE_CURRENT_SOURCE_DIR}/src/nn/proto/net.proto)
set(PROTO_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/proto)
file(MAKE_DIRECTORY ${PROTO_OUTPUT_DIR})

# Custom command to generate protobuf files in the correct location
# The proto file outputs to PROTO_OUTPUT_DIR so includes like "proto/net.pb.h" work
add_custom_command(
OUTPUT ${PROTO_OUTPUT_DIR}/net.pb.cc ${PROTO_OUTPUT_DIR}/net.pb.h
COMMAND ${Protobuf_PROTOC_EXECUTABLE}
ARGS --cpp_out=${PROTO_OUTPUT_DIR}
--proto_path=${CMAKE_CURRENT_SOURCE_DIR}/src/nn/proto
${PROTO_FILE}
DEPENDS ${PROTO_FILE}
COMMENT "Generating protobuf files from net.proto"
VERBATIM
)

# Add generated directory to include path (so "proto/net.pb.h" works from build dir)
# The include path should be the parent of proto/ so that "proto/net.pb.h" resolves
include_directories(${CMAKE_CURRENT_BINARY_DIR})
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/nn)

# Neural network source files (includes generated protobuf)
set(NN_SOURCES
${PROTO_OUTPUT_DIR}/net.pb.cc
src/nn/loader.cpp
src/nn/encoder.cpp
src/nn/policy_map.cpp
src/nn/network.cpp)

# Metal GPU acceleration (macOS only)
if(USE_METAL AND METAL_CPP_AVAILABLE)
set(GPU_SOURCES ${GPU_SOURCES} src/gpu/metal/metal_backend.mm)
set(NN_SOURCES ${NN_SOURCES} src/nn/metal/metal_network.mm)

# Disable ARC for Metal network implementation (uses manual memory management)
set_source_files_properties(src/nn/metal/metal_network.mm
PROPERTIES COMPILE_FLAGS "-fno-objc-arc")

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DUSE_METAL")
message(STATUS "Metal GPU acceleration: ENABLED")

Expand Down Expand Up @@ -328,7 +374,8 @@ set(SOURCES
${UCI_SOURCES}
${SYZYGY_SOURCES}
${GPU_SOURCES}
${MCTS_SOURCES})
${MCTS_SOURCES}
${NN_SOURCES})

# Create executable
if(USE_CUDA AND CUDA_AVAILABLE)
Expand All @@ -346,9 +393,33 @@ if(TARGET metal_shaders)
add_dependencies(metalfish metal_shaders)
endif()

# Find zlib (for loading .pb.gz files)
find_package(ZLIB REQUIRED)

# Find absl (required by protobuf >= 22 on some platforms)
# Initialize to empty - only set if found
set(ABSL_LIBS "")
find_package(absl CONFIG QUIET)
if(absl_FOUND)
message(STATUS "Found abseil - linking absl::log")
set(ABSL_LIBS absl::log absl::log_internal_check_op absl::log_internal_message)
else()
# Try pkg-config as fallback (for Linux)
find_package(PkgConfig QUIET)
if(PKG_CONFIG_FOUND)
pkg_check_modules(ABSL_PKG QUIET absl_log)
if(ABSL_PKG_FOUND)
message(STATUS "Found abseil via pkg-config")
set(ABSL_LIBS ${ABSL_PKG_LIBRARIES})
include_directories(${ABSL_PKG_INCLUDE_DIRS})
link_directories(${ABSL_PKG_LIBRARY_DIRS})
endif()
endif()
endif()

# Link pthread
find_package(Threads REQUIRED)
target_link_libraries(metalfish Threads::Threads)
target_link_libraries(metalfish Threads::Threads ${Protobuf_LIBRARIES} ${ZLIB_LIBRARIES} ${ABSL_LIBS})

# macOS specific
if(APPLE)
Expand All @@ -357,12 +428,14 @@ if(APPLE)
find_library(ACCELERATE_FRAMEWORK Accelerate)
find_library(COREFOUNDATION_FRAMEWORK CoreFoundation)
find_library(QUARTZCORE_FRAMEWORK QuartzCore)
find_library(MPS_FRAMEWORK MetalPerformanceShaders)
find_library(MPSGRAPH_FRAMEWORK MetalPerformanceShadersGraph)

if(USE_METAL AND METAL_CPP_AVAILABLE)
target_link_libraries(
metalfish ${METAL_FRAMEWORK} ${FOUNDATION_FRAMEWORK}
${COREFOUNDATION_FRAMEWORK} ${QUARTZCORE_FRAMEWORK}
${ACCELERATE_FRAMEWORK})
target_link_libraries(metalfish ${METAL_FRAMEWORK} ${FOUNDATION_FRAMEWORK}
${COREFOUNDATION_FRAMEWORK} ${QUARTZCORE_FRAMEWORK}
${MPS_FRAMEWORK} ${MPSGRAPH_FRAMEWORK}
${ACCELERATE_FRAMEWORK})
endif()
endif()

Expand Down Expand Up @@ -409,6 +482,11 @@ if(BUILD_TESTS)
tests/test_metal.cpp
tests/test_gpu_nnue.cpp
tests/test_cuda.cpp)

set(NN_TEST_SOURCES
tests/test_nn_comparison.cpp
${CORE_SOURCES}
${NN_SOURCES})

if(USE_CUDA AND CUDA_AVAILABLE)
# CUDA test executable
Expand All @@ -427,6 +505,7 @@ if(BUILD_TESTS)
metalfish_tests PROPERTIES CUDA_SEPARABLE_COMPILATION ON
CUDA_RESOLVE_DEVICE_SYMBOLS ON)
target_link_libraries(metalfish_tests Threads::Threads
${Protobuf_LIBRARIES} ${ZLIB_LIBRARIES} ${ABSL_LIBS}
${CUDA_LINK_LIBRARIES})
else()
add_executable(
Expand All @@ -438,8 +517,9 @@ if(BUILD_TESTS)
${UCI_SOURCES}
${SYZYGY_SOURCES}
${GPU_SOURCES}
${MCTS_SOURCES})
target_link_libraries(metalfish_tests Threads::Threads)
${MCTS_SOURCES}
${NN_SOURCES})
target_link_libraries(metalfish_tests Threads::Threads ${Protobuf_LIBRARIES} ${ZLIB_LIBRARIES} ${ABSL_LIBS})
endif()

if(APPLE
Expand All @@ -448,10 +528,24 @@ if(BUILD_TESTS)
target_link_libraries(
metalfish_tests ${METAL_FRAMEWORK} ${FOUNDATION_FRAMEWORK}
${COREFOUNDATION_FRAMEWORK} ${QUARTZCORE_FRAMEWORK}
${MPS_FRAMEWORK} ${MPSGRAPH_FRAMEWORK}
${ACCELERATE_FRAMEWORK})
endif()

add_test(NAME metalfish_tests COMMAND metalfish_tests)

# Neural network comparison test
add_executable(test_nn_comparison ${NN_TEST_SOURCES} ${MCTS_SOURCES})
target_link_libraries(test_nn_comparison Threads::Threads ${Protobuf_LIBRARIES} ${ZLIB_LIBRARIES} ${ABSL_LIBS})

if(APPLE AND USE_METAL AND METAL_CPP_AVAILABLE)
target_link_libraries(
test_nn_comparison ${METAL_FRAMEWORK} ${FOUNDATION_FRAMEWORK}
${COREFOUNDATION_FRAMEWORK} ${QUARTZCORE_FRAMEWORK}
${MPS_FRAMEWORK} ${MPSGRAPH_FRAMEWORK})
endif()

add_test(NAME test_nn_comparison COMMAND test_nn_comparison)
endif()

# ============================================================================
Expand All @@ -465,7 +559,7 @@ if(BUILD_GPU_BENCHMARK)
target_link_libraries(
metalfish_gpu_bench Threads::Threads ${METAL_FRAMEWORK}
${FOUNDATION_FRAMEWORK} ${COREFOUNDATION_FRAMEWORK}
${QUARTZCORE_FRAMEWORK})
${QUARTZCORE_FRAMEWORK} ${MPS_FRAMEWORK} ${MPSGRAPH_FRAMEWORK})

# Paper benchmark with full NNUE support
add_executable(
Expand All @@ -474,7 +568,7 @@ if(BUILD_GPU_BENCHMARK)
target_link_libraries(
metalfish_paper_bench Threads::Threads ${METAL_FRAMEWORK}
${FOUNDATION_FRAMEWORK} ${COREFOUNDATION_FRAMEWORK}
${QUARTZCORE_FRAMEWORK})
${QUARTZCORE_FRAMEWORK} ${MPS_FRAMEWORK} ${MPSGRAPH_FRAMEWORK})
elseif(USE_CUDA AND CUDA_AVAILABLE)
add_executable(metalfish_gpu_bench src/benchmark_gpu.cpp ${CORE_SOURCES}
${GPU_SOURCES} ${CUDA_SOURCES})
Expand Down
Loading