From da9585ed111b3aa9e7b918b3761c78472adfb4f7 Mon Sep 17 00:00:00 2001 From: Rong Ma Date: Fri, 15 Aug 2025 10:15:56 +0100 Subject: [PATCH] remove qat/iaa/hbm --- .../CelebornPartitionWriterJniWrapper.java | 1 - ...VeloxCelebornColumnarBatchSerializer.scala | 3 - .../VeloxCelebornColumnarShuffleWriter.scala | 1 - .../UnifflePartitionWriterJniWrapper.java | 1 - .../VeloxUniffleColumnarShuffleWriter.java | 6 - .../vectorized/ColumnarBatchSerializer.scala | 3 - .../spark/shuffle/ColumnarShuffleWriter.scala | 1 - .../tests/json/gtest_local_engine_config.json | 1 - cpp/CMake/BuildQATZstd.cmake | 103 --- cpp/CMake/BuildQATzip.cmake | 126 ---- cpp/CMake/BuildQpl.cmake | 60 -- cpp/CMakeLists.txt | 11 - cpp/core/CMakeLists.txt | 23 - cpp/core/config/GlutenConfig.h | 3 - cpp/core/jni/JniCommon.h | 14 - cpp/core/jni/JniWrapper.cc | 7 +- cpp/core/memory/HbwAllocator.cc | 92 --- cpp/core/memory/HbwAllocator.h | 48 -- cpp/core/memory/MemoryAllocator.cc | 5 - cpp/core/shuffle/Options.h | 1 - cpp/core/tests/CMakeLists.txt | 4 - cpp/core/tests/HbwAllocatorTest.cc | 94 --- cpp/core/utils/Compression.cc | 51 +- cpp/core/utils/Compression.h | 5 +- cpp/core/utils/qat/QatCodec.cc | 304 --------- cpp/core/utils/qat/QatCodec.h | 39 -- cpp/core/utils/qpl/QplCodec.cc | 255 -------- cpp/core/utils/qpl/QplCodec.h | 35 - cpp/core/utils/qpl/QplJobPool.cc | 122 ---- cpp/core/utils/qpl/QplJobPool.h | 85 --- cpp/velox/benchmarks/GenericBenchmark.cc | 21 +- cpp/velox/compute/VeloxBackend.cc | 6 - cpp/velox/compute/VeloxRuntime.cc | 2 +- cpp/velox/jni/VeloxJniWrapper.cc | 6 +- cpp/velox/memory/VeloxMemoryManager.h | 4 - cpp/velox/tests/VeloxShuffleWriterTest.cc | 63 +- dev/__pycache__/util.cpython-313.pyc | Bin 0 -> 3791 bytes dev/builddeps-veloxbe.sh | 18 - dev/setup-qat-ubuntu.sh | 59 -- docs/Configuration.md | 3 +- docs/get-started/Velox.md | 5 - docs/get-started/VeloxHBM.md | 30 - docs/get-started/VeloxIAA.md | 75 --- docs/get-started/VeloxQAT.md | 155 ----- .../LocalPartitionWriterJniWrapper.java | 1 - .../vectorized/ShuffleReaderJniWrapper.java | 1 - .../apache/gluten/config/GlutenConfig.scala | 31 +- .../spark/shuffle/GlutenShuffleUtils.scala | 14 +- .../benchmark_velox/params.yaml.template | 2 - .../benchmark_velox/sample/tpch_q1.html | 610 ++++++++++++++---- .../benchmark_velox/tpc_workload.ipynb | 3 - 51 files changed, 546 insertions(+), 2067 deletions(-) delete mode 100644 cpp/CMake/BuildQATZstd.cmake delete mode 100644 cpp/CMake/BuildQATzip.cmake delete mode 100644 cpp/CMake/BuildQpl.cmake delete mode 100644 cpp/core/memory/HbwAllocator.cc delete mode 100644 cpp/core/memory/HbwAllocator.h delete mode 100644 cpp/core/tests/HbwAllocatorTest.cc delete mode 100644 cpp/core/utils/qat/QatCodec.cc delete mode 100644 cpp/core/utils/qat/QatCodec.h delete mode 100644 cpp/core/utils/qpl/QplCodec.cc delete mode 100644 cpp/core/utils/qpl/QplCodec.h delete mode 100644 cpp/core/utils/qpl/QplJobPool.cc delete mode 100644 cpp/core/utils/qpl/QplJobPool.h create mode 100644 dev/__pycache__/util.cpython-313.pyc delete mode 100755 dev/setup-qat-ubuntu.sh delete mode 100644 docs/get-started/VeloxHBM.md delete mode 100644 docs/get-started/VeloxIAA.md delete mode 100644 docs/get-started/VeloxQAT.md diff --git a/backends-velox/src-celeborn/main/java/org/apache/gluten/vectorized/CelebornPartitionWriterJniWrapper.java b/backends-velox/src-celeborn/main/java/org/apache/gluten/vectorized/CelebornPartitionWriterJniWrapper.java index 7cbfe6895560..0acaa12006f0 100644 --- a/backends-velox/src-celeborn/main/java/org/apache/gluten/vectorized/CelebornPartitionWriterJniWrapper.java +++ b/backends-velox/src-celeborn/main/java/org/apache/gluten/vectorized/CelebornPartitionWriterJniWrapper.java @@ -38,7 +38,6 @@ public long rtHandle() { public native long createPartitionWriter( int numPartitions, String codec, - String codecBackend, int compressionLevel, int compressionBufferSize, int pushBufferMaxSize, diff --git a/backends-velox/src-celeborn/main/scala/org/apache/spark/shuffle/VeloxCelebornColumnarBatchSerializer.scala b/backends-velox/src-celeborn/main/scala/org/apache/spark/shuffle/VeloxCelebornColumnarBatchSerializer.scala index 0869ad3c30c8..4773bd9aa764 100644 --- a/backends-velox/src-celeborn/main/scala/org/apache/spark/shuffle/VeloxCelebornColumnarBatchSerializer.scala +++ b/backends-velox/src-celeborn/main/scala/org/apache/spark/shuffle/VeloxCelebornColumnarBatchSerializer.scala @@ -89,8 +89,6 @@ private class CelebornColumnarBatchSerializerInstance( } else { null // uncompressed } - val compressionCodecBackend = - GlutenConfig.get.columnarShuffleCodecBackend.orNull val jniWrapper = ShuffleReaderJniWrapper.create(runtime) val batchSize = GlutenConfig.get.maxBatchSize val readerBufferSize = GlutenConfig.get.columnarShuffleReaderBufferSize @@ -99,7 +97,6 @@ private class CelebornColumnarBatchSerializerInstance( .make( cSchema.memoryAddress(), compressionCodec, - compressionCodecBackend, batchSize, readerBufferSize, deserializerBufferSize, diff --git a/backends-velox/src-celeborn/main/scala/org/apache/spark/shuffle/VeloxCelebornColumnarShuffleWriter.scala b/backends-velox/src-celeborn/main/scala/org/apache/spark/shuffle/VeloxCelebornColumnarShuffleWriter.scala index d2c27e960c84..067ac5ce9e3d 100644 --- a/backends-velox/src-celeborn/main/scala/org/apache/spark/shuffle/VeloxCelebornColumnarShuffleWriter.scala +++ b/backends-velox/src-celeborn/main/scala/org/apache/spark/shuffle/VeloxCelebornColumnarShuffleWriter.scala @@ -133,7 +133,6 @@ class VeloxCelebornColumnarShuffleWriter[K, V]( val partitionWriterHandle = partitionWriterJniWrapper.createPartitionWriter( numPartitions, compressionCodec.orNull, - GlutenConfig.get.columnarShuffleCodecBackend.orNull, compressionLevel, compressionBufferSize, clientPushBufferMaxSize, diff --git a/backends-velox/src-uniffle/main/java/org/apache/gluten/vectorized/UnifflePartitionWriterJniWrapper.java b/backends-velox/src-uniffle/main/java/org/apache/gluten/vectorized/UnifflePartitionWriterJniWrapper.java index cf3ee9c6648b..5e0c549a2543 100644 --- a/backends-velox/src-uniffle/main/java/org/apache/gluten/vectorized/UnifflePartitionWriterJniWrapper.java +++ b/backends-velox/src-uniffle/main/java/org/apache/gluten/vectorized/UnifflePartitionWriterJniWrapper.java @@ -38,7 +38,6 @@ public long rtHandle() { public native long createPartitionWriter( int numPartitions, String codec, - String codecBackend, int compressionLevel, int compressionBufferSize, int pushBufferMaxSize, diff --git a/backends-velox/src-uniffle/main/java/org/apache/spark/shuffle/writer/VeloxUniffleColumnarShuffleWriter.java b/backends-velox/src-uniffle/main/java/org/apache/spark/shuffle/writer/VeloxUniffleColumnarShuffleWriter.java index 3240a500642c..225ac184fece 100644 --- a/backends-velox/src-uniffle/main/java/org/apache/spark/shuffle/writer/VeloxUniffleColumnarShuffleWriter.java +++ b/backends-velox/src-uniffle/main/java/org/apache/spark/shuffle/writer/VeloxUniffleColumnarShuffleWriter.java @@ -66,7 +66,6 @@ public class VeloxUniffleColumnarShuffleWriter extends RssShuffleWriter codecBackend = GlutenConfig.get().columnarShuffleCodecBackend(); - if (codecBackend.isDefined()) { - this.codecBackend = codecBackend.get(); - } } } @@ -156,7 +151,6 @@ protected void writeImpl(Iterator> records) { partitionWriterJniWrapper.createPartitionWriter( numPartitions, compressionCodec, - codecBackend, compressionLevel, compressionBufferSize, bufferSize, diff --git a/backends-velox/src/main/scala/org/apache/gluten/vectorized/ColumnarBatchSerializer.scala b/backends-velox/src/main/scala/org/apache/gluten/vectorized/ColumnarBatchSerializer.scala index 53354f432bfc..e2378ffedc66 100644 --- a/backends-velox/src/main/scala/org/apache/gluten/vectorized/ColumnarBatchSerializer.scala +++ b/backends-velox/src/main/scala/org/apache/gluten/vectorized/ColumnarBatchSerializer.scala @@ -93,8 +93,6 @@ private class ColumnarBatchSerializerInstance( } else { null // uncompressed } - val compressionCodecBackend = - GlutenConfig.get.columnarShuffleCodecBackend.orNull val batchSize = GlutenConfig.get.maxBatchSize val readerBufferSize = GlutenConfig.get.columnarShuffleReaderBufferSize val deserializerBufferSize = GlutenConfig.get.columnarSortShuffleDeserializerBufferSize @@ -103,7 +101,6 @@ private class ColumnarBatchSerializerInstance( val shuffleReaderHandle = jniWrapper.make( cSchema.memoryAddress(), compressionCodec, - compressionCodecBackend, batchSize, readerBufferSize, deserializerBufferSize, diff --git a/backends-velox/src/main/scala/org/apache/spark/shuffle/ColumnarShuffleWriter.scala b/backends-velox/src/main/scala/org/apache/spark/shuffle/ColumnarShuffleWriter.scala index 94735e5b70a0..b236711590ef 100644 --- a/backends-velox/src/main/scala/org/apache/spark/shuffle/ColumnarShuffleWriter.scala +++ b/backends-velox/src/main/scala/org/apache/spark/shuffle/ColumnarShuffleWriter.scala @@ -146,7 +146,6 @@ class ColumnarShuffleWriter[K, V]( val partitionWriterHandle = partitionWriterJniWrapper.createPartitionWriter( numPartitions, compressionCodec.orNull, - GlutenConfig.get.columnarShuffleCodecBackend.orNull, compressionLevel, compressionBufferSize, GlutenConfig.get.columnarShuffleCompressionThreshold, diff --git a/cpp-ch/local-engine/tests/json/gtest_local_engine_config.json b/cpp-ch/local-engine/tests/json/gtest_local_engine_config.json index 1bb7562e5372..03be6e9b5579 100644 --- a/cpp-ch/local-engine/tests/json/gtest_local_engine_config.json +++ b/cpp-ch/local-engine/tests/json/gtest_local_engine_config.json @@ -40,7 +40,6 @@ "spark.gluten.sql.columnar.backend.ch.runtime_config.storage_configuration.disks.hdfs.endpoint": "hdfs://127.0.0.1:8020/", "spark.gluten.sql.columnar.backend.ch.runtime_config.storage_configuration.disks.hdfs_cache.max_size": "10Gi", "spark.gluten.sql.columnar.backend.ch.runtime_config.storage_configuration.disks.hdfs.metadata_path": "/tmp/metadata/hdfs/3.5/", - "spark.gluten.sql.columnar.shuffle.codecBackend": "", "spark.gluten.sql.columnar.backend.ch.runtime_config.hdfs.input_write_timeout": "180000", "spark.gluten.memory.task.offHeap.size.in.bytes": "10737418240", "spark.gluten.sql.columnar.backend.ch.runtime_config.storage_configuration.policies.__hdfs_main.volumes.main.disk": "hdfs_cache", diff --git a/cpp/CMake/BuildQATZstd.cmake b/cpp/CMake/BuildQATZstd.cmake deleted file mode 100644 index f79e9ea58fcc..000000000000 --- a/cpp/CMake/BuildQATZstd.cmake +++ /dev/null @@ -1,103 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -include(ExternalProject) - -if("${MAKE}" STREQUAL "") - if(NOT MSVC) - find_program(MAKE make) - endif() -endif() - -macro(build_qatzstd) - # Find ZSTD - include(FindZstd) - - message(STATUS "Building QAT-ZSTD from source") - set(QATZSTD_SOURCE_URL "https://github.com/marin-ma/QAT-ZSTD-Plugin.git") - set(QATZSTD_SOURCE_BRANCH "fix-duplicate-symbol") - set(QATZSTD_LIB_NAME "qatseqprod") - - set(QATZSTD_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/qatzstd_ep-install") - set(QATZSTD_SOURCE_DIR "${QATZSTD_PREFIX}/src/qatzstd_ep") - set(QATZSTD_INCLUDE_DIR "${QATZSTD_SOURCE_DIR}/src") - set(QATZSTD_STATIC_LIB_NAME - "${CMAKE_STATIC_LIBRARY_PREFIX}${QATZSTD_LIB_NAME}${CMAKE_STATIC_LIBRARY_SUFFIX}" - ) - set(QATZSTD_STATIC_LIB_TARGETS - "${QATZSTD_SOURCE_DIR}/src/${QATZSTD_STATIC_LIB_NAME}") - set(QATZSTD_MAKE_ARGS "ENABLE_USDM_DRV=1" "ZSTDLIB=${ZSTD_INCLUDE_DIR}") - - ExternalProject_Add( - qatzstd_ep - PREFIX ${QATZSTD_PREFIX} - GIT_REPOSITORY ${QATZSTD_SOURCE_URL} - GIT_TAG ${QATZSTD_SOURCE_BRANCH} - SOURCE_DIR ${QATZSTD_SOURCE_DIR} - CONFIGURE_COMMAND "" - BUILD_COMMAND ${MAKE} ${QATZSTD_MAKE_ARGS} - INSTALL_COMMAND "" - BUILD_BYPRODUCTS ${QATZSTD_STATIC_LIB_TARGETS} - BUILD_IN_SOURCE 1) - - add_library(qatzstd::qatzstd STATIC IMPORTED) - - # The include directory must exist before it is referenced by a target. - file(MAKE_DIRECTORY "${QATZSTD_INCLUDE_DIR}") - - set(QATZSTD_INCLUDE_DIRS "${QATZSTD_INCLUDE_DIR}" "${ZSTD_INCLUDE_DIR}") - - set(QATZSTD_LINK_LIBRARIES - "${ZSTD_LIBRARY}" "${QAT_LIBRARY}" "${USDM_DRV_LIBRARY}" "${ADF_LIBRARY}" - "${OSAL_LIBRARY}") - - set_target_properties( - qatzstd::qatzstd - PROPERTIES IMPORTED_LOCATION "${QATZSTD_STATIC_LIB_TARGETS}" - INTERFACE_INCLUDE_DIRECTORIES "${QATZSTD_INCLUDE_DIRS}" - INTERFACE_LINK_LIBRARIES "${QATZSTD_LINK_LIBRARIES}") - - add_dependencies(qatzstd::qatzstd qatzstd_ep) -endmacro() - -find_library( - QAT_LIBRARY REQUIRED - NAMES qat - PATHS "$ENV{ICP_ROOT}/build" - NO_DEFAULT_PATH) -find_library( - USDM_DRV_LIBRARY REQUIRED - NAMES usdm_drv - PATHS "$ENV{ICP_ROOT}/build" - NO_DEFAULT_PATH) -find_library( - ADF_LIBRARY REQUIRED - NAMES adf - PATHS "$ENV{ICP_ROOT}/build" - NO_DEFAULT_PATH) -find_library( - OSAL_LIBRARY REQUIRED - NAMES osal - PATHS "$ENV{ICP_ROOT}/build" - NO_DEFAULT_PATH) - -message(STATUS "Found qat: ${QAT_LIBRARY}") -message(STATUS "Found usdm_drv: ${USDM_DRV_LIBRARY}") -message(STATUS "Found adf: ${ADF_LIBRARY}") -message(STATUS "Found osal: ${OSAL_LIBRARY}") - -build_qatzstd() diff --git a/cpp/CMake/BuildQATzip.cmake b/cpp/CMake/BuildQATzip.cmake deleted file mode 100644 index fd75757d7286..000000000000 --- a/cpp/CMake/BuildQATzip.cmake +++ /dev/null @@ -1,126 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -include(ExternalProject) - -if("${MAKE}" STREQUAL "") - if(NOT MSVC) - find_program(MAKE make) - endif() -endif() - -macro(build_qatzip) - message(STATUS "Building QATzip from source") - set(QATZIP_BUILD_VERSION "v1.1.1") - set(QATZIP_BUILD_SHA256_CHECKSUM - "679f5522deb35e7ffa36f227ae49d07ef2d69a83e56bfda849303829b274e79b") - set(QATZIP_SOURCE_URL - "https://github.com/intel/QATzip/archive/refs/tags/${QATZIP_BUILD_VERSION}.tar.gz" - ) - set(QATZIP_LIB_NAME "qatzip") - - set(QATZIP_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/qatzip_ep-install") - set(QATZIP_SOURCE_DIR "${QATZIP_PREFIX}/src/qatzip_ep") - set(QATZIP_INCLUDE_DIR "${QATZIP_SOURCE_DIR}/include") - set(QATZIP_STATIC_LIB_NAME - "${CMAKE_STATIC_LIBRARY_PREFIX}${QATZIP_LIB_NAME}${CMAKE_STATIC_LIBRARY_SUFFIX}" - ) - set(QATZIP_STATIC_LIB_TARGETS - "${QATZIP_SOURCE_DIR}/src/.libs/${QATZIP_STATIC_LIB_NAME}") - set(QATZIP_CONFIGURE_ARGS "--prefix=${QATZIP_PREFIX}" "--with-pic" - "--with-ICP_ROOT=$ENV{ICP_ROOT}") - - ExternalProject_Add( - qatzip_ep - PREFIX ${QATZIP_PREFIX} - URL ${QATZIP_SOURCE_URL} - URL_HASH "SHA256=${QATZIP_BUILD_SHA256_CHECKSUM}" - SOURCE_DIR ${QATZIP_SOURCE_DIR} - CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env QZ_ROOT=${QATZIP_SOURCE_DIR} - ./configure ${QATZIP_CONFIGURE_ARGS} - BUILD_COMMAND ${MAKE} all - BUILD_BYPRODUCTS ${QATZIP_STATIC_LIB_TARGETS} - BUILD_IN_SOURCE 1) - - ExternalProject_Add_Step( - qatzip_ep pre-configure - COMMAND ./autogen.sh - DEPENDEES download - DEPENDERS configure - WORKING_DIRECTORY ${QATZIP_SOURCE_DIR}) - - # The include directory must exist before it is referenced by a target. - file(MAKE_DIRECTORY "${QATZIP_INCLUDE_DIR}") - - set(QATZIP_LINK_LIBRARIES - "${ZLIB_LIBRARY}" - "${LZ4_LIBRARY}" - "${UDEV_LIBRARY}" - "${QAT_LIBRARY}" - "${USDM_DRV_LIBRARY}" - "${ADF_LIBRARY}" - "${OSAL_LIBRARY}" - Threads::Threads) - - # Fix libudev.so not get linked. - set(QATZIP_LINK_OPTIONS "-Wl,--no-as-needed") - - add_library(qatzip::qatzip STATIC IMPORTED) - set_target_properties( - qatzip::qatzip - PROPERTIES IMPORTED_LOCATION "${QATZIP_STATIC_LIB_TARGETS}" - INTERFACE_INCLUDE_DIRECTORIES "${QATZIP_INCLUDE_DIR}" - INTERFACE_LINK_LIBRARIES "${QATZIP_LINK_LIBRARIES}" - INTERFACE_LINK_OPTIONS "${QATZIP_LINK_OPTIONS}") - - add_dependencies(qatzip::qatzip qatzip_ep) -endmacro() - -set(THREADS_PREFER_PTHREAD_FLAG ON) -find_package(Threads REQUIRED) - -find_library(ZLIB_LIBRARY REQUIRED NAMES z) -find_library(LZ4_LIBRARY REQUIRED NAMES lz4) -find_library(UDEV_LIBRARY REQUIRED NAMES udev) -find_library( - USDM_DRV_LIBRARY REQUIRED - NAMES usdm_drv - PATHS "$ENV{ICP_ROOT}/build" - NO_DEFAULT_PATH) -find_library( - QAT_LIBRARY REQUIRED - NAMES qat - PATHS "$ENV{ICP_ROOT}/build" - NO_DEFAULT_PATH) -find_library( - OSAL_LIBRARY REQUIRED - NAMES osal - PATHS "$ENV{ICP_ROOT}/build" - NO_DEFAULT_PATH) -find_library( - ADF_LIBRARY REQUIRED - NAMES adf - PATHS "$ENV{ICP_ROOT}/build" - NO_DEFAULT_PATH) - -message(STATUS "Found zlib: ${ZLIB_LIBRARY}") -message(STATUS "Found lz4: ${LZ4_LIBRARY}") -message(STATUS "Found udev: ${UDEV_LIBRARY}") -message(STATUS "Found usdm_drv: ${USDM_DRV_LIBRARY}") -message(STATUS "Found qat: ${QAT_LIBRARY}") - -build_qatzip() diff --git a/cpp/CMake/BuildQpl.cmake b/cpp/CMake/BuildQpl.cmake deleted file mode 100644 index 7715bb8e767f..000000000000 --- a/cpp/CMake/BuildQpl.cmake +++ /dev/null @@ -1,60 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -include(ExternalProject) - -macro(build_qpl) - message(STATUS "Building QPL from source") - set(QPL_BUILD_VERSION "v1.1.0") - set(QPL_BUILD_SHA256_CHECKSUM - "00306000035621dfbc21007481395c46ba9723fc8add8ca5142847b94dc564c5") - set(QPL_SOURCE_URL - "https://github.com/intel/qpl/archive/refs/tags/v1.1.0.tar.gz") - set(QPL_LIB_NAME "qpl") - - set(QPL_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/qpl_ep-install") - set(QPL_SOURCE_DIR "${QPL_PREFIX}/src/qpl_ep") - set(QPL_INCLUDE_DIR "${QPL_PREFIX}/include") - set(QPL_LIB_DIR "${QPL_PREFIX}/lib") - set(QPL_STATIC_LIB_NAME - "${CMAKE_STATIC_LIBRARY_PREFIX}${QPL_LIB_NAME}${CMAKE_STATIC_LIBRARY_SUFFIX}${QPL_STATIC_LIB_MAJOR_VERSION}" - ) - set(QPL_STATIC_LIB_TARGETS "${QPL_LIB_DIR}/${QPL_STATIC_LIB_NAME}") - ExternalProject_Add( - qpl_ep - PREFIX ${QPL_PREFIX} - URL ${QPL_SOURCE_URL} - URL_HASH "SHA256=${QPL_BUILD_SHA256_CHECKSUM}" - SOURCE_DIR ${QPL_SOURCE_DIR} - CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${QPL_PREFIX} - -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DQPL_BUILD_TESTS=OFF - -DLOG_HW_INIT=ON - BUILD_BYPRODUCTS ${QPL_STATIC_LIB_TARGETS}) - - # The include directory must exist before it is referenced by a target. - file(MAKE_DIRECTORY "${QPL_INCLUDE_DIR}") - - add_library(qpl::qpl STATIC IMPORTED) - set_target_properties( - qpl::qpl - PROPERTIES IMPORTED_LOCATION "${QPL_LIB_DIR}/${QPL_STATIC_LIB_NAME}" - INTERFACE_INCLUDE_DIRECTORIES "${QPL_INCLUDE_DIR}") - - add_dependencies(qpl::qpl qpl_ep) -endmacro() - -build_qpl() diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 50b95d3f63a6..719ff59f9c9c 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -48,9 +48,6 @@ option(BUILD_EXAMPLES "Build Examples" OFF) option(BUILD_BENCHMARKS "Build Benchmarks" OFF) option(ENABLE_JEMALLOC_STATS "Prints Jemalloc stats for debugging" OFF) option(BUILD_GLOG "Build Glog from Source" OFF) -option(ENABLE_HBM "Enable HBM allocator" OFF) -option(ENABLE_QAT "Enable QAT for de/compression" OFF) -option(ENABLE_IAA "Enable IAA for de/compression" OFF) option(ENABLE_GCS "Enable GCS" OFF) option(ENABLE_S3 "Enable S3" OFF) option(ENABLE_HDFS "Enable HDFS" OFF) @@ -230,14 +227,6 @@ if(BUILD_TESTS OR BUILD_BENCHMARKS) endif() endif() -if(ENABLE_QAT) - add_definitions(-DGLUTEN_ENABLE_QAT) -endif() - -if(ENABLE_IAA) - add_definitions(-DGLUTEN_ENABLE_IAA) -endif() - if(ENABLE_GPU) add_definitions(-DGLUTEN_ENABLE_GPU) endif() diff --git a/cpp/core/CMakeLists.txt b/cpp/core/CMakeLists.txt index 5264eeb63ef1..ac354c0c74fb 100644 --- a/cpp/core/CMakeLists.txt +++ b/cpp/core/CMakeLists.txt @@ -178,29 +178,6 @@ endif() find_arrow_lib(${ARROW_LIB_NAME}) find_arrow_lib(${ARROW_BUNDLED_DEPS}) -if(ENABLE_HBM) - include(BuildMemkind) - target_sources(gluten PRIVATE memory/HbwAllocator.cc) - target_link_libraries(gluten PRIVATE memkind::memkind) - add_definitions(-DGLUTEN_ENABLE_HBM) -endif() - -if(ENABLE_QAT) - include(BuildQATzip) - include(BuildQATZstd) - target_sources(gluten PRIVATE utils/qat/QatCodec.cc) - target_include_directories(gluten PUBLIC ${QATZIP_INCLUDE_DIR} - ${QATZSTD_INCLUDE_DIR}) - target_link_libraries(gluten PUBLIC qatzip::qatzip qatzstd::qatzstd) -endif() - -if(ENABLE_IAA) - include(BuildQpl) - target_include_directories(gluten PUBLIC ${QPL_INCLUDE_DIR}) - target_sources(gluten PRIVATE utils/qpl/QplJobPool.cc utils/qpl/QplCodec.cc) - target_link_libraries(gluten PUBLIC qpl::qpl) -endif() - find_protobuf() message(STATUS "Found Protobuf: ${PROTOBUF_LIBRARY}") target_link_libraries(gluten LINK_PUBLIC ${PROTOBUF_LIBRARY}) diff --git a/cpp/core/config/GlutenConfig.h b/cpp/core/config/GlutenConfig.h index fe242603069e..8d10a562b0db 100644 --- a/cpp/core/config/GlutenConfig.h +++ b/cpp/core/config/GlutenConfig.h @@ -74,12 +74,9 @@ const std::string kUGIUserName = "spark.gluten.ugi.username"; const std::string kUGITokens = "spark.gluten.ugi.tokens"; const std::string kShuffleCompressionCodec = "spark.gluten.sql.columnar.shuffle.codec"; -const std::string kShuffleCompressionCodecBackend = "spark.gluten.sql.columnar.shuffle.codecBackend"; const std::string kShuffleSpillDiskWriteBufferSize = "spark.shuffle.spill.diskWriteBufferSize"; const std::string kSortShuffleReaderDeserializerBufferSize = "spark.gluten.sql.columnar.shuffle.sort.deserializerBufferSize"; -const std::string kQatBackendName = "qat"; -const std::string kIaaBackendName = "iaa"; const std::string kSparkRedactionRegex = "spark.redaction.regex"; const std::string kSparkRedactionString = "*********(redacted)"; diff --git a/cpp/core/jni/JniCommon.h b/cpp/core/jni/JniCommon.h index d777d39fa761..e8f49e0b0b03 100644 --- a/cpp/core/jni/JniCommon.h +++ b/cpp/core/jni/JniCommon.h @@ -354,20 +354,6 @@ static inline arrow::Compression::type getCompressionType(JNIEnv* env, jstring c return compressionType; } -static inline gluten::CodecBackend getCodecBackend(JNIEnv* env, jstring codecBackendJstr) { - if (codecBackendJstr == nullptr) { - return gluten::CodecBackend::NONE; - } - auto codecBackend = jStringToCString(env, codecBackendJstr); - if (codecBackend == "qat") { - return gluten::CodecBackend::QAT; - } - if (codecBackend == "iaa") { - return gluten::CodecBackend::IAA; - } - throw std::invalid_argument("Not support this codec backend " + codecBackend); -} - static inline gluten::CompressionMode getCompressionMode(JNIEnv* env, jstring compressionModeJstr) { GLUTEN_DCHECK(compressionModeJstr != nullptr, "CompressionMode cannot be null"); auto compressionMode = jStringToCString(env, compressionModeJstr); diff --git a/cpp/core/jni/JniWrapper.cc b/cpp/core/jni/JniWrapper.cc index 523c4a74940e..f9fbecd4d4ab 100644 --- a/cpp/core/jni/JniWrapper.cc +++ b/cpp/core/jni/JniWrapper.cc @@ -798,7 +798,6 @@ Java_org_apache_gluten_vectorized_LocalPartitionWriterJniWrapper_createPartition jobject wrapper, jint numPartitions, jstring codecJstr, - jstring codecBackendJstr, jint compressionLevel, jint compressionBufferSize, jint compressionThreshold, @@ -827,7 +826,7 @@ Java_org_apache_gluten_vectorized_LocalPartitionWriterJniWrapper_createPartition auto partitionWriter = std::make_shared( numPartitions, - createArrowIpcCodec(getCompressionType(env, codecJstr), getCodecBackend(env, codecBackendJstr), compressionLevel), + createCompressionCodec(getCompressionType(env, codecJstr), compressionLevel), ctx->memoryManager(), partitionWriterOptions, dataFile, @@ -1035,7 +1034,6 @@ JNIEXPORT jlong JNICALL Java_org_apache_gluten_vectorized_ShuffleReaderJniWrappe jobject wrapper, jlong cSchema, jstring compressionType, - jstring compressionBackend, jint batchSize, jlong readerBufferSize, jlong deserializerBufferSize, @@ -1045,9 +1043,6 @@ JNIEXPORT jlong JNICALL Java_org_apache_gluten_vectorized_ShuffleReaderJniWrappe ShuffleReaderOptions options = ShuffleReaderOptions{}; options.compressionType = getCompressionType(env, compressionType); - if (compressionType != nullptr) { - options.codecBackend = getCodecBackend(env, compressionBackend); - } options.batchSize = batchSize; options.readerBufferSize = readerBufferSize; options.deserializerBufferSize = deserializerBufferSize; diff --git a/cpp/core/memory/HbwAllocator.cc b/cpp/core/memory/HbwAllocator.cc deleted file mode 100644 index ef0dc82b8f93..000000000000 --- a/cpp/core/memory/HbwAllocator.cc +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "HbwAllocator.h" - -#include -#include -#include -#include "MemoryAllocator.h" - -namespace gluten { - -std::shared_ptr HbwMemoryAllocator::newInstance() { - auto memkindHbwNodes = std::getenv("MEMKIND_HBW_NODES"); - if (memkindHbwNodes == nullptr) { - std::cout << "MEMKIND_HBW_NODES not set. Use StdMemoryAllocator." << std::endl; - return std::make_shared(); - } - std::cout << "MEMKIND_HBW_NODES set. Use StdMemoryAllocator." << std::endl; - return std::make_shared(); -} - -bool HbwMemoryAllocator::allocate(int64_t size, void** out) { - *out = hbw_malloc(size); - bytes_ += size; - return true; -} - -bool HbwMemoryAllocator::allocateZeroFilled(int64_t nmemb, int64_t size, void** out) { - *out = hbw_calloc(nmemb, size); - bytes_ += size; - return true; -} - -bool HbwMemoryAllocator::allocateAligned(uint64_t alignment, int64_t size, void** out) { - if (hbw_posix_memalign(out, alignment, size) != 0) { - return false; - } - bytes_ += size; - return true; -} - -bool HbwMemoryAllocator::reallocate(void* p, int64_t size, int64_t newSize, void** out) { - *out = hbw_realloc(p, newSize); - bytes_ += (newSize - size); - return true; -} - -bool HbwMemoryAllocator::reallocateAligned(void* p, uint64_t alignment, int64_t size, int64_t newSize, void** out) { - if (newSize <= 0) { - return false; - } - void* reallocatedP = nullptr; - if (hbw_posix_memalign(&reallocatedP, alignment, newSize) != 0) { - return false; - } - memcpy(reallocatedP, p, std::min(size, newSize)); - hbw_free(p); - *out = reallocatedP; - bytes_ += (newSize - size); - return true; -} - -bool HbwMemoryAllocator::free(void* p, int64_t size) { - hbw_free(p); - bytes_ -= size; - return true; -} - -int64_t HbwMemoryAllocator::getBytes() const { - return bytes_; -} - -int64_t HbwMemoryAllocator::peakBytes() const { - return 0; -} - -} // namespace gluten diff --git a/cpp/core/memory/HbwAllocator.h b/cpp/core/memory/HbwAllocator.h deleted file mode 100644 index e50a71bd56b7..000000000000 --- a/cpp/core/memory/HbwAllocator.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include "MemoryAllocator.h" - -namespace gluten { - -class HbwMemoryAllocator final : public MemoryAllocator { - public: - static std::shared_ptr newInstance(); - - bool allocate(int64_t size, void** out) override; - - bool allocateZeroFilled(int64_t nmemb, int64_t size, void** out) override; - - bool allocateAligned(uint64_t alignment, int64_t size, void** out) override; - - bool reallocate(void* p, int64_t size, int64_t newSize, void** out) override; - - bool reallocateAligned(void* p, uint64_t alignment, int64_t size, int64_t newSize, void** out) override; - - bool free(void* p, int64_t size) override; - - int64_t getBytes() const override; - - int64_t peakBytes() const override; - - private: - std::atomic_int64_t bytes_{0}; -}; - -} // namespace gluten diff --git a/cpp/core/memory/MemoryAllocator.cc b/cpp/core/memory/MemoryAllocator.cc index 1bd16216dc7f..0ca27085b22f 100644 --- a/cpp/core/memory/MemoryAllocator.cc +++ b/cpp/core/memory/MemoryAllocator.cc @@ -16,7 +16,6 @@ */ #include "MemoryAllocator.h" -#include "HbwAllocator.h" #include "utils/Macros.h" namespace gluten { @@ -200,11 +199,7 @@ int64_t StdMemoryAllocator::peakBytes() const { } std::shared_ptr defaultMemoryAllocator() { -#if defined(GLUTEN_ENABLE_HBM) - static std::shared_ptr alloc = HbwMemoryAllocator::newInstance(); -#else static std::shared_ptr alloc = std::make_shared(); -#endif return alloc; } diff --git a/cpp/core/shuffle/Options.h b/cpp/core/shuffle/Options.h index 717f75dea54e..80d47f855ca8 100644 --- a/cpp/core/shuffle/Options.h +++ b/cpp/core/shuffle/Options.h @@ -52,7 +52,6 @@ struct ShuffleReaderOptions { // Compression options. arrow::Compression::type compressionType = arrow::Compression::type::LZ4_FRAME; - CodecBackend codecBackend = CodecBackend::NONE; // Output batch size. int32_t batchSize = kDefaultBatchSize; diff --git a/cpp/core/tests/CMakeLists.txt b/cpp/core/tests/CMakeLists.txt index 407045d9f9c4..ac3c719db262 100644 --- a/cpp/core/tests/CMakeLists.txt +++ b/cpp/core/tests/CMakeLists.txt @@ -13,9 +13,5 @@ # See the License for the specific language governing permissions and # limitations under the License. -if(ENABLE_HBM) - add_test_case(hbw_allocator_test SOURCES HbwAllocatorTest.cc) -endif() - add_test_case(round_robin_partitioner_test SOURCES RoundRobinPartitionerTest.cc) add_test_case(object_store_test SOURCES ObjectStoreTest.cc) diff --git a/cpp/core/tests/HbwAllocatorTest.cc b/cpp/core/tests/HbwAllocatorTest.cc deleted file mode 100644 index b3a0e23c5fd5..000000000000 --- a/cpp/core/tests/HbwAllocatorTest.cc +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include - -#include "memory/HbwAllocator.h" -#include "memory/MemoryAllocator.h" - -class TestHbwAllocator : public ::testing::Test { - protected: - void checkBytesAndFree(void*& buf, int64_t size) { - ASSERT_NE(buf, nullptr); - ASSERT_EQ(allocator_->getBytes(), size); - allocator_->free(buf, size); - ASSERT_EQ(allocator_->getBytes(), 0); - buf = nullptr; - } - - std::shared_ptr allocator_; -}; - -class TestHbwAllocatorEnabled : public TestHbwAllocator { - protected: - static void SetUpTestSuite() { - setenv("MEMKIND_HBW_NODES", "0", 1); - } - - TestHbwAllocatorEnabled() { - allocator_ = gluten::defaultMemoryAllocator(); - } -}; - -class TestHbwAllocatorDisabled : public TestHbwAllocator { - protected: - static void SetUpTestSuite() { - unsetenv("MEMKIND_HBW_NODES"); - } - - TestHbwAllocatorDisabled() { - allocator_ = gluten::defaultMemoryAllocator(); - } -}; - -TEST_F(TestHbwAllocatorEnabled, TestHbwEnabled) { - auto ptr = std::dynamic_pointer_cast(allocator_); - ASSERT_NE(ptr, nullptr); -} - -TEST_F(TestHbwAllocatorDisabled, TestHbwDisabled) { - unsetenv("MEMKIND_HBW_NODES"); - allocator_ = gluten::defaultMemoryAllocator(); - auto ptr = std::dynamic_pointer_cast(allocator_); - ASSERT_NE(ptr, nullptr); -} - -TEST_F(TestHbwAllocatorEnabled, TestAllocateHbm) { - setenv("MEMKIND_HBW_NODES", "0", 1); - allocator_ = gluten::defaultMemoryAllocator(); - - const size_t size = 1024 * 1024; // 1M of data - void* buf = nullptr; - - allocator_->allocate(size, &buf); - checkBytesAndFree(buf, size); - - allocator_->allocateAligned(64, size, &buf); - checkBytesAndFree(buf, size); - - allocator_->allocateZeroFilled(1, size, &buf); - checkBytesAndFree(buf, size); - - allocator_->allocate(size, &buf); - allocator_->reallocate(buf, size, size << 1, &buf); - checkBytesAndFree(buf, size << 1); - - allocator_->allocate(size, &buf); - allocator_->reallocateAligned(buf, 64, size, size << 1, &buf); - checkBytesAndFree(buf, size << 1); -} diff --git a/cpp/core/utils/Compression.cc b/cpp/core/utils/Compression.cc index 76e33312677b..8fcf817bf095 100644 --- a/cpp/core/utils/Compression.cc +++ b/cpp/core/utils/Compression.cc @@ -19,56 +19,21 @@ #include "Exception.h" -#ifdef GLUTEN_ENABLE_QAT -#include "utils/qat/QatCodec.h" -#endif - -#ifdef GLUTEN_ENABLE_IAA -#include "utils/qpl/QplCodec.h" -#endif - namespace gluten { -std::unique_ptr -createArrowIpcCodec(arrow::Compression::type compressedType, CodecBackend codecBackend, int32_t compressionLevel) { +std::unique_ptr createCompressionCodec( + arrow::Compression::type compressedType, + int32_t compressionLevel) { std::unique_ptr codec; + // TODO: More compression codecs should be supported. switch (compressedType) { - case arrow::Compression::LZ4_FRAME: { - GLUTEN_ASSIGN_OR_THROW(codec, arrow::util::Codec::Create(compressedType)); - } break; + case arrow::Compression::LZ4_FRAME: case arrow::Compression::ZSTD: { - if (codecBackend == CodecBackend::NONE) { - GLUTEN_ASSIGN_OR_THROW(codec, arrow::util::Codec::Create(compressedType, compressionLevel)); - } else if (codecBackend == CodecBackend::QAT) { -#if defined(GLUTEN_ENABLE_QAT) - codec = qat::makeDefaultQatZstdCodec(); -#else - throw GlutenException("Backend QAT but not compile with option GLUTEN_ENABLE_QAT"); -#endif - } else { - throw GlutenException("Backend IAA not support zstd compression"); - } - } break; - case arrow::Compression::GZIP: { - if (codecBackend == CodecBackend::NONE) { - return nullptr; - } else if (codecBackend == CodecBackend::QAT) { -#if defined(GLUTEN_ENABLE_QAT) - codec = qat::makeDefaultQatGZipCodec(); -#else - throw GlutenException("Backend QAT but not compile with option GLUTEN_ENABLE_QAT"); -#endif - } else { -#if defined(GLUTEN_ENABLE_IAA) - codec = qpl::MakeDefaultQplGZipCodec(); -#else - throw GlutenException("Backend IAA but not compile with option GLUTEN_ENABLE_IAA"); -#endif - } - } break; + GLUTEN_ASSIGN_OR_THROW(codec, arrow::util::Codec::Create(compressedType, compressionLevel)); + return codec; + } default: return nullptr; } - return codec; } } // namespace gluten diff --git a/cpp/core/utils/Compression.h b/cpp/core/utils/Compression.h index aebce00f3442..702833ddf39b 100644 --- a/cpp/core/utils/Compression.h +++ b/cpp/core/utils/Compression.h @@ -21,15 +21,12 @@ namespace gluten { -enum CodecBackend { NONE, QAT, IAA }; - // BUFFER mode will preallocate max compressed buffer, and then compress each buffer to the max compressed buffer // ROWVECTOR mode will copy the buffers to a big buffer and then compress the big buffer enum CompressionMode { BUFFER, ROWVECTOR }; -std::unique_ptr createArrowIpcCodec( +std::unique_ptr createCompressionCodec( arrow::Compression::type compressedType, - CodecBackend codecBackend, int32_t compressionLevel = arrow::util::kUseDefaultCompressionLevel); } // namespace gluten diff --git a/cpp/core/utils/qat/QatCodec.cc b/cpp/core/utils/qat/QatCodec.cc deleted file mode 100644 index c86fc3bc2152..000000000000 --- a/cpp/core/utils/qat/QatCodec.cc +++ /dev/null @@ -1,304 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "QatCodec.h" - -#define QZ_INIT_FAIL(rc) ((QZ_OK != (rc)) && (QZ_DUPLICATE != (rc))) - -#define QZ_SETUP_SESSION_FAIL(rc) (QZ_PARAMS == (rc) || QZ_NOSW_NO_HW == (rc) || QZ_NOSW_LOW_MEM == (rc)) - -namespace gluten { -namespace qat { - -class QatZipCodec : public arrow::util::Codec { - protected: - explicit QatZipCodec(int compressionLevel) : compressionLevel_(compressionLevel) {} - - ~QatZipCodec() { - static_cast(qzTeardownSession(&qzSession_)); - static_cast(qzClose(&qzSession_)); - } - - arrow::Result Decompress(int64_t inputLen, const uint8_t* input, int64_t outputLen, uint8_t* output) - override { - uint32_t compressedSize = static_cast(inputLen); - uint32_t uncompressedSize = static_cast(outputLen); - int ret = qzDecompress(&qzSession_, input, &compressedSize, output, &uncompressedSize); - if (ret == QZ_OK) { - return static_cast(uncompressedSize); - } else if (ret == QZ_PARAMS) { - return arrow::Status::IOError("QAT decompression failure: params is invalid"); - } else if (ret == QZ_FAIL) { - return arrow::Status::IOError("QAT decompression failure: Function did not succeed"); - } else { - return arrow::Status::IOError("QAT decompression failure with error:", ret); - } - } - - int64_t MaxCompressedLen(int64_t inputLen, const uint8_t* ARROW_ARG_UNUSED(input)) override { - ARROW_DCHECK_GE(inputLen, 0); - return qzMaxCompressedLength(static_cast(inputLen), &qzSession_); - } - - arrow::Result Compress(int64_t inputLen, const uint8_t* input, int64_t outputLen, uint8_t* output) override { - uint32_t uncompressedSize = static_cast(inputLen); - uint32_t compressedSize = static_cast(outputLen); - int ret = qzCompress(&qzSession_, input, &uncompressedSize, output, &compressedSize, 1); - if (ret == QZ_OK) { - return static_cast(compressedSize); - } else if (ret == QZ_PARAMS) { - return arrow::Status::IOError("QAT compression failure: params is invalid"); - } else if (ret == QZ_FAIL) { - return arrow::Status::IOError("QAT compression failure: function did not succeed"); - } else { - return arrow::Status::IOError("QAT compression failure with error:", ret); - } - } - - arrow::Result> MakeCompressor() override { - return arrow::Status::NotImplemented("Streaming compression unsupported with QAT"); - } - - arrow::Result> MakeDecompressor() override { - return arrow::Status::NotImplemented("Streaming decompression unsupported with QAT"); - } - - int compression_level() const override { - return compressionLevel_; - } - - int compressionLevel_; - QzSession_T qzSession_ = {0}; -}; - -class QatGZipCodec final : public QatZipCodec { - public: - QatGZipCodec(QzPollingMode_T pollingMode, int compressionLevel) : QatZipCodec(compressionLevel) { - auto rc = qzInit(&qzSession_, /* sw_backup = */ 1); - if (QZ_INIT_FAIL(rc)) { - ARROW_LOG(WARNING) << "qzInit failed with error: " << rc; - } else { - QzSessionParamsDeflate_T params; - qzGetDefaultsDeflate(¶ms); // get the default value. - params.common_params.polling_mode = pollingMode; - params.common_params.comp_lvl = compressionLevel; - rc = qzSetupSessionDeflate(&qzSession_, ¶ms); - if (QZ_SETUP_SESSION_FAIL(rc)) { - ARROW_LOG(WARNING) << "qzSetupSession failed with error: " << rc; - } - } - } - - arrow::Compression::type compression_type() const override { - return arrow::Compression::GZIP; - } - - int minimum_compression_level() const override { - return QZ_DEFLATE_COMP_LVL_MINIMUM; - } - int maximum_compression_level() const override { - return QZ_DEFLATE_COMP_LVL_MAXIMUM; - } - int default_compression_level() const override { - return QZ_COMP_LEVEL_DEFAULT; - } -}; - -bool supportsCodec(const std::string& codec) { - return !codec.empty() && std::any_of(kQatSupportedCodec.begin(), kQatSupportedCodec.end(), [&](const auto& qatCodec) { - return qatCodec == codec; - }); -} - -std::unique_ptr makeQatGZipCodec(QzPollingMode_T pollingMode, int compressionLevel) { - return std::unique_ptr(new QatGZipCodec(pollingMode, compressionLevel)); -} - -std::unique_ptr makeDefaultQatGZipCodec() { - return makeQatGZipCodec(QZ_BUSY_POLLING, QZ_COMP_LEVEL_DEFAULT); -} - -namespace { -constexpr int kZSTDDefaultCompressionLevel = 1; -arrow::Status ZSTDError(size_t ret, const char* prefix_msg) { - return arrow::Status::IOError(prefix_msg, ZSTD_getErrorName(ret)); -} - -void logZstdOnError(size_t ret, const char* prefixMsg) { - if (ZSTD_isError(ret)) { - ARROW_LOG(WARNING) << prefixMsg << ZSTD_getErrorName(ret); - } -} - -} // namespace - -class QatDevice { - public: - QatDevice() { - if (QZSTD_startQatDevice() == QZSTD_FAIL) { - ARROW_LOG(WARNING) << "QZSTD_startQatDevice failed"; - } else { - initialized_ = true; - } - } - - ~QatDevice() { - if (initialized_) { - QZSTD_stopQatDevice(); - } - } - - static std::shared_ptr getInstance() { - std::call_once(initQat_, []() { instance_ = std::make_shared(); }); - return instance_; - } - - bool deviceInitialized() { - return initialized_; - } - - private: - inline static std::shared_ptr instance_; - inline static std::once_flag initQat_; - bool initialized_{false}; -}; - -class QatZstdCodec final : public arrow::util::Codec { - public: - explicit QatZstdCodec(int compressionLevel) : compressionLevel_(compressionLevel) {} - - ~QatZstdCodec() { - if (initCCtx_) { - ZSTD_freeCCtx(zc_); - if (sequenceProducerState_) { - QZSTD_freeSeqProdState(sequenceProducerState_); - } - } - } - - arrow::Compression::type compression_type() const override { - return arrow::Compression::ZSTD; - } - - arrow::Result Decompress(int64_t inputLen, const uint8_t* input, int64_t outputLen, uint8_t* output) - override { - if (output == nullptr) { - // We may pass a NULL 0-byte output buffer but some zstd versions demand - // a valid pointer: https://github.com/facebook/zstd/issues/1385 - static uint8_t emptyBuffer; - DCHECK_EQ(outputLen, 0); - output = &emptyBuffer; - } - - size_t ret = ZSTD_decompress(output, static_cast(outputLen), input, static_cast(inputLen)); - if (ZSTD_isError(ret)) { - return ZSTDError(ret, "ZSTD decompression failed: "); - } - if (static_cast(ret) != outputLen) { - return arrow::Status::IOError("Corrupt ZSTD compressed data."); - } - return static_cast(ret); - } - - int64_t MaxCompressedLen(int64_t inputLen, const uint8_t* ARROW_ARG_UNUSED(input)) override { - DCHECK_GE(inputLen, 0); - return ZSTD_compressBound(static_cast(inputLen)); - } - - arrow::Result Compress(int64_t inputLen, const uint8_t* input, int64_t outputLen, uint8_t* output) override { - RETURN_NOT_OK(initCCtx()); - size_t ret = ZSTD_compress2(zc_, output, static_cast(outputLen), input, static_cast(inputLen)); - if (ZSTD_isError(ret)) { - return ZSTDError(ret, "ZSTD compression failed: "); - } - return static_cast(ret); - } - - arrow::Result> MakeCompressor() override { - return arrow::Status::NotImplemented("Streaming compression unsupported with QAT"); - } - - arrow::Result> MakeDecompressor() override { - return arrow::Status::NotImplemented("Streaming decompression unsupported with QAT"); - } - - int minimum_compression_level() const override { - return ZSTD_minCLevel(); - } - int maximum_compression_level() const override { - return ZSTD_maxCLevel(); - } - int default_compression_level() const override { - return kZSTDDefaultCompressionLevel; - } - - int compression_level() const override { - return compressionLevel_; - } - - private: - int compressionLevel_; - ZSTD_CCtx* zc_; - bool initCCtx_{false}; - - std::shared_ptr qatDevice_; - void* sequenceProducerState_{nullptr}; - - arrow::Status initCCtx() { - if (initCCtx_) { - return arrow::Status::OK(); - } - zc_ = ZSTD_createCCtx(); - logZstdOnError( - ZSTD_CCtx_setParameter(zc_, ZSTD_c_compressionLevel, compressionLevel_), - "ZSTD_CCtx_setParameter failed on ZSTD_c_compressionLevel: "); - if (!qatDevice_) { - qatDevice_ = QatDevice::getInstance(); - } - if (qatDevice_->deviceInitialized()) { - sequenceProducerState_ = QZSTD_createSeqProdState(); - /* register qatSequenceProducer */ - ZSTD_registerSequenceProducer(zc_, sequenceProducerState_, qatSequenceProducer); - /* Enable sequence producer fallback */ - logZstdOnError( - ZSTD_CCtx_setParameter(zc_, ZSTD_c_enableSeqProducerFallback, 1), - "ZSTD_CCtx_setParameter failed on ZSTD_c_enableSeqProducerFallback: "); - } - initCCtx_ = true; - return arrow::Status::OK(); - } -}; - -std::unique_ptr makeQatZstdCodec(int compressionLevel) { - return std::unique_ptr(new QatZstdCodec(compressionLevel)); -} - -std::unique_ptr makeDefaultQatZstdCodec() { - return makeQatZstdCodec(kZSTDDefaultCompressionLevel); -} - -} // namespace qat -} // namespace gluten diff --git a/cpp/core/utils/qat/QatCodec.h b/cpp/core/utils/qat/QatCodec.h deleted file mode 100644 index d56f2fda1244..000000000000 --- a/cpp/core/utils/qat/QatCodec.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include -#include -#include - -namespace gluten { -namespace qat { - -static const std::vector kQatSupportedCodec = {"gzip", "zstd"}; - -bool supportsCodec(const std::string& qatCodec); - -std::unique_ptr makeQatGZipCodec(QzPollingMode_T pollingMode, int compressionLevel); - -std::unique_ptr makeDefaultQatGZipCodec(); - -std::unique_ptr makeQatZstdCodec(int compressionLevel); - -std::unique_ptr makeDefaultQatZstdCodec(); -} // namespace qat -} // namespace gluten diff --git a/cpp/core/utils/qpl/QplCodec.cc b/cpp/core/utils/qpl/QplCodec.cc deleted file mode 100644 index b41a00585e81..000000000000 --- a/cpp/core/utils/qpl/QplCodec.cc +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include -#include - -namespace gluten { -namespace qpl { - -class HardwareCodecDeflateQpl { - public: - /// RET_ERROR stands for hardware codec fail,need fallback to software codec. - static constexpr int64_t RET_ERROR = -1; - - explicit HardwareCodecDeflateQpl(qpl_compression_levels compressionLevel) : compressionLevel_(compressionLevel){}; - - int64_t doCompressData(const uint8_t* source, uint32_t source_size, uint8_t* dest, uint32_t dest_size) const { - uint32_t job_id; - qpl_job* jobPtr; - if (!(jobPtr = QplJobHWPool::GetInstance().AcquireJob(job_id))) { - ARROW_LOG(WARNING) - << "DeflateQpl HW codec failed, falling back to SW codec. (Details: doCompressData->AcquireJob fail, probably job pool exhausted)"; - return RET_ERROR; - } - - jobPtr->op = qpl_op_compress; - jobPtr->next_in_ptr = const_cast(source); - jobPtr->next_out_ptr = dest; - jobPtr->available_in = source_size; - jobPtr->level = compressionLevel_; - jobPtr->available_out = dest_size; - jobPtr->flags = QPL_FLAG_FIRST | QPL_FLAG_DYNAMIC_HUFFMAN | QPL_FLAG_LAST | QPL_FLAG_OMIT_VERIFY; - - if (auto status = qpl_execute_job(jobPtr); status == QPL_STS_OK) { - auto compressed_size = jobPtr->total_out; - QplJobHWPool::GetInstance().ReleaseJob(job_id); - return compressed_size; - } else { - ARROW_LOG(WARNING) - << "DeflateQpl HW codec failed, falling back to SW codec. (Details: doCompressData->qpl_execute_job with error code: " - << status << " - please refer to qpl_status in ./contrib/qpl/include/qpl/c_api/status.h)"; - QplJobHWPool::GetInstance().ReleaseJob(job_id); - return RET_ERROR; - } - } - - /// Submit job request to the IAA hardware and then busy waiting till it complete. - int64_t doDecompressData(const uint8_t* source, uint32_t source_size, uint8_t* dest, uint32_t uncompressed_size) { - uint32_t job_id = 0; - qpl_job* jobPtr; - if (!(jobPtr = QplJobHWPool::GetInstance().AcquireJob(job_id))) { - ARROW_LOG(WARNING) - << "DeflateQpl HW codec failed, falling back to SW codec.(Details: doDecompressData->AcquireJob fail, probably job pool exhausted)"; - return RET_ERROR; - } - - // Performing a decompression operation - jobPtr->op = qpl_op_decompress; - jobPtr->next_in_ptr = const_cast(source); - jobPtr->next_out_ptr = dest; - jobPtr->available_in = source_size; - jobPtr->available_out = uncompressed_size; - jobPtr->flags = QPL_FLAG_FIRST | QPL_FLAG_LAST; - - if (auto status = qpl_execute_job(jobPtr); status == QPL_STS_OK) { - auto decompressed_size = jobPtr->total_out; - QplJobHWPool::GetInstance().ReleaseJob(job_id); - return decompressed_size; - } else { - ARROW_LOG(WARNING) - << "DeflateQpl HW codec failed, falling back to SW codec. (Details: doDeCompressData->qpl_execute_job with error code: " - << status << " - please refer to qpl_status in ./contrib/qpl/include/qpl/c_api/status.h)"; - QplJobHWPool::GetInstance().ReleaseJob(job_id); - return RET_ERROR; - } - } - - private: - qpl_compression_levels compressionLevel_ = qpl_default_level; -}; - -class SoftwareCodecDeflateQpl final { - public: - explicit SoftwareCodecDeflateQpl(qpl_compression_levels compressionLevel) : compressionLevel_(compressionLevel){}; - - ~SoftwareCodecDeflateQpl() { - if (swJob) { - qpl_fini_job(swJob); - } - } - - int64_t doCompressData(const uint8_t* source, uint32_t source_size, uint8_t* dest, uint32_t dest_size) { - qpl_job* jobPtr = getJobCodecPtr(); - // Performing a compression operation - jobPtr->op = qpl_op_compress; - jobPtr->next_in_ptr = const_cast(source); - jobPtr->next_out_ptr = dest; - jobPtr->available_in = source_size; - jobPtr->level = compressionLevel_; - jobPtr->available_out = dest_size; - jobPtr->flags = QPL_FLAG_FIRST | QPL_FLAG_DYNAMIC_HUFFMAN | QPL_FLAG_LAST | QPL_FLAG_OMIT_VERIFY; - - if (auto status = qpl_execute_job(jobPtr); status != QPL_STS_OK) { - throw GlutenException( - "Execution of DeflateQpl software fallback codec failed. (Details: qpl_init_job with error code: " + - std::to_string(status) + " - please refer to qpl_status in ./contrib/qpl/include/qpl/c_api/status.h)"); - } - - return jobPtr->total_out; - } - - int64_t doDecompressData(const uint8_t* source, uint32_t source_size, uint8_t* dest, uint32_t uncompressed_size) { - qpl_job* jobPtr = getJobCodecPtr(); - - // Performing a decompression operation - jobPtr->op = qpl_op_decompress; - jobPtr->next_in_ptr = const_cast(source); - jobPtr->next_out_ptr = dest; - jobPtr->available_in = source_size; - jobPtr->available_out = uncompressed_size; - jobPtr->flags = QPL_FLAG_FIRST | QPL_FLAG_LAST; - - if (auto status = qpl_execute_job(jobPtr); status != QPL_STS_OK) { - throw GlutenException( - "Execution of DeflateQpl software fallback codec failed. (Details: qpl_init_job with error code: " + - std::to_string(status) + " - please refer to qpl_status in ./contrib/qpl/include/qpl/c_api/status.h)"); - } - - return jobPtr->total_out; - } - - private: - qpl_job* swJob = nullptr; - std::unique_ptr sw_buffer; - qpl_compression_levels compressionLevel_ = qpl_default_level; - - qpl_job* getJobCodecPtr() { - if (!swJob) { - uint32_t size = 0; - qpl_get_job_size(qpl_path_software, &size); - - sw_buffer = std::make_unique(size); - swJob = reinterpret_cast(sw_buffer.get()); - - // Job initialization - if (auto status = qpl_init_job(qpl_path_software, swJob); status != QPL_STS_OK) - throw GlutenException( - "Initialization of DeflateQpl software fallback codec failed. (Details: qpl_init_job with error code: " + - std::to_string(status) + " - please refer to qpl_status in ./contrib/qpl/include/qpl/c_api/status.h)"); - } - return swJob; - } -}; - -class QplGzipCodec final : public arrow::util::Codec { - public: - explicit QplGzipCodec(qpl_compression_levels compressionLevel) - : hwCodec_(std::make_unique(compressionLevel)), - swCodec_(std::make_unique(compressionLevel)) {} - - arrow::Result - Compress(int64_t input_len, const uint8_t* input, int64_t output_buffer_len, uint8_t* output_buffer) override { - auto res = HardwareCodecDeflateQpl::RET_ERROR; - if (QplJobHWPool::GetInstance().IsJobPoolReady()) { - res = hwCodec_->doCompressData(input, input_len, output_buffer, output_buffer_len); - } - if (res == HardwareCodecDeflateQpl::RET_ERROR) { - return swCodec_->doCompressData(input, input_len, output_buffer, output_buffer_len); - } - return res; - } - - arrow::Result - Decompress(int64_t input_len, const uint8_t* input, int64_t output_buffer_len, uint8_t* output_buffer) override { - auto res = HardwareCodecDeflateQpl::RET_ERROR; - if (QplJobHWPool::GetInstance().IsJobPoolReady()) { - res = hwCodec_->doDecompressData(input, input_len, output_buffer, output_buffer_len); - } - if (res == HardwareCodecDeflateQpl::RET_ERROR) { - return swCodec_->doDecompressData(input, input_len, output_buffer, output_buffer_len); - } - return res; - } - - int64_t MaxCompressedLen(int64_t input_len, const uint8_t* ARROW_ARG_UNUSED(input)) override { - ARROW_DCHECK_GE(input_len, 0); - /// Aligned with ZLIB - return ((input_len) + ((input_len) >> 12) + ((input_len) >> 14) + ((input_len) >> 25) + 13LL); - } - - arrow::Result> MakeCompressor() override { - return arrow::Status::NotImplemented("Streaming compression unsupported with QAT"); - } - - arrow::Result> MakeDecompressor() override { - return arrow::Status::NotImplemented("Streaming decompression unsupported with QAT"); - } - - arrow::Compression::type compression_type() const override { - return arrow::Compression::GZIP; - } - - int minimum_compression_level() const override { - return qpl_level_1; - } - int maximum_compression_level() const override { - return qpl_high_level; - } - int default_compression_level() const override { - return qpl_default_level; - } - - private: - std::unique_ptr hwCodec_; - std::unique_ptr swCodec_; -}; - -bool SupportsCodec(const std::string& codec) { - if (std::any_of(qpl_supported_codec.begin(), qpl_supported_codec.end(), [&](const auto& qat_codec) { - return qat_codec == codec; - })) { - return true; - } - return false; -} - -std::unique_ptr MakeQplGZipCodec(int compressionLevel) { - auto qplCompressionLevel = static_cast(compressionLevel); - return std::unique_ptr(new QplGzipCodec(qplCompressionLevel)); -} - -std::unique_ptr MakeDefaultQplGZipCodec() { - return MakeQplGZipCodec(qpl_default_level); -} - -} // namespace qpl -} // namespace gluten diff --git a/cpp/core/utils/qpl/QplCodec.h b/cpp/core/utils/qpl/QplCodec.h deleted file mode 100644 index 249b42cd001b..000000000000 --- a/cpp/core/utils/qpl/QplCodec.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include -#include - -namespace gluten { -namespace qpl { - -static const std::vector qpl_supported_codec = {"gzip"}; - -bool SupportsCodec(const std::string& codec); - -std::unique_ptr MakeQplGZipCodec(int compressionLevel); - -std::unique_ptr MakeDefaultQplGZipCodec(); - -} // namespace qpl -} // namespace gluten diff --git a/cpp/core/utils/qpl/QplJobPool.cc b/cpp/core/utils/qpl/QplJobPool.cc deleted file mode 100644 index 87a4b7687257..000000000000 --- a/cpp/core/utils/qpl/QplJobPool.cc +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "utils/qpl/QplJobPool.h" -#include "utils/Macros.h" - -#include -#include - -namespace gluten { -namespace qpl { - -std::array QplJobHWPool::jobPool; -std::array QplJobHWPool::jobLocks; -bool QplJobHWPool::jobPoolReady = false; -std::unique_ptr QplJobHWPool::hwJobsBuffer; - -QplJobHWPool& QplJobHWPool::GetInstance() { - static QplJobHWPool pool; - return pool; -} - -QplJobHWPool::QplJobHWPool() : randomEngine(std::random_device()()), distribution(0, MAX_JOB_NUMBER - 1) { - uint64_t initTime = 0; - TIME_NANO(initTime, InitJobPool()); - DLOG(INFO) << "Init job pool took " << 1.0 * initTime / 1e6 << "ms"; -} - -QplJobHWPool::~QplJobHWPool() { - for (uint32_t i = 0; i < MAX_JOB_NUMBER; ++i) { - if (jobPool[i]) { - while (!tryLockJob(i)) - ; - qpl_fini_job(jobPool[i]); - unLockJob(i); - jobPool[i] = nullptr; - } - } - jobPoolReady = false; -} - -void QplJobHWPool::InitJobPool() { - uint32_t jobSize = 0; - const char* qpl_version = qpl_get_library_version(); - - // Get size required for saving a single qpl job object - qpl_get_job_size(qpl_path_hardware, &jobSize); - // Allocate entire buffer for storing all job objects - hwJobsBuffer = std::make_unique(jobSize * MAX_JOB_NUMBER); - // Initialize pool for storing all job object pointers - // Reallocate buffer by shifting address offset for each job object. - for (uint32_t index = 0; index < MAX_JOB_NUMBER; ++index) { - qpl_job* qplJobPtr = reinterpret_cast(hwJobsBuffer.get() + index * jobSize); - if (auto status = qpl_init_job(qpl_path_hardware, qplJobPtr); status != QPL_STS_OK) { - jobPoolReady = false; - ARROW_LOG(WARNING) - << "Initialization of hardware-assisted DeflateQpl codec failed at index: " << index - << ", falling back to SW codec. (Details: QplJobHWPool->qpl_init_job with error code: " << status - << " - please refer to qpl_status in ./contrib/qpl/include/qpl/c_api/status.h). " - << "Please check if Intel In-Memory Analytics Accelerator (IAA) is properly set up. QPL Version: " - << qpl_version; - return; - } - jobPool[index] = qplJobPtr; - jobLocks[index].store(false); - } - ARROW_LOG(WARNING) << "Initialization of hardware-assisted DeflateQpl codec succeeded."; - jobPoolReady = true; -} - -qpl_job* QplJobHWPool::AcquireJob(uint32_t& jobId) { - if (!IsJobPoolReady()) { - return nullptr; - } - uint32_t retry = 0; - auto index = distribution(randomEngine); - while (!tryLockJob(index)) { - index = distribution(randomEngine); - retry++; - if (retry > MAX_JOB_NUMBER) { - return nullptr; - } - } - jobId = MAX_JOB_NUMBER - index; - DLOG(INFO) << "Acquired job index " << index << " after " << retry << " retries."; - return jobPool[index]; -} - -void QplJobHWPool::ReleaseJob(uint32_t jobId) { - if (IsJobPoolReady()) { - auto index = MAX_JOB_NUMBER - jobId; - unLockJob(index); - } -} - -bool QplJobHWPool::tryLockJob(uint32_t index) { - CheckJobIndex(index); - bool expected = false; - return jobLocks[index].compare_exchange_strong(expected, true); -} - -void QplJobHWPool::unLockJob(uint32_t index) { - CheckJobIndex(index); - jobLocks[index].store(false); -} - -} // namespace qpl -} // namespace gluten diff --git a/cpp/core/utils/qpl/QplJobPool.h b/cpp/core/utils/qpl/QplJobPool.h deleted file mode 100644 index 929f7691faac..000000000000 --- a/cpp/core/utils/qpl/QplJobPool.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -#include -#include "utils/Exception.h" - -namespace gluten { -namespace qpl { - -/// QplJobHWPool is resource pool to provide the job objects, which is -/// used for storing context information during. -/// Memory for QPL job will be allocated when the QPLJobHWPool instance is created -/// -// QPL job can offload RLE-decoding/Filter/(De)compression works to hardware accelerator. -class QplJobHWPool { - public: - static QplJobHWPool& GetInstance(); - - /// Acquire QPL job - /// - /// @param jobId QPL job id, used when release QPL job - /// \return Pointer to the QPL job. If acquire job failed, return nullptr. - qpl_job* AcquireJob(uint32_t& jobId); - - /// \brief Release QPL job by the jobId. - void ReleaseJob(uint32_t jobId); - - /// \brief Return if the QPL job is allocated sucessfully. - static const bool& IsJobPoolReady() { - return jobPoolReady; - } - - private: - QplJobHWPool(); - ~QplJobHWPool(); - static void InitJobPool(); - bool tryLockJob(uint32_t index); - void unLockJob(uint32_t index); - - static inline void CheckJobIndex(uint32_t index) { - if (index >= MAX_JOB_NUMBER) { - throw GlutenException("Index exceeds MAX_JOB_NUMBER 512: " + std::to_string(index)); - } - } - - /// Max jobs in QPL_JOB_POOL - static constexpr auto MAX_JOB_NUMBER = 64; - /// Entire buffer for storing all job objects - static std::unique_ptr hwJobsBuffer; - /// Job pool for storing all job object pointers - static std::array jobPool; - /// Locks for accessing each job object pointers - static std::array jobLocks; - - static bool jobPoolReady; - std::mt19937 randomEngine; - std::uniform_int_distribution distribution; -}; - -} // namespace qpl -} // namespace gluten diff --git a/cpp/velox/benchmarks/GenericBenchmark.cc b/cpp/velox/benchmarks/GenericBenchmark.cc index 24e8d3b62b49..07969e3be2d9 100644 --- a/cpp/velox/benchmarks/GenericBenchmark.cc +++ b/cpp/velox/benchmarks/GenericBenchmark.cc @@ -61,7 +61,7 @@ DEFINE_bool(rss, false, "Mocking rss."); DEFINE_string( compression, "lz4", - "Specify the compression codec. Valid options are none, lz4, zstd, qat_gzip, qat_zstd, iaa_gzip"); + "Specify the compression codec. Valid options are none, lz4, zstd"); DEFINE_int32(shuffle_partitions, 200, "Number of shuffle split (reducer) partitions"); DEFINE_bool(shuffle_dictionary, false, "Whether to enable dictionary encoding for shuffle write."); @@ -164,23 +164,13 @@ void cleanupLocalDirs(const std::vector& localDirs) { } } -void setCompressionTypeFromFlag(arrow::Compression::type& compressionType, CodecBackend& codecBackend) { - codecBackend = CodecBackend::NONE; +void setCompressionTypeFromFlag(arrow::Compression::type& compressionType) { if (FLAGS_compression == "none") { compressionType = arrow::Compression::UNCOMPRESSED; } else if (FLAGS_compression == "lz4") { compressionType = arrow::Compression::LZ4_FRAME; } else if (FLAGS_compression == "zstd") { compressionType = arrow::Compression::ZSTD; - } else if (FLAGS_compression == "qat_gzip") { - codecBackend = CodecBackend::QAT; - compressionType = arrow::Compression::GZIP; - } else if (FLAGS_compression == "qat_zstd") { - codecBackend = CodecBackend::QAT; - compressionType = arrow::Compression::ZSTD; - } else if (FLAGS_compression == "iaa_gzip") { - codecBackend = CodecBackend::IAA; - compressionType = arrow::Compression::GZIP; } else { throw GlutenException("Unrecognized compression type: " + FLAGS_compression); } @@ -193,11 +183,10 @@ std::unique_ptr createCodec() { } arrow::Compression::type compressionType; - CodecBackend codecBackend; - setCompressionTypeFromFlag(compressionType, codecBackend); + setCompressionTypeFromFlag(compressionType); - return createArrowIpcCodec(compressionType, codecBackend); + return createCompressionCodec(compressionType); } std::shared_ptr @@ -249,7 +238,7 @@ std::shared_ptr createShuffleWriter( std::shared_ptr createShuffleReader(Runtime* runtime, const std::shared_ptr& schema) { auto readerOptions = ShuffleReaderOptions{}; readerOptions.shuffleWriterType = ShuffleWriter::stringToType(FLAGS_shuffle_writer), - setCompressionTypeFromFlag(readerOptions.compressionType, readerOptions.codecBackend); + setCompressionTypeFromFlag(readerOptions.compressionType); return runtime->createShuffleReader(schema, readerOptions); } diff --git a/cpp/velox/compute/VeloxBackend.cc b/cpp/velox/compute/VeloxBackend.cc index 7ba2392f9b4d..fcf87658df6d 100644 --- a/cpp/velox/compute/VeloxBackend.cc +++ b/cpp/velox/compute/VeloxBackend.cc @@ -24,12 +24,6 @@ #include "operators/plannodes/RowVectorStream.h" #include "utils/ConfigExtractor.h" -#ifdef GLUTEN_ENABLE_QAT -#include "utils/qat/QatCodec.h" -#endif -#ifdef GLUTEN_ENABLE_IAA -#include "utils/qpl/QplCodec.h" -#endif #ifdef GLUTEN_ENABLE_GPU #include "velox/experimental/cudf/exec/ToCudf.h" #endif diff --git a/cpp/velox/compute/VeloxRuntime.cc b/cpp/velox/compute/VeloxRuntime.cc index e826837e934f..cc488bc2f241 100644 --- a/cpp/velox/compute/VeloxRuntime.cc +++ b/cpp/velox/compute/VeloxRuntime.cc @@ -288,7 +288,7 @@ std::shared_ptr VeloxRuntime::createDataSource( std::shared_ptr VeloxRuntime::createShuffleReader( std::shared_ptr schema, ShuffleReaderOptions options) { - auto codec = gluten::createArrowIpcCodec(options.compressionType, options.codecBackend); + auto codec = gluten::createCompressionCodec(options.compressionType); const auto veloxCompressionKind = arrowCompressionTypeToVelox(options.compressionType); const auto rowType = facebook::velox::asRowType(gluten::fromArrowSchema(schema)); diff --git a/cpp/velox/jni/VeloxJniWrapper.cc b/cpp/velox/jni/VeloxJniWrapper.cc index 624a93f17005..6da20ecb2bfe 100644 --- a/cpp/velox/jni/VeloxJniWrapper.cc +++ b/cpp/velox/jni/VeloxJniWrapper.cc @@ -587,7 +587,6 @@ Java_org_apache_gluten_vectorized_CelebornPartitionWriterJniWrapper_createPartit jobject wrapper, jint numPartitions, jstring codecJstr, - jstring codecBackendJstr, jint compressionLevel, jint compressionBufferSize, jint pushBufferMaxSize, @@ -615,7 +614,7 @@ Java_org_apache_gluten_vectorized_CelebornPartitionWriterJniWrapper_createPartit auto partitionWriter = std::make_shared( numPartitions, - createArrowIpcCodec(getCompressionType(env, codecJstr), getCodecBackend(env, codecBackendJstr), compressionLevel), + createCompressionCodec(getCompressionType(env, codecJstr), compressionLevel), ctx->memoryManager(), partitionWriterOptions, celebornClient); @@ -630,7 +629,6 @@ Java_org_apache_gluten_vectorized_UnifflePartitionWriterJniWrapper_createPartiti jobject wrapper, jint numPartitions, jstring codecJstr, - jstring codecBackendJstr, jint compressionLevel, jint compressionBufferSize, jint pushBufferMaxSize, @@ -658,7 +656,7 @@ Java_org_apache_gluten_vectorized_UnifflePartitionWriterJniWrapper_createPartiti auto partitionWriter = std::make_shared( numPartitions, - createArrowIpcCodec(getCompressionType(env, codecJstr), getCodecBackend(env, codecBackendJstr), compressionLevel), + createCompressionCodec(getCompressionType(env, codecJstr), compressionLevel), ctx->memoryManager(), partitionWriterOptions, uniffleClient); diff --git a/cpp/velox/memory/VeloxMemoryManager.h b/cpp/velox/memory/VeloxMemoryManager.h index 15e298629e9f..570d1ec43ab1 100644 --- a/cpp/velox/memory/VeloxMemoryManager.h +++ b/cpp/velox/memory/VeloxMemoryManager.h @@ -105,10 +105,6 @@ class VeloxMemoryManager final : public MemoryManager { void dropMemoryPool(const std::string& name); -#ifdef GLUTEN_ENABLE_HBM - std::unique_ptr wrappedAlloc_; -#endif - std::unique_ptr listener_; std::unique_ptr blockListener_; diff --git a/cpp/velox/tests/VeloxShuffleWriterTest.cc b/cpp/velox/tests/VeloxShuffleWriterTest.cc index 419f18861e73..74a38888ce46 100644 --- a/cpp/velox/tests/VeloxShuffleWriterTest.cc +++ b/cpp/velox/tests/VeloxShuffleWriterTest.cc @@ -108,46 +108,50 @@ std::vector getTestParams() { for (const auto partitionWriterType : {PartitionWriterType::kLocal, PartitionWriterType::kRss}) { for (const auto diskWriteBufferSize : {4, 56, 32 * 1024}) { for (const bool useRadixSort : {true, false}) { - for (const int64_t deserializerBufferSize : {1L, kDefaultDeserializerBufferSize}) { - params.push_back(ShuffleTestParams{ - .shuffleWriterType = ShuffleWriterType::kSortShuffle, - .partitionWriterType = partitionWriterType, - .compressionType = compression, - .diskWriteBufferSize = diskWriteBufferSize, - .useRadixSort = useRadixSort, - .deserializerBufferSize = deserializerBufferSize}); + for (const auto deserializerBufferSize : {static_cast(1L), kDefaultDeserializerBufferSize}) { + params.push_back( + ShuffleTestParams{ + .shuffleWriterType = ShuffleWriterType::kSortShuffle, + .partitionWriterType = partitionWriterType, + .compressionType = compression, + .diskWriteBufferSize = diskWriteBufferSize, + .useRadixSort = useRadixSort, + .deserializerBufferSize = deserializerBufferSize}); } } } } // Rss sort-based shuffle. - params.push_back(ShuffleTestParams{ - .shuffleWriterType = ShuffleWriterType::kRssSortShuffle, - .partitionWriterType = PartitionWriterType::kRss, - .compressionType = compression}); + params.push_back( + ShuffleTestParams{ + .shuffleWriterType = ShuffleWriterType::kRssSortShuffle, + .partitionWriterType = PartitionWriterType::kRss, + .compressionType = compression}); // Hash-based shuffle. for (const auto compressionThreshold : compressionThresholds) { // Local. for (const auto mergeBufferSize : mergeBufferSizes) { for (const bool enableDictionary : {true, false}) { - params.push_back(ShuffleTestParams{ - .shuffleWriterType = ShuffleWriterType::kHashShuffle, - .partitionWriterType = PartitionWriterType::kLocal, - .compressionType = compression, - .compressionThreshold = compressionThreshold, - .mergeBufferSize = mergeBufferSize, - .enableDictionary = enableDictionary}); + params.push_back( + ShuffleTestParams{ + .shuffleWriterType = ShuffleWriterType::kHashShuffle, + .partitionWriterType = PartitionWriterType::kLocal, + .compressionType = compression, + .compressionThreshold = compressionThreshold, + .mergeBufferSize = mergeBufferSize, + .enableDictionary = enableDictionary}); } } // Rss. - params.push_back(ShuffleTestParams{ - .shuffleWriterType = ShuffleWriterType::kHashShuffle, - .partitionWriterType = PartitionWriterType::kRss, - .compressionType = compression, - .compressionThreshold = compressionThreshold}); + params.push_back( + ShuffleTestParams{ + .shuffleWriterType = ShuffleWriterType::kHashShuffle, + .partitionWriterType = PartitionWriterType::kRss, + .compressionType = compression, + .compressionThreshold = compressionThreshold}); } } @@ -163,7 +167,7 @@ std::shared_ptr createPartitionWriter( int32_t mergeBufferSize, int32_t compressionThreshold, bool enableDictionary) { - GLUTEN_ASSIGN_OR_THROW(auto codec, arrow::util::Codec::Create(compressionType)); + auto codec = createCompressionCodec(compressionType); switch (partitionWriterType) { case PartitionWriterType::kLocal: { auto options = std::make_shared(); @@ -292,7 +296,7 @@ class VeloxShuffleWriterTest : public ::testing::TestWithParamgetLeafMemoryPool().get()); - auto codec = createArrowIpcCodec(compressionType, CodecBackend::NONE); + auto codec = createCompressionCodec(compressionType); // Set batchSize to a large value to make all batches are merged by reader. auto deserializerFactory = std::make_unique( @@ -501,12 +505,7 @@ TEST_P(HashPartitioningShuffleWriterTest, hashPart1Vector) { makeFlatVector({232, 34567235, 1212, 4567}, DECIMAL(20, 4)), makeFlatVector( 4, [](vector_size_t row) { return row % 2; }, nullEvery(5), DATE()), - makeFlatVector( - 4, - [](vector_size_t row) { - return Timestamp{row % 2, 0}; - }, - nullEvery(5))}; + makeFlatVector(4, [](vector_size_t row) { return Timestamp{row % 2, 0}; }, nullEvery(5))}; const auto vector = makeRowVector(data); diff --git a/dev/__pycache__/util.cpython-313.pyc b/dev/__pycache__/util.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..25857ed060efdee058a4fe4c6ded3cbc4bf4fe8d GIT binary patch literal 3791 zcmbssYfl^5_0H3SZ5SYs2atqPLOX)s?uPdw$hM(NLJP#Rrbv!t8GA5JjP2eThlEX3 z)JQ9nRs||$A!?+sQl;HUD{VhEQl({kD(;r49#yO(w;AeIU3G+dR0*J0EdyAtx&cx#c|vXxd>6clq1-LrZ^?F)oe(O*e#P-UTv177X<3X@cvA`+ z293re#?Bcayda~B+mu3~WO!B!g-mxSG@FWM5{P?4p0W%@>OsGnpx07#1_IO2E0KFRI=3WsG>DJ$;|@aM%JUntm3*r(~=8 z^k#KauDWSqq=-Hmp;ZoRX@xfe`MAQ-*kFDRprGj8JGf9dQ=nQ*yJrfsVIwkQ z3Nf0>q!rfWbuBS%@>IK**74HDMp_M%>C)~QGz=!IupixCSf2-?jsh%@ZMkOYlgFQ| zb>!uiO}Q;6w|#jtFZ(tmpQW#eng)u#;soPq_ z2+gEYcR(ioww_9wLLwE8>Xs!HhStL&9Y1XgLca&7=_v?-{Ef(P3IIxQYH9xQ{95x@ z!#TNgL+Z2*jjlDSxTp(e3Ymb=G6Wbw6y>+>q?L#vt9=NyMr#~^8q&Q0J|%lBBmC$e zA|rI!jL37$`uG_S{PsTs13+$J0_+E{3|}QA0MU!8OLD=YHUpev-(b-@`X+%NE>_u6 z9&va=WiMN|1vo!`^~6w%H{*AI0MsB#Z;evTCkXz{HW>^1HR4sQRgRyqno5K<}J;U6avB&2p6n%js^rjrhpSeffx`~sc#N^0kT;TUDX-^ zF?hkjOTADn>t!2JpN$UJ;XFCf!9n!7M@=D~OlJ&}anB1GWBPK>$Cy;~87+~(#1>5f z4QGu~Q;f%wDXKxhim*&k-6VkX)A59+RGGYSKdqU3BCZ<{!Kru>xRQ}nR5RUrW-3in z5lz=kj%Jc3KYo3D$mC=5@wDlVYLV1zngWrcpIE_Wint3$1&r`CRe)d$X-Kn%$?5lX z(@ixaL#^u-m+68VX2Z#->2|KtqNaFfE=*%Oy=0xGS~_vx{s3O4W1KYF!^({G3T#-Q z8OaS0mkVUeRk7TXcb(m;JiR=(B4>radE{l`Hy=D}&U-Fw)tp_uzH)s{%hxoo8@Za+ z?9iLKi_hDhwyn?Q>wH-;JGUrrdrvQoJ|5kYm|Jd-*{hob3Nm~6|k@Olc~tYuJN; zze(tCh#x5jrWg7TXiaPa9fBuZgP)G^5B0!PzSO<}PTB@w=ie|Co_>fMKL%h*dO87})je>0kWOJK z3I=h3yT?j$3`=toO~i-XVJf8PDH zd$YbZSKs>8Pre?0G5n{SFGlk9J$VnPu=j1}LR(uZ{4*e+LU00m1d47C?t%3loHqa! z9}lRUwbKt-zt|J_dFSNeTuOmXEjvXf7@hSIojpZ{p|Yl`{Mh!K7!LP1`*Y|wJfso$ zlT0(bq!}=KHGSx+_!^VBtO)cvV759TRYxJ|mw}R_`2RqsJwStARKU2@DYhub9M)r1 z9xG~fIsw#=k>dscQ1zj2u63?gJ?&Z7|1h|%w0(W<#kozTKd1D+QU>z!;J3=add;eP z#r>H#rwrue!3{`%a!uCzuRVcOUS)JtKKJ#-MiFXVnF;39&+oqB~fRJ?S`7zx|(SfPxVTnpejd+~pXC*}p&-?`z_DP0C&q zK&oC7_kqYV-_IHc1f~PGz;tER0|L`Q<$0!U?<$;X*^>mOcCV6Q`t~KBskNNyKc|Sp Aod5s; literal 0 HcmV?d00001 diff --git a/dev/builddeps-veloxbe.sh b/dev/builddeps-veloxbe.sh index a5fdca73c380..10cfeeef2e72 100755 --- a/dev/builddeps-veloxbe.sh +++ b/dev/builddeps-veloxbe.sh @@ -31,9 +31,6 @@ BUILD_BENCHMARKS=OFF ENABLE_JEMALLOC_STATS=OFF BUILD_VELOX_TESTS=OFF BUILD_VELOX_BENCHMARKS=OFF -ENABLE_QAT=OFF -ENABLE_IAA=OFF -ENABLE_HBM=OFF ENABLE_GCS=OFF ENABLE_S3=OFF ENABLE_HDFS=OFF @@ -85,18 +82,6 @@ do ENABLE_JEMALLOC_STATS=("${arg#*=}") shift # Remove argument name from processing ;; - --enable_qat=*) - ENABLE_QAT=("${arg#*=}") - shift # Remove argument name from processing - ;; - --enable_iaa=*) - ENABLE_IAA=("${arg#*=}") - shift # Remove argument name from processing - ;; - --enable_hbm=*) - ENABLE_HBM=("${arg#*=}") - shift # Remove argument name from processing - ;; --enable_gcs=*) ENABLE_GCS=("${arg#*=}") shift # Remove argument name from processing @@ -245,9 +230,6 @@ function build_gluten_cpp { -DBUILD_EXAMPLES=$BUILD_EXAMPLES \ -DBUILD_BENCHMARKS=$BUILD_BENCHMARKS \ -DENABLE_JEMALLOC_STATS=$ENABLE_JEMALLOC_STATS \ - -DENABLE_HBM=$ENABLE_HBM \ - -DENABLE_QAT=$ENABLE_QAT \ - -DENABLE_IAA=$ENABLE_IAA \ -DENABLE_GCS=$ENABLE_GCS \ -DENABLE_S3=$ENABLE_S3 \ -DENABLE_HDFS=$ENABLE_HDFS \ diff --git a/dev/setup-qat-ubuntu.sh b/dev/setup-qat-ubuntu.sh deleted file mode 100755 index 979def4e2fab..000000000000 --- a/dev/setup-qat-ubuntu.sh +++ /dev/null @@ -1,59 +0,0 @@ -#!/bin/bash - -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Exit on any error -set -e - -# Define versions and URLs -QAT_VERSION="QAT20.L.1.0.50-00003" -QAT_URL="https://downloadmirror.intel.com/783270/${QAT_VERSION}.tar.gz" -ZSTD_VERSION="zstd-1.5.5" -ZSTD_URL="https://github.com/facebook/zstd/releases/download/v1.5.5/${ZSTD_VERSION}.tar.gz" - -# Install required packages for QAT -sudo apt-get update -sudo apt-get install -y zlib1g-dev libisal-dev libudev-dev udev yasm libboost-all-dev gcc g++ pkg-config linux-headers-$(uname -r) - -# Download and extract QAT driver -sudo rm -rf /opt/QAT20 -sudo mkdir -p /opt/QAT20 -sudo wget -O /opt/QAT20/${QAT_VERSION}.tar.gz ${QAT_URL} -sudo tar -C /opt/QAT20 -zxf /opt/QAT20/${QAT_VERSION}.tar.gz - -# Compile and install QAT driver -cd /opt/QAT20 -sudo ./configure -sudo make -sudo make install - -# Update environment variables for QAT driver -echo "export ICP_ROOT=/opt/QAT20" >> ~/.bashrc - -# Download and extract zstd -sudo wget -O /opt/${ZSTD_VERSION}.tar.gz ${ZSTD_URL} -sudo tar -C /opt -zxf /opt/${ZSTD_VERSION}.tar.gz - -# Compile and install zstd -sudo mkdir -p /opt/${ZSTD_VERSION}/build/cmake/build -cd /opt/${ZSTD_VERSION}/build/cmake/build -sudo cmake -DCMAKE_INSTALL_PREFIX=/usr/local .. -sudo make -j -sudo make install - -echo -e "QAT setup is complete." -echo -e "To apply the changes, please log out and log back in." - diff --git a/docs/Configuration.md b/docs/Configuration.md index 5313386cad8f..25670fcf1a23 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -108,8 +108,7 @@ nav_order: 15 | spark.gluten.sql.columnar.shuffle | true | Enable or disable columnar shuffle. | | spark.gluten.sql.columnar.shuffle.celeborn.fallback.enabled | true | If enabled, fall back to ColumnarShuffleManager when celeborn service is unavailable.Otherwise, throw an exception. | | spark.gluten.sql.columnar.shuffle.celeborn.useRssSort | true | If true, use RSS sort implementation for Celeborn sort-based shuffle.If false, use Gluten's row-based sort implementation. Only valid when `spark.celeborn.client.spark.shuffle.writer` is set to `sort`. | -| spark.gluten.sql.columnar.shuffle.codec | <undefined> | By default, the supported codecs are lz4 and zstd. When spark.gluten.sql.columnar.shuffle.codecBackend=qat,the supported codecs are gzip and zstd. When spark.gluten.sql.columnar.shuffle.codecBackend=iaa,the supported codec is gzip. | -| spark.gluten.sql.columnar.shuffle.codecBackend | <undefined> | +| spark.gluten.sql.columnar.shuffle.codec | <undefined> | By default, the supported codecs are lz4 and zstd.| | spark.gluten.sql.columnar.shuffle.compression.threshold | 100 | If number of rows in a batch falls below this threshold, will copy all buffers into one buffer to compress. | | spark.gluten.sql.columnar.shuffle.compressionMode | buffer | buffer means compress each buffer to pre allocated big buffer,rowvector means to copy the buffers to a big buffer, and then compress the buffer | | spark.gluten.sql.columnar.shuffle.dictionary.enabled | false | Enable dictionary in hash-based shuffle. | diff --git a/docs/get-started/Velox.md b/docs/get-started/Velox.md index 8d4ab79336ab..70658ef4d5aa 100644 --- a/docs/get-started/Velox.md +++ b/docs/get-started/Velox.md @@ -576,8 +576,3 @@ To enable this feature, you can set the following Spark configuration: This feature has been tested through a series of tests, and we are collecting more feedback from users. If you have memory problem on broadcast build relations, please try this feature and give more feedbacks. **Note**: This feature will become the default behavior once stabilized. Stay tuned for updates! - - -# Accelerators - -Please refer [HBM](VeloxHBM.md) [QAT](VeloxQAT.md) [IAA](VeloxIAA.md) for details diff --git a/docs/get-started/VeloxHBM.md b/docs/get-started/VeloxHBM.md deleted file mode 100644 index 7056bb2fb076..000000000000 --- a/docs/get-started/VeloxHBM.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -layout: page -title: HBM Support in Velox Backend -nav_order: 1 -parent: Getting-Started ---- -# High-Bandwidth Memory (HBM) support - -Gluten supports allocating memory on HBM. This feature is optional and is disabled by default. It is implemented on top of [Memkind library](http://memkind.github.io/memkind/). You can refer to memkind's [readme](https://github.com/memkind/memkind#memkind) for more details. - -# Build Gluten with HBM - -Gluten will internally build and link to a specific version of Memkind library and [hwloc](https://github.com/open-mpi/hwloc). Other dependencies should be installed on Driver and Worker node first: - -```bash -sudo apt install -y autoconf automake g++ libnuma-dev libtool numactl unzip libdaxctl-dev -``` - -After the set-up, you can now build Gluten with HBM. Below command is used to enable this feature - -```bash -cd /path/to/gluten - -## The script builds four jars for spark 3.2.2, 3.3.1, 3.4.3 and 3.5.1. -./dev/buildbundle-veloxbe.sh --enable_hbm=ON -``` - -## Configure and enable HBM in Spark Application - -At runtime, `MEMKIND_HBW_NODES` enviroment variable is detected for configuring HBM NUMA nodes. For the explaination to this variable, please refer to memkind's manual page. This can be set for all executors through spark conf, e.g. `--conf spark.executorEnv.MEMKIND_HBW_NODES=8-15`. Note that memory allocation fallback is also supported and cannot be turned off. If HBM is unavailable or fills up, the allocator will use default(DDR) memory. diff --git a/docs/get-started/VeloxIAA.md b/docs/get-started/VeloxIAA.md deleted file mode 100644 index ffd74bf6c62e..000000000000 --- a/docs/get-started/VeloxIAA.md +++ /dev/null @@ -1,75 +0,0 @@ ---- -layout: page -title: IAA Support in Velox Backend -nav_order: 1 -parent: Getting-Started ---- - - -# Intel® In-memory Analytics Accelerator (IAA/IAX) support - -Similar to Intel® QAT, Gluten supports using Intel® In-memory Analytics Accelerator (IAA, also called IAX) for data compression during Spark Shuffle. It benefits from IAA Hardware-based acceleration on compression/decompression, and uses Gzip as compression format for higher compression ratio to reduce the pressure on disks and network transmission. - -This feature is based on Intel® [QPL](https://github.com/intel/qpl). - -## Build Gluten with IAA - -Gluten will internally build and link to a specific version of QPL library, but extra environment setup is still required. Please refer to [QPL Installation Guide](https://intel.github.io/qpl/documentation/get_started_docs/installation.html) to install dependencies and configure accelerators. - -**This step is required if your application is running as Non-root user.** -Create a group for the users who have privilege to use IAA, and grant group iaa read/write access to the IAA Work-Queues. - -```bash -sudo groupadd iaa -sudo usermod -aG iaa username # need to relogin -sudo chgrp -R iaa /dev/iax -sudo chmod -R g+rw /dev/iax -``` - -After the set-up, you can now build Gluten with QAT. Below command is used to enable this feature - -```bash -cd /path/to/gluten - -## The script builds four jars for spark 3.2.2, 3.3.1, 3.4.3 and 3.5.1. -./dev/buildbundle-veloxbe.sh --enable_iaa=ON -``` - -## Enable IAA with Gzip Compression for shuffle compression - -1. To enable QAT at run-time, first make sure you have configured the IAA Work-Queues correctly, and the file permissions of /dev/iax/wqX.0 are correct. - -```bash -sudo ls -l /dev/iax -``` - -The output should be like: - -``` -total 0 -crw-rw---- 1 root iaa 509, 0 Apr 5 18:54 wq1.0 -crw-rw---- 1 root iaa 509, 5 Apr 5 18:54 wq11.0 -crw-rw---- 1 root iaa 509, 6 Apr 5 18:54 wq13.0 -crw-rw---- 1 root iaa 509, 7 Apr 5 18:54 wq15.0 -crw-rw---- 1 root iaa 509, 1 Apr 5 18:54 wq3.0 -crw-rw---- 1 root iaa 509, 2 Apr 5 18:54 wq5.0 -crw-rw---- 1 root iaa 509, 3 Apr 5 18:54 wq7.0 -crw-rw---- 1 root iaa 509, 4 Apr 5 18:54 wq9.0 -``` - -2. Extra Gluten configurations are required when starting Spark application - -``` ---conf spark.gluten.sql.columnar.shuffle.codec=gzip ---conf spark.gluten.sql.columnar.shuffle.codecBackend=iaa -``` - -## IAA references - -**Intel® IAA Enabling Guide** - -Check out the [Intel® In-Memory Analytics Accelerator (Intel® IAA) Enabling Guide](https://www.intel.com/content/www/us/en/developer/articles/technical/intel-iaa-enabling-guide.html) - -**Intel® QPL Documentation** - -Check out the [Intel® Query Processing Library (Intel® QPL) Documentation](https://intel.github.io/qpl/index.html) diff --git a/docs/get-started/VeloxQAT.md b/docs/get-started/VeloxQAT.md deleted file mode 100644 index 6d33654e59d5..000000000000 --- a/docs/get-started/VeloxQAT.md +++ /dev/null @@ -1,155 +0,0 @@ ---- -layout: page -title: QAT Support in Velox Backend -nav_order: 1 -parent: Getting-Started ---- - -# Intel® QuickAssist Technology (QAT) support - -Gluten supports using Intel® QuickAssist Technology (QAT) for data compression during Spark Shuffle. It benefits from QAT Hardware-based acceleration on compression/decompression, and uses Gzip as compression format for higher compression ratio to reduce the pressure on disks and network transmission. - -This feature is based on QAT driver library and [QATzip](https://github.com/intel/QATzip) library. Please manually download QAT driver for your system, and follow its README to build and install on all Driver and Worker node: [Intel® QuickAssist Technology Driver for Linux* – HW Version 2.0](https://www.intel.com/content/www/us/en/download/765501/intel-quickassist-technology-driver-for-linux-hw-version-2-0.html?wapkw=quickassist). - -## Software Requirements - -- Download QAT driver for your system, and follow its README to build and install on all Driver and Worker nodes: [Intel® QuickAssist Technology Driver for Linux* – HW Version 2.0](https://www.intel.com/content/www/us/en/download/765501/intel-quickassist-technology-driver-for-linux-hw-version-2-0.html?wapkw=quickassist). -- Below compression libraries need to be installed on all Driver and Worker nodes: - - Zlib* library of version 1.2.7 or higher - - ZSTD* library of version 1.5.4 or higher - - LZ4* library - -## Build Gluten with QAT - -1. Setup ICP_ROOT environment variable to the directory where QAT driver is extracted. This environment variable is required during building Gluten and running Spark applications. It's recommended to put it in .bashrc on Driver and Worker nodes. - -```bash -echo "export ICP_ROOT=/path/to/QAT_driver" >> ~/.bashrc -source ~/.bashrc - -# Also set for root if running as non-root user -sudo su - -echo "export ICP_ROOT=/path/to/QAT_driver" >> ~/.bashrc -exit -``` - -2. **This step is required if your application is running as Non-root user.** - The users must be added to the 'qat' group after QAT drvier is installed. And change the amount of max locked memory for the username that is included in the group name. This can be done by specifying the limit in /etc/security/limits.conf. - -```bash -sudo su - -usermod -aG qat username # need relogin to take effect - -# To set 500MB add a line like this in /etc/security/limits.conf -echo "@qat - memlock 500000" >> /etc/security/limits.conf - -exit -``` - -3. Enable huge page. This step is required to execute each time after system reboot. We recommend using systemctl to manage at system startup. You change the values for "max_huge_pages" and "max_huge_pages_per_process" to make sure there are enough resources for your workload. As for Spark applications, one process matches one executor. Within the executor, every task is allocated a maximum of 5 huge pages. - -```bash -sudo su - - -cat << EOF > /usr/local/bin/qat_startup.sh -#!/bin/bash -echo 1024 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages -rmmod usdm_drv -insmod $ICP_ROOT/build/usdm_drv.ko max_huge_pages=1024 max_huge_pages_per_process=32 -EOF - -chmod +x /usr/local/bin/qat_startup.sh - -cat << EOF > /etc/systemd/system/qat_startup.service -[Unit] -Description=Configure QAT - -[Service] -ExecStart=/usr/local/bin/qat_startup.sh - -[Install] -WantedBy=multi-user.target -EOF - -systemctl enable qat_startup.service -systemctl start qat_startup.service # setup immediately -systemctl status qat_startup.service - -exit -``` - -4. After the setup, you are now ready to build Gluten with QAT. Use the command below to enable this feature: - -```bash -cd /path/to/gluten - -## The script builds four jars for spark 3.2.2, 3.3.1, 3.4.3 and 3.5.1. -./dev/buildbundle-veloxbe.sh --enable_qat=ON -``` - -## Enable QAT with Gzip/Zstd for shuffle compression - -1. To offload shuffle compression into QAT, first make sure you have the right QAT configuration file at /etc/4xxx_devX.conf. We provide a [example configuration file](../qat/4x16.conf). This configuration sets up to 4 processes that can bind to 1 QAT, and each process can use up to 16 QAT DC instances. - -```bash -## run as root -## Overwrite QAT configuration file. -cd /etc -for i in {0..7}; do echo "4xxx_dev$i.conf"; done | xargs -i cp -f /path/to/gluten/docs/qat/4x16.conf {} -## Restart QAT after updating configuration files. -adf_ctl restart -``` - -2. Check QAT status and make sure the status is up - -```bash -adf_ctl status -``` - -The output should be like: - -``` -Checking status of all devices. -There is 8 QAT acceleration device(s) in the system: - qat_dev0 - type: 4xxx, inst_id: 0, node_id: 0, bsf: 0000:6b:00.0, #accel: 1 #engines: 9 state: up - qat_dev1 - type: 4xxx, inst_id: 1, node_id: 1, bsf: 0000:70:00.0, #accel: 1 #engines: 9 state: up - qat_dev2 - type: 4xxx, inst_id: 2, node_id: 2, bsf: 0000:75:00.0, #accel: 1 #engines: 9 state: up - qat_dev3 - type: 4xxx, inst_id: 3, node_id: 3, bsf: 0000:7a:00.0, #accel: 1 #engines: 9 state: up - qat_dev4 - type: 4xxx, inst_id: 4, node_id: 4, bsf: 0000:e8:00.0, #accel: 1 #engines: 9 state: up - qat_dev5 - type: 4xxx, inst_id: 5, node_id: 5, bsf: 0000:ed:00.0, #accel: 1 #engines: 9 state: up - qat_dev6 - type: 4xxx, inst_id: 6, node_id: 6, bsf: 0000:f2:00.0, #accel: 1 #engines: 9 state: up - qat_dev7 - type: 4xxx, inst_id: 7, node_id: 7, bsf: 0000:f7:00.0, #accel: 1 #engines: 9 state: up -``` - -3. Extra Gluten configurations are required when starting Spark application - -``` ---conf spark.gluten.sql.columnar.shuffle.codec=gzip # Valid options are gzip and zstd ---conf spark.gluten.sql.columnar.shuffle.codecBackend=qat -``` - -4. You can use below command to check whether QAT is working normally at run-time. The value of fw_counters should continue to increase during shuffle. - -``` -while :; do cat /sys/kernel/debug/qat_4xxx_0000:6b:00.0/fw_counters; sleep 1; done -``` - -## QAT driver references - -**Documentation** - -[README Text Files (README_QAT20.L.1.0.0-00021.txt)](https://downloadmirror.intel.com/765523/README_QAT20.L.1.0.0-00021.txt) - -**Release Notes** - -Check out the [Intel® QuickAssist Technology Software for Linux*](https://www.intel.com/content/www/us/en/content-details/632507/intel-quickassist-technology-intel-qat-software-for-linux-release-notes-hardware-version-2-0.html) - Release Notes for the latest changes in this release. - -**Getting Started Guide** - -Check out the [Intel® QuickAssist Technology Software for Linux*](https://www.intel.com/content/www/us/en/content-details/632506/intel-quickassist-technology-intel-qat-software-for-linux-getting-started-guide-hardware-version-2-0.html) - Getting Started Guide for detailed installation instructions. - -**Programmer's Guide** - -Check out the [Intel® QuickAssist Technology Software for Linux*](https://www.intel.com/content/www/us/en/content-details/743912/intel-quickassist-technology-intel-qat-software-for-linux-programmers-guide-hardware-version-2-0.html) - Programmer's Guide for software usage guidelines. - -For more Intel® QuickAssist Technology resources go to [Intel® QuickAssist Technology (Intel® QAT)](https://developer.intel.com/quickassist) diff --git a/gluten-arrow/src/main/java/org/apache/gluten/vectorized/LocalPartitionWriterJniWrapper.java b/gluten-arrow/src/main/java/org/apache/gluten/vectorized/LocalPartitionWriterJniWrapper.java index 3269e7b17610..38bf22aeade5 100644 --- a/gluten-arrow/src/main/java/org/apache/gluten/vectorized/LocalPartitionWriterJniWrapper.java +++ b/gluten-arrow/src/main/java/org/apache/gluten/vectorized/LocalPartitionWriterJniWrapper.java @@ -38,7 +38,6 @@ public long rtHandle() { public native long createPartitionWriter( int numPartitions, String codec, - String codecBackend, int compressionLevel, int compressionBufferSize, int compressionThreshold, diff --git a/gluten-arrow/src/main/java/org/apache/gluten/vectorized/ShuffleReaderJniWrapper.java b/gluten-arrow/src/main/java/org/apache/gluten/vectorized/ShuffleReaderJniWrapper.java index 46787d4209d5..66c6f249562f 100644 --- a/gluten-arrow/src/main/java/org/apache/gluten/vectorized/ShuffleReaderJniWrapper.java +++ b/gluten-arrow/src/main/java/org/apache/gluten/vectorized/ShuffleReaderJniWrapper.java @@ -38,7 +38,6 @@ public long rtHandle() { public native long make( long cSchema, String compressionType, - String compressionCodecBackend, int batchSize, long readerBufferSize, long deserializerBufferSize, diff --git a/gluten-substrait/src/main/scala/org/apache/gluten/config/GlutenConfig.scala b/gluten-substrait/src/main/scala/org/apache/gluten/config/GlutenConfig.scala index e81d6b06644b..146bba2c8a83 100644 --- a/gluten-substrait/src/main/scala/org/apache/gluten/config/GlutenConfig.scala +++ b/gluten-substrait/src/main/scala/org/apache/gluten/config/GlutenConfig.scala @@ -204,15 +204,6 @@ class GlutenConfig(conf: SQLConf) extends GlutenCoreConfig(conf) { def columnarShuffleCompressionMode: String = getConf(COLUMNAR_SHUFFLE_COMPRESSION_MODE) - def columnarShuffleCodecBackend: Option[String] = getConf(COLUMNAR_SHUFFLE_CODEC_BACKEND) - .filter(Set(GLUTEN_QAT_BACKEND_NAME, GLUTEN_IAA_BACKEND_NAME).contains(_)) - - def columnarShuffleEnableQat: Boolean = - columnarShuffleCodecBackend.contains(GlutenConfig.GLUTEN_QAT_BACKEND_NAME) - - def columnarShuffleEnableIaa: Boolean = - columnarShuffleCodecBackend.contains(GlutenConfig.GLUTEN_IAA_BACKEND_NAME) - def columnarShuffleCompressionThreshold: Int = getConf(COLUMNAR_SHUFFLE_COMPRESSION_THRESHOLD) @@ -436,13 +427,6 @@ object GlutenConfig { val SPARK_GCS_AUTH_SERVICE_ACCOUNT_JSON_KEYFILE: String = HADOOP_PREFIX + GCS_PREFIX + AUTH_SERVICE_ACCOUNT_JSON_KEYFILE - // QAT config - val GLUTEN_QAT_BACKEND_NAME = "qat" - val GLUTEN_QAT_SUPPORTED_CODEC: Set[String] = Set("gzip", "zstd") - // IAA config - val GLUTEN_IAA_BACKEND_NAME = "iaa" - val GLUTEN_IAA_SUPPORTED_CODEC: Set[String] = Set("gzip") - // Private Spark configs. val SPARK_OVERHEAD_SIZE_KEY = "spark.executor.memoryOverhead" val SPARK_OVERHEAD_FACTOR_KEY = "spark.executor.memoryOverheadFactor" @@ -604,7 +588,6 @@ object GlutenConfig { GlutenCoreConfig.NUM_TASK_SLOTS_PER_EXECUTOR.key, GlutenCoreConfig.NUM_TASK_SLOTS_PER_EXECUTOR.defaultValueString)), (COLUMNAR_SHUFFLE_CODEC.key, ""), - (COLUMNAR_SHUFFLE_CODEC_BACKEND.key, ""), (DEBUG_CUDF.key, DEBUG_CUDF.defaultValueString), ("spark.hadoop.input.connect.timeout", "180000"), ("spark.hadoop.input.read.timeout", "180000"), @@ -1020,19 +1003,7 @@ object GlutenConfig { val COLUMNAR_SHUFFLE_CODEC = buildConf("spark.gluten.sql.columnar.shuffle.codec") .internal() - .doc( - "By default, the supported codecs are lz4 and zstd. " + - "When spark.gluten.sql.columnar.shuffle.codecBackend=qat," + - "the supported codecs are gzip and zstd. " + - "When spark.gluten.sql.columnar.shuffle.codecBackend=iaa," + - "the supported codec is gzip.") - .stringConf - .transform(_.toLowerCase(Locale.ROOT)) - .createOptional - - val COLUMNAR_SHUFFLE_CODEC_BACKEND = - buildConf("spark.gluten.sql.columnar.shuffle.codecBackend") - .internal() + .doc("Supported codecs are lz4 and zstd.") .stringConf .transform(_.toLowerCase(Locale.ROOT)) .createOptional diff --git a/gluten-substrait/src/main/scala/org/apache/spark/shuffle/GlutenShuffleUtils.scala b/gluten-substrait/src/main/scala/org/apache/spark/shuffle/GlutenShuffleUtils.scala index b06ccd8b292e..61d6f1247fff 100644 --- a/gluten-substrait/src/main/scala/org/apache/spark/shuffle/GlutenShuffleUtils.scala +++ b/gluten-substrait/src/main/scala/org/apache/spark/shuffle/GlutenShuffleUtils.scala @@ -58,16 +58,10 @@ object GlutenShuffleUtils { glutenConfig.columnarShuffleCodec match { case Some(codec) => val glutenCodecKey = GlutenConfig.COLUMNAR_SHUFFLE_CODEC.key - if (glutenConfig.columnarShuffleEnableQat) { - checkCodecValues(glutenCodecKey, codec, GlutenConfig.GLUTEN_QAT_SUPPORTED_CODEC) - } else if (glutenConfig.columnarShuffleEnableIaa) { - checkCodecValues(glutenCodecKey, codec, GlutenConfig.GLUTEN_IAA_SUPPORTED_CODEC) - } else { - checkCodecValues( - glutenCodecKey, - codec, - BackendsApiManager.getSettings.shuffleSupportedCodec()) - } + checkCodecValues( + glutenCodecKey, + codec, + BackendsApiManager.getSettings.shuffleSupportedCodec()) codec case None => val sparkCodecKey = IO_COMPRESSION_CODEC.key diff --git a/tools/workload/benchmark_velox/params.yaml.template b/tools/workload/benchmark_velox/params.yaml.template index ce92bdeacafd..799a66de1254 100644 --- a/tools/workload/benchmark_velox/params.yaml.template +++ b/tools/workload/benchmark_velox/params.yaml.template @@ -52,8 +52,6 @@ gluten_offheap_ratio: 7.0 spark_codec: lz4 # spark.gluten.sql.columnar.shuffle.codec gluten_codec: lz4 -# spark.gluten.sql.columnar.shuffle.codecBackend -gluten_codec_backend: '' # spark.gluten.sql.columnar.maxBatchSize max_batch_size: 4096 # spark.app.name, empty to use default name. diff --git a/tools/workload/benchmark_velox/sample/tpch_q1.html b/tools/workload/benchmark_velox/sample/tpch_q1.html index 545d60812ffa..180d2c9f2583 100644 --- a/tools/workload/benchmark_velox/sample/tpch_q1.html +++ b/tools/workload/benchmark_velox/sample/tpch_q1.html @@ -13226,77 +13226,115 @@

Self app info
-
[Stage 0:>                                                          (0 + 1) / 1]
+
+[Stage 0:>                                                          (0 + 1) / 1]
+
-
                                                                                
+
+                                                                                
+
-
[Stage 1:>                                                          (0 + 1) / 1]
+
+[Stage 1:>                                                          (0 + 1) / 1]
+
-
                                                                                
+
+                                                                                
+
-
[Stage 4:>                                                          (0 + 1) / 1]
+
+[Stage 4:>                                                          (0 + 1) / 1]
+
-
                                                                                
+
+                                                                                
+
-
[Stage 5:>                                                          (0 + 1) / 1]
+
+[Stage 5:>                                                          (0 + 1) / 1]
+
-
                                                                                
+
+                                                                                
+
-
[Stage 17:>                                                         (0 + 1) / 1]
+
+[Stage 17:>                                                         (0 + 1) / 1]
+
-
                                                                                
+
+                                                                                
+
-
[Stage 39:>                                                      (0 + 16) / 200]

[Stage 39:=>                                                     (6 + 16) / 200]
+
+[Stage 39:>                                                      (0 + 16) / 200]
+
+[Stage 39:=>                                                     (6 + 16) / 200]
+
-
[Stage 39:===>                                                  (14 + 16) / 200]
+
+[Stage 39:===>                                                  (14 + 16) / 200]
+
-
[Stage 39:========>                                             (33 + 16) / 200]

[Stage 39:==================>                                   (67 + 16) / 200]
+
+[Stage 39:========>                                             (33 + 16) / 200]
+
+[Stage 39:==================>                                   (67 + 16) / 200]
+
-
[Stage 39:==========================>                           (97 + 16) / 200]

[Stage 39:==================================>                  (131 + 16) / 200]
+
+[Stage 39:==========================>                           (97 + 16) / 200]
+
+[Stage 39:==================================>                  (131 + 16) / 200]
+
-
[Stage 39:=================================================>   (185 + 15) / 200]

                                                                                
+
+[Stage 39:=================================================>   (185 + 15) / 200]
+
+                                                                                
+
@@ -13304,37 +13342,63 @@

Self app info
-
[Stage 42:(177 + 5) / 200][Stage 43:>   (0 + 1) / 1][Stage 44:>(0 + 11) / 200]

                                                                                
+
+[Stage 42:(177 + 5) / 200][Stage 43:>   (0 + 1) / 1][Stage 44:>(0 + 11) / 200]
+
+                                                                                
+
-
[Stage 44:(113 + 12) / 200][Stage 45:>   (0 + 1) / 1][Stage 46:> (0 + 3) / 200]

[Stage 44:(182 + 5) / 200][Stage 46:>(4 + 11) / 200][Stage 47:> (0 + 0) / 200]
+
+[Stage 44:(113 + 12) / 200][Stage 45:>   (0 + 1) / 1][Stage 46:> (0 + 3) / 200]
+
+[Stage 44:(182 + 5) / 200][Stage 46:>(4 + 11) / 200][Stage 47:> (0 + 0) / 200]
+
-
[Stage 46:(43 + 16) / 200][Stage 47:> (0 + 0) / 200][Stage 48:> (0 + 0) / 200]

[Stage 46:(110 + 8) / 200][Stage 47:> (0 + 8) / 200][Stage 48:> (0 + 0) / 200]
+
+[Stage 46:(43 + 16) / 200][Stage 47:> (0 + 0) / 200][Stage 48:> (0 + 0) / 200]
+
+[Stage 46:(110 + 8) / 200][Stage 47:> (0 + 8) / 200][Stage 48:> (0 + 0) / 200]
+
-
[Stage 46:(155 + 8) / 200][Stage 47:>(47 + 8) / 200][Stage 48:> (0 + 0) / 200]

[Stage 46:(194 + 4) / 200][Stage 47:>(73 + 4) / 200][Stage 48:> (8 + 8) / 200]
+
+[Stage 46:(155 + 8) / 200][Stage 47:>(47 + 8) / 200][Stage 48:> (0 + 0) / 200]
+
+[Stage 46:(194 + 4) / 200][Stage 47:>(73 + 4) / 200][Stage 48:> (8 + 8) / 200]
+
-
[Stage 47:(114 + 8) / 200][Stage 48:>(57 + 4) / 200][Stage 49:>  (0 + 4) / 16]

[Stage 47:(185 + 4) / 200][Stage 48:>(73 + 4) / 200][Stage 49:>  (0 + 8) / 16]
+
+[Stage 47:(114 + 8) / 200][Stage 48:>(57 + 4) / 200][Stage 49:>  (0 + 4) / 16]
+
+[Stage 47:(185 + 4) / 200][Stage 48:>(73 + 4) / 200][Stage 49:>  (0 + 8) / 16]
+
-
[Stage 48:(126 + 8) / 200][Stage 49:>  (0 + 8) / 16][Stage 51:>   (0 + 0) / 1]

[Stage 48:(184 + 4) / 200][Stage 49:> (4 + 12) / 16][Stage 51:>   (0 + 0) / 1]
+
+[Stage 48:(126 + 8) / 200][Stage 49:>  (0 + 8) / 16][Stage 51:>   (0 + 0) / 1]
+
+[Stage 48:(184 + 4) / 200][Stage 49:> (4 + 12) / 16][Stage 51:>   (0 + 0) / 1]
+
-
                                                                                
+
+                                                                                
+
@@ -13492,12 +13556,18 @@

Self app info
-
[Stage 92:(161 + 4) / 200][Stage 93:>(68 + 9) / 200][Stage 94:> (8 + 4) / 200]

[Stage 93:(151 + 4) / 200][Stage 94:>(66 + 8) / 200][Stage 95:>  (1 + 4) / 16]
+
+[Stage 92:(161 + 4) / 200][Stage 93:>(68 + 9) / 200][Stage 94:> (8 + 4) / 200]
+
+[Stage 93:(151 + 4) / 200][Stage 94:>(66 + 8) / 200][Stage 95:>  (1 + 4) / 16]
+
-
                                                                                
+
+                                                                                
+
@@ -13508,167 +13578,289 @@

Self app info
-
[Stage 129:>                (0 + 2) / 2][Stage 130:>                (0 + 2) / 2]

[Stage 129:>  (0 + 2) / 2][Stage 130:>  (0 + 2) / 2][Stage 131:>  (0 + 4) / 4]
+
+[Stage 129:>                (0 + 2) / 2][Stage 130:>                (0 + 2) / 2]
+
+[Stage 129:>  (0 + 2) / 2][Stage 130:>  (0 + 2) / 2][Stage 131:>  (0 + 4) / 4]
+
-
[Stage 129:=> (1 + 1) / 2][Stage 130:=> (1 + 1) / 2][Stage 131:>  (1 + 3) / 4]

[Stage 129:========>        (1 + 1) / 2][Stage 131:====>            (1 + 3) / 4]
+
+[Stage 129:=> (1 + 1) / 2][Stage 130:=> (1 + 1) / 2][Stage 131:>  (1 + 3) / 4]
+
+[Stage 129:========>        (1 + 1) / 2][Stage 131:====>            (1 + 3) / 4]
+
-
                                                                                
+
+                                                                                
+
-
[Stage 143:==>                                                  (16 + 16) / 400]

[Stage 143:==>                                                  (17 + 16) / 400]
+
+[Stage 143:==>                                                  (16 + 16) / 400]
+
+[Stage 143:==>                                                  (17 + 16) / 400]
+
-
[Stage 143:===>                                                 (24 + 16) / 400]

[Stage 143:====>                                                (34 + 16) / 400]
+
+[Stage 143:===>                                                 (24 + 16) / 400]
+
+[Stage 143:====>                                                (34 + 16) / 400]
+
-
[Stage 143:=====>                                               (43 + 16) / 400]

[Stage 143:=======>                                             (53 + 16) / 400]
+
+[Stage 143:=====>                                               (43 + 16) / 400]
+
+[Stage 143:=======>                                             (53 + 16) / 400]
+
-
[Stage 143:========>                                            (65 + 16) / 400]

[Stage 143:=========>                                           (72 + 16) / 400]
+
+[Stage 143:========>                                            (65 + 16) / 400]
+
+[Stage 143:=========>                                           (72 + 16) / 400]
+
-
[Stage 143:==========>                                          (83 + 16) / 400]

[Stage 143:===========>                                         (90 + 16) / 400]
+
+[Stage 143:==========>                                          (83 + 16) / 400]
+
+[Stage 143:===========>                                         (90 + 16) / 400]
+
-
[Stage 143:=============>                                       (99 + 16) / 400]

[Stage 143:=============>                                      (106 + 16) / 400]
+
+[Stage 143:=============>                                       (99 + 16) / 400]
+
+[Stage 143:=============>                                      (106 + 16) / 400]
+
-
[Stage 143:==============>                                     (113 + 16) / 400]

[Stage 143:===============>                                    (118 + 16) / 400]
+
+[Stage 143:==============>                                     (113 + 16) / 400]
+
+[Stage 143:===============>                                    (118 + 16) / 400]
+
-
[Stage 143:================>                                   (126 + 16) / 400]

[Stage 143:=================>                                  (132 + 16) / 400]
+
+[Stage 143:================>                                   (126 + 16) / 400]
+
+[Stage 143:=================>                                  (132 + 16) / 400]
+
-
[Stage 143:==================>                                 (140 + 16) / 400]

[Stage 143:==================>                                 (146 + 16) / 400]
+
+[Stage 143:==================>                                 (140 + 16) / 400]
+
+[Stage 143:==================>                                 (146 + 16) / 400]
+
-
[Stage 143:===================>                                (153 + 16) / 400]

[Stage 143:====================>                               (160 + 16) / 400]
+
+[Stage 143:===================>                                (153 + 16) / 400]
+
+[Stage 143:====================>                               (160 + 16) / 400]
+
-
[Stage 143:======================>                             (170 + 16) / 400]

[Stage 143:======================>                             (173 + 16) / 400]
+
+[Stage 143:======================>                             (170 + 16) / 400]
+
+[Stage 143:======================>                             (173 + 16) / 400]
+
-
[Stage 143:=======================>                            (182 + 16) / 400]

[Stage 143:========================>                           (186 + 16) / 400]
+
+[Stage 143:=======================>                            (182 + 16) / 400]
+
+[Stage 143:========================>                           (186 + 16) / 400]
+
-
[Stage 143:=========================>                          (194 + 16) / 400]

[Stage 143:=========================>                          (197 + 16) / 400]
+
+[Stage 143:=========================>                          (194 + 16) / 400]
+
+[Stage 143:=========================>                          (197 + 16) / 400]
+
-
[Stage 143:==========================>                         (204 + 16) / 400]

[Stage 143:===========================>                        (211 + 16) / 400]
+
+[Stage 143:==========================>                         (204 + 16) / 400]
+
+[Stage 143:===========================>                        (211 + 16) / 400]
+
-
[Stage 143:===========================>                        (214 + 16) / 400]

[Stage 143:============================>                       (222 + 16) / 400]
+
+[Stage 143:===========================>                        (214 + 16) / 400]
+
+[Stage 143:============================>                       (222 + 16) / 400]
+
-
[Stage 143:=============================>                      (230 + 16) / 400]

[Stage 143:==============================>                     (236 + 16) / 400]
+
+[Stage 143:=============================>                      (230 + 16) / 400]
+
+[Stage 143:==============================>                     (236 + 16) / 400]
+
-
[Stage 143:===============================>                    (243 + 16) / 400]

[Stage 143:================================>                   (249 + 16) / 400]
+
+[Stage 143:===============================>                    (243 + 16) / 400]
+
+[Stage 143:================================>                   (249 + 16) / 400]
+
-
[Stage 143:=================================>                  (256 + 16) / 400]

[Stage 143:==================================>                 (263 + 16) / 400]
+
+[Stage 143:=================================>                  (256 + 16) / 400]
+
+[Stage 143:==================================>                 (263 + 16) / 400]
+
-
[Stage 143:===================================>                (272 + 16) / 400]

[Stage 143:====================================>               (279 + 16) / 400]
+
+[Stage 143:===================================>                (272 + 16) / 400]
+
+[Stage 143:====================================>               (279 + 16) / 400]
+
-
[Stage 143:======================================>             (294 + 16) / 400]

[Stage 143:======================================>             (299 + 16) / 400]
+
+[Stage 143:======================================>             (294 + 16) / 400]
+
+[Stage 143:======================================>             (299 + 16) / 400]
+
-
[Stage 143:========================================>           (311 + 16) / 400]

[Stage 143:=========================================>          (322 + 16) / 400]
+
+[Stage 143:========================================>           (311 + 16) / 400]
+
+[Stage 143:=========================================>          (322 + 16) / 400]
+
-
[Stage 143:===========================================>        (333 + 17) / 400]

[Stage 143:=============================================>      (348 + 16) / 400]
+
+[Stage 143:===========================================>        (333 + 17) / 400]
+
+[Stage 143:=============================================>      (348 + 16) / 400]
+
-
[Stage 143:==============================================>     (360 + 16) / 400]

[Stage 143:================================================>   (372 + 16) / 400]
+
+[Stage 143:==============================================>     (360 + 16) / 400]
+
+[Stage 143:================================================>   (372 + 16) / 400]
+
-
[Stage 143:==================================================> (386 + 14) / 400]
+
+[Stage 143:==================================================> (386 + 14) / 400]
+
-
[Stage 148:>                                                        (0 + 1) / 1]
+
+[Stage 148:>                                                        (0 + 1) / 1]
+
-
[Stage 154:>                                                        (0 + 3) / 3]
+
+[Stage 154:>                                                        (0 + 3) / 3]
+
-
[Stage 154:===================>                                     (1 + 2) / 3]

[Stage 154:======================================>                  (2 + 1) / 3]
+
+[Stage 154:===================>                                     (1 + 2) / 3]
+
+[Stage 154:======================================>                  (2 + 1) / 3]
+
-
                                                                                
+
+                                                                                
+
-
[Stage 157:>                                                        (0 + 3) / 3]

[Stage 157:===================>                                     (1 + 2) / 3]
+
+[Stage 157:>                                                        (0 + 3) / 3]
+
+[Stage 157:===================>                                     (1 + 2) / 3]
+
-
[Stage 157:======================================>                  (2 + 1) / 3]

                                                                                
+
+[Stage 157:======================================>                  (2 + 1) / 3]
+
+                                                                                
+
@@ -13896,22 +14088,30 @@

Self app info
-
[Stage 330:>                                                        (0 + 1) / 1]
+
+[Stage 330:>                                                        (0 + 1) / 1]
+
-
                                                                                
+
+                                                                                
+
-
[Stage 341:>                                                        (0 + 1) / 1]
+
+[Stage 341:>                                                        (0 + 1) / 1]
+
-
                                                                                
+
+                                                                                
+
@@ -13922,22 +14122,30 @@

Self app info
-
[Stage 388:>                                                        (0 + 1) / 1]
+
+[Stage 388:>                                                        (0 + 1) / 1]
+
-
                                                                                
+
+                                                                                
+
-
[Stage 396:>                                                        (0 + 1) / 1]
+
+[Stage 396:>                                                        (0 + 1) / 1]
+
-
                                                                                
+
+                                                                                
+
@@ -13947,7 +14155,11 @@

Self app info
-
[Stage 490:===================>                                     (1 + 2) / 3]

                                                                                
+
+[Stage 490:===================>                                     (1 + 2) / 3]
+
+                                                                                
+
@@ -13970,227 +14182,387 @@

Self app info
-
[Stage 605:==>                                                   (11 + 0) / 200]

[Stage 531:(174 + 16) / 200][Stage 532:>(0 + 0) / 200][Stage 533:>(0 + 0) / 200]
+
+[Stage 605:==>                                                   (11 + 0) / 200]
+
+[Stage 531:(174 + 16) / 200][Stage 532:>(0 + 0) / 200][Stage 533:>(0 + 0) / 200]
+
-
[Stage 532:(102 + 16) / 200][Stage 533:>(0 + 0) / 200][Stage 534:>(0 + 0) / 200]

[Stage 533:(72 + 16) / 200][Stage 534:>(0 + 0) / 200][Stage 535:>(0 + 0) / 200]
+
+[Stage 532:(102 + 16) / 200][Stage 533:>(0 + 0) / 200][Stage 534:>(0 + 0) / 200]
+
+[Stage 533:(72 + 16) / 200][Stage 534:>(0 + 0) / 200][Stage 535:>(0 + 0) / 200]
+
-
[Stage 534:(63 + 16) / 200][Stage 535:>(0 + 0) / 200][Stage 536:>(0 + 0) / 200]

[Stage 535:(75 + 16) / 200][Stage 536:>(0 + 0) / 200][Stage 537:>(0 + 0) / 200]
+
+[Stage 534:(63 + 16) / 200][Stage 535:>(0 + 0) / 200][Stage 536:>(0 + 0) / 200]
+
+[Stage 535:(75 + 16) / 200][Stage 536:>(0 + 0) / 200][Stage 537:>(0 + 0) / 200]
+
-
[Stage 536:(102 + 17) / 200][Stage 537:>(0 + 0) / 200][Stage 538:>(3 + 0) / 200]

[Stage 537:(114 + 16) / 200][Stage 538:>(3 + 0) / 200][Stage 539:>(0 + 0) / 200]
+
+[Stage 536:(102 + 17) / 200][Stage 537:>(0 + 0) / 200][Stage 538:>(3 + 0) / 200]
+
+[Stage 537:(114 + 16) / 200][Stage 538:>(3 + 0) / 200][Stage 539:>(0 + 0) / 200]
+
-
[Stage 538:(105 + 16) / 200][Stage 539:>(0 + 0) / 200][Stage 540:>(0 + 0) / 200]

[Stage 539:(67 + 16) / 200][Stage 540:>(0 + 0) / 200][Stage 541:>(0 + 0) / 200]
+
+[Stage 538:(105 + 16) / 200][Stage 539:>(0 + 0) / 200][Stage 540:>(0 + 0) / 200]
+
+[Stage 539:(67 + 16) / 200][Stage 540:>(0 + 0) / 200][Stage 541:>(0 + 0) / 200]
+
-
[Stage 540:(59 + 16) / 200][Stage 541:>(0 + 0) / 200][Stage 542:>(0 + 0) / 200]

[Stage 541:(104 + 16) / 200][Stage 542:>(0 + 0) / 200][Stage 543:>(0 + 0) / 200]
+
+[Stage 540:(59 + 16) / 200][Stage 541:>(0 + 0) / 200][Stage 542:>(0 + 0) / 200]
+
+[Stage 541:(104 + 16) / 200][Stage 542:>(0 + 0) / 200][Stage 543:>(0 + 0) / 200]
+
-
[Stage 542:(115 + 16) / 200][Stage 543:>(0 + 0) / 200][Stage 544:>(0 + 0) / 200]

[Stage 543:(148 + 16) / 200][Stage 544:>(0 + 0) / 200][Stage 545:>(0 + 0) / 200]
+
+[Stage 542:(115 + 16) / 200][Stage 543:>(0 + 0) / 200][Stage 544:>(0 + 0) / 200]
+
+[Stage 543:(148 + 16) / 200][Stage 544:>(0 + 0) / 200][Stage 545:>(0 + 0) / 200]
+
-
[Stage 545:(0 + 16) / 200][Stage 546:>(0 + 0) / 200][Stage 547:>(0 + 0) / 200]

[Stage 546:(38 + 16) / 200][Stage 547:>(0 + 0) / 200][Stage 548:>(0 + 0) / 200]
+
+[Stage 545:(0 + 16) / 200][Stage 546:>(0 + 0) / 200][Stage 547:>(0 + 0) / 200]
+
+[Stage 546:(38 + 16) / 200][Stage 547:>(0 + 0) / 200][Stage 548:>(0 + 0) / 200]
+
-
[Stage 547:(58 + 17) / 200][Stage 548:>(0 + 0) / 200][Stage 549:>(0 + 0) / 200]

[Stage 548:(94 + 16) / 200][Stage 549:>(0 + 0) / 200][Stage 559:>(0 + 0) / 200]
+
+[Stage 547:(58 + 17) / 200][Stage 548:>(0 + 0) / 200][Stage 549:>(0 + 0) / 200]
+
+[Stage 548:(94 + 16) / 200][Stage 549:>(0 + 0) / 200][Stage 559:>(0 + 0) / 200]
+
-
[Stage 549:(113 + 17) / 200][Stage 557:>(0 + 0) / 200][Stage 559:>(0 + 0) / 200]

[Stage 555:>(0 + 0) / 200][Stage 557:>(0 + 0) / 200][Stage 559:>(0 + 0) / 200]
+
+[Stage 549:(113 + 17) / 200][Stage 557:>(0 + 0) / 200][Stage 559:>(0 + 0) / 200]
+
+[Stage 555:>(0 + 0) / 200][Stage 557:>(0 + 0) / 200][Stage 559:>(0 + 0) / 200]
+
-
[Stage 551:(16 + 1) / 200][Stage 553:>(0 + 0) / 200][Stage 555:>(0 + 0) / 200]

[Stage 551:(179 + 16) / 200][Stage 553:>(0 + 0) / 200][Stage 555:>(0 + 0) / 200]
+
+[Stage 551:(16 + 1) / 200][Stage 553:>(0 + 0) / 200][Stage 555:>(0 + 0) / 200]
+
+[Stage 551:(179 + 16) / 200][Stage 553:>(0 + 0) / 200][Stage 555:>(0 + 0) / 200]
+
-
[Stage 553:(16 + 0) / 200][Stage 555:>(0 + 0) / 200][Stage 557:>(0 + 0) / 200]

[Stage 553:(54 + 17) / 200][Stage 555:>(0 + 0) / 200][Stage 557:>(0 + 0) / 200]
+
+[Stage 553:(16 + 0) / 200][Stage 555:>(0 + 0) / 200][Stage 557:>(0 + 0) / 200]
+
+[Stage 553:(54 + 17) / 200][Stage 555:>(0 + 0) / 200][Stage 557:>(0 + 0) / 200]
+
-
[Stage 555:>(8 + 8) / 200][Stage 557:>(0 + 0) / 200][Stage 559:>(0 + 0) / 200]

[Stage 555:(16 + 0) / 200][Stage 557:>(0 + 0) / 200][Stage 559:>(0 + 0) / 200]
+
+[Stage 555:>(8 + 8) / 200][Stage 557:>(0 + 0) / 200][Stage 559:>(0 + 0) / 200]
+
+[Stage 555:(16 + 0) / 200][Stage 557:>(0 + 0) / 200][Stage 559:>(0 + 0) / 200]
+
-
[Stage 555:(199 + 1) / 200][Stage 557:(0 + 15) / 200][Stage 559:>(0 + 0) / 200]

[Stage 557:(16 + 0) / 200][Stage 559:>(0 + 0) / 200][Stage 560:>(0 + 0) / 200]
+
+[Stage 555:(199 + 1) / 200][Stage 557:(0 + 15) / 200][Stage 559:>(0 + 0) / 200]
+
+[Stage 557:(16 + 0) / 200][Stage 559:>(0 + 0) / 200][Stage 560:>(0 + 0) / 200]
+
-
[Stage 557:(84 + 16) / 200][Stage 559:>(0 + 0) / 200][Stage 560:>(0 + 0) / 200]

[Stage 559:(16 + 0) / 200][Stage 560:>(0 + 0) / 200][Stage 564:>(0 + 0) / 200]
+
+[Stage 557:(84 + 16) / 200][Stage 559:>(0 + 0) / 200][Stage 560:>(0 + 0) / 200]
+
+[Stage 559:(16 + 0) / 200][Stage 560:>(0 + 0) / 200][Stage 564:>(0 + 0) / 200]
+
-
[Stage 559:(29 + 16) / 200][Stage 560:>(0 + 0) / 200][Stage 564:>(0 + 0) / 200]

[Stage 560:(85 + 16) / 200][Stage 564:>(0 + 0) / 200][Stage 566:>(0 + 0) / 200]
+
+[Stage 559:(29 + 16) / 200][Stage 560:>(0 + 0) / 200][Stage 564:>(0 + 0) / 200]
+
+[Stage 560:(85 + 16) / 200][Stage 564:>(0 + 0) / 200][Stage 566:>(0 + 0) / 200]
+
-
[Stage 564:>(0 + 0) / 200][Stage 566:>(0 + 0) / 200][Stage 568:>(0 + 0) / 200]
+
+[Stage 564:>(0 + 0) / 200][Stage 566:>(0 + 0) / 200][Stage 568:>(0 + 0) / 200]
+
-
[Stage 564:(16 + 0) / 200][Stage 566:>(0 + 0) / 200][Stage 568:>(0 + 0) / 200]
+
+[Stage 564:(16 + 0) / 200][Stage 566:>(0 + 0) / 200][Stage 568:>(0 + 0) / 200]
+
-
[Stage 564:(149 + 16) / 200][Stage 566:>(0 + 0) / 200][Stage 568:>(0 + 0) / 200]

[Stage 566:(16 + 0) / 200][Stage 568:>(0 + 0) / 200][Stage 569:>(0 + 0) / 200]
+
+[Stage 564:(149 + 16) / 200][Stage 566:>(0 + 0) / 200][Stage 568:>(0 + 0) / 200]
+
+[Stage 566:(16 + 0) / 200][Stage 568:>(0 + 0) / 200][Stage 569:>(0 + 0) / 200]
+
-
[Stage 566:(71 + 16) / 200][Stage 568:>(0 + 0) / 200][Stage 569:>(0 + 0) / 200]

[Stage 568:(16 + 0) / 200][Stage 569:>(0 + 0) / 200][Stage 573:>(0 + 0) / 200]
+
+[Stage 566:(71 + 16) / 200][Stage 568:>(0 + 0) / 200][Stage 569:>(0 + 0) / 200]
+
+[Stage 568:(16 + 0) / 200][Stage 569:>(0 + 0) / 200][Stage 573:>(0 + 0) / 200]
+
-
[Stage 568:(16 + 2) / 200][Stage 569:>(0 + 0) / 200][Stage 573:>(0 + 0) / 200]

[Stage 569:(42 + 18) / 200][Stage 573:>(0 + 0) / 200][Stage 575:>(0 + 0) / 200]
+
+[Stage 568:(16 + 2) / 200][Stage 569:>(0 + 0) / 200][Stage 573:>(0 + 0) / 200]
+
+[Stage 569:(42 + 18) / 200][Stage 573:>(0 + 0) / 200][Stage 575:>(0 + 0) / 200]
+
-
[Stage 573:>(0 + 0) / 200][Stage 575:>(0 + 0) / 200][Stage 577:>(0 + 0) / 200]
+
+[Stage 573:>(0 + 0) / 200][Stage 575:>(0 + 0) / 200][Stage 577:>(0 + 0) / 200]
+
-
[Stage 573:(0 + 16) / 200][Stage 575:>(0 + 0) / 200][Stage 577:>(0 + 0) / 200]

[Stage 573:(16 + 0) / 200][Stage 575:>(0 + 0) / 200][Stage 577:>(0 + 0) / 200]
+
+[Stage 573:(0 + 16) / 200][Stage 575:>(0 + 0) / 200][Stage 577:>(0 + 0) / 200]
+
+[Stage 573:(16 + 0) / 200][Stage 575:>(0 + 0) / 200][Stage 577:>(0 + 0) / 200]
+
-
[Stage 573:(67 + 16) / 200][Stage 575:>(0 + 0) / 200][Stage 577:>(0 + 0) / 200]

[Stage 575:(16 + 0) / 200][Stage 577:>(0 + 0) / 200][Stage 578:>(0 + 0) / 200]
+
+[Stage 573:(67 + 16) / 200][Stage 575:>(0 + 0) / 200][Stage 577:>(0 + 0) / 200]
+
+[Stage 575:(16 + 0) / 200][Stage 577:>(0 + 0) / 200][Stage 578:>(0 + 0) / 200]
+
-
[Stage 575:(144 + 16) / 200][Stage 577:>(0 + 0) / 200][Stage 578:>(0 + 0) / 200]

[Stage 577:(16 + 0) / 200][Stage 578:>(0 + 0) / 200][Stage 581:>(0 + 0) / 200]
+
+[Stage 575:(144 + 16) / 200][Stage 577:>(0 + 0) / 200][Stage 578:>(0 + 0) / 200]
+
+[Stage 577:(16 + 0) / 200][Stage 578:>(0 + 0) / 200][Stage 581:>(0 + 0) / 200]
+
-
[Stage 577:(184 + 16) / 200][Stage 578:>(0 + 0) / 200][Stage 581:>(0 + 0) / 200]

[Stage 578:(197 + 3) / 200][Stage 581:>(0 + 0) / 200][Stage 585:>(0 + 0) / 200]
+
+[Stage 577:(184 + 16) / 200][Stage 578:>(0 + 0) / 200][Stage 581:>(0 + 0) / 200]
+
+[Stage 578:(197 + 3) / 200][Stage 581:>(0 + 0) / 200][Stage 585:>(0 + 0) / 200]
+
-
[Stage 581:>(0 + 0) / 200][Stage 585:>(0 + 0) / 200][Stage 587:>(0 + 0) / 200]

[Stage 580:(58 + 16) / 200][Stage 581:>(0 + 0) / 200][Stage 585:>(0 + 0) / 200]
+
+[Stage 581:>(0 + 0) / 200][Stage 585:>(0 + 0) / 200][Stage 587:>(0 + 0) / 200]
+
+[Stage 580:(58 + 16) / 200][Stage 581:>(0 + 0) / 200][Stage 585:>(0 + 0) / 200]
+
-
[Stage 580:(176 + 17) / 200][Stage 581:>(0 + 0) / 200][Stage 585:>(0 + 0) / 200]

[Stage 581:(195 + 5) / 200][Stage 585:>(0 + 0) / 200][Stage 587:>(0 + 0) / 200]
+
+[Stage 580:(176 + 17) / 200][Stage 581:>(0 + 0) / 200][Stage 585:>(0 + 0) / 200]
+
+[Stage 581:(195 + 5) / 200][Stage 585:>(0 + 0) / 200][Stage 587:>(0 + 0) / 200]
+
-
[Stage 585:>(0 + 0) / 200][Stage 587:>(0 + 0) / 200][Stage 589:>(0 + 0) / 200]

[Stage 583:(69 + 17) / 200][Stage 585:>(0 + 0) / 200][Stage 587:>(0 + 0) / 200]
+
+[Stage 585:>(0 + 0) / 200][Stage 587:>(0 + 0) / 200][Stage 589:>(0 + 0) / 200]
+
+[Stage 583:(69 + 17) / 200][Stage 585:>(0 + 0) / 200][Stage 587:>(0 + 0) / 200]
+
-
[Stage 583:(170 + 16) / 200][Stage 585:>(0 + 0) / 200][Stage 587:>(0 + 0) / 200]

[Stage 585:(16 + 0) / 200][Stage 587:>(0 + 0) / 200][Stage 589:>(0 + 0) / 200]
+
+[Stage 583:(170 + 16) / 200][Stage 585:>(0 + 0) / 200][Stage 587:>(0 + 0) / 200]
+
+[Stage 585:(16 + 0) / 200][Stage 587:>(0 + 0) / 200][Stage 589:>(0 + 0) / 200]
+
-
[Stage 585:(75 + 16) / 200][Stage 587:>(0 + 0) / 200][Stage 589:>(0 + 0) / 200]
+
+[Stage 585:(75 + 16) / 200][Stage 587:>(0 + 0) / 200][Stage 589:>(0 + 0) / 200]
+
-
[Stage 587:(16 + 0) / 200][Stage 589:>(0 + 0) / 200][Stage 591:>(0 + 0) / 200]
+
+[Stage 587:(16 + 0) / 200][Stage 589:>(0 + 0) / 200][Stage 591:>(0 + 0) / 200]
+
-
[Stage 587:(16 + 6) / 200][Stage 589:>(0 + 0) / 200][Stage 591:>(0 + 0) / 200]

[Stage 589:>(8 + 8) / 200][Stage 591:>(0 + 0) / 200][Stage 593:>(0 + 0) / 200]
+
+[Stage 587:(16 + 6) / 200][Stage 589:>(0 + 0) / 200][Stage 591:>(0 + 0) / 200]
+
+[Stage 589:>(8 + 8) / 200][Stage 591:>(0 + 0) / 200][Stage 593:>(0 + 0) / 200]
+
-
[Stage 589:(16 + 0) / 200][Stage 591:>(0 + 0) / 200][Stage 593:>(0 + 0) / 200]
+
+[Stage 589:(16 + 0) / 200][Stage 591:>(0 + 0) / 200][Stage 593:>(0 + 0) / 200]
+
-
[Stage 589:(182 + 17) / 200][Stage 591:>(0 + 0) / 200][Stage 593:>(0 + 0) / 200]

[Stage 591:(16 + 0) / 200][Stage 593:>(0 + 0) / 200][Stage 595:>(0 + 0) / 200]
+
+[Stage 589:(182 + 17) / 200][Stage 591:>(0 + 0) / 200][Stage 593:>(0 + 0) / 200]
+
+[Stage 591:(16 + 0) / 200][Stage 593:>(0 + 0) / 200][Stage 595:>(0 + 0) / 200]
+
-
[Stage 591:(133 + 17) / 200][Stage 593:>(0 + 0) / 200][Stage 595:>(0 + 0) / 200]

[Stage 593:(16 + 0) / 200][Stage 595:>(0 + 0) / 200][Stage 597:>(0 + 0) / 200]
+
+[Stage 591:(133 + 17) / 200][Stage 593:>(0 + 0) / 200][Stage 595:>(0 + 0) / 200]
+
+[Stage 593:(16 + 0) / 200][Stage 595:>(0 + 0) / 200][Stage 597:>(0 + 0) / 200]
+
-
[Stage 593:(39 + 18) / 200][Stage 595:>(0 + 0) / 200][Stage 597:>(0 + 0) / 200]

[Stage 595:(16 + 0) / 200][Stage 597:>(0 + 0) / 200][Stage 599:>(0 + 0) / 200]
+
+[Stage 593:(39 + 18) / 200][Stage 595:>(0 + 0) / 200][Stage 597:>(0 + 0) / 200]
+
+[Stage 595:(16 + 0) / 200][Stage 597:>(0 + 0) / 200][Stage 599:>(0 + 0) / 200]
+
-
[Stage 597:(16 + 0) / 200][Stage 599:>(0 + 0) / 200][Stage 600:>(0 + 0) / 200]
+
+[Stage 597:(16 + 0) / 200][Stage 599:>(0 + 0) / 200][Stage 600:>(0 + 0) / 200]
+
-
[Stage 599:(0 + 16) / 200][Stage 600:>(0 + 0) / 200][Stage 605:(11 + 0) / 200]

[Stage 599:(16 + 0) / 200][Stage 600:>(0 + 0) / 200][Stage 605:(11 + 0) / 200]
+
+[Stage 599:(0 + 16) / 200][Stage 600:>(0 + 0) / 200][Stage 605:(11 + 0) / 200]
+
+[Stage 599:(16 + 0) / 200][Stage 600:>(0 + 0) / 200][Stage 605:(11 + 0) / 200]
+
-
[Stage 599:(169 + 16) / 200][Stage 600:>(0 + 0) / 200][Stage 605:(11 + 0) / 200]

[Stage 605:==>                                                   (11 + 0) / 200]
+
+[Stage 599:(169 + 16) / 200][Stage 600:>(0 + 0) / 200][Stage 605:(11 + 0) / 200]
+
+[Stage 605:==>                                                   (11 + 0) / 200]
+
-
[Stage 602:======>     (102 + 18) / 200][Stage 605:>             (11 + 0) / 200]

[Stage 605:==>                                                  (11 + 16) / 200]
+
+[Stage 602:======>     (102 + 18) / 200][Stage 605:>             (11 + 0) / 200]
+
+[Stage 605:==>                                                  (11 + 16) / 200]
+
-
[Stage 606:============================================>       (170 + 16) / 200]
+
+[Stage 606:============================================>       (170 + 16) / 200]
+
-
[Stage 607:===================================>                (135 + 16) / 200]
+
+[Stage 607:===================================>                (135 + 16) / 200]
+
-
                                                                                
+
+                                                                                
+
-
[Stage 932:====================================================>(197 + 3) / 200]

                                                                                
+
+[Stage 932:====================================================>(197 + 3) / 200]
+
+                                                                                
+

@@ -14633,12 +15005,18 @@

Compare to vanilla
-
[Stage 1319:>                                                       (0 + 3) / 3]
+
+[Stage 1319:>                                                       (0 + 3) / 3]
+

-
[Stage 1319:==================>                                     (1 + 2) / 3]

                                                                                
+
+[Stage 1319:==================>                                     (1 + 2) / 3]
+
+                                                                                
+
@@ -16297,12 +16675,6 @@

Config compare