Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
16 changes: 16 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,16 @@ jobs:
-o tests/tari_miner_reliability_test
tests/tari_miner_reliability_test

- name: Build and run pipeline selection regressions
run: |
g++ -std=c++17 -O2 -I. \
tests/tari_miner_pipeline_test.cpp \
-o tests/tari_miner_pipeline_test
tests/tari_miner_pipeline_test

- name: Run GPU recall verifier fixtures
run: python3 tests/tari_c29_gpu_recall.py --self-test

- name: Build and run Tari wrapper self-test
run: |
g++ -std=c++17 -O2 \
Expand Down Expand Up @@ -92,6 +102,8 @@ jobs:
'tests\tari_pool_protocol_test.exe',
'cl /nologo /std:c++17 /EHsc /O2 /I. tests\tari_miner_reliability_test.cpp /Fe:tests\tari_miner_reliability_test.exe',
'tests\tari_miner_reliability_test.exe',
'cl /nologo /std:c++17 /EHsc /O2 /I. tests\tari_miner_pipeline_test.cpp /Fe:tests\tari_miner_pipeline_test.exe',
'tests\tari_miner_pipeline_test.exe',
'cl /nologo /std:c++17 /EHsc /O2 tari_c29.cpp tari_c29_selftest.cpp /Fe:tari_c29_selftest.exe',
'tari_c29_selftest.exe'
) -join ' && '
Expand Down Expand Up @@ -120,3 +132,7 @@ jobs:
if ($manifest -contains 13) {
throw 'HiveOS manifest must use LF line endings.'
}

- name: Run GPU recall verifier fixtures
shell: powershell
run: python tests\tari_c29_gpu_recall.py --self-test
41 changes: 38 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ NVIDIA GPU and selects the correct backend for each card:

Mixed rigs are supported. Each GPU runs in its own process with a worker name
such as `RIG01-gpu0` or `RIG01-gpu1`. Pipeline depth is also selected inside
each process from that card's available VRAM.
each process from the free VRAM remaining after its first solver context starts.
Automatic selection can use up to five contexts on Linux and Windows TCC, and
up to four on Windows WDDM. An explicit `--pipeline` value from 1 through 5
overrides the automatic platform cap; allocation still stops safely if VRAM
runs out.

The starter does not change GPU clocks, voltage, fans, or power limits.

Expand Down Expand Up @@ -198,6 +202,35 @@ bin/tari_c29_solver_sm_89 --device 0 --count 320 --pipeline 2

A correct run ends with `verify failures: 0`.

### Exact GPU recall regression

The GPU recall test compares exact `(header nonce, proof hash)` sets, not just
cycle counts. It independently packs every 42-edge proof, recalculates its
BLAKE2b-256 hash and difficulty, repeats both builds, and checks pipeline
parity. Build the shipped and conservative reference profiles for the GPU
architecture, then run:

```bat
build_solver.bat sm_120
build_solver.bat sm_120 reference
python tests\tari_c29_gpu_recall.py run --candidate bin\tari_c29_solver_sm_120.exe --reference bin\validation\tari_c29_solver_sm_120_reference.exe --arch sm_120 --output-dir validation --parity-pipeline 4
```

```bash
./build_solver.sh sm_89
./build_solver.sh sm_89 reference
python3 tests/tari_c29_gpu_recall.py run --candidate bin/tari_c29_solver_sm_89 --reference bin/validation/tari_c29_solver_sm_89_reference --arch sm_89 --output-dir validation --parity-pipeline 2
```

The default sequence tests 4,200 fixed graphs and saves the raw logs, JSONL
proof records, invoked commands, and comparison report. The reference binaries
remain under `bin/validation` and are not included in release packages.
The runner also rejects a binary whose embedded build target, runtime GPU
architecture, or compiled trim default does not match `--arch`. Throughput
measurements are a separate performance check and do not replace the exact
recall gate. Hosted CI compiles both profiles and exercises the verifier
fixtures; the full sequence runs only on a trusted host with the matching GPU.

## Build From Source

The repository includes its required third-party source under
Expand All @@ -218,8 +251,10 @@ three target architectures:
./build_all.sh
```

Individual backends can be built with `build_solver` or `build_pool_miner` and
one of `sm_86`, `sm_89`, or `sm_120`.
`build_all` also compiles the non-release reference solvers used by the recall
test. Individual backends can be built with `build_solver` or
`build_pool_miner` and one of `sm_86`, `sm_89`, or `sm_120`; pass `reference`
as the second `build_solver` argument to build only that validation profile.

## License

Expand Down
2 changes: 2 additions & 0 deletions build_all.bat
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ for %%A in (sm_86 sm_89 sm_120) do (
if errorlevel 1 goto failed
call build_pool_miner.bat %%A
if errorlevel 1 goto failed
call build_solver.bat %%A reference
if errorlevel 1 goto failed
)

echo.
Expand Down
1 change: 1 addition & 0 deletions build_all.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
for arch in sm_86 sm_89 sm_120; do
"$ROOT/build_solver.sh" "$arch"
"$ROOT/build_pool_miner.sh" "$arch"
"$ROOT/build_solver.sh" "$arch" reference
done

echo "All Linux GPU backends built successfully."
2 changes: 1 addition & 1 deletion build_pool_miner.bat
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ set "CUCKAROO=%ROOT%third_party\cuckoo\src\cuckaroo"
set "CRYPTO=%ROOT%third_party\cuckoo\src\crypto"

echo Building tari_c29_pool_miner for %ARCH% ...
"%NVCC%" -O3 -std=c++17 -arch=%ARCH% --default-stream per-thread -DXBITS=7 -DIDXSHIFT=9 -DGRAPH_UNION_SKIP=1 -DSOLVER_PRELAUNCH_NEXT=1 -DRECOVERY_SMALL_OUTPUT=1 -DSEEDA_REHASH=1 %EXTRA_FLAGS% -maxrregcount=96 -Xptxas -flcm=cg ^
"%NVCC%" -O3 -std=c++17 -arch=%ARCH% --default-stream per-thread -DXBITS=7 -DIDXSHIFT=9 -DGRAPH_UNION_SKIP=1 -DRECOVERY_SMALL_OUTPUT=1 -DSEEDA_REHASH=1 %EXTRA_FLAGS% -maxrregcount=96 -Xptxas -flcm=cg ^
-I"%ROOT%compat" ^
-I"%CUCKAROO%" ^
-I"%CRYPTO%" ^
Expand Down
2 changes: 1 addition & 1 deletion build_pool_miner.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ if [[ "$ARCH" == "sm_120" ]]; then
fi

echo "Building tari_c29_pool_miner_linux for $ARCH ..."
"$NVCC" "${HOST_FLAGS[@]}" -O3 -std="$STD" --default-stream per-thread -DXBITS="$XBITS" -DIDXSHIFT="$IDXSHIFT" -DGRAPH_UNION_SKIP=1 -DSOLVER_PRELAUNCH_NEXT=1 -DRECOVERY_SMALL_OUTPUT=1 -DSEEDA_REHASH=1 \
"$NVCC" "${HOST_FLAGS[@]}" -O3 -std="$STD" --default-stream per-thread -DXBITS="$XBITS" -DIDXSHIFT="$IDXSHIFT" -DGRAPH_UNION_SKIP=1 -DRECOVERY_SMALL_OUTPUT=1 -DSEEDA_REHASH=1 \
"${EXTRA_FLAGS[@]}" \
-maxrregcount="$MAXRREGCOUNT" -Xptxas -flcm=cg \
-gencode "arch=$COMPUTE,code=$ARCH" \
Expand Down
24 changes: 22 additions & 2 deletions build_solver.bat
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,38 @@ setlocal
set "ROOT=%~dp0"
set ARCH=%1
if "%ARCH%"=="" set ARCH=sm_120
set BUILD_ARCH=%ARCH:sm_=%
set PROFILE=%2
if "%PROFILE%"=="" set PROFILE=release
if not exist "%ROOT%bin" mkdir "%ROOT%bin"
if /I "%PROFILE%"=="release" goto release_profile
if /I "%PROFILE%"=="reference" goto reference_profile
echo Unknown solver profile "%PROFILE%". Use release or reference.
endlocal
exit /b 2

:release_profile
set "OUTPUT=%ROOT%bin\tari_c29_solver_%ARCH%.exe"
set "PROFILE_FLAGS=-DGRAPH_UNION_SKIP=1 -DRECOVERY_SMALL_OUTPUT=1 -DSEEDA_REHASH=1"
set EXTRA_FLAGS=
if /I "%ARCH%"=="sm_120" set EXTRA_FLAGS=-DWARP_DST_ATOMICS_LATE=1 -DTARI_C29_DEFAULT_NTRIMS=48 -DSEEDB_REVERSE_LOOP=1 -DROUND0_DST_HASH_DYNAMIC_BITS=12 -DROUND0_DST_HASH_DYNAMIC_PROBES=4 -DROUND0_DST_HASH_FALLBACK_PLAIN=1 -DROUND0_DST_HASH_REPLAY_NORMAL_LOAD=1 -DROUND0_DST_HASH_REVERSE_INSERT=1 -DFUSE_FINAL_TAIL_CURRENT=1 -DFUSE_FINAL_TAIL_COUNT_NORMAL_LOAD=1 -DROUND23_TPB=960 -DROUND1_COUNT_NORMAL_LOAD=1 -DROUND23_COUNT_NORMAL_LOAD=1
goto profile_ready

:reference_profile
if not exist "%ROOT%bin\validation" mkdir "%ROOT%bin\validation"
set "OUTPUT=%ROOT%bin\validation\tari_c29_solver_%ARCH%_reference.exe"
set "PROFILE_FLAGS=-DTARI_C29_REFERENCE_BUILD=1 -DGRAPH_UNION_SKIP=0 -DRECOVERY_SMALL_OUTPUT=0 -DSEEDA_REHASH=0 -DSKIP_LATE_NULL_CHECKS=0 -DWARP_DST_ATOMICS_LATE=0 -DTARI_C29_DEFAULT_NTRIMS=50 -DSEEDB_REVERSE_LOOP=0 -DROUND0_DST_HASH_DYNAMIC_BITS=0 -DROUND0_DST_HASH_DYNAMIC_PROBES=8 -DROUND0_DST_HASH_FALLBACK_PLAIN=0 -DROUND0_DST_HASH_REPLAY_NORMAL_LOAD=0 -DROUND0_DST_HASH_REVERSE_INSERT=0 -DFUSE_FINAL_TAIL_CURRENT=0 -DFUSE_FINAL_TAIL_COUNT_NORMAL_LOAD=0 -DROUND1_COUNT_NORMAL_LOAD=0 -DROUND23_COUNT_NORMAL_LOAD=0 -DROUND23_TPB=1024"
set EXTRA_FLAGS=

:profile_ready

if not defined NVCC set "NVCC=C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v13.2\bin\nvcc.exe"
if not exist "%NVCC%" set "NVCC=nvcc"
set "CUCKAROO=%ROOT%third_party\cuckoo\src\cuckaroo"
set "CRYPTO=%ROOT%third_party\cuckoo\src\crypto"

echo Building tari_c29_solver for %ARCH% ...
"%NVCC%" -O3 -std=c++17 -arch=%ARCH% --default-stream per-thread -DXBITS=7 -DIDXSHIFT=9 -DGRAPH_UNION_SKIP=1 -DSOLVER_PRELAUNCH_NEXT=1 -DRECOVERY_SMALL_OUTPUT=1 -DSEEDA_REHASH=1 %EXTRA_FLAGS% -maxrregcount=96 -Xptxas -flcm=cg ^
echo Building tari_c29_solver for %ARCH% profile=%PROFILE% ...
"%NVCC%" -O3 -std=c++17 -arch=%ARCH% --default-stream per-thread -DXBITS=7 -DIDXSHIFT=9 -DTARI_C29_BUILD_ARCH=%BUILD_ARCH% %PROFILE_FLAGS% %EXTRA_FLAGS% -maxrregcount=96 -Xptxas -flcm=cg ^
-I"%ROOT%compat" ^
-I"%CUCKAROO%" ^
-I"%CRYPTO%" ^
Expand Down
30 changes: 24 additions & 6 deletions build_solver.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ set -euo pipefail
# forward JIT. With a newer toolkit, pass NVCC=/path/to/nvcc and sm_89/sm_120.

ARCH="${1:-sm_86}"
BUILD_ARCH="${ARCH#sm_}"
PROFILE="${2:-release}"
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
mkdir -p "$ROOT/bin"
OUTPUT="$ROOT/bin/tari_c29_solver_$ARCH"
CUCKOO_ROOT="${CUCKOO_ROOT:-"$ROOT/third_party/cuckoo"}"
CUCKAROO="$CUCKOO_ROOT/src/cuckaroo"
CRYPTO="$CUCKOO_ROOT/src/crypto"
Expand All @@ -24,13 +25,30 @@ HOST_FLAGS=()
if [[ -n "$NVCC_HOST" ]]; then
HOST_FLAGS=(-ccbin "$NVCC_HOST" --allow-unsupported-compiler)
fi
PROFILE_FLAGS=()
EXTRA_FLAGS=()
if [[ "$ARCH" == "sm_120" ]]; then
EXTRA_FLAGS=(-DWARP_DST_ATOMICS_LATE=1 -DTARI_C29_DEFAULT_NTRIMS=48 -DSEEDB_REVERSE_LOOP=1 -DROUND0_DST_HASH_DYNAMIC_BITS=12 -DROUND0_DST_HASH_DYNAMIC_PROBES=4 -DROUND0_DST_HASH_FALLBACK_PLAIN=1 -DROUND0_DST_HASH_REPLAY_NORMAL_LOAD=1 -DROUND0_DST_HASH_REVERSE_INSERT=1 -DFUSE_FINAL_TAIL_CURRENT=1 -DFUSE_FINAL_TAIL_COUNT_NORMAL_LOAD=1 -DROUND23_TPB=960 -DROUND1_COUNT_NORMAL_LOAD=1 -DROUND23_COUNT_NORMAL_LOAD=1)
fi
case "$PROFILE" in
release)
OUTPUT="$ROOT/bin/tari_c29_solver_$ARCH"
PROFILE_FLAGS=(-DGRAPH_UNION_SKIP=1 -DRECOVERY_SMALL_OUTPUT=1 -DSEEDA_REHASH=1)
if [[ "$ARCH" == "sm_120" ]]; then
EXTRA_FLAGS=(-DWARP_DST_ATOMICS_LATE=1 -DTARI_C29_DEFAULT_NTRIMS=48 -DSEEDB_REVERSE_LOOP=1 -DROUND0_DST_HASH_DYNAMIC_BITS=12 -DROUND0_DST_HASH_DYNAMIC_PROBES=4 -DROUND0_DST_HASH_FALLBACK_PLAIN=1 -DROUND0_DST_HASH_REPLAY_NORMAL_LOAD=1 -DROUND0_DST_HASH_REVERSE_INSERT=1 -DFUSE_FINAL_TAIL_CURRENT=1 -DFUSE_FINAL_TAIL_COUNT_NORMAL_LOAD=1 -DROUND23_TPB=960 -DROUND1_COUNT_NORMAL_LOAD=1 -DROUND23_COUNT_NORMAL_LOAD=1)
fi
;;
reference)
mkdir -p "$ROOT/bin/validation"
OUTPUT="$ROOT/bin/validation/tari_c29_solver_${ARCH}_reference"
PROFILE_FLAGS=(-DTARI_C29_REFERENCE_BUILD=1 -DGRAPH_UNION_SKIP=0 -DRECOVERY_SMALL_OUTPUT=0 -DSEEDA_REHASH=0 -DSKIP_LATE_NULL_CHECKS=0 -DWARP_DST_ATOMICS_LATE=0 -DTARI_C29_DEFAULT_NTRIMS=50 -DSEEDB_REVERSE_LOOP=0 -DROUND0_DST_HASH_DYNAMIC_BITS=0 -DROUND0_DST_HASH_DYNAMIC_PROBES=8 -DROUND0_DST_HASH_FALLBACK_PLAIN=0 -DROUND0_DST_HASH_REPLAY_NORMAL_LOAD=0 -DROUND0_DST_HASH_REVERSE_INSERT=0 -DFUSE_FINAL_TAIL_CURRENT=0 -DFUSE_FINAL_TAIL_COUNT_NORMAL_LOAD=0 -DROUND1_COUNT_NORMAL_LOAD=0 -DROUND23_COUNT_NORMAL_LOAD=0 -DROUND23_TPB=1024)
;;
*)
echo "Unknown solver profile '$PROFILE'. Use release or reference." >&2
exit 2
;;
esac

echo "Building tari_c29_solver_linux for $ARCH ..."
"$NVCC" "${HOST_FLAGS[@]}" -O3 -std="$STD" --default-stream per-thread -DXBITS="$XBITS" -DIDXSHIFT="$IDXSHIFT" -DGRAPH_UNION_SKIP=1 -DSOLVER_PRELAUNCH_NEXT=1 -DRECOVERY_SMALL_OUTPUT=1 -DSEEDA_REHASH=1 \
echo "Building tari_c29_solver_linux for $ARCH profile=$PROFILE ..."
"$NVCC" "${HOST_FLAGS[@]}" -O3 -std="$STD" --default-stream per-thread -DXBITS="$XBITS" -DIDXSHIFT="$IDXSHIFT" -DTARI_C29_BUILD_ARCH="$BUILD_ARCH" \
"${PROFILE_FLAGS[@]}" \
"${EXTRA_FLAGS[@]}" \
-maxrregcount="$MAXRREGCOUNT" -Xptxas -flcm=cg \
-gencode "arch=$COMPUTE,code=$ARCH" \
Expand Down
3 changes: 2 additions & 1 deletion compress.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Derived from tromp/cuckoo. SPDX-License-Identifier: GPL-2.0-or-later

#include <stdio.h>
#include <new>

// compressor for cuckaroo nodes where edgetrimming
Expand Down Expand Up @@ -63,7 +64,7 @@ class compressor {
word_t cu = nodes[ui];
if (cu == NIL) {
if (nnodes >= SIZE) {
print_log("NODE OVERFLOW at %x\n", u);
fprintf(stderr, "NODE OVERFLOW at %x\n", u);
return 0;
}
nodes[ui] = u << SIZEBITS | nnodes;
Expand Down
2 changes: 1 addition & 1 deletion mean_c29.cu
Original file line number Diff line number Diff line change
Expand Up @@ -1148,7 +1148,7 @@ struct solver_ctx {
return 0;
}
if (nedges > MAXEDGES) {
print_log("OOPS; losing %d edges beyond MAXEDGES=%d\n", nedges-MAXEDGES, MAXEDGES);
fprintf(stderr, "OOPS; losing %d edges beyond MAXEDGES=%d\n", nedges-MAXEDGES, MAXEDGES);
nedges = MAXEDGES;
}
#if TRIM_STAGE_TIMING
Expand Down
Loading
Loading