1
0
mirror of https://github.com/xmrig/xmrig.git synced 2025-12-11 09:22:48 -05:00

Compare commits

..

61 Commits

Author SHA1 Message Date
XMRig
6e4a5a6d94 v6.24.0 2025-06-23 07:44:53 +07:00
XMRig
273133aa63 Merge branch 'dev' 2025-06-23 07:44:05 +07:00
xmrig
c69e30c9a0 Update CHANGELOG.md 2025-06-23 05:39:26 +07:00
XMRig
6a690ba1e9 More DNS cleanup. 2025-06-20 23:45:53 +07:00
XMRig
545aef0937 v6.24.0-dev 2025-06-20 08:34:58 +07:00
xmrig
9fa66d3242 Merge pull request #3678 from xmrig/dns_ip_version
Improved IPv6 support.
2025-06-20 08:33:50 +07:00
XMRig
ec286c7fef Improved IPv6 support. 2025-06-20 07:39:52 +07:00
xmrig
e28d663d80 Merge pull request #3677 from SChernykh/dev
Tweaked autoconfig for AMD CPUs with < 2 MB L3 cache per thread, again (hopefully the last time)
2025-06-19 18:07:54 +07:00
SChernykh
aba1ad8cfc Tweaked autoconfig for AMD CPUs with < 2 MB L3 cache per thread, again (hopefully the last time) 2025-06-19 12:58:31 +02:00
xmrig
bf44ed52e9 Merge pull request #3674 from benthetechguy/armhf
cflags: Add lax-vector-conversions on ARMv7
2025-06-19 04:46:02 +07:00
Ben Westover
762c435fa8 cflags: Add lax-vector-conversions on ARMv7
lax-vector-conversions is enabled in the CXXFLAGS but not CFLAGS for ARMv7.
This commit adds it to CFLAGS which fixes the ARMv7 build (Fixes: #3673).
2025-06-18 16:38:05 -04:00
xmrig
48faf0a11b Merge pull request #3671 from SChernykh/dev
Hwloc: fixed detection of L2 cache size for some complex NUMA topologies
2025-06-17 18:52:43 +07:00
SChernykh
d125d22d27 Hwloc: fixed detection of L2 cache size for some complex NUMA topologies 2025-06-17 13:49:02 +02:00
XMRig
9f3591ae0d v6.23.1-dev 2025-06-16 21:29:17 +07:00
XMRig
6bbbcc71f1 Merge branch 'master' into dev 2025-06-16 21:28:48 +07:00
XMRig
e5a7a69cc0 v6.23.0 2025-06-16 21:00:42 +07:00
XMRig
f354b85a7b Merge branch 'dev' 2025-06-16 21:00:12 +07:00
xmrig
5ed8d79574 Update CHANGELOG.md 2025-06-16 20:46:33 +07:00
XMRig
fc395a5800 Update ARM CPUs database. 2025-06-16 19:54:08 +07:00
XMRig
9138690126 v6.23.0-dev 2025-06-16 02:05:43 +07:00
XMRig
d58061c903 Add detection for _aligned_malloc. 2025-06-15 20:06:19 +07:00
XMRig
3b863cf88f Fixed __umul128 for MSVC ARM64. 2025-06-15 04:58:03 +07:00
XMRig
9c7468df64 Fixed user agent string. 2025-06-15 00:21:23 +07:00
xmrig
a18fa269a6 Merge pull request #3666 from SChernykh/dev
Better detection of aligned malloc functions
2025-06-14 23:09:05 +07:00
SChernykh
bcc5581535 Better detection of aligned malloc functions 2025-06-14 18:00:27 +02:00
XMRig
dba336aa04 Update hwloc for MSVC. 2025-06-14 22:11:33 +07:00
XMRig
3ff41f7c94 Fixed UTF-8 paths support for the config file with Clang compiler on Windows ARM64. 2025-06-14 15:38:25 +07:00
XMRig
faa3d55123 Remove deprecated -Ofast for Clang. 2025-06-13 21:53:03 +07:00
XMRig
9e7cf69ac3 Detect CPU name and AES instructions on Windows ARM64. 2025-06-13 21:02:10 +07:00
XMRig
57a4998ae2 Fix Linux build. 2025-06-13 04:05:30 +07:00
XMRig
34b4448a81 Split BasicCpuInfo_arm. 2025-06-13 03:57:13 +07:00
XMRig
650d794fb1 Initial Windows ARM64 support via MSYS2. 2025-06-13 03:00:34 +07:00
XMRig
064a61988a Update deps scripts. 2025-06-12 00:52:49 +07:00
xmrig
2ab7f85ccd Merge pull request #3665 from SChernykh/dev
Tweaked autoconfig for AMD CPUs with < 2 MB L3 cache per thread
2025-06-11 23:40:46 +07:00
SChernykh
e4c30eb0dd Tweaked autoconfig for AMD CPUs with < 2 MB L3 cache per thread 2025-06-11 18:34:50 +02:00
XMRig
d4e57d9427 Fix LLHTTP_EXPORT 2025-06-10 03:13:34 +07:00
XMRig
9a71190ca1 Update llhttp to 9.3.0 2025-06-09 03:02:26 +07:00
XMRig
a7dcbb143e Bump minimum CMake version to 3.10 2025-06-08 23:23:40 +07:00
XMRig
a6a0f80b12 Fix header path. 2025-06-06 14:42:49 +07:00
XMRig
682834b87d Universal fix for NaN and Infinity in JSON output 2025-06-06 14:36:21 +07:00
XMRig
184d6100dc Update rapidjson 2025-06-05 01:22:31 +07:00
XMRig
0c52d789a9 v6.22.4-dev 2025-06-04 18:59:39 +07:00
XMRig
e33334f11a Merge branch 'master' into dev 2025-06-04 18:58:55 +07:00
XMRig
6184224a66 v6.22.3 2025-06-04 18:11:51 +07:00
XMRig
f499155032 Merge branch 'dev' 2025-06-04 18:11:14 +07:00
xmrig
a32b688dcf Update CHANGELOG.md 2025-06-04 01:47:57 +07:00
XMRig
35b334d58a Fixed compile warning. 2025-05-31 01:12:00 +07:00
XMRig
33623492fe Allow run generate_cl.js from the scripts directory. 2025-05-30 01:47:08 +07:00
xmrig
77009bd0d1 Merge pull request #3662 from ybh1998/keccak_f800
Fix type of `keccak_f800`
2025-05-30 01:04:22 +07:00
ybh1998
46572dcb3d Fix type of keccak_f800 2025-05-30 01:57:08 +08:00
xmrig
0d9af3347d Merge pull request #3652 from SChernykh/dev
Fixed HttpsClient::flush logic
2025-04-17 16:12:31 +07:00
SChernykh
d24e13e605 Fixed HttpsClient::flush logic
- Don't write empty buffers
- Don't write if an error was returned
2025-04-17 10:32:14 +02:00
xmrig
36fdfa2694 Merge pull request #3646 from SChernykh/dev
Optimized autoconfig for AMD CPUs with < 2 MB L3 cache per thread
2025-03-22 18:36:09 +07:00
SChernykh
6cfc02d24f Optimized autoconfig for AMD CPUs with < 2 MB L3 cache per thread 2025-03-22 11:34:23 +01:00
XMRig
16ecb8f085 Allow use of the previous CUDA plugin version with a warning. 2024-12-23 23:14:06 +07:00
xmrig
0229c65232 Merge pull request #3605 from SChernykh/dev
CUDA backend: update RandomX dataset when it changes
2024-12-18 22:36:08 +07:00
SChernykh
4a13a8a75c CUDA backend: update RandomX dataset when it changes 2024-12-18 13:45:10 +01:00
XMRig
cd2fd9d7a6 Simplified getting PCI topology for the OpenCL backend. 2024-11-08 13:03:35 +07:00
XMRig
064cd3ef20 Fixed and simplified OpenCL GPU type detection. 2024-11-08 07:09:35 +07:00
XMRig
e8bbd134f9 v6.22.3-dev 2024-11-03 15:06:54 +07:00
XMRig
cf86a1e05c Merge branch 'master' into dev 2024-11-03 15:06:22 +07:00
217 changed files with 13975 additions and 28303 deletions

View File

@@ -1,258 +0,0 @@
on:
push:
tags:
- 'v*'
name: Create release and build artifacts
jobs:
build_win:
name: Build Windows artifacts
runs-on: windows-2019
steps:
- name: Checkout code
uses: actions/checkout@master
- name: Checkout deps
run: git clone https://github.com/xmrig/xmrig-deps.git
- name: Build project on Windows
run: |
cmake . -G "MinGW Makefiles" -DXMRIG_DEPS=xmrig-deps\gcc\x64
make -j2
copy src\config.json .
copy bin\WinRing0\WinRing0x64.sys .
7z a -tzip -mx windows_build.zip xmrig.exe config.json WinRing0x64.sys
- name: Upload Windows build artifacts
uses: actions/upload-artifact@v4
with:
name: windows_build
path: windows_build.zip
build_lin:
name: Build Ubuntu artifacts
runs-on: ubuntu-22.04
steps:
- name: Prepare Ubuntu tools
run: |
sudo apt update
sudo apt install -y git build-essential cmake libuv1-dev libssl-dev libhwloc-dev
- name: Checkout code
uses: actions/checkout@master
- name: Build project on Ubuntu
run: |
cmake .
make -j$(nproc)
cp src/config.json .
tar cfz ubuntu_build.tar.gz xmrig config.json
- name: Upload Ubuntu build artifacts
uses: actions/upload-artifact@v4
with:
name: ubuntu_build
path: ubuntu_build.tar.gz
build_macos:
name: Build MacOS artifacts
runs-on: macos-latest
steps:
- name: Prepare MacOS tools
run: |
brew install cmake libuv openssl hwloc
- name: Checkout code
uses: actions/checkout@master
- name: Build hwloc on MacOS
run: |
curl -O https://download.open-mpi.org/release/hwloc/v2.1/hwloc-2.1.0.tar.bz2
tar xjf hwloc-2.1.0.tar.bz2
cd hwloc-2.1.0
./configure --disable-shared --enable-static --disable-io --disable-libxml2
make -j$(sysctl -n hw.logicalcpu)
cd ..
- name: Build project on MacOS
run: |
cmake . -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl -DHWLOC_INCLUDE_DIR=hwloc-2.1.0/include -DHWLOC_LIBRARY=hwloc-2.1.0/hwloc/.libs/libhwloc.a
make -j$(sysctl -n hw.logicalcpu)
cp src/config.json .
tar cfz macos_build.tar.gz xmrig config.json
- name: Upload MacOS build artifacts
uses: actions/upload-artifact@v4
with:
name: macos_build
path: macos_build.tar.gz
build_macos_intel:
name: Build MacOS (Intel) artifacts
runs-on: macos-13
steps:
- name: Prepare MacOS tools
run: |
brew install cmake libuv openssl hwloc
- name: Checkout code
uses: actions/checkout@master
- name: Build hwloc on MacOS
run: |
curl -O https://download.open-mpi.org/release/hwloc/v2.1/hwloc-2.1.0.tar.bz2
tar xjf hwloc-2.1.0.tar.bz2
cd hwloc-2.1.0
./configure --disable-shared --enable-static --disable-io --disable-libxml2
make -j$(sysctl -n hw.logicalcpu)
cd ..
- name: Build project on MacOS
run: |
cmake . -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl -DHWLOC_INCLUDE_DIR=hwloc-2.1.0/include -DHWLOC_LIBRARY=hwloc-2.1.0/hwloc/.libs/libhwloc.a
make -j$(sysctl -n hw.logicalcpu)
cp src/config.json .
tar cfz macos_build_intel.tar.gz xmrig config.json
- name: Upload MacOS build artifacts
uses: actions/upload-artifact@v4
with:
name: macos_build_intel
path: macos_build_intel.tar.gz
build_lin_ub12:
name: Build Ubuntu 12.04 artifacts
runs-on: ubuntu-latest
steps:
- name: Run build inside docker
run: |
mkdir /tmp/docker
cat >/tmp/docker/script.sh <<EOF
set -x
sed -i -r 's/(archive|security).ubuntu.com/old-releases.ubuntu.com/g' /etc/apt/sources.list
apt-get update
apt-get install -y python-software-properties
add-apt-repository -y ppa:ubuntu-toolchain-r/test
apt-get update
apt-get install -y git build-essential automake libtool autoconf wget libgmp-dev libmpfr-dev texinfo bison flex gcc-9 g++-9 curl
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 60 --slave /usr/bin/g++ g++ /usr/bin/g++-9
curl -sSL https://cmake.org/files/v3.27/cmake-3.27.9-linux-x86_64.tar.gz | tar -xzC /opt
git clone --depth 1 git://sourceware.org/git/binutils-gdb.git /tmp/binutils-gdb
(cd /tmp/binutils-gdb && git checkout binutils-2_38 && CC=gcc ./configure && make -j$(nproc) && make install)
git clone https://github.com/MoneroOcean/xmrig.git
cd xmrig
git checkout $GITHUB_REF_NAME
(cd scripts && ./build_deps.sh && cd ..)
/opt/cmake-3.27.9-linux-x86_64/bin/cmake . -DXMRIG_DEPS=scripts/deps
make -j$(nproc)
cp src/config.json .
tar cfz /tmp/docker/ubuntu12_build.tar.gz xmrig config.json
EOF
chmod +x /tmp/docker/script.sh
docker run -i -v /tmp/docker:/tmp/docker ubuntu:12.04 /bin/bash -c /tmp/docker/script.sh
- name: Upload Ubuntu 12.04 build artifacts
uses: actions/upload-artifact@v4
with:
name: ubuntu12_build
path: /tmp/docker/ubuntu12_build.tar.gz
deploy:
needs: [build_win, build_lin, build_macos, build_macos_intel, build_lin_ub12]
name: Create release and upload artifacts
runs-on: ubuntu-latest
steps:
- name: Create Release
id: create_release
uses: actions/create-release@v1.0.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: Release ${{ github.ref }}
draft: false
prerelease: false
- name: Set version
id: version
run: echo ::set-output name=VERSION::$GITHUB_REF_NAME
- name: Download Windows build artifacts
uses: actions/download-artifact@v4
with:
name: windows_build
- name: Download Ubuntu build artifacts
uses: actions/download-artifact@v4
with:
name: ubuntu_build
- name: Download MacOS build artifacts
uses: actions/download-artifact@v4
with:
name: macos_build
- name: Download MacOS (Intel) build artifacts
uses: actions/download-artifact@v4
with:
name: macos_build_intel
- name: Download Ubuntu 12.04 build artifacts
uses: actions/download-artifact@v4
with:
name: ubuntu12_build
- name: Upload Windows build release asset
uses: actions/upload-release-asset@v1.0.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: windows_build.zip
asset_name: xmrig-${{steps.version.outputs.VERSION}}-win64.zip
asset_content_type: application/zip
- name: Upload Ubuntu build release asset
uses: actions/upload-release-asset@v1.0.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ubuntu_build.tar.gz
asset_name: xmrig-${{steps.version.outputs.VERSION}}-lin64.tar.gz
asset_content_type: application/zip
- name: Upload MacOS build release asset
uses: actions/upload-release-asset@v1.0.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: macos_build.tar.gz
asset_name: xmrig-${{steps.version.outputs.VERSION}}-mac64.tar.gz
asset_content_type: application/zip
- name: Upload MacOS (Intel) build release asset
uses: actions/upload-release-asset@v1.0.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: macos_build_intel.tar.gz
asset_name: xmrig-${{steps.version.outputs.VERSION}}-mac-intel.tar.gz
asset_content_type: application/zip
- name: Upload Ubuntu 12.04 build release asset
uses: actions/upload-release-asset@v1.0.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ubuntu12_build.tar.gz
asset_name: xmrig-${{steps.version.outputs.VERSION}}-lin64-compat.tar.gz
asset_content_type: application/zip
- name: Update xmrig_setup repo
run: |
git clone https://$GITHUB_ACTOR:${{secrets.xmrig_setup_key}}@github.com/MoneroOcean/xmrig_setup.git
cd xmrig_setup
git config user.name MoneroOcean
git config user.email support@moneroocean.stream
cp ../ubuntu12_build.tar.gz xmrig.tar.gz
cp ../windows_build.zip xmrig.zip
unzip xmrig.zip
zip -u offline_miner_setup.zip xmrig.exe config.json WinRing0x64.sys
git commit -m "xmrig "$GITHUB_REF_NAME" based release" xmrig.tar.gz xmrig.zip offline_miner_setup.zip
git push
cd ..
- name: Update hiveos repo
run: |
git clone https://$GITHUB_ACTOR:${{secrets.xmrig_setup_key}}@github.com/MoneroOcean/hiveos.git
cd hiveos
git config user.name MoneroOcean
git config user.email support@moneroocean.stream
tar xf ../ubuntu12_build.tar.gz
mv xmrig mo_xmrig/xmrig
mv config.json mo_xmrig/config_global.json
export VER=$GITHUB_REF_NAME
export VER=${VER//-/_}
tar -zcvf mo_xmrig-$VER.tar.gz mo_xmrig
git add mo_xmrig-$VER.tar.gz mo_xmrig/xmrig mo_xmrig/config_global.json
git commit -m "xmrig "$GITHUB_REF_NAME" based release" mo_xmrig-$VER.tar.gz
git push

View File

@@ -1,32 +0,0 @@
on: push
name: Test builds
jobs:
build_win:
name: Windows build
runs-on: windows-2019
steps:
- name: Checkout code
uses: actions/checkout@master
- name: Checkout deps
run: git clone https://github.com/xmrig/xmrig-deps.git
- name: Build project on Windows
run: |
cmake . -G "MinGW Makefiles" -DXMRIG_DEPS=xmrig-deps\gcc\x64
make -j2
build_lin:
name: Ubuntu build
runs-on: ubuntu-latest
steps:
- name: Prepare Ubuntu tools
run: |
sudo apt update
sudo apt install -y git build-essential cmake libuv1-dev libssl-dev libhwloc-dev
- name: Checkout code
uses: actions/checkout@master
- name: Build project on Ubuntu
run: |
cmake .
make -j$(nproc)

View File

@@ -1,3 +1,19 @@
# v6.24.0
- [#3671](https://github.com/xmrig/xmrig/pull/3671) Fixed detection of L2 cache size for some complex NUMA topologies.
- [#3674](https://github.com/xmrig/xmrig/pull/3674) Fixed ARMv7 build.
- [#3677](https://github.com/xmrig/xmrig/pull/3677) Fixed auto-config for AMD CPUs with less than 2 MB L3 cache per thread.
- [#3678](https://github.com/xmrig/xmrig/pull/3678) Improved IPv6 support: the new default settings use IPv6 equally with IPv4.
# v6.23.0
- [#3668](https://github.com/xmrig/xmrig/issues/3668) Added support for Windows ARM64.
- [#3665](https://github.com/xmrig/xmrig/pull/3665) Tweaked auto-config for AMD CPUs with < 2 MB L3 cache per thread.
# v6.22.3
- [#3605](https://github.com/xmrig/xmrig/pull/3605) CUDA backend: added missing RandomX dataset update.
- [#3646](https://github.com/xmrig/xmrig/pull/3646) Optimized auto-config for AMD CPUs with less than 2 MB L3 cache per thread.
- [#3652](https://github.com/xmrig/xmrig/pull/3652) Fixed possible crash when submitting RandomX benchmark.
- [#3662](https://github.com/xmrig/xmrig/pull/3662) Fixed OpenCL kernel compilation error on some platforms.
# v6.22.2
- [#3569](https://github.com/xmrig/xmrig/pull/3569) Fixed corrupted API output in some rare conditions.
- [#3571](https://github.com/xmrig/xmrig/pull/3571) Fixed number of threads on the new Intel Core Ultra CPUs.

View File

@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.5)
cmake_minimum_required(VERSION 3.10)
project(xmrig)
option(WITH_HWLOC "Enable hwloc support" ON)
@@ -6,7 +6,6 @@ option(WITH_CN_LITE "Enable CryptoNight-Lite algorithms family" ON)
option(WITH_CN_HEAVY "Enable CryptoNight-Heavy algorithms family" ON)
option(WITH_CN_PICO "Enable CryptoNight-Pico algorithm" ON)
option(WITH_CN_FEMTO "Enable CryptoNight-UPX2 algorithm" ON)
option(WITH_CN_GPU "Enable CryptoNight-GPU algorithm" ON)
option(WITH_RANDOMX "Enable RandomX algorithms family" ON)
option(WITH_ARGON2 "Enable Argon2 algorithms family" ON)
option(WITH_KAWPOW "Enable KawPow algorithms family" ON)
@@ -26,7 +25,6 @@ option(WITH_NVML "Enable NVML (NVIDIA Management Library) support (on
option(WITH_ADL "Enable ADL (AMD Display Library) or sysfs support (only if OpenCL backend enabled)" ON)
option(WITH_STRICT_CACHE "Enable strict checks for OpenCL cache" ON)
option(WITH_INTERLEAVE_DEBUG_LOG "Enable debug log for threads interleave" OFF)
option(WITH_MO_BENCHMARK "Enable Benchmark module and algo-perf feature (for MoneroOcean)" ON)
option(WITH_PROFILING "Enable profiling for developers" OFF)
option(WITH_SSE4_1 "Enable SSE 4.1 for Blake2" ON)
option(WITH_AVX2 "Enable AVX2 for Blake2" ON)
@@ -131,17 +129,8 @@ set(SOURCES_CRYPTO
src/crypto/common/MemoryPool.cpp
src/crypto/common/Nonce.cpp
src/crypto/common/VirtualMemory.cpp
src/crypto/flex/flex.cpp
src/crypto/flex/flex_keccak.c
)
if (WITH_MO_BENCHMARK)
list(APPEND SOURCES
src/core/MoBenchmark.cpp
)
add_definitions(/DXMRIG_FEATURE_MO_BENCHMARK)
endif()
if (CMAKE_C_COMPILER_ID MATCHES GNU)
set_source_files_properties(src/crypto/cn/CnHash.cpp PROPERTIES COMPILE_FLAGS "-Ofast -fno-tree-vectorize")
endif()
@@ -209,7 +198,6 @@ add_definitions(-D__STDC_FORMAT_MACROS -DUNICODE -D_FILE_OFFSET_BITS=64)
find_package(UV REQUIRED)
include(cmake/flags.cmake)
include(cmake/cn-gpu.cmake)
include(cmake/randomx.cmake)
include(cmake/argon2.cmake)
include(cmake/kawpow.cmake)
@@ -252,7 +240,10 @@ add_executable(${CMAKE_PROJECT_NAME} ${HEADERS} ${SOURCES} ${SOURCES_OS} ${HEADE
target_link_libraries(${CMAKE_PROJECT_NAME} ${XMRIG_ASM_LIBRARY} ${OPENSSL_LIBRARIES} ${UV_LIBRARIES} ${EXTRA_LIBS} ${CPUID_LIB} ${ARGON2_LIBRARY} ${ETHASH_LIBRARY} ${GHOSTRIDER_LIBRARY})
if (WIN32)
add_custom_command(TARGET ${CMAKE_PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/bin/WinRing0/WinRing0x64.sys" $<TARGET_FILE_DIR:${CMAKE_PROJECT_NAME}>)
if (NOT ARM_TARGET)
add_custom_command(TARGET ${CMAKE_PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/bin/WinRing0/WinRing0x64.sys" $<TARGET_FILE_DIR:${CMAKE_PROJECT_NAME}>)
endif()
add_custom_command(TARGET ${CMAKE_PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/scripts/benchmark_1M.cmd" $<TARGET_FILE_DIR:${CMAKE_PROJECT_NAME}>)
add_custom_command(TARGET ${CMAKE_PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/scripts/benchmark_10M.cmd" $<TARGET_FILE_DIR:${CMAKE_PROJECT_NAME}>)
add_custom_command(TARGET ${CMAKE_PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/scripts/pool_mine_example.cmd" $<TARGET_FILE_DIR:${CMAKE_PROJECT_NAME}>)
@@ -261,5 +252,5 @@ if (WIN32)
endif()
if (CMAKE_CXX_COMPILER_ID MATCHES Clang AND CMAKE_BUILD_TYPE STREQUAL Release AND NOT CMAKE_GENERATOR STREQUAL Xcode)
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_STRIP} ${CMAKE_PROJECT_NAME})
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_STRIP} "$<TARGET_FILE:${CMAKE_PROJECT_NAME}>")
endif()

View File

@@ -1,21 +1,21 @@
# XMRig
[![Github All Releases](https://img.shields.io/github/downloads/xmrig/xmrig/total.svg)](https://github.com/MoneroOcean/xmrig/releases)
[![GitHub release](https://img.shields.io/github/release/xmrig/xmrig/all.svg)](https://github.com/MoneroOcean/xmrig/releases)
[![GitHub Release Date](https://img.shields.io/github/release-date/xmrig/xmrig.svg)](https://github.com/MoneroOcean/xmrig/releases)
[![GitHub license](https://img.shields.io/github/license/xmrig/xmrig.svg)](https://github.com/MoneroOcean/xmrig/blob/master/LICENSE)
[![GitHub stars](https://img.shields.io/github/stars/xmrig/xmrig.svg)](https://github.com/MoneroOcean/xmrig/stargazers)
[![GitHub forks](https://img.shields.io/github/forks/xmrig/xmrig.svg)](https://github.com/MoneroOcean/xmrig/network)
[![Github All Releases](https://img.shields.io/github/downloads/xmrig/xmrig/total.svg)](https://github.com/xmrig/xmrig/releases)
[![GitHub release](https://img.shields.io/github/release/xmrig/xmrig/all.svg)](https://github.com/xmrig/xmrig/releases)
[![GitHub Release Date](https://img.shields.io/github/release-date/xmrig/xmrig.svg)](https://github.com/xmrig/xmrig/releases)
[![GitHub license](https://img.shields.io/github/license/xmrig/xmrig.svg)](https://github.com/xmrig/xmrig/blob/master/LICENSE)
[![GitHub stars](https://img.shields.io/github/stars/xmrig/xmrig.svg)](https://github.com/xmrig/xmrig/stargazers)
[![GitHub forks](https://img.shields.io/github/forks/xmrig/xmrig.svg)](https://github.com/xmrig/xmrig/network)
XMRig is a high performance, open source, cross platform RandomX, KawPow, CryptoNight and [GhostRider](https://github.com/xmrig/xmrig/tree/master/src/crypto/ghostrider#readme) unified CPU/GPU miner and [RandomX benchmark](https://xmrig.com/benchmark). Official binaries are available for Windows, Linux, macOS and FreeBSD.
## Mining backends
- **CPU** (x86/x64/ARMv7/ARMv8)
- **OpenCL** for AMD GPUs.
- **CUDA** for NVIDIA GPUs via external [CUDA plugin](https://github.com/MoneroOcean/xmrig-cuda).
- **CUDA** for NVIDIA GPUs via external [CUDA plugin](https://github.com/xmrig/xmrig-cuda).
## Download
* **[Binary releases](https://github.com/MoneroOcean/xmrig/releases)**
* **[Binary releases](https://github.com/xmrig/xmrig/releases)**
* **[Build from source](https://xmrig.com/docs/miner/build)**
## Usage

View File

@@ -1,31 +0,0 @@
if (WITH_CN_GPU AND CMAKE_SIZEOF_VOID_P EQUAL 8)
add_definitions(/DXMRIG_ALGO_CN_GPU)
if (XMRIG_ARM)
list(APPEND SOURCES_CRYPTO
src/crypto/cn/gpu/cn_gpu_arm.cpp
)
if (CMAKE_CXX_COMPILER_ID MATCHES GNU OR CMAKE_CXX_COMPILER_ID MATCHES Clang)
set_source_files_properties(src/crypto/cn/gpu/cn_gpu_arm.cpp PROPERTIES COMPILE_FLAGS "-O3")
endif()
else()
list(APPEND SOURCES_CRYPTO
src/crypto/cn/gpu/cn_gpu_avx.cpp
src/crypto/cn/gpu/cn_gpu_ssse3.cpp
)
if (CMAKE_CXX_COMPILER_ID MATCHES GNU OR CMAKE_CXX_COMPILER_ID MATCHES Clang)
set_source_files_properties(src/crypto/cn/gpu/cn_gpu_avx.cpp PROPERTIES COMPILE_FLAGS "-O3 -mavx2")
set_source_files_properties(src/crypto/cn/gpu/cn_gpu_ssse3.cpp PROPERTIES COMPILE_FLAGS "-O3")
elseif (CMAKE_CXX_COMPILER_ID MATCHES Intel)
set_source_files_properties(src/crypto/cn/gpu/cn_gpu_avx.cpp PROPERTIES COMPILE_FLAGS "-O3 -mavx2")
set_source_files_properties(src/crypto/cn/gpu/cn_gpu_ssse3.cpp PROPERTIES COMPILE_FLAGS "-O1")
elseif (CMAKE_CXX_COMPILER_ID MATCHES MSVC)
set_source_files_properties(src/crypto/cn/gpu/cn_gpu_avx.cpp PROPERTIES COMPILE_FLAGS "/arch:AVX")
endif()
endif()
else()
remove_definitions(/DXMRIG_ALGO_CN_GPU)
endif()

View File

@@ -29,6 +29,8 @@ else()
set(WITH_VAES OFF)
endif()
add_definitions(-DRAPIDJSON_WRITE_DEFAULT_FLAGS=6) # rapidjson::kWriteNanAndInfFlag | rapidjson::kWriteNanAndInfNullFlag
if (ARM_V8)
set(ARM_TARGET 8)
elseif (ARM_V7)
@@ -36,7 +38,7 @@ elseif (ARM_V7)
endif()
if (NOT ARM_TARGET)
if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64|arm64|armv8-a)$")
if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64|arm64|ARM64|armv8-a)$")
set(ARM_TARGET 8)
elseif (CMAKE_SYSTEM_PROCESSOR MATCHES "^(armv7|armv7f|armv7s|armv7k|armv7-a|armv7l|armv7ve)$")
set(ARM_TARGET 7)
@@ -49,7 +51,7 @@ if (ARM_TARGET AND ARM_TARGET GREATER 6)
message(STATUS "Use ARM_TARGET=${ARM_TARGET} (${CMAKE_SYSTEM_PROCESSOR})")
if (ARM_TARGET EQUAL 8)
if (ARM_TARGET EQUAL 8 AND (CMAKE_CXX_COMPILER_ID MATCHES GNU OR CMAKE_CXX_COMPILER_ID MATCHES Clang))
CHECK_CXX_COMPILER_FLAG(-march=armv8-a+crypto XMRIG_ARM_CRYPTO)
if (XMRIG_ARM_CRYPTO)

View File

@@ -26,7 +26,7 @@ if (CMAKE_CXX_COMPILER_ID MATCHES GNU)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${ARM8_CXX_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARM8_CXX_FLAGS} -flax-vector-conversions")
elseif (ARM_TARGET EQUAL 7)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv7-a -mfpu=neon")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv7-a -mfpu=neon -flax-vector-conversions")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=armv7-a -mfpu=neon -flax-vector-conversions")
else()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes")
@@ -63,10 +63,10 @@ elseif (CMAKE_CXX_COMPILER_ID MATCHES MSVC)
elseif (CMAKE_CXX_COMPILER_ID MATCHES Clang)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast -funroll-loops -fmerge-all-constants")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -funroll-loops -fmerge-all-constants")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fexceptions -fno-rtti -Wno-missing-braces")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -funroll-loops -fmerge-all-constants")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fexceptions -fno-rtti")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -funroll-loops -fmerge-all-constants")
if (ARM_TARGET EQUAL 8)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${ARM8_CXX_FLAGS}")
@@ -84,10 +84,9 @@ elseif (CMAKE_CXX_COMPILER_ID MATCHES Clang)
endif()
endif()
if (BUILD_STATIC)
if ((WIN32 AND ARM_TARGET) OR BUILD_STATIC)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
endif()
endif()
if (NOT WIN32)

View File

@@ -20,7 +20,6 @@ else()
endif()
endif()
if (XMRIG_OS_WIN)
add_definitions(-DWIN32 -DXMRIG_OS_WIN)
elseif(XMRIG_OS_APPLE)

View File

@@ -1,4 +1,18 @@
if (WITH_RANDOMX)
include(CheckSymbolExists)
if (WIN32)
check_symbol_exists(_aligned_malloc "stdlib.h" HAVE_ALIGNED_MALLOC)
if (HAVE_ALIGNED_MALLOC)
add_compile_definitions(HAVE_ALIGNED_MALLOC)
endif()
else()
check_symbol_exists(posix_memalign "stdlib.h" HAVE_POSIX_MEMALIGN)
if (HAVE_POSIX_MEMALIGN)
add_compile_definitions(HAVE_POSIX_MEMALIGN)
endif()
endif()
add_definitions(/DXMRIG_ALGO_RANDOMX)
set(WITH_ARGON2 ON)
@@ -40,13 +54,6 @@ if (WITH_RANDOMX)
src/crypto/rx/RxDataset.cpp
src/crypto/rx/RxQueue.cpp
src/crypto/rx/RxVm.cpp
### Removed useless includes
src/crypto/randomx/panthera/sha256.c
src/crypto/randomx/panthera/KangarooTwelve.c
src/crypto/randomx/panthera/KeccakP-1600-reference.c
src/crypto/randomx/panthera/KeccakSpongeWidth1600.c
src/crypto/randomx/panthera/yespower-opt.c
)
if (WITH_ASM AND CMAKE_C_COMPILER_ID MATCHES MSVC)

View File

@@ -27,7 +27,6 @@ Option `coin` useful for pools without [algorithm negotiation](https://xmrig.com
| `cn/zls` | 2 MB | 2.14.0+ | CryptoNight variant 2 with 3/4 iterations. | |
| `cn/double` | 2 MB | 2.14.0+ | CryptoNight variant 2 with double iterations. | |
| `cn/r` | 2 MB | 2.13.0+ | CryptoNightR (Monero's variant 4). | |
| `cn/gpu` | 2 MB | 2.11.0+ | CryptoNight-GPU. | |
| `cn-pico` | 256 KB | 2.10.0+ | CryptoNight-Pico. | |
| `cn/half` | 2 MB | 2.9.0+ | CryptoNight variant 2 with half iterations. | |
| `cn/2` | 2 MB | 2.8.0+ | CryptoNight variant 2. | |

View File

@@ -6,7 +6,6 @@
* **`-DWITH_CN_LITE=OFF`** disable all CryptoNight-Lite algorithms (`cn-lite/0`, `cn-lite/1`).
* **`-DWITH_CN_HEAVY=OFF`** disable all CryptoNight-Heavy algorithms (`cn-heavy/0`, `cn-heavy/xhv`, `cn-heavy/tube`).
* **`-DWITH_CN_PICO=OFF`** disable CryptoNight-Pico algorithm (`cn-pico`).
* **`-DWITH_CN_GPU=OFF`** disable CryptoNight-GPU algorithm (`cn/gpu`).
* **`-DWITH_RANDOMX=OFF`** disable RandomX algorithms (`rx/loki`, `rx/wow`).
* **`-DWITH_ARGON2=OFF`** disable Argon2 algorithms (`argon2/chukwa`, `argon2/wrkz`).

View File

@@ -1,8 +1,8 @@
#!/bin/sh -e
HWLOC_VERSION_MAJOR="2"
HWLOC_VERSION_MINOR="11"
HWLOC_VERSION_PATCH="2"
HWLOC_VERSION_MINOR="12"
HWLOC_VERSION_PATCH="1"
HWLOC_VERSION="${HWLOC_VERSION_MAJOR}.${HWLOC_VERSION_MINOR}.${HWLOC_VERSION_PATCH}"

View File

@@ -1,6 +1,6 @@
#!/bin/sh -e
OPENSSL_VERSION="3.0.15"
OPENSSL_VERSION="3.0.16"
mkdir -p deps
mkdir -p deps/include

View File

@@ -1,6 +1,6 @@
#!/bin/sh -e
UV_VERSION="1.49.2"
UV_VERSION="1.51.0"
mkdir -p deps
mkdir -p deps/include

View File

@@ -6,7 +6,6 @@ const fs = require('fs');
const path = require('path');
const { text2h, text2h_bundle, addIncludes } = require('./js/opencl');
const { opencl_minify } = require('./js/opencl_minify');
const cwd = process.cwd();
function cn()
@@ -50,8 +49,6 @@ function rx()
'randomx_constants_monero.h',
'randomx_constants_wow.h',
'randomx_constants_arqma.h',
'randomx_constants_equilibria.h',
'randomx_constants_keva.h',
'randomx_constants_graft.h',
'aes.cl',
'blake2b.cl',
@@ -78,28 +75,24 @@ function kawpow()
fs.writeFileSync('kawpow_dag_cl.h', text2h(kawpow_dag, 'xmrig', 'kawpow_dag_cl'));
}
for (let i = 0; i < 2; i++) {
if (fs.existsSync('src/backend/opencl/cl/OclSource.h')) {
break;
}
function cn_gpu()
{
const cn_gpu = opencl_minify(addIncludes('cryptonight_gpu.cl', [ 'wolf-aes.cl', 'keccak.cl' ]));
// fs.writeFileSync('cryptonight_gpu_gen.cl', cn_gpu);
fs.writeFileSync('cryptonight_gpu_cl.h', text2h(cn_gpu, 'xmrig', 'cryptonight_gpu_cl'));
process.chdir('..');
}
process.chdir(path.resolve('src/backend/opencl/cl'));
process.chdir(path.resolve('src/backend/opencl/cl/cn'));
const cwd = process.cwd();
process.chdir(path.resolve(cwd, 'cn'));
cn();
cn_r();
cn_gpu();
process.chdir(cwd);
process.chdir(path.resolve('src/backend/opencl/cl/rx'));
process.chdir(path.resolve(cwd, 'rx'));
rx();
process.chdir(cwd);
process.chdir(path.resolve('src/backend/opencl/cl/kawpow'));
process.chdir(path.resolve(cwd, 'kawpow'));
kawpow();

View File

@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.5)
cmake_minimum_required(VERSION 3.10)
project(argon2 C)
set(CMAKE_C_STANDARD 99)

View File

@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.5)
cmake_minimum_required(VERSION 3.10)
project (hwloc C)
include_directories(include)

View File

@@ -1,5 +1,5 @@
Copyright © 2009 CNRS
Copyright © 2009-2024 Inria. All rights reserved.
Copyright © 2009-2025 Inria. All rights reserved.
Copyright © 2009-2013 Université Bordeaux
Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
Copyright © 2020 Hewlett Packard Enterprise. All rights reserved.
@@ -17,6 +17,52 @@ bug fixes (and other actions) for each version of hwloc since version
0.9.
Version 2.12.1
--------------
* Add hwloc-calc's --default-nodes option to hwloc-bind and hwloc-info.
* Improve the --best-memattr "default" fallback, try to use "default"
memory nodes, and add verbose messages and warnings if some
performance info are incomplete or missing.
Thanks to Antoine Morvan for the report.
* Fix CPU and memory binding on different locations,
thanks to Antoine Morvan for the report.
* Add HWLOC_LOCAL_NUMANODE_FLAG_INTERSECT_LOCALITY and enable it by
default in hwloc-calc --local-memory for finding local NUMA nodes
that do not exactly match input locations.
Thanks to Antoine Morvan for the report.
* Fix a possible crash in the x86 backend when Qemu is configured to
expose multicore/thread CPUs that are actually single-core/thread.
Thanks to Georg Pfuetzenreuter.
Version 2.12.0
--------------
* Add hwloc_topology_get_default_nodeset() for the set of default
NUMA nodes.
- hwloc-calc now has --default-nodes option.
* Rework oneAPI LevelZero support to use zesInit() and avoid the need
to set ZES_ENABLE_SYSMAN=1 in the environment.
- zesDriverGetDeviceByUuidExp() is now required in the L0 runtime.
- ZES/Sysman variants were added in hwloc/levelzero.h to specifically
handle ZES/Sysman device handles.
* Fix the locality of AMD GPU partitions, thanks to Edgar Leon for
reporting and debugging the issue.
* Better detect Cray Slingshot NICs, thanks to Edgar Leon.
* Add support for Die objects and Module groups on Windows.
* Only filter-out Dies that are identical to their Packages
when it applies to all Dies.
* Improve hwloc-calc to handle CPU-less NUMA nodes or platforms with
heterogeneous memory without requiring --nodeset-output.
* hwloc-calc now accepts counting/listing cpukinds and memory tiers
with -N and -I cpukind/memorytier.
* The systemd-dbus-api output of hwloc-calc has changed, and
--nodeset-output-format was added, to support NUMA node outputs.
Thanks to Pierre Neyron.
* Update NVLink bandwidth and CUDA capabilities up to NVIDIA Blackwell.
* Fix some NUMA syscalls on Linux for platforms with old libc headers.
* Some minor fixes in distances.
Version 2.11.2
--------------
* Add missing CPU info attrs on aarch64 on Linux.

View File

@@ -8,8 +8,8 @@
# Please update HWLOC_VERSION* in contrib/windows/hwloc_config.h too.
major=2
minor=11
release=2
minor=12
release=1
# greek is used for alpha or beta release tags. If it is non-empty,
# it will be appended to the version number. It does not have to be
@@ -22,7 +22,7 @@ greek=
# The date when this release was created
date="Sep 26, 2024"
date="May 12, 2025"
# If snapshot=1, then use the value from snapshot_version as the
# entire hwloc version (i.e., ignore major, minor, release, and
@@ -41,6 +41,6 @@ snapshot_version=${major}.${minor}.${release}${greek}-git
# 2. Version numbers are described in the Libtool current:revision:age
# format.
libhwloc_so_version=23:1:8
libhwloc_so_version=25:0:10
# Please also update the <TargetName> lines in contrib/windows/libhwloc.vcxproj

View File

@@ -1,6 +1,6 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2024 Inria. All rights reserved.
* Copyright © 2009-2025 Inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux
* Copyright © 2009-2020 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
@@ -112,7 +112,7 @@ extern "C" {
* Two stable releases of the same series usually have the same ::HWLOC_API_VERSION
* even if their HWLOC_VERSION are different.
*/
#define HWLOC_API_VERSION 0x00020b00
#define HWLOC_API_VERSION 0x00020c00
/** \brief Indicate at runtime which hwloc API version was used at build time.
*
@@ -346,9 +346,10 @@ typedef enum {
*
* Some operating systems (e.g. Linux) may expose a single die per package
* even if the hardware does not support dies at all. To avoid showing
* such non-existing dies, the corresponding hwloc backend may filter them out.
* such non-existing dies, hwloc will filter them out if all of them are
* identical to packages.
* This is functionally equivalent to ::HWLOC_TYPE_FILTER_KEEP_STRUCTURE
* being enforced.
* being enforced for Dies versus Packages.
*/
HWLOC_OBJ_TYPE_MAX /**< \private Sentinel value */
@@ -1047,7 +1048,7 @@ HWLOC_DECLSPEC const char * hwloc_obj_type_string (hwloc_obj_type_t type) __hwlo
* If \p size is 0, \p string may safely be \c NULL.
*
* \return the number of characters that were actually written if not truncating,
* or that would have been written (not including the ending \\0).
* or that would have been written (not including the ending \c \0).
*/
HWLOC_DECLSPEC int hwloc_obj_type_snprintf(char * __hwloc_restrict string, size_t size,
hwloc_obj_t obj,
@@ -1062,7 +1063,7 @@ HWLOC_DECLSPEC int hwloc_obj_type_snprintf(char * __hwloc_restrict string, size_
* If \p size is 0, \p string may safely be \c NULL.
*
* \return the number of characters that were actually written if not truncating,
* or that would have been written (not including the ending \\0).
* or that would have been written (not including the ending \c \0).
*/
HWLOC_DECLSPEC int hwloc_obj_attr_snprintf(char * __hwloc_restrict string, size_t size,
hwloc_obj_t obj, const char * __hwloc_restrict separator,
@@ -2002,7 +2003,7 @@ HWLOC_DECLSPEC int hwloc_topology_set_xml(hwloc_topology_t __hwloc_restrict topo
* a file, as with hwloc_topology_set_xml()).
*
* Gather topology information from the XML memory buffer given at
* \p buffer and of length \p size (including an ending \0).
* \p buffer and of length \p size (including an ending \c \0).
* This buffer may have been filled earlier with
* hwloc_topology_export_xmlbuffer() in hwloc/export.h.
*

View File

@@ -1,6 +1,6 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2024 Inria. All rights reserved.
* Copyright © 2009-2025 Inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
@@ -11,10 +11,10 @@
#ifndef HWLOC_CONFIG_H
#define HWLOC_CONFIG_H
#define HWLOC_VERSION "2.11.2"
#define HWLOC_VERSION "2.12.1"
#define HWLOC_VERSION_MAJOR 2
#define HWLOC_VERSION_MINOR 11
#define HWLOC_VERSION_RELEASE 2
#define HWLOC_VERSION_MINOR 12
#define HWLOC_VERSION_RELEASE 1
#define HWLOC_VERSION_GREEK ""
#define __hwloc_restrict

View File

@@ -1,6 +1,6 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2023 Inria. All rights reserved.
* Copyright © 2009-2024 Inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
@@ -113,51 +113,88 @@ HWLOC_DECLSPEC int hwloc_bitmap_copy(hwloc_bitmap_t dst, hwloc_const_bitmap_t sr
* Bitmap/String Conversion
*/
/** \brief Stringify a bitmap.
/** \brief Stringify a bitmap in the default hwloc format.
*
* <b>Note that if the bitmap is a CPU or nodeset, it contains physical indexes.</b>
*
* Print the bits set inside a bitmap as a comma-separated list of hexadecimal 32-bit blocks.
* A bitmap containing bits 1, 33, 34, and all from 64 to 95 is printed as <tt>"0xffffffff,0x00000006,0x00000002"</tt>.
*
* Up to \p buflen characters may be written in buffer \p buf.
*
* If \p buflen is 0, \p buf may safely be \c NULL.
*
* \return the number of characters that were actually written if not truncating,
* or that would have been written (not including the ending \\0).
* or that would have been written (not including the ending \c \0).
* \return -1 on error.
*/
HWLOC_DECLSPEC int hwloc_bitmap_snprintf(char * __hwloc_restrict buf, size_t buflen, hwloc_const_bitmap_t bitmap);
/** \brief Stringify a bitmap into a newly allocated string.
/** \brief Stringify a bitmap into a newly allocated string in the default hwloc format.
*
* \return 0 on success, -1 on error.
* <b>Note that if the bitmap is a CPU or nodeset, it contains physical indexes.</b>
*
* Print the bits set inside a bitmap as a comma-separated list of hexadecimal 32-bit blocks.
* A bitmap containing bits 1, 33, 34, and all from 64 to 95 is printed as <tt>"0xffffffff,0x00000006,0x00000002"</tt>.
*
* \return the number of characters that were written (not including the ending \c \0).
* \return -1 on error, for instance with \p errno set to \c ENOMEM on failure to allocate the output string.
*/
HWLOC_DECLSPEC int hwloc_bitmap_asprintf(char ** strp, hwloc_const_bitmap_t bitmap);
/** \brief Parse a bitmap string and stores it in bitmap \p bitmap.
/** \brief Parse a bitmap string as the default hwloc format and stores it in bitmap \p bitmap.
*
* <b>Note that if the bitmap is a CPU or nodeset, the input string must contain physical indexes.</b>
*
* The input string should be a comma-separared list of hexadecimal 32-bit blocks.
* String <tt>"0xffffffff,0x6,0x2"</tt> is parsed as a bitmap containing all bits between 64 and 95,
* and bits 33, 34 and 1.
*
* \return 0 on success, -1 on error.
*/
HWLOC_DECLSPEC int hwloc_bitmap_sscanf(hwloc_bitmap_t bitmap, const char * __hwloc_restrict string);
/** \brief Stringify a bitmap in the list format.
*
* <b>Note that if the bitmap is a CPU or nodeset, it contains physical indexes.</b>
*
* Lists are comma-separated indexes or ranges.
* Ranges are dash separated indexes.
* The last range may not have an ending indexes if the bitmap is infinitely set.
* A bitmap containing bits 1, 33, 34, and all from 64 to 95 is printed as <tt>"1,33-34,64-95"</tt>.
* The last range may not have an ending index if the bitmap is infinitely set.
*
* Up to \p buflen characters may be written in buffer \p buf.
*
* If \p buflen is 0, \p buf may safely be \c NULL.
*
* \return the number of characters that were actually written if not truncating,
* or that would have been written (not including the ending \\0).
* or that would have been written (not including the ending \c \0).
* \return -1 on error.
*/
HWLOC_DECLSPEC int hwloc_bitmap_list_snprintf(char * __hwloc_restrict buf, size_t buflen, hwloc_const_bitmap_t bitmap);
/** \brief Stringify a bitmap into a newly allocated list string.
*
* \return 0 on success, -1 on error.
* <b>Note that if the bitmap is a CPU or nodeset, it contains physical indexes.</b>
*
* Lists are comma-separated indexes or ranges.
* Ranges are dash separated indexes.
* A bitmap containing bits 1, 33, 34, and all from 64 to 95 is printed as <tt>"1,33-34,64-95"</tt>.
* The last range may not have an ending index if the bitmap is infinitely set.
*
* \return the number of characters that were written (not including the ending \c \0).
* \return -1 on error, for instance with \p errno set to \c ENOMEM on failure to allocate the output string.
*/
HWLOC_DECLSPEC int hwloc_bitmap_list_asprintf(char ** strp, hwloc_const_bitmap_t bitmap);
/** \brief Parse a list string and stores it in bitmap \p bitmap.
*
* <b>Note that if the bitmap is a CPU or nodeset, the input string must contain physical indexes.</b>
*
* Lists are comma-separated indexes or ranges.
* Ranges are dash separated indexes.
* String <tt>"1,33-34,64-95"</tt> is parsed as a bitmap containing bits 1, 33, 34, and all from 64 to 95.
* The last range may not have an ending index if the bitmap is infinitely set.
*
* \return 0 on success, -1 on error.
*/
@@ -165,25 +202,43 @@ HWLOC_DECLSPEC int hwloc_bitmap_list_sscanf(hwloc_bitmap_t bitmap, const char *
/** \brief Stringify a bitmap in the taskset-specific format.
*
* The taskset command manipulates bitmap strings that contain a single
* <b>Note that if the bitmap is a CPU or nodeset, it contains physical indexes.</b>
*
* The taskset program manipulates bitmap strings that contain a single
* (possible very long) hexadecimal number starting with 0x.
* A bitmap containing bits 1, 33, 34, and all from 64 to 95 is printed as </tt>"0xffffffff0000000600000002"</tt>.
*
* Up to \p buflen characters may be written in buffer \p buf.
*
* If \p buflen is 0, \p buf may safely be \c NULL.
*
* \return the number of characters that were actually written if not truncating,
* or that would have been written (not including the ending \\0).
* or that would have been written (not including the ending \c \0).
* \return -1 on error.
*/
HWLOC_DECLSPEC int hwloc_bitmap_taskset_snprintf(char * __hwloc_restrict buf, size_t buflen, hwloc_const_bitmap_t bitmap);
/** \brief Stringify a bitmap into a newly allocated taskset-specific string.
*
* \return 0 on success, -1 on error.
* <b>Note that if the bitmap is a CPU or nodeset, it contains physical indexes.</b>
*
* The taskset program manipulates bitmap strings that contain a single
* (possible very long) hexadecimal number starting with 0x.
* A bitmap containing bits 1, 33, 34, and all from 64 to 95 is printed as <tt>"0xffffffff0000000600000002"</tt>.
*
* \return the number of characters that were written (not including the ending \c \0).
* \return -1 on error, for instance with \p errno set to \c ENOMEM on failure to allocate the output string.
*/
HWLOC_DECLSPEC int hwloc_bitmap_taskset_asprintf(char ** strp, hwloc_const_bitmap_t bitmap);
/** \brief Parse a taskset-specific bitmap string and stores it in bitmap \p bitmap.
*
* <b>Note that if the bitmap is a CPU or nodeset, the input string must contain physical indexes.</b>
*
* The taskset program manipulates bitmap strings that contain a single
* (possible very long) hexadecimal number starting with 0x.
* String <tt>"0xffffffff0000000600000002"</tt> is parsed as a bitmap containing all bits between 64 and 95,
* and bits 33, 34 and 1.
*
* \return 0 on success, -1 on error.
*/

View File

@@ -1,5 +1,5 @@
/*
* Copyright © 2013-2023 Inria. All rights reserved.
* Copyright © 2013-2024 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
@@ -258,7 +258,7 @@ HWLOC_DECLSPEC int hwloc_topology_diff_export_xml(hwloc_topology_diff_t diff, co
/** \brief Load a list of topology differences from a XML buffer.
*
* Build a list of differences from the XML memory buffer given
* at \p xmlbuffer and of length \p buflen (including an ending \0).
* at \p xmlbuffer and of length \p buflen (including an ending \c \0).
* This buffer may have been filled earlier with
* hwloc_topology_diff_export_xmlbuffer().
*
@@ -284,7 +284,7 @@ HWLOC_DECLSPEC int hwloc_topology_diff_load_xmlbuffer(const char *xmlbuffer, int
* that contains the reference topology.
* This attribute is given back when reading the diff from XML.
*
* The returned buffer ends with a \0 that is included in the returned
* The returned buffer ends with a \c \0 that is included in the returned
* length.
*
* \return 0 on success, -1 on error.

View File

@@ -1,5 +1,5 @@
/*
* Copyright © 2010-2024 Inria. All rights reserved.
* Copyright © 2010-2025 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
@@ -227,17 +227,24 @@ enum hwloc_distances_transform_e {
HWLOC_DISTANCES_TRANSFORM_LINKS = 1,
/** \brief Merge switches with multiple ports into a single object.
* This currently only applies to NVSwitches where GPUs seem connected to different
* separate switch ports in the NVLinkBandwidth matrix. This transformation will
* replace all of them with the same port connected to all GPUs.
* Other ports are removed by applying ::HWLOC_DISTANCES_TRANSFORM_REMOVE_NULL internally.
*
* This currently only applies to NVSwitches where GPUs seem connected
* to different switch ports. Switch ports must be objects with subtype
* "NVSwitch" as in the NVLinkBandwidth matrix.
*
* This transformation will replace all ports with only the first one,
* now connected to all GPUs. Other ports are removed by applying
* ::HWLOC_DISTANCES_TRANSFORM_REMOVE_NULL internally.
* \hideinitializer
*/
HWLOC_DISTANCES_TRANSFORM_MERGE_SWITCH_PORTS = 2,
/** \brief Apply a transitive closure to the matrix to connect objects across switches.
* This currently only applies to GPUs and NVSwitches in the NVLinkBandwidth matrix.
* All pairs of GPUs will be reported as directly connected.
*
* All pairs of GPUs will be reported as directly connected instead GPUs being
* only connected to switches.
*
* Switch ports must be objects with subtype "NVSwitch" as in the NVLinkBandwidth matrix.
* \hideinitializer
*/
HWLOC_DISTANCES_TRANSFORM_TRANSITIVE_CLOSURE = 3

View File

@@ -1,5 +1,5 @@
/*
* Copyright © 2021-2023 Inria. All rights reserved.
* Copyright © 2021-2024 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
@@ -32,7 +32,8 @@ extern "C" {
/** \defgroup hwlocality_levelzero Interoperability with the oneAPI Level Zero interface.
*
* This interface offers ways to retrieve topology information about
* devices managed by the Level Zero API.
* devices managed by the Level Zero API, both for main Core devices (ZE API)
* and the Sysman devices (ZES API).
*
* @{
*/
@@ -44,9 +45,68 @@ extern "C" {
* the Level Zero device \p device.
*
* Topology \p topology and device \p device must match the local machine.
* The Level Zero library must have been initialized with zeInit().
* I/O devices detection and the Level Zero component are not needed in the
* topology.
*
* The function only returns the locality of the device.
* If more information about the device is needed, OS objects should
* be used instead, see hwloc_levelzero_get_device_osdev().
*
* This function is currently only implemented in a meaningful way for
* Linux; other systems will simply get a full cpuset.
*
* \return 0 on success.
* \return -1 on error, for instance if device information could not be found.
*
* \note zeDevicePciGetPropertiesExt() must be supported, or the entire machine
* locality will be returned.
*/
static __hwloc_inline int
hwloc_levelzero_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
ze_device_handle_t device, hwloc_cpuset_t set)
{
#ifdef HWLOC_LINUX_SYS
/* If we're on Linux, use the sysfs mechanism to get the local cpus */
#define HWLOC_LEVELZERO_DEVICE_SYSFS_PATH_MAX 128
char path[HWLOC_LEVELZERO_DEVICE_SYSFS_PATH_MAX];
ze_pci_ext_properties_t pci;
ze_result_t res;
if (!hwloc_topology_is_thissystem(topology)) {
errno = EINVAL;
return -1;
}
pci.stype = ZE_STRUCTURE_TYPE_PCI_EXT_PROPERTIES;
pci.pNext = NULL;
res = zeDevicePciGetPropertiesExt(device, &pci);
if (res != ZE_RESULT_SUCCESS) {
errno = EINVAL;
return -1;
}
sprintf(path, "/sys/bus/pci/devices/%04x:%02x:%02x.%01x/local_cpus",
pci.address.domain, pci.address.bus, pci.address.device, pci.address.function);
if (hwloc_linux_read_path_as_cpumask(path, set) < 0
|| hwloc_bitmap_iszero(set))
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
#else
/* Non-Linux systems simply get a full cpuset */
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
#endif
return 0;
}
/** \brief Get the CPU set of logical processors that are physically
* close to the Level Zero Sysman device \p device
*
* Store in \p set the CPU-set describing the locality of
* the Level Zero device \p device.
*
* Topology \p topology and device \p device must match the local machine.
* The Level Zero library must have been initialized with Sysman enabled
* (by calling zesInit(0) if supported,
* or by setting ZES_ENABLE_SYSMAN=1 in the environment).
* with zesInit().
* I/O devices detection and the Level Zero component are not needed in the
* topology.
*
@@ -61,15 +121,14 @@ extern "C" {
* \return -1 on error, for instance if device information could not be found.
*/
static __hwloc_inline int
hwloc_levelzero_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
ze_device_handle_t device, hwloc_cpuset_t set)
hwloc_levelzero_get_sysman_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
zes_device_handle_t device, hwloc_cpuset_t set)
{
#ifdef HWLOC_LINUX_SYS
/* If we're on Linux, use the sysfs mechanism to get the local cpus */
#define HWLOC_LEVELZERO_DEVICE_SYSFS_PATH_MAX 128
char path[HWLOC_LEVELZERO_DEVICE_SYSFS_PATH_MAX];
zes_pci_properties_t pci;
zes_device_handle_t sdevice = device;
ze_result_t res;
if (!hwloc_topology_is_thissystem(topology)) {
@@ -77,7 +136,7 @@ hwloc_levelzero_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_un
return -1;
}
res = zesDevicePciGetProperties(sdevice, &pci);
res = zesDevicePciGetProperties(device, &pci);
if (res != ZE_RESULT_SUCCESS) {
errno = EINVAL;
return -1;
@@ -102,17 +161,90 @@ hwloc_levelzero_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_un
* \return \c NULL if none could be found.
*
* Topology \p topology and device \p dv_ind must match the local machine.
* The Level Zero library must have been initialized with zeInit().
* I/O devices detection and the Level Zero component must be enabled in the
* topology. If not, the locality of the object may still be found using
* hwloc_levelzero_get_device_cpuset().
*
* \note If the input ZE device is actually a subdevice, then its parent
* (root device) is actually translated, i.e. the main hwloc OS device
* is returned instead of one of its children.
*
* \note The corresponding hwloc PCI device may be found by looking
* at the result parent pointer (unless PCI devices are filtered out).
*
* \note zeDevicePciGetPropertiesExt() must be supported.
*/
static __hwloc_inline hwloc_obj_t
hwloc_levelzero_get_device_osdev(hwloc_topology_t topology, ze_device_handle_t device)
{
ze_pci_ext_properties_t pci;
ze_result_t res;
hwloc_obj_t osdev;
if (!hwloc_topology_is_thissystem(topology)) {
errno = EINVAL;
return NULL;
}
pci.stype = ZE_STRUCTURE_TYPE_PCI_EXT_PROPERTIES;
pci.pNext = NULL;
res = zeDevicePciGetPropertiesExt(device, &pci);
if (res != ZE_RESULT_SUCCESS) {
errno = EINVAL;
return NULL;
}
osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
hwloc_obj_t pcidev;
if (strncmp(osdev->name, "ze", 2))
continue;
pcidev = osdev;
while (pcidev && pcidev->type != HWLOC_OBJ_PCI_DEVICE)
pcidev = pcidev->parent;
if (!pcidev)
continue;
if (pcidev
&& pcidev->type == HWLOC_OBJ_PCI_DEVICE
&& pcidev->attr->pcidev.domain == pci.address.domain
&& pcidev->attr->pcidev.bus == pci.address.bus
&& pcidev->attr->pcidev.dev == pci.address.device
&& pcidev->attr->pcidev.func == pci.address.function)
return osdev;
/* FIXME: when we'll have serialnumber, try it in case PCI is filtered-out */
}
return NULL;
}
/** \brief Get the hwloc OS device object corresponding to Level Zero Sysman device
* \p device.
*
* \return The hwloc OS device object that describes the given Level Zero device \p device.
* \return \c NULL if none could be found.
*
* Topology \p topology and device \p dv_ind must match the local machine.
* The Level Zero library must have been initialized with Sysman enabled
* with zesInit().
* I/O devices detection and the Level Zero component must be enabled in the
* topology. If not, the locality of the object may still be found using
* hwloc_levelzero_get_device_cpuset().
*
* \note If the input ZES device is actually a subdevice, then its parent
* (root device) is actually translated, i.e. the main hwloc OS device
* is returned instead of one of its children.
*
* \note The corresponding hwloc PCI device may be found by looking
* at the result parent pointer (unless PCI devices are filtered out).
*/
static __hwloc_inline hwloc_obj_t
hwloc_levelzero_get_device_osdev(hwloc_topology_t topology, ze_device_handle_t device)
hwloc_levelzero_get_sysman_device_osdev(hwloc_topology_t topology, zes_device_handle_t device)
{
zes_device_handle_t sdevice = device;
zes_pci_properties_t pci;
ze_result_t res;
hwloc_obj_t osdev;
@@ -122,20 +254,25 @@ hwloc_levelzero_get_device_osdev(hwloc_topology_t topology, ze_device_handle_t d
return NULL;
}
res = zesDevicePciGetProperties(sdevice, &pci);
res = zesDevicePciGetProperties(device, &pci);
if (res != ZE_RESULT_SUCCESS) {
/* L0 was likely initialized without sysman, don't bother */
errno = EINVAL;
return NULL;
}
osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
hwloc_obj_t pcidev = osdev->parent;
hwloc_obj_t pcidev;
if (strncmp(osdev->name, "ze", 2))
continue;
pcidev = osdev;
while (pcidev && pcidev->type != HWLOC_OBJ_PCI_DEVICE)
pcidev = pcidev->parent;
if (!pcidev)
continue;
if (pcidev
&& pcidev->type == HWLOC_OBJ_PCI_DEVICE
&& pcidev->attr->pcidev.domain == pci.address.domain

View File

@@ -1,5 +1,5 @@
/*
* Copyright © 2019-2024 Inria. All rights reserved.
* Copyright © 2019-2025 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
@@ -58,6 +58,11 @@ extern "C" {
* an easy way to distinguish NUMA nodes of different kinds, as explained
* in \ref heteromem.
*
* Beside tiers, hwloc defines a set of "default" nodes where normal memory
* allocations should be made from (see hwloc_topology_get_default_nodeset()).
* This is also useful for dividing the machine into a set of non-overlapping
* NUMA domains, for instance for binding tasks per domain.
*
* \sa An example is available in doc/examples/memory-attributes.c in the source tree.
*
* \note The API also supports specific objects as initiator,
@@ -245,6 +250,16 @@ enum hwloc_local_numanode_flag_e {
*/
HWLOC_LOCAL_NUMANODE_FLAG_SMALLER_LOCALITY = (1UL<<1),
/** \breif Select NUMA nodes whose locality intersects the given cpuset.
* This includes larger and smaller localities as well as localities
* that are partially included.
* For instance, if the locality is one core of both packages, a NUMA node
* local to one package is neither larger nor smaller than this locality,
* but it intersects it.
* \hideinitializer
*/
HWLOC_LOCAL_NUMANODE_FLAG_INTERSECT_LOCALITY = (1UL<<3),
/** \brief Select all NUMA nodes in the topology.
* The initiator \p initiator is ignored.
* \hideinitializer
@@ -290,7 +305,57 @@ hwloc_get_local_numanode_objs(hwloc_topology_t topology,
hwloc_obj_t *nodes,
unsigned long flags);
/** \brief Return the set of default NUMA nodes
*
* In machines with heterogeneous memory, some NUMA nodes are considered
* the default ones, i.e. where basic allocations should be made from.
* These are usually DRAM nodes.
*
* Other nodes may be reserved for specific use (I/O device memory, e.g. GPU memory),
* small but high performance (HBM), large but slow memory (NVM), etc.
* Buffers should usually not be allocated from there unless explicitly required.
*
* This function fills \p nodeset with the bits of NUMA nodes considered default.
*
* It is guaranteed that these nodes have non-intersecting CPU sets,
* i.e. cores may not have multiple local NUMA nodes anymore.
* Hence this may be used to iterate over the platform divided into separate
* NUMA localities, for instance for binding one task per NUMA domain.
*
* Any core that had some local NUMA node(s) in the initial topology should
* still have one in the default nodeset. Corner cases where this would be
* wrong consist in asymmetric platforms with missing DRAM nodes, or topologies
* that were already restricted to less NUMA nodes.
*
* The returned nodeset may be passed to hwloc_topology_restrict() with
* ::HWLOC_RESTRICT_FLAG_BYNODESET to remove all non-default nodes from
* the topology. The resulting topology will be easier to use when iterating
* over (now homogeneous) NUMA nodes.
*
* The heuristics for finding default nodes relies on memory tiers and subtypes
* (see \ref heteromem) as well as the assumption that hardware vendors list
* default nodes first in hardware tables.
*
* \p flags must be \c 0 for now.
*
* \return 0 on success.
* \return -1 on error.
*
* \note The returned nodeset usually contains all nodes from a single memory
* tier, likely the DRAM one.
*
* \note The returned nodeset is included in the list of available nodes
* returned by hwloc_topology_get_topology_nodeset(). It is strictly smaller
* if the machine has heterogeneous memory.
*
* \note The heuristics may return a suboptimal set of nodes if hwloc could
* not guess memory types and/or if some default nodes were removed earlier
* from the topology (e.g. with hwloc_topology_restrict()).
*/
HWLOC_DECLSPEC int
hwloc_topology_get_default_nodeset(hwloc_topology_t topology,
hwloc_nodeset_t nodeset,
unsigned long flags);
/** \brief Return an attribute value for a specific target NUMA node.
*

View File

@@ -26,7 +26,7 @@ struct hwloc_backend;
/** \defgroup hwlocality_disc_components Components and Plugins: Discovery components
/** \defgroup hwlocality_disc_components Components and Plugins: Discovery components and backends
*
* \note These structures and functions may change when ::HWLOC_COMPONENT_ABI is modified.
*
@@ -90,18 +90,6 @@ struct hwloc_disc_component {
struct hwloc_disc_component * next;
};
/** @} */
/** \defgroup hwlocality_disc_backends Components and Plugins: Discovery backends
*
* \note These structures and functions may change when ::HWLOC_COMPONENT_ABI is modified.
*
* @{
*/
/** \brief Discovery phase */
typedef enum hwloc_disc_phase_e {
/** \brief xml or synthetic, platform-specific components such as bgq.
@@ -313,6 +301,64 @@ struct hwloc_component {
void * data;
};
/** \brief Make sure that plugins can lookup core symbols.
*
* This is a sanity check to avoid lazy-lookup failures when libhwloc
* is loaded within a plugin, and later tries to load its own plugins.
* This may fail (and abort the program) if libhwloc symbols are in a
* private namespace.
*
* \return 0 on success.
* \return -1 if the plugin cannot be successfully loaded. The caller
* plugin init() callback should return a negative error code as well.
*
* Plugins should call this function in their init() callback to avoid
* later crashes if lazy symbol resolution is used by the upper layer that
* loaded hwloc (e.g. OpenCL implementations using dlopen with RTLD_LAZY).
*
* \note The build system must define HWLOC_INSIDE_PLUGIN if and only if
* building the caller as a plugin.
*
* \note This function should remain inline so plugins can call it even
* when they cannot find libhwloc symbols.
*/
static __hwloc_inline int
hwloc_plugin_check_namespace(const char *pluginname __hwloc_attribute_unused, const char *symbol __hwloc_attribute_unused)
{
#ifdef HWLOC_INSIDE_PLUGIN
void *sym;
#ifdef HWLOC_HAVE_LTDL
lt_dlhandle handle = lt_dlopen(NULL);
#else
void *handle = dlopen(NULL, RTLD_NOW|RTLD_LOCAL);
#endif
if (!handle)
/* cannot check, assume things will work */
return 0;
#ifdef HWLOC_HAVE_LTDL
sym = lt_dlsym(handle, symbol);
lt_dlclose(handle);
#else
sym = dlsym(handle, symbol);
dlclose(handle);
#endif
if (!sym) {
static int verboseenv_checked = 0;
static int verboseenv_value = 0;
if (!verboseenv_checked) {
const char *verboseenv = getenv("HWLOC_PLUGINS_VERBOSE");
verboseenv_value = verboseenv ? atoi(verboseenv) : 0;
verboseenv_checked = 1;
}
if (verboseenv_value)
fprintf(stderr, "Plugin `%s' disabling itself because it cannot find the `%s' core symbol.\n",
pluginname, symbol);
return -1;
}
#endif /* HWLOC_INSIDE_PLUGIN */
return 0;
}
/** @} */
@@ -422,64 +468,6 @@ HWLOC_DECLSPEC int hwloc_obj_add_children_sets(hwloc_obj_t obj);
*/
HWLOC_DECLSPEC int hwloc_topology_reconnect(hwloc_topology_t topology, unsigned long flags __hwloc_attribute_unused);
/** \brief Make sure that plugins can lookup core symbols.
*
* This is a sanity check to avoid lazy-lookup failures when libhwloc
* is loaded within a plugin, and later tries to load its own plugins.
* This may fail (and abort the program) if libhwloc symbols are in a
* private namespace.
*
* \return 0 on success.
* \return -1 if the plugin cannot be successfully loaded. The caller
* plugin init() callback should return a negative error code as well.
*
* Plugins should call this function in their init() callback to avoid
* later crashes if lazy symbol resolution is used by the upper layer that
* loaded hwloc (e.g. OpenCL implementations using dlopen with RTLD_LAZY).
*
* \note The build system must define HWLOC_INSIDE_PLUGIN if and only if
* building the caller as a plugin.
*
* \note This function should remain inline so plugins can call it even
* when they cannot find libhwloc symbols.
*/
static __hwloc_inline int
hwloc_plugin_check_namespace(const char *pluginname __hwloc_attribute_unused, const char *symbol __hwloc_attribute_unused)
{
#ifdef HWLOC_INSIDE_PLUGIN
void *sym;
#ifdef HWLOC_HAVE_LTDL
lt_dlhandle handle = lt_dlopen(NULL);
#else
void *handle = dlopen(NULL, RTLD_NOW|RTLD_LOCAL);
#endif
if (!handle)
/* cannot check, assume things will work */
return 0;
#ifdef HWLOC_HAVE_LTDL
sym = lt_dlsym(handle, symbol);
lt_dlclose(handle);
#else
sym = dlsym(handle, symbol);
dlclose(handle);
#endif
if (!sym) {
static int verboseenv_checked = 0;
static int verboseenv_value = 0;
if (!verboseenv_checked) {
const char *verboseenv = getenv("HWLOC_PLUGINS_VERBOSE");
verboseenv_value = verboseenv ? atoi(verboseenv) : 0;
verboseenv_checked = 1;
}
if (verboseenv_value)
fprintf(stderr, "Plugin `%s' disabling itself because it cannot find the `%s' core symbol.\n",
pluginname, symbol);
return -1;
}
#endif /* HWLOC_INSIDE_PLUGIN */
return 0;
}
/** @} */

View File

@@ -1,6 +1,6 @@
/*
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* Copyright © 2010-2024 Inria. All rights reserved.
* Copyright © 2010-2025 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
@@ -409,8 +409,10 @@ extern "C" {
#define hwloc_local_numanode_flag_e HWLOC_NAME(local_numanode_flag_e)
#define HWLOC_LOCAL_NUMANODE_FLAG_LARGER_LOCALITY HWLOC_NAME_CAPS(LOCAL_NUMANODE_FLAG_LARGER_LOCALITY)
#define HWLOC_LOCAL_NUMANODE_FLAG_SMALLER_LOCALITY HWLOC_NAME_CAPS(LOCAL_NUMANODE_FLAG_SMALLER_LOCALITY)
#define HWLOC_LOCAL_NUMANODE_FLAG_INTERSECT_LOCALITY HWLOC_NAME_CAPS(LOCAL_NUMANODE_FLAG_INTERSECT_LOCALITY)
#define HWLOC_LOCAL_NUMANODE_FLAG_ALL HWLOC_NAME_CAPS(LOCAL_NUMANODE_FLAG_ALL)
#define hwloc_get_local_numanode_objs HWLOC_NAME(get_local_numanode_objs)
#define hwloc_topology_get_default_nodeset HWLOC_NAME(topology_get_default_nodeset)
#define hwloc_memattr_get_name HWLOC_NAME(memattr_get_name)
#define hwloc_memattr_get_flags HWLOC_NAME(memattr_get_flags)
@@ -599,7 +601,9 @@ extern "C" {
/* levelzero.h */
#define hwloc_levelzero_get_device_cpuset HWLOC_NAME(levelzero_get_device_cpuset)
#define hwloc_levelzero_get_sysman_device_cpuset HWLOC_NAME(levelzero_get_sysman_device_cpuset)
#define hwloc_levelzero_get_device_osdev HWLOC_NAME(levelzero_get_device_osdev)
#define hwloc_levelzero_get_sysman_device_osdev HWLOC_NAME(levelzero_get_sysman_device_osdev)
/* gl.h */
@@ -813,6 +817,8 @@ extern "C" {
#define hwloc_topology_setup_defaults HWLOC_NAME(topology_setup_defaults)
#define hwloc_topology_clear HWLOC_NAME(topology_clear)
#define hwloc__reconnect HWLOC_NAME(_reconnect)
#define hwloc__attach_memory_object HWLOC_NAME(insert_memory_object)
#define hwloc_get_obj_by_type_and_gp_index HWLOC_NAME(get_obj_by_type_and_gp_index)

View File

@@ -1,6 +1,6 @@
/*
* Copyright © 2009, 2011, 2012 CNRS. All rights reserved.
* Copyright © 2009-2020 Inria. All rights reserved.
* Copyright © 2009-2021 Inria. All rights reserved.
* Copyright © 2009, 2011, 2012, 2015 Université Bordeaux. All rights reserved.
* Copyright © 2009-2020 Cisco Systems, Inc. All rights reserved.
* $COPYRIGHT$
@@ -17,10 +17,6 @@
#define HWLOC_HAVE_MSVC_CPUIDEX 1
/* #undef HAVE_MKSTEMP */
#define HWLOC_HAVE_X86_CPUID 1
/* Define to 1 if the system has the type `CACHE_DESCRIPTOR'. */
#define HAVE_CACHE_DESCRIPTOR 0
@@ -132,7 +128,8 @@
#define HAVE_DECL__SC_PAGE_SIZE 0
/* Define to 1 if you have the <dirent.h> header file. */
/* #undef HAVE_DIRENT_H */
/* #define HAVE_DIRENT_H 1 */
#undef HAVE_DIRENT_H
/* Define to 1 if you have the <dlfcn.h> header file. */
/* #undef HAVE_DLFCN_H */
@@ -285,7 +282,7 @@
#define HAVE_STRING_H 1
/* Define to 1 if you have the `strncasecmp' function. */
/* #undef HAVE_STRNCASECMP */
#define HAVE_STRNCASECMP 1
/* Define to '1' if sysctl is present and usable */
/* #undef HAVE_SYSCTL */
@@ -326,7 +323,8 @@
/* #undef HAVE_UNAME */
/* Define to 1 if you have the <unistd.h> header file. */
/* #undef HAVE_UNISTD_H */
/* #define HAVE_UNISTD_H 1 */
#undef HAVE_UNISTD_H
/* Define to 1 if you have the `uselocale' function. */
/* #undef HAVE_USELOCALE */
@@ -661,7 +659,7 @@
#define hwloc_pid_t HANDLE
/* Define this to either strncasecmp or strncmp */
/* #undef hwloc_strncasecmp */
#define hwloc_strncasecmp strncasecmp
/* Define this to the thread ID type */
#define hwloc_thread_t HANDLE

View File

@@ -186,7 +186,7 @@ hwloc_ffsl_from_ffs32(unsigned long x)
/**
* flsl helpers.
*/
#ifdef __GNUC_____
#ifdef __GNUC__
# if (__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4))
# define hwloc_flsl(x) ((x) ? (8*sizeof(long) - __builtin_clzl(x)) : 0)

View File

@@ -1,6 +1,6 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2023 Inria. All rights reserved.
* Copyright © 2009-2025 Inria. All rights reserved.
* Copyright © 2009-2012, 2020 Université Bordeaux
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
*
@@ -302,6 +302,9 @@ extern void hwloc__reorder_children(hwloc_obj_t parent);
extern void hwloc_topology_setup_defaults(struct hwloc_topology *topology);
extern void hwloc_topology_clear(struct hwloc_topology *topology);
#define _HWLOC_RECONNECT_FLAG_KEEPSTRUCTURE (1UL<<0)
extern int hwloc__reconnect(struct hwloc_topology *topology, unsigned long flags);
/* insert memory object as memory child of normal parent */
extern struct hwloc_obj * hwloc__attach_memory_object(struct hwloc_topology *topology, hwloc_obj_t parent,
hwloc_obj_t obj, const char *reason);

View File

@@ -1,5 +1,5 @@
/*
* Copyright © 2010-2024 Inria. All rights reserved.
* Copyright © 2010-2025 Inria. All rights reserved.
* Copyright © 2011-2012 Université Bordeaux
* Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
@@ -699,7 +699,7 @@ hwloc_distances_add_commit(hwloc_topology_t topology,
}
/* in case we added some groups, see if we need to reconnect */
hwloc_topology_reconnect(topology, 0);
hwloc__reconnect(topology, 0);
return 0;
@@ -1387,19 +1387,12 @@ static __hwloc_inline int is_nvswitch(hwloc_obj_t obj)
}
static int
hwloc__distances_transform_merge_switch_ports(hwloc_topology_t topology,
struct hwloc_distances_s *distances)
hwloc__distances_transform_merge_switch_ports(struct hwloc_distances_s *distances)
{
struct hwloc_internal_distances_s *dist = hwloc__internal_distances_from_public(topology, distances);
hwloc_obj_t *objs = distances->objs;
hwloc_uint64_t *values = distances->values;
unsigned first, i, j, nbobjs = distances->nbobjs;
if (strcmp(dist->name, "NVLinkBandwidth")) {
errno = EINVAL;
return -1;
}
/* find the first port */
first = (unsigned) -1;
for(i=0; i<nbobjs; i++)
@@ -1435,20 +1428,13 @@ hwloc__distances_transform_merge_switch_ports(hwloc_topology_t topology,
}
static int
hwloc__distances_transform_transitive_closure(hwloc_topology_t topology,
struct hwloc_distances_s *distances)
hwloc__distances_transform_transitive_closure(struct hwloc_distances_s *distances)
{
struct hwloc_internal_distances_s *dist = hwloc__internal_distances_from_public(topology, distances);
hwloc_obj_t *objs = distances->objs;
hwloc_uint64_t *values = distances->values;
unsigned nbobjs = distances->nbobjs;
unsigned i, j, k;
if (strcmp(dist->name, "NVLinkBandwidth")) {
errno = EINVAL;
return -1;
}
for(i=0; i<nbobjs; i++) {
hwloc_uint64_t bw_i2sw = 0;
if (is_nvswitch(objs[i]))
@@ -1467,8 +1453,8 @@ hwloc__distances_transform_transitive_closure(hwloc_topology_t topology,
if (is_nvswitch(objs[k]))
bw_sw2j += values[k*nbobjs+j];
/* bandwidth from i to j is now min(i2sw,sw2j) */
values[i*nbobjs+j] = bw_i2sw > bw_sw2j ? bw_sw2j : bw_i2sw;
/* bandwidth from i to j now gets indirect bandwidth too, min(i2sw,sw2j) */
values[i*nbobjs+j] += bw_i2sw > bw_sw2j ? bw_sw2j : bw_i2sw;
}
}
@@ -1476,7 +1462,7 @@ hwloc__distances_transform_transitive_closure(hwloc_topology_t topology,
}
int
hwloc_distances_transform(hwloc_topology_t topology,
hwloc_distances_transform(hwloc_topology_t topology __hwloc_attribute_unused,
struct hwloc_distances_s *distances,
enum hwloc_distances_transform_e transform,
void *transform_attr,
@@ -1495,13 +1481,13 @@ hwloc_distances_transform(hwloc_topology_t topology,
case HWLOC_DISTANCES_TRANSFORM_MERGE_SWITCH_PORTS:
{
int err;
err = hwloc__distances_transform_merge_switch_ports(topology, distances);
err = hwloc__distances_transform_merge_switch_ports(distances);
if (!err)
err = hwloc__distances_transform_remove_null(distances);
return err;
}
case HWLOC_DISTANCES_TRANSFORM_TRANSITIVE_CLOSURE:
return hwloc__distances_transform_transitive_closure(topology, distances);
return hwloc__distances_transform_transitive_closure(distances);
default:
errno = EINVAL;
return -1;

View File

@@ -1,5 +1,5 @@
/*
* Copyright © 2020-2024 Inria. All rights reserved.
* Copyright © 2020-2025 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
@@ -1158,6 +1158,8 @@ match_local_obj_cpuset(hwloc_obj_t node, hwloc_cpuset_t cpuset, unsigned long fl
{
if (flags & HWLOC_LOCAL_NUMANODE_FLAG_ALL)
return 1;
if (flags & HWLOC_LOCAL_NUMANODE_FLAG_INTERSECT_LOCALITY)
return hwloc_bitmap_intersects(node->cpuset, cpuset);
if ((flags & HWLOC_LOCAL_NUMANODE_FLAG_LARGER_LOCALITY)
&& hwloc_bitmap_isincluded(cpuset, node->cpuset))
return 1;
@@ -1180,6 +1182,7 @@ hwloc_get_local_numanode_objs(hwloc_topology_t topology,
if (flags & ~(HWLOC_LOCAL_NUMANODE_FLAG_SMALLER_LOCALITY
|HWLOC_LOCAL_NUMANODE_FLAG_LARGER_LOCALITY
|HWLOC_LOCAL_NUMANODE_FLAG_INTERSECT_LOCALITY
| HWLOC_LOCAL_NUMANODE_FLAG_ALL)) {
errno = EINVAL;
return -1;
@@ -1226,6 +1229,93 @@ hwloc_get_local_numanode_objs(hwloc_topology_t topology,
return 0;
}
static int compare_nodes_by_os_index(const void *_a, const void *_b)
{
const hwloc_obj_t * a = _a, * b = _b;
return (*a)->os_index - (*b)->os_index;
}
int
hwloc_topology_get_default_nodeset(hwloc_topology_t topology,
hwloc_nodeset_t nodeset,
unsigned long flags)
{
hwloc_obj_t *nodes;
hwloc_bitmap_t remainingcpuset;
unsigned nrnodes, i;
const char *first_subtype;
if (flags) {
errno = EINVAL;
goto out;
}
remainingcpuset = hwloc_bitmap_dup(topology->levels[0][0]->cpuset);
if (!remainingcpuset)
goto out;
nrnodes = topology->slevels[HWLOC_SLEVEL_NUMANODE].nbobjs;
nodes = malloc(nrnodes * sizeof(*nodes));
if (!nodes)
goto out_with_remainingcpuset;
memcpy(nodes, topology->slevels[HWLOC_SLEVEL_NUMANODE].objs, nrnodes * sizeof(*nodes));
qsort(nodes, nrnodes, sizeof(*nodes), compare_nodes_by_os_index);
hwloc_bitmap_zero(nodeset);
/* always take the first node (FIXME: except if unexpected subtype?) */
first_subtype = nodes[0]->subtype;
hwloc_bitmap_set(nodeset, nodes[0]->os_index);
hwloc_bitmap_andnot(remainingcpuset, remainingcpuset, nodes[0]->cpuset);
/* use all non-intersecting nodes with same subtype */
for(i=1; i<nrnodes; i++) {
/* check same or no subtype */
if (first_subtype) {
if (!nodes[i]->subtype || strcmp(first_subtype, nodes[i]->subtype))
continue;
} else if (nodes[i]->subtype) {
continue;
}
/* take non-overlapping nodes */
if (hwloc_bitmap_isincluded(nodes[i]->cpuset, remainingcpuset) /* can be empty */) {
hwloc_bitmap_set(nodeset, nodes[i]->os_index);
hwloc_bitmap_andnot(remainingcpuset, remainingcpuset, nodes[i]->cpuset);
}
/* more needed? */
if (hwloc_bitmap_iszero(remainingcpuset))
goto done;
}
/* find more nodes to cover the entire topology cpuset.
* only take what's necessary: first nodes, non-empty */
for(i=1; i<nrnodes; i++) {
/* already taken? */
if (hwloc_bitmap_isset(nodeset, i))
continue;
/* take non-overlapping nodes, except empty */
if (hwloc_bitmap_isincluded(nodes[i]->cpuset, remainingcpuset)
&& !hwloc_bitmap_iszero(nodes[i]->cpuset)) {
hwloc_bitmap_set(nodeset, nodes[i]->os_index);
hwloc_bitmap_andnot(remainingcpuset, remainingcpuset, nodes[i]->cpuset);
}
/* more needed? */
if (hwloc_bitmap_iszero(remainingcpuset))
goto done;
}
done:
free(nodes);
hwloc_bitmap_free(remainingcpuset);
return 0;
out_with_remainingcpuset:
hwloc_bitmap_free(remainingcpuset);
out:
return -1;
}
/**************************************
* Using memattrs to identify HBM/DRAM
@@ -1433,10 +1523,15 @@ hwloc__group_memory_tiers(hwloc_topology_t topology,
}
}
/* Sort nodes.
* We could also sort by the existing subtype.
* KNL is the only case where subtypes are set in backends, but we set memattrs as well there.
* Also HWLOC_MEMTIERS_REFRESH would be a special value to ignore existing subtypes.
/* Sort nodes by tier type and bandwidth.
*
* We could also use the existing subtype but it's not clear it'd be better.
* For NVIDIA GPU, "GPUMemory" is set in the Linux backend, and used above to set tier type anyway.
* For KNL, the Linux backend sets subtypes and memattrs, sorting by memattrs already works fine.
* Existing subtypes could have been imported from XML, usually mostly OK except maybe SPM (fallback for I don't know)?
* An envvar (or HWLOC_MEMTIERS_REFRESH special value?) could be passed to ignore existing subtypes,
* but "GPUMemory" wouldn't be available anymore, we'd have to use something else like "PCIBusId",
* but that one might not always be specific to GPU-backed NUMA nodes?
*/
hwloc_debug("Sorting memory node infos...\n");
qsort(nodeinfos, n, sizeof(*nodeinfos), compare_node_infos_by_type_and_bw);

View File

@@ -1,6 +1,6 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2024 Inria. All rights reserved.
* Copyright © 2009-2025 Inria. All rights reserved.
* Copyright © 2009-2012, 2020 Université Bordeaux
* Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
@@ -56,6 +56,9 @@ typedef enum _LOGICAL_PROCESSOR_RELATIONSHIP {
RelationCache,
RelationProcessorPackage,
RelationGroup,
RelationProcessorDie,
RelationNumaNodeEx, /* only used to *request* extended numa info only, but included in RelationAll, never returned on output */
RelationProcessorModule,
RelationAll = 0xffff
} LOGICAL_PROCESSOR_RELATIONSHIP;
#else /* HAVE_LOGICAL_PROCESSOR_RELATIONSHIP */
@@ -64,6 +67,11 @@ typedef enum _LOGICAL_PROCESSOR_RELATIONSHIP {
# define RelationGroup 4
# define RelationAll 0xffff
# endif /* HAVE_RELATIONPROCESSORPACKAGE */
# ifndef HAVE_RELATIONPROCESSORDIE
# define RelationProcessorDie 5
# define RelationNumaNodeEx 6
# define RelationProcessorModule 7
# endif
#endif /* HAVE_LOGICAL_PROCESSOR_RELATIONSHIP */
#ifndef HAVE_GROUP_AFFINITY
@@ -366,7 +374,7 @@ hwloc_win_get_processor_groups(void)
hwloc_debug("found %lu windows processor groups\n", nr_processor_groups);
if (nr_processor_groups > 1 && SIZEOF_VOID_P == 4) {
if (HWLOC_SHOW_ALL_ERRORS())
if (HWLOC_SHOW_CRITICAL_ERRORS())
fprintf(stderr, "hwloc/windows: multiple processor groups found on 32bits Windows, topology may be invalid/incomplete.\n");
}
@@ -1068,6 +1076,7 @@ hwloc_look_windows(struct hwloc_backend *backend, struct hwloc_disc_status *dsta
id = HWLOC_UNKNOWN_INDEX;
switch (procInfo->Relationship) {
case RelationNumaNodeEx: /* only used on input anyway */
case RelationNumaNode:
type = HWLOC_OBJ_NUMANODE;
/* Starting with Windows 11 and Server 2022, the GroupCount field is valid and >=1
@@ -1087,9 +1096,19 @@ hwloc_look_windows(struct hwloc_backend *backend, struct hwloc_disc_status *dsta
break;
case RelationProcessorPackage:
type = HWLOC_OBJ_PACKAGE;
num = procInfo->Processor.GroupCount;
GroupMask = procInfo->Processor.GroupMask;
break;
case RelationProcessorDie:
type = HWLOC_OBJ_DIE;
num = procInfo->Processor.GroupCount;
GroupMask = procInfo->Processor.GroupMask;
break;
break;
case RelationProcessorModule:
type = HWLOC_OBJ_GROUP;
num = procInfo->Processor.GroupCount;
GroupMask = procInfo->Processor.GroupMask;
break;
case RelationCache:
type = (procInfo->Cache.Type == CacheInstruction ? HWLOC_OBJ_L1ICACHE : HWLOC_OBJ_L1CACHE) + procInfo->Cache.Level - 1;
/* GroupCount added approximately with NumaNode.GroupCount above */
@@ -1211,6 +1230,19 @@ hwloc_look_windows(struct hwloc_backend *backend, struct hwloc_disc_status *dsta
continue;
}
break;
case HWLOC_OBJ_GROUP:
switch (procInfo->Relationship) {
case RelationGroup:
obj->attr->group.kind = HWLOC_GROUP_KIND_WINDOWS_PROCESSOR_GROUP;
break;
case RelationProcessorModule:
obj->attr->group.kind = HWLOC_GROUP_KIND_INTEL_MODULE;
obj->subtype = strdup("Module");
break;
default:
obj->attr->group.kind = HWLOC_GROUP_KIND_WINDOWS_RELATIONSHIP_UNKNOWN;
}
break;
default:
break;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright © 2010-2024 Inria. All rights reserved.
* Copyright © 2010-2025 Inria. All rights reserved.
* Copyright © 2010-2013 Université Bordeaux
* Copyright © 2010-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
@@ -653,7 +653,13 @@ static void look_proc(struct hwloc_backend *backend, struct procinfo *infos, uns
cpuid_or_from_dump(&eax, &ebx, &ecx, &edx, src_cpuiddump);
infos->apicid = ebx >> 24;
if (edx & (1 << 28)) {
legacy_max_log_proc = 1 << hwloc_flsl(((ebx >> 16) & 0xff) - 1);
unsigned ebx_16_23 = (ebx >> 16) & 0xff;
if (ebx_16_23) {
legacy_max_log_proc = 1 << hwloc_flsl(ebx_16_23 - 1);
} else {
hwloc_debug("HTT bit set in CPUID 0x01.edx, but legacy_max_proc = 0 in ebx, assuming legacy_max_log_proc = 1\n");
legacy_max_log_proc = 1;
}
} else {
hwloc_debug("HTT bit not set in CPUID 0x01.edx, assuming legacy_max_log_proc = 1\n");
legacy_max_log_proc = 1;
@@ -1742,7 +1748,7 @@ hwloc_x86_discover(struct hwloc_backend *backend, struct hwloc_disc_status *dsta
if (topology->levels[0][0]->cpuset) {
/* somebody else discovered things, reconnect levels so that we can look at them */
hwloc_topology_reconnect(topology, 0);
hwloc__reconnect(topology, 0);
if (topology->nb_levels == 2 && topology->level_nbobjects[1] == data->nbprocs) {
/* only PUs were discovered, as much as we would, complete the topology with everything else */
alreadypus = 1;

View File

@@ -1,6 +1,6 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2024 Inria. All rights reserved.
* Copyright © 2009-2025 Inria. All rights reserved.
* Copyright © 2009-2011, 2020 Université Bordeaux
* Copyright © 2009-2018 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
@@ -415,6 +415,20 @@ hwloc__xml_import_object_attr(struct hwloc_topology *topology,
}
}
else if (!strcmp(name, "numanode_type")) {
switch (obj->type) {
case HWLOC_OBJ_NUMANODE: {
/* ignored for now, here for possible forward compat */
break;
}
default:
if (hwloc__xml_verbose())
fprintf(stderr, "%s: ignoring numanode_type attribute for non-NUMA object\n",
state->global->msgprefix);
break;
}
}
else if (data->version_major < 2) {
/************************
* deprecated from 1.x
@@ -876,14 +890,19 @@ hwloc__xml_import_object(hwloc_topology_t topology,
/* deal with possible future type */
obj->type = HWLOC_OBJ_GROUP;
obj->attr->group.kind = HWLOC_GROUP_KIND_LINUX_CLUSTER;
} else if (!strcasecmp(attrvalue, "MemCache")) {
}
#if 0
/* reenable if there's ever a future type that should be ignored without being an error */
else if (!strcasecmp(attrvalue, "MemCache")) {
/* ignore possible future type */
obj->type = _HWLOC_OBJ_FUTURE;
ignored = 1;
if (hwloc__xml_verbose())
fprintf(stderr, "%s: %s object not-supported, will be ignored\n",
state->global->msgprefix, attrvalue);
} else {
}
#endif
else {
if (hwloc__xml_verbose())
fprintf(stderr, "%s: unrecognized object type string %s\n",
state->global->msgprefix, attrvalue);
@@ -958,22 +977,22 @@ hwloc__xml_import_object(hwloc_topology_t topology,
if (hwloc__obj_type_is_normal(obj->type)) {
if (!hwloc__obj_type_is_normal(parent->type)) {
if (hwloc__xml_verbose())
fprintf(stderr, "normal object %s cannot be child of non-normal parent %s\n",
hwloc_obj_type_string(obj->type), hwloc_obj_type_string(parent->type));
fprintf(stderr, "%s: normal object %s cannot be child of non-normal parent %s\n",
state->global->msgprefix, hwloc_obj_type_string(obj->type), hwloc_obj_type_string(parent->type));
goto error_with_object;
}
} else if (hwloc__obj_type_is_memory(obj->type)) {
if (hwloc__obj_type_is_io(parent->type) || HWLOC_OBJ_MISC == parent->type) {
if (hwloc__xml_verbose())
fprintf(stderr, "Memory object %s cannot be child of non-normal-or-memory parent %s\n",
hwloc_obj_type_string(obj->type), hwloc_obj_type_string(parent->type));
fprintf(stderr, "%s: Memory object %s cannot be child of non-normal-or-memory parent %s\n",
state->global->msgprefix, hwloc_obj_type_string(obj->type), hwloc_obj_type_string(parent->type));
goto error_with_object;
}
} else if (hwloc__obj_type_is_io(obj->type)) {
if (hwloc__obj_type_is_memory(parent->type) || HWLOC_OBJ_MISC == parent->type) {
if (hwloc__xml_verbose())
fprintf(stderr, "I/O object %s cannot be child of non-normal-or-I/O parent %s\n",
hwloc_obj_type_string(obj->type), hwloc_obj_type_string(parent->type));
fprintf(stderr, "%s: I/O object %s cannot be child of non-normal-or-I/O parent %s\n",
state->global->msgprefix, hwloc_obj_type_string(obj->type), hwloc_obj_type_string(parent->type));
goto error_with_object;
}
}

View File

@@ -1,6 +1,6 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2023 Inria. All rights reserved.
* Copyright © 2009-2025 Inria. All rights reserved.
* Copyright © 2009-2012, 2020 Université Bordeaux
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* Copyright © 2022 IBM Corporation. All rights reserved.
@@ -54,56 +54,6 @@
#endif
#ifdef HWLOC_HAVE_LEVELZERO
/*
* Define ZES_ENABLE_SYSMAN=1 early so that the LevelZero backend gets Sysman enabled.
*
* Only if the levelzero was enabled in this build so that we don't enable sysman
* for external levelzero users when hwloc doesn't need it. If somebody ever loads
* an external levelzero plugin in a hwloc library built without levelzero (unlikely),
* he may have to manually set ZES_ENABLE_SYSMAN=1.
*
* Use the constructor if supported and/or the Windows DllMain callback.
* Do it in the main hwloc library instead of the levelzero component because
* the latter could be loaded later as a plugin.
*
* L0 seems to be using getenv() to check this variable on Windows
* (at least in the Intel Compute-Runtime of March 2021),
* but setenv() doesn't seem to exist on Windows, hence use putenv() to set the variable.
*
* For the record, Get/SetEnvironmentVariable() is not exactly the same as getenv/putenv():
* - getenv() doesn't see what was set with SetEnvironmentVariable()
* - GetEnvironmentVariable() doesn't see putenv() in cygwin (while it does in MSVC and MinGW).
* Hence, if L0 ever switches from getenv() to GetEnvironmentVariable(),
* it will break in cygwin, we'll have to use both putenv() and SetEnvironmentVariable().
* Hopefully L0 will provide a way to enable Sysman without env vars before it happens.
*/
#if HWLOC_HAVE_ATTRIBUTE_CONSTRUCTOR
static void hwloc_constructor(void) __attribute__((constructor));
static void hwloc_constructor(void)
{
if (!getenv("ZES_ENABLE_SYSMAN"))
#ifdef HWLOC_WIN_SYS
putenv("ZES_ENABLE_SYSMAN=1");
#else
setenv("ZES_ENABLE_SYSMAN", "1", 1);
#endif
}
#endif
#ifdef HWLOC_WIN_SYS
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
{
if (fdwReason == DLL_PROCESS_ATTACH) {
if (!getenv("ZES_ENABLE_SYSMAN"))
/* Windows does not have a setenv, so use putenv. */
putenv((char *) "ZES_ENABLE_SYSMAN=1");
}
return TRUE;
}
#endif
#endif /* HWLOC_HAVE_LEVELZERO */
unsigned hwloc_get_api_version(void)
{
return HWLOC_API_VERSION;
@@ -179,7 +129,7 @@ static void report_insert_error(hwloc_obj_t new, hwloc_obj_t old, const char *ms
report_insert_error_format_obj(oldstr, sizeof(oldstr), old);
fprintf(stderr, "****************************************************************************\n");
fprintf(stderr, "* hwloc %s received invalid information from the operating system.\n", HWLOC_VERSION);
fprintf(stderr, "* hwloc %s received invalid information.\n", HWLOC_VERSION);
fprintf(stderr, "*\n");
fprintf(stderr, "* Failed with error: %s\n", msg);
fprintf(stderr, "* while inserting %s\n", newstr);
@@ -1966,6 +1916,51 @@ static void hwloc_set_group_depth(hwloc_topology_t topology);
static void hwloc_connect_children(hwloc_obj_t parent);
static int hwloc_connect_levels(hwloc_topology_t topology);
static int hwloc_connect_special_levels(hwloc_topology_t topology);
static int hwloc_filter_levels_keep_structure(hwloc_topology_t topology);
/* reconnect children and levels,
* and optionnally merged identical levels while keeping structure.
*/
int
hwloc__reconnect(struct hwloc_topology *topology, unsigned long flags)
{
int merged_levels = 0;
if (topology->modified) {
hwloc_connect_children(topology->levels[0][0]);
if (hwloc_connect_levels(topology) < 0)
return -1;
}
if (flags & _HWLOC_RECONNECT_FLAG_KEEPSTRUCTURE) {
merged_levels = hwloc_filter_levels_keep_structure(topology);
/* If > 0, we merged some levels,
* some child+parent special children list may have been merged,
* hence specials level might need reordering,
* So reconnect special levels only here at the end.
*/
}
if (topology->modified || merged_levels) {
if (hwloc_connect_special_levels(topology) < 0)
return -1;
}
topology->modified = 0;
return 0;
}
int
hwloc_topology_reconnect(struct hwloc_topology *topology, unsigned long flags)
{
if (flags) {
errno = EINVAL;
return -1;
}
return hwloc__reconnect(topology, 0);
}
hwloc_obj_t
hwloc_topology_insert_group_object(struct hwloc_topology *topology, hwloc_obj_t obj)
@@ -2058,7 +2053,10 @@ hwloc_topology_insert_group_object(struct hwloc_topology *topology, hwloc_obj_t
/* properly inserted */
hwloc_obj_add_children_sets(res);
if (hwloc_topology_reconnect(topology, 0) < 0)
/* reconnect levels.
* no need to filter levels keep_structure because groups are either auto-merged
* or have the dont_merge attribute */
if (hwloc__reconnect(topology, 0) < 0)
return NULL;
/* Compute group total_memory. */
@@ -2550,26 +2548,13 @@ hwloc_compare_levels_structure(hwloc_topology_t topology, unsigned i)
return 0;
}
/* return > 0 if any level was removed.
* performs its own reconnect internally if needed
*/
/* return > 0 if any level was removed. */
static int
hwloc_filter_levels_keep_structure(hwloc_topology_t topology)
{
unsigned i, j;
int res = 0;
if (topology->modified) {
/* WARNING: hwloc_topology_reconnect() is duplicated partially here
* and at the end of this function:
* - we need normal levels before merging.
* - and we'll need to update special levels after merging.
*/
hwloc_connect_children(topology->levels[0][0]);
if (hwloc_connect_levels(topology) < 0)
return -1;
}
/* start from the bottom since we'll remove intermediate levels */
for(i=topology->nb_levels-1; i>0; i--) {
int replacechild = 0, replaceparent = 0;
@@ -2591,9 +2576,15 @@ hwloc_filter_levels_keep_structure(hwloc_topology_t topology)
if (type1 == HWLOC_OBJ_GROUP && hwloc_dont_merge_group_level(topology, i))
replacechild = 0;
}
if (!replacechild && !replaceparent)
if (!replacechild && !replaceparent) {
/* always merge Die into Package when levels are identical */
if (type1 == HWLOC_OBJ_PACKAGE && type2 == HWLOC_OBJ_DIE)
replacechild = 1;
}
if (!replacechild && !replaceparent) {
/* no ignoring */
continue;
}
/* Decide which one to actually replace */
if (replaceparent && replacechild) {
/* If both may be replaced, look at obj_type_priority */
@@ -2736,20 +2727,6 @@ hwloc_filter_levels_keep_structure(hwloc_topology_t topology)
}
}
if (res > 0 || topology-> modified) {
/* WARNING: hwloc_topology_reconnect() is duplicated partially here
* and at the beginning of this function.
* If we merged some levels, some child+parent special children lisst
* may have been merged, hence specials level might need reordering,
* So reconnect special levels only here at the end
* (it's not needed at the beginning of this function).
*/
if (hwloc_connect_special_levels(topology) < 0)
return -1;
topology->modified = 0;
}
return 0;
}
@@ -3278,33 +3255,6 @@ hwloc_connect_levels(hwloc_topology_t topology)
return 0;
}
int
hwloc_topology_reconnect(struct hwloc_topology *topology, unsigned long flags)
{
/* WARNING: when updating this function, the replicated code must
* also be updated inside hwloc_filter_levels_keep_structure()
*/
if (flags) {
errno = EINVAL;
return -1;
}
if (!topology->modified)
return 0;
hwloc_connect_children(topology->levels[0][0]);
if (hwloc_connect_levels(topology) < 0)
return -1;
if (hwloc_connect_special_levels(topology) < 0)
return -1;
topology->modified = 0;
return 0;
}
/* for regression testing, make sure the order of io devices
* doesn't change with the dentry order in the filesystem
*
@@ -3561,32 +3511,13 @@ hwloc_discover(struct hwloc_topology *topology,
hwloc_debug_print_objects(0, topology->levels[0][0]);
}
/* see if we should ignore the root now that we know how many children it has */
if (!hwloc_filter_check_keep_object(topology, topology->levels[0][0])
&& topology->levels[0][0]->first_child && !topology->levels[0][0]->first_child->next_sibling) {
hwloc_obj_t oldroot = topology->levels[0][0];
hwloc_obj_t newroot = oldroot->first_child;
/* switch to the new root */
newroot->parent = NULL;
topology->levels[0][0] = newroot;
/* move oldroot memory/io/misc children before newroot children */
if (oldroot->memory_first_child)
prepend_siblings_list(&newroot->memory_first_child, oldroot->memory_first_child, newroot);
if (oldroot->io_first_child)
prepend_siblings_list(&newroot->io_first_child, oldroot->io_first_child, newroot);
if (oldroot->misc_first_child)
prepend_siblings_list(&newroot->misc_first_child, oldroot->misc_first_child, newroot);
/* destroy oldroot and use the new one */
hwloc_free_unlinked_object(oldroot);
}
/*
* All object cpusets and nodesets are properly set now.
*/
/* Now connect handy pointers to make remaining discovery easier. */
hwloc_debug("%s", "\nOk, finished tweaking, now connect\n");
if (hwloc_topology_reconnect(topology, 0) < 0)
if (hwloc__reconnect(topology, 0) < 0)
return -1;
hwloc_debug_print_objects(0, topology->levels[0][0]);
@@ -3642,12 +3573,12 @@ hwloc_discover(struct hwloc_topology *topology,
}
hwloc_debug_print_objects(0, topology->levels[0][0]);
/* reconnect all (new groups might have appears, IO added, etc),
* and (now that everything was added) remove identical levels while keeping structure
*/
hwloc_debug("%s", "\nRemoving levels with HWLOC_TYPE_FILTER_KEEP_STRUCTURE\n");
if (hwloc_filter_levels_keep_structure(topology) < 0)
if (hwloc__reconnect(topology, _HWLOC_RECONNECT_FLAG_KEEPSTRUCTURE) < 0)
return -1;
/* takes care of reconnecting children/levels internally,
* because it needs normal levels.
* and it's often needed below because of Groups inserted for I/Os anyway */
hwloc_debug_print_objects(0, topology->levels[0][0]);
/* accumulate children memory in total_memory fields (only once parent is set) */
@@ -4494,7 +4425,7 @@ hwloc_topology_restrict(struct hwloc_topology *topology, hwloc_const_bitmap_t se
hwloc_bitmap_free(droppedcpuset);
hwloc_bitmap_free(droppednodeset);
if (hwloc_filter_levels_keep_structure(topology) < 0) /* takes care of reconnecting internally */
if (hwloc__reconnect(topology, _HWLOC_RECONNECT_FLAG_KEEPSTRUCTURE) < 0)
goto out;
/* some objects may have disappeared and sets were modified,
@@ -5116,6 +5047,8 @@ hwloc_topology_check(struct hwloc_topology *topology)
unsigned i;
int j, depth;
assert(!topology->modified);
/* make sure we can use ranges to check types */
/* hwloc__obj_type_is_{,d,i}cache() want cache types to be ordered like this */

View File

@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.5)
cmake_minimum_required(VERSION 3.10)
project (ethash C)
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Os")

View File

@@ -4,7 +4,7 @@
#include "llhttp.h"
#define CALLBACK_MAYBE(PARSER, NAME, ...) \
#define CALLBACK_MAYBE(PARSER, NAME) \
do { \
const llhttp_settings_t* settings; \
settings = (const llhttp_settings_t*) (PARSER)->settings; \
@@ -12,7 +12,22 @@
err = 0; \
break; \
} \
err = settings->NAME(__VA_ARGS__); \
err = settings->NAME((PARSER)); \
} while (0)
#define SPAN_CALLBACK_MAYBE(PARSER, NAME, START, LEN) \
do { \
const llhttp_settings_t* settings; \
settings = (const llhttp_settings_t*) (PARSER)->settings; \
if (settings == NULL || settings->NAME == NULL) { \
err = 0; \
break; \
} \
err = settings->NAME((PARSER), (START), (LEN)); \
if (err == -1) { \
err = HPE_USER; \
llhttp_set_error_reason((PARSER), "Span callback error in " #NAME); \
} \
} while (0)
void llhttp_init(llhttp_t* parser, llhttp_type_t type,
@@ -31,21 +46,25 @@ extern int wasm_on_url(llhttp_t* p, const char* at, size_t length);
extern int wasm_on_status(llhttp_t* p, const char* at, size_t length);
extern int wasm_on_header_field(llhttp_t* p, const char* at, size_t length);
extern int wasm_on_header_value(llhttp_t* p, const char* at, size_t length);
extern int wasm_on_headers_complete(llhttp_t * p);
extern int wasm_on_headers_complete(llhttp_t * p, int status_code,
uint8_t upgrade, int should_keep_alive);
extern int wasm_on_body(llhttp_t* p, const char* at, size_t length);
extern int wasm_on_message_complete(llhttp_t * p);
static int wasm_on_headers_complete_wrap(llhttp_t* p) {
return wasm_on_headers_complete(p, p->status_code, p->upgrade,
llhttp_should_keep_alive(p));
}
const llhttp_settings_t wasm_settings = {
wasm_on_message_begin,
wasm_on_url,
wasm_on_status,
wasm_on_header_field,
wasm_on_header_value,
wasm_on_headers_complete,
wasm_on_body,
wasm_on_message_complete,
NULL,
NULL,
.on_message_begin = wasm_on_message_begin,
.on_url = wasm_on_url,
.on_status = wasm_on_status,
.on_header_field = wasm_on_header_field,
.on_header_value = wasm_on_header_value,
.on_headers_complete = wasm_on_headers_complete_wrap,
.on_body = wasm_on_body,
.on_message_complete = wasm_on_message_complete,
};
@@ -59,6 +78,8 @@ void llhttp_free(llhttp_t* parser) {
free(parser);
}
#endif // defined(__wasm__)
/* Some getters required to get stuff from the parser */
uint8_t llhttp_get_type(llhttp_t* parser) {
@@ -85,14 +106,12 @@ uint8_t llhttp_get_upgrade(llhttp_t* parser) {
return parser->upgrade;
}
#endif // defined(__wasm__)
void llhttp_reset(llhttp_t* parser) {
llhttp_type_t type = parser->type;
const llhttp_settings_t* settings = parser->settings;
void* data = parser->data;
uint8_t lenient_flags = parser->lenient_flags;
uint16_t lenient_flags = parser->lenient_flags;
llhttp__internal_init(parser);
@@ -123,7 +142,7 @@ llhttp_errno_t llhttp_finish(llhttp_t* parser) {
switch (parser->finish) {
case HTTP_FINISH_SAFE_WITH_CB:
CALLBACK_MAYBE(parser, on_message_complete, parser);
CALLBACK_MAYBE(parser, on_message_complete);
if (err != HPE_OK) return err;
/* FALLTHROUGH */
@@ -199,12 +218,21 @@ const char* llhttp_errno_name(llhttp_errno_t err) {
const char* llhttp_method_name(llhttp_method_t method) {
#define HTTP_METHOD_GEN(NUM, NAME, STRING) case HTTP_##NAME: return #STRING;
switch (method) {
HTTP_METHOD_MAP(HTTP_METHOD_GEN)
HTTP_ALL_METHOD_MAP(HTTP_METHOD_GEN)
default: abort();
}
#undef HTTP_METHOD_GEN
}
const char* llhttp_status_name(llhttp_status_t status) {
#define HTTP_STATUS_GEN(NUM, NAME, STRING) case HTTP_STATUS_##NAME: return #STRING;
switch (status) {
HTTP_STATUS_MAP(HTTP_STATUS_GEN)
default: abort();
}
#undef HTTP_STATUS_GEN
}
void llhttp_set_lenient_headers(llhttp_t* parser, int enabled) {
if (enabled) {
@@ -232,103 +260,236 @@ void llhttp_set_lenient_keep_alive(llhttp_t* parser, int enabled) {
}
}
void llhttp_set_lenient_transfer_encoding(llhttp_t* parser, int enabled) {
if (enabled) {
parser->lenient_flags |= LENIENT_TRANSFER_ENCODING;
} else {
parser->lenient_flags &= ~LENIENT_TRANSFER_ENCODING;
}
}
void llhttp_set_lenient_version(llhttp_t* parser, int enabled) {
if (enabled) {
parser->lenient_flags |= LENIENT_VERSION;
} else {
parser->lenient_flags &= ~LENIENT_VERSION;
}
}
void llhttp_set_lenient_data_after_close(llhttp_t* parser, int enabled) {
if (enabled) {
parser->lenient_flags |= LENIENT_DATA_AFTER_CLOSE;
} else {
parser->lenient_flags &= ~LENIENT_DATA_AFTER_CLOSE;
}
}
void llhttp_set_lenient_optional_lf_after_cr(llhttp_t* parser, int enabled) {
if (enabled) {
parser->lenient_flags |= LENIENT_OPTIONAL_LF_AFTER_CR;
} else {
parser->lenient_flags &= ~LENIENT_OPTIONAL_LF_AFTER_CR;
}
}
void llhttp_set_lenient_optional_crlf_after_chunk(llhttp_t* parser, int enabled) {
if (enabled) {
parser->lenient_flags |= LENIENT_OPTIONAL_CRLF_AFTER_CHUNK;
} else {
parser->lenient_flags &= ~LENIENT_OPTIONAL_CRLF_AFTER_CHUNK;
}
}
void llhttp_set_lenient_optional_cr_before_lf(llhttp_t* parser, int enabled) {
if (enabled) {
parser->lenient_flags |= LENIENT_OPTIONAL_CR_BEFORE_LF;
} else {
parser->lenient_flags &= ~LENIENT_OPTIONAL_CR_BEFORE_LF;
}
}
void llhttp_set_lenient_spaces_after_chunk_size(llhttp_t* parser, int enabled) {
if (enabled) {
parser->lenient_flags |= LENIENT_SPACES_AFTER_CHUNK_SIZE;
} else {
parser->lenient_flags &= ~LENIENT_SPACES_AFTER_CHUNK_SIZE;
}
}
/* Callbacks */
int llhttp__on_message_begin(llhttp_t* s, const char* p, const char* endp) {
int err;
CALLBACK_MAYBE(s, on_message_begin, s);
CALLBACK_MAYBE(s, on_message_begin);
return err;
}
int llhttp__on_protocol(llhttp_t* s, const char* p, const char* endp) {
int err;
SPAN_CALLBACK_MAYBE(s, on_protocol, p, endp - p);
return err;
}
int llhttp__on_protocol_complete(llhttp_t* s, const char* p, const char* endp) {
int err;
CALLBACK_MAYBE(s, on_protocol_complete);
return err;
}
int llhttp__on_url(llhttp_t* s, const char* p, const char* endp) {
int err;
CALLBACK_MAYBE(s, on_url, s, p, endp - p);
SPAN_CALLBACK_MAYBE(s, on_url, p, endp - p);
return err;
}
int llhttp__on_url_complete(llhttp_t* s, const char* p, const char* endp) {
int err;
CALLBACK_MAYBE(s, on_url_complete, s);
CALLBACK_MAYBE(s, on_url_complete);
return err;
}
int llhttp__on_status(llhttp_t* s, const char* p, const char* endp) {
int err;
CALLBACK_MAYBE(s, on_status, s, p, endp - p);
SPAN_CALLBACK_MAYBE(s, on_status, p, endp - p);
return err;
}
int llhttp__on_status_complete(llhttp_t* s, const char* p, const char* endp) {
int err;
CALLBACK_MAYBE(s, on_status_complete, s);
CALLBACK_MAYBE(s, on_status_complete);
return err;
}
int llhttp__on_method(llhttp_t* s, const char* p, const char* endp) {
int err;
SPAN_CALLBACK_MAYBE(s, on_method, p, endp - p);
return err;
}
int llhttp__on_method_complete(llhttp_t* s, const char* p, const char* endp) {
int err;
CALLBACK_MAYBE(s, on_method_complete);
return err;
}
int llhttp__on_version(llhttp_t* s, const char* p, const char* endp) {
int err;
SPAN_CALLBACK_MAYBE(s, on_version, p, endp - p);
return err;
}
int llhttp__on_version_complete(llhttp_t* s, const char* p, const char* endp) {
int err;
CALLBACK_MAYBE(s, on_version_complete);
return err;
}
int llhttp__on_header_field(llhttp_t* s, const char* p, const char* endp) {
int err;
CALLBACK_MAYBE(s, on_header_field, s, p, endp - p);
SPAN_CALLBACK_MAYBE(s, on_header_field, p, endp - p);
return err;
}
int llhttp__on_header_field_complete(llhttp_t* s, const char* p, const char* endp) {
int err;
CALLBACK_MAYBE(s, on_header_field_complete, s);
CALLBACK_MAYBE(s, on_header_field_complete);
return err;
}
int llhttp__on_header_value(llhttp_t* s, const char* p, const char* endp) {
int err;
CALLBACK_MAYBE(s, on_header_value, s, p, endp - p);
SPAN_CALLBACK_MAYBE(s, on_header_value, p, endp - p);
return err;
}
int llhttp__on_header_value_complete(llhttp_t* s, const char* p, const char* endp) {
int err;
CALLBACK_MAYBE(s, on_header_value_complete, s);
CALLBACK_MAYBE(s, on_header_value_complete);
return err;
}
int llhttp__on_headers_complete(llhttp_t* s, const char* p, const char* endp) {
int err;
CALLBACK_MAYBE(s, on_headers_complete, s);
CALLBACK_MAYBE(s, on_headers_complete);
return err;
}
int llhttp__on_message_complete(llhttp_t* s, const char* p, const char* endp) {
int err;
CALLBACK_MAYBE(s, on_message_complete, s);
CALLBACK_MAYBE(s, on_message_complete);
return err;
}
int llhttp__on_body(llhttp_t* s, const char* p, const char* endp) {
int err;
CALLBACK_MAYBE(s, on_body, s, p, endp - p);
SPAN_CALLBACK_MAYBE(s, on_body, p, endp - p);
return err;
}
int llhttp__on_chunk_header(llhttp_t* s, const char* p, const char* endp) {
int err;
CALLBACK_MAYBE(s, on_chunk_header, s);
CALLBACK_MAYBE(s, on_chunk_header);
return err;
}
int llhttp__on_chunk_extension_name(llhttp_t* s, const char* p, const char* endp) {
int err;
SPAN_CALLBACK_MAYBE(s, on_chunk_extension_name, p, endp - p);
return err;
}
int llhttp__on_chunk_extension_name_complete(llhttp_t* s, const char* p, const char* endp) {
int err;
CALLBACK_MAYBE(s, on_chunk_extension_name_complete);
return err;
}
int llhttp__on_chunk_extension_value(llhttp_t* s, const char* p, const char* endp) {
int err;
SPAN_CALLBACK_MAYBE(s, on_chunk_extension_value, p, endp - p);
return err;
}
int llhttp__on_chunk_extension_value_complete(llhttp_t* s, const char* p, const char* endp) {
int err;
CALLBACK_MAYBE(s, on_chunk_extension_value_complete);
return err;
}
int llhttp__on_chunk_complete(llhttp_t* s, const char* p, const char* endp) {
int err;
CALLBACK_MAYBE(s, on_chunk_complete, s);
CALLBACK_MAYBE(s, on_chunk_complete);
return err;
}
int llhttp__on_reset(llhttp_t* s, const char* p, const char* endp) {
int err;
CALLBACK_MAYBE(s, on_reset);
return err;
}

View File

@@ -1,253 +0,0 @@
#ifndef INCLUDE_LLHTTP_API_H_
#define INCLUDE_LLHTTP_API_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stddef.h>
#if defined(__wasm__)
#define LLHTTP_EXPORT __attribute__((visibility("default")))
#else
#define LLHTTP_EXPORT
#endif
typedef llhttp__internal_t llhttp_t;
typedef struct llhttp_settings_s llhttp_settings_t;
typedef int (*llhttp_data_cb)(llhttp_t*, const char *at, size_t length);
typedef int (*llhttp_cb)(llhttp_t*);
struct llhttp_settings_s {
/* Possible return values 0, -1, `HPE_PAUSED` */
llhttp_cb on_message_begin;
llhttp_data_cb on_url;
llhttp_data_cb on_status;
llhttp_data_cb on_header_field;
llhttp_data_cb on_header_value;
/* Possible return values:
* 0 - Proceed normally
* 1 - Assume that request/response has no body, and proceed to parsing the
* next message
* 2 - Assume absence of body (as above) and make `llhttp_execute()` return
* `HPE_PAUSED_UPGRADE`
* -1 - Error
* `HPE_PAUSED`
*/
llhttp_cb on_headers_complete;
llhttp_data_cb on_body;
/* Possible return values 0, -1, `HPE_PAUSED` */
llhttp_cb on_message_complete;
/* When on_chunk_header is called, the current chunk length is stored
* in parser->content_length.
* Possible return values 0, -1, `HPE_PAUSED`
*/
llhttp_cb on_chunk_header;
llhttp_cb on_chunk_complete;
llhttp_cb on_url_complete;
llhttp_cb on_status_complete;
llhttp_cb on_header_field_complete;
llhttp_cb on_header_value_complete;
};
/* Initialize the parser with specific type and user settings.
*
* NOTE: lifetime of `settings` has to be at least the same as the lifetime of
* the `parser` here. In practice, `settings` has to be either a static
* variable or be allocated with `malloc`, `new`, etc.
*/
LLHTTP_EXPORT
void llhttp_init(llhttp_t* parser, llhttp_type_t type,
const llhttp_settings_t* settings);
#if defined(__wasm__)
LLHTTP_EXPORT
llhttp_t* llhttp_alloc(llhttp_type_t type);
LLHTTP_EXPORT
void llhttp_free(llhttp_t* parser);
LLHTTP_EXPORT
uint8_t llhttp_get_type(llhttp_t* parser);
LLHTTP_EXPORT
uint8_t llhttp_get_http_major(llhttp_t* parser);
LLHTTP_EXPORT
uint8_t llhttp_get_http_minor(llhttp_t* parser);
LLHTTP_EXPORT
uint8_t llhttp_get_method(llhttp_t* parser);
LLHTTP_EXPORT
int llhttp_get_status_code(llhttp_t* parser);
LLHTTP_EXPORT
uint8_t llhttp_get_upgrade(llhttp_t* parser);
#endif // defined(__wasm__)
/* Reset an already initialized parser back to the start state, preserving the
* existing parser type, callback settings, user data, and lenient flags.
*/
LLHTTP_EXPORT
void llhttp_reset(llhttp_t* parser);
/* Initialize the settings object */
LLHTTP_EXPORT
void llhttp_settings_init(llhttp_settings_t* settings);
/* Parse full or partial request/response, invoking user callbacks along the
* way.
*
* If any of `llhttp_data_cb` returns errno not equal to `HPE_OK` - the parsing
* interrupts, and such errno is returned from `llhttp_execute()`. If
* `HPE_PAUSED` was used as a errno, the execution can be resumed with
* `llhttp_resume()` call.
*
* In a special case of CONNECT/Upgrade request/response `HPE_PAUSED_UPGRADE`
* is returned after fully parsing the request/response. If the user wishes to
* continue parsing, they need to invoke `llhttp_resume_after_upgrade()`.
*
* NOTE: if this function ever returns a non-pause type error, it will continue
* to return the same error upon each successive call up until `llhttp_init()`
* is called.
*/
LLHTTP_EXPORT
llhttp_errno_t llhttp_execute(llhttp_t* parser, const char* data, size_t len);
/* This method should be called when the other side has no further bytes to
* send (e.g. shutdown of readable side of the TCP connection.)
*
* Requests without `Content-Length` and other messages might require treating
* all incoming bytes as the part of the body, up to the last byte of the
* connection. This method will invoke `on_message_complete()` callback if the
* request was terminated safely. Otherwise a error code would be returned.
*/
LLHTTP_EXPORT
llhttp_errno_t llhttp_finish(llhttp_t* parser);
/* Returns `1` if the incoming message is parsed until the last byte, and has
* to be completed by calling `llhttp_finish()` on EOF
*/
LLHTTP_EXPORT
int llhttp_message_needs_eof(const llhttp_t* parser);
/* Returns `1` if there might be any other messages following the last that was
* successfully parsed.
*/
LLHTTP_EXPORT
int llhttp_should_keep_alive(const llhttp_t* parser);
/* Make further calls of `llhttp_execute()` return `HPE_PAUSED` and set
* appropriate error reason.
*
* Important: do not call this from user callbacks! User callbacks must return
* `HPE_PAUSED` if pausing is required.
*/
LLHTTP_EXPORT
void llhttp_pause(llhttp_t* parser);
/* Might be called to resume the execution after the pause in user's callback.
* See `llhttp_execute()` above for details.
*
* Call this only if `llhttp_execute()` returns `HPE_PAUSED`.
*/
LLHTTP_EXPORT
void llhttp_resume(llhttp_t* parser);
/* Might be called to resume the execution after the pause in user's callback.
* See `llhttp_execute()` above for details.
*
* Call this only if `llhttp_execute()` returns `HPE_PAUSED_UPGRADE`
*/
LLHTTP_EXPORT
void llhttp_resume_after_upgrade(llhttp_t* parser);
/* Returns the latest return error */
LLHTTP_EXPORT
llhttp_errno_t llhttp_get_errno(const llhttp_t* parser);
/* Returns the verbal explanation of the latest returned error.
*
* Note: User callback should set error reason when returning the error. See
* `llhttp_set_error_reason()` for details.
*/
LLHTTP_EXPORT
const char* llhttp_get_error_reason(const llhttp_t* parser);
/* Assign verbal description to the returned error. Must be called in user
* callbacks right before returning the errno.
*
* Note: `HPE_USER` error code might be useful in user callbacks.
*/
LLHTTP_EXPORT
void llhttp_set_error_reason(llhttp_t* parser, const char* reason);
/* Returns the pointer to the last parsed byte before the returned error. The
* pointer is relative to the `data` argument of `llhttp_execute()`.
*
* Note: this method might be useful for counting the number of parsed bytes.
*/
LLHTTP_EXPORT
const char* llhttp_get_error_pos(const llhttp_t* parser);
/* Returns textual name of error code */
LLHTTP_EXPORT
const char* llhttp_errno_name(llhttp_errno_t err);
/* Returns textual name of HTTP method */
LLHTTP_EXPORT
const char* llhttp_method_name(llhttp_method_t method);
/* Enables/disables lenient header value parsing (disabled by default).
*
* Lenient parsing disables header value token checks, extending llhttp's
* protocol support to highly non-compliant clients/server. No
* `HPE_INVALID_HEADER_TOKEN` will be raised for incorrect header values when
* lenient parsing is "on".
*
* **(USE AT YOUR OWN RISK)**
*/
LLHTTP_EXPORT
void llhttp_set_lenient_headers(llhttp_t* parser, int enabled);
/* Enables/disables lenient handling of conflicting `Transfer-Encoding` and
* `Content-Length` headers (disabled by default).
*
* Normally `llhttp` would error when `Transfer-Encoding` is present in
* conjunction with `Content-Length`. This error is important to prevent HTTP
* request smuggling, but may be less desirable for small number of cases
* involving legacy servers.
*
* **(USE AT YOUR OWN RISK)**
*/
LLHTTP_EXPORT
void llhttp_set_lenient_chunked_length(llhttp_t* parser, int enabled);
/* Enables/disables lenient handling of `Connection: close` and HTTP/1.0
* requests responses.
*
* Normally `llhttp` would error on (in strict mode) or discard (in loose mode)
* the HTTP request/response after the request/response with `Connection: close`
* and `Content-Length`. This is important to prevent cache poisoning attacks,
* but might interact badly with outdated and insecure clients. With this flag
* the extra request/response will be parsed normally.
*
* **(USE AT YOUR OWN RISK)**
*/
void llhttp_set_lenient_keep_alive(llhttp_t* parser, int enabled);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* INCLUDE_LLHTTP_API_H_ */

View File

@@ -39,20 +39,41 @@ int llhttp__after_headers_complete(llhttp_t* parser, const char* p,
int hasBody;
hasBody = parser->flags & F_CHUNKED || parser->content_length > 0;
if (parser->upgrade && (parser->method == HTTP_CONNECT ||
(parser->flags & F_SKIPBODY) || !hasBody)) {
if (
(parser->upgrade && (parser->method == HTTP_CONNECT ||
(parser->flags & F_SKIPBODY) || !hasBody)) ||
/* See RFC 2616 section 4.4 - 1xx e.g. Continue */
(parser->type == HTTP_RESPONSE && parser->status_code == 101)
) {
/* Exit, the rest of the message is in a different protocol. */
return 1;
}
if (parser->flags & F_SKIPBODY) {
if (parser->type == HTTP_RESPONSE && parser->status_code == 100) {
/* No body, restart as the message is complete */
return 0;
}
/* See RFC 2616 section 4.4 */
if (
parser->flags & F_SKIPBODY || /* response to a HEAD request */
(
parser->type == HTTP_RESPONSE && (
parser->status_code == 102 || /* Processing */
parser->status_code == 103 || /* Early Hints */
parser->status_code == 204 || /* No Content */
parser->status_code == 304 /* Not Modified */
)
)
) {
return 0;
} else if (parser->flags & F_CHUNKED) {
/* chunked encoding - ignore Content-Length header, prepare for a chunk */
return 2;
} else if (parser->flags & F_TRANSFER_ENCODING) {
if (parser->type == HTTP_REQUEST &&
(parser->lenient_flags & LENIENT_CHUNKED_LENGTH) == 0) {
(parser->lenient_flags & LENIENT_CHUNKED_LENGTH) == 0 &&
(parser->lenient_flags & LENIENT_TRANSFER_ENCODING) == 0) {
/* RFC 7230 3.3.3 */
/* If a Transfer-Encoding header field

File diff suppressed because it is too large Load Diff

View File

@@ -1,14 +1,11 @@
#ifndef INCLUDE_LLHTTP_H_
#define INCLUDE_LLHTTP_H_
#define LLHTTP_VERSION_MAJOR 5
#define LLHTTP_VERSION_MINOR 1
#define LLHTTP_VERSION_MAJOR 9
#define LLHTTP_VERSION_MINOR 3
#define LLHTTP_VERSION_PATCH 0
#ifndef LLHTTP_STRICT_MODE
# define LLHTTP_STRICT_MODE 0
#endif
#ifndef INCLUDE_LLHTTP_ITSELF_H_
#define INCLUDE_LLHTTP_ITSELF_H_
#ifdef __cplusplus
@@ -33,11 +30,12 @@ struct llhttp__internal_s {
uint8_t http_major;
uint8_t http_minor;
uint8_t header_state;
uint8_t lenient_flags;
uint16_t lenient_flags;
uint8_t upgrade;
uint8_t finish;
uint16_t flags;
uint16_t status_code;
uint8_t initial_message_completed;
void* settings;
};
@@ -49,6 +47,7 @@ int llhttp__internal_execute(llhttp__internal_t* s, const char* p, const char* e
#endif
#endif /* INCLUDE_LLHTTP_ITSELF_H_ */
#ifndef LLLLHTTP_C_HEADERS_
#define LLLLHTTP_C_HEADERS_
#ifdef __cplusplus
@@ -59,8 +58,10 @@ enum llhttp_errno {
HPE_OK = 0,
HPE_INTERNAL = 1,
HPE_STRICT = 2,
HPE_CR_EXPECTED = 25,
HPE_LF_EXPECTED = 3,
HPE_UNEXPECTED_CONTENT_LENGTH = 4,
HPE_UNEXPECTED_SPACE = 30,
HPE_CLOSED_CONNECTION = 5,
HPE_INVALID_METHOD = 6,
HPE_INVALID_URL = 7,
@@ -80,7 +81,17 @@ enum llhttp_errno {
HPE_PAUSED = 21,
HPE_PAUSED_UPGRADE = 22,
HPE_PAUSED_H2_UPGRADE = 23,
HPE_USER = 24
HPE_USER = 24,
HPE_CB_URL_COMPLETE = 26,
HPE_CB_STATUS_COMPLETE = 27,
HPE_CB_METHOD_COMPLETE = 32,
HPE_CB_VERSION_COMPLETE = 33,
HPE_CB_HEADER_FIELD_COMPLETE = 28,
HPE_CB_HEADER_VALUE_COMPLETE = 29,
HPE_CB_CHUNK_EXTENSION_NAME_COMPLETE = 34,
HPE_CB_CHUNK_EXTENSION_VALUE_COMPLETE = 35,
HPE_CB_RESET = 31,
HPE_CB_PROTOCOL_COMPLETE = 38
};
typedef enum llhttp_errno llhttp_errno_t;
@@ -100,7 +111,14 @@ typedef enum llhttp_flags llhttp_flags_t;
enum llhttp_lenient_flags {
LENIENT_HEADERS = 0x1,
LENIENT_CHUNKED_LENGTH = 0x2,
LENIENT_KEEP_ALIVE = 0x4
LENIENT_KEEP_ALIVE = 0x4,
LENIENT_TRANSFER_ENCODING = 0x8,
LENIENT_VERSION = 0x10,
LENIENT_DATA_AFTER_CLOSE = 0x20,
LENIENT_OPTIONAL_LF_AFTER_CR = 0x40,
LENIENT_OPTIONAL_CRLF_AFTER_CHUNK = 0x80,
LENIENT_OPTIONAL_CR_BEFORE_LF = 0x100,
LENIENT_SPACES_AFTER_CHUNK_SIZE = 0x200
};
typedef enum llhttp_lenient_flags llhttp_lenient_flags_t;
@@ -164,16 +182,122 @@ enum llhttp_method {
HTTP_SET_PARAMETER = 42,
HTTP_REDIRECT = 43,
HTTP_RECORD = 44,
HTTP_FLUSH = 45
HTTP_FLUSH = 45,
HTTP_QUERY = 46
};
typedef enum llhttp_method llhttp_method_t;
enum llhttp_status {
HTTP_STATUS_CONTINUE = 100,
HTTP_STATUS_SWITCHING_PROTOCOLS = 101,
HTTP_STATUS_PROCESSING = 102,
HTTP_STATUS_EARLY_HINTS = 103,
HTTP_STATUS_RESPONSE_IS_STALE = 110,
HTTP_STATUS_REVALIDATION_FAILED = 111,
HTTP_STATUS_DISCONNECTED_OPERATION = 112,
HTTP_STATUS_HEURISTIC_EXPIRATION = 113,
HTTP_STATUS_MISCELLANEOUS_WARNING = 199,
HTTP_STATUS_OK = 200,
HTTP_STATUS_CREATED = 201,
HTTP_STATUS_ACCEPTED = 202,
HTTP_STATUS_NON_AUTHORITATIVE_INFORMATION = 203,
HTTP_STATUS_NO_CONTENT = 204,
HTTP_STATUS_RESET_CONTENT = 205,
HTTP_STATUS_PARTIAL_CONTENT = 206,
HTTP_STATUS_MULTI_STATUS = 207,
HTTP_STATUS_ALREADY_REPORTED = 208,
HTTP_STATUS_TRANSFORMATION_APPLIED = 214,
HTTP_STATUS_IM_USED = 226,
HTTP_STATUS_MISCELLANEOUS_PERSISTENT_WARNING = 299,
HTTP_STATUS_MULTIPLE_CHOICES = 300,
HTTP_STATUS_MOVED_PERMANENTLY = 301,
HTTP_STATUS_FOUND = 302,
HTTP_STATUS_SEE_OTHER = 303,
HTTP_STATUS_NOT_MODIFIED = 304,
HTTP_STATUS_USE_PROXY = 305,
HTTP_STATUS_SWITCH_PROXY = 306,
HTTP_STATUS_TEMPORARY_REDIRECT = 307,
HTTP_STATUS_PERMANENT_REDIRECT = 308,
HTTP_STATUS_BAD_REQUEST = 400,
HTTP_STATUS_UNAUTHORIZED = 401,
HTTP_STATUS_PAYMENT_REQUIRED = 402,
HTTP_STATUS_FORBIDDEN = 403,
HTTP_STATUS_NOT_FOUND = 404,
HTTP_STATUS_METHOD_NOT_ALLOWED = 405,
HTTP_STATUS_NOT_ACCEPTABLE = 406,
HTTP_STATUS_PROXY_AUTHENTICATION_REQUIRED = 407,
HTTP_STATUS_REQUEST_TIMEOUT = 408,
HTTP_STATUS_CONFLICT = 409,
HTTP_STATUS_GONE = 410,
HTTP_STATUS_LENGTH_REQUIRED = 411,
HTTP_STATUS_PRECONDITION_FAILED = 412,
HTTP_STATUS_PAYLOAD_TOO_LARGE = 413,
HTTP_STATUS_URI_TOO_LONG = 414,
HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE = 415,
HTTP_STATUS_RANGE_NOT_SATISFIABLE = 416,
HTTP_STATUS_EXPECTATION_FAILED = 417,
HTTP_STATUS_IM_A_TEAPOT = 418,
HTTP_STATUS_PAGE_EXPIRED = 419,
HTTP_STATUS_ENHANCE_YOUR_CALM = 420,
HTTP_STATUS_MISDIRECTED_REQUEST = 421,
HTTP_STATUS_UNPROCESSABLE_ENTITY = 422,
HTTP_STATUS_LOCKED = 423,
HTTP_STATUS_FAILED_DEPENDENCY = 424,
HTTP_STATUS_TOO_EARLY = 425,
HTTP_STATUS_UPGRADE_REQUIRED = 426,
HTTP_STATUS_PRECONDITION_REQUIRED = 428,
HTTP_STATUS_TOO_MANY_REQUESTS = 429,
HTTP_STATUS_REQUEST_HEADER_FIELDS_TOO_LARGE_UNOFFICIAL = 430,
HTTP_STATUS_REQUEST_HEADER_FIELDS_TOO_LARGE = 431,
HTTP_STATUS_LOGIN_TIMEOUT = 440,
HTTP_STATUS_NO_RESPONSE = 444,
HTTP_STATUS_RETRY_WITH = 449,
HTTP_STATUS_BLOCKED_BY_PARENTAL_CONTROL = 450,
HTTP_STATUS_UNAVAILABLE_FOR_LEGAL_REASONS = 451,
HTTP_STATUS_CLIENT_CLOSED_LOAD_BALANCED_REQUEST = 460,
HTTP_STATUS_INVALID_X_FORWARDED_FOR = 463,
HTTP_STATUS_REQUEST_HEADER_TOO_LARGE = 494,
HTTP_STATUS_SSL_CERTIFICATE_ERROR = 495,
HTTP_STATUS_SSL_CERTIFICATE_REQUIRED = 496,
HTTP_STATUS_HTTP_REQUEST_SENT_TO_HTTPS_PORT = 497,
HTTP_STATUS_INVALID_TOKEN = 498,
HTTP_STATUS_CLIENT_CLOSED_REQUEST = 499,
HTTP_STATUS_INTERNAL_SERVER_ERROR = 500,
HTTP_STATUS_NOT_IMPLEMENTED = 501,
HTTP_STATUS_BAD_GATEWAY = 502,
HTTP_STATUS_SERVICE_UNAVAILABLE = 503,
HTTP_STATUS_GATEWAY_TIMEOUT = 504,
HTTP_STATUS_HTTP_VERSION_NOT_SUPPORTED = 505,
HTTP_STATUS_VARIANT_ALSO_NEGOTIATES = 506,
HTTP_STATUS_INSUFFICIENT_STORAGE = 507,
HTTP_STATUS_LOOP_DETECTED = 508,
HTTP_STATUS_BANDWIDTH_LIMIT_EXCEEDED = 509,
HTTP_STATUS_NOT_EXTENDED = 510,
HTTP_STATUS_NETWORK_AUTHENTICATION_REQUIRED = 511,
HTTP_STATUS_WEB_SERVER_UNKNOWN_ERROR = 520,
HTTP_STATUS_WEB_SERVER_IS_DOWN = 521,
HTTP_STATUS_CONNECTION_TIMEOUT = 522,
HTTP_STATUS_ORIGIN_IS_UNREACHABLE = 523,
HTTP_STATUS_TIMEOUT_OCCURED = 524,
HTTP_STATUS_SSL_HANDSHAKE_FAILED = 525,
HTTP_STATUS_INVALID_SSL_CERTIFICATE = 526,
HTTP_STATUS_RAILGUN_ERROR = 527,
HTTP_STATUS_SITE_IS_OVERLOADED = 529,
HTTP_STATUS_SITE_IS_FROZEN = 530,
HTTP_STATUS_IDENTITY_PROVIDER_AUTHENTICATION_ERROR = 561,
HTTP_STATUS_NETWORK_READ_TIMEOUT = 598,
HTTP_STATUS_NETWORK_CONNECT_TIMEOUT = 599
};
typedef enum llhttp_status llhttp_status_t;
#define HTTP_ERRNO_MAP(XX) \
XX(0, OK, OK) \
XX(1, INTERNAL, INTERNAL) \
XX(2, STRICT, STRICT) \
XX(25, CR_EXPECTED, CR_EXPECTED) \
XX(3, LF_EXPECTED, LF_EXPECTED) \
XX(4, UNEXPECTED_CONTENT_LENGTH, UNEXPECTED_CONTENT_LENGTH) \
XX(30, UNEXPECTED_SPACE, UNEXPECTED_SPACE) \
XX(5, CLOSED_CONNECTION, CLOSED_CONNECTION) \
XX(6, INVALID_METHOD, INVALID_METHOD) \
XX(7, INVALID_URL, INVALID_URL) \
@@ -194,9 +318,74 @@ typedef enum llhttp_method llhttp_method_t;
XX(22, PAUSED_UPGRADE, PAUSED_UPGRADE) \
XX(23, PAUSED_H2_UPGRADE, PAUSED_H2_UPGRADE) \
XX(24, USER, USER) \
XX(26, CB_URL_COMPLETE, CB_URL_COMPLETE) \
XX(27, CB_STATUS_COMPLETE, CB_STATUS_COMPLETE) \
XX(32, CB_METHOD_COMPLETE, CB_METHOD_COMPLETE) \
XX(33, CB_VERSION_COMPLETE, CB_VERSION_COMPLETE) \
XX(28, CB_HEADER_FIELD_COMPLETE, CB_HEADER_FIELD_COMPLETE) \
XX(29, CB_HEADER_VALUE_COMPLETE, CB_HEADER_VALUE_COMPLETE) \
XX(34, CB_CHUNK_EXTENSION_NAME_COMPLETE, CB_CHUNK_EXTENSION_NAME_COMPLETE) \
XX(35, CB_CHUNK_EXTENSION_VALUE_COMPLETE, CB_CHUNK_EXTENSION_VALUE_COMPLETE) \
XX(31, CB_RESET, CB_RESET) \
XX(38, CB_PROTOCOL_COMPLETE, CB_PROTOCOL_COMPLETE) \
#define HTTP_METHOD_MAP(XX) \
XX(0, DELETE, DELETE) \
XX(1, GET, GET) \
XX(2, HEAD, HEAD) \
XX(3, POST, POST) \
XX(4, PUT, PUT) \
XX(5, CONNECT, CONNECT) \
XX(6, OPTIONS, OPTIONS) \
XX(7, TRACE, TRACE) \
XX(8, COPY, COPY) \
XX(9, LOCK, LOCK) \
XX(10, MKCOL, MKCOL) \
XX(11, MOVE, MOVE) \
XX(12, PROPFIND, PROPFIND) \
XX(13, PROPPATCH, PROPPATCH) \
XX(14, SEARCH, SEARCH) \
XX(15, UNLOCK, UNLOCK) \
XX(16, BIND, BIND) \
XX(17, REBIND, REBIND) \
XX(18, UNBIND, UNBIND) \
XX(19, ACL, ACL) \
XX(20, REPORT, REPORT) \
XX(21, MKACTIVITY, MKACTIVITY) \
XX(22, CHECKOUT, CHECKOUT) \
XX(23, MERGE, MERGE) \
XX(24, MSEARCH, M-SEARCH) \
XX(25, NOTIFY, NOTIFY) \
XX(26, SUBSCRIBE, SUBSCRIBE) \
XX(27, UNSUBSCRIBE, UNSUBSCRIBE) \
XX(28, PATCH, PATCH) \
XX(29, PURGE, PURGE) \
XX(30, MKCALENDAR, MKCALENDAR) \
XX(31, LINK, LINK) \
XX(32, UNLINK, UNLINK) \
XX(33, SOURCE, SOURCE) \
XX(46, QUERY, QUERY) \
#define RTSP_METHOD_MAP(XX) \
XX(1, GET, GET) \
XX(3, POST, POST) \
XX(6, OPTIONS, OPTIONS) \
XX(35, DESCRIBE, DESCRIBE) \
XX(36, ANNOUNCE, ANNOUNCE) \
XX(37, SETUP, SETUP) \
XX(38, PLAY, PLAY) \
XX(39, PAUSE, PAUSE) \
XX(40, TEARDOWN, TEARDOWN) \
XX(41, GET_PARAMETER, GET_PARAMETER) \
XX(42, SET_PARAMETER, SET_PARAMETER) \
XX(43, REDIRECT, REDIRECT) \
XX(44, RECORD, RECORD) \
XX(45, FLUSH, FLUSH) \
#define HTTP_ALL_METHOD_MAP(XX) \
XX(0, DELETE, DELETE) \
XX(1, GET, GET) \
XX(2, HEAD, HEAD) \
@@ -243,14 +432,117 @@ typedef enum llhttp_method llhttp_method_t;
XX(43, REDIRECT, REDIRECT) \
XX(44, RECORD, RECORD) \
XX(45, FLUSH, FLUSH) \
XX(46, QUERY, QUERY) \
#define HTTP_STATUS_MAP(XX) \
XX(100, CONTINUE, CONTINUE) \
XX(101, SWITCHING_PROTOCOLS, SWITCHING_PROTOCOLS) \
XX(102, PROCESSING, PROCESSING) \
XX(103, EARLY_HINTS, EARLY_HINTS) \
XX(110, RESPONSE_IS_STALE, RESPONSE_IS_STALE) \
XX(111, REVALIDATION_FAILED, REVALIDATION_FAILED) \
XX(112, DISCONNECTED_OPERATION, DISCONNECTED_OPERATION) \
XX(113, HEURISTIC_EXPIRATION, HEURISTIC_EXPIRATION) \
XX(199, MISCELLANEOUS_WARNING, MISCELLANEOUS_WARNING) \
XX(200, OK, OK) \
XX(201, CREATED, CREATED) \
XX(202, ACCEPTED, ACCEPTED) \
XX(203, NON_AUTHORITATIVE_INFORMATION, NON_AUTHORITATIVE_INFORMATION) \
XX(204, NO_CONTENT, NO_CONTENT) \
XX(205, RESET_CONTENT, RESET_CONTENT) \
XX(206, PARTIAL_CONTENT, PARTIAL_CONTENT) \
XX(207, MULTI_STATUS, MULTI_STATUS) \
XX(208, ALREADY_REPORTED, ALREADY_REPORTED) \
XX(214, TRANSFORMATION_APPLIED, TRANSFORMATION_APPLIED) \
XX(226, IM_USED, IM_USED) \
XX(299, MISCELLANEOUS_PERSISTENT_WARNING, MISCELLANEOUS_PERSISTENT_WARNING) \
XX(300, MULTIPLE_CHOICES, MULTIPLE_CHOICES) \
XX(301, MOVED_PERMANENTLY, MOVED_PERMANENTLY) \
XX(302, FOUND, FOUND) \
XX(303, SEE_OTHER, SEE_OTHER) \
XX(304, NOT_MODIFIED, NOT_MODIFIED) \
XX(305, USE_PROXY, USE_PROXY) \
XX(306, SWITCH_PROXY, SWITCH_PROXY) \
XX(307, TEMPORARY_REDIRECT, TEMPORARY_REDIRECT) \
XX(308, PERMANENT_REDIRECT, PERMANENT_REDIRECT) \
XX(400, BAD_REQUEST, BAD_REQUEST) \
XX(401, UNAUTHORIZED, UNAUTHORIZED) \
XX(402, PAYMENT_REQUIRED, PAYMENT_REQUIRED) \
XX(403, FORBIDDEN, FORBIDDEN) \
XX(404, NOT_FOUND, NOT_FOUND) \
XX(405, METHOD_NOT_ALLOWED, METHOD_NOT_ALLOWED) \
XX(406, NOT_ACCEPTABLE, NOT_ACCEPTABLE) \
XX(407, PROXY_AUTHENTICATION_REQUIRED, PROXY_AUTHENTICATION_REQUIRED) \
XX(408, REQUEST_TIMEOUT, REQUEST_TIMEOUT) \
XX(409, CONFLICT, CONFLICT) \
XX(410, GONE, GONE) \
XX(411, LENGTH_REQUIRED, LENGTH_REQUIRED) \
XX(412, PRECONDITION_FAILED, PRECONDITION_FAILED) \
XX(413, PAYLOAD_TOO_LARGE, PAYLOAD_TOO_LARGE) \
XX(414, URI_TOO_LONG, URI_TOO_LONG) \
XX(415, UNSUPPORTED_MEDIA_TYPE, UNSUPPORTED_MEDIA_TYPE) \
XX(416, RANGE_NOT_SATISFIABLE, RANGE_NOT_SATISFIABLE) \
XX(417, EXPECTATION_FAILED, EXPECTATION_FAILED) \
XX(418, IM_A_TEAPOT, IM_A_TEAPOT) \
XX(419, PAGE_EXPIRED, PAGE_EXPIRED) \
XX(420, ENHANCE_YOUR_CALM, ENHANCE_YOUR_CALM) \
XX(421, MISDIRECTED_REQUEST, MISDIRECTED_REQUEST) \
XX(422, UNPROCESSABLE_ENTITY, UNPROCESSABLE_ENTITY) \
XX(423, LOCKED, LOCKED) \
XX(424, FAILED_DEPENDENCY, FAILED_DEPENDENCY) \
XX(425, TOO_EARLY, TOO_EARLY) \
XX(426, UPGRADE_REQUIRED, UPGRADE_REQUIRED) \
XX(428, PRECONDITION_REQUIRED, PRECONDITION_REQUIRED) \
XX(429, TOO_MANY_REQUESTS, TOO_MANY_REQUESTS) \
XX(430, REQUEST_HEADER_FIELDS_TOO_LARGE_UNOFFICIAL, REQUEST_HEADER_FIELDS_TOO_LARGE_UNOFFICIAL) \
XX(431, REQUEST_HEADER_FIELDS_TOO_LARGE, REQUEST_HEADER_FIELDS_TOO_LARGE) \
XX(440, LOGIN_TIMEOUT, LOGIN_TIMEOUT) \
XX(444, NO_RESPONSE, NO_RESPONSE) \
XX(449, RETRY_WITH, RETRY_WITH) \
XX(450, BLOCKED_BY_PARENTAL_CONTROL, BLOCKED_BY_PARENTAL_CONTROL) \
XX(451, UNAVAILABLE_FOR_LEGAL_REASONS, UNAVAILABLE_FOR_LEGAL_REASONS) \
XX(460, CLIENT_CLOSED_LOAD_BALANCED_REQUEST, CLIENT_CLOSED_LOAD_BALANCED_REQUEST) \
XX(463, INVALID_X_FORWARDED_FOR, INVALID_X_FORWARDED_FOR) \
XX(494, REQUEST_HEADER_TOO_LARGE, REQUEST_HEADER_TOO_LARGE) \
XX(495, SSL_CERTIFICATE_ERROR, SSL_CERTIFICATE_ERROR) \
XX(496, SSL_CERTIFICATE_REQUIRED, SSL_CERTIFICATE_REQUIRED) \
XX(497, HTTP_REQUEST_SENT_TO_HTTPS_PORT, HTTP_REQUEST_SENT_TO_HTTPS_PORT) \
XX(498, INVALID_TOKEN, INVALID_TOKEN) \
XX(499, CLIENT_CLOSED_REQUEST, CLIENT_CLOSED_REQUEST) \
XX(500, INTERNAL_SERVER_ERROR, INTERNAL_SERVER_ERROR) \
XX(501, NOT_IMPLEMENTED, NOT_IMPLEMENTED) \
XX(502, BAD_GATEWAY, BAD_GATEWAY) \
XX(503, SERVICE_UNAVAILABLE, SERVICE_UNAVAILABLE) \
XX(504, GATEWAY_TIMEOUT, GATEWAY_TIMEOUT) \
XX(505, HTTP_VERSION_NOT_SUPPORTED, HTTP_VERSION_NOT_SUPPORTED) \
XX(506, VARIANT_ALSO_NEGOTIATES, VARIANT_ALSO_NEGOTIATES) \
XX(507, INSUFFICIENT_STORAGE, INSUFFICIENT_STORAGE) \
XX(508, LOOP_DETECTED, LOOP_DETECTED) \
XX(509, BANDWIDTH_LIMIT_EXCEEDED, BANDWIDTH_LIMIT_EXCEEDED) \
XX(510, NOT_EXTENDED, NOT_EXTENDED) \
XX(511, NETWORK_AUTHENTICATION_REQUIRED, NETWORK_AUTHENTICATION_REQUIRED) \
XX(520, WEB_SERVER_UNKNOWN_ERROR, WEB_SERVER_UNKNOWN_ERROR) \
XX(521, WEB_SERVER_IS_DOWN, WEB_SERVER_IS_DOWN) \
XX(522, CONNECTION_TIMEOUT, CONNECTION_TIMEOUT) \
XX(523, ORIGIN_IS_UNREACHABLE, ORIGIN_IS_UNREACHABLE) \
XX(524, TIMEOUT_OCCURED, TIMEOUT_OCCURED) \
XX(525, SSL_HANDSHAKE_FAILED, SSL_HANDSHAKE_FAILED) \
XX(526, INVALID_SSL_CERTIFICATE, INVALID_SSL_CERTIFICATE) \
XX(527, RAILGUN_ERROR, RAILGUN_ERROR) \
XX(529, SITE_IS_OVERLOADED, SITE_IS_OVERLOADED) \
XX(530, SITE_IS_FROZEN, SITE_IS_FROZEN) \
XX(561, IDENTITY_PROVIDER_AUTHENTICATION_ERROR, IDENTITY_PROVIDER_AUTHENTICATION_ERROR) \
XX(598, NETWORK_READ_TIMEOUT, NETWORK_READ_TIMEOUT) \
XX(599, NETWORK_CONNECT_TIMEOUT, NETWORK_CONNECT_TIMEOUT) \
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* LLLLHTTP_C_HEADERS_ */
#ifndef INCLUDE_LLHTTP_API_H_
#define INCLUDE_LLHTTP_API_H_
#ifdef __cplusplus
@@ -274,10 +566,16 @@ struct llhttp_settings_s {
/* Possible return values 0, -1, `HPE_PAUSED` */
llhttp_cb on_message_begin;
/* Possible return values 0, -1, HPE_USER */
llhttp_data_cb on_protocol;
llhttp_data_cb on_url;
llhttp_data_cb on_status;
llhttp_data_cb on_method;
llhttp_data_cb on_version;
llhttp_data_cb on_header_field;
llhttp_data_cb on_header_value;
llhttp_data_cb on_chunk_extension_name;
llhttp_data_cb on_chunk_extension_value;
/* Possible return values:
* 0 - Proceed normally
@@ -290,10 +588,20 @@ struct llhttp_settings_s {
*/
llhttp_cb on_headers_complete;
/* Possible return values 0, -1, HPE_USER */
llhttp_data_cb on_body;
/* Possible return values 0, -1, `HPE_PAUSED` */
llhttp_cb on_message_complete;
llhttp_cb on_protocol_complete;
llhttp_cb on_url_complete;
llhttp_cb on_status_complete;
llhttp_cb on_method_complete;
llhttp_cb on_version_complete;
llhttp_cb on_header_field_complete;
llhttp_cb on_header_value_complete;
llhttp_cb on_chunk_extension_name_complete;
llhttp_cb on_chunk_extension_value_complete;
/* When on_chunk_header is called, the current chunk length is stored
* in parser->content_length.
@@ -301,11 +609,7 @@ struct llhttp_settings_s {
*/
llhttp_cb on_chunk_header;
llhttp_cb on_chunk_complete;
llhttp_cb on_url_complete;
llhttp_cb on_status_complete;
llhttp_cb on_header_field_complete;
llhttp_cb on_header_value_complete;
llhttp_cb on_reset;
};
/* Initialize the parser with specific type and user settings.
@@ -318,8 +622,6 @@ LLHTTP_EXPORT
void llhttp_init(llhttp_t* parser, llhttp_type_t type,
const llhttp_settings_t* settings);
#if defined(__wasm__)
LLHTTP_EXPORT
llhttp_t* llhttp_alloc(llhttp_type_t type);
@@ -344,8 +646,6 @@ int llhttp_get_status_code(llhttp_t* parser);
LLHTTP_EXPORT
uint8_t llhttp_get_upgrade(llhttp_t* parser);
#endif // defined(__wasm__)
/* Reset an already initialized parser back to the start state, preserving the
* existing parser type, callback settings, user data, and lenient flags.
*/
@@ -459,6 +759,9 @@ const char* llhttp_errno_name(llhttp_errno_t err);
LLHTTP_EXPORT
const char* llhttp_method_name(llhttp_method_t method);
/* Returns textual name of HTTP status */
LLHTTP_EXPORT
const char* llhttp_status_name(llhttp_status_t status);
/* Enables/disables lenient header value parsing (disabled by default).
*
@@ -467,7 +770,8 @@ const char* llhttp_method_name(llhttp_method_t method);
* `HPE_INVALID_HEADER_TOKEN` will be raised for incorrect header values when
* lenient parsing is "on".
*
* **(USE AT YOUR OWN RISK)**
* **Enabling this flag can pose a security issue since you will be exposed to
* request smuggling attacks. USE WITH CAUTION!**
*/
LLHTTP_EXPORT
void llhttp_set_lenient_headers(llhttp_t* parser, int enabled);
@@ -481,7 +785,8 @@ void llhttp_set_lenient_headers(llhttp_t* parser, int enabled);
* request smuggling, but may be less desirable for small number of cases
* involving legacy servers.
*
* **(USE AT YOUR OWN RISK)**
* **Enabling this flag can pose a security issue since you will be exposed to
* request smuggling attacks. USE WITH CAUTION!**
*/
LLHTTP_EXPORT
void llhttp_set_lenient_chunked_length(llhttp_t* parser, int enabled);
@@ -496,13 +801,105 @@ void llhttp_set_lenient_chunked_length(llhttp_t* parser, int enabled);
* but might interact badly with outdated and insecure clients. With this flag
* the extra request/response will be parsed normally.
*
* **(USE AT YOUR OWN RISK)**
* **Enabling this flag can pose a security issue since you will be exposed to
* poisoning attacks. USE WITH CAUTION!**
*/
LLHTTP_EXPORT
void llhttp_set_lenient_keep_alive(llhttp_t* parser, int enabled);
/* Enables/disables lenient handling of `Transfer-Encoding` header.
*
* Normally `llhttp` would error when a `Transfer-Encoding` has `chunked` value
* and another value after it (either in a single header or in multiple
* headers whose value are internally joined using `, `).
* This is mandated by the spec to reliably determine request body size and thus
* avoid request smuggling.
* With this flag the extra value will be parsed normally.
*
* **Enabling this flag can pose a security issue since you will be exposed to
* request smuggling attacks. USE WITH CAUTION!**
*/
LLHTTP_EXPORT
void llhttp_set_lenient_transfer_encoding(llhttp_t* parser, int enabled);
/* Enables/disables lenient handling of HTTP version.
*
* Normally `llhttp` would error when the HTTP version in the request or status line
* is not `0.9`, `1.0`, `1.1` or `2.0`.
* With this flag the invalid value will be parsed normally.
*
* **Enabling this flag can pose a security issue since you will allow unsupported
* HTTP versions. USE WITH CAUTION!**
*/
LLHTTP_EXPORT
void llhttp_set_lenient_version(llhttp_t* parser, int enabled);
/* Enables/disables lenient handling of additional data received after a message ends
* and keep-alive is disabled.
*
* Normally `llhttp` would error when additional unexpected data is received if the message
* contains the `Connection` header with `close` value.
* With this flag the extra data will discarded without throwing an error.
*
* **Enabling this flag can pose a security issue since you will be exposed to
* poisoning attacks. USE WITH CAUTION!**
*/
LLHTTP_EXPORT
void llhttp_set_lenient_data_after_close(llhttp_t* parser, int enabled);
/* Enables/disables lenient handling of incomplete CRLF sequences.
*
* Normally `llhttp` would error when a CR is not followed by LF when terminating the
* request line, the status line, the headers or a chunk header.
* With this flag only a CR is required to terminate such sections.
*
* **Enabling this flag can pose a security issue since you will be exposed to
* request smuggling attacks. USE WITH CAUTION!**
*/
LLHTTP_EXPORT
void llhttp_set_lenient_optional_lf_after_cr(llhttp_t* parser, int enabled);
/*
* Enables/disables lenient handling of line separators.
*
* Normally `llhttp` would error when a LF is not preceded by CR when terminating the
* request line, the status line, the headers, a chunk header or a chunk data.
* With this flag only a LF is required to terminate such sections.
*
* **Enabling this flag can pose a security issue since you will be exposed to
* request smuggling attacks. USE WITH CAUTION!**
*/
LLHTTP_EXPORT
void llhttp_set_lenient_optional_cr_before_lf(llhttp_t* parser, int enabled);
/* Enables/disables lenient handling of chunks not separated via CRLF.
*
* Normally `llhttp` would error when after a chunk data a CRLF is missing before
* starting a new chunk.
* With this flag the new chunk can start immediately after the previous one.
*
* **Enabling this flag can pose a security issue since you will be exposed to
* request smuggling attacks. USE WITH CAUTION!**
*/
LLHTTP_EXPORT
void llhttp_set_lenient_optional_crlf_after_chunk(llhttp_t* parser, int enabled);
/* Enables/disables lenient handling of spaces after chunk size.
*
* Normally `llhttp` would error when after a chunk size is followed by one or more
* spaces are present instead of a CRLF or `;`.
* With this flag this check is disabled.
*
* **Enabling this flag can pose a security issue since you will be exposed to
* request smuggling attacks. USE WITH CAUTION!**
*/
LLHTTP_EXPORT
void llhttp_set_lenient_spaces_after_chunk_size(llhttp_t* parser, int enabled);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* INCLUDE_LLHTTP_API_H_ */
#endif /* INCLUDE_LLHTTP_H_ */

View File

@@ -19,6 +19,7 @@
#include "internal/meta.h"
#include <memory>
#include <limits>
#if RAPIDJSON_HAS_CXX11
#include <type_traits>
@@ -433,7 +434,7 @@ namespace internal {
template<typename T, typename A>
inline T* Realloc(A& a, T* old_p, size_t old_n, size_t new_n)
{
RAPIDJSON_NOEXCEPT_ASSERT(old_n <= SIZE_MAX / sizeof(T) && new_n <= SIZE_MAX / sizeof(T));
RAPIDJSON_NOEXCEPT_ASSERT(old_n <= (std::numeric_limits<size_t>::max)() / sizeof(T) && new_n <= (std::numeric_limits<size_t>::max)() / sizeof(T));
return static_cast<T*>(a.Realloc(old_p, old_n * sizeof(T), new_n * sizeof(T)));
}
@@ -496,9 +497,9 @@ public:
#endif
/* implicit */
StdAllocator(const BaseAllocator& allocator) RAPIDJSON_NOEXCEPT :
StdAllocator(const BaseAllocator& baseAllocator) RAPIDJSON_NOEXCEPT :
allocator_type(),
baseAllocator_(allocator)
baseAllocator_(baseAllocator)
{ }
~StdAllocator() RAPIDJSON_NOEXCEPT

View File

@@ -75,7 +75,7 @@ class GenericDocument;
User can define this to use CrtAllocator or MemoryPoolAllocator.
*/
#ifndef RAPIDJSON_DEFAULT_ALLOCATOR
#define RAPIDJSON_DEFAULT_ALLOCATOR MemoryPoolAllocator<CrtAllocator>
#define RAPIDJSON_DEFAULT_ALLOCATOR ::RAPIDJSON_NAMESPACE::MemoryPoolAllocator<::RAPIDJSON_NAMESPACE::CrtAllocator>
#endif
/*! \def RAPIDJSON_DEFAULT_STACK_ALLOCATOR
@@ -85,7 +85,7 @@ class GenericDocument;
User can define this to use CrtAllocator or MemoryPoolAllocator.
*/
#ifndef RAPIDJSON_DEFAULT_STACK_ALLOCATOR
#define RAPIDJSON_DEFAULT_STACK_ALLOCATOR CrtAllocator
#define RAPIDJSON_DEFAULT_STACK_ALLOCATOR ::RAPIDJSON_NAMESPACE::CrtAllocator
#endif
/*! \def RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY
@@ -1033,7 +1033,7 @@ public:
return false;
for (ConstMemberIterator lhsMemberItr = MemberBegin(); lhsMemberItr != MemberEnd(); ++lhsMemberItr) {
typename RhsType::ConstMemberIterator rhsMemberItr = rhs.FindMember(lhsMemberItr->name);
if (rhsMemberItr == rhs.MemberEnd() || lhsMemberItr->value != rhsMemberItr->value)
if (rhsMemberItr == rhs.MemberEnd() || (!(lhsMemberItr->value == rhsMemberItr->value)))
return false;
}
return true;
@@ -1042,7 +1042,7 @@ public:
if (data_.a.size != rhs.data_.a.size)
return false;
for (SizeType i = 0; i < data_.a.size; i++)
if ((*this)[i] != rhs[i])
if (!((*this)[i] == rhs[i]))
return false;
return true;
@@ -1078,6 +1078,7 @@ public:
*/
template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>,internal::IsGenericValue<T> >), (bool)) operator==(const T& rhs) const { return *this == GenericValue(rhs); }
#ifndef __cpp_impl_three_way_comparison
//! Not-equal-to operator
/*! \return !(*this == rhs)
*/
@@ -1092,7 +1093,6 @@ public:
*/
template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& rhs) const { return !(*this == rhs); }
#ifndef __cpp_lib_three_way_comparison
//! Equal-to operator with arbitrary types (symmetric version)
/*! \return (rhs == lhs)
*/
@@ -1230,13 +1230,28 @@ public:
else {
RAPIDJSON_ASSERT(false); // see above note
// This will generate -Wexit-time-destructors in clang
// static GenericValue NullValue;
// return NullValue;
// Use static buffer and placement-new to prevent destruction
static char buffer[sizeof(GenericValue)];
#if RAPIDJSON_HAS_CXX11
// Use thread-local storage to prevent races between threads.
// Use static buffer and placement-new to prevent destruction, with
// alignas() to ensure proper alignment.
alignas(GenericValue) thread_local static char buffer[sizeof(GenericValue)];
return *new (buffer) GenericValue();
#elif defined(_MSC_VER) && _MSC_VER < 1900
// There's no way to solve both thread locality and proper alignment
// simultaneously.
__declspec(thread) static char buffer[sizeof(GenericValue)];
return *new (buffer) GenericValue();
#elif defined(__GNUC__) || defined(__clang__)
// This will generate -Wexit-time-destructors in clang, but that's
// better than having under-alignment.
__thread static GenericValue buffer;
return buffer;
#else
// Don't know what compiler this is, so don't know how to ensure
// thread-locality.
static GenericValue buffer;
return buffer;
#endif
}
}
template <typename SourceAllocator>
@@ -2430,13 +2445,14 @@ private:
data_.f.flags = kShortStringFlag;
data_.ss.SetLength(s.length);
str = data_.ss.str;
std::memmove(str, s, s.length * sizeof(Ch));
} else {
data_.f.flags = kCopyStringFlag;
data_.s.length = s.length;
str = static_cast<Ch *>(allocator.Malloc((s.length + 1) * sizeof(Ch)));
SetStringPointer(str);
std::memcpy(str, s, s.length * sizeof(Ch));
}
std::memcpy(str, s, s.length * sizeof(Ch));
str[s.length] = '\0';
}
@@ -2486,6 +2502,7 @@ public:
typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding.
typedef GenericValue<Encoding, Allocator> ValueType; //!< Value type of the document.
typedef Allocator AllocatorType; //!< Allocator type from template parameter.
typedef StackAllocator StackAllocatorType; //!< StackAllocator type from template parameter.
//! Constructor
/*! Creates an empty document of specified type.

View File

@@ -177,10 +177,10 @@ struct UTF8 {
template <typename InputStream, typename OutputStream>
static bool Validate(InputStream& is, OutputStream& os) {
#define RAPIDJSON_COPY() os.Put(c = is.Take())
#define RAPIDJSON_COPY() if (c != '\0') os.Put(c = is.Take())
#define RAPIDJSON_TRANS(mask) result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0)
#define RAPIDJSON_TAIL() RAPIDJSON_COPY(); RAPIDJSON_TRANS(0x70)
Ch c;
Ch c = static_cast<Ch>(-1);
RAPIDJSON_COPY();
if (!(c & 0x80))
return true;

View File

@@ -104,15 +104,69 @@ inline const RAPIDJSON_ERROR_CHARTYPE* GetValidateError_En(ValidateErrorCode val
case kValidateErrorType: return RAPIDJSON_ERROR_STRING("Property has a type '%actual' that is not in the following list: '%expected'.");
case kValidateErrorOneOf: return RAPIDJSON_ERROR_STRING("Property did not match any of the sub-schemas specified by 'oneOf', refer to following errors.");
case kValidateErrorOneOfMatch: return RAPIDJSON_ERROR_STRING("Property matched more than one of the sub-schemas specified by 'oneOf'.");
case kValidateErrorOneOfMatch: return RAPIDJSON_ERROR_STRING("Property matched more than one of the sub-schemas specified by 'oneOf', indices '%matches'.");
case kValidateErrorAllOf: return RAPIDJSON_ERROR_STRING("Property did not match all of the sub-schemas specified by 'allOf', refer to following errors.");
case kValidateErrorAnyOf: return RAPIDJSON_ERROR_STRING("Property did not match any of the sub-schemas specified by 'anyOf', refer to following errors.");
case kValidateErrorNot: return RAPIDJSON_ERROR_STRING("Property matched the sub-schema specified by 'not'.");
case kValidateErrorReadOnly: return RAPIDJSON_ERROR_STRING("Property is read-only but has been provided when validation is for writing.");
case kValidateErrorWriteOnly: return RAPIDJSON_ERROR_STRING("Property is write-only but has been provided when validation is for reading.");
default: return RAPIDJSON_ERROR_STRING("Unknown error.");
}
}
//! Maps error code of schema document compilation into error message.
/*!
\ingroup RAPIDJSON_ERRORS
\param schemaErrorCode Error code obtained from compiling the schema document.
\return the error message.
\note User can make a copy of this function for localization.
Using switch-case is safer for future modification of error codes.
*/
inline const RAPIDJSON_ERROR_CHARTYPE* GetSchemaError_En(SchemaErrorCode schemaErrorCode) {
switch (schemaErrorCode) {
case kSchemaErrorNone: return RAPIDJSON_ERROR_STRING("No error.");
case kSchemaErrorStartUnknown: return RAPIDJSON_ERROR_STRING("Pointer '%value' to start of schema does not resolve to a location in the document.");
case kSchemaErrorRefPlainName: return RAPIDJSON_ERROR_STRING("$ref fragment '%value' must be a JSON pointer.");
case kSchemaErrorRefInvalid: return RAPIDJSON_ERROR_STRING("$ref must not be an empty string.");
case kSchemaErrorRefPointerInvalid: return RAPIDJSON_ERROR_STRING("$ref fragment '%value' is not a valid JSON pointer at offset '%offset'.");
case kSchemaErrorRefUnknown: return RAPIDJSON_ERROR_STRING("$ref '%value' does not resolve to a location in the target document.");
case kSchemaErrorRefCyclical: return RAPIDJSON_ERROR_STRING("$ref '%value' is cyclical.");
case kSchemaErrorRefNoRemoteProvider: return RAPIDJSON_ERROR_STRING("$ref is remote but there is no remote provider.");
case kSchemaErrorRefNoRemoteSchema: return RAPIDJSON_ERROR_STRING("$ref '%value' is remote but the remote provider did not return a schema.");
case kSchemaErrorRegexInvalid: return RAPIDJSON_ERROR_STRING("Invalid regular expression '%value' in 'pattern' or 'patternProperties'.");
case kSchemaErrorSpecUnknown: return RAPIDJSON_ERROR_STRING("JSON schema draft or OpenAPI version is not recognized.");
case kSchemaErrorSpecUnsupported: return RAPIDJSON_ERROR_STRING("JSON schema draft or OpenAPI version is not supported.");
case kSchemaErrorSpecIllegal: return RAPIDJSON_ERROR_STRING("Both JSON schema draft and OpenAPI version found in document.");
case kSchemaErrorReadOnlyAndWriteOnly: return RAPIDJSON_ERROR_STRING("Property must not be both 'readOnly' and 'writeOnly'.");
default: return RAPIDJSON_ERROR_STRING("Unknown error.");
}
}
//! Maps error code of pointer parse into error message.
/*!
\ingroup RAPIDJSON_ERRORS
\param pointerParseErrorCode Error code obtained from pointer parse.
\return the error message.
\note User can make a copy of this function for localization.
Using switch-case is safer for future modification of error codes.
*/
inline const RAPIDJSON_ERROR_CHARTYPE* GetPointerParseError_En(PointerParseErrorCode pointerParseErrorCode) {
switch (pointerParseErrorCode) {
case kPointerParseErrorNone: return RAPIDJSON_ERROR_STRING("No error.");
case kPointerParseErrorTokenMustBeginWithSolidus: return RAPIDJSON_ERROR_STRING("A token must begin with a '/'.");
case kPointerParseErrorInvalidEscape: return RAPIDJSON_ERROR_STRING("Invalid escape.");
case kPointerParseErrorInvalidPercentEncoding: return RAPIDJSON_ERROR_STRING("Invalid percent encoding in URI fragment.");
case kPointerParseErrorCharacterMustPercentEncode: return RAPIDJSON_ERROR_STRING("A character must be percent encoded in a URI fragment.");
default: return RAPIDJSON_ERROR_STRING("Unknown error.");
}
}
RAPIDJSON_NAMESPACE_END
#ifdef __clang__

View File

@@ -42,7 +42,7 @@ RAPIDJSON_DIAG_OFF(padded)
///////////////////////////////////////////////////////////////////////////////
// RAPIDJSON_ERROR_STRING
//! Macro for converting string literial to \ref RAPIDJSON_ERROR_CHARTYPE[].
//! Macro for converting string literal to \ref RAPIDJSON_ERROR_CHARTYPE[].
/*! \ingroup RAPIDJSON_ERRORS
By default this conversion macro does nothing.
On Windows, user can define this macro as \c _T(x) for supporting both
@@ -185,14 +185,17 @@ enum ValidateErrorCode {
kValidateErrorPatternProperties, //!< See other errors.
kValidateErrorDependencies, //!< Object has missing property or schema dependencies.
kValidateErrorEnum, //!< Property has a value that is not one of its allowed enumerated values
kValidateErrorType, //!< Property has a type that is not allowed by the schema..
kValidateErrorEnum, //!< Property has a value that is not one of its allowed enumerated values.
kValidateErrorType, //!< Property has a type that is not allowed by the schema.
kValidateErrorOneOf, //!< Property did not match any of the sub-schemas specified by 'oneOf'.
kValidateErrorOneOfMatch, //!< Property matched more than one of the sub-schemas specified by 'oneOf'.
kValidateErrorAllOf, //!< Property did not match all of the sub-schemas specified by 'allOf'.
kValidateErrorAnyOf, //!< Property did not match any of the sub-schemas specified by 'anyOf'.
kValidateErrorNot //!< Property matched the sub-schema specified by 'not'.
kValidateErrorNot, //!< Property matched the sub-schema specified by 'not'.
kValidateErrorReadOnly, //!< Property is read-only but has been provided when validation is for writing
kValidateErrorWriteOnly //!< Property is write-only but has been provided when validation is for reading
};
//! Function pointer type of GetValidateError().
@@ -207,6 +210,72 @@ enum ValidateErrorCode {
*/
typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetValidateErrorFunc)(ValidateErrorCode);
///////////////////////////////////////////////////////////////////////////////
// SchemaErrorCode
//! Error codes when validating.
/*! \ingroup RAPIDJSON_ERRORS
\see GenericSchemaValidator
*/
enum SchemaErrorCode {
kSchemaErrorNone = 0, //!< No error.
kSchemaErrorStartUnknown, //!< Pointer to start of schema does not resolve to a location in the document
kSchemaErrorRefPlainName, //!< $ref fragment must be a JSON pointer
kSchemaErrorRefInvalid, //!< $ref must not be an empty string
kSchemaErrorRefPointerInvalid, //!< $ref fragment is not a valid JSON pointer at offset
kSchemaErrorRefUnknown, //!< $ref does not resolve to a location in the target document
kSchemaErrorRefCyclical, //!< $ref is cyclical
kSchemaErrorRefNoRemoteProvider, //!< $ref is remote but there is no remote provider
kSchemaErrorRefNoRemoteSchema, //!< $ref is remote but the remote provider did not return a schema
kSchemaErrorRegexInvalid, //!< Invalid regular expression in 'pattern' or 'patternProperties'
kSchemaErrorSpecUnknown, //!< JSON schema draft or OpenAPI version is not recognized
kSchemaErrorSpecUnsupported, //!< JSON schema draft or OpenAPI version is not supported
kSchemaErrorSpecIllegal, //!< Both JSON schema draft and OpenAPI version found in document
kSchemaErrorReadOnlyAndWriteOnly //!< Property must not be both 'readOnly' and 'writeOnly'
};
//! Function pointer type of GetSchemaError().
/*! \ingroup RAPIDJSON_ERRORS
This is the prototype for \c GetSchemaError_X(), where \c X is a locale.
User can dynamically change locale in runtime, e.g.:
\code
GetSchemaErrorFunc GetSchemaError = GetSchemaError_En; // or whatever
const RAPIDJSON_ERROR_CHARTYPE* s = GetSchemaError(validator.GetInvalidSchemaCode());
\endcode
*/
typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetSchemaErrorFunc)(SchemaErrorCode);
///////////////////////////////////////////////////////////////////////////////
// PointerParseErrorCode
//! Error code of JSON pointer parsing.
/*! \ingroup RAPIDJSON_ERRORS
\see GenericPointer::GenericPointer, GenericPointer::GetParseErrorCode
*/
enum PointerParseErrorCode {
kPointerParseErrorNone = 0, //!< The parse is successful
kPointerParseErrorTokenMustBeginWithSolidus, //!< A token must begin with a '/'
kPointerParseErrorInvalidEscape, //!< Invalid escape
kPointerParseErrorInvalidPercentEncoding, //!< Invalid percent encoding in URI fragment
kPointerParseErrorCharacterMustPercentEncode //!< A character must percent encoded in URI fragment
};
//! Function pointer type of GetPointerParseError().
/*! \ingroup RAPIDJSON_ERRORS
This is the prototype for \c GetPointerParseError_X(), where \c X is a locale.
User can dynamically change locale in runtime, e.g.:
\code
GetPointerParseErrorFunc GetPointerParseError = GetPointerParseError_En; // or whatever
const RAPIDJSON_ERROR_CHARTYPE* s = GetPointerParseError(pointer.GetParseErrorCode());
\endcode
*/
typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetPointerParseErrorFunc)(PointerParseErrorCode);
RAPIDJSON_NAMESPACE_END
#ifdef __clang__

View File

@@ -19,7 +19,11 @@
#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && defined(_M_AMD64)
#include <intrin.h> // for _umul128
#if !defined(_ARM64EC_)
#pragma intrinsic(_umul128)
#else
#pragma comment(lib,"softintrin")
#endif
#endif
RAPIDJSON_NAMESPACE_BEGIN
@@ -255,7 +259,7 @@ private:
if (low < k)
(*outHigh)++;
return low;
#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__)
#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__)
__extension__ typedef unsigned __int128 uint128;
uint128 p = static_cast<uint128>(a) * static_cast<uint128>(b);
p += k;

View File

@@ -25,7 +25,11 @@
#if defined(_MSC_VER) && defined(_M_AMD64) && !defined(__INTEL_COMPILER)
#include <intrin.h>
#if !defined(_ARM64EC_)
#pragma intrinsic(_umul128)
#else
#pragma comment(lib,"softintrin")
#endif
#endif
RAPIDJSON_NAMESPACE_BEGIN
@@ -75,7 +79,7 @@ struct DiyFp {
if (l & (uint64_t(1) << 63)) // rounding
h++;
return DiyFp(h, e + rhs.e + 64);
#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__)
#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__)
__extension__ typedef unsigned __int128 uint128;
uint128 p = static_cast<uint128>(f) * static_cast<uint128>(rhs.f);
uint64_t h = static_cast<uint64_t>(p >> 64);

View File

@@ -58,11 +58,11 @@ inline int CountDecimalDigit32(uint32_t n) {
}
inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buffer, int* len, int* K) {
static const uint64_t kPow10[] = { 1U, 10U, 100U, 1000U, 10000U, 100000U, 1000000U, 10000000U, 100000000U,
1000000000U, 10000000000U, 100000000000U, 1000000000000U,
10000000000000U, 100000000000000U, 1000000000000000U,
10000000000000000U, 100000000000000000U, 1000000000000000000U,
10000000000000000000U };
static const uint64_t kPow10[] = { 1ULL, 10ULL, 100ULL, 1000ULL, 10000ULL, 100000ULL, 1000000ULL, 10000000ULL, 100000000ULL,
1000000000ULL, 10000000000ULL, 100000000000ULL, 1000000000000ULL,
10000000000000ULL, 100000000000000ULL, 1000000000000000ULL,
10000000000000000ULL, 100000000000000000ULL, 1000000000000000000ULL,
10000000000000000000ULL };
const DiyFp one(uint64_t(1) << -Mp.e, Mp.e);
const DiyFp wp_w = Mp - W;
uint32_t p1 = static_cast<uint32_t>(Mp.f >> -one.e);

View File

@@ -615,7 +615,7 @@ public:
RAPIDJSON_ASSERT(regex_.IsValid());
if (!allocator_)
ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
stateSet_ = static_cast<unsigned*>(allocator_->Malloc(GetStateSetSize()));
stateSet_ = static_cast<uint32_t*>(allocator_->Malloc(GetStateSetSize()));
state0_.template Reserve<SizeType>(regex_.stateCount_);
state1_.template Reserve<SizeType>(regex_.stateCount_);
}

View File

@@ -134,7 +134,7 @@ inline bool StrtodDiyFp(const Ch* decimals, int dLen, int dExp, double* result)
int i = 0; // 2^64 - 1 = 18446744073709551615, 1844674407370955161 = 0x1999999999999999
for (; i < dLen; i++) {
if (significand > RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) ||
(significand == RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) && decimals[i] > Ch('5')))
(significand == RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) && decimals[i] >= Ch('5')))
break;
significand = significand * 10u + static_cast<unsigned>(decimals[i] - Ch('0'));
}

View File

@@ -18,6 +18,7 @@
#include "document.h"
#include "uri.h"
#include "internal/itoa.h"
#include "error/error.h" // PointerParseErrorCode
#ifdef __clang__
RAPIDJSON_DIAG_PUSH
@@ -27,23 +28,16 @@ RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
#endif
#if defined(RAPIDJSON_CPLUSPLUS) && RAPIDJSON_CPLUSPLUS >= 201703L
#define RAPIDJSON_IF_CONSTEXPR if constexpr
#else
#define RAPIDJSON_IF_CONSTEXPR if
#endif
RAPIDJSON_NAMESPACE_BEGIN
static const SizeType kPointerInvalidIndex = ~SizeType(0); //!< Represents an invalid index in GenericPointer::Token
//! Error code of parsing.
/*! \ingroup RAPIDJSON_ERRORS
\see GenericPointer::GenericPointer, GenericPointer::GetParseErrorCode
*/
enum PointerParseErrorCode {
kPointerParseErrorNone = 0, //!< The parse is successful
kPointerParseErrorTokenMustBeginWithSolidus, //!< A token must begin with a '/'
kPointerParseErrorInvalidEscape, //!< Invalid escape
kPointerParseErrorInvalidPercentEncoding, //!< Invalid percent encoding in URI fragment
kPointerParseErrorCharacterMustPercentEncode //!< A character must percent encoded in URI fragment
};
///////////////////////////////////////////////////////////////////////////////
// GenericPointer
@@ -84,7 +78,7 @@ public:
typedef GenericUri<ValueType, Allocator> UriType;
//! A token is the basic units of internal representation.
//! A token is the basic units of internal representation.
/*!
A JSON pointer string representation "/foo/123" is parsed to two tokens:
"foo" and 123. 123 will be represented in both numeric form and string form.
@@ -303,7 +297,7 @@ public:
SizeType length = static_cast<SizeType>(end - buffer);
buffer[length] = '\0';
if (sizeof(Ch) == 1) {
RAPIDJSON_IF_CONSTEXPR (sizeof(Ch) == 1) {
Token token = { reinterpret_cast<Ch*>(buffer), length, index };
return Append(token, allocator);
}
@@ -902,10 +896,16 @@ private:
std::memcpy(nameBuffer_, rhs.nameBuffer_, nameBufferSize * sizeof(Ch));
}
// Adjust pointers to name buffer
std::ptrdiff_t diff = nameBuffer_ - rhs.nameBuffer_;
for (Token *t = tokens_; t != tokens_ + rhs.tokenCount_; ++t)
t->name += diff;
// The names of each token point to a string in the nameBuffer_. The
// previous memcpy copied over string pointers into the rhs.nameBuffer_,
// but they should point to the strings in the new nameBuffer_.
for (size_t i = 0; i < rhs.tokenCount_; ++i) {
// The offset between the string address and the name buffer should
// still be constant, so we can just get this offset and set each new
// token name according the new buffer start + the known offset.
std::ptrdiff_t name_offset = rhs.tokens_[i].name - rhs.nameBuffer_;
tokens_[i].name = nameBuffer_ + name_offset;
}
return nameBuffer_ + nameBufferSize;
}

View File

@@ -195,7 +195,7 @@
*/
#ifndef RAPIDJSON_NO_INT64DEFINE
//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
#if defined(_MSC_VER) && (_MSC_VER < 1800) // Visual Studio 2013
#if defined(_MSC_VER) && (_MSC_VER < 1800) // Visual Studio 2013
#include "msinttypes/stdint.h"
#include "msinttypes/inttypes.h"
#else
@@ -268,7 +268,7 @@
# elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN)
# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
// Detect with architecture macros
# elif defined(__sparc) || defined(__sparc__) || defined(_POWER) || defined(__powerpc__) || defined(__ppc__) || defined(__hpux) || defined(__hppa) || defined(_MIPSEB) || defined(_POWER) || defined(__s390__)
# elif defined(__sparc) || defined(__sparc__) || defined(_POWER) || defined(__powerpc__) || defined(__ppc__) || defined(__ppc64__) || defined(__hpux) || defined(__hppa) || defined(_MIPSEB) || defined(_POWER) || defined(__s390__)
# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
# elif defined(__i386__) || defined(__alpha__) || defined(__ia64) || defined(__ia64__) || defined(_M_IX86) || defined(_M_IA64) || defined(_M_ALPHA) || defined(__amd64) || defined(__amd64__) || defined(_M_AMD64) || defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || defined(__bfin__)
# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN

View File

@@ -1433,7 +1433,7 @@ private:
class NumberStream<InputStream, StackCharacter, true, false> : public NumberStream<InputStream, StackCharacter, false, false> {
typedef NumberStream<InputStream, StackCharacter, false, false> Base;
public:
NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is), stackStream(reader.stack_) {}
NumberStream(GenericReader& reader, InputStream& s) : Base(reader, s), stackStream(reader.stack_) {}
RAPIDJSON_FORCEINLINE Ch TakePush() {
stackStream.Put(static_cast<StackCharacter>(Base::is.Peek()));
@@ -1459,7 +1459,7 @@ private:
class NumberStream<InputStream, StackCharacter, true, true> : public NumberStream<InputStream, StackCharacter, true, false> {
typedef NumberStream<InputStream, StackCharacter, true, false> Base;
public:
NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is) {}
NumberStream(GenericReader& reader, InputStream& s) : Base(reader, s) {}
RAPIDJSON_FORCEINLINE Ch Take() { return Base::TakePush(); }
};
@@ -1584,7 +1584,7 @@ private:
// Parse frac = decimal-point 1*DIGIT
int expFrac = 0;
size_t decimalPosition;
if (Consume(s, '.')) {
if (!useNanOrInf && Consume(s, '.')) {
decimalPosition = s.Length();
if (RAPIDJSON_UNLIKELY(!(s.Peek() >= '0' && s.Peek() <= '9')))
@@ -1631,7 +1631,7 @@ private:
// Parse exp = e [ minus / plus ] 1*DIGIT
int exp = 0;
if (Consume(s, 'e') || Consume(s, 'E')) {
if (!useNanOrInf && (Consume(s, 'e') || Consume(s, 'E'))) {
if (!useDouble) {
d = static_cast<double>(use64bit ? i64 : i);
useDouble = true;
@@ -1694,7 +1694,7 @@ private:
}
else {
SizeType numCharsToCopy = static_cast<SizeType>(s.Length());
GenericStringStream<UTF8<NumberCharacter>> srcStream(s.Pop());
GenericStringStream<UTF8<NumberCharacter> > srcStream(s.Pop());
StackStream<typename TargetEncoding::Ch> dstStream(stack_);
while (numCharsToCopy--) {
Transcoder<UTF8<typename TargetEncoding::Ch>, TargetEncoding>::Transcode(srcStream, dstStream);

File diff suppressed because it is too large Load Diff

View File

@@ -238,20 +238,27 @@ private:
// Allocate one block containing each part of the URI (5) plus base plus full URI, all null terminated.
// Order: scheme, auth, path, query, frag, base, uri
// Note need to set, increment, assign in 3 stages to avoid compiler warning bug.
size_t total = (3 * len + 7) * sizeof(Ch);
scheme_ = static_cast<Ch*>(allocator_->Malloc(total));
*scheme_ = '\0';
auth_ = scheme_ + 1;
auth_ = scheme_;
auth_++;
*auth_ = '\0';
path_ = auth_ + 1;
path_ = auth_;
path_++;
*path_ = '\0';
query_ = path_ + 1;
query_ = path_;
query_++;
*query_ = '\0';
frag_ = query_ + 1;
frag_ = query_;
frag_++;
*frag_ = '\0';
base_ = frag_ + 1;
base_ = frag_;
base_++;
*base_ = '\0';
uri_ = base_ + 1;
uri_ = base_;
uri_++;
*uri_ = '\0';
return total;
}
@@ -293,7 +300,9 @@ private:
}
}
// Look for auth (//([^/?#]*))?
auth_ = scheme_ + GetSchemeStringLength() + 1;
// Note need to set, increment, assign in 3 stages to avoid compiler warning bug.
auth_ = scheme_ + GetSchemeStringLength();
auth_++;
*auth_ = '\0';
if (start < len - 1 && uri[start] == '/' && uri[start + 1] == '/') {
pos2 = start + 2;
@@ -308,7 +317,9 @@ private:
start = pos2;
}
// Look for path ([^?#]*)
path_ = auth_ + GetAuthStringLength() + 1;
// Note need to set, increment, assign in 3 stages to avoid compiler warning bug.
path_ = auth_ + GetAuthStringLength();
path_++;
*path_ = '\0';
if (start < len) {
pos2 = start;
@@ -326,7 +337,9 @@ private:
}
}
// Look for query (\?([^#]*))?
query_ = path_ + GetPathStringLength() + 1;
// Note need to set, increment, assign in 3 stages to avoid compiler warning bug.
query_ = path_ + GetPathStringLength();
query_++;
*query_ = '\0';
if (start < len && uri[start] == '?') {
pos2 = start + 1;
@@ -341,7 +354,9 @@ private:
}
}
// Look for fragment (#(.*))?
frag_ = query_ + GetQueryStringLength() + 1;
// Note need to set, increment, assign in 3 stages to avoid compiler warning bug.
frag_ = query_ + GetQueryStringLength();
frag_++;
*frag_ = '\0';
if (start < len && uri[start] == '#') {
std::memcpy(frag_, &uri[start], (len - start) * sizeof(Ch));

View File

@@ -67,6 +67,7 @@ enum WriteFlag {
kWriteNoFlags = 0, //!< No flags are set.
kWriteValidateEncodingFlag = 1, //!< Validate encoding of JSON strings.
kWriteNanAndInfFlag = 2, //!< Allow writing of Infinity, -Infinity and NaN.
kWriteNanAndInfNullFlag = 4, //!< Allow writing of Infinity, -Infinity and NaN as null.
kWriteDefaultFlags = RAPIDJSON_WRITE_DEFAULT_FLAGS //!< Default write flags. Can be customized by defining RAPIDJSON_WRITE_DEFAULT_FLAGS
};
@@ -349,8 +350,13 @@ protected:
bool WriteDouble(double d) {
if (internal::Double(d).IsNanOrInf()) {
if (!(writeFlags & kWriteNanAndInfFlag))
if (!(writeFlags & kWriteNanAndInfFlag) && !(writeFlags & kWriteNanAndInfNullFlag))
return false;
if (writeFlags & kWriteNanAndInfNullFlag) {
PutReserve(*os_, 4);
PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'u'); PutUnsafe(*os_, 'l'); PutUnsafe(*os_, 'l');
return true;
}
if (internal::Double(d).IsNan()) {
PutReserve(*os_, 3);
PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'N');
@@ -549,6 +555,11 @@ inline bool Writer<StringBuffer>::WriteDouble(double d) {
// Note: This code path can only be reached if (RAPIDJSON_WRITE_DEFAULT_FLAGS & kWriteNanAndInfFlag).
if (!(kWriteDefaultFlags & kWriteNanAndInfFlag))
return false;
if (kWriteDefaultFlags & kWriteNanAndInfNullFlag) {
PutReserve(*os_, 4);
PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'u'); PutUnsafe(*os_, 'l'); PutUnsafe(*os_, 'l');
return true;
}
if (internal::Double(d).IsNan()) {
PutReserve(*os_, 3);
PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'N');

View File

@@ -84,25 +84,6 @@ int xmrig::App::exec()
return 0;
}
# ifdef XMRIG_FEATURE_MO_BENCHMARK
const std::vector<Pool>& pools = m_controller->config()->pools().data();
if (pools.size() != 1 || pools[0].mode() != Pool::MODE_BENCHMARK) {
m_controller->pre_start();
m_controller->config()->benchmark().set_controller(m_controller);
if (m_controller->config()->benchmark().isNewBenchRun() || m_controller->config()->isRebenchAlgo()) {
if (m_controller->config()->isShouldSave()) {
m_controller->config()->save();
}
if (m_controller->config()->isRebenchAlgo()) {
m_controller->config()->benchmark().flush_perf();
}
m_controller->config()->benchmark().start_perf();
} else {
m_controller->start();
}
} else
# endif
m_controller->start();
rc = uv_run(uv_default_loop(), UV_RUN_DEFAULT);

View File

@@ -46,10 +46,6 @@ const char *ocl_tag();
const char *cuda_tag();
#endif
#ifdef XMRIG_FEATURE_MO_BENCHMARK
const char *bm_tag();
#endif
} // namespace xmrig

View File

@@ -128,8 +128,6 @@ xmrig::String xmrig::Threads<T>::profileName(const Algorithm &algorithm, bool st
}
}
if (std::is_same<T, CpuThreads>::value && (name == "defyx" || name == "panthera") && has("rx")) return "rx";
if (has(kAsterisk)) {
return kAsterisk;
}

View File

@@ -1,6 +1,6 @@
/* XMRig
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2018-2024 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2024 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,10 +19,8 @@
#ifndef XMRIG_PCITOPOLOGY_H
#define XMRIG_PCITOPOLOGY_H
#include <cstdio>
#include "base/tools/String.h"
@@ -33,7 +31,14 @@ class PciTopology
{
public:
PciTopology() = default;
PciTopology(uint32_t bus, uint32_t device, uint32_t function) : m_valid(true), m_bus(bus), m_device(device), m_function(function) {}
template<typename T>
inline PciTopology(T bus, T device, T function)
: m_valid(true),
m_bus(static_cast<uint8_t>(bus)),
m_device(static_cast<uint8_t>(device)),
m_function(static_cast<uint8_t>(function))
{}
inline bool isEqual(const PciTopology &other) const { return m_valid == other.m_valid && toUint32() == other.toUint32(); }
inline bool isValid() const { return m_valid; }
@@ -70,4 +75,4 @@ private:
} // namespace xmrig
#endif /* XMRIG_PCITOPOLOGY_H */
#endif // XMRIG_PCITOPOLOGY_H

View File

@@ -262,7 +262,7 @@ bool xmrig::CpuBackend::isEnabled() const
bool xmrig::CpuBackend::isEnabled(const Algorithm &algorithm) const
{
return algorithm.isValid() && !d_ptr->controller->config()->cpu().threads().get(algorithm).isEmpty();
return !d_ptr->controller->config()->cpu().threads().get(algorithm).isEmpty();
}

View File

@@ -48,10 +48,6 @@ size_t inline generate<Algorithm::CN>(Threads<CpuThreads> &threads, uint32_t lim
size_t count = 0;
count += generate(Algorithm::kCN, threads, Algorithm::CN_1, limit);
count += generate(Algorithm::kCN_2, threads, Algorithm::CN_2, limit);
# ifdef XMRIG_ALGO_CN_GPU
count += generate(Algorithm::kCN_GPU, threads, Algorithm::CN_GPU, limit);
# endif
if (!threads.isExist(Algorithm::CN_0)) {
threads.disable(Algorithm::CN_0);
@@ -126,36 +122,10 @@ size_t inline generate<Algorithm::RANDOM_X>(Threads<CpuThreads> &threads, uint32
}
}
if (!threads.isExist(Algorithm::RX_XEQ)) {
auto xeq = cpuInfo->threads(Algorithm::RX_XEQ, limit);
if (xeq == wow) {
threads.setAlias(Algorithm::RX_XEQ, Algorithm::kRX_WOW);
++count;
}
else {
count += threads.move(Algorithm::kRX_XEQ, std::move(xeq));
}
}
if (!threads.isExist(Algorithm::RX_KEVA)) {
auto keva = cpuInfo->threads(Algorithm::RX_KEVA, limit);
if (keva == wow) {
threads.setAlias(Algorithm::RX_KEVA, Algorithm::kRX_WOW);
++count;
}
else {
count += threads.move(Algorithm::kRX_KEVA, std::move(keva));
}
}
if (!threads.isExist(Algorithm::RX_WOW)) {
count += threads.move(Algorithm::kRX_WOW, std::move(wow));
}
if (!threads.isExist(Algorithm::RX_XLA)) {
count += generate(Algorithm::kRX_XLA, threads, Algorithm::RX_XLA, limit);
}
count += generate(Algorithm::kRX, threads, Algorithm::RX_0, limit);
return count;
@@ -176,10 +146,7 @@ size_t inline generate<Algorithm::ARGON2>(Threads<CpuThreads> &threads, uint32_t
template<>
size_t inline generate<Algorithm::GHOSTRIDER>(Threads<CpuThreads>& threads, uint32_t limit)
{
size_t count = 0;
count += threads.move(Algorithm::kGHOSTRIDER, std::move(Cpu::info()->threads(Algorithm::GHOSTRIDER_RTM, limit)));
count += threads.move(Algorithm::kFLEX, std::move(Cpu::info()->threads(Algorithm::FLEX_KCN, limit)));
return count;
return generate(Algorithm::kGHOSTRIDER, threads, Algorithm::GHOSTRIDER_RTM, limit);
}
#endif

View File

@@ -37,7 +37,6 @@
#include "crypto/rx/RxDataset.h"
#include "crypto/rx/RxVm.h"
#include "crypto/ghostrider/ghostrider.h"
#include "crypto/flex/flex.h"
#include "net/JobResults.h"
@@ -169,13 +168,7 @@ bool xmrig::CpuWorker<N>::selfTest()
# ifdef XMRIG_ALGO_GHOSTRIDER
if (m_algorithm.family() == Algorithm::GHOSTRIDER) {
switch (m_algorithm.id()) {
case Algorithm::GHOSTRIDER_RTM:
return (N == 8) && verify(Algorithm::GHOSTRIDER_RTM, test_output_gr);
case Algorithm::FLEX_KCN:
return (N == 1) && verify(Algorithm::FLEX_KCN, test_output_flex);
default:;
}
return (N == 8) && verify(Algorithm::GHOSTRIDER_RTM, test_output_gr);
}
# endif
@@ -191,18 +184,8 @@ bool xmrig::CpuWorker<N>::selfTest()
verify(Algorithm::CN_RWZ, test_output_rwz) &&
verify(Algorithm::CN_ZLS, test_output_zls) &&
verify(Algorithm::CN_CCX, test_output_ccx) &&
verify(Algorithm::CN_DOUBLE, test_output_double)
# ifdef XMRIG_ALGO_CN_GPU
&&
verify(Algorithm::CN_GPU, test_output_gpu)
# endif
;
verify(Algorithm::CN_DOUBLE, test_output_double);
# ifdef XMRIG_ALGO_CN_GPU
if (! (!rc || N > 1)) {
return verify(Algorithm::CN_GPU, test_output_gpu);
} else
# endif
return rc;
}
@@ -308,13 +291,12 @@ void xmrig::CpuWorker<N>::start()
# ifdef XMRIG_ALGO_RANDOMX
uint8_t* miner_signature_ptr = m_job.blob() + m_job.nonceOffset() + m_job.nonceSize();
if (job.algorithm().family() == Algorithm::RANDOM_X) {
if (first) {
first = false;
if (job.hasMinerSignature()) {
job.generateMinerSignature(m_job.blob(), job.size(), miner_signature_ptr);
}
randomx_calculate_hash_first(m_vm, tempHash, m_job.blob(), job.size(), job.algorithm());
randomx_calculate_hash_first(m_vm, tempHash, m_job.blob(), job.size());
}
if (!nextRound()) {
@@ -325,7 +307,7 @@ void xmrig::CpuWorker<N>::start()
memcpy(miner_signature_saved, miner_signature_ptr, sizeof(miner_signature_saved));
job.generateMinerSignature(m_job.blob(), job.size(), miner_signature_ptr);
}
randomx_calculate_hash_next(m_vm, tempHash, m_job.blob(), job.size(), m_hash, job.algorithm());
randomx_calculate_hash_next(m_vm, tempHash, m_job.blob(), job.size(), m_hash);
}
else
# endif
@@ -334,23 +316,11 @@ void xmrig::CpuWorker<N>::start()
# ifdef XMRIG_ALGO_GHOSTRIDER
case Algorithm::GHOSTRIDER:
switch (job.algorithm()) {
case Algorithm::GHOSTRIDER_RTM:
if (N == 8) {
ghostrider::hash_octa(m_job.blob(), job.size(), m_hash, m_ctx, m_ghHelper);
} else {
valid = false;
}
break;
case Algorithm::FLEX_KCN:
if (N == 1) {
flex_hash(reinterpret_cast<const char*>(m_job.blob()), reinterpret_cast<char*>(m_hash), m_ctx);
} else {
valid = false;
}
break;
default:
valid = false;
if (N == 8) {
ghostrider::hash_octa(m_job.blob(), job.size(), m_hash, m_ctx, m_ghHelper);
}
else {
valid = false;
}
break;
# endif
@@ -419,8 +389,7 @@ template<size_t N>
bool xmrig::CpuWorker<N>::verify(const Algorithm &algorithm, const uint8_t *referenceValue)
{
# ifdef XMRIG_ALGO_GHOSTRIDER
switch (algorithm) {
case Algorithm::GHOSTRIDER_RTM: {
if (algorithm == Algorithm::GHOSTRIDER_RTM) {
uint8_t blob[N * 80] = {};
for (size_t i = 0; i < N; ++i) {
blob[i * 80 + 0] = static_cast<uint8_t>(i);
@@ -447,19 +416,6 @@ bool xmrig::CpuWorker<N>::verify(const Algorithm &algorithm, const uint8_t *refe
}
return true;
}
case Algorithm::FLEX_KCN: {
const uint8_t header[80] = {
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0xcc, 0xa6, 0x6a,
0x44, 0xf8, 0xbd, 0x55, 0x45, 0xc3, 0x16, 0x4a, 0x3a, 0x76, 0xda, 0x50, 0x39, 0x53, 0x28, 0xc9, 0x07, 0x56, 0x33, 0x77,
0x5b, 0xc4, 0xc8, 0x79, 0x8f, 0xd6, 0x77, 0x2b, 0x70, 0x0d, 0x21, 0x5c, 0xf0, 0xff, 0x0f, 0x1e, 0x00, 0x00, 0x00, 0x00
};
char hash[32] = {};
flex_hash(reinterpret_cast<const char*>(header), hash, m_ctx);
return memcmp(referenceValue, hash, sizeof hash) == 0;
}
default:;
}
# endif

View File

@@ -55,7 +55,7 @@ public:
size_t threads() const override
{
# ifdef XMRIG_ALGO_GHOSTRIDER
return ((m_algorithm.id() == Algorithm::GHOSTRIDER_RTM) && m_ghHelper) ? 2 : 1;
return ((m_algorithm.family() == Algorithm::GHOSTRIDER) && m_ghHelper) ? 2 : 1;
# else
return 1;
# endif

View File

@@ -49,8 +49,15 @@ endif()
if (XMRIG_ARM)
list(APPEND SOURCES_BACKEND_CPU src/backend/cpu/platform/BasicCpuInfo_arm.cpp)
if (XMRIG_OS_UNIX)
list(APPEND SOURCES_BACKEND_CPU src/backend/cpu/platform/lscpu_arm.cpp)
if (XMRIG_OS_WIN)
list(APPEND SOURCES_BACKEND_CPU src/backend/cpu/platform/BasicCpuInfo_arm_win.cpp)
elseif(XMRIG_OS_APPLE)
list(APPEND SOURCES_BACKEND_CPU src/backend/cpu/platform/BasicCpuInfo_arm_mac.cpp)
else()
list(APPEND SOURCES_BACKEND_CPU
src/backend/cpu/platform/lscpu_arm.cpp
src/backend/cpu/platform/BasicCpuInfo_arm_unix.cpp
)
endif()
else()
list(APPEND SOURCES_BACKEND_CPU src/backend/cpu/platform/BasicCpuInfo.cpp)

View File

@@ -323,12 +323,9 @@ const char *xmrig::BasicCpuInfo::backend() const
}
xmrig::CpuThreads xmrig::BasicCpuInfo::threads(const Algorithm &algorithm, uint32_t limit) const
xmrig::CpuThreads xmrig::BasicCpuInfo::threads(const Algorithm &algorithm, uint32_t) const
{
const uint32_t count = std::thread::hardware_concurrency();
const uint32_t count_limit = std::max(static_cast<uint32_t>(count * (limit / 100.0f)), 1U);
const uint32_t count_limit2 = std::max(static_cast<uint32_t>(count / 2), count_limit);
const uint32_t count_limit4 = std::max(static_cast<uint32_t>(count / 4), count_limit);
const size_t count = std::thread::hardware_concurrency();
if (count == 1) {
return 1;
@@ -338,13 +335,13 @@ xmrig::CpuThreads xmrig::BasicCpuInfo::threads(const Algorithm &algorithm, uint3
# ifdef XMRIG_ALGO_CN_LITE
if (f == Algorithm::CN_LITE) {
return CpuThreads(count_limit, 1);
return CpuThreads(count, 1);
}
# endif
# ifdef XMRIG_ALGO_CN_PICO
if (f == Algorithm::CN_PICO) {
return CpuThreads(count_limit, 2);
return CpuThreads(count, 2);
}
# endif
@@ -356,50 +353,33 @@ xmrig::CpuThreads xmrig::BasicCpuInfo::threads(const Algorithm &algorithm, uint3
# ifdef XMRIG_ALGO_CN_HEAVY
if (f == Algorithm::CN_HEAVY) {
return CpuThreads(count_limit4, 1);
}
# endif
# ifdef XMRIG_ALGO_CN_GPU
if (algorithm == Algorithm::CN_GPU) {
return count_limit;
return CpuThreads(std::max<size_t>(count / 4, 1), 1);
}
# endif
# ifdef XMRIG_ALGO_RANDOMX
if (f == Algorithm::RANDOM_X) {
if (algorithm == Algorithm::RX_WOW) {
return count_limit;
return count;
}
if (algorithm == Algorithm::RX_XLA) {
CpuThreads threads;
for (size_t i = 0; i < count_limit2; ++i) {
threads.add(i, 0);
}
return threads;
}
return count_limit2;
return std::max<size_t>(count / 2, 1);
}
# endif
# ifdef XMRIG_ALGO_ARGON2
if (f == Algorithm::ARGON2) {
return count_limit;
return count;
}
# endif
# ifdef XMRIG_ALGO_GHOSTRIDER
switch (algorithm.id()) {
case Algorithm::GHOSTRIDER_RTM: return CpuThreads(std::max<size_t>(count_limit2, 1), 8);
case Algorithm::FLEX_KCN: return CpuThreads(std::max<size_t>(count_limit2, 1), 1);
default:
break;
if (f == Algorithm::GHOSTRIDER) {
return CpuThreads(std::max<size_t>(count / 2, 1), 8);
}
# endif
return CpuThreads(count_limit2, 1);
return CpuThreads(std::max<size_t>(count / 2, 1), 1);
}

View File

@@ -1,7 +1,7 @@
/* XMRig
* Copyright (c) 2017-2019 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright (c) 2018-2023 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2023 XMRig <support@xmrig.com>
* Copyright (c) 2018-2025 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2025 XMRig <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -85,6 +85,8 @@ private:
uint32_t m_family = 0;
uint32_t m_model = 0;
uint32_t m_stepping = 0;
# else
void init_arm();
# endif
Assembly m_assembly = Assembly::NONE;

View File

@@ -1,6 +1,6 @@
/* XMRig
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <support@xmrig.com>
* Copyright (c) 2018-2025 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2025 XMRig <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -16,44 +16,15 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "base/tools/String.h"
#include <array>
#include <cstring>
#include <fstream>
#include <thread>
#if __ARM_FEATURE_CRYPTO && !defined(__APPLE__)
# include <sys/auxv.h>
# if !defined(XMRIG_OS_FREEBSD)
# include <asm/hwcap.h>
# else
# include <stdint.h>
# include <machine/armreg.h>
# ifndef ID_AA64ISAR0_AES_VAL
# define ID_AA64ISAR0_AES_VAL ID_AA64ISAR0_AES
# endif
# endif
#endif
#include "backend/cpu/platform/BasicCpuInfo.h"
#include "3rdparty/rapidjson/document.h"
#if defined(XMRIG_OS_UNIX)
namespace xmrig {
extern String cpu_name_arm();
} // namespace xmrig
#elif defined(XMRIG_OS_MACOS)
# include <sys/sysctl.h>
#endif
xmrig::BasicCpuInfo::BasicCpuInfo() :
m_threads(std::thread::hardware_concurrency())
{
@@ -68,28 +39,7 @@ xmrig::BasicCpuInfo::BasicCpuInfo() :
memcpy(m_brand, "ARMv7", 5);
# endif
# if __ARM_FEATURE_CRYPTO
# if defined(__APPLE__)
m_flags.set(FLAG_AES, true);
# elif defined(XMRIG_OS_FREEBSD)
uint64_t isar0 = READ_SPECIALREG(id_aa64isar0_el1);
m_flags.set(FLAG_AES, ID_AA64ISAR0_AES_VAL(isar0) >= ID_AA64ISAR0_AES_BASE);
# else
m_flags.set(FLAG_AES, getauxval(AT_HWCAP) & HWCAP_AES);
# endif
# endif
# if defined(XMRIG_OS_UNIX)
auto name = cpu_name_arm();
if (!name.isNull()) {
strncpy(m_brand, name, sizeof(m_brand) - 1);
}
m_flags.set(FLAG_PDPE1GB, std::ifstream("/sys/kernel/mm/hugepages/hugepages-1048576kB/nr_hugepages").good());
# elif defined(XMRIG_OS_MACOS)
size_t buflen = sizeof(m_brand);
sysctlbyname("machdep.cpu.brand_string", &m_brand, &buflen, nullptr, 0);
# endif
init_arm();
}
@@ -102,9 +52,8 @@ const char *xmrig::BasicCpuInfo::backend() const
xmrig::CpuThreads xmrig::BasicCpuInfo::threads(const Algorithm &algorithm, uint32_t) const
{
# ifdef XMRIG_ALGO_GHOSTRIDER
switch (algorithm.id()) {
case Algorithm::GHOSTRIDER_RTM: return CpuThreads(threads(), 8);
case Algorithm::FLEX_KCN: return CpuThreads(threads(), 1);
if (algorithm.family() == Algorithm::GHOSTRIDER) {
return CpuThreads(threads(), 8);
}
# endif

View File

@@ -0,0 +1,32 @@
/* XMRig
* Copyright (c) 2018-2025 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2025 XMRig <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "backend/cpu/platform/BasicCpuInfo.h"
#include <sys/sysctl.h>
void xmrig::BasicCpuInfo::init_arm()
{
# if __ARM_FEATURE_CRYPTO
m_flags.set(FLAG_AES, true); // FIXME
# endif
size_t buflen = sizeof(m_brand);
sysctlbyname("machdep.cpu.brand_string", &m_brand, &buflen, nullptr, 0);
}

View File

@@ -0,0 +1,68 @@
/* XMRig
* Copyright (c) 2018-2025 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2025 XMRig <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "backend/cpu/platform/BasicCpuInfo.h"
#include "base/tools/String.h"
#include <fstream>
#if __ARM_FEATURE_CRYPTO
# include <sys/auxv.h>
# if !defined(XMRIG_OS_FREEBSD)
# include <asm/hwcap.h>
# else
# include <stdint.h>
# include <machine/armreg.h>
# ifndef ID_AA64ISAR0_AES_VAL
# define ID_AA64ISAR0_AES_VAL ID_AA64ISAR0_AES
# endif
# endif
#endif
namespace xmrig {
extern String cpu_name_arm();
} // namespace xmrig
void xmrig::BasicCpuInfo::init_arm()
{
# if __ARM_FEATURE_CRYPTO
# if defined(XMRIG_OS_FREEBSD)
uint64_t isar0 = READ_SPECIALREG(id_aa64isar0_el1);
m_flags.set(FLAG_AES, ID_AA64ISAR0_AES_VAL(isar0) >= ID_AA64ISAR0_AES_BASE);
# else
m_flags.set(FLAG_AES, getauxval(AT_HWCAP) & HWCAP_AES);
# endif
# endif
# if defined(XMRIG_OS_UNIX)
auto name = cpu_name_arm();
if (!name.isNull()) {
strncpy(m_brand, name, sizeof(m_brand) - 1);
}
m_flags.set(FLAG_PDPE1GB, std::ifstream("/sys/kernel/mm/hugepages/hugepages-1048576kB/nr_hugepages").good());
# endif
}

View File

@@ -0,0 +1,32 @@
/* XMRig
* Copyright (c) 2018-2025 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2025 XMRig <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "backend/cpu/platform/BasicCpuInfo.h"
#include <Windows.h>
void xmrig::BasicCpuInfo::init_arm()
{
DWORD size = sizeof(m_brand) - 1;
const char *subkey = "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0";
RegGetValueA(HKEY_LOCAL_MACHINE, subkey, "ProcessorNameString", RRF_RT_REG_SZ, nullptr, m_brand, &size);
m_flags.set(FLAG_AES, IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE));
}

View File

@@ -260,7 +260,7 @@ xmrig::CpuThreads xmrig::HwlocCpuInfo::allThreads(const Algorithm &algorithm, ui
CpuThreads threads;
threads.reserve(m_threads);
const uint32_t intensity = (algorithm.id() == Algorithm::GHOSTRIDER_RTM) ? 8 : 0;
const uint32_t intensity = (algorithm.family() == Algorithm::GHOSTRIDER) ? 8 : 0;
for (const int32_t pu : m_units) {
threads.add(pu, intensity);
@@ -311,17 +311,35 @@ void xmrig::HwlocCpuInfo::processTopLevelCache(hwloc_obj_t cache, const Algorith
uint32_t intensity = algorithm.maxIntensity() == 1 ? 0 : 1;
if (cache->attr->cache.depth == 3) {
for (size_t i = 0; i < cache->arity; ++i) {
hwloc_obj_t l2 = cache->children[i];
auto process_L2 = [&L2, &L2_associativity, L3_exclusive, this, &extra, scratchpad](hwloc_obj_t l2) {
if (!hwloc_obj_type_is_cache(l2->type) || l2->attr == nullptr) {
continue;
return;
}
L2 += l2->attr->cache.size;
L2_associativity = l2->attr->cache.associativity;
if (L3_exclusive && l2->attr->cache.size >= scratchpad) {
extra += scratchpad;
if (L3_exclusive) {
if ((vendor() == VENDOR_AMD) && ((arch() == ARCH_ZEN4) || (arch() == ARCH_ZEN5))) {
// Use extra L2 only on newer CPUs because older CPUs (Zen 3 and older) don't benefit from it.
// For some reason, AMD CPUs can use only half of the exclusive L2/L3 cache combo efficiently
extra += std::min<size_t>(l2->attr->cache.size / 2, scratchpad);
}
else if (l2->attr->cache.size >= scratchpad) {
extra += scratchpad;
}
}
};
for (size_t i = 0; i < cache->arity; ++i) {
hwloc_obj_t ch = cache->children[i];
if (ch->type == HWLOC_OBJ_GROUP) {
for (size_t j = 0; j < ch->arity; ++j) {
process_L2(ch->children[j]);
}
}
else {
process_L2(ch);
}
}
}
@@ -341,12 +359,6 @@ void xmrig::HwlocCpuInfo::processTopLevelCache(hwloc_obj_t cache, const Algorith
intensity = 2;
}
# ifdef XMRIG_ALGO_CN_GPU
if (algorithm == Algorithm::CN_GPU) {
cacheHashes = PUs;
}
# endif
# ifdef XMRIG_ALGO_RANDOMX
if ((vendor() == VENDOR_INTEL) && (algorithm.family() == Algorithm::RANDOM_X) && L3_exclusive && (PUs < cores.size() * 2)) {
// Use all L3+L2 on latest Intel CPUs with P-cores, E-cores and exclusive L3 cache
@@ -355,8 +367,6 @@ void xmrig::HwlocCpuInfo::processTopLevelCache(hwloc_obj_t cache, const Algorith
if (extra == 0 && algorithm.l2() > 0) {
cacheHashes = std::min<size_t>(std::max<size_t>(L2 / algorithm.l2(), cores.size()), cacheHashes);
}
if (algorithm == Algorithm::RX_XLA) cacheHashes = cores.size();
# endif
if (limit > 0) {

View File

@@ -1,7 +1,7 @@
/* XMRig
* Copyright (c) 2018 Riku Voipio <riku.voipio@iki.fi>
* Copyright (c) 2018-2023 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2023 XMRig <support@xmrig.com>
* Copyright (c) 2018-2025 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2025 XMRig <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -98,8 +98,11 @@ static const id_part arm_part[] = {
{ 0xd0e, "Cortex-A76AE" },
{ 0xd13, "Cortex-R52" },
{ 0xd15, "Cortex-R82" },
{ 0xd16, "Cortex-R52+" },
{ 0xd20, "Cortex-M23" },
{ 0xd21, "Cortex-M33" },
{ 0xd22, "Cortex-M55" },
{ 0xd23, "Cortex-M85" },
{ 0xd40, "Neoverse-V1" },
{ 0xd41, "Cortex-A78" },
{ 0xd42, "Cortex-A78AE" },
@@ -115,6 +118,17 @@ static const id_part arm_part[] = {
{ 0xd4d, "Cortex-A715" },
{ 0xd4e, "Cortex-X3" },
{ 0xd4f, "Neoverse-V2" },
{ 0xd80, "Cortex-A520" },
{ 0xd81, "Cortex-A720" },
{ 0xd82, "Cortex-X4" },
{ 0xd83, "Neoverse-V3AE" },
{ 0xd84, "Neoverse-V3" },
{ 0xd85, "Cortex-X925" },
{ 0xd87, "Cortex-A725" },
{ 0xd88, "Cortex-A520AE" },
{ 0xd89, "Cortex-A720AE" },
{ 0xd8e, "Neoverse-N3" },
{ 0xd8f, "Cortex-A320" },
{ -1, nullptr }
};
@@ -154,6 +168,7 @@ static const id_part apm_part[] = {
};
static const id_part qcom_part[] = {
{ 0x001, "Oryon" },
{ 0x00f, "Scorpion" },
{ 0x02d, "Scorpion" },
{ 0x04d, "Krait" },
@@ -194,6 +209,22 @@ static const id_part marvell_part[] = {
{ -1, nullptr }
};
static const id_part apple_part[] = {
{ 0x022, "M1" },
{ 0x023, "M1" },
{ 0x024, "M1-Pro" },
{ 0x025, "M1-Pro" },
{ 0x028, "M1-Max" },
{ 0x029, "M1-Max" },
{ 0x032, "M2" },
{ 0x033, "M2" },
{ 0x034, "M2-Pro" },
{ 0x035, "M2-Pro" },
{ 0x038, "M2-Max" },
{ 0x039, "M2-Max" },
{ -1, nullptr }
};
static const id_part faraday_part[] = {
{ 0x526, "FA526" },
{ 0x626, "FA626" },
@@ -227,47 +258,40 @@ static const id_part intel_part[] = {
static const struct id_part fujitsu_part[] = {
{ 0x001, "A64FX" },
{ 0x003, "MONAKA" },
{ -1, nullptr }
};
static const id_part hisi_part[] = {
{ 0xd01, "Kunpeng-920" }, /* aka tsv110 */
{ 0xd40, "Cortex-A76" }, /* HiSilicon uses this ID though advertises A76 */
{ 0xd01, "TaiShan-v110" }, /* used in Kunpeng-920 SoC */
{ 0xd02, "TaiShan-v120" }, /* used in Kirin 990A and 9000S SoCs */
{ 0xd40, "Cortex-A76" }, /* HiSilicon uses this ID though advertises A76 */
{ 0xd41, "Cortex-A77" }, /* HiSilicon uses this ID though advertises A77 */
{ -1, nullptr }
};
static const id_part apple_part[] = {
{ 0x022, "M1" },
{ 0x023, "M1" },
{ 0x024, "M1-Pro" },
{ 0x025, "M1-Pro" },
{ 0x028, "M1-Max" },
{ 0x029, "M1-Max" },
{ 0x032, "M2" },
{ 0x033, "M2" },
{ 0x034, "M2-Pro" },
{ 0x035, "M2-Pro" },
{ 0x038, "M2-Max" },
{ 0x039, "M2-Max" },
{ -1, nullptr }
};
static const struct id_part ft_part[] = {
{ 0x660, "FTC660" },
{ 0x661, "FTC661" },
{ 0x662, "FTC662" },
{ 0x663, "FTC663" },
{ -1, nullptr }
};
static const struct id_part ampere_part[] = {
{ 0xac3, "Ampere-1" },
{ 0xac4, "Ampere-1a" },
{ -1, nullptr }
};
static const struct id_part ft_part[] = {
{ 0x303, "FTC310" },
{ 0x660, "FTC660" },
{ 0x661, "FTC661" },
{ 0x662, "FTC662" },
{ 0x663, "FTC663" },
{ 0x664, "FTC664" },
{ 0x862, "FTC862" },
{ -1, nullptr }
};
static const struct id_part ms_part[] = {
{ 0xd49, "Azure-Cobalt-100" },
{ -1, nullptr }
};
static const hw_impl hw_implementer[] = {
{ 0x41, arm_part, "ARM" },
@@ -276,7 +300,7 @@ static const hw_impl hw_implementer[] = {
{ 0x44, dec_part, "DEC" },
{ 0x46, fujitsu_part, "FUJITSU" },
{ 0x48, hisi_part, "HiSilicon" },
{ 0x4e, nvidia_part, "Nvidia" },
{ 0x4e, nvidia_part, "NVIDIA" },
{ 0x50, apm_part, "APM" },
{ 0x51, qcom_part, "Qualcomm" },
{ 0x53, samsung_part, "Samsung" },
@@ -284,6 +308,7 @@ static const hw_impl hw_implementer[] = {
{ 0x61, apple_part, "Apple" },
{ 0x66, faraday_part, "Faraday" },
{ 0x69, intel_part, "Intel" },
{ 0x6d, ms_part, "Microsoft" },
{ 0x70, ft_part, "Phytium" },
{ 0xc0, ampere_part, "Ampere" }
};

View File

@@ -1,6 +1,6 @@
/* XMRig
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2018-2024 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2024 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -227,7 +227,7 @@ public:
# endif
Log::print("|" CYAN_BOLD("%3zu") " |" CYAN_BOLD("%4u") " |" YELLOW(" %7s") " |" CYAN_BOLD("%10d") " |" CYAN_BOLD("%8d") " |"
CYAN_BOLD("%7d") " |" CYAN_BOLD("%3d") " |" CYAN_BOLD("%4d") " |" CYAN("%7zu") " | " GREEN("%s"),
CYAN_BOLD("%7d") " |" CYAN_BOLD("%3d") " |" CYAN_BOLD("%4d") " |" CYAN("%7zu") " | " GREEN_BOLD("%s"),
i,
data.thread.index(),
data.device.topology().toString().data(),

View File

@@ -52,9 +52,6 @@ size_t inline generate<Algorithm::CN>(Threads<CudaThreads> &threads, const std::
count += generate(Algorithm::kCN, threads, Algorithm::CN_1, devices);
count += generate(Algorithm::kCN_2, threads, Algorithm::CN_2, devices);
# ifdef XMRIG_ALGO_CN_GPU
count += generate(Algorithm::kCN_GPU, threads, Algorithm::CN_GPU, devices);
# endif
if (!threads.isExist(Algorithm::CN_0)) {
threads.disable(Algorithm::CN_0);
@@ -117,8 +114,6 @@ size_t inline generate<Algorithm::RANDOM_X>(Threads<CudaThreads> &threads, const
auto rx = CudaThreads(devices, Algorithm::RX_0);
auto wow = CudaThreads(devices, Algorithm::RX_WOW);
auto arq = CudaThreads(devices, Algorithm::RX_ARQ);
auto xeq = CudaThreads(devices, Algorithm::RX_XEQ);
auto kva = CudaThreads(devices, Algorithm::RX_KEVA);
if (!threads.isExist(Algorithm::RX_WOW) && wow != rx) {
count += threads.move(Algorithm::kRX_WOW, std::move(wow));
@@ -128,14 +123,6 @@ size_t inline generate<Algorithm::RANDOM_X>(Threads<CudaThreads> &threads, const
count += threads.move(Algorithm::kRX_ARQ, std::move(arq));
}
if (!threads.isExist(Algorithm::RX_XEQ) && xeq != rx) {
count += threads.move(Algorithm::kRX_XEQ, std::move(xeq));
}
if (!threads.isExist(Algorithm::RX_KEVA) && kva != rx) {
count += threads.move(Algorithm::kRX_KEVA, std::move(kva));
}
count += threads.move(Algorithm::kRX, std::move(rx));
return count;

View File

@@ -5,8 +5,8 @@
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright 2018-2024 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2024 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,7 +22,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "backend/cuda/runners/CudaRxRunner.h"
#include "backend/cuda/CudaLaunchData.h"
#include "backend/cuda/wrappers/CudaLib.h"
@@ -55,12 +54,21 @@ bool xmrig::CudaRxRunner::run(uint32_t startNonce, uint32_t *rescount, uint32_t
bool xmrig::CudaRxRunner::set(const Job &job, uint8_t *blob)
{
if (!m_datasetHost && (m_seed != job.seed())) {
m_seed = job.seed();
if (m_ready) {
const auto *dataset = Rx::dataset(job, 0);
callWrapper(CudaLib::rxUpdateDataset(m_ctx, dataset->raw(), dataset->size(false)));
}
}
const bool rc = CudaBaseRunner::set(job, blob);
if (!rc || m_ready) {
return rc;
}
auto dataset = Rx::dataset(job, 0);
const auto *dataset = Rx::dataset(job, 0);
m_ready = callWrapper(CudaLib::rxPrepare(m_ctx, dataset->raw(), dataset->size(false), m_datasetHost, m_intensity));
return m_ready;

View File

@@ -5,8 +5,8 @@
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright 2018-2024 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2024 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -27,6 +27,7 @@
#include "backend/cuda/runners/CudaBaseRunner.h"
#include "base/tools/Buffer.h"
namespace xmrig {
@@ -46,6 +47,7 @@ protected:
private:
bool m_ready = false;
const bool m_datasetHost = false;
Buffer m_seed;
size_t m_intensity = 0;
};

View File

@@ -5,8 +5,8 @@
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright 2018-2024 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2024 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,7 +22,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "backend/cuda/wrappers/CudaDevice.h"
#include "3rdparty/rapidjson/document.h"
#include "backend/cuda/CudaThreads.h"
@@ -41,7 +40,7 @@
xmrig::CudaDevice::CudaDevice(uint32_t index, int32_t bfactor, int32_t bsleep) :
m_index(index)
{
auto ctx = CudaLib::alloc(index, bfactor, bsleep);
auto *ctx = CudaLib::alloc(index, bfactor, bsleep);
if (!CudaLib::deviceInfo(ctx, 0, 0, Algorithm::INVALID)) {
CudaLib::release(ctx);
@@ -50,7 +49,7 @@ xmrig::CudaDevice::CudaDevice(uint32_t index, int32_t bfactor, int32_t bsleep) :
m_ctx = ctx;
m_name = CudaLib::deviceName(ctx);
m_topology = PciTopology(CudaLib::deviceUint(ctx, CudaLib::DevicePciBusID), CudaLib::deviceUint(ctx, CudaLib::DevicePciDeviceID), 0);
m_topology = { CudaLib::deviceUint(ctx, CudaLib::DevicePciBusID), CudaLib::deviceUint(ctx, CudaLib::DevicePciDeviceID), 0U };
}

View File

@@ -19,10 +19,10 @@
#include <stdexcept>
#include <uv.h>
#include "backend/cuda/wrappers/CudaLib.h"
#include "base/io/Env.h"
#include "base/io/log/Log.h"
#include "base/io/log/Tags.h"
#include "base/kernel/Process.h"
#include "crypto/rx/RxAlgo.h"
@@ -68,6 +68,7 @@ static const char *kPluginVersion = "pluginVersion";
static const char *kRelease = "release";
static const char *kRxHash = "rxHash";
static const char *kRxPrepare = "rxPrepare";
static const char *kRxUpdateDataset = "rxUpdateDataset";
static const char *kSetJob = "setJob";
static const char *kSetJob_v2 = "setJob_v2";
static const char *kVersion = "version";
@@ -92,6 +93,7 @@ using pluginVersion_t = const char * (*)();
using release_t = void (*)(nvid_ctx *);
using rxHash_t = bool (*)(nvid_ctx *, uint32_t, uint64_t, uint32_t *, uint32_t *);
using rxPrepare_t = bool (*)(nvid_ctx *, const void *, size_t, bool, uint32_t);
using rxUpdateDataset_t = bool (*)(nvid_ctx *, const void *, size_t);
using setJob_t = bool (*)(nvid_ctx *, const void *, size_t, uint32_t);
using setJob_v2_t = bool (*)(nvid_ctx *, const void *, size_t, const char *);
using version_t = uint32_t (*)(Version);
@@ -116,6 +118,7 @@ static pluginVersion_t pPluginVersion = nullptr;
static release_t pRelease = nullptr;
static rxHash_t pRxHash = nullptr;
static rxPrepare_t pRxPrepare = nullptr;
static rxUpdateDataset_t pRxUpdateDataset = nullptr;
static setJob_t pSetJob = nullptr;
static setJob_v2_t pSetJob_v2 = nullptr;
static version_t pVersion = nullptr;
@@ -202,10 +205,26 @@ bool xmrig::CudaLib::rxHash(nvid_ctx *ctx, uint32_t startNonce, uint64_t target,
bool xmrig::CudaLib::rxPrepare(nvid_ctx *ctx, const void *dataset, size_t datasetSize, bool dataset_host, uint32_t batchSize) noexcept
{
# ifdef XMRIG_ALGO_RANDOMX
if (!pRxUpdateDataset) {
LOG_WARN("%s" YELLOW_BOLD("CUDA plugin is outdated. Please update to the latest version"), Tags::randomx());
}
# endif
return pRxPrepare(ctx, dataset, datasetSize, dataset_host, batchSize);
}
bool xmrig::CudaLib::rxUpdateDataset(nvid_ctx *ctx, const void *dataset, size_t datasetSize) noexcept
{
if (pRxUpdateDataset) {
return pRxUpdateDataset(ctx, dataset, datasetSize);
}
return true;
}
bool xmrig::CudaLib::kawPowHash(nvid_ctx *ctx, uint8_t* job_blob, uint64_t target, uint32_t *rescount, uint32_t *resnonce, uint32_t *skipped_hashes) noexcept
{
return pKawPowHash(ctx, job_blob, target, rescount, resnonce, skipped_hashes);
@@ -401,5 +420,7 @@ void xmrig::CudaLib::load()
DLSYM(SetJob_v2);
}
uv_dlsym(&cudaLib, kRxUpdateDataset, reinterpret_cast<void**>(&pRxUpdateDataset));
pInit();
}

View File

@@ -1,6 +1,6 @@
/* XMRig
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2018-2024 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2024 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -71,6 +71,7 @@ public:
static bool deviceInit(nvid_ctx *ctx) noexcept;
static bool rxHash(nvid_ctx *ctx, uint32_t startNonce, uint64_t target, uint32_t *rescount, uint32_t *resnonce) noexcept;
static bool rxPrepare(nvid_ctx *ctx, const void *dataset, size_t datasetSize, bool dataset_host, uint32_t batchSize) noexcept;
static bool rxUpdateDataset(nvid_ctx *ctx, const void *dataset, size_t datasetSize) noexcept;
static bool kawPowHash(nvid_ctx *ctx, uint8_t* job_blob, uint64_t target, uint32_t *rescount, uint32_t *resnonce, uint32_t *skipped_hashes) noexcept;
static bool kawPowPrepare(nvid_ctx *ctx, const void* cache, size_t cache_size, const void* dag_precalc, size_t dag_size, uint32_t height, const uint64_t* dag_sizes) noexcept;
static bool kawPowStopHash(nvid_ctx *ctx) noexcept;

View File

@@ -51,9 +51,6 @@ size_t inline generate<Algorithm::CN>(Threads<OclThreads> &threads, const std::v
count += generate(Algorithm::kCN, threads, Algorithm::CN_1, devices);
count += generate(Algorithm::kCN_2, threads, Algorithm::CN_2, devices);
# ifdef XMRIG_ALGO_CN_GPU
count += generate(Algorithm::kCN_GPU, threads, Algorithm::CN_GPU, devices);
# endif
if (!threads.isExist(Algorithm::CN_0)) {
threads.disable(Algorithm::CN_0);
@@ -116,7 +113,6 @@ size_t inline generate<Algorithm::RANDOM_X>(Threads<OclThreads> &threads, const
auto rx = OclThreads(devices, Algorithm::RX_0);
auto wow = OclThreads(devices, Algorithm::RX_WOW);
auto arq = OclThreads(devices, Algorithm::RX_ARQ);
auto xeq = OclThreads(devices, Algorithm::RX_XEQ);
if (!threads.isExist(Algorithm::RX_WOW) && wow != rx) {
count += threads.move(Algorithm::kRX_WOW, std::move(wow));
@@ -126,10 +122,6 @@ size_t inline generate<Algorithm::RANDOM_X>(Threads<OclThreads> &threads, const
count += threads.move(Algorithm::kRX_ARQ, std::move(arq));
}
if (!threads.isExist(Algorithm::RX_XEQ) && xeq != rx) {
count += threads.move(Algorithm::kRX_XEQ, std::move(xeq));
}
count += threads.move(Algorithm::kRX, std::move(rx));
return count;

View File

@@ -45,20 +45,6 @@ public:
setIntensity(intensity);
}
# ifdef XMRIG_ALGO_CN_GPU
OclThread(uint32_t index, uint32_t intensity, uint32_t worksize, uint32_t threads, uint32_t unrollFactor) :
m_fields(0),
m_threads(threads, -1),
m_index(index),
m_memChunk(0),
m_stridedIndex(0),
m_unrollFactor(unrollFactor),
m_worksize(worksize)
{
setIntensity(intensity);
}
# endif
# ifdef XMRIG_ALGO_RANDOMX
OclThread(uint32_t index, uint32_t intensity, uint32_t worksize, uint32_t threads, bool gcnAsm, bool datasetHost, uint32_t bfactor) :
m_datasetHost(datasetHost),

View File

@@ -30,10 +30,6 @@
#include "net/JobResults.h"
#ifdef XMRIG_ALGO_CN_GPU
# include "backend/opencl/runners/OclRyoRunner.h"
#endif
#ifdef XMRIG_ALGO_RANDOMX
# include "backend/opencl/runners/OclRxJitRunner.h"
# include "backend/opencl/runners/OclRxVmRunner.h"
@@ -97,12 +93,6 @@ xmrig::OclWorker::OclWorker(size_t id, const OclLaunchData &data) :
break;
default:
# ifdef XMRIG_ALGO_CN_GPU
if (m_algorithm == Algorithm::CN_GPU) {
m_runner = new OclRyoRunner(id, data);
}
else
# endif
m_runner = new OclCnRunner(id, data);
break;
}

View File

@@ -28,10 +28,6 @@
#include "base/crypto/Algorithm.h"
#ifdef XMRIG_ALGO_CN_GPU
# include "backend/opencl/cl/cn/cryptonight_gpu_cl.h"
#endif
#ifdef XMRIG_ALGO_RANDOMX
# include "backend/opencl/cl/rx/randomx_cl.h"
#endif
@@ -44,12 +40,6 @@
const char *xmrig::OclSource::get(const Algorithm &algorithm)
{
# ifdef XMRIG_ALGO_CN_GPU
if (algorithm == Algorithm::CN_GPU) {
return cryptonight_gpu_cl;
}
# endif
# ifdef XMRIG_ALGO_RANDOMX
if (algorithm.family() == Algorithm::RANDOM_X) {
return randomx_cl;

View File

@@ -18,11 +18,9 @@
#define ALGO_CN_PICO_0 0x63120200
#define ALGO_CN_PICO_TLO 0x63120274
#define ALGO_CN_UPX2 0x63110200
#define ALGO_CN_GPU 0x63150300
#define ALGO_RX_0 0x72151200
#define ALGO_RX_WOW 0x72141177
#define ALGO_RX_ARQ 0x72121061
#define ALGO_RX_XEQ 0x72121000
#define ALGO_RX_ARQMA 0x72121061
#define ALGO_RX_SFX 0x72151273
#define ALGO_RX_GRAFT 0x72151267
#define ALGO_RX_YADA 0x72151279
@@ -31,8 +29,6 @@
#define ALGO_AR2_WRKZ 0x61120000
#define ALGO_KAWPOW_RVN 0x6b0f0000
#define ALGO_RX_XLA 0x721211ff
#define FAMILY_UNKNOWN 0
#define FAMILY_CN 0x63150000
#define FAMILY_CN_LITE 0x63140000

File diff suppressed because it is too large Load Diff

View File

@@ -1,520 +0,0 @@
#include "wolf-aes.cl"
#include "keccak.cl"
inline uint getIdx()
{
return get_global_id(0) - get_global_offset(0);
}
#define IDX(x) (x)
inline float4 _mm_add_ps(float4 a, float4 b)
{
return a + b;
}
inline float4 _mm_sub_ps(float4 a, float4 b)
{
return a - b;
}
inline float4 _mm_mul_ps(float4 a, float4 b)
{
return a * b;
}
inline float4 _mm_div_ps(float4 a, float4 b)
{
return a / b;
}
inline float4 _mm_and_ps(float4 a, int b)
{
return as_float4(as_int4(a) & (int4)(b));
}
inline float4 _mm_or_ps(float4 a, int b)
{
return as_float4(as_int4(a) | (int4)(b));
}
inline float4 _mm_fmod_ps(float4 v, float dc)
{
float4 d = (float4)(dc);
float4 c = _mm_div_ps(v, d);
c = trunc(c);
c = _mm_mul_ps(c, d);
return _mm_sub_ps(v, c);
}
inline int4 _mm_xor_si128(int4 a, int4 b)
{
return a ^ b;
}
inline float4 _mm_xor_ps(float4 a, int b)
{
return as_float4(as_int4(a) ^ (int4)(b));
}
inline int4 _mm_alignr_epi8(int4 a, const uint rot)
{
const uint right = 8 * rot;
const uint left = (32 - 8 * rot);
return (int4)(
((uint)a.x >> right) | ( a.y << left ),
((uint)a.y >> right) | ( a.z << left ),
((uint)a.z >> right) | ( a.w << left ),
((uint)a.w >> right) | ( a.x << left )
);
}
inline global int4* scratchpad_ptr(uint idx, uint n, __global int *lpad) { return (__global int4*)((__global char*)lpad + (idx & MASK) + n * 16); }
inline float4 fma_break(float4 x)
{
// Break the dependency chain by setting the exp to ?????01
x = _mm_and_ps(x, 0xFEFFFFFF);
return _mm_or_ps(x, 0x00800000);
}
inline void sub_round(float4 n0, float4 n1, float4 n2, float4 n3, float4 rnd_c, float4* n, float4* d, float4* c)
{
n1 = _mm_add_ps(n1, *c);
float4 nn = _mm_mul_ps(n0, *c);
nn = _mm_mul_ps(n1, _mm_mul_ps(nn,nn));
nn = fma_break(nn);
*n = _mm_add_ps(*n, nn);
n3 = _mm_sub_ps(n3, *c);
float4 dd = _mm_mul_ps(n2, *c);
dd = _mm_mul_ps(n3, _mm_mul_ps(dd,dd));
dd = fma_break(dd);
*d = _mm_add_ps(*d, dd);
//Constant feedback
*c = _mm_add_ps(*c, rnd_c);
*c = _mm_add_ps(*c, (float4)(0.734375f));
float4 r = _mm_add_ps(nn, dd);
r = _mm_and_ps(r, 0x807FFFFF);
r = _mm_or_ps(r, 0x40000000);
*c = _mm_add_ps(*c, r);
}
// 9*8 + 2 = 74
inline void round_compute(float4 n0, float4 n1, float4 n2, float4 n3, float4 rnd_c, float4* c, float4* r)
{
float4 n = (float4)(0.0f);
float4 d = (float4)(0.0f);
sub_round(n0, n1, n2, n3, rnd_c, &n, &d, c);
sub_round(n1, n2, n3, n0, rnd_c, &n, &d, c);
sub_round(n2, n3, n0, n1, rnd_c, &n, &d, c);
sub_round(n3, n0, n1, n2, rnd_c, &n, &d, c);
sub_round(n3, n2, n1, n0, rnd_c, &n, &d, c);
sub_round(n2, n1, n0, n3, rnd_c, &n, &d, c);
sub_round(n1, n0, n3, n2, rnd_c, &n, &d, c);
sub_round(n0, n3, n2, n1, rnd_c, &n, &d, c);
// Make sure abs(d) > 2.0 - this prevents division by zero and accidental overflows by division by < 1.0
d = _mm_and_ps(d, 0xFF7FFFFF);
d = _mm_or_ps(d, 0x40000000);
*r =_mm_add_ps(*r, _mm_div_ps(n,d));
}
inline int4 single_compute(float4 n0, float4 n1, float4 n2, float4 n3, float cnt, float4 rnd_c, __local float4* sum)
{
float4 c= (float4)(cnt);
// 35 maths calls follow (140 FLOPS)
float4 r = (float4)(0.0f);
for (int i = 0; i < 4; ++i) {
round_compute(n0, n1, n2, n3, rnd_c, &c, &r);
}
// do a quick fmod by setting exp to 2
r = _mm_and_ps(r, 0x807FFFFF);
r = _mm_or_ps(r, 0x40000000);
*sum = r; // 34
float4 x = (float4)(536870880.0f);
r = _mm_mul_ps(r, x); // 35
return convert_int4_rte(r);
}
inline void single_compute_wrap(const uint rot, int4 v0, int4 v1, int4 v2, int4 v3, float cnt, float4 rnd_c, __local float4* sum, __local int4* out)
{
float4 n0 = convert_float4_rte(v0);
float4 n1 = convert_float4_rte(v1);
float4 n2 = convert_float4_rte(v2);
float4 n3 = convert_float4_rte(v3);
int4 r = single_compute(n0, n1, n2, n3, cnt, rnd_c, sum);
*out = rot == 0 ? r : _mm_alignr_epi8(r, rot);
}
static const __constant uint look[16][4] = {
{0, 1, 2, 3},
{0, 2, 3, 1},
{0, 3, 1, 2},
{0, 3, 2, 1},
{1, 0, 2, 3},
{1, 2, 3, 0},
{1, 3, 0, 2},
{1, 3, 2, 0},
{2, 1, 0, 3},
{2, 0, 3, 1},
{2, 3, 1, 0},
{2, 3, 0, 1},
{3, 1, 2, 0},
{3, 2, 0, 1},
{3, 0, 1, 2},
{3, 0, 2, 1}
};
static const __constant float ccnt[16] = {
1.34375f,
1.28125f,
1.359375f,
1.3671875f,
1.4296875f,
1.3984375f,
1.3828125f,
1.3046875f,
1.4140625f,
1.2734375f,
1.2578125f,
1.2890625f,
1.3203125f,
1.3515625f,
1.3359375f,
1.4609375f
};
struct SharedMemChunk
{
int4 out[16];
float4 va[16];
};
__attribute__((reqd_work_group_size(WORKSIZE * 16, 1, 1)))
__kernel void cn1(__global int *lpad_in, __global int *spad, uint numThreads)
{
const uint gIdx = getIdx();
uint chunk = get_local_id(0) / 16;
__global int* lpad = (__global int*)((__global char*)lpad_in + MEMORY * (gIdx/16));
__local struct SharedMemChunk smem_in[WORKSIZE];
__local struct SharedMemChunk* smem = smem_in + chunk;
uint tid = get_local_id(0) % 16;
uint idxHash = gIdx/16;
uint s = ((__global uint*)spad)[idxHash * 50] >> 8;
float4 vs = (float4)(0);
// tid divided
const uint tidd = tid / 4;
// tid modulo
const uint tidm = tid % 4;
const uint block = tidd * 16 + tidm;
#pragma unroll CN_UNROLL
for (uint i = 0; i < ITERATIONS; i++) {
mem_fence(CLK_LOCAL_MEM_FENCE);
int tmp = ((__global int*)scratchpad_ptr(s, tidd, lpad))[tidm];
((__local int*)(smem->out))[tid] = tmp;
mem_fence(CLK_LOCAL_MEM_FENCE);
{
single_compute_wrap(
tidm,
*(smem->out + look[tid][0]),
*(smem->out + look[tid][1]),
*(smem->out + look[tid][2]),
*(smem->out + look[tid][3]),
ccnt[tid], vs, smem->va + tid,
smem->out + tid
);
}
mem_fence(CLK_LOCAL_MEM_FENCE);
int outXor = ((__local int*)smem->out)[block];
for (uint dd = block + 4; dd < (tidd + 1) * 16; dd += 4) {
outXor ^= ((__local int*)smem->out)[dd];
}
((__global int*)scratchpad_ptr(s, tidd, lpad))[tidm] = outXor ^ tmp;
((__local int*)smem->out)[tid] = outXor;
float va_tmp1 = ((__local float*)smem->va)[block] + ((__local float*)smem->va)[block + 4];
float va_tmp2 = ((__local float*)smem->va)[block+ 8] + ((__local float*)smem->va)[block + 12];
((__local float*)smem->va)[tid] = va_tmp1 + va_tmp2;
mem_fence(CLK_LOCAL_MEM_FENCE);
int out2 = ((__local int*)smem->out)[tid] ^ ((__local int*)smem->out)[tid + 4 ] ^ ((__local int*)smem->out)[tid + 8] ^ ((__local int*)smem->out)[tid + 12];
va_tmp1 = ((__local float*)smem->va)[block] + ((__local float*)smem->va)[block + 4];
va_tmp2 = ((__local float*)smem->va)[block + 8] + ((__local float*)smem->va)[block + 12];
va_tmp1 = va_tmp1 + va_tmp2;
va_tmp1 = fabs(va_tmp1);
float xx = va_tmp1 * 16777216.0f;
int xx_int = (int)xx;
((__local int*)smem->out)[tid] = out2 ^ xx_int;
((__local float*)smem->va)[tid] = va_tmp1 / 64.0f;
mem_fence(CLK_LOCAL_MEM_FENCE);
vs = smem->va[0];
s = smem->out[0].x ^ smem->out[0].y ^ smem->out[0].z ^ smem->out[0].w;
}
}
static const __constant uint skip[3] = {
20,22,22
};
inline void generate_512(uint idx, __local ulong* in, __global ulong* out)
{
ulong hash[25];
hash[0] = in[0] ^ idx;
for (int i = 1; i < 25; ++i) {
hash[i] = in[i];
}
for (int a = 0; a < 3; ++a) {
keccakf1600_1(hash);
for (int i = 0; i < skip[a]; ++i) {
out[i] = hash[i];
}
out += skip[a];
}
}
__attribute__((reqd_work_group_size(8, 8, 1)))
__kernel void cn0(__global ulong *input, int inlen, __global int *Scratchpad, __global ulong *states, uint Threads)
{
const uint gIdx = getIdx();
__local ulong State_buf[8 * 25];
__local ulong* State = State_buf + get_local_id(0) * 25;
{
states += 25 * gIdx;
Scratchpad = (__global int*)((__global char*)Scratchpad + MEMORY * gIdx);
if (get_local_id(1) == 0) {
# ifdef __NV_CL_C_VERSION
for(uint i = 0; i < 8; ++i)
State[i] = input[i];
# else
((__local ulong8 *)State)[0] = vload8(0, input);
# endif
State[8] = input[8];
State[9] = input[9];
State[10] = input[10];
((__local uint *)State)[9] &= 0x00FFFFFFU;
((__local uint *)State)[9] |= (((uint)get_global_id(0)) & 0xFF) << 24;
((__local uint *)State)[10] &= 0xFF000000U;
/* explicit cast to `uint` is required because some OpenCL implementations (e.g. NVIDIA)
* handle get_global_id and get_global_offset as signed long long int and add
* 0xFFFFFFFF... to `get_global_id` if we set on host side a 32bit offset where the first bit is `1`
* (even if it is correct casted to unsigned on the host)
*/
((__local uint *)State)[10] |= (((uint)get_global_id(0) >> 8));
for (int i = 11; i < 25; ++i) {
State[i] = 0x00UL;
}
// Last bit of padding
State[16] = 0x8000000000000000UL;
keccakf1600_2(State);
#pragma unroll
for (int i = 0; i < 25; ++i) {
states[i] = State[i];
}
}
}
}
__attribute__((reqd_work_group_size(64, 1, 1)))
__kernel void cn00(__global int *Scratchpad, __global ulong *states)
{
const uint gIdx = getIdx() / 64;
__local ulong State[25];
states += 25 * gIdx;
Scratchpad = (__global int*)((__global char*)Scratchpad + MEMORY * gIdx);
for (int i = get_local_id(0); i < 25; i += get_local_size(0)) {
State[i] = states[i];
}
barrier(CLK_LOCAL_MEM_FENCE);
for (uint i = get_local_id(0); i < MEMORY / 512; i += get_local_size(0)) {
generate_512(i, State, (__global ulong*)((__global uchar*)Scratchpad + i * 512));
}
}
__attribute__((reqd_work_group_size(8, 8, 1)))
__kernel void cn2(__global uint4 *Scratchpad, __global ulong *states, __global uint *output, ulong Target, uint Threads)
{
__local uint AES0[256], AES1[256], AES2[256], AES3[256];
uint ExpandedKey2[40];
uint4 text;
const uint gIdx = getIdx();
for (int i = get_local_id(1) * 8 + get_local_id(0); i < 256; i += 8 * 8) {
const uint tmp = AES0_C[i];
AES0[i] = tmp;
AES1[i] = rotate(tmp, 8U);
AES2[i] = rotate(tmp, 16U);
AES3[i] = rotate(tmp, 24U);
}
barrier(CLK_LOCAL_MEM_FENCE);
__local uint4 xin1[8][8];
__local uint4 xin2[8][8];
{
states += 25 * gIdx;
Scratchpad += gIdx * (MEMORY >> 4);
#if defined(__Tahiti__) || defined(__Pitcairn__)
for(int i = 0; i < 4; ++i) ((ulong *)ExpandedKey2)[i] = states[i + 4];
text = vload4(get_local_id(1) + 4, (__global uint *)states);
#else
text = vload4(get_local_id(1) + 4, (__global uint *)states);
((uint8 *)ExpandedKey2)[0] = vload8(1, (__global uint *)states);
#endif
AESExpandKey256(ExpandedKey2);
}
barrier(CLK_LOCAL_MEM_FENCE);
__local uint4* xin1_store = &xin1[get_local_id(1)][get_local_id(0)];
__local uint4* xin1_load = &xin1[(get_local_id(1) + 1) % 8][get_local_id(0)];
__local uint4* xin2_store = &xin2[get_local_id(1)][get_local_id(0)];
__local uint4* xin2_load = &xin2[(get_local_id(1) + 1) % 8][get_local_id(0)];
*xin2_store = (uint4)(0, 0, 0, 0);
{
#pragma unroll 2
for (int i = 0, i1 = get_local_id(1); i < (MEMORY >> 7); ++i, i1 = (i1 + 16) % (MEMORY >> 4)) {
text ^= Scratchpad[(uint)i1];
barrier(CLK_LOCAL_MEM_FENCE);
text ^= *xin2_load;
#pragma unroll 10
for(int j = 0; j < 10; ++j)
text = AES_Round(AES0, AES1, AES2, AES3, text, ((uint4 *)ExpandedKey2)[j]);
*xin1_store = text;
text ^= Scratchpad[(uint)i1 + 8u];
barrier(CLK_LOCAL_MEM_FENCE);
text ^= *xin1_load;
#pragma unroll 10
for(int j = 0; j < 10; ++j)
text = AES_Round(AES0, AES1, AES2, AES3, text, ((uint4 *)ExpandedKey2)[j]);
*xin2_store = text;
}
barrier(CLK_LOCAL_MEM_FENCE);
text ^= *xin2_load;
}
/* Also left over threads performe this loop.
* The left over thread results will be ignored
*/
#pragma unroll 16
for(size_t i = 0; i < 16; i++)
{
#pragma unroll 10
for (int j = 0; j < 10; ++j) {
text = AES_Round(AES0, AES1, AES2, AES3, text, ((uint4 *)ExpandedKey2)[j]);
}
barrier(CLK_LOCAL_MEM_FENCE);
*xin1_store = text;
barrier(CLK_LOCAL_MEM_FENCE);
text ^= *xin1_load;
}
__local ulong State_buf[8 * 25];
{
vstore2(as_ulong2(text), get_local_id(1) + 4, states);
}
barrier(CLK_GLOBAL_MEM_FENCE);
{
if(!get_local_id(1))
{
__local ulong* State = State_buf + get_local_id(0) * 25;
for(int i = 0; i < 25; ++i) State[i] = states[i];
keccakf1600_2(State);
if(State[3] <= Target)
{
ulong outIdx = atomic_inc(output + 0xFF);
if(outIdx < 0xFF)
output[outIdx] = get_global_id(0);
}
}
}
mem_fence(CLK_GLOBAL_MEM_FENCE);
}

View File

@@ -1,639 +0,0 @@
#pragma once
namespace xmrig {
static const char cryptonight_gpu_cl[20170] = {
0x23,0x69,0x66,0x6e,0x64,0x65,0x66,0x20,0x57,0x4f,0x4c,0x46,0x5f,0x41,0x45,0x53,0x5f,0x43,0x4c,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x57,0x4f,0x4c,0x46,
0x5f,0x41,0x45,0x53,0x5f,0x43,0x4c,0x0a,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x53,0x54,0x41,0x54,0x49,0x43,0x0a,0x23,0x75,0x6e,0x64,0x65,0x66,0x20,0x53,0x54,0x41,
0x54,0x49,0x43,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x63,0x6c,0x5f,0x61,0x6d,0x64,0x5f,0x6d,0x65,0x64,0x69,0x61,0x5f,0x6f,
0x70,0x73,0x32,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x54,0x41,0x54,0x49,0x43,0x20,0x73,0x74,0x61,0x74,0x69,0x63,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,
0x61,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x20,0x45,0x58,0x54,0x45,0x4e,0x53,0x49,0x4f,0x4e,0x20,0x63,0x6c,0x5f,0x61,0x6d,0x64,0x5f,0x6d,0x65,0x64,0x69,0x61,0x5f,
0x6f,0x70,0x73,0x32,0x20,0x3a,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x54,0x41,0x54,
0x49,0x43,0x0a,0x69,0x6e,0x6c,0x69,0x6e,0x65,0x20,0x69,0x6e,0x74,0x20,0x61,0x6d,0x64,0x5f,0x62,0x66,0x65,0x28,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,
0x20,0x73,0x72,0x63,0x30,0x2c,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x2c,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,
0x6e,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x28,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x77,0x69,0x64,0x74,0x68,0x29,0x3c,0x33,0x32,
0x75,0x29,0x20,0x7b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x28,0x73,0x72,0x63,0x30,0x3c,0x3c,0x28,0x33,0x32,0x75,0x2d,0x6f,0x66,0x66,0x73,0x65,0x74,0x2d,0x77,
0x69,0x64,0x74,0x68,0x29,0x29,0x3e,0x3e,0x28,0x33,0x32,0x75,0x2d,0x77,0x69,0x64,0x74,0x68,0x29,0x3b,0x0a,0x7d,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x73,0x72,
0x63,0x30,0x3e,0x3e,0x6f,0x66,0x66,0x73,0x65,0x74,0x3b,0x0a,0x7d,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x53,0x54,0x41,0x54,0x49,0x43,0x20,0x63,0x6f,0x6e,0x73,
0x74,0x20,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x41,0x45,0x53,0x30,0x5f,0x43,0x5b,0x32,0x35,0x36,0x5d,0x20,0x3d,0x0a,
0x7b,0x0a,0x30,0x78,0x41,0x35,0x36,0x33,0x36,0x33,0x43,0x36,0x55,0x2c,0x30,0x78,0x38,0x34,0x37,0x43,0x37,0x43,0x46,0x38,0x55,0x2c,0x30,0x78,0x39,0x39,0x37,0x37,
0x37,0x37,0x45,0x45,0x55,0x2c,0x30,0x78,0x38,0x44,0x37,0x42,0x37,0x42,0x46,0x36,0x55,0x2c,0x0a,0x30,0x78,0x30,0x44,0x46,0x32,0x46,0x32,0x46,0x46,0x55,0x2c,0x30,
0x78,0x42,0x44,0x36,0x42,0x36,0x42,0x44,0x36,0x55,0x2c,0x30,0x78,0x42,0x31,0x36,0x46,0x36,0x46,0x44,0x45,0x55,0x2c,0x30,0x78,0x35,0x34,0x43,0x35,0x43,0x35,0x39,
0x31,0x55,0x2c,0x0a,0x30,0x78,0x35,0x30,0x33,0x30,0x33,0x30,0x36,0x30,0x55,0x2c,0x30,0x78,0x30,0x33,0x30,0x31,0x30,0x31,0x30,0x32,0x55,0x2c,0x30,0x78,0x41,0x39,
0x36,0x37,0x36,0x37,0x43,0x45,0x55,0x2c,0x30,0x78,0x37,0x44,0x32,0x42,0x32,0x42,0x35,0x36,0x55,0x2c,0x0a,0x30,0x78,0x31,0x39,0x46,0x45,0x46,0x45,0x45,0x37,0x55,
0x2c,0x30,0x78,0x36,0x32,0x44,0x37,0x44,0x37,0x42,0x35,0x55,0x2c,0x30,0x78,0x45,0x36,0x41,0x42,0x41,0x42,0x34,0x44,0x55,0x2c,0x30,0x78,0x39,0x41,0x37,0x36,0x37,
0x36,0x45,0x43,0x55,0x2c,0x0a,0x30,0x78,0x34,0x35,0x43,0x41,0x43,0x41,0x38,0x46,0x55,0x2c,0x30,0x78,0x39,0x44,0x38,0x32,0x38,0x32,0x31,0x46,0x55,0x2c,0x30,0x78,
0x34,0x30,0x43,0x39,0x43,0x39,0x38,0x39,0x55,0x2c,0x30,0x78,0x38,0x37,0x37,0x44,0x37,0x44,0x46,0x41,0x55,0x2c,0x0a,0x30,0x78,0x31,0x35,0x46,0x41,0x46,0x41,0x45,
0x46,0x55,0x2c,0x30,0x78,0x45,0x42,0x35,0x39,0x35,0x39,0x42,0x32,0x55,0x2c,0x30,0x78,0x43,0x39,0x34,0x37,0x34,0x37,0x38,0x45,0x55,0x2c,0x30,0x78,0x30,0x42,0x46,
0x30,0x46,0x30,0x46,0x42,0x55,0x2c,0x0a,0x30,0x78,0x45,0x43,0x41,0x44,0x41,0x44,0x34,0x31,0x55,0x2c,0x30,0x78,0x36,0x37,0x44,0x34,0x44,0x34,0x42,0x33,0x55,0x2c,
0x30,0x78,0x46,0x44,0x41,0x32,0x41,0x32,0x35,0x46,0x55,0x2c,0x30,0x78,0x45,0x41,0x41,0x46,0x41,0x46,0x34,0x35,0x55,0x2c,0x0a,0x30,0x78,0x42,0x46,0x39,0x43,0x39,
0x43,0x32,0x33,0x55,0x2c,0x30,0x78,0x46,0x37,0x41,0x34,0x41,0x34,0x35,0x33,0x55,0x2c,0x30,0x78,0x39,0x36,0x37,0x32,0x37,0x32,0x45,0x34,0x55,0x2c,0x30,0x78,0x35,
0x42,0x43,0x30,0x43,0x30,0x39,0x42,0x55,0x2c,0x0a,0x30,0x78,0x43,0x32,0x42,0x37,0x42,0x37,0x37,0x35,0x55,0x2c,0x30,0x78,0x31,0x43,0x46,0x44,0x46,0x44,0x45,0x31,
0x55,0x2c,0x30,0x78,0x41,0x45,0x39,0x33,0x39,0x33,0x33,0x44,0x55,0x2c,0x30,0x78,0x36,0x41,0x32,0x36,0x32,0x36,0x34,0x43,0x55,0x2c,0x0a,0x30,0x78,0x35,0x41,0x33,
0x36,0x33,0x36,0x36,0x43,0x55,0x2c,0x30,0x78,0x34,0x31,0x33,0x46,0x33,0x46,0x37,0x45,0x55,0x2c,0x30,0x78,0x30,0x32,0x46,0x37,0x46,0x37,0x46,0x35,0x55,0x2c,0x30,
0x78,0x34,0x46,0x43,0x43,0x43,0x43,0x38,0x33,0x55,0x2c,0x0a,0x30,0x78,0x35,0x43,0x33,0x34,0x33,0x34,0x36,0x38,0x55,0x2c,0x30,0x78,0x46,0x34,0x41,0x35,0x41,0x35,
0x35,0x31,0x55,0x2c,0x30,0x78,0x33,0x34,0x45,0x35,0x45,0x35,0x44,0x31,0x55,0x2c,0x30,0x78,0x30,0x38,0x46,0x31,0x46,0x31,0x46,0x39,0x55,0x2c,0x0a,0x30,0x78,0x39,
0x33,0x37,0x31,0x37,0x31,0x45,0x32,0x55,0x2c,0x30,0x78,0x37,0x33,0x44,0x38,0x44,0x38,0x41,0x42,0x55,0x2c,0x30,0x78,0x35,0x33,0x33,0x31,0x33,0x31,0x36,0x32,0x55,
0x2c,0x30,0x78,0x33,0x46,0x31,0x35,0x31,0x35,0x32,0x41,0x55,0x2c,0x0a,0x30,0x78,0x30,0x43,0x30,0x34,0x30,0x34,0x30,0x38,0x55,0x2c,0x30,0x78,0x35,0x32,0x43,0x37,
0x43,0x37,0x39,0x35,0x55,0x2c,0x30,0x78,0x36,0x35,0x32,0x33,0x32,0x33,0x34,0x36,0x55,0x2c,0x30,0x78,0x35,0x45,0x43,0x33,0x43,0x33,0x39,0x44,0x55,0x2c,0x0a,0x30,
0x78,0x32,0x38,0x31,0x38,0x31,0x38,0x33,0x30,0x55,0x2c,0x30,0x78,0x41,0x31,0x39,0x36,0x39,0x36,0x33,0x37,0x55,0x2c,0x30,0x78,0x30,0x46,0x30,0x35,0x30,0x35,0x30,
0x41,0x55,0x2c,0x30,0x78,0x42,0x35,0x39,0x41,0x39,0x41,0x32,0x46,0x55,0x2c,0x0a,0x30,0x78,0x30,0x39,0x30,0x37,0x30,0x37,0x30,0x45,0x55,0x2c,0x30,0x78,0x33,0x36,
0x31,0x32,0x31,0x32,0x32,0x34,0x55,0x2c,0x30,0x78,0x39,0x42,0x38,0x30,0x38,0x30,0x31,0x42,0x55,0x2c,0x30,0x78,0x33,0x44,0x45,0x32,0x45,0x32,0x44,0x46,0x55,0x2c,
0x0a,0x30,0x78,0x32,0x36,0x45,0x42,0x45,0x42,0x43,0x44,0x55,0x2c,0x30,0x78,0x36,0x39,0x32,0x37,0x32,0x37,0x34,0x45,0x55,0x2c,0x30,0x78,0x43,0x44,0x42,0x32,0x42,
0x32,0x37,0x46,0x55,0x2c,0x30,0x78,0x39,0x46,0x37,0x35,0x37,0x35,0x45,0x41,0x55,0x2c,0x0a,0x30,0x78,0x31,0x42,0x30,0x39,0x30,0x39,0x31,0x32,0x55,0x2c,0x30,0x78,
0x39,0x45,0x38,0x33,0x38,0x33,0x31,0x44,0x55,0x2c,0x30,0x78,0x37,0x34,0x32,0x43,0x32,0x43,0x35,0x38,0x55,0x2c,0x30,0x78,0x32,0x45,0x31,0x41,0x31,0x41,0x33,0x34,
0x55,0x2c,0x0a,0x30,0x78,0x32,0x44,0x31,0x42,0x31,0x42,0x33,0x36,0x55,0x2c,0x30,0x78,0x42,0x32,0x36,0x45,0x36,0x45,0x44,0x43,0x55,0x2c,0x30,0x78,0x45,0x45,0x35,
0x41,0x35,0x41,0x42,0x34,0x55,0x2c,0x30,0x78,0x46,0x42,0x41,0x30,0x41,0x30,0x35,0x42,0x55,0x2c,0x0a,0x30,0x78,0x46,0x36,0x35,0x32,0x35,0x32,0x41,0x34,0x55,0x2c,
0x30,0x78,0x34,0x44,0x33,0x42,0x33,0x42,0x37,0x36,0x55,0x2c,0x30,0x78,0x36,0x31,0x44,0x36,0x44,0x36,0x42,0x37,0x55,0x2c,0x30,0x78,0x43,0x45,0x42,0x33,0x42,0x33,
0x37,0x44,0x55,0x2c,0x0a,0x30,0x78,0x37,0x42,0x32,0x39,0x32,0x39,0x35,0x32,0x55,0x2c,0x30,0x78,0x33,0x45,0x45,0x33,0x45,0x33,0x44,0x44,0x55,0x2c,0x30,0x78,0x37,
0x31,0x32,0x46,0x32,0x46,0x35,0x45,0x55,0x2c,0x30,0x78,0x39,0x37,0x38,0x34,0x38,0x34,0x31,0x33,0x55,0x2c,0x0a,0x30,0x78,0x46,0x35,0x35,0x33,0x35,0x33,0x41,0x36,
0x55,0x2c,0x30,0x78,0x36,0x38,0x44,0x31,0x44,0x31,0x42,0x39,0x55,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x55,0x2c,0x30,0x78,0x32,0x43,0x45,0x44,
0x45,0x44,0x43,0x31,0x55,0x2c,0x0a,0x30,0x78,0x36,0x30,0x32,0x30,0x32,0x30,0x34,0x30,0x55,0x2c,0x30,0x78,0x31,0x46,0x46,0x43,0x46,0x43,0x45,0x33,0x55,0x2c,0x30,
0x78,0x43,0x38,0x42,0x31,0x42,0x31,0x37,0x39,0x55,0x2c,0x30,0x78,0x45,0x44,0x35,0x42,0x35,0x42,0x42,0x36,0x55,0x2c,0x0a,0x30,0x78,0x42,0x45,0x36,0x41,0x36,0x41,
0x44,0x34,0x55,0x2c,0x30,0x78,0x34,0x36,0x43,0x42,0x43,0x42,0x38,0x44,0x55,0x2c,0x30,0x78,0x44,0x39,0x42,0x45,0x42,0x45,0x36,0x37,0x55,0x2c,0x30,0x78,0x34,0x42,
0x33,0x39,0x33,0x39,0x37,0x32,0x55,0x2c,0x0a,0x30,0x78,0x44,0x45,0x34,0x41,0x34,0x41,0x39,0x34,0x55,0x2c,0x30,0x78,0x44,0x34,0x34,0x43,0x34,0x43,0x39,0x38,0x55,
0x2c,0x30,0x78,0x45,0x38,0x35,0x38,0x35,0x38,0x42,0x30,0x55,0x2c,0x30,0x78,0x34,0x41,0x43,0x46,0x43,0x46,0x38,0x35,0x55,0x2c,0x0a,0x30,0x78,0x36,0x42,0x44,0x30,
0x44,0x30,0x42,0x42,0x55,0x2c,0x30,0x78,0x32,0x41,0x45,0x46,0x45,0x46,0x43,0x35,0x55,0x2c,0x30,0x78,0x45,0x35,0x41,0x41,0x41,0x41,0x34,0x46,0x55,0x2c,0x30,0x78,
0x31,0x36,0x46,0x42,0x46,0x42,0x45,0x44,0x55,0x2c,0x0a,0x30,0x78,0x43,0x35,0x34,0x33,0x34,0x33,0x38,0x36,0x55,0x2c,0x30,0x78,0x44,0x37,0x34,0x44,0x34,0x44,0x39,
0x41,0x55,0x2c,0x30,0x78,0x35,0x35,0x33,0x33,0x33,0x33,0x36,0x36,0x55,0x2c,0x30,0x78,0x39,0x34,0x38,0x35,0x38,0x35,0x31,0x31,0x55,0x2c,0x0a,0x30,0x78,0x43,0x46,
0x34,0x35,0x34,0x35,0x38,0x41,0x55,0x2c,0x30,0x78,0x31,0x30,0x46,0x39,0x46,0x39,0x45,0x39,0x55,0x2c,0x30,0x78,0x30,0x36,0x30,0x32,0x30,0x32,0x30,0x34,0x55,0x2c,
0x30,0x78,0x38,0x31,0x37,0x46,0x37,0x46,0x46,0x45,0x55,0x2c,0x0a,0x30,0x78,0x46,0x30,0x35,0x30,0x35,0x30,0x41,0x30,0x55,0x2c,0x30,0x78,0x34,0x34,0x33,0x43,0x33,
0x43,0x37,0x38,0x55,0x2c,0x30,0x78,0x42,0x41,0x39,0x46,0x39,0x46,0x32,0x35,0x55,0x2c,0x30,0x78,0x45,0x33,0x41,0x38,0x41,0x38,0x34,0x42,0x55,0x2c,0x0a,0x30,0x78,
0x46,0x33,0x35,0x31,0x35,0x31,0x41,0x32,0x55,0x2c,0x30,0x78,0x46,0x45,0x41,0x33,0x41,0x33,0x35,0x44,0x55,0x2c,0x30,0x78,0x43,0x30,0x34,0x30,0x34,0x30,0x38,0x30,
0x55,0x2c,0x30,0x78,0x38,0x41,0x38,0x46,0x38,0x46,0x30,0x35,0x55,0x2c,0x0a,0x30,0x78,0x41,0x44,0x39,0x32,0x39,0x32,0x33,0x46,0x55,0x2c,0x30,0x78,0x42,0x43,0x39,
0x44,0x39,0x44,0x32,0x31,0x55,0x2c,0x30,0x78,0x34,0x38,0x33,0x38,0x33,0x38,0x37,0x30,0x55,0x2c,0x30,0x78,0x30,0x34,0x46,0x35,0x46,0x35,0x46,0x31,0x55,0x2c,0x0a,
0x30,0x78,0x44,0x46,0x42,0x43,0x42,0x43,0x36,0x33,0x55,0x2c,0x30,0x78,0x43,0x31,0x42,0x36,0x42,0x36,0x37,0x37,0x55,0x2c,0x30,0x78,0x37,0x35,0x44,0x41,0x44,0x41,
0x41,0x46,0x55,0x2c,0x30,0x78,0x36,0x33,0x32,0x31,0x32,0x31,0x34,0x32,0x55,0x2c,0x0a,0x30,0x78,0x33,0x30,0x31,0x30,0x31,0x30,0x32,0x30,0x55,0x2c,0x30,0x78,0x31,
0x41,0x46,0x46,0x46,0x46,0x45,0x35,0x55,0x2c,0x30,0x78,0x30,0x45,0x46,0x33,0x46,0x33,0x46,0x44,0x55,0x2c,0x30,0x78,0x36,0x44,0x44,0x32,0x44,0x32,0x42,0x46,0x55,
0x2c,0x0a,0x30,0x78,0x34,0x43,0x43,0x44,0x43,0x44,0x38,0x31,0x55,0x2c,0x30,0x78,0x31,0x34,0x30,0x43,0x30,0x43,0x31,0x38,0x55,0x2c,0x30,0x78,0x33,0x35,0x31,0x33,
0x31,0x33,0x32,0x36,0x55,0x2c,0x30,0x78,0x32,0x46,0x45,0x43,0x45,0x43,0x43,0x33,0x55,0x2c,0x0a,0x30,0x78,0x45,0x31,0x35,0x46,0x35,0x46,0x42,0x45,0x55,0x2c,0x30,
0x78,0x41,0x32,0x39,0x37,0x39,0x37,0x33,0x35,0x55,0x2c,0x30,0x78,0x43,0x43,0x34,0x34,0x34,0x34,0x38,0x38,0x55,0x2c,0x30,0x78,0x33,0x39,0x31,0x37,0x31,0x37,0x32,
0x45,0x55,0x2c,0x0a,0x30,0x78,0x35,0x37,0x43,0x34,0x43,0x34,0x39,0x33,0x55,0x2c,0x30,0x78,0x46,0x32,0x41,0x37,0x41,0x37,0x35,0x35,0x55,0x2c,0x30,0x78,0x38,0x32,
0x37,0x45,0x37,0x45,0x46,0x43,0x55,0x2c,0x30,0x78,0x34,0x37,0x33,0x44,0x33,0x44,0x37,0x41,0x55,0x2c,0x0a,0x30,0x78,0x41,0x43,0x36,0x34,0x36,0x34,0x43,0x38,0x55,
0x2c,0x30,0x78,0x45,0x37,0x35,0x44,0x35,0x44,0x42,0x41,0x55,0x2c,0x30,0x78,0x32,0x42,0x31,0x39,0x31,0x39,0x33,0x32,0x55,0x2c,0x30,0x78,0x39,0x35,0x37,0x33,0x37,
0x33,0x45,0x36,0x55,0x2c,0x0a,0x30,0x78,0x41,0x30,0x36,0x30,0x36,0x30,0x43,0x30,0x55,0x2c,0x30,0x78,0x39,0x38,0x38,0x31,0x38,0x31,0x31,0x39,0x55,0x2c,0x30,0x78,
0x44,0x31,0x34,0x46,0x34,0x46,0x39,0x45,0x55,0x2c,0x30,0x78,0x37,0x46,0x44,0x43,0x44,0x43,0x41,0x33,0x55,0x2c,0x0a,0x30,0x78,0x36,0x36,0x32,0x32,0x32,0x32,0x34,
0x34,0x55,0x2c,0x30,0x78,0x37,0x45,0x32,0x41,0x32,0x41,0x35,0x34,0x55,0x2c,0x30,0x78,0x41,0x42,0x39,0x30,0x39,0x30,0x33,0x42,0x55,0x2c,0x30,0x78,0x38,0x33,0x38,
0x38,0x38,0x38,0x30,0x42,0x55,0x2c,0x0a,0x30,0x78,0x43,0x41,0x34,0x36,0x34,0x36,0x38,0x43,0x55,0x2c,0x30,0x78,0x32,0x39,0x45,0x45,0x45,0x45,0x43,0x37,0x55,0x2c,
0x30,0x78,0x44,0x33,0x42,0x38,0x42,0x38,0x36,0x42,0x55,0x2c,0x30,0x78,0x33,0x43,0x31,0x34,0x31,0x34,0x32,0x38,0x55,0x2c,0x0a,0x30,0x78,0x37,0x39,0x44,0x45,0x44,
0x45,0x41,0x37,0x55,0x2c,0x30,0x78,0x45,0x32,0x35,0x45,0x35,0x45,0x42,0x43,0x55,0x2c,0x30,0x78,0x31,0x44,0x30,0x42,0x30,0x42,0x31,0x36,0x55,0x2c,0x30,0x78,0x37,
0x36,0x44,0x42,0x44,0x42,0x41,0x44,0x55,0x2c,0x0a,0x30,0x78,0x33,0x42,0x45,0x30,0x45,0x30,0x44,0x42,0x55,0x2c,0x30,0x78,0x35,0x36,0x33,0x32,0x33,0x32,0x36,0x34,
0x55,0x2c,0x30,0x78,0x34,0x45,0x33,0x41,0x33,0x41,0x37,0x34,0x55,0x2c,0x30,0x78,0x31,0x45,0x30,0x41,0x30,0x41,0x31,0x34,0x55,0x2c,0x0a,0x30,0x78,0x44,0x42,0x34,
0x39,0x34,0x39,0x39,0x32,0x55,0x2c,0x30,0x78,0x30,0x41,0x30,0x36,0x30,0x36,0x30,0x43,0x55,0x2c,0x30,0x78,0x36,0x43,0x32,0x34,0x32,0x34,0x34,0x38,0x55,0x2c,0x30,
0x78,0x45,0x34,0x35,0x43,0x35,0x43,0x42,0x38,0x55,0x2c,0x0a,0x30,0x78,0x35,0x44,0x43,0x32,0x43,0x32,0x39,0x46,0x55,0x2c,0x30,0x78,0x36,0x45,0x44,0x33,0x44,0x33,
0x42,0x44,0x55,0x2c,0x30,0x78,0x45,0x46,0x41,0x43,0x41,0x43,0x34,0x33,0x55,0x2c,0x30,0x78,0x41,0x36,0x36,0x32,0x36,0x32,0x43,0x34,0x55,0x2c,0x0a,0x30,0x78,0x41,
0x38,0x39,0x31,0x39,0x31,0x33,0x39,0x55,0x2c,0x30,0x78,0x41,0x34,0x39,0x35,0x39,0x35,0x33,0x31,0x55,0x2c,0x30,0x78,0x33,0x37,0x45,0x34,0x45,0x34,0x44,0x33,0x55,
0x2c,0x30,0x78,0x38,0x42,0x37,0x39,0x37,0x39,0x46,0x32,0x55,0x2c,0x0a,0x30,0x78,0x33,0x32,0x45,0x37,0x45,0x37,0x44,0x35,0x55,0x2c,0x30,0x78,0x34,0x33,0x43,0x38,
0x43,0x38,0x38,0x42,0x55,0x2c,0x30,0x78,0x35,0x39,0x33,0x37,0x33,0x37,0x36,0x45,0x55,0x2c,0x30,0x78,0x42,0x37,0x36,0x44,0x36,0x44,0x44,0x41,0x55,0x2c,0x0a,0x30,
0x78,0x38,0x43,0x38,0x44,0x38,0x44,0x30,0x31,0x55,0x2c,0x30,0x78,0x36,0x34,0x44,0x35,0x44,0x35,0x42,0x31,0x55,0x2c,0x30,0x78,0x44,0x32,0x34,0x45,0x34,0x45,0x39,
0x43,0x55,0x2c,0x30,0x78,0x45,0x30,0x41,0x39,0x41,0x39,0x34,0x39,0x55,0x2c,0x0a,0x30,0x78,0x42,0x34,0x36,0x43,0x36,0x43,0x44,0x38,0x55,0x2c,0x30,0x78,0x46,0x41,
0x35,0x36,0x35,0x36,0x41,0x43,0x55,0x2c,0x30,0x78,0x30,0x37,0x46,0x34,0x46,0x34,0x46,0x33,0x55,0x2c,0x30,0x78,0x32,0x35,0x45,0x41,0x45,0x41,0x43,0x46,0x55,0x2c,
0x0a,0x30,0x78,0x41,0x46,0x36,0x35,0x36,0x35,0x43,0x41,0x55,0x2c,0x30,0x78,0x38,0x45,0x37,0x41,0x37,0x41,0x46,0x34,0x55,0x2c,0x30,0x78,0x45,0x39,0x41,0x45,0x41,
0x45,0x34,0x37,0x55,0x2c,0x30,0x78,0x31,0x38,0x30,0x38,0x30,0x38,0x31,0x30,0x55,0x2c,0x0a,0x30,0x78,0x44,0x35,0x42,0x41,0x42,0x41,0x36,0x46,0x55,0x2c,0x30,0x78,
0x38,0x38,0x37,0x38,0x37,0x38,0x46,0x30,0x55,0x2c,0x30,0x78,0x36,0x46,0x32,0x35,0x32,0x35,0x34,0x41,0x55,0x2c,0x30,0x78,0x37,0x32,0x32,0x45,0x32,0x45,0x35,0x43,
0x55,0x2c,0x0a,0x30,0x78,0x32,0x34,0x31,0x43,0x31,0x43,0x33,0x38,0x55,0x2c,0x30,0x78,0x46,0x31,0x41,0x36,0x41,0x36,0x35,0x37,0x55,0x2c,0x30,0x78,0x43,0x37,0x42,
0x34,0x42,0x34,0x37,0x33,0x55,0x2c,0x30,0x78,0x35,0x31,0x43,0x36,0x43,0x36,0x39,0x37,0x55,0x2c,0x0a,0x30,0x78,0x32,0x33,0x45,0x38,0x45,0x38,0x43,0x42,0x55,0x2c,
0x30,0x78,0x37,0x43,0x44,0x44,0x44,0x44,0x41,0x31,0x55,0x2c,0x30,0x78,0x39,0x43,0x37,0x34,0x37,0x34,0x45,0x38,0x55,0x2c,0x30,0x78,0x32,0x31,0x31,0x46,0x31,0x46,
0x33,0x45,0x55,0x2c,0x0a,0x30,0x78,0x44,0x44,0x34,0x42,0x34,0x42,0x39,0x36,0x55,0x2c,0x30,0x78,0x44,0x43,0x42,0x44,0x42,0x44,0x36,0x31,0x55,0x2c,0x30,0x78,0x38,
0x36,0x38,0x42,0x38,0x42,0x30,0x44,0x55,0x2c,0x30,0x78,0x38,0x35,0x38,0x41,0x38,0x41,0x30,0x46,0x55,0x2c,0x0a,0x30,0x78,0x39,0x30,0x37,0x30,0x37,0x30,0x45,0x30,
0x55,0x2c,0x30,0x78,0x34,0x32,0x33,0x45,0x33,0x45,0x37,0x43,0x55,0x2c,0x30,0x78,0x43,0x34,0x42,0x35,0x42,0x35,0x37,0x31,0x55,0x2c,0x30,0x78,0x41,0x41,0x36,0x36,
0x36,0x36,0x43,0x43,0x55,0x2c,0x0a,0x30,0x78,0x44,0x38,0x34,0x38,0x34,0x38,0x39,0x30,0x55,0x2c,0x30,0x78,0x30,0x35,0x30,0x33,0x30,0x33,0x30,0x36,0x55,0x2c,0x30,
0x78,0x30,0x31,0x46,0x36,0x46,0x36,0x46,0x37,0x55,0x2c,0x30,0x78,0x31,0x32,0x30,0x45,0x30,0x45,0x31,0x43,0x55,0x2c,0x0a,0x30,0x78,0x41,0x33,0x36,0x31,0x36,0x31,
0x43,0x32,0x55,0x2c,0x30,0x78,0x35,0x46,0x33,0x35,0x33,0x35,0x36,0x41,0x55,0x2c,0x30,0x78,0x46,0x39,0x35,0x37,0x35,0x37,0x41,0x45,0x55,0x2c,0x30,0x78,0x44,0x30,
0x42,0x39,0x42,0x39,0x36,0x39,0x55,0x2c,0x0a,0x30,0x78,0x39,0x31,0x38,0x36,0x38,0x36,0x31,0x37,0x55,0x2c,0x30,0x78,0x35,0x38,0x43,0x31,0x43,0x31,0x39,0x39,0x55,
0x2c,0x30,0x78,0x32,0x37,0x31,0x44,0x31,0x44,0x33,0x41,0x55,0x2c,0x30,0x78,0x42,0x39,0x39,0x45,0x39,0x45,0x32,0x37,0x55,0x2c,0x0a,0x30,0x78,0x33,0x38,0x45,0x31,
0x45,0x31,0x44,0x39,0x55,0x2c,0x30,0x78,0x31,0x33,0x46,0x38,0x46,0x38,0x45,0x42,0x55,0x2c,0x30,0x78,0x42,0x33,0x39,0x38,0x39,0x38,0x32,0x42,0x55,0x2c,0x30,0x78,
0x33,0x33,0x31,0x31,0x31,0x31,0x32,0x32,0x55,0x2c,0x0a,0x30,0x78,0x42,0x42,0x36,0x39,0x36,0x39,0x44,0x32,0x55,0x2c,0x30,0x78,0x37,0x30,0x44,0x39,0x44,0x39,0x41,
0x39,0x55,0x2c,0x30,0x78,0x38,0x39,0x38,0x45,0x38,0x45,0x30,0x37,0x55,0x2c,0x30,0x78,0x41,0x37,0x39,0x34,0x39,0x34,0x33,0x33,0x55,0x2c,0x0a,0x30,0x78,0x42,0x36,
0x39,0x42,0x39,0x42,0x32,0x44,0x55,0x2c,0x30,0x78,0x32,0x32,0x31,0x45,0x31,0x45,0x33,0x43,0x55,0x2c,0x30,0x78,0x39,0x32,0x38,0x37,0x38,0x37,0x31,0x35,0x55,0x2c,
0x30,0x78,0x32,0x30,0x45,0x39,0x45,0x39,0x43,0x39,0x55,0x2c,0x0a,0x30,0x78,0x34,0x39,0x43,0x45,0x43,0x45,0x38,0x37,0x55,0x2c,0x30,0x78,0x46,0x46,0x35,0x35,0x35,
0x35,0x41,0x41,0x55,0x2c,0x30,0x78,0x37,0x38,0x32,0x38,0x32,0x38,0x35,0x30,0x55,0x2c,0x30,0x78,0x37,0x41,0x44,0x46,0x44,0x46,0x41,0x35,0x55,0x2c,0x0a,0x30,0x78,
0x38,0x46,0x38,0x43,0x38,0x43,0x30,0x33,0x55,0x2c,0x30,0x78,0x46,0x38,0x41,0x31,0x41,0x31,0x35,0x39,0x55,0x2c,0x30,0x78,0x38,0x30,0x38,0x39,0x38,0x39,0x30,0x39,
0x55,0x2c,0x30,0x78,0x31,0x37,0x30,0x44,0x30,0x44,0x31,0x41,0x55,0x2c,0x0a,0x30,0x78,0x44,0x41,0x42,0x46,0x42,0x46,0x36,0x35,0x55,0x2c,0x30,0x78,0x33,0x31,0x45,
0x36,0x45,0x36,0x44,0x37,0x55,0x2c,0x30,0x78,0x43,0x36,0x34,0x32,0x34,0x32,0x38,0x34,0x55,0x2c,0x30,0x78,0x42,0x38,0x36,0x38,0x36,0x38,0x44,0x30,0x55,0x2c,0x0a,
0x30,0x78,0x43,0x33,0x34,0x31,0x34,0x31,0x38,0x32,0x55,0x2c,0x30,0x78,0x42,0x30,0x39,0x39,0x39,0x39,0x32,0x39,0x55,0x2c,0x30,0x78,0x37,0x37,0x32,0x44,0x32,0x44,
0x35,0x41,0x55,0x2c,0x30,0x78,0x31,0x31,0x30,0x46,0x30,0x46,0x31,0x45,0x55,0x2c,0x0a,0x30,0x78,0x43,0x42,0x42,0x30,0x42,0x30,0x37,0x42,0x55,0x2c,0x30,0x78,0x46,
0x43,0x35,0x34,0x35,0x34,0x41,0x38,0x55,0x2c,0x30,0x78,0x44,0x36,0x42,0x42,0x42,0x42,0x36,0x44,0x55,0x2c,0x30,0x78,0x33,0x41,0x31,0x36,0x31,0x36,0x32,0x43,0x55,
0x0a,0x7d,0x3b,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x42,0x59,0x54,0x45,0x28,0x78,0x2c,0x20,0x79,0x29,0x20,0x28,0x61,0x6d,0x64,0x5f,0x62,0x66,0x65,0x28,
0x28,0x78,0x29,0x2c,0x20,0x28,0x79,0x29,0x20,0x3c,0x3c,0x20,0x33,0x55,0x2c,0x20,0x38,0x55,0x29,0x29,0x0a,0x23,0x69,0x66,0x20,0x28,0x41,0x4c,0x47,0x4f,0x20,0x3d,
0x3d,0x20,0x41,0x4c,0x47,0x4f,0x5f,0x43,0x4e,0x5f,0x48,0x45,0x41,0x56,0x59,0x5f,0x54,0x55,0x42,0x45,0x29,0x0a,0x69,0x6e,0x6c,0x69,0x6e,0x65,0x20,0x75,0x69,0x6e,
0x74,0x34,0x20,0x41,0x45,0x53,0x5f,0x52,0x6f,0x75,0x6e,0x64,0x5f,0x62,0x69,0x74,0x74,0x75,0x62,0x65,0x32,0x28,0x63,0x6f,0x6e,0x73,0x74,0x20,0x5f,0x5f,0x6c,0x6f,
0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x20,0x2a,0x41,0x45,0x53,0x30,0x2c,0x63,0x6f,0x6e,0x73,0x74,0x20,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,
0x74,0x20,0x2a,0x41,0x45,0x53,0x31,0x2c,0x75,0x69,0x6e,0x74,0x34,0x20,0x78,0x2c,0x75,0x69,0x6e,0x74,0x34,0x20,0x6b,0x29,0x0a,0x7b,0x0a,0x78,0x3d,0x7e,0x78,0x3b,
0x0a,0x6b,0x2e,0x73,0x30,0x20,0x5e,0x3d,0x20,0x41,0x45,0x53,0x30,0x5b,0x42,0x59,0x54,0x45,0x28,0x78,0x2e,0x73,0x30,0x2c,0x30,0x29,0x5d,0x5e,0x41,0x45,0x53,0x31,
0x5b,0x42,0x59,0x54,0x45,0x28,0x78,0x2e,0x73,0x31,0x2c,0x31,0x29,0x5d,0x5e,0x72,0x6f,0x74,0x61,0x74,0x65,0x28,0x41,0x45,0x53,0x30,0x5b,0x42,0x59,0x54,0x45,0x28,
0x78,0x2e,0x73,0x32,0x2c,0x32,0x29,0x5d,0x5e,0x41,0x45,0x53,0x31,0x5b,0x42,0x59,0x54,0x45,0x28,0x78,0x2e,0x73,0x33,0x2c,0x33,0x29,0x5d,0x2c,0x31,0x36,0x55,0x29,
0x3b,0x0a,0x78,0x2e,0x73,0x30,0x20,0x5e,0x3d,0x20,0x6b,0x2e,0x73,0x30,0x3b,0x0a,0x6b,0x2e,0x73,0x31,0x20,0x5e,0x3d,0x20,0x41,0x45,0x53,0x30,0x5b,0x42,0x59,0x54,
0x45,0x28,0x78,0x2e,0x73,0x31,0x2c,0x30,0x29,0x5d,0x5e,0x41,0x45,0x53,0x31,0x5b,0x42,0x59,0x54,0x45,0x28,0x78,0x2e,0x73,0x32,0x2c,0x31,0x29,0x5d,0x5e,0x72,0x6f,
0x74,0x61,0x74,0x65,0x28,0x41,0x45,0x53,0x30,0x5b,0x42,0x59,0x54,0x45,0x28,0x78,0x2e,0x73,0x33,0x2c,0x32,0x29,0x5d,0x5e,0x41,0x45,0x53,0x31,0x5b,0x42,0x59,0x54,
0x45,0x28,0x78,0x2e,0x73,0x30,0x2c,0x33,0x29,0x5d,0x2c,0x31,0x36,0x55,0x29,0x3b,0x0a,0x78,0x2e,0x73,0x31,0x20,0x5e,0x3d,0x20,0x6b,0x2e,0x73,0x31,0x3b,0x0a,0x6b,
0x2e,0x73,0x32,0x20,0x5e,0x3d,0x20,0x41,0x45,0x53,0x30,0x5b,0x42,0x59,0x54,0x45,0x28,0x78,0x2e,0x73,0x32,0x2c,0x30,0x29,0x5d,0x5e,0x41,0x45,0x53,0x31,0x5b,0x42,
0x59,0x54,0x45,0x28,0x78,0x2e,0x73,0x33,0x2c,0x31,0x29,0x5d,0x5e,0x72,0x6f,0x74,0x61,0x74,0x65,0x28,0x41,0x45,0x53,0x30,0x5b,0x42,0x59,0x54,0x45,0x28,0x78,0x2e,
0x73,0x30,0x2c,0x32,0x29,0x5d,0x5e,0x41,0x45,0x53,0x31,0x5b,0x42,0x59,0x54,0x45,0x28,0x78,0x2e,0x73,0x31,0x2c,0x33,0x29,0x5d,0x2c,0x31,0x36,0x55,0x29,0x3b,0x0a,
0x78,0x2e,0x73,0x32,0x20,0x5e,0x3d,0x20,0x6b,0x2e,0x73,0x32,0x3b,0x0a,0x6b,0x2e,0x73,0x33,0x20,0x5e,0x3d,0x20,0x41,0x45,0x53,0x30,0x5b,0x42,0x59,0x54,0x45,0x28,
0x78,0x2e,0x73,0x33,0x2c,0x30,0x29,0x5d,0x5e,0x41,0x45,0x53,0x31,0x5b,0x42,0x59,0x54,0x45,0x28,0x78,0x2e,0x73,0x30,0x2c,0x31,0x29,0x5d,0x5e,0x72,0x6f,0x74,0x61,
0x74,0x65,0x28,0x41,0x45,0x53,0x30,0x5b,0x42,0x59,0x54,0x45,0x28,0x78,0x2e,0x73,0x31,0x2c,0x32,0x29,0x5d,0x5e,0x41,0x45,0x53,0x31,0x5b,0x42,0x59,0x54,0x45,0x28,
0x78,0x2e,0x73,0x32,0x2c,0x33,0x29,0x5d,0x2c,0x31,0x36,0x55,0x29,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6b,0x3b,0x0a,0x7d,0x0a,0x23,0x65,0x6e,0x64,0x69,
0x66,0x0a,0x75,0x69,0x6e,0x74,0x34,0x20,0x41,0x45,0x53,0x5f,0x52,0x6f,0x75,0x6e,0x64,0x28,0x63,0x6f,0x6e,0x73,0x74,0x20,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,
0x75,0x69,0x6e,0x74,0x20,0x2a,0x41,0x45,0x53,0x30,0x2c,0x63,0x6f,0x6e,0x73,0x74,0x20,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x20,0x2a,0x41,
0x45,0x53,0x31,0x2c,0x63,0x6f,0x6e,0x73,0x74,0x20,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x20,0x2a,0x41,0x45,0x53,0x32,0x2c,0x63,0x6f,0x6e,
0x73,0x74,0x20,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x20,0x2a,0x41,0x45,0x53,0x33,0x2c,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,
0x34,0x20,0x58,0x2c,0x75,0x69,0x6e,0x74,0x34,0x20,0x6b,0x65,0x79,0x29,0x0a,0x7b,0x0a,0x6b,0x65,0x79,0x2e,0x73,0x30,0x20,0x5e,0x3d,0x20,0x41,0x45,0x53,0x30,0x5b,
0x42,0x59,0x54,0x45,0x28,0x58,0x2e,0x73,0x30,0x2c,0x30,0x29,0x5d,0x5e,0x41,0x45,0x53,0x31,0x5b,0x42,0x59,0x54,0x45,0x28,0x58,0x2e,0x73,0x31,0x2c,0x31,0x29,0x5d,
0x5e,0x41,0x45,0x53,0x32,0x5b,0x42,0x59,0x54,0x45,0x28,0x58,0x2e,0x73,0x32,0x2c,0x32,0x29,0x5d,0x5e,0x41,0x45,0x53,0x33,0x5b,0x42,0x59,0x54,0x45,0x28,0x58,0x2e,
0x73,0x33,0x2c,0x33,0x29,0x5d,0x3b,0x0a,0x6b,0x65,0x79,0x2e,0x73,0x31,0x20,0x5e,0x3d,0x20,0x41,0x45,0x53,0x30,0x5b,0x42,0x59,0x54,0x45,0x28,0x58,0x2e,0x73,0x31,
0x2c,0x30,0x29,0x5d,0x5e,0x41,0x45,0x53,0x31,0x5b,0x42,0x59,0x54,0x45,0x28,0x58,0x2e,0x73,0x32,0x2c,0x31,0x29,0x5d,0x5e,0x41,0x45,0x53,0x32,0x5b,0x42,0x59,0x54,
0x45,0x28,0x58,0x2e,0x73,0x33,0x2c,0x32,0x29,0x5d,0x5e,0x41,0x45,0x53,0x33,0x5b,0x42,0x59,0x54,0x45,0x28,0x58,0x2e,0x73,0x30,0x2c,0x33,0x29,0x5d,0x3b,0x0a,0x6b,
0x65,0x79,0x2e,0x73,0x32,0x20,0x5e,0x3d,0x20,0x41,0x45,0x53,0x30,0x5b,0x42,0x59,0x54,0x45,0x28,0x58,0x2e,0x73,0x32,0x2c,0x30,0x29,0x5d,0x5e,0x41,0x45,0x53,0x31,
0x5b,0x42,0x59,0x54,0x45,0x28,0x58,0x2e,0x73,0x33,0x2c,0x31,0x29,0x5d,0x5e,0x41,0x45,0x53,0x32,0x5b,0x42,0x59,0x54,0x45,0x28,0x58,0x2e,0x73,0x30,0x2c,0x32,0x29,
0x5d,0x5e,0x41,0x45,0x53,0x33,0x5b,0x42,0x59,0x54,0x45,0x28,0x58,0x2e,0x73,0x31,0x2c,0x33,0x29,0x5d,0x3b,0x0a,0x6b,0x65,0x79,0x2e,0x73,0x33,0x20,0x5e,0x3d,0x20,
0x41,0x45,0x53,0x30,0x5b,0x42,0x59,0x54,0x45,0x28,0x58,0x2e,0x73,0x33,0x2c,0x30,0x29,0x5d,0x5e,0x41,0x45,0x53,0x31,0x5b,0x42,0x59,0x54,0x45,0x28,0x58,0x2e,0x73,
0x30,0x2c,0x31,0x29,0x5d,0x5e,0x41,0x45,0x53,0x32,0x5b,0x42,0x59,0x54,0x45,0x28,0x58,0x2e,0x73,0x31,0x2c,0x32,0x29,0x5d,0x5e,0x41,0x45,0x53,0x33,0x5b,0x42,0x59,
0x54,0x45,0x28,0x58,0x2e,0x73,0x32,0x2c,0x33,0x29,0x5d,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6b,0x65,0x79,0x3b,0x0a,0x7d,0x0a,0x75,0x69,0x6e,0x74,0x34,
0x20,0x41,0x45,0x53,0x5f,0x52,0x6f,0x75,0x6e,0x64,0x5f,0x54,0x77,0x6f,0x5f,0x54,0x61,0x62,0x6c,0x65,0x73,0x28,0x63,0x6f,0x6e,0x73,0x74,0x20,0x5f,0x5f,0x6c,0x6f,
0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x20,0x2a,0x41,0x45,0x53,0x30,0x2c,0x63,0x6f,0x6e,0x73,0x74,0x20,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,
0x74,0x20,0x2a,0x41,0x45,0x53,0x31,0x2c,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x34,0x20,0x58,0x2c,0x75,0x69,0x6e,0x74,0x34,0x20,0x6b,0x65,0x79,0x29,
0x0a,0x7b,0x0a,0x6b,0x65,0x79,0x2e,0x73,0x30,0x20,0x5e,0x3d,0x20,0x41,0x45,0x53,0x30,0x5b,0x42,0x59,0x54,0x45,0x28,0x58,0x2e,0x73,0x30,0x2c,0x30,0x29,0x5d,0x5e,
0x41,0x45,0x53,0x31,0x5b,0x42,0x59,0x54,0x45,0x28,0x58,0x2e,0x73,0x31,0x2c,0x31,0x29,0x5d,0x5e,0x72,0x6f,0x74,0x61,0x74,0x65,0x28,0x41,0x45,0x53,0x30,0x5b,0x42,
0x59,0x54,0x45,0x28,0x58,0x2e,0x73,0x32,0x2c,0x32,0x29,0x5d,0x5e,0x41,0x45,0x53,0x31,0x5b,0x42,0x59,0x54,0x45,0x28,0x58,0x2e,0x73,0x33,0x2c,0x33,0x29,0x5d,0x2c,
0x31,0x36,0x55,0x29,0x3b,0x0a,0x6b,0x65,0x79,0x2e,0x73,0x31,0x20,0x5e,0x3d,0x20,0x41,0x45,0x53,0x30,0x5b,0x42,0x59,0x54,0x45,0x28,0x58,0x2e,0x73,0x31,0x2c,0x30,
0x29,0x5d,0x5e,0x41,0x45,0x53,0x31,0x5b,0x42,0x59,0x54,0x45,0x28,0x58,0x2e,0x73,0x32,0x2c,0x31,0x29,0x5d,0x5e,0x72,0x6f,0x74,0x61,0x74,0x65,0x28,0x41,0x45,0x53,
0x30,0x5b,0x42,0x59,0x54,0x45,0x28,0x58,0x2e,0x73,0x33,0x2c,0x32,0x29,0x5d,0x5e,0x41,0x45,0x53,0x31,0x5b,0x42,0x59,0x54,0x45,0x28,0x58,0x2e,0x73,0x30,0x2c,0x33,
0x29,0x5d,0x2c,0x31,0x36,0x55,0x29,0x3b,0x0a,0x6b,0x65,0x79,0x2e,0x73,0x32,0x20,0x5e,0x3d,0x20,0x41,0x45,0x53,0x30,0x5b,0x42,0x59,0x54,0x45,0x28,0x58,0x2e,0x73,
0x32,0x2c,0x30,0x29,0x5d,0x5e,0x41,0x45,0x53,0x31,0x5b,0x42,0x59,0x54,0x45,0x28,0x58,0x2e,0x73,0x33,0x2c,0x31,0x29,0x5d,0x5e,0x72,0x6f,0x74,0x61,0x74,0x65,0x28,
0x41,0x45,0x53,0x30,0x5b,0x42,0x59,0x54,0x45,0x28,0x58,0x2e,0x73,0x30,0x2c,0x32,0x29,0x5d,0x5e,0x41,0x45,0x53,0x31,0x5b,0x42,0x59,0x54,0x45,0x28,0x58,0x2e,0x73,
0x31,0x2c,0x33,0x29,0x5d,0x2c,0x31,0x36,0x55,0x29,0x3b,0x0a,0x6b,0x65,0x79,0x2e,0x73,0x33,0x20,0x5e,0x3d,0x20,0x41,0x45,0x53,0x30,0x5b,0x42,0x59,0x54,0x45,0x28,
0x58,0x2e,0x73,0x33,0x2c,0x30,0x29,0x5d,0x5e,0x41,0x45,0x53,0x31,0x5b,0x42,0x59,0x54,0x45,0x28,0x58,0x2e,0x73,0x30,0x2c,0x31,0x29,0x5d,0x5e,0x72,0x6f,0x74,0x61,
0x74,0x65,0x28,0x41,0x45,0x53,0x30,0x5b,0x42,0x59,0x54,0x45,0x28,0x58,0x2e,0x73,0x31,0x2c,0x32,0x29,0x5d,0x5e,0x41,0x45,0x53,0x31,0x5b,0x42,0x59,0x54,0x45,0x28,
0x58,0x2e,0x73,0x32,0x2c,0x33,0x29,0x5d,0x2c,0x31,0x36,0x55,0x29,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6b,0x65,0x79,0x3b,0x0a,0x7d,0x0a,0x53,0x54,0x41,
0x54,0x49,0x43,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x75,0x63,0x68,0x61,0x72,0x20,0x72,0x63,0x6f,0x6e,0x5b,
0x38,0x5d,0x3d,0x7b,0x20,0x30,0x78,0x38,0x64,0x2c,0x30,0x78,0x30,0x31,0x2c,0x30,0x78,0x30,0x32,0x2c,0x30,0x78,0x30,0x34,0x2c,0x30,0x78,0x30,0x38,0x2c,0x30,0x78,
0x31,0x30,0x2c,0x30,0x78,0x32,0x30,0x2c,0x30,0x78,0x34,0x30,0x20,0x7d,0x3b,0x0a,0x53,0x54,0x41,0x54,0x49,0x43,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x5f,0x5f,0x63,
0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x75,0x63,0x68,0x61,0x72,0x20,0x73,0x62,0x6f,0x78,0x5b,0x32,0x35,0x36,0x5d,0x20,0x3d,0x0a,0x7b,0x0a,0x30,0x78,0x36,0x33,
0x2c,0x30,0x78,0x37,0x43,0x2c,0x30,0x78,0x37,0x37,0x2c,0x30,0x78,0x37,0x42,0x2c,0x30,0x78,0x46,0x32,0x2c,0x30,0x78,0x36,0x42,0x2c,0x30,0x78,0x36,0x46,0x2c,0x30,
0x78,0x43,0x35,0x2c,0x30,0x78,0x33,0x30,0x2c,0x30,0x78,0x30,0x31,0x2c,0x30,0x78,0x36,0x37,0x2c,0x30,0x78,0x32,0x42,0x2c,0x30,0x78,0x46,0x45,0x2c,0x30,0x78,0x44,
0x37,0x2c,0x30,0x78,0x41,0x42,0x2c,0x30,0x78,0x37,0x36,0x2c,0x0a,0x30,0x78,0x43,0x41,0x2c,0x30,0x78,0x38,0x32,0x2c,0x30,0x78,0x43,0x39,0x2c,0x30,0x78,0x37,0x44,
0x2c,0x30,0x78,0x46,0x41,0x2c,0x30,0x78,0x35,0x39,0x2c,0x30,0x78,0x34,0x37,0x2c,0x30,0x78,0x46,0x30,0x2c,0x30,0x78,0x41,0x44,0x2c,0x30,0x78,0x44,0x34,0x2c,0x30,
0x78,0x41,0x32,0x2c,0x30,0x78,0x41,0x46,0x2c,0x30,0x78,0x39,0x43,0x2c,0x30,0x78,0x41,0x34,0x2c,0x30,0x78,0x37,0x32,0x2c,0x30,0x78,0x43,0x30,0x2c,0x0a,0x30,0x78,
0x42,0x37,0x2c,0x30,0x78,0x46,0x44,0x2c,0x30,0x78,0x39,0x33,0x2c,0x30,0x78,0x32,0x36,0x2c,0x30,0x78,0x33,0x36,0x2c,0x30,0x78,0x33,0x46,0x2c,0x30,0x78,0x46,0x37,
0x2c,0x30,0x78,0x43,0x43,0x2c,0x30,0x78,0x33,0x34,0x2c,0x30,0x78,0x41,0x35,0x2c,0x30,0x78,0x45,0x35,0x2c,0x30,0x78,0x46,0x31,0x2c,0x30,0x78,0x37,0x31,0x2c,0x30,
0x78,0x44,0x38,0x2c,0x30,0x78,0x33,0x31,0x2c,0x30,0x78,0x31,0x35,0x2c,0x0a,0x30,0x78,0x30,0x34,0x2c,0x30,0x78,0x43,0x37,0x2c,0x30,0x78,0x32,0x33,0x2c,0x30,0x78,
0x43,0x33,0x2c,0x30,0x78,0x31,0x38,0x2c,0x30,0x78,0x39,0x36,0x2c,0x30,0x78,0x30,0x35,0x2c,0x30,0x78,0x39,0x41,0x2c,0x30,0x78,0x30,0x37,0x2c,0x30,0x78,0x31,0x32,
0x2c,0x30,0x78,0x38,0x30,0x2c,0x30,0x78,0x45,0x32,0x2c,0x30,0x78,0x45,0x42,0x2c,0x30,0x78,0x32,0x37,0x2c,0x30,0x78,0x42,0x32,0x2c,0x30,0x78,0x37,0x35,0x2c,0x0a,
0x30,0x78,0x30,0x39,0x2c,0x30,0x78,0x38,0x33,0x2c,0x30,0x78,0x32,0x43,0x2c,0x30,0x78,0x31,0x41,0x2c,0x30,0x78,0x31,0x42,0x2c,0x30,0x78,0x36,0x45,0x2c,0x30,0x78,
0x35,0x41,0x2c,0x30,0x78,0x41,0x30,0x2c,0x30,0x78,0x35,0x32,0x2c,0x30,0x78,0x33,0x42,0x2c,0x30,0x78,0x44,0x36,0x2c,0x30,0x78,0x42,0x33,0x2c,0x30,0x78,0x32,0x39,
0x2c,0x30,0x78,0x45,0x33,0x2c,0x30,0x78,0x32,0x46,0x2c,0x30,0x78,0x38,0x34,0x2c,0x0a,0x30,0x78,0x35,0x33,0x2c,0x30,0x78,0x44,0x31,0x2c,0x30,0x78,0x30,0x30,0x2c,
0x30,0x78,0x45,0x44,0x2c,0x30,0x78,0x32,0x30,0x2c,0x30,0x78,0x46,0x43,0x2c,0x30,0x78,0x42,0x31,0x2c,0x30,0x78,0x35,0x42,0x2c,0x30,0x78,0x36,0x41,0x2c,0x30,0x78,
0x43,0x42,0x2c,0x30,0x78,0x42,0x45,0x2c,0x30,0x78,0x33,0x39,0x2c,0x30,0x78,0x34,0x41,0x2c,0x30,0x78,0x34,0x43,0x2c,0x30,0x78,0x35,0x38,0x2c,0x30,0x78,0x43,0x46,
0x2c,0x0a,0x30,0x78,0x44,0x30,0x2c,0x30,0x78,0x45,0x46,0x2c,0x30,0x78,0x41,0x41,0x2c,0x30,0x78,0x46,0x42,0x2c,0x30,0x78,0x34,0x33,0x2c,0x30,0x78,0x34,0x44,0x2c,
0x30,0x78,0x33,0x33,0x2c,0x30,0x78,0x38,0x35,0x2c,0x30,0x78,0x34,0x35,0x2c,0x30,0x78,0x46,0x39,0x2c,0x30,0x78,0x30,0x32,0x2c,0x30,0x78,0x37,0x46,0x2c,0x30,0x78,
0x35,0x30,0x2c,0x30,0x78,0x33,0x43,0x2c,0x30,0x78,0x39,0x46,0x2c,0x30,0x78,0x41,0x38,0x2c,0x0a,0x30,0x78,0x35,0x31,0x2c,0x30,0x78,0x41,0x33,0x2c,0x30,0x78,0x34,
0x30,0x2c,0x30,0x78,0x38,0x46,0x2c,0x30,0x78,0x39,0x32,0x2c,0x30,0x78,0x39,0x44,0x2c,0x30,0x78,0x33,0x38,0x2c,0x30,0x78,0x46,0x35,0x2c,0x30,0x78,0x42,0x43,0x2c,
0x30,0x78,0x42,0x36,0x2c,0x30,0x78,0x44,0x41,0x2c,0x30,0x78,0x32,0x31,0x2c,0x30,0x78,0x31,0x30,0x2c,0x30,0x78,0x46,0x46,0x2c,0x30,0x78,0x46,0x33,0x2c,0x30,0x78,
0x44,0x32,0x2c,0x0a,0x30,0x78,0x43,0x44,0x2c,0x30,0x78,0x30,0x43,0x2c,0x30,0x78,0x31,0x33,0x2c,0x30,0x78,0x45,0x43,0x2c,0x30,0x78,0x35,0x46,0x2c,0x30,0x78,0x39,
0x37,0x2c,0x30,0x78,0x34,0x34,0x2c,0x30,0x78,0x31,0x37,0x2c,0x30,0x78,0x43,0x34,0x2c,0x30,0x78,0x41,0x37,0x2c,0x30,0x78,0x37,0x45,0x2c,0x30,0x78,0x33,0x44,0x2c,
0x30,0x78,0x36,0x34,0x2c,0x30,0x78,0x35,0x44,0x2c,0x30,0x78,0x31,0x39,0x2c,0x30,0x78,0x37,0x33,0x2c,0x0a,0x30,0x78,0x36,0x30,0x2c,0x30,0x78,0x38,0x31,0x2c,0x30,
0x78,0x34,0x46,0x2c,0x30,0x78,0x44,0x43,0x2c,0x30,0x78,0x32,0x32,0x2c,0x30,0x78,0x32,0x41,0x2c,0x30,0x78,0x39,0x30,0x2c,0x30,0x78,0x38,0x38,0x2c,0x30,0x78,0x34,
0x36,0x2c,0x30,0x78,0x45,0x45,0x2c,0x30,0x78,0x42,0x38,0x2c,0x30,0x78,0x31,0x34,0x2c,0x30,0x78,0x44,0x45,0x2c,0x30,0x78,0x35,0x45,0x2c,0x30,0x78,0x30,0x42,0x2c,
0x30,0x78,0x44,0x42,0x2c,0x0a,0x30,0x78,0x45,0x30,0x2c,0x30,0x78,0x33,0x32,0x2c,0x30,0x78,0x33,0x41,0x2c,0x30,0x78,0x30,0x41,0x2c,0x30,0x78,0x34,0x39,0x2c,0x30,
0x78,0x30,0x36,0x2c,0x30,0x78,0x32,0x34,0x2c,0x30,0x78,0x35,0x43,0x2c,0x30,0x78,0x43,0x32,0x2c,0x30,0x78,0x44,0x33,0x2c,0x30,0x78,0x41,0x43,0x2c,0x30,0x78,0x36,
0x32,0x2c,0x30,0x78,0x39,0x31,0x2c,0x30,0x78,0x39,0x35,0x2c,0x30,0x78,0x45,0x34,0x2c,0x30,0x78,0x37,0x39,0x2c,0x0a,0x30,0x78,0x45,0x37,0x2c,0x30,0x78,0x43,0x38,
0x2c,0x30,0x78,0x33,0x37,0x2c,0x30,0x78,0x36,0x44,0x2c,0x30,0x78,0x38,0x44,0x2c,0x30,0x78,0x44,0x35,0x2c,0x30,0x78,0x34,0x45,0x2c,0x30,0x78,0x41,0x39,0x2c,0x30,
0x78,0x36,0x43,0x2c,0x30,0x78,0x35,0x36,0x2c,0x30,0x78,0x46,0x34,0x2c,0x30,0x78,0x45,0x41,0x2c,0x30,0x78,0x36,0x35,0x2c,0x30,0x78,0x37,0x41,0x2c,0x30,0x78,0x41,
0x45,0x2c,0x30,0x78,0x30,0x38,0x2c,0x0a,0x30,0x78,0x42,0x41,0x2c,0x30,0x78,0x37,0x38,0x2c,0x30,0x78,0x32,0x35,0x2c,0x30,0x78,0x32,0x45,0x2c,0x30,0x78,0x31,0x43,
0x2c,0x30,0x78,0x41,0x36,0x2c,0x30,0x78,0x42,0x34,0x2c,0x30,0x78,0x43,0x36,0x2c,0x30,0x78,0x45,0x38,0x2c,0x30,0x78,0x44,0x44,0x2c,0x30,0x78,0x37,0x34,0x2c,0x30,
0x78,0x31,0x46,0x2c,0x30,0x78,0x34,0x42,0x2c,0x30,0x78,0x42,0x44,0x2c,0x30,0x78,0x38,0x42,0x2c,0x30,0x78,0x38,0x41,0x2c,0x0a,0x30,0x78,0x37,0x30,0x2c,0x30,0x78,
0x33,0x45,0x2c,0x30,0x78,0x42,0x35,0x2c,0x30,0x78,0x36,0x36,0x2c,0x30,0x78,0x34,0x38,0x2c,0x30,0x78,0x30,0x33,0x2c,0x30,0x78,0x46,0x36,0x2c,0x30,0x78,0x30,0x45,
0x2c,0x30,0x78,0x36,0x31,0x2c,0x30,0x78,0x33,0x35,0x2c,0x30,0x78,0x35,0x37,0x2c,0x30,0x78,0x42,0x39,0x2c,0x30,0x78,0x38,0x36,0x2c,0x30,0x78,0x43,0x31,0x2c,0x30,
0x78,0x31,0x44,0x2c,0x30,0x78,0x39,0x45,0x2c,0x0a,0x30,0x78,0x45,0x31,0x2c,0x30,0x78,0x46,0x38,0x2c,0x30,0x78,0x39,0x38,0x2c,0x30,0x78,0x31,0x31,0x2c,0x30,0x78,
0x36,0x39,0x2c,0x30,0x78,0x44,0x39,0x2c,0x30,0x78,0x38,0x45,0x2c,0x30,0x78,0x39,0x34,0x2c,0x30,0x78,0x39,0x42,0x2c,0x30,0x78,0x31,0x45,0x2c,0x30,0x78,0x38,0x37,
0x2c,0x30,0x78,0x45,0x39,0x2c,0x30,0x78,0x43,0x45,0x2c,0x30,0x78,0x35,0x35,0x2c,0x30,0x78,0x32,0x38,0x2c,0x30,0x78,0x44,0x46,0x2c,0x0a,0x30,0x78,0x38,0x43,0x2c,
0x30,0x78,0x41,0x31,0x2c,0x30,0x78,0x38,0x39,0x2c,0x30,0x78,0x30,0x44,0x2c,0x30,0x78,0x42,0x46,0x2c,0x30,0x78,0x45,0x36,0x2c,0x30,0x78,0x34,0x32,0x2c,0x30,0x78,
0x36,0x38,0x2c,0x30,0x78,0x34,0x31,0x2c,0x30,0x78,0x39,0x39,0x2c,0x30,0x78,0x32,0x44,0x2c,0x30,0x78,0x30,0x46,0x2c,0x30,0x78,0x42,0x30,0x2c,0x30,0x78,0x35,0x34,
0x2c,0x30,0x78,0x42,0x42,0x2c,0x30,0x78,0x31,0x36,0x0a,0x7d,0x3b,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x75,0x62,0x57,0x6f,0x72,0x64,0x28,0x69,0x6e,
0x77,0x29,0x20,0x28,0x28,0x73,0x62,0x6f,0x78,0x5b,0x42,0x59,0x54,0x45,0x28,0x69,0x6e,0x77,0x2c,0x20,0x33,0x29,0x5d,0x20,0x3c,0x3c,0x20,0x32,0x34,0x29,0x20,0x7c,
0x20,0x28,0x73,0x62,0x6f,0x78,0x5b,0x42,0x59,0x54,0x45,0x28,0x69,0x6e,0x77,0x2c,0x20,0x32,0x29,0x5d,0x20,0x3c,0x3c,0x20,0x31,0x36,0x29,0x20,0x7c,0x20,0x28,0x73,
0x62,0x6f,0x78,0x5b,0x42,0x59,0x54,0x45,0x28,0x69,0x6e,0x77,0x2c,0x20,0x31,0x29,0x5d,0x20,0x3c,0x3c,0x20,0x38,0x29,0x20,0x7c,0x20,0x73,0x62,0x6f,0x78,0x5b,0x42,
0x59,0x54,0x45,0x28,0x69,0x6e,0x77,0x2c,0x20,0x30,0x29,0x5d,0x29,0x0a,0x76,0x6f,0x69,0x64,0x20,0x41,0x45,0x53,0x45,0x78,0x70,0x61,0x6e,0x64,0x4b,0x65,0x79,0x32,
0x35,0x36,0x28,0x75,0x69,0x6e,0x74,0x20,0x2a,0x6b,0x65,0x79,0x62,0x75,0x66,0x29,0x0a,0x7b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x20,0x63,0x3d,0x38,
0x2c,0x69,0x3d,0x31,0x3b,0x20,0x63,0x3c,0x34,0x30,0x3b,0x20,0x2b,0x2b,0x63,0x29,0x20,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x20,0x74,0x3d,0x28,0x28,0x21,0x28,0x63,0x26,
0x37,0x29,0x29,0x7c,0x7c,0x28,0x28,0x63,0x26,0x37,0x29,0x3d,0x3d,0x34,0x29,0x29,0x3f,0x53,0x75,0x62,0x57,0x6f,0x72,0x64,0x28,0x6b,0x65,0x79,0x62,0x75,0x66,0x5b,
0x63,0x2d,0x31,0x5d,0x29,0x3a,0x6b,0x65,0x79,0x62,0x75,0x66,0x5b,0x63,0x2d,0x31,0x5d,0x3b,0x0a,0x6b,0x65,0x79,0x62,0x75,0x66,0x5b,0x63,0x5d,0x3d,0x6b,0x65,0x79,
0x62,0x75,0x66,0x5b,0x63,0x2d,0x38,0x5d,0x5e,0x28,0x28,0x21,0x28,0x63,0x26,0x37,0x29,0x29,0x3f,0x72,0x6f,0x74,0x61,0x74,0x65,0x28,0x74,0x2c,0x32,0x34,0x55,0x29,
0x5e,0x61,0x73,0x5f,0x75,0x69,0x6e,0x74,0x28,0x28,0x75,0x63,0x68,0x61,0x72,0x34,0x29,0x28,0x72,0x63,0x6f,0x6e,0x5b,0x69,0x2b,0x2b,0x5d,0x2c,0x30,0x55,0x2c,0x30,
0x55,0x2c,0x30,0x55,0x29,0x29,0x3a,0x74,0x29,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x23,0x69,0x66,0x6e,0x64,0x65,0x66,0x20,0x58,0x4d,
0x52,0x49,0x47,0x5f,0x4b,0x45,0x43,0x43,0x41,0x4b,0x5f,0x43,0x4c,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x58,0x4d,0x52,0x49,0x47,0x5f,0x4b,0x45,0x43,0x43,
0x41,0x4b,0x5f,0x43,0x4c,0x0a,0x53,0x54,0x41,0x54,0x49,0x43,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x75,0x6c,
0x6f,0x6e,0x67,0x20,0x6b,0x65,0x63,0x63,0x61,0x6b,0x66,0x5f,0x72,0x6e,0x64,0x63,0x5b,0x32,0x34,0x5d,0x20,0x3d,0x0a,0x7b,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x32,0x2c,0x30,
0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x61,0x2c,0x0a,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,
0x30,0x38,0x30,0x30,0x30,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x62,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x2c,0x0a,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x38,0x31,0x2c,
0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x39,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x38,0x61,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x38,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x30,0x39,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x61,0x2c,
0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x38,0x62,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x30,0x38,0x62,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x39,0x2c,0x0a,0x30,0x78,0x38,0x30,0x30,
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x33,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x32,
0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x38,0x30,0x30,0x61,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x61,0x2c,0x30,0x78,0x38,0x30,0x30,
0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x38,0x31,0x2c,0x0a,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,
0x30,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,
0x30,0x30,0x30,0x38,0x30,0x30,0x38,0x0a,0x7d,0x3b,0x0a,0x53,0x54,0x41,0x54,0x49,0x43,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,
0x6e,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6b,0x65,0x63,0x63,0x61,0x6b,0x66,0x5f,0x72,0x6f,0x74,0x63,0x5b,0x32,0x34,0x5d,0x20,0x3d,0x0a,0x7b,0x0a,0x31,0x2c,0x33,
0x2c,0x36,0x2c,0x31,0x30,0x2c,0x31,0x35,0x2c,0x32,0x31,0x2c,0x32,0x38,0x2c,0x33,0x36,0x2c,0x34,0x35,0x2c,0x35,0x35,0x2c,0x32,0x2c,0x31,0x34,0x2c,0x0a,0x32,0x37,
0x2c,0x34,0x31,0x2c,0x35,0x36,0x2c,0x38,0x2c,0x32,0x35,0x2c,0x34,0x33,0x2c,0x36,0x32,0x2c,0x31,0x38,0x2c,0x33,0x39,0x2c,0x36,0x31,0x2c,0x32,0x30,0x2c,0x34,0x34,
0x0a,0x7d,0x3b,0x0a,0x53,0x54,0x41,0x54,0x49,0x43,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x75,0x69,0x6e,0x74,
0x20,0x6b,0x65,0x63,0x63,0x61,0x6b,0x66,0x5f,0x70,0x69,0x6c,0x6e,0x5b,0x32,0x34,0x5d,0x20,0x3d,0x0a,0x7b,0x0a,0x31,0x30,0x2c,0x37,0x2c,0x31,0x31,0x2c,0x31,0x37,
0x2c,0x31,0x38,0x2c,0x33,0x2c,0x35,0x2c,0x31,0x36,0x2c,0x38,0x2c,0x32,0x31,0x2c,0x32,0x34,0x2c,0x34,0x2c,0x0a,0x31,0x35,0x2c,0x32,0x33,0x2c,0x31,0x39,0x2c,0x31,
0x33,0x2c,0x31,0x32,0x2c,0x32,0x2c,0x32,0x30,0x2c,0x31,0x34,0x2c,0x32,0x32,0x2c,0x39,0x2c,0x36,0x2c,0x31,0x0a,0x7d,0x3b,0x0a,0x76,0x6f,0x69,0x64,0x20,0x6b,0x65,
0x63,0x63,0x61,0x6b,0x66,0x31,0x36,0x30,0x30,0x5f,0x31,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x2a,0x73,0x74,0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x74,0x20,0x69,0x2c,0x72,
0x6f,0x75,0x6e,0x64,0x3b,0x0a,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x74,0x2c,0x62,0x63,0x5b,0x35,0x5d,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,
0x6f,0x6c,0x6c,0x20,0x31,0x0a,0x66,0x6f,0x72,0x20,0x28,0x72,0x6f,0x75,0x6e,0x64,0x3d,0x30,0x3b,0x20,0x72,0x6f,0x75,0x6e,0x64,0x3c,0x32,0x34,0x3b,0x20,0x2b,0x2b,
0x72,0x6f,0x75,0x6e,0x64,0x29,0x20,0x7b,0x0a,0x62,0x63,0x5b,0x30,0x5d,0x3d,0x73,0x74,0x5b,0x30,0x5d,0x5e,0x73,0x74,0x5b,0x35,0x5d,0x5e,0x73,0x74,0x5b,0x31,0x30,
0x5d,0x5e,0x73,0x74,0x5b,0x31,0x35,0x5d,0x5e,0x73,0x74,0x5b,0x32,0x30,0x5d,0x3b,0x0a,0x62,0x63,0x5b,0x31,0x5d,0x3d,0x73,0x74,0x5b,0x31,0x5d,0x5e,0x73,0x74,0x5b,
0x36,0x5d,0x5e,0x73,0x74,0x5b,0x31,0x31,0x5d,0x5e,0x73,0x74,0x5b,0x31,0x36,0x5d,0x5e,0x73,0x74,0x5b,0x32,0x31,0x5d,0x3b,0x0a,0x62,0x63,0x5b,0x32,0x5d,0x3d,0x73,
0x74,0x5b,0x32,0x5d,0x5e,0x73,0x74,0x5b,0x37,0x5d,0x5e,0x73,0x74,0x5b,0x31,0x32,0x5d,0x5e,0x73,0x74,0x5b,0x31,0x37,0x5d,0x5e,0x73,0x74,0x5b,0x32,0x32,0x5d,0x3b,
0x0a,0x62,0x63,0x5b,0x33,0x5d,0x3d,0x73,0x74,0x5b,0x33,0x5d,0x5e,0x73,0x74,0x5b,0x38,0x5d,0x5e,0x73,0x74,0x5b,0x31,0x33,0x5d,0x5e,0x73,0x74,0x5b,0x31,0x38,0x5d,
0x5e,0x73,0x74,0x5b,0x32,0x33,0x5d,0x3b,0x0a,0x62,0x63,0x5b,0x34,0x5d,0x3d,0x73,0x74,0x5b,0x34,0x5d,0x5e,0x73,0x74,0x5b,0x39,0x5d,0x5e,0x73,0x74,0x5b,0x31,0x34,
0x5d,0x5e,0x73,0x74,0x5b,0x31,0x39,0x5d,0x5e,0x73,0x74,0x5b,0x32,0x34,0x5d,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,
0x31,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x35,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x20,0x7b,0x0a,0x74,0x3d,0x62,0x63,0x5b,0x28,0x69,0x2b,
0x34,0x29,0x20,0x25,0x20,0x35,0x5d,0x5e,0x72,0x6f,0x74,0x61,0x74,0x65,0x28,0x62,0x63,0x5b,0x28,0x69,0x2b,0x31,0x29,0x20,0x25,0x20,0x35,0x5d,0x2c,0x31,0x55,0x4c,
0x29,0x3b,0x0a,0x73,0x74,0x5b,0x69,0x20,0x5d,0x20,0x5e,0x3d,0x20,0x74,0x3b,0x0a,0x73,0x74,0x5b,0x69,0x2b,0x35,0x5d,0x20,0x5e,0x3d,0x20,0x74,0x3b,0x0a,0x73,0x74,
0x5b,0x69,0x2b,0x31,0x30,0x5d,0x20,0x5e,0x3d,0x20,0x74,0x3b,0x0a,0x73,0x74,0x5b,0x69,0x2b,0x31,0x35,0x5d,0x20,0x5e,0x3d,0x20,0x74,0x3b,0x0a,0x73,0x74,0x5b,0x69,
0x2b,0x32,0x30,0x5d,0x20,0x5e,0x3d,0x20,0x74,0x3b,0x0a,0x7d,0x0a,0x74,0x3d,0x73,0x74,0x5b,0x31,0x5d,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,
0x72,0x6f,0x6c,0x6c,0x20,0x31,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x32,0x34,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x20,0x7b,0x0a,0x62,0x63,
0x5b,0x30,0x5d,0x3d,0x73,0x74,0x5b,0x6b,0x65,0x63,0x63,0x61,0x6b,0x66,0x5f,0x70,0x69,0x6c,0x6e,0x5b,0x69,0x5d,0x5d,0x3b,0x0a,0x73,0x74,0x5b,0x6b,0x65,0x63,0x63,
0x61,0x6b,0x66,0x5f,0x70,0x69,0x6c,0x6e,0x5b,0x69,0x5d,0x5d,0x3d,0x72,0x6f,0x74,0x61,0x74,0x65,0x28,0x74,0x2c,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x6b,0x65,0x63,
0x63,0x61,0x6b,0x66,0x5f,0x72,0x6f,0x74,0x63,0x5b,0x69,0x5d,0x29,0x3b,0x0a,0x74,0x3d,0x62,0x63,0x5b,0x30,0x5d,0x3b,0x0a,0x7d,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,
0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x31,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x32,0x35,0x3b,0x20,0x69,
0x2b,0x3d,0x35,0x29,0x20,0x7b,0x0a,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x74,0x6d,0x70,0x5b,0x35,0x5d,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,
0x6f,0x6c,0x6c,0x20,0x31,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x78,0x3d,0x30,0x3b,0x20,0x78,0x3c,0x35,0x3b,0x20,0x2b,0x2b,0x78,0x29,0x20,0x7b,0x0a,
0x74,0x6d,0x70,0x5b,0x78,0x5d,0x3d,0x62,0x69,0x74,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x74,0x5b,0x69,0x2b,0x78,0x5d,0x5e,0x73,0x74,0x5b,0x69,0x2b,0x28,0x28,
0x78,0x2b,0x32,0x29,0x20,0x25,0x20,0x35,0x29,0x5d,0x2c,0x73,0x74,0x5b,0x69,0x2b,0x78,0x5d,0x2c,0x73,0x74,0x5b,0x69,0x2b,0x28,0x28,0x78,0x2b,0x31,0x29,0x20,0x25,
0x20,0x35,0x29,0x5d,0x29,0x3b,0x0a,0x7d,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x31,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,
0x6e,0x74,0x20,0x78,0x3d,0x30,0x3b,0x20,0x78,0x3c,0x35,0x3b,0x20,0x2b,0x2b,0x78,0x29,0x20,0x7b,0x0a,0x73,0x74,0x5b,0x69,0x2b,0x78,0x5d,0x3d,0x74,0x6d,0x70,0x5b,
0x78,0x5d,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x73,0x74,0x5b,0x30,0x5d,0x20,0x5e,0x3d,0x20,0x6b,0x65,0x63,0x63,0x61,0x6b,0x66,0x5f,0x72,0x6e,0x64,0x63,0x5b,0x72,0x6f,
0x75,0x6e,0x64,0x5d,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x76,0x6f,0x69,0x64,0x20,0x6b,0x65,0x63,0x63,0x61,0x6b,0x66,0x31,0x36,0x30,0x30,0x5f,0x32,0x28,0x5f,0x5f,0x6c,
0x6f,0x63,0x61,0x6c,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x2a,0x73,0x74,0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x74,0x20,0x69,0x2c,0x72,0x6f,0x75,0x6e,0x64,0x3b,0x0a,0x75,
0x6c,0x6f,0x6e,0x67,0x20,0x74,0x2c,0x62,0x63,0x5b,0x35,0x5d,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x31,0x0a,0x66,
0x6f,0x72,0x20,0x28,0x72,0x6f,0x75,0x6e,0x64,0x3d,0x30,0x3b,0x20,0x72,0x6f,0x75,0x6e,0x64,0x3c,0x32,0x34,0x3b,0x20,0x2b,0x2b,0x72,0x6f,0x75,0x6e,0x64,0x29,0x20,
0x7b,0x0a,0x62,0x63,0x5b,0x30,0x5d,0x3d,0x73,0x74,0x5b,0x30,0x5d,0x5e,0x73,0x74,0x5b,0x35,0x5d,0x5e,0x73,0x74,0x5b,0x31,0x30,0x5d,0x5e,0x73,0x74,0x5b,0x31,0x35,
0x5d,0x5e,0x73,0x74,0x5b,0x32,0x30,0x5d,0x5e,0x72,0x6f,0x74,0x61,0x74,0x65,0x28,0x73,0x74,0x5b,0x32,0x5d,0x5e,0x73,0x74,0x5b,0x37,0x5d,0x5e,0x73,0x74,0x5b,0x31,
0x32,0x5d,0x5e,0x73,0x74,0x5b,0x31,0x37,0x5d,0x5e,0x73,0x74,0x5b,0x32,0x32,0x5d,0x2c,0x31,0x55,0x4c,0x29,0x3b,0x0a,0x62,0x63,0x5b,0x31,0x5d,0x3d,0x73,0x74,0x5b,
0x31,0x5d,0x5e,0x73,0x74,0x5b,0x36,0x5d,0x5e,0x73,0x74,0x5b,0x31,0x31,0x5d,0x5e,0x73,0x74,0x5b,0x31,0x36,0x5d,0x5e,0x73,0x74,0x5b,0x32,0x31,0x5d,0x5e,0x72,0x6f,
0x74,0x61,0x74,0x65,0x28,0x73,0x74,0x5b,0x33,0x5d,0x5e,0x73,0x74,0x5b,0x38,0x5d,0x5e,0x73,0x74,0x5b,0x31,0x33,0x5d,0x5e,0x73,0x74,0x5b,0x31,0x38,0x5d,0x5e,0x73,
0x74,0x5b,0x32,0x33,0x5d,0x2c,0x31,0x55,0x4c,0x29,0x3b,0x0a,0x62,0x63,0x5b,0x32,0x5d,0x3d,0x73,0x74,0x5b,0x32,0x5d,0x5e,0x73,0x74,0x5b,0x37,0x5d,0x5e,0x73,0x74,
0x5b,0x31,0x32,0x5d,0x5e,0x73,0x74,0x5b,0x31,0x37,0x5d,0x5e,0x73,0x74,0x5b,0x32,0x32,0x5d,0x5e,0x72,0x6f,0x74,0x61,0x74,0x65,0x28,0x73,0x74,0x5b,0x34,0x5d,0x5e,
0x73,0x74,0x5b,0x39,0x5d,0x5e,0x73,0x74,0x5b,0x31,0x34,0x5d,0x5e,0x73,0x74,0x5b,0x31,0x39,0x5d,0x5e,0x73,0x74,0x5b,0x32,0x34,0x5d,0x2c,0x31,0x55,0x4c,0x29,0x3b,
0x0a,0x62,0x63,0x5b,0x33,0x5d,0x3d,0x73,0x74,0x5b,0x33,0x5d,0x5e,0x73,0x74,0x5b,0x38,0x5d,0x5e,0x73,0x74,0x5b,0x31,0x33,0x5d,0x5e,0x73,0x74,0x5b,0x31,0x38,0x5d,
0x5e,0x73,0x74,0x5b,0x32,0x33,0x5d,0x5e,0x72,0x6f,0x74,0x61,0x74,0x65,0x28,0x73,0x74,0x5b,0x30,0x5d,0x5e,0x73,0x74,0x5b,0x35,0x5d,0x5e,0x73,0x74,0x5b,0x31,0x30,
0x5d,0x5e,0x73,0x74,0x5b,0x31,0x35,0x5d,0x5e,0x73,0x74,0x5b,0x32,0x30,0x5d,0x2c,0x31,0x55,0x4c,0x29,0x3b,0x0a,0x62,0x63,0x5b,0x34,0x5d,0x3d,0x73,0x74,0x5b,0x34,
0x5d,0x5e,0x73,0x74,0x5b,0x39,0x5d,0x5e,0x73,0x74,0x5b,0x31,0x34,0x5d,0x5e,0x73,0x74,0x5b,0x31,0x39,0x5d,0x5e,0x73,0x74,0x5b,0x32,0x34,0x5d,0x5e,0x72,0x6f,0x74,
0x61,0x74,0x65,0x28,0x73,0x74,0x5b,0x31,0x5d,0x5e,0x73,0x74,0x5b,0x36,0x5d,0x5e,0x73,0x74,0x5b,0x31,0x31,0x5d,0x5e,0x73,0x74,0x5b,0x31,0x36,0x5d,0x5e,0x73,0x74,
0x5b,0x32,0x31,0x5d,0x2c,0x31,0x55,0x4c,0x29,0x3b,0x0a,0x73,0x74,0x5b,0x30,0x5d,0x20,0x5e,0x3d,0x20,0x62,0x63,0x5b,0x34,0x5d,0x3b,0x0a,0x73,0x74,0x5b,0x35,0x5d,
0x20,0x5e,0x3d,0x20,0x62,0x63,0x5b,0x34,0x5d,0x3b,0x0a,0x73,0x74,0x5b,0x31,0x30,0x5d,0x20,0x5e,0x3d,0x20,0x62,0x63,0x5b,0x34,0x5d,0x3b,0x0a,0x73,0x74,0x5b,0x31,
0x35,0x5d,0x20,0x5e,0x3d,0x20,0x62,0x63,0x5b,0x34,0x5d,0x3b,0x0a,0x73,0x74,0x5b,0x32,0x30,0x5d,0x20,0x5e,0x3d,0x20,0x62,0x63,0x5b,0x34,0x5d,0x3b,0x0a,0x73,0x74,
0x5b,0x31,0x5d,0x20,0x5e,0x3d,0x20,0x62,0x63,0x5b,0x30,0x5d,0x3b,0x0a,0x73,0x74,0x5b,0x36,0x5d,0x20,0x5e,0x3d,0x20,0x62,0x63,0x5b,0x30,0x5d,0x3b,0x0a,0x73,0x74,
0x5b,0x31,0x31,0x5d,0x20,0x5e,0x3d,0x20,0x62,0x63,0x5b,0x30,0x5d,0x3b,0x0a,0x73,0x74,0x5b,0x31,0x36,0x5d,0x20,0x5e,0x3d,0x20,0x62,0x63,0x5b,0x30,0x5d,0x3b,0x0a,
0x73,0x74,0x5b,0x32,0x31,0x5d,0x20,0x5e,0x3d,0x20,0x62,0x63,0x5b,0x30,0x5d,0x3b,0x0a,0x73,0x74,0x5b,0x32,0x5d,0x20,0x5e,0x3d,0x20,0x62,0x63,0x5b,0x31,0x5d,0x3b,
0x0a,0x73,0x74,0x5b,0x37,0x5d,0x20,0x5e,0x3d,0x20,0x62,0x63,0x5b,0x31,0x5d,0x3b,0x0a,0x73,0x74,0x5b,0x31,0x32,0x5d,0x20,0x5e,0x3d,0x20,0x62,0x63,0x5b,0x31,0x5d,
0x3b,0x0a,0x73,0x74,0x5b,0x31,0x37,0x5d,0x20,0x5e,0x3d,0x20,0x62,0x63,0x5b,0x31,0x5d,0x3b,0x0a,0x73,0x74,0x5b,0x32,0x32,0x5d,0x20,0x5e,0x3d,0x20,0x62,0x63,0x5b,
0x31,0x5d,0x3b,0x0a,0x73,0x74,0x5b,0x33,0x5d,0x20,0x5e,0x3d,0x20,0x62,0x63,0x5b,0x32,0x5d,0x3b,0x0a,0x73,0x74,0x5b,0x38,0x5d,0x20,0x5e,0x3d,0x20,0x62,0x63,0x5b,
0x32,0x5d,0x3b,0x0a,0x73,0x74,0x5b,0x31,0x33,0x5d,0x20,0x5e,0x3d,0x20,0x62,0x63,0x5b,0x32,0x5d,0x3b,0x0a,0x73,0x74,0x5b,0x31,0x38,0x5d,0x20,0x5e,0x3d,0x20,0x62,
0x63,0x5b,0x32,0x5d,0x3b,0x0a,0x73,0x74,0x5b,0x32,0x33,0x5d,0x20,0x5e,0x3d,0x20,0x62,0x63,0x5b,0x32,0x5d,0x3b,0x0a,0x73,0x74,0x5b,0x34,0x5d,0x20,0x5e,0x3d,0x20,
0x62,0x63,0x5b,0x33,0x5d,0x3b,0x0a,0x73,0x74,0x5b,0x39,0x5d,0x20,0x5e,0x3d,0x20,0x62,0x63,0x5b,0x33,0x5d,0x3b,0x0a,0x73,0x74,0x5b,0x31,0x34,0x5d,0x20,0x5e,0x3d,
0x20,0x62,0x63,0x5b,0x33,0x5d,0x3b,0x0a,0x73,0x74,0x5b,0x31,0x39,0x5d,0x20,0x5e,0x3d,0x20,0x62,0x63,0x5b,0x33,0x5d,0x3b,0x0a,0x73,0x74,0x5b,0x32,0x34,0x5d,0x20,
0x5e,0x3d,0x20,0x62,0x63,0x5b,0x33,0x5d,0x3b,0x0a,0x74,0x3d,0x73,0x74,0x5b,0x31,0x5d,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,
0x6c,0x20,0x31,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x32,0x34,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x20,0x7b,0x0a,0x62,0x63,0x5b,0x30,0x5d,
0x3d,0x73,0x74,0x5b,0x6b,0x65,0x63,0x63,0x61,0x6b,0x66,0x5f,0x70,0x69,0x6c,0x6e,0x5b,0x69,0x5d,0x5d,0x3b,0x0a,0x73,0x74,0x5b,0x6b,0x65,0x63,0x63,0x61,0x6b,0x66,
0x5f,0x70,0x69,0x6c,0x6e,0x5b,0x69,0x5d,0x5d,0x3d,0x72,0x6f,0x74,0x61,0x74,0x65,0x28,0x74,0x2c,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x29,0x6b,0x65,0x63,0x63,0x61,0x6b,
0x66,0x5f,0x72,0x6f,0x74,0x63,0x5b,0x69,0x5d,0x29,0x3b,0x0a,0x74,0x3d,0x62,0x63,0x5b,0x30,0x5d,0x3b,0x0a,0x7d,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,
0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x31,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x32,0x35,0x3b,0x20,0x69,0x2b,0x3d,0x35,
0x29,0x20,0x7b,0x0a,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x74,0x6d,0x70,0x31,0x3d,0x73,0x74,0x5b,0x69,0x5d,0x2c,0x74,0x6d,0x70,0x32,0x3d,0x73,0x74,0x5b,0x69,0x2b,0x31,
0x5d,0x3b,0x0a,0x73,0x74,0x5b,0x69,0x5d,0x3d,0x62,0x69,0x74,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x74,0x5b,0x69,0x5d,0x5e,0x73,0x74,0x5b,0x69,0x2b,0x32,0x5d,
0x2c,0x73,0x74,0x5b,0x69,0x5d,0x2c,0x73,0x74,0x5b,0x69,0x2b,0x31,0x5d,0x29,0x3b,0x0a,0x73,0x74,0x5b,0x69,0x2b,0x31,0x5d,0x3d,0x62,0x69,0x74,0x73,0x65,0x6c,0x65,
0x63,0x74,0x28,0x73,0x74,0x5b,0x69,0x2b,0x31,0x5d,0x5e,0x73,0x74,0x5b,0x69,0x2b,0x33,0x5d,0x2c,0x73,0x74,0x5b,0x69,0x2b,0x31,0x5d,0x2c,0x73,0x74,0x5b,0x69,0x2b,
0x32,0x5d,0x29,0x3b,0x0a,0x73,0x74,0x5b,0x69,0x2b,0x32,0x5d,0x3d,0x62,0x69,0x74,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x74,0x5b,0x69,0x2b,0x32,0x5d,0x5e,0x73,
0x74,0x5b,0x69,0x2b,0x34,0x5d,0x2c,0x73,0x74,0x5b,0x69,0x2b,0x32,0x5d,0x2c,0x73,0x74,0x5b,0x69,0x2b,0x33,0x5d,0x29,0x3b,0x0a,0x73,0x74,0x5b,0x69,0x2b,0x33,0x5d,
0x3d,0x62,0x69,0x74,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x74,0x5b,0x69,0x2b,0x33,0x5d,0x5e,0x74,0x6d,0x70,0x31,0x2c,0x73,0x74,0x5b,0x69,0x2b,0x33,0x5d,0x2c,
0x73,0x74,0x5b,0x69,0x2b,0x34,0x5d,0x29,0x3b,0x0a,0x73,0x74,0x5b,0x69,0x2b,0x34,0x5d,0x3d,0x62,0x69,0x74,0x73,0x65,0x6c,0x65,0x63,0x74,0x28,0x73,0x74,0x5b,0x69,
0x2b,0x34,0x5d,0x5e,0x74,0x6d,0x70,0x32,0x2c,0x73,0x74,0x5b,0x69,0x2b,0x34,0x5d,0x2c,0x74,0x6d,0x70,0x31,0x29,0x3b,0x0a,0x7d,0x0a,0x73,0x74,0x5b,0x30,0x5d,0x20,
0x5e,0x3d,0x20,0x6b,0x65,0x63,0x63,0x61,0x6b,0x66,0x5f,0x72,0x6e,0x64,0x63,0x5b,0x72,0x6f,0x75,0x6e,0x64,0x5d,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x23,0x65,0x6e,0x64,
0x69,0x66,0x0a,0x69,0x6e,0x6c,0x69,0x6e,0x65,0x20,0x75,0x69,0x6e,0x74,0x20,0x67,0x65,0x74,0x49,0x64,0x78,0x28,0x29,0x0a,0x7b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,
0x20,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2d,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x6f,0x66,0x66,
0x73,0x65,0x74,0x28,0x30,0x29,0x3b,0x0a,0x7d,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x49,0x44,0x58,0x28,0x78,0x29,0x20,0x28,0x78,0x29,0x0a,0x69,0x6e,0x6c,
0x69,0x6e,0x65,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x5f,0x6d,0x6d,0x5f,0x61,0x64,0x64,0x5f,0x70,0x73,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x61,0x2c,0x66,
0x6c,0x6f,0x61,0x74,0x34,0x20,0x62,0x29,0x0a,0x7b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x61,0x2b,0x62,0x3b,0x0a,0x7d,0x0a,0x69,0x6e,0x6c,0x69,0x6e,0x65,0x20,
0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x5f,0x6d,0x6d,0x5f,0x73,0x75,0x62,0x5f,0x70,0x73,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x61,0x2c,0x66,0x6c,0x6f,0x61,0x74,
0x34,0x20,0x62,0x29,0x0a,0x7b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x61,0x2d,0x62,0x3b,0x0a,0x7d,0x0a,0x69,0x6e,0x6c,0x69,0x6e,0x65,0x20,0x66,0x6c,0x6f,0x61,
0x74,0x34,0x20,0x5f,0x6d,0x6d,0x5f,0x6d,0x75,0x6c,0x5f,0x70,0x73,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x61,0x2c,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x62,0x29,
0x0a,0x7b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x61,0x2a,0x62,0x3b,0x0a,0x7d,0x0a,0x69,0x6e,0x6c,0x69,0x6e,0x65,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x5f,
0x6d,0x6d,0x5f,0x64,0x69,0x76,0x5f,0x70,0x73,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x61,0x2c,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x62,0x29,0x0a,0x7b,0x0a,0x72,
0x65,0x74,0x75,0x72,0x6e,0x20,0x61,0x2f,0x62,0x3b,0x0a,0x7d,0x0a,0x69,0x6e,0x6c,0x69,0x6e,0x65,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x5f,0x6d,0x6d,0x5f,0x61,
0x6e,0x64,0x5f,0x70,0x73,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x61,0x2c,0x69,0x6e,0x74,0x20,0x62,0x29,0x0a,0x7b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x61,
0x73,0x5f,0x66,0x6c,0x6f,0x61,0x74,0x34,0x28,0x61,0x73,0x5f,0x69,0x6e,0x74,0x34,0x28,0x61,0x29,0x26,0x28,0x69,0x6e,0x74,0x34,0x29,0x28,0x62,0x29,0x29,0x3b,0x0a,
0x7d,0x0a,0x69,0x6e,0x6c,0x69,0x6e,0x65,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x5f,0x6d,0x6d,0x5f,0x6f,0x72,0x5f,0x70,0x73,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,
0x20,0x61,0x2c,0x69,0x6e,0x74,0x20,0x62,0x29,0x0a,0x7b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x61,0x73,0x5f,0x66,0x6c,0x6f,0x61,0x74,0x34,0x28,0x61,0x73,0x5f,
0x69,0x6e,0x74,0x34,0x28,0x61,0x29,0x7c,0x28,0x69,0x6e,0x74,0x34,0x29,0x28,0x62,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x69,0x6e,0x6c,0x69,0x6e,0x65,0x20,0x66,0x6c,0x6f,
0x61,0x74,0x34,0x20,0x5f,0x6d,0x6d,0x5f,0x66,0x6d,0x6f,0x64,0x5f,0x70,0x73,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x76,0x2c,0x66,0x6c,0x6f,0x61,0x74,0x20,0x64,
0x63,0x29,0x0a,0x7b,0x0a,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x64,0x3d,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x29,0x28,0x64,0x63,0x29,0x3b,0x0a,0x66,0x6c,0x6f,0x61,
0x74,0x34,0x20,0x63,0x3d,0x5f,0x6d,0x6d,0x5f,0x64,0x69,0x76,0x5f,0x70,0x73,0x28,0x76,0x2c,0x64,0x29,0x3b,0x0a,0x63,0x3d,0x74,0x72,0x75,0x6e,0x63,0x28,0x63,0x29,
0x3b,0x0a,0x63,0x3d,0x5f,0x6d,0x6d,0x5f,0x6d,0x75,0x6c,0x5f,0x70,0x73,0x28,0x63,0x2c,0x64,0x29,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x5f,0x6d,0x6d,0x5f,
0x73,0x75,0x62,0x5f,0x70,0x73,0x28,0x76,0x2c,0x63,0x29,0x3b,0x0a,0x7d,0x0a,0x69,0x6e,0x6c,0x69,0x6e,0x65,0x20,0x69,0x6e,0x74,0x34,0x20,0x5f,0x6d,0x6d,0x5f,0x78,
0x6f,0x72,0x5f,0x73,0x69,0x31,0x32,0x38,0x28,0x69,0x6e,0x74,0x34,0x20,0x61,0x2c,0x69,0x6e,0x74,0x34,0x20,0x62,0x29,0x0a,0x7b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,
0x20,0x61,0x5e,0x62,0x3b,0x0a,0x7d,0x0a,0x69,0x6e,0x6c,0x69,0x6e,0x65,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x5f,0x6d,0x6d,0x5f,0x78,0x6f,0x72,0x5f,0x70,0x73,
0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x61,0x2c,0x69,0x6e,0x74,0x20,0x62,0x29,0x0a,0x7b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x61,0x73,0x5f,0x66,0x6c,0x6f,
0x61,0x74,0x34,0x28,0x61,0x73,0x5f,0x69,0x6e,0x74,0x34,0x28,0x61,0x29,0x5e,0x28,0x69,0x6e,0x74,0x34,0x29,0x28,0x62,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x69,0x6e,0x6c,
0x69,0x6e,0x65,0x20,0x69,0x6e,0x74,0x34,0x20,0x5f,0x6d,0x6d,0x5f,0x61,0x6c,0x69,0x67,0x6e,0x72,0x5f,0x65,0x70,0x69,0x38,0x28,0x69,0x6e,0x74,0x34,0x20,0x61,0x2c,
0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x72,0x6f,0x74,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x72,0x69,0x67,
0x68,0x74,0x3d,0x38,0x2a,0x72,0x6f,0x74,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6c,0x65,0x66,0x74,0x3d,0x28,0x33,0x32,0x2d,0x38,0x2a,
0x72,0x6f,0x74,0x29,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x28,0x69,0x6e,0x74,0x34,0x29,0x28,0x0a,0x28,0x28,0x75,0x69,0x6e,0x74,0x29,0x61,0x2e,0x78,0x3e,
0x3e,0x72,0x69,0x67,0x68,0x74,0x29,0x7c,0x28,0x20,0x61,0x2e,0x79,0x3c,0x3c,0x6c,0x65,0x66,0x74,0x20,0x29,0x2c,0x0a,0x28,0x28,0x75,0x69,0x6e,0x74,0x29,0x61,0x2e,
0x79,0x3e,0x3e,0x72,0x69,0x67,0x68,0x74,0x29,0x7c,0x28,0x20,0x61,0x2e,0x7a,0x3c,0x3c,0x6c,0x65,0x66,0x74,0x20,0x29,0x2c,0x0a,0x28,0x28,0x75,0x69,0x6e,0x74,0x29,
0x61,0x2e,0x7a,0x3e,0x3e,0x72,0x69,0x67,0x68,0x74,0x29,0x7c,0x28,0x20,0x61,0x2e,0x77,0x3c,0x3c,0x6c,0x65,0x66,0x74,0x20,0x29,0x2c,0x0a,0x28,0x28,0x75,0x69,0x6e,
0x74,0x29,0x61,0x2e,0x77,0x3e,0x3e,0x72,0x69,0x67,0x68,0x74,0x29,0x7c,0x28,0x20,0x61,0x2e,0x78,0x3c,0x3c,0x6c,0x65,0x66,0x74,0x20,0x29,0x0a,0x29,0x3b,0x0a,0x7d,
0x0a,0x69,0x6e,0x6c,0x69,0x6e,0x65,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x69,0x6e,0x74,0x34,0x2a,0x20,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,
0x70,0x74,0x72,0x28,0x75,0x69,0x6e,0x74,0x20,0x69,0x64,0x78,0x2c,0x75,0x69,0x6e,0x74,0x20,0x6e,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x69,0x6e,0x74,
0x20,0x2a,0x6c,0x70,0x61,0x64,0x29,0x20,0x7b,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x69,0x6e,0x74,0x34,0x2a,
0x29,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x68,0x61,0x72,0x2a,0x29,0x6c,0x70,0x61,0x64,0x2b,0x28,0x69,0x64,0x78,0x26,0x4d,0x41,0x53,0x4b,
0x29,0x2b,0x6e,0x2a,0x31,0x36,0x29,0x3b,0x20,0x7d,0x0a,0x69,0x6e,0x6c,0x69,0x6e,0x65,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x66,0x6d,0x61,0x5f,0x62,0x72,0x65,
0x61,0x6b,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x78,0x29,0x0a,0x7b,0x0a,0x78,0x3d,0x5f,0x6d,0x6d,0x5f,0x61,0x6e,0x64,0x5f,0x70,0x73,0x28,0x78,0x2c,0x30,0x78,
0x46,0x45,0x46,0x46,0x46,0x46,0x46,0x46,0x29,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x5f,0x6d,0x6d,0x5f,0x6f,0x72,0x5f,0x70,0x73,0x28,0x78,0x2c,0x30,0x78,
0x30,0x30,0x38,0x30,0x30,0x30,0x30,0x30,0x29,0x3b,0x0a,0x7d,0x0a,0x69,0x6e,0x6c,0x69,0x6e,0x65,0x20,0x76,0x6f,0x69,0x64,0x20,0x73,0x75,0x62,0x5f,0x72,0x6f,0x75,
0x6e,0x64,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x6e,0x30,0x2c,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x6e,0x31,0x2c,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x6e,0x32,
0x2c,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x6e,0x33,0x2c,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x72,0x6e,0x64,0x5f,0x63,0x2c,0x66,0x6c,0x6f,0x61,0x74,0x34,0x2a,0x20,
0x6e,0x2c,0x66,0x6c,0x6f,0x61,0x74,0x34,0x2a,0x20,0x64,0x2c,0x66,0x6c,0x6f,0x61,0x74,0x34,0x2a,0x20,0x63,0x29,0x0a,0x7b,0x0a,0x6e,0x31,0x3d,0x5f,0x6d,0x6d,0x5f,
0x61,0x64,0x64,0x5f,0x70,0x73,0x28,0x6e,0x31,0x2c,0x2a,0x63,0x29,0x3b,0x0a,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x6e,0x6e,0x3d,0x5f,0x6d,0x6d,0x5f,0x6d,0x75,0x6c,
0x5f,0x70,0x73,0x28,0x6e,0x30,0x2c,0x2a,0x63,0x29,0x3b,0x0a,0x6e,0x6e,0x3d,0x5f,0x6d,0x6d,0x5f,0x6d,0x75,0x6c,0x5f,0x70,0x73,0x28,0x6e,0x31,0x2c,0x5f,0x6d,0x6d,
0x5f,0x6d,0x75,0x6c,0x5f,0x70,0x73,0x28,0x6e,0x6e,0x2c,0x6e,0x6e,0x29,0x29,0x3b,0x0a,0x6e,0x6e,0x3d,0x66,0x6d,0x61,0x5f,0x62,0x72,0x65,0x61,0x6b,0x28,0x6e,0x6e,
0x29,0x3b,0x0a,0x2a,0x6e,0x3d,0x5f,0x6d,0x6d,0x5f,0x61,0x64,0x64,0x5f,0x70,0x73,0x28,0x2a,0x6e,0x2c,0x6e,0x6e,0x29,0x3b,0x0a,0x6e,0x33,0x3d,0x5f,0x6d,0x6d,0x5f,
0x73,0x75,0x62,0x5f,0x70,0x73,0x28,0x6e,0x33,0x2c,0x2a,0x63,0x29,0x3b,0x0a,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x64,0x64,0x3d,0x5f,0x6d,0x6d,0x5f,0x6d,0x75,0x6c,
0x5f,0x70,0x73,0x28,0x6e,0x32,0x2c,0x2a,0x63,0x29,0x3b,0x0a,0x64,0x64,0x3d,0x5f,0x6d,0x6d,0x5f,0x6d,0x75,0x6c,0x5f,0x70,0x73,0x28,0x6e,0x33,0x2c,0x5f,0x6d,0x6d,
0x5f,0x6d,0x75,0x6c,0x5f,0x70,0x73,0x28,0x64,0x64,0x2c,0x64,0x64,0x29,0x29,0x3b,0x0a,0x64,0x64,0x3d,0x66,0x6d,0x61,0x5f,0x62,0x72,0x65,0x61,0x6b,0x28,0x64,0x64,
0x29,0x3b,0x0a,0x2a,0x64,0x3d,0x5f,0x6d,0x6d,0x5f,0x61,0x64,0x64,0x5f,0x70,0x73,0x28,0x2a,0x64,0x2c,0x64,0x64,0x29,0x3b,0x0a,0x2a,0x63,0x3d,0x5f,0x6d,0x6d,0x5f,
0x61,0x64,0x64,0x5f,0x70,0x73,0x28,0x2a,0x63,0x2c,0x72,0x6e,0x64,0x5f,0x63,0x29,0x3b,0x0a,0x2a,0x63,0x3d,0x5f,0x6d,0x6d,0x5f,0x61,0x64,0x64,0x5f,0x70,0x73,0x28,
0x2a,0x63,0x2c,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x29,0x28,0x30,0x2e,0x37,0x33,0x34,0x33,0x37,0x35,0x66,0x29,0x29,0x3b,0x0a,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,
0x72,0x3d,0x5f,0x6d,0x6d,0x5f,0x61,0x64,0x64,0x5f,0x70,0x73,0x28,0x6e,0x6e,0x2c,0x64,0x64,0x29,0x3b,0x0a,0x72,0x3d,0x5f,0x6d,0x6d,0x5f,0x61,0x6e,0x64,0x5f,0x70,
0x73,0x28,0x72,0x2c,0x30,0x78,0x38,0x30,0x37,0x46,0x46,0x46,0x46,0x46,0x29,0x3b,0x0a,0x72,0x3d,0x5f,0x6d,0x6d,0x5f,0x6f,0x72,0x5f,0x70,0x73,0x28,0x72,0x2c,0x30,
0x78,0x34,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,0x3b,0x0a,0x2a,0x63,0x3d,0x5f,0x6d,0x6d,0x5f,0x61,0x64,0x64,0x5f,0x70,0x73,0x28,0x2a,0x63,0x2c,0x72,0x29,0x3b,
0x0a,0x7d,0x0a,0x69,0x6e,0x6c,0x69,0x6e,0x65,0x20,0x76,0x6f,0x69,0x64,0x20,0x72,0x6f,0x75,0x6e,0x64,0x5f,0x63,0x6f,0x6d,0x70,0x75,0x74,0x65,0x28,0x66,0x6c,0x6f,
0x61,0x74,0x34,0x20,0x6e,0x30,0x2c,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x6e,0x31,0x2c,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x6e,0x32,0x2c,0x66,0x6c,0x6f,0x61,0x74,
0x34,0x20,0x6e,0x33,0x2c,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x72,0x6e,0x64,0x5f,0x63,0x2c,0x66,0x6c,0x6f,0x61,0x74,0x34,0x2a,0x20,0x63,0x2c,0x66,0x6c,0x6f,0x61,
0x74,0x34,0x2a,0x20,0x72,0x29,0x0a,0x7b,0x0a,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x6e,0x3d,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x29,0x28,0x30,0x2e,0x30,0x66,0x29,
0x3b,0x0a,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x64,0x3d,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x29,0x28,0x30,0x2e,0x30,0x66,0x29,0x3b,0x0a,0x73,0x75,0x62,0x5f,0x72,
0x6f,0x75,0x6e,0x64,0x28,0x6e,0x30,0x2c,0x6e,0x31,0x2c,0x6e,0x32,0x2c,0x6e,0x33,0x2c,0x72,0x6e,0x64,0x5f,0x63,0x2c,0x26,0x6e,0x2c,0x26,0x64,0x2c,0x63,0x29,0x3b,
0x0a,0x73,0x75,0x62,0x5f,0x72,0x6f,0x75,0x6e,0x64,0x28,0x6e,0x31,0x2c,0x6e,0x32,0x2c,0x6e,0x33,0x2c,0x6e,0x30,0x2c,0x72,0x6e,0x64,0x5f,0x63,0x2c,0x26,0x6e,0x2c,
0x26,0x64,0x2c,0x63,0x29,0x3b,0x0a,0x73,0x75,0x62,0x5f,0x72,0x6f,0x75,0x6e,0x64,0x28,0x6e,0x32,0x2c,0x6e,0x33,0x2c,0x6e,0x30,0x2c,0x6e,0x31,0x2c,0x72,0x6e,0x64,
0x5f,0x63,0x2c,0x26,0x6e,0x2c,0x26,0x64,0x2c,0x63,0x29,0x3b,0x0a,0x73,0x75,0x62,0x5f,0x72,0x6f,0x75,0x6e,0x64,0x28,0x6e,0x33,0x2c,0x6e,0x30,0x2c,0x6e,0x31,0x2c,
0x6e,0x32,0x2c,0x72,0x6e,0x64,0x5f,0x63,0x2c,0x26,0x6e,0x2c,0x26,0x64,0x2c,0x63,0x29,0x3b,0x0a,0x73,0x75,0x62,0x5f,0x72,0x6f,0x75,0x6e,0x64,0x28,0x6e,0x33,0x2c,
0x6e,0x32,0x2c,0x6e,0x31,0x2c,0x6e,0x30,0x2c,0x72,0x6e,0x64,0x5f,0x63,0x2c,0x26,0x6e,0x2c,0x26,0x64,0x2c,0x63,0x29,0x3b,0x0a,0x73,0x75,0x62,0x5f,0x72,0x6f,0x75,
0x6e,0x64,0x28,0x6e,0x32,0x2c,0x6e,0x31,0x2c,0x6e,0x30,0x2c,0x6e,0x33,0x2c,0x72,0x6e,0x64,0x5f,0x63,0x2c,0x26,0x6e,0x2c,0x26,0x64,0x2c,0x63,0x29,0x3b,0x0a,0x73,
0x75,0x62,0x5f,0x72,0x6f,0x75,0x6e,0x64,0x28,0x6e,0x31,0x2c,0x6e,0x30,0x2c,0x6e,0x33,0x2c,0x6e,0x32,0x2c,0x72,0x6e,0x64,0x5f,0x63,0x2c,0x26,0x6e,0x2c,0x26,0x64,
0x2c,0x63,0x29,0x3b,0x0a,0x73,0x75,0x62,0x5f,0x72,0x6f,0x75,0x6e,0x64,0x28,0x6e,0x30,0x2c,0x6e,0x33,0x2c,0x6e,0x32,0x2c,0x6e,0x31,0x2c,0x72,0x6e,0x64,0x5f,0x63,
0x2c,0x26,0x6e,0x2c,0x26,0x64,0x2c,0x63,0x29,0x3b,0x0a,0x64,0x3d,0x5f,0x6d,0x6d,0x5f,0x61,0x6e,0x64,0x5f,0x70,0x73,0x28,0x64,0x2c,0x30,0x78,0x46,0x46,0x37,0x46,
0x46,0x46,0x46,0x46,0x29,0x3b,0x0a,0x64,0x3d,0x5f,0x6d,0x6d,0x5f,0x6f,0x72,0x5f,0x70,0x73,0x28,0x64,0x2c,0x30,0x78,0x34,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x29,
0x3b,0x0a,0x2a,0x72,0x20,0x3d,0x5f,0x6d,0x6d,0x5f,0x61,0x64,0x64,0x5f,0x70,0x73,0x28,0x2a,0x72,0x2c,0x5f,0x6d,0x6d,0x5f,0x64,0x69,0x76,0x5f,0x70,0x73,0x28,0x6e,
0x2c,0x64,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x69,0x6e,0x6c,0x69,0x6e,0x65,0x20,0x69,0x6e,0x74,0x34,0x20,0x73,0x69,0x6e,0x67,0x6c,0x65,0x5f,0x63,0x6f,0x6d,0x70,0x75,
0x74,0x65,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x6e,0x30,0x2c,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x6e,0x31,0x2c,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x6e,0x32,
0x2c,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x6e,0x33,0x2c,0x66,0x6c,0x6f,0x61,0x74,0x20,0x63,0x6e,0x74,0x2c,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x72,0x6e,0x64,0x5f,
0x63,0x2c,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x2a,0x20,0x73,0x75,0x6d,0x29,0x0a,0x7b,0x0a,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,
0x63,0x3d,0x20,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x29,0x28,0x63,0x6e,0x74,0x29,0x3b,0x0a,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x72,0x3d,0x28,0x66,0x6c,0x6f,0x61,
0x74,0x34,0x29,0x28,0x30,0x2e,0x30,0x66,0x29,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x34,0x3b,0x20,0x2b,0x2b,
0x69,0x29,0x20,0x7b,0x0a,0x72,0x6f,0x75,0x6e,0x64,0x5f,0x63,0x6f,0x6d,0x70,0x75,0x74,0x65,0x28,0x6e,0x30,0x2c,0x6e,0x31,0x2c,0x6e,0x32,0x2c,0x6e,0x33,0x2c,0x72,
0x6e,0x64,0x5f,0x63,0x2c,0x26,0x63,0x2c,0x26,0x72,0x29,0x3b,0x0a,0x7d,0x0a,0x72,0x3d,0x5f,0x6d,0x6d,0x5f,0x61,0x6e,0x64,0x5f,0x70,0x73,0x28,0x72,0x2c,0x30,0x78,
0x38,0x30,0x37,0x46,0x46,0x46,0x46,0x46,0x29,0x3b,0x0a,0x72,0x3d,0x5f,0x6d,0x6d,0x5f,0x6f,0x72,0x5f,0x70,0x73,0x28,0x72,0x2c,0x30,0x78,0x34,0x30,0x30,0x30,0x30,
0x30,0x30,0x30,0x29,0x3b,0x0a,0x2a,0x73,0x75,0x6d,0x3d,0x72,0x3b,0x20,0x0a,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x78,0x3d,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x29,
0x28,0x35,0x33,0x36,0x38,0x37,0x30,0x38,0x38,0x30,0x2e,0x30,0x66,0x29,0x3b,0x0a,0x72,0x3d,0x5f,0x6d,0x6d,0x5f,0x6d,0x75,0x6c,0x5f,0x70,0x73,0x28,0x72,0x2c,0x78,
0x29,0x3b,0x20,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x5f,0x69,0x6e,0x74,0x34,0x5f,0x72,0x74,0x65,0x28,0x72,0x29,0x3b,0x0a,
0x7d,0x0a,0x69,0x6e,0x6c,0x69,0x6e,0x65,0x20,0x76,0x6f,0x69,0x64,0x20,0x73,0x69,0x6e,0x67,0x6c,0x65,0x5f,0x63,0x6f,0x6d,0x70,0x75,0x74,0x65,0x5f,0x77,0x72,0x61,
0x70,0x28,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x72,0x6f,0x74,0x2c,0x69,0x6e,0x74,0x34,0x20,0x76,0x30,0x2c,0x69,0x6e,0x74,0x34,0x20,0x76,0x31,
0x2c,0x69,0x6e,0x74,0x34,0x20,0x76,0x32,0x2c,0x69,0x6e,0x74,0x34,0x20,0x76,0x33,0x2c,0x66,0x6c,0x6f,0x61,0x74,0x20,0x63,0x6e,0x74,0x2c,0x66,0x6c,0x6f,0x61,0x74,
0x34,0x20,0x72,0x6e,0x64,0x5f,0x63,0x2c,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x2a,0x20,0x73,0x75,0x6d,0x2c,0x5f,0x5f,0x6c,0x6f,
0x63,0x61,0x6c,0x20,0x69,0x6e,0x74,0x34,0x2a,0x20,0x6f,0x75,0x74,0x29,0x0a,0x7b,0x0a,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x6e,0x30,0x3d,0x63,0x6f,0x6e,0x76,0x65,
0x72,0x74,0x5f,0x66,0x6c,0x6f,0x61,0x74,0x34,0x5f,0x72,0x74,0x65,0x28,0x76,0x30,0x29,0x3b,0x0a,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x6e,0x31,0x3d,0x63,0x6f,0x6e,
0x76,0x65,0x72,0x74,0x5f,0x66,0x6c,0x6f,0x61,0x74,0x34,0x5f,0x72,0x74,0x65,0x28,0x76,0x31,0x29,0x3b,0x0a,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x6e,0x32,0x3d,0x63,
0x6f,0x6e,0x76,0x65,0x72,0x74,0x5f,0x66,0x6c,0x6f,0x61,0x74,0x34,0x5f,0x72,0x74,0x65,0x28,0x76,0x32,0x29,0x3b,0x0a,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x6e,0x33,
0x3d,0x63,0x6f,0x6e,0x76,0x65,0x72,0x74,0x5f,0x66,0x6c,0x6f,0x61,0x74,0x34,0x5f,0x72,0x74,0x65,0x28,0x76,0x33,0x29,0x3b,0x0a,0x69,0x6e,0x74,0x34,0x20,0x72,0x3d,
0x73,0x69,0x6e,0x67,0x6c,0x65,0x5f,0x63,0x6f,0x6d,0x70,0x75,0x74,0x65,0x28,0x6e,0x30,0x2c,0x6e,0x31,0x2c,0x6e,0x32,0x2c,0x6e,0x33,0x2c,0x63,0x6e,0x74,0x2c,0x72,
0x6e,0x64,0x5f,0x63,0x2c,0x73,0x75,0x6d,0x29,0x3b,0x0a,0x2a,0x6f,0x75,0x74,0x3d,0x72,0x6f,0x74,0x3d,0x3d,0x30,0x3f,0x72,0x3a,0x5f,0x6d,0x6d,0x5f,0x61,0x6c,0x69,
0x67,0x6e,0x72,0x5f,0x65,0x70,0x69,0x38,0x28,0x72,0x2c,0x72,0x6f,0x74,0x29,0x3b,0x0a,0x7d,0x0a,0x73,0x74,0x61,0x74,0x69,0x63,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,
0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x6c,0x6f,0x6f,0x6b,0x5b,0x31,0x36,0x5d,0x5b,0x34,0x5d,0x3d,0x7b,0x0a,0x7b,0x30,
0x2c,0x31,0x2c,0x32,0x2c,0x33,0x7d,0x2c,0x0a,0x7b,0x30,0x2c,0x32,0x2c,0x33,0x2c,0x31,0x7d,0x2c,0x0a,0x7b,0x30,0x2c,0x33,0x2c,0x31,0x2c,0x32,0x7d,0x2c,0x0a,0x7b,
0x30,0x2c,0x33,0x2c,0x32,0x2c,0x31,0x7d,0x2c,0x0a,0x7b,0x31,0x2c,0x30,0x2c,0x32,0x2c,0x33,0x7d,0x2c,0x0a,0x7b,0x31,0x2c,0x32,0x2c,0x33,0x2c,0x30,0x7d,0x2c,0x0a,
0x7b,0x31,0x2c,0x33,0x2c,0x30,0x2c,0x32,0x7d,0x2c,0x0a,0x7b,0x31,0x2c,0x33,0x2c,0x32,0x2c,0x30,0x7d,0x2c,0x0a,0x7b,0x32,0x2c,0x31,0x2c,0x30,0x2c,0x33,0x7d,0x2c,
0x0a,0x7b,0x32,0x2c,0x30,0x2c,0x33,0x2c,0x31,0x7d,0x2c,0x0a,0x7b,0x32,0x2c,0x33,0x2c,0x31,0x2c,0x30,0x7d,0x2c,0x0a,0x7b,0x32,0x2c,0x33,0x2c,0x30,0x2c,0x31,0x7d,
0x2c,0x0a,0x7b,0x33,0x2c,0x31,0x2c,0x32,0x2c,0x30,0x7d,0x2c,0x0a,0x7b,0x33,0x2c,0x32,0x2c,0x30,0x2c,0x31,0x7d,0x2c,0x0a,0x7b,0x33,0x2c,0x30,0x2c,0x31,0x2c,0x32,
0x7d,0x2c,0x0a,0x7b,0x33,0x2c,0x30,0x2c,0x32,0x2c,0x31,0x7d,0x0a,0x7d,0x3b,0x0a,0x73,0x74,0x61,0x74,0x69,0x63,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x5f,0x5f,0x63,
0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x63,0x63,0x6e,0x74,0x5b,0x31,0x36,0x5d,0x3d,0x7b,0x0a,0x31,0x2e,0x33,0x34,0x33,0x37,0x35,
0x66,0x2c,0x0a,0x31,0x2e,0x32,0x38,0x31,0x32,0x35,0x66,0x2c,0x0a,0x31,0x2e,0x33,0x35,0x39,0x33,0x37,0x35,0x66,0x2c,0x0a,0x31,0x2e,0x33,0x36,0x37,0x31,0x38,0x37,
0x35,0x66,0x2c,0x0a,0x31,0x2e,0x34,0x32,0x39,0x36,0x38,0x37,0x35,0x66,0x2c,0x0a,0x31,0x2e,0x33,0x39,0x38,0x34,0x33,0x37,0x35,0x66,0x2c,0x0a,0x31,0x2e,0x33,0x38,
0x32,0x38,0x31,0x32,0x35,0x66,0x2c,0x0a,0x31,0x2e,0x33,0x30,0x34,0x36,0x38,0x37,0x35,0x66,0x2c,0x0a,0x31,0x2e,0x34,0x31,0x34,0x30,0x36,0x32,0x35,0x66,0x2c,0x0a,
0x31,0x2e,0x32,0x37,0x33,0x34,0x33,0x37,0x35,0x66,0x2c,0x0a,0x31,0x2e,0x32,0x35,0x37,0x38,0x31,0x32,0x35,0x66,0x2c,0x0a,0x31,0x2e,0x32,0x38,0x39,0x30,0x36,0x32,
0x35,0x66,0x2c,0x0a,0x31,0x2e,0x33,0x32,0x30,0x33,0x31,0x32,0x35,0x66,0x2c,0x0a,0x31,0x2e,0x33,0x35,0x31,0x35,0x36,0x32,0x35,0x66,0x2c,0x0a,0x31,0x2e,0x33,0x33,
0x35,0x39,0x33,0x37,0x35,0x66,0x2c,0x0a,0x31,0x2e,0x34,0x36,0x30,0x39,0x33,0x37,0x35,0x66,0x0a,0x7d,0x3b,0x0a,0x73,0x74,0x72,0x75,0x63,0x74,0x20,0x53,0x68,0x61,
0x72,0x65,0x64,0x4d,0x65,0x6d,0x43,0x68,0x75,0x6e,0x6b,0x0a,0x7b,0x0a,0x69,0x6e,0x74,0x34,0x20,0x6f,0x75,0x74,0x5b,0x31,0x36,0x5d,0x3b,0x0a,0x66,0x6c,0x6f,0x61,
0x74,0x34,0x20,0x76,0x61,0x5b,0x31,0x36,0x5d,0x3b,0x0a,0x7d,0x3b,0x0a,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x72,0x65,0x71,
0x64,0x5f,0x77,0x6f,0x72,0x6b,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x28,0x57,0x4f,0x52,0x4b,0x53,0x49,0x5a,0x45,0x2a,0x31,0x36,0x2c,0x31,0x2c,
0x31,0x29,0x29,0x29,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x63,0x6e,0x31,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,
0x69,0x6e,0x74,0x20,0x2a,0x6c,0x70,0x61,0x64,0x5f,0x69,0x6e,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x69,0x6e,0x74,0x20,0x2a,0x73,0x70,0x61,0x64,0x2c,
0x75,0x69,0x6e,0x74,0x20,0x6e,0x75,0x6d,0x54,0x68,0x72,0x65,0x61,0x64,0x73,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x67,0x49,
0x64,0x78,0x3d,0x67,0x65,0x74,0x49,0x64,0x78,0x28,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x20,0x63,0x68,0x75,0x6e,0x6b,0x3d,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,
0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2f,0x31,0x36,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x69,0x6e,0x74,0x2a,0x20,0x6c,0x70,0x61,0x64,0x3d,0x28,
0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x69,0x6e,0x74,0x2a,0x29,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x68,0x61,0x72,0x2a,0x29,0x6c,
0x70,0x61,0x64,0x5f,0x69,0x6e,0x2b,0x4d,0x45,0x4d,0x4f,0x52,0x59,0x2a,0x28,0x67,0x49,0x64,0x78,0x2f,0x31,0x36,0x29,0x29,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,
0x6c,0x20,0x73,0x74,0x72,0x75,0x63,0x74,0x20,0x53,0x68,0x61,0x72,0x65,0x64,0x4d,0x65,0x6d,0x43,0x68,0x75,0x6e,0x6b,0x20,0x73,0x6d,0x65,0x6d,0x5f,0x69,0x6e,0x5b,
0x57,0x4f,0x52,0x4b,0x53,0x49,0x5a,0x45,0x5d,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x73,0x74,0x72,0x75,0x63,0x74,0x20,0x53,0x68,0x61,0x72,0x65,0x64,
0x4d,0x65,0x6d,0x43,0x68,0x75,0x6e,0x6b,0x2a,0x20,0x73,0x6d,0x65,0x6d,0x3d,0x73,0x6d,0x65,0x6d,0x5f,0x69,0x6e,0x2b,0x63,0x68,0x75,0x6e,0x6b,0x3b,0x0a,0x75,0x69,
0x6e,0x74,0x20,0x74,0x69,0x64,0x3d,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x20,0x25,0x20,0x31,0x36,0x3b,0x0a,0x75,0x69,0x6e,
0x74,0x20,0x69,0x64,0x78,0x48,0x61,0x73,0x68,0x3d,0x67,0x49,0x64,0x78,0x2f,0x31,0x36,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x20,0x73,0x3d,0x28,0x28,0x5f,0x5f,0x67,0x6c,
0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x29,0x73,0x70,0x61,0x64,0x29,0x5b,0x69,0x64,0x78,0x48,0x61,0x73,0x68,0x2a,0x35,0x30,0x5d,0x3e,0x3e,0x38,0x3b,
0x0a,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x76,0x73,0x3d,0x28,0x66,0x6c,0x6f,0x61,0x74,0x34,0x29,0x28,0x30,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,
0x6e,0x74,0x20,0x74,0x69,0x64,0x64,0x3d,0x74,0x69,0x64,0x2f,0x34,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x74,0x69,0x64,0x6d,0x3d,0x74,
0x69,0x64,0x20,0x25,0x20,0x34,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x62,0x6c,0x6f,0x63,0x6b,0x3d,0x74,0x69,0x64,0x64,0x2a,0x31,0x36,
0x2b,0x74,0x69,0x64,0x6d,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x43,0x4e,0x5f,0x55,0x4e,0x52,0x4f,0x4c,0x4c,0x0a,
0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x49,0x54,0x45,0x52,0x41,0x54,0x49,0x4f,0x4e,0x53,0x3b,0x20,0x69,0x2b,0x2b,
0x29,0x20,0x7b,0x0a,0x6d,0x65,0x6d,0x5f,0x66,0x65,0x6e,0x63,0x65,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,
0x45,0x29,0x3b,0x0a,0x69,0x6e,0x74,0x20,0x74,0x6d,0x70,0x3d,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x69,0x6e,0x74,0x2a,0x29,0x73,0x63,0x72,0x61,
0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x70,0x74,0x72,0x28,0x73,0x2c,0x74,0x69,0x64,0x64,0x2c,0x6c,0x70,0x61,0x64,0x29,0x29,0x5b,0x74,0x69,0x64,0x6d,0x5d,0x3b,0x0a,
0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x69,0x6e,0x74,0x2a,0x29,0x28,0x73,0x6d,0x65,0x6d,0x2d,0x3e,0x6f,0x75,0x74,0x29,0x29,0x5b,0x74,0x69,0x64,0x5d,
0x3d,0x74,0x6d,0x70,0x3b,0x0a,0x6d,0x65,0x6d,0x5f,0x66,0x65,0x6e,0x63,0x65,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,
0x4e,0x43,0x45,0x29,0x3b,0x0a,0x7b,0x0a,0x73,0x69,0x6e,0x67,0x6c,0x65,0x5f,0x63,0x6f,0x6d,0x70,0x75,0x74,0x65,0x5f,0x77,0x72,0x61,0x70,0x28,0x0a,0x74,0x69,0x64,
0x6d,0x2c,0x0a,0x2a,0x28,0x73,0x6d,0x65,0x6d,0x2d,0x3e,0x6f,0x75,0x74,0x2b,0x6c,0x6f,0x6f,0x6b,0x5b,0x74,0x69,0x64,0x5d,0x5b,0x30,0x5d,0x29,0x2c,0x0a,0x2a,0x28,
0x73,0x6d,0x65,0x6d,0x2d,0x3e,0x6f,0x75,0x74,0x2b,0x6c,0x6f,0x6f,0x6b,0x5b,0x74,0x69,0x64,0x5d,0x5b,0x31,0x5d,0x29,0x2c,0x0a,0x2a,0x28,0x73,0x6d,0x65,0x6d,0x2d,
0x3e,0x6f,0x75,0x74,0x2b,0x6c,0x6f,0x6f,0x6b,0x5b,0x74,0x69,0x64,0x5d,0x5b,0x32,0x5d,0x29,0x2c,0x0a,0x2a,0x28,0x73,0x6d,0x65,0x6d,0x2d,0x3e,0x6f,0x75,0x74,0x2b,
0x6c,0x6f,0x6f,0x6b,0x5b,0x74,0x69,0x64,0x5d,0x5b,0x33,0x5d,0x29,0x2c,0x0a,0x63,0x63,0x6e,0x74,0x5b,0x74,0x69,0x64,0x5d,0x2c,0x76,0x73,0x2c,0x73,0x6d,0x65,0x6d,
0x2d,0x3e,0x76,0x61,0x2b,0x74,0x69,0x64,0x2c,0x0a,0x73,0x6d,0x65,0x6d,0x2d,0x3e,0x6f,0x75,0x74,0x2b,0x74,0x69,0x64,0x0a,0x29,0x3b,0x0a,0x7d,0x0a,0x6d,0x65,0x6d,
0x5f,0x66,0x65,0x6e,0x63,0x65,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x69,0x6e,0x74,
0x20,0x6f,0x75,0x74,0x58,0x6f,0x72,0x3d,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x69,0x6e,0x74,0x2a,0x29,0x73,0x6d,0x65,0x6d,0x2d,0x3e,0x6f,0x75,0x74,
0x29,0x5b,0x62,0x6c,0x6f,0x63,0x6b,0x5d,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x20,0x64,0x64,0x3d,0x62,0x6c,0x6f,0x63,0x6b,0x2b,0x34,0x3b,0x20,
0x64,0x64,0x3c,0x28,0x74,0x69,0x64,0x64,0x2b,0x31,0x29,0x2a,0x31,0x36,0x3b,0x20,0x64,0x64,0x2b,0x3d,0x34,0x29,0x20,0x7b,0x0a,0x6f,0x75,0x74,0x58,0x6f,0x72,0x20,
0x5e,0x3d,0x20,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x69,0x6e,0x74,0x2a,0x29,0x73,0x6d,0x65,0x6d,0x2d,0x3e,0x6f,0x75,0x74,0x29,0x5b,0x64,0x64,0x5d,
0x3b,0x0a,0x7d,0x0a,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x69,0x6e,0x74,0x2a,0x29,0x73,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5f,0x70,
0x74,0x72,0x28,0x73,0x2c,0x74,0x69,0x64,0x64,0x2c,0x6c,0x70,0x61,0x64,0x29,0x29,0x5b,0x74,0x69,0x64,0x6d,0x5d,0x3d,0x6f,0x75,0x74,0x58,0x6f,0x72,0x5e,0x74,0x6d,
0x70,0x3b,0x0a,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x69,0x6e,0x74,0x2a,0x29,0x73,0x6d,0x65,0x6d,0x2d,0x3e,0x6f,0x75,0x74,0x29,0x5b,0x74,0x69,0x64,
0x5d,0x3d,0x6f,0x75,0x74,0x58,0x6f,0x72,0x3b,0x0a,0x66,0x6c,0x6f,0x61,0x74,0x20,0x76,0x61,0x5f,0x74,0x6d,0x70,0x31,0x3d,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,
0x6c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x2a,0x29,0x73,0x6d,0x65,0x6d,0x2d,0x3e,0x76,0x61,0x29,0x5b,0x62,0x6c,0x6f,0x63,0x6b,0x5d,0x2b,0x28,0x28,0x5f,0x5f,0x6c,0x6f,
0x63,0x61,0x6c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x2a,0x29,0x73,0x6d,0x65,0x6d,0x2d,0x3e,0x76,0x61,0x29,0x5b,0x62,0x6c,0x6f,0x63,0x6b,0x2b,0x34,0x5d,0x3b,0x0a,0x66,
0x6c,0x6f,0x61,0x74,0x20,0x76,0x61,0x5f,0x74,0x6d,0x70,0x32,0x3d,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x2a,0x29,0x73,0x6d,
0x65,0x6d,0x2d,0x3e,0x76,0x61,0x29,0x5b,0x62,0x6c,0x6f,0x63,0x6b,0x2b,0x20,0x38,0x5d,0x2b,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x66,0x6c,0x6f,0x61,
0x74,0x2a,0x29,0x73,0x6d,0x65,0x6d,0x2d,0x3e,0x76,0x61,0x29,0x5b,0x62,0x6c,0x6f,0x63,0x6b,0x2b,0x31,0x32,0x5d,0x3b,0x0a,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,
0x6c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x2a,0x29,0x73,0x6d,0x65,0x6d,0x2d,0x3e,0x76,0x61,0x29,0x5b,0x74,0x69,0x64,0x5d,0x3d,0x76,0x61,0x5f,0x74,0x6d,0x70,0x31,0x2b,
0x76,0x61,0x5f,0x74,0x6d,0x70,0x32,0x3b,0x0a,0x6d,0x65,0x6d,0x5f,0x66,0x65,0x6e,0x63,0x65,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,
0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x69,0x6e,0x74,0x20,0x6f,0x75,0x74,0x32,0x3d,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x69,0x6e,0x74,0x2a,
0x29,0x73,0x6d,0x65,0x6d,0x2d,0x3e,0x6f,0x75,0x74,0x29,0x5b,0x74,0x69,0x64,0x5d,0x5e,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x69,0x6e,0x74,0x2a,0x29,
0x73,0x6d,0x65,0x6d,0x2d,0x3e,0x6f,0x75,0x74,0x29,0x5b,0x74,0x69,0x64,0x2b,0x34,0x20,0x5d,0x5e,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x69,0x6e,0x74,
0x2a,0x29,0x73,0x6d,0x65,0x6d,0x2d,0x3e,0x6f,0x75,0x74,0x29,0x5b,0x74,0x69,0x64,0x2b,0x38,0x5d,0x5e,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x69,0x6e,
0x74,0x2a,0x29,0x73,0x6d,0x65,0x6d,0x2d,0x3e,0x6f,0x75,0x74,0x29,0x5b,0x74,0x69,0x64,0x2b,0x31,0x32,0x5d,0x3b,0x0a,0x76,0x61,0x5f,0x74,0x6d,0x70,0x31,0x3d,0x28,
0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x2a,0x29,0x73,0x6d,0x65,0x6d,0x2d,0x3e,0x76,0x61,0x29,0x5b,0x62,0x6c,0x6f,0x63,0x6b,0x5d,
0x2b,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x2a,0x29,0x73,0x6d,0x65,0x6d,0x2d,0x3e,0x76,0x61,0x29,0x5b,0x62,0x6c,0x6f,0x63,
0x6b,0x2b,0x34,0x5d,0x3b,0x0a,0x76,0x61,0x5f,0x74,0x6d,0x70,0x32,0x3d,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x2a,0x29,0x73,
0x6d,0x65,0x6d,0x2d,0x3e,0x76,0x61,0x29,0x5b,0x62,0x6c,0x6f,0x63,0x6b,0x2b,0x38,0x5d,0x2b,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x66,0x6c,0x6f,0x61,
0x74,0x2a,0x29,0x73,0x6d,0x65,0x6d,0x2d,0x3e,0x76,0x61,0x29,0x5b,0x62,0x6c,0x6f,0x63,0x6b,0x2b,0x31,0x32,0x5d,0x3b,0x0a,0x76,0x61,0x5f,0x74,0x6d,0x70,0x31,0x3d,
0x76,0x61,0x5f,0x74,0x6d,0x70,0x31,0x2b,0x76,0x61,0x5f,0x74,0x6d,0x70,0x32,0x3b,0x0a,0x76,0x61,0x5f,0x74,0x6d,0x70,0x31,0x3d,0x66,0x61,0x62,0x73,0x28,0x76,0x61,
0x5f,0x74,0x6d,0x70,0x31,0x29,0x3b,0x0a,0x66,0x6c,0x6f,0x61,0x74,0x20,0x78,0x78,0x3d,0x76,0x61,0x5f,0x74,0x6d,0x70,0x31,0x2a,0x31,0x36,0x37,0x37,0x37,0x32,0x31,
0x36,0x2e,0x30,0x66,0x3b,0x0a,0x69,0x6e,0x74,0x20,0x78,0x78,0x5f,0x69,0x6e,0x74,0x3d,0x28,0x69,0x6e,0x74,0x29,0x78,0x78,0x3b,0x0a,0x28,0x28,0x5f,0x5f,0x6c,0x6f,
0x63,0x61,0x6c,0x20,0x69,0x6e,0x74,0x2a,0x29,0x73,0x6d,0x65,0x6d,0x2d,0x3e,0x6f,0x75,0x74,0x29,0x5b,0x74,0x69,0x64,0x5d,0x3d,0x6f,0x75,0x74,0x32,0x5e,0x78,0x78,
0x5f,0x69,0x6e,0x74,0x3b,0x0a,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x2a,0x29,0x73,0x6d,0x65,0x6d,0x2d,0x3e,0x76,0x61,0x29,
0x5b,0x74,0x69,0x64,0x5d,0x3d,0x76,0x61,0x5f,0x74,0x6d,0x70,0x31,0x2f,0x36,0x34,0x2e,0x30,0x66,0x3b,0x0a,0x6d,0x65,0x6d,0x5f,0x66,0x65,0x6e,0x63,0x65,0x28,0x43,
0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x76,0x73,0x3d,0x73,0x6d,0x65,0x6d,0x2d,0x3e,0x76,0x61,
0x5b,0x30,0x5d,0x3b,0x0a,0x73,0x3d,0x73,0x6d,0x65,0x6d,0x2d,0x3e,0x6f,0x75,0x74,0x5b,0x30,0x5d,0x2e,0x78,0x5e,0x73,0x6d,0x65,0x6d,0x2d,0x3e,0x6f,0x75,0x74,0x5b,
0x30,0x5d,0x2e,0x79,0x5e,0x73,0x6d,0x65,0x6d,0x2d,0x3e,0x6f,0x75,0x74,0x5b,0x30,0x5d,0x2e,0x7a,0x5e,0x73,0x6d,0x65,0x6d,0x2d,0x3e,0x6f,0x75,0x74,0x5b,0x30,0x5d,
0x2e,0x77,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x73,0x74,0x61,0x74,0x69,0x63,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,
0x75,0x69,0x6e,0x74,0x20,0x73,0x6b,0x69,0x70,0x5b,0x33,0x5d,0x3d,0x7b,0x0a,0x32,0x30,0x2c,0x32,0x32,0x2c,0x32,0x32,0x0a,0x7d,0x3b,0x0a,0x69,0x6e,0x6c,0x69,0x6e,
0x65,0x20,0x76,0x6f,0x69,0x64,0x20,0x67,0x65,0x6e,0x65,0x72,0x61,0x74,0x65,0x5f,0x35,0x31,0x32,0x28,0x75,0x69,0x6e,0x74,0x20,0x69,0x64,0x78,0x2c,0x5f,0x5f,0x6c,
0x6f,0x63,0x61,0x6c,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x2a,0x20,0x69,0x6e,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x2a,0x20,0x6f,
0x75,0x74,0x29,0x0a,0x7b,0x0a,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x68,0x61,0x73,0x68,0x5b,0x32,0x35,0x5d,0x3b,0x0a,0x68,0x61,0x73,0x68,0x5b,0x30,0x5d,0x3d,0x69,0x6e,
0x5b,0x30,0x5d,0x5e,0x69,0x64,0x78,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x31,0x3b,0x20,0x69,0x3c,0x32,0x35,0x3b,0x20,0x2b,0x2b,0x69,
0x29,0x20,0x7b,0x0a,0x68,0x61,0x73,0x68,0x5b,0x69,0x5d,0x3d,0x69,0x6e,0x5b,0x69,0x5d,0x3b,0x0a,0x7d,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x61,0x3d,
0x30,0x3b,0x20,0x61,0x3c,0x33,0x3b,0x20,0x2b,0x2b,0x61,0x29,0x20,0x7b,0x0a,0x6b,0x65,0x63,0x63,0x61,0x6b,0x66,0x31,0x36,0x30,0x30,0x5f,0x31,0x28,0x68,0x61,0x73,
0x68,0x29,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x73,0x6b,0x69,0x70,0x5b,0x61,0x5d,0x3b,0x20,0x2b,0x2b,0x69,
0x29,0x20,0x7b,0x0a,0x6f,0x75,0x74,0x5b,0x69,0x5d,0x3d,0x68,0x61,0x73,0x68,0x5b,0x69,0x5d,0x3b,0x0a,0x7d,0x0a,0x6f,0x75,0x74,0x2b,0x3d,0x73,0x6b,0x69,0x70,0x5b,
0x61,0x5d,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x72,0x65,0x71,0x64,0x5f,0x77,0x6f,0x72,0x6b,
0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x28,0x38,0x2c,0x38,0x2c,0x31,0x29,0x29,0x29,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,
0x69,0x64,0x20,0x63,0x6e,0x30,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x2a,0x69,0x6e,0x70,0x75,0x74,0x2c,0x69,0x6e,0x74,
0x20,0x69,0x6e,0x6c,0x65,0x6e,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x69,0x6e,0x74,0x20,0x2a,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x2c,
0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x2a,0x73,0x74,0x61,0x74,0x65,0x73,0x2c,0x75,0x69,0x6e,0x74,0x20,0x54,0x68,0x72,0x65,
0x61,0x64,0x73,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x67,0x49,0x64,0x78,0x3d,0x67,0x65,0x74,0x49,0x64,0x78,0x28,0x29,0x3b,
0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x53,0x74,0x61,0x74,0x65,0x5f,0x62,0x75,0x66,0x5b,0x38,0x2a,0x32,0x35,0x5d,0x3b,0x0a,
0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x2a,0x20,0x53,0x74,0x61,0x74,0x65,0x3d,0x53,0x74,0x61,0x74,0x65,0x5f,0x62,0x75,0x66,0x2b,0x67,
0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2a,0x32,0x35,0x3b,0x0a,0x7b,0x0a,0x73,0x74,0x61,0x74,0x65,0x73,0x2b,0x3d,0x32,0x35,0x2a,
0x67,0x49,0x64,0x78,0x3b,0x0a,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x3d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x69,0x6e,0x74,0x2a,0x29,
0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x68,0x61,0x72,0x2a,0x29,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x2b,0x4d,0x45,0x4d,0x4f,
0x52,0x59,0x2a,0x67,0x49,0x64,0x78,0x29,0x3b,0x0a,0x69,0x66,0x28,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3d,0x3d,0x30,0x29,
0x20,0x7b,0x0a,0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x5f,0x5f,0x4e,0x56,0x5f,0x43,0x4c,0x5f,0x43,0x5f,0x56,0x45,0x52,0x53,0x49,0x4f,0x4e,0x0a,0x66,0x6f,0x72,0x28,
0x75,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x38,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a,0x53,0x74,0x61,0x74,0x65,0x5b,0x69,0x5d,0x3d,0x69,0x6e,0x70,
0x75,0x74,0x5b,0x69,0x5d,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x38,0x20,0x2a,0x29,
0x53,0x74,0x61,0x74,0x65,0x29,0x5b,0x30,0x5d,0x3d,0x76,0x6c,0x6f,0x61,0x64,0x38,0x28,0x30,0x2c,0x69,0x6e,0x70,0x75,0x74,0x29,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,
0x66,0x0a,0x53,0x74,0x61,0x74,0x65,0x5b,0x38,0x5d,0x3d,0x69,0x6e,0x70,0x75,0x74,0x5b,0x38,0x5d,0x3b,0x0a,0x53,0x74,0x61,0x74,0x65,0x5b,0x39,0x5d,0x3d,0x69,0x6e,
0x70,0x75,0x74,0x5b,0x39,0x5d,0x3b,0x0a,0x53,0x74,0x61,0x74,0x65,0x5b,0x31,0x30,0x5d,0x3d,0x69,0x6e,0x70,0x75,0x74,0x5b,0x31,0x30,0x5d,0x3b,0x0a,0x28,0x28,0x5f,
0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x20,0x2a,0x29,0x53,0x74,0x61,0x74,0x65,0x29,0x5b,0x39,0x5d,0x20,0x26,0x3d,0x20,0x30,0x78,0x30,0x30,0x46,
0x46,0x46,0x46,0x46,0x46,0x55,0x3b,0x0a,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x20,0x2a,0x29,0x53,0x74,0x61,0x74,0x65,0x29,0x5b,
0x39,0x5d,0x7c,0x3d,0x28,0x28,0x28,0x75,0x69,0x6e,0x74,0x29,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x29,0x26,0x30,0x78,
0x46,0x46,0x29,0x3c,0x3c,0x32,0x34,0x3b,0x0a,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x20,0x2a,0x29,0x53,0x74,0x61,0x74,0x65,0x29,
0x5b,0x31,0x30,0x5d,0x20,0x26,0x3d,0x20,0x30,0x78,0x46,0x46,0x30,0x30,0x30,0x30,0x30,0x30,0x55,0x3b,0x0a,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,
0x69,0x6e,0x74,0x20,0x2a,0x29,0x53,0x74,0x61,0x74,0x65,0x29,0x5b,0x31,0x30,0x5d,0x7c,0x3d,0x28,0x28,0x28,0x75,0x69,0x6e,0x74,0x29,0x67,0x65,0x74,0x5f,0x67,0x6c,
0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3e,0x3e,0x38,0x29,0x29,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x31,0x31,0x3b,0x20,
0x69,0x3c,0x32,0x35,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x20,0x7b,0x0a,0x53,0x74,0x61,0x74,0x65,0x5b,0x69,0x5d,0x3d,0x30,0x78,0x30,0x30,0x55,0x4c,0x3b,0x0a,0x7d,0x0a,
0x53,0x74,0x61,0x74,0x65,0x5b,0x31,0x36,0x5d,0x3d,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x55,0x4c,0x3b,0x0a,
0x6b,0x65,0x63,0x63,0x61,0x6b,0x66,0x31,0x36,0x30,0x30,0x5f,0x32,0x28,0x53,0x74,0x61,0x74,0x65,0x29,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,
0x72,0x6f,0x6c,0x6c,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x32,0x35,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x20,0x7b,0x0a,
0x73,0x74,0x61,0x74,0x65,0x73,0x5b,0x69,0x5d,0x3d,0x53,0x74,0x61,0x74,0x65,0x5b,0x69,0x5d,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x7d,0x0a,0x7d,0x0a,0x5f,0x5f,0x61,0x74,
0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x72,0x65,0x71,0x64,0x5f,0x77,0x6f,0x72,0x6b,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x28,
0x36,0x34,0x2c,0x31,0x2c,0x31,0x29,0x29,0x29,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x63,0x6e,0x30,0x30,0x28,0x5f,0x5f,0x67,
0x6c,0x6f,0x62,0x61,0x6c,0x20,0x69,0x6e,0x74,0x20,0x2a,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,
0x6c,0x6f,0x6e,0x67,0x20,0x2a,0x73,0x74,0x61,0x74,0x65,0x73,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x67,0x49,0x64,0x78,0x3d,
0x67,0x65,0x74,0x49,0x64,0x78,0x28,0x29,0x2f,0x36,0x34,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x53,0x74,0x61,0x74,0x65,
0x5b,0x32,0x35,0x5d,0x3b,0x0a,0x73,0x74,0x61,0x74,0x65,0x73,0x2b,0x3d,0x32,0x35,0x2a,0x67,0x49,0x64,0x78,0x3b,0x0a,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,
0x64,0x3d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x69,0x6e,0x74,0x2a,0x29,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x68,0x61,0x72,
0x2a,0x29,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x2b,0x4d,0x45,0x4d,0x4f,0x52,0x59,0x2a,0x67,0x49,0x64,0x78,0x29,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,
0x69,0x6e,0x74,0x20,0x69,0x3d,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x20,0x69,0x3c,0x32,0x35,0x3b,0x20,0x69,0x2b,0x3d,
0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x28,0x30,0x29,0x29,0x20,0x7b,0x0a,0x53,0x74,0x61,0x74,0x65,0x5b,0x69,0x5d,0x3d,0x73,0x74,
0x61,0x74,0x65,0x73,0x5b,0x69,0x5d,0x3b,0x0a,0x7d,0x0a,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,
0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x20,0x69,0x3d,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,
0x64,0x28,0x30,0x29,0x3b,0x20,0x69,0x3c,0x4d,0x45,0x4d,0x4f,0x52,0x59,0x2f,0x35,0x31,0x32,0x3b,0x20,0x69,0x2b,0x3d,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,
0x5f,0x73,0x69,0x7a,0x65,0x28,0x30,0x29,0x29,0x20,0x7b,0x0a,0x67,0x65,0x6e,0x65,0x72,0x61,0x74,0x65,0x5f,0x35,0x31,0x32,0x28,0x69,0x2c,0x53,0x74,0x61,0x74,0x65,
0x2c,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x2a,0x29,0x28,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x63,0x68,
0x61,0x72,0x2a,0x29,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x2b,0x69,0x2a,0x35,0x31,0x32,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x5f,0x5f,0x61,0x74,
0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x72,0x65,0x71,0x64,0x5f,0x77,0x6f,0x72,0x6b,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x28,
0x38,0x2c,0x38,0x2c,0x31,0x29,0x29,0x29,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x63,0x6e,0x32,0x28,0x5f,0x5f,0x67,0x6c,0x6f,
0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x34,0x20,0x2a,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,
0x6c,0x6f,0x6e,0x67,0x20,0x2a,0x73,0x74,0x61,0x74,0x65,0x73,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x20,0x2a,0x6f,0x75,0x74,0x70,
0x75,0x74,0x2c,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x54,0x61,0x72,0x67,0x65,0x74,0x2c,0x75,0x69,0x6e,0x74,0x20,0x54,0x68,0x72,0x65,0x61,0x64,0x73,0x29,0x0a,0x7b,0x0a,
0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x20,0x41,0x45,0x53,0x30,0x5b,0x32,0x35,0x36,0x5d,0x2c,0x41,0x45,0x53,0x31,0x5b,0x32,0x35,0x36,0x5d,
0x2c,0x41,0x45,0x53,0x32,0x5b,0x32,0x35,0x36,0x5d,0x2c,0x41,0x45,0x53,0x33,0x5b,0x32,0x35,0x36,0x5d,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x20,0x45,0x78,0x70,0x61,0x6e,
0x64,0x65,0x64,0x4b,0x65,0x79,0x32,0x5b,0x34,0x30,0x5d,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x34,0x20,0x74,0x65,0x78,0x74,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,
0x69,0x6e,0x74,0x20,0x67,0x49,0x64,0x78,0x3d,0x67,0x65,0x74,0x49,0x64,0x78,0x28,0x29,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x67,0x65,
0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x2a,0x38,0x2b,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,
0x20,0x69,0x3c,0x32,0x35,0x36,0x3b,0x20,0x69,0x2b,0x3d,0x38,0x2a,0x38,0x29,0x20,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,0x74,0x6d,0x70,
0x3d,0x41,0x45,0x53,0x30,0x5f,0x43,0x5b,0x69,0x5d,0x3b,0x0a,0x41,0x45,0x53,0x30,0x5b,0x69,0x5d,0x3d,0x74,0x6d,0x70,0x3b,0x0a,0x41,0x45,0x53,0x31,0x5b,0x69,0x5d,
0x3d,0x72,0x6f,0x74,0x61,0x74,0x65,0x28,0x74,0x6d,0x70,0x2c,0x38,0x55,0x29,0x3b,0x0a,0x41,0x45,0x53,0x32,0x5b,0x69,0x5d,0x3d,0x72,0x6f,0x74,0x61,0x74,0x65,0x28,
0x74,0x6d,0x70,0x2c,0x31,0x36,0x55,0x29,0x3b,0x0a,0x41,0x45,0x53,0x33,0x5b,0x69,0x5d,0x3d,0x72,0x6f,0x74,0x61,0x74,0x65,0x28,0x74,0x6d,0x70,0x2c,0x32,0x34,0x55,
0x29,0x3b,0x0a,0x7d,0x0a,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,
0x29,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x34,0x20,0x78,0x69,0x6e,0x31,0x5b,0x38,0x5d,0x5b,0x38,0x5d,0x3b,0x0a,0x5f,0x5f,0x6c,
0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x34,0x20,0x78,0x69,0x6e,0x32,0x5b,0x38,0x5d,0x5b,0x38,0x5d,0x3b,0x0a,0x7b,0x0a,0x73,0x74,0x61,0x74,0x65,0x73,0x2b,
0x3d,0x32,0x35,0x2a,0x67,0x49,0x64,0x78,0x3b,0x0a,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x2b,0x3d,0x67,0x49,0x64,0x78,0x2a,0x28,0x4d,0x45,0x4d,0x4f,
0x52,0x59,0x3e,0x3e,0x34,0x29,0x3b,0x0a,0x23,0x69,0x66,0x20,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x28,0x5f,0x5f,0x54,0x61,0x68,0x69,0x74,0x69,0x5f,0x5f,0x29,0x20,
0x7c,0x7c,0x20,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x28,0x5f,0x5f,0x50,0x69,0x74,0x63,0x61,0x69,0x72,0x6e,0x5f,0x5f,0x29,0x0a,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,
0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x34,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x20,0x28,0x28,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x2a,0x29,0x45,0x78,0x70,0x61,0x6e,0x64,
0x65,0x64,0x4b,0x65,0x79,0x32,0x29,0x5b,0x69,0x5d,0x3d,0x73,0x74,0x61,0x74,0x65,0x73,0x5b,0x69,0x2b,0x34,0x5d,0x3b,0x0a,0x74,0x65,0x78,0x74,0x3d,0x76,0x6c,0x6f,
0x61,0x64,0x34,0x28,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x2b,0x34,0x2c,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,
0x75,0x69,0x6e,0x74,0x20,0x2a,0x29,0x73,0x74,0x61,0x74,0x65,0x73,0x29,0x3b,0x0a,0x23,0x65,0x6c,0x73,0x65,0x0a,0x74,0x65,0x78,0x74,0x3d,0x76,0x6c,0x6f,0x61,0x64,
0x34,0x28,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x2b,0x34,0x2c,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,
0x6e,0x74,0x20,0x2a,0x29,0x73,0x74,0x61,0x74,0x65,0x73,0x29,0x3b,0x0a,0x28,0x28,0x75,0x69,0x6e,0x74,0x38,0x20,0x2a,0x29,0x45,0x78,0x70,0x61,0x6e,0x64,0x65,0x64,
0x4b,0x65,0x79,0x32,0x29,0x5b,0x30,0x5d,0x3d,0x76,0x6c,0x6f,0x61,0x64,0x38,0x28,0x31,0x2c,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,
0x20,0x2a,0x29,0x73,0x74,0x61,0x74,0x65,0x73,0x29,0x3b,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x41,0x45,0x53,0x45,0x78,0x70,0x61,0x6e,0x64,0x4b,0x65,0x79,0x32,
0x35,0x36,0x28,0x45,0x78,0x70,0x61,0x6e,0x64,0x65,0x64,0x4b,0x65,0x79,0x32,0x29,0x3b,0x0a,0x7d,0x0a,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,
0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x34,0x2a,
0x20,0x78,0x69,0x6e,0x31,0x5f,0x73,0x74,0x6f,0x72,0x65,0x3d,0x26,0x78,0x69,0x6e,0x31,0x5b,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,
0x29,0x5d,0x5b,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x5d,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,
0x74,0x34,0x2a,0x20,0x78,0x69,0x6e,0x31,0x5f,0x6c,0x6f,0x61,0x64,0x3d,0x26,0x78,0x69,0x6e,0x31,0x5b,0x28,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,
0x64,0x28,0x31,0x29,0x2b,0x31,0x29,0x20,0x25,0x20,0x38,0x5d,0x5b,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x5d,0x3b,0x0a,0x5f,
0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x34,0x2a,0x20,0x78,0x69,0x6e,0x32,0x5f,0x73,0x74,0x6f,0x72,0x65,0x3d,0x26,0x78,0x69,0x6e,0x32,0x5b,0x67,
0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x5d,0x5b,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x5d,
0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x34,0x2a,0x20,0x78,0x69,0x6e,0x32,0x5f,0x6c,0x6f,0x61,0x64,0x3d,0x26,0x78,0x69,0x6e,0x32,
0x5b,0x28,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x2b,0x31,0x29,0x20,0x25,0x20,0x38,0x5d,0x5b,0x67,0x65,0x74,0x5f,0x6c,0x6f,
0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x5d,0x3b,0x0a,0x2a,0x78,0x69,0x6e,0x32,0x5f,0x73,0x74,0x6f,0x72,0x65,0x3d,0x28,0x75,0x69,0x6e,0x74,0x34,0x29,0x28,
0x30,0x2c,0x30,0x2c,0x30,0x2c,0x30,0x29,0x3b,0x0a,0x7b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x32,0x0a,0x66,0x6f,0x72,
0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x2c,0x69,0x31,0x3d,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x3b,0x20,0x69,0x3c,
0x28,0x4d,0x45,0x4d,0x4f,0x52,0x59,0x3e,0x3e,0x37,0x29,0x3b,0x20,0x2b,0x2b,0x69,0x2c,0x69,0x31,0x3d,0x28,0x69,0x31,0x2b,0x31,0x36,0x29,0x20,0x25,0x20,0x28,0x4d,
0x45,0x4d,0x4f,0x52,0x59,0x3e,0x3e,0x34,0x29,0x29,0x20,0x7b,0x0a,0x74,0x65,0x78,0x74,0x20,0x5e,0x3d,0x20,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5b,
0x28,0x75,0x69,0x6e,0x74,0x29,0x69,0x31,0x5d,0x3b,0x0a,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,
0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x74,0x65,0x78,0x74,0x20,0x5e,0x3d,0x20,0x2a,0x78,0x69,0x6e,0x32,0x5f,0x6c,0x6f,0x61,0x64,0x3b,0x0a,0x23,0x70,0x72,
0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x31,0x30,0x0a,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x6a,0x3d,0x30,0x3b,0x20,0x6a,0x3c,0x31,0x30,
0x3b,0x20,0x2b,0x2b,0x6a,0x29,0x0a,0x74,0x65,0x78,0x74,0x3d,0x41,0x45,0x53,0x5f,0x52,0x6f,0x75,0x6e,0x64,0x28,0x41,0x45,0x53,0x30,0x2c,0x41,0x45,0x53,0x31,0x2c,
0x41,0x45,0x53,0x32,0x2c,0x41,0x45,0x53,0x33,0x2c,0x74,0x65,0x78,0x74,0x2c,0x28,0x28,0x75,0x69,0x6e,0x74,0x34,0x20,0x2a,0x29,0x45,0x78,0x70,0x61,0x6e,0x64,0x65,
0x64,0x4b,0x65,0x79,0x32,0x29,0x5b,0x6a,0x5d,0x29,0x3b,0x0a,0x2a,0x78,0x69,0x6e,0x31,0x5f,0x73,0x74,0x6f,0x72,0x65,0x3d,0x74,0x65,0x78,0x74,0x3b,0x0a,0x74,0x65,
0x78,0x74,0x20,0x5e,0x3d,0x20,0x53,0x63,0x72,0x61,0x74,0x63,0x68,0x70,0x61,0x64,0x5b,0x28,0x75,0x69,0x6e,0x74,0x29,0x69,0x31,0x2b,0x38,0x75,0x5d,0x3b,0x0a,0x62,
0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x74,0x65,0x78,
0x74,0x20,0x5e,0x3d,0x20,0x2a,0x78,0x69,0x6e,0x31,0x5f,0x6c,0x6f,0x61,0x64,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,
0x31,0x30,0x0a,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x6a,0x3d,0x30,0x3b,0x20,0x6a,0x3c,0x31,0x30,0x3b,0x20,0x2b,0x2b,0x6a,0x29,0x0a,0x74,0x65,0x78,0x74,0x3d,
0x41,0x45,0x53,0x5f,0x52,0x6f,0x75,0x6e,0x64,0x28,0x41,0x45,0x53,0x30,0x2c,0x41,0x45,0x53,0x31,0x2c,0x41,0x45,0x53,0x32,0x2c,0x41,0x45,0x53,0x33,0x2c,0x74,0x65,
0x78,0x74,0x2c,0x28,0x28,0x75,0x69,0x6e,0x74,0x34,0x20,0x2a,0x29,0x45,0x78,0x70,0x61,0x6e,0x64,0x65,0x64,0x4b,0x65,0x79,0x32,0x29,0x5b,0x6a,0x5d,0x29,0x3b,0x0a,
0x2a,0x78,0x69,0x6e,0x32,0x5f,0x73,0x74,0x6f,0x72,0x65,0x3d,0x74,0x65,0x78,0x74,0x3b,0x0a,0x7d,0x0a,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,
0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x74,0x65,0x78,0x74,0x20,0x5e,0x3d,0x20,0x2a,0x78,0x69,0x6e,0x32,0x5f,
0x6c,0x6f,0x61,0x64,0x3b,0x0a,0x7d,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x31,0x36,0x0a,0x66,0x6f,0x72,0x28,0x73,0x69,
0x7a,0x65,0x5f,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x31,0x36,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x7b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,
0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x31,0x30,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6a,0x3d,0x30,0x3b,0x20,0x6a,0x3c,0x31,0x30,0x3b,0x20,0x2b,0x2b,0x6a,
0x29,0x20,0x7b,0x0a,0x74,0x65,0x78,0x74,0x3d,0x41,0x45,0x53,0x5f,0x52,0x6f,0x75,0x6e,0x64,0x28,0x41,0x45,0x53,0x30,0x2c,0x41,0x45,0x53,0x31,0x2c,0x41,0x45,0x53,
0x32,0x2c,0x41,0x45,0x53,0x33,0x2c,0x74,0x65,0x78,0x74,0x2c,0x28,0x28,0x75,0x69,0x6e,0x74,0x34,0x20,0x2a,0x29,0x45,0x78,0x70,0x61,0x6e,0x64,0x65,0x64,0x4b,0x65,
0x79,0x32,0x29,0x5b,0x6a,0x5d,0x29,0x3b,0x0a,0x7d,0x0a,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,
0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x2a,0x78,0x69,0x6e,0x31,0x5f,0x73,0x74,0x6f,0x72,0x65,0x3d,0x74,0x65,0x78,0x74,0x3b,0x0a,0x62,0x61,0x72,0x72,0x69,
0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x74,0x65,0x78,0x74,0x20,0x5e,0x3d,
0x20,0x2a,0x78,0x69,0x6e,0x31,0x5f,0x6c,0x6f,0x61,0x64,0x3b,0x0a,0x7d,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x53,0x74,0x61,
0x74,0x65,0x5f,0x62,0x75,0x66,0x5b,0x38,0x2a,0x32,0x35,0x5d,0x3b,0x0a,0x7b,0x0a,0x76,0x73,0x74,0x6f,0x72,0x65,0x32,0x28,0x61,0x73,0x5f,0x75,0x6c,0x6f,0x6e,0x67,
0x32,0x28,0x74,0x65,0x78,0x74,0x29,0x2c,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x2b,0x34,0x2c,0x73,0x74,0x61,0x74,0x65,0x73,
0x29,0x3b,0x0a,0x7d,0x0a,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,
0x45,0x29,0x3b,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x21,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x31,0x29,0x29,0x0a,0x7b,0x0a,0x5f,0x5f,0x6c,
0x6f,0x63,0x61,0x6c,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x2a,0x20,0x53,0x74,0x61,0x74,0x65,0x3d,0x53,0x74,0x61,0x74,0x65,0x5f,0x62,0x75,0x66,0x2b,0x67,0x65,0x74,0x5f,
0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x2a,0x32,0x35,0x3b,0x0a,0x66,0x6f,0x72,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x32,
0x35,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x20,0x53,0x74,0x61,0x74,0x65,0x5b,0x69,0x5d,0x3d,0x73,0x74,0x61,0x74,0x65,0x73,0x5b,0x69,0x5d,0x3b,0x0a,0x6b,0x65,0x63,0x63,
0x61,0x6b,0x66,0x31,0x36,0x30,0x30,0x5f,0x32,0x28,0x53,0x74,0x61,0x74,0x65,0x29,0x3b,0x0a,0x69,0x66,0x28,0x53,0x74,0x61,0x74,0x65,0x5b,0x33,0x5d,0x3c,0x3d,0x54,
0x61,0x72,0x67,0x65,0x74,0x29,0x0a,0x7b,0x0a,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x6f,0x75,0x74,0x49,0x64,0x78,0x3d,0x61,0x74,0x6f,0x6d,0x69,0x63,0x5f,0x69,0x6e,0x63,
0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x30,0x78,0x46,0x46,0x29,0x3b,0x0a,0x69,0x66,0x28,0x6f,0x75,0x74,0x49,0x64,0x78,0x3c,0x30,0x78,0x46,0x46,0x29,0x0a,0x6f,
0x75,0x74,0x70,0x75,0x74,0x5b,0x6f,0x75,0x74,0x49,0x64,0x78,0x5d,0x3d,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,
0x7d,0x0a,0x7d,0x0a,0x7d,0x0a,0x6d,0x65,0x6d,0x5f,0x66,0x65,0x6e,0x63,0x65,0x28,0x43,0x4c,0x4b,0x5f,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,
0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x7d,0x0a,0x00
};
} // namespace xmrig

View File

@@ -74,7 +74,7 @@ void keccak_f800_round(uint32_t st[25], const int r)
// Keccak - implemented as a variant of SHAKE
// The width is 800, with a bitrate of 576, a capacity of 224, and no padding
// Only need 64 bits of output for mining
uint64_t keccak_f800(uint32_t* st)
void keccak_f800(uint32_t* st)
{
// Complete all 22 rounds as a separate impl to
// evaluate only first 8 words is wasteful of regsters

View File

@@ -2,7 +2,7 @@
namespace xmrig {
static const char kawpow_cl[5948] = {
static const char kawpow_cl[5944] = {
0x23,0x69,0x66,0x64,0x65,0x66,0x20,0x63,0x6c,0x5f,0x63,0x6c,0x61,0x6e,0x67,0x5f,0x73,0x74,0x6f,0x72,0x61,0x67,0x65,0x5f,0x63,0x6c,0x61,0x73,0x73,0x5f,0x73,0x70,
0x65,0x63,0x69,0x66,0x69,0x65,0x72,0x73,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,0x20,0x45,0x58,0x54,0x45,0x4e,0x53,0x49,0x4f,
0x4e,0x20,0x63,0x6c,0x5f,0x63,0x6c,0x61,0x6e,0x67,0x5f,0x73,0x74,0x6f,0x72,0x61,0x67,0x65,0x5f,0x63,0x6c,0x61,0x73,0x73,0x5f,0x73,0x70,0x65,0x63,0x69,0x66,0x69,
@@ -76,119 +76,119 @@ static const char kawpow_cl[5948] = {
0x3d,0x73,0x74,0x5b,0x6a,0x2b,0x69,0x5d,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x35,0x3b,0x20,0x69,0x2b,0x2b,
0x29,0x0a,0x73,0x74,0x5b,0x6a,0x2b,0x69,0x5d,0x20,0x5e,0x3d,0x20,0x28,0x7e,0x62,0x63,0x5b,0x28,0x69,0x2b,0x31,0x29,0x20,0x25,0x20,0x35,0x5d,0x29,0x26,0x62,0x63,
0x5b,0x28,0x69,0x2b,0x32,0x29,0x20,0x25,0x20,0x35,0x5d,0x3b,0x0a,0x7d,0x0a,0x73,0x74,0x5b,0x30,0x5d,0x20,0x5e,0x3d,0x20,0x6b,0x65,0x63,0x63,0x61,0x6b,0x66,0x5f,
0x72,0x6e,0x64,0x63,0x5b,0x72,0x5d,0x3b,0x0a,0x7d,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x6b,0x65,0x63,0x63,0x61,0x6b,0x5f,0x66,0x38,0x30,0x30,0x28,
0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x73,0x74,0x29,0x0a,0x7b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x72,0x3d,0x30,0x3b,0x20,0x72,0x3c,
0x32,0x32,0x3b,0x20,0x72,0x2b,0x2b,0x29,0x20,0x7b,0x0a,0x6b,0x65,0x63,0x63,0x61,0x6b,0x5f,0x66,0x38,0x30,0x30,0x5f,0x72,0x6f,0x75,0x6e,0x64,0x28,0x73,0x74,0x2c,
0x72,0x29,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x66,0x6e,0x76,0x31,0x61,0x28,0x68,0x2c,0x20,0x64,0x29,0x20,0x28,0x68,0x20,0x3d,
0x20,0x28,0x68,0x20,0x5e,0x20,0x64,0x29,0x20,0x2a,0x20,0x46,0x4e,0x56,0x5f,0x50,0x52,0x49,0x4d,0x45,0x29,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x73,0x74,
0x72,0x75,0x63,0x74,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x7a,0x2c,0x77,0x2c,0x6a,0x73,0x72,0x2c,0x6a,0x63,0x6f,0x6e,0x67,0x3b,0x0a,0x7d,
0x20,0x6b,0x69,0x73,0x73,0x39,0x39,0x5f,0x74,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6b,0x69,0x73,0x73,0x39,0x39,0x28,0x6b,0x69,0x73,0x73,0x39,
0x39,0x5f,0x74,0x2a,0x20,0x73,0x74,0x29,0x0a,0x7b,0x0a,0x73,0x74,0x2d,0x3e,0x7a,0x3d,0x33,0x36,0x39,0x36,0x39,0x2a,0x28,0x73,0x74,0x2d,0x3e,0x7a,0x26,0x36,0x35,
0x35,0x33,0x35,0x29,0x2b,0x28,0x73,0x74,0x2d,0x3e,0x7a,0x3e,0x3e,0x31,0x36,0x29,0x3b,0x0a,0x73,0x74,0x2d,0x3e,0x77,0x3d,0x31,0x38,0x30,0x30,0x30,0x2a,0x28,0x73,
0x74,0x2d,0x3e,0x77,0x26,0x36,0x35,0x35,0x33,0x35,0x29,0x2b,0x28,0x73,0x74,0x2d,0x3e,0x77,0x3e,0x3e,0x31,0x36,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
0x74,0x20,0x4d,0x57,0x43,0x3d,0x28,0x28,0x73,0x74,0x2d,0x3e,0x7a,0x3c,0x3c,0x31,0x36,0x29,0x2b,0x73,0x74,0x2d,0x3e,0x77,0x29,0x3b,0x0a,0x73,0x74,0x2d,0x3e,0x6a,
0x73,0x72,0x20,0x5e,0x3d,0x20,0x28,0x73,0x74,0x2d,0x3e,0x6a,0x73,0x72,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x0a,0x73,0x74,0x2d,0x3e,0x6a,0x73,0x72,0x20,0x5e,0x3d,0x20,
0x28,0x73,0x74,0x2d,0x3e,0x6a,0x73,0x72,0x3e,0x3e,0x31,0x33,0x29,0x3b,0x0a,0x73,0x74,0x2d,0x3e,0x6a,0x73,0x72,0x20,0x5e,0x3d,0x20,0x28,0x73,0x74,0x2d,0x3e,0x6a,
0x73,0x72,0x3c,0x3c,0x35,0x29,0x3b,0x0a,0x73,0x74,0x2d,0x3e,0x6a,0x63,0x6f,0x6e,0x67,0x3d,0x36,0x39,0x30,0x36,0x39,0x2a,0x73,0x74,0x2d,0x3e,0x6a,0x63,0x6f,0x6e,
0x67,0x2b,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x28,0x28,0x4d,0x57,0x43,0x5e,0x73,0x74,0x2d,0x3e,0x6a,0x63,0x6f,0x6e,
0x67,0x29,0x2b,0x73,0x74,0x2d,0x3e,0x6a,0x73,0x72,0x29,0x3b,0x0a,0x7d,0x0a,0x76,0x6f,0x69,0x64,0x20,0x66,0x69,0x6c,0x6c,0x5f,0x6d,0x69,0x78,0x28,0x6c,0x6f,0x63,
0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x73,0x65,0x65,0x64,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x61,0x6e,0x65,0x5f,
0x69,0x64,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x6d,0x69,0x78,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x66,0x6e,0x76,
0x5f,0x68,0x61,0x73,0x68,0x3d,0x46,0x4e,0x56,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x5f,0x42,0x41,0x53,0x49,0x53,0x3b,0x0a,0x6b,0x69,0x73,0x73,0x39,0x39,0x5f,0x74,
0x20,0x73,0x74,0x3b,0x0a,0x73,0x74,0x2e,0x7a,0x3d,0x66,0x6e,0x76,0x31,0x61,0x28,0x66,0x6e,0x76,0x5f,0x68,0x61,0x73,0x68,0x2c,0x73,0x65,0x65,0x64,0x5b,0x30,0x5d,
0x29,0x3b,0x0a,0x73,0x74,0x2e,0x77,0x3d,0x66,0x6e,0x76,0x31,0x61,0x28,0x66,0x6e,0x76,0x5f,0x68,0x61,0x73,0x68,0x2c,0x73,0x65,0x65,0x64,0x5b,0x31,0x5d,0x29,0x3b,
0x0a,0x73,0x74,0x2e,0x6a,0x73,0x72,0x3d,0x66,0x6e,0x76,0x31,0x61,0x28,0x66,0x6e,0x76,0x5f,0x68,0x61,0x73,0x68,0x2c,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,0x29,0x3b,
0x0a,0x73,0x74,0x2e,0x6a,0x63,0x6f,0x6e,0x67,0x3d,0x66,0x6e,0x76,0x31,0x61,0x28,0x66,0x6e,0x76,0x5f,0x68,0x61,0x73,0x68,0x2c,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,
0x29,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,
0x69,0x3c,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x52,0x45,0x47,0x53,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x6d,0x69,0x78,0x5b,0x69,0x5d,0x3d,0x6b,0x69,0x73,0x73,
0x39,0x39,0x28,0x26,0x73,0x74,0x29,0x3b,0x0a,0x7d,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x73,0x74,0x72,0x75,0x63,0x74,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,
0x33,0x32,0x5f,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x4c,0x41,0x4e,0x45,0x53,0x5d,0x3b,0x0a,0x7d,0x20,0x73,
0x68,0x75,0x66,0x66,0x6c,0x65,0x5f,0x74,0x3b,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x73,0x74,0x72,0x75,0x63,0x74,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x33,
0x32,0x5f,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x33,0x32,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x5d,
0x3b,0x0a,0x7d,0x20,0x68,0x61,0x73,0x68,0x33,0x32,0x5f,0x74,0x3b,0x0a,0x23,0x69,0x66,0x20,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x20,0x21,0x3d,0x20,0x4f,0x50,
0x45,0x4e,0x43,0x4c,0x5f,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x5f,0x4e,0x56,0x49,0x44,0x49,0x41,0x20,0x0a,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,
0x65,0x5f,0x5f,0x28,0x28,0x72,0x65,0x71,0x64,0x5f,0x77,0x6f,0x72,0x6b,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x28,0x47,0x52,0x4f,0x55,0x50,0x5f,
0x53,0x49,0x5a,0x45,0x2c,0x31,0x2c,0x31,0x29,0x29,0x29,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,
0x20,0x70,0x72,0x6f,0x67,0x70,0x6f,0x77,0x5f,0x73,0x65,0x61,0x72,0x63,0x68,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x64,0x61,0x67,0x5f,0x74,0x20,0x63,
0x6f,0x6e,0x73,0x74,0x2a,0x20,0x67,0x5f,0x64,0x61,0x67,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x6a,0x6f,0x62,0x5f,0x62,
0x6c,0x6f,0x62,0x2c,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x74,0x61,0x72,0x67,0x65,0x74,0x2c,0x75,0x69,0x6e,0x74,0x20,0x68,0x61,0x63,0x6b,0x5f,0x66,0x61,0x6c,0x73,0x65,
0x2c,0x76,0x6f,0x6c,0x61,0x74,0x69,0x6c,0x65,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x73,
0x2c,0x76,0x6f,0x6c,0x61,0x74,0x69,0x6c,0x65,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x73,0x74,0x6f,0x70,0x29,0x0a,0x7b,
0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x69,0x64,0x3d,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,
0x28,0x30,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x67,0x69,0x64,0x3d,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,
0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x69,0x66,0x28,0x73,0x74,0x6f,0x70,0x5b,0x30,0x5d,0x29,0x20,0x7b,0x0a,0x69,0x66,0x28,0x6c,0x69,0x64,0x3d,0x3d,
0x30,0x29,0x20,0x7b,0x0a,0x61,0x74,0x6f,0x6d,0x69,0x63,0x5f,0x69,0x6e,0x63,0x28,0x73,0x74,0x6f,0x70,0x2b,0x31,0x29,0x3b,0x0a,0x7d,0x0a,0x72,0x65,0x74,0x75,0x72,
0x6e,0x3b,0x0a,0x7d,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x73,0x68,0x75,0x66,0x66,0x6c,0x65,0x5f,0x74,0x20,0x73,0x68,0x61,0x72,0x65,0x5b,0x48,0x41,0x53,
0x48,0x45,0x53,0x5f,0x50,0x45,0x52,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5d,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,
0x20,0x63,0x5f,0x64,0x61,0x67,0x5b,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x43,0x41,0x43,0x48,0x45,0x5f,0x57,0x4f,0x52,0x44,0x53,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,
0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,0x3d,0x6c,0x69,0x64,0x26,0x28,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,
0x5f,0x4c,0x41,0x4e,0x45,0x53,0x2d,0x31,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x67,0x72,0x6f,0x75,0x70,0x5f,
0x69,0x64,0x3d,0x6c,0x69,0x64,0x2f,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x4c,0x41,0x4e,0x45,0x53,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,
0x32,0x5f,0x74,0x20,0x77,0x6f,0x72,0x64,0x3d,0x6c,0x69,0x64,0x2a,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x44,0x41,0x47,0x5f,0x4c,0x4f,0x41,0x44,0x53,0x3b,0x20,
0x77,0x6f,0x72,0x64,0x3c,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x43,0x41,0x43,0x48,0x45,0x5f,0x57,0x4f,0x52,0x44,0x53,0x3b,0x20,0x77,0x6f,0x72,0x64,0x2b,0x3d,
0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,0x2a,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x44,0x41,0x47,0x5f,0x4c,0x4f,0x41,0x44,0x53,0x29,0x0a,0x7b,0x0a,
0x64,0x61,0x67,0x5f,0x74,0x20,0x6c,0x6f,0x61,0x64,0x3d,0x67,0x5f,0x64,0x61,0x67,0x5b,0x77,0x6f,0x72,0x64,0x2f,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x44,0x41,
0x47,0x5f,0x4c,0x4f,0x41,0x44,0x53,0x5d,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x50,0x52,0x4f,0x47,0x50,0x4f,
0x57,0x5f,0x44,0x41,0x47,0x5f,0x4c,0x4f,0x41,0x44,0x53,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x63,0x5f,0x64,0x61,0x67,0x5b,0x77,0x6f,0x72,0x64,0x2b,0x69,0x5d,0x3d,
0x6c,0x6f,0x61,0x64,0x2e,0x73,0x5b,0x69,0x5d,0x3b,0x0a,0x7d,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x68,0x61,0x73,0x68,0x5f,0x73,0x65,0x65,0x64,0x5b,
0x32,0x5d,0x3b,0x20,0x0a,0x68,0x61,0x73,0x68,0x33,0x32,0x5f,0x74,0x20,0x64,0x69,0x67,0x65,0x73,0x74,0x3b,0x20,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,
0x73,0x74,0x61,0x74,0x65,0x32,0x5b,0x38,0x5d,0x3b,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x74,0x61,0x74,0x65,0x5b,0x32,0x35,0x5d,0x3b,
0x20,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x31,0x30,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x73,0x74,0x61,0x74,0x65,
0x5b,0x69,0x5d,0x3d,0x6a,0x6f,0x62,0x5f,0x62,0x6c,0x6f,0x62,0x5b,0x69,0x5d,0x3b,0x0a,0x73,0x74,0x61,0x74,0x65,0x5b,0x38,0x5d,0x3d,0x67,0x69,0x64,0x3b,0x0a,0x66,
0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x31,0x30,0x3b,0x20,0x69,0x3c,0x32,0x35,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x73,0x74,0x61,0x74,0x65,0x5b,0x69,
0x5d,0x3d,0x72,0x61,0x76,0x65,0x6e,0x63,0x6f,0x69,0x6e,0x5f,0x72,0x6e,0x64,0x63,0x5b,0x69,0x2d,0x31,0x30,0x5d,0x3b,0x0a,0x6b,0x65,0x63,0x63,0x61,0x6b,0x5f,0x66,
0x38,0x30,0x30,0x28,0x73,0x74,0x61,0x74,0x65,0x29,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x38,0x3b,0x20,0x69,
0x2b,0x2b,0x29,0x0a,0x73,0x74,0x61,0x74,0x65,0x32,0x5b,0x69,0x5d,0x3d,0x73,0x74,0x61,0x74,0x65,0x5b,0x69,0x5d,0x3b,0x0a,0x7d,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,
0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x31,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x68,0x3d,0x30,0x3b,0x20,0x68,0x3c,
0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x4c,0x41,0x4e,0x45,0x53,0x3b,0x20,0x68,0x2b,0x2b,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6d,
0x69,0x78,0x5b,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x52,0x45,0x47,0x53,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,0x3d,0x3d,0x68,0x29,
0x20,0x7b,0x0a,0x73,0x68,0x61,0x72,0x65,0x5b,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x30,0x5d,0x3d,0x73,0x74,
0x61,0x74,0x65,0x32,0x5b,0x30,0x5d,0x3b,0x0a,0x73,0x68,0x61,0x72,0x65,0x5b,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,
0x5b,0x31,0x5d,0x3d,0x73,0x74,0x61,0x74,0x65,0x32,0x5b,0x31,0x5d,0x3b,0x0a,0x7d,0x0a,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,
0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x66,0x69,0x6c,0x6c,0x5f,0x6d,0x69,0x78,0x28,0x73,0x68,0x61,0x72,0x65,0x5b,0x67,0x72,
0x6f,0x75,0x70,0x5f,0x69,0x64,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x2c,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,0x2c,0x6d,0x69,0x78,0x29,0x3b,0x0a,0x23,0x70,
0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x32,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x6f,0x6f,
0x70,0x3d,0x30,0x3b,0x20,0x6c,0x6f,0x6f,0x70,0x3c,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x43,0x4e,0x54,0x5f,0x44,0x41,0x47,0x3b,0x20,0x2b,0x2b,0x6c,0x6f,0x6f,
0x70,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,0x3d,0x3d,0x28,0x6c,0x6f,0x6f,0x70,0x20,0x25,0x20,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,
0x5f,0x4c,0x41,0x4e,0x45,0x53,0x29,0x29,0x0a,0x73,0x68,0x61,0x72,0x65,0x5b,0x30,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x67,0x72,0x6f,0x75,0x70,0x5f,
0x69,0x64,0x5d,0x3d,0x6d,0x69,0x78,0x5b,0x30,0x5d,0x3b,0x0a,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,
0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x73,0x68,0x61,0x72,0x65,0x5b,
0x30,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x5d,0x3b,0x0a,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x25,0x3d,0x20,
0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x44,0x41,0x47,0x5f,0x45,0x4c,0x45,0x4d,0x45,0x4e,0x54,0x53,0x3b,0x0a,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x6f,0x66,0x66,
0x73,0x65,0x74,0x2a,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x4c,0x41,0x4e,0x45,0x53,0x2b,0x28,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,0x5e,0x6c,0x6f,0x6f,0x70,0x29,
0x20,0x25,0x20,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x4c,0x41,0x4e,0x45,0x53,0x3b,0x0a,0x64,0x61,0x67,0x5f,0x74,0x20,0x64,0x61,0x74,0x61,0x5f,0x64,0x61,0x67,
0x3d,0x67,0x5f,0x64,0x61,0x67,0x5b,0x6f,0x66,0x66,0x73,0x65,0x74,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x68,0x61,0x63,0x6b,0x5f,0x66,0x61,0x6c,0x73,0x65,0x29,0x20,0x62,
0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x75,0x69,0x6e,
0x74,0x33,0x32,0x5f,0x74,0x20,0x64,0x61,0x74,0x61,0x3b,0x0a,0x58,0x4d,0x52,0x49,0x47,0x5f,0x49,0x4e,0x43,0x4c,0x55,0x44,0x45,0x5f,0x50,0x52,0x4f,0x47,0x50,0x4f,
0x57,0x5f,0x52,0x41,0x4e,0x44,0x4f,0x4d,0x5f,0x4d,0x41,0x54,0x48,0x0a,0x69,0x66,0x28,0x68,0x61,0x63,0x6b,0x5f,0x66,0x61,0x6c,0x73,0x65,0x29,0x20,0x62,0x61,0x72,
0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x58,0x4d,0x52,0x49,0x47,
0x5f,0x49,0x4e,0x43,0x4c,0x55,0x44,0x45,0x5f,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x44,0x41,0x54,0x41,0x5f,0x4c,0x4f,0x41,0x44,0x53,0x0a,0x7d,0x0a,0x75,0x69,
0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6d,0x69,0x78,0x5f,0x68,0x61,0x73,0x68,0x3d,0x46,0x4e,0x56,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x5f,0x42,0x41,0x53,0x49,0x53,
0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,
0x3c,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x52,0x45,0x47,0x53,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x66,0x6e,0x76,0x31,0x61,0x28,0x6d,0x69,0x78,0x5f,0x68,0x61,
0x73,0x68,0x2c,0x6d,0x69,0x78,0x5b,0x69,0x5d,0x29,0x3b,0x0a,0x68,0x61,0x73,0x68,0x33,0x32,0x5f,0x74,0x20,0x64,0x69,0x67,0x65,0x73,0x74,0x5f,0x74,0x65,0x6d,0x70,
0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x38,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x64,0x69,0x67,0x65,0x73,0x74,
0x5f,0x74,0x65,0x6d,0x70,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x69,0x5d,0x3d,0x46,0x4e,0x56,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x5f,0x42,0x41,0x53,0x49,
0x53,0x3b,0x0a,0x73,0x68,0x61,0x72,0x65,0x5b,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x6c,0x61,0x6e,0x65,0x5f,
0x69,0x64,0x5d,0x3d,0x6d,0x69,0x78,0x5f,0x68,0x61,0x73,0x68,0x3b,0x0a,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,
0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x0a,0x66,0x6f,0x72,0x20,0x28,
0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x4c,0x41,0x4e,0x45,0x53,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x66,
0x6e,0x76,0x31,0x61,0x28,0x64,0x69,0x67,0x65,0x73,0x74,0x5f,0x74,0x65,0x6d,0x70,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x69,0x20,0x25,0x20,0x38,0x5d,0x2c,
0x73,0x68,0x61,0x72,0x65,0x5b,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x69,0x5d,0x29,0x3b,0x0a,0x69,0x66,0x28,
0x68,0x3d,0x3d,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,0x29,0x0a,0x64,0x69,0x67,0x65,0x73,0x74,0x3d,0x64,0x69,0x67,0x65,0x73,0x74,0x5f,0x74,0x65,0x6d,0x70,0x3b,0x0a,
0x7d,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x3b,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x74,
0x61,0x74,0x65,0x5b,0x32,0x35,0x5d,0x3d,0x7b,0x30,0x78,0x30,0x7d,0x3b,0x20,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,
0x38,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x73,0x74,0x61,0x74,0x65,0x5b,0x69,0x5d,0x3d,0x73,0x74,0x61,0x74,0x65,0x32,0x5b,0x69,0x5d,0x3b,0x0a,0x66,0x6f,0x72,0x20,
0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x38,0x3b,0x20,0x69,0x3c,0x31,0x36,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x73,0x74,0x61,0x74,0x65,0x5b,0x69,0x5d,0x3d,0x64,0x69,
0x67,0x65,0x73,0x74,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x69,0x2d,0x38,0x5d,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x31,0x36,
0x3b,0x20,0x69,0x3c,0x32,0x35,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x73,0x74,0x61,0x74,0x65,0x5b,0x69,0x5d,0x3d,0x72,0x61,0x76,0x65,0x6e,0x63,0x6f,0x69,0x6e,0x5f,
0x72,0x6e,0x64,0x63,0x5b,0x69,0x2d,0x31,0x36,0x5d,0x3b,0x0a,0x6b,0x65,0x63,0x63,0x61,0x6b,0x5f,0x66,0x38,0x30,0x30,0x28,0x73,0x74,0x61,0x74,0x65,0x29,0x3b,0x0a,
0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x72,0x65,0x73,0x3d,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x73,0x74,0x61,0x74,0x65,0x5b,0x31,0x5d,0x3c,
0x3c,0x33,0x32,0x7c,0x73,0x74,0x61,0x74,0x65,0x5b,0x30,0x5d,0x3b,0x0a,0x72,0x65,0x73,0x75,0x6c,0x74,0x3d,0x61,0x73,0x5f,0x75,0x6c,0x6f,0x6e,0x67,0x28,0x61,0x73,
0x5f,0x75,0x63,0x68,0x61,0x72,0x38,0x28,0x72,0x65,0x73,0x29,0x2e,0x73,0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30,0x29,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x72,0x65,
0x73,0x75,0x6c,0x74,0x3c,0x3d,0x74,0x61,0x72,0x67,0x65,0x74,0x29,0x0a,0x7b,0x0a,0x2a,0x73,0x74,0x6f,0x70,0x3d,0x31,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,
0x69,0x6e,0x74,0x20,0x6b,0x3d,0x61,0x74,0x6f,0x6d,0x69,0x63,0x5f,0x69,0x6e,0x63,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x73,0x29,0x2b,0x31,0x3b,0x0a,0x69,0x66,0x28,
0x6b,0x3c,0x3d,0x31,0x35,0x29,0x0a,0x72,0x65,0x73,0x75,0x6c,0x74,0x73,0x5b,0x6b,0x5d,0x3d,0x67,0x69,0x64,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x00
0x72,0x6e,0x64,0x63,0x5b,0x72,0x5d,0x3b,0x0a,0x7d,0x0a,0x76,0x6f,0x69,0x64,0x20,0x6b,0x65,0x63,0x63,0x61,0x6b,0x5f,0x66,0x38,0x30,0x30,0x28,0x75,0x69,0x6e,0x74,
0x33,0x32,0x5f,0x74,0x2a,0x20,0x73,0x74,0x29,0x0a,0x7b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x72,0x3d,0x30,0x3b,0x20,0x72,0x3c,0x32,0x32,0x3b,0x20,
0x72,0x2b,0x2b,0x29,0x20,0x7b,0x0a,0x6b,0x65,0x63,0x63,0x61,0x6b,0x5f,0x66,0x38,0x30,0x30,0x5f,0x72,0x6f,0x75,0x6e,0x64,0x28,0x73,0x74,0x2c,0x72,0x29,0x3b,0x0a,
0x7d,0x0a,0x7d,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x66,0x6e,0x76,0x31,0x61,0x28,0x68,0x2c,0x20,0x64,0x29,0x20,0x28,0x68,0x20,0x3d,0x20,0x28,0x68,0x20,
0x5e,0x20,0x64,0x29,0x20,0x2a,0x20,0x46,0x4e,0x56,0x5f,0x50,0x52,0x49,0x4d,0x45,0x29,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x73,0x74,0x72,0x75,0x63,0x74,
0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x7a,0x2c,0x77,0x2c,0x6a,0x73,0x72,0x2c,0x6a,0x63,0x6f,0x6e,0x67,0x3b,0x0a,0x7d,0x20,0x6b,0x69,0x73,
0x73,0x39,0x39,0x5f,0x74,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6b,0x69,0x73,0x73,0x39,0x39,0x28,0x6b,0x69,0x73,0x73,0x39,0x39,0x5f,0x74,0x2a,
0x20,0x73,0x74,0x29,0x0a,0x7b,0x0a,0x73,0x74,0x2d,0x3e,0x7a,0x3d,0x33,0x36,0x39,0x36,0x39,0x2a,0x28,0x73,0x74,0x2d,0x3e,0x7a,0x26,0x36,0x35,0x35,0x33,0x35,0x29,
0x2b,0x28,0x73,0x74,0x2d,0x3e,0x7a,0x3e,0x3e,0x31,0x36,0x29,0x3b,0x0a,0x73,0x74,0x2d,0x3e,0x77,0x3d,0x31,0x38,0x30,0x30,0x30,0x2a,0x28,0x73,0x74,0x2d,0x3e,0x77,
0x26,0x36,0x35,0x35,0x33,0x35,0x29,0x2b,0x28,0x73,0x74,0x2d,0x3e,0x77,0x3e,0x3e,0x31,0x36,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x4d,0x57,
0x43,0x3d,0x28,0x28,0x73,0x74,0x2d,0x3e,0x7a,0x3c,0x3c,0x31,0x36,0x29,0x2b,0x73,0x74,0x2d,0x3e,0x77,0x29,0x3b,0x0a,0x73,0x74,0x2d,0x3e,0x6a,0x73,0x72,0x20,0x5e,
0x3d,0x20,0x28,0x73,0x74,0x2d,0x3e,0x6a,0x73,0x72,0x3c,0x3c,0x31,0x37,0x29,0x3b,0x0a,0x73,0x74,0x2d,0x3e,0x6a,0x73,0x72,0x20,0x5e,0x3d,0x20,0x28,0x73,0x74,0x2d,
0x3e,0x6a,0x73,0x72,0x3e,0x3e,0x31,0x33,0x29,0x3b,0x0a,0x73,0x74,0x2d,0x3e,0x6a,0x73,0x72,0x20,0x5e,0x3d,0x20,0x28,0x73,0x74,0x2d,0x3e,0x6a,0x73,0x72,0x3c,0x3c,
0x35,0x29,0x3b,0x0a,0x73,0x74,0x2d,0x3e,0x6a,0x63,0x6f,0x6e,0x67,0x3d,0x36,0x39,0x30,0x36,0x39,0x2a,0x73,0x74,0x2d,0x3e,0x6a,0x63,0x6f,0x6e,0x67,0x2b,0x31,0x32,
0x33,0x34,0x35,0x36,0x37,0x3b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x28,0x28,0x4d,0x57,0x43,0x5e,0x73,0x74,0x2d,0x3e,0x6a,0x63,0x6f,0x6e,0x67,0x29,0x2b,0x73,
0x74,0x2d,0x3e,0x6a,0x73,0x72,0x29,0x3b,0x0a,0x7d,0x0a,0x76,0x6f,0x69,0x64,0x20,0x66,0x69,0x6c,0x6c,0x5f,0x6d,0x69,0x78,0x28,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,
0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x73,0x65,0x65,0x64,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,0x2c,0x75,
0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x6d,0x69,0x78,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x66,0x6e,0x76,0x5f,0x68,0x61,0x73,
0x68,0x3d,0x46,0x4e,0x56,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x5f,0x42,0x41,0x53,0x49,0x53,0x3b,0x0a,0x6b,0x69,0x73,0x73,0x39,0x39,0x5f,0x74,0x20,0x73,0x74,0x3b,
0x0a,0x73,0x74,0x2e,0x7a,0x3d,0x66,0x6e,0x76,0x31,0x61,0x28,0x66,0x6e,0x76,0x5f,0x68,0x61,0x73,0x68,0x2c,0x73,0x65,0x65,0x64,0x5b,0x30,0x5d,0x29,0x3b,0x0a,0x73,
0x74,0x2e,0x77,0x3d,0x66,0x6e,0x76,0x31,0x61,0x28,0x66,0x6e,0x76,0x5f,0x68,0x61,0x73,0x68,0x2c,0x73,0x65,0x65,0x64,0x5b,0x31,0x5d,0x29,0x3b,0x0a,0x73,0x74,0x2e,
0x6a,0x73,0x72,0x3d,0x66,0x6e,0x76,0x31,0x61,0x28,0x66,0x6e,0x76,0x5f,0x68,0x61,0x73,0x68,0x2c,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,0x29,0x3b,0x0a,0x73,0x74,0x2e,
0x6a,0x63,0x6f,0x6e,0x67,0x3d,0x66,0x6e,0x76,0x31,0x61,0x28,0x66,0x6e,0x76,0x5f,0x68,0x61,0x73,0x68,0x2c,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,0x29,0x3b,0x0a,0x23,
0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x50,0x52,
0x4f,0x47,0x50,0x4f,0x57,0x5f,0x52,0x45,0x47,0x53,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x6d,0x69,0x78,0x5b,0x69,0x5d,0x3d,0x6b,0x69,0x73,0x73,0x39,0x39,0x28,0x26,
0x73,0x74,0x29,0x3b,0x0a,0x7d,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x73,0x74,0x72,0x75,0x63,0x74,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,
0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x4c,0x41,0x4e,0x45,0x53,0x5d,0x3b,0x0a,0x7d,0x20,0x73,0x68,0x75,0x66,0x66,
0x6c,0x65,0x5f,0x74,0x3b,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x73,0x74,0x72,0x75,0x63,0x74,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,
0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x33,0x32,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x5d,0x3b,0x0a,0x7d,0x20,
0x68,0x61,0x73,0x68,0x33,0x32,0x5f,0x74,0x3b,0x0a,0x23,0x69,0x66,0x20,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x20,0x21,0x3d,0x20,0x4f,0x50,0x45,0x4e,0x43,0x4c,
0x5f,0x50,0x4c,0x41,0x54,0x46,0x4f,0x52,0x4d,0x5f,0x4e,0x56,0x49,0x44,0x49,0x41,0x20,0x0a,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,
0x28,0x72,0x65,0x71,0x64,0x5f,0x77,0x6f,0x72,0x6b,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x28,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,
0x2c,0x31,0x2c,0x31,0x29,0x29,0x29,0x0a,0x23,0x65,0x6e,0x64,0x69,0x66,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x70,0x72,0x6f,
0x67,0x70,0x6f,0x77,0x5f,0x73,0x65,0x61,0x72,0x63,0x68,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x64,0x61,0x67,0x5f,0x74,0x20,0x63,0x6f,0x6e,0x73,0x74,
0x2a,0x20,0x67,0x5f,0x64,0x61,0x67,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x6a,0x6f,0x62,0x5f,0x62,0x6c,0x6f,0x62,0x2c,
0x75,0x6c,0x6f,0x6e,0x67,0x20,0x74,0x61,0x72,0x67,0x65,0x74,0x2c,0x75,0x69,0x6e,0x74,0x20,0x68,0x61,0x63,0x6b,0x5f,0x66,0x61,0x6c,0x73,0x65,0x2c,0x76,0x6f,0x6c,
0x61,0x74,0x69,0x6c,0x65,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x73,0x2c,0x76,0x6f,0x6c,
0x61,0x74,0x69,0x6c,0x65,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x2a,0x20,0x73,0x74,0x6f,0x70,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,
0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x69,0x64,0x3d,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,
0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x67,0x69,0x64,0x3d,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,
0x64,0x28,0x30,0x29,0x3b,0x0a,0x69,0x66,0x28,0x73,0x74,0x6f,0x70,0x5b,0x30,0x5d,0x29,0x20,0x7b,0x0a,0x69,0x66,0x28,0x6c,0x69,0x64,0x3d,0x3d,0x30,0x29,0x20,0x7b,
0x0a,0x61,0x74,0x6f,0x6d,0x69,0x63,0x5f,0x69,0x6e,0x63,0x28,0x73,0x74,0x6f,0x70,0x2b,0x31,0x29,0x3b,0x0a,0x7d,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x0a,0x7d,
0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x73,0x68,0x75,0x66,0x66,0x6c,0x65,0x5f,0x74,0x20,0x73,0x68,0x61,0x72,0x65,0x5b,0x48,0x41,0x53,0x48,0x45,0x53,0x5f,
0x50,0x45,0x52,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5d,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x63,0x5f,0x64,
0x61,0x67,0x5b,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x43,0x41,0x43,0x48,0x45,0x5f,0x57,0x4f,0x52,0x44,0x53,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,
0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,0x3d,0x6c,0x69,0x64,0x26,0x28,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x4c,0x41,0x4e,
0x45,0x53,0x2d,0x31,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x3d,0x6c,
0x69,0x64,0x2f,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x4c,0x41,0x4e,0x45,0x53,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,
0x77,0x6f,0x72,0x64,0x3d,0x6c,0x69,0x64,0x2a,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x44,0x41,0x47,0x5f,0x4c,0x4f,0x41,0x44,0x53,0x3b,0x20,0x77,0x6f,0x72,0x64,
0x3c,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x43,0x41,0x43,0x48,0x45,0x5f,0x57,0x4f,0x52,0x44,0x53,0x3b,0x20,0x77,0x6f,0x72,0x64,0x2b,0x3d,0x47,0x52,0x4f,0x55,
0x50,0x5f,0x53,0x49,0x5a,0x45,0x2a,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x44,0x41,0x47,0x5f,0x4c,0x4f,0x41,0x44,0x53,0x29,0x0a,0x7b,0x0a,0x64,0x61,0x67,0x5f,
0x74,0x20,0x6c,0x6f,0x61,0x64,0x3d,0x67,0x5f,0x64,0x61,0x67,0x5b,0x77,0x6f,0x72,0x64,0x2f,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x44,0x41,0x47,0x5f,0x4c,0x4f,
0x41,0x44,0x53,0x5d,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x44,0x41,
0x47,0x5f,0x4c,0x4f,0x41,0x44,0x53,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x63,0x5f,0x64,0x61,0x67,0x5b,0x77,0x6f,0x72,0x64,0x2b,0x69,0x5d,0x3d,0x6c,0x6f,0x61,0x64,
0x2e,0x73,0x5b,0x69,0x5d,0x3b,0x0a,0x7d,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x68,0x61,0x73,0x68,0x5f,0x73,0x65,0x65,0x64,0x5b,0x32,0x5d,0x3b,0x20,
0x0a,0x68,0x61,0x73,0x68,0x33,0x32,0x5f,0x74,0x20,0x64,0x69,0x67,0x65,0x73,0x74,0x3b,0x20,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x74,0x61,0x74,
0x65,0x32,0x5b,0x38,0x5d,0x3b,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x74,0x61,0x74,0x65,0x5b,0x32,0x35,0x5d,0x3b,0x20,0x0a,0x66,0x6f,
0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x31,0x30,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x73,0x74,0x61,0x74,0x65,0x5b,0x69,0x5d,0x3d,
0x6a,0x6f,0x62,0x5f,0x62,0x6c,0x6f,0x62,0x5b,0x69,0x5d,0x3b,0x0a,0x73,0x74,0x61,0x74,0x65,0x5b,0x38,0x5d,0x3d,0x67,0x69,0x64,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,
0x69,0x6e,0x74,0x20,0x69,0x3d,0x31,0x30,0x3b,0x20,0x69,0x3c,0x32,0x35,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x73,0x74,0x61,0x74,0x65,0x5b,0x69,0x5d,0x3d,0x72,0x61,
0x76,0x65,0x6e,0x63,0x6f,0x69,0x6e,0x5f,0x72,0x6e,0x64,0x63,0x5b,0x69,0x2d,0x31,0x30,0x5d,0x3b,0x0a,0x6b,0x65,0x63,0x63,0x61,0x6b,0x5f,0x66,0x38,0x30,0x30,0x28,
0x73,0x74,0x61,0x74,0x65,0x29,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x38,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,
0x73,0x74,0x61,0x74,0x65,0x32,0x5b,0x69,0x5d,0x3d,0x73,0x74,0x61,0x74,0x65,0x5b,0x69,0x5d,0x3b,0x0a,0x7d,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,
0x72,0x6f,0x6c,0x6c,0x20,0x31,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x68,0x3d,0x30,0x3b,0x20,0x68,0x3c,0x50,0x52,0x4f,0x47,
0x50,0x4f,0x57,0x5f,0x4c,0x41,0x4e,0x45,0x53,0x3b,0x20,0x68,0x2b,0x2b,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6d,0x69,0x78,0x5b,0x50,
0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x52,0x45,0x47,0x53,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,0x3d,0x3d,0x68,0x29,0x20,0x7b,0x0a,0x73,
0x68,0x61,0x72,0x65,0x5b,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x30,0x5d,0x3d,0x73,0x74,0x61,0x74,0x65,0x32,
0x5b,0x30,0x5d,0x3b,0x0a,0x73,0x68,0x61,0x72,0x65,0x5b,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x31,0x5d,0x3d,
0x73,0x74,0x61,0x74,0x65,0x32,0x5b,0x31,0x5d,0x3b,0x0a,0x7d,0x0a,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,
0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x66,0x69,0x6c,0x6c,0x5f,0x6d,0x69,0x78,0x28,0x73,0x68,0x61,0x72,0x65,0x5b,0x67,0x72,0x6f,0x75,0x70,0x5f,
0x69,0x64,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x2c,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,0x2c,0x6d,0x69,0x78,0x29,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,
0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x32,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x6f,0x6f,0x70,0x3d,0x30,0x3b,
0x20,0x6c,0x6f,0x6f,0x70,0x3c,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x43,0x4e,0x54,0x5f,0x44,0x41,0x47,0x3b,0x20,0x2b,0x2b,0x6c,0x6f,0x6f,0x70,0x29,0x0a,0x7b,
0x0a,0x69,0x66,0x28,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,0x3d,0x3d,0x28,0x6c,0x6f,0x6f,0x70,0x20,0x25,0x20,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x4c,0x41,0x4e,
0x45,0x53,0x29,0x29,0x0a,0x73,0x68,0x61,0x72,0x65,0x5b,0x30,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x5d,0x3d,
0x6d,0x69,0x78,0x5b,0x30,0x5d,0x3b,0x0a,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,
0x4e,0x43,0x45,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x73,0x68,0x61,0x72,0x65,0x5b,0x30,0x5d,0x2e,0x75,
0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x5d,0x3b,0x0a,0x6f,0x66,0x66,0x73,0x65,0x74,0x20,0x25,0x3d,0x20,0x50,0x52,0x4f,0x47,
0x50,0x4f,0x57,0x5f,0x44,0x41,0x47,0x5f,0x45,0x4c,0x45,0x4d,0x45,0x4e,0x54,0x53,0x3b,0x0a,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x6f,0x66,0x66,0x73,0x65,0x74,0x2a,
0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x4c,0x41,0x4e,0x45,0x53,0x2b,0x28,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,0x5e,0x6c,0x6f,0x6f,0x70,0x29,0x20,0x25,0x20,0x50,
0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x4c,0x41,0x4e,0x45,0x53,0x3b,0x0a,0x64,0x61,0x67,0x5f,0x74,0x20,0x64,0x61,0x74,0x61,0x5f,0x64,0x61,0x67,0x3d,0x67,0x5f,0x64,
0x61,0x67,0x5b,0x6f,0x66,0x66,0x73,0x65,0x74,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x68,0x61,0x63,0x6b,0x5f,0x66,0x61,0x6c,0x73,0x65,0x29,0x20,0x62,0x61,0x72,0x72,0x69,
0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
0x74,0x20,0x64,0x61,0x74,0x61,0x3b,0x0a,0x58,0x4d,0x52,0x49,0x47,0x5f,0x49,0x4e,0x43,0x4c,0x55,0x44,0x45,0x5f,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x52,0x41,
0x4e,0x44,0x4f,0x4d,0x5f,0x4d,0x41,0x54,0x48,0x0a,0x69,0x66,0x28,0x68,0x61,0x63,0x6b,0x5f,0x66,0x61,0x6c,0x73,0x65,0x29,0x20,0x62,0x61,0x72,0x72,0x69,0x65,0x72,
0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x58,0x4d,0x52,0x49,0x47,0x5f,0x49,0x4e,0x43,
0x4c,0x55,0x44,0x45,0x5f,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x44,0x41,0x54,0x41,0x5f,0x4c,0x4f,0x41,0x44,0x53,0x0a,0x7d,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,
0x5f,0x74,0x20,0x6d,0x69,0x78,0x5f,0x68,0x61,0x73,0x68,0x3d,0x46,0x4e,0x56,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x5f,0x42,0x41,0x53,0x49,0x53,0x3b,0x0a,0x23,0x70,
0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x50,0x52,0x4f,
0x47,0x50,0x4f,0x57,0x5f,0x52,0x45,0x47,0x53,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x66,0x6e,0x76,0x31,0x61,0x28,0x6d,0x69,0x78,0x5f,0x68,0x61,0x73,0x68,0x2c,0x6d,
0x69,0x78,0x5b,0x69,0x5d,0x29,0x3b,0x0a,0x68,0x61,0x73,0x68,0x33,0x32,0x5f,0x74,0x20,0x64,0x69,0x67,0x65,0x73,0x74,0x5f,0x74,0x65,0x6d,0x70,0x3b,0x0a,0x66,0x6f,
0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x38,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x64,0x69,0x67,0x65,0x73,0x74,0x5f,0x74,0x65,0x6d,
0x70,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x69,0x5d,0x3d,0x46,0x4e,0x56,0x5f,0x4f,0x46,0x46,0x53,0x45,0x54,0x5f,0x42,0x41,0x53,0x49,0x53,0x3b,0x0a,0x73,
0x68,0x61,0x72,0x65,0x5b,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x6c,0x61,0x6e,0x65,0x5f,0x69,0x64,0x5d,0x3d,
0x6d,0x69,0x78,0x5f,0x68,0x61,0x73,0x68,0x3b,0x0a,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,
0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,
0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x50,0x52,0x4f,0x47,0x50,0x4f,0x57,0x5f,0x4c,0x41,0x4e,0x45,0x53,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x66,0x6e,0x76,0x31,0x61,
0x28,0x64,0x69,0x67,0x65,0x73,0x74,0x5f,0x74,0x65,0x6d,0x70,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x69,0x20,0x25,0x20,0x38,0x5d,0x2c,0x73,0x68,0x61,0x72,
0x65,0x5b,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x5d,0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x69,0x5d,0x29,0x3b,0x0a,0x69,0x66,0x28,0x68,0x3d,0x3d,0x6c,
0x61,0x6e,0x65,0x5f,0x69,0x64,0x29,0x0a,0x64,0x69,0x67,0x65,0x73,0x74,0x3d,0x64,0x69,0x67,0x65,0x73,0x74,0x5f,0x74,0x65,0x6d,0x70,0x3b,0x0a,0x7d,0x0a,0x75,0x69,
0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x3b,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x74,0x61,0x74,0x65,0x5b,
0x32,0x35,0x5d,0x3d,0x7b,0x30,0x78,0x30,0x7d,0x3b,0x20,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x38,0x3b,0x20,0x69,
0x2b,0x2b,0x29,0x0a,0x73,0x74,0x61,0x74,0x65,0x5b,0x69,0x5d,0x3d,0x73,0x74,0x61,0x74,0x65,0x32,0x5b,0x69,0x5d,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,
0x20,0x69,0x3d,0x38,0x3b,0x20,0x69,0x3c,0x31,0x36,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x73,0x74,0x61,0x74,0x65,0x5b,0x69,0x5d,0x3d,0x64,0x69,0x67,0x65,0x73,0x74,
0x2e,0x75,0x69,0x6e,0x74,0x33,0x32,0x73,0x5b,0x69,0x2d,0x38,0x5d,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x31,0x36,0x3b,0x20,0x69,0x3c,
0x32,0x35,0x3b,0x20,0x69,0x2b,0x2b,0x29,0x0a,0x73,0x74,0x61,0x74,0x65,0x5b,0x69,0x5d,0x3d,0x72,0x61,0x76,0x65,0x6e,0x63,0x6f,0x69,0x6e,0x5f,0x72,0x6e,0x64,0x63,
0x5b,0x69,0x2d,0x31,0x36,0x5d,0x3b,0x0a,0x6b,0x65,0x63,0x63,0x61,0x6b,0x5f,0x66,0x38,0x30,0x30,0x28,0x73,0x74,0x61,0x74,0x65,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,
0x36,0x34,0x5f,0x74,0x20,0x72,0x65,0x73,0x3d,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x73,0x74,0x61,0x74,0x65,0x5b,0x31,0x5d,0x3c,0x3c,0x33,0x32,0x7c,
0x73,0x74,0x61,0x74,0x65,0x5b,0x30,0x5d,0x3b,0x0a,0x72,0x65,0x73,0x75,0x6c,0x74,0x3d,0x61,0x73,0x5f,0x75,0x6c,0x6f,0x6e,0x67,0x28,0x61,0x73,0x5f,0x75,0x63,0x68,
0x61,0x72,0x38,0x28,0x72,0x65,0x73,0x29,0x2e,0x73,0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30,0x29,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,
0x3c,0x3d,0x74,0x61,0x72,0x67,0x65,0x74,0x29,0x0a,0x7b,0x0a,0x2a,0x73,0x74,0x6f,0x70,0x3d,0x31,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x20,
0x6b,0x3d,0x61,0x74,0x6f,0x6d,0x69,0x63,0x5f,0x69,0x6e,0x63,0x28,0x72,0x65,0x73,0x75,0x6c,0x74,0x73,0x29,0x2b,0x31,0x3b,0x0a,0x69,0x66,0x28,0x6b,0x3c,0x3d,0x31,
0x35,0x29,0x0a,0x72,0x65,0x73,0x75,0x6c,0x74,0x73,0x5b,0x6b,0x5d,0x3d,0x67,0x69,0x64,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x00
};
} // namespace xmrig

View File

@@ -4,12 +4,8 @@
#include "randomx_constants_monero.h"
#elif (ALGO == ALGO_RX_WOW)
#include "randomx_constants_wow.h"
#elif (ALGO == ALGO_RX_ARQ)
#elif (ALGO == ALGO_RX_ARQMA)
#include "randomx_constants_arqma.h"
#elif (ALGO == ALGO_RX_XEQ)
#include "randomx_constants_equilibria.h"
#elif (ALGO == ALGO_RX_KEVA)
#include "randomx_constants_keva.h"
#elif (ALGO == ALGO_RX_GRAFT)
#include "randomx_constants_graft.h"
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,96 +0,0 @@
/*
Copyright (c) 2019 SChernykh
This file is part of RandomX OpenCL.
RandomX OpenCL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
RandomX OpenCL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with RandomX OpenCL. If not, see <http://www.gnu.org/licenses/>.
*/
//Dataset base size in bytes. Must be a power of 2.
#define RANDOMX_DATASET_BASE_SIZE 2147483648
//Dataset extra size. Must be divisible by 64.
#define RANDOMX_DATASET_EXTRA_SIZE 33554368
//Scratchpad L3 size in bytes. Must be a power of 2.
#define RANDOMX_SCRATCHPAD_L3 262144
//Scratchpad L2 size in bytes. Must be a power of two and less than or equal to RANDOMX_SCRATCHPAD_L3.
#define RANDOMX_SCRATCHPAD_L2 131072
//Scratchpad L1 size in bytes. Must be a power of two (minimum 64) and less than or equal to RANDOMX_SCRATCHPAD_L2.
#define RANDOMX_SCRATCHPAD_L1 16384
//Jump condition mask size in bits.
#define RANDOMX_JUMP_BITS 8
//Jump condition mask offset in bits. The sum of RANDOMX_JUMP_BITS and RANDOMX_JUMP_OFFSET must not exceed 16.
#define RANDOMX_JUMP_OFFSET 8
//Integer instructions
#define RANDOMX_FREQ_IADD_RS 16
#define RANDOMX_FREQ_IADD_M 7
#define RANDOMX_FREQ_ISUB_R 16
#define RANDOMX_FREQ_ISUB_M 7
#define RANDOMX_FREQ_IMUL_R 16
#define RANDOMX_FREQ_IMUL_M 4
#define RANDOMX_FREQ_IMULH_R 4
#define RANDOMX_FREQ_IMULH_M 1
#define RANDOMX_FREQ_ISMULH_R 4
#define RANDOMX_FREQ_ISMULH_M 1
#define RANDOMX_FREQ_IMUL_RCP 8
#define RANDOMX_FREQ_INEG_R 2
#define RANDOMX_FREQ_IXOR_R 15
#define RANDOMX_FREQ_IXOR_M 5
#define RANDOMX_FREQ_IROR_R 8
#define RANDOMX_FREQ_IROL_R 2
#define RANDOMX_FREQ_ISWAP_R 4
//Floating point instructions
#define RANDOMX_FREQ_FSWAP_R 4
#define RANDOMX_FREQ_FADD_R 16
#define RANDOMX_FREQ_FADD_M 5
#define RANDOMX_FREQ_FSUB_R 16
#define RANDOMX_FREQ_FSUB_M 5
#define RANDOMX_FREQ_FSCAL_R 6
#define RANDOMX_FREQ_FMUL_R 32
#define RANDOMX_FREQ_FDIV_M 4
#define RANDOMX_FREQ_FSQRT_R 6
//Control instructions
#define RANDOMX_FREQ_CBRANCH 25
#define RANDOMX_FREQ_CFROUND 1
//Store instruction
#define RANDOMX_FREQ_ISTORE 16
//No-op instruction
#define RANDOMX_FREQ_NOP 0
#define RANDOMX_DATASET_ITEM_SIZE 64
#define RANDOMX_PROGRAM_SIZE 256
#define HASH_SIZE 64
#define ENTROPY_SIZE (128 + RANDOMX_PROGRAM_SIZE * 8)
#define REGISTERS_SIZE 256
#define IMM_BUF_SIZE (RANDOMX_PROGRAM_SIZE * 4 - REGISTERS_SIZE)
#define IMM_INDEX_COUNT ((IMM_BUF_SIZE / 4) - 2)
#define VM_STATE_SIZE (REGISTERS_SIZE + IMM_BUF_SIZE + RANDOMX_PROGRAM_SIZE * 4)
#define ROUNDING_MODE (RANDOMX_FREQ_CFROUND ? -1 : 0)
// Scratchpad L1/L2/L3 bits
#define LOC_L1 (32 - 14)
#define LOC_L2 (32 - 17)
#define LOC_L3 (32 - 18)

View File

@@ -1,96 +0,0 @@
/*
Copyright (c) 2019 SChernykh
This file is part of RandomX OpenCL.
RandomX OpenCL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
RandomX OpenCL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with RandomX OpenCL. If not, see <http://www.gnu.org/licenses/>.
*/
//Dataset base size in bytes. Must be a power of 2.
#define RANDOMX_DATASET_BASE_SIZE 2147483648
//Dataset extra size. Must be divisible by 64.
#define RANDOMX_DATASET_EXTRA_SIZE 33554368
//Scratchpad L3 size in bytes. Must be a power of 2.
#define RANDOMX_SCRATCHPAD_L3 1048576
//Scratchpad L2 size in bytes. Must be a power of two and less than or equal to RANDOMX_SCRATCHPAD_L3.
#define RANDOMX_SCRATCHPAD_L2 131072
//Scratchpad L1 size in bytes. Must be a power of two (minimum 64) and less than or equal to RANDOMX_SCRATCHPAD_L2.
#define RANDOMX_SCRATCHPAD_L1 16384
//Jump condition mask size in bits.
#define RANDOMX_JUMP_BITS 8
//Jump condition mask offset in bits. The sum of RANDOMX_JUMP_BITS and RANDOMX_JUMP_OFFSET must not exceed 16.
#define RANDOMX_JUMP_OFFSET 8
//Integer instructions
#define RANDOMX_FREQ_IADD_RS 16
#define RANDOMX_FREQ_IADD_M 7
#define RANDOMX_FREQ_ISUB_R 16
#define RANDOMX_FREQ_ISUB_M 7
#define RANDOMX_FREQ_IMUL_R 16
#define RANDOMX_FREQ_IMUL_M 4
#define RANDOMX_FREQ_IMULH_R 4
#define RANDOMX_FREQ_IMULH_M 1
#define RANDOMX_FREQ_ISMULH_R 4
#define RANDOMX_FREQ_ISMULH_M 1
#define RANDOMX_FREQ_IMUL_RCP 8
#define RANDOMX_FREQ_INEG_R 2
#define RANDOMX_FREQ_IXOR_R 15
#define RANDOMX_FREQ_IXOR_M 5
#define RANDOMX_FREQ_IROR_R 8
#define RANDOMX_FREQ_IROL_R 2
#define RANDOMX_FREQ_ISWAP_R 4
//Floating point instructions
#define RANDOMX_FREQ_FSWAP_R 4
#define RANDOMX_FREQ_FADD_R 16
#define RANDOMX_FREQ_FADD_M 5
#define RANDOMX_FREQ_FSUB_R 16
#define RANDOMX_FREQ_FSUB_M 5
#define RANDOMX_FREQ_FSCAL_R 6
#define RANDOMX_FREQ_FMUL_R 32
#define RANDOMX_FREQ_FDIV_M 4
#define RANDOMX_FREQ_FSQRT_R 6
//Control instructions
#define RANDOMX_FREQ_CBRANCH 25
#define RANDOMX_FREQ_CFROUND 1
//Store instruction
#define RANDOMX_FREQ_ISTORE 16
//No-op instruction
#define RANDOMX_FREQ_NOP 0
#define RANDOMX_DATASET_ITEM_SIZE 64
#define RANDOMX_PROGRAM_SIZE 256
#define HASH_SIZE 64
#define ENTROPY_SIZE (128 + RANDOMX_PROGRAM_SIZE * 8)
#define REGISTERS_SIZE 256
#define IMM_BUF_SIZE (RANDOMX_PROGRAM_SIZE * 4 - REGISTERS_SIZE)
#define IMM_INDEX_COUNT ((IMM_BUF_SIZE / 4) - 2)
#define VM_STATE_SIZE (REGISTERS_SIZE + IMM_BUF_SIZE + RANDOMX_PROGRAM_SIZE * 4)
#define ROUNDING_MODE (RANDOMX_FREQ_CFROUND ? -1 : 0)
// Scratchpad L1/L2/L3 bits
#define LOC_L1 (32 - 14)
#define LOC_L2 (32 - 17)
#define LOC_L3 (32 - 20)

View File

@@ -1,87 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "backend/opencl/OclThreads.h"
#include "backend/opencl/wrappers/OclDevice.h"
#include "base/crypto/Algorithm.h"
#include <algorithm>
namespace xmrig {
constexpr const size_t oneMiB = 1024u * 1024u;
bool ocl_generic_cn_gpu_generator(const OclDevice &device, const Algorithm &algorithm, OclThreads &threads)
{
if (algorithm != Algorithm::CN_GPU) {
return false;
}
uint32_t worksize = 8;
uint32_t numThreads = 1u;
size_t minFreeMem = 128u * oneMiB;
if (device.type() == OclDevice::Vega_10 || device.type() == OclDevice::Vega_20) {
minFreeMem = oneMiB;
worksize = 16;
}
else if (device.type() == OclDevice::Navi_10) {
numThreads = 2u;
}
else if (device.name() == "Fiji") {
worksize = 16;
}
size_t maxThreads = device.computeUnits() * 6 * 8;
const size_t maxAvailableFreeMem = device.freeMemSize() - minFreeMem;
const size_t memPerThread = std::min(device.maxMemAllocSize(), maxAvailableFreeMem);
size_t memPerHash = algorithm.l3() + 240u;
size_t maxIntensity = memPerThread / memPerHash;
size_t possibleIntensity = std::min(maxThreads, maxIntensity);
size_t intensity = 0;
size_t cuUtilization = ((possibleIntensity * 100) / (worksize * device.computeUnits())) % 100;
if (cuUtilization >= 75) {
intensity = (possibleIntensity / worksize) * worksize;
}
else {
intensity = (possibleIntensity / (worksize * device.computeUnits())) * device.computeUnits() * worksize;
}
threads.add(OclThread(device.index(), intensity, worksize, numThreads, 1));
return true;
}
} // namespace xmrig

View File

@@ -1,44 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "backend/opencl/kernels/Cn00RyoKernel.h"
#include "backend/opencl/wrappers/OclLib.h"
void xmrig::Cn00RyoKernel::enqueue(cl_command_queue queue, size_t threads)
{
const size_t gthreads = threads * 64;
const size_t lthreads = 64;
enqueueNDRange(queue, 1, nullptr, &gthreads, &lthreads);
}
// __kernel void cn00(__global int *Scratchpad, __global ulong *states)
void xmrig::Cn00RyoKernel::setArgs(cl_mem scratchpads, cl_mem states)
{
setArg(0, sizeof(cl_mem), &scratchpads);
setArg(1, sizeof(cl_mem), &states);
}

Some files were not shown because too many files have changed in this diff Show More