diff --git a/.ci/daint.cscs.ch/ocl.build.sh b/.ci/daint.cscs.ch/ocl.build.sh index 56dd2e749c0..ef788d6a9ce 100755 --- a/.ci/daint.cscs.ch/ocl.build.sh +++ b/.ci/daint.cscs.ch/ocl.build.sh @@ -27,7 +27,7 @@ if [ ! -d "${HOME}/libxsmm" ]; then fi cd "${HOME}/libxsmm" git fetch -git checkout 3235b3e09c9f084abf4213748da46844254bfef9 +git checkout 05705477183444a82c8d9be8d7c2627efd6d67fa make -j cd .. diff --git a/.ci/daint.cscs.ch/ocl.test.sh b/.ci/daint.cscs.ch/ocl.test.sh index b06f33dc3d8..ccf3aa298ad 100755 --- a/.ci/daint.cscs.ch/ocl.test.sh +++ b/.ci/daint.cscs.ch/ocl.test.sh @@ -31,6 +31,9 @@ export LD_LIBRARY_PATH=${HOME}/libxsmm/lib:${LD_LIBRARY_PATH} export OMP_PROC_BIND=TRUE # set thread affinity # OMP_NUM_THREADS is set by cmake +# use default parameters (omit loading tuned parameters) +export OPENCL_LIBSMM_SMM_PARAMS=0 + # document the current environment env |& tee -a "${STAGE_NAME}.out" diff --git a/.github/workflows/doc-generation.yml b/.github/workflows/doc-generation.yml index bd1fd2e4d91..1991bd5ef58 100644 --- a/.github/workflows/doc-generation.yml +++ b/.github/workflows/doc-generation.yml @@ -12,12 +12,12 @@ jobs: build-and-deploy: runs-on: ubuntu-latest container: - image: ghcr.io/cp2k/dbcsr-build-env-ubuntu-20.04:develop + image: ghcr.io/cp2k/dbcsr-build-env-ubuntu-22.04:develop volumes: - "/etc/ssh/ssh_known_hosts:/etc/ssh/ssh_known_hosts:ro" steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 submodules: true diff --git a/.github/workflows/docker-build-env.yml b/.github/workflows/docker-build-env.yml index cf3c718b937..0a4acec0759 100644 --- a/.github/workflows/docker-build-env.yml +++ b/.github/workflows/docker-build-env.yml @@ -19,7 +19,7 @@ jobs: strategy: matrix: include: - - docker_image: ghcr.io/cp2k/dbcsr-build-env-ubuntu-20.04 + - docker_image: ghcr.io/cp2k/dbcsr-build-env-ubuntu-22.04 context: tools/docker file: Dockerfile.build-env-ubuntu registry: ghcr.io @@ -31,14 +31,14 @@ jobs: context: tools/docker file: Dockerfile.build-env-rocm registry: ghcr.io - - docker_image: ghcr.io/cp2k/dbcsr-build-env-ubuntu-20.04-cuda + - docker_image: ghcr.io/cp2k/dbcsr-build-env-ubuntu-22.04-cuda context: tools/docker file: Dockerfile.build-env-ubuntu-cuda registry: ghcr.io steps: - name: Checkout Repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Prepare id: prep @@ -56,22 +56,22 @@ jobs: if [ "${{ github.event_name }}" = "push" ]; then TAGS="$TAGS,${DOCKER_IMAGE}:sha-${GITHUB_SHA::8}" fi - echo ::set-output name=version::${VERSION} - echo ::set-output name=tags::${TAGS} - echo ::set-output name=created::$(date -u +'%Y-%m-%dT%H:%M:%SZ') + echo "version=${VERSION}" >> $GITHUB_OUTPUT + echo "tags=${TAGS}" >> $GITHUB_OUTPUT + echo "created=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 + uses: docker/setup-buildx-action@v3 - name: Login to Container registry - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: registry: ${{ matrix.registry }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Build and push container image - uses: docker/build-push-action@v3 + uses: docker/build-push-action@v5 with: context: ${{ matrix.context }} file: ${{ matrix.context }}/${{ matrix.file }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6a3de46ac8b..fffcf4f62df 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,10 +9,10 @@ jobs: build-and-upload: runs-on: ubuntu-latest container: - image: ghcr.io/cp2k/dbcsr-build-env-ubuntu-20.04:develop + image: ghcr.io/cp2k/dbcsr-build-env-ubuntu-22.04:develop steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: submodules: true diff --git a/.github/workflows/testing-gcc.yml b/.github/workflows/testing-gcc.yml index a986213e5c2..8fec395cc1d 100644 --- a/.github/workflows/testing-gcc.yml +++ b/.github/workflows/testing-gcc.yml @@ -13,7 +13,7 @@ jobs: image: ghcr.io/cp2k/dbcsr-build-env-latest-gcc:develop steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 submodules: true diff --git a/.github/workflows/testing-linux.yml b/.github/workflows/testing-linux.yml index c8b0f993b55..32a7d300365 100644 --- a/.github/workflows/testing-linux.yml +++ b/.github/workflows/testing-linux.yml @@ -13,9 +13,9 @@ jobs: pre-commit: runs-on: ubuntu-latest container: - image: ghcr.io/cp2k/dbcsr-build-env-ubuntu-20.04:develop + image: ghcr.io/cp2k/dbcsr-build-env-ubuntu-22.04:develop steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Run pre-commit run: | git config --global --add safe.directory "$GITHUB_WORKSPACE" @@ -27,7 +27,7 @@ jobs: build-and-test: runs-on: ubuntu-latest container: - image: ghcr.io/cp2k/dbcsr-build-env-ubuntu-20.04:develop + image: ghcr.io/cp2k/dbcsr-build-env-ubuntu-22.04:develop strategy: matrix: @@ -40,7 +40,7 @@ jobs: mpi_suffix: mpich steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 submodules: true @@ -55,7 +55,7 @@ jobs: -DUSE_${{ matrix.use_openmp }} \ -DUSE_${{ matrix.use_smm }} \ -DMPI_EXECUTABLE_SUFFIX=.${{ matrix.mpi_suffix }} \ - -DMPIEXEC_PREFLAGS="$([ "${{ matrix.mpi_suffix }}" = "openmpi" ] && echo "-mca btl ^openib --allow-run-as-root")" \ + -DMPIEXEC_PREFLAGS="$([ "${{ matrix.mpi_suffix }}" = "openmpi" ] && echo "-mca btl ^openib --allow-run-as-root --oversubscribe")" \ -DLCOV_ARGS="--test-name;${{ matrix.use_mpi }}-${{ matrix.use_openmp }}-${{ matrix.use_smm }}-cpu" \ .. @@ -93,14 +93,14 @@ jobs: build-on-cuda: runs-on: ubuntu-latest container: - image: ghcr.io/cp2k/dbcsr-build-env-ubuntu-20.04-cuda:develop + image: ghcr.io/cp2k/dbcsr-build-env-ubuntu-22.04-cuda:develop strategy: matrix: use_openmp: [OPENMP=ON] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 submodules: true @@ -126,7 +126,7 @@ jobs: build-on-opencl: runs-on: ubuntu-latest container: - image: ghcr.io/cp2k/dbcsr-build-env-ubuntu-20.04-cuda:develop + image: ghcr.io/cp2k/dbcsr-build-env-ubuntu-22.04-cuda:develop strategy: matrix: @@ -134,7 +134,7 @@ jobs: use_smm: [SMM=libxsmm] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 submodules: true @@ -164,9 +164,10 @@ jobs: strategy: matrix: use_openmp: [OPENMP=ON] + use_g2g: [G2G=ON, G2G=OFF] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 submodules: true @@ -176,10 +177,11 @@ jobs: mkdir -p build cd build cmake -G Ninja \ - -DCMAKE_BUILD_TYPE=Debug \ + -DCMAKE_BUILD_TYPE=Release \ -DUSE_${{ matrix.use_openmp }} \ -DUSE_ACCEL=hip \ - -DWITH_GPU=Mi100 \ + -DWITH_GPU=Mi250 \ + -DWITH_${{ matrix.use_g2g }} \ -DWITH_EXAMPLES=ON \ -DCMAKE_PREFIX_PATH=/opt/rocm \ .. @@ -191,10 +193,10 @@ jobs: runs-on: ubuntu-latest needs: build-and-test container: - image: ghcr.io/cp2k/dbcsr-build-env-ubuntu-20.04:develop + image: ghcr.io/cp2k/dbcsr-build-env-ubuntu-22.04:develop steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Download coverage data uses: actions/download-artifact@v3 diff --git a/.github/workflows/testing-macos.yml b/.github/workflows/testing-macos.yml index 12cf73a9421..6c5228b521f 100644 --- a/.github/workflows/testing-macos.yml +++ b/.github/workflows/testing-macos.yml @@ -26,7 +26,7 @@ jobs: mpi_suffix: mpich steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 submodules: true @@ -45,9 +45,9 @@ jobs: mkdir -p build cd build env \ - CC=gcc-11 CXX=g++-11 FC=gfortran-11 \ + CC=gcc-12 CXX=g++-12 FC=gfortran-12 \ cmake -G Ninja \ - -DCMAKE_BUILD_TYPE=Debug \ + -DCMAKE_BUILD_TYPE=Release \ -DUSE_${{ matrix.use_mpi }} \ -DUSE_${{ matrix.use_openmp }} \ -DUSE_${{ matrix.use_smm }} \ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1a896399594..a43656db2b9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,9 +3,10 @@ default_language_version: exclude: '^tools/(build_utils/fypp)' fail_fast: false +minimum_pre_commit_version: 3.2.0 repos: -- repo: https://github.com/charliermarsh/ruff-pre-commit - rev: 'v0.0.276' +- repo: https://github.com/astral-sh/ruff-pre-commit + rev: 'v0.3.2' hooks: - id: ruff args: [ --fix, --exit-non-zero-on-fix ] @@ -14,13 +15,13 @@ repos: .cp2k/.*| )$ - repo: https://github.com/psf/black - rev: 23.3.0 + rev: 24.2.0 hooks: - id: black name: Reformat Python files with the black code formatter files: '^.*(/PACKAGE)|(\.py)$' - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: v4.5.0 hooks: - id: check-ast - id: check-yaml diff --git a/.pre-commit/check_header.py b/.pre-commit/check_header.py index 75c6b40c7c8..3cf7d58233c 100755 --- a/.pre-commit/check_header.py +++ b/.pre-commit/check_header.py @@ -13,7 +13,9 @@ import re import mmap import sys -from os import path +import pathlib +from collections import defaultdict +from os import path, listdir from contextlib import contextmanager TYPES = { @@ -41,14 +43,19 @@ def mmap_open(name, mode="r"): def check_header(header_dir, files, verbose=False): retval = 0 - header_re = {} - header_len = {} - - for headertype in TYPES: - with open(path.join(header_dir, headertype), "rb") as fhandle: - header_content = fhandle.read() - header_re[headertype] = re.compile(re.escape(header_content)) - header_len[headertype] = len(header_content) + header_re = defaultdict(list) + header_len = defaultdict(list) + + for headerfile in listdir(header_dir): + headertype = pathlib.Path(headerfile).stem + if headertype in TYPES: + with open(path.join(header_dir, headerfile), "rb") as fhandle: + header_content = fhandle.read() + header_re[headertype].append(re.compile(re.escape(header_content))) + header_len[headertype].append(len(header_content)) + else: + print("no matching headerfile to file extensions") + sys.exit(1) ext_map = {e: t for t, exts in TYPES.items() for e in exts} @@ -62,9 +69,10 @@ def check_header(header_dir, files, verbose=False): with mmap_open(fpath) as fmapped: header_type = ext_map[fext] - match = header_re[header_type].search( - fmapped, 0, ALLOWED_LINES * MAX_LINE_LENGTH + header_len[header_type] - ) + for h_re, h_len in zip(header_re[header_type], header_len[header_type]): + match = h_re.search(fmapped, 0, ALLOWED_LINES * MAX_LINE_LENGTH + h_len) + if match: + break if not match: print("✗ {} ... required header not found".format(fpath)) diff --git a/.pre-commit/headers/c_cpp b/.pre-commit/headers/c_cpp.1 similarity index 100% rename from .pre-commit/headers/c_cpp rename to .pre-commit/headers/c_cpp.1 diff --git a/.pre-commit/headers/c_cpp.2 b/.pre-commit/headers/c_cpp.2 new file mode 100644 index 00000000000..24c5e9d07bc --- /dev/null +++ b/.pre-commit/headers/c_cpp.2 @@ -0,0 +1,9 @@ +/*------------------------------------------------------------------------------------------------*/ +/* Copyright (C) by the DBCSR developers group - All rights reserved */ +/* Copyright (C) 2022 Advanced Micro Devices, Inc. - All rights reserved */ +/* This file is part of the DBCSR library. */ +/* */ +/* For information on the license, see the LICENSE file. */ +/* For further information please visit https://dbcsr.cp2k.org */ +/* SPDX-License-Identifier: GPL-2.0+ */ +/*------------------------------------------------------------------------------------------------*/ diff --git a/.pre-commit/headers/fortran b/.pre-commit/headers/fortran.1 similarity index 100% rename from .pre-commit/headers/fortran rename to .pre-commit/headers/fortran.1 diff --git a/.pre-commit/headers/fortran.2 b/.pre-commit/headers/fortran.2 new file mode 100644 index 00000000000..9a02814edd4 --- /dev/null +++ b/.pre-commit/headers/fortran.2 @@ -0,0 +1,9 @@ +!--------------------------------------------------------------------------------------------------! +! Copyright (C) by the DBCSR developers group - All rights reserved ! +! Copyright (C) 2022 Advanced Micro Devices, Inc. - All rights reserved ! +! This file is part of the DBCSR library. ! +! ! +! For information on the license, see the LICENSE file. ! +! For further information please visit https://dbcsr.cp2k.org ! +! SPDX-License-Identifier: GPL-2.0+ ! +!--------------------------------------------------------------------------------------------------! diff --git a/.pre-commit/headers/fypp b/.pre-commit/headers/fypp.1 similarity index 100% rename from .pre-commit/headers/fypp rename to .pre-commit/headers/fypp.1 diff --git a/.pre-commit/headers/python b/.pre-commit/headers/python.1 similarity index 100% rename from .pre-commit/headers/python rename to .pre-commit/headers/python.1 diff --git a/AUTHORS b/AUTHORS index e1e3899a02c..bcf316119d5 100644 --- a/AUTHORS +++ b/AUTHORS @@ -4,6 +4,7 @@ Christian Pousa Dorothea Golze Fawzi Mohamed Florian Schiffmann +Gina Sitaraman Harald Forbert H. Bani-Hashemian Iain Bethune @@ -11,6 +12,7 @@ Ilia Sivkov Jan Wilhelm Joost VandeVondele Juerg Hutter +Leopold Grinberg Lianheng Tong Marcella Mauri-Iannuzzi Matthias Krack diff --git a/CMakeLists.txt b/CMakeLists.txt index 6fe704ff952..21f9b8ff9a9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,7 @@ cmake_minimum_required(VERSION 3.22) +set(CMAKE_INTERPROCEDURAL_OPTIMIZATION FALSE FORCE) + # include our cmake snippets set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake) @@ -111,7 +113,13 @@ set_property(CACHE WITH_GPU PROPERTY STRINGS ${SUPPORTED_CUDA_ARCHITECTURES} option(WITH_CUDA_PROFILING "Enable profiling within CUDA" OFF) option(WITH_HIP_PROFILING "Enable profiling within HIP" OFF) +option(WITH_G2G "Enable GPU aware MPI within CUDA/HIP backends" OFF) +if (WITH_G2G AND ((NOT USE_ACCEL) OR ((NOT USE_ACCEL MATCHES "cuda") + AND (NOT USE_ACCEL MATCHES "hip")))) + message( + FATAL_ERROR "GPU aware MPI can only be enabled for HIP/CUDA GPU backends") +endif () # ================================================================================================= # LANGUAGES AND TESTING enable_language(Fortran) @@ -236,6 +244,7 @@ if (USE_ACCEL MATCHES "cuda|hip") endif () if (USE_ACCEL MATCHES "cuda") + enable_language(CUDA) find_package(CUDAToolkit REQUIRED) if (CUDAToolkit_VERSION LESS 5.5) @@ -257,9 +266,15 @@ if (USE_ACCEL MATCHES "cuda") message(STATUS "Kernel parameters: " ${WITH_GPU_PARAMS}) message(STATUS "GPU architecture number: " ${ACC_ARCH_NUMBER}) message(STATUS "GPU profiling enabled: " ${WITH_CUDA_PROFILING}) + message(STATUS "GPU aware MPI enabled: " ${WITH_G2G}) endif () if (USE_ACCEL MATCHES "hip") + if (NOT CMAKE_HIP_ARCHITECTURES) + set(CMAKE_HIP_ARCHITECTURES OFF) + endif () + enable_language(HIP) + # Make sure the GPU required is supported list(FIND SUPPORTED_HIP_ARCHITECTURES ${WITH_GPU} GPU_SUPPORTED) if (GPU_SUPPORTED EQUAL -1) @@ -296,6 +311,7 @@ if (USE_ACCEL MATCHES "hip") message(STATUS "Kernel parameters: " ${WITH_GPU_PARAMS}) message(STATUS "GPU architecture number: " ${ACC_ARCH_NUMBER}) message(STATUS "GPU profiling enabled: " ${WITH_HIP_PROFILING}) + message(STATUS "GPU aware MPI enabled: " ${WITH_G2G}) # =================================== BLAS on GPU backend find_package(hipblas CONFIG REQUIRED HINTS ${ROCM_PATH}) @@ -339,3 +355,6 @@ endif () add_subdirectory(docs) include(CustomTargets) + +# Disable LTO +set(CMAKE_INTERPROCEDURAL_OPTIMIZATION FALSE FORCE) diff --git a/VERSION b/VERSION index 82b165030f4..78fa0e9f008 100644 --- a/VERSION +++ b/VERSION @@ -1,8 +1,8 @@ MAJOR = 2 -MINOR = 6 -PATCH = 0 +MINOR = 7 +PATCH = 0-rc1 # A specific DATE (YYYY-MM-DD) fixes an official release, otherwise # it is considered Development version. -DATE = 2023-07-10 +DATE = 2024-03-13 diff --git a/cmake/CompilerConfiguration.cmake b/cmake/CompilerConfiguration.cmake index 8e4b2edec54..1b3c8959abd 100644 --- a/cmake/CompilerConfiguration.cmake +++ b/cmake/CompilerConfiguration.cmake @@ -1,27 +1,26 @@ if (CMAKE_Fortran_COMPILER_ID STREQUAL "GNU") - set(CMAKE_Fortran_FLAGS "-ffree-form -std=f2008ts -fimplicit-none -Werror=aliasing -Werror=ampersand -Werror=c-binding-type -Werror=intrinsic-shadow -Werror=intrinsics-std -Werror=line-truncation -Werror=tabs -Werror=target-lifetime -Werror=underflow -Werror=unused-but-set-parameter -Werror=unused-but-set-variable -Werror=unused-variable -Werror=unused-dummy-argument -Werror=conversion -Werror=zerotrip -Werror=uninitialized -Wno-maybe-uninitialized -Werror=unused-parameter") + set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -ffree-form -std=f2008ts -fimplicit-none -Werror=aliasing -Werror=ampersand -Werror=c-binding-type -Werror=intrinsic-shadow -Werror=intrinsics-std -Werror=line-truncation -Werror=tabs -Werror=target-lifetime -Werror=underflow -Werror=unused-but-set-parameter -Werror=unused-but-set-variable -Werror=unused-variable -Werror=unused-dummy-argument -Werror=conversion -Werror=zerotrip -Werror=uninitialized -Wno-maybe-uninitialized -Werror=unused-parameter") if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 10) set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -Werror=argument-mismatch") # gcc 10+ has this automatically else () set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fallow-argument-mismatch") # requires for 10+ for the MPI wrap module endif () set(CMAKE_Fortran_FLAGS_RELEASE "-O3 -g -funroll-loops") - set(CMAKE_Fortran_FLAGS_COVERAGE "-O0 -g --coverage -fno-omit-frame-pointer -fcheck=all -ffpe-trap=invalid,zero,overflow -fbacktrace -finit-real=snan -finit-integer=-42 -finit-derived -Werror=realloc-lhs -finline-matmul-limit=0 -Werror") + set(CMAKE_Fortran_FLAGS_COVERAGE "-O0 -g --coverage -fno-omit-frame-pointer -fcheck=all,no-array-temps -ffpe-trap=invalid,zero,overflow -fbacktrace -finit-real=snan -finit-integer=-42 -finit-derived -Werror=realloc-lhs -finline-matmul-limit=0 -Werror") set(CMAKE_Fortran_FLAGS_DEBUG "-O2 -ggdb -fno-omit-frame-pointer -fcheck=all -ffpe-trap=invalid,zero,overflow -fbacktrace -finit-real=snan -finit-integer=-42 -finit-derived -finline-matmul-limit=0 -fsanitize=undefined -fsanitize=address -fsanitize-recover=all -Wall -Wextra -Werror -Werror=realloc-lhs -Wno-error=array-temporaries -Wno-error=compare-reals -Wno-error=function-elimination -Wno-error=surprising") if ((NOT (USE_MPI)) OR (NOT ("${MPI_Fortran_LIBRARY_VERSION_STRING}" MATCHES "Open MPI"))) - set(CMAKE_Fortran_FLAGS_COVERAGE "${CMAKE_Fortran_FLAGS_COVERAGE} -fsanitize=leak") set(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} -fsanitize=leak") endif () elseif (CMAKE_Fortran_COMPILER_ID STREQUAL "Intel") - set(CMAKE_Fortran_FLAGS "-free -stand=f18 -fpp -heap-arrays") + set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -free -stand=f18 -fpp -heap-arrays") set(CMAKE_Fortran_FLAGS_RELEASE "-O3 -g") set(CMAKE_Fortran_FLAGS_DEBUG "-O2 -debug") elseif (CMAKE_Fortran_COMPILER_ID STREQUAL "PGI") - set(CMAKE_Fortran_FLAGS "-Mfreeform -Mextend -Mallocatable=03") # -Mallocatable=03: enable F2003+ assignment semantics + set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -Mfreeform -Mextend -Mallocatable=03") # -Mallocatable=03: enable F2003+ assignment semantics set(CMAKE_Fortran_FLAGS_RELEASE "-fast") set(CMAKE_Fortran_FLAGS_DEBUG "-g") elseif (CMAKE_Fortran_COMPILER_ID STREQUAL "NAG") - set(CMAKE_Fortran_FLAGS "-f2008 -free -Warn=reallocation -Warn=subnormal") + set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -f2008 -free -Warn=reallocation -Warn=subnormal") set(CMAKE_Fortran_FLAGS_RELEASE "-O2") set(CMAKE_Fortran_FLAGS_DEBUG "-g -C") if (NOT OpenMP_FOUND) @@ -29,7 +28,7 @@ elseif (CMAKE_Fortran_COMPILER_ID STREQUAL "NAG") set(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} -C=all") # some checks are not available with OpenMP endif () elseif (CMAKE_Fortran_COMPILER_ID STREQUAL "Cray") - set(CMAKE_Fortran_FLAGS "-f free -M3105 -ME7212") # -M3105: hide a false-positive warning about modified loop variables due to loop fusing, promote warning 7212 to an error + set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -f free -M3105 -ME7212") # -M3105: hide a false-positive warning about modified loop variables due to loop fusing, promote warning 7212 to an error set(CMAKE_Fortran_FLAGS_RELEASE "-O2 -G2") set(CMAKE_Fortran_FLAGS_DEBUG "-G2") set(CMAKE_Fortran_MODOUT_FLAG "-ef") # override to get lower-case module file names @@ -47,7 +46,6 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") set(CMAKE_CXX_FLAGS_COVERAGE "-O0 -g --coverage -Wall -Wextra -Werror -Wno-missing-field-initializers") set(CMAKE_CXX_FLAGS_DEBUG "-O2 -ggdb -Wall -Wextra -Werror -Wno-missing-field-initializers -fsanitize=undefined -fsanitize=address -fsanitize-recover=all") if ((NOT (USE_MPI)) OR (NOT ("${MPI_Fortran_LIBRARY_VERSION_STRING}" MATCHES "Open MPI"))) - set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_COVERAGE} -fsanitize=leak") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=leak") endif () elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") diff --git a/docs/guide/2-user-guide/1-installation/index.md b/docs/guide/2-user-guide/1-installation/index.md index fc06dbb2b86..33d71864284 100644 --- a/docs/guide/2-user-guide/1-installation/index.md +++ b/docs/guide/2-user-guide/1-installation/index.md @@ -69,6 +69,8 @@ make -DUSE_SMM= -DUSE_ACCEL= -DWITH_CUDA_PROFILING= +-DWITH_HIP_PROFILING= +-DWITH_G2G= -DWITH_C_API= -DWITH_EXAMPLES= -DWITH_GPU= diff --git a/docs/guide/2-user-guide/4-gpu/index.md b/docs/guide/2-user-guide/4-gpu/index.md index 3e543800ca6..2b8a8032b81 100644 --- a/docs/guide/2-user-guide/4-gpu/index.md +++ b/docs/guide/2-user-guide/4-gpu/index.md @@ -1,12 +1,20 @@ title: GPUs -# CUDA/HIP backend and LIBSMM_ACC +# Introduction -Users interested to tune kernels for the CUDA/HIP backend, can take a look at the [Developer Guide](../../3-developer-guide/3-programming/2-accelerator-backend/2-libsmm_acc/3-tune.html). Following the guide, [tuned parameters](https://github.com/cp2k/dbcsr/tree/develop/src/acc/libsmm_acc/parameters) can be collected for the desired GPU and potentially submitted for the benefit of others. +[CP2K](https://github.com/cp2k/cp2k/) was initially enabled for GPUs by the means of the DBCSR library. The original development focused on scalability and an assumption of a `1:1`-relationship between CPUs and GPUs (one CPU-socket drives one GPU). Multi-GPU asks for associating CPU-ranks with the closest GPU (affinity), but is usually a desparture in terms of algorithms as well (GPU to GPU communication). DBCSR associates ranks with GPUs based on a round-robin scheme using the rank-ID, i.e., GPU-affinity is only achieved with the help of the underlying MPI implementation or support from other runtimes. Aggregating GPU acceleration in as little as possible systems is contrary to the original design of DBCSR (and CP2K at that time). CP2K is a versatile toolbox covering a variety of workloads (input language), which imposes several hotspots beyond DBCSR ([status](https://www.cp2k.org/gpu)). -# OpenCL Backend and OpenCL based LIBSMM +CP2K or DBCSR can scale to thousands of nodes and furter benefit from thread-scalability once communication starts to dominate (due to higher total rank-counts). Thread-scalability (OpenMP) in DBCSR if not CP2K is not equally developed when compared to process scalability (MPI), i.e., higher rank-counts tend to yield better performance on smaller number of systems or nodes. With multiple ranks per GPU, context switches and other overhead can negatively impact performance. However, more ranks are needed to best drive the CPU-dominated portion of the code, and hence GPU and in particular multi-GPU acceleration poses a challenge. -This section shows how to auto-tune a kernel for the OpenCL based LIBSMM library. The process builds a stand-alone driver program which is then driven by an [OpenTuner](https://opentuner.org/) based script guiding the auto-tuning of the desired kernel. The [Developer Guide](../../3-developer-guide/3-programming/2-accelerator-backend/4-opencl-libsmm.html) provides more information, e.g., about constraining execution time or parallelizing the tuning-process as well as how to select and tune an entire set of kernels. +CP2K almost exclusively uses double-precision calculations on CPUs and GPUs (along with DBCSR's need for atomic update instructions for GPUs). Consumer focused GPU offerings often deliver a FLOP-rate ratio between single and double precision up to `SP:DP = 64:1`, which renders them unsuitable for CP2K like not beneficial when compared to modestly many CPU cores. Further, GPU accleration hinges on memory bandwidth rather than compute which further limits the benefit. + +# CUDA/HIP Backend + +Users interested to tune kernels for the CUDA/HIP backend and LIBSMM_ACC, can take a look at the [Developer Guide](../../3-developer-guide/3-programming/2-accelerator-backend/2-libsmm_acc/3-tune.html). Following the guide, [tuned parameters](https://github.com/cp2k/dbcsr/tree/develop/src/acc/libsmm_acc/parameters) can be collected for the desired GPU and potentially submitted for the benefit of others. + +# OpenCL Backend + +This section shows how to auto-tune a kernel for the OpenCL based LIBSMM library. The process builds a stand-alone driver program which is then driven by an [OpenTuner](https://opentuner.org/) based script guiding the auto-tuning of the desired kernel. The [Developer Guide](../../3-developer-guide/3-programming/2-accelerator-backend/3-libsmm_ocl/1-autotune.html) provides more information, e.g., about constraining execution time or parallelizing the tuning-process as well as how to select and tune an entire set of kernels. For simplicity, the GNU Compiler is used to build the afore mentioned driver program, both DBCSR and LIBXSMM are Git-cloned into the same common directory, e.g., the user's `HOME` directory, and the driver is built for tuning double-precision kernels (DP). @@ -29,7 +37,7 @@ cd ${HOME}/dbcsr/src/acc/opencl/smm ./tune_multiply.py 23x23x23 ``` -Beside of interactive termination, above process would also terminate based on OpenTuner's default or can be constrained by the number of steps (experiments), time to be spent, or a combination of both. Details can be found in the [Developer Guide](../../3-developer-guide/3-programming/2-accelerator-backend/4-opencl-libsmm.html). +Beside of interactive termination, above process would also terminate based on OpenTuner's default or can be constrained by the number of steps (experiments), time to be spent, or a combination of both. Details can be found in the [Developer Guide](../../3-developer-guide/3-programming/2-accelerator-backend/2-libsmm_acc/3-tune.html). Suppose the 23x23x23-kernel was tuned for some time (e.g., 5-10 minutes), tuned parameters can be incorporated into the backend. The aggregated parameters (`tune_multiply.csv`) are automatically embedded when rebuilding the library and driver. diff --git a/docs/guide/3-developer-guide/2-documentation/index.md b/docs/guide/3-developer-guide/2-documentation/index.md index db7245a89b0..f6f5b358285 100644 --- a/docs/guide/3-developer-guide/2-documentation/index.md +++ b/docs/guide/3-developer-guide/2-documentation/index.md @@ -2,7 +2,7 @@ title: Documentation # Documentation -## Build +## Build To build the documentation you need [FORD](https://github.com/Fortran-FOSS-Programmers/ford). diff --git a/docs/guide/3-developer-guide/3-programming/1-overview/index.md b/docs/guide/3-developer-guide/3-programming/1-overview/index.md index d55b9b3f30f..27f6bda40d0 100644 --- a/docs/guide/3-developer-guide/3-programming/1-overview/index.md +++ b/docs/guide/3-developer-guide/3-programming/1-overview/index.md @@ -55,3 +55,4 @@ Assumed square matrix with 20x20 matrix with 5x5 blocks and a 2x2 processor grid | `__CUDA_PROFILING` | To turn on Nvidia Tools Extensions. It requires to link `-lnvToolsExt` | Fortran, C, C++ | | `__CUDA` | Enable CUDA acceleration | C, C++ | | `__HIP` | Enable HIP acceleration | C, C++ | +| `__DBCSR_ACC_G2G` | Enable GPU Aware MPI in CUDA and HIP backends | Fortran, C, C++ | diff --git a/docs/guide/3-developer-guide/3-programming/2-accelerator-backend/2-libsmm_acc/index.md b/docs/guide/3-developer-guide/3-programming/2-accelerator-backend/2-libsmm_acc/index.md index d16170b5c03..b0941695748 100644 --- a/docs/guide/3-developer-guide/3-programming/2-accelerator-backend/2-libsmm_acc/index.md +++ b/docs/guide/3-developer-guide/3-programming/2-accelerator-backend/2-libsmm_acc/index.md @@ -1,3 +1,3 @@ -title: LIBSMM (CUDA/HIP) +title: CUDA/HIP {!./src/acc/libsmm_acc/README.md!} diff --git a/docs/guide/3-developer-guide/3-programming/2-accelerator-backend/3-libsmm_ocl/1-autotune.md b/docs/guide/3-developer-guide/3-programming/2-accelerator-backend/3-libsmm_ocl/1-autotune.md new file mode 100644 index 00000000000..f0631abbc38 --- /dev/null +++ b/docs/guide/3-developer-guide/3-programming/2-accelerator-backend/3-libsmm_ocl/1-autotune.md @@ -0,0 +1,3 @@ +title: Autotune + +{!./src/acc/opencl/smm/README-autotune.md!} diff --git a/docs/guide/3-developer-guide/3-programming/2-accelerator-backend/3-libsmm_ocl/2-bulktune.md b/docs/guide/3-developer-guide/3-programming/2-accelerator-backend/3-libsmm_ocl/2-bulktune.md new file mode 100644 index 00000000000..ed40e9e4545 --- /dev/null +++ b/docs/guide/3-developer-guide/3-programming/2-accelerator-backend/3-libsmm_ocl/2-bulktune.md @@ -0,0 +1,3 @@ +title: Parameters + +{!./src/acc/opencl/smm/README-bulktune.md!} diff --git a/docs/guide/3-developer-guide/3-programming/2-accelerator-backend/3-libsmm_ocl/index.md b/docs/guide/3-developer-guide/3-programming/2-accelerator-backend/3-libsmm_ocl/index.md new file mode 100644 index 00000000000..ef1b62d07ae --- /dev/null +++ b/docs/guide/3-developer-guide/3-programming/2-accelerator-backend/3-libsmm_ocl/index.md @@ -0,0 +1,5 @@ +title: OpenCL + +{!./src/acc/opencl/README.md!} + +{!./src/acc/opencl/smm/README.md!} diff --git a/docs/guide/3-developer-guide/3-programming/2-accelerator-backend/3-opencl-backend.md b/docs/guide/3-developer-guide/3-programming/2-accelerator-backend/3-opencl-backend.md deleted file mode 100644 index 8965c8f435b..00000000000 --- a/docs/guide/3-developer-guide/3-programming/2-accelerator-backend/3-opencl-backend.md +++ /dev/null @@ -1,3 +0,0 @@ -title: OpenCL Backend - -{!./src/acc/opencl/README.md!} diff --git a/docs/guide/3-developer-guide/3-programming/2-accelerator-backend/4-opencl-libsmm.md b/docs/guide/3-developer-guide/3-programming/2-accelerator-backend/4-opencl-libsmm.md deleted file mode 100644 index abf96990301..00000000000 --- a/docs/guide/3-developer-guide/3-programming/2-accelerator-backend/4-opencl-libsmm.md +++ /dev/null @@ -1,3 +0,0 @@ -title: OpenCL LIBSMM - -{!./src/acc/opencl/smm/README.md!} diff --git a/examples/dbcsr_example_3.cpp b/examples/dbcsr_example_3.cpp index a49a169ff4d..a59c4d23adc 100644 --- a/examples/dbcsr_example_3.cpp +++ b/examples/dbcsr_example_3.cpp @@ -53,8 +53,8 @@ int main(int argc, char* argv[]) { for (int i = 0; i != mpi_size; ++i) { if (mpi_rank == i) { - std::cout << "I'm processor " << mpi_rank << " over " << mpi_size << " proc" - << ", (" << coord[0] << ", " << coord[1] << ") in the 2D grid" << std::endl; + std::cout << "I'm processor " << mpi_rank << " over " << mpi_size << " proc" << ", (" << coord[0] << ", " << coord[1] + << ") in the 2D grid" << std::endl; } MPI_Barrier(MPI_COMM_WORLD); } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d5196c595cf..3f64deea382 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -109,10 +109,12 @@ set(DBCSR_HIP_AND_CUDA_SRCS acc/libsmm_acc/libsmm_acc_benchmark.cpp acc/libsmm_acc/libsmm_acc_init.cpp acc/libsmm_acc/libsmm_acc.cpp + acc/cuda_hip/calculate_norms.cpp acc/cuda_hip/acc_blas.cpp acc/cuda_hip/acc_dev.cpp acc/cuda_hip/acc_error.cpp acc/cuda_hip/acc_event.cpp + acc/cuda_hip/acc_utils.cpp acc/cuda_hip/acc_init.cpp acc/cuda_hip/acc_mem.cpp acc/cuda_hip/acc_stream.cpp) @@ -122,6 +124,18 @@ set(DBCSR_CUDA_SRCS ${DBCSR_HIP_AND_CUDA_SRCS} acc/cuda/acc_cuda.cpp set(DBCSR_HIP_SRCS ${DBCSR_HIP_AND_CUDA_SRCS} acc/hip/acc_hip.cpp) +if (USE_ACCEL MATCHES "hip") + set_source_files_properties(acc/cuda_hip/calculate_norms.cpp + PROPERTIES LANGUAGE HIP) + set_source_files_properties(acc/cuda_hip/calculate_norms.cpp + PROPERTIES COMPILE_FLAGS "-fPIE") +elseif (USE_ACCEL MATCHES "cuda") + set_source_files_properties(acc/cuda_hip/calculate_norms.cpp + PROPERTIES LANGUAGE CUDA) + set_source_files_properties(acc/cuda_hip/calculate_norms.cpp + PROPERTIES COMPILE_FLAGS "--x cu") +endif () + set(DBCSR_OPENCL_SRCS acc/opencl/smm/opencl_libsmm.c acc/opencl/acc_opencl.c acc/opencl/acc_opencl_event.c acc/opencl/acc_opencl_mem.c @@ -164,6 +178,13 @@ set_target_properties( SOVERSION ${dbcsr_APIVERSION} POSITION_INDEPENDENT_CODE ON) +if (USE_ACCEL MATCHES "hip") + set_target_properties(dbcsr PROPERTIES HIP_ARCHITECTURES "${ACC_ARCH_NUMBER}") +elseif (USE_ACCEL MATCHES "cuda") + set_target_properties(dbcsr PROPERTIES CUDA_ARCHITECTURES + "${ACC_ARCH_NUMBER}") +endif () + if (USE_SMM MATCHES "libxsmm") target_compile_definitions(dbcsr PRIVATE __LIBXSMM) target_link_directories(dbcsr PUBLIC ${LIBXSMM_LIBRARY_DIRS}) @@ -171,6 +192,7 @@ if (USE_SMM MATCHES "libxsmm") target_link_libraries(dbcsr PRIVATE PkgConfig::LIBXSMMEXT) endif () target_link_libraries(dbcsr PRIVATE PkgConfig::LIBXSMM) + target_link_libraries(dbcsr PRIVATE ${BLAS_LIBRARIES}) endif () if (BLAS_LIBRARIES MATCHES "mkl_") @@ -262,6 +284,18 @@ if (USE_ACCEL) $<$:roctx64> $<$:roctracer64> $<$:OpenCL::OpenCL>) + + if (WITH_G2G) + target_compile_definitions( + dbcsr + PRIVATE __DBCSR_ACC_G2G + $<$:__CUDA> + $<$:ARCH_NUMBER=${ACC_ARCH_NUMBER}> + $<$:__HIP> + $<$:ARCH_NUMBER=${ACC_ARCH_NUMBER}> + $<$:__CUDA_PROFILING> + $<$:__HIP_PROFILING>) + endif () endif () # ================================================================================================= @@ -304,10 +338,16 @@ install( EXPORT DBCSRTargets LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}") +# See https://gitlab.kitware.com/cmake/cmake/-/issues/19608 +# CMAKE_INSTALL_Fortran_MODULES is not an "official" cmake variable yet, but +# should be the standard soon +if (NOT CMAKE_INSTALL_Fortran_MODULES) + set(CMAKE_INSTALL_Fortran_MODULES "${CMAKE_INSTALL_INCLUDEDIR}") +endif () install(FILES "${CMAKE_CURRENT_BINARY_DIR}/dbcsr_api.mod" - DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") + DESTINATION "${CMAKE_INSTALL_Fortran_MODULES}") install(FILES "${CMAKE_CURRENT_BINARY_DIR}/dbcsr_tensor_api.mod" - DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") + DESTINATION "${CMAKE_INSTALL_Fortran_MODULES}") if (WITH_C_API) install( diff --git a/src/acc/README.md b/src/acc/README.md index 40e405816fd..d753d0cf6c5 100644 --- a/src/acc/README.md +++ b/src/acc/README.md @@ -1,27 +1,32 @@ -# ACCelerator Interfaces +# ACCelerator Interface -## Overview +## Backends -This folder contains the ISO_C_BINDING based Fortran code of DBCSR's [ACC-backend interface](https://github.com/cp2k/dbcsr/blob/develop/src/acc/acc.h) and [LIBSMM/ACC-interface](https://github.com/cp2k/dbcsr/blob/develop/src/acc/acc_libsmm.h). It also contains the CUDA (for Nvidia GPUs), the HIP (for AMD GPUs), and the OpenCL accelerator backends. +The accelerator interface (ACC) consists of ISO_C_BINDING based Fortran code of DBCSR's [ACC-backend interface](https://github.com/cp2k/dbcsr/blob/develop/src/acc/acc.h) and [LIBSMM/ACC-interface](https://github.com/cp2k/dbcsr/blob/develop/src/acc/acc_libsmm.h). The interface is implemented by CUDA (for Nvidia GPUs), the HIP (for AMD GPUs), and the OpenCL accelerator backends. -Further, two stand-alone sample codes are given exercising both interfaces (benchmarks). +The code for both the CUDA and the HIP backend is unified, and can be found in the `cuda` directory. At compile-time either one or the other backend is chosen per macro (`__CUDA` or `__HIP`). Similarly, the code for the OpenCL backend is activated by a build-time macro (`__OPENCL`). -## CUDA and HIP backends +## Drivers -The code for both the CUDA and HIP backends is unified, and can be found in the `cuda` directory. -At compile-time either one or the other backend is chosen per macro (`__CUDA` or `__HIP`). +There are two stand-alone sample codes or drivers exercising the ACC-interface. The driver code (only depending on above mentioned interfaces) can be built locally and in a rather self-contained fashion, i.e., no DBCSR library is needed (except runtime libraries such as CUDA, HIP, OpenCL). For OpenCL, the LIBXSMM library is mandatory and preferred as baseline and for validation in any case. To build LIBXSMM, a folder `libxsmm` in parallel to DBCSR's root directory (`dbcsr`) is expected to be present and prebuilt. -## OpenCL backend - -The code for both the OpenCL backends is enabled with a build-time macro (`__OPENCL`). +```bash +git clone -b main https://github.com/libxsmm/libxsmm.git +cd libxsmm +make GNU=1 -j +``` -## Benchmarks +To build the driver code (`opencl` in below example), change into the respective backend folder (`cuda` or `opencl`), and invoke `make` (`DBG=0|1|2` is supported among other optional key-value pairs). -Two stand-alone drivers (only depending on above mentioned interfaces) can be built locally and in a rather self-contained fashion, i.e., no DBCSR library is needed (except runtime libraries such as CUDA, HIP, OpenCL/LIBXSMM). For OpenCL, a folder `libxsmm` parallel to DBCSR's root directory (`dbcsr`) is expected to be present and prebuilt (`make` in LIBXSMM's root directory is enough). To build the driver code, change into the respective backend folder (`cuda` or `opencl`), and invoke `make` (`DBG=0|1|2`, and a few other key-value pairs are optional). When building the code is completed, change back into the parent folder and invoke either `acc_bench_trans` or `acc_bench_smm`. +```bash +git clone https://github.com/cp2k/dbcsr.git +cd dbcsr/src/acc/opencl +make +``` -**NOTE**: To activate a certain device, an environment variable `DEVICE` can be used. For example, `DEVICE=1 ./acc_bench_trans` activates the second device (at least two devices must be discovered). +**NOTE**: To activate a certain device, the drivers consider an environment variable called `DEVICE`. For example, `DEVICE=1 ./acc_bench_trans` activates the second device (at least two devices must be discovered). This environment variable is implemented by the driver code and meant to work across backends, i.e., the OpenCL backend also supports `ACC_OPENCL_DEVICE=1` (see Developer Guide for the OpenCL backend). -The drivers support a few command line options (_nrepeat_, _stack_size_, _m_, _n_, ...). Command line arguments are positional but allow `0` as placeholder to access the default value (`acc_bench_smm 0 0 5 13 5` performs the default number of repetitions with the default stacksize when running the 5x13x5-kernel). For example, running the tranpose benchmark may look like: +The drivers support command line options (_nrepeat_, _stack_size_, _m_, _n_, ...). Command line arguments are positional but allow `0` as placeholder to refer to the default value (`acc_bench_smm 0 0 5 13 5` performs the default number of repetitions with the default stacksize when running the 5x13x5-kernel). For example, running the tranpose benchmark may look like: ```bash $ OMP_PROC_BIND=TRUE ./acc_bench_trans 5 30000 23 23 @@ -36,19 +41,17 @@ errors: 0 For timing, comparison (host code), and validation, LIBXSMM is required. The drivers exercise the respective backend. For example with the CUDA backend: ```bash -cd cuda -make DBG=0 WITH_GPU=P100 -cd .. +cd src/acc/cuda +make WITH_GPU=P100 +../acc_bench_smm ``` For the OpenCL backend: ```bash -cd opencl -make DBG=0 -cd .. +cd src/acc/opencl +make +../acc_bench_smm ``` -In either of the above cases, `acc_bench_trans` and `acc_bench_smm` are built using the respective backends. -Both driver codes can be instantiated for at least double- and single-precision using a build-time macro (`ELEM_TYPE`). -Several build-time settings can be made on the build-line (`-D`) or inside of the source files (`acc_bench_trans.c` or `acc_bench_smm.c`). +In above cases, `acc_bench_trans` and `acc_bench_smm` are built using the respective backend. Both driver codes can be built for double-precision (default) or single-precision using a build-time macro (`make ELEM_TYPE=float` or `-DELEM_TYPE=float` in general). diff --git a/src/acc/acc_bench_smm.c b/src/acc/acc_bench_smm.c index 83467635bb9..381c86864a5 100644 --- a/src/acc/acc_bench_smm.c +++ b/src/acc/acc_bench_smm.c @@ -72,6 +72,9 @@ #if !defined(NREPEAT) # define NREPEAT 3 #endif +#if !defined(XREPEAT) +# define XREPEAT 66 +#endif #if !defined(TRANSPOSE) # define TRANSPOSE #endif @@ -86,10 +89,10 @@ #endif #define ACC_BENCH_SMM_EPSILON(T) DBCSR_CONCATENATE(ACC_BENCH_SMM_EPSILON_, T) -#define ACC_BENCH_SMM_EPSILON_double 3E-3 -#define ACC_BENCH_SMM_EPSILON_float 3E-3 +#define ACC_BENCH_SMM_EPSILON_double 1E-3 +#define ACC_BENCH_SMM_EPSILON_float 2E-3 -#define ROUNDUP2(N, NPOT) ((((unsigned long long)N) + ((NPOT)-1)) & ~((NPOT)-1)) +#define ROUNDUP2(N, NPOT) ((((unsigned long long)N) + ((NPOT) - 1)) & ~((NPOT) - 1)) #define CHECK(EXPR, RPTR, VALUE) \ do { \ if (NULL != ((const void*)(RPTR))) { \ @@ -213,7 +216,7 @@ int main(int argc, char* argv[]) { const char *snc = NULL, *sna = NULL, *snb = NULL; FILE* file = NULL; #if defined(USE_LIBXSMM) && defined(VALIDATE) - double maxerror = 0; + double maxdiff = 0; #else DBCSR_MARK_USED(check); #endif @@ -292,7 +295,8 @@ int main(int argc, char* argv[]) { double duration = 0; #endif const char* const env_stack_size = getenv("SMM_BATCHSIZE"); - int nrepeat = (0 < inr ? inr : NREPEAT); + const int xrepeat = (0 != check ? NREPEAT : XREPEAT); + int nrepeat = (0 < inr ? inr : xrepeat); int stack_size, na, nb, nc, nr, r; if (NULL == env_stack_size) { stack_size = 0; @@ -325,7 +329,7 @@ int main(int argc, char* argv[]) { const int r = rnd[nok % NRAND], ss = -stack_size, bs = (1 < ss ? ss : BATCHSIZE); const int limit = (BATCHGRAIN < ss ? ((bs + BATCHGRAIN - 1) / BATCHGRAIN) : ss); stack_size = (r % limit + 1) * BATCHGRAIN; - nrepeat = MAX((BATCHSIZE * nrepeat + stack_size - 1) / stack_size, NREPEAT); + nrepeat = MAX((BATCHSIZE * nrepeat + stack_size - 1) / stack_size, xrepeat); } else stack_size = BATCHSIZE; /* plain default */ } @@ -480,18 +484,22 @@ int main(int argc, char* argv[]) { /* transfer result from device to host for validation */ CHECK(c_dbcsr_acc_memcpy_d2h(cmat_dev, cmat_hst, sizeof(ELEM_TYPE) * mn * nc, stream), &result, check); CHECK(c_dbcsr_acc_stream_sync(stream), &result, check); -# if LIBXSMM_VERSION4(1, 17, 0, 0) < LIBXSMM_VERSION_NUMBER +# if defined(USE_LIBXSMM) if (EXIT_SUCCESS == result) { libxsmm_matdiff_info diff; /* validate result buffers at once (including excess/padded space) */ result = libxsmm_matdiff(&diff, LIBXSMM_DATATYPE(ELEM_TYPE), mn, nc, gold_hst, cmat_hst, &mn, &mn); if (EXIT_SUCCESS == result) { - const double relerror = 1.0 - diff.rsq; - PRINTF("rel.error: %g", relerror); - if (maxerror < relerror && NULL != file) maxerror = relerror; - if (0 < relerror) { +# if defined(USE_LIBXSMM) && LIBXSMM_VERSION4(1, 17, 0, 0) < LIBXSMM_VERSION_NUMBER + const double epsilon = libxsmm_matdiff_epsilon(&diff); /* 1.0 - diff.rsq */ +# else + const double epsilon = diff.normf_rel; +# endif + PRINTF("diff.cur: %g", epsilon); + if (maxdiff < epsilon && NULL != file) maxdiff = epsilon; + if (0 < epsilon) { if (LIBXSMM_NOTNAN(diff.v_tst)) { - PRINTF(" (%g != %g)\n", diff.v_ref, diff.v_tst); + PRINTF(" (|%g-%g|=%g)\n", diff.v_ref, diff.v_tst, fabs(diff.v_ref - diff.v_tst)); } else { PRINTF(" (%g)\n", diff.v_tst); @@ -500,7 +508,7 @@ int main(int argc, char* argv[]) { else { PRINTF("\n"); } - if (0 < check && check < relerror) result = EXIT_FAILURE; + if (0 < check && check < epsilon) result = EXIT_FAILURE; } } # endif @@ -546,7 +554,7 @@ int main(int argc, char* argv[]) { #endif CHECK(c_dbcsr_acc_finalize(), NULL, check); #if defined(USE_LIBXSMM) && defined(VALIDATE) - if (1 < nok) printf("\nmax.error: %g\n", maxerror); + if (1 < nok) printf("\ndiff.max: %g\n", maxdiff); #endif if (EXIT_SUCCESS != result) { if (NULL != file) fclose(file); diff --git a/src/acc/acc_bench_trans.c b/src/acc/acc_bench_trans.c index e124b8567c5..be5643478eb 100644 --- a/src/acc/acc_bench_trans.c +++ b/src/acc/acc_bench_trans.c @@ -56,7 +56,7 @@ #endif #define MAX(A, B) ((B) < (A) ? (A) : (B)) -#define ROUNDUP2(N, NPOT) ((((unsigned long long)N) + ((NPOT)-1)) & ~((NPOT)-1)) +#define ROUNDUP2(N, NPOT) ((((unsigned long long)N) + ((NPOT) - 1)) & ~((NPOT) - 1)) #define CHECK(EXPR, RPTR) \ if ((NULL != ((const void*)(RPTR)) && EXIT_SUCCESS != *((const int*)(RPTR))) || \ EXIT_SUCCESS != (NULL != ((const void*)(RPTR)) ? (*((int*)(RPTR)) = (EXPR)) : (EXPR))) \ diff --git a/src/acc/acc_libsmm.h b/src/acc/acc_libsmm.h index ddf3c1ccdba..06957d74074 100644 --- a/src/acc/acc_libsmm.h +++ b/src/acc/acc_libsmm.h @@ -46,7 +46,7 @@ int libsmm_acc_process(const int* host_param_stack, const int* dev_param_stack, const void* dev_a_data, const void* dev_b_data, void* dev_c_data, int m_max, int n_max, int k_max, int max_kernel_dim, c_dbcsr_acc_bool_t def_mnk, void* stack_stream, void* c_stream); -int c_calculate_norms(double* mat, int nblks, int* offsets, int* nelems, float* norms, void* stream_ptr); +int c_calculate_norms(const double* mat, int nblks, const int* offsets, const int* nelems, float* norms, void* stream_ptr); static const char libsmm_acc_transpose_routine_name_str[] = "jit_kernel_transpose"; static const char* const libsmm_acc_transpose_routine_name_ptr = libsmm_acc_transpose_routine_name_str; diff --git a/src/acc/cuda/Makefile b/src/acc/cuda/Makefile index 82546ecbfd8..79092692035 100644 --- a/src/acc/cuda/Makefile +++ b/src/acc/cuda/Makefile @@ -30,6 +30,7 @@ UNAME := $(shell uname) HEADERONLY ?= 0 STATIC ?= 1 INTEL ?= 0 +GNU ?= 0 DEV ?= 0 # select from set of predefined triplet specifications @@ -109,6 +110,15 @@ else ifneq (0,$(INTEL)) CXX := icpx CC := icx AR := xiar +else ifneq (0,$(GNU)) + override CXX := g++ + override CC := gcc + ifneq (Darwin,$(UNAME)) + override AR := gcc-ar + else + override AR := ar + endif + override LD_LIBRARY_DIRS := $(NULL) else CXX := g++ CC := gcc @@ -184,8 +194,9 @@ ifneq (,$(LIBXSMMROOT)) endif ifneq (,$(CUDA_PATH)) - LDFLAGS += -L$(CUDA_PATH)/lib64/stubs -Wl,-rpath=$(CUDA_PATH)/lib64/stubs - LDFLAGS += -L$(CUDA_PATH)/lib64 -Wl,-rpath=$(CUDA_PATH)/lib64 + CUDA_LIBDIR := $(if $(wildcard $(CUDA_PATH)/lib64),lib64,lib) + LDFLAGS += -L$(CUDA_PATH)/$(CUDA_LIBDIR)/stubs -Wl,-rpath=$(CUDA_PATH)/$(CUDA_LIBDIR)/stubs + LDFLAGS += -L$(CUDA_PATH)/$(CUDA_LIBDIR) -Wl,-rpath=$(CUDA_PATH)/$(CUDA_LIBDIR) CUDAINC := $(strip $(lastword $(sort $(wildcard $(CUDA_PATH)/../cuda/*/targets/x86_64-linux/include/cuda.h)))) ifneq (,$(CUDAINC)) CFLAGS += -I$(abspath $(dir $(CUDAINC))) @@ -195,9 +206,9 @@ ifneq (,$(CUDA_PATH)) endif # Collect all paths in LD_LIBRARY_PATH and LD_LIBRARY_PATH/stubs, and append to LDFLAGS -LD_LIBRARY_PATH := $(wildcard $(subst :, ,$(LD_LIBRARY_PATH))) -LD_LIBSTUB_PATH := $(wildcard $(patsubst %,%/stubs,$(LD_LIBRARY_PATH))) -LIBPATHS := $(foreach DIR,$(LD_LIBRARY_PATH),$(if $(filter -L$(DIR),$(LDFLAGS)),$(NULL),-L$(DIR))) +LD_LIBRARY_DIRS := $(wildcard $(subst :, ,$(LD_LIBRARY_PATH))) +LD_LIBSTUB_PATH := $(wildcard $(patsubst %,%/stubs,$(LD_LIBRARY_DIRS))) +LIBPATHS := $(foreach DIR,$(LD_LIBRARY_DIRS),$(if $(filter -L$(DIR),$(LDFLAGS)),$(NULL),-L$(DIR))) LIBSTUBS := $(foreach DIR,$(LD_LIBSTUB_PATH),$(if $(filter -L$(DIR),$(LDFLAGS)),$(NULL),-L$(DIR))) LDFLAGS += $(LIBPATHS) $(LIBSTUBS) -lcudart -lcublas -lnvrtc -lcuda CXXFLAGS += -std=c++11 $(CFLAGS) @@ -291,7 +302,7 @@ $(ACCDIR)/dbcsr_acc_smm.a: $(OBJSMM) %.o: %.cpp $(INCALL) $(MAKDIR)/Makefile $(CXX) $(DFLAGS) $(CXXFLAGS) $(CFLAGS_XSMM) -c $< -o $@ -$(DIRSMM)/calculate_norms.o: $(DIRSMM)/calculate_norms.cpp $(INCALL) $(MAKDIR)/Makefile +$(ACCDIR)/cuda_hip/calculate_norms.o: $(ACCDIR)/cuda_hip/calculate_norms.cpp $(INCALL) $(MAKDIR)/Makefile $(NVCC) $(DFLAGS) -x cu -allow-unsupported-compiler \ --compiler-options="$(filter-out -pedantic,$(CXXFLAGS)) $(CFLAGS_XSMM)" -c $< -o $@ diff --git a/src/acc/cuda/acc_cuda.h b/src/acc/cuda/acc_cuda.h index b0f9e1f9f20..115265af607 100644 --- a/src/acc/cuda/acc_cuda.h +++ b/src/acc/cuda/acc_cuda.h @@ -14,6 +14,7 @@ #include #include #include +#include #define ACC(x) cuda##x #define ACC_DRV(x) CU##x diff --git a/src/acc/cuda_hip/acc_dev.cpp b/src/acc/cuda_hip/acc_dev.cpp index 154a59bf529..9028a4a3c5f 100644 --- a/src/acc/cuda_hip/acc_dev.cpp +++ b/src/acc/cuda_hip/acc_dev.cpp @@ -1,5 +1,6 @@ /*------------------------------------------------------------------------------------------------*/ /* Copyright (C) by the DBCSR developers group - All rights reserved */ +/* Copyright (C) 2022 Advanced Micro Devices, Inc. - All rights reserved */ /* This file is part of the DBCSR library. */ /* */ /* For information on the license, see the LICENSE file. */ @@ -20,7 +21,9 @@ #include // for debug purpose +#if defined(__HIP_PLATFORM_NVCC__) static const int verbose_print = 1; +#endif /****************************************************************************/ extern "C" int c_dbcsr_acc_get_ndevices(int* n_devices) { diff --git a/src/acc/cuda_hip/acc_utils.cpp b/src/acc/cuda_hip/acc_utils.cpp new file mode 100644 index 00000000000..c2b641640c7 --- /dev/null +++ b/src/acc/cuda_hip/acc_utils.cpp @@ -0,0 +1,25 @@ +/*------------------------------------------------------------------------------------------------*/ +/* Copyright (C) by the DBCSR developers group - All rights reserved */ +/* This file is part of the DBCSR library. */ +/* */ +/* For information on the license, see the LICENSE file. */ +/* For further information please visit https://dbcsr.cp2k.org */ +/* SPDX-License-Identifier: GPL-2.0+ */ +/*------------------------------------------------------------------------------------------------*/ + +#include "acc_utils.h" + +#if defined(__CUDA) +# include "../cuda/acc_cuda.h" +#elif defined(__HIP) +# include "../hip/acc_hip.h" +#endif + +//=========================================================================== +int acc_get_gpu_warp_size() { + int device = 0; + ACC(DeviceProp) prop; + ACC_API_CALL(GetDevice, (&device)); + ACC_API_CALL(GetDeviceProperties, (&prop, device)); + return prop.warpSize; +} diff --git a/src/acc/cuda_hip/acc_utils.h b/src/acc/cuda_hip/acc_utils.h new file mode 100644 index 00000000000..940812102d3 --- /dev/null +++ b/src/acc/cuda_hip/acc_utils.h @@ -0,0 +1,15 @@ +/*------------------------------------------------------------------------------------------------*/ +/* Copyright (C) by the DBCSR developers group - All rights reserved */ +/* This file is part of the DBCSR library. */ +/* */ +/* For information on the license, see the LICENSE file. */ +/* For further information please visit https://dbcsr.cp2k.org */ +/* SPDX-License-Identifier: GPL-2.0+ */ +/*------------------------------------------------------------------------------------------------*/ + +#ifndef ACC_UTILS_H +#define ACC_UTILS_H + +int acc_get_gpu_warp_size(void); + +#endif /*ACC_UTILS_H*/ diff --git a/src/acc/cuda_hip/calculate_norms.cpp b/src/acc/cuda_hip/calculate_norms.cpp new file mode 100644 index 00000000000..fc69a80dcd8 --- /dev/null +++ b/src/acc/cuda_hip/calculate_norms.cpp @@ -0,0 +1,118 @@ +/*------------------------------------------------------------------------------------------------*/ +/* Copyright (C) by the DBCSR developers group - All rights reserved */ +/* Copyright (C) 2022 Advanced Micro Devices, Inc. - All rights reserved */ +/* This file is part of the DBCSR library. */ +/* */ +/* For information on the license, see the LICENSE file. */ +/* For further information please visit https://dbcsr.cp2k.org */ +/* SPDX-License-Identifier: GPL-2.0+ */ +/*------------------------------------------------------------------------------------------------*/ + +/***************************************************************************** + * Authors: Gina Sitaraman * + *****************************************************************************/ + +/* + * Execution configuration: + * gridDim.x = number of matrix blocks in this batched norms calculation + * = length of the batched norms calculation stack + * blockIdx.x = {0, ..., gridDim.x-1} + * blockDim.x = warp size (for now, assuming warp size is going to be 64 or 32) + * threadIdx.x = {0, ..., blockDim.x-1} + + * Execute batched norms calculation + + * Function arguments + * --- norms: (pointer to global memory): + * output array of norms, one per matrix in the stack + * --- offsets: (pointer to global memory): + * array of offsets, indicating where each block starts in the "mat" buffer + * --- nelems: (pointer to global memory): + * array of integers, indicating the number of elements in each matrix/block + * --- mat (pointer to global memory): + * arrays containing the matrices for which norms are calculated + + * Algorithm specificities: + * --- warp level primitives are used to reduce within a warp/wavefront, and + * shared memory is used if more than one warp/wavefront is detected + */ + +#if defined(__CUDA) +# include "../cuda/acc_cuda.h" +#elif defined(__HIP) +# include "../hip/acc_hip.h" +#endif +#include "acc_utils.h" + +template +__global__ void calculate_norms_d( + float* __restrict__ norms, const int* __restrict__ offsets, const int* __restrict__ nelems, const double* __restrict__ mat) { + __shared__ double buf[(blocksz + warpsz - 1) / warpsz]; + double d, sum = 0.0; + + /* Get the offset in the stack that this thread block should handle */ + int blkoffset = offsets[blockIdx.x]; + + /* Get the number of elements in this matrix */ + int nelem = nelems[blockIdx.x]; + + /* Loop over nelem matrix elements for this block */ + for (int i = threadIdx.x; i < nelem; i += blockDim.x) { + /* Load matrix elements, reduce in register */ + d = mat[blkoffset + i]; + sum += d * d; + } + __syncthreads(); + + /* reduce in warp to one value using warp level primitives */ +#if defined(__CUDA) + unsigned mask = 0xffffffff; + for (int offset = warpsz / 2; offset > 0; offset /= 2) { + sum += __shfl_down_sync(mask, sum, offset); + } +#elif defined(__HIP) + for (int offset = warpsz / 2; offset > 0; offset /= 2) { + sum += __shfl_down(sum, offset); + } +#endif + + /* reduce between warps if needed */ + if (blocksz > warpsz) { + if (threadIdx.x % warpsz == 0) { + int warpid = threadIdx.x / warpsz; + buf[warpid] = sum; + } + __syncthreads(); + if (threadIdx.x == 0) { + for (int i = 1; i < blocksz / warpsz; ++i) { + sum += buf[i]; + } + } + } + if (threadIdx.x == 0) { + /* write out this stack's dot product */ + norms[blockIdx.x] = sum; + } +} + +extern "C" int c_calculate_norms( + const double* mat, int nblks, const int* offsets, const int* nelems, float* norms, void* stream_ptr) { + int warp_size = acc_get_gpu_warp_size(); + + dim3 grid(nblks); + dim3 block(warp_size); + + ACC_DRV(stream) stream = *((ACC_DRV(stream)*)stream_ptr); + /* block size may be a multiple of warp_size as well */ + if (warp_size == 64) { + calculate_norms_d<64, 64><<>>(norms, offsets, nelems, mat); + } + else if (warp_size == 32) { + calculate_norms_d<32, 32><<>>(norms, offsets, nelems, mat); + } + else { + fprintf(stderr, "Found warp size other than 64 or 32, aborting..\n"); + return -1; + } + return 0; +} diff --git a/src/acc/dbcsr_acc_devmem.F b/src/acc/dbcsr_acc_devmem.F index 475414bfb4a..7c97019c42d 100644 --- a/src/acc/dbcsr_acc_devmem.F +++ b/src/acc/dbcsr_acc_devmem.F @@ -10,7 +10,7 @@ MODULE dbcsr_acc_devmem !! Accelerator support #if defined (__DBCSR_ACC) - USE ISO_C_BINDING, ONLY: C_INT, C_SIZE_T, C_PTR, C_LOC, C_NULL_PTR + USE ISO_C_BINDING, ONLY: C_INT, C_SIZE_T, C_PTR, C_LOC, C_NULL_PTR, C_ASSOCIATED #endif USE dbcsr_kinds, ONLY: int_4, & int_4_size, & @@ -255,6 +255,10 @@ FUNCTION acc_devmem_allocated(this) RESULT(res) LOGICAL :: res !! true if device memory is allocated, false otherwise +#if defined (__DBCSR_ACC) + DBCSR_ASSERT(C_ASSOCIATED(this%cptr) .OR. this%size_in_bytes <= 0) +#endif + res = this%size_in_bytes >= 0 END FUNCTION acc_devmem_allocated diff --git a/src/acc/libsmm_acc/kernels/smm_acc_predict.py b/src/acc/libsmm_acc/kernels/smm_acc_predict.py index 111b9a3c7df..b65f48cdaa5 100644 --- a/src/acc/libsmm_acc/kernels/smm_acc_predict.py +++ b/src/acc/libsmm_acc/kernels/smm_acc_predict.py @@ -42,7 +42,7 @@ "size_b", "size_c", # 'nblks', 'nthreads', # constant value for largeDB, since the grouping is always = 16 - "sm_desired" + "sm_desired", # 'warps_per_blk', 'nwarps', # linearly dependent on threads, nthreads # 'ru_param_stack_unroll_factor', # constant values for each algo ], diff --git a/src/acc/libsmm_acc/libsmm_acc.cpp b/src/acc/libsmm_acc/libsmm_acc.cpp index ade641a67d3..c7c6b044c4d 100644 --- a/src/acc/libsmm_acc/libsmm_acc.cpp +++ b/src/acc/libsmm_acc/libsmm_acc.cpp @@ -1,5 +1,6 @@ /*------------------------------------------------------------------------------------------------*/ /* Copyright (C) by the DBCSR developers group - All rights reserved */ +/* Copyright (C) 2022 Advanced Micro Devices, Inc. - All rights reserved */ /* This file is part of the DBCSR library. */ /* */ /* For information on the license, see the LICENSE file. */ @@ -140,8 +141,8 @@ inline void jit_kernel(ACC_DRV(function) & kern_func, libsmm_acc_algo algo, int const char* compileOptions[] = {"-D__CUDA", "-w", ARCH_OPTION}; size_t nOptions = 3; #else - const char* compileOptions[] = {"-D__HIP", "-O3", "-w"}; - size_t nOptions = 3; + const char* compileOptions[] = {"-D__HIP", "-O3", "-w", "-munsafe-fp-atomics"}; + size_t nOptions = 4; #endif ACC_RTC(Result) compileResult = ACC_RTC(CompileProgram)(kernel_program, nOptions, compileOptions); if (compileResult != ACC_RTC_SUCCESS) { diff --git a/src/acc/libsmm_acc/libsmm_acc_init.cpp b/src/acc/libsmm_acc/libsmm_acc_init.cpp index b29f7852c9b..381584c1e09 100644 --- a/src/acc/libsmm_acc/libsmm_acc_init.cpp +++ b/src/acc/libsmm_acc/libsmm_acc_init.cpp @@ -9,6 +9,7 @@ #include "libsmm_acc_init.h" #include "../acc_libsmm.h" +#include "../cuda_hip/acc_utils.h" #if defined(_OPENMP) # include @@ -102,15 +103,6 @@ int libsmm_acc_check_gpu_warp_size_consistency() { return 0; } -//=========================================================================== -int acc_get_gpu_warp_size() { - int device = 0; - ACC(DeviceProp) prop; - ACC_API_CALL(GetDevice, (&device)); - ACC_API_CALL(GetDeviceProperties, (&prop, device)); - return prop.warpSize; -} - //=========================================================================== extern "C" int libsmm_acc_is_thread_safe() { #if defined(_OPENMP) diff --git a/src/acc/libsmm_acc/libsmm_acc_init.h b/src/acc/libsmm_acc/libsmm_acc_init.h index c928cf550df..ea48c4a90f4 100644 --- a/src/acc/libsmm_acc/libsmm_acc_init.h +++ b/src/acc/libsmm_acc/libsmm_acc_init.h @@ -25,8 +25,6 @@ int libsmm_acc_gpu_blas_init(); int libsmm_acc_check_gpu_warp_size_consistency(void); -int acc_get_gpu_warp_size(void); - extern "C" int libsmm_acc_is_thread_safe(void); extern std::vector acc_blashandles; diff --git a/src/acc/libsmm_acc/predict/predict_collect.py b/src/acc/libsmm_acc/predict/predict_collect.py index 9dee95323af..ab41ebe1de2 100755 --- a/src/acc/libsmm_acc/predict/predict_collect.py +++ b/src/acc/libsmm_acc/predict/predict_collect.py @@ -105,12 +105,12 @@ def read_log_file(log_folder, m, n, k): "threads": match.group(9), "grouping": match.group(10), "minblocks": match.group(11), - "tile_m": match.group(5) - if match.group(5) is not None - else None, - "tile_n": match.group(6) - if match.group(6) is not None - else None, + "tile_m": ( + match.group(5) if match.group(5) is not None else None + ), + "tile_n": ( + match.group(6) if match.group(6) is not None else None + ), "w": match.group(7) if match.group(7) is not None else None, "v": match.group(8) if match.group(8) is not None else None, "perf (Gflop/s)": match.group(12), diff --git a/src/acc/libsmm_acc/predict/predict_train.py b/src/acc/libsmm_acc/predict/predict_train.py index 7370cc8990c..cf2b3845202 100755 --- a/src/acc/libsmm_acc/predict/predict_train.py +++ b/src/acc/libsmm_acc/predict/predict_train.py @@ -1184,9 +1184,9 @@ def get_predive_model_performances( perf_chosen_idx = [np.argmax(y_pred[idx_mnk])] perf_effective = y_true.iloc[idx_mnk].iloc[perf_chosen_idx].values.item() - predictive_model_perf_scaled[ - (m, n, k) - ] = perf_effective # 'scaled' between 0 and 1 + predictive_model_perf_scaled[(m, n, k)] = ( + perf_effective # 'scaled' between 0 and 1 + ) predictive_model_perf = dict( zip( diff --git a/src/acc/libsmm_acc/tune/tune_setup.py b/src/acc/libsmm_acc/tune/tune_setup.py index b2b2c042e6a..deb8a10011e 100755 --- a/src/acc/libsmm_acc/tune/tune_setup.py +++ b/src/acc/libsmm_acc/tune/tune_setup.py @@ -364,7 +364,9 @@ def gen_makefile(outdir, compiler, arch): + " -w -c -o $@ -std=c++11 $<\n\n" ) else: - output += "\thipcc -O3 -D__TUNING -D__HIP -w -c -o $@ $<\n\n" + output += ( + "\thipcc -O3 -D__TUNING -D__HIP -w -munsafe-fp-atomics -c -o $@ $<\n\n" + ) # compilation rule for kernel files headers = " ".join([f"../{fn}" for fn in Path("../kernels").glob("*.h")]) @@ -372,7 +374,7 @@ def gen_makefile(outdir, compiler, arch): if compiler == "nvcc": output += f" nvcc -O3 -D__TUNING -D__CUDA -arch={str(arch)} -w -c $<\n\n" else: - output += "\thipcc -O3 -D__TUNING -D__HIP -w -c $<\n\n" + output += "\thipcc -O3 -D__TUNING -D__HIP -w -munsafe-fp-atomics -c $<\n\n" # compilation rule for autotuning executables for exe_src in all_exe_src: @@ -396,7 +398,7 @@ def gen_makefile(outdir, compiler, arch): ) else: rocm_path = os.getenv("ROCM_PATH", "/opt/rocm") - output += f"\thipcc -O3 -D__HIP -w -o $@ $^ {rocm_path}/hip/lib/libamdhip64.so\n\n" + output += f"\thipcc -O3 -D__HIP -w -munsafe-fp-atomics -o $@ $^ {rocm_path}/hip/lib/libamdhip64.so\n\n" # write Makefile writefile(outdir / "Makefile", output) diff --git a/src/acc/opencl/Makefile b/src/acc/opencl/Makefile index 591dbe77895..81607ad860e 100644 --- a/src/acc/opencl/Makefile +++ b/src/acc/opencl/Makefile @@ -23,6 +23,7 @@ UNAME := $(shell uname) HEADERONLY ?= 0 STATIC ?= 1 INTEL ?= 0 +GNU ?= 0 DEV ?= 0 # select from set of predefined triplet specifications @@ -60,7 +61,7 @@ endif endif CFLAGS := -fPIC \ - -Wall -Wextra \ + -Wall -Wextra -Wcast-qual \ -Wno-overlength-strings \ -Wno-variadic-macros \ -Wno-unused-function \ @@ -80,6 +81,15 @@ else ifneq (0,$(INTEL)) CXX := icpx CC := icx AR := xiar +else ifneq (0,$(GNU)) + override CXX := g++ + override CC := gcc + ifneq (Darwin,$(UNAME)) + override AR := gcc-ar + else + override AR := ar + endif + override LD_LIBRARY_DIRS := $(NULL) else CXX := g++ CC := gcc @@ -126,7 +136,7 @@ ifneq (0,$(DBG)) CFLAGS += -O0 endif else - CFLAGS += -O2 -DNDEBUG -DNDBGDEV + CFLAGS += -O2 -DNDEBUG SYM := 0 endif ifneq (0,$(SYM)) @@ -186,17 +196,22 @@ else CUDATOOLKIT_HOME := $(if $(NVCC),$(abspath $(dir $(NVCC))/..)) endif ifneq (,$(CUDATOOLKIT_HOME)) + CUDA_LIBDIR := $(if $(wildcard $(CUDATOOLKIT_HOME)/lib64),lib64,lib) ifeq (,$(wildcard $(OPENCL_INC))) CLINC := $(strip $(lastword $(sort $(wildcard $(CUDATOOLKIT_HOME)/../cuda/*/targets/x86_64-linux/include/CL/cl.h)))) - ifneq (,$(CLINC)) - OPENCL_INC := $(abspath $(dir $(CLINC))/..) - else - CFLAGS += -I$(CUDATOOLKIT_HOME)/include - endif + OPENCL_INC := $(if $(CLINC),$(abspath $(dir $(CLINC))/..),$(CUDATOOLKIT_HOME)/include) endif ifeq (,$(wildcard $(OPENCL_LIB))) - LDFLAGS += -L$(CUDATOOLKIT_HOME)/lib64 - LDFLAGS += -Wl,-rpath=$(CUDATOOLKIT_HOME)/lib64 + LDFLAGS += -L$(CUDATOOLKIT_HOME)/$(CUDA_LIBDIR) + LDFLAGS += -Wl,-rpath=$(CUDATOOLKIT_HOME)/$(CUDA_LIBDIR) + endif + else ifeq (,$(OPENCL_INC)) + ifneq (,$(wildcard $(OPENCL_ROOT)/include/CL/cl.h)) + OPENCL_INC := $(OPENCL_ROOT)/include + LDFLAGS += -L$(OPENCL_ROOT)/lib64 + else ifneq (,$(wildcard $(OCL_ROOT)/include/CL/cl.h)) + OPENCL_INC := $(OCL_ROOT)/include + LDFLAGS += -L$(OCL_ROOT)/lib64 endif endif # OPENCL_INC: directory containing CL/cl.h. @@ -207,14 +222,14 @@ else ifneq (,$(wildcard $(OPENCL_LIB))) LDFLAGS += $(OPENCL_LIB) else - LDFLAGS += -lOpenCL + LDFLAGS += -l:libOpenCL.so.1 endif endif # Collect all paths in LD_LIBRARY_PATH and LD_LIBRARY_PATH/stubs, and append to LDFLAGS -LD_LIBRARY_PATH := $(wildcard $(subst :, ,$(LD_LIBRARY_PATH))) -LD_LIBSTUB_PATH := $(wildcard $(patsubst %,%/stubs,$(LD_LIBRARY_PATH))) -LIBPATHS := $(foreach DIR,$(LD_LIBRARY_PATH),$(if $(filter -L$(DIR),$(LDFLAGS)),$(NULL),-L$(DIR))) +LD_LIBRARY_DIRS := $(wildcard $(subst :, ,$(LD_LIBRARY_PATH))) +LD_LIBSTUB_PATH := $(wildcard $(patsubst %,%/stubs,$(LD_LIBRARY_DIRS))) +LIBPATHS := $(foreach DIR,$(LD_LIBRARY_DIRS),$(if $(filter -L$(DIR),$(LDFLAGS)),$(NULL),-L$(DIR))) LIBSTUBS := $(foreach DIR,$(LD_LIBSTUB_PATH),$(if $(filter -L$(DIR),$(LDFLAGS)),$(NULL),-L$(DIR))) LDFLAGS += $(LIBPATHS) $(LIBSTUBS) @@ -288,7 +303,7 @@ endif fi $(MAKDIR)/smm/opencl_kernels.h: $(MAKDIR)/acc_opencl.sh $(KERNEL) $(PARAMS) - @CPPFLAGS=$(CPP_OPENCL_FLAGS) $(MAKDIR)/acc_opencl.sh $(KERNEL) $(PARAMS) $@ + CPPFLAGS=$(CPP_OPENCL_FLAGS) $(MAKDIR)/acc_opencl.sh $(KERNEL) $(PARAMS) $@ .PHONY: backend backend: $(ACCDIR)/dbcsr_acc.a diff --git a/src/acc/opencl/README.md b/src/acc/opencl/README.md index e1a24129b4b..ef62147fc0a 100644 --- a/src/acc/opencl/README.md +++ b/src/acc/opencl/README.md @@ -1,12 +1,14 @@ -# OpenCL Backend +# Backend -## Overview +The OpenCL backend implements the [ACC interface](https://github.com/cp2k/dbcsr/blob/develop/src/acc/acc.h), which is exposed in Fortran and used throughout DBCSR's code base to drive (GPU-)acceleration based on ACC's device enumeration, data movement, and synchronization functionality. By design, DBCSR activates one device per rank (process). For instance, multiple GPUs can be used by the means of multiple ranks per system or at least one rank per device. The LIBSMM library complements the backend and implements the [ACC LIBSMM interface](https://github.com/cp2k/dbcsr/blob/develop/src/acc/acc_libsmm.h). -The OpenCL backend implements the [ACC interface](https://github.com/cp2k/dbcsr/blob/develop/src/acc/acc.h), which is exposed in Fortran and used throughout DBCSR's code base to drive (GPU-)acceleration based on ACC's device enumeration, data movement, and synchronization functionality. By design, DBCSR activates one device per rank (process). For instance, multiple GPUs can be used by the means of multiple ranks per system or at least one rank per device. +All major GPU vendors support OpenCL even if the vendor-preferred programming model suggests otherwise. On Nvidia GPUs, the OpenCL backend can be used with CUDA based GPU-code in other portions of CP2K. The OpenCL based backend provides the following benefits: -## Customization +* Code portability between GPU vendors (if not performance portability). For instance, performance of the OpenCL backend matches the performance of the CUDA backend or exceeds it. +* Acceptable performance for kernels not covered by specifically tuned parameters, and the ability to run on GPU if no tuned parameters are present. +* Auto-tuning kernels within an acceptable time limit along with handy scripts to retune parameters and to carry forward an existing set (new GPU). -Compile-time settings are (implicitly) documented and can be adjusted by editing [acc_opencl.h](https://github.com/cp2k/dbcsr/blob/develop/src/acc/opencl/acc_opencl.h). Runtime settings are made by the means of environment variables. The OpenCL backend provides `acc_getenv.sh` to list all occurrences of `getenv` categorized into "OpenCL Backend environment variables" and "OpenCL LIBSMM environment variables". Common backend related settings are: +Runtime settings are made by the means of environment variables. The OpenCL backend provides `acc_getenv.sh` to list all occurrences of `getenv` categorized into "OpenCL Backend environment variables" and "OpenCL LIBSMM environment variables". Common backend related settings are: * `ACC_OPENCL_DEVSPLIT`: integer enabling devices to be split into subdevices (non-zero/default: subdevices, zero: aggregated). * `ACC_OPENCL_DEVTYPE`: character string selecting "cpu", "gpu", "all" (unfiltered), or any other string (neither CPU or GPU). @@ -20,4 +22,4 @@ Compile-time settings are (implicitly) documented and can be adjusted by editing * `ACC_OPENCL_DUMP=1`: dump preprocessed kernel source code and use it for JIT compilation. Instantiates the original source code using preprocessor definitions (`-D`) and collapses the code accordingly. * `ACC_OPENCL_DUMP=2`: dump compiled OpenCL kernels (depends on OpenCL implementation), e.g., PTX code on Nvidia. -The OpenCL backend enumerates and orders devices by device-kind, i.e., GPU, CPU, and "other" (primary criterion) and by memory capacity (secondary criterion). Device IDs are zero-based as defined by the ACC interface (and less than what is permitted/returned by `acc_get_ndevices`). +The OpenCL backend enumerates and orders devices by kind, i.e., GPU, CPU, and "other" (primary criterion) and by memory capacity (secondary criterion). Device IDs are zero-based as defined by the ACC interface (and less than what is permitted by `acc_get_ndevices`). diff --git a/src/acc/opencl/acc_opencl.c b/src/acc/opencl/acc_opencl.c index cd7ab1d802d..64756cc7d11 100644 --- a/src/acc/opencl/acc_opencl.c +++ b/src/acc/opencl/acc_opencl.c @@ -28,8 +28,17 @@ # define S_ISDIR(A) ((S_IFMT & (A)) == S_IFDIR) # endif -# if !defined(ACC_OPENCL_CACHEDIR) && 1 -# define ACC_OPENCL_CACHEDIR ".cl_cache" +# if !defined(ACC_OPENCL_NLOCKS) +# define ACC_OPENCL_NLOCKS 4 +# endif +# if !defined(ACC_OPENCL_TEMPDIR) && 1 +# define ACC_OPENCL_TEMPDIR "/tmp" +# endif +# if !defined(ACC_OPENCL_CACHE_DID) && 1 +# define ACC_OPENCL_CACHE_DID +# endif +# if !defined(ACC_OPENCL_CACHE_DIR) && 0 +# define ACC_OPENCL_CACHE_DIR ".cl_cache" # endif # if !defined(ACC_OPENCL_CPPBIN) && 1 # define ACC_OPENCL_CPPBIN "/usr/bin/cpp" @@ -37,8 +46,12 @@ # if !defined(ACC_OPENCL_SEDBIN) && 1 # define ACC_OPENCL_SEDBIN "/usr/bin/sed" # endif +/* attempt to enable command aggregation */ +# if !defined(ACC_OPENCL_CMDAGR) && 1 +# define ACC_OPENCL_CMDAGR +# endif # if !defined(ACC_OPENCL_NCCS) && 1 -# define ACC_OPENCL_NCCS 4 +# define ACC_OPENCL_NCCS 0 # endif @@ -46,11 +59,22 @@ extern "C" { # endif +char c_dbcsr_acc_opencl_locks[ACC_OPENCL_CACHELINE * ACC_OPENCL_NLOCKS]; /* global configuration discovered during initialization */ c_dbcsr_acc_opencl_config_t c_dbcsr_acc_opencl_config; +# if defined(ACC_OPENCL_CACHE_DID) +int c_dbcsr_acc_opencl_active_id; +# endif + + +void __wrap__gfortran_runtime_warning_at(const char* /*where*/, const char* /*message*/, ...); +void __wrap__gfortran_runtime_warning_at(const char* where, const char* message, ...) { + LIBXSMM_UNUSED(message); + LIBXSMM_UNUSED(where); +} + -# if !defined(NDEBUG) void c_dbcsr_acc_opencl_notify(const char /*errinfo*/[], const void* /*private_info*/, size_t /*cb*/, void* /*user_data*/); void c_dbcsr_acc_opencl_notify(const char errinfo[], const void* private_info, size_t cb, void* user_data) { LIBXSMM_UNUSED(private_info); @@ -58,48 +82,6 @@ void c_dbcsr_acc_opencl_notify(const char errinfo[], const void* private_info, s LIBXSMM_UNUSED(user_data); fprintf(stderr, "ERROR ACC/OpenCL: %s\n", errinfo); } -# endif - - -cl_context c_dbcsr_acc_opencl_context(int* thread_id) { - cl_context result; - const int tid = ACC_OPENCL_OMP_TID(); - assert(0 <= tid && tid < c_dbcsr_acc_opencl_config.nthreads); - assert(NULL != c_dbcsr_acc_opencl_config.device); - result = c_dbcsr_acc_opencl_config.device[tid].context; - if (NULL == result) { /* fallback */ - int i = 0; /* prefer master's context */ - for (; i < c_dbcsr_acc_opencl_config.nthreads; ++i) { - if (tid != i) { /* adopt another context */ - result = c_dbcsr_acc_opencl_config.device[i].context; - if (NULL != result && CL_SUCCESS == clRetainContext(result)) break; - else result = NULL; - } - } - } - if (NULL != thread_id) *thread_id = tid; - return result; -} - - -cl_context c_dbcsr_acc_opencl_device_context(cl_device_id device, const int* thread_id) { - const int i0 = (NULL != thread_id ? *thread_id : /*main*/ 0); - cl_context result = NULL; - int i = 0; - for (; i < c_dbcsr_acc_opencl_config.nthreads; ++i) { - const int j = i + i0, tid = (j < c_dbcsr_acc_opencl_config.nthreads ? j : (j - c_dbcsr_acc_opencl_config.nthreads)); - result = c_dbcsr_acc_opencl_config.device[tid].context; - if (NULL != result) { - cl_device_id device_id = NULL; - if (CL_SUCCESS == clGetContextInfo(result, CL_CONTEXT_DEVICES, sizeof(cl_device_id), &device_id, NULL) && device == device_id) - { - break; - } - else result = NULL; - } - } - return result; -} /** @@ -164,23 +146,52 @@ int c_dbcsr_acc_opencl_order_devices(const void* dev_a, const void* dev_b) { } -int c_dbcsr_acc_opencl_order_streams(const void* /*a*/, const void* /*b*/); -int c_dbcsr_acc_opencl_order_streams(const void* a, const void* b) { /* NULL-pointers are sorted to the upper end */ - const cl_command_queue *const p = (const cl_command_queue*)a, *const q = (const cl_command_queue*)b; - assert(NULL != p && NULL != q); - return *p < *q ? -1 : (*p > *q ? 1 : 0); -} - - -LIBXSMM_ATTRIBUTE_CTOR void c_dbcsr_acc_opencl_init(void) { - /* attempt to automatically initialize backend */ - ACC_OPENCL_EXPECT(EXIT_SUCCESS == c_dbcsr_acc_init()); -} +/* attempt to automatically initialize backend */ +LIBXSMM_ATTRIBUTE_CTOR void c_dbcsr_acc_opencl_init(void) { ACC_OPENCL_EXPECT(EXIT_SUCCESS == c_dbcsr_acc_init()); } +/* attempt to automatically finalize backend */ LIBXSMM_ATTRIBUTE_DTOR void c_dbcsr_acc_opencl_finalize(void) { - /* attempt to automatically finalize backend */ - ACC_OPENCL_EXPECT(EXIT_SUCCESS == c_dbcsr_acc_finalize()); + assert(c_dbcsr_acc_opencl_config.ndevices < ACC_OPENCL_MAXNDEVS); + if (0 != c_dbcsr_acc_opencl_config.ndevices) { + int i; + for (i = 0; i < ACC_OPENCL_MAXNDEVS; ++i) { + const cl_device_id device_id = c_dbcsr_acc_opencl_config.devices[i]; + if (NULL != device_id) { +# if defined(CL_VERSION_1_2) && defined(_DEBUG) + ACC_OPENCL_EXPECT(EXIT_SUCCESS == clReleaseDevice(device_id)); +# endif + /* c_dbcsr_acc_opencl_create_context scans for non-NULL devices */ + c_dbcsr_acc_opencl_config.devices[i] = NULL; + } + } + if (NULL != c_dbcsr_acc_opencl_config.device.stream.queue) { /* release private stream */ + clReleaseCommandQueue(c_dbcsr_acc_opencl_config.device.stream.queue); /* ignore return code */ + } + if (NULL != c_dbcsr_acc_opencl_config.device.context) { + const cl_context context = c_dbcsr_acc_opencl_config.device.context; + c_dbcsr_acc_opencl_config.device.context = NULL; + clReleaseContext(context); /* ignore return code */ + } + for (i = 0; i < ACC_OPENCL_NLOCKS; ++i) { /* destroy locks */ + ACC_OPENCL_DESTROY((ACC_OPENCL_LOCKTYPE*)(c_dbcsr_acc_opencl_locks + ACC_OPENCL_CACHELINE * i)); + } + /* release/reset buffers */ +# if defined(ACC_OPENCL_MEM_DEVPTR) + free(c_dbcsr_acc_opencl_config.memptrs); + free(c_dbcsr_acc_opencl_config.memptr_data); +# endif + free(c_dbcsr_acc_opencl_config.streams); + free(c_dbcsr_acc_opencl_config.stream_data); + free(c_dbcsr_acc_opencl_config.events); + free(c_dbcsr_acc_opencl_config.event_data); + /* clear entire configuration structure */ + memset(&c_dbcsr_acc_opencl_config, 0, sizeof(c_dbcsr_acc_opencl_config)); +# if defined(ACC_OPENCL_CACHE_DID) + c_dbcsr_acc_opencl_active_id = 0; /* reset cached active device-ID */ +# endif + libxsmm_finalize(); + } } @@ -198,90 +209,153 @@ int c_dbcsr_acc_init(void) { c_dbcsr_timeset((const char**)&routine_name_ptr, &routine_name_len, &routine_handle); # endif if (EXIT_SUCCESS == result && 0 == c_dbcsr_acc_opencl_config.ndevices) { /* avoid to initialize multiple times */ - cl_platform_id platforms[ACC_OPENCL_DEVICES_MAXCOUNT] = {NULL}; - cl_device_id devices[ACC_OPENCL_DEVICES_MAXCOUNT]; + cl_platform_id platforms[ACC_OPENCL_MAXNDEVS] = {NULL}; + cl_device_id devices[ACC_OPENCL_MAXNDEVS]; char buffer[ACC_OPENCL_BUFFERSIZE]; const char *const env_devmatch = getenv("ACC_OPENCL_DEVMATCH"), *const env_devtype = getenv("ACC_OPENCL_DEVTYPE"); const char *const env_priority = getenv("ACC_OPENCL_PRIORITY"), *const env_xhints = getenv("ACC_OPENCL_XHINTS"); - const char *const env_devcopy = getenv("ACC_OPENCL_DEVCOPY"), *const env_verbose = getenv("ACC_OPENCL_VERBOSE"); - const char *const env_dump_acc = getenv("ACC_OPENCL_DUMP"), *const env_share = getenv("ACC_OPENCL_SHARE"); - const char *const env_device = getenv("ACC_OPENCL_DEVICE"), *const env_async = getenv("ACC_OPENCL_ASYNC"); - const char *const env_flush = getenv("ACC_OPENCL_FLUSH"), *const env_timer = getenv("ACC_OPENCL_TIMER"); + const char *const env_verbose = getenv("ACC_OPENCL_VERBOSE"), *const env_debug = getenv("ACC_OPENCL_DEBUG"); + const char *const env_device = getenv("ACC_OPENCL_DEVICE"), *const env_dump_acc = getenv("ACC_OPENCL_DUMP"); + const char *const env_timer = getenv("ACC_OPENCL_TIMER"), *const env_nlocks = getenv("ACC_OPENCL_NLOCKS"); const char* const env_dump = (NULL != env_dump_acc ? env_dump_acc : getenv("IGC_ShaderDumpEnable")); -# if defined(ACC_OPENCL_NCCS) && (0 < ACC_OPENCL_NCCS) - const char *const env_zex = getenv("ZEX_NUMBER_OF_CCS"), *const env_nccs = getenv("ACC_OPENCL_NCCS"); - const int nccs = (NULL == env_nccs ? 0 : atoi(env_nccs)); +# if defined(ACC_OPENCL_NCCS) + const char* const env_nccs = getenv("ACC_OPENCL_NCCS"); + const int nccs = (NULL == env_nccs ? ACC_OPENCL_NCCS : atoi(env_nccs)); +# endif + const char *const env_neo = getenv("NEOReadDebugKeys"), *const env_wa = getenv("ACC_OPENCL_WA"); + const int neo = (NULL == env_neo ? 1 : atoi(env_neo)), wa = neo * (NULL == env_wa ? 3 : atoi(env_wa)); +# if defined(ACC_OPENCL_ASYNC) + const char* const env_async = (ACC_OPENCL_ASYNC); + const int async_default = 3; +# else + const char* const env_async = NULL; + const int async_default = 0; # endif char* const env_devids = getenv("ACC_OPENCL_DEVIDS"); int device_id = (NULL == env_device ? 0 : atoi(env_device)); + const int nlocks = (NULL == env_nlocks ? 1 /*default*/ : atoi(env_nlocks)); cl_uint nplatforms = 0, ndevices = 0, i; cl_device_type type = CL_DEVICE_TYPE_ALL; # if defined(_OPENMP) const int max_threads = omp_get_max_threads(), num_threads = omp_get_num_threads(); c_dbcsr_acc_opencl_config.nthreads = (num_threads < max_threads ? max_threads : num_threads); + c_dbcsr_acc_opencl_config.nstreams = (num_threads < max_threads ? (ACC_OPENCL_MAXNITEMS * max_threads) + : (ACC_OPENCL_MAXNITEMS)); # else c_dbcsr_acc_opencl_config.nthreads = 1; + c_dbcsr_acc_opencl_config.nstreams = ACC_OPENCL_MAXNITEMS; +# endif +# if defined(ACC_OPENCL_CACHE_DID) + assert(0 == c_dbcsr_acc_opencl_active_id); # endif + assert(sizeof(ACC_OPENCL_LOCKTYPE) <= ACC_OPENCL_CACHELINE); + for (i = 0; i < ACC_OPENCL_NLOCKS; ++i) { + ACC_OPENCL_INIT((ACC_OPENCL_LOCKTYPE*)(c_dbcsr_acc_opencl_locks + ACC_OPENCL_CACHELINE * i)); + } + c_dbcsr_acc_opencl_config.lock_main = (ACC_OPENCL_LOCKTYPE*)c_dbcsr_acc_opencl_locks; + c_dbcsr_acc_opencl_config.lock_memory = /* 2nd lock-domain */ + (1 < LIBXSMM_MIN(nlocks, ACC_OPENCL_NLOCKS) ? ((ACC_OPENCL_LOCKTYPE*)(c_dbcsr_acc_opencl_locks + ACC_OPENCL_CACHELINE * 1)) + : c_dbcsr_acc_opencl_config.lock_main); + c_dbcsr_acc_opencl_config.lock_stream = /* 3rd lock-domain */ + (2 < LIBXSMM_MIN(nlocks, ACC_OPENCL_NLOCKS) ? ((ACC_OPENCL_LOCKTYPE*)(c_dbcsr_acc_opencl_locks + ACC_OPENCL_CACHELINE * 2)) + : c_dbcsr_acc_opencl_config.lock_main); + c_dbcsr_acc_opencl_config.lock_event = /* 4th lock-domain */ + (3 < LIBXSMM_MIN(nlocks, ACC_OPENCL_NLOCKS) ? ((ACC_OPENCL_LOCKTYPE*)(c_dbcsr_acc_opencl_locks + ACC_OPENCL_CACHELINE * 3)) + : c_dbcsr_acc_opencl_config.lock_main); c_dbcsr_acc_opencl_config.verbosity = (NULL == env_verbose ? 0 : atoi(env_verbose)); c_dbcsr_acc_opencl_config.priority = (NULL == env_priority ? /*default*/ 3 : atoi(env_priority)); - c_dbcsr_acc_opencl_config.devcopy = (NULL == env_devcopy ? /*default*/ 0 : atoi(env_devcopy)); - c_dbcsr_acc_opencl_config.xhints = (NULL == env_xhints ? /*default*/ 1 : atoi(env_xhints)); - c_dbcsr_acc_opencl_config.share = (NULL == env_share ? /*default*/ 0 : atoi(env_share)); - c_dbcsr_acc_opencl_config.async = (NULL == env_async ? /*default*/ 3 : atoi(env_async)); - c_dbcsr_acc_opencl_config.flush = (NULL == env_flush ? /*default*/ 0 : atoi(env_flush)); + c_dbcsr_acc_opencl_config.xhints = (NULL == env_xhints ? /*default*/ 7 : atoi(env_xhints)); + c_dbcsr_acc_opencl_config.async = (NULL == env_async ? async_default : atoi(env_async)); c_dbcsr_acc_opencl_config.dump = (NULL == env_dump ? /*default*/ 0 : atoi(env_dump)); + c_dbcsr_acc_opencl_config.debug = (NULL == env_debug ? c_dbcsr_acc_opencl_config.dump : atoi(env_debug)); if (EXIT_SUCCESS != c_dbcsr_acc_opencl_device_uid(NULL /*device*/, env_devmatch, &c_dbcsr_acc_opencl_config.devmatch)) { c_dbcsr_acc_opencl_config.devmatch = 1; } libxsmm_init(); - /* sanitize ACC_OPENCL_SHARE */ - if (1 == c_dbcsr_acc_opencl_config.share) c_dbcsr_acc_opencl_config.share = 2; - else if (0 > c_dbcsr_acc_opencl_config.share) c_dbcsr_acc_opencl_config.share = 0; if (NULL != env_timer && (c_dbcsr_acc_opencl_timer_host == atoi(env_timer) || (env_timer == LIBXSMM_STRISTR(env_timer, "host") && 4 == strlen(env_timer)) || (env_timer == LIBXSMM_STRISTR(env_timer, "cpu") && 3 == strlen(env_timer)))) { c_dbcsr_acc_opencl_config.timer = c_dbcsr_acc_opencl_timer_host; } -# if defined(ACC_OPENCL_NCCS) && (0 < ACC_OPENCL_NCCS) - if ((NULL == env_zex && 0 == (4 & c_dbcsr_acc_opencl_config.xhints)) || 0 != nccs) { - static char zex_number_of_ccs[ACC_OPENCL_DEVICES_MAXCOUNT * 8 + 32] = "ZEX_NUMBER_OF_CCS="; - int j = strlen(zex_number_of_ccs); - for (i = 0; i < ACC_OPENCL_DEVICES_MAXCOUNT; ++i) { - const int n = LIBXSMM_SNPRINTF( - zex_number_of_ccs + j, sizeof(zex_number_of_ccs) - j, 0 < i ? ",%u:%i" : "%u:%i", i, 0 >= nccs ? ACC_OPENCL_NCCS : nccs); + if (NULL == getenv("ZE_FLAT_DEVICE_HIERARCHY") && 0 != (1 & c_dbcsr_acc_opencl_config.xhints)) { + static char ze_flat[] = "ZE_FLAT_DEVICE_HIERARCHY=COMPOSITE"; + /* environment is populated before touching the compute runtime */ + ACC_OPENCL_EXPECT(0 == LIBXSMM_PUTENV(ze_flat)); /* soft-error */ + } +# if defined(ACC_OPENCL_NCCS) + if (NULL == getenv("ZEX_NUMBER_OF_CCS") && 0 != nccs) { + static char zex_nccs[ACC_OPENCL_MAXNDEVS * 8 + 32] = "ZEX_NUMBER_OF_CCS="; + int j = strlen(zex_nccs); + for (i = 0; i < ACC_OPENCL_MAXNDEVS; ++i) { + const char* const istr = (0 < i ? ",%u:%i" : "%u:%i"); + const int n = LIBXSMM_SNPRINTF(zex_nccs + j, sizeof(zex_nccs) - j, istr, i, LIBXSMM_MAX(nccs, 1)); if (0 < n) j += n; else { j = 0; break; } } - if (0 < j) ACC_OPENCL_EXPECT(0 == LIBXSMM_PUTENV(zex_number_of_ccs)); /* soft-error */ + /* environment is populated before touching the compute runtime */ + if (0 < j) ACC_OPENCL_EXPECT(0 == LIBXSMM_PUTENV(zex_nccs)); /* soft-error */ } # endif -# if defined(ACC_OPENCL_CACHEDIR) - { - const char* const env_cache = getenv("ACC_OPENCL_CACHE"); - const int cache = (NULL == env_cache ? CL_FALSE : (0 != atoi(env_cache) ? CL_TRUE : CL_FALSE)); + if (0 != wa) { /* environment is populated before touching the compute runtime */ + static char* key_value[] = { + "NEOReadDebugKeys=1", "EnableRecoverablePageFaults=0", "DirectSubmissionOverrideBlitterSupport=0"}; + if (NULL == env_neo) ACC_OPENCL_EXPECT(0 == LIBXSMM_PUTENV(key_value[0])); + if (0 != (1 & wa) && NULL == getenv("EnableRecoverablePageFaults")) { + ACC_OPENCL_EXPECT(0 == LIBXSMM_PUTENV(key_value[1])); + } + if (0 != (2 & wa) && NULL == getenv("DirectSubmissionOverrideBlitterSupport")) { + ACC_OPENCL_EXPECT(0 == LIBXSMM_PUTENV(key_value[2])); + } + } +# if defined(ACC_OPENCL_CACHE_DIR) + { /* environment is populated before touching the compute runtime */ + const char *const env_cache = getenv("ACC_OPENCL_CACHE"), *env_cachedir = getenv("NEO_CACHE_DIR"); + int cache = (NULL == env_cache ? 0 : atoi(env_cache)); struct stat cachedir; - if (0 != cache || (stat(ACC_OPENCL_CACHEDIR, &cachedir) == 0 && S_ISDIR(cachedir.st_mode))) { -# if !defined(_WIN32) - static char cl_cache_dir[] = "cl_cache_dir=" ACC_OPENCL_CACHEDIR; + if (0 == cache) { + if (stat(ACC_OPENCL_CACHE_DIR, &cachedir) == 0 && S_ISDIR(cachedir.st_mode)) cache = 1; + else if (stat(ACC_OPENCL_TEMPDIR "/" ACC_OPENCL_CACHE_DIR, &cachedir) == 0 && S_ISDIR(cachedir.st_mode)) cache = 2; + } + if (1 == cache) { + static char neo_cachedir[] = "NEO_CACHE_DIR=" ACC_OPENCL_CACHE_DIR; + static char ocl_cachedir[] = "cl_cache_dir=" ACC_OPENCL_CACHE_DIR; + ACC_OPENCL_EXPECT(0 == LIBXSMM_PUTENV(neo_cachedir)); /* putenv before entering OpenCL */ + ACC_OPENCL_EXPECT(0 == LIBXSMM_PUTENV(ocl_cachedir)); /* putenv before entering OpenCL */ + env_cachedir = ACC_OPENCL_CACHE_DIR; + } +# if defined(ACC_OPENCL_TEMPDIR) + else if (NULL == env_cachedir) { /* code-path entered by default */ + if (NULL == env_cache || 0 != cache) { /* customize NEO_CACHE_DIR unless ACC_OPENCL_CACHE=0 */ + static char neo_cachedir[] = "NEO_CACHE_DIR=" ACC_OPENCL_TEMPDIR "/" ACC_OPENCL_CACHE_DIR; + ACC_OPENCL_EXPECT(0 == LIBXSMM_PUTENV(neo_cachedir)); /* putenv before entering OpenCL */ + env_cachedir = ACC_OPENCL_TEMPDIR "/" ACC_OPENCL_CACHE_DIR; + } + if (0 != cache) { /* legacy-NEO is treated with explicit opt-in */ + static char ocl_cachedir[] = "cl_cache_dir=" ACC_OPENCL_TEMPDIR "/" ACC_OPENCL_CACHE_DIR; + ACC_OPENCL_EXPECT(0 == LIBXSMM_PUTENV(ocl_cachedir)); /* putenv before entering OpenCL */ + } + } +# endif + if (NULL != env_cachedir) { +# if defined(_WIN32) + LIBXSMM_UNUSED(env_cachedir); +# else # if defined(S_IRWXU) && defined(S_IRGRP) && defined(S_IXGRP) && defined(S_IROTH) && defined(S_IXOTH) const int mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; # else const int mode = 0xFFFFFFFF; # endif - if (0 == mkdir(ACC_OPENCL_CACHEDIR, mode) || EEXIST == errno) { /* putenv before entering OpenCL */ - ACC_OPENCL_EXPECT(0 == LIBXSMM_PUTENV(cl_cache_dir)); /* soft-error */ - } + ACC_OPENCL_EXPECT(0 == mkdir(env_cachedir, mode) || EEXIST == errno); /* soft-error */ # endif } } # endif - if (CL_SUCCESS == clGetPlatformIDs(0, NULL, &nplatforms) && 0 < nplatforms) { - ACC_OPENCL_CHECK( - clGetPlatformIDs(nplatforms <= ACC_OPENCL_DEVICES_MAXCOUNT ? nplatforms : ACC_OPENCL_DEVICES_MAXCOUNT, platforms, 0), + if (EXIT_SUCCESS == clGetPlatformIDs(0, NULL, &nplatforms) && 0 < nplatforms) { + ACC_OPENCL_CHECK(clGetPlatformIDs(nplatforms <= ACC_OPENCL_MAXNDEVS ? nplatforms : ACC_OPENCL_MAXNDEVS, platforms, 0), "retrieve platform ids", result); } if (EXIT_SUCCESS == result) { @@ -301,7 +375,7 @@ int c_dbcsr_acc_init(void) { } c_dbcsr_acc_opencl_config.ndevices = 0; for (i = 0; i < nplatforms; ++i) { - if (CL_SUCCESS == clGetDeviceIDs(platforms[i], type, 0, NULL, &ndevices) && 0 < ndevices) { + if (EXIT_SUCCESS == clGetDeviceIDs(platforms[i], type, 0, NULL, &ndevices) && 0 < ndevices) { ACC_OPENCL_CHECK(clGetDeviceIDs(platforms[i], type, ndevices, devices, NULL), "retrieve device ids", result); if (EXIT_SUCCESS == result) { cl_uint j = 0; @@ -316,24 +390,32 @@ int c_dbcsr_acc_init(void) { cl_device_partition_property properties[] = { CL_DEVICE_PARTITION_BY_AFFINITY_DOMAIN, CL_DEVICE_AFFINITY_DOMAIN_NUMA, /*terminator*/ 0}; cl_uint nunits = 0; - if (1 < devsplit && - CL_SUCCESS == clGetDeviceInfo(devices[j], CL_DEVICE_MAX_COMPUTE_UNITS, sizeof(cl_uint), &nunits, NULL)) + if (0 != devsplit && + EXIT_SUCCESS == clGetDeviceInfo(devices[j], CL_DEVICE_MAX_COMPUTE_UNITS, sizeof(cl_uint), &nunits, NULL) && + 1 < nunits) { - properties[0] = CL_DEVICE_PARTITION_EQUALLY; - properties[1] = nunits / devsplit; + if (1 < devsplit) { + properties[0] = CL_DEVICE_PARTITION_EQUALLY; + properties[1] = (nunits + devsplit - 1) / devsplit; + } } if ((NULL != env_devsplit && '0' == *env_devsplit) || - (c_dbcsr_acc_opencl_config.ndevices + 1) == ACC_OPENCL_DEVICES_MAXCOUNT || - (CL_SUCCESS != clCreateSubDevices(devices[j], properties, 0, NULL, &n))) + (c_dbcsr_acc_opencl_config.ndevices + 1) == ACC_OPENCL_MAXNDEVS || + (EXIT_SUCCESS != clCreateSubDevices(devices[j], properties, 0, NULL, &n))) # endif { c_dbcsr_acc_opencl_config.devices[c_dbcsr_acc_opencl_config.ndevices] = devices[j]; ++c_dbcsr_acc_opencl_config.ndevices; } # if defined(CL_VERSION_1_2) - else if (1 < n) { /* create subdevices */ - if (ACC_OPENCL_DEVICES_MAXCOUNT < (c_dbcsr_acc_opencl_config.ndevices + n)) { - n = (cl_uint)ACC_OPENCL_DEVICES_MAXCOUNT - c_dbcsr_acc_opencl_config.ndevices; + else if (1 < n || 1 < nunits) { /* create subdevices */ + if (1 < nunits) { + properties[0] = CL_DEVICE_PARTITION_EQUALLY; + properties[1] = 1; + n = nunits; + } + if (ACC_OPENCL_MAXNDEVS < (c_dbcsr_acc_opencl_config.ndevices + n)) { + n = (cl_uint)ACC_OPENCL_MAXNDEVS - c_dbcsr_acc_opencl_config.ndevices; } if (EXIT_SUCCESS == clCreateSubDevices(devices[j], properties, n, c_dbcsr_acc_opencl_config.devices + c_dbcsr_acc_opencl_config.ndevices, NULL)) @@ -358,12 +440,12 @@ int c_dbcsr_acc_init(void) { /* filter device by vendor (if requested) */ if (NULL != env_vendor && '\0' != *env_vendor) { for (i = 0; (int)i < c_dbcsr_acc_opencl_config.ndevices;) { - if (CL_SUCCESS == + if (EXIT_SUCCESS == clGetDeviceInfo(c_dbcsr_acc_opencl_config.devices[i], CL_DEVICE_VENDOR, ACC_OPENCL_BUFFERSIZE, buffer, NULL)) { if (NULL == LIBXSMM_STRISTR(buffer, env_vendor)) { # if defined(CL_VERSION_1_2) - ACC_OPENCL_EXPECT(CL_SUCCESS == clReleaseDevice(c_dbcsr_acc_opencl_config.devices[i])); + ACC_OPENCL_EXPECT(EXIT_SUCCESS == clReleaseDevice(c_dbcsr_acc_opencl_config.devices[i])); # endif --c_dbcsr_acc_opencl_config.ndevices; if ((int)i < c_dbcsr_acc_opencl_config.ndevices) { /* keep original order (stable) */ @@ -383,12 +465,9 @@ int c_dbcsr_acc_init(void) { } /* ACC_OPENCL_DEVIDS is parsed as a list of devices (whitelist) */ if (EXIT_SUCCESS == result && NULL != env_devids && '\0' != *env_devids) { - cl_uint devids[ACC_OPENCL_DEVICES_MAXCOUNT], ndevids = 0; - const char* const end = env_devids + strlen(env_devids); /* before strtok */ - char* did = strtok(env_devids, ACC_OPENCL_DELIMS); - for (; NULL != did && ndevids < ACC_OPENCL_DEVICES_MAXCOUNT; - did = ((did + 1) < end ? strtok((did + 1) + strlen(did), ACC_OPENCL_DELIMS) : NULL)) - { + cl_uint devids[ACC_OPENCL_MAXNDEVS], ndevids = 0; + char* did = strtok(env_devids, ACC_OPENCL_DELIMS " "); + for (; NULL != did && ndevids < ACC_OPENCL_MAXNDEVS; did = strtok(NULL, ACC_OPENCL_DELIMS " ")) { const int id = atoi(did); if (0 <= id && id < c_dbcsr_acc_opencl_config.ndevices) devids[ndevids++] = id; } @@ -404,7 +483,7 @@ int c_dbcsr_acc_init(void) { while (++j < ndevids); if (0 == match) { # if defined(CL_VERSION_1_2) - ACC_OPENCL_EXPECT(CL_SUCCESS == clReleaseDevice(c_dbcsr_acc_opencl_config.devices[i])); + ACC_OPENCL_EXPECT(EXIT_SUCCESS == clReleaseDevice(c_dbcsr_acc_opencl_config.devices[i])); # endif c_dbcsr_acc_opencl_config.devices[i] = NULL; } @@ -424,14 +503,14 @@ int c_dbcsr_acc_init(void) { } } if (EXIT_SUCCESS == result && 0 < c_dbcsr_acc_opencl_config.ndevices) { - /* preselect any default device or prune to homogeneous set of GPUs */ + /* preselect any default device or prune to homogeneous set of devices */ if (NULL == env_device || '\0' == *env_device) { char tmp[ACC_OPENCL_BUFFERSIZE] = ""; ndevices = (cl_uint)c_dbcsr_acc_opencl_config.ndevices; for (i = 0; i < ndevices; ++i) { cl_device_type itype; result = clGetDeviceInfo(c_dbcsr_acc_opencl_config.devices[i], CL_DEVICE_TYPE, sizeof(cl_device_type), &itype, NULL); - if (CL_SUCCESS == result) { + if (EXIT_SUCCESS == result) { if (0 != (CL_DEVICE_TYPE_DEFAULT & itype)) { if (0 < i) { c_dbcsr_acc_opencl_config.devices[0] = c_dbcsr_acc_opencl_config.devices[i]; @@ -440,9 +519,9 @@ int c_dbcsr_acc_init(void) { device_id = (int)i; break; } - else if (CL_DEVICE_TYPE_ALL == type && NULL == env_devtype && CL_DEVICE_TYPE_GPU == itype && device_id <= (int)i) { + else if (CL_DEVICE_TYPE_ALL == type && NULL == env_devtype /*&& CL_DEVICE_TYPE_GPU == itype*/ && device_id <= (int)i) { result = clGetDeviceInfo(c_dbcsr_acc_opencl_config.devices[i], CL_DEVICE_NAME, ACC_OPENCL_BUFFERSIZE, buffer, NULL); - if (CL_SUCCESS == result /* prune for homogeneous set of GPUs */ + if (EXIT_SUCCESS == result /* prune for homogeneous set of devices */ && ('\0' == *tmp || 0 == strncmp(buffer, tmp, ACC_OPENCL_BUFFERSIZE))) { c_dbcsr_acc_opencl_config.ndevices = i + 1; @@ -467,58 +546,87 @@ int c_dbcsr_acc_init(void) { } if (device_id < c_dbcsr_acc_opencl_config.ndevices) { if (EXIT_SUCCESS == result) { - assert(NULL == c_dbcsr_acc_opencl_config.device && 0 < c_dbcsr_acc_opencl_config.ndevices); - assert(c_dbcsr_acc_opencl_config.ndevices < ACC_OPENCL_DEVICES_MAXCOUNT); - c_dbcsr_acc_opencl_config.device = (c_dbcsr_acc_opencl_device_t*)calloc(/* thread-specific */ - c_dbcsr_acc_opencl_config.nthreads, sizeof(c_dbcsr_acc_opencl_device_t)); - if (NULL != c_dbcsr_acc_opencl_config.device) { - result = c_dbcsr_acc_opencl_set_active_device(/*main*/ 0, device_id); - assert(EXIT_SUCCESS == result || NULL == c_dbcsr_acc_opencl_config.device[/*main*/ 0].context); - if (1 < c_dbcsr_acc_opencl_config.verbosity || 0 > c_dbcsr_acc_opencl_config.verbosity) { + const size_t nhandles = ACC_OPENCL_MAXNITEMS * c_dbcsr_acc_opencl_config.nthreads; + assert(0 < c_dbcsr_acc_opencl_config.ndevices); + assert(c_dbcsr_acc_opencl_config.ndevices < ACC_OPENCL_MAXNDEVS); +# if defined(ACC_OPENCL_MEM_DEVPTR) + c_dbcsr_acc_opencl_config.memptrs = NULL; + c_dbcsr_acc_opencl_config.memptr_data = NULL; + c_dbcsr_acc_opencl_config.nmemptrs = 0; +# endif + c_dbcsr_acc_opencl_config.streams = NULL; + c_dbcsr_acc_opencl_config.events = NULL; + c_dbcsr_acc_opencl_config.stream_data = NULL; + c_dbcsr_acc_opencl_config.event_data = NULL; + c_dbcsr_acc_opencl_config.nstreams = c_dbcsr_acc_opencl_config.nevents = 0; +# if defined(ACC_OPENCL_CACHE_DID) + c_dbcsr_acc_opencl_active_id = device_id + 1; /* update c_dbcsr_acc_opencl_active_id */ +# endif +# if defined(ACC_OPENCL_MEM_DEVPTR) /* allocate and initialize memptr registry */ + c_dbcsr_acc_opencl_config.nmemptrs = nhandles; + c_dbcsr_acc_opencl_config.memptrs = (c_dbcsr_acc_opencl_info_memptr_t**)malloc( + sizeof(c_dbcsr_acc_opencl_info_memptr_t*) * nhandles); + c_dbcsr_acc_opencl_config.memptr_data = (c_dbcsr_acc_opencl_info_memptr_t*)malloc( + sizeof(c_dbcsr_acc_opencl_info_memptr_t) * nhandles); + if (NULL != c_dbcsr_acc_opencl_config.memptrs && NULL != c_dbcsr_acc_opencl_config.memptr_data) { + c_dbcsr_acc_opencl_pmalloc_init(NULL /*lock*/, sizeof(c_dbcsr_acc_opencl_info_memptr_t), + &c_dbcsr_acc_opencl_config.nmemptrs, (void**)c_dbcsr_acc_opencl_config.memptrs, c_dbcsr_acc_opencl_config.memptr_data); + } + else { + free(c_dbcsr_acc_opencl_config.memptrs); + free(c_dbcsr_acc_opencl_config.memptr_data); + c_dbcsr_acc_opencl_config.memptr_data = NULL; + c_dbcsr_acc_opencl_config.memptrs = NULL; + c_dbcsr_acc_opencl_config.nmemptrs = 0; + result = EXIT_FAILURE; + } +# endif + /* allocate and initialize streams registry */ + c_dbcsr_acc_opencl_config.nstreams = nhandles; + c_dbcsr_acc_opencl_config.streams = (c_dbcsr_acc_opencl_stream_t**)malloc(sizeof(c_dbcsr_acc_opencl_stream_t*) * nhandles); + c_dbcsr_acc_opencl_config.stream_data = (c_dbcsr_acc_opencl_stream_t*)malloc( + sizeof(c_dbcsr_acc_opencl_stream_t) * nhandles); + if (NULL != c_dbcsr_acc_opencl_config.streams && NULL != c_dbcsr_acc_opencl_config.stream_data) { + c_dbcsr_acc_opencl_pmalloc_init(NULL /*lock*/, sizeof(c_dbcsr_acc_opencl_stream_t), &c_dbcsr_acc_opencl_config.nstreams, + (void**)c_dbcsr_acc_opencl_config.streams, c_dbcsr_acc_opencl_config.stream_data); + } + else { + free(c_dbcsr_acc_opencl_config.streams); + free(c_dbcsr_acc_opencl_config.stream_data); + c_dbcsr_acc_opencl_config.stream_data = NULL; + c_dbcsr_acc_opencl_config.streams = NULL; + c_dbcsr_acc_opencl_config.nstreams = 0; + result = EXIT_FAILURE; + } + /* allocate and initialize events registry */ + c_dbcsr_acc_opencl_config.nevents = nhandles; + c_dbcsr_acc_opencl_config.events = (cl_event**)malloc(sizeof(cl_event*) * nhandles); + c_dbcsr_acc_opencl_config.event_data = (cl_event*)malloc(sizeof(cl_event) * nhandles); + if (NULL != c_dbcsr_acc_opencl_config.events && NULL != c_dbcsr_acc_opencl_config.event_data) { + c_dbcsr_acc_opencl_pmalloc_init(NULL /*lock*/, sizeof(cl_event*), &c_dbcsr_acc_opencl_config.nevents, + (void**)c_dbcsr_acc_opencl_config.events, c_dbcsr_acc_opencl_config.event_data); + } + else { + free(c_dbcsr_acc_opencl_config.events); + free(c_dbcsr_acc_opencl_config.event_data); + c_dbcsr_acc_opencl_config.event_data = NULL; + c_dbcsr_acc_opencl_config.events = NULL; + c_dbcsr_acc_opencl_config.nevents = 0; + result = EXIT_FAILURE; + } + if (EXIT_SUCCESS == result) { /* lastly, print active device and list of devices */ + result = c_dbcsr_acc_opencl_set_active_device(NULL /*lock*/, device_id); + if (2 <= c_dbcsr_acc_opencl_config.verbosity || 0 > c_dbcsr_acc_opencl_config.verbosity) { char platform_name[ACC_OPENCL_BUFFERSIZE]; for (i = 0; i < (cl_uint)c_dbcsr_acc_opencl_config.ndevices; ++i) { if (EXIT_SUCCESS == c_dbcsr_acc_opencl_device_name(c_dbcsr_acc_opencl_config.devices[i], buffer, - ACC_OPENCL_BUFFERSIZE, platform_name, ACC_OPENCL_BUFFERSIZE)) + ACC_OPENCL_BUFFERSIZE, platform_name, ACC_OPENCL_BUFFERSIZE, /*cleanup*/ 0)) { fprintf(stderr, "INFO ACC/OpenCL: DEVICE -> \"%s : %s\"\n", platform_name, buffer); } } } } - else { - result = EXIT_FAILURE; - } - c_dbcsr_acc_opencl_config.handle = 0; - c_dbcsr_acc_opencl_config.handles = NULL; - c_dbcsr_acc_opencl_config.storage = NULL; -# if LIBXSMM_VERSION4(1, 17, 0, 0) < LIBXSMM_VERSION_NUMBER && defined(ACC_OPENCL_HANDLES_MAXCOUNT) && \ - (0 < ACC_OPENCL_HANDLES_MAXCOUNT) - if (EXIT_SUCCESS == result) { - c_dbcsr_acc_opencl_config.handle = ACC_OPENCL_HANDLES_MAXCOUNT * c_dbcsr_acc_opencl_config.nthreads; - c_dbcsr_acc_opencl_config.handles = (void**)malloc(sizeof(void*) * c_dbcsr_acc_opencl_config.handle); - c_dbcsr_acc_opencl_config.storage = malloc(sizeof(void*) * c_dbcsr_acc_opencl_config.handle); - if (NULL != c_dbcsr_acc_opencl_config.handles && NULL != c_dbcsr_acc_opencl_config.storage) { - libxsmm_pmalloc_init(sizeof(void*), &c_dbcsr_acc_opencl_config.handle, c_dbcsr_acc_opencl_config.handles, - c_dbcsr_acc_opencl_config.storage); - } - else { - free(c_dbcsr_acc_opencl_config.handles); - free(c_dbcsr_acc_opencl_config.storage); - c_dbcsr_acc_opencl_config.handles = NULL; - c_dbcsr_acc_opencl_config.storage = NULL; - c_dbcsr_acc_opencl_config.handle = 0; - result = EXIT_FAILURE; - } - } -# endif - if (EXIT_SUCCESS == result) { - const int nelements = ACC_OPENCL_STREAMS_MAXCOUNT * c_dbcsr_acc_opencl_config.nthreads; - c_dbcsr_acc_opencl_config.streams = (void**)calloc(nelements, sizeof(void*)); /* allocate streams */ - if (NULL != c_dbcsr_acc_opencl_config.streams) { /* allocate counters */ - c_dbcsr_acc_opencl_config.stats = (cl_command_queue*)calloc(nelements, sizeof(cl_command_queue)); - } - else result = EXIT_FAILURE; - } } } else { /* mark as initialized */ @@ -547,47 +655,26 @@ int c_dbcsr_acc_finalize(void) { # else int result = EXIT_SUCCESS; # endif + static void (*cleanup)(void) = c_dbcsr_acc_opencl_finalize; # if defined(__DBCSR_ACC) && defined(ACC_OPENCL_PROFILE) int routine_handle; static const char* const routine_name_ptr = LIBXSMM_FUNCNAME; static const int routine_name_len = (int)sizeof(LIBXSMM_FUNCNAME) - 1; c_dbcsr_timeset((const char**)&routine_name_ptr, &routine_name_len, &routine_handle); # endif - if (0 != c_dbcsr_acc_opencl_config.ndevices) { - int i; - assert(c_dbcsr_acc_opencl_config.ndevices < ACC_OPENCL_DEVICES_MAXCOUNT); + assert(c_dbcsr_acc_opencl_config.ndevices < ACC_OPENCL_MAXNDEVS); + if (0 != c_dbcsr_acc_opencl_config.ndevices && NULL != cleanup) { if (0 != c_dbcsr_acc_opencl_config.verbosity) { - cl_device_id device; + cl_device_id device = NULL; int d; fprintf(stderr, "INFO ACC/OpenCL: pid=%u nthreads=%i", libxsmm_get_pid(), c_dbcsr_acc_opencl_config.nthreads); - if (EXIT_SUCCESS == c_dbcsr_acc_opencl_device(0, &device) && + if (NULL != c_dbcsr_acc_opencl_config.device.context && + EXIT_SUCCESS == + clGetContextInfo(c_dbcsr_acc_opencl_config.device.context, CL_CONTEXT_DEVICES, sizeof(cl_device_id), &device, NULL) && EXIT_SUCCESS == c_dbcsr_acc_opencl_device_id(device, NULL /*devid*/, &d)) { fprintf(stderr, " device=%i", d); } - if (NULL != c_dbcsr_acc_opencl_config.stats) { - const int nelements = ACC_OPENCL_STREAMS_MAXCOUNT * c_dbcsr_acc_opencl_config.nthreads; - cl_command_queue s = NULL; - int nstreams, j; - fprintf(stderr, " streams={"); - for (i = 0; i < nelements; i += ACC_OPENCL_STREAMS_MAXCOUNT) { - for (j = 0, nstreams = 0; j < ACC_OPENCL_STREAMS_MAXCOUNT; ++j) { - if (NULL != c_dbcsr_acc_opencl_config.stats[i + j]) ++nstreams; - } - if (0 != nstreams || 0 == i) fprintf(stderr, 0 < i ? " %i" : "%i", nstreams); - } - qsort(c_dbcsr_acc_opencl_config.stats, nelements, sizeof(cl_command_queue), - c_dbcsr_acc_opencl_order_streams); /* NULL -> upper end */ - for (i = 0, nstreams = 0; i < nelements; ++i) { - const cl_command_queue q = c_dbcsr_acc_opencl_config.stats[i]; - if (NULL != q && s != q) { - s = q; - ++nstreams; - } - } - free(c_dbcsr_acc_opencl_config.stats); /* release buffer */ - fprintf(stderr, "} nstreams=%i", nstreams); - } fprintf(stderr, "\n"); } # if defined(__DBCSR_ACC) @@ -598,33 +685,8 @@ int c_dbcsr_acc_finalize(void) { */ if (EXIT_SUCCESS == result) result = libsmm_acc_finalize(); # endif - libxsmm_finalize(); - if (NULL != c_dbcsr_acc_opencl_config.device) { - for (i = 0; i < c_dbcsr_acc_opencl_config.nthreads; ++i) { - const cl_context context = c_dbcsr_acc_opencl_config.device[i].context; - if (NULL != context) { - c_dbcsr_acc_opencl_config.device[i].context = NULL; - clReleaseContext(context); /* ignore return code */ - } - } - free(c_dbcsr_acc_opencl_config.device); /* release buffer */ - } - for (i = 0; i < ACC_OPENCL_DEVICES_MAXCOUNT; ++i) { - const cl_device_id device_id = c_dbcsr_acc_opencl_config.devices[i]; - if (NULL != device_id) { -# if defined(CL_VERSION_1_2) && defined(_DEBUG) - ACC_OPENCL_CHECK(clReleaseDevice(device_id), "release device", result); -# endif - /* c_dbcsr_acc_opencl_create_context scans for non-NULL devices */ - c_dbcsr_acc_opencl_config.devices[i] = NULL; - } - } - /* release/reset buffers */ - free(c_dbcsr_acc_opencl_config.handles); - free(c_dbcsr_acc_opencl_config.storage); - free(c_dbcsr_acc_opencl_config.streams); - /* clear configuration */ - memset(&c_dbcsr_acc_opencl_config, 0, sizeof(c_dbcsr_acc_opencl_config)); + if (EXIT_SUCCESS == result) result = atexit(cleanup); + cleanup = NULL; } # if defined(__DBCSR_ACC) && defined(ACC_OPENCL_PROFILE) c_dbcsr_timestop(&routine_handle); @@ -663,30 +725,9 @@ int c_dbcsr_acc_get_ndevices(int* ndevices) { } -int c_dbcsr_acc_opencl_device(int thread_id, cl_device_id* device) { - int result = EXIT_SUCCESS; - assert(0 <= thread_id && thread_id < c_dbcsr_acc_opencl_config.nthreads); - assert(NULL != device); - if (NULL != c_dbcsr_acc_opencl_config.device) { - cl_context context = c_dbcsr_acc_opencl_config.device[thread_id].context; -# if defined(_OPENMP) - if (NULL == context && 0 < thread_id) { /* fallback to master's context */ - context = c_dbcsr_acc_opencl_config.device[/*main*/ 0].context; - } -# endif - if (NULL != context) { - result = clGetContextInfo(context, CL_CONTEXT_DEVICES, sizeof(cl_device_id), device, NULL); - } - else *device = NULL; - } - else *device = NULL; - return result; -} - - int c_dbcsr_acc_opencl_device_id(cl_device_id device, int* device_id, int* global_id) { int result = EXIT_SUCCESS, i; - assert(c_dbcsr_acc_opencl_config.ndevices < ACC_OPENCL_DEVICES_MAXCOUNT); + assert(c_dbcsr_acc_opencl_config.ndevices < ACC_OPENCL_MAXNDEVS); assert(NULL != device_id || NULL != global_id); for (i = 0; i < c_dbcsr_acc_opencl_config.ndevices; ++i) { if (device == c_dbcsr_acc_opencl_config.devices[i]) break; @@ -695,7 +736,7 @@ int c_dbcsr_acc_opencl_device_id(cl_device_id device, int* device_id, int* globa if (NULL != device_id) *device_id = i; if (NULL != global_id) { *global_id = i; - for (++i; i < ACC_OPENCL_DEVICES_MAXCOUNT; ++i) { + for (++i; i < ACC_OPENCL_MAXNDEVS; ++i) { if (NULL != c_dbcsr_acc_opencl_config.devices[i]) { if (device == c_dbcsr_acc_opencl_config.devices[i]) { *global_id = i; @@ -715,12 +756,21 @@ int c_dbcsr_acc_opencl_device_id(cl_device_id device, int* device_id, int* globa } -int c_dbcsr_acc_opencl_device_vendor(cl_device_id device, const char vendor[]) { +int c_dbcsr_acc_opencl_device_vendor(cl_device_id device, const char vendor[], int use_platform_name) { char buffer[ACC_OPENCL_BUFFERSIZE]; int result = EXIT_SUCCESS; assert(NULL != device && NULL != vendor); - ACC_OPENCL_CHECK( - clGetDeviceInfo(device, CL_DEVICE_VENDOR, ACC_OPENCL_BUFFERSIZE, buffer, NULL), "retrieve device vendor", result); + if (0 == use_platform_name) { + result = clGetDeviceInfo(device, CL_DEVICE_VENDOR, ACC_OPENCL_BUFFERSIZE, buffer, NULL); + } + else { + cl_platform_id platform; + result = clGetDeviceInfo(device, CL_DEVICE_PLATFORM, sizeof(cl_platform_id), &platform, NULL); + if (EXIT_SUCCESS == result) { + result = clGetPlatformInfo( + platform, 1 == use_platform_name ? CL_PLATFORM_NAME : CL_PLATFORM_VENDOR, ACC_OPENCL_BUFFERSIZE, buffer, NULL); + } + } if (EXIT_SUCCESS == result) { result = (NULL != LIBXSMM_STRISTR(buffer, vendor) ? EXIT_SUCCESS : EXIT_FAILURE); } @@ -731,7 +781,7 @@ int c_dbcsr_acc_opencl_device_vendor(cl_device_id device, const char vendor[]) { int c_dbcsr_acc_opencl_device_uid(cl_device_id device, const char devname[], unsigned int* uid) { int result; if (NULL != uid) { - if (NULL != device && EXIT_SUCCESS == c_dbcsr_acc_opencl_device_vendor(device, "intel")) { + if (NULL != device && EXIT_SUCCESS == c_dbcsr_acc_opencl_device_vendor(device, "intel", 0 /*use_platform_name*/)) { result = clGetDeviceInfo(device, 0x4251 /*CL_DEVICE_ID_INTEL*/, sizeof(unsigned int), uid, NULL); } else result = EXIT_FAILURE; @@ -762,16 +812,21 @@ int c_dbcsr_acc_opencl_device_uid(cl_device_id device, const char devname[], uns } -int c_dbcsr_acc_opencl_device_name(cl_device_id device, char name[], size_t name_maxlen, char platform[], size_t platform_maxlen) { +int c_dbcsr_acc_opencl_device_name( + cl_device_id device, char name[], size_t name_maxlen, char platform[], size_t platform_maxlen, int cleanup) { int result_name = 0, result_platform = 0; assert(NULL != name || NULL != platform); if (NULL != name && 0 != name_maxlen) { result_name = clGetDeviceInfo(device, CL_DEVICE_NAME, name_maxlen, name, NULL); + if (0 != cleanup && EXIT_SUCCESS == result_name) { + char* const part = strchr(name, ':'); + if (NULL != part) *part = '\0'; + } } if (NULL != platform && 0 != platform_maxlen) { cl_platform_id platform_id; result_platform = clGetDeviceInfo(device, CL_DEVICE_PLATFORM, sizeof(cl_platform_id), &platform_id, NULL); - if (CL_SUCCESS == result_platform) { + if (EXIT_SUCCESS == result_platform) { result_platform = clGetPlatformInfo(platform_id, CL_PLATFORM_NAME, platform_maxlen, platform, NULL); } } @@ -780,61 +835,57 @@ int c_dbcsr_acc_opencl_device_name(cl_device_id device, char name[], size_t name int c_dbcsr_acc_opencl_device_level( - cl_device_id device, int* level_major, int* level_minor, char cl_std[16], cl_device_type* type) { - cl_int result = EXIT_SUCCESS; - assert(NULL != device && (NULL != level_major || NULL != level_minor || NULL != cl_std || NULL != type)); - if (NULL != level_major || NULL != level_minor || NULL != cl_std) { - char buffer[ACC_OPENCL_BUFFERSIZE]; - result = clGetDeviceInfo(device, CL_DEVICE_VERSION, ACC_OPENCL_BUFFERSIZE, buffer, NULL); - if (CL_SUCCESS == result) { - unsigned int cl_std_level[2]; - if (2 == sscanf(buffer, "OpenCL %u.%u", cl_std_level, cl_std_level + 1)) { - if (NULL != level_major) *level_major = (int)cl_std_level[0]; - if (NULL != level_minor) *level_minor = (int)cl_std_level[1]; - if (NULL != cl_std) { - if (2 <= cl_std_level[0]) { - const int nchar = LIBXSMM_SNPRINTF(cl_std, 16, "-cl-std=CL%u.0", cl_std_level[0]); - if (0 >= nchar || 16 <= nchar) result = EXIT_FAILURE; - } - else if (1 <= cl_std_level[0]) { - if (1 <= cl_std_level[1]) { - const int nchar = LIBXSMM_SNPRINTF(cl_std, 16, "-cl-std=CL%u.%u", cl_std_level[0], cl_std_level[1]); - if (0 >= nchar || 16 <= nchar) result = EXIT_FAILURE; - } - else { - result = clGetDeviceInfo(device, CL_DEVICE_OPENCL_C_VERSION, ACC_OPENCL_BUFFERSIZE, buffer, NULL); - if (CL_SUCCESS == result) { - if (2 == sscanf(buffer, "OpenCL C %u.%u", cl_std_level, cl_std_level + 1)) { - const int nchar = LIBXSMM_SNPRINTF(cl_std, 16, "-cl-std=CL%u.%u", cl_std_level[0], cl_std_level[1]); - if (0 >= nchar || 16 <= nchar) result = EXIT_FAILURE; - } - else { - result = EXIT_FAILURE; - *cl_std = '\0'; - } - } - else *cl_std = '\0'; - } - } - else *cl_std = '\0'; - } - } - else { - if (NULL != level_major) *level_major = 0; - if (NULL != level_minor) *level_minor = 0; - if (NULL != cl_std) *cl_std = '\0'; - result = EXIT_FAILURE; + cl_device_id device, int std_clevel[2], int std_level[2], char std_flag[16], cl_device_type* type) { + char buffer[ACC_OPENCL_BUFFERSIZE]; + unsigned int std_clevel_uint[2] = {0}, std_level_uint[2] = {0}; + int result = EXIT_SUCCESS; + assert(NULL != device && (NULL != std_clevel || NULL != std_level || NULL != std_flag || NULL != type)); + result = clGetDeviceInfo(device, CL_DEVICE_OPENCL_C_VERSION, ACC_OPENCL_BUFFERSIZE / 2, buffer, NULL); + if (EXIT_SUCCESS == result && (NULL != std_clevel || NULL != std_flag)) { + if (2 == sscanf(buffer, "OpenCL C %u.%u", std_clevel_uint, std_clevel_uint + 1)) { + std_clevel[0] = (int)std_clevel_uint[0]; + std_clevel[1] = (int)std_clevel_uint[1]; + } + else result = EXIT_FAILURE; + } + if (EXIT_SUCCESS == result && (NULL != std_level || NULL != std_flag)) { + result = clGetDeviceInfo( + device, CL_DEVICE_VERSION, ACC_OPENCL_BUFFERSIZE - ACC_OPENCL_BUFFERSIZE / 2, buffer + ACC_OPENCL_BUFFERSIZE / 2, NULL); + if (EXIT_SUCCESS == result) { + if (2 == sscanf(buffer + ACC_OPENCL_BUFFERSIZE / 2, "OpenCL %u.%u", std_level_uint, std_level_uint + 1)) { + std_level[0] = (int)std_level_uint[0]; + std_level[1] = (int)std_level_uint[1]; } + else result = EXIT_FAILURE; } - else { - if (NULL != level_major) *level_major = 0; - if (NULL != level_minor) *level_minor = 0; - if (NULL != cl_std) *cl_std = '\0'; + } + if (EXIT_SUCCESS == result && NULL != std_flag) { + if (2 <= std_level_uint[0]) { + const int nchar = LIBXSMM_SNPRINTF(std_flag, 16, "-cl-std=CL%u.0", std_level_uint[0]); + if (0 >= nchar || 16 <= nchar) result = EXIT_FAILURE; } + else if (1 <= std_level_uint[0]) { + if (1 <= std_level_uint[1]) { + const int nchar = LIBXSMM_SNPRINTF(std_flag, 16, "-cl-std=CL%u.%u", std_level_uint[0], std_level_uint[1]); + if (0 >= nchar || 16 <= nchar) result = EXIT_FAILURE; + } + else if (1 <= std_clevel_uint[0]) { /* fallback */ + const int nchar = LIBXSMM_SNPRINTF(std_flag, 16, "-cl-std=CL%u.%u", std_clevel_uint[0], std_clevel_uint[1]); + if (0 >= nchar || 16 <= nchar) result = EXIT_FAILURE; + } + else *std_flag = '\0'; /* not an error */ + } + else *std_flag = '\0'; /* not an error */ } - if (NULL != type && EXIT_SUCCESS == result) { + if (EXIT_SUCCESS == result && NULL != type) { result = clGetDeviceInfo(device, CL_DEVICE_TYPE, sizeof(cl_device_type), type, NULL); } + if (EXIT_SUCCESS != result) { + if (NULL != std_clevel) std_clevel[0] = std_clevel[1] = 0; + if (NULL != std_level) std_level[0] = std_level[1] = 0; + if (NULL != std_flag) *std_flag = '\0'; + if (NULL != type) *type = 0; + } return result; } @@ -862,43 +913,33 @@ int c_dbcsr_acc_opencl_device_ext(cl_device_id device, const char* const extname } -int c_dbcsr_acc_opencl_create_context(int thread_id, cl_device_id active_id) { +int c_dbcsr_acc_opencl_create_context(cl_device_id active_id, cl_context* context) { cl_platform_id platform = NULL; - cl_int result; - assert(0 <= thread_id && thread_id < c_dbcsr_acc_opencl_config.nthreads); - assert(NULL == c_dbcsr_acc_opencl_config.device[thread_id].context); + int result; assert(0 < c_dbcsr_acc_opencl_config.ndevices); - assert(NULL != active_id); + assert(NULL != active_id && NULL != context); result = clGetDeviceInfo(active_id, CL_DEVICE_PLATFORM, sizeof(cl_platform_id), &platform, NULL); - assert(CL_SUCCESS != result || NULL != platform); - if (CL_SUCCESS == result) { -# if defined(NDEBUG) - void (*const notify)(const char*, const void*, size_t, void*) = NULL; -# else - void (*const notify)(const char*, const void*, size_t, void*) = c_dbcsr_acc_opencl_notify; -# endif + assert(EXIT_SUCCESS != result || NULL != platform); + if (EXIT_SUCCESS == result) { + void (*const notify)( + const char*, const void*, size_t, void*) = (0 != c_dbcsr_acc_opencl_config.verbosity ? c_dbcsr_acc_opencl_notify : NULL); cl_context_properties properties[] = { CL_CONTEXT_PLATFORM, 0 /*placeholder*/, 0 /* end of properties */ }; - cl_context context = NULL; + cl_context ctx = NULL; properties[1] = (long)platform; - context = clCreateContext(properties, 1 /*num_devices*/, &active_id, notify, NULL /* user_data*/, &result); - if (CL_SUCCESS != result && CL_INVALID_DEVICE != result) { /* retry */ - context = clCreateContext(NULL /*properties*/, 1 /*num_devices*/, &active_id, notify, NULL /* user_data*/, &result); + ctx = clCreateContext(properties, 1 /*num_devices*/, &active_id, notify, NULL /* user_data*/, &result); + if (EXIT_SUCCESS != result && CL_INVALID_DEVICE != result) { /* retry */ + ctx = clCreateContext(NULL /*properties*/, 1 /*num_devices*/, &active_id, notify, NULL /* user_data*/, &result); } - if (CL_SUCCESS == result) { - assert(NULL != context); - c_dbcsr_acc_opencl_config.device[thread_id].context = context; - if (0 != thread_id) { - /* apply context to master-thread if master's context is NULL */ - LIBXSMM_ATOMIC_CMPSWP(&c_dbcsr_acc_opencl_config.device[/*main*/ 0].context, NULL, context, LIBXSMM_ATOMIC_RELAXED); - assert(NULL != c_dbcsr_acc_opencl_config.device[/*main*/ 0].context); - } + if (EXIT_SUCCESS == result) { + assert(NULL != ctx); + *context = ctx; if (0 != c_dbcsr_acc_opencl_config.verbosity) { char buffer[ACC_OPENCL_BUFFERSIZE]; int global_id = 0; - if (EXIT_SUCCESS == - c_dbcsr_acc_opencl_device_name(active_id, buffer, ACC_OPENCL_BUFFERSIZE, NULL /*platform*/, 0 /*platform_maxlen*/) && + if (EXIT_SUCCESS == c_dbcsr_acc_opencl_device_name( + active_id, buffer, ACC_OPENCL_BUFFERSIZE, NULL /*platform*/, 0 /*platform_maxlen*/, /*cleanup*/ 1) && EXIT_SUCCESS == c_dbcsr_acc_opencl_device_id(active_id, NULL /*devid*/, &global_id)) { const size_t size = strlen(buffer); @@ -913,141 +954,161 @@ int c_dbcsr_acc_opencl_create_context(int thread_id, cl_device_id active_id) { } } } - else if (CL_INVALID_DEVICE == result && EXIT_SUCCESS == c_dbcsr_acc_opencl_device_vendor(active_id, "nvidia")) { - fprintf(stderr, "WARN ACC/OpenCL: if MPI-ranks target the same device in exclusive mode,\n" - " SMI must be used to enable sharing the device.\n"); + else { + if (CL_INVALID_DEVICE == result && + EXIT_SUCCESS == c_dbcsr_acc_opencl_device_vendor(active_id, "nvidia", 0 /*use_platform_name*/)) + { + fprintf(stderr, "WARN ACC/OpenCL: if MPI-ranks target the same device in exclusive mode,\n" + " SMI must be used to enable sharing the device.\n"); + } + *context = NULL; } } return result; } -int c_dbcsr_acc_opencl_set_active_device(int thread_id, int device_id) { +int c_dbcsr_acc_opencl_set_active_device(ACC_OPENCL_LOCKTYPE* lock, int device_id) { int result = EXIT_SUCCESS; - cl_device_id active_id; - assert(0 <= thread_id && thread_id < c_dbcsr_acc_opencl_config.nthreads); - assert(c_dbcsr_acc_opencl_config.ndevices < ACC_OPENCL_DEVICES_MAXCOUNT); - if (0 <= device_id && device_id < c_dbcsr_acc_opencl_config.ndevices) { - assert(NULL != c_dbcsr_acc_opencl_config.device); - active_id = c_dbcsr_acc_opencl_config.devices[device_id]; - if (NULL != active_id) { -# if defined(_OPENMP) -# pragma omp critical(c_dbcsr_acc_set_active_device) + cl_device_id active_id = NULL, context_id = NULL; + assert(c_dbcsr_acc_opencl_config.ndevices < ACC_OPENCL_MAXNDEVS); + assert(0 <= device_id && device_id < c_dbcsr_acc_opencl_config.ndevices); + /* accessing devices is thread-safe (array is fixed after initialization) */ + active_id = c_dbcsr_acc_opencl_config.devices[device_id]; + if (NULL != active_id) { + cl_context context = NULL; + if (NULL != lock) ACC_OPENCL_ACQUIRE(lock); + context = c_dbcsr_acc_opencl_config.device.context; + if (NULL != context) { + result = clGetContextInfo(context, CL_CONTEXT_DEVICES, sizeof(cl_device_id), &context_id, NULL); + if (EXIT_SUCCESS == result && active_id != context_id) { + assert(NULL != context_id); + result = clReleaseContext(context); + context = NULL; + } + } + if (EXIT_SUCCESS == result && active_id != context_id) { + result = c_dbcsr_acc_opencl_create_context(active_id, &context); + assert(NULL != context || EXIT_SUCCESS != result); + } + if (EXIT_SUCCESS == result && active_id != context_id) { /* update/cache device-specific information */ + if (NULL != c_dbcsr_acc_opencl_config.device.stream.queue) { /* release private stream */ + ACC_OPENCL_EXPECT(EXIT_SUCCESS == clReleaseCommandQueue(c_dbcsr_acc_opencl_config.device.stream.queue)); + } + memset(&c_dbcsr_acc_opencl_config.device, 0, sizeof(c_dbcsr_acc_opencl_config.device)); + result = c_dbcsr_acc_opencl_device_level(active_id, c_dbcsr_acc_opencl_config.device.std_clevel, + c_dbcsr_acc_opencl_config.device.std_level, c_dbcsr_acc_opencl_config.device.std_flag, + &c_dbcsr_acc_opencl_config.device.type); + if (EXIT_SUCCESS == result) { + char devname[ACC_OPENCL_BUFFERSIZE] = ""; +# if defined(ACC_OPENCL_CMDAGR) + ACC_OPENCL_STREAM_PROPERTIES_TYPE properties[4] = { + CL_QUEUE_PROPERTIES, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, 0 /* terminator */ + }; # endif - { - int inherit_id = 0; - const cl_context context = c_dbcsr_acc_opencl_device_context(active_id, &inherit_id); - const cl_context inherit = c_dbcsr_acc_opencl_config.device[inherit_id].context; - if (NULL != context) { - if (context != inherit) { - if (NULL != inherit) { - c_dbcsr_acc_opencl_config.device[inherit_id].context = NULL; - result = clReleaseContext(inherit); - } - else if (thread_id != inherit_id) { - c_dbcsr_acc_opencl_config.device[inherit_id].context = context; - result = clRetainContext(context); +# if defined(ACC_OPENCL_MEM_DEVPTR) + cl_platform_id platform = NULL; + cl_bitfield bitfield = 0; +# endif + c_dbcsr_acc_opencl_config.device.intel = (EXIT_SUCCESS == + c_dbcsr_acc_opencl_device_vendor(active_id, "intel", 0 /*use_platform_name*/)); + c_dbcsr_acc_opencl_config.device.nv = (EXIT_SUCCESS == + c_dbcsr_acc_opencl_device_vendor(active_id, "nvidia", 0 /*use_platform_name*/)); + + if (EXIT_SUCCESS != c_dbcsr_acc_opencl_device_name( + active_id, devname, ACC_OPENCL_BUFFERSIZE, NULL /*platform*/, 0 /*platform_maxlen*/, /*cleanup*/ 1) || + EXIT_SUCCESS != c_dbcsr_acc_opencl_device_uid(active_id, devname, &c_dbcsr_acc_opencl_config.device.uid)) + { + c_dbcsr_acc_opencl_config.device.uid = (cl_uint)-1; + } + if (EXIT_SUCCESS == c_dbcsr_acc_opencl_device_vendor(active_id, "amd", 0 /*use_platform_name*/) || + EXIT_SUCCESS == c_dbcsr_acc_opencl_device_vendor(active_id, "amd", 1 /*use_platform_name*/)) + { + c_dbcsr_acc_opencl_config.device.amd = 1; + if ('\0' != *devname) { + const char* const gfxname = LIBXSMM_STRISTR(devname, "gfx"); + if (NULL != gfxname && 90 <= atoi(gfxname + 3)) { + c_dbcsr_acc_opencl_config.device.amd = 2; } } } - else if (NULL == c_dbcsr_acc_opencl_config.device[thread_id].context) { - result = c_dbcsr_acc_opencl_create_context(thread_id, active_id); - if (EXIT_SUCCESS == result && NULL /*context*/ != inherit) { - c_dbcsr_acc_opencl_config.device[inherit_id].context = c_dbcsr_acc_opencl_config.device[thread_id].context; - result = clReleaseContext(inherit); - } + if (EXIT_SUCCESS != clGetDeviceInfo(active_id, CL_DEVICE_HOST_UNIFIED_MEMORY, sizeof(cl_bool) /*cl_int*/, + &c_dbcsr_acc_opencl_config.device.unified, NULL)) + { + c_dbcsr_acc_opencl_config.device.unified = CL_FALSE; + } +# if defined(ACC_OPENCL_MEM_DEVPTR) + if (0 != (4 & c_dbcsr_acc_opencl_config.xhints) && 2 <= *c_dbcsr_acc_opencl_config.device.std_level && + 0 != c_dbcsr_acc_opencl_config.device.intel && 0 == c_dbcsr_acc_opencl_config.device.unified && + EXIT_SUCCESS == clGetDeviceInfo(active_id, CL_DEVICE_PLATFORM, sizeof(cl_platform_id), &platform, NULL) && + EXIT_SUCCESS == c_dbcsr_acc_opencl_device_vendor(active_id, "intel", 2 /*platform vendor*/) && + EXIT_SUCCESS == clGetDeviceInfo(active_id, 0x4191 /*CL_DEVICE_DEVICE_MEM_CAPABILITIES_INTEL*/, sizeof(cl_bitfield), + &bitfield, NULL) && + 0 != bitfield) /* cl_intel_unified_shared_memory extension */ + { + void* ptr = NULL; + ptr = clGetExtensionFunctionAddressForPlatform(platform, "clSetKernelArgMemPointerINTEL"); + LIBXSMM_ASSIGN127(&c_dbcsr_acc_opencl_config.device.clSetKernelArgMemPointerINTEL, &ptr); + ptr = clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueMemFillINTEL"); + LIBXSMM_ASSIGN127(&c_dbcsr_acc_opencl_config.device.clEnqueueMemFillINTEL, &ptr); + ptr = clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueMemcpyINTEL"); + LIBXSMM_ASSIGN127(&c_dbcsr_acc_opencl_config.device.clEnqueueMemcpyINTEL, &ptr); + ptr = clGetExtensionFunctionAddressForPlatform(platform, "clDeviceMemAllocINTEL"); + LIBXSMM_ASSIGN127(&c_dbcsr_acc_opencl_config.device.clDeviceMemAllocINTEL, &ptr); + ptr = clGetExtensionFunctionAddressForPlatform(platform, "clMemFreeINTEL"); + LIBXSMM_ASSIGN127(&c_dbcsr_acc_opencl_config.device.clMemFreeINTEL, &ptr); } - if (EXIT_SUCCESS == result) { /* update/cache device-specific information */ - char devname[ACC_OPENCL_BUFFERSIZE]; -# if defined(CL_VERSION_2_0) - const char* const env_svm = getenv("ACC_OPENCL_SVM"); - int level_major = 0; - const int nok = (NULL == env_svm || EXIT_SUCCESS != c_dbcsr_acc_opencl_device_level(active_id, &level_major, - NULL /*level_minor*/, NULL /*cl_std*/, NULL /*type*/)); - c_dbcsr_acc_opencl_config.device[thread_id].svm_interop = ((0 != nok || 2 > level_major) ? 0 : atoi(env_svm)); # endif - if (CL_SUCCESS != clGetDeviceInfo(active_id, CL_DEVICE_HOST_UNIFIED_MEMORY, sizeof(cl_bool), - &c_dbcsr_acc_opencl_config.device[thread_id].unified, NULL)) - { - c_dbcsr_acc_opencl_config.device[thread_id].unified = CL_FALSE; - } - if (EXIT_SUCCESS != c_dbcsr_acc_opencl_device_name( - active_id, devname, ACC_OPENCL_BUFFERSIZE, NULL /*platform*/, 0 /*platform_maxlen*/) || - EXIT_SUCCESS != c_dbcsr_acc_opencl_device_uid(active_id, devname, &c_dbcsr_acc_opencl_config.device[thread_id].uid)) - { - c_dbcsr_acc_opencl_config.device[thread_id].uid = (cl_uint)-1; +# if defined(ACC_OPENCL_CMDAGR) + if (0 != c_dbcsr_acc_opencl_config.device.intel) { /* device vendor (above) can now be used */ + int result_cmdagr = EXIT_SUCCESS; + const cl_command_queue q = ACC_OPENCL_CREATE_COMMAND_QUEUE(context, active_id, properties, &result_cmdagr); + if (EXIT_SUCCESS == result_cmdagr) { +# if 0 /* force host-timer? */ + c_dbcsr_acc_opencl_config.timer = c_dbcsr_acc_opencl_timer_host; +# endif + assert(NULL != q); + clReleaseCommandQueue(q); } - c_dbcsr_acc_opencl_config.device[thread_id].intel = - (EXIT_SUCCESS == c_dbcsr_acc_opencl_device_vendor(active_id, "intel") ? CL_TRUE : CL_FALSE); } +# endif + properties[1] = 0; + c_dbcsr_acc_opencl_config.device.stream.queue = ACC_OPENCL_CREATE_COMMAND_QUEUE(context, active_id, properties, &result); } + if (EXIT_SUCCESS == result) { + if (active_id != context_id) c_dbcsr_acc_opencl_config.device.context = context; + } + else memset(&c_dbcsr_acc_opencl_config.device, 0, sizeof(c_dbcsr_acc_opencl_config.device)); } - else result = EXIT_FAILURE; + if (NULL != lock) ACC_OPENCL_RELEASE(lock); } + else result = EXIT_FAILURE; + assert(EXIT_SUCCESS == result || NULL == c_dbcsr_acc_opencl_config.device.context); return result; } int c_dbcsr_acc_set_active_device(int device_id) { - int result; + int result = EXIT_SUCCESS; # if defined(__DBCSR_ACC) && defined(ACC_OPENCL_PROFILE) int routine_handle; static const char* const routine_name_ptr = LIBXSMM_FUNCNAME; static const int routine_name_len = (int)sizeof(LIBXSMM_FUNCNAME) - 1; c_dbcsr_timeset((const char**)&routine_name_ptr, &routine_name_len, &routine_handle); # endif - assert(0 != c_dbcsr_acc_opencl_config.ndevices); - result = c_dbcsr_acc_opencl_set_active_device(ACC_OPENCL_OMP_TID(), device_id); -# if defined(__DBCSR_ACC) && defined(ACC_OPENCL_PROFILE) - c_dbcsr_timestop(&routine_handle); + if (0 <= device_id && device_id < c_dbcsr_acc_opencl_config.ndevices) { +# if defined(ACC_OPENCL_CACHE_DID) + if (c_dbcsr_acc_opencl_active_id != (device_id + 1)) # endif - ACC_OPENCL_RETURN(result); -} - - -int c_dbcsr_acc_opencl_device_synchronize(int thread_id) { - int result = EXIT_SUCCESS; - if ((0 == (4 & c_dbcsr_acc_opencl_config.flush)) && - (0 == c_dbcsr_acc_opencl_config.share || 0 == (thread_id % c_dbcsr_acc_opencl_config.share))) - { - void** const streams = c_dbcsr_acc_opencl_config.streams + ACC_OPENCL_STREAMS_MAXCOUNT * thread_id; - int i = 0; - assert(0 <= thread_id && thread_id < c_dbcsr_acc_opencl_config.nthreads); - assert(NULL != c_dbcsr_acc_opencl_config.streams); - for (; i < ACC_OPENCL_STREAMS_MAXCOUNT; ++i) { - void* const stream = streams[i]; - if (NULL != stream) { - result = c_dbcsr_acc_stream_sync(stream); - if (EXIT_SUCCESS != result) break; - } - else break; - } - } - return result; -} - - -int c_dbcsr_acc_device_synchronize(void) { - int result = EXIT_SUCCESS; -# if defined(__DBCSR_ACC) && defined(ACC_OPENCL_PROFILE) - int routine_handle; - static const char* const routine_name_ptr = LIBXSMM_FUNCNAME; - static const int routine_name_len = (int)sizeof(LIBXSMM_FUNCNAME) - 1; - c_dbcsr_timeset((const char**)&routine_name_ptr, &routine_name_len, &routine_handle); + { + result = c_dbcsr_acc_opencl_set_active_device(c_dbcsr_acc_opencl_config.lock_main, device_id); +# if defined(ACC_OPENCL_CACHE_DID) + if (EXIT_SUCCESS == result) c_dbcsr_acc_opencl_active_id = device_id + 1; # endif -# if defined(_OPENMP) - if (1 < omp_get_num_threads()) { - result = c_dbcsr_acc_opencl_device_synchronize(omp_get_thread_num()); - } - else { - int i; -# pragma omp parallel for private(i) - for (i = 0; i < c_dbcsr_acc_opencl_config.nthreads; ++i) { - ACC_OPENCL_EXPECT(EXIT_SUCCESS == c_dbcsr_acc_opencl_device_synchronize(i)); } } -# else - result = c_dbcsr_acc_opencl_device_synchronize(/*main*/ 0); +# if !defined(NDEBUG) + else result = EXIT_FAILURE; # endif # if defined(__DBCSR_ACC) && defined(ACC_OPENCL_PROFILE) c_dbcsr_timestop(&routine_handle); @@ -1088,17 +1149,168 @@ int c_dbcsr_acc_opencl_wgsize(cl_device_id device, cl_kernel kernel, size_t* max } -int c_dbcsr_acc_opencl_build_flags(const char build_params[], const char build_options[], const char try_build_options[], - const char cl_std[], char buffer[], size_t buffer_size) { - int result; +int c_dbcsr_acc_opencl_flags_atomics(const c_dbcsr_acc_opencl_device_t* devinfo, c_dbcsr_acc_opencl_atomic_fp_t kind, + const char* exts[], int exts_maxlen, char flags[], size_t flags_maxlen) { + cl_device_id device_id = NULL; + int result = 0, ext1, ext2; + for (ext1 = 0; ext1 < exts_maxlen; ++ext1) { + if (NULL == exts[ext1] || '\0' == *exts[ext1]) break; + } + for (ext2 = ext1 + 1; ext2 < exts_maxlen; ++ext2) { + if (NULL == exts[ext2] || '\0' == *exts[ext2]) break; + } + if (NULL != devinfo && ext2 < exts_maxlen && + EXIT_SUCCESS == clGetContextInfo(devinfo->context, CL_CONTEXT_DEVICES, sizeof(cl_device_id), &device_id, NULL)) + { + const char* atomic_type = ""; + switch (kind) { + case c_dbcsr_acc_opencl_atomic_fp_64: { + exts[ext1] = "cl_khr_fp64 cl_khr_int64_base_atomics cl_khr_int64_extended_atomics"; + if (2 <= *devinfo->std_level && EXIT_SUCCESS == c_dbcsr_acc_opencl_device_ext(device_id, exts, ext2)) { + atomic_type = "-DTA=long -DTA2=atomic_long -DTF=atomic_double"; + } + else { + exts[ext1] = "cl_khr_fp64 cl_khr_int64_base_atomics"; + if (EXIT_SUCCESS == c_dbcsr_acc_opencl_device_ext(device_id, exts, ext2)) { + atomic_type = "-DTA=long"; + } + else { /* fallback */ + exts[ext1] = "cl_khr_fp64 cl_khr_global_int32_base_atomics cl_khr_global_int32_extended_atomics"; + if (2 <= *devinfo->std_level && EXIT_SUCCESS == c_dbcsr_acc_opencl_device_ext(device_id, exts, ext2)) { + atomic_type = "-DATOMIC32_ADD64 -DTA=int -DTA2=atomic_int -DTF=atomic_double"; + } + else { + exts[ext1] = "cl_khr_fp64 cl_khr_global_int32_base_atomics"; + if (EXIT_SUCCESS == c_dbcsr_acc_opencl_device_ext(device_id, exts, ext2)) { + atomic_type = "-DATOMIC32_ADD64 -DTA=int"; + } + else kind = c_dbcsr_acc_opencl_atomic_fp_no; + } + } + } + } break; + case c_dbcsr_acc_opencl_atomic_fp_32: { + exts[ext1] = "cl_khr_global_int32_base_atomics cl_khr_global_int32_extended_atomics"; + if (2 <= *devinfo->std_level && EXIT_SUCCESS == c_dbcsr_acc_opencl_device_ext(device_id, exts, ext2)) { + exts[ext2] = "cl_khr_int64_base_atomics cl_khr_int64_extended_atomics"; + atomic_type = "-DTA=int -DTA2=atomic_int -DTF=atomic_float"; + } + else { + exts[ext1] = "cl_khr_global_int32_base_atomics"; + if (EXIT_SUCCESS == c_dbcsr_acc_opencl_device_ext(device_id, exts, ext2)) { + exts[ext2] = "cl_khr_int64_base_atomics"; + atomic_type = "-DTA=int"; + } + else kind = c_dbcsr_acc_opencl_atomic_fp_no; + } + } break; + default: assert(c_dbcsr_acc_opencl_atomic_fp_no == kind); + } + if (c_dbcsr_acc_opencl_atomic_fp_no != kind) { + const char *barrier_expr = NULL, *atomic_exp = NULL, *atomic_ops = ""; + const char* const env_barrier = getenv("ACC_OPENCL_BARRIER"); + const char* const env_atomics = getenv("ACC_OPENCL_ATOMICS"); + if (NULL == env_barrier || '0' != *env_barrier) { + barrier_expr = ((2 <= *devinfo->std_level && (0 == devinfo->intel || (CL_DEVICE_TYPE_CPU != devinfo->type))) + ? "-D\"BARRIER(A)=work_group_barrier(A,memory_scope_work_group)\"" + : "-D\"BARRIER(A)=barrier(A)\""); + } + else barrier_expr = ""; /* no barrier */ + assert(NULL != barrier_expr); + if (NULL == env_atomics || '0' != *env_atomics) { + /* can signal/force atomics without confirmation */ + const int force_atomics = ((NULL == env_atomics || '\0' == *env_atomics) ? 0 : atoi(env_atomics)); + if (NULL == env_atomics || '\0' == *env_atomics || 0 != force_atomics) { + cl_bitfield fp_atomics = 0; + if (EXIT_SUCCESS == clGetDeviceInfo(device_id, + (cl_device_info)(c_dbcsr_acc_opencl_atomic_fp_64 == kind ? 0x4232 : 0x4231), sizeof(cl_bitfield), + &fp_atomics, NULL) && + 0 != (/*add*/ (1 << 1) & fp_atomics)) + { +# if 0 /* enabling this permitted extension in source code causes compiler warning */ + exts[ext2] = "cl_ext_float_atomics"; +# endif + atomic_exp = (c_dbcsr_acc_opencl_atomic_fp_64 == kind + ? "atomic_fetch_add_explicit((GLOBAL_VOLATILE(atomic_double)*)A,B," + "memory_order_relaxed,memory_scope_work_group)" + : "atomic_fetch_add_explicit((GLOBAL_VOLATILE(atomic_float)*)A,B," + "memory_order_relaxed,memory_scope_work_group)"); + } + else if (0 != force_atomics || (0 != devinfo->intel && ((0x4905 != devinfo->uid && 0 == devinfo->unified)))) { + if ((((0 != force_atomics || (0 != devinfo->intel && ((0x0bd0 <= devinfo->uid && 0x0bdb >= devinfo->uid) || + c_dbcsr_acc_opencl_atomic_fp_32 == kind)))))) + { + if (0 == force_atomics && (0 == devinfo->intel || 0x0bd0 > devinfo->uid || 0x0bdb < devinfo->uid)) { + exts[ext2] = "cl_intel_global_float_atomics"; + atomic_ops = "-Dcl_intel_global_float_atomics"; + } + else { + atomic_ops = ((2 > *devinfo->std_level && 2 > force_atomics) + ? "-DATOMIC_PROTOTYPES=1" + : (3 > force_atomics ? "-DATOMIC_PROTOTYPES=2" : "-DATOMIC_PROTOTYPES=3")); + } + atomic_exp = ((2 > *devinfo->std_level && 2 > force_atomics) ? "atomic_add(A,B)" + : "atomic_fetch_add_explicit((GLOBAL_VOLATILE(TF)*)A,B," + "memory_order_relaxed,memory_scope_work_group)"); + } + else { + atomic_exp = "atomic_add_global_cmpxchg(A,B)"; + atomic_ops = "-DCMPXCHG=atom_cmpxchg"; + } + } + else if (0 == devinfo->nv) { + if (1 >= devinfo->amd) { + atomic_ops = (c_dbcsr_acc_opencl_atomic_fp_32 == kind ? "-DCMPXCHG=atomic_cmpxchg" : "-DCMPXCHG=atom_cmpxchg"); + atomic_exp = "atomic_add_global_cmpxchg(A,B)"; + exts[ext2] = NULL; + } + else { /* GCN */ + atomic_exp = (c_dbcsr_acc_opencl_atomic_fp_64 == kind + ? "__builtin_amdgcn_global_atomic_fadd_f64(A,B,__ATOMIC_RELAXED)" + : "__builtin_amdgcn_global_atomic_fadd_f32(A,B,__ATOMIC_RELAXED)"); + } + } + else { /* xchg */ + assert(NULL != atomic_ops && '\0' == *atomic_ops); + atomic_exp = "atomic_add_global_xchg(A,B)"; + } + } + else if (NULL != LIBXSMM_STRISTR(env_atomics, "cmpxchg")) { + atomic_ops = (c_dbcsr_acc_opencl_atomic_fp_32 == kind ? "-DCMPXCHG=atomic_cmpxchg" : "-DCMPXCHG=atom_cmpxchg"); + atomic_exp = "atomic_add_global_cmpxchg(A,B)"; + exts[ext2] = NULL; + } + else { /* xchg */ + atomic_exp = "atomic_add_global_xchg(A,B)"; + atomic_ops = (c_dbcsr_acc_opencl_atomic_fp_32 == kind ? "-DXCHG=atomic_xchg" : "-DXCHG=atom_xchg"); + } + } + else { /* unsynchronized */ + atomic_exp = "*(A)+=(B)"; /* non-atomic update */ + } + assert(NULL != atomic_exp); + /* compose build parameters and flags */ + result = LIBXSMM_SNPRINTF(flags, flags_maxlen, "-DTAN=%i %s %s -D\"ATOMIC_ADD_GLOBAL(A,B)=%s\" %s", kind, atomic_type, + atomic_ops, atomic_exp, barrier_expr); + } + } + return result; +} + + +int c_dbcsr_acc_opencl_flags( + const char build_params[], const char build_options[], const char try_build_options[], char buffer[], size_t buffer_size) { + int result = EXIT_SUCCESS; if (NULL != buffer) { - const int nchar = LIBXSMM_SNPRINTF(buffer, buffer_size, "%s %s %s %s", NULL != cl_std ? cl_std : "", - NULL != build_options ? build_options : "", NULL != build_params ? build_params : "", - NULL != try_build_options ? try_build_options : ""); + const int std_clevel = 100 * c_dbcsr_acc_opencl_config.device.std_clevel[0] + + 10 * c_dbcsr_acc_opencl_config.device.std_clevel[1]; + const int std_level = 100 * c_dbcsr_acc_opencl_config.device.std_level[0] + 10 * c_dbcsr_acc_opencl_config.device.std_level[1]; + const int nchar = LIBXSMM_SNPRINTF(buffer, buffer_size, "%s -DACC_OPENCL_VERSION=%u -DACC_OPENCL_C_VERSION=%u %s %s %s", + c_dbcsr_acc_opencl_config.device.std_flag, std_level, std_clevel, NULL != build_options ? build_options : "", + NULL != build_params ? build_params : "", NULL != try_build_options ? try_build_options : ""); if (0 < nchar && (int)buffer_size > nchar) { char* replace = strpbrk(buffer, "\""); /* more portable (system/cpp needs quotes to protect braces) */ for (; NULL != replace; replace = strpbrk(replace + 1, "\"")) *replace = ' '; - result = EXIT_SUCCESS; } else { result = EXIT_FAILURE; @@ -1113,21 +1325,19 @@ int c_dbcsr_acc_opencl_build_flags(const char build_params[], const char build_o int c_dbcsr_acc_opencl_kernel(int source_is_file, const char source[], const char kernel_name[], const char build_params[], const char build_options[], const char try_build_options[], int* try_ok, const char* const extnames[], int num_exts, cl_kernel* kernel) { - char buffer[ACC_OPENCL_BUFFERSIZE] = "", cl_std[16]; - char buffer_name[ACC_OPENCL_MAXSTRLEN * 2]; - int tid = 0, ok = EXIT_SUCCESS, source_is_cl = 1, nchar, level_major, level_minor; - const cl_context context = c_dbcsr_acc_opencl_context(&tid); + char buffer[ACC_OPENCL_BUFFERSIZE] = "", buffer_name[ACC_OPENCL_MAXSTRLEN * 2]; + int ok = EXIT_SUCCESS, source_is_cl = 1, nchar; cl_device_id active_id = NULL; - cl_int result = ((NULL != source && NULL != kernel_name && '\0' != *kernel_name && NULL != kernel) - ? c_dbcsr_acc_opencl_device(tid, &active_id) - : EXIT_FAILURE); + int result = ((NULL != source && NULL != kernel_name && '\0' != *kernel_name) + ? clGetContextInfo( + c_dbcsr_acc_opencl_config.device.context, CL_CONTEXT_DEVICES, sizeof(cl_device_id), &active_id, NULL) + : EXIT_FAILURE); cl_program program = NULL; FILE* file_src = NULL; size_t size_src = 0; - if (EXIT_SUCCESS == result) { - result = c_dbcsr_acc_opencl_device_level(active_id, &level_major, &level_minor, cl_std, NULL /*type*/); - if (0 != source_is_file) file_src = fopen(source, "rb"); - } + assert(NULL != kernel); + *kernel = NULL; + if (EXIT_SUCCESS == result && 0 != source_is_file) file_src = fopen(source, "rb"); if (NULL != file_src) { if (EXIT_SUCCESS == result) { const char* const file_ext = strrchr(source, '.'); @@ -1196,7 +1406,7 @@ int c_dbcsr_acc_opencl_kernel(int source_is_file, const char source[], const cha else break; } # if !defined(NDEBUG) - if (EXIT_SUCCESS == c_dbcsr_acc_opencl_device_ext(active_id, (const char**)&ext, 1)) + if (EXIT_SUCCESS == c_dbcsr_acc_opencl_device_ext(active_id, (const char* const*)&ext, 1)) # endif { /* NDEBUG: assume given extension is supported (confirmed upfront) */ if (NULL == line) { /* extension is not already part of source */ @@ -1223,7 +1433,7 @@ int c_dbcsr_acc_opencl_kernel(int source_is_file, const char source[], const cha /* consider preprocessing kernel for analysis (cpp); failure does not matter (result) */ # if defined(ACC_OPENCL_CPPBIN) if (0 != c_dbcsr_acc_opencl_config.dump && NULL == file_src) { - nchar = LIBXSMM_SNPRINTF(buffer_name, sizeof(buffer_name), "/tmp/.%s.XXXXXX", kernel_name); + nchar = LIBXSMM_SNPRINTF(buffer_name, sizeof(buffer_name), ACC_OPENCL_TEMPDIR "/.%s.XXXXXX", kernel_name); if (0 < nchar && (int)sizeof(buffer_name) > nchar) { FILE* const file_cpp = fopen(ACC_OPENCL_CPPBIN, "rb"); const char* sed_pattern = ""; @@ -1238,14 +1448,19 @@ int c_dbcsr_acc_opencl_kernel(int source_is_file, const char source[], const cha const int file_tmp = mkstemp(buffer_name); fclose(file_cpp); /* existence-check */ if (0 <= file_tmp) { - const int cl_std_len = (int)strlen(cl_std); + const int std_clevel = 100 * c_dbcsr_acc_opencl_config.device.std_clevel[0] + + 10 * c_dbcsr_acc_opencl_config.device.std_clevel[1]; + const int std_level = 100 * c_dbcsr_acc_opencl_config.device.std_level[0] + + 10 * c_dbcsr_acc_opencl_config.device.std_level[1]; + const int std_flag_len = (int)strlen(c_dbcsr_acc_opencl_config.device.std_flag); nchar = LIBXSMM_SNPRINTF(buffer, sizeof(buffer), - ACC_OPENCL_CPPBIN " -P -C -nostdinc -D__OPENCL_VERSION__=%u %s %s %s %s >%s.cl", 100 * level_major + 10 * level_minor, - EXIT_SUCCESS != c_dbcsr_acc_opencl_device_vendor(active_id, "nvidia") ? "" : "-D__NV_CL_C_VERSION", + ACC_OPENCL_CPPBIN " -P -C -nostdinc -DACC_OPENCL_VERSION=%u -DACC_OPENCL_C_VERSION=%u %s %s %s %s >%s.cl", std_level, + std_clevel, 0 == c_dbcsr_acc_opencl_config.device.nv ? "" : "-D__NV_CL_C_VERSION", NULL != build_params ? build_params : "", buffer_name, sed_pattern, kernel_name); if (0 < nchar && (int)sizeof(buffer) > nchar && - (0 == cl_std_len || (3 == write(file_tmp, "/*\n", 3) && cl_std_len == write(file_tmp, cl_std, cl_std_len) && - 4 == write(file_tmp, "\n*/\n", 4))) && + (0 == std_flag_len || (3 == write(file_tmp, "/*\n", 3) && + std_flag_len == write(file_tmp, c_dbcsr_acc_opencl_config.device.std_flag, std_flag_len) && + 4 == write(file_tmp, "\n*/\n", 4))) && size_src == (size_t)write(file_tmp, ext_source, size_src)) { if (EXIT_SUCCESS == system(buffer)) { @@ -1259,7 +1474,11 @@ int c_dbcsr_acc_opencl_kernel(int source_is_file, const char source[], const cha : NULL); if (NULL != src) { if ((size_t)size == fread(src, 1 /*sizeof(char)*/, size /*count*/, file)) { - if (source != ext_source) libxsmm_free((void*)ext_source); + if (source != ext_source) { + void* p = NULL; + LIBXSMM_ASSIGN127(&p, &ext_source); + libxsmm_free(p); + } src[size] = '\0'; ext_source = src; } @@ -1278,158 +1497,152 @@ int c_dbcsr_acc_opencl_kernel(int source_is_file, const char source[], const cha } } # endif - program = clCreateProgramWithSource(context, 1 /*nlines*/, &ext_source, NULL, &result); - if (CL_SUCCESS == result) { + program = clCreateProgramWithSource(c_dbcsr_acc_opencl_config.device.context, 1 /*nlines*/, &ext_source, NULL, &result); + if (EXIT_SUCCESS == result) { assert(NULL != program); - result = c_dbcsr_acc_opencl_build_flags(build_params, build_options, try_build_options, cl_std, buffer, sizeof(buffer)); + result = c_dbcsr_acc_opencl_flags(build_params, build_options, try_build_options, buffer, sizeof(buffer)); if (EXIT_SUCCESS == result) { result = clBuildProgram(program, 1 /*num_devices*/, &active_id, buffer, NULL /*callback*/, NULL /*user_data*/); } - if (CL_SUCCESS != result && NULL != try_build_options && '\0' != *try_build_options) { - result = c_dbcsr_acc_opencl_build_flags( - build_params, build_options, NULL /*try_build_options*/, cl_std, buffer, sizeof(buffer)); + if (EXIT_SUCCESS != result && NULL != try_build_options && '\0' != *try_build_options) { + result = c_dbcsr_acc_opencl_flags(build_params, build_options, NULL /*try_build_options*/, buffer, sizeof(buffer)); if (EXIT_SUCCESS == result) { - ACC_OPENCL_EXPECT(CL_SUCCESS == clReleaseProgram(program)); /* recreate below (to avoid unclean state) */ - program = clCreateProgramWithSource(context, 1 /*nlines*/, &ext_source, NULL, &result); - assert(CL_SUCCESS != result || NULL != program); - if (CL_SUCCESS == result) { + ACC_OPENCL_EXPECT(EXIT_SUCCESS == clReleaseProgram(program)); /* recreate below (to avoid unclean state) */ + program = clCreateProgramWithSource(c_dbcsr_acc_opencl_config.device.context, 1 /*nlines*/, &ext_source, NULL, &result); + assert(EXIT_SUCCESS != result || NULL != program); + if (EXIT_SUCCESS == result) { result = clBuildProgram(program, 1 /*num_devices*/, &active_id, buffer, NULL /*callback*/, NULL /*user_data*/); } } ok = EXIT_FAILURE; } - if (source != ext_source) libxsmm_free((void*)ext_source); + if (source != ext_source) { + void* p = NULL; + LIBXSMM_ASSIGN127(&p, &ext_source); + libxsmm_free(p); + } buffer[0] = '\0'; /* reset to empty */ - if (CL_SUCCESS == result) { + if (EXIT_SUCCESS == result) { /* extract kernel */ *kernel = clCreateKernel(program, kernel_name, &result); - if (CL_SUCCESS == result) { + if (EXIT_SUCCESS == result) { assert(NULL != *kernel); if (NULL == file_src && (2 <= c_dbcsr_acc_opencl_config.dump || 0 > c_dbcsr_acc_opencl_config.dump)) { unsigned char* binary = NULL; size_t size; - binary = (unsigned char*)(CL_SUCCESS == clGetProgramInfo(program, CL_PROGRAM_BINARY_SIZES, sizeof(size_t), &size, NULL) + binary = (unsigned char*)(EXIT_SUCCESS == + clGetProgramInfo(program, CL_PROGRAM_BINARY_SIZES, sizeof(size_t), &size, NULL) ? libxsmm_aligned_scratch(size, 0 /*auto-align*/) : NULL); if (NULL != binary) { result = clGetProgramInfo(program, CL_PROGRAM_BINARIES, sizeof(unsigned char*), &binary, NULL); - if (CL_SUCCESS == result) { + if (EXIT_SUCCESS == result) { /* successfully queried program binary */ FILE* file; nchar = LIBXSMM_SNPRINTF(buffer, sizeof(buffer), "%s.dump", kernel_name); file = (0 < nchar && (int)sizeof(buffer) > nchar) ? fopen(buffer, "wb") : NULL; buffer[0] = '\0'; /* reset to empty */ if (NULL != file) { - if (size != fwrite(binary, 1, size, file)) { - ACC_OPENCL_EXPECT(CL_SUCCESS == clReleaseProgram(program)); - ACC_OPENCL_EXPECT(CL_SUCCESS == clReleaseKernel(*kernel)); - result = EXIT_FAILURE; - } + if (size != fwrite(binary, 1, size, file)) result = EXIT_FAILURE; fclose(file); } - else { - ACC_OPENCL_EXPECT(CL_SUCCESS == clReleaseProgram(program)); - ACC_OPENCL_EXPECT(CL_SUCCESS == clReleaseKernel(*kernel)); - result = EXIT_FAILURE; - } - } - else { /* error: querying program binary */ - ACC_OPENCL_EXPECT(CL_SUCCESS == clReleaseProgram(program)); - ACC_OPENCL_EXPECT(CL_SUCCESS == clReleaseKernel(*kernel)); + else result = EXIT_FAILURE; } libxsmm_free(binary); } - else { - ACC_OPENCL_EXPECT(CL_SUCCESS == clReleaseProgram(program)); - ACC_OPENCL_EXPECT(CL_SUCCESS == clReleaseKernel(*kernel)); - result = EXIT_FAILURE; - } + else result = EXIT_FAILURE; } } - else { /* error: creating kernel */ - ACC_OPENCL_EXPECT(CL_SUCCESS == clReleaseProgram(program)); - } - } - else { - ACC_OPENCL_EXPECT( - CL_SUCCESS == clGetProgramBuildInfo(program, active_id, CL_PROGRAM_BUILD_LOG, ACC_OPENCL_BUFFERSIZE, buffer, NULL)); - ACC_OPENCL_EXPECT(CL_SUCCESS == clReleaseProgram(program)); } } else if (source != ext_source) { /* error: creating program */ - libxsmm_free((void*)ext_source); + void* p = NULL; + LIBXSMM_ASSIGN127(&p, &ext_source); + libxsmm_free(p); } } else if (EXIT_SUCCESS == result) { /* binary representation */ # if defined(CL_VERSION_2_1) - if (0 != c_dbcsr_acc_opencl_config.dump) program = clCreateProgramWithIL(context, source, size_src, &result); + if (0 != c_dbcsr_acc_opencl_config.dump) + program = clCreateProgramWithIL(c_dbcsr_acc_opencl_config.device.context, source, size_src, &result); else # endif { - program = clCreateProgramWithBinary( - context, 1, &active_id, &size_src, (const unsigned char**)(const void*)&source, NULL /*binary_status*/, &result); + program = clCreateProgramWithBinary(c_dbcsr_acc_opencl_config.device.context, 1, &active_id, &size_src, + (const unsigned char**)&source, NULL /*binary_status*/, &result); } - if (CL_SUCCESS == result) { + if (EXIT_SUCCESS == result) { assert(NULL != program); - result = c_dbcsr_acc_opencl_build_flags(build_params, build_options, try_build_options, cl_std, buffer, sizeof(buffer)); + result = c_dbcsr_acc_opencl_flags(build_params, build_options, try_build_options, buffer, sizeof(buffer)); if (EXIT_SUCCESS == result) { result = clBuildProgram(program, 1 /*num_devices*/, &active_id, buffer, NULL /*callback*/, NULL /*user_data*/); } - if (CL_SUCCESS != result && NULL != try_build_options && '\0' != *try_build_options) { - result = c_dbcsr_acc_opencl_build_flags( - build_params, build_options, NULL /*try_build_options*/, cl_std, buffer, sizeof(buffer)); + if (EXIT_SUCCESS != result && NULL != try_build_options && '\0' != *try_build_options) { + result = c_dbcsr_acc_opencl_flags(build_params, build_options, NULL /*try_build_options*/, buffer, sizeof(buffer)); if (EXIT_SUCCESS == result) { - ACC_OPENCL_EXPECT(CL_SUCCESS == clReleaseProgram(program)); /* recreate below (to avoid unclean state) */ + ACC_OPENCL_EXPECT(EXIT_SUCCESS == clReleaseProgram(program)); /* recreate below (to avoid unclean state) */ # if defined(CL_VERSION_2_1) - if (0 != c_dbcsr_acc_opencl_config.dump) program = clCreateProgramWithIL(context, source, size_src, &result); + if (0 != c_dbcsr_acc_opencl_config.dump) + program = clCreateProgramWithIL(c_dbcsr_acc_opencl_config.device.context, source, size_src, &result); else # endif { - program = clCreateProgramWithBinary( - context, 1, &active_id, &size_src, (const unsigned char**)(const void*)&source, NULL /*binary_status*/, &result); + program = clCreateProgramWithBinary(c_dbcsr_acc_opencl_config.device.context, 1, &active_id, &size_src, + (const unsigned char**)&source, NULL /*binary_status*/, &result); } - assert(CL_SUCCESS != result || NULL != program); - if (CL_SUCCESS == result) { + assert(EXIT_SUCCESS != result || NULL != program); + if (EXIT_SUCCESS == result) { result = clBuildProgram(program, 1 /*num_devices*/, &active_id, buffer, NULL /*callback*/, NULL /*user_data*/); } } ok = EXIT_FAILURE; } - if (CL_SUCCESS == result) { + if (EXIT_SUCCESS == result) { *kernel = clCreateKernel(program, kernel_name, &result); - assert(CL_SUCCESS != result || NULL != *kernel); - if (CL_SUCCESS != result) { /* error: creating kernel */ # if defined(CL_VERSION_1_2) - /* discover available kernels in program, and adopt the last kernel listed */ - if (CL_SUCCESS == clGetProgramInfo(program, CL_PROGRAM_KERNEL_NAMES, sizeof(char*), buffer, NULL) && '\0' != *buffer) { - const char *const semicolon = strrchr(buffer, ';'), *const name = (NULL == semicolon ? buffer : (semicolon + 1)); - *kernel = clCreateKernel(program, name, &result); - assert(CL_SUCCESS != result || NULL != *kernel); - if (CL_SUCCESS != result) ACC_OPENCL_EXPECT(CL_SUCCESS == clReleaseProgram(program)); - } - else -# endif - { - ACC_OPENCL_EXPECT(CL_SUCCESS == clReleaseProgram(program)); - } + /* error creating kernel: discover available kernels in program, and adopt the last kernel listed */ + if (EXIT_SUCCESS != result && + EXIT_SUCCESS == clGetProgramInfo(program, CL_PROGRAM_KERNEL_NAMES, sizeof(char*), buffer, NULL) && '\0' != *buffer) + { + const char *const semicolon = strrchr(buffer, ';'), *const name = (NULL == semicolon ? buffer : (semicolon + 1)); + *kernel = clCreateKernel(program, name, &result); } - } - else { - ACC_OPENCL_EXPECT( - CL_SUCCESS == clGetProgramBuildInfo(program, active_id, CL_PROGRAM_BUILD_LOG, ACC_OPENCL_BUFFERSIZE, buffer, NULL)); - ACC_OPENCL_EXPECT(CL_SUCCESS == clReleaseProgram(program)); +# endif + assert(EXIT_SUCCESS != result || NULL != *kernel); } } } if (NULL != file_src) { + void* p = NULL; + LIBXSMM_ASSIGN127(&p, (const void**)&source); assert(0 != source_is_file); - libxsmm_free((void*)source); + libxsmm_free(p); + } + if (NULL != program) { + if (EXIT_SUCCESS != result && NULL != *kernel) { + ACC_OPENCL_EXPECT(EXIT_SUCCESS == clReleaseKernel(*kernel)); + *kernel = NULL; + } + if (2 <= c_dbcsr_acc_opencl_config.verbosity || 0 > c_dbcsr_acc_opencl_config.verbosity) { + if (EXIT_SUCCESS == clGetProgramBuildInfo(program, active_id, CL_PROGRAM_BUILD_LOG, ACC_OPENCL_BUFFERSIZE, buffer, NULL)) { + const char* info = buffer; + while ('\0' != *info && NULL != strchr("\n\r\t ", *info)) ++info; /* remove preceding newline etc. */ + assert(NULL != kernel_name && '\0' != *kernel_name); + if ('\0' != *info) fprintf(stderr, "INFO ACC/OpenCL: %s -> %s\n", kernel_name, info); + } + else buffer[0] = '\0'; /* reset to empty */ + } + ACC_OPENCL_EXPECT(EXIT_SUCCESS == clReleaseProgram(program)); /* release in any case (EXIT_SUCCESS) */ } -# if !defined(NDEBUG) - if (EXIT_SUCCESS != result && NULL != kernel) *kernel = NULL; -# endif if (NULL != try_ok) *try_ok = result | ok; ACC_OPENCL_RETURN_CAUSE(result, buffer); } + +int c_dbcsr_acc_opencl_set_kernel_ptr(cl_kernel kernel, cl_uint arg_index, const void* arg_value) { + return (NULL != c_dbcsr_acc_opencl_config.device.clSetKernelArgMemPointerINTEL + ? c_dbcsr_acc_opencl_config.device.clSetKernelArgMemPointerINTEL(kernel, arg_index, arg_value) + : clSetKernelArg(kernel, arg_index, sizeof(cl_mem), &arg_value)); +} + # if defined(__cplusplus) } # endif diff --git a/src/acc/opencl/acc_opencl.h b/src/acc/opencl/acc_opencl.h index e0ce920d239..8cdbc15f2df 100644 --- a/src/acc/opencl/acc_opencl.h +++ b/src/acc/opencl/acc_opencl.h @@ -9,11 +9,15 @@ #ifndef ACC_OPENCL_H #define ACC_OPENCL_H -#if !defined(CL_TARGET_OPENCL_VERSION) -# define CL_TARGET_OPENCL_VERSION 220 +/* Support for other libraries, e.g., CP2K's DBM/DBT */ +#if defined(__OFFLOAD_OPENCL) && !defined(__OPENCL) +# define __OPENCL #endif #if defined(__OPENCL) +# if !defined(CL_TARGET_OPENCL_VERSION) +# define CL_TARGET_OPENCL_VERSION 220 +# endif # if defined(__APPLE__) # include # else @@ -56,12 +60,6 @@ LIBXSMM_VERSION4(LIBXSMM_VERSION_MAJOR, LIBXSMM_VERSION_MINOR, LIBXSMM_VERSION_UPDATE, LIBXSMM_VERSION_PATCH) #endif -#if LIBXSMM_VERSION4(1, 17, 0, 0) < LIBXSMM_VERSION_NUMBER -# define LIBXSMM_STRISTR libxsmm_stristr -#else -# define LIBXSMM_STRISTR strstr -#endif - #include "../acc.h" #if !defined(NDEBUG) # include @@ -69,11 +67,19 @@ #include #include -#if !defined(ACC_OPENCL_CACHELINE_NBYTES) -# define ACC_OPENCL_CACHELINE_NBYTES LIBXSMM_CACHELINE +#if !defined(ACC_OPENCL_CACHELINE) +# define ACC_OPENCL_CACHELINE LIBXSMM_CACHELINE #endif -#if !defined(ACC_OPENCL_MAXALIGN_NBYTES) -# define ACC_OPENCL_MAXALIGN_NBYTES (2 << 20 /*2MB*/) +#if !defined(ACC_OPENCL_ATOMIC) +# define ACC_OPENCL_ATOMIC LIBXSMM_ATOMIC_SEQ_CST +#endif +#if defined(LIBXSMM_ATOMIC_LOCKTYPE) +# define ACC_OPENCL_ATOMIC_LOCKTYPE volatile LIBXSMM_ATOMIC_LOCKTYPE +#else +# define ACC_OPENCL_ATOMIC_LOCKTYPE volatile int +#endif +#if !defined(ACC_OPENCL_MAXALIGN) +# define ACC_OPENCL_MAXALIGN (2 << 20 /*2MB*/) #endif #if !defined(ACC_OPENCL_BUFFERSIZE) # define ACC_OPENCL_BUFFERSIZE (8 << 10 /*8KB*/) @@ -81,82 +87,113 @@ #if !defined(ACC_OPENCL_MAXSTRLEN) # define ACC_OPENCL_MAXSTRLEN 48 #endif -#if !defined(ACC_OPENCL_DEVICES_MAXCOUNT) -# define ACC_OPENCL_DEVICES_MAXCOUNT 256 +#if !defined(ACC_OPENCL_MAXNDEVS) +# define ACC_OPENCL_MAXNDEVS 64 #endif -/** Counted on a per-thread basis! */ -#if !defined(ACC_OPENCL_HANDLES_MAXCOUNT) -# define ACC_OPENCL_HANDLES_MAXCOUNT 1024 -#endif -/** Counted on a per-thread basis! */ -#if !defined(ACC_OPENCL_STREAMS_MAXCOUNT) -# define ACC_OPENCL_STREAMS_MAXCOUNT 128 -#endif -#if !defined(ACC_OPENCL_OVERMALLOC) -# if defined(__DBCSR_ACC) || 1 -# define ACC_OPENCL_OVERMALLOC 0 -# else -# define ACC_OPENCL_OVERMALLOC 8192 -# endif +/* Counted on a per-thread basis! */ +#if !defined(ACC_OPENCL_MAXNITEMS) +# define ACC_OPENCL_MAXNITEMS 1024 #endif /* First char is CSV-separator by default (w/o spaces) */ #if !defined(ACC_OPENCL_DELIMS) # define ACC_OPENCL_DELIMS ",;" #endif - #if !defined(ACC_OPENCL_LAZYINIT) && (defined(__DBCSR_ACC) || 1) # define ACC_OPENCL_LAZYINIT #endif +#if !defined(ACC_OPENCL_ASYNC) && 1 +# define ACC_OPENCL_ASYNC getenv("ACC_OPENCL_ASYNC") +#endif #if !defined(ACC_OPENCL_STREAM_PRIORITIES) && 0 # if defined(CL_QUEUE_PRIORITY_KHR) # define ACC_OPENCL_STREAM_PRIORITIES # endif #endif +/* Support arithmetic for device-pointers */ +#if !defined(ACC_OPENCL_MEM_DEVPTR) && 1 +# define ACC_OPENCL_MEM_DEVPTR +#endif +#if !defined(ACC_OPENCL_OMPLOCKS) && 1 +# define ACC_OPENCL_OMPLOCKS +#endif +/* Use DBCSR's profile for detailed timings */ #if !defined(ACC_OPENCL_PROFILE) && 0 # define ACC_OPENCL_PROFILE #endif -/* can depend on OpenCL implementation (unlikely) */ -#if !defined(ACC_OPENCL_MEM_NOALLOC) && 1 -# define ACC_OPENCL_MEM_NOALLOC -# define ACC_OPENCL_MEM(A) ((cl_mem*)&(A)) -#else -# define ACC_OPENCL_MEM(A) ((cl_mem*)(A)) +#if defined(__OFFLOAD_OPENCL) && !defined(ACC_OPENCL_MEM_DEVPTR) +# error Support for ACC_OPENCL_MEM_DEVPTR is required! #endif -/* attaching c_dbcsr_acc_opencl_info_stream_t is needed */ -#define ACC_OPENCL_STREAM(A) ((cl_command_queue*)(A)) + +/* attaching c_dbcsr_acc_opencl_stream_t is needed */ +#define ACC_OPENCL_STREAM(A) ((const c_dbcsr_acc_opencl_stream_t*)(A)) /* incompatible with c_dbcsr_acc_event_record */ -#define ACC_OPENCL_EVENT(A) ((cl_event*)(A)) +#define ACC_OPENCL_EVENT(A) ((const cl_event*)(A)) #if defined(_OPENMP) # include # define ACC_OPENCL_OMP_TID() omp_get_thread_num() #else # define ACC_OPENCL_OMP_TID() (/*main*/ 0) +# undef ACC_OPENCL_OMPLOCKS +#endif + +#define ACC_OPENCL_ATOMIC_ACQUIRE(LOCK) \ + do { \ + LIBXSMM_ATOMIC_ACQUIRE(LOCK, LIBXSMM_SYNC_NPAUSE, ACC_OPENCL_ATOMIC); \ + } while (0) +#define ACC_OPENCL_ATOMIC_RELEASE(LOCK) \ + do { \ + LIBXSMM_ATOMIC_RELEASE(LOCK, ACC_OPENCL_ATOMIC); \ + } while (0) + +#if defined(ACC_OPENCL_OMPLOCKS) +# define ACC_OPENCL_INIT(LOCK) omp_init_lock(LOCK) +# define ACC_OPENCL_DESTROY(LOCK) omp_destroy_lock(LOCK) +# define ACC_OPENCL_ACQUIRE(LOCK) omp_set_lock(LOCK) +# define ACC_OPENCL_RELEASE(LOCK) omp_unset_lock(LOCK) +# define ACC_OPENCL_LOCKTYPE omp_lock_t +#else +# define ACC_OPENCL_INIT(LOCK) (*(LOCK) = 0) +# define ACC_OPENCL_DESTROY(LOCK) +# define ACC_OPENCL_ACQUIRE(LOCK) ACC_OPENCL_ATOMIC_ACQUIRE(LOCK) +# define ACC_OPENCL_RELEASE(LOCK) ACC_OPENCL_ATOMIC_RELEASE(LOCK) +# define ACC_OPENCL_LOCKTYPE ACC_OPENCL_ATOMIC_LOCKTYPE +#endif + +#if defined(CL_VERSION_2_0) +# define ACC_OPENCL_STREAM_PROPERTIES_TYPE cl_queue_properties +# define ACC_OPENCL_CREATE_COMMAND_QUEUE(CTX, DEV, PROPS, RESULT) clCreateCommandQueueWithProperties(CTX, DEV, PROPS, RESULT) +#else +# define ACC_OPENCL_STREAM_PROPERTIES_TYPE cl_int +# define ACC_OPENCL_CREATE_COMMAND_QUEUE(CTX, DEV, PROPS, RESULT) \ + clCreateCommandQueue(CTX, DEV, (cl_command_queue_properties)(NULL != (PROPS) ? ((PROPS)[1]) : 0), RESULT) #endif #if LIBXSMM_VERSION4(1, 17, 0, 0) < LIBXSMM_VERSION_NUMBER # define ACC_OPENCL_EXPECT(EXPR) LIBXSMM_EXPECT(EXPR) +# define LIBXSMM_STRISTR libxsmm_stristr #else # define ACC_OPENCL_EXPECT(EXPR) \ - if (0 == (EXPR)) assert(0); + if (0 == (EXPR)) assert(0) +# define LIBXSMM_STRISTR strstr #endif -#if !defined(NDEBUG) +#if !defined(NDEBUG) && 1 # define ACC_OPENCL_CHECK(EXPR, MSG, RESULT) \ do { \ if (EXIT_SUCCESS == (RESULT)) { \ (RESULT) = (EXPR); \ assert((MSG) && *(MSG)); \ - if (CL_SUCCESS != (RESULT)) { \ - assert(CL_SUCCESS == EXIT_SUCCESS); \ + if (EXIT_SUCCESS != (RESULT)) { \ + assert(EXIT_SUCCESS == EXIT_SUCCESS); \ if (-1001 != (RESULT)) { \ fprintf(stderr, "ERROR ACC/OpenCL: " MSG); \ if (EXIT_FAILURE != (RESULT)) { \ fprintf(stderr, " (code=%i)", RESULT); \ } \ fprintf(stderr, ".\n"); \ - assert(CL_SUCCESS != (RESULT)); \ + assert(EXIT_SUCCESS != (RESULT)); \ } \ else { \ fprintf(stderr, "ERROR ACC/OpenCL: incomplete installation (" MSG ").\n"); \ @@ -203,45 +240,85 @@ extern "C" { #endif -/** Enumeration of timer kinds used for built-in execution-profile. */ -typedef enum c_dbcsr_acc_opencl_timer_t { - c_dbcsr_acc_opencl_timer_device, - c_dbcsr_acc_opencl_timer_host -} c_dbcsr_acc_opencl_timer_t; +/** Information about streams (c_dbcsr_acc_stream_create). */ +typedef struct c_dbcsr_acc_opencl_stream_t { + cl_command_queue queue; + int tid; +#if defined(ACC_OPENCL_STREAM_PRIORITIES) + int priority; +#endif +} c_dbcsr_acc_opencl_stream_t; /** Settings updated during c_dbcsr_acc_set_active_device. */ typedef struct c_dbcsr_acc_opencl_device_t { /** Activated device context. */ cl_context context; -#if defined(CL_VERSION_2_0) - /** Runtime SVM support. */ - cl_bool svm_interop; -#endif + /** + * Stream for internal purpose, e.g., stream-argument + * (ACC-interface) can be NULL (synchronous) + */ + c_dbcsr_acc_opencl_stream_t stream; + /** OpenCL compiler flag (language standard). */ + char std_flag[16]; + /** OpenCL support-level of device. */ + cl_int std_level[2], std_clevel[2]; + /** Kind of device (GPU, CPU, or other). */ + cl_device_type type; + /** Whether host memory is unified. */ + cl_int unified; /** Device-ID. */ cl_uint uid; - /** Intel device? */ - cl_bool intel; - /** Whether host memory is unified or not. */ - cl_bool unified; + /** Main vendor? */ + cl_int intel, amd, nv; + /* USM support functions */ + cl_int (*clSetKernelArgMemPointerINTEL)(cl_kernel, cl_uint, const void*); + cl_int (*clEnqueueMemFillINTEL)(cl_command_queue, void*, const void*, size_t, size_t, cl_uint, const cl_event*, cl_event*); + cl_int (*clEnqueueMemcpyINTEL)(cl_command_queue, cl_bool, void*, const void*, size_t, cl_uint, const cl_event*, cl_event*); + void* (*clDeviceMemAllocINTEL)(cl_context, cl_device_id, const void /*cl_mem_properties_intel*/*, size_t, cl_uint, cl_int*); + cl_int (*clMemFreeINTEL)(cl_context, void*); } c_dbcsr_acc_opencl_device_t; +/** Information about host/device-memory pointer. */ +typedef struct c_dbcsr_acc_opencl_info_memptr_t { + cl_mem memory; /* first item! */ + void* memptr; +} c_dbcsr_acc_opencl_info_memptr_t; + +/** Enumeration of timer kinds used for built-in execution-profile. */ +typedef enum c_dbcsr_acc_opencl_timer_t { + c_dbcsr_acc_opencl_timer_device, + c_dbcsr_acc_opencl_timer_host +} c_dbcsr_acc_opencl_timer_t; + +/** Enumeration of FP-atomic kinds. */ +typedef enum c_dbcsr_acc_opencl_atomic_fp_t { + c_dbcsr_acc_opencl_atomic_fp_no = 0, + c_dbcsr_acc_opencl_atomic_fp_32 = 1, + c_dbcsr_acc_opencl_atomic_fp_64 = 2 +} c_dbcsr_acc_opencl_atomic_fp_t; + /** * Settings discovered/setup during c_dbcsr_acc_init (independent of the device) * and settings updated during c_dbcsr_acc_set_active_device (devinfo). */ typedef struct c_dbcsr_acc_opencl_config_t { /** Table of ordered viable/discovered devices (matching criterion). */ - cl_device_id devices[ACC_OPENCL_DEVICES_MAXCOUNT]; + cl_device_id devices[ACC_OPENCL_MAXNDEVS]; /** Table of devices (thread-specific). */ - c_dbcsr_acc_opencl_device_t* device; + c_dbcsr_acc_opencl_device_t device; + /** Locks used by domain. */ + ACC_OPENCL_LOCKTYPE *lock_main, *lock_stream, *lock_event, *lock_memory; +#if defined(ACC_OPENCL_MEM_DEVPTR) + /** All memptrs and related storage/counter. */ + c_dbcsr_acc_opencl_info_memptr_t **memptrs, *memptr_data; + size_t nmemptrs; /* counter */ +#endif /** Handle-counter. */ - size_t handle; - /** All handles and related storage. */ - void **handles, *storage; - /** All created streams partitioned by thread-ID (thread-local slots). */ - void** streams; - /** Counts number of streams created (thread-local). */ - cl_command_queue* stats; + size_t nstreams, nevents; + /** All streams and related storage. */ + c_dbcsr_acc_opencl_stream_t **streams, *stream_data; + /** All events and related storage. */ + cl_event **events, *event_data; /** Kind of timer used for built-in execution-profile. */ c_dbcsr_acc_opencl_timer_t timer; /* c_dbcsr_acc_opencl_device_t? */ /** Kernel-parameters are matched against device's UID */ @@ -254,16 +331,12 @@ typedef struct c_dbcsr_acc_opencl_config_t { cl_int nthreads; /** How to apply/use stream priorities. */ cl_int priority; - /** How to zero/copy device-side buffers. */ - cl_int devcopy; - /** Execution-hints (command stream). */ + /** Configuration and execution-hints. */ cl_int xhints; - /** Share streams across threads. */ - cl_int share; - /** Asynchronous memory ops. */ + /** Asynchronous memory operations. */ cl_int async; - /** Flush level. */ - cl_int flush; + /** Debug (output/symbols, etc.). */ + cl_int debug; /** Dump level. */ cl_int dump; } c_dbcsr_acc_opencl_config_t; @@ -271,54 +344,45 @@ typedef struct c_dbcsr_acc_opencl_config_t { /** Global configuration setup in c_dbcsr_acc_init. */ extern c_dbcsr_acc_opencl_config_t c_dbcsr_acc_opencl_config; -/** Contexts implement 1:1 relation with device. */ -cl_context c_dbcsr_acc_opencl_context(int* thread_id); -/** Share context for given device (start searching at optional thread_id), or return NULL). */ -cl_context c_dbcsr_acc_opencl_device_context(cl_device_id device, const int* thread_id); - -/** Information about host-memory pointer (c_dbcsr_acc_host_mem_allocate). */ -typedef struct c_dbcsr_acc_opencl_info_hostptr_t { - cl_mem memory; - void* mapped; -} c_dbcsr_acc_opencl_info_hostptr_t; -c_dbcsr_acc_opencl_info_hostptr_t* c_dbcsr_acc_opencl_info_hostptr(void* memory); - -/** Information about streams (c_dbcsr_acc_stream_create). */ -typedef struct c_dbcsr_acc_opencl_info_stream_t { - void* pointer; - int priority; - int tid; -} c_dbcsr_acc_opencl_info_stream_t; -c_dbcsr_acc_opencl_info_stream_t* c_dbcsr_acc_opencl_info_stream(void* stream); -const int* c_dbcsr_acc_opencl_stream_priority(const void* stream); - -/** Get host-pointer associated with device-memory (c_dbcsr_acc_dev_mem_allocate). */ -void* c_dbcsr_acc_opencl_get_hostptr(cl_mem memory); +/** Determines host-pointer registration for modification. */ +c_dbcsr_acc_opencl_info_memptr_t* c_dbcsr_acc_opencl_info_hostptr(void* memory); +/** Determines device-pointer registration for modification (internal). */ +c_dbcsr_acc_opencl_info_memptr_t* c_dbcsr_acc_opencl_info_devptr_modify( + ACC_OPENCL_LOCKTYPE* lock, void* memory, size_t elsize, const size_t* amount, size_t* offset); +/** Determines device-pointer registration for information (lock-control). */ +int c_dbcsr_acc_opencl_info_devptr_lock(c_dbcsr_acc_opencl_info_memptr_t* info, ACC_OPENCL_LOCKTYPE* lock, const void* memory, + size_t elsize, const size_t* amount, size_t* offset); +/** Determines device-pointer registration for information. */ +int c_dbcsr_acc_opencl_info_devptr( + c_dbcsr_acc_opencl_info_memptr_t* info, const void* memory, size_t elsize, const size_t* amount, size_t* offset); +/** Finds an existing stream for the given thread-ID (or NULL). */ +const c_dbcsr_acc_opencl_stream_t* c_dbcsr_acc_opencl_stream(ACC_OPENCL_LOCKTYPE* lock, int thread_id); +/** Determines default-stream (see c_dbcsr_acc_opencl_device_t::stream). */ +const c_dbcsr_acc_opencl_stream_t* c_dbcsr_acc_opencl_stream_default(void); +/** Like c_dbcsr_acc_memset_zero, but supporting an arbitrary value used as initialization pattern. */ +int c_dbcsr_acc_opencl_memset(void* dev_mem, int value, size_t offset, size_t nbytes, void* stream); /** Amount of device memory; local memory is only non-zero if separate from global. */ int c_dbcsr_acc_opencl_info_devmem(cl_device_id device, size_t* mem_free, size_t* mem_total, size_t* mem_local, int* mem_unified); -/** Get device associated with thread-ID. */ -int c_dbcsr_acc_opencl_device(int thread_id, cl_device_id* device); /** Get device-ID for given device, and optionally global device-ID. */ int c_dbcsr_acc_opencl_device_id(cl_device_id device, int* device_id, int* global_id); /** Confirm the vendor of the given device. */ -int c_dbcsr_acc_opencl_device_vendor(cl_device_id device, const char vendor[]); +int c_dbcsr_acc_opencl_device_vendor(cl_device_id device, const char vendor[], int use_platform_name); /** Capture or calculate UID based on the device-name. */ int c_dbcsr_acc_opencl_device_uid(cl_device_id device, const char devname[], unsigned int* uid); /** Based on the device-ID, return the device's UID (capture or calculate), device name, and platform name. */ -int c_dbcsr_acc_opencl_device_name(cl_device_id device, char name[], size_t name_maxlen, char platform[], size_t platform_maxlen); -/** Return the OpenCL support level for the given device. */ -int c_dbcsr_acc_opencl_device_level(cl_device_id device, int* level_major, int* level_minor, char cl_std[16], cl_device_type* type); +int c_dbcsr_acc_opencl_device_name( + cl_device_id device, char name[], size_t name_maxlen, char platform[], size_t platform_maxlen, int cleanup); +/** Return the OpenCL support-level for the given device. */ +int c_dbcsr_acc_opencl_device_level( + cl_device_id device, int std_clevel[2], int std_level[2], char std_flag[16], cl_device_type* type); /** Check if given device supports the extensions. */ int c_dbcsr_acc_opencl_device_ext(cl_device_id device, const char* const extnames[], int num_exts); -/** Create context for given thread-ID and device. */ -int c_dbcsr_acc_opencl_create_context(int thread_id, cl_device_id device_id); +/** Create context for given device. */ +int c_dbcsr_acc_opencl_create_context(cl_device_id device_id, cl_context* context); /** Internal variant of c_dbcsr_acc_set_active_device. */ -int c_dbcsr_acc_opencl_set_active_device(int thread_id, int device_id); +int c_dbcsr_acc_opencl_set_active_device(ACC_OPENCL_LOCKTYPE* lock, int device_id); /** Get preferred multiple and max. size of workgroup (kernel- or device-specific). */ int c_dbcsr_acc_opencl_wgsize(cl_device_id device, cl_kernel kernel, size_t* max_value, size_t* preferred_multiple); -/** Assemble various flags for calling clBuildProgram into the given buffer.*/ -int c_dbcsr_acc_opencl_build_flags(const char build_params[], const char build_options[], const char try_build_options[], - const char cl_std[], char buffer[], size_t buffer_size); /** * Build kernel from source with given kernel_name, build_params and build_options. * The build_params are meant to instantiate the kernel (-D) whereas build_options @@ -328,9 +392,22 @@ int c_dbcsr_acc_opencl_kernel(int source_is_file, const char source[], const cha const char build_options[], const char try_build_options[], int* try_ok, const char* const extnames[], int num_exts, cl_kernel* kernel); /** Per-thread variant of c_dbcsr_acc_device_synchronize. */ -int c_dbcsr_acc_opencl_device_synchronize(int thread_id); -/** Create user-event if not created and sets initial state. */ -int c_dbcsr_acc_opencl_event_create(cl_event* event_p); +int c_dbcsr_acc_opencl_device_synchronize(ACC_OPENCL_LOCKTYPE* lock, int thread_id); +/** Assemble flags to support atomic operations. */ +int c_dbcsr_acc_opencl_flags_atomics(const c_dbcsr_acc_opencl_device_t* devinfo, c_dbcsr_acc_opencl_atomic_fp_t kind, + const char* exts[], int exts_maxlen, char flags[], size_t flags_maxlen); +/** Combines build-params and build-options, optional flags (try_build_options). */ +int c_dbcsr_acc_opencl_flags( + const char build_params[], const char build_options[], const char try_build_options[], char buffer[], size_t buffer_size); +/** To support USM, call this function for pointer arguments instead of clSetKernelArg. */ +int c_dbcsr_acc_opencl_set_kernel_ptr(cl_kernel kernel, cl_uint arg_index, const void* arg_value); + +/** Support older LIBXSMM (libxsmm_pmalloc_init). */ +void c_dbcsr_acc_opencl_pmalloc_init(ACC_OPENCL_LOCKTYPE* lock, size_t size, size_t* num, void* pool[], void* storage); +/** Support older LIBXSMM (libxsmm_pmalloc). */ +void* c_dbcsr_acc_opencl_pmalloc(ACC_OPENCL_LOCKTYPE* lock, void* pool[], size_t* i); +/** Support older LIBXSMM (libxsmm_pfree). */ +void c_dbcsr_acc_opencl_pfree(ACC_OPENCL_LOCKTYPE* lock, const void* pointer, void* pool[], size_t* i); #if defined(__cplusplus) } diff --git a/src/acc/opencl/acc_opencl.sh b/src/acc/opencl/acc_opencl.sh index fc74cbd1d62..e7dda72ec15 100755 --- a/src/acc/opencl/acc_opencl.sh +++ b/src/acc/opencl/acc_opencl.sh @@ -10,6 +10,8 @@ # shellcheck disable=SC2048,SC2129 BASENAME=$(command -v basename) +DIRNAME=$(command -v dirname) +HEAD=$(command -v head) SORT=$(command -v sort) SED=$(command -v gsed) CPP=$(command -v cpp) @@ -28,17 +30,62 @@ if [ ! "${SED}" ]; then SED=$(command -v sed) fi -if [ "${BASENAME}" ] && [ "${SORT}" ] && [ "${SED}" ] && \ - [ "${TR}" ] && [ "${RM}" ] && [ "${WC}" ]; +trap_exit() { + if [ "0" != "$?" ] && [ "${HFILE}" ]; then ${RM} -f "${OFILE}"; fi +} + +process_pre() { + if [ "${CPP}" ] && \ + [ "$(eval "${CPP} ${CPPBASEFLAGS} $1" 2>/dev/null >/dev/null && echo "YES")" ]; + then + if [ "${CPPFLAGS}" ] && \ + [ "$(eval "${CPP} ${CPPFLAGS} ${CPPBASEFLAGS} $1" 2>/dev/null >/dev/null && echo "YES")" ]; + then + eval "${CPP} ${CPPFLAGS} ${CPPBASEFLAGS} $1" 2>/dev/null + else + eval "${CPP} ${CPPBASEFLAGS} $1" 2>/dev/null + fi + else # fallback to sed + ${SED} -r ':a;s%(.*)/\*.*\*/%\1%;ta;/\/\*/!b;N;ba' "$1" + fi +} + +process() { + IFS=$'\n' + while read -r LINE; do + INCLUDE=$(${SED} -n "s/#[[:space:]]*include[[:space:]][[:space:]]*\"/\"/p" <<<"${LINE}") + if [ "${INCLUDE}" ] && [ "$1" ] && [ -e "$1" ]; then + CLINC=$(${SED} "s/\"//g" <<<"${INCLUDE}") + CLPATH=$(${DIRNAME} "$1") + FILE=${CLPATH}/${CLINC} + if [ "${FILE}" ] && [ -e "${FILE}" ]; then + process_pre "${FILE}" | process "${FILE}" + else + >&2 echo "ERROR: header file ${FILE} not found!" + exit 1 + fi + else + ${SED} <<<"${LINE}" \ + -e '/^[[:space:]]*$/d' -e 's/[[:space:]]*$//' \ + -e 's/\\/\\\\/g' -e 's/"/\\"/g' -e 's/^/ "/' -e 's/$/\\n" \\/' + fi + done + unset IFS +} + +if [ "${BASENAME}" ] && [ "${DIRNAME}" ] && [ "${HEAD}" ] && [ "${SORT}" ] && \ + [ "${SED}" ] && [ "${TR}" ] && [ "${RM}" ] && [ "${WC}" ]; then for OFILE in "$@"; do :; done while test $# -gt 0; do case "$1" in -h|--help) shift $#;; + -b|--banner) + BANNER=$2 + shift 2;; -p|--params) - PARAMPATH=yes - PARAMS=$2 + PARAMS="$2\t" shift 2;; -c|-d|--debug|--comments) CPPFLAGS+=" -C" @@ -49,14 +96,10 @@ then *) break;; esac done - HERE="$(cd "$(dirname "$0")" && pwd -P)" - PARAMDIR=$(if [ ! "${PARAMDIR}" ]; then echo "${HERE}/smm/params"; fi) - if [ "${PARAMPATH}" ]; then - PARAMPATH=${PARAMS} - else - HERE="$(cd "$(dirname "$0")" && pwd -P)" - PARAMPATH=${PARAMDIR} - fi + HERE="$(cd "$(${DIRNAME} "$0")" && pwd -P)" + PARAMDIR=${PARAMDIR:-${PARAMS}} + PARAMDIR=${PARAMDIR:-${HERE}/smm/params} + PARAMDIR=$(echo -e "${PARAMDIR}" | ${TR} -d '\t') if [ "$#" -gt 1 ]; then # allow for instance /dev/stdout if [ "${OFILE##*.}" = "h" ]; then @@ -75,45 +118,33 @@ then echo "$0 $*" fi fi + trap 'trap_exit' EXIT + RNAME=$(${BASENAME} "$(${DIRNAME} "$1")") + ANAME=$(${TR} '[:lower:]' '[:upper:]' <<<"${RNAME}") NFILES_OCL=0 for CLFILE in ${*:1:${#@}-1}; do if [ "${CLFILE##*.}" = "cl" ]; then if [ -e "${CLFILE}" ]; then - BNAME=$(${BASENAME} "${CLFILE}" .cl) - UNAME=$(echo "${BNAME}" | ${TR} '[:lower:]' '[:upper:]') - SNAME=OPENCL_LIBSMM_STRING_${UNAME} - VNAME=opencl_libsmm_source_${BNAME} - MNAME=OPENCL_LIBSMM_SOURCE_${UNAME} + CNAME=$(${BASENAME} "${CLFILE}" .cl | ${SED} "s/${RNAME}_//") + BNAME=$(${TR} '[:lower:]' '[:upper:]' <<<"${CNAME}") + SNAME=OPENCL_${ANAME}_STRING_${BNAME} + VNAME=opencl_${RNAME}_source_${CNAME} + MNAME=OPENCL_${ANAME}_SOURCE_${BNAME} if [ "0" != "$((0<(NFILES_OCL)))" ]; then - echo >>"${OFILE}" + echo + elif [ "${BANNER}" ] && [ "0" != "${BANNER}" ]; then + ${HEAD} -n"${BANNER}" "${CLFILE}" fi - echo "#define ${MNAME} ${VNAME}" >>"${OFILE}" - echo "#define ${SNAME} \\" >>"${OFILE}" - if [ "${CPP}" ] && \ - [ "$(eval "${CPP} ${CPPBASEFLAGS} ${CLFILE}" 2>/dev/null >/dev/null && echo "YES")" ]; - then - if [ "" != "${CPPFLAGS}" ] && \ - [ "$(eval "${CPP} ${CPPFLAGS} ${CPPBASEFLAGS} ${CLFILE}" 2>/dev/null >/dev/null && echo "YES")" ]; - then - eval "${CPP} ${CPPFLAGS} ${CPPBASEFLAGS} ${CLFILE}" 2>/dev/null - else - eval "${CPP} ${CPPBASEFLAGS} ${CLFILE}" 2>/dev/null - fi - else # fallback to sed - ${SED} -r ':a;s%(.*)/\*.*\*/%\1%;ta;/\/\*/!b;N;ba' "${CLFILE}" - fi | \ - ${SED} \ - -e '/^[[:space:]]*$/d' -e 's/[[:space:]]*$//' \ - -e 's/\\/\\\\/g' -e 's/"/\\"/g' -e 's/^/ "/' -e 's/$/\\n" \\/' \ - >>"${OFILE}" - echo " \"\"" >>"${OFILE}" - echo "static const char ${VNAME}[] = ${SNAME};" >>"${OFILE}" + echo "#define ${MNAME} ${VNAME}" + echo "#define ${SNAME} \\" + process_pre "${CLFILE}" | process "${CLFILE}" + echo " \"\"" + echo "static const char ${VNAME}[] = ${SNAME};" NFILES_OCL=$((NFILES_OCL+1)) else >&2 echo "ERROR: ${CLFILE} does not exist!" - if [ "${HFILE}" ]; then ${RM} -f "${OFILE}"; fi exit 1 - fi + fi >>"${OFILE}" else CSVFILES=("${*:NFILES_OCL+1:${#@}-NFILES_OCL-1}") break @@ -121,30 +152,28 @@ then done if [ "0" = "${NFILES_OCL}" ]; then >&2 echo "ERROR: no OpenCL file was given!" - if [ "${HFILE}" ]; then ${RM} -f "${OFILE}"; fi exit 1 fi NFILES_CSV=0 for CSVFILE in "${CSVFILES[@]}"; do if [ "${CSVFILE##*.}" = "csv" ]; then - if [ -e "${CSVFILE}" ]; then + if [ -f "${CSVFILE}" ]; then NFILES_CSV=$((NFILES_CSV+1)) fi else >&2 echo "ERROR: ${CSVFILE} is not a CSV file!" - if [ "${HFILE}" ]; then ${RM} -f "${OFILE}"; fi exit 1 fi done - if [ "0" = "${NFILES_CSV}" ] && [ "${PARAMPATH}" ]; then - CSVFILES=("${PARAMPATH}"/*.csv) + if [ "0" = "${NFILES_CSV}" ] && [ "${PARAMDIR}" ] && [ -d "${PARAMDIR}" ]; then + CSVFILES=("${PARAMDIR}"/*.csv) NFILES_CSV=${#CSVFILES[@]} fi for CSVFILE in "${CSVFILES[@]}"; do if [ ! "${DELIM}" ]; then - SEPAR=$(${SED} -n "1s/[^${DELIMS}]//gp" "${CSVFILE}") + SEPAR=$(${SED} -n "1s/[^${DELIMS}]//gp" "${CSVFILE}" 2>/dev/null) DELIM=${SEPAR:0:1} - MATCH=$(${SED} -n "1s/[^${DELIM}]//gp" "${CSVFILE}") + MATCH=$(${SED} -n "1s/[^${DELIM}]//gp" "${CSVFILE}" 2>/dev/null) fi if [ "${DELIM}" ]; then CHECK=$(${SED} "/^[[:space:]]*$/d;s/[^${DELIM}]//g" "${CSVFILE}" | ${SORT} -u | ${SED} -n "0,/./p") @@ -156,49 +185,49 @@ then else ERRFILE=${CSVFILE} fi - if [ "${ERRFILE}" ]; then + if [ "${ERRFILE}" ] && [ -f "${ERRFILE}" ]; then >&2 echo "ERROR: ${ERRFILE} is malformed!" - if [ "${HFILE}" ]; then ${RM} -f "${OFILE}"; fi exit 1 fi done DEVPAT="s/${DELIM}..*//" DEVICES=$(for CSVFILE in "${CSVFILES[@]}"; do ${SED} "1d;/^[[:space:]]*$/d;${DEVPAT}" "${CSVFILE}"; done | ${SORT} -u) - SNAME=OPENCL_LIBSMM_STRING_PARAMS_SMM - VNAME=opencl_libsmm_params_smm - DNAME=opencl_libsmm_devices - MNAME=$(echo "${VNAME}" | ${TR} '[:lower:]' '[:upper:]') - NNAME=$(echo "${DNAME}" | ${TR} '[:lower:]' '[:upper:]') + SNAME=OPENCL_${ANAME}_STRING_PARAMS_SMM + VNAME=opencl_${RNAME}_params_smm + DNAME=opencl_${RNAME}_devices + MNAME=$(${TR} '[:lower:]' '[:upper:]' <<<"${VNAME}") + NNAME=$(${TR} '[:lower:]' '[:upper:]' <<<"${DNAME}") if [ "${DEVICES}" ]; then - echo >>"${OFILE}" - echo "#define ${MNAME} ${VNAME}" >>"${OFILE}" - echo "#define ${SNAME} \\" >>"${OFILE}" + echo + echo "#define ${MNAME} ${VNAME}" + echo "#define ${SNAME} \\" CSVLINES=$(for CSVFILE in "${CSVFILES[@]}"; do ${SED} "1d;/^[[:space:]]*$/d;s/[\r]*$/\\\n\" \\\/" "${CSVFILE}"; done) IFS=$'\n' for LINE in ${CSVLINES}; do - I=0; IDEVICE=$(echo "${LINE}" | ${SED} "${DEVPAT}") + I=0; IDEVICE=$(${SED} "${DEVPAT}" <<<"${LINE}") for DEVICE in ${DEVICES}; do if [ "${DEVICE}" = "${IDEVICE}" ]; then break; fi I=$((I+1)); done - echo "${LINE}" | ${SED} "s/[^${DELIM}]*//;s/^/ \"${I}/" >>"${OFILE}" + ${SED} "s/[^${DELIM}]*/ \"${I}/" <<<"${LINE}" done - echo " \"\"" >>"${OFILE}" - echo "static const char ${VNAME}[] = ${SNAME};" >>"${OFILE}" - echo >>"${OFILE}" - echo "#define ${NNAME} ${DNAME}" >>"${OFILE}" - echo "static const char *const ${DNAME}[] = {" >>"${OFILE}" - I=0; S=","; NDEVICES=$(echo "${DEVICES}" | ${WC} -l) + echo " \"\"" + echo "static const char ${VNAME}[] = ${SNAME};" + echo + echo "#define ${NNAME} ${DNAME}" + echo "static const char *const ${DNAME}[] = {" + I=0; S=","; NDEVICES=$(${WC} -l <<<"${DEVICES}") for DEVICE in ${DEVICES}; do I=$((I+1)); if [ "0" != "$((NDEVICES==I))" ]; then S=""; fi - echo " \"${DEVICE}\"${S}" >>"${OFILE}" + echo " \"${DEVICE}\"${S}" done unset IFS - echo "};" >>"${OFILE}" - fi + echo "};" + fi >>"${OFILE}" else echo "Usage: $0 infile.cl [infile2.cl .. infileN.cl] [infile.csv [.. infileN.csv]] outfile.h" echo " At least one OpenCL file and one header file must be supplied." + echo " -b|--banner N: number of lines used as banner (default: 0)" echo " -p|--params P: directory-path to CSV-files (can be \"\")" echo " default: ${PARAMDIR}" echo " -c|-d|--debug|--comments: keep comments in source-code" diff --git a/src/acc/opencl/acc_opencl_event.c b/src/acc/opencl/acc_opencl_event.c index fe869f8e6e7..7fde985a04e 100644 --- a/src/acc/opencl/acc_opencl_event.c +++ b/src/acc/opencl/acc_opencl_event.c @@ -9,17 +9,14 @@ #if defined(__OPENCL) # include "acc_opencl.h" -# if defined(CL_VERSION_1_2) -# define ACC_OPENCL_WAIT_EVENT(QUEUE, EVENT) clEnqueueMarkerWithWaitList(QUEUE, 1, EVENT, NULL) -# else -# define ACC_OPENCL_WAIT_EVENT(QUEUE, EVENT) clEnqueueWaitForEvents(QUEUE, 1, EVENT) +# if !defined(ACC_OPENCL_EVENT_FLUSH) && 0 +# define ACC_OPENCL_EVENT_FLUSH # endif - -# if !defined(ACC_OPENCL_EVENT_BARRIER) && 0 -# define ACC_OPENCL_EVENT_BARRIER +# if !defined(ACC_OPENCL_EVENT_CHAIN) && 0 +# define ACC_OPENCL_EVENT_CHAIN # endif -# if !defined(ACC_OPENCL_EVENT_CREATE) && 0 -# define ACC_OPENCL_EVENT_CREATE +# if !defined(ACC_OPENCL_EVENT_WAIT) && 0 +# define ACC_OPENCL_EVENT_WAIT # endif @@ -27,69 +24,19 @@ extern "C" { # endif -int c_dbcsr_acc_opencl_event_create(cl_event* event_p) { - int result; - assert(NULL != event_p); - if (NULL != *event_p) result = EXIT_SUCCESS; - else { - *event_p = clCreateUserEvent(c_dbcsr_acc_opencl_context(NULL /*tid*/), &result); - } - if (CL_SUCCESS == result) { - assert(NULL != *event_p); - /* an empty event (unrecorded) has no work to wait for; hence it is - * considered occurred and c_dbcsr_acc_event_synchronize must not block - */ - result = clSetUserEventStatus(*event_p, CL_COMPLETE); - if (CL_SUCCESS != result) { /* error: setting initial event state */ - ACC_OPENCL_EXPECT(CL_SUCCESS == clReleaseEvent(*event_p)); - *event_p = NULL; - } - } - else { - *event_p = NULL; /* error: creating user-defined event */ - } - return result; -} - - int c_dbcsr_acc_event_create(void** event_p) { int result = EXIT_SUCCESS; - cl_event event = NULL; # if defined(__DBCSR_ACC) && defined(ACC_OPENCL_PROFILE) int routine_handle; static const char* const routine_name_ptr = LIBXSMM_FUNCNAME; static const int routine_name_len = (int)sizeof(LIBXSMM_FUNCNAME) - 1; c_dbcsr_timeset((const char**)&routine_name_ptr, &routine_name_len, &routine_handle); # endif - assert(NULL != event_p); -# if defined(ACC_OPENCL_EVENT_CREATE) - result = c_dbcsr_acc_opencl_event_create(&event); - assert(NULL != event || EXIT_SUCCESS != result); - if (EXIT_SUCCESS == result) -# endif - { - assert(NULL == c_dbcsr_acc_opencl_config.handles || sizeof(void*) >= sizeof(cl_event)); - *event_p = ( -# if LIBXSMM_VERSION4(1, 17, 0, 0) < LIBXSMM_VERSION_NUMBER && defined(ACC_OPENCL_HANDLES_MAXCOUNT) && \ - (0 < ACC_OPENCL_HANDLES_MAXCOUNT) - NULL != c_dbcsr_acc_opencl_config.handles - ? libxsmm_pmalloc(c_dbcsr_acc_opencl_config.handles, &c_dbcsr_acc_opencl_config.handle) - : -# endif - malloc(sizeof(cl_event))); - if (NULL != *event_p) { - *(cl_event*)*event_p = event; - } - else { - if (NULL != event) ACC_OPENCL_EXPECT(CL_SUCCESS == clReleaseEvent(event)); - result = EXIT_FAILURE; - } - } -# if defined(ACC_OPENCL_EVENT_CREATE) - else { - *event_p = NULL; /* error: creating user-defined event */ - } -# endif + assert(NULL != c_dbcsr_acc_opencl_config.events && NULL != event_p); + *event_p = c_dbcsr_acc_opencl_pmalloc( + c_dbcsr_acc_opencl_config.lock_event, (void**)c_dbcsr_acc_opencl_config.events, &c_dbcsr_acc_opencl_config.nevents); + if (NULL != *event_p) *(cl_event*)*event_p = NULL; + else result = EXIT_FAILURE; # if defined(__DBCSR_ACC) && defined(ACC_OPENCL_PROFILE) c_dbcsr_timestop(&routine_handle); # endif @@ -107,18 +54,16 @@ int c_dbcsr_acc_event_destroy(void* event) { # endif if (NULL != event) { const cl_event clevent = *ACC_OPENCL_EVENT(event); - if (NULL != clevent) result = clReleaseEvent(clevent); -# if LIBXSMM_VERSION4(1, 17, 0, 0) < LIBXSMM_VERSION_NUMBER && defined(ACC_OPENCL_HANDLES_MAXCOUNT) && \ - (0 < ACC_OPENCL_HANDLES_MAXCOUNT) - if (NULL != c_dbcsr_acc_opencl_config.handles) { - /**(cl_event*)event = NULL; assert(NULL == *ACC_OPENCL_EVENT(event));*/ - libxsmm_pfree(event, c_dbcsr_acc_opencl_config.handles, &c_dbcsr_acc_opencl_config.handle); - } - else + assert(NULL != c_dbcsr_acc_opencl_config.events); + ACC_OPENCL_ACQUIRE(c_dbcsr_acc_opencl_config.lock_event); + c_dbcsr_acc_opencl_pfree(NULL /*lock*/, event, (void**)c_dbcsr_acc_opencl_config.events, &c_dbcsr_acc_opencl_config.nevents); + if (NULL != clevent) { + result = clReleaseEvent(clevent); +# if !defined(NDEBUG) + *(cl_event*)event = NULL; # endif - { - free(event); } + ACC_OPENCL_RELEASE(c_dbcsr_acc_opencl_config.lock_event); } # if defined(__DBCSR_ACC) && defined(ACC_OPENCL_PROFILE) c_dbcsr_timestop(&routine_handle); @@ -129,22 +74,40 @@ int c_dbcsr_acc_event_destroy(void* event) { int c_dbcsr_acc_stream_wait_event(void* stream, void* event) { /* wait for an event (device-side) */ int result = EXIT_SUCCESS; - cl_event clevent; + const c_dbcsr_acc_opencl_stream_t* str = NULL; + cl_event clevent = NULL; # if defined(__DBCSR_ACC) && defined(ACC_OPENCL_PROFILE) int routine_handle; static const char* const routine_name_ptr = LIBXSMM_FUNCNAME; static const int routine_name_len = (int)sizeof(LIBXSMM_FUNCNAME) - 1; c_dbcsr_timeset((const char**)&routine_name_ptr, &routine_name_len, &routine_handle); # endif - assert(NULL != stream && NULL != event); + str = (NULL != stream ? ACC_OPENCL_STREAM(stream) : c_dbcsr_acc_opencl_stream_default()); + assert(NULL != str && NULL != str->queue && NULL != event); clevent = *ACC_OPENCL_EVENT(event); -# if defined(ACC_OPENCL_EVENT_CREATE) - assert(NULL != clevent); + if (NULL != clevent) { +# if defined(CL_VERSION_1_2) + cl_event clevent_result = NULL; + result = clEnqueueBarrierWithWaitList(str->queue, 1, &clevent, &clevent_result); + if (EXIT_SUCCESS == result) { +# if defined(ACC_OPENCL_EVENT_CHAIN) + result = clReleaseEvent(clevent); + assert(NULL != clevent_result); + *(cl_event*)event = (EXIT_SUCCESS == result ? clevent_result : NULL); +# endif + } + else # else - if (NULL != clevent) + result = clEnqueueWaitForEvents(str->queue, 1, &clevent); + if (EXIT_SUCCESS != result) # endif - { - result = ACC_OPENCL_WAIT_EVENT(*ACC_OPENCL_STREAM(stream), &clevent); + { + ACC_OPENCL_EXPECT(EXIT_SUCCESS == clReleaseEvent(clevent)); + *(cl_event*)event = NULL; + } + } + else if (3 <= c_dbcsr_acc_opencl_config.verbosity || 0 > c_dbcsr_acc_opencl_config.verbosity) { + fprintf(stderr, "WARN ACC/OpenCL: c_dbcsr_acc_stream_wait_event discovered an empty event.\n"); } # if defined(__DBCSR_ACC) && defined(ACC_OPENCL_PROFILE) c_dbcsr_timestop(&routine_handle); @@ -154,25 +117,49 @@ int c_dbcsr_acc_stream_wait_event(void* stream, void* event) { /* wait for an ev int c_dbcsr_acc_event_record(void* event, void* stream) { - int result; - cl_event clevent = NULL; + int result = EXIT_SUCCESS; + const c_dbcsr_acc_opencl_stream_t* str = NULL; + cl_event clevent = NULL, clevent_result = NULL; # if defined(__DBCSR_ACC) && defined(ACC_OPENCL_PROFILE) int routine_handle; static const char* const routine_name_ptr = LIBXSMM_FUNCNAME; static const int routine_name_len = (int)sizeof(LIBXSMM_FUNCNAME) - 1; c_dbcsr_timeset((const char**)&routine_name_ptr, &routine_name_len, &routine_handle); # endif - assert(NULL != event && NULL != stream); -# if defined(ACC_OPENCL_EVENT_BARRIER) && defined(CL_VERSION_1_2) - result = clEnqueueBarrierWithWaitList(*ACC_OPENCL_STREAM(stream), 0, NULL, &clevent); -# elif defined(CL_VERSION_1_2) - result = clEnqueueMarkerWithWaitList(*ACC_OPENCL_STREAM(stream), 0, NULL, &clevent); + str = (NULL != stream ? ACC_OPENCL_STREAM(stream) : c_dbcsr_acc_opencl_stream_default()); + assert(NULL != str && NULL != str->queue && NULL != event); + clevent = *ACC_OPENCL_EVENT(event); +# if defined(ACC_OPENCL_EVENT_FLUSH) + result = clFlush(str->queue); + if (EXIT_SUCCESS == result) +# endif + { +# if defined(CL_VERSION_1_2) +# if defined(ACC_OPENCL_EVENT_WAIT) + if (NULL != clevent) result = clEnqueueMarkerWithWaitList(str->queue, 1, &clevent, &clevent_result); + else +# endif + { + result = clEnqueueMarkerWithWaitList(str->queue, 0, NULL, &clevent_result); + } # else - result = clEnqueueMarker(*ACC_OPENCL_STREAM(stream), &clevent); +# if defined(ACC_OPENCL_EVENT_WAIT) + if (NULL != clevent) result = clEnqueueWaitForEvents(str->queue, 1, &clevent); +# endif + if (EXIT_SUCCESS == result) result = clEnqueueMarker(str->queue, &clevent_result); # endif - if (CL_SUCCESS == result) { - assert(NULL != clevent); - *(cl_event*)event = clevent; + } + if (NULL != clevent) { + const int result_release = clReleaseEvent(clevent); + if (EXIT_SUCCESS == result) result = result_release; + } + if (EXIT_SUCCESS == result) { + assert(NULL != clevent_result); + *(cl_event*)event = clevent_result; + } + else { + if (NULL != clevent_result) ACC_OPENCL_EXPECT(EXIT_SUCCESS == clReleaseEvent(clevent_result)); + *(cl_event*)event = NULL; } # if defined(__DBCSR_ACC) && defined(ACC_OPENCL_PROFILE) c_dbcsr_timestop(&routine_handle); @@ -192,18 +179,9 @@ int c_dbcsr_acc_event_query(void* event, c_dbcsr_acc_bool_t* has_occurred) { # endif assert(NULL != event && NULL != has_occurred); result = clGetEventInfo(*ACC_OPENCL_EVENT(event), CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof(cl_int), &status, NULL); - if (CL_SUCCESS == result && 0 <= status) { - *has_occurred = (CL_COMPLETE == status ? 1 : 0); - if (0 == *has_occurred && 0 != (8 & c_dbcsr_acc_opencl_config.flush)) { - result = c_dbcsr_acc_opencl_device_synchronize(ACC_OPENCL_OMP_TID()); - } - } + if (EXIT_SUCCESS == result && 0 <= status) *has_occurred = (CL_COMPLETE == status ? 1 : 0); else { /* error state */ -# if defined(ACC_OPENCL_EVENT_CREATE) - if (CL_SUCCESS == result) result = EXIT_FAILURE; -# else - result = EXIT_SUCCESS; -# endif + result = EXIT_SUCCESS; /* soft-error */ *has_occurred = 1; } # if defined(__DBCSR_ACC) && defined(ACC_OPENCL_PROFILE) @@ -214,7 +192,7 @@ int c_dbcsr_acc_event_query(void* event, c_dbcsr_acc_bool_t* has_occurred) { int c_dbcsr_acc_event_synchronize(void* event) { /* waits on the host-side */ - int result; + int result = EXIT_SUCCESS; cl_event clevent; # if defined(__DBCSR_ACC) && defined(ACC_OPENCL_PROFILE) int routine_handle; @@ -224,14 +202,9 @@ int c_dbcsr_acc_event_synchronize(void* event) { /* waits on the host-side */ # endif assert(NULL != event); clevent = *ACC_OPENCL_EVENT(event); -# if !defined(ACC_OPENCL_EVENT_CREATE) - if (NULL == clevent) { - result = EXIT_SUCCESS; - } - else -# endif - { - result = clWaitForEvents(1, &clevent); + if (NULL != clevent) result = clWaitForEvents(1, &clevent); + else if (3 <= c_dbcsr_acc_opencl_config.verbosity || 0 > c_dbcsr_acc_opencl_config.verbosity) { + fprintf(stderr, "WARN ACC/OpenCL: c_dbcsr_acc_event_synchronize discovered an empty event.\n"); } # if defined(__DBCSR_ACC) && defined(ACC_OPENCL_PROFILE) c_dbcsr_timestop(&routine_handle); diff --git a/src/acc/opencl/acc_opencl_mem.c b/src/acc/opencl/acc_opencl_mem.c index e2032080588..5ea4846ad86 100644 --- a/src/acc/opencl/acc_opencl_mem.c +++ b/src/acc/opencl/acc_opencl_mem.c @@ -28,90 +28,182 @@ extern "C" { # endif -int c_dbcsr_acc_opencl_memalignment(size_t /*size*/); -int c_dbcsr_acc_opencl_memalignment(size_t size) { - int result; - if ((ACC_OPENCL_MEM_ALIGNSCALE * ACC_OPENCL_MAXALIGN_NBYTES) <= size) { - result = ACC_OPENCL_MAXALIGN_NBYTES; - } - else if ((ACC_OPENCL_MEM_ALIGNSCALE * ACC_OPENCL_CACHELINE_NBYTES) <= size) { - result = ACC_OPENCL_CACHELINE_NBYTES; +void c_dbcsr_acc_opencl_pmalloc_init(ACC_OPENCL_LOCKTYPE* lock, size_t size, size_t* num, void* pool[], void* storage) { + char* p = (char*)storage; + size_t n, i = 0; + assert(0 < size && NULL != num && NULL != pool && NULL != storage); + if (NULL != lock) ACC_OPENCL_ACQUIRE(lock); + for (n = *num; i < n; ++i, p += size) pool[i] = p; + if (NULL != lock) ACC_OPENCL_RELEASE(lock); +} + + +void* c_dbcsr_acc_opencl_pmalloc(ACC_OPENCL_LOCKTYPE* lock, void* pool[], size_t* i) { + void* pointer; + assert(NULL != pool && NULL != i); + if (NULL != lock) ACC_OPENCL_ACQUIRE(lock); + pointer = (0 < *i ? pool[--(*i)] : NULL); + if (NULL != lock) ACC_OPENCL_RELEASE(lock); + assert(NULL != pointer); + return pointer; +} + + +void c_dbcsr_acc_opencl_pfree(ACC_OPENCL_LOCKTYPE* lock, const void* pointer, void* pool[], size_t* i) { + assert(NULL != pool && NULL != i); + if (NULL != pointer) { + if (NULL != lock) ACC_OPENCL_ACQUIRE(lock); + LIBXSMM_ASSIGN127(pool + *i, &pointer); + ++(*i); + if (NULL != lock) ACC_OPENCL_RELEASE(lock); } - else { - result = sizeof(void*); +} + + +c_dbcsr_acc_opencl_info_memptr_t* c_dbcsr_acc_opencl_info_hostptr(void* memory) { + assert(NULL == memory || sizeof(c_dbcsr_acc_opencl_info_memptr_t) <= (uintptr_t)memory); + return (NULL != memory ? (c_dbcsr_acc_opencl_info_memptr_t*)((uintptr_t)memory - sizeof(c_dbcsr_acc_opencl_info_memptr_t)) + : (c_dbcsr_acc_opencl_info_memptr_t*)NULL); +} + + +c_dbcsr_acc_opencl_info_memptr_t* c_dbcsr_acc_opencl_info_devptr_modify( + ACC_OPENCL_LOCKTYPE* lock, void* memory, size_t elsize, const size_t* amount, size_t* offset) { + c_dbcsr_acc_opencl_info_memptr_t* result = NULL; + assert(0 < elsize); + if (NULL != memory) { +# if defined(ACC_OPENCL_MEM_DEVPTR) + if (NULL == c_dbcsr_acc_opencl_config.device.clSetKernelArgMemPointerINTEL) { + const char* const pointer = (const char*)memory; + const size_t n = ACC_OPENCL_MAXNITEMS * c_dbcsr_acc_opencl_config.nthreads; + size_t hit = (size_t)-1, i; + assert(NULL != c_dbcsr_acc_opencl_config.memptrs); + if (NULL != lock) ACC_OPENCL_ACQUIRE(lock); + for (i = c_dbcsr_acc_opencl_config.nmemptrs; i < n; ++i) { + c_dbcsr_acc_opencl_info_memptr_t* const info = c_dbcsr_acc_opencl_config.memptrs[i]; + if (NULL != info) { + char* const memptr = (char*)info->memptr; + assert(NULL != memptr); + if (memptr == pointer) { /* fast-path */ + if (NULL != offset) *offset = 0; + result = info; + break; + } + else if (memptr < pointer && NULL != offset) { + size_t d = pointer - memptr, s = d; + assert(0 != d); + if (d < hit && +# if !defined(NDEBUG) + (EXIT_SUCCESS == clGetMemObjectInfo(info->memory, CL_MEM_SIZE, sizeof(size_t), &s, NULL)) && + (NULL == amount || (*amount * elsize + d) <= s) && +# endif + (1 == elsize || (0 == (d % elsize) && 0 == (s % elsize))) && d <= s) + { + *offset = (1 == elsize ? d : (d / elsize)); + result = info; + hit = d; + } + } + } + else break; + } + if (NULL != lock) ACC_OPENCL_RELEASE(lock); + } + else +# endif + { +# if defined(ACC_OPENCL_MEM_DEVPTR) +# if defined(NDEBUG) + LIBXSMM_UNUSED(amount); +# endif +# else + LIBXSMM_UNUSED(lock); + LIBXSMM_UNUSED(elsize); + LIBXSMM_UNUSED(amount); +# endif + /* assume only first item of c_dbcsr_acc_opencl_info_memptr_t is accessed */ + result = (c_dbcsr_acc_opencl_info_memptr_t*)memory; + if (NULL != offset) *offset = 0; + } } return result; } -void* c_dbcsr_acc_opencl_get_hostptr(cl_mem memory) { - void* result = NULL; - ACC_OPENCL_EXPECT(CL_SUCCESS == clGetMemObjectInfo(memory, CL_MEM_HOST_PTR, sizeof(void*), &result, NULL)); +int c_dbcsr_acc_opencl_info_devptr_lock(c_dbcsr_acc_opencl_info_memptr_t* info, ACC_OPENCL_LOCKTYPE* lock, const void* memory, + size_t elsize, const size_t* amount, size_t* offset) { + c_dbcsr_acc_opencl_info_memptr_t* devptr = NULL; + int result = EXIT_SUCCESS; + void* non_const; + LIBXSMM_ASSIGN127(&non_const, &memory); + assert(NULL != info); + devptr = c_dbcsr_acc_opencl_info_devptr_modify(lock, non_const, elsize, amount, offset); + if (NULL != devptr) { +# if defined(ACC_OPENCL_MEM_DEVPTR) + if (NULL == c_dbcsr_acc_opencl_config.device.clSetKernelArgMemPointerINTEL) { + LIBXSMM_ASSIGN127(info, devptr); + } + else +# endif + { +# if !defined(NDEBUG) + LIBXSMM_MEMZERO127(info); +# endif + info->memory = (cl_mem)devptr; + } + } + else result = EXIT_FAILURE; return result; } -c_dbcsr_acc_opencl_info_hostptr_t* c_dbcsr_acc_opencl_info_hostptr(void* memory) { - assert(NULL == memory || sizeof(c_dbcsr_acc_opencl_info_hostptr_t) <= (uintptr_t)memory); - return (NULL != memory ? (c_dbcsr_acc_opencl_info_hostptr_t*)((uintptr_t)memory - sizeof(c_dbcsr_acc_opencl_info_hostptr_t)) - : (c_dbcsr_acc_opencl_info_hostptr_t*)NULL); +int c_dbcsr_acc_opencl_info_devptr( + c_dbcsr_acc_opencl_info_memptr_t* info, const void* memory, size_t elsize, const size_t* amount, size_t* offset) { + return c_dbcsr_acc_opencl_info_devptr_lock(info, c_dbcsr_acc_opencl_config.lock_memory, memory, elsize, amount, offset); } int c_dbcsr_acc_host_mem_allocate(void** host_mem, size_t nbytes, void* stream) { - c_dbcsr_acc_opencl_info_stream_t* const info = c_dbcsr_acc_opencl_info_stream(stream); - const size_t size_meminfo = sizeof(c_dbcsr_acc_opencl_info_hostptr_t); - const int alignment = c_dbcsr_acc_opencl_memalignment(nbytes); - void* host_ptr = NULL; + const size_t size_meminfo = sizeof(c_dbcsr_acc_opencl_info_memptr_t); + int result = EXIT_SUCCESS, alignment = sizeof(void*); cl_mem memory = NULL; - cl_int result; # if defined(__DBCSR_ACC) && defined(ACC_OPENCL_PROFILE) int routine_handle; static const char* const routine_name_ptr = LIBXSMM_FUNCNAME; static const int routine_name_len = (int)sizeof(LIBXSMM_FUNCNAME) - 1; c_dbcsr_timeset((const char**)&routine_name_ptr, &routine_name_len, &routine_handle); # endif - nbytes += alignment + size_meminfo - 1; - assert(NULL != host_mem && NULL != stream && NULL != info); -# if defined(CL_VERSION_2_0) - if (0 != c_dbcsr_acc_opencl_config.device[info->tid].svm_interop) { - host_ptr = clSVMAlloc( - c_dbcsr_acc_opencl_config.device[info->tid].context, CL_MEM_READ_WRITE, nbytes, sizeof(void*) /*minimal alignment*/); - if (NULL == host_ptr) c_dbcsr_acc_opencl_config.device[info->tid].svm_interop = 0; /* sanitize */ + if ((ACC_OPENCL_MEM_ALIGNSCALE * ACC_OPENCL_CACHELINE) <= nbytes) { + alignment = ((ACC_OPENCL_MEM_ALIGNSCALE * ACC_OPENCL_MAXALIGN) <= nbytes ? ACC_OPENCL_MAXALIGN : ACC_OPENCL_CACHELINE); } -# endif - memory = clCreateBuffer(c_dbcsr_acc_opencl_config.device[info->tid].context, - NULL == host_ptr ? CL_MEM_ALLOC_HOST_PTR : CL_MEM_USE_HOST_PTR, nbytes, host_ptr, &result); - assert(CL_SUCCESS == result || NULL == memory); - if (CL_SUCCESS == result) { - const cl_command_queue queue = *ACC_OPENCL_STREAM(stream); + nbytes += alignment + size_meminfo - 1; + assert(NULL != host_mem); + memory = clCreateBuffer(c_dbcsr_acc_opencl_config.device.context, CL_MEM_ALLOC_HOST_PTR, nbytes, NULL /*host_ptr*/, &result); + if (EXIT_SUCCESS == result) { + const c_dbcsr_acc_opencl_stream_t* const str = (NULL != stream ? ACC_OPENCL_STREAM(stream) + : c_dbcsr_acc_opencl_stream_default()); void* const mapped = clEnqueueMapBuffer( - queue, memory, CL_TRUE /*blocking*/, CL_MAP_READ | CL_MAP_WRITE, 0 /*offset*/, nbytes, 0, NULL, NULL, &result); - assert(CL_SUCCESS == result || NULL == mapped); - if (CL_SUCCESS == result) { + str->queue, memory, CL_TRUE /*always block*/, CL_MAP_READ | CL_MAP_WRITE, 0 /*offset*/, nbytes, 0, NULL, NULL, &result); + assert(EXIT_SUCCESS == result || NULL == mapped); + if (EXIT_SUCCESS == result) { const uintptr_t address = (uintptr_t)mapped; const uintptr_t aligned = LIBXSMM_UP2(address + size_meminfo, alignment); - c_dbcsr_acc_opencl_info_hostptr_t* meminfo; + c_dbcsr_acc_opencl_info_memptr_t* meminfo; assert(address + size_meminfo <= aligned); - meminfo = (c_dbcsr_acc_opencl_info_hostptr_t*)(aligned - size_meminfo); + meminfo = (c_dbcsr_acc_opencl_info_memptr_t*)(aligned - size_meminfo); if (NULL != meminfo) { meminfo->memory = memory; - meminfo->mapped = mapped; + meminfo->memptr = mapped; *host_mem = (void*)aligned; } - else { /* error: buffer info */ - result = EXIT_FAILURE; - *host_mem = NULL; - } - } - else { /* error: mapping host buffer */ - ACC_OPENCL_EXPECT(CL_SUCCESS == clReleaseMemObject(memory)); - *host_mem = NULL; + else result = EXIT_FAILURE; } } - else { - *host_mem = NULL; /* error: creating host buffer */ + if (EXIT_SUCCESS != result) { + if (NULL != memory) ACC_OPENCL_EXPECT(EXIT_SUCCESS == clReleaseMemObject(memory)); + *host_mem = NULL; } + assert(EXIT_SUCCESS == result || NULL == *host_mem); # if defined(__DBCSR_ACC) && defined(ACC_OPENCL_PROFILE) c_dbcsr_timestop(&routine_handle); # endif @@ -120,39 +212,28 @@ int c_dbcsr_acc_host_mem_allocate(void** host_mem, size_t nbytes, void* stream) int c_dbcsr_acc_host_mem_deallocate(void* host_mem, void* stream) { - int result; + int result = EXIT_SUCCESS; # if defined(__DBCSR_ACC) && defined(ACC_OPENCL_PROFILE) int routine_handle; static const char* const routine_name_ptr = LIBXSMM_FUNCNAME; static const int routine_name_len = (int)sizeof(LIBXSMM_FUNCNAME) - 1; c_dbcsr_timeset((const char**)&routine_name_ptr, &routine_name_len, &routine_handle); # endif - assert(NULL != stream); if (NULL != host_mem) { - c_dbcsr_acc_opencl_info_hostptr_t* const meminfo = c_dbcsr_acc_opencl_info_hostptr(host_mem); + c_dbcsr_acc_opencl_info_memptr_t* const meminfo = c_dbcsr_acc_opencl_info_hostptr(host_mem); if (NULL != meminfo->memory) { - const c_dbcsr_acc_opencl_info_hostptr_t info = *meminfo; /* copy meminfo prior to unmap */ - const cl_command_queue queue = *ACC_OPENCL_STREAM(stream); + const c_dbcsr_acc_opencl_info_memptr_t info = *meminfo; /* copy meminfo prior to unmap */ + const c_dbcsr_acc_opencl_stream_t* const str = (NULL != stream ? ACC_OPENCL_STREAM(stream) + : c_dbcsr_acc_opencl_stream_default()); int result_release; - result = clEnqueueUnmapMemObject(queue, info.memory, info.mapped, 0, NULL, NULL); -# if defined(CL_VERSION_2_0) - { - const c_dbcsr_acc_opencl_info_stream_t* const qinfo = c_dbcsr_acc_opencl_info_stream(stream); - assert(NULL != qinfo); - if (0 != c_dbcsr_acc_opencl_config.device[qinfo->tid].svm_interop) { - clSVMFree(c_dbcsr_acc_opencl_config.device[qinfo->tid].context, info.mapped); - } - } -# endif + cl_event event; + assert(NULL != str && NULL != str->queue); + result = clEnqueueUnmapMemObject(str->queue, info.memory, info.memptr, 0, NULL, &event); + if (NULL == stream && EXIT_SUCCESS == result) result = clWaitForEvents(1, &event); result_release = clReleaseMemObject(info.memory); if (EXIT_SUCCESS == result) result = result_release; } - else { - result = EXIT_FAILURE; - } - } - else { - result = EXIT_FAILURE; + else result = EXIT_FAILURE; } # if defined(__DBCSR_ACC) && defined(ACC_OPENCL_PROFILE) c_dbcsr_timestop(&routine_handle); @@ -161,80 +242,140 @@ int c_dbcsr_acc_host_mem_deallocate(void* host_mem, void* stream) { } +/* like c_dbcsr_acc_memcpy_d2h, but apply some async workaround. */ +int c_dbcsr_acc_opencl_memcpy_d2h( + cl_mem /*dev_mem*/, void* /*host_mem*/, size_t /*offset*/, size_t /*nbytes*/, cl_command_queue /*queue*/, int /*blocking*/); +int c_dbcsr_acc_opencl_memcpy_d2h( + cl_mem dev_mem, void* host_mem, size_t offset, size_t nbytes, cl_command_queue queue, int blocking) { +# if defined(ACC_OPENCL_ASYNC) + const cl_bool finish = (0 != blocking || 0 == (2 & c_dbcsr_acc_opencl_config.async) || + (0 != c_dbcsr_acc_opencl_config.device.nv && NULL == (ACC_OPENCL_ASYNC))); +# else + const cl_bool finish = CL_TRUE; +# endif + int result = EXIT_SUCCESS; +# if defined(ACC_OPENCL_MEM_DEVPTR) + if (NULL != c_dbcsr_acc_opencl_config.device.clEnqueueMemcpyINTEL) { + result = c_dbcsr_acc_opencl_config.device.clEnqueueMemcpyINTEL(queue, finish, host_mem, dev_mem, nbytes, 0, NULL, NULL); + } + else +# endif + { + result = clEnqueueReadBuffer(queue, dev_mem, finish, offset, nbytes, host_mem, 0, NULL, NULL); + } + if (EXIT_SUCCESS != result && !finish) { /* retry synchronously */ + int result_sync = EXIT_SUCCESS; +# if defined(ACC_OPENCL_MEM_DEVPTR) + if (NULL != c_dbcsr_acc_opencl_config.device.clEnqueueMemcpyINTEL) { + result_sync = c_dbcsr_acc_opencl_config.device.clEnqueueMemcpyINTEL(queue, CL_TRUE, host_mem, dev_mem, nbytes, 0, NULL, NULL); + } + else +# endif + { + result_sync = clEnqueueReadBuffer(queue, dev_mem, CL_TRUE, offset, nbytes, host_mem, 0, NULL, NULL); + } + if (EXIT_SUCCESS == result_sync) { + c_dbcsr_acc_opencl_config.async &= ~2; /* retract async feature */ + if (0 != c_dbcsr_acc_opencl_config.verbosity) { + fprintf(stderr, "WARN ACC/OpenCL: falling back to synchronous readback (code=%i).\n", result); + } + result = EXIT_SUCCESS; + } + } + return result; +} + + int c_dbcsr_acc_dev_mem_allocate(void** dev_mem, size_t nbytes) { - cl_int result; - int tid = 0; - const cl_context context = c_dbcsr_acc_opencl_context(&tid); - const int devuid = c_dbcsr_acc_opencl_config.device[tid].uid, - try_flag = ((0 != c_dbcsr_acc_opencl_config.device[tid].unified || 0 == c_dbcsr_acc_opencl_config.device[tid].intel || - (0x4905 != devuid && 0x020a != devuid && (0x0bd0 > devuid || 0x0bdb < devuid))) - ? 0 - : (1u << 22)); - cl_mem buffer; + int result = EXIT_SUCCESS; + /* assume no lock is needed to protect against context/device changes */ + const cl_context context = c_dbcsr_acc_opencl_config.device.context; + cl_mem memory = NULL; + void* memptr = NULL; # if defined(__DBCSR_ACC) && defined(ACC_OPENCL_PROFILE) int routine_handle; static const char* const routine_name_ptr = LIBXSMM_FUNCNAME; static const int routine_name_len = (int)sizeof(LIBXSMM_FUNCNAME) - 1; c_dbcsr_timeset((const char**)&routine_name_ptr, &routine_name_len, &routine_handle); # endif - assert(NULL != dev_mem && 0 <= ACC_OPENCL_OVERMALLOC); - assert(NULL != context); - buffer = ( -# if defined(CL_VERSION_2_0) - 0 != c_dbcsr_acc_opencl_config.device[tid].svm_interop - ? clCreateBuffer(context, CL_MEM_USE_HOST_PTR, nbytes + ACC_OPENCL_OVERMALLOC, - clSVMAlloc( - context, (cl_mem_flags)(CL_MEM_READ_WRITE | try_flag), nbytes + ACC_OPENCL_OVERMALLOC, 0 /*default alignment*/), - &result) - : -# endif - clCreateBuffer( - context, (cl_mem_flags)(CL_MEM_READ_WRITE | try_flag), nbytes + ACC_OPENCL_OVERMALLOC, NULL /*host_ptr*/, &result)); - if (0 != try_flag && CL_SUCCESS != result) { /* retry without try_flag */ - buffer = ( -# if defined(CL_VERSION_2_0) - 0 != c_dbcsr_acc_opencl_config.device[tid].svm_interop - ? clCreateBuffer(context, CL_MEM_USE_HOST_PTR, nbytes + ACC_OPENCL_OVERMALLOC, - clSVMAlloc(context, CL_MEM_READ_WRITE, nbytes + ACC_OPENCL_OVERMALLOC, 0 /*default alignment*/), &result) - : -# endif - clCreateBuffer(context, CL_MEM_READ_WRITE, nbytes + ACC_OPENCL_OVERMALLOC, NULL /*host_ptr*/, &result)); + assert(NULL != dev_mem && NULL != context); +# if defined(ACC_OPENCL_MEM_DEVPTR) + if (NULL != c_dbcsr_acc_opencl_config.device.clDeviceMemAllocINTEL) { + cl_device_id device = NULL; + result = clGetContextInfo(context, CL_CONTEXT_DEVICES, sizeof(cl_device_id), &device, NULL); + if (EXIT_SUCCESS == result) { + *dev_mem = memptr = c_dbcsr_acc_opencl_config.device.clDeviceMemAllocINTEL( + context, device, NULL /*properties*/, nbytes, 0 /*alignment*/, &result); + } + if (EXIT_SUCCESS != result) *dev_mem = NULL; } - if (EXIT_SUCCESS == result) { - assert(NULL != buffer); -# if defined(ACC_OPENCL_MEM_NOALLOC) - assert(sizeof(void*) >= sizeof(cl_mem)); - *dev_mem = (void*)buffer; -# else - assert(NULL == c_dbcsr_acc_opencl_config.handles || sizeof(void*) >= sizeof(cl_mem)); - *dev_mem = ( -# if LIBXSMM_VERSION4(1, 17, 0, 0) < LIBXSMM_VERSION_NUMBER && defined(ACC_OPENCL_HANDLES_MAXCOUNT) && \ - (0 < ACC_OPENCL_HANDLES_MAXCOUNT) - NULL != c_dbcsr_acc_opencl_config.handles - ? libxsmm_pmalloc(c_dbcsr_acc_opencl_config.handles, &c_dbcsr_acc_opencl_config.handle) - : -# endif - malloc(sizeof(cl_mem))); - if (NULL != *dev_mem) { - *(cl_mem*)*dev_mem = buffer; + else +# endif + { + const int devuid = c_dbcsr_acc_opencl_config.device.uid; + const int try_flag = ((0 != c_dbcsr_acc_opencl_config.device.unified || 0 == c_dbcsr_acc_opencl_config.device.intel || + (0x4905 != devuid && 0x020a != devuid && (0x0bd0 > devuid || 0x0bdb < devuid))) + ? 0 + : (1u << 22)); + memory = clCreateBuffer(context, (cl_mem_flags)(CL_MEM_READ_WRITE | try_flag), nbytes, NULL /*host_ptr*/, &result); + if (0 != try_flag && EXIT_SUCCESS != result) { /* retry without try_flag */ + memory = clCreateBuffer(context, CL_MEM_READ_WRITE, nbytes, NULL /*host_ptr*/, &result); } - else { -# if defined(CL_VERSION_2_0) - void* const ptr = (0 != c_dbcsr_acc_opencl_config.device[tid].svm_interop ? c_dbcsr_acc_opencl_get_hostptr(buffer) : NULL); -# endif - clReleaseMemObject(buffer); -# if defined(CL_VERSION_2_0) - if (0 != c_dbcsr_acc_opencl_config.device[tid].svm_interop /*&& (NULL != ptr)*/) { - clSVMFree(context, ptr); + if (EXIT_SUCCESS == result) { +# if defined(ACC_OPENCL_MEM_DEVPTR) + const c_dbcsr_acc_opencl_stream_t* str = NULL; + static cl_kernel kernel = NULL; + const size_t size = 1; + ACC_OPENCL_ACQUIRE(c_dbcsr_acc_opencl_config.lock_memory); + str = c_dbcsr_acc_opencl_stream(NULL /*lock*/, ACC_OPENCL_OMP_TID()); + /* determine device-side value of device-memory object by running some kernel */ + assert(NULL != memory && NULL != str && NULL != str->queue); + if (NULL == kernel) { /* generate kernel */ + const char source[] = "kernel void memptr(global unsigned long* ptr) {\n" + " const union { global unsigned long* p; unsigned long u; } cast = { ptr };\n" + " const size_t i = get_global_id(0);\n" + " ptr[i] = cast.u + i;\n" + "}\n"; + assert(sizeof(size_t) == sizeof(cl_ulong)); + result = c_dbcsr_acc_opencl_kernel(0 /*source_is_file*/, source, "memptr" /*kernel_name*/, NULL /*build_params*/, + NULL /*build_options*/, NULL /*try_build_options*/, NULL /*try_ok*/, NULL /*extnames*/, 0 /*num_exts*/, &kernel); } -# endif - result = EXIT_FAILURE; - } + /* TODO: backup/restore memory */ + if (EXIT_SUCCESS == result) result = clSetKernelArg(kernel, 0, sizeof(cl_mem), &memory); + if (EXIT_SUCCESS == result) { + result = clEnqueueNDRangeKernel( + str->queue, kernel, 1 /*work_dim*/, NULL /*offset*/, &size, NULL /*local_work_size*/, 0, NULL, NULL); + } + if (EXIT_SUCCESS == result) { + result = c_dbcsr_acc_opencl_memcpy_d2h(memory, &memptr, 0, sizeof(void*), str->queue, 1 /*blocking*/); + } + assert(EXIT_SUCCESS != result || NULL != memptr); + if (EXIT_SUCCESS == result) { + c_dbcsr_acc_opencl_info_memptr_t* const info = (c_dbcsr_acc_opencl_info_memptr_t*)c_dbcsr_acc_opencl_pmalloc( + NULL /*lock*/, (void**)c_dbcsr_acc_opencl_config.memptrs, &c_dbcsr_acc_opencl_config.nmemptrs); + assert(NULL != memptr); + if (NULL != info) { + info->memory = memory; + info->memptr = memptr; + *dev_mem = memptr; + } + else result = EXIT_FAILURE; + } + ACC_OPENCL_RELEASE(c_dbcsr_acc_opencl_config.lock_memory); +# else + *dev_mem = memptr = memory; # endif + } + if (EXIT_SUCCESS != result) { + if (NULL != memory) ACC_OPENCL_EXPECT(EXIT_SUCCESS == clReleaseMemObject(memory)); + *dev_mem = NULL; + } } - else { - *dev_mem = NULL; /* error: creating device buffer */ + if (0 != c_dbcsr_acc_opencl_config.debug && 0 != c_dbcsr_acc_opencl_config.verbosity && EXIT_SUCCESS == result) { + fprintf(stderr, "INFO ACC/OpenCL: memory=%p pointer=%p size=%llu allocated\n", (const void*)memory, memptr, + (unsigned long long)nbytes); } + assert(EXIT_SUCCESS == result || NULL == *dev_mem); # if defined(__DBCSR_ACC) && defined(ACC_OPENCL_PROFILE) c_dbcsr_timestop(&routine_handle); # endif @@ -251,43 +392,51 @@ int c_dbcsr_acc_dev_mem_deallocate(void* dev_mem) { c_dbcsr_timeset((const char**)&routine_name_ptr, &routine_name_len, &routine_handle); # endif if (NULL != dev_mem) { - const cl_mem buffer = *ACC_OPENCL_MEM(dev_mem); -# if defined(CL_VERSION_2_0) - const int tid = ACC_OPENCL_OMP_TID(); - void* const ptr = (0 != c_dbcsr_acc_opencl_config.device[tid].svm_interop ? c_dbcsr_acc_opencl_get_hostptr(buffer) : NULL); -# endif - ACC_OPENCL_CHECK(clReleaseMemObject(buffer), "release device memory buffer", result); -# if defined(ACC_OPENCL_MEM_NOALLOC) - assert(sizeof(void*) >= sizeof(cl_mem)); + cl_mem memory = NULL; +# if !defined(ACC_OPENCL_MEM_DEVPTR) + memory = (cl_mem)dev_mem; # else -# if LIBXSMM_VERSION4(1, 17, 0, 0) < LIBXSMM_VERSION_NUMBER && defined(ACC_OPENCL_HANDLES_MAXCOUNT) && \ - (0 < ACC_OPENCL_HANDLES_MAXCOUNT) - if (NULL != c_dbcsr_acc_opencl_config.handles) { - /**(cl_mem*)dev_mem = NULL; assert(NULL == *ACC_OPENCL_MEM(dev_mem));*/ - libxsmm_pfree(dev_mem, c_dbcsr_acc_opencl_config.handles, &c_dbcsr_acc_opencl_config.handle); + if (NULL != c_dbcsr_acc_opencl_config.device.clMemFreeINTEL) { + cl_device_id device = NULL; + assert(NULL != c_dbcsr_acc_opencl_config.device.context); + result = clGetContextInfo(c_dbcsr_acc_opencl_config.device.context, CL_CONTEXT_DEVICES, sizeof(cl_device_id), &device, NULL); + if (EXIT_SUCCESS == result) { + result = c_dbcsr_acc_opencl_config.device.clMemFreeINTEL(c_dbcsr_acc_opencl_config.device.context, dev_mem); + } } - else + else { + c_dbcsr_acc_opencl_info_memptr_t* info = NULL; + ACC_OPENCL_ACQUIRE(c_dbcsr_acc_opencl_config.lock_memory); + info = c_dbcsr_acc_opencl_info_devptr_modify(NULL /*lock*/, dev_mem, 1 /*elsize*/, NULL /*amount*/, NULL /*offset*/); + if (NULL != info && info->memptr == dev_mem && NULL != info->memory) { + c_dbcsr_acc_opencl_info_memptr_t* const pfree = c_dbcsr_acc_opencl_config.memptrs[c_dbcsr_acc_opencl_config.nmemptrs]; + memory = info->memory; +# endif + result = clReleaseMemObject(memory); +# if defined(ACC_OPENCL_MEM_DEVPTR) + c_dbcsr_acc_opencl_pfree(NULL /*lock*/, pfree, (void**)c_dbcsr_acc_opencl_config.memptrs, &c_dbcsr_acc_opencl_config.nmemptrs); + *info = *pfree; +# if !defined(NDEBUG) + LIBXSMM_MEMZERO127(pfree); # endif - { - free(dev_mem); - } -# endif -# if defined(CL_VERSION_2_0) - if (0 != c_dbcsr_acc_opencl_config.device[tid].svm_interop /*&& (NULL != ptr)*/) { - assert(NULL != c_dbcsr_acc_opencl_config.device[tid].context); - clSVMFree(c_dbcsr_acc_opencl_config.device[tid].context, ptr); - } -# endif } + else result = EXIT_FAILURE; + ACC_OPENCL_RELEASE(c_dbcsr_acc_opencl_config.lock_memory); +} +# endif +if (0 != c_dbcsr_acc_opencl_config.debug && 0 != c_dbcsr_acc_opencl_config.verbosity && EXIT_SUCCESS == result) { + fprintf(stderr, "INFO ACC/OpenCL: memory=%p pointer=%p deallocated\n", (const void*)memory, dev_mem); +} +} # if defined(__DBCSR_ACC) && defined(ACC_OPENCL_PROFILE) - c_dbcsr_timestop(&routine_handle); +c_dbcsr_timestop(&routine_handle); # endif - ACC_OPENCL_RETURN(result); +ACC_OPENCL_RETURN(result); } -int c_dbcsr_acc_dev_mem_set_ptr(void** dev_mem, void* other, size_t lb) { - int result; +int c_dbcsr_acc_dev_mem_set_ptr(void** dev_mem, void* other, size_t offset) { + int result = EXIT_SUCCESS; # if defined(__DBCSR_ACC) && defined(ACC_OPENCL_PROFILE) int routine_handle; static const char* const routine_name_ptr = LIBXSMM_FUNCNAME; @@ -295,12 +444,12 @@ int c_dbcsr_acc_dev_mem_set_ptr(void** dev_mem, void* other, size_t lb) { c_dbcsr_timeset((const char**)&routine_name_ptr, &routine_name_len, &routine_handle); # endif assert(NULL != dev_mem); - if (NULL != other || 0 == lb) { - *dev_mem = (char*)other + lb; - result = EXIT_SUCCESS; + if (NULL != other || 0 == offset) { + *dev_mem = (char*)other + offset; } else { result = EXIT_FAILURE; + *dev_mem = NULL; } # if defined(__DBCSR_ACC) && defined(ACC_OPENCL_PROFILE) c_dbcsr_timestop(&routine_handle); @@ -317,10 +466,38 @@ int c_dbcsr_acc_memcpy_h2d(const void* host_mem, void* dev_mem, size_t nbytes, v static const int routine_name_len = (int)sizeof(LIBXSMM_FUNCNAME) - 1; c_dbcsr_timeset((const char**)&routine_name_ptr, &routine_name_len, &routine_handle); # endif - assert((NULL != host_mem || 0 == nbytes) && (NULL != dev_mem || 0 == nbytes) && NULL != stream); + assert((NULL != host_mem && NULL != dev_mem) || 0 == nbytes); if (NULL != host_mem && NULL != dev_mem && 0 != nbytes) { - result = clEnqueueWriteBuffer(*ACC_OPENCL_STREAM(stream), *ACC_OPENCL_MEM(dev_mem), 0 == (1 & c_dbcsr_acc_opencl_config.async), - 0 /*offset*/, nbytes, host_mem, 0, NULL, NULL); + const c_dbcsr_acc_opencl_stream_t* const str = + (NULL != stream ? ACC_OPENCL_STREAM(stream) : c_dbcsr_acc_opencl_stream(NULL /*lock*/, ACC_OPENCL_OMP_TID())); +# if defined(ACC_OPENCL_ASYNC) + const cl_bool finish = (0 == (1 & c_dbcsr_acc_opencl_config.async) || NULL == stream || + (0 != c_dbcsr_acc_opencl_config.device.nv && NULL == (ACC_OPENCL_ASYNC))); +# else + const cl_bool finish = CL_TRUE; +# endif + assert(NULL != str && NULL != str->queue); +# if defined(ACC_OPENCL_MEM_DEVPTR) + if (NULL != c_dbcsr_acc_opencl_config.device.clEnqueueMemcpyINTEL) { + result = c_dbcsr_acc_opencl_config.device.clEnqueueMemcpyINTEL(str->queue, finish, dev_mem, host_mem, nbytes, 0, NULL, NULL); + } + else +# endif + { + c_dbcsr_acc_opencl_info_memptr_t info; + size_t offset = 0; +# if defined(ACC_OPENCL_MEM_DEVPTR) + ACC_OPENCL_ACQUIRE(c_dbcsr_acc_opencl_config.lock_memory); +# endif + result = c_dbcsr_acc_opencl_info_devptr_lock(&info, NULL /*lock*/, dev_mem, 1 /*elsize*/, &nbytes, &offset); + if (EXIT_SUCCESS == result) { + assert(NULL != info.memory); + result = clEnqueueWriteBuffer(str->queue, info.memory, finish, offset, nbytes, host_mem, 0, NULL, NULL); + } +# if defined(ACC_OPENCL_MEM_DEVPTR) + ACC_OPENCL_RELEASE(c_dbcsr_acc_opencl_config.lock_memory); +# endif + } } # if defined(__DBCSR_ACC) && defined(ACC_OPENCL_PROFILE) c_dbcsr_timestop(&routine_handle); @@ -337,20 +514,25 @@ int c_dbcsr_acc_memcpy_d2h(const void* dev_mem, void* host_mem, size_t nbytes, v static const int routine_name_len = (int)sizeof(LIBXSMM_FUNCNAME) - 1; c_dbcsr_timeset((const char**)&routine_name_ptr, &routine_name_len, &routine_handle); # endif - assert((NULL != dev_mem || 0 == nbytes) && (NULL != host_mem || 0 == nbytes) && NULL != stream); + assert((NULL != dev_mem && NULL != host_mem) || 0 == nbytes); if (NULL != host_mem && NULL != dev_mem && 0 != nbytes) { - const cl_command_queue queue = *ACC_OPENCL_STREAM(stream); - result = clEnqueueReadBuffer( - queue, *ACC_OPENCL_MEM(dev_mem), 0 == (2 & c_dbcsr_acc_opencl_config.async), 0 /*offset*/, nbytes, host_mem, 0, NULL, NULL); - if (CL_SUCCESS != result) { - const int result_sync = clEnqueueReadBuffer( - queue, *ACC_OPENCL_MEM(dev_mem), CL_TRUE, 0 /*offset*/, nbytes, host_mem, 0, NULL, NULL); - c_dbcsr_acc_opencl_config.async |= 2; /* retract feature */ - if (0 != c_dbcsr_acc_opencl_config.verbosity) { - fprintf(stderr, "WARN ACC/OpenCL: falling back to synchronous readback (code=%i).\n", result); - } - result = result_sync; + const c_dbcsr_acc_opencl_stream_t* const str = + (NULL != stream ? ACC_OPENCL_STREAM(stream) : c_dbcsr_acc_opencl_stream(NULL /*lock*/, ACC_OPENCL_OMP_TID())); + const cl_bool finish = (NULL != stream ? CL_FALSE : CL_TRUE); + c_dbcsr_acc_opencl_info_memptr_t info; + size_t offset = 0; + assert(NULL != str && NULL != str->queue); +# if defined(ACC_OPENCL_MEM_DEVPTR) + ACC_OPENCL_ACQUIRE(c_dbcsr_acc_opencl_config.lock_memory); +# endif + result = c_dbcsr_acc_opencl_info_devptr_lock(&info, NULL /*lock*/, dev_mem, 1 /*elsize*/, &nbytes, &offset); + if (EXIT_SUCCESS == result) { + assert(NULL != info.memory); + result = c_dbcsr_acc_opencl_memcpy_d2h(info.memory, host_mem, offset, nbytes, str->queue, finish); } +# if defined(ACC_OPENCL_MEM_DEVPTR) + ACC_OPENCL_RELEASE(c_dbcsr_acc_opencl_config.lock_memory); +# endif } # if defined(__DBCSR_ACC) && defined(ACC_OPENCL_PROFILE) c_dbcsr_timestop(&routine_handle); @@ -367,38 +549,36 @@ int c_dbcsr_acc_memcpy_d2d(const void* devmem_src, void* devmem_dst, size_t nbyt static const int routine_name_len = (int)sizeof(LIBXSMM_FUNCNAME) - 1; c_dbcsr_timeset((const char**)&routine_name_ptr, &routine_name_len, &routine_handle); # endif - assert((NULL != devmem_src || 0 == nbytes) && (NULL != devmem_dst || 0 == nbytes) && NULL != stream); + assert((NULL != devmem_src && NULL != devmem_dst) || 0 == nbytes); if (NULL != devmem_src && NULL != devmem_dst && 0 != nbytes) { - const cl_mem *const src = ACC_OPENCL_MEM(devmem_src), *const dst = ACC_OPENCL_MEM(devmem_dst); - assert(NULL != *src && NULL != *dst); - if (*src != *dst) { - const cl_command_queue queue = *ACC_OPENCL_STREAM(stream); - if (0 == (2 & c_dbcsr_acc_opencl_config.devcopy)) { - result = clEnqueueCopyBuffer(queue, *src, *dst, 0 /*src_offset*/, 0 /*dst_offset*/, nbytes, 0, NULL, NULL); - } - else { - static volatile int lock; /* creating cl_kernel and clSetKernelArg must be synchronized */ - static cl_kernel kernel = NULL; - LIBXSMM_ATOMIC_ACQUIRE(&lock, LIBXSMM_SYNC_NPAUSE, LIBXSMM_ATOMIC_RELAXED); - if (NULL == kernel) { /* generate kernel */ - const char source[] = "kernel void memcpy_d2d(global uchar *restrict src, global uchar *restrict dst) {\n" - " const size_t i = get_global_id(0);\n" - " dst[i] = src[i];\n" - "}\n"; - result = c_dbcsr_acc_opencl_kernel(0 /*source_is_file*/, source, "memcpy_d2d" /*kernel_name*/, NULL /*build_params*/, - NULL /*build_options*/, NULL /*try_build_options*/, NULL /*try_ok*/, NULL /*extnames*/, 0 /*num_exts*/, &kernel); - } - if (EXIT_SUCCESS == result) { - assert(NULL != kernel); - ACC_OPENCL_CHECK(clSetKernelArg(kernel, 0, sizeof(cl_mem), src), "set src argument of memcpy_d2d kernel", result); - ACC_OPENCL_CHECK(clSetKernelArg(kernel, 1, sizeof(cl_mem), dst), "set dst argument of memcpy_d2d kernel", result); - ACC_OPENCL_CHECK(clEnqueueNDRangeKernel( - queue, kernel, 1 /*work_dim*/, NULL /*offset*/, &nbytes, NULL /*local_work_size*/, 0, NULL, NULL), - "launch memcpy_d2d kernel", result); - } - LIBXSMM_ATOMIC_RELEASE(&lock, LIBXSMM_ATOMIC_RELAXED); + const c_dbcsr_acc_opencl_stream_t* const str = + (NULL != stream ? ACC_OPENCL_STREAM(stream) : c_dbcsr_acc_opencl_stream(NULL /*lock*/, ACC_OPENCL_OMP_TID())); + cl_event event = NULL; + assert(NULL != str && NULL != str->queue); +# if defined(ACC_OPENCL_MEM_DEVPTR) + if (NULL != c_dbcsr_acc_opencl_config.device.clEnqueueMemcpyINTEL) { + result = c_dbcsr_acc_opencl_config.device.clEnqueueMemcpyINTEL( + str->queue, CL_FALSE /*blocking*/, devmem_dst, devmem_src, nbytes, 0, NULL, &event); + } + else +# endif + { + c_dbcsr_acc_opencl_info_memptr_t info_src, info_dst; + size_t offset_src = 0, offset_dst = 0; +# if defined(ACC_OPENCL_MEM_DEVPTR) + ACC_OPENCL_ACQUIRE(c_dbcsr_acc_opencl_config.lock_memory); +# endif + result |= c_dbcsr_acc_opencl_info_devptr_lock(&info_src, NULL /*lock*/, devmem_src, 1 /*elsize*/, &nbytes, &offset_src); + result |= c_dbcsr_acc_opencl_info_devptr_lock(&info_dst, NULL /*lock*/, devmem_dst, 1 /*elsize*/, &nbytes, &offset_dst); + if (EXIT_SUCCESS == result) { + assert(NULL != info_src.memory && NULL != info_dst.memory); + result = clEnqueueCopyBuffer(str->queue, info_src.memory, info_dst.memory, offset_src, offset_dst, nbytes, 0, NULL, &event); } +# if defined(ACC_OPENCL_MEM_DEVPTR) + ACC_OPENCL_RELEASE(c_dbcsr_acc_opencl_config.lock_memory); +# endif } + if (NULL == stream && EXIT_SUCCESS == result) result = clWaitForEvents(1, &event); } # if defined(__DBCSR_ACC) && defined(ACC_OPENCL_PROFILE) c_dbcsr_timestop(&routine_handle); @@ -407,7 +587,7 @@ int c_dbcsr_acc_memcpy_d2d(const void* devmem_src, void* devmem_dst, size_t nbyt } -int c_dbcsr_acc_memset_zero(void* dev_mem, size_t offset, size_t nbytes, void* stream) { +int c_dbcsr_acc_opencl_memset(void* dev_mem, int value, size_t offset, size_t nbytes, void* stream) { int result = EXIT_SUCCESS; # if defined(__DBCSR_ACC) && defined(ACC_OPENCL_PROFILE) int routine_handle; @@ -415,36 +595,44 @@ int c_dbcsr_acc_memset_zero(void* dev_mem, size_t offset, size_t nbytes, void* s static const int routine_name_len = (int)sizeof(LIBXSMM_FUNCNAME) - 1; c_dbcsr_timeset((const char**)&routine_name_ptr, &routine_name_len, &routine_handle); # endif - assert((NULL != dev_mem || 0 == nbytes) && NULL != stream); + assert(NULL != dev_mem || 0 == nbytes); if (0 != nbytes) { - const cl_command_queue queue = *ACC_OPENCL_STREAM(stream); - const cl_mem* const buffer = ACC_OPENCL_MEM(dev_mem); - if (0 == (1 & c_dbcsr_acc_opencl_config.devcopy)) { - static const cl_uchar pattern = 0; /* fill with zeros */ - result = clEnqueueFillBuffer(queue, *buffer, &pattern, sizeof(pattern), offset, nbytes, 0, NULL, NULL); - } - else { - static volatile int lock; /* creating cl_kernel and clSetKernelArg must be synchronized */ - static cl_kernel kernel = NULL; - LIBXSMM_ATOMIC_ACQUIRE(&lock, LIBXSMM_SYNC_NPAUSE, LIBXSMM_ATOMIC_RELAXED); - if (NULL == kernel) { /* generate kernel */ - const char source[] = "kernel void memset_zero(global uchar *restrict buffer) {\n" - " const size_t i = get_global_id(0);\n" - " const uchar pattern = 0;\n" - " buffer[i] = pattern;\n" - "}\n"; - result = c_dbcsr_acc_opencl_kernel(0 /*source_is_file*/, source, "memset_zero" /*kernel_name*/, NULL /*build_params*/, - NULL /*build_options*/, NULL /*try_build_options*/, NULL /*try_ok*/, NULL /*extnames*/, 0 /*num_exts*/, &kernel); + const c_dbcsr_acc_opencl_stream_t* const str = + (NULL != stream ? ACC_OPENCL_STREAM(stream) : c_dbcsr_acc_opencl_stream(NULL /*lock*/, ACC_OPENCL_OMP_TID())); + size_t size_of_value = 1; + cl_event event; + if (0 == LIBXSMM_MOD2(nbytes, 4)) size_of_value = 4; + else if (0 == LIBXSMM_MOD2(nbytes, 2)) size_of_value = 2; + assert(NULL != str && NULL != str->queue); +# if defined(ACC_OPENCL_MEM_DEVPTR) + if (NULL != c_dbcsr_acc_opencl_config.device.clEnqueueMemFillINTEL) { + cl_device_id device = NULL; + assert(NULL != c_dbcsr_acc_opencl_config.device.context); + result = clGetContextInfo(c_dbcsr_acc_opencl_config.device.context, CL_CONTEXT_DEVICES, sizeof(cl_device_id), &device, NULL); + if (EXIT_SUCCESS == result) { + result = c_dbcsr_acc_opencl_config.device.clEnqueueMemFillINTEL( + str->queue, (char*)dev_mem + offset, &value, size_of_value, nbytes, 0, NULL, &event); } + } + else +# endif + { + size_t offset_info = 0; + c_dbcsr_acc_opencl_info_memptr_t info; +# if defined(ACC_OPENCL_MEM_DEVPTR) + ACC_OPENCL_ACQUIRE(c_dbcsr_acc_opencl_config.lock_memory); +# endif + result = c_dbcsr_acc_opencl_info_devptr_lock(&info, NULL /*lock*/, dev_mem, 1 /*elsize*/, &nbytes, &offset_info); if (EXIT_SUCCESS == result) { - assert(NULL != kernel); - ACC_OPENCL_CHECK(clSetKernelArg(kernel, 0, sizeof(cl_mem), buffer), "set buffer argument of memset_zero kernel", result); - ACC_OPENCL_CHECK( - clEnqueueNDRangeKernel(queue, kernel, 1 /*work_dim*/, &offset, &nbytes, NULL /*local_work_size*/, 0, NULL, NULL), - "launch memset_zero kernel", result); + assert(NULL != info.memory); + offset_info += offset; + result = clEnqueueFillBuffer(str->queue, info.memory, &value, size_of_value, offset_info, nbytes, 0, NULL, &event); } - LIBXSMM_ATOMIC_RELEASE(&lock, LIBXSMM_ATOMIC_RELAXED); +# if defined(ACC_OPENCL_MEM_DEVPTR) + ACC_OPENCL_RELEASE(c_dbcsr_acc_opencl_config.lock_memory); +# endif } + if (NULL == stream && EXIT_SUCCESS == result) result = clWaitForEvents(1, &event); } # if defined(__DBCSR_ACC) && defined(ACC_OPENCL_PROFILE) c_dbcsr_timestop(&routine_handle); @@ -453,6 +641,11 @@ int c_dbcsr_acc_memset_zero(void* dev_mem, size_t offset, size_t nbytes, void* s } +int c_dbcsr_acc_memset_zero(void* dev_mem, size_t offset, size_t nbytes, void* stream) { + return c_dbcsr_acc_opencl_memset(dev_mem, 0 /*value*/, offset, nbytes, stream); +} + + int c_dbcsr_acc_opencl_info_devmem(cl_device_id device, size_t* mem_free, size_t* mem_total, size_t* mem_local, int* mem_unified) { int result = EXIT_SUCCESS, unified = 0; size_t size_free = 0, size_total = 0, size_local = 0; @@ -465,35 +658,35 @@ int c_dbcsr_acc_opencl_info_devmem(cl_device_id device, size_t* mem_free, size_t } # else # if defined(_SC_PAGE_SIZE) - const long page_size = sysconf(_SC_PAGE_SIZE); + const long page_size = sysconf(_SC_PAGE_SIZE); # else - const long page_size = 4096; + const long page_size = 4096; # endif - long pages_free = 0, pages_total = 0; + long pages_free = 0, pages_total = 0; # if defined(__linux__) # if defined(_SC_PHYS_PAGES) - pages_total = sysconf(_SC_PHYS_PAGES); + pages_total = sysconf(_SC_PHYS_PAGES); # else - pages_total = 0; + pages_total = 0; # endif # if defined(_SC_AVPHYS_PAGES) - pages_free = sysconf(_SC_AVPHYS_PAGES); + pages_free = sysconf(_SC_AVPHYS_PAGES); # else - pages_free = pages_total; + pages_free = pages_total; # endif # elif defined(__APPLE__) && defined(__MACH__) - /*const*/ size_t size_pages_free = sizeof(const long), size_pages_total = sizeof(const long); - ACC_OPENCL_EXPECT(0 == sysctlbyname("hw.memsize", &pages_total, &size_pages_total, NULL, 0)); - if (0 < page_size) pages_total /= page_size; - if (0 != sysctlbyname("vm.page_free_count", &pages_free, &size_pages_free, NULL, 0)) { - pages_free = pages_total; - } + /*const*/ size_t size_pages_free = sizeof(const long), size_pages_total = sizeof(const long); + ACC_OPENCL_EXPECT(0 == sysctlbyname("hw.memsize", &pages_total, &size_pages_total, NULL, 0)); + if (0 < page_size) pages_total /= page_size; + if (0 != sysctlbyname("vm.page_free_count", &pages_free, &size_pages_free, NULL, 0)) { + pages_free = pages_total; + } # endif - if (0 < page_size && 0 <= pages_free && 0 <= pages_total) { - const size_t size_page = (size_t)page_size; - size_total = size_page * (size_t)pages_total; - size_free = size_page * (size_t)pages_free; - } + if (0 < page_size && 0 <= pages_free && 0 <= pages_total) { + const size_t size_page = (size_t)page_size; + size_total = size_page * (size_t)pages_total; + size_free = size_page * (size_t)pages_free; + } # endif if (NULL != device) { cl_device_local_mem_type cl_local_type = CL_GLOBAL; @@ -527,8 +720,10 @@ int c_dbcsr_acc_opencl_info_devmem(cl_device_id device, size_t* mem_free, size_t int c_dbcsr_acc_dev_mem_info(size_t* mem_free, size_t* mem_total) { - cl_device_id active_id = NULL; - int result = 0 < c_dbcsr_acc_opencl_config.ndevices ? c_dbcsr_acc_opencl_device(ACC_OPENCL_OMP_TID(), &active_id) : EXIT_FAILURE; + cl_device_id device = NULL; + int result = (0 < c_dbcsr_acc_opencl_config.ndevices ? clGetContextInfo(c_dbcsr_acc_opencl_config.device.context, + CL_CONTEXT_DEVICES, sizeof(cl_device_id), &device, NULL) + : EXIT_FAILURE); # if defined(__DBCSR_ACC) && defined(ACC_OPENCL_PROFILE) int routine_handle; static const char* const routine_name_ptr = LIBXSMM_FUNCNAME; @@ -536,7 +731,7 @@ int c_dbcsr_acc_dev_mem_info(size_t* mem_free, size_t* mem_total) { c_dbcsr_timeset((const char**)&routine_name_ptr, &routine_name_len, &routine_handle); # endif if (EXIT_SUCCESS == result) { - result = c_dbcsr_acc_opencl_info_devmem(active_id, mem_free, mem_total, NULL /*mem_local*/, NULL /*mem_unified*/); + result = c_dbcsr_acc_opencl_info_devmem(device, mem_free, mem_total, NULL /*mem_local*/, NULL /*mem_unified*/); } # if defined(__DBCSR_ACC) && defined(ACC_OPENCL_PROFILE) c_dbcsr_timestop(&routine_handle); diff --git a/src/acc/opencl/acc_opencl_stream.c b/src/acc/opencl/acc_opencl_stream.c index a5f6c7f6920..11d3159473c 100644 --- a/src/acc/opencl/acc_opencl_stream.c +++ b/src/acc/opencl/acc_opencl_stream.c @@ -10,15 +10,6 @@ # include "acc_opencl.h" # include -# if defined(CL_VERSION_2_0) -# define ACC_OPENCL_STREAM_PROPERTIES_TYPE cl_queue_properties -# define ACC_OPENCL_CREATE_COMMAND_QUEUE(CTX, DEV, PROPS, RESULT) clCreateCommandQueueWithProperties(CTX, DEV, PROPS, RESULT) -# else -# define ACC_OPENCL_STREAM_PROPERTIES_TYPE cl_int -# define ACC_OPENCL_CREATE_COMMAND_QUEUE(CTX, DEV, PROPS, RESULT) \ - clCreateCommandQueue(CTX, DEV, (cl_command_queue_properties)(NULL != (PROPS) ? ((PROPS)[1]) : 0), RESULT) -# endif - # if defined(__cplusplus) extern "C" { @@ -28,25 +19,38 @@ int c_dbcsr_acc_opencl_stream_counter_base; int c_dbcsr_acc_opencl_stream_counter; -c_dbcsr_acc_opencl_info_stream_t* c_dbcsr_acc_opencl_info_stream(void* stream) { - assert(NULL == stream || sizeof(c_dbcsr_acc_opencl_info_stream_t) <= (uintptr_t)stream); - return ( - NULL != stream ? ((c_dbcsr_acc_opencl_info_stream_t*)((uintptr_t)stream - sizeof(c_dbcsr_acc_opencl_info_stream_t))) : NULL); +const c_dbcsr_acc_opencl_stream_t* c_dbcsr_acc_opencl_stream(ACC_OPENCL_LOCKTYPE* lock, int thread_id) { + const c_dbcsr_acc_opencl_stream_t *result = NULL, *result_main = NULL; + const size_t n = ACC_OPENCL_MAXNITEMS * c_dbcsr_acc_opencl_config.nthreads; + size_t i; + assert(NULL != c_dbcsr_acc_opencl_config.streams); + assert(thread_id < c_dbcsr_acc_opencl_config.nthreads); + if (NULL != lock) ACC_OPENCL_ACQUIRE(lock); + for (i = c_dbcsr_acc_opencl_config.nstreams; i < n; ++i) { + const c_dbcsr_acc_opencl_stream_t* const str = c_dbcsr_acc_opencl_config.streams[i]; + if (NULL != str && NULL != str->queue) { + if (str->tid == thread_id || 0 > thread_id) { /* hit */ + result = str; + break; + } + else if (NULL == result_main && 0 == str->tid) { + result_main = str; + } + } + else break; /* error */ + } + if (NULL == result) { /* fallback */ + result = (NULL != result_main ? result_main : &c_dbcsr_acc_opencl_config.device.stream); + } + if (NULL != lock) ACC_OPENCL_RELEASE(lock); + return result; } -const int* c_dbcsr_acc_opencl_stream_priority(const void* stream) { - const int* result; -# if !defined(ACC_OPENCL_STREAM_PRIORITIES) - LIBXSMM_UNUSED(stream); -# else - const c_dbcsr_acc_opencl_info_stream_t* const info = c_dbcsr_acc_opencl_info_stream((void*)stream); - if (NULL != info) { - result = &info->priority; - } - else -# endif - result = NULL; +const c_dbcsr_acc_opencl_stream_t* c_dbcsr_acc_opencl_stream_default(void) { + const c_dbcsr_acc_opencl_stream_t* result = NULL; + result = c_dbcsr_acc_opencl_stream(c_dbcsr_acc_opencl_config.lock_stream, ACC_OPENCL_OMP_TID()); + assert(NULL != result); return result; } @@ -55,10 +59,8 @@ int c_dbcsr_acc_stream_create(void** stream_p, const char* name, int priority) { ACC_OPENCL_STREAM_PROPERTIES_TYPE properties[8] = { CL_QUEUE_PROPERTIES, 0 /*placeholder*/, 0 /* terminator */ }; - int result, i, tid = 0, offset = 0; + int result, tid = 0, offset = 0; cl_command_queue queue = NULL; - cl_context context = NULL; - void** streams = NULL; # if defined(__DBCSR_ACC) && defined(ACC_OPENCL_PROFILE) int routine_handle; static const char* const routine_name_ptr = LIBXSMM_FUNCNAME; @@ -92,151 +94,74 @@ int c_dbcsr_acc_stream_create(void** stream_p, const char* name, int priority) { properties[4] = 0; /* terminator */ } # endif + ACC_OPENCL_ACQUIRE(c_dbcsr_acc_opencl_config.lock_stream); # if defined(_OPENMP) if (1 < omp_get_num_threads()) { + const int i = c_dbcsr_acc_opencl_stream_counter++; assert(0 < c_dbcsr_acc_opencl_config.nthreads); -# if (201107 /*v3.1*/ <= _OPENMP) -# pragma omp atomic capture -# else -# pragma omp critical(c_dbcsr_acc_opencl_stream) -# endif - i = c_dbcsr_acc_opencl_stream_counter++; tid = (i < c_dbcsr_acc_opencl_config.nthreads ? i : (i % c_dbcsr_acc_opencl_config.nthreads)); - if (NULL != c_dbcsr_acc_opencl_config.device) { /* inherit master's context if current context is NULL */ - LIBXSMM_ATOMIC_CMPSWP(&c_dbcsr_acc_opencl_config.device[tid].context, NULL, - c_dbcsr_acc_opencl_config.device[/*main*/ 0].context, LIBXSMM_ATOMIC_RELAXED); - } } else offset = c_dbcsr_acc_opencl_stream_counter_base++; # endif - if (NULL != c_dbcsr_acc_opencl_config.device) context = c_dbcsr_acc_opencl_config.device[tid].context; - if (NULL != context) { + if (NULL != c_dbcsr_acc_opencl_config.device.context) { cl_device_id device = NULL; - result = clGetContextInfo(context, CL_CONTEXT_DEVICES, sizeof(cl_device_id), &device, NULL); - if (CL_SUCCESS == result) { - const int s = c_dbcsr_acc_opencl_config.share; - if (0 == s || 0 == (tid % s)) { - if (0 != c_dbcsr_acc_opencl_config.device[tid].intel) { - const int xhints = ((1 == c_dbcsr_acc_opencl_config.xhints || 0 > c_dbcsr_acc_opencl_config.xhints) - ? (0 != c_dbcsr_acc_opencl_config.device[tid].intel ? 1 : 0) - : (c_dbcsr_acc_opencl_config.xhints >> 1)); - if (0 != (1 & xhints)) { /* attempt to enable command aggregation */ - const ACC_OPENCL_STREAM_PROPERTIES_TYPE props[4] = { - CL_QUEUE_PROPERTIES, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, 0 /* terminator */ - }; - const cl_command_queue q = ACC_OPENCL_CREATE_COMMAND_QUEUE(context, device, props, &result); - if (CL_SUCCESS == result) { - c_dbcsr_acc_opencl_config.timer = c_dbcsr_acc_opencl_timer_host; /* force host-timer */ - clReleaseCommandQueue(q); - } - else result = CL_SUCCESS; - } - if (0 != (2 & xhints)) { /* attempt to enable queue families */ - struct { - cl_command_queue_properties properties; - cl_bitfield capabilities; - cl_uint count; - char name[64 /*CL_QUEUE_FAMILY_MAX_NAME_SIZE_INTEL*/]; - } intel_qfprops[16]; - size_t nbytes = 0, i; - if (CL_SUCCESS == clGetDeviceInfo(device, 0x418B /*CL_DEVICE_QUEUE_FAMILY_PROPERTIES_INTEL*/, sizeof(intel_qfprops), - intel_qfprops, &nbytes)) - { - for (i = 0; (i * sizeof(*intel_qfprops)) < nbytes; ++i) { - if (0 /*CL_QUEUE_DEFAULT_CAPABILITIES_INTEL*/ == intel_qfprops[i].capabilities && 1 < intel_qfprops[i].count) { - const int j = (0 /*terminator*/ == properties[2] ? 2 : 4); - properties[j + 0] = 0x418C; /* CL_QUEUE_FAMILY_INTEL */ - properties[j + 1] = (int)i; - properties[j + 2] = 0x418D; /* CL_QUEUE_INDEX_INTEL */ - properties[j + 3] = (i + offset) % intel_qfprops[i].count; - properties[j + 4] = 0; /* terminator */ - break; - } - } - } - } - } - if ((c_dbcsr_acc_opencl_timer_device == c_dbcsr_acc_opencl_config.timer) && - (3 <= c_dbcsr_acc_opencl_config.verbosity || 0 > c_dbcsr_acc_opencl_config.verbosity)) + result = clGetContextInfo(c_dbcsr_acc_opencl_config.device.context, CL_CONTEXT_DEVICES, sizeof(cl_device_id), &device, NULL); + if (EXIT_SUCCESS == result) { + if (0 != (2 & c_dbcsr_acc_opencl_config.xhints) && 0 != c_dbcsr_acc_opencl_config.device.intel) { /* enable queue families */ + struct { + cl_command_queue_properties properties; + cl_bitfield capabilities; + cl_uint count; + char name[64 /*CL_QUEUE_FAMILY_MAX_NAME_SIZE_INTEL*/]; + } intel_qfprops[16]; + size_t nbytes = 0, i; + if (EXIT_SUCCESS == clGetDeviceInfo(device, 0x418B /*CL_DEVICE_QUEUE_FAMILY_PROPERTIES_INTEL*/, sizeof(intel_qfprops), + intel_qfprops, &nbytes)) { - properties[1] = CL_QUEUE_PROFILING_ENABLE; - } - queue = ACC_OPENCL_CREATE_COMMAND_QUEUE(context, device, properties, &result); - } - else { /* attempt to share existing stream */ - const int maxn = c_dbcsr_acc_opencl_config.nthreads; - cl_command_queue stream = NULL; - assert(0 < tid); - for (i = 0; i < maxn; ++i) { - int j = i + tid - 1, t = (j < maxn ? j : (j - maxn)); - if (0 < t && t != tid) { /* avoid cloning master's and own streams */ - streams = c_dbcsr_acc_opencl_config.streams + ACC_OPENCL_STREAMS_MAXCOUNT * t; - for (j = 0; j < ACC_OPENCL_STREAMS_MAXCOUNT; ++j) { - if (NULL != streams[j]) { - stream = *ACC_OPENCL_STREAM(streams[j]); - i = maxn; /* break outer loop */ - break; - } - } - } - } - if (NULL != stream) { /* clone existing stream */ - result = clRetainCommandQueue(stream); - } - else { - for (i = 0; i < ACC_OPENCL_STREAMS_MAXCOUNT; ++i) { /* adopt master's stream created last */ - if (NULL != c_dbcsr_acc_opencl_config.streams[i]) { - stream = *ACC_OPENCL_STREAM(c_dbcsr_acc_opencl_config.streams[i]); - result = clRetainCommandQueue(stream); + for (i = 0; (i * sizeof(*intel_qfprops)) < nbytes; ++i) { + if (0 /*CL_QUEUE_DEFAULT_CAPABILITIES_INTEL*/ == intel_qfprops[i].capabilities && 1 < intel_qfprops[i].count) { + const int j = (0 /*terminator*/ == properties[2] ? 2 : 4); + properties[j + 0] = 0x418C; /* CL_QUEUE_FAMILY_INTEL */ + properties[j + 1] = (int)i; + properties[j + 2] = 0x418D; /* CL_QUEUE_INDEX_INTEL */ + properties[j + 3] = (i + offset) % intel_qfprops[i].count; + properties[j + 4] = 0; /* terminator */ + break; } - else break; } } - if (EXIT_SUCCESS == result) queue = stream; } + if ((c_dbcsr_acc_opencl_timer_device == c_dbcsr_acc_opencl_config.timer) && + (3 <= c_dbcsr_acc_opencl_config.verbosity || 0 > c_dbcsr_acc_opencl_config.verbosity)) + { + properties[1] = CL_QUEUE_PROFILING_ENABLE; + } + queue = ACC_OPENCL_CREATE_COMMAND_QUEUE(c_dbcsr_acc_opencl_config.device.context, device, properties, &result); } } else { result = EXIT_FAILURE; } - if (EXIT_SUCCESS == result) { - const int base = ACC_OPENCL_STREAMS_MAXCOUNT * tid; - cl_command_queue* const stats = c_dbcsr_acc_opencl_config.stats + base; - streams = c_dbcsr_acc_opencl_config.streams + base; - for (i = 0; i < ACC_OPENCL_STREAMS_MAXCOUNT; ++i) { - if (NULL == streams[i]) break; - } - if (i < ACC_OPENCL_STREAMS_MAXCOUNT) { /* register stream */ - const size_t size_info = sizeof(c_dbcsr_acc_opencl_info_stream_t); - const size_t size = sizeof(cl_command_queue) + sizeof(void*) + size_info - 1; - void* const handle = malloc(size); - assert(NULL != queue); - if (NULL != handle) { - const uintptr_t address = (uintptr_t)handle; - const uintptr_t aligned = LIBXSMM_UP2(address + size_info, sizeof(void*)); - c_dbcsr_acc_opencl_info_stream_t* const info = (c_dbcsr_acc_opencl_info_stream_t*)(aligned - size_info); - assert(address + size_info <= aligned && NULL != info); - info->pointer = (void*)address; - info->priority = priority; - info->tid = tid; - stats[i] = *(cl_command_queue*)aligned = queue; - streams[i] = *stream_p = (void*)aligned; - assert(queue == *ACC_OPENCL_STREAM(streams[i])); - assert(queue == *ACC_OPENCL_STREAM(*stream_p)); - } - else { - clReleaseCommandQueue(queue); - result = EXIT_FAILURE; - *stream_p = NULL; - } - } - else { - clReleaseCommandQueue(queue); - result = EXIT_FAILURE; - *stream_p = NULL; + if (EXIT_SUCCESS == result) { /* register stream */ + assert(NULL != c_dbcsr_acc_opencl_config.streams && NULL != queue); + *stream_p = c_dbcsr_acc_opencl_pmalloc( + NULL /*lock*/, (void**)c_dbcsr_acc_opencl_config.streams, &c_dbcsr_acc_opencl_config.nstreams); + if (NULL != *stream_p) { + c_dbcsr_acc_opencl_stream_t* const str = (c_dbcsr_acc_opencl_stream_t*)*stream_p; +# if !defined(NDEBUG) + LIBXSMM_MEMZERO127(str); +# endif + str->queue = queue; + str->tid = tid; +# if defined(ACC_OPENCL_STREAM_PRIORITIES) + str->priority = priority; +# endif } + else result = EXIT_FAILURE; } - else { + ACC_OPENCL_RELEASE(c_dbcsr_acc_opencl_config.lock_stream); + if (EXIT_SUCCESS != result && NULL != queue) { + clReleaseCommandQueue(queue); *stream_p = NULL; } # if defined(__DBCSR_ACC) && defined(ACC_OPENCL_PROFILE) @@ -253,43 +178,20 @@ int c_dbcsr_acc_stream_destroy(void* stream) { static const char* const routine_name_ptr = LIBXSMM_FUNCNAME; static const int routine_name_len = (int)sizeof(LIBXSMM_FUNCNAME) - 1; c_dbcsr_timeset((const char**)&routine_name_ptr, &routine_name_len, &routine_handle); -# endif -# if defined(_OPENMP) -# pragma omp critical(c_dbcsr_acc_opencl_stream) # endif if (NULL != stream) { - const cl_command_queue queue = *ACC_OPENCL_STREAM(stream); + const c_dbcsr_acc_opencl_stream_t* const str = ACC_OPENCL_STREAM(stream); + const cl_command_queue queue = str->queue; assert(NULL != c_dbcsr_acc_opencl_config.streams); + ACC_OPENCL_ACQUIRE(c_dbcsr_acc_opencl_config.lock_stream); + c_dbcsr_acc_opencl_pfree(NULL /*lock*/, stream, (void**)c_dbcsr_acc_opencl_config.streams, &c_dbcsr_acc_opencl_config.nstreams); if (NULL != queue) { - int tid = 0, i = ACC_OPENCL_STREAMS_MAXCOUNT; - void** streams = NULL; - for (; tid < c_dbcsr_acc_opencl_config.nthreads; ++tid) { /* unregister */ - streams = c_dbcsr_acc_opencl_config.streams + ACC_OPENCL_STREAMS_MAXCOUNT * tid; - for (i = 0; i < ACC_OPENCL_STREAMS_MAXCOUNT; ++i) { - if (stream == streams[i]) { - const int j = i + 1, result_release = clReleaseCommandQueue(queue); /* soft-error */ - if (j < ACC_OPENCL_STREAMS_MAXCOUNT && NULL != streams[j]) { /* compacting streams is not thread-safe */ - memmove(streams + i, streams + j, sizeof(void*) * (ACC_OPENCL_STREAMS_MAXCOUNT - j)); - } - streams[ACC_OPENCL_STREAMS_MAXCOUNT - j] = NULL; - /* consider breaking outer loop */ - if (0 == c_dbcsr_acc_opencl_config.share) { - tid = c_dbcsr_acc_opencl_config.nthreads; - result = result_release; /* promote */ - } - else if (EXIT_SUCCESS != result_release) { - tid = c_dbcsr_acc_opencl_config.nthreads; - } - break; - } - else if (NULL == streams[i]) { /* compact streams */ - break; - } - } - } + result = clReleaseCommandQueue(queue); +# if !defined(NDEBUG) + LIBXSMM_MEMZERO127((c_dbcsr_acc_opencl_stream_t*)stream); +# endif } - c_dbcsr_acc_opencl_stream_counter_base = c_dbcsr_acc_opencl_stream_counter = 0; /* reset */ - free(c_dbcsr_acc_opencl_info_stream(stream)->pointer); + ACC_OPENCL_RELEASE(c_dbcsr_acc_opencl_config.lock_stream); } # if defined(__DBCSR_ACC) && defined(ACC_OPENCL_PROFILE) c_dbcsr_timestop(&routine_handle); @@ -314,14 +216,16 @@ int c_dbcsr_acc_stream_priority_range(int* least, int* greatest) { cl_platform_id platform = NULL; cl_device_id active_id = NULL; if (EXIT_SUCCESS == result) { - result = c_dbcsr_acc_opencl_device(ACC_OPENCL_OMP_TID(), &active_id); + result = clGetContextInfo( + c_dbcsr_acc_opencl_config.device.context, CL_CONTEXT_DEVICES, sizeof(cl_device_id), &active_id, NULL); } ACC_OPENCL_CHECK(clGetDeviceInfo(active_id, CL_DEVICE_PLATFORM, sizeof(cl_platform_id), &platform, NULL), "retrieve platform associated with active device", result); ACC_OPENCL_CHECK(clGetPlatformInfo(platform, CL_PLATFORM_EXTENSIONS, ACC_OPENCL_BUFFERSIZE, buffer, NULL), "retrieve platform extensions", result); if (EXIT_SUCCESS == result) { - if (NULL != strstr(buffer, "cl_khr_priority_hints") || EXIT_SUCCESS == c_dbcsr_acc_opencl_device_vendor(active_id, "nvidia")) + if (NULL != strstr(buffer, "cl_khr_priority_hints") || + EXIT_SUCCESS == c_dbcsr_acc_opencl_device_vendor(active_id, "nvidia", 0 /*use_platform_name*/)) { priohi = CL_QUEUE_PRIORITY_HIGH_KHR; priolo = CL_QUEUE_PRIORITY_LOW_KHR; @@ -339,29 +243,67 @@ int c_dbcsr_acc_stream_priority_range(int* least, int* greatest) { int c_dbcsr_acc_stream_sync(void* stream) { + const c_dbcsr_acc_opencl_stream_t* str = NULL; int result = EXIT_SUCCESS; -# if defined(ACC_OPENCL_STREAM_PRIORITIES) - const int* const priority = (0 == (1 & c_dbcsr_acc_opencl_config.flush) ? NULL : c_dbcsr_acc_opencl_stream_priority(stream)); -# endif # if defined(__DBCSR_ACC) && defined(ACC_OPENCL_PROFILE) int routine_handle; static const char* const routine_name_ptr = LIBXSMM_FUNCNAME; static const int routine_name_len = (int)sizeof(LIBXSMM_FUNCNAME) - 1; c_dbcsr_timeset((const char**)&routine_name_ptr, &routine_name_len, &routine_handle); # endif - assert(NULL != stream); -# if defined(ACC_OPENCL_STREAM_PRIORITIES) - if (NULL != priority && CL_QUEUE_PRIORITY_HIGH_KHR <= *priority && CL_QUEUE_PRIORITY_MED_KHR > *priority) { - if (0 != (2 & c_dbcsr_acc_opencl_config.flush)) { - result = clFlush(*ACC_OPENCL_STREAM(stream)); + str = (NULL != stream ? ACC_OPENCL_STREAM(stream) : c_dbcsr_acc_opencl_stream_default()); + assert(NULL != str && NULL != str->queue); + result = clFinish(str->queue); +# if defined(__DBCSR_ACC) && defined(ACC_OPENCL_PROFILE) + c_dbcsr_timestop(&routine_handle); +# endif + ACC_OPENCL_RETURN(result); +} + + +int c_dbcsr_acc_opencl_device_synchronize(ACC_OPENCL_LOCKTYPE* lock, int thread_id) { + int result = EXIT_SUCCESS; + const size_t n = ACC_OPENCL_MAXNITEMS * c_dbcsr_acc_opencl_config.nthreads; + size_t i; + assert(thread_id < c_dbcsr_acc_opencl_config.nthreads); + assert(NULL != c_dbcsr_acc_opencl_config.streams); + if (NULL != lock) ACC_OPENCL_ACQUIRE(lock); + for (i = c_dbcsr_acc_opencl_config.nstreams; i < n; ++i) { + const c_dbcsr_acc_opencl_stream_t* const str = c_dbcsr_acc_opencl_config.streams[i]; + if (NULL != str && NULL != str->queue) { + if (str->tid == thread_id || 0 > thread_id) { /* hit */ + result = clFinish(str->queue); + if (EXIT_SUCCESS != result) break; + } + } + else { /* error */ + result = EXIT_FAILURE; + break; } } - else + if (NULL != lock) ACC_OPENCL_RELEASE(lock); + return result; +} + + +int c_dbcsr_acc_device_synchronize(void) { + int result = EXIT_SUCCESS; +# if defined(__DBCSR_ACC) && defined(ACC_OPENCL_PROFILE) + int routine_handle; + static const char* const routine_name_ptr = LIBXSMM_FUNCNAME; + static const int routine_name_len = (int)sizeof(LIBXSMM_FUNCNAME) - 1; + c_dbcsr_timeset((const char**)&routine_name_ptr, &routine_name_len, &routine_handle); # endif - { - const cl_command_queue queue = *ACC_OPENCL_STREAM(stream); - result = clFinish(queue); +# if defined(_OPENMP) + if (1 == omp_get_num_threads()) { + result = c_dbcsr_acc_opencl_device_synchronize(c_dbcsr_acc_opencl_config.lock_stream, -1 /*all*/); } + else { + result = c_dbcsr_acc_opencl_device_synchronize(NULL /*lock*/, omp_get_thread_num()); + } +# else + result = c_dbcsr_acc_opencl_device_synchronize(NULL /*lock*/, /*main*/ 0); +# endif # if defined(__DBCSR_ACC) && defined(ACC_OPENCL_PROFILE) c_dbcsr_timestop(&routine_handle); # endif diff --git a/src/acc/opencl/common/opencl_atomics.h b/src/acc/opencl/common/opencl_atomics.h new file mode 100644 index 00000000000..7809a5216cd --- /dev/null +++ b/src/acc/opencl/common/opencl_atomics.h @@ -0,0 +1,148 @@ +/*------------------------------------------------------------------------------------------------*/ +/* Copyright (C) by the DBCSR developers group - All rights reserved */ +/* This file is part of the DBCSR library. */ +/* */ +/* For information on the license, see the LICENSE file. */ +/* For further information please visit https://dbcsr.cp2k.org */ +/* SPDX-License-Identifier: GPL-2.0+ */ +/*------------------------------------------------------------------------------------------------*/ +#ifndef OPENCL_ATOMICS_H +#define OPENCL_ATOMICS_H + +#include "opencl_common.h" + +#if (2 == TAN /*c_dbcsr_acc_opencl_atomic_fp_64*/) +# if !defined(T) +# define T double +# endif +# define ZERO 0.0 +#elif (1 == TAN /*c_dbcsr_acc_opencl_atomic_fp_32*/) +# if !defined(T) +# define T float +# endif +# define ZERO 0.f +#elif defined(T) /*c_dbcsr_acc_opencl_atomic_fp_no*/ +# define ZERO 0 +#endif + +#define GLOBAL_VOLATILE(A) global volatile A + +#if defined(ATOMIC_PROTOTYPES) || defined(__opencl_c_ext_fp64_global_atomic_add) +# if defined(__opencl_c_ext_fp64_global_atomic_add) +# undef ATOMIC_ADD_GLOBAL +# if defined(TF) +# define ATOMIC_ADD_GLOBAL(A, B) \ + atomic_fetch_add_explicit((GLOBAL_VOLATILE(TF)*)A, B, memory_order_relaxed, memory_scope_work_group) +# else +# define ATOMIC_ADD_GLOBAL(A, B) atomic_add(A, B) +# endif +# elif (2 < ATOMIC_PROTOTYPES) && defined(TF) +# undef ATOMIC_ADD_GLOBAL +# define ATOMIC_ADD_GLOBAL(A, B) \ + __opencl_atomic_fetch_add((GLOBAL_VOLATILE(TF)*)A, B, memory_order_relaxed, memory_scope_work_group) +# else +# if defined(TF) && (!defined(ATOMIC_PROTOTYPES) || 1 < ATOMIC_PROTOTYPES) +__attribute__((overloadable)) T atomic_fetch_add_explicit(GLOBAL_VOLATILE(TF) *, T, memory_order, memory_scope); +# else +__attribute__((overloadable)) T atomic_add(GLOBAL_VOLATILE(T) *, T); +# endif +# endif +#endif + +#define ACCUMULATE(A, B) ATOMIC_ADD_GLOBAL(A, B) + + +#if !defined(cl_intel_global_float_atomics) || (2 == TAN /*c_dbcsr_acc_opencl_atomic_fp_64*/) +# if defined(ATOMIC32_ADD64) +__attribute__((always_inline)) inline void atomic32_add64_global(GLOBAL_VOLATILE(double) * dst, double inc) { + *dst += inc; /* TODO */ +} +# endif +#endif + + +#if !defined(cl_intel_global_float_atomics) || (2 == TAN /*c_dbcsr_acc_opencl_atomic_fp_64*/) +# if defined(CMPXCHG) +__attribute__((always_inline)) inline void atomic_add_global_cmpxchg(GLOBAL_VOLATILE(T) * dst, T inc) { +# if !defined(ATOMIC32_ADD64) + union { + T f; + TA a; + } exp_val, try_val, cur_val = {.f = *dst}; + do { + exp_val.a = cur_val.a; + try_val.f = exp_val.f + inc; +# if defined(TA2) + if (0 == atomic_compare_exchange_weak_explicit((GLOBAL_VOLATILE(TA2)*)dst, &cur_val.a, try_val.a, memory_order_relaxed, + memory_order_relaxed, memory_scope_work_group)) + continue; +# else + cur_val.a = CMPXCHG((GLOBAL_VOLATILE(TA)*)dst, exp_val.a, try_val.a); +# endif + } while (cur_val.a != exp_val.a); +# else + atomic32_add64_global(dst, inc); +# endif +} +# endif +#endif + + +#if !defined(cl_intel_global_float_atomics) || (2 == TAN /*c_dbcsr_acc_opencl_atomic_fp_64*/) +# if defined(ATOMIC_ADD2_GLOBAL) && (1 == TAN /*c_dbcsr_acc_opencl_atomic_fp_32*/) +__attribute__((always_inline)) inline void atomic_add_global_cmpxchg2(GLOBAL_VOLATILE(float) * dst, float2 inc) { + union { + float2 f; + long a; + } exp_val, try_val, cur_val = {.f = (float2)(dst[0], dst[1])}; + do { + exp_val.a = cur_val.a; + try_val.f = exp_val.f + inc; +# if defined(TA2) + if (0 == atomic_compare_exchange_weak_explicit((GLOBAL_VOLATILE(atomic_long)*)dst, &cur_val.a, try_val.a, memory_order_relaxed, + memory_order_relaxed, memory_scope_work_group)) + continue; +# else + cur_val.a = atom_cmpxchg((GLOBAL_VOLATILE(long)*)dst, exp_val.a, try_val.a); +# endif + } while (cur_val.a != exp_val.a); +} +# endif +#endif + + +#if !defined(cl_intel_global_float_atomics) || (2 == TAN /*c_dbcsr_acc_opencl_atomic_fp_64*/) +# if defined(XCHG) || (defined(__NV_CL_C_VERSION) && !defined(CMPXCHG) && !defined(ATOMIC_PROTOTYPES)) +__attribute__((always_inline)) inline void atomic_add_global_xchg(GLOBAL_VOLATILE(T) * dst, T inc) { +# if !defined(ATOMIC32_ADD64) +# if (defined(__NV_CL_C_VERSION) && !defined(XCHG)) && (1 == TAN /*c_dbcsr_acc_opencl_atomic_fp_32*/) + asm("{ .reg .f32 t; atom.global.add.f32 t, [%0], %1; }" ::"l"(dst), "f"(inc)); +# elif (defined(__NV_CL_C_VERSION) && !defined(XCHG)) && (2 == TAN /*c_dbcsr_acc_opencl_atomic_fp_64*/) + asm("{ .reg .f64 t; atom.global.add.f64 t, [%0], %1; }" ::"l"(dst), "d"(inc)); +# else + union { + T f; + TA a; + } exp_val = {.f = inc}, try_val, cur_val = {/*.f = ZERO*/ .a = 0}; + do { +# if defined(TA2) + try_val.a = atomic_exchange_explicit((GLOBAL_VOLATILE(TA2)*)dst, cur_val.a, memory_order_relaxed, memory_scope_work_group); +# else + try_val.a = XCHG((GLOBAL_VOLATILE(TA)*)dst, cur_val.a); +# endif + try_val.f += exp_val.f; +# if defined(TA2) + exp_val.a = atomic_exchange_explicit((GLOBAL_VOLATILE(TA2)*)dst, try_val.a, memory_order_relaxed, memory_scope_work_group); +# else + exp_val.a = XCHG((GLOBAL_VOLATILE(TA)*)dst, try_val.a); +# endif + } while (cur_val.a != exp_val.a); +# endif +# else + atomic32_add64_global(dst, inc); +# endif +} +# endif +#endif + +#endif /*OPENCL_ATOMICS_H*/ diff --git a/src/acc/opencl/common/opencl_common.h b/src/acc/opencl/common/opencl_common.h new file mode 100644 index 00000000000..8fa27d612c0 --- /dev/null +++ b/src/acc/opencl/common/opencl_common.h @@ -0,0 +1,51 @@ +/*------------------------------------------------------------------------------------------------*/ +/* Copyright (C) by the DBCSR developers group - All rights reserved */ +/* This file is part of the DBCSR library. */ +/* */ +/* For information on the license, see the LICENSE file. */ +/* For further information please visit https://dbcsr.cp2k.org */ +/* SPDX-License-Identifier: GPL-2.0+ */ +/*------------------------------------------------------------------------------------------------*/ +#ifndef OPENCL_COMMON_H +#define OPENCL_COMMON_H + +#if !defined(ACC_OPENCL_C_VERSION) +# define ACC_OPENCL_C_VERSION __OPENCL_C_VERSION__ +#endif +#if !defined(ACC_OPENCL_VERSION) +# define ACC_OPENCL_VERSION __OPENCL_VERSION__ +#endif + +#if (200 /*CL_VERSION_2_0*/ <= ACC_OPENCL_C_VERSION) || defined(__NV_CL_C_VERSION) +# define UNROLL_FORCE(N) __attribute__((opencl_unroll_hint(N))) +# define UNROLL_AUTO __attribute__((opencl_unroll_hint)) +#else +# define UNROLL_FORCE(N) +# define UNROLL_AUTO +#endif + +#if !defined(MIN) +# define MIN(A, B) ((A) < (B) ? (A) : (B)) +#endif +#if !defined(MAX) +# define MAX(A, B) ((A) < (B) ? (B) : (A)) +#endif +#if !defined(MAD) +# define MAD fma +#endif + +#if !defined(LU) || (-1 == LU) +# define UNROLL_OUTER(N) +# define UNROLL(N) +#else /* (-2) full, (-1) no hints, (0) inner, (1) outer-dehint, (2) block-m */ +# if (1 <= LU) /* outer-dehint */ +# define UNROLL_OUTER(N) UNROLL_FORCE(1) +# elif (-1 > LU) /* full */ +# define UNROLL_OUTER(N) UNROLL_FORCE(N) +# else /* inner */ +# define UNROLL_OUTER(N) +# endif +# define UNROLL(N) UNROLL_FORCE(N) +#endif + +#endif /*OPENCL_COMMON_H*/ diff --git a/src/acc/opencl/smm/.gitignore b/src/acc/opencl/smm/.gitignore index dc6a8d940a0..9cb97ee5dac 100644 --- a/src/acc/opencl/smm/.gitignore +++ b/src/acc/opencl/smm/.gitignore @@ -1 +1,2 @@ opencl_kernels.h +.with_gpu diff --git a/src/acc/opencl/smm/CMakeLists.txt b/src/acc/opencl/smm/CMakeLists.txt index 9585d75a3d6..d3b37392f73 100644 --- a/src/acc/opencl/smm/CMakeLists.txt +++ b/src/acc/opencl/smm/CMakeLists.txt @@ -1,26 +1,35 @@ -set(LIBSMM_ACC_HEADER_KERNELS ${CMAKE_CURRENT_SOURCE_DIR}/opencl_kernels.h) +set(LIBSMM_ACC_KERNELS_INC ${CMAKE_CURRENT_SOURCE_DIR}/opencl_kernels.h) -set(SMM_ACC_KERNEL_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/../acc_opencl.sh) +set(SMM_ACC_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/../acc_opencl.sh) +set(SMM_ACC_COMMON ../common/opencl_atomics.h ../common/opencl_common.h) set(SMM_ACC_KERNELS kernels/multiply.cl kernels/transpose.cl) list(TRANSFORM SMM_ACC_KERNELS PREPEND ${CMAKE_CURRENT_SOURCE_DIR}/) set(SMM_ACC_PARAMS_WITHGPU ${CMAKE_CURRENT_SOURCE_DIR}/params/tune_multiply_${WITH_GPU}.csv) -set(SMM_ACC_PARAMS_DEFAULT ${CMAKE_CURRENT_SOURCE_DIR}/tune_multiply.csv) +set(SMM_ACC_PARAMS_CUSTOM ${CMAKE_CURRENT_SOURCE_DIR}/tune_multiply.csv) if (EXISTS ${SMM_ACC_PARAMS_WITHGPU}) + set(SMM_ACC_SCRIPT_MSG "ACC/LIBSMM OpenCL: using parameters for ${WITH_GPU}") set(SMM_ACC_PARAMS ${SMM_ACC_PARAMS_WITHGPU}) -elseif (EXISTS ${SMM_ACC_PARAMS_DEFAULT}) - set(SMM_ACC_PARAMS ${SMM_ACC_PARAMS_DEFAULT}) +elseif (WITH_GPU MATCHES "none") + set(SMM_ACC_SCRIPT_MSG "ACC/LIBSMM OpenCL: no tuned parameters used") + set(SMM_ACC_SCRIPT_ARGS -p \"\") +elseif (EXISTS ${SMM_ACC_PARAMS_CUSTOM}) + set(SMM_ACC_SCRIPT_MSG "ACC/LIBSMM OpenCL: using custom parameters") + set(SMM_ACC_PARAMS ${SMM_ACC_PARAMS_CUSTOM}) +else () + set(SMM_ACC_SCRIPT_MSG "ACC/LIBSMM OpenCL: using all tuned parameters") endif () +message(STATUS ${SMM_ACC_SCRIPT_MSG}) add_custom_target( - parameters ALL - COMMAND ${SMM_ACC_KERNEL_SCRIPT} ${SMM_ACC_KERNELS} ${SMM_ACC_PARAMS} - ${LIBSMM_ACC_HEADER_KERNELS} - DEPENDS ${SMM_ACC_KERNEL_SCRIPT} ${SMM_ACC_KERNELS} - BYPRODUCTS ${LIBSMM_ACC_HEADER_KERNELS} - COMMENT "libsmm_acc: generating kernels") + parameters # ALL + COMMAND ${SMM_ACC_SCRIPT} ${SMM_ACC_SCRIPT_ARGS} ${SMM_ACC_KERNELS} + ${SMM_ACC_PARAMS} ${LIBSMM_ACC_KERNELS_INC} + DEPENDS ${SMM_ACC_SCRIPT} ${SMM_ACC_KERNELS} ${SMM_ACC_COMMON} + BYPRODUCTS ${LIBSMM_ACC_KERNELS_INC} + COMMENT ${SMM_ACC_SCRIPT_MSG}) add_dependencies(dbcsr parameters) target_include_directories(dbcsr PRIVATE ${CMAKE_CURRENT_BINARY_DIR} diff --git a/src/acc/opencl/smm/README-autotune.md b/src/acc/opencl/smm/README-autotune.md new file mode 100644 index 00000000000..2f22cbb27b3 --- /dev/null +++ b/src/acc/opencl/smm/README-autotune.md @@ -0,0 +1,52 @@ +# Auto Tuning + +Auto tuning code for performance is a practical way to find the "best" setting for parameterized code (e.g., GPU kernels). Introducing effective parameters is a prerequisite, and exploring the (potentially) high-dimensional parameter space in an efficient way is an art. It is desirable to have reasonable defaults even without auto-tuning the parameters. It would be even better to avoid auto-tuning if best performance was possible right away. + +For the OpenCL based LIBSMM, a variety of parameters are explored using [OpenTuner](http://opentuner.org/). The script [tune_multiply.py](https://github.com/cp2k/dbcsr/blob/develop/src/acc/opencl/smm/tune_multiply.py) (or tune_multiply.sh) leverages the `acc_bench_smm` by parsing console output (timing, data type, etc.). This way, the tuning is implemented without being intermingled with the subject being tuned. The "communication" between the tuner and the executable is solely based on environment variables. + +**NOTE**: If `tune_multiply.py` (or `tune_multiply.sh`) is called with an environment variable already set, the respective parameter (e.g., `OPENCL_LIBSMM_SMM_BM` or `OPENCL_LIBSMM_SMM_BN`) is considered fixed (and not tuned automatically). This way, the parameter space is reduced in size and effort can be directed more intensely towards the remaining parameters. + +To toggle the benchmarks between tuning single precision (SP) and double precision (DP), `make ELEM_TYPE=float` can be used when building the benchmark drivers (`ELEM_TYPE` can be also directly edited in [acc_bench_smm.c](https://github.com/cp2k/dbcsr/blob/develop/src/acc/acc_bench_smm.c#L26)). Auto-tuned parameters for SP and DP can be embedded into the same final application and are considered correctly at runtime. + +To build the benchmarks in double precision (`ELEM_TYPE=double` is default): + +```bash +cd src/acc/opencl +make +``` + +To build the benchmarks in single precision (SP): + +```bash +cd src/acc/opencl +make ELEM_TYPE=float +``` + +To auto-tune, please install the Python `wheel` and `opentuner` packages: + +```bash +cd src/acc/opencl/smm +pip install -r requirements.txt +``` + +The OpenTuner script supports several command line arguments (`tune_multiply.py --help`). For example, `--stop-after=300` can be of interest to finish in five minutes (without limit, OpenTuner decides when the auto-tuning process is finished). A single kernel can be selected by M, N, and K parameters (GEMM), e.g., `M=15`, `N=5`, and `K=7`: + +```bash +./tune_multiply.py 13x5x7 +``` + +**NOTE**: If multiple different kernels are tuned using `tune_multiply.py`, it is advisable to delete the `opentuner.db` directory prior to tuning a different kernel since otherwise auto-tuning is potentially (mis-)guided by information which was collected for a different kernel (`tune_multiply.sh` does this automatically). + +The OpenTuner script implements multiple objectives ("cost"), primarily "accuracy" (maximized) and a secondary objective "size" (minimized). The former represents the achieved performance (GFLOPS/s) while the latter represents an artificial kernel requirement (just to prefer one parameter set over another in case of similar performance). The console output looks like ("accuracy" denotes performance in GFLOPS/s): + +```text +[ 15s] INFO opentuner.search.plugin.DisplayPlugin: tests=8, best {'BS': 32, 'BM': 6, 'BN': 1}, cost accuracy=28.80000000, size=1.0, found by UniformGreedyMutation +[ 27s] INFO opentuner.search.plugin.DisplayPlugin: tests=19, best {'BS': 48, 'BM': 8, 'BN': 1}, cost accuracy=32.20000000, size=1.0, found by UniformGreedyMutation +[ 40s] INFO opentuner.search.plugin.DisplayPlugin: tests=31, best {'BS': 48, 'BM': 8, 'BN': 1}, cost accuracy=32.20000000, size=1.0, found by UniformGreedyMutation +[ 54s] INFO opentuner.search.plugin.DisplayPlugin: tests=43, best {'BS': 48, 'BM': 8, 'BN': 1}, cost accuracy=32.20000000, size=1.0, found by UniformGreedyMutation +[ 67s] INFO opentuner.search.plugin.DisplayPlugin: tests=53, best {'BS': 48, 'BM': 8, 'BN': 1}, cost accuracy=32.20000000, size=1.0, found by UniformGreedyMutation +``` + +The script finally writes a JSON-file with a filename like `tune_multiply-float-12x12x12-s15-60gflops.json` which is encoding the benchmark ("multiply"), the precision ("float"), the kernel ("12x12x12"), the number of bits necessary to represent the size of the problem, i.e., log2 of the problem-size ("s15"), and the achieved performance ("60gflops"). The script handles SIGINT (like Ctrl-C), and output is still written despite of abnormally terminating (can be abused to tune interactively). Tuning starts from an internal default that is supposed to match LIBSMM's internal default parameters. However, tuning can be (re-)started with specific parameters (e.g., `-bs 64`, `-bm 13`, `-bn 1` for `OPENCL_LIBSMM_SMM_BS`, `OPENCL_LIBSMM_SMM_BM`, and `OPENCL_LIBSMM_SMM_BN` respectively), or partially fixed for a subset of parameters. + +**NOTE**: The `acc_bench_smm` executable is potentially started many times when auto-tuning parameters, therefore it is advisable to keep the state of the GPU driver stack persistent (if the setup would otherwise unload the driver configuration), e.g., `nvidia-smi -pm ENABLED`. This can happen in cases where the GPU is only for compute and not used for graphics (no X-Window system, e.g., in case of a "headless" system). Time needed for tuning parameters is not only impacted by accessing and readying the device, but also by the time needed to compile a kernel at runtime aka Just-In-Time (JIT). diff --git a/src/acc/opencl/smm/README-bulktune.md b/src/acc/opencl/smm/README-bulktune.md new file mode 100644 index 00000000000..36bee50ee28 --- /dev/null +++ b/src/acc/opencl/smm/README-bulktune.md @@ -0,0 +1,89 @@ +# Optimized Kernels + +Optimized kernel parameters are stored in JSON-files and are automatically summarized into a CSV-file. Further and beyond auto-tuning kernels, [tune_multiply.py](https://github.com/cp2k/dbcsr/blob/develop/src/acc/opencl/smm/tune_multiply.py) can be used to perform basic operations on collected data: explicitly merging all JSON-files into a CSV-file (`tune_multiply.py -m`), and updating the device name in all JSON-files according to current driver version (`tune_multiply.py -u`). + +Collected or auto-tuned parameters achieved with single precision (SP), double precision (DP), or from different devices can be safely combined. Practically, `acc_opencl.sh` transforms the CSV-file into source code compiled into the final binary, which is independent of `OPENCL_LIBSMM_SMM_PARAMS` accepting a CSV-file (path/filename). However, `acc_opencl.sh` currently limits the origin of parameters to a single device. Care must still be taken to not summarize unrelated results, e.g., after (major) source code changes. The CSV-file is automatically incorporated into LIBSMM by the next clean (re-)build. The format of the CSV-file is assumed to contain column names in the first row (header). + +Different problem sizes (like "s15"; see above) are not represented individually, but are instead collected into a maximum value. In turn, this means tuning for a non-default problem-size must be manually kept pure since the result achieved with a larger problem may dominate (maximum value). + +```bash +cd src/acc/opencl +make realclean +make +``` + +This way auto-tuned kernels just work and can be of course exercised using the afore mentioned benchmark: + +```bash +cd src/acc +./acc_bench_smm 5 30000 13 5 7 +``` + +Tuned parameters can be also disabled at runtime like: + +```bash +cd src/acc +OPENCL_LIBSMM_SMM_PARAMS=0 ./acc_bench_smm 5 30000 13 5 7 +``` + +By supplying a CSV-file at runtime, embedded parameters and defaults are overriden, and given parameters are applied even if the current device is different from what would match the given parameters: + +```bash +cd src/acc +OPENCL_LIBSMM_SMM_PARAMS=opencl/smm/tune_multiply.csv ./acc_bench_smm 5 30000 13 5 7 +``` + +To tune multiple kernels in a convenient fashion, a triplet specification can be supplied to the [tune_multiply.sh](https://github.com/cp2k/dbcsr/blob/develop/src/acc/opencl/smm/tune_multiply.sh) wrapper script. This script estimates the total runtime for auto-tuning kernels, cleans up intermediate results (`opentuner.db`), allows to specify triplets, and splits work to auto-tune in parallel. + +Triplets are used to conveniently describe multiple kernels. A triplet specification consists of comma-separated groups of (M,N,K)-extents, i.e., matrix shapes according to GEMM. For example: + +```text +4 10 15, 6 7 8, 23 +``` + +This triplet specification expands to 55 kernels using the Cartesian product within each group and concatenating the result of such expanded groups followed by removing duplicate triplets. Further, the wrapper script allows to limit the time spent for tuning a single kernel and to partition the number of kernels to be tuned, e.g., among a cluster of eight systems (below the first partition out of eight would be processed with five minutes per kernel and about 35 minutes in total per partition). + +```bash +cd src/acc/opencl/smm +./tune_multiply.sh -t 300 -j 8 -i 1 4 10 15, 6 7 8, 23 +``` + +The script `tune_multiply.sh` is tuning 1266 kernels by default (`./tune_multiply.sh -t 300 -j 8 -i 1` takes approximately 13 hours per part). If the process is interrupted earlier (per SIGINT or Ctrl-C), the execution terminates for all requested kernels (triplet specification) unless `--continue` is given (or `-c`, or an environment variable `CONTINUE=1`). + +For convenience, it is possible to "update" an existing set of JSON-files (path can be given with `-p`), i.e., to parse the (M,N,K)-triplet denoted by the JSON filename and to re-tune with an almost unconstrained tuning-level (`-a 1` by default) as well as a limited duration (160 seconds per kernel by default). + +```bash +cd src/acc/opencl +make realclean +echo "Rebuild and embed smm/params/tune_multiply_P100.csv" +make WITH_GPU=P100 + +echo "Retune original parameters" +smm/tune_multiply.sh -p smm/params/p100 -u + +echo "Override original parameters" +cp tune_multiply.csv smm/params/tune_multiply_P100.csv +``` + +Tuning kernels further is only sensible if the previously tuned parameters are embedded into the binary (such that the process does not start from scratch). Retuned parameters are captured with JSON-files as usual. + +# Advanced Tuning + +To utilize multiple devices per system and to accelerate tuning kernels, `tune_multiply.py` comes with built-in support for running under MPI (SPMD execution model). The basic assumption is to spawn one process per device usually with different kernels tuned per device (SPMD). Of course, tuning the same kernels in parallel on multiple devices is possible but it is a waste of resources. Tuning on multiple devices per system can be also more realistic given the common power budget of all devices and less room for an increased operating frequency per device (Turbo clock speed). + +For example, a single dual-socket system with two PVC cards (modules) per socket exposes eight GPU devices (two GPU stacks or tiles per card). Then 350 kernels can be tuned in less than 2 1/2 hours with a duration of 200 seconds for tuning each kernel. + +```bash +MAXTIME=200 NPARTS=8 UPDATE=1 JSONDIR=params/pvc mpirun \ + ./tune_multiply.sh -i 1 : \ + ./tune_multiply.sh -i 2 : \ + ./tune_multiply.sh -i 3 : \ + ./tune_multiply.sh -i 4 : \ + ./tune_multiply.sh -i 5 : \ + ./tune_multiply.sh -i 6 : \ + ./tune_multiply.sh -i 7 : \ + ./tune_multiply.sh -i 8 \ +>out.log 2>&1 +``` + +**NOTE**: The above shown example prefers environment variables over command-line options that would be common to the eight launches of `tune_multiply.sh`. diff --git a/src/acc/opencl/smm/README.md b/src/acc/opencl/smm/README.md index 0e8e462cb4f..a34c0700942 100644 --- a/src/acc/opencl/smm/README.md +++ b/src/acc/opencl/smm/README.md @@ -1,26 +1,10 @@ -# LIBSMM (OpenCL) - -## Overview +# LIBSMM The LIBSMM library implements the [ACC LIBSMM interface](https://github.com/cp2k/dbcsr/blob/develop/src/acc/acc_libsmm.h), and depends on the [OpenCL backend](https://github.com/cp2k/dbcsr/blob/develop/src/acc/opencl/README.md). -## Customization - -Compile-time settings are (implicitly) documented and can be adjusted by editing [opencl_libsmm.h](https://github.com/cp2k/dbcsr/blob/develop/src/acc/opencl/smm/opencl_libsmm.h), e.g., `OPENCL_LIBSMM_VALIDATE` is disabled by default but can be enabled for debug purpose. The `OPENCL_LIBSMM_VALIDATE` compile-time setting enables side-by-side validation of matrix transpose and multiply operations between device and host. For example, running DBCSR's unit tests with `OPENCL_LIBSMM_VALIDATE` enabled produces console output that allows to pin-point a kernel which misses validation. Runtime settings are made by the means of environment variables. The OpenCL backend provides `acc_getenv.sh` to list all occurrences of `getenv` categorized into "OpenCL Backend environment variables" and "OpenCL LIBSMM environment variables". Common backend related settings are: - -* `ACC_OPENCL_DEVSPLIT`: integer enabling devices to be split into subdevices (non-zero/default: subdevices, zero: aggregated). -* `ACC_OPENCL_DEVTYPE`: character string selecting "cpu", "gpu", "all" (unfiltered), or any other string (neither CPU or GPU). -* `ACC_OPENCL_DEVICE`: non-negative integer number to select a device from the (internally enumerated) list of devices. -* `ACC_OPENCL_VENDOR`: character string matching the vendor of the OpenCL device in a case-insensitive fashion, e.g., "intel". -* `ACC_OPENCL_VERBOSE`: verbosity level (integer) with console output on `stderr`. - * `ACC_OPENCL_VERBOSE=1`: outputs the number of devices found and the name of the selected device. - * `ACC_OPENCL_VERBOSE=2`: outputs the duration needed to generate a requested kernel. - * `ACC_OPENCL_VERBOSE=3`: outputs device-side performance of kernels (every launch profiled). -* `ACC_OPENCL_DUMP`: dump preprocessed kernel source code (1) or dump compiled OpenCL kernels (2). - * `ACC_OPENCL_DUMP=1`: dump preprocessed kernel source code and use it for JIT compilation. Instantiates the original source code using preprocessor definitions (`-D`) and collapses the code accordingly. - * `ACC_OPENCL_DUMP=2`: dump compiled OpenCL kernels (depends on OpenCL implementation), e.g., PTX code on Nvidia. +Compile-time settings are (implicitly) documented and can be adjusted by editing [opencl_libsmm.h](https://github.com/cp2k/dbcsr/blob/develop/src/acc/opencl/smm/opencl_libsmm.h), e.g., `OPENCL_LIBSMM_VALIDATE` is disabled by default but can be enabled for debug purpose. The `OPENCL_LIBSMM_VALIDATE` compile-time setting enables side-by-side validation of matrix transpose and multiply operations between device and host. For example, running DBCSR's unit tests with `OPENCL_LIBSMM_VALIDATE` enabled produces console output that allows to pin-point a kernel which misses validation. Runtime settings are made by the means of environment variables. The OpenCL backend provides `acc_getenv.sh` to list all occurrences of `getenv` categorized into "OpenCL Backend environment variables" and "OpenCL LIBSMM environment variables". -There are two categories for the two domains in OpenCL based LIBSMM, i.e., matrix transpose (`OPENCL_LIBSMM_TRANS_*`) and matrix multiplication (`OPENCL_LIBSMM_SMM_*`). For transposing matrices, the settings are: +There are two categories for the two domains in LIBSMM, i.e., matrix transpose (`OPENCL_LIBSMM_TRANS_*`) and matrix multiplication (`OPENCL_LIBSMM_SMM_*`). For transposing matrices, the settings are: * `OPENCL_LIBSMM_TRANS_BUILDOPTS`: character string with build options (compile and link) supplied to the OpenCL runtime compiler. * `OPENCL_LIBSMM_TRANS_INPLACE`: Boolean value (zero or non-zero integer) for in-place matrix transpose (no local memory needed). @@ -29,7 +13,6 @@ There are two categories for the two domains in OpenCL based LIBSMM, i.e., matri The most common settings for multiplying matrices are: * `OPENCL_LIBSMM_SMM_BUILDOPTS`: character string with build options (compile and link) supplied to the OpenCL runtime compiler. -* `OPENCL_LIBSMM_SMM_ATOMICS`: selects the kind of atomic operation used for global memory updates (`xchg`, `cmpxchg`, `cmpxchg2`), attempts to force atomic instructions, or disables atomic instructions (`0`). The latter is for instance to quantify the impact of atomic operations. * `OPENCL_LIBSMM_SMM_PARAMS`: Disable embedded/auto-tuned parameters (`0`), or load CSV-file (e.g., `path/to/tune_multiply.csv`). * `OPENCL_LIBSMM_SMM_BS`: non-negative integer number denoting the intra-kernel (mini-)batchsize mainly used to amortize atomic updates of data in global/main memory. The remainder with respect to the "stacksize" is handled by the kernel. * `OPENCL_LIBSMM_SMM_BM`: non-negative integer number (less/equal than the M-extent) denoting the blocksize in M-direction. @@ -43,124 +26,6 @@ The full list of tunable parameters and some explanation can be received with `s **NOTE**: LIBSMM's tunable runtime settings can be non-smooth like producing distinct code-paths, e.g., `OPENCL_LIBSMM_SMM_BS=1` vs. `OPENCL_LIBSMM_SMM_BS=2`. -## Auto Tuning - -Auto tuning code for performance is a practical way to find the "best" setting for parameterized code (e.g., GPU kernels). Introducing effective parameters is a prerequisite, and exploring the (potentially) high-dimensional parameter space in an efficient way is an art. It is desirable to have reasonable defaults even without auto-tuning the parameters. It would be even better to avoid auto-tuning if best performance was possible right away. - -For the OpenCL based LIBSMM, a variety of parameters are explored using [OpenTuner](http://opentuner.org/). The script [tune_multiply.py](https://github.com/cp2k/dbcsr/blob/develop/src/acc/opencl/smm/tune_multiply.py) (or tune_multiply.sh) leverages the `acc_bench_smm` by parsing console output (timing, data type, etc.). This way, the tuning is implemented without being intermingled with the subject being tuned. The "communication" between the tuner and the executable is solely based on environment variables. - -**NOTE**: If `tune_multiply.py` (or `tune_multiply.sh`) is called with an environment variable already set, the respective parameter (e.g., `OPENCL_LIBSMM_SMM_BM` or `OPENCL_LIBSMM_SMM_BN`) is considered fixed (and not tuned automatically). This way, the parameter space is reduced in size and effort can be directed more intensely towards the remaining parameters. - -To toggle the benchmarks between tuning single precision (SP) and double precision (DP), `make ELEM_TYPE=float` can be used when building the benchmark drivers (`ELEM_TYPE` can be also directly edited in [acc_bench_smm.c](https://github.com/cp2k/dbcsr/blob/develop/src/acc/acc_bench_smm.c#L26)). Auto-tuned parameters for SP and DP can be embedded into the same final application and are considered correctly at runtime. - -To build the benchmarks in double precision (`ELEM_TYPE=double` is default): - -```bash -cd src/acc/opencl -make -``` - -To build the benchmarks in single precision (SP): - -```bash -cd src/acc/opencl -make ELEM_TYPE=float -``` - -To auto-tune, please install the Python `wheel` and `opentuner` packages: - -```bash -cd src/acc/opencl/smm -pip install -r requirements.txt -``` - -The OpenTuner script supports several command line arguments (`tune_multiply.py --help`). For example, `--stop-after=300` can be of interest to finish in five minutes (without limit, OpenTuner decides when the auto-tuning process is finished). A single kernel can be selected by M, N, and K parameters (GEMM), e.g., `M=15`, `N=5`, and `K=7`: - -```bash -./tune_multiply.py 13x5x7 -``` - -**NOTE**: If multiple different kernels are tuned using `tune_multiply.py`, it is advisable to delete the `opentuner.db` directory prior to tuning a different kernel since otherwise auto-tuning is potentially (mis-)guided by information which was collected for a different kernel (`tune_multiply.sh` does this automatically). - -The OpenTuner script implements multiple objectives ("cost"), primarily "accuracy" (maximized) and a secondary objective "size" (minimized). The former represents the achieved performance (GFLOPS/s) while the latter represents an artificial kernel requirement (just to prefer one parameter set over another in case of similar performance). The console output looks like ("accuracy" denotes performance in GFLOPS/s): - -```text -[ 15s] INFO opentuner.search.plugin.DisplayPlugin: tests=8, best {'BS': 32, 'BM': 6, 'BN': 1}, cost accuracy=28.80000000, size=1.0, found by UniformGreedyMutation -[ 27s] INFO opentuner.search.plugin.DisplayPlugin: tests=19, best {'BS': 48, 'BM': 8, 'BN': 1}, cost accuracy=32.20000000, size=1.0, found by UniformGreedyMutation -[ 40s] INFO opentuner.search.plugin.DisplayPlugin: tests=31, best {'BS': 48, 'BM': 8, 'BN': 1}, cost accuracy=32.20000000, size=1.0, found by UniformGreedyMutation -[ 54s] INFO opentuner.search.plugin.DisplayPlugin: tests=43, best {'BS': 48, 'BM': 8, 'BN': 1}, cost accuracy=32.20000000, size=1.0, found by UniformGreedyMutation -[ 67s] INFO opentuner.search.plugin.DisplayPlugin: tests=53, best {'BS': 48, 'BM': 8, 'BN': 1}, cost accuracy=32.20000000, size=1.0, found by UniformGreedyMutation -``` - -The script finally writes a JSON-file with a filename like `tune_multiply-float-12x12x12-s15-60gflops.json` which is encoding the benchmark ("multiply"), the precision ("float"), the kernel ("12x12x12"), the number of bits necessary to represent the size of the problem, i.e., log2 of the problem-size ("s15"), and the achieved performance ("60gflops"). The script handles SIGINT (like Ctrl-C), and output is still written despite of abnormally terminating (can be abused to tune interactively). Tuning starts from an internal default that is supposed to match LIBSMM's internal default parameters. However, tuning can be (re-)started with specific parameters (e.g., `-bs 64`, `-bm 13`, `-bn 1` for `OPENCL_LIBSMM_SMM_BS`, `OPENCL_LIBSMM_SMM_BM`, and `OPENCL_LIBSMM_SMM_BN` respectively), or partially fixed for a subset of parameters. - -**NOTE**: The `acc_bench_smm` executable is potentially started many times when auto-tuning parameters, therefore it is advisable to keep the state of the GPU driver stack persistent (if the setup would otherwise unload the driver configuration), e.g., `nvidia-smi -pm ENABLED`. This can happen in cases where the GPU is only for compute and not used for graphics (no X-Window system, e.g., in case of a "headless" system). Time needed for tuning parameters is not only impacted by accessing and readying the device, but also by the time needed to compile a kernel at runtime aka Just-In-Time (JIT). - -## Optimized Kernels - -JSON-files in the above mentioned smm-directory are automatically summarized into a CSV-file. Further and beyond auto-tuning kernels, [tune_multiply.py](https://github.com/cp2k/dbcsr/blob/develop/src/acc/opencl/smm/tune_multiply.py) can be used to perform basic operations on collected data: explicitly merging all JSON-files into a CSV-file (`tune_multiply.py -m`), and updating the device name in all JSON-files according to current driver version (`tune_multiply.py -u`). - -Collected or auto-tuned parameters achieved with single precision (SP), double precision (DP), or from different devices can be safely combined. Practically, `acc_opencl.sh` transforms the CSV-file into source code compiled into the final binary, which is independent of `OPENCL_LIBSMM_SMM_PARAMS` accepting a CSV-file (path/filename). However, `acc_opencl.sh` currently limits the origin of parameters to a single device. Care must still be taken to not summarize unrelated results, e.g., after (major) source code changes. The CSV-file is automatically incorporated into LIBSMM by the next clean (re-)build. The format of the CSV-file is assumed to contain column names in the first row (header). - -Different problem sizes (like "s15"; see above) are not represented individually, but are instead collected into a maximum value. In turn, this means tuning for a non-default problem-size must be manually kept pure since the result achieved with a larger problem may dominate (maximum value). - -```bash -cd src/acc/opencl -make realclean -make -``` - -This way auto-tuned kernels just work and can be of course exercised using the afore mentioned benchmark: - -```bash -cd src/acc -./acc_bench_smm 5 30000 13 5 7 -``` - -Tuned parameters can be also disabled at runtime like: - -```bash -cd src/acc -OPENCL_LIBSMM_SMM_PARAMS=0 ./acc_bench_smm 5 30000 13 5 7 -``` - -By supplying a CSV-file at runtime, embedded parameters and defaults are overriden, and given parameters are applied even if the current device is different from what would match the given parameters: - -```bash -cd src/acc -OPENCL_LIBSMM_SMM_PARAMS=opencl/smm/tune_multiply.csv ./acc_bench_smm 5 30000 13 5 7 -``` - -To tune multiple kernels in a convenient fashion, a triplet specification can be supplied to the [tune_multiply.sh](https://github.com/cp2k/dbcsr/blob/develop/src/acc/opencl/smm/tune_multiply.sh) wrapper script. This script estimates the total runtime for auto-tuning kernels, cleans up intermediate results (`opentuner.db`), allows to specify triplets, and splits work to auto-tune in parallel. - -Triplets are used to conveniently describe multiple kernels. A triplet specification consists of comma-separated groups of (M,N,K)-extents, i.e., matrix shapes according to GEMM. For example: - -```text -4 10 15, 6 7 8, 23 -``` - -This triplet specification expands to 55 kernels using the Cartesian product within each group and concatenating the result of such expanded groups followed by removing duplicate triplets. Further, the wrapper script allows to limit the time spent for tuning a single kernel and to partition the number of kernels to be tuned, e.g., among a cluster of eight systems (below the first partition out of eight would be processed with five minutes per kernel and about 35 minutes in total per partition). - -```bash -cd src/acc/opencl/smm -./tune_multiply.sh -t 300 -j 8 -i 1 4 10 15, 6 7 8, 23 -``` - -The script `tune_multiply.sh` is tuning 1266 kernels by default (`./tune_multiply.sh -t 300 -j 8 -i 1` takes approximately 13 hours per part). If the process is interrupted earlier (per SIGINT or Ctrl-C), the execution terminates for all requested kernels (triplet specification) unless `--continue` is given (or `-c`, or an environment variable `CONTINUE=1`). - -For convenience, it is possible to "update" an existing set of JSON-files (path can be given with `-p`), i.e., to parse the (M,N,K)-triplet denoted by the JSON filename and to re-tune with an almost unconstrained tuning-level (`-a 1` by default) as well as a limited duration (160 seconds per kernel by default). - -```bash -cd src/acc/opencl -make realclean -echo "Rebuild and embed smm/params/tune_multiply_P100.csv" -make WITH_GPU=P100 - -echo "Retune original parameters" -smm/tune_multiply.sh -p smm/params/p100 -u - -echo "Override original parameters" -cp tune_multiply.csv smm/params/tune_multiply_P100.csv -``` +# Auto Tuning -Tuning kernels further is only sensible if the previously tuned parameters are embedded into the binary (such that the process does not start from scratch). Retuned parameters are captured with JSON-files as usual. +To tune and optimize a kernel and generating kernel parameters, please refer to the [Auto Tuning](https://cp2k.github.io/dbcsr/develop/page/3-developer-guide/3-programming/2-accelerator-backend/3-libsmm_ocl/1-autotune.html) guide. To update or retune an entire set of kernels (optimized parameters), please refer to the [Bulk Tuning](https://cp2k.github.io/dbcsr/develop/page/3-developer-guide/3-programming/2-accelerator-backend/3-libsmm_ocl/2-bulktune.html) guide. diff --git a/src/acc/opencl/smm/kernels/multiply.cl b/src/acc/opencl/smm/kernels/multiply.cl index 1119bf50de7..bf02cce2ade 100644 --- a/src/acc/opencl/smm/kernels/multiply.cl +++ b/src/acc/opencl/smm/kernels/multiply.cl @@ -6,37 +6,16 @@ /* For further information please visit https://dbcsr.cp2k.org */ /* SPDX-License-Identifier: GPL-2.0+ */ /*------------------------------------------------------------------------------------------------*/ -#if (200 /*CL_VERSION_2_0*/ <= __OPENCL_VERSION__) || defined(__NV_CL_C_VERSION) -# define UNROLL_FORCE(N) __attribute__((opencl_unroll_hint(N))) -#else -# define UNROLL_FORCE(N) -#endif - -#define MIN(A, B) ((A) < (B) ? (A) : (B)) -#define MAX(A, B) ((A) < (B) ? (B) : (A)) - -#if defined(LU) && (0 <= LU || -1 != LU) -# if (0 == LU) -# define UNROLL_OUTER(N) UNROLL_FORCE(N) -# elif (1 <= LU) -# define UNROLL_OUTER(N) UNROLL_FORCE(MIN(LU, N)) -# else -# define UNROLL_OUTER(N) UNROLL_FORCE(N) -# endif -# define UNROLL(N) UNROLL_FORCE(N) -#else -# define UNROLL_OUTER(N) -# define UNROLL(N) -#endif +#include "../../common/opencl_atomics.h" #if !defined(AL) || (SM != SN) || (SM != BM) || (SN != SK) || (1 == BS) -# define ADX(M, K) adata[SM * K + M + a0] -# define BDX(K, N) bdata[SN * K + N + b0] -# define CDX(M, N) cdata[SM * N + M + c0] +# define ADX(M, K) adata[SM * K + M + a0] /* transposed */ +# define BDX(K, N) bdata[SN * K + N + b0] /* linear */ +# define CDX(M, N) cdata[SM * N + M + c0] /* transposed */ #else -# define ADX(M, K) adata[SK * M + K + a0] -# define BDX(K, N) bdata[SK * N + K + b0] -# define CDX(M, N) cdata[SN * M + N + c0] +# define ADX(M, K) adata[SK * M + K + a0] /* linear */ +# define BDX(K, N) bdata[SK * N + K + b0] /* transposed */ +# define CDX(M, N) cdata[SN * M + N + c0] /* linear */ #endif #if defined(SLM_A) @@ -57,7 +36,7 @@ #if defined(SLM_B) # define BNK(N, K) bnk[N][K] #elif defined(REG_B) -# if (BM < SM || 1 != BN) +# if (BM < SM && 1 != BN) # define BNK(N, K) bnk[N][K] # else # define BNK(N, K) bnk[K] @@ -65,18 +44,14 @@ #else # define BNK(N, K) BDX(K, N) #endif -#if (1 < BS) && (defined(SLM_C) || (BM < SM || 1 != BN)) +#if (1 < BS) && (defined(SLM_C) || (BM < SM && 1 != BN)) # define CNM(N, M) cnm[N][M] #else # define CNM(N, M) cnm[M] #endif -#if (1 == TN) -# define ZERO 0.f -#elif (3 == TN) -# define ZERO 0.0 -#else -# define ZERO 0 +#if !defined(SINT) /* covers matrix shape */ +# define SINT signed char #endif #if defined(SLM_P) && (1 < BS) @@ -95,113 +70,6 @@ #define UM (SM / BK) #define VM (SM % UM) -#define GLOBAL_VOLATILE(A) global volatile A -#if defined(ATOMIC_PROTOTYPES) || defined(__opencl_c_ext_fp64_global_atomic_add) -# if defined(__opencl_c_ext_fp64_global_atomic_add) -# undef ATOMIC_ADD_GLOBAL -# if defined(TF) -# define ATOMIC_ADD_GLOBAL(A, B) \ - atomic_fetch_add_explicit((GLOBAL_VOLATILE(TF)*)A, B, memory_order_relaxed, memory_scope_work_group) -# else -# define ATOMIC_ADD_GLOBAL(A, B) atomic_add(A, B) -# endif -# elif (2 < ATOMIC_PROTOTYPES) && defined(TF) -# undef ATOMIC_ADD_GLOBAL -# define ATOMIC_ADD_GLOBAL(A, B) \ - __opencl_atomic_fetch_add((GLOBAL_VOLATILE(TF)*)A, B, memory_order_relaxed, memory_scope_work_group) -# else -# if defined(TF) && (!defined(ATOMIC_PROTOTYPES) || 1 < ATOMIC_PROTOTYPES) -__attribute__((overloadable)) T atomic_fetch_add_explicit(GLOBAL_VOLATILE(TF) *, T, memory_order, memory_scope); -# else -__attribute__((overloadable)) T atomic_add(GLOBAL_VOLATILE(T) *, T); -# endif -# endif -#endif - -#if !defined(cl_intel_global_float_atomics) || (1 != TN) -# if defined(ATOMIC32_ADD64) -__attribute__((always_inline)) inline void atomic32_add64_global(GLOBAL_VOLATILE(double) * dst, double inc) { - *dst += inc; /* TODO */ -} -# endif - -# if defined(CMPXCHG) -__attribute__((always_inline)) inline void atomic_add_global_cmpxchg(GLOBAL_VOLATILE(T) * dst, T inc) { -# if !defined(ATOMIC32_ADD64) - union { - T f; - TA a; - } exp_val, try_val, cur_val = {.f = *dst}; - do { - exp_val.a = cur_val.a; - try_val.f = exp_val.f + inc; -# if defined(TA2) - if (0 == atomic_compare_exchange_weak_explicit((GLOBAL_VOLATILE(TA2)*)dst, &cur_val.a, try_val.a, memory_order_relaxed, - memory_order_relaxed, memory_scope_work_group)) - continue; -# else - cur_val.a = CMPXCHG((GLOBAL_VOLATILE(TA)*)dst, exp_val.a, try_val.a); -# endif - } while (cur_val.a != exp_val.a); -# else - atomic32_add64_global(dst, inc); -# endif -} -# endif - -# if defined(ATOMIC_ADD2_GLOBAL) && (1 == TN) -__attribute__((always_inline)) inline void atomic_add_global_cmpxchg2(GLOBAL_VOLATILE(float) * dst, float2 inc) { - union { - float2 f; - long a; - } exp_val, try_val, cur_val = {.f = (float2)(dst[0], dst[1])}; - do { - exp_val.a = cur_val.a; - try_val.f = exp_val.f + inc; -# if defined(TA2) - if (0 == atomic_compare_exchange_weak_explicit((GLOBAL_VOLATILE(atomic_long)*)dst, &cur_val.a, try_val.a, memory_order_relaxed, - memory_order_relaxed, memory_scope_work_group)) - continue; -# else - cur_val.a = atom_cmpxchg((GLOBAL_VOLATILE(long)*)dst, exp_val.a, try_val.a); -# endif - } while (cur_val.a != exp_val.a); -} -# endif - -# if defined(XCHG) || (defined(__NV_CL_C_VERSION) && !defined(CMPXCHG) && !defined(ATOMIC_PROTOTYPES)) -__attribute__((always_inline)) inline void atomic_add_global_xchg(GLOBAL_VOLATILE(T) * dst, T inc) { -# if !defined(ATOMIC32_ADD64) -# if (defined(__NV_CL_C_VERSION) && !defined(XCHG)) && (1 == TN) - asm("{ .reg .f32 t; atom.global.add.f32 t, [%0], %1; }" ::"l"(dst), "f"(inc)); -# elif (defined(__NV_CL_C_VERSION) && !defined(XCHG)) && (3 == TN) - asm("{ .reg .f64 t; atom.global.add.f64 t, [%0], %1; }" ::"l"(dst), "d"(inc)); -# else - union { - T f; - TA a; - } exp_val = {.f = inc}, try_val, cur_val = {/*.f = ZERO*/ .a = 0}; - do { -# if defined(TA2) - try_val.a = atomic_exchange_explicit((GLOBAL_VOLATILE(TA2)*)dst, cur_val.a, memory_order_relaxed, memory_scope_work_group); -# else - try_val.a = XCHG((GLOBAL_VOLATILE(TA)*)dst, cur_val.a); -# endif - try_val.f += exp_val.f; -# if defined(TA2) - exp_val.a = atomic_exchange_explicit((GLOBAL_VOLATILE(TA2)*)dst, try_val.a, memory_order_relaxed, memory_scope_work_group); -# else - exp_val.a = XCHG((GLOBAL_VOLATILE(TA)*)dst, try_val.a); -# endif - } while (cur_val.a != exp_val.a); -# endif -# else - atomic32_add64_global(dst, inc); -# endif -} -# endif -#endif - __attribute__((reqd_work_group_size(SWG, 1, 1))) #if (0 < SGS) @@ -233,17 +101,25 @@ FN(global T* restrict cdata, GLOBAL const T* restrict adata, GLOBAL const T* res T amk[SK]; #endif #if defined(SLM_B) - local T bnk[SN][SK + SLM_B - 1]; + local T bnk[SN][SK + SLM_B - 1]; /* tile */ #endif #if (BM < SM || 1 != BN) # if defined(REG_A) && !defined(SLM_A) && (1 == BK) T amk[BM]; # endif # if defined(REG_B) && !defined(SLM_B) - T bnk[BN][SK]; +# if (1 != BN) + T bnk[BN][SK]; /* rows */ +# else + T bnk[SK]; /* row */ +# endif # endif # if !defined(SLM_C) && (1 < BS) - T cnm[BN][BM]; +# if (1 != BN) + T cnm[BN][BM]; /* general tile */ +# else + T cnm[BM]; /* column-block */ +# endif # endif const int m0 = (idx / NBN) * BM, n0 = (idx % NBN) * BN; #else @@ -251,10 +127,10 @@ FN(global T* restrict cdata, GLOBAL const T* restrict adata, GLOBAL const T* res T amk[SM]; # endif # if defined(REG_B) && !defined(SLM_B) - T bnk[SK]; + T bnk[SK]; /* row */ # endif # if !defined(SLM_C) && (1 < BS) - T cnm[SM]; + T cnm[SM]; /* column */ # endif #endif #if defined(TRACK_B) && (1 < BS) && defined(REG_B) && !defined(SLM_B) @@ -266,32 +142,40 @@ FN(global T* restrict cdata, GLOBAL const T* restrict adata, GLOBAL const T* res const int batchsize = min(bs, stack_size - bs * gid); int c0; # if defined(SLM_C) - local T cnm[SN][SM + SLM_C - 1]; - for (short n = (short)idx; n < SN; n += SWG) { + local T cnm[SN][SM + SLM_C - 1]; /* tile in SLM */ + for (SINT n = (SINT)idx; n < SN; n += SWG) { UNROLL_FORCE(SM) - for (short m = 0; m < SM; ++m) cnm[n][m] = ZERO; + for (SINT m = 0; m < SM; ++m) cnm[n][m] = ZERO; } # elif (BM < SM || 1 != BN) +# if (1 != BN) UNROLL(BN) - for (short bn = 0; bn < BN; ++bn) { + for (SINT bn = 0; bn < BN; ++bn) +# endif + { UNROLL_FORCE(BM) - for (short bm = 0; bm < BM; ++bm) cnm[bn][bm] = ZERO; + for (SINT bm = 0; bm < BM; ++bm) CNM(bn, bm) = ZERO; } # else UNROLL_FORCE(SM) - for (short m = 0; m < SM; ++m) cnm[m] = ZERO; + for (SINT m = 0; m < SM; ++m) cnm[m] = ZERO; # endif # if defined(SLM_P) + UNROLL_FORCE(3 * BS) for (int i = idx; i < (3 * batchsize); i += SWG) params[i] = pbase[i] - 1; # endif # if defined(BARRIER) && (MAX(1, SGS) < SWG) && (defined(SLM_C) || defined(SLM_P)) BARRIER(CLK_LOCAL_MEM_FENCE); # endif # if (WRK < SWG) - if (WRK <= idx) return; + if (WRK <= idx) return; /* WRK <= idx */ # endif c0 = params[2] - IDXBASE; +# if defined(BSC) && (1 != BK) && (1 != UM) + UNROLL_OUTER(REPEAT * BS) +# else UNROLL_FORCE(1) +# endif # if (1 < REPEAT) for (int item = 0; item < (REPEAT * batchsize); ++item) { const int i = item % batchsize; @@ -303,21 +187,22 @@ FN(global T* restrict cdata, GLOBAL const T* restrict adata, GLOBAL const T* res const int c1 = ((i + 1) < batchsize ? (params[3 * i + 5] - IDXBASE) : -1); #else # if (WRK < SWG) - if (WRK > idx) + if (WRK > idx) /* WRK > idx */ # endif { const int a0 = params[0] - IDXBASE, b0 = params[1] - IDXBASE, c0 = params[2] - IDXBASE; #endif #if defined(SLM_A) && (1 != BK || BM < SM || 1 != BN) - /* copy or transpose A-matrix into SLM */ - int m = idx; + { /* copy or transpose A-matrix into SLM */ + int m = idx; # if (WRK != SM) - for (; m < SM; m += WRK) + for (; m < SM; m += WRK) # endif - { - UNROLL_FORCE(SK) - for (short k = 0; k < SK; ++k) amk[m][k] = ADX(m, k); + { + UNROLL_FORCE(SK) + for (SINT k = 0; k < SK; ++k) amk[m][k] = ADX(m, k); + } } #endif @@ -329,7 +214,7 @@ FN(global T* restrict cdata, GLOBAL const T* restrict adata, GLOBAL const T* res # endif { UNROLL(SK) - for (short k = 0; k < SK; ++k) bnk[n][k] = BDX(k, n); + for (SINT k = 0; k < SK; ++k) bnk[n][k] = BDX(k, n); } } #elif defined(REG_B) @@ -340,16 +225,20 @@ FN(global T* restrict cdata, GLOBAL const T* restrict adata, GLOBAL const T* res { /* copy or transpose B-matrix into registers */ # endif UNROLL(SK) - for (short k = 0; k < SK; ++k) { + for (SINT k = 0; k < SK; ++k) { # if (BM < SM || 1 != BN) + SINT bn = 0; +# if (1 != BN) UNROLL_FORCE(BN) - for (short bn = 0; bn < BN; ++bn) { + for (; bn < BN; ++bn) +# endif + { # if (SN % BN) const int n = min(bn + n0, SN - 1); # else const int n = bn + n0; # endif - bnk[bn][k] = BDX(k, n); + BNK(bn, k) = BDX(k, n); } # else bnk[k] = BDX(k, idx); @@ -367,107 +256,122 @@ FN(global T* restrict cdata, GLOBAL const T* restrict adata, GLOBAL const T* res { /* calculate result-tile using general tiles */ # if defined(REG_A) && !defined(SLM_A) && (1 != BK) # if (1 == BS) - T cnm[BN] = {ZERO}; + T cnm[BN] = {ZERO}; /* row */ # endif UNROLL(BM) - for (short bm = 0; bm < BM; ++bm) { - const int m = bm + m0; # if (SM % BM) - if (m < SM) + for (SINT bm = 0, m = m0; bm < BM && m < SM; m = ++bm + m0) +# else + for (SINT bm = 0, m = m0; bm < BM; m = ++bm + m0) +# endif + { /* general BK, A in registers */ + SINT bn = 0; + UNROLL_FORCE(SK) + for (SINT k = 0; k < SK; ++k) amk[k] = ADX(m, k); +# if (1 != BN) + UNROLL(BN) + for (; bn < BN; ++bn) # endif { - UNROLL_FORCE(SK) - for (short k = 0; k < SK; ++k) amk[k] = ADX(m, k); - UNROLL(BN) - for (short bn = 0; bn < BN; ++bn) { - const int n = bn + n0; +# if (SN % BN) || (defined(SLM_C) && (1 < BS)) || !defined(REG_B) + const int n = bn + n0; +# endif # if (SN % BN) - if (n < SN) + if (n < SN) /* n < SN */ # endif - { + { # if defined(SLM_C) && (1 < BS) - const int mc = m, nc = n; + const int mc = m, nc = n; # elif (1 < BS) - const int mc = bm, nc = bn; + const int mc = bm, nc = bn; # else - const int mc = bn, nc = idx; + const int mc = bn, nc = idx; # endif - UNROLL_FORCE(SK) - for (short k = 0; k < SK; ++k) { - CNM(nc, mc) = MAD(AMK(m, k), + UNROLL_FORCE(SK) + for (SINT k = 0; k < SK; ++k) { + CNM(nc, mc) = MAD(AMK(m, k), # if defined(REG_B) - BNK(bn, k), + BNK(bn, k), # else - BNK(n, k), + BNK(n, k), # endif - CNM(nc, mc)); - } + CNM(nc, mc)); } } + } # if (1 == BS) - UNROLL(BN) - for (short bn = 0; bn < BN; ++bn) { + bn = 0; +# if (1 != BN) + UNROLL(BN) + for (; bn < BN; ++bn) +# endif + { # if defined(ATOMIC_INC_NZ) - if (ZERO != CNM(idx, bn)) + if (ZERO != CNM(idx, bn)) # endif - { - ATOMIC_ADD_GLOBAL(&CDX(m, bn + n0), CNM(idx, bn)); - CNM(idx, bn) = ZERO; /* reset */ - } + { + ACCUMULATE(&CDX(m, bn + n0), CNM(idx, bn)); + CNM(idx, bn) = ZERO; /* reset */ } -# endif } +# endif } # elif (1 == BK) # if (1 == BS) - T cnm[BM] = {ZERO}; + T cnm[BM] = {ZERO}; /* column-block */ # endif UNROLL(SK) - for (short k = 0; k < SK; ++k) { + for (SINT k = 0; k < SK; ++k) { +# if (SN % BN) || !defined(REG_B) || (defined(SLM_C) && (1 < BS)) || (1 == BS) || (1 != BN) + SINT bn = 0; +# endif # if defined(REG_A) && !defined(SLM_A) UNROLL_FORCE(BM) - for (short bm = 0; bm < BM; ++bm) amk[bm] = ADX(bm + m0, k); + for (SINT bm = 0; bm < BM; ++bm) amk[bm] = ADX(bm + m0, k); # endif +# if (1 != BN) UNROLL(BN) - for (short bn = 0; bn < BN; ++bn) { + for (; bn < BN; ++bn) +# endif + { /* BK=1 */ +# if (SN % BN) || !defined(REG_B) || (defined(SLM_C) && (1 < BS)) || (1 == BS) const int n = bn + n0; +# endif # if (SN % BN) - if (n < SN) + if (n < SN) /* n < SN */ # endif { # if defined(REG_B) - const int nb = bn; + const T b = BNK(bn, k); # else - const int nb = n; + const T b = BNK(n, k); # endif UNROLL_FORCE(BM) - for (short bm = 0; bm < BM; ++bm) { - const int m = bm + m0; # if (SM % BM) - if (m < SM) -# endif - { -# if defined(SLM_C) && (1 < BS) - const int mc = m, nc = n; + for (SINT bm = 0, m = m0; bm < BM && m < SM; m = ++bm + m0) # else - const int mc = bm, nc = bn; + for (SINT bm = 0, m = m0; bm < BM; m = ++bm + m0) # endif + { # if defined(REG_A) && !defined(SLM_A) - const int ma = bm; + const T a = AMK(bm, k); # else - const int ma = m; + const T a = AMK(m, k); +# endif +# if defined(SLM_C) && (1 < BS) + CNM(n, m) = MAD(a, b, CNM(n, m)); +# else + CNM(bn, bm) = MAD(a, b, CNM(bn, bm)); # endif - CNM(nc, mc) = MAD(AMK(ma, k), BNK(nb, k), CNM(nc, mc)); - } } # if (1 == BS) UNROLL(BM) - for (short bm = 0; bm < BM; ++bm) { + for (SINT bm = 0; bm < BM; ++bm) { # if defined(ATOMIC_INC_NZ) if (ZERO != CNM(idx, bm)) # endif { - ATOMIC_ADD_GLOBAL(&CDX(bm + m0, n), CNM(idx, bm)); + ACCUMULATE(&CDX(bm + m0, n), CNM(idx, bm)); CNM(idx, bm) = ZERO; /* reset */ } } @@ -475,46 +379,59 @@ FN(global T* restrict cdata, GLOBAL const T* restrict adata, GLOBAL const T* res } } } -# else +# else /* general BK */ + SINT bn = 0; +# if (1 != BN) UNROLL(BN) - for (short bn = 0; bn < BN; ++bn) { + for (; bn < BN; ++bn) +# endif + { +# if (SN % BN) || !defined(REG_B) || (defined(SLM_C) && (1 < BS)) || (1 == BS) const int n = bn + n0; +# endif # if (SN % BN) - if (n < SN) + if (n < SN) /* n < SN */ # endif - { + { /* general BK */ # if (1 == BS) - T cnm[BM] = {ZERO}; -# endif -# if defined(REG_B) - const int nb = bn; -# else - const int nb = n; + T cnm[BM] = {ZERO}; /* column-block */ # endif UNROLL(BM) - for (short bm = 0; bm < BM; ++bm) { - const int m = bm + m0; # if (SM % BM) - if (m < SM) + for (SINT bm = 0, m = m0; bm < BM && m < SM; m = ++bm + m0) +# else + for (SINT bm = 0, m = m0; bm < BM; m = ++bm + m0) # endif - { + { # if defined(SLM_C) && (1 < BS) - const int mc = m, nc = n; +# if (1 < BS) && (defined(SLM_C) || (BM < SM && 1 != BN)) + const int mc = m, nc = n; +# else + const int mc = m; +# endif # else - const int mc = bm, nc = bn; +# if (1 < BS) && (defined(SLM_C) || (BM < SM && 1 != BN)) + const int mc = bm, nc = bn; +# else + const int mc = bm; +# endif # endif - UNROLL_FORCE(SK) - for (short k = 0; k < SK; ++k) CNM(nc, mc) = MAD(AMK(m, k), BNK(nb, k), CNM(nc, mc)); - } +# if defined(REG_B) + const int nb = bn; +# else + const int nb = n; +# endif + UNROLL_FORCE(SK) + for (SINT k = 0; k < SK; ++k) CNM(nc, mc) = MAD(AMK(m, k), BNK(nb, k), CNM(nc, mc)); } # if (1 == BS) UNROLL(BM) - for (short bm = 0; bm < BM; ++bm) { + for (SINT bm = 0; bm < BM; ++bm) { # if defined(ATOMIC_INC_NZ) if (ZERO != CNM(idx, bm)) # endif { - ATOMIC_ADD_GLOBAL(&CDX(bm + m0, n), CNM(idx, bm)); + ACCUMULATE(&CDX(bm + m0, n), CNM(idx, bm)); CNM(idx, bm) = ZERO; /* reset */ } } @@ -523,57 +440,61 @@ FN(global T* restrict cdata, GLOBAL const T* restrict adata, GLOBAL const T* res } # endif } -#else +#else /* BM == SM && 1 == BN */ { /* calculate result-tile using columns */ # if (1 == BS) - T cnm[UM] = {ZERO}; + T cnm[UM] = {ZERO}; /* column-block */ # endif # if (1 == BK) UNROLL_OUTER(SK) - for (short k = 0; k < SK; ++k) { + for (SINT k = 0; k < SK; ++k) { const T b = BNK(idx, k); # if defined(SLM_A) # if (WRK != SM) - for (short m = (short)idx; m < SM; m += WRK) amk[m] = ADX(m, k); + for (SINT m = (SINT)idx; m < SM; m += WRK) amk[m] = ADX(m, k); # else amk[idx] = ADX(idx, k); # endif # elif defined(REG_A) UNROLL_FORCE(SM) - for (short m = 0; m < SM; ++m) amk[m] = ADX(m, k); + for (SINT m = 0; m < SM; ++m) amk[m] = ADX(m, k); # endif # if defined(BARRIER) && (MAX(1, SGS) < SWG) && defined(SLM_A) BARRIER(CLK_LOCAL_MEM_FENCE); # endif -# if (WRK == SM) && (SGS >= SM) && !defined(SLM_A) && !defined(REG_A) +# if defined(ACC_OPENCL_VERSION) && (200 /*2.0*/ <= ACC_OPENCL_VERSION) && (!defined(GPU) || (0 != GPU)) && !defined(SLM_A) && \ + !defined(REG_A) && (WRK == SM) && (SM <= SGS || SM <= SWG) /* use ACC_OPENCL_VERSION rather than ACC_OPENCL_C_VERSION */ const T a = AMK(idx, k); -# endif UNROLL_FORCE(SM) - for (short m = 0; m < SM; ++m) { -# if (WRK == SM) && (SGS >= SM) && !defined(SLM_A) && !defined(REG_A) - CNM(idx, m) = MAD(sub_group_broadcast(a, m), b, CNM(idx, m)); + for (SINT m = 0; m < SM; ++m) { +# if (SM <= SGS) + CNM(idx, m) = MAD(sub_group_broadcast(a, m), b, CNM(idx, m)); /* size of subgroup is sufficient */ +# else + CNM(idx, m) = MAD(work_group_broadcast(a, m), b, CNM(idx, m)); /* size of workgroup is sufficient */ +# endif + } # else - CNM(idx, m) = MAD(AMK(m, k), b, CNM(idx, m)); + UNROLL_FORCE(SM) + for (SINT m = 0; m < SM; ++m) CNM(idx, m) = MAD(AMK(m, k), b, CNM(idx, m)); /* fallback */ # endif - } # if defined(BARRIER) && (MAX(1, SGS) < SWG) && defined(SLM_A) BARRIER(CLK_LOCAL_MEM_FENCE); # endif } # if (1 == BS) UNROLL(SM) - for (short m = 0; m < SM; ++m) { + for (SINT m = 0; m < SM; ++m) { # if defined(ATOMIC_INC_NZ) if (ZERO != CNM(idx, m)) # endif { - ATOMIC_ADD_GLOBAL(&CDX(m, idx), CNM(idx, m)); + ACCUMULATE(&CDX(m, idx), CNM(idx, m)); CNM(idx, m) = ZERO; /* reset */ } } # endif # else - int m = 0, u; + SINT m = 0, u; # if (1 == UM) UNROLL_OUTER(SM) # endif @@ -592,10 +513,10 @@ FN(global T* restrict cdata, GLOBAL const T* restrict adata, GLOBAL const T* res # endif # if defined(REG_A) && !defined(SLM_A) UNROLL_FORCE(SK) - for (short k = 0; k < SK; ++k) amk[k] = ADX(um, k); + for (SINT k = 0; k < SK; ++k) amk[k] = ADX(um, k); # endif UNROLL_FORCE(SK) - for (short k = 0; k < SK; ++k) { + for (SINT k = 0; k < SK; ++k) { CNM(idx, vm) = MAD(AMK(um, k), BNK(idx, k), CNM(idx, vm)); } } @@ -609,7 +530,7 @@ FN(global T* restrict cdata, GLOBAL const T* restrict adata, GLOBAL const T* res if (ZERO != CNM(idx, u)) # endif { - ATOMIC_ADD_GLOBAL(&CDX(u + m, idx), CNM(idx, u)); + ACCUMULATE(&CDX(u + m, idx), CNM(idx, u)); CNM(idx, u) = ZERO; /* reset */ } # endif @@ -630,10 +551,10 @@ FN(global T* restrict cdata, GLOBAL const T* restrict adata, GLOBAL const T* res # endif # if defined(REG_A) && !defined(SLM_A) UNROLL_FORCE(SK) - for (short k = 0; k < SK; ++k) amk[k] = ADX(um, k); + for (SINT k = 0; k < SK; ++k) amk[k] = ADX(um, k); # endif UNROLL_FORCE(SK) - for (short k = 0; k < SK; ++k) { + for (SINT k = 0; k < SK; ++k) { CNM(idx, vm) = MAD(AMK(um, k), BNK(idx, k), CNM(idx, vm)); } } @@ -647,7 +568,7 @@ FN(global T* restrict cdata, GLOBAL const T* restrict adata, GLOBAL const T* res if (ZERO != CNM(idx, u)) # endif { - ATOMIC_ADD_GLOBAL(&CDX(u + m, idx), CNM(idx, u)); + ACCUMULATE(&CDX(u + m, idx), CNM(idx, u)); CNM(idx, u) = ZERO; /* reset */ } # endif @@ -662,40 +583,50 @@ FN(global T* restrict cdata, GLOBAL const T* restrict adata, GLOBAL const T* res # endif # if (BM < SM || 1 != BN) { /* atomically commit C-tile to global memory */ + SINT bn = 0; +# if (1 != BN) UNROLL(BN) - for (short bn = 0; bn < BN; ++bn) { + for (; bn < BN; ++bn) +# endif + { const int n = bn + n0; # if (SN % BN) - if (n < SN) + if (n < SN) /* n < SN */ # endif { UNROLL_FORCE(BM) - for (short bm = 0; bm < BM; ++bm) { - const int m = bm + m0; # if (SM % BM) - if (m < SM) + for (SINT bm = 0, m = m0; bm < BM && m < SM; m = ++bm + m0) +# else + for (SINT bm = 0, m = m0; bm < BM; m = ++bm + m0) # endif - { + { # if defined(SLM_C) - const int mc = m, nc = n; +# if (1 < BS) && (defined(SLM_C) || (BM < SM && 1 != BN)) + const int mc = m, nc = n; +# else + const int mc = m; +# endif # else - const int mc = bm, nc = bn; -# endif -# if defined(ATOMIC_INC_NZ) - if (ZERO != CNM(nc, mc)) { +# if (1 < BS) && (defined(SLM_C) || (BM < SM && 1 != BN)) + const int mc = bm, nc = bn; +# else + const int mc = bm; +# endif # endif - ATOMIC_ADD_GLOBAL(&CDX(m, n), CNM(nc, mc)); - CNM(nc, mc) = ZERO; /* reset */ # if defined(ATOMIC_INC_NZ) - } + if (ZERO != CNM(nc, mc)) # endif + { + ACCUMULATE(&CDX(m, n), CNM(nc, mc)); + CNM(nc, mc) = ZERO; /* reset */ } } } } # else { /* atomically commit C-column to global memory */ - int m = 0; + SINT m = 0; # if defined(ATOMIC_ADD2_GLOBAL) for (; m < (SM - 1); m += 2) { # if defined(ATOMIC_INC_NZ) @@ -716,7 +647,7 @@ FN(global T* restrict cdata, GLOBAL const T* restrict adata, GLOBAL const T* res if (ZERO != CNM(idx, m)) # endif { - ATOMIC_ADD_GLOBAL(&CDX(m, idx), CNM(idx, m)); + ACCUMULATE(&CDX(m, idx), CNM(idx, m)); CNM(idx, m) = ZERO; /* reset */ } } @@ -725,6 +656,9 @@ FN(global T* restrict cdata, GLOBAL const T* restrict adata, GLOBAL const T* res /* next iteration */ c0 = c1; } +#endif +#if defined(BARRIER) && (MAX(1, SGS) < SWG) && defined(SLM_A) && (BM <= SM || 1 != BN || 1 != BK) + BARRIER(CLK_LOCAL_MEM_FENCE); #endif } } diff --git a/src/acc/opencl/smm/kernels/transpose.cl b/src/acc/opencl/smm/kernels/transpose.cl index 25b01128641..3e5bbc75a29 100644 --- a/src/acc/opencl/smm/kernels/transpose.cl +++ b/src/acc/opencl/smm/kernels/transpose.cl @@ -8,7 +8,7 @@ /*------------------------------------------------------------------------------------------------*/ __attribute__((reqd_work_group_size(SWG, 1, 1))) kernel void FN( - GLOBAL const int* restrict trs_stack, int trs_offset, global T* restrict matrix) { + int trs_offset, GLOBAL const int* restrict trs_stack, global T* restrict matrix) { /* offset in the transpose-stack that this block ID should handle */ const int offset = trs_stack[trs_offset + get_group_id(0)]; /* matrix according to the index (transpose-stack) */ diff --git a/src/acc/opencl/smm/opencl_libsmm.c b/src/acc/opencl/smm/opencl_libsmm.c index cbda4bf0acb..6089fe572bd 100644 --- a/src/acc/opencl/smm/opencl_libsmm.c +++ b/src/acc/opencl/smm/opencl_libsmm.c @@ -13,24 +13,19 @@ # include "../../acc_bench.h" # include -# if LIBXSMM_VERSION4(1, 17, 0, 0) < LIBXSMM_VERSION_NUMBER -# define OPENCL_LIBSMM_GEMM_BATCH(IPREC, OPREC, TRANSA, TRANSB, M, N, K, ALPHA, A, LDA, STRIDE_A, B, LDB, STRIDE_B, BETA, C, \ - LDC, STRIDE_C, INDEX_STRIDE, INDEX_BASE, BATCHSIZE) \ - OPENCL_LIBSMM_USEOMP(libxsmm_gemm_batch) \ - (IPREC, OPREC, TRANSA, TRANSB, M, N, K, ALPHA, A, LDA, STRIDE_A, B, LDB, STRIDE_B, BETA, C, LDC, STRIDE_C, INDEX_STRIDE, \ - INDEX_BASE, BATCHSIZE, 0 /*batchcheck*/) -# else -# define OPENCL_LIBSMM_GEMM_BATCH(IPREC, OPREC, TRANSA, TRANSB, M, N, K, ALPHA, A, LDA, STRIDE_A, B, LDB, STRIDE_B, BETA, C, \ - LDC, STRIDE_C, INDEX_STRIDE, INDEX_BASE, BATCHSIZE) \ - OPENCL_LIBSMM_USEOMP(libxsmm_gemm_batch) \ - ((libxsmm_gemm_precision)(IPREC), (libxsmm_gemm_precision)(OPREC), TRANSA, TRANSB, M, N, K, ALPHA, A, LDA, B, LDB, BETA, C, \ - LDC, INDEX_BASE, INDEX_STRIDE, STRIDE_A, STRIDE_B, STRIDE_C, BATCHSIZE) +# if !defined(OPENCL_KERNELS_SOURCE_TRANSPOSE) +# error "OpenCL transpose-kernel code not found!" +# endif +# if !defined(OPENCL_KERNELS_SOURCE_MULTIPLY) +# error "OpenCL SMM-kernel code not found!" # endif -# if defined(_OPENMP) && !defined(__DBCSR_ACC) -# define OPENCL_LIBSMM_USEOMP(FUNC) LIBXSMM_USEOMP(FUNC) +# if LIBXSMM_VERSION4(1, 17, 0, 0) < LIBXSMM_VERSION_NUMBER +# define OPENCL_LIBSMM_DESCINIT(BLOB, PREC, M, N, K, LDA, LDB, LDC, FLAGS, PREFETCH) \ + libxsmm_gemm_descriptor_init(BLOB, PREC, PREC, PREC, PREC, M, N, K, LDA, LDB, LDC, FLAGS, PREFETCH) # else -# define OPENCL_LIBSMM_USEOMP(FUNC) (FUNC) +# define OPENCL_LIBSMM_DESCINIT(BLOB, PREC, M, N, K, LDA, LDB, LDC, FLAGS, PREFETCH) \ + libxsmm_gemm_descriptor_dinit(BLOB, PREC, M, N, K, LDA, LDB, LDC, 1.0, 1.0, FLAGS, PREFETCH) # endif # if !defined(OPENCL_LIBSMM_VALIDATE_TRANS) && defined(OPENCL_LIBSMM_VALIDATE) && \ @@ -90,34 +85,15 @@ /* approximate arithmetic intensity for SMMs like C += Ai * Bi (beta=1) */ # define OPENCL_LIBSMM_AI(M, N, K, TYPESIZE) ((2.0 * (M) * (N) * (K)) / ((TYPESIZE) * (K) * ((M) + (N)))) - +/* determine type-size of a given type-ID */ # define OPENCL_LIBSMM_TYPESIZE(TYPEID) \ (dbcsr_type_real_8 == (TYPEID) ? ((int)sizeof(double)) : (dbcsr_type_real_4 == (TYPEID) ? ((int)sizeof(float)) : 0 /*unknown*/)) -# define OPENCL_LIBSMM_ISORT(IARR, SIZE) \ - { \ - int opencl_libsmm_isort_i_ = 0; \ - for (; opencl_libsmm_isort_i_ < ((int)(SIZE)-1); ++opencl_libsmm_isort_i_) { \ - int opencl_libsmm_isort_j_ = opencl_libsmm_isort_i_ + 2; \ - int opencl_libsmm_isort_k_ = opencl_libsmm_isort_i_ + 1; \ - for (; opencl_libsmm_isort_j_ < ((int)(SIZE)); ++opencl_libsmm_isort_j_) { \ - if ((IARR)[opencl_libsmm_isort_j_] < (IARR)[opencl_libsmm_isort_k_]) { \ - opencl_libsmm_isort_k_ = opencl_libsmm_isort_j_; \ - } \ - } \ - if ((IARR)[opencl_libsmm_isort_k_] < (IARR)[opencl_libsmm_isort_i_]) { \ - LIBXSMM_ISWAP((IARR)[opencl_libsmm_isort_i_], (IARR)[opencl_libsmm_isort_k_]); \ - } \ - } \ - } - # if defined(__cplusplus) extern "C" { # endif -/* maintain GFLOPS/AI ratios for performance estimates and suitability */ -double opencl_libsmm_shst, opencl_libsmm_dhst, opencl_libsmm_sacc, opencl_libsmm_dacc; /* track initialization status of LIBSMM */ int opencl_libsmm_initialized; @@ -138,7 +114,7 @@ int opencl_libsmm_use_cmem(cl_device_id device) { } -# if defined(_DEBUG) && defined(OPENCL_LIBSMM_VALIDATE) && (0 != OPENCL_LIBSMM_VALIDATE) +# if defined(OPENCL_LIBSMM_VALIDATE) && (0 != OPENCL_LIBSMM_VALIDATE) void opencl_libsmm_print_matrix(FILE* ostream, const char* label, libsmm_acc_data_t type, const void* mat, int m, int n) { int i, j; const char* const s = (NULL != label ? label : ""); @@ -152,8 +128,8 @@ void opencl_libsmm_print_matrix(FILE* ostream, const char* label, libsmm_acc_dat } for (j = 0; j < n; ++j) { switch (type) { - case dbcsr_type_real_8: fprintf(ostream, "%.2f ", ((double*)mat)[i * n + j]); break; - case dbcsr_type_real_4: fprintf(ostream, "%.2f ", ((float*)mat)[i * n + j]); break; + case dbcsr_type_real_8: fprintf(ostream, "%.2f ", ((const double*)mat)[i * n + j]); break; + case dbcsr_type_real_4: fprintf(ostream, "%.2f ", ((const float*)mat)[i * n + j]); break; default: fprintf(ostream, "? "); } } @@ -204,6 +180,7 @@ int opencl_libsmm_write_smm_params(FILE* stream, int only_key, const opencl_libs result += fprintf(stream, "%i%c%i%c%i%c%i%c %i%c%i%c %i%c%i%c%i%c %i%c%i%c %i%c%i%c%i%c%i", config->bs, d, config->bm, d, config->bn, d, config->bk, d, config->ws, d, config->wg, d, config->lu, d, config->nz, d, config->al, d, config->tb, d, config->tc, d, config->ap, d, config->aa, d, config->ab, d, config->ac); + if (0 != config->flags) result += fprintf(stream, "%c %i", d, config->flags); } } else { @@ -228,9 +205,8 @@ int opencl_libsmm_read_smm_params( char* parambuf, opencl_libsmm_smmkey_t* key, opencl_libsmm_smm_t* value, opencl_libsmm_perfest_t* perfest, char* device) { const char* const end = parambuf + strlen(parambuf); /* before strtok */ char* s = strtok(parambuf, ACC_OPENCL_DELIMS); - int result = EXIT_SUCCESS, i = 0, ivalue, consumed = 0, c = 0; const int opt_consumed = (NULL != perfest ? 2 : 0) + (NULL != device ? 1 : 0); - const int max_consumed = opt_consumed + 19; + int result = EXIT_SUCCESS, i = 0, ivalue, consumed = 0, c = 0, max_consumed = opt_consumed + 19; double gflops; assert(NULL != key && NULL != value); for (; NULL != s; @@ -368,6 +344,13 @@ int opencl_libsmm_read_smm_params( ++consumed; } break; + case 22: + if (1 == sscanf(s, "%i", &ivalue)) { + value->flags = ivalue; + ++max_consumed; + ++consumed; + } + break; default: s = NULL; /* break */ } } @@ -411,7 +394,7 @@ int libsmm_acc_init(void) { int result = EXIT_SUCCESS; # endif /* multiple calls to libsmm_acc_init are not considered as an error */ - if (1 == LIBXSMM_ATOMIC_ADD_FETCH(&opencl_libsmm_initialized, 1, LIBXSMM_ATOMIC_RELAXED)) { + if (1 == LIBXSMM_ATOMIC_ADD_FETCH(&opencl_libsmm_initialized, 1, ACC_OPENCL_ATOMIC)) { # if !defined(__DBCSR_ACC) /* DBCSR shall call c_dbcsr_acc_init as well as libsmm_acc_init (since both interfaces are used). * Also, libsmm_acc_init may privately call c_dbcsr_acc_init (as it depends on the ACC interface). @@ -424,17 +407,11 @@ int libsmm_acc_init(void) { if (EXIT_SUCCESS == result) { opencl_libsmm_perfest_t perfest; char* const env_params = getenv("OPENCL_LIBSMM_SMM_PARAMS"); - const char* const env_suitable = getenv("OPENCL_LIBSMM_SUITABLE"); -# if defined(OPENCL_LIBSMM_SUITABLE) - const int suitable = (NULL == env_suitable ? 1 : ('0' != *env_suitable)); -# else - const int suitable = (NULL == env_suitable ? 0 : ('0' != *env_suitable)); -# endif memset(&perfest, 0, sizeof(perfest)); if (NULL == env_params || '0' != *env_params) { char buffer[ACC_OPENCL_BUFFERSIZE], bufname[ACC_OPENCL_BUFFERSIZE], control = '0'; -# if defined(OPENCL_LIBSMM_DEVICES) - const int ndevices_params = (int)(sizeof(OPENCL_LIBSMM_DEVICES) / sizeof(*OPENCL_LIBSMM_DEVICES)); +# if defined(OPENCL_KERNELS_DEVICES) + const int ndevices_params = (int)(sizeof(OPENCL_KERNELS_DEVICES) / sizeof(*OPENCL_KERNELS_DEVICES)); unsigned int ntuned = 0; # endif opencl_libsmm_smm_t config; @@ -459,7 +436,7 @@ int libsmm_acc_init(void) { result = EXIT_FAILURE; break; } -# if defined(OPENCL_LIBSMM_DEVICES) +# if defined(OPENCL_KERNELS_DEVICES) else ++ntuned; # endif } @@ -469,7 +446,7 @@ int libsmm_acc_init(void) { } else { if (0 != c_dbcsr_acc_opencl_config.verbosity) { - fprintf(stderr, "WARN LIBSMM: failed to load tuned parameters!\n"); + fprintf(stderr, "WARN LIBSMM: failed to load tuned parameters from CSV-file!\n"); } break; /* invalid entry */ } @@ -483,25 +460,26 @@ int libsmm_acc_init(void) { } else control = '2'; } -# if defined(OPENCL_LIBSMM_PARAMS_SMM) && defined(OPENCL_LIBSMM_DEVICES) +# if defined(OPENCL_KERNELS_PARAMS_SMM) && defined(OPENCL_KERNELS_DEVICES) if (EXIT_SUCCESS == result && '1' != control) { - const char *line = OPENCL_LIBSMM_PARAMS_SMM, *next; + const char *line = OPENCL_KERNELS_PARAMS_SMM, *next; # if LIBXSMM_VERSION4(1, 17, 0, 0) < LIBXSMM_VERSION_NUMBER cl_device_id active_id = NULL; unsigned int active_uid; int active_match = -1; - if (EXIT_SUCCESS == c_dbcsr_acc_opencl_device(ACC_OPENCL_OMP_TID(), &active_id) && - EXIT_SUCCESS == c_dbcsr_acc_opencl_device_name( - active_id, bufname, ACC_OPENCL_BUFFERSIZE, NULL /*platform*/, 0 /*platform_maxlen*/) && + if (EXIT_SUCCESS == clGetContextInfo(c_dbcsr_acc_opencl_config.device.context, CL_CONTEXT_DEVICES, sizeof(cl_device_id), + &active_id, NULL) && + EXIT_SUCCESS == c_dbcsr_acc_opencl_device_name(active_id, bufname, ACC_OPENCL_BUFFERSIZE, NULL /*platform*/, + 0 /*platform_maxlen*/, /*cleanup*/ 1) && EXIT_SUCCESS == c_dbcsr_acc_opencl_device_uid(active_id, bufname, &active_uid)) { int i = 0, best = 0; for (; i < ndevices_params; ++i) { - const int score = libxsmm_strimatch(bufname, OPENCL_LIBSMM_DEVICES[i], NULL); + const int score = libxsmm_strimatch(bufname, OPENCL_KERNELS_DEVICES[i], NULL); unsigned int uid; if (best < score || ((best == score) && - EXIT_SUCCESS == c_dbcsr_acc_opencl_device_uid(NULL /*device*/, OPENCL_LIBSMM_DEVICES[i], &uid) && + EXIT_SUCCESS == c_dbcsr_acc_opencl_device_uid(NULL /*device*/, OPENCL_KERNELS_DEVICES[i], &uid) && uid == active_uid)) { active_match = i; @@ -523,7 +501,7 @@ int libsmm_acc_init(void) { opencl_libsmm_smm_t* config_init; const int i = atoi(bufname); if (0 >= ndevices_params || 0 == c_dbcsr_acc_opencl_config.devmatch || 0 > i || ndevices_params <= i || - EXIT_SUCCESS != c_dbcsr_acc_opencl_device_uid(NULL /*device*/, OPENCL_LIBSMM_DEVICES[i], &key.devuid)) + EXIT_SUCCESS != c_dbcsr_acc_opencl_device_uid(NULL /*device*/, OPENCL_KERNELS_DEVICES[i], &key.devuid)) { key.devuid = 0; } @@ -545,10 +523,10 @@ int libsmm_acc_init(void) { if (NULL == config_init && NULL != libxsmm_xregister(&key, sizeof(key), sizeof(config), &config)) { static int info = 0; if (0 == info && 0 != c_dbcsr_acc_opencl_config.verbosity && - EXIT_SUCCESS == c_dbcsr_acc_opencl_device_name( - active_id, bufname, ACC_OPENCL_BUFFERSIZE, NULL /*platform*/, 0 /*platform_maxlen*/)) + EXIT_SUCCESS == c_dbcsr_acc_opencl_device_name(active_id, bufname, ACC_OPENCL_BUFFERSIZE, NULL /*platform*/, + 0 /*platform_maxlen*/, /*cleanup*/ 0)) { - fprintf(stderr, "INFO ACC/OpenCL: PARAMS of \"%s\" used for \"%s\"\n", OPENCL_LIBSMM_DEVICES[i], bufname); + fprintf(stderr, "INFO ACC/LIBSMM: PARAMS of \"%s\" used for \"%s\"\n", OPENCL_KERNELS_DEVICES[i], bufname); info = 1; } } @@ -557,7 +535,7 @@ int libsmm_acc_init(void) { } else { if (0 != c_dbcsr_acc_opencl_config.verbosity) { - fprintf(stderr, "WARN LIBSMM: failed to load tuned parameters!\n"); + fprintf(stderr, "WARN LIBSMM: failed to load embedded parameters!\n"); } break; } @@ -573,7 +551,7 @@ int libsmm_acc_init(void) { key.devuid = 0; if (NULL != libxsmm_xregister(&key, sizeof(key), sizeof(config), &config)) { c_dbcsr_acc_opencl_config.devmatch = 0; /* disable device-match */ -# if defined(OPENCL_LIBSMM_DEVICES) +# if defined(OPENCL_KERNELS_DEVICES) ntuned = LIBXSMM_MAX(ntuned, 1); /* no destinction of overridden or new */ # endif } @@ -583,15 +561,15 @@ int libsmm_acc_init(void) { fprintf(stderr, "WARN LIBSMM: failed to open parameter file!\n"); } } -# if defined(OPENCL_LIBSMM_DEVICES) +# if defined(OPENCL_KERNELS_DEVICES) if (0 != c_dbcsr_acc_opencl_config.verbosity && 0 != ntuned) { - fprintf(stderr, "INFO ACC/OpenCL: PARAMS in %u set%s loaded targeting ", ntuned, 1 != ntuned ? "s" : ""); + fprintf(stderr, "INFO ACC/LIBSMM: PARAMS in %u set%s loaded targeting ", ntuned, 1 != ntuned ? "s" : ""); if (0 != c_dbcsr_acc_opencl_config.devmatch) { fprintf(stderr, "%i device%s\n", ndevices_params, 1 != ndevices_params ? "s" : ""); - if (1 < c_dbcsr_acc_opencl_config.verbosity || 0 > c_dbcsr_acc_opencl_config.verbosity) { + if (2 <= c_dbcsr_acc_opencl_config.verbosity || 0 > c_dbcsr_acc_opencl_config.verbosity) { unsigned int i = 0; for (; i < (unsigned int)ndevices_params; ++i) { - fprintf(stderr, "INFO ACC/OpenCL: PARAMS -> \"%s\"\n", OPENCL_LIBSMM_DEVICES[i]); + fprintf(stderr, "INFO ACC/LIBSMM: PARAMS -> \"%s\"\n", OPENCL_KERNELS_DEVICES[i]); } } } @@ -600,85 +578,6 @@ int libsmm_acc_init(void) { # endif } } - if (0 != suitable && EXIT_SUCCESS == result) { - const int stack_size = 30000, nrepeat = 100; - const int nc = LIBXSMM_MAX(stack_size / 16, 1), na = 10 * nc, nb = 10 * nc; - const int m = 8, n = 8, k = 8, mn = m * n, mk = m * k, kn = k * n; - const size_t scratch_size = /*stack*/ stack_size * 3 * sizeof(int) + - (/*a*/ na * mk + /*b*/ nb * kn + /*c*/ nc * mn) * /*max.typesize*/ sizeof(double) + - 3 * (LIBXSMM_ALIGNMENT - 1) /*alignments*/; - void* const scratch = libxsmm_aligned_scratch(scratch_size, LIBXSMM_ALIGNMENT); - int *const s = (int*)scratch, i; - libxsmm_timer_tickint start; - const char notrans = 'N'; - if (0 != perfest.scount && 0 < perfest.gf_ai_sratio_max) { - if (NULL != scratch) { - float* const a = (float*)LIBXSMM_UP2((uintptr_t)s + sizeof(int) * stack_size * 3, LIBXSMM_ALIGNMENT); - float* const b = (float*)LIBXSMM_UP2((uintptr_t)a + sizeof(float) * na * mk, LIBXSMM_ALIGNMENT); - float* const c = (float*)LIBXSMM_UP2((uintptr_t)b + sizeof(float) * nb * kn, LIBXSMM_ALIGNMENT); - const float alpha = 1, beta = 1; - init_stack(s, stack_size, 0 /*rnd_size*/, NULL /*rnd*/, mn, mk, kn, nc, na, nb); -# if defined(_OPENMP) -# pragma omp parallel -# endif - { -# if defined(_OPENMP) -# pragma omp for -# endif - for (i = 0; i < na; ++i) INIT_MAT(float, i + 42, &a[i * mk], m, k, 1.0 / (nc * na)); -# if defined(_OPENMP) -# pragma omp for -# endif - for (i = 0; i < nb; ++i) INIT_MAT(float, i + 24, &b[i * kn], k, n, 1.0 / (nc * nb)); - } - memset(c, 0, sizeof(float) * nc * mn); - start = libxsmm_timer_tick(); - for (i = 0; i < nrepeat; ++i) { - OPENCL_LIBSMM_GEMM_BATCH(LIBXSMM_DATATYPE_F32, LIBXSMM_DATATYPE_F32, ¬rans, ¬rans, m, n, k, &alpha, a, - &m /*lda*/, s + 0 /*stride_a*/, b, &k /*ldb*/, s + 1 /*stride_b*/, &beta, c, &m /*ldc*/, s + 2 /*stride_c*/, - sizeof(int) * 3, 1 /*index_base*/, stack_size); - } - opencl_libsmm_shst = 1E-9 * ((size_t)2 * m * n * k * stack_size * nrepeat) / - (libxsmm_timer_duration(start, libxsmm_timer_tick()) * OPENCL_LIBSMM_AI(m, n, k, sizeof(float))); - } - opencl_libsmm_sacc = (/*sqrt(perfest.gf_ai_sratio_max **/ - exp(perfest.gf_ai_sratio_sumlog / perfest.scount)); - } - if (0 != perfest.dcount && 0 < perfest.gf_ai_dratio_max) { - if (NULL != scratch) { - double* const a = (double*)LIBXSMM_UP2((uintptr_t)s + sizeof(int) * stack_size * 3, LIBXSMM_ALIGNMENT); - double* const b = (double*)LIBXSMM_UP2((uintptr_t)a + sizeof(double) * na * mk, LIBXSMM_ALIGNMENT); - double* const c = (double*)LIBXSMM_UP2((uintptr_t)b + sizeof(double) * nb * kn, LIBXSMM_ALIGNMENT); - const double alpha = 1, beta = 1; - init_stack(s, stack_size, 0 /*rnd_size*/, NULL /*rnd*/, mn, mk, kn, nc, na, nb); -# if defined(_OPENMP) -# pragma omp parallel -# endif - { -# if defined(_OPENMP) -# pragma omp for -# endif - for (i = 0; i < na; ++i) INIT_MAT(double, i + 42, &a[i * mk], m, k, 1.0 / (nc * na)); -# if defined(_OPENMP) -# pragma omp for -# endif - for (i = 0; i < nb; ++i) INIT_MAT(double, i + 24, &b[i * kn], k, n, 1.0 / (nc * nb)); - } - memset(c, 0, sizeof(double) * nc * mn); - start = libxsmm_timer_tick(); - for (i = 0; i < nrepeat; ++i) { - OPENCL_LIBSMM_GEMM_BATCH(LIBXSMM_DATATYPE_F64, LIBXSMM_DATATYPE_F64, ¬rans, ¬rans, m, n, k, &alpha, a, - &m /*lda*/, s + 0 /*stride_a*/, b, &k /*ldb*/, s + 1 /*stride_b*/, &beta, c, &m /*ldc*/, s + 2 /*stride_c*/, - sizeof(int) * 3, 1 /*index_base*/, stack_size); - } - opencl_libsmm_dhst = 1E-9 * ((size_t)2 * m * n * k * stack_size * nrepeat) / - (libxsmm_timer_duration(start, libxsmm_timer_tick()) * OPENCL_LIBSMM_AI(m, n, k, sizeof(double))); - } - opencl_libsmm_dacc = (/*sqrt(perfest.gf_ai_dratio_max **/ - exp(perfest.gf_ai_dratio_sumlog / perfest.dcount)); - } - libxsmm_free(scratch); - } } } ACC_OPENCL_RETURN(result); @@ -697,7 +596,7 @@ int libsmm_acc_finalize(void) { int result = EXIT_SUCCESS; # endif /* multiple calls to libsmm_acc_finalize are not considered as an error */ - if (0 == LIBXSMM_ATOMIC_SUB_FETCH(&opencl_libsmm_initialized, 1, LIBXSMM_ATOMIC_RELAXED)) { + if (0 == LIBXSMM_ATOMIC_SUB_FETCH(&opencl_libsmm_initialized, 1, ACC_OPENCL_ATOMIC)) { # if LIBXSMM_VERSION4(1, 17, 0, 0) < LIBXSMM_VERSION_NUMBER char fname[ACC_OPENCL_MAXSTRLEN]; const void* regentry = libxsmm_get_registry_begin(LIBXSMM_KERNEL_KIND_USER, NULL /*key*/); @@ -706,24 +605,23 @@ int libsmm_acc_finalize(void) { cl_kernel kernel = *(const cl_kernel*)regentry; if (NULL == kernel) kernel = ((const opencl_libsmm_smm_t*)regentry)->kernel[1]; if (NULL != kernel) { /* only consider user-entry if clGetKernelInfo succeeded */ - cl_int result_entry = clGetKernelInfo(kernel, CL_KERNEL_FUNCTION_NAME, sizeof(fname), fname, NULL); - if (CL_SUCCESS == result_entry) { + int result_entry = clGetKernelInfo(kernel, CL_KERNEL_FUNCTION_NAME, sizeof(fname), fname, NULL); + if (EXIT_SUCCESS == result_entry) { if (NULL != strstr(fname, OPENCL_LIBSMM_KERNELNAME_TRANS)) { /* trans-kernel */ result_entry = clReleaseKernel(kernel); } else if (NULL != strstr(fname, OPENCL_LIBSMM_KERNELNAME_SMM)) { /* SMM-kernel */ result_entry = clReleaseKernel(kernel); - if (CL_SUCCESS == result_entry && kernel != ((const opencl_libsmm_smm_t*)regentry)->kernel[1]) { + if (EXIT_SUCCESS == result_entry && kernel != ((const opencl_libsmm_smm_t*)regentry)->kernel[1]) { kernel = ((const opencl_libsmm_smm_t*)regentry)->kernel[1]; /* release 2nd kernel */ if (NULL != kernel) result_entry = clReleaseKernel(kernel); } } - if (CL_SUCCESS != result_entry) result = result_entry; + if (EXIT_SUCCESS != result_entry) result = result_entry; } } } # endif - opencl_libsmm_shst = opencl_libsmm_dhst = opencl_libsmm_sacc = opencl_libsmm_dacc = 0; # if !defined(__DBCSR_ACC) /* DBCSR shall call c_dbcsr_acc_init as well as libsmm_acc_init (since both interfaces are used). * Also, libsmm_acc_init may privately call c_dbcsr_acc_init (as it depends on the ACC interface). @@ -751,36 +649,35 @@ c_dbcsr_acc_bool_t libsmm_acc_is_thread_safe(void) { int libsmm_acc_transpose(const int* dev_trs_stack, int offset, int stack_size, void* dev_data, libsmm_acc_data_t datatype, int m, int n, int max_kernel_dim, void* stream) { + c_dbcsr_acc_opencl_info_memptr_t info_stack, info_mdata; int result = EXIT_SUCCESS; -# if !defined(OPENCL_LIBSMM_SOURCE_TRANSPOSE) - result = EXIT_FAILURE; -# else const int mn = m * n; - assert((NULL != dev_trs_stack && NULL != stream && NULL != dev_data && NULL != *ACC_OPENCL_MEM(dev_data) && 0 <= offset && - 0 <= stack_size) || - 0 == stack_size); - if (( -# if defined(OPENCL_LIBSMM_F64) + assert((NULL != dev_trs_stack && NULL != stream && NULL != dev_data && 0 <= offset && 0 <= stack_size) || 0 == stack_size); + result |= c_dbcsr_acc_opencl_info_devptr(&info_stack, dev_trs_stack, sizeof(int), NULL /*amount*/, NULL /*offset*/); + result |= c_dbcsr_acc_opencl_info_devptr(&info_mdata, dev_data, 1 /*elsize*/, NULL /*amount*/, NULL /*offset*/); + if (EXIT_SUCCESS == result && + ( +# if defined(OPENCL_LIBSMM_F64) dbcsr_type_real_8 == datatype -# else +# else 0 -# endif +# endif || -# if defined(OPENCL_LIBSMM_F32) +# if defined(OPENCL_LIBSMM_F32) dbcsr_type_real_4 == datatype -# else +# else 0 -# endif +# endif ) && 0 < stack_size && 1 < mn && m <= max_kernel_dim && n <= max_kernel_dim) { - const cl_command_queue queue = *ACC_OPENCL_STREAM(stream); + const c_dbcsr_acc_opencl_stream_t* const str = ACC_OPENCL_STREAM(stream); opencl_libsmm_trans_t* config; opencl_libsmm_transkey_t key; -# if !defined(OPENCL_LIBSMM_VALIDATE_TRANS) +# if !defined(OPENCL_LIBSMM_VALIDATE_TRANS) double duration; const libxsmm_timer_tickint start = libxsmm_timer_tick(); -# endif +# endif LIBXSMM_MEMZERO127(&key); /* potentially heterogeneous key-data (alignment gaps) */ key.type = datatype; key.m = m; @@ -792,24 +689,23 @@ int libsmm_acc_transpose(const int* dev_trs_stack, int offset, int stack_size, v int nchar = LIBXSMM_SNPRINTF(fname, sizeof(fname), /* kernel name are meant to be unambiguous (BLAS-typeprefix and kernelsize) */ "x" OPENCL_LIBSMM_KERNELNAME_TRANS "%ix%i", m, n); -# if defined(__DBCSR_ACC) +# if defined(__DBCSR_ACC) int routine_handle; c_dbcsr_timeset(LIBSMM_ACC_TRANSPOSE_ROUTINE_NAME_STRPTR, LIBSMM_ACC_TRANSPOSE_ROUTINE_NAME_LENPTR, &routine_handle); -# endif +# endif if (0 < nchar && (int)sizeof(fname) > nchar) { cl_device_id active_device; - result = clGetCommandQueueInfo(queue, CL_QUEUE_DEVICE, sizeof(cl_device_id), &active_device, NULL); - if (CL_SUCCESS == result) { - const char* const param_format = "-DGLOBAL=%s -DINPLACE=%i -DFN=%s -DSM=%i -DSN=%i -DSWG=%i -DT=%s"; + result = clGetCommandQueueInfo(str->queue, CL_QUEUE_DEVICE, sizeof(cl_device_id), &active_device, NULL); + if (EXIT_SUCCESS == result) { + const char *const env_cl = getenv("OPENCL_LIBSMM_TRANS_BUILDOPTS"), *const env_bm = getenv("OPENCL_LIBSMM_TRANS_BM"); const char* const cmem = (EXIT_SUCCESS != opencl_libsmm_use_cmem(active_device) ? "global" : "constant"); - const char *const env_options = getenv("OPENCL_LIBSMM_TRANS_BUILDOPTS"), *tname = ""; - const char* const env_inplace = getenv("OPENCL_LIBSMM_TRANS_INPLACE"); - const char* const env_bm = getenv("OPENCL_LIBSMM_TRANS_BM"); -# if defined(OPENCL_LIBSMM_TRANS_INPLACE) + const char* const param_format = "-DGLOBAL=%s -DINPLACE=%i -DFN=%s -DSM=%i -DSN=%i -DSWG=%i -DT=%s"; + const char *const env_inplace = getenv("OPENCL_LIBSMM_TRANS_INPLACE"), *tname = ""; +# if defined(OPENCL_LIBSMM_TRANS_INPLACE) const int inplace = ((m == n) && (NULL == env_inplace ? 1 : ('0' != *env_inplace))); -# else +# else const int inplace = ((m == n) && (NULL == env_inplace ? 0 : ('0' != *env_inplace))); -# endif +# endif const int blockm = ((NULL == env_bm || '\0' == *env_bm) ? 0 : atoi(env_bm)); const int bm = (0 >= blockm ? (NULL == config ? /*default*/ m : /*LIBXSMM_CLMP(config->bm, 1, m)*/ m) : LIBXSMM_MIN(blockm, m)); @@ -830,14 +726,14 @@ int libsmm_acc_transpose(const int* dev_trs_stack, int offset, int stack_size, v default: assert('\0' == *tname); } new_config.wgsize = LIBXSMM_MIN((size_t)((m == bm || 0 == (m % bm)) ? bm : m), wgsize_max); - nchar = LIBXSMM_SNPRINTF(buffer, sizeof(buffer), "%s", NULL == env_options ? "" : env_options); + nchar = LIBXSMM_SNPRINTF(buffer, sizeof(buffer), "%s", NULL == env_cl ? "" : env_cl); if (0 <= /*<*/ nchar && (int)sizeof(buffer) > nchar) { nchar = LIBXSMM_SNPRINTF( build_params, sizeof(build_params), param_format, cmem, inplace, fname, m, n, (int)new_config.wgsize, tname); } } if ('\0' != *tname && 0 < nchar && (int)sizeof(build_params) > nchar) { - result = c_dbcsr_acc_opencl_kernel(0 /*source_is_file*/, OPENCL_LIBSMM_SOURCE_TRANSPOSE, fname, build_params, buffer, + result = c_dbcsr_acc_opencl_kernel(0 /*source_is_file*/, OPENCL_KERNELS_SOURCE_TRANSPOSE, fname, build_params, buffer, NULL /*try*/, NULL /*try_ok*/, NULL /*extnames*/, 0 /*num_exts*/, &new_config.kernel); if (EXIT_SUCCESS == result) { result = c_dbcsr_acc_opencl_wgsize(active_device, new_config.kernel, &wgsize_max, NULL /*prefmult*/); @@ -848,18 +744,18 @@ int libsmm_acc_transpose(const int* dev_trs_stack, int offset, int stack_size, v nchar = LIBXSMM_SNPRINTF( build_params, sizeof(build_params), param_format, cmem, inplace, fname, m, n, (int)new_config.wgsize, tname); if (0 < nchar && (int)sizeof(build_params) > nchar) { - result = c_dbcsr_acc_opencl_kernel(0 /*source_is_file*/, OPENCL_LIBSMM_SOURCE_TRANSPOSE, fname, build_params, + result = c_dbcsr_acc_opencl_kernel(0 /*source_is_file*/, OPENCL_KERNELS_SOURCE_TRANSPOSE, fname, build_params, buffer, NULL /*try*/, NULL /*try_ok*/, NULL /*extnames*/, 0 /*num_exts*/, &new_config.kernel); } else result = EXIT_FAILURE; } if (EXIT_SUCCESS == result) { config = (opencl_libsmm_trans_t*)libxsmm_xregister(&key, sizeof(key), sizeof(new_config), &new_config); -# if !defined(OPENCL_LIBSMM_VALIDATE_TRANS) +# if !defined(OPENCL_LIBSMM_VALIDATE_TRANS) if (2 <= c_dbcsr_acc_opencl_config.verbosity || 0 > c_dbcsr_acc_opencl_config.verbosity) { LIBXSMM_STDIO_ACQUIRE(); duration = libxsmm_timer_duration(start, libxsmm_timer_tick()); - fprintf(stderr, "INFO ACC/OpenCL: TRANS-kernel "); + fprintf(stderr, "INFO ACC/LIBSMM: TRANS-kernel "); opencl_libsmm_write_trans_params( stderr, 0 /*only_key*/, &key, NULL /*config*/, NULL /*delim*/, NULL /*begin*/, NULL /*close*/); fprintf(stderr, "="); @@ -868,7 +764,7 @@ int libsmm_acc_transpose(const int* dev_trs_stack, int offset, int stack_size, v fprintf(stderr, " gen=%.1f ms\n", 1E3 * duration); LIBXSMM_STDIO_RELEASE(); } -# endif +# endif } } } @@ -881,9 +777,9 @@ int libsmm_acc_transpose(const int* dev_trs_stack, int offset, int stack_size, v else { result = EXIT_FAILURE; } -# if defined(__DBCSR_ACC) +# if defined(__DBCSR_ACC) c_dbcsr_timestop(&routine_handle); -# endif +# endif } assert((NULL != config && NULL != config->kernel && 0 < config->wgsize) || EXIT_SUCCESS != result); if (EXIT_SUCCESS == result) { @@ -893,13 +789,13 @@ int libsmm_acc_transpose(const int* dev_trs_stack, int offset, int stack_size, v : &event); const size_t work_size = config->wgsize * stack_size; const int typesize = OPENCL_LIBSMM_TYPESIZE(datatype); -# if defined(OPENCL_LIBSMM_VALIDATE_TRANS) +# if defined(OPENCL_LIBSMM_VALIDATE_TRANS) const int offset_stack_size = offset + stack_size; char *imat = NULL, *omat = NULL, *gold = NULL; void* scratch = NULL; int* stack = NULL; size_t data_size; - if (CL_SUCCESS == clGetMemObjectInfo(*ACC_OPENCL_MEM(dev_data), CL_MEM_SIZE, sizeof(size_t), &data_size, NULL)) { + if (EXIT_SUCCESS == clGetMemObjectInfo(info_mdata.memory, CL_MEM_SIZE, sizeof(size_t), &data_size, NULL)) { const size_t scratch_size = (sizeof(int) * offset_stack_size) /*stack*/ + data_size /*imat*/ + data_size /*omat*/ + (mn * typesize) /*gold*/ + 3 * (LIBXSMM_ALIGNMENT - 1) /*alignments*/; @@ -909,39 +805,38 @@ int libsmm_acc_transpose(const int* dev_trs_stack, int offset, int stack_size, v imat = (char*)LIBXSMM_UP2((uintptr_t)stack + sizeof(int) * offset_stack_size, LIBXSMM_ALIGNMENT); omat = (char*)LIBXSMM_UP2((uintptr_t)imat + data_size, LIBXSMM_ALIGNMENT); gold = (char*)LIBXSMM_UP2((uintptr_t)omat + data_size, LIBXSMM_ALIGNMENT); - ACC_OPENCL_CHECK( - c_dbcsr_acc_memcpy_d2h(dev_trs_stack, stack, sizeof(int) * offset_stack_size, stream), "transfer debug stack", result); - ACC_OPENCL_CHECK(c_dbcsr_acc_memcpy_d2h(dev_data, imat, data_size, stream), "transfer debug input", result); + ACC_OPENCL_CHECK(c_dbcsr_acc_memcpy_d2h(dev_trs_stack, stack, sizeof(int) * offset_stack_size, stream), + "transfer validation stack", result); + ACC_OPENCL_CHECK(c_dbcsr_acc_memcpy_d2h(dev_data, imat, data_size, stream), "transfer validation input", result); } else result = EXIT_FAILURE; } else { result = EXIT_FAILURE; } -# endif +# endif assert(!(OPENCL_LIBSMM_NLOCKS_TRANS & (OPENCL_LIBSMM_NLOCKS_TRANS - 1))); /* POT */ - { /* OpenCL is thread-safe except for clSetKernelArg and launching such shared kernel */ - static volatile int locks[OPENCL_LIBSMM_NLOCKS_TRANS]; -# if (1 < OPENCL_LIBSMM_NLOCKS_TRANS) + { /* calling clSetKernelArg/clEnqueueNDRangeKernel must be consistent */ + static ACC_OPENCL_ATOMIC_LOCKTYPE locks[OPENCL_LIBSMM_NLOCKS_TRANS]; +# if (1 < OPENCL_LIBSMM_NLOCKS_TRANS) const unsigned int hash = libxsmm_hash(&config->kernel, sizeof(cl_kernel), 25071975 /*seed*/); const unsigned int lidx = LIBXSMM_MOD2(hash, OPENCL_LIBSMM_NLOCKS_TRANS); - volatile int* const lock = locks + lidx; -# else - volatile int* const lock = locks; -# endif - /* calling clSetKernelArg must be consistent across host-threads */ - LIBXSMM_ATOMIC_ACQUIRE(lock, LIBXSMM_SYNC_NPAUSE, LIBXSMM_ATOMIC_RELAXED); - ACC_OPENCL_CHECK(clSetKernelArg(config->kernel, 0, sizeof(cl_mem), ACC_OPENCL_MEM(dev_trs_stack)), - "set batch-list argument of transpose kernel", result); + ACC_OPENCL_ATOMIC_LOCKTYPE* const lock = locks + lidx; +# else + ACC_OPENCL_ATOMIC_LOCKTYPE* const lock = locks; +# endif + ACC_OPENCL_ATOMIC_ACQUIRE(lock); ACC_OPENCL_CHECK( - clSetKernelArg(config->kernel, 1, sizeof(int), &offset), "set offset argument of transpose kernel", result); - ACC_OPENCL_CHECK(clSetKernelArg(config->kernel, 2, sizeof(cl_mem), ACC_OPENCL_MEM(dev_data)), + clSetKernelArg(config->kernel, 0, sizeof(int), &offset), "set offset argument of transpose kernel", result); + ACC_OPENCL_CHECK(c_dbcsr_acc_opencl_set_kernel_ptr(config->kernel, 1, info_stack.memory), + "set batch-list argument of transpose kernel", result); + ACC_OPENCL_CHECK(c_dbcsr_acc_opencl_set_kernel_ptr(config->kernel, 2, info_mdata.memory), "set matrix-data argument of transpose kernel", result); - ACC_OPENCL_CHECK(clEnqueueNDRangeKernel(queue, config->kernel, 1 /*work_dim*/, NULL /*offset*/, &work_size, &config->wgsize, - 0, NULL, perf_event), + ACC_OPENCL_CHECK(clEnqueueNDRangeKernel(str->queue, config->kernel, 1 /*work_dim*/, NULL /*offset*/, &work_size, + &config->wgsize, 0, NULL, perf_event), "launch transpose kernel", result); /* eventually update performance counters inside of locked region */ -# if !defined(OPENCL_LIBSMM_VALIDATE_TRANS) +# if !defined(OPENCL_LIBSMM_VALIDATE_TRANS) if (3 <= c_dbcsr_acc_opencl_config.verbosity || 0 > c_dbcsr_acc_opencl_config.verbosity) { if (NULL != perf_event) { cl_ulong begin = 0, end = 0; @@ -953,33 +848,31 @@ int libsmm_acc_transpose(const int* dev_trs_stack, int offset, int stack_size, v duration = 1E-9 * LIBXSMM_DELTA(begin, end); /* Nanoseconds->seconds */ } else { - clFinish(queue); + clFinish(str->queue); duration = libxsmm_timer_duration(start, libxsmm_timer_tick()); /* seconds */ } if (EXIT_SUCCESS == result) { const double membw = (1ULL * stack_size * (typesize * m * n)) / (duration * (1ULL << 30)); - const int* const priority = c_dbcsr_acc_opencl_stream_priority(stream); LIBXSMM_STDIO_ACQUIRE(); - fprintf(stderr, "INFO ACC/OpenCL: TRANS-kernel "); + fprintf(stderr, "INFO ACC/LIBSMM: TRANS-kernel "); opencl_libsmm_write_trans_params( stderr, 1 /*only_key*/, &key, NULL /*config*/, NULL /*delim*/, NULL /*begin*/, NULL /*close*/); fprintf(stderr, "="); opencl_libsmm_write_trans_params(stderr, 1 /*only_key*/, &key, config, NULL /*delim*/, NULL /*begin*/, NULL /*close*/); - fprintf(stderr, " prio=%i ss=%i cur=%.1f GB/s dur=%.2g ms\n", NULL != priority ? *priority : -1, stack_size, membw, - 1E3 * duration); + fprintf(stderr, " ss=%i cur=%.1f GB/s dur=%.2g ms\n", stack_size, membw, 1E3 * duration); LIBXSMM_STDIO_RELEASE(); } } -# endif - LIBXSMM_ATOMIC_RELEASE(lock, LIBXSMM_ATOMIC_RELAXED); +# endif + ACC_OPENCL_ATOMIC_RELEASE(lock); } -# if defined(OPENCL_LIBSMM_VALIDATE_TRANS) - ACC_OPENCL_CHECK(c_dbcsr_acc_memcpy_d2h(dev_data, omat, data_size, stream), "transfer debug test", result); -# endif -# if defined(OPENCL_LIBSMM_VALIDATE_TRANS) +# if defined(OPENCL_LIBSMM_VALIDATE_TRANS) + ACC_OPENCL_CHECK(c_dbcsr_acc_memcpy_d2h(dev_data, omat, data_size, stream), "transfer validation test", result); +# endif +# if defined(OPENCL_LIBSMM_VALIDATE_TRANS) ACC_OPENCL_CHECK(c_dbcsr_acc_stream_sync(stream), "sync stream", result); -# endif -# if defined(OPENCL_LIBSMM_VALIDATE_TRANS) +# endif +# if defined(OPENCL_LIBSMM_VALIDATE_TRANS) if (EXIT_SUCCESS == result) { int i, j; LIBXSMM_STDIO_ACQUIRE(); @@ -1006,30 +899,31 @@ int libsmm_acc_transpose(const int* dev_trs_stack, int offset, int stack_size, v n, max_kernel_dim, stream); } fprintf(stderr, " => ERROR\n"); -# if defined(_DEBUG) - opencl_libsmm_print_matrix(stderr, "orig = ", datatype, orig, m, n); - opencl_libsmm_print_matrix(stderr, "gold = ", datatype, gold, n, m); - opencl_libsmm_print_matrix(stderr, "test = ", datatype, test, n, m); - fprintf(stderr, "\n"); -# endif -# if defined(OPENCL_LIBSMM_VALIDATE_EXIT) + if (3 <= c_dbcsr_acc_opencl_config.verbosity || 0 > c_dbcsr_acc_opencl_config.verbosity) { + fprintf(stderr, "stackposition = %i (index=%llu)\n", i, (unsigned long long)index); + opencl_libsmm_print_matrix(stderr, "orig = ", datatype, orig, m, n); + opencl_libsmm_print_matrix(stderr, "gold = ", datatype, gold, n, m); + opencl_libsmm_print_matrix(stderr, "test = ", datatype, test, n, m); + fprintf(stderr, "\n"); + } +# if defined(OPENCL_LIBSMM_VALIDATE_EXIT) exit(EXIT_FAILURE); -# else +# else result = EXIT_FAILURE; break; -# endif +# endif } for (j = offset; j < i; ++j) { const size_t duplicate = stack[j]; if (index == duplicate) { fprintf(stderr, " => ERROR\n"); -# if defined(OPENCL_LIBSMM_VALIDATE_EXIT) +# if defined(OPENCL_LIBSMM_VALIDATE_EXIT) exit(EXIT_FAILURE); -# else +# else i = offset_stack_size; result = EXIT_FAILURE; break; -# endif +# endif } } } @@ -1039,10 +933,9 @@ int libsmm_acc_transpose(const int* dev_trs_stack, int offset, int stack_size, v LIBXSMM_STDIO_RELEASE(); } libxsmm_free(scratch); -# endif +# endif } } -# endif ACC_OPENCL_RETURN(result); } @@ -1050,7 +943,6 @@ int libsmm_acc_transpose(const int* dev_trs_stack, int offset, int stack_size, v c_dbcsr_acc_bool_t libsmm_acc_process_suitable( c_dbcsr_acc_bool_t def_mnk, libsmm_acc_data_t datatype, int stack_size, int m_max, int n_max, int k_max, int max_kernel_dim) { c_dbcsr_acc_bool_t result = 0; /* false */ - double hst = 0, acc = 0; if (0 < m_max && 0 < n_max && 0 < k_max && 0 < stack_size && 0 != def_mnk /*homogeneous*/ /* allow k_max to exceed max_kernel_dim, TODO: BLAS for large kernels (m,n) */ @@ -1059,16 +951,12 @@ c_dbcsr_acc_bool_t libsmm_acc_process_suitable( switch (datatype) { # if defined(OPENCL_LIBSMM_F64) case dbcsr_type_real_8: { - hst = opencl_libsmm_dhst; - acc = opencl_libsmm_dacc; - if (0 >= hst || 0 >= acc || hst < acc) result = 1; /* true */ + result = 1; /* true */ } break; # endif # if defined(OPENCL_LIBSMM_F32) case dbcsr_type_real_4: { - hst = opencl_libsmm_shst; - acc = opencl_libsmm_sacc; - if (0 >= hst || 0 >= acc || hst < acc) result = 1; /* true */ + result = 1; /* true */ } break; # endif default: assert(/*false*/ 0 == result); @@ -1083,19 +971,13 @@ c_dbcsr_acc_bool_t libsmm_acc_process_suitable( key.k = k_max; /* initialize key */ memset(&dummy, 0, sizeof(dummy)); /* mute warnings about potentially uninitialized data */ LIBXSMM_STDIO_ACQUIRE(); - fprintf(stderr, "INFO ACC/OpenCL: SMM-kernel "); + fprintf(stderr, "INFO ACC/LIBSMM: SMM-kernel "); opencl_libsmm_write_smm_params(stderr, 1 /*only_key*/, &key, NULL /*config*/, NULL /*delim*/, NULL /*begin*/, NULL /*close*/); fprintf(stderr, "="); opencl_libsmm_write_smm_params(stderr, 1 /*only_key*/, &key, &dummy, NULL /*delim*/, NULL /*begin*/, NULL /*close*/); fprintf(stderr, " ss=%i", stack_size); if (m_max <= max_kernel_dim && n_max <= max_kernel_dim) { - if (0 < hst && 0 < acc) { - const double ai = OPENCL_LIBSMM_AI(m_max, n_max, k_max, OPENCL_LIBSMM_TYPESIZE(datatype)); - fprintf(stderr, " hst=%.1f acc=%.1f GFLOPS/s is not suitable\n", ai * hst, ai * acc); - } - else { - fprintf(stderr, 0 != def_mnk ? " is ignored\n" : " is inhomogeneous\n"); - } + fprintf(stderr, 0 != def_mnk ? " is ignored\n" : " is inhomogeneous\n"); } else fprintf(stderr, " is too large\n"); LIBXSMM_STDIO_RELEASE(); @@ -1109,126 +991,79 @@ int libsmm_acc_process(const int* host_param_stack, const int* dev_param_stack, c_dbcsr_acc_bool_t def_mnk, void* stream, void* c_stream) { int result = EXIT_SUCCESS; const int nparams = 3; -# if !defined(OPENCL_LIBSMM_SOURCE_MULTIPLY) - result = EXIT_FAILURE; -# else LIBXSMM_UNUSED(c_stream); /* TODO */ - assert(0 == stack_size || (NULL != dev_a_data && NULL != *ACC_OPENCL_MEM(dev_a_data))); - assert(0 == stack_size || (NULL != dev_b_data && NULL != *ACC_OPENCL_MEM(dev_b_data))); - assert(0 == stack_size || (NULL != dev_c_data && NULL != *ACC_OPENCL_MEM(dev_c_data))); + assert(0 == stack_size || (NULL != dev_a_data && NULL != dev_b_data && NULL != dev_c_data)); assert(0 == stack_size || (NULL != host_param_stack && NULL != dev_param_stack)); assert(0 < nparams && 0 < max_kernel_dim && NULL != stream); assert(0 <= stack_size && 0 <= m_max && 0 <= n_max && 0 <= k_max); if (0 != libsmm_acc_process_suitable(def_mnk, datatype, stack_size, m_max, n_max, k_max, max_kernel_dim)) { + c_dbcsr_acc_opencl_info_memptr_t info_stack, info_adata, info_bdata, info_cdata; opencl_libsmm_smmkey_t key; -# if !defined(OPENCL_LIBSMM_VALIDATE_SMM) +# if !defined(OPENCL_LIBSMM_VALIDATE_SMM) double duration; const libxsmm_timer_tickint start = libxsmm_timer_tick(); -# endif - const c_dbcsr_acc_opencl_info_stream_t* const qinfo = c_dbcsr_acc_opencl_info_stream(stream); - const c_dbcsr_acc_opencl_device_t* const devinfo = c_dbcsr_acc_opencl_config.device + qinfo->tid; - const cl_command_queue queue = *ACC_OPENCL_STREAM(stream); +# endif + const c_dbcsr_acc_opencl_stream_t* const str = ACC_OPENCL_STREAM(stream); LIBXSMM_MEMZERO127(&key); /* potentially heterogeneous key-data */ key.devuid = ((1 != c_dbcsr_acc_opencl_config.devmatch && ((unsigned int)-1) != c_dbcsr_acc_opencl_config.devmatch) ? c_dbcsr_acc_opencl_config.devmatch - : devinfo->uid); + : c_dbcsr_acc_opencl_config.device.uid); key.type = datatype; key.m = m_max; key.n = n_max; key.k = k_max; - if (CL_SUCCESS == result) { - static volatile int locks[OPENCL_LIBSMM_NLOCKS_SMM]; /* OpenCL is thread-safe except for clSetKernelArg */ + result |= c_dbcsr_acc_opencl_info_devptr(&info_stack, dev_param_stack, sizeof(int), NULL /*amount*/, NULL /*offset*/); + result |= c_dbcsr_acc_opencl_info_devptr(&info_adata, dev_a_data, 1 /*elsize*/, NULL /*amount*/, NULL /*offset*/); + result |= c_dbcsr_acc_opencl_info_devptr(&info_bdata, dev_b_data, 1 /*elsize*/, NULL /*amount*/, NULL /*offset*/); + result |= c_dbcsr_acc_opencl_info_devptr(&info_cdata, dev_c_data, 1 /*elsize*/, NULL /*amount*/, NULL /*offset*/); + if (EXIT_SUCCESS == result) { + static ACC_OPENCL_ATOMIC_LOCKTYPE locks[OPENCL_LIBSMM_NLOCKS_SMM]; const char *const env_s = getenv("OPENCL_LIBSMM_SMM_S"), *const env_bs = getenv("OPENCL_LIBSMM_SMM_BS"); const int s = ((NULL == env_s || '\0' == *env_s) ? OPENCL_LIBSMM_SMM_S : atoi(env_s)); int kernel_idx = 0, bs = ((NULL == env_bs || '\0' == *env_bs) ? 0 : atoi(env_bs)); opencl_libsmm_smm_t* config; - volatile int* lock = locks; -# if (1 < OPENCL_LIBSMM_NLOCKS_SMM) + ACC_OPENCL_ATOMIC_LOCKTYPE* lock = locks; +# if (1 < OPENCL_LIBSMM_NLOCKS_SMM) assert(!(OPENCL_LIBSMM_NLOCKS_SMM & (OPENCL_LIBSMM_NLOCKS_SMM - 1))); /* POT */ lock += LIBXSMM_MOD2(libxsmm_hash(&key, sizeof(key), 25071975 /*seed*/), OPENCL_LIBSMM_NLOCKS_SMM); -# endif - LIBXSMM_ATOMIC_ACQUIRE(lock, LIBXSMM_SYNC_NPAUSE, LIBXSMM_ATOMIC_RELAXED); +# endif + ACC_OPENCL_ATOMIC_ACQUIRE(lock); /* calling clSetKernelArg/clEnqueueNDRangeKernel must be consistent */ config = (opencl_libsmm_smm_t*)libxsmm_xdispatch(&key, sizeof(key)); if (0 >= bs) bs = ((NULL != config && 0 < config->bs) ? config->bs : OPENCL_LIBSMM_DEFAULT_BS); /* determine kernel-kind (mini-batch vs. mini-kernel) */ if (1 == bs || 0 > s || (bs * s) > stack_size) kernel_idx = bs = 1; if (NULL == config || NULL == config->kernel[kernel_idx]) { - char buffer[ACC_OPENCL_BUFFERSIZE], build_params[ACC_OPENCL_BUFFERSIZE]; - char fname[ACC_OPENCL_MAXSTRLEN]; - int cl_level_major, nchar = LIBXSMM_SNPRINTF(fname, sizeof(fname), - /* kernel name are meant to be unambiguous (BLAS-typeprefix and kernelsize) */ - "x" OPENCL_LIBSMM_KERNELNAME_SMM "%ix%ix%i", m_max, n_max, k_max); - const char* extensions[] = {NULL, NULL}; + char buffer[ACC_OPENCL_BUFFERSIZE], build_params[ACC_OPENCL_BUFFERSIZE], fname[ACC_OPENCL_MAXSTRLEN]; + int nchar = LIBXSMM_SNPRINTF(fname, sizeof(fname), + /* kernel name are meant to be unambiguous (BLAS-typeprefix and kernelsize) */ + "x" OPENCL_LIBSMM_KERNELNAME_SMM "%ix%ix%i", m_max, n_max, k_max); cl_device_id active_device = NULL; - cl_device_type device_type = 0; -# if defined(__DBCSR_ACC) +# if defined(__DBCSR_ACC) int routine_handle; c_dbcsr_timeset(LIBSMM_ACC_PROCESS_ROUTINE_NAME_STRPTR, LIBSMM_ACC_PROCESS_ROUTINE_NAME_LENPTR, &routine_handle); -# endif +# endif result = ((0 < nchar && (int)sizeof(fname) > nchar) - ? clGetCommandQueueInfo(queue, CL_QUEUE_DEVICE, sizeof(cl_device_id), &active_device, NULL) + ? clGetCommandQueueInfo(str->queue, CL_QUEUE_DEVICE, sizeof(cl_device_id), &active_device, NULL) : EXIT_FAILURE); if (EXIT_SUCCESS == result) { - result = c_dbcsr_acc_opencl_device_level( - active_device, &cl_level_major, NULL /*level_minor*/, NULL /*cl_std*/, &device_type); - } - if (EXIT_SUCCESS == result) { - const char *tname = NULL, *atomic_type = ""; - int std_c11 = 0; + c_dbcsr_acc_opencl_atomic_fp_t tkind = c_dbcsr_acc_opencl_atomic_fp_no; + const char* tname = NULL; switch (datatype) { case dbcsr_type_real_8: { - extensions[0] = "cl_khr_fp64 cl_khr_int64_base_atomics cl_khr_int64_extended_atomics"; + tkind = c_dbcsr_acc_opencl_atomic_fp_64; tname = "double"; fname[0] = 'd'; - if (2 <= cl_level_major && EXIT_SUCCESS == c_dbcsr_acc_opencl_device_ext(active_device, extensions, 1)) { - atomic_type = "-DTA=long -DTA2=atomic_long -DTF=atomic_double"; - std_c11 = 1; - } - else { - extensions[0] = "cl_khr_fp64 cl_khr_int64_base_atomics"; - if (EXIT_SUCCESS == c_dbcsr_acc_opencl_device_ext(active_device, extensions, 1)) { - atomic_type = "-DTA=long"; - } - else { /* fallback */ - extensions[0] = "cl_khr_fp64 cl_khr_global_int32_base_atomics cl_khr_global_int32_extended_atomics"; - if (2 <= cl_level_major && EXIT_SUCCESS == c_dbcsr_acc_opencl_device_ext(active_device, extensions, 1)) { - atomic_type = "-DATOMIC32_ADD64 -DTA=int -DTA2=atomic_int -DTF=atomic_double"; - std_c11 = 1; - } - else { - extensions[0] = "cl_khr_fp64 cl_khr_global_int32_base_atomics"; - if (EXIT_SUCCESS == c_dbcsr_acc_opencl_device_ext(active_device, extensions, 1)) { - atomic_type = "-DATOMIC32_ADD64 -DTA=int"; - } - else tname = NULL; - } - } - } } break; case dbcsr_type_real_4: { - extensions[0] = "cl_khr_global_int32_base_atomics cl_khr_global_int32_extended_atomics"; - if (2 <= cl_level_major && EXIT_SUCCESS == c_dbcsr_acc_opencl_device_ext(active_device, extensions, 1)) { - extensions[1] = "cl_khr_int64_base_atomics cl_khr_int64_extended_atomics"; - atomic_type = "-DTA=int -DTA2=atomic_int -DTF=atomic_float"; - std_c11 = 1; - tname = "float"; - fname[0] = 's'; - } - else { - extensions[0] = "cl_khr_global_int32_base_atomics"; - if (EXIT_SUCCESS == c_dbcsr_acc_opencl_device_ext(active_device, extensions, 1)) { - extensions[1] = "cl_khr_int64_base_atomics"; - atomic_type = "-DTA=int"; - tname = "float"; - fname[0] = 's'; - } - } + tkind = c_dbcsr_acc_opencl_atomic_fp_32; + tname = "float"; + fname[0] = 's'; } break; default: assert(NULL == tname); } if (NULL != tname) { - const char* const env_devid = getenv("OPENCL_LIBSMM_SMM_DEVID"); - const unsigned int devuid = (NULL == env_devid || '\0' == *env_devid) ? devinfo->uid + const char *extensions[] = {NULL, NULL}, *const env_devid = getenv("OPENCL_LIBSMM_SMM_DEVID"); + const unsigned int devuid = (NULL == env_devid || '\0' == *env_devid) ? c_dbcsr_acc_opencl_config.device.uid : (unsigned int)strtoul(env_devid, NULL, 0); size_t wgsize_max, wgsize_prf, sgs = 0; opencl_libsmm_smm_t new_config; @@ -1248,7 +1083,15 @@ int libsmm_acc_process(const int* host_param_stack, const int* dev_param_stack, const char *const env_tb = getenv("OPENCL_LIBSMM_SMM_TB"), *const env_tc = getenv("OPENCL_LIBSMM_SMM_TC"); const char *const env_ap = getenv("OPENCL_LIBSMM_SMM_AP"), *const env_aa = getenv("OPENCL_LIBSMM_SMM_AA"); const char *const env_ab = getenv("OPENCL_LIBSMM_SMM_AB"), *const env_ac = getenv("OPENCL_LIBSMM_SMM_AC"); - const int blockm = ((NULL == env_bm || '\0' == *env_bm) ? 0 : atoi(env_bm)); + const char *const env_xf = getenv("OPENCL_LIBSMM_SMM_XF"), *const env_cl = getenv("OPENCL_LIBSMM_SMM_BUILDOPTS"); + const char* const intel_xf = "-cl-intel-256-GRF-per-thread"; + const int default_lu = (0 != c_dbcsr_acc_opencl_config.device.intel ? -1 : 0); + const int unroll = LIBXSMM_MAX(-2, (NULL == env_lu || '\0' == *env_lu) + ? (0 == kernel_idx ? (NULL == config ? default_lu : config->lu) : default_lu) + : atoi(env_lu)); /* populate only lower bound */ + const int blockm = ((NULL == env_bm || '\0' == *env_bm || 1 < unroll) /* 1= unroll ? 0 : LIBXSMM_UP(m_max / unroll, OPENCL_LIBSMM_VMIN)) + : atoi(env_bm)); const int blockn = ((NULL == env_bn || '\0' == *env_bn) ? 0 : atoi(env_bn)); const int blockk = ((NULL == env_bk || '\0' == *env_bk) ? 0 : atoi(env_bk)); const int wgmin = ((NULL == env_ws || '\0' == *env_ws) ? 0 : atoi(env_ws)); @@ -1259,8 +1102,8 @@ int libsmm_acc_process(const int* host_param_stack, const int* dev_param_stack, : LIBXSMM_MIN(OPENCL_LIBSMM_VMIN, m_max)) : 1); const int default_wg = (((0x0bd0 > devuid || 0x0bdb < devuid)) ? (0 == kernel_idx ? 0 : -2) : -1); - const int default_lu = (0 != devinfo->intel ? -1 : 0); int nbm, nbn; + new_config.lu = unroll; /* two defaults for new_config parameters: 1st - regular, 2nd - BS=1 kernel */ new_config.bm = (0 >= blockm ? (0 == kernel_idx ? (NULL == config ? LIBXSMM_MIN(OPENCL_LIBSMM_DEFAULT_BM, m_max) : LIBXSMM_CLMP(config->bm, 1, m_max)) @@ -1278,16 +1121,13 @@ int libsmm_acc_process(const int* host_param_stack, const int* dev_param_stack, : LIBXSMM_MIN(wgmin, n_max * m_max)); new_config.wg = LIBXSMM_CLMP( (NULL == env_wg || '\0' == *env_wg) ? (NULL == config ? default_wg : config->wg) : atoi(env_wg), -2, 2); - new_config.lu = LIBXSMM_MAX(-2, (NULL == env_lu || '\0' == *env_lu) - ? (0 == kernel_idx ? (NULL == config ? default_lu : config->lu) : default_lu) - : atoi(env_lu)); /* populate only lower bound */ new_config.nz = LIBXSMM_CLMP((NULL == env_nz || '\0' == *env_nz) ? (0 == kernel_idx ? (NULL == config ? /*default*/ 0 : config->nz) : /*default*/ 0) : atoi(env_nz), 0, 1); - new_config.al = LIBXSMM_CLMP((NULL == env_al || '\0' == *env_al) - ? (0 == kernel_idx ? (NULL == config ? /*default*/ 0 : config->al) : /*default*/ 0) - : atoi(env_al), + new_config.al = LIBXSMM_CLMP(/* bug: AL=1 */ + (NULL == env_al || '\0' == *env_al) ? 0 /*(0 == kernel_idx ? (NULL == config ? 0 : config->al) : 0)*/ + : atoi(env_al), 0, 1); new_config.tb = LIBXSMM_CLMP((NULL == env_tb || '\0' == *env_tb) ? (0 == kernel_idx ? (NULL == config ? /*default*/ 0 : config->tb) : /*default*/ 0) @@ -1305,23 +1145,32 @@ int libsmm_acc_process(const int* host_param_stack, const int* dev_param_stack, (NULL == env_aa || '\0' == *env_aa) ? (0 == kernel_idx ? (NULL == config ? /*default*/ default_aa : config->aa) : /*default*/ default_aa) : atoi(env_aa), - 0, 3); + 0, 2); new_config.ab = LIBXSMM_CLMP( (NULL == env_ab || '\0' == *env_ab) ? (0 == kernel_idx ? (NULL == config ? /*default*/ default_ab : config->ab) : /*default*/ default_ab) : atoi(env_ab), - 0, 3); + 0, 2); new_config.ac = LIBXSMM_CLMP( (NULL == env_ac || '\0' == *env_ac) ? (0 == kernel_idx ? (NULL == config ? /*default*/ default_ac : config->ac) : /*default*/ default_ac) : atoi(env_ac), - 0, 2); + 0, 1); + if (NULL == env_xf || '\0' == *env_xf) { + if (0 == c_dbcsr_acc_opencl_config.device.intel || CL_DEVICE_TYPE_GPU != c_dbcsr_acc_opencl_config.device.type || + NULL == env_cl || NULL == strstr(env_cl, intel_xf)) + { + new_config.flags = (NULL == config ? /*default*/ 0 : config->flags); + } + else new_config.flags = 1; + } + else new_config.flags = atoi(env_xf); if (0 >= new_config.s) new_config.s = stack_size; if (0 == kernel_idx || 1 >= new_config.bs) new_config.bs = bs; nbm = (m_max + new_config.bm - 1) / new_config.bm; nbn = (n_max + new_config.bn - 1) / new_config.bn; new_config.wgsize[kernel_idx] = LIBXSMM_MAX(nbm * nbn, new_config.ws); -# if LIBXSMM_VERSION4(1, 17, 0, 0) < LIBXSMM_VERSION_NUMBER +# if LIBXSMM_VERSION4(1, 17, 0, 0) < LIBXSMM_VERSION_NUMBER if (0 != new_config.wg) { const unsigned int limit = (unsigned int)LIBXSMM_MAX(wgsize_prf, OPENCL_LIBSMM_VLEN); unsigned int r = libxsmm_remainder( @@ -1357,7 +1206,7 @@ int libsmm_acc_process(const int* host_param_stack, const int* dev_param_stack, else wgsize_prf = r; } else -# endif +# endif { wgsize_prf = new_config.wgsize[kernel_idx]; } @@ -1366,16 +1215,18 @@ int libsmm_acc_process(const int* host_param_stack, const int* dev_param_stack, assert(1 <= bs && 0 < new_config.wgsize[kernel_idx] && 0 < wgsize_max && 0 < wgsize_prf); /* ensure minimum requested WG-size */ while ((nbm * nbn) < new_config.ws && (nbm < m_max || nbn < n_max)) { - if (nbn < n_max) { - ++nbn; - new_config.bn = (n_max + nbn - 1) / nbn; - } - else if (nbm < m_max) { - ++nbm; - new_config.bm = (m_max + nbm - 1) / nbm; - } + if (nbn < n_max) ++nbn; + else if (nbm < m_max) ++nbm; + } + if ((nbm * nbn) < new_config.ws) { + new_config.bn = (n_max + nbn - 1) / nbn; + new_config.bm = (m_max + nbm - 1) / nbm; new_config.wgsize[kernel_idx] = (2 > new_config.wg ? (nbm * nbn) : ((int)LIBXSMM_UP2POT(nbm * nbn))); } + else { /* reset */ + nbm = (m_max + new_config.bm - 1) / new_config.bm; + nbn = (n_max + new_config.bn - 1) / new_config.bn; + } /* limit WG-size to maximum WG-size */ while (wgsize_max < new_config.wgsize[kernel_idx] && (new_config.bm < m_max || new_config.bn < n_max)) { if (new_config.bn < n_max) { @@ -1390,127 +1241,44 @@ int libsmm_acc_process(const int* host_param_stack, const int* dev_param_stack, } if (new_config.wgsize[kernel_idx] <= wgsize_max) { /* SMMs can be potentially handled by device */ const char* const cmem = (EXIT_SUCCESS != opencl_libsmm_use_cmem(active_device) ? "global" : "constant"); - const char* const env_options = getenv("OPENCL_LIBSMM_SMM_BUILDOPTS"); - const char* const env_barrier = getenv("OPENCL_LIBSMM_SMM_BARRIER"); - const char* const env_atomics = getenv("OPENCL_LIBSMM_SMM_ATOMICS"); const char* const env_nrepeat = getenv("SMM_NREPEAT"); - const char *barrier_expr = NULL, *atomic_ops = ""; - const char *atomic_exp = NULL, *atomic_expr2 = ""; - if (NULL == env_barrier || '0' != *env_barrier) { - barrier_expr = ((0 != std_c11 && (0 == devinfo->intel || (CL_DEVICE_TYPE_CPU != device_type))) - ? "-D\"BARRIER(A)=work_group_barrier(A,memory_scope_work_group)\"" - : "-D\"BARRIER(A)=barrier(A)\""); - } - else barrier_expr = ""; /* no barrier */ - assert(NULL != barrier_expr); - if (NULL == env_atomics || '0' != *env_atomics) { - /* atomics_force: attempt to force atomics without confirmation */ - const int atomics_force = ((NULL == env_atomics || '\0' == *env_atomics) ? 0 : atoi(env_atomics)); - const int cl_nonv = (EXIT_SUCCESS != c_dbcsr_acc_opencl_device_vendor(active_device, "nvidia")); - if (NULL == env_atomics || '\0' == *env_atomics || 0 != atomics_force) { - cl_bitfield fp_atomics; - assert(dbcsr_type_real_8 == datatype || dbcsr_type_real_4 == datatype); - if (CL_SUCCESS == clGetDeviceInfo(active_device, - (cl_device_info)(dbcsr_type_real_8 == datatype ? 0x4232 : 0x4231), sizeof(cl_bitfield), - &fp_atomics, NULL) && - 0 != (/*add*/ (1 << 1) & fp_atomics)) - { - extensions[1] = "cl_ext_float_atomics"; - atomic_exp = (dbcsr_type_real_8 == datatype - ? "atomic_fetch_add_explicit((GLOBAL_VOLATILE(atomic_double)*)A,B," - "memory_order_relaxed,memory_scope_work_group)" - : "atomic_fetch_add_explicit((GLOBAL_VOLATILE(atomic_float)*)A,B," - "memory_order_relaxed,memory_scope_work_group)"); - } - else if ((0 != devinfo->intel && 0x4905 != devinfo->uid && 0 == devinfo->unified) || 0 != atomics_force) { - if ((0 != devinfo->intel && - (dbcsr_type_real_4 == datatype || (0x0bd0 <= devinfo->uid && 0x0bdb >= devinfo->uid))) || - (0 != atomics_force)) - { - if (0 == atomics_force && (0 == devinfo->intel || 0x0bd0 > devinfo->uid || 0x0bdb < devinfo->uid)) { - extensions[1] = "cl_intel_global_float_atomics"; - atomic_ops = "-Dcl_intel_global_float_atomics"; - } - else { - atomic_ops = ((0 == std_c11 && 2 > atomics_force) - ? "-DATOMIC_PROTOTYPES=1" - : (3 > atomics_force ? "-DATOMIC_PROTOTYPES=2" : "-DATOMIC_PROTOTYPES=3")); - } - atomic_exp = ((0 == std_c11 && 2 > atomics_force) ? "atomic_add(A,B)" - : "atomic_fetch_add_explicit((GLOBAL_VOLATILE(TF)*)A,B," - "memory_order_relaxed,memory_scope_work_group)"); - } - else { - atomic_exp = "atomic_add_global_cmpxchg(A,B)"; - atomic_ops = "-DCMPXCHG=atom_cmpxchg"; - } - } - else if (cl_nonv) { - if (NULL != extensions[1] && 1 < bs && 1 == new_config.bn && new_config.bm >= m_max && 0 == new_config.al && - (0 == (m_max & 1) || (0 == devinfo->intel /*&& cl_nonv*/)) /* TODO */ - && EXIT_SUCCESS == c_dbcsr_acc_opencl_device_ext(active_device, extensions + 1, 1)) - { - assert(dbcsr_type_real_4 == datatype); - atomic_expr2 = "-D\"ATOMIC_ADD2_GLOBAL(A,B)=atomic_add_global_cmpxchg2(A,B)\""; - } - else { - extensions[1] = NULL; - } - atomic_exp = "atomic_add_global_cmpxchg(A,B)"; - atomic_ops = (dbcsr_type_real_4 == datatype ? "-DCMPXCHG=atomic_cmpxchg" : "-DCMPXCHG=atom_cmpxchg"); - } - else { - assert(NULL != atomic_ops && '\0' == *atomic_ops); - atomic_exp = "atomic_add_global_xchg(A,B)"; - } - } - else if (NULL != LIBXSMM_STRISTR(env_atomics, "cmpxchg")) { - if (NULL != extensions[1] && 1 < bs && 1 == new_config.bn && new_config.bm >= m_max && 0 == new_config.al && - (0 == (m_max & 1) || (0 == devinfo->intel && cl_nonv)) /* TODO */ - && '2' == env_atomics[strlen(env_atomics) - 1] && - EXIT_SUCCESS == c_dbcsr_acc_opencl_device_ext(active_device, extensions + 1, 1)) - { - assert(dbcsr_type_real_4 == datatype); - atomic_expr2 = "-D\"ATOMIC_ADD2_GLOBAL(A,B)=atomic_add_global_cmpxchg2(A,B)\""; - } - else { - extensions[1] = NULL; - } - atomic_exp = "atomic_add_global_cmpxchg(A,B)"; - atomic_ops = (dbcsr_type_real_4 == datatype ? "-DCMPXCHG=atomic_cmpxchg" : "-DCMPXCHG=atom_cmpxchg"); - } - else { - atomic_exp = "atomic_add_global_xchg(A,B)"; - atomic_ops = (dbcsr_type_real_4 == datatype ? "-DXCHG=atomic_xchg" : "-DXCHG=atom_xchg"); - } - } - else { /* unsynchronized */ - assert(NULL != env_atomics); - atomic_exp = "*(A)+=(B)"; /* non-atomic update */ - } - assert(NULL != atomic_exp); + const int typesize = OPENCL_LIBSMM_TYPESIZE(datatype); + const int slm_a = (1 != new_config.aa ? 0 : (LIBXSMM_ISPOT(k_max * typesize) + 1)); + const int slm_b = (1 != new_config.ab ? 0 : (LIBXSMM_ISPOT(k_max * typesize) + 1)); + const int slm_c = (1 != new_config.ac ? 0 : (LIBXSMM_ISPOT(m_max * typesize) + 1)); /* compose build parameters and flags */ nchar = LIBXSMM_SNPRINTF(build_params, sizeof(build_params), - "-DMAD=fma -DINTEL=%u -DGLOBAL=%s -DSWG=%i -DSGS=%i -DFN=%s -DREPEAT=%i -DLU=%i " - "-DSM=%i -DSN=%i -DSK=%i -DBS=%i -DBM=%i -DBN=%i -DBK=%i -DT=%s -DTN=%i " - "%s %s %s %s %s %s %s %s %s %s -D\"ATOMIC_ADD_GLOBAL(A,B)=%s\" %s %s", - 0 != devinfo->intel ? devinfo->uid : 0, cmem, (int)new_config.wgsize[kernel_idx], (int)sgs, fname, - NULL == env_nrepeat ? 1 : atoi(env_nrepeat), new_config.lu, m_max, n_max, k_max, bs, new_config.bm, new_config.bn, - new_config.bk, tname, datatype, 0 == new_config.nz ? "" : "-DATOMIC_INC_NZ", 0 == new_config.al ? "" : "-DAL", - 0 == new_config.tb ? "" : "-DTRACK_B", 0 != new_config.tc ? "-DTRACK_C" : "", 0 == new_config.ap ? "" : "-DSLM_P", - 0 == new_config.aa ? "" : (1 == new_config.aa ? "-DSLM_A=1" : (2 == new_config.aa ? "-DSLM_A=2" : "-DREG_A")), - 0 == new_config.ab ? "" : (1 == new_config.ab ? "-DSLM_B=1" : (2 == new_config.ab ? "-DSLM_B=2" : "-DREG_B")), - 0 == new_config.ac ? "" : (1 == new_config.ac ? "-DSLM_C=1" : "-DSLM_C=2"), atomic_type, atomic_ops, atomic_exp, - atomic_expr2, barrier_expr); + "-DT=%s -DGPU=%u -DGLOBAL=%s -DSWG=%i -DSGS=%i -DFN=%s -DREPEAT=%i -DLU=%i " + "-DSM=%i -DSN=%i -DSK=%i -DBS=%i -DVL=%i %s -DBM=%i -DBN=%i -DBK=%i " + "%s %s %s %s %s %s %s %s ", /* space! */ + tname, CL_DEVICE_TYPE_GPU == c_dbcsr_acc_opencl_config.device.type, cmem, (int)new_config.wgsize[kernel_idx], + (int)sgs, fname, NULL == env_nrepeat ? 1 : atoi(env_nrepeat), new_config.lu, m_max, n_max, k_max, bs, + OPENCL_LIBSMM_VMIN, bs == new_config.bs ? "-DBSC" : "", new_config.bm, new_config.bn, new_config.bk, + 0 == new_config.tb ? "" : "-DTRACK_B", 0 != new_config.tc ? "-DTRACK_C" : "", + 0 == new_config.nz ? "" : "-DATOMIC_INC_NZ", 0 == new_config.al ? "" : "-DAL", + 0 == new_config.ap ? "" : "-DSLM_P", + 0 == new_config.aa ? "" : (1 == slm_a ? "-DSLM_A=1" : (0 != slm_a ? "-DSLM_A=2" : "-DREG_A")), + 0 == new_config.ab ? "" : (1 == slm_b ? "-DSLM_B=1" : (0 != slm_b ? "-DSLM_B=2" : "-DREG_B")), + 0 == new_config.ac ? "" : (1 == slm_c ? "-DSLM_C=1" : "-DSLM_C=2")); + /* apply support for FP-atomics */ if (0 < nchar && (int)sizeof(build_params) > nchar) { -# if !defined(NDBGDEV) - const char* const cl_debug = ((0 != devinfo->intel && CL_DEVICE_TYPE_CPU != device_type) ? "-gline-tables-only" - : ""); -# else - const char* const cl_debug = ""; -# endif - nchar = LIBXSMM_SNPRINTF(buffer, sizeof(buffer), "%s %s -cl-fast-relaxed-math -cl-denorms-are-zero", - NULL == env_options ? "" : env_options, cl_debug); + nchar = c_dbcsr_acc_opencl_flags_atomics(&c_dbcsr_acc_opencl_config.device, tkind, extensions, + sizeof(extensions) / sizeof(*extensions), build_params + nchar, sizeof(build_params) - nchar); + } + else result = EXIT_FAILURE; + if (0 < nchar && (int)sizeof(build_params) > nchar) { + const char* const cl_debug = ((0 != c_dbcsr_acc_opencl_config.debug && + 0 != c_dbcsr_acc_opencl_config.device.intel && + CL_DEVICE_TYPE_CPU != c_dbcsr_acc_opencl_config.device.type) + ? "-gline-tables-only" + : ""); + nchar = LIBXSMM_SNPRINTF(buffer, sizeof(buffer), "%s %s %s %s", + (0 == new_config.flags || 0 == c_dbcsr_acc_opencl_config.device.intel || + CL_DEVICE_TYPE_GPU != c_dbcsr_acc_opencl_config.device.type) + ? "" + : intel_xf, + cl_debug, 0 == c_dbcsr_acc_opencl_config.debug ? "-cl-fast-relaxed-math -cl-denorms-are-zero" : "", + NULL == env_cl ? "" : env_cl); if (0 >= nchar || (int)sizeof(buffer) <= nchar) result = EXIT_FAILURE; } else result = EXIT_FAILURE; @@ -1521,7 +1289,7 @@ int libsmm_acc_process(const int* host_param_stack, const int* dev_param_stack, if (EXIT_SUCCESS == result) { const char* const env_kernel = getenv("OPENCL_LIBSMM_SMM_KERNEL"); result = c_dbcsr_acc_opencl_kernel(NULL == env_kernel ? 0 : 1, - NULL == env_kernel ? OPENCL_LIBSMM_SOURCE_MULTIPLY : env_kernel, fname, build_params, buffer, NULL /*cl_try*/, + NULL == env_kernel ? OPENCL_KERNELS_SOURCE_MULTIPLY : env_kernel, fname, build_params, buffer, NULL /*cl_try*/, NULL /*cl_try_ok*/, extensions, sizeof(extensions) / sizeof(*extensions), new_config.kernel + kernel_idx); if (EXIT_SUCCESS == result) { size_t wgsize_max_kernel = wgsize_max; @@ -1535,11 +1303,11 @@ int libsmm_acc_process(const int* host_param_stack, const int* dev_param_stack, config = (opencl_libsmm_smm_t*)libxsmm_xregister(&key, sizeof(key), sizeof(new_config), &new_config); } if (NULL != config) { -# if !defined(OPENCL_LIBSMM_VALIDATE_SMM) +# if !defined(OPENCL_LIBSMM_VALIDATE_SMM) if (2 <= c_dbcsr_acc_opencl_config.verbosity || 0 > c_dbcsr_acc_opencl_config.verbosity) { LIBXSMM_STDIO_ACQUIRE(); duration = libxsmm_timer_duration(start, libxsmm_timer_tick()); - fprintf(stderr, "INFO ACC/OpenCL: SMM-kernel "); + fprintf(stderr, "INFO ACC/LIBSMM: SMM-kernel "); opencl_libsmm_write_smm_params( stderr, 0 /*only_key*/, &key, NULL /*config*/, NULL /*delim*/, NULL /*begin*/, NULL /*close*/); fprintf(stderr, "="); @@ -1548,7 +1316,7 @@ int libsmm_acc_process(const int* host_param_stack, const int* dev_param_stack, fprintf(stderr, " gen=%.1f ms\n", 1E3 * duration); LIBXSMM_STDIO_RELEASE(); } -# endif +# endif } /* failed to register config */ else result = EXIT_FAILURE; @@ -1562,6 +1330,19 @@ int libsmm_acc_process(const int* host_param_stack, const int* dev_param_stack, } } } +# if defined(NDEBUG) + else if (2 <= c_dbcsr_acc_opencl_config.verbosity || 0 > c_dbcsr_acc_opencl_config.verbosity) { + LIBXSMM_STDIO_ACQUIRE(); + fprintf(stderr, "WARNING: SMM-kernel "); + opencl_libsmm_write_smm_params( + stderr, 0 /*only_key*/, &key, NULL /*config*/, NULL /*delim*/, NULL /*begin*/, NULL /*close*/); + fprintf(stderr, "="); + opencl_libsmm_write_smm_params( + stderr, 0 /*only_key*/, &key, &new_config, NULL /*delim*/, NULL /*begin*/, NULL /*close*/); + fprintf(stderr, " failed to compile!\n"); + LIBXSMM_STDIO_RELEASE(); + } +# endif } } /* insufficient device capabilities */ @@ -1571,9 +1352,9 @@ int libsmm_acc_process(const int* host_param_stack, const int* dev_param_stack, if (EXIT_SUCCESS != result && NULL != config) { libxsmm_xrelease(&key, sizeof(key)); } -# if defined(__DBCSR_ACC) +# if defined(__DBCSR_ACC) c_dbcsr_timestop(&routine_handle); -# endif +# endif } assert(EXIT_SUCCESS != result || (NULL != config && NULL != config->kernel[kernel_idx])); assert(EXIT_SUCCESS != result || (1 <= config->bm && config->bm <= m_max)); @@ -1587,9 +1368,9 @@ int libsmm_acc_process(const int* host_param_stack, const int* dev_param_stack, assert(EXIT_SUCCESS != result || (0 <= config->tb && 1 >= config->tb)); assert(EXIT_SUCCESS != result || (0 <= config->tc && 1 >= config->tc)); assert(EXIT_SUCCESS != result || (0 <= config->ap && 1 >= config->ap)); - assert(EXIT_SUCCESS != result || (0 <= config->aa && 3 >= config->aa)); - assert(EXIT_SUCCESS != result || (0 <= config->ab && 3 >= config->ab)); - assert(EXIT_SUCCESS != result || (0 <= config->ac && 2 >= config->ac)); + assert(EXIT_SUCCESS != result || (0 <= config->aa && 2 >= config->aa)); + assert(EXIT_SUCCESS != result || (0 <= config->ab && 2 >= config->ab)); + assert(EXIT_SUCCESS != result || (0 <= config->ac && 1 >= config->ac)); assert(EXIT_SUCCESS != result || (1 <= config->wgsize[kernel_idx])); assert(EXIT_SUCCESS != result || (1 <= config->s && 1 <= config->bs)); if (EXIT_SUCCESS == result) { @@ -1599,63 +1380,67 @@ int libsmm_acc_process(const int* host_param_stack, const int* dev_param_stack, ? NULL : &event); size_t work_size; -# if defined(OPENCL_LIBSMM_VALIDATE_SMM) +# if defined(OPENCL_LIBSMM_VALIDATE_SMM) /* validate result (implies readback from device and performance penalty) */ + int* pinp = NULL; char *ainp = NULL, *binp = NULL, *test = NULL, *gold = NULL, *btrn = NULL; const libxsmm_datatype precision = (dbcsr_type_real_8 == datatype ? LIBXSMM_DATATYPE_F64 : (dbcsr_type_real_4 == datatype ? LIBXSMM_DATATYPE_F32 : LIBXSMM_DATATYPE_UNSUPPORTED)); const int typesize = OPENCL_LIBSMM_TYPESIZE(datatype); libxsmm_xmmfunction kernel_cpu = {NULL}; - size_t asize, bsize, csize; + size_t psize, asize, bsize, csize; void* scratch = NULL; - if (CL_SUCCESS == clGetMemObjectInfo(*ACC_OPENCL_MEM(dev_a_data), CL_MEM_SIZE, sizeof(size_t), &asize, NULL) && - CL_SUCCESS == clGetMemObjectInfo(*ACC_OPENCL_MEM(dev_b_data), CL_MEM_SIZE, sizeof(size_t), &bsize, NULL) && - CL_SUCCESS == clGetMemObjectInfo(*ACC_OPENCL_MEM(dev_c_data), CL_MEM_SIZE, sizeof(size_t), &csize, NULL)) + if (EXIT_SUCCESS == clGetMemObjectInfo(info_stack.memory, CL_MEM_SIZE, sizeof(size_t), &psize, NULL) && + EXIT_SUCCESS == clGetMemObjectInfo(info_adata.memory, CL_MEM_SIZE, sizeof(size_t), &asize, NULL) && + EXIT_SUCCESS == clGetMemObjectInfo(info_bdata.memory, CL_MEM_SIZE, sizeof(size_t), &bsize, NULL) && + EXIT_SUCCESS == clGetMemObjectInfo(info_cdata.memory, CL_MEM_SIZE, sizeof(size_t), &csize, NULL)) { - const double alpha = 1, beta = 1; libxsmm_descriptor_blob blob; - libxsmm_gemm_descriptor* const desc = libxsmm_gemm_descriptor_dinit( - &blob, precision, m_max, n_max, k_max, m_max, k_max, m_max, alpha, beta, LIBXSMM_GEMM_FLAG_NONE, LIBXSMM_PREFETCH_NONE); - scratch = libxsmm_aligned_scratch( - asize + bsize + csize + csize + k_max * n_max * typesize + 4 * (LIBXSMM_ALIGNMENT - 1) /*alignments*/, - LIBXSMM_ALIGNMENT); + libxsmm_gemm_descriptor* const desc = OPENCL_LIBSMM_DESCINIT( + &blob, precision, m_max, n_max, k_max, m_max, k_max, m_max, LIBXSMM_GEMM_FLAG_NONE, LIBXSMM_PREFETCH_NONE); + const size_t scratch_size = psize + asize + bsize + csize + csize + k_max * n_max * typesize + + 5 * (LIBXSMM_ALIGNMENT - 1) /*alignments*/; + scratch = libxsmm_aligned_scratch(scratch_size, LIBXSMM_ALIGNMENT); if (NULL != desc && NULL != scratch) { - ainp = (char*)scratch; + pinp = (int*)scratch; + ainp = (char*)LIBXSMM_UP2((uintptr_t)pinp + psize, LIBXSMM_ALIGNMENT); binp = (char*)LIBXSMM_UP2((uintptr_t)ainp + asize, LIBXSMM_ALIGNMENT); test = (char*)LIBXSMM_UP2((uintptr_t)binp + bsize, LIBXSMM_ALIGNMENT); gold = (char*)LIBXSMM_UP2((uintptr_t)test + csize, LIBXSMM_ALIGNMENT); btrn = (char*)LIBXSMM_UP2((uintptr_t)gold + csize, LIBXSMM_ALIGNMENT); - ACC_OPENCL_CHECK(c_dbcsr_acc_memcpy_d2h(dev_a_data, ainp, asize, stream), "transfer debug a-data", result); - ACC_OPENCL_CHECK(c_dbcsr_acc_memcpy_d2h(dev_b_data, binp, bsize, stream), "transfer debug b-data", result); - ACC_OPENCL_CHECK(c_dbcsr_acc_memcpy_d2h(dev_c_data, gold, csize, stream), "transfer debug c-data", result); + ACC_OPENCL_CHECK( + c_dbcsr_acc_memcpy_d2h(dev_param_stack, pinp, psize, stream), "transfer validation param-data", result); + ACC_OPENCL_CHECK(c_dbcsr_acc_memcpy_d2h(dev_a_data, ainp, asize, stream), "transfer validation a-data", result); + ACC_OPENCL_CHECK(c_dbcsr_acc_memcpy_d2h(dev_b_data, binp, bsize, stream), "transfer validation b-data", result); + ACC_OPENCL_CHECK(c_dbcsr_acc_memcpy_d2h(dev_c_data, gold, csize, stream), "transfer validation c-data", result); kernel_cpu = libxsmm_xmmdispatch(desc); assert(NULL != kernel_cpu.xmm); } else result = EXIT_FAILURE; } else result = EXIT_FAILURE; -# endif +# endif /* scale intra-kernel batchsize according to stacksize */ if (0 == kernel_idx && 1 < config->bs && stack_size < config->s) { -# if defined(OPENCL_LIBSMM_BS_MIN) +# if defined(OPENCL_LIBSMM_BS_MIN) const int config_bs = LIBXSMM_MAX(config->bs, OPENCL_LIBSMM_BS_MIN); -# else +# else const int config_bs = config->bs; -# endif +# endif bs = (stack_size * config_bs + config->s - 1) / (config->s - 1); if (config->bs < bs) bs = config->bs; } /* adjust launchsize according to intra-kernel batchsize */ work_size = ((stack_size + bs - 1) / bs) * config->wgsize[kernel_idx]; - /* calling clSetKernelArg must be consistent across host-threads */ - ACC_OPENCL_CHECK(clSetKernelArg(config->kernel[kernel_idx], 0, sizeof(cl_mem), ACC_OPENCL_MEM(dev_c_data)), + /* calling clSetKernelArg/clEnqueueNDRangeKernel must be consistent */ + ACC_OPENCL_CHECK(c_dbcsr_acc_opencl_set_kernel_ptr(config->kernel[kernel_idx], 0, info_cdata.memory), "set C-matrix argument of SMM-kernel", result); - ACC_OPENCL_CHECK(clSetKernelArg(config->kernel[kernel_idx], 1, sizeof(cl_mem), ACC_OPENCL_MEM(dev_a_data)), + ACC_OPENCL_CHECK(c_dbcsr_acc_opencl_set_kernel_ptr(config->kernel[kernel_idx], 1, info_adata.memory), "set A-matrix argument of SMM-kernel", result); - ACC_OPENCL_CHECK(clSetKernelArg(config->kernel[kernel_idx], 2, sizeof(cl_mem), ACC_OPENCL_MEM(dev_b_data)), + ACC_OPENCL_CHECK(c_dbcsr_acc_opencl_set_kernel_ptr(config->kernel[kernel_idx], 2, info_bdata.memory), "set B-matrix argument of SMM-kernel", result); - ACC_OPENCL_CHECK(clSetKernelArg(config->kernel[kernel_idx], 3, sizeof(cl_mem), ACC_OPENCL_MEM(dev_param_stack)), + ACC_OPENCL_CHECK(c_dbcsr_acc_opencl_set_kernel_ptr(config->kernel[kernel_idx], 3, info_stack.memory), "set batch-list argument of SMM-kernel", result); if (0 == kernel_idx) { assert(bs <= config->bs); @@ -1664,11 +1449,11 @@ int libsmm_acc_process(const int* host_param_stack, const int* dev_param_stack, ACC_OPENCL_CHECK( clSetKernelArg(config->kernel[kernel_idx], 5, sizeof(int), &bs), "set minibatch argument of SMM-kernel", result); } - ACC_OPENCL_CHECK(clEnqueueNDRangeKernel(queue, config->kernel[kernel_idx], 1 /*work_dim*/, NULL /*offset*/, &work_size, + ACC_OPENCL_CHECK(clEnqueueNDRangeKernel(str->queue, config->kernel[kernel_idx], 1 /*work_dim*/, NULL /*offset*/, &work_size, config->wgsize + kernel_idx, 0, NULL, perf_event), "launch SMM-kernel", result); /* eventually update performance counters inside of locked region */ -# if !defined(OPENCL_LIBSMM_VALIDATE_SMM) +# if !defined(OPENCL_LIBSMM_VALIDATE_SMM) if (3 <= c_dbcsr_acc_opencl_config.verbosity || 0 > c_dbcsr_acc_opencl_config.verbosity) { if (NULL != perf_event) { cl_ulong begin = 0, end = 0; @@ -1680,39 +1465,29 @@ int libsmm_acc_process(const int* host_param_stack, const int* dev_param_stack, duration = 1E-9 * LIBXSMM_DELTA(begin, end); /* Nanoseconds->seconds */ } else { - clFinish(queue); + clFinish(str->queue); duration = libxsmm_timer_duration(start, libxsmm_timer_tick()); /* seconds */ } if (EXIT_SUCCESS == result) { const double gflops = 1E-9 * (2ULL * m_max * n_max * k_max * stack_size) / duration; - const double est = (dbcsr_type_real_8 == datatype - ? (OPENCL_LIBSMM_AI(m_max, n_max, k_max, sizeof(double)) * opencl_libsmm_dacc) - : (OPENCL_LIBSMM_AI(m_max, n_max, k_max, sizeof(float)) * opencl_libsmm_sacc)); - const int* const priority = c_dbcsr_acc_opencl_stream_priority(stream); LIBXSMM_STDIO_ACQUIRE(); - fprintf(stderr, "INFO ACC/OpenCL: SMM-kernel "); + fprintf(stderr, "INFO ACC/LIBSMM: SMM-kernel "); opencl_libsmm_write_smm_params( stderr, 1 /*only_key*/, &key, NULL /*config*/, NULL /*delim*/, NULL /*begin*/, NULL /*close*/); fprintf(stderr, "="); opencl_libsmm_write_smm_params(stderr, 1 /*only_key*/, &key, config, NULL /*delim*/, NULL /*begin*/, NULL /*close*/); - fprintf(stderr, " prio=%i ss=%i cur=%.1f", NULL != priority ? *priority : -1, stack_size, gflops); - if (0 < est) fprintf(stderr, " est=%.1f", est); - fprintf(stderr, " GFLOPS/s dur=%.2g ms\n", 1E3 * duration); + fprintf(stderr, " ss=%i cur=%.1f GFLOPS/s dur=%.2g ms\n", stack_size, gflops, 1E3 * duration); LIBXSMM_STDIO_RELEASE(); } } -# endif -# if defined(OPENCL_LIBSMM_VALIDATE_SMM) - ACC_OPENCL_CHECK(c_dbcsr_acc_memcpy_d2h(dev_c_data, test, csize, stream), "transfer debug test", result); -# endif -# if defined(OPENCL_LIBSMM_VALIDATE_SMM) +# endif +# if defined(OPENCL_LIBSMM_VALIDATE_SMM) + ACC_OPENCL_CHECK(c_dbcsr_acc_memcpy_d2h(dev_c_data, test, csize, stream), "transfer validation test", result); ACC_OPENCL_CHECK(c_dbcsr_acc_stream_sync(stream), "sync stream", result); -# endif -# if defined(OPENCL_LIBSMM_VALIDATE_SMM) if (EXIT_SUCCESS == result) { const char* const env_tol = getenv("OPENCL_LIBSMM_SMM_TOLERANCE"); const double tolerance = ((NULL == env_tol || '\0' == *env_tol) ? 1E-3 : atof(env_tol)); - const int* const params = host_param_stack + (4 <= nparams ? (nparams - 4) : 0); + const int* const params = pinp + (4 <= nparams ? (nparams - 4) : 0); size_t i; LIBXSMM_STDIO_ACQUIRE(); if (0 != c_dbcsr_acc_opencl_config.verbosity) { @@ -1731,31 +1506,38 @@ int libsmm_acc_process(const int* host_param_stack, const int* dev_param_stack, /* some result may be validated multiple times in case of duplicated c-indexes */ for (i = 0; i < ((size_t)stack_size * nparams); i += nparams) { const size_t ic = (size_t)(params[i + 2] - 1) * typesize; + double epsilon = 0; libxsmm_matdiff_info diff; libxsmm_matdiff( &diff, (libxsmm_datatype)precision, m_max, n_max, gold + ic, test + ic, &m_max /*ldref*/, &m_max /*ldtst*/); - if (tolerance < diff.normf_rel) { +# if LIBXSMM_VERSION4(1, 17, 0, 0) < LIBXSMM_VERSION_NUMBER + epsilon = libxsmm_matdiff_epsilon(&diff); +# else + epsilon = diff.normf_rel; +# endif + if (tolerance < epsilon) { if (0 == c_dbcsr_acc_opencl_config.verbosity) { fprintf(stderr, "libsmm_acc_process(size=%i, type=%s, m=%i, n=%i, k=%i, max=%i, stream=%p)", stack_size, dbcsr_type_real_8 == datatype ? "f64" : (dbcsr_type_real_4 == datatype ? "f32" : "unknown"), m_max, n_max, k_max, max_kernel_dim, stream); } -# if LIBXSMM_VERSION4(1, 17, 0, 0) < LIBXSMM_VERSION_NUMBER +# if LIBXSMM_VERSION4(1, 17, 0, 0) < LIBXSMM_VERSION_NUMBER fprintf(stderr, " => ERROR diff=%g (%g != %g)\n", diff.linf_abs, diff.v_ref, diff.v_tst); -# else +# else fprintf(stderr, " => ERROR diff=%g\n", diff.linf_abs); -# endif -# if defined(_DEBUG) - opencl_libsmm_print_matrix(stderr, "gold = ", datatype, gold + ic, m_max, n_max); - opencl_libsmm_print_matrix(stderr, "test = ", datatype, test + ic, m_max, n_max); - fprintf(stderr, "\n"); -# endif -# if defined(OPENCL_LIBSMM_VALIDATE_EXIT) +# endif + if (3 <= c_dbcsr_acc_opencl_config.verbosity || 0 > c_dbcsr_acc_opencl_config.verbosity) { + fprintf(stderr, "stackposition = %llu (index=%llu)\n", (unsigned long long)i, (unsigned long long)ic); + opencl_libsmm_print_matrix(stderr, "gold = ", datatype, gold + ic, m_max, n_max); + opencl_libsmm_print_matrix(stderr, "test = ", datatype, test + ic, m_max, n_max); + fprintf(stderr, "\n"); + } +# if defined(OPENCL_LIBSMM_VALIDATE_EXIT) exit(EXIT_FAILURE); -# else +# else result = EXIT_FAILURE; break; -# endif +# endif } } if (0 != c_dbcsr_acc_opencl_config.verbosity && EXIT_SUCCESS == result) { @@ -1764,23 +1546,24 @@ int libsmm_acc_process(const int* host_param_stack, const int* dev_param_stack, LIBXSMM_STDIO_RELEASE(); } libxsmm_free(scratch); -# elif defined(NDEBUG) - LIBXSMM_UNUSED(host_param_stack); +# elif defined(NDEBUG) LIBXSMM_UNUSED(nparams); -# endif +# endif +# if defined(NDEBUG) + LIBXSMM_UNUSED(host_param_stack); +# endif } - LIBXSMM_ATOMIC_RELEASE(lock, LIBXSMM_ATOMIC_RELAXED); + ACC_OPENCL_ATOMIC_RELEASE(lock); } } else if (0 < stack_size) { /* inhomogeneous, large kernel, or unsupported datatype */ return -1; /* TODO: document result code to trigger host-fallback */ } -# endif ACC_OPENCL_RETURN(result); } -int c_calculate_norms(double* mat, int nblks, int* offsets, int* nelems, float* norms, void* stream_ptr) { +int c_calculate_norms(const double* mat, int nblks, const int* offsets, const int* nelems, float* norms, void* stream_ptr) { LIBXSMM_UNUSED(mat); LIBXSMM_UNUSED(nblks); LIBXSMM_UNUSED(offsets); diff --git a/src/acc/opencl/smm/opencl_libsmm.h b/src/acc/opencl/smm/opencl_libsmm.h index 0dfbea0c1b3..8a354ca78ec 100644 --- a/src/acc/opencl/smm/opencl_libsmm.h +++ b/src/acc/opencl/smm/opencl_libsmm.h @@ -12,14 +12,10 @@ #include "../../acc_libsmm.h" #include "../acc_opencl.h" -/* Inplace-transpose by default (similar environment variable exists for runtime) */ +/* Inplace-transpose by default (corresponding environment variable exists also) */ #if !defined(OPENCL_LIBSMM_TRANS_INPLACE) && 0 # define OPENCL_LIBSMM_TRANS_INPLACE #endif -/* Suitability check by default (similar environment variable exists for runtime) */ -#if !defined(OPENCL_LIBSMM_SUITABLE) && 0 -# define OPENCL_LIBSMM_SUITABLE -#endif /* Validate kernels (1: OPENCL_LIBSMM_VALIDATE_SMM, 2: OPENCL_LIBSMM_VALIDATE_TRANS) */ #if !defined(OPENCL_LIBSMM_VALIDATE) && 0 # define OPENCL_LIBSMM_VALIDATE 1 @@ -65,7 +61,7 @@ typedef struct opencl_libsmm_smm_t { size_t wgsize[2]; double gflops; /* (pseudo-)parameters (either pretuned or determined) */ - int s, bs, bm, bn, bk, ws, wg, lu, nz, al, tb, tc, ap, aa, ab, ac; + int s, bs, bm, bn, bk, ws, wg, lu, nz, al, tb, tc, ap, aa, ab, ac, flags; } opencl_libsmm_smm_t; /** Type to collect statistics about tuned SMM-kernels */ diff --git a/src/acc/opencl/smm/params/tune_multiply_A100-40GB.csv b/src/acc/opencl/smm/params/tune_multiply_A100-40GB.csv deleted file mode 100644 index c2c344091fb..00000000000 --- a/src/acc/opencl/smm/params/tune_multiply_A100-40GB.csv +++ /dev/null @@ -1,215 +0,0 @@ -DEVICE;TYPEID;M;N;K;S;GFLOPS;BS;BM;BN;BK;WS;WG;LU;NZ;AL;TB;TC;AP;AA;AB;AC -NVIDIA A100-PCIE-40GB [0xa01f];3;2;2;2;30000;0;9;2;1;2;0;1;0;0;0;0;1;0;3;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;3;3;3;30000;0;9;1;1;2;0;0;1;0;0;0;1;1;0;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;4;4;30000;0;10;1;1;1;0;-1;-2;1;0;0;1;1;3;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;4;5;30000;0;10;1;1;1;0;-1;1;0;0;1;1;0;0;0;2 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;4;7;30000;0;10;4;1;2;0;1;-1;0;0;1;1;0;1;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;4;9;30000;0;6;1;2;3;0;0;-2;1;0;1;1;0;3;2;1 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;4;10;30000;0;6;1;1;1;0;1;0;1;0;0;1;1;3;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;4;13;30000;0;10;1;1;2;0;-1;0;1;0;1;1;0;3;0;2 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;4;15;30000;0;22;1;1;3;0;-2;1;1;0;0;0;1;0;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;4;17;30000;0;5;4;1;4;0;1;-1;0;0;0;1;0;1;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;4;25;30000;0;14;1;1;2;0;0;1;0;0;0;1;0;0;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;4;26;30000;0;4;1;1;2;0;0;-1;1;0;1;1;0;0;2;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;4;28;30000;0;20;1;1;3;0;0;0;0;0;0;1;0;0;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;4;32;30000;0;18;1;1;3;0;-1;1;0;0;0;0;1;3;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;5;4;30000;0;10;1;1;3;0;-1;-2;0;0;0;1;0;3;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;5;5;30000;0;9;1;1;3;0;1;-1;1;0;1;1;0;3;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;5;7;30000;0;12;1;1;4;0;1;-1;1;0;1;1;1;3;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;5;9;30000;0;6;1;3;4;0;1;1;1;0;1;1;0;3;1;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;5;13;30000;0;21;1;1;3;0;-1;-2;1;0;1;1;0;3;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;5;17;30000;0;5;4;1;2;0;0;-1;0;0;0;1;0;2;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;5;25;30000;0;6;1;1;3;0;0;-1;0;0;0;0;0;0;0;2 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;5;32;30000;0;5;4;1;4;0;1;0;0;0;0;1;0;2;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;7;4;30000;0;10;1;1;3;0;2;0;1;0;1;1;1;3;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;7;5;30000;0;9;1;1;1;0;1;-2;1;0;1;1;0;0;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;7;7;30000;0;10;1;1;1;0;-1;-1;0;0;1;1;1;3;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;7;9;30000;0;17;1;1;2;0;0;1;0;0;1;0;1;3;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;7;13;30000;0;16;2;1;4;0;-2;-1;1;0;1;1;0;3;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;9;4;30000;0;11;1;2;4;0;1;-2;0;0;0;1;1;3;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;9;5;30000;0;19;2;1;1;0;-1;-1;1;0;0;1;1;3;1;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;9;7;30000;0;14;4;1;4;0;0;-1;0;0;0;1;0;1;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;9;9;30000;0;13;1;1;4;0;1;-2;0;0;0;1;0;0;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;9;13;30000;0;9;3;1;4;0;-1;0;0;0;0;1;1;0;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;10;4;30000;0;15;3;1;2;0;1;1;0;0;0;1;0;0;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;10;10;30000;0;15;4;1;2;0;1;0;0;0;0;1;1;2;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;13;4;30000;0;19;4;1;2;0;-2;-2;0;0;0;1;0;3;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;13;5;30000;0;17;2;1;1;0;0;-2;0;0;0;1;0;0;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;13;7;30000;0;14;2;1;1;0;2;0;0;0;0;1;0;3;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;13;9;30000;0;7;2;1;3;0;-2;-2;1;0;1;1;1;0;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;13;13;30000;0;10;4;1;2;0;-1;-1;0;0;0;1;0;1;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;13;17;30000;0;14;4;1;2;0;0;1;0;0;0;1;0;2;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;13;32;30000;0;7;4;1;4;0;0;0;0;0;0;1;0;2;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;15;4;30000;0;20;2;1;1;0;0;-2;0;0;1;1;0;3;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;17;4;30000;0;18;4;1;3;0;0;0;0;0;0;1;0;0;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;17;5;30000;0;14;4;1;2;0;-1;0;0;0;0;1;0;0;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;17;13;30000;0;13;4;1;3;0;0;0;0;0;0;1;0;1;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;17;17;30000;0;10;4;1;3;0;-1;-1;0;0;0;1;0;1;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;17;32;30000;0;7;4;1;4;0;-2;0;0;0;0;1;0;2;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;25;4;30000;0;23;4;1;1;0;0;0;0;0;0;1;1;0;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;25;5;30000;0;21;4;1;2;0;0;0;0;0;0;1;0;3;3;2 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;26;4;30000;0;22;4;1;1;0;0;0;1;0;0;1;1;0;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;28;4;30000;0;20;4;1;1;0;-1;0;0;0;0;1;1;0;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;32;4;30000;0;21;4;1;3;0;0;0;0;0;0;1;0;3;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;32;5;30000;0;14;4;1;2;0;-1;-1;0;0;0;1;0;0;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;32;13;30000;0;11;4;1;2;0;1;-2;0;0;0;1;0;1;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;32;17;30000;0;12;4;1;3;0;0;-2;0;0;0;1;0;2;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;4;32;32;30000;0;8;4;1;4;0;0;0;0;0;0;1;0;2;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;5;4;4;30000;0;11;1;1;3;0;0;-2;1;0;0;1;0;0;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;5;4;5;30000;0;9;1;1;2;0;-1;0;0;0;0;1;0;0;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;5;4;7;30000;0;12;1;1;1;0;1;-1;1;0;0;1;1;3;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;5;4;9;30000;0;12;1;1;4;0;-1;-2;0;0;0;1;0;0;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;5;4;13;30000;0;12;1;1;5;0;1;-2;0;0;1;1;0;0;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;5;4;17;30000;0;5;5;1;5;0;-2;1;0;0;0;1;0;1;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;5;4;25;30000;0;27;1;1;4;0;1;-2;0;0;0;0;0;3;0;1 -NVIDIA A100-PCIE-40GB [0xa01f];3;5;4;32;30000;0;3;5;1;5;0;-2;0;0;0;0;1;0;2;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;5;5;4;30000;0;11;1;1;5;0;1;-1;0;0;0;1;1;3;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;5;5;5;30000;0;10;1;1;3;0;-2;1;0;0;0;1;0;0;0;2 -NVIDIA A100-PCIE-40GB [0xa01f];3;5;5;7;30000;0;9;1;1;5;0;1;-1;0;0;0;1;0;0;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;5;5;9;30000;0;25;1;1;4;0;1;-2;0;0;1;1;0;3;3;2 -NVIDIA A100-PCIE-40GB [0xa01f];3;5;5;13;30000;0;10;2;1;4;0;1;-1;0;0;1;1;1;3;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;5;5;17;30000;0;5;5;1;5;0;0;0;0;0;0;1;0;1;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;5;5;32;30000;0;3;5;1;5;0;0;0;0;0;0;1;0;2;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;5;7;4;30000;0;11;2;1;3;0;1;0;0;0;1;1;0;0;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;5;7;5;30000;0;16;5;1;5;0;-1;0;1;0;1;1;0;1;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;5;7;7;30000;0;19;2;1;4;0;0;-2;1;0;0;1;1;0;3;2 -NVIDIA A100-PCIE-40GB [0xa01f];3;5;7;9;30000;0;12;1;2;4;0;-2;0;0;0;0;1;1;3;3;1 -NVIDIA A100-PCIE-40GB [0xa01f];3;5;7;13;30000;0;20;1;2;5;0;1;-1;1;0;1;1;1;3;3;2 -NVIDIA A100-PCIE-40GB [0xa01f];3;5;9;4;30000;0;15;1;2;4;0;0;-1;0;0;1;1;1;3;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;5;9;5;30000;0;34;2;1;2;0;1;-2;0;0;1;1;0;3;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;5;9;7;30000;0;15;5;1;2;0;1;1;1;0;0;1;1;0;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;5;9;9;30000;0;25;1;2;2;0;0;1;0;0;1;1;1;3;1;1 -NVIDIA A100-PCIE-40GB [0xa01f];3;5;13;4;30000;0;20;5;1;1;0;0;0;0;0;0;1;1;0;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;5;13;5;30000;0;14;1;3;1;0;1;0;1;0;0;1;1;3;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;5;13;7;30000;0;24;3;1;2;0;1;0;1;0;0;1;1;0;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;5;13;13;30000;0;6;5;1;2;0;-1;-1;0;0;0;1;0;1;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;5;13;17;30000;0;12;5;1;5;0;0;-2;0;0;0;1;0;2;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;5;25;4;30000;0;30;5;1;1;0;1;-2;0;0;0;1;1;0;0;1 -NVIDIA A100-PCIE-40GB [0xa01f];3;6;6;6;30000;0;18;6;1;3;0;0;1;0;0;0;1;0;1;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;6;6;7;30000;0;19;2;1;6;0;1;-1;0;0;0;1;0;0;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;6;6;8;30000;0;15;6;1;3;0;1;1;0;0;0;1;0;2;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;6;7;6;30000;0;28;2;1;1;0;-2;-2;0;0;0;1;0;3;0;1 -NVIDIA A100-PCIE-40GB [0xa01f];3;6;7;7;30000;0;12;1;2;1;0;0;1;1;0;0;1;0;1;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;6;7;8;30000;0;15;2;1;6;0;-1;1;0;0;0;1;0;3;3;2 -NVIDIA A100-PCIE-40GB [0xa01f];3;6;8;6;30000;0;14;3;1;2;0;0;0;0;0;0;1;1;1;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;6;8;7;30000;0;32;1;2;4;0;-1;0;0;0;1;1;1;0;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;6;8;8;30000;0;23;1;2;5;0;-1;0;1;0;1;0;0;0;0;1 -NVIDIA A100-PCIE-40GB [0xa01f];3;7;4;4;30000;0;9;1;1;6;0;0;0;0;0;0;1;0;0;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;7;4;5;30000;0;15;1;1;7;0;-2;0;0;0;1;1;1;3;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;7;4;7;30000;0;24;1;1;4;0;-1;0;0;0;0;1;0;0;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;7;4;9;30000;0;14;1;1;6;0;1;-1;0;0;0;1;0;0;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;7;4;13;30000;0;15;1;4;2;0;-1;-1;0;0;0;1;1;0;2;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;7;5;4;30000;0;15;7;1;2;0;0;-1;1;0;0;1;0;0;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;7;5;5;30000;0;6;2;1;2;0;0;-2;0;0;0;1;0;3;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;7;5;7;30000;0;14;3;1;2;0;-2;-2;0;0;1;1;1;3;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;7;5;9;30000;0;10;1;1;4;0;1;0;0;0;1;1;0;0;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;7;5;13;30000;0;5;1;2;1;0;1;-2;1;0;1;1;0;3;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;7;6;6;30000;0;14;1;3;7;0;0;1;0;0;1;1;1;0;0;2 -NVIDIA A100-PCIE-40GB [0xa01f];3;7;6;7;30000;0;19;2;1;1;0;1;-2;1;0;0;1;1;0;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;7;6;8;30000;0;43;1;2;4;0;1;0;1;0;0;1;1;0;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;7;7;4;30000;0;18;7;1;3;0;-1;-1;1;0;0;1;0;2;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;7;7;5;30000;0;29;1;2;1;0;1;-1;0;0;0;1;1;3;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;7;7;6;30000;0;18;3;1;4;0;-2;0;0;0;1;1;1;0;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;7;7;7;30000;0;18;7;1;2;0;2;0;0;0;0;1;0;1;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;7;7;8;30000;0;11;2;1;1;0;-1;-2;1;0;0;1;1;0;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;7;7;9;30000;0;11;1;2;7;0;1;-2;0;0;0;1;0;3;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;7;7;13;30000;0;9;2;1;4;0;2;1;1;0;0;1;1;0;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;7;8;6;30000;0;10;2;1;2;0;0;1;1;0;0;1;0;0;0;1 -NVIDIA A100-PCIE-40GB [0xa01f];3;7;8;7;0;0;18;7;1;0;0;1;0;0;0;0;1;1;2;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;7;8;8;30000;0;10;2;1;4;0;1;-1;0;0;0;1;0;2;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;7;9;4;30000;0;16;1;1;2;0;-2;0;0;0;1;1;1;3;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;7;9;5;30000;0;13;3;1;2;0;-1;-2;1;0;0;1;1;0;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;7;9;7;30000;0;9;1;8;1;0;-2;-2;1;0;1;1;1;3;1;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;7;13;4;30000;0;21;4;1;1;0;1;-2;0;0;0;1;1;0;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;7;13;5;30000;0;9;1;4;3;0;1;1;1;0;1;1;1;3;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;7;13;7;30000;0;14;7;1;3;0;1;0;1;0;0;1;1;1;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;7;13;13;0;0;12;7;1;0;0;2;-2;0;0;0;1;0;2;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;8;6;6;30000;0;14;1;2;4;0;-2;-2;0;0;1;1;1;3;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;8;6;7;30000;0;13;2;1;5;0;1;-1;0;0;0;1;0;3;1;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;8;6;8;30000;0;20;1;2;8;0;1;1;0;0;0;0;0;0;3;2 -NVIDIA A100-PCIE-40GB [0xa01f];3;8;7;6;30000;0;5;1;7;6;0;-1;-1;0;0;1;1;1;0;1;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;8;7;7;30000;0;22;2;1;2;0;-2;-1;0;0;0;1;0;0;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;8;7;8;30000;0;16;2;1;3;0;-1;0;1;0;0;1;0;3;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;8;8;6;30000;0;18;8;1;2;0;1;-2;1;0;0;1;0;2;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;8;8;7;30000;0;14;2;1;3;0;-1;-2;0;0;0;1;0;0;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;8;8;8;30000;0;18;8;1;6;0;0;0;0;0;1;1;1;2;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;9;4;4;30000;0;17;1;1;1;0;-2;1;1;0;0;1;1;3;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;9;4;5;30000;0;11;1;3;1;0;-2;1;1;0;0;1;0;3;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;9;4;7;30000;0;10;2;1;3;0;1;1;1;0;0;1;1;3;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;9;4;9;30000;0;10;1;1;7;0;-2;1;1;0;1;1;1;3;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;9;4;13;30000;0;10;1;2;2;0;0;0;0;0;1;0;0;1;0;1 -NVIDIA A100-PCIE-40GB [0xa01f];3;9;5;4;30000;0;18;1;2;3;0;-2;-1;1;0;1;1;0;0;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;9;5;5;30000;0;19;2;1;1;0;-1;0;1;0;1;1;0;3;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;9;5;7;30000;0;12;1;5;5;0;0;-1;1;0;0;1;0;0;1;1 -NVIDIA A100-PCIE-40GB [0xa01f];3;9;5;9;30000;0;14;2;1;2;0;1;-2;0;0;0;1;1;0;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;9;7;4;30000;0;16;4;1;1;0;0;1;0;0;0;1;1;0;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;9;7;5;30000;0;18;6;1;3;0;0;-2;0;0;0;1;1;2;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;9;7;7;30000;0;19;1;1;3;0;1;-1;0;0;0;1;0;0;3;1 -NVIDIA A100-PCIE-40GB [0xa01f];3;9;9;4;30000;0;24;9;1;8;0;-2;0;0;0;1;1;1;2;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;9;9;5;30000;0;17;3;1;7;0;-2;1;0;0;0;1;0;0;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;9;9;9;30000;0;15;3;1;3;0;-1;-2;0;0;0;1;0;3;3;1 -NVIDIA A100-PCIE-40GB [0xa01f];3;9;9;16;30000;0;15;3;1;1;0;1;1;0;0;0;1;1;3;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;9;9;22;30000;0;12;1;3;9;0;1;-1;1;0;0;1;0;3;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;9;9;32;0;0;14;1;3;8;0;0;-1;0;0;0;0;1;3;3;1 -NVIDIA A100-PCIE-40GB [0xa01f];3;9;13;4;30000;0;17;9;1;3;0;-1;0;1;0;0;1;1;1;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;9;16;9;0;0;13;9;1;0;0;1;-2;0;0;0;1;1;2;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;9;16;16;30000;0;12;7;1;1;0;0;0;1;0;0;1;0;2;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;9;16;22;30000;0;19;5;1;1;0;1;-2;1;0;0;1;0;2;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;9;22;9;30000;0;17;9;1;6;0;-2;-2;1;0;0;1;1;1;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;9;22;16;0;0;13;9;1;0;0;1;-2;1;0;0;1;0;2;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;9;22;22;30000;0;10;9;1;6;0;1;0;1;0;0;1;1;2;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;9;22;32;0;0;24;9;7;9;0;0;-2;0;0;0;1;1;2;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;10;4;4;30000;0;14;1;2;5;0;-2;-1;0;0;0;1;0;3;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;10;4;10;30000;0;10;1;2;1;0;0;-2;1;0;0;1;1;0;0;1 -NVIDIA A100-PCIE-40GB [0xa01f];3;10;10;4;30000;0;24;10;1;5;0;1;1;0;0;0;1;1;2;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;10;10;10;30000;0;14;4;1;9;0;0;-1;0;0;0;1;1;2;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;13;4;4;30000;0;16;1;2;9;0;0;0;0;0;0;1;1;0;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;13;4;5;30000;0;17;2;1;7;0;1;-2;1;0;1;1;1;3;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;13;4;7;30000;0;19;2;1;11;0;1;0;1;0;0;1;1;0;0;1 -NVIDIA A100-PCIE-40GB [0xa01f];3;13;4;9;30000;0;9;2;1;1;0;1;-1;1;0;1;1;0;0;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;13;5;4;30000;0;14;4;1;2;0;1;-1;0;0;1;1;0;0;1;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;13;5;5;30000;0;15;13;1;2;0;2;-2;0;0;0;1;1;1;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;13;5;7;30000;0;6;1;1;13;0;-2;-2;0;0;0;1;1;1;1;2 -NVIDIA A100-PCIE-40GB [0xa01f];3;13;5;13;30000;0;9;1;1;1;0;-2;0;0;0;0;1;0;0;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;13;7;4;30000;0;21;1;1;11;0;1;-2;1;0;1;1;0;0;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;13;7;5;30000;0;18;3;2;5;0;0;1;1;0;1;1;1;3;3;1 -NVIDIA A100-PCIE-40GB [0xa01f];3;13;7;7;30000;0;5;1;5;9;0;-1;0;1;0;1;1;0;3;1;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;13;7;13;30000;0;10;1;4;8;0;-2;-2;1;0;1;1;0;3;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;13;9;4;30000;0;18;9;1;1;0;0;0;1;0;0;1;1;2;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;13;13;5;30000;0;24;13;1;5;0;1;1;0;0;0;1;0;2;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;13;13;7;30000;0;24;13;1;2;0;1;0;1;0;1;1;1;1;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;13;13;13;30000;0;14;13;1;3;0;1;-2;1;0;0;1;0;1;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;15;4;4;30000;0;21;2;1;4;0;1;-2;1;0;0;1;1;3;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;15;15;15;30000;0;16;15;1;14;0;-2;0;0;0;0;1;1;1;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;16;9;9;30000;0;12;16;1;2;0;0;-2;0;0;0;1;0;1;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;16;9;16;30000;0;14;2;1;1;0;0;-2;1;0;0;1;1;2;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;16;9;22;30000;0;20;6;1;9;0;0;-2;1;0;0;1;1;1;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;16;16;9;30000;0;18;16;1;6;0;1;1;1;0;0;1;0;2;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;16;16;16;0;0;14;16;1;0;0;1;0;1;0;0;1;0;2;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;16;16;22;0;0;14;16;1;0;0;0;-2;1;0;0;1;0;1;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;16;22;9;30000;0;18;16;1;4;0;1;-2;1;0;0;1;1;2;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;16;22;16;0;0;19;16;1;0;0;2;-2;1;0;0;1;1;2;0;1 -NVIDIA A100-PCIE-40GB [0xa01f];3;16;22;22;0;0;24;16;1;0;0;1;-2;1;0;0;1;1;1;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;20;20;20;30000;0;15;20;17;14;0;0;0;1;0;0;1;1;1;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;22;9;9;30000;0;6;2;5;4;0;-1;1;0;0;0;1;0;3;3;2 -NVIDIA A100-PCIE-40GB [0xa01f];3;22;9;16;0;0;14;22;1;0;0;1;-2;0;0;0;1;0;2;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;22;9;22;0;0;24;22;1;0;0;0;-2;0;0;0;1;1;1;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;22;9;32;0;0;10;8;1;4;0;0;-1;0;0;0;1;0;2;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;22;16;9;0;0;19;22;1;0;0;1;-2;1;0;0;1;0;1;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;22;16;16;0;0;14;22;1;0;0;1;-2;1;0;0;1;0;2;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;22;16;22;0;0;18;22;1;0;0;1;-2;1;0;0;1;0;1;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;22;22;9;0;0;24;22;1;0;0;1;-2;1;0;0;1;0;1;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;22;22;16;0;0;15;22;1;0;0;1;-2;1;0;0;1;1;2;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;22;22;22;0;0;24;22;1;0;0;2;-2;1;0;0;1;0;1;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;22;22;32;0;0;15;22;14;17;0;0;-2;0;0;0;1;0;2;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;23;23;23;30000;0;24;23;1;22;0;-2;0;1;0;0;1;1;1;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;24;24;24;0;0;18;24;1;0;0;1;-2;1;0;0;1;1;2;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;25;4;4;0;0;15;25;1;0;0;0;0;0;0;0;1;0;2;0;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;25;4;5;0;0;18;25;1;0;0;2;-2;0;0;0;1;1;2;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;25;5;4;0;0;18;25;1;0;0;2;0;0;0;0;1;1;2;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;25;25;25;0;0;24;25;1;0;0;1;-2;1;0;0;1;0;1;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;26;4;4;0;0;18;26;1;0;0;2;-2;0;0;0;1;1;1;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;28;4;4;0;0;18;28;1;0;0;0;0;0;0;0;1;1;1;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;28;28;28;0;0;18;28;1;0;0;1;-2;1;0;0;1;1;1;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;30;30;30;0;0;18;30;1;0;0;0;0;0;0;0;1;0;1;3;0 -NVIDIA A100-PCIE-40GB [0xa01f];3;32;32;32;0;0;36;32;4;32;0;0;0;0;0;0;1;0;2;3;0 diff --git a/src/acc/opencl/smm/params/tune_multiply_A100-80GB.csv b/src/acc/opencl/smm/params/tune_multiply_A100-80GB.csv deleted file mode 100644 index bf294c2d9d4..00000000000 --- a/src/acc/opencl/smm/params/tune_multiply_A100-80GB.csv +++ /dev/null @@ -1,293 +0,0 @@ -DEVICE;TYPEID;M;N;K;S;GFLOPS;BS;BM;BN;BK;WS;WG;LU;NZ;AL;TB;TC;AP;AA;AB;AC -NVIDIA A100 80GB PCIe [0x1f79];3;2;2;2;30000;0;9;2;1;2;0;1;0;0;0;0;1;0;3;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;3;3;3;30000;0;9;1;1;2;0;0;1;0;0;0;1;1;0;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;4;4;30000;0;6;4;1;4;0;0;0;0;0;0;1;0;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;4;5;30000;0;9;4;1;3;0;-1;-1;0;0;0;1;0;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;4;7;30000;0;10;4;1;2;0;1;-1;0;0;1;1;0;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;4;9;30000;0;6;1;2;3;0;0;-2;1;0;1;1;0;3;2;1 -NVIDIA A100 80GB PCIe [0x1f79];3;4;4;10;30000;0;6;1;1;1;0;1;0;1;0;0;1;1;3;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;4;13;30000;0;5;4;1;4;0;-1;-1;0;0;0;1;0;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;4;15;30000;0;22;1;1;3;0;-2;1;1;0;0;0;1;0;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;4;17;30000;0;5;4;1;4;0;-1;0;1;0;0;1;0;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;4;25;30000;0;14;1;1;2;0;0;1;0;0;0;1;0;0;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;4;26;30000;0;4;1;1;2;0;0;-1;1;0;1;1;0;0;2;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;4;28;30000;0;20;1;1;3;0;0;0;0;0;0;1;0;0;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;4;32;30000;0;3;4;1;4;0;1;-1;0;0;0;1;0;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;5;4;30000;0;12;4;1;2;0;1;0;0;0;0;1;0;0;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;5;5;30000;0;9;4;1;3;0;0;-2;0;0;0;1;0;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;5;7;30000;0;12;1;1;4;0;1;-1;1;0;1;1;1;3;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;5;9;30000;0;6;1;3;4;0;1;1;1;0;1;1;0;3;1;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;5;13;30000;0;4;4;1;4;0;-2;-2;1;0;0;1;0;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;5;17;30000;0;5;4;1;2;0;0;-1;0;0;0;1;1;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;5;25;30000;0;6;1;1;3;0;0;-1;0;0;0;0;0;0;0;2 -NVIDIA A100 80GB PCIe [0x1f79];3;4;5;32;30000;0;3;4;1;3;0;-1;-1;0;0;0;1;0;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;7;4;30000;0;10;1;1;3;0;2;0;1;0;1;1;1;3;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;7;5;30000;0;9;1;1;1;0;1;-2;1;0;1;1;0;0;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;7;7;30000;0;10;1;1;1;0;-1;-1;0;0;1;1;1;3;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;7;9;30000;0;17;1;1;2;0;0;1;0;0;1;0;1;3;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;7;13;30000;0;16;2;1;4;0;-2;-1;1;0;1;1;0;3;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;9;4;30000;0;11;1;2;4;0;1;-2;0;0;0;1;1;3;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;9;5;30000;0;19;2;1;1;0;-1;-1;1;0;0;1;1;3;1;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;9;7;30000;0;14;4;1;4;0;0;-1;0;0;0;1;0;1;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;9;9;30000;0;13;1;1;4;0;1;-2;0;0;0;1;0;0;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;9;13;30000;0;9;3;1;4;0;-1;0;0;0;0;1;1;0;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;10;4;30000;0;15;3;1;2;0;1;1;0;0;0;1;0;0;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;10;10;30000;0;15;4;1;2;0;1;0;0;0;0;1;1;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;13;4;30000;0;19;4;1;4;0;0;-2;0;0;1;1;0;0;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;13;5;30000;0;12;4;1;4;0;-1;-2;0;0;0;1;0;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;13;7;30000;0;14;2;1;1;0;2;0;0;0;0;1;0;3;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;13;9;30000;0;7;2;1;3;0;-2;-2;1;0;1;1;1;0;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;13;13;30000;0;10;4;1;4;0;-2;-2;0;0;0;1;1;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;13;17;30000;0;10;4;1;2;0;-2;1;0;0;0;1;0;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;13;32;30000;0;15;4;1;4;0;-1;-2;0;0;0;1;0;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;15;4;30000;0;20;2;1;1;0;0;-2;0;0;1;1;0;3;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;17;4;30000;0;22;4;1;2;0;0;-1;1;0;0;1;0;0;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;17;5;30000;0;12;4;1;3;0;0;-2;0;0;0;1;0;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;17;13;30000;0;10;4;1;4;0;0;-2;0;0;0;1;0;1;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;17;17;30000;0;10;4;1;3;0;-1;-2;0;0;0;1;0;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;17;32;30000;0;15;4;1;3;0;1;0;0;0;0;1;0;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;25;4;30000;0;23;4;1;1;0;0;0;0;0;0;1;1;0;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;25;5;30000;0;21;4;1;2;0;0;0;0;0;0;1;0;3;3;2 -NVIDIA A100 80GB PCIe [0x1f79];3;4;26;4;30000;0;22;4;1;1;0;0;0;1;0;0;1;1;0;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;28;4;30000;0;20;4;1;1;0;-1;0;0;0;0;1;1;0;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;32;4;30000;0;19;4;1;1;0;0;-2;1;0;0;1;0;3;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;32;5;30000;0;19;4;1;4;0;-2;-1;0;0;1;1;0;0;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;32;13;30000;0;12;4;1;3;0;1;-1;0;0;0;1;1;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;4;32;17;30000;0;13;4;1;3;0;1;1;0;0;0;1;1;2;3;2 -NVIDIA A100 80GB PCIe [0x1f79];3;4;32;32;30000;0;24;4;1;4;0;0;2;0;0;0;1;1;2;3;1 -NVIDIA A100 80GB PCIe [0x1f79];3;5;4;4;30000;0;9;5;1;4;0;0;0;0;0;1;1;0;0;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;5;4;5;30000;0;12;5;1;4;0;0;1;0;0;0;1;0;0;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;5;4;7;30000;0;12;1;1;1;0;1;-1;1;0;0;1;1;3;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;5;4;9;30000;0;12;1;1;4;0;-1;-2;0;0;0;1;0;0;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;5;4;13;30000;0;4;5;1;5;0;-1;2;0;0;0;1;0;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;5;4;17;30000;0;3;5;1;5;0;0;1;0;0;0;1;0;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;5;4;25;30000;0;27;1;1;4;0;1;-2;0;0;0;0;0;3;0;1 -NVIDIA A100 80GB PCIe [0x1f79];3;5;4;32;30000;0;3;5;1;5;0;1;0;0;0;0;1;1;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;5;5;4;30000;0;14;5;1;5;0;0;-1;0;0;0;1;0;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;5;5;5;30000;0;18;5;1;5;0;-1;-1;0;0;0;1;0;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;5;5;7;30000;0;9;1;1;5;0;1;-1;0;0;0;1;0;0;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;5;5;9;30000;0;25;1;1;4;0;1;-2;0;0;1;1;0;3;3;2 -NVIDIA A100 80GB PCIe [0x1f79];3;5;5;13;30000;0;7;5;1;4;0;0;-2;0;0;0;1;0;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;5;5;17;30000;0;4;5;1;4;0;-1;-2;0;0;0;1;0;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;5;5;32;30000;0;5;5;1;5;0;-2;0;0;0;0;1;1;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;5;7;4;30000;0;11;2;1;3;0;1;0;0;0;1;1;0;0;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;5;7;5;30000;0;16;5;1;5;0;-1;0;1;0;1;1;0;1;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;5;7;7;30000;0;19;2;1;4;0;0;-2;1;0;0;1;1;0;3;2 -NVIDIA A100 80GB PCIe [0x1f79];3;5;7;9;30000;0;12;1;2;4;0;-2;0;0;0;0;1;1;3;3;1 -NVIDIA A100 80GB PCIe [0x1f79];3;5;7;13;30000;0;20;1;2;5;0;1;-1;1;0;1;1;1;3;3;2 -NVIDIA A100 80GB PCIe [0x1f79];3;5;9;4;30000;0;15;1;2;4;0;0;-1;0;0;1;1;1;3;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;5;9;5;30000;0;34;2;1;2;0;1;-2;0;0;1;1;0;3;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;5;9;7;30000;0;15;5;1;2;0;1;1;1;0;0;1;1;0;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;5;9;9;30000;0;25;1;2;2;0;0;1;0;0;1;1;1;3;1;1 -NVIDIA A100 80GB PCIe [0x1f79];3;5;13;4;30000;0;12;5;1;4;0;0;0;0;0;0;1;0;2;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;5;13;5;30000;0;14;5;1;3;0;-1;0;1;0;1;1;1;1;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;5;13;7;30000;0;24;3;1;2;0;1;0;1;0;0;1;1;0;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;5;13;13;30000;0;10;5;1;2;0;-1;0;0;0;0;1;1;2;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;5;13;17;30000;0;10;5;1;4;0;-2;0;1;0;0;1;0;2;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;5;13;32;30000;0;15;5;1;3;0;-2;0;0;0;0;1;0;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;5;17;4;30000;0;14;5;1;4;0;0;-1;0;0;0;1;0;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;5;17;5;30000;0;12;5;1;5;0;-2;0;0;0;0;1;0;1;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;5;17;13;30000;0;10;5;1;4;0;0;0;1;0;0;1;0;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;5;17;17;30000;0;10;5;1;5;0;1;-1;0;0;0;1;0;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;5;17;32;30000;0;15;5;1;4;0;1;0;0;0;0;1;0;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;5;25;4;30000;0;30;5;1;1;0;1;-2;0;0;0;1;1;0;0;1 -NVIDIA A100 80GB PCIe [0x1f79];3;5;32;4;30000;0;24;5;1;5;0;-2;-1;1;0;1;1;0;0;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;5;32;5;30000;0;20;5;1;5;0;-1;-1;1;0;1;1;1;0;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;5;32;13;30000;0;13;5;1;5;0;1;-1;0;0;0;1;0;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;5;32;17;30000;0;13;5;1;2;0;1;0;0;0;0;1;1;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;5;32;32;30000;0;15;5;1;5;0;-1;0;0;0;0;1;1;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;6;6;6;30000;0;18;6;1;3;0;0;1;0;0;0;1;0;1;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;6;6;7;30000;0;19;2;1;6;0;1;-1;0;0;0;1;0;0;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;6;6;8;30000;0;15;6;1;3;0;1;1;0;0;0;1;0;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;6;7;6;30000;0;28;2;1;1;0;-2;-2;0;0;0;1;0;3;0;1 -NVIDIA A100 80GB PCIe [0x1f79];3;6;7;7;30000;0;12;1;2;1;0;0;1;1;0;0;1;0;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;6;7;8;30000;0;15;2;1;6;0;-1;1;0;0;0;1;0;3;3;2 -NVIDIA A100 80GB PCIe [0x1f79];3;6;8;6;30000;0;14;3;1;2;0;0;0;0;0;0;1;1;1;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;6;8;7;30000;0;32;1;2;4;0;-1;0;0;0;1;1;1;0;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;6;8;8;30000;0;23;1;2;5;0;-1;0;1;0;1;0;0;0;0;1 -NVIDIA A100 80GB PCIe [0x1f79];3;7;4;4;30000;0;9;1;1;6;0;0;0;0;0;0;1;0;0;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;7;4;5;30000;0;15;1;1;7;0;-2;0;0;0;1;1;1;3;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;7;4;7;30000;0;24;1;1;4;0;-1;0;0;0;0;1;0;0;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;7;4;9;30000;0;14;1;1;6;0;1;-1;0;0;0;1;0;0;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;7;4;13;30000;0;15;1;4;2;0;-1;-1;0;0;0;1;1;0;2;0 -NVIDIA A100 80GB PCIe [0x1f79];3;7;5;4;30000;0;15;7;1;2;0;0;-1;1;0;0;1;0;0;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;7;5;5;30000;0;6;2;1;2;0;0;-2;0;0;0;1;0;3;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;7;5;7;30000;0;14;3;1;2;0;-2;-2;0;0;1;1;1;3;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;7;5;9;30000;0;10;1;1;4;0;1;0;0;0;1;1;0;0;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;7;5;13;30000;0;5;1;2;1;0;1;-2;1;0;1;1;0;3;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;7;6;6;30000;0;14;1;3;7;0;0;1;0;0;1;1;1;0;0;2 -NVIDIA A100 80GB PCIe [0x1f79];3;7;6;7;30000;0;19;2;1;1;0;1;-2;1;0;0;1;1;0;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;7;6;8;30000;0;43;1;2;4;0;1;0;1;0;0;1;1;0;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;7;7;4;30000;0;18;7;1;3;0;-1;-1;1;0;0;1;0;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;7;7;5;30000;0;29;1;2;1;0;1;-1;0;0;0;1;1;3;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;7;7;6;30000;0;18;3;1;4;0;-2;0;0;0;1;1;1;0;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;7;7;7;30000;0;18;7;1;2;0;2;0;0;0;0;1;0;1;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;7;7;8;30000;0;11;2;1;1;0;-1;-2;1;0;0;1;1;0;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;7;7;9;30000;0;11;1;2;7;0;1;-2;0;0;0;1;0;3;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;7;7;13;30000;0;9;7;1;1;0;0;2;1;0;1;1;0;0;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;7;8;6;30000;0;10;2;1;2;0;0;1;1;0;0;1;0;0;0;1 -NVIDIA A100 80GB PCIe [0x1f79];3;7;8;7;0;0;18;7;1;0;0;1;0;0;0;0;1;1;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;7;8;8;30000;0;10;2;1;4;0;1;-1;0;0;0;1;0;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;7;9;4;30000;0;16;1;1;2;0;-2;0;0;0;1;1;1;3;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;7;9;5;30000;0;13;3;1;2;0;-1;-2;1;0;0;1;1;0;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;7;9;7;30000;0;9;1;8;1;0;-2;-2;1;0;1;1;1;3;1;0 -NVIDIA A100 80GB PCIe [0x1f79];3;7;13;4;30000;0;21;4;1;1;0;1;-2;0;0;0;1;1;0;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;7;13;5;30000;0;9;1;4;3;0;1;1;1;0;1;1;1;3;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;7;13;7;30000;0;16;7;1;1;0;0;0;1;0;1;1;0;0;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;7;13;13;30000;0;9;7;1;1;0;-2;-2;0;0;0;1;0;3;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;8;6;6;30000;0;14;1;2;4;0;-2;-2;0;0;1;1;1;3;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;8;6;7;30000;0;13;2;1;5;0;1;-1;0;0;0;1;0;3;1;0 -NVIDIA A100 80GB PCIe [0x1f79];3;8;6;8;30000;0;20;1;2;8;0;1;1;0;0;0;0;0;0;3;2 -NVIDIA A100 80GB PCIe [0x1f79];3;8;7;6;30000;0;5;1;7;6;0;-1;-1;0;0;1;1;1;0;1;0 -NVIDIA A100 80GB PCIe [0x1f79];3;8;7;7;30000;0;22;2;1;2;0;-2;-1;0;0;0;1;0;0;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;8;7;8;30000;0;16;2;1;3;0;-1;0;1;0;0;1;0;3;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;8;8;6;30000;0;18;8;1;2;0;1;-2;1;0;0;1;0;2;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;8;8;7;30000;0;14;2;1;3;0;-1;-2;0;0;0;1;0;0;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;8;8;8;30000;0;18;8;1;6;0;0;0;0;0;1;1;1;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;9;4;4;30000;0;17;1;1;1;0;-2;1;1;0;0;1;1;3;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;9;4;5;30000;0;11;1;3;1;0;-2;1;1;0;0;1;0;3;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;9;4;7;30000;0;10;2;1;3;0;1;1;1;0;0;1;1;3;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;9;4;9;30000;0;10;1;1;7;0;-2;1;1;0;1;1;1;3;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;9;4;13;30000;0;10;1;2;2;0;0;0;0;0;1;0;0;1;0;1 -NVIDIA A100 80GB PCIe [0x1f79];3;9;5;4;30000;0;18;1;2;3;0;-2;-1;1;0;1;1;0;0;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;9;5;5;30000;0;19;2;1;1;0;-1;0;1;0;1;1;0;3;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;9;5;7;30000;0;12;1;5;5;0;0;-1;1;0;0;1;0;0;1;1 -NVIDIA A100 80GB PCIe [0x1f79];3;9;5;9;30000;0;14;2;1;2;0;1;-2;0;0;0;1;1;0;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;9;7;4;30000;0;16;4;1;1;0;0;1;0;0;0;1;1;0;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;9;7;5;30000;0;18;6;1;3;0;0;-2;0;0;0;1;1;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;9;7;7;30000;0;19;1;1;3;0;1;-1;0;0;0;1;0;0;3;1 -NVIDIA A100 80GB PCIe [0x1f79];3;9;9;4;30000;0;24;9;1;8;0;-2;0;0;0;1;1;1;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;9;9;5;30000;0;17;3;1;7;0;-2;1;0;0;0;1;0;0;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;9;9;9;30000;0;14;9;1;1;0;1;0;0;0;0;1;0;3;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;9;9;16;30000;0;15;3;1;1;0;1;1;0;0;0;1;1;3;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;9;9;22;30000;0;12;1;3;9;0;1;-1;1;0;0;1;0;3;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;9;9;32;0;0;14;1;3;8;0;0;-1;0;0;0;0;1;3;3;1 -NVIDIA A100 80GB PCIe [0x1f79];3;9;13;4;30000;0;17;9;1;3;0;-1;0;1;0;0;1;1;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;9;16;9;30000;0;11;9;1;1;0;1;-2;1;0;0;1;0;3;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;9;16;16;30000;0;10;9;1;1;0;-1;0;0;0;0;1;0;0;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;9;16;22;30000;0;19;5;1;1;0;1;-2;1;0;0;1;0;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;9;22;9;30000;0;10;9;1;1;0;0;-2;1;0;1;1;0;0;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;9;22;16;30000;0;10;9;1;1;0;1;-2;1;0;0;1;1;0;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;9;22;22;30000;0;10;9;1;1;0;-2;0;0;0;0;1;1;3;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;9;22;32;30000;0;15;9;1;1;0;1;0;1;0;1;1;1;0;2;1 -NVIDIA A100 80GB PCIe [0x1f79];3;10;4;4;30000;0;14;1;2;5;0;-2;-1;0;0;0;1;0;3;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;10;4;10;30000;0;10;1;2;1;0;0;-2;1;0;0;1;1;0;0;1 -NVIDIA A100 80GB PCIe [0x1f79];3;10;10;4;30000;0;24;10;1;5;0;1;1;0;0;0;1;1;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;10;10;10;30000;0;9;10;1;1;0;-2;0;0;0;0;1;0;3;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;13;4;4;30000;0;14;13;1;13;0;0;1;0;0;0;1;0;3;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;13;4;5;30000;0;9;13;1;9;0;-1;0;1;0;1;1;1;0;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;13;4;7;30000;0;19;2;1;11;0;1;0;1;0;0;1;1;0;0;1 -NVIDIA A100 80GB PCIe [0x1f79];3;13;4;9;30000;0;9;2;1;1;0;1;-1;1;0;1;1;0;0;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;13;4;13;30000;0;12;13;1;12;0;0;-2;0;0;0;1;1;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;13;4;17;30000;0;10;13;1;1;0;-1;-2;0;0;0;1;0;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;13;4;32;30000;0;15;13;1;2;0;-1;2;1;0;0;1;1;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;13;5;4;30000;0;20;13;1;1;0;-2;-2;0;0;1;1;0;3;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;13;5;5;30000;0;20;13;1;10;0;-1;-2;0;0;0;1;0;0;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;13;5;7;30000;0;6;1;1;13;0;-2;-2;0;0;0;1;1;1;1;2 -NVIDIA A100 80GB PCIe [0x1f79];3;13;5;13;30000;0;6;13;1;12;0;-1;-1;0;0;0;1;0;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;13;5;17;30000;0;5;13;1;1;0;0;-1;0;0;0;1;0;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;13;5;32;30000;0;7;13;1;1;0;0;0;1;0;0;1;1;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;13;7;4;30000;0;21;1;1;11;0;1;-2;1;0;1;1;0;0;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;13;7;5;30000;0;18;3;2;5;0;0;1;1;0;1;1;1;3;3;1 -NVIDIA A100 80GB PCIe [0x1f79];3;13;7;7;30000;0;16;13;1;1;0;-1;0;1;0;1;1;0;3;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;13;7;13;30000;0;10;1;4;8;0;-2;-2;1;0;1;1;0;3;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;13;9;4;30000;0;18;9;1;1;0;0;0;1;0;0;1;1;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;13;13;4;30000;0;24;13;1;13;0;-1;-2;0;0;0;1;0;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;13;13;5;30000;0;24;13;1;3;0;0;0;1;0;0;1;0;1;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;13;13;7;30000;0;14;13;1;1;0;0;0;1;0;0;1;1;1;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;13;13;13;30000;0;9;13;1;4;0;-2;1;1;0;0;1;0;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;13;13;17;30000;0;7;13;1;12;0;1;-1;0;0;0;1;0;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;13;13;32;30000;0;9;13;1;12;0;0;0;0;0;0;1;0;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;13;17;4;30000;0;18;13;1;12;0;-2;-1;0;0;0;1;0;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;13;17;5;30000;0;14;13;1;6;0;0;-1;1;0;0;1;1;1;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;13;17;13;30000;0;15;13;1;8;0;-2;0;0;0;0;1;1;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;13;17;17;30000;0;15;13;1;4;0;-1;0;0;0;1;1;1;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;13;17;32;30000;0;7;13;1;13;0;-1;0;1;0;0;1;1;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;13;32;4;30000;0;22;13;1;7;0;-2;-2;1;0;0;1;1;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;13;32;5;30000;0;18;13;1;10;0;-1;-1;0;0;0;1;0;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;13;32;13;30000;0;20;13;1;13;0;1;-2;0;0;0;1;1;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;13;32;17;30000;0;26;13;1;10;0;-1;-1;0;0;0;1;0;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;13;32;32;30000;0;15;13;1;10;0;-2;-2;0;0;0;1;0;2;3;1 -NVIDIA A100 80GB PCIe [0x1f79];3;15;4;4;30000;0;21;2;1;4;0;1;-2;1;0;0;1;1;3;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;15;15;15;30000;0;15;15;1;1;0;-2;0;1;0;0;1;1;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;16;9;9;30000;0;9;16;1;1;0;-2;-2;0;0;0;1;0;3;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;16;9;16;30000;0;14;2;1;1;0;0;-2;1;0;0;1;1;2;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;16;9;22;30000;0;20;6;1;9;0;0;-2;1;0;0;1;1;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;16;16;9;30000;0;15;16;1;1;0;1;0;1;0;0;1;0;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;16;16;16;30000;0;12;16;1;1;0;-1;2;1;0;0;1;1;1;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;16;16;22;30000;0;14;16;1;1;0;-2;-2;1;0;0;1;1;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;16;22;9;30000;0;13;16;1;1;0;1;0;1;0;1;1;1;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;16;22;16;30000;0;10;16;1;1;0;-2;-2;1;0;1;1;1;1;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;16;22;22;0;0;24;16;1;0;0;1;-2;1;0;0;1;1;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;17;4;4;30000;0;10;17;1;15;0;-2;0;1;0;0;1;0;0;0;2 -NVIDIA A100 80GB PCIe [0x1f79];3;17;4;5;30000;0;22;17;1;15;0;1;-2;0;0;0;1;0;0;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;17;4;13;30000;0;10;17;1;12;0;0;-2;0;0;0;1;1;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;17;4;17;30000;0;10;17;1;3;0;1;1;0;0;0;1;1;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;17;4;32;30000;0;7;17;1;1;0;1;-2;1;0;0;1;1;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;17;5;4;30000;0;24;17;1;2;0;0;-2;0;0;0;1;0;0;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;17;5;5;30000;0;24;17;1;11;0;-1;0;0;0;0;1;0;0;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;17;5;13;30000;0;10;17;1;1;0;0;-1;0;0;0;1;0;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;17;5;17;30000;0;10;17;1;17;0;-1;0;0;0;0;1;0;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;17;5;32;30000;0;4;17;1;17;0;-2;-2;0;0;0;1;0;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;17;13;4;30000;0;19;17;1;7;0;0;1;0;0;0;1;0;0;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;17;13;5;30000;0;18;17;1;16;0;-2;-2;0;0;0;1;1;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;17;13;13;30000;0;12;17;1;17;0;0;0;0;0;0;1;0;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;17;13;17;30000;0;8;17;1;1;0;-2;-2;1;0;0;1;0;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;17;13;32;30000;0;26;17;1;4;0;-1;-2;0;0;0;1;1;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;17;17;4;30000;0;24;17;1;14;0;0;-2;0;0;0;1;0;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;17;17;5;30000;0;24;17;1;15;0;0;0;0;0;0;1;0;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;17;17;13;30000;0;15;17;1;12;0;0;0;0;0;0;1;0;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;17;17;17;30000;0;24;17;1;17;0;0;0;0;0;0;1;0;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;17;17;32;30000;0;7;17;1;16;0;0;-1;0;0;0;1;0;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;17;32;4;30000;0;18;17;1;15;0;1;0;1;0;0;1;0;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;17;32;5;30000;0;18;17;1;16;0;-1;-2;1;0;0;1;1;1;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;17;32;13;30000;0;20;17;1;7;0;-1;0;1;0;1;1;1;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;17;32;17;30000;0;20;17;1;14;0;1;0;0;0;0;1;0;1;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;17;32;32;30000;0;24;17;1;17;0;-2;0;0;0;0;1;0;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;20;20;20;30000;0;10;20;1;1;0;-1;0;1;0;0;1;1;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;22;9;9;30000;0;6;2;5;4;0;-1;1;0;0;0;1;0;3;3;2 -NVIDIA A100 80GB PCIe [0x1f79];3;22;9;16;0;0;14;22;1;0;0;1;-2;0;0;0;1;0;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;22;9;22;0;0;24;22;1;0;0;0;-2;0;0;0;1;1;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;22;9;32;0;0;10;8;1;4;0;0;-1;0;0;0;1;0;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;22;16;9;30000;0;10;22;1;1;0;0;1;1;0;0;1;0;1;1;0 -NVIDIA A100 80GB PCIe [0x1f79];3;22;16;16;0;0;14;22;1;0;0;1;-2;1;0;0;1;0;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;22;16;22;0;0;18;22;1;0;0;1;-2;1;0;0;1;0;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;22;22;9;30000;0;18;22;1;1;0;-2;-2;1;0;1;1;0;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;22;22;16;30000;0;15;22;1;1;0;-1;0;1;0;0;1;1;2;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;22;22;22;30000;0;24;22;1;1;0;-2;-2;1;0;0;1;0;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;22;22;32;0;0;15;22;14;17;0;0;-2;0;0;0;1;0;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;23;23;23;30000;0;24;23;1;13;0;-1;-2;1;0;1;1;1;1;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;24;24;24;0;0;18;24;1;0;0;1;-2;1;0;0;1;1;2;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;25;4;4;0;0;15;25;1;0;0;0;0;0;0;0;1;0;2;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;25;4;5;0;0;18;25;1;0;0;2;-2;0;0;0;1;1;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;25;5;4;0;0;18;25;1;0;0;2;0;0;0;0;1;1;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;25;25;25;0;0;24;25;1;0;0;1;-2;1;0;0;1;0;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;26;4;4;0;0;18;26;1;0;0;2;-2;0;0;0;1;1;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;28;4;4;0;0;18;28;1;0;0;0;0;0;0;0;1;1;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;28;28;28;0;0;18;28;1;0;0;1;-2;1;0;0;1;1;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;30;30;30;0;0;18;30;1;0;0;0;0;0;0;0;1;0;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;32;4;4;30000;0;23;32;1;28;0;-1;0;1;0;1;1;0;3;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;32;4;5;30000;0;17;32;1;16;0;-2;-1;0;0;0;1;0;0;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;32;4;13;30000;0;9;32;1;5;0;-2;0;0;0;0;1;1;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;32;4;17;30000;0;13;32;1;22;0;-2;0;1;0;1;1;1;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;32;4;32;30000;0;24;32;1;7;0;-2;1;1;0;1;1;0;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;32;5;4;30000;0;27;32;1;30;0;-1;1;0;0;0;1;0;3;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;32;5;5;30000;0;18;32;1;29;0;1;-1;0;0;1;1;0;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;32;5;13;30000;0;9;32;1;31;0;1;0;0;0;0;1;0;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;32;5;17;30000;0;20;32;1;20;0;-1;1;0;0;0;1;0;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;32;5;32;30000;0;30;32;1;7;0;1;0;0;0;0;1;0;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;32;13;4;30000;0;18;32;1;31;0;0;-1;1;0;0;1;1;1;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;32;13;5;30000;0;18;32;1;13;0;-2;-1;1;0;1;1;0;1;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;32;13;13;30000;0;11;32;1;29;0;1;2;0;0;0;1;0;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;32;13;17;30000;0;8;32;1;25;0;-2;0;1;0;0;1;0;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;32;13;32;30000;0;35;32;1;10;0;-1;-2;1;0;0;1;0;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;32;17;4;30000;0;24;32;1;13;0;1;1;0;0;1;1;1;2;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;32;17;5;30000;0;18;32;1;15;0;-1;2;1;0;0;1;1;2;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;32;17;13;30000;0;25;32;1;15;0;-2;-1;1;0;1;1;1;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;32;17;17;30000;0;25;32;1;9;0;0;0;0;0;0;1;1;2;3;2 -NVIDIA A100 80GB PCIe [0x1f79];3;32;17;32;30000;0;8;32;1;32;0;0;0;0;0;0;1;0;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;32;32;4;30000;0;38;32;1;17;0;1;0;1;0;1;1;0;2;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;32;32;5;30000;0;26;32;1;22;0;1;-2;1;0;1;1;0;1;0;0 -NVIDIA A100 80GB PCIe [0x1f79];3;32;32;13;30000;0;40;32;1;3;0;0;0;1;0;0;1;0;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;32;32;17;30000;0;24;32;1;31;0;-1;0;1;0;0;1;0;1;3;0 -NVIDIA A100 80GB PCIe [0x1f79];3;32;32;32;30000;0;38;32;1;32;0;-1;-2;1;0;1;1;1;2;3;0 diff --git a/src/acc/opencl/smm/params/tune_multiply_A100.csv b/src/acc/opencl/smm/params/tune_multiply_A100.csv new file mode 100644 index 00000000000..8077da6bbf2 --- /dev/null +++ b/src/acc/opencl/smm/params/tune_multiply_A100.csv @@ -0,0 +1,310 @@ +DEVICE;TYPEID;M;N;K;S;GFLOPS;BS;BM;BN;BK;WS;WG;LU;NZ;AL;TB;TC;AP;AA;AB;AC +NVIDIA A100 80GB PCIe [0x1f79];3;2;2;2;30000;0;9;2;1;2;0;1;-1;0;0;0;1;0;2;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;3;3;3;30000;0;9;3;1;3;1;-1;-2;0;0;0;1;0;2;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;4;4;30000;0;9;1;1;2;1;-1;-2;0;1;0;1;0;2;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;4;5;30000;0;6;1;1;4;0;1;-1;1;0;0;1;1;2;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;4;7;30000;0;7;4;1;2;1;1;-2;0;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;4;9;30000;0;5;4;1;2;1;-1;0;0;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;4;10;30000;0;6;4;1;4;0;0;-1;1;1;1;1;0;1;2;1;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;4;13;30000;0;4;1;1;4;1;-1;0;0;0;0;1;0;2;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;4;15;30000;0;14;4;1;2;0;-2;-1;1;0;1;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;4;17;30000;0;5;4;1;4;0;-2;-1;1;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;4;25;30000;0;14;4;1;2;0;0;1;0;0;0;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;4;26;30000;0;14;4;1;3;0;-2;-1;1;0;1;1;1;1;0;1;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;4;28;30000;0;6;4;1;2;0;-1;-1;0;1;0;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;4;32;30000;0;3;4;1;4;0;1;-1;0;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;5;4;30000;0;12;4;1;4;1;1;-1;0;0;0;1;0;0;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;5;5;30000;0;9;1;1;1;0;-1;1;1;1;0;1;0;0;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;5;7;30000;0;6;4;1;2;1;1;0;0;1;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;5;9;30000;0;6;4;1;2;1;0;-2;0;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;5;13;30000;0;4;4;1;4;0;-1;-2;1;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;5;17;30000;0;5;4;1;2;0;1;-1;0;0;0;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;5;25;30000;0;6;4;1;3;0;-1;-1;0;0;1;0;0;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;5;32;30000;0;2;1;1;2;1;-2;1;0;0;0;1;0;0;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;7;4;30000;0;24;4;1;3;1;0;0;0;0;0;1;0;2;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;7;5;30000;0;14;4;1;2;1;1;-2;0;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;7;7;30000;0;10;4;1;1;0;-1;-1;0;1;1;1;1;0;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;7;9;30000;0;6;4;1;3;0;-2;0;0;1;0;1;0;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;7;13;30000;0;4;4;1;3;0;1;-2;1;0;0;1;0;1;0;1;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;9;4;30000;0;15;4;1;4;0;0;-2;0;0;0;1;1;2;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;9;5;30000;0;10;4;1;2;1;0;-1;0;1;0;1;0;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;9;7;30000;0;14;4;1;4;0;0;-1;0;0;0;1;0;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;9;9;30000;0;10;4;1;4;0;1;-2;0;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;9;13;30000;0;5;4;1;4;0;0;0;0;0;0;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;10;4;30000;0;24;4;1;4;1;-2;-1;0;1;0;1;0;2;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;10;10;30000;0;14;4;1;4;1;0;0;0;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;13;4;30000;0;12;2;1;3;0;1;0;0;1;0;1;0;0;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;13;5;30000;0;16;2;2;4;0;-2;-1;0;1;1;1;0;0;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;13;7;30000;0;14;4;1;1;0;2;0;0;0;0;1;0;2;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;13;9;30000;0;7;4;1;3;0;1;-2;1;1;0;1;1;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;13;13;30000;0;10;4;1;3;0;-2;-2;0;0;0;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;13;17;30000;0;10;4;1;2;0;-2;1;0;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;13;32;30000;0;15;4;1;4;0;-1;-2;0;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;15;4;30000;0;20;4;1;1;0;0;0;0;0;1;1;0;0;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;17;4;30000;0;22;4;1;2;0;-1;-1;1;0;0;1;0;0;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;17;5;30000;0;12;4;1;3;0;1;-2;1;0;0;1;0;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;17;13;30000;0;10;4;1;4;0;0;-2;0;0;0;1;0;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;17;17;30000;0;10;4;1;3;0;-1;-2;0;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;17;32;30000;0;15;4;1;3;0;1;0;0;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;25;4;30000;0;23;4;1;1;0;0;0;0;0;0;1;1;0;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;25;5;30000;0;21;4;1;2;0;0;0;0;0;1;1;0;2;2;1;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;26;4;30000;0;22;4;1;1;0;-2;0;1;0;1;1;0;0;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;28;4;30000;0;18;4;1;1;0;-2;0;0;1;1;1;0;2;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;32;4;30000;0;19;4;1;1;0;0;-2;1;0;0;1;0;2;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;32;5;30000;0;19;4;1;2;1;1;-2;0;1;0;1;0;0;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;32;13;30000;0;12;4;1;3;0;1;-1;0;0;0;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;32;17;30000;0;13;4;1;3;0;1;1;0;0;0;1;1;1;2;1;0 +NVIDIA A100 80GB PCIe [0x1f79];3;4;32;32;30000;0;25;4;1;4;0;1;-1;0;1;0;1;1;1;2;1;0 +NVIDIA A100 80GB PCIe [0x1f79];3;5;4;4;30000;0;9;1;1;5;1;0;-1;0;1;1;1;0;0;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;5;4;5;30000;0;12;1;1;3;1;0;-2;0;1;0;1;0;0;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;5;4;7;30000;0;15;1;1;1;0;-2;0;0;0;0;1;0;2;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;5;4;9;30000;0;12;1;1;5;1;0;0;0;0;0;1;0;2;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;5;4;13;30000;0;10;1;1;2;0;0;-1;0;1;0;0;0;2;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;5;4;17;30000;0;4;1;1;1;1;0;-2;0;1;0;1;0;0;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;5;4;25;30000;0;5;5;1;4;0;1;-2;0;0;0;0;0;2;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;5;4;32;30000;0;2;1;1;2;1;0;0;0;0;0;1;0;2;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;5;5;4;30000;0;10;1;1;2;1;0;0;1;1;0;1;0;2;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;5;5;5;30000;0;18;5;1;2;1;1;-1;0;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;5;5;7;30000;0;7;5;1;5;1;-1;-2;0;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;5;5;9;30000;0;25;5;1;5;0;1;-2;0;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;5;5;13;30000;0;10;1;1;2;1;0;-1;0;0;0;1;0;0;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;5;5;17;30000;0;4;1;1;3;1;0;1;0;0;0;1;0;2;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;5;5;32;30000;0;5;5;1;2;0;-2;-1;0;0;0;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;5;7;4;30000;0;12;5;1;2;1;1;0;0;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;5;7;5;30000;0;14;5;1;2;1;1;-2;0;1;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;5;7;7;30000;0;14;5;1;4;0;-2;0;1;0;1;1;0;2;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;5;7;9;30000;0;16;5;1;4;0;-1;-1;1;0;1;1;0;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;5;7;13;30000;0;12;5;1;5;0;-1;-2;1;0;0;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;5;9;4;30000;0;18;5;1;4;1;0;-2;0;0;0;1;0;2;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;5;9;5;30000;0;24;5;1;3;0;1;-2;0;0;1;1;0;2;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;5;9;7;30000;0;15;5;1;2;0;1;-1;0;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;5;9;9;30000;0;12;5;1;1;0;1;0;1;1;1;1;0;0;0;1;0 +NVIDIA A100 80GB PCIe [0x1f79];3;5;13;4;30000;0;12;5;1;4;0;0;0;0;0;0;1;0;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;5;13;5;30000;0;14;5;1;3;0;-1;0;1;0;1;1;1;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;5;13;7;30000;0;24;5;1;2;0;1;0;1;0;0;1;1;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;5;13;13;30000;0;10;5;1;2;0;-1;0;0;0;0;1;1;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;5;13;17;30000;0;10;5;1;4;0;-2;-1;1;0;0;1;0;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;5;13;32;30000;0;15;5;1;4;0;-2;-1;0;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;5;17;4;30000;0;22;5;1;5;0;-1;0;0;0;0;1;1;0;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;5;17;5;30000;0;12;5;1;4;0;-2;0;1;0;0;1;0;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;5;17;13;30000;0;10;5;1;3;0;0;-1;1;0;1;1;1;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;5;17;17;30000;0;10;5;1;5;0;1;-1;0;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;5;17;32;30000;0;15;5;1;4;0;1;0;0;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;5;25;4;30000;0;29;5;1;1;0;1;-2;0;0;0;1;1;0;0;1;0 +NVIDIA A100 80GB PCIe [0x1f79];3;5;32;4;30000;0;24;5;1;5;0;-2;-1;1;0;1;1;0;0;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;5;32;5;30000;0;20;5;1;5;0;-1;-1;0;0;1;1;1;0;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;5;32;13;30000;0;13;5;1;5;0;1;-1;0;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;5;32;17;30000;0;10;5;1;2;0;1;0;0;0;0;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;5;32;32;30000;0;15;5;1;2;0;-1;0;1;0;0;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;6;6;6;30000;0;10;6;1;2;1;-2;0;0;1;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;6;6;7;30000;0;19;6;1;6;0;-2;-1;1;1;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;6;6;8;30000;0;10;6;1;2;0;1;1;0;0;1;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;6;7;6;30000;0;28;6;1;5;0;-2;0;1;0;0;1;1;2;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;6;7;7;30000;0;11;6;1;2;0;1;-1;1;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;6;7;8;30000;0;14;6;1;4;0;-1;0;1;0;0;1;0;1;2;1;0 +NVIDIA A100 80GB PCIe [0x1f79];3;6;8;6;30000;0;14;6;1;3;0;0;0;0;0;0;1;1;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;6;8;7;30000;0;12;6;1;4;0;-1;-1;0;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;6;8;8;30000;0;26;6;1;4;0;0;-1;0;1;1;1;1;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;7;4;4;30000;0;9;1;1;3;1;-2;0;1;0;0;1;0;0;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;7;4;5;30000;0;10;1;1;2;0;-2;-2;0;0;1;1;0;2;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;7;4;7;30000;0;9;1;1;5;0;-1;-1;0;0;0;1;0;0;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;7;4;9;30000;0;6;1;1;5;0;0;-2;0;0;0;1;0;0;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;7;4;13;30000;0;19;7;1;2;0;-1;-2;0;1;1;1;0;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;7;5;4;30000;0;16;7;1;3;1;1;0;0;1;0;1;0;0;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;7;5;5;30000;0;10;7;1;2;1;-1;1;0;0;0;1;0;0;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;7;5;7;30000;0;14;7;1;2;0;-2;0;0;0;1;1;1;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;7;5;9;30000;0;10;7;1;4;0;1;0;0;1;1;1;0;0;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;7;5;13;30000;0;10;1;2;3;0;1;-2;1;0;1;1;0;2;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;7;6;6;30000;0;14;7;1;7;0;0;-1;0;0;0;1;1;0;0;1;0 +NVIDIA A100 80GB PCIe [0x1f79];3;7;6;7;30000;0;14;2;1;3;0;1;-2;1;0;1;1;1;0;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;7;6;8;30000;0;20;7;1;2;0;0;-1;0;1;1;1;1;0;2;1;0 +NVIDIA A100 80GB PCIe [0x1f79];3;7;7;4;30000;0;24;7;1;2;1;0;-2;0;1;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;7;7;5;30000;0;13;7;1;6;0;-2;0;0;0;0;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;7;7;6;30000;0;35;7;1;3;0;0;1;1;0;1;1;0;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;7;7;7;30000;0;18;7;1;2;0;2;0;0;0;1;1;0;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;7;7;8;30000;0;21;7;1;3;0;-2;1;0;0;0;1;0;1;2;1;0 +NVIDIA A100 80GB PCIe [0x1f79];3;7;7;9;30000;0;7;7;1;4;0;-2;-1;0;0;1;1;0;1;1;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;7;7;13;30000;0;20;7;1;2;0;1;0;1;0;1;1;1;1;1;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;7;8;6;30000;0;19;7;1;3;0;1;-1;0;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;7;8;7;30000;0;12;7;1;4;0;0;-2;0;1;0;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;7;8;8;30000;0;10;7;1;6;0;1;-1;0;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;7;9;4;30000;0;16;7;1;2;0;-2;0;0;0;1;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;7;9;5;30000;0;13;7;1;3;0;0;-2;1;0;0;1;0;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;7;9;7;30000;0;12;7;1;4;0;0;0;0;0;0;1;1;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;7;13;4;30000;0;21;7;1;6;0;0;-2;0;0;1;1;0;0;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;7;13;5;30000;0;9;7;1;4;0;1;0;1;0;1;1;1;1;1;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;7;13;7;30000;0;22;7;1;2;0;0;0;1;0;1;1;0;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;7;13;13;30000;0;5;1;2;3;0;0;-2;1;1;1;1;0;2;0;1;0 +NVIDIA A100 80GB PCIe [0x1f79];3;8;6;6;30000;0;12;1;2;8;1;-1;0;0;0;0;1;0;2;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;8;6;7;30000;0;13;8;1;8;0;-2;-1;0;0;0;1;0;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;8;6;8;30000;0;18;8;1;8;0;1;1;0;0;0;1;0;0;2;1;0 +NVIDIA A100 80GB PCIe [0x1f79];3;8;7;6;30000;0;15;8;1;2;0;0;-1;0;1;0;1;0;2;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;8;7;7;30000;0;10;2;1;2;0;-2;0;0;0;0;1;0;0;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;8;7;8;30000;0;12;2;1;6;0;-1;-1;1;0;1;1;0;2;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;8;8;6;30000;0;18;8;1;2;0;-2;-1;1;0;0;1;0;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;8;8;7;30000;0;14;8;1;3;0;0;-2;0;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;8;8;8;30000;0;12;8;1;5;0;0;-1;0;0;1;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;9;4;4;30000;0;14;9;1;4;1;-1;-2;0;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;9;4;5;30000;0;14;9;1;4;1;1;0;0;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;9;4;7;30000;0;9;2;1;4;1;1;1;0;0;0;1;0;2;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;9;4;9;30000;0;9;1;2;8;1;0;-2;0;1;0;1;0;2;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;9;4;13;30000;0;10;9;1;2;0;1;0;0;0;1;1;0;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;9;5;4;30000;0;14;9;1;7;1;-2;-2;0;0;0;1;0;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;9;5;5;30000;0;12;2;1;3;1;0;0;0;0;0;1;0;2;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;9;5;7;30000;0;18;9;1;4;0;-2;-1;0;0;0;1;0;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;9;5;9;30000;0;14;2;1;3;0;0;-2;0;0;0;1;1;0;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;9;7;4;30000;0;18;9;1;3;0;-1;0;1;0;1;1;1;1;2;1;0 +NVIDIA A100 80GB PCIe [0x1f79];3;9;7;5;30000;0;18;9;1;3;0;0;-2;0;0;1;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;9;7;7;30000;0;10;9;1;3;0;1;-1;0;0;0;1;0;1;2;1;0 +NVIDIA A100 80GB PCIe [0x1f79];3;9;9;4;30000;0;24;9;1;7;0;-2;0;0;0;1;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;9;9;5;30000;0;15;9;1;2;0;0;-2;1;0;1;1;1;0;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;9;9;9;30000;0;14;9;1;9;0;1;-1;0;1;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;9;9;16;30000;0;10;9;1;6;0;1;-1;1;1;1;1;0;1;2;1;0 +NVIDIA A100 80GB PCIe [0x1f79];3;9;9;22;30000;0;10;9;1;2;0;-2;1;0;1;1;1;0;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;9;9;32;30000;0;12;9;1;3;0;-1;-1;0;1;0;1;0;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;9;13;4;30000;0;17;9;1;3;0;-1;0;1;0;0;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;9;16;9;30000;0;12;9;1;2;1;-1;-2;0;1;0;1;0;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;9;16;16;30000;0;2;1;8;8;0;-2;-1;0;0;0;0;0;2;1;1;0 +NVIDIA A100 80GB PCIe [0x1f79];3;9;16;22;30000;0;8;9;1;2;0;-1;0;0;1;0;1;1;1;1;1;0 +NVIDIA A100 80GB PCIe [0x1f79];3;9;22;9;30000;0;15;9;1;2;0;1;-2;1;0;0;1;1;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;9;22;16;30000;0;10;9;1;5;0;-2;-2;1;0;0;1;0;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;9;22;22;30000;0;10;9;1;5;0;-1;-1;1;0;0;1;0;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;9;22;32;30000;0;15;9;1;5;0;1;-2;1;1;0;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;9;32;9;30000;0;13;9;1;4;0;1;-1;1;1;0;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;9;32;22;30000;0;12;9;1;7;0;-1;-2;1;1;1;1;0;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;9;32;32;30000;0;12;9;1;9;0;-1;-2;1;1;1;1;0;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;10;4;4;30000;0;12;1;2;4;0;-2;-1;0;0;0;1;0;2;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;10;4;10;30000;0;10;1;2;6;0;0;-2;0;0;1;1;1;0;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;10;10;4;30000;0;24;10;1;5;0;1;1;0;0;0;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;10;10;10;30000;0;3;10;1;3;0;-2;-1;1;0;0;1;1;1;2;1;0 +NVIDIA A100 80GB PCIe [0x1f79];3;13;4;4;30000;0;16;1;2;5;0;1;1;0;0;0;1;1;0;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;13;4;5;30000;0;9;13;1;9;0;-1;0;1;0;1;1;1;0;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;13;4;7;30000;0;10;2;1;10;1;1;0;0;0;0;1;0;0;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;13;4;9;30000;0;9;2;1;2;0;0;-1;1;0;1;1;0;0;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;13;4;13;30000;0;12;13;1;12;0;0;-2;0;0;0;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;13;4;17;30000;0;10;13;1;1;0;-1;-2;0;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;13;4;32;30000;0;15;13;1;2;0;-1;-1;1;0;0;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;13;5;4;30000;0;9;1;3;13;1;-1;-1;0;1;0;1;0;2;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;13;5;5;30000;0;14;3;1;8;1;0;1;0;0;0;1;0;0;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;13;5;7;30000;0;4;13;1;12;0;1;-1;1;1;1;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;13;5;13;30000;0;10;3;1;9;0;-1;-1;0;0;1;1;0;0;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;13;5;17;30000;0;14;2;2;5;0;-1;0;0;1;0;1;0;0;1;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;13;5;32;30000;0;40;2;2;7;0;-1;0;0;1;0;1;0;0;2;1;0 +NVIDIA A100 80GB PCIe [0x1f79];3;13;7;4;30000;0;14;13;1;10;0;1;-2;0;0;1;1;0;1;1;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;13;7;5;30000;0;18;13;1;4;0;-1;0;1;1;1;1;1;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;13;7;7;30000;0;17;13;1;3;0;-2;1;1;1;1;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;13;7;13;30000;0;10;1;4;4;0;-1;-2;1;0;1;1;0;2;1;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;13;9;4;30000;0;18;13;1;12;0;-1;0;1;0;1;1;1;1;2;1;0 +NVIDIA A100 80GB PCIe [0x1f79];3;13;13;4;30000;0;18;13;1;12;0;0;-2;1;0;1;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;13;13;5;30000;0;24;13;1;3;0;0;0;1;0;0;1;0;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;13;13;7;30000;0;20;13;1;8;0;0;0;1;0;1;1;1;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;13;13;13;30000;0;9;13;1;4;0;-2;1;1;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;13;13;17;30000;0;7;13;1;12;0;1;-1;0;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;13;13;32;30000;0;9;13;1;13;0;0;0;0;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;13;17;4;30000;0;18;13;1;11;0;-2;-1;0;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;13;17;5;30000;0;19;13;1;13;0;-1;-1;1;0;0;1;1;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;13;17;13;30000;0;15;13;1;9;0;-2;0;0;0;0;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;13;17;17;30000;0;15;13;1;5;0;1;-2;0;0;1;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;13;17;32;30000;0;26;13;1;11;0;-2;0;1;0;0;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;13;32;4;30000;0;26;13;1;8;0;-2;-1;1;0;0;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;13;32;5;30000;0;18;13;1;4;0;-1;0;0;0;0;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;13;32;13;30000;0;20;13;1;13;0;1;-1;0;0;0;1;1;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;13;32;17;30000;0;26;13;1;9;0;-1;-1;0;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;13;32;32;30000;0;12;13;1;13;1;-1;0;1;0;0;1;0;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;15;4;4;30000;0;9;2;1;2;1;-1;-2;0;0;0;1;0;0;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;15;15;15;30000;0;15;15;1;2;0;-1;0;1;0;0;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;16;9;9;30000;0;10;16;1;8;0;0;0;1;1;1;1;0;1;1;1;0 +NVIDIA A100 80GB PCIe [0x1f79];3;16;9;16;30000;0;10;16;1;4;0;0;0;0;0;0;1;0;1;0;1;0 +NVIDIA A100 80GB PCIe [0x1f79];3;16;9;22;30000;0;20;16;1;7;0;0;-1;0;0;0;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;16;16;9;30000;0;15;16;1;2;0;0;0;1;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;16;16;16;30000;0;12;16;1;2;0;-1;-1;1;0;0;1;1;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;16;16;22;30000;0;11;16;1;14;0;1;-1;1;1;0;1;1;1;0;1;0 +NVIDIA A100 80GB PCIe [0x1f79];3;16;22;9;30000;0;13;16;1;14;0;1;0;1;0;0;1;1;1;2;1;0 +NVIDIA A100 80GB PCIe [0x1f79];3;16;22;16;30000;0;23;16;1;3;0;-2;-2;1;0;0;1;1;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;16;22;22;30000;0;31;16;1;7;0;-1;-1;1;0;1;1;1;1;0;1;0 +NVIDIA A100 80GB PCIe [0x1f79];3;17;4;4;30000;0;10;17;1;15;0;-2;0;1;0;0;1;0;0;0;1;0 +NVIDIA A100 80GB PCIe [0x1f79];3;17;4;5;30000;0;9;2;2;9;0;-1;-1;1;1;0;1;0;2;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;17;4;13;30000;0;9;3;1;15;0;-2;-1;0;1;0;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;17;4;17;30000;0;10;17;1;3;0;1;1;0;0;0;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;17;4;32;30000;0;7;17;1;1;0;1;-2;1;0;0;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;17;5;4;30000;0;14;3;1;3;0;0;-2;0;0;0;1;0;0;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;17;5;5;30000;0;24;17;1;11;0;-1;0;0;0;0;1;0;0;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;17;5;13;30000;0;10;1;5;13;0;-1;-2;0;1;1;1;1;2;1;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;17;5;17;30000;0;10;17;1;17;0;-1;0;0;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;17;5;32;30000;0;4;17;1;17;0;-2;-2;0;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;17;13;4;30000;0;19;9;1;5;0;0;-1;0;0;0;1;0;0;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;17;13;5;30000;0;14;17;1;16;0;-2;-2;0;0;0;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;17;13;13;30000;0;12;17;1;17;0;0;0;0;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;17;13;17;30000;0;8;17;1;1;0;-2;-2;1;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;17;13;32;30000;0;26;17;1;4;0;-1;-2;0;0;0;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;17;17;4;30000;0;24;17;1;14;0;0;-2;0;1;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;17;17;5;30000;0;18;17;1;15;0;0;-1;0;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;17;17;13;30000;0;15;17;1;9;0;0;-2;0;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;17;17;17;30000;0;24;17;1;17;0;0;0;0;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;17;17;32;30000;0;7;17;1;16;0;0;-1;0;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;17;32;4;30000;0;18;17;1;6;0;-2;-2;1;1;0;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;17;32;5;30000;0;18;17;1;17;0;-1;-2;1;1;0;1;1;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;17;32;13;30000;0;20;17;1;10;0;-1;0;1;0;1;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;17;32;17;30000;0;20;17;1;14;0;1;0;0;0;0;1;0;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;17;32;32;30000;0;24;17;1;2;1;0;-2;1;1;0;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;20;20;20;30000;0;24;20;1;17;0;1;-1;0;0;1;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;22;9;9;30000;0;18;22;1;11;0;1;-1;0;1;1;1;1;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;22;9;16;30000;0;18;22;1;6;0;-1;-1;1;1;1;1;0;1;1;1;0 +NVIDIA A100 80GB PCIe [0x1f79];3;22;9;22;30000;0;7;22;1;3;0;-1;-2;0;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;22;9;32;30000;0;1;22;1;14;0;-2;-2;1;1;0;1;0;2;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;22;16;9;30000;0;13;22;1;10;0;1;0;0;1;1;1;1;1;1;1;0 +NVIDIA A100 80GB PCIe [0x1f79];3;22;16;16;30000;0;7;22;1;3;0;1;-1;1;1;0;1;0;1;0;1;0 +NVIDIA A100 80GB PCIe [0x1f79];3;22;16;22;30000;0;24;22;1;9;0;1;0;1;1;0;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;22;22;9;30000;0;24;22;1;5;0;0;0;1;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;22;22;16;30000;0;15;22;1;15;0;-1;0;1;0;0;1;1;1;0;1;0 +NVIDIA A100 80GB PCIe [0x1f79];3;22;22;22;30000;0;24;22;1;22;0;0;-2;1;0;1;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;22;22;32;30000;0;24;22;1;13;1;0;-2;0;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;22;32;9;30000;0;15;22;1;9;0;-1;1;1;1;0;1;0;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;22;32;22;30000;0;24;22;1;19;0;0;-2;1;0;1;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;22;32;32;30000;0;24;22;1;15;1;-2;-2;0;1;1;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;23;23;23;30000;0;24;23;1;13;0;-1;-2;1;0;1;1;1;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;24;24;24;30000;0;18;24;1;17;1;-1;2;1;1;0;1;1;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;25;4;4;30000;0;19;25;1;10;0;1;1;0;0;1;1;0;1;1;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;25;4;5;30000;0;1;25;1;15;0;0;1;0;1;0;0;1;2;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;25;5;4;30000;0;5;25;1;14;0;-2;0;0;1;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;25;25;25;30000;0;24;25;1;13;1;1;-2;1;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;26;4;4;30000;0;18;26;1;3;0;0;-2;0;0;0;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;28;4;4;30000;0;14;28;1;16;1;1;4;0;0;0;1;0;2;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;28;28;28;30000;0;25;28;1;3;1;1;-2;1;0;1;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;30;30;30;30000;0;41;30;1;16;1;-2;-2;1;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;32;4;4;30000;0;19;2;2;32;0;-1;-1;0;1;0;1;0;0;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;32;4;5;30000;0;10;1;4;26;0;1;0;0;0;0;1;1;2;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;32;4;13;30000;0;9;32;1;5;0;-2;0;0;0;0;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;32;4;17;30000;0;13;32;1;22;0;-2;0;1;0;1;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;32;4;32;30000;0;24;4;1;6;0;-2;1;1;0;1;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;32;5;4;30000;0;34;2;2;13;0;0;0;1;1;1;1;0;0;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;32;5;5;30000;0;20;1;5;14;0;1;0;1;1;1;1;0;2;0;1;0 +NVIDIA A100 80GB PCIe [0x1f79];3;32;5;13;30000;0;10;1;5;19;0;-2;-1;0;0;1;1;1;0;1;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;32;5;17;30000;0;20;32;1;20;0;-1;1;0;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;32;5;32;30000;0;30;32;1;7;0;1;0;0;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;32;9;9;30000;0;24;3;5;26;0;-1;0;0;1;0;1;1;2;2;1;0 +NVIDIA A100 80GB PCIe [0x1f79];3;32;9;22;30000;0;25;3;6;23;0;-2;0;0;0;1;1;1;2;1;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;32;9;32;30000;0;11;5;1;4;0;0;-1;1;1;0;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;32;13;4;30000;0;18;32;1;30;0;0;-1;1;0;0;1;1;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;32;13;5;30000;0;13;1;13;32;0;0;1;0;1;0;1;1;0;1;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;32;13;13;30000;0;6;1;7;31;0;-1;-1;1;0;1;1;0;2;1;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;32;13;17;30000;0;8;32;1;25;0;-2;0;1;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;32;13;32;30000;0;35;32;1;4;1;-1;4;0;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;32;17;4;30000;0;24;32;1;13;0;1;1;0;0;1;1;1;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;32;17;5;30000;0;18;32;1;10;0;-1;-2;1;0;0;1;1;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;32;17;13;30000;0;25;32;1;27;0;-2;0;1;0;1;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;32;17;17;30000;0;25;32;1;11;0;0;0;0;0;0;1;1;1;2;1;0 +NVIDIA A100 80GB PCIe [0x1f79];3;32;17;32;30000;0;8;32;1;32;1;0;0;1;0;1;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;32;22;9;30000;0;28;32;1;11;0;-1;1;1;1;0;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;32;22;22;30000;0;36;32;1;7;1;-1;-1;0;0;0;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;32;22;32;30000;0;28;32;1;31;1;-2;4;1;0;1;1;1;1;1;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;32;32;4;30000;0;38;32;1;17;0;1;0;1;0;1;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;32;32;5;30000;0;26;32;1;22;0;1;-2;1;0;1;1;0;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;32;32;9;30000;0;41;32;1;2;0;0;0;1;0;1;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;32;32;13;30000;0;40;32;1;6;1;0;-2;1;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;32;32;17;30000;0;24;32;1;16;1;-2;0;1;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;32;32;22;30000;0;24;32;1;8;1;0;-2;1;0;0;1;0;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;32;32;32;30000;0;40;32;1;28;1;-2;-2;1;0;1;1;1;1;2;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;35;35;35;30000;0;10;35;1;35;1;0;0;1;0;0;1;1;1;2;1;0 +NVIDIA A100 80GB PCIe [0x1f79];3;36;36;36;30000;0;41;36;1;9;1;-1;4;1;0;1;1;1;1;0;0;0 +NVIDIA A100 80GB PCIe [0x1f79];3;40;40;40;30000;0;13;40;1;40;1;1;0;0;0;0;1;0;1;2;0;0 diff --git a/src/acc/opencl/smm/params/tune_multiply_H100.csv b/src/acc/opencl/smm/params/tune_multiply_H100.csv index b4164dfdc31..45789e7c430 100644 --- a/src/acc/opencl/smm/params/tune_multiply_H100.csv +++ b/src/acc/opencl/smm/params/tune_multiply_H100.csv @@ -1,296 +1,296 @@ DEVICE;TYPEID;M;N;K;S;GFLOPS;BS;BM;BN;BK;WS;WG;LU;NZ;AL;TB;TC;AP;AA;AB;AC -NVIDIA H100 PCIe [0xa32d];3;2;2;2;30000;0;9;2;1;2;0;1;0;0;0;0;1;0;3;3;0 -NVIDIA H100 PCIe [0xa32d];3;3;3;3;30000;0;13;3;1;1;0;-1;-1;1;0;0;1;0;0;3;0 -NVIDIA H100 PCIe [0xa32d];3;4;4;4;30000;0;5;4;1;4;0;0;0;0;0;0;1;0;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;4;4;5;30000;0;11;4;1;3;0;-1;-1;0;0;0;1;0;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;4;4;7;30000;0;6;4;1;2;0;-1;-1;0;0;1;1;0;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;4;4;9;30000;0;6;4;1;3;0;1;-2;0;0;1;1;1;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;4;4;10;30000;0;11;4;1;4;0;1;-2;0;0;0;1;1;3;0;2 -NVIDIA H100 PCIe [0xa32d];3;4;4;13;30000;0;6;4;1;4;0;0;0;1;0;0;1;1;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;4;4;15;30000;0;11;4;1;4;0;-2;0;0;0;0;0;0;0;0;0 -NVIDIA H100 PCIe [0xa32d];3;4;4;17;30000;0;6;4;1;4;0;0;0;1;0;0;1;1;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;4;4;25;30000;0;11;4;1;2;0;1;2;0;0;0;1;0;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;4;4;26;30000;0;6;4;1;2;0;-1;-1;0;0;0;1;1;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;4;4;28;30000;0;22;4;1;4;0;0;0;1;0;0;1;1;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;4;4;32;30000;0;3;4;1;4;0;1;-1;0;0;0;1;0;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;4;5;4;30000;0;15;4;1;4;0;0;-1;0;0;1;1;0;0;3;0 -NVIDIA H100 PCIe [0xa32d];3;4;5;5;30000;0;12;4;1;1;0;0;-1;0;0;0;1;0;0;3;0 -NVIDIA H100 PCIe [0xa32d];3;4;5;7;30000;0;11;4;1;1;0;1;-1;0;0;1;1;0;0;3;0 -NVIDIA H100 PCIe [0xa32d];3;4;5;9;30000;0;12;4;1;2;0;1;2;1;0;0;1;0;3;3;0 -NVIDIA H100 PCIe [0xa32d];3;4;5;13;30000;0;6;4;1;4;0;0;-1;1;0;0;1;0;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;4;5;17;30000;0;6;4;1;3;0;1;0;0;0;0;1;1;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;4;5;25;30000;0;6;4;1;4;0;-2;-2;0;0;0;0;0;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;4;5;32;30000;0;3;4;1;3;0;-1;-1;1;0;0;1;0;2;0;0 -NVIDIA H100 PCIe [0xa32d];3;4;7;4;30000;0;10;4;1;2;0;0;-1;1;0;1;1;0;3;3;0 -NVIDIA H100 PCIe [0xa32d];3;4;7;5;30000;0;14;4;1;1;0;0;0;1;0;1;1;0;0;0;2 -NVIDIA H100 PCIe [0xa32d];3;4;7;7;30000;0;6;4;1;4;0;0;0;0;0;1;1;1;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;4;7;9;30000;0;13;4;1;2;0;1;1;0;0;1;1;1;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;4;7;13;30000;0;11;4;1;4;0;-1;-1;0;0;0;1;0;3;3;0 -NVIDIA H100 PCIe [0xa32d];3;4;9;4;30000;0;12;4;1;1;0;1;-1;0;0;0;1;1;3;3;0 -NVIDIA H100 PCIe [0xa32d];3;4;9;5;30000;0;18;4;1;1;0;-2;0;1;0;0;1;1;3;3;0 -NVIDIA H100 PCIe [0xa32d];3;4;9;7;30000;0;11;4;1;3;0;1;-1;0;0;0;1;0;1;0;0 -NVIDIA H100 PCIe [0xa32d];3;4;9;9;30000;0;12;4;1;3;0;1;-1;0;0;0;1;0;0;3;0 -NVIDIA H100 PCIe [0xa32d];3;4;9;13;30000;0;6;4;1;2;0;-2;0;0;0;0;1;1;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;4;10;4;30000;0;25;4;1;1;0;0;-2;0;0;0;1;0;0;3;0 -NVIDIA H100 PCIe [0xa32d];3;4;10;10;30000;0;10;4;1;3;0;1;-2;1;0;1;1;0;0;0;0 -NVIDIA H100 PCIe [0xa32d];3;4;13;4;30000;0;18;4;1;3;0;0;-2;1;0;1;1;0;0;0;0 -NVIDIA H100 PCIe [0xa32d];3;4;13;5;30000;0;17;4;1;4;0;1;-2;1;0;0;1;1;0;3;0 -NVIDIA H100 PCIe [0xa32d];3;4;13;7;30000;0;14;4;1;1;0;2;-1;1;0;0;1;1;3;0;0 -NVIDIA H100 PCIe [0xa32d];3;4;13;9;30000;0;17;4;1;3;0;-2;-1;0;0;0;1;1;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;4;13;13;30000;0;5;4;1;4;0;-2;-2;0;0;0;1;1;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;4;13;17;30000;0;6;4;1;3;0;1;0;0;0;0;1;0;1;0;0 -NVIDIA H100 PCIe [0xa32d];3;4;13;32;30000;0;3;4;1;3;0;0;-2;0;0;0;1;0;2;0;0 -NVIDIA H100 PCIe [0xa32d];3;4;15;4;30000;0;16;4;1;4;0;-2;-2;0;0;0;1;0;3;3;0 -NVIDIA H100 PCIe [0xa32d];3;4;17;4;30000;0;19;4;1;2;0;0;1;0;0;0;1;0;3;3;0 -NVIDIA H100 PCIe [0xa32d];3;4;17;5;30000;0;9;4;1;4;0;-2;-2;0;0;0;1;1;3;3;0 -NVIDIA H100 PCIe [0xa32d];3;4;17;13;30000;0;6;4;1;4;0;0;-1;0;0;0;1;0;1;0;0 -NVIDIA H100 PCIe [0xa32d];3;4;17;17;30000;0;10;4;1;3;0;0;-1;0;0;1;1;0;0;0;0 -NVIDIA H100 PCIe [0xa32d];3;4;17;32;30000;0;15;4;1;3;0;-2;0;0;0;0;1;1;2;3;2 -NVIDIA H100 PCIe [0xa32d];3;4;25;4;30000;0;17;4;1;3;0;1;-1;0;0;1;1;1;0;0;0 -NVIDIA H100 PCIe [0xa32d];3;4;25;5;30000;0;17;4;1;2;0;1;-2;0;0;0;1;0;3;3;2 -NVIDIA H100 PCIe [0xa32d];3;4;26;4;30000;0;20;4;1;1;0;0;-1;1;0;0;1;1;0;3;0 -NVIDIA H100 PCIe [0xa32d];3;4;28;4;30000;0;20;4;1;4;0;-1;0;1;0;1;1;1;0;3;0 -NVIDIA H100 PCIe [0xa32d];3;4;32;4;30000;0;19;4;1;1;0;0;-2;1;0;1;1;0;3;3;0 -NVIDIA H100 PCIe [0xa32d];3;4;32;5;30000;0;15;4;1;1;0;1;-2;0;0;1;1;0;0;3;0 -NVIDIA H100 PCIe [0xa32d];3;4;32;13;30000;0;13;4;1;4;0;1;0;1;0;0;1;1;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;4;32;17;30000;0;13;4;1;3;0;0;2;0;0;0;1;1;2;3;2 -NVIDIA H100 PCIe [0xa32d];3;4;32;32;30000;0;15;4;1;4;0;0;1;0;0;0;1;0;2;3;2 -NVIDIA H100 PCIe [0xa32d];3;5;4;4;30000;0;12;5;1;5;0;-2;-1;1;0;0;1;1;3;3;0 -NVIDIA H100 PCIe [0xa32d];3;5;4;5;30000;0;11;5;1;3;0;0;0;0;0;0;1;0;0;3;0 -NVIDIA H100 PCIe [0xa32d];3;5;4;7;30000;0;12;5;1;1;0;0;-2;0;0;0;1;1;3;3;0 -NVIDIA H100 PCIe [0xa32d];3;5;4;9;30000;0;13;5;1;5;0;-2;-2;0;0;0;1;0;0;0;0 -NVIDIA H100 PCIe [0xa32d];3;5;4;13;30000;0;1;5;1;3;0;-2;-2;0;0;0;1;1;3;3;0 -NVIDIA H100 PCIe [0xa32d];3;5;4;17;30000;0;1;5;1;3;0;-1;1;0;0;0;1;1;3;3;0 -NVIDIA H100 PCIe [0xa32d];3;5;4;25;30000;0;1;5;1;5;0;0;-1;0;0;1;1;0;3;3;0 -NVIDIA H100 PCIe [0xa32d];3;5;4;32;30000;0;1;5;1;4;0;-2;1;0;0;1;1;1;3;3;0 -NVIDIA H100 PCIe [0xa32d];3;5;5;4;30000;0;14;5;1;3;0;1;-1;1;0;0;1;0;0;3;0 -NVIDIA H100 PCIe [0xa32d];3;5;5;5;30000;0;14;5;1;2;0;0;-1;0;0;0;1;1;2;0;0 -NVIDIA H100 PCIe [0xa32d];3;5;5;7;30000;0;6;5;1;5;0;0;0;1;0;1;1;1;1;0;0 -NVIDIA H100 PCIe [0xa32d];3;5;5;9;30000;0;10;5;1;5;0;-2;0;0;0;0;1;1;2;3;1 -NVIDIA H100 PCIe [0xa32d];3;5;5;13;30000;0;6;5;1;4;0;1;-2;0;0;0;1;0;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;5;5;17;30000;0;6;5;1;3;0;-2;-2;0;0;0;1;1;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;5;5;32;30000;0;6;5;1;5;0;-2;-1;0;0;0;1;1;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;5;7;4;30000;0;16;5;1;3;0;1;0;1;0;1;1;0;0;3;0 -NVIDIA H100 PCIe [0xa32d];3;5;7;5;30000;0;10;5;1;4;0;-2;-2;0;0;0;1;0;0;0;0 -NVIDIA H100 PCIe [0xa32d];3;5;7;7;30000;0;13;5;1;4;0;1;-1;1;0;0;1;1;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;5;7;9;30000;0;12;5;1;4;0;-2;0;0;0;0;1;0;3;3;2 -NVIDIA H100 PCIe [0xa32d];3;5;7;13;30000;0;6;5;1;5;0;-2;0;0;0;0;1;0;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;5;9;4;30000;0;15;5;1;4;0;0;0;1;0;0;1;0;3;3;0 -NVIDIA H100 PCIe [0xa32d];3;5;9;5;30000;0;11;5;1;5;0;-1;-2;1;0;0;1;0;3;0;0 -NVIDIA H100 PCIe [0xa32d];3;5;9;7;30000;0;15;5;1;1;0;1;-1;0;0;1;1;0;0;3;0 -NVIDIA H100 PCIe [0xa32d];3;5;9;9;30000;0;10;5;1;2;0;0;0;0;0;1;1;1;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;5;13;4;30000;0;14;5;1;2;0;-1;0;0;0;0;1;0;0;0;0 -NVIDIA H100 PCIe [0xa32d];3;5;13;5;30000;0;15;5;1;3;0;0;-1;1;0;1;1;0;3;0;0 -NVIDIA H100 PCIe [0xa32d];3;5;13;7;30000;0;11;5;1;3;0;1;0;1;0;0;1;1;0;3;0 -NVIDIA H100 PCIe [0xa32d];3;5;13;13;30000;0;6;5;1;2;0;-2;0;0;0;0;1;1;2;0;0 -NVIDIA H100 PCIe [0xa32d];3;5;13;17;30000;0;6;5;1;5;0;-2;0;0;0;0;1;0;2;0;0 -NVIDIA H100 PCIe [0xa32d];3;5;13;32;30000;0;3;5;1;3;0;-2;0;0;0;0;1;0;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;5;17;4;30000;0;17;5;1;4;0;0;-2;1;0;0;1;0;3;3;0 -NVIDIA H100 PCIe [0xa32d];3;5;17;5;30000;0;16;5;1;4;0;-2;0;0;0;1;1;0;3;0;0 -NVIDIA H100 PCIe [0xa32d];3;5;17;13;30000;0;6;5;1;2;0;0;2;1;0;0;1;1;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;5;17;17;30000;0;6;5;1;4;0;-1;0;0;0;0;1;1;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;5;17;32;30000;0;6;5;1;4;0;1;-2;0;0;0;1;0;2;0;0 -NVIDIA H100 PCIe [0xa32d];3;5;25;4;30000;0;15;5;1;3;0;0;-1;1;0;1;1;0;0;0;0 -NVIDIA H100 PCIe [0xa32d];3;5;32;4;30000;0;22;5;1;5;0;-2;-1;1;0;1;1;0;0;3;0 -NVIDIA H100 PCIe [0xa32d];3;5;32;5;30000;0;16;5;1;4;0;-1;0;1;0;1;1;1;0;3;0 -NVIDIA H100 PCIe [0xa32d];3;5;32;13;30000;0;11;5;1;4;0;1;0;0;0;0;1;0;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;5;32;17;30000;0;13;5;1;3;0;1;-1;0;0;0;1;1;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;5;32;32;30000;0;15;5;1;5;0;1;-1;0;0;0;1;0;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;6;6;6;30000;0;7;6;1;6;0;0;-2;0;0;0;1;0;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;6;6;7;30000;0;11;6;1;4;0;1;-2;0;0;0;1;0;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;6;6;8;30000;0;18;6;1;2;0;-1;1;0;0;0;1;1;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;6;7;6;30000;0;14;6;1;6;0;-2;0;0;0;0;1;0;1;0;0 -NVIDIA H100 PCIe [0xa32d];3;6;7;7;30000;0;17;6;1;2;0;1;1;1;0;1;1;1;1;0;0 -NVIDIA H100 PCIe [0xa32d];3;6;7;8;30000;0;6;6;1;6;0;-1;-1;0;0;0;1;0;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;6;8;6;30000;0;14;6;1;2;0;0;0;0;0;0;1;1;1;0;0 -NVIDIA H100 PCIe [0xa32d];3;6;8;7;30000;0;14;6;1;3;0;0;-2;0;0;0;1;1;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;6;8;8;30000;0;5;6;1;2;0;0;-2;0;0;0;1;1;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;7;4;4;30000;0;12;7;1;5;0;0;0;0;0;0;1;0;0;0;0 -NVIDIA H100 PCIe [0xa32d];3;7;4;5;30000;0;11;7;1;5;0;-2;-1;0;0;1;1;1;3;0;0 -NVIDIA H100 PCIe [0xa32d];3;7;4;7;30000;0;11;7;1;4;0;-2;-2;0;0;0;1;0;0;0;0 -NVIDIA H100 PCIe [0xa32d];3;7;4;9;30000;0;14;7;1;1;0;1;0;0;0;1;1;0;0;0;0 -NVIDIA H100 PCIe [0xa32d];3;7;4;13;30000;0;1;7;1;4;0;-1;0;1;0;1;0;0;0;3;0 -NVIDIA H100 PCIe [0xa32d];3;7;5;4;30000;0;15;7;1;3;0;1;2;1;0;1;1;0;0;0;0 -NVIDIA H100 PCIe [0xa32d];3;7;5;5;30000;0;12;7;1;2;0;1;-2;0;0;0;1;0;3;3;0 -NVIDIA H100 PCIe [0xa32d];3;7;5;7;30000;0;14;7;1;2;0;-2;-2;0;0;0;1;0;3;0;0 -NVIDIA H100 PCIe [0xa32d];3;7;5;9;30000;0;14;7;1;4;0;1;-1;0;0;1;1;0;0;0;0 -NVIDIA H100 PCIe [0xa32d];3;7;5;13;30000;0;12;7;1;1;0;1;-2;0;0;1;1;0;3;0;0 -NVIDIA H100 PCIe [0xa32d];3;7;6;6;30000;0;11;7;1;6;0;0;2;0;0;1;1;1;0;0;1 -NVIDIA H100 PCIe [0xa32d];3;7;6;7;30000;0;11;7;1;2;0;1;-1;1;0;0;1;1;0;3;0 -NVIDIA H100 PCIe [0xa32d];3;7;6;8;30000;0;11;7;1;3;0;0;0;0;0;0;1;0;3;0;0 -NVIDIA H100 PCIe [0xa32d];3;7;7;4;30000;0;18;7;1;2;0;1;-1;0;0;0;1;1;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;7;7;5;30000;0;11;7;1;7;0;1;0;1;0;1;1;0;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;7;7;6;30000;0;17;7;1;2;0;-2;1;1;0;0;1;1;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;7;7;7;30000;0;14;7;1;4;0;0;0;0;0;1;1;1;1;0;0 -NVIDIA H100 PCIe [0xa32d];3;7;7;8;30000;0;24;7;1;2;0;-1;-1;0;0;0;1;0;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;7;7;9;30000;0;6;7;1;2;0;-1;-1;0;0;0;1;0;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;7;7;13;30000;0;6;7;1;2;0;-1;2;0;0;1;1;1;2;0;0 -NVIDIA H100 PCIe [0xa32d];3;7;8;6;30000;0;10;7;1;2;0;-2;1;0;0;1;1;1;1;0;0 -NVIDIA H100 PCIe [0xa32d];3;7;8;7;30000;0;6;7;1;3;0;-1;-2;0;0;0;1;0;1;0;0 -NVIDIA H100 PCIe [0xa32d];3;7;8;8;30000;0;7;7;1;2;0;1;-1;0;0;0;1;0;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;7;9;4;30000;0;16;7;1;2;0;-1;-1;0;0;0;1;0;3;3;0 -NVIDIA H100 PCIe [0xa32d];3;7;9;5;30000;0;12;7;1;2;0;0;0;0;0;0;1;0;1;0;0 -NVIDIA H100 PCIe [0xa32d];3;7;9;7;30000;0;9;7;1;6;0;-1;-1;1;0;1;1;1;2;0;0 -NVIDIA H100 PCIe [0xa32d];3;7;13;4;30000;0;14;7;1;6;0;-2;0;0;0;0;1;1;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;7;13;5;30000;0;11;7;1;2;0;1;1;1;0;1;1;1;2;0;0 -NVIDIA H100 PCIe [0xa32d];3;7;13;7;30000;0;14;7;1;3;0;-1;-2;1;0;1;1;1;1;0;0 -NVIDIA H100 PCIe [0xa32d];3;7;13;13;30000;0;14;7;1;5;0;-2;-1;1;0;1;1;1;2;0;0 -NVIDIA H100 PCIe [0xa32d];3;8;6;6;30000;0;14;8;1;6;0;1;-1;0;0;1;1;0;3;3;0 -NVIDIA H100 PCIe [0xa32d];3;8;6;7;30000;0;14;8;1;7;0;-1;-2;0;0;0;1;0;3;0;0 -NVIDIA H100 PCIe [0xa32d];3;8;6;8;30000;0;11;8;1;4;0;0;-1;0;0;0;1;1;0;0;0 -NVIDIA H100 PCIe [0xa32d];3;8;7;6;30000;0;14;8;1;4;0;1;-1;1;0;0;1;1;1;0;0 -NVIDIA H100 PCIe [0xa32d];3;8;7;7;30000;0;14;8;1;1;0;-2;0;0;0;0;1;0;0;3;0 -NVIDIA H100 PCIe [0xa32d];3;8;7;8;30000;0;16;8;1;4;0;-1;0;0;0;1;1;0;3;3;0 -NVIDIA H100 PCIe [0xa32d];3;8;8;6;30000;0;18;8;1;6;0;0;-1;1;0;1;1;1;1;0;0 -NVIDIA H100 PCIe [0xa32d];3;8;8;7;30000;0;17;8;1;3;0;-1;1;0;0;0;1;1;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;8;8;8;30000;0;14;8;1;3;0;0;-2;0;0;1;1;1;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;9;4;4;30000;0;11;9;1;3;0;-1;1;1;0;0;1;0;3;3;0 -NVIDIA H100 PCIe [0xa32d];3;9;4;5;30000;0;11;9;1;4;0;1;1;1;0;0;1;1;0;3;0 -NVIDIA H100 PCIe [0xa32d];3;9;4;7;30000;0;11;9;1;3;0;1;-2;1;0;0;1;1;3;0;0 -NVIDIA H100 PCIe [0xa32d];3;9;4;9;30000;0;1;9;1;9;0;-2;-2;0;0;0;0;1;3;0;1 -NVIDIA H100 PCIe [0xa32d];3;9;4;13;30000;0;1;9;1;6;0;-2;0;0;0;0;0;0;3;0;1 -NVIDIA H100 PCIe [0xa32d];3;9;5;4;30000;0;13;9;1;2;0;-2;1;0;0;0;1;1;1;0;0 -NVIDIA H100 PCIe [0xa32d];3;9;5;5;30000;0;14;9;1;2;0;0;2;1;0;1;1;0;3;0;0 -NVIDIA H100 PCIe [0xa32d];3;9;5;7;30000;0;17;9;1;2;0;-1;-2;0;0;1;1;1;0;0;1 -NVIDIA H100 PCIe [0xa32d];3;9;5;9;30000;0;15;9;1;2;0;1;-2;0;0;0;1;1;0;3;0 -NVIDIA H100 PCIe [0xa32d];3;9;7;4;30000;0;14;9;1;3;0;0;-2;1;0;1;1;0;3;3;0 -NVIDIA H100 PCIe [0xa32d];3;9;7;5;30000;0;12;9;1;5;0;0;-2;0;0;0;1;1;3;3;0 -NVIDIA H100 PCIe [0xa32d];3;9;7;7;30000;0;10;9;1;3;0;0;0;0;0;0;1;1;1;0;0 -NVIDIA H100 PCIe [0xa32d];3;9;9;4;30000;0;18;9;1;9;0;-1;-1;0;0;0;1;1;2;2;0 -NVIDIA H100 PCIe [0xa32d];3;9;9;5;30000;0;21;9;1;4;0;-2;-1;0;0;0;1;1;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;9;9;9;30000;0;7;9;1;3;0;-2;0;1;0;0;1;0;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;9;9;16;30000;0;6;9;1;2;0;-2;0;1;0;1;1;1;2;0;0 -NVIDIA H100 PCIe [0xa32d];3;9;9;22;30000;0;11;9;1;8;0;1;-2;1;0;1;1;0;2;0;0 -NVIDIA H100 PCIe [0xa32d];3;9;9;32;30000;0;22;9;1;5;0;-2;-2;0;0;0;1;1;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;9;13;4;30000;0;14;9;1;3;0;-1;0;1;0;0;1;1;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;9;16;9;30000;0;18;9;1;6;0;0;0;0;0;0;1;1;2;0;2 -NVIDIA H100 PCIe [0xa32d];3;9;16;16;30000;0;4;9;1;4;0;-1;1;1;0;0;1;1;2;0;0 -NVIDIA H100 PCIe [0xa32d];3;9;16;22;30000;0;10;9;1;8;0;1;1;1;0;1;1;1;1;0;1 -NVIDIA H100 PCIe [0xa32d];3;9;22;9;30000;0;20;9;1;4;0;1;0;1;0;0;1;1;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;9;22;16;30000;0;13;9;1;4;0;1;0;1;0;1;1;1;2;0;0 -NVIDIA H100 PCIe [0xa32d];3;9;22;22;30000;0;13;9;1;5;0;-1;0;1;0;0;1;1;2;0;0 -NVIDIA H100 PCIe [0xa32d];3;9;22;32;30000;0;24;9;1;8;0;1;-2;1;0;0;1;0;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;10;4;4;30000;0;15;10;1;5;0;-1;0;0;0;0;1;0;3;3;0 -NVIDIA H100 PCIe [0xa32d];3;10;4;10;30000;0;1;10;1;3;0;-1;-2;0;0;1;0;0;3;3;0 -NVIDIA H100 PCIe [0xa32d];3;10;10;4;30000;0;14;10;1;10;0;1;-1;0;0;1;1;1;2;2;0 -NVIDIA H100 PCIe [0xa32d];3;10;10;10;30000;0;18;10;1;4;0;-1;-2;1;0;0;1;1;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;13;4;4;30000;0;10;13;1;3;0;1;0;0;0;1;1;0;3;1;0 -NVIDIA H100 PCIe [0xa32d];3;13;4;5;30000;0;1;13;1;8;0;-1;2;0;0;1;0;1;3;0;0 -NVIDIA H100 PCIe [0xa32d];3;13;4;7;30000;0;12;13;1;6;0;-1;-2;0;0;0;1;1;0;0;0 -NVIDIA H100 PCIe [0xa32d];3;13;4;9;30000;0;1;13;1;8;0;-2;1;0;0;1;1;1;3;3;2 -NVIDIA H100 PCIe [0xa32d];3;13;4;13;30000;0;1;13;1;11;0;0;2;1;0;1;0;1;3;3;0 -NVIDIA H100 PCIe [0xa32d];3;13;4;17;30000;0;1;13;1;5;0;0;2;1;0;1;1;1;3;3;2 -NVIDIA H100 PCIe [0xa32d];3;13;4;32;30000;0;22;13;1;2;0;0;-1;1;0;0;1;1;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;13;5;4;30000;0;11;13;1;13;0;1;0;1;0;1;1;0;2;0;0 -NVIDIA H100 PCIe [0xa32d];3;13;5;5;30000;0;14;13;1;7;0;1;0;0;0;0;1;1;2;0;0 -NVIDIA H100 PCIe [0xa32d];3;13;5;7;30000;0;6;13;1;12;0;0;0;0;0;0;1;1;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;13;5;13;30000;0;1;13;1;8;0;-1;-2;1;0;0;1;1;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;13;5;17;30000;0;11;13;1;4;0;-1;0;0;0;0;1;0;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;13;5;32;30000;0;17;13;1;4;0;-2;-2;0;0;1;1;1;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;13;7;4;30000;0;18;13;1;13;0;-2;-1;0;0;0;1;1;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;13;7;5;30000;0;10;13;1;4;0;1;0;1;0;1;1;1;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;13;7;7;30000;0;14;13;1;9;0;-2;-2;1;0;1;1;1;2;0;0 -NVIDIA H100 PCIe [0xa32d];3;13;7;13;30000;0;14;13;1;4;0;-2;2;0;0;1;1;1;2;0;0 -NVIDIA H100 PCIe [0xa32d];3;13;9;4;30000;0;14;13;1;8;0;1;-2;0;0;1;1;1;1;0;0 -NVIDIA H100 PCIe [0xa32d];3;13;13;4;30000;0;24;13;1;10;0;-1;-2;0;0;0;1;0;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;13;13;5;30000;0;20;13;1;6;0;0;-1;1;0;0;1;0;1;0;0 -NVIDIA H100 PCIe [0xa32d];3;13;13;7;30000;0;17;13;1;3;0;1;-2;1;0;0;1;1;1;0;0 -NVIDIA H100 PCIe [0xa32d];3;13;13;13;30000;0;11;13;1;5;0;-2;1;1;0;0;1;0;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;13;13;17;30000;0;17;13;1;8;0;-2;-2;1;0;0;1;1;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;13;13;32;30000;0;6;13;1;5;0;1;-2;1;0;0;1;1;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;13;17;4;30000;0;18;13;1;9;0;-2;-1;1;0;0;1;1;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;13;17;5;30000;0;17;13;1;5;0;0;2;1;0;0;1;1;1;0;0 -NVIDIA H100 PCIe [0xa32d];3;13;17;13;30000;0;11;13;1;10;0;-2;0;0;0;0;1;1;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;13;17;17;30000;0;17;13;1;2;0;-2;1;0;0;0;1;1;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;13;17;32;30000;0;17;13;1;12;0;1;0;0;0;0;1;1;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;13;32;4;30000;0;25;13;1;11;0;-2;-2;1;0;0;1;1;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;13;32;5;30000;0;18;13;1;10;0;1;0;1;0;0;1;0;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;13;32;13;30000;0;22;13;1;12;0;0;-2;0;0;0;1;1;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;13;32;17;30000;0;25;13;1;10;0;-1;-1;0;0;0;1;1;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;13;32;32;30000;0;15;13;1;12;0;0;0;1;0;0;1;0;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;15;4;4;30000;0;9;15;1;11;0;1;-2;1;0;0;1;0;3;3;0 -NVIDIA H100 PCIe [0xa32d];3;15;15;15;30000;0;12;15;1;7;0;-2;-2;0;0;1;1;0;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;16;9;9;30000;0;17;16;1;3;0;-2;1;0;0;1;1;1;2;0;0 -NVIDIA H100 PCIe [0xa32d];3;16;9;16;30000;0;1;16;1;3;0;-1;1;1;0;1;0;0;3;0;2 -NVIDIA H100 PCIe [0xa32d];3;16;9;22;30000;0;17;16;1;6;0;0;-2;1;0;0;1;1;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;16;16;9;30000;0;17;16;1;10;0;1;-1;1;0;0;1;1;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;16;16;16;30000;0;14;16;1;4;0;-2;0;0;0;0;1;1;2;0;0 -NVIDIA H100 PCIe [0xa32d];3;16;16;22;30000;0;25;16;1;5;0;-2;-1;1;0;0;1;1;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;16;22;9;30000;0;17;16;1;3;0;1;1;1;0;1;1;1;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;16;22;16;30000;0;9;16;1;13;0;1;-2;1;0;1;1;1;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;16;22;22;30000;0;15;16;1;16;0;0;-2;0;0;1;1;0;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;17;4;4;30000;0;14;17;1;13;0;-2;0;1;0;0;1;0;0;0;2 -NVIDIA H100 PCIe [0xa32d];3;17;4;5;30000;0;11;17;1;16;0;1;0;0;0;1;1;1;2;0;0 -NVIDIA H100 PCIe [0xa32d];3;17;4;13;30000;0;1;17;1;8;0;-2;1;0;0;0;0;0;3;3;0 -NVIDIA H100 PCIe [0xa32d];3;17;4;17;30000;0;1;17;1;9;0;1;0;1;0;0;0;1;0;3;1 -NVIDIA H100 PCIe [0xa32d];3;17;4;32;30000;0;1;17;1;3;0;-1;0;1;0;1;1;0;3;3;2 -NVIDIA H100 PCIe [0xa32d];3;17;5;4;30000;0;14;17;1;4;0;-2;2;0;0;1;1;1;1;0;0 -NVIDIA H100 PCIe [0xa32d];3;17;5;5;30000;0;1;17;1;4;0;-2;1;0;0;1;0;0;3;0;2 -NVIDIA H100 PCIe [0xa32d];3;17;5;13;30000;0;1;17;1;7;0;1;-1;0;0;1;1;0;3;3;0 -NVIDIA H100 PCIe [0xa32d];3;17;5;17;30000;0;1;17;1;5;0;-1;-2;1;0;0;1;0;1;3;1 -NVIDIA H100 PCIe [0xa32d];3;17;5;32;30000;0;1;17;1;2;0;1;1;0;0;0;1;0;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;17;13;4;30000;0;19;17;1;5;0;1;1;1;0;1;1;0;0;3;2 -NVIDIA H100 PCIe [0xa32d];3;17;13;5;30000;0;18;17;1;17;0;1;-2;0;0;0;1;1;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;17;13;13;30000;0;12;17;1;17;0;0;-1;0;0;1;1;0;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;17;13;17;30000;0;10;17;1;15;0;-2;-2;1;0;0;1;1;2;3;2 -NVIDIA H100 PCIe [0xa32d];3;17;13;32;30000;0;22;17;1;4;0;0;-2;0;0;0;1;1;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;17;17;4;30000;0;24;17;1;11;0;-2;-2;0;0;0;1;0;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;17;17;5;30000;0;24;17;1;5;0;1;0;0;0;0;1;0;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;17;17;13;30000;0;22;17;1;17;0;-1;0;0;0;0;1;0;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;17;17;17;30000;0;24;17;1;14;0;0;-1;0;0;0;1;0;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;17;17;32;30000;0;11;17;1;9;0;1;-1;0;0;0;1;0;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;17;32;4;30000;0;18;17;1;8;0;1;1;1;0;0;1;0;2;0;0 -NVIDIA H100 PCIe [0xa32d];3;17;32;5;30000;0;18;17;1;13;0;-1;-2;1;0;0;1;1;1;0;0 -NVIDIA H100 PCIe [0xa32d];3;17;32;13;30000;0;15;17;1;4;0;0;0;1;0;1;1;1;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;17;32;17;30000;0;15;17;1;16;0;1;0;0;0;0;1;0;1;0;0 -NVIDIA H100 PCIe [0xa32d];3;17;32;32;30000;0;22;17;1;11;0;0;-2;0;0;0;1;1;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;20;20;20;30000;0;10;20;1;13;0;-1;-1;1;0;0;1;1;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;22;9;9;30000;0;17;22;1;9;0;0;1;0;0;0;1;1;1;0;0 -NVIDIA H100 PCIe [0xa32d];3;22;9;16;30000;0;10;22;1;17;0;1;0;0;0;0;1;1;2;0;2 -NVIDIA H100 PCIe [0xa32d];3;22;9;22;30000;0;14;22;1;21;0;1;0;0;0;1;1;1;2;0;0 -NVIDIA H100 PCIe [0xa32d];3;22;9;32;30000;0;1;22;1;3;0;0;-1;0;0;0;1;0;3;3;0 -NVIDIA H100 PCIe [0xa32d];3;22;16;9;30000;0;13;22;1;11;0;-1;1;1;0;0;1;0;1;1;0 -NVIDIA H100 PCIe [0xa32d];3;22;16;16;30000;0;17;22;1;11;0;-1;0;1;0;1;1;1;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;22;16;22;30000;0;22;22;1;3;0;-1;0;0;0;0;1;0;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;22;22;9;30000;0;13;22;1;4;0;-2;2;1;0;1;1;0;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;22;22;16;30000;0;14;22;1;7;0;-1;-1;1;0;0;1;1;2;0;0 -NVIDIA H100 PCIe [0xa32d];3;22;22;22;30000;0;24;22;1;9;0;0;-1;0;0;1;1;1;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;22;22;32;30000;0;33;22;1;17;0;1;-2;0;0;0;1;1;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;23;23;23;30000;0;22;23;1;23;0;-1;-1;0;0;0;1;1;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;24;24;24;30000;0;18;24;1;20;0;-2;-2;0;0;0;1;1;2;0;0 -NVIDIA H100 PCIe [0xa32d];3;25;4;4;30000;0;1;25;1;16;0;-1;-2;0;0;0;0;0;3;2;0 -NVIDIA H100 PCIe [0xa32d];3;25;4;5;30000;0;1;25;1;3;0;1;-2;1;0;1;1;1;3;3;2 -NVIDIA H100 PCIe [0xa32d];3;25;5;4;30000;0;13;25;1;9;0;0;0;0;0;0;1;0;1;0;0 -NVIDIA H100 PCIe [0xa32d];3;25;25;25;30000;0;26;25;1;10;0;-1;-1;1;0;0;1;1;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;26;4;4;30000;0;12;26;1;4;0;1;-2;0;0;1;1;0;3;0;2 -NVIDIA H100 PCIe [0xa32d];3;28;4;4;30000;0;1;28;1;26;0;-2;0;1;0;1;1;1;3;3;2 -NVIDIA H100 PCIe [0xa32d];3;28;28;28;30000;0;24;28;1;18;0;1;0;1;0;1;1;1;2;0;2 -NVIDIA H100 PCIe [0xa32d];3;30;30;30;30000;0;11;30;1;19;0;0;0;0;0;0;1;0;2;0;2 -NVIDIA H100 PCIe [0xa32d];3;32;4;4;30000;0;17;32;1;17;0;1;-2;0;0;1;1;0;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;32;4;5;30000;0;1;32;1;13;0;-1;1;0;0;0;0;1;3;1;2 -NVIDIA H100 PCIe [0xa32d];3;32;4;13;30000;0;1;32;1;12;0;-1;-1;0;0;0;1;1;3;0;1 -NVIDIA H100 PCIe [0xa32d];3;32;4;17;30000;0;1;32;1;25;0;-2;-1;0;0;0;0;0;3;3;2 -NVIDIA H100 PCIe [0xa32d];3;32;4;32;30000;0;1;32;1;15;0;0;-2;0;0;0;1;0;2;0;0 -NVIDIA H100 PCIe [0xa32d];3;32;5;4;30000;0;17;32;1;6;0;0;1;0;0;0;1;1;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;32;5;5;30000;0;18;32;1;24;0;-2;-1;0;0;0;1;1;2;0;0 -NVIDIA H100 PCIe [0xa32d];3;32;5;13;30000;0;1;32;1;29;0;0;0;0;0;0;1;0;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;32;5;17;30000;0;1;32;1;21;0;-1;1;0;0;0;1;0;3;3;2 -NVIDIA H100 PCIe [0xa32d];3;32;5;32;30000;0;24;32;1;32;0;1;-2;1;0;0;1;1;2;0;2 -NVIDIA H100 PCIe [0xa32d];3;32;13;4;30000;0;18;32;1;29;0;0;-1;1;0;0;1;1;1;0;0 -NVIDIA H100 PCIe [0xa32d];3;32;13;5;30000;0;18;32;1;9;0;1;-2;1;0;0;1;1;1;0;0 -NVIDIA H100 PCIe [0xa32d];3;32;13;13;30000;0;22;32;1;26;0;1;-1;0;0;0;1;1;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;32;13;17;30000;0;24;32;1;21;0;-2;-1;1;0;0;1;0;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;32;13;32;30000;0;5;32;1;19;0;-1;-2;1;0;0;1;0;2;3;2 -NVIDIA H100 PCIe [0xa32d];3;32;17;4;30000;0;17;32;1;9;0;1;-1;0;0;0;1;1;2;0;0 -NVIDIA H100 PCIe [0xa32d];3;32;17;5;30000;0;18;32;1;9;0;-2;-2;1;0;0;1;1;2;0;0 -NVIDIA H100 PCIe [0xa32d];3;32;17;13;30000;0;22;32;1;5;0;-2;-2;1;0;1;1;1;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;32;17;17;30000;0;22;32;1;8;0;1;0;1;0;0;1;1;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;32;17;32;30000;0;4;32;1;25;0;1;0;0;0;0;1;0;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;32;32;4;30000;0;37;32;1;21;0;0;0;0;0;1;1;0;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;32;32;5;30000;0;33;32;1;11;0;0;-1;1;0;0;1;1;1;1;0 -NVIDIA H100 PCIe [0xa32d];3;32;32;13;30000;0;34;32;1;7;0;0;0;1;0;1;1;0;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;32;32;17;30000;0;24;32;1;32;0;-1;0;1;0;1;1;0;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;32;32;32;30000;0;22;32;1;18;0;1;-2;1;0;0;1;1;2;3;0 -NVIDIA H100 PCIe [0xa32d];3;35;35;35;30000;0;27;35;1;35;0;1;0;0;0;0;1;0;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;36;36;36;30000;0;17;36;1;36;0;0;0;0;0;0;1;0;1;3;0 -NVIDIA H100 PCIe [0xa32d];3;40;40;40;30000;0;8;40;1;30;0;-1;0;0;0;0;1;0;2;3;0 +NVIDIA H100 PCIe [0xa32d];3;2;2;2;30000;0;11;2;1;1;1;-2;0;0;1;1;1;0;2;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;3;3;3;30000;0;14;3;1;3;1;-1;-1;0;1;0;1;0;0;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;4;4;30000;0;17;4;1;4;1;1;-1;0;1;0;1;0;0;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;4;5;30000;0;14;4;1;1;1;1;-1;0;0;0;1;0;2;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;4;7;30000;0;16;4;1;1;1;-2;-2;1;1;1;1;0;2;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;4;9;30000;0;6;4;1;2;1;0;-2;0;1;1;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;4;10;30000;0;5;4;1;4;1;-1;0;1;0;1;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;4;13;30000;0;6;4;1;4;1;-1;-2;1;1;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;4;15;30000;0;14;4;1;4;1;-1;-1;0;0;0;0;0;0;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;4;17;30000;0;6;4;1;2;1;1;-2;0;1;0;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;4;25;30000;0;6;4;1;2;1;-1;1;1;1;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;4;26;30000;0;6;4;1;4;1;-1;0;0;0;0;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;4;28;30000;0;6;4;1;4;1;0;0;0;1;0;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;4;32;30000;0;6;4;1;4;1;-1;-2;0;0;0;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;5;4;30000;0;15;4;1;2;1;-2;-1;0;1;1;1;0;2;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;5;5;30000;0;14;4;1;3;1;-2;-1;1;1;1;1;0;0;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;5;7;30000;0;15;4;1;1;1;0;0;0;0;0;1;0;2;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;5;9;30000;0;12;4;1;1;1;-1;0;1;1;0;1;0;0;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;5;13;30000;0;6;4;1;4;1;0;-2;0;0;0;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;5;17;30000;0;6;4;1;3;1;1;-2;0;1;0;1;0;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;5;25;30000;0;6;4;1;4;1;0;2;1;0;0;1;0;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;5;32;30000;0;3;4;1;3;1;0;0;1;1;0;1;0;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;7;4;30000;0;17;4;1;2;1;-1;0;0;1;1;1;0;0;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;7;5;30000;0;14;4;1;4;1;1;0;1;1;1;1;0;2;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;7;7;30000;0;15;4;1;1;1;-1;0;0;0;0;1;0;2;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;7;9;30000;0;15;4;1;2;1;0;-2;0;1;0;1;0;0;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;7;13;30000;0;14;4;1;2;1;0;0;0;0;0;1;0;2;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;9;4;30000;0;15;4;1;2;1;-2;-2;0;1;0;1;0;2;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;9;5;30000;0;12;4;1;2;1;-2;-1;0;1;1;1;0;2;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;9;7;30000;0;15;4;1;2;1;-2;0;1;1;0;1;0;2;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;9;9;30000;0;12;4;1;3;1;1;-1;0;0;0;1;0;0;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;9;13;30000;0;6;4;1;2;1;-2;-1;0;0;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;10;4;30000;0;18;4;1;4;1;-2;-1;0;1;1;1;0;0;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;10;10;30000;0;11;4;1;3;1;1;-2;1;0;0;1;0;0;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;13;4;30000;0;17;4;1;3;1;0;-1;0;0;1;1;0;0;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;13;5;30000;0;15;4;1;3;1;-2;0;1;0;1;1;0;2;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;13;7;30000;0;14;4;1;2;1;-1;2;0;0;0;1;0;2;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;13;9;30000;0;14;4;1;4;1;-2;0;0;0;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;13;13;30000;0;6;4;1;3;1;1;-2;0;0;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;13;17;30000;0;6;4;1;4;1;-1;0;0;0;1;1;0;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;13;32;30000;0;12;4;1;2;1;-1;1;1;0;0;1;0;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;15;4;30000;0;19;4;1;2;1;1;1;0;1;1;1;0;2;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;17;4;30000;0;17;4;1;3;1;-2;-2;0;0;0;1;0;2;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;17;5;30000;0;18;4;1;3;1;-2;-1;0;1;0;1;1;2;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;17;13;30000;0;14;4;1;2;1;1;2;1;1;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;17;17;30000;0;12;4;1;4;1;-2;-2;0;0;0;1;0;0;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;17;32;30000;0;15;4;1;2;1;-1;-2;1;1;0;1;0;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;25;4;30000;0;17;4;1;1;1;1;0;1;0;1;1;0;2;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;25;5;30000;0;14;4;1;4;25;0;0;0;0;0;1;0;2;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;26;4;30000;0;19;4;1;1;1;0;-1;1;0;1;1;1;0;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;28;4;30000;0;20;4;1;3;1;-1;-1;0;1;1;1;1;2;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;32;4;30000;0;19;4;1;1;1;0;-2;1;0;0;1;0;2;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;32;5;30000;0;18;4;1;1;1;0;-2;0;1;1;1;1;0;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;32;13;30000;0;12;4;1;2;1;-1;1;0;1;0;1;0;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;4;32;17;30000;0;12;4;1;2;1;0;4;0;0;0;1;1;1;0;1;0 +NVIDIA H100 PCIe [0xa32d];3;4;32;32;30000;0;15;4;1;4;1;0;1;0;0;0;1;0;1;2;1;0 +NVIDIA H100 PCIe [0xa32d];3;5;4;4;30000;0;17;5;1;3;1;-2;-1;1;0;1;1;0;2;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;5;4;5;30000;0;14;5;1;2;1;-1;1;0;0;0;1;0;0;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;5;4;7;30000;0;14;5;1;2;1;-1;-1;1;0;0;1;0;2;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;5;4;9;30000;0;14;5;1;4;1;1;0;0;0;0;1;0;2;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;5;4;13;30000;0;11;5;1;2;5;0;-2;0;1;0;1;0;2;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;5;4;17;30000;0;11;5;1;2;5;0;3;0;0;0;0;0;2;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;5;4;25;30000;0;15;5;1;5;5;0;0;0;1;1;0;1;2;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;5;4;32;30000;0;12;5;1;5;5;-1;0;0;0;1;1;0;2;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;5;5;4;30000;0;15;5;1;2;1;1;-2;0;1;1;1;0;0;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;5;5;5;30000;0;6;5;1;4;1;0;0;0;1;1;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;5;5;7;30000;0;6;5;1;5;1;0;-2;1;0;1;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;5;5;9;30000;0;5;5;1;2;1;0;-2;1;0;0;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;5;5;13;30000;0;5;5;1;4;1;1;-2;1;1;1;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;5;5;17;30000;0;6;5;1;5;1;-2;-2;0;0;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;5;5;32;30000;0;6;5;1;4;1;-2;0;1;0;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;5;7;4;30000;0;16;5;1;2;1;0;-1;0;0;1;1;0;2;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;5;7;5;30000;0;14;5;1;3;1;-2;-2;0;1;0;1;0;0;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;5;7;7;30000;0;5;5;1;4;1;-2;-1;0;0;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;5;7;9;30000;0;12;5;1;2;1;-2;0;0;1;0;1;0;0;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;5;7;13;30000;0;6;5;1;5;1;-2;-1;0;1;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;5;9;4;30000;0;18;5;1;2;1;-1;4;0;0;0;1;0;2;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;5;9;5;30000;0;14;5;1;3;1;-1;0;0;1;1;1;0;2;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;5;9;7;30000;0;14;5;1;1;1;1;0;0;0;1;1;0;0;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;5;9;9;30000;0;10;5;1;2;1;1;2;0;0;1;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;5;13;4;30000;0;21;5;1;2;1;-1;-1;0;1;0;1;0;0;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;5;13;5;30000;0;15;5;1;1;1;1;-1;0;0;0;1;0;0;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;5;13;7;30000;0;14;5;1;1;1;0;-2;1;0;1;1;0;2;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;5;13;13;30000;0;10;5;1;4;1;1;0;0;0;1;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;5;13;17;30000;0;10;5;1;4;1;-2;0;0;0;1;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;5;13;32;30000;0;5;5;1;5;1;-1;-2;0;1;0;1;0;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;5;17;4;30000;0;17;5;1;4;1;-1;-2;1;0;0;1;0;2;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;5;17;5;30000;0;16;5;1;4;1;1;0;0;1;1;1;0;2;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;5;17;13;30000;0;10;5;1;4;1;-1;-1;0;0;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;5;17;17;30000;0;11;5;1;3;1;-1;-1;0;0;0;1;0;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;5;17;32;30000;0;10;5;1;4;1;1;-2;0;0;1;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;5;25;4;30000;0;21;5;1;3;1;-1;0;1;0;1;1;0;2;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;5;32;4;30000;0;19;5;1;2;1;-2;1;1;0;1;1;0;0;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;5;32;5;30000;0;18;5;1;4;1;-2;-2;1;0;1;1;1;2;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;5;32;13;30000;0;12;5;1;3;1;0;-1;1;1;0;1;0;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;5;32;17;30000;0;12;5;1;3;1;0;-2;0;0;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;5;32;32;30000;0;15;5;1;5;1;0;-2;0;0;0;1;0;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;6;6;6;30000;0;6;6;1;5;1;1;0;0;1;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;6;6;7;30000;0;11;6;1;2;1;-1;-2;0;1;1;1;0;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;6;6;8;30000;0;10;6;1;3;1;0;1;1;0;1;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;6;7;6;30000;0;6;6;1;5;1;1;0;0;0;0;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;6;7;7;30000;0;10;6;1;3;1;-2;-1;0;0;1;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;6;7;8;30000;0;15;6;1;6;1;-2;-1;0;1;0;1;0;0;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;6;8;6;30000;0;10;6;1;3;1;1;-1;0;0;0;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;6;8;7;30000;0;10;6;1;5;1;1;0;0;1;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;6;8;8;30000;0;6;6;1;3;1;-1;-1;0;0;0;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;7;4;4;30000;0;15;7;1;1;1;0;0;0;0;0;1;0;2;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;7;4;5;30000;0;11;7;1;2;1;0;3;0;1;1;1;0;0;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;7;4;7;30000;0;14;7;1;7;1;-2;-1;0;0;0;1;0;0;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;7;4;9;30000;0;11;7;1;3;1;1;2;0;1;0;1;0;2;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;7;4;13;30000;0;11;7;1;6;7;0;-2;0;1;0;1;0;2;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;7;5;4;30000;0;15;7;1;1;1;-1;-2;0;1;0;1;0;0;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;7;5;5;30000;0;11;7;1;1;1;-2;0;0;0;0;1;0;2;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;7;5;7;30000;0;17;7;1;2;1;-2;-2;0;0;1;1;0;0;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;7;5;9;30000;0;11;7;1;2;1;1;-1;0;0;1;1;0;0;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;7;5;13;30000;0;12;7;1;2;1;1;-2;0;0;1;1;0;2;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;7;6;6;30000;0;15;7;1;2;1;-2;0;0;1;1;1;0;0;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;7;6;7;30000;0;15;7;1;2;1;0;4;0;0;0;1;0;2;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;7;6;8;30000;0;14;7;1;2;1;-2;0;0;1;1;1;0;2;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;7;7;4;30000;0;9;7;1;3;1;-1;1;0;0;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;7;7;5;30000;0;10;7;1;7;1;-2;-1;1;0;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;7;7;6;30000;0;10;7;1;3;1;-1;2;1;0;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;7;7;7;30000;0;14;7;1;4;1;1;-2;0;1;0;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;7;7;8;30000;0;22;7;1;6;1;-2;0;0;0;0;1;0;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;7;7;9;30000;0;14;7;1;2;1;0;2;1;0;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;7;7;13;30000;0;10;7;1;3;1;-1;-2;0;1;1;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;7;8;6;30000;0;10;7;1;2;1;0;-1;0;0;0;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;7;8;7;30000;0;10;7;1;2;1;1;4;0;0;1;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;7;8;8;30000;0;11;7;1;5;1;-1;-2;0;1;0;1;0;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;7;9;4;30000;0;15;7;1;3;1;-2;-2;0;0;0;1;0;0;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;7;9;5;30000;0;10;7;1;2;1;1;1;0;1;0;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;7;9;7;30000;0;14;7;1;4;1;-1;-2;1;1;1;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;7;13;4;30000;0;17;7;1;6;1;0;-2;0;1;0;1;0;0;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;7;13;5;30000;0;11;7;1;2;1;1;-1;1;0;0;1;0;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;7;13;7;30000;0;14;7;1;2;1;1;-1;1;0;1;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;7;13;13;30000;0;14;7;1;6;1;-2;-1;0;1;1;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;8;6;6;30000;0;11;8;1;1;1;0;-2;0;1;1;1;0;2;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;8;6;7;30000;0;15;8;1;4;1;1;-1;0;0;0;1;0;2;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;8;6;8;30000;0;11;8;1;3;1;-1;-1;0;0;0;1;0;2;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;8;7;6;30000;0;14;8;1;4;1;-1;-1;0;0;0;1;0;2;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;8;7;7;30000;0;14;8;1;5;1;-2;-2;0;1;0;1;0;2;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;8;7;8;30000;0;14;8;1;5;1;-1;0;0;1;1;1;0;2;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;8;8;6;30000;0;10;8;1;2;1;1;1;1;0;1;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;8;8;7;30000;0;14;8;1;4;1;-1;-1;0;0;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;8;8;8;30000;0;14;8;1;6;1;0;-1;0;0;1;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;9;4;4;30000;0;16;9;1;4;1;0;1;0;0;1;1;0;2;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;9;4;5;30000;0;11;9;1;1;1;-1;0;0;0;1;1;0;0;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;9;4;7;30000;0;11;9;1;4;1;-1;0;0;1;1;1;0;2;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;9;4;9;30000;0;11;8;1;9;9;1;-1;0;0;1;1;0;2;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;9;4;13;30000;0;11;9;1;7;9;-1;-2;0;1;0;1;0;2;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;9;5;4;30000;0;15;9;1;1;1;-2;-2;0;0;0;1;0;2;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;9;5;5;30000;0;14;9;1;7;1;-1;-1;0;0;1;1;0;0;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;9;5;7;30000;0;11;8;1;2;9;0;-1;0;1;1;1;0;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;9;5;9;30000;0;15;9;1;5;1;1;-2;0;0;0;1;1;2;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;9;7;4;30000;0;14;9;1;2;1;-2;1;0;1;1;1;0;2;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;9;7;5;30000;0;10;8;1;9;1;1;0;0;0;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;9;7;7;30000;0;11;8;1;5;1;1;2;0;0;0;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;9;9;4;30000;0;17;9;1;7;1;-1;-2;0;0;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;9;9;5;30000;0;22;9;1;4;1;-1;-1;1;0;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;9;9;9;30000;0;18;9;1;5;1;1;-1;0;1;0;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;9;9;16;30000;0;22;9;1;9;1;1;-1;0;1;1;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;9;9;22;30000;0;6;9;1;3;1;-2;-2;0;1;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;9;9;32;30000;0;22;9;1;7;1;0;-2;0;0;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;9;13;4;30000;0;14;9;1;4;1;-2;-1;1;0;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;9;16;9;30000;0;17;9;1;7;1;0;-1;1;0;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;9;16;16;30000;0;10;9;1;4;1;-2;3;1;1;0;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;9;16;22;30000;0;10;9;1;2;1;1;1;0;0;0;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;9;22;9;30000;0;18;9;1;6;1;0;0;1;0;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;9;22;16;30000;0;12;9;1;3;1;-2;0;1;0;1;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;9;22;22;30000;0;13;9;1;7;1;-1;0;1;1;0;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;9;22;32;30000;0;24;9;1;8;1;-1;-1;1;0;0;1;0;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;10;4;4;30000;0;15;10;1;6;1;0;0;0;1;0;1;0;0;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;10;4;10;30000;0;11;8;1;3;10;-2;3;0;0;1;1;0;0;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;10;10;4;30000;0;14;10;1;9;1;1;-1;1;1;0;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;10;10;10;30000;0;17;10;1;3;1;1;-1;0;1;1;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;13;4;4;30000;0;9;8;1;13;1;1;0;0;1;1;1;0;2;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;13;4;5;30000;0;10;8;1;6;13;0;2;0;1;1;1;0;0;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;13;4;7;30000;0;11;8;1;12;1;-2;6;0;0;1;1;0;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;13;4;9;30000;0;6;8;1;11;13;-2;1;0;0;1;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;13;4;13;30000;0;6;8;1;4;13;-1;6;0;1;1;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;13;4;17;30000;0;6;8;1;10;13;1;4;0;1;0;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;13;4;32;30000;0;17;8;1;6;1;0;-1;0;0;0;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;13;5;4;30000;0;9;8;1;5;1;-2;3;0;1;0;1;0;2;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;13;5;5;30000;0;9;8;1;7;1;0;2;0;1;1;1;0;2;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;13;5;7;30000;0;11;8;1;10;1;1;1;1;0;0;1;1;0;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;13;5;13;30000;0;10;8;1;4;13;1;4;0;1;1;1;1;2;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;13;5;17;30000;0;10;8;1;4;1;-2;0;0;0;1;1;1;0;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;13;5;32;30000;0;6;8;1;9;1;1;-2;0;0;1;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;13;7;4;30000;0;11;8;1;2;1;1;2;0;0;0;1;0;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;13;7;5;30000;0;14;13;1;10;1;1;3;0;0;1;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;13;7;7;30000;0;14;8;1;13;1;-1;3;1;1;1;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;13;7;13;30000;0;14;8;1;2;1;-1;1;0;1;1;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;13;9;4;30000;0;14;8;1;11;1;1;2;0;0;0;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;13;13;4;30000;0;25;13;1;10;1;0;-2;0;0;0;1;0;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;13;13;5;30000;0;22;13;1;12;1;-2;-1;1;0;1;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;13;13;7;30000;0;18;13;1;3;13;-2;-2;1;1;1;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;13;13;13;30000;0;5;13;1;4;1;0;-2;0;1;0;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;13;13;17;30000;0;17;13;1;10;1;1;0;0;0;1;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;13;13;32;30000;0;24;13;1;7;1;-2;-1;1;0;0;1;0;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;13;17;4;30000;0;18;13;1;10;1;1;-1;1;0;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;13;17;5;30000;0;17;13;1;2;1;1;-1;1;1;0;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;13;17;13;30000;0;18;13;1;9;1;1;0;1;0;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;13;17;17;30000;0;17;13;1;2;1;-2;1;0;0;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;13;17;32;30000;0;22;13;1;12;1;1;-2;0;0;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;13;32;4;30000;0;25;13;1;13;1;-2;-2;1;1;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;13;32;5;30000;0;26;13;1;11;1;1;-1;1;0;0;1;0;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;13;32;13;30000;0;22;13;1;13;1;1;-2;0;0;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;13;32;17;30000;0;25;8;1;4;1;0;4;0;0;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;13;32;32;30000;0;15;13;1;11;1;-1;-1;1;0;0;1;0;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;15;4;4;30000;0;9;8;1;11;1;0;2;1;0;0;1;0;2;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;15;15;15;30000;0;12;15;1;9;1;-2;-1;0;0;1;1;0;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;16;9;9;30000;0;14;8;1;9;1;0;4;0;0;0;1;0;2;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;16;9;16;30000;0;14;8;1;2;16;-2;5;0;1;1;1;1;1;2;1;0 +NVIDIA H100 PCIe [0xa32d];3;16;9;22;30000;0;15;8;1;6;16;1;0;0;1;0;1;0;0;2;1;0 +NVIDIA H100 PCIe [0xa32d];3;16;16;9;30000;0;18;16;1;8;1;0;0;1;0;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;16;16;16;30000;0;13;16;1;3;1;1;-1;0;0;0;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;16;16;22;30000;0;24;16;1;10;1;-2;-1;1;0;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;16;22;9;30000;0;17;16;1;10;1;1;-1;1;0;0;1;0;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;16;22;16;30000;0;18;16;1;9;1;0;-2;1;0;1;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;16;22;22;30000;0;15;16;1;12;1;0;0;0;0;1;1;0;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;17;4;4;30000;0;9;8;1;11;1;-1;-1;0;1;1;1;0;0;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;17;4;5;30000;0;13;8;1;4;1;-2;6;0;1;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;17;4;13;30000;0;10;8;1;5;17;1;0;0;1;0;1;0;0;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;17;4;17;30000;0;12;8;1;5;17;-1;1;0;1;1;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;17;4;32;30000;0;3;8;1;10;17;0;3;0;1;0;1;0;1;0;1;0 +NVIDIA H100 PCIe [0xa32d];3;17;5;4;30000;0;14;8;1;16;1;-1;-1;0;0;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;17;5;5;30000;0;10;17;1;16;17;-2;4;0;0;1;1;1;0;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;17;5;13;30000;0;11;8;1;5;17;0;-2;0;0;0;1;0;2;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;17;5;17;30000;0;15;8;1;15;17;-2;0;0;1;0;1;0;0;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;17;5;32;30000;0;20;8;1;13;17;-2;6;1;1;0;1;1;2;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;17;13;4;30000;0;15;17;1;13;1;1;-2;0;0;0;1;0;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;17;13;5;30000;0;18;17;1;8;1;-2;-2;0;0;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;17;13;13;30000;0;19;8;1;14;1;-1;4;1;1;0;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;17;13;17;30000;0;10;17;1;12;1;-1;-2;1;0;0;1;1;1;2;1;0 +NVIDIA H100 PCIe [0xa32d];3;17;13;32;30000;0;22;17;1;14;1;-1;0;1;1;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;17;17;4;30000;0;24;17;1;14;1;-2;-2;0;0;1;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;17;17;5;30000;0;24;17;1;11;1;0;0;0;0;0;1;0;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;17;17;13;30000;0;18;17;1;16;1;1;0;0;0;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;17;17;17;30000;0;22;17;1;9;1;-1;-1;0;0;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;17;17;32;30000;0;11;17;1;15;1;1;-1;0;1;0;1;0;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;17;32;4;30000;0;22;17;1;16;1;-2;-2;1;1;1;1;0;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;17;32;5;30000;0;26;17;1;2;1;1;-2;0;0;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;17;32;13;30000;0;12;17;1;9;1;-1;0;1;0;0;1;0;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;17;32;17;30000;0;22;17;1;13;1;-2;-2;1;0;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;17;32;32;30000;0;24;17;1;17;1;-2;-1;0;0;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;20;20;20;30000;0;22;20;1;18;1;1;-2;1;0;1;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;22;9;9;30000;0;12;8;1;7;1;-1;4;0;0;1;1;0;2;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;22;9;16;30000;0;18;8;1;15;1;-2;5;0;1;1;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;22;9;22;30000;0;20;22;1;13;22;-1;5;0;1;0;1;1;2;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;22;9;32;30000;0;20;8;1;18;22;-1;3;0;0;0;1;0;0;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;22;16;9;30000;0;22;8;1;5;1;-1;5;0;1;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;22;16;16;30000;0;22;8;1;8;1;-1;3;0;1;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;22;16;22;30000;0;34;8;1;12;1;1;6;0;0;1;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;22;22;9;30000;0;17;22;1;11;0;-2;-1;1;0;0;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;22;22;16;30000;0;24;22;1;11;1;0;-1;0;1;0;1;0;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;22;22;22;30000;0;24;22;1;15;0;-1;-2;0;0;1;1;0;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;22;22;32;30000;0;22;22;1;17;1;0;-1;1;0;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;23;23;23;30000;0;22;23;1;20;1;1;-2;0;0;0;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;24;24;24;30000;0;24;24;1;22;0;-2;-2;0;0;1;1;1;1;0;1;0 +NVIDIA H100 PCIe [0xa32d];3;25;4;4;30000;0;10;8;1;8;25;1;4;0;0;1;1;1;2;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;25;4;5;30000;0;9;25;1;11;25;-1;6;0;1;0;1;1;0;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;25;5;4;30000;0;9;8;1;21;1;-1;1;0;0;1;1;0;0;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;25;25;25;30000;0;25;25;1;2;1;-1;-1;1;0;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;26;4;4;30000;0;9;8;1;26;26;-2;4;1;0;1;1;0;0;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;28;4;4;30000;0;13;8;1;20;1;-2;5;0;1;0;1;0;0;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;28;28;28;30000;0;24;28;1;19;0;0;0;0;0;1;1;0;1;0;1;0 +NVIDIA H100 PCIe [0xa32d];3;30;30;30;30000;0;25;30;1;18;1;0;0;1;0;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;32;4;4;30000;0;11;8;1;15;32;1;4;1;1;0;1;1;0;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;32;4;5;30000;0;16;8;1;32;32;1;6;1;0;1;1;0;0;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;32;4;13;30000;0;12;8;1;11;32;1;4;0;1;0;1;0;0;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;32;4;17;30000;0;13;8;1;24;32;0;4;0;0;1;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;32;4;32;30000;0;24;8;1;29;32;-2;5;0;1;0;1;1;0;0;1;0 +NVIDIA H100 PCIe [0xa32d];3;32;5;4;30000;0;18;8;1;26;1;1;4;0;0;1;1;1;2;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;32;5;5;30000;0;18;8;1;14;1;0;4;1;0;0;1;0;2;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;32;5;13;30000;0;11;8;1;27;32;-2;6;0;1;1;1;0;0;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;32;5;17;30000;0;22;8;1;16;32;-2;0;0;0;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;32;5;32;30000;0;24;32;1;9;32;-1;6;0;0;1;1;1;2;0;1;0 +NVIDIA H100 PCIe [0xa32d];3;32;13;4;30000;0;24;8;1;1;1;-2;6;1;1;0;1;1;0;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;32;13;5;30000;0;22;8;1;10;1;0;6;1;0;0;1;1;2;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;32;13;13;30000;0;20;8;1;18;1;1;5;0;1;0;1;0;0;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;32;13;17;30000;0;22;8;1;9;1;-1;6;0;0;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;32;13;32;30000;0;11;8;1;16;1;-1;1;0;1;0;1;0;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;32;17;4;30000;0;22;32;1;5;1;-2;0;0;0;0;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;32;17;5;30000;0;22;32;1;9;0;-1;1;0;0;1;1;1;1;0;0;0 +NVIDIA H100 PCIe [0xa32d];3;32;17;13;30000;0;22;32;1;22;0;-1;0;0;0;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;32;17;17;30000;0;22;32;1;7;0;0;1;1;0;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;32;17;32;30000;0;22;32;1;28;1;-1;0;0;1;1;1;1;1;1;0;0 +NVIDIA H100 PCIe [0xa32d];3;32;32;4;30000;0;33;32;1;10;0;1;1;0;0;1;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;32;32;5;30000;0;33;32;1;11;0;0;-1;1;0;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;32;32;13;30000;0;34;32;1;7;1;0;1;0;0;0;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;32;32;17;30000;0;24;32;1;28;1;0;-1;1;0;1;1;0;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;32;32;32;30000;0;25;32;1;29;1;-1;-2;1;0;1;1;1;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;35;35;35;30000;0;22;35;1;23;1;1;0;0;0;0;1;0;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;36;36;36;30000;0;22;36;1;23;0;0;0;0;0;0;1;0;1;2;0;0 +NVIDIA H100 PCIe [0xa32d];3;40;40;40;30000;0;44;40;1;22;1;-1;0;0;0;0;1;0;1;2;0;0 diff --git a/src/acc/opencl/smm/params/tune_multiply_Mi250.csv b/src/acc/opencl/smm/params/tune_multiply_Mi250.csv new file mode 100644 index 00000000000..0d42a4acb78 --- /dev/null +++ b/src/acc/opencl/smm/params/tune_multiply_Mi250.csv @@ -0,0 +1,362 @@ +DEVICE;TYPEID;M;N;K;S;GFLOPS;BS;BM;BN;BK;WS;WG;LU;NZ;AL;TB;TC;AP;AA;AB;AC +gfx90a [0x989f];3;3;3;3;30000;0;18;3;1;3;1;1;4;0;1;1;1;0;2;0;1;0 +gfx90a [0x989f];3;3;3;4;30000;0;24;3;1;3;0;-1;-1;0;0;0;1;0;0;2;0;0 +gfx90a [0x989f];3;3;3;5;30000;0;25;3;1;2;1;1;2;0;1;0;1;0;2;0;0;0 +gfx90a [0x989f];3;3;3;6;30000;0;25;3;1;2;1;-2;-1;0;1;0;1;0;0;0;0;0 +gfx90a [0x989f];3;3;3;7;30000;0;29;3;1;3;1;1;0;0;0;1;1;0;2;2;1;0 +gfx90a [0x989f];3;3;3;8;30000;0;9;3;1;3;1;-1;3;1;1;1;1;0;2;0;1;0 +gfx90a [0x989f];3;3;3;9;30000;0;11;3;1;2;1;1;4;0;1;0;1;0;2;2;1;0 +gfx90a [0x989f];3;3;3;10;30000;0;9;3;1;2;1;-2;-1;0;1;0;1;0;2;0;0;0 +gfx90a [0x989f];3;3;3;11;30000;0;8;3;1;3;1;1;-1;0;1;0;1;0;2;0;1;0 +gfx90a [0x989f];3;3;3;12;30000;0;6;3;1;2;1;-1;5;0;1;1;1;0;2;0;0;0 +gfx90a [0x989f];3;3;3;16;30000;0;6;3;1;1;1;-2;0;0;1;0;1;0;2;2;1;0 +gfx90a [0x989f];3;3;3;23;30000;0;42;3;1;3;1;0;-2;0;1;0;1;0;2;2;0;0 +gfx90a [0x989f];3;3;4;3;30000;0;20;3;1;1;1;-2;-2;0;1;1;1;0;2;0;0;0 +gfx90a [0x989f];3;3;4;4;30000;0;9;3;1;3;1;0;3;0;1;0;1;0;2;0;1;0 +gfx90a [0x989f];3;3;5;3;30000;0;15;3;1;2;1;0;0;0;1;0;1;0;2;2;0;0 +gfx90a [0x989f];3;3;5;5;30000;0;24;3;1;3;1;-2;0;1;1;0;1;0;2;0;0;0 +gfx90a [0x989f];3;3;6;3;30000;0;15;3;1;1;1;-2;-1;0;0;1;1;0;0;2;0;0 +gfx90a [0x989f];3;3;6;6;30000;0;29;3;1;1;1;-2;-2;0;1;1;1;0;2;0;0;0 +gfx90a [0x989f];3;3;7;3;30000;0;17;3;1;1;1;1;-2;1;0;0;1;0;0;2;1;0 +gfx90a [0x989f];3;3;7;7;30000;0;29;3;1;3;1;-1;2;0;1;0;1;0;2;2;0;0 +gfx90a [0x989f];3;3;8;3;30000;0;15;3;1;2;1;0;0;0;1;1;1;0;2;2;0;0 +gfx90a [0x989f];3;3;8;8;30000;0;29;3;1;2;1;0;-2;1;0;1;1;0;2;2;0;0 +gfx90a [0x989f];3;3;9;3;30000;0;14;3;1;2;1;-1;-2;1;1;1;1;0;0;0;0;0 +gfx90a [0x989f];3;3;9;9;30000;0;30;3;1;1;1;0;3;0;1;0;1;0;0;2;1;0 +gfx90a [0x989f];3;3;10;3;30000;0;18;3;1;3;1;1;2;0;1;0;1;0;2;0;0;0 +gfx90a [0x989f];3;3;10;10;30000;0;25;3;1;1;1;1;-1;0;1;1;1;0;2;2;0;0 +gfx90a [0x989f];3;3;11;3;30000;0;15;3;1;3;1;-1;-2;0;1;0;1;0;0;2;0;0 +gfx90a [0x989f];3;3;11;11;30000;0;30;3;1;1;1;1;0;0;1;0;1;0;2;2;0;0 +gfx90a [0x989f];3;3;12;3;30000;0;15;3;1;3;1;1;-2;0;1;0;1;0;0;2;0;0 +gfx90a [0x989f];3;3;12;12;30000;0;30;3;1;1;1;-2;2;0;1;1;1;0;2;0;1;0 +gfx90a [0x989f];3;3;16;3;30000;0;12;3;1;2;1;-2;-2;1;1;0;1;0;0;0;0;0 +gfx90a [0x989f];3;3;16;16;30000;0;50;3;1;3;0;1;-1;0;1;0;1;1;2;2;1;0 +gfx90a [0x989f];3;3;23;3;30000;0;15;3;1;3;1;0;-2;1;1;0;1;0;0;2;1;0 +gfx90a [0x989f];3;3;23;23;30000;0;50;3;1;3;1;-1;0;1;1;0;1;0;0;2;1;0 +gfx90a [0x989f];3;4;3;3;30000;0;22;4;1;4;1;-1;-2;0;1;1;1;0;0;0;0;0 +gfx90a [0x989f];3;4;3;4;30000;0;25;4;1;1;1;-1;2;0;1;0;1;0;0;2;0;0 +gfx90a [0x989f];3;4;4;3;30000;0;16;4;1;2;1;1;6;0;1;0;1;0;2;0;1;0 +gfx90a [0x989f];3;4;4;4;30000;0;11;4;1;4;1;1;6;1;1;1;1;0;2;2;1;0 +gfx90a [0x989f];3;4;4;5;30000;0;21;4;1;4;1;-2;-1;0;0;1;1;0;0;2;0;0 +gfx90a [0x989f];3;4;4;6;30000;0;13;4;1;4;1;0;2;1;1;1;1;0;2;0;1;0 +gfx90a [0x989f];3;4;4;7;30000;0;29;4;1;2;1;0;-1;0;1;0;1;0;2;0;0;0 +gfx90a [0x989f];3;4;4;8;30000;0;12;4;1;2;1;0;6;1;1;0;1;0;2;2;1;0 +gfx90a [0x989f];3;4;4;9;30000;0;12;4;1;4;1;0;-1;1;1;1;1;0;0;2;1;0 +gfx90a [0x989f];3;4;4;10;30000;0;29;4;1;2;1;-2;5;0;1;1;1;0;0;0;0;0 +gfx90a [0x989f];3;4;4;11;30000;0;12;4;1;2;1;-2;0;0;1;0;1;0;2;2;1;0 +gfx90a [0x989f];3;4;4;12;30000;0;29;4;1;3;1;-2;-2;0;1;0;1;0;0;0;1;0 +gfx90a [0x989f];3;4;4;16;30000;0;6;4;1;3;1;-1;-2;0;0;0;1;0;0;0;0;0 +gfx90a [0x989f];3;4;4;23;30000;0;30;4;1;3;1;-2;0;0;1;0;1;0;2;0;1;0 +gfx90a [0x989f];3;4;5;4;30000;0;20;4;1;4;1;0;5;0;1;1;1;0;2;2;1;0 +gfx90a [0x989f];3;4;5;5;30000;0;24;4;1;3;1;0;4;0;1;1;1;0;0;2;0;0 +gfx90a [0x989f];3;4;6;4;30000;0;20;4;1;2;1;0;1;1;1;1;1;0;2;2;1;0 +gfx90a [0x989f];3;4;6;6;30000;0;24;4;1;3;1;0;-1;1;0;0;1;0;2;0;1;0 +gfx90a [0x989f];3;4;7;4;30000;0;23;4;1;1;1;-2;-1;0;1;1;1;0;0;0;0;0 +gfx90a [0x989f];3;4;7;7;30000;0;25;4;1;4;1;-1;-1;0;1;1;1;0;2;2;1;0 +gfx90a [0x989f];3;4;8;4;30000;0;18;4;1;4;1;-1;0;0;1;0;1;0;0;2;0;0 +gfx90a [0x989f];3;4;8;8;30000;0;12;4;1;4;1;-2;3;0;1;1;1;0;2;0;0;0 +gfx90a [0x989f];3;4;9;4;30000;0;21;4;1;4;1;1;0;0;1;1;1;0;2;0;1;0 +gfx90a [0x989f];3;4;9;9;30000;0;15;4;1;1;1;0;3;1;1;1;1;0;0;2;0;0 +gfx90a [0x989f];3;4;10;4;30000;0;20;4;1;4;1;-2;-1;0;0;1;1;0;2;0;1;0 +gfx90a [0x989f];3;4;10;10;30000;0;30;4;1;2;1;-2;6;0;1;0;1;0;2;2;1;0 +gfx90a [0x989f];3;4;11;4;30000;0;19;4;1;1;1;0;3;0;1;0;1;0;0;2;1;0 +gfx90a [0x989f];3;4;11;11;30000;0;24;4;1;2;1;-2;2;1;1;1;1;0;0;2;0;0 +gfx90a [0x989f];3;4;12;4;30000;0;20;4;1;4;1;0;-2;0;1;0;1;0;2;2;1;0 +gfx90a [0x989f];3;4;12;12;30000;0;40;4;1;4;1;-1;-1;0;1;1;1;1;2;0;1;0 +gfx90a [0x989f];3;4;16;4;30000;0;20;4;1;3;1;1;-2;0;1;0;1;0;0;2;0;0 +gfx90a [0x989f];3;4;16;16;30000;0;25;4;1;4;1;0;2;0;0;0;1;0;2;1;1;0 +gfx90a [0x989f];3;4;23;4;30000;0;24;4;1;1;1;0;3;0;1;0;1;0;2;0;1;0 +gfx90a [0x989f];3;4;23;23;30000;0;40;4;1;2;1;-1;5;1;0;0;1;0;0;0;1;0 +gfx90a [0x989f];3;5;3;3;30000;0;18;5;1;4;1;0;-2;1;1;1;1;0;2;0;1;0 +gfx90a [0x989f];3;5;3;5;30000;0;18;5;1;2;1;-1;2;0;1;0;1;0;0;2;0;0 +gfx90a [0x989f];3;5;4;4;30000;0;20;5;1;5;1;1;0;0;0;1;1;0;0;0;1;0 +gfx90a [0x989f];3;5;4;5;30000;0;9;5;1;4;1;-1;0;1;1;0;1;0;0;0;0;0 +gfx90a [0x989f];3;5;5;3;30000;0;18;5;1;4;1;-2;6;0;0;0;1;0;2;2;0;0 +gfx90a [0x989f];3;5;5;4;30000;0;10;5;1;5;1;1;-2;0;1;1;1;0;0;0;0;0 +gfx90a [0x989f];3;5;5;5;30000;0;10;5;1;3;1;1;0;0;1;1;1;1;0;0;0;0 +gfx90a [0x989f];3;5;5;6;30000;0;12;5;1;2;1;-1;2;0;1;0;1;0;2;2;1;0 +gfx90a [0x989f];3;5;5;7;30000;0;9;5;1;1;1;-2;-1;0;1;1;1;0;2;0;0;0 +gfx90a [0x989f];3;5;5;8;30000;0;24;5;1;3;1;0;4;0;1;1;1;0;2;0;0;0 +gfx90a [0x989f];3;5;5;9;30000;0;24;5;1;4;1;1;-1;1;1;1;1;0;2;0;1;0 +gfx90a [0x989f];3;5;5;10;30000;0;20;5;1;1;1;-2;0;1;0;0;1;0;2;2;0;0 +gfx90a [0x989f];3;5;5;11;30000;0;25;5;1;1;1;-2;-2;0;0;0;1;0;2;2;1;0 +gfx90a [0x989f];3;5;5;12;30000;0;4;5;1;3;1;1;0;1;0;0;1;1;2;0;0;0 +gfx90a [0x989f];3;5;5;16;30000;0;12;5;1;4;1;0;2;1;1;1;1;1;0;2;1;0 +gfx90a [0x989f];3;5;5;23;30000;0;2;5;1;1;5;-2;0;1;0;1;1;0;2;0;1;0 +gfx90a [0x989f];3;5;6;5;30000;0;20;5;1;3;1;-2;-2;0;0;1;1;0;2;0;0;0 +gfx90a [0x989f];3;5;6;6;30000;0;24;5;1;3;1;0;-1;0;1;1;1;0;2;0;0;0 +gfx90a [0x989f];3;5;7;5;30000;0;12;5;1;3;1;0;-2;1;0;0;1;0;0;0;1;0 +gfx90a [0x989f];3;5;7;7;30000;0;12;5;1;2;1;0;2;1;1;0;1;0;2;0;1;0 +gfx90a [0x989f];3;5;8;5;30000;0;13;5;1;3;1;-2;6;0;1;1;1;0;2;0;0;0 +gfx90a [0x989f];3;5;8;8;30000;0;10;5;1;3;1;0;0;1;1;1;1;0;0;0;0;0 +gfx90a [0x989f];3;5;9;5;30000;0;24;5;1;3;0;-2;-1;0;1;0;1;1;0;2;0;0 +gfx90a [0x989f];3;5;9;9;30000;0;25;5;1;4;1;1;4;1;0;1;1;0;0;0;1;0 +gfx90a [0x989f];3;5;10;5;30000;0;20;5;1;3;1;1;3;0;0;0;1;0;0;2;0;0 +gfx90a [0x989f];3;5;10;10;30000;0;30;5;1;1;0;-2;-1;1;0;1;1;1;0;0;1;0 +gfx90a [0x989f];3;5;11;5;30000;0;15;5;1;2;1;0;-1;1;0;1;1;0;2;0;0;0 +gfx90a [0x989f];3;5;11;11;30000;0;25;5;1;3;0;-2;-1;0;0;0;1;0;0;0;0;0 +gfx90a [0x989f];3;5;12;5;30000;0;25;5;1;4;1;-1;3;1;1;0;1;1;2;0;0;0 +gfx90a [0x989f];3;5;12;12;30000;0;25;5;1;2;1;-2;2;0;1;0;1;0;0;0;1;0 +gfx90a [0x989f];3;5;16;5;30000;0;24;5;1;3;0;-2;0;0;0;0;1;1;2;2;0;0 +gfx90a [0x989f];3;5;16;16;30000;0;24;5;1;4;0;1;0;0;1;0;1;1;2;0;0;0 +gfx90a [0x989f];3;5;23;5;30000;0;20;5;1;5;1;-1;-2;1;1;0;1;0;2;2;0;0 +gfx90a [0x989f];3;5;23;23;30000;0;24;5;1;1;1;-2;0;0;1;1;1;1;2;1;0;0 +gfx90a [0x989f];3;6;3;3;30000;0;12;6;1;2;1;1;0;0;1;0;1;0;0;0;1;0 +gfx90a [0x989f];3;6;3;6;30000;0;18;6;1;3;1;-2;-1;0;1;0;1;0;2;0;0;0 +gfx90a [0x989f];3;6;4;4;30000;0;18;6;1;2;1;1;2;0;1;1;1;0;0;0;0;0 +gfx90a [0x989f];3;6;4;6;30000;0;15;6;1;5;1;1;4;1;1;1;1;0;0;0;0;0 +gfx90a [0x989f];3;6;5;5;30000;0;9;6;1;6;1;-2;2;0;1;1;1;0;2;0;1;0 +gfx90a [0x989f];3;6;5;6;30000;0;15;6;1;4;1;0;-2;0;0;0;1;0;2;0;1;0 +gfx90a [0x989f];3;6;6;3;30000;0;12;6;1;2;1;-1;3;1;1;0;1;0;0;0;0;0 +gfx90a [0x989f];3;6;6;4;30000;0;15;6;1;3;1;-1;3;0;1;0;1;0;2;0;0;0 +gfx90a [0x989f];3;6;6;5;30000;0;12;6;1;1;1;0;6;1;0;1;1;0;2;2;0;0 +gfx90a [0x989f];3;6;6;6;30000;0;12;6;1;1;1;-2;-1;0;1;0;1;1;2;0;0;0 +gfx90a [0x989f];3;6;6;7;30000;0;12;6;1;5;1;-1;0;0;1;0;1;0;2;2;1;0 +gfx90a [0x989f];3;6;6;8;30000;0;20;6;1;5;1;1;-2;1;1;0;1;0;0;0;1;0 +gfx90a [0x989f];3;6;6;9;30000;0;12;6;1;1;1;0;5;1;1;0;1;0;2;2;1;0 +gfx90a [0x989f];3;6;6;10;30000;0;12;6;1;3;1;-2;1;1;1;1;1;0;0;2;1;0 +gfx90a [0x989f];3;6;6;11;30000;0;24;6;1;5;1;0;0;1;1;1;1;1;2;2;1;0 +gfx90a [0x989f];3;6;6;12;30000;0;15;6;1;1;0;-2;0;0;0;0;1;1;2;1;0;0 +gfx90a [0x989f];3;6;6;16;30000;0;4;6;1;1;0;-2;-2;0;1;0;1;1;2;0;0;0 +gfx90a [0x989f];3;6;6;23;30000;0;15;6;1;1;1;0;3;0;1;1;1;0;2;2;0;0 +gfx90a [0x989f];3;6;7;6;30000;0;20;6;1;6;1;1;4;0;1;0;1;1;0;0;1;0 +gfx90a [0x989f];3;6;7;7;30000;0;12;6;1;6;1;1;2;1;0;0;1;0;2;2;0;0 +gfx90a [0x989f];3;6;8;6;30000;0;15;6;1;6;1;1;-2;0;1;1;1;0;2;0;1;0 +gfx90a [0x989f];3;6;8;8;30000;0;20;6;1;6;1;-1;-2;0;0;1;1;0;0;0;0;0 +gfx90a [0x989f];3;6;9;6;30000;0;13;6;1;6;1;-1;-1;1;1;0;1;0;0;2;0;0 +gfx90a [0x989f];3;6;9;9;30000;0;24;6;1;2;0;-1;0;0;1;1;1;1;0;0;1;0 +gfx90a [0x989f];3;6;10;6;30000;0;20;6;1;6;1;-2;3;1;0;1;1;0;2;0;0;0 +gfx90a [0x989f];3;6;10;10;30000;0;25;6;1;4;1;0;0;0;1;0;1;1;2;0;1;0 +gfx90a [0x989f];3;6;11;6;30000;0;15;6;1;2;0;0;-1;0;1;0;1;0;2;0;0;0 +gfx90a [0x989f];3;6;11;11;30000;0;25;6;1;1;0;0;-2;0;1;1;1;1;2;0;0;0 +gfx90a [0x989f];3;6;12;6;30000;0;20;6;1;6;1;-1;2;0;1;1;1;1;0;2;1;0 +gfx90a [0x989f];3;6;12;12;30000;0;15;6;1;6;1;-2;-2;1;0;0;1;0;0;0;1;0 +gfx90a [0x989f];3;6;16;6;30000;0;20;6;1;5;1;0;-1;0;1;0;1;1;0;2;1;0 +gfx90a [0x989f];3;6;16;16;30000;0;26;6;1;6;1;0;0;0;1;0;1;1;2;2;0;0 +gfx90a [0x989f];3;6;23;6;30000;0;24;6;1;1;0;-2;0;0;0;0;1;1;0;0;1;0 +gfx90a [0x989f];3;6;23;23;30000;0;24;6;1;1;1;1;-2;0;1;1;1;1;0;2;1;0 +gfx90a [0x989f];3;7;3;3;30000;0;16;7;1;3;1;-1;4;0;1;0;1;0;0;0;1;0 +gfx90a [0x989f];3;7;3;7;30000;0;15;7;1;6;1;0;0;0;1;0;1;0;0;2;1;0 +gfx90a [0x989f];3;7;4;4;30000;0;22;7;1;3;1;1;-1;0;1;1;1;1;0;2;0;0 +gfx90a [0x989f];3;7;4;7;30000;0;12;7;1;3;1;1;3;0;1;1;1;0;0;0;0;0 +gfx90a [0x989f];3;7;5;5;30000;0;12;7;1;2;1;0;1;0;1;1;1;0;2;0;0;0 +gfx90a [0x989f];3;7;5;7;30000;0;13;7;1;5;1;1;-1;0;1;0;1;0;2;2;1;0 +gfx90a [0x989f];3;7;6;6;30000;0;9;7;1;1;1;0;3;1;0;0;1;1;2;2;1;0 +gfx90a [0x989f];3;7;6;7;30000;0;15;7;1;3;1;-1;1;1;1;0;1;0;2;2;0;0 +gfx90a [0x989f];3;7;7;3;30000;0;15;7;1;7;1;-1;2;0;1;0;1;0;2;2;0;0 +gfx90a [0x989f];3;7;7;4;30000;0;18;7;1;3;1;1;1;0;1;0;1;1;2;2;0;0 +gfx90a [0x989f];3;7;7;5;30000;0;15;7;1;6;1;0;-2;0;1;0;1;0;2;0;1;0 +gfx90a [0x989f];3;7;7;6;30000;0;15;7;1;6;1;-2;-2;0;1;0;1;0;0;0;1;0 +gfx90a [0x989f];3;7;7;7;30000;0;12;7;1;3;1;1;2;0;1;0;1;1;0;0;0;0 +gfx90a [0x989f];3;7;7;8;30000;0;24;7;1;6;0;-2;-1;0;1;0;1;1;2;2;0;0 +gfx90a [0x989f];3;7;7;9;30000;0;15;7;1;4;0;1;-2;0;0;1;1;0;2;0;1;0 +gfx90a [0x989f];3;7;7;10;30000;0;12;7;1;1;1;-1;0;1;1;1;1;1;2;2;0;0 +gfx90a [0x989f];3;7;7;11;30000;0;15;7;1;1;1;0;-2;0;0;1;1;1;2;2;1;0 +gfx90a [0x989f];3;7;7;12;30000;0;12;7;1;1;0;-1;-2;1;1;1;1;1;2;2;0;0 +gfx90a [0x989f];3;7;7;16;30000;0;15;7;1;1;0;-1;-1;1;1;0;1;1;2;1;0;0 +gfx90a [0x989f];3;7;7;23;30000;0;1;7;1;1;1;1;6;0;1;1;0;1;2;2;1;0 +gfx90a [0x989f];3;7;8;7;30000;0;12;7;1;5;1;1;-2;1;1;1;1;1;2;0;1;0 +gfx90a [0x989f];3;7;8;8;30000;0;24;7;1;6;0;-1;-1;0;0;1;1;1;0;2;1;0 +gfx90a [0x989f];3;7;9;7;30000;0;20;7;1;7;1;-2;0;0;1;1;1;1;2;0;1;0 +gfx90a [0x989f];3;7;9;9;30000;0;20;7;1;7;0;-1;-1;0;0;0;1;1;2;2;0;0 +gfx90a [0x989f];3;7;10;7;30000;0;20;7;1;7;1;1;-2;0;1;0;1;1;2;2;0;0 +gfx90a [0x989f];3;7;10;10;30000;0;15;7;1;1;1;0;0;0;0;0;1;0;2;0;1;0 +gfx90a [0x989f];3;7;11;7;30000;0;20;7;1;5;1;-2;0;0;1;0;1;1;2;2;0;0 +gfx90a [0x989f];3;7;11;11;30000;0;20;7;1;1;0;-2;-1;0;0;1;1;1;0;0;1;0 +gfx90a [0x989f];3;7;12;7;30000;0;24;7;1;2;0;1;0;0;0;0;1;1;0;0;0;0 +gfx90a [0x989f];3;7;12;12;30000;0;24;7;1;6;1;1;-2;0;1;0;1;1;0;2;1;0 +gfx90a [0x989f];3;7;16;7;30000;0;24;7;1;7;0;0;0;0;1;0;1;1;0;2;0;0 +gfx90a [0x989f];3;7;16;16;30000;0;24;7;1;1;1;1;-2;0;0;0;1;1;2;2;0;0 +gfx90a [0x989f];3;7;23;7;30000;0;25;7;1;3;1;0;1;1;1;0;1;0;0;2;0;0 +gfx90a [0x989f];3;7;23;23;30000;0;24;7;1;1;1;0;-2;1;0;1;1;1;2;0;1;0 +gfx90a [0x989f];3;8;3;3;30000;0;12;8;1;4;1;-2;3;0;1;1;1;0;2;0;1;0 +gfx90a [0x989f];3;8;3;8;30000;0;6;8;1;2;1;-2;-1;0;0;1;1;1;0;2;1;0 +gfx90a [0x989f];3;8;4;4;30000;0;12;8;1;3;1;0;0;0;0;1;1;0;0;2;1;0 +gfx90a [0x989f];3;8;4;8;30000;0;9;8;1;4;1;1;4;1;0;1;1;1;0;2;1;0 +gfx90a [0x989f];3;8;5;5;30000;0;12;8;1;2;1;-2;4;0;1;1;1;1;2;0;1;0 +gfx90a [0x989f];3;8;5;8;30000;0;10;8;1;7;1;-1;6;0;1;0;1;1;2;0;1;0 +gfx90a [0x989f];3;8;6;6;30000;0;12;8;1;6;1;-2;2;0;1;0;1;0;2;2;1;0 +gfx90a [0x989f];3;8;6;8;30000;0;15;8;1;5;1;0;-2;0;1;1;1;1;0;2;0;0 +gfx90a [0x989f];3;8;7;7;30000;0;12;8;1;8;1;-1;0;1;0;0;1;1;0;2;1;0 +gfx90a [0x989f];3;8;7;8;30000;0;20;8;1;4;1;-2;0;0;0;0;1;1;0;2;1;0 +gfx90a [0x989f];3;8;8;3;30000;0;20;8;1;7;1;-1;-1;0;1;0;1;0;0;2;0;0 +gfx90a [0x989f];3;8;8;4;30000;0;22;8;1;5;0;1;-1;0;0;0;1;1;2;2;1;0 +gfx90a [0x989f];3;8;8;5;30000;0;15;8;1;5;1;-2;0;1;1;0;1;1;0;0;1;0 +gfx90a [0x989f];3;8;8;6;30000;0;15;8;1;3;0;-2;-1;0;1;0;1;1;2;2;1;0 +gfx90a [0x989f];3;8;8;7;30000;0;15;8;1;7;1;-1;-1;1;1;1;1;1;0;2;1;0 +gfx90a [0x989f];3;8;8;8;30000;0;10;8;1;4;1;1;1;0;1;0;1;1;0;0;1;0 +gfx90a [0x989f];3;8;8;16;30000;0;24;8;1;8;0;-2;0;0;1;0;1;1;0;2;0;0 +gfx90a [0x989f];3;8;8;23;30000;0;2;8;1;1;1;-2;-2;0;1;1;1;0;2;1;0;0 +gfx90a [0x989f];3;8;16;8;30000;0;24;8;1;2;0;-2;1;0;1;1;1;1;2;2;1;0 +gfx90a [0x989f];3;8;16;16;30000;0;20;8;1;1;1;1;0;1;1;0;1;1;0;2;0;0 +gfx90a [0x989f];3;8;23;8;30000;0;24;8;1;8;0;1;0;1;1;1;1;1;2;2;1;0 +gfx90a [0x989f];3;8;23;23;30000;0;20;8;1;1;1;-1;-1;1;1;1;1;1;0;2;1;0 +gfx90a [0x989f];3;9;3;3;30000;0;13;9;1;4;1;-1;-2;0;0;0;1;0;0;0;0;0 +gfx90a [0x989f];3;9;3;9;30000;0;12;9;1;1;1;-1;0;0;1;1;1;1;2;2;0;0 +gfx90a [0x989f];3;9;4;4;30000;0;12;9;1;3;1;1;0;0;0;0;1;1;2;0;0;0 +gfx90a [0x989f];3;9;4;9;30000;0;6;9;1;9;0;0;-1;0;0;0;1;0;1;2;0;0 +gfx90a [0x989f];3;9;5;5;30000;0;11;9;1;7;1;-1;0;0;1;0;1;1;0;2;0;0 +gfx90a [0x989f];3;9;5;9;30000;0;12;9;1;1;1;-2;0;1;1;0;1;1;2;0;0;0 +gfx90a [0x989f];3;9;6;6;30000;0;15;9;1;4;1;-1;1;0;0;1;1;1;2;0;1;0 +gfx90a [0x989f];3;9;6;9;30000;0;10;9;1;1;1;-1;-2;1;1;0;1;1;0;2;1;0 +gfx90a [0x989f];3;9;7;7;30000;0;12;9;1;1;1;-2;-1;1;1;0;1;1;0;0;1;0 +gfx90a [0x989f];3;9;7;9;30000;0;13;9;1;1;1;-2;0;1;1;1;1;1;2;0;1;0 +gfx90a [0x989f];3;9;9;3;30000;0;15;9;1;8;1;-2;0;0;1;1;1;1;0;0;0;0 +gfx90a [0x989f];3;9;9;4;30000;0;13;9;1;7;0;-1;-1;0;1;0;1;1;2;2;0;0 +gfx90a [0x989f];3;9;9;5;30000;0;15;9;1;2;1;0;1;0;1;0;1;1;2;0;0;0 +gfx90a [0x989f];3;9;9;6;30000;0;24;9;1;2;0;0;-2;0;0;0;1;1;0;0;1;0 +gfx90a [0x989f];3;9;9;7;30000;0;13;9;1;3;0;-2;1;0;0;1;1;1;2;2;1;0 +gfx90a [0x989f];3;9;9;9;30000;0;10;9;1;4;0;0;1;0;1;1;1;1;0;2;1;0 +gfx90a [0x989f];3;9;9;16;30000;0;12;9;1;1;1;0;-2;1;1;1;1;1;2;2;1;0 +gfx90a [0x989f];3;9;9;23;30000;0;3;9;1;8;1;0;-2;1;1;0;1;0;1;2;0;0 +gfx90a [0x989f];3;9;16;9;30000;0;13;9;1;1;0;0;0;1;0;0;1;1;2;2;1;0 +gfx90a [0x989f];3;9;16;16;30000;0;20;9;1;1;1;-2;0;0;0;0;1;0;2;2;0;0 +gfx90a [0x989f];3;9;23;9;30000;0;24;9;1;1;1;0;-2;1;1;1;1;1;0;2;1;0 +gfx90a [0x989f];3;9;23;23;30000;0;3;8;1;7;1;0;3;1;1;0;1;0;1;2;1;0 +gfx90a [0x989f];3;10;3;3;30000;0;10;10;1;8;1;0;-2;0;1;0;1;1;2;0;0;0 +gfx90a [0x989f];3;10;3;10;30000;0;12;10;1;1;1;-1;0;0;0;1;1;1;2;0;1;0 +gfx90a [0x989f];3;10;4;4;30000;0;13;10;1;3;1;-2;-1;1;1;0;1;1;0;2;0;0 +gfx90a [0x989f];3;10;4;10;30000;0;12;10;1;1;1;-1;0;0;1;1;1;1;2;2;0;0 +gfx90a [0x989f];3;10;5;5;30000;0;15;10;1;3;1;-1;-2;0;1;1;1;1;0;0;1;0 +gfx90a [0x989f];3;10;5;10;30000;0;15;10;1;1;1;1;0;0;1;1;1;1;2;2;0;0 +gfx90a [0x989f];3;10;6;6;30000;0;9;10;1;1;1;-1;-1;1;1;1;1;1;2;0;1;0 +gfx90a [0x989f];3;10;6;10;30000;0;6;10;1;9;0;0;1;0;0;0;1;0;1;2;0;0 +gfx90a [0x989f];3;10;7;7;30000;0;24;10;1;8;1;1;0;0;0;1;1;1;2;2;0;0 +gfx90a [0x989f];3;10;7;10;30000;0;12;10;1;1;1;1;-2;0;1;1;1;1;2;0;0;0 +gfx90a [0x989f];3;10;10;3;30000;0;15;10;1;10;0;1;-1;1;1;1;1;1;0;0;0;0 +gfx90a [0x989f];3;10;10;4;30000;0;20;10;1;4;0;-1;1;0;0;1;1;1;2;0;0;0 +gfx90a [0x989f];3;10;10;5;30000;0;15;10;1;3;0;0;0;0;0;0;1;1;2;2;1;0 +gfx90a [0x989f];3;10;10;6;30000;0;20;10;1;10;0;-1;0;0;0;0;1;1;2;0;0;0 +gfx90a [0x989f];3;10;10;7;30000;0;12;10;1;1;1;0;0;1;0;1;1;1;2;2;1;0 +gfx90a [0x989f];3;10;10;10;30000;0;10;10;1;9;1;0;-2;0;1;1;1;1;0;1;0;0 +gfx90a [0x989f];3;10;10;16;30000;0;15;10;1;1;1;-1;0;0;0;0;1;0;2;2;0;0 +gfx90a [0x989f];3;10;10;23;30000;0;3;10;1;7;1;-1;-2;0;1;0;1;0;1;2;0;0 +gfx90a [0x989f];3;10;16;10;30000;0;20;10;1;1;1;-2;0;0;1;0;1;1;2;0;0;0 +gfx90a [0x989f];3;10;16;16;30000;0;15;10;1;1;1;0;0;1;1;1;1;1;2;2;1;0 +gfx90a [0x989f];3;10;23;10;30000;0;24;10;1;7;0;-1;-1;0;1;1;1;1;0;0;1;0 +gfx90a [0x989f];3;10;23;23;30000;0;3;10;1;9;1;-2;0;1;0;1;1;0;1;2;0;0 +gfx90a [0x989f];3;11;3;3;30000;0;9;11;1;10;1;-1;0;1;1;0;1;0;2;2;1;0 +gfx90a [0x989f];3;11;3;11;30000;0;10;11;1;1;1;1;-2;0;0;1;1;1;0;2;1;0 +gfx90a [0x989f];3;11;4;4;30000;0;13;11;1;5;1;-2;-1;0;0;1;1;0;2;0;1;0 +gfx90a [0x989f];3;11;4;11;30000;0;12;11;1;1;1;-2;0;0;1;1;1;1;2;2;0;0 +gfx90a [0x989f];3;11;5;5;30000;0;10;11;1;9;0;0;-2;0;1;0;1;0;0;2;0;0 +gfx90a [0x989f];3;11;5;11;30000;0;12;11;1;1;1;-2;0;0;1;1;1;1;2;2;0;0 +gfx90a [0x989f];3;11;6;6;30000;0;12;11;1;6;1;-1;0;0;0;1;1;1;2;1;0;0 +gfx90a [0x989f];3;11;6;11;30000;0;12;11;1;1;1;0;0;1;1;1;1;1;2;2;1;0 +gfx90a [0x989f];3;11;7;7;30000;0;13;11;1;1;1;-2;0;0;1;0;1;1;2;2;0;0 +gfx90a [0x989f];3;11;7;11;30000;0;4;11;1;1;0;-2;2;0;1;0;1;0;1;2;0;0 +gfx90a [0x989f];3;11;11;3;30000;0;20;11;1;3;1;-1;0;0;0;0;1;1;2;0;1;0 +gfx90a [0x989f];3;11;11;4;30000;0;20;11;1;10;1;-2;-2;0;1;1;1;1;0;0;1;0 +gfx90a [0x989f];3;11;11;5;30000;0;20;11;1;3;1;-2;0;0;1;0;1;1;2;0;1;0 +gfx90a [0x989f];3;11;11;6;30000;0;20;11;1;1;1;-2;0;0;1;0;1;1;2;2;0;0 +gfx90a [0x989f];3;11;11;7;30000;0;6;8;1;2;1;-1;0;1;1;0;1;0;1;2;0;0 +gfx90a [0x989f];3;11;11;11;30000;0;12;11;1;8;1;-2;-2;0;1;0;1;1;2;0;0;0 +gfx90a [0x989f];3;11;11;16;30000;0;4;8;1;4;1;-1;2;1;1;0;1;0;1;2;0;0 +gfx90a [0x989f];3;11;11;23;30000;0;15;11;1;1;1;-1;-1;0;1;0;1;1;2;2;0;0 +gfx90a [0x989f];3;11;16;11;30000;0;15;11;1;1;1;0;-2;0;1;0;1;1;2;2;0;0 +gfx90a [0x989f];3;11;16;16;30000;0;4;8;1;1;1;-1;4;1;0;0;1;0;1;2;0;0 +gfx90a [0x989f];3;11;23;11;30000;0;24;11;1;6;1;-2;-2;0;1;0;1;1;2;1;0;0 +gfx90a [0x989f];3;11;23;23;30000;0;3;8;1;10;1;-1;2;0;1;0;1;0;1;2;1;0 +gfx90a [0x989f];3;12;3;3;30000;0;15;12;1;2;0;-1;-2;0;1;0;1;0;0;0;0;0 +gfx90a [0x989f];3;12;3;12;30000;0;12;12;1;1;1;-1;-2;0;0;1;1;1;0;2;1;0 +gfx90a [0x989f];3;12;4;4;30000;0;13;12;1;12;0;-1;0;0;1;0;1;0;2;2;0;0 +gfx90a [0x989f];3;12;4;12;30000;0;15;12;1;1;12;0;0;0;1;1;1;1;2;2;1;0 +gfx90a [0x989f];3;12;5;5;30000;0;10;12;1;7;1;0;0;0;1;1;1;1;0;0;0;0 +gfx90a [0x989f];3;12;5;12;30000;0;12;12;1;1;1;1;-2;0;0;1;1;1;2;0;0;0 +gfx90a [0x989f];3;12;6;6;30000;0;13;12;1;10;1;1;-2;0;0;0;1;1;0;0;1;0 +gfx90a [0x989f];3;12;6;12;30000;0;15;12;1;1;1;0;-2;1;1;1;1;1;2;0;1;0 +gfx90a [0x989f];3;12;7;7;30000;0;15;12;1;1;1;0;0;1;1;1;1;1;2;0;1;0 +gfx90a [0x989f];3;12;7;12;30000;0;12;12;1;1;1;-2;0;1;1;1;1;1;0;2;1;0 +gfx90a [0x989f];3;12;12;3;30000;0;20;12;1;12;0;-2;-2;0;1;0;1;0;2;2;0;0 +gfx90a [0x989f];3;12;12;4;30000;0;20;12;1;9;0;0;-2;0;0;0;1;0;2;0;0;0 +gfx90a [0x989f];3;12;12;5;30000;0;15;12;1;7;1;0;0;0;1;0;1;1;0;2;1;0 +gfx90a [0x989f];3;12;12;6;30000;0;26;12;1;7;1;-1;-2;0;0;0;1;1;2;2;1;0 +gfx90a [0x989f];3;12;12;7;30000;0;15;12;1;1;1;1;0;1;1;0;1;1;2;0;1;0 +gfx90a [0x989f];3;12;12;12;30000;0;12;12;1;8;1;1;0;0;1;0;1;1;0;1;0;0 +gfx90a [0x989f];3;12;12;16;30000;0;24;12;1;7;1;0;0;0;1;0;1;0;2;2;0;0 +gfx90a [0x989f];3;12;12;23;30000;0;3;12;1;2;0;-2;2;0;1;0;1;0;1;0;0;0 +gfx90a [0x989f];3;12;16;12;30000;0;10;8;1;10;1;0;0;1;0;0;1;0;1;0;0;0 +gfx90a [0x989f];3;12;16;16;30000;0;15;12;1;1;1;0;0;1;1;1;1;1;2;2;0;0 +gfx90a [0x989f];3;12;23;12;30000;0;24;12;1;11;1;-1;-2;0;1;0;1;0;2;2;0;0 +gfx90a [0x989f];3;12;23;23;30000;0;5;8;1;4;1;0;1;0;1;1;1;0;1;2;1;0 +gfx90a [0x989f];3;13;13;13;30000;0;12;13;1;12;1;-2;-1;0;1;0;1;1;0;2;1;0 +gfx90a [0x989f];3;13;13;23;30000;0;12;13;1;1;1;-1;0;1;0;0;1;0;2;0;1;0 +gfx90a [0x989f];3;13;23;13;30000;0;8;13;1;3;1;1;0;0;0;0;1;0;1;2;0;0 +gfx90a [0x989f];3;13;23;23;30000;0;3;8;1;9;1;-2;2;1;0;1;1;0;1;2;1;0 +gfx90a [0x989f];3;14;14;14;30000;0;10;14;1;12;1;0;-2;0;1;1;1;1;0;2;0;0 +gfx90a [0x989f];3;14;14;23;30000;0;15;14;1;1;1;1;0;0;0;0;1;1;2;0;0;0 +gfx90a [0x989f];3;14;14;29;30000;0;5;14;1;3;14;-1;2;0;1;0;1;0;1;0;1;0 +gfx90a [0x989f];3;14;14;32;30000;0;2;8;1;11;1;-2;0;1;1;0;1;0;1;0;1;0 +gfx90a [0x989f];3;14;23;14;30000;0;13;8;1;10;1;-2;3;0;1;0;1;0;1;0;0;0 +gfx90a [0x989f];3;14;23;23;30000;0;4;8;1;7;1;-2;1;0;0;1;1;0;1;0;1;0 +gfx90a [0x989f];3;14;29;14;30000;0;30;8;1;4;1;-1;1;1;0;0;1;1;1;0;1;0 +gfx90a [0x989f];3;14;29;29;30000;0;3;8;1;6;1;1;2;0;1;0;1;0;1;2;1;0 +gfx90a [0x989f];3;14;29;32;30000;0;3;8;1;6;1;-1;-1;0;0;1;1;0;1;2;1;0 +gfx90a [0x989f];3;14;32;14;30000;0;30;8;1;10;1;-2;4;1;1;0;1;0;1;0;1;0 +gfx90a [0x989f];3;14;32;29;30000;0;3;8;1;6;1;0;5;0;1;1;1;0;1;2;1;0 +gfx90a [0x989f];3;14;32;32;30000;0;40;8;1;4;1;1;4;0;1;0;1;1;1;0;1;0 +gfx90a [0x989f];3;15;15;15;30000;0;4;8;1;2;1;-1;1;0;1;1;1;0;1;0;1;0 +gfx90a [0x989f];3;15;15;23;30000;0;4;8;1;3;1;0;0;1;1;0;1;0;1;2;1;0 +gfx90a [0x989f];3;15;23;15;30000;0;3;15;1;10;1;0;5;1;0;1;1;0;1;2;1;0 +gfx90a [0x989f];3;15;23;23;30000;0;4;8;1;6;1;-2;3;1;1;1;1;0;1;2;1;0 +gfx90a [0x989f];3;16;3;3;30000;0;15;16;1;10;0;-1;-2;0;1;0;1;1;0;0;0;0 +gfx90a [0x989f];3;16;3;16;30000;0;13;16;1;10;1;0;0;0;0;1;1;1;0;0;1;0 +gfx90a [0x989f];3;16;4;4;30000;0;12;16;1;6;1;0;-1;0;1;0;1;1;0;0;1;0 +gfx90a [0x989f];3;16;4;16;30000;0;4;8;1;6;1;0;-1;1;0;0;1;1;1;0;1;0 +gfx90a [0x989f];3;16;5;5;30000;0;15;8;1;4;1;-1;2;0;1;1;1;0;1;2;0;0 +gfx90a [0x989f];3;16;5;16;30000;0;8;8;1;6;1;-1;2;0;1;0;1;0;1;0;0;0 +gfx90a [0x989f];3;16;6;6;30000;0;15;16;1;1;1;1;-2;1;1;1;1;1;2;0;1;0 +gfx90a [0x989f];3;16;6;16;30000;0;12;16;1;1;1;1;0;0;1;1;1;1;2;0;1;0 +gfx90a [0x989f];3;16;7;7;30000;0;10;16;1;1;0;-2;0;0;1;1;1;1;2;2;1;0 +gfx90a [0x989f];3;16;7;16;30000;0;24;16;1;13;1;0;0;1;1;0;1;1;2;2;0;0 +gfx90a [0x989f];3;16;8;8;30000;0;24;16;1;3;0;-2;-1;0;0;0;1;1;2;2;1;0 +gfx90a [0x989f];3;16;8;16;30000;0;5;8;1;2;1;0;0;1;0;1;1;0;1;2;0;0 +gfx90a [0x989f];3;16;9;9;30000;0;6;8;1;3;1;-2;1;1;1;0;1;1;1;0;0;0 +gfx90a [0x989f];3;16;9;16;30000;0;4;8;1;7;1;0;2;1;1;1;1;0;1;2;0;0 +gfx90a [0x989f];3;16;10;10;30000;0;30;16;1;9;0;-1;2;0;1;0;1;0;1;0;0;0 +gfx90a [0x989f];3;16;10;16;30000;0;8;8;1;6;1;0;0;0;0;0;1;0;1;2;0;0 +gfx90a [0x989f];3;16;11;11;30000;0;6;8;1;4;1;-1;2;0;1;0;1;1;1;0;0;0 +gfx90a [0x989f];3;16;11;16;30000;0;30;8;1;4;1;-2;2;1;0;0;1;1;1;2;0;0 +gfx90a [0x989f];3;16;12;12;30000;0;6;8;1;15;1;-2;2;1;1;1;1;0;1;0;0;0 +gfx90a [0x989f];3;16;12;16;30000;0;12;16;1;1;1;-1;-2;0;1;0;1;1;2;2;1;0 +gfx90a [0x989f];3;16;16;3;30000;0;25;16;1;9;0;-1;-2;1;0;1;1;1;0;0;1;0 +gfx90a [0x989f];3;16;16;4;30000;0;22;16;1;2;0;1;-1;1;1;0;1;1;2;2;1;0 +gfx90a [0x989f];3;16;16;5;30000;0;20;16;1;1;1;-2;-2;1;1;0;1;1;2;2;0;0 +gfx90a [0x989f];3;16;16;6;30000;0;25;16;1;9;0;-1;2;1;1;0;1;1;1;0;0;0 +gfx90a [0x989f];3;16;16;7;30000;0;15;16;1;1;0;0;0;1;1;0;1;1;2;2;0;0 +gfx90a [0x989f];3;16;16;8;30000;0;24;16;1;8;1;0;1;1;0;1;1;1;2;0;1;0 +gfx90a [0x989f];3;16;16;9;30000;0;25;8;1;8;1;-2;3;1;0;1;1;0;1;2;0;0 +gfx90a [0x989f];3;16;16;10;30000;0;25;8;1;4;1;-1;4;1;1;0;1;0;1;2;0;0 +gfx90a [0x989f];3;16;16;11;30000;0;26;8;1;8;1;-1;4;1;1;1;1;0;1;0;0;0 +gfx90a [0x989f];3;16;16;12;30000;0;14;8;1;6;1;1;0;0;0;0;1;0;1;2;0;0 +gfx90a [0x989f];3;16;16;16;30000;0;12;16;1;2;1;1;-1;0;1;1;1;1;2;0;1;0 +gfx90a [0x989f];3;16;16;23;30000;0;3;8;1;7;1;-1;3;1;1;0;1;1;1;2;0;0 +gfx90a [0x989f];3;16;23;16;30000;0;31;8;1;4;1;-1;-1;1;1;1;1;0;1;2;1;0 +gfx90a [0x989f];3;16;23;23;30000;0;3;8;1;11;1;-1;3;0;0;0;1;1;1;0;0;0 +gfx90a [0x989f];3;17;17;17;30000;0;12;17;1;17;1;-1;-1;0;1;0;1;0;0;2;0;0 +gfx90a [0x989f];3;17;17;23;30000;0;3;8;1;15;1;-1;0;1;1;1;1;0;1;0;1;0 +gfx90a [0x989f];3;17;17;32;30000;0;4;8;1;14;17;0;3;1;1;0;1;0;1;0;1;0 +gfx90a [0x989f];3;17;17;35;30000;0;5;17;1;4;17;-2;3;1;0;1;1;1;1;0;1;0 +gfx90a [0x989f];3;17;23;17;30000;0;4;17;1;5;1;0;-1;0;1;1;1;0;1;2;0;0 +gfx90a [0x989f];3;17;23;23;30000;0;3;17;1;17;1;0;0;1;1;0;1;0;1;2;0;0 +gfx90a [0x989f];3;17;32;17;30000;0;20;17;1;1;1;1;-1;1;1;0;1;1;2;2;0;0 +gfx90a [0x989f];3;17;32;35;30000;0;3;8;1;13;1;1;-2;0;1;0;1;0;1;0;1;0 +gfx90a [0x989f];3;17;35;17;30000;0;25;17;1;16;1;0;-1;1;1;0;1;1;1;2;0;0 +gfx90a [0x989f];3;17;35;32;30000;0;3;17;1;14;1;1;-1;1;1;0;1;0;1;2;0;0 +gfx90a [0x989f];3;17;35;35;30000;0;30;17;1;1;1;0;0;0;1;1;1;0;0;0;0;0 +gfx90a [0x989f];3;18;18;18;30000;0;30;18;1;11;0;0;4;0;1;0;1;0;1;0;1;0 +gfx90a [0x989f];3;18;18;23;30000;0;7;8;1;17;1;0;1;0;0;1;1;1;1;2;1;0 +gfx90a [0x989f];3;18;23;18;30000;0;4;18;1;15;1;-2;-2;1;0;1;1;0;1;2;0;0 +gfx90a [0x989f];3;18;23;23;30000;0;3;8;1;16;1;-1;6;0;0;0;1;0;1;2;1;0 +gfx90a [0x989f];3;19;19;19;30000;0;4;8;1;7;1;-2;4;1;1;0;1;1;1;2;1;0 +gfx90a [0x989f];3;19;19;23;30000;0;5;8;1;5;1;-2;0;0;0;1;1;0;1;0;1;0 +gfx90a [0x989f];3;23;23;23;30000;0;1;1;12;9;0;-2;0;0;1;0;1;1;2;1;1;0 +gfx90a [0x989f];3;32;32;32;30000;0;25;32;1;20;1;-2;0;0;1;0;1;0;2;0;0;0 +gfx90a [0x989f];3;35;17;17;30000;0;15;35;1;29;1;1;0;0;1;0;1;0;2;1;0;0 +gfx90a [0x989f];3;35;17;32;30000;0;20;35;1;1;1;0;-2;1;1;0;1;1;2;0;0;0 +gfx90a [0x989f];3;35;17;35;30000;0;7;35;1;31;1;-2;4;1;0;0;1;1;1;2;1;0 +gfx90a [0x989f];3;35;32;17;30000;0;39;35;1;35;1;1;4;0;1;1;1;1;1;0;0;0 +gfx90a [0x989f];3;35;32;35;30000;0;3;35;1;31;1;-2;0;1;1;0;1;1;1;2;0;0 +gfx90a [0x989f];3;35;35;17;30000;0;33;35;1;20;1;1;4;1;1;1;1;0;1;0;0;0 +gfx90a [0x989f];3;35;35;32;30000;0;15;35;1;35;35;-2;0;0;1;0;1;1;2;2;0;0 +gfx90a [0x989f];3;35;35;35;30000;0;2;35;1;30;0;1;-1;0;1;0;1;0;1;2;0;0 diff --git a/src/acc/opencl/smm/params/tune_multiply_P100.csv b/src/acc/opencl/smm/params/tune_multiply_P100.csv index b183fe487b6..ad038b17ef7 100644 --- a/src/acc/opencl/smm/params/tune_multiply_P100.csv +++ b/src/acc/opencl/smm/params/tune_multiply_P100.csv @@ -1,251 +1,251 @@ DEVICE;TYPEID;M;N;K;S;GFLOPS;BS;BM;BN;BK;WS;WG;LU;NZ;AL;TB;TC;AP;AA;AB;AC -Tesla P100-PCIE-16GB [0x2f6c];3;2;2;2;30000;23.4;17;2;1;2;0;-2;0;0;0;0;1;1;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;3;3;1;30000;33.4;20;3;1;2;0;-2;-2;0;1;0;1;1;3;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;3;3;3;30000;61.7;20;3;1;2;0;-2;-2;0;0;1;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;4;4;4;30000;144.3;17;4;1;2;0;0;0;0;1;1;1;1;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;5;5;5;30000;184.7;30;5;1;3;0;0;0;0;0;0;1;1;1;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;5;5;7;30000;190.1;31;5;1;3;0;-1;-2;0;1;0;1;1;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;5;5;13;30000;218.9;60;5;1;4;0;-2;-1;0;1;0;1;1;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;5;5;16;30000;217.4;60;5;1;4;0;-2;-1;0;0;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;5;5;24;30000;222.9;30;5;1;5;0;0;-2;1;1;1;1;1;2;3;2 -Tesla P100-PCIE-16GB [0x2f6c];3;5;5;26;30000;227.5;40;5;1;4;0;-1;-2;0;0;1;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;5;7;5;30000;246.9;20;5;1;2;0;0;-2;0;1;1;1;1;1;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;5;7;7;30000;270.9;25;5;1;3;0;-2;-2;0;0;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;5;7;13;30000;294.2;30;5;1;5;0;0;-1;0;1;1;1;1;1;0;2 -Tesla P100-PCIE-16GB [0x2f6c];3;5;13;5;30000;396.8;20;5;1;4;0;0;-2;1;0;0;1;1;1;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;5;13;7;30000;449.7;26;5;1;4;0;1;-2;1;0;1;1;1;1;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;5;13;13;30000;498.4;40;5;1;2;0;0;-2;1;0;0;1;1;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;5;13;16;30000;461.2;20;5;1;3;0;0;-2;1;1;1;1;1;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;5;13;24;30000;494.4;60;5;1;4;0;-1;-1;1;0;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;5;13;26;30000;486.0;30;5;1;4;0;-1;2;1;1;0;1;1;1;3;1 -Tesla P100-PCIE-16GB [0x2f6c];3;5;16;5;30000;454.9;24;5;1;3;0;-2;0;1;1;1;1;1;1;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;5;16;13;30000;578.2;25;5;1;2;0;1;0;1;1;1;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;5;16;16;30000;597.7;30;5;1;2;0;-2;-2;0;1;1;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;5;16;24;30000;597.0;30;5;1;3;0;-2;-2;1;1;0;1;1;1;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;5;16;26;30000;594.9;30;5;1;4;0;-2;-1;1;0;0;1;1;1;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;5;24;5;30000;553.6;24;5;1;3;0;0;0;1;0;1;1;1;1;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;5;24;13;30000;677.3;40;5;1;4;0;-1;-2;0;0;0;1;1;1;3;1 -Tesla P100-PCIE-16GB [0x2f6c];3;5;24;16;30000;664.1;50;5;1;3;0;1;-1;0;1;1;1;1;2;0;1 -Tesla P100-PCIE-16GB [0x2f6c];3;5;24;24;30000;734.9;50;5;1;5;0;-1;-1;0;1;1;1;1;1;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;5;24;26;30000;724.8;50;5;1;2;0;-1;0;0;0;0;1;0;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;5;26;5;30000;556.3;24;5;1;2;0;-2;0;0;0;1;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;5;26;13;30000;753.2;60;5;1;2;0;1;1;1;1;0;1;1;2;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;5;26;16;30000;744.1;30;5;1;4;0;1;-2;1;1;0;1;1;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;5;26;24;30000;658.7;60;5;1;4;0;-1;0;0;0;1;1;1;2;3;1 -Tesla P100-PCIE-16GB [0x2f6c];3;5;26;26;30000;521.7;7;5;1;3;0;-1;-2;1;1;1;1;1;1;2;0 -Tesla P100-PCIE-16GB [0x2f6c];3;6;6;6;30000;272.0;25;6;1;5;0;1;0;0;1;1;1;1;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;7;5;5;30000;158.7;30;7;1;5;0;0;-1;0;0;1;1;1;2;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;7;5;7;30000;165.6;30;7;1;7;0;-2;-1;0;0;0;1;1;1;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;7;5;13;30000;190.0;1;7;1;5;0;-1;-1;1;0;0;1;0;2;3;2 -Tesla P100-PCIE-16GB [0x2f6c];3;7;7;5;30000;331.1;25;7;1;2;0;-2;0;0;1;1;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;7;7;7;30000;354.4;26;7;1;4;0;-1;-2;0;0;1;1;1;2;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;7;7;13;30000;394.8;30;7;1;5;0;0;-2;0;0;1;1;1;2;0;1 -Tesla P100-PCIE-16GB [0x2f6c];3;7;13;5;30000;494.5;25;7;1;6;0;-1;-1;0;0;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;7;13;7;30000;571.0;26;7;1;3;0;-2;-1;0;0;0;1;1;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;7;13;13;30000;654.0;30;7;1;2;0;1;0;0;0;0;1;1;2;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;8;8;8;30000;471.1;30;8;1;7;0;0;-1;1;0;0;1;1;1;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;9;9;9;30000;545.1;30;9;1;6;0;0;-2;0;0;0;1;1;2;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;9;9;16;30000;577.2;30;9;1;8;0;0;-1;0;0;1;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;9;9;22;30000;566.3;40;9;1;4;0;-1;-1;0;1;1;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;9;9;32;30000;546.8;50;9;1;5;0;0;0;0;0;1;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;9;16;9;30000;791.8;30;9;1;7;0;0;-2;1;0;0;1;1;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;9;16;16;30000;856.2;30;9;1;8;0;-1;0;1;1;0;1;1;1;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;9;16;22;30000;879.6;50;9;1;4;0;0;0;0;1;0;1;1;2;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;9;22;9;30000;945.7;40;9;1;8;0;-2;0;0;0;1;1;1;2;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;9;22;16;30000;1062.4;40;9;1;3;0;-2;-1;1;1;1;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;9;22;22;30000;1065.8;60;9;1;5;0;0;0;0;1;1;1;1;2;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;9;22;32;30000;1072.5;60;9;1;2;0;0;-2;0;1;1;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;9;32;9;30000;1113.6;50;9;1;6;0;1;0;1;0;1;1;1;2;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;9;32;22;30000;1351.2;60;9;1;3;0;-2;0;1;0;1;1;1;2;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;9;32;32;30000;1398.1;60;9;1;8;0;-2;0;1;1;1;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;10;10;10;30000;637.6;30;10;1;2;0;-1;-1;0;0;0;1;1;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;13;5;5;30000;245.9;20;13;1;2;0;1;-1;0;0;0;1;1;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;13;5;7;30000;262.0;24;13;1;12;0;-1;0;0;0;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;13;5;8;30000;268.9;25;13;1;11;0;-1;-1;0;1;0;1;1;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;13;5;13;30000;278.8;30;13;1;4;0;-1;2;0;0;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;13;5;16;30000;457.6;30;13;1;9;0;-2;-1;0;1;0;1;1;2;3;2 -Tesla P100-PCIE-16GB [0x2f6c];3;13;5;24;30000;464.2;40;13;1;13;0;-1;0;0;0;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;13;5;26;30000;437.1;53;13;1;6;0;1;-2;0;0;1;1;1;1;3;2 -Tesla P100-PCIE-16GB [0x2f6c];3;13;7;5;30000;347.6;25;13;1;12;0;-1;-2;0;1;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;13;7;7;30000;364.8;24;13;1;5;0;-2;-2;0;0;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;13;7;13;30000;433.8;30;13;1;13;0;1;0;0;0;1;1;1;2;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;13;8;5;30000;388.2;25;13;1;11;0;-2;-1;0;1;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;13;13;5;30000;716.0;26;13;1;12;0;-1;-2;0;0;0;1;1;2;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;13;13;7;30000;808.8;40;13;1;6;0;0;-2;0;1;0;1;1;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;13;13;13;30000;838.5;50;13;1;5;0;-2;-2;0;0;0;1;1;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;13;13;16;30000;875.5;50;13;1;8;0;1;-1;0;0;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;13;13;24;30000;749.0;17;13;1;10;0;-1;0;0;1;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;13;13;26;30000;746.5;5;13;1;6;0;-2;2;1;0;1;1;1;1;0;2 -Tesla P100-PCIE-16GB [0x2f6c];3;13;16;5;30000;770.1;25;13;1;12;0;1;-2;0;0;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;13;16;13;30000;982.7;50;13;1;13;0;-1;-1;1;0;0;1;1;2;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;13;16;16;30000;973.6;60;13;1;7;0;0;-1;0;1;1;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;13;16;24;30000;1050.2;60;13;1;8;0;0;0;0;1;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;13;16;26;30000;975.0;53;13;1;2;0;-1;0;1;0;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;13;24;5;30000;825.2;50;13;1;6;0;-1;2;0;1;0;1;1;2;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;13;24;13;30000;1175.7;40;13;1;6;0;-1;-2;1;1;0;1;0;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;13;24;16;30000;1263.4;40;13;1;4;0;-2;1;1;0;0;1;0;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;13;24;24;30000;1356.1;60;13;1;7;0;1;-1;1;0;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;13;24;26;30000;1209.2;53;13;1;6;0;-1;2;0;1;0;1;0;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;13;26;5;30000;874.1;30;13;1;11;0;-2;-1;0;0;1;1;1;2;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;13;26;13;30000;1295.5;60;13;1;13;0;-2;-2;1;1;1;1;1;1;1;0 -Tesla P100-PCIE-16GB [0x2f6c];3;13;26;16;30000;1376.1;60;13;1;4;0;1;-2;1;1;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;13;26;24;30000;1084.3;54;13;1;8;0;-1;-1;0;0;1;1;1;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;13;26;26;30000;1427.8;60;13;1;11;0;1;0;0;1;0;1;0;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;14;14;14;30000;908.2;50;14;1;3;0;1;-1;0;0;0;1;1;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;14;14;16;30000;947.5;30;14;1;14;0;0;0;0;1;1;1;0;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;14;14;29;30000;834.1;5;14;1;6;0;0;0;0;0;0;1;1;1;1;0 -Tesla P100-PCIE-16GB [0x2f6c];3;14;16;14;30000;987.5;40;14;1;13;0;-1;-2;1;0;1;1;0;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;14;16;16;30000;1013.9;60;14;1;7;0;-2;-1;0;0;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;14;16;29;30000;893.9;4;14;1;4;0;0;0;1;1;1;1;1;1;0;2 -Tesla P100-PCIE-16GB [0x2f6c];3;14;29;14;30000;1441.8;60;14;1;7;0;-2;-2;1;0;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;14;29;16;30000;1521.6;60;14;1;13;0;1;-1;0;0;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;14;29;29;30000;1489.4;50;14;1;9;0;0;-1;1;1;1;1;0;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;15;15;15;30000;973.0;30;15;1;12;0;-2;-2;0;0;0;1;1;1;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;16;5;5;0;194.0;23;16;1;0;0;0;0;0;0;0;1;0;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;16;5;13;30000;581.2;50;16;1;16;0;-1;1;0;0;0;1;1;1;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;16;5;16;30000;592.4;40;16;1;12;0;-1;0;0;1;1;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;16;5;24;30000;439.1;6;16;1;14;0;1;1;0;0;1;1;1;2;2;0 -Tesla P100-PCIE-16GB [0x2f6c];3;16;5;26;30000;581.3;60;16;1;15;0;0;0;0;0;1;1;1;2;3;2 -Tesla P100-PCIE-16GB [0x2f6c];3;16;8;5;30000;462.6;25;16;1;8;0;-2;-2;0;0;1;1;1;1;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;16;8;8;30000;511.4;30;16;1;15;0;0;-2;0;0;1;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;16;9;9;30000;562.2;30;16;1;16;0;1;0;0;0;1;1;1;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;16;9;16;30000;634.9;40;16;1;7;0;0;2;0;1;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;16;9;22;30000;632.4;50;16;1;10;0;-2;-2;0;0;1;1;1;1;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;16;13;5;30000;786.7;24;16;1;15;0;-2;2;0;0;0;1;1;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;16;13;13;30000;1056.9;25;16;1;2;0;1;1;1;1;0;1;1;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;16;13;16;30000;1147.4;30;16;1;4;0;0;-2;0;0;0;1;1;2;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;16;13;24;30000;852.4;5;16;1;10;0;-1;-2;1;0;0;1;1;2;2;0 -Tesla P100-PCIE-16GB [0x2f6c];3;16;13;26;30000;1097.1;40;16;1;15;0;1;2;1;0;1;1;0;2;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;16;14;14;30000;1136.9;25;16;1;12;0;1;-2;0;1;1;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;16;14;16;30000;1169.5;30;16;1;14;0;-1;2;0;0;0;1;0;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;16;14;29;30000;901.8;7;16;1;10;0;1;0;0;0;0;1;0;1;1;0 -Tesla P100-PCIE-16GB [0x2f6c];3;16;16;5;30000;860.6;25;16;1;16;0;-1;-2;0;1;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;16;16;9;30000;1044.8;50;16;1;7;0;0;0;0;0;1;1;1;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;16;16;13;30000;1059.9;50;16;1;15;0;-2;0;0;0;0;1;0;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;16;16;14;30000;1083.5;40;16;1;15;0;0;-1;0;0;0;1;0;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;16;16;16;30000;1099.0;40;16;1;14;0;-1;0;0;0;1;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;16;16;22;30000;1128.1;60;16;1;10;0;1;-2;0;0;0;1;1;2;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;16;16;24;30000;1110.8;40;16;1;15;0;0;-2;0;1;1;1;0;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;16;16;26;30000;1104.1;50;16;1;11;0;0;-2;1;0;0;1;0;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;16;16;29;30000;977.5;5;16;1;6;0;1;-2;0;1;1;1;1;1;2;0 -Tesla P100-PCIE-16GB [0x2f6c];3;16;16;55;30000;1030.9;1;16;1;7;0;1;1;0;0;1;1;0;1;0;1 -Tesla P100-PCIE-16GB [0x2f6c];3;16;22;9;30000;1267.6;30;16;1;2;0;0;-1;0;1;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;16;22;16;30000;1382.6;50;16;1;8;0;1;1;1;1;0;1;1;2;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;16;22;22;30000;1411.9;60;16;1;12;0;1;-2;1;0;1;1;1;2;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;16;24;5;30000;877.9;25;16;1;11;0;0;-2;1;0;0;1;0;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;16;24;13;30000;1361.4;40;16;1;13;0;1;-2;1;0;0;1;1;1;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;16;24;16;30000;1463.5;60;16;1;4;0;-2;-2;0;0;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;16;24;24;30000;1164.1;36;16;1;10;0;-1;0;0;0;1;1;0;2;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;16;24;26;30000;1158.0;7;16;1;15;0;1;0;0;0;1;1;1;1;2;0 -Tesla P100-PCIE-16GB [0x2f6c];3;16;26;5;30000;969.1;30;16;1;10;0;-1;-1;0;0;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;16;26;13;30000;1469.9;50;16;1;5;0;1;0;1;1;1;1;1;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;16;26;16;30000;1548.9;60;16;1;6;0;-1;0;1;0;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;16;26;24;30000;1554.5;60;16;1;11;0;0;-1;0;0;0;1;0;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;16;26;26;30000;1486.2;50;16;1;11;0;0;-1;0;1;0;1;0;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;16;29;14;30000;1578.2;50;16;1;4;0;-1;1;1;0;1;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;16;29;16;30000;1569.0;50;16;1;9;0;0;0;0;0;0;1;0;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;16;29;29;30000;1555.2;50;16;1;10;0;-1;-2;0;0;1;1;0;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;16;29;55;30000;1359.1;17;16;1;15;0;1;0;0;1;1;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;16;55;16;30000;1411.0;45;16;1;3;0;-2;1;1;0;1;1;1;2;2;0 -Tesla P100-PCIE-16GB [0x2f6c];3;16;55;29;30000;1505.1;23;16;1;13;0;0;-1;0;0;0;1;1;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;16;55;55;30000;1634.4;36;16;1;13;0;-1;0;0;1;0;1;0;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;20;20;20;30000;1396.9;50;20;1;8;0;-2;-2;0;0;1;1;0;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;22;9;9;30000;620.0;30;22;1;14;0;1;0;0;0;0;1;1;2;1;0 -Tesla P100-PCIE-16GB [0x2f6c];3;22;9;16;30000;635.4;40;22;1;21;0;-2;-2;0;0;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;22;9;22;30000;642.7;60;22;1;18;0;-2;-1;0;0;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;22;9;32;30000;603.6;27;22;1;17;0;-1;0;0;0;1;1;1;2;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;22;16;9;30000;955.7;50;22;1;12;0;-2;-2;1;0;1;1;1;1;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;22;16;16;30000;1124.4;50;22;1;11;0;-1;-2;0;0;1;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;22;16;22;30000;1161.8;60;22;1;21;0;0;0;0;0;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;22;22;9;30000;1371.4;60;22;1;8;0;0;2;0;0;0;1;1;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;22;22;16;30000;1475.2;50;22;1;8;0;-1;-2;0;1;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;22;22;22;30000;1550.1;60;22;1;19;0;0;-1;0;0;1;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;22;22;32;30000;1421.8;40;22;1;1;0;-2;0;0;0;0;1;1;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;22;32;9;30000;1594.6;50;22;1;3;0;0;1;0;1;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;22;32;22;30000;2044.8;60;22;1;10;0;-2;0;0;1;0;1;0;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;22;32;32;30000;2052.0;60;22;1;15;0;0;0;0;1;0;1;0;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;23;23;23;30000;1657.8;50;23;1;17;0;0;0;0;0;1;1;0;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;24;5;5;30000;557.5;24;24;1;1;0;-1;-1;0;1;0;1;1;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;24;5;13;30000;657.2;40;24;1;22;0;0;0;1;1;0;1;1;1;3;2 -Tesla P100-PCIE-16GB [0x2f6c];3;24;5;16;30000;652.6;50;24;1;13;0;0;-1;1;0;1;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;24;5;24;30000;600.1;53;24;1;1;0;-2;1;0;1;1;1;0;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;24;5;26;30000;621.4;60;24;1;20;0;0;-2;1;0;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;24;13;5;30000;857.0;30;24;1;20;0;1;2;1;0;1;1;1;1;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;24;13;13;30000;1145.1;25;24;1;22;0;1;1;1;0;0;1;0;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;24;13;16;30000;991.2;45;24;1;19;0;-1;0;0;0;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;24;13;24;30000;1111.6;50;24;1;6;0;-1;-1;0;0;1;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;24;13;26;30000;1022.9;25;24;1;22;0;-2;2;0;1;1;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;24;16;5;30000;980.0;40;24;1;10;0;-1;0;0;0;1;1;1;1;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;24;16;13;30000;1524.4;50;24;1;21;0;-2;2;0;0;1;1;1;2;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;24;16;16;30000;1541.4;60;24;1;12;0;0;-1;1;0;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;24;16;24;30000;1506.5;50;24;1;24;0;-1;2;0;1;1;1;0;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;24;16;26;30000;1178.7;26;24;1;24;0;0;0;1;0;1;1;1;1;1;0 -Tesla P100-PCIE-16GB [0x2f6c];3;24;24;5;30000;1051.1;50;24;1;23;0;1;-2;1;0;1;1;1;2;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;24;24;13;30000;1584.1;50;24;1;7;0;-1;-1;1;1;1;1;1;2;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;24;24;16;30000;1630.0;60;24;1;5;0;0;-2;0;0;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;24;24;24;30000;1606.4;50;24;1;1;0;1;0;1;0;0;1;1;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;24;24;26;30000;1483.6;46;24;1;4;0;-1;0;0;1;1;1;0;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;24;26;5;30000;1069.4;40;24;1;20;0;0;-1;0;1;0;1;1;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;24;26;13;30000;1516.6;40;24;1;23;0;-1;-1;0;0;0;1;1;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;24;26;16;30000;1617.3;40;24;1;21;0;1;0;0;0;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;24;26;24;30000;1806.5;60;24;1;13;0;-2;0;0;0;0;1;0;2;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;24;26;26;30000;1777.9;60;24;1;17;0;1;0;1;0;1;1;0;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;25;25;25;30000;1779.6;60;25;1;12;0;-2;2;0;0;1;1;0;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;26;5;5;30000;534.8;20;26;1;1;0;-1;0;1;0;1;1;1;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;26;5;13;30000;691.2;40;26;1;13;0;-1;-2;1;1;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;26;5;16;30000;693.3;40;26;1;21;0;0;2;0;1;0;1;0;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;26;5;24;30000;520.0;25;26;1;23;0;1;-2;0;0;0;1;0;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;26;5;26;30000;524.8;3;26;1;25;0;1;1;1;1;0;1;1;2;3;2 -Tesla P100-PCIE-16GB [0x2f6c];3;26;13;5;30000;939.0;40;26;1;9;0;-1;-1;0;1;0;1;1;1;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;26;13;13;30000;1240.9;40;26;1;7;0;-2;0;0;0;0;1;1;1;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;26;13;16;30000;1178.2;50;26;1;22;0;0;-2;1;0;0;1;1;2;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;26;13;24;30000;1030.6;24;26;1;26;0;1;2;0;1;0;1;0;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;26;13;26;30000;1253.7;60;26;1;1;0;1;0;1;0;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;26;16;5;30000;976.2;40;26;1;11;0;0;-2;1;0;0;1;1;2;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;26;16;13;30000;1571.2;50;26;1;26;0;1;1;0;0;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;26;16;16;30000;1174.4;47;26;1;4;0;-1;2;1;0;1;1;1;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;26;16;24;30000;1579.9;60;26;1;23;0;1;-1;0;1;1;1;0;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;26;16;26;30000;1195.7;25;26;1;18;0;-2;-2;0;1;1;1;0;1;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;26;24;5;30000;1085.3;50;26;1;26;0;0;0;0;0;0;1;1;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;26;24;13;30000;1443.2;50;26;1;1;0;1;2;1;1;1;1;1;2;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;26;24;16;30000;1652.9;60;26;1;9;0;0;0;0;0;1;1;1;2;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;26;24;24;30000;1443.9;30;26;1;15;0;0;2;0;0;0;1;0;2;2;0 -Tesla P100-PCIE-16GB [0x2f6c];3;26;24;26;30000;1482.0;36;26;1;23;0;1;0;0;1;0;1;1;2;2;0 -Tesla P100-PCIE-16GB [0x2f6c];3;26;26;5;30000;1076.0;50;26;1;23;0;0;-1;0;0;0;1;0;2;1;0 -Tesla P100-PCIE-16GB [0x2f6c];3;26;26;13;30000;1654.9;60;26;1;23;0;0;-2;0;0;0;1;0;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;26;26;16;30000;1613.0;53;26;1;26;0;-1;0;0;1;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;26;26;24;30000;1521.5;25;26;1;17;0;1;-1;0;0;1;1;0;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;26;26;26;30000;1825.8;60;26;1;22;0;1;0;0;0;1;1;0;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;28;28;28;30000;2017.4;60;28;1;25;0;0;0;0;0;1;1;0;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;29;14;14;30000;1063.5;50;29;1;28;0;0;-1;0;0;0;1;0;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;29;14;16;30000;1124.0;60;29;1;27;0;0;0;1;1;0;1;0;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;29;14;29;30000;1086.7;7;29;1;26;0;-2;0;1;0;0;1;1;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;29;16;14;30000;1190.2;55;29;1;1;0;1;2;1;1;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;29;16;16;30000;1402.8;50;29;1;5;0;1;0;0;0;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;29;16;29;30000;1226.1;30;29;1;14;0;-2;0;1;0;0;1;0;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;29;16;55;30000;1096.1;9;29;1;22;0;0;0;1;0;0;1;1;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;29;29;14;30000;1676.4;40;29;1;24;0;-1;0;1;1;1;1;0;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;29;29;16;30000;1869.9;60;29;1;10;0;1;2;0;0;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;29;29;29;30000;1741.8;40;29;1;25;0;-2;0;0;0;0;1;0;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;29;29;55;30000;1646.8;37;29;1;28;0;1;-2;1;1;1;1;0;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;29;55;16;30000;1872.0;40;29;1;27;0;0;0;0;0;0;1;0;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;29;55;29;30000;2156.0;31;29;1;17;0;0;0;1;0;0;1;1;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;29;55;55;30000;2066.8;5;29;1;25;0;0;0;0;0;0;1;0;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;30;30;30;30000;1919.2;40;30;1;1;0;-2;0;0;0;0;1;1;2;0;0 -Tesla P100-PCIE-16GB [0x2f6c];3;32;32;9;30000;1831.3;60;32;1;6;0;-1;1;1;0;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;32;32;22;30000;2073.6;40;32;1;1;0;-1;-1;0;1;0;1;1;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;32;32;32;30000;2187.8;50;32;1;1;0;1;0;0;0;0;1;1;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;35;35;35;30000;1744.5;18;35;1;33;0;2;0;0;0;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;36;36;36;30000;1823.8;36;36;1;24;0;-1;-2;0;0;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;40;40;40;0;1912.2;34;40;1;0;0;0;0;0;0;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;55;16;16;30000;1311.0;25;55;1;32;0;0;0;1;1;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;55;16;29;30000;1499.1;22;55;1;19;0;-1;0;1;0;0;1;1;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;55;16;55;30000;1080.8;8;55;1;19;0;-1;0;1;0;1;1;0;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;55;29;16;30000;1699.5;34;55;1;19;0;-1;-1;0;1;0;1;1;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;55;29;29;30000;1710.1;9;55;1;52;0;0;0;0;0;0;1;1;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;55;29;55;30000;1030.0;8;55;1;33;0;0;0;0;0;0;1;0;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;55;55;16;30000;2125.2;46;55;1;51;0;0;-2;0;0;0;1;0;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;55;55;29;30000;2243.0;8;55;1;29;0;0;0;0;1;0;1;0;1;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;55;55;55;30000;1768.7;8;55;1;42;0;0;0;0;0;0;1;0;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;64;64;64;30000;1239.7;55;64;1;1;0;0;0;0;0;0;0;0;2;3;0 -Tesla P100-PCIE-16GB [0x2f6c];3;78;78;78;30000;524.9;1;78;1;43;0;-1;1;0;1;0;1;1;0;3;2 +Tesla P100-PCIE-16GB [0x2f6c];3;2;2;2;30000;23.4;17;2;1;2;0;-2;0;0;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;3;3;1;30000;33.4;20;3;1;2;0;-2;-2;0;1;0;1;1;2;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;3;3;3;30000;61.7;20;3;1;2;0;-2;-2;0;0;1;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;4;4;4;30000;144.3;17;4;1;2;0;0;0;0;1;1;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;5;5;5;30000;184.7;30;5;1;3;0;0;0;0;0;0;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;5;5;7;30000;190.1;31;5;1;3;0;-1;-2;0;1;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;5;5;13;30000;218.9;60;5;1;4;0;-2;-1;0;1;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;5;5;16;30000;217.4;60;5;1;4;0;-2;-1;0;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;5;5;24;30000;222.9;30;5;1;5;0;0;-2;1;1;1;1;1;1;2;1;0 +Tesla P100-PCIE-16GB [0x2f6c];3;5;5;26;30000;227.5;40;5;1;4;0;-1;-2;0;0;1;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;5;7;5;30000;246.9;20;5;1;2;0;0;-2;0;1;1;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;5;7;7;30000;270.9;25;5;1;3;0;-2;-2;0;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;5;7;13;30000;294.2;30;5;1;5;0;0;-1;0;1;1;1;1;1;0;1;0 +Tesla P100-PCIE-16GB [0x2f6c];3;5;13;5;30000;396.8;20;5;1;4;0;0;-2;1;0;0;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;5;13;7;30000;449.7;26;5;1;4;0;1;-2;1;0;1;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;5;13;13;30000;498.4;40;5;1;2;0;0;-2;1;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;5;13;16;30000;461.2;20;5;1;3;0;0;-2;1;1;1;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;5;13;24;30000;494.4;60;5;1;4;0;-1;-1;1;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;5;13;26;30000;486.0;30;5;1;4;0;-1;-1;1;1;0;1;1;1;2;1;0 +Tesla P100-PCIE-16GB [0x2f6c];3;5;16;5;30000;454.9;24;5;1;3;0;-2;0;1;1;1;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;5;16;13;30000;578.2;25;5;1;2;0;1;0;1;1;1;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;5;16;16;30000;597.7;30;5;1;2;0;-2;-2;0;1;1;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;5;16;24;30000;597.0;30;5;1;3;0;-2;-2;1;1;0;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;5;16;26;30000;594.9;30;5;1;4;0;-2;-1;1;0;0;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;5;24;5;30000;553.6;24;5;1;3;0;0;0;1;0;1;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;5;24;13;30000;677.3;40;5;1;4;0;-1;-2;0;0;0;1;1;1;2;1;0 +Tesla P100-PCIE-16GB [0x2f6c];3;5;24;16;30000;664.1;50;5;1;3;0;1;-1;0;1;1;1;1;1;0;1;0 +Tesla P100-PCIE-16GB [0x2f6c];3;5;24;24;30000;734.9;50;5;1;5;0;-1;-1;0;1;1;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;5;24;26;30000;724.8;50;5;1;2;0;-1;0;0;0;0;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;5;26;5;30000;556.3;24;5;1;2;0;-2;0;0;0;1;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;5;26;13;30000;753.2;60;5;1;2;0;1;1;1;1;0;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;5;26;16;30000;744.1;30;5;1;4;0;1;-2;1;1;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;5;26;24;30000;658.7;60;5;1;4;0;-1;0;0;0;1;1;1;1;2;1;0 +Tesla P100-PCIE-16GB [0x2f6c];3;5;26;26;30000;521.7;7;5;1;3;0;-1;-2;1;1;1;1;1;1;1;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;6;6;6;30000;272.0;25;6;1;5;0;1;0;0;1;1;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;7;5;5;30000;158.7;30;7;1;5;0;0;-1;0;0;1;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;7;5;7;30000;165.6;30;7;1;7;0;-2;-1;0;0;0;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;7;5;13;30000;190.0;1;7;1;5;0;-1;-1;1;0;0;1;0;1;2;1;0 +Tesla P100-PCIE-16GB [0x2f6c];3;7;7;5;30000;331.1;25;7;1;2;0;-2;0;0;1;1;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;7;7;7;30000;354.4;26;7;1;4;0;-1;-2;0;0;1;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;7;7;13;30000;394.8;30;7;1;5;0;0;-2;0;0;1;1;1;1;0;1;0 +Tesla P100-PCIE-16GB [0x2f6c];3;7;13;5;30000;494.5;25;7;1;6;0;-1;-1;0;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;7;13;7;30000;571.0;26;7;1;3;0;-2;-1;0;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;7;13;13;30000;654.0;30;7;1;2;0;1;0;0;0;0;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;8;8;8;30000;471.1;30;8;1;7;0;0;-1;1;0;0;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;9;9;9;30000;545.1;30;9;1;6;0;0;-2;0;0;0;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;9;9;16;30000;577.2;30;9;1;8;0;0;-1;0;0;1;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;9;9;22;30000;566.3;40;9;1;4;0;-1;-1;0;1;1;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;9;9;32;30000;546.8;50;9;1;5;0;0;0;0;0;1;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;9;16;9;30000;791.8;30;9;1;7;0;0;-2;1;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;9;16;16;30000;856.2;30;9;1;8;0;-1;0;1;1;0;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;9;16;22;30000;879.6;50;9;1;4;0;0;0;0;1;0;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;9;22;9;30000;945.7;40;9;1;8;0;-2;0;0;0;1;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;9;22;16;30000;1062.4;40;9;1;3;0;-2;-1;1;1;1;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;9;22;22;30000;1065.8;60;9;1;5;0;0;0;0;1;1;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;9;22;32;30000;1072.5;60;9;1;2;0;0;-2;0;1;1;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;9;32;9;30000;1113.6;50;9;1;6;0;1;0;1;0;1;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;9;32;22;30000;1351.2;60;9;1;3;0;-2;0;1;0;1;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;9;32;32;30000;1398.1;60;9;1;8;0;-2;0;1;1;1;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;10;10;10;30000;637.6;30;10;1;2;0;-1;-1;0;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;13;5;5;30000;245.9;20;13;1;2;0;1;-1;0;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;13;5;7;30000;262.0;24;13;1;12;0;-1;0;0;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;13;5;8;30000;268.9;25;13;1;11;0;-1;-1;0;1;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;13;5;13;30000;278.8;30;13;1;4;0;-1;-1;0;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;13;5;16;30000;457.6;30;13;1;9;0;-2;-1;0;1;0;1;1;1;2;1;0 +Tesla P100-PCIE-16GB [0x2f6c];3;13;5;24;30000;464.2;40;13;1;13;0;-1;0;0;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;13;5;26;30000;437.1;53;13;1;6;0;1;-2;0;0;1;1;1;1;2;1;0 +Tesla P100-PCIE-16GB [0x2f6c];3;13;7;5;30000;347.6;25;13;1;12;0;-1;-2;0;1;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;13;7;7;30000;364.8;24;13;1;5;0;-2;-2;0;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;13;7;13;30000;433.8;30;13;1;13;0;1;0;0;0;1;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;13;8;5;30000;388.2;25;13;1;11;0;-2;-1;0;1;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;13;13;5;30000;716.0;26;13;1;12;0;-1;-2;0;0;0;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;13;13;7;30000;808.8;40;13;1;6;0;0;-2;0;1;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;13;13;13;30000;838.5;50;13;1;5;0;-2;-2;0;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;13;13;16;30000;875.5;50;13;1;8;0;1;-1;0;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;13;13;24;30000;749.0;17;13;1;10;0;-1;0;0;1;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;13;13;26;30000;746.5;5;13;1;6;0;-2;-1;1;0;1;1;1;1;0;1;0 +Tesla P100-PCIE-16GB [0x2f6c];3;13;16;5;30000;770.1;25;13;1;12;0;1;-2;0;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;13;16;13;30000;982.7;50;13;1;13;0;-1;-1;1;0;0;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;13;16;16;30000;973.6;60;13;1;7;0;0;-1;0;1;1;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;13;16;24;30000;1050.2;60;13;1;8;0;0;0;0;1;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;13;16;26;30000;975.0;53;13;1;2;0;-1;0;1;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;13;24;5;30000;825.2;50;13;1;6;0;-1;-1;0;1;0;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;13;24;13;30000;1175.7;40;13;1;6;0;-1;-2;1;1;0;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;13;24;16;30000;1263.4;40;13;1;4;0;-2;1;1;0;0;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;13;24;24;30000;1356.1;60;13;1;7;0;1;-1;1;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;13;24;26;30000;1209.2;53;13;1;6;0;-1;-1;0;1;0;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;13;26;5;30000;874.1;30;13;1;11;0;-2;-1;0;0;1;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;13;26;13;30000;1295.5;60;13;1;13;0;-2;-2;1;1;1;1;1;1;1;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;13;26;16;30000;1376.1;60;13;1;4;0;1;-2;1;1;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;13;26;24;30000;1084.3;54;13;1;8;0;-1;-1;0;0;1;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;13;26;26;30000;1427.8;60;13;1;11;0;1;0;0;1;0;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;14;14;14;30000;908.2;50;14;1;3;0;1;-1;0;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;14;14;16;30000;947.5;30;14;1;14;0;0;0;0;1;1;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;14;14;29;30000;834.1;5;14;1;6;0;0;0;0;0;0;1;1;1;1;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;14;16;14;30000;987.5;40;14;1;13;0;-1;-2;1;0;1;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;14;16;16;30000;1013.9;60;14;1;7;0;-2;-1;0;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;14;16;29;30000;893.9;4;14;1;4;0;0;0;1;1;1;1;1;1;0;1;0 +Tesla P100-PCIE-16GB [0x2f6c];3;14;29;14;30000;1441.8;60;14;1;7;0;-2;-2;1;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;14;29;16;30000;1521.6;60;14;1;13;0;1;-1;0;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;14;29;29;30000;1489.4;50;14;1;9;0;0;-1;1;1;1;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;15;15;15;30000;973.0;30;15;1;12;0;-2;-2;0;0;0;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;5;5;0;194.0;23;16;1;0;0;0;0;0;0;0;1;0;0;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;5;13;30000;581.2;50;16;1;16;0;-1;1;0;0;0;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;5;16;30000;592.4;40;16;1;12;0;-1;0;0;1;1;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;5;24;30000;439.1;6;16;1;14;0;1;1;0;0;1;1;1;1;1;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;5;26;30000;581.3;60;16;1;15;0;0;0;0;0;1;1;1;1;2;1;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;8;5;30000;462.6;25;16;1;8;0;-2;-2;0;0;1;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;8;8;30000;511.4;30;16;1;15;0;0;-2;0;0;1;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;9;9;30000;562.2;30;16;1;16;0;1;0;0;0;1;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;9;16;30000;634.9;40;16;1;7;0;0;-1;0;1;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;9;22;30000;632.4;50;16;1;10;0;-2;-2;0;0;1;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;13;5;30000;786.7;24;16;1;15;0;-2;-1;0;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;13;13;30000;1056.9;25;16;1;2;0;1;1;1;1;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;13;16;30000;1147.4;30;16;1;4;0;0;-2;0;0;0;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;13;24;30000;852.4;5;16;1;10;0;-1;-2;1;0;0;1;1;1;1;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;13;26;30000;1097.1;40;16;1;15;0;1;-1;1;0;1;1;0;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;14;14;30000;1136.9;25;16;1;12;0;1;-2;0;1;1;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;14;16;30000;1169.5;30;16;1;14;0;-1;-1;0;0;0;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;14;29;30000;901.8;7;16;1;10;0;1;0;0;0;0;1;0;1;1;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;16;5;30000;860.6;25;16;1;16;0;-1;-2;0;1;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;16;9;30000;1044.8;50;16;1;7;0;0;0;0;0;1;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;16;13;30000;1059.9;50;16;1;15;0;-2;0;0;0;0;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;16;14;30000;1083.5;40;16;1;15;0;0;-1;0;0;0;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;16;16;30000;1099.0;40;16;1;14;0;-1;0;0;0;1;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;16;22;30000;1128.1;60;16;1;10;0;1;-2;0;0;0;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;16;24;30000;1110.8;40;16;1;15;0;0;-2;0;1;1;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;16;26;30000;1104.1;50;16;1;11;0;0;-2;1;0;0;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;16;29;30000;977.5;5;16;1;6;0;1;-2;0;1;1;1;1;1;1;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;16;55;30000;1030.9;1;16;1;7;0;1;1;0;0;1;1;0;1;0;1;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;22;9;30000;1267.6;30;16;1;2;0;0;-1;0;1;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;22;16;30000;1382.6;50;16;1;8;0;1;1;1;1;0;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;22;22;30000;1411.9;60;16;1;12;0;1;-2;1;0;1;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;24;5;30000;877.9;25;16;1;11;0;0;-2;1;0;0;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;24;13;30000;1361.4;40;16;1;13;0;1;-2;1;0;0;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;24;16;30000;1463.5;60;16;1;4;0;-2;-2;0;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;24;24;30000;1164.1;36;16;1;10;0;-1;0;0;0;1;1;0;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;24;26;30000;1158.0;7;16;1;15;0;1;0;0;0;1;1;1;1;1;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;26;5;30000;969.1;30;16;1;10;0;-1;-1;0;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;26;13;30000;1469.9;50;16;1;5;0;1;0;1;1;1;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;26;16;30000;1548.9;60;16;1;6;0;-1;0;1;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;26;24;30000;1554.5;60;16;1;11;0;0;-1;0;0;0;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;26;26;30000;1486.2;50;16;1;11;0;0;-1;0;1;0;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;29;14;30000;1578.2;50;16;1;4;0;-1;1;1;0;1;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;29;16;30000;1569.0;50;16;1;9;0;0;0;0;0;0;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;29;29;30000;1555.2;50;16;1;10;0;-1;-2;0;0;1;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;29;55;30000;1359.1;17;16;1;15;0;1;0;0;1;1;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;55;16;30000;1411.0;45;16;1;3;0;-2;1;1;0;1;1;1;1;1;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;55;29;30000;1505.1;23;16;1;13;0;0;-1;0;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;16;55;55;30000;1634.4;36;16;1;13;0;-1;0;0;1;0;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;20;20;20;30000;1396.9;50;20;1;8;0;-2;-2;0;0;1;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;22;9;9;30000;620.0;30;22;1;14;0;1;0;0;0;0;1;1;1;1;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;22;9;16;30000;635.4;40;22;1;21;0;-2;-2;0;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;22;9;22;30000;642.7;60;22;1;18;0;-2;-1;0;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;22;9;32;30000;603.6;27;22;1;17;0;-1;0;0;0;1;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;22;16;9;30000;955.7;50;22;1;12;0;-2;-2;1;0;1;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;22;16;16;30000;1124.4;50;22;1;11;0;-1;-2;0;0;1;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;22;16;22;30000;1161.8;60;22;1;21;0;0;0;0;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;22;22;9;30000;1371.4;60;22;1;8;0;0;-1;0;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;22;22;16;30000;1475.2;50;22;1;8;0;-1;-2;0;1;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;22;22;22;30000;1550.1;60;22;1;19;0;0;-1;0;0;1;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;22;22;32;30000;1421.8;40;22;1;1;0;-2;0;0;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;22;32;9;30000;1594.6;50;22;1;3;0;0;1;0;1;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;22;32;22;30000;2044.8;60;22;1;10;0;-2;0;0;1;0;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;22;32;32;30000;2052.0;60;22;1;15;0;0;0;0;1;0;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;23;23;23;30000;1657.8;50;23;1;17;0;0;0;0;0;1;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;24;5;5;30000;557.5;24;24;1;1;0;-1;-1;0;1;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;24;5;13;30000;657.2;40;24;1;22;0;0;0;1;1;0;1;1;1;2;1;0 +Tesla P100-PCIE-16GB [0x2f6c];3;24;5;16;30000;652.6;50;24;1;13;0;0;-1;1;0;1;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;24;5;24;30000;600.1;53;24;1;1;0;-2;1;0;1;1;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;24;5;26;30000;621.4;60;24;1;20;0;0;-2;1;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;24;13;5;30000;857.0;30;24;1;20;0;1;-1;1;0;1;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;24;13;13;30000;1145.1;25;24;1;22;0;1;1;1;0;0;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;24;13;16;30000;991.2;45;24;1;19;0;-1;0;0;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;24;13;24;30000;1111.6;50;24;1;6;0;-1;-1;0;0;1;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;24;13;26;30000;1022.9;25;24;1;22;0;-2;-1;0;1;1;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;24;16;5;30000;980.0;40;24;1;10;0;-1;0;0;0;1;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;24;16;13;30000;1524.4;50;24;1;21;0;-2;-1;0;0;1;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;24;16;16;30000;1541.4;60;24;1;12;0;0;-1;1;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;24;16;24;30000;1506.5;50;24;1;24;0;-1;-1;0;1;1;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;24;16;26;30000;1178.7;26;24;1;24;0;0;0;1;0;1;1;1;1;1;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;24;24;5;30000;1051.1;50;24;1;23;0;1;-2;1;0;1;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;24;24;13;30000;1584.1;50;24;1;7;0;-1;-1;1;1;1;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;24;24;16;30000;1630.0;60;24;1;5;0;0;-2;0;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;24;24;24;30000;1606.4;50;24;1;1;0;1;0;1;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;24;24;26;30000;1483.6;46;24;1;4;0;-1;0;0;1;1;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;24;26;5;30000;1069.4;40;24;1;20;0;0;-1;0;1;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;24;26;13;30000;1516.6;40;24;1;23;0;-1;-1;0;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;24;26;16;30000;1617.3;40;24;1;21;0;1;0;0;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;24;26;24;30000;1806.5;60;24;1;13;0;-2;0;0;0;0;1;0;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;24;26;26;30000;1777.9;60;24;1;17;0;1;0;1;0;1;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;25;25;25;30000;1779.6;60;25;1;12;0;-2;-1;0;0;1;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;26;5;5;30000;534.8;20;26;1;1;0;-1;0;1;0;1;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;26;5;13;30000;691.2;40;26;1;13;0;-1;-2;1;1;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;26;5;16;30000;693.3;40;26;1;21;0;0;-1;0;1;0;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;26;5;24;30000;520.0;25;26;1;23;0;1;-2;0;0;0;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;26;5;26;30000;524.8;3;26;1;25;0;1;1;1;1;0;1;1;1;2;1;0 +Tesla P100-PCIE-16GB [0x2f6c];3;26;13;5;30000;939.0;40;26;1;9;0;-1;-1;0;1;0;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;26;13;13;30000;1240.9;40;26;1;7;0;-2;0;0;0;0;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;26;13;16;30000;1178.2;50;26;1;22;0;0;-2;1;0;0;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;26;13;24;30000;1030.6;24;26;1;26;0;1;-1;0;1;0;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;26;13;26;30000;1253.7;60;26;1;1;0;1;0;1;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;26;16;5;30000;976.2;40;26;1;11;0;0;-2;1;0;0;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;26;16;13;30000;1571.2;50;26;1;26;0;1;1;0;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;26;16;16;30000;1174.4;47;26;1;4;0;-1;-1;1;0;1;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;26;16;24;30000;1579.9;60;26;1;23;0;1;-1;0;1;1;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;26;16;26;30000;1195.7;25;26;1;18;0;-2;-2;0;1;1;1;0;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;26;24;5;30000;1085.3;50;26;1;26;0;0;0;0;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;26;24;13;30000;1443.2;50;26;1;1;0;1;-1;1;1;1;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;26;24;16;30000;1652.9;60;26;1;9;0;0;0;0;0;1;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;26;24;24;30000;1443.9;30;26;1;15;0;0;-1;0;0;0;1;0;1;1;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;26;24;26;30000;1482.0;36;26;1;23;0;1;0;0;1;0;1;1;1;1;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;26;26;5;30000;1076.0;50;26;1;23;0;0;-1;0;0;0;1;0;1;1;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;26;26;13;30000;1654.9;60;26;1;23;0;0;-2;0;0;0;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;26;26;16;30000;1613.0;53;26;1;26;0;-1;0;0;1;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;26;26;24;30000;1521.5;25;26;1;17;0;1;-1;0;0;1;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;26;26;26;30000;1825.8;60;26;1;22;0;1;0;0;0;1;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;28;28;28;30000;2017.4;60;28;1;25;0;0;0;0;0;1;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;29;14;14;30000;1063.5;50;29;1;28;0;0;-1;0;0;0;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;29;14;16;30000;1124.0;60;29;1;27;0;0;0;1;1;0;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;29;14;29;30000;1086.7;7;29;1;26;0;-2;0;1;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;29;16;14;30000;1190.2;55;29;1;1;0;1;-1;1;1;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;29;16;16;30000;1402.8;50;29;1;5;0;1;0;0;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;29;16;29;30000;1226.1;30;29;1;14;0;-2;0;1;0;0;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;29;16;55;30000;1096.1;9;29;1;22;0;0;0;1;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;29;29;14;30000;1676.4;40;29;1;24;0;-1;0;1;1;1;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;29;29;16;30000;1869.9;60;29;1;10;0;1;-1;0;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;29;29;29;30000;1741.8;40;29;1;25;0;-2;0;0;0;0;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;29;29;55;30000;1646.8;37;29;1;28;0;1;-2;1;1;1;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;29;55;16;30000;1872.0;40;29;1;27;0;0;0;0;0;0;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;29;55;29;30000;2156.0;31;29;1;17;0;0;0;1;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;29;55;55;30000;2066.8;5;29;1;25;0;0;0;0;0;0;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;30;30;30;30000;1919.2;40;30;1;1;0;-2;0;0;0;0;1;1;1;0;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;32;32;9;30000;1831.3;60;32;1;6;0;-1;1;1;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;32;32;22;30000;2073.6;40;32;1;1;0;-1;-1;0;1;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;32;32;32;30000;2187.8;50;32;1;1;0;1;0;0;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;35;35;35;30000;1744.5;18;35;1;33;0;2;0;0;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;36;36;36;30000;1823.8;36;36;1;24;0;-1;-2;0;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;40;40;40;0;1912.2;34;40;1;0;0;0;0;0;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;55;16;16;30000;1311.0;25;55;1;32;0;0;0;1;1;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;55;16;29;30000;1499.1;22;55;1;19;0;-1;0;1;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;55;16;55;30000;1080.8;8;55;1;19;0;-1;0;1;0;1;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;55;29;16;30000;1699.5;34;55;1;19;0;-1;-1;0;1;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;55;29;29;30000;1710.1;9;55;1;52;0;0;0;0;0;0;1;1;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;55;29;55;30000;1030.0;8;55;1;33;0;0;0;0;0;0;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;55;55;16;30000;2125.2;46;55;1;51;0;0;-2;0;0;0;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;55;55;29;30000;2243.0;8;55;1;29;0;0;0;0;1;0;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;55;55;55;30000;1768.7;8;55;1;42;0;0;0;0;0;0;1;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;64;64;64;30000;1239.7;55;64;1;1;0;0;0;0;0;0;0;0;1;2;0;0 +Tesla P100-PCIE-16GB [0x2f6c];3;78;78;78;30000;524.9;1;78;1;43;0;-1;1;0;1;0;1;1;0;2;1;0 diff --git a/src/acc/opencl/smm/params/tune_multiply_PVC.csv b/src/acc/opencl/smm/params/tune_multiply_PVC.csv index ac8a8a2100a..b98cde99aab 100644 --- a/src/acc/opencl/smm/params/tune_multiply_PVC.csv +++ b/src/acc/opencl/smm/params/tune_multiply_PVC.csv @@ -1,374 +1,1229 @@ DEVICE;TYPEID;M;N;K;S;GFLOPS;BS;BM;BN;BK;WS;WG;LU;NZ;AL;TB;TC;AP;AA;AB;AC -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;2;2;2;30000;0;4;2;1;1;0;-1;2;0;1;0;1;0;3;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;3;3;1;30000;0;5;3;1;2;0;-1;-2;0;1;0;1;0;2;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;3;3;3;30000;0;5;3;1;2;0;-1;-2;1;1;0;1;0;3;0;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;4;4;30000;0;10;4;1;2;0;-2;1;0;1;1;1;1;0;2;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;4;5;30000;0;11;4;1;4;0;1;-1;0;1;0;1;0;0;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;4;7;30000;0;9;4;1;2;0;1;0;0;0;1;1;0;0;3;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;4;9;30000;0;9;4;1;2;0;-2;0;0;0;0;1;0;0;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;4;10;30000;0;9;4;1;2;0;-1;2;0;1;0;1;0;0;1;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;4;13;30000;0;8;4;1;1;0;0;-1;1;0;0;1;0;0;0;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;4;15;30000;0;8;4;1;1;0;-2;0;1;1;1;1;0;3;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;4;17;30000;0;8;4;1;1;0;-1;-2;0;1;0;1;0;0;2;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;4;25;30000;0;8;4;1;2;0;-2;2;0;1;0;1;0;3;3;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;4;26;30000;0;9;4;1;1;0;-1;0;0;1;1;1;0;3;0;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;4;28;30000;0;9;4;1;1;0;1;0;0;1;1;1;1;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;4;32;30000;0;8;4;1;1;0;0;-1;0;1;1;1;1;0;0;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;5;4;30000;0;10;4;1;2;0;-1;-2;1;0;0;1;1;3;0;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;5;5;30000;0;10;4;1;3;0;-2;-2;0;1;0;1;0;3;3;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;5;7;30000;0;10;4;1;3;0;-2;-1;0;1;0;1;0;3;0;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;5;9;30000;0;9;4;1;1;0;-2;0;0;0;0;1;0;3;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;5;13;30000;0;8;4;1;1;0;-1;-2;1;1;1;1;0;0;2;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;5;17;30000;0;8;4;1;1;0;-2;0;1;1;0;1;0;0;0;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;5;25;30000;0;5;4;1;1;0;-1;0;1;1;0;1;0;0;3;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;5;32;30000;0;8;4;1;1;0;-2;-1;0;1;1;1;0;3;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;7;4;30000;0;11;4;1;2;0;-1;-2;0;1;0;1;1;3;2;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;7;5;30000;0;14;4;1;1;0;-2;-2;0;1;1;1;1;0;0;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;7;7;30000;0;12;4;1;1;0;-1;0;0;0;1;1;0;0;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;7;9;30000;0;9;4;1;2;0;-1;2;1;1;0;1;1;3;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;7;13;30000;0;8;4;1;1;0;-1;-2;1;1;0;1;1;3;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;9;4;30000;0;14;4;1;1;0;-1;-2;0;1;0;1;1;3;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;9;5;30000;0;12;4;1;4;0;-1;-1;0;0;0;1;1;3;0;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;9;7;30000;0;12;4;1;2;0;-1;1;0;1;0;1;1;3;3;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;9;9;30000;0;8;4;1;1;0;-1;-2;0;0;0;1;1;0;0;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;9;13;30000;0;8;4;1;4;0;-1;0;0;1;0;1;0;1;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;10;4;30000;0;16;4;1;4;0;-1;-1;0;1;0;1;1;3;0;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;10;10;30000;0;9;4;1;3;0;1;0;0;1;0;1;1;3;3;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;13;4;30000;0;16;4;1;2;0;-1;-2;0;0;1;1;1;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;13;5;30000;0;14;4;1;1;0;-2;0;0;0;1;1;0;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;13;7;30000;0;12;4;1;1;0;2;0;0;1;1;1;0;3;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;13;9;30000;0;8;4;1;2;0;-2;-2;0;1;0;1;1;0;1;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;13;13;30000;0;8;4;1;1;0;-2;-2;0;1;0;1;1;0;1;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;13;17;30000;0;8;4;1;1;0;-1;-1;0;1;1;1;1;0;0;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;13;32;30000;0;8;4;1;1;0;-1;-1;0;1;1;1;1;0;0;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;15;4;30000;0;14;4;1;2;0;-2;2;0;1;0;1;1;3;0;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;17;4;30000;0;12;4;1;3;0;-1;-2;0;1;0;1;1;3;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;17;5;30000;0;14;4;1;2;0;0;1;0;1;0;1;1;3;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;17;13;30000;0;8;4;1;1;0;1;-1;1;1;0;1;1;0;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;17;17;30000;0;8;4;1;1;0;0;-1;0;1;0;1;1;0;0;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;17;32;30000;0;8;4;1;1;0;-2;0;1;1;0;1;1;3;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;25;4;30000;0;14;4;1;2;0;-2;0;0;1;0;1;1;3;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;25;5;30000;0;12;4;1;2;0;0;0;0;1;0;1;0;3;3;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;26;4;30000;0;14;4;1;4;0;0;0;1;1;0;1;1;0;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;28;4;30000;0;17;4;1;1;0;-1;0;0;1;0;1;1;0;1;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;32;4;30000;0;17;4;1;2;0;0;1;1;1;0;1;0;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;32;5;30000;0;21;4;1;1;0;-1;-1;0;1;1;1;1;0;0;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;32;13;30000;0;8;4;1;1;0;-1;-2;0;1;0;1;1;3;0;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;32;17;30000;0;8;4;1;1;0;1;-1;1;1;1;1;0;3;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;32;32;30000;0;8;4;1;1;0;1;2;1;1;1;1;0;3;0;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;4;4;30000;0;14;5;1;1;0;-1;-2;0;0;0;1;0;0;1;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;4;5;30000;0;12;5;1;2;0;0;0;0;0;0;1;0;0;0;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;4;7;30000;0;12;5;1;1;0;-1;-2;0;1;1;1;0;3;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;4;9;30000;0;12;5;1;1;0;-2;-1;0;1;0;1;0;3;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;4;13;30000;0;8;5;1;1;0;-2;-2;0;0;1;1;0;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;4;17;30000;0;12;5;1;1;0;-2;-1;0;1;0;1;0;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;4;25;30000;0;8;5;1;1;0;-2;-1;1;1;0;1;0;0;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;4;32;30000;0;8;5;1;3;0;-1;-1;0;0;1;1;1;3;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;5;4;30000;0;12;5;1;1;0;-1;-1;0;0;0;1;0;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;5;5;30000;0;8;5;1;2;0;-2;2;0;1;1;1;0;0;2;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;5;7;30000;0;12;5;1;1;0;-1;-2;0;0;0;1;0;0;2;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;5;9;30000;0;11;5;1;1;0;-2;-1;0;1;0;1;0;0;2;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;5;13;30000;0;9;5;1;1;0;-1;0;0;0;1;1;0;0;1;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;5;16;30000;0;8;5;1;1;0;-2;-1;0;0;0;1;0;0;1;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;5;17;30000;0;8;5;1;1;0;-1;0;1;1;0;1;0;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;5;24;30000;0;8;5;1;1;0;-1;-1;0;0;0;1;0;0;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;5;26;30000;0;8;5;1;1;0;-1;0;1;0;0;1;0;0;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;5;32;30000;0;8;5;1;1;0;-1;-1;0;1;0;1;0;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;7;4;30000;0;12;5;1;1;0;0;0;0;0;0;1;0;0;0;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;7;5;30000;0;13;5;1;1;0;-2;-2;0;1;0;1;0;3;1;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;7;7;30000;0;12;5;1;1;0;-2;-2;0;1;0;1;0;0;1;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;7;9;30000;0;8;5;1;1;0;0;-1;1;1;0;1;0;3;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;7;13;30000;0;8;5;1;2;0;1;0;1;1;0;1;1;0;3;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;9;4;30000;0;16;5;1;1;0;1;0;0;1;0;1;0;0;0;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;9;5;30000;0;16;5;1;1;0;-1;0;1;1;0;1;0;3;2;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;9;7;30000;0;12;5;1;1;0;-1;-2;0;1;0;1;0;0;0;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;9;9;30000;0;12;5;1;1;0;-1;0;1;1;1;1;1;0;0;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;13;4;30000;0;16;5;1;1;0;-2;-1;0;1;0;1;0;0;0;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;13;5;30000;0;14;5;1;1;0;-2;-2;0;1;1;1;1;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;13;7;30000;0;12;5;1;1;0;-1;-1;1;1;0;1;1;0;3;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;13;13;30000;0;8;5;1;1;0;-2;-1;1;1;0;1;1;0;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;13;16;30000;0;8;5;1;1;0;-1;0;1;1;0;1;1;3;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;13;17;30000;0;8;5;1;1;0;-2;-1;1;1;0;1;1;0;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;13;24;30000;0;8;5;1;1;0;-2;-1;0;1;1;1;1;0;0;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;13;26;30000;0;8;5;1;1;0;-1;-2;0;1;0;1;1;0;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;13;32;30000;0;8;5;1;1;0;-2;0;0;1;0;1;0;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;16;5;30000;0;16;5;1;1;0;-1;-1;1;1;1;1;1;0;1;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;16;13;30000;0;8;5;1;1;0;-1;-1;1;1;0;1;1;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;16;16;30000;0;8;5;1;1;0;-2;-1;1;1;1;1;0;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;16;24;30000;0;8;5;1;1;0;-1;-2;1;1;1;1;0;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;16;26;30000;0;8;5;1;1;0;-2;-1;0;1;0;1;1;0;0;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;17;4;30000;0;14;5;1;5;0;-2;-1;0;1;0;1;0;3;3;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;17;5;30000;0;17;5;1;1;0;-2;-1;0;1;0;1;1;0;2;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;17;13;30000;0;8;5;1;1;0;-2;-2;0;1;0;1;0;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;17;17;30000;0;8;5;1;1;0;-2;-2;0;1;1;1;1;3;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;17;32;30000;0;8;5;1;1;0;1;0;0;1;0;1;1;3;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;24;5;30000;0;23;5;1;1;0;1;0;0;1;0;1;1;3;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;24;13;30000;0;17;5;1;1;0;1;0;1;1;0;1;1;3;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;24;16;30000;0;8;5;1;1;0;1;0;1;0;1;1;0;3;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;25;4;30000;0;22;5;1;1;0;-2;0;0;1;0;1;1;3;0;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;26;5;30000;0;17;5;1;1;0;-1;-1;0;1;0;1;1;3;2;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;26;13;30000;0;8;5;1;1;0;1;0;1;1;1;1;0;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;26;16;30000;0;8;5;1;1;0;-1;0;1;1;1;1;0;3;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;32;4;30000;0;22;5;1;1;0;-1;0;0;1;1;1;1;3;1;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;32;5;30000;0;22;5;1;1;0;-1;-2;1;1;0;1;1;0;2;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;32;13;30000;0;8;5;1;1;0;0;0;0;1;0;1;1;3;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;32;17;30000;0;8;5;1;1;0;-2;0;0;1;1;1;0;3;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;32;32;30000;0;8;5;1;1;0;1;-2;0;1;0;1;0;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;6;6;6;30000;0;9;6;1;3;0;0;1;0;1;0;1;1;0;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;6;6;7;30000;0;12;6;1;1;0;-1;0;0;1;0;1;0;0;1;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;6;6;8;30000;0;13;6;1;1;0;0;0;0;1;0;1;0;3;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;6;7;6;30000;0;14;6;1;1;0;-1;-2;0;1;0;1;1;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;6;7;7;30000;0;9;6;1;3;0;0;-1;0;1;1;1;0;0;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;6;7;8;30000;0;9;6;1;6;0;-1;0;1;1;1;1;0;2;1;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;6;8;6;30000;0;14;6;1;2;0;0;0;0;1;1;1;1;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;6;8;7;30000;0;15;6;1;1;0;-2;0;0;1;1;1;1;0;1;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;6;8;8;30000;0;16;6;1;5;0;1;-2;0;1;0;1;0;3;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;4;4;30000;0;16;7;1;5;0;-2;-1;0;1;0;1;0;0;1;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;4;5;30000;0;14;7;1;7;0;-1;0;0;1;0;1;1;0;0;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;4;7;30000;0;12;7;1;3;0;-2;1;0;1;0;1;1;0;0;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;4;9;30000;0;9;7;1;2;0;-2;-1;0;1;1;1;0;3;2;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;4;13;30000;0;9;7;1;3;0;-2;0;0;1;0;1;0;2;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;5;4;30000;0;16;7;1;1;0;1;0;1;1;0;1;0;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;5;5;30000;0;16;7;1;1;0;1;-2;0;1;0;1;1;3;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;5;7;30000;0;16;7;1;1;0;-2;-2;0;1;1;1;1;3;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;5;9;30000;0;11;7;1;1;0;-1;-2;0;1;1;1;0;0;1;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;5;13;30000;0;8;7;1;5;0;-2;-2;0;1;0;1;0;3;0;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;6;6;30000;0;16;7;1;7;0;-1;-1;0;1;0;1;0;0;0;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;6;7;30000;0;12;7;1;1;0;-1;-2;1;1;0;1;1;0;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;6;8;30000;0;16;7;1;5;0;-1;-1;0;1;0;1;0;0;1;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;7;4;30000;0;14;7;1;1;0;-2;-2;1;1;0;1;1;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;7;5;30000;0;16;7;1;1;0;-1;-2;0;1;0;1;1;3;1;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;7;6;30000;0;16;7;1;1;0;-2;-1;0;1;1;1;1;0;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;7;7;30000;0;9;7;1;3;0;0;0;0;1;0;1;1;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;7;8;30000;0;13;7;1;1;0;-1;-1;1;1;0;1;1;0;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;7;9;30000;0;13;7;1;2;0;-1;0;0;1;1;1;0;3;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;7;13;30000;0;8;7;1;2;0;0;2;1;1;1;1;0;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;8;6;30000;0;16;7;1;1;0;-2;-1;1;1;1;1;0;0;0;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;8;7;30000;0;16;7;1;4;0;0;0;0;1;0;1;1;0;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;8;8;30000;0;15;7;1;4;0;-1;-1;0;1;1;1;0;0;3;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;9;4;30000;0;18;7;1;2;0;-1;-1;0;1;1;1;1;3;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;9;5;30000;0;18;7;1;1;0;-1;-2;0;1;0;1;1;3;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;9;7;30000;0;12;7;1;1;0;1;-2;0;1;0;1;1;3;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;13;4;30000;0;21;7;1;1;0;0;-2;0;1;0;1;1;0;0;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;13;5;30000;0;17;7;1;6;0;-2;-1;1;1;1;1;1;3;1;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;13;7;30000;0;14;7;1;1;0;1;-1;1;1;1;1;0;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;13;13;30000;0;11;7;1;1;0;0;-2;1;1;1;1;1;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;8;6;6;30000;0;16;8;1;4;0;-1;-1;0;1;0;1;0;0;1;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;8;6;7;30000;0;10;8;1;4;0;0;2;1;1;0;1;0;3;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;8;6;8;30000;0;9;8;1;6;0;-1;0;0;1;1;1;0;3;3;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;8;7;6;30000;0;15;8;1;4;0;-1;-1;1;1;0;1;0;3;0;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;8;7;7;30000;0;13;8;1;2;0;-2;-1;0;1;0;1;0;0;2;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;8;7;8;30000;0;16;8;1;1;0;-1;0;0;1;1;1;0;3;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;8;8;6;30000;0;12;8;1;2;0;1;-2;1;1;0;1;0;3;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;8;8;7;30000;0;16;8;1;1;0;-2;-2;0;1;0;1;1;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;8;8;8;30000;0;4;8;1;4;0;-1;1;0;1;0;1;1;0;1;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;4;4;30000;0;18;9;1;2;0;-1;0;0;1;0;1;0;3;0;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;4;5;30000;0;16;9;1;8;0;-1;-2;1;1;1;1;1;3;2;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;4;7;30000;0;12;9;1;1;0;-2;-2;0;1;1;1;1;3;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;4;9;30000;0;9;9;1;3;0;-2;1;1;1;1;1;1;3;2;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;4;13;30000;0;8;9;1;9;0;-1;0;0;1;0;1;1;3;0;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;5;4;30000;0;21;9;1;4;0;-2;-1;0;1;1;1;1;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;5;5;30000;0;16;9;1;1;0;-1;0;1;1;1;1;0;0;3;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;5;7;30000;0;9;9;1;9;0;-2;-1;1;1;0;1;0;3;0;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;5;9;30000;0;9;9;1;3;0;-1;-2;1;1;0;1;1;0;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;7;4;30000;0;18;9;1;1;0;-1;-1;0;1;0;1;1;0;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;7;5;30000;0;13;9;1;4;0;1;2;1;1;1;1;1;0;0;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;7;7;30000;0;11;9;1;1;0;-2;-2;1;1;0;1;0;0;0;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;9;4;30000;0;16;9;1;8;0;-1;-2;0;1;0;1;0;3;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;9;5;30000;0;16;9;1;5;0;0;-1;1;1;0;1;1;3;0;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;9;9;30000;0;9;9;1;4;0;-1;-2;0;1;0;1;1;0;2;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;9;16;30000;0;11;9;1;5;0;-1;-2;1;0;0;1;0;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;9;22;30000;0;8;9;1;8;0;-1;-1;0;1;0;1;0;0;0;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;9;32;30000;0;8;9;1;1;0;-1;-1;1;1;1;1;0;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;13;4;30000;0;22;9;1;4;0;-1;0;1;1;0;1;1;0;2;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;16;9;30000;0;18;9;1;3;0;-1;-2;1;0;1;1;0;0;0;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;16;16;30000;0;14;9;1;1;0;-1;-1;1;1;0;1;0;0;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;16;22;30000;0;12;9;1;9;0;-1;0;1;1;0;1;0;0;3;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;22;9;30000;0;21;9;1;1;0;-1;-1;1;0;0;1;1;3;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;22;16;30000;0;9;9;1;1;0;1;-2;1;1;0;1;1;0;2;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;22;22;30000;0;8;9;1;1;0;-2;2;1;1;0;1;1;0;0;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;22;32;30000;0;8;9;1;1;0;0;-2;1;1;0;1;1;3;0;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;32;9;30000;0;23;9;1;2;0;-2;0;1;1;0;1;1;2;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;32;22;30000;0;8;9;1;1;0;-2;2;1;1;1;1;0;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;32;32;30000;0;8;9;1;1;0;0;-2;0;1;1;1;1;1;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;10;4;4;30000;0;14;10;1;5;0;-2;-1;0;1;1;1;1;3;1;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;10;4;10;30000;0;10;10;1;5;0;0;-2;0;1;0;1;1;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;10;10;4;30000;0;16;10;1;2;0;-1;-1;1;1;1;1;1;0;2;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;10;10;10;30000;0;8;10;1;3;0;-1;1;1;1;0;1;1;0;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;4;4;30000;0;16;13;1;8;0;-1;-1;0;1;1;1;1;0;2;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;4;5;30000;0;14;13;1;5;0;-1;-1;0;1;0;1;0;0;1;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;4;7;30000;0;9;13;1;12;0;-1;0;1;1;0;1;1;0;0;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;4;9;30000;0;10;13;1;5;0;-1;1;0;1;0;1;1;0;0;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;4;13;30000;0;9;13;1;4;0;-2;0;0;1;1;1;1;3;3;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;4;17;30000;0;10;13;1;13;0;-1;0;1;1;0;1;0;3;3;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;4;32;30000;0;9;13;1;13;0;-2;1;0;1;1;1;1;0;3;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;5;4;30000;0;13;13;1;5;0;-1;1;0;1;0;1;0;0;0;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;5;5;30000;0;9;13;1;4;0;-1;0;1;1;1;1;1;2;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;5;7;30000;0;9;13;1;9;0;-1;-2;0;1;0;1;1;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;5;13;30000;0;9;13;1;6;0;-1;-2;0;1;0;1;1;0;3;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;5;16;30000;0;9;13;1;3;0;-2;0;0;1;1;1;1;0;3;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;5;17;30000;0;9;13;1;6;0;-2;0;0;1;0;1;1;0;3;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;5;24;30000;0;8;13;1;3;0;-1;-1;0;1;0;1;1;0;3;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;5;26;30000;0;8;13;1;7;0;-1;-2;0;1;0;1;0;3;3;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;5;32;30000;0;10;13;1;1;0;-2;-1;1;1;1;1;1;3;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;7;4;30000;0;14;13;1;1;0;-2;-2;0;1;0;1;0;3;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;7;5;30000;0;23;13;1;4;0;-1;0;0;1;1;1;0;3;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;7;7;30000;0;16;13;1;2;0;-1;0;1;1;1;1;0;3;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;7;13;30000;0;10;13;1;8;0;-2;-2;1;1;0;1;1;3;3;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;9;4;30000;0;15;13;1;11;0;-1;0;0;1;0;1;1;0;0;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;13;4;30000;0;26;13;1;1;0;-1;-2;1;1;0;1;0;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;13;5;30000;0;23;13;1;5;0;-1;0;1;1;1;1;1;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;13;7;30000;0;18;13;1;1;0;-1;0;1;1;1;1;0;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;13;13;30000;0;8;13;1;6;0;-1;2;0;1;0;1;1;3;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;13;17;30000;0;8;13;1;1;0;-1;0;1;1;0;1;1;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;13;32;30000;0;8;13;1;1;0;-2;0;1;1;0;1;1;0;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;16;5;30000;0;21;13;1;2;0;-2;0;1;1;0;1;1;0;1;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;17;4;30000;0;22;13;1;3;0;-1;-2;1;1;0;1;0;0;3;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;17;5;30000;0;20;13;1;9;0;0;0;1;1;1;1;0;1;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;17;13;30000;0;16;13;1;4;0;0;-1;1;1;0;1;0;3;3;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;17;17;30000;0;8;13;1;2;0;-1;-1;0;1;0;1;0;3;3;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;17;32;30000;0;9;13;1;1;0;0;2;1;1;1;1;1;3;0;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;24;5;30000;0;23;13;1;6;0;1;-1;1;1;1;1;0;1;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;26;5;30000;0;18;13;1;6;0;0;-1;1;1;0;1;0;1;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;32;4;30000;0;25;13;1;11;0;0;0;1;1;0;1;1;2;1;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;32;5;30000;0;29;13;1;6;0;1;-2;1;1;0;1;0;2;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;32;13;30000;0;9;13;1;1;0;-2;2;0;1;0;1;0;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;32;17;30000;0;8;13;1;1;0;-2;1;0;1;0;1;0;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;32;32;30000;0;21;13;1;1;0;0;0;1;0;0;1;1;3;0;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;15;4;4;30000;0;14;15;1;1;0;-2;2;0;1;1;1;0;3;0;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;15;15;15;30000;0;8;15;1;12;0;-1;-1;0;1;0;1;1;0;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;5;5;30000;0;17;16;1;13;0;-2;-2;0;1;0;1;0;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;5;13;30000;0;9;16;1;16;0;-2;-2;0;1;0;1;0;3;3;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;5;16;30000;0;9;16;1;9;0;-2;0;0;1;0;1;0;3;0;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;5;24;30000;0;8;16;1;14;0;-1;0;1;1;1;1;0;3;1;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;5;26;30000;0;8;16;1;14;0;-2;0;1;1;0;1;0;0;3;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;7;3;30000;0;23;16;1;5;0;-1;-2;0;1;1;1;1;0;2;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;9;9;30000;0;14;16;1;8;0;-1;-1;0;1;0;1;0;2;1;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;9;16;30000;0;9;16;1;11;0;-1;0;0;1;0;1;1;0;3;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;9;22;30000;0;6;16;1;10;0;0;0;0;1;0;1;1;3;1;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;13;5;30000;0;20;16;1;10;0;-1;0;1;1;0;1;1;3;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;16;5;30000;0;32;16;1;1;0;-2;2;1;1;0;1;0;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;16;9;30000;0;21;16;1;13;0;-1;-1;0;1;1;1;0;1;3;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;16;16;30000;0;8;16;1;5;0;-2;2;0;1;0;1;0;0;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;16;22;30000;0;21;16;1;1;0;-1;0;1;1;1;1;0;0;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;22;9;30000;0;9;16;1;5;0;-2;2;0;1;1;1;0;2;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;22;16;30000;0;9;16;1;1;0;1;1;1;1;1;1;0;3;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;22;22;30000;0;11;16;1;15;0;0;-2;0;1;0;1;1;3;1;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;24;5;30000;0;18;16;1;13;0;-2;-2;1;1;1;1;0;0;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;26;5;30000;0;19;16;1;7;0;1;-2;1;1;0;1;0;3;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;4;4;30000;0;16;17;1;7;0;-1;-1;0;1;0;1;0;0;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;4;5;30000;0;14;17;1;2;0;-1;1;0;1;0;1;1;3;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;4;13;30000;0;9;17;1;6;0;-1;0;1;1;0;1;0;3;2;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;4;17;30000;0;8;17;1;10;0;-2;0;1;1;0;1;0;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;4;32;30000;0;8;17;1;1;0;-2;2;0;1;0;1;1;0;0;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;5;4;30000;0;17;17;1;10;0;-1;-2;0;1;0;1;0;3;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;5;5;30000;0;16;17;1;15;0;-2;-2;1;1;0;1;0;3;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;5;13;30000;0;15;17;1;10;0;-1;-2;0;1;0;1;0;0;2;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;5;17;30000;0;8;17;1;10;0;-1;-2;0;1;1;1;0;0;3;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;5;32;30000;0;8;17;1;1;0;-1;-2;1;1;0;1;0;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;13;4;30000;0;15;17;1;16;0;1;-2;1;1;1;1;0;0;3;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;13;5;30000;0;19;17;1;2;0;-1;0;1;1;0;1;0;3;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;13;13;30000;0;14;17;1;7;0;-1;-2;0;1;0;1;1;0;3;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;13;17;30000;0;8;17;1;16;0;-1;0;1;1;0;1;1;0;2;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;13;32;30000;0;8;17;1;1;0;-1;-2;1;1;0;1;1;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;17;4;30000;0;21;17;1;11;0;1;-2;0;1;1;1;0;3;0;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;17;5;30000;0;22;17;1;7;0;-2;2;0;1;0;1;0;2;0;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;17;13;30000;0;41;17;1;7;0;0;-2;0;1;0;1;0;2;0;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;17;17;30000;0;4;17;1;6;0;1;-1;0;1;0;1;1;3;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;17;32;30000;0;8;17;1;4;0;-2;2;1;1;0;1;0;3;2;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;32;4;30000;0;26;17;1;12;0;0;-2;1;1;0;1;1;2;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;32;5;30000;0;21;17;1;11;0;-1;-2;1;1;0;1;1;3;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;32;13;30000;0;22;17;1;5;0;-1;2;0;1;0;1;0;3;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;32;17;30000;0;41;17;1;11;0;-1;1;1;1;0;1;1;1;0;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;32;32;30000;0;11;17;1;1;0;0;1;1;0;1;1;1;3;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;20;20;20;30000;0;3;20;1;16;0;-1;0;1;1;1;1;1;3;0;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;22;9;9;30000;0;9;22;1;6;0;-1;0;1;1;0;1;0;0;3;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;22;9;16;30000;0;23;22;1;11;0;-1;2;0;1;0;1;1;1;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;22;9;22;30000;0;8;22;1;11;0;-1;2;0;1;0;1;1;3;0;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;22;9;32;30000;0;8;22;1;1;0;-1;2;0;1;0;1;1;0;0;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;22;16;9;30000;0;19;22;1;4;0;-2;2;1;1;1;1;0;1;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;22;16;16;30000;0;9;22;1;21;0;-2;0;0;1;1;1;1;0;0;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;22;16;22;30000;0;9;22;1;10;0;-2;-1;0;1;0;1;1;0;0;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;22;22;9;30000;0;42;22;1;11;0;0;2;0;1;0;1;0;1;3;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;22;22;16;30000;0;15;22;1;1;0;-1;1;0;1;0;1;0;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;22;22;22;30000;0;15;22;1;1;0;-2;0;0;0;1;1;0;0;0;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;22;22;32;30000;0;16;22;1;1;0;-1;0;1;0;0;1;1;0;0;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;22;32;9;30000;0;30;22;1;14;0;-2;0;1;0;1;1;0;0;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;22;32;22;30000;0;15;22;1;21;0;0;0;1;0;0;1;0;1;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;22;32;32;30000;0;8;22;1;1;0;-1;1;1;1;0;1;0;1;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;23;23;23;30000;0;8;23;1;1;0;-1;1;1;0;0;1;0;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;24;5;5;30000;0;16;24;1;11;0;-2;2;1;0;1;1;1;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;24;5;13;30000;0;8;24;1;6;0;-1;0;0;1;1;1;1;3;2;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;24;5;16;30000;0;8;24;1;14;0;-1;0;0;1;0;1;1;3;3;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;24;13;5;30000;0;19;24;1;13;0;-2;-2;1;1;0;1;0;3;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;24;16;5;30000;0;27;24;1;1;0;-1;0;0;1;0;1;0;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;24;24;24;30000;0;13;24;1;13;0;0;-2;0;0;0;1;0;2;3;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;24;24;26;30000;0;11;24;1;9;0;0;0;0;0;0;1;1;1;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;24;24;32;30000;0;8;24;1;1;0;-1;1;0;1;1;1;1;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;24;26;24;30000;0;8;24;1;1;0;-2;1;1;0;0;1;1;2;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;24;26;26;30000;0;11;24;1;24;0;-1;0;0;0;0;1;1;2;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;24;26;32;30000;0;8;24;1;1;0;-1;1;0;0;1;1;0;1;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;24;32;24;30000;0;11;24;1;6;0;1;-1;0;0;1;1;0;1;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;24;32;26;30000;0;9;24;1;15;0;-2;-1;0;0;0;1;1;2;0;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;24;32;32;30000;0;17;24;1;21;0;0;0;0;0;0;1;1;1;3;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;4;4;30000;0;15;25;1;9;0;-1;-2;1;1;0;1;1;0;1;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;4;5;30000;0;12;25;1;4;0;-1;1;0;1;0;1;0;0;3;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;5;4;30000;0;16;25;1;18;0;-2;-1;0;1;0;1;0;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;25;25;30000;0;8;25;1;1;0;-1;1;1;0;0;1;0;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;4;4;30000;0;15;26;1;15;0;-1;0;0;1;1;1;1;0;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;5;5;30000;0;14;26;1;6;0;-1;0;0;0;0;1;0;0;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;5;13;30000;0;15;26;1;16;0;-1;0;0;0;1;1;0;3;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;5;16;30000;0;15;26;1;15;0;-1;-2;0;0;0;1;0;3;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;13;5;30000;0;20;26;1;3;0;-2;2;1;1;1;1;0;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;16;5;30000;0;22;26;1;8;0;-2;1;1;1;0;1;1;3;2;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;24;24;30000;0;11;26;1;23;0;-2;-2;1;0;0;1;0;2;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;24;26;30000;0;8;26;1;1;0;-2;1;0;0;1;1;1;1;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;24;32;30000;0;5;26;1;15;0;-1;0;1;0;0;1;1;1;3;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;26;24;30000;0;8;26;1;1;0;-1;1;0;1;0;1;0;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;26;26;30000;0;14;26;1;1;0;-2;1;1;0;1;1;0;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;26;32;30000;0;15;26;1;1;0;1;1;1;0;1;1;1;3;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;32;24;30000;0;8;26;1;14;0;-1;0;1;0;0;1;1;2;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;32;26;30000;0;12;26;1;25;0;0;-2;1;0;0;1;1;1;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;32;32;30000;0;15;26;1;1;0;0;1;1;0;0;1;1;0;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;4;4;30000;0;11;28;1;28;0;-1;-2;1;1;1;1;1;0;2;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;28;28;30000;0;15;28;1;1;0;0;2;0;0;0;1;1;3;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;30;30;30;30000;0;9;30;1;1;0;-1;1;1;0;0;1;0;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;4;4;30000;0;12;32;1;22;0;-1;0;0;0;0;1;0;0;1;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;4;5;30000;0;8;32;1;22;0;-1;-1;0;0;0;1;0;3;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;4;13;30000;0;8;32;1;1;0;-1;-1;0;0;0;1;0;3;0;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;4;17;30000;0;8;32;1;1;0;-2;-1;0;0;0;1;0;3;2;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;4;32;30000;0;8;32;1;1;0;-1;-2;0;0;0;1;0;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;5;4;30000;0;13;32;1;4;0;-1;-1;0;1;0;1;1;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;5;5;30000;0;12;32;1;9;0;-1;-1;0;1;0;1;0;0;2;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;5;13;30000;0;9;32;1;22;0;-2;-2;0;1;0;1;0;3;0;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;5;17;30000;0;8;32;1;22;0;-1;2;0;1;1;1;1;0;3;1 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;5;32;30000;0;8;32;1;20;0;-1;-1;1;1;0;1;1;0;0;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;13;4;30000;0;22;32;1;3;0;-1;1;0;1;0;1;0;1;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;13;5;30000;0;22;32;1;18;0;-1;-1;0;1;1;1;1;0;1;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;13;13;30000;0;21;32;1;30;0;-1;0;1;1;0;1;1;0;3;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;13;17;30000;0;9;32;1;10;0;-2;2;1;1;0;1;1;0;3;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;13;32;30000;0;9;32;1;19;0;-2;2;0;1;1;1;0;3;3;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;17;4;30000;0;41;32;1;30;0;0;-1;0;1;1;1;1;0;0;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;17;5;30000;0;44;32;1;15;0;-2;2;0;1;1;1;0;1;0;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;17;13;30000;0;12;32;1;14;0;0;1;0;1;0;1;0;1;0;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;17;17;30000;0;16;32;1;20;0;1;-1;0;1;1;1;1;2;2;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;17;32;30000;0;2;32;1;1;0;-2;0;0;0;0;1;0;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;24;24;30000;0;15;32;1;1;0;0;1;0;0;0;1;1;3;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;24;26;30000;0;16;32;1;1;0;1;1;1;0;0;1;0;3;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;24;32;30000;0;15;32;1;1;0;0;1;1;0;0;1;0;3;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;26;24;30000;0;15;32;1;1;0;1;1;0;0;1;1;1;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;26;26;30000;0;15;32;1;1;0;-2;1;0;0;1;1;1;3;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;26;32;30000;0;15;32;1;1;0;-2;1;0;0;1;1;1;3;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;32;4;30000;0;17;32;1;19;0;-1;-2;0;1;1;1;1;2;1;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;32;5;30000;0;23;32;1;15;0;-2;0;0;1;0;1;1;3;3;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;32;9;30000;0;26;32;1;2;0;0;-1;1;0;1;1;0;2;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;32;13;30000;0;13;32;1;7;0;-2;2;0;1;1;1;1;2;0;2 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;32;17;30000;0;11;32;1;1;0;-1;1;1;1;1;1;0;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;32;22;30000;0;11;32;1;1;0;-1;1;0;1;1;1;1;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;32;24;30000;0;8;32;1;1;0;-2;1;0;1;0;1;1;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;32;26;30000;0;9;32;1;1;0;-2;1;1;0;0;1;1;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;32;32;30000;0;8;32;1;1;0;-1;1;0;0;0;1;0;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;35;35;35;30000;0;30;35;1;1;0;0;2;1;0;1;1;1;0;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;36;36;36;30000;0;9;2;3;1;0;1;1;1;0;0;1;0;0;1;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;40;40;40;30000;0;8;5;1;1;0;0;1;1;0;0;1;1;1;0;0 -Intel(R) Data Center GPU Max 1550 [0x0bd5];3;45;45;45;30000;0;11;45;1;1;0;0;1;1;0;1;1;0;2;3;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;2;2;2;30000;0;4;2;1;1;1;-2;-1;0;1;1;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;3;3;1;30000;0;6;3;1;1;1;-2;0;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;3;3;3;30000;0;5;3;1;2;1;-2;-2;0;1;1;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;4;4;30000;0;5;4;1;2;1;-1;-1;0;1;1;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;4;5;30000;0;10;4;1;4;1;-2;-1;0;1;0;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;4;7;30000;0;10;4;1;2;1;-2;0;0;0;1;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;4;9;30000;0;9;4;1;1;1;-2;0;0;1;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;4;10;30000;0;9;4;1;4;1;-1;-1;0;0;0;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;4;13;30000;0;8;4;1;1;1;-2;-1;0;0;1;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;4;15;30000;0;8;4;1;1;1;-1;-2;0;1;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;4;17;30000;0;8;4;1;2;1;-2;5;0;1;0;1;0;0;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;4;25;30000;0;8;4;1;1;1;-2;0;0;1;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;4;26;30000;0;8;4;1;1;1;-1;0;0;1;1;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;4;28;30000;0;8;4;1;1;1;-2;-2;0;0;1;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;4;32;30000;0;8;4;1;1;1;-1;-1;0;1;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;4;45;30000;0;8;4;1;1;4;-1;-2;0;1;1;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;5;4;30000;0;10;4;1;3;1;-2;-1;0;0;1;1;0;0;1;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;5;5;30000;0;11;4;1;2;1;-2;4;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;5;7;30000;0;11;4;1;2;1;-2;0;0;0;1;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;5;9;30000;0;9;4;1;4;1;-2;-1;0;0;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;5;13;30000;0;8;4;1;1;1;-1;-1;0;0;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;5;17;30000;0;8;4;1;1;1;-2;0;1;1;1;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;5;25;30000;0;8;4;1;1;1;-1;-1;0;1;1;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;5;26;30000;0;8;4;1;1;5;-1;0;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;5;28;30000;0;8;4;1;1;5;0;-1;0;1;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;5;32;30000;0;8;4;1;1;1;0;-2;0;0;0;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;5;45;30000;0;8;4;1;1;5;-1;-1;0;1;1;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;7;4;30000;0;11;4;1;4;1;-2;-1;0;0;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;7;5;30000;0;11;4;1;4;1;-2;0;1;0;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;7;7;30000;0;12;4;1;2;1;-2;0;0;1;1;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;7;9;30000;0;9;4;1;1;1;-1;0;1;1;0;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;7;13;30000;0;8;4;1;1;1;-1;-2;0;1;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;7;25;30000;0;8;4;1;1;7;-2;0;0;0;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;7;26;30000;0;8;4;1;1;7;-1;0;0;0;1;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;7;28;30000;0;8;4;1;1;7;-1;-2;0;0;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;7;32;30000;0;8;4;1;1;7;-1;-1;0;0;1;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;7;45;30000;0;8;4;1;1;7;-2;-2;0;1;1;1;1;0;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;9;4;30000;0;16;4;1;2;1;1;0;0;0;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;9;5;30000;0;14;4;1;2;1;-1;-1;0;1;1;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;9;7;30000;0;11;4;1;1;1;-1;-2;0;1;0;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;9;9;30000;0;9;4;1;1;1;-2;-2;0;0;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;9;13;30000;0;8;4;1;1;1;-1;-1;0;0;0;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;9;25;30000;0;8;4;1;1;9;-1;0;0;1;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;9;26;30000;0;8;4;1;1;9;-1;-2;0;0;0;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;9;28;30000;0;8;4;1;1;9;-1;-1;0;1;1;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;9;32;30000;0;8;4;1;1;9;-1;0;0;0;1;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;9;45;30000;0;4;4;1;1;9;-1;-1;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;10;4;30000;0;12;4;1;1;1;-1;-1;0;1;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;10;10;30000;0;9;4;1;1;1;-1;-2;0;0;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;10;15;30000;0;8;4;1;1;10;-1;-2;0;1;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;13;4;30000;0;16;4;1;2;1;0;0;0;0;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;13;5;30000;0;14;4;1;4;1;-1;-2;0;1;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;13;7;30000;0;11;4;1;2;1;-1;-1;0;1;1;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;13;9;30000;0;8;4;1;4;1;-2;-2;0;1;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;13;13;30000;0;8;4;1;1;1;-1;-2;0;1;1;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;13;17;30000;0;8;4;1;1;1;-1;-2;1;0;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;13;25;30000;0;8;4;1;1;13;-1;0;0;0;0;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;13;26;30000;0;8;4;1;1;13;-2;-1;0;0;0;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;13;28;30000;0;8;4;1;2;13;-2;1;0;1;0;1;1;2;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;13;32;30000;0;8;4;1;1;1;-2;0;0;1;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;13;45;30000;0;4;4;1;1;13;-1;0;0;1;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;15;4;30000;0;16;4;1;1;1;-2;-2;0;0;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;15;10;30000;0;8;4;1;1;15;-1;0;0;1;1;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;15;15;30000;0;8;4;1;1;15;-1;-1;0;0;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;17;4;30000;0;17;4;1;2;1;1;-2;0;0;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;17;5;30000;0;14;4;1;3;1;1;-1;0;0;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;17;13;30000;0;8;4;1;2;1;1;5;0;0;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;17;17;30000;0;8;4;1;1;1;-1;-2;0;0;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;17;32;30000;0;8;4;1;1;1;1;0;0;0;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;25;4;30000;0;17;4;1;3;1;-2;-1;0;1;0;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;25;5;30000;0;14;4;1;4;1;0;0;0;0;1;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;25;7;30000;0;8;4;1;3;25;-1;-2;0;0;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;25;9;30000;0;8;4;1;1;25;-2;0;1;0;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;25;13;30000;0;9;4;1;1;25;-1;0;0;1;1;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;25;25;30000;0;8;4;1;1;25;-2;0;0;1;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;25;26;30000;0;8;4;1;1;25;-2;0;0;0;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;25;28;30000;0;8;4;1;1;25;-1;0;0;1;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;25;32;30000;0;8;4;1;1;25;1;-2;0;0;1;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;25;45;30000;0;8;4;1;1;25;-1;0;0;0;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;26;4;30000;0;17;4;1;4;1;-2;0;1;1;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;26;5;30000;0;14;4;1;2;26;-1;3;0;0;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;26;7;30000;0;8;4;1;3;26;-1;-1;1;1;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;26;9;30000;0;8;4;1;1;26;0;-2;1;0;1;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;26;13;30000;0;8;4;1;1;26;1;0;0;1;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;26;25;30000;0;8;4;1;1;26;-2;4;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;26;26;30000;0;8;4;1;1;26;-2;-1;0;0;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;26;28;30000;0;8;4;1;1;26;0;-2;1;0;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;26;32;30000;0;8;4;1;1;26;-2;-1;1;0;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;26;45;30000;0;8;4;1;1;26;0;0;0;1;1;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;28;4;30000;0;17;4;1;2;1;-2;-1;1;0;1;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;28;5;30000;0;17;4;1;4;28;-1;-2;0;0;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;28;7;30000;0;8;4;1;3;28;-1;-2;0;1;0;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;28;9;30000;0;8;4;1;1;28;-1;0;0;0;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;28;13;30000;0;8;4;1;1;28;0;-2;1;0;0;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;28;25;30000;0;8;4;1;1;28;0;0;0;0;1;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;28;26;30000;0;8;4;1;1;28;0;-1;1;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;28;28;30000;0;8;4;1;1;28;0;-2;1;1;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;28;32;30000;0;8;4;1;1;28;1;-2;1;1;1;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;28;45;30000;0;8;4;1;1;28;0;-1;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;32;4;30000;0;20;4;1;2;1;0;-1;1;0;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;32;5;30000;0;22;4;1;1;1;0;-1;1;1;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;32;7;30000;0;21;4;1;4;32;-1;0;1;1;0;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;32;9;30000;0;8;4;1;1;32;1;-1;1;1;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;32;13;30000;0;8;4;1;1;1;-1;0;1;1;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;32;17;30000;0;8;4;1;1;1;-2;0;0;1;1;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;32;25;30000;0;8;4;1;1;32;1;-1;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;32;26;30000;0;8;4;1;1;32;1;0;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;32;28;30000;0;8;4;1;1;32;0;-2;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;32;32;30000;0;8;4;1;1;1;0;0;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;32;45;30000;0;4;4;1;1;32;-1;-2;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;45;4;30000;0;15;4;1;2;45;-1;-2;1;1;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;45;5;30000;0;15;4;1;4;45;-2;-2;0;0;1;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;45;7;30000;0;10;4;1;2;45;0;3;0;1;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;45;9;30000;0;15;4;1;2;45;1;-1;0;1;0;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;45;13;30000;0;6;4;1;1;45;1;-1;0;0;0;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;45;25;30000;0;4;4;1;1;45;-1;6;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;45;26;30000;0;4;4;1;1;45;-2;0;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;45;28;30000;0;4;4;1;1;45;0;0;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;45;32;30000;0;4;4;1;1;45;-1;5;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;4;45;45;30000;0;3;4;1;1;45;-2;-1;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;4;4;30000;0;12;5;1;1;1;-1;-1;0;0;1;1;0;2;1;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;4;5;30000;0;13;5;1;1;1;-1;-1;0;1;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;4;7;30000;0;12;5;1;1;1;-1;-2;0;0;1;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;4;9;30000;0;11;5;1;1;1;-2;0;0;1;1;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;4;13;30000;0;9;5;1;1;1;-2;-1;1;0;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;4;17;30000;0;8;5;1;1;1;-1;-1;1;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;4;25;30000;0;8;5;1;1;1;-2;0;0;1;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;4;26;30000;0;8;5;1;1;5;-1;-1;0;1;1;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;4;28;30000;0;8;5;1;1;5;-1;-1;0;0;0;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;4;32;30000;0;8;5;1;1;1;-2;-2;0;1;1;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;4;45;30000;0;8;5;1;1;5;-2;-1;0;1;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;5;4;30000;0;13;5;1;1;1;-2;-1;0;1;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;5;5;30000;0;12;5;1;1;1;-1;-1;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;5;7;30000;0;11;5;1;2;1;0;3;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;5;9;30000;0;11;5;1;1;1;-2;6;0;1;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;5;13;30000;0;8;5;1;1;1;-2;-1;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;5;16;30000;0;8;5;1;1;1;-2;-1;0;0;0;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;5;17;30000;0;8;5;1;1;1;-2;-2;1;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;5;24;30000;0;8;5;1;1;1;-1;-1;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;5;26;30000;0;8;5;1;1;1;-1;-2;0;1;0;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;5;28;30000;0;8;5;1;1;5;-1;-2;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;5;32;30000;0;8;5;1;1;1;-2;-2;0;1;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;7;4;30000;0;13;5;1;1;1;-1;0;0;0;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;7;5;30000;0;12;5;1;1;1;-1;-1;0;0;1;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;7;7;30000;0;11;5;1;1;1;-1;0;0;1;1;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;7;9;30000;0;11;5;1;1;1;-2;-2;0;0;0;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;7;13;30000;0;8;5;1;1;1;-2;-2;0;1;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;9;4;30000;0;17;5;1;4;1;-1;0;1;0;0;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;9;5;30000;0;16;5;1;1;1;-1;-2;0;0;1;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;9;7;30000;0;12;5;1;1;1;1;-1;0;0;1;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;9;9;30000;0;11;5;1;1;1;-1;-1;0;0;1;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;13;4;30000;0;16;5;1;1;1;-2;-2;0;0;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;13;5;30000;0;17;5;1;1;1;-1;-2;1;1;1;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;13;7;30000;0;14;5;1;1;1;-1;0;1;1;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;13;13;30000;0;8;5;1;1;1;-1;-2;1;1;0;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;13;16;30000;0;8;5;1;1;1;-2;0;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;13;17;30000;0;8;5;1;1;1;-1;-1;1;1;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;13;24;30000;0;8;5;1;1;1;-2;4;1;1;0;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;13;26;30000;0;8;5;1;1;1;-1;3;0;0;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;13;32;30000;0;8;5;1;1;1;-1;-2;0;0;0;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;13;45;30000;0;8;5;1;1;13;-1;0;0;1;1;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;14;28;30000;0;8;5;1;1;14;-2;-2;0;0;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;16;5;30000;0;16;5;1;1;1;-2;-2;0;1;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;16;13;30000;0;8;5;1;1;1;-2;0;1;1;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;16;16;30000;0;8;5;1;1;1;-2;-1;1;1;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;16;24;30000;0;8;5;1;1;1;-2;-2;0;1;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;16;26;30000;0;8;5;1;1;1;-2;-1;1;0;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;17;4;30000;0;18;5;1;1;1;1;-1;0;1;0;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;17;5;30000;0;17;5;1;1;1;-1;0;0;1;1;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;17;13;30000;0;8;5;1;1;1;-2;0;1;0;0;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;17;17;30000;0;8;5;1;1;1;-1;-2;0;1;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;17;32;30000;0;8;5;1;1;1;-1;-2;0;0;1;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;24;5;30000;0;22;5;1;1;1;-2;0;0;0;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;24;13;30000;0;17;5;1;1;1;-1;-2;1;1;0;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;24;16;30000;0;17;5;1;1;1;-1;2;1;1;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;24;24;30000;0;8;5;1;1;24;-1;0;1;1;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;24;26;30000;0;8;5;1;1;24;-2;0;1;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;24;32;30000;0;8;5;1;1;24;0;-1;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;25;4;30000;0;17;5;1;3;1;0;0;0;0;1;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;25;5;30000;0;21;5;1;1;25;1;0;1;1;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;25;7;30000;0;14;5;1;1;25;-2;-1;1;0;1;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;25;9;30000;0;8;5;1;1;25;-1;-2;1;0;1;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;25;13;30000;0;8;5;1;1;25;0;-1;0;1;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;25;25;30000;0;8;5;1;1;25;0;-1;1;0;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;25;26;30000;0;8;5;1;1;25;-2;-2;0;0;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;25;28;30000;0;8;5;1;1;25;-1;0;0;0;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;25;32;30000;0;8;5;1;1;25;-1;-2;0;1;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;25;45;30000;0;8;5;1;1;25;-1;0;0;0;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;26;4;30000;0;22;5;1;1;26;1;-2;1;0;1;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;26;5;30000;0;21;5;1;1;1;1;0;1;0;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;26;7;30000;0;17;5;1;1;26;-1;0;1;1;1;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;26;9;30000;0;8;5;1;4;26;-2;-2;1;0;1;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;26;13;30000;0;8;5;1;1;1;1;0;1;1;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;26;16;30000;0;8;5;1;1;1;-2;-1;0;1;1;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;26;24;30000;0;8;5;1;1;26;-1;-2;0;1;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;26;25;30000;0;8;5;1;1;26;-2;-1;0;0;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;26;26;30000;0;8;5;1;1;26;-1;-2;1;1;1;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;26;28;30000;0;8;5;1;1;26;0;-2;1;0;1;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;26;32;30000;0;8;5;1;1;26;-1;0;0;0;1;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;26;45;30000;0;8;5;1;1;26;-2;0;0;0;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;28;4;30000;0;22;5;1;1;28;1;-1;0;0;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;28;5;30000;0;22;5;1;1;28;-2;0;0;0;0;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;28;7;30000;0;17;5;1;1;28;0;-1;1;0;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;28;9;30000;0;17;5;1;1;28;1;-1;1;0;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;28;13;30000;0;8;5;1;1;28;-1;-1;0;0;1;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;28;14;30000;0;8;5;1;1;28;-1;-1;1;1;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;28;25;30000;0;8;5;1;1;28;-1;0;0;1;1;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;28;26;30000;0;8;5;1;1;28;0;-2;0;0;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;28;28;30000;0;8;5;1;1;28;-2;0;1;1;1;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;28;32;30000;0;8;5;1;1;28;-2;-2;1;1;1;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;28;45;30000;0;8;5;1;1;28;1;-2;0;1;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;32;4;30000;0;22;5;1;1;1;0;-2;1;0;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;32;5;30000;0;22;5;1;1;1;-1;-2;1;1;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;32;7;30000;0;22;5;1;1;32;-2;-2;1;0;1;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;32;9;30000;0;22;5;1;1;32;0;-1;1;0;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;32;13;30000;0;8;5;1;1;1;-2;0;0;1;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;32;17;30000;0;8;5;1;1;1;-1;-2;0;1;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;32;24;30000;0;8;5;1;1;32;-1;0;0;0;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;32;25;30000;0;8;5;1;1;32;-1;2;0;1;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;32;26;30000;0;8;5;1;1;32;-1;0;0;0;1;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;32;28;30000;0;8;5;1;1;32;-1;-1;0;1;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;32;32;30000;0;8;5;1;1;1;-1;0;0;0;1;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;32;45;30000;0;8;5;1;1;32;-2;-1;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;45;4;30000;0;17;5;1;3;45;-1;-2;1;0;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;45;5;30000;0;17;5;1;2;45;1;2;1;0;1;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;45;7;30000;0;15;5;1;2;45;-1;4;0;1;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;45;9;30000;0;15;5;1;4;45;-2;-1;0;0;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;45;13;30000;0;8;5;1;3;45;-2;-2;0;1;1;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;45;25;30000;0;5;5;1;1;45;-2;-1;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;45;26;30000;0;6;5;1;1;45;-2;-1;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;45;28;30000;0;5;5;1;1;45;-1;-2;1;0;1;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;45;32;30000;0;4;5;1;1;45;-1;-2;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;5;45;45;30000;0;9;5;1;1;45;-2;-1;0;0;0;1;1;0;2;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;6;6;6;30000;0;9;6;1;3;1;-2;0;0;1;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;6;6;7;30000;0;10;6;1;1;1;-1;-1;1;1;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;6;6;8;30000;0;12;6;1;1;1;-1;-1;1;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;6;7;6;30000;0;14;6;1;1;1;-2;-2;0;1;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;6;7;7;30000;0;11;6;1;1;1;-2;0;1;0;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;6;7;8;30000;0;11;6;1;1;1;-1;-1;0;0;1;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;6;8;6;30000;0;16;6;1;3;1;-2;2;0;1;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;6;8;7;30000;0;16;6;1;1;1;1;0;0;0;1;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;6;8;8;30000;0;16;6;1;1;1;-1;-2;0;1;1;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;4;4;30000;0;16;7;1;1;1;-1;-2;0;1;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;4;5;30000;0;16;7;1;6;1;-2;-2;1;0;1;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;4;7;30000;0;10;7;1;1;1;-1;-2;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;4;9;30000;0;12;7;1;2;1;-2;1;0;1;1;1;0;2;1;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;4;13;30000;0;9;7;1;1;1;-1;0;0;1;0;1;0;2;1;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;4;25;30000;0;8;7;1;1;7;1;-2;1;0;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;4;26;30000;0;8;7;1;1;7;0;-2;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;4;28;30000;0;8;7;1;1;7;1;-2;0;1;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;4;32;30000;0;8;7;1;1;7;1;0;0;0;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;4;45;30000;0;8;7;1;1;7;1;0;0;0;1;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;5;4;30000;0;16;7;1;3;1;-1;4;0;1;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;5;5;30000;0;16;7;1;1;1;-2;0;0;0;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;5;7;30000;0;13;7;1;1;1;-2;0;0;1;1;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;5;9;30000;0;11;7;1;2;1;-1;2;0;1;0;1;0;2;1;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;5;13;30000;0;11;7;1;1;1;0;0;0;1;1;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;5;25;30000;0;8;7;1;1;7;-2;-2;1;0;0;1;1;0;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;5;26;30000;0;8;7;1;1;7;1;0;0;1;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;5;28;30000;0;8;7;1;1;7;-2;0;1;0;0;1;1;2;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;5;32;30000;0;8;7;1;1;7;-1;0;1;1;0;1;1;2;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;5;45;30000;0;8;7;1;1;7;-2;0;0;0;1;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;6;6;30000;0;16;7;1;1;1;-1;-1;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;6;7;30000;0;11;7;1;7;1;-2;0;1;0;1;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;6;8;30000;0;12;7;1;6;1;-1;-2;0;0;1;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;7;4;30000;0;16;7;1;1;1;-1;0;0;0;0;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;7;5;30000;0;17;7;1;1;1;-1;0;0;1;0;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;7;6;30000;0;16;7;1;1;1;-2;-2;1;1;0;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;7;7;30000;0;9;7;1;2;1;1;-2;0;1;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;7;8;30000;0;11;7;1;1;1;-2;-1;1;1;0;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;7;9;30000;0;14;7;1;1;1;-2;-1;0;0;1;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;7;13;30000;0;12;7;1;1;1;-2;-1;0;1;0;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;7;25;30000;0;8;7;1;1;7;-1;-2;0;1;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;7;26;30000;0;8;7;1;1;7;-1;-2;0;1;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;7;28;30000;0;8;7;1;1;7;-1;-2;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;7;32;30000;0;8;7;1;1;7;-1;0;1;0;1;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;7;45;30000;0;8;7;1;1;7;-1;-1;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;8;6;30000;0;16;7;1;1;1;-2;-2;0;1;0;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;8;7;30000;0;16;7;1;1;1;-2;0;0;1;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;8;8;30000;0;16;7;1;2;1;-1;-1;1;1;1;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;9;4;30000;0;16;7;1;1;1;-1;-1;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;9;5;30000;0;18;7;1;1;1;-1;-2;0;0;1;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;9;7;30000;0;17;7;1;1;1;-1;0;0;1;0;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;9;9;30000;0;17;7;1;2;9;-2;5;0;1;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;9;13;30000;0;9;7;1;1;9;-1;-2;1;1;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;9;25;30000;0;9;7;1;3;9;-1;-2;1;1;1;1;0;1;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;9;26;30000;0;8;7;1;5;9;-1;-1;0;1;0;1;1;2;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;9;28;30000;0;8;7;1;1;9;-1;-2;1;0;0;1;1;2;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;9;32;30000;0;8;7;1;1;9;-1;-2;1;1;0;1;1;0;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;9;45;30000;0;8;7;1;1;9;1;0;0;0;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;13;4;30000;0;20;7;1;1;1;-2;-1;0;0;1;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;13;5;30000;0;17;7;1;2;1;-2;1;0;1;1;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;13;7;30000;0;14;7;1;1;1;-2;0;1;1;1;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;13;13;30000;0;9;7;1;1;1;-2;-2;1;1;1;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;32;13;30000;0;21;7;1;5;32;0;-2;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;32;25;30000;0;8;7;1;1;32;0;-1;0;1;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;32;26;30000;0;8;7;1;1;32;-1;-2;0;0;1;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;32;28;30000;0;8;7;1;1;32;-2;-2;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;32;32;30000;0;8;7;1;1;32;0;0;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;32;45;30000;0;15;7;1;1;32;1;0;1;0;0;1;0;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;45;4;30000;0;42;7;1;1;45;-2;-1;1;0;1;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;45;5;30000;0;55;7;1;3;45;-2;-1;1;0;1;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;45;7;30000;0;15;7;1;3;45;1;-1;1;1;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;45;9;30000;0;41;7;1;5;45;0;-2;0;0;1;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;45;13;30000;0;15;7;1;3;45;-1;5;0;1;0;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;45;25;30000;0;15;7;1;1;45;1;0;1;1;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;45;26;30000;0;10;7;1;1;45;0;-2;0;0;0;1;0;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;45;28;30000;0;11;7;1;1;45;-1;-2;1;0;0;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;45;32;30000;0;8;7;1;1;45;-2;0;1;0;1;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;7;45;45;30000;0;9;7;1;1;45;1;0;1;0;0;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;8;6;6;30000;0;16;8;1;6;1;-1;-1;0;0;1;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;8;6;7;30000;0;13;8;1;4;1;0;-2;0;1;1;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;8;6;8;30000;0;11;8;1;5;1;-2;-2;1;0;1;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;8;7;6;30000;0;16;8;1;4;1;-2;-1;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;8;7;7;30000;0;16;8;1;4;1;-2;-2;0;0;1;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;8;7;8;30000;0;16;8;1;1;1;-2;3;0;0;1;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;8;8;6;30000;0;19;8;1;1;1;-2;2;0;1;0;1;0;0;1;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;8;8;7;30000;0;16;8;1;1;1;-1;0;0;0;1;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;8;8;8;30000;0;4;8;1;2;1;-1;-1;0;1;1;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;4;4;30000;0;12;1;4;9;1;-1;-1;0;1;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;4;5;30000;0;16;9;1;1;1;0;0;0;0;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;4;7;30000;0;16;9;1;1;1;-1;0;0;0;1;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;4;9;30000;0;10;9;1;6;1;-1;-2;0;1;0;1;0;2;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;4;13;30000;0;8;9;1;1;1;-1;0;0;0;0;1;0;2;1;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;4;25;30000;0;8;9;1;1;9;-1;-1;0;0;1;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;4;26;30000;0;8;9;1;1;9;-1;0;0;1;1;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;4;28;30000;0;8;9;1;1;9;-1;-2;0;1;0;1;0;0;1;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;4;32;30000;0;8;9;1;1;9;-1;0;0;1;1;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;4;45;30000;0;8;9;1;1;9;-1;0;0;0;0;1;1;2;1;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;5;4;30000;0;16;9;1;1;1;-1;-2;0;0;1;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;5;5;30000;0;16;9;1;1;1;0;-2;0;1;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;5;7;30000;0;16;9;1;1;1;-2;-2;1;0;1;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;5;9;30000;0;11;9;1;1;1;-1;-1;1;0;1;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;5;13;30000;0;11;9;1;1;9;-1;0;0;1;1;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;5;25;30000;0;8;9;1;1;9;-1;0;1;0;0;1;1;0;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;5;26;30000;0;8;9;1;3;9;-1;1;0;0;0;1;1;0;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;5;28;30000;0;8;9;1;1;9;-1;0;0;0;1;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;5;32;30000;0;8;9;1;1;9;-1;-2;0;0;1;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;5;45;30000;0;8;9;1;1;9;-1;0;0;1;0;1;0;0;1;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;7;4;30000;0;17;9;1;1;1;-1;-1;0;1;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;7;5;30000;0;16;9;1;1;1;1;-2;0;1;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;7;7;30000;0;14;9;1;1;1;-2;0;0;0;1;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;7;9;30000;0;11;9;1;5;9;1;-1;0;1;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;7;13;30000;0;9;9;1;5;9;-1;0;0;1;1;1;1;0;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;7;25;30000;0;8;9;1;1;9;-1;-2;0;0;1;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;7;26;30000;0;8;9;1;9;9;-1;0;1;1;0;1;1;1;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;7;28;30000;0;8;9;1;1;9;-1;-1;0;0;1;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;7;32;30000;0;8;9;1;1;9;-1;0;0;0;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;7;45;30000;0;8;9;1;1;9;-1;-2;1;0;1;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;9;4;30000;0;18;9;1;7;1;-1;0;1;0;0;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;9;5;30000;0;18;9;1;1;1;-1;0;0;1;0;1;0;0;1;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;9;7;30000;0;17;9;1;1;9;-1;-1;1;0;0;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;9;9;30000;0;8;9;1;2;1;-1;1;0;1;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;9;13;30000;0;14;9;1;1;9;-1;-1;1;1;0;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;9;16;30000;0;11;9;1;5;0;-1;-2;1;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;9;22;30000;0;8;9;1;3;1;-1;-1;0;1;0;1;1;2;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;9;25;30000;0;8;9;1;1;9;-1;0;1;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;9;26;30000;0;8;9;1;1;9;-1;-2;1;0;1;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;9;28;30000;0;8;9;1;1;9;-1;-2;0;0;0;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;9;32;30000;0;8;9;1;1;1;-1;-2;1;0;1;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;9;45;30000;0;8;9;1;1;9;-1;-2;0;1;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;13;4;30000;0;25;9;1;1;1;-1;-1;1;0;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;13;5;30000;0;22;9;1;1;13;-2;0;0;0;1;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;13;7;30000;0;16;9;1;4;13;-2;1;1;0;0;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;13;9;30000;0;17;9;1;1;13;-1;-2;0;0;0;1;0;0;1;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;13;13;30000;0;14;9;1;8;13;-1;-1;1;1;0;1;1;0;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;13;25;30000;0;8;9;1;1;13;-2;0;1;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;13;26;30000;0;8;9;1;1;13;-1;0;1;1;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;13;28;30000;0;8;9;1;1;13;-1;-2;1;0;1;1;1;0;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;13;32;30000;0;8;9;1;1;13;-1;0;1;1;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;13;45;30000;0;8;9;1;1;13;-2;-2;1;1;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;16;9;30000;0;18;9;1;9;1;-2;-1;1;1;1;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;16;16;30000;0;15;9;1;1;1;-2;0;1;1;1;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;16;22;30000;0;11;9;1;1;1;1;-2;1;1;1;1;1;0;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;22;9;30000;0;17;9;1;6;1;1;0;0;0;0;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;22;16;30000;0;9;9;1;9;1;0;-1;1;1;0;1;0;2;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;22;22;30000;0;8;9;1;5;1;0;1;0;1;0;1;0;1;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;22;32;30000;0;8;9;1;1;1;-2;-1;1;0;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;25;4;30000;0;32;9;1;9;25;-1;-2;1;1;0;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;25;5;30000;0;30;9;1;1;25;-1;0;1;0;1;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;25;7;30000;0;21;9;1;1;25;1;0;1;1;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;25;9;30000;0;17;9;1;9;25;1;-1;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;25;13;30000;0;9;9;1;6;25;0;-1;1;1;0;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;25;25;30000;0;8;9;1;9;25;-2;1;1;0;1;1;1;0;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;25;26;30000;0;8;9;1;1;25;0;-2;1;0;1;1;1;2;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;25;28;30000;0;8;9;1;1;25;-2;-1;1;0;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;25;32;30000;0;8;9;1;1;25;-2;-2;1;1;0;1;1;0;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;25;45;30000;0;15;9;1;1;25;1;0;1;1;1;1;1;0;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;26;4;30000;0;30;9;1;7;26;1;0;1;1;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;26;5;30000;0;27;9;1;8;26;0;-2;1;1;0;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;26;7;30000;0;18;9;1;2;26;-1;1;1;1;0;1;0;1;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;26;9;30000;0;17;9;1;7;26;1;0;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;26;13;30000;0;8;9;1;3;26;-1;0;0;0;1;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;26;25;30000;0;8;9;1;1;26;-1;1;1;0;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;26;26;30000;0;8;9;1;1;26;-2;0;1;1;1;1;1;2;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;26;28;30000;0;8;9;1;1;26;1;-2;1;0;0;1;0;1;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;26;32;30000;0;8;9;1;1;26;-2;-2;1;0;1;1;1;2;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;26;45;30000;0;15;9;1;1;26;0;0;1;1;0;1;1;0;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;28;4;30000;0;33;9;1;1;28;-1;-1;0;0;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;28;5;30000;0;28;9;1;4;28;-2;-2;0;1;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;28;7;30000;0;23;9;1;1;28;-1;-2;1;1;1;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;28;9;30000;0;21;9;1;7;28;-2;-2;0;1;1;1;1;1;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;28;13;30000;0;15;9;1;4;28;0;1;1;1;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;28;25;30000;0;8;9;1;1;28;0;0;0;1;0;1;0;1;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;28;26;30000;0;10;9;1;1;28;-2;0;0;1;1;1;0;0;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;28;28;30000;0;8;9;1;1;28;-1;0;1;1;0;1;0;0;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;28;32;30000;0;15;9;1;1;28;-1;-2;0;0;0;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;28;45;30000;0;15;9;1;1;28;-2;0;0;1;0;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;32;4;30000;0;32;9;1;5;32;0;-1;1;1;1;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;32;5;30000;0;28;9;1;3;32;0;-2;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;32;7;30000;0;28;9;1;9;32;1;-1;1;0;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;32;9;30000;0;22;9;1;9;1;0;-1;1;0;0;1;1;2;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;32;13;30000;0;9;9;1;4;32;0;0;0;0;1;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;32;22;30000;0;8;9;1;1;1;-1;1;1;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;32;25;30000;0;8;9;1;1;32;1;1;1;1;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;32;26;30000;0;8;9;1;1;32;0;1;1;0;1;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;32;28;30000;0;15;9;1;1;32;0;0;0;0;0;1;1;0;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;32;32;30000;0;15;9;1;1;1;-2;0;1;0;0;1;1;0;2;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;32;45;30000;0;15;9;1;1;32;1;0;0;1;0;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;45;32;30000;0;10;9;1;1;45;1;0;1;0;0;1;0;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;9;45;45;30000;0;9;9;1;1;45;1;-2;1;1;1;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;10;4;4;30000;0;16;10;1;1;1;-1;-1;0;0;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;10;4;10;30000;0;12;10;1;1;1;-1;-2;0;0;1;1;0;2;1;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;10;4;15;30000;0;8;10;1;3;10;-1;1;0;1;0;1;1;0;1;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;10;10;4;30000;0;20;10;1;4;1;-1;0;1;1;0;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;10;10;10;30000;0;8;10;1;2;1;-1;-2;0;1;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;10;10;15;30000;0;8;10;1;1;10;-1;0;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;10;15;4;30000;0;22;10;1;1;15;-1;0;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;10;15;10;30000;0;17;10;1;9;15;-1;-2;0;0;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;10;15;15;30000;0;12;10;1;2;15;-2;0;0;1;0;1;0;0;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;12;12;12;30000;0;8;12;1;12;12;-2;-1;1;1;1;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;4;4;30000;0;16;13;1;1;1;-1;-1;0;1;1;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;4;5;30000;0;16;13;1;1;1;-1;-1;0;1;1;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;4;7;30000;0;11;13;1;7;1;-2;-2;0;1;0;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;4;9;30000;0;9;13;1;4;1;-1;1;0;0;1;1;0;2;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;4;13;30000;0;9;13;1;2;1;-2;1;1;1;1;1;0;0;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;4;17;30000;0;8;13;1;13;1;-1;-1;0;0;1;1;1;0;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;4;25;30000;0;8;13;1;1;13;-2;-1;1;0;1;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;4;26;30000;0;8;13;1;1;13;-1;-1;0;1;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;4;28;30000;0;8;13;1;1;13;-2;-1;1;1;1;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;4;32;30000;0;8;13;1;11;1;-2;0;0;1;1;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;4;45;30000;0;8;13;1;1;13;-1;-1;1;0;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;5;4;30000;0;16;13;1;1;1;-2;0;0;0;1;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;5;5;30000;0;16;13;1;1;1;-1;-2;0;1;1;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;5;7;30000;0;13;13;1;2;1;-2;-1;1;0;1;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;5;9;30000;0;11;13;1;4;13;-1;-1;0;0;0;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;5;13;30000;0;8;13;1;6;1;-1;-2;0;1;0;1;1;2;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;5;16;30000;0;8;13;1;10;1;-2;-1;1;1;1;1;0;0;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;5;17;30000;0;8;13;1;7;1;-2;-2;0;1;0;1;1;0;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;5;24;30000;0;8;13;1;11;1;-1;0;0;1;1;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;5;25;30000;0;8;13;1;1;13;-2;-1;1;1;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;5;26;30000;0;8;13;1;10;1;-1;-2;0;0;0;1;0;0;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;5;28;30000;0;8;13;1;1;13;-2;-1;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;5;32;30000;0;8;13;1;1;1;-2;0;0;1;0;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;5;45;30000;0;8;13;1;1;13;-2;0;0;1;1;1;0;0;1;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;7;4;30000;0;17;13;1;1;1;-1;0;1;1;1;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;7;5;30000;0;17;13;1;1;1;-1;0;0;1;1;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;7;7;30000;0;14;13;1;10;1;-1;-1;0;1;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;7;9;30000;0;12;13;1;11;13;-2;-1;1;0;1;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;7;13;30000;0;9;13;1;6;1;-1;-1;1;1;1;1;0;0;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;7;25;30000;0;8;13;1;1;13;-2;-1;1;0;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;7;26;30000;0;8;13;1;1;13;-2;-2;1;0;1;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;7;28;30000;0;8;13;1;1;13;-2;-1;0;0;1;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;7;32;30000;0;8;13;1;1;13;0;-2;1;1;1;1;0;0;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;7;45;30000;0;8;13;1;1;13;1;-2;0;0;0;1;1;0;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;9;4;30000;0;19;13;1;1;1;-1;-1;1;0;1;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;9;5;30000;0;17;13;1;1;13;-1;-1;0;0;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;9;7;30000;0;17;13;1;13;13;-1;-1;1;0;1;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;9;9;30000;0;14;13;1;10;13;-2;-1;1;1;1;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;9;13;30000;0;8;13;1;1;13;-1;-1;1;0;1;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;9;25;30000;0;8;13;1;1;13;-1;-1;1;1;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;9;26;30000;0;8;13;1;1;13;-2;0;1;1;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;9;28;30000;0;8;13;1;1;13;-2;-1;0;1;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;9;32;30000;0;8;13;1;1;13;-2;0;1;0;0;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;9;45;30000;0;8;13;1;1;13;0;-2;0;1;1;1;1;2;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;13;4;30000;0;23;13;1;1;1;-2;-2;1;0;1;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;13;5;30000;0;24;13;1;1;1;-2;-2;1;1;1;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;13;7;30000;0;22;13;1;1;1;-2;-2;1;0;1;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;13;9;30000;0;18;13;1;1;13;-1;-1;1;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;13;13;30000;0;8;13;1;4;1;-1;-2;0;1;1;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;13;14;30000;0;21;13;1;1;13;-1;-2;1;0;0;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;13;17;30000;0;8;13;1;1;1;-1;-1;1;1;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;13;24;30000;0;8;13;1;1;13;-1;-2;1;1;1;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;13;25;30000;0;8;13;1;1;13;-1;0;1;0;1;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;13;26;30000;0;9;13;1;1;13;-1;-1;1;1;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;13;28;30000;0;8;13;1;1;13;-1;-1;1;1;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;13;32;30000;0;8;13;1;1;1;-1;0;1;0;0;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;13;45;30000;0;8;13;1;1;13;-2;0;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;14;13;30000;0;15;13;1;2;14;-1;-1;1;0;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;14;14;30000;0;13;13;1;2;14;-1;1;0;0;1;1;1;2;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;14;25;30000;0;8;13;1;1;14;-2;-1;1;1;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;14;26;30000;0;8;13;1;1;14;-2;0;1;0;1;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;14;32;30000;0;8;13;1;1;14;-2;-2;1;0;1;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;16;5;30000;0;20;13;1;9;1;-1;0;1;0;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;17;4;30000;0;19;13;1;11;1;-1;-1;1;1;0;1;1;2;1;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;17;5;30000;0;19;13;1;10;1;0;-1;1;1;0;1;0;1;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;17;13;30000;0;9;13;1;9;1;1;-1;1;1;0;1;1;2;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;17;17;30000;0;8;13;1;1;1;-2;1;1;0;1;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;17;32;30000;0;8;13;1;1;1;1;-2;1;0;0;1;1;2;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;24;5;30000;0;22;13;1;5;1;1;-1;1;1;0;1;0;1;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;24;13;30000;0;8;13;1;8;24;-1;-1;0;0;0;1;0;1;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;24;24;30000;0;8;13;1;1;24;1;1;1;0;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;24;26;30000;0;15;13;1;1;24;1;0;0;1;0;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;24;32;30000;0;16;13;1;1;24;1;0;1;0;1;1;0;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;25;4;30000;0;24;13;1;4;25;-2;1;1;1;0;1;0;2;1;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;25;5;30000;0;22;13;1;3;25;0;-1;1;1;1;1;0;1;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;25;7;30000;0;15;8;1;13;25;-2;5;0;1;1;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;25;9;30000;0;15;8;1;4;25;-2;6;0;0;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;25;13;30000;0;8;13;1;7;25;-2;-1;1;1;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;25;14;30000;0;15;8;1;7;25;0;1;1;1;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;25;25;30000;0;10;8;1;3;25;1;3;0;1;1;1;0;1;0;1;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;25;26;30000;0;15;13;1;1;25;1;-2;1;1;0;1;1;2;2;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;25;28;30000;0;15;8;1;1;25;-1;2;0;1;1;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;25;32;30000;0;5;8;1;1;25;-1;0;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;25;45;30000;0;15;13;1;1;25;0;-2;1;0;1;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;26;4;30000;0;15;8;1;11;26;0;6;0;0;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;26;5;30000;0;23;13;1;13;1;0;-2;1;0;0;1;0;1;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;26;7;30000;0;22;13;1;13;26;0;-2;1;1;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;26;9;30000;0;16;13;1;11;26;-1;-1;1;0;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;26;13;30000;0;8;13;1;13;26;0;0;0;1;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;26;14;30000;0;8;13;1;11;26;-2;-2;1;1;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;26;24;30000;0;15;13;1;1;26;-1;-2;0;1;0;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;26;25;30000;0;15;13;1;1;26;-1;0;1;0;0;1;0;0;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;26;26;30000;0;15;13;1;1;26;-1;0;0;1;1;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;26;28;30000;0;16;13;1;1;26;-2;-2;0;0;1;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;26;32;30000;0;15;13;1;1;26;0;-2;1;0;0;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;26;45;30000;0;15;13;1;1;26;1;-2;1;0;1;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;28;4;30000;0;27;13;1;4;28;-1;-1;1;0;0;1;1;2;1;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;28;5;30000;0;19;13;1;9;28;-1;-2;1;0;0;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;28;7;30000;0;23;13;1;10;28;-1;-2;1;0;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;28;9;30000;0;17;13;1;10;28;1;-1;1;1;1;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;28;13;30000;0;8;13;1;13;28;0;-1;0;0;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;28;25;30000;0;16;13;1;1;28;1;0;1;0;0;1;0;2;2;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;28;26;30000;0;16;13;1;1;28;-1;-2;1;1;0;1;0;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;28;28;30000;0;15;13;1;1;28;-1;-2;0;1;0;1;1;2;2;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;28;32;30000;0;15;13;1;1;28;1;0;0;0;1;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;28;45;30000;0;15;13;1;1;28;-1;-2;1;1;0;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;32;4;30000;0;27;13;1;11;1;-2;-1;1;0;0;1;1;0;1;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;32;5;30000;0;23;13;1;9;1;0;-1;0;1;0;1;0;1;1;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;32;7;30000;0;25;13;1;6;32;0;-1;1;1;1;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;32;9;30000;0;18;13;1;10;32;0;-2;1;1;1;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;32;13;30000;0;10;13;1;1;0;1;1;1;1;1;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;32;14;30000;0;8;13;1;10;32;-2;-1;0;1;0;1;0;1;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;32;17;30000;0;8;13;1;1;1;-1;1;1;1;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;32;24;30000;0;16;13;1;1;32;-2;-2;1;1;0;1;0;2;2;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;32;25;30000;0;15;13;1;1;32;1;-2;1;0;0;1;0;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;32;26;30000;0;15;13;1;1;32;-1;0;1;1;1;1;0;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;32;28;30000;0;16;13;1;1;32;-1;-2;1;0;1;1;0;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;32;32;30000;0;15;13;1;1;1;0;0;1;1;1;1;0;0;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;32;45;30000;0;15;13;1;1;32;-2;-2;1;1;0;1;1;0;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;45;4;30000;0;26;13;1;1;45;-2;1;1;0;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;45;5;30000;0;32;8;1;4;45;1;-1;0;1;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;45;7;30000;0;35;13;1;5;45;-2;-2;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;45;9;30000;0;28;13;1;8;45;1;0;1;0;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;45;13;30000;0;15;13;1;11;45;1;-2;0;1;0;1;0;1;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;45;25;30000;0;17;8;1;9;45;0;1;1;0;1;1;0;1;0;1;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;45;26;30000;0;30;13;1;1;45;-1;-2;1;0;0;1;0;2;2;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;45;28;30000;0;10;8;1;6;45;-1;-1;0;1;0;1;0;1;2;1;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;45;32;30000;0;10;8;1;3;45;-1;0;0;1;0;1;1;0;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;13;45;45;30000;0;30;13;1;1;45;-2;0;1;1;1;1;0;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;14;5;28;30000;0;8;14;1;9;14;-2;0;0;0;0;1;1;2;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;14;13;13;30000;0;8;14;1;7;14;-2;-1;0;0;0;1;0;0;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;14;13;14;30000;0;8;14;1;1;14;-1;0;1;1;1;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;14;13;25;30000;0;8;14;1;1;14;-2;-2;1;1;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;14;13;26;30000;0;8;14;1;1;14;-1;-1;0;0;1;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;14;13;32;30000;0;8;14;1;1;14;-2;-1;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;14;14;13;30000;0;22;14;1;1;14;-2;-1;1;1;0;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;14;14;14;30000;0;8;14;1;5;14;-1;-1;0;1;0;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;14;14;16;30000;0;21;14;1;1;14;-1;-1;1;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;14;14;25;30000;0;8;14;1;1;14;-2;-1;0;1;1;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;14;14;26;30000;0;8;14;1;1;14;-1;-2;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;14;14;28;30000;0;8;14;1;1;14;-2;0;1;1;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;14;14;29;30000;0;8;14;1;1;14;-2;-2;1;1;0;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;14;14;32;30000;0;8;14;1;1;14;-2;-1;1;1;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;14;16;14;30000;0;18;14;1;11;16;-2;0;1;0;1;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;14;16;16;30000;0;17;14;1;4;16;-1;-1;1;0;1;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;14;16;29;30000;0;8;14;1;1;16;-2;-2;0;1;1;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;14;25;13;30000;0;8;14;1;1;25;1;1;0;1;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;14;25;14;30000;0;8;14;1;13;25;-2;0;0;0;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;14;25;25;30000;0;15;14;1;1;25;1;-1;0;1;0;1;0;0;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;14;25;26;30000;0;15;8;1;1;25;1;3;1;0;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;14;25;32;30000;0;10;14;1;1;25;-1;1;1;0;1;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;14;26;13;30000;0;21;14;1;13;26;0;-2;0;1;0;1;1;2;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;14;26;14;30000;0;8;14;1;9;26;1;-1;0;0;0;1;0;1;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;14;26;25;30000;0;8;14;1;1;26;0;1;0;0;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;14;26;26;30000;0;8;14;1;1;26;-2;1;1;0;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;14;26;32;30000;0;8;14;1;1;26;-2;1;0;0;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;14;28;5;30000;0;32;14;1;13;28;-2;0;1;1;1;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;14;28;14;30000;0;8;14;1;9;28;-2;0;0;0;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;14;28;28;30000;0;15;14;1;1;28;-1;0;0;0;0;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;14;29;14;30000;0;10;14;1;1;29;0;1;0;1;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;14;29;16;30000;0;9;14;1;9;29;1;1;0;1;0;1;1;1;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;14;29;29;30000;0;13;14;1;1;29;1;1;1;0;1;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;14;29;32;30000;0;16;14;1;1;29;1;-1;1;0;1;1;0;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;14;32;13;30000;0;8;14;1;8;32;0;-1;0;0;0;1;0;1;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;14;32;14;30000;0;13;14;1;12;32;-1;-2;0;1;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;14;32;25;30000;0;8;14;1;1;32;-2;1;1;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;14;32;26;30000;0;8;14;1;1;32;-2;1;0;1;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;14;32;29;30000;0;16;14;1;1;32;1;-2;0;1;0;1;0;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;14;32;32;30000;0;16;14;1;1;32;0;-1;1;1;1;1;0;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;15;4;4;30000;0;16;15;1;1;1;-2;-1;0;1;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;15;4;10;30000;0;11;15;1;1;15;-1;-1;1;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;15;4;15;30000;0;8;15;1;1;15;-2;0;1;0;1;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;15;10;4;30000;0;17;15;1;6;15;-1;0;1;0;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;15;10;10;30000;0;11;15;1;1;15;-2;-1;1;0;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;15;10;15;30000;0;8;15;1;8;15;-1;0;1;0;0;1;0;1;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;15;15;4;30000;0;28;15;1;1;15;-1;-1;1;0;0;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;15;15;10;30000;0;17;15;1;15;15;-1;0;1;0;1;1;1;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;15;15;15;30000;0;8;15;1;8;1;-1;-2;0;1;0;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;5;5;30000;0;16;16;1;10;1;-1;0;0;1;1;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;5;13;30000;0;8;8;1;15;1;-1;0;0;0;0;1;1;2;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;5;16;30000;0;8;16;1;7;1;-2;-1;0;1;0;1;0;0;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;5;24;30000;0;8;16;1;4;1;-1;-1;0;0;0;1;1;0;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;5;26;30000;0;8;16;1;14;1;-1;-2;1;1;0;1;0;0;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;7;3;30000;0;24;16;1;7;1;-1;1;0;0;1;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;9;9;30000;0;15;16;1;2;1;-1;-2;1;1;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;9;16;30000;0;8;16;1;1;1;-1;-2;1;1;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;9;22;30000;0;8;16;1;1;1;-1;0;0;1;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;13;5;30000;0;22;16;1;8;1;-1;-1;1;1;0;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;14;14;30000;0;14;16;1;1;16;-2;-1;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;14;16;30000;0;12;16;1;1;16;-2;0;1;0;0;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;14;29;30000;0;8;16;1;1;16;-1;0;1;0;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;16;5;30000;0;32;16;1;1;1;-1;0;1;0;1;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;16;9;30000;0;25;16;1;1;1;-1;-2;1;1;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;16;14;30000;0;27;16;1;1;16;-1;-2;1;1;1;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;16;16;30000;0;8;16;1;3;1;-2;1;0;1;0;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;16;22;30000;0;21;16;1;1;1;-2;0;1;0;1;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;16;29;30000;0;8;16;1;1;16;-2;0;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;16;55;30000;0;8;16;1;1;16;-2;0;1;1;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;22;9;30000;0;21;16;1;9;1;-2;-1;1;1;1;1;1;0;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;22;16;30000;0;8;16;1;1;1;-1;1;1;0;1;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;22;22;30000;0;8;16;1;1;1;0;1;1;1;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;24;5;30000;0;22;16;1;13;1;-2;-2;1;0;1;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;26;5;30000;0;22;16;1;6;1;1;-1;1;1;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;29;14;30000;0;41;16;1;11;29;-2;-1;0;0;0;1;1;2;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;29;16;30000;0;15;16;1;2;29;0;2;0;1;1;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;29;29;30000;0;16;16;1;1;29;1;0;1;0;1;1;1;0;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;29;55;30000;0;15;16;1;1;29;1;0;0;1;0;1;0;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;55;16;30000;0;32;16;1;1;55;1;-1;1;1;1;1;0;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;55;29;30000;0;30;16;1;1;55;-1;0;1;0;0;1;1;2;2;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;16;55;55;30000;0;15;16;1;1;55;1;1;1;1;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;1;1;30000;0;15;17;1;1;17;1;1;0;1;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;4;4;30000;0;16;17;1;1;1;-1;-1;0;0;1;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;4;5;30000;0;17;17;1;3;1;-1;-2;0;1;0;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;4;13;30000;0;9;17;1;1;1;-2;0;0;1;1;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;4;17;30000;0;8;17;1;1;1;-2;-2;0;1;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;4;32;30000;0;8;17;1;1;1;-1;-2;0;1;1;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;5;4;30000;0;16;17;1;1;1;-2;-2;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;5;5;30000;0;16;17;1;12;1;-2;-2;0;1;0;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;5;13;30000;0;8;17;1;4;1;-1;-2;0;1;1;1;0;0;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;5;17;30000;0;8;17;1;2;1;-2;-1;0;0;0;1;1;0;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;5;32;30000;0;8;17;1;1;1;-1;0;0;1;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;13;4;30000;0;19;17;1;1;1;-1;0;1;0;0;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;13;5;30000;0;22;17;1;3;1;-2;1;1;0;0;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;13;13;30000;0;14;17;1;1;1;-1;0;1;1;1;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;13;17;30000;0;14;17;1;1;1;-2;-2;1;0;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;13;32;30000;0;8;17;1;1;1;-1;0;1;1;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;17;4;30000;0;21;17;1;6;1;-2;1;0;0;1;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;17;5;30000;0;17;17;1;10;1;-2;-1;0;1;0;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;17;13;30000;0;8;17;1;1;1;0;1;1;1;1;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;17;17;30000;0;8;17;1;4;1;-1;-1;0;1;1;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;17;32;30000;0;17;17;1;1;1;0;-2;1;1;0;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;17;35;30000;0;15;17;1;1;1;-2;-2;1;1;1;1;0;0;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;32;4;30000;0;36;17;1;10;1;-2;-1;0;0;0;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;32;5;30000;0;28;17;1;8;1;-2;1;0;0;1;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;32;13;30000;0;11;17;1;1;0;-2;1;1;0;1;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;32;17;30000;0;27;17;1;1;1;-1;0;0;0;0;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;32;32;30000;0;16;17;1;1;1;1;0;1;1;0;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;32;35;30000;0;15;17;1;1;1;0;0;0;0;0;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;35;17;30000;0;30;17;1;1;1;-2;-2;1;0;1;1;0;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;35;32;30000;0;30;17;1;1;1;1;-2;0;1;0;1;1;0;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;17;35;35;30000;0;30;17;1;1;1;0;-2;1;1;1;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;20;20;20;30000;0;8;20;1;1;1;-1;1;0;1;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;22;9;9;30000;0;14;22;1;1;1;-1;-1;1;1;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;22;9;16;30000;0;8;22;1;1;1;-1;-2;1;1;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;22;9;22;30000;0;8;22;1;1;1;-1;0;0;0;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;22;9;32;30000;0;8;22;1;1;1;-1;-2;1;0;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;22;16;9;30000;0;22;22;1;1;1;-1;-2;1;1;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;22;16;16;30000;0;15;22;1;1;1;-1;0;1;0;1;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;22;16;22;30000;0;8;22;1;1;1;-2;-2;1;1;1;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;22;22;9;30000;0;13;22;1;1;1;-2;1;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;22;22;16;30000;0;8;22;1;1;1;-2;1;0;1;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;22;22;22;30000;0;15;22;1;1;1;-2;-1;0;0;0;1;0;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;22;22;32;30000;0;15;22;1;1;1;-1;-2;0;1;1;1;0;0;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;22;32;9;30000;0;41;22;1;10;1;1;-2;0;1;0;1;0;1;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;22;32;22;30000;0;17;22;1;1;1;-2;-1;0;1;1;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;22;32;32;30000;0;16;22;1;1;1;-1;-1;1;0;0;1;0;0;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;23;23;23;30000;0;15;23;1;1;1;-1;-1;0;0;0;1;0;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;24;5;5;30000;0;17;8;1;21;1;-1;0;1;0;0;1;1;2;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;24;5;13;30000;0;8;8;1;17;1;-1;3;1;1;0;1;0;2;1;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;24;5;16;30000;0;8;8;1;7;1;-1;4;1;1;0;1;0;2;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;24;5;24;30000;0;8;8;1;1;24;0;-2;1;1;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;24;5;26;30000;0;6;8;1;19;24;0;0;0;0;0;1;0;0;1;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;24;5;32;30000;0;1;8;1;6;24;-2;1;0;0;0;0;0;2;1;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;24;13;5;30000;0;20;24;1;24;1;-2;-2;1;1;1;1;0;0;1;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;24;13;13;30000;0;15;8;1;17;24;1;3;0;0;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;24;13;24;30000;0;6;8;1;1;24;-1;4;1;1;1;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;24;13;26;30000;0;17;24;1;1;24;-1;-1;0;0;1;1;0;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;24;13;32;30000;0;9;8;1;1;24;1;-2;1;0;0;1;0;2;2;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;24;16;5;30000;0;24;24;1;8;1;-2;-2;1;1;0;1;0;0;1;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;24;24;5;30000;0;32;8;1;18;24;-1;3;1;1;1;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;24;24;13;30000;0;15;24;1;11;24;0;1;0;1;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;24;24;24;30000;0;15;24;1;1;1;-2;-1;0;1;0;1;1;0;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;24;24;26;30000;0;16;24;1;1;1;0;-1;0;1;0;1;0;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;24;24;32;30000;0;15;24;1;1;1;-1;-1;1;0;1;1;0;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;24;26;5;30000;0;32;8;1;16;26;1;4;0;1;0;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;24;26;13;30000;0;13;8;1;23;26;-2;5;0;1;0;1;1;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;24;26;24;30000;0;10;8;1;12;1;-1;0;0;1;0;1;0;1;2;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;24;26;26;30000;0;16;24;1;1;26;-2;-1;0;0;0;1;0;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;24;26;32;30000;0;15;24;1;1;1;0;-1;1;0;0;1;0;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;24;32;5;30000;0;32;8;1;19;32;1;4;0;0;0;1;1;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;24;32;13;30000;0;32;8;1;8;32;0;-2;0;1;0;1;1;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;24;32;24;30000;0;17;24;1;1;1;1;-1;1;1;1;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;24;32;26;30000;0;18;8;1;7;32;1;-1;0;1;1;1;0;1;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;24;32;32;30000;0;15;24;1;1;1;-1;-1;1;1;0;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;4;4;30000;0;16;25;1;1;1;-2;-1;0;1;0;1;0;0;1;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;4;5;30000;0;11;8;1;11;1;-1;3;1;0;1;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;4;7;30000;0;9;8;1;24;25;-1;3;1;0;1;1;0;0;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;4;9;30000;0;8;8;1;23;25;0;3;0;0;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;4;13;30000;0;8;25;1;9;25;0;-1;0;1;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;4;25;30000;0;10;8;1;13;25;-2;0;0;1;1;1;0;2;1;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;4;26;30000;0;8;8;1;1;25;1;0;0;1;1;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;4;28;30000;0;8;8;1;1;25;1;1;0;1;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;4;32;30000;0;8;8;1;1;25;0;4;0;0;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;4;45;30000;0;8;8;1;1;25;0;4;0;0;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;5;4;30000;0;16;25;1;23;1;-2;0;1;0;0;1;1;0;1;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;5;5;30000;0;9;8;1;16;25;-1;5;0;0;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;5;7;30000;0;8;8;1;13;25;-1;3;0;1;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;5;9;30000;0;9;8;1;2;25;-1;4;0;0;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;5;13;30000;0;8;8;1;17;25;-1;4;1;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;5;25;30000;0;4;8;1;14;25;-1;0;0;0;1;1;0;2;1;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;5;26;30000;0;8;8;1;1;25;0;3;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;5;28;30000;0;8;8;1;1;25;-1;3;0;1;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;5;32;30000;0;9;8;1;2;25;-1;4;0;0;1;1;0;0;1;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;5;45;30000;0;23;8;1;19;25;-1;0;0;0;0;1;1;0;1;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;7;4;30000;0;11;8;1;22;25;-1;1;0;1;0;1;1;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;7;5;30000;0;11;8;1;2;25;-1;-1;0;0;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;7;7;30000;0;8;8;1;23;25;1;3;0;0;0;1;0;2;1;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;7;9;30000;0;10;8;1;1;25;-2;6;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;7;13;30000;0;8;8;1;12;25;-1;-1;1;0;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;7;25;30000;0;10;8;1;4;25;-1;1;0;0;1;1;0;2;1;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;7;26;30000;0;8;25;1;2;25;-2;4;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;7;28;30000;0;10;8;1;6;25;-2;1;0;1;1;1;0;2;1;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;7;32;30000;0;2;8;1;1;25;0;5;1;0;1;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;7;45;30000;0;21;8;1;18;25;0;0;1;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;9;4;30000;0;15;8;1;18;25;-2;4;0;1;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;9;5;30000;0;10;8;1;18;25;0;-2;0;0;1;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;9;7;30000;0;15;8;1;3;25;0;-1;0;0;1;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;9;9;30000;0;15;8;1;19;25;-2;3;0;0;1;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;9;13;30000;0;10;8;1;14;25;1;5;1;1;1;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;9;25;30000;0;7;8;1;1;25;0;1;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;9;26;30000;0;3;8;1;1;25;-1;4;1;0;1;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;9;28;30000;0;3;8;1;1;25;-2;0;1;1;1;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;9;32;30000;0;8;16;1;1;25;-1;2;0;1;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;9;45;30000;0;3;8;1;1;25;-1;0;0;1;1;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;13;4;30000;0;15;8;1;8;25;-2;5;1;0;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;13;5;30000;0;15;8;1;6;25;-2;0;0;1;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;13;7;30000;0;15;8;1;14;25;-1;-1;1;0;1;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;13;9;30000;0;15;8;1;4;25;-2;1;0;1;1;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;13;13;30000;0;15;8;1;18;25;-2;4;1;1;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;13;14;30000;0;8;25;1;10;25;1;1;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;13;25;30000;0;5;8;1;1;25;1;4;1;1;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;13;26;30000;0;16;8;1;1;25;0;0;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;13;28;30000;0;8;16;1;1;25;0;3;1;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;13;32;30000;0;8;8;1;1;25;-2;0;0;1;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;13;45;30000;0;15;25;1;1;25;0;-1;0;1;0;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;14;13;30000;0;8;25;1;10;25;1;1;0;1;1;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;14;14;30000;0;8;25;1;12;25;-2;-1;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;14;25;30000;0;15;25;1;1;25;-1;-1;1;1;1;1;1;0;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;14;26;30000;0;15;25;1;1;25;0;-1;1;0;0;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;14;32;30000;0;16;25;1;1;25;1;-1;0;1;0;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;25;4;30000;0;30;8;1;17;25;0;3;0;1;0;1;1;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;25;5;30000;0;24;8;1;23;25;0;4;0;0;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;25;7;30000;0;30;8;1;15;25;-2;0;0;1;1;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;25;9;30000;0;30;8;1;20;25;1;3;0;1;1;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;25;13;30000;0;15;25;1;1;25;0;-1;0;0;1;1;0;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;25;14;30000;0;17;25;1;1;25;-1;-1;1;1;0;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;25;25;30000;0;16;25;1;1;1;-2;-1;0;0;0;1;0;0;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;25;26;30000;0;15;25;1;1;25;-1;-1;0;1;1;1;1;0;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;25;28;30000;0;15;25;1;1;25;0;-1;1;1;1;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;25;32;30000;0;16;25;1;1;25;-1;-1;1;1;1;1;0;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;25;45;30000;0;8;25;1;1;25;-1;1;0;1;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;26;4;30000;0;30;8;1;20;26;-1;3;0;0;0;1;1;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;26;5;30000;0;30;8;1;2;26;-2;1;0;0;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;26;7;30000;0;30;8;1;18;26;-1;3;0;1;1;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;26;9;30000;0;30;8;1;10;26;0;4;0;1;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;26;13;30000;0;16;25;1;1;26;1;-1;1;0;0;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;26;14;30000;0;17;25;1;1;26;1;-1;0;1;0;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;26;25;30000;0;15;25;1;1;26;1;0;1;1;0;1;1;0;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;26;26;30000;0;15;25;1;1;26;-1;-1;1;1;0;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;26;28;30000;0;6;8;1;19;26;1;4;0;1;1;1;0;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;26;32;30000;0;16;25;1;1;26;0;0;1;0;0;1;0;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;26;45;30000;0;8;25;1;1;26;-2;1;0;0;1;1;1;1;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;28;4;30000;0;30;8;1;17;28;-1;6;0;1;0;1;1;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;28;5;30000;0;14;8;1;17;28;1;3;0;0;1;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;28;7;30000;0;30;8;1;23;28;-2;3;1;1;1;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;28;9;30000;0;8;25;1;1;28;-2;1;0;1;0;1;0;1;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;28;13;30000;0;15;25;1;1;28;-1;-1;1;0;1;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;28;25;30000;0;15;25;1;1;28;0;0;0;0;1;1;1;0;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;28;26;30000;0;16;25;1;1;28;-2;-1;1;0;1;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;28;28;30000;0;16;25;1;1;28;-2;-1;0;0;0;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;28;32;30000;0;16;25;1;1;28;0;0;0;1;1;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;28;45;30000;0;17;25;1;1;28;-1;0;1;1;1;1;0;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;32;4;30000;0;49;25;1;4;32;1;4;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;32;5;30000;0;8;25;1;1;32;-1;-1;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;32;7;30000;0;32;25;1;1;32;1;4;0;0;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;32;9;30000;0;62;25;1;2;32;0;1;0;1;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;32;13;30000;0;51;25;1;8;32;1;4;0;1;0;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;32;14;30000;0;32;25;1;9;32;-1;0;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;32;25;30000;0;8;25;1;1;32;-1;1;0;1;0;1;0;1;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;32;26;30000;0;8;25;1;1;32;-2;1;0;1;0;1;0;1;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;32;28;30000;0;8;25;1;1;32;-2;1;0;0;0;1;0;1;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;32;32;30000;0;4;25;1;1;32;-1;1;0;0;0;1;0;1;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;32;45;30000;0;8;25;1;1;32;-1;1;0;1;0;1;0;1;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;45;4;30000;0;35;25;1;9;45;-2;4;0;1;0;1;0;0;1;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;45;5;30000;0;25;25;1;9;45;-2;3;0;0;0;1;0;0;1;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;45;7;30000;0;16;25;1;12;45;1;-1;1;0;0;1;1;0;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;45;9;30000;0;17;25;1;9;45;0;1;1;1;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;45;13;30000;0;31;25;1;1;45;-2;-1;1;0;0;1;0;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;45;25;30000;0;30;25;1;1;45;-1;-1;0;0;1;1;0;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;45;26;30000;0;5;8;1;1;45;0;2;0;0;0;1;0;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;45;28;30000;0;7;8;1;1;45;-2;2;0;0;1;1;0;2;2;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;45;32;30000;0;15;25;1;1;45;1;-1;1;0;0;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;25;45;45;30000;0;10;25;1;1;45;0;1;1;0;0;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;4;4;30000;0;16;26;1;6;1;-1;-2;1;0;1;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;4;5;30000;0;14;26;1;2;26;1;3;0;0;1;1;1;2;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;4;7;30000;0;9;26;1;3;26;0;4;1;1;1;1;0;0;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;4;9;30000;0;8;26;1;22;26;0;0;0;0;0;1;1;0;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;4;13;30000;0;8;26;1;5;26;0;3;0;0;1;1;0;2;1;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;4;25;30000;0;8;26;1;1;26;-2;4;1;0;1;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;4;26;30000;0;4;26;1;16;26;-2;3;1;1;0;1;1;2;1;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;4;28;30000;0;8;26;1;1;26;-2;3;0;1;1;1;0;2;1;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;4;32;30000;0;8;26;1;1;26;-1;-2;0;0;0;1;1;0;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;4;45;30000;0;8;26;1;1;26;0;4;0;0;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;5;4;30000;0;8;26;1;3;26;0;3;0;0;0;1;0;0;1;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;5;5;30000;0;14;26;1;3;1;-2;-1;0;1;0;1;0;2;1;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;5;7;30000;0;8;26;1;26;26;0;4;0;0;1;1;0;0;1;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;5;9;30000;0;8;26;1;20;26;0;-1;0;0;0;1;1;0;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;5;13;30000;0;15;26;1;16;0;-1;0;0;0;1;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;5;16;30000;0;8;8;1;16;1;0;3;0;1;1;1;1;2;1;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;5;24;30000;0;1;26;1;11;26;0;3;1;1;0;1;0;2;1;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;5;25;30000;0;4;26;1;1;26;1;-2;0;1;1;1;1;0;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;5;26;30000;0;8;8;1;1;26;0;1;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;5;28;30000;0;5;26;1;13;26;-2;4;0;1;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;5;32;30000;0;3;26;1;11;26;-2;3;1;1;0;1;0;0;1;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;5;45;30000;0;6;8;1;1;26;-2;3;0;0;1;1;1;0;1;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;7;4;30000;0;11;8;1;24;26;-1;3;0;1;0;1;1;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;7;5;30000;0;8;8;1;19;26;-2;-1;1;0;0;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;7;7;30000;0;8;8;1;18;26;-2;1;0;1;0;1;0;2;1;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;7;9;30000;0;8;8;1;22;26;-1;3;1;1;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;7;13;30000;0;8;8;1;14;26;-1;5;0;0;0;1;0;0;1;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;7;25;30000;0;4;8;1;25;26;1;3;0;1;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;7;26;30000;0;4;8;1;1;26;0;4;0;0;1;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;7;28;30000;0;8;26;1;1;26;0;3;0;1;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;7;32;30000;0;9;8;1;17;26;-1;4;0;0;0;1;0;0;1;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;7;45;30000;0;8;16;1;1;26;-1;4;0;0;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;9;4;30000;0;16;8;1;25;26;0;5;0;1;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;9;5;30000;0;12;8;1;15;26;-2;-1;1;0;1;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;9;7;30000;0;15;8;1;10;26;0;3;0;0;1;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;9;9;30000;0;17;8;1;17;26;0;-1;1;1;1;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;9;13;30000;0;8;26;1;19;26;0;-1;0;1;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;9;25;30000;0;3;8;1;25;26;1;1;0;1;1;1;1;2;1;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;9;26;30000;0;4;26;1;1;26;1;1;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;9;28;30000;0;3;8;1;25;26;-2;4;0;1;0;1;0;2;1;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;9;32;30000;0;8;26;1;1;26;0;1;0;1;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;9;45;30000;0;15;26;1;1;26;0;-1;1;1;1;1;0;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;13;4;30000;0;15;8;1;25;26;-1;6;0;0;1;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;13;5;30000;0;22;26;1;3;1;-2;-2;1;0;1;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;13;7;30000;0;15;8;1;26;26;0;5;1;1;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;13;9;30000;0;15;8;1;25;26;1;4;0;1;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;13;13;30000;0;8;26;1;7;26;1;1;0;1;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;13;14;30000;0;8;26;1;12;26;-2;1;0;0;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;13;24;30000;0;16;8;1;1;26;0;0;0;1;1;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;13;25;30000;0;15;26;1;1;26;-2;-1;1;0;0;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;13;26;30000;0;15;8;1;1;26;-2;4;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;13;28;30000;0;15;8;1;1;26;0;4;0;0;1;1;0;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;13;32;30000;0;15;8;1;1;26;-1;3;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;13;45;30000;0;5;8;1;1;26;1;0;0;1;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;14;13;30000;0;15;8;1;20;26;-2;4;1;1;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;14;14;30000;0;8;26;1;6;26;1;1;0;0;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;14;25;30000;0;16;26;1;1;26;0;-1;0;1;1;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;14;26;30000;0;15;26;1;1;26;1;-1;0;1;0;1;0;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;14;32;30000;0;8;26;1;1;26;-1;-1;0;0;0;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;16;5;30000;0;22;26;1;25;1;-2;0;1;1;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;24;5;30000;0;31;8;1;23;26;0;3;0;0;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;24;13;30000;0;17;26;1;1;26;0;-1;1;0;1;1;0;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;24;24;30000;0;12;8;1;1;1;-2;1;0;1;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;24;26;30000;0;15;26;1;1;1;1;-1;1;1;1;1;0;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;24;32;30000;0;12;8;1;1;1;1;1;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;25;4;30000;0;28;8;1;10;26;-1;4;0;1;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;25;5;30000;0;24;8;1;26;26;0;0;1;0;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;25;7;30000;0;24;8;1;23;26;0;5;0;0;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;25;9;30000;0;8;26;1;14;26;0;-1;0;1;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;25;13;30000;0;15;26;1;1;26;0;-1;1;1;0;1;0;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;25;14;30000;0;32;8;1;5;26;1;1;0;0;1;1;0;1;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;25;25;30000;0;15;8;1;1;26;1;2;0;0;1;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;25;26;30000;0;5;8;1;1;26;-2;-2;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;25;28;30000;0;8;8;1;1;26;-2;6;1;0;1;1;0;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;25;32;30000;0;3;8;1;1;26;1;2;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;25;45;30000;0;10;8;1;1;26;-2;2;0;1;1;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;26;4;30000;0;30;8;1;22;26;0;3;0;1;1;1;1;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;26;5;30000;0;30;8;1;3;26;0;5;0;0;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;26;7;30000;0;24;8;1;6;26;-1;5;0;0;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;26;9;30000;0;20;26;1;1;26;-2;1;0;1;1;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;26;13;30000;0;30;8;1;26;26;-1;-1;1;1;1;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;26;14;30000;0;15;26;1;1;26;1;-1;0;1;0;1;0;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;26;24;30000;0;15;26;1;1;1;-1;-1;1;0;0;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;26;25;30000;0;16;26;1;1;26;-2;-1;1;0;1;1;0;0;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;26;26;30000;0;17;26;1;1;1;0;-1;1;0;0;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;26;28;30000;0;15;26;1;1;26;-2;-1;1;1;0;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;26;32;30000;0;15;26;1;1;1;-2;-1;0;0;0;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;26;45;30000;0;8;26;1;1;26;-2;1;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;28;4;30000;0;30;8;1;3;28;-2;-1;1;0;0;1;1;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;28;5;30000;0;30;8;1;14;28;-1;5;1;1;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;28;7;30000;0;23;26;1;23;28;-2;1;0;0;1;1;1;1;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;28;9;30000;0;15;8;1;19;28;1;3;0;1;1;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;28;13;30000;0;15;26;1;1;28;0;-1;0;0;1;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;28;25;30000;0;16;26;1;1;28;-1;-1;1;0;1;1;0;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;28;26;30000;0;16;26;1;1;28;0;-1;0;0;0;1;0;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;28;28;30000;0;61;8;1;19;28;-1;1;1;1;0;1;1;1;2;1;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;28;32;30000;0;15;26;1;1;28;0;-1;1;1;1;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;28;45;30000;0;15;26;1;1;28;-1;-1;0;1;0;1;1;0;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;32;4;30000;0;37;26;1;12;32;1;6;0;0;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;32;5;30000;0;30;26;1;6;32;-1;6;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;32;7;30000;0;30;26;1;3;32;-1;5;0;0;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;32;9;30000;0;31;26;1;22;32;1;6;0;1;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;32;13;30000;0;15;26;1;1;32;1;-1;0;1;0;1;0;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;32;14;30000;0;21;26;1;25;32;0;-1;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;32;24;30000;0;30;8;1;1;1;-1;-1;1;0;0;1;0;1;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;32;25;30000;0;8;26;1;1;32;-2;1;0;0;0;1;0;1;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;32;26;30000;0;1;26;1;21;32;0;-2;0;0;1;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;32;28;30000;0;4;8;1;1;32;-2;-2;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;32;32;30000;0;8;26;1;1;0;-2;1;0;0;1;1;1;1;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;32;45;30000;0;8;26;1;1;32;-2;1;0;1;0;1;0;1;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;45;4;30000;0;22;26;1;15;45;0;5;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;45;5;30000;0;23;26;1;11;45;1;4;0;0;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;45;7;30000;0;15;26;1;7;45;-1;4;0;0;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;45;9;30000;0;17;26;1;13;45;1;-1;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;45;13;30000;0;17;26;1;12;45;0;1;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;45;25;30000;0;4;8;1;26;45;-1;4;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;45;26;30000;0;5;26;1;1;45;-2;1;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;45;28;30000;0;1;26;1;19;45;-2;1;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;45;32;30000;0;3;26;1;10;45;1;6;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;26;45;45;30000;0;5;26;1;1;45;1;1;0;1;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;4;4;30000;0;16;28;1;6;1;-2;-1;1;1;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;4;5;30000;0;9;8;1;5;28;1;4;0;1;0;1;1;0;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;4;7;30000;0;9;8;1;6;28;0;4;0;0;1;1;1;2;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;4;9;30000;0;8;8;1;10;28;0;4;0;0;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;4;13;30000;0;10;8;1;13;28;-1;5;1;1;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;4;25;30000;0;8;28;1;1;28;0;6;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;4;26;30000;0;8;28;1;8;28;-1;4;0;0;0;1;0;0;1;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;4;28;30000;0;8;28;1;1;28;-2;4;0;1;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;4;32;30000;0;8;28;1;1;28;-1;1;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;4;45;30000;0;4;28;1;1;28;1;1;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;5;4;30000;0;14;8;1;25;28;0;0;0;1;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;5;5;30000;0;8;8;1;19;28;0;5;0;0;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;5;7;30000;0;8;8;1;24;28;-2;0;0;1;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;5;9;30000;0;8;8;1;9;28;-1;4;0;0;1;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;5;13;30000;0;9;8;1;19;28;1;1;1;1;1;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;5;25;30000;0;8;28;1;25;28;-1;4;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;5;26;30000;0;5;28;1;26;28;-2;4;0;0;0;1;0;0;1;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;5;28;30000;0;21;28;1;23;28;-1;4;0;1;1;1;0;2;1;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;5;32;30000;0;3;28;1;6;28;-1;-1;1;0;0;1;0;2;1;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;5;45;30000;0;4;28;1;12;28;-1;-1;0;0;0;1;0;0;1;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;7;4;30000;0;14;28;1;27;28;-2;4;1;0;1;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;7;5;30000;0;11;28;1;18;28;0;-2;0;0;1;1;0;0;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;7;7;30000;0;9;28;1;4;28;0;4;0;0;0;1;0;1;1;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;7;9;30000;0;8;28;1;5;28;-2;4;0;1;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;7;13;30000;0;8;28;1;8;28;1;-1;1;0;0;1;0;0;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;7;25;30000;0;5;28;1;9;28;-2;4;0;1;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;7;26;30000;0;21;28;1;7;28;-1;4;0;0;1;1;1;2;1;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;7;28;30000;0;4;28;1;14;28;0;2;0;1;0;0;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;7;32;30000;0;5;28;1;16;28;-1;4;0;1;1;1;0;0;1;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;7;45;30000;0;3;28;1;14;28;0;-1;0;0;0;0;0;2;1;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;9;4;30000;0;15;28;1;17;28;0;4;0;0;1;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;9;5;30000;0;15;28;1;16;28;-2;4;1;0;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;9;7;30000;0;26;28;1;19;28;-2;-1;0;0;1;1;1;2;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;9;9;30000;0;9;28;1;23;28;-1;0;0;1;0;1;0;0;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;9;13;30000;0;9;28;1;4;28;1;-1;0;0;1;1;0;2;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;9;25;30000;0;15;28;1;1;28;0;4;0;1;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;9;26;30000;0;5;28;1;1;28;-2;4;0;0;1;1;0;0;1;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;9;28;30000;0;5;28;1;8;28;1;0;1;1;0;1;1;2;1;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;9;32;30000;0;5;28;1;18;28;1;4;1;0;1;1;0;0;1;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;9;45;30000;0;8;28;1;1;28;-2;2;0;1;1;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;13;4;30000;0;21;28;1;5;28;-2;-2;0;1;1;1;0;0;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;13;5;30000;0;15;28;1;17;28;1;4;0;0;1;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;13;7;30000;0;16;28;1;6;28;0;4;0;0;1;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;13;9;30000;0;21;28;1;8;28;0;0;0;1;0;1;1;0;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;13;13;30000;0;12;28;1;2;28;0;-2;0;1;1;1;0;0;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;13;25;30000;0;8;28;1;12;28;-2;4;0;0;1;1;1;2;1;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;13;26;30000;0;4;28;1;18;28;-1;4;1;1;1;1;0;0;1;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;13;28;30000;0;8;28;1;6;28;0;4;0;0;0;1;0;2;1;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;13;32;30000;0;1;28;1;25;28;0;0;0;0;1;0;0;2;1;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;13;45;30000;0;2;28;1;1;28;-1;3;0;1;0;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;25;4;30000;0;15;28;1;1;28;-1;2;1;1;1;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;25;5;30000;0;41;28;1;7;28;1;-2;1;1;0;1;1;0;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;25;7;30000;0;45;28;1;10;28;-2;-1;0;0;0;1;1;2;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;25;9;30000;0;11;28;1;18;28;0;-1;0;1;1;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;25;13;30000;0;42;28;1;3;28;1;0;1;0;0;1;1;2;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;25;25;30000;0;9;28;1;1;28;-1;1;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;25;26;30000;0;15;28;1;1;28;-1;6;0;1;0;1;0;1;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;25;28;30000;0;8;28;1;1;28;-1;1;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;25;32;30000;0;10;8;1;1;28;-2;1;0;1;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;25;45;30000;0;8;28;1;1;28;-1;1;0;1;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;26;4;30000;0;28;28;1;4;28;1;4;0;1;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;26;5;30000;0;28;28;1;13;28;0;6;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;26;7;30000;0;30;28;1;18;28;1;4;0;1;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;26;9;30000;0;32;28;1;23;28;-1;4;0;1;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;26;13;30000;0;23;28;1;14;28;0;-2;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;26;25;30000;0;8;28;1;1;28;0;1;0;1;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;26;26;30000;0;15;16;1;1;28;1;1;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;26;28;30000;0;8;28;1;1;28;0;1;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;26;32;30000;0;8;28;1;1;28;-2;1;0;1;1;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;26;45;30000;0;15;28;1;1;28;1;1;1;1;1;1;0;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;28;4;30000;0;32;28;1;23;28;-1;4;0;1;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;28;5;30000;0;41;28;1;12;28;-1;0;0;0;0;1;0;2;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;28;7;30000;0;32;28;1;8;28;0;5;0;1;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;28;9;30000;0;30;28;1;4;28;1;6;0;0;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;28;13;30000;0;8;28;1;5;28;1;1;0;1;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;28;14;30000;0;15;28;1;1;28;-2;1;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;28;25;30000;0;16;28;1;1;28;-1;1;0;1;1;1;0;0;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;28;26;30000;0;16;28;1;1;28;-2;-1;1;1;1;1;0;0;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;28;28;30000;0;8;8;1;16;1;-2;4;0;0;1;1;0;0;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;28;32;30000;0;9;28;1;1;28;-2;1;0;1;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;28;45;30000;0;8;28;1;1;28;-1;1;0;1;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;32;4;30000;0;30;28;1;21;32;1;5;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;32;5;30000;0;32;28;1;16;32;-1;6;0;1;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;32;7;30000;0;30;28;1;22;32;-2;4;0;0;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;32;9;30000;0;21;28;1;23;32;1;-1;0;1;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;32;13;30000;0;17;28;1;1;32;0;1;0;0;1;1;0;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;32;25;30000;0;15;16;1;1;32;0;-2;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;32;26;30000;0;8;28;1;1;32;-2;1;0;1;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;32;28;30000;0;8;28;1;1;32;0;1;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;32;32;30000;0;8;28;1;1;32;1;1;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;32;45;30000;0;8;28;1;1;32;-1;1;0;1;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;45;4;30000;0;23;28;1;24;45;1;5;0;0;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;45;5;30000;0;25;28;1;5;45;1;6;0;0;0;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;45;7;30000;0;26;28;1;19;45;-1;6;0;1;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;45;9;30000;0;18;28;1;4;45;-2;5;0;0;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;45;13;30000;0;15;28;1;6;45;0;-1;0;0;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;45;25;30000;0;7;8;1;1;45;1;0;0;1;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;45;26;30000;0;4;8;1;1;45;1;0;0;1;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;45;28;30000;0;4;8;1;13;45;-1;-1;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;45;32;30000;0;15;28;1;1;45;-1;1;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;28;45;45;30000;0;3;8;1;28;45;-1;5;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;29;14;14;30000;0;8;29;1;15;29;1;-1;0;1;0;1;0;1;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;29;14;16;30000;0;8;29;1;1;29;-1;2;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;29;14;29;30000;0;8;29;1;1;29;0;3;0;1;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;29;14;32;30000;0;8;29;1;1;29;1;-2;0;1;0;1;0;1;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;29;16;14;30000;0;8;29;1;22;29;1;5;0;1;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;29;16;16;30000;0;15;29;1;1;29;-2;4;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;29;16;29;30000;0;8;29;1;1;29;1;-1;0;0;0;1;0;1;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;29;16;55;30000;0;8;16;1;1;29;0;-2;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;29;29;14;30000;0;6;29;1;22;29;1;-1;0;1;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;29;29;16;30000;0;13;29;1;1;29;-2;1;0;0;1;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;29;29;29;30000;0;8;29;1;1;29;-1;1;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;29;29;32;30000;0;10;8;1;1;29;1;4;1;0;1;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;29;29;55;30000;0;8;29;1;1;29;-1;1;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;29;32;14;30000;0;9;29;1;18;32;-1;-1;0;0;0;1;0;1;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;29;32;29;30000;0;15;16;1;1;32;-1;1;0;1;1;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;29;32;32;30000;0;30;29;1;1;32;-2;5;0;1;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;29;32;55;30000;0;5;16;1;1;32;1;3;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;29;55;16;30000;0;15;29;1;12;55;0;1;0;0;0;1;0;1;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;29;55;29;30000;0;6;8;1;11;55;-1;6;0;1;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;29;55;32;30000;0;6;8;1;1;55;0;6;0;0;0;1;0;1;1;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;29;55;55;30000;0;3;16;1;1;55;0;2;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;30;30;30;30000;0;8;30;1;1;1;-2;1;0;0;1;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;30;30;76;30000;0;8;30;1;1;30;-1;1;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;30;76;30;30000;0;27;8;1;1;76;-1;4;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;30;76;76;30000;0;4;16;1;1;76;1;2;0;0;1;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;4;4;30000;0;19;8;1;25;1;-2;-2;1;0;1;1;1;2;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;4;5;30000;0;17;8;1;25;1;-1;-2;1;0;1;1;1;2;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;4;7;30000;0;9;8;1;7;32;0;4;1;1;0;1;1;0;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;4;9;30000;0;8;32;1;13;32;1;1;0;0;1;1;1;2;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;4;13;30000;0;11;8;1;7;1;-2;-1;1;0;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;4;17;30000;0;8;8;1;12;1;-2;5;1;0;1;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;4;25;30000;0;8;8;1;10;32;0;6;0;1;0;1;0;0;1;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;4;26;30000;0;8;8;1;1;32;-1;6;0;1;1;1;1;0;1;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;4;28;30000;0;5;8;1;13;32;0;4;0;1;1;1;1;0;1;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;4;32;30000;0;8;32;1;1;1;-1;-2;0;1;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;4;45;30000;0;8;8;1;1;32;-1;4;1;0;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;5;4;30000;0;17;16;1;21;1;-1;0;1;0;1;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;5;5;30000;0;17;8;1;5;1;1;0;0;0;0;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;5;7;30000;0;9;8;1;6;32;-1;-1;0;0;0;1;0;0;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;5;9;30000;0;8;8;1;30;32;1;-1;0;0;0;1;0;0;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;5;13;30000;0;8;32;1;26;1;-2;-2;0;1;0;1;0;0;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;5;17;30000;0;8;32;1;14;1;-1;-1;0;0;0;1;1;2;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;5;24;30000;0;8;8;1;1;32;-2;-1;0;0;0;1;0;2;1;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;5;25;30000;0;2;32;1;1;32;1;2;1;1;0;1;0;0;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;5;26;30000;0;9;8;1;1;32;-2;5;1;0;1;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;5;28;30000;0;4;32;1;21;32;-1;6;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;5;32;30000;0;8;32;1;1;1;-1;-1;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;5;45;30000;0;2;8;1;28;32;-2;6;0;1;0;1;1;0;1;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;7;4;30000;0;17;8;1;30;32;-2;5;0;1;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;7;5;30000;0;14;8;1;18;32;1;1;1;0;1;1;0;2;1;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;7;7;30000;0;14;8;1;26;32;-1;5;0;0;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;7;9;30000;0;8;8;1;21;32;0;4;0;1;0;1;1;2;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;7;13;30000;0;21;8;1;10;32;-1;6;0;0;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;7;25;30000;0;8;8;1;1;32;1;5;1;1;0;1;1;0;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;7;26;30000;0;8;8;1;1;32;0;0;1;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;7;28;30000;0;4;8;1;17;32;0;4;1;0;1;1;0;0;1;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;7;32;30000;0;9;8;1;1;32;-1;1;0;0;1;0;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;7;45;30000;0;8;8;1;1;32;1;1;1;0;0;1;1;0;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;9;4;30000;0;17;8;1;19;32;1;5;0;0;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;9;5;30000;0;15;8;1;20;32;-1;4;1;1;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;9;7;30000;0;15;8;1;22;32;0;5;0;0;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;9;9;30000;0;10;8;1;1;32;1;4;0;1;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;9;13;30000;0;15;8;1;11;32;0;4;0;1;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;9;22;30000;0;3;8;1;1;32;-1;4;1;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;9;25;30000;0;6;8;1;1;32;1;1;1;0;1;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;9;26;30000;0;5;16;1;1;32;1;4;0;1;1;1;1;0;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;9;28;30000;0;6;8;1;1;32;-2;-2;1;0;1;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;9;32;30000;0;5;8;1;30;32;1;4;0;1;0;1;0;0;1;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;9;45;30000;0;4;8;1;1;32;-1;-2;1;0;1;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;13;4;30000;0;22;32;1;8;1;-1;1;1;0;1;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;13;5;30000;0;20;32;1;8;1;-1;0;1;1;1;1;0;2;1;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;13;7;30000;0;17;8;1;3;32;0;6;0;1;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;13;9;30000;0;21;32;1;27;32;-1;-1;0;1;1;1;0;0;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;13;13;30000;0;9;32;1;21;1;-1;-2;1;0;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;13;14;30000;0;31;32;1;15;32;1;-1;1;1;0;1;0;0;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;13;17;30000;0;8;32;1;17;1;-2;-2;0;0;0;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;13;24;30000;0;15;8;1;17;32;1;3;0;1;0;1;1;0;1;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;13;25;30000;0;15;8;1;1;32;-2;-2;1;1;1;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;13;26;30000;0;15;8;1;1;32;-1;3;0;1;0;1;1;2;2;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;13;28;30000;0;18;16;1;5;32;-2;4;1;1;0;1;0;0;2;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;13;32;30000;0;8;32;1;1;1;-2;0;0;0;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;13;45;30000;0;5;8;1;1;32;-1;1;0;0;1;1;0;0;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;14;13;30000;0;15;32;1;28;32;-2;6;0;0;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;14;14;30000;0;21;32;1;7;32;1;-2;0;1;0;1;0;0;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;14;25;30000;0;15;32;1;1;32;-1;4;1;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;14;26;30000;0;15;32;1;1;32;-2;4;1;1;1;1;1;0;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;14;29;30000;0;8;8;1;1;32;-1;6;1;1;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;14;32;30000;0;8;16;1;1;32;-1;-1;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;17;4;30000;0;32;8;1;8;1;0;1;1;0;1;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;17;5;30000;0;32;8;1;27;1;1;1;0;1;0;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;17;13;30000;0;12;8;1;25;1;0;0;0;1;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;17;17;30000;0;15;32;1;1;1;-1;1;1;0;1;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;17;32;30000;0;12;8;1;1;1;-2;1;1;0;0;1;0;2;2;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;22;9;30000;0;13;32;1;26;32;0;4;0;1;1;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;22;22;30000;0;12;8;1;1;1;1;4;1;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;22;32;30000;0;17;8;1;1;1;1;1;1;0;0;1;1;2;2;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;24;5;30000;0;18;32;1;15;32;0;4;0;1;0;1;1;0;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;24;13;30000;0;9;32;1;7;32;-2;-1;1;0;0;1;0;2;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;24;24;30000;0;12;8;1;1;32;-2;-2;1;0;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;24;26;30000;0;12;8;1;1;32;-1;5;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;24;32;30000;0;13;8;1;1;1;-1;0;0;0;0;1;1;2;2;1;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;25;4;30000;0;30;32;1;31;32;1;4;0;0;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;25;5;30000;0;17;32;1;20;32;1;4;1;0;1;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;25;7;30000;0;30;32;1;24;32;1;4;0;1;0;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;25;9;30000;0;12;32;1;10;32;-2;1;0;1;1;1;0;2;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;25;13;30000;0;30;32;1;12;32;-2;4;0;1;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;25;14;30000;0;30;32;1;23;32;0;4;0;1;0;1;0;2;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;25;25;30000;0;15;32;1;1;32;-1;1;0;1;1;1;1;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;25;26;30000;0;15;32;1;1;32;1;1;1;1;0;1;0;0;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;25;28;30000;0;6;16;1;1;32;-1;4;1;0;1;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;25;32;30000;0;12;8;1;1;32;1;0;1;0;1;1;0;1;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;25;45;30000;0;10;8;1;1;32;-2;4;1;1;1;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;26;4;30000;0;30;32;1;25;32;1;4;1;0;1;1;1;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;26;5;30000;0;31;32;1;24;32;1;4;1;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;26;7;30000;0;30;32;1;11;32;1;4;0;1;0;1;1;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;26;9;30000;0;30;32;1;8;32;1;4;1;0;0;1;1;2;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;26;13;30000;0;41;32;1;15;32;-1;0;1;0;1;1;0;0;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;26;14;30000;0;9;32;1;7;32;0;-1;0;0;1;1;0;0;0;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;26;24;30000;0;10;8;1;1;1;0;0;1;1;1;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;26;25;30000;0;10;32;1;1;32;-1;4;1;0;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;26;26;30000;0;30;8;1;15;1;1;2;0;1;0;1;1;0;2;1;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;26;28;30000;0;15;8;1;7;32;-2;4;0;0;0;1;0;2;2;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;26;32;30000;0;15;8;1;1;1;-1;-2;1;1;1;1;0;1;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;26;45;30000;0;20;8;1;1;32;-1;5;0;1;1;1;0;1;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;28;4;30000;0;16;32;1;28;32;0;4;0;0;1;1;1;0;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;28;5;30000;0;41;32;1;15;32;1;-1;0;0;0;1;1;0;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;28;7;30000;0;31;32;1;2;32;1;4;0;1;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;28;9;30000;0;41;32;1;28;32;-2;0;0;0;0;1;0;2;2;1;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;28;13;30000;0;15;32;1;1;32;-1;4;1;1;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;28;25;30000;0;20;8;1;1;32;-2;4;0;1;1;1;1;1;2;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;28;26;30000;0;30;16;1;31;32;0;-2;0;0;0;1;0;2;2;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;28;28;30000;0;30;16;1;1;32;0;4;1;0;1;1;0;1;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;28;32;30000;0;20;8;1;1;32;-2;-2;1;1;1;1;0;1;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;28;45;30000;0;20;8;1;1;32;1;-2;0;1;1;1;0;1;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;29;14;30000;0;31;8;1;12;32;-2;2;0;1;0;1;0;0;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;29;29;30000;0;30;8;1;23;32;1;4;1;1;0;1;0;0;2;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;29;32;30000;0;20;8;1;1;32;-2;0;1;1;0;1;0;2;2;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;29;55;30000;0;59;8;1;1;32;-1;4;0;1;1;1;0;1;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;32;4;30000;0;30;16;1;27;1;-2;4;0;0;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;32;5;30000;0;30;32;1;10;1;-2;6;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;32;7;30000;0;30;32;1;27;32;1;4;0;1;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;32;9;30000;0;15;32;1;1;1;1;5;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;32;13;30000;0;30;32;1;17;1;-1;4;0;1;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;32;14;30000;0;15;8;1;1;32;1;-2;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;32;17;30000;0;11;32;1;1;0;-1;1;0;1;0;1;1;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;32;22;30000;0;8;32;1;1;1;1;1;0;0;0;1;0;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;32;24;30000;0;8;32;1;1;1;-2;1;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;32;25;30000;0;30;32;1;1;32;1;4;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;32;26;30000;0;8;32;1;1;0;-1;1;1;0;1;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;32;28;30000;0;10;8;1;1;32;-1;6;0;1;0;1;0;2;1;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;32;29;30000;0;8;32;1;1;32;-2;1;0;1;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;32;32;30000;0;8;32;1;1;1;-1;1;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;32;45;30000;0;10;32;1;1;32;-1;1;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;32;55;30000;0;10;32;1;1;32;-1;1;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;45;4;30000;0;31;32;1;17;45;-2;5;0;0;0;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;45;5;30000;0;27;32;1;26;45;-1;5;0;0;0;1;0;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;45;7;30000;0;28;32;1;2;45;-1;4;0;0;0;1;0;2;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;45;9;30000;0;19;32;1;1;45;1;6;0;0;0;1;0;2;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;45;13;30000;0;28;32;1;22;45;0;4;0;0;0;1;0;1;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;45;25;30000;0;16;8;1;1;45;-1;5;0;0;1;1;0;1;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;45;26;30000;0;19;8;1;21;45;0;-1;0;1;1;1;0;1;2;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;45;28;30000;0;12;8;1;1;45;1;5;1;1;0;1;1;1;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;45;32;30000;0;34;8;1;31;45;-1;-2;0;1;0;1;1;1;2;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;45;45;30000;0;12;8;1;1;45;-2;-2;0;0;1;1;1;1;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;55;29;30000;0;12;16;1;19;55;-2;2;0;0;0;1;1;0;2;1;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;55;32;30000;0;18;8;1;6;55;0;-2;0;1;0;1;0;0;0;1;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;32;55;55;30000;0;8;8;1;1;55;-2;0;1;0;0;1;1;1;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;35;17;17;30000;0;12;8;1;21;1;-2;4;1;0;1;1;1;0;2;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;35;17;32;30000;0;10;8;1;3;1;0;0;0;1;0;1;1;0;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;35;32;35;30000;0;11;8;1;33;35;-1;5;1;1;1;1;0;0;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;35;35;32;30000;0;9;8;1;21;35;0;0;0;0;0;1;0;0;2;1;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;35;35;35;30000;0;9;8;1;34;1;0;4;0;1;1;1;1;2;0;1;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;36;36;36;30000;0;6;8;1;23;36;1;5;1;0;0;1;0;2;2;1;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;40;40;40;30000;0;12;8;1;1;1;0;0;1;0;0;1;1;1;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;45;4;4;30000;0;3;45;1;36;45;0;2;0;1;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;45;13;13;30000;0;10;8;1;1;45;1;6;0;1;0;1;0;1;2;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;45;32;28;30000;0;19;16;1;20;45;-1;6;0;0;0;1;0;0;2;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;45;45;45;30000;0;30;45;1;1;45;-2;1;0;0;0;1;0;2;0;0;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;50;20;50;30000;0;3;8;1;1;50;1;1;0;1;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;76;30;30;30000;0;12;16;1;50;76;1;10;0;1;1;1;1;0;0;1;1 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;76;30;76;30000;0;8;76;1;4;76;-1;-1;0;0;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;76;76;30;30000;0;47;16;1;1;76;0;5;0;1;0;1;0;0;0;0;0 +Intel(R) Data Center GPU Max 1550 [0x0bd5];3;76;76;76;30000;0;47;16;1;1;76;-2;6;0;1;0;1;0;2;0;0;0 diff --git a/src/acc/opencl/smm/params/tune_multiply_V100.csv b/src/acc/opencl/smm/params/tune_multiply_V100.csv index daac22c121a..d319dd6b2b4 100644 --- a/src/acc/opencl/smm/params/tune_multiply_V100.csv +++ b/src/acc/opencl/smm/params/tune_multiply_V100.csv @@ -1,158 +1,158 @@ DEVICE;TYPEID;M;N;K;S;GFLOPS;BS;BM;BN;BK;WS;WG;LU;NZ;AL;TB;TC;AP;AA;AB;AC -Tesla V100-PCIE-16GB [0xb271];3;2;2;2;30000;35.1;12;1;1;2;0;-1;1;0;0;1;1;0;0;0;0 -Tesla V100-PCIE-16GB [0xb271];3;3;3;3;30000;93.7;12;3;1;3;0;-2;-1;0;0;0;1;0;0;0;0 -Tesla V100-PCIE-16GB [0xb271];3;4;4;4;30000;192.8;12;4;1;4;0;-2;0;0;0;0;1;0;1;0;0 -Tesla V100-PCIE-16GB [0xb271];3;4;4;5;30000;209.3;12;4;1;3;0;-2;0;0;0;1;1;0;2;3;0 -Tesla V100-PCIE-16GB [0xb271];3;4;4;7;30000;240.6;15;4;1;4;0;-1;-1;0;0;1;1;0;1;3;0 -Tesla V100-PCIE-16GB [0xb271];3;4;4;9;30000;254.8;8;4;1;2;0;-1;-1;0;0;0;1;0;1;3;0 -Tesla V100-PCIE-16GB [0xb271];3;4;4;10;30000;264.8;13;4;1;4;0;-2;0;0;0;0;1;0;2;3;0 -Tesla V100-PCIE-16GB [0xb271];3;4;4;13;30000;282.9;15;4;1;3;0;0;-1;0;0;1;1;0;1;0;0 -Tesla V100-PCIE-16GB [0xb271];3;4;4;15;30000;283.7;12;4;1;2;0;-2;-1;0;0;1;0;0;1;3;0 -Tesla V100-PCIE-16GB [0xb271];3;4;4;25;30000;310.8;25;4;1;4;0;0;-1;0;0;0;1;0;2;3;0 -Tesla V100-PCIE-16GB [0xb271];3;4;4;26;30000;308.3;4;4;1;2;0;-2;1;0;0;0;1;1;2;0;0 -Tesla V100-PCIE-16GB [0xb271];3;4;4;28;30000;316.8;25;4;1;4;0;0;0;0;0;0;1;0;2;3;0 -Tesla V100-PCIE-16GB [0xb271];3;4;4;32;30000;318.9;3;4;1;2;0;0;-2;0;0;0;1;1;2;0;0 -Tesla V100-PCIE-16GB [0xb271];3;4;5;4;30000;216.7;8;4;1;3;0;-1;0;0;0;0;1;0;0;0;0 -Tesla V100-PCIE-16GB [0xb271];3;4;5;5;30000;226.0;12;4;1;4;0;-1;0;0;0;0;1;1;1;3;0 -Tesla V100-PCIE-16GB [0xb271];3;4;5;7;30000;274.4;12;4;1;4;0;1;0;0;0;0;1;1;1;3;0 -Tesla V100-PCIE-16GB [0xb271];3;4;5;9;30000;302.3;12;4;1;4;0;-2;0;1;0;0;1;0;1;3;0 -Tesla V100-PCIE-16GB [0xb271];3;4;5;13;30000;337.3;15;4;1;2;0;0;0;0;0;0;1;1;1;3;0 -Tesla V100-PCIE-16GB [0xb271];3;4;5;25;30000;386.3;15;4;1;2;0;1;-1;0;0;0;1;1;2;0;0 -Tesla V100-PCIE-16GB [0xb271];3;4;7;4;30000;290.9;15;4;1;4;0;-1;-1;1;0;1;1;0;0;3;0 -Tesla V100-PCIE-16GB [0xb271];3;4;7;5;30000;311.1;12;4;1;3;0;-2;-1;0;0;1;1;1;1;0;0 -Tesla V100-PCIE-16GB [0xb271];3;4;7;7;30000;381.1;12;4;1;4;0;-2;-1;0;0;0;1;1;1;3;0 -Tesla V100-PCIE-16GB [0xb271];3;4;7;9;30000;423.7;12;4;1;3;0;-1;-1;0;0;0;1;1;1;3;0 -Tesla V100-PCIE-16GB [0xb271];3;4;7;13;30000;460.8;15;4;1;2;0;-2;0;0;0;1;1;1;1;0;0 -Tesla V100-PCIE-16GB [0xb271];3;4;9;4;30000;353.8;15;4;1;1;0;-2;-1;1;0;0;1;0;3;3;0 -Tesla V100-PCIE-16GB [0xb271];3;4;9;5;30000;387.9;12;4;1;4;0;-1;0;1;0;0;1;1;1;3;0 -Tesla V100-PCIE-16GB [0xb271];3;4;9;7;30000;481.5;12;4;1;2;0;1;-2;0;0;0;1;1;1;3;0 -Tesla V100-PCIE-16GB [0xb271];3;4;9;9;30000;531.4;12;4;1;4;0;-1;-1;0;0;0;1;1;1;3;0 -Tesla V100-PCIE-16GB [0xb271];3;4;9;13;30000;587.2;15;4;1;2;0;0;1;0;0;0;1;1;1;3;0 -Tesla V100-PCIE-16GB [0xb271];3;4;10;4;30000;394.9;15;4;1;2;0;0;-1;1;0;1;1;0;0;3;0 -Tesla V100-PCIE-16GB [0xb271];3;4;10;10;30000;593.4;13;4;1;2;0;1;1;0;0;1;1;1;1;0;0 -Tesla V100-PCIE-16GB [0xb271];3;4;13;4;30000;460.4;20;4;1;2;0;1;1;1;0;1;1;0;0;3;0 -Tesla V100-PCIE-16GB [0xb271];3;4;13;5;30000;491.0;12;4;1;4;0;-2;-1;0;0;0;1;1;2;3;0 -Tesla V100-PCIE-16GB [0xb271];3;4;13;7;30000;606.8;13;4;1;2;0;1;-1;0;0;0;1;1;1;3;0 -Tesla V100-PCIE-16GB [0xb271];3;4;13;9;30000;659.9;15;4;1;2;0;-2;-1;1;0;0;1;1;1;0;0 -Tesla V100-PCIE-16GB [0xb271];3;4;15;4;30000;484.4;24;4;1;4;0;-2;-1;0;0;1;1;1;0;0;0 -Tesla V100-PCIE-16GB [0xb271];3;4;25;4;30000;672.2;24;4;1;1;0;-2;0;1;0;1;1;0;3;3;0 -Tesla V100-PCIE-16GB [0xb271];3;4;25;5;30000;741.7;24;4;1;4;0;-1;-2;1;0;1;1;1;0;3;0 -Tesla V100-PCIE-16GB [0xb271];3;4;26;4;30000;692.1;20;4;1;2;0;-1;-1;1;0;1;1;0;0;3;0 -Tesla V100-PCIE-16GB [0xb271];3;4;28;4;30000;720.9;25;4;1;1;0;0;0;1;0;1;1;0;3;3;0 -Tesla V100-PCIE-16GB [0xb271];3;4;32;4;30000;760.2;24;4;1;4;0;0;-2;1;0;1;1;0;0;3;0 -Tesla V100-PCIE-16GB [0xb271];3;5;4;4;30000;242.9;12;5;1;2;0;0;0;0;0;0;1;0;0;3;0 -Tesla V100-PCIE-16GB [0xb271];3;5;4;5;30000;247.6;20;5;1;5;0;1;-1;0;0;0;1;0;3;3;0 -Tesla V100-PCIE-16GB [0xb271];3;5;4;7;30000;282.4;12;5;1;5;0;0;1;0;0;0;1;1;3;3;0 -Tesla V100-PCIE-16GB [0xb271];3;5;4;9;30000;303.9;12;5;1;4;0;-2;-1;0;0;1;1;0;0;3;0 -Tesla V100-PCIE-16GB [0xb271];3;5;4;13;30000;245.5;7;5;1;2;0;-2;1;1;0;0;1;1;2;0;0 -Tesla V100-PCIE-16GB [0xb271];3;5;4;25;30000;375.3;20;5;1;3;0;1;-1;1;0;0;1;1;2;3;0 -Tesla V100-PCIE-16GB [0xb271];3;5;5;4;30000;257.8;14;5;1;2;0;-1;0;0;0;0;1;1;1;3;0 -Tesla V100-PCIE-16GB [0xb271];3;5;5;5;30000;300.3;15;5;1;2;0;-1;-2;0;0;1;1;0;1;3;0 -Tesla V100-PCIE-16GB [0xb271];3;5;5;7;30000;338.9;20;5;1;3;0;-1;-2;0;0;0;1;0;1;3;0 -Tesla V100-PCIE-16GB [0xb271];3;5;5;9;30000;364.9;20;5;1;2;0;-1;1;0;0;1;1;0;1;0;0 -Tesla V100-PCIE-16GB [0xb271];3;5;5;13;30000;393.2;20;5;1;5;0;-1;-1;0;0;0;1;0;1;3;0 -Tesla V100-PCIE-16GB [0xb271];3;5;7;4;30000;314.7;12;5;1;2;0;-1;0;0;0;0;1;1;2;3;0 -Tesla V100-PCIE-16GB [0xb271];3;5;7;5;30000;360.8;12;5;1;4;0;1;-2;1;0;1;1;1;1;3;0 -Tesla V100-PCIE-16GB [0xb271];3;5;7;7;30000;435.2;12;5;1;2;0;-2;0;1;0;1;1;1;1;0;0 -Tesla V100-PCIE-16GB [0xb271];3;5;7;9;30000;479.6;13;5;1;3;0;1;-2;0;0;0;1;1;1;3;0 -Tesla V100-PCIE-16GB [0xb271];3;5;7;13;30000;523.5;12;5;1;5;0;-1;0;1;0;0;1;0;2;0;0 -Tesla V100-PCIE-16GB [0xb271];3;5;9;4;30000;386.9;12;5;1;3;0;-1;-1;1;0;0;1;1;2;3;0 -Tesla V100-PCIE-16GB [0xb271];3;5;9;5;30000;454.4;12;5;1;4;0;0;-2;1;0;0;1;1;1;3;0 -Tesla V100-PCIE-16GB [0xb271];3;5;9;7;30000;551.2;12;5;1;5;0;-2;0;0;0;1;1;1;1;3;0 -Tesla V100-PCIE-16GB [0xb271];3;5;9;9;30000;596.0;13;5;1;3;0;1;-2;0;0;0;1;1;1;3;0 -Tesla V100-PCIE-16GB [0xb271];3;5;13;4;30000;498.9;13;5;1;3;0;-1;0;1;0;0;1;1;1;3;0 -Tesla V100-PCIE-16GB [0xb271];3;5;13;5;30000;569.6;12;5;1;5;0;1;0;1;0;0;1;1;1;0;0 -Tesla V100-PCIE-16GB [0xb271];3;5;13;7;30000;699.9;13;5;1;4;0;-2;-2;1;0;1;1;1;1;3;0 -Tesla V100-PCIE-16GB [0xb271];3;5;13;13;30000;844.8;20;5;1;4;0;0;0;0;0;0;1;1;1;0;0 -Tesla V100-PCIE-16GB [0xb271];3;5;25;4;30000;593.2;11;5;1;5;0;0;0;0;0;0;1;1;0;3;0 -Tesla V100-PCIE-16GB [0xb271];3;7;5;5;30000;399.0;16;2;1;5;0;-1;-2;0;0;0;1;0;0;3;0 -Tesla V100-PCIE-16GB [0xb271];3;7;5;7;30000;438.8;20;2;1;3;0;0;-1;0;0;1;1;1;0;3;0 -Tesla V100-PCIE-16GB [0xb271];3;7;7;5;30000;506.3;15;1;2;6;0;-1;-2;1;0;1;1;0;3;0;0 -Tesla V100-PCIE-16GB [0xb271];3;7;7;7;30000;531.5;20;2;1;4;0;1;-2;1;0;1;1;0;0;3;0 -Tesla V100-PCIE-16GB [0xb271];3;7;7;13;30000;635.9;24;7;1;5;0;-1;0;0;0;0;1;1;2;3;0 -Tesla V100-PCIE-16GB [0xb271];3;7;13;13;30000;1037.5;20;7;1;5;0;0;-2;1;0;0;1;1;1;3;0 -Tesla V100-PCIE-16GB [0xb271];3;9;9;13;30000;905.3;25;9;1;7;0;0;0;0;0;0;1;1;2;3;0 -Tesla V100-PCIE-16GB [0xb271];3;9;13;9;30000;1027.6;20;9;1;2;0;0;0;0;0;0;1;1;1;0;0 -Tesla V100-PCIE-16GB [0xb271];3;9;13;13;30000;1136.0;20;9;1;8;0;1;-1;0;0;0;1;1;1;3;0 -Tesla V100-PCIE-16GB [0xb271];3;9;16;16;30000;1367.4;24;9;1;2;0;1;-1;1;0;0;1;1;2;3;0 -Tesla V100-PCIE-16GB [0xb271];3;9;22;16;30000;1569.6;24;9;1;6;0;-1;0;0;0;0;1;1;2;3;0 -Tesla V100-PCIE-16GB [0xb271];3;9;22;22;30000;1665.8;25;9;1;5;0;-2;-2;1;0;0;1;1;2;0;0 -Tesla V100-PCIE-16GB [0xb271];3;9;32;9;30000;1604.0;30;9;1;2;0;0;-1;1;0;0;1;1;1;3;0 -Tesla V100-PCIE-16GB [0xb271];3;9;32;22;30000;1944.9;50;9;1;4;0;0;1;1;0;0;1;1;2;3;0 -Tesla V100-PCIE-16GB [0xb271];3;9;32;32;30000;2154.3;50;9;1;3;0;0;0;0;0;0;1;1;2;3;0 -Tesla V100-PCIE-16GB [0xb271];3;13;5;5;30000;515.2;25;3;1;7;0;0;1;1;0;0;1;1;3;3;0 -Tesla V100-PCIE-16GB [0xb271];3;13;5;7;30000;547.3;13;3;1;8;0;0;1;0;0;1;1;1;1;3;0 -Tesla V100-PCIE-16GB [0xb271];3;13;5;13;30000;596.1;24;2;1;2;0;0;-2;1;0;0;1;1;1;3;0 -Tesla V100-PCIE-16GB [0xb271];3;13;7;5;30000;636.4;18;2;2;4;0;0;1;1;0;1;1;1;3;3;2 -Tesla V100-PCIE-16GB [0xb271];3;13;7;13;30000;811.2;12;13;1;12;0;0;0;0;0;0;1;1;1;3;0 -Tesla V100-PCIE-16GB [0xb271];3;13;9;9;30000;857.9;20;13;1;3;0;0;0;0;0;0;1;0;1;3;0 -Tesla V100-PCIE-16GB [0xb271];3;13;9;13;30000;885.8;25;13;1;2;0;1;0;0;0;0;1;1;1;0;0 -Tesla V100-PCIE-16GB [0xb271];3;13;13;5;30000;1009.6;24;13;1;8;0;1;0;1;0;0;1;1;1;3;0 -Tesla V100-PCIE-16GB [0xb271];3;13;13;7;30000;1189.4;25;13;1;10;0;1;-1;1;0;0;1;1;1;3;0 -Tesla V100-PCIE-16GB [0xb271];3;13;13;9;30000;1294.8;24;13;1;10;0;-1;-2;1;0;0;1;1;1;0;0 -Tesla V100-PCIE-16GB [0xb271];3;13;13;13;30000;1351.9;25;13;1;10;0;-1;0;0;0;0;1;1;1;3;0 -Tesla V100-PCIE-16GB [0xb271];3;16;9;16;30000;1054.4;12;16;1;4;0;-1;-2;1;0;1;1;1;0;0;0 -Tesla V100-PCIE-16GB [0xb271];3;16;9;22;30000;1094.0;25;16;1;5;0;0;-2;0;0;0;1;1;2;3;0 -Tesla V100-PCIE-16GB [0xb271];3;16;16;9;30000;1631.8;25;16;1;2;0;-1;-1;1;0;0;1;0;1;3;0 -Tesla V100-PCIE-16GB [0xb271];3;16;16;16;30000;1809.8;25;16;1;16;0;0;0;0;0;1;1;1;2;3;0 -Tesla V100-PCIE-16GB [0xb271];3;16;16;22;30000;1847.2;50;16;1;12;0;1;-2;1;0;1;1;1;2;3;0 -Tesla V100-PCIE-16GB [0xb271];3;16;22;9;30000;1783.9;25;16;1;6;0;-2;-1;1;0;1;1;0;1;0;0 -Tesla V100-PCIE-16GB [0xb271];3;16;22;16;30000;1999.5;40;16;1;16;0;-1;-2;0;0;1;1;1;2;3;0 -Tesla V100-PCIE-16GB [0xb271];3;16;22;22;30000;1934.5;25;16;1;14;0;0;0;0;0;0;1;0;2;3;2 -Tesla V100-PCIE-16GB [0xb271];3;20;20;20;30000;1986.9;40;20;1;13;0;1;-2;1;0;1;1;0;2;3;0 -Tesla V100-PCIE-16GB [0xb271];3;22;9;9;30000;809.5;20;22;1;17;0;-1;0;0;0;0;1;1;1;3;2 -Tesla V100-PCIE-16GB [0xb271];3;22;9;16;30000;1256.9;26;22;1;1;0;-2;-1;1;0;0;1;0;2;3;0 -Tesla V100-PCIE-16GB [0xb271];3;22;9;22;30000;1271.4;30;22;1;1;0;-2;1;0;0;0;1;1;2;3;0 -Tesla V100-PCIE-16GB [0xb271];3;22;9;32;30000;1371.7;24;22;1;1;0;0;-2;1;0;1;1;0;2;3;0 -Tesla V100-PCIE-16GB [0xb271];3;22;16;9;30000;1629.0;25;22;1;7;0;1;0;0;0;0;1;1;2;0;1 -Tesla V100-PCIE-16GB [0xb271];3;22;16;16;30000;2019.3;30;22;1;1;0;-2;0;0;0;0;1;1;2;3;0 -Tesla V100-PCIE-16GB [0xb271];3;22;16;22;30000;2279.6;50;22;1;9;0;0;0;1;0;1;1;1;1;2;0 -Tesla V100-PCIE-16GB [0xb271];3;22;22;9;30000;2034.8;50;22;1;6;0;1;1;1;0;0;1;1;1;3;0 -Tesla V100-PCIE-16GB [0xb271];3;22;22;16;30000;1982.0;40;22;1;15;0;-2;0;1;0;0;1;1;2;0;2 -Tesla V100-PCIE-16GB [0xb271];3;22;22;22;30000;2292.6;24;22;1;19;0;0;-2;1;0;0;1;1;2;0;0 -Tesla V100-PCIE-16GB [0xb271];3;22;22;32;30000;1891.9;14;22;1;14;0;-1;-1;0;0;1;1;0;2;3;2 -Tesla V100-PCIE-16GB [0xb271];3;22;32;9;30000;2402.7;40;22;1;13;0;1;0;1;0;0;1;1;1;0;0 -Tesla V100-PCIE-16GB [0xb271];3;22;32;22;30000;2739.0;50;22;1;15;0;-1;0;1;0;1;1;1;1;2;0 -Tesla V100-PCIE-16GB [0xb271];3;22;32;32;30000;3198.7;50;22;1;15;0;1;0;0;0;1;1;1;2;0;0 -Tesla V100-PCIE-16GB [0xb271];3;23;23;23;30000;2459.7;50;23;1;14;0;0;0;1;0;1;1;1;1;3;0 -Tesla V100-PCIE-16GB [0xb271];3;24;24;24;30000;2071.2;38;24;1;21;0;0;0;0;0;1;1;1;2;3;0 -Tesla V100-PCIE-16GB [0xb271];3;24;24;26;30000;2642.7;50;24;1;20;0;-1;0;1;0;0;1;1;1;3;0 -Tesla V100-PCIE-16GB [0xb271];3;24;24;32;30000;2244.6;50;24;1;17;0;-1;1;0;0;0;1;1;2;0;2 -Tesla V100-PCIE-16GB [0xb271];3;24;26;24;30000;2711.3;50;24;1;20;0;1;-2;0;0;1;1;1;2;3;0 -Tesla V100-PCIE-16GB [0xb271];3;24;26;26;30000;2121.7;48;24;1;2;0;1;-1;0;0;0;1;1;1;3;2 -Tesla V100-PCIE-16GB [0xb271];3;24;26;32;30000;2144.4;4;24;1;19;0;0;0;0;0;1;1;1;2;3;0 -Tesla V100-PCIE-16GB [0xb271];3;24;32;24;30000;2902.7;50;24;1;11;0;1;-1;1;0;0;1;0;2;3;2 -Tesla V100-PCIE-16GB [0xb271];3;24;32;26;30000;2408.9;25;24;1;16;0;0;-1;1;0;1;1;1;2;3;2 -Tesla V100-PCIE-16GB [0xb271];3;24;32;32;30000;3031.2;40;24;1;13;0;-1;-2;1;0;0;1;1;2;0;0 -Tesla V100-PCIE-16GB [0xb271];3;25;4;4;30000;291.1;24;25;1;3;0;1;0;0;0;1;1;1;1;0;0 -Tesla V100-PCIE-16GB [0xb271];3;25;4;5;30000;316.7;24;25;1;19;0;0;-2;0;0;0;1;1;1;3;0 -Tesla V100-PCIE-16GB [0xb271];3;25;5;4;30000;328.2;14;25;1;7;0;0;1;1;0;0;1;0;2;0;1 -Tesla V100-PCIE-16GB [0xb271];3;25;25;25;30000;2349.7;24;25;1;1;0;-1;-2;1;0;0;1;0;1;3;0 -Tesla V100-PCIE-16GB [0xb271];3;26;4;4;30000;306.9;1;26;1;26;0;-1;-1;1;0;1;1;1;3;0;0 -Tesla V100-PCIE-16GB [0xb271];3;26;24;24;30000;1976.0;21;26;1;26;0;-1;-1;0;0;1;1;1;2;3;2 -Tesla V100-PCIE-16GB [0xb271];3;26;24;26;30000;2405.2;50;26;1;26;0;1;0;0;0;1;1;0;1;3;0 -Tesla V100-PCIE-16GB [0xb271];3;26;24;32;30000;2449.8;50;26;1;23;0;1;-2;0;0;1;1;1;2;3;0 -Tesla V100-PCIE-16GB [0xb271];3;26;26;24;30000;2180.2;48;26;1;3;0;-2;0;0;0;0;1;1;2;0;2 -Tesla V100-PCIE-16GB [0xb271];3;26;26;26;30000;2978.2;50;26;1;19;0;0;-2;1;0;0;1;1;1;0;0 -Tesla V100-PCIE-16GB [0xb271];3;26;26;32;30000;2410.9;50;26;1;5;0;0;-2;0;0;1;1;0;2;0;1 -Tesla V100-PCIE-16GB [0xb271];3;26;32;24;30000;3304.4;50;26;1;15;0;1;-2;0;0;0;1;0;2;3;0 -Tesla V100-PCIE-16GB [0xb271];3;26;32;26;30000;2762.0;60;26;1;18;0;-1;-2;1;0;1;1;0;2;2;0 -Tesla V100-PCIE-16GB [0xb271];3;26;32;32;30000;2593.6;32;26;1;26;0;-1;0;0;0;1;1;1;2;3;0 -Tesla V100-PCIE-16GB [0xb271];3;28;4;4;30000;271.5;14;28;1;18;0;-1;-2;0;0;1;1;1;1;3;2 -Tesla V100-PCIE-16GB [0xb271];3;28;28;28;30000;2548.1;50;28;1;1;0;0;-2;1;0;0;1;1;2;3;0 -Tesla V100-PCIE-16GB [0xb271];3;30;30;30;30000;2542.6;32;30;1;30;0;-1;0;0;0;0;1;0;2;0;0 -Tesla V100-PCIE-16GB [0xb271];3;32;24;24;30000;2442.3;40;32;1;24;0;1;0;0;0;1;1;1;2;3;0 -Tesla V100-PCIE-16GB [0xb271];3;32;24;26;30000;2213.6;16;32;1;17;0;1;-2;0;0;1;1;1;2;3;0 -Tesla V100-PCIE-16GB [0xb271];3;32;24;32;30000;1755.0;1;32;1;12;0;0;0;0;0;0;1;0;2;2;0 -Tesla V100-PCIE-16GB [0xb271];3;32;26;24;30000;2360.4;32;32;1;32;0;1;0;0;0;1;1;0;2;3;0 -Tesla V100-PCIE-16GB [0xb271];3;32;26;26;30000;2579.2;40;32;1;31;0;-1;0;1;0;1;1;1;2;3;0 -Tesla V100-PCIE-16GB [0xb271];3;32;26;32;30000;2487.2;40;32;1;29;0;0;0;1;0;0;1;0;2;3;0 -Tesla V100-PCIE-16GB [0xb271];3;32;32;9;30000;2755.0;50;32;1;22;0;1;-2;0;0;0;1;0;1;0;0 -Tesla V100-PCIE-16GB [0xb271];3;32;32;22;30000;2680.6;32;32;1;31;0;-1;0;1;0;1;1;1;1;0;0 -Tesla V100-PCIE-16GB [0xb271];3;32;32;24;30000;2742.6;54;32;1;22;0;0;-2;1;0;1;1;1;1;2;0 -Tesla V100-PCIE-16GB [0xb271];3;32;32;26;30000;3464.2;50;32;1;27;0;-1;0;0;0;1;1;0;1;3;0 -Tesla V100-PCIE-16GB [0xb271];3;32;32;32;30000;3267.1;50;32;1;31;0;1;-2;1;0;0;1;1;2;3;0 -Tesla V100-PCIE-16GB [0xb271];3;35;35;35;30000;2236.7;9;35;1;25;0;0;-2;0;0;1;1;1;2;0;0 -Tesla V100-PCIE-16GB [0xb271];3;36;36;36;30000;2138.9;71;36;1;1;0;1;-2;1;0;0;1;0;1;0;0 -Tesla V100-PCIE-16GB [0xb271];3;40;40;40;30000;2291.0;9;40;1;1;0;0;0;1;0;0;1;1;2;2;0 -Tesla V100-PCIE-16GB [0xb271];3;45;45;45;30000;2754.3;50;45;1;29;0;0;0;1;0;0;1;1;1;3;0 +Tesla V100-PCIE-16GB [0xb271];3;2;2;2;30000;35.1;12;1;1;2;0;-1;1;0;0;1;1;0;0;0;0;0 +Tesla V100-PCIE-16GB [0xb271];3;3;3;3;30000;93.7;12;3;1;3;0;-2;-1;0;0;0;1;0;0;0;0;0 +Tesla V100-PCIE-16GB [0xb271];3;4;4;4;30000;192.8;12;4;1;4;0;-2;0;0;0;0;1;0;1;0;0;0 +Tesla V100-PCIE-16GB [0xb271];3;4;4;5;30000;209.3;12;4;1;3;0;-2;0;0;0;1;1;0;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;4;4;7;30000;240.6;15;4;1;4;0;-1;-1;0;0;1;1;0;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;4;4;9;30000;254.8;8;4;1;2;0;-1;-1;0;0;0;1;0;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;4;4;10;30000;264.8;13;4;1;4;0;-2;0;0;0;0;1;0;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;4;4;13;30000;282.9;15;4;1;3;0;0;-1;0;0;1;1;0;1;0;0;0 +Tesla V100-PCIE-16GB [0xb271];3;4;4;15;30000;283.7;12;4;1;2;0;-2;-1;0;0;1;0;0;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;4;4;25;30000;310.8;25;4;1;4;0;0;-1;0;0;0;1;0;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;4;4;26;30000;308.3;4;4;1;2;0;-2;1;0;0;0;1;1;1;0;0;0 +Tesla V100-PCIE-16GB [0xb271];3;4;4;28;30000;316.8;25;4;1;4;0;0;0;0;0;0;1;0;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;4;4;32;30000;318.9;3;4;1;2;0;0;-2;0;0;0;1;1;1;0;0;0 +Tesla V100-PCIE-16GB [0xb271];3;4;5;4;30000;216.7;8;4;1;3;0;-1;0;0;0;0;1;0;0;0;0;0 +Tesla V100-PCIE-16GB [0xb271];3;4;5;5;30000;226.0;12;4;1;4;0;-1;0;0;0;0;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;4;5;7;30000;274.4;12;4;1;4;0;1;0;0;0;0;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;4;5;9;30000;302.3;12;4;1;4;0;-2;0;1;0;0;1;0;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;4;5;13;30000;337.3;15;4;1;2;0;0;0;0;0;0;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;4;5;25;30000;386.3;15;4;1;2;0;1;-1;0;0;0;1;1;1;0;0;0 +Tesla V100-PCIE-16GB [0xb271];3;4;7;4;30000;290.9;15;4;1;4;0;-1;-1;1;0;1;1;0;0;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;4;7;5;30000;311.1;12;4;1;3;0;-2;-1;0;0;1;1;1;1;0;0;0 +Tesla V100-PCIE-16GB [0xb271];3;4;7;7;30000;381.1;12;4;1;4;0;-2;-1;0;0;0;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;4;7;9;30000;423.7;12;4;1;3;0;-1;-1;0;0;0;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;4;7;13;30000;460.8;15;4;1;2;0;-2;0;0;0;1;1;1;1;0;0;0 +Tesla V100-PCIE-16GB [0xb271];3;4;9;4;30000;353.8;15;4;1;1;0;-2;-1;1;0;0;1;0;2;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;4;9;5;30000;387.9;12;4;1;4;0;-1;0;1;0;0;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;4;9;7;30000;481.5;12;4;1;2;0;1;-2;0;0;0;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;4;9;9;30000;531.4;12;4;1;4;0;-1;-1;0;0;0;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;4;9;13;30000;587.2;15;4;1;2;0;0;1;0;0;0;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;4;10;4;30000;394.9;15;4;1;2;0;0;-1;1;0;1;1;0;0;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;4;10;10;30000;593.4;13;4;1;2;0;1;1;0;0;1;1;1;1;0;0;0 +Tesla V100-PCIE-16GB [0xb271];3;4;13;4;30000;460.4;20;4;1;2;0;1;1;1;0;1;1;0;0;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;4;13;5;30000;491.0;12;4;1;4;0;-2;-1;0;0;0;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;4;13;7;30000;606.8;13;4;1;2;0;1;-1;0;0;0;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;4;13;9;30000;659.9;15;4;1;2;0;-2;-1;1;0;0;1;1;1;0;0;0 +Tesla V100-PCIE-16GB [0xb271];3;4;15;4;30000;484.4;24;4;1;4;0;-2;-1;0;0;1;1;1;0;0;0;0 +Tesla V100-PCIE-16GB [0xb271];3;4;25;4;30000;672.2;24;4;1;1;0;-2;0;1;0;1;1;0;2;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;4;25;5;30000;741.7;24;4;1;4;0;-1;-2;1;0;1;1;1;0;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;4;26;4;30000;692.1;20;4;1;2;0;-1;-1;1;0;1;1;0;0;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;4;28;4;30000;720.9;25;4;1;1;0;0;0;1;0;1;1;0;2;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;4;32;4;30000;760.2;24;4;1;4;0;0;-2;1;0;1;1;0;0;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;5;4;4;30000;242.9;12;5;1;2;0;0;0;0;0;0;1;0;0;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;5;4;5;30000;247.6;20;5;1;5;0;1;-1;0;0;0;1;0;2;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;5;4;7;30000;282.4;12;5;1;5;0;0;1;0;0;0;1;1;2;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;5;4;9;30000;303.9;12;5;1;4;0;-2;-1;0;0;1;1;0;0;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;5;4;13;30000;245.5;7;5;1;2;0;-2;1;1;0;0;1;1;1;0;0;0 +Tesla V100-PCIE-16GB [0xb271];3;5;4;25;30000;375.3;20;5;1;3;0;1;-1;1;0;0;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;5;5;4;30000;257.8;14;5;1;2;0;-1;0;0;0;0;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;5;5;5;30000;300.3;15;5;1;2;0;-1;-2;0;0;1;1;0;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;5;5;7;30000;338.9;20;5;1;3;0;-1;-2;0;0;0;1;0;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;5;5;9;30000;364.9;20;5;1;2;0;-1;1;0;0;1;1;0;1;0;0;0 +Tesla V100-PCIE-16GB [0xb271];3;5;5;13;30000;393.2;20;5;1;5;0;-1;-1;0;0;0;1;0;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;5;7;4;30000;314.7;12;5;1;2;0;-1;0;0;0;0;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;5;7;5;30000;360.8;12;5;1;4;0;1;-2;1;0;1;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;5;7;7;30000;435.2;12;5;1;2;0;-2;0;1;0;1;1;1;1;0;0;0 +Tesla V100-PCIE-16GB [0xb271];3;5;7;9;30000;479.6;13;5;1;3;0;1;-2;0;0;0;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;5;7;13;30000;523.5;12;5;1;5;0;-1;0;1;0;0;1;0;1;0;0;0 +Tesla V100-PCIE-16GB [0xb271];3;5;9;4;30000;386.9;12;5;1;3;0;-1;-1;1;0;0;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;5;9;5;30000;454.4;12;5;1;4;0;0;-2;1;0;0;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;5;9;7;30000;551.2;12;5;1;5;0;-2;0;0;0;1;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;5;9;9;30000;596.0;13;5;1;3;0;1;-2;0;0;0;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;5;13;4;30000;498.9;13;5;1;3;0;-1;0;1;0;0;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;5;13;5;30000;569.6;12;5;1;5;0;1;0;1;0;0;1;1;1;0;0;0 +Tesla V100-PCIE-16GB [0xb271];3;5;13;7;30000;699.9;13;5;1;4;0;-2;-2;1;0;1;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;5;13;13;30000;844.8;20;5;1;4;0;0;0;0;0;0;1;1;1;0;0;0 +Tesla V100-PCIE-16GB [0xb271];3;5;25;4;30000;593.2;11;5;1;5;0;0;0;0;0;0;1;1;0;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;7;5;5;30000;399.0;16;2;1;5;0;-1;-2;0;0;0;1;0;0;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;7;5;7;30000;438.8;20;2;1;3;0;0;-1;0;0;1;1;1;0;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;7;7;5;30000;506.3;15;1;2;6;0;-1;-2;1;0;1;1;0;2;0;0;0 +Tesla V100-PCIE-16GB [0xb271];3;7;7;7;30000;531.5;20;2;1;4;0;1;-2;1;0;1;1;0;0;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;7;7;13;30000;635.9;24;7;1;5;0;-1;0;0;0;0;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;7;13;13;30000;1037.5;20;7;1;5;0;0;-2;1;0;0;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;9;9;13;30000;905.3;25;9;1;7;0;0;0;0;0;0;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;9;13;9;30000;1027.6;20;9;1;2;0;0;0;0;0;0;1;1;1;0;0;0 +Tesla V100-PCIE-16GB [0xb271];3;9;13;13;30000;1136.0;20;9;1;8;0;1;-1;0;0;0;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;9;16;16;30000;1367.4;24;9;1;2;0;1;-1;1;0;0;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;9;22;16;30000;1569.6;24;9;1;6;0;-1;0;0;0;0;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;9;22;22;30000;1665.8;25;9;1;5;0;-2;-2;1;0;0;1;1;1;0;0;0 +Tesla V100-PCIE-16GB [0xb271];3;9;32;9;30000;1604.0;30;9;1;2;0;0;-1;1;0;0;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;9;32;22;30000;1944.9;50;9;1;4;0;0;1;1;0;0;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;9;32;32;30000;2154.3;50;9;1;3;0;0;0;0;0;0;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;13;5;5;30000;515.2;25;3;1;7;0;0;1;1;0;0;1;1;2;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;13;5;7;30000;547.3;13;3;1;8;0;0;1;0;0;1;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;13;5;13;30000;596.1;24;2;1;2;0;0;-2;1;0;0;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;13;7;5;30000;636.4;18;2;2;4;0;0;1;1;0;1;1;1;2;2;1;0 +Tesla V100-PCIE-16GB [0xb271];3;13;7;13;30000;811.2;12;13;1;12;0;0;0;0;0;0;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;13;9;9;30000;857.9;20;13;1;3;0;0;0;0;0;0;1;0;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;13;9;13;30000;885.8;25;13;1;2;0;1;0;0;0;0;1;1;1;0;0;0 +Tesla V100-PCIE-16GB [0xb271];3;13;13;5;30000;1009.6;24;13;1;8;0;1;0;1;0;0;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;13;13;7;30000;1189.4;25;13;1;10;0;1;-1;1;0;0;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;13;13;9;30000;1294.8;24;13;1;10;0;-1;-2;1;0;0;1;1;1;0;0;0 +Tesla V100-PCIE-16GB [0xb271];3;13;13;13;30000;1351.9;25;13;1;10;0;-1;0;0;0;0;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;16;9;16;30000;1054.4;12;16;1;4;0;-1;-2;1;0;1;1;1;0;0;0;0 +Tesla V100-PCIE-16GB [0xb271];3;16;9;22;30000;1094.0;25;16;1;5;0;0;-2;0;0;0;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;16;16;9;30000;1631.8;25;16;1;2;0;-1;-1;1;0;0;1;0;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;16;16;16;30000;1809.8;25;16;1;16;0;0;0;0;0;1;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;16;16;22;30000;1847.2;50;16;1;12;0;1;-2;1;0;1;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;16;22;9;30000;1783.9;25;16;1;6;0;-2;-1;1;0;1;1;0;1;0;0;0 +Tesla V100-PCIE-16GB [0xb271];3;16;22;16;30000;1999.5;40;16;1;16;0;-1;-2;0;0;1;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;16;22;22;30000;1934.5;25;16;1;14;0;0;0;0;0;0;1;0;1;2;1;0 +Tesla V100-PCIE-16GB [0xb271];3;20;20;20;30000;1986.9;40;20;1;13;0;1;-2;1;0;1;1;0;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;22;9;9;30000;809.5;20;22;1;17;0;-1;0;0;0;0;1;1;1;2;1;0 +Tesla V100-PCIE-16GB [0xb271];3;22;9;16;30000;1256.9;26;22;1;1;0;-2;-1;1;0;0;1;0;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;22;9;22;30000;1271.4;30;22;1;1;0;-2;1;0;0;0;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;22;9;32;30000;1371.7;24;22;1;1;0;0;-2;1;0;1;1;0;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;22;16;9;30000;1629.0;25;22;1;7;0;1;0;0;0;0;1;1;1;0;1;0 +Tesla V100-PCIE-16GB [0xb271];3;22;16;16;30000;2019.3;30;22;1;1;0;-2;0;0;0;0;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;22;16;22;30000;2279.6;50;22;1;9;0;0;0;1;0;1;1;1;1;1;0;0 +Tesla V100-PCIE-16GB [0xb271];3;22;22;9;30000;2034.8;50;22;1;6;0;1;1;1;0;0;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;22;22;16;30000;1982.0;40;22;1;15;0;-2;0;1;0;0;1;1;1;0;1;0 +Tesla V100-PCIE-16GB [0xb271];3;22;22;22;30000;2292.6;24;22;1;19;0;0;-2;1;0;0;1;1;1;0;0;0 +Tesla V100-PCIE-16GB [0xb271];3;22;22;32;30000;1891.9;14;22;1;14;0;-1;-1;0;0;1;1;0;1;2;1;0 +Tesla V100-PCIE-16GB [0xb271];3;22;32;9;30000;2402.7;40;22;1;13;0;1;0;1;0;0;1;1;1;0;0;0 +Tesla V100-PCIE-16GB [0xb271];3;22;32;22;30000;2739.0;50;22;1;15;0;-1;0;1;0;1;1;1;1;1;0;0 +Tesla V100-PCIE-16GB [0xb271];3;22;32;32;30000;3198.7;50;22;1;15;0;1;0;0;0;1;1;1;1;0;0;0 +Tesla V100-PCIE-16GB [0xb271];3;23;23;23;30000;2459.7;50;23;1;14;0;0;0;1;0;1;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;24;24;24;30000;2071.2;38;24;1;21;0;0;0;0;0;1;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;24;24;26;30000;2642.7;50;24;1;20;0;-1;0;1;0;0;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;24;24;32;30000;2244.6;50;24;1;17;0;-1;1;0;0;0;1;1;1;0;1;0 +Tesla V100-PCIE-16GB [0xb271];3;24;26;24;30000;2711.3;50;24;1;20;0;1;-2;0;0;1;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;24;26;26;30000;2121.7;48;24;1;2;0;1;-1;0;0;0;1;1;1;2;1;0 +Tesla V100-PCIE-16GB [0xb271];3;24;26;32;30000;2144.4;4;24;1;19;0;0;0;0;0;1;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;24;32;24;30000;2902.7;50;24;1;11;0;1;-1;1;0;0;1;0;1;2;1;0 +Tesla V100-PCIE-16GB [0xb271];3;24;32;26;30000;2408.9;25;24;1;16;0;0;-1;1;0;1;1;1;1;2;1;0 +Tesla V100-PCIE-16GB [0xb271];3;24;32;32;30000;3031.2;40;24;1;13;0;-1;-2;1;0;0;1;1;1;0;0;0 +Tesla V100-PCIE-16GB [0xb271];3;25;4;4;30000;291.1;24;25;1;3;0;1;0;0;0;1;1;1;1;0;0;0 +Tesla V100-PCIE-16GB [0xb271];3;25;4;5;30000;316.7;24;25;1;19;0;0;-2;0;0;0;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;25;5;4;30000;328.2;14;25;1;7;0;0;1;1;0;0;1;0;1;0;1;0 +Tesla V100-PCIE-16GB [0xb271];3;25;25;25;30000;2349.7;24;25;1;1;0;-1;-2;1;0;0;1;0;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;26;4;4;30000;306.9;1;26;1;26;0;-1;-1;1;0;1;1;1;2;0;0;0 +Tesla V100-PCIE-16GB [0xb271];3;26;24;24;30000;1976.0;21;26;1;26;0;-1;-1;0;0;1;1;1;1;2;1;0 +Tesla V100-PCIE-16GB [0xb271];3;26;24;26;30000;2405.2;50;26;1;26;0;1;0;0;0;1;1;0;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;26;24;32;30000;2449.8;50;26;1;23;0;1;-2;0;0;1;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;26;26;24;30000;2180.2;48;26;1;3;0;-2;0;0;0;0;1;1;1;0;1;0 +Tesla V100-PCIE-16GB [0xb271];3;26;26;26;30000;2978.2;50;26;1;19;0;0;-2;1;0;0;1;1;1;0;0;0 +Tesla V100-PCIE-16GB [0xb271];3;26;26;32;30000;2410.9;50;26;1;5;0;0;-2;0;0;1;1;0;1;0;1;0 +Tesla V100-PCIE-16GB [0xb271];3;26;32;24;30000;3304.4;50;26;1;15;0;1;-2;0;0;0;1;0;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;26;32;26;30000;2762.0;60;26;1;18;0;-1;-2;1;0;1;1;0;1;1;0;0 +Tesla V100-PCIE-16GB [0xb271];3;26;32;32;30000;2593.6;32;26;1;26;0;-1;0;0;0;1;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;28;4;4;30000;271.5;14;28;1;18;0;-1;-2;0;0;1;1;1;1;2;1;0 +Tesla V100-PCIE-16GB [0xb271];3;28;28;28;30000;2548.1;50;28;1;1;0;0;-2;1;0;0;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;30;30;30;30000;2542.6;32;30;1;30;0;-1;0;0;0;0;1;0;1;0;0;0 +Tesla V100-PCIE-16GB [0xb271];3;32;24;24;30000;2442.3;40;32;1;24;0;1;0;0;0;1;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;32;24;26;30000;2213.6;16;32;1;17;0;1;-2;0;0;1;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;32;24;32;30000;1755.0;1;32;1;12;0;0;0;0;0;0;1;0;1;1;0;0 +Tesla V100-PCIE-16GB [0xb271];3;32;26;24;30000;2360.4;32;32;1;32;0;1;0;0;0;1;1;0;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;32;26;26;30000;2579.2;40;32;1;31;0;-1;0;1;0;1;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;32;26;32;30000;2487.2;40;32;1;29;0;0;0;1;0;0;1;0;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;32;32;9;30000;2755.0;50;32;1;22;0;1;-2;0;0;0;1;0;1;0;0;0 +Tesla V100-PCIE-16GB [0xb271];3;32;32;22;30000;2680.6;32;32;1;31;0;-1;0;1;0;1;1;1;1;0;0;0 +Tesla V100-PCIE-16GB [0xb271];3;32;32;24;30000;2742.6;54;32;1;22;0;0;-2;1;0;1;1;1;1;1;0;0 +Tesla V100-PCIE-16GB [0xb271];3;32;32;26;30000;3464.2;50;32;1;27;0;-1;0;0;0;1;1;0;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;32;32;32;30000;3267.1;50;32;1;31;0;1;-2;1;0;0;1;1;1;2;0;0 +Tesla V100-PCIE-16GB [0xb271];3;35;35;35;30000;2236.7;9;35;1;25;0;0;-2;0;0;1;1;1;1;0;0;0 +Tesla V100-PCIE-16GB [0xb271];3;36;36;36;30000;2138.9;71;36;1;1;0;1;-2;1;0;0;1;0;1;0;0;0 +Tesla V100-PCIE-16GB [0xb271];3;40;40;40;30000;2291.0;9;40;1;1;0;0;0;1;0;0;1;1;1;1;0;0 +Tesla V100-PCIE-16GB [0xb271];3;45;45;45;30000;2754.3;50;45;1;29;0;0;0;1;0;0;1;1;1;2;0;0 diff --git a/src/acc/opencl/smm/tune_multiply.py b/src/acc/opencl/smm/tune_multiply.py index b75a90caef0..a6fd8e64f02 100755 --- a/src/acc/opencl/smm/tune_multiply.py +++ b/src/acc/opencl/smm/tune_multiply.py @@ -9,38 +9,36 @@ #################################################################################################### import opentuner from opentuner.search.manipulator import IntegerParameter +from opentuner.tuningrunmain import TuningRunMain from opentuner import ConfigurationManipulator from opentuner import MeasurementInterface from opentuner import Result -from signal import signal, getsignal, SIGINT +from signal import signal, SIGINT +import tempfile +import socket +import shutil +import copy import json import glob +import math import sys import re import os +default_enable_tune = {"tune", "enabled", "on"} default_basename = "tune_multiply" default_mnk = "23x23x23" +default_dbg = False +default_retry = 1 +default_vlen = 8 -def env_isfixed(envname): - strvalue = os.getenv(envname) - if strvalue: - try: - ivalue = int(strvalue) - return ivalue == ivalue - except ValueError: - pass - return False - - -def env_value(envname, default): - strvalue = os.getenv(envname, default) +def env_intvalue(env, default, lookup=True): + value = os.getenv(env, default) if lookup else env if env is not None else default try: - return int(strvalue) + return int(value) except ValueError: - pass - return int(default) + return int(default) def ilog2(n): @@ -52,46 +50,46 @@ def ilog2(n): class SmmTuner(MeasurementInterface): - def manipulator(self): + def __init__(self, args): """Setup common state and define search space""" + super(SmmTuner, self).__init__(args) + dbdir = os.path.join(tempfile.gettempdir(), "opentuner") manipulator = ConfigurationManipulator() # parse and sanitize kernel shape argument if not self.args.mnk: self.args.mnk = default_mnk mnk = tuple(max(int(i), 1) for i in self.args.mnk.split("x")) self.mnk = (mnk + (mnk[0], mnk[0]))[:3] + self.wsx = self.mnk[0] * self.mnk[1] # sanitize input arguments self.args.mb = max(self.args.mb, 1) self.args.bs = max(min(self.args.bs, self.args.mb), 1) self.args.bm = [max(self.args.bm, 1), self.mnk[0]][0 == self.args.bm] self.args.bn = [max(self.args.bn, 1), 1][0 == self.args.bn] self.args.bk = [max(self.args.bk, 1), self.mnk[2]][0 == self.args.bk] - self.args.ws = min(self.args.ws, self.mnk[0] * self.mnk[1]) + self.args.ws = min(self.args.ws, self.wsx) + self.ndevices = self.gfbase = self.gfsave = self.gflops = 0 + self.config = self.typename = self.typeid = self.device = self.size = None self.bs = self.bm = self.bn = self.bk = self.ws = self.wg = self.lu = None self.nz = self.al = self.tb = self.tc = None self.ap = self.aa = self.ab = self.ac = None - self.typename = self.typeid = None - self.device = self.size = None - self.gfbase = self.gflops = 0 - self.config = None + self.idevice = None self.exename = "acc_bench_smm" self.exepath = os.path.join( os.path.dirname(sys.argv[0]), "..", "..", self.exename ) - run_result = ( # verbosity to capture device name and tuned parameters + self.run_result = ( # verbosity to capture device name and tuned parameters self.launch(["ACC_OPENCL_VERBOSE=2", "CHECK=0"], nrep=1) if (self.args.merge is None or 0 > self.args.merge) and (self.args.update is None or "" == self.args.update) else None ) - if run_result: - stdout = str(run_result["stdout"]) + if self.run_result: + stdout = str(self.run_result["stdout"]) if 0 >= self.args.size: - size = re.search( - "{}\\s+[0-9]+\\s+([0-9]+)".format(self.exepath), - stdout, - ) - self.size = int(size.group(1)) if size and size.group(1) else 0 + sizepat = "(\\w+)\\s+[0-9]+\\s+([0-9]+)" + size = re.search(sizepat, stdout) + self.size = int(size.group(2)) if size and size.group(2) else 0 else: self.size = self.args.size typename = re.search("typename \\(id=([0-9]+)\\):\\s+(\\w+)", stdout) @@ -99,60 +97,64 @@ def manipulator(self): self.typeid = ( int(typename.group(1)) if typename and typename.group(1) else 0 ) - device = re.search( - 'INFO ACC/OpenCL:\\s+ndevices=[0-9]+\\s+device[0-9]+="([^"]+)"', - str(run_result["stderr"]), + devicepat = ( + 'INFO ACC/OpenCL:\\s+ndevices=([0-9]+)\\s+device[0-9]+="([^"]+)"' ) - self.device = device.group(1) if device and device.group(1) else "" + device = re.search(devicepat, str(self.run_result["stderr"])) + self.ndevices = int(device.group(1)) if device and device.group(1) else 0 + self.device = device.group(2) if device and device.group(2) else "" elif self.args.update is not None and "" != self.args.update: self.device = self.args.update - if run_result and 0 == run_result["returncode"]: - seedpat = "INFO ACC/OpenCL:\\s+SMM-kernel\\s+{}={}\\s+gen=".format( + if self.run_result and 0 == self.run_result["returncode"]: + seedpat = "INFO ACC/LIBSMM:\\s+SMM-kernel\\s+{}={}\\s+gen=".format( "{t,m,n,k, bs,bm,bn,bk, ws,wg, lu,nz,al, tb,tc, ap,aa,ab,ac}", "{{{}, {}}}".format( # key and value - "{},{},{},{}".format( # t,m,n,k (key) - self.typeid, self.mnk[0], self.mnk[1], self.mnk[2] + "{},{}".format( # t,m,n,k (key) + self.typeid, ",".join(map(str, self.mnk)) ), - "{}, {}, {}, {}, {}".format( # value: some can be neg. hence "-*[0-9]+" + "{}, {}, {}, {}, {}".format( # value: if neg. "-*[0-9]+" "(-*[0-9]+),(-*[0-9]+),(-*[0-9]+),(-*[0-9]+)", # bs,bm,bn,bk "(-*[0-9]+),(-*[0-9]+)", # ws,wg "(-*[0-9]+),(-*[0-9]+),(-*[0-9]+)", # lu,nz,al "(-*[0-9]+),(-*[0-9]+)", # tb,tc - "(-*[0-9]+),(-*[0-9]+),(-*[0-9]+),(-*[0-9]+)", # ap,aa,ab,ac + "(-*[0-9]+),(-*[0-9]+),(-*[0-9]+),(-*[0-9]+)(, .+)*", # ap,aa,ab,ac[, ext] ), ), ) - seed = re.search(seedpat, str(run_result["stderr"])) - if 15 != (len(seed.groups()) if seed else 0): + seed = re.search(seedpat, str(self.run_result["stderr"])) + nprm = len(seed.groups()) if seed else 0 + if 15 > nprm: print("WARNING: missed to parse initial parameters!") + maxlu = (self.mnk[0] + default_vlen - 1) / default_vlen # setup fixed and tunable parameters params, paramt = [], [] self.create_param("BS", params, paramt, seed, 1, 1, self.args.mb) self.create_param("BM", params, paramt, seed, 2, 1, self.mnk[0]) self.create_param("BN", params, paramt, seed, 3, 1, self.mnk[1]) self.create_param("BK", params, paramt, seed, 4, 1, self.mnk[0]) - self.create_param( - "WS", params, paramt, seed, 5, 1, self.mnk[0] * self.mnk[1] - ) - self.create_param("WG", params, paramt, seed, 6, -2, 1) # avoid WG=2 - self.create_param("LU", params, paramt, seed, 7, -2, 2) + self.create_param("WS", params, paramt, seed, 5, 1, self.wsx) + self.create_param("WG", params, paramt, seed, 6, -2, 1, False) # avoid WG=2 + self.create_param("LU", params, paramt, seed, 7, -2, maxlu) self.create_param("NZ", params, paramt, seed, 8, 0, 1) self.create_param("AL", params, paramt, seed, 9, 0, 1) self.create_param("TB", params, paramt, seed, 10, 0, 1) self.create_param("TC", params, paramt, seed, 11, 0, 1) self.create_param("AP", params, paramt, seed, 12, 0, 1) - self.create_param("AA", params, paramt, seed, 13, 0, 3) - self.create_param("AB", params, paramt, seed, 14, 0, 3) - self.create_param("AC", params, paramt, seed, 15, 0, 2) + self.create_param("AA", params, paramt, seed, 13, 0, 2) + self.create_param("AB", params, paramt, seed, 14, 0, 2) + self.create_param("AC", params, paramt, seed, 15, 0, 1) + if 15 < nprm and seed.group(16) and 2 < len(seed.group(16)): + self.create_param("XF", params, paramt, seed.group(16)[2:], -1, 0, 1) + else: + self.create_param("XF", params, paramt, 0, -1, 0, 1) if not paramt: sys.tracebacklimit = 0 raise RuntimeError( - "All tunable parameters are fixed with environment variables!" + "All parameters are fixed with environment variables!" ) for param in params + paramt: manipulator.add_parameter(param) - # consider to update and/or merge JSONS (update first) - if ( + if ( # consider to update and/or merge JSONS (update first) (self.args.merge is not None and (0 <= self.args.merge or self.typeid)) or self.args.update is None or "" != self.args.update @@ -169,16 +171,27 @@ def manipulator(self): elif ( (self.typename and "" != self.typename) and (self.device and "" != self.device) + and (self.typeid and 0 < self.ndevices) and (self.size and 0 < self.size) - and self.typeid - ): # construct label used for the database session - if not self.args.label: # consider to include self.device - self.args.label = "{}-{}-{}x{}x{}-s{}".format( + ): # setup database (DB) + if args.database is None: # adjust DB-location + envrank = os.getenv("PMI_RANK", os.getenv("OMPI_COMM_WORLD_LOCAL_RANK")) + if envrank: + self.idevice = int(envrank) % self.ndevices + directory = "{}-{}.db".format(dbdir, self.idevice) + else: + directory = "{}.db".format(dbdir) + if os.path.isdir(directory): + shutil.rmtree(directory) + os.mkdir(directory) + self.args.database = "sqlite:///" + os.path.join( + directory, "{}.db".format(socket.gethostname()) + ) + if not self.args.label: # label for DB-session + self.args.label = "{}-{}-{}-s{}".format( default_basename, self.typename, - self.mnk[0], - self.mnk[1], - self.mnk[2], + "x".join(map(str, self.mnk)), ilog2(self.size), ) else: @@ -186,35 +199,60 @@ def manipulator(self): raise RuntimeError("Setup failed for {}!".format(self.exepath)) # register signal handler (CTRL-C) signal(SIGINT, self.handle_sigint) - return manipulator + self.handle_sigint_counter = 0 + self.manip = manipulator - def create_param(self, name, params, paramt, match, match_id, value0, value1): + def manipulator(self): + return self.manip + + def create_param( + self, name, params, paramt, match, match_id, value0, value1, expand=True + ): """Append integer-parameter to either params or paramt list""" - if env_isfixed("OPENCL_LIBSMM_SMM_{}".format(name)): - value_fix = getattr(self.args, name.lower()) - params.append(IntegerParameter(name, value_fix, value_fix)) + value_key = "OPENCL_LIBSMM_SMM_{}".format(name) + value_env = os.getenv(value_key) + attribute = getattr(self, name.lower(), None) + tunable = value_env in default_enable_tune + if 0 <= match_id: + if match and match.group(match_id): + value = int(match.group(match_id)) + else: + value = 0 if value_env is None else int(value_env) + if not tunable: + tunable = value_env is None else: - value = ( - int(match.group(match_id)) if match and match.group(match_id) else None - ) + if attribute is None: + value = getattr(self.args, name.lower(), None) + if value is None: + value = int(value_env if match is None else match) + else: + value = int(attribute) + if not tunable: + tunable = value_env is None and 0 != value + if tunable: # consider expanding value range according to seed + v0 = min(value0, value) if expand else value0 + v1 = max(value1, value) if expand else value1 + paramt.append(IntegerParameter(name, v0, v1)) + else: # fixed parameter + params.append(IntegerParameter(name, value, value)) + if attribute is None: setattr(self, name.lower(), value) - paramt.append(IntegerParameter(name, value0, value1)) def launch(self, envs, nrep=None, verbose=None): """Launch executable supplying environment and arguments""" envstrs = " ".join(map(str, envs)) if verbose is not None and 0 != int(verbose): print(envstrs.replace("OPENCL_LIBSMM_SMM_", "").replace(" CHECK=0", "")) - return self.call_program( - "OMP_PROC_BIND=TRUE OPENCL_LIBSMM_SMM_S=0 {} {} {} {} {}".format( - envstrs, # environment variables - "{}".format(self.exepath), - # executable's arguments - self.args.r if nrep is None else nrep, - self.size if self.size else self.args.size, - "{} {} {}".format(self.mnk[0], self.mnk[1], self.mnk[2]), - ) + env_defaults = "OMP_PROC_BIND=TRUE OPENCL_LIBSMM_SMM_S=0 NEO_CACHE_PERSISTENT=0" + env_exe_args = "{} {} {} {} {} {}".format( # consider device-id + "" if self.idevice is None else "ACC_OPENCL_DEVICE={}".format(self.idevice), + "{} {}".format(env_defaults, envstrs), # environment + self.exepath, # executable file + self.args.r if nrep is None else nrep, + self.size if self.size else self.args.size, + " ".join(map(str, self.mnk)), ) + return self.call_program(env_exe_args) def seed_configurations(self): return [ @@ -234,6 +272,7 @@ def seed_configurations(self): "AA": self.aa if self.aa is not None else self.args.aa, "AB": self.ab if self.ab is not None else self.args.ab, "AC": self.ac if self.ac is not None else self.args.ac, + "XF": self.xf if self.xf is not None else 0, } ] @@ -245,35 +284,22 @@ def objective(self): def environment(self, config): return [ - "OPENCL_LIBSMM_SMM_BS={}".format(config["BS"]), - "OPENCL_LIBSMM_SMM_BM={}".format(config["BM"]), - "OPENCL_LIBSMM_SMM_BN={}".format(config["BN"]), - "OPENCL_LIBSMM_SMM_BK={}".format(config["BK"]), - "OPENCL_LIBSMM_SMM_WS={}".format(config["WS"]), - "OPENCL_LIBSMM_SMM_WG={}".format(config["WG"]), - "OPENCL_LIBSMM_SMM_LU={}".format(config["LU"]), - "OPENCL_LIBSMM_SMM_NZ={}".format(config["NZ"]), - "OPENCL_LIBSMM_SMM_AL={}".format(config["AL"]), - "OPENCL_LIBSMM_SMM_TB={}".format(config["TB"]), - "OPENCL_LIBSMM_SMM_TC={}".format(config["TC"]), - "OPENCL_LIBSMM_SMM_AP={}".format(config["AP"]), - "OPENCL_LIBSMM_SMM_AA={}".format(config["AA"]), - "OPENCL_LIBSMM_SMM_AB={}".format(config["AB"]), - "OPENCL_LIBSMM_SMM_AC={}".format(config["AC"]), + "OPENCL_LIBSMM_SMM_{}={}".format(key, config[key]) + for key in sorted(config.keys()) + if 2 == len(key) ] def run(self, desired_result, input, limit): """Run a configuration and return performance""" config = desired_result.configuration.data cfgenv = self.environment(config) - run_result = self.launch( - cfgenv + ["CHECK={}".format(self.args.check)], - verbose=self.args.verbose, + self.run_result = self.launch( + cfgenv + ["CHECK={}".format(self.args.check)], verbose=self.args.verbose ) - if 0 == run_result["returncode"]: + if 0 == self.run_result["returncode"]: performance = re.search( "device:\\s+([0-9]+[^ ]*) ms\\s+([0-9]+[^ ]*)", - str(run_result["stdout"]), + str(self.run_result["stdout"]), ) else: failed = " ".join(map(str, cfgenv)).replace("OPENCL_LIBSMM_SMM_", "") @@ -288,10 +314,9 @@ def run(self, desired_result, input, limit): self.gflops = gflops if 0 == self.gfbase: # seed configuration self.gfbase = gflops - self.save_final_config(desired_result.configuration, final=False) - kernelreq = round( - (100.0 * config["BM"] * config["BN"]) / (self.mnk[0] * self.mnk[1]) - ) + else: + self.save_final_config(desired_result.configuration, final=False) + kernelreq = round((100.0 * config["BM"] * config["BN"]) / self.wsx) # gflops are reported as "accuracy" (console output) return Result(time=mseconds, accuracy=gflops, size=kernelreq) else: # return non-competitive/bad result in case of an error @@ -324,109 +349,162 @@ def update_jsons(self, filenames): def merge_jsons(self, filenames): """Merge all JSONs into a single CSV-file""" - if self.args.csvfile: - merged, worse = dict(), dict() - for filename in filenames: - try: - data = dict() - with open(filename, "r") as file: - data = json.load(file) - if self.args.merge is not None and ( - (0 > self.args.merge and self.typeid != data["TYPEID"]) - or (1 == self.args.merge and 1 != data["TYPEID"]) - or (2 == self.args.merge and 3 != data["TYPEID"]) - ): - continue - device = data["DEVICE"] if "DEVICE" in data else self.device - key = ( - device, - data["TYPEID"], - data["M"], - data["N"], - data["K"], - ) - value = ( - data["S"] if "S" in data else 0, # pseudo key component + if not self.args.csvfile or (self.idevice is not None and 0 != self.idevice): + return # early exit + merged, worse = dict(), dict() + for filename in filenames: + try: + data = dict() + with open(filename, "r") as file: + data = json.load(file) + if self.args.merge is not None and ( + (0 > self.args.merge and self.typeid != data["TYPEID"]) + or (1 == self.args.merge and 1 != data["TYPEID"]) + or (2 == self.args.merge and 3 != data["TYPEID"]) + ): + continue + device = data["DEVICE"] if "DEVICE" in data else self.device + key = (device, data["TYPEID"], data["M"], data["N"], data["K"]) + value = ( + data["S"] if "S" in data else 0, # pseudo key component + ( data["GFLOPS"] if "GFLOPS" in data and not self.args.nogflops - else 0, - data["BS"], - data["BM"], - data["BN"], - data["BK"] if "BK" in data else 0, - data["WS"] if "WS" in data else 0, - data["WG"] if "WG" in data else 0, - data["LU"] if "LU" in data else 0, - data["NZ"] if "NZ" in data else 0, - data["AL"] if "AL" in data else 0, - data["TB"] if "TB" in data else 0, - data["TC"] if "TC" in data else 1, - data["AP"] if "AP" in data else 0, - data["AA"] if "AA" in data else 1, - data["AB"] if "AB" in data else 3, - data["AC"] if "AC" in data else 0, - filename, # last entry - ) - if key not in merged: + else 0 + ), + data["BS"], + data["BM"], + data["BN"], + data["BK"] if "BK" in data else 0, + data["WS"] if "WS" in data else 0, + data["WG"] if "WG" in data else 0, + data["LU"] if "LU" in data else 0, + data["NZ"] if "NZ" in data else 0, + data["AL"] if "AL" in data else 0, + data["TB"] if "TB" in data else 0, + data["TC"] if "TC" in data else 1, + data["AP"] if "AP" in data else 0, + data["AA"] if "AA" in data else 0, + data["AB"] if "AB" in data else 0, + data["AC"] if "AC" in data else 0, + data["XF"] if "XF" in data else 0, + filename, # last entry + ) + if key not in merged: + merged[key] = value + else: + filename2 = merged[key][-1] + if merged[key][1] <= value[1]: # GFLOPS merged[key] = value else: - filename2 = merged[key][-1] - if merged[key][1] <= value[1]: # GFLOPS - merged[key] = value - else: - filename2 = filename - if key in worse: - worse[key].append(filename2) - else: - worse[key] = [filename2] - except (json.JSONDecodeError, KeyError, TypeError): - print("Failed to merge {} into CSV-file.".format(filename)) - if bool(merged): - with open(self.args.csvfile, "w") as file: - file.write( # CSV header line with termination/newline - "{}{}{}{}{}{}{}{}{}\n".format( # key-part - self.args.csvsep.join(["DEVICE", "TYPEID", "M", "N", "K"]), - self.args.csvsep, # separator for value-part - "S", # pseudo-key component - self.args.csvsep, - self.args.csvsep.join(["GFLOPS", "BS", "BM", "BN", "BK"]), - self.args.csvsep, - self.args.csvsep.join(["WS", "WG", "LU", "NZ", "AL"]), - self.args.csvsep, - self.args.csvsep.join(["TB", "TC", "AP", "AA", "AB", "AC"]), - ) - ) - for key, value in sorted(merged.items()): # CSV data lines - strkey = self.args.csvsep.join([str(k) for k in key]) - strval = self.args.csvsep.join([str(v) for v in value[:-1]]) - file.write("{}{}{}\n".format(strkey, self.args.csvsep, strval)) - retain, delete = [], [] - for key, value in worse.items(): - mtime = os.path.getmtime(merged[key][-1]) - for filename in value: - if mtime < os.path.getmtime(filename): - retain.append(filename) - else: - delete.append(filename) - if retain: - print("Worse and newer (retain): {}".format(" ".join(retain))) - if delete: - print("Worse and older (delete): {}".format(" ".join(delete))) - print( - "Merged {} of {} JSONs into {}".format( - len(merged), len(filenames), self.args.csvfile + filename2 = filename + if key in worse: + worse[key].append(filename2) + else: + worse[key] = [filename2] + except (json.JSONDecodeError, KeyError, TypeError): + print("Failed to merge {} into CSV-file.".format(filename)) + except: # noqa: E722 + pass + if bool(merged): + with open(self.args.csvfile, "w") as file: + file.write( # CSV header line with termination/newline + "{}{}{}{}{}{}{}{}{}\n".format( # key-part + self.args.csvsep.join(["DEVICE", "TYPEID", "M", "N", "K"]), + self.args.csvsep, # separator for value-part + "S", # pseudo-key component + self.args.csvsep, + self.args.csvsep.join(["GFLOPS", "BS", "BM", "BN", "BK"]), + self.args.csvsep, + self.args.csvsep.join(["WS", "WG", "LU", "NZ", "AL"]), + self.args.csvsep, + self.args.csvsep.join(["TB", "TC", "AP", "AA", "AB", "AC"]), ) ) - elif glob.glob(self.args.csvfile): - backup = "{}.bak".format(self.args.csvfile) - print("Renamed {} to {}.".format(self.args.csvfile, backup)) - os.rename(self.args.csvfile, backup) + for key, value in sorted(merged.items()): # CSV data lines + strkey = self.args.csvsep.join([str(k) for k in key]) + strval = self.args.csvsep.join([str(v) for v in value[:-1]]) + file.write("{}{}{}\n".format(strkey, self.args.csvsep, strval)) + retsld, delsld = [0, 0, 0], [0, 0, 0] # [min, geo, max] + retain, delete = [], [] # lists of filenames + retcnt = delcnt = 0 # geo-counter + retbad = None + for key, value in worse.items(): + gflops = round(merged[key][1]) + mtime = os.path.getmtime(merged[key][-1]) + for filename in value: + s = 0 + if 0 < gflops: + g = int(filename.split("-")[-1].split("g")[0]) + s = gflops / g # slowdown + if mtime < os.path.getmtime(filename): + if 0 < s: + retsld[1] = retsld[1] + math.log(s) + retsld[0] = min(retsld[0], s) if 0 < retsld[0] else s + if retsld[2] < s: # maximum + retmnk = os.path.basename(filename).split("-") + retbad = retmnk[2] if 2 < len(retmnk) else None + retsld[2] = s + retcnt = retcnt + 1 + retain.append(filename) + else: + if 0 < s: + delsld[1] = delsld[1] + math.log(s) + delsld[0] = min(delsld[0], s) if 0 < delsld[0] else s + delsld[2] = max(delsld[2], s) + delcnt = delcnt + 1 + delete.append(filename) + if not self.args.nogflops: + retsld[1] = math.exp(retsld[1] / retcnt) if 0 < retcnt else 1 + delsld[1] = math.exp(delsld[1] / delcnt) if 0 < delcnt else 1 + if not self.args.delete: + if retain: + num, lst = len(retain), " ".join(retain) + msg = "Worse and newer (retain {} @ {}x{}): {}" + rnd = [str(round(i, 2)) for i in retsld] + bad = " " + retbad if retbad and self.args.verbose else "" + print(msg.format(num, "..".join(rnd), bad, lst)) + if delete: + num, lst = len(delete), " ".join(delete) + msg = "Worse and older (delete {} @ {}x): {}" + rnd = [str(round(i, 2)) for i in delsld] + print(msg.format(num, "..".join(rnd), lst)) + else: + for file in retain + delete: + try: + os.remove(file) + except: # noqa: E722 + pass + msl = round(min(retsld[0], delsld[0]), 2) + xsl = round(max(retsld[2], delsld[2]), 2) + geo = round(math.sqrt(retsld[1] * delsld[1]), 2) + msg = "Removed outperformed parameter sets{}.".format( + " ({} @ {}..{}..{}x)".format(retcnt + delcnt, msl, geo, xsl) + if 0 < msl + else "" + ) + print(msg) + elif bool(worse): + print("WARNING: incorrectly merged duplicates") + print(" due to nogflops argument!") + msg = "Merged {} of {} JSONs into {}".format( + len(merged), len(filenames), self.args.csvfile + ) + print(msg) def save_final_config(self, configuration, final=True): """Called at termination""" - if 0 < self.gflops and configuration: - # extend result for easier reuse later - config = configuration.data + if not final and (0 >= self.gflops or not configuration): + return # nothing to save + config = configuration.data if configuration else None + cfgenv = self.environment(config) if config else None + result = self.run_result["returncode"] if config and self.run_result else 1 + envchk = os.getenv("CHECK") # conside CHECKing result unless CHECK=0 + if 0 == result and 0 == self.args.check and (envchk is None or "0" != envchk): + self.run_result = self.launch(cfgenv + ["CHECK=1"]) + result = self.run_result["returncode"] if self.run_result else 1 + # extend result for easier reuse + if config: config["DEVICE"] = self.device config["GFLOPS"] = self.gflops if not self.args.nogflops else 0 config["TYPEID"] = self.typeid @@ -434,64 +512,79 @@ def save_final_config(self, configuration, final=True): config["N"] = self.mnk[1] config["K"] = self.mnk[2] config["S"] = self.size - filepattern = "{}-*.json".format(default_basename) - filenames = ( - glob.glob( - os.path.normpath(os.path.join(self.args.jsondir, filepattern)) + filedev = "" if self.idevice is None else "-{}".format(self.idevice) + filedot = os.path.join( + self.args.jsondir, ".{}{}.json".format(self.args.label, filedev) + ) + if config and self.gfsave < self.gflops: # save intermediate result + if 0 == self.gfsave and os.path.exists(filedot): # backup + data = None + try: + with open(filedot, "r") as file: + data = json.load(file) + except: # noqa: E722 + pass + gflops = data["GFLOPS"] if data and "GFLOPS" in data else 0 + filename = os.path.join( + self.args.jsondir, + ( + "{}-{}gflops.json".format(self.args.label, round(gflops)) + if 0 < gflops + else "{}.json".format(self.args.label) + ), ) - if final - else None - ) + try: + os.rename(filedot, filename) + except: # noqa: E722 + pass # self.manipulator().save_to_file(config, filename) - with open( - os.path.join(self.args.jsondir, ".{}.json".format(self.args.label)), - "w", - ) as file: - json.dump(config, file, sort_keys=True) + with open(filedot, "w") as file: + cfg = config + if "XF" in config and 0 == config["XF"]: + cfg = copy.deepcopy(config) + del cfg["XF"] + json.dump(cfg, file, sort_keys=True) file.write("\n") # append newline at EOF - if final: - if not filenames and glob.glob(self.args.csvfile): - print( - "WARNING: no JSON file found but (unrelated?) {}".format( - self.args.csvfile - ) - ) - filename = os.path.normpath( - os.path.join( - self.args.jsondir, - "{}-{}gflops.json".format(self.args.label, round(self.gflops)), - ) - ) - os.rename( - os.path.join(self.args.jsondir, ".{}.json".format(self.args.label)), - filename, - ) - if filename not in filenames: - filenames.append(filename) - self.merge_jsons(filenames) - speedup = round( - (self.gflops / self.gfbase) if 0 < self.gfbase else 0, 1 - ) - print( - "Result{} was written to {}".format( - " ({}x over seed)".format(speedup) if 1 < speedup else "", - filename, - ) - ) - # no validation in SIGINT (user may fired signal due to apps misbehavior) - if 0 == self.args.check and self.handle_sigint != getsignal(SIGINT): - run_result = self.launch(self.environment(config) + ["CHECK=1"]) - if 0 != run_result["returncode"]: - print("WARNING: tuned result seems to be incorrect!") + self.gfsave = self.gflops + # check return code (consider not saving parameters) + if 0 != result and not final: # incorrect result + failed = " ".join(map(str, cfgenv)).replace("OPENCL_LIBSMM_SMM_", "") + print("FAILED: {}".format(failed)) + return + if final and os.path.exists(filedot): + filepattern = "{}-*.json".format(default_basename) + fileglobs = glob.glob( + os.path.normpath(os.path.join(self.args.jsondir, filepattern)) + ) + filenames = fileglobs if final else None + if not filenames and glob.glob(self.args.csvfile): + msg = "WARNING: no JSON-file found but {} will be overwritten." + print(msg.format(self.args.csvfile)) + fileonly = "{}-{}gflops.json".format(self.args.label, round(self.gflops)) + filename = os.path.normpath(os.path.join(self.args.jsondir, fileonly)) + try: + os.rename(filedot, filename) + except: # noqa: E722 + pass + if filename not in filenames: # rebuild CSV-file + filenames.append(filename) + self.merge_jsons(filenames) + speedup = round((self.gflops / self.gfbase) if 0 < self.gfbase else 0, 1) + msg = " ({}x over seed)".format(speedup) if 1 < speedup else "" + print("Result{} was written to {}".format(msg, filename)) + elif final and self.args.merge is None: + print("WARNING: no tuned results produced!") def handle_sigint(self, signum, frame): """Handle SIGINT or CTRL-C""" - print( - "\nWARNING: tuning {}x{}x{}-kernel was interrupted".format( - self.mnk[0], self.mnk[1], self.mnk[2] - ) - ) - self.save_final_config(self.config) + if 1 > self.handle_sigint_counter: # avoid recursion + self.handle_sigint_counter = self.handle_sigint_counter + 1 + msg = "\nWARNING: tuning {}-kernel interrupted." + print(msg.format("x".join(map(str, self.mnk)))) + try: + self.save_final_config(self.config, True) + except: # noqa: E722 + pass exit(1) @@ -576,15 +669,20 @@ def handle_sigint(self, signum, frame): type=float, default=0, nargs="?", - dest="check", help="Validate kernel (epsilon, 0:off)", ) + argparser.add_argument( + "-d", + "--delete", + action="store_true", + default=False, + help="Delete outperformed JSONs", + ) argparser.add_argument( "-v", "--verbose", action="store_true", default=False, - dest="verbose", help="Verbose output", ) argparser.add_argument( @@ -600,7 +698,7 @@ def handle_sigint(self, signum, frame): "-bm", "--initial-bm", type=int, - default=env_value("OPENCL_LIBSMM_SMM_BM", "0"), + default=env_intvalue("OPENCL_LIBSMM_SMM_BM", "0"), nargs="?", dest="bm", help="Block/tile size (0:auto)", @@ -609,7 +707,7 @@ def handle_sigint(self, signum, frame): "-bn", "--initial-bn", type=int, - default=env_value("OPENCL_LIBSMM_SMM_BN", "0"), + default=env_intvalue("OPENCL_LIBSMM_SMM_BN", "0"), nargs="?", dest="bn", help="Block/tile size (0:auto)", @@ -618,7 +716,7 @@ def handle_sigint(self, signum, frame): "-bk", "--initial-bk", type=int, - default=env_value("OPENCL_LIBSMM_SMM_BK", "0"), + default=env_intvalue("OPENCL_LIBSMM_SMM_BK", "0"), nargs="?", dest="bk", help="Block size (0:auto)", @@ -627,7 +725,7 @@ def handle_sigint(self, signum, frame): "-ws", "--initial-ws", type=int, - default=env_value("OPENCL_LIBSMM_SMM_WS", "0"), + default=env_intvalue("OPENCL_LIBSMM_SMM_WS", "0"), nargs="?", dest="ws", help="Minimum WG-size (0:auto)", @@ -636,7 +734,7 @@ def handle_sigint(self, signum, frame): "-wg", "--initial-wg", type=int, - default=env_value("OPENCL_LIBSMM_SMM_WG", "0"), + default=env_intvalue("OPENCL_LIBSMM_SMM_WG", "0"), dest="wg", help="Size of WG: subgroups (-1), tight (0), round-up (1), PoT (2)", ) @@ -644,15 +742,16 @@ def handle_sigint(self, signum, frame): "-lu", "--initial-lu", type=int, - default=env_value("OPENCL_LIBSMM_SMM_LU", "-1"), + default=env_intvalue("OPENCL_LIBSMM_SMM_LU", "-1"), dest="lu", - help="Loop unroll (-2) full, (-1) no hints (default), (0) inner, (1) outer-dehint, (2) literal", + help="Loop unroll (-2) full, (-1) no hints (default)," + + " (0) inner, (1) outer-dehint, (2) block-m", ) argparser.add_argument( "-nz", "--initial-nz", type=int, - default=env_value("OPENCL_LIBSMM_SMM_NZ", "0"), + default=env_intvalue("OPENCL_LIBSMM_SMM_NZ", "0"), dest="nz", help="Check (1) atomic increment to be non-zero (0:off)", ) @@ -660,7 +759,7 @@ def handle_sigint(self, signum, frame): "-al", "--initial-al", type=int, - default=env_value("OPENCL_LIBSMM_SMM_AL", "0"), + default=env_intvalue("OPENCL_LIBSMM_SMM_AL", "0"), dest="al", help="Access: transposed (0), linear (1)", ) @@ -668,7 +767,7 @@ def handle_sigint(self, signum, frame): "-tb", "--initial-tb", type=int, - default=env_value("OPENCL_LIBSMM_SMM_TB", "0"), + default=env_intvalue("OPENCL_LIBSMM_SMM_TB", "0"), dest="tb", help="Matrix B: untracked (0), tracked (1)", ) @@ -676,7 +775,7 @@ def handle_sigint(self, signum, frame): "-tc", "--initial-tc", type=int, - default=env_value("OPENCL_LIBSMM_SMM_TC", "1"), + default=env_intvalue("OPENCL_LIBSMM_SMM_TC", "1"), dest="tc", help="Matrix C: untracked (0), tracked (1)", ) @@ -684,7 +783,7 @@ def handle_sigint(self, signum, frame): "-ap", "--initial-ap", type=int, - default=env_value("OPENCL_LIBSMM_SMM_AP", "0"), + default=env_intvalue("OPENCL_LIBSMM_SMM_AP", "0"), dest="ap", help="Params: global (0), shared (1)", ) @@ -692,31 +791,31 @@ def handle_sigint(self, signum, frame): "-aa", "--initial-aa", type=int, - default=env_value("OPENCL_LIBSMM_SMM_AA", "0"), + default=env_intvalue("OPENCL_LIBSMM_SMM_AA", "0"), dest="aa", - help="Matrix A: global (0), shared (1), shared-bc (2), register (3)", + help="Matrix A: global (0), shared (1), register (2)", ) argparser.add_argument( "-ab", "--initial-ab", type=int, - default=env_value("OPENCL_LIBSMM_SMM_AB", "0"), + default=env_intvalue("OPENCL_LIBSMM_SMM_AB", "0"), dest="ab", - help="Matrix B: global (0), shared (1), shared-bc (2), register (3)", + help="Matrix B: global (0), shared (1), register (2)", ) argparser.add_argument( "-ac", "--initial-ac", type=int, - default=env_value("OPENCL_LIBSMM_SMM_AC", "0"), + default=env_intvalue("OPENCL_LIBSMM_SMM_AC", "0"), dest="ac", - help="Matrix C: register (0), shared (1), shared-bc (2)", + help="Matrix C: register (0), shared (1)", ) argparser.add_argument( "-bs", "--initial-bs", type=int, - default=env_value("OPENCL_LIBSMM_SMM_BS", "0"), + default=env_intvalue("OPENCL_LIBSMM_SMM_BS", "0"), nargs="?", dest="bs", help="Minibatch size (0:auto)", @@ -741,10 +840,8 @@ def handle_sigint(self, signum, frame): ) args = argparser.parse_args() # OPENCL_LIBSMM_SMM_xx=tune|enabled|on must be given to permit tuning) - if os.getenv("OPENCL_LIBSMM_SMM_WS") not in {"tune", "enabled", "on"}: + if os.getenv("OPENCL_LIBSMM_SMM_WS") not in default_enable_tune: os.environ["OPENCL_LIBSMM_SMM_WS"] = "{}".format(args.ws) - # if not os.getenv("OPENCL_LIBSMM_SMM_AL") in {"tune", "enabled", "on"}: - # os.environ["OPENCL_LIBSMM_SMM_AL"] = "{}".format(args.al) # fix tunables according to level of tuning if 1 <= args.tlevel or 0 > args.tlevel: os.environ["OPENCL_LIBSMM_SMM_BM"] = "{}".format(args.bm) @@ -762,5 +859,20 @@ def handle_sigint(self, signum, frame): os.environ["OPENCL_LIBSMM_SMM_LU"] = "{}".format(args.lu) if 0 == args.mb: args.mb = 64 - # additional/depending arguments - SmmTuner.main(args) + instance = SmmTuner(args) + if not default_dbg: + for retry in range(default_retry): + try: + TuningRunMain(instance, args).main() + exit(0) + except Exception as e: + ign = ( + "[{}/{}]".format(retry + 1, default_retry) + if 1 < default_retry + else "" + ) + print("IGNORED{} {}: {}".format(ign, type(e).__name__, e)) + pass + instance.save_final_config(None, True) + else: + TuningRunMain(instance, args).main() diff --git a/src/acc/opencl/smm/tune_multiply.sh b/src/acc/opencl/smm/tune_multiply.sh index 6447c4002d4..736e4058bcb 100755 --- a/src/acc/opencl/smm/tune_multiply.sh +++ b/src/acc/opencl/smm/tune_multiply.sh @@ -42,6 +42,9 @@ then -u|--update) UPDATE=1 shift 1;; + -d|--delete) + DELETE=1 + shift 1;; -a|--tuning-level) TLEVEL=$2 shift 2;; @@ -117,6 +120,9 @@ then if [ "0" != "$((NPARTS&2 echo "ERROR: part-number ${PART} is larger than the requested ${NPARTS} parts!" exit 1 + elif [ "0" != "$((1>PART))" ]; then + >&2 echo "ERROR: part-number must be 1-based!" + exit 1 fi HERE=$(cd "$(dirname "$0")" && pwd -P) JSONS=$(${LS} -1 ${JSONDIR}/tune_multiply-*-*x*x*-*gflops.json 2>/dev/null) @@ -126,7 +132,7 @@ then elif [ ! "${HELP}" ] || [ "0" = "${HELP}" ]; then if [ "${UPDATE}" ] && [ "0" != "${UPDATE}" ]; then if [ ! "${TLEVEL}" ] || [ "0" != "$((0>TLEVEL))" ]; then TLEVEL=1; fi - MNKS=$(echo "${JSONS}" | ${SED} -n "s/.*tune_multiply-..*-\(..*x..*x.[^-]*\)-..*gflops\.json/\1/p" \ + MNKS=$(${SED} -n "s/.*tune_multiply-..*-\(..*x..*x.[^-]*\)-..*gflops\.json/\1/p" <<<"${JSONS}" \ | ${SORT} -u -n -tx -k1,1 -k2,2 -k3,3) elif [ "${SPECID}" ]; then MNKS=$(eval "${HERE}/../../acc_triplets.sh -k ${SPECID} 2>/dev/null") @@ -140,7 +146,7 @@ then if [ "${BOUNDL}" ] || [ "${BOUNDU}" ]; then if [ ! "${BOUNDL}" ]; then BOUNDL=0; elif [ ! "${BOUNDU}" ]; then BOUNDU=0; fi if [ "0" != "$((0<=BOUNDL))" ]; then - for MNK in $(echo "${MNKS}" | ${SED} "s/x/*/g"); do + for MNK in $(${SED} "s/x/*/g" <<<"${MNKS}"); do S=$((MNK)) if [ "0" != "$((BOUNDL&2 echo "ERROR: invalid or no given!" @@ -202,7 +208,8 @@ then else echo "Tuning ${PARTSIZE} kernels will take an unknown time (no limit given)." fi - NJSONS=$(echo "${JSONS}" | ${WC} -l) + if [ "${DELETE}" ] && [ "0" != "${DELETE}" ]; then DELETE=-d; fi + NJSONS=$(${WC} -l <<<"${JSONS}") if [ "0" != "${NJSONS}" ]; then if [ ! "${UPDATE}" ] || [ "0" = "${UPDATE}" ]; then echo "Already found ${NJSONS} (unrelated?) JSON-files." @@ -217,14 +224,14 @@ then sleep ${WAIT} fi N=0 - MNKPART=$(echo "${MNKS}" | ${CUT} -d' ' -f $((PARTOFFS+1))-$((PARTOFFS+PARTSIZE))) + MNKPART=$(${CUT} -d' ' -f $((PARTOFFS+1))-$((PARTOFFS+PARTSIZE)) <<<"${MNKS}") for MNK in ${MNKPART}; do if [ "0" != "$(((N) dbcsr_mp_pgrid(left_mp_obj) + right_pgrid => dbcsr_mp_pgrid(right_mp_obj) + product_pgrid => dbcsr_mp_pgrid(product_mp_obj) + CALL dbcsr_mp_grid_setup(product_mp_obj) + CALL dbcsr_mp_grid_setup(left_mp_obj) + CALL dbcsr_mp_grid_setup(right_mp_obj) + ! + ! Dummy checks + ! left/right matching + IF (left_col_nimages .NE. right_row_mult) & + DBCSR_ABORT("Left/Right image mismatch") + IF (left_col_mult .NE. right_row_nimages) & + DBCSR_ABORT("Left/Right image mismatch") + IF (left_col_nimages*left_npcols .NE. right_row_nimages*right_nprows) & + DBCSR_ABORT("Left/Right total mismatch") + ! product/left matching + IF (left_row_mult*dbcsr_mp_nprows(product_mp_obj) .NE. left_row_nimages*left_nprows) & + DBCSR_ABORT("Product/Left total mismatch") + ! product/left matching + IF (right_col_mult*dbcsr_mp_npcols(product_mp_obj) .NE. right_col_nimages*right_npcols) & + DBCSR_ABORT("Product/Right total mismatch") + ! Limitations + IF (left_row_nimages .NE. 1) & + DBCSR_ABORT("Product/Left matrix process grid mismatch") + IF (left_row_mult .NE. 1) & + DBCSR_ABORT("Product/Left matrix process grid mismatch") + IF (right_col_nimages .NE. 1) & + DBCSR_ABORT("Product/Right matrix process grid mismatch") + IF (right_col_mult .NE. 1) & + DBCSR_ABORT("Product/Right matrix process grid mismatch") + + dbcsr_mpi_statistics%nimages = MAX(dbcsr_mpi_statistics%nimages, left_row_nimages*left_col_nimages) + dbcsr_mpi_statistics%nimages = MAX(dbcsr_mpi_statistics%nimages, right_row_nimages*right_col_nimages) + ! + ! Exchange size data + ALLOCATE (my_sizes(4, MAX(left_row_nimages, right_row_nimages), & + MAX(left_col_nimages, right_col_nimages))) + my_sizes(:, :, :) = 0 + DO left_row_image = 1, left_row_nimages + DO left_col_image = 1, left_col_nimages + my_sizes(idata + ileft, left_row_image, left_col_image) & + = dbcsr_data_get_size_referenced( & + left_set%mats(left_row_image, left_col_image)%data_area) + my_sizes(imeta + ileft, left_row_image, left_col_image) = & + left_set%mats(left_row_image, left_col_image)%index & + (dbcsr_slot_size) + END DO + END DO + + DO right_row_image = 1, right_row_nimages + DO right_col_image = 1, right_col_nimages + my_sizes(idata + iright, right_row_image, right_col_image) & + = dbcsr_data_get_size_referenced( & + right_set%mats(right_row_image, right_col_image)%data_area) + my_sizes(imeta + iright, right_row_image, right_col_image) = & + right_set%mats(right_row_image, right_col_image)%index & + (dbcsr_slot_size) + END DO + END DO + + ALLOCATE (all_sizes(4, LBOUND(my_sizes, 2):UBOUND(my_sizes, 2), & + LBOUND(my_sizes, 3):UBOUND(my_sizes, 3), 0:numnodes - 1)) + CALL mp_allgather(my_sizes, all_sizes, mp_group) + ! + ! Count the maximum possible multiplies per row for on-the-fly + ! filtering. + per_row_eps: IF (.NOT. otf_filtering) THEN + ! These arrays must be valid when passed to called subroutines. + ALLOCATE (left_norms(0), right_norms(0), row_max_epss(0), stat=stat) + IF (stat .NE. 0) & + DBCSR_ABORT("Could not allocate memory") + ELSE + IF (careful_mod) THEN + IF (left_set%mats(1, 1)%bcsc) & + DBCSR_ABORT("Can not do on-the-fly filtering with CSC-indexed matrices.") + END IF + IF (dbcsr_has_local_row_index(left_set%mats(1, 1))) THEN + nblkrows_used = dbcsr_nblkrows_local(left_set%mats(1, 1)) + ELSE + nblkrows_used = dbcsr_nblkrows_total(left_set%mats(1, 1)) + END IF + ALLOCATE (row_max_epss(nblkrows_used), stat=stat) + IF (stat .NE. 0) & + DBCSR_ABORT("Could not allocate memory for left epsilons") + ALLOCATE (row_counts(nblkrows_used), stat=stat) + IF (stat .NE. 0) & + DBCSR_ABORT("Could not allocate memory for left row counts") + ! The summation could be done prow-locally but it would + ! complicate the pre-row eps calculation. + ALLOCATE (total_row_counts(nblkrows_used), stat=stat) + IF (stat .NE. 0) & + DBCSR_ABORT("Could not allocate memory for left row counts") + ! Each prow member matrix (npcols * row_images) counts the + ! blocks present in each of its rows. + total_row_counts(:) = 0 + DO left_row_image = 1, left_row_nimages + DO left_col_image = 1, left_col_nimages + list_indexing = & + left_set%mats(left_row_image, left_col_image)%list_indexing + IF (careful_mod) THEN + IF (list_indexing) THEN + IF ((left_set%mats(left_row_image, left_col_image)%nblks)*3 .NE. & + SIZE(left_set%mats(left_row_image, left_col_image)%coo_l)) & + DBCSR_ABORT("Row count mismatch") + ELSE + IF (nblkrows_used + 1 .NE. SIZE(left_set%mats(left_row_image, left_col_image)%row_p)) & + DBCSR_ABORT("Row count mismatch") + END IF + END IF + IF (list_indexing) THEN + CALL count_bins( & + left_set%mats(left_row_image, left_col_image)%nblks, & + left_set%mats(left_row_image, left_col_image)%coo_l(1::3), & + nblkrows_used, row_counts) + ELSE + CALL dbcsr_count_row_index( & + left_set%mats(left_row_image, left_col_image)%row_p, & + row_counts, nblkrows_used) + END IF + total_row_counts(:) = total_row_counts(:) & + + row_counts(:) + END DO + END DO + ! The counted blocks are then summed up + CALL mp_sum(total_row_counts, dbcsr_mp_my_row_group(product_mp_obj)) + ! and used to determine the maximum per-block epsilon. + filter_eps_sp = REAL(filter_eps, KIND=KIND(row_max_epss)) +!$OMP PARALLEL DO DEFAULT (NONE) & +!$OMP SHARED(nblkrows_used,row_max_epss,filter_eps_sp,& +!$OMP total_row_counts) + DO row = 1, nblkrows_used + row_max_epss(row) & + = (filter_eps_sp & + /REAL(MAX(1, total_row_counts(row)), KIND=KIND(row_max_epss)))**2 + END DO +!$OMP END PARALLEL DO + ! + DEALLOCATE (row_counts) + DEALLOCATE (total_row_counts) + END IF per_row_eps + ! + ! The main transfer loop goes through the virtual rows/columns. + ! The number of steps may be smaller if the grid dimension is very + ! non-optimal (both left column images and right row images are > + ! 1). + min_nimages = MIN(left_col_nimages, right_row_nimages) + nvirt_k = left_npcols*left_col_nimages + nsteps_k = nvirt_k/min_nimages + ! + ! Translate the all_sizes to account for pre-distribution. This + ! is just done to simplify lookups. + ALLOCATE (left_sizes(2, 0:left_nprows*left_row_nimages - 1, 0:nvirt_k - 1)) + left_sizes = -1 + DO left_src_vcol = 0, left_col_nimages*left_npcols - 1 + DO left_src_vrow = 0, left_row_nimages*left_nprows - 1 + ! Calculate what was shifted. The left_src_v{row,col} are + ! the "source" rows/columns; the left_dst are the shifted + ! targets where the data was placed in make_images. + CALL image_calculator(left_set%image_dist, & + prow=left_dst_prow, pcol=left_dst_pcol, & + rowi=left_dst_irow, coli=left_dst_icol, & + myvprow=left_src_vrow, myvpcol=left_src_vcol, & + shifting='l') + left_dst_p = left_pgrid(left_dst_prow, left_dst_pcol) + left_sizes(idata, left_src_vrow, left_src_vcol) = & + all_sizes( & + idata + ileft, left_dst_irow, left_dst_icol, left_dst_p) + left_sizes(imeta, left_src_vrow, left_src_vcol) = & + all_sizes( & + imeta + ileft, left_dst_irow, left_dst_icol, left_dst_p) + END DO + END DO + ! + ALLOCATE (right_sizes(2, 0:nvirt_k - 1, 0:right_npcols*right_col_nimages - 1)) + right_sizes = -1 + DO right_src_vcol = 0, right_col_nimages*right_npcols - 1 + DO right_src_vrow = 0, right_row_nimages*right_nprows - 1 + ! Calculate what was shifted. The right_src_v{row,col} are + ! the "source" rows/columns; the right_dst are the shifted + ! targets where the data was placed in make_images. + CALL image_calculator(right_set%image_dist, & + prow=right_dst_prow, pcol=right_dst_pcol, & + rowi=right_dst_irow, coli=right_dst_icol, & + myvprow=right_src_vrow, myvpcol=right_src_vcol, & + shifting='r') + right_dst_p = right_pgrid(right_dst_prow, right_dst_pcol) + right_sizes(idata, right_src_vrow, right_src_vcol) = & + all_sizes( & + idata + iright, right_dst_irow, right_dst_icol, right_dst_p) + right_sizes(imeta, right_src_vrow, right_src_vcol) = & + all_sizes( & + imeta + iright, right_dst_irow, right_dst_icol, right_dst_p) + END DO + END DO + ! + ! Setup product work areas + left_max_nze = MAXVAL(all_sizes(idata + ileft, :, :, :)) + left_max_nblks = MAXVAL(all_sizes(imeta + ileft, :, :, :)) + right_max_nze = MAXVAL(all_sizes(idata + iright, :, :, :)) + right_max_nblks = MAXVAL(all_sizes(imeta + iright, :, :, :)) + !! + ! Evaluate sizes for workspaces + IF (.NOT. keep_sparsity) THEN + IF (has_acc) THEN + size_guess_init = product_matrix_size_guess(left_set%mats(1, 1), right_set%mats(1, 1), product_matrix, & + left_max_nze, right_max_nze, & + left_col_nimages, right_row_nimages, & + nthreads) + ELSE + size_guess_init = 1 + END IF + END IF + ithread = 0 +!$OMP PARALLEL DEFAULT(NONE) & +!$OMP PRIVATE (i, size_guess, ithread) & +!$OMP SHARED (product_matrix, left_max_nze, right_max_nze) & +!$OMP SHARED (left_set, right_set, & +!$OMP left_col_nimages, right_row_nimages) & +!$OMP SHARED (nthreads, keep_sparsity, mynode, size_guess_init) + ! +!$ ithread = OMP_GET_THREAD_NUM() + ! The work arrays have to be setup (actually, not quite sure). + i = ithread + 1 + size_guess = product_matrix%wms(i)%datasize ! Should be minimal + IF (.NOT. keep_sparsity) THEN + size_guess = MAX(size_guess, size_guess_init) + END IF + CALL dbcsr_data_ensure_size(product_matrix%wms(i)%data_area, & + size_guess) + CALL dbcsr_data_set_size_referenced(product_matrix%wms(i)%data_area, & + product_matrix%wms(i)%datasize) + ! XXXXXXX a quick fix right now, allocation with size 1 might actually not be needed at all, + ! but something expects this to be associated + CALL ensure_array_size(product_matrix%wms(i)%row_i, ub=1) + CALL ensure_array_size(product_matrix%wms(i)%col_i, ub=1) + CALL ensure_array_size(product_matrix%wms(i)%blk_p, ub=1) +!$OMP END PARALLEL + + ! update capacity of memory-pools, +1 for the dense case + IF (ASSOCIATED(memtype_abpanel_1%pool)) & + CALL dbcsr_mempool_limit_capacity(memtype_abpanel_1%pool, & + capacity=left_row_mult*left_col_nimages + right_row_nimages*right_col_mult + 1) + IF (ASSOCIATED(memtype_abpanel_2%pool)) & + CALL dbcsr_mempool_limit_capacity(memtype_abpanel_2%pool, & + capacity=left_row_mult*left_col_nimages + right_row_nimages*right_col_mult + 1) + IF (has_acc) THEN + ! enumerate the blocksizes to keep the following 2D-arrays small. + CALL enumerate_blk_sizes(right_set%mats(1, 1)%row_blk_size%low%data, & + dbcsr_max_row_size(right_set%mats(1, 1)), & + row_blk_sizes2enum, enum2row_blk_sizes) + CALL enumerate_blk_sizes(right_set%mats(1, 1)%col_blk_size%low%data, & + dbcsr_max_col_size(right_set%mats(1, 1)), & + col_blk_sizes2enum, enum2col_blk_sizes) + END IF + + ! Save col and row communicators + IF (dbcsr_mp_has_subgroups(right_mp_obj)) THEN + right_grp = dbcsr_mp_my_col_group(right_mp_obj) + ELSE + right_grp = dbcsr_mp_group(right_mp_obj) + END IF + IF (dbcsr_mp_has_subgroups(left_mp_obj)) THEN + left_grp = dbcsr_mp_my_row_group(left_mp_obj) + ELSE + left_grp = dbcsr_mp_group(left_mp_obj) + END IF + CALL mp_environ(left_numnodes, left_mynode, left_grp) + CALL mp_environ(right_numnodes, right_mynode, right_grp) + + ! + ! Setup the left buffer matrices + ! + CALL buffer_matrices_ensure_size(left_set, index_size=left_max_nblks, & + data_size=left_max_nze) + + CALL setup_buffer_matrices(left_buffer_2, left_row_mult, left_col_nimages, & + left_set%mats(1, 1), index_size=left_max_nblks, & + data_size=left_max_nze) + IF (otf_filtering) THEN + ALLOCATE (left_norms(left_max_nblks), stat=stat) + IF (stat .NE. 0) & + DBCSR_ABORT("Could not allocate memory for left norms") + IF (stat .NE. 0) otf_filtering = .FALSE. + END IF + left_buffer_calc => left_set + left_buffer_comm => left_buffer_2 + ALLOCATE (left_data_sr(left_col_nimages)) + ALLOCATE (left_index_sr(left_col_nimages)) + ALLOCATE (left_data_rr(left_col_nimages)) + ALLOCATE (left_index_rr(left_col_nimages)) + left_data_sr = mp_request_null + left_data_rr = mp_request_null + left_index_sr = mp_request_null + left_index_rr = mp_request_null + + ! Setup buffers for right matrix + CALL buffer_matrices_ensure_size(right_set, index_size=right_max_nblks, & + data_size=right_max_nze) + + CALL setup_buffer_matrices(right_buffer_2, right_row_nimages, right_col_mult, & + right_set%mats(1, 1), index_size=right_max_nblks, data_size=right_max_nze) + IF (otf_filtering) THEN + ALLOCATE (right_norms(right_max_nblks), stat=stat) + IF (stat .NE. 0) & + DBCSR_WARN("Could not allocate memory for right norms") + IF (stat .NE. 0) otf_filtering = .FALSE. + + END IF + IF (has_acc .and. otf_filtering) THEN + max_nblks = MAX(left_max_nblks, right_max_nblks) + CALL dbcsr_data_init(normsbuf) + CALL dbcsr_data_new(normsbuf, data_type=dbcsr_type_real_4, & + data_size=max_nblks, memory_type=memtype_normsbuf) + CALL dbcsr_data_init(offsetsbuf) + CALL dbcsr_data_new(offsetsbuf, data_type=dbcsr_type_int_4, & + data_size=max_nblks, memory_type=memtype_offsetsbuf) + CALL dbcsr_data_init(nelemsbuf) + CALL dbcsr_data_new(nelemsbuf, data_type=dbcsr_type_int_4, & + data_size=max_nblks, memory_type=memtype_nelemsbuf) + END IF + right_buffer_calc => right_set + right_buffer_comm => right_buffer_2 + ALLOCATE (right_data_sr(right_row_nimages)) + ALLOCATE (right_index_sr(right_row_nimages)) + ALLOCATE (right_data_rr(right_row_nimages)) + ALLOCATE (right_index_rr(right_row_nimages)) + right_data_sr = mp_request_null + right_data_rr = mp_request_null + right_index_sr = mp_request_null + right_index_rr = mp_request_null + ! + ALLOCATE (m_sizes(dbcsr_nblkrows_local(product_matrix))) + CALL local_filter(array_data(product_matrix%row_blk_size), array_size(product_matrix%local_rows), & + array_data(product_matrix%local_rows), m_sizes) + ALLOCATE (n_sizes(dbcsr_nblkcols_local(product_matrix))) + CALL local_filter(array_data(product_matrix%col_blk_size), array_size(product_matrix%local_cols), & + array_data(product_matrix%local_cols), n_sizes) + ! +!$OMP PARALLEL & +!$OMP DEFAULT (NONE) & +!$OMP SHARED (left_buffer_comm, right_buffer_comm, product_matrix,& +!$OMP keep_sparsity, filter_eps, row_max_epss, multrec, nthreads, & +!$OMP right_data_sr, right_data_rr, left_data_sr, left_data_rr,& +!$OMP right_index_sr, right_index_rr, left_index_sr, left_index_rr,& +!$OMP m_sizes, n_sizes, keep_product_data), & +!$OMP PRIVATE(ithread) + ithread = 0 +!$ ithread = OMP_GET_THREAD_NUM() + ALLOCATE (multrec(ithread)%p) + CALL dbcsr_mm_multrec_init(multrec(ithread)%p, & + product=product_matrix, & + keep_sparsity=keep_sparsity, & + eps=filter_eps, & + row_max_epss=row_max_epss, & + block_estimate=MAX(product_matrix%nblks, & + left_buffer_comm%mats(1, 1)%nblks, & + right_buffer_comm%mats(1, 1)%nblks)/nthreads, & + right_row_blk_size=array_data(right_buffer_comm%mats(1, 1)%row_blk_size), & + m_sizes=m_sizes, n_sizes=n_sizes, & + keep_product_data=keep_product_data) +!$OMP END PARALLEL + ! + ! Setup indexing + CALL setup_rec_index_2d(left_set, left_row_nimages, left_col_nimages) + CALL setup_rec_index_2d(right_set, right_row_nimages, right_col_nimages) + ! + ! Setup the send/receive data pointers + CALL dbcsr_data_init(left_data_sp) + CALL dbcsr_data_init(left_data_rp) + CALL dbcsr_data_init(right_data_sp) + CALL dbcsr_data_init(right_data_rp) + CALL dbcsr_data_new(left_data_sp, data_type) + CALL dbcsr_data_new(left_data_rp, data_type) + CALL dbcsr_data_new(right_data_sp, data_type) + CALL dbcsr_data_new(right_data_rp, data_type) + + ! Setup transpose stackbuffers + IF (has_acc) THEN + CALL dbcsr_data_init(trs_stackbuf_1) + CALL dbcsr_data_init(trs_stackbuf_2) + CALL dbcsr_data_new(trs_stackbuf_1, data_type=dbcsr_type_int_4, & + data_size=2*right_max_nblks, memory_type=memtype_trsbuffer_1) + CALL dbcsr_data_new(trs_stackbuf_2, data_type=dbcsr_type_int_4, & + data_size=2*right_max_nblks, memory_type=memtype_trsbuffer_2) + trs_stackbuf_calc => trs_stackbuf_1 + trs_stackbuf_comm => trs_stackbuf_2 + END IF + ! + ! Reset indices for virtual images + v_ki_right = 0 + v_ki_left = 0 + ! + ! Here is the main loop. + ! + ! In the first loop iteration, the data is fetched from the + ! sources. In the remaining iterations, the data are exchanged + ! among neighbors. In the last loop only calculations take place. + ! + CALL timeset(routineN//"_loop", handle1) + copy_left = .true. + copy_right = .true. + ! + grouped_k_index: DO metronome = 0, nvirt_k - 1 + ! Wait for right matrix transfer completion. Wait in all but + ! the first loop iteration. + CALL timeset(routineN//"_metrocomm1", handle2) + wait_right: IF (v_ki_right .EQ. right_row_nimages) THEN + ! Reset index + v_ki_right = 0 + IF (debug_mod) WRITE (*, '(1X,A)') routineN//" waiting for right" + ! + CALL mp_waitall(right_data_sr) + CALL mp_waitall(right_data_rr) + CALL mp_waitall(right_index_sr) + CALL mp_waitall(right_index_rr) + ! + ! Repoint indices of right matrices + DO v_ki = 0, right_row_nimages - 1 + CALL dbcsr_repoint_index(right_buffer_calc%mats(v_ki + 1, 1)) + right_buffer_calc%mats(v_ki + 1, 1)%valid = .TRUE. + END DO + END IF wait_right + CALL timestop(handle2) + ! + ! Wait for left matrix transfer completion. Wait in all but + ! the first loop iteration. + CALL timeset(routineN//"_metrocomm3", handle2) + wait_left: IF (v_ki_left .EQ. left_col_nimages) THEN + ! Reset index + v_ki_left = 0 + IF (debug_mod) WRITE (*, '(1X,A)') routineN//" waiting for left" + CALL mp_waitall(left_data_sr) + CALL mp_waitall(left_data_rr) + CALL mp_waitall(left_index_sr) + CALL mp_waitall(left_index_rr) + ! + ! Repoint indices of left matrices + DO v_ki = 0, left_col_nimages - 1 + CALL dbcsr_repoint_index(left_buffer_calc%mats(1, v_ki + 1)) + left_buffer_calc%mats(1, v_ki + 1)%valid = .TRUE. + END DO + END IF wait_left + CALL timestop(handle2) + + v_ki_left = v_ki_left + 1 + v_ki_right = v_ki_right + 1 + + IF (debug_mod) THEN + CALL dbcsr_print(left_buffer_calc%mats(1, v_ki_left), nodata=.TRUE.) + CALL dbcsr_print(right_buffer_calc%mats(v_ki_right, 1), nodata=.TRUE.) + END IF + ! + ! from here the code for dbcsr_mm_driver_inner_init was taken + ! + IF (.FALSE.) WRITE (*, *) routineN//" TICK", metronome + ! Since the right matrix is shifted vertically, the + ! received data always has different notions of "local + ! rows". Thus the local_rows and global_rows must be + ! recalculated. + CALL dbcsr_reset_vlocals(right_buffer_calc%mats(v_ki_right, 1), & + right_set%image_dist) + CALL dbcsr_reset_vlocals(left_buffer_calc%mats(1, v_ki_left), & + left_set%image_dist) + ! + CALL ensure_array_size(k_sizes, ub=array_size(right_buffer_calc%mats(v_ki_right, 1)%local_rows)) + CALL local_filter(array_data(right_buffer_calc%mats(v_ki_right, 1)%row_blk_size), & + array_size(right_buffer_calc%mats(v_ki_right, 1)%local_rows), & + array_data(right_buffer_calc%mats(v_ki_right, 1)%local_rows), & + k_sizes) + ! + ! Transfer left and right buffers from host to GPU memory + IF (has_acc) THEN + IF (copy_left) THEN + ! copy left buffer images to device + DO v_ki = 1, left_col_nimages + CALL dbcsr_data_host2dev(left_buffer_calc%mats(1, v_ki)%data_area) + CALL timeset(routineN//"_sync_h2d", handle2) + CALL acc_stream_synchronize(left_buffer_calc%mats(1, v_ki)%data_area%d%memory_type%acc_stream) + CALL timestop(handle2) + END DO + copy_left = .false. + END IF + ! calculate norms for matrices in left buffer + IF (otf_filtering) THEN + left_norms(:) = huge_norm + CALL acc_calculate_norms(left_buffer_calc%mats(1, v_ki_left), & + left_norms, normsbuf, offsetsbuf, nelemsbuf, m_sizes, k_sizes) + END IF + + IF (copy_right) THEN + ! copy right buffer images to device + DO v_ki = 1, right_row_nimages + CALL dbcsr_data_host2dev(right_buffer_calc%mats(v_ki, 1)%data_area) + CALL timeset(routineN//"_sync_h2d", handle2) + CALL acc_stream_synchronize(right_buffer_calc%mats(v_ki, 1)%data_area%d%memory_type%acc_stream) + CALL timestop(handle2) + + ! now transpose right buffer image + CALL acc_transpose_blocks(right_buffer_calc%mats(v_ki, 1), trs_stackbuf_calc, & + k_sizes, n_sizes, & + row_blk_sizes2enum, enum2row_blk_sizes, & + col_blk_sizes2enum, enum2col_blk_sizes) + END DO + ! Wait for transpose to complete before proceeding + CALL timeset(routineN//"_sync_h2d", handle2) + CALL acc_stream_synchronize(trs_stackbuf_calc%d%memory_type%acc_stream) + CALL timestop(handle2) + copy_right = .false. + END IF + ! calculate norms for matrices in right buffer + IF (otf_filtering) THEN + right_norms(:) = huge_norm + CALL acc_calculate_norms(right_buffer_calc%mats(v_ki_right, 1), & + right_norms, normsbuf, offsetsbuf, nelemsbuf, k_sizes, n_sizes) + END IF + END IF + ! + ! Right matrix transfer. Transfer in all but the last loop + ! iteration. + xfer_right: IF (v_ki_right .EQ. 1 .AND. metronome + right_row_nimages .LT. nvirt_k) THEN + DO v_ki = 0, right_row_nimages - 1 + ! Calculate the process to send to. It's the virtual + ! process row -min_nimages up (i.e., smaller row number) + ! from me. + CALL image_calculator(right_set%image_dist, & + prow=right_send_prow, rowi=right_send_irow, & ! output + pcol=right_send_pcol, coli=right_send_icol, & ! output + vprow=right_send_vrow, vpcol=right_send_vcol, & ! output + ! myvprow goes through all of my (process row) images + myvprow=v_ki + right_myfirstvrow, & + myvpcol=right_myfirstvcol, & ! nothing happens in the columns + vprow_shift=-right_row_nimages, & + shifting='0') + ! Calculate which data I send. + CALL image_calculator(right_set%image_dist, & + prow=right_dst_prow, rowi=right_dst_irow, & + pcol=right_dst_pcol, coli=right_dst_icol, & + vprow=right_dst_vrow, vpcol=right_dst_vcol, & + ! myvprows goes through all of my (process row) images + myvprow=v_ki + right_myfirstvrow, & + myvpcol=right_myfirstvcol, & ! nothing happens in the columns + vprow_shift=metronome, & + ! This is with relative shifting. + shifting='R') + right_dst_p = right_pgrid(right_dst_prow, right_dst_pcol) + CALL dbcsr_data_set_pointer( & + area=right_data_sp, & + rsize=right_sizes(idata, right_dst_vrow, right_dst_vcol), & + csize=1, & + pointee=right_buffer_calc%mats(v_ki + 1, 1)%data_area) + right_index_sp => right_buffer_calc%mats( & + v_ki + 1, 1 & + )%index(1: & + right_sizes(imeta, right_dst_vrow, right_dst_vcol)) + ! + ! Calculate the process to receive from + CALL image_calculator(right_set%image_dist, & + prow=right_recv_prow, rowi=right_recv_irow, & + pcol=right_recv_pcol, coli=right_recv_icol, & + vprow=right_recv_vrow, vpcol=right_recv_vcol, & + myvprow=v_ki + right_myfirstvrow, & + myvpcol=right_myfirstvcol, & + vprow_shift=+right_row_nimages, & ! just the opposite as "send to" + shifting='0') + ! Calculate which data I receive + CALL image_calculator(right_set%image_dist, & + prow=right_src_prow, rowi=right_src_irow, & + pcol=right_src_pcol, coli=right_src_icol, & + vprow=right_src_vrow, vpcol=right_src_vcol, & + myvprow=v_ki + right_myfirstvrow, & + myvpcol=right_myfirstvcol, & + ! receive window moves with the metronome + vprow_shift=metronome + right_row_nimages, & + shifting='R') + ! + IF (has_acc) THEN + CALL timeset(routineN//"_acc_sync_right", handle3) + CALL acc_event_synchronize(right_buffer_comm%mats(v_ki + 1, 1)%data_area%d%acc_ready) + CALL timestop(handle3) + END IF + + right_src_p = right_pgrid(right_src_prow, right_src_pcol) + CALL dbcsr_data_set_pointer( & + area=right_data_rp, & + rsize=right_sizes(idata, right_src_vrow, right_src_vcol), & + csize=1, & + pointee=right_buffer_comm%mats(v_ki + 1, 1)%data_area) + right_index_rp => right_buffer_comm%mats( & + v_ki + 1, 1 & + )%index(1: & + right_sizes(imeta, right_src_vrow, right_src_vcol)) + ! + right_send_p = right_pgrid(right_send_prow, right_send_pcol) + right_recv_p = right_pgrid(right_recv_prow, right_recv_pcol) + ! These are column-communicator relative + IF (dbcsr_mp_has_subgroups(right_mp_obj)) THEN + right_send_p = right_send_prow + right_recv_p = right_recv_prow + grp = dbcsr_mp_my_col_group(right_mp_obj) + ELSE + grp = dbcsr_mp_group(right_mp_obj) + END IF + ! + CALL timeset(routineN//"_metrocomm2", handle2) + IF (.not. has_acc) THEN + CALL dbcsr_irecv_any(right_data_rp, right_recv_p, & + grp, right_data_rr(v_ki + 1), tag=right_src_vrow) + ELSE + msglen = right_sizes(idata, right_src_vrow, right_src_vcol) +#if defined (__DBCSR_ACC) + CALL C_F_POINTER(acc_devmem_cptr(right_buffer_comm%mats( & + v_ki + 1, 1)%data_area%d%acc_devmem), & + right_data_rp%d%r_dp, (/msglen/)) +#endif + CALL mp_irecv(right_data_rp%d%r_dp, & + right_recv_p, grp, & + right_data_rr(v_ki + 1), tag=right_src_vrow) + END IF + CALL mp_irecv(right_index_rp, right_recv_p, & + grp, right_index_rr(v_ki + 1), tag=right_src_vrow) + IF (.not. has_acc) THEN + CALL dbcsr_isend_any(right_data_sp, right_send_p, & + grp, right_data_sr(v_ki + 1), tag=right_dst_vrow) + ELSE + msglen = right_sizes(idata, right_dst_vrow, right_dst_vcol) +#if defined (__DBCSR_ACC) + CALL C_F_POINTER(acc_devmem_cptr(right_buffer_calc%mats( & + v_ki + 1, 1)%data_area%d%acc_devmem), & + right_data_sp%d%r_dp, (/msglen/)) +#endif + CALL mp_isend(right_data_sp%d%r_dp, & + right_send_p, grp, & + right_data_sr(v_ki + 1), tag=right_dst_vrow) + END IF + CALL mp_isend(right_index_sp, right_send_p, & + grp, right_index_sr(v_ki + 1), tag=right_dst_vrow) + dbcsr_mpi_statistics%nexchanged = dbcsr_mpi_statistics%nexchanged + 1 + CALL count_mpi_statistics(dbcsr_mpi_statistics%data_size(1, :), & + dbcsr_data_get_size(right_data_rp), & + data_type_byte, & + dbcsr_mpi_statistics%data_size_breakdown(:, :, 1)) + CALL timestop(handle2) + END DO + END IF xfer_right + ! + ! Left matrix transfer. Transfer in all but the last processor images. + xfer_left: IF (v_ki_left .EQ. 1 .AND. metronome + left_col_nimages .LT. nvirt_k) THEN + DO v_ki = 0, left_col_nimages - 1 + ! Calculate the process to send to. + CALL image_calculator(left_set%image_dist, & + prow=left_send_prow, rowi=left_send_irow, & ! output + pcol=left_send_pcol, coli=left_send_icol, & ! output + vprow=left_send_vrow, vpcol=left_send_vcol, & ! output + myvprow=left_myfirstvrow, & ! nothing happens in the rows + ! go through all my column images + myvpcol=v_ki + left_myfirstvcol, & + ! send to process left_col_nimages left in the grid + vpcol_shift=-left_col_nimages, & + shifting='0') + ! Calculate which data I send. + CALL image_calculator(left_set%image_dist, & + prow=left_dst_prow, rowi=left_dst_irow, & + pcol=left_dst_pcol, coli=left_dst_icol, & + vprow=left_dst_vrow, vpcol=left_dst_vcol, & + myvprow=left_myfirstvrow, & + ! go through all my column images + myvpcol=v_ki + left_myfirstvcol, & + vpcol_shift=metronome, & + ! This is with relative shifting. + shifting='L') + ! + left_dst_p = left_pgrid(left_dst_prow, left_dst_pcol) + CALL dbcsr_data_set_pointer( & + area=left_data_sp, & + rsize=left_sizes(idata, left_dst_vrow, left_dst_vcol), & + csize=1, & + pointee=left_buffer_calc%mats(1, v_ki + 1)%data_area) + left_index_sp => left_buffer_calc%mats( & + 1, v_ki + 1 & + )%index(1: & + left_sizes(imeta, left_dst_vrow, left_dst_vcol)) + ! + ! Calculate the process to receive from + CALL image_calculator(left_set%image_dist, & + prow=left_recv_prow, rowi=left_recv_irow, & + pcol=left_recv_pcol, coli=left_recv_icol, & + vprow=left_recv_vrow, vpcol=left_recv_vcol, & + myvprow=left_myfirstvrow, & + myvpcol=v_ki + left_myfirstvcol, & + vpcol_shift=+left_col_nimages, & ! just the opposite as "send to" + shifting='0') + ! Calculate which data I receive + CALL image_calculator(left_set%image_dist, & + prow=left_src_prow, rowi=left_src_irow, & + pcol=left_src_pcol, coli=left_src_icol, & + vprow=left_src_vrow, vpcol=left_src_vcol, & + myvprow=left_myfirstvrow, & + myvpcol=v_ki + left_myfirstvcol, & + ! receive window moves with the metronome + vpcol_shift=metronome + left_col_nimages, & + shifting='L') + ! + IF (has_acc) THEN + CALL timeset(routineN//"_acc_sync_left", handle3) + CALL acc_event_synchronize(left_buffer_comm%mats(1, v_ki + 1)%data_area%d%acc_ready) + CALL timestop(handle3) + END IF + + left_src_p = left_pgrid(left_src_prow, left_src_pcol) + CALL dbcsr_data_set_pointer( & + area=left_data_rp, & + rsize=left_sizes(idata, left_src_vrow, left_src_vcol), & + csize=1, & + pointee=left_buffer_comm%mats(1, v_ki + 1)%data_area) + left_index_rp => left_buffer_comm%mats( & + 1, v_ki + 1 & + )%index(1: & + left_sizes(imeta, left_src_vrow, left_src_vcol)) + ! + left_send_p = left_pgrid(left_send_prow, left_send_pcol) + left_recv_p = left_pgrid(left_recv_prow, left_recv_pcol) + ! These are column-communicator relative + IF (dbcsr_mp_has_subgroups(left_mp_obj)) THEN + left_send_p = left_send_pcol + left_recv_p = left_recv_pcol + grp = dbcsr_mp_my_row_group(left_mp_obj) + ELSE + grp = dbcsr_mp_group(left_mp_obj) + END IF + ! + CALL timeset(routineN//"_metrocomm4", handle2) + IF (.not. has_acc) THEN + CALL dbcsr_irecv_any(left_data_rp, left_recv_p, & + grp, left_data_rr(v_ki + 1), tag=left_src_vcol) + ELSE + msglen = left_sizes(idata, left_src_vrow, left_src_vcol) +#if defined (__DBCSR_ACC) + CALL C_F_POINTER(acc_devmem_cptr(left_buffer_comm%mats( & + 1, v_ki + 1)%data_area%d%acc_devmem), & + left_data_rp%d%r_dp, (/msglen/)) +#endif + CALL mp_irecv(left_data_rp%d%r_dp, & + left_recv_p, grp, & + left_data_rr(v_ki + 1), tag=left_src_vcol) + END IF + CALL mp_irecv(left_index_rp, left_recv_p, & + grp, left_index_rr(v_ki + 1), tag=left_src_vcol) + IF (.not. has_acc) THEN + CALL dbcsr_isend_any(left_data_sp, left_send_p, & + grp, left_data_sr(v_ki + 1), tag=left_dst_vcol) + ELSE + msglen = left_sizes(idata, left_dst_vrow, left_dst_vcol) +#if defined (__DBCSR_ACC) + CALL C_F_POINTER(acc_devmem_cptr(left_buffer_calc%mats( & + 1, v_ki + 1)%data_area%d%acc_devmem), & + left_data_sp%d%r_dp, (/msglen/)) +#endif + CALL mp_isend(left_data_sp%d%r_dp, & + left_send_p, grp, & + left_data_sr(v_ki + 1), tag=left_dst_vcol) + END IF + CALL mp_isend(left_index_sp, left_send_p, & + grp, left_index_sr(v_ki + 1), tag=left_dst_vcol) + dbcsr_mpi_statistics%nexchanged = dbcsr_mpi_statistics%nexchanged + 1 + CALL count_mpi_statistics(dbcsr_mpi_statistics%data_size(2, :), & + dbcsr_data_get_size(left_data_rp), & + data_type_byte, & + dbcsr_mpi_statistics%data_size_breakdown(:, :, 2)) + CALL timestop(handle2) + END DO + END IF xfer_left + + ! Do multiplication + + ! If no GPU backend, calculate norms on the CPU + IF (otf_filtering .and. .not. has_acc) THEN + left_norms(:) = huge_norm + right_norms(:) = huge_norm + CALL calculate_norms(right_buffer_calc%mats(v_ki_right, 1), & + right_norms, k_sizes, n_sizes) + CALL calculate_norms(left_buffer_calc%mats(1, v_ki_left), & + left_norms, m_sizes, k_sizes) + END IF + ! + flop_single = 0 + threads_finished = 0 + +!$OMP PARALLEL DEFAULT (NONE) & +!$OMP SHARED (left_buffer_calc, right_buffer_calc, & +!$OMP v_ki_left, v_ki_right, handle2, handle3, & +!$OMP product_matrix, multrec,& +!$OMP filter_eps, right_norms, left_norms, row_max_epss, & +!$OMP keep_sparsity,threads_finished, & +!$OMP right_data_sr, right_data_rr, right_index_sr, right_index_rr, & +!$OMP left_data_sr, left_data_rr, left_index_sr, left_index_rr, & +!$OMP dbcsr_cfg, k_sizes, nvirt_k, metronome) & +!$OMP PRIVATE (ithread,nthreads,threads_finished_read) & +!$OMP REDUCTION (+: flop_single) + ithread = 0; nthreads = 1 +!$ ithread = omp_get_thread_num(); nthreads = omp_get_num_threads() + + CALL timeset(routineN//"_multrec", handle2) + + CALL dbcsr_mm_multrec_multiply(multrec(ithread)%p, & + left=left_buffer_calc%mats(1, v_ki_left), & + right=right_buffer_calc%mats(v_ki_right, 1), & + flop=flop_single, & + a_norms=left_norms, b_norms=right_norms, & + k_sizes=k_sizes) + + IF (metronome == nvirt_k - 1) THEN + CALL timeset(routineN//"_multrec_finalize", handle3) + CALL dbcsr_mm_multrec_finalize(multrec(ithread)%p) + DEALLOCATE (multrec(ithread)%p) + CALL timestop(handle3) + END IF + +!$OMP ATOMIC + threads_finished = threads_finished + 1 + IF (dbcsr_cfg%use_comm_thread%val .AND. (ithread .EQ. 0)) THEN + DO +! requires OMP 3.1 (e.g. gcc >=4.7), for correctness, otherwise we keep fingers crossed +#if defined _OPENMP && _OPENMP >= 200711 +!$OMP ATOMIC READ +#endif + threads_finished_read = threads_finished + IF (threads_finished_read .EQ. nthreads) EXIT + ! Using MPI_Testany to trigger forward progress in MPI + CALL mp_testany(right_data_sr) + CALL mp_testany(right_data_rr) + CALL mp_testany(left_data_sr) + CALL mp_testany(left_data_rr) + CALL mp_testany(right_index_sr) + CALL mp_testany(right_index_rr) + CALL mp_testany(left_index_sr) + CALL mp_testany(left_index_rr) + END DO + END IF +!$OMP BARRIER + CALL timestop(handle2) + +!$OMP END PARALLEL + flop_total = flop_total + flop_single + ! + ! Move to the next images + IF (v_ki_left .EQ. left_col_nimages) THEN + CALL dbcsr_switch(left_buffer_calc, left_buffer_comm) + END IF + IF (v_ki_right .EQ. right_row_nimages) THEN + CALL dbcsr_switch(right_buffer_calc, right_buffer_comm) + CALL dbcsr_switch(trs_stackbuf_calc, trs_stackbuf_comm) + END IF + + END DO grouped_k_index + CALL timestop(handle1) + CALL m_memory(mem) + max_memory = MAX(max_memory, REAL(mem)) + + IF (has_acc) THEN + CALL dbcsr_data_release(trs_stackbuf_1) + CALL dbcsr_data_release(trs_stackbuf_2) + DEALLOCATE (row_blk_sizes2enum, enum2row_blk_sizes) + DEALLOCATE (col_blk_sizes2enum, enum2col_blk_sizes) + IF (otf_filtering) THEN + CALL dbcsr_data_release(normsbuf) + CALL dbcsr_data_release(offsetsbuf) + CALL dbcsr_data_release(nelemsbuf) + END IF + END IF + + IF (ALLOCATED(right_norms)) THEN + DEALLOCATE (right_norms) + END IF + IF (ALLOCATED(left_norms)) THEN + DEALLOCATE (left_norms) + END IF + IF (ALLOCATED(row_max_epss)) THEN + DEALLOCATE (row_max_epss) + END IF + ! + CALL dbcsr_destroy_array(right_buffer_2) + CALL dbcsr_destroy_array(left_buffer_2) + DEALLOCATE (my_sizes) + ! + CALL dbcsr_data_clear_pointer(left_data_sp) + CALL dbcsr_data_clear_pointer(left_data_rp) + CALL dbcsr_data_clear_pointer(right_data_sp) + CALL dbcsr_data_clear_pointer(right_data_rp) + CALL dbcsr_data_release(left_data_sp) + CALL dbcsr_data_release(left_data_rp) + CALL dbcsr_data_release(right_data_sp) + CALL dbcsr_data_release(right_data_rp) + ! + DEALLOCATE (left_data_rr, left_data_sr, left_index_rr, left_index_sr, & + right_data_rr, right_data_sr, right_index_rr, right_index_sr) + ! + ! + IF (debug_mod) THEN + v_ki = 0 + DO i = 1, SIZE(product_matrix%blk_p) + v_ki = MAX(v_ki, ABS(product_matrix%blk_p(i))) + END DO + WRITE (*, *) routineN//" Actual final size", & + LOG(REAL(dbcsr_data_get_size(product_matrix%data_area)))/LOG(10.0), & + LOG(REAL(v_ki))/LOG(10.0) + END IF + ! + flop = flop_total + DEALLOCATE (left_buffer_2, right_buffer_2) + DEALLOCATE (m_sizes, n_sizes) + IF (ASSOCIATED(k_sizes)) DEALLOCATE (k_sizes) + ! + CALL timestop(handle) + END SUBROUTINE multiply_cannon_g2g + SUBROUTINE setup_buffer_matrices(buffer_set, buff_nrows, buff_ncols, & source_matrix, index_size, data_size) TYPE(dbcsr_2d_array_type), INTENT(OUT) :: buffer_set diff --git a/src/mm/dbcsr_mm_common.F b/src/mm/dbcsr_mm_common.F index 937043f23e9..af586472eb7 100644 --- a/src/mm/dbcsr_mm_common.F +++ b/src/mm/dbcsr_mm_common.F @@ -1,5 +1,6 @@ !--------------------------------------------------------------------------------------------------! ! Copyright (C) by the DBCSR developers group - All rights reserved ! +! Copyright (C) 2022 Advanced Micro Devices, Inc. - All rights reserved ! ! This file is part of the DBCSR library. ! ! ! ! For information on the license, see the LICENSE file. ! @@ -12,16 +13,22 @@ MODULE dbcsr_mm_common !! Modification history: !! - 2016-08 Code organization (Alfio Lazzaro). + USE ISO_C_BINDING, ONLY: C_PTR, C_INT + USE dbcsr_acc_event, ONLY: acc_event_record, & acc_event_synchronize, & acc_stream_wait_event - USE dbcsr_acc_stream, ONLY: acc_stream_type + USE dbcsr_acc_stream, ONLY: acc_stream_type, & + acc_stream_synchronize, & + acc_stream_cptr + USE dbcsr_acc_devmem, ONLY: acc_devmem_cptr USE dbcsr_array_types, ONLY: array_data, & array_hold USE dbcsr_acc_operations, ONLY: dbcsr_acc_transpose USE dbcsr_data_methods, ONLY: dbcsr_data_ensure_size, & dbcsr_data_get_size, & dbcsr_data_host2dev, & + dbcsr_data_dev2host, & dbcsr_data_set_size_referenced, & dbcsr_get_data_p_c, & dbcsr_get_data_p_d, & @@ -67,6 +74,8 @@ MODULE dbcsr_mm_common TYPE(dbcsr_memtype_type), SAVE :: memtype_abpanel_1, memtype_abpanel_2, & memtype_trsbuffer_1, memtype_trsbuffer_2, & + memtype_normsbuf, memtype_offsetsbuf, & + memtype_nelemsbuf, & memtype_mpi_buffer, memtype_mpi_product TYPE(acc_stream_type), SAVE :: stream_1, stream_2 ! ab-panels and streams are shared between all threads @@ -83,6 +92,8 @@ MODULE dbcsr_mm_common PUBLIC :: memtype_abpanel_1, memtype_abpanel_2, & memtype_trsbuffer_1, memtype_trsbuffer_2, & + memtype_normsbuf, memtype_offsetsbuf, & + memtype_nelemsbuf, & memtype_mpi_buffer, memtype_mpi_product PUBLIC :: stream_1, stream_2 @@ -93,6 +104,7 @@ MODULE dbcsr_mm_common PUBLIC :: enumerate_blk_sizes PUBLIC :: acc_transpose_blocks + PUBLIC :: acc_calculate_norms PUBLIC :: product_matrix_size_guess @@ -100,6 +112,24 @@ MODULE dbcsr_mm_common PUBLIC :: huge_norm PUBLIC :: local_filter +#if defined (__DBCSR_ACC) + INTERFACE + FUNCTION acc_interface_calculate_norms(mat, nblks, offsets, nelems, norms, stream_ptr) RESULT(istat) & + BIND(C, name="c_calculate_norms") + IMPORT + TYPE(C_PTR), INTENT(IN), VALUE :: mat + TYPE(C_PTR), INTENT(IN), VALUE :: offsets + TYPE(C_PTR), INTENT(IN), VALUE :: nelems + TYPE(C_PTR), VALUE :: norms + INTEGER(KIND=C_INT), INTENT(IN), & + VALUE :: nblks + TYPE(C_PTR), VALUE :: stream_ptr + INTEGER(KIND=C_INT) :: istat + + END FUNCTION acc_interface_calculate_norms + END INTERFACE +#endif + CONTAINS SUBROUTINE count_mpi_statistics(mpi_statistics, data_size, & @@ -463,6 +493,101 @@ SUBROUTINE acc_transpose_blocks(matrix, trs_stackbuf, & CALL timestop(handle) END SUBROUTINE acc_transpose_blocks + SUBROUTINE acc_calculate_norms(matrix, norms, normsbuf, offsetsbuf, nelemsbuf, row_blk_sizes, col_blk_sizes) + !! calculate norms for a set of blocks in matrix whose row and col sizes are given + TYPE(dbcsr_type), INTENT(IN) :: matrix + REAL(kind=sp), DIMENSION(:), INTENT(OUT) :: norms + TYPE(dbcsr_data_obj), INTENT(INOUT), TARGET :: normsbuf + TYPE(dbcsr_data_obj), INTENT(INOUT), TARGET :: offsetsbuf + TYPE(dbcsr_data_obj), INTENT(INOUT), TARGET :: nelemsbuf + INTEGER, DIMENSION(:), POINTER, CONTIGUOUS, INTENT(IN) :: row_blk_sizes, col_blk_sizes + + CHARACTER(len=*), PARAMETER :: routineN = 'acc_calculate_norms' + + INTEGER :: nblks, blk_p, handle, i + INTEGER :: nblks_final, j + INTEGER :: data_type + INTEGER :: row, col + INTEGER, DIMENSION(:), POINTER :: blk_index + REAL, DIMENSION(:), POINTER, CONTIGUOUS :: normsbuf_ptr + INTEGER, DIMENSION(:), POINTER, CONTIGUOUS :: offsetsbuf_ptr + INTEGER, DIMENSION(:), POINTER, CONTIGUOUS :: nelemsbuf_ptr +#if defined (__DBCSR_ACC) + INTEGER :: istat +#endif + + CALL timeset(routineN, handle) + + blk_index => matrix%coo_l + nblks = matrix%nblks + data_type = dbcsr_get_data_type(matrix) + + if (nblks > 0 .and. data_type .eq. dbcsr_type_real_8) then + + IF (normsbuf%d%data_type /= dbcsr_type_real_4) & + DBCSR_ABORT("acc_calculate_norms: normsbuf has wrong datatype") + IF (offsetsbuf%d%data_type /= dbcsr_type_int_4) & + DBCSR_ABORT("acc_calculate_norms: offsetsbuf has wrong datatype") + IF (nelemsbuf%d%data_type /= dbcsr_type_int_4) & + DBCSR_ABORT("acc_calculate_norms: nelemsbuf has wrong datatype") + + NULLIFY (normsbuf_ptr) + NULLIFY (offsetsbuf_ptr) + NULLIFY (nelemsbuf_ptr) + CALL dbcsr_data_ensure_size(normsbuf, data_size=nblks, nocopy=.TRUE.) + CALL dbcsr_data_set_size_referenced(normsbuf, nblks) + normsbuf_ptr => normsbuf%d%r_sp + CALL dbcsr_data_ensure_size(offsetsbuf, data_size=nblks, nocopy=.TRUE.) + CALL dbcsr_data_set_size_referenced(offsetsbuf, nblks) + offsetsbuf_ptr => offsetsbuf%d%i4 + CALL dbcsr_data_ensure_size(nelemsbuf, data_size=nblks, nocopy=.TRUE.) + CALL dbcsr_data_set_size_referenced(nelemsbuf, nblks) + nelemsbuf_ptr => nelemsbuf%d%i4 + + j = 1 + DO i = 1, nblks + blk_p = blk_index(3*i) + IF (blk_p == 0) CYCLE + offsetsbuf_ptr(j) = blk_p - 1 + row = blk_index(3*i - 2) + col = blk_index(3*i - 1) + nelemsbuf_ptr(j) = row_blk_sizes(row)*col_blk_sizes(col) + j = j + 1 + END DO + nblks_final = j - 1 + + ! copy offsets to GPU buffer, launch kernel, copy norms back to host + ! offsetsbuf, nelemsbuf and normsbuf share the same stream, so no need + ! to synchronize stream until norms are copied back to host + CALL dbcsr_data_host2dev(offsetsbuf) + CALL dbcsr_data_host2dev(nelemsbuf) +#if defined (__DBCSR_ACC) + istat = acc_interface_calculate_norms(acc_devmem_cptr(matrix%data_area%d%acc_devmem), & + INT(nblks_final, KIND=C_INT), & + acc_devmem_cptr(offsetsbuf%d%acc_devmem), & + acc_devmem_cptr(nelemsbuf%d%acc_devmem), & + acc_devmem_cptr(normsbuf%d%acc_devmem), & + acc_stream_cptr(normsbuf%d%memory_type%acc_stream)) + IF (istat == -1) & + DBCSR_ABORT("acc_calculate_norms: warp size obtained is unexpected") +#endif + CALL dbcsr_data_dev2host(normsbuf) + CALL acc_stream_synchronize(normsbuf%d%memory_type%acc_stream) + + j = 1 + DO i = 1, nblks + blk_p = blk_index(3*i) + IF (blk_p == 0) CYCLE + norms(i) = normsbuf_ptr(j) + j = j + 1 + END DO + else + ! call CPU function to calculate norms + CALL calculate_norms(matrix, norms, row_blk_sizes, col_blk_sizes) + end if + CALL timestop(handle) + END SUBROUTINE acc_calculate_norms + FUNCTION product_matrix_size_guess(matrix_left, matrix_right, product_matrix, & !! Guess the size of the product matrix from the A and B sparsities left_data_size, right_data_size, & diff --git a/src/work/dbcsr_work_operations.F b/src/work/dbcsr_work_operations.F index 8a4e100d13e..dbab7e229aa 100644 --- a/src/work/dbcsr_work_operations.F +++ b/src/work/dbcsr_work_operations.F @@ -769,7 +769,9 @@ SUBROUTINE dbcsr_finalize(matrix, reshuffle) CALL timeset(routineN, handle) +!$OMP MASTER NULLIFY (old_blk_p, old_col_i, old_row_p) +!$OMP END MASTER !$OMP BARRIER ! If the matrix is not marked as dirty then skip the work. diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 6be544b1fd1..1eeadafb63d 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,15 +1,22 @@ +# =================================== OpenMP +if (USE_OPENMP) + set(NUM_THREADS ${TEST_OMP_THREADS}) +else () + set(NUM_THREADS 1) +endif () + # =================================== MPI if (USE_MPI) if (TEST_MPI_RANKS STREQUAL "auto") include(ProcessorCount) ProcessorCount(nproc) - math(EXPR num_ranks "(${nproc}+${TEST_OMP_THREADS}-1)/${TEST_OMP_THREADS}" - )# get 1/$TEST_OMP_THREADS the number of procs (rounded up) + math(EXPR num_ranks "(${nproc}+${NUM_THREADS}-1)/${NUM_THREADS}" + )# get 1/$NUM_THREADS the number of procs (rounded up) else () set(num_ranks ${TEST_MPI_RANKS}) endif () message( - "Tests will run with ${num_ranks} MPI ranks and ${TEST_OMP_THREADS} OpenMP threads each" + "Tests will run with ${num_ranks} MPI ranks and ${NUM_THREADS} OpenMP threads each" ) endif () @@ -45,9 +52,8 @@ foreach (dbcsr_perf_test ${DBCSR_PERF_TESTS}) COMMAND $ "${CMAKE_CURRENT_SOURCE_DIR}/${dbcsr_perf_test}") endif () - set_tests_properties( - dbcsr_perf:${dbcsr_perf_test} - PROPERTIES ENVIRONMENT OMP_NUM_THREADS=${TEST_OMP_THREADS}) + set_tests_properties(dbcsr_perf:${dbcsr_perf_test} + PROPERTIES ENVIRONMENT OMP_NUM_THREADS=${NUM_THREADS}) endforeach () # =================================== DBCSR CORRECTNESS TESTS Define all the @@ -96,16 +102,16 @@ set(dbcsr_unittest_common_SRCS dbcsr_test_add.F dbcsr_test_multiply.F) # OBJECT lib, but we would need cmake 3.12 to be able to specify # target_link_libraries on those to get the proper compile flags add_library(dbcsr_unittest_common STATIC ${dbcsr_unittest_common_SRCS}) +# target_link_libraries(dbcsr_unittest_common PUBLIC dbcsr) target_link_libraries(dbcsr_unittest_common PUBLIC ${BLAS_LIBRARIES} ${LAPACK_LIBRARIES}) if (OpenMP_FOUND) target_link_libraries(dbcsr_unittest_common PUBLIC OpenMP::OpenMP_Fortran) endif () - if (APPLE AND BLAS_LIBRARIES MATCHES "Accelerate") target_compile_definitions(dbcsr_unittest_common PRIVATE __ACCELERATE) endif () -target_link_libraries(dbcsr_unittest_common PUBLIC dbcsr) +target_link_libraries(dbcsr_unittest_common PUBLIC dbcsr) # last # Compile Fortran tests foreach (dbcsr_test ${DBCSR_TESTS_FTN}) @@ -125,8 +131,8 @@ foreach (dbcsr_test ${DBCSR_TESTS_FTN}) endif () if (OpenMP_FOUND) target_link_libraries(${dbcsr_test} OpenMP::OpenMP_Fortran) - set_tests_properties( - ${dbcsr_test} PROPERTIES ENVIRONMENT OMP_NUM_THREADS=${TEST_OMP_THREADS}) + set_tests_properties(${dbcsr_test} + PROPERTIES ENVIRONMENT OMP_NUM_THREADS=${NUM_THREADS}) endif () endforeach () @@ -158,7 +164,7 @@ if (WITH_C_API) if (OpenMP_FOUND) set_tests_properties( ${dbcsr_test_cpp_name} PROPERTIES ENVIRONMENT - OMP_NUM_THREADS=${TEST_OMP_THREADS}) + OMP_NUM_THREADS=${NUM_THREADS}) endif () endforeach () endif () @@ -175,7 +181,7 @@ if (NOT USE_MPI) if (OpenMP_FOUND) set_tests_properties( ${dbcsr_test_backend} PROPERTIES ENVIRONMENT - OMP_NUM_THREADS=${TEST_OMP_THREADS}) + OMP_NUM_THREADS=${NUM_THREADS}) endif () endforeach () endif () diff --git a/tests/dbcsr_test.cpp b/tests/dbcsr_test.cpp index e7fa02bb0d4..b7865101440 100644 --- a/tests/dbcsr_test.cpp +++ b/tests/dbcsr_test.cpp @@ -51,8 +51,8 @@ int main(int argc, char* argv[]) { for (int i = 0; i != mpi_size; ++i) { if (mpi_rank == i) { - std::cout << "I'm processor " << mpi_rank << " over " << mpi_size << " proc" - << ", (" << coord[0] << ", " << coord[1] << ") in the 2D grid" << std::endl; + std::cout << "I'm processor " << mpi_rank << " over " << mpi_size << " proc" << ", (" << coord[0] << ", " << coord[1] + << ") in the 2D grid" << std::endl; } MPI_Barrier(MPI_COMM_WORLD); } diff --git a/tests/dbcsr_test_multiply.F b/tests/dbcsr_test_multiply.F index ebd4a8a0ea3..10e2b540c29 100644 --- a/tests/dbcsr_test_multiply.F +++ b/tests/dbcsr_test_multiply.F @@ -70,7 +70,7 @@ SUBROUTINE dbcsr_test_multiplies(test_name, mp_group, mp_env, npdims, io_unit, & !! processor grids CHARACTER(len=*), INTENT(IN) :: test_name - TYPE(mp_comm_type), INTENT(IN) :: mp_group + TYPE(mp_comm_type), INTENT(IN) :: mp_group !! MPI communicator TYPE(dbcsr_mp_obj), INTENT(IN) :: mp_env INTEGER, DIMENSION(2), INTENT(in) :: npdims @@ -208,7 +208,7 @@ SUBROUTINE dbcsr_test_multiplies(test_name, mp_group, mp_env, npdims, io_unit, & CALL dbcsr_make_random_block_sizes(sizes_k, matrix_sizes(3), bs_k) ! - ! if we have symmetry the row and column block sizes hae to match + ! if we have symmetry the row and column block sizes have to match IF (c_symm .NE. dbcsr_type_no_symmetry .AND. a_symm .NE. dbcsr_type_no_symmetry .AND. & b_symm .NE. dbcsr_type_no_symmetry) THEN my_sizes_m => sizes_m @@ -750,8 +750,8 @@ SUBROUTINE dbcsr_check_multiply(test_name, matrix_c, dense_c_dbcsr, dense_a, den DBCSR_ABORT("Incorrect or 1-D data type") END SELECT - eps_norm = residual/((a_norm + b_norm + c_norm_in)*REAL(n, real_8)*eps) IF (mynode .EQ. 0) THEN + eps_norm = residual/((a_norm + b_norm + c_norm_in)*REAL(n, real_8)*eps) IF (eps_norm .GT. 10.0_real_8) THEN success = .FALSE. ELSE @@ -761,6 +761,7 @@ SUBROUTINE dbcsr_check_multiply(test_name, matrix_c, dense_c_dbcsr, dense_a, den ! ! synchronize the result... CALL mp_bcast(success, 0, mp_group) + CALL mp_bcast(eps_norm, 0, mp_group) ! ! printing IF (io_unit .GT. 0) THEN diff --git a/tools/docker/Dockerfile.build-env-rocm b/tools/docker/Dockerfile.build-env-rocm index 9703a032d75..f2117dbab20 100644 --- a/tools/docker/Dockerfile.build-env-rocm +++ b/tools/docker/Dockerfile.build-env-rocm @@ -1,4 +1,4 @@ -FROM rocm/dev-ubuntu-20.04:latest +FROM rocm/dev-ubuntu-22.04:latest ENV DEBIAN_FRONTEND=noninteractive @@ -14,7 +14,7 @@ RUN set -ex ; \ curl -LsS https://apt.kitware.com/keys/kitware-archive-latest.asc \ | gpg --dearmor - \ | tee /etc/apt/trusted.gpg.d/kitware.gpg >/dev/null ; \ - apt-add-repository 'deb https://apt.kitware.com/ubuntu/ focal main' ; \ + apt-add-repository 'deb https://apt.kitware.com/ubuntu/ jammy main' ; \ apt-get install -y \ locales \ gfortran \ diff --git a/tools/docker/Dockerfile.build-env-ubuntu b/tools/docker/Dockerfile.build-env-ubuntu index 2216177e556..73c935dec18 100644 --- a/tools/docker/Dockerfile.build-env-ubuntu +++ b/tools/docker/Dockerfile.build-env-ubuntu @@ -1,4 +1,4 @@ -FROM ubuntu:20.04 +FROM ubuntu:22.04 # we need at least Ubuntu 19.10 for: # git > 2.18 @@ -22,15 +22,15 @@ RUN set -ex ; \ curl -LsS https://apt.kitware.com/keys/kitware-archive-latest.asc \ | gpg --dearmor - \ | tee /etc/apt/trusted.gpg.d/kitware.gpg >/dev/null ; \ - apt-add-repository 'deb https://apt.kitware.com/ubuntu/ focal main' ; \ + apt-add-repository 'deb https://apt.kitware.com/ubuntu/ jammy main' ; \ apt-get install -y \ locales \ gfortran \ g++ \ openmpi-bin \ libopenmpi-dev \ - mpich \ - libmpich-dev \ + mpich \ + libmpich-dev \ libopenblas-openmp-dev \ cmake \ ninja-build \ @@ -64,6 +64,12 @@ RUN set -ex ; \ ENV PKG_CONFIG_PATH="/opt/libxsmm/lib:${PKG_CONFIG_PATH}" +# Remove LTO for MPICH (default now in Ubuntu >=22) +RUN set -ex ; \ + for ff in /usr/lib/x86_64-linux-gnu/pkgconfig/mpich.pc /usr/bin/mpicc.mpich /usr/bin/mpicxx.mpich /usr/bin/mpif77.mpich /usr/bin/mpif90.mpich /usr/bin/mpifort.mpich; do \ + sed -i -e 's/-flto=auto//g' -e 's/-ffat-lto-objects//g' ${ff}; \ + done + # Leak suppression COPY lsan.supp /opt ENV LSAN_OPTIONS=suppressions=/opt/lsan.supp diff --git a/tools/docker/Dockerfile.build-env-ubuntu-cuda b/tools/docker/Dockerfile.build-env-ubuntu-cuda index 201cd79e06a..bdcc7bc109d 100644 --- a/tools/docker/Dockerfile.build-env-ubuntu-cuda +++ b/tools/docker/Dockerfile.build-env-ubuntu-cuda @@ -1,5 +1,4 @@ -FROM nvidia/cuda:11.6.0-devel-ubuntu20.04 - +FROM nvidia/cuda:12.2.0-devel-ubuntu22.04 ENV DEBIAN_FRONTEND=noninteractive RUN set -ex ; \ @@ -14,7 +13,7 @@ RUN set -ex ; \ curl -LsS https://apt.kitware.com/keys/kitware-archive-latest.asc \ | gpg --dearmor - \ | tee /etc/apt/trusted.gpg.d/kitware.gpg >/dev/null ; \ - apt-add-repository 'deb https://apt.kitware.com/ubuntu/ focal main' ; \ + apt-add-repository 'deb https://apt.kitware.com/ubuntu/ jammy main' ; \ apt-get install -y \ locales \ gfortran \ diff --git a/tools/docker/Makefile b/tools/docker/Makefile new file mode 100644 index 00000000000..69237778935 --- /dev/null +++ b/tools/docker/Makefile @@ -0,0 +1,4 @@ +all: build-env-latest-gcc build-env-rocm build-env-ubuntu build-env-ubuntu-cuda + +build-env-%: Dockerfile.build-env-% + docker build -t dbcsr-$@ -f $< . diff --git a/tools/docker/README.md b/tools/docker/README.md index 60cb8cdb01e..60cc6aacb5a 100644 --- a/tools/docker/README.md +++ b/tools/docker/README.md @@ -4,7 +4,7 @@ All images are hosted on the [GitHub Container Registry of the CP2K organization ## Ubuntu Build Environment -The image is based on Ubuntu 20.04 and contains: +The image is based on Ubuntu 22.04 and contains: * GNU Fortran Compiler * OpenBLAS @@ -19,7 +19,7 @@ The image is based on Ubuntu 20.04 and contains: ```console $ cd dbcsr -$ docker run --rm -it -v $PWD:/app --workdir /app --user $(id -u):$(id -g) ghcr.io/cp2k/dbcsr-build-env-ubuntu-20.04 /bin/bash +$ docker run --rm -it -v $PWD:/app --workdir /app --user $(id -u):$(id -g) ghcr.io/cp2k/dbcsr-build-env-ubuntu-22.04 /bin/bash $ mkdir build && cd build/ $ cmake -G Ninja .. $ cmake --build . @@ -31,12 +31,12 @@ If you need to rebuild the image, use: ```console $ cd dbcsr/tools/docker -$ docker build -t dbcsr-build-env-ubuntu-20.04 -f Dockerfile.build-env-ubuntu . +$ docker build -t dbcsr-build-env-ubuntu-22.04 -f Dockerfile.build-env-ubuntu . ``` ## ROCm Build Environment -The image is based on Ubuntu 20.04 and contains: +The image is based on Ubuntu 22.04 and contains: * GNU Fortran Compiler * OpenBLAS