Merge branch 'dev'
This commit is contained in:
commit
eadf272425
88 changed files with 3091 additions and 367 deletions
|
@ -1,3 +1,10 @@
|
|||
# v6.17.0
|
||||
- [#2954](https://github.com/xmrig/xmrig/pull/2954) **Dero HE fork support (`astrobwt/v2` algorithm).**
|
||||
- [#2961](https://github.com/xmrig/xmrig/pull/2961) Dero HE (`astrobwt/v2`) CUDA config generator.
|
||||
- [#2969](https://github.com/xmrig/xmrig/pull/2969) Dero HE (`astrobwt/v2`) OpenCL support.
|
||||
- Fixed displayed DMI memory information for empty slots.
|
||||
- [#2932](https://github.com/xmrig/xmrig/pull/2932) Fixed GhostRider with hwloc disabled.
|
||||
|
||||
# v6.16.4
|
||||
- [#2904](https://github.com/xmrig/xmrig/pull/2904) Fixed unaligned memory accesses.
|
||||
- [#2908](https://github.com/xmrig/xmrig/pull/2908) Added MSVC/2022 to `version.h`.
|
||||
|
|
|
@ -3,10 +3,12 @@ if (WITH_ASTROBWT)
|
|||
|
||||
list(APPEND HEADERS_CRYPTO
|
||||
src/crypto/astrobwt/AstroBWT.h
|
||||
src/crypto/astrobwt/sort_indices2.h
|
||||
)
|
||||
|
||||
list(APPEND SOURCES_CRYPTO
|
||||
src/crypto/astrobwt/AstroBWT.cpp
|
||||
src/crypto/astrobwt/sort_indices2.cpp
|
||||
)
|
||||
|
||||
if (XMRIG_ARM)
|
||||
|
@ -21,6 +23,10 @@ if (WITH_ASTROBWT)
|
|||
src/crypto/astrobwt/salsa20_ref/salsa20.c
|
||||
)
|
||||
else()
|
||||
if (CMAKE_C_COMPILER_ID MATCHES MSVC)
|
||||
set_source_files_properties(src/crypto/astrobwt/sort_indices2.cpp PROPERTIES COMPILE_FLAGS "/std:c++20")
|
||||
endif()
|
||||
|
||||
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
add_definitions(/DASTROBWT_AVX2)
|
||||
list(APPEND SOURCES_CRYPTO src/crypto/astrobwt/xmm6int/salsa20_xmm6int-avx2.c)
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
HWLOC_VERSION="2.5.0"
|
||||
HWLOC_VERSION_MAJOR="2"
|
||||
HWLOC_VERSION_MINOR="7"
|
||||
HWLOC_VERSION_PATCH="0"
|
||||
|
||||
HWLOC_VERSION="${HWLOC_VERSION_MAJOR}.${HWLOC_VERSION_MINOR}.${HWLOC_VERSION_PATCH}"
|
||||
|
||||
mkdir -p deps
|
||||
mkdir -p deps/include
|
||||
|
@ -8,7 +12,7 @@ mkdir -p deps/lib
|
|||
|
||||
mkdir -p build && cd build
|
||||
|
||||
wget https://download.open-mpi.org/release/hwloc/v2.5/hwloc-${HWLOC_VERSION}.tar.gz -O hwloc-${HWLOC_VERSION}.tar.gz
|
||||
wget https://download.open-mpi.org/release/hwloc/v${HWLOC_VERSION_MAJOR}.${HWLOC_VERSION_MINOR}/hwloc-${HWLOC_VERSION}.tar.gz -O hwloc-${HWLOC_VERSION}.tar.gz
|
||||
tar -xzf hwloc-${HWLOC_VERSION}.tar.gz
|
||||
|
||||
cd hwloc-${HWLOC_VERSION}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
LIBRESSL_VERSION="3.0.2"
|
||||
LIBRESSL_VERSION="3.4.2"
|
||||
|
||||
mkdir -p deps
|
||||
mkdir -p deps/include
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
OPENSSL_VERSION="1.1.1l"
|
||||
OPENSSL_VERSION="1.1.1m"
|
||||
|
||||
mkdir -p deps
|
||||
mkdir -p deps/include
|
||||
|
|
20
scripts/build.openssl3.sh
Executable file
20
scripts/build.openssl3.sh
Executable file
|
@ -0,0 +1,20 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
OPENSSL_VERSION="3.0.1"
|
||||
|
||||
mkdir -p deps
|
||||
mkdir -p deps/include
|
||||
mkdir -p deps/lib
|
||||
|
||||
mkdir -p build && cd build
|
||||
|
||||
wget https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz -O openssl-${OPENSSL_VERSION}.tar.gz
|
||||
tar -xzf openssl-${OPENSSL_VERSION}.tar.gz
|
||||
|
||||
cd openssl-${OPENSSL_VERSION}
|
||||
./config -no-shared -no-asm -no-zlib -no-comp -no-dgram -no-filenames -no-cms
|
||||
make -j$(nproc || sysctl -n hw.ncpu || sysctl -n hw.logicalcpu)
|
||||
cp -fr include ../../deps
|
||||
cp libcrypto.a ../../deps/lib
|
||||
cp libssl.a ../../deps/lib
|
||||
cd ..
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
UV_VERSION="1.42.0"
|
||||
UV_VERSION="1.43.0"
|
||||
|
||||
mkdir -p deps
|
||||
mkdir -p deps/include
|
||||
|
|
|
@ -76,6 +76,14 @@ function astrobwt()
|
|||
}
|
||||
|
||||
|
||||
function astrobwt_v2()
|
||||
{
|
||||
const astrobwt = opencl_minify(addIncludes('astrobwt_v2.cl', [ 'BWT.cl', 'salsa20.cl', 'sha3.cl' ]));
|
||||
|
||||
fs.writeFileSync('astrobwt_v2_cl.h', text2h(astrobwt, 'xmrig', 'astrobwt_v2_cl'));
|
||||
}
|
||||
|
||||
|
||||
function kawpow()
|
||||
{
|
||||
const kawpow = opencl_minify(addIncludes('kawpow.cl', [ 'defs.h' ]));
|
||||
|
@ -102,6 +110,11 @@ process.chdir(path.resolve('src/backend/opencl/cl/astrobwt'));
|
|||
|
||||
astrobwt();
|
||||
|
||||
process.chdir(cwd);
|
||||
process.chdir(path.resolve('src/backend/opencl/cl/astrobwt_v2'));
|
||||
|
||||
astrobwt_v2();
|
||||
|
||||
process.chdir(cwd);
|
||||
process.chdir(path.resolve('src/backend/opencl/cl/kawpow'));
|
||||
|
||||
|
|
70
src/3rdparty/hwloc/NEWS
vendored
70
src/3rdparty/hwloc/NEWS
vendored
|
@ -17,6 +17,76 @@ bug fixes (and other actions) for each version of hwloc since version
|
|||
0.9.
|
||||
|
||||
|
||||
Version 2.7.0
|
||||
-------------
|
||||
* Backends
|
||||
+ Add support for NUMA nodes and caches with more than 64 PUs across
|
||||
multiple processor groups on Windows 11 and Windows Server 2022.
|
||||
+ Group objects are not created for Windows processor groups anymore,
|
||||
except if HWLOC_WINDOWS_PROCESSOR_GROUP_OBJS=1 in the environment.
|
||||
+ Expose "Cluster" group objects on Linux kernel 5.16+ for CPUs
|
||||
that share some internal cache or bus. This can be equivalent
|
||||
to the L2 Cache level on some platforms (e.g. x86) or a specific
|
||||
level between L2 and L3 on others (e.g. ARM Kungpeng 920).
|
||||
Thanks to Jonathan Cameron for the help.
|
||||
- HWLOC_DONT_MERGE_CLUSTER_GROUPS=1 may be set in the environment
|
||||
to prevent these groups from being merged with identical caches, etc.
|
||||
+ Improve the oneAPI LevelZero backend:
|
||||
- Expose subdevices such as "ze0.1" inside root OS devices ("ze0")
|
||||
when the hardware contains multiple subdevices.
|
||||
- Add many new attributes to describe device type, and the
|
||||
numbers of slices, subslices, execution units and threads.
|
||||
- Expose the memory information as LevelZeroHBM/DDR/MemorySize infos.
|
||||
+ Ignore the max frequencies of cores in Linux cpukinds when the
|
||||
base frequencies are available (to avoid exposing hybrid CPUs
|
||||
when Intel Turbo Boost Max 3.0 gives slightly different max
|
||||
frequencies to CPU cores).
|
||||
- May be reverted by setting HWLOC_CPUKINDS_MAXFREQ=1 in the environment.
|
||||
* Tools
|
||||
+ Add --grey and --palette options to switch lstopo to greyscale or
|
||||
white-background-only graphics, or to tune individual colors.
|
||||
* Build
|
||||
+ Windows CMake builds now support non-MSVC compilers, detect several
|
||||
features at build time, can build/run tests, etc.
|
||||
Thanks to Michael Hirsch and Alexander Neumann .
|
||||
|
||||
|
||||
Version 2.6.0
|
||||
-------------
|
||||
* Backends
|
||||
+ Expose two cpukinds for energy-efficient cores (icestorm) and
|
||||
high-performance cores (firestorm) on Apple M1 on Mac OS X.
|
||||
+ Use sysfs CPU "capacity" to rank hybrid cores by efficiency
|
||||
on Linux when available (mostly on recent ARM platforms for now).
|
||||
+ Improve HWLOC_MEMBIND_BIND (without the STRICT flag) on Linux kernel
|
||||
>= 5.15: If more than one node is given, the kernel may now use all
|
||||
of them instead of only the first one before falling back to others.
|
||||
+ Expose cache os_index when available on Linux, it may be needed
|
||||
when using resctrl to configure cache partitioning, memory bandwidth
|
||||
monitoring, etc.
|
||||
+ Add a "XGMIHops" distances matrix in the RSMI backend for AMD GPU
|
||||
interconnected through XGMI links.
|
||||
+ Expose AMD GPU memory information (VRAM and GTT) in the RSMI backend.
|
||||
+ Add OS devices such as "bxi0" for Atos/Bull BXI HCAs on Linux.
|
||||
* Tools
|
||||
+ lstopo has a better placement algorithm with respect to I/O
|
||||
objects, see --children-order in the manpage for details.
|
||||
+ hwloc-annotate may now change object subtypes and cache or memory
|
||||
sizes.
|
||||
* Build
|
||||
+ Allow to specify the ROCm installation for building the RSMI backend:
|
||||
- Use a custom installation path if specified with --with-rocm=<dir>.
|
||||
- Use /opt/rocm-<version> if specified with --with-rocm-version=<version>
|
||||
or the ROCM_VERSION environment variable.
|
||||
- Try /opt/rocm if it exists.
|
||||
- See "How do I enable ROCm SMI and select which version to use?"
|
||||
in the FAQ for details.
|
||||
+ Add a CMakeLists for Windows under contrib/windows-cmake/ .
|
||||
* Documentation
|
||||
+ Add FAQ entry "How do I create a custom heterogeneous and
|
||||
asymmetric topology?"
|
||||
|
||||
|
||||
Version 2.5.0
|
||||
-------------
|
||||
* API
|
||||
|
|
6
src/3rdparty/hwloc/VERSION
vendored
6
src/3rdparty/hwloc/VERSION
vendored
|
@ -8,7 +8,7 @@
|
|||
# Please update HWLOC_VERSION* in contrib/windows/hwloc_config.h too.
|
||||
|
||||
major=2
|
||||
minor=5
|
||||
minor=7
|
||||
release=0
|
||||
|
||||
# greek is used for alpha or beta release tags. If it is non-empty,
|
||||
|
@ -22,7 +22,7 @@ greek=
|
|||
|
||||
# The date when this release was created
|
||||
|
||||
date="Jun 14, 2021"
|
||||
date="Dec 06, 2021"
|
||||
|
||||
# If snapshot=1, then use the value from snapshot_version as the
|
||||
# entire hwloc version (i.e., ignore major, minor, release, and
|
||||
|
@ -41,7 +41,7 @@ snapshot_version=${major}.${minor}.${release}${greek}-git
|
|||
# 2. Version numbers are described in the Libtool current:revision:age
|
||||
# format.
|
||||
|
||||
libhwloc_so_version=20:0:5
|
||||
libhwloc_so_version=20:2:5
|
||||
libnetloc_so_version=0:0:0
|
||||
|
||||
# Please also update the <TargetName> lines in contrib/windows/libhwloc.vcxproj
|
||||
|
|
45
src/3rdparty/hwloc/include/hwloc.h
vendored
45
src/3rdparty/hwloc/include/hwloc.h
vendored
|
@ -346,7 +346,8 @@ typedef enum hwloc_obj_osdev_type_e {
|
|||
* For instance the "eth0" interface on Linux. */
|
||||
HWLOC_OBJ_OSDEV_OPENFABRICS, /**< \brief Operating system openfabrics device.
|
||||
* For instance the "mlx4_0" InfiniBand HCA,
|
||||
* or "hfi1_0" Omni-Path interface on Linux. */
|
||||
* "hfi1_0" Omni-Path interface,
|
||||
* or "bxi0" Atos/Bull BXI HCA on Linux. */
|
||||
HWLOC_OBJ_OSDEV_DMA, /**< \brief Operating system dma engine device.
|
||||
* For instance the "dma0chan0" DMA channel on Linux. */
|
||||
HWLOC_OBJ_OSDEV_COPROC /**< \brief Operating system co-processor device.
|
||||
|
@ -1212,8 +1213,9 @@ HWLOC_DECLSPEC int hwloc_set_cpubind(hwloc_topology_t topology, hwloc_const_cpus
|
|||
|
||||
/** \brief Get current process or thread binding.
|
||||
*
|
||||
* Writes into \p set the physical cpuset which the process or thread (according to \e
|
||||
* flags) was last bound to.
|
||||
* The CPU-set \p set (previously allocated by the caller)
|
||||
* is filled with the list of PUs which the process or
|
||||
* thread (according to \e flags) was last bound to.
|
||||
*/
|
||||
HWLOC_DECLSPEC int hwloc_get_cpubind(hwloc_topology_t topology, hwloc_cpuset_t set, int flags);
|
||||
|
||||
|
@ -1231,6 +1233,10 @@ HWLOC_DECLSPEC int hwloc_get_cpubind(hwloc_topology_t topology, hwloc_cpuset_t s
|
|||
HWLOC_DECLSPEC int hwloc_set_proc_cpubind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_const_cpuset_t set, int flags);
|
||||
|
||||
/** \brief Get the current physical binding of process \p pid.
|
||||
*
|
||||
* The CPU-set \p set (previously allocated by the caller)
|
||||
* is filled with the list of PUs which the process
|
||||
* was last bound to.
|
||||
*
|
||||
* \note \p hwloc_pid_t is \p pid_t on Unix platforms,
|
||||
* and \p HANDLE on native Windows platforms.
|
||||
|
@ -1256,6 +1262,10 @@ HWLOC_DECLSPEC int hwloc_set_thread_cpubind(hwloc_topology_t topology, hwloc_thr
|
|||
|
||||
#ifdef hwloc_thread_t
|
||||
/** \brief Get the current physical binding of thread \p tid.
|
||||
*
|
||||
* The CPU-set \p set (previously allocated by the caller)
|
||||
* is filled with the list of PUs which the thread
|
||||
* was last bound to.
|
||||
*
|
||||
* \note \p hwloc_thread_t is \p pthread_t on Unix platforms,
|
||||
* and \p HANDLE on native Windows platforms.
|
||||
|
@ -1266,6 +1276,10 @@ HWLOC_DECLSPEC int hwloc_get_thread_cpubind(hwloc_topology_t topology, hwloc_thr
|
|||
#endif
|
||||
|
||||
/** \brief Get the last physical CPU where the current process or thread ran.
|
||||
*
|
||||
* The CPU-set \p set (previously allocated by the caller)
|
||||
* is filled with the list of PUs which the process or
|
||||
* thread (according to \e flags) last ran on.
|
||||
*
|
||||
* The operating system may move some tasks from one processor
|
||||
* to another at any time according to their binding,
|
||||
|
@ -1281,6 +1295,10 @@ HWLOC_DECLSPEC int hwloc_get_thread_cpubind(hwloc_topology_t topology, hwloc_thr
|
|||
HWLOC_DECLSPEC int hwloc_get_last_cpu_location(hwloc_topology_t topology, hwloc_cpuset_t set, int flags);
|
||||
|
||||
/** \brief Get the last physical CPU where a process ran.
|
||||
*
|
||||
* The CPU-set \p set (previously allocated by the caller)
|
||||
* is filled with the list of PUs which the process
|
||||
* last ran on.
|
||||
*
|
||||
* The operating system may move some tasks from one processor
|
||||
* to another at any time according to their binding,
|
||||
|
@ -1511,6 +1529,9 @@ HWLOC_DECLSPEC int hwloc_set_membind(hwloc_topology_t topology, hwloc_const_bitm
|
|||
/** \brief Query the default memory binding policy and physical locality of the
|
||||
* current process or thread.
|
||||
*
|
||||
* The bitmap \p set (previously allocated by the caller)
|
||||
* is filled with the process or thread memory binding.
|
||||
*
|
||||
* This function has two output parameters: \p set and \p policy.
|
||||
* The values returned in these parameters depend on both the \p flags
|
||||
* passed in and the current memory binding policies and nodesets in
|
||||
|
@ -1571,6 +1592,9 @@ HWLOC_DECLSPEC int hwloc_set_proc_membind(hwloc_topology_t topology, hwloc_pid_t
|
|||
/** \brief Query the default memory binding policy and physical locality of the
|
||||
* specified process.
|
||||
*
|
||||
* The bitmap \p set (previously allocated by the caller)
|
||||
* is filled with the process memory binding.
|
||||
*
|
||||
* This function has two output parameters: \p set and \p policy.
|
||||
* The values returned in these parameters depend on both the \p flags
|
||||
* passed in and the current memory binding policies and nodesets in
|
||||
|
@ -1624,6 +1648,9 @@ HWLOC_DECLSPEC int hwloc_set_area_membind(hwloc_topology_t topology, const void
|
|||
/** \brief Query the CPUs near the physical NUMA node(s) and binding policy of
|
||||
* the memory identified by (\p addr, \p len ).
|
||||
*
|
||||
* The bitmap \p set (previously allocated by the caller)
|
||||
* is filled with the memory area binding.
|
||||
*
|
||||
* This function has two output parameters: \p set and \p policy.
|
||||
* The values returned in these parameters depend on both the \p flags
|
||||
* passed in and the memory binding policies and nodesets of the pages
|
||||
|
@ -1652,7 +1679,8 @@ HWLOC_DECLSPEC int hwloc_get_area_membind(hwloc_topology_t topology, const void
|
|||
|
||||
/** \brief Get the NUMA nodes where memory identified by (\p addr, \p len ) is physically allocated.
|
||||
*
|
||||
* Fills \p set according to the NUMA nodes where the memory area pages
|
||||
* The bitmap \p set (previously allocated by the caller)
|
||||
* is filled according to the NUMA nodes where the memory area pages
|
||||
* are physically allocated. If no page is actually allocated yet,
|
||||
* \p set may be empty.
|
||||
*
|
||||
|
@ -1698,9 +1726,12 @@ HWLOC_DECLSPEC void *hwloc_alloc_membind(hwloc_topology_t topology, size_t len,
|
|||
|
||||
/** \brief Allocate some memory on NUMA memory nodes specified by \p set
|
||||
*
|
||||
* This is similar to hwloc_alloc_membind_nodeset() except that it is allowed to change
|
||||
* the current memory binding policy, thus providing more binding support, at
|
||||
* the expense of changing the current state.
|
||||
* First, try to allocate properly with hwloc_alloc_membind().
|
||||
* On failure, the current process or thread memory binding policy
|
||||
* is changed with hwloc_set_membind() before allocating memory.
|
||||
* Thus this function works in more cases, at the expense of changing
|
||||
* the current state (possibly affecting future allocations that
|
||||
* would not specify any policy).
|
||||
*
|
||||
* If ::HWLOC_MEMBIND_BYNODESET is specified, set is considered a nodeset.
|
||||
* Otherwise it's a cpuset.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright © 2009 CNRS
|
||||
* Copyright © 2009-2020 Inria. All rights reserved.
|
||||
* Copyright © 2009-2021 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,9 +11,9 @@
|
|||
#ifndef HWLOC_CONFIG_H
|
||||
#define HWLOC_CONFIG_H
|
||||
|
||||
#define HWLOC_VERSION "2.5.0"
|
||||
#define HWLOC_VERSION "2.7.0"
|
||||
#define HWLOC_VERSION_MAJOR 2
|
||||
#define HWLOC_VERSION_MINOR 5
|
||||
#define HWLOC_VERSION_MINOR 7
|
||||
#define HWLOC_VERSION_RELEASE 0
|
||||
#define HWLOC_VERSION_GREEK ""
|
||||
|
||||
|
|
25
src/3rdparty/hwloc/include/hwloc/cpukinds.h
vendored
25
src/3rdparty/hwloc/include/hwloc/cpukinds.h
vendored
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2020 Inria. All rights reserved.
|
||||
* Copyright © 2020-2021 Inria. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
|
@ -42,18 +42,23 @@ extern "C" {
|
|||
* (for instance the "CoreType" and "FrequencyMaxMHz",
|
||||
* see \ref topoattrs_cpukinds).
|
||||
*
|
||||
* A higher efficiency value means intrinsic greater performance
|
||||
* A higher efficiency value means greater intrinsic performance
|
||||
* (and possibly less performance/power efficiency).
|
||||
* Kinds with lower efficiency are ranked first:
|
||||
* Kinds with lower efficiency values are ranked first:
|
||||
* Passing 0 as \p kind_index to hwloc_cpukinds_get_info() will
|
||||
* return information about the less efficient CPU kind.
|
||||
* return information about the CPU kind with lower performance
|
||||
* but higher energy-efficiency.
|
||||
* Higher \p kind_index values would rather return information
|
||||
* about power-hungry high-performance cores.
|
||||
*
|
||||
* When available, efficiency values are gathered from the operating
|
||||
* system (when \p cpukind_efficiency is set in the
|
||||
* struct hwloc_topology_discovery_support array, only on Windows 10 for now).
|
||||
* Otherwise hwloc tries to compute efficiencies
|
||||
* by comparing CPU kinds using frequencies (on ARM),
|
||||
* or core types and frequencies (on other architectures).
|
||||
* When available, efficiency values are gathered from the operating system.
|
||||
* If so, \p cpukind_efficiency is set in the struct hwloc_topology_discovery_support array.
|
||||
* This is currently available on Windows 10, Mac OS X (Darwin),
|
||||
* and on some Linux platforms where core "capacity" is exposed in sysfs.
|
||||
*
|
||||
* If the operating system does not expose core efficiencies natively,
|
||||
* hwloc tries to compute efficiencies by comparing CPU kinds using
|
||||
* frequencies (on ARM), or core types and frequencies (on other architectures).
|
||||
* The environment variable HWLOC_CPUKINDS_RANKING may be used
|
||||
* to change this heuristics, see \ref envvar.
|
||||
*
|
||||
|
|
5
src/3rdparty/hwloc/include/hwloc/distances.h
vendored
5
src/3rdparty/hwloc/include/hwloc/distances.h
vendored
|
@ -35,7 +35,8 @@ extern "C" {
|
|||
* from a core in another node.
|
||||
* The corresponding kind is ::HWLOC_DISTANCES_KIND_FROM_OS | ::HWLOC_DISTANCES_KIND_FROM_USER.
|
||||
* The name of this distances structure is "NUMALatency".
|
||||
* Others distance structures include and "XGMIBandwidth" and "NVLinkBandwidth".
|
||||
* Others distance structures include and "XGMIBandwidth", "XGMIHops"
|
||||
* and "NVLinkBandwidth".
|
||||
*
|
||||
* The matrix may also contain bandwidths between random sets of objects,
|
||||
* possibly provided by the user, as specified in the \p kind attribute.
|
||||
|
@ -159,7 +160,7 @@ hwloc_distances_get_by_type(hwloc_topology_t topology, hwloc_obj_type_t type,
|
|||
* Usually only one distances structure may match a given name.
|
||||
*
|
||||
* The name of the most common structure is "NUMALatency".
|
||||
* Others include "XGMIBandwidth" and "NVLinkBandwidth".
|
||||
* Others include "XGMIBandwidth", "XGMIHops" and "NVLinkBandwidth".
|
||||
*/
|
||||
HWLOC_DECLSPEC int
|
||||
hwloc_distances_get_by_name(hwloc_topology_t topology, const char *name,
|
||||
|
|
9
src/3rdparty/hwloc/include/hwloc/linux.h
vendored
9
src/3rdparty/hwloc/include/hwloc/linux.h
vendored
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright © 2009 CNRS
|
||||
* Copyright © 2009-2016 Inria. All rights reserved.
|
||||
* Copyright © 2009-2021 Inria. All rights reserved.
|
||||
* Copyright © 2009-2011 Université Bordeaux
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
@ -44,6 +44,10 @@ extern "C" {
|
|||
HWLOC_DECLSPEC int hwloc_linux_set_tid_cpubind(hwloc_topology_t topology, pid_t tid, hwloc_const_cpuset_t set);
|
||||
|
||||
/** \brief Get the current binding of thread \p tid
|
||||
*
|
||||
* The CPU-set \p set (previously allocated by the caller)
|
||||
* is filled with the list of PUs which the thread
|
||||
* was last bound to.
|
||||
*
|
||||
* The behavior is exactly the same as the Linux sched_getaffinity system call,
|
||||
* but uses a hwloc cpuset.
|
||||
|
@ -54,6 +58,9 @@ HWLOC_DECLSPEC int hwloc_linux_set_tid_cpubind(hwloc_topology_t topology, pid_t
|
|||
HWLOC_DECLSPEC int hwloc_linux_get_tid_cpubind(hwloc_topology_t topology, pid_t tid, hwloc_cpuset_t set);
|
||||
|
||||
/** \brief Get the last physical CPU where thread \p tid ran.
|
||||
*
|
||||
* The CPU-set \p set (previously allocated by the caller)
|
||||
* is filled with the PU which the thread last ran on.
|
||||
*
|
||||
* \note This is equivalent to calling hwloc_get_proc_last_cpu_location() with
|
||||
* ::HWLOC_CPUBIND_THREAD as flags.
|
||||
|
|
1
src/3rdparty/hwloc/include/hwloc/plugins.h
vendored
1
src/3rdparty/hwloc/include/hwloc/plugins.h
vendored
|
@ -497,6 +497,7 @@ hwloc_filter_check_pcidev_subtype_important(unsigned classid)
|
|||
return (baseclass == 0x03 /* PCI_BASE_CLASS_DISPLAY */
|
||||
|| baseclass == 0x02 /* PCI_BASE_CLASS_NETWORK */
|
||||
|| baseclass == 0x01 /* PCI_BASE_CLASS_STORAGE */
|
||||
|| baseclass == 0x00 /* Unclassified, for Atos/Bull BXI */
|
||||
|| baseclass == 0x0b /* PCI_BASE_CLASS_PROCESSOR */
|
||||
|| classid == 0x0c04 /* PCI_CLASS_SERIAL_FIBER */
|
||||
|| classid == 0x0c06 /* PCI_CLASS_SERIAL_INFINIBAND */
|
||||
|
|
|
@ -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$
|
||||
|
@ -290,10 +290,6 @@
|
|||
/* Define to '1' if sysctlbyname is present and usable */
|
||||
/* #undef HAVE_SYSCTLBYNAME */
|
||||
|
||||
/* Define to 1 if the system has the type
|
||||
`SYSTEM_LOGICAL_PROCESSOR_INFORMATION'. */
|
||||
#define HAVE_SYSTEM_LOGICAL_PROCESSOR_INFORMATION 1
|
||||
|
||||
/* Define to 1 if the system has the type
|
||||
`SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX'. */
|
||||
#define HAVE_SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX 1
|
||||
|
|
2
src/3rdparty/hwloc/include/private/misc.h
vendored
2
src/3rdparty/hwloc/include/private/misc.h
vendored
|
@ -504,7 +504,7 @@ hwloc__obj_type_is_icache(hwloc_obj_type_t type)
|
|||
} \
|
||||
} while(0)
|
||||
#else /* HAVE_USELOCALE */
|
||||
#if __HWLOC_HAVE_ATTRIBUTE_UNUSED
|
||||
#if HWLOC_HAVE_ATTRIBUTE_UNUSED
|
||||
#define hwloc_localeswitch_declare int __dummy_nolocale __hwloc_attribute_unused
|
||||
#define hwloc_localeswitch_init()
|
||||
#else
|
||||
|
|
1
src/3rdparty/hwloc/include/private/private.h
vendored
1
src/3rdparty/hwloc/include/private/private.h
vendored
|
@ -480,6 +480,7 @@ extern char * hwloc_progname(struct hwloc_topology *topology);
|
|||
#define HWLOC_GROUP_KIND_AIX_SDL_UNKNOWN 210 /* subkind is SDL level */
|
||||
#define HWLOC_GROUP_KIND_WINDOWS_PROCESSOR_GROUP 220 /* no subkind */
|
||||
#define HWLOC_GROUP_KIND_WINDOWS_RELATIONSHIP_UNKNOWN 221 /* no subkind */
|
||||
#define HWLOC_GROUP_KIND_LINUX_CLUSTER 222 /* no subkind */
|
||||
/* distance groups */
|
||||
#define HWLOC_GROUP_KIND_DISTANCE 900 /* subkind is round of adding these groups during distance based grouping */
|
||||
/* finally, hwloc-specific groups required to insert something else, should disappear as soon as possible */
|
||||
|
|
21
src/3rdparty/hwloc/include/private/windows.h
vendored
Normal file
21
src/3rdparty/hwloc/include/private/windows.h
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Copyright © 2009 Université Bordeaux
|
||||
* Copyright © 2020 Inria. All rights reserved.
|
||||
*
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
#ifndef HWLOC_PRIVATE_WINDOWS_H
|
||||
#define HWLOC_PRIVATE_WINDOWS_H
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define _ANONYMOUS_UNION __extension__
|
||||
#define _ANONYMOUS_STRUCT __extension__
|
||||
#else
|
||||
#define _ANONYMOUS_UNION
|
||||
#define _ANONYMOUS_STRUCT
|
||||
#endif /* __GNUC__ */
|
||||
#define DUMMYUNIONNAME
|
||||
#define DUMMYSTRUCTNAME
|
||||
|
||||
#endif /* HWLOC_PRIVATE_WINDOWS_H */
|
7
src/3rdparty/hwloc/src/cpukinds.c
vendored
7
src/3rdparty/hwloc/src/cpukinds.c
vendored
|
@ -42,6 +42,9 @@ hwloc_internal_cpukinds_dup(hwloc_topology_t new, hwloc_topology_t old)
|
|||
struct hwloc_internal_cpukind_s *kinds;
|
||||
unsigned i;
|
||||
|
||||
if (!old->nr_cpukinds)
|
||||
return 0;
|
||||
|
||||
kinds = hwloc_tma_malloc(tma, old->nr_cpukinds * sizeof(*kinds));
|
||||
if (!kinds)
|
||||
return -1;
|
||||
|
@ -445,7 +448,9 @@ static int hwloc__cpukinds_compare_ranking_values(const void *_a, const void *_b
|
|||
{
|
||||
const struct hwloc_internal_cpukind_s *a = _a;
|
||||
const struct hwloc_internal_cpukind_s *b = _b;
|
||||
return a->ranking_value - b->ranking_value;
|
||||
uint64_t arv = a->ranking_value;
|
||||
uint64_t brv = b->ranking_value;
|
||||
return arv < brv ? -1 : arv > brv ? 1 : 0;
|
||||
}
|
||||
|
||||
/* this function requires ranking values to be unique */
|
||||
|
|
4
src/3rdparty/hwloc/src/memattrs.c
vendored
4
src/3rdparty/hwloc/src/memattrs.c
vendored
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2020 Inria. All rights reserved.
|
||||
* Copyright © 2020-2021 Inria. All rights reserved.
|
||||
* See COPYING in top-level directory.
|
||||
*/
|
||||
|
||||
|
@ -127,6 +127,8 @@ hwloc_internal_memattrs_dup(struct hwloc_topology *new, struct hwloc_topology *o
|
|||
struct hwloc_internal_memattr_s *imattrs;
|
||||
hwloc_memattr_id_t id;
|
||||
|
||||
/* old->nr_memattrs is always > 0 thanks to default memattrs */
|
||||
|
||||
imattrs = hwloc_tma_malloc(tma, old->nr_memattrs * sizeof(*imattrs));
|
||||
if (!imattrs)
|
||||
return -1;
|
||||
|
|
3
src/3rdparty/hwloc/src/pci-common.c
vendored
3
src/3rdparty/hwloc/src/pci-common.c
vendored
|
@ -810,13 +810,14 @@ hwloc_pcidisc_find_linkspeed(const unsigned char *config,
|
|||
* PCIe Gen3 = 8 GT/s signal-rate per lane with 128/130 encoding = 1 GB/s data-rate per lane
|
||||
* PCIe Gen4 = 16 GT/s signal-rate per lane with 128/130 encoding = 2 GB/s data-rate per lane
|
||||
* PCIe Gen5 = 32 GT/s signal-rate per lane with 128/130 encoding = 4 GB/s data-rate per lane
|
||||
* PCIe Gen6 = 64 GT/s signal-rate per lane with 128/130 encoding = 8 GB/s data-rate per lane
|
||||
*/
|
||||
|
||||
/* lanespeed in Gbit/s */
|
||||
if (speed <= 2)
|
||||
lanespeed = 2.5f * speed * 0.8f;
|
||||
else
|
||||
lanespeed = 8.0f * (1<<(speed-3)) * 128/130; /* assume Gen6 will be 64 GT/s and so on */
|
||||
lanespeed = 8.0f * (1<<(speed-3)) * 128/130; /* assume Gen7 will be 128 GT/s and so on */
|
||||
|
||||
/* linkspeed in GB/s */
|
||||
*linkspeed = lanespeed * width / 8;
|
||||
|
|
242
src/3rdparty/hwloc/src/topology-windows.c
vendored
242
src/3rdparty/hwloc/src/topology-windows.c
vendored
|
@ -13,6 +13,7 @@
|
|||
#include "hwloc.h"
|
||||
#include "hwloc/windows.h"
|
||||
#include "private/private.h"
|
||||
#include "private/windows.h" /* must be before windows.h */
|
||||
#include "private/debug.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
@ -65,26 +66,6 @@ typedef enum _LOGICAL_PROCESSOR_RELATIONSHIP {
|
|||
# endif /* HAVE_RELATIONPROCESSORPACKAGE */
|
||||
#endif /* HAVE_LOGICAL_PROCESSOR_RELATIONSHIP */
|
||||
|
||||
#ifndef HAVE_SYSTEM_LOGICAL_PROCESSOR_INFORMATION
|
||||
typedef struct _SYSTEM_LOGICAL_PROCESSOR_INFORMATION {
|
||||
ULONG_PTR ProcessorMask;
|
||||
LOGICAL_PROCESSOR_RELATIONSHIP Relationship;
|
||||
_ANONYMOUS_UNION
|
||||
union {
|
||||
struct {
|
||||
BYTE flags;
|
||||
} ProcessorCore;
|
||||
struct {
|
||||
DWORD NodeNumber;
|
||||
} NumaNode;
|
||||
CACHE_DESCRIPTOR Cache;
|
||||
ULONGLONG Reserved[2];
|
||||
} DUMMYUNIONNAME;
|
||||
} SYSTEM_LOGICAL_PROCESSOR_INFORMATION, *PSYSTEM_LOGICAL_PROCESSOR_INFORMATION;
|
||||
#endif
|
||||
|
||||
/* Extended interface, for group support */
|
||||
|
||||
#ifndef HAVE_GROUP_AFFINITY
|
||||
typedef struct _GROUP_AFFINITY {
|
||||
KAFFINITY Mask;
|
||||
|
@ -93,35 +74,40 @@ typedef struct _GROUP_AFFINITY {
|
|||
} GROUP_AFFINITY, *PGROUP_AFFINITY;
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_PROCESSOR_RELATIONSHIP
|
||||
/* always use our own structure because the EfficiencyClass field didn't exist before Win10 */
|
||||
typedef struct HWLOC_PROCESSOR_RELATIONSHIP {
|
||||
BYTE Flags;
|
||||
BYTE EfficiencyClass; /* for RelationProcessorCore, higher means greater performance but less efficiency, only available in Win10+ */
|
||||
BYTE EfficiencyClass; /* for RelationProcessorCore, higher means greater performance but less efficiency */
|
||||
BYTE Reserved[20];
|
||||
WORD GroupCount;
|
||||
GROUP_AFFINITY GroupMask[ANYSIZE_ARRAY];
|
||||
} PROCESSOR_RELATIONSHIP, *PPROCESSOR_RELATIONSHIP;
|
||||
#endif
|
||||
} HWLOC_PROCESSOR_RELATIONSHIP;
|
||||
|
||||
#ifndef HAVE_NUMA_NODE_RELATIONSHIP
|
||||
typedef struct _NUMA_NODE_RELATIONSHIP {
|
||||
/* always use our own structure because the GroupCount and GroupMasks fields didn't exist in some Win10 */
|
||||
typedef struct HWLOC_NUMA_NODE_RELATIONSHIP {
|
||||
DWORD NodeNumber;
|
||||
BYTE Reserved[20];
|
||||
BYTE Reserved[18];
|
||||
WORD GroupCount;
|
||||
_ANONYMOUS_UNION
|
||||
union {
|
||||
GROUP_AFFINITY GroupMask;
|
||||
} NUMA_NODE_RELATIONSHIP, *PNUMA_NODE_RELATIONSHIP;
|
||||
#endif
|
||||
GROUP_AFFINITY GroupMasks[ANYSIZE_ARRAY];
|
||||
} DUMMYUNIONNAME;
|
||||
} HWLOC_NUMA_NODE_RELATIONSHIP;
|
||||
|
||||
#ifndef HAVE_CACHE_RELATIONSHIP
|
||||
typedef struct _CACHE_RELATIONSHIP {
|
||||
typedef struct HWLOC_CACHE_RELATIONSHIP {
|
||||
BYTE Level;
|
||||
BYTE Associativity;
|
||||
WORD LineSize;
|
||||
DWORD CacheSize;
|
||||
PROCESSOR_CACHE_TYPE Type;
|
||||
BYTE Reserved[20];
|
||||
BYTE Reserved[18];
|
||||
WORD GroupCount;
|
||||
union {
|
||||
GROUP_AFFINITY GroupMask;
|
||||
} CACHE_RELATIONSHIP, *PCACHE_RELATIONSHIP;
|
||||
#endif
|
||||
GROUP_AFFINITY GroupMasks[ANYSIZE_ARRAY];
|
||||
} DUMMYUNIONNAME;
|
||||
} HWLOC_CACHE_RELATIONSHIP;
|
||||
|
||||
#ifndef HAVE_PROCESSOR_GROUP_INFO
|
||||
typedef struct _PROCESSOR_GROUP_INFO {
|
||||
|
@ -141,20 +127,19 @@ typedef struct _GROUP_RELATIONSHIP {
|
|||
} GROUP_RELATIONSHIP, *PGROUP_RELATIONSHIP;
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
|
||||
typedef struct _SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX {
|
||||
/* always use our own structure because we need our own HWLOC_PROCESSOR/CACHE/NUMA_NODE_RELATIONSHIP */
|
||||
typedef struct HWLOC_SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX {
|
||||
LOGICAL_PROCESSOR_RELATIONSHIP Relationship;
|
||||
DWORD Size;
|
||||
_ANONYMOUS_UNION
|
||||
union {
|
||||
PROCESSOR_RELATIONSHIP Processor;
|
||||
NUMA_NODE_RELATIONSHIP NumaNode;
|
||||
CACHE_RELATIONSHIP Cache;
|
||||
HWLOC_PROCESSOR_RELATIONSHIP Processor;
|
||||
HWLOC_NUMA_NODE_RELATIONSHIP NumaNode;
|
||||
HWLOC_CACHE_RELATIONSHIP Cache;
|
||||
GROUP_RELATIONSHIP Group;
|
||||
/* Odd: no member to tell the cpu mask of the package... */
|
||||
} DUMMYUNIONNAME;
|
||||
} SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX, *PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX;
|
||||
#endif
|
||||
} HWLOC_SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX;
|
||||
|
||||
#ifndef HAVE_PSAPI_WORKING_SET_EX_BLOCK
|
||||
typedef union _PSAPI_WORKING_SET_EX_BLOCK {
|
||||
|
@ -200,10 +185,7 @@ static PFN_GETCURRENTPROCESSORNUMBER GetCurrentProcessorNumberProc;
|
|||
typedef VOID (WINAPI *PFN_GETCURRENTPROCESSORNUMBEREX)(PPROCESSOR_NUMBER);
|
||||
static PFN_GETCURRENTPROCESSORNUMBEREX GetCurrentProcessorNumberExProc;
|
||||
|
||||
typedef BOOL (WINAPI *PFN_GETLOGICALPROCESSORINFORMATION)(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION Buffer, PDWORD ReturnLength);
|
||||
static PFN_GETLOGICALPROCESSORINFORMATION GetLogicalProcessorInformationProc;
|
||||
|
||||
typedef BOOL (WINAPI *PFN_GETLOGICALPROCESSORINFORMATIONEX)(LOGICAL_PROCESSOR_RELATIONSHIP relationship, PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX Buffer, PDWORD ReturnLength);
|
||||
typedef BOOL (WINAPI *PFN_GETLOGICALPROCESSORINFORMATIONEX)(LOGICAL_PROCESSOR_RELATIONSHIP relationship, HWLOC_SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *Buffer, PDWORD ReturnLength);
|
||||
static PFN_GETLOGICALPROCESSORINFORMATIONEX GetLogicalProcessorInformationExProc;
|
||||
|
||||
typedef BOOL (WINAPI *PFN_SETTHREADGROUPAFFINITY)(HANDLE hThread, const GROUP_AFFINITY *GroupAffinity, PGROUP_AFFINITY PreviousGroupAffinity);
|
||||
|
@ -244,8 +226,6 @@ static void hwloc_win_get_function_ptrs(void)
|
|||
(PFN_GETACTIVEPROCESSORGROUPCOUNT) GetProcAddress(kernel32, "GetActiveProcessorGroupCount");
|
||||
GetActiveProcessorCountProc =
|
||||
(PFN_GETACTIVEPROCESSORCOUNT) GetProcAddress(kernel32, "GetActiveProcessorCount");
|
||||
GetLogicalProcessorInformationProc =
|
||||
(PFN_GETLOGICALPROCESSORINFORMATION) GetProcAddress(kernel32, "GetLogicalProcessorInformation");
|
||||
GetCurrentProcessorNumberProc =
|
||||
(PFN_GETCURRENTPROCESSORNUMBER) GetProcAddress(kernel32, "GetCurrentProcessorNumber");
|
||||
GetCurrentProcessorNumberExProc =
|
||||
|
@ -370,13 +350,13 @@ static hwloc_cpuset_t * processor_group_cpusets = NULL;
|
|||
static void
|
||||
hwloc_win_get_processor_groups(void)
|
||||
{
|
||||
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX procInfoTotal, tmpprocInfoTotal, procInfo;
|
||||
HWLOC_SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *procInfoTotal, *tmpprocInfoTotal, *procInfo;
|
||||
DWORD length;
|
||||
unsigned i;
|
||||
|
||||
hwloc_debug("querying windows processor groups\n");
|
||||
|
||||
if (!GetActiveProcessorGroupCountProc || !GetLogicalProcessorInformationExProc)
|
||||
if (!GetLogicalProcessorInformationExProc)
|
||||
goto error;
|
||||
|
||||
nr_processor_groups = GetActiveProcessorGroupCountProc();
|
||||
|
@ -415,6 +395,8 @@ hwloc_win_get_processor_groups(void)
|
|||
|
||||
assert(procInfo->Relationship == RelationGroup);
|
||||
|
||||
hwloc_debug("Found %u active windows processor groups\n",
|
||||
(unsigned) procInfo->Group.ActiveGroupCount);
|
||||
for (id = 0; id < procInfo->Group.ActiveGroupCount; id++) {
|
||||
KAFFINITY mask;
|
||||
hwloc_bitmap_t set;
|
||||
|
@ -424,8 +406,8 @@ hwloc_win_get_processor_groups(void)
|
|||
goto error_with_cpusets;
|
||||
|
||||
mask = procInfo->Group.GroupInfo[id].ActiveProcessorMask;
|
||||
hwloc_debug("group %u %d cpus mask %lx\n", id,
|
||||
procInfo->Group.GroupInfo[id].ActiveProcessorCount, mask);
|
||||
hwloc_debug("group %u with %u cpus mask 0x%llx\n", id,
|
||||
(unsigned) procInfo->Group.GroupInfo[id].ActiveProcessorCount, (unsigned long long) mask);
|
||||
/* KAFFINITY is ULONG_PTR */
|
||||
hwloc_bitmap_set_ith_ULONG_PTR(set, id, mask);
|
||||
/* FIXME: what if running 32bits on a 64bits windows with 64-processor groups?
|
||||
|
@ -1008,6 +990,8 @@ hwloc_look_windows(struct hwloc_backend *backend, struct hwloc_disc_status *dsta
|
|||
unsigned hostname_size = sizeof(hostname);
|
||||
int has_efficiencyclass = 0;
|
||||
struct hwloc_win_efficiency_classes eclasses;
|
||||
char *env = getenv("HWLOC_WINDOWS_PROCESSOR_GROUP_OBJS");
|
||||
int keep_pgroup_objs = (env && atoi(env));
|
||||
|
||||
assert(dstatus->phase == HWLOC_DISC_PHASE_CPU);
|
||||
|
||||
|
@ -1038,137 +1022,8 @@ hwloc_look_windows(struct hwloc_backend *backend, struct hwloc_disc_status *dsta
|
|||
|
||||
GetSystemInfo(&SystemInfo);
|
||||
|
||||
if (!GetLogicalProcessorInformationExProc && GetLogicalProcessorInformationProc) {
|
||||
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION procInfo, tmpprocInfo;
|
||||
unsigned id;
|
||||
unsigned i;
|
||||
struct hwloc_obj *obj;
|
||||
hwloc_obj_type_t type;
|
||||
|
||||
length = 0;
|
||||
procInfo = NULL;
|
||||
|
||||
while (1) {
|
||||
if (GetLogicalProcessorInformationProc(procInfo, &length))
|
||||
break;
|
||||
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
|
||||
return -1;
|
||||
tmpprocInfo = realloc(procInfo, length);
|
||||
if (!tmpprocInfo) {
|
||||
free(procInfo);
|
||||
goto out;
|
||||
}
|
||||
procInfo = tmpprocInfo;
|
||||
}
|
||||
|
||||
assert(!length || procInfo);
|
||||
|
||||
for (i = 0; i < length / sizeof(*procInfo); i++) {
|
||||
|
||||
/* Ignore unknown caches */
|
||||
if (procInfo->Relationship == RelationCache
|
||||
&& procInfo->Cache.Type != CacheUnified
|
||||
&& procInfo->Cache.Type != CacheData
|
||||
&& procInfo->Cache.Type != CacheInstruction)
|
||||
continue;
|
||||
|
||||
id = HWLOC_UNKNOWN_INDEX;
|
||||
switch (procInfo[i].Relationship) {
|
||||
case RelationNumaNode:
|
||||
type = HWLOC_OBJ_NUMANODE;
|
||||
id = procInfo[i].NumaNode.NodeNumber;
|
||||
gotnuma++;
|
||||
if (id > max_numanode_index)
|
||||
max_numanode_index = id;
|
||||
break;
|
||||
case RelationProcessorPackage:
|
||||
type = HWLOC_OBJ_PACKAGE;
|
||||
break;
|
||||
case RelationCache:
|
||||
type = (procInfo[i].Cache.Type == CacheInstruction ? HWLOC_OBJ_L1ICACHE : HWLOC_OBJ_L1CACHE) + procInfo[i].Cache.Level - 1;
|
||||
break;
|
||||
case RelationProcessorCore:
|
||||
type = HWLOC_OBJ_CORE;
|
||||
break;
|
||||
case RelationGroup:
|
||||
default:
|
||||
type = HWLOC_OBJ_GROUP;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!hwloc_filter_check_keep_object_type(topology, type))
|
||||
continue;
|
||||
|
||||
obj = hwloc_alloc_setup_object(topology, type, id);
|
||||
obj->cpuset = hwloc_bitmap_alloc();
|
||||
hwloc_debug("%s#%u mask %llx\n", hwloc_obj_type_string(type), id, (unsigned long long) procInfo[i].ProcessorMask);
|
||||
/* ProcessorMask is a ULONG_PTR */
|
||||
hwloc_bitmap_set_ith_ULONG_PTR(obj->cpuset, 0, procInfo[i].ProcessorMask);
|
||||
hwloc_debug_2args_bitmap("%s#%u bitmap %s\n", hwloc_obj_type_string(type), id, obj->cpuset);
|
||||
|
||||
switch (type) {
|
||||
case HWLOC_OBJ_NUMANODE:
|
||||
{
|
||||
ULONGLONG avail;
|
||||
obj->nodeset = hwloc_bitmap_alloc();
|
||||
hwloc_bitmap_set(obj->nodeset, id);
|
||||
if ((GetNumaAvailableMemoryNodeExProc && GetNumaAvailableMemoryNodeExProc(id, &avail))
|
||||
|| (GetNumaAvailableMemoryNodeProc && GetNumaAvailableMemoryNodeProc(id, &avail))) {
|
||||
obj->attr->numanode.local_memory = avail;
|
||||
gotnumamemory++;
|
||||
}
|
||||
obj->attr->numanode.page_types_len = 2;
|
||||
obj->attr->numanode.page_types = malloc(2 * sizeof(*obj->attr->numanode.page_types));
|
||||
memset(obj->attr->numanode.page_types, 0, 2 * sizeof(*obj->attr->numanode.page_types));
|
||||
obj->attr->numanode.page_types_len = 1;
|
||||
obj->attr->numanode.page_types[0].size = SystemInfo.dwPageSize;
|
||||
#if HAVE_DECL__SC_LARGE_PAGESIZE
|
||||
obj->attr->numanode.page_types_len++;
|
||||
obj->attr->numanode.page_types[1].size = sysconf(_SC_LARGE_PAGESIZE);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case HWLOC_OBJ_L1CACHE:
|
||||
case HWLOC_OBJ_L2CACHE:
|
||||
case HWLOC_OBJ_L3CACHE:
|
||||
case HWLOC_OBJ_L4CACHE:
|
||||
case HWLOC_OBJ_L5CACHE:
|
||||
case HWLOC_OBJ_L1ICACHE:
|
||||
case HWLOC_OBJ_L2ICACHE:
|
||||
case HWLOC_OBJ_L3ICACHE:
|
||||
obj->attr->cache.size = procInfo[i].Cache.Size;
|
||||
obj->attr->cache.associativity = procInfo[i].Cache.Associativity == CACHE_FULLY_ASSOCIATIVE ? -1 : procInfo[i].Cache.Associativity ;
|
||||
obj->attr->cache.linesize = procInfo[i].Cache.LineSize;
|
||||
obj->attr->cache.depth = procInfo[i].Cache.Level;
|
||||
switch (procInfo->Cache.Type) {
|
||||
case CacheUnified:
|
||||
obj->attr->cache.type = HWLOC_OBJ_CACHE_UNIFIED;
|
||||
break;
|
||||
case CacheData:
|
||||
obj->attr->cache.type = HWLOC_OBJ_CACHE_DATA;
|
||||
break;
|
||||
case CacheInstruction:
|
||||
obj->attr->cache.type = HWLOC_OBJ_CACHE_INSTRUCTION;
|
||||
break;
|
||||
default:
|
||||
hwloc_free_unlinked_object(obj);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case HWLOC_OBJ_GROUP:
|
||||
obj->attr->group.kind = procInfo[i].Relationship == RelationGroup ? HWLOC_GROUP_KIND_WINDOWS_PROCESSOR_GROUP : HWLOC_GROUP_KIND_WINDOWS_RELATIONSHIP_UNKNOWN;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
hwloc__insert_object_by_cpuset(topology, NULL, obj, "windows:GetLogicalProcessorInformation");
|
||||
}
|
||||
|
||||
free(procInfo);
|
||||
}
|
||||
|
||||
if (GetLogicalProcessorInformationExProc) {
|
||||
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX procInfoTotal, tmpprocInfoTotal, procInfo;
|
||||
HWLOC_SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *procInfoTotal, *tmpprocInfoTotal, *procInfo;
|
||||
unsigned id;
|
||||
struct hwloc_obj *obj;
|
||||
hwloc_obj_type_t type;
|
||||
|
@ -1207,8 +1062,16 @@ hwloc_look_windows(struct hwloc_backend *backend, struct hwloc_disc_status *dsta
|
|||
switch (procInfo->Relationship) {
|
||||
case RelationNumaNode:
|
||||
type = HWLOC_OBJ_NUMANODE;
|
||||
/* Starting with Windows 11 and Server 2022, the GroupCount field is valid and >=1
|
||||
* and we may read GroupMasks[]. Older releases have GroupCount==0 and we must read GroupMask.
|
||||
*/
|
||||
if (procInfo->NumaNode.GroupCount) {
|
||||
num = procInfo->NumaNode.GroupCount;
|
||||
GroupMask = procInfo->NumaNode.GroupMasks;
|
||||
} else {
|
||||
num = 1;
|
||||
GroupMask = &procInfo->NumaNode.GroupMask;
|
||||
}
|
||||
id = procInfo->NumaNode.NodeNumber;
|
||||
gotnuma++;
|
||||
if (id > max_numanode_index)
|
||||
|
@ -1221,18 +1084,20 @@ hwloc_look_windows(struct hwloc_backend *backend, struct hwloc_disc_status *dsta
|
|||
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 */
|
||||
if (procInfo->Cache.GroupCount) {
|
||||
num = procInfo->Cache.GroupCount;
|
||||
GroupMask = procInfo->Cache.GroupMasks;
|
||||
} else {
|
||||
num = 1;
|
||||
GroupMask = &procInfo->Cache.GroupMask;
|
||||
}
|
||||
break;
|
||||
case RelationProcessorCore:
|
||||
type = HWLOC_OBJ_CORE;
|
||||
num = procInfo->Processor.GroupCount;
|
||||
GroupMask = procInfo->Processor.GroupMask;
|
||||
if (has_efficiencyclass)
|
||||
/* the EfficiencyClass field didn't exist before Windows10 and recent MSVC headers,
|
||||
* so just access it manually instead of trying to detect it.
|
||||
*/
|
||||
efficiency_class = * ((&procInfo->Processor.Flags) + 1);
|
||||
efficiency_class = procInfo->Processor.EfficiencyClass;
|
||||
break;
|
||||
case RelationGroup:
|
||||
/* So strange an interface... */
|
||||
|
@ -1257,11 +1122,12 @@ hwloc_look_windows(struct hwloc_backend *backend, struct hwloc_disc_status *dsta
|
|||
groups_pu_set = hwloc_bitmap_alloc();
|
||||
hwloc_bitmap_or(groups_pu_set, groups_pu_set, set);
|
||||
|
||||
if (hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_GROUP)) {
|
||||
/* Ignore processor groups unless requested and filtered-in */
|
||||
if (keep_pgroup_objs && hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_GROUP)) {
|
||||
obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_GROUP, id);
|
||||
obj->cpuset = set;
|
||||
obj->attr->group.kind = HWLOC_GROUP_KIND_WINDOWS_PROCESSOR_GROUP;
|
||||
hwloc__insert_object_by_cpuset(topology, NULL, obj, "windows:GetLogicalProcessorInformation:ProcessorGroup");
|
||||
hwloc__insert_object_by_cpuset(topology, NULL, obj, "windows:GetLogicalProcessorInformationEx:ProcessorGroup");
|
||||
} else
|
||||
hwloc_bitmap_free(set);
|
||||
}
|
||||
|
|
35
src/3rdparty/hwloc/src/topology-x86.c
vendored
35
src/3rdparty/hwloc/src/topology-x86.c
vendored
|
@ -500,7 +500,8 @@ static void read_amd_cores_topoext(struct procinfo *infos, unsigned long flags,
|
|||
nodes_per_proc = ((ecx >> 8) & 7) + 1;
|
||||
}
|
||||
if ((infos->cpufamilynumber == 0x15 && nodes_per_proc > 2)
|
||||
|| ((infos->cpufamilynumber == 0x17 || infos->cpufamilynumber == 0x18) && nodes_per_proc > 4)) {
|
||||
|| ((infos->cpufamilynumber == 0x17 || infos->cpufamilynumber == 0x18) && nodes_per_proc > 4)
|
||||
|| (infos->cpufamilynumber == 0x19 && nodes_per_proc > 1)) {
|
||||
hwloc_debug("warning: undefined nodes_per_proc value %u, assuming it means %u\n", nodes_per_proc, nodes_per_proc);
|
||||
}
|
||||
}
|
||||
|
@ -775,13 +776,19 @@ static void look_proc(struct hwloc_backend *backend, struct procinfo *infos, uns
|
|||
|
||||
} else if (cpuid_type == amd) {
|
||||
/* AMD quirks */
|
||||
if (infos->cpufamilynumber == 0x17
|
||||
&& cache->level == 3 && cache->nbthreads_sharing == 6) {
|
||||
/* AMD family 0x17 always shares L3 between 8 APIC ids,
|
||||
* even when only 6 APIC ids are enabled and reported in nbthreads_sharing
|
||||
* (on 24-core CPUs).
|
||||
if (infos->cpufamilynumber >= 0x17 && cache->level == 3) {
|
||||
/* AMD family 0x19 always shares L3 between 16 APIC ids (8 HT cores).
|
||||
* while Family 0x17 shares between 8 APIC ids (4 HT cores).
|
||||
* But many models have less APIC ids enabled and reported in nbthreads_sharing.
|
||||
* It means we must round-up nbthreads_sharing to the nearest power of 2
|
||||
* before computing cacheid.
|
||||
*/
|
||||
cache->cacheid = infos->apicid / 8;
|
||||
unsigned nbapics_sharing = cache->nbthreads_sharing;
|
||||
if (nbapics_sharing & (nbapics_sharing-1))
|
||||
/* not a power of two, round-up */
|
||||
nbapics_sharing = 1U<<(1+hwloc_ffsl(nbapics_sharing));
|
||||
|
||||
cache->cacheid = infos->apicid / nbapics_sharing;
|
||||
|
||||
} else if (infos->cpufamilynumber== 0x10 && infos->cpumodelnumber == 0x9
|
||||
&& cache->level == 3
|
||||
|
@ -807,7 +814,7 @@ static void look_proc(struct hwloc_backend *backend, struct procinfo *infos, uns
|
|||
} else if (infos->cpufamilynumber == 0x15
|
||||
&& (infos->cpumodelnumber == 0x1 /* Bulldozer */ || infos->cpumodelnumber == 0x2 /* Piledriver */)
|
||||
&& cache->level == 3 && cache->nbthreads_sharing == 6) {
|
||||
/* AMD Bulldozer and Piledriver 12-core processors have same APIC ids as Magny-Cours below,
|
||||
/* AMD Bulldozer and Piledriver 12-core processors have same APIC ids as Magny-Cours above,
|
||||
* but we can't merge the checks because the original nbthreads_sharing must be exactly 6 here.
|
||||
*/
|
||||
cache->cacheid = (infos->apicid % legacy_max_log_proc) / cache->nbthreads_sharing /* cacheid within the package */
|
||||
|
@ -1231,6 +1238,18 @@ static void summarize(struct hwloc_backend *backend, struct procinfo *infos, uns
|
|||
}
|
||||
}
|
||||
cache = hwloc_alloc_setup_object(topology, otype, HWLOC_UNKNOWN_INDEX);
|
||||
/* We don't specify the os_index of caches because we want to be
|
||||
* 100% sure they are identical to what the Linux kernel reports
|
||||
* (so that things like resctrl work).
|
||||
* However, vendor/model-specific quirks in the x86 code above
|
||||
* make this difficult.
|
||||
*
|
||||
* Caveat: if the x86 backend is used on Linux to avoid kernel bugs,
|
||||
* IDs won't be available to resctrl users. But resctrl heavily
|
||||
* relies on the kernel x86 discovery being non-buggy anyway.
|
||||
*
|
||||
* TODO: make this optional? or only disable it on Linux?
|
||||
*/
|
||||
cache->attr->cache.depth = level;
|
||||
cache->attr->cache.size = infos[i].cache[l].size;
|
||||
cache->attr->cache.linesize = infos[i].cache[l].linesize;
|
||||
|
|
3
src/3rdparty/hwloc/src/topology-xml.c
vendored
3
src/3rdparty/hwloc/src/topology-xml.c
vendored
|
@ -243,7 +243,7 @@ hwloc__xml_import_object_attr(struct hwloc_topology *topology,
|
|||
else if (!strcmp(name, "dont_merge")) {
|
||||
unsigned long lvalue = strtoul(value, NULL, 10);
|
||||
if (obj->type == HWLOC_OBJ_GROUP)
|
||||
obj->attr->group.dont_merge = lvalue;
|
||||
obj->attr->group.dont_merge = (unsigned char) lvalue;
|
||||
else if (hwloc__xml_verbose())
|
||||
fprintf(stderr, "%s: ignoring dont_merge attribute for non-group object type\n",
|
||||
state->global->msgprefix);
|
||||
|
@ -2825,6 +2825,7 @@ hwloc__xml_v1export_object_with_memory(hwloc__xml_export_state_t parentstate, hw
|
|||
/* child has sibling, we must add a Group around those memory children */
|
||||
hwloc_obj_t group = parentstate->global->v1_memory_group;
|
||||
parentstate->new_child(parentstate, &gstate, "object");
|
||||
group->parent = obj->parent;
|
||||
group->cpuset = obj->cpuset;
|
||||
group->complete_cpuset = obj->complete_cpuset;
|
||||
group->nodeset = obj->nodeset;
|
||||
|
|
64
src/3rdparty/hwloc/src/topology.c
vendored
64
src/3rdparty/hwloc/src/topology.c
vendored
|
@ -69,7 +69,7 @@
|
|||
* it will break in cygwin, we'll have to use both putenv() and SetEnvironmentVariable().
|
||||
* Hopefully L0 will be provide a way to enable Sysman without env vars before it happens.
|
||||
*/
|
||||
#ifdef HWLOC_HAVE_ATTRIBUTE_CONSTRUCTOR
|
||||
#if HWLOC_HAVE_ATTRIBUTE_CONSTRUCTOR
|
||||
static void hwloc_constructor(void) __attribute__((constructor));
|
||||
static void hwloc_constructor(void)
|
||||
{
|
||||
|
@ -1901,6 +1901,9 @@ hwloc_topology_alloc_group_object(struct hwloc_topology *topology)
|
|||
static void hwloc_propagate_symmetric_subtree(hwloc_topology_t topology, hwloc_obj_t root);
|
||||
static void propagate_total_memory(hwloc_obj_t obj);
|
||||
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);
|
||||
|
||||
hwloc_obj_t
|
||||
hwloc_topology_insert_group_object(struct hwloc_topology *topology, hwloc_obj_t obj)
|
||||
|
@ -2474,13 +2477,26 @@ hwloc_compare_levels_structure(hwloc_topology_t topology, unsigned i)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* return > 0 if any level was removed, which means reconnect is needed */
|
||||
static void
|
||||
/* return > 0 if any level was removed.
|
||||
* performs its own reconnect internally if needed
|
||||
*/
|
||||
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;
|
||||
|
@ -2646,6 +2662,22 @@ hwloc_filter_levels_keep_structure(hwloc_topology_t topology)
|
|||
topology->type_depth[type] = HWLOC_TYPE_DEPTH_MULTIPLE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -2963,9 +2995,9 @@ hwloc_list_special_objects(hwloc_topology_t topology, hwloc_obj_t obj)
|
|||
}
|
||||
}
|
||||
|
||||
/* Build I/O levels */
|
||||
/* Build Memory, I/O and Misc levels */
|
||||
static int
|
||||
hwloc_connect_io_misc_levels(hwloc_topology_t topology)
|
||||
hwloc_connect_special_levels(hwloc_topology_t topology)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
|
@ -3176,6 +3208,10 @@ hwloc_connect_levels(hwloc_topology_t topology)
|
|||
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;
|
||||
|
@ -3188,7 +3224,7 @@ hwloc_topology_reconnect(struct hwloc_topology *topology, unsigned long flags)
|
|||
if (hwloc_connect_levels(topology) < 0)
|
||||
return -1;
|
||||
|
||||
if (hwloc_connect_io_misc_levels(topology) < 0)
|
||||
if (hwloc_connect_special_levels(topology) < 0)
|
||||
return -1;
|
||||
|
||||
topology->modified = 0;
|
||||
|
@ -3529,15 +3565,12 @@ hwloc_discover(struct hwloc_topology *topology,
|
|||
}
|
||||
hwloc_debug_print_objects(0, topology->levels[0][0]);
|
||||
|
||||
/* Reconnect things after all these changes.
|
||||
* Often needed because of Groups inserted for I/Os.
|
||||
* And required for KEEP_STRUCTURE below.
|
||||
*/
|
||||
if (hwloc_topology_reconnect(topology, 0) < 0)
|
||||
return -1;
|
||||
|
||||
hwloc_debug("%s", "\nRemoving levels with HWLOC_TYPE_FILTER_KEEP_STRUCTURE\n");
|
||||
hwloc_filter_levels_keep_structure(topology);
|
||||
if (hwloc_filter_levels_keep_structure(topology) < 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) */
|
||||
|
@ -4360,14 +4393,13 @@ hwloc_topology_restrict(struct hwloc_topology *topology, hwloc_const_bitmap_t se
|
|||
hwloc_bitmap_free(droppedcpuset);
|
||||
hwloc_bitmap_free(droppednodeset);
|
||||
|
||||
if (hwloc_topology_reconnect(topology, 0) < 0)
|
||||
if (hwloc_filter_levels_keep_structure(topology) < 0) /* takes care of reconnecting internally */
|
||||
goto out;
|
||||
|
||||
/* some objects may have disappeared, we need to update distances objs arrays */
|
||||
hwloc_internal_distances_invalidate_cached_objs(topology);
|
||||
hwloc_internal_memattrs_need_refresh(topology);
|
||||
|
||||
hwloc_filter_levels_keep_structure(topology);
|
||||
hwloc_propagate_symmetric_subtree(topology, topology->levels[0][0]);
|
||||
propagate_total_memory(topology->levels[0][0]);
|
||||
hwloc_internal_cpukinds_restrict(topology);
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
/* 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-2019 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2021 XMRig <support@xmrig.com>
|
||||
* Copyright (c) 2018-2022 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2022 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 +16,6 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <cinttypes>
|
||||
#include <cstdio>
|
||||
#include <uv.h>
|
||||
|
@ -158,7 +151,7 @@ static void print_memory(const Config *config)
|
|||
"", memory.id().data(), memory.size() / oneGiB, memory.type(), memory.speed() / 1000000ULL, memory.product().data());
|
||||
}
|
||||
else if (printEmpty) {
|
||||
Log::print(WHITE_BOLD(" %-13s") "%s: " BLACK_BOLD("<empty>"), "", memory.slot().data());
|
||||
Log::print(WHITE_BOLD(" %-13s") "%s: " BLACK_BOLD("<empty>"), "", memory.id().data());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
/* 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-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2022 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2022 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
|
||||
|
|
|
@ -157,7 +157,15 @@ size_t inline generate<Algorithm::ARGON2>(Threads<CpuThreads> &threads, uint32_t
|
|||
template<>
|
||||
size_t inline generate<Algorithm::ASTROBWT>(Threads<CpuThreads>& threads, uint32_t limit)
|
||||
{
|
||||
return generate(Algorithm::kASTROBWT, threads, Algorithm::ASTROBWT_DERO, limit);
|
||||
size_t count = 0;
|
||||
|
||||
if (!threads.isExist(Algorithm::ASTROBWT_DERO_2)) {
|
||||
auto v2 = Cpu::info()->threads(Algorithm::ASTROBWT_DERO_2, limit);
|
||||
count += threads.move(Algorithm::kASTROBWT_DERO_2, std::move(v2));
|
||||
}
|
||||
|
||||
count += generate(Algorithm::kASTROBWT, threads, Algorithm::ASTROBWT_DERO, limit);
|
||||
return count;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -224,9 +224,8 @@ bool xmrig::CpuWorker<N>::selfTest()
|
|||
# endif
|
||||
|
||||
# ifdef XMRIG_ALGO_ASTROBWT
|
||||
if (m_algorithm.family() == Algorithm::ASTROBWT) {
|
||||
return verify(Algorithm::ASTROBWT_DERO, astrobwt_dero_test_out);
|
||||
}
|
||||
if (m_algorithm.id() == Algorithm::ASTROBWT_DERO) return verify(Algorithm::ASTROBWT_DERO, astrobwt_dero_test_out);
|
||||
if (m_algorithm.id() == Algorithm::ASTROBWT_DERO_2) return verify(Algorithm::ASTROBWT_DERO_2, astrobwt_dero_2_test_out);
|
||||
# endif
|
||||
|
||||
return false;
|
||||
|
@ -320,9 +319,16 @@ void xmrig::CpuWorker<N>::start()
|
|||
|
||||
# ifdef XMRIG_ALGO_ASTROBWT
|
||||
case Algorithm::ASTROBWT:
|
||||
if (job.algorithm().id() == Algorithm::ASTROBWT_DERO) {
|
||||
if (!astrobwt::astrobwt_dero(m_job.blob(), job.size(), m_ctx[0]->memory, m_hash, m_astrobwtMaxSize, m_astrobwtAVX2)) {
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!astrobwt::astrobwt_dero_v2(m_job.blob(), job.size(), m_ctx[0]->memory, m_hash)) {
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
# endif
|
||||
|
||||
|
|
|
@ -221,7 +221,7 @@ public:
|
|||
size_t algo_l3 = algo.l3();
|
||||
|
||||
# ifdef XMRIG_ALGO_ASTROBWT
|
||||
if (algo.family() == Algorithm::ASTROBWT) {
|
||||
if (algo.id() == Algorithm::ASTROBWT_DERO) {
|
||||
algo_l3 = CudaAstroBWTRunner::BWT_DATA_STRIDE * 17 + 1024;
|
||||
}
|
||||
# endif
|
||||
|
|
|
@ -139,7 +139,14 @@ size_t inline generate<Algorithm::RANDOM_X>(Threads<CudaThreads> &threads, const
|
|||
template<>
|
||||
size_t inline generate<Algorithm::ASTROBWT>(Threads<CudaThreads> &threads, const std::vector<CudaDevice> &devices)
|
||||
{
|
||||
return generate(Algorithm::kASTROBWT, threads, Algorithm::ASTROBWT_DERO, devices);
|
||||
size_t count = 0;
|
||||
|
||||
if (!threads.isExist(Algorithm::ASTROBWT_DERO_2)) {
|
||||
count += threads.move(Algorithm::kASTROBWT_DERO_2, CudaThreads(devices, Algorithm::ASTROBWT_DERO_2));
|
||||
}
|
||||
|
||||
count += generate(Algorithm::kASTROBWT, threads, Algorithm::ASTROBWT_DERO, devices);
|
||||
return count;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -32,11 +32,17 @@
|
|||
constexpr uint32_t xmrig::CudaAstroBWTRunner::BWT_DATA_STRIDE;
|
||||
|
||||
|
||||
xmrig::CudaAstroBWTRunner::CudaAstroBWTRunner(size_t index, const CudaLaunchData &data) :
|
||||
CudaBaseRunner(index, data)
|
||||
xmrig::CudaAstroBWTRunner::CudaAstroBWTRunner(size_t index, const CudaLaunchData &data)
|
||||
: CudaBaseRunner(index, data)
|
||||
, m_algorithm(data.algorithm)
|
||||
{
|
||||
m_intensity = m_data.thread.threads() * m_data.thread.blocks();
|
||||
m_intensity -= m_intensity % 32;
|
||||
|
||||
// Dero HE has very fast blocks, so we can't use high intensity
|
||||
if ((m_algorithm == Algorithm::ASTROBWT_DERO_2) && (m_intensity > 4096)) {
|
||||
m_intensity = 4096;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -58,10 +64,14 @@ bool xmrig::CudaAstroBWTRunner::set(const Job &job, uint8_t *blob)
|
|||
|
||||
size_t xmrig::CudaAstroBWTRunner::roundSize() const
|
||||
{
|
||||
if (m_algorithm == Algorithm::ASTROBWT_DERO_2) {
|
||||
return m_intensity;
|
||||
}
|
||||
|
||||
constexpr uint32_t STAGE1_SIZE = 147253;
|
||||
constexpr uint32_t STAGE1_DATA_STRIDE = (STAGE1_SIZE + 256 + 255) & ~255U;
|
||||
|
||||
const uint32_t BATCH2_SIZE = m_intensity;
|
||||
const uint32_t BATCH2_SIZE = static_cast<uint32_t>(m_intensity);
|
||||
const uint32_t BWT_ALLOCATION_SIZE = BATCH2_SIZE * BWT_DATA_STRIDE;
|
||||
const uint32_t BATCH1_SIZE = (BWT_ALLOCATION_SIZE / STAGE1_DATA_STRIDE) & ~255U;
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
|
||||
#include "backend/cuda/runners/CudaBaseRunner.h"
|
||||
#include "base/crypto/Algorithm.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
@ -50,6 +51,7 @@ protected:
|
|||
|
||||
private:
|
||||
size_t m_intensity = 0;
|
||||
Algorithm m_algorithm;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -205,7 +205,7 @@ public:
|
|||
size_t algo_l3 = algo.l3();
|
||||
|
||||
# ifdef XMRIG_ALGO_ASTROBWT
|
||||
if (algo.family() == Algorithm::ASTROBWT) {
|
||||
if (algo.id() == Algorithm::ASTROBWT_DERO) {
|
||||
algo_l3 = OclAstroBWTRunner::BWT_DATA_STRIDE * 17 + 324;
|
||||
}
|
||||
# endif
|
||||
|
|
|
@ -133,7 +133,14 @@ size_t inline generate<Algorithm::RANDOM_X>(Threads<OclThreads> &threads, const
|
|||
template<>
|
||||
size_t inline generate<Algorithm::ASTROBWT>(Threads<OclThreads>& threads, const std::vector<OclDevice>& devices)
|
||||
{
|
||||
return generate(Algorithm::kASTROBWT, threads, Algorithm::ASTROBWT_DERO, devices);
|
||||
size_t count = 0;
|
||||
|
||||
if (!threads.isExist(Algorithm::ASTROBWT_DERO_2)) {
|
||||
count += threads.move(Algorithm::kASTROBWT_DERO_2, OclThreads(devices, Algorithm::ASTROBWT_DERO_2));
|
||||
}
|
||||
|
||||
count += generate(Algorithm::kASTROBWT, threads, Algorithm::ASTROBWT_DERO, devices);
|
||||
return count;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
|
||||
#ifdef XMRIG_ALGO_ASTROBWT
|
||||
# include "backend/opencl/runners/OclAstroBWTRunner.h"
|
||||
# include "backend/opencl/runners/OclAstroBWT_v2_Runner.h"
|
||||
#endif
|
||||
|
||||
#ifdef XMRIG_ALGO_KAWPOW
|
||||
|
@ -92,7 +93,12 @@ xmrig::OclWorker::OclWorker(size_t id, const OclLaunchData &data) :
|
|||
|
||||
case Algorithm::ASTROBWT:
|
||||
# ifdef XMRIG_ALGO_ASTROBWT
|
||||
if (m_algorithm.id() == Algorithm::ASTROBWT_DERO_2) {
|
||||
m_runner = new OclAstroBWT_v2_Runner(id, data);
|
||||
}
|
||||
else {
|
||||
m_runner = new OclAstroBWTRunner(id, data);
|
||||
}
|
||||
# endif
|
||||
break;
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
|
||||
#ifdef XMRIG_ALGO_ASTROBWT
|
||||
# include "backend/opencl/cl/astrobwt/astrobwt_cl.h"
|
||||
# include "backend/opencl/cl/astrobwt_v2/astrobwt_v2_cl.h"
|
||||
#endif
|
||||
|
||||
#ifdef XMRIG_ALGO_KAWPOW
|
||||
|
@ -52,7 +53,7 @@ const char *xmrig::OclSource::get(const Algorithm &algorithm)
|
|||
|
||||
# ifdef XMRIG_ALGO_ASTROBWT
|
||||
if (algorithm.family() == Algorithm::ASTROBWT) {
|
||||
return astrobwt_cl;
|
||||
return (algorithm.id() == Algorithm::ASTROBWT_DERO_2) ? astrobwt_v2_cl : astrobwt_cl;
|
||||
}
|
||||
# endif
|
||||
|
||||
|
|
179
src/backend/opencl/cl/astrobwt_v2/BWT.cl
Normal file
179
src/backend/opencl/cl/astrobwt_v2/BWT.cl
Normal file
|
@ -0,0 +1,179 @@
|
|||
/* 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-2022 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2022 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/>.
|
||||
*/
|
||||
|
||||
#define BLOCK_SIZE 1024
|
||||
#define DATA_SIZE 9973
|
||||
#define DATA_STRIDE 10240
|
||||
#define BITS 14
|
||||
#define COUNTERS_SIZE (1 << BITS)
|
||||
|
||||
inline uint16_t atomic_inc16(__local uint16_t* value)
|
||||
{
|
||||
const size_t k = (size_t) value;
|
||||
if ((k & 3) == 0) {
|
||||
return atomic_add((__local uint32_t*) value, 1);
|
||||
}
|
||||
return atomic_add((__local uint32_t*)(k - 2), 0x10000) >> 16;
|
||||
}
|
||||
|
||||
__attribute__((reqd_work_group_size(BLOCK_SIZE, 1, 1)))
|
||||
__kernel void BWT_preprocess(__global const uint8_t* datas, __global uint32_t* keys)
|
||||
{
|
||||
const uint32_t data_offset = get_group_id(0) * DATA_STRIDE;
|
||||
const uint32_t tid = get_local_id(0);
|
||||
|
||||
__local uint32_t counters_buf[COUNTERS_SIZE / 2];
|
||||
__local uint16_t* counters = (__local uint16_t*) counters_buf;
|
||||
for (uint32_t i = tid; i < COUNTERS_SIZE / 2; i += BLOCK_SIZE) {
|
||||
counters_buf[i] = 0;
|
||||
}
|
||||
barrier(CLK_LOCAL_MEM_FENCE);
|
||||
|
||||
datas += data_offset;
|
||||
keys += data_offset;
|
||||
|
||||
for (uint32_t i = tid; i < DATA_SIZE; i += BLOCK_SIZE) {
|
||||
const uint32_t k0 = datas[i];
|
||||
const uint32_t k1 = datas[i + 1];
|
||||
const uint32_t k = ((k0 << 8) | k1) >> (16 - BITS);
|
||||
atomic_inc16(counters + k);
|
||||
}
|
||||
barrier(CLK_LOCAL_MEM_FENCE);
|
||||
|
||||
#pragma unroll BITS
|
||||
for (int k = 0; k < BITS; ++k) {
|
||||
for (uint32_t t1 = tid; t1 < ((COUNTERS_SIZE / 2) >> k); t1 += BLOCK_SIZE) {
|
||||
const uint32_t i = (t1 << (k + 1)) + ((1 << (k + 1)) - 1);
|
||||
counters[i] += counters[i - (1 << k)];
|
||||
}
|
||||
barrier(CLK_LOCAL_MEM_FENCE);
|
||||
}
|
||||
|
||||
if (tid == 0) {
|
||||
counters[COUNTERS_SIZE - 1] = 0;
|
||||
}
|
||||
barrier(CLK_LOCAL_MEM_FENCE);
|
||||
|
||||
#pragma unroll BITS
|
||||
for (int k = BITS - 1; k >= 0; --k) {
|
||||
for (uint32_t t1 = tid; t1 < ((COUNTERS_SIZE / 2) >> k); t1 += BLOCK_SIZE) {
|
||||
const uint32_t i = (t1 << (k + 1)) + ((1 << (k + 1)) - 1);
|
||||
const uint16_t old = counters[i];
|
||||
counters[i] = old + counters[i - (1 << k)];
|
||||
counters[i - (1 << k)] = old;
|
||||
}
|
||||
barrier(CLK_LOCAL_MEM_FENCE);
|
||||
}
|
||||
|
||||
for (uint32_t i = tid; i < DATA_SIZE; i += BLOCK_SIZE) {
|
||||
const uint32_t k0 = datas[i];
|
||||
const uint32_t k1 = datas[i + 1];
|
||||
const uint32_t k = (k0 << 8) | k1;
|
||||
const uint32_t index = atomic_inc16(counters + (k >> (16 - BITS)));
|
||||
keys[index] = (k << 16) | i;
|
||||
}
|
||||
}
|
||||
|
||||
inline void fix_order(__global const uint8_t* input, uint32_t a, uint32_t b, __global uint32_t* keys)
|
||||
{
|
||||
const uint32_t ka = keys[a];
|
||||
const uint32_t kb = keys[b];
|
||||
const uint32_t index_a = ka & 0xFFFF;
|
||||
const uint32_t index_b = kb & 0xFFFF;
|
||||
|
||||
const uint32_t value_a =
|
||||
(((uint32_t)input[index_a + 1]) << 24) |
|
||||
(((uint32_t)input[index_a + 2]) << 16) |
|
||||
(((uint32_t)input[index_a + 3]) << 8) |
|
||||
((uint32_t)input[index_a + 4]);
|
||||
|
||||
const uint32_t value_b =
|
||||
(((uint32_t)input[index_b + 1]) << 24) |
|
||||
(((uint32_t)input[index_b + 2]) << 16) |
|
||||
(((uint32_t)input[index_b + 3]) << 8) |
|
||||
((uint32_t)input[index_b + 4]);
|
||||
|
||||
if (value_a > value_b)
|
||||
{
|
||||
keys[a] = kb;
|
||||
keys[b] = ka;
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((reqd_work_group_size(BLOCK_SIZE, 1, 1)))
|
||||
__kernel void BWT_fix_order(__global const uint8_t* datas, __global uint32_t* keys, __global uint16_t* values)
|
||||
{
|
||||
const uint32_t tid = get_local_id(0);
|
||||
const uint32_t gid = get_group_id(0);
|
||||
|
||||
const uint32_t data_offset = gid * 10240;
|
||||
|
||||
const uint32_t N = 9973;
|
||||
|
||||
datas += data_offset;
|
||||
keys += data_offset;
|
||||
values += data_offset;
|
||||
|
||||
for (uint32_t i = tid, N1 = N - 1; i < N1; i += BLOCK_SIZE)
|
||||
{
|
||||
const uint32_t value = keys[i] >> (32 - BITS);
|
||||
if (value == (keys[i + 1] >> (32 - BITS)))
|
||||
{
|
||||
if (i && (value == (keys[i - 1] >> (32 - BITS))))
|
||||
continue;
|
||||
|
||||
uint32_t n = i + 2;
|
||||
while ((n < N) && (value == (keys[n] >> (32 - BITS))))
|
||||
++n;
|
||||
|
||||
for (uint32_t j = i; j < n; ++j)
|
||||
for (uint32_t k = j + 1; k < n; ++k)
|
||||
fix_order(datas, j, k, keys);
|
||||
}
|
||||
}
|
||||
barrier(CLK_GLOBAL_MEM_FENCE);
|
||||
|
||||
for (uint32_t i = tid; i < N; i += BLOCK_SIZE) {
|
||||
values[i] = keys[i];
|
||||
}
|
||||
}
|
||||
|
||||
__kernel void find_shares(__global const uint64_t* hashes, uint64_t target, __global uint32_t* shares)
|
||||
{
|
||||
const uint32_t global_index = get_global_id(0);
|
||||
|
||||
if (hashes[global_index * 4 + 3] >= target) {
|
||||
return;
|
||||
}
|
||||
|
||||
const uint32_t idx = atomic_inc(shares + 0xFF);
|
||||
if (idx < 0xFF)
|
||||
shares[idx] = global_index;
|
||||
}
|
||||
|
||||
#undef BLOCK_SIZE
|
||||
#undef DATA_SIZE
|
||||
#undef DATA_STRIDE
|
||||
#undef BITS
|
||||
#undef COUNTERS_SIZE
|
35
src/backend/opencl/cl/astrobwt_v2/astrobwt_v2.cl
Normal file
35
src/backend/opencl/cl/astrobwt_v2/astrobwt_v2.cl
Normal file
|
@ -0,0 +1,35 @@
|
|||
/* 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-2022 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2022 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/>.
|
||||
*/
|
||||
|
||||
typedef uchar uint8_t;
|
||||
typedef ushort uint16_t;
|
||||
typedef uint uint32_t;
|
||||
typedef ulong uint64_t;
|
||||
|
||||
typedef int int32_t;
|
||||
typedef long int64_t;
|
||||
|
||||
#include "BWT.cl"
|
||||
#include "salsa20.cl"
|
||||
#include "sha3.cl"
|
388
src/backend/opencl/cl/astrobwt_v2/astrobwt_v2_cl.h
Normal file
388
src/backend/opencl/cl/astrobwt_v2/astrobwt_v2_cl.h
Normal file
|
@ -0,0 +1,388 @@
|
|||
#pragma once
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
static const char astrobwt_v2_cl[12139] = {
|
||||
0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x75,0x63,0x68,0x61,0x72,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x3b,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x75,
|
||||
0x73,0x68,0x6f,0x72,0x74,0x20,0x75,0x69,0x6e,0x74,0x31,0x36,0x5f,0x74,0x3b,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x75,0x69,0x6e,0x74,0x20,0x75,0x69,0x6e,
|
||||
0x74,0x33,0x32,0x5f,0x74,0x3b,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x3b,0x0a,0x74,
|
||||
0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x3b,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x6c,0x6f,0x6e,0x67,
|
||||
0x20,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x3b,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x20,0x31,0x30,0x32,
|
||||
0x34,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x44,0x41,0x54,0x41,0x5f,0x53,0x49,0x5a,0x45,0x20,0x39,0x39,0x37,0x33,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,
|
||||
0x20,0x44,0x41,0x54,0x41,0x5f,0x53,0x54,0x52,0x49,0x44,0x45,0x20,0x31,0x30,0x32,0x34,0x30,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x42,0x49,0x54,0x53,0x20,
|
||||
0x31,0x34,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x43,0x4f,0x55,0x4e,0x54,0x45,0x52,0x53,0x5f,0x53,0x49,0x5a,0x45,0x20,0x28,0x31,0x20,0x3c,0x3c,0x20,0x42,
|
||||
0x49,0x54,0x53,0x29,0x0a,0x69,0x6e,0x6c,0x69,0x6e,0x65,0x20,0x75,0x69,0x6e,0x74,0x31,0x36,0x5f,0x74,0x20,0x61,0x74,0x6f,0x6d,0x69,0x63,0x5f,0x69,0x6e,0x63,0x31,
|
||||
0x36,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x31,0x36,0x5f,0x74,0x2a,0x20,0x76,0x61,0x6c,0x75,0x65,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,
|
||||
0x73,0x74,0x20,0x73,0x69,0x7a,0x65,0x5f,0x74,0x20,0x6b,0x3d,0x28,0x73,0x69,0x7a,0x65,0x5f,0x74,0x29,0x20,0x76,0x61,0x6c,0x75,0x65,0x3b,0x0a,0x69,0x66,0x28,0x28,
|
||||
0x6b,0x26,0x33,0x29,0x3d,0x3d,0x30,0x29,0x20,0x7b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x61,0x74,0x6f,0x6d,0x69,0x63,0x5f,0x61,0x64,0x64,0x28,0x28,0x5f,0x5f,
|
||||
0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x20,0x76,0x61,0x6c,0x75,0x65,0x2c,0x31,0x29,0x3b,0x0a,0x7d,0x0a,0x72,0x65,0x74,
|
||||
0x75,0x72,0x6e,0x20,0x61,0x74,0x6f,0x6d,0x69,0x63,0x5f,0x61,0x64,0x64,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,
|
||||
0x2a,0x29,0x28,0x6b,0x2d,0x32,0x29,0x2c,0x30,0x78,0x31,0x30,0x30,0x30,0x30,0x29,0x3e,0x3e,0x31,0x36,0x3b,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,0x42,0x4c,0x4f,0x43,
|
||||
0x4b,0x5f,0x53,0x49,0x5a,0x45,0x2c,0x31,0x2c,0x31,0x29,0x29,0x29,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x42,0x57,0x54,0x5f,
|
||||
0x70,0x72,0x65,0x70,0x72,0x6f,0x63,0x65,0x73,0x73,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,
|
||||
0x74,0x2a,0x20,0x64,0x61,0x74,0x61,0x73,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x6b,0x65,0x79,0x73,
|
||||
0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x64,0x61,0x74,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x67,
|
||||
0x65,0x74,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x28,0x30,0x29,0x2a,0x44,0x41,0x54,0x41,0x5f,0x53,0x54,0x52,0x49,0x44,0x45,0x3b,0x0a,0x63,0x6f,0x6e,0x73,
|
||||
0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x74,0x69,0x64,0x3d,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,
|
||||
0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5f,0x62,0x75,0x66,0x5b,0x43,0x4f,
|
||||
0x55,0x4e,0x54,0x45,0x52,0x53,0x5f,0x53,0x49,0x5a,0x45,0x2f,0x32,0x5d,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x31,0x36,0x5f,0x74,
|
||||
0x2a,0x20,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x3d,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x31,0x36,0x5f,0x74,0x2a,0x29,0x20,0x63,
|
||||
0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5f,0x62,0x75,0x66,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x3d,0x74,0x69,0x64,
|
||||
0x3b,0x20,0x69,0x3c,0x43,0x4f,0x55,0x4e,0x54,0x45,0x52,0x53,0x5f,0x53,0x49,0x5a,0x45,0x2f,0x32,0x3b,0x20,0x69,0x2b,0x3d,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,
|
||||
0x5a,0x45,0x29,0x20,0x7b,0x0a,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5f,0x62,0x75,0x66,0x5b,0x69,0x5d,0x3d,0x30,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,0x64,0x61,0x74,0x61,0x73,0x2b,0x3d,
|
||||
0x64,0x61,0x74,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3b,0x0a,0x6b,0x65,0x79,0x73,0x2b,0x3d,0x64,0x61,0x74,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3b,0x0a,
|
||||
0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x3d,0x74,0x69,0x64,0x3b,0x20,0x69,0x3c,0x44,0x41,0x54,0x41,0x5f,0x53,0x49,0x5a,0x45,
|
||||
0x3b,0x20,0x69,0x2b,0x3d,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x29,0x20,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
|
||||
0x74,0x20,0x6b,0x30,0x3d,0x64,0x61,0x74,0x61,0x73,0x5b,0x69,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6b,0x31,
|
||||
0x3d,0x64,0x61,0x74,0x61,0x73,0x5b,0x69,0x2b,0x31,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6b,0x3d,0x28,0x28,
|
||||
0x6b,0x30,0x3c,0x3c,0x38,0x29,0x7c,0x6b,0x31,0x29,0x3e,0x3e,0x28,0x31,0x36,0x2d,0x42,0x49,0x54,0x53,0x29,0x3b,0x0a,0x61,0x74,0x6f,0x6d,0x69,0x63,0x5f,0x69,0x6e,
|
||||
0x63,0x31,0x36,0x28,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x2b,0x6b,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,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,
|
||||
0x42,0x49,0x54,0x53,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6b,0x3d,0x30,0x3b,0x20,0x6b,0x3c,0x42,0x49,0x54,0x53,0x3b,0x20,0x2b,0x2b,0x6b,0x29,0x20,
|
||||
0x7b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x74,0x31,0x3d,0x74,0x69,0x64,0x3b,0x20,0x74,0x31,0x3c,0x28,0x28,0x43,0x4f,0x55,
|
||||
0x4e,0x54,0x45,0x52,0x53,0x5f,0x53,0x49,0x5a,0x45,0x2f,0x32,0x29,0x3e,0x3e,0x6b,0x29,0x3b,0x20,0x74,0x31,0x2b,0x3d,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,
|
||||
0x45,0x29,0x20,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x3d,0x28,0x74,0x31,0x3c,0x3c,0x28,0x6b,0x2b,0x31,0x29,
|
||||
0x29,0x2b,0x28,0x28,0x31,0x3c,0x3c,0x28,0x6b,0x2b,0x31,0x29,0x29,0x2d,0x31,0x29,0x3b,0x0a,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5b,0x69,0x5d,0x2b,0x3d,0x63,
|
||||
0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5b,0x69,0x2d,0x28,0x31,0x3c,0x3c,0x6b,0x29,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,0x7d,0x0a,0x69,0x66,0x28,0x74,0x69,0x64,0x3d,0x3d,0x30,0x29,0x20,
|
||||
0x7b,0x0a,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5b,0x43,0x4f,0x55,0x4e,0x54,0x45,0x52,0x53,0x5f,0x53,0x49,0x5a,0x45,0x2d,0x31,0x5d,0x3d,0x30,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,0x23,
|
||||
0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x42,0x49,0x54,0x53,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x6b,0x3d,0x42,0x49,
|
||||
0x54,0x53,0x2d,0x31,0x3b,0x20,0x6b,0x3e,0x3d,0x30,0x3b,0x20,0x2d,0x2d,0x6b,0x29,0x20,0x7b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,
|
||||
0x20,0x74,0x31,0x3d,0x74,0x69,0x64,0x3b,0x20,0x74,0x31,0x3c,0x28,0x28,0x43,0x4f,0x55,0x4e,0x54,0x45,0x52,0x53,0x5f,0x53,0x49,0x5a,0x45,0x2f,0x32,0x29,0x3e,0x3e,
|
||||
0x6b,0x29,0x3b,0x20,0x74,0x31,0x2b,0x3d,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x29,0x20,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,
|
||||
0x33,0x32,0x5f,0x74,0x20,0x69,0x3d,0x28,0x74,0x31,0x3c,0x3c,0x28,0x6b,0x2b,0x31,0x29,0x29,0x2b,0x28,0x28,0x31,0x3c,0x3c,0x28,0x6b,0x2b,0x31,0x29,0x29,0x2d,0x31,
|
||||
0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x31,0x36,0x5f,0x74,0x20,0x6f,0x6c,0x64,0x3d,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5b,0x69,
|
||||
0x5d,0x3b,0x0a,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5b,0x69,0x5d,0x3d,0x6f,0x6c,0x64,0x2b,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5b,0x69,0x2d,0x28,0x31,
|
||||
0x3c,0x3c,0x6b,0x29,0x5d,0x3b,0x0a,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5b,0x69,0x2d,0x28,0x31,0x3c,0x3c,0x6b,0x29,0x5d,0x3d,0x6f,0x6c,0x64,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,0x7d,
|
||||
0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x3d,0x74,0x69,0x64,0x3b,0x20,0x69,0x3c,0x44,0x41,0x54,0x41,0x5f,0x53,0x49,0x5a,
|
||||
0x45,0x3b,0x20,0x69,0x2b,0x3d,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x29,0x20,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,
|
||||
0x5f,0x74,0x20,0x6b,0x30,0x3d,0x64,0x61,0x74,0x61,0x73,0x5b,0x69,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6b,
|
||||
0x31,0x3d,0x64,0x61,0x74,0x61,0x73,0x5b,0x69,0x2b,0x31,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6b,0x3d,0x28,
|
||||
0x6b,0x30,0x3c,0x3c,0x38,0x29,0x7c,0x6b,0x31,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x6e,0x64,0x65,0x78,0x3d,
|
||||
0x61,0x74,0x6f,0x6d,0x69,0x63,0x5f,0x69,0x6e,0x63,0x31,0x36,0x28,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x2b,0x28,0x6b,0x3e,0x3e,0x28,0x31,0x36,0x2d,0x42,0x49,
|
||||
0x54,0x53,0x29,0x29,0x29,0x3b,0x0a,0x6b,0x65,0x79,0x73,0x5b,0x69,0x6e,0x64,0x65,0x78,0x5d,0x3d,0x28,0x6b,0x3c,0x3c,0x31,0x36,0x29,0x7c,0x69,0x3b,0x0a,0x7d,0x0a,
|
||||
0x7d,0x0a,0x69,0x6e,0x6c,0x69,0x6e,0x65,0x20,0x76,0x6f,0x69,0x64,0x20,0x66,0x69,0x78,0x5f,0x6f,0x72,0x64,0x65,0x72,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,
|
||||
0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x61,
|
||||
0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x62,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x6b,
|
||||
0x65,0x79,0x73,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6b,0x61,0x3d,0x6b,0x65,0x79,0x73,0x5b,0x61,0x5d,
|
||||
0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6b,0x62,0x3d,0x6b,0x65,0x79,0x73,0x5b,0x62,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,
|
||||
0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x6e,0x64,0x65,0x78,0x5f,0x61,0x3d,0x6b,0x61,0x26,0x30,0x78,0x46,0x46,0x46,0x46,0x3b,0x0a,0x63,
|
||||
0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x6e,0x64,0x65,0x78,0x5f,0x62,0x3d,0x6b,0x62,0x26,0x30,0x78,0x46,0x46,0x46,0x46,0x3b,
|
||||
0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x20,0x3d,0x0a,0x28,0x28,0x28,0x75,0x69,0x6e,
|
||||
0x74,0x33,0x32,0x5f,0x74,0x29,0x69,0x6e,0x70,0x75,0x74,0x5b,0x69,0x6e,0x64,0x65,0x78,0x5f,0x61,0x2b,0x31,0x5d,0x29,0x3c,0x3c,0x32,0x34,0x29,0x20,0x7c,0x0a,0x28,
|
||||
0x28,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x69,0x6e,0x70,0x75,0x74,0x5b,0x69,0x6e,0x64,0x65,0x78,0x5f,0x61,0x2b,0x32,0x5d,0x29,0x3c,0x3c,0x31,0x36,
|
||||
0x29,0x20,0x7c,0x0a,0x28,0x28,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x69,0x6e,0x70,0x75,0x74,0x5b,0x69,0x6e,0x64,0x65,0x78,0x5f,0x61,0x2b,0x33,0x5d,
|
||||
0x29,0x3c,0x3c,0x38,0x29,0x20,0x7c,0x0a,0x28,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x69,0x6e,0x70,0x75,0x74,0x5b,0x69,0x6e,0x64,0x65,0x78,0x5f,0x61,
|
||||
0x2b,0x34,0x5d,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x20,0x3d,0x0a,0x28,
|
||||
0x28,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x69,0x6e,0x70,0x75,0x74,0x5b,0x69,0x6e,0x64,0x65,0x78,0x5f,0x62,0x2b,0x31,0x5d,0x29,0x3c,0x3c,0x32,0x34,
|
||||
0x29,0x20,0x7c,0x0a,0x28,0x28,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x69,0x6e,0x70,0x75,0x74,0x5b,0x69,0x6e,0x64,0x65,0x78,0x5f,0x62,0x2b,0x32,0x5d,
|
||||
0x29,0x3c,0x3c,0x31,0x36,0x29,0x20,0x7c,0x0a,0x28,0x28,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x69,0x6e,0x70,0x75,0x74,0x5b,0x69,0x6e,0x64,0x65,0x78,
|
||||
0x5f,0x62,0x2b,0x33,0x5d,0x29,0x3c,0x3c,0x38,0x29,0x20,0x7c,0x0a,0x28,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x69,0x6e,0x70,0x75,0x74,0x5b,0x69,0x6e,
|
||||
0x64,0x65,0x78,0x5f,0x62,0x2b,0x34,0x5d,0x29,0x3b,0x0a,0x69,0x66,0x28,0x76,0x61,0x6c,0x75,0x65,0x5f,0x61,0x3e,0x76,0x61,0x6c,0x75,0x65,0x5f,0x62,0x29,0x0a,0x7b,
|
||||
0x0a,0x6b,0x65,0x79,0x73,0x5b,0x61,0x5d,0x3d,0x6b,0x62,0x3b,0x0a,0x6b,0x65,0x79,0x73,0x5b,0x62,0x5d,0x3d,0x6b,0x61,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,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x2c,0x31,0x2c,0x31,0x29,0x29,0x29,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,
|
||||
0x20,0x42,0x57,0x54,0x5f,0x66,0x69,0x78,0x5f,0x6f,0x72,0x64,0x65,0x72,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,
|
||||
0x6e,0x74,0x38,0x5f,0x74,0x2a,0x20,0x64,0x61,0x74,0x61,0x73,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,
|
||||
0x6b,0x65,0x79,0x73,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x31,0x36,0x5f,0x74,0x2a,0x20,0x76,0x61,0x6c,0x75,0x65,0x73,0x29,0x0a,
|
||||
0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x74,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,0x72,0x6f,
|
||||
0x75,0x70,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x64,0x61,0x74,0x61,0x5f,0x6f,0x66,
|
||||
0x66,0x73,0x65,0x74,0x3d,0x67,0x69,0x64,0x2a,0x31,0x30,0x32,0x34,0x30,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x4e,
|
||||
0x3d,0x39,0x39,0x37,0x33,0x3b,0x0a,0x64,0x61,0x74,0x61,0x73,0x2b,0x3d,0x64,0x61,0x74,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3b,0x0a,0x6b,0x65,0x79,0x73,0x2b,
|
||||
0x3d,0x64,0x61,0x74,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3b,0x0a,0x76,0x61,0x6c,0x75,0x65,0x73,0x2b,0x3d,0x64,0x61,0x74,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,
|
||||
0x74,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x3d,0x74,0x69,0x64,0x2c,0x4e,0x31,0x3d,0x4e,0x2d,0x31,0x3b,0x20,0x69,
|
||||
0x3c,0x4e,0x31,0x3b,0x20,0x69,0x2b,0x3d,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,
|
||||
0x33,0x32,0x5f,0x74,0x20,0x76,0x61,0x6c,0x75,0x65,0x3d,0x6b,0x65,0x79,0x73,0x5b,0x69,0x5d,0x3e,0x3e,0x28,0x33,0x32,0x2d,0x42,0x49,0x54,0x53,0x29,0x3b,0x0a,0x69,
|
||||
0x66,0x28,0x76,0x61,0x6c,0x75,0x65,0x3d,0x3d,0x28,0x6b,0x65,0x79,0x73,0x5b,0x69,0x2b,0x31,0x5d,0x3e,0x3e,0x28,0x33,0x32,0x2d,0x42,0x49,0x54,0x53,0x29,0x29,0x29,
|
||||
0x0a,0x7b,0x0a,0x69,0x66,0x28,0x69,0x26,0x26,0x28,0x76,0x61,0x6c,0x75,0x65,0x3d,0x3d,0x28,0x6b,0x65,0x79,0x73,0x5b,0x69,0x2d,0x31,0x5d,0x3e,0x3e,0x28,0x33,0x32,
|
||||
0x2d,0x42,0x49,0x54,0x53,0x29,0x29,0x29,0x29,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6e,0x3d,0x69,
|
||||
0x2b,0x32,0x3b,0x0a,0x77,0x68,0x69,0x6c,0x65,0x20,0x28,0x28,0x6e,0x3c,0x4e,0x29,0x26,0x26,0x28,0x76,0x61,0x6c,0x75,0x65,0x3d,0x3d,0x28,0x6b,0x65,0x79,0x73,0x5b,
|
||||
0x6e,0x5d,0x3e,0x3e,0x28,0x33,0x32,0x2d,0x42,0x49,0x54,0x53,0x29,0x29,0x29,0x29,0x0a,0x2b,0x2b,0x6e,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,
|
||||
0x32,0x5f,0x74,0x20,0x6a,0x3d,0x69,0x3b,0x20,0x6a,0x3c,0x6e,0x3b,0x20,0x2b,0x2b,0x6a,0x29,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,
|
||||
0x20,0x6b,0x3d,0x6a,0x2b,0x31,0x3b,0x20,0x6b,0x3c,0x6e,0x3b,0x20,0x2b,0x2b,0x6b,0x29,0x0a,0x66,0x69,0x78,0x5f,0x6f,0x72,0x64,0x65,0x72,0x28,0x64,0x61,0x74,0x61,
|
||||
0x73,0x2c,0x6a,0x2c,0x6b,0x2c,0x6b,0x65,0x79,0x73,0x29,0x3b,0x0a,0x7d,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,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x3d,
|
||||
0x74,0x69,0x64,0x3b,0x20,0x69,0x3c,0x4e,0x3b,0x20,0x69,0x2b,0x3d,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x29,0x20,0x7b,0x0a,0x76,0x61,0x6c,0x75,0x65,
|
||||
0x73,0x5b,0x69,0x5d,0x3d,0x6b,0x65,0x79,0x73,0x5b,0x69,0x5d,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,
|
||||
0x66,0x69,0x6e,0x64,0x5f,0x73,0x68,0x61,0x72,0x65,0x73,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,
|
||||
0x34,0x5f,0x74,0x2a,0x20,0x68,0x61,0x73,0x68,0x65,0x73,0x2c,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x74,0x61,0x72,0x67,0x65,0x74,0x2c,0x5f,0x5f,0x67,0x6c,
|
||||
0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x73,0x68,0x61,0x72,0x65,0x73,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,
|
||||
0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3d,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,
|
||||
0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x69,0x66,0x28,0x68,0x61,0x73,0x68,0x65,0x73,0x5b,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x2a,0x34,0x2b,
|
||||
0x33,0x5d,0x3e,0x3d,0x74,0x61,0x72,0x67,0x65,0x74,0x29,0x20,0x7b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x0a,0x7d,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,
|
||||
0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x64,0x78,0x3d,0x61,0x74,0x6f,0x6d,0x69,0x63,0x5f,0x69,0x6e,0x63,0x28,0x73,0x68,0x61,0x72,0x65,0x73,0x2b,0x30,0x78,0x46,
|
||||
0x46,0x29,0x3b,0x0a,0x69,0x66,0x28,0x69,0x64,0x78,0x3c,0x30,0x78,0x46,0x46,0x29,0x0a,0x73,0x68,0x61,0x72,0x65,0x73,0x5b,0x69,0x64,0x78,0x5d,0x3d,0x67,0x6c,0x6f,
|
||||
0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3b,0x0a,0x7d,0x0a,0x23,0x75,0x6e,0x64,0x65,0x66,0x20,0x42,0x4c,0x4f,0x43,0x4b,0x5f,0x53,0x49,0x5a,0x45,0x0a,0x23,
|
||||
0x75,0x6e,0x64,0x65,0x66,0x20,0x44,0x41,0x54,0x41,0x5f,0x53,0x49,0x5a,0x45,0x0a,0x23,0x75,0x6e,0x64,0x65,0x66,0x20,0x44,0x41,0x54,0x41,0x5f,0x53,0x54,0x52,0x49,
|
||||
0x44,0x45,0x0a,0x23,0x75,0x6e,0x64,0x65,0x66,0x20,0x42,0x49,0x54,0x53,0x0a,0x23,0x75,0x6e,0x64,0x65,0x66,0x20,0x43,0x4f,0x55,0x4e,0x54,0x45,0x52,0x53,0x5f,0x53,
|
||||
0x49,0x5a,0x45,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x76,0x2c,0x63,0x29,0x20,0x28,0x72,0x6f,0x74,0x61,0x74,0x65,0x28,
|
||||
0x76,0x2c,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x63,0x29,0x29,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x58,0x4f,0x52,0x28,0x76,0x2c,0x77,0x29,
|
||||
0x20,0x28,0x28,0x76,0x29,0x20,0x5e,0x20,0x28,0x77,0x29,0x29,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x50,0x4c,0x55,0x53,0x28,0x76,0x2c,0x77,0x29,0x20,0x28,
|
||||
0x28,0x76,0x29,0x20,0x2b,0x20,0x28,0x77,0x29,0x29,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,0x53,0x41,0x4c,0x53,0x41,0x32,0x30,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,
|
||||
0x45,0x2c,0x31,0x2c,0x31,0x29,0x29,0x29,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x53,0x61,0x6c,0x73,0x61,0x32,0x30,0x5f,0x58,
|
||||
0x4f,0x52,0x4b,0x65,0x79,0x53,0x74,0x72,0x65,0x61,0x6d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,
|
||||
0x32,0x5f,0x74,0x2a,0x20,0x6b,0x65,0x79,0x73,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x6f,0x75,0x74,
|
||||
0x70,0x75,0x74,0x73,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x74,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,0x3d,0x67,0x65,0x74,0x5f,0x67,
|
||||
0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,
|
||||
0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x67,0x2a,0x31,0x30,0x32,0x34,0x30,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,
|
||||
0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x6b,0x3d,0x6b,0x65,0x79,0x73,0x2b,0x67,0x2a,0x38,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,
|
||||
0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x3d,0x6f,0x75,0x74,0x70,0x75,0x74,0x73,0x2b,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,
|
||||
0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x28,0x74,0x2a,0x36,0x34,0x29,0x29,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,
|
||||
0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x3d,0x39,0x39,0x37,
|
||||
0x33,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x31,0x3d,0x6b,0x5b,0x30,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,
|
||||
0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x32,0x3d,0x6b,0x5b,0x31,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
|
||||
0x74,0x20,0x6a,0x33,0x3d,0x6b,0x5b,0x32,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x34,0x3d,0x6b,0x5b,0x33,
|
||||
0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x31,0x31,0x3d,0x6b,0x5b,0x34,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,
|
||||
0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x31,0x32,0x3d,0x6b,0x5b,0x35,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,
|
||||
0x32,0x5f,0x74,0x20,0x6a,0x31,0x33,0x3d,0x6b,0x5b,0x36,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x31,0x34,
|
||||
0x3d,0x6b,0x5b,0x37,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x30,0x3d,0x30,0x78,0x36,0x31,0x37,0x30,0x37,
|
||||
0x38,0x36,0x35,0x55,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x35,0x3d,0x30,0x78,0x33,0x33,0x32,0x30,0x36,0x34,
|
||||
0x36,0x45,0x55,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x31,0x30,0x3d,0x30,0x78,0x37,0x39,0x36,0x32,0x32,0x44,
|
||||
0x33,0x32,0x55,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x31,0x35,0x3d,0x30,0x78,0x36,0x42,0x32,0x30,0x36,0x35,
|
||||
0x37,0x34,0x55,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x36,0x3d,0x30,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,
|
||||
0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x37,0x3d,0x30,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x38,
|
||||
0x3d,0x30,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x39,0x3d,0x30,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,
|
||||
0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x3d,0x74,0x2a,0x36,0x34,0x3b,0x20,0x69,0x3c,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x3b,0x20,0x69,0x2b,
|
||||
0x3d,0x53,0x41,0x4c,0x53,0x41,0x32,0x30,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,0x2a,0x36,0x34,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,
|
||||
0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x38,0x5f,0x31,0x3d,0x6a,0x38,0x2b,0x28,0x69,0x2f,0x36,0x34,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
|
||||
0x74,0x20,0x78,0x30,0x3d,0x6a,0x30,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x31,0x3d,0x6a,0x31,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
|
||||
0x74,0x20,0x78,0x32,0x3d,0x6a,0x32,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x33,0x3d,0x6a,0x33,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
|
||||
0x74,0x20,0x78,0x34,0x3d,0x6a,0x34,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x35,0x3d,0x6a,0x35,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
|
||||
0x74,0x20,0x78,0x36,0x3d,0x6a,0x36,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x37,0x3d,0x6a,0x37,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
|
||||
0x74,0x20,0x78,0x38,0x3d,0x6a,0x38,0x5f,0x31,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x39,0x3d,0x6a,0x39,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,
|
||||
0x32,0x5f,0x74,0x20,0x78,0x31,0x30,0x3d,0x6a,0x31,0x30,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x31,0x31,0x3d,0x6a,0x31,0x31,0x3b,0x0a,0x75,
|
||||
0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x31,0x32,0x3d,0x6a,0x31,0x32,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x31,0x33,0x3d,0x6a,0x31,
|
||||
0x33,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x31,0x34,0x3d,0x6a,0x31,0x34,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x31,
|
||||
0x35,0x3d,0x6a,0x31,0x35,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x35,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,
|
||||
0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x3d,0x30,0x3b,0x20,0x6a,0x3c,0x31,0x30,0x3b,0x20,0x2b,0x2b,0x6a,0x29,0x0a,0x7b,0x0a,0x78,0x34,0x3d,0x58,0x4f,0x52,0x28,0x20,
|
||||
0x78,0x34,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x30,0x2c,0x78,0x31,0x32,0x29,0x2c,0x37,0x29,0x29,0x3b,0x0a,0x78,0x38,0x3d,
|
||||
0x58,0x4f,0x52,0x28,0x20,0x78,0x38,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x34,0x2c,0x78,0x30,0x29,0x2c,0x39,0x29,0x29,0x3b,
|
||||
0x0a,0x78,0x31,0x32,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x32,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x38,0x2c,0x78,0x34,0x29,
|
||||
0x2c,0x31,0x33,0x29,0x29,0x3b,0x0a,0x78,0x30,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x30,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,
|
||||
0x32,0x2c,0x78,0x38,0x29,0x2c,0x31,0x38,0x29,0x29,0x3b,0x0a,0x78,0x39,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x39,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,
|
||||
0x55,0x53,0x28,0x20,0x78,0x35,0x2c,0x78,0x31,0x29,0x2c,0x37,0x29,0x29,0x3b,0x0a,0x78,0x31,0x33,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x33,0x2c,0x52,0x4f,0x54,0x41,
|
||||
0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x39,0x2c,0x78,0x35,0x29,0x2c,0x39,0x29,0x29,0x3b,0x0a,0x78,0x31,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x31,0x2c,
|
||||
0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x33,0x2c,0x78,0x39,0x29,0x2c,0x31,0x33,0x29,0x29,0x3b,0x0a,0x78,0x35,0x3d,0x58,0x4f,0x52,
|
||||
0x28,0x20,0x78,0x35,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x31,0x2c,0x78,0x31,0x33,0x29,0x2c,0x31,0x38,0x29,0x29,0x3b,0x0a,
|
||||
0x78,0x31,0x34,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x34,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x30,0x2c,0x78,0x36,0x29,0x2c,
|
||||
0x37,0x29,0x29,0x3b,0x0a,0x78,0x32,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x32,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x34,0x2c,
|
||||
0x78,0x31,0x30,0x29,0x2c,0x39,0x29,0x29,0x3b,0x0a,0x78,0x36,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x36,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,
|
||||
0x28,0x20,0x78,0x32,0x2c,0x78,0x31,0x34,0x29,0x2c,0x31,0x33,0x29,0x29,0x3b,0x0a,0x78,0x31,0x30,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x30,0x2c,0x52,0x4f,0x54,0x41,
|
||||
0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x36,0x2c,0x78,0x32,0x29,0x2c,0x31,0x38,0x29,0x29,0x3b,0x0a,0x78,0x33,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x33,
|
||||
0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x35,0x2c,0x78,0x31,0x31,0x29,0x2c,0x37,0x29,0x29,0x3b,0x0a,0x78,0x37,0x3d,0x58,0x4f,
|
||||
0x52,0x28,0x20,0x78,0x37,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x33,0x2c,0x78,0x31,0x35,0x29,0x2c,0x39,0x29,0x29,0x3b,0x0a,
|
||||
0x78,0x31,0x31,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x31,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x37,0x2c,0x78,0x33,0x29,0x2c,
|
||||
0x31,0x33,0x29,0x29,0x3b,0x0a,0x78,0x31,0x35,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x35,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,
|
||||
0x31,0x2c,0x78,0x37,0x29,0x2c,0x31,0x38,0x29,0x29,0x3b,0x0a,0x78,0x31,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x31,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,
|
||||
0x55,0x53,0x28,0x20,0x78,0x30,0x2c,0x78,0x33,0x29,0x2c,0x37,0x29,0x29,0x3b,0x0a,0x78,0x32,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x32,0x2c,0x52,0x4f,0x54,0x41,0x54,
|
||||
0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x31,0x2c,0x78,0x30,0x29,0x2c,0x39,0x29,0x29,0x3b,0x0a,0x78,0x33,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x33,0x2c,0x52,
|
||||
0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x32,0x2c,0x78,0x31,0x29,0x2c,0x31,0x33,0x29,0x29,0x3b,0x0a,0x78,0x30,0x3d,0x58,0x4f,0x52,0x28,
|
||||
0x20,0x78,0x30,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x33,0x2c,0x78,0x32,0x29,0x2c,0x31,0x38,0x29,0x29,0x3b,0x0a,0x78,0x36,
|
||||
0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x36,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x35,0x2c,0x78,0x34,0x29,0x2c,0x37,0x29,0x29,
|
||||
0x3b,0x0a,0x78,0x37,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x37,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x36,0x2c,0x78,0x35,0x29,
|
||||
0x2c,0x39,0x29,0x29,0x3b,0x0a,0x78,0x34,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x34,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x37,
|
||||
0x2c,0x78,0x36,0x29,0x2c,0x31,0x33,0x29,0x29,0x3b,0x0a,0x78,0x35,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x35,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,
|
||||
0x53,0x28,0x20,0x78,0x34,0x2c,0x78,0x37,0x29,0x2c,0x31,0x38,0x29,0x29,0x3b,0x0a,0x78,0x31,0x31,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x31,0x2c,0x52,0x4f,0x54,0x41,
|
||||
0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x30,0x2c,0x78,0x39,0x29,0x2c,0x37,0x29,0x29,0x3b,0x0a,0x78,0x38,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x38,0x2c,
|
||||
0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x31,0x2c,0x78,0x31,0x30,0x29,0x2c,0x39,0x29,0x29,0x3b,0x0a,0x78,0x39,0x3d,0x58,0x4f,0x52,
|
||||
0x28,0x20,0x78,0x39,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x38,0x2c,0x78,0x31,0x31,0x29,0x2c,0x31,0x33,0x29,0x29,0x3b,0x0a,
|
||||
0x78,0x31,0x30,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x30,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x39,0x2c,0x78,0x38,0x29,0x2c,
|
||||
0x31,0x38,0x29,0x29,0x3b,0x0a,0x78,0x31,0x32,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x32,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,
|
||||
0x35,0x2c,0x78,0x31,0x34,0x29,0x2c,0x37,0x29,0x29,0x3b,0x0a,0x78,0x31,0x33,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x33,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,
|
||||
0x4c,0x55,0x53,0x28,0x78,0x31,0x32,0x2c,0x78,0x31,0x35,0x29,0x2c,0x39,0x29,0x29,0x3b,0x0a,0x78,0x31,0x34,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x34,0x2c,0x52,0x4f,
|
||||
0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x33,0x2c,0x78,0x31,0x32,0x29,0x2c,0x31,0x33,0x29,0x29,0x3b,0x0a,0x78,0x31,0x35,0x3d,0x58,0x4f,0x52,
|
||||
0x28,0x78,0x31,0x35,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x34,0x2c,0x78,0x31,0x33,0x29,0x2c,0x31,0x38,0x29,0x29,0x3b,0x0a,
|
||||
0x7d,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x30,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x30,0x2c,0x6a,0x30,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,
|
||||
0x31,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x2c,0x6a,0x31,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x32,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,
|
||||
0x32,0x2c,0x6a,0x32,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x33,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x33,0x2c,0x6a,0x33,0x29,0x3b,0x0a,0x6f,0x75,
|
||||
0x74,0x70,0x75,0x74,0x5b,0x34,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x34,0x2c,0x6a,0x34,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x35,0x5d,0x3d,0x50,
|
||||
0x4c,0x55,0x53,0x28,0x78,0x35,0x2c,0x6a,0x35,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x36,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x36,0x2c,0x6a,0x36,
|
||||
0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x37,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x37,0x2c,0x6a,0x37,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,
|
||||
0x5b,0x38,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x38,0x2c,0x6a,0x38,0x5f,0x31,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x39,0x5d,0x3d,0x50,0x4c,0x55,
|
||||
0x53,0x28,0x78,0x39,0x2c,0x6a,0x39,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x31,0x30,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x30,0x2c,0x6a,0x31,
|
||||
0x30,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x31,0x31,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x31,0x2c,0x6a,0x31,0x31,0x29,0x3b,0x0a,0x6f,0x75,
|
||||
0x74,0x70,0x75,0x74,0x5b,0x31,0x32,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x32,0x2c,0x6a,0x31,0x32,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x31,
|
||||
0x33,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x33,0x2c,0x6a,0x31,0x33,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x31,0x34,0x5d,0x3d,0x50,0x4c,0x55,
|
||||
0x53,0x28,0x78,0x31,0x34,0x2c,0x6a,0x31,0x34,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x31,0x35,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x35,0x2c,
|
||||
0x6a,0x31,0x35,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x3d,0x28,0x53,0x41,0x4c,0x53,0x41,0x32,0x30,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,
|
||||
0x45,0x2a,0x36,0x34,0x29,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,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,0x69,0x66,0x28,0x74,0x3c,0x31,0x36,
|
||||
0x29,0x0a,0x7b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x70,0x3d,0x6f,0x75,0x74,0x70,0x75,0x74,0x73,
|
||||
0x2b,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x2b,0x33,0x29,0x2f,0x73,
|
||||
0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x3b,0x0a,0x70,0x5b,0x74,0x5d,0x3d,0x30,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x28,0x74,
|
||||
0x3d,0x3d,0x30,0x29,0x26,0x26,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x26,0x33,0x29,0x29,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x73,0x5b,0x28,
|
||||
0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x29,0x2f,0x73,0x69,0x7a,0x65,0x6f,
|
||||
0x66,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x5d,0x20,0x26,0x3d,0x20,0x30,0x78,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x55,0x3e,0x3e,0x28,0x28,0x34,
|
||||
0x2d,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x26,0x33,0x29,0x29,0x3c,0x3c,0x33,0x29,0x3b,0x0a,0x7d,0x0a,0x23,0x75,0x6e,0x64,0x65,0x66,0x20,
|
||||
0x52,0x4f,0x54,0x41,0x54,0x45,0x0a,0x23,0x75,0x6e,0x64,0x65,0x66,0x20,0x58,0x4f,0x52,0x0a,0x23,0x75,0x6e,0x64,0x65,0x66,0x20,0x50,0x4c,0x55,0x53,0x0a,0x23,0x64,
|
||||
0x65,0x66,0x69,0x6e,0x65,0x20,0x52,0x4f,0x55,0x4e,0x44,0x53,0x20,0x32,0x34,0x0a,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x63,0x6f,0x6e,0x73,0x74,
|
||||
0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x72,0x63,0x5b,0x32,0x34,0x5d,0x3d,0x7b,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
|
||||
0x30,0x30,0x30,0x30,0x31,0x55,0x4c,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x32,0x55,0x4c,0x2c,0x30,0x78,0x38,
|
||||
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x41,0x55,0x4c,0x2c,0x0a,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,
|
||||
0x30,0x38,0x30,0x30,0x30,0x55,0x4c,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x42,0x55,0x4c,0x2c,0x30,0x78,0x30,
|
||||
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x55,0x4c,0x2c,0x0a,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,
|
||||
0x30,0x38,0x30,0x38,0x31,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x39,0x55,0x4c,0x2c,0x30,0x78,0x30,
|
||||
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x41,0x55,0x4c,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
|
||||
0x30,0x30,0x30,0x38,0x38,0x55,0x4c,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x30,0x39,0x55,0x4c,0x2c,0x30,0x78,0x30,
|
||||
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x41,0x55,0x4c,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,
|
||||
0x30,0x38,0x30,0x38,0x42,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x42,0x55,0x4c,0x2c,0x30,0x78,0x38,
|
||||
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x39,0x55,0x4c,0x2c,0x0a,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
|
||||
0x30,0x38,0x30,0x30,0x33,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x32,0x55,0x4c,0x2c,0x30,0x78,0x38,
|
||||
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x55,0x4c,0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
|
||||
0x30,0x38,0x30,0x30,0x41,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x41,0x55,0x4c,0x2c,0x30,0x78,0x38,
|
||||
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x38,0x31,0x55,0x4c,0x2c,0x0a,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
|
||||
0x30,0x38,0x30,0x38,0x30,0x55,0x4c,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x55,0x4c,0x2c,0x30,0x78,0x38,
|
||||
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x30,0x38,0x55,0x4c,0x0a,0x7d,0x3b,0x0a,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,
|
||||
0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x5b,0x32,0x35,0x5d,0x5b,0x32,0x5d,0x3d,0x7b,0x0a,0x7b,0x20,0x31,0x2c,0x32,0x7d,0x2c,0x7b,0x20,0x32,0x2c,
|
||||
0x33,0x7d,0x2c,0x7b,0x20,0x33,0x2c,0x34,0x7d,0x2c,0x7b,0x20,0x34,0x2c,0x30,0x7d,0x2c,0x7b,0x20,0x30,0x2c,0x31,0x7d,0x2c,0x0a,0x7b,0x20,0x36,0x2c,0x37,0x7d,0x2c,
|
||||
0x7b,0x20,0x37,0x2c,0x38,0x7d,0x2c,0x7b,0x20,0x38,0x2c,0x39,0x7d,0x2c,0x7b,0x20,0x39,0x2c,0x35,0x7d,0x2c,0x7b,0x20,0x35,0x2c,0x36,0x7d,0x2c,0x0a,0x7b,0x31,0x31,
|
||||
0x2c,0x31,0x32,0x7d,0x2c,0x7b,0x31,0x32,0x2c,0x31,0x33,0x7d,0x2c,0x7b,0x31,0x33,0x2c,0x31,0x34,0x7d,0x2c,0x7b,0x31,0x34,0x2c,0x31,0x30,0x7d,0x2c,0x7b,0x31,0x30,
|
||||
0x2c,0x31,0x31,0x7d,0x2c,0x0a,0x7b,0x31,0x36,0x2c,0x31,0x37,0x7d,0x2c,0x7b,0x31,0x37,0x2c,0x31,0x38,0x7d,0x2c,0x7b,0x31,0x38,0x2c,0x31,0x39,0x7d,0x2c,0x7b,0x31,
|
||||
0x39,0x2c,0x31,0x35,0x7d,0x2c,0x7b,0x31,0x35,0x2c,0x31,0x36,0x7d,0x2c,0x0a,0x7b,0x32,0x31,0x2c,0x32,0x32,0x7d,0x2c,0x7b,0x32,0x32,0x2c,0x32,0x33,0x7d,0x2c,0x7b,
|
||||
0x32,0x33,0x2c,0x32,0x34,0x7d,0x2c,0x7b,0x32,0x34,0x2c,0x32,0x30,0x7d,0x2c,0x7b,0x32,0x30,0x2c,0x32,0x31,0x7d,0x0a,0x7d,0x3b,0x0a,0x5f,0x5f,0x63,0x6f,0x6e,0x73,
|
||||
0x74,0x61,0x6e,0x74,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x70,0x70,0x69,0x5b,0x32,0x35,0x5d,0x5b,0x32,0x5d,0x3d,0x7b,0x0a,0x7b,0x30,0x2c,0x30,
|
||||
0x7d,0x2c,0x7b,0x36,0x2c,0x34,0x34,0x7d,0x2c,0x7b,0x31,0x32,0x2c,0x34,0x33,0x7d,0x2c,0x7b,0x31,0x38,0x2c,0x32,0x31,0x7d,0x2c,0x7b,0x32,0x34,0x2c,0x31,0x34,0x7d,
|
||||
0x2c,0x7b,0x33,0x2c,0x32,0x38,0x7d,0x2c,0x7b,0x39,0x2c,0x32,0x30,0x7d,0x2c,0x7b,0x31,0x30,0x2c,0x33,0x7d,0x2c,0x7b,0x31,0x36,0x2c,0x34,0x35,0x7d,0x2c,0x0a,0x7b,
|
||||
0x32,0x32,0x2c,0x36,0x31,0x7d,0x2c,0x7b,0x31,0x2c,0x31,0x7d,0x2c,0x7b,0x37,0x2c,0x36,0x7d,0x2c,0x7b,0x31,0x33,0x2c,0x32,0x35,0x7d,0x2c,0x7b,0x31,0x39,0x2c,0x38,
|
||||
0x7d,0x2c,0x7b,0x32,0x30,0x2c,0x31,0x38,0x7d,0x2c,0x7b,0x34,0x2c,0x32,0x37,0x7d,0x2c,0x7b,0x35,0x2c,0x33,0x36,0x7d,0x2c,0x7b,0x31,0x31,0x2c,0x31,0x30,0x7d,0x2c,
|
||||
0x0a,0x7b,0x31,0x37,0x2c,0x31,0x35,0x7d,0x2c,0x7b,0x32,0x33,0x2c,0x35,0x36,0x7d,0x2c,0x7b,0x32,0x2c,0x36,0x32,0x7d,0x2c,0x7b,0x38,0x2c,0x35,0x35,0x7d,0x2c,0x7b,
|
||||
0x31,0x34,0x2c,0x33,0x39,0x7d,0x2c,0x7b,0x31,0x35,0x2c,0x34,0x31,0x7d,0x2c,0x7b,0x32,0x31,0x2c,0x32,0x7d,0x0a,0x7d,0x3b,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,
|
||||
0x20,0x52,0x36,0x34,0x28,0x61,0x2c,0x62,0x2c,0x63,0x29,0x20,0x28,0x28,0x28,0x61,0x29,0x20,0x3c,0x3c,0x20,0x62,0x29,0x20,0x7c,0x20,0x28,0x28,0x61,0x29,0x20,0x3e,
|
||||
0x3e,0x20,0x63,0x29,0x29,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x6b,0x29,0x20,0x5c,0x0a,0x64,0x6f,0x20,0x7b,0x20,0x5c,0x0a,
|
||||
0x43,0x5b,0x74,0x5d,0x3d,0x41,0x5b,0x73,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x35,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x31,0x30,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x31,0x35,0x5d,
|
||||
0x5e,0x41,0x5b,0x73,0x2b,0x32,0x30,0x5d,0x3b,0x20,0x5c,0x0a,0x41,0x5b,0x74,0x5d,0x20,0x5e,0x3d,0x20,0x43,0x5b,0x73,0x2b,0x34,0x5d,0x5e,0x52,0x36,0x34,0x28,0x43,
|
||||
0x5b,0x73,0x2b,0x31,0x5d,0x2c,0x31,0x2c,0x36,0x33,0x29,0x3b,0x20,0x5c,0x0a,0x43,0x5b,0x74,0x5d,0x3d,0x52,0x36,0x34,0x28,0x41,0x5b,0x61,0x74,0x5d,0x2c,0x72,0x6f,
|
||||
0x30,0x2c,0x72,0x6f,0x31,0x29,0x3b,0x20,0x5c,0x0a,0x41,0x5b,0x74,0x5d,0x3d,0x28,0x43,0x5b,0x74,0x5d,0x5e,0x28,0x28,0x7e,0x43,0x5b,0x63,0x31,0x5d,0x29,0x26,0x43,
|
||||
0x5b,0x63,0x32,0x5d,0x29,0x29,0x5e,0x28,0x6b,0x31,0x26,0x28,0x6b,0x29,0x29,0x3b,0x20,0x5c,0x0a,0x7d,0x20,0x77,0x68,0x69,0x6c,0x65,0x20,0x28,0x30,0x29,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,0x33,0x32,0x2c,0x31,0x2c,0x31,0x29,0x29,0x29,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x73,0x68,0x61,0x33,0x28,
|
||||
0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x73,0x2c,0x5f,
|
||||
0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x68,0x61,0x73,0x68,0x65,0x73,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,
|
||||
0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x74,0x3d,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x69,0x66,
|
||||
0x28,0x74,0x3e,0x3d,0x32,0x35,0x29,0x20,0x7b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x0a,0x7d,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,
|
||||
0x5f,0x74,0x20,0x67,0x3d,0x67,0x65,0x74,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,
|
||||
0x36,0x34,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x31,0x30,0x32,0x34,0x30,0x2a,0x32,0x2a,0x67,0x3b,0x0a,0x5f,0x5f,0x67,
|
||||
0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x3d,0x28,0x5f,0x5f,0x67,
|
||||
0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x29,0x28,0x69,0x6e,0x70,0x75,0x74,0x73,0x2b,0x69,0x6e,
|
||||
0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x41,0x5b,
|
||||
0x32,0x35,0x5d,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x43,0x5b,0x32,0x35,0x5d,0x3b,0x0a,0x41,0x5b,0x74,
|
||||
0x5d,0x3d,0x30,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x3d,0x74,0x20,0x25,0x20,0x35,0x3b,0x0a,0x63,0x6f,0x6e,
|
||||
0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x61,0x74,0x3d,0x70,0x70,0x69,0x5b,0x74,0x5d,0x5b,0x30,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x72,
|
||||
0x6f,0x30,0x3d,0x70,0x70,0x69,0x5b,0x74,0x5d,0x5b,0x31,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x72,0x6f,0x31,0x3d,0x36,0x34,0x2d,0x72,
|
||||
0x6f,0x30,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x31,0x3d,0x63,0x5b,0x74,0x5d,0x5b,0x30,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,
|
||||
0x69,0x6e,0x74,0x20,0x63,0x32,0x3d,0x63,0x5b,0x74,0x5d,0x5b,0x31,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x6b,
|
||||
0x31,0x3d,0x28,0x74,0x3d,0x3d,0x30,0x29,0x3f,0x30,0x78,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x55,0x4c,0x3a,0x30,0x55,
|
||||
0x4c,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x3d,0x39,0x39,0x37,
|
||||
0x33,0x2a,0x32,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x6f,0x72,0x64,0x73,0x3d,
|
||||
0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x3b,0x0a,0x5f,0x5f,0x67,
|
||||
0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x70,0x75,
|
||||
0x74,0x5f,0x65,0x6e,0x64,0x31,0x37,0x3d,0x69,0x6e,0x70,0x75,0x74,0x2b,0x28,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x6f,0x72,0x64,0x73,0x2f,0x31,0x37,0x29,0x2a,
|
||||
0x31,0x37,0x29,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x63,0x6f,
|
||||
0x6e,0x73,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x65,0x6e,0x64,0x3d,0x69,0x6e,0x70,0x75,0x74,0x2b,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x6f,0x72,0x64,0x73,0x3b,
|
||||
0x0a,0x66,0x6f,0x72,0x20,0x28,0x3b,0x20,0x69,0x6e,0x70,0x75,0x74,0x3c,0x69,0x6e,0x70,0x75,0x74,0x5f,0x65,0x6e,0x64,0x31,0x37,0x3b,0x20,0x69,0x6e,0x70,0x75,0x74,
|
||||
0x2b,0x3d,0x31,0x37,0x29,0x20,0x7b,0x0a,0x69,0x66,0x28,0x74,0x3c,0x31,0x37,0x29,0x20,0x41,0x5b,0x74,0x5d,0x20,0x5e,0x3d,0x20,0x69,0x6e,0x70,0x75,0x74,0x5b,0x74,
|
||||
0x5d,0x3b,0x0a,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x55,0x4c,0x29,0x3b,0x20,
|
||||
0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x32,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,
|
||||
0x4e,0x44,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x41,0x55,0x4c,0x29,0x3b,0x0a,0x52,0x4f,0x55,0x4e,0x44,0x28,
|
||||
0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x30,
|
||||
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x42,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x30,0x30,0x30,0x30,
|
||||
0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x55,0x4c,0x29,0x3b,0x0a,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,
|
||||
0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x38,0x31,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
|
||||
0x30,0x30,0x38,0x30,0x30,0x39,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
|
||||
0x30,0x38,0x41,0x55,0x4c,0x29,0x3b,0x0a,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x38,
|
||||
0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x30,0x39,0x55,0x4c,0x29,
|
||||
0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x41,0x55,0x4c,0x29,0x3b,0x0a,0x52,
|
||||
0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x38,0x42,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,
|
||||
0x44,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x42,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,
|
||||
0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x39,0x55,0x4c,0x29,0x3b,0x0a,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x38,0x30,
|
||||
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x33,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x30,
|
||||
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x32,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
|
||||
0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x55,0x4c,0x29,0x3b,0x0a,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
|
||||
0x30,0x38,0x30,0x30,0x41,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x30,0x30,
|
||||
0x30,0x41,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x38,0x31,0x55,
|
||||
0x4c,0x29,0x3b,0x0a,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x30,0x55,0x4c,0x29,0x3b,
|
||||
0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,
|
||||
0x55,0x4e,0x44,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x30,0x38,0x55,0x4c,0x29,0x3b,0x0a,0x7d,0x0a,0x63,0x6f,0x6e,
|
||||
0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x77,0x6f,0x72,0x64,0x49,0x6e,0x64,0x65,0x78,0x3d,0x69,0x6e,0x70,0x75,0x74,0x5f,0x65,0x6e,0x64,0x2d,
|
||||
0x69,0x6e,0x70,0x75,0x74,0x3b,0x0a,0x69,0x66,0x28,0x74,0x3c,0x77,0x6f,0x72,0x64,0x49,0x6e,0x64,0x65,0x78,0x29,0x20,0x41,0x5b,0x74,0x5d,0x20,0x5e,0x3d,0x20,0x69,
|
||||
0x6e,0x70,0x75,0x74,0x5b,0x74,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x74,0x3d,0x3d,0x30,0x29,0x20,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x74,0x61,0x69,
|
||||
0x6c,0x3d,0x30,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x20,0x70,0x3d,0x28,
|
||||
0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x29,0x69,0x6e,0x70,0x75,0x74,0x5f,0x65,0x6e,
|
||||
0x64,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x74,0x61,0x69,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x3d,0x69,0x6e,0x70,0x75,
|
||||
0x74,0x5f,0x73,0x69,0x7a,0x65,0x20,0x25,0x20,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,
|
||||
0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x74,0x61,0x69,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x20,
|
||||
0x7b,0x0a,0x74,0x61,0x69,0x6c,0x7c,0x3d,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x28,0x70,0x5b,0x69,0x5d,0x29,0x3c,0x3c,0x28,0x69,0x2a,0x38,0x29,0x3b,
|
||||
0x0a,0x7d,0x0a,0x41,0x5b,0x77,0x6f,0x72,0x64,0x49,0x6e,0x64,0x65,0x78,0x5d,0x20,0x5e,0x3d,0x20,0x74,0x61,0x69,0x6c,0x5e,0x28,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,
|
||||
0x5f,0x74,0x29,0x28,0x28,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x28,0x30,0x78,0x30,0x32,0x7c,0x28,0x31,0x3c,0x3c,0x32,0x29,0x29,0x29,0x3c,0x3c,0x28,
|
||||
0x74,0x61,0x69,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x2a,0x38,0x29,0x29,0x29,0x3b,0x0a,0x41,0x5b,0x31,0x36,0x5d,0x20,0x5e,0x3d,0x20,0x30,0x78,0x38,0x30,0x30,0x30,0x30,
|
||||
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x55,0x4c,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,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,0x52,0x4f,0x55,0x4e,0x44,0x53,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x20,0x7b,0x0a,0x43,
|
||||
0x5b,0x74,0x5d,0x3d,0x41,0x5b,0x73,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x35,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x31,0x30,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x31,0x35,0x5d,0x5e,
|
||||
0x41,0x5b,0x73,0x2b,0x32,0x30,0x5d,0x3b,0x0a,0x41,0x5b,0x74,0x5d,0x20,0x5e,0x3d,0x20,0x43,0x5b,0x73,0x2b,0x34,0x5d,0x5e,0x52,0x36,0x34,0x28,0x43,0x5b,0x73,0x2b,
|
||||
0x31,0x5d,0x2c,0x31,0x2c,0x36,0x33,0x29,0x3b,0x0a,0x43,0x5b,0x74,0x5d,0x3d,0x52,0x36,0x34,0x28,0x41,0x5b,0x61,0x74,0x5d,0x2c,0x72,0x6f,0x30,0x2c,0x72,0x6f,0x31,
|
||||
0x29,0x3b,0x0a,0x41,0x5b,0x74,0x5d,0x3d,0x28,0x43,0x5b,0x74,0x5d,0x5e,0x28,0x28,0x7e,0x43,0x5b,0x63,0x31,0x5d,0x29,0x26,0x43,0x5b,0x63,0x32,0x5d,0x29,0x29,0x5e,
|
||||
0x28,0x72,0x63,0x5b,0x69,0x5d,0x26,0x6b,0x31,0x29,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x74,0x3c,0x34,0x29,0x20,0x7b,0x0a,0x68,0x61,0x73,0x68,0x65,0x73,0x5b,0x67,
|
||||
0x2a,0x34,0x2b,0x74,0x5d,0x3d,0x41,0x5b,0x74,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,0x33,0x32,0x2c,0x31,0x2c,0x31,0x29,0x29,0x29,0x0a,0x5f,0x5f,
|
||||
0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x73,0x68,0x61,0x33,0x5f,0x69,0x6e,0x69,0x74,0x69,0x61,0x6c,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,
|
||||
0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2c,0x75,0x69,0x6e,0x74,
|
||||
0x33,0x32,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6e,0x6f,0x6e,0x63,0x65,0x2c,0x5f,
|
||||
0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x68,0x61,0x73,0x68,0x65,0x73,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,
|
||||
0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x74,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,0x3d,0x67,0x65,0x74,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,
|
||||
0x69,0x66,0x28,0x74,0x3e,0x3d,0x32,0x35,0x29,0x20,0x7b,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x0a,0x7d,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,
|
||||
0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x3d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,
|
||||
0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x29,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x29,0x3b,0x0a,0x5f,0x5f,0x6c,
|
||||
0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x41,0x5b,0x32,0x35,0x5d,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,
|
||||
0x74,0x36,0x34,0x5f,0x74,0x20,0x43,0x5b,0x32,0x35,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,
|
||||
0x74,0x5f,0x77,0x6f,0x72,0x64,0x73,0x3d,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,
|
||||
0x5f,0x74,0x29,0x3b,0x0a,0x41,0x5b,0x74,0x5d,0x3d,0x28,0x74,0x3c,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x6f,0x72,0x64,0x73,0x29,0x3f,0x69,0x6e,0x70,0x75,0x74,0x5b,
|
||||
0x74,0x5d,0x3a,0x30,0x3b,0x0a,0x69,0x66,0x28,0x74,0x3d,0x3d,0x30,0x29,0x20,0x7b,0x0a,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,
|
||||
0x32,0x5f,0x74,0x2a,0x29,0x41,0x29,0x5b,0x31,0x31,0x5d,0x3d,0x6e,0x6f,0x6e,0x63,0x65,0x2b,0x67,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,
|
||||
0x32,0x5f,0x74,0x20,0x74,0x61,0x69,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x3d,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x20,0x25,0x20,0x73,0x69,0x7a,0x65,0x6f,
|
||||
0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x3b,0x0a,0x41,0x5b,0x69,0x6e,0x70,0x75,0x74,0x5f,0x77,0x6f,0x72,0x64,0x73,0x5d,0x20,0x5e,0x3d,0x20,0x28,
|
||||
0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x28,0x28,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x28,0x30,0x78,0x30,0x32,0x7c,0x28,0x31,0x3c,0x3c,0x32,
|
||||
0x29,0x29,0x29,0x3c,0x3c,0x28,0x74,0x61,0x69,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x2a,0x38,0x29,0x29,0x3b,0x0a,0x41,0x5b,0x31,0x36,0x5d,0x20,0x5e,0x3d,0x20,0x30,0x78,
|
||||
0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x55,0x4c,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,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,
|
||||
0x5f,0x74,0x20,0x73,0x3d,0x74,0x20,0x25,0x20,0x35,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x61,0x74,0x3d,0x70,0x70,0x69,0x5b,0x74,0x5d,0x5b,
|
||||
0x30,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x72,0x6f,0x30,0x3d,0x70,0x70,0x69,0x5b,0x74,0x5d,0x5b,0x31,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,
|
||||
0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x72,0x6f,0x31,0x3d,0x36,0x34,0x2d,0x72,0x6f,0x30,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x31,0x3d,
|
||||
0x63,0x5b,0x74,0x5d,0x5b,0x30,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x32,0x3d,0x63,0x5b,0x74,0x5d,0x5b,0x31,0x5d,0x3b,0x0a,0x63,
|
||||
0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x6b,0x31,0x3d,0x28,0x74,0x3d,0x3d,0x30,0x29,0x3f,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,
|
||||
0x74,0x29,0x28,0x2d,0x31,0x29,0x3a,0x30,0x3b,0x0a,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
|
||||
0x30,0x31,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x32,0x55,
|
||||
0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x41,0x55,0x4c,0x29,0x3b,
|
||||
0x0a,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,
|
||||
0x55,0x4e,0x44,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x42,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,
|
||||
0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x55,0x4c,0x29,0x3b,0x0a,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,
|
||||
0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x38,0x31,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x38,0x30,0x30,
|
||||
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x39,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,
|
||||
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x41,0x55,0x4c,0x29,0x3b,0x0a,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
|
||||
0x30,0x30,0x30,0x30,0x30,0x38,0x38,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,
|
||||
0x38,0x30,0x30,0x39,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x30,0x30,0x30,
|
||||
0x41,0x55,0x4c,0x29,0x3b,0x0a,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x38,0x42,0x55,0x4c,
|
||||
0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x42,0x55,0x4c,0x29,0x3b,0x20,
|
||||
0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x39,0x55,0x4c,0x29,0x3b,0x0a,0x52,0x4f,0x55,
|
||||
0x4e,0x44,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x33,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,
|
||||
0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x32,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x38,
|
||||
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x55,0x4c,0x29,0x3b,0x0a,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x30,0x30,0x30,0x30,
|
||||
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x41,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,
|
||||
0x30,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x41,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,
|
||||
0x30,0x30,0x38,0x30,0x38,0x31,0x55,0x4c,0x29,0x3b,0x0a,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,
|
||||
0x30,0x38,0x30,0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x31,
|
||||
0x55,0x4c,0x29,0x3b,0x20,0x52,0x4f,0x55,0x4e,0x44,0x28,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x30,0x38,0x55,0x4c,0x29,
|
||||
0x3b,0x0a,0x69,0x66,0x28,0x74,0x3c,0x34,0x29,0x20,0x7b,0x0a,0x68,0x61,0x73,0x68,0x65,0x73,0x5b,0x67,0x2a,0x34,0x2b,0x74,0x5d,0x3d,0x41,0x5b,0x74,0x5d,0x3b,0x0a,
|
||||
0x7d,0x0a,0x7d,0x0a,0x23,0x75,0x6e,0x64,0x65,0x66,0x20,0x52,0x4f,0x55,0x4e,0x44,0x53,0x0a,0x23,0x75,0x6e,0x64,0x65,0x66,0x20,0x52,0x36,0x34,0x0a,0x23,0x75,0x6e,
|
||||
0x64,0x65,0x66,0x20,0x52,0x4f,0x55,0x4e,0x44,0x0a,0x00
|
||||
};
|
||||
|
||||
} // namespace xmrig
|
151
src/backend/opencl/cl/astrobwt_v2/salsa20.cl
Normal file
151
src/backend/opencl/cl/astrobwt_v2/salsa20.cl
Normal file
|
@ -0,0 +1,151 @@
|
|||
/* 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-2022 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2022 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/>.
|
||||
*/
|
||||
|
||||
#define ROTATE(v,c) (rotate(v,(uint32_t)c))
|
||||
#define XOR(v,w) ((v) ^ (w))
|
||||
#define PLUS(v,w) ((v) + (w))
|
||||
|
||||
__attribute__((reqd_work_group_size(SALSA20_GROUP_SIZE, 1, 1)))
|
||||
__kernel void Salsa20_XORKeyStream(__global const uint32_t* keys, __global uint32_t* outputs)
|
||||
{
|
||||
const uint32_t t = get_local_id(0);
|
||||
const uint32_t g = get_group_id(0);
|
||||
|
||||
const uint64_t output_offset = g * 10240;
|
||||
|
||||
__global const uint32_t* k = keys + g * 8;
|
||||
__global uint32_t* output = outputs + (output_offset + (t * 64)) / sizeof(uint32_t);
|
||||
const uint32_t output_size = 9973;
|
||||
|
||||
const uint32_t j1 = k[0];
|
||||
const uint32_t j2 = k[1];
|
||||
const uint32_t j3 = k[2];
|
||||
const uint32_t j4 = k[3];
|
||||
const uint32_t j11 = k[4];
|
||||
const uint32_t j12 = k[5];
|
||||
const uint32_t j13 = k[6];
|
||||
const uint32_t j14 = k[7];
|
||||
const uint32_t j0 = 0x61707865U;
|
||||
const uint32_t j5 = 0x3320646EU;
|
||||
const uint32_t j10 = 0x79622D32U;
|
||||
const uint32_t j15 = 0x6B206574U;
|
||||
const uint32_t j6 = 0;
|
||||
const uint32_t j7 = 0;
|
||||
const uint32_t j8 = 0;
|
||||
const uint32_t j9 = 0;
|
||||
|
||||
for (uint32_t i = t * 64; i < output_size; i += SALSA20_GROUP_SIZE * 64)
|
||||
{
|
||||
const uint32_t j8_1 = j8 + (i / 64);
|
||||
|
||||
uint32_t x0 = j0;
|
||||
uint32_t x1 = j1;
|
||||
uint32_t x2 = j2;
|
||||
uint32_t x3 = j3;
|
||||
uint32_t x4 = j4;
|
||||
uint32_t x5 = j5;
|
||||
uint32_t x6 = j6;
|
||||
uint32_t x7 = j7;
|
||||
uint32_t x8 = j8_1;
|
||||
uint32_t x9 = j9;
|
||||
uint32_t x10 = j10;
|
||||
uint32_t x11 = j11;
|
||||
uint32_t x12 = j12;
|
||||
uint32_t x13 = j13;
|
||||
uint32_t x14 = j14;
|
||||
uint32_t x15 = j15;
|
||||
|
||||
#pragma unroll 5
|
||||
for (uint32_t j = 0; j < 10; ++j)
|
||||
{
|
||||
x4 = XOR( x4,ROTATE(PLUS( x0,x12), 7));
|
||||
x8 = XOR( x8,ROTATE(PLUS( x4, x0), 9));
|
||||
x12 = XOR(x12,ROTATE(PLUS( x8, x4),13));
|
||||
x0 = XOR( x0,ROTATE(PLUS(x12, x8),18));
|
||||
x9 = XOR( x9,ROTATE(PLUS( x5, x1), 7));
|
||||
x13 = XOR(x13,ROTATE(PLUS( x9, x5), 9));
|
||||
x1 = XOR( x1,ROTATE(PLUS(x13, x9),13));
|
||||
x5 = XOR( x5,ROTATE(PLUS( x1,x13),18));
|
||||
x14 = XOR(x14,ROTATE(PLUS(x10, x6), 7));
|
||||
x2 = XOR( x2,ROTATE(PLUS(x14,x10), 9));
|
||||
x6 = XOR( x6,ROTATE(PLUS( x2,x14),13));
|
||||
x10 = XOR(x10,ROTATE(PLUS( x6, x2),18));
|
||||
x3 = XOR( x3,ROTATE(PLUS(x15,x11), 7));
|
||||
x7 = XOR( x7,ROTATE(PLUS( x3,x15), 9));
|
||||
x11 = XOR(x11,ROTATE(PLUS( x7, x3),13));
|
||||
x15 = XOR(x15,ROTATE(PLUS(x11, x7),18));
|
||||
x1 = XOR( x1,ROTATE(PLUS( x0, x3), 7));
|
||||
x2 = XOR( x2,ROTATE(PLUS( x1, x0), 9));
|
||||
x3 = XOR( x3,ROTATE(PLUS( x2, x1),13));
|
||||
x0 = XOR( x0,ROTATE(PLUS( x3, x2),18));
|
||||
x6 = XOR( x6,ROTATE(PLUS( x5, x4), 7));
|
||||
x7 = XOR( x7,ROTATE(PLUS( x6, x5), 9));
|
||||
x4 = XOR( x4,ROTATE(PLUS( x7, x6),13));
|
||||
x5 = XOR( x5,ROTATE(PLUS( x4, x7),18));
|
||||
x11 = XOR(x11,ROTATE(PLUS(x10, x9), 7));
|
||||
x8 = XOR( x8,ROTATE(PLUS(x11,x10), 9));
|
||||
x9 = XOR( x9,ROTATE(PLUS( x8,x11),13));
|
||||
x10 = XOR(x10,ROTATE(PLUS( x9, x8),18));
|
||||
x12 = XOR(x12,ROTATE(PLUS(x15,x14), 7));
|
||||
x13 = XOR(x13,ROTATE(PLUS(x12,x15), 9));
|
||||
x14 = XOR(x14,ROTATE(PLUS(x13,x12),13));
|
||||
x15 = XOR(x15,ROTATE(PLUS(x14,x13),18));
|
||||
}
|
||||
|
||||
output[0] = PLUS(x0, j0);
|
||||
output[1] = PLUS(x1, j1);
|
||||
output[2] = PLUS(x2, j2);
|
||||
output[3] = PLUS(x3, j3);
|
||||
output[4] = PLUS(x4, j4);
|
||||
output[5] = PLUS(x5, j5);
|
||||
output[6] = PLUS(x6, j6);
|
||||
output[7] = PLUS(x7, j7);
|
||||
output[8] = PLUS(x8, j8_1);
|
||||
output[9] = PLUS(x9, j9);
|
||||
output[10] = PLUS(x10,j10);
|
||||
output[11] = PLUS(x11,j11);
|
||||
output[12] = PLUS(x12,j12);
|
||||
output[13] = PLUS(x13,j13);
|
||||
output[14] = PLUS(x14,j14);
|
||||
output[15] = PLUS(x15,j15);
|
||||
|
||||
output += (SALSA20_GROUP_SIZE * 64) / sizeof(uint32_t);
|
||||
}
|
||||
|
||||
barrier(CLK_GLOBAL_MEM_FENCE);
|
||||
|
||||
// Put zeroes after output's end
|
||||
if (t < 16)
|
||||
{
|
||||
__global uint32_t* p = outputs + (output_offset + output_size + 3) / sizeof(uint32_t);
|
||||
p[t] = 0;
|
||||
}
|
||||
|
||||
if ((t == 0) && (output_size & 3))
|
||||
outputs[(output_offset + output_size) / sizeof(uint32_t)] &= 0xFFFFFFFFU >> ((4 - (output_size & 3)) << 3);
|
||||
}
|
||||
|
||||
#undef ROTATE
|
||||
#undef XOR
|
||||
#undef PLUS
|
188
src/backend/opencl/cl/astrobwt_v2/sha3.cl
Normal file
188
src/backend/opencl/cl/astrobwt_v2/sha3.cl
Normal file
|
@ -0,0 +1,188 @@
|
|||
/* 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-2022 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2022 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/>.
|
||||
*/
|
||||
|
||||
#define ROUNDS 24
|
||||
|
||||
__constant const uint64_t rc[24] = {
|
||||
0x0000000000000001UL, 0x0000000000008082UL, 0x800000000000808AUL,
|
||||
0x8000000080008000UL, 0x000000000000808BUL, 0x0000000080000001UL,
|
||||
0x8000000080008081UL, 0x8000000000008009UL, 0x000000000000008AUL,
|
||||
0x0000000000000088UL, 0x0000000080008009UL, 0x000000008000000AUL,
|
||||
0x000000008000808BUL, 0x800000000000008BUL, 0x8000000000008089UL,
|
||||
0x8000000000008003UL, 0x8000000000008002UL, 0x8000000000000080UL,
|
||||
0x000000000000800AUL, 0x800000008000000AUL, 0x8000000080008081UL,
|
||||
0x8000000000008080UL, 0x0000000080000001UL, 0x8000000080008008UL
|
||||
};
|
||||
|
||||
__constant const int c[25][2] = {
|
||||
{ 1, 2}, { 2, 3}, { 3, 4}, { 4, 0}, { 0, 1},
|
||||
{ 6, 7}, { 7, 8}, { 8, 9}, { 9, 5}, { 5, 6},
|
||||
{11,12}, {12,13}, {13,14}, {14,10}, {10,11},
|
||||
{16,17}, {17,18}, {18,19}, {19,15}, {15,16},
|
||||
{21,22}, {22,23}, {23,24}, {24,20}, {20,21}
|
||||
};
|
||||
|
||||
__constant const int ppi[25][2] = {
|
||||
{0, 0}, {6, 44}, {12, 43}, {18, 21}, {24, 14}, {3, 28}, {9, 20}, {10, 3}, {16, 45},
|
||||
{22, 61}, {1, 1}, {7, 6}, {13, 25}, {19, 8}, {20, 18}, {4, 27}, {5, 36}, {11, 10},
|
||||
{17, 15}, {23, 56}, {2, 62}, {8, 55}, {14, 39}, {15, 41}, {21, 2}
|
||||
};
|
||||
|
||||
#define R64(a,b,c) (((a) << b) | ((a) >> c))
|
||||
|
||||
#define ROUND(k) \
|
||||
do { \
|
||||
C[t] = A[s] ^ A[s + 5] ^ A[s + 10] ^ A[s + 15] ^ A[s + 20]; \
|
||||
A[t] ^= C[s + 4] ^ R64(C[s + 1], 1, 63); \
|
||||
C[t] = R64(A[at], ro0, ro1); \
|
||||
A[t] = (C[t] ^ ((~C[c1]) & C[c2])) ^ (k1 & (k)); \
|
||||
} while (0)
|
||||
|
||||
__attribute__((reqd_work_group_size(32, 1, 1)))
|
||||
__kernel void sha3(__global const uint8_t* inputs, __global uint64_t* hashes)
|
||||
{
|
||||
const uint32_t t = get_local_id(0);
|
||||
|
||||
if (t >= 25) {
|
||||
return;
|
||||
}
|
||||
|
||||
const uint32_t g = get_group_id(0);
|
||||
const uint64_t input_offset = 10240 * 2 * g;
|
||||
__global const uint64_t* input = (__global const uint64_t*)(inputs + input_offset);
|
||||
|
||||
__local uint64_t A[25];
|
||||
__local uint64_t C[25];
|
||||
|
||||
A[t] = 0;
|
||||
|
||||
const uint32_t s = t % 5;
|
||||
const int at = ppi[t][0];
|
||||
const int ro0 = ppi[t][1];
|
||||
const int ro1 = 64 - ro0;
|
||||
const int c1 = c[t][0];
|
||||
const int c2 = c[t][1];
|
||||
const uint64_t k1 = (t == 0) ? 0xFFFFFFFFFFFFFFFFUL : 0UL;
|
||||
|
||||
const uint32_t input_size = 9973 * 2;
|
||||
const uint32_t input_words = input_size / sizeof(uint64_t);
|
||||
__global const uint64_t* const input_end17 = input + ((input_words / 17) * 17);
|
||||
__global const uint64_t* const input_end = input + input_words;
|
||||
|
||||
for (; input < input_end17; input += 17) {
|
||||
if (t < 17) A[t] ^= input[t];
|
||||
|
||||
ROUND(0x0000000000000001UL); ROUND(0x0000000000008082UL); ROUND(0x800000000000808AUL);
|
||||
ROUND(0x8000000080008000UL); ROUND(0x000000000000808BUL); ROUND(0x0000000080000001UL);
|
||||
ROUND(0x8000000080008081UL); ROUND(0x8000000000008009UL); ROUND(0x000000000000008AUL);
|
||||
ROUND(0x0000000000000088UL); ROUND(0x0000000080008009UL); ROUND(0x000000008000000AUL);
|
||||
ROUND(0x000000008000808BUL); ROUND(0x800000000000008BUL); ROUND(0x8000000000008089UL);
|
||||
ROUND(0x8000000000008003UL); ROUND(0x8000000000008002UL); ROUND(0x8000000000000080UL);
|
||||
ROUND(0x000000000000800AUL); ROUND(0x800000008000000AUL); ROUND(0x8000000080008081UL);
|
||||
ROUND(0x8000000000008080UL); ROUND(0x0000000080000001UL); ROUND(0x8000000080008008UL);
|
||||
}
|
||||
|
||||
const uint32_t wordIndex = input_end - input;
|
||||
if (t < wordIndex) A[t] ^= input[t];
|
||||
|
||||
if (t == 0) {
|
||||
uint64_t tail = 0;
|
||||
__global const uint8_t* p = (__global const uint8_t*)input_end;
|
||||
const uint32_t tail_size = input_size % sizeof(uint64_t);
|
||||
for (uint32_t i = 0; i < tail_size; ++i) {
|
||||
tail |= (uint64_t)(p[i]) << (i * 8);
|
||||
}
|
||||
|
||||
A[wordIndex] ^= tail ^ ((uint64_t)(((uint64_t)(0x02 | (1 << 2))) << (tail_size * 8)));
|
||||
A[16] ^= 0x8000000000000000UL;
|
||||
}
|
||||
|
||||
barrier(CLK_LOCAL_MEM_FENCE);
|
||||
|
||||
#pragma unroll 1
|
||||
for (int i = 0; i < ROUNDS; ++i) {
|
||||
C[t] = A[s] ^ A[s + 5] ^ A[s + 10] ^ A[s + 15] ^ A[s + 20];
|
||||
A[t] ^= C[s + 4] ^ R64(C[s + 1], 1, 63);
|
||||
C[t] = R64(A[at], ro0, ro1);
|
||||
A[t] = (C[t] ^ ((~C[c1]) & C[c2])) ^ (rc[i] & k1);
|
||||
}
|
||||
|
||||
if (t < 4) {
|
||||
hashes[g * 4 + t] = A[t];
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((reqd_work_group_size(32, 1, 1)))
|
||||
__kernel void sha3_initial(__global const uint8_t* input_data, uint32_t input_size, uint32_t nonce, __global uint64_t* hashes)
|
||||
{
|
||||
const uint32_t t = get_local_id(0);
|
||||
const uint32_t g = get_group_id(0);
|
||||
|
||||
if (t >= 25) {
|
||||
return;
|
||||
}
|
||||
|
||||
__global const uint64_t* input = (__global const uint64_t*)(input_data);
|
||||
|
||||
__local uint64_t A[25];
|
||||
__local uint64_t C[25];
|
||||
|
||||
const uint32_t input_words = input_size / sizeof(uint64_t);
|
||||
A[t] = (t < input_words) ? input[t] : 0;
|
||||
|
||||
if (t == 0) {
|
||||
((__local uint32_t*)A)[11] = nonce + g;
|
||||
|
||||
const uint32_t tail_size = input_size % sizeof(uint64_t);
|
||||
A[input_words] ^= (uint64_t)(((uint64_t)(0x02 | (1 << 2))) << (tail_size * 8));
|
||||
A[16] ^= 0x8000000000000000UL;
|
||||
}
|
||||
|
||||
barrier(CLK_LOCAL_MEM_FENCE);
|
||||
|
||||
const uint32_t s = t % 5;
|
||||
const int at = ppi[t][0];
|
||||
const int ro0 = ppi[t][1];
|
||||
const int ro1 = 64 - ro0;
|
||||
const int c1 = c[t][0];
|
||||
const int c2 = c[t][1];
|
||||
const uint64_t k1 = (t == 0) ? (uint64_t)(-1) : 0;
|
||||
|
||||
ROUND(0x0000000000000001UL); ROUND(0x0000000000008082UL); ROUND(0x800000000000808AUL);
|
||||
ROUND(0x8000000080008000UL); ROUND(0x000000000000808BUL); ROUND(0x0000000080000001UL);
|
||||
ROUND(0x8000000080008081UL); ROUND(0x8000000000008009UL); ROUND(0x000000000000008AUL);
|
||||
ROUND(0x0000000000000088UL); ROUND(0x0000000080008009UL); ROUND(0x000000008000000AUL);
|
||||
ROUND(0x000000008000808BUL); ROUND(0x800000000000008BUL); ROUND(0x8000000000008089UL);
|
||||
ROUND(0x8000000000008003UL); ROUND(0x8000000000008002UL); ROUND(0x8000000000000080UL);
|
||||
ROUND(0x000000000000800AUL); ROUND(0x800000008000000AUL); ROUND(0x8000000080008081UL);
|
||||
ROUND(0x8000000000008080UL); ROUND(0x0000000080000001UL); ROUND(0x8000000080008008UL);
|
||||
|
||||
if (t < 4) {
|
||||
hashes[g * 4 + t] = A[t];
|
||||
}
|
||||
}
|
||||
|
||||
#undef ROUNDS
|
||||
#undef R64
|
||||
#undef ROUND
|
|
@ -40,6 +40,15 @@ bool ocl_generic_astrobwt_generator(const OclDevice &device, const Algorithm &al
|
|||
return false;
|
||||
}
|
||||
|
||||
if (algorithm.id() == Algorithm::ASTROBWT_DERO_2) {
|
||||
uint32_t intensity = device.computeUnits() * 128;
|
||||
if (!intensity || (intensity > 4096)) {
|
||||
intensity = 4096;
|
||||
}
|
||||
threads.add(OclThread(device.index(), intensity, 1));
|
||||
return true;
|
||||
}
|
||||
|
||||
const size_t mem = device.globalMemSize();
|
||||
|
||||
uint32_t per_thread_mem = 10 << 20;
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
/* 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-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/kernels/astrobwt_v2/AstroBWT_v2_BWT_FixOrderKernel.h"
|
||||
#include "backend/opencl/wrappers/OclLib.h"
|
||||
|
||||
|
||||
void xmrig::AstroBWT_v2_BWT_FixOrderKernel::enqueue(cl_command_queue queue, size_t threads, size_t workgroup_size)
|
||||
{
|
||||
const size_t gthreads = threads * workgroup_size;
|
||||
enqueueNDRange(queue, 1, nullptr, >hreads, &workgroup_size);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::AstroBWT_v2_BWT_FixOrderKernel::setArgs(cl_mem datas, cl_mem keys, cl_mem temp_storage)
|
||||
{
|
||||
setArg(0, sizeof(cl_mem), &datas);
|
||||
setArg(1, sizeof(cl_mem), &keys);
|
||||
setArg(2, sizeof(cl_mem), &temp_storage);
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/* 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-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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "backend/opencl/wrappers/OclKernel.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class AstroBWT_v2_BWT_FixOrderKernel : public OclKernel
|
||||
{
|
||||
public:
|
||||
inline AstroBWT_v2_BWT_FixOrderKernel(cl_program program) : OclKernel(program, "BWT_fix_order") {}
|
||||
|
||||
void enqueue(cl_command_queue queue, size_t threads, size_t workgroup_size);
|
||||
void setArgs(cl_mem datas, cl_mem keys, cl_mem temp_storage);
|
||||
};
|
||||
|
||||
|
||||
} // namespace xmrig
|
|
@ -0,0 +1,41 @@
|
|||
/* 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-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/kernels/astrobwt_v2/AstroBWT_v2_BWT_PreprocessKernel.h"
|
||||
#include "backend/opencl/wrappers/OclLib.h"
|
||||
|
||||
|
||||
void xmrig::AstroBWT_v2_BWT_PreprocessKernel::enqueue(cl_command_queue queue, size_t threads, size_t workgroup_size)
|
||||
{
|
||||
const size_t gthreads = threads * workgroup_size;
|
||||
enqueueNDRange(queue, 1, nullptr, >hreads, &workgroup_size);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::AstroBWT_v2_BWT_PreprocessKernel::setArgs(cl_mem datas, cl_mem keys)
|
||||
{
|
||||
setArg(0, sizeof(cl_mem), &datas);
|
||||
setArg(1, sizeof(cl_mem), &keys);
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/* 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-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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "backend/opencl/wrappers/OclKernel.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class AstroBWT_v2_BWT_PreprocessKernel : public OclKernel
|
||||
{
|
||||
public:
|
||||
inline AstroBWT_v2_BWT_PreprocessKernel(cl_program program) : OclKernel(program, "BWT_preprocess") {}
|
||||
|
||||
void enqueue(cl_command_queue queue, size_t threads, size_t workgroup_size);
|
||||
void setArgs(cl_mem datas, cl_mem keys);
|
||||
};
|
||||
|
||||
|
||||
} // namespace xmrig
|
|
@ -0,0 +1,46 @@
|
|||
/* 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/astrobwt_v2/AstroBWT_v2_FindSharesKernel.h"
|
||||
#include "backend/opencl/wrappers/OclLib.h"
|
||||
|
||||
|
||||
void xmrig::AstroBWT_v2_FindSharesKernel::enqueue(cl_command_queue queue, size_t threads, size_t workgroup_size)
|
||||
{
|
||||
enqueueNDRange(queue, 1, nullptr, &threads, &workgroup_size);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::AstroBWT_v2_FindSharesKernel::setArgs(cl_mem hashes, cl_mem shares)
|
||||
{
|
||||
setArg(0, sizeof(cl_mem), &hashes);
|
||||
setArg(2, sizeof(cl_mem), &shares);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::AstroBWT_v2_FindSharesKernel::setTarget(uint64_t target)
|
||||
{
|
||||
setArg(1, sizeof(uint64_t), &target);
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/* 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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "backend/opencl/wrappers/OclKernel.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class AstroBWT_v2_FindSharesKernel : public OclKernel
|
||||
{
|
||||
public:
|
||||
inline AstroBWT_v2_FindSharesKernel(cl_program program) : OclKernel(program, "find_shares") {}
|
||||
|
||||
void enqueue(cl_command_queue queue, size_t threads, size_t workgroup_size);
|
||||
void setArgs(cl_mem hashes, cl_mem shares);
|
||||
void setTarget(uint64_t target);
|
||||
};
|
||||
|
||||
|
||||
} // namespace xmrig
|
|
@ -0,0 +1,44 @@
|
|||
/* 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-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/kernels/astrobwt_v2/AstroBWT_v2_SHA3InitialKernel.h"
|
||||
#include "backend/opencl/wrappers/OclLib.h"
|
||||
|
||||
|
||||
void xmrig::AstroBWT_v2_SHA3InitialKernel::enqueue(cl_command_queue queue, size_t threads)
|
||||
{
|
||||
const size_t workgroup_size = 32;
|
||||
const size_t gthreads = threads * workgroup_size;
|
||||
enqueueNDRange(queue, 1, nullptr, >hreads, &workgroup_size);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::AstroBWT_v2_SHA3InitialKernel::setArgs(cl_mem input, uint32_t input_size, uint32_t nonce, cl_mem output_salsa20_keys)
|
||||
{
|
||||
setArg(0, sizeof(cl_mem), &input);
|
||||
setArg(1, sizeof(uint32_t), &input_size);
|
||||
setArg(2, sizeof(uint32_t), &nonce);
|
||||
setArg(3, sizeof(cl_mem), &output_salsa20_keys);
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/* 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-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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "backend/opencl/wrappers/OclKernel.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class AstroBWT_v2_SHA3InitialKernel : public OclKernel
|
||||
{
|
||||
public:
|
||||
inline AstroBWT_v2_SHA3InitialKernel(cl_program program) : OclKernel(program, "sha3_initial") {}
|
||||
|
||||
void enqueue(cl_command_queue queue, size_t threads);
|
||||
void setArgs(cl_mem input, uint32_t input_size, uint32_t nonce, cl_mem output_salsa20_keys);
|
||||
};
|
||||
|
||||
|
||||
} // namespace xmrig
|
|
@ -0,0 +1,42 @@
|
|||
/* 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-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/kernels/astrobwt_v2/AstroBWT_v2_SHA3Kernel.h"
|
||||
#include "backend/opencl/wrappers/OclLib.h"
|
||||
|
||||
|
||||
void xmrig::AstroBWT_v2_SHA3Kernel::enqueue(cl_command_queue queue, size_t threads)
|
||||
{
|
||||
const size_t workgroup_size = 32;
|
||||
const size_t gthreads = threads * workgroup_size;
|
||||
enqueueNDRange(queue, 1, nullptr, >hreads, &workgroup_size);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::AstroBWT_v2_SHA3Kernel::setArgs(cl_mem temp_storage, cl_mem hashes)
|
||||
{
|
||||
setArg(0, sizeof(cl_mem), &temp_storage);
|
||||
setArg(1, sizeof(cl_mem), &hashes);
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/* 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-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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "backend/opencl/wrappers/OclKernel.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class AstroBWT_v2_SHA3Kernel : public OclKernel
|
||||
{
|
||||
public:
|
||||
inline AstroBWT_v2_SHA3Kernel(cl_program program) : OclKernel(program, "sha3") {}
|
||||
|
||||
void enqueue(cl_command_queue queue, size_t threads);
|
||||
void setArgs(cl_mem temp_storage, cl_mem hashes);
|
||||
};
|
||||
|
||||
|
||||
} // namespace xmrig
|
|
@ -0,0 +1,41 @@
|
|||
/* 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-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/kernels/astrobwt_v2/AstroBWT_v2_Salsa20Kernel.h"
|
||||
#include "backend/opencl/wrappers/OclLib.h"
|
||||
|
||||
|
||||
void xmrig::AstroBWT_v2_Salsa20Kernel::enqueue(cl_command_queue queue, size_t threads, size_t workgroup_size)
|
||||
{
|
||||
const size_t gthreads = threads * workgroup_size;
|
||||
enqueueNDRange(queue, 1, nullptr, >hreads, &workgroup_size);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::AstroBWT_v2_Salsa20Kernel::setArgs(cl_mem salsa20_keys, cl_mem outputs)
|
||||
{
|
||||
setArg(0, sizeof(cl_mem), &salsa20_keys);
|
||||
setArg(1, sizeof(cl_mem), &outputs);
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/* 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-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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "backend/opencl/wrappers/OclKernel.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class AstroBWT_v2_Salsa20Kernel : public OclKernel
|
||||
{
|
||||
public:
|
||||
inline AstroBWT_v2_Salsa20Kernel(cl_program program) : OclKernel(program, "Salsa20_XORKeyStream") {}
|
||||
|
||||
void enqueue(cl_command_queue queue, size_t threads, size_t workgroup_size);
|
||||
void setArgs(cl_mem salsa20_keys, cl_mem outputs);
|
||||
};
|
||||
|
||||
|
||||
} // namespace xmrig
|
|
@ -119,7 +119,14 @@ if (WITH_OPENCL)
|
|||
src/backend/opencl/kernels/astrobwt/AstroBWT_Salsa20Kernel.h
|
||||
src/backend/opencl/kernels/astrobwt/AstroBWT_SHA3InitialKernel.h
|
||||
src/backend/opencl/kernels/astrobwt/AstroBWT_SHA3Kernel.h
|
||||
src/backend/opencl/kernels/astrobwt_v2/AstroBWT_v2_BWT_FixOrderKernel.h
|
||||
src/backend/opencl/kernels/astrobwt_v2/AstroBWT_v2_BWT_PreprocessKernel.h
|
||||
src/backend/opencl/kernels/astrobwt_v2/AstroBWT_v2_FindSharesKernel.h
|
||||
src/backend/opencl/kernels/astrobwt_v2/AstroBWT_v2_Salsa20Kernel.h
|
||||
src/backend/opencl/kernels/astrobwt_v2/AstroBWT_v2_SHA3InitialKernel.h
|
||||
src/backend/opencl/kernels/astrobwt_v2/AstroBWT_v2_SHA3Kernel.h
|
||||
src/backend/opencl/runners/OclAstroBWTRunner.h
|
||||
src/backend/opencl/runners/OclAstroBWT_v2_Runner.h
|
||||
)
|
||||
|
||||
list(APPEND SOURCES_BACKEND_OPENCL
|
||||
|
@ -131,7 +138,14 @@ if (WITH_OPENCL)
|
|||
src/backend/opencl/kernels/astrobwt/AstroBWT_Salsa20Kernel.cpp
|
||||
src/backend/opencl/kernels/astrobwt/AstroBWT_SHA3InitialKernel.cpp
|
||||
src/backend/opencl/kernels/astrobwt/AstroBWT_SHA3Kernel.cpp
|
||||
src/backend/opencl/kernels/astrobwt_v2/AstroBWT_v2_BWT_FixOrderKernel.cpp
|
||||
src/backend/opencl/kernels/astrobwt_v2/AstroBWT_v2_BWT_PreprocessKernel.cpp
|
||||
src/backend/opencl/kernels/astrobwt_v2/AstroBWT_v2_FindSharesKernel.cpp
|
||||
src/backend/opencl/kernels/astrobwt_v2/AstroBWT_v2_Salsa20Kernel.cpp
|
||||
src/backend/opencl/kernels/astrobwt_v2/AstroBWT_v2_SHA3InitialKernel.cpp
|
||||
src/backend/opencl/kernels/astrobwt_v2/AstroBWT_v2_SHA3Kernel.cpp
|
||||
src/backend/opencl/runners/OclAstroBWTRunner.cpp
|
||||
src/backend/opencl/runners/OclAstroBWT_v2_Runner.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
|
|
155
src/backend/opencl/runners/OclAstroBWT_v2_Runner.cpp
Normal file
155
src/backend/opencl/runners/OclAstroBWT_v2_Runner.cpp
Normal file
|
@ -0,0 +1,155 @@
|
|||
/* XMRig
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 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/runners/OclAstroBWT_v2_Runner.h"
|
||||
#include "backend/opencl/kernels/astrobwt_v2/AstroBWT_v2_FindSharesKernel.h"
|
||||
#include "backend/opencl/kernels/astrobwt_v2/AstroBWT_v2_BWT_FixOrderKernel.h"
|
||||
#include "backend/opencl/kernels/astrobwt_v2/AstroBWT_v2_BWT_PreprocessKernel.h"
|
||||
#include "backend/opencl/kernels/astrobwt_v2/AstroBWT_v2_Salsa20Kernel.h"
|
||||
#include "backend/opencl/kernels/astrobwt_v2/AstroBWT_v2_SHA3InitialKernel.h"
|
||||
#include "backend/opencl/kernels/astrobwt_v2/AstroBWT_v2_SHA3Kernel.h"
|
||||
#include "backend/opencl/OclLaunchData.h"
|
||||
#include "backend/opencl/wrappers/OclLib.h"
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/net/stratum/Job.h"
|
||||
|
||||
|
||||
xmrig::OclAstroBWT_v2_Runner::OclAstroBWT_v2_Runner(size_t index, const OclLaunchData &data) : OclBaseRunner(index, data)
|
||||
{
|
||||
switch (data.device.type())
|
||||
{
|
||||
case OclDevice::Baffin:
|
||||
case OclDevice::Ellesmere:
|
||||
case OclDevice::Polaris:
|
||||
case OclDevice::Lexa:
|
||||
case OclDevice::Vega_10:
|
||||
case OclDevice::Vega_20:
|
||||
case OclDevice::Raven:
|
||||
m_workgroup_size = 64;
|
||||
break;
|
||||
|
||||
default:
|
||||
m_workgroup_size = 32;
|
||||
break;
|
||||
}
|
||||
|
||||
m_options += " -DSALSA20_GROUP_SIZE=" + std::to_string(m_workgroup_size);
|
||||
m_bwt_allocation_size = m_intensity * BWT_DATA_STRIDE;
|
||||
}
|
||||
|
||||
|
||||
xmrig::OclAstroBWT_v2_Runner::~OclAstroBWT_v2_Runner()
|
||||
{
|
||||
delete m_find_shares_kernel;
|
||||
delete m_bwt_fix_order_kernel;
|
||||
delete m_bwt_preprocess_kernel;
|
||||
delete m_salsa20_kernel;
|
||||
delete m_sha3_initial_kernel;
|
||||
delete m_sha3_kernel;
|
||||
|
||||
OclLib::release(m_input);
|
||||
OclLib::release(m_hashes);
|
||||
OclLib::release(m_data);
|
||||
OclLib::release(m_keys);
|
||||
OclLib::release(m_temp_storage);
|
||||
}
|
||||
|
||||
|
||||
size_t xmrig::OclAstroBWT_v2_Runner::bufferSize() const
|
||||
{
|
||||
return OclBaseRunner::bufferSize() +
|
||||
align(m_intensity * 32) + // m_hashes
|
||||
align(m_bwt_allocation_size) + // m_data
|
||||
align(m_bwt_allocation_size * 4) + // m_keys
|
||||
align(m_bwt_allocation_size * 2); // m_temp_storage
|
||||
}
|
||||
|
||||
|
||||
void xmrig::OclAstroBWT_v2_Runner::run(uint32_t nonce, uint32_t *hashOutput)
|
||||
{
|
||||
const uint32_t zero = 0;
|
||||
enqueueWriteBuffer(m_output, CL_FALSE, sizeof(cl_uint) * 0xFF, sizeof(uint32_t), &zero);
|
||||
|
||||
m_sha3_initial_kernel->setArg(2, sizeof(nonce), &nonce);
|
||||
m_sha3_initial_kernel->enqueue(m_queue, m_intensity);
|
||||
|
||||
m_salsa20_kernel->enqueue(m_queue, m_intensity, m_workgroup_size);
|
||||
|
||||
m_bwt_preprocess_kernel->enqueue(m_queue, m_intensity, 1024);
|
||||
m_bwt_fix_order_kernel->enqueue(m_queue, m_intensity, 1024);
|
||||
|
||||
m_sha3_kernel->enqueue(m_queue, m_intensity);
|
||||
|
||||
m_find_shares_kernel->enqueue(m_queue, m_intensity, m_workgroup_size);
|
||||
|
||||
finalize(hashOutput);
|
||||
|
||||
OclLib::finish(m_queue);
|
||||
|
||||
for (uint32_t i = 0; i < hashOutput[0xFF]; ++i) {
|
||||
hashOutput[i] += nonce;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::OclAstroBWT_v2_Runner::set(const Job &job, uint8_t *blob)
|
||||
{
|
||||
if (job.size() > (Job::kMaxBlobSize - 4)) {
|
||||
throw std::length_error("job size too big");
|
||||
}
|
||||
|
||||
if (job.size() < Job::kMaxBlobSize) {
|
||||
memset(blob + job.size(), 0, Job::kMaxBlobSize - job.size());
|
||||
}
|
||||
|
||||
enqueueWriteBuffer(m_input, CL_TRUE, 0, Job::kMaxBlobSize, blob);
|
||||
|
||||
m_sha3_initial_kernel->setArgs(m_input, static_cast<uint32_t>(job.size()), *job.nonce(), m_hashes);
|
||||
m_salsa20_kernel->setArgs(m_hashes, m_data);
|
||||
m_bwt_preprocess_kernel->setArgs(m_data, m_keys);
|
||||
m_bwt_fix_order_kernel->setArgs(m_data, m_keys, m_temp_storage);
|
||||
m_sha3_kernel->setArgs(m_temp_storage, m_hashes);
|
||||
m_find_shares_kernel->setArgs(m_hashes, m_output);
|
||||
m_find_shares_kernel->setTarget(job.target());
|
||||
}
|
||||
|
||||
|
||||
void xmrig::OclAstroBWT_v2_Runner::build()
|
||||
{
|
||||
OclBaseRunner::build();
|
||||
|
||||
m_find_shares_kernel = new AstroBWT_v2_FindSharesKernel(m_program);
|
||||
m_bwt_fix_order_kernel = new AstroBWT_v2_BWT_FixOrderKernel(m_program);
|
||||
m_bwt_preprocess_kernel = new AstroBWT_v2_BWT_PreprocessKernel(m_program);
|
||||
m_salsa20_kernel = new AstroBWT_v2_Salsa20Kernel(m_program);
|
||||
m_sha3_initial_kernel = new AstroBWT_v2_SHA3InitialKernel(m_program);
|
||||
m_sha3_kernel = new AstroBWT_v2_SHA3Kernel(m_program);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::OclAstroBWT_v2_Runner::init()
|
||||
{
|
||||
OclBaseRunner::init();
|
||||
|
||||
const cl_mem_flags f = CL_MEM_READ_WRITE | CL_MEM_HOST_NO_ACCESS;
|
||||
|
||||
m_hashes = createSubBuffer(f, m_intensity * 32);
|
||||
m_data = createSubBuffer(f, m_bwt_allocation_size);
|
||||
m_keys = createSubBuffer(f, m_bwt_allocation_size * 4);
|
||||
m_temp_storage = createSubBuffer(f, m_bwt_allocation_size * 2);
|
||||
}
|
78
src/backend/opencl/runners/OclAstroBWT_v2_Runner.h
Normal file
78
src/backend/opencl/runners/OclAstroBWT_v2_Runner.h
Normal file
|
@ -0,0 +1,78 @@
|
|||
/* XMRig
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 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/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_OclAstroBWT_v2_Runner_H
|
||||
#define XMRIG_OclAstroBWT_v2_Runner_H
|
||||
|
||||
|
||||
#include "backend/opencl/runners/OclBaseRunner.h"
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class AstroBWT_v2_FindSharesKernel;
|
||||
class AstroBWT_v2_BWT_FixOrderKernel;
|
||||
class AstroBWT_v2_BWT_PreprocessKernel;
|
||||
class AstroBWT_v2_Salsa20Kernel;
|
||||
class AstroBWT_v2_SHA3InitialKernel;
|
||||
class AstroBWT_v2_SHA3Kernel;
|
||||
|
||||
|
||||
class OclAstroBWT_v2_Runner : public OclBaseRunner
|
||||
{
|
||||
public:
|
||||
static constexpr uint32_t BWT_DATA_SIZE = 9973;
|
||||
static constexpr uint32_t BWT_DATA_STRIDE = 10240;
|
||||
|
||||
XMRIG_DISABLE_COPY_MOVE_DEFAULT(OclAstroBWT_v2_Runner)
|
||||
|
||||
OclAstroBWT_v2_Runner(size_t index, const OclLaunchData &data);
|
||||
~OclAstroBWT_v2_Runner() override;
|
||||
|
||||
inline uint32_t roundSize() const override { return m_intensity; }
|
||||
inline uint32_t processedHashes() const override { return m_intensity; }
|
||||
|
||||
protected:
|
||||
size_t bufferSize() const override;
|
||||
void run(uint32_t nonce, uint32_t *hashOutput) override;
|
||||
void set(const Job &job, uint8_t *blob) override;
|
||||
void build() override;
|
||||
void init() override;
|
||||
|
||||
private:
|
||||
AstroBWT_v2_FindSharesKernel* m_find_shares_kernel = nullptr;
|
||||
AstroBWT_v2_BWT_FixOrderKernel* m_bwt_fix_order_kernel = nullptr;
|
||||
AstroBWT_v2_BWT_PreprocessKernel* m_bwt_preprocess_kernel = nullptr;
|
||||
AstroBWT_v2_Salsa20Kernel* m_salsa20_kernel = nullptr;
|
||||
AstroBWT_v2_SHA3InitialKernel* m_sha3_initial_kernel = nullptr;
|
||||
AstroBWT_v2_SHA3Kernel* m_sha3_kernel = nullptr;
|
||||
|
||||
cl_mem m_hashes = nullptr;
|
||||
cl_mem m_data = nullptr;
|
||||
cl_mem m_keys = nullptr;
|
||||
cl_mem m_temp_storage = nullptr;
|
||||
|
||||
uint32_t m_workgroup_size = 0;
|
||||
uint32_t m_bwt_allocation_size = 0;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif // XMRIG_OclAstroBWT_v2_Runner_H
|
|
@ -94,6 +94,7 @@ const char *Algorithm::kAR2_WRKZ = "argon2/ninja";
|
|||
#ifdef XMRIG_ALGO_ASTROBWT
|
||||
const char *Algorithm::kASTROBWT = "astrobwt";
|
||||
const char *Algorithm::kASTROBWT_DERO = "astrobwt";
|
||||
const char *Algorithm::kASTROBWT_DERO_2 = "astrobwt/v2";
|
||||
#endif
|
||||
|
||||
#ifdef XMRIG_ALGO_KAWPOW
|
||||
|
@ -163,6 +164,7 @@ static const std::map<uint32_t, const char *> kAlgorithmNames = {
|
|||
|
||||
# ifdef XMRIG_ALGO_ASTROBWT
|
||||
ALGO_NAME(ASTROBWT_DERO),
|
||||
ALGO_NAME(ASTROBWT_DERO_2),
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_ALGO_KAWPOW
|
||||
|
@ -282,6 +284,9 @@ static const std::map<const char *, Algorithm::Id, aliasCompare> kAlgorithmAlias
|
|||
|
||||
# ifdef XMRIG_ALGO_ASTROBWT
|
||||
ALGO_ALIAS_AUTO(ASTROBWT_DERO), ALGO_ALIAS(ASTROBWT_DERO, "astrobwt/dero"),
|
||||
ALGO_ALIAS_AUTO(ASTROBWT_DERO_2), ALGO_ALIAS(ASTROBWT_DERO_2, "astrobwt/v2"),
|
||||
ALGO_ALIAS_AUTO(ASTROBWT_DERO_2), ALGO_ALIAS(ASTROBWT_DERO_2, "astrobwt/dero_he"),
|
||||
ALGO_ALIAS_AUTO(ASTROBWT_DERO_2), ALGO_ALIAS(ASTROBWT_DERO_2, "astrobwt/derohe"),
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_ALGO_KAWPOW
|
||||
|
@ -365,7 +370,7 @@ std::vector<xmrig::Algorithm> xmrig::Algorithm::all(const std::function<bool(con
|
|||
CN_UPX2,
|
||||
RX_0, RX_WOW, RX_ARQ, RX_GRAFT, RX_SFX, RX_KEVA,
|
||||
AR2_CHUKWA, AR2_CHUKWA_V2, AR2_WRKZ,
|
||||
ASTROBWT_DERO,
|
||||
ASTROBWT_DERO, ASTROBWT_DERO_2,
|
||||
KAWPOW_RVN,
|
||||
GHOSTRIDER_RTM
|
||||
};
|
||||
|
|
|
@ -82,6 +82,7 @@ public:
|
|||
AR2_CHUKWA_V2 = 0x61140000, // "argon2/chukwav2" Argon2id (Chukwa v2).
|
||||
AR2_WRKZ = 0x61120000, // "argon2/wrkz" Argon2id (WRKZ)
|
||||
ASTROBWT_DERO = 0x41000000, // "astrobwt" AstroBWT (Dero)
|
||||
ASTROBWT_DERO_2 = 0x41110000, // "astrobwt/v2" AstroBWT (Dero HE)
|
||||
KAWPOW_RVN = 0x6b0f0000, // "kawpow/rvn" KawPow (RVN)
|
||||
};
|
||||
|
||||
|
@ -158,6 +159,7 @@ public:
|
|||
# ifdef XMRIG_ALGO_ASTROBWT
|
||||
static const char *kASTROBWT;
|
||||
static const char *kASTROBWT_DERO;
|
||||
static const char* kASTROBWT_DERO_2;
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_ALGO_KAWPOW
|
||||
|
|
|
@ -50,6 +50,7 @@ static const CoinInfo coinInfo[] = {
|
|||
{ Algorithm::CN_R, "SUMO", "Sumokoin", 240, 1000000000, BLUE_BG_BOLD( WHITE_BOLD_S " sumo ") },
|
||||
{ Algorithm::RX_ARQ, "ARQ", "ArQmA", 120, 1000000000, BLUE_BG_BOLD( WHITE_BOLD_S " arqma ") },
|
||||
{ Algorithm::ASTROBWT_DERO, "DERO", "DERO", 0, 0, BLUE_BG_BOLD( WHITE_BOLD_S " dero ") },
|
||||
{ Algorithm::ASTROBWT_DERO_2, "DERO_HE", "DERO_HE", 0, 0, BLUE_BG_BOLD( WHITE_BOLD_S " dero_he ") },
|
||||
{ Algorithm::RX_GRAFT, "GRFT", "Graft", 120, 10000000000, BLUE_BG_BOLD( WHITE_BOLD_S " graft ") },
|
||||
{ Algorithm::RX_KEVA, "KVA", "Kevacoin", 0, 0, MAGENTA_BG_BOLD(WHITE_BOLD_S " keva ") },
|
||||
{ Algorithm::KAWPOW_RVN, "RVN", "Ravencoin", 0, 0, BLUE_BG_BOLD( WHITE_BOLD_S " raven ") },
|
||||
|
|
|
@ -36,6 +36,7 @@ public:
|
|||
SUMO,
|
||||
ARQMA,
|
||||
DERO,
|
||||
DERO_HE,
|
||||
GRAFT,
|
||||
KEVA,
|
||||
RAVEN,
|
||||
|
|
|
@ -53,10 +53,8 @@ const uint64_t keccakf_rndc[24] =
|
|||
|
||||
void xmrig::keccakf(uint64_t st[25], int rounds)
|
||||
{
|
||||
int i, j, round;
|
||||
uint64_t t, bc[5];
|
||||
|
||||
for (round = 0; round < rounds; ++round) {
|
||||
for (int round = 0; round < rounds; ++round) {
|
||||
uint64_t bc[5];
|
||||
|
||||
// Theta
|
||||
bc[0] = st[0] ^ st[5] ^ st[10] ^ st[15] ^ st[20];
|
||||
|
@ -65,17 +63,21 @@ void xmrig::keccakf(uint64_t st[25], int rounds)
|
|||
bc[3] = st[3] ^ st[8] ^ st[13] ^ st[18] ^ st[23];
|
||||
bc[4] = st[4] ^ st[9] ^ st[14] ^ st[19] ^ st[24];
|
||||
|
||||
for (i = 0; i < 5; ++i) {
|
||||
t = bc[(i + 4) % 5] ^ ROTL64(bc[(i + 1) % 5], 1);
|
||||
st[i ] ^= t;
|
||||
st[i + 5] ^= t;
|
||||
st[i + 10] ^= t;
|
||||
st[i + 15] ^= t;
|
||||
st[i + 20] ^= t;
|
||||
#define X(i) { \
|
||||
const uint64_t t = bc[(i + 4) % 5] ^ ROTL64(bc[(i + 1) % 5], 1); \
|
||||
st[i ] ^= t; \
|
||||
st[i + 5] ^= t; \
|
||||
st[i + 10] ^= t; \
|
||||
st[i + 15] ^= t; \
|
||||
st[i + 20] ^= t; \
|
||||
}
|
||||
|
||||
X(0); X(1); X(2); X(3); X(4);
|
||||
|
||||
#undef X
|
||||
|
||||
// Rho Pi
|
||||
t = st[1];
|
||||
const uint64_t t = st[1];
|
||||
st[ 1] = ROTL64(st[ 6], 44);
|
||||
st[ 6] = ROTL64(st[ 9], 20);
|
||||
st[ 9] = ROTL64(st[22], 61);
|
||||
|
@ -103,7 +105,7 @@ void xmrig::keccakf(uint64_t st[25], int rounds)
|
|||
|
||||
// Chi
|
||||
// unrolled loop, where only last iteration is different
|
||||
j = 0;
|
||||
int j = 0;
|
||||
bc[0] = st[j ];
|
||||
bc[1] = st[j + 1];
|
||||
|
||||
|
|
|
@ -61,6 +61,7 @@ public:
|
|||
virtual bool hasExtension(Extension extension) const noexcept = 0;
|
||||
virtual bool isEnabled() const = 0;
|
||||
virtual bool isTLS() const = 0;
|
||||
virtual bool isWSS() const = 0;
|
||||
virtual const char *mode() const = 0;
|
||||
virtual const char *tag() const = 0;
|
||||
virtual const char *tlsFingerprint() const = 0;
|
||||
|
|
|
@ -59,6 +59,8 @@ protected:
|
|||
void setPool(const Pool &pool) override;
|
||||
|
||||
protected:
|
||||
bool isWSS() const override { return false; }
|
||||
|
||||
enum SocketState {
|
||||
UnconnectedState,
|
||||
HostLookupState,
|
||||
|
|
|
@ -48,8 +48,14 @@
|
|||
#include "net/JobResult.h"
|
||||
|
||||
|
||||
#ifdef XMRIG_FEATURE_TLS
|
||||
#include <openssl/ssl.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <random>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
@ -59,6 +65,8 @@ Storage<DaemonClient> DaemonClient::m_storage;
|
|||
|
||||
|
||||
static const char* kBlocktemplateBlob = "blocktemplate_blob";
|
||||
static const char* kBlockhashingBlob = "blockhashing_blob";
|
||||
static const char* kLastError = "lasterror";
|
||||
static const char *kGetHeight = "/getheight";
|
||||
static const char *kGetInfo = "/getinfo";
|
||||
static const char *kHash = "hash";
|
||||
|
@ -73,6 +81,14 @@ static constexpr size_t kZMQGreetingSize1 = 11;
|
|||
static const char kZMQHandshake[] = "\4\x19\5READY\xbSocket-Type\0\0\0\3SUB";
|
||||
static const char kZMQSubscribe[] = "\0\x18\1json-minimal-chain_main";
|
||||
|
||||
static const char kWSSLogin[] = "\
|
||||
GET /ws/%s HTTP/1.1\r\n\
|
||||
Host: %s\r\n\
|
||||
Upgrade: websocket\r\n\
|
||||
Connection: Upgrade\r\n\
|
||||
Sec-WebSocket-Key: %s\r\n\
|
||||
Sec-WebSocket-Version: 13\r\n\r\n";
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
|
@ -89,11 +105,20 @@ xmrig::DaemonClient::~DaemonClient()
|
|||
{
|
||||
delete m_timer;
|
||||
delete m_ZMQSocket;
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
delete m_wss.m_socket;
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
void xmrig::DaemonClient::deleteLater()
|
||||
{
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
if (m_pool.isWSS()) {
|
||||
WSSClose(true);
|
||||
}
|
||||
else
|
||||
# endif
|
||||
if (m_pool.zmq_port() >= 0) {
|
||||
ZMQClose(true);
|
||||
}
|
||||
|
@ -123,6 +148,12 @@ bool xmrig::DaemonClient::isTLS() const
|
|||
}
|
||||
|
||||
|
||||
bool xmrig::DaemonClient::isWSS() const
|
||||
{
|
||||
return m_pool.isWSS();
|
||||
}
|
||||
|
||||
|
||||
int64_t xmrig::DaemonClient::submit(const JobResult &result)
|
||||
{
|
||||
if (result.jobId != m_currentJobId) {
|
||||
|
@ -151,6 +182,17 @@ int64_t xmrig::DaemonClient::submit(const JobResult &result)
|
|||
|
||||
Cvt::toHex(data + m_job.nonceOffset() * 2, 8, reinterpret_cast<const uint8_t*>(&result.nonce), 4);
|
||||
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
if (m_pool.isWSS() && (m_apiVersion == API_DERO) && (m_pool.algorithm().id() == Algorithm::ASTROBWT_DERO_2)) {
|
||||
char buf[256];
|
||||
const int n = snprintf(buf, sizeof(buf), "{\"jobid\":\"%s\",\"mbl_blob\":\"%s\"}", m_job.id().data(), data);
|
||||
if (0 <= n && n < static_cast<int>(sizeof(buf))) {
|
||||
return WSSWrite(buf, n) ? 1 : -1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
# endif
|
||||
|
||||
if (m_blocktemplate.hasMinerSignature()) {
|
||||
Cvt::toHex(data + sig_offset * 2, 128, result.minerSignature(), 64);
|
||||
}
|
||||
|
@ -193,19 +235,24 @@ void xmrig::DaemonClient::connect()
|
|||
|
||||
setState(ConnectingState);
|
||||
|
||||
if (!m_walletAddress.isValid()) {
|
||||
return connectError("Invalid wallet address.");
|
||||
}
|
||||
|
||||
if (!m_coin.isValid() && !m_pool.algorithm().isValid()) {
|
||||
return connectError("Invalid algorithm.");
|
||||
}
|
||||
|
||||
if ((m_pool.algorithm() == Algorithm::ASTROBWT_DERO) || (m_coin == Coin::DERO)) {
|
||||
if (!m_pool.algorithm().isValid()) {
|
||||
m_pool.setAlgo(m_coin.algorithm());
|
||||
}
|
||||
|
||||
const xmrig::Algorithm algo = m_pool.algorithm();
|
||||
if ((algo == Algorithm::ASTROBWT_DERO) || (algo == Algorithm::ASTROBWT_DERO_2) || (m_coin == Coin::DERO) || (m_coin == Coin::DERO_HE)) {
|
||||
m_apiVersion = API_DERO;
|
||||
}
|
||||
|
||||
if (m_pool.zmq_port() >= 0) {
|
||||
if ((m_apiVersion == API_MONERO) && !m_walletAddress.isValid()) {
|
||||
return connectError("Invalid wallet address.");
|
||||
}
|
||||
|
||||
if ((m_pool.zmq_port() >= 0) || m_pool.isWSS()) {
|
||||
m_dns = Dns::resolve(m_pool.host(), this);
|
||||
}
|
||||
else {
|
||||
|
@ -306,6 +353,9 @@ void xmrig::DaemonClient::onTimer(const Timer *)
|
|||
connect();
|
||||
}
|
||||
else if (m_state == ConnectedState) {
|
||||
if (m_pool.isWSS()) {
|
||||
return;
|
||||
}
|
||||
if (m_apiVersion == API_DERO) {
|
||||
rpcSend(JsonRequest::create(m_sequence, "get_info"));
|
||||
}
|
||||
|
@ -330,26 +380,35 @@ void xmrig::DaemonClient::onResolved(const DnsRecords &records, int status, cons
|
|||
}
|
||||
|
||||
|
||||
delete m_ZMQSocket;
|
||||
|
||||
|
||||
const auto &record = records.get();
|
||||
m_ip = record.ip();
|
||||
|
||||
auto req = new uv_connect_t;
|
||||
req->data = m_storage.ptr(m_key);
|
||||
|
||||
m_ZMQSocket = new uv_tcp_t;
|
||||
m_ZMQSocket->data = m_storage.ptr(m_key);
|
||||
uv_tcp_t* s = new uv_tcp_t;
|
||||
s->data = m_storage.ptr(m_key);
|
||||
|
||||
uv_tcp_init(uv_default_loop(), m_ZMQSocket);
|
||||
uv_tcp_nodelay(m_ZMQSocket, 1);
|
||||
uv_tcp_init(uv_default_loop(), s);
|
||||
uv_tcp_nodelay(s, 1);
|
||||
|
||||
# ifndef WIN32
|
||||
uv_tcp_keepalive(m_ZMQSocket, 1, 60);
|
||||
uv_tcp_keepalive(s, 1, 60);
|
||||
# endif
|
||||
|
||||
uv_tcp_connect(req, m_ZMQSocket, record.addr(m_pool.zmq_port()), onZMQConnect);
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
if (m_pool.isWSS()) {
|
||||
delete m_wss.m_socket;
|
||||
m_wss.m_socket = s;
|
||||
uv_tcp_connect(req, s, record.addr(m_pool.port()), onWSSConnect);
|
||||
}
|
||||
else
|
||||
# endif
|
||||
if (m_pool.zmq_port() > 0) {
|
||||
delete m_ZMQSocket;
|
||||
m_ZMQSocket = s;
|
||||
uv_tcp_connect(req, s, record.addr(m_pool.zmq_port()), onZMQConnect);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -396,7 +455,7 @@ bool xmrig::DaemonClient::parseJob(const rapidjson::Value ¶ms, int *code)
|
|||
);
|
||||
# endif
|
||||
|
||||
m_blockhashingblob = Json::getString(params, "blockhashing_blob");
|
||||
m_blockhashingblob = Json::getString(params, kBlockhashingBlob);
|
||||
|
||||
if (m_blocktemplate.hasMinerSignature()) {
|
||||
if (m_pool.spendSecretKey().isEmpty()) {
|
||||
|
@ -589,6 +648,12 @@ void xmrig::DaemonClient::retry()
|
|||
setState(ConnectingState);
|
||||
}
|
||||
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
if (m_wss.m_socket) {
|
||||
uv_close(reinterpret_cast<uv_handle_t*>(m_wss.m_socket), onWSSClose);
|
||||
}
|
||||
else
|
||||
# endif
|
||||
if ((m_ZMQConnectionState != ZMQ_NOT_CONNECTED) && (m_ZMQConnectionState != ZMQ_DISCONNECTING)) {
|
||||
uv_close(reinterpret_cast<uv_handle_t*>(m_ZMQSocket), onZMQClose);
|
||||
}
|
||||
|
@ -913,3 +978,377 @@ bool xmrig::DaemonClient::ZMQClose(bool shutdown)
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#ifdef XMRIG_FEATURE_TLS
|
||||
void xmrig::DaemonClient::onWSSConnect(uv_connect_t* req, int status)
|
||||
{
|
||||
DaemonClient* client = getClient(req->data);
|
||||
delete req;
|
||||
|
||||
if (!client) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (status < 0) {
|
||||
LOG_ERR("%s " RED("WSS connect error: ") RED_BOLD("\"%s\""), client->tag(), uv_strerror(status));
|
||||
client->retry();
|
||||
return;
|
||||
}
|
||||
|
||||
client->WSSConnected();
|
||||
}
|
||||
|
||||
|
||||
void xmrig::DaemonClient::onWSSRead(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf)
|
||||
{
|
||||
DaemonClient* client = getClient(stream->data);
|
||||
if (client) {
|
||||
client->WSSRead(nread, buf);
|
||||
}
|
||||
|
||||
NetBuffer::release(buf);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::DaemonClient::onWSSClose(uv_handle_t* handle)
|
||||
{
|
||||
DaemonClient* client = getClient(handle->data);
|
||||
if (client) {
|
||||
# ifdef APP_DEBUG
|
||||
LOG_DEBUG(CYAN("%s") BLACK_BOLD(" disconnected"), client->m_pool.url().data());
|
||||
# endif
|
||||
client->m_wss.cleanup();
|
||||
client->retry();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::DaemonClient::onWSSShutdown(uv_handle_t* handle)
|
||||
{
|
||||
DaemonClient* client = getClient(handle->data);
|
||||
if (client) {
|
||||
# ifdef APP_DEBUG
|
||||
LOG_DEBUG(CYAN("%s") BLACK_BOLD(" shutdown"), client->m_pool.url().data());
|
||||
# endif
|
||||
client->m_wss.cleanup();
|
||||
m_storage.remove(client->m_key);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::DaemonClient::WSSConnected()
|
||||
{
|
||||
m_wss.m_ctx = SSL_CTX_new(SSLv23_method());
|
||||
m_wss.m_write = BIO_new(BIO_s_mem());
|
||||
m_wss.m_read = BIO_new(BIO_s_mem());
|
||||
|
||||
SSL_CTX_set_options(m_wss.m_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
|
||||
m_wss.m_ssl = SSL_new(m_wss.m_ctx);
|
||||
SSL_set_connect_state(m_wss.m_ssl);
|
||||
SSL_set_bio(m_wss.m_ssl, m_wss.m_read, m_wss.m_write);
|
||||
SSL_do_handshake(m_wss.m_ssl);
|
||||
|
||||
if (WSSWrite(nullptr, 0)) {
|
||||
uv_read_start(reinterpret_cast<uv_stream_t*>(m_wss.m_socket), NetBuffer::onAlloc, onWSSRead);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::DaemonClient::WSSWrite(const char* data, size_t size)
|
||||
{
|
||||
if (!m_wss.m_socket) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (data && size) {
|
||||
# ifdef APP_DEBUG
|
||||
LOG_DEBUG(CYAN("%s") BLACK_BOLD(" write ") CYAN_BOLD("%zu") BLACK_BOLD(" bytes") " %s", m_pool.url().data(), size, data);
|
||||
# endif
|
||||
|
||||
if (!m_wss.m_handshake) {
|
||||
WSS::Header h{};
|
||||
h.fin = 1;
|
||||
h.mask = 1;
|
||||
h.opcode = 1;
|
||||
|
||||
uint8_t size_buf[8];
|
||||
if (size < 126) {
|
||||
h.payload_len = static_cast<uint8_t>(size);
|
||||
}
|
||||
else if (size < 65536) {
|
||||
h.payload_len = 126;
|
||||
size_buf[0] = static_cast<uint8_t>(size >> 8);
|
||||
size_buf[1] = static_cast<uint8_t>(size & 0xFF);
|
||||
}
|
||||
else {
|
||||
h.payload_len = 127;
|
||||
uint64_t k = size;
|
||||
for (int i = 7; i >= 0; --i, k >>= 8) {
|
||||
size_buf[i] = static_cast<uint8_t>(k & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
// Header
|
||||
SSL_write(m_wss.m_ssl, &h, sizeof(h));
|
||||
|
||||
// Optional extended payload length
|
||||
if (h.payload_len == 126) SSL_write(m_wss.m_ssl, size_buf, 2);
|
||||
if (h.payload_len == 127) SSL_write(m_wss.m_ssl, size_buf, 8);
|
||||
|
||||
// Masking-key
|
||||
SSL_write(m_wss.m_ssl, "\0\0\0\0", 4);
|
||||
}
|
||||
|
||||
SSL_write(m_wss.m_ssl, data, static_cast<int>(size));
|
||||
}
|
||||
|
||||
uv_buf_t buf;
|
||||
buf.len = BIO_get_mem_data(m_wss.m_write, &buf.base);
|
||||
|
||||
if (buf.len == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const int rc = uv_try_write(reinterpret_cast<uv_stream_t*>(m_wss.m_socket), &buf, 1);
|
||||
|
||||
BIO_reset(m_wss.m_write);
|
||||
|
||||
if (static_cast<size_t>(rc) == buf.len) {
|
||||
return true;
|
||||
}
|
||||
|
||||
LOG_ERR("%s " RED("WSS write failed, rc = %d"), tag(), rc);
|
||||
WSSClose();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::DaemonClient::WSSRead(ssize_t nread, const uv_buf_t* read_buf)
|
||||
{
|
||||
if (nread <= 0) {
|
||||
LOG_ERR("%s " RED("WSS read failed, nread = %" PRId64), tag(), nread);
|
||||
WSSClose();
|
||||
return;
|
||||
}
|
||||
|
||||
BIO_write(m_wss.m_read, read_buf->base, static_cast<int>(nread));
|
||||
|
||||
if (!SSL_is_init_finished(m_wss.m_ssl)) {
|
||||
const int rc = SSL_connect(m_wss.m_ssl);
|
||||
|
||||
if ((rc < 0) && (SSL_get_error(m_wss.m_ssl, rc) == SSL_ERROR_WANT_READ)) {
|
||||
WSSWrite(nullptr, 0);
|
||||
}
|
||||
else if (rc == 1) {
|
||||
// login
|
||||
static constexpr char Base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
char key[25];
|
||||
std::random_device r;
|
||||
|
||||
for (int i = 0; i < 21; ++i) {
|
||||
key[i] = Base64[r() % 64];
|
||||
}
|
||||
|
||||
key[21] = Base64[0];
|
||||
key[22] = '=';
|
||||
key[23] = '=';
|
||||
key[24] = '\0';
|
||||
|
||||
const int n = snprintf(m_wss.m_buf, sizeof(m_wss.m_buf), kWSSLogin, m_pool.user().data(), m_pool.host().data(), key);
|
||||
if (0 <= n && n < static_cast<int>(sizeof(m_wss.m_buf))) {
|
||||
WSSWrite(m_wss.m_buf, n);
|
||||
}
|
||||
else {
|
||||
WSSClose();
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int n = 0;
|
||||
while ((n = SSL_read(m_wss.m_ssl, m_wss.m_buf, sizeof(m_wss.m_buf))) > 0) {
|
||||
m_wss.m_data.insert(m_wss.m_data.end(), m_wss.m_buf, m_wss.m_buf + n);
|
||||
|
||||
// Skip the first message (HTTP upgrade response)
|
||||
if (m_wss.m_handshake) {
|
||||
const size_t len = m_wss.m_data.size();
|
||||
if (len >= 4) {
|
||||
for (size_t k = 0; k <= len - 4; ++k) {
|
||||
if (memcmp(m_wss.m_data.data() + k, "\r\n\r\n", 4) == 0) {
|
||||
m_wss.m_handshake = false;
|
||||
m_wss.m_data.erase(m_wss.m_data.begin(), m_wss.m_data.begin() + k + 4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
const uint8_t* p0 = reinterpret_cast<uint8_t*>(m_wss.m_data.data());
|
||||
const uint8_t* p = p0;
|
||||
const uint8_t* e = p0 + m_wss.m_data.size();
|
||||
|
||||
if (e - p < static_cast<int>(sizeof(WSS::Header)))
|
||||
continue;
|
||||
|
||||
const WSS::Header* h = reinterpret_cast<const WSS::Header*>(p);
|
||||
p += sizeof(WSS::Header);
|
||||
|
||||
uint64_t len = h->payload_len;
|
||||
|
||||
if (len == 126) {
|
||||
if (e - p < static_cast<int>(sizeof(uint16_t))) {
|
||||
continue;
|
||||
}
|
||||
len = 0;
|
||||
for (size_t i = 0; i < sizeof(uint16_t); ++i, ++p) {
|
||||
len = (len << 8) | *p;
|
||||
}
|
||||
}
|
||||
else if (len == 127) {
|
||||
if (e - p < static_cast<int>(sizeof(uint64_t))) {
|
||||
continue;
|
||||
}
|
||||
len = 0;
|
||||
for (size_t i = 0; i < sizeof(uint64_t); ++i, ++p) {
|
||||
len = (len << 8) | *p;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t mask_key[4] = {};
|
||||
if (h->mask) {
|
||||
if (e - p < 4)
|
||||
continue;
|
||||
memcpy(mask_key, p, 4);
|
||||
p += 4;
|
||||
}
|
||||
|
||||
if (static_cast<uint64_t>(e - p) < len)
|
||||
continue;
|
||||
|
||||
for (uint64_t i = 0; i < len; ++i) {
|
||||
m_wss.m_message.push_back(p[i] ^ mask_key[i % 4]);
|
||||
}
|
||||
p += len;
|
||||
|
||||
m_wss.m_data.erase(m_wss.m_data.begin(), m_wss.m_data.begin() + (p - p0));
|
||||
|
||||
if (h->fin) {
|
||||
if (m_wss.m_message.back() == '\n') {
|
||||
m_wss.m_message.back() = '\0';
|
||||
}
|
||||
else {
|
||||
m_wss.m_message.push_back('\0');
|
||||
}
|
||||
WSSParse();
|
||||
m_wss.m_message.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::DaemonClient::WSSParse()
|
||||
{
|
||||
# ifdef APP_DEBUG
|
||||
LOG_DEBUG(CYAN("%s") BLACK_BOLD(" read ") CYAN_BOLD("%zu") BLACK_BOLD(" bytes") " %s", m_pool.url().data(), m_wss.m_message.size(), m_wss.m_message.data());
|
||||
# endif
|
||||
|
||||
using namespace rapidjson;
|
||||
|
||||
Document doc;
|
||||
if (doc.ParseInsitu(m_wss.m_message.data()).HasParseError() || !doc.IsObject()) {
|
||||
if (!isQuiet()) {
|
||||
LOG_ERR("%s " RED("JSON decode failed: ") RED_BOLD("\"%s\""), tag(), GetParseError_En(doc.GetParseError()));
|
||||
}
|
||||
|
||||
return retry();
|
||||
}
|
||||
|
||||
if (doc.HasMember(kLastError)) {
|
||||
String err = Json::getString(doc, kLastError, "");
|
||||
if (!err.isEmpty()) {
|
||||
LOG_ERR("%s " RED_BOLD("\"%s\""), tag(), err.data());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (doc.HasMember(kBlockhashingBlob)) {
|
||||
Job job(false, m_pool.algorithm(), String());
|
||||
|
||||
m_blockhashingblob = Json::getString(doc, kBlockhashingBlob, "");
|
||||
if (m_blockhashingblob.isEmpty()) {
|
||||
LOG_ERR("%s " RED_BOLD("blockhashing_blob is empty"), tag());
|
||||
return;
|
||||
}
|
||||
job.setBlob(m_blockhashingblob);
|
||||
memset(job.blob() + job.nonceOffset(), 0, job.nonceSize());
|
||||
|
||||
const uint64_t height = Json::getUint64(doc, kHeight);
|
||||
|
||||
job.setHeight(height);
|
||||
job.setDiff(Json::getUint64(doc, "difficultyuint64"));
|
||||
//job.setDiff(100000);
|
||||
|
||||
m_currentJobId = Json::getString(doc, "jobid");
|
||||
job.setId(m_currentJobId);
|
||||
|
||||
m_job = std::move(job);
|
||||
|
||||
if (m_state == ConnectingState) {
|
||||
setState(ConnectedState);
|
||||
}
|
||||
|
||||
const uint64_t blocks = Json::getUint64(doc, "blocks");
|
||||
const uint64_t miniblocks = Json::getUint64(doc, "miniblocks");
|
||||
|
||||
if ((blocks != m_wss.m_blocks) || (miniblocks != m_wss.m_miniblocks) || (height != m_wss.m_height)) {
|
||||
LOG_INFO("%s " GREEN_BOLD("%" PRIu64 " blocks, %" PRIu64 " mini blocks"), tag(), blocks, miniblocks);
|
||||
m_wss.m_blocks = blocks;
|
||||
m_wss.m_miniblocks = miniblocks;
|
||||
m_wss.m_height = height;
|
||||
}
|
||||
|
||||
m_listener->onJobReceived(this, m_job, doc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::DaemonClient::WSSClose(bool shutdown)
|
||||
{
|
||||
if (m_wss.m_socket && (uv_is_closing(reinterpret_cast<uv_handle_t*>(m_wss.m_socket)) == 0)) {
|
||||
uv_close(reinterpret_cast<uv_handle_t*>(m_wss.m_socket), shutdown ? onWSSShutdown : onWSSClose);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::DaemonClient::WSS::cleanup()
|
||||
{
|
||||
delete m_socket;
|
||||
m_socket = nullptr;
|
||||
|
||||
if (m_ctx) {
|
||||
SSL_CTX_free(m_ctx);
|
||||
m_ctx = nullptr;
|
||||
}
|
||||
if (m_ssl) {
|
||||
SSL_free(m_ssl);
|
||||
m_ssl = nullptr;
|
||||
}
|
||||
|
||||
m_read = nullptr;
|
||||
m_write = nullptr;
|
||||
m_handshake = true;
|
||||
m_blocks = 0;
|
||||
m_miniblocks = 0;
|
||||
m_height = 0;
|
||||
m_data.clear();
|
||||
m_message.clear();
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -39,6 +39,12 @@ using uv_handle_t = struct uv_handle_s;
|
|||
using uv_stream_t = struct uv_stream_s;
|
||||
using uv_tcp_t = struct uv_tcp_s;
|
||||
|
||||
#ifdef XMRIG_FEATURE_TLS
|
||||
using BIO = struct bio_st;
|
||||
using SSL = struct ssl_st;
|
||||
using SSL_CTX = struct ssl_ctx_st;
|
||||
#endif
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
@ -57,6 +63,7 @@ public:
|
|||
protected:
|
||||
bool disconnect() override;
|
||||
bool isTLS() const override;
|
||||
bool isWSS() const override;
|
||||
int64_t submit(const JobResult &result) override;
|
||||
void connect() override;
|
||||
void connect(const Pool &pool) override;
|
||||
|
@ -136,6 +143,45 @@ private:
|
|||
|
||||
std::vector<char> m_ZMQSendBuf;
|
||||
std::vector<char> m_ZMQRecvBuf;
|
||||
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
static void onWSSConnect(uv_connect_t* req, int status);
|
||||
static void onWSSRead(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf);
|
||||
static void onWSSClose(uv_handle_t* handle);
|
||||
static void onWSSShutdown(uv_handle_t* handle);
|
||||
|
||||
void WSSConnected();
|
||||
bool WSSWrite(const char* data, size_t size);
|
||||
void WSSRead(ssize_t nread, const uv_buf_t* buf);
|
||||
void WSSParse();
|
||||
bool WSSClose(bool shutdown = false);
|
||||
|
||||
struct WSS {
|
||||
struct Header
|
||||
{
|
||||
uint8_t opcode : 4;
|
||||
uint8_t reserved : 3;
|
||||
uint8_t fin : 1;
|
||||
uint8_t payload_len : 7;
|
||||
uint8_t mask : 1;
|
||||
};
|
||||
|
||||
uv_tcp_t* m_socket = nullptr;
|
||||
SSL_CTX* m_ctx = nullptr;
|
||||
BIO* m_read = nullptr;
|
||||
BIO* m_write = nullptr;
|
||||
SSL* m_ssl = nullptr;
|
||||
char m_buf[512] = {};
|
||||
bool m_handshake = true;
|
||||
uint64_t m_blocks = 0;
|
||||
uint64_t m_miniblocks = 0;
|
||||
uint64_t m_height = 0;
|
||||
std::vector<char> m_data;
|
||||
std::vector<char> m_message;
|
||||
|
||||
void cleanup();
|
||||
} m_wss;
|
||||
# endif
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -164,6 +164,18 @@ void xmrig::Job::setSigKey(const char *sig_key)
|
|||
}
|
||||
|
||||
|
||||
int32_t xmrig::Job::nonceOffset() const
|
||||
{
|
||||
auto f = algorithm().family();
|
||||
if (f == Algorithm::KAWPOW) return 32;
|
||||
if (f == Algorithm::GHOSTRIDER) return 76;
|
||||
|
||||
auto id = algorithm().id();
|
||||
if (id == Algorithm::ASTROBWT_DERO_2) return 44;
|
||||
|
||||
return 39;
|
||||
}
|
||||
|
||||
uint32_t xmrig::Job::getNumTransactions() const
|
||||
{
|
||||
if (!(m_algorithm.isCN() || m_algorithm.family() == Algorithm::RANDOM_X)) {
|
||||
|
|
|
@ -76,7 +76,7 @@ public:
|
|||
inline const String &poolWallet() const { return m_poolWallet; }
|
||||
inline const uint32_t *nonce() const { return reinterpret_cast<const uint32_t*>(m_blob + nonceOffset()); }
|
||||
inline const uint8_t *blob() const { return m_blob; }
|
||||
inline int32_t nonceOffset() const { auto f = algorithm().family(); return (f == Algorithm::KAWPOW) ? 32 : ((f == Algorithm::GHOSTRIDER) ? 76 : 39); }
|
||||
int32_t nonceOffset() const;
|
||||
inline size_t nonceSize() const { return (algorithm().family() == Algorithm::KAWPOW) ? 8 : 4; }
|
||||
inline size_t size() const { return m_size; }
|
||||
inline uint32_t *nonce() { return reinterpret_cast<uint32_t*>(m_blob + nonceOffset()); }
|
||||
|
|
|
@ -76,6 +76,7 @@ const char *Pool::kSelfSelect = "self-select";
|
|||
const char *Pool::kSOCKS5 = "socks5";
|
||||
const char *Pool::kSubmitToOrigin = "submit-to-origin";
|
||||
const char *Pool::kTls = "tls";
|
||||
const char *Pool::kWSS = "wss";
|
||||
const char *Pool::kUrl = "url";
|
||||
const char *Pool::kUser = "user";
|
||||
const char *Pool::kSpendSecretKey = "spend-secret-key";
|
||||
|
@ -93,7 +94,7 @@ xmrig::Pool::Pool(const char *url) :
|
|||
}
|
||||
|
||||
|
||||
xmrig::Pool::Pool(const char *host, uint16_t port, const char *user, const char *password, const char* spendSecretKey, int keepAlive, bool nicehash, bool tls, Mode mode) :
|
||||
xmrig::Pool::Pool(const char *host, uint16_t port, const char *user, const char *password, const char* spendSecretKey, int keepAlive, bool nicehash, bool tls, bool wss, Mode mode) :
|
||||
m_keepAlive(keepAlive),
|
||||
m_mode(mode),
|
||||
m_flags(1 << FLAG_ENABLED),
|
||||
|
@ -105,6 +106,7 @@ xmrig::Pool::Pool(const char *host, uint16_t port, const char *user, const char
|
|||
{
|
||||
m_flags.set(FLAG_NICEHASH, nicehash || strstr(host, kNicehashHost));
|
||||
m_flags.set(FLAG_TLS, tls);
|
||||
m_flags.set(FLAG_WSS, wss);
|
||||
}
|
||||
|
||||
|
||||
|
@ -132,6 +134,7 @@ xmrig::Pool::Pool(const rapidjson::Value &object) :
|
|||
m_flags.set(FLAG_ENABLED, Json::getBool(object, kEnabled, true));
|
||||
m_flags.set(FLAG_NICEHASH, Json::getBool(object, kNicehash) || m_url.host().contains(kNicehashHost));
|
||||
m_flags.set(FLAG_TLS, Json::getBool(object, kTls) || m_url.isTLS());
|
||||
m_flags.set(FLAG_WSS, Json::getBool(object, kWSS) || m_url.isWSS());
|
||||
|
||||
setKeepAlive(Json::getValue(object, kKeepalive));
|
||||
|
||||
|
@ -293,6 +296,7 @@ rapidjson::Value xmrig::Pool::toJSON(rapidjson::Document &doc) const
|
|||
|
||||
obj.AddMember(StringRef(kEnabled), m_flags.test(FLAG_ENABLED), allocator);
|
||||
obj.AddMember(StringRef(kTls), isTLS(), allocator);
|
||||
obj.AddMember(StringRef(kWSS), isWSS(), allocator);
|
||||
obj.AddMember(StringRef(kFingerprint), m_fingerprint.toJSON(), allocator);
|
||||
obj.AddMember(StringRef(kDaemon), m_mode == MODE_DAEMON, allocator);
|
||||
obj.AddMember(StringRef(kSOCKS5), m_proxy.toJSON(doc), allocator);
|
||||
|
|
|
@ -69,10 +69,12 @@ public:
|
|||
static const char *kSOCKS5;
|
||||
static const char *kSubmitToOrigin;
|
||||
static const char *kTls;
|
||||
static const char* kWSS;
|
||||
static const char *kUrl;
|
||||
static const char *kUser;
|
||||
static const char* kSpendSecretKey;
|
||||
static const char* kDaemonZMQPort;
|
||||
static const char* kDaemonWSSPort;
|
||||
static const char *kNicehashHost;
|
||||
|
||||
constexpr static int kKeepAliveTimeout = 60;
|
||||
|
@ -80,7 +82,7 @@ public:
|
|||
constexpr static uint64_t kDefaultPollInterval = 1000;
|
||||
|
||||
Pool() = default;
|
||||
Pool(const char *host, uint16_t port, const char *user, const char *password, const char* spendSecretKey, int keepAlive, bool nicehash, bool tls, Mode mode);
|
||||
Pool(const char *host, uint16_t port, const char *user, const char *password, const char* spendSecretKey, int keepAlive, bool nicehash, bool tls, bool wss, Mode mode);
|
||||
Pool(const char *url);
|
||||
Pool(const rapidjson::Value &object);
|
||||
|
||||
|
@ -93,6 +95,7 @@ public:
|
|||
|
||||
inline bool isNicehash() const { return m_flags.test(FLAG_NICEHASH); }
|
||||
inline bool isTLS() const { return m_flags.test(FLAG_TLS) || m_url.isTLS(); }
|
||||
inline bool isWSS() const { return m_flags.test(FLAG_WSS) || m_url.isWSS(); }
|
||||
inline bool isValid() const { return m_url.isValid(); }
|
||||
inline const Algorithm &algorithm() const { return m_algorithm; }
|
||||
inline const Coin &coin() const { return m_coin; }
|
||||
|
@ -135,6 +138,7 @@ private:
|
|||
FLAG_ENABLED,
|
||||
FLAG_NICEHASH,
|
||||
FLAG_TLS,
|
||||
FLAG_WSS,
|
||||
FLAG_MAX
|
||||
};
|
||||
|
||||
|
|
|
@ -49,6 +49,7 @@ protected:
|
|||
inline bool hasExtension(Extension extension) const noexcept override { return m_client->hasExtension(extension); }
|
||||
inline bool isEnabled() const override { return m_client->isEnabled(); }
|
||||
inline bool isTLS() const override { return m_client->isTLS(); }
|
||||
inline bool isWSS() const override { return m_client->isWSS(); }
|
||||
inline const char *mode() const override { return m_client->mode(); }
|
||||
inline const char *tag() const override { return m_client->tag(); }
|
||||
inline const char *tlsFingerprint() const override { return m_client->tlsFingerprint(); }
|
||||
|
|
|
@ -39,6 +39,7 @@ static const char kSOCKS5[] = "socks5://";
|
|||
#ifdef XMRIG_FEATURE_HTTP
|
||||
static const char kDaemonHttp[] = "daemon+http://";
|
||||
static const char kDaemonHttps[] = "daemon+https://";
|
||||
static const char kDaemonWss[] = "daemon+wss://";
|
||||
#endif
|
||||
|
||||
} // namespace xmrig
|
||||
|
@ -103,6 +104,11 @@ bool xmrig::Url::parse(const char *url)
|
|||
m_scheme = DAEMON;
|
||||
m_tls = false;
|
||||
}
|
||||
else if (strncasecmp(url, kDaemonWss, sizeof(kDaemonWss) - 1) == 0) {
|
||||
m_scheme = DAEMON;
|
||||
m_tls = true;
|
||||
m_wss = true;
|
||||
}
|
||||
# endif
|
||||
else {
|
||||
return false;
|
||||
|
|
|
@ -41,6 +41,7 @@ public:
|
|||
Url(const char *host, uint16_t port, bool tls = false, Scheme scheme = UNSPECIFIED);
|
||||
|
||||
inline bool isTLS() const { return m_tls; }
|
||||
inline bool isWSS() const { return m_wss; }
|
||||
inline bool isValid() const { return !m_host.isNull() && m_port > 0; }
|
||||
inline const String &host() const { return m_host; }
|
||||
inline const String &url() const { return m_url; }
|
||||
|
@ -57,6 +58,7 @@ protected:
|
|||
bool parseIPv6(const char *addr);
|
||||
|
||||
bool m_tls = false;
|
||||
bool m_wss = false;
|
||||
Scheme m_scheme = UNSPECIFIED;
|
||||
String m_host;
|
||||
String m_url;
|
||||
|
|
|
@ -41,6 +41,7 @@ public:
|
|||
inline bool hasExtension(Extension) const noexcept override { return false; }
|
||||
inline bool isEnabled() const override { return true; }
|
||||
inline bool isTLS() const override { return false; }
|
||||
inline bool isWSS() const override { return false; }
|
||||
inline const char *mode() const override { return "benchmark"; }
|
||||
inline const char *tlsFingerprint() const override { return nullptr; }
|
||||
inline const char *tlsVersion() const override { return nullptr; }
|
||||
|
|
|
@ -23,10 +23,12 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#define bswap_64(x) _byteswap_uint64(x)
|
||||
#define bswap_32(x) _byteswap_ulong(x)
|
||||
|
||||
#elif defined __GNUC__
|
||||
|
||||
#define bswap_64(x) __builtin_bswap64(x)
|
||||
#define bswap_32(x) __builtin_bswap32(x)
|
||||
|
||||
#else
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "base/crypto/sha3.h"
|
||||
#include "base/tools/bswap_64.h"
|
||||
#include "crypto/cn/CryptoNight.h"
|
||||
#include "crypto/astrobwt/sort_indices2.h"
|
||||
|
||||
|
||||
#include <limits>
|
||||
|
@ -433,6 +434,45 @@ bool xmrig::astrobwt::astrobwt_dero(const void* input_data, uint32_t input_size,
|
|||
}
|
||||
|
||||
|
||||
bool xmrig::astrobwt::astrobwt_dero_v2(const void* input_data, uint32_t input_size, void* scratchpad, uint8_t* output_hash)
|
||||
{
|
||||
constexpr size_t N = 9973;
|
||||
constexpr size_t STRIDE = 10240;
|
||||
|
||||
alignas(8) uint8_t key[32];
|
||||
uint8_t* scratchpad_ptr = (uint8_t*)(scratchpad) + 64;
|
||||
uint8_t* v = scratchpad_ptr;
|
||||
uint32_t* indices = (uint32_t*)(scratchpad_ptr + STRIDE);
|
||||
uint32_t* tmp_indices = (uint32_t*)(scratchpad_ptr + STRIDE * 5);
|
||||
|
||||
#ifdef ASTROBWT_AVX2
|
||||
if (hasAVX2) {
|
||||
SHA3_256_AVX2_ASM(input_data, input_size, key);
|
||||
Salsa20_XORKeyStream_AVX256(key, v, N);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
sha3_HashBuffer(256, SHA3_FLAGS_NONE, input_data, input_size, key, sizeof(key));
|
||||
Salsa20_XORKeyStream(key, v, N);
|
||||
}
|
||||
|
||||
sort_indices_astrobwt_v2(N, v, indices, tmp_indices);
|
||||
|
||||
#ifdef ASTROBWT_AVX2
|
||||
if (hasAVX2) {
|
||||
SHA3_256_AVX2_ASM(indices, N * 2, output_hash);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
sha3_HashBuffer(256, SHA3_FLAGS_NONE, indices, N * 2, output_hash, 32);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::astrobwt::init()
|
||||
{
|
||||
if (!astrobwtInitialized) {
|
||||
|
@ -450,3 +490,10 @@ void xmrig::astrobwt::single_hash<xmrig::Algorithm::ASTROBWT_DERO>(const uint8_t
|
|||
{
|
||||
astrobwt_dero(input, static_cast<uint32_t>(size), ctx[0]->memory, output, std::numeric_limits<int>::max(), true);
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
void xmrig::astrobwt::single_hash<xmrig::Algorithm::ASTROBWT_DERO_2>(const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx** ctx, uint64_t)
|
||||
{
|
||||
astrobwt_dero_v2(input, static_cast<uint32_t>(size), ctx[0]->memory, output);
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ namespace xmrig {
|
|||
namespace astrobwt {
|
||||
|
||||
bool astrobwt_dero(const void* input_data, uint32_t input_size, void* scratchpad, uint8_t* output_hash, int stage2_max_size, bool avx2);
|
||||
bool astrobwt_dero_v2(const void* input_data, uint32_t input_size, void* scratchpad, uint8_t* output_hash);
|
||||
void init();
|
||||
|
||||
template<Algorithm::Id ALGO>
|
||||
|
@ -40,5 +41,7 @@ void single_hash(const uint8_t* input, size_t size, uint8_t* output, cryptonight
|
|||
template<>
|
||||
void single_hash<Algorithm::ASTROBWT_DERO>(const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx** ctx, uint64_t);
|
||||
|
||||
template<>
|
||||
void single_hash<Algorithm::ASTROBWT_DERO_2>(const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx** ctx, uint64_t);
|
||||
|
||||
}} // namespace xmrig::astrobwt
|
||||
|
|
208
src/crypto/astrobwt/sort_indices2.cpp
Normal file
208
src/crypto/astrobwt/sort_indices2.cpp
Normal file
|
@ -0,0 +1,208 @@
|
|||
/* XMRig
|
||||
* Copyright (c) 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright (c) 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright (c) 2000 Transmeta Corporation <https://github.com/intel/msr-tools>
|
||||
* Copyright (c) 2004-2008 H. Peter Anvin <https://github.com/intel/msr-tools>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 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 "crypto/astrobwt/sort_indices2.h"
|
||||
#include "base/tools/bswap_64.h"
|
||||
#include <cstring>
|
||||
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define NOINLINE __attribute__((noinline))
|
||||
#define RESTRICT __restrict__
|
||||
#elif _MSC_VER
|
||||
#define NOINLINE __declspec(noinline)
|
||||
#define RESTRICT __restrict
|
||||
#else
|
||||
#define NOINLINE
|
||||
#define RESTRICT
|
||||
#endif
|
||||
|
||||
|
||||
#if __has_cpp_attribute(unlikely)
|
||||
#define UNLIKELY(X) (X) [[unlikely]]
|
||||
#elif defined __GNUC__
|
||||
#define UNLIKELY(X) (__builtin_expect((X), 0))
|
||||
#else
|
||||
#define UNLIKELY(X) (X)
|
||||
#endif
|
||||
|
||||
|
||||
static NOINLINE void fix(const uint8_t* RESTRICT v, uint32_t* RESTRICT indices, int32_t i)
|
||||
{
|
||||
uint32_t prev_t = indices[i - 1];
|
||||
uint32_t t = indices[i];
|
||||
|
||||
const uint32_t data_a = bswap_32(*(const uint32_t*)(v + (t & 0xFFFF) + 2));
|
||||
if (data_a < bswap_32(*(const uint32_t*)(v + (prev_t & 0xFFFF) + 2)))
|
||||
{
|
||||
const uint32_t t2 = prev_t;
|
||||
int32_t j = i - 1;
|
||||
do
|
||||
{
|
||||
indices[j + 1] = prev_t;
|
||||
--j;
|
||||
|
||||
if (j < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
prev_t = indices[j];
|
||||
} while (((t ^ prev_t) <= 0xFFFF) && (data_a < bswap_32(*(const uint32_t*)(v + (prev_t & 0xFFFF) + 2))));
|
||||
indices[j + 1] = t;
|
||||
t = t2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static NOINLINE void sort_indices(uint32_t N, const uint8_t* RESTRICT v, uint32_t* RESTRICT indices, uint32_t* RESTRICT tmp_indices)
|
||||
{
|
||||
uint8_t byte_counters[2][256] = {};
|
||||
uint32_t counters[2][256];
|
||||
|
||||
{
|
||||
#define ITER(X) ++byte_counters[1][v[i + X]];
|
||||
|
||||
enum { unroll = 12 };
|
||||
|
||||
uint32_t i = 0;
|
||||
const uint32_t n = N - (unroll - 1);
|
||||
for (; i < n; i += unroll) {
|
||||
ITER(0); ITER(1); ITER(2); ITER(3); ITER(4); ITER(5); ITER(6); ITER(7); ITER(8); ITER(9); ITER(10); ITER(11);
|
||||
}
|
||||
for (; i < N; ++i) {
|
||||
ITER(0);
|
||||
}
|
||||
memcpy(&byte_counters[0], &byte_counters[1], 256);
|
||||
--byte_counters[0][v[0]];
|
||||
|
||||
#undef ITER
|
||||
}
|
||||
|
||||
{
|
||||
uint32_t c0 = byte_counters[0][0];
|
||||
uint32_t c1 = byte_counters[1][0] - 1;
|
||||
counters[0][0] = c0;
|
||||
counters[1][0] = c1;
|
||||
uint8_t* src = &byte_counters[0][0] + 1;
|
||||
uint32_t* dst = &counters[0][0] + 1;
|
||||
const uint8_t* const e = &byte_counters[0][0] + 256;
|
||||
do {
|
||||
c0 += src[0];
|
||||
c1 += src[256];
|
||||
dst[0] = c0;
|
||||
dst[256] = c1;
|
||||
++src;
|
||||
++dst;
|
||||
} while (src < e);
|
||||
}
|
||||
|
||||
{
|
||||
#define ITER(X) \
|
||||
do { \
|
||||
const uint32_t byte0 = v[i - X + 0]; \
|
||||
const uint32_t byte1 = v[i - X + 1]; \
|
||||
tmp_indices[counters[0][byte1]--] = (byte0 << 24) | (byte1 << 16) | (i - X); \
|
||||
} while (0)
|
||||
|
||||
enum { unroll = 8 };
|
||||
|
||||
uint32_t i = N;
|
||||
for (; i >= unroll; i -= unroll) {
|
||||
ITER(1); ITER(2); ITER(3); ITER(4); ITER(5); ITER(6); ITER(7); ITER(8);
|
||||
}
|
||||
for (; i > 0; --i) {
|
||||
ITER(1);
|
||||
}
|
||||
|
||||
#undef ITER
|
||||
}
|
||||
|
||||
{
|
||||
#define ITER(X) \
|
||||
do { \
|
||||
const uint32_t data = tmp_indices[i - X]; \
|
||||
indices[counters[1][data >> 24]--] = data; \
|
||||
} while (0)
|
||||
|
||||
enum { unroll = 8 };
|
||||
|
||||
uint32_t i = N;
|
||||
for (; i >= unroll; i -= unroll) {
|
||||
ITER(1); ITER(2); ITER(3); ITER(4); ITER(5); ITER(6); ITER(7); ITER(8);
|
||||
}
|
||||
for (; i > 0; --i) {
|
||||
ITER(1);
|
||||
}
|
||||
|
||||
#undef ITER
|
||||
}
|
||||
|
||||
{
|
||||
#define ITER(X) do { if UNLIKELY(a[X * 2] == a[(X + 1) * 2]) fix(v, indices, i + X); } while (0)
|
||||
|
||||
enum { unroll = 16 };
|
||||
|
||||
uint32_t i = 1;
|
||||
const uint32_t n = N - (unroll - 1);
|
||||
const uint16_t* a = ((const uint16_t*)indices) + 1;
|
||||
|
||||
for (; i < n; i += unroll, a += unroll * 2) {
|
||||
ITER(0); ITER(1); ITER(2); ITER(3); ITER(4); ITER(5); ITER(6); ITER(7);
|
||||
ITER(8); ITER(9); ITER(10); ITER(11); ITER(12); ITER(13); ITER(14); ITER(15);
|
||||
}
|
||||
for (; i < N; ++i, a += 2) {
|
||||
ITER(0);
|
||||
}
|
||||
|
||||
#undef ITER
|
||||
}
|
||||
|
||||
{
|
||||
#define ITER(X) a[X] = b[X * 2];
|
||||
|
||||
enum { unroll = 32 };
|
||||
|
||||
uint16_t* a = (uint16_t*)indices;
|
||||
uint16_t* b = (uint16_t*)indices;
|
||||
uint16_t* e = ((uint16_t*)indices) + (N - (unroll - 1));
|
||||
|
||||
for (; a < e; a += unroll, b += unroll * 2) {
|
||||
ITER(0); ITER(1); ITER(2); ITER(3); ITER(4); ITER(5); ITER(6); ITER(7);
|
||||
ITER(8); ITER(9); ITER(10); ITER(11); ITER(12); ITER(13); ITER(14); ITER(15);
|
||||
ITER(16); ITER(17); ITER(18); ITER(19); ITER(20); ITER(21); ITER(22); ITER(23);
|
||||
ITER(24); ITER(25); ITER(26); ITER(27); ITER(28); ITER(29); ITER(30); ITER(31);
|
||||
}
|
||||
|
||||
e = ((uint16_t*)indices) + N;
|
||||
for (; a < e; ++a, b += 2) {
|
||||
ITER(0);
|
||||
}
|
||||
|
||||
#undef ITER
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void sort_indices_astrobwt_v2(uint32_t N, const uint8_t* v, uint32_t* indices, uint32_t* tmp_indices)
|
||||
{
|
||||
sort_indices(N, v, indices, tmp_indices);
|
||||
}
|
26
src/crypto/astrobwt/sort_indices2.h
Normal file
26
src/crypto/astrobwt/sort_indices2.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
/* XMRig
|
||||
* Copyright (c) 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright (c) 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright (c) 2000 Transmeta Corporation <https://github.com/intel/msr-tools>
|
||||
* Copyright (c) 2004-2008 H. Peter Anvin <https://github.com/intel/msr-tools>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 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 <stdint.h>
|
||||
|
||||
|
||||
void sort_indices_astrobwt_v2(uint32_t N, const uint8_t* v, uint32_t* indices, uint32_t* tmp_indices);
|
|
@ -379,6 +379,10 @@ xmrig::CnHash::CnHash()
|
|||
m_map[Algorithm::ASTROBWT_DERO] = new cn_hash_fun_array{};
|
||||
m_map[Algorithm::ASTROBWT_DERO]->data[AV_SINGLE][Assembly::NONE] = astrobwt::single_hash<Algorithm::ASTROBWT_DERO>;
|
||||
m_map[Algorithm::ASTROBWT_DERO]->data[AV_SINGLE_SOFT][Assembly::NONE] = astrobwt::single_hash<Algorithm::ASTROBWT_DERO>;
|
||||
|
||||
m_map[Algorithm::ASTROBWT_DERO_2] = new cn_hash_fun_array{};
|
||||
m_map[Algorithm::ASTROBWT_DERO_2]->data[AV_SINGLE][Assembly::NONE] = astrobwt::single_hash<Algorithm::ASTROBWT_DERO_2>;
|
||||
m_map[Algorithm::ASTROBWT_DERO_2]->data[AV_SINGLE_SOFT][Assembly::NONE] = astrobwt::single_hash<Algorithm::ASTROBWT_DERO_2>;
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_ALGO_GHOSTRIDER
|
||||
|
|
|
@ -447,6 +447,19 @@ const static uint8_t astrobwt_dero_test_out[256] = {
|
|||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
// "astrobwt/v2"
|
||||
const static uint8_t astrobwt_dero_2_test_out[256] = {
|
||||
0x48, 0x9E, 0xD2, 0x66, 0x14, 0x27, 0x98, 0x65, 0x03, 0xFB, 0x87, 0x25, 0xE1, 0xD3, 0x98, 0xDA,
|
||||
0x27, 0xEE, 0x25, 0x3D, 0xB4, 0x37, 0x87, 0x98, 0xBF, 0x5A, 0x5C, 0x94, 0xEE, 0x0C, 0xE2, 0x2A,
|
||||
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, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -773,6 +773,11 @@ void hash_octa(const uint8_t* data, size_t size, uint8_t* output, cryptonight_ct
|
|||
{
|
||||
constexpr uint32_t N = 8;
|
||||
|
||||
uint8_t* ctx_memory[N];
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
ctx_memory[i] = ctx[i]->memory;
|
||||
}
|
||||
|
||||
// PrevBlockHash (GhostRider's seed) is stored in bytes [4; 36)
|
||||
const uint8_t* seed = data + 4;
|
||||
|
||||
|
@ -800,30 +805,50 @@ void hash_octa(const uint8_t* data, size_t size, uint8_t* output, cryptonight_ct
|
|||
|
||||
const CnHash::AlgoVariant* av = Cpu::info()->hasAES() ? av_hw_aes : av_soft_aes;
|
||||
|
||||
const cn_hash_fun f[3] = {
|
||||
CnHash::fn(cn_hash[cn_indices[0]], av[step[cn_indices[0]]], Assembly::AUTO),
|
||||
CnHash::fn(cn_hash[cn_indices[1]], av[step[cn_indices[1]]], Assembly::AUTO),
|
||||
CnHash::fn(cn_hash[cn_indices[2]], av[step[cn_indices[2]]], Assembly::AUTO),
|
||||
};
|
||||
|
||||
uint8_t tmp[64 * N];
|
||||
|
||||
for (uint64_t part = 0; part < 3; ++part) {
|
||||
for (uint64_t i = 0; i < 5; ++i) {
|
||||
for (uint64_t j = 0; j < N; ++j) {
|
||||
for (size_t part = 0; part < 3; ++part) {
|
||||
|
||||
// Allocate scratchpads
|
||||
{
|
||||
uint8_t* p = ctx_memory[0];
|
||||
|
||||
for (size_t i = 0, k = 0; i < N; ++i) {
|
||||
if ((i % step[cn_indices[part]]) == 0) {
|
||||
k = 0;
|
||||
p = ctx_memory[0];
|
||||
}
|
||||
else if (p - ctx_memory[k] >= (1 << 21)) {
|
||||
++k;
|
||||
p = ctx_memory[k];
|
||||
}
|
||||
ctx[i]->memory = p;
|
||||
p += cn_sizes[cn_indices[part]];
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 5; ++i) {
|
||||
for (size_t j = 0; j < N; ++j) {
|
||||
core_hash[core_indices[part * 5 + i]](data + j * size, size, tmp + j * 64);
|
||||
}
|
||||
data = tmp;
|
||||
size = 64;
|
||||
}
|
||||
|
||||
auto f = CnHash::fn(cn_hash[cn_indices[part]], av[step[cn_indices[part]]], Assembly::AUTO);
|
||||
for (size_t j = 0; j < N; j += step[cn_indices[part]]) {
|
||||
f(tmp + j * 64, 64, output + j * 32, ctx, 0);
|
||||
}
|
||||
for (uint64_t j = 0, k = step[cn_indices[part]]; j < N; j += k) {
|
||||
f[part](tmp + j * 64, 64, output + j * 32, ctx, 0);
|
||||
}
|
||||
for (uint64_t j = 0; j < N; ++j) {
|
||||
|
||||
for (size_t j = 0; j < N; ++j) {
|
||||
memcpy(tmp + j * 64, output + j * 32, 32);
|
||||
memset(tmp + j * 64 + 32, 0, 32);
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
ctx[i]->memory = ctx_memory[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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-2022 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2022 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
|
||||
|
@ -70,9 +70,9 @@ xmrig::DonateStrategy::DonateStrategy(Controller *controller, IStrategyListener
|
|||
# endif
|
||||
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
m_pools.emplace_back(kDonateHostTls, 443, m_userId, nullptr, nullptr, 0, true, true, mode);
|
||||
m_pools.emplace_back(kDonateHostTls, 443, m_userId, nullptr, nullptr, 0, true, true, false, mode);
|
||||
# endif
|
||||
m_pools.emplace_back(kDonateHost, 3333, m_userId, nullptr, nullptr, 0, true, false, mode);
|
||||
m_pools.emplace_back(kDonateHost, 3333, m_userId, nullptr, nullptr, 0, true, false, false, mode);
|
||||
|
||||
if (m_pools.size() > 1) {
|
||||
m_strategy = new FailoverStrategy(m_pools, 10, 2, this, true);
|
||||
|
@ -106,6 +106,12 @@ int64_t xmrig::DonateStrategy::submit(const JobResult &result)
|
|||
|
||||
void xmrig::DonateStrategy::connect()
|
||||
{
|
||||
# ifdef XMRIG_ALGO_ASTROBWT
|
||||
if (m_algorithm == Algorithm::ASTROBWT_DERO_2) {
|
||||
return;
|
||||
}
|
||||
# endif
|
||||
|
||||
m_proxy = createProxy();
|
||||
if (m_proxy) {
|
||||
m_proxy->connect();
|
||||
|
@ -252,7 +258,7 @@ xmrig::IClient *xmrig::DonateStrategy::createProxy()
|
|||
const IClient *client = strategy->client();
|
||||
m_tls = client->hasExtension(IClient::EXT_TLS);
|
||||
|
||||
Pool pool(client->pool().proxy().isValid() ? client->pool().host() : client->ip(), client->pool().port(), m_userId, client->pool().password(), client->pool().spendSecretKey(), 0, true, client->isTLS(), Pool::MODE_POOL);
|
||||
Pool pool(client->pool().proxy().isValid() ? client->pool().host() : client->ip(), client->pool().port(), m_userId, client->pool().password(), client->pool().spendSecretKey(), 0, true, client->isTLS(), client->isWSS(), Pool::MODE_POOL);
|
||||
pool.setAlgo(client->pool().algorithm());
|
||||
pool.setProxy(client->pool().proxy());
|
||||
|
||||
|
|
|
@ -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-2022 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2022 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
|
||||
|
|
|
@ -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-2022 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2022 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,15 +22,15 @@
|
|||
#define APP_ID "xmrig"
|
||||
#define APP_NAME "XMRig"
|
||||
#define APP_DESC "XMRig miner"
|
||||
#define APP_VERSION "6.16.4"
|
||||
#define APP_VERSION "6.17.0-dev"
|
||||
#define APP_DOMAIN "xmrig.com"
|
||||
#define APP_SITE "www.xmrig.com"
|
||||
#define APP_COPYRIGHT "Copyright (C) 2016-2021 xmrig.com"
|
||||
#define APP_COPYRIGHT "Copyright (C) 2016-2022 xmrig.com"
|
||||
#define APP_KIND "miner"
|
||||
|
||||
#define APP_VER_MAJOR 6
|
||||
#define APP_VER_MINOR 16
|
||||
#define APP_VER_PATCH 4
|
||||
#define APP_VER_MINOR 17
|
||||
#define APP_VER_PATCH 0
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# if (_MSC_VER >= 1930)
|
||||
|
|
Loading…
Reference in a new issue