pax_global_header00006660000000000000000000000064145053470140014515gustar00rootroot0000000000000052 comment=f0c400a5b5af32c8252a9aa5a7c10acbe98e882b level-zero-raytracing-support-1.0.0/000077500000000000000000000000001450534701400174525ustar00rootroot00000000000000level-zero-raytracing-support-1.0.0/.github/000077500000000000000000000000001450534701400210125ustar00rootroot00000000000000level-zero-raytracing-support-1.0.0/.github/workflows/000077500000000000000000000000001450534701400230475ustar00rootroot00000000000000level-zero-raytracing-support-1.0.0/.github/workflows/continuous.yml000066400000000000000000000305521450534701400260050ustar00rootroot00000000000000## Copyright 2022 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 name: continuous on: [push, workflow_dispatch] jobs: ze_raytracing-ubuntu22_04-GCC: secrets: inherit uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main with: image: embree/ubuntu:22.04 runs-on: '[ "Linux", "docker", "build" ]' cmd: | mkdir build cd build cmake -G Ninja -D CMAKE_CXX_COMPILER=g++ -D CMAKE_C_COMPILER=gcc -D CMAKE_BUILD_TYPE=Release .. cmake --build . --target package ubuntu22_04-pkg-build: secrets: inherit uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main with: image: gfx-build/testinstall-ubuntu22.04:18 runs-on: '[ "Linux", "docker", "build" ]' artifact-out: ubuntu22_04-pkg-build artifact-path: intel-level-zero-gpu-raytracing_*.dsc intel-level-zero-gpu-raytracing_*.tar.xz intel-level-zero-gpu-raytracing_*amd64.deb intel-level-zero-gpu-raytracing_*amd64.buildinfo pre-cmd: | apt update eatmydata apt -y install git git-lfs cmd: | # Build source packages. mkdir intel-level-zero-gpu-raytracing cp -r * intel-level-zero-gpu-raytracing || true cd intel-level-zero-gpu-raytracing git clone -b v2021.6.0 https://github.com/oneapi-src/oneTBB.git tbb dpkg-buildpackage -j`nproc --all` --no-sign -S -d -rfakeroot cd .. # Install source package in intel-level-zero-gpu-raytracing-build dir. # Then we are going to build binaries from it. # Keep in mind that packages will be written to this dir. eatmydata apt-get build-dep -y ./intel-level-zero-gpu-raytracing_*.dsc dpkg-source -x ./intel-level-zero-gpu-raytracing*.dsc intel-level-zero-gpu-raytracing-build cd intel-level-zero-gpu-raytracing-build dpkg-buildpackage -j`nproc --all` -B --no-sign -rfakeroot rhel_86-pkg-build: secrets: inherit uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main with: image: gfx-build/rhel-8.6:17 runs-on: '[ "Linux", "docker", "build" ]' artifact-out: rhel_86-pkg-build artifact-path: intel-level-zero-gpu-raytracing*.rpm pre-cmd: | dnf makecache dnf install -y git git-lfs rpmdevtools cmd: | VERSION="1.0.0" # Prep the source tar exactly like defined in spec file rm -rf /build/* mkdir -p /build/intel-level-zero-gpu-raytracing-$VERSION cp -r * /build/intel-level-zero-gpu-raytracing-$VERSION || true pushd /build/intel-level-zero-gpu-raytracing-$VERSION git clone -b v2021.6.0 https://github.com/oneapi-src/oneTBB.git tbb rm -rf ~/rpmbuild rpmdev-setuptree && cd /build tar czf ~/rpmbuild/SOURCES/intel-level-zero-gpu-raytracing-$VERSION.tar.gz intel-level-zero-gpu-raytracing-$VERSION cp -pr intel-level-zero-gpu-raytracing-$VERSION/rhel/intel-level-zero-gpu-raytracing.spec ~/rpmbuild/SPECS/intel-level-zero-gpu-raytracing.spec # Build starts here # Build rpm src pkg first, ignoring dependencies because it's only source rpm rpmbuild -bs --nodeps '--define=dist .el8_6' ~/rpmbuild/SPECS/intel-level-zero-gpu-raytracing.spec #Make sure rpmbuild uses src tarball and not above created sources rm -rf ~/rpmbuild/SOURCES/intel-level-zero-gpu-raytracing-$VERSION.tar.gz # Build binary pkgs from source pkg, but first install dependencies dnf builddep -y ~/rpmbuild/SRPMS/*.src.rpm rpmbuild --rebuild '--define=dist .el8_6' --define='__cmake_builddir .' ~/rpmbuild/SRPMS/*.src.rpm # Test install the built package dnf install -y ~/rpmbuild/RPMS/*/*.rpm # Copy artifacts popd rm -rf ~/rpmbuild/RPMS/*/intel-level-zero-gpu-raytracing-debug*.rpm cp -pr ~/rpmbuild/RPMS/*/*.rpm . rm -rf ~/rpmbuild sles_15sp4-pkg-build: secrets: inherit uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main with: image: gfx-build/testinstall-sle15-15.4:45 runs-on: '[ "Linux", "docker", "build" ]' artifact-out: sles_15sp4-pkg-build artifact-path: intel-level-zero-gpu-raytracing*.rpm pre-cmd: | unset no_proxy unset NO_PROXY zypper ref -s zypper install -y git rpmbuild # Add repo with Intel graphics stack dependencies zypper addrepo -r https://repositories.intel.com/graphics/sles/15sp4/intel-graphics.repo zypper --non-interactive --gpg-auto-import-keys refresh cmd: | unset no_proxy unset NO_PROXY VERSION="1.0.0" # Prep the source tar exactly like defined in spec file rm -rf /tmp/* mkdir -p /tmp/intel-level-zero-gpu-raytracing-$VERSION cp -r * /tmp/intel-level-zero-gpu-raytracing-$VERSION || true pushd /tmp/intel-level-zero-gpu-raytracing-$VERSION git clone -b v2021.6.0 https://github.com/oneapi-src/oneTBB.git tbb rm -rf ~/rpmbuild rpmdev-setuptree && cd /tmp tar czf ~/rpmbuild/SOURCES/intel-level-zero-gpu-raytracing-$VERSION.tar.gz intel-level-zero-gpu-raytracing-$VERSION cp -pr intel-level-zero-gpu-raytracing-$VERSION/sle/intel-level-zero-gpu-raytracing.spec ~/rpmbuild/SPECS/intel-level-zero-gpu-raytracing.spec # Build starts here # Build rpm src pkg first, ignoring dependencies because it's only source rpm rpmbuild -bs --nodeps ~/rpmbuild/SPECS/intel-level-zero-gpu-raytracing.spec # Set up build dependencies from Intel gfx stack # Build binary pkgs from source pkg, but first remove created sources and install dependencies rm -rf ~/rpmbuild/SOURCES/intel-level-zero-gpu-raytracing*.tar.gz zypper --non-interactive si ~/rpmbuild/SRPMS/*.src.rpm rpmbuild --rebuild ~/rpmbuild/SRPMS/*.src.rpm # Test install the built package zypper install --allow-unsigned-rpm -y ~/rpmbuild/RPMS/*/*.rpm # Copy artifacts popd rm -rf ~/rpmbuild/RPMS/*/intel-level-zero-gpu-raytracing-debug*.rpm cp -pr ~/rpmbuild/RPMS/*/*.rpm . rm -rf ~/rpmbuild ze_raytracing-linux-test: secrets: inherit uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker_gpu.yml@main with: image: embree/ubuntu:22.04 runs-on: '[ "Linux", "docker", "build" ]' env-from-files: ./.github/workflows/dpcpp-sycl-nightly.env install-gfx-driver: false artifact-out: ze_raytracing-linux-test artifact-path: ./build/intel-level-zero-rt-support*.tar.gz cmd: | mkdir build cd build cmake -G Ninja -D CMAKE_BUILD_TYPE=ReleaseInternal -D CMAKE_CXX_COMPILER=clang++ -D CMAKE_C_COMPILER=clang -D ZE_RAYTRACING_SYCL_TESTS=INTERNAL_RTAS_BUILDER .. cmake --build . --target package ze_raytracing-linux-test-DG2: secrets: inherit uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker_gpu.yml@main needs: ["ze_raytracing-linux-test"] with: image: embree/ubuntu:22.04 options: --device=/dev/dri:/dev/dri runs-on: '[ "Linux", "docker", "dg2" ]' env-from-files: ./.github/workflows/gfx-ubuntu22-internal.env artifact-in: ze_raytracing-linux-test cmd: | cd build tar xzf intel-level-zero-rt-support*.x86_64.linux.tar.gz cd intel-level-zero-rt-support*.x86_64.linux cd bin ctest ze_raytracing-linux-test-PVC: secrets: inherit uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker_gpu.yml@main needs: ["ze_raytracing-linux-test"] with: image: embree/ubuntu:22.04 options: --device=/dev/dri:/dev/dri runs-on: '[ "Linux", "docker", "pvc" ]' env-from-files: ./.github/workflows/gfx-ubuntu22-internal.env artifact-in: ze_raytracing-linux-test cmd: | cd build tar xzf intel-level-zero-rt-support*.x86_64.linux.tar.gz cd intel-level-zero-rt-support*.x86_64.linux cd bin ctest ze_raytracing-windows-V142-Debug: secrets: inherit uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/windows.yml@main with: runs-on: '[ "Windows", "NAS", "dg2" ]' shell: cmd cmd: | mkdir build || exit /b cd build || exit /b cmake -G "Visual Studio 16 2019" -T "V142" -A "x64" .. || exit /b cmake --build . --config Debug --target package || exit /b ze_raytracing-windows-V142-Release: secrets: inherit uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/windows.yml@main with: runs-on: '[ "Windows", "NAS", "dg2" ]' shell: cmd cmd: | mkdir build || exit /b cd build || exit /b cmake -G "Visual Studio 16 2019" -T "V142" -A "x64" .. || exit /b cmake --build . --config Release --target package || exit /b ze_raytracing-windows-V142-ReleaseInternal: secrets: inherit uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/windows.yml@main with: runs-on: '[ "Windows", "NAS", "dg2" ]' shell: cmd cmd: | mkdir build || exit /b cd build || exit /b cmake -G "Visual Studio 16 2019" -T "V142" -A "x64" .. || exit /b cmake --build . --config ReleaseInternal --target package || exit /b ze_raytracing-windows-test: secrets: inherit uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/windows_gpu.yml@devel with: runs-on: '[ "Windows", "NAS", "build" ]' env-from-files: ./.github/workflows/dpcpp-sycl-nightly.env install-gfx-driver: false artifact-path: ./build/intel-level-zero-rt-support*.zip artifact-out: ze_raytracing-windows-test shell: cmd cmd: | mkdir build || exit /b cd build || exit /b cmake -G Ninja -D CMAKE_CXX_COMPILER=clang++ -D CMAKE_C_COMPILER=clang -D ZE_RAYTRACING_SYCL_TESTS=INTERNAL_RTAS_BUILDER .. || exit /b cmake --build . --config ReleaseInternal --target package || exit /b ze_raytracing-windows-test-DG2: secrets: inherit uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/windows_gpu.yml@devel needs: ["ze_raytracing-windows-test"] with: runs-on: '[ "Windows", "NAS", "dg2" ]' env-from-files: ./.github/workflows/gfx-windows-internal.env artifact-in: ze_raytracing-windows-test shell: cmd cmd: | cd build || exit /b unzip intel-level-zero-rt-support*.x64.windows.zip || exit /b cd intel-level-zero-rt-support*.x64.windows || exit /b cd bin || exit /b ctest || exit /b static-analysis-klocwork: secrets: inherit uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/static_analysis.yml@main with: project: ze_raytracing_support coverity: false prebuild: | cmake -S . -B build -D CMAKE_CXX_COMPILER=g++ -D CMAKE_C_COMPILER=gcc -D CMAKE_BUILD_TYPE=Release -D ZE_RAYTRACING_TBB_STATIC=ON build: cmake --build build static-analysis-coverity: secrets: inherit uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/static_analysis.yml@main with: project: "Level Zero Ray Tracing Support" coverity: true server: prod4 prebuild: | cmake -S . -B build -D CMAKE_CXX_COMPILER=g++ -D CMAKE_C_COMPILER=gcc -D CMAKE_BUILD_TYPE=Release -D ZE_RAYTRACING_TBB_STATIC=ON build: cmake --build build success: runs-on: ubuntu-latest needs: - ze_raytracing-ubuntu22_04-GCC - ubuntu22_04-pkg-build - rhel_86-pkg-build - sles_15sp4-pkg-build - ze_raytracing-linux-test - ze_raytracing-linux-test-DG2 - ze_raytracing-linux-test-PVC - ze_raytracing-windows-V142-Debug - ze_raytracing-windows-V142-Release - ze_raytracing-windows-V142-ReleaseInternal - ze_raytracing-windows-test - ze_raytracing-windows-test-DG2 - static-analysis-klocwork - static-analysis-coverity if: failure() || cancelled() steps: - name: Failure run: | echo "::notice title=Success::Workflow failed" exit 1 level-zero-raytracing-support-1.0.0/.github/workflows/dpcpp-sycl-nightly.env000066400000000000000000000000431450534701400273100ustar00rootroot00000000000000DPCPP_VERSION=sycl-nightly/20230724level-zero-raytracing-support-1.0.0/.github/workflows/gfx-ubuntu22-internal.env000066400000000000000000000001321450534701400276370ustar00rootroot00000000000000GFX_DRIVER_VERSION=neo-builds/ci/master/ci-neo-master-025905/artifacts/linux/ubuntu/22.04 level-zero-raytracing-support-1.0.0/.github/workflows/gfx-windows-internal.env000066400000000000000000000001341450534701400276450ustar00rootroot00000000000000GFX_DRIVER_VERSION=gfx-driver-builds/ci/master/gfx-driver-ci-master-13324/artifacts/Windows level-zero-raytracing-support-1.0.0/.github/workflows/release.yml000066400000000000000000000173651450534701400252260ustar00rootroot00000000000000## Copyright 2022 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 name: release on: schedule: - cron: '00 00 * * *' workflow_dispatch: jobs: release-ze_raytracing-ubuntu22_04-GCC: secrets: inherit uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main with: image: embree/ubuntu:22.04 runs-on: '[ "Linux", "docker", "build" ]' artifact-out: release-ze_raytracing-ubuntu22_04-GCC artifact-path: ./build cmd: | mkdir build cd build cmake -G Ninja -D CMAKE_CXX_COMPILER=g++ -D CMAKE_C_COMPILER=gcc -D CMAKE_BUILD_TYPE=ReleaseInternal .. cmake --build . --target package ubuntu22_04-pkg-build: secrets: inherit uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main with: image: gfx-build/testinstall-ubuntu22.04:18 runs-on: '[ "Linux", "docker", "build" ]' artifact-out: ubuntu22_04-pkg-build artifact-path: intel-level-zero-gpu-raytracing_*.dsc intel-level-zero-gpu-raytracing_*.tar.xz intel-level-zero-gpu-raytracing_*amd64.deb intel-level-zero-gpu-raytracing_*amd64.buildinfo pre-cmd: | apt update eatmydata apt -y install git git-lfs cmd: | # Build source packages. mkdir intel-level-zero-gpu-raytracing cp -r * intel-level-zero-gpu-raytracing || true cd intel-level-zero-gpu-raytracing git clone -b v2021.6.0 https://github.com/oneapi-src/oneTBB.git tbb dpkg-buildpackage -j`nproc --all` --no-sign -S -d -rfakeroot cd .. # Install source package in intel-level-zero-gpu-raytracing-build dir. # Then we are going to build binaries from it. # Keep in mind that packages will be written to this dir. eatmydata apt-get build-dep -y ./intel-level-zero-gpu-raytracing_*.dsc dpkg-source -x ./intel-level-zero-gpu-raytracing*.dsc intel-level-zero-gpu-raytracing-build cd intel-level-zero-gpu-raytracing-build dpkg-buildpackage -j`nproc --all` -B --no-sign -rfakeroot rhel_86-pkg-build: secrets: inherit uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main with: image: gfx-build/rhel-8.6:17 runs-on: '[ "Linux", "docker", "build" ]' artifact-out: rhel_86-pkg-build artifact-path: intel-level-zero-gpu-raytracing*.rpm pre-cmd: | dnf makecache dnf install -y git git-lfs rpmdevtools cmd: | VERSION="1.0.0" # Prep the source tar exactly like defined in spec file rm -rf /build/* mkdir -p /build/intel-level-zero-gpu-raytracing-$VERSION cp -r * /build/intel-level-zero-gpu-raytracing-$VERSION || true pushd /build/intel-level-zero-gpu-raytracing-$VERSION git clone -b v2021.6.0 https://github.com/oneapi-src/oneTBB.git tbb rm -rf ~/rpmbuild rpmdev-setuptree && cd /build tar czf ~/rpmbuild/SOURCES/intel-level-zero-gpu-raytracing-$VERSION.tar.gz intel-level-zero-gpu-raytracing-$VERSION cp -pr intel-level-zero-gpu-raytracing-$VERSION/rhel/intel-level-zero-gpu-raytracing.spec ~/rpmbuild/SPECS/intel-level-zero-gpu-raytracing.spec # Build starts here # Build rpm src pkg first, ignoring dependencies because it's only source rpm rpmbuild -bs --nodeps '--define=dist .el8_6' ~/rpmbuild/SPECS/intel-level-zero-gpu-raytracing.spec #Make sure rpmbuild uses src tarball and not above created sources rm -rf ~/rpmbuild/SOURCES/intel-level-zero-gpu-raytracing-$VERSION.tar.gz # Build binary pkgs from source pkg, but first install dependencies dnf builddep -y ~/rpmbuild/SRPMS/*.src.rpm rpmbuild --rebuild '--define=dist .el8_6' --define='__cmake_builddir .' ~/rpmbuild/SRPMS/*.src.rpm # Test install the built package dnf install -y ~/rpmbuild/RPMS/*/*.rpm # Copy artifacts popd rm -rf ~/rpmbuild/RPMS/*/intel-level-zero-gpu-raytracing-debug*.rpm cp -pr ~/rpmbuild/RPMS/*/*.rpm . rm -rf ~/rpmbuild sles_15sp4-pkg-build: secrets: inherit uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/docker.yml@main with: image: gfx-build/testinstall-sle15-15.4:45 runs-on: '[ "Linux", "docker", "build" ]' artifact-out: sles_15sp4-pkg-build artifact-path: intel-level-zero-gpu-raytracing*.rpm pre-cmd: | unset no_proxy unset NO_PROXY zypper ref -s zypper install -y git rpmbuild # Add repo with Intel graphics stack dependencies zypper addrepo -r https://repositories.intel.com/graphics/sles/15sp4/intel-graphics.repo zypper --non-interactive --gpg-auto-import-keys refresh cmd: | unset no_proxy unset NO_PROXY VERSION="1.0.0" # Prep the source tar exactly like defined in spec file rm -rf /tmp/* mkdir -p /tmp/intel-level-zero-gpu-raytracing-$VERSION cp -r * /tmp/intel-level-zero-gpu-raytracing-$VERSION || true pushd /tmp/intel-level-zero-gpu-raytracing-$VERSION git clone -b v2021.6.0 https://github.com/oneapi-src/oneTBB.git tbb rm -rf ~/rpmbuild rpmdev-setuptree && cd /tmp tar czf ~/rpmbuild/SOURCES/intel-level-zero-gpu-raytracing-$VERSION.tar.gz intel-level-zero-gpu-raytracing-$VERSION cp -pr intel-level-zero-gpu-raytracing-$VERSION/sle/intel-level-zero-gpu-raytracing.spec ~/rpmbuild/SPECS/intel-level-zero-gpu-raytracing.spec # Build starts here # Build rpm src pkg first, ignoring dependencies because it's only source rpm rpmbuild -bs --nodeps ~/rpmbuild/SPECS/intel-level-zero-gpu-raytracing.spec # Set up build dependencies from Intel gfx stack # Build binary pkgs from source pkg, but first remove created sources and install dependencies rm -rf ~/rpmbuild/SOURCES/intel-level-zero-gpu-raytracing*.tar.gz zypper --non-interactive si ~/rpmbuild/SRPMS/*.src.rpm rpmbuild --rebuild ~/rpmbuild/SRPMS/*.src.rpm # Test install the built package zypper install --allow-unsigned-rpm -y ~/rpmbuild/RPMS/*/*.rpm # Copy artifacts popd rm -rf ~/rpmbuild/RPMS/*/intel-level-zero-gpu-raytracing-debug*.rpm cp -pr ~/rpmbuild/RPMS/*/*.rpm . rm -rf ~/rpmbuild release-ze_raytracing-windows-V142: secrets: inherit uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/windows.yml@main with: runs-on: '[ "Windows", "NAS", "dg2" ]' artifact-path: ./build artifact-out: release-ze_raytracing-windows-V142 shell: cmd cmd: | mkdir build cd build cmake -G "Visual Studio 16 2019" -T "V142" -A "x64" .. cmake --build . --config ReleaseInternal --target package binary-analysis: needs: - release-ze_raytracing-ubuntu22_04-GCC - release-ze_raytracing-windows-V142 secrets: inherit uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/binary_analysis.yml@main with: project: embree artifact-in-windows: release-ze_raytracing-windows-V142 artifact-in-linux: release-ze_raytracing-ubuntu22_04-GCC path: "build/*.zip build/*.gz" antivirus-scan: needs: - release-ze_raytracing-ubuntu22_04-GCC - release-ze_raytracing-windows-V142 secrets: inherit uses: intel-innersource/libraries.devops.renderkit.workflows/.github/workflows/antivirus_scan.yml@main with: project: embree artifact-in-windows: release-ze_raytracing-windows-V142 artifact-in-linux: release-ze_raytracing-ubuntu22_04-GCC path: "build/*.zip build/*.gz" level-zero-raytracing-support-1.0.0/CHANGELOG.md000066400000000000000000000002371450534701400212650ustar00rootroot00000000000000Version History --------------- ### oneAPI Level Zero Ray Tracing Support 1.0.0 - Initial implementation of oneAPI Level Zero Ray Tracing Support library level-zero-raytracing-support-1.0.0/CMakeLists.txt000066400000000000000000000135401450534701400222150ustar00rootroot00000000000000## Copyright 2009-2021 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 cmake_minimum_required(VERSION 3.1.0) project(ze_raytracing) SET(ZE_RAYTRACING_VERSION_MAJOR 1) SET(ZE_RAYTRACING_VERSION_MINOR 0) SET(ZE_RAYTRACING_VERSION_PATCH 0) SET(ZE_RAYTRACING_VERSION ${ZE_RAYTRACING_VERSION_MAJOR}.${ZE_RAYTRACING_VERSION_MINOR}.${ZE_RAYTRACING_VERSION_PATCH}) IF(COMMAND cmake_policy) if(POLICY CMP0135) message("set policy CMP0135 to NEW") cmake_policy(SET CMP0135 NEW) endif() ENDIF() SET(CMAKE_CXX_STANDARD 17) SET(EMBREE_CMAKEEXPORT_DIR "cmake") SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") SET(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) # Build configurations to use SET(CMAKE_BUILD_TYPE "ReleaseInternal" CACHE STRING "Specifies the build type." FORCE) SET_PROPERTY(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS Debug Release ReleaseInternal) SET(CMAKE_CONFIGURATION_TYPES "Debug;Release;ReleaseInternal" CACHE STRING "List of generated configurations." FORCE) # Debug build configuration IF (WIN32) # Link runtime statically under Windows STRING(REGEX REPLACE "/MD" "/MT" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}") STRING(REGEX REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") ENDIF() MESSAGE("CMAKE_CXX_FLAGS_DEBUG = ${CMAKE_CXX_FLAGS_DEBUG}") MESSAGE("CMAKE_C_FLAGS_DEBUG = ${CMAKE_C_FLAGS_DEBUG}") MESSAGE("CMAKE_SHARED_LINKER_FLAGS_DEBUG = ${CMAKE_SHARED_LINKER_FLAGS_DEBUG}") MESSAGE("CMAKE_EXE_LINKER_FLAGS_DEBUG = ${CMAKE_EXE_LINKER_FLAGS_DEBUG}") # Release build configuration SET(CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}) SET(CMAKE_C_FLAGS_RELEASE ${CMAKE_C_FLAGS_RELWITHDEBINFO}) SET(CMAKE_SHARED_LINKER_FLAGS_RELEASE ${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO}) SET(CMAKE_EXE_LINKER_FLAGS_RELEASE ${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO}) IF (WIN32) # Link runtime statically under Windows STRING(REGEX REPLACE "/MD" "/MT" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}") STRING(REGEX REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") ENDIF() IF (WIN32) # enable dynamic control flow guard mitigation under windows SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /guard:cf") SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /guard:cf") SET(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /DynamicBase /guard:cf") SET(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /DynamicBase /guard:cf") ENDIF() MESSAGE("CMAKE_CXX_FLAGS_RELEASE = ${CMAKE_CXX_FLAGS_RELEASE}") MESSAGE("CMAKE_C_FLAGS_RELEASE = ${CMAKE_C_FLAGS_RELEASE}") MESSAGE("CMAKE_SHARED_LINKER_FLAGS_RELEASE = ${CMAKE_SHARED_LINKER_FLAGS_RELEASE}") MESSAGE("CMAKE_EXE_LINKER_FLAGS_RELEASE = ${CMAKE_EXE_LINKER_FLAGS_RELEASE}") # ReleaseInternal build configuration string(REPLACE "DNDEBUG" "DDEBUG" CMAKE_CXX_FLAGS_RELEASEINTERNAL "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") string(REPLACE "DNDEBUG" "DDEBUG" CMAKE_C_FLAGS_RELEASEINTERNAL "${CMAKE_C_FLAGS_RELWITHDEBINFO}") SET(CMAKE_SHARED_LINKER_FLAGS_RELEASEINTERNAL ${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO}) SET(CMAKE_EXE_LINKER_FLAGS_RELEASEINTERNAL ${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO}) IF (WIN32) # Link runtime statically under Windows STRING(REGEX REPLACE "/MD" "/MT" CMAKE_C_FLAGS_RELEASEINTERNAL "${CMAKE_C_FLAGS_RELEASEINTERNAL}") STRING(REGEX REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELEASEINTERNAL "${CMAKE_CXX_FLAGS_RELEASEINTERNAL}") ENDIF() MESSAGE("CMAKE_CXX_FLAGS_RELEASEINTERNAL = ${CMAKE_CXX_FLAGS_RELEASEINTERNAL}") MESSAGE("CMAKE_C_FLAGS_RELEASEINTERNAL = ${CMAKE_C_FLAGS_RELEASEINTERNAL}") MESSAGE("CMAKE_SHARED_LINKER_FLAGS_RELEASEINTERNAL = ${CMAKE_SHARED_LINKER_FLAGS_RELEASEINTERNAL}") MESSAGE("CMAKE_EXE_LINKER_FLAGS_RELEASEINTERNAL = ${CMAKE_EXE_LINKER_FLAGS_RELEASEINTERNAL}") # configure resource file file CONFIGURE_FILE( "${PROJECT_SOURCE_DIR}/level_zero_raytracing.rc.in" "${PROJECT_SOURCE_DIR}/level_zero_raytracing.rc" ) # we support building TBB statically OPTION(ZE_RAYTRACING_TBB_STATIC "Using statically build TBB" ON) IF (ZE_RAYTRACING_TBB_STATIC) INCLUDE(fetchtbb) ELSE() FIND_PACKAGE(TBB REQUIRED) ENDIF() ADD_DEFINITIONS(-DTASKING_TBB) OPTION(ZE_RAYTRACING_RT_SIMULATION "Using hardware simulation" OFF) IF (ZE_RAYTRACING_RT_SIMULATION AND (NOT ZE_RAYTRACING_RT_VALIDATION_API OR ZE_RAYTRACING_IMPLICIT_DISPATCH_GLOBALS)) MESSAGE(FATAL_ERROR "Using ZE_RAYTRACING_RT_SIMULATION requires ZE_RAYTRACING_RT_VALIDATION_API=ON and ZE_RAYTRACING_IMPLICIT_DISPATCH_GLOBALS=OFF") ENDIF() IF (ZE_RAYTRACING_RT_SIMULATION) FIND_PACKAGE(rtcore) ADD_DEFINITIONS("-DEMBREE_SYCL_RT_SIMULATION") ENDIF() OPTION(ZE_RAYTRACING_RT_VALIDATION_API "Use rt_validation API instead of IGC provided rt_production API" OFF) IF (ZE_RAYTRACING_RT_VALIDATION_API) ADD_DEFINITIONS("-DEMBREE_SYCL_RT_VALIDATION_API") ENDIF() SET(ZE_RAYTRACING_DEVICE -1 CACHE STRING "Forces Xe device to use.") ADD_DEFINITIONS("-DZE_RAYTRACING_DEVICE=${ZE_RAYTRACING_DEVICE}") OPTION(ZE_RAYTRACING_IMPLICIT_DISPATCH_GLOBALS "Using L0 allocated Dispatch Globals" ON) IF (NOT ZE_RAYTRACING_IMPLICIT_DISPATCH_GLOBALS) ADD_DEFINITIONS("-DEMBREE_SYCL_ALLOC_DISPATCH_GLOBALS") ENDIF() STRING(TOLOWER "${CMAKE_CXX_COMPILER_ID}" LOWER_CXX_COMPILER_ID) include(${LOWER_CXX_COMPILER_ID}) INCLUDE(CTest) include(package) INCLUDE(CPack) IF (ZE_RAYTRACING_RT_VALIDATION_API) ADD_SUBDIRECTORY(rttrace) SET(EMBREE_RTHWIF_SYCL embree_rthwif_sycl) ENDIF() ADD_SUBDIRECTORY(level_zero) ADD_SUBDIRECTORY(rtbuild) SET(ZE_RAYTRACING_SYCL_TESTS "OFF" CACHE STRING "Enable SYCL tests.") SET_PROPERTY(CACHE ZE_RAYTRACING_SYCL_TESTS PROPERTY STRINGS OFF DEFAULT_RTAS_BUILDER INTERNAL_RTAS_BUILDER LEVEL_ZERO_RTAS_BUILDER) IF (NOT ZE_RAYTRACING_SYCL_TESTS STREQUAL "OFF") ADD_SUBDIRECTORY(testing) ENDIF() level-zero-raytracing-support-1.0.0/LICENSE.txt000066400000000000000000000261361450534701400213050ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. level-zero-raytracing-support-1.0.0/README.md000066400000000000000000000024561450534701400207400ustar00rootroot00000000000000 oneAPI Level Zero Ray Tracing Support ===================================== The oneAPI Level Zero Ray Tracing Support library implements high performance CPU based construction algorithms for 3D acceleration structures that are compatible with the ray tracing hardware of Intel GPUs. This library is used by Intel(R) oneAPI Level Zero to implement part of the RTAS builder extension. This library should not get used directly but only through Level Zero. To compile the library under Linux execute: mkdir build cd build cmake -G Ninja -D CMAKE_CXX_COMPILER=g++ -D CMAKE_C_COMPILER=gcc -D CMAKE_BUILD_TYPE=Release .. cmake --build . --target package To compile the library under Windows execute: mkdir build cd build cmake -G "Visual Studio 16 2019" -T "V142" -A "x64" -D CMAKE_BUILD_TYPE=Release .. cmake --build . --target package To compile the library under Linux including SYCL examples: wget https://github.com/intel/llvm/releases/download/sycl-nightly%2F20230304/dpcpp-compiler.tar.gz tar xzf dpcpp-compiler source dpcpp_compiler/startup.sh mkdir build cd build cmake -G Ninja -D CMAKE_CXX_COMPILER=clang++ -D CMAKE_C_COMPILER=clang -D CMAKE_BUILD_TYPE=Release -D ZE_RAYTRACING_SYCL_TESTS=INTERNAL_RTAS_BUILDER .. cmake --build . --target package ctest level-zero-raytracing-support-1.0.0/SECURITY.md000066400000000000000000000010101450534701400212330ustar00rootroot00000000000000Security Policy =============== Intel is committed to rapidly addressing security vulnerabilities affecting our customers and providing clear guidance on the solution, impact, severity and mitigation. Reporting a Vulnerability ------------------------- Please [report any security vulnerabilities][guidelines] in this project utilizing the [guidelines here][guidelines]. [guidelines]: https://www.intel.com/content/www/us/en/security-center/vulnerability-handling-guidelines.html "Vulnerability Handling Guidelines" level-zero-raytracing-support-1.0.0/cmake/000077500000000000000000000000001450534701400205325ustar00rootroot00000000000000level-zero-raytracing-support-1.0.0/cmake/clang.cmake000066400000000000000000000046471450534701400226330ustar00rootroot00000000000000## Copyright 2009-2021 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") # enables most warnings SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wformat -Wformat-security") # enables string format vulnerability warnings #SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-class-memaccess") # disables clearing an object of type ‘XXX’ with no trivial copy-assignment; use assignment or value-initialization instead #SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-strict-overflow") # assume that signed overflow occurs SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-delete-null-pointer-checks") # keep all checks for NULL pointers SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fwrapv") # this option instructs the compiler to assume that signed arithmetic overflow warps around. SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsigned-char") # treat char as signed on all processors, including ARM IF (NOT WIN32) SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIE") # enables support for more secure position independent execution SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") # generate position independent code suitable for shared libraries ENDIF() SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-strict-aliasing") # disables strict aliasing rules SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_FORTIFY_SOURCE=2") # perform extra security checks for some standard library calls SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector") # protects against return address overrides IF (NOT WIN32) SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined") # issues link error for undefined symbols in shared library SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -z noexecstack") # we do not need an executable stack SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -z relro -z now") # re-arranges data sections to increase security SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -z noexecstack") # we do not need an executable stack SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -z relro -z now") # re-arranges data sections to increase security SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pie") # enables position independent execution for executable ENDIF() level-zero-raytracing-support-1.0.0/cmake/fetchtbb.cmake000066400000000000000000000040071450534701400233160ustar00rootroot00000000000000## Copyright 2009-2021 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 #################################################################### # fetch TBB and build static version of it IF (WIN32) option(TBB_STRICT "Treat compiler warnings as errors" OFF) ENDIF() option(TBB_TEST "Enable testing" OFF) option(TBBMALLOC_BUILD "Enable tbbmalloc build" OFF) SET(TBB_DIR OFF) SET(BUILD_SHARED_LIBS OFF) IF (EXISTS ${PROJECT_SOURCE_DIR}/tbb) add_subdirectory(${PROJECT_SOURCE_DIR}/tbb ${CMAKE_BINARY_DIR}/tbb EXCLUDE_FROM_ALL) ELSE() INCLUDE(FetchContent) SET(FETCHCONTENT_QUIET OFF) IF (NOT EMBREE_RTHWIF_TBB_GIT_REPOSITORY) # allow setting this externally SET(EMBREE_RTHWIF_TBB_GIT_REPOSITORY "https://github.com/oneapi-src/oneTBB.git") ENDIF() FetchContent_Declare( tbb_static GIT_REPOSITORY ${EMBREE_RTHWIF_TBB_GIT_REPOSITORY} GIT_TAG v2021.6.0 ) FetchContent_GetProperties(tbb_static) if(NOT tbb_static_POPULATED) FetchContent_Populate(tbb_static) # We want to build tbb_static to link it into embree_rthwif, but don't want to # install it as part of the Embree install targets. add_subdirectory(${tbb_static_SOURCE_DIR} ${tbb_static_BINARY_DIR} EXCLUDE_FROM_ALL) endif() ENDIF() MARK_AS_ADVANCED(FETCHCONTENT_BASE_DIR) MARK_AS_ADVANCED(FETCHCONTENT_FULLY_DISCONNECTED) MARK_AS_ADVANCED(FETCHCONTENT_QUIET) MARK_AS_ADVANCED(FETCHCONTENT_SOURCE_DIR_TBB_STATIC) MARK_AS_ADVANCED(FETCHCONTENT_UPDATES_DISCONNECTED) MARK_AS_ADVANCED(FETCHCONTENT_UPDATES_DISCONNECTED_TBB_STATIC) MARK_AS_ADVANCED(TBB4PY_BUILD) MARK_AS_ADVANCED(TBBMALLOC_BUILD) MARK_AS_ADVANCED(TBB_BUILD) MARK_AS_ADVANCED(TBB_CPF) MARK_AS_ADVANCED(TBB_DISABLE_HWLOC_AUTOMATIC_SEARCH) MARK_AS_ADVANCED(TBB_ENABLE_IPO) MARK_AS_ADVANCED(TBB_EXAMPLES) MARK_AS_ADVANCED(TBB_FIND_PACKAGE) MARK_AS_ADVANCED(TBB_INSTALL_VARS) MARK_AS_ADVANCED(TBB_NO_APPCONTAINER) MARK_AS_ADVANCED(TBB_SANITIZE) MARK_AS_ADVANCED(TBB_STRICT) MARK_AS_ADVANCED(TBB_TEST) MARK_AS_ADVANCED(TBB_TEST_SPEC) MARK_AS_ADVANCED(TBB_VALGRIND_MEMCHECK) MARK_AS_ADVANCED(TBB_WINDOWS_DRIVER) level-zero-raytracing-support-1.0.0/cmake/gnu.cmake000066400000000000000000000045471450534701400223370ustar00rootroot00000000000000## Copyright 2009-2021 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") # enables most warnings SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wformat -Wformat-security") # enables string format vulnerability warnings SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-class-memaccess") # disables clearing an object of type ‘XXX’ with no trivial copy-assignment; use assignment or value-initialization instead SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-strict-overflow") # assume that signed overflow occurs SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-delete-null-pointer-checks") # keep all checks for NULL pointers SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fwrapv") # this option instructs the compiler to assume that signed arithmetic overflow warps around. SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsigned-char") # treat char as signed on all processors, including ARM SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIE") # enables support for more secure position independent execution SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") # generate position independent code suitable for shared libraries SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-strict-aliasing") # disables strict aliasing rules SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_FORTIFY_SOURCE=2") # perform extra security checks for some standard library calls SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector") # protects against return address overrides SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined") # issues link error for undefined symbols in shared library SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -z noexecstack") # we do not need an executable stack SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -z relro -z now") # re-arranges data sections to increase security SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -z noexecstack") # we do not need an executable stack SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -z relro -z now") # re-arranges data sections to increase security SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pie") # enables position independent execution for executable level-zero-raytracing-support-1.0.0/cmake/intelllvm.cmake000066400000000000000000000046471450534701400235550ustar00rootroot00000000000000## Copyright 2009-2021 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") # enables most warnings SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wformat -Wformat-security") # enables string format vulnerability warnings #SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-class-memaccess") # disables clearing an object of type ‘XXX’ with no trivial copy-assignment; use assignment or value-initialization instead #SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-strict-overflow") # assume that signed overflow occurs SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-delete-null-pointer-checks") # keep all checks for NULL pointers SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fwrapv") # this option instructs the compiler to assume that signed arithmetic overflow warps around. SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsigned-char") # treat char as signed on all processors, including ARM IF (NOT WIN32) SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIE") # enables support for more secure position independent execution SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") # generate position independent code suitable for shared libraries ENDIF() SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-strict-aliasing") # disables strict aliasing rules SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_FORTIFY_SOURCE=2") # perform extra security checks for some standard library calls SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector") # protects against return address overrides IF (NOT WIN32) SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined") # issues link error for undefined symbols in shared library SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -z noexecstack") # we do not need an executable stack SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -z relro -z now") # re-arranges data sections to increase security SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -z noexecstack") # we do not need an executable stack SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -z relro -z now") # re-arranges data sections to increase security SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pie") # enables position independent execution for executable ENDIF() level-zero-raytracing-support-1.0.0/cmake/msvc.cmake000066400000000000000000000014371450534701400225110ustar00rootroot00000000000000## Copyright 2009-2021 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /GS") # protects against return address overrides SET(SECURE_LINKER_FLAGS "") SET(SECURE_LINKER_FLAGS "${SECURE_LINKER_FLAGS} /NXCompat") # compatible with data execution prevention (on by default) SET(SECURE_LINKER_FLAGS "${SECURE_LINKER_FLAGS} /DynamicBase") # random rebase of executable at load time IF (CMAKE_SIZEOF_VOID_P EQUAL 4) SET(SECURE_LINKER_FLAGS "${SECURE_LINKER_FLAGS} /SafeSEH") # invoke known exception handlers (Win32 only, x64 exception handlers are safe by design) ENDIF() SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${SECURE_LINKER_FLAGS}") SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${SECURE_LINKER_FLAGS}") level-zero-raytracing-support-1.0.0/cmake/package.cmake000066400000000000000000000046311450534701400231330ustar00rootroot00000000000000## Copyright 2009-2021 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 INCLUDE(GNUInstallDirs) ############################################################## # Install Documentation ############################################################## IF (WIN32) INSTALL(FILES "${PROJECT_SOURCE_DIR}/LICENSE.txt" DESTINATION doc COMPONENT lib) INSTALL(FILES "${PROJECT_SOURCE_DIR}/third-party-programs.txt" DESTINATION doc COMPONENT lib) INSTALL(FILES "${PROJECT_SOURCE_DIR}/third-party-programs-TBB.txt" DESTINATION doc COMPONENT lib) # INSTALL(FILES "${PROJECT_SOURCE_DIR}/CHANGELOG.md" DESTINATION doc COMPONENT lib) ELSE() # Linux package builds include these separately ENDIF() ############################################################## # CPack specific stuff ############################################################## SET(CPACK_PACKAGE_NAME "oneAPI Level Zero Ray Tracing Support") SET(CPACK_PACKAGE_FILE_NAME "intel-level-zero-rt-support-${ZE_RAYTRACING_VERSION}") SET(CPACK_STRIP_FILES TRUE) SET(CPACK_PACKAGE_VERSION_MAJOR ${ZE_RAYTRACING_VERSION_MAJOR}) SET(CPACK_PACKAGE_VERSION_MINOR ${ZE_RAYTRACING_VERSION_MINOR}) SET(CPACK_PACKAGE_VERSION_PATCH ${ZE_RAYTRACING_VERSION_PATCH}) SET(CPACK_PACKAGE_VERSION ${ZE_RAYTRACING_VERSION}) SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Support library for Level Zero ray tracing extension.") SET(CPACK_PACKAGE_VENDOR "Intel Corporation") SET(CPACK_PACKAGE_CONTACT embree_support@intel.com) #SET(CPACK_MONOLITHIC_INSTALL 0) #SET(CPACK_COMPONENTS_GROUPING ONE_PER_GROUP) #SET(CPACK_COMPONENTS_GROUPING IGNORE) SET(CPACK_COMPONENT_LIB_DISPLAY_NAME "Library") SET(CPACK_COMPONENT_LIB_DESCRIPTION "Library") SET(CPACK_COMPONENT_LIB_GROUP LIB) SET(CPACK_COMPONENT_DEVEL_DISPLAY_NAME "Development") SET(CPACK_COMPONENT_DEVEL_DESCRIPTION "Development") SET(CPACK_COMPONENT_DEVEL_GROUP DEVEL) SET(CPACK_COMPONENT_TEST_DISPLAY_NAME "Tests") SET(CPACK_COMPONENT_TEST_DESCRIPTION "Tests") SET(CPACK_COMPONENT_TEST_GROUP TEST) SET(CPACK_COMPONENTS_ALL LIB DEVEL TEST) # Windows specific settings IF(WIN32) SET(CPACK_GENERATOR ZIP) SET(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}.x64.windows") # MacOSX specific settings ELSEIF(APPLE) SET(CPACK_GENERATOR ZIP) SET(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}.x86_64.macosx") # Linux specific settings ELSE() SET(CPACK_GENERATOR TGZ) SET(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}.x86_64.linux") ENDIF() level-zero-raytracing-support-1.0.0/debian/000077500000000000000000000000001450534701400206745ustar00rootroot00000000000000level-zero-raytracing-support-1.0.0/debian/changelog000066400000000000000000000002621450534701400225460ustar00rootroot00000000000000intel-level-zero-gpu-raytracing (1.0.0) experimental; urgency=medium * First Release -- Pavel Androniychuk Fri, 21 Apr 2023 15:46:02 -0800 level-zero-raytracing-support-1.0.0/debian/compat000066400000000000000000000000031450534701400220730ustar00rootroot0000000000000011 level-zero-raytracing-support-1.0.0/debian/control000066400000000000000000000015671450534701400223100ustar00rootroot00000000000000Source: intel-level-zero-gpu-raytracing Section: libs Priority: optional Maintainer: Intel Graphics Team Build-Depends: debhelper (>= 11), cmake, ninja-build, pkg-config, make, gcc, git, libpthread-stubs0-dev Standards-Version: 4.3.0 Homepage: https://github.com/intel/level-zero-raytracing-support Package: intel-level-zero-gpu-raytracing Architecture: amd64 Depends: ${misc:Depends}, ${shlibs:Depends}, level-zero Description: Level Zero Ray Tracing Support library . The Level Zero Ray Tracing Support library implements high performance CPU based construction algorithms for 3D acceleration structures that are compatible with the ray tracing hardware of Intel GPUs. This library is used by Intel(R) oneAPI Level Zero to implement part of the RTAS builder extension. This library should not get used directly but only through Level Zero. level-zero-raytracing-support-1.0.0/debian/copyright000066400000000000000000000264401450534701400226350ustar00rootroot00000000000000Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: level-zero-raytracing Source: https://github.com/intel/level-zero-raytracing-support License: Apache2 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. level-zero-raytracing-support-1.0.0/debian/intel-level-zero-gpu-raytracing.docs000066400000000000000000000000661450534701400276770ustar00rootroot00000000000000third-party-programs.txt third-party-programs-TBB.txt level-zero-raytracing-support-1.0.0/debian/rules000077500000000000000000000003501450534701400217520ustar00rootroot00000000000000#!/usr/bin/make -f %: dh $@ --builddir build --buildsystem=cmake+ninja override_dh_builddeb: dh_builddeb -- -Zxz override_dh_auto_configure: dh_auto_configure -- \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX=/usr level-zero-raytracing-support-1.0.0/debian/source/000077500000000000000000000000001450534701400221745ustar00rootroot00000000000000level-zero-raytracing-support-1.0.0/debian/source/format000066400000000000000000000000151450534701400234030ustar00rootroot000000000000003.0 (native) level-zero-raytracing-support-1.0.0/level_zero/000077500000000000000000000000001450534701400216205ustar00rootroot00000000000000level-zero-raytracing-support-1.0.0/level_zero/CMakeLists.txt000066400000000000000000000017721450534701400243670ustar00rootroot00000000000000## Copyright 2009-2021 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 SET(ZE_LOADER_RUNTIME_LINK_NAME_LINUX "libze_loader.so.1" CACHE STRING "Name of the ze_loader lib that is looked for at runtime on Linux") SET(ZE_LOADER_RUNTIME_LINK_NAME_WINDOWS "ze_loader.dll" CACHE STRING "Name of the ze_loader lib that is looked for at runtime on Windows") MARK_AS_ADVANCED(ZE_LOADER_RUNTIME_LINK_NAME_LINUX) MARK_AS_ADVANCED(ZE_LOADER_RUNTIME_LINK_NAME_WINDOWS) ADD_LIBRARY(ze_wrapper STATIC ze_wrapper.cpp) IF (NOT ZE_RAYTRACING_SYCL_TESTS STREQUAL "LEVEL_ZERO_RTAS_BUILDER") TARGET_LINK_LIBRARIES(ze_wrapper PUBLIC embree_rthwif) ELSE() ADD_COMPILE_DEFINITIONS(ZE_RAYTRACING_DISABLE_INTERNAL_BUILDER) ENDIF() TARGET_INCLUDE_DIRECTORIES(ze_wrapper PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/..) TARGET_COMPILE_DEFINITIONS(ze_wrapper PRIVATE ZE_LOADER_NAME_LINUX="${ZE_LOADER_RUNTIME_LINK_NAME_LINUX}") TARGET_COMPILE_DEFINITIONS(ze_wrapper PRIVATE ZE_LOADER_NAME_WINDOWS="${ZE_LOADER_RUNTIME_LINK_NAME_WINDOWS}") level-zero-raytracing-support-1.0.0/level_zero/ze_api.h000066400000000000000000022457121450534701400232550ustar00rootroot00000000000000/* * * Copyright (C) 2019-2021 Intel Corporation * * SPDX-License-Identifier: MIT * * @file ze_api.h * @version v1.6-r1.6.0 * */ #ifndef _ZE_API_H #define _ZE_API_H #if defined(__cplusplus) #pragma once #endif // standard headers #include #include #if defined(__cplusplus) extern "C" { #endif // Intel 'oneAPI' Level-Zero API common types #if !defined(__GNUC__) #pragma region common #endif /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_MAKE_VERSION /// @brief Generates generic 'oneAPI' API versions #define ZE_MAKE_VERSION( _major, _minor ) (( _major << 16 )|( _minor & 0x0000ffff)) #endif // ZE_MAKE_VERSION /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_MAJOR_VERSION /// @brief Extracts 'oneAPI' API major version #define ZE_MAJOR_VERSION( _ver ) ( _ver >> 16 ) #endif // ZE_MAJOR_VERSION /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_MINOR_VERSION /// @brief Extracts 'oneAPI' API minor version #define ZE_MINOR_VERSION( _ver ) ( _ver & 0x0000ffff ) #endif // ZE_MINOR_VERSION /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_APICALL #if defined(_WIN32) /// @brief Calling convention for all API functions #define ZE_APICALL __cdecl #else #define ZE_APICALL #endif // defined(_WIN32) #endif // ZE_APICALL /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_APIEXPORT #if defined(_WIN32) /// @brief Microsoft-specific dllexport storage-class attribute #define ZE_APIEXPORT __declspec(dllexport) #endif // defined(_WIN32) #endif // ZE_APIEXPORT /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_APIEXPORT #if __GNUC__ >= 4 /// @brief GCC-specific dllexport storage-class attribute #define ZE_APIEXPORT __attribute__ ((visibility ("default"))) #else #define ZE_APIEXPORT #endif // __GNUC__ >= 4 #endif // ZE_APIEXPORT /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_DLLEXPORT #if defined(_WIN32) /// @brief Microsoft-specific dllexport storage-class attribute #define ZE_DLLEXPORT __declspec(dllexport) #endif // defined(_WIN32) #endif // ZE_DLLEXPORT /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_DLLEXPORT #if __GNUC__ >= 4 /// @brief GCC-specific dllexport storage-class attribute #define ZE_DLLEXPORT __attribute__ ((visibility ("default"))) #else #define ZE_DLLEXPORT #endif // __GNUC__ >= 4 #endif // ZE_DLLEXPORT /////////////////////////////////////////////////////////////////////////////// /// @brief compiler-independent type typedef uint8_t ze_bool_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Handle of a driver instance typedef struct _ze_driver_handle_t *ze_driver_handle_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Handle of driver's device object typedef struct _ze_device_handle_t *ze_device_handle_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Handle of driver's context object typedef struct _ze_context_handle_t *ze_context_handle_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Handle of driver's command queue object typedef struct _ze_command_queue_handle_t *ze_command_queue_handle_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Handle of driver's command list object typedef struct _ze_command_list_handle_t *ze_command_list_handle_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Handle of driver's fence object typedef struct _ze_fence_handle_t *ze_fence_handle_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Handle of driver's event pool object typedef struct _ze_event_pool_handle_t *ze_event_pool_handle_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Handle of driver's event object typedef struct _ze_event_handle_t *ze_event_handle_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Handle of driver's image object typedef struct _ze_image_handle_t *ze_image_handle_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Handle of driver's module object typedef struct _ze_module_handle_t *ze_module_handle_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Handle of module's build log object typedef struct _ze_module_build_log_handle_t *ze_module_build_log_handle_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Handle of driver's kernel object typedef struct _ze_kernel_handle_t *ze_kernel_handle_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Handle of driver's sampler object typedef struct _ze_sampler_handle_t *ze_sampler_handle_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Handle of physical memory object typedef struct _ze_physical_mem_handle_t *ze_physical_mem_handle_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Handle of driver's fabric vertex object typedef struct _ze_fabric_vertex_handle_t *ze_fabric_vertex_handle_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Handle of driver's fabric edge object typedef struct _ze_fabric_edge_handle_t *ze_fabric_edge_handle_t; /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_MAX_IPC_HANDLE_SIZE /// @brief Maximum IPC handle size #define ZE_MAX_IPC_HANDLE_SIZE 64 #endif // ZE_MAX_IPC_HANDLE_SIZE /////////////////////////////////////////////////////////////////////////////// /// @brief IPC handle to a memory allocation typedef struct _ze_ipc_mem_handle_t { char data[ZE_MAX_IPC_HANDLE_SIZE]; ///< [out] Opaque data representing an IPC handle } ze_ipc_mem_handle_t; /////////////////////////////////////////////////////////////////////////////// /// @brief IPC handle to a event pool allocation typedef struct _ze_ipc_event_pool_handle_t { char data[ZE_MAX_IPC_HANDLE_SIZE]; ///< [out] Opaque data representing an IPC handle } ze_ipc_event_pool_handle_t; /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_BIT /// @brief Generic macro for enumerator bit masks #define ZE_BIT( _i ) ( 1 << _i ) #endif // ZE_BIT /////////////////////////////////////////////////////////////////////////////// /// @brief Defines Return/Error codes typedef enum _ze_result_t { ZE_RESULT_SUCCESS = 0, ///< [Core] success ZE_RESULT_NOT_READY = 1, ///< [Core] synchronization primitive not signaled ZE_RESULT_ERROR_DEVICE_LOST = 0x70000001, ///< [Core] device hung, reset, was removed, or driver update occurred ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY = 0x70000002,///< [Core] insufficient host memory to satisfy call ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY = 0x70000003, ///< [Core] insufficient device memory to satisfy call ZE_RESULT_ERROR_MODULE_BUILD_FAILURE = 0x70000004, ///< [Core] error occurred when building module, see build log for details ZE_RESULT_ERROR_MODULE_LINK_FAILURE = 0x70000005, ///< [Core] error occurred when linking modules, see build log for details ZE_RESULT_ERROR_DEVICE_REQUIRES_RESET = 0x70000006, ///< [Core] device requires a reset ZE_RESULT_ERROR_DEVICE_IN_LOW_POWER_STATE = 0x70000007, ///< [Core] device currently in low power state ZE_RESULT_EXP_ERROR_DEVICE_IS_NOT_VERTEX = 0x7ff00001, ///< [Core, Expoerimental] device is not represented by a fabric vertex ZE_RESULT_EXP_ERROR_VERTEX_IS_NOT_DEVICE = 0x7ff00002, ///< [Core, Experimental] fabric vertex does not represent a device ZE_RESULT_EXP_ERROR_REMOTE_DEVICE = 0x7ff00003, ///< [Core, Expoerimental] fabric vertex represents a remote device or ///< subdevice ZE_RESULT_ERROR_INSUFFICIENT_PERMISSIONS = 0x70010000, ///< [Sysman] access denied due to permission level ZE_RESULT_ERROR_NOT_AVAILABLE = 0x70010001, ///< [Sysman] resource already in use and simultaneous access not allowed ///< or resource was removed ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE = 0x70020000,///< [Tools] external required dependency is unavailable or missing ZE_RESULT_WARNING_DROPPED_DATA = 0x70020001, ///< [Tools] data may have been dropped ZE_RESULT_ERROR_UNINITIALIZED = 0x78000001, ///< [Validation] driver is not initialized ZE_RESULT_ERROR_UNSUPPORTED_VERSION = 0x78000002, ///< [Validation] generic error code for unsupported versions ZE_RESULT_ERROR_UNSUPPORTED_FEATURE = 0x78000003, ///< [Validation] generic error code for unsupported features ZE_RESULT_ERROR_INVALID_ARGUMENT = 0x78000004, ///< [Validation] generic error code for invalid arguments ZE_RESULT_ERROR_INVALID_NULL_HANDLE = 0x78000005, ///< [Validation] handle argument is not valid ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE = 0x78000006, ///< [Validation] object pointed to by handle still in-use by device ZE_RESULT_ERROR_INVALID_NULL_POINTER = 0x78000007, ///< [Validation] pointer argument may not be nullptr ZE_RESULT_ERROR_INVALID_SIZE = 0x78000008, ///< [Validation] size argument is invalid (e.g., must not be zero) ZE_RESULT_ERROR_UNSUPPORTED_SIZE = 0x78000009, ///< [Validation] size argument is not supported by the device (e.g., too ///< large) ZE_RESULT_ERROR_UNSUPPORTED_ALIGNMENT = 0x7800000a, ///< [Validation] alignment argument is not supported by the device (e.g., ///< too small) ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT = 0x7800000b,///< [Validation] synchronization object in invalid state ZE_RESULT_ERROR_INVALID_ENUMERATION = 0x7800000c, ///< [Validation] enumerator argument is not valid ZE_RESULT_ERROR_UNSUPPORTED_ENUMERATION = 0x7800000d, ///< [Validation] enumerator argument is not supported by the device ZE_RESULT_ERROR_UNSUPPORTED_IMAGE_FORMAT = 0x7800000e, ///< [Validation] image format is not supported by the device ZE_RESULT_ERROR_INVALID_NATIVE_BINARY = 0x7800000f, ///< [Validation] native binary is not supported by the device ZE_RESULT_ERROR_INVALID_GLOBAL_NAME = 0x78000010, ///< [Validation] global variable is not found in the module ZE_RESULT_ERROR_INVALID_KERNEL_NAME = 0x78000011, ///< [Validation] kernel name is not found in the module ZE_RESULT_ERROR_INVALID_FUNCTION_NAME = 0x78000012, ///< [Validation] function name is not found in the module ZE_RESULT_ERROR_INVALID_GROUP_SIZE_DIMENSION = 0x78000013, ///< [Validation] group size dimension is not valid for the kernel or ///< device ZE_RESULT_ERROR_INVALID_GLOBAL_WIDTH_DIMENSION = 0x78000014,///< [Validation] global width dimension is not valid for the kernel or ///< device ZE_RESULT_ERROR_INVALID_KERNEL_ARGUMENT_INDEX = 0x78000015, ///< [Validation] kernel argument index is not valid for kernel ZE_RESULT_ERROR_INVALID_KERNEL_ARGUMENT_SIZE = 0x78000016, ///< [Validation] kernel argument size does not match kernel ZE_RESULT_ERROR_INVALID_KERNEL_ATTRIBUTE_VALUE = 0x78000017,///< [Validation] value of kernel attribute is not valid for the kernel or ///< device ZE_RESULT_ERROR_INVALID_MODULE_UNLINKED = 0x78000018, ///< [Validation] module with imports needs to be linked before kernels can ///< be created from it. ZE_RESULT_ERROR_INVALID_COMMAND_LIST_TYPE = 0x78000019, ///< [Validation] command list type does not match command queue type ZE_RESULT_ERROR_OVERLAPPING_REGIONS = 0x7800001a, ///< [Validation] copy operations do not support overlapping regions of ///< memory ZE_RESULT_WARNING_ACTION_REQUIRED = 0x7800001b, ///< [Sysman] an action is required to complete the desired operation ZE_RESULT_ERROR_UNKNOWN = 0x7ffffffe, ///< [Core] unknown or internal error ZE_RESULT_FORCE_UINT32 = 0x7fffffff } ze_result_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Defines structure types typedef enum _ze_structure_type_t { ZE_STRUCTURE_TYPE_DRIVER_PROPERTIES = 0x1, ///< ::ze_driver_properties_t ZE_STRUCTURE_TYPE_DRIVER_IPC_PROPERTIES = 0x2, ///< ::ze_driver_ipc_properties_t ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES = 0x3, ///< ::ze_device_properties_t ZE_STRUCTURE_TYPE_DEVICE_COMPUTE_PROPERTIES = 0x4, ///< ::ze_device_compute_properties_t ZE_STRUCTURE_TYPE_DEVICE_MODULE_PROPERTIES = 0x5, ///< ::ze_device_module_properties_t ZE_STRUCTURE_TYPE_COMMAND_QUEUE_GROUP_PROPERTIES = 0x6, ///< ::ze_command_queue_group_properties_t ZE_STRUCTURE_TYPE_DEVICE_MEMORY_PROPERTIES = 0x7, ///< ::ze_device_memory_properties_t ZE_STRUCTURE_TYPE_DEVICE_MEMORY_ACCESS_PROPERTIES = 0x8,///< ::ze_device_memory_access_properties_t ZE_STRUCTURE_TYPE_DEVICE_CACHE_PROPERTIES = 0x9,///< ::ze_device_cache_properties_t ZE_STRUCTURE_TYPE_DEVICE_IMAGE_PROPERTIES = 0xa,///< ::ze_device_image_properties_t ZE_STRUCTURE_TYPE_DEVICE_P2P_PROPERTIES = 0xb, ///< ::ze_device_p2p_properties_t ZE_STRUCTURE_TYPE_DEVICE_EXTERNAL_MEMORY_PROPERTIES = 0xc, ///< ::ze_device_external_memory_properties_t ZE_STRUCTURE_TYPE_CONTEXT_DESC = 0xd, ///< ::ze_context_desc_t ZE_STRUCTURE_TYPE_COMMAND_QUEUE_DESC = 0xe, ///< ::ze_command_queue_desc_t ZE_STRUCTURE_TYPE_COMMAND_LIST_DESC = 0xf, ///< ::ze_command_list_desc_t ZE_STRUCTURE_TYPE_EVENT_POOL_DESC = 0x10, ///< ::ze_event_pool_desc_t ZE_STRUCTURE_TYPE_EVENT_DESC = 0x11, ///< ::ze_event_desc_t ZE_STRUCTURE_TYPE_FENCE_DESC = 0x12, ///< ::ze_fence_desc_t ZE_STRUCTURE_TYPE_IMAGE_DESC = 0x13, ///< ::ze_image_desc_t ZE_STRUCTURE_TYPE_IMAGE_PROPERTIES = 0x14, ///< ::ze_image_properties_t ZE_STRUCTURE_TYPE_DEVICE_MEM_ALLOC_DESC = 0x15, ///< ::ze_device_mem_alloc_desc_t ZE_STRUCTURE_TYPE_HOST_MEM_ALLOC_DESC = 0x16, ///< ::ze_host_mem_alloc_desc_t ZE_STRUCTURE_TYPE_MEMORY_ALLOCATION_PROPERTIES = 0x17, ///< ::ze_memory_allocation_properties_t ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_EXPORT_DESC = 0x18, ///< ::ze_external_memory_export_desc_t ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMPORT_FD = 0x19, ///< ::ze_external_memory_import_fd_t ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_EXPORT_FD = 0x1a, ///< ::ze_external_memory_export_fd_t ZE_STRUCTURE_TYPE_MODULE_DESC = 0x1b, ///< ::ze_module_desc_t ZE_STRUCTURE_TYPE_MODULE_PROPERTIES = 0x1c, ///< ::ze_module_properties_t ZE_STRUCTURE_TYPE_KERNEL_DESC = 0x1d, ///< ::ze_kernel_desc_t ZE_STRUCTURE_TYPE_KERNEL_PROPERTIES = 0x1e, ///< ::ze_kernel_properties_t ZE_STRUCTURE_TYPE_SAMPLER_DESC = 0x1f, ///< ::ze_sampler_desc_t ZE_STRUCTURE_TYPE_PHYSICAL_MEM_DESC = 0x20, ///< ::ze_physical_mem_desc_t ZE_STRUCTURE_TYPE_KERNEL_PREFERRED_GROUP_SIZE_PROPERTIES = 0x21,///< ::ze_kernel_preferred_group_size_properties_t ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMPORT_WIN32 = 0x22, ///< ::ze_external_memory_import_win32_handle_t ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_EXPORT_WIN32 = 0x23, ///< ::ze_external_memory_export_win32_handle_t ZE_STRUCTURE_TYPE_DEVICE_RAYTRACING_EXT_PROPERTIES = 0x00010001,///< ::ze_device_raytracing_ext_properties_t ZE_STRUCTURE_TYPE_RAYTRACING_MEM_ALLOC_EXT_DESC = 0x10002, ///< ::ze_raytracing_mem_alloc_ext_desc_t ZE_STRUCTURE_TYPE_FLOAT_ATOMIC_EXT_PROPERTIES = 0x10003,///< ::ze_float_atomic_ext_properties_t ZE_STRUCTURE_TYPE_CACHE_RESERVATION_EXT_DESC = 0x10004, ///< ::ze_cache_reservation_ext_desc_t ZE_STRUCTURE_TYPE_EU_COUNT_EXT = 0x10005, ///< ::ze_eu_count_ext_t ZE_STRUCTURE_TYPE_SRGB_EXT_DESC = 0x10006, ///< ::ze_srgb_ext_desc_t ZE_STRUCTURE_TYPE_LINKAGE_INSPECTION_EXT_DESC = 0x10007,///< ::ze_linkage_inspection_ext_desc_t ZE_STRUCTURE_TYPE_PCI_EXT_PROPERTIES = 0x10008, ///< ::ze_pci_ext_properties_t ZE_STRUCTURE_TYPE_DRIVER_MEMORY_FREE_EXT_PROPERTIES = 0x10009, ///< ::ze_driver_memory_free_ext_properties_t ZE_STRUCTURE_TYPE_MEMORY_FREE_EXT_DESC = 0x1000a, ///< ::ze_memory_free_ext_desc_t ZE_STRUCTURE_TYPE_MEMORY_COMPRESSION_HINTS_EXT_DESC = 0x1000b, ///< ::ze_memory_compression_hints_ext_desc_t ZE_STRUCTURE_TYPE_IMAGE_ALLOCATION_EXT_PROPERTIES = 0x1000c,///< ::ze_image_allocation_ext_properties_t ZE_STRUCTURE_TYPE_DEVICE_LUID_EXT_PROPERTIES = 0x1000d, ///< ::ze_device_luid_ext_properties_t ZE_STRUCTURE_TYPE_DEVICE_MEMORY_EXT_PROPERTIES = 0x1000e, ///< ::ze_device_memory_ext_properties_t ZE_STRUCTURE_TYPE_DEVICE_IP_VERSION_EXT = 0x1000f, ///< ::ze_device_ip_version_ext_t ZE_STRUCTURE_TYPE_IMAGE_VIEW_PLANAR_EXT_DESC = 0x10010, ///< ::ze_image_view_planar_ext_desc_t ZE_STRUCTURE_TYPE_EVENT_QUERY_KERNEL_TIMESTAMPS_EXT_PROPERTIES = 0x10011, ///< ::ze_event_query_kernel_timestamps_ext_properties_t ZE_STRUCTURE_TYPE_EVENT_QUERY_KERNEL_TIMESTAMPS_RESULTS_EXT_PROPERTIES = 0x10012, ///< ::ze_event_query_kernel_timestamps_results_ext_properties_t ZE_STRUCTURE_TYPE_RELAXED_ALLOCATION_LIMITS_EXP_DESC = 0x00020001, ///< ::ze_relaxed_allocation_limits_exp_desc_t ZE_STRUCTURE_TYPE_MODULE_PROGRAM_EXP_DESC = 0x00020002, ///< ::ze_module_program_exp_desc_t ZE_STRUCTURE_TYPE_SCHEDULING_HINT_EXP_PROPERTIES = 0x00020003, ///< ::ze_scheduling_hint_exp_properties_t ZE_STRUCTURE_TYPE_SCHEDULING_HINT_EXP_DESC = 0x00020004,///< ::ze_scheduling_hint_exp_desc_t ZE_STRUCTURE_TYPE_IMAGE_VIEW_PLANAR_EXP_DESC = 0x00020005, ///< ::ze_image_view_planar_exp_desc_t ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES_1_2 = 0x00020006, ///< ::ze_device_properties_t ZE_STRUCTURE_TYPE_IMAGE_MEMORY_EXP_PROPERTIES = 0x00020007, ///< ::ze_image_memory_properties_exp_t ZE_STRUCTURE_TYPE_POWER_SAVING_HINT_EXP_DESC = 0x00020008, ///< ::ze_context_power_saving_hint_exp_desc_t ZE_STRUCTURE_TYPE_COPY_BANDWIDTH_EXP_PROPERTIES = 0x00020009, ///< ::ze_copy_bandwidth_exp_properties_t ZE_STRUCTURE_TYPE_DEVICE_P2P_BANDWIDTH_EXP_PROPERTIES = 0x0002000A, ///< ::ze_device_p2p_bandwidth_exp_properties_t ZE_STRUCTURE_TYPE_FABRIC_VERTEX_EXP_PROPERTIES = 0x0002000B,///< ::ze_fabric_vertex_exp_properties_t ZE_STRUCTURE_TYPE_FABRIC_EDGE_EXP_PROPERTIES = 0x0002000C, ///< ::ze_fabric_edge_exp_properties_t ZE_STRUCTURE_TYPE_MEMORY_SUB_ALLOCATIONS_EXP_PROPERTIES = 0x0002000D, ///< ::ze_memory_sub_allocations_exp_properties_t ZE_STRUCTURE_TYPE_FORCE_UINT32 = 0x7fffffff } ze_structure_type_t; /////////////////////////////////////////////////////////////////////////////// /// @brief External memory type flags typedef uint32_t ze_external_memory_type_flags_t; typedef enum _ze_external_memory_type_flag_t { ZE_EXTERNAL_MEMORY_TYPE_FLAG_OPAQUE_FD = ZE_BIT(0), ///< an opaque POSIX file descriptor handle ZE_EXTERNAL_MEMORY_TYPE_FLAG_DMA_BUF = ZE_BIT(1), ///< a file descriptor handle for a Linux dma_buf ZE_EXTERNAL_MEMORY_TYPE_FLAG_OPAQUE_WIN32 = ZE_BIT(2), ///< an NT handle ZE_EXTERNAL_MEMORY_TYPE_FLAG_OPAQUE_WIN32_KMT = ZE_BIT(3), ///< a global share (KMT) handle ZE_EXTERNAL_MEMORY_TYPE_FLAG_D3D11_TEXTURE = ZE_BIT(4), ///< an NT handle referring to a Direct3D 10 or 11 texture resource ZE_EXTERNAL_MEMORY_TYPE_FLAG_D3D11_TEXTURE_KMT = ZE_BIT(5), ///< a global share (KMT) handle referring to a Direct3D 10 or 11 texture ///< resource ZE_EXTERNAL_MEMORY_TYPE_FLAG_D3D12_HEAP = ZE_BIT(6),///< an NT handle referring to a Direct3D 12 heap resource ZE_EXTERNAL_MEMORY_TYPE_FLAG_D3D12_RESOURCE = ZE_BIT(7),///< an NT handle referring to a Direct3D 12 committed resource ZE_EXTERNAL_MEMORY_TYPE_FLAG_FORCE_UINT32 = 0x7fffffff } ze_external_memory_type_flag_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Bandwidth unit typedef enum _ze_bandwidth_unit_t { ZE_BANDWIDTH_UNIT_UNKNOWN = 0, ///< The unit used for bandwidth is unknown ZE_BANDWIDTH_UNIT_BYTES_PER_NANOSEC = 1, ///< Bandwidth is provided in bytes/nanosec ZE_BANDWIDTH_UNIT_BYTES_PER_CLOCK = 2, ///< Bandwidth is provided in bytes/clock ZE_BANDWIDTH_UNIT_FORCE_UINT32 = 0x7fffffff } ze_bandwidth_unit_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Latency unit typedef enum _ze_latency_unit_t { ZE_LATENCY_UNIT_UNKNOWN = 0, ///< The unit used for latency is unknown ZE_LATENCY_UNIT_NANOSEC = 1, ///< Latency is provided in nanosecs ZE_LATENCY_UNIT_CLOCK = 2, ///< Latency is provided in clocks ZE_LATENCY_UNIT_HOP = 3, ///< Latency is provided in hops (normalized so that the lowest latency ///< link has a latency of 1 hop) ZE_LATENCY_UNIT_FORCE_UINT32 = 0x7fffffff } ze_latency_unit_t; /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_MAX_UUID_SIZE /// @brief Maximum universal unique id (UUID) size in bytes #define ZE_MAX_UUID_SIZE 16 #endif // ZE_MAX_UUID_SIZE /////////////////////////////////////////////////////////////////////////////// /// @brief Universal unique id (UUID) typedef struct _ze_uuid_t { uint8_t id[ZE_MAX_UUID_SIZE]; ///< [out] opaque data representing a UUID } ze_uuid_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Base for all properties types typedef struct _ze_base_properties_t { ze_structure_type_t stype; ///< [in] type of this structure void* pNext; ///< [in,out][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). } ze_base_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Base for all descriptor types typedef struct _ze_base_desc_t { ze_structure_type_t stype; ///< [in] type of this structure const void* pNext; ///< [in][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). } ze_base_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forces driver to only report devices (and sub-devices) as specified by /// values /////////////////////////////////////////////////////////////////////////////// /// @brief Forces driver to report devices from lowest to highest PCI bus ID /////////////////////////////////////////////////////////////////////////////// /// @brief Forces all shared allocations into device memory /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_ipc_mem_handle_t typedef struct _ze_ipc_mem_handle_t ze_ipc_mem_handle_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_ipc_event_pool_handle_t typedef struct _ze_ipc_event_pool_handle_t ze_ipc_event_pool_handle_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_uuid_t typedef struct _ze_uuid_t ze_uuid_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_base_properties_t typedef struct _ze_base_properties_t ze_base_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_base_desc_t typedef struct _ze_base_desc_t ze_base_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_driver_uuid_t typedef struct _ze_driver_uuid_t ze_driver_uuid_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_driver_properties_t typedef struct _ze_driver_properties_t ze_driver_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_driver_ipc_properties_t typedef struct _ze_driver_ipc_properties_t ze_driver_ipc_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_driver_extension_properties_t typedef struct _ze_driver_extension_properties_t ze_driver_extension_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_device_uuid_t typedef struct _ze_device_uuid_t ze_device_uuid_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_device_properties_t typedef struct _ze_device_properties_t ze_device_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_device_thread_t typedef struct _ze_device_thread_t ze_device_thread_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_device_compute_properties_t typedef struct _ze_device_compute_properties_t ze_device_compute_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_native_kernel_uuid_t typedef struct _ze_native_kernel_uuid_t ze_native_kernel_uuid_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_device_module_properties_t typedef struct _ze_device_module_properties_t ze_device_module_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_command_queue_group_properties_t typedef struct _ze_command_queue_group_properties_t ze_command_queue_group_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_device_memory_properties_t typedef struct _ze_device_memory_properties_t ze_device_memory_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_device_memory_access_properties_t typedef struct _ze_device_memory_access_properties_t ze_device_memory_access_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_device_cache_properties_t typedef struct _ze_device_cache_properties_t ze_device_cache_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_device_image_properties_t typedef struct _ze_device_image_properties_t ze_device_image_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_device_external_memory_properties_t typedef struct _ze_device_external_memory_properties_t ze_device_external_memory_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_device_p2p_properties_t typedef struct _ze_device_p2p_properties_t ze_device_p2p_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_context_desc_t typedef struct _ze_context_desc_t ze_context_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_command_queue_desc_t typedef struct _ze_command_queue_desc_t ze_command_queue_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_command_list_desc_t typedef struct _ze_command_list_desc_t ze_command_list_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_copy_region_t typedef struct _ze_copy_region_t ze_copy_region_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_image_region_t typedef struct _ze_image_region_t ze_image_region_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_event_pool_desc_t typedef struct _ze_event_pool_desc_t ze_event_pool_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_event_desc_t typedef struct _ze_event_desc_t ze_event_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_kernel_timestamp_data_t typedef struct _ze_kernel_timestamp_data_t ze_kernel_timestamp_data_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_kernel_timestamp_result_t typedef struct _ze_kernel_timestamp_result_t ze_kernel_timestamp_result_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_fence_desc_t typedef struct _ze_fence_desc_t ze_fence_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_image_format_t typedef struct _ze_image_format_t ze_image_format_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_image_desc_t typedef struct _ze_image_desc_t ze_image_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_image_properties_t typedef struct _ze_image_properties_t ze_image_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_device_mem_alloc_desc_t typedef struct _ze_device_mem_alloc_desc_t ze_device_mem_alloc_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_host_mem_alloc_desc_t typedef struct _ze_host_mem_alloc_desc_t ze_host_mem_alloc_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_memory_allocation_properties_t typedef struct _ze_memory_allocation_properties_t ze_memory_allocation_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_external_memory_export_desc_t typedef struct _ze_external_memory_export_desc_t ze_external_memory_export_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_external_memory_import_fd_t typedef struct _ze_external_memory_import_fd_t ze_external_memory_import_fd_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_external_memory_export_fd_t typedef struct _ze_external_memory_export_fd_t ze_external_memory_export_fd_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_external_memory_import_win32_handle_t typedef struct _ze_external_memory_import_win32_handle_t ze_external_memory_import_win32_handle_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_external_memory_export_win32_handle_t typedef struct _ze_external_memory_export_win32_handle_t ze_external_memory_export_win32_handle_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_module_constants_t typedef struct _ze_module_constants_t ze_module_constants_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_module_desc_t typedef struct _ze_module_desc_t ze_module_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_module_properties_t typedef struct _ze_module_properties_t ze_module_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_kernel_desc_t typedef struct _ze_kernel_desc_t ze_kernel_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_kernel_uuid_t typedef struct _ze_kernel_uuid_t ze_kernel_uuid_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_kernel_properties_t typedef struct _ze_kernel_properties_t ze_kernel_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_kernel_preferred_group_size_properties_t typedef struct _ze_kernel_preferred_group_size_properties_t ze_kernel_preferred_group_size_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_group_count_t typedef struct _ze_group_count_t ze_group_count_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_module_program_exp_desc_t typedef struct _ze_module_program_exp_desc_t ze_module_program_exp_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_device_raytracing_ext_properties_t typedef struct _ze_device_raytracing_ext_properties_t ze_device_raytracing_ext_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_raytracing_mem_alloc_ext_desc_t typedef struct _ze_raytracing_mem_alloc_ext_desc_t ze_raytracing_mem_alloc_ext_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_sampler_desc_t typedef struct _ze_sampler_desc_t ze_sampler_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_physical_mem_desc_t typedef struct _ze_physical_mem_desc_t ze_physical_mem_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_float_atomic_ext_properties_t typedef struct _ze_float_atomic_ext_properties_t ze_float_atomic_ext_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_relaxed_allocation_limits_exp_desc_t typedef struct _ze_relaxed_allocation_limits_exp_desc_t ze_relaxed_allocation_limits_exp_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_cache_reservation_ext_desc_t typedef struct _ze_cache_reservation_ext_desc_t ze_cache_reservation_ext_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_image_memory_properties_exp_t typedef struct _ze_image_memory_properties_exp_t ze_image_memory_properties_exp_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_image_view_planar_ext_desc_t typedef struct _ze_image_view_planar_ext_desc_t ze_image_view_planar_ext_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_image_view_planar_exp_desc_t typedef struct _ze_image_view_planar_exp_desc_t ze_image_view_planar_exp_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_scheduling_hint_exp_properties_t typedef struct _ze_scheduling_hint_exp_properties_t ze_scheduling_hint_exp_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_scheduling_hint_exp_desc_t typedef struct _ze_scheduling_hint_exp_desc_t ze_scheduling_hint_exp_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_context_power_saving_hint_exp_desc_t typedef struct _ze_context_power_saving_hint_exp_desc_t ze_context_power_saving_hint_exp_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_eu_count_ext_t typedef struct _ze_eu_count_ext_t ze_eu_count_ext_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_pci_address_ext_t typedef struct _ze_pci_address_ext_t ze_pci_address_ext_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_pci_speed_ext_t typedef struct _ze_pci_speed_ext_t ze_pci_speed_ext_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_pci_ext_properties_t typedef struct _ze_pci_ext_properties_t ze_pci_ext_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_srgb_ext_desc_t typedef struct _ze_srgb_ext_desc_t ze_srgb_ext_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_image_allocation_ext_properties_t typedef struct _ze_image_allocation_ext_properties_t ze_image_allocation_ext_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_linkage_inspection_ext_desc_t typedef struct _ze_linkage_inspection_ext_desc_t ze_linkage_inspection_ext_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_memory_compression_hints_ext_desc_t typedef struct _ze_memory_compression_hints_ext_desc_t ze_memory_compression_hints_ext_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_driver_memory_free_ext_properties_t typedef struct _ze_driver_memory_free_ext_properties_t ze_driver_memory_free_ext_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_memory_free_ext_desc_t typedef struct _ze_memory_free_ext_desc_t ze_memory_free_ext_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_device_p2p_bandwidth_exp_properties_t typedef struct _ze_device_p2p_bandwidth_exp_properties_t ze_device_p2p_bandwidth_exp_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_copy_bandwidth_exp_properties_t typedef struct _ze_copy_bandwidth_exp_properties_t ze_copy_bandwidth_exp_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_device_luid_ext_t typedef struct _ze_device_luid_ext_t ze_device_luid_ext_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_device_luid_ext_properties_t typedef struct _ze_device_luid_ext_properties_t ze_device_luid_ext_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_fabric_vertex_pci_exp_address_t typedef struct _ze_fabric_vertex_pci_exp_address_t ze_fabric_vertex_pci_exp_address_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_fabric_vertex_exp_properties_t typedef struct _ze_fabric_vertex_exp_properties_t ze_fabric_vertex_exp_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_fabric_edge_exp_properties_t typedef struct _ze_fabric_edge_exp_properties_t ze_fabric_edge_exp_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_device_memory_ext_properties_t typedef struct _ze_device_memory_ext_properties_t ze_device_memory_ext_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_device_ip_version_ext_t typedef struct _ze_device_ip_version_ext_t ze_device_ip_version_ext_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_kernel_max_group_size_properties_ext_t typedef struct _ze_kernel_max_group_size_properties_ext_t ze_kernel_max_group_size_properties_ext_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_sub_allocation_t typedef struct _ze_sub_allocation_t ze_sub_allocation_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_memory_sub_allocations_exp_properties_t typedef struct _ze_memory_sub_allocations_exp_properties_t ze_memory_sub_allocations_exp_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_event_query_kernel_timestamps_ext_properties_t typedef struct _ze_event_query_kernel_timestamps_ext_properties_t ze_event_query_kernel_timestamps_ext_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_synchronized_timestamp_data_ext_t typedef struct _ze_synchronized_timestamp_data_ext_t ze_synchronized_timestamp_data_ext_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_synchronized_timestamp_result_ext_t typedef struct _ze_synchronized_timestamp_result_ext_t ze_synchronized_timestamp_result_ext_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_event_query_kernel_timestamps_results_ext_properties_t typedef struct _ze_event_query_kernel_timestamps_results_ext_properties_t ze_event_query_kernel_timestamps_results_ext_properties_t; #if !defined(__GNUC__) #pragma endregion #endif // Intel 'oneAPI' Level-Zero APIs #if !defined(__GNUC__) #pragma region driver #endif /////////////////////////////////////////////////////////////////////////////// /// @brief Supported initialization flags typedef uint32_t ze_init_flags_t; typedef enum _ze_init_flag_t { ZE_INIT_FLAG_GPU_ONLY = ZE_BIT(0), ///< only initialize GPU drivers ZE_INIT_FLAG_VPU_ONLY = ZE_BIT(1), ///< only initialize VPU drivers ZE_INIT_FLAG_FORCE_UINT32 = 0x7fffffff } ze_init_flag_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Initialize the 'oneAPI' driver(s) /// /// @details /// - The application must call this function before calling any other /// function. /// - If this function is not called then all other functions will return /// ::ZE_RESULT_ERROR_UNINITIALIZED. /// - Only one instance of each driver will be initialized per process. /// - The application may call this function multiple times with different /// flags or environment variables enabled. /// - The application must call this function after forking new processes. /// Each forked process must call this function. /// - The application may call this function from simultaneous threads. /// - The implementation of this function must be thread-safe for scenarios /// where multiple libraries may initialize the driver(s) simultaneously. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_ENUMERATION /// + `0x3 < flags` ZE_APIEXPORT ze_result_t ZE_APICALL zeInit( ze_init_flags_t flags ///< [in] initialization flags. ///< must be 0 (default) or a combination of ::ze_init_flag_t. ); /////////////////////////////////////////////////////////////////////////////// /// @brief Retrieves driver instances /// /// @details /// - A driver represents a collection of physical devices. /// - Multiple calls to this function will return identical driver handles, /// in the same order. /// - The application may pass nullptr for pDrivers when only querying the /// number of drivers. /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @remarks /// _Analogues_ /// - clGetPlatformIDs /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pCount` ZE_APIEXPORT ze_result_t ZE_APICALL zeDriverGet( uint32_t* pCount, ///< [in,out] pointer to the number of driver instances. ///< if count is zero, then the loader shall update the value with the ///< total number of drivers available. ///< if count is greater than the number of drivers available, then the ///< loader shall update the value with the correct number of drivers available. ze_driver_handle_t* phDrivers ///< [in,out][optional][range(0, *pCount)] array of driver instance handles. ///< if count is less than the number of drivers available, then the loader ///< shall only retrieve that number of drivers. ); /////////////////////////////////////////////////////////////////////////////// /// @brief Supported API versions /// /// @details /// - API versions contain major and minor attributes, use /// ::ZE_MAJOR_VERSION and ::ZE_MINOR_VERSION typedef enum _ze_api_version_t { ZE_API_VERSION_1_0 = ZE_MAKE_VERSION( 1, 0 ), ///< version 1.0 ZE_API_VERSION_1_1 = ZE_MAKE_VERSION( 1, 1 ), ///< version 1.1 ZE_API_VERSION_1_2 = ZE_MAKE_VERSION( 1, 2 ), ///< version 1.2 ZE_API_VERSION_1_3 = ZE_MAKE_VERSION( 1, 3 ), ///< version 1.3 ZE_API_VERSION_1_4 = ZE_MAKE_VERSION( 1, 4 ), ///< version 1.4 ZE_API_VERSION_1_5 = ZE_MAKE_VERSION( 1, 5 ), ///< version 1.5 ZE_API_VERSION_1_6 = ZE_MAKE_VERSION( 1, 6 ), ///< version 1.6 ZE_API_VERSION_CURRENT = ZE_MAKE_VERSION( 1, 6 ), ///< latest known version ZE_API_VERSION_FORCE_UINT32 = 0x7fffffff } ze_api_version_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Returns the API version supported by the specified driver /// /// @details /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hDriver` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == version` ZE_APIEXPORT ze_result_t ZE_APICALL zeDriverGetApiVersion( ze_driver_handle_t hDriver, ///< [in] handle of the driver instance ze_api_version_t* version ///< [out] api version ); /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_MAX_DRIVER_UUID_SIZE /// @brief Maximum driver universal unique id (UUID) size in bytes #define ZE_MAX_DRIVER_UUID_SIZE 16 #endif // ZE_MAX_DRIVER_UUID_SIZE /////////////////////////////////////////////////////////////////////////////// /// @brief Driver universal unique id (UUID) typedef struct _ze_driver_uuid_t { uint8_t id[ZE_MAX_DRIVER_UUID_SIZE]; ///< [out] opaque data representing a driver UUID } ze_driver_uuid_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Driver properties queried using ::zeDriverGetProperties typedef struct _ze_driver_properties_t { ze_structure_type_t stype; ///< [in] type of this structure void* pNext; ///< [in,out][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). ze_driver_uuid_t uuid; ///< [out] universal unique identifier. uint32_t driverVersion; ///< [out] driver version ///< The driver version is a non-zero, monotonically increasing value where ///< higher values always indicate a more recent version. } ze_driver_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Retrieves properties of the driver. /// /// @details /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @remarks /// _Analogues_ /// - **clGetPlatformInfo** /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hDriver` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pDriverProperties` ZE_APIEXPORT ze_result_t ZE_APICALL zeDriverGetProperties( ze_driver_handle_t hDriver, ///< [in] handle of the driver instance ze_driver_properties_t* pDriverProperties ///< [in,out] query result for driver properties ); /////////////////////////////////////////////////////////////////////////////// /// @brief Supported IPC property flags typedef uint32_t ze_ipc_property_flags_t; typedef enum _ze_ipc_property_flag_t { ZE_IPC_PROPERTY_FLAG_MEMORY = ZE_BIT(0), ///< Supports passing memory allocations between processes. See ///< ::zeMemGetIpcHandle. ZE_IPC_PROPERTY_FLAG_EVENT_POOL = ZE_BIT(1), ///< Supports passing event pools between processes. See ///< ::zeEventPoolGetIpcHandle. ZE_IPC_PROPERTY_FLAG_FORCE_UINT32 = 0x7fffffff } ze_ipc_property_flag_t; /////////////////////////////////////////////////////////////////////////////// /// @brief IPC properties queried using ::zeDriverGetIpcProperties typedef struct _ze_driver_ipc_properties_t { ze_structure_type_t stype; ///< [in] type of this structure void* pNext; ///< [in,out][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). ze_ipc_property_flags_t flags; ///< [out] 0 (none) or a valid combination of ::ze_ipc_property_flag_t } ze_driver_ipc_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Retrieves IPC attributes of the driver /// /// @details /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hDriver` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pIpcProperties` ZE_APIEXPORT ze_result_t ZE_APICALL zeDriverGetIpcProperties( ze_driver_handle_t hDriver, ///< [in] handle of the driver instance ze_driver_ipc_properties_t* pIpcProperties ///< [in,out] query result for IPC properties ); /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_MAX_EXTENSION_NAME /// @brief Maximum extension name string size #define ZE_MAX_EXTENSION_NAME 256 #endif // ZE_MAX_EXTENSION_NAME /////////////////////////////////////////////////////////////////////////////// /// @brief Extension properties queried using ::zeDriverGetExtensionProperties typedef struct _ze_driver_extension_properties_t { char name[ZE_MAX_EXTENSION_NAME]; ///< [out] extension name uint32_t version; ///< [out] extension version using ::ZE_MAKE_VERSION } ze_driver_extension_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Retrieves extension properties /// /// @details /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @remarks /// _Analogues_ /// - **vkEnumerateInstanceExtensionProperties** /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hDriver` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pCount` ZE_APIEXPORT ze_result_t ZE_APICALL zeDriverGetExtensionProperties( ze_driver_handle_t hDriver, ///< [in] handle of the driver instance uint32_t* pCount, ///< [in,out] pointer to the number of extension properties. ///< if count is zero, then the driver shall update the value with the ///< total number of extension properties available. ///< if count is greater than the number of extension properties available, ///< then the driver shall update the value with the correct number of ///< extension properties available. ze_driver_extension_properties_t* pExtensionProperties ///< [in,out][optional][range(0, *pCount)] array of query results for ///< extension properties. ///< if count is less than the number of extension properties available, ///< then driver shall only retrieve that number of extension properties. ); /////////////////////////////////////////////////////////////////////////////// /// @brief Retrieves function pointer for vendor-specific or experimental /// extensions /// /// @details /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hDriver` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == name` /// + `nullptr == ppFunctionAddress` ZE_APIEXPORT ze_result_t ZE_APICALL zeDriverGetExtensionFunctionAddress( ze_driver_handle_t hDriver, ///< [in] handle of the driver instance const char* name, ///< [in] extension function name void** ppFunctionAddress ///< [out] pointer to function pointer ); /////////////////////////////////////////////////////////////////////////////// /// @brief Retrieves a string describing the last error code returned by the /// driver in the current thread. /// /// @details /// - String returned is thread local. /// - String is only updated on calls returning an error, i.e., not on calls /// returning ::ZE_RESULT_SUCCESS. /// - String may be empty if driver considers error code is already explicit /// enough to describe cause. /// - Memory pointed to by ppString is owned by the driver. /// - String returned is null-terminated. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hDriver` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == ppString` ZE_APIEXPORT ze_result_t ZE_APICALL zeDriverGetLastErrorDescription( ze_driver_handle_t hDriver, ///< [in] handle of the driver instance const char** ppString ///< [in,out] pointer to a null-terminated array of characters describing ///< cause of error. ); #if !defined(__GNUC__) #pragma endregion #endif // Intel 'oneAPI' Level-Zero APIs for Device #if !defined(__GNUC__) #pragma region device #endif /////////////////////////////////////////////////////////////////////////////// /// @brief Retrieves devices within a driver /// /// @details /// - Multiple calls to this function will return identical device handles, /// in the same order. /// - The number and order of handles returned from this function is /// affected by the ::ZE_AFFINITY_MASK and ::ZE_ENABLE_PCI_ID_DEVICE_ORDER /// environment variables. /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hDriver` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pCount` ZE_APIEXPORT ze_result_t ZE_APICALL zeDeviceGet( ze_driver_handle_t hDriver, ///< [in] handle of the driver instance uint32_t* pCount, ///< [in,out] pointer to the number of devices. ///< if count is zero, then the driver shall update the value with the ///< total number of devices available. ///< if count is greater than the number of devices available, then the ///< driver shall update the value with the correct number of devices available. ze_device_handle_t* phDevices ///< [in,out][optional][range(0, *pCount)] array of handle of devices. ///< if count is less than the number of devices available, then driver ///< shall only retrieve that number of devices. ); /////////////////////////////////////////////////////////////////////////////// /// @brief Retrieves a sub-device from a device /// /// @details /// - Multiple calls to this function will return identical device handles, /// in the same order. /// - The number of handles returned from this function is affected by the /// ::ZE_AFFINITY_MASK environment variable. /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @remarks /// _Analogues_ /// - clCreateSubDevices /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hDevice` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pCount` ZE_APIEXPORT ze_result_t ZE_APICALL zeDeviceGetSubDevices( ze_device_handle_t hDevice, ///< [in] handle of the device object uint32_t* pCount, ///< [in,out] pointer to the number of sub-devices. ///< if count is zero, then the driver shall update the value with the ///< total number of sub-devices available. ///< if count is greater than the number of sub-devices available, then the ///< driver shall update the value with the correct number of sub-devices available. ze_device_handle_t* phSubdevices ///< [in,out][optional][range(0, *pCount)] array of handle of sub-devices. ///< if count is less than the number of sub-devices available, then driver ///< shall only retrieve that number of sub-devices. ); /////////////////////////////////////////////////////////////////////////////// /// @brief Supported device types typedef enum _ze_device_type_t { ZE_DEVICE_TYPE_GPU = 1, ///< Graphics Processing Unit ZE_DEVICE_TYPE_CPU = 2, ///< Central Processing Unit ZE_DEVICE_TYPE_FPGA = 3, ///< Field Programmable Gate Array ZE_DEVICE_TYPE_MCA = 4, ///< Memory Copy Accelerator ZE_DEVICE_TYPE_VPU = 5, ///< Vision Processing Unit ZE_DEVICE_TYPE_FORCE_UINT32 = 0x7fffffff } ze_device_type_t; /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_MAX_DEVICE_UUID_SIZE /// @brief Maximum device universal unique id (UUID) size in bytes #define ZE_MAX_DEVICE_UUID_SIZE 16 #endif // ZE_MAX_DEVICE_UUID_SIZE /////////////////////////////////////////////////////////////////////////////// /// @brief Device universal unique id (UUID) typedef struct _ze_device_uuid_t { uint8_t id[ZE_MAX_DEVICE_UUID_SIZE]; ///< [out] opaque data representing a device UUID } ze_device_uuid_t; /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_MAX_DEVICE_NAME /// @brief Maximum device name string size #define ZE_MAX_DEVICE_NAME 256 #endif // ZE_MAX_DEVICE_NAME /////////////////////////////////////////////////////////////////////////////// /// @brief Supported device property flags typedef uint32_t ze_device_property_flags_t; typedef enum _ze_device_property_flag_t { ZE_DEVICE_PROPERTY_FLAG_INTEGRATED = ZE_BIT(0), ///< Device is integrated with the Host. ZE_DEVICE_PROPERTY_FLAG_SUBDEVICE = ZE_BIT(1), ///< Device handle used for query represents a sub-device. ZE_DEVICE_PROPERTY_FLAG_ECC = ZE_BIT(2), ///< Device supports error correction memory access. ZE_DEVICE_PROPERTY_FLAG_ONDEMANDPAGING = ZE_BIT(3), ///< Device supports on-demand page-faulting. ZE_DEVICE_PROPERTY_FLAG_FORCE_UINT32 = 0x7fffffff } ze_device_property_flag_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Device properties queried using ::zeDeviceGetProperties typedef struct _ze_device_properties_t { ze_structure_type_t stype; ///< [in] type of this structure void* pNext; ///< [in,out][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). ze_device_type_t type; ///< [out] generic device type uint32_t vendorId; ///< [out] vendor id from PCI configuration uint32_t deviceId; ///< [out] device id from PCI configuration ///< Note, the device id uses little-endian format. ze_device_property_flags_t flags; ///< [out] 0 (none) or a valid combination of ::ze_device_property_flag_t uint32_t subdeviceId; ///< [out] sub-device id. Only valid if ::ZE_DEVICE_PROPERTY_FLAG_SUBDEVICE ///< is set. uint32_t coreClockRate; ///< [out] Clock rate for device core. uint64_t maxMemAllocSize; ///< [out] Maximum memory allocation size. uint32_t maxHardwareContexts; ///< [out] Maximum number of logical hardware contexts. uint32_t maxCommandQueuePriority; ///< [out] Maximum priority for command queues. Higher value is higher ///< priority. uint32_t numThreadsPerEU; ///< [out] Maximum number of threads per EU. uint32_t physicalEUSimdWidth; ///< [out] The physical EU simd width. uint32_t numEUsPerSubslice; ///< [out] Maximum number of EUs per sub-slice. uint32_t numSubslicesPerSlice; ///< [out] Maximum number of sub-slices per slice. uint32_t numSlices; ///< [out] Maximum number of slices. uint64_t timerResolution; ///< [out] Returns the resolution of device timer used for profiling, ///< timestamps, etc. When stype==::ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES the ///< units are in nanoseconds. When ///< stype==::ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES_1_2 units are in ///< cycles/sec uint32_t timestampValidBits; ///< [out] Returns the number of valid bits in the timestamp value. uint32_t kernelTimestampValidBits; ///< [out] Returns the number of valid bits in the kernel timestamp values ze_device_uuid_t uuid; ///< [out] universal unique identifier. Note: Subdevices will have their ///< own uuid. char name[ZE_MAX_DEVICE_NAME]; ///< [out] Device name } ze_device_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Device thread identifier. typedef struct _ze_device_thread_t { uint32_t slice; ///< [in,out] the slice number. ///< Must be UINT32_MAX (all) or less than ::ze_device_properties_t.numSlices. uint32_t subslice; ///< [in,out] the sub-slice number within its slice. ///< Must be UINT32_MAX (all) or less than ::ze_device_properties_t.numSubslicesPerSlice. uint32_t eu; ///< [in,out] the EU number within its sub-slice. ///< Must be UINT32_MAX (all) or less than ::ze_device_properties_t.numEUsPerSubslice. uint32_t thread; ///< [in,out] the thread number within its EU. ///< Must be UINT32_MAX (all) or less than ::ze_device_properties_t.numThreadsPerEU. } ze_device_thread_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Retrieves properties of the device. /// /// @details /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @remarks /// _Analogues_ /// - clGetDeviceInfo /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hDevice` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pDeviceProperties` ZE_APIEXPORT ze_result_t ZE_APICALL zeDeviceGetProperties( ze_device_handle_t hDevice, ///< [in] handle of the device ze_device_properties_t* pDeviceProperties ///< [in,out] query result for device properties ); /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_SUBGROUPSIZE_COUNT /// @brief Maximum number of subgroup sizes supported. #define ZE_SUBGROUPSIZE_COUNT 8 #endif // ZE_SUBGROUPSIZE_COUNT /////////////////////////////////////////////////////////////////////////////// /// @brief Device compute properties queried using ::zeDeviceGetComputeProperties typedef struct _ze_device_compute_properties_t { ze_structure_type_t stype; ///< [in] type of this structure void* pNext; ///< [in,out][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). uint32_t maxTotalGroupSize; ///< [out] Maximum items per compute group. (groupSizeX * groupSizeY * ///< groupSizeZ) <= maxTotalGroupSize uint32_t maxGroupSizeX; ///< [out] Maximum items for X dimension in group uint32_t maxGroupSizeY; ///< [out] Maximum items for Y dimension in group uint32_t maxGroupSizeZ; ///< [out] Maximum items for Z dimension in group uint32_t maxGroupCountX; ///< [out] Maximum groups that can be launched for x dimension uint32_t maxGroupCountY; ///< [out] Maximum groups that can be launched for y dimension uint32_t maxGroupCountZ; ///< [out] Maximum groups that can be launched for z dimension uint32_t maxSharedLocalMemory; ///< [out] Maximum shared local memory per group. uint32_t numSubGroupSizes; ///< [out] Number of subgroup sizes supported. This indicates number of ///< entries in subGroupSizes. uint32_t subGroupSizes[ZE_SUBGROUPSIZE_COUNT]; ///< [out] Size group sizes supported. } ze_device_compute_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Retrieves compute properties of the device. /// /// @details /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @remarks /// _Analogues_ /// - clGetDeviceInfo /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hDevice` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pComputeProperties` ZE_APIEXPORT ze_result_t ZE_APICALL zeDeviceGetComputeProperties( ze_device_handle_t hDevice, ///< [in] handle of the device ze_device_compute_properties_t* pComputeProperties ///< [in,out] query result for compute properties ); /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_MAX_NATIVE_KERNEL_UUID_SIZE /// @brief Maximum native kernel universal unique id (UUID) size in bytes #define ZE_MAX_NATIVE_KERNEL_UUID_SIZE 16 #endif // ZE_MAX_NATIVE_KERNEL_UUID_SIZE /////////////////////////////////////////////////////////////////////////////// /// @brief Native kernel universal unique id (UUID) typedef struct _ze_native_kernel_uuid_t { uint8_t id[ZE_MAX_NATIVE_KERNEL_UUID_SIZE]; ///< [out] opaque data representing a native kernel UUID } ze_native_kernel_uuid_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Supported device module flags typedef uint32_t ze_device_module_flags_t; typedef enum _ze_device_module_flag_t { ZE_DEVICE_MODULE_FLAG_FP16 = ZE_BIT(0), ///< Device supports 16-bit floating-point operations ZE_DEVICE_MODULE_FLAG_FP64 = ZE_BIT(1), ///< Device supports 64-bit floating-point operations ZE_DEVICE_MODULE_FLAG_INT64_ATOMICS = ZE_BIT(2),///< Device supports 64-bit atomic operations ZE_DEVICE_MODULE_FLAG_DP4A = ZE_BIT(3), ///< Device supports four component dot product and accumulate operations ZE_DEVICE_MODULE_FLAG_FORCE_UINT32 = 0x7fffffff } ze_device_module_flag_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Supported floating-Point capability flags typedef uint32_t ze_device_fp_flags_t; typedef enum _ze_device_fp_flag_t { ZE_DEVICE_FP_FLAG_DENORM = ZE_BIT(0), ///< Supports denorms ZE_DEVICE_FP_FLAG_INF_NAN = ZE_BIT(1), ///< Supports INF and quiet NaNs ZE_DEVICE_FP_FLAG_ROUND_TO_NEAREST = ZE_BIT(2), ///< Supports rounding to nearest even rounding mode ZE_DEVICE_FP_FLAG_ROUND_TO_ZERO = ZE_BIT(3), ///< Supports rounding to zero. ZE_DEVICE_FP_FLAG_ROUND_TO_INF = ZE_BIT(4), ///< Supports rounding to both positive and negative INF. ZE_DEVICE_FP_FLAG_FMA = ZE_BIT(5), ///< Supports IEEE754-2008 fused multiply-add. ZE_DEVICE_FP_FLAG_ROUNDED_DIVIDE_SQRT = ZE_BIT(6), ///< Supports rounding as defined by IEEE754 for divide and sqrt ///< operations. ZE_DEVICE_FP_FLAG_SOFT_FLOAT = ZE_BIT(7), ///< Uses software implementation for basic floating-point operations. ZE_DEVICE_FP_FLAG_FORCE_UINT32 = 0x7fffffff } ze_device_fp_flag_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Device module properties queried using ::zeDeviceGetModuleProperties typedef struct _ze_device_module_properties_t { ze_structure_type_t stype; ///< [in] type of this structure void* pNext; ///< [in,out][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). uint32_t spirvVersionSupported; ///< [out] Maximum supported SPIR-V version. ///< Returns zero if SPIR-V is not supported. ///< Contains major and minor attributes, use ::ZE_MAJOR_VERSION and ::ZE_MINOR_VERSION. ze_device_module_flags_t flags; ///< [out] 0 or a valid combination of ::ze_device_module_flag_t ze_device_fp_flags_t fp16flags; ///< [out] Capabilities for half-precision floating-point operations. ///< returns 0 (if ::ZE_DEVICE_MODULE_FLAG_FP16 is not set) or a ///< combination of ::ze_device_fp_flag_t. ze_device_fp_flags_t fp32flags; ///< [out] Capabilities for single-precision floating-point operations. ///< returns a combination of ::ze_device_fp_flag_t. ze_device_fp_flags_t fp64flags; ///< [out] Capabilities for double-precision floating-point operations. ///< returns 0 (if ::ZE_DEVICE_MODULE_FLAG_FP64 is not set) or a ///< combination of ::ze_device_fp_flag_t. uint32_t maxArgumentsSize; ///< [out] Maximum kernel argument size that is supported. uint32_t printfBufferSize; ///< [out] Maximum size of internal buffer that holds output of printf ///< calls from kernel. ze_native_kernel_uuid_t nativeKernelSupported; ///< [out] Compatibility UUID of supported native kernel. ///< UUID may or may not be the same across driver release, devices, or ///< operating systems. ///< Application is responsible for ensuring UUID matches before creating ///< module using ///< previously created native kernel. } ze_device_module_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Retrieves module properties of the device /// /// @details /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hDevice` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pModuleProperties` ZE_APIEXPORT ze_result_t ZE_APICALL zeDeviceGetModuleProperties( ze_device_handle_t hDevice, ///< [in] handle of the device ze_device_module_properties_t* pModuleProperties///< [in,out] query result for module properties ); /////////////////////////////////////////////////////////////////////////////// /// @brief Supported command queue group property flags typedef uint32_t ze_command_queue_group_property_flags_t; typedef enum _ze_command_queue_group_property_flag_t { ZE_COMMAND_QUEUE_GROUP_PROPERTY_FLAG_COMPUTE = ZE_BIT(0), ///< Command queue group supports enqueing compute commands. ZE_COMMAND_QUEUE_GROUP_PROPERTY_FLAG_COPY = ZE_BIT(1), ///< Command queue group supports enqueing copy commands. ZE_COMMAND_QUEUE_GROUP_PROPERTY_FLAG_COOPERATIVE_KERNELS = ZE_BIT(2), ///< Command queue group supports cooperative kernels. ///< See ::zeCommandListAppendLaunchCooperativeKernel for more details. ZE_COMMAND_QUEUE_GROUP_PROPERTY_FLAG_METRICS = ZE_BIT(3), ///< Command queue groups supports metric queries. ZE_COMMAND_QUEUE_GROUP_PROPERTY_FLAG_FORCE_UINT32 = 0x7fffffff } ze_command_queue_group_property_flag_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Command queue group properties queried using /// ::zeDeviceGetCommandQueueGroupProperties typedef struct _ze_command_queue_group_properties_t { ze_structure_type_t stype; ///< [in] type of this structure void* pNext; ///< [in,out][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). ze_command_queue_group_property_flags_t flags; ///< [out] 0 (none) or a valid combination of ///< ::ze_command_queue_group_property_flag_t size_t maxMemoryFillPatternSize; ///< [out] maximum `pattern_size` supported by command queue group. ///< See ::zeCommandListAppendMemoryFill for more details. uint32_t numQueues; ///< [out] the number of physical engines within the group. } ze_command_queue_group_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Retrieves command queue group properties of the device. /// /// @details /// - Properties are reported for each physical command queue type supported /// by the device. /// - Multiple calls to this function will return properties in the same /// order. /// - The order in which the properties are returned defines the command /// queue group's ordinal. /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @remarks /// _Analogues_ /// - **vkGetPhysicalDeviceQueueFamilyProperties** /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hDevice` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pCount` ZE_APIEXPORT ze_result_t ZE_APICALL zeDeviceGetCommandQueueGroupProperties( ze_device_handle_t hDevice, ///< [in] handle of the device uint32_t* pCount, ///< [in,out] pointer to the number of command queue group properties. ///< if count is zero, then the driver shall update the value with the ///< total number of command queue group properties available. ///< if count is greater than the number of command queue group properties ///< available, then the driver shall update the value with the correct ///< number of command queue group properties available. ze_command_queue_group_properties_t* pCommandQueueGroupProperties ///< [in,out][optional][range(0, *pCount)] array of query results for ///< command queue group properties. ///< if count is less than the number of command queue group properties ///< available, then driver shall only retrieve that number of command ///< queue group properties. ); /////////////////////////////////////////////////////////////////////////////// /// @brief Supported device memory property flags typedef uint32_t ze_device_memory_property_flags_t; typedef enum _ze_device_memory_property_flag_t { ZE_DEVICE_MEMORY_PROPERTY_FLAG_TBD = ZE_BIT(0), ///< reserved for future use ZE_DEVICE_MEMORY_PROPERTY_FLAG_FORCE_UINT32 = 0x7fffffff } ze_device_memory_property_flag_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Device local memory properties queried using /// ::zeDeviceGetMemoryProperties typedef struct _ze_device_memory_properties_t { ze_structure_type_t stype; ///< [in] type of this structure void* pNext; ///< [in,out][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). ze_device_memory_property_flags_t flags; ///< [out] 0 (none) or a valid combination of ///< ::ze_device_memory_property_flag_t uint32_t maxClockRate; ///< [out] Maximum clock rate for device memory. uint32_t maxBusWidth; ///< [out] Maximum bus width between device and memory. uint64_t totalSize; ///< [out] Total memory size in bytes that is available to the device. char name[ZE_MAX_DEVICE_NAME]; ///< [out] Memory name } ze_device_memory_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Retrieves local memory properties of the device. /// /// @details /// - Properties are reported for each physical memory type supported by the /// device. /// - Multiple calls to this function will return properties in the same /// order. /// - The order in which the properties are returned defines the device's /// local memory ordinal. /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @remarks /// _Analogues_ /// - clGetDeviceInfo /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hDevice` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pCount` ZE_APIEXPORT ze_result_t ZE_APICALL zeDeviceGetMemoryProperties( ze_device_handle_t hDevice, ///< [in] handle of the device uint32_t* pCount, ///< [in,out] pointer to the number of memory properties. ///< if count is zero, then the driver shall update the value with the ///< total number of memory properties available. ///< if count is greater than the number of memory properties available, ///< then the driver shall update the value with the correct number of ///< memory properties available. ze_device_memory_properties_t* pMemProperties ///< [in,out][optional][range(0, *pCount)] array of query results for ///< memory properties. ///< if count is less than the number of memory properties available, then ///< driver shall only retrieve that number of memory properties. ); /////////////////////////////////////////////////////////////////////////////// /// @brief Memory access capability flags /// /// @details /// - Supported access capabilities for different types of memory /// allocations typedef uint32_t ze_memory_access_cap_flags_t; typedef enum _ze_memory_access_cap_flag_t { ZE_MEMORY_ACCESS_CAP_FLAG_RW = ZE_BIT(0), ///< Supports load/store access ZE_MEMORY_ACCESS_CAP_FLAG_ATOMIC = ZE_BIT(1), ///< Supports atomic access ZE_MEMORY_ACCESS_CAP_FLAG_CONCURRENT = ZE_BIT(2), ///< Supports concurrent access ZE_MEMORY_ACCESS_CAP_FLAG_CONCURRENT_ATOMIC = ZE_BIT(3),///< Supports concurrent atomic access ZE_MEMORY_ACCESS_CAP_FLAG_FORCE_UINT32 = 0x7fffffff } ze_memory_access_cap_flag_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Device memory access properties queried using /// ::zeDeviceGetMemoryAccessProperties typedef struct _ze_device_memory_access_properties_t { ze_structure_type_t stype; ///< [in] type of this structure void* pNext; ///< [in,out][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). ze_memory_access_cap_flags_t hostAllocCapabilities; ///< [out] host memory capabilities. ///< returns 0 (unsupported) or a combination of ::ze_memory_access_cap_flag_t. ze_memory_access_cap_flags_t deviceAllocCapabilities; ///< [out] device memory capabilities. ///< returns 0 (unsupported) or a combination of ::ze_memory_access_cap_flag_t. ze_memory_access_cap_flags_t sharedSingleDeviceAllocCapabilities; ///< [out] shared, single-device memory capabilities. ///< returns 0 (unsupported) or a combination of ::ze_memory_access_cap_flag_t. ze_memory_access_cap_flags_t sharedCrossDeviceAllocCapabilities;///< [out] shared, cross-device memory capabilities. ///< returns 0 (unsupported) or a combination of ::ze_memory_access_cap_flag_t. ze_memory_access_cap_flags_t sharedSystemAllocCapabilities; ///< [out] shared, system memory capabilities. ///< returns 0 (unsupported) or a combination of ::ze_memory_access_cap_flag_t. } ze_device_memory_access_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Retrieves memory access properties of the device. /// /// @details /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @remarks /// _Analogues_ /// - clGetDeviceInfo /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hDevice` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pMemAccessProperties` ZE_APIEXPORT ze_result_t ZE_APICALL zeDeviceGetMemoryAccessProperties( ze_device_handle_t hDevice, ///< [in] handle of the device ze_device_memory_access_properties_t* pMemAccessProperties ///< [in,out] query result for memory access properties ); /////////////////////////////////////////////////////////////////////////////// /// @brief Supported cache control property flags typedef uint32_t ze_device_cache_property_flags_t; typedef enum _ze_device_cache_property_flag_t { ZE_DEVICE_CACHE_PROPERTY_FLAG_USER_CONTROL = ZE_BIT(0), ///< Device support User Cache Control (i.e. SLM section vs Generic Cache) ZE_DEVICE_CACHE_PROPERTY_FLAG_FORCE_UINT32 = 0x7fffffff } ze_device_cache_property_flag_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Device cache properties queried using ::zeDeviceGetCacheProperties typedef struct _ze_device_cache_properties_t { ze_structure_type_t stype; ///< [in] type of this structure void* pNext; ///< [in,out][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). ze_device_cache_property_flags_t flags; ///< [out] 0 (none) or a valid combination of ///< ::ze_device_cache_property_flag_t size_t cacheSize; ///< [out] Per-cache size, in bytes } ze_device_cache_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Retrieves cache properties of the device /// /// @details /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @remarks /// _Analogues_ /// - clGetDeviceInfo /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hDevice` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pCount` ZE_APIEXPORT ze_result_t ZE_APICALL zeDeviceGetCacheProperties( ze_device_handle_t hDevice, ///< [in] handle of the device uint32_t* pCount, ///< [in,out] pointer to the number of cache properties. ///< if count is zero, then the driver shall update the value with the ///< total number of cache properties available. ///< if count is greater than the number of cache properties available, ///< then the driver shall update the value with the correct number of ///< cache properties available. ze_device_cache_properties_t* pCacheProperties ///< [in,out][optional][range(0, *pCount)] array of query results for cache properties. ///< if count is less than the number of cache properties available, then ///< driver shall only retrieve that number of cache properties. ); /////////////////////////////////////////////////////////////////////////////// /// @brief Device image properties queried using ::zeDeviceGetImageProperties typedef struct _ze_device_image_properties_t { ze_structure_type_t stype; ///< [in] type of this structure void* pNext; ///< [in,out][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). uint32_t maxImageDims1D; ///< [out] Maximum image dimensions for 1D resources. if 0, then 1D images ///< are unsupported. uint32_t maxImageDims2D; ///< [out] Maximum image dimensions for 2D resources. if 0, then 2D images ///< are unsupported. uint32_t maxImageDims3D; ///< [out] Maximum image dimensions for 3D resources. if 0, then 3D images ///< are unsupported. uint64_t maxImageBufferSize; ///< [out] Maximum image buffer size in bytes. if 0, then buffer images are ///< unsupported. uint32_t maxImageArraySlices; ///< [out] Maximum image array slices. if 0, then image arrays are ///< unsupported. uint32_t maxSamplers; ///< [out] Max samplers that can be used in kernel. if 0, then sampling is ///< unsupported. uint32_t maxReadImageArgs; ///< [out] Returns the maximum number of simultaneous image objects that ///< can be read from by a kernel. if 0, then reading images is ///< unsupported. uint32_t maxWriteImageArgs; ///< [out] Returns the maximum number of simultaneous image objects that ///< can be written to by a kernel. if 0, then writing images is ///< unsupported. } ze_device_image_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Retrieves image properties of the device /// /// @details /// - See ::zeImageGetProperties for format-specific capabilities. /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hDevice` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pImageProperties` ZE_APIEXPORT ze_result_t ZE_APICALL zeDeviceGetImageProperties( ze_device_handle_t hDevice, ///< [in] handle of the device ze_device_image_properties_t* pImageProperties ///< [in,out] query result for image properties ); /////////////////////////////////////////////////////////////////////////////// /// @brief Device external memory import and export properties typedef struct _ze_device_external_memory_properties_t { ze_structure_type_t stype; ///< [in] type of this structure void* pNext; ///< [in,out][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). ze_external_memory_type_flags_t memoryAllocationImportTypes;///< [out] Supported external memory import types for memory allocations. ze_external_memory_type_flags_t memoryAllocationExportTypes;///< [out] Supported external memory export types for memory allocations. ze_external_memory_type_flags_t imageImportTypes; ///< [out] Supported external memory import types for images. ze_external_memory_type_flags_t imageExportTypes; ///< [out] Supported external memory export types for images. } ze_device_external_memory_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Retrieves external memory import and export of the device /// /// @details /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hDevice` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pExternalMemoryProperties` ZE_APIEXPORT ze_result_t ZE_APICALL zeDeviceGetExternalMemoryProperties( ze_device_handle_t hDevice, ///< [in] handle of the device ze_device_external_memory_properties_t* pExternalMemoryProperties ///< [in,out] query result for external memory properties ); /////////////////////////////////////////////////////////////////////////////// /// @brief Supported device peer-to-peer property flags typedef uint32_t ze_device_p2p_property_flags_t; typedef enum _ze_device_p2p_property_flag_t { ZE_DEVICE_P2P_PROPERTY_FLAG_ACCESS = ZE_BIT(0), ///< Device supports access between peer devices. ZE_DEVICE_P2P_PROPERTY_FLAG_ATOMICS = ZE_BIT(1),///< Device supports atomics between peer devices. ZE_DEVICE_P2P_PROPERTY_FLAG_FORCE_UINT32 = 0x7fffffff } ze_device_p2p_property_flag_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Device peer-to-peer properties queried using /// ::zeDeviceGetP2PProperties typedef struct _ze_device_p2p_properties_t { ze_structure_type_t stype; ///< [in] type of this structure void* pNext; ///< [in,out][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). ze_device_p2p_property_flags_t flags; ///< [out] 0 (none) or a valid combination of ///< ::ze_device_p2p_property_flag_t } ze_device_p2p_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Retrieves peer-to-peer properties between one device and a peer /// devices /// /// @details /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hDevice` /// + `nullptr == hPeerDevice` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pP2PProperties` ZE_APIEXPORT ze_result_t ZE_APICALL zeDeviceGetP2PProperties( ze_device_handle_t hDevice, ///< [in] handle of the device performing the access ze_device_handle_t hPeerDevice, ///< [in] handle of the peer device with the allocation ze_device_p2p_properties_t* pP2PProperties ///< [in,out] Peer-to-Peer properties between source and peer device ); /////////////////////////////////////////////////////////////////////////////// /// @brief Queries if one device can directly access peer device allocations /// /// @details /// - Any device can access any other device within a node through a /// scale-up fabric. /// - The following are conditions for CanAccessPeer query. /// + If both device and peer device are the same then return true. /// + If both sub-device and peer sub-device are the same then return /// true. /// + If both are sub-devices and share the same parent device then /// return true. /// + If both device and remote device are connected by a direct or /// indirect scale-up fabric or over PCIe (same root complex or shared /// PCIe switch) then true. /// + If both sub-device and remote parent device (and vice-versa) are /// connected by a direct or indirect scale-up fabric or over PCIe /// (same root complex or shared PCIe switch) then true. /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hDevice` /// + `nullptr == hPeerDevice` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == value` ZE_APIEXPORT ze_result_t ZE_APICALL zeDeviceCanAccessPeer( ze_device_handle_t hDevice, ///< [in] handle of the device performing the access ze_device_handle_t hPeerDevice, ///< [in] handle of the peer device with the allocation ze_bool_t* value ///< [out] returned access capability ); /////////////////////////////////////////////////////////////////////////////// /// @brief Returns current status of the device. /// /// @details /// - Once a device is reset, this call will update the OS handle attached /// to the device handle. /// - The application may call this function from simultaneous threads with /// the same device handle. /// - The implementation of this function must be thread-safe. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hDevice` /// - ::ZE_RESULT_SUCCESS /// + Device is available for use. /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// + Device is lost; must be reset for use. ZE_APIEXPORT ze_result_t ZE_APICALL zeDeviceGetStatus( ze_device_handle_t hDevice ///< [in] handle of the device ); /////////////////////////////////////////////////////////////////////////////// /// @brief Returns synchronized Host and device global timestamps. /// /// @details /// - The application may call this function from simultaneous threads with /// the same device handle. /// - The implementation of this function must be thread-safe. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hDevice` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == hostTimestamp` /// + `nullptr == deviceTimestamp` ZE_APIEXPORT ze_result_t ZE_APICALL zeDeviceGetGlobalTimestamps( ze_device_handle_t hDevice, ///< [in] handle of the device uint64_t* hostTimestamp, ///< [out] value of the Host's global timestamp that correlates with the ///< Device's global timestamp value uint64_t* deviceTimestamp ///< [out] value of the Device's global timestamp that correlates with the ///< Host's global timestamp value ); #if !defined(__GNUC__) #pragma endregion #endif // Intel 'oneAPI' Level-Zero APIs for Context #if !defined(__GNUC__) #pragma region context #endif /////////////////////////////////////////////////////////////////////////////// /// @brief Supported context creation flags typedef uint32_t ze_context_flags_t; typedef enum _ze_context_flag_t { ZE_CONTEXT_FLAG_TBD = ZE_BIT(0), ///< reserved for future use ZE_CONTEXT_FLAG_FORCE_UINT32 = 0x7fffffff } ze_context_flag_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Context descriptor typedef struct _ze_context_desc_t { ze_structure_type_t stype; ///< [in] type of this structure const void* pNext; ///< [in][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). ze_context_flags_t flags; ///< [in] creation flags. ///< must be 0 (default) or a valid combination of ::ze_context_flag_t; ///< default behavior may use implicit driver-based heuristics. } ze_context_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Creates a context for the driver. /// /// @details /// - The application must only use the context for the driver which was /// provided during creation. /// - The application may call this function from simultaneous threads. /// - The implementation of this function must be thread-safe. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hDriver` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == desc` /// + `nullptr == phContext` /// - ::ZE_RESULT_ERROR_INVALID_ENUMERATION /// + `0x1 < desc->flags` ZE_APIEXPORT ze_result_t ZE_APICALL zeContextCreate( ze_driver_handle_t hDriver, ///< [in] handle of the driver object const ze_context_desc_t* desc, ///< [in] pointer to context descriptor ze_context_handle_t* phContext ///< [out] pointer to handle of context object created ); /////////////////////////////////////////////////////////////////////////////// /// @brief Creates a context for the driver. /// /// @details /// - The application must only use the context for the driver which was /// provided during creation. /// - The application may call this function from simultaneous threads. /// - The implementation of this function must be thread-safe. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hDriver` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == desc` /// + `nullptr == phContext` /// - ::ZE_RESULT_ERROR_INVALID_ENUMERATION /// + `0x1 < desc->flags` /// - ::ZE_RESULT_ERROR_INVALID_SIZE /// + `(nullptr == phDevices) && (0 < numDevices)` ZE_APIEXPORT ze_result_t ZE_APICALL zeContextCreateEx( ze_driver_handle_t hDriver, ///< [in] handle of the driver object const ze_context_desc_t* desc, ///< [in] pointer to context descriptor uint32_t numDevices, ///< [in][optional] number of device handles; must be 0 if `nullptr == ///< phDevices` ze_device_handle_t* phDevices, ///< [in][optional][range(0, numDevices)] array of device handles which ///< context has visibility. ///< if nullptr, then all devices and any sub-devices supported by the ///< driver instance are ///< visible to the context. ///< otherwise, the context only has visibility to the devices and any ///< sub-devices of the ///< devices in this array. ze_context_handle_t* phContext ///< [out] pointer to handle of context object created ); /////////////////////////////////////////////////////////////////////////////// /// @brief Destroys a context. /// /// @details /// - The application must ensure the device is not currently referencing /// the context before it is deleted. /// - The implementation of this function may immediately free all Host and /// Device allocations associated with this context. /// - The application must **not** call this function from simultaneous /// threads with the same context handle. /// - The implementation of this function must be thread-safe. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hContext` /// - ::ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE ZE_APIEXPORT ze_result_t ZE_APICALL zeContextDestroy( ze_context_handle_t hContext ///< [in][release] handle of context object to destroy ); /////////////////////////////////////////////////////////////////////////////// /// @brief Returns current status of the context. /// /// @details /// - The application may call this function from simultaneous threads with /// the same context handle. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hContext` /// - ::ZE_RESULT_SUCCESS /// + Context is available for use. /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// + Context is invalid; due to device lost or reset. ZE_APIEXPORT ze_result_t ZE_APICALL zeContextGetStatus( ze_context_handle_t hContext ///< [in] handle of context object ); #if !defined(__GNUC__) #pragma endregion #endif // Intel 'oneAPI' Level-Zero APIs for Command Queue #if !defined(__GNUC__) #pragma region cmdqueue #endif /////////////////////////////////////////////////////////////////////////////// /// @brief Supported command queue flags typedef uint32_t ze_command_queue_flags_t; typedef enum _ze_command_queue_flag_t { ZE_COMMAND_QUEUE_FLAG_EXPLICIT_ONLY = ZE_BIT(0),///< command queue should be optimized for submission to a single device engine. ///< driver **must** disable any implicit optimizations for distributing ///< work across multiple engines. ///< this flag should be used when applications want full control over ///< multi-engine submission and scheduling. ZE_COMMAND_QUEUE_FLAG_FORCE_UINT32 = 0x7fffffff } ze_command_queue_flag_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Supported command queue modes typedef enum _ze_command_queue_mode_t { ZE_COMMAND_QUEUE_MODE_DEFAULT = 0, ///< implicit default behavior; uses driver-based heuristics ZE_COMMAND_QUEUE_MODE_SYNCHRONOUS = 1, ///< Device execution always completes immediately on execute; ///< Host thread is blocked using wait on implicit synchronization object ZE_COMMAND_QUEUE_MODE_ASYNCHRONOUS = 2, ///< Device execution is scheduled and will complete in future; ///< explicit synchronization object must be used to determine completeness ZE_COMMAND_QUEUE_MODE_FORCE_UINT32 = 0x7fffffff } ze_command_queue_mode_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Supported command queue priorities typedef enum _ze_command_queue_priority_t { ZE_COMMAND_QUEUE_PRIORITY_NORMAL = 0, ///< [default] normal priority ZE_COMMAND_QUEUE_PRIORITY_PRIORITY_LOW = 1, ///< lower priority than normal ZE_COMMAND_QUEUE_PRIORITY_PRIORITY_HIGH = 2, ///< higher priority than normal ZE_COMMAND_QUEUE_PRIORITY_FORCE_UINT32 = 0x7fffffff } ze_command_queue_priority_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Command Queue descriptor typedef struct _ze_command_queue_desc_t { ze_structure_type_t stype; ///< [in] type of this structure const void* pNext; ///< [in][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). uint32_t ordinal; ///< [in] command queue group ordinal uint32_t index; ///< [in] command queue index within the group; ///< must be zero if ::ZE_COMMAND_QUEUE_FLAG_EXPLICIT_ONLY is not set ze_command_queue_flags_t flags; ///< [in] usage flags. ///< must be 0 (default) or a valid combination of ::ze_command_queue_flag_t; ///< default behavior may use implicit driver-based heuristics to balance ///< latency and throughput. ze_command_queue_mode_t mode; ///< [in] operation mode ze_command_queue_priority_t priority; ///< [in] priority } ze_command_queue_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Creates a command queue on the context. /// /// @details /// - A command queue represents a logical input stream to the device, tied /// to a physical input stream. /// - The application must only use the command queue for the device, or its /// sub-devices, which was provided during creation. /// - The application may call this function from simultaneous threads. /// - The implementation of this function must be thread-safe. /// /// @remarks /// _Analogues_ /// - **clCreateCommandQueue** /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hContext` /// + `nullptr == hDevice` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == desc` /// + `nullptr == phCommandQueue` /// - ::ZE_RESULT_ERROR_INVALID_ENUMERATION /// + `0x1 < desc->flags` /// + `::ZE_COMMAND_QUEUE_MODE_ASYNCHRONOUS < desc->mode` /// + `::ZE_COMMAND_QUEUE_PRIORITY_PRIORITY_HIGH < desc->priority` ZE_APIEXPORT ze_result_t ZE_APICALL zeCommandQueueCreate( ze_context_handle_t hContext, ///< [in] handle of the context object ze_device_handle_t hDevice, ///< [in] handle of the device object const ze_command_queue_desc_t* desc, ///< [in] pointer to command queue descriptor ze_command_queue_handle_t* phCommandQueue ///< [out] pointer to handle of command queue object created ); /////////////////////////////////////////////////////////////////////////////// /// @brief Destroys a command queue. /// /// @details /// - The application must destroy all fence handles created from the /// command queue before destroying the command queue itself /// - The application must ensure the device is not currently referencing /// the command queue before it is deleted /// - The implementation of this function may immediately free all Host and /// Device allocations associated with this command queue /// - The application must **not** call this function from simultaneous /// threads with the same command queue handle. /// - The implementation of this function must be thread-safe. /// /// @remarks /// _Analogues_ /// - **clReleaseCommandQueue** /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hCommandQueue` /// - ::ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE ZE_APIEXPORT ze_result_t ZE_APICALL zeCommandQueueDestroy( ze_command_queue_handle_t hCommandQueue ///< [in][release] handle of command queue object to destroy ); /////////////////////////////////////////////////////////////////////////////// /// @brief Executes a command list in a command queue. /// /// @details /// - The command lists are submitted to the device in the order they are /// received, whether from multiple calls (on the same or different /// threads) or a single call with multiple command lists. /// - The application must ensure the command lists are accessible by the /// device on which the command queue was created. /// - The application must ensure the device is not currently referencing /// the command list since the implementation is allowed to modify the /// contents of the command list for submission. /// - The application must only execute command lists created with an /// identical command queue group ordinal to the command queue. /// - The application must use a fence created using the same command queue. /// - The application must ensure the command queue, command list and fence /// were created on the same context. /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @remarks /// _Analogues_ /// - vkQueueSubmit /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hCommandQueue` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == phCommandLists` /// - ::ZE_RESULT_ERROR_INVALID_SIZE /// + `0 == numCommandLists` /// - ::ZE_RESULT_ERROR_INVALID_COMMAND_LIST_TYPE /// - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT ZE_APIEXPORT ze_result_t ZE_APICALL zeCommandQueueExecuteCommandLists( ze_command_queue_handle_t hCommandQueue, ///< [in] handle of the command queue uint32_t numCommandLists, ///< [in] number of command lists to execute ze_command_list_handle_t* phCommandLists, ///< [in][range(0, numCommandLists)] list of handles of the command lists ///< to execute ze_fence_handle_t hFence ///< [in][optional] handle of the fence to signal on completion ); /////////////////////////////////////////////////////////////////////////////// /// @brief Synchronizes a command queue by waiting on the host. /// /// @details /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hCommandQueue` /// - ::ZE_RESULT_NOT_READY /// + timeout expired ZE_APIEXPORT ze_result_t ZE_APICALL zeCommandQueueSynchronize( ze_command_queue_handle_t hCommandQueue, ///< [in] handle of the command queue uint64_t timeout ///< [in] if non-zero, then indicates the maximum time (in nanoseconds) to ///< yield before returning ::ZE_RESULT_SUCCESS or ::ZE_RESULT_NOT_READY; ///< if zero, then immediately returns the status of the command queue; ///< if UINT64_MAX, then function will not return until complete or device ///< is lost. ///< Due to external dependencies, timeout may be rounded to the closest ///< value allowed by the accuracy of those dependencies. ); #if !defined(__GNUC__) #pragma endregion #endif // Intel 'oneAPI' Level-Zero APIs for Command List #if !defined(__GNUC__) #pragma region cmdlist #endif /////////////////////////////////////////////////////////////////////////////// /// @brief Supported command list creation flags typedef uint32_t ze_command_list_flags_t; typedef enum _ze_command_list_flag_t { ZE_COMMAND_LIST_FLAG_RELAXED_ORDERING = ZE_BIT(0), ///< driver may reorder commands (e.g., kernels, copies) between barriers ///< and synchronization primitives. ///< using this flag may increase Host overhead of ::zeCommandListClose. ///< therefore, this flag should **not** be set for low-latency usage-models. ZE_COMMAND_LIST_FLAG_MAXIMIZE_THROUGHPUT = ZE_BIT(1), ///< driver may perform additional optimizations that increase execution ///< throughput. ///< using this flag may increase Host overhead of ::zeCommandListClose and ::zeCommandQueueExecuteCommandLists. ///< therefore, this flag should **not** be set for low-latency usage-models. ZE_COMMAND_LIST_FLAG_EXPLICIT_ONLY = ZE_BIT(2), ///< command list should be optimized for submission to a single command ///< queue and device engine. ///< driver **must** disable any implicit optimizations for distributing ///< work across multiple engines. ///< this flag should be used when applications want full control over ///< multi-engine submission and scheduling. ZE_COMMAND_LIST_FLAG_FORCE_UINT32 = 0x7fffffff } ze_command_list_flag_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Command List descriptor typedef struct _ze_command_list_desc_t { ze_structure_type_t stype; ///< [in] type of this structure const void* pNext; ///< [in][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). uint32_t commandQueueGroupOrdinal; ///< [in] command queue group ordinal to which this command list will be ///< submitted ze_command_list_flags_t flags; ///< [in] usage flags. ///< must be 0 (default) or a valid combination of ::ze_command_list_flag_t; ///< default behavior may use implicit driver-based heuristics to balance ///< latency and throughput. } ze_command_list_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Creates a command list on the context. /// /// @details /// - A command list represents a sequence of commands for execution on a /// command queue. /// - The command list is created in the 'open' state. /// - The application must only use the command list for the device, or its /// sub-devices, which was provided during creation. /// - The application may call this function from simultaneous threads. /// - The implementation of this function must be thread-safe. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hContext` /// + `nullptr == hDevice` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == desc` /// + `nullptr == phCommandList` /// - ::ZE_RESULT_ERROR_INVALID_ENUMERATION /// + `0x7 < desc->flags` ZE_APIEXPORT ze_result_t ZE_APICALL zeCommandListCreate( ze_context_handle_t hContext, ///< [in] handle of the context object ze_device_handle_t hDevice, ///< [in] handle of the device object const ze_command_list_desc_t* desc, ///< [in] pointer to command list descriptor ze_command_list_handle_t* phCommandList ///< [out] pointer to handle of command list object created ); /////////////////////////////////////////////////////////////////////////////// /// @brief Creates an immediate command list on the context. /// /// @details /// - An immediate command list is used for low-latency submission of /// commands. /// - An immediate command list creates an implicit command queue. /// - Commands appended into an immediate command list may execute /// synchronously, by blocking until the command is complete. /// - The command list is created in the 'open' state and never needs to be /// closed. /// - The application must only use the command list for the device, or its /// sub-devices, which was provided during creation. /// - The application may call this function from simultaneous threads. /// - The implementation of this function must be thread-safe. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hContext` /// + `nullptr == hDevice` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == altdesc` /// + `nullptr == phCommandList` /// - ::ZE_RESULT_ERROR_INVALID_ENUMERATION /// + `0x1 < altdesc->flags` /// + `::ZE_COMMAND_QUEUE_MODE_ASYNCHRONOUS < altdesc->mode` /// + `::ZE_COMMAND_QUEUE_PRIORITY_PRIORITY_HIGH < altdesc->priority` ZE_APIEXPORT ze_result_t ZE_APICALL zeCommandListCreateImmediate( ze_context_handle_t hContext, ///< [in] handle of the context object ze_device_handle_t hDevice, ///< [in] handle of the device object const ze_command_queue_desc_t* altdesc, ///< [in] pointer to command queue descriptor ze_command_list_handle_t* phCommandList ///< [out] pointer to handle of command list object created ); /////////////////////////////////////////////////////////////////////////////// /// @brief Destroys a command list. /// /// @details /// - The application must ensure the device is not currently referencing /// the command list before it is deleted. /// - The implementation of this function may immediately free all Host and /// Device allocations associated with this command list. /// - The application must **not** call this function from simultaneous /// threads with the same command list handle. /// - The implementation of this function must be thread-safe. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hCommandList` /// - ::ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE ZE_APIEXPORT ze_result_t ZE_APICALL zeCommandListDestroy( ze_command_list_handle_t hCommandList ///< [in][release] handle of command list object to destroy ); /////////////////////////////////////////////////////////////////////////////// /// @brief Closes a command list; ready to be executed by a command queue. /// /// @details /// - The application must **not** call this function from simultaneous /// threads with the same command list handle. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hCommandList` ZE_APIEXPORT ze_result_t ZE_APICALL zeCommandListClose( ze_command_list_handle_t hCommandList ///< [in] handle of command list object to close ); /////////////////////////////////////////////////////////////////////////////// /// @brief Reset a command list to initial (empty) state; ready for appending /// commands. /// /// @details /// - The application must ensure the device is not currently referencing /// the command list before it is reset /// - The application must **not** call this function from simultaneous /// threads with the same command list handle. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hCommandList` ZE_APIEXPORT ze_result_t ZE_APICALL zeCommandListReset( ze_command_list_handle_t hCommandList ///< [in] handle of command list object to reset ); /////////////////////////////////////////////////////////////////////////////// /// @brief Appends a memory write of the device's global timestamp value into a /// command list. /// /// @details /// - The application must ensure the events are accessible by the device on /// which the command list was created. /// - The timestamp frequency can be queried from /// ::ze_device_properties_t.timerResolution. /// - The number of valid bits in the timestamp value can be queried from /// ::ze_device_properties_t.timestampValidBits. /// - The application must ensure the memory pointed to by dstptr is /// accessible by the device on which the command list was created. /// - The application must ensure the command list and events were created, /// and the memory was allocated, on the same context. /// - The application must **not** call this function from simultaneous /// threads with the same command list handle. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hCommandList` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == dstptr` /// - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT /// - ::ZE_RESULT_ERROR_INVALID_SIZE /// + `(nullptr == phWaitEvents) && (0 < numWaitEvents)` ZE_APIEXPORT ze_result_t ZE_APICALL zeCommandListAppendWriteGlobalTimestamp( ze_command_list_handle_t hCommandList, ///< [in] handle of the command list uint64_t* dstptr, ///< [in,out] pointer to memory where timestamp value will be written; must ///< be 8byte-aligned. ze_event_handle_t hSignalEvent, ///< [in][optional] handle of the event to signal on completion uint32_t numWaitEvents, ///< [in][optional] number of events to wait on before executing query; ///< must be 0 if `nullptr == phWaitEvents` ze_event_handle_t* phWaitEvents ///< [in][optional][range(0, numWaitEvents)] handle of the events to wait ///< on before executing query ); /////////////////////////////////////////////////////////////////////////////// /// @brief Synchronizes an immediate command list by waiting on the host for the /// completion of all commands previously submitted to it. /// /// @details /// - The application must call this function only with command lists /// created with ::zeCommandListCreateImmediate. /// - Waiting on one immediate command list shall not block the concurrent /// execution of commands appended to other /// immediate command lists created with either a different ordinal or /// different index. /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hCommandList` /// - ::ZE_RESULT_NOT_READY /// + timeout expired /// - ::ZE_RESULT_ERROR_INVALID_ARGUMENT /// + handle does not correspond to an immediate command list ZE_APIEXPORT ze_result_t ZE_APICALL zeCommandListHostSynchronize( ze_command_list_handle_t hCommandList, ///< [in] handle of the immediate command list uint64_t timeout ///< [in] if non-zero, then indicates the maximum time (in nanoseconds) to ///< yield before returning ::ZE_RESULT_SUCCESS or ::ZE_RESULT_NOT_READY; ///< if zero, then immediately returns the status of the immediate command list; ///< if UINT64_MAX, then function will not return until complete or device ///< is lost. ///< Due to external dependencies, timeout may be rounded to the closest ///< value allowed by the accuracy of those dependencies. ); #if !defined(__GNUC__) #pragma endregion #endif // Intel 'oneAPI' Level-Zero APIs for Barrier #if !defined(__GNUC__) #pragma region barrier #endif /////////////////////////////////////////////////////////////////////////////// /// @brief Appends an execution and global memory barrier into a command list. /// /// @details /// - The application must ensure the events are accessible by the device on /// which the command list was created. /// - If numWaitEvents is zero, then all previous commands, enqueued on same /// command queue, must complete prior to the execution of the barrier. /// This is not the case when numWaitEvents is non-zero. /// - If numWaitEvents is non-zero, then only all phWaitEvents must be /// signaled prior to the execution of the barrier. /// - This command blocks all following commands from beginning until the /// execution of the barrier completes. /// - The application must **not** call this function from simultaneous /// threads with the same command list handle. /// - The implementation of this function should be lock-free. /// /// @remarks /// _Analogues_ /// - **vkCmdPipelineBarrier** /// - clEnqueueBarrierWithWaitList /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hCommandList` /// - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT /// - ::ZE_RESULT_ERROR_INVALID_SIZE /// + `(nullptr == phWaitEvents) && (0 < numWaitEvents)` ZE_APIEXPORT ze_result_t ZE_APICALL zeCommandListAppendBarrier( ze_command_list_handle_t hCommandList, ///< [in] handle of the command list ze_event_handle_t hSignalEvent, ///< [in][optional] handle of the event to signal on completion uint32_t numWaitEvents, ///< [in][optional] number of events to wait on before executing barrier; ///< must be 0 if `nullptr == phWaitEvents` ze_event_handle_t* phWaitEvents ///< [in][optional][range(0, numWaitEvents)] handle of the events to wait ///< on before executing barrier ); /////////////////////////////////////////////////////////////////////////////// /// @brief Appends a global memory ranges barrier into a command list. /// /// @details /// - The application must ensure the events are accessible by the device on /// which the command list was created. /// - If numWaitEvents is zero, then all previous commands are completed /// prior to the execution of the barrier. /// - If numWaitEvents is non-zero, then then all phWaitEvents must be /// signaled prior to the execution of the barrier. /// - This command blocks all following commands from beginning until the /// execution of the barrier completes. /// - The application must **not** call this function from simultaneous /// threads with the same command list handle. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hCommandList` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pRangeSizes` /// + `nullptr == pRanges` /// - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT /// - ::ZE_RESULT_ERROR_INVALID_SIZE /// + `(nullptr == phWaitEvents) && (0 < numWaitEvents)` ZE_APIEXPORT ze_result_t ZE_APICALL zeCommandListAppendMemoryRangesBarrier( ze_command_list_handle_t hCommandList, ///< [in] handle of the command list uint32_t numRanges, ///< [in] number of memory ranges const size_t* pRangeSizes, ///< [in][range(0, numRanges)] array of sizes of memory range const void** pRanges, ///< [in][range(0, numRanges)] array of memory ranges ze_event_handle_t hSignalEvent, ///< [in][optional] handle of the event to signal on completion uint32_t numWaitEvents, ///< [in][optional] number of events to wait on before executing barrier; ///< must be 0 if `nullptr == phWaitEvents` ze_event_handle_t* phWaitEvents ///< [in][optional][range(0, numWaitEvents)] handle of the events to wait ///< on before executing barrier ); /////////////////////////////////////////////////////////////////////////////// /// @brief Ensures in-bound writes to the device are globally observable. /// /// @details /// - This is a special-case system level barrier that can be used to ensure /// global observability of writes; /// typically needed after a producer (e.g., NIC) performs direct writes /// to the device's memory (e.g., Direct RDMA writes). /// This is typically required when the memory corresponding to the writes /// is subsequently accessed from a remote device. /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hContext` /// + `nullptr == hDevice` ZE_APIEXPORT ze_result_t ZE_APICALL zeContextSystemBarrier( ze_context_handle_t hContext, ///< [in] handle of context object ze_device_handle_t hDevice ///< [in] handle of the device ); #if !defined(__GNUC__) #pragma endregion #endif // Intel 'oneAPI' Level-Zero APIs for Copies #if !defined(__GNUC__) #pragma region copy #endif /////////////////////////////////////////////////////////////////////////////// /// @brief Copies host, device, or shared memory. /// /// @details /// - The application must ensure the memory pointed to by dstptr and srcptr /// is accessible by the device on which the command list was created. /// - The implementation must not access the memory pointed to by dstptr and /// srcptr as they are free to be modified by either the Host or device up /// until execution. /// - The application must ensure the events are accessible by the device on /// which the command list was created. /// - The application must ensure the command list and events were created, /// and the memory was allocated, on the same context. /// - The application must **not** call this function from simultaneous /// threads with the same command list handle. /// - The implementation of this function should be lock-free. /// /// @remarks /// _Analogues_ /// - **clEnqueueCopyBuffer** /// - **clEnqueueReadBuffer** /// - **clEnqueueWriteBuffer** /// - **clEnqueueSVMMemcpy** /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hCommandList` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == dstptr` /// + `nullptr == srcptr` /// - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT /// - ::ZE_RESULT_ERROR_INVALID_SIZE /// + `(nullptr == phWaitEvents) && (0 < numWaitEvents)` ZE_APIEXPORT ze_result_t ZE_APICALL zeCommandListAppendMemoryCopy( ze_command_list_handle_t hCommandList, ///< [in] handle of command list void* dstptr, ///< [in] pointer to destination memory to copy to const void* srcptr, ///< [in] pointer to source memory to copy from size_t size, ///< [in] size in bytes to copy ze_event_handle_t hSignalEvent, ///< [in][optional] handle of the event to signal on completion uint32_t numWaitEvents, ///< [in][optional] number of events to wait on before launching; must be 0 ///< if `nullptr == phWaitEvents` ze_event_handle_t* phWaitEvents ///< [in][optional][range(0, numWaitEvents)] handle of the events to wait ///< on before launching ); /////////////////////////////////////////////////////////////////////////////// /// @brief Initializes host, device, or shared memory. /// /// @details /// - The application must ensure the memory pointed to by dstptr is /// accessible by the device on which the command list was created. /// - The implementation must not access the memory pointed to by dstptr as /// it is free to be modified by either the Host or device up until /// execution. /// - The value to initialize memory to is described by the pattern and the /// pattern size. /// - The pattern size must be a power-of-two and less than or equal to /// ::ze_command_queue_group_properties_t.maxMemoryFillPatternSize. /// - The application must ensure the events are accessible by the device on /// which the command list was created. /// - The application must ensure the command list and events were created, /// and the memory was allocated, on the same context. /// - The application must **not** call this function from simultaneous /// threads with the same command list handle. /// - The implementation of this function should be lock-free. /// /// @remarks /// _Analogues_ /// - **clEnqueueFillBuffer** /// - **clEnqueueSVMMemFill** /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hCommandList` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == ptr` /// + `nullptr == pattern` /// - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT /// - ::ZE_RESULT_ERROR_INVALID_SIZE /// + `(nullptr == phWaitEvents) && (0 < numWaitEvents)` ZE_APIEXPORT ze_result_t ZE_APICALL zeCommandListAppendMemoryFill( ze_command_list_handle_t hCommandList, ///< [in] handle of command list void* ptr, ///< [in] pointer to memory to initialize const void* pattern, ///< [in] pointer to value to initialize memory to size_t pattern_size, ///< [in] size in bytes of the value to initialize memory to size_t size, ///< [in] size in bytes to initialize ze_event_handle_t hSignalEvent, ///< [in][optional] handle of the event to signal on completion uint32_t numWaitEvents, ///< [in][optional] number of events to wait on before launching; must be 0 ///< if `nullptr == phWaitEvents` ze_event_handle_t* phWaitEvents ///< [in][optional][range(0, numWaitEvents)] handle of the events to wait ///< on before launching ); /////////////////////////////////////////////////////////////////////////////// /// @brief Copy region descriptor typedef struct _ze_copy_region_t { uint32_t originX; ///< [in] The origin x offset for region in bytes uint32_t originY; ///< [in] The origin y offset for region in rows uint32_t originZ; ///< [in] The origin z offset for region in slices uint32_t width; ///< [in] The region width relative to origin in bytes uint32_t height; ///< [in] The region height relative to origin in rows uint32_t depth; ///< [in] The region depth relative to origin in slices. Set this to 0 for ///< 2D copy. } ze_copy_region_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Copies a region from a 2D or 3D array of host, device, or shared /// memory. /// /// @details /// - The application must ensure the memory pointed to by dstptr and srcptr /// is accessible by the device on which the command list was created. /// - The implementation must not access the memory pointed to by dstptr and /// srcptr as they are free to be modified by either the Host or device up /// until execution. /// - The region width, height, and depth for both src and dst must be same. /// The origins can be different. /// - The src and dst regions cannot be overlapping. /// - The application must ensure the events are accessible by the device on /// which the command list was created. /// - The application must ensure the command list and events were created, /// and the memory was allocated, on the same context. /// - The application must **not** call this function from simultaneous /// threads with the same command list handle. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hCommandList` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == dstptr` /// + `nullptr == dstRegion` /// + `nullptr == srcptr` /// + `nullptr == srcRegion` /// - ::ZE_RESULT_ERROR_OVERLAPPING_REGIONS /// - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT /// - ::ZE_RESULT_ERROR_INVALID_SIZE /// + `(nullptr == phWaitEvents) && (0 < numWaitEvents)` ZE_APIEXPORT ze_result_t ZE_APICALL zeCommandListAppendMemoryCopyRegion( ze_command_list_handle_t hCommandList, ///< [in] handle of command list void* dstptr, ///< [in] pointer to destination memory to copy to const ze_copy_region_t* dstRegion, ///< [in] pointer to destination region to copy to uint32_t dstPitch, ///< [in] destination pitch in bytes uint32_t dstSlicePitch, ///< [in] destination slice pitch in bytes. This is required for 3D region ///< copies where ::ze_copy_region_t.depth is not 0, otherwise it's ///< ignored. const void* srcptr, ///< [in] pointer to source memory to copy from const ze_copy_region_t* srcRegion, ///< [in] pointer to source region to copy from uint32_t srcPitch, ///< [in] source pitch in bytes uint32_t srcSlicePitch, ///< [in] source slice pitch in bytes. This is required for 3D region ///< copies where ::ze_copy_region_t.depth is not 0, otherwise it's ///< ignored. ze_event_handle_t hSignalEvent, ///< [in][optional] handle of the event to signal on completion uint32_t numWaitEvents, ///< [in][optional] number of events to wait on before launching; must be 0 ///< if `nullptr == phWaitEvents` ze_event_handle_t* phWaitEvents ///< [in][optional][range(0, numWaitEvents)] handle of the events to wait ///< on before launching ); /////////////////////////////////////////////////////////////////////////////// /// @brief Copies host, device, or shared memory from another context. /// /// @details /// - The current active and source context must be from the same driver. /// - The application must ensure the memory pointed to by dstptr and srcptr /// is accessible by the device on which the command list was created. /// - The implementation must not access the memory pointed to by dstptr and /// srcptr as they are free to be modified by either the Host or device up /// until execution. /// - The application must ensure the events are accessible by the device on /// which the command list was created. /// - The application must ensure the command list and events were created, /// and the memory was allocated, on the same context. /// - The application must **not** call this function from simultaneous /// threads with the same command list handle. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hCommandList` /// + `nullptr == hContextSrc` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == dstptr` /// + `nullptr == srcptr` /// - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT /// - ::ZE_RESULT_ERROR_INVALID_SIZE /// + `(nullptr == phWaitEvents) && (0 < numWaitEvents)` ZE_APIEXPORT ze_result_t ZE_APICALL zeCommandListAppendMemoryCopyFromContext( ze_command_list_handle_t hCommandList, ///< [in] handle of command list void* dstptr, ///< [in] pointer to destination memory to copy to ze_context_handle_t hContextSrc, ///< [in] handle of source context object const void* srcptr, ///< [in] pointer to source memory to copy from size_t size, ///< [in] size in bytes to copy ze_event_handle_t hSignalEvent, ///< [in][optional] handle of the event to signal on completion uint32_t numWaitEvents, ///< [in][optional] number of events to wait on before launching; must be 0 ///< if `nullptr == phWaitEvents` ze_event_handle_t* phWaitEvents ///< [in][optional][range(0, numWaitEvents)] handle of the events to wait ///< on before launching ); /////////////////////////////////////////////////////////////////////////////// /// @brief Copies an image. /// /// @details /// - The application must ensure the image and events are accessible by the /// device on which the command list was created. /// - The application must ensure the image format descriptors for both /// source and destination images are the same. /// - The application must ensure the command list, images and events were /// created on the same context. /// - The application must **not** call this function from simultaneous /// threads with the same command list handle. /// - The implementation of this function should be lock-free. /// /// @remarks /// _Analogues_ /// - **clEnqueueCopyImage** /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hCommandList` /// + `nullptr == hDstImage` /// + `nullptr == hSrcImage` /// - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT /// - ::ZE_RESULT_ERROR_INVALID_SIZE /// + `(nullptr == phWaitEvents) && (0 < numWaitEvents)` ZE_APIEXPORT ze_result_t ZE_APICALL zeCommandListAppendImageCopy( ze_command_list_handle_t hCommandList, ///< [in] handle of command list ze_image_handle_t hDstImage, ///< [in] handle of destination image to copy to ze_image_handle_t hSrcImage, ///< [in] handle of source image to copy from ze_event_handle_t hSignalEvent, ///< [in][optional] handle of the event to signal on completion uint32_t numWaitEvents, ///< [in][optional] number of events to wait on before launching; must be 0 ///< if `nullptr == phWaitEvents` ze_event_handle_t* phWaitEvents ///< [in][optional][range(0, numWaitEvents)] handle of the events to wait ///< on before launching ); /////////////////////////////////////////////////////////////////////////////// /// @brief Region descriptor typedef struct _ze_image_region_t { uint32_t originX; ///< [in] The origin x offset for region in pixels uint32_t originY; ///< [in] The origin y offset for region in pixels uint32_t originZ; ///< [in] The origin z offset for region in pixels uint32_t width; ///< [in] The region width relative to origin in pixels uint32_t height; ///< [in] The region height relative to origin in pixels uint32_t depth; ///< [in] The region depth relative to origin. For 1D or 2D images, set ///< this to 1. } ze_image_region_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Copies a region of an image to another image. /// /// @details /// - The application must ensure the image and events are accessible by the /// device on which the command list was created. /// - The region width and height for both src and dst must be same. The /// origins can be different. /// - The src and dst regions cannot be overlapping. /// - The application must ensure the image format descriptors for both /// source and destination images are the same. /// - The application must ensure the command list, images and events were /// created, and the memory was allocated, on the same context. /// - The application must **not** call this function from simultaneous /// threads with the same command list handle. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hCommandList` /// + `nullptr == hDstImage` /// + `nullptr == hSrcImage` /// - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT /// - ::ZE_RESULT_ERROR_OVERLAPPING_REGIONS /// - ::ZE_RESULT_ERROR_INVALID_SIZE /// + `(nullptr == phWaitEvents) && (0 < numWaitEvents)` ZE_APIEXPORT ze_result_t ZE_APICALL zeCommandListAppendImageCopyRegion( ze_command_list_handle_t hCommandList, ///< [in] handle of command list ze_image_handle_t hDstImage, ///< [in] handle of destination image to copy to ze_image_handle_t hSrcImage, ///< [in] handle of source image to copy from const ze_image_region_t* pDstRegion, ///< [in][optional] destination region descriptor const ze_image_region_t* pSrcRegion, ///< [in][optional] source region descriptor ze_event_handle_t hSignalEvent, ///< [in][optional] handle of the event to signal on completion uint32_t numWaitEvents, ///< [in][optional] number of events to wait on before launching; must be 0 ///< if `nullptr == phWaitEvents` ze_event_handle_t* phWaitEvents ///< [in][optional][range(0, numWaitEvents)] handle of the events to wait ///< on before launching ); /////////////////////////////////////////////////////////////////////////////// /// @brief Copies from an image to device or shared memory. /// /// @details /// - The application must ensure the memory pointed to by dstptr is /// accessible by the device on which the command list was created. /// - The implementation must not access the memory pointed to by dstptr as /// it is free to be modified by either the Host or device up until /// execution. /// - The application must ensure the image and events are accessible by the /// device on which the command list was created. /// - The application must ensure the image format descriptor for the source /// image is a single-planar format. /// - The application must ensure the command list, image and events were /// created, and the memory was allocated, on the same context. /// - The application must **not** call this function from simultaneous /// threads with the same command list handle. /// - The implementation of this function should be lock-free. /// /// @remarks /// _Analogues_ /// - clEnqueueReadImage /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hCommandList` /// + `nullptr == hSrcImage` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == dstptr` /// - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT /// - ::ZE_RESULT_ERROR_INVALID_SIZE /// + `(nullptr == phWaitEvents) && (0 < numWaitEvents)` ZE_APIEXPORT ze_result_t ZE_APICALL zeCommandListAppendImageCopyToMemory( ze_command_list_handle_t hCommandList, ///< [in] handle of command list void* dstptr, ///< [in] pointer to destination memory to copy to ze_image_handle_t hSrcImage, ///< [in] handle of source image to copy from const ze_image_region_t* pSrcRegion, ///< [in][optional] source region descriptor ze_event_handle_t hSignalEvent, ///< [in][optional] handle of the event to signal on completion uint32_t numWaitEvents, ///< [in][optional] number of events to wait on before launching; must be 0 ///< if `nullptr == phWaitEvents` ze_event_handle_t* phWaitEvents ///< [in][optional][range(0, numWaitEvents)] handle of the events to wait ///< on before launching ); /////////////////////////////////////////////////////////////////////////////// /// @brief Copies to an image from device or shared memory. /// /// @details /// - The application must ensure the memory pointed to by srcptr is /// accessible by the device on which the command list was created. /// - The implementation must not access the memory pointed to by srcptr as /// it is free to be modified by either the Host or device up until /// execution. /// - The application must ensure the image and events are accessible by the /// device on which the command list was created. /// - The application must ensure the image format descriptor for the /// destination image is a single-planar format. /// - The application must ensure the command list, image and events were /// created, and the memory was allocated, on the same context. /// - The application must **not** call this function from simultaneous /// threads with the same command list handle. /// - The implementation of this function should be lock-free. /// /// @remarks /// _Analogues_ /// - clEnqueueWriteImage /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hCommandList` /// + `nullptr == hDstImage` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == srcptr` /// - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT /// - ::ZE_RESULT_ERROR_INVALID_SIZE /// + `(nullptr == phWaitEvents) && (0 < numWaitEvents)` ZE_APIEXPORT ze_result_t ZE_APICALL zeCommandListAppendImageCopyFromMemory( ze_command_list_handle_t hCommandList, ///< [in] handle of command list ze_image_handle_t hDstImage, ///< [in] handle of destination image to copy to const void* srcptr, ///< [in] pointer to source memory to copy from const ze_image_region_t* pDstRegion, ///< [in][optional] destination region descriptor ze_event_handle_t hSignalEvent, ///< [in][optional] handle of the event to signal on completion uint32_t numWaitEvents, ///< [in][optional] number of events to wait on before launching; must be 0 ///< if `nullptr == phWaitEvents` ze_event_handle_t* phWaitEvents ///< [in][optional][range(0, numWaitEvents)] handle of the events to wait ///< on before launching ); /////////////////////////////////////////////////////////////////////////////// /// @brief Asynchronously prefetches shared memory to the device associated with /// the specified command list /// /// @details /// - This is a hint to improve performance only and is not required for /// correctness. /// - Only prefetching to the device associated with the specified command /// list is supported. /// Prefetching to the host or to a peer device is not supported. /// - Prefetching may not be supported for all allocation types for all devices. /// If memory prefetching is not supported for the specified memory range /// the prefetch hint may be ignored. /// - Prefetching may only be supported at a device-specific granularity, /// such as at a page boundary. /// In this case, the memory range may be expanded such that the start and /// end of the range satisfy granularity requirements. /// - The application must ensure the memory pointed to by ptr is accessible /// by the device on which the command list was created. /// - The application must ensure the command list was created, and the /// memory was allocated, on the same context. /// - The application must **not** call this function from simultaneous /// threads with the same command list handle. /// - The implementation of this function should be lock-free. /// /// @remarks /// _Analogues_ /// - clEnqueueSVMMigrateMem /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hCommandList` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == ptr` ZE_APIEXPORT ze_result_t ZE_APICALL zeCommandListAppendMemoryPrefetch( ze_command_list_handle_t hCommandList, ///< [in] handle of command list const void* ptr, ///< [in] pointer to start of the memory range to prefetch size_t size ///< [in] size in bytes of the memory range to prefetch ); /////////////////////////////////////////////////////////////////////////////// /// @brief Supported memory advice hints typedef enum _ze_memory_advice_t { ZE_MEMORY_ADVICE_SET_READ_MOSTLY = 0, ///< hint that memory will be read from frequently and written to rarely ZE_MEMORY_ADVICE_CLEAR_READ_MOSTLY = 1, ///< removes the affect of ::ZE_MEMORY_ADVICE_SET_READ_MOSTLY ZE_MEMORY_ADVICE_SET_PREFERRED_LOCATION = 2, ///< hint that the preferred memory location is the specified device ZE_MEMORY_ADVICE_CLEAR_PREFERRED_LOCATION = 3, ///< removes the affect of ::ZE_MEMORY_ADVICE_SET_PREFERRED_LOCATION ZE_MEMORY_ADVICE_SET_NON_ATOMIC_MOSTLY = 4, ///< hints that memory will mostly be accessed non-atomically ZE_MEMORY_ADVICE_CLEAR_NON_ATOMIC_MOSTLY = 5, ///< removes the affect of ::ZE_MEMORY_ADVICE_SET_NON_ATOMIC_MOSTLY ZE_MEMORY_ADVICE_BIAS_CACHED = 6, ///< hints that memory should be cached ZE_MEMORY_ADVICE_BIAS_UNCACHED = 7, ///< hints that memory should be not be cached ZE_MEMORY_ADVICE_FORCE_UINT32 = 0x7fffffff } ze_memory_advice_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Provides advice about the use of a shared memory range /// /// @details /// - Memory advice is a performance hint only and is not required for /// functional correctness. /// - Memory advice can be used to override driver heuristics to explicitly /// control shared memory behavior. /// - Not all memory advice hints may be supported for all allocation types /// for all devices. /// If a memory advice hint is not supported by the device it will be ignored. /// - Memory advice may only be supported at a device-specific granularity, /// such as at a page boundary. /// In this case, the memory range may be expanded such that the start and /// end of the range satisfy granularity requirements. /// - The application must ensure the memory pointed to by ptr is accessible /// by the device on which the command list was created. /// - The application must ensure the command list was created, and memory /// was allocated, on the same context. /// - The application must **not** call this function from simultaneous /// threads with the same command list handle, and the memory was /// allocated. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hCommandList` /// + `nullptr == hDevice` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == ptr` /// - ::ZE_RESULT_ERROR_INVALID_ENUMERATION /// + `::ZE_MEMORY_ADVICE_BIAS_UNCACHED < advice` ZE_APIEXPORT ze_result_t ZE_APICALL zeCommandListAppendMemAdvise( ze_command_list_handle_t hCommandList, ///< [in] handle of command list ze_device_handle_t hDevice, ///< [in] device associated with the memory advice const void* ptr, ///< [in] Pointer to the start of the memory range size_t size, ///< [in] Size in bytes of the memory range ze_memory_advice_t advice ///< [in] Memory advice for the memory range ); #if !defined(__GNUC__) #pragma endregion #endif // Intel 'oneAPI' Level-Zero APIs for Event #if !defined(__GNUC__) #pragma region event #endif /////////////////////////////////////////////////////////////////////////////// /// @brief Supported event pool creation flags typedef uint32_t ze_event_pool_flags_t; typedef enum _ze_event_pool_flag_t { ZE_EVENT_POOL_FLAG_HOST_VISIBLE = ZE_BIT(0), ///< signals and waits are also visible to host ZE_EVENT_POOL_FLAG_IPC = ZE_BIT(1), ///< signals and waits may be shared across processes ZE_EVENT_POOL_FLAG_KERNEL_TIMESTAMP = ZE_BIT(2),///< Indicates all events in pool will contain kernel timestamps ZE_EVENT_POOL_FLAG_KERNEL_MAPPED_TIMESTAMP = ZE_BIT(3), ///< Indicates all events in pool will contain kernel timestamps ///< synchronized to host time domain; cannot be combined with ///< ::ZE_EVENT_POOL_FLAG_KERNEL_TIMESTAMP ZE_EVENT_POOL_FLAG_FORCE_UINT32 = 0x7fffffff } ze_event_pool_flag_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Event pool descriptor typedef struct _ze_event_pool_desc_t { ze_structure_type_t stype; ///< [in] type of this structure const void* pNext; ///< [in][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). ze_event_pool_flags_t flags; ///< [in] creation flags. ///< must be 0 (default) or a valid combination of ::ze_event_pool_flag_t; ///< default behavior is signals and waits are visible to the entire device ///< and peer devices. uint32_t count; ///< [in] number of events within the pool; must be greater than 0 } ze_event_pool_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Creates a pool of events on the context. /// /// @details /// - The application must only use events within the pool for the /// device(s), or their sub-devices, which were provided during creation. /// - The application may call this function from simultaneous threads. /// - The implementation of this function must be thread-safe. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hContext` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == desc` /// + `nullptr == phEventPool` /// - ::ZE_RESULT_ERROR_INVALID_ENUMERATION /// + `0xf < desc->flags` /// - ::ZE_RESULT_ERROR_INVALID_SIZE /// + `0 == desc->count` /// + `(nullptr == phDevices) && (0 < numDevices)` ZE_APIEXPORT ze_result_t ZE_APICALL zeEventPoolCreate( ze_context_handle_t hContext, ///< [in] handle of the context object const ze_event_pool_desc_t* desc, ///< [in] pointer to event pool descriptor uint32_t numDevices, ///< [in][optional] number of device handles; must be 0 if `nullptr == ///< phDevices` ze_device_handle_t* phDevices, ///< [in][optional][range(0, numDevices)] array of device handles which ///< have visibility to the event pool. ///< if nullptr, then event pool is visible to all devices supported by the ///< driver instance. ze_event_pool_handle_t* phEventPool ///< [out] pointer handle of event pool object created ); /////////////////////////////////////////////////////////////////////////////// /// @brief Deletes an event pool object. /// /// @details /// - The application must destroy all event handles created from the pool /// before destroying the pool itself. /// - The application must ensure the device is not currently referencing /// the any event within the pool before it is deleted. /// - The implementation of this function may immediately free all Host and /// Device allocations associated with this event pool. /// - The application must **not** call this function from simultaneous /// threads with the same event pool handle. /// - The implementation of this function must be thread-safe. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hEventPool` /// - ::ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE ZE_APIEXPORT ze_result_t ZE_APICALL zeEventPoolDestroy( ze_event_pool_handle_t hEventPool ///< [in][release] handle of event pool object to destroy ); /////////////////////////////////////////////////////////////////////////////// /// @brief Supported event scope flags typedef uint32_t ze_event_scope_flags_t; typedef enum _ze_event_scope_flag_t { ZE_EVENT_SCOPE_FLAG_SUBDEVICE = ZE_BIT(0), ///< cache hierarchies are flushed or invalidated sufficient for local ///< sub-device access ZE_EVENT_SCOPE_FLAG_DEVICE = ZE_BIT(1), ///< cache hierarchies are flushed or invalidated sufficient for global ///< device access and peer device access ZE_EVENT_SCOPE_FLAG_HOST = ZE_BIT(2), ///< cache hierarchies are flushed or invalidated sufficient for device and ///< host access ZE_EVENT_SCOPE_FLAG_FORCE_UINT32 = 0x7fffffff } ze_event_scope_flag_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Event descriptor typedef struct _ze_event_desc_t { ze_structure_type_t stype; ///< [in] type of this structure const void* pNext; ///< [in][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). uint32_t index; ///< [in] index of the event within the pool; must be less than the count ///< specified during pool creation ze_event_scope_flags_t signal; ///< [in] defines the scope of relevant cache hierarchies to flush on a ///< signal action before the event is triggered. ///< must be 0 (default) or a valid combination of ::ze_event_scope_flag_t; ///< default behavior is synchronization within the command list only, no ///< additional cache hierarchies are flushed. ze_event_scope_flags_t wait; ///< [in] defines the scope of relevant cache hierarchies to invalidate on ///< a wait action after the event is complete. ///< must be 0 (default) or a valid combination of ::ze_event_scope_flag_t; ///< default behavior is synchronization within the command list only, no ///< additional cache hierarchies are invalidated. } ze_event_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Creates an event from the pool. /// /// @details /// - An event is used to communicate fine-grain host-to-device, /// device-to-host or device-to-device dependencies have completed. /// - The application must ensure the location in the pool is not being used /// by another event. /// - The application must **not** call this function from simultaneous /// threads with the same event pool handle. /// - The implementation of this function should be lock-free. /// /// @remarks /// _Analogues_ /// - **clCreateUserEvent** /// - vkCreateEvent /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hEventPool` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == desc` /// + `nullptr == phEvent` /// - ::ZE_RESULT_ERROR_INVALID_ENUMERATION /// + `0x7 < desc->signal` /// + `0x7 < desc->wait` ZE_APIEXPORT ze_result_t ZE_APICALL zeEventCreate( ze_event_pool_handle_t hEventPool, ///< [in] handle of the event pool const ze_event_desc_t* desc, ///< [in] pointer to event descriptor ze_event_handle_t* phEvent ///< [out] pointer to handle of event object created ); /////////////////////////////////////////////////////////////////////////////// /// @brief Deletes an event object. /// /// @details /// - The application must ensure the device is not currently referencing /// the event before it is deleted. /// - The implementation of this function may immediately free all Host and /// Device allocations associated with this event. /// - The application must **not** call this function from simultaneous /// threads with the same event handle. /// - The implementation of this function should be lock-free. /// /// @remarks /// _Analogues_ /// - **clReleaseEvent** /// - vkDestroyEvent /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hEvent` /// - ::ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE ZE_APIEXPORT ze_result_t ZE_APICALL zeEventDestroy( ze_event_handle_t hEvent ///< [in][release] handle of event object to destroy ); /////////////////////////////////////////////////////////////////////////////// /// @brief Gets an IPC event pool handle for the specified event handle that can /// be shared with another process. /// /// @details /// - Event pool must have been created with ::ZE_EVENT_POOL_FLAG_IPC. /// - The application may call this function from simultaneous threads. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hEventPool` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == phIpc` /// - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT ZE_APIEXPORT ze_result_t ZE_APICALL zeEventPoolGetIpcHandle( ze_event_pool_handle_t hEventPool, ///< [in] handle of event pool object ze_ipc_event_pool_handle_t* phIpc ///< [out] Returned IPC event handle ); /////////////////////////////////////////////////////////////////////////////// /// @brief Returns an IPC event pool handle to the driver /// /// @details /// - This call must be used for IPC handles previously obtained with /// ::zeEventPoolGetIpcHandle. /// - Upon call, driver may release any underlying resources associated with /// the IPC handle. /// For instance, it may close the file descriptor contained in the IPC /// handle, if such type of handle is being used by the driver. /// - This call does not destroy the original event pool for which the IPC /// handle was created. /// - This function may **not** be called from simultaneous threads with the /// same IPC handle. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hContext` ZE_APIEXPORT ze_result_t ZE_APICALL zeEventPoolPutIpcHandle( ze_context_handle_t hContext, ///< [in] handle of the context object associated with the IPC event pool ///< handle ze_ipc_event_pool_handle_t hIpc ///< [in] IPC event pool handle ); /////////////////////////////////////////////////////////////////////////////// /// @brief Opens an IPC event pool handle to retrieve an event pool handle from /// another process. /// /// @details /// - Multiple calls to this function with the same IPC handle will return /// unique event pool handles. /// - The event handle in this process should not be freed with /// ::zeEventPoolDestroy, but rather with ::zeEventPoolCloseIpcHandle. /// - The application may call this function from simultaneous threads. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hContext` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == phEventPool` ZE_APIEXPORT ze_result_t ZE_APICALL zeEventPoolOpenIpcHandle( ze_context_handle_t hContext, ///< [in] handle of the context object to associate with the IPC event pool ///< handle ze_ipc_event_pool_handle_t hIpc, ///< [in] IPC event pool handle ze_event_pool_handle_t* phEventPool ///< [out] pointer handle of event pool object created ); /////////////////////////////////////////////////////////////////////////////// /// @brief Closes an IPC event handle in the current process. /// /// @details /// - Closes an IPC event handle by destroying events that were opened in /// this process using ::zeEventPoolOpenIpcHandle. /// - The application must **not** call this function from simultaneous /// threads with the same event pool handle. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hEventPool` ZE_APIEXPORT ze_result_t ZE_APICALL zeEventPoolCloseIpcHandle( ze_event_pool_handle_t hEventPool ///< [in][release] handle of event pool object ); /////////////////////////////////////////////////////////////////////////////// /// @brief Appends a signal of the event from the device into a command list. /// /// @details /// - The application must ensure the events are accessible by the device on /// which the command list was created. /// - The duration of an event created from an event pool that was created /// using ::ZE_EVENT_POOL_FLAG_KERNEL_TIMESTAMP or /// ::ZE_EVENT_POOL_FLAG_KERNEL_MAPPED_TIMESTAMP flags is undefined. /// However, for consistency and orthogonality the event will report /// correctly as signaled when used by other event API functionality. /// - The application must ensure the command list and events were created /// on the same context. /// - The application must **not** call this function from simultaneous /// threads with the same command list handle. /// - The implementation of this function should be lock-free. /// /// @remarks /// _Analogues_ /// - **clSetUserEventStatus** /// - vkCmdSetEvent /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hCommandList` /// + `nullptr == hEvent` /// - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT ZE_APIEXPORT ze_result_t ZE_APICALL zeCommandListAppendSignalEvent( ze_command_list_handle_t hCommandList, ///< [in] handle of the command list ze_event_handle_t hEvent ///< [in] handle of the event ); /////////////////////////////////////////////////////////////////////////////// /// @brief Appends wait on event(s) on the device into a command list. /// /// @details /// - The application must ensure the events are accessible by the device on /// which the command list was created. /// - The application must ensure the command list and events were created /// on the same context. /// - The application must **not** call this function from simultaneous /// threads with the same command list handle. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hCommandList` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == phEvents` /// - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT ZE_APIEXPORT ze_result_t ZE_APICALL zeCommandListAppendWaitOnEvents( ze_command_list_handle_t hCommandList, ///< [in] handle of the command list uint32_t numEvents, ///< [in] number of events to wait on before continuing ze_event_handle_t* phEvents ///< [in][range(0, numEvents)] handles of the events to wait on before ///< continuing ); /////////////////////////////////////////////////////////////////////////////// /// @brief Signals a event from host. /// /// @details /// - The duration of an event created from an event pool that was created /// using ::ZE_EVENT_POOL_FLAG_KERNEL_TIMESTAMP or /// ::ZE_EVENT_POOL_FLAG_KERNEL_MAPPED_TIMESTAMP flags is undefined. /// However, for consistency and orthogonality the event will report /// correctly as signaled when used by other event API functionality. /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @remarks /// _Analogues_ /// - clSetUserEventStatus /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hEvent` /// - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT ZE_APIEXPORT ze_result_t ZE_APICALL zeEventHostSignal( ze_event_handle_t hEvent ///< [in] handle of the event ); /////////////////////////////////////////////////////////////////////////////// /// @brief The current host thread waits on an event to be signaled. /// /// @details /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @remarks /// _Analogues_ /// - clWaitForEvents /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hEvent` /// - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT /// - ::ZE_RESULT_NOT_READY /// + timeout expired ZE_APIEXPORT ze_result_t ZE_APICALL zeEventHostSynchronize( ze_event_handle_t hEvent, ///< [in] handle of the event uint64_t timeout ///< [in] if non-zero, then indicates the maximum time (in nanoseconds) to ///< yield before returning ::ZE_RESULT_SUCCESS or ::ZE_RESULT_NOT_READY; ///< if zero, then operates exactly like ::zeEventQueryStatus; ///< if UINT64_MAX, then function will not return until complete or device ///< is lost. ///< Due to external dependencies, timeout may be rounded to the closest ///< value allowed by the accuracy of those dependencies. ); /////////////////////////////////////////////////////////////////////////////// /// @brief Queries an event object's status on the host. /// /// @details /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @remarks /// _Analogues_ /// - **clGetEventInfo** /// - vkGetEventStatus /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hEvent` /// - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT /// - ::ZE_RESULT_NOT_READY /// + not signaled ZE_APIEXPORT ze_result_t ZE_APICALL zeEventQueryStatus( ze_event_handle_t hEvent ///< [in] handle of the event ); /////////////////////////////////////////////////////////////////////////////// /// @brief Appends a reset of an event back to not signaled state into a command /// list. /// /// @details /// - The application must ensure the events are accessible by the device on /// which the command list was created. /// - The application must ensure the command list and events were created /// on the same context. /// - The application must **not** call this function from simultaneous /// threads with the same command list handle. /// - The implementation of this function should be lock-free. /// /// @remarks /// _Analogues_ /// - vkResetEvent /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hCommandList` /// + `nullptr == hEvent` /// - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT ZE_APIEXPORT ze_result_t ZE_APICALL zeCommandListAppendEventReset( ze_command_list_handle_t hCommandList, ///< [in] handle of the command list ze_event_handle_t hEvent ///< [in] handle of the event ); /////////////////////////////////////////////////////////////////////////////// /// @brief The current host thread resets an event back to not signaled state. /// /// @details /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @remarks /// _Analogues_ /// - vkResetEvent /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hEvent` /// - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT ZE_APIEXPORT ze_result_t ZE_APICALL zeEventHostReset( ze_event_handle_t hEvent ///< [in] handle of the event ); /////////////////////////////////////////////////////////////////////////////// /// @brief Kernel timestamp clock data /// /// @details /// - The timestamp frequency can be queried from /// ::ze_device_properties_t.timerResolution. /// - The number of valid bits in the timestamp value can be queried from /// ::ze_device_properties_t.kernelTimestampValidBits. typedef struct _ze_kernel_timestamp_data_t { uint64_t kernelStart; ///< [out] device clock at start of kernel execution uint64_t kernelEnd; ///< [out] device clock at end of kernel execution } ze_kernel_timestamp_data_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Kernel timestamp result typedef struct _ze_kernel_timestamp_result_t { ze_kernel_timestamp_data_t global; ///< [out] wall-clock data ze_kernel_timestamp_data_t context; ///< [out] context-active data; only includes clocks while device context ///< was actively executing. } ze_kernel_timestamp_result_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Queries an event's timestamp value on the host. /// /// @details /// - The application must ensure the event was created from an event pool /// that was created using ::ZE_EVENT_POOL_FLAG_KERNEL_TIMESTAMP or /// ::ZE_EVENT_POOL_FLAG_KERNEL_MAPPED_TIMESTAMP flag. /// - The destination memory will be unmodified if the event has not been /// signaled. /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hEvent` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == dstptr` /// - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT /// - ::ZE_RESULT_NOT_READY /// + not signaled ZE_APIEXPORT ze_result_t ZE_APICALL zeEventQueryKernelTimestamp( ze_event_handle_t hEvent, ///< [in] handle of the event ze_kernel_timestamp_result_t* dstptr ///< [in,out] pointer to memory for where timestamp result will be written. ); /////////////////////////////////////////////////////////////////////////////// /// @brief Appends a query of an events' timestamp value(s) into a command list. /// /// @details /// - The application must ensure the events are accessible by the device on /// which the command list was created. /// - The application must ensure the events were created from an event pool /// that was created using ::ZE_EVENT_POOL_FLAG_KERNEL_TIMESTAMP flag. /// - The application must ensure the memory pointed to by both dstptr and /// pOffsets is accessible by the device on which the command list was /// created. /// - The value(s) written to the destination buffer are undefined if any /// timestamp event has not been signaled. /// - If pOffsets is nullptr, then multiple results will be appended /// sequentially into memory in the same order as phEvents. /// - The application must ensure the command list and events were created, /// and the memory was allocated, on the same context. /// - The application must **not** call this function from simultaneous /// threads with the same command list handle. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hCommandList` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == phEvents` /// + `nullptr == dstptr` /// - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT /// - ::ZE_RESULT_ERROR_INVALID_SIZE /// + `(nullptr == phWaitEvents) && (0 < numWaitEvents)` ZE_APIEXPORT ze_result_t ZE_APICALL zeCommandListAppendQueryKernelTimestamps( ze_command_list_handle_t hCommandList, ///< [in] handle of the command list uint32_t numEvents, ///< [in] the number of timestamp events to query ze_event_handle_t* phEvents, ///< [in][range(0, numEvents)] handles of timestamp events to query void* dstptr, ///< [in,out] pointer to memory where ::ze_kernel_timestamp_result_t will ///< be written; must be size-aligned. const size_t* pOffsets, ///< [in][optional][range(0, numEvents)] offset, in bytes, to write ///< results; address must be 4byte-aligned and offsets must be ///< size-aligned. ze_event_handle_t hSignalEvent, ///< [in][optional] handle of the event to signal on completion uint32_t numWaitEvents, ///< [in][optional] number of events to wait on before executing query; ///< must be 0 if `nullptr == phWaitEvents` ze_event_handle_t* phWaitEvents ///< [in][optional][range(0, numWaitEvents)] handle of the events to wait ///< on before executing query ); #if !defined(__GNUC__) #pragma endregion #endif // Intel 'oneAPI' Level-Zero APIs for Fence #if !defined(__GNUC__) #pragma region fence #endif /////////////////////////////////////////////////////////////////////////////// /// @brief Supported fence creation flags typedef uint32_t ze_fence_flags_t; typedef enum _ze_fence_flag_t { ZE_FENCE_FLAG_SIGNALED = ZE_BIT(0), ///< fence is created in the signaled state, otherwise not signaled. ZE_FENCE_FLAG_FORCE_UINT32 = 0x7fffffff } ze_fence_flag_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Fence descriptor typedef struct _ze_fence_desc_t { ze_structure_type_t stype; ///< [in] type of this structure const void* pNext; ///< [in][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). ze_fence_flags_t flags; ///< [in] creation flags. ///< must be 0 (default) or a valid combination of ::ze_fence_flag_t. } ze_fence_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Creates a fence for the command queue. /// /// @details /// - A fence is a heavyweight synchronization primitive used to communicate /// to the host that command list execution has completed. /// - The application must only use the fence for the command queue which /// was provided during creation. /// - The application may call this function from simultaneous threads. /// - The implementation of this function must be thread-safe. /// /// @remarks /// _Analogues_ /// - **vkCreateFence** /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hCommandQueue` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == desc` /// + `nullptr == phFence` /// - ::ZE_RESULT_ERROR_INVALID_ENUMERATION /// + `0x1 < desc->flags` ZE_APIEXPORT ze_result_t ZE_APICALL zeFenceCreate( ze_command_queue_handle_t hCommandQueue, ///< [in] handle of command queue const ze_fence_desc_t* desc, ///< [in] pointer to fence descriptor ze_fence_handle_t* phFence ///< [out] pointer to handle of fence object created ); /////////////////////////////////////////////////////////////////////////////// /// @brief Deletes a fence object. /// /// @details /// - The application must ensure the device is not currently referencing /// the fence before it is deleted. /// - The implementation of this function may immediately free all Host and /// Device allocations associated with this fence. /// - The application must **not** call this function from simultaneous /// threads with the same fence handle. /// - The implementation of this function must be thread-safe. /// /// @remarks /// _Analogues_ /// - **vkDestroyFence** /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hFence` /// - ::ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE ZE_APIEXPORT ze_result_t ZE_APICALL zeFenceDestroy( ze_fence_handle_t hFence ///< [in][release] handle of fence object to destroy ); /////////////////////////////////////////////////////////////////////////////// /// @brief The current host thread waits on a fence to be signaled. /// /// @details /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @remarks /// _Analogues_ /// - **vkWaitForFences** /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hFence` /// - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT /// - ::ZE_RESULT_NOT_READY /// + timeout expired ZE_APIEXPORT ze_result_t ZE_APICALL zeFenceHostSynchronize( ze_fence_handle_t hFence, ///< [in] handle of the fence uint64_t timeout ///< [in] if non-zero, then indicates the maximum time (in nanoseconds) to ///< yield before returning ::ZE_RESULT_SUCCESS or ::ZE_RESULT_NOT_READY; ///< if zero, then operates exactly like ::zeFenceQueryStatus; ///< if UINT64_MAX, then function will not return until complete or device ///< is lost. ///< Due to external dependencies, timeout may be rounded to the closest ///< value allowed by the accuracy of those dependencies. ); /////////////////////////////////////////////////////////////////////////////// /// @brief Queries a fence object's status. /// /// @details /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @remarks /// _Analogues_ /// - **vkGetFenceStatus** /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hFence` /// - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT /// - ::ZE_RESULT_NOT_READY /// + not signaled ZE_APIEXPORT ze_result_t ZE_APICALL zeFenceQueryStatus( ze_fence_handle_t hFence ///< [in] handle of the fence ); /////////////////////////////////////////////////////////////////////////////// /// @brief Reset a fence back to the not signaled state. /// /// @details /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @remarks /// _Analogues_ /// - **vkResetFences** /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hFence` ZE_APIEXPORT ze_result_t ZE_APICALL zeFenceReset( ze_fence_handle_t hFence ///< [in] handle of the fence ); #if !defined(__GNUC__) #pragma endregion #endif // Intel 'oneAPI' Level-Zero APIs for Images #if !defined(__GNUC__) #pragma region image #endif /////////////////////////////////////////////////////////////////////////////// /// @brief Supported image creation flags typedef uint32_t ze_image_flags_t; typedef enum _ze_image_flag_t { ZE_IMAGE_FLAG_KERNEL_WRITE = ZE_BIT(0), ///< kernels will write contents ZE_IMAGE_FLAG_BIAS_UNCACHED = ZE_BIT(1), ///< device should not cache contents ZE_IMAGE_FLAG_FORCE_UINT32 = 0x7fffffff } ze_image_flag_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Supported image types typedef enum _ze_image_type_t { ZE_IMAGE_TYPE_1D = 0, ///< 1D ZE_IMAGE_TYPE_1DARRAY = 1, ///< 1D array ZE_IMAGE_TYPE_2D = 2, ///< 2D ZE_IMAGE_TYPE_2DARRAY = 3, ///< 2D array ZE_IMAGE_TYPE_3D = 4, ///< 3D ZE_IMAGE_TYPE_BUFFER = 5, ///< Buffer ZE_IMAGE_TYPE_FORCE_UINT32 = 0x7fffffff } ze_image_type_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Supported image format layouts typedef enum _ze_image_format_layout_t { ZE_IMAGE_FORMAT_LAYOUT_8 = 0, ///< 8-bit single component layout ZE_IMAGE_FORMAT_LAYOUT_16 = 1, ///< 16-bit single component layout ZE_IMAGE_FORMAT_LAYOUT_32 = 2, ///< 32-bit single component layout ZE_IMAGE_FORMAT_LAYOUT_8_8 = 3, ///< 2-component 8-bit layout ZE_IMAGE_FORMAT_LAYOUT_8_8_8_8 = 4, ///< 4-component 8-bit layout ZE_IMAGE_FORMAT_LAYOUT_16_16 = 5, ///< 2-component 16-bit layout ZE_IMAGE_FORMAT_LAYOUT_16_16_16_16 = 6, ///< 4-component 16-bit layout ZE_IMAGE_FORMAT_LAYOUT_32_32 = 7, ///< 2-component 32-bit layout ZE_IMAGE_FORMAT_LAYOUT_32_32_32_32 = 8, ///< 4-component 32-bit layout ZE_IMAGE_FORMAT_LAYOUT_10_10_10_2 = 9, ///< 4-component 10_10_10_2 layout ZE_IMAGE_FORMAT_LAYOUT_11_11_10 = 10, ///< 3-component 11_11_10 layout ZE_IMAGE_FORMAT_LAYOUT_5_6_5 = 11, ///< 3-component 5_6_5 layout ZE_IMAGE_FORMAT_LAYOUT_5_5_5_1 = 12, ///< 4-component 5_5_5_1 layout ZE_IMAGE_FORMAT_LAYOUT_4_4_4_4 = 13, ///< 4-component 4_4_4_4 layout ZE_IMAGE_FORMAT_LAYOUT_Y8 = 14, ///< Media Format: Y8. Format type and swizzle is ignored for this. ZE_IMAGE_FORMAT_LAYOUT_NV12 = 15, ///< Media Format: NV12. Format type and swizzle is ignored for this. ZE_IMAGE_FORMAT_LAYOUT_YUYV = 16, ///< Media Format: YUYV. Format type and swizzle is ignored for this. ZE_IMAGE_FORMAT_LAYOUT_VYUY = 17, ///< Media Format: VYUY. Format type and swizzle is ignored for this. ZE_IMAGE_FORMAT_LAYOUT_YVYU = 18, ///< Media Format: YVYU. Format type and swizzle is ignored for this. ZE_IMAGE_FORMAT_LAYOUT_UYVY = 19, ///< Media Format: UYVY. Format type and swizzle is ignored for this. ZE_IMAGE_FORMAT_LAYOUT_AYUV = 20, ///< Media Format: AYUV. Format type and swizzle is ignored for this. ZE_IMAGE_FORMAT_LAYOUT_P010 = 21, ///< Media Format: P010. Format type and swizzle is ignored for this. ZE_IMAGE_FORMAT_LAYOUT_Y410 = 22, ///< Media Format: Y410. Format type and swizzle is ignored for this. ZE_IMAGE_FORMAT_LAYOUT_P012 = 23, ///< Media Format: P012. Format type and swizzle is ignored for this. ZE_IMAGE_FORMAT_LAYOUT_Y16 = 24, ///< Media Format: Y16. Format type and swizzle is ignored for this. ZE_IMAGE_FORMAT_LAYOUT_P016 = 25, ///< Media Format: P016. Format type and swizzle is ignored for this. ZE_IMAGE_FORMAT_LAYOUT_Y216 = 26, ///< Media Format: Y216. Format type and swizzle is ignored for this. ZE_IMAGE_FORMAT_LAYOUT_P216 = 27, ///< Media Format: P216. Format type and swizzle is ignored for this. ZE_IMAGE_FORMAT_LAYOUT_P8 = 28, ///< Media Format: P8. Format type and swizzle is ignored for this. ZE_IMAGE_FORMAT_LAYOUT_YUY2 = 29, ///< Media Format: YUY2. Format type and swizzle is ignored for this. ZE_IMAGE_FORMAT_LAYOUT_A8P8 = 30, ///< Media Format: A8P8. Format type and swizzle is ignored for this. ZE_IMAGE_FORMAT_LAYOUT_IA44 = 31, ///< Media Format: IA44. Format type and swizzle is ignored for this. ZE_IMAGE_FORMAT_LAYOUT_AI44 = 32, ///< Media Format: AI44. Format type and swizzle is ignored for this. ZE_IMAGE_FORMAT_LAYOUT_Y416 = 33, ///< Media Format: Y416. Format type and swizzle is ignored for this. ZE_IMAGE_FORMAT_LAYOUT_Y210 = 34, ///< Media Format: Y210. Format type and swizzle is ignored for this. ZE_IMAGE_FORMAT_LAYOUT_I420 = 35, ///< Media Format: I420. Format type and swizzle is ignored for this. ZE_IMAGE_FORMAT_LAYOUT_YV12 = 36, ///< Media Format: YV12. Format type and swizzle is ignored for this. ZE_IMAGE_FORMAT_LAYOUT_400P = 37, ///< Media Format: 400P. Format type and swizzle is ignored for this. ZE_IMAGE_FORMAT_LAYOUT_422H = 38, ///< Media Format: 422H. Format type and swizzle is ignored for this. ZE_IMAGE_FORMAT_LAYOUT_422V = 39, ///< Media Format: 422V. Format type and swizzle is ignored for this. ZE_IMAGE_FORMAT_LAYOUT_444P = 40, ///< Media Format: 444P. Format type and swizzle is ignored for this. ZE_IMAGE_FORMAT_LAYOUT_RGBP = 41, ///< Media Format: RGBP. Format type and swizzle is ignored for this. ZE_IMAGE_FORMAT_LAYOUT_BRGP = 42, ///< Media Format: BRGP. Format type and swizzle is ignored for this. ZE_IMAGE_FORMAT_LAYOUT_FORCE_UINT32 = 0x7fffffff } ze_image_format_layout_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Supported image format types typedef enum _ze_image_format_type_t { ZE_IMAGE_FORMAT_TYPE_UINT = 0, ///< Unsigned integer ZE_IMAGE_FORMAT_TYPE_SINT = 1, ///< Signed integer ZE_IMAGE_FORMAT_TYPE_UNORM = 2, ///< Unsigned normalized integer ZE_IMAGE_FORMAT_TYPE_SNORM = 3, ///< Signed normalized integer ZE_IMAGE_FORMAT_TYPE_FLOAT = 4, ///< Float ZE_IMAGE_FORMAT_TYPE_FORCE_UINT32 = 0x7fffffff } ze_image_format_type_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Supported image format component swizzle into channel typedef enum _ze_image_format_swizzle_t { ZE_IMAGE_FORMAT_SWIZZLE_R = 0, ///< Red component ZE_IMAGE_FORMAT_SWIZZLE_G = 1, ///< Green component ZE_IMAGE_FORMAT_SWIZZLE_B = 2, ///< Blue component ZE_IMAGE_FORMAT_SWIZZLE_A = 3, ///< Alpha component ZE_IMAGE_FORMAT_SWIZZLE_0 = 4, ///< Zero ZE_IMAGE_FORMAT_SWIZZLE_1 = 5, ///< One ZE_IMAGE_FORMAT_SWIZZLE_X = 6, ///< Don't care ZE_IMAGE_FORMAT_SWIZZLE_FORCE_UINT32 = 0x7fffffff } ze_image_format_swizzle_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Image format typedef struct _ze_image_format_t { ze_image_format_layout_t layout; ///< [in] image format component layout (e.g. N-component layouts and media ///< formats) ze_image_format_type_t type; ///< [in] image format type ze_image_format_swizzle_t x; ///< [in] image component swizzle into channel x ze_image_format_swizzle_t y; ///< [in] image component swizzle into channel y ze_image_format_swizzle_t z; ///< [in] image component swizzle into channel z ze_image_format_swizzle_t w; ///< [in] image component swizzle into channel w } ze_image_format_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Image descriptor typedef struct _ze_image_desc_t { ze_structure_type_t stype; ///< [in] type of this structure const void* pNext; ///< [in][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). ze_image_flags_t flags; ///< [in] creation flags. ///< must be 0 (default) or a valid combination of ::ze_image_flag_t; ///< default is read-only, cached access. ze_image_type_t type; ///< [in] image type. Media format layouts are unsupported for ///< ::ZE_IMAGE_TYPE_BUFFER ze_image_format_t format; ///< [in] image format uint64_t width; ///< [in] width dimension. ///< ::ZE_IMAGE_TYPE_BUFFER: size in bytes; see ///< ::ze_device_image_properties_t.maxImageBufferSize for limits. ///< ::ZE_IMAGE_TYPE_1D, ::ZE_IMAGE_TYPE_1DARRAY: width in pixels; see ///< ::ze_device_image_properties_t.maxImageDims1D for limits. ///< ::ZE_IMAGE_TYPE_2D, ::ZE_IMAGE_TYPE_2DARRAY: width in pixels; see ///< ::ze_device_image_properties_t.maxImageDims2D for limits. ///< ::ZE_IMAGE_TYPE_3D: width in pixels; see ///< ::ze_device_image_properties_t.maxImageDims3D for limits. uint32_t height; ///< [in] height dimension. ///< ::ZE_IMAGE_TYPE_2D, ::ZE_IMAGE_TYPE_2DARRAY: height in pixels; see ///< ::ze_device_image_properties_t.maxImageDims2D for limits. ///< ::ZE_IMAGE_TYPE_3D: height in pixels; see ///< ::ze_device_image_properties_t.maxImageDims3D for limits. ///< other: ignored. uint32_t depth; ///< [in] depth dimension. ///< ::ZE_IMAGE_TYPE_3D: depth in pixels; see ///< ::ze_device_image_properties_t.maxImageDims3D for limits. ///< other: ignored. uint32_t arraylevels; ///< [in] array levels. ///< ::ZE_IMAGE_TYPE_1DARRAY, ::ZE_IMAGE_TYPE_2DARRAY: see ///< ::ze_device_image_properties_t.maxImageArraySlices for limits. ///< other: ignored. uint32_t miplevels; ///< [in] mipmap levels (must be 0) } ze_image_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Supported sampler filtering flags typedef uint32_t ze_image_sampler_filter_flags_t; typedef enum _ze_image_sampler_filter_flag_t { ZE_IMAGE_SAMPLER_FILTER_FLAG_POINT = ZE_BIT(0), ///< device supports point filtering ZE_IMAGE_SAMPLER_FILTER_FLAG_LINEAR = ZE_BIT(1),///< device supports linear filtering ZE_IMAGE_SAMPLER_FILTER_FLAG_FORCE_UINT32 = 0x7fffffff } ze_image_sampler_filter_flag_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Image properties typedef struct _ze_image_properties_t { ze_structure_type_t stype; ///< [in] type of this structure void* pNext; ///< [in,out][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). ze_image_sampler_filter_flags_t samplerFilterFlags; ///< [out] supported sampler filtering. ///< returns 0 (unsupported) or a combination of ::ze_image_sampler_filter_flag_t. } ze_image_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Retrieves supported properties of an image. /// /// @details /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hDevice` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == desc` /// + `nullptr == pImageProperties` /// - ::ZE_RESULT_ERROR_INVALID_ENUMERATION /// + `0x3 < desc->flags` /// + `::ZE_IMAGE_TYPE_BUFFER < desc->type` ZE_APIEXPORT ze_result_t ZE_APICALL zeImageGetProperties( ze_device_handle_t hDevice, ///< [in] handle of the device const ze_image_desc_t* desc, ///< [in] pointer to image descriptor ze_image_properties_t* pImageProperties ///< [out] pointer to image properties ); /////////////////////////////////////////////////////////////////////////////// /// @brief Creates an image on the context. /// /// @details /// - The application must only use the image for the device, or its /// sub-devices, which was provided during creation. /// - The application may call this function from simultaneous threads. /// - The implementation of this function must be thread-safe. /// /// @remarks /// _Analogues_ /// - clCreateImage /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hContext` /// + `nullptr == hDevice` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == desc` /// + `nullptr == phImage` /// - ::ZE_RESULT_ERROR_INVALID_ENUMERATION /// + `0x3 < desc->flags` /// + `::ZE_IMAGE_TYPE_BUFFER < desc->type` /// - ::ZE_RESULT_ERROR_UNSUPPORTED_IMAGE_FORMAT ZE_APIEXPORT ze_result_t ZE_APICALL zeImageCreate( ze_context_handle_t hContext, ///< [in] handle of the context object ze_device_handle_t hDevice, ///< [in] handle of the device const ze_image_desc_t* desc, ///< [in] pointer to image descriptor ze_image_handle_t* phImage ///< [out] pointer to handle of image object created ); /////////////////////////////////////////////////////////////////////////////// /// @brief Deletes an image object. /// /// @details /// - The application must ensure the device is not currently referencing /// the image before it is deleted. /// - The implementation of this function may immediately free all Host and /// Device allocations associated with this image. /// - The application must **not** call this function from simultaneous /// threads with the same image handle. /// - The implementation of this function must be thread-safe. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hImage` /// - ::ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE ZE_APIEXPORT ze_result_t ZE_APICALL zeImageDestroy( ze_image_handle_t hImage ///< [in][release] handle of image object to destroy ); #if !defined(__GNUC__) #pragma endregion #endif // Intel 'oneAPI' Level-Zero APIs for Memory #if !defined(__GNUC__) #pragma region memory #endif /////////////////////////////////////////////////////////////////////////////// /// @brief Supported memory allocation flags typedef uint32_t ze_device_mem_alloc_flags_t; typedef enum _ze_device_mem_alloc_flag_t { ZE_DEVICE_MEM_ALLOC_FLAG_BIAS_CACHED = ZE_BIT(0), ///< device should cache allocation ZE_DEVICE_MEM_ALLOC_FLAG_BIAS_UNCACHED = ZE_BIT(1), ///< device should not cache allocation (UC) ZE_DEVICE_MEM_ALLOC_FLAG_BIAS_INITIAL_PLACEMENT = ZE_BIT(2),///< optimize shared allocation for first access on the device ZE_DEVICE_MEM_ALLOC_FLAG_FORCE_UINT32 = 0x7fffffff } ze_device_mem_alloc_flag_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Device memory allocation descriptor typedef struct _ze_device_mem_alloc_desc_t { ze_structure_type_t stype; ///< [in] type of this structure const void* pNext; ///< [in][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). ze_device_mem_alloc_flags_t flags; ///< [in] flags specifying additional allocation controls. ///< must be 0 (default) or a valid combination of ::ze_device_mem_alloc_flag_t; ///< default behavior may use implicit driver-based heuristics. uint32_t ordinal; ///< [in] ordinal of the device's local memory to allocate from. ///< must be less than the count returned from ::zeDeviceGetMemoryProperties. } ze_device_mem_alloc_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Supported host memory allocation flags typedef uint32_t ze_host_mem_alloc_flags_t; typedef enum _ze_host_mem_alloc_flag_t { ZE_HOST_MEM_ALLOC_FLAG_BIAS_CACHED = ZE_BIT(0), ///< host should cache allocation ZE_HOST_MEM_ALLOC_FLAG_BIAS_UNCACHED = ZE_BIT(1), ///< host should not cache allocation (UC) ZE_HOST_MEM_ALLOC_FLAG_BIAS_WRITE_COMBINED = ZE_BIT(2), ///< host memory should be allocated write-combined (WC) ZE_HOST_MEM_ALLOC_FLAG_BIAS_INITIAL_PLACEMENT = ZE_BIT(3), ///< optimize shared allocation for first access on the host ZE_HOST_MEM_ALLOC_FLAG_FORCE_UINT32 = 0x7fffffff } ze_host_mem_alloc_flag_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Host memory allocation descriptor typedef struct _ze_host_mem_alloc_desc_t { ze_structure_type_t stype; ///< [in] type of this structure const void* pNext; ///< [in][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). ze_host_mem_alloc_flags_t flags; ///< [in] flags specifying additional allocation controls. ///< must be 0 (default) or a valid combination of ::ze_host_mem_alloc_flag_t; ///< default behavior may use implicit driver-based heuristics. } ze_host_mem_alloc_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Allocates shared memory on the context. /// /// @details /// - Shared allocations share ownership between the host and one or more /// devices. /// - Shared allocations may optionally be associated with a device by /// passing a handle to the device. /// - Devices supporting only single-device shared access capabilities may /// access shared memory associated with the device. /// For these devices, ownership of the allocation is shared between the /// host and the associated device only. /// - Passing nullptr as the device handle does not associate the shared /// allocation with any device. /// For allocations with no associated device, ownership of the allocation /// is shared between the host and all devices supporting cross-device /// shared access capabilities. /// - The application must only use the memory allocation for the context /// and device, or its sub-devices, which was provided during allocation. /// - The application may call this function from simultaneous threads. /// - The implementation of this function must be thread-safe. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hContext` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == device_desc` /// + `nullptr == host_desc` /// + `nullptr == pptr` /// - ::ZE_RESULT_ERROR_INVALID_ENUMERATION /// + `0x7 < device_desc->flags` /// + `0xf < host_desc->flags` /// - ::ZE_RESULT_ERROR_UNSUPPORTED_SIZE /// + `0 == size` /// - ::ZE_RESULT_ERROR_UNSUPPORTED_ALIGNMENT /// + Must be zero or a power-of-two /// + `0 != (alignment & (alignment - 1))` ZE_APIEXPORT ze_result_t ZE_APICALL zeMemAllocShared( ze_context_handle_t hContext, ///< [in] handle of the context object const ze_device_mem_alloc_desc_t* device_desc, ///< [in] pointer to device memory allocation descriptor const ze_host_mem_alloc_desc_t* host_desc, ///< [in] pointer to host memory allocation descriptor size_t size, ///< [in] size in bytes to allocate; must be less than or equal to ///< ::ze_device_properties_t.maxMemAllocSize. size_t alignment, ///< [in] minimum alignment in bytes for the allocation; must be a power of ///< two. ze_device_handle_t hDevice, ///< [in][optional] device handle to associate with void** pptr ///< [out] pointer to shared allocation ); /////////////////////////////////////////////////////////////////////////////// /// @brief Allocates device memory on the context. /// /// @details /// - Device allocations are owned by a specific device. /// - In general, a device allocation may only be accessed by the device /// that owns it. /// - The application must only use the memory allocation for the context /// and device, or its sub-devices, which was provided during allocation. /// - The application may call this function from simultaneous threads. /// - The implementation of this function must be thread-safe. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hContext` /// + `nullptr == hDevice` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == device_desc` /// + `nullptr == pptr` /// - ::ZE_RESULT_ERROR_INVALID_ENUMERATION /// + `0x7 < device_desc->flags` /// - ::ZE_RESULT_ERROR_UNSUPPORTED_SIZE /// + `0 == size` /// - ::ZE_RESULT_ERROR_UNSUPPORTED_ALIGNMENT /// + Must be zero or a power-of-two /// + `0 != (alignment & (alignment - 1))` ZE_APIEXPORT ze_result_t ZE_APICALL zeMemAllocDevice( ze_context_handle_t hContext, ///< [in] handle of the context object const ze_device_mem_alloc_desc_t* device_desc, ///< [in] pointer to device memory allocation descriptor size_t size, ///< [in] size in bytes to allocate; must be less than or equal to ///< ::ze_device_properties_t.maxMemAllocSize. size_t alignment, ///< [in] minimum alignment in bytes for the allocation; must be a power of ///< two. ze_device_handle_t hDevice, ///< [in] handle of the device void** pptr ///< [out] pointer to device allocation ); /////////////////////////////////////////////////////////////////////////////// /// @brief Allocates host memory on the context. /// /// @details /// - Host allocations are owned by the host process. /// - Host allocations are accessible by the host and all devices within the /// driver's context. /// - Host allocations are frequently used as staging areas to transfer data /// to or from devices. /// - The application must only use the memory allocation for the context /// which was provided during allocation. /// - The application may call this function from simultaneous threads. /// - The implementation of this function must be thread-safe. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hContext` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == host_desc` /// + `nullptr == pptr` /// - ::ZE_RESULT_ERROR_INVALID_ENUMERATION /// + `0xf < host_desc->flags` /// - ::ZE_RESULT_ERROR_UNSUPPORTED_SIZE /// + `0 == size` /// - ::ZE_RESULT_ERROR_UNSUPPORTED_ALIGNMENT /// + Must be zero or a power-of-two /// + `0 != (alignment & (alignment - 1))` ZE_APIEXPORT ze_result_t ZE_APICALL zeMemAllocHost( ze_context_handle_t hContext, ///< [in] handle of the context object const ze_host_mem_alloc_desc_t* host_desc, ///< [in] pointer to host memory allocation descriptor size_t size, ///< [in] size in bytes to allocate; must be less than or equal to ///< ::ze_device_properties_t.maxMemAllocSize. size_t alignment, ///< [in] minimum alignment in bytes for the allocation; must be a power of ///< two. void** pptr ///< [out] pointer to host allocation ); /////////////////////////////////////////////////////////////////////////////// /// @brief Frees allocated host memory, device memory, or shared memory on the /// context. /// /// @details /// - The application must ensure the device is not currently referencing /// the memory before it is freed /// - The implementation of this function may immediately free all Host and /// Device allocations associated with this memory /// - The application must **not** call this function from simultaneous /// threads with the same pointer. /// - The implementation of this function must be thread-safe. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hContext` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == ptr` ZE_APIEXPORT ze_result_t ZE_APICALL zeMemFree( ze_context_handle_t hContext, ///< [in] handle of the context object void* ptr ///< [in][release] pointer to memory to free ); /////////////////////////////////////////////////////////////////////////////// /// @brief Memory allocation type typedef enum _ze_memory_type_t { ZE_MEMORY_TYPE_UNKNOWN = 0, ///< the memory pointed to is of unknown type ZE_MEMORY_TYPE_HOST = 1, ///< the memory pointed to is a host allocation ZE_MEMORY_TYPE_DEVICE = 2, ///< the memory pointed to is a device allocation ZE_MEMORY_TYPE_SHARED = 3, ///< the memory pointed to is a shared ownership allocation ZE_MEMORY_TYPE_FORCE_UINT32 = 0x7fffffff } ze_memory_type_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Memory allocation properties queried using ::zeMemGetAllocProperties typedef struct _ze_memory_allocation_properties_t { ze_structure_type_t stype; ///< [in] type of this structure void* pNext; ///< [in,out][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). ze_memory_type_t type; ///< [out] type of allocated memory uint64_t id; ///< [out] identifier for this allocation uint64_t pageSize; ///< [out] page size used for allocation } ze_memory_allocation_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Retrieves attributes of a memory allocation /// /// @details /// - The application may call this function from simultaneous threads. /// - The application may query attributes of a memory allocation unrelated /// to the context. /// When this occurs, the returned allocation type will be /// ::ZE_MEMORY_TYPE_UNKNOWN, and the returned identifier and associated /// device is unspecified. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hContext` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == ptr` /// + `nullptr == pMemAllocProperties` ZE_APIEXPORT ze_result_t ZE_APICALL zeMemGetAllocProperties( ze_context_handle_t hContext, ///< [in] handle of the context object const void* ptr, ///< [in] memory pointer to query ze_memory_allocation_properties_t* pMemAllocProperties, ///< [in,out] query result for memory allocation properties ze_device_handle_t* phDevice ///< [out][optional] device associated with this allocation ); /////////////////////////////////////////////////////////////////////////////// /// @brief Retrieves the base address and/or size of an allocation /// /// @details /// - The application may call this function from simultaneous threads. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hContext` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == ptr` ZE_APIEXPORT ze_result_t ZE_APICALL zeMemGetAddressRange( ze_context_handle_t hContext, ///< [in] handle of the context object const void* ptr, ///< [in] memory pointer to query void** pBase, ///< [in,out][optional] base address of the allocation size_t* pSize ///< [in,out][optional] size of the allocation ); /////////////////////////////////////////////////////////////////////////////// /// @brief Creates an IPC memory handle for the specified allocation /// /// @details /// - Takes a pointer to a device memory allocation and creates an IPC /// memory handle for exporting it for use in another process. /// - The pointer must be base pointer of a device or host memory /// allocation; i.e. the value returned from ::zeMemAllocDevice or from /// ::zeMemAllocHost, respectively. /// - The application may call this function from simultaneous threads. /// - The implementation of this function must be thread-safe. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hContext` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == ptr` /// + `nullptr == pIpcHandle` ZE_APIEXPORT ze_result_t ZE_APICALL zeMemGetIpcHandle( ze_context_handle_t hContext, ///< [in] handle of the context object const void* ptr, ///< [in] pointer to the device memory allocation ze_ipc_mem_handle_t* pIpcHandle ///< [out] Returned IPC memory handle ); /////////////////////////////////////////////////////////////////////////////// /// @brief Creates an IPC memory handle out of a file descriptor /// /// @details /// - Handle passed must be a valid file descriptor obtained with /// ::ze_external_memory_export_fd_t via ::zeMemGetAllocProperties. /// - Returned IPC handle may contain metadata in addition to the file /// descriptor. /// - The application may call this function from simultaneous threads. /// - The implementation of this function must be thread-safe. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hContext` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pIpcHandle` ZE_APIEXPORT ze_result_t ZE_APICALL zeMemGetIpcHandleFromFileDescriptorExp( ze_context_handle_t hContext, ///< [in] handle of the context object uint64_t handle, ///< [in] file descriptor ze_ipc_mem_handle_t* pIpcHandle ///< [out] Returned IPC memory handle ); /////////////////////////////////////////////////////////////////////////////// /// @brief Gets the file descriptor contained in an IPC memory handle /// /// @details /// - IPC memory handle must be a valid handle obtained with /// ::zeMemGetIpcHandle. /// - The application may call this function from simultaneous threads. /// - The implementation of this function must be thread-safe. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hContext` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pHandle` ZE_APIEXPORT ze_result_t ZE_APICALL zeMemGetFileDescriptorFromIpcHandleExp( ze_context_handle_t hContext, ///< [in] handle of the context object ze_ipc_mem_handle_t ipcHandle, ///< [in] IPC memory handle uint64_t* pHandle ///< [out] Returned file descriptor ); /////////////////////////////////////////////////////////////////////////////// /// @brief Returns an IPC memory handle to the driver /// /// @details /// - This call may be used for IPC handles previously obtained with either /// ::zeMemGetIpcHandle or with ::ze_external_memory_export_fd_t via ::zeMemGetAllocProperties. /// - Upon call, driver may release any underlying resources associated with /// the IPC handle. /// For instance, it may close the file descriptor contained in the IPC /// handle, if such type of handle is being used by the driver. /// - This call does not free the original allocation for which the IPC /// handle was created. /// - This function may **not** be called from simultaneous threads with the /// same IPC handle. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hContext` ZE_APIEXPORT ze_result_t ZE_APICALL zeMemPutIpcHandle( ze_context_handle_t hContext, ///< [in] handle of the context object ze_ipc_mem_handle_t handle ///< [in] IPC memory handle ); /////////////////////////////////////////////////////////////////////////////// /// @brief Supported IPC memory flags typedef uint32_t ze_ipc_memory_flags_t; typedef enum _ze_ipc_memory_flag_t { ZE_IPC_MEMORY_FLAG_BIAS_CACHED = ZE_BIT(0), ///< device should cache allocation ZE_IPC_MEMORY_FLAG_BIAS_UNCACHED = ZE_BIT(1), ///< device should not cache allocation (UC) ZE_IPC_MEMORY_FLAG_FORCE_UINT32 = 0x7fffffff } ze_ipc_memory_flag_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Opens an IPC memory handle to retrieve a device pointer on the /// context. /// /// @details /// - Takes an IPC memory handle from a remote process and associates it /// with a device pointer usable in this process. /// - The device pointer in this process should not be freed with /// ::zeMemFree, but rather with ::zeMemCloseIpcHandle. /// - Multiple calls to this function with the same IPC handle will return /// unique pointers. /// - The application may call this function from simultaneous threads. /// - The implementation of this function must be thread-safe. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hContext` /// + `nullptr == hDevice` /// - ::ZE_RESULT_ERROR_INVALID_ENUMERATION /// + `0x3 < flags` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pptr` ZE_APIEXPORT ze_result_t ZE_APICALL zeMemOpenIpcHandle( ze_context_handle_t hContext, ///< [in] handle of the context object ze_device_handle_t hDevice, ///< [in] handle of the device to associate with the IPC memory handle ze_ipc_mem_handle_t handle, ///< [in] IPC memory handle ze_ipc_memory_flags_t flags, ///< [in] flags controlling the operation. ///< must be 0 (default) or a valid combination of ::ze_ipc_memory_flag_t. void** pptr ///< [out] pointer to device allocation in this process ); /////////////////////////////////////////////////////////////////////////////// /// @brief Closes an IPC memory handle /// /// @details /// - Closes an IPC memory handle by unmapping memory that was opened in /// this process using ::zeMemOpenIpcHandle. /// - The application must **not** call this function from simultaneous /// threads with the same pointer. /// - The implementation of this function must be thread-safe. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hContext` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == ptr` ZE_APIEXPORT ze_result_t ZE_APICALL zeMemCloseIpcHandle( ze_context_handle_t hContext, ///< [in] handle of the context object const void* ptr ///< [in][release] pointer to device allocation in this process ); /////////////////////////////////////////////////////////////////////////////// /// @brief Additional allocation descriptor for exporting external memory /// /// @details /// - This structure may be passed to ::zeMemAllocDevice and /// ::zeMemAllocHost, via the `pNext` member of /// ::ze_device_mem_alloc_desc_t or ::ze_host_mem_alloc_desc_t, /// respectively, to indicate an exportable memory allocation. /// - This structure may be passed to ::zeImageCreate, via the `pNext` /// member of ::ze_image_desc_t, to indicate an exportable image. typedef struct _ze_external_memory_export_desc_t { ze_structure_type_t stype; ///< [in] type of this structure const void* pNext; ///< [in][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). ze_external_memory_type_flags_t flags; ///< [in] flags specifying memory export types for this allocation. ///< must be 0 (default) or a valid combination of ::ze_external_memory_type_flags_t } ze_external_memory_export_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Additional allocation descriptor for importing external memory as a /// file descriptor /// /// @details /// - This structure may be passed to ::zeMemAllocDevice or /// ::zeMemAllocHost, via the `pNext` member of /// ::ze_device_mem_alloc_desc_t or of ::ze_host_mem_alloc_desc_t, /// respectively, to import memory from a file descriptor. /// - This structure may be passed to ::zeImageCreate, via the `pNext` /// member of ::ze_image_desc_t, to import memory from a file descriptor. typedef struct _ze_external_memory_import_fd_t { ze_structure_type_t stype; ///< [in] type of this structure const void* pNext; ///< [in][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). ze_external_memory_type_flags_t flags; ///< [in] flags specifying the memory import type for the file descriptor. ///< must be 0 (default) or a valid combination of ::ze_external_memory_type_flags_t int fd; ///< [in] the file descriptor handle to import } ze_external_memory_import_fd_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Exports an allocation as a file descriptor /// /// @details /// - This structure may be passed to ::zeMemGetAllocProperties, via the /// `pNext` member of ::ze_memory_allocation_properties_t, to export a /// memory allocation as a file descriptor. /// - This structure may be passed to ::zeImageGetAllocPropertiesExt, via /// the `pNext` member of ::ze_image_allocation_ext_properties_t, to /// export an image as a file descriptor. /// - The requested memory export type must have been specified when the /// allocation was made. typedef struct _ze_external_memory_export_fd_t { ze_structure_type_t stype; ///< [in] type of this structure const void* pNext; ///< [in][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). ze_external_memory_type_flags_t flags; ///< [in] flags specifying the memory export type for the file descriptor. ///< must be 0 (default) or a valid combination of ::ze_external_memory_type_flags_t int fd; ///< [out] the exported file descriptor handle representing the allocation. } ze_external_memory_export_fd_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Additional allocation descriptor for importing external memory as a /// Win32 handle /// /// @details /// - When `handle` is `nullptr`, `name` must not be `nullptr`. /// - When `name` is `nullptr`, `handle` must not be `nullptr`. /// - When `flags` is ::ZE_EXTERNAL_MEMORY_TYPE_FLAG_OPAQUE_WIN32_KMT, /// `name` must be `nullptr`. /// - This structure may be passed to ::zeMemAllocDevice or /// ::zeMemAllocHost, via the `pNext` member of /// ::ze_device_mem_alloc_desc_t or of ::ze_host_mem_alloc_desc_t, /// respectively, to import memory from a Win32 handle. /// - This structure may be passed to ::zeImageCreate, via the `pNext` /// member of ::ze_image_desc_t, to import memory from a Win32 handle. typedef struct _ze_external_memory_import_win32_handle_t { ze_structure_type_t stype; ///< [in] type of this structure const void* pNext; ///< [in][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). ze_external_memory_type_flags_t flags; ///< [in] flags specifying the memory import type for the Win32 handle. ///< must be 0 (default) or a valid combination of ::ze_external_memory_type_flags_t void* handle; ///< [in][optional] the Win32 handle to import const void* name; ///< [in][optional] name of a memory object to import } ze_external_memory_import_win32_handle_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Exports an allocation as a Win32 handle /// /// @details /// - This structure may be passed to ::zeMemGetAllocProperties, via the /// `pNext` member of ::ze_memory_allocation_properties_t, to export a /// memory allocation as a Win32 handle. /// - This structure may be passed to ::zeImageGetAllocPropertiesExt, via /// the `pNext` member of ::ze_image_allocation_ext_properties_t, to /// export an image as a Win32 handle. /// - The requested memory export type must have been specified when the /// allocation was made. typedef struct _ze_external_memory_export_win32_handle_t { ze_structure_type_t stype; ///< [in] type of this structure const void* pNext; ///< [in][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). ze_external_memory_type_flags_t flags; ///< [in] flags specifying the memory export type for the Win32 handle. ///< must be 0 (default) or a valid combination of ::ze_external_memory_type_flags_t void* handle; ///< [out] the exported Win32 handle representing the allocation. } ze_external_memory_export_win32_handle_t; #if !defined(__GNUC__) #pragma endregion #endif // Intel 'oneAPI' Level-Zero APIs for Module #if !defined(__GNUC__) #pragma region module #endif /////////////////////////////////////////////////////////////////////////////// /// @brief Supported module creation input formats typedef enum _ze_module_format_t { ZE_MODULE_FORMAT_IL_SPIRV = 0, ///< Format is SPIRV IL format ZE_MODULE_FORMAT_NATIVE = 1, ///< Format is device native format ZE_MODULE_FORMAT_FORCE_UINT32 = 0x7fffffff } ze_module_format_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Specialization constants - User defined constants typedef struct _ze_module_constants_t { uint32_t numConstants; ///< [in] Number of specialization constants. const uint32_t* pConstantIds; ///< [in][range(0, numConstants)] Array of IDs that is sized to ///< numConstants. const void** pConstantValues; ///< [in][range(0, numConstants)] Array of pointers to values that is sized ///< to numConstants. } ze_module_constants_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Module descriptor typedef struct _ze_module_desc_t { ze_structure_type_t stype; ///< [in] type of this structure const void* pNext; ///< [in][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). ze_module_format_t format; ///< [in] Module format passed in with pInputModule size_t inputSize; ///< [in] size of input IL or ISA from pInputModule. const uint8_t* pInputModule; ///< [in] pointer to IL or ISA const char* pBuildFlags; ///< [in][optional] string containing one or more (comma-separated) ///< compiler flags. If unsupported, flag is ignored with a warning. ///< - "-ze-opt-disable" ///< - Disable optimizations ///< - "-ze-opt-level" ///< - Specifies optimization level for compiler. Levels are ///< implementation specific. ///< - 0 is no optimizations (equivalent to -ze-opt-disable) ///< - 1 is optimize minimally (may be the same as 2) ///< - 2 is optimize more (default) ///< - "-ze-opt-greater-than-4GB-buffer-required" ///< - Use 64-bit offset calculations for buffers. ///< - "-ze-opt-large-register-file" ///< - Increase number of registers available to threads. ///< - "-ze-opt-has-buffer-offset-arg" ///< - Extend stateless to stateful optimization to more ///< cases with the use of additional offset (e.g. 64-bit ///< pointer to binding table with 32-bit offset). ///< - "-g" ///< - Include debugging information. const ze_module_constants_t* pConstants; ///< [in][optional] pointer to specialization constants. Valid only for ///< SPIR-V input. This must be set to nullptr if no specialization ///< constants are provided. } ze_module_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Creates a module on the context. /// /// @details /// - Compiles the module for execution on the device. /// - The application must only use the module for the device, or its /// sub-devices, which was provided during creation. /// - The module can be copied to other devices and contexts within the same /// driver instance by using ::zeModuleGetNativeBinary. /// - A build log can optionally be returned to the caller. The caller is /// responsible for destroying build log using ::zeModuleBuildLogDestroy. /// - The module descriptor constants are only supported for SPIR-V /// specialization constants. /// - The application may call this function from simultaneous threads. /// - The implementation of this function must be thread-safe. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hContext` /// + `nullptr == hDevice` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == desc` /// + `nullptr == desc->pInputModule` /// + `nullptr == phModule` /// - ::ZE_RESULT_ERROR_INVALID_ENUMERATION /// + `::ZE_MODULE_FORMAT_NATIVE < desc->format` /// - ::ZE_RESULT_ERROR_INVALID_NATIVE_BINARY /// - ::ZE_RESULT_ERROR_INVALID_SIZE /// + `0 == desc->inputSize` /// - ::ZE_RESULT_ERROR_MODULE_BUILD_FAILURE ZE_APIEXPORT ze_result_t ZE_APICALL zeModuleCreate( ze_context_handle_t hContext, ///< [in] handle of the context object ze_device_handle_t hDevice, ///< [in] handle of the device const ze_module_desc_t* desc, ///< [in] pointer to module descriptor ze_module_handle_t* phModule, ///< [out] pointer to handle of module object created ze_module_build_log_handle_t* phBuildLog ///< [out][optional] pointer to handle of module's build log. ); /////////////////////////////////////////////////////////////////////////////// /// @brief Destroys module /// /// @details /// - The application must destroy all kernel and build log handles created /// from the module before destroying the module itself. /// - The application must ensure the device is not currently referencing /// the module before it is deleted. /// - The implementation of this function may immediately free all Host and /// Device allocations associated with this module. /// - The application must **not** call this function from simultaneous /// threads with the same module handle. /// - The implementation of this function must be thread-safe. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hModule` /// - ::ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE ZE_APIEXPORT ze_result_t ZE_APICALL zeModuleDestroy( ze_module_handle_t hModule ///< [in][release] handle of the module ); /////////////////////////////////////////////////////////////////////////////// /// @brief Dynamically link modules together that share import/export linkage /// dependencies. /// /// @details /// - Modules support SPIR-V import and export linkage types for functions /// and global variables. See the SPIR-V specification for linkage /// details. /// - Modules can have both import and export linkage. /// - Modules that do not have any imports or exports do not need to be /// linked. /// - All module import requirements must be satisfied via linking before /// kernel objects can be created from them. /// - Modules cannot be partially linked. Unsatisfiable import dependencies /// in the set of modules passed to ::zeModuleDynamicLink will result in /// ::ZE_RESULT_ERROR_MODULE_LINK_FAILURE being returned. /// - Modules will only be linked once. A module can be used in multiple /// link calls if it has exports but its imports will not be re-linked. /// - Ambiguous dependencies, where multiple modules satisfy the same import /// dependencies for a module, are not allowed. /// - The application must ensure the modules being linked were created on /// the same context. /// - The application may call this function from simultaneous threads as /// long as the import modules being linked are not the same. /// - ModuleGetNativeBinary can be called on any module regardless of /// whether it is linked or not. /// - A link log can optionally be returned to the caller. The caller is /// responsible for destroying the link log using /// ::zeModuleBuildLogDestroy. /// - The link log may contain a list of the unresolved import dependencies /// if present. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == phModules` /// - ::ZE_RESULT_ERROR_MODULE_LINK_FAILURE ZE_APIEXPORT ze_result_t ZE_APICALL zeModuleDynamicLink( uint32_t numModules, ///< [in] number of modules to be linked pointed to by phModules. ze_module_handle_t* phModules, ///< [in][range(0, numModules)] pointer to an array of modules to ///< dynamically link together. ze_module_build_log_handle_t* phLinkLog ///< [out][optional] pointer to handle of dynamic link log. ); /////////////////////////////////////////////////////////////////////////////// /// @brief Destroys module build log object /// /// @details /// - The implementation of this function may immediately free all Host /// allocations associated with this object. /// - The application must **not** call this function from simultaneous /// threads with the same build log handle. /// - The implementation of this function should be lock-free. /// - This function can be called before or after ::zeModuleDestroy for the /// associated module. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hModuleBuildLog` /// - ::ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE ZE_APIEXPORT ze_result_t ZE_APICALL zeModuleBuildLogDestroy( ze_module_build_log_handle_t hModuleBuildLog ///< [in][release] handle of the module build log object. ); /////////////////////////////////////////////////////////////////////////////// /// @brief Retrieves text string for build log. /// /// @details /// - The caller can pass nullptr for pBuildLog when querying only for size. /// - The caller must provide memory for build log. /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hModuleBuildLog` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pSize` ZE_APIEXPORT ze_result_t ZE_APICALL zeModuleBuildLogGetString( ze_module_build_log_handle_t hModuleBuildLog, ///< [in] handle of the module build log object. size_t* pSize, ///< [in,out] size of build log string. char* pBuildLog ///< [in,out][optional] pointer to null-terminated string of the log. ); /////////////////////////////////////////////////////////////////////////////// /// @brief Retrieve native binary from Module. /// /// @details /// - The native binary output can be cached to disk and new modules can be /// later constructed from the cached copy. /// - The native binary will retain debugging information that is associated /// with a module. /// - The caller can pass nullptr for pModuleNativeBinary when querying only /// for size. /// - The implementation will copy the native binary into a buffer supplied /// by the caller. /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hModule` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pSize` ZE_APIEXPORT ze_result_t ZE_APICALL zeModuleGetNativeBinary( ze_module_handle_t hModule, ///< [in] handle of the module size_t* pSize, ///< [in,out] size of native binary in bytes. uint8_t* pModuleNativeBinary ///< [in,out][optional] byte pointer to native binary ); /////////////////////////////////////////////////////////////////////////////// /// @brief Retrieve global variable pointer from Module. /// /// @details /// - The application may query global pointer from any module that either /// exports or imports it. /// - The application must dynamically link a module that imports a global /// before the global pointer can be queried from it. /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hModule` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pGlobalName` /// - ::ZE_RESULT_ERROR_INVALID_GLOBAL_NAME ZE_APIEXPORT ze_result_t ZE_APICALL zeModuleGetGlobalPointer( ze_module_handle_t hModule, ///< [in] handle of the module const char* pGlobalName, ///< [in] name of global variable in module size_t* pSize, ///< [in,out][optional] size of global variable void** pptr ///< [in,out][optional] device visible pointer ); /////////////////////////////////////////////////////////////////////////////// /// @brief Retrieve all kernel names in the module. /// /// @details /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hModule` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pCount` ZE_APIEXPORT ze_result_t ZE_APICALL zeModuleGetKernelNames( ze_module_handle_t hModule, ///< [in] handle of the module uint32_t* pCount, ///< [in,out] pointer to the number of names. ///< if count is zero, then the driver shall update the value with the ///< total number of names available. ///< if count is greater than the number of names available, then the ///< driver shall update the value with the correct number of names available. const char** pNames ///< [in,out][optional][range(0, *pCount)] array of names of functions. ///< if count is less than the number of names available, then driver shall ///< only retrieve that number of names. ); /////////////////////////////////////////////////////////////////////////////// /// @brief Supported module property flags typedef uint32_t ze_module_property_flags_t; typedef enum _ze_module_property_flag_t { ZE_MODULE_PROPERTY_FLAG_IMPORTS = ZE_BIT(0), ///< Module has imports (i.e. imported global variables and/or kernels). ///< See ::zeModuleDynamicLink. ZE_MODULE_PROPERTY_FLAG_FORCE_UINT32 = 0x7fffffff } ze_module_property_flag_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Module properties typedef struct _ze_module_properties_t { ze_structure_type_t stype; ///< [in] type of this structure void* pNext; ///< [in,out][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). ze_module_property_flags_t flags; ///< [out] 0 (none) or a valid combination of ::ze_module_property_flag_t } ze_module_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Retrieve module properties. /// /// @details /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hModule` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pModuleProperties` ZE_APIEXPORT ze_result_t ZE_APICALL zeModuleGetProperties( ze_module_handle_t hModule, ///< [in] handle of the module ze_module_properties_t* pModuleProperties ///< [in,out] query result for module properties. ); /////////////////////////////////////////////////////////////////////////////// /// @brief Supported kernel creation flags typedef uint32_t ze_kernel_flags_t; typedef enum _ze_kernel_flag_t { ZE_KERNEL_FLAG_FORCE_RESIDENCY = ZE_BIT(0), ///< force all device allocations to be resident during execution ZE_KERNEL_FLAG_EXPLICIT_RESIDENCY = ZE_BIT(1), ///< application is responsible for all residency of device allocations. ///< driver may disable implicit residency management. ZE_KERNEL_FLAG_FORCE_UINT32 = 0x7fffffff } ze_kernel_flag_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Kernel descriptor typedef struct _ze_kernel_desc_t { ze_structure_type_t stype; ///< [in] type of this structure const void* pNext; ///< [in][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). ze_kernel_flags_t flags; ///< [in] creation flags. ///< must be 0 (default) or a valid combination of ::ze_kernel_flag_t; ///< default behavior may use driver-based residency. const char* pKernelName; ///< [in] null-terminated name of kernel in module } ze_kernel_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Create a kernel from the module. /// /// @details /// - Modules that have unresolved imports need to be dynamically linked /// before a kernel can be created from them. (See ::zeModuleDynamicLink) /// - The application may call this function from simultaneous threads. /// - The implementation of this function must be thread-safe. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hModule` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == desc` /// + `nullptr == desc->pKernelName` /// + `nullptr == phKernel` /// - ::ZE_RESULT_ERROR_INVALID_ENUMERATION /// + `0x3 < desc->flags` /// - ::ZE_RESULT_ERROR_INVALID_KERNEL_NAME /// - ::ZE_RESULT_ERROR_INVALID_MODULE_UNLINKED ZE_APIEXPORT ze_result_t ZE_APICALL zeKernelCreate( ze_module_handle_t hModule, ///< [in] handle of the module const ze_kernel_desc_t* desc, ///< [in] pointer to kernel descriptor ze_kernel_handle_t* phKernel ///< [out] handle of the Function object ); /////////////////////////////////////////////////////////////////////////////// /// @brief Destroys a kernel object /// /// @details /// - The application must ensure the device is not currently referencing /// the kernel before it is deleted. /// - The implementation of this function may immediately free all Host and /// Device allocations associated with this kernel. /// - The application must **not** call this function from simultaneous /// threads with the same kernel handle. /// - The implementation of this function must be thread-safe. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hKernel` /// - ::ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE ZE_APIEXPORT ze_result_t ZE_APICALL zeKernelDestroy( ze_kernel_handle_t hKernel ///< [in][release] handle of the kernel object ); /////////////////////////////////////////////////////////////////////////////// /// @brief Retrieve a function pointer from a module by name /// /// @details /// - The function pointer is unique for the device on which the module was /// created. /// - The function pointer is no longer valid if module is destroyed. /// - The function name should only refer to callable functions within the /// module. /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hModule` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pFunctionName` /// + `nullptr == pfnFunction` /// - ::ZE_RESULT_ERROR_INVALID_FUNCTION_NAME ZE_APIEXPORT ze_result_t ZE_APICALL zeModuleGetFunctionPointer( ze_module_handle_t hModule, ///< [in] handle of the module const char* pFunctionName, ///< [in] Name of function to retrieve function pointer for. void** pfnFunction ///< [out] pointer to function. ); /////////////////////////////////////////////////////////////////////////////// /// @brief Set group size for a kernel. /// /// @details /// - The group size will be used when a ::zeCommandListAppendLaunchKernel /// variant is called. /// - The application must **not** call this function from simultaneous /// threads with the same kernel handle. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hKernel` /// - ::ZE_RESULT_ERROR_INVALID_GROUP_SIZE_DIMENSION ZE_APIEXPORT ze_result_t ZE_APICALL zeKernelSetGroupSize( ze_kernel_handle_t hKernel, ///< [in] handle of the kernel object uint32_t groupSizeX, ///< [in] group size for X dimension to use for this kernel uint32_t groupSizeY, ///< [in] group size for Y dimension to use for this kernel uint32_t groupSizeZ ///< [in] group size for Z dimension to use for this kernel ); /////////////////////////////////////////////////////////////////////////////// /// @brief Query a suggested group size for a kernel given a global size for each /// dimension. /// /// @details /// - This function ignores the group size that is set using /// ::zeKernelSetGroupSize. /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hKernel` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == groupSizeX` /// + `nullptr == groupSizeY` /// + `nullptr == groupSizeZ` /// - ::ZE_RESULT_ERROR_INVALID_GLOBAL_WIDTH_DIMENSION ZE_APIEXPORT ze_result_t ZE_APICALL zeKernelSuggestGroupSize( ze_kernel_handle_t hKernel, ///< [in] handle of the kernel object uint32_t globalSizeX, ///< [in] global width for X dimension uint32_t globalSizeY, ///< [in] global width for Y dimension uint32_t globalSizeZ, ///< [in] global width for Z dimension uint32_t* groupSizeX, ///< [out] recommended size of group for X dimension uint32_t* groupSizeY, ///< [out] recommended size of group for Y dimension uint32_t* groupSizeZ ///< [out] recommended size of group for Z dimension ); /////////////////////////////////////////////////////////////////////////////// /// @brief Query a suggested max group count for a cooperative kernel. /// /// @details /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hKernel` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == totalGroupCount` ZE_APIEXPORT ze_result_t ZE_APICALL zeKernelSuggestMaxCooperativeGroupCount( ze_kernel_handle_t hKernel, ///< [in] handle of the kernel object uint32_t* totalGroupCount ///< [out] recommended total group count. ); /////////////////////////////////////////////////////////////////////////////// /// @brief Set kernel argument for a kernel. /// /// @details /// - The argument values will be used when a /// ::zeCommandListAppendLaunchKernel variant is called. /// - The application must **not** call this function from simultaneous /// threads with the same kernel handle. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hKernel` /// - ::ZE_RESULT_ERROR_INVALID_KERNEL_ARGUMENT_INDEX /// - ::ZE_RESULT_ERROR_INVALID_KERNEL_ARGUMENT_SIZE ZE_APIEXPORT ze_result_t ZE_APICALL zeKernelSetArgumentValue( ze_kernel_handle_t hKernel, ///< [in] handle of the kernel object uint32_t argIndex, ///< [in] argument index in range [0, num args - 1] size_t argSize, ///< [in] size of argument type const void* pArgValue ///< [in][optional] argument value represented as matching arg type. If ///< null then argument value is considered null. ); /////////////////////////////////////////////////////////////////////////////// /// @brief Kernel indirect access flags typedef uint32_t ze_kernel_indirect_access_flags_t; typedef enum _ze_kernel_indirect_access_flag_t { ZE_KERNEL_INDIRECT_ACCESS_FLAG_HOST = ZE_BIT(0),///< Indicates that the kernel accesses host allocations indirectly. ZE_KERNEL_INDIRECT_ACCESS_FLAG_DEVICE = ZE_BIT(1), ///< Indicates that the kernel accesses device allocations indirectly. ZE_KERNEL_INDIRECT_ACCESS_FLAG_SHARED = ZE_BIT(2), ///< Indicates that the kernel accesses shared allocations indirectly. ZE_KERNEL_INDIRECT_ACCESS_FLAG_FORCE_UINT32 = 0x7fffffff } ze_kernel_indirect_access_flag_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Sets kernel indirect access flags. /// /// @details /// - The application should specify which allocations will be indirectly /// accessed by the kernel to allow driver to optimize which allocations /// are made resident /// - This function may **not** be called from simultaneous threads with the /// same Kernel handle. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hKernel` /// - ::ZE_RESULT_ERROR_INVALID_ENUMERATION /// + `0x7 < flags` ZE_APIEXPORT ze_result_t ZE_APICALL zeKernelSetIndirectAccess( ze_kernel_handle_t hKernel, ///< [in] handle of the kernel object ze_kernel_indirect_access_flags_t flags ///< [in] kernel indirect access flags ); /////////////////////////////////////////////////////////////////////////////// /// @brief Retrieve kernel indirect access flags. /// /// @details /// - This function may be called from simultaneous threads with the same /// Kernel handle. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hKernel` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pFlags` ZE_APIEXPORT ze_result_t ZE_APICALL zeKernelGetIndirectAccess( ze_kernel_handle_t hKernel, ///< [in] handle of the kernel object ze_kernel_indirect_access_flags_t* pFlags ///< [out] query result for kernel indirect access flags. ); /////////////////////////////////////////////////////////////////////////////// /// @brief Retrieve all declared kernel attributes (i.e. can be specified with /// __attribute__ in runtime language). /// /// @details /// - This function may be called from simultaneous threads with the same /// Kernel handle. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hKernel` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pSize` ZE_APIEXPORT ze_result_t ZE_APICALL zeKernelGetSourceAttributes( ze_kernel_handle_t hKernel, ///< [in] handle of the kernel object uint32_t* pSize, ///< [in,out] pointer to size of string in bytes, including ///< null-terminating character. char** pString ///< [in,out][optional] pointer to application-managed character array ///< (string data). ///< If NULL, the string length of the kernel source attributes, including ///< a null-terminating character, is returned in pSize. ///< Otherwise, pString must point to valid application memory that is ///< greater than or equal to *pSize bytes in length, and on return the ///< pointed-to string will contain a space-separated list of kernel source attributes. ); /////////////////////////////////////////////////////////////////////////////// /// @brief Supported Cache Config flags typedef uint32_t ze_cache_config_flags_t; typedef enum _ze_cache_config_flag_t { ZE_CACHE_CONFIG_FLAG_LARGE_SLM = ZE_BIT(0), ///< Large SLM size ZE_CACHE_CONFIG_FLAG_LARGE_DATA = ZE_BIT(1), ///< Large General Data size ZE_CACHE_CONFIG_FLAG_FORCE_UINT32 = 0x7fffffff } ze_cache_config_flag_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Sets the preferred cache configuration. /// /// @details /// - The cache configuration will be used when a /// ::zeCommandListAppendLaunchKernel variant is called. /// - The application must **not** call this function from simultaneous /// threads with the same kernel handle. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hKernel` /// - ::ZE_RESULT_ERROR_INVALID_ENUMERATION /// + `0x3 < flags` /// - ::ZE_RESULT_ERROR_UNSUPPORTED_FEATURE ZE_APIEXPORT ze_result_t ZE_APICALL zeKernelSetCacheConfig( ze_kernel_handle_t hKernel, ///< [in] handle of the kernel object ze_cache_config_flags_t flags ///< [in] cache configuration. ///< must be 0 (default configuration) or a valid combination of ::ze_cache_config_flag_t. ); /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_MAX_KERNEL_UUID_SIZE /// @brief Maximum kernel universal unique id (UUID) size in bytes #define ZE_MAX_KERNEL_UUID_SIZE 16 #endif // ZE_MAX_KERNEL_UUID_SIZE /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_MAX_MODULE_UUID_SIZE /// @brief Maximum module universal unique id (UUID) size in bytes #define ZE_MAX_MODULE_UUID_SIZE 16 #endif // ZE_MAX_MODULE_UUID_SIZE /////////////////////////////////////////////////////////////////////////////// /// @brief Kernel universal unique id (UUID) typedef struct _ze_kernel_uuid_t { uint8_t kid[ZE_MAX_KERNEL_UUID_SIZE]; ///< [out] opaque data representing a kernel UUID uint8_t mid[ZE_MAX_MODULE_UUID_SIZE]; ///< [out] opaque data representing the kernel's module UUID } ze_kernel_uuid_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Kernel properties typedef struct _ze_kernel_properties_t { ze_structure_type_t stype; ///< [in] type of this structure void* pNext; ///< [in,out][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). uint32_t numKernelArgs; ///< [out] number of kernel arguments. uint32_t requiredGroupSizeX; ///< [out] required group size in the X dimension, ///< or zero if there is no required group size uint32_t requiredGroupSizeY; ///< [out] required group size in the Y dimension, ///< or zero if there is no required group size uint32_t requiredGroupSizeZ; ///< [out] required group size in the Z dimension, ///< or zero if there is no required group size uint32_t requiredNumSubGroups; ///< [out] required number of subgroups per thread group, ///< or zero if there is no required number of subgroups uint32_t requiredSubgroupSize; ///< [out] required subgroup size, ///< or zero if there is no required subgroup size uint32_t maxSubgroupSize; ///< [out] maximum subgroup size uint32_t maxNumSubgroups; ///< [out] maximum number of subgroups per thread group uint32_t localMemSize; ///< [out] local memory size used by each thread group uint32_t privateMemSize; ///< [out] private memory size allocated by compiler used by each thread uint32_t spillMemSize; ///< [out] spill memory size allocated by compiler ze_kernel_uuid_t uuid; ///< [out] universal unique identifier. } ze_kernel_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Additional kernel preferred group size properties /// /// @details /// - This structure may be passed to ::zeKernelGetProperties, via the /// `pNext` member of ::ze_kernel_properties_t, to query additional kernel /// preferred group size properties. typedef struct _ze_kernel_preferred_group_size_properties_t { ze_structure_type_t stype; ///< [in] type of this structure void* pNext; ///< [in,out][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). uint32_t preferredMultiple; ///< [out] preferred group size multiple } ze_kernel_preferred_group_size_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Retrieve kernel properties. /// /// @details /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hKernel` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pKernelProperties` ZE_APIEXPORT ze_result_t ZE_APICALL zeKernelGetProperties( ze_kernel_handle_t hKernel, ///< [in] handle of the kernel object ze_kernel_properties_t* pKernelProperties ///< [in,out] query result for kernel properties. ); /////////////////////////////////////////////////////////////////////////////// /// @brief Retrieve kernel name from Kernel. /// /// @details /// - The caller can pass nullptr for pName when querying only for size. /// - The implementation will copy the kernel name into a buffer supplied by /// the caller. /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hKernel` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pSize` ZE_APIEXPORT ze_result_t ZE_APICALL zeKernelGetName( ze_kernel_handle_t hKernel, ///< [in] handle of the kernel object size_t* pSize, ///< [in,out] size of kernel name string, including null terminator, in ///< bytes. char* pName ///< [in,out][optional] char pointer to kernel name. ); /////////////////////////////////////////////////////////////////////////////// /// @brief Kernel dispatch group count. typedef struct _ze_group_count_t { uint32_t groupCountX; ///< [in] number of thread groups in X dimension uint32_t groupCountY; ///< [in] number of thread groups in Y dimension uint32_t groupCountZ; ///< [in] number of thread groups in Z dimension } ze_group_count_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Launch kernel over one or more work groups. /// /// @details /// - The application must ensure the kernel and events are accessible by /// the device on which the command list was created. /// - This may **only** be called for a command list created with command /// queue group ordinal that supports compute. /// - The application must ensure the command list, kernel and events were /// created on the same context. /// - This function may **not** be called from simultaneous threads with the /// same command list handle. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hCommandList` /// + `nullptr == hKernel` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pLaunchFuncArgs` /// - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT /// - ::ZE_RESULT_ERROR_INVALID_SIZE /// + `(nullptr == phWaitEvents) && (0 < numWaitEvents)` ZE_APIEXPORT ze_result_t ZE_APICALL zeCommandListAppendLaunchKernel( ze_command_list_handle_t hCommandList, ///< [in] handle of the command list ze_kernel_handle_t hKernel, ///< [in] handle of the kernel object const ze_group_count_t* pLaunchFuncArgs, ///< [in] thread group launch arguments ze_event_handle_t hSignalEvent, ///< [in][optional] handle of the event to signal on completion uint32_t numWaitEvents, ///< [in][optional] number of events to wait on before launching; must be 0 ///< if `nullptr == phWaitEvents` ze_event_handle_t* phWaitEvents ///< [in][optional][range(0, numWaitEvents)] handle of the events to wait ///< on before launching ); /////////////////////////////////////////////////////////////////////////////// /// @brief Launch kernel cooperatively over one or more work groups. /// /// @details /// - The application must ensure the kernel and events are accessible by /// the device on which the command list was created. /// - This may **only** be called for a command list created with command /// queue group ordinal that supports compute. /// - This may only be used for a command list that are submitted to command /// queue with cooperative flag set. /// - The application must ensure the command list, kernel and events were /// created on the same context. /// - This function may **not** be called from simultaneous threads with the /// same command list handle. /// - The implementation of this function should be lock-free. /// - Use ::zeKernelSuggestMaxCooperativeGroupCount to recommend max group /// count for device for cooperative functions that device supports. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hCommandList` /// + `nullptr == hKernel` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pLaunchFuncArgs` /// - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT /// - ::ZE_RESULT_ERROR_INVALID_SIZE /// + `(nullptr == phWaitEvents) && (0 < numWaitEvents)` ZE_APIEXPORT ze_result_t ZE_APICALL zeCommandListAppendLaunchCooperativeKernel( ze_command_list_handle_t hCommandList, ///< [in] handle of the command list ze_kernel_handle_t hKernel, ///< [in] handle of the kernel object const ze_group_count_t* pLaunchFuncArgs, ///< [in] thread group launch arguments ze_event_handle_t hSignalEvent, ///< [in][optional] handle of the event to signal on completion uint32_t numWaitEvents, ///< [in][optional] number of events to wait on before launching; must be 0 ///< if `nullptr == phWaitEvents` ze_event_handle_t* phWaitEvents ///< [in][optional][range(0, numWaitEvents)] handle of the events to wait ///< on before launching ); /////////////////////////////////////////////////////////////////////////////// /// @brief Launch kernel over one or more work groups using indirect arguments. /// /// @details /// - The application must ensure the kernel and events are accessible by /// the device on which the command list was created. /// - The application must ensure the launch arguments are visible to the /// device on which the command list was created. /// - The implementation must not access the contents of the launch /// arguments as they are free to be modified by either the Host or device /// up until execution. /// - This may **only** be called for a command list created with command /// queue group ordinal that supports compute. /// - The application must ensure the command list, kernel and events were /// created, and the memory was allocated, on the same context. /// - This function may **not** be called from simultaneous threads with the /// same command list handle. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hCommandList` /// + `nullptr == hKernel` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pLaunchArgumentsBuffer` /// - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT /// - ::ZE_RESULT_ERROR_INVALID_SIZE /// + `(nullptr == phWaitEvents) && (0 < numWaitEvents)` ZE_APIEXPORT ze_result_t ZE_APICALL zeCommandListAppendLaunchKernelIndirect( ze_command_list_handle_t hCommandList, ///< [in] handle of the command list ze_kernel_handle_t hKernel, ///< [in] handle of the kernel object const ze_group_count_t* pLaunchArgumentsBuffer, ///< [in] pointer to device buffer that will contain thread group launch ///< arguments ze_event_handle_t hSignalEvent, ///< [in][optional] handle of the event to signal on completion uint32_t numWaitEvents, ///< [in][optional] number of events to wait on before launching; must be 0 ///< if `nullptr == phWaitEvents` ze_event_handle_t* phWaitEvents ///< [in][optional][range(0, numWaitEvents)] handle of the events to wait ///< on before launching ); /////////////////////////////////////////////////////////////////////////////// /// @brief Launch multiple kernels over one or more work groups using an array of /// indirect arguments. /// /// @details /// - The application must ensure the kernel and events are accessible by /// the device on which the command list was created. /// - The application must ensure the array of launch arguments and count /// buffer are visible to the device on which the command list was /// created. /// - The implementation must not access the contents of the array of launch /// arguments or count buffer as they are free to be modified by either /// the Host or device up until execution. /// - This may **only** be called for a command list created with command /// queue group ordinal that supports compute. /// - The application must enusre the command list, kernel and events were /// created, and the memory was allocated, on the same context. /// - This function may **not** be called from simultaneous threads with the /// same command list handle. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hCommandList` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == phKernels` /// + `nullptr == pCountBuffer` /// + `nullptr == pLaunchArgumentsBuffer` /// - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT /// - ::ZE_RESULT_ERROR_INVALID_SIZE /// + `(nullptr == phWaitEvents) && (0 < numWaitEvents)` ZE_APIEXPORT ze_result_t ZE_APICALL zeCommandListAppendLaunchMultipleKernelsIndirect( ze_command_list_handle_t hCommandList, ///< [in] handle of the command list uint32_t numKernels, ///< [in] maximum number of kernels to launch ze_kernel_handle_t* phKernels, ///< [in][range(0, numKernels)] handles of the kernel objects const uint32_t* pCountBuffer, ///< [in] pointer to device memory location that will contain the actual ///< number of kernels to launch; value must be less than or equal to ///< numKernels const ze_group_count_t* pLaunchArgumentsBuffer, ///< [in][range(0, numKernels)] pointer to device buffer that will contain ///< a contiguous array of thread group launch arguments ze_event_handle_t hSignalEvent, ///< [in][optional] handle of the event to signal on completion uint32_t numWaitEvents, ///< [in][optional] number of events to wait on before launching; must be 0 ///< if `nullptr == phWaitEvents` ze_event_handle_t* phWaitEvents ///< [in][optional][range(0, numWaitEvents)] handle of the events to wait ///< on before launching ); #if !defined(__GNUC__) #pragma endregion #endif // Intel 'oneAPI' Level-Zero Extension for supporting module programs. #if !defined(__GNUC__) #pragma region program #endif /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_MODULE_PROGRAM_EXP_NAME /// @brief Module Program Extension Name #define ZE_MODULE_PROGRAM_EXP_NAME "ZE_experimental_module_program" #endif // ZE_MODULE_PROGRAM_EXP_NAME /////////////////////////////////////////////////////////////////////////////// /// @brief Module Program Extension Version(s) typedef enum _ze_module_program_exp_version_t { ZE_MODULE_PROGRAM_EXP_VERSION_1_0 = ZE_MAKE_VERSION( 1, 0 ),///< version 1.0 ZE_MODULE_PROGRAM_EXP_VERSION_CURRENT = ZE_MAKE_VERSION( 1, 0 ),///< latest known version ZE_MODULE_PROGRAM_EXP_VERSION_FORCE_UINT32 = 0x7fffffff } ze_module_program_exp_version_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Module extended descriptor to support multiple input modules. /// /// @details /// - Implementation must support ::ZE_experimental_module_program extension /// - Modules support import and export linkage for functions and global /// variables. /// - SPIR-V import and export linkage types are used. See SPIR-V /// specification for linkage details. /// - pInputModules, pBuildFlags, and pConstants from ::ze_module_desc_t is /// ignored. /// - Format in ::ze_module_desc_t needs to be set to /// ::ZE_MODULE_FORMAT_IL_SPIRV. typedef struct _ze_module_program_exp_desc_t { ze_structure_type_t stype; ///< [in] type of this structure const void* pNext; ///< [in][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). uint32_t count; ///< [in] Count of input modules const size_t* inputSizes; ///< [in][range(0, count)] sizes of each input IL module in pInputModules. const uint8_t** pInputModules; ///< [in][range(0, count)] pointer to an array of IL (e.g. SPIR-V modules). ///< Valid only for SPIR-V input. const char** pBuildFlags; ///< [in][optional][range(0, count)] array of strings containing build ///< flags. See pBuildFlags in ::ze_module_desc_t. const ze_module_constants_t** pConstants; ///< [in][optional][range(0, count)] pointer to array of specialization ///< constant strings. Valid only for SPIR-V input. This must be set to ///< nullptr if no specialization constants are provided. } ze_module_program_exp_desc_t; #if !defined(__GNUC__) #pragma endregion #endif // Intel 'oneAPI' Level-Zero Extension APIs for Raytracing #if !defined(__GNUC__) #pragma region raytracing #endif /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_RAYTRACING_EXT_NAME /// @brief Raytracing Extension Name #define ZE_RAYTRACING_EXT_NAME "ZE_extension_raytracing" #endif // ZE_RAYTRACING_EXT_NAME /////////////////////////////////////////////////////////////////////////////// /// @brief Raytracing Extension Version(s) typedef enum _ze_raytracing_ext_version_t { ZE_RAYTRACING_EXT_VERSION_1_0 = ZE_MAKE_VERSION( 1, 0 ),///< version 1.0 ZE_RAYTRACING_EXT_VERSION_CURRENT = ZE_MAKE_VERSION( 1, 0 ),///< latest known version ZE_RAYTRACING_EXT_VERSION_FORCE_UINT32 = 0x7fffffff } ze_raytracing_ext_version_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Supported raytracing capability flags typedef uint32_t ze_device_raytracing_ext_flags_t; typedef enum _ze_device_raytracing_ext_flag_t { ZE_DEVICE_RAYTRACING_EXT_FLAG_RAYQUERY = ZE_BIT(0), ///< Supports rayquery ZE_DEVICE_RAYTRACING_EXT_FLAG_FORCE_UINT32 = 0x7fffffff } ze_device_raytracing_ext_flag_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Raytracing properties queried using ::zeDeviceGetModuleProperties /// /// @details /// - This structure may be returned from ::zeDeviceGetModuleProperties, via /// `pNext` member of ::ze_device_module_properties_t. typedef struct _ze_device_raytracing_ext_properties_t { ze_structure_type_t stype; ///< [in] type of this structure void* pNext; ///< [in,out][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). ze_device_raytracing_ext_flags_t flags; ///< [out] 0 or a valid combination of ::ze_device_raytracing_ext_flags_t uint32_t maxBVHLevels; ///< [out] Maximum number of BVH levels supported } ze_device_raytracing_ext_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Supported raytracing memory allocation flags typedef uint32_t ze_raytracing_mem_alloc_ext_flags_t; typedef enum _ze_raytracing_mem_alloc_ext_flag_t { ZE_RAYTRACING_MEM_ALLOC_EXT_FLAG_TBD = ZE_BIT(0), ///< reserved for future use ZE_RAYTRACING_MEM_ALLOC_EXT_FLAG_FORCE_UINT32 = 0x7fffffff } ze_raytracing_mem_alloc_ext_flag_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Raytracing memory allocation descriptor /// /// @details /// - This structure must be passed to ::zeMemAllocShared or /// ::zeMemAllocDevice, via `pNext` member of /// ::ze_device_mem_alloc_desc_t, for any memory allocation that is to be /// accessed by raytracing fixed-function of the device. typedef struct _ze_raytracing_mem_alloc_ext_desc_t { ze_structure_type_t stype; ///< [in] type of this structure const void* pNext; ///< [in][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). ze_raytracing_mem_alloc_ext_flags_t flags; ///< [in] flags specifying additional allocation controls. ///< must be 0 (default) or a valid combination of ::ze_raytracing_mem_alloc_ext_flag_t; ///< default behavior may use implicit driver-based heuristics. } ze_raytracing_mem_alloc_ext_desc_t; #if !defined(__GNUC__) #pragma endregion #endif // Intel 'oneAPI' Level-Zero APIs for Memory Residency #if !defined(__GNUC__) #pragma region residency #endif /////////////////////////////////////////////////////////////////////////////// /// @brief Makes memory resident for the device. /// /// @details /// - The application must ensure the memory is resident before being /// referenced by the device /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hContext` /// + `nullptr == hDevice` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == ptr` ZE_APIEXPORT ze_result_t ZE_APICALL zeContextMakeMemoryResident( ze_context_handle_t hContext, ///< [in] handle of context object ze_device_handle_t hDevice, ///< [in] handle of the device void* ptr, ///< [in] pointer to memory to make resident size_t size ///< [in] size in bytes to make resident ); /////////////////////////////////////////////////////////////////////////////// /// @brief Allows memory to be evicted from the device. /// /// @details /// - The application must ensure the device is not currently referencing /// the memory before it is evicted /// - The application may free the memory without evicting; the memory is /// implicitly evicted when freed. /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hContext` /// + `nullptr == hDevice` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == ptr` ZE_APIEXPORT ze_result_t ZE_APICALL zeContextEvictMemory( ze_context_handle_t hContext, ///< [in] handle of context object ze_device_handle_t hDevice, ///< [in] handle of the device void* ptr, ///< [in] pointer to memory to evict size_t size ///< [in] size in bytes to evict ); /////////////////////////////////////////////////////////////////////////////// /// @brief Makes image resident for the device. /// /// @details /// - The application must ensure the image is resident before being /// referenced by the device /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hContext` /// + `nullptr == hDevice` /// + `nullptr == hImage` ZE_APIEXPORT ze_result_t ZE_APICALL zeContextMakeImageResident( ze_context_handle_t hContext, ///< [in] handle of context object ze_device_handle_t hDevice, ///< [in] handle of the device ze_image_handle_t hImage ///< [in] handle of image to make resident ); /////////////////////////////////////////////////////////////////////////////// /// @brief Allows image to be evicted from the device. /// /// @details /// - The application must ensure the device is not currently referencing /// the image before it is evicted /// - The application may destroy the image without evicting; the image is /// implicitly evicted when destroyed. /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hContext` /// + `nullptr == hDevice` /// + `nullptr == hImage` ZE_APIEXPORT ze_result_t ZE_APICALL zeContextEvictImage( ze_context_handle_t hContext, ///< [in] handle of context object ze_device_handle_t hDevice, ///< [in] handle of the device ze_image_handle_t hImage ///< [in] handle of image to make evict ); #if !defined(__GNUC__) #pragma endregion #endif // Intel 'oneAPI' Level-Zero APIs for Sampler #if !defined(__GNUC__) #pragma region sampler #endif /////////////////////////////////////////////////////////////////////////////// /// @brief Sampler addressing modes typedef enum _ze_sampler_address_mode_t { ZE_SAMPLER_ADDRESS_MODE_NONE = 0, ///< No coordinate modifications for out-of-bounds image access. ZE_SAMPLER_ADDRESS_MODE_REPEAT = 1, ///< Out-of-bounds coordinates are wrapped back around. ZE_SAMPLER_ADDRESS_MODE_CLAMP = 2, ///< Out-of-bounds coordinates are clamped to edge. ZE_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER = 3, ///< Out-of-bounds coordinates are clamped to border color which is (0.0f, ///< 0.0f, 0.0f, 0.0f) if image format swizzle contains alpha, otherwise ///< (0.0f, 0.0f, 0.0f, 1.0f). ZE_SAMPLER_ADDRESS_MODE_MIRROR = 4, ///< Out-of-bounds coordinates are mirrored starting from edge. ZE_SAMPLER_ADDRESS_MODE_FORCE_UINT32 = 0x7fffffff } ze_sampler_address_mode_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Sampler filtering modes typedef enum _ze_sampler_filter_mode_t { ZE_SAMPLER_FILTER_MODE_NEAREST = 0, ///< No coordinate modifications for out of bounds image access. ZE_SAMPLER_FILTER_MODE_LINEAR = 1, ///< Out-of-bounds coordinates are wrapped back around. ZE_SAMPLER_FILTER_MODE_FORCE_UINT32 = 0x7fffffff } ze_sampler_filter_mode_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Sampler descriptor typedef struct _ze_sampler_desc_t { ze_structure_type_t stype; ///< [in] type of this structure const void* pNext; ///< [in][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). ze_sampler_address_mode_t addressMode; ///< [in] Sampler addressing mode to determine how out-of-bounds ///< coordinates are handled. ze_sampler_filter_mode_t filterMode; ///< [in] Sampler filter mode to determine how samples are filtered. ze_bool_t isNormalized; ///< [in] Are coordinates normalized [0, 1] or not. } ze_sampler_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Creates sampler on the context. /// /// @details /// - The application must only use the sampler for the device, or its /// sub-devices, which was provided during creation. /// - The application may call this function from simultaneous threads. /// - The implementation of this function must be thread-safe. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hContext` /// + `nullptr == hDevice` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == desc` /// + `nullptr == phSampler` /// - ::ZE_RESULT_ERROR_INVALID_ENUMERATION /// + `::ZE_SAMPLER_ADDRESS_MODE_MIRROR < desc->addressMode` /// + `::ZE_SAMPLER_FILTER_MODE_LINEAR < desc->filterMode` ZE_APIEXPORT ze_result_t ZE_APICALL zeSamplerCreate( ze_context_handle_t hContext, ///< [in] handle of the context object ze_device_handle_t hDevice, ///< [in] handle of the device const ze_sampler_desc_t* desc, ///< [in] pointer to sampler descriptor ze_sampler_handle_t* phSampler ///< [out] handle of the sampler ); /////////////////////////////////////////////////////////////////////////////// /// @brief Destroys sampler object /// /// @details /// - The application must ensure the device is not currently referencing /// the sampler before it is deleted. /// - The implementation of this function may immediately free all Host and /// Device allocations associated with this sampler. /// - The application must **not** call this function from simultaneous /// threads with the same sampler handle. /// - The implementation of this function must be thread-safe. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hSampler` /// - ::ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE ZE_APIEXPORT ze_result_t ZE_APICALL zeSamplerDestroy( ze_sampler_handle_t hSampler ///< [in][release] handle of the sampler ); #if !defined(__GNUC__) #pragma endregion #endif // Intel 'oneAPI' Level-Zero APIs for Virtual Memory Management #if !defined(__GNUC__) #pragma region virtual #endif /////////////////////////////////////////////////////////////////////////////// /// @brief Virtual memory page access attributes typedef enum _ze_memory_access_attribute_t { ZE_MEMORY_ACCESS_ATTRIBUTE_NONE = 0, ///< Indicates the memory page is inaccessible. ZE_MEMORY_ACCESS_ATTRIBUTE_READWRITE = 1, ///< Indicates the memory page supports read write access. ZE_MEMORY_ACCESS_ATTRIBUTE_READONLY = 2, ///< Indicates the memory page supports read-only access. ZE_MEMORY_ACCESS_ATTRIBUTE_FORCE_UINT32 = 0x7fffffff } ze_memory_access_attribute_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Reserves pages in virtual address space. /// /// @details /// - The application must only use the memory allocation on the context for /// which it was created. /// - The starting address and size must be page aligned. See /// ::zeVirtualMemQueryPageSize. /// - If pStart is not null then implementation will attempt to reserve /// starting from that address. If not available then will find another /// suitable starting address. /// - The application may call this function from simultaneous threads. /// - The access attributes will default to none to indicate reservation is /// inaccessible. /// - The implementation of this function must be thread-safe. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hContext` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pptr` /// - ::ZE_RESULT_ERROR_UNSUPPORTED_SIZE /// + `0 == size` ZE_APIEXPORT ze_result_t ZE_APICALL zeVirtualMemReserve( ze_context_handle_t hContext, ///< [in] handle of the context object const void* pStart, ///< [in][optional] pointer to start of region to reserve. If nullptr then ///< implementation will choose a start address. size_t size, ///< [in] size in bytes to reserve; must be page aligned. void** pptr ///< [out] pointer to virtual reservation. ); /////////////////////////////////////////////////////////////////////////////// /// @brief Free pages in a reserved virtual address range. /// /// @details /// - Any existing virtual mappings for the range will be unmapped. /// - Physical allocations objects that were mapped to this range will not /// be destroyed. These need to be destroyed explicitly. /// - The application may call this function from simultaneous threads. /// - The implementation of this function must be thread-safe. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hContext` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == ptr` /// - ::ZE_RESULT_ERROR_UNSUPPORTED_SIZE /// + `0 == size` /// - ::ZE_RESULT_ERROR_UNSUPPORTED_ALIGNMENT ZE_APIEXPORT ze_result_t ZE_APICALL zeVirtualMemFree( ze_context_handle_t hContext, ///< [in] handle of the context object const void* ptr, ///< [in] pointer to start of region to free. size_t size ///< [in] size in bytes to free; must be page aligned. ); /////////////////////////////////////////////////////////////////////////////// /// @brief Queries page size to use for aligning virtual memory reservations and /// physical memory allocations. /// /// @details /// - The application may call this function from simultaneous threads. /// - The implementation of this function must be thread-safe. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hContext` /// + `nullptr == hDevice` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pagesize` /// - ::ZE_RESULT_ERROR_UNSUPPORTED_SIZE /// + `0 == size` ZE_APIEXPORT ze_result_t ZE_APICALL zeVirtualMemQueryPageSize( ze_context_handle_t hContext, ///< [in] handle of the context object ze_device_handle_t hDevice, ///< [in] handle of the device object size_t size, ///< [in] unaligned allocation size in bytes size_t* pagesize ///< [out] pointer to page size to use for start address and size ///< alignments. ); /////////////////////////////////////////////////////////////////////////////// /// @brief Supported physical memory creation flags typedef uint32_t ze_physical_mem_flags_t; typedef enum _ze_physical_mem_flag_t { ZE_PHYSICAL_MEM_FLAG_TBD = ZE_BIT(0), ///< reserved for future use. ZE_PHYSICAL_MEM_FLAG_FORCE_UINT32 = 0x7fffffff } ze_physical_mem_flag_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Physical memory descriptor typedef struct _ze_physical_mem_desc_t { ze_structure_type_t stype; ///< [in] type of this structure const void* pNext; ///< [in][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). ze_physical_mem_flags_t flags; ///< [in] creation flags. ///< must be 0 (default) or a valid combination of ::ze_physical_mem_flag_t. size_t size; ///< [in] size in bytes to reserve; must be page aligned. } ze_physical_mem_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Creates a physical memory object for the context. /// /// @details /// - The application must only use the physical memory object on the /// context for which it was created. /// - The size must be page aligned. See ::zeVirtualMemQueryPageSize. /// - The application may call this function from simultaneous threads. /// - The implementation of this function must be thread-safe. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hContext` /// + `nullptr == hDevice` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == desc` /// + `nullptr == phPhysicalMemory` /// - ::ZE_RESULT_ERROR_INVALID_ENUMERATION /// + `0x1 < desc->flags` /// - ::ZE_RESULT_ERROR_UNSUPPORTED_SIZE /// + `0 == desc->size` /// - ::ZE_RESULT_ERROR_UNSUPPORTED_ALIGNMENT ZE_APIEXPORT ze_result_t ZE_APICALL zePhysicalMemCreate( ze_context_handle_t hContext, ///< [in] handle of the context object ze_device_handle_t hDevice, ///< [in] handle of the device object ze_physical_mem_desc_t* desc, ///< [in] pointer to physical memory descriptor. ze_physical_mem_handle_t* phPhysicalMemory ///< [out] pointer to handle of physical memory object created ); /////////////////////////////////////////////////////////////////////////////// /// @brief Destroys a physical memory object. /// /// @details /// - The application must ensure the device is not currently referencing /// the physical memory object before it is deleted /// - The application must **not** call this function from simultaneous /// threads with the same physical memory handle. /// - The implementation of this function must be thread-safe. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hContext` /// + `nullptr == hPhysicalMemory` /// - ::ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE ZE_APIEXPORT ze_result_t ZE_APICALL zePhysicalMemDestroy( ze_context_handle_t hContext, ///< [in] handle of the context object ze_physical_mem_handle_t hPhysicalMemory ///< [in][release] handle of physical memory object to destroy ); /////////////////////////////////////////////////////////////////////////////// /// @brief Maps pages in virtual address space to pages from physical memory /// object. /// /// @details /// - The virtual address range must have been reserved using /// ::zeVirtualMemReserve. /// - The application must only use the mapped memory allocation on the /// context for which it was created. /// - The virtual start address and size must be page aligned. See /// ::zeVirtualMemQueryPageSize. /// - The application should use, for the starting address and size, the /// same size alignment used for the physical allocation. /// - The application may call this function from simultaneous threads. /// - The implementation of this function must be thread-safe. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hContext` /// + `nullptr == hPhysicalMemory` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == ptr` /// - ::ZE_RESULT_ERROR_INVALID_ENUMERATION /// + `::ZE_MEMORY_ACCESS_ATTRIBUTE_READONLY < access` /// - ::ZE_RESULT_ERROR_UNSUPPORTED_SIZE /// + `0 == size` /// - ::ZE_RESULT_ERROR_UNSUPPORTED_ALIGNMENT ZE_APIEXPORT ze_result_t ZE_APICALL zeVirtualMemMap( ze_context_handle_t hContext, ///< [in] handle of the context object const void* ptr, ///< [in] pointer to start of virtual address range to map. size_t size, ///< [in] size in bytes of virtual address range to map; must be page ///< aligned. ze_physical_mem_handle_t hPhysicalMemory, ///< [in] handle to physical memory object. size_t offset, ///< [in] offset into physical memory allocation object; must be page ///< aligned. ze_memory_access_attribute_t access ///< [in] specifies page access attributes to apply to the virtual address ///< range. ); /////////////////////////////////////////////////////////////////////////////// /// @brief Unmaps pages in virtual address space from pages from a physical /// memory object. /// /// @details /// - The page access attributes for virtual address range will revert back /// to none. /// - The application may call this function from simultaneous threads. /// - The implementation of this function must be thread-safe. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hContext` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == ptr` /// - ::ZE_RESULT_ERROR_UNSUPPORTED_ALIGNMENT - "Address must be page aligned" /// - ::ZE_RESULT_ERROR_UNSUPPORTED_SIZE /// + `0 == size` /// + Size must be page aligned ZE_APIEXPORT ze_result_t ZE_APICALL zeVirtualMemUnmap( ze_context_handle_t hContext, ///< [in] handle of the context object const void* ptr, ///< [in] pointer to start of region to unmap. size_t size ///< [in] size in bytes to unmap; must be page aligned. ); /////////////////////////////////////////////////////////////////////////////// /// @brief Set memory access attributes for a virtual address range. /// /// @details /// - This function may be called from simultaneous threads with the same /// function handle. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hContext` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == ptr` /// - ::ZE_RESULT_ERROR_INVALID_ENUMERATION /// + `::ZE_MEMORY_ACCESS_ATTRIBUTE_READONLY < access` /// - ::ZE_RESULT_ERROR_UNSUPPORTED_ALIGNMENT - "Address must be page aligned" /// - ::ZE_RESULT_ERROR_UNSUPPORTED_SIZE /// + `0 == size` /// + Size must be page aligned ZE_APIEXPORT ze_result_t ZE_APICALL zeVirtualMemSetAccessAttribute( ze_context_handle_t hContext, ///< [in] handle of the context object const void* ptr, ///< [in] pointer to start of reserved virtual address region. size_t size, ///< [in] size in bytes; must be page aligned. ze_memory_access_attribute_t access ///< [in] specifies page access attributes to apply to the virtual address ///< range. ); /////////////////////////////////////////////////////////////////////////////// /// @brief Get memory access attribute for a virtual address range. /// /// @details /// - If size and outSize are equal then the pages in the specified virtual /// address range have the same access attributes. /// - This function may be called from simultaneous threads with the same /// function handle. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hContext` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == ptr` /// + `nullptr == access` /// + `nullptr == outSize` /// - ::ZE_RESULT_ERROR_UNSUPPORTED_ALIGNMENT - "Address must be page aligned" /// - ::ZE_RESULT_ERROR_UNSUPPORTED_SIZE /// + `0 == size` /// + Size must be page aligned ZE_APIEXPORT ze_result_t ZE_APICALL zeVirtualMemGetAccessAttribute( ze_context_handle_t hContext, ///< [in] handle of the context object const void* ptr, ///< [in] pointer to start of virtual address region for query. size_t size, ///< [in] size in bytes; must be page aligned. ze_memory_access_attribute_t* access, ///< [out] query result for page access attribute. size_t* outSize ///< [out] query result for size of virtual address range, starting at ptr, ///< that shares same access attribute. ); #if !defined(__GNUC__) #pragma endregion #endif // Intel 'oneAPI' Level-Zero Extension APIs for Floating-Point Atomics #if !defined(__GNUC__) #pragma region floatAtomics #endif /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_FLOAT_ATOMICS_EXT_NAME /// @brief Floating-Point Atomics Extension Name #define ZE_FLOAT_ATOMICS_EXT_NAME "ZE_extension_float_atomics" #endif // ZE_FLOAT_ATOMICS_EXT_NAME /////////////////////////////////////////////////////////////////////////////// /// @brief Floating-Point Atomics Extension Version(s) typedef enum _ze_float_atomics_ext_version_t { ZE_FLOAT_ATOMICS_EXT_VERSION_1_0 = ZE_MAKE_VERSION( 1, 0 ), ///< version 1.0 ZE_FLOAT_ATOMICS_EXT_VERSION_CURRENT = ZE_MAKE_VERSION( 1, 0 ), ///< latest known version ZE_FLOAT_ATOMICS_EXT_VERSION_FORCE_UINT32 = 0x7fffffff } ze_float_atomics_ext_version_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Supported floating-point atomic capability flags typedef uint32_t ze_device_fp_atomic_ext_flags_t; typedef enum _ze_device_fp_atomic_ext_flag_t { ZE_DEVICE_FP_ATOMIC_EXT_FLAG_GLOBAL_LOAD_STORE = ZE_BIT(0), ///< Supports atomic load, store, and exchange ZE_DEVICE_FP_ATOMIC_EXT_FLAG_GLOBAL_ADD = ZE_BIT(1),///< Supports atomic add and subtract ZE_DEVICE_FP_ATOMIC_EXT_FLAG_GLOBAL_MIN_MAX = ZE_BIT(2),///< Supports atomic min and max ZE_DEVICE_FP_ATOMIC_EXT_FLAG_LOCAL_LOAD_STORE = ZE_BIT(16), ///< Supports atomic load, store, and exchange ZE_DEVICE_FP_ATOMIC_EXT_FLAG_LOCAL_ADD = ZE_BIT(17),///< Supports atomic add and subtract ZE_DEVICE_FP_ATOMIC_EXT_FLAG_LOCAL_MIN_MAX = ZE_BIT(18),///< Supports atomic min and max ZE_DEVICE_FP_ATOMIC_EXT_FLAG_FORCE_UINT32 = 0x7fffffff } ze_device_fp_atomic_ext_flag_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Device floating-point atomic properties queried using /// ::zeDeviceGetModuleProperties /// /// @details /// - This structure may be returned from ::zeDeviceGetModuleProperties, via /// `pNext` member of ::ze_device_module_properties_t. typedef struct _ze_float_atomic_ext_properties_t { ze_structure_type_t stype; ///< [in] type of this structure void* pNext; ///< [in,out][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). ze_device_fp_atomic_ext_flags_t fp16Flags; ///< [out] Capabilities for half-precision floating-point atomic operations ze_device_fp_atomic_ext_flags_t fp32Flags; ///< [out] Capabilities for single-precision floating-point atomic ///< operations ze_device_fp_atomic_ext_flags_t fp64Flags; ///< [out] Capabilities for double-precision floating-point atomic ///< operations } ze_float_atomic_ext_properties_t; #if !defined(__GNUC__) #pragma endregion #endif // Intel 'oneAPI' Level-Zero Extension for supporting kernel global work offset. #if !defined(__GNUC__) #pragma region globaloffset #endif /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_GLOBAL_OFFSET_EXP_NAME /// @brief Global Offset Extension Name #define ZE_GLOBAL_OFFSET_EXP_NAME "ZE_experimental_global_offset" #endif // ZE_GLOBAL_OFFSET_EXP_NAME /////////////////////////////////////////////////////////////////////////////// /// @brief Global Offset Extension Version(s) typedef enum _ze_global_offset_exp_version_t { ZE_GLOBAL_OFFSET_EXP_VERSION_1_0 = ZE_MAKE_VERSION( 1, 0 ), ///< version 1.0 ZE_GLOBAL_OFFSET_EXP_VERSION_CURRENT = ZE_MAKE_VERSION( 1, 0 ), ///< latest known version ZE_GLOBAL_OFFSET_EXP_VERSION_FORCE_UINT32 = 0x7fffffff } ze_global_offset_exp_version_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Set global work offset for a kernel. /// /// @details /// - The global work offset will be used when a /// ::zeCommandListAppendLaunchKernel() variant is called. /// - The application must **not** call this function from simultaneous /// threads with the same kernel handle. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hKernel` ZE_APIEXPORT ze_result_t ZE_APICALL zeKernelSetGlobalOffsetExp( ze_kernel_handle_t hKernel, ///< [in] handle of the kernel object uint32_t offsetX, ///< [in] global offset for X dimension to use for this kernel uint32_t offsetY, ///< [in] global offset for Y dimension to use for this kernel uint32_t offsetZ ///< [in] global offset for Z dimension to use for this kernel ); #if !defined(__GNUC__) #pragma endregion #endif // Intel 'oneAPI' Level-Zero Extension for supporting relaxed allocation limits. #if !defined(__GNUC__) #pragma region relaxedAllocLimits #endif /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_RELAXED_ALLOCATION_LIMITS_EXP_NAME /// @brief Relaxed Allocation Limits Extension Name #define ZE_RELAXED_ALLOCATION_LIMITS_EXP_NAME "ZE_experimental_relaxed_allocation_limits" #endif // ZE_RELAXED_ALLOCATION_LIMITS_EXP_NAME /////////////////////////////////////////////////////////////////////////////// /// @brief Relaxed Allocation Limits Extension Version(s) typedef enum _ze_relaxed_allocation_limits_exp_version_t { ZE_RELAXED_ALLOCATION_LIMITS_EXP_VERSION_1_0 = ZE_MAKE_VERSION( 1, 0 ), ///< version 1.0 ZE_RELAXED_ALLOCATION_LIMITS_EXP_VERSION_CURRENT = ZE_MAKE_VERSION( 1, 0 ), ///< latest known version ZE_RELAXED_ALLOCATION_LIMITS_EXP_VERSION_FORCE_UINT32 = 0x7fffffff } ze_relaxed_allocation_limits_exp_version_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Supported relaxed memory allocation flags typedef uint32_t ze_relaxed_allocation_limits_exp_flags_t; typedef enum _ze_relaxed_allocation_limits_exp_flag_t { ZE_RELAXED_ALLOCATION_LIMITS_EXP_FLAG_MAX_SIZE = ZE_BIT(0), ///< Allocation size may exceed ::ze_device_properties_t.maxMemAllocSize ZE_RELAXED_ALLOCATION_LIMITS_EXP_FLAG_FORCE_UINT32 = 0x7fffffff } ze_relaxed_allocation_limits_exp_flag_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Relaxed limits memory allocation descriptor /// /// @details /// - This structure may be passed to ::zeMemAllocShared or /// ::zeMemAllocDevice, via `pNext` member of /// ::ze_device_mem_alloc_desc_t. /// - This structure may also be passed to ::zeMemAllocHost, via `pNext` /// member of ::ze_host_mem_alloc_desc_t. typedef struct _ze_relaxed_allocation_limits_exp_desc_t { ze_structure_type_t stype; ///< [in] type of this structure const void* pNext; ///< [in][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). ze_relaxed_allocation_limits_exp_flags_t flags; ///< [in] flags specifying allocation limits to relax. ///< must be 0 (default) or a valid combination of ::ze_relaxed_allocation_limits_exp_flag_t; } ze_relaxed_allocation_limits_exp_desc_t; #if !defined(__GNUC__) #pragma endregion #endif // Intel 'oneAPI' Level-Zero Extension APIs for Cache Reservation #if !defined(__GNUC__) #pragma region cacheReservation #endif /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_CACHE_RESERVATION_EXT_NAME /// @brief Cache_Reservation Extension Name #define ZE_CACHE_RESERVATION_EXT_NAME "ZE_extension_cache_reservation" #endif // ZE_CACHE_RESERVATION_EXT_NAME /////////////////////////////////////////////////////////////////////////////// /// @brief Cache_Reservation Extension Version(s) typedef enum _ze_cache_reservation_ext_version_t { ZE_CACHE_RESERVATION_EXT_VERSION_1_0 = ZE_MAKE_VERSION( 1, 0 ), ///< version 1.0 ZE_CACHE_RESERVATION_EXT_VERSION_CURRENT = ZE_MAKE_VERSION( 1, 0 ), ///< latest known version ZE_CACHE_RESERVATION_EXT_VERSION_FORCE_UINT32 = 0x7fffffff } ze_cache_reservation_ext_version_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Cache Reservation Region typedef enum _ze_cache_ext_region_t { ZE_CACHE_EXT_REGION_ZE_CACHE_REGION_DEFAULT = 0,///< utilize driver default scheme ZE_CACHE_EXT_REGION_ZE_CACHE_RESERVE_REGION = 1,///< Utilize reserver region ZE_CACHE_EXT_REGION_ZE_CACHE_NON_RESERVED_REGION = 2, ///< Utilize non-reserverd region ZE_CACHE_EXT_REGION_FORCE_UINT32 = 0x7fffffff } ze_cache_ext_region_t; /////////////////////////////////////////////////////////////////////////////// /// @brief CacheReservation structure /// /// @details /// - This structure must be passed to ::zeDeviceGetCacheProperties via /// `pNext` member of ::ze_device_cache_properties_t /// - Used for determining the max cache reservation allowed on device. Size /// of zero means no reservation available. typedef struct _ze_cache_reservation_ext_desc_t { ze_structure_type_t stype; ///< [in] type of this structure const void* pNext; ///< [in][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). size_t maxCacheReservationSize; ///< [out] max cache reservation size } ze_cache_reservation_ext_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Reserve Cache on Device /// /// @details /// - The application may call this function but may not be successful as /// some other application may have reserve prior /// /// @remarks /// _Analogues_ /// - None /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hDevice` ZE_APIEXPORT ze_result_t ZE_APICALL zeDeviceReserveCacheExt( ze_device_handle_t hDevice, ///< [in] handle of the device object size_t cacheLevel, ///< [in] cache level where application want to reserve. If zero, then the ///< driver shall default to last level of cache and attempt to reserve in ///< that cache. size_t cacheReservationSize ///< [in] value for reserving size, in bytes. If zero, then the driver ///< shall remove prior reservation ); /////////////////////////////////////////////////////////////////////////////// /// @brief Assign VA section to use reserved section /// /// @details /// - The application may call this function to assign VA to particular /// reservartion region /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hDevice` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == ptr` /// - ::ZE_RESULT_ERROR_INVALID_ENUMERATION /// + `::ZE_CACHE_EXT_REGION_::ZE_CACHE_NON_RESERVED_REGION < cacheRegion` ZE_APIEXPORT ze_result_t ZE_APICALL zeDeviceSetCacheAdviceExt( ze_device_handle_t hDevice, ///< [in] handle of the device object void* ptr, ///< [in] memory pointer to query size_t regionSize, ///< [in] region size, in pages ze_cache_ext_region_t cacheRegion ///< [in] reservation region ); #if !defined(__GNUC__) #pragma endregion #endif // Intel 'oneAPI' Level-Zero Extension for supporting event query timestamps. #if !defined(__GNUC__) #pragma region eventquerytimestamps #endif /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_EVENT_QUERY_TIMESTAMPS_EXP_NAME /// @brief Event Query Timestamps Extension Name #define ZE_EVENT_QUERY_TIMESTAMPS_EXP_NAME "ZE_experimental_event_query_timestamps" #endif // ZE_EVENT_QUERY_TIMESTAMPS_EXP_NAME /////////////////////////////////////////////////////////////////////////////// /// @brief Event Query Timestamps Extension Version(s) typedef enum _ze_event_query_timestamps_exp_version_t { ZE_EVENT_QUERY_TIMESTAMPS_EXP_VERSION_1_0 = ZE_MAKE_VERSION( 1, 0 ),///< version 1.0 ZE_EVENT_QUERY_TIMESTAMPS_EXP_VERSION_CURRENT = ZE_MAKE_VERSION( 1, 0 ),///< latest known version ZE_EVENT_QUERY_TIMESTAMPS_EXP_VERSION_FORCE_UINT32 = 0x7fffffff } ze_event_query_timestamps_exp_version_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Query event timestamps for a device or sub-device. /// /// @details /// - The application may call this function from simultaneous threads. /// - The implementation of this function must be thread-safe. /// - The implementation must support /// ::ZE_experimental_event_query_timestamps. /// - The implementation must return all timestamps for the specified event /// and device pair. /// - The implementation must return all timestamps for all sub-devices when /// device handle is parent device. /// - The implementation may return all timestamps for sub-devices when /// device handle is sub-device or may return 0 for count. /// /// @remarks /// _Analogues_ /// - None /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hEvent` /// + `nullptr == hDevice` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pCount` ZE_APIEXPORT ze_result_t ZE_APICALL zeEventQueryTimestampsExp( ze_event_handle_t hEvent, ///< [in] handle of the event ze_device_handle_t hDevice, ///< [in] handle of the device to query uint32_t* pCount, ///< [in,out] pointer to the number of timestamp results. ///< if count is zero, then the driver shall update the value with the ///< total number of timestamps available. ///< if count is greater than the number of timestamps available, then the ///< driver shall update the value with the correct number of timestamps available. ze_kernel_timestamp_result_t* pTimestamps ///< [in,out][optional][range(0, *pCount)] array of timestamp results. ///< if count is less than the number of timestamps available, then driver ///< shall only retrieve that number of timestamps. ); #if !defined(__GNUC__) #pragma endregion #endif // Intel 'oneAPI' Level-Zero Extension for supporting image memory properties. #if !defined(__GNUC__) #pragma region imagememoryproperties #endif /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_IMAGE_MEMORY_PROPERTIES_EXP_NAME /// @brief Image Memory Properties Extension Name #define ZE_IMAGE_MEMORY_PROPERTIES_EXP_NAME "ZE_experimental_image_memory_properties" #endif // ZE_IMAGE_MEMORY_PROPERTIES_EXP_NAME /////////////////////////////////////////////////////////////////////////////// /// @brief Image Memory Properties Extension Version(s) typedef enum _ze_image_memory_properties_exp_version_t { ZE_IMAGE_MEMORY_PROPERTIES_EXP_VERSION_1_0 = ZE_MAKE_VERSION( 1, 0 ), ///< version 1.0 ZE_IMAGE_MEMORY_PROPERTIES_EXP_VERSION_CURRENT = ZE_MAKE_VERSION( 1, 0 ), ///< latest known version ZE_IMAGE_MEMORY_PROPERTIES_EXP_VERSION_FORCE_UINT32 = 0x7fffffff } ze_image_memory_properties_exp_version_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Image memory properties typedef struct _ze_image_memory_properties_exp_t { ze_structure_type_t stype; ///< [in] type of this structure const void* pNext; ///< [in][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). uint64_t size; ///< [out] size of image allocation in bytes. uint64_t rowPitch; ///< [out] size of image row in bytes. uint64_t slicePitch; ///< [out] size of image slice in bytes. } ze_image_memory_properties_exp_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Query image memory properties. /// /// @details /// - The application may call this function from simultaneous threads. /// - The implementation of this function must be thread-safe. /// - The implementation must support /// ::ZE_experimental_image_memory_properties extension. /// /// @remarks /// _Analogues_ /// - None /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hImage` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pMemoryProperties` ZE_APIEXPORT ze_result_t ZE_APICALL zeImageGetMemoryPropertiesExp( ze_image_handle_t hImage, ///< [in] handle of image object ze_image_memory_properties_exp_t* pMemoryProperties ///< [in,out] query result for image memory properties. ); #if !defined(__GNUC__) #pragma endregion #endif // Intel 'oneAPI' Level-Zero Extension for supporting image views. #if !defined(__GNUC__) #pragma region imageview #endif /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_IMAGE_VIEW_EXT_NAME /// @brief Image View Extension Name #define ZE_IMAGE_VIEW_EXT_NAME "ZE_extension_image_view" #endif // ZE_IMAGE_VIEW_EXT_NAME /////////////////////////////////////////////////////////////////////////////// /// @brief Image View Extension Version(s) typedef enum _ze_image_view_ext_version_t { ZE_IMAGE_VIEW_EXT_VERSION_1_0 = ZE_MAKE_VERSION( 1, 0 ),///< version 1.0 ZE_IMAGE_VIEW_EXT_VERSION_CURRENT = ZE_MAKE_VERSION( 1, 0 ),///< latest known version ZE_IMAGE_VIEW_EXT_VERSION_FORCE_UINT32 = 0x7fffffff } ze_image_view_ext_version_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Create image view on the context. /// /// @details /// - The application must only use the image view for the device, or its /// sub-devices, which was provided during creation. /// - The application may call this function from simultaneous threads. /// - The implementation of this function must be thread-safe. /// - The implementation must support ::ZE_extension_image_view extension. /// - Image views are treated as images from the API. /// - Image views provide a mechanism to redescribe how an image is /// interpreted (e.g. different format). /// - Image views become disabled when their corresponding image resource is /// destroyed. /// - Use ::zeImageDestroy to destroy image view objects. /// /// @remarks /// _Analogues_ /// - None /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hContext` /// + `nullptr == hDevice` /// + `nullptr == hImage` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == desc` /// + `nullptr == phImageView` /// - ::ZE_RESULT_ERROR_INVALID_ENUMERATION /// + `0x3 < desc->flags` /// + `::ZE_IMAGE_TYPE_BUFFER < desc->type` /// - ::ZE_RESULT_ERROR_UNSUPPORTED_IMAGE_FORMAT ZE_APIEXPORT ze_result_t ZE_APICALL zeImageViewCreateExt( ze_context_handle_t hContext, ///< [in] handle of the context object ze_device_handle_t hDevice, ///< [in] handle of the device const ze_image_desc_t* desc, ///< [in] pointer to image descriptor ze_image_handle_t hImage, ///< [in] handle of image object to create view from ze_image_handle_t* phImageView ///< [out] pointer to handle of image object created for view ); /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_IMAGE_VIEW_EXP_NAME /// @brief Image View Extension Name #define ZE_IMAGE_VIEW_EXP_NAME "ZE_experimental_image_view" #endif // ZE_IMAGE_VIEW_EXP_NAME /////////////////////////////////////////////////////////////////////////////// /// @brief Image View Extension Version(s) typedef enum _ze_image_view_exp_version_t { ZE_IMAGE_VIEW_EXP_VERSION_1_0 = ZE_MAKE_VERSION( 1, 0 ),///< version 1.0 ZE_IMAGE_VIEW_EXP_VERSION_CURRENT = ZE_MAKE_VERSION( 1, 0 ),///< latest known version ZE_IMAGE_VIEW_EXP_VERSION_FORCE_UINT32 = 0x7fffffff } ze_image_view_exp_version_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Create image view on the context. /// /// @details /// - The application must only use the image view for the device, or its /// sub-devices, which was provided during creation. /// - The application may call this function from simultaneous threads. /// - The implementation of this function must be thread-safe. /// - The implementation must support ::ZE_experimental_image_view /// extension. /// - Image views are treated as images from the API. /// - Image views provide a mechanism to redescribe how an image is /// interpreted (e.g. different format). /// - Image views become disabled when their corresponding image resource is /// destroyed. /// - Use ::zeImageDestroy to destroy image view objects. /// - Note: This function is deprecated and replaced by /// ::zeImageViewCreateExt. /// /// @remarks /// _Analogues_ /// - None /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hContext` /// + `nullptr == hDevice` /// + `nullptr == hImage` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == desc` /// + `nullptr == phImageView` /// - ::ZE_RESULT_ERROR_INVALID_ENUMERATION /// + `0x3 < desc->flags` /// + `::ZE_IMAGE_TYPE_BUFFER < desc->type` /// - ::ZE_RESULT_ERROR_UNSUPPORTED_IMAGE_FORMAT ZE_APIEXPORT ze_result_t ZE_APICALL zeImageViewCreateExp( ze_context_handle_t hContext, ///< [in] handle of the context object ze_device_handle_t hDevice, ///< [in] handle of the device const ze_image_desc_t* desc, ///< [in] pointer to image descriptor ze_image_handle_t hImage, ///< [in] handle of image object to create view from ze_image_handle_t* phImageView ///< [out] pointer to handle of image object created for view ); #if !defined(__GNUC__) #pragma endregion #endif // Intel 'oneAPI' Level-Zero Extension for supporting image views for planar images. #if !defined(__GNUC__) #pragma region imageviewplanar #endif /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_IMAGE_VIEW_PLANAR_EXT_NAME /// @brief Image View Planar Extension Name #define ZE_IMAGE_VIEW_PLANAR_EXT_NAME "ZE_extension_image_view_planar" #endif // ZE_IMAGE_VIEW_PLANAR_EXT_NAME /////////////////////////////////////////////////////////////////////////////// /// @brief Image View Planar Extension Version(s) typedef enum _ze_image_view_planar_ext_version_t { ZE_IMAGE_VIEW_PLANAR_EXT_VERSION_1_0 = ZE_MAKE_VERSION( 1, 0 ), ///< version 1.0 ZE_IMAGE_VIEW_PLANAR_EXT_VERSION_CURRENT = ZE_MAKE_VERSION( 1, 0 ), ///< latest known version ZE_IMAGE_VIEW_PLANAR_EXT_VERSION_FORCE_UINT32 = 0x7fffffff } ze_image_view_planar_ext_version_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Image view planar descriptor typedef struct _ze_image_view_planar_ext_desc_t { ze_structure_type_t stype; ///< [in] type of this structure const void* pNext; ///< [in][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). uint32_t planeIndex; ///< [in] the 0-based plane index (e.g. NV12 is 0 = Y plane, 1 UV plane) } ze_image_view_planar_ext_desc_t; /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_IMAGE_VIEW_PLANAR_EXP_NAME /// @brief Image View Planar Extension Name #define ZE_IMAGE_VIEW_PLANAR_EXP_NAME "ZE_experimental_image_view_planar" #endif // ZE_IMAGE_VIEW_PLANAR_EXP_NAME /////////////////////////////////////////////////////////////////////////////// /// @brief Image View Planar Extension Version(s) typedef enum _ze_image_view_planar_exp_version_t { ZE_IMAGE_VIEW_PLANAR_EXP_VERSION_1_0 = ZE_MAKE_VERSION( 1, 0 ), ///< version 1.0 ZE_IMAGE_VIEW_PLANAR_EXP_VERSION_CURRENT = ZE_MAKE_VERSION( 1, 0 ), ///< latest known version ZE_IMAGE_VIEW_PLANAR_EXP_VERSION_FORCE_UINT32 = 0x7fffffff } ze_image_view_planar_exp_version_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Image view planar descriptor typedef struct _ze_image_view_planar_exp_desc_t { ze_structure_type_t stype; ///< [in] type of this structure const void* pNext; ///< [in][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). uint32_t planeIndex; ///< [in] the 0-based plane index (e.g. NV12 is 0 = Y plane, 1 UV plane) } ze_image_view_planar_exp_desc_t; #if !defined(__GNUC__) #pragma endregion #endif // Intel 'oneAPI' Level-Zero Extension for specifying kernel scheduling hints. #if !defined(__GNUC__) #pragma region kernelSchedulingHints #endif /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_KERNEL_SCHEDULING_HINTS_EXP_NAME /// @brief Kernel Scheduling Hints Extension Name #define ZE_KERNEL_SCHEDULING_HINTS_EXP_NAME "ZE_experimental_scheduling_hints" #endif // ZE_KERNEL_SCHEDULING_HINTS_EXP_NAME /////////////////////////////////////////////////////////////////////////////// /// @brief Kernel Scheduling Hints Extension Version(s) typedef enum _ze_scheduling_hints_exp_version_t { ZE_SCHEDULING_HINTS_EXP_VERSION_1_0 = ZE_MAKE_VERSION( 1, 0 ), ///< version 1.0 ZE_SCHEDULING_HINTS_EXP_VERSION_CURRENT = ZE_MAKE_VERSION( 1, 0 ), ///< latest known version ZE_SCHEDULING_HINTS_EXP_VERSION_FORCE_UINT32 = 0x7fffffff } ze_scheduling_hints_exp_version_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Supported kernel scheduling hint flags typedef uint32_t ze_scheduling_hint_exp_flags_t; typedef enum _ze_scheduling_hint_exp_flag_t { ZE_SCHEDULING_HINT_EXP_FLAG_OLDEST_FIRST = ZE_BIT(0), ///< Hint that the kernel prefers oldest-first scheduling ZE_SCHEDULING_HINT_EXP_FLAG_ROUND_ROBIN = ZE_BIT(1),///< Hint that the kernel prefers round-robin scheduling ZE_SCHEDULING_HINT_EXP_FLAG_STALL_BASED_ROUND_ROBIN = ZE_BIT(2),///< Hint that the kernel prefers stall-based round-robin scheduling ZE_SCHEDULING_HINT_EXP_FLAG_FORCE_UINT32 = 0x7fffffff } ze_scheduling_hint_exp_flag_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Device kernel scheduling hint properties queried using /// ::zeDeviceGetModuleProperties /// /// @details /// - This structure may be returned from ::zeDeviceGetModuleProperties, via /// `pNext` member of ::ze_device_module_properties_t. typedef struct _ze_scheduling_hint_exp_properties_t { ze_structure_type_t stype; ///< [in] type of this structure void* pNext; ///< [in,out][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). ze_scheduling_hint_exp_flags_t schedulingHintFlags; ///< [out] Supported kernel scheduling hints. ///< May be 0 (none) or a valid combination of ::ze_scheduling_hint_exp_flag_t. } ze_scheduling_hint_exp_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Kernel scheduling hint descriptor /// /// @details /// - This structure may be passed to ::zeKernelSchedulingHintExp. typedef struct _ze_scheduling_hint_exp_desc_t { ze_structure_type_t stype; ///< [in] type of this structure const void* pNext; ///< [in][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). ze_scheduling_hint_exp_flags_t flags; ///< [in] flags specifying kernel scheduling hints. ///< must be 0 (default) or a valid combination of ::ze_scheduling_hint_exp_flag_t. } ze_scheduling_hint_exp_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Provide kernel scheduling hints that may improve performance /// /// @details /// - The scheduling hints may improve performance only and are not required /// for correctness. /// - If a specified scheduling hint is unsupported it will be silently /// ignored. /// - If two conflicting scheduling hints are specified there is no defined behavior; /// the hints may be ignored or one hint may be chosen arbitrarily. /// - The application must not call this function from simultaneous threads /// with the same kernel handle. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hKernel` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pHint` /// - ::ZE_RESULT_ERROR_INVALID_ENUMERATION /// + `0x7 < pHint->flags` ZE_APIEXPORT ze_result_t ZE_APICALL zeKernelSchedulingHintExp( ze_kernel_handle_t hKernel, ///< [in] handle of the kernel object ze_scheduling_hint_exp_desc_t* pHint ///< [in] pointer to kernel scheduling hint descriptor ); #if !defined(__GNUC__) #pragma endregion #endif // Intel 'oneAPI' Level-Zero Extension APIs for One-Definition-Rule Linkage Types #if !defined(__GNUC__) #pragma region linkonceodr #endif /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_LINKONCE_ODR_EXT_NAME /// @brief Linkonce ODR Extension Name #define ZE_LINKONCE_ODR_EXT_NAME "ZE_extension_linkonce_odr" #endif // ZE_LINKONCE_ODR_EXT_NAME /////////////////////////////////////////////////////////////////////////////// /// @brief Linkonce ODR Extension Version(s) typedef enum _ze_linkonce_odr_ext_version_t { ZE_LINKONCE_ODR_EXT_VERSION_1_0 = ZE_MAKE_VERSION( 1, 0 ), ///< version 1.0 ZE_LINKONCE_ODR_EXT_VERSION_CURRENT = ZE_MAKE_VERSION( 1, 0 ), ///< latest known version ZE_LINKONCE_ODR_EXT_VERSION_FORCE_UINT32 = 0x7fffffff } ze_linkonce_odr_ext_version_t; #if !defined(__GNUC__) #pragma endregion #endif // Intel 'oneAPI' Level-Zero Extension for supporting power saving hint. #if !defined(__GNUC__) #pragma region powersavinghint #endif /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_CONTEXT_POWER_SAVING_HINT_EXP_NAME /// @brief Power Saving Hint Extension Name #define ZE_CONTEXT_POWER_SAVING_HINT_EXP_NAME "ZE_experimental_power_saving_hint" #endif // ZE_CONTEXT_POWER_SAVING_HINT_EXP_NAME /////////////////////////////////////////////////////////////////////////////// /// @brief Power Saving Hint Extension Version(s) typedef enum _ze_power_saving_hint_exp_version_t { ZE_POWER_SAVING_HINT_EXP_VERSION_1_0 = ZE_MAKE_VERSION( 1, 0 ), ///< version 1.0 ZE_POWER_SAVING_HINT_EXP_VERSION_CURRENT = ZE_MAKE_VERSION( 1, 0 ), ///< latest known version ZE_POWER_SAVING_HINT_EXP_VERSION_FORCE_UINT32 = 0x7fffffff } ze_power_saving_hint_exp_version_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Supported device types typedef enum _ze_power_saving_hint_type_t { ZE_POWER_SAVING_HINT_TYPE_MIN = 0, ///< Minumum power savings. The device will make no attempt to save power ///< while executing work submitted to this context. ZE_POWER_SAVING_HINT_TYPE_MAX = 100, ///< Maximum power savings. The device will do everything to bring power to ///< a minimum while executing work submitted to this context. ZE_POWER_SAVING_HINT_TYPE_FORCE_UINT32 = 0x7fffffff } ze_power_saving_hint_type_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Extended context descriptor containing power saving hint. typedef struct _ze_context_power_saving_hint_exp_desc_t { ze_structure_type_t stype; ///< [in] type of this structure const void* pNext; ///< [in][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). uint32_t hint; ///< [in] power saving hint (default value = 0). This is value from [0,100] ///< and can use pre-defined settings from ::ze_power_saving_hint_type_t. } ze_context_power_saving_hint_exp_desc_t; #if !defined(__GNUC__) #pragma endregion #endif // Intel 'oneAPI' Level-Zero Extension APIs for Subgroups #if !defined(__GNUC__) #pragma region subgroups #endif /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_SUBGROUPS_EXT_NAME /// @brief Subgroups Extension Name #define ZE_SUBGROUPS_EXT_NAME "ZE_extension_subgroups" #endif // ZE_SUBGROUPS_EXT_NAME /////////////////////////////////////////////////////////////////////////////// /// @brief Subgroups Extension Version(s) typedef enum _ze_subgroup_ext_version_t { ZE_SUBGROUP_EXT_VERSION_1_0 = ZE_MAKE_VERSION( 1, 0 ), ///< version 1.0 ZE_SUBGROUP_EXT_VERSION_CURRENT = ZE_MAKE_VERSION( 1, 0 ), ///< latest known version ZE_SUBGROUP_EXT_VERSION_FORCE_UINT32 = 0x7fffffff } ze_subgroup_ext_version_t; #if !defined(__GNUC__) #pragma endregion #endif // Intel 'oneAPI' Level-Zero Extension APIs for EU Count #if !defined(__GNUC__) #pragma region EUCount #endif /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_EU_COUNT_EXT_NAME /// @brief EU Count Extension Name #define ZE_EU_COUNT_EXT_NAME "ZE_extension_eu_count" #endif // ZE_EU_COUNT_EXT_NAME /////////////////////////////////////////////////////////////////////////////// /// @brief EU Count Extension Version(s) typedef enum _ze_eu_count_ext_version_t { ZE_EU_COUNT_EXT_VERSION_1_0 = ZE_MAKE_VERSION( 1, 0 ), ///< version 1.0 ZE_EU_COUNT_EXT_VERSION_CURRENT = ZE_MAKE_VERSION( 1, 0 ), ///< latest known version ZE_EU_COUNT_EXT_VERSION_FORCE_UINT32 = 0x7fffffff } ze_eu_count_ext_version_t; /////////////////////////////////////////////////////////////////////////////// /// @brief EU count queried using ::zeDeviceGetProperties /// /// @details /// - This structure may be returned from ::zeDeviceGetProperties via /// `pNext` member of ::ze_device_properties_t /// - Used for determining the total number of EUs available on device. typedef struct _ze_eu_count_ext_t { ze_structure_type_t stype; ///< [in] type of this structure const void* pNext; ///< [in][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). uint32_t numTotalEUs; ///< [out] Total number of EUs available } ze_eu_count_ext_t; #if !defined(__GNUC__) #pragma endregion #endif // Intel 'oneAPI' Level-Zero Extension APIs for PCI Properties #if !defined(__GNUC__) #pragma region PCIProperties #endif /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_PCI_PROPERTIES_EXT_NAME /// @brief PCI Properties Extension Name #define ZE_PCI_PROPERTIES_EXT_NAME "ZE_extension_pci_properties" #endif // ZE_PCI_PROPERTIES_EXT_NAME /////////////////////////////////////////////////////////////////////////////// /// @brief PCI Properties Extension Version(s) typedef enum _ze_pci_properties_ext_version_t { ZE_PCI_PROPERTIES_EXT_VERSION_1_0 = ZE_MAKE_VERSION( 1, 0 ),///< version 1.0 ZE_PCI_PROPERTIES_EXT_VERSION_CURRENT = ZE_MAKE_VERSION( 1, 0 ),///< latest known version ZE_PCI_PROPERTIES_EXT_VERSION_FORCE_UINT32 = 0x7fffffff } ze_pci_properties_ext_version_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Device PCI address /// /// @details /// - This structure may be passed to ::zeDevicePciGetPropertiesExt as an /// attribute of ::ze_pci_ext_properties_t. /// - A PCI BDF address is the bus:device:function address of the device and /// is useful for locating the device in the PCI switch fabric. typedef struct _ze_pci_address_ext_t { uint32_t domain; ///< [out] PCI domain number uint32_t bus; ///< [out] PCI BDF bus number uint32_t device; ///< [out] PCI BDF device number uint32_t function; ///< [out] PCI BDF function number } ze_pci_address_ext_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Device PCI speed typedef struct _ze_pci_speed_ext_t { int32_t genVersion; ///< [out] The link generation. A value of -1 means that this property is ///< unknown. int32_t width; ///< [out] The number of lanes. A value of -1 means that this property is ///< unknown. int64_t maxBandwidth; ///< [out] The theoretical maximum bandwidth in bytes/sec (sum of all ///< lanes). A value of -1 means that this property is unknown. } ze_pci_speed_ext_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Static PCI properties typedef struct _ze_pci_ext_properties_t { ze_structure_type_t stype; ///< [in] type of this structure void* pNext; ///< [in,out][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). ze_pci_address_ext_t address; ///< [out] The BDF address ze_pci_speed_ext_t maxSpeed; ///< [out] Fastest port configuration supported by the device (sum of all ///< lanes) } ze_pci_ext_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Get PCI properties - address, max speed /// /// @details /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @remarks /// _Analogues_ /// - None /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hDevice` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pPciProperties` ZE_APIEXPORT ze_result_t ZE_APICALL zeDevicePciGetPropertiesExt( ze_device_handle_t hDevice, ///< [in] handle of the device object. ze_pci_ext_properties_t* pPciProperties ///< [in,out] returns the PCI properties of the device. ); #if !defined(__GNUC__) #pragma endregion #endif // Intel 'oneAPI' Level-Zero Extension APIs for sRGB #if !defined(__GNUC__) #pragma region SRGB #endif /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_SRGB_EXT_NAME /// @brief sRGB Extension Name #define ZE_SRGB_EXT_NAME "ZE_extension_srgb" #endif // ZE_SRGB_EXT_NAME /////////////////////////////////////////////////////////////////////////////// /// @brief sRGB Extension Version(s) typedef enum _ze_srgb_ext_version_t { ZE_SRGB_EXT_VERSION_1_0 = ZE_MAKE_VERSION( 1, 0 ), ///< version 1.0 ZE_SRGB_EXT_VERSION_CURRENT = ZE_MAKE_VERSION( 1, 0 ), ///< latest known version ZE_SRGB_EXT_VERSION_FORCE_UINT32 = 0x7fffffff } ze_srgb_ext_version_t; /////////////////////////////////////////////////////////////////////////////// /// @brief sRGB image descriptor /// /// @details /// - This structure may be passed to ::zeImageCreate via the `pNext` member /// of ::ze_image_desc_t /// - Used for specifying that the image is in sRGB format. typedef struct _ze_srgb_ext_desc_t { ze_structure_type_t stype; ///< [in] type of this structure const void* pNext; ///< [in][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). ze_bool_t sRGB; ///< [in] Is sRGB. } ze_srgb_ext_desc_t; #if !defined(__GNUC__) #pragma endregion #endif // Intel 'oneAPI' Level-Zero Extension APIs for Image Copy To/From Memory #if !defined(__GNUC__) #pragma region imageCopy #endif /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_IMAGE_COPY_EXT_NAME /// @brief Image Copy Extension Name #define ZE_IMAGE_COPY_EXT_NAME "ZE_extension_image_copy" #endif // ZE_IMAGE_COPY_EXT_NAME /////////////////////////////////////////////////////////////////////////////// /// @brief Image Copy Extension Version(s) typedef enum _ze_image_copy_ext_version_t { ZE_IMAGE_COPY_EXT_VERSION_1_0 = ZE_MAKE_VERSION( 1, 0 ),///< version 1.0 ZE_IMAGE_COPY_EXT_VERSION_CURRENT = ZE_MAKE_VERSION( 1, 0 ),///< latest known version ZE_IMAGE_COPY_EXT_VERSION_FORCE_UINT32 = 0x7fffffff } ze_image_copy_ext_version_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Copies from an image to device or shared memory. /// /// @details /// - The application must ensure the memory pointed to by dstptr is /// accessible by the device on which the command list was created. /// - The implementation must not access the memory pointed to by dstptr as /// it is free to be modified by either the Host or device up until /// execution. /// - The application must ensure the image and events are accessible by the /// device on which the command list was created. /// - The application must ensure the image format descriptor for the source /// image is a single-planar format. /// - The application must ensure that the rowPitch is set to 0 if image is /// a 1D image. Otherwise the rowPitch must be greater than or equal to /// the element size in bytes x width. /// - If rowPitch is set to 0, the appropriate row pitch is calculated based /// on the size of each element in bytes multiplied by width /// - The application must ensure that the slicePitch is set to 0 if image /// is a 1D or 2D image. Otherwise this value must be greater than or /// equal to rowPitch x height. /// - If slicePitch is set to 0, the appropriate slice pitch is calculated /// based on the rowPitch x height. /// - The application must ensure the command list, image and events were /// created, and the memory was allocated, on the same context. /// - The application must **not** call this function from simultaneous /// threads with the same command list handle. /// - The implementation of this function should be lock-free. /// /// @remarks /// _Analogues_ /// - clEnqueueReadImage /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hCommandList` /// + `nullptr == hSrcImage` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == dstptr` /// - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT /// - ::ZE_RESULT_ERROR_INVALID_SIZE /// + `(nullptr == phWaitEvents) && (0 < numWaitEvents)` ZE_APIEXPORT ze_result_t ZE_APICALL zeCommandListAppendImageCopyToMemoryExt( ze_command_list_handle_t hCommandList, ///< [in] handle of command list void* dstptr, ///< [in] pointer to destination memory to copy to ze_image_handle_t hSrcImage, ///< [in] handle of source image to copy from const ze_image_region_t* pSrcRegion, ///< [in][optional] source region descriptor uint32_t destRowPitch, ///< [in] size in bytes of the 1D slice of the 2D region of a 2D or 3D ///< image or each image of a 1D or 2D image array being written uint32_t destSlicePitch, ///< [in] size in bytes of the 2D slice of the 3D region of a 3D image or ///< each image of a 1D or 2D image array being written ze_event_handle_t hSignalEvent, ///< [in][optional] handle of the event to signal on completion uint32_t numWaitEvents, ///< [in][optional] number of events to wait on before launching; must be 0 ///< if `nullptr == phWaitEvents` ze_event_handle_t* phWaitEvents ///< [in][optional][range(0, numWaitEvents)] handle of the events to wait ///< on before launching ); /////////////////////////////////////////////////////////////////////////////// /// @brief Copies to an image from device or shared memory. /// /// @details /// - The application must ensure the memory pointed to by srcptr is /// accessible by the device on which the command list was created. /// - The implementation must not access the memory pointed to by srcptr as /// it is free to be modified by either the Host or device up until /// execution. /// - The application must ensure the image and events are accessible by the /// device on which the command list was created. /// - The application must ensure the image format descriptor for the /// destination image is a single-planar format. /// - The application must ensure that the rowPitch is set to 0 if image is /// a 1D image. Otherwise the rowPitch must be greater than or equal to /// the element size in bytes x width. /// - If rowPitch is set to 0, the appropriate row pitch is calculated based /// on the size of each element in bytes multiplied by width /// - The application must ensure that the slicePitch is set to 0 if image /// is a 1D or 2D image. Otherwise this value must be greater than or /// equal to rowPitch x height. /// - If slicePitch is set to 0, the appropriate slice pitch is calculated /// based on the rowPitch x height. /// - The application must ensure the command list, image and events were /// created, and the memory was allocated, on the same context. /// - The application must **not** call this function from simultaneous /// threads with the same command list handle. /// - The implementation of this function should be lock-free. /// /// @remarks /// _Analogues_ /// - clEnqueueWriteImage /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hCommandList` /// + `nullptr == hDstImage` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == srcptr` /// - ::ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT /// - ::ZE_RESULT_ERROR_INVALID_SIZE /// + `(nullptr == phWaitEvents) && (0 < numWaitEvents)` ZE_APIEXPORT ze_result_t ZE_APICALL zeCommandListAppendImageCopyFromMemoryExt( ze_command_list_handle_t hCommandList, ///< [in] handle of command list ze_image_handle_t hDstImage, ///< [in] handle of destination image to copy to const void* srcptr, ///< [in] pointer to source memory to copy from const ze_image_region_t* pDstRegion, ///< [in][optional] destination region descriptor uint32_t srcRowPitch, ///< [in] size in bytes of the 1D slice of the 2D region of a 2D or 3D ///< image or each image of a 1D or 2D image array being read uint32_t srcSlicePitch, ///< [in] size in bytes of the 2D slice of the 3D region of a 3D image or ///< each image of a 1D or 2D image array being read ze_event_handle_t hSignalEvent, ///< [in][optional] handle of the event to signal on completion uint32_t numWaitEvents, ///< [in][optional] number of events to wait on before launching; must be 0 ///< if `nullptr == phWaitEvents` ze_event_handle_t* phWaitEvents ///< [in][optional][range(0, numWaitEvents)] handle of the events to wait ///< on before launching ); #if !defined(__GNUC__) #pragma endregion #endif // Intel 'oneAPI' Level-Zero Extension for Querying Image Allocation Properties. #if !defined(__GNUC__) #pragma region imageQueryAllocProperties #endif /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_IMAGE_QUERY_ALLOC_PROPERTIES_EXT_NAME /// @brief Image Query Allocation Properties Extension Name #define ZE_IMAGE_QUERY_ALLOC_PROPERTIES_EXT_NAME "ZE_extension_image_query_alloc_properties" #endif // ZE_IMAGE_QUERY_ALLOC_PROPERTIES_EXT_NAME /////////////////////////////////////////////////////////////////////////////// /// @brief Image Query Allocation Properties Extension Version(s) typedef enum _ze_image_query_alloc_properties_ext_version_t { ZE_IMAGE_QUERY_ALLOC_PROPERTIES_EXT_VERSION_1_0 = ZE_MAKE_VERSION( 1, 0 ), ///< version 1.0 ZE_IMAGE_QUERY_ALLOC_PROPERTIES_EXT_VERSION_CURRENT = ZE_MAKE_VERSION( 1, 0 ), ///< latest known version ZE_IMAGE_QUERY_ALLOC_PROPERTIES_EXT_VERSION_FORCE_UINT32 = 0x7fffffff } ze_image_query_alloc_properties_ext_version_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Image allocation properties queried using /// ::zeImageGetAllocPropertiesExt typedef struct _ze_image_allocation_ext_properties_t { ze_structure_type_t stype; ///< [in] type of this structure void* pNext; ///< [in,out][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). uint64_t id; ///< [out] identifier for this allocation } ze_image_allocation_ext_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Retrieves attributes of an image allocation /// /// @details /// - The application may call this function from simultaneous threads. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hContext` /// + `nullptr == hImage` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pImageAllocProperties` ZE_APIEXPORT ze_result_t ZE_APICALL zeImageGetAllocPropertiesExt( ze_context_handle_t hContext, ///< [in] handle of the context object ze_image_handle_t hImage, ///< [in] handle of image object to query ze_image_allocation_ext_properties_t* pImageAllocProperties ///< [in,out] query result for image allocation properties ); #if !defined(__GNUC__) #pragma endregion #endif // Intel 'oneAPI' Level-Zero Extension APIs for Linkage Inspection #if !defined(__GNUC__) #pragma region linkageInspection #endif /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_LINKAGE_INSPECTION_EXT_NAME /// @brief Linkage Inspection Extension Name #define ZE_LINKAGE_INSPECTION_EXT_NAME "ZE_extension_linkage_inspection" #endif // ZE_LINKAGE_INSPECTION_EXT_NAME /////////////////////////////////////////////////////////////////////////////// /// @brief Linkage Inspection Extension Version(s) typedef enum _ze_linkage_inspection_ext_version_t { ZE_LINKAGE_INSPECTION_EXT_VERSION_1_0 = ZE_MAKE_VERSION( 1, 0 ),///< version 1.0 ZE_LINKAGE_INSPECTION_EXT_VERSION_CURRENT = ZE_MAKE_VERSION( 1, 0 ),///< latest known version ZE_LINKAGE_INSPECTION_EXT_VERSION_FORCE_UINT32 = 0x7fffffff } ze_linkage_inspection_ext_version_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Supported module linkage inspection flags typedef uint32_t ze_linkage_inspection_ext_flags_t; typedef enum _ze_linkage_inspection_ext_flag_t { ZE_LINKAGE_INSPECTION_EXT_FLAG_IMPORTS = ZE_BIT(0), ///< List all imports of modules ZE_LINKAGE_INSPECTION_EXT_FLAG_UNRESOLVABLE_IMPORTS = ZE_BIT(1),///< List all imports of modules that do not have a corresponding export ZE_LINKAGE_INSPECTION_EXT_FLAG_EXPORTS = ZE_BIT(2), ///< List all exports of modules ZE_LINKAGE_INSPECTION_EXT_FLAG_FORCE_UINT32 = 0x7fffffff } ze_linkage_inspection_ext_flag_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Module linkage inspection descriptor /// /// @details /// - This structure may be passed to ::zeModuleInspectLinkageExt. typedef struct _ze_linkage_inspection_ext_desc_t { ze_structure_type_t stype; ///< [in] type of this structure const void* pNext; ///< [in][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). ze_linkage_inspection_ext_flags_t flags; ///< [in] flags specifying module linkage inspection. ///< must be 0 (default) or a valid combination of ::ze_linkage_inspection_ext_flag_t. } ze_linkage_inspection_ext_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief List Imports & Exports /// /// @details /// - List all the import & unresolveable import dependencies & exports of a /// set of modules /// /// @remarks /// _Analogues_ /// - None /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pInspectDesc` /// + `nullptr == phModules` /// + `nullptr == phLog` /// - ::ZE_RESULT_ERROR_INVALID_ENUMERATION /// + `0x7 < pInspectDesc->flags` ZE_APIEXPORT ze_result_t ZE_APICALL zeModuleInspectLinkageExt( ze_linkage_inspection_ext_desc_t* pInspectDesc, ///< [in] pointer to linkage inspection descriptor structure. uint32_t numModules, ///< [in] number of modules to be inspected pointed to by phModules. ze_module_handle_t* phModules, ///< [in][range(0, numModules)] pointer to an array of modules to be ///< inspected for import dependencies. ze_module_build_log_handle_t* phLog ///< [out] pointer to handle of linkage inspection log. Log object will ///< contain separate lists of imports, un-resolvable imports, and exports. ); #if !defined(__GNUC__) #pragma endregion #endif // Intel 'oneAPI' Level-Zero Extension for supporting memory compression hints. #if !defined(__GNUC__) #pragma region memoryCompressionHints #endif /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_MEMORY_COMPRESSION_HINTS_EXT_NAME /// @brief Memory Compression Hints Extension Name #define ZE_MEMORY_COMPRESSION_HINTS_EXT_NAME "ZE_extension_memory_compression_hints" #endif // ZE_MEMORY_COMPRESSION_HINTS_EXT_NAME /////////////////////////////////////////////////////////////////////////////// /// @brief Memory Compression Hints Extension Version(s) typedef enum _ze_memory_compression_hints_ext_version_t { ZE_MEMORY_COMPRESSION_HINTS_EXT_VERSION_1_0 = ZE_MAKE_VERSION( 1, 0 ), ///< version 1.0 ZE_MEMORY_COMPRESSION_HINTS_EXT_VERSION_CURRENT = ZE_MAKE_VERSION( 1, 0 ), ///< latest known version ZE_MEMORY_COMPRESSION_HINTS_EXT_VERSION_FORCE_UINT32 = 0x7fffffff } ze_memory_compression_hints_ext_version_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Supported memory compression hints flags typedef uint32_t ze_memory_compression_hints_ext_flags_t; typedef enum _ze_memory_compression_hints_ext_flag_t { ZE_MEMORY_COMPRESSION_HINTS_EXT_FLAG_COMPRESSED = ZE_BIT(0),///< Hint Driver implementation to make allocation compressible ZE_MEMORY_COMPRESSION_HINTS_EXT_FLAG_UNCOMPRESSED = ZE_BIT(1), ///< Hint Driver implementation to make allocation not compressible ZE_MEMORY_COMPRESSION_HINTS_EXT_FLAG_FORCE_UINT32 = 0x7fffffff } ze_memory_compression_hints_ext_flag_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Compression hints memory allocation descriptor /// /// @details /// - This structure may be passed to ::zeMemAllocShared or /// ::zeMemAllocDevice, via `pNext` member of /// ::ze_device_mem_alloc_desc_t. /// - This structure may be passed to ::zeMemAllocHost, via `pNext` member /// of ::ze_host_mem_alloc_desc_t. /// - This structure may be passed to ::zeImageCreate, via `pNext` member of /// ::ze_image_desc_t. typedef struct _ze_memory_compression_hints_ext_desc_t { ze_structure_type_t stype; ///< [in] type of this structure const void* pNext; ///< [in][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). ze_memory_compression_hints_ext_flags_t flags; ///< [in] flags specifying if allocation should be compressible or not. ///< Must be set to one of the ::ze_memory_compression_hints_ext_flag_t; } ze_memory_compression_hints_ext_desc_t; #if !defined(__GNUC__) #pragma endregion #endif // Intel 'oneAPI' Level-Zero Extension APIs for Memory Free Policies #if !defined(__GNUC__) #pragma region memoryFreePolicies #endif /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_MEMORY_FREE_POLICIES_EXT_NAME /// @brief Memory Free Policies Extension Name #define ZE_MEMORY_FREE_POLICIES_EXT_NAME "ZE_extension_memory_free_policies" #endif // ZE_MEMORY_FREE_POLICIES_EXT_NAME /////////////////////////////////////////////////////////////////////////////// /// @brief Memory Free Policies Extension Version(s) typedef enum _ze_memory_free_policies_ext_version_t { ZE_MEMORY_FREE_POLICIES_EXT_VERSION_1_0 = ZE_MAKE_VERSION( 1, 0 ), ///< version 1.0 ZE_MEMORY_FREE_POLICIES_EXT_VERSION_CURRENT = ZE_MAKE_VERSION( 1, 0 ), ///< latest known version ZE_MEMORY_FREE_POLICIES_EXT_VERSION_FORCE_UINT32 = 0x7fffffff } ze_memory_free_policies_ext_version_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Supported memory free policy capability flags typedef uint32_t ze_driver_memory_free_policy_ext_flags_t; typedef enum _ze_driver_memory_free_policy_ext_flag_t { ZE_DRIVER_MEMORY_FREE_POLICY_EXT_FLAG_BLOCKING_FREE = ZE_BIT(0),///< blocks until all commands using the memory are complete before freeing ZE_DRIVER_MEMORY_FREE_POLICY_EXT_FLAG_DEFER_FREE = ZE_BIT(1), ///< schedules the memory to be freed but does not free immediately ZE_DRIVER_MEMORY_FREE_POLICY_EXT_FLAG_FORCE_UINT32 = 0x7fffffff } ze_driver_memory_free_policy_ext_flag_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Driver memory free properties queried using ::zeDriverGetProperties /// /// @details /// - All drivers must support an immediate free policy, which is the /// default free policy. /// - This structure may be returned from ::zeDriverGetProperties, via /// `pNext` member of ::ze_driver_properties_t. typedef struct _ze_driver_memory_free_ext_properties_t { ze_structure_type_t stype; ///< [in] type of this structure void* pNext; ///< [in,out][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). ze_driver_memory_free_policy_ext_flags_t freePolicies; ///< [out] Supported memory free policies. ///< must be 0 or a combination of ::ze_driver_memory_free_policy_ext_flag_t. } ze_driver_memory_free_ext_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Memory free descriptor with free policy typedef struct _ze_memory_free_ext_desc_t { ze_structure_type_t stype; ///< [in] type of this structure const void* pNext; ///< [in][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). ze_driver_memory_free_policy_ext_flags_t freePolicy;///< [in] flags specifying the memory free policy. ///< must be 0 (default) or a supported ::ze_driver_memory_free_policy_ext_flag_t; ///< default behavior is to free immediately. } ze_memory_free_ext_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Frees allocated host memory, device memory, or shared memory using the /// specified free policy. /// /// @details /// - The memory free policy is specified by the memory free descriptor. /// - The application must **not** call this function from simultaneous /// threads with the same pointer. /// - The implementation of this function must be thread-safe. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hContext` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pMemFreeDesc` /// + `nullptr == ptr` /// - ::ZE_RESULT_ERROR_INVALID_ENUMERATION /// + `0x3 < pMemFreeDesc->freePolicy` ZE_APIEXPORT ze_result_t ZE_APICALL zeMemFreeExt( ze_context_handle_t hContext, ///< [in] handle of the context object const ze_memory_free_ext_desc_t* pMemFreeDesc, ///< [in] pointer to memory free descriptor void* ptr ///< [in][release] pointer to memory to free ); #if !defined(__GNUC__) #pragma endregion #endif // Intel 'oneAPI' Level-Zero Extension APIs for Bandwidth #if !defined(__GNUC__) #pragma region bandwidth #endif /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_BANDWIDTH_PROPERTIES_EXP_NAME /// @brief Bandwidth Extension Name #define ZE_BANDWIDTH_PROPERTIES_EXP_NAME "ZE_experimental_bandwidth_properties" #endif // ZE_BANDWIDTH_PROPERTIES_EXP_NAME /////////////////////////////////////////////////////////////////////////////// /// @brief P2P Bandwidth Properties /// /// @details /// - This structure may be passed to ::zeDeviceGetP2PProperties by having /// the pNext member of ::ze_device_p2p_properties_t point at this struct. typedef struct _ze_device_p2p_bandwidth_exp_properties_t { ze_structure_type_t stype; ///< [in] type of this structure void* pNext; ///< [in,out][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). uint32_t logicalBandwidth; ///< [out] total logical design bandwidth for all links connecting the two ///< devices uint32_t physicalBandwidth; ///< [out] total physical design bandwidth for all links connecting the two ///< devices ze_bandwidth_unit_t bandwidthUnit; ///< [out] bandwidth unit uint32_t logicalLatency; ///< [out] average logical design latency for all links connecting the two ///< devices uint32_t physicalLatency; ///< [out] average physical design latency for all links connecting the two ///< devices ze_latency_unit_t latencyUnit; ///< [out] latency unit } ze_device_p2p_bandwidth_exp_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Copy Bandwidth Properties /// /// @details /// - This structure may be passed to /// ::zeDeviceGetCommandQueueGroupProperties by having the pNext member of /// ::ze_command_queue_group_properties_t point at this struct. typedef struct _ze_copy_bandwidth_exp_properties_t { ze_structure_type_t stype; ///< [in] type of this structure void* pNext; ///< [in,out][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). uint32_t copyBandwidth; ///< [out] design bandwidth supported by this engine type for copy ///< operations ze_bandwidth_unit_t copyBandwidthUnit; ///< [out] copy bandwidth unit } ze_copy_bandwidth_exp_properties_t; #if !defined(__GNUC__) #pragma endregion #endif // Intel 'oneAPI' Level-Zero Extension APIs for Device Local Identifier (LUID) #if !defined(__GNUC__) #pragma region deviceLUID #endif /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_DEVICE_LUID_EXT_NAME /// @brief Device Local Identifier (LUID) Extension Name #define ZE_DEVICE_LUID_EXT_NAME "ZE_extension_device_luid" #endif // ZE_DEVICE_LUID_EXT_NAME /////////////////////////////////////////////////////////////////////////////// /// @brief Device Local Identifier (LUID) Extension Version(s) typedef enum _ze_device_luid_ext_version_t { ZE_DEVICE_LUID_EXT_VERSION_1_0 = ZE_MAKE_VERSION( 1, 0 ), ///< version 1.0 ZE_DEVICE_LUID_EXT_VERSION_CURRENT = ZE_MAKE_VERSION( 1, 0 ), ///< latest known version ZE_DEVICE_LUID_EXT_VERSION_FORCE_UINT32 = 0x7fffffff } ze_device_luid_ext_version_t; /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_MAX_DEVICE_LUID_SIZE_EXT /// @brief Maximum device local identifier (LUID) size in bytes #define ZE_MAX_DEVICE_LUID_SIZE_EXT 8 #endif // ZE_MAX_DEVICE_LUID_SIZE_EXT /////////////////////////////////////////////////////////////////////////////// /// @brief Device local identifier (LUID) typedef struct _ze_device_luid_ext_t { uint8_t id[ZE_MAX_DEVICE_LUID_SIZE_EXT]; ///< [out] opaque data representing a device LUID } ze_device_luid_ext_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Device LUID properties queried using ::zeDeviceGetProperties /// /// @details /// - This structure may be returned from ::zeDeviceGetProperties, via /// `pNext` member of ::ze_device_properties_t. typedef struct _ze_device_luid_ext_properties_t { ze_structure_type_t stype; ///< [in] type of this structure void* pNext; ///< [in,out][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). ze_device_luid_ext_t luid; ///< [out] locally unique identifier (LUID). ///< The returned LUID can be cast to a LUID object and must be equal to ///< the locally ///< unique identifier of an IDXGIAdapter1 object that corresponds to the device. uint32_t nodeMask; ///< [out] node mask. ///< The returned node mask must contain exactly one bit. ///< If the device is running on an operating system that supports the ///< Direct3D 12 API ///< and the device corresponds to an individual device in a linked device ///< adapter, the ///< returned node mask identifies the Direct3D 12 node corresponding to ///< the device. ///< Otherwise, the returned node mask must be 1. } ze_device_luid_ext_properties_t; #if !defined(__GNUC__) #pragma endregion #endif // Intel 'oneAPI' Level-Zero Extension APIs for Fabric Topology Discovery #if !defined(__GNUC__) #pragma region fabric #endif /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_FABRIC_EXP_NAME /// @brief Fabric Topology Discovery Extension Name #define ZE_FABRIC_EXP_NAME "ZE_experimental_fabric" #endif // ZE_FABRIC_EXP_NAME /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_MAX_FABRIC_EDGE_MODEL_EXP_SIZE /// @brief Maximum fabric edge model string size #define ZE_MAX_FABRIC_EDGE_MODEL_EXP_SIZE 256 #endif // ZE_MAX_FABRIC_EDGE_MODEL_EXP_SIZE /////////////////////////////////////////////////////////////////////////////// /// @brief Fabric Vertex types typedef enum _ze_fabric_vertex_exp_type_t { ZE_FABRIC_VERTEX_EXP_TYPE_UNKNOWN = 0, ///< Fabric vertex type is unknown ZE_FABRIC_VERTEX_EXP_TYPE_DEVICE = 1, ///< Fabric vertex represents a device ZE_FABRIC_VERTEX_EXP_TYPE_SUBDEVICE = 2, ///< Fabric vertex represents a subdevice ZE_FABRIC_VERTEX_EXP_TYPE_SWITCH = 3, ///< Fabric vertex represents a switch ZE_FABRIC_VERTEX_EXP_TYPE_FORCE_UINT32 = 0x7fffffff } ze_fabric_vertex_exp_type_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Fabric edge duplexity typedef enum _ze_fabric_edge_exp_duplexity_t { ZE_FABRIC_EDGE_EXP_DUPLEXITY_UNKNOWN = 0, ///< Fabric edge duplexity is unknown ZE_FABRIC_EDGE_EXP_DUPLEXITY_HALF_DUPLEX = 1, ///< Fabric edge is half duplex, i.e. stated bandwidth is obtained in only ///< one direction at time ZE_FABRIC_EDGE_EXP_DUPLEXITY_FULL_DUPLEX = 2, ///< Fabric edge is full duplex, i.e. stated bandwidth is supported in both ///< directions simultaneously ZE_FABRIC_EDGE_EXP_DUPLEXITY_FORCE_UINT32 = 0x7fffffff } ze_fabric_edge_exp_duplexity_t; /////////////////////////////////////////////////////////////////////////////// /// @brief PCI address /// /// @details /// - A PCI BDF address is the bus:device:function address of the device and /// is useful for locating the device in the PCI switch fabric. typedef struct _ze_fabric_vertex_pci_exp_address_t { uint32_t domain; ///< [out] PCI domain number uint32_t bus; ///< [out] PCI BDF bus number uint32_t device; ///< [out] PCI BDF device number uint32_t function; ///< [out] PCI BDF function number } ze_fabric_vertex_pci_exp_address_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Fabric Vertex properties typedef struct _ze_fabric_vertex_exp_properties_t { ze_structure_type_t stype; ///< [in] type of this structure void* pNext; ///< [in,out][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). ze_uuid_t uuid; ///< [out] universal unique identifier. If the vertex is co-located with a ///< device/subdevice, then this uuid will match that of the corresponding ///< device/subdevice ze_fabric_vertex_exp_type_t type; ///< [out] does the fabric vertex represent a device, subdevice, or switch? ze_bool_t remote; ///< [out] does the fabric vertex live on the local node or on a remote ///< node? ze_fabric_vertex_pci_exp_address_t address; ///< [out] B/D/F address of fabric vertex & associated device/subdevice if ///< available } ze_fabric_vertex_exp_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Fabric Edge properties typedef struct _ze_fabric_edge_exp_properties_t { ze_structure_type_t stype; ///< [in] type of this structure void* pNext; ///< [in,out][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). ze_uuid_t uuid; ///< [out] universal unique identifier. char model[ZE_MAX_FABRIC_EDGE_MODEL_EXP_SIZE]; ///< [out] Description of fabric edge technology. Will be set to the string ///< "unkown" if this cannot be determined for this edge uint32_t bandwidth; ///< [out] design bandwidth ze_bandwidth_unit_t bandwidthUnit; ///< [out] bandwidth unit uint32_t latency; ///< [out] design latency ze_latency_unit_t latencyUnit; ///< [out] latency unit ze_fabric_edge_exp_duplexity_t duplexity; ///< [out] Duplexity of the fabric edge } ze_fabric_edge_exp_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Retrieves fabric vertices within a driver /// /// @details /// - A fabric vertex represents either a device or a switch connected to /// other fabric vertices. /// - The application may call this function from simultaneous threads. /// - The implementation of this function must be thread-safe. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hDriver` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pCount` ZE_APIEXPORT ze_result_t ZE_APICALL zeFabricVertexGetExp( ze_driver_handle_t hDriver, ///< [in] handle of the driver instance uint32_t* pCount, ///< [in,out] pointer to the number of fabric vertices. ///< if count is zero, then the driver shall update the value with the ///< total number of fabric vertices available. ///< if count is greater than the number of fabric vertices available, then ///< the driver shall update the value with the correct number of fabric ///< vertices available. ze_fabric_vertex_handle_t* phVertices ///< [in,out][optional][range(0, *pCount)] array of handle of fabric vertices. ///< if count is less than the number of fabric vertices available, then ///< driver shall only retrieve that number of fabric vertices. ); /////////////////////////////////////////////////////////////////////////////// /// @brief Retrieves a fabric sub-vertex from a fabric vertex /// /// @details /// - Multiple calls to this function will return identical fabric vertex /// handles, in the same order. /// - The number of handles returned from this function is affected by the /// ::ZE_AFFINITY_MASK environment variable. /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hVertex` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pCount` ZE_APIEXPORT ze_result_t ZE_APICALL zeFabricVertexGetSubVerticesExp( ze_fabric_vertex_handle_t hVertex, ///< [in] handle of the fabric vertex object uint32_t* pCount, ///< [in,out] pointer to the number of sub-vertices. ///< if count is zero, then the driver shall update the value with the ///< total number of sub-vertices available. ///< if count is greater than the number of sub-vertices available, then ///< the driver shall update the value with the correct number of ///< sub-vertices available. ze_fabric_vertex_handle_t* phSubvertices ///< [in,out][optional][range(0, *pCount)] array of handle of sub-vertices. ///< if count is less than the number of sub-vertices available, then ///< driver shall only retrieve that number of sub-vertices. ); /////////////////////////////////////////////////////////////////////////////// /// @brief Retrieves properties of the fabric vertex. /// /// @details /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hVertex` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pVertexProperties` ZE_APIEXPORT ze_result_t ZE_APICALL zeFabricVertexGetPropertiesExp( ze_fabric_vertex_handle_t hVertex, ///< [in] handle of the fabric vertex ze_fabric_vertex_exp_properties_t* pVertexProperties///< [in,out] query result for fabric vertex properties ); /////////////////////////////////////////////////////////////////////////////// /// @brief Returns device handle from fabric vertex handle. /// /// @details /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hVertex` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == phDevice` /// - ::ZE_RESULT_EXP_ERROR_VERTEX_IS_NOT_DEVICE /// + Provided fabric vertex handle does not correspond to a device or subdevice. /// - ::ZE_RESULT_EXP_ERROR_REMOTE_DEVICE /// + Provided fabric vertex handle corresponds to remote device or subdevice. ZE_APIEXPORT ze_result_t ZE_APICALL zeFabricVertexGetDeviceExp( ze_fabric_vertex_handle_t hVertex, ///< [in] handle of the fabric vertex ze_device_handle_t* phDevice ///< [out] device handle corresponding to fabric vertex ); /////////////////////////////////////////////////////////////////////////////// /// @brief Returns fabric vertex handle from device handle. /// /// @details /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hDevice` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == phVertex` /// - ::ZE_RESULT_EXP_ERROR_DEVICE_IS_NOT_VERTEX /// + Provided device handle does not correspond to a fabric vertex. ZE_APIEXPORT ze_result_t ZE_APICALL zeDeviceGetFabricVertexExp( ze_device_handle_t hDevice, ///< [in] handle of the device ze_fabric_vertex_handle_t* phVertex ///< [out] fabric vertex handle corresponding to device ); /////////////////////////////////////////////////////////////////////////////// /// @brief Retrieves all fabric edges between provided pair of fabric vertices /// /// @details /// - A fabric edge represents one or more physical links between two fabric /// vertices. /// - The application may call this function from simultaneous threads. /// - The implementation of this function must be thread-safe. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hVertexA` /// + `nullptr == hVertexB` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pCount` ZE_APIEXPORT ze_result_t ZE_APICALL zeFabricEdgeGetExp( ze_fabric_vertex_handle_t hVertexA, ///< [in] handle of first fabric vertex instance ze_fabric_vertex_handle_t hVertexB, ///< [in] handle of second fabric vertex instance uint32_t* pCount, ///< [in,out] pointer to the number of fabric edges. ///< if count is zero, then the driver shall update the value with the ///< total number of fabric edges available. ///< if count is greater than the number of fabric edges available, then ///< the driver shall update the value with the correct number of fabric ///< edges available. ze_fabric_edge_handle_t* phEdges ///< [in,out][optional][range(0, *pCount)] array of handle of fabric edges. ///< if count is less than the number of fabric edges available, then ///< driver shall only retrieve that number of fabric edges. ); /////////////////////////////////////////////////////////////////////////////// /// @brief Retrieves fabric vertices connected by a fabric edge /// /// @details /// - A fabric vertex represents either a device or a switch connected to /// other fabric vertices via a fabric edge. /// - The application may call this function from simultaneous threads. /// - The implementation of this function must be thread-safe. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hEdge` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == phVertexA` /// + `nullptr == phVertexB` ZE_APIEXPORT ze_result_t ZE_APICALL zeFabricEdgeGetVerticesExp( ze_fabric_edge_handle_t hEdge, ///< [in] handle of the fabric edge instance ze_fabric_vertex_handle_t* phVertexA, ///< [out] fabric vertex connected to one end of the given fabric edge. ze_fabric_vertex_handle_t* phVertexB ///< [out] fabric vertex connected to other end of the given fabric edge. ); /////////////////////////////////////////////////////////////////////////////// /// @brief Retrieves properties of the fabric edge. /// /// @details /// - The application may call this function from simultaneous threads. /// - The implementation of this function should be lock-free. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hEdge` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pEdgeProperties` ZE_APIEXPORT ze_result_t ZE_APICALL zeFabricEdgeGetPropertiesExp( ze_fabric_edge_handle_t hEdge, ///< [in] handle of the fabric edge ze_fabric_edge_exp_properties_t* pEdgeProperties///< [in,out] query result for fabric edge properties ); #if !defined(__GNUC__) #pragma endregion #endif // Intel 'oneAPI' Level-Zero Extension APIs for Device Memory Properties #if !defined(__GNUC__) #pragma region memoryProperties #endif /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_DEVICE_MEMORY_PROPERTIES_EXT_NAME /// @brief Device Memory Properties Extension Name #define ZE_DEVICE_MEMORY_PROPERTIES_EXT_NAME "ZE_extension_device_memory_properties" #endif // ZE_DEVICE_MEMORY_PROPERTIES_EXT_NAME /////////////////////////////////////////////////////////////////////////////// /// @brief Device Memory Properties Extension Version(s) typedef enum _ze_device_memory_properties_ext_version_t { ZE_DEVICE_MEMORY_PROPERTIES_EXT_VERSION_1_0 = ZE_MAKE_VERSION( 1, 0 ), ///< version 1.0 ZE_DEVICE_MEMORY_PROPERTIES_EXT_VERSION_CURRENT = ZE_MAKE_VERSION( 1, 0 ), ///< latest known version ZE_DEVICE_MEMORY_PROPERTIES_EXT_VERSION_FORCE_UINT32 = 0x7fffffff } ze_device_memory_properties_ext_version_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Memory module types typedef enum _ze_device_memory_ext_type_t { ZE_DEVICE_MEMORY_EXT_TYPE_HBM = 0, ///< HBM memory ZE_DEVICE_MEMORY_EXT_TYPE_HBM2 = 1, ///< HBM2 memory ZE_DEVICE_MEMORY_EXT_TYPE_DDR = 2, ///< DDR memory ZE_DEVICE_MEMORY_EXT_TYPE_DDR2 = 3, ///< DDR2 memory ZE_DEVICE_MEMORY_EXT_TYPE_DDR3 = 4, ///< DDR3 memory ZE_DEVICE_MEMORY_EXT_TYPE_DDR4 = 5, ///< DDR4 memory ZE_DEVICE_MEMORY_EXT_TYPE_DDR5 = 6, ///< DDR5 memory ZE_DEVICE_MEMORY_EXT_TYPE_LPDDR = 7, ///< LPDDR memory ZE_DEVICE_MEMORY_EXT_TYPE_LPDDR3 = 8, ///< LPDDR3 memory ZE_DEVICE_MEMORY_EXT_TYPE_LPDDR4 = 9, ///< LPDDR4 memory ZE_DEVICE_MEMORY_EXT_TYPE_LPDDR5 = 10, ///< LPDDR5 memory ZE_DEVICE_MEMORY_EXT_TYPE_SRAM = 11, ///< SRAM memory ZE_DEVICE_MEMORY_EXT_TYPE_L1 = 12, ///< L1 cache ZE_DEVICE_MEMORY_EXT_TYPE_L3 = 13, ///< L3 cache ZE_DEVICE_MEMORY_EXT_TYPE_GRF = 14, ///< Execution unit register file ZE_DEVICE_MEMORY_EXT_TYPE_SLM = 15, ///< Execution unit shared local memory ZE_DEVICE_MEMORY_EXT_TYPE_GDDR4 = 16, ///< GDDR4 memory ZE_DEVICE_MEMORY_EXT_TYPE_GDDR5 = 17, ///< GDDR5 memory ZE_DEVICE_MEMORY_EXT_TYPE_GDDR5X = 18, ///< GDDR5X memory ZE_DEVICE_MEMORY_EXT_TYPE_GDDR6 = 19, ///< GDDR6 memory ZE_DEVICE_MEMORY_EXT_TYPE_GDDR6X = 20, ///< GDDR6X memory ZE_DEVICE_MEMORY_EXT_TYPE_GDDR7 = 21, ///< GDDR7 memory ZE_DEVICE_MEMORY_EXT_TYPE_FORCE_UINT32 = 0x7fffffff } ze_device_memory_ext_type_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Memory properties /// /// @details /// - This structure may be returned from ::zeDeviceGetMemoryProperties via /// the `pNext` member of ::ze_device_memory_properties_t typedef struct _ze_device_memory_ext_properties_t { ze_structure_type_t stype; ///< [in] type of this structure void* pNext; ///< [in,out][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). ze_device_memory_ext_type_t type; ///< [out] The memory type uint64_t physicalSize; ///< [out] Physical memory size in bytes. A value of 0 indicates that this ///< property is not known. However, a call to $sMemoryGetState() will ///< correctly return the total size of usable memory. uint32_t readBandwidth; ///< [out] Design bandwidth for reads uint32_t writeBandwidth; ///< [out] Design bandwidth for writes ze_bandwidth_unit_t bandwidthUnit; ///< [out] bandwidth unit } ze_device_memory_ext_properties_t; #if !defined(__GNUC__) #pragma endregion #endif // Intel 'oneAPI' Level-Zero Extension APIs for Bfloat16 Conversions #if !defined(__GNUC__) #pragma region bfloat16conversions #endif /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_BFLOAT16_CONVERSIONS_EXT_NAME /// @brief Bfloat16 Conversions Extension Name #define ZE_BFLOAT16_CONVERSIONS_EXT_NAME "ZE_extension_bfloat16_conversions" #endif // ZE_BFLOAT16_CONVERSIONS_EXT_NAME /////////////////////////////////////////////////////////////////////////////// /// @brief Bfloat16 Conversions Extension Version(s) typedef enum _ze_bfloat16_conversions_ext_version_t { ZE_BFLOAT16_CONVERSIONS_EXT_VERSION_1_0 = ZE_MAKE_VERSION( 1, 0 ), ///< version 1.0 ZE_BFLOAT16_CONVERSIONS_EXT_VERSION_CURRENT = ZE_MAKE_VERSION( 1, 0 ), ///< latest known version ZE_BFLOAT16_CONVERSIONS_EXT_VERSION_FORCE_UINT32 = 0x7fffffff } ze_bfloat16_conversions_ext_version_t; #if !defined(__GNUC__) #pragma endregion #endif // Intel 'oneAPI' Level-Zero Extension APIs for Device IP Version #if !defined(__GNUC__) #pragma region deviceipversion #endif /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_DEVICE_IP_VERSION_EXT_NAME /// @brief Device IP Version Extension Name #define ZE_DEVICE_IP_VERSION_EXT_NAME "ZE_extension_device_ip_version" #endif // ZE_DEVICE_IP_VERSION_EXT_NAME /////////////////////////////////////////////////////////////////////////////// /// @brief Device IP Version Extension Version(s) typedef enum _ze_device_ip_version_version_t { ZE_DEVICE_IP_VERSION_VERSION_1_0 = ZE_MAKE_VERSION( 1, 0 ), ///< version 1.0 ZE_DEVICE_IP_VERSION_VERSION_CURRENT = ZE_MAKE_VERSION( 1, 0 ), ///< latest known version ZE_DEVICE_IP_VERSION_VERSION_FORCE_UINT32 = 0x7fffffff } ze_device_ip_version_version_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Device IP version queried using ::zeDeviceGetProperties /// /// @details /// - This structure may be returned from ::zeDeviceGetProperties via /// `pNext` member of ::ze_device_properties_t typedef struct _ze_device_ip_version_ext_t { ze_structure_type_t stype; ///< [in] type of this structure const void* pNext; ///< [in][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). uint32_t ipVersion; ///< [out] Device IP version. The meaning of the device IP version is ///< implementation-defined, but newer devices should have a higher ///< version than older devices. } ze_device_ip_version_ext_t; #if !defined(__GNUC__) #pragma endregion #endif // Intel 'oneAPI' Level-Zero Extension for querying kernel max group size properties. #if !defined(__GNUC__) #pragma region kernelMaxGroupSizeProperties #endif /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_KERNEL_MAX_GROUP_SIZE_PROPERTIES_EXT_NAME /// @brief Kernel Max Group Size Properties Extension Name #define ZE_KERNEL_MAX_GROUP_SIZE_PROPERTIES_EXT_NAME "ZE_extension_kernel_max_group_size_properties" #endif // ZE_KERNEL_MAX_GROUP_SIZE_PROPERTIES_EXT_NAME /////////////////////////////////////////////////////////////////////////////// /// @brief Kernel Max Group Size Properties Extension Version(s) typedef enum _ze_kernel_max_group_size_properties_ext_version_t { ZE_KERNEL_MAX_GROUP_SIZE_PROPERTIES_EXT_VERSION_1_0 = ZE_MAKE_VERSION( 1, 0 ), ///< version 1.0 ZE_KERNEL_MAX_GROUP_SIZE_PROPERTIES_EXT_VERSION_CURRENT = ZE_MAKE_VERSION( 1, 0 ), ///< latest known version ZE_KERNEL_MAX_GROUP_SIZE_PROPERTIES_EXT_VERSION_FORCE_UINT32 = 0x7fffffff } ze_kernel_max_group_size_properties_ext_version_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Additional kernel max group size properties /// /// @details /// - This structure may be passed to ::zeKernelGetProperties, via the /// `pNext` member of ::ze_kernel_properties_t, to query additional kernel /// max group size properties. typedef struct _ze_kernel_max_group_size_properties_ext_t { ze_structure_type_t stype; ///< [in] type of this structure void* pNext; ///< [in,out][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). uint32_t maxGroupSize; ///< [out] maximum group size that can be used to execute the kernel. This ///< value may be less than or equal to the `maxTotalGroupSize` member of ///< ::ze_device_compute_properties_t. } ze_kernel_max_group_size_properties_ext_t; #if !defined(__GNUC__) #pragma endregion #endif // Intel 'oneAPI' Level-Zero Extension for querying sub-allocations properties. #if !defined(__GNUC__) #pragma region subAllocationsProperties #endif /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_SUB_ALLOCATIONS_EXP_NAME /// @brief Sub-Allocations Properties Extension Name #define ZE_SUB_ALLOCATIONS_EXP_NAME "ZE_experimental_sub_allocations" #endif // ZE_SUB_ALLOCATIONS_EXP_NAME /////////////////////////////////////////////////////////////////////////////// /// @brief Sub-Allocations Properties Extension Version(s) typedef enum _ze_sub_allocations_exp_version_t { ZE_SUB_ALLOCATIONS_EXP_VERSION_1_0 = ZE_MAKE_VERSION( 1, 0 ), ///< version 1.0 ZE_SUB_ALLOCATIONS_EXP_VERSION_CURRENT = ZE_MAKE_VERSION( 1, 0 ), ///< latest known version ZE_SUB_ALLOCATIONS_EXP_VERSION_FORCE_UINT32 = 0x7fffffff } ze_sub_allocations_exp_version_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Properties returned for a sub-allocation typedef struct _ze_sub_allocation_t { void* base; ///< [in,out][optional] base address of the sub-allocation size_t size; ///< [in,out][optional] size of the allocation } ze_sub_allocation_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Sub-Allocations Properties /// /// @details /// - This structure may be passed to ::zeMemGetAllocProperties, via `pNext` /// member of ::ze_memory_allocation_properties_t. typedef struct _ze_memory_sub_allocations_exp_properties_t { ze_structure_type_t stype; ///< [in] type of this structure void* pNext; ///< [in,out][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). uint32_t* pCount; ///< [in,out] pointer to the number of sub-allocations. ///< if count is zero, then the driver shall update the value with the ///< total number of sub-allocations on which the allocation has been divided. ///< if count is greater than the number of sub-allocations, then the ///< driver shall update the value with the correct number of sub-allocations. ze_sub_allocation_t* pSubAllocations; ///< [in,out][optional][range(0, *pCount)] array of properties for sub-allocations. ///< if count is less than the number of sub-allocations available, then ///< driver shall only retrieve properties for that number of sub-allocations. } ze_memory_sub_allocations_exp_properties_t; #if !defined(__GNUC__) #pragma endregion #endif // Intel 'oneAPI' Level-Zero Extension for supporting the querying of synchronized event timestamps. #if !defined(__GNUC__) #pragma region eventQueryKernelTimestamps #endif /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_EVENT_QUERY_KERNEL_TIMESTAMPS_EXT_NAME /// @brief Event Query Kernel Timestamps Extension Name #define ZE_EVENT_QUERY_KERNEL_TIMESTAMPS_EXT_NAME "ZE_extension_event_query_kernel_timestamps" #endif // ZE_EVENT_QUERY_KERNEL_TIMESTAMPS_EXT_NAME /////////////////////////////////////////////////////////////////////////////// /// @brief Event Query Kernel Timestamps Extension Version(s) typedef enum _ze_event_query_kernel_timestamps_ext_version_t { ZE_EVENT_QUERY_KERNEL_TIMESTAMPS_EXT_VERSION_1_0 = ZE_MAKE_VERSION( 1, 0 ), ///< version 1.0 ZE_EVENT_QUERY_KERNEL_TIMESTAMPS_EXT_VERSION_CURRENT = ZE_MAKE_VERSION( 1, 0 ), ///< latest known version ZE_EVENT_QUERY_KERNEL_TIMESTAMPS_EXT_VERSION_FORCE_UINT32 = 0x7fffffff } ze_event_query_kernel_timestamps_ext_version_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Event query kernel timestamps flags typedef uint32_t ze_event_query_kernel_timestamps_ext_flags_t; typedef enum _ze_event_query_kernel_timestamps_ext_flag_t { ZE_EVENT_QUERY_KERNEL_TIMESTAMPS_EXT_FLAG_KERNEL = ZE_BIT(0), ///< Kernel timestamp results ZE_EVENT_QUERY_KERNEL_TIMESTAMPS_EXT_FLAG_SYNCHRONIZED = ZE_BIT(1), ///< Device event timestamps synchronized to the host time domain ZE_EVENT_QUERY_KERNEL_TIMESTAMPS_EXT_FLAG_FORCE_UINT32 = 0x7fffffff } ze_event_query_kernel_timestamps_ext_flag_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Event query kernel timestamps properties /// /// @details /// - This structure may be returned from ::zeDeviceGetProperties, via /// `pNext` member of ::ze_device_properties_t. typedef struct _ze_event_query_kernel_timestamps_ext_properties_t { ze_structure_type_t stype; ///< [in] type of this structure void* pNext; ///< [in,out][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). ze_event_query_kernel_timestamps_ext_flags_t flags; ///< [out] 0 or some combination of ///< ::ze_event_query_kernel_timestamps_ext_flag_t flags } ze_event_query_kernel_timestamps_ext_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Kernel timestamp clock data synchronized to the host time domain typedef struct _ze_synchronized_timestamp_data_ext_t { uint64_t kernelStart; ///< [out] synchronized clock at start of kernel execution uint64_t kernelEnd; ///< [out] synchronized clock at end of kernel execution } ze_synchronized_timestamp_data_ext_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Synchronized kernel timestamp result typedef struct _ze_synchronized_timestamp_result_ext_t { ze_synchronized_timestamp_data_ext_t global; ///< [out] wall-clock data ze_synchronized_timestamp_data_ext_t context; ///< [out] context-active data; only includes clocks while device context ///< was actively executing. } ze_synchronized_timestamp_result_ext_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Event query kernel timestamps results properties typedef struct _ze_event_query_kernel_timestamps_results_ext_properties_t { ze_structure_type_t stype; ///< [in] type of this structure void* pNext; ///< [in,out][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). ze_kernel_timestamp_result_t* pKernelTimestampsBuffer; ///< [in,out][optional][range(0, *pCount)] pointer to destination buffer of ///< kernel timestamp results ze_synchronized_timestamp_result_ext_t* pSynchronizedTimestampsBuffer; ///< [in,out][optional][range(0, *pCount)] pointer to destination buffer of ///< synchronized timestamp results } ze_event_query_kernel_timestamps_results_ext_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Query an event's timestamp value on the host, with domain preference. /// /// @details /// - For collecting *only* kernel timestamps, the application must ensure /// the event was created from an event pool that was created using /// ::ZE_EVENT_POOL_FLAG_KERNEL_TIMESTAMP flag. /// - For collecting synchronized timestamps, the application must ensure /// the event was created from an event pool that was created using /// ::ZE_EVENT_POOL_FLAG_KERNEL_MAPPED_TIMESTAMP flag. Kernel timestamps /// are also available from this type of event pool, but there is a /// performance cost. /// - The destination memory will be unmodified if the event has not been /// signaled. /// - The application may call this function from simultaneous threads. /// - The implementation of this function must be thread-safe. /// - The implementation must support /// ::ZE_extension_event_query_kernel_timestamps. /// - The implementation must return all timestamps for the specified event /// and device pair. /// - The implementation must return all timestamps for all sub-devices when /// device handle is parent device. /// - The implementation may return all timestamps for sub-devices when /// device handle is sub-device or may return 0 for count. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hEvent` /// + `nullptr == hDevice` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pCount` ZE_APIEXPORT ze_result_t ZE_APICALL zeEventQueryKernelTimestampsExt( ze_event_handle_t hEvent, ///< [in] handle of the event ze_device_handle_t hDevice, ///< [in] handle of the device to query uint32_t* pCount, ///< [in,out] pointer to the number of event packets available. ///< - This value is implementation specific. ///< - if `*pCount` is zero, then the driver shall update the value with ///< the total number of event packets available. ///< - if `*pCount` is greater than the number of event packets ///< available, the driver shall update the value with the correct value. ///< - Buffer(s) for query results must be sized by the application to ///< accommodate a minimum of `*pCount` elements. ze_event_query_kernel_timestamps_results_ext_properties_t* pResults ///< [in][optional] pointer to event query properties structure(s). ///< - This parameter may be null when `*pCount` is zero. ///< - if `*pCount` is less than the number of event packets available, ///< the driver may only update `*pCount` elements, starting at element zero. ///< - if `*pCount` is greater than the number of event packets ///< available, the driver may only update the valid elements. ); #if !defined(__GNUC__) #pragma endregion #endif // Intel 'oneAPI' Level-Zero API Callbacks #if !defined(__GNUC__) #pragma region callbacks #endif /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeInit /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_init_params_t { ze_init_flags_t* pflags; } ze_init_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeInit /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnInitCb_t)( ze_init_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Table of Global callback functions pointers typedef struct _ze_global_callbacks_t { ze_pfnInitCb_t pfnInitCb; } ze_global_callbacks_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeDriverGet /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_driver_get_params_t { uint32_t** ppCount; ze_driver_handle_t** pphDrivers; } ze_driver_get_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeDriverGet /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnDriverGetCb_t)( ze_driver_get_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeDriverGetApiVersion /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_driver_get_api_version_params_t { ze_driver_handle_t* phDriver; ze_api_version_t** pversion; } ze_driver_get_api_version_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeDriverGetApiVersion /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnDriverGetApiVersionCb_t)( ze_driver_get_api_version_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeDriverGetProperties /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_driver_get_properties_params_t { ze_driver_handle_t* phDriver; ze_driver_properties_t** ppDriverProperties; } ze_driver_get_properties_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeDriverGetProperties /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnDriverGetPropertiesCb_t)( ze_driver_get_properties_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeDriverGetIpcProperties /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_driver_get_ipc_properties_params_t { ze_driver_handle_t* phDriver; ze_driver_ipc_properties_t** ppIpcProperties; } ze_driver_get_ipc_properties_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeDriverGetIpcProperties /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnDriverGetIpcPropertiesCb_t)( ze_driver_get_ipc_properties_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeDriverGetExtensionProperties /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_driver_get_extension_properties_params_t { ze_driver_handle_t* phDriver; uint32_t** ppCount; ze_driver_extension_properties_t** ppExtensionProperties; } ze_driver_get_extension_properties_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeDriverGetExtensionProperties /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnDriverGetExtensionPropertiesCb_t)( ze_driver_get_extension_properties_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Table of Driver callback functions pointers typedef struct _ze_driver_callbacks_t { ze_pfnDriverGetCb_t pfnGetCb; ze_pfnDriverGetApiVersionCb_t pfnGetApiVersionCb; ze_pfnDriverGetPropertiesCb_t pfnGetPropertiesCb; ze_pfnDriverGetIpcPropertiesCb_t pfnGetIpcPropertiesCb; ze_pfnDriverGetExtensionPropertiesCb_t pfnGetExtensionPropertiesCb; } ze_driver_callbacks_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeDeviceGet /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_device_get_params_t { ze_driver_handle_t* phDriver; uint32_t** ppCount; ze_device_handle_t** pphDevices; } ze_device_get_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeDeviceGet /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnDeviceGetCb_t)( ze_device_get_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeDeviceGetSubDevices /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_device_get_sub_devices_params_t { ze_device_handle_t* phDevice; uint32_t** ppCount; ze_device_handle_t** pphSubdevices; } ze_device_get_sub_devices_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeDeviceGetSubDevices /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnDeviceGetSubDevicesCb_t)( ze_device_get_sub_devices_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeDeviceGetProperties /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_device_get_properties_params_t { ze_device_handle_t* phDevice; ze_device_properties_t** ppDeviceProperties; } ze_device_get_properties_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeDeviceGetProperties /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnDeviceGetPropertiesCb_t)( ze_device_get_properties_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeDeviceGetComputeProperties /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_device_get_compute_properties_params_t { ze_device_handle_t* phDevice; ze_device_compute_properties_t** ppComputeProperties; } ze_device_get_compute_properties_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeDeviceGetComputeProperties /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnDeviceGetComputePropertiesCb_t)( ze_device_get_compute_properties_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeDeviceGetModuleProperties /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_device_get_module_properties_params_t { ze_device_handle_t* phDevice; ze_device_module_properties_t** ppModuleProperties; } ze_device_get_module_properties_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeDeviceGetModuleProperties /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnDeviceGetModulePropertiesCb_t)( ze_device_get_module_properties_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeDeviceGetCommandQueueGroupProperties /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_device_get_command_queue_group_properties_params_t { ze_device_handle_t* phDevice; uint32_t** ppCount; ze_command_queue_group_properties_t** ppCommandQueueGroupProperties; } ze_device_get_command_queue_group_properties_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeDeviceGetCommandQueueGroupProperties /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnDeviceGetCommandQueueGroupPropertiesCb_t)( ze_device_get_command_queue_group_properties_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeDeviceGetMemoryProperties /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_device_get_memory_properties_params_t { ze_device_handle_t* phDevice; uint32_t** ppCount; ze_device_memory_properties_t** ppMemProperties; } ze_device_get_memory_properties_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeDeviceGetMemoryProperties /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnDeviceGetMemoryPropertiesCb_t)( ze_device_get_memory_properties_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeDeviceGetMemoryAccessProperties /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_device_get_memory_access_properties_params_t { ze_device_handle_t* phDevice; ze_device_memory_access_properties_t** ppMemAccessProperties; } ze_device_get_memory_access_properties_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeDeviceGetMemoryAccessProperties /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnDeviceGetMemoryAccessPropertiesCb_t)( ze_device_get_memory_access_properties_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeDeviceGetCacheProperties /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_device_get_cache_properties_params_t { ze_device_handle_t* phDevice; uint32_t** ppCount; ze_device_cache_properties_t** ppCacheProperties; } ze_device_get_cache_properties_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeDeviceGetCacheProperties /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnDeviceGetCachePropertiesCb_t)( ze_device_get_cache_properties_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeDeviceGetImageProperties /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_device_get_image_properties_params_t { ze_device_handle_t* phDevice; ze_device_image_properties_t** ppImageProperties; } ze_device_get_image_properties_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeDeviceGetImageProperties /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnDeviceGetImagePropertiesCb_t)( ze_device_get_image_properties_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeDeviceGetExternalMemoryProperties /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_device_get_external_memory_properties_params_t { ze_device_handle_t* phDevice; ze_device_external_memory_properties_t** ppExternalMemoryProperties; } ze_device_get_external_memory_properties_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeDeviceGetExternalMemoryProperties /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnDeviceGetExternalMemoryPropertiesCb_t)( ze_device_get_external_memory_properties_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeDeviceGetP2PProperties /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_device_get_p2_p_properties_params_t { ze_device_handle_t* phDevice; ze_device_handle_t* phPeerDevice; ze_device_p2p_properties_t** ppP2PProperties; } ze_device_get_p2_p_properties_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeDeviceGetP2PProperties /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnDeviceGetP2PPropertiesCb_t)( ze_device_get_p2_p_properties_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeDeviceCanAccessPeer /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_device_can_access_peer_params_t { ze_device_handle_t* phDevice; ze_device_handle_t* phPeerDevice; ze_bool_t** pvalue; } ze_device_can_access_peer_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeDeviceCanAccessPeer /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnDeviceCanAccessPeerCb_t)( ze_device_can_access_peer_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeDeviceGetStatus /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_device_get_status_params_t { ze_device_handle_t* phDevice; } ze_device_get_status_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeDeviceGetStatus /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnDeviceGetStatusCb_t)( ze_device_get_status_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Table of Device callback functions pointers typedef struct _ze_device_callbacks_t { ze_pfnDeviceGetCb_t pfnGetCb; ze_pfnDeviceGetSubDevicesCb_t pfnGetSubDevicesCb; ze_pfnDeviceGetPropertiesCb_t pfnGetPropertiesCb; ze_pfnDeviceGetComputePropertiesCb_t pfnGetComputePropertiesCb; ze_pfnDeviceGetModulePropertiesCb_t pfnGetModulePropertiesCb; ze_pfnDeviceGetCommandQueueGroupPropertiesCb_t pfnGetCommandQueueGroupPropertiesCb; ze_pfnDeviceGetMemoryPropertiesCb_t pfnGetMemoryPropertiesCb; ze_pfnDeviceGetMemoryAccessPropertiesCb_t pfnGetMemoryAccessPropertiesCb; ze_pfnDeviceGetCachePropertiesCb_t pfnGetCachePropertiesCb; ze_pfnDeviceGetImagePropertiesCb_t pfnGetImagePropertiesCb; ze_pfnDeviceGetExternalMemoryPropertiesCb_t pfnGetExternalMemoryPropertiesCb; ze_pfnDeviceGetP2PPropertiesCb_t pfnGetP2PPropertiesCb; ze_pfnDeviceCanAccessPeerCb_t pfnCanAccessPeerCb; ze_pfnDeviceGetStatusCb_t pfnGetStatusCb; } ze_device_callbacks_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeContextCreate /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_context_create_params_t { ze_driver_handle_t* phDriver; const ze_context_desc_t** pdesc; ze_context_handle_t** pphContext; } ze_context_create_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeContextCreate /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnContextCreateCb_t)( ze_context_create_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeContextDestroy /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_context_destroy_params_t { ze_context_handle_t* phContext; } ze_context_destroy_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeContextDestroy /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnContextDestroyCb_t)( ze_context_destroy_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeContextGetStatus /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_context_get_status_params_t { ze_context_handle_t* phContext; } ze_context_get_status_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeContextGetStatus /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnContextGetStatusCb_t)( ze_context_get_status_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeContextSystemBarrier /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_context_system_barrier_params_t { ze_context_handle_t* phContext; ze_device_handle_t* phDevice; } ze_context_system_barrier_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeContextSystemBarrier /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnContextSystemBarrierCb_t)( ze_context_system_barrier_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeContextMakeMemoryResident /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_context_make_memory_resident_params_t { ze_context_handle_t* phContext; ze_device_handle_t* phDevice; void** pptr; size_t* psize; } ze_context_make_memory_resident_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeContextMakeMemoryResident /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnContextMakeMemoryResidentCb_t)( ze_context_make_memory_resident_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeContextEvictMemory /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_context_evict_memory_params_t { ze_context_handle_t* phContext; ze_device_handle_t* phDevice; void** pptr; size_t* psize; } ze_context_evict_memory_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeContextEvictMemory /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnContextEvictMemoryCb_t)( ze_context_evict_memory_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeContextMakeImageResident /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_context_make_image_resident_params_t { ze_context_handle_t* phContext; ze_device_handle_t* phDevice; ze_image_handle_t* phImage; } ze_context_make_image_resident_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeContextMakeImageResident /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnContextMakeImageResidentCb_t)( ze_context_make_image_resident_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeContextEvictImage /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_context_evict_image_params_t { ze_context_handle_t* phContext; ze_device_handle_t* phDevice; ze_image_handle_t* phImage; } ze_context_evict_image_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeContextEvictImage /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnContextEvictImageCb_t)( ze_context_evict_image_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Table of Context callback functions pointers typedef struct _ze_context_callbacks_t { ze_pfnContextCreateCb_t pfnCreateCb; ze_pfnContextDestroyCb_t pfnDestroyCb; ze_pfnContextGetStatusCb_t pfnGetStatusCb; ze_pfnContextSystemBarrierCb_t pfnSystemBarrierCb; ze_pfnContextMakeMemoryResidentCb_t pfnMakeMemoryResidentCb; ze_pfnContextEvictMemoryCb_t pfnEvictMemoryCb; ze_pfnContextMakeImageResidentCb_t pfnMakeImageResidentCb; ze_pfnContextEvictImageCb_t pfnEvictImageCb; } ze_context_callbacks_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeCommandQueueCreate /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_command_queue_create_params_t { ze_context_handle_t* phContext; ze_device_handle_t* phDevice; const ze_command_queue_desc_t** pdesc; ze_command_queue_handle_t** pphCommandQueue; } ze_command_queue_create_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeCommandQueueCreate /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnCommandQueueCreateCb_t)( ze_command_queue_create_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeCommandQueueDestroy /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_command_queue_destroy_params_t { ze_command_queue_handle_t* phCommandQueue; } ze_command_queue_destroy_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeCommandQueueDestroy /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnCommandQueueDestroyCb_t)( ze_command_queue_destroy_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeCommandQueueExecuteCommandLists /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_command_queue_execute_command_lists_params_t { ze_command_queue_handle_t* phCommandQueue; uint32_t* pnumCommandLists; ze_command_list_handle_t** pphCommandLists; ze_fence_handle_t* phFence; } ze_command_queue_execute_command_lists_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeCommandQueueExecuteCommandLists /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnCommandQueueExecuteCommandListsCb_t)( ze_command_queue_execute_command_lists_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeCommandQueueSynchronize /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_command_queue_synchronize_params_t { ze_command_queue_handle_t* phCommandQueue; uint64_t* ptimeout; } ze_command_queue_synchronize_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeCommandQueueSynchronize /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnCommandQueueSynchronizeCb_t)( ze_command_queue_synchronize_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Table of CommandQueue callback functions pointers typedef struct _ze_command_queue_callbacks_t { ze_pfnCommandQueueCreateCb_t pfnCreateCb; ze_pfnCommandQueueDestroyCb_t pfnDestroyCb; ze_pfnCommandQueueExecuteCommandListsCb_t pfnExecuteCommandListsCb; ze_pfnCommandQueueSynchronizeCb_t pfnSynchronizeCb; } ze_command_queue_callbacks_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeCommandListCreate /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_command_list_create_params_t { ze_context_handle_t* phContext; ze_device_handle_t* phDevice; const ze_command_list_desc_t** pdesc; ze_command_list_handle_t** pphCommandList; } ze_command_list_create_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeCommandListCreate /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnCommandListCreateCb_t)( ze_command_list_create_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeCommandListCreateImmediate /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_command_list_create_immediate_params_t { ze_context_handle_t* phContext; ze_device_handle_t* phDevice; const ze_command_queue_desc_t** paltdesc; ze_command_list_handle_t** pphCommandList; } ze_command_list_create_immediate_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeCommandListCreateImmediate /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnCommandListCreateImmediateCb_t)( ze_command_list_create_immediate_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeCommandListDestroy /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_command_list_destroy_params_t { ze_command_list_handle_t* phCommandList; } ze_command_list_destroy_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeCommandListDestroy /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnCommandListDestroyCb_t)( ze_command_list_destroy_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeCommandListClose /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_command_list_close_params_t { ze_command_list_handle_t* phCommandList; } ze_command_list_close_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeCommandListClose /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnCommandListCloseCb_t)( ze_command_list_close_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeCommandListReset /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_command_list_reset_params_t { ze_command_list_handle_t* phCommandList; } ze_command_list_reset_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeCommandListReset /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnCommandListResetCb_t)( ze_command_list_reset_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeCommandListAppendWriteGlobalTimestamp /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_command_list_append_write_global_timestamp_params_t { ze_command_list_handle_t* phCommandList; uint64_t** pdstptr; ze_event_handle_t* phSignalEvent; uint32_t* pnumWaitEvents; ze_event_handle_t** pphWaitEvents; } ze_command_list_append_write_global_timestamp_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeCommandListAppendWriteGlobalTimestamp /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnCommandListAppendWriteGlobalTimestampCb_t)( ze_command_list_append_write_global_timestamp_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeCommandListAppendBarrier /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_command_list_append_barrier_params_t { ze_command_list_handle_t* phCommandList; ze_event_handle_t* phSignalEvent; uint32_t* pnumWaitEvents; ze_event_handle_t** pphWaitEvents; } ze_command_list_append_barrier_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeCommandListAppendBarrier /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnCommandListAppendBarrierCb_t)( ze_command_list_append_barrier_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeCommandListAppendMemoryRangesBarrier /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_command_list_append_memory_ranges_barrier_params_t { ze_command_list_handle_t* phCommandList; uint32_t* pnumRanges; const size_t** ppRangeSizes; const void*** ppRanges; ze_event_handle_t* phSignalEvent; uint32_t* pnumWaitEvents; ze_event_handle_t** pphWaitEvents; } ze_command_list_append_memory_ranges_barrier_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeCommandListAppendMemoryRangesBarrier /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnCommandListAppendMemoryRangesBarrierCb_t)( ze_command_list_append_memory_ranges_barrier_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeCommandListAppendMemoryCopy /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_command_list_append_memory_copy_params_t { ze_command_list_handle_t* phCommandList; void** pdstptr; const void** psrcptr; size_t* psize; ze_event_handle_t* phSignalEvent; uint32_t* pnumWaitEvents; ze_event_handle_t** pphWaitEvents; } ze_command_list_append_memory_copy_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeCommandListAppendMemoryCopy /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnCommandListAppendMemoryCopyCb_t)( ze_command_list_append_memory_copy_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeCommandListAppendMemoryFill /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_command_list_append_memory_fill_params_t { ze_command_list_handle_t* phCommandList; void** pptr; const void** ppattern; size_t* ppattern_size; size_t* psize; ze_event_handle_t* phSignalEvent; uint32_t* pnumWaitEvents; ze_event_handle_t** pphWaitEvents; } ze_command_list_append_memory_fill_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeCommandListAppendMemoryFill /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnCommandListAppendMemoryFillCb_t)( ze_command_list_append_memory_fill_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeCommandListAppendMemoryCopyRegion /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_command_list_append_memory_copy_region_params_t { ze_command_list_handle_t* phCommandList; void** pdstptr; const ze_copy_region_t** pdstRegion; uint32_t* pdstPitch; uint32_t* pdstSlicePitch; const void** psrcptr; const ze_copy_region_t** psrcRegion; uint32_t* psrcPitch; uint32_t* psrcSlicePitch; ze_event_handle_t* phSignalEvent; uint32_t* pnumWaitEvents; ze_event_handle_t** pphWaitEvents; } ze_command_list_append_memory_copy_region_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeCommandListAppendMemoryCopyRegion /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnCommandListAppendMemoryCopyRegionCb_t)( ze_command_list_append_memory_copy_region_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeCommandListAppendMemoryCopyFromContext /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_command_list_append_memory_copy_from_context_params_t { ze_command_list_handle_t* phCommandList; void** pdstptr; ze_context_handle_t* phContextSrc; const void** psrcptr; size_t* psize; ze_event_handle_t* phSignalEvent; uint32_t* pnumWaitEvents; ze_event_handle_t** pphWaitEvents; } ze_command_list_append_memory_copy_from_context_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeCommandListAppendMemoryCopyFromContext /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnCommandListAppendMemoryCopyFromContextCb_t)( ze_command_list_append_memory_copy_from_context_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeCommandListAppendImageCopy /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_command_list_append_image_copy_params_t { ze_command_list_handle_t* phCommandList; ze_image_handle_t* phDstImage; ze_image_handle_t* phSrcImage; ze_event_handle_t* phSignalEvent; uint32_t* pnumWaitEvents; ze_event_handle_t** pphWaitEvents; } ze_command_list_append_image_copy_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeCommandListAppendImageCopy /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnCommandListAppendImageCopyCb_t)( ze_command_list_append_image_copy_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeCommandListAppendImageCopyRegion /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_command_list_append_image_copy_region_params_t { ze_command_list_handle_t* phCommandList; ze_image_handle_t* phDstImage; ze_image_handle_t* phSrcImage; const ze_image_region_t** ppDstRegion; const ze_image_region_t** ppSrcRegion; ze_event_handle_t* phSignalEvent; uint32_t* pnumWaitEvents; ze_event_handle_t** pphWaitEvents; } ze_command_list_append_image_copy_region_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeCommandListAppendImageCopyRegion /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnCommandListAppendImageCopyRegionCb_t)( ze_command_list_append_image_copy_region_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeCommandListAppendImageCopyToMemory /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_command_list_append_image_copy_to_memory_params_t { ze_command_list_handle_t* phCommandList; void** pdstptr; ze_image_handle_t* phSrcImage; const ze_image_region_t** ppSrcRegion; ze_event_handle_t* phSignalEvent; uint32_t* pnumWaitEvents; ze_event_handle_t** pphWaitEvents; } ze_command_list_append_image_copy_to_memory_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeCommandListAppendImageCopyToMemory /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnCommandListAppendImageCopyToMemoryCb_t)( ze_command_list_append_image_copy_to_memory_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeCommandListAppendImageCopyFromMemory /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_command_list_append_image_copy_from_memory_params_t { ze_command_list_handle_t* phCommandList; ze_image_handle_t* phDstImage; const void** psrcptr; const ze_image_region_t** ppDstRegion; ze_event_handle_t* phSignalEvent; uint32_t* pnumWaitEvents; ze_event_handle_t** pphWaitEvents; } ze_command_list_append_image_copy_from_memory_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeCommandListAppendImageCopyFromMemory /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnCommandListAppendImageCopyFromMemoryCb_t)( ze_command_list_append_image_copy_from_memory_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeCommandListAppendMemoryPrefetch /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_command_list_append_memory_prefetch_params_t { ze_command_list_handle_t* phCommandList; const void** pptr; size_t* psize; } ze_command_list_append_memory_prefetch_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeCommandListAppendMemoryPrefetch /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnCommandListAppendMemoryPrefetchCb_t)( ze_command_list_append_memory_prefetch_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeCommandListAppendMemAdvise /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_command_list_append_mem_advise_params_t { ze_command_list_handle_t* phCommandList; ze_device_handle_t* phDevice; const void** pptr; size_t* psize; ze_memory_advice_t* padvice; } ze_command_list_append_mem_advise_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeCommandListAppendMemAdvise /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnCommandListAppendMemAdviseCb_t)( ze_command_list_append_mem_advise_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeCommandListAppendSignalEvent /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_command_list_append_signal_event_params_t { ze_command_list_handle_t* phCommandList; ze_event_handle_t* phEvent; } ze_command_list_append_signal_event_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeCommandListAppendSignalEvent /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnCommandListAppendSignalEventCb_t)( ze_command_list_append_signal_event_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeCommandListAppendWaitOnEvents /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_command_list_append_wait_on_events_params_t { ze_command_list_handle_t* phCommandList; uint32_t* pnumEvents; ze_event_handle_t** pphEvents; } ze_command_list_append_wait_on_events_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeCommandListAppendWaitOnEvents /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnCommandListAppendWaitOnEventsCb_t)( ze_command_list_append_wait_on_events_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeCommandListAppendEventReset /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_command_list_append_event_reset_params_t { ze_command_list_handle_t* phCommandList; ze_event_handle_t* phEvent; } ze_command_list_append_event_reset_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeCommandListAppendEventReset /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnCommandListAppendEventResetCb_t)( ze_command_list_append_event_reset_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeCommandListAppendQueryKernelTimestamps /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_command_list_append_query_kernel_timestamps_params_t { ze_command_list_handle_t* phCommandList; uint32_t* pnumEvents; ze_event_handle_t** pphEvents; void** pdstptr; const size_t** ppOffsets; ze_event_handle_t* phSignalEvent; uint32_t* pnumWaitEvents; ze_event_handle_t** pphWaitEvents; } ze_command_list_append_query_kernel_timestamps_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeCommandListAppendQueryKernelTimestamps /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnCommandListAppendQueryKernelTimestampsCb_t)( ze_command_list_append_query_kernel_timestamps_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeCommandListAppendLaunchKernel /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_command_list_append_launch_kernel_params_t { ze_command_list_handle_t* phCommandList; ze_kernel_handle_t* phKernel; const ze_group_count_t** ppLaunchFuncArgs; ze_event_handle_t* phSignalEvent; uint32_t* pnumWaitEvents; ze_event_handle_t** pphWaitEvents; } ze_command_list_append_launch_kernel_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeCommandListAppendLaunchKernel /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnCommandListAppendLaunchKernelCb_t)( ze_command_list_append_launch_kernel_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeCommandListAppendLaunchCooperativeKernel /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_command_list_append_launch_cooperative_kernel_params_t { ze_command_list_handle_t* phCommandList; ze_kernel_handle_t* phKernel; const ze_group_count_t** ppLaunchFuncArgs; ze_event_handle_t* phSignalEvent; uint32_t* pnumWaitEvents; ze_event_handle_t** pphWaitEvents; } ze_command_list_append_launch_cooperative_kernel_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeCommandListAppendLaunchCooperativeKernel /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnCommandListAppendLaunchCooperativeKernelCb_t)( ze_command_list_append_launch_cooperative_kernel_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeCommandListAppendLaunchKernelIndirect /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_command_list_append_launch_kernel_indirect_params_t { ze_command_list_handle_t* phCommandList; ze_kernel_handle_t* phKernel; const ze_group_count_t** ppLaunchArgumentsBuffer; ze_event_handle_t* phSignalEvent; uint32_t* pnumWaitEvents; ze_event_handle_t** pphWaitEvents; } ze_command_list_append_launch_kernel_indirect_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeCommandListAppendLaunchKernelIndirect /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnCommandListAppendLaunchKernelIndirectCb_t)( ze_command_list_append_launch_kernel_indirect_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeCommandListAppendLaunchMultipleKernelsIndirect /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_command_list_append_launch_multiple_kernels_indirect_params_t { ze_command_list_handle_t* phCommandList; uint32_t* pnumKernels; ze_kernel_handle_t** pphKernels; const uint32_t** ppCountBuffer; const ze_group_count_t** ppLaunchArgumentsBuffer; ze_event_handle_t* phSignalEvent; uint32_t* pnumWaitEvents; ze_event_handle_t** pphWaitEvents; } ze_command_list_append_launch_multiple_kernels_indirect_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeCommandListAppendLaunchMultipleKernelsIndirect /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnCommandListAppendLaunchMultipleKernelsIndirectCb_t)( ze_command_list_append_launch_multiple_kernels_indirect_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Table of CommandList callback functions pointers typedef struct _ze_command_list_callbacks_t { ze_pfnCommandListCreateCb_t pfnCreateCb; ze_pfnCommandListCreateImmediateCb_t pfnCreateImmediateCb; ze_pfnCommandListDestroyCb_t pfnDestroyCb; ze_pfnCommandListCloseCb_t pfnCloseCb; ze_pfnCommandListResetCb_t pfnResetCb; ze_pfnCommandListAppendWriteGlobalTimestampCb_t pfnAppendWriteGlobalTimestampCb; ze_pfnCommandListAppendBarrierCb_t pfnAppendBarrierCb; ze_pfnCommandListAppendMemoryRangesBarrierCb_t pfnAppendMemoryRangesBarrierCb; ze_pfnCommandListAppendMemoryCopyCb_t pfnAppendMemoryCopyCb; ze_pfnCommandListAppendMemoryFillCb_t pfnAppendMemoryFillCb; ze_pfnCommandListAppendMemoryCopyRegionCb_t pfnAppendMemoryCopyRegionCb; ze_pfnCommandListAppendMemoryCopyFromContextCb_t pfnAppendMemoryCopyFromContextCb; ze_pfnCommandListAppendImageCopyCb_t pfnAppendImageCopyCb; ze_pfnCommandListAppendImageCopyRegionCb_t pfnAppendImageCopyRegionCb; ze_pfnCommandListAppendImageCopyToMemoryCb_t pfnAppendImageCopyToMemoryCb; ze_pfnCommandListAppendImageCopyFromMemoryCb_t pfnAppendImageCopyFromMemoryCb; ze_pfnCommandListAppendMemoryPrefetchCb_t pfnAppendMemoryPrefetchCb; ze_pfnCommandListAppendMemAdviseCb_t pfnAppendMemAdviseCb; ze_pfnCommandListAppendSignalEventCb_t pfnAppendSignalEventCb; ze_pfnCommandListAppendWaitOnEventsCb_t pfnAppendWaitOnEventsCb; ze_pfnCommandListAppendEventResetCb_t pfnAppendEventResetCb; ze_pfnCommandListAppendQueryKernelTimestampsCb_t pfnAppendQueryKernelTimestampsCb; ze_pfnCommandListAppendLaunchKernelCb_t pfnAppendLaunchKernelCb; ze_pfnCommandListAppendLaunchCooperativeKernelCb_t pfnAppendLaunchCooperativeKernelCb; ze_pfnCommandListAppendLaunchKernelIndirectCb_t pfnAppendLaunchKernelIndirectCb; ze_pfnCommandListAppendLaunchMultipleKernelsIndirectCb_t pfnAppendLaunchMultipleKernelsIndirectCb; } ze_command_list_callbacks_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeImageGetProperties /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_image_get_properties_params_t { ze_device_handle_t* phDevice; const ze_image_desc_t** pdesc; ze_image_properties_t** ppImageProperties; } ze_image_get_properties_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeImageGetProperties /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnImageGetPropertiesCb_t)( ze_image_get_properties_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeImageCreate /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_image_create_params_t { ze_context_handle_t* phContext; ze_device_handle_t* phDevice; const ze_image_desc_t** pdesc; ze_image_handle_t** pphImage; } ze_image_create_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeImageCreate /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnImageCreateCb_t)( ze_image_create_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeImageDestroy /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_image_destroy_params_t { ze_image_handle_t* phImage; } ze_image_destroy_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeImageDestroy /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnImageDestroyCb_t)( ze_image_destroy_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Table of Image callback functions pointers typedef struct _ze_image_callbacks_t { ze_pfnImageGetPropertiesCb_t pfnGetPropertiesCb; ze_pfnImageCreateCb_t pfnCreateCb; ze_pfnImageDestroyCb_t pfnDestroyCb; } ze_image_callbacks_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeFenceCreate /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_fence_create_params_t { ze_command_queue_handle_t* phCommandQueue; const ze_fence_desc_t** pdesc; ze_fence_handle_t** pphFence; } ze_fence_create_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeFenceCreate /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnFenceCreateCb_t)( ze_fence_create_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeFenceDestroy /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_fence_destroy_params_t { ze_fence_handle_t* phFence; } ze_fence_destroy_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeFenceDestroy /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnFenceDestroyCb_t)( ze_fence_destroy_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeFenceHostSynchronize /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_fence_host_synchronize_params_t { ze_fence_handle_t* phFence; uint64_t* ptimeout; } ze_fence_host_synchronize_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeFenceHostSynchronize /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnFenceHostSynchronizeCb_t)( ze_fence_host_synchronize_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeFenceQueryStatus /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_fence_query_status_params_t { ze_fence_handle_t* phFence; } ze_fence_query_status_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeFenceQueryStatus /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnFenceQueryStatusCb_t)( ze_fence_query_status_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeFenceReset /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_fence_reset_params_t { ze_fence_handle_t* phFence; } ze_fence_reset_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeFenceReset /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnFenceResetCb_t)( ze_fence_reset_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Table of Fence callback functions pointers typedef struct _ze_fence_callbacks_t { ze_pfnFenceCreateCb_t pfnCreateCb; ze_pfnFenceDestroyCb_t pfnDestroyCb; ze_pfnFenceHostSynchronizeCb_t pfnHostSynchronizeCb; ze_pfnFenceQueryStatusCb_t pfnQueryStatusCb; ze_pfnFenceResetCb_t pfnResetCb; } ze_fence_callbacks_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeEventPoolCreate /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_event_pool_create_params_t { ze_context_handle_t* phContext; const ze_event_pool_desc_t** pdesc; uint32_t* pnumDevices; ze_device_handle_t** pphDevices; ze_event_pool_handle_t** pphEventPool; } ze_event_pool_create_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeEventPoolCreate /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnEventPoolCreateCb_t)( ze_event_pool_create_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeEventPoolDestroy /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_event_pool_destroy_params_t { ze_event_pool_handle_t* phEventPool; } ze_event_pool_destroy_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeEventPoolDestroy /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnEventPoolDestroyCb_t)( ze_event_pool_destroy_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeEventPoolGetIpcHandle /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_event_pool_get_ipc_handle_params_t { ze_event_pool_handle_t* phEventPool; ze_ipc_event_pool_handle_t** pphIpc; } ze_event_pool_get_ipc_handle_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeEventPoolGetIpcHandle /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnEventPoolGetIpcHandleCb_t)( ze_event_pool_get_ipc_handle_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeEventPoolOpenIpcHandle /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_event_pool_open_ipc_handle_params_t { ze_context_handle_t* phContext; ze_ipc_event_pool_handle_t* phIpc; ze_event_pool_handle_t** pphEventPool; } ze_event_pool_open_ipc_handle_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeEventPoolOpenIpcHandle /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnEventPoolOpenIpcHandleCb_t)( ze_event_pool_open_ipc_handle_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeEventPoolCloseIpcHandle /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_event_pool_close_ipc_handle_params_t { ze_event_pool_handle_t* phEventPool; } ze_event_pool_close_ipc_handle_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeEventPoolCloseIpcHandle /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnEventPoolCloseIpcHandleCb_t)( ze_event_pool_close_ipc_handle_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Table of EventPool callback functions pointers typedef struct _ze_event_pool_callbacks_t { ze_pfnEventPoolCreateCb_t pfnCreateCb; ze_pfnEventPoolDestroyCb_t pfnDestroyCb; ze_pfnEventPoolGetIpcHandleCb_t pfnGetIpcHandleCb; ze_pfnEventPoolOpenIpcHandleCb_t pfnOpenIpcHandleCb; ze_pfnEventPoolCloseIpcHandleCb_t pfnCloseIpcHandleCb; } ze_event_pool_callbacks_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeEventCreate /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_event_create_params_t { ze_event_pool_handle_t* phEventPool; const ze_event_desc_t** pdesc; ze_event_handle_t** pphEvent; } ze_event_create_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeEventCreate /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnEventCreateCb_t)( ze_event_create_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeEventDestroy /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_event_destroy_params_t { ze_event_handle_t* phEvent; } ze_event_destroy_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeEventDestroy /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnEventDestroyCb_t)( ze_event_destroy_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeEventHostSignal /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_event_host_signal_params_t { ze_event_handle_t* phEvent; } ze_event_host_signal_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeEventHostSignal /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnEventHostSignalCb_t)( ze_event_host_signal_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeEventHostSynchronize /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_event_host_synchronize_params_t { ze_event_handle_t* phEvent; uint64_t* ptimeout; } ze_event_host_synchronize_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeEventHostSynchronize /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnEventHostSynchronizeCb_t)( ze_event_host_synchronize_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeEventQueryStatus /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_event_query_status_params_t { ze_event_handle_t* phEvent; } ze_event_query_status_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeEventQueryStatus /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnEventQueryStatusCb_t)( ze_event_query_status_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeEventHostReset /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_event_host_reset_params_t { ze_event_handle_t* phEvent; } ze_event_host_reset_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeEventHostReset /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnEventHostResetCb_t)( ze_event_host_reset_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeEventQueryKernelTimestamp /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_event_query_kernel_timestamp_params_t { ze_event_handle_t* phEvent; ze_kernel_timestamp_result_t** pdstptr; } ze_event_query_kernel_timestamp_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeEventQueryKernelTimestamp /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnEventQueryKernelTimestampCb_t)( ze_event_query_kernel_timestamp_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Table of Event callback functions pointers typedef struct _ze_event_callbacks_t { ze_pfnEventCreateCb_t pfnCreateCb; ze_pfnEventDestroyCb_t pfnDestroyCb; ze_pfnEventHostSignalCb_t pfnHostSignalCb; ze_pfnEventHostSynchronizeCb_t pfnHostSynchronizeCb; ze_pfnEventQueryStatusCb_t pfnQueryStatusCb; ze_pfnEventHostResetCb_t pfnHostResetCb; ze_pfnEventQueryKernelTimestampCb_t pfnQueryKernelTimestampCb; } ze_event_callbacks_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeModuleCreate /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_module_create_params_t { ze_context_handle_t* phContext; ze_device_handle_t* phDevice; const ze_module_desc_t** pdesc; ze_module_handle_t** pphModule; ze_module_build_log_handle_t** pphBuildLog; } ze_module_create_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeModuleCreate /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnModuleCreateCb_t)( ze_module_create_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeModuleDestroy /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_module_destroy_params_t { ze_module_handle_t* phModule; } ze_module_destroy_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeModuleDestroy /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnModuleDestroyCb_t)( ze_module_destroy_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeModuleDynamicLink /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_module_dynamic_link_params_t { uint32_t* pnumModules; ze_module_handle_t** pphModules; ze_module_build_log_handle_t** pphLinkLog; } ze_module_dynamic_link_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeModuleDynamicLink /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnModuleDynamicLinkCb_t)( ze_module_dynamic_link_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeModuleGetNativeBinary /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_module_get_native_binary_params_t { ze_module_handle_t* phModule; size_t** ppSize; uint8_t** ppModuleNativeBinary; } ze_module_get_native_binary_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeModuleGetNativeBinary /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnModuleGetNativeBinaryCb_t)( ze_module_get_native_binary_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeModuleGetGlobalPointer /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_module_get_global_pointer_params_t { ze_module_handle_t* phModule; const char** ppGlobalName; size_t** ppSize; void*** ppptr; } ze_module_get_global_pointer_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeModuleGetGlobalPointer /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnModuleGetGlobalPointerCb_t)( ze_module_get_global_pointer_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeModuleGetKernelNames /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_module_get_kernel_names_params_t { ze_module_handle_t* phModule; uint32_t** ppCount; const char*** ppNames; } ze_module_get_kernel_names_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeModuleGetKernelNames /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnModuleGetKernelNamesCb_t)( ze_module_get_kernel_names_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeModuleGetProperties /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_module_get_properties_params_t { ze_module_handle_t* phModule; ze_module_properties_t** ppModuleProperties; } ze_module_get_properties_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeModuleGetProperties /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnModuleGetPropertiesCb_t)( ze_module_get_properties_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeModuleGetFunctionPointer /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_module_get_function_pointer_params_t { ze_module_handle_t* phModule; const char** ppFunctionName; void*** ppfnFunction; } ze_module_get_function_pointer_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeModuleGetFunctionPointer /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnModuleGetFunctionPointerCb_t)( ze_module_get_function_pointer_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Table of Module callback functions pointers typedef struct _ze_module_callbacks_t { ze_pfnModuleCreateCb_t pfnCreateCb; ze_pfnModuleDestroyCb_t pfnDestroyCb; ze_pfnModuleDynamicLinkCb_t pfnDynamicLinkCb; ze_pfnModuleGetNativeBinaryCb_t pfnGetNativeBinaryCb; ze_pfnModuleGetGlobalPointerCb_t pfnGetGlobalPointerCb; ze_pfnModuleGetKernelNamesCb_t pfnGetKernelNamesCb; ze_pfnModuleGetPropertiesCb_t pfnGetPropertiesCb; ze_pfnModuleGetFunctionPointerCb_t pfnGetFunctionPointerCb; } ze_module_callbacks_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeModuleBuildLogDestroy /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_module_build_log_destroy_params_t { ze_module_build_log_handle_t* phModuleBuildLog; } ze_module_build_log_destroy_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeModuleBuildLogDestroy /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnModuleBuildLogDestroyCb_t)( ze_module_build_log_destroy_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeModuleBuildLogGetString /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_module_build_log_get_string_params_t { ze_module_build_log_handle_t* phModuleBuildLog; size_t** ppSize; char** ppBuildLog; } ze_module_build_log_get_string_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeModuleBuildLogGetString /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnModuleBuildLogGetStringCb_t)( ze_module_build_log_get_string_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Table of ModuleBuildLog callback functions pointers typedef struct _ze_module_build_log_callbacks_t { ze_pfnModuleBuildLogDestroyCb_t pfnDestroyCb; ze_pfnModuleBuildLogGetStringCb_t pfnGetStringCb; } ze_module_build_log_callbacks_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeKernelCreate /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_kernel_create_params_t { ze_module_handle_t* phModule; const ze_kernel_desc_t** pdesc; ze_kernel_handle_t** pphKernel; } ze_kernel_create_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeKernelCreate /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnKernelCreateCb_t)( ze_kernel_create_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeKernelDestroy /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_kernel_destroy_params_t { ze_kernel_handle_t* phKernel; } ze_kernel_destroy_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeKernelDestroy /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnKernelDestroyCb_t)( ze_kernel_destroy_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeKernelSetCacheConfig /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_kernel_set_cache_config_params_t { ze_kernel_handle_t* phKernel; ze_cache_config_flags_t* pflags; } ze_kernel_set_cache_config_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeKernelSetCacheConfig /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnKernelSetCacheConfigCb_t)( ze_kernel_set_cache_config_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeKernelSetGroupSize /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_kernel_set_group_size_params_t { ze_kernel_handle_t* phKernel; uint32_t* pgroupSizeX; uint32_t* pgroupSizeY; uint32_t* pgroupSizeZ; } ze_kernel_set_group_size_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeKernelSetGroupSize /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnKernelSetGroupSizeCb_t)( ze_kernel_set_group_size_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeKernelSuggestGroupSize /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_kernel_suggest_group_size_params_t { ze_kernel_handle_t* phKernel; uint32_t* pglobalSizeX; uint32_t* pglobalSizeY; uint32_t* pglobalSizeZ; uint32_t** pgroupSizeX; uint32_t** pgroupSizeY; uint32_t** pgroupSizeZ; } ze_kernel_suggest_group_size_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeKernelSuggestGroupSize /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnKernelSuggestGroupSizeCb_t)( ze_kernel_suggest_group_size_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeKernelSuggestMaxCooperativeGroupCount /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_kernel_suggest_max_cooperative_group_count_params_t { ze_kernel_handle_t* phKernel; uint32_t** ptotalGroupCount; } ze_kernel_suggest_max_cooperative_group_count_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeKernelSuggestMaxCooperativeGroupCount /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnKernelSuggestMaxCooperativeGroupCountCb_t)( ze_kernel_suggest_max_cooperative_group_count_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeKernelSetArgumentValue /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_kernel_set_argument_value_params_t { ze_kernel_handle_t* phKernel; uint32_t* pargIndex; size_t* pargSize; const void** ppArgValue; } ze_kernel_set_argument_value_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeKernelSetArgumentValue /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnKernelSetArgumentValueCb_t)( ze_kernel_set_argument_value_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeKernelSetIndirectAccess /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_kernel_set_indirect_access_params_t { ze_kernel_handle_t* phKernel; ze_kernel_indirect_access_flags_t* pflags; } ze_kernel_set_indirect_access_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeKernelSetIndirectAccess /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnKernelSetIndirectAccessCb_t)( ze_kernel_set_indirect_access_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeKernelGetIndirectAccess /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_kernel_get_indirect_access_params_t { ze_kernel_handle_t* phKernel; ze_kernel_indirect_access_flags_t** ppFlags; } ze_kernel_get_indirect_access_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeKernelGetIndirectAccess /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnKernelGetIndirectAccessCb_t)( ze_kernel_get_indirect_access_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeKernelGetSourceAttributes /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_kernel_get_source_attributes_params_t { ze_kernel_handle_t* phKernel; uint32_t** ppSize; char*** ppString; } ze_kernel_get_source_attributes_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeKernelGetSourceAttributes /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnKernelGetSourceAttributesCb_t)( ze_kernel_get_source_attributes_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeKernelGetProperties /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_kernel_get_properties_params_t { ze_kernel_handle_t* phKernel; ze_kernel_properties_t** ppKernelProperties; } ze_kernel_get_properties_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeKernelGetProperties /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnKernelGetPropertiesCb_t)( ze_kernel_get_properties_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeKernelGetName /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_kernel_get_name_params_t { ze_kernel_handle_t* phKernel; size_t** ppSize; char** ppName; } ze_kernel_get_name_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeKernelGetName /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnKernelGetNameCb_t)( ze_kernel_get_name_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Table of Kernel callback functions pointers typedef struct _ze_kernel_callbacks_t { ze_pfnKernelCreateCb_t pfnCreateCb; ze_pfnKernelDestroyCb_t pfnDestroyCb; ze_pfnKernelSetCacheConfigCb_t pfnSetCacheConfigCb; ze_pfnKernelSetGroupSizeCb_t pfnSetGroupSizeCb; ze_pfnKernelSuggestGroupSizeCb_t pfnSuggestGroupSizeCb; ze_pfnKernelSuggestMaxCooperativeGroupCountCb_t pfnSuggestMaxCooperativeGroupCountCb; ze_pfnKernelSetArgumentValueCb_t pfnSetArgumentValueCb; ze_pfnKernelSetIndirectAccessCb_t pfnSetIndirectAccessCb; ze_pfnKernelGetIndirectAccessCb_t pfnGetIndirectAccessCb; ze_pfnKernelGetSourceAttributesCb_t pfnGetSourceAttributesCb; ze_pfnKernelGetPropertiesCb_t pfnGetPropertiesCb; ze_pfnKernelGetNameCb_t pfnGetNameCb; } ze_kernel_callbacks_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeSamplerCreate /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_sampler_create_params_t { ze_context_handle_t* phContext; ze_device_handle_t* phDevice; const ze_sampler_desc_t** pdesc; ze_sampler_handle_t** pphSampler; } ze_sampler_create_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeSamplerCreate /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnSamplerCreateCb_t)( ze_sampler_create_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeSamplerDestroy /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_sampler_destroy_params_t { ze_sampler_handle_t* phSampler; } ze_sampler_destroy_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeSamplerDestroy /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnSamplerDestroyCb_t)( ze_sampler_destroy_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Table of Sampler callback functions pointers typedef struct _ze_sampler_callbacks_t { ze_pfnSamplerCreateCb_t pfnCreateCb; ze_pfnSamplerDestroyCb_t pfnDestroyCb; } ze_sampler_callbacks_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zePhysicalMemCreate /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_physical_mem_create_params_t { ze_context_handle_t* phContext; ze_device_handle_t* phDevice; ze_physical_mem_desc_t** pdesc; ze_physical_mem_handle_t** pphPhysicalMemory; } ze_physical_mem_create_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zePhysicalMemCreate /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnPhysicalMemCreateCb_t)( ze_physical_mem_create_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zePhysicalMemDestroy /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_physical_mem_destroy_params_t { ze_context_handle_t* phContext; ze_physical_mem_handle_t* phPhysicalMemory; } ze_physical_mem_destroy_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zePhysicalMemDestroy /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnPhysicalMemDestroyCb_t)( ze_physical_mem_destroy_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Table of PhysicalMem callback functions pointers typedef struct _ze_physical_mem_callbacks_t { ze_pfnPhysicalMemCreateCb_t pfnCreateCb; ze_pfnPhysicalMemDestroyCb_t pfnDestroyCb; } ze_physical_mem_callbacks_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeMemAllocShared /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_mem_alloc_shared_params_t { ze_context_handle_t* phContext; const ze_device_mem_alloc_desc_t** pdevice_desc; const ze_host_mem_alloc_desc_t** phost_desc; size_t* psize; size_t* palignment; ze_device_handle_t* phDevice; void*** ppptr; } ze_mem_alloc_shared_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeMemAllocShared /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnMemAllocSharedCb_t)( ze_mem_alloc_shared_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeMemAllocDevice /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_mem_alloc_device_params_t { ze_context_handle_t* phContext; const ze_device_mem_alloc_desc_t** pdevice_desc; size_t* psize; size_t* palignment; ze_device_handle_t* phDevice; void*** ppptr; } ze_mem_alloc_device_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeMemAllocDevice /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnMemAllocDeviceCb_t)( ze_mem_alloc_device_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeMemAllocHost /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_mem_alloc_host_params_t { ze_context_handle_t* phContext; const ze_host_mem_alloc_desc_t** phost_desc; size_t* psize; size_t* palignment; void*** ppptr; } ze_mem_alloc_host_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeMemAllocHost /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnMemAllocHostCb_t)( ze_mem_alloc_host_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeMemFree /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_mem_free_params_t { ze_context_handle_t* phContext; void** pptr; } ze_mem_free_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeMemFree /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnMemFreeCb_t)( ze_mem_free_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeMemGetAllocProperties /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_mem_get_alloc_properties_params_t { ze_context_handle_t* phContext; const void** pptr; ze_memory_allocation_properties_t** ppMemAllocProperties; ze_device_handle_t** pphDevice; } ze_mem_get_alloc_properties_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeMemGetAllocProperties /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnMemGetAllocPropertiesCb_t)( ze_mem_get_alloc_properties_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeMemGetAddressRange /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_mem_get_address_range_params_t { ze_context_handle_t* phContext; const void** pptr; void*** ppBase; size_t** ppSize; } ze_mem_get_address_range_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeMemGetAddressRange /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnMemGetAddressRangeCb_t)( ze_mem_get_address_range_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeMemGetIpcHandle /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_mem_get_ipc_handle_params_t { ze_context_handle_t* phContext; const void** pptr; ze_ipc_mem_handle_t** ppIpcHandle; } ze_mem_get_ipc_handle_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeMemGetIpcHandle /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnMemGetIpcHandleCb_t)( ze_mem_get_ipc_handle_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeMemOpenIpcHandle /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_mem_open_ipc_handle_params_t { ze_context_handle_t* phContext; ze_device_handle_t* phDevice; ze_ipc_mem_handle_t* phandle; ze_ipc_memory_flags_t* pflags; void*** ppptr; } ze_mem_open_ipc_handle_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeMemOpenIpcHandle /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnMemOpenIpcHandleCb_t)( ze_mem_open_ipc_handle_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeMemCloseIpcHandle /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_mem_close_ipc_handle_params_t { ze_context_handle_t* phContext; const void** pptr; } ze_mem_close_ipc_handle_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeMemCloseIpcHandle /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnMemCloseIpcHandleCb_t)( ze_mem_close_ipc_handle_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Table of Mem callback functions pointers typedef struct _ze_mem_callbacks_t { ze_pfnMemAllocSharedCb_t pfnAllocSharedCb; ze_pfnMemAllocDeviceCb_t pfnAllocDeviceCb; ze_pfnMemAllocHostCb_t pfnAllocHostCb; ze_pfnMemFreeCb_t pfnFreeCb; ze_pfnMemGetAllocPropertiesCb_t pfnGetAllocPropertiesCb; ze_pfnMemGetAddressRangeCb_t pfnGetAddressRangeCb; ze_pfnMemGetIpcHandleCb_t pfnGetIpcHandleCb; ze_pfnMemOpenIpcHandleCb_t pfnOpenIpcHandleCb; ze_pfnMemCloseIpcHandleCb_t pfnCloseIpcHandleCb; } ze_mem_callbacks_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeVirtualMemReserve /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_virtual_mem_reserve_params_t { ze_context_handle_t* phContext; const void** ppStart; size_t* psize; void*** ppptr; } ze_virtual_mem_reserve_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeVirtualMemReserve /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnVirtualMemReserveCb_t)( ze_virtual_mem_reserve_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeVirtualMemFree /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_virtual_mem_free_params_t { ze_context_handle_t* phContext; const void** pptr; size_t* psize; } ze_virtual_mem_free_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeVirtualMemFree /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnVirtualMemFreeCb_t)( ze_virtual_mem_free_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeVirtualMemQueryPageSize /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_virtual_mem_query_page_size_params_t { ze_context_handle_t* phContext; ze_device_handle_t* phDevice; size_t* psize; size_t** ppagesize; } ze_virtual_mem_query_page_size_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeVirtualMemQueryPageSize /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnVirtualMemQueryPageSizeCb_t)( ze_virtual_mem_query_page_size_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeVirtualMemMap /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_virtual_mem_map_params_t { ze_context_handle_t* phContext; const void** pptr; size_t* psize; ze_physical_mem_handle_t* phPhysicalMemory; size_t* poffset; ze_memory_access_attribute_t* paccess; } ze_virtual_mem_map_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeVirtualMemMap /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnVirtualMemMapCb_t)( ze_virtual_mem_map_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeVirtualMemUnmap /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_virtual_mem_unmap_params_t { ze_context_handle_t* phContext; const void** pptr; size_t* psize; } ze_virtual_mem_unmap_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeVirtualMemUnmap /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnVirtualMemUnmapCb_t)( ze_virtual_mem_unmap_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeVirtualMemSetAccessAttribute /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_virtual_mem_set_access_attribute_params_t { ze_context_handle_t* phContext; const void** pptr; size_t* psize; ze_memory_access_attribute_t* paccess; } ze_virtual_mem_set_access_attribute_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeVirtualMemSetAccessAttribute /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnVirtualMemSetAccessAttributeCb_t)( ze_virtual_mem_set_access_attribute_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function parameters for zeVirtualMemGetAccessAttribute /// @details Each entry is a pointer to the parameter passed to the function; /// allowing the callback the ability to modify the parameter's value typedef struct _ze_virtual_mem_get_access_attribute_params_t { ze_context_handle_t* phContext; const void** pptr; size_t* psize; ze_memory_access_attribute_t** paccess; size_t** poutSize; } ze_virtual_mem_get_access_attribute_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function-pointer for zeVirtualMemGetAccessAttribute /// @param[in] params Parameters passed to this instance /// @param[in] result Return value /// @param[in] pTracerUserData Per-Tracer user data /// @param[in,out] ppTracerInstanceUserData Per-Tracer, Per-Instance user data typedef void (ZE_APICALL *ze_pfnVirtualMemGetAccessAttributeCb_t)( ze_virtual_mem_get_access_attribute_params_t* params, ze_result_t result, void* pTracerUserData, void** ppTracerInstanceUserData ); /////////////////////////////////////////////////////////////////////////////// /// @brief Table of VirtualMem callback functions pointers typedef struct _ze_virtual_mem_callbacks_t { ze_pfnVirtualMemReserveCb_t pfnReserveCb; ze_pfnVirtualMemFreeCb_t pfnFreeCb; ze_pfnVirtualMemQueryPageSizeCb_t pfnQueryPageSizeCb; ze_pfnVirtualMemMapCb_t pfnMapCb; ze_pfnVirtualMemUnmapCb_t pfnUnmapCb; ze_pfnVirtualMemSetAccessAttributeCb_t pfnSetAccessAttributeCb; ze_pfnVirtualMemGetAccessAttributeCb_t pfnGetAccessAttributeCb; } ze_virtual_mem_callbacks_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Container for all callbacks typedef struct _ze_callbacks_t { ze_global_callbacks_t Global; ze_driver_callbacks_t Driver; ze_device_callbacks_t Device; ze_context_callbacks_t Context; ze_command_queue_callbacks_t CommandQueue; ze_command_list_callbacks_t CommandList; ze_fence_callbacks_t Fence; ze_event_pool_callbacks_t EventPool; ze_event_callbacks_t Event; ze_image_callbacks_t Image; ze_module_callbacks_t Module; ze_module_build_log_callbacks_t ModuleBuildLog; ze_kernel_callbacks_t Kernel; ze_sampler_callbacks_t Sampler; ze_physical_mem_callbacks_t PhysicalMem; ze_mem_callbacks_t Mem; ze_virtual_mem_callbacks_t VirtualMem; } ze_callbacks_t; #if !defined(__GNUC__) #pragma endregion #endif #if defined(__cplusplus) } // extern "C" #endif #endif // _ZE_API_Hlevel-zero-raytracing-support-1.0.0/level_zero/ze_rtas.h000066400000000000000000001712721450534701400234520ustar00rootroot00000000000000// Copyright 2009-2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once /////////////////////////////////////////////////////////////////////////////// /// @brief Defines Return/Error codes #define ZE_RESULT_EXP_ERROR_OPERANDS_INCOMPATIBLE ((ze_result_t)0x7ff00004) ///< [Core, Experimental] operands of comparison are not compatible #define ZE_RESULT_EXP_RTAS_BUILD_RETRY ((ze_result_t) 0x7ff00005) ///< [Core, Experimental] ray tracing acceleration structure build failed ///< due to insufficient resources, retry with a larger buffer allocation #define ZE_RESULT_EXP_RTAS_BUILD_DEFERRED ((ze_result_t) 0x7ff00006) ///< [Core, Experimental] ray tracing acceleration structure build ///< operation deferred to parallel operation join #define ZE_STRUCTURE_TYPE_RTAS_BUILDER_EXP_DESC ((ze_structure_type_t)0x0002000E) ///< ::ze_rtas_builder_exp_desc_t #define ZE_STRUCTURE_TYPE_RTAS_BUILDER_BUILD_OP_EXP_DESC ((ze_structure_type_t)0x0002000F) ///< ::ze_rtas_builder_build_op_exp_desc_t #define ZE_STRUCTURE_TYPE_RTAS_BUILDER_EXP_PROPERTIES ((ze_structure_type_t)0x00020010) ///< ::ze_rtas_builder_exp_properties_t #define ZE_STRUCTURE_TYPE_RTAS_PARALLEL_OPERATION_EXP_PROPERTIES ((ze_structure_type_t)0x00020011) ///< ::ze_rtas_parallel_operation_exp_properties_t #define ZE_STRUCTURE_TYPE_RTAS_DEVICE_EXP_PROPERTIES ((ze_structure_type_t)0x00020012) ///< ::ze_rtas_device_exp_properties_t #define ZE_STRUCTURE_TYPE_RTAS_GEOMETRY_AABBS_EXP_CB_PARAMS ((ze_structure_type_t)0x00020013) ///< ::ze_rtas_geometry_aabbs_exp_cb_params_t /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_rtas_builder_exp_desc_t typedef struct _ze_rtas_builder_exp_desc_t ze_rtas_builder_exp_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_rtas_builder_exp_properties_t typedef struct _ze_rtas_builder_exp_properties_t ze_rtas_builder_exp_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_rtas_parallel_operation_exp_properties_t typedef struct _ze_rtas_parallel_operation_exp_properties_t ze_rtas_parallel_operation_exp_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_rtas_device_exp_properties_t typedef struct _ze_rtas_device_exp_properties_t ze_rtas_device_exp_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_rtas_float3_exp_t typedef struct _ze_rtas_float3_exp_t ze_rtas_float3_exp_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_rtas_transform_float3x4_column_major_exp_t typedef struct _ze_rtas_transform_float3x4_column_major_exp_t ze_rtas_transform_float3x4_column_major_exp_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_rtas_transform_float3x4_aligned_column_major_exp_t typedef struct _ze_rtas_transform_float3x4_aligned_column_major_exp_t ze_rtas_transform_float3x4_aligned_column_major_exp_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_rtas_transform_float3x4_row_major_exp_t typedef struct _ze_rtas_transform_float3x4_row_major_exp_t ze_rtas_transform_float3x4_row_major_exp_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_rtas_aabb_exp_t typedef struct _ze_rtas_aabb_exp_t ze_rtas_aabb_exp_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_rtas_triangle_indices_uint32_exp_t typedef struct _ze_rtas_triangle_indices_uint32_exp_t ze_rtas_triangle_indices_uint32_exp_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_rtas_quad_indices_uint32_exp_t typedef struct _ze_rtas_quad_indices_uint32_exp_t ze_rtas_quad_indices_uint32_exp_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_rtas_builder_geometry_info_exp_t typedef struct _ze_rtas_builder_geometry_info_exp_t ze_rtas_builder_geometry_info_exp_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_rtas_builder_triangles_geometry_info_exp_t typedef struct _ze_rtas_builder_triangles_geometry_info_exp_t ze_rtas_builder_triangles_geometry_info_exp_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_rtas_builder_quads_geometry_info_exp_t typedef struct _ze_rtas_builder_quads_geometry_info_exp_t ze_rtas_builder_quads_geometry_info_exp_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_rtas_geometry_aabbs_exp_cb_params_t typedef struct _ze_rtas_geometry_aabbs_exp_cb_params_t ze_rtas_geometry_aabbs_exp_cb_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_rtas_builder_procedural_geometry_info_exp_t typedef struct _ze_rtas_builder_procedural_geometry_info_exp_t ze_rtas_builder_procedural_geometry_info_exp_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_rtas_builder_instance_geometry_info_exp_t typedef struct _ze_rtas_builder_instance_geometry_info_exp_t ze_rtas_builder_instance_geometry_info_exp_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Forward-declare ze_rtas_builder_build_op_exp_desc_t typedef struct _ze_rtas_builder_build_op_exp_desc_t ze_rtas_builder_build_op_exp_desc_t; // Intel 'oneAPI' Level-Zero Extension for supporting ray tracing acceleration structure builder. #if !defined(__GNUC__) #pragma region RTASBuilder #endif /////////////////////////////////////////////////////////////////////////////// #ifndef ZE_RTAS_BUILDER_EXP_NAME /// @brief Ray Tracing Acceleration Structure Builder Extension Name #define ZE_RTAS_BUILDER_EXP_NAME "ZE_experimental_rtas_builder" #endif // ZE_RTAS_BUILDER_EXP_NAME /////////////////////////////////////////////////////////////////////////////// /// @brief Ray Tracing Acceleration Structure Builder Extension Version(s) typedef enum _ze_rtas_builder_exp_version_t { ZE_RTAS_BUILDER_EXP_VERSION_1_0 = ZE_MAKE_VERSION( 1, 0 ), ///< version 1.0 ZE_RTAS_BUILDER_EXP_VERSION_CURRENT = ZE_MAKE_VERSION( 1, 0 ), ///< latest known version ZE_RTAS_BUILDER_EXP_VERSION_FORCE_UINT32 = 0x7fffffff } ze_rtas_builder_exp_version_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Ray tracing acceleration structure device flags typedef uint32_t ze_rtas_device_exp_flags_t; typedef enum _ze_rtas_device_exp_flag_t { ZE_RTAS_DEVICE_EXP_FLAG_RESERVED = ZE_BIT(0), ///< reserved for future use ZE_RTAS_DEVICE_EXP_FLAG_FORCE_UINT32 = 0x7fffffff } ze_rtas_device_exp_flag_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Ray tracing acceleration structure format /// /// @details /// - This is an opaque ray tracing acceleration structure format /// identifier. typedef enum _ze_rtas_format_exp_t { ZE_RTAS_FORMAT_EXP_INVALID = 0, ///< Invalid acceleration structure format ZE_RTAS_FORMAT_EXP_FORCE_UINT32 = 0x7fffffff } ze_rtas_format_exp_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Ray tracing acceleration structure builder flags typedef uint32_t ze_rtas_builder_exp_flags_t; typedef enum _ze_rtas_builder_exp_flag_t { ZE_RTAS_BUILDER_EXP_FLAG_RESERVED = ZE_BIT(0), ///< Reserved for future use ZE_RTAS_BUILDER_EXP_FLAG_FORCE_UINT32 = 0x7fffffff } ze_rtas_builder_exp_flag_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Ray tracing acceleration structure builder parallel operation flags typedef uint32_t ze_rtas_parallel_operation_exp_flags_t; typedef enum _ze_rtas_parallel_operation_exp_flag_t { ZE_RTAS_PARALLEL_OPERATION_EXP_FLAG_RESERVED = ZE_BIT(0), ///< Reserved for future use ZE_RTAS_PARALLEL_OPERATION_EXP_FLAG_FORCE_UINT32 = 0x7fffffff } ze_rtas_parallel_operation_exp_flag_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Ray tracing acceleration structure builder geometry flags typedef uint32_t ze_rtas_builder_geometry_exp_flags_t; typedef enum _ze_rtas_builder_geometry_exp_flag_t { ZE_RTAS_BUILDER_GEOMETRY_EXP_FLAG_NON_OPAQUE = ZE_BIT(0), ///< non-opaque geometries invoke an any-hit shader ZE_RTAS_BUILDER_GEOMETRY_EXP_FLAG_FORCE_UINT32 = 0x7fffffff } ze_rtas_builder_geometry_exp_flag_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Packed ray tracing acceleration structure builder geometry flags (see /// ::ze_rtas_builder_geometry_exp_flags_t) typedef uint8_t ze_rtas_builder_packed_geometry_exp_flags_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Ray tracing acceleration structure builder instance flags typedef uint32_t ze_rtas_builder_instance_exp_flags_t; typedef enum _ze_rtas_builder_instance_exp_flag_t { ZE_RTAS_BUILDER_INSTANCE_EXP_FLAG_TRIANGLE_CULL_DISABLE = ZE_BIT(0), ///< disables culling of front-facing and back-facing triangles ZE_RTAS_BUILDER_INSTANCE_EXP_FLAG_TRIANGLE_FRONT_COUNTERCLOCKWISE = ZE_BIT(1), ///< reverses front and back face of triangles ZE_RTAS_BUILDER_INSTANCE_EXP_FLAG_TRIANGLE_FORCE_OPAQUE = ZE_BIT(2), ///< forces instanced geometry to be opaque, unless ray flag forces it to ///< be non-opaque ZE_RTAS_BUILDER_INSTANCE_EXP_FLAG_TRIANGLE_FORCE_NON_OPAQUE = ZE_BIT(3),///< forces instanced geometry to be non-opaque, unless ray flag forces it ///< to be opaque ZE_RTAS_BUILDER_INSTANCE_EXP_FLAG_FORCE_UINT32 = 0x7fffffff } ze_rtas_builder_instance_exp_flag_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Packed ray tracing acceleration structure builder instance flags (see /// ::ze_rtas_builder_instance_exp_flags_t) typedef uint8_t ze_rtas_builder_packed_instance_exp_flags_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Ray tracing acceleration structure builder build operation flags /// /// @details /// - These flags allow the application to tune the acceleration structure /// build operation. /// - The acceleration structure builder implementation might choose to use /// spatial splitting to split large or long primitives into smaller /// pieces. This may result in any-hit shaders being invoked multiple /// times for non-opaque primitives, unless /// ::ZE_RTAS_BUILDER_BUILD_OP_EXP_FLAG_NO_DUPLICATE_ANYHIT_INVOCATION is specified. /// - Usage of any of these flags may reduce ray tracing performance. typedef uint32_t ze_rtas_builder_build_op_exp_flags_t; typedef enum _ze_rtas_builder_build_op_exp_flag_t { ZE_RTAS_BUILDER_BUILD_OP_EXP_FLAG_COMPACT = ZE_BIT(0), ///< build more compact acceleration structure ZE_RTAS_BUILDER_BUILD_OP_EXP_FLAG_NO_DUPLICATE_ANYHIT_INVOCATION = ZE_BIT(1), ///< guarantees single any-hit shader invocation per primitive ZE_RTAS_BUILDER_BUILD_OP_EXP_FLAG_FORCE_UINT32 = 0x7fffffff } ze_rtas_builder_build_op_exp_flag_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Ray tracing acceleration structure builder build quality hint /// /// @details /// - Depending on use case different quality modes for acceleration /// structure build are supported. /// - A low-quality build builds an acceleration structure fast, but at the /// cost of some reduction in ray tracing performance. This mode is /// recommended for dynamic content, such as animated characters. /// - A medium-quality build uses a compromise between build quality and ray /// tracing performance. This mode should be used by default. /// - Higher ray tracing performance can be achieved by using a high-quality /// build, but acceleration structure build performance might be /// significantly reduced. typedef enum _ze_rtas_builder_build_quality_hint_exp_t { ZE_RTAS_BUILDER_BUILD_QUALITY_HINT_EXP_LOW = 0, ///< build low-quality acceleration structure (fast) ZE_RTAS_BUILDER_BUILD_QUALITY_HINT_EXP_MEDIUM = 1, ///< build medium-quality acceleration structure (slower) ZE_RTAS_BUILDER_BUILD_QUALITY_HINT_EXP_HIGH = 2, ///< build high-quality acceleration structure (slow) ZE_RTAS_BUILDER_BUILD_QUALITY_HINT_EXP_FORCE_UINT32 = 0x7fffffff } ze_rtas_builder_build_quality_hint_exp_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Ray tracing acceleration structure builder geometry type typedef enum _ze_rtas_builder_geometry_type_exp_t { ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_TRIANGLES = 0, ///< triangle mesh geometry type ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_QUADS = 1, ///< quad mesh geometry type ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL = 2, ///< procedural geometry type ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_INSTANCE = 3, ///< instance geometry type ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_FORCE_UINT32 = 0x7fffffff } ze_rtas_builder_geometry_type_exp_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Packed ray tracing acceleration structure builder geometry type (see /// ::ze_rtas_builder_geometry_type_exp_t) typedef uint8_t ze_rtas_builder_packed_geometry_type_exp_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Ray tracing acceleration structure data buffer element format /// /// @details /// - Specifies the format of data buffer elements. /// - Data buffers may contain instancing transform matrices, triangle/quad /// vertex indices, etc... typedef enum _ze_rtas_builder_input_data_format_exp_t { ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_FLOAT3 = 0, ///< 3-component float vector (see ::ze_rtas_float3_exp_t) ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_FLOAT3X4_COLUMN_MAJOR = 1, ///< 3x4 affine transformation in column-major format (see ///< ::ze_rtas_transform_float3x4_column_major_exp_t) ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_FLOAT3X4_ALIGNED_COLUMN_MAJOR = 2,///< 3x4 affine transformation in column-major format (see ///< ::ze_rtas_transform_float3x4_aligned_column_major_exp_t) ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_FLOAT3X4_ROW_MAJOR = 3, ///< 3x4 affine transformation in row-major format (see ///< ::ze_rtas_transform_float3x4_row_major_exp_t) ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_AABB = 4, ///< 3-dimensional axis-aligned bounding-box (see ::ze_rtas_aabb_exp_t) ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_TRIANGLE_INDICES_UINT32 = 5, ///< Unsigned 32-bit triangle indices (see ///< ::ze_rtas_triangle_indices_uint32_exp_t) ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_QUAD_INDICES_UINT32 = 6, ///< Unsigned 32-bit quad indices (see ::ze_rtas_quad_indices_uint32_exp_t) ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_FORCE_UINT32 = 0x7fffffff } ze_rtas_builder_input_data_format_exp_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Packed ray tracing acceleration structure data buffer element format /// (see ::ze_rtas_builder_input_data_format_exp_t) typedef uint8_t ze_rtas_builder_packed_input_data_format_exp_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Handle of ray tracing acceleration structure builder object typedef struct _ze_rtas_builder_exp_handle_t *ze_rtas_builder_exp_handle_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Handle of ray tracing acceleration structure builder parallel /// operation object typedef struct _ze_rtas_parallel_operation_exp_handle_t *ze_rtas_parallel_operation_exp_handle_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Ray tracing acceleration structure builder descriptor typedef struct _ze_rtas_builder_exp_desc_t { ze_structure_type_t stype; ///< [in] type of this structure const void* pNext; ///< [in][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains stype and pNext). ze_rtas_builder_exp_version_t builderVersion; ///< [in] ray tracing acceleration structure builder version } ze_rtas_builder_exp_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Ray tracing acceleration structure builder properties typedef struct _ze_rtas_builder_exp_properties_t { ze_structure_type_t stype; ///< [in] type of this structure void* pNext; ///< [in,out][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains stype and pNext). ze_rtas_builder_exp_flags_t flags; ///< [out] ray tracing acceleration structure builder flags size_t rtasBufferSizeBytesExpected; ///< [out] expected size (in bytes) required for acceleration structure buffer ///< - When using an acceleration structure buffer of this size, the ///< build is expected to succeed; however, it is possible that the build ///< may fail with ::ZE_RESULT_EXP_RTAS_BUILD_RETRY size_t rtasBufferSizeBytesMaxRequired; ///< [out] worst-case size (in bytes) required for acceleration structure buffer ///< - When using an acceleration structure buffer of this size, the ///< build is guaranteed to not run out of memory. size_t scratchBufferSizeBytes; ///< [out] scratch buffer size (in bytes) required for acceleration ///< structure build. } ze_rtas_builder_exp_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Ray tracing acceleration structure builder parallel operation /// properties typedef struct _ze_rtas_parallel_operation_exp_properties_t { ze_structure_type_t stype; ///< [in] type of this structure void* pNext; ///< [in,out][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains stype and pNext). ze_rtas_parallel_operation_exp_flags_t flags; ///< [out] ray tracing acceleration structure builder parallel operation ///< flags uint32_t maxConcurrency; ///< [out] maximum number of threads that may join the parallel operation } ze_rtas_parallel_operation_exp_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Ray tracing acceleration structure device properties /// /// @details /// - This structure may be passed to ::zeDeviceGetProperties, via `pNext` /// member of ::ze_device_properties_t. /// - The implementation shall populate `format` with a value other than /// ::ZE_RTAS_FORMAT_EXP_INVALID when the device supports ray tracing. typedef struct _ze_rtas_device_exp_properties_t { ze_structure_type_t stype; ///< [in] type of this structure void* pNext; ///< [in,out][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains stype and pNext). ze_rtas_device_exp_flags_t flags; ///< [out] ray tracing acceleration structure device flags ze_rtas_format_exp_t rtasFormat; ///< [out] ray tracing acceleration structure format uint32_t rtasBufferAlignment; ///< [out] required alignment of acceleration structure buffer } ze_rtas_device_exp_properties_t; /////////////////////////////////////////////////////////////////////////////// /// @brief A 3-component vector type typedef struct _ze_rtas_float3_exp_t { float x; ///< [in] x-coordinate of float3 vector float y; ///< [in] y-coordinate of float3 vector float z; ///< [in] z-coordinate of float3 vector } ze_rtas_float3_exp_t; /////////////////////////////////////////////////////////////////////////////// /// @brief 3x4 affine transformation in column-major layout /// /// @details /// - A 3x4 affine transformation in column major layout, consisting of vectors /// - vx=(vx_x, vx_y, vx_z), /// - vy=(vy_x, vy_y, vy_z), /// - vz=(vz_x, vz_y, vz_z), and /// - p=(p_x, p_y, p_z) /// - The transformation transforms a point (x, y, z) to: `x*vx + y*vy + /// z*vz + p`. typedef struct _ze_rtas_transform_float3x4_column_major_exp_t { float vx_x; ///< [in] element 0 of column 0 of 3x4 matrix float vx_y; ///< [in] element 1 of column 0 of 3x4 matrix float vx_z; ///< [in] element 2 of column 0 of 3x4 matrix float vy_x; ///< [in] element 0 of column 1 of 3x4 matrix float vy_y; ///< [in] element 1 of column 1 of 3x4 matrix float vy_z; ///< [in] element 2 of column 1 of 3x4 matrix float vz_x; ///< [in] element 0 of column 2 of 3x4 matrix float vz_y; ///< [in] element 1 of column 2 of 3x4 matrix float vz_z; ///< [in] element 2 of column 2 of 3x4 matrix float p_x; ///< [in] element 0 of column 3 of 3x4 matrix float p_y; ///< [in] element 1 of column 3 of 3x4 matrix float p_z; ///< [in] element 2 of column 3 of 3x4 matrix } ze_rtas_transform_float3x4_column_major_exp_t; /////////////////////////////////////////////////////////////////////////////// /// @brief 3x4 affine transformation in column-major layout with aligned column /// vectors /// /// @details /// - A 3x4 affine transformation in column major layout, consisting of vectors /// - vx=(vx_x, vx_y, vx_z), /// - vy=(vy_x, vy_y, vy_z), /// - vz=(vz_x, vz_y, vz_z), and /// - p=(p_x, p_y, p_z) /// - The transformation transforms a point (x, y, z) to: `x*vx + y*vy + /// z*vz + p`. /// - The column vectors are aligned to 16-bytes and pad members are /// ignored. typedef struct _ze_rtas_transform_float3x4_aligned_column_major_exp_t { float vx_x; ///< [in] element 0 of column 0 of 3x4 matrix float vx_y; ///< [in] element 1 of column 0 of 3x4 matrix float vx_z; ///< [in] element 2 of column 0 of 3x4 matrix float pad0; ///< [in] ignored padding float vy_x; ///< [in] element 0 of column 1 of 3x4 matrix float vy_y; ///< [in] element 1 of column 1 of 3x4 matrix float vy_z; ///< [in] element 2 of column 1 of 3x4 matrix float pad1; ///< [in] ignored padding float vz_x; ///< [in] element 0 of column 2 of 3x4 matrix float vz_y; ///< [in] element 1 of column 2 of 3x4 matrix float vz_z; ///< [in] element 2 of column 2 of 3x4 matrix float pad2; ///< [in] ignored padding float p_x; ///< [in] element 0 of column 3 of 3x4 matrix float p_y; ///< [in] element 1 of column 3 of 3x4 matrix float p_z; ///< [in] element 2 of column 3 of 3x4 matrix float pad3; ///< [in] ignored padding } ze_rtas_transform_float3x4_aligned_column_major_exp_t; /////////////////////////////////////////////////////////////////////////////// /// @brief 3x4 affine transformation in row-major layout /// /// @details /// - A 3x4 affine transformation in row-major layout, consisting of vectors /// - vx=(vx_x, vx_y, vx_z), /// - vy=(vy_x, vy_y, vy_z), /// - vz=(vz_x, vz_y, vz_z), and /// - p=(p_x, p_y, p_z) /// - The transformation transforms a point (x, y, z) to: `x*vx + y*vy + /// z*vz + p`. typedef struct _ze_rtas_transform_float3x4_row_major_exp_t { float vx_x; ///< [in] element 0 of row 0 of 3x4 matrix float vy_x; ///< [in] element 1 of row 0 of 3x4 matrix float vz_x; ///< [in] element 2 of row 0 of 3x4 matrix float p_x; ///< [in] element 3 of row 0 of 3x4 matrix float vx_y; ///< [in] element 0 of row 1 of 3x4 matrix float vy_y; ///< [in] element 1 of row 1 of 3x4 matrix float vz_y; ///< [in] element 2 of row 1 of 3x4 matrix float p_y; ///< [in] element 3 of row 1 of 3x4 matrix float vx_z; ///< [in] element 0 of row 2 of 3x4 matrix float vy_z; ///< [in] element 1 of row 2 of 3x4 matrix float vz_z; ///< [in] element 2 of row 2 of 3x4 matrix float p_z; ///< [in] element 3 of row 2 of 3x4 matrix } ze_rtas_transform_float3x4_row_major_exp_t; /////////////////////////////////////////////////////////////////////////////// /// @brief A 3-dimensional axis-aligned bounding-box with lower and upper bounds /// in each dimension typedef struct _ze_rtas_aabb_exp_t { ze_rtas_float3_exp_t lower; ///< [in] lower bounds of AABB ze_rtas_float3_exp_t upper; ///< [in] upper bounds of AABB } ze_rtas_aabb_exp_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Triangle represented using 3 vertex indices /// /// @details /// - Represents a triangle using 3 vertex indices that index into a vertex /// array that needs to be provided together with the index array. /// - The linear barycentric u/v parametrization of the triangle is defined as: /// - (u=0, v=0) at v0, /// - (u=1, v=0) at v1, and /// - (u=0, v=1) at v2 typedef struct _ze_rtas_triangle_indices_uint32_exp_t { uint32_t v0; ///< [in] first index pointing to the first triangle vertex in vertex array uint32_t v1; ///< [in] second index pointing to the second triangle vertex in vertex ///< array uint32_t v2; ///< [in] third index pointing to the third triangle vertex in vertex array } ze_rtas_triangle_indices_uint32_exp_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Quad represented using 4 vertex indices /// /// @details /// - Represents a quad composed of 4 indices that index into a vertex array /// that needs to be provided together with the index array. /// - A quad is a triangle pair represented using 4 vertex indices v0, v1, /// v2, v3. /// The first triangle is made out of indices v0, v1, v3 and the second triangle /// from indices v2, v3, v1. The piecewise linear barycentric u/v parametrization /// of the quad is defined as: /// - (u=0, v=0) at v0, /// - (u=1, v=0) at v1, /// - (u=0, v=1) at v3, and /// - (u=1, v=1) at v2 /// This is achieved by correcting the u'/v' coordinates of the second /// triangle by /// *u = 1-u'* and *v = 1-v'*, yielding a piecewise linear parametrization. typedef struct _ze_rtas_quad_indices_uint32_exp_t { uint32_t v0; ///< [in] first index pointing to the first quad vertex in vertex array uint32_t v1; ///< [in] second index pointing to the second quad vertex in vertex array uint32_t v2; ///< [in] third index pointing to the third quad vertex in vertex array uint32_t v3; ///< [in] fourth index pointing to the fourth quad vertex in vertex array } ze_rtas_quad_indices_uint32_exp_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Ray tracing acceleration structure builder geometry info typedef struct _ze_rtas_builder_geometry_info_exp_t { ze_rtas_builder_packed_geometry_type_exp_t geometryType; ///< [in] geometry type } ze_rtas_builder_geometry_info_exp_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Ray tracing acceleration structure builder triangle mesh geometry info /// /// @details /// - The linear barycentric u/v parametrization of the triangle is defined as: /// - (u=0, v=0) at v0, /// - (u=1, v=0) at v1, and /// - (u=0, v=1) at v2 typedef struct _ze_rtas_builder_triangles_geometry_info_exp_t { ze_rtas_builder_packed_geometry_type_exp_t geometryType; ///< [in] geometry type, must be ///< ::ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_TRIANGLES ze_rtas_builder_packed_geometry_exp_flags_t geometryFlags; ///< [in] 0 or some combination of ::ze_rtas_builder_geometry_exp_flag_t ///< bits representing the geometry flags for all primitives of this ///< geometry uint8_t geometryMask; ///< [in] 8-bit geometry mask for ray masking ze_rtas_builder_packed_input_data_format_exp_t triangleFormat; ///< [in] format of triangle buffer data, must be ///< ::ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_TRIANGLE_INDICES_UINT32 ze_rtas_builder_packed_input_data_format_exp_t vertexFormat; ///< [in] format of vertex buffer data, must be ///< ::ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_FLOAT3 uint32_t triangleCount; ///< [in] number of triangles in triangle buffer uint32_t vertexCount; ///< [in] number of vertices in vertex buffer uint32_t triangleStride; ///< [in] stride (in bytes) of triangles in triangle buffer uint32_t vertexStride; ///< [in] stride (in bytes) of vertices in vertex buffer void* pTriangleBuffer; ///< [in] pointer to array of triangle indices in specified format void* pVertexBuffer; ///< [in] pointer to array of triangle vertices in specified format } ze_rtas_builder_triangles_geometry_info_exp_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Ray tracing acceleration structure builder quad mesh geometry info /// /// @details /// - A quad is a triangle pair represented using 4 vertex indices v0, v1, /// v2, v3. /// The first triangle is made out of indices v0, v1, v3 and the second triangle /// from indices v2, v3, v1. The piecewise linear barycentric u/v parametrization /// of the quad is defined as: /// - (u=0, v=0) at v0, /// - (u=1, v=0) at v1, /// - (u=0, v=1) at v3, and /// - (u=1, v=1) at v2 /// This is achieved by correcting the u'/v' coordinates of the second /// triangle by /// *u = 1-u'* and *v = 1-v'*, yielding a piecewise linear parametrization. typedef struct _ze_rtas_builder_quads_geometry_info_exp_t { ze_rtas_builder_packed_geometry_type_exp_t geometryType; ///< [in] geometry type, must be ::ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_QUADS ze_rtas_builder_packed_geometry_exp_flags_t geometryFlags; ///< [in] 0 or some combination of ::ze_rtas_builder_geometry_exp_flag_t ///< bits representing the geometry flags for all primitives of this ///< geometry uint8_t geometryMask; ///< [in] 8-bit geometry mask for ray masking ze_rtas_builder_packed_input_data_format_exp_t quadFormat; ///< [in] format of quad buffer data, must be ///< ::ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_QUAD_INDICES_UINT32 ze_rtas_builder_packed_input_data_format_exp_t vertexFormat; ///< [in] format of vertex buffer data, must be ///< ::ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_FLOAT3 uint32_t quadCount; ///< [in] number of quads in quad buffer uint32_t vertexCount; ///< [in] number of vertices in vertex buffer uint32_t quadStride; ///< [in] stride (in bytes) of quads in quad buffer uint32_t vertexStride; ///< [in] stride (in bytes) of vertices in vertex buffer void* pQuadBuffer; ///< [in] pointer to array of quad indices in specified format void* pVertexBuffer; ///< [in] pointer to array of quad vertices in specified format } ze_rtas_builder_quads_geometry_info_exp_t; /////////////////////////////////////////////////////////////////////////////// /// @brief AABB callback function parameters typedef struct _ze_rtas_geometry_aabbs_exp_cb_params_t { ze_structure_type_t stype; ///< [in] type of this structure void* pNext; ///< [in,out][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains sType and pNext). uint32_t primID; ///< [in] first primitive to return bounds for uint32_t primIDCount; ///< [in] number of primitives to return bounds for void* pGeomUserPtr; ///< [in] pointer provided through geometry descriptor void* pBuildUserPtr; ///< [in] pointer provided through ::zeRTASBuilderBuildExp function ze_rtas_aabb_exp_t* pBoundsOut; ///< [out] destination buffer to write AABB bounds to } ze_rtas_geometry_aabbs_exp_cb_params_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Callback function pointer type to return AABBs for a range of /// procedural primitives typedef void (*ze_rtas_geometry_aabbs_cb_exp_t)( ze_rtas_geometry_aabbs_exp_cb_params_t* params ///< [in] callback function parameters structure ); /////////////////////////////////////////////////////////////////////////////// /// @brief Ray tracing acceleration structure builder procedural primitives /// geometry info /// /// @details /// - A host-side bounds callback function is invoked by the acceleration /// structure builder to query the bounds of procedural primitives on /// demand. The callback is passed some `pGeomUserPtr` that can point to /// an application-side representation of the procedural primitives. /// Further, a second `pBuildUserPtr`, which is set by a parameter to /// ::zeRTASBuilderBuildExp, is passed to the callback. This allows the /// build to change the bounds of the procedural geometry, for example, to /// build a BVH only over a short time range to implement multi-segment /// motion blur. typedef struct _ze_rtas_builder_procedural_geometry_info_exp_t { ze_rtas_builder_packed_geometry_type_exp_t geometryType; ///< [in] geometry type, must be ///< ::ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL ze_rtas_builder_packed_geometry_exp_flags_t geometryFlags; ///< [in] 0 or some combination of ::ze_rtas_builder_geometry_exp_flag_t ///< bits representing the geometry flags for all primitives of this ///< geometry uint8_t geometryMask; ///< [in] 8-bit geometry mask for ray masking uint8_t reserved; ///< [in] reserved for future use uint32_t primCount; ///< [in] number of primitives in geometry ze_rtas_geometry_aabbs_cb_exp_t pfnGetBoundsCb; ///< [in] pointer to callback function to get the axis-aligned bounding-box ///< for a range of primitives void* pGeomUserPtr; ///< [in] user data pointer passed to callback } ze_rtas_builder_procedural_geometry_info_exp_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Ray tracing acceleration structure builder instance geometry info typedef struct _ze_rtas_builder_instance_geometry_info_exp_t { ze_rtas_builder_packed_geometry_type_exp_t geometryType; ///< [in] geometry type, must be ///< ::ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_INSTANCE ze_rtas_builder_packed_instance_exp_flags_t instanceFlags; ///< [in] 0 or some combination of ::ze_rtas_builder_geometry_exp_flag_t ///< bits representing the geometry flags for all primitives of this ///< geometry uint8_t geometryMask; ///< [in] 8-bit geometry mask for ray masking ze_rtas_builder_packed_input_data_format_exp_t transformFormat; ///< [in] format of the specified transformation uint32_t instanceUserID; ///< [in] user-specified identifier for the instance void* pTransform; ///< [in] object-to-world instance transformation in specified format ze_rtas_aabb_exp_t* pBounds; ///< [in] object-space axis-aligned bounding-box of the instanced ///< acceleration structure void* pAccelerationStructure; ///< [in] pointer to acceleration structure to instantiate } ze_rtas_builder_instance_geometry_info_exp_t; /////////////////////////////////////////////////////////////////////////////// /// @brief typedef struct _ze_rtas_builder_build_op_exp_desc_t { ze_structure_type_t stype; ///< [in] type of this structure const void* pNext; ///< [in][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains stype and pNext). ze_rtas_format_exp_t rtasFormat; ///< [in] ray tracing acceleration structure format ze_rtas_builder_build_quality_hint_exp_t buildQuality; ///< [in] acceleration structure build quality hint ze_rtas_builder_build_op_exp_flags_t buildFlags; ///< [in] 0 or some combination of ::ze_rtas_builder_build_op_exp_flag_t ///< flags const ze_rtas_builder_geometry_info_exp_t** ppGeometries; ///< [in][optional][range(0, `numGeometries`)] NULL or a valid array of ///< pointers to geometry infos uint32_t numGeometries; ///< [in] number of geometries in geometry infos array, can be zero when ///< `ppGeometries` is NULL } ze_rtas_builder_build_op_exp_desc_t; /////////////////////////////////////////////////////////////////////////////// /// @brief Creates a ray tracing acceleration structure builder object /// /// @details /// - The application may call this function from simultaneous threads. /// - The implementation of this function must be thread-safe. /// - The implementation must support ::ZE_experimental_rtas_builder /// extension. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hDriver` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pDescriptor` /// + `nullptr == phBuilder` /// - ::ZE_RESULT_ERROR_INVALID_ENUMERATION /// + `::ZE_RTAS_BUILDER_EXP_VERSION_CURRENT < pDescriptor->builderVersion` ZE_APIEXPORT ze_result_t ZE_APICALL zeRTASBuilderCreateExp( ze_driver_handle_t hDriver, ///< [in] handle of driver object const ze_rtas_builder_exp_desc_t* pDescriptor, ///< [in] pointer to builder descriptor ze_rtas_builder_exp_handle_t* phBuilder ///< [out] handle of builder object ); /////////////////////////////////////////////////////////////////////////////// /// @brief Retrieves ray tracing acceleration structure builder properties /// /// @details /// - The application may call this function from simultaneous threads. /// - The implementation of this function must be thread-safe. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hBuilder` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pBuildOpDescriptor` /// + `nullptr == pProperties` /// - ::ZE_RESULT_ERROR_INVALID_ENUMERATION /// + `::ZE_RTAS_FORMAT_EXP_INVALID < pBuildOpDescriptor->rtasFormat` /// + `::ZE_RTAS_BUILDER_BUILD_QUALITY_HINT_EXP_HIGH < pBuildOpDescriptor->buildQuality` /// + `0x3 < pBuildOpDescriptor->buildFlags` ZE_APIEXPORT ze_result_t ZE_APICALL zeRTASBuilderGetBuildPropertiesExp( ze_rtas_builder_exp_handle_t hBuilder, ///< [in] handle of builder object const ze_rtas_builder_build_op_exp_desc_t* pBuildOpDescriptor, ///< [in] pointer to build operation descriptor ze_rtas_builder_exp_properties_t* pProperties ///< [in,out] query result for builder properties ); /////////////////////////////////////////////////////////////////////////////// /// @brief Checks ray tracing acceleration structure format compatibility /// /// @details /// - The application may call this function from simultaneous threads. /// - The implementation of this function must be thread-safe. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hDriver` /// - ::ZE_RESULT_ERROR_INVALID_ENUMERATION /// + `::ZE_RTAS_FORMAT_EXP_INVALID < rtasFormatA` /// + `::ZE_RTAS_FORMAT_EXP_INVALID < rtasFormatB` /// - ::ZE_RESULT_SUCCESS /// + An acceleration structure built with `rtasFormatA` is compatible with devices that report `rtasFormatB`. /// - ::ZE_RESULT_EXP_ERROR_OPERANDS_INCOMPATIBLE /// + An acceleration structure built with `rtasFormatA` is **not** compatible with devices that report `rtasFormatB`. ZE_APIEXPORT ze_result_t ZE_APICALL zeDriverRTASFormatCompatibilityCheckExp( ze_driver_handle_t hDriver, ///< [in] handle of driver object ze_rtas_format_exp_t rtasFormatA, ///< [in] operand A ze_rtas_format_exp_t rtasFormatB ///< [in] operand B ); /////////////////////////////////////////////////////////////////////////////// /// @brief Build ray tracing acceleration structure /// /// @details /// - This function builds an acceleration structure of the scene consisting /// of the specified geometry information and writes the acceleration /// structure to the provided destination buffer. All types of geometries /// can get freely mixed inside a scene. /// - It is the user's responsibility to manage the acceleration structure /// buffer allocation, de-allocation, and potential prefetching to the /// device memory. The required size of the acceleration structure buffer /// can be queried with the ::zeRTASBuilderGetPropertiesExp function. The /// acceleration structure buffer must be a shared USM allocation and /// should be present on the host at build time. The referenced scene data /// (index- and vertex- buffers) can be standard host allocations, and /// will not be referenced into by the build acceleration structure. /// - Before an acceleration structure can be built, the user must allocate /// the memory for the acceleration structure buffer and scratch buffer /// using sizes based on a query for the estimated size properties. /// - When using the "worst-case" size for the acceleration structure /// buffer, the acceleration structure construction will never fail with ::ZE_RESULT_EXP_RTAS_BUILD_RETRY. /// - When using the "expected" size for the acceleration structure buffer, /// the acceleration structure construction may fail with /// ::ZE_RESULT_EXP_RTAS_BUILD_RETRY. If this happens, the user may resize /// their acceleration structure buffer using the returned /// `*pRtasBufferSizeBytes` value, which will be updated with an improved /// size estimate that will likely result in a successful build. /// - The acceleration structure construction is run on the host and is /// synchronous, thus after the function returns with a successful result, /// the acceleration structure may be used. /// - All provided data buffers must be host-accessible. /// - The acceleration structure buffer must be a USM allocation. /// - A successfully constructed acceleration structure is entirely /// self-contained. There is no requirement for input data to persist /// beyond build completion. /// - A successfully constructed acceleration structure is non-copyable. /// - Acceleration structure construction may be parallelized by passing a /// valid handle to a parallel operation object and joining that parallel /// operation using ::zeRTASParallelOperationJoinExp with user-provided /// worker threads. /// - **Additional Notes** /// - "The geometry infos array, geometry infos, and scratch buffer must /// all be standard host memory allocations." /// - "A pointer to a geometry info can be a null pointer, in which case /// the geometry is treated as empty." /// - "If no parallel operation handle is provided, the build is run /// sequentially on the current thread." /// - "A parallel operation object may only be associated with a single /// acceleration structure build at a time." /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hBuilder` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pBuildOpDescriptor` /// + `nullptr == pScratchBuffer` /// + `nullptr == pRtasBuffer` /// - ::ZE_RESULT_ERROR_INVALID_ENUMERATION /// + `::ZE_RTAS_FORMAT_EXP_INVALID < pBuildOpDescriptor->rtasFormat` /// + `::ZE_RTAS_BUILDER_BUILD_QUALITY_HINT_EXP_HIGH < pBuildOpDescriptor->buildQuality` /// + `0x3 < pBuildOpDescriptor->buildFlags` /// - ::ZE_RESULT_EXP_RTAS_BUILD_DEFERRED /// + Acceleration structure build completion is deferred to parallel operation join. /// - ::ZE_RESULT_EXP_RTAS_BUILD_RETRY /// + Acceleration structure build failed due to insufficient resources, retry the build operation with a larger acceleration structure buffer allocation. /// - ::ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE /// + Acceleration structure build failed due to parallel operation object participation in another build operation. ZE_APIEXPORT ze_result_t ZE_APICALL zeRTASBuilderBuildExp( ze_rtas_builder_exp_handle_t hBuilder, ///< [in] handle of builder object const ze_rtas_builder_build_op_exp_desc_t* pBuildOpDescriptor, ///< [in] pointer to build operation descriptor void* pScratchBuffer, ///< [in][range(0, `scratchBufferSizeBytes`)] scratch buffer to be used ///< during acceleration structure construction size_t scratchBufferSizeBytes, ///< [in] size of scratch buffer, in bytes void* pRtasBuffer, ///< [in] pointer to destination buffer size_t rtasBufferSizeBytes, ///< [in] destination buffer size, in bytes ze_rtas_parallel_operation_exp_handle_t hParallelOperation, ///< [in][optional] handle to parallel operation object void* pBuildUserPtr, ///< [in][optional] pointer passed to callbacks ze_rtas_aabb_exp_t* pBounds, ///< [in,out][optional] pointer to destination address for acceleration ///< structure bounds size_t* pRtasBufferSizeBytes ///< [out][optional] updated acceleration structure size requirement, in ///< bytes ); /////////////////////////////////////////////////////////////////////////////// /// @brief Destroys a ray tracing acceleration structure builder object /// /// @details /// - The implementation of this function may immediately release any /// internal Host and Device resources associated with this builder. /// - The application must **not** call this function from simultaneous /// threads with the same builder handle. /// - The implementation of this function must be thread-safe. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hBuilder` /// - ::ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE ZE_APIEXPORT ze_result_t ZE_APICALL zeRTASBuilderDestroyExp( ze_rtas_builder_exp_handle_t hBuilder ///< [in][release] handle of builder object to destroy ); /////////////////////////////////////////////////////////////////////////////// /// @brief Creates a ray tracing acceleration structure builder parallel /// operation object /// /// @details /// - The application may call this function from simultaneous threads. /// - The implementation of this function must be thread-safe. /// - The implementation must support ::ZE_experimental_rtas_builder /// extension. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hDriver` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == phParallelOperation` ZE_APIEXPORT ze_result_t ZE_APICALL zeRTASParallelOperationCreateExp( ze_driver_handle_t hDriver, ///< [in] handle of driver object ze_rtas_parallel_operation_exp_handle_t* phParallelOperation ///< [out] handle of parallel operation object ); /////////////////////////////////////////////////////////////////////////////// /// @brief Retrieves ray tracing acceleration structure builder parallel /// operation properties /// /// @details /// - The application must first bind the parallel operation object to a /// build operation before it may query the parallel operation properties. /// In other words, the application must first call /// ::zeRTASBuilderBuildExp with **hParallelOperation** before calling /// this function. /// - The application may call this function from simultaneous threads. /// - The implementation of this function must be thread-safe. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hParallelOperation` /// - ::ZE_RESULT_ERROR_INVALID_NULL_POINTER /// + `nullptr == pProperties` ZE_APIEXPORT ze_result_t ZE_APICALL zeRTASParallelOperationGetPropertiesExp( ze_rtas_parallel_operation_exp_handle_t hParallelOperation, ///< [in] handle of parallel operation object ze_rtas_parallel_operation_exp_properties_t* pProperties ///< [in,out] query result for parallel operation properties ); /////////////////////////////////////////////////////////////////////////////// /// @brief Joins a parallel build operation /// /// @details /// - All worker threads return the same error code for the parallel build /// operation upon build completion /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hParallelOperation` ZE_APIEXPORT ze_result_t ZE_APICALL zeRTASParallelOperationJoinExp( ze_rtas_parallel_operation_exp_handle_t hParallelOperation ///< [in] handle of parallel operation object ); /////////////////////////////////////////////////////////////////////////////// /// @brief Destroys a ray tracing acceleration structure builder parallel /// operation object /// /// @details /// - The implementation of this function may immediately release any /// internal Host and Device resources associated with this parallel /// operation. /// - The application must **not** call this function from simultaneous /// threads with the same parallel operation handle. /// - The implementation of this function must be thread-safe. /// /// @returns /// - ::ZE_RESULT_SUCCESS /// - ::ZE_RESULT_ERROR_UNINITIALIZED /// - ::ZE_RESULT_ERROR_DEVICE_LOST /// - ::ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::ZE_RESULT_ERROR_OUT_OF_DEVICE_MEMORY /// - ::ZE_RESULT_ERROR_INVALID_NULL_HANDLE /// + `nullptr == hParallelOperation` ZE_APIEXPORT ze_result_t ZE_APICALL zeRTASParallelOperationDestroyExp( ze_rtas_parallel_operation_exp_handle_t hParallelOperation ///< [in][release] handle of parallel operation object to destroy ); #if !defined(__GNUC__) #pragma endregion #endif level-zero-raytracing-support-1.0.0/level_zero/ze_wrapper.cpp000066400000000000000000000421101450534701400245000ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 /* detect Linux platform */ #if defined(linux) || defined(__linux__) || defined(__LINUX__) # if !defined(__LINUX__) # define __LINUX__ # endif #endif #if defined(__LINUX__) #include #else #include #endif #include "ze_wrapper.h" #include "../rtbuild/rtbuild.h" #include #include #include #include #include ZeWrapper::RTAS_BUILD_MODE ZeWrapper::rtas_builder = ZeWrapper::AUTO; static std::mutex zeWrapperMutex; static void* handle = nullptr; static decltype(zeMemFree)* zeMemFreeInternal = nullptr; static decltype(zeMemAllocShared)* zeMemAllocSharedInternal = nullptr; static decltype(zeDriverGetExtensionProperties)* zeDriverGetExtensionPropertiesInternal = nullptr; static decltype(zeDeviceGetProperties)* zeDeviceGetPropertiesInternal = nullptr; static decltype(zeDeviceGetModuleProperties)* zeDeviceGetModulePropertiesInternal = nullptr; static decltype(zeRTASBuilderCreateExp)* zeRTASBuilderCreateExpInternal = nullptr; static decltype(zeRTASBuilderDestroyExp)* zeRTASBuilderDestroyExpInternal = nullptr; static decltype(zeDriverRTASFormatCompatibilityCheckExp)* zeDriverRTASFormatCompatibilityCheckExpInternal = nullptr; static decltype(zeRTASBuilderGetBuildPropertiesExp)* zeRTASBuilderGetBuildPropertiesExpInternal = nullptr; static decltype(zeRTASBuilderBuildExp)* zeRTASBuilderBuildExpInternal = nullptr; static decltype(zeRTASParallelOperationCreateExp)* zeRTASParallelOperationCreateExpInternal = nullptr; static decltype(zeRTASParallelOperationDestroyExp)* zeRTASParallelOperationDestroyExpInternal = nullptr; static decltype(zeRTASParallelOperationGetPropertiesExp)* zeRTASParallelOperationGetPropertiesExpInternal = nullptr; static decltype(zeRTASParallelOperationJoinExp)* zeRTASParallelOperationJoinExpInternal = nullptr; template T find_symbol(void* handle, std::string const& symbol) { #if defined(__LINUX__) T result = (T) dlsym(handle, symbol.c_str()); #else T result = (T) GetProcAddress((HMODULE)handle, symbol.c_str()); #endif if (!result) { throw std::runtime_error("level_zero wrapper: symbol " + symbol + " not found"); } return result; } void* load_module() { #if defined(__LINUX__) void* handle = dlopen(ZE_LOADER_NAME_LINUX,RTLD_LAZY); if (!handle) { throw std::runtime_error("module " ZE_LOADER_NAME_LINUX " not found"); } #else void* handle = LoadLibraryExA(ZE_LOADER_NAME_WINDOWS,NULL,LOAD_LIBRARY_SEARCH_SYSTEM32); if (!handle) { throw std::runtime_error("module " ZE_LOADER_NAME_WINDOWS " not found"); } #endif return handle; } void unload_module(void* handle) { if (handle) { #if defined(__LINUX__) dlclose(handle); #else FreeLibrary((HMODULE)handle); #endif } } ZeWrapper::~ZeWrapper() { unload_module(handle); } ze_result_t selectLevelZeroRTASBuilder(ze_driver_handle_t hDriver) { if (ZeWrapper::rtas_builder == ZeWrapper::LEVEL_ZERO) return ZE_RESULT_SUCCESS; auto zeRTASBuilderCreateExpTemp = find_symbol(handle,"zeRTASBuilderCreateExp"); auto zeRTASBuilderDestroyExpTemp = find_symbol(handle,"zeRTASBuilderDestroyExp"); ze_rtas_builder_exp_desc_t builderDesc = { ZE_STRUCTURE_TYPE_RTAS_BUILDER_EXP_DESC }; ze_rtas_builder_exp_handle_t hBuilder = nullptr; ze_result_t err = zeRTASBuilderCreateExpTemp(hDriver, &builderDesc, &hBuilder); /* when ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE is reported extension cannot get loaded */ if (err == ZE_RESULT_ERROR_DEPENDENCY_UNAVAILABLE) return err; if (err == ZE_RESULT_SUCCESS) zeRTASBuilderDestroyExpTemp(hBuilder); zeRTASBuilderCreateExpInternal = zeRTASBuilderCreateExpTemp; zeRTASBuilderDestroyExpInternal = zeRTASBuilderDestroyExpTemp; zeDriverRTASFormatCompatibilityCheckExpInternal = find_symbol(handle,"zeDriverRTASFormatCompatibilityCheckExp"); zeRTASBuilderGetBuildPropertiesExpInternal = find_symbol(handle,"zeRTASBuilderGetBuildPropertiesExp"); zeRTASBuilderBuildExpInternal = find_symbol(handle,"zeRTASBuilderBuildExp"); zeRTASParallelOperationCreateExpInternal = find_symbol(handle,"zeRTASParallelOperationCreateExp"); zeRTASParallelOperationDestroyExpInternal = find_symbol(handle,"zeRTASParallelOperationDestroyExp"); zeRTASParallelOperationGetPropertiesExpInternal = find_symbol(handle,"zeRTASParallelOperationGetPropertiesExp"); zeRTASParallelOperationJoinExpInternal = find_symbol(handle,"zeRTASParallelOperationJoinExp"); ZeWrapper::rtas_builder = ZeWrapper::LEVEL_ZERO; return ZE_RESULT_SUCCESS; } void selectInternalRTASBuilder() { #if defined(ZE_RAYTRACING_DISABLE_INTERNAL_BUILDER) throw std::runtime_error("internal builder disabled at compile time"); #else if (ZeWrapper::rtas_builder == ZeWrapper::INTERNAL) return; zeRTASBuilderCreateExpInternal = &zeRTASBuilderCreateExpImpl; zeRTASBuilderDestroyExpInternal = &zeRTASBuilderDestroyExpImpl; zeDriverRTASFormatCompatibilityCheckExpInternal = &zeDriverRTASFormatCompatibilityCheckExpImpl; zeRTASBuilderGetBuildPropertiesExpInternal = &zeRTASBuilderGetBuildPropertiesExpImpl; zeRTASBuilderBuildExpInternal = &zeRTASBuilderBuildExpImpl; zeRTASParallelOperationCreateExpInternal = &zeRTASParallelOperationCreateExpImpl; zeRTASParallelOperationDestroyExpInternal = &zeRTASParallelOperationDestroyExpImpl; zeRTASParallelOperationGetPropertiesExpInternal = &zeRTASParallelOperationGetPropertiesExpImpl; zeRTASParallelOperationJoinExpInternal = &zeRTASParallelOperationJoinExpImpl; ZeWrapper::rtas_builder = ZeWrapper::INTERNAL; #endif } ze_result_t ZeWrapper::init() { std::lock_guard lock(zeWrapperMutex); if (handle) return ZE_RESULT_SUCCESS; try { handle = load_module(); zeMemFreeInternal = find_symbol(handle, "zeMemFree"); zeMemAllocSharedInternal = find_symbol(handle, "zeMemAllocShared"); zeDriverGetExtensionPropertiesInternal = find_symbol(handle, "zeDriverGetExtensionProperties"); zeDeviceGetPropertiesInternal = find_symbol(handle, "zeDeviceGetProperties"); zeDeviceGetModulePropertiesInternal = find_symbol(handle, "zeDeviceGetModuleProperties"); } catch (std::exception& e) { return ZE_RESULT_ERROR_UNKNOWN; } return ZE_RESULT_SUCCESS; } ze_result_t ZeWrapper::initRTASBuilder(ze_driver_handle_t hDriver, RTAS_BUILD_MODE rtas_build_mode) { std::lock_guard lock(zeWrapperMutex); /* only select rtas builder once! */ if (rtas_builder != RTAS_BUILD_MODE::AUTO) { if (rtas_build_mode == RTAS_BUILD_MODE::AUTO) return ZE_RESULT_SUCCESS; if (rtas_builder == rtas_build_mode) return ZE_RESULT_SUCCESS; return ZE_RESULT_ERROR_UNKNOWN; } try { if (rtas_build_mode == RTAS_BUILD_MODE::AUTO) { try { if (selectLevelZeroRTASBuilder(hDriver) != ZE_RESULT_SUCCESS) selectInternalRTASBuilder(); } catch (std::exception& e) { selectInternalRTASBuilder(); } } else if (rtas_build_mode == RTAS_BUILD_MODE::INTERNAL) selectInternalRTASBuilder(); else if (rtas_build_mode == RTAS_BUILD_MODE::LEVEL_ZERO) return selectLevelZeroRTASBuilder(hDriver); else throw std::runtime_error("internal error"); } catch (std::exception& e) { return ZE_RESULT_ERROR_UNKNOWN; } return ZE_RESULT_SUCCESS; } ze_result_t ZeWrapper::zeMemFree(ze_context_handle_t context, void* ptr) { if (!handle || !zeMemFreeInternal) throw std::runtime_error("ZeWrapper not initialized, call ZeWrapper::init() first."); return zeMemFreeInternal(context, ptr); } ze_result_t ZeWrapper::zeMemAllocShared(ze_context_handle_t context, const ze_device_mem_alloc_desc_t* descd, const ze_host_mem_alloc_desc_t* desch, size_t s0, size_t s1, ze_device_handle_t ze_handle, void** ptr) { if (!handle || !zeMemAllocSharedInternal) throw std::runtime_error("ZeWrapper not initialized, call ZeWrapper::init() first."); return zeMemAllocSharedInternal(context, descd, desch, s0, s1, ze_handle, ptr); } ze_result_t ZeWrapper::zeDriverGetExtensionProperties(ze_driver_handle_t ze_handle, uint32_t* ptr, ze_driver_extension_properties_t* props) { if (!handle || !zeDriverGetExtensionPropertiesInternal) throw std::runtime_error("ZeWrapper not initialized, call ZeWrapper::init() first."); return zeDriverGetExtensionPropertiesInternal(ze_handle, ptr, props); } #define VALIDATE(arg) \ {\ ze_result_t result = validate(arg);\ if (result != ZE_RESULT_SUCCESS) return result; \ } ze_result_t validate(ze_device_handle_t hDevice) { if (hDevice == nullptr) return ZE_RESULT_ERROR_INVALID_NULL_HANDLE; return ZE_RESULT_SUCCESS; } ze_result_t validate(ze_rtas_device_exp_properties_t* pProperties) { if (pProperties == nullptr) return ZE_RESULT_ERROR_INVALID_NULL_POINTER; if (pProperties->stype != ZE_STRUCTURE_TYPE_RTAS_DEVICE_EXP_PROPERTIES) return ZE_RESULT_ERROR_INVALID_ENUMERATION; //if (!checkDescChain((zet_base_desc_t_*)pProperties)) //return ZE_RESULT_ERROR_INVALID_ENUMERATION; return ZE_RESULT_SUCCESS; } ze_result_t zeDeviceGetRTASPropertiesExp( const ze_device_handle_t hDevice, ze_rtas_device_exp_properties_t* pProperties ) { /* input validation */ VALIDATE(hDevice); VALIDATE(pProperties); /* fill properties */ pProperties->flags = 0; pProperties->rtasFormat = (ze_rtas_format_exp_t) ZE_RTAS_DEVICE_FORMAT_EXP_INVALID; pProperties->rtasBufferAlignment = 128; /* check for supported device ID */ ze_device_properties_t device_props{ ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES }; ze_result_t status = ZeWrapper::zeDeviceGetProperties(hDevice, &device_props); if (status != ZE_RESULT_SUCCESS) return status; /* check for Intel vendor */ const uint32_t vendor_id = device_props.vendorId; const uint32_t device_id = device_props.deviceId; if (vendor_id != 0x8086) return ZE_RESULT_ERROR_UNKNOWN; /* disabling of device check through env variable */ const char* disable_device_check = getenv("EMBREE_DISABLE_DEVICEID_CHECK"); if (disable_device_check && strcmp(disable_device_check,"1") == 0) { pProperties->rtasFormat = (ze_rtas_format_exp_t) ZE_RTAS_DEVICE_FORMAT_EXP_VERSION_1; return ZE_RESULT_SUCCESS; } /* DG2 */ const bool dg2 = (0x4F80 <= device_id && device_id <= 0x4F88) || (0x5690 <= device_id && device_id <= 0x5698) || (0x56A0 <= device_id && device_id <= 0x56A6) || (0x56B0 <= device_id && device_id <= 0x56B3) || (0x56C0 <= device_id && device_id <= 0x56C1); if (dg2) { pProperties->rtasFormat = (ze_rtas_format_exp_t) ZE_RTAS_DEVICE_FORMAT_EXP_VERSION_1; return ZE_RESULT_SUCCESS; } /* PVC */ const bool pvc = (0x0BD5 <= device_id && device_id <= 0x0BDB) || (device_id == 0x0B69 ); if (pvc) { pProperties->rtasFormat = (ze_rtas_format_exp_t) ZE_RTAS_DEVICE_FORMAT_EXP_VERSION_1; return ZE_RESULT_SUCCESS; } /* MTL */ const bool mtl = (device_id == 0x7D40) || (device_id == 0x7D55) || (device_id == 0x7DD5) || (device_id == 0x7D45) || (device_id == 0x7D60); if (mtl) { pProperties->rtasFormat = (ze_rtas_format_exp_t) ZE_RTAS_DEVICE_FORMAT_EXP_VERSION_1; return ZE_RESULT_SUCCESS; } return ZE_RESULT_ERROR_UNKNOWN; } ze_result_t ZeWrapper::zeDeviceGetProperties(ze_device_handle_t ze_handle, ze_device_properties_t* props) { if (!handle || !zeDeviceGetPropertiesInternal) throw std::runtime_error("ZeWrapper not initialized, call ZeWrapper::init() first."); if (ZeWrapper::rtas_builder == ZeWrapper::INTERNAL) { if (props->pNext && ((ze_base_properties_t*)props->pNext)->stype == ZE_STRUCTURE_TYPE_RTAS_DEVICE_EXP_PROPERTIES) { ze_result_t result = zeDeviceGetRTASPropertiesExp(ze_handle, (ze_rtas_device_exp_properties_t*)props->pNext); if (result != ZE_RESULT_SUCCESS) return result; void* pNext = props->pNext; props->pNext = ((ze_base_properties_t*)props->pNext)->pNext; result = zeDeviceGetPropertiesInternal(ze_handle, props); props->pNext = pNext; return result; } } return zeDeviceGetPropertiesInternal(ze_handle, props); } ze_result_t ZeWrapper::zeDeviceGetModuleProperties(ze_device_handle_t ze_handle, ze_device_module_properties_t* props) { if (!handle || !zeDeviceGetModulePropertiesInternal) throw std::runtime_error("ZeWrapper not initialized, call ZeWrapper::init() first."); return zeDeviceGetModulePropertiesInternal(ze_handle, props); } ze_result_t ZeWrapper::zeRTASBuilderCreateExp(ze_driver_handle_t hDriver, const ze_rtas_builder_exp_desc_t *pDescriptor, ze_rtas_builder_exp_handle_t *phBuilder) { if (!handle || !zeRTASBuilderCreateExpInternal) throw std::runtime_error("ZeWrapper not initialized, call ZeWrapper::init() first."); return zeRTASBuilderCreateExpInternal(hDriver,pDescriptor,phBuilder); } ze_result_t ZeWrapper::zeRTASBuilderDestroyExp(ze_rtas_builder_exp_handle_t hBuilder) { if (!handle || !zeRTASBuilderDestroyExpInternal) throw std::runtime_error("ZeWrapper not initialized, call ZeWrapper::init() first."); return zeRTASBuilderDestroyExpInternal(hBuilder); } ze_result_t ZeWrapper::zeDriverRTASFormatCompatibilityCheckExp( ze_driver_handle_t hDriver, const ze_rtas_format_exp_t accelFormat, const ze_rtas_format_exp_t otherAccelFormat) { if (!handle || !zeDriverRTASFormatCompatibilityCheckExpInternal) throw std::runtime_error("ZeWrapper not initialized, call ZeWrapper::init() first."); return zeDriverRTASFormatCompatibilityCheckExpInternal( hDriver, accelFormat, otherAccelFormat); } ze_result_t ZeWrapper::zeRTASBuilderGetBuildPropertiesExp(ze_rtas_builder_exp_handle_t hBuilder, const ze_rtas_builder_build_op_exp_desc_t* args, ze_rtas_builder_exp_properties_t* pProp) { if (!handle || !zeRTASBuilderGetBuildPropertiesExpInternal) throw std::runtime_error("ZeWrapper not initialized, call ZeWrapper::init() first."); return zeRTASBuilderGetBuildPropertiesExpInternal(hBuilder, args, pProp); } ze_result_t ZeWrapper::zeRTASBuilderBuildExp(ze_rtas_builder_exp_handle_t hBuilder, const ze_rtas_builder_build_op_exp_desc_t* args, void *pScratchBuffer, size_t scratchBufferSizeBytes, void *pRtasBuffer, size_t rtasBufferSizeBytes, ze_rtas_parallel_operation_exp_handle_t hParallelOperation, void *pBuildUserPtr, ze_rtas_aabb_exp_t *pBounds, size_t *pRtasBufferSizeBytes) { if (!handle || !zeRTASBuilderBuildExpInternal) throw std::runtime_error("ZeWrapper not initialized, call ZeWrapper::init() first."); return zeRTASBuilderBuildExpInternal(hBuilder, args, pScratchBuffer, scratchBufferSizeBytes, pRtasBuffer, rtasBufferSizeBytes, hParallelOperation, pBuildUserPtr, pBounds, pRtasBufferSizeBytes); } ze_result_t ZeWrapper::zeRTASParallelOperationCreateExp(ze_driver_handle_t hDriver, ze_rtas_parallel_operation_exp_handle_t* phParallelOperation) { if (!handle || !zeRTASParallelOperationCreateExpInternal) throw std::runtime_error("ZeWrapper not initialized, call ZeWrapper::init() first."); return zeRTASParallelOperationCreateExpInternal(hDriver, phParallelOperation); } ze_result_t ZeWrapper::zeRTASParallelOperationDestroyExp( ze_rtas_parallel_operation_exp_handle_t hParallelOperation ) { if (!handle || !zeRTASParallelOperationDestroyExpInternal) throw std::runtime_error("ZeWrapper not initialized, call ZeWrapper::init() first."); return zeRTASParallelOperationDestroyExpInternal( hParallelOperation ); }; ze_result_t ZeWrapper::zeRTASParallelOperationGetPropertiesExp( ze_rtas_parallel_operation_exp_handle_t hParallelOperation, ze_rtas_parallel_operation_exp_properties_t* pProperties ) { if (!handle || !zeRTASParallelOperationGetPropertiesExpInternal) throw std::runtime_error("ZeWrapper not initialized, call ZeWrapper::init() first."); return zeRTASParallelOperationGetPropertiesExpInternal( hParallelOperation, pProperties ); } ze_result_t ZeWrapper::zeRTASParallelOperationJoinExp( ze_rtas_parallel_operation_exp_handle_t hParallelOperation) { if (!handle || !zeRTASParallelOperationJoinExpInternal) throw std::runtime_error("ZeWrapper not initialized, call ZeWrapper::init() first."); return zeRTASParallelOperationJoinExpInternal(hParallelOperation); } level-zero-raytracing-support-1.0.0/level_zero/ze_wrapper.h000066400000000000000000000075401450534701400241550ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "ze_api.h" #if !defined(ZE_RTAS_BUILDER_EXP_NAME) #include "ze_rtas.h" #endif ////////////////////// // Debug extension #define ZE_STRUCTURE_TYPE_RTAS_BUILDER_BUILD_OP_DEBUG_EXP_DESC ((ze_structure_type_t)0x00020020) ///< ::ze_rtas_builder_build_op_debug_exp_desc_t typedef struct _ze_rtas_builder_build_op_debug_exp_desc_t { ze_structure_type_t stype; ///< [in] type of this structure const void* pNext; ///< [in][optional] must be null or a pointer to an extension-specific ///< structure (i.e. contains stype and pNext). void* dispatchGlobalsPtr; } ze_rtas_builder_build_op_debug_exp_desc_t; //////////////////// struct ZeWrapper { enum RTAS_BUILD_MODE { AUTO = 0, // try L0 implementation first and fallback to internal implementation INTERNAL = 1, // use internal RTAS build implementation LEVEL_ZERO = 2, // use Level Zero provided RTAS build implementation }; ~ZeWrapper(); static ze_result_t init(); static ze_result_t initRTASBuilder(ze_driver_handle_t hDriver, RTAS_BUILD_MODE rtas_build_mode = RTAS_BUILD_MODE::AUTO); static ze_result_t zeMemFree(ze_context_handle_t, void*); static ze_result_t zeMemAllocShared(ze_context_handle_t, const ze_device_mem_alloc_desc_t*, const ze_host_mem_alloc_desc_t*, size_t, size_t, ze_device_handle_t, void**); static ze_result_t zeDriverGetExtensionProperties(ze_driver_handle_t, uint32_t*, ze_driver_extension_properties_t*); static ze_result_t zeDeviceGetProperties(ze_device_handle_t, ze_device_properties_t*); static ze_result_t zeDeviceGetModuleProperties(ze_device_handle_t, ze_device_module_properties_t*); static ze_result_t zeRTASBuilderCreateExp(ze_driver_handle_t hDriver, const ze_rtas_builder_exp_desc_t *pDescriptor, ze_rtas_builder_exp_handle_t *phBuilder); static ze_result_t zeRTASBuilderDestroyExp(ze_rtas_builder_exp_handle_t hBuilder); static ze_result_t zeDriverRTASFormatCompatibilityCheckExp( ze_driver_handle_t hDriver, const ze_rtas_format_exp_t accelFormat, const ze_rtas_format_exp_t otherAccelFormat); static ze_result_t zeRTASBuilderGetBuildPropertiesExp(ze_rtas_builder_exp_handle_t hBuilder, const ze_rtas_builder_build_op_exp_desc_t* args, ze_rtas_builder_exp_properties_t* pProp); static ze_result_t zeRTASBuilderBuildExp(ze_rtas_builder_exp_handle_t hBuilder, const ze_rtas_builder_build_op_exp_desc_t* args, void *pScratchBuffer, size_t scratchBufferSizeBytes, void *pRtasBuffer, size_t rtasBufferSizeBytes, ze_rtas_parallel_operation_exp_handle_t hParallelOperation, void *pBuildUserPtr, ze_rtas_aabb_exp_t *pBounds, size_t *pRtasBufferSizeBytes); static ze_result_t zeRTASParallelOperationCreateExp(ze_driver_handle_t hDriver, ze_rtas_parallel_operation_exp_handle_t* phParallelOperation); static ze_result_t zeRTASParallelOperationDestroyExp( ze_rtas_parallel_operation_exp_handle_t hParallelOperation ); static ze_result_t zeRTASParallelOperationGetPropertiesExp( ze_rtas_parallel_operation_exp_handle_t hParallelOperation, ze_rtas_parallel_operation_exp_properties_t* pProperties ); static ze_result_t zeRTASParallelOperationJoinExp( ze_rtas_parallel_operation_exp_handle_t hParallelOperation); static RTAS_BUILD_MODE rtas_builder; }; level-zero-raytracing-support-1.0.0/level_zero_raytracing.rc.in000066400000000000000000000025211450534701400247760ustar00rootroot00000000000000#define VER_FILEVERSION @ZE_RAYTRACING_VERSION_MAJOR@,@ZE_RAYTRACING_VERSION_MINOR@,@ZE_RAYTRACING_VERSION_PATCH@ #define VER_FILEVERSION_STR "@ZE_RAYTRACING_VERSION_MAJOR@.@ZE_RAYTRACING_VERSION_MINOR@.@ZE_RAYTRACING_VERSION_PATCH@" #define VER_PRODUCTVERSION @ZE_RAYTRACING_VERSION_MAJOR@,@ZE_RAYTRACING_VERSION_MINOR@,@ZE_RAYTRACING_VERSION_PATCH@ #define VER_PRODUCTVERSION_STR "@ZE_RAYTRACING_VERSION_MAJOR@.@ZE_RAYTRACING_VERSION_MINOR@.@ZE_RAYTRACING_VERSION_PATCH@" #define VER_FILEDESCRIPTION_STR "oneAPI Level Zero Ray Tracing Support for Windows(R) Level Zero Drivers" #define VER_PRODUCT_NAME_STR "oneAPI Level Zero Ray Tracing Support for Windows(R)" #define VER_LEGALCOPYRIGHT_STR "Copyright (C) 2023 Intel Corporation" 1 VERSIONINFO FILEVERSION VER_FILEVERSION PRODUCTVERSION VER_PRODUCTVERSION BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904E4" BEGIN VALUE "FileDescription", VER_FILEDESCRIPTION_STR VALUE "FileVersion", VER_FILEVERSION_STR VALUE "ProductVersion", VER_PRODUCTVERSION_STR VALUE "ProductName", VER_PRODUCT_NAME_STR VALUE "LegalCopyright", VER_LEGALCOPYRIGHT_STR END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x409, 1252 END END level-zero-raytracing-support-1.0.0/rhel/000077500000000000000000000000001450534701400204045ustar00rootroot00000000000000level-zero-raytracing-support-1.0.0/rhel/intel-level-zero-gpu-raytracing.spec000066400000000000000000000024411450534701400274100ustar00rootroot00000000000000#it's changed by external script %global ver 1.0.0 %global rel 1 Name: intel-level-zero-gpu-raytracing Version: %{ver} Release: %{rel}%{?dist} Summary: Level Zero Ray Tracing Support library Group: System Environment/Libraries License: Apache2 URL: https://github.com/oneapi-src/level-zero-raytracing Source0: %{url}/archive/%{ver}/intel-level-zero-gpu-raytracing-%{ver}.tar.gz BuildRequires: make gcc-c++ cmake ninja-build git pkg-config %description The Level Zero Ray Tracing Support library implements high performance CPU based construction algorithms for 3D acceleration structures that are compatible with the ray tracing hardware of Intel GPUs. This library is used by Intel(R) oneAPI Level Zero to implement part of the RTAS builder extension. This library should not get used directly but only through Level Zero. . Level Zero Ray Tracing Support library %prep %autosetup -p1 -n %{name}-%{ver} %build mkdir build cd build %cmake .. \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX=/usr %make_build %install cd build %make_install %files %defattr(-,root,root) %config(noreplace) %license LICENSE.txt %license third-party-programs* %{_libdir}/libze_intel_gpu_raytracing.so %doc %changelog * Thu Jun 8 2023 Pavel Androniychuk - 1.0.0 - Spec file init level-zero-raytracing-support-1.0.0/rtbuild/000077500000000000000000000000001450534701400211175ustar00rootroot00000000000000level-zero-raytracing-support-1.0.0/rtbuild/CMakeLists.txt000066400000000000000000000022271450534701400236620ustar00rootroot00000000000000## Copyright 2009-2021 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 ADD_SUBDIRECTORY(sys) ADD_SUBDIRECTORY(simd) ADD_LIBRARY(embree_rthwif SHARED rtbuild.cpp qbvh6.cpp statistics.cpp ../level_zero_raytracing.rc) TARGET_LINK_LIBRARIES(embree_rthwif PUBLIC ${EMBREE_RTHWIF_SYCL} PRIVATE tbb simd sys) SET_TARGET_PROPERTIES(embree_rthwif PROPERTIES OUTPUT_NAME ze_intel_gpu_raytracing) TARGET_COMPILE_DEFINITIONS(embree_rthwif PRIVATE ZE_RAYTRACING) TARGET_INCLUDE_DIRECTORIES(embree_rthwif PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/..") IF (WIN32) ELSE() SET_TARGET_PROPERTIES(embree_rthwif PROPERTIES LINK_FLAGS -Wl,--version-script="${CMAKE_CURRENT_SOURCE_DIR}/export.linux.map") SET_SOURCE_FILES_PROPERTIES(rtbuild.cpp PROPERTIES OBJECT_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/export.linux.map") ENDIF() INSTALL(TARGETS embree_rthwif EXPORT ze_raytracing-targets LIBRARY NAMELINK_SKIP DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT lib RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT lib ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT devel) #INSTALL(EXPORT ze_raytracing-targets DESTINATION "${EMBREE_CMAKEEXPORT_DIR}" COMPONENT devel) level-zero-raytracing-support-1.0.0/rtbuild/algorithms/000077500000000000000000000000001450534701400232705ustar00rootroot00000000000000level-zero-raytracing-support-1.0.0/rtbuild/algorithms/parallel_for.h000066400000000000000000000104301450534701400261010ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "../sys/array.h" #include "../math/emath.h" #include "../math/range.h" // We need to define these to avoid implicit linkage against // tbb_debug.lib under Windows. When removing these lines debug build // under Windows fails. #define __TBB_NO_IMPLICIT_LINKAGE 1 #define __TBBMALLOC_NO_IMPLICIT_LINKAGE 1 #define TBB_SUPPRESS_DEPRECATED_MESSAGES 1 #define TBB_PREVIEW_ISOLATED_TASK_GROUP 1 #include "tbb/tbb.h" namespace embree { struct TaskScheduler { /* returns the total number of threads */ static __forceinline size_t threadCount() { #if TBB_INTERFACE_VERSION >= 9100 return tbb::this_task_arena::max_concurrency(); #else return tbb::task_scheduler_init::default_num_threads(); #endif } }; /* parallel_for without range */ template __forceinline void parallel_for( const Index N, const Func& func) { #if TBB_INTERFACE_VERSION >= 12002 tbb::task_group_context context; tbb::parallel_for(Index(0),N,Index(1),[&](Index i) { func(i); },context); if (context.is_group_execution_cancelled()) throw std::runtime_error("task cancelled"); #else tbb::parallel_for(Index(0),N,Index(1),[&](Index i) { func(i); }); if (tbb::task::self().is_cancelled()) throw std::runtime_error("task cancelled"); #endif } /* parallel for with range and granulatity */ template __forceinline void parallel_for( const Index first, const Index last, const Index minStepSize, const Func& func) { assert(first <= last); #if TBB_INTERFACE_VERSION >= 12002 tbb::task_group_context context; tbb::parallel_for(tbb::blocked_range(first,last,minStepSize),[&](const tbb::blocked_range& r) { func(range(r.begin(),r.end())); },context); if (context.is_group_execution_cancelled()) throw std::runtime_error("task cancelled"); #else tbb::parallel_for(tbb::blocked_range(first,last,minStepSize),[&](const tbb::blocked_range& r) { func(range(r.begin(),r.end())); }); if (tbb::task::self().is_cancelled()) throw std::runtime_error("task cancelled"); #endif } /* parallel for with range */ template __forceinline void parallel_for( const Index first, const Index last, const Func& func) { assert(first <= last); parallel_for(first,last,(Index)1,func); } #if (TBB_INTERFACE_VERSION > 4001) template __forceinline void parallel_for_static( const Index N, const Func& func) { #if TBB_INTERFACE_VERSION >= 12002 tbb::task_group_context context; tbb::parallel_for(Index(0),N,Index(1),[&](Index i) { func(i); },tbb::simple_partitioner(),context); if (context.is_group_execution_cancelled()) throw std::runtime_error("task cancelled"); #else tbb::parallel_for(Index(0),N,Index(1),[&](Index i) { func(i); },tbb::simple_partitioner()); if (tbb::task::self().is_cancelled()) throw std::runtime_error("task cancelled"); #endif } typedef tbb::affinity_partitioner affinity_partitioner; template __forceinline void parallel_for_affinity( const Index N, const Func& func, tbb::affinity_partitioner& ap) { #if TBB_INTERFACE_VERSION >= 12002 tbb::task_group_context context; tbb::parallel_for(Index(0),N,Index(1),[&](Index i) { func(i); },ap,context); if (context.is_group_execution_cancelled()) throw std::runtime_error("task cancelled"); #else tbb::parallel_for(Index(0),N,Index(1),[&](Index i) { func(i); },ap); if (tbb::task::self().is_cancelled()) throw std::runtime_error("task cancelled"); #endif } #else template __forceinline void parallel_for_static( const Index N, const Func& func) { parallel_for(N,func); } struct affinity_partitioner { }; template __forceinline void parallel_for_affinity( const Index N, const Func& func, affinity_partitioner& ap) { parallel_for(N,func); } #endif } level-zero-raytracing-support-1.0.0/rtbuild/algorithms/parallel_for_for.h000066400000000000000000000115671450534701400267630ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "parallel_for.h" namespace embree { template __forceinline void sequential_for_for( ArrayArray& array2, const size_t minStepSize, const Func& func ) { size_t k=0; for (size_t i=0; i!=array2.size(); ++i) { const size_t N = array2[i]->size(); if (N) func(array2[i],range(0,N),k); k+=N; } } class ParallelForForState { public: enum { MAX_TASKS = 64 }; __forceinline ParallelForForState () : taskCount(0) {} template __forceinline ParallelForForState (ArrayArray& array2, const size_t minStepSize) { init(array2,minStepSize); } template __forceinline ParallelForForState (const size_t numArrays, const SizeFunc& getSize, const size_t minStepSize) { init(numArrays,getSize,minStepSize); } template __forceinline void init ( const size_t numArrays, const SizeFunc& getSize, const size_t minStepSize ) { /* first calculate total number of elements */ size_t N = 0; for (size_t i=0; iN = N; /* calculate number of tasks to use */ const size_t numThreads = TaskScheduler::threadCount(); const size_t numBlocks = (N+minStepSize-1)/minStepSize; taskCount = max(size_t(1),min(numThreads,numBlocks,size_t(ParallelForForState::MAX_TASKS))); /* calculate start (i,j) for each task */ size_t taskIndex = 0; i0[taskIndex] = 0; j0[taskIndex] = 0; size_t k0 = (++taskIndex)*N/taskCount; for (size_t i=0, k=0; taskIndex < taskCount; i++) { assert(i= k0 && taskIndex < taskCount) { assert(taskIndex __forceinline void init ( ArrayArray& array2, const size_t minStepSize ) { init(array2.size(),[&](size_t i) { return array2[i] ? array2[i]->size() : 0; },minStepSize); } __forceinline size_t size() const { return N; } public: size_t i0[MAX_TASKS]; size_t j0[MAX_TASKS]; size_t taskCount; size_t N; }; template __forceinline void parallel_for_for( ArrayArray& array2, const size_t minStepSize, const Func& func ) { ParallelForForState state(array2,minStepSize); parallel_for(state.taskCount, [&](const size_t taskIndex) { /* calculate range */ const size_t k0 = (taskIndex+0)*state.size()/state.taskCount; const size_t k1 = (taskIndex+1)*state.size()/state.taskCount; size_t i0 = state.i0[taskIndex]; size_t j0 = state.j0[taskIndex]; /* iterate over arrays */ size_t k=k0; for (size_t i=i0; ksize() : 0; const size_t r0 = j0, r1 = min(N,r0+k1-k); if (r1 > r0) func(array2[i],range(r0,r1),k); k+=r1-r0; j0 = 0; } }); } template __forceinline void parallel_for_for( ArrayArray& array2, const Func& func ) { parallel_for_for(array2,1,func); } template __forceinline Value parallel_for_for_reduce( ArrayArray& array2, const size_t minStepSize, const Value& identity, const Func& func, const Reduction& reduction ) { ParallelForForState state(array2,minStepSize); Value temp[ParallelForForState::MAX_TASKS]; for (size_t i=0; isize() : 0; const size_t r0 = j0, r1 = min(N,r0+k1-k); if (r1 > r0) temp[taskIndex] = reduction(temp[taskIndex],func(array2[i],range(r0,r1),k)); k+=r1-r0; j0 = 0; } }); Value ret = identity; for (size_t i=0; i __forceinline Value parallel_for_for_reduce( ArrayArray& array2, const Value& identity, const Func& func, const Reduction& reduction) { return parallel_for_for_reduce(array2,1,identity,func,reduction); } } level-zero-raytracing-support-1.0.0/rtbuild/algorithms/parallel_for_for_prefix_sum.h000066400000000000000000000137421450534701400312210ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "parallel_for_for.h" #include "parallel_prefix_sum.h" namespace embree { template struct ParallelForForPrefixSumState : public ParallelForForState { __forceinline ParallelForForPrefixSumState () {} template __forceinline ParallelForForPrefixSumState (ArrayArray& array2, const size_t minStepSize) : ParallelForForState(array2,minStepSize) {} template __forceinline ParallelForForPrefixSumState (size_t numArrays, const SizeFunc& getSize, const size_t minStepSize) : ParallelForForState(numArrays,getSize,minStepSize) {} ParallelPrefixSumState prefix_state; }; template __forceinline Value parallel_for_for_prefix_sum0_( ParallelForForPrefixSumState& state, Index minStepSize, const SizeFunc& getSize, const Value& identity, const Func& func, const Reduction& reduction) { /* calculate number of tasks to use */ const size_t taskCount = state.taskCount; /* perform parallel prefix sum */ parallel_for(taskCount, [&](const size_t taskIndex) { const size_t k0 = (taskIndex+0)*state.size()/taskCount; const size_t k1 = (taskIndex+1)*state.size()/taskCount; size_t i0 = state.i0[taskIndex]; size_t j0 = state.j0[taskIndex]; /* iterate over arrays */ size_t k=k0; Value N=identity; for (size_t i=i0; k r0) N = reduction(N, func((Index)i,range((Index)r0,(Index)r1),(Index)k)); k+=r1-r0; j0 = 0; } state.prefix_state.counts[taskIndex] = N; }); /* calculate prefix sum */ Value sum=identity; for (size_t i=0; i __forceinline Value parallel_for_for_prefix_sum1_( ParallelForForPrefixSumState& state, Index minStepSize, const SizeFunc& getSize, const Value& identity, const Func& func, const Reduction& reduction) { /* calculate number of tasks to use */ const size_t taskCount = state.taskCount; /* perform parallel prefix sum */ parallel_for(taskCount, [&](const size_t taskIndex) { const size_t k0 = (taskIndex+0)*state.size()/taskCount; const size_t k1 = (taskIndex+1)*state.size()/taskCount; size_t i0 = state.i0[taskIndex]; size_t j0 = state.j0[taskIndex]; /* iterate over arrays */ size_t k=k0; Value N=identity; for (size_t i=i0; k r0) N = reduction(N, func((Index)i,range((Index)r0,(Index)r1),(Index)k,reduction(state.prefix_state.sums[taskIndex],N))); k+=r1-r0; j0 = 0; } state.prefix_state.counts[taskIndex] = N; }); /* calculate prefix sum */ Value sum=identity; for (size_t i=0; i __forceinline Value parallel_for_for_prefix_sum0( ParallelForForPrefixSumState& state, ArrayArray& array2, Index minStepSize, const Value& identity, const Func& func, const Reduction& reduction) { return parallel_for_for_prefix_sum0_(state,minStepSize, [&](Index i) { return array2[i] ? array2[i]->size() : 0; }, identity, [&](Index i, const range& r, Index k) { return func(array2[i], r, k, i); }, reduction); } template __forceinline Value parallel_for_for_prefix_sum1( ParallelForForPrefixSumState& state, ArrayArray& array2, Index minStepSize, const Value& identity, const Func& func, const Reduction& reduction) { return parallel_for_for_prefix_sum1_(state,minStepSize, [&](Index i) { return array2[i] ? array2[i]->size() : 0; }, identity, [&](Index i, const range& r, Index k, const Value& base) { return func(array2[i], r, k, i, base); }, reduction); } template __forceinline Value parallel_for_for_prefix_sum0( ParallelForForPrefixSumState& state, ArrayArray& array2, const Value& identity, const Func& func, const Reduction& reduction) { return parallel_for_for_prefix_sum0(state,array2,size_t(1),identity,func,reduction); } template __forceinline Value parallel_for_for_prefix_sum1( ParallelForForPrefixSumState& state, ArrayArray& array2, const Value& identity, const Func& func, const Reduction& reduction) { return parallel_for_for_prefix_sum1(state,array2,size_t(1),identity,func,reduction); } } level-zero-raytracing-support-1.0.0/rtbuild/algorithms/parallel_partition.h000066400000000000000000000254011450534701400273300ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "parallel_for.h" #include "../math/range.h" namespace embree { /* serial partitioning */ template __forceinline size_t serial_partitioning(T* array, const size_t begin, const size_t end, V& leftReduction, V& rightReduction, const IsLeft& is_left, const Reduction_T& reduction_t) { T* l = array + begin; T* r = array + end - 1; while(1) { /* *l < pivot */ while (likely(l <= r && is_left(*l) )) { //prefetchw(l+4); // FIXME: enable? reduction_t(leftReduction,*l); ++l; } /* *r >= pivot) */ while (likely(l <= r && !is_left(*r))) { //prefetchw(r-4); FIXME: enable? reduction_t(rightReduction,*r); --r; } if (r class __aligned(64) parallel_partition_task { ALIGNED_CLASS_(64); private: static const size_t MAX_TASKS = 64; T* array; size_t N; const IsLeft& is_left; const Reduction_T& reduction_t; const Reduction_V& reduction_v; const Vi& identity; size_t numTasks; __aligned(64) size_t counter_start[MAX_TASKS+1]; __aligned(64) size_t counter_left[MAX_TASKS+1]; __aligned(64) range leftMisplacedRanges[MAX_TASKS]; __aligned(64) range rightMisplacedRanges[MAX_TASKS]; __aligned(64) V leftReductions[MAX_TASKS]; __aligned(64) V rightReductions[MAX_TASKS]; public: __forceinline parallel_partition_task(T* array, const size_t N, const Vi& identity, const IsLeft& is_left, const Reduction_T& reduction_t, const Reduction_V& reduction_v, const size_t BLOCK_SIZE) : array(array), N(N), is_left(is_left), reduction_t(reduction_t), reduction_v(reduction_v), identity(identity), numTasks(min((N+BLOCK_SIZE-1)/BLOCK_SIZE,min(TaskScheduler::threadCount(),MAX_TASKS))) {} __forceinline const range* findStartRange(size_t& index, const range* const r, const size_t numRanges) { size_t i = 0; while(index >= (size_t)r[i].size()) { assert(i < numRanges); index -= (size_t)r[i].size(); i++; } return &r[i]; } __forceinline void swapItemsInMisplacedRanges(const size_t numLeftMisplacedRanges, const size_t numRightMisplacedRanges, const size_t startID, const size_t endID) { size_t leftLocalIndex = startID; size_t rightLocalIndex = startID; const range* l_range = findStartRange(leftLocalIndex,leftMisplacedRanges,numLeftMisplacedRanges); const range* r_range = findStartRange(rightLocalIndex,rightMisplacedRanges,numRightMisplacedRanges); size_t l_left = l_range->size() - leftLocalIndex; size_t r_left = r_range->size() - rightLocalIndex; T *__restrict__ l = &array[l_range->begin() + leftLocalIndex]; T *__restrict__ r = &array[r_range->begin() + rightLocalIndex]; size_t size = endID - startID; size_t items = min(size,min(l_left,r_left)); while (size) { if (unlikely(l_left == 0)) { l_range++; l_left = l_range->size(); l = &array[l_range->begin()]; items = min(size,min(l_left,r_left)); } if (unlikely(r_left == 0)) { r_range++; r_left = r_range->size(); r = &array[r_range->begin()]; items = min(size,min(l_left,r_left)); } size -= items; l_left -= items; r_left -= items; while(items) { items--; xchg(*l++,*r++); } } } __forceinline size_t partition(V& leftReduction, V& rightReduction) { /* partition the individual ranges for each task */ parallel_for(numTasks,[&] (const size_t taskID) { const size_t startID = (taskID+0)*N/numTasks; const size_t endID = (taskID+1)*N/numTasks; V local_left(identity); V local_right(identity); const size_t mid = serial_partitioning(array,startID,endID,local_left,local_right,is_left,reduction_t); counter_start[taskID] = startID; counter_left [taskID] = mid-startID; leftReductions[taskID] = local_left; rightReductions[taskID] = local_right; }); counter_start[numTasks] = N; counter_left[numTasks] = 0; /* finalize the reductions */ for (size_t i=0; i globalLeft (0,mid); const range globalRight(mid,N); /* calculate all left and right ranges that are on the wrong global side */ size_t numMisplacedRangesLeft = 0; size_t numMisplacedRangesRight = 0; size_t numMisplacedItemsLeft MAYBE_UNUSED = 0; size_t numMisplacedItemsRight MAYBE_UNUSED = 0; for (size_t i=0; i left_range (counter_start[i], counter_start[i] + counter_left[i]); const range right_range(counter_start[i] + counter_left[i], counter_start[i+1]); const range left_misplaced = globalLeft. intersect(right_range); const range right_misplaced = globalRight.intersect(left_range); if (!left_misplaced.empty()) { numMisplacedItemsLeft += left_misplaced.size(); leftMisplacedRanges[numMisplacedRangesLeft++] = left_misplaced; } if (!right_misplaced.empty()) { numMisplacedItemsRight += right_misplaced.size(); rightMisplacedRanges[numMisplacedRangesRight++] = right_misplaced; } } assert( numMisplacedItemsLeft == numMisplacedItemsRight ); /* if no items are misplaced we are done */ if (numMisplacedItemsLeft == 0) return mid; /* otherwise we copy the items to the right place in parallel */ parallel_for(numTasks,[&] (const size_t taskID) { const size_t startID = (taskID+0)*numMisplacedItemsLeft/numTasks; const size_t endID = (taskID+1)*numMisplacedItemsLeft/numTasks; swapItemsInMisplacedRanges(numMisplacedRangesLeft,numMisplacedRangesRight,startID,endID); }); return mid; } }; template __noinline size_t parallel_partitioning(T* array, const size_t begin, const size_t end, const Vi &identity, V &leftReduction, V &rightReduction, const IsLeft& is_left, const Reduction_T& reduction_t, const Reduction_V& reduction_v, size_t BLOCK_SIZE = 128) { /* fall back to single threaded partitioning for small N */ if (unlikely(end-begin < BLOCK_SIZE)) return serial_partitioning(array,begin,end,leftReduction,rightReduction,is_left,reduction_t); /* otherwise use parallel code */ else { typedef parallel_partition_task partition_task; std::unique_ptr p(new partition_task(&array[begin],end-begin,identity,is_left,reduction_t,reduction_v,BLOCK_SIZE)); return begin+p->partition(leftReduction,rightReduction); } } template __noinline size_t parallel_partitioning(T* array, const size_t begin, const size_t end, const Vi &identity, V &leftReduction, V &rightReduction, const IsLeft& is_left, const Reduction_T& reduction_t, const Reduction_V& reduction_v, size_t BLOCK_SIZE, size_t PARALLEL_THRESHOLD) { /* fall back to single threaded partitioning for small N */ if (unlikely(end-begin < PARALLEL_THRESHOLD)) return serial_partitioning(array,begin,end,leftReduction,rightReduction,is_left,reduction_t); /* otherwise use parallel code */ else { typedef parallel_partition_task partition_task; std::unique_ptr p(new partition_task(&array[begin],end-begin,identity,is_left,reduction_t,reduction_v,BLOCK_SIZE)); return begin+p->partition(leftReduction,rightReduction); } } template inline size_t parallel_partitioning(T* array, const size_t begin, const size_t end, const IsLeft& is_left, size_t BLOCK_SIZE = 128) { size_t leftReduction = 0; size_t rightReduction = 0; return parallel_partitioning( array,begin,end,0,leftReduction,rightReduction,is_left, [] (size_t& t,const T& ref) { }, [] (size_t& t0,size_t& t1) { }, BLOCK_SIZE); } } level-zero-raytracing-support-1.0.0/rtbuild/algorithms/parallel_prefix_sum.h000066400000000000000000000054341450534701400275040ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "parallel_for.h" namespace embree { template struct ParallelPrefixSumState { enum { MAX_TASKS = 64 }; Value counts[MAX_TASKS]; Value sums [MAX_TASKS]; }; template __forceinline Value parallel_prefix_sum( ParallelPrefixSumState& state, Index first, Index last, Index minStepSize, const Value& identity, const Func& func, const Reduction& reduction) { /* calculate number of tasks to use */ const size_t numThreads = TaskScheduler::threadCount(); const size_t numBlocks = (last-first+minStepSize-1)/minStepSize; const size_t taskCount = min(numThreads,numBlocks,size_t(ParallelPrefixSumState::MAX_TASKS)); /* perform parallel prefix sum */ parallel_for(taskCount, [&](const size_t taskIndex) { const size_t i0 = first+(taskIndex+0)*(last-first)/taskCount; const size_t i1 = first+(taskIndex+1)*(last-first)/taskCount; state.counts[taskIndex] = func(range(i0,i1),state.sums[taskIndex]); }); /* calculate prefix sum */ Value sum=identity; for (size_t i=0; i __forceinline Value parallel_prefix_sum(const SrcArray& src, DstArray& dst, size_t N, const Value& identity, const Add& add, const size_t SINGLE_THREAD_THRESHOLD = 4096) { /* perform single threaded prefix operation for small N */ if (N < SINGLE_THREAD_THRESHOLD) { Value sum=identity; for (size_t i=0; i state; /* initial run just sets up start values for subtasks */ parallel_prefix_sum( state, size_t(0), size_t(N), size_t(1024), identity, [&](const range& r, const Value& sum) -> Value { Value s = identity; for (size_t i=r.begin(); i& r, const Value& sum) -> Value { Value s = identity; for (size_t i=r.begin(); i __forceinline Value sequential_reduce( const Index first, const Index last, const Value& identity, const Func& func, const Reduction& reduction ) { return func(range(first,last)); } template __forceinline Value sequential_reduce( const Index first, const Index last, const Index minStepSize, const Value& identity, const Func& func, const Reduction& reduction ) { return func(range(first,last)); } template __noinline Value parallel_reduce_internal( Index taskCount, const Index first, const Index last, const Index minStepSize, const Value& identity, const Func& func, const Reduction& reduction ) { const Index maxTasks = 512; const Index threadCount = (Index) TaskScheduler::threadCount(); taskCount = min(taskCount,threadCount,maxTasks); /* parallel invocation of all tasks */ dynamic_large_stack_array(Value,values,taskCount,8192); // consumes at most 8192 bytes on the stack parallel_for(taskCount, [&](const Index taskIndex) { const Index k0 = first+(taskIndex+0)*(last-first)/taskCount; const Index k1 = first+(taskIndex+1)*(last-first)/taskCount; values[taskIndex] = func(range(k0,k1)); }); /* perform reduction over all tasks */ Value v = identity; for (Index i=0; i __forceinline Value parallel_reduce( const Index first, const Index last, const Index minStepSize, const Value& identity, const Func& func, const Reduction& reduction ) { #if defined(TASKING_INTERNAL) && !defined(TASKING_TBB) /* fast path for small number of iterations */ Index taskCount = (last-first+minStepSize-1)/minStepSize; if (likely(taskCount == 1)) { return func(range(first,last)); } return parallel_reduce_internal(taskCount,first,last,minStepSize,identity,func,reduction); #elif defined(TASKING_TBB) #if TBB_INTERFACE_VERSION >= 12002 tbb::task_group_context context; const Value v = tbb::parallel_reduce(tbb::blocked_range(first,last,minStepSize),identity, [&](const tbb::blocked_range& r, const Value& start) { return reduction(start,func(range(r.begin(),r.end()))); }, reduction,context); if (context.is_group_execution_cancelled()) throw std::runtime_error("task cancelled"); return v; #else const Value v = tbb::parallel_reduce(tbb::blocked_range(first,last,minStepSize),identity, [&](const tbb::blocked_range& r, const Value& start) { return reduction(start,func(range(r.begin(),r.end()))); }, reduction); if (tbb::task::self().is_cancelled()) throw std::runtime_error("task cancelled"); return v; #endif #else // TASKING_PPL struct AlignedValue { char storage[__alignof(Value)+sizeof(Value)]; static uintptr_t alignUp(uintptr_t p, size_t a) { return p + (~(p - 1) % a); }; Value* getValuePtr() { return reinterpret_cast(alignUp(uintptr_t(storage), __alignof(Value))); } const Value* getValuePtr() const { return reinterpret_cast(alignUp(uintptr_t(storage), __alignof(Value))); } AlignedValue(const Value& v) { new(getValuePtr()) Value(v); } AlignedValue(const AlignedValue& v) { new(getValuePtr()) Value(*v.getValuePtr()); } AlignedValue(const AlignedValue&& v) { new(getValuePtr()) Value(*v.getValuePtr()); }; AlignedValue& operator = (const AlignedValue& v) { *getValuePtr() = *v.getValuePtr(); return *this; }; AlignedValue& operator = (const AlignedValue&& v) { *getValuePtr() = *v.getValuePtr(); return *this; }; operator Value() const { return *getValuePtr(); } }; struct Iterator_Index { Index v; typedef std::forward_iterator_tag iterator_category; typedef AlignedValue value_type; typedef Index difference_type; typedef Index distance_type; typedef AlignedValue* pointer; typedef AlignedValue& reference; __forceinline Iterator_Index() {} __forceinline Iterator_Index(Index v) : v(v) {} __forceinline bool operator== (Iterator_Index other) { return v == other.v; } __forceinline bool operator!= (Iterator_Index other) { return v != other.v; } __forceinline Iterator_Index operator++() { return Iterator_Index(++v); } __forceinline Iterator_Index operator++(int) { return Iterator_Index(v++); } }; auto range_reduction = [&](Iterator_Index begin, Iterator_Index end, const AlignedValue& start) { assert(begin.v < end.v); return reduction(start, func(range(begin.v, end.v))); }; const Value v = concurrency::parallel_reduce(Iterator_Index(first), Iterator_Index(last), AlignedValue(identity), range_reduction, reduction); return v; #endif } template __forceinline Value parallel_reduce( const Index first, const Index last, const Index minStepSize, const Index parallel_threshold, const Value& identity, const Func& func, const Reduction& reduction ) { if (likely(last-first < parallel_threshold)) { return func(range(first,last)); } else { return parallel_reduce(first,last,minStepSize,identity,func,reduction); } } template __forceinline Value parallel_reduce( const range range, const Index minStepSize, const Index parallel_threshold, const Value& identity, const Func& func, const Reduction& reduction ) { return parallel_reduce(range.begin(),range.end(),minStepSize,parallel_threshold,identity,func,reduction); } template __forceinline Value parallel_reduce( const Index first, const Index last, const Value& identity, const Func& func, const Reduction& reduction ) { auto funcr = [&] ( const range r ) { Value v = identity; for (Index i=r.begin(); i __forceinline Value parallel_reduce( const range range, const Value& identity, const Func& func, const Reduction& reduction ) { return parallel_reduce(range.begin(),range.end(),Index(1),identity,func,reduction); } } level-zero-raytracing-support-1.0.0/rtbuild/algorithms/parallel_sort.h000066400000000000000000000312711450534701400263100ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "../simd/simd.h" #include "parallel_for.h" #include namespace embree { template __forceinline void insertionsort_ascending(T *__restrict__ array, const size_t length) { for(size_t i = 1;i 0 && v < array[j-1]) { array[j] = array[j-1]; --j; } array[j] = v; } } template __forceinline void insertionsort_decending(T *__restrict__ array, const size_t length) { for(size_t i = 1;i 0 && v > array[j-1]) { array[j] = array[j-1]; --j; } array[j] = v; } } template void quicksort_ascending(T *__restrict__ t, const ssize_t begin, const ssize_t end) { if (likely(begin < end)) { const T pivotvalue = t[begin]; ssize_t left = begin - 1; ssize_t right = end + 1; while(1) { while (t[--right] > pivotvalue); while (t[++left] < pivotvalue); if (left >= right) break; const T temp = t[right]; t[right] = t[left]; t[left] = temp; } const int pivot = right; quicksort_ascending(t, begin, pivot); quicksort_ascending(t, pivot + 1, end); } } template void quicksort_decending(T *__restrict__ t, const ssize_t begin, const ssize_t end) { if (likely(begin < end)) { const T pivotvalue = t[begin]; ssize_t left = begin - 1; ssize_t right = end + 1; while(1) { while (t[--right] < pivotvalue); while (t[++left] > pivotvalue); if (left >= right) break; const T temp = t[right]; t[right] = t[left]; t[left] = temp; } const int pivot = right; quicksort_decending(t, begin, pivot); quicksort_decending(t, pivot + 1, end); } } template void quicksort_insertionsort_ascending(T *__restrict__ t, const ssize_t begin, const ssize_t end) { if (likely(begin < end)) { const ssize_t size = end-begin+1; if (likely(size <= THRESHOLD)) { insertionsort_ascending(&t[begin],size); } else { const T pivotvalue = t[begin]; ssize_t left = begin - 1; ssize_t right = end + 1; while(1) { while (t[--right] > pivotvalue); while (t[++left] < pivotvalue); if (left >= right) break; const T temp = t[right]; t[right] = t[left]; t[left] = temp; } const ssize_t pivot = right; quicksort_insertionsort_ascending(t, begin, pivot); quicksort_insertionsort_ascending(t, pivot + 1, end); } } } template void quicksort_insertionsort_decending(T *__restrict__ t, const ssize_t begin, const ssize_t end) { if (likely(begin < end)) { const ssize_t size = end-begin+1; if (likely(size <= THRESHOLD)) { insertionsort_decending(&t[begin],size); } else { const T pivotvalue = t[begin]; ssize_t left = begin - 1; ssize_t right = end + 1; while(1) { while (t[--right] < pivotvalue); while (t[++left] > pivotvalue); if (left >= right) break; const T temp = t[right]; t[right] = t[left]; t[left] = temp; } const ssize_t pivot = right; quicksort_insertionsort_decending(t, begin, pivot); quicksort_insertionsort_decending(t, pivot + 1, end); } } } template static void radixsort32(T* const morton, const size_t num, const unsigned int shift = 3*8) { static const unsigned int BITS = 8; static const unsigned int BUCKETS = (1 << BITS); static const unsigned int CMP_SORT_THRESHOLD = 16; __aligned(64) unsigned int count[BUCKETS]; /* clear buckets */ for (size_t i=0;i> shift) & (BUCKETS-1)]++; /* prefix sums */ __aligned(64) unsigned int head[BUCKETS]; __aligned(64) unsigned int tail[BUCKETS]; head[0] = 0; for (size_t i=1; i> shift) & (BUCKETS-1); if (b == i) break; std::swap(v,morton[head[b]++]); } assert((unsigned(v) >> shift & (BUCKETS-1)) == i); morton[head[i]++] = v; } } if (shift == 0) return; size_t offset = 0; for (size_t i=0;i> shift) & (BUCKETS-1)) == i); if (unlikely(count[i] < CMP_SORT_THRESHOLD)) insertionsort_ascending(morton + offset, count[i]); else radixsort32(morton + offset, count[i], shift-BITS); for (size_t j=offset;j class ParallelRadixSort { static const size_t MAX_TASKS = 64; static const size_t BITS = 8; static const size_t BUCKETS = (1 << BITS); typedef unsigned int TyRadixCount[BUCKETS]; template static bool compare(const T& v0, const T& v1) { return (Key)v0 < (Key)v1; } private: ParallelRadixSort (const ParallelRadixSort& other) DELETED; // do not implement ParallelRadixSort& operator= (const ParallelRadixSort& other) DELETED; // do not implement public: ParallelRadixSort (Ty* const src, Ty* const tmp, const size_t N) : radixCount(nullptr), src(src), tmp(tmp), N(N) {} void sort(const size_t blockSize) { assert(blockSize > 0); /* perform single threaded sort for small N */ if (N<=blockSize) // handles also special case of 0! { /* do inplace sort inside destination array */ std::sort(src,src+N,compare); } /* perform parallel sort for large N */ else { const size_t numThreads = min((N+blockSize-1)/blockSize,TaskScheduler::threadCount(),size_t(MAX_TASKS)); tbbRadixSort(numThreads); } } ~ParallelRadixSort() { alignedFree(radixCount); radixCount = nullptr; } private: void tbbRadixIteration0(const Key shift, const Ty* __restrict const src, Ty* __restrict const dst, const size_t threadIndex, const size_t threadCount) { const size_t startID = (threadIndex+0)*N/threadCount; const size_t endID = (threadIndex+1)*N/threadCount; /* mask to extract some number of bits */ const Key mask = BUCKETS-1; /* count how many items go into the buckets */ for (size_t i=0; i> (size_t)shift) & (size_t)mask; #else const Key index = ((Key)src[i] >> shift) & mask; #endif count[index]++; } } void tbbRadixIteration1(const Key shift, const Ty* __restrict const src, Ty* __restrict const dst, const size_t threadIndex, const size_t threadCount) { const size_t startID = (threadIndex+0)*N/threadCount; const size_t endID = (threadIndex+1)*N/threadCount; /* mask to extract some number of bits */ const Key mask = BUCKETS-1; /* calculate total number of items for each bucket */ __aligned(64) unsigned int total[BUCKETS]; /* for (size_t i=0; i> (size_t)shift) & (size_t)mask; #else const size_t index = ((Key)src[i] >> shift) & mask; #endif dst[offset[index]++] = elt; } } void tbbRadixIteration(const Key shift, const bool last, const Ty* __restrict src, Ty* __restrict dst, const size_t numTasks) { affinity_partitioner ap; parallel_for_affinity(numTasks,[&] (size_t taskIndex) { tbbRadixIteration0(shift,src,dst,taskIndex,numTasks); },ap); parallel_for_affinity(numTasks,[&] (size_t taskIndex) { tbbRadixIteration1(shift,src,dst,taskIndex,numTasks); },ap); } void tbbRadixSort(const size_t numTasks) { radixCount = (TyRadixCount*) alignedMalloc(MAX_TASKS*sizeof(TyRadixCount),64); if (sizeof(Key) == sizeof(uint32_t)) { tbbRadixIteration(0*BITS,0,src,tmp,numTasks); tbbRadixIteration(1*BITS,0,tmp,src,numTasks); tbbRadixIteration(2*BITS,0,src,tmp,numTasks); tbbRadixIteration(3*BITS,1,tmp,src,numTasks); } else if (sizeof(Key) == sizeof(uint64_t)) { tbbRadixIteration(0*BITS,0,src,tmp,numTasks); tbbRadixIteration(1*BITS,0,tmp,src,numTasks); tbbRadixIteration(2*BITS,0,src,tmp,numTasks); tbbRadixIteration(3*BITS,0,tmp,src,numTasks); tbbRadixIteration(4*BITS,0,src,tmp,numTasks); tbbRadixIteration(5*BITS,0,tmp,src,numTasks); tbbRadixIteration(6*BITS,0,src,tmp,numTasks); tbbRadixIteration(7*BITS,1,tmp,src,numTasks); } } private: TyRadixCount* radixCount; Ty* const src; Ty* const tmp; const size_t N; }; template void radix_sort(Ty* const src, Ty* const tmp, const size_t N, const size_t blockSize = 8192) { ParallelRadixSort(src,tmp,N).sort(blockSize); } template void radix_sort(Ty* const src, Ty* const tmp, const size_t N, const size_t blockSize = 8192) { ParallelRadixSort(src,tmp,N).sort(blockSize); } template void radix_sort_u32(Ty* const src, Ty* const tmp, const size_t N, const size_t blockSize = 8192) { radix_sort(src,tmp,N,blockSize); } template void radix_sort_u64(Ty* const src, Ty* const tmp, const size_t N, const size_t blockSize = 8192) { radix_sort(src,tmp,N,blockSize); } } level-zero-raytracing-support-1.0.0/rtbuild/builders/000077500000000000000000000000001450534701400227305ustar00rootroot00000000000000level-zero-raytracing-support-1.0.0/rtbuild/builders/heuristic_binning.h000066400000000000000000000550501450534701400266110ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "priminfo.h" #include "../algorithms/parallel_reduce.h" #include "../algorithms/parallel_partition.h" namespace embree { namespace isa { /*! mapping into bins */ template struct BinMapping { public: __forceinline BinMapping() {} /*! calculates the mapping */ __forceinline BinMapping(size_t N, const BBox3fa& centBounds) { num = min(BINS,size_t(4.0f + 0.05f*N)); assert(num >= 1); const vfloat4 eps = 1E-34f; const vfloat4 diag = max(eps, (vfloat4) centBounds.size()); scale = select(diag > eps,vfloat4(0.99f*num)/diag,vfloat4(0.0f)); ofs = (vfloat4) centBounds.lower; } /*! calculates the mapping */ __forceinline BinMapping(const BBox3fa& centBounds) { num = BINS; const vfloat4 eps = 1E-34f; const vfloat4 diag = max(eps, (vfloat4) centBounds.size()); scale = select(diag > eps,vfloat4(0.99f*num)/diag,vfloat4(0.0f)); ofs = (vfloat4) centBounds.lower; } /*! calculates the mapping */ template __forceinline BinMapping(const PrimInfo& pinfo) { const vfloat4 eps = 1E-34f; num = min(BINS,size_t(4.0f + 0.05f*pinfo.size())); const vfloat4 diag = max(eps,(vfloat4) pinfo.centBounds.size()); scale = select(diag > eps,vfloat4(0.99f*num)/diag,vfloat4(0.0f)); ofs = (vfloat4) pinfo.centBounds.lower; } /*! returns number of bins */ __forceinline size_t size() const { return num; } /*! slower but safe binning */ __forceinline Vec3ia bin(const Vec3fa& p) const { const vint4 i = floori((vfloat4(p)-ofs)*scale); assert(i[0] >= 0 && (size_t)i[0] < num); assert(i[1] >= 0 && (size_t)i[1] < num); assert(i[2] >= 0 && (size_t)i[2] < num); // we clamp to handle corner cases that could calculate out of bounds bin return Vec3ia(clamp(i,vint4(0),vint4(num-1))); } /*! faster but unsafe binning */ __forceinline Vec3ia bin_unsafe(const Vec3fa& p) const { return Vec3ia(floori((vfloat4(p)-ofs)*scale)); } /*! faster but unsafe binning */ template __forceinline Vec3ia bin_unsafe(const PrimRef& p) const { return bin_unsafe(p.binCenter()); } /*! faster but unsafe binning */ template __forceinline Vec3ia bin_unsafe(const PrimRef& p, const BinBoundsAndCenter& binBoundsAndCenter) const { return bin_unsafe(binBoundsAndCenter.binCenter(p)); } template __forceinline bool bin_unsafe(const PrimRef& ref, const vint4& vSplitPos, const vbool4& splitDimMask) const // FIXME: rename to isLeft { return any(((vint4)bin_unsafe(center2(ref.bounds())) < vSplitPos) & splitDimMask); } /*! calculates left spatial position of bin */ __forceinline float pos(const size_t bin, const size_t dim) const { return madd(float(bin),1.0f / scale[dim],ofs[dim]); } /*! returns true if the mapping is invalid in some dimension */ __forceinline bool invalid(const size_t dim) const { return scale[dim] == 0.0f; } /*! stream output */ friend embree_ostream operator<<(embree_ostream cout, const BinMapping& mapping) { return cout << "BinMapping { num = " << mapping.num << ", ofs = " << mapping.ofs << ", scale = " << mapping.scale << "}"; } public: size_t num; vfloat4 ofs,scale; //!< linear function that maps to bin ID }; /*! stores all information to perform some split */ template struct BinSplit { enum { SPLIT_OBJECT = 0, SPLIT_FALLBACK = 1, SPLIT_ENFORCE = 2, // splits with larger ID are enforced in createLargeLeaf even if we could create a leaf already SPLIT_TEMPORAL = 2, SPLIT_GEOMID = 3, }; /*! construct an invalid split by default */ __forceinline BinSplit() : sah(inf), dim(-1), pos(0), data(0) {} __forceinline BinSplit(float sah, unsigned data, int dim = 0, float fpos = 0) : sah(sah), dim(dim), fpos(fpos), data(data) {} /*! constructs specified split */ __forceinline BinSplit(float sah, int dim, int pos, const BinMapping& mapping) : sah(sah), dim(dim), pos(pos), data(0), mapping(mapping) {} /*! tests if this split is valid */ __forceinline bool valid() const { return dim != -1; } /*! calculates surface area heuristic for performing the split */ __forceinline float splitSAH() const { return sah; } /*! stream output */ friend embree_ostream operator<<(embree_ostream cout, const BinSplit& split) { return cout << "BinSplit { sah = " << split.sah << ", dim = " << split.dim << ", pos = " << split.pos << "}"; } public: float sah; //!< SAH cost of the split int dim; //!< split dimension union { int pos; float fpos; }; //!< bin index for splitting unsigned int data; //!< extra optional split data BinMapping mapping; //!< mapping into bins }; /*! stores extended information about the split */ template struct SplitInfoT { __forceinline SplitInfoT () {} __forceinline SplitInfoT (size_t leftCount, const BBox& leftBounds, size_t rightCount, const BBox& rightBounds) : leftCount(leftCount), rightCount(rightCount), leftBounds(leftBounds), rightBounds(rightBounds) {} public: size_t leftCount,rightCount; BBox leftBounds,rightBounds; }; typedef SplitInfoT SplitInfo; /*! stores all binning information */ template struct __aligned(64) BinInfoT { typedef BinSplit Split; typedef vbool4 vbool; typedef vint4 vint; typedef vfloat4 vfloat; __forceinline BinInfoT() { } __forceinline BinInfoT(EmptyTy) { clear(); } /*! bin access function */ __forceinline BBox &bounds(const size_t binID, const size_t dimID) { return _bounds[binID][dimID]; } __forceinline const BBox &bounds(const size_t binID, const size_t dimID) const { return _bounds[binID][dimID]; } __forceinline unsigned int &counts(const size_t binID, const size_t dimID) { return _counts[binID][dimID]; } __forceinline const unsigned int &counts(const size_t binID, const size_t dimID) const { return _counts[binID][dimID]; } __forceinline vuint4 &counts(const size_t binID) { return _counts[binID]; } __forceinline const vuint4 &counts(const size_t binID) const { return _counts[binID]; } /*! clears the bin info */ __forceinline void clear() { for (size_t i=0; i& mapping) { if (unlikely(N == 0)) return; size_t i; for (i=0; i(bin0); bounds(b00,0).extend(prim0); const unsigned int b01 = extract<1>(bin0); bounds(b01,1).extend(prim0); const unsigned int b02 = extract<2>(bin0); bounds(b02,2).extend(prim0); const unsigned int s0 = (unsigned int)prims[i+0].size(); counts(b00,0)+=s0; counts(b01,1)+=s0; counts(b02,2)+=s0; /*! increase bounds of bins for odd primitive */ const unsigned int b10 = extract<0>(bin1); bounds(b10,0).extend(prim1); const unsigned int b11 = extract<1>(bin1); bounds(b11,1).extend(prim1); const unsigned int b12 = extract<2>(bin1); bounds(b12,2).extend(prim1); const unsigned int s1 = (unsigned int)prims[i+1].size(); counts(b10,0)+=s1; counts(b11,1)+=s1; counts(b12,2)+=s1; } /*! for uneven number of primitives */ if (i < N) { /*! map primitive to bin */ BBox prim0; Vec3fa center0; prims[i].binBoundsAndCenter(prim0,center0); const vint4 bin0 = (vint4)mapping.bin(center0); /*! increase bounds of bins */ const unsigned int s0 = (unsigned int)prims[i].size(); const int b00 = extract<0>(bin0); counts(b00,0)+=s0; bounds(b00,0).extend(prim0); const int b01 = extract<1>(bin0); counts(b01,1)+=s0; bounds(b01,1).extend(prim0); const int b02 = extract<2>(bin0); counts(b02,2)+=s0; bounds(b02,2).extend(prim0); } } /*! bins an array of primitives */ template __forceinline void bin (const PrimRef* prims, size_t N, const BinMapping& mapping, const BinBoundsAndCenter& binBoundsAndCenter) { if (N == 0) return; size_t i; for (i=0; i(bin0); counts(b00,0)+=s0; bounds(b00,0).extend(prim0); const int b01 = extract<1>(bin0); counts(b01,1)+=s0; bounds(b01,1).extend(prim0); const int b02 = extract<2>(bin0); counts(b02,2)+=s0; bounds(b02,2).extend(prim0); /*! increase bounds of bins for odd primitive */ const unsigned int s1 = prims[i+1].size(); const int b10 = extract<0>(bin1); counts(b10,0)+=s1; bounds(b10,0).extend(prim1); const int b11 = extract<1>(bin1); counts(b11,1)+=s1; bounds(b11,1).extend(prim1); const int b12 = extract<2>(bin1); counts(b12,2)+=s1; bounds(b12,2).extend(prim1); } /*! for uneven number of primitives */ if (i < N) { /*! map primitive to bin */ BBox prim0; Vec3fa center0; binBoundsAndCenter.binBoundsAndCenter(prims[i+0],prim0,center0); const vint4 bin0 = (vint4)mapping.bin(center0); /*! increase bounds of bins */ const unsigned int s0 = prims[i+0].size(); const int b00 = extract<0>(bin0); counts(b00,0)+=s0; bounds(b00,0).extend(prim0); const int b01 = extract<1>(bin0); counts(b01,1)+=s0; bounds(b01,1).extend(prim0); const int b02 = extract<2>(bin0); counts(b02,2)+=s0; bounds(b02,2).extend(prim0); } } __forceinline void bin(const PrimRef* prims, size_t begin, size_t end, const BinMapping& mapping) { bin(prims+begin,end-begin,mapping); } template __forceinline void bin(const PrimRef* prims, size_t begin, size_t end, const BinMapping& mapping, const BinBoundsAndCenter& binBoundsAndCenter) { bin(prims+begin,end-begin,mapping,binBoundsAndCenter); } /*! merges in other binning information */ __forceinline void merge (const BinInfoT& other, size_t numBins) { for (size_t i=0; i& mapping, const size_t blocks_shift) const { /* sweep from right to left and compute parallel prefix of merged bounds */ vfloat4 rAreas[BINS]; vuint4 rCounts[BINS]; vuint4 count = 0; BBox bx = empty; BBox by = empty; BBox bz = empty; for (size_t i=mapping.size()-1; i>0; i--) { count += counts(i); rCounts[i] = count; bx.extend(bounds(i,0)); rAreas[i][0] = expectedApproxHalfArea(bx); by.extend(bounds(i,1)); rAreas[i][1] = expectedApproxHalfArea(by); bz.extend(bounds(i,2)); rAreas[i][2] = expectedApproxHalfArea(bz); rAreas[i][3] = 0.0f; } /* sweep from left to right and compute SAH */ vuint4 blocks_add = (1 << blocks_shift)-1; vuint4 ii = 1; vfloat4 vbestSAH = pos_inf; vuint4 vbestPos = 0; count = 0; bx = empty; by = empty; bz = empty; for (size_t i=1; i> (unsigned int)(blocks_shift); // if blocks_shift >=1 then lCount < 4B and could be represented with an vint4, which would allow for faster vfloat4 conversions. const vuint4 rCount = (rCounts[i]+blocks_add) >> (unsigned int)(blocks_shift); const vfloat4 sah = madd(lArea,vfloat4(lCount),rArea*vfloat4(rCount)); //const vfloat4 sah = madd(lArea,vfloat4(vint4(lCount)),rArea*vfloat4(vint4(rCount))); vbestPos = select(sah < vbestSAH,ii ,vbestPos); vbestSAH = select(sah < vbestSAH,sah,vbestSAH); } /* find best dimension */ float bestSAH = inf; int bestDim = -1; int bestPos = 0; for (int dim=0; dim<3; dim++) { /* ignore zero sized dimensions */ if (unlikely(mapping.invalid(dim))) continue; /* test if this is a better dimension */ if (vbestSAH[dim] < bestSAH && vbestPos[dim] != 0) { bestDim = dim; bestPos = vbestPos[dim]; bestSAH = vbestSAH[dim]; } } return Split(bestSAH,bestDim,bestPos,mapping); } /*! finds the best split by scanning binning information */ __forceinline Split best_block_size(const BinMapping& mapping, const size_t blockSize) const { /* sweep from right to left and compute parallel prefix of merged bounds */ vfloat4 rAreas[BINS]; vuint4 rCounts[BINS]; vuint4 count = 0; BBox bx = empty; BBox by = empty; BBox bz = empty; for (size_t i=mapping.size()-1; i>0; i--) { count += counts(i); rCounts[i] = count; bx.extend(bounds(i,0)); rAreas[i][0] = expectedApproxHalfArea(bx); by.extend(bounds(i,1)); rAreas[i][1] = expectedApproxHalfArea(by); bz.extend(bounds(i,2)); rAreas[i][2] = expectedApproxHalfArea(bz); rAreas[i][3] = 0.0f; } /* sweep from left to right and compute SAH */ vuint4 blocks_add = blockSize-1; vfloat4 blocks_factor = 1.0f/float(blockSize); vuint4 ii = 1; vfloat4 vbestSAH = pos_inf; vuint4 vbestPos = 0; count = 0; bx = empty; by = empty; bz = empty; for (size_t i=1; i& mapping, const Split& split, SplitInfoT& info) const { if (split.dim == -1) { new (&info) SplitInfoT(0,empty,0,empty); return; } size_t leftCount = 0; BBox leftBounds = empty; for (size_t i=0; i<(size_t)split.pos; i++) { leftCount += counts(i,split.dim); leftBounds.extend(bounds(i,split.dim)); } size_t rightCount = 0; BBox rightBounds = empty; for (size_t i=split.pos; i(leftCount,leftBounds,rightCount,rightBounds); } /*! gets the number of primitives left of the split */ __forceinline size_t getLeftCount(const BinMapping& mapping, const Split& split) const { if (unlikely(split.dim == -1)) return -1; size_t leftCount = 0; for (size_t i = 0; i < (size_t)split.pos; i++) { leftCount += counts(i, split.dim); } return leftCount; } /*! gets the number of primitives right of the split */ __forceinline size_t getRightCount(const BinMapping& mapping, const Split& split) const { if (unlikely(split.dim == -1)) return -1; size_t rightCount = 0; for (size_t i = (size_t)split.pos; i __forceinline void bin_parallel(BinInfoT& binner, const PrimRef* prims, size_t begin, size_t end, size_t blockSize, size_t parallelThreshold, const BinMapping& mapping) { if (likely(end-begin < parallelThreshold)) { binner.bin(prims,begin,end,mapping); } else { binner = parallel_reduce(begin,end,blockSize,binner, [&](const range& r) -> BinInfoT { BinInfoT binner(empty); binner.bin(prims + r.begin(), r.size(), mapping); return binner; }, [&](const BinInfoT& b0, const BinInfoT& b1) -> BinInfoT { BinInfoT r = b0; r.merge(b1, mapping.size()); return r; }); } } template __forceinline void bin_parallel(BinInfoT& binner, const PrimRef* prims, size_t begin, size_t end, size_t blockSize, size_t parallelThreshold, const BinMapping& mapping, const BinBoundsAndCenter& binBoundsAndCenter) { if (likely(end-begin < parallelThreshold)) { binner.bin(prims,begin,end,mapping,binBoundsAndCenter); } else { binner = parallel_reduce(begin,end,blockSize,binner, [&](const range& r) -> BinInfoT { BinInfoT binner(empty); binner.bin(prims + r.begin(), r.size(), mapping, binBoundsAndCenter); return binner; }, [&](const BinInfoT& b0, const BinInfoT& b1) -> BinInfoT { BinInfoT r = b0; r.merge(b1, mapping.size()); return r; }); } } template __forceinline void bin_serial_or_parallel(BinInfoT& binner, const PrimRef* prims, size_t begin, size_t end, size_t blockSize, const BinMapping& mapping) { if (!parallel) { binner.bin(prims,begin,end,mapping); } else { binner = parallel_reduce(begin,end,blockSize,binner, [&](const range& r) -> BinInfoT { BinInfoT binner(empty); binner.bin(prims + r.begin(), r.size(), mapping); return binner; }, [&](const BinInfoT& b0, const BinInfoT& b1) -> BinInfoT { BinInfoT r = b0; r.merge(b1, mapping.size()); return r; }); } } template __forceinline void bin_serial_or_parallel(BinInfoT& binner, const PrimRef* prims, size_t begin, size_t end, size_t blockSize, const BinMapping& mapping, const BinBoundsAndCenter& binBoundsAndCenter) { if (!parallel) { binner.bin(prims,begin,end,mapping,binBoundsAndCenter); } else { binner = parallel_reduce(begin,end,blockSize,binner, [&](const range& r) -> BinInfoT { BinInfoT binner(empty); binner.bin(prims + r.begin(), r.size(), mapping, binBoundsAndCenter); return binner; }, [&](const BinInfoT& b0, const BinInfoT& b1) -> BinInfoT { BinInfoT r = b0; r.merge(b1, mapping.size()); return r; }); } } } level-zero-raytracing-support-1.0.0/rtbuild/builders/heuristic_binning_array_aligned.h000066400000000000000000000201441450534701400314660ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "heuristic_binning.h" namespace embree { namespace isa { struct PrimInfoRange : public CentGeomBBox3fa, public range { __forceinline PrimInfoRange () { } __forceinline PrimInfoRange(const PrimInfo& pinfo) : CentGeomBBox3fa(pinfo), range(pinfo.begin,pinfo.end) {} __forceinline PrimInfoRange(EmptyTy) : CentGeomBBox3fa(EmptyTy()), range(0,0) {} __forceinline PrimInfoRange (size_t begin, size_t end, const CentGeomBBox3fa& centGeomBounds) : CentGeomBBox3fa(centGeomBounds), range(begin,end) {} __forceinline PrimInfoRange (range r, const CentGeomBBox3fa& centGeomBounds) : CentGeomBBox3fa(centGeomBounds), range(r) {} __forceinline float leafSAH() const { return expectedApproxHalfArea(geomBounds)*float(size()); } __forceinline float leafSAH(size_t block_shift) const { return expectedApproxHalfArea(geomBounds)*float((size()+(size_t(1)<> block_shift); } __forceinline range get_range() const { return range(begin(),end()); } template __forceinline void add_primref(const PrimRef& prim) { CentGeomBBox3fa::extend_primref(prim); _end++; } }; inline void performFallbackSplit(PrimRef* const prims, const PrimInfoRange& pinfo, PrimInfoRange& linfo, PrimInfoRange& rinfo) { const size_t begin = pinfo.begin(); const size_t end = pinfo.end(); const size_t center = (begin + end)/2; CentGeomBBox3fa left(empty); for (size_t i=begin; i inline void performTypeSplit(const getTypeFunc& getType, Type type, PrimRef* const prims, range range, PrimInfoRange& linfo, PrimInfoRange& rinfo) { CentGeomBBox3fa local_left(empty), local_right(empty); auto isLeft = [&] (const PrimRef& ref) { return type == getType(ref.geomID()); }; const size_t center = serial_partitioning(prims,range.begin(),range.end(),local_left,local_right,isLeft,CentGeomBBox3fa::extend_ref); linfo = PrimInfoRange(make_range(range.begin(),center ),local_left); rinfo = PrimInfoRange(make_range(center ,range.end()),local_right); } /*! Performs standard object binning */ template struct HeuristicArrayBinningSAH { typedef BinSplit Split; typedef BinInfoT Binner; typedef range Set; static const size_t PARALLEL_THRESHOLD = 3 * 1024; static const size_t PARALLEL_FIND_BLOCK_SIZE = 1024; static const size_t PARALLEL_PARTITION_BLOCK_SIZE = 128; __forceinline HeuristicArrayBinningSAH () : prims(nullptr) {} /*! remember prim array */ __forceinline HeuristicArrayBinningSAH (PrimRef* prims) : prims(prims) {} /*! finds the best split */ __noinline const Split find(const PrimInfoRange& pinfo, const size_t logBlockSize) { if (likely(pinfo.size() < PARALLEL_THRESHOLD)) return find_template(pinfo,logBlockSize); else return find_template(pinfo,logBlockSize); } template __forceinline const Split find_template(const PrimInfoRange& pinfo, const size_t logBlockSize) { Binner binner(empty); const BinMapping mapping(pinfo); bin_serial_or_parallel(binner,prims,pinfo.begin(),pinfo.end(),PARALLEL_FIND_BLOCK_SIZE,mapping); return binner.best(mapping,logBlockSize); } /*! finds the best split */ __noinline const Split find_block_size(const PrimInfoRange& pinfo, const size_t blockSize) { if (likely(pinfo.size() < PARALLEL_THRESHOLD)) return find_block_size_template(pinfo,blockSize); else return find_block_size_template(pinfo,blockSize); } template __forceinline const Split find_block_size_template(const PrimInfoRange& pinfo, const size_t blockSize) { Binner binner(empty); const BinMapping mapping(pinfo); bin_serial_or_parallel(binner,prims,pinfo.begin(),pinfo.end(),PARALLEL_FIND_BLOCK_SIZE,mapping); return binner.best_block_size(mapping,blockSize); } /*! array partitioning */ __forceinline void split(const Split& split, const PrimInfoRange& pinfo, PrimInfoRange& linfo, PrimInfoRange& rinfo) { if (likely(pinfo.size() < PARALLEL_THRESHOLD)) split_template(split,pinfo,linfo,rinfo); else split_template(split,pinfo,linfo,rinfo); } template __forceinline void split_template(const Split& split, const PrimInfoRange& set, PrimInfoRange& lset, PrimInfoRange& rset) { if (!split.valid()) { deterministic_order(set); return splitFallback(set,lset,rset); } const size_t begin = set.begin(); const size_t end = set.end(); CentGeomBBox3fa local_left(empty); CentGeomBBox3fa local_right(empty); const unsigned int splitPos = split.pos; const unsigned int splitDim = split.dim; const unsigned int splitDimMask = (unsigned int)1 << splitDim; const typename Binner::vint vSplitPos(splitPos); const typename Binner::vbool vSplitMask(splitDimMask); auto isLeft = [&] (const PrimRef &ref) { return split.mapping.bin_unsafe(ref,vSplitPos,vSplitMask); }; size_t center = 0; if (!parallel) center = serial_partitioning(prims,begin,end,local_left,local_right,isLeft, [] (CentGeomBBox3fa& pinfo,const PrimRef& ref) { pinfo.extend_center2(ref); }); else center = parallel_partitioning( prims,begin,end,EmptyTy(),local_left,local_right,isLeft, [] (CentGeomBBox3fa& pinfo,const PrimRef& ref) { pinfo.extend_center2(ref); }, [] (CentGeomBBox3fa& pinfo0,const CentGeomBBox3fa& pinfo1) { pinfo0.merge(pinfo1); }, PARALLEL_PARTITION_BLOCK_SIZE); new (&lset) PrimInfoRange(begin,center,local_left); new (&rset) PrimInfoRange(center,end,local_right); assert(area(lset.geomBounds) >= 0.0f); assert(area(rset.geomBounds) >= 0.0f); } void deterministic_order(const PrimInfoRange& pinfo) { /* required as parallel partition destroys original primitive order */ std::sort(&prims[pinfo.begin()],&prims[pinfo.end()]); } void splitFallback(const PrimInfoRange& pinfo, PrimInfoRange& linfo, PrimInfoRange& rinfo) { performFallbackSplit(prims,pinfo,linfo,rinfo); } void splitByGeometry(const range& range, PrimInfoRange& linfo, PrimInfoRange& rinfo) { assert(range.size() > 1); CentGeomBBox3fa left(empty); CentGeomBBox3fa right(empty); unsigned int geomID = prims[range.begin()].geomID(); size_t center = serial_partitioning(prims,range.begin(),range.end(),left,right, [&] ( const PrimRef& prim ) { return prim.geomID() == geomID; }, [ ] ( CentGeomBBox3fa& a, const PrimRef& ref ) { a.extend_center2(ref); }); new (&linfo) PrimInfoRange(range.begin(),center,left); new (&rinfo) PrimInfoRange(center,range.end(),right); } private: PrimRef* const prims; }; } } level-zero-raytracing-support-1.0.0/rtbuild/builders/heuristic_spatial.h000066400000000000000000000332351450534701400266230ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "priminfo.h" namespace embree { static const unsigned int RESERVED_NUM_SPATIAL_SPLITS_GEOMID_BITS = 5; namespace isa { /*! mapping into bins */ template struct SpatialBinMapping { public: __forceinline SpatialBinMapping() {} /*! calculates the mapping */ __forceinline SpatialBinMapping(const CentGeomBBox3fa& pinfo) { const vfloat4 lower = (vfloat4) pinfo.geomBounds.lower; const vfloat4 upper = (vfloat4) pinfo.geomBounds.upper; const vfloat4 eps = 128.0f*vfloat4(ulp)*max(abs(lower),abs(upper)); const vfloat4 diag = max(eps,(vfloat4) pinfo.geomBounds.size()); scale = select(upper-lower <= eps,vfloat4(0.0f),vfloat4(BINS)/diag); ofs = (vfloat4) pinfo.geomBounds.lower; inv_scale = 1.0f / scale; } /*! slower but safe binning */ __forceinline vint4 bin(const Vec3fa& p) const { const vint4 i = floori((vfloat4(p)-ofs)*scale); return clamp(i,vint4(0),vint4(BINS-1)); } __forceinline std::pair bin(const BBox3fa& b) const { #if defined(__AVX__) const vfloat8 ofs8(ofs); const vfloat8 scale8(scale); const vint8 lu = floori((vfloat8::loadu(&b)-ofs8)*scale8); const vint8 c_lu = clamp(lu,vint8(zero),vint8(BINS-1)); return std::pair(extract4<0>(c_lu),extract4<1>(c_lu)); #else const vint4 lower = floori((vfloat4(b.lower)-ofs)*scale); const vint4 upper = floori((vfloat4(b.upper)-ofs)*scale); const vint4 c_lower = clamp(lower,vint4(0),vint4(BINS-1)); const vint4 c_upper = clamp(upper,vint4(0),vint4(BINS-1)); return std::pair(c_lower,c_upper); #endif } /*! calculates left spatial position of bin */ __forceinline float pos(const size_t bin, const size_t dim) const { return madd(float(bin),inv_scale[dim],ofs[dim]); } /*! calculates left spatial position of bin */ template __forceinline vfloat posN(const vfloat bin, const size_t dim) const { return madd(bin,vfloat(inv_scale[dim]),vfloat(ofs[dim])); } /*! returns true if the mapping is invalid in some dimension */ __forceinline bool invalid(const size_t dim) const { return scale[dim] == 0.0f; } public: vfloat4 ofs,scale,inv_scale; //!< linear function that maps to bin ID }; /*! stores all information required to perform some split */ template struct SpatialBinSplit { /*! construct an invalid split by default */ __forceinline SpatialBinSplit() : sah(inf), dim(-1), pos(0), left(-1), right(-1), factor(1.0f) {} /*! constructs specified split */ __forceinline SpatialBinSplit(float sah, int dim, int pos, const SpatialBinMapping& mapping) : sah(sah), dim(dim), pos(pos), left(-1), right(-1), factor(1.0f), mapping(mapping) {} /*! constructs specified split */ __forceinline SpatialBinSplit(float sah, int dim, int pos, int left, int right, float factor, const SpatialBinMapping& mapping) : sah(sah), dim(dim), pos(pos), left(left), right(right), factor(factor), mapping(mapping) {} /*! tests if this split is valid */ __forceinline bool valid() const { return dim != -1; } /*! calculates surface area heuristic for performing the split */ __forceinline float splitSAH() const { return sah; } /*! stream output */ friend embree_ostream operator<<(embree_ostream cout, const SpatialBinSplit& split) { return cout << "SpatialBinSplit { sah = " << split.sah << ", dim = " << split.dim << ", pos = " << split.pos << ", left = " << split.left << ", right = " << split.right << ", factor = " << split.factor << "}"; } public: float sah; //!< SAH cost of the split int dim; //!< split dimension int pos; //!< split position int left; //!< number of elements on the left side int right; //!< number of elements on the right side float factor; //!< factor splitting the extended range SpatialBinMapping mapping; //!< mapping into bins }; /*! stores all binning information */ template struct __aligned(64) SpatialBinInfo { SpatialBinInfo() { } __forceinline SpatialBinInfo(EmptyTy) { clear(); } /*! clears the bin info */ __forceinline void clear() { for (size_t i=0; i __forceinline void bin2(const PrimitiveSplitterFactory& splitterFactory, const PrimRef* source, size_t begin, size_t end, const SpatialBinMapping& mapping) { for (size_t i=begin; i> (32-RESERVED_NUM_SPATIAL_SPLITS_GEOMID_BITS); if (unlikely(splits <= 1)) { const vint4 bin = mapping.bin(center(prim.bounds())); for (size_t dim=0; dim<3; dim++) { assert(bin[dim] >= (int)0 && bin[dim] < (int)BINS); add(dim,bin[dim],bin[dim],bin[dim],prim.bounds()); } } else { const vint4 bin0 = mapping.bin(prim.bounds().lower); const vint4 bin1 = mapping.bin(prim.bounds().upper); for (size_t dim=0; dim<3; dim++) { if (unlikely(mapping.invalid(dim))) continue; size_t bin; size_t l = bin0[dim]; size_t r = bin1[dim]; // same bin optimization if (likely(l == r)) { add(dim,l,l,l,prim.bounds()); continue; } size_t bin_start = bin0[dim]; size_t bin_end = bin1[dim]; BBox3fa rest = prim.bounds(); /* assure that split position always overlaps the primitive bounds */ while (bin_start < bin_end && mapping.pos(bin_start+1,dim) <= rest.lower[dim]) bin_start++; while (bin_start < bin_end && mapping.pos(bin_end ,dim) >= rest.upper[dim]) bin_end--; const auto splitter = splitterFactory(prim); for (bin=bin_start; bin& mapping) { for (size_t i=begin; i best(const SpatialBinMapping& mapping, const size_t blocks_shift) const { /* sweep from right to left and compute parallel prefix of merged bounds */ vfloat4 rAreas[BINS]; vuint4 rCounts[BINS]; vuint4 count = 0; BBox3fa bx = empty; BBox3fa by = empty; BBox3fa bz = empty; for (size_t i=BINS-1; i>0; i--) { count += numEnd[i]; rCounts[i] = count; bx.extend(bounds[i][0]); rAreas[i][0] = halfArea(bx); by.extend(bounds[i][1]); rAreas[i][1] = halfArea(by); bz.extend(bounds[i][2]); rAreas[i][2] = halfArea(bz); rAreas[i][3] = 0.0f; } /* sweep from left to right and compute SAH */ vuint4 blocks_add = (1 << blocks_shift)-1; vuint4 ii = 1; vfloat4 vbestSAH = pos_inf; vuint4 vbestPos = 0; vuint4 vbestlCount = 0; vuint4 vbestrCount = 0; count = 0; bx = empty; by = empty; bz = empty; for (size_t i=1; i> (unsigned int)(blocks_shift); const vuint4 rCount = (rCounts[i]+blocks_add) >> (unsigned int)(blocks_shift); const vfloat4 sah = madd(lArea,vfloat4(lCount),rArea*vfloat4(rCount)); // const vfloat4 sah = madd(lArea,vfloat4(vint4(lCount)),rArea*vfloat4(vint4(rCount))); const vbool4 mask = sah < vbestSAH; vbestPos = select(mask,ii ,vbestPos); vbestSAH = select(mask,sah,vbestSAH); vbestlCount = select(mask,count,vbestlCount); vbestrCount = select(mask,rCounts[i],vbestrCount); } /* find best dimension */ float bestSAH = inf; int bestDim = -1; int bestPos = 0; unsigned int bestlCount = 0; unsigned int bestrCount = 0; for (int dim=0; dim<3; dim++) { /* ignore zero sized dimensions */ if (unlikely(mapping.invalid(dim))) continue; /* test if this is a better dimension */ if (vbestSAH[dim] < bestSAH && vbestPos[dim] != 0) { bestDim = dim; bestPos = vbestPos[dim]; bestSAH = vbestSAH[dim]; bestlCount = vbestlCount[dim]; bestrCount = vbestrCount[dim]; } } assert(bestSAH >= 0.0f); /* return invalid split if no split found */ if (bestDim == -1) return SpatialBinSplit(inf,-1,0,mapping); /* return best found split */ return SpatialBinSplit(bestSAH,bestDim,bestPos,bestlCount,bestrCount,1.0f,mapping); } private: BBox3fa bounds[BINS][3]; //!< geometry bounds for each bin in each dimension vuint4 numBegin[BINS]; //!< number of primitives starting in bin vuint4 numEnd[BINS]; //!< number of primitives ending in bin }; } } level-zero-raytracing-support-1.0.0/rtbuild/builders/priminfo.h000066400000000000000000000114401450534701400247240ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "primref.h" namespace embree { // FIXME: maybe there's a better place for this util fct __forceinline float areaProjectedTriangle(const Vec3fa& v0, const Vec3fa& v1, const Vec3fa& v2) { const Vec3fa e0 = v1-v0; const Vec3fa e1 = v2-v0; const Vec3fa d = cross(e0,e1); return fabs(d.x) + fabs(d.y) + fabs(d.z); } //namespace isa //{ template class CentGeom { public: __forceinline CentGeom () {} __forceinline CentGeom (EmptyTy) : geomBounds(empty), centBounds(empty) {} __forceinline CentGeom (const BBox& geomBounds, const BBox3fa& centBounds) : geomBounds(geomBounds), centBounds(centBounds) {} template __forceinline void extend_primref(const PrimRef& prim) { BBox bounds; Vec3fa center; prim.binBoundsAndCenter(bounds,center); geomBounds.extend(bounds); centBounds.extend(center); } static void extend_ref (CentGeom& pinfo, const PrimRef& ref) { pinfo.extend_primref(ref); }; template __forceinline void extend_center2(const PrimRef& prim) { BBox3fa bounds = prim.bounds(); geomBounds.extend(bounds); centBounds.extend(bounds.center2()); } __forceinline void extend(const BBox& geomBounds_) { geomBounds.extend(geomBounds_); centBounds.extend(center2(geomBounds_)); } __forceinline void merge(const CentGeom& other) { geomBounds.extend(other.geomBounds); centBounds.extend(other.centBounds); } static __forceinline const CentGeom merge2(const CentGeom& a, const CentGeom& b) { CentGeom r = a; r.merge(b); return r; } public: BBox geomBounds; //!< geometry bounds of primitives BBox3fa centBounds; //!< centroid bounds of primitives }; typedef CentGeom CentGeomBBox3fa; /*! stores bounding information for a set of primitives */ template class PrimInfoT : public CentGeom { public: using CentGeom::geomBounds; using CentGeom::centBounds; __forceinline PrimInfoT () {} __forceinline PrimInfoT (EmptyTy) : CentGeom(empty), begin(0), end(0) {} __forceinline PrimInfoT (size_t N) : CentGeom(empty), begin(0), end(N) {} __forceinline PrimInfoT (size_t begin, size_t end, const CentGeomBBox3fa& centGeomBounds) : CentGeom(centGeomBounds), begin(begin), end(end) {} template __forceinline void add_primref(const PrimRef& prim) { CentGeom::extend_primref(prim); end++; } template __forceinline void add_center2(const PrimRef& prim) { CentGeom::extend_center2(prim); end++; } template __forceinline void add_center2(const PrimRef& prim, const size_t i) { CentGeom::extend_center2(prim); end+=i; } /*__forceinline void add(const BBox& geomBounds_) { CentGeom::extend(geomBounds_); end++; } __forceinline void add(const BBox& geomBounds_, const size_t i) { CentGeom::extend(geomBounds_); end+=i; }*/ __forceinline void merge(const PrimInfoT& other) { CentGeom::merge(other); begin += other.begin; end += other.end; } static __forceinline const PrimInfoT merge(const PrimInfoT& a, const PrimInfoT& b) { PrimInfoT r = a; r.merge(b); return r; } /*! returns the number of primitives */ __forceinline size_t size() const { return end-begin; } __forceinline float halfArea() { return expectedApproxHalfArea(geomBounds); } __forceinline float leafSAH() const { return expectedApproxHalfArea(geomBounds)*float(size()); //return halfArea(geomBounds)*blocks(num); } __forceinline float leafSAH(size_t block_shift) const { return expectedApproxHalfArea(geomBounds)*float((size()+(size_t(1)<> block_shift); //return halfArea(geomBounds)*float((num+3) >> 2); //return halfArea(geomBounds)*blocks(num); } /*! stream output */ friend embree_ostream operator<<(embree_ostream cout, const PrimInfoT& pinfo) { return cout << "PrimInfo { begin = " << pinfo.begin << ", end = " << pinfo.end << ", geomBounds = " << pinfo.geomBounds << ", centBounds = " << pinfo.centBounds << "}"; } public: size_t begin,end; //!< number of primitives }; typedef PrimInfoT PrimInfo; //typedef PrimInfoT PrimInfoMB; //} } level-zero-raytracing-support-1.0.0/rtbuild/builders/primref.h000066400000000000000000000105471450534701400245540ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "../sys/platform.h" #include "../sys/sysinfo.h" #include "../math/emath.h" #include "../simd/simd.h" #include "../math/vec2.h" #include "../math/vec3.h" #include "../math/vec3fa.h" #include "../math/bbox.h" #include "../math/affinespace.h" #include "../math/range.h" namespace embree { /*! A primitive reference stores the bounds of the primitive and its ID. */ struct __aligned(32) PrimRef { __forceinline PrimRef () {} #if defined(__AVX__) __forceinline PrimRef(const PrimRef& v) { vfloat8::store((float*)this,vfloat8::load((float*)&v)); } __forceinline PrimRef& operator=(const PrimRef& v) { vfloat8::store((float*)this,vfloat8::load((float*)&v)); return *this; } #endif __forceinline PrimRef (const BBox3fa& bounds, unsigned int geomID, unsigned int primID) { lower = Vec3fx(bounds.lower, geomID); upper = Vec3fx(bounds.upper, primID); } __forceinline PrimRef (const BBox3fa& bounds, size_t id) { #if defined(__64BIT__) lower = Vec3fx(bounds.lower, (unsigned)(id & 0xFFFFFFFF)); upper = Vec3fx(bounds.upper, (unsigned)((id >> 32) & 0xFFFFFFFF)); #else lower = Vec3fx(bounds.lower, (unsigned)id); upper = Vec3fx(bounds.upper, (unsigned)0); #endif } /*! calculates twice the center of the primitive */ __forceinline const Vec3fa center2() const { return lower+upper; } /*! return the bounding box of the primitive */ __forceinline const BBox3fa bounds() const { return BBox3fa(lower,upper); } /*! size for bin heuristic is 1 */ __forceinline unsigned size() const { return 1; } /*! returns bounds and centroid used for binning */ __forceinline void binBoundsAndCenter(BBox3fa& bounds_o, Vec3fa& center_o) const { bounds_o = bounds(); center_o = embree::center2(bounds_o); } __forceinline unsigned& geomIDref() { // FIXME: remove !!!!!!! return lower.u; } __forceinline unsigned& primIDref() { // FIXME: remove !!!!!!! return upper.u; } /*! returns the geometry ID */ __forceinline unsigned geomID() const { return lower.a; } /*! returns the primitive ID */ __forceinline unsigned primID() const { return upper.a; } /*! returns an size_t sized ID */ __forceinline size_t ID() const { #if defined(__64BIT__) return size_t(lower.u) + (size_t(upper.u) << 32); #else return size_t(lower.u); #endif } /*! special function for operator< */ __forceinline uint64_t ID64() const { return (((uint64_t)primID()) << 32) + (uint64_t)geomID(); } /*! allows sorting the primrefs by ID */ friend __forceinline bool operator<(const PrimRef& p0, const PrimRef& p1) { return p0.ID64() < p1.ID64(); } /*! Outputs primitive reference to a stream. */ friend __forceinline embree_ostream operator<<(embree_ostream cout, const PrimRef& ref) { return cout << "{ lower = " << ref.lower << ", upper = " << ref.upper << ", geomID = " << ref.geomID() << ", primID = " << ref.primID() << " }"; } public: Vec3fx lower; //!< lower bounds and geomID Vec3fx upper; //!< upper bounds and primID }; /*! fast exchange for PrimRefs */ __forceinline void xchg(PrimRef& a, PrimRef& b) { #if defined(__AVX__) const vfloat8 aa = vfloat8::load((float*)&a); const vfloat8 bb = vfloat8::load((float*)&b); vfloat8::store((float*)&a,bb); vfloat8::store((float*)&b,aa); #else std::swap(a,b); #endif } /************************************************************************************/ /************************************************************************************/ /************************************************************************************/ /************************************************************************************/ struct SubGridBuildData { unsigned short sx,sy; unsigned int primID; __forceinline SubGridBuildData() {}; __forceinline SubGridBuildData(const unsigned int sx, const unsigned int sy, const unsigned int primID) : sx(sx), sy(sy), primID(primID) {}; __forceinline size_t x() const { return (size_t)sx & 0x7fff; } __forceinline size_t y() const { return (size_t)sy & 0x7fff; } }; } level-zero-raytracing-support-1.0.0/rtbuild/builders/primrefgen_presplit.h000066400000000000000000000366451450534701400271770ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "../algorithms/parallel_reduce.h" #include "../algorithms/parallel_sort.h" #include "../builders/heuristic_spatial.h" #include "../builders/splitter.h" #include "../algorithms/parallel_partition.h" #include "../algorithms/parallel_for_for.h" #include "../algorithms/parallel_for_for_prefix_sum.h" #define DBG_PRESPLIT(x) #define CHECK_PRESPLIT(x) #define GRID_SIZE 1024 //#define MAX_PRESPLITS_PER_PRIMITIVE_LOG 6 #define MAX_PRESPLITS_PER_PRIMITIVE_LOG 5 #define MAX_PRESPLITS_PER_PRIMITIVE (1<= vint4(gupper),vint4(ilower),vint4(iupper)); /* compute a morton code for the lower and upper grid coordinates. */ const unsigned int lower_code = bitInterleave(ilower.x,ilower.y,ilower.z); const unsigned int upper_code = bitInterleave(iupper.x,iupper.y,iupper.z); /* if all bits are equal then we cannot split */ if (unlikely(lower_code == upper_code)) return false; /* compute octree level and dimension to perform the split in */ const unsigned int diff = 31 - lzcnt(lower_code^upper_code); const unsigned int level = diff / 3; const unsigned int dim = diff % 3; /* now we compute the grid position of the split */ const unsigned int isplit = iupper[dim] & ~((1<= fsplit); dim_o = dim; fsplit_o = fsplit; return true; } __forceinline Vec2i computeMC(const PrimRef& ref) const { const Vec3fa lower = ref.lower; const Vec3fa upper = ref.upper; const Vec3fa glower = (lower-base)*Vec3fa(scale)+Vec3fa(0.2f); const Vec3fa gupper = (upper-base)*Vec3fa(scale)-Vec3fa(0.2f); Vec3ia ilower(floor(glower)); Vec3ia iupper(floor(gupper)); /* this ignores dimensions that are empty */ iupper = (Vec3ia)select(vint4(glower) >= vint4(gupper),vint4(ilower),vint4(iupper)); /* compute a morton code for the lower and upper grid coordinates. */ const unsigned int lower_code = bitInterleave(ilower.x,ilower.y,ilower.z); const unsigned int upper_code = bitInterleave(iupper.x,iupper.y,iupper.z); return Vec2i(lower_code,upper_code); } Vec3fa base; float scale; float extend; }; struct PresplitItem { union { float priority; unsigned int data; }; unsigned int index; __forceinline operator unsigned() const { return data; } template __forceinline static float compute_priority(const ProjectedPrimitiveAreaFunc& primitiveArea, const PrimRef &ref, const Vec2i &mc) { const float area_aabb = area(ref.bounds()); const float area_prim = primitiveArea(ref); if (area_prim == 0.0f) return 0.0f; const unsigned int diff = 31 - lzcnt(mc.x^mc.y); //assert(area_prim <= area_aabb); // may trigger due to numerical issues const float area_diff = max(0.0f, area_aabb - area_prim); //const float priority = powf(area_diff * powf(PRIORITY_SPLIT_POS_WEIGHT,(float)diff),1.0f/4.0f); const float priority = sqrtf(sqrtf( area_diff * powf(PRIORITY_SPLIT_POS_WEIGHT,(float)diff) )); //const float priority = sqrtf(sqrtf( area_diff ) ); //const float priority = sqrtfarea_diff; //const float priority = area_diff; // 104 fps !!!!!!!!!! //const float priority = 0.2f*area_aabb + 0.8f*area_diff; // 104 fps //const float priority = area_aabb * max(area_aabb/area_prim,32.0f); //const float priority = area_prim; assert(priority >= 0.0f && priority < FLT_LARGE); return priority; } }; inline std::ostream &operator<<(std::ostream &cout, const PresplitItem& item) { return cout << "index " << item.index << " priority " << item.priority; }; #if 1 template void splitPrimitive(const Splitter& splitter, const PrimRef& prim, const unsigned int splitprims, const SplittingGrid& grid, PrimRef subPrims[MAX_PRESPLITS_PER_PRIMITIVE], unsigned int& numSubPrims) { assert(splitprims > 0 && splitprims <= MAX_PRESPLITS_PER_PRIMITIVE); if (splitprims == 1) { assert(numSubPrims < MAX_PRESPLITS_PER_PRIMITIVE); subPrims[numSubPrims++] = prim; } else { unsigned int dim; float fsplit; if (!grid.split_pos(prim, dim, fsplit)) { assert(numSubPrims < MAX_PRESPLITS_PER_PRIMITIVE); subPrims[numSubPrims++] = prim; return; } /* split primitive */ PrimRef left,right; splitter(prim,dim,fsplit,left,right); assert(!left.bounds().empty()); assert(!right.bounds().empty()); const unsigned int splitprims_left = splitprims/2; const unsigned int splitprims_right = splitprims - splitprims_left; splitPrimitive(splitter,left,splitprims_left,grid,subPrims,numSubPrims); splitPrimitive(splitter,right,splitprims_right,grid,subPrims,numSubPrims); } } #else template void splitPrimitive(const Splitter& splitter, const PrimRef& prim, const unsigned int targetSubPrims, const SplittingGrid& grid, PrimRef subPrims[MAX_PRESPLITS_PER_PRIMITIVE], unsigned int& numSubPrims) { assert(targetSubPrims > 0 && targetSubPrims <= MAX_PRESPLITS_PER_PRIMITIVE); auto compare = [] ( const PrimRef& a, const PrimRef& b ) { return area(a.bounds()) < area(b.bounds()); }; subPrims[numSubPrims++] = prim; while (numSubPrims < targetSubPrims) { /* get top heap element */ std::pop_heap(subPrims+0,subPrims+numSubPrims, compare); PrimRef top = subPrims[--numSubPrims]; unsigned int dim; float fsplit; if (!grid.split_pos(top, dim, fsplit)) { assert(numSubPrims < MAX_PRESPLITS_PER_PRIMITIVE); subPrims[numSubPrims++] = top; return; } /* split primitive */ PrimRef left,right; splitter(top,dim,fsplit,left,right); assert(!left.bounds().empty()); assert(!right.bounds().empty()); subPrims[numSubPrims++] = left; std::push_heap(subPrims+0, subPrims+numSubPrims, compare); subPrims[numSubPrims++] = right; std::push_heap(subPrims+0, subPrims+numSubPrims, compare); } } #endif template PrimInfo createPrimRefArray_presplit(size_t numPrimRefs, PrimVector& prims, const PrimInfo& pinfo, const SplitPrimitiveFunc& splitPrimitive, const ProjectedPrimitiveAreaFunc& primitiveArea) { static const size_t MIN_STEP_SIZE = 128; /* use correct number of primitives */ size_t numPrimitives = pinfo.size(); const size_t numPrimitivesExt = prims.size(); const size_t numSplitPrimitivesBudget = numPrimitivesExt - numPrimitives; /* allocate double buffer presplit items */ avector preSplitItem0(numPrimitivesExt); avector preSplitItem1(numPrimitivesExt); /* compute grid */ SplittingGrid grid(pinfo.geomBounds); /* init presplit items and get total sum */ const float psum = parallel_reduce( size_t(0), numPrimitives, size_t(MIN_STEP_SIZE), 0.0f, [&](const range& r) -> float { float sum = 0.0f; for (size_t i=r.begin(); i float { return a+b; }); /* compute number of splits per primitive */ const float inv_psum = 1.0f / psum; parallel_for( size_t(0), numPrimitives, size_t(MIN_STEP_SIZE), [&](const range& r) -> void { for (size_t i=r.begin(); i= numPrimitives) return pinfo; size_t numPrimitivesToSplit = numPrimitives - center; assert(preSplitItem0[center].data >= 1.0f); /* sort presplit items in ascending order */ radix_sort_u32(preSplitItem0.data() + center,preSplitItem1.data() + center,numPrimitivesToSplit,1024); CHECK_PRESPLIT( parallel_for( size_t(center+1), numPrimitives, size_t(MIN_STEP_SIZE), [&](const range& r) -> void { for (size_t i=r.begin(); i& t) -> size_t { size_t sum = 0; for (size_t i=t.begin(); i= 1 && splitprims <= MAX_PRESPLITS_PER_PRIMITIVE); unsigned int numSubPrims = 0; PrimRef subPrims[MAX_PRESPLITS_PER_PRIMITIVE]; splitPrimitive(prims[primrefID],splitprims,grid,subPrims,numSubPrims); assert(numSubPrims); numSubPrims--; // can reuse slot sum+=numSubPrims; preSplitItem0[i].data = (numSubPrims << 16) | splitprims; primOffset0[i-center] = numSubPrims; } return sum; },[](const size_t& a, const size_t& b) -> size_t { return a+b; }); /* if we are over budget, need to shrink the range */ if (totalNumSubPrims > numSplitPrimitivesBudget) { size_t new_center = numPrimitives-1; size_t sum = 0; for (;new_center>=center;new_center--) { const unsigned int numSubPrims = preSplitItem0[new_center].data >> 16; if (unlikely(sum + numSubPrims >= numSplitPrimitivesBudget)) break; sum += numSubPrims; } new_center++; primOffset0 += new_center - center; numPrimitivesToSplit -= new_center - center; center = new_center; assert(numPrimitivesToSplit == (numPrimitives - center)); } /* parallel prefix sum to compute offsets for storing sub-primitives */ const unsigned int offset = parallel_prefix_sum(primOffset0,primOffset1,numPrimitivesToSplit,(unsigned int)0,std::plus()); assert(numPrimitives+offset <= numPrimitivesExt); /* iterate over range, and split primitives into sub primitives and append them to prims array */ parallel_for( size_t(center), numPrimitives, size_t(MIN_STEP_SIZE), [&](const range& rn) -> void { for (size_t j=rn.begin(); j= 1 && splitprims <= MAX_PRESPLITS_PER_PRIMITIVE); unsigned int numSubPrims = 0; PrimRef subPrims[MAX_PRESPLITS_PER_PRIMITIVE]; splitPrimitive(prims[primrefID],splitprims,grid,subPrims,numSubPrims); const unsigned int numSubPrimsExpected MAYBE_UNUSED = preSplitItem0[j].data >> 16; assert(numSubPrims-1 == numSubPrimsExpected); const size_t newID = numPrimitives + primOffset1[j-center]; assert(newID+numSubPrims-1 <= numPrimitivesExt); prims[primrefID] = subPrims[0]; for (size_t i=1;i& r) -> PrimInfo { PrimInfo p(empty); for (size_t j=r.begin(); j PrimInfo { return PrimInfo::merge(a,b); }); assert(pinfo1.size() == numPrimitives); return pinfo1; } } } level-zero-raytracing-support-1.0.0/rtbuild/builders/splitter.h000066400000000000000000000101171450534701400247470ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "../builders/primref.h" namespace embree { namespace isa { template __forceinline void splitPolygon(const BBox3fa& bounds, const size_t dim, const float pos, const Vec3fa (&v)[N+1], BBox3fa& left_o, BBox3fa& right_o) { BBox3fa left = empty, right = empty; /* clip triangle to left and right box by processing all edges */ for (size_t i=0; i= pos) right.extend(v0); // this point is on right side if ((v0d < pos && pos < v1d) || (v1d < pos && pos < v0d)) // the edge crosses the splitting location { assert((v1d-v0d) != 0.0f); const float inv_length = 1.0f/(v1d-v0d); const Vec3fa c = madd(Vec3fa((pos-v0d)*inv_length),v1-v0,v0); left.extend(c); right.extend(c); } } /* clip against current bounds */ left_o = intersect(left,bounds); right_o = intersect(right,bounds); } template __forceinline void splitPolygon(const BBox3fa& bounds, const size_t dim, const float pos, const Vec3fa (&v)[N+1], const Vec3fa (&inv_length)[N], BBox3fa& left_o, BBox3fa& right_o) { BBox3fa left = empty, right = empty; /* clip triangle to left and right box by processing all edges */ for (size_t i=0; i= pos) right.extend(v0); // this point is on right side if ((v0d < pos && pos < v1d) || (v1d < pos && pos < v0d)) // the edge crosses the splitting location { assert((v1d-v0d) != 0.0f); const Vec3fa c = madd(Vec3fa((pos-v0d)*inv_length[i][dim]),v1-v0,v0); left.extend(c); right.extend(c); } } /* clip against current bounds */ left_o = intersect(left,bounds); right_o = intersect(right,bounds); } template __forceinline void splitPolygon(const PrimRef& prim, const size_t dim, const float pos, const Vec3fa (&v)[N+1], PrimRef& left_o, PrimRef& right_o) { BBox3fa left = empty, right = empty; for (size_t i=0; i= pos) right.extend(v0); // this point is on right side if ((v0d < pos && pos < v1d) || (v1d < pos && pos < v0d)) // the edge crosses the splitting location { assert((v1d-v0d) != 0.0f); const float inv_length = 1.0f/(v1d-v0d); const Vec3fa c = madd(Vec3fa((pos-v0d)*inv_length),v1-v0,v0); left.extend(c); right.extend(c); } } /* clip against current bounds */ new (&left_o ) PrimRef(intersect(left ,prim.bounds()),prim.geomID(), prim.primID()); new (&right_o) PrimRef(intersect(right,prim.bounds()),prim.geomID(), prim.primID()); } } } level-zero-raytracing-support-1.0.0/rtbuild/export.linux.map000066400000000000000000000000411450534701400242700ustar00rootroot00000000000000{ global: ze*; local: *; }; level-zero-raytracing-support-1.0.0/rtbuild/leaf.h000066400000000000000000000541131450534701400222030ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #if defined(ZE_RAYTRACING) #include "sys/sysinfo.h" #include "sys/vector.h" #include "math/vec2.h" #include "math/vec3.h" #include "math/bbox.h" #include "math/affinespace.h" #else #include "../../../common/sys/sysinfo.h" #include "../../../common/sys/vector.h" #include "../../../common/math/vec2.h" #include "../../../common/math/vec3.h" #include "../../../common/math/bbox.h" #include "../../../common/math/lbbox.h" #include "../../../common/math/affinespace.h" #endif #include "node_type.h" #include #include namespace embree { /* Internal representation for GeometryFlags. */ #undef OPAQUE // Windows defines OPAQUE in gdi.h enum class GeometryFlags : uint32_t { NONE = 0x0, OPAQUE = 0x1 }; inline bool operator& (GeometryFlags a, GeometryFlags b) { return (int(a) & int(b)) ? true : false; } /* output operator for GeometryFlags */ inline std::ostream& operator<<(std::ostream& cout, const GeometryFlags& gflags) { #if !defined(__SYCL_DEVICE_ONLY__) if (gflags == GeometryFlags::NONE) return cout << "NONE"; if (gflags & GeometryFlags::OPAQUE) cout << "OPAQUE "; #endif return cout; } /* This structure is a header for each leaf type. Only the InstanceLeaf has a slightly different header. All primitives inside a leaf are of the same geometry, thus have the same geometry index (geomIndex), the same shader index (shaderIndex), the same geometry mask (geomMask), and the same geometry flags (geomFlags). The shaderIndex is used to calculate the shader record to invoke. This is an extension to DXR where the geomIndex is used for that purpose. For DXR we can always set the shaderIndex to be equal to the geomIndex. */ struct PrimLeafDesc { static const uint32_t MAX_GEOM_INDEX = 0x3FFFFFFF; static const uint32_t MAX_SHADER_INDEX = 0xFFFFFF; enum Type : uint32_t { TYPE_NONE = 0, /* For a node type of NODE_TYPE_PROCEDURAL we support enabling * and disabling the opaque/non_opaque culling. */ TYPE_OPACITY_CULLING_ENABLED = 0, TYPE_OPACITY_CULLING_DISABLED = 1 }; PrimLeafDesc() {} PrimLeafDesc(uint32_t shaderIndex, uint32_t geomIndex, GeometryFlags gflags, uint32_t geomMask, Type type = TYPE_NONE) : shaderIndex(shaderIndex), geomMask(geomMask), geomIndex(geomIndex), type(type), geomFlags((uint32_t)gflags) { if (shaderIndex > MAX_SHADER_INDEX) throw std::runtime_error("too large shader ID"); if (geomIndex > MAX_GEOM_INDEX) throw std::runtime_error("too large geometry ID"); } /* compares two PrimLeafDesc's for equality */ friend bool operator ==(const PrimLeafDesc& a, const PrimLeafDesc& b) { if (a.geomIndex != b.geomIndex) return false; assert(a.shaderIndex == b.shaderIndex); assert(a.geomMask == b.geomMask); assert(a.type == b.type); assert(a.geomFlags == b.geomFlags); return true; } friend bool operator !=(const PrimLeafDesc& a, const PrimLeafDesc& b) { return !(a == b); } void print(std::ostream& cout, uint32_t depth) const { #if !defined(__SYCL_DEVICE_ONLY__) cout << tab(depth) << "PrimLeafDesc {" << std::endl; cout << tab(depth) << " shaderIndex = " << shaderIndex << std::endl; cout << tab(depth) << " geomMask = " << std::bitset<8>(geomMask) << std::endl; cout << tab(depth) << " geomFlags = " << getGeomFlags() << std::endl; cout << tab(depth) << " geomIndex = " << geomIndex << std::endl; cout << tab(depth) << "}"; #endif } friend inline std::ostream& operator<<(std::ostream& cout, const PrimLeafDesc& desc) { desc.print(cout,0); return cout; } /* Checks if opaque culling is enabled. */ bool opaqueCullingEnabled() const { return type == TYPE_OPACITY_CULLING_ENABLED; } /* procedural instances store some valid shader index */ bool isProceduralInstance() const { return shaderIndex != 0xFFFFFF; } /* returns geometry flags */ GeometryFlags getGeomFlags() const { return (GeometryFlags) geomFlags; } public: uint32_t shaderIndex : 24; // shader index used for shader record calculations uint32_t geomMask : 8; // geometry mask used for ray masking uint32_t geomIndex : 29; // the geometry index specifies the n'th geometry of the scene /*Type*/ uint32_t type : 1; // enable/disable culling for procedurals and instances /*GeometryFlags*/ uint32_t geomFlags : 2; // geometry flags of this geometry }; /* The QuadLeaf structure stores a single quad. A quad is a triangle pair with a shared edge. The first triangle has vertices v0,v1,v2, while the second triangle has vertices v[j0],v[j1],v[j2], thus the second triangle used local triangle indices. */ struct QuadLeaf { QuadLeaf() {} QuadLeaf (Vec3f v0, Vec3f v1, Vec3f v2, Vec3f v3, uint8_t j0, uint8_t j1, uint8_t j2, uint32_t shaderIndex, uint32_t geomIndex, uint32_t primIndex0, uint32_t primIndex1, GeometryFlags gflags, uint32_t geomMask, bool last) : leafDesc(shaderIndex,geomIndex,gflags,geomMask), primIndex0(primIndex0), primIndex1Delta(primIndex1-primIndex0), pad1(0), j0(j0),j1(j1),j2(j2),last(last),pad(0), v0(v0), v1(v1), v2(v2), v3(v3) { /* There are some constraints on the primitive indices. The * second primitive index always has to be the largest and the * distance between them can be at most 0xFFFF as we use 16 bits * to encode that difference. */ assert(primIndex0 <= primIndex1 && primIndex1 - primIndex0 < 0xFFFF); } /* returns the i'th vertex */ __forceinline Vec3f vertex(size_t i) const { assert(i < 4); return (&v0)[i]; } /* Checks if the specified triange is the last inside a leaf * list. */ bool isLast(uint32_t i = 1) const { assert(i<2); if (i == 0) return false; // the first triangle is never the last else return last; // the last bit tags the second triangle to be last } /* Checks if the second triangle exists. */ bool valid2() const { return !(j0 == 0 && j1 == 0 && j2 == 0); } /* Calculates the number of stored triangles. */ size_t size() const { return 1 + valid2(); } /* Calculates the effectively used bytes. If we store only one * triangle we waste the storage of one vertex. */ size_t usedBytes() const { if (valid2()) return sizeof(QuadLeaf); else return sizeof(QuadLeaf)-sizeof(Vec3f); } /* Calculates to delta to add to primIndex0 to get the primitive * index of the i'th triangle. */ uint32_t primIndexDelta(uint32_t i) const { assert(i<2); return i*primIndex1Delta; } /* Calculates the primitive index of the i'th triangle. */ uint32_t primIndex(uint32_t i) const { assert(i<2); return primIndex0 + primIndexDelta(i); } /* Quad mode is a special mode where the uv's over the quad are * defined over the entire range [0,1]x[0,1]. */ bool quadMode() const { return primIndex1Delta == 0; } /* Calculates the bounding box of this leaf. */ BBox3f bounds() const { BBox3f b = empty; b.extend(v0); b.extend(v1); b.extend(v2); if (valid2()) b.extend(v3); return b; } /* output of quad leaf */ void print(std::ostream& cout, uint32_t depth) const { #if !defined(__SYCL_DEVICE_ONLY__) cout << tab(depth) << "QuadLeaf {" << std::endl; cout << tab(depth) << " addr = " << this << std::endl; cout << tab(depth) << " shaderIndex = " << leafDesc.shaderIndex << std::endl; cout << tab(depth) << " geomMask = " << std::bitset<8>(leafDesc.geomMask) << std::endl; cout << tab(depth) << " geomFlags = " << leafDesc.getGeomFlags() << std::endl; cout << tab(depth) << " geomIndex = " << leafDesc.geomIndex << std::endl; cout << tab(depth) << " triangle0 = { " << std::endl; cout << tab(depth) << " primIndex = " << primIndex(0) << std::endl; cout << tab(depth) << " v0 = " << v0 << std::endl; cout << tab(depth) << " v1 = " << v1 << std::endl; cout << tab(depth) << " v2 = " << v2 << std::endl; cout << tab(depth) << " }" << std::endl; if (valid2()) { cout << tab(depth) << " triangle1 = { " << std::endl; cout << tab(depth) << " primIndex = " << primIndex(1) << std::endl; cout << tab(depth) << " v0 = " << vertex(j0) << std::endl; cout << tab(depth) << " v1 = " << vertex(j1) << std::endl; cout << tab(depth) << " v2 = " << vertex(j2) << std::endl; cout << tab(depth) << " }" << std::endl; } cout << tab(depth) << "}"; #endif } /* output operator for QuadLeaf */ friend inline std::ostream& operator<<(std::ostream& cout, const QuadLeaf& leaf) { leaf.print(cout,0); return cout; } public: PrimLeafDesc leafDesc; // the leaf header uint32_t primIndex0; // primitive index of first triangle struct { uint32_t primIndex1Delta : 5; // delta encoded primitive index of second triangle uint32_t pad1 : 11; // MBZ uint32_t j0 : 2; // specifies first vertex of second triangle uint32_t j1 : 2; // specified second vertex of second triangle uint32_t j2 : 2; // specified third vertex of second triangle uint32_t last : 1; // true if the second triangle is the last triangle in a leaf list uint32_t pad : 9; // unused bits }; Vec3f v0; // first vertex of first triangle Vec3f v1; // second vertex of first triangle Vec3f v2; // third vertex of first triangle Vec3f v3; // forth vertex used for second triangle }; static_assert(sizeof(QuadLeaf) == 64, "QuadLeaf must be 64 bytes large"); /* Internal instance flags definition. */ struct InstanceFlags { enum Flags : uint8_t { NONE = 0x0, TRIANGLE_CULL_DISABLE = 0x1, // disables culling of front and back facing triangles through ray flags TRIANGLE_FRONT_COUNTERCLOCKWISE = 0x2, // for mirroring transformations the instance can switch front and backface of triangles FORCE_OPAQUE = 0x4, // forces all primitives inside this instance to be opaque FORCE_NON_OPAQUE = 0x8 // forces all primitives inside this instane to be non-opaque }; InstanceFlags() {} InstanceFlags(Flags rflags) : flags(rflags) {} InstanceFlags(uint8_t rflags) : flags((Flags)rflags) {} operator Flags () const { return flags; } /* output operator for InstanceFlags */ friend inline std::ostream& operator<<(std::ostream& cout, const InstanceFlags& iflags) { #if !defined(__SYCL_DEVICE_ONLY__) if (iflags == InstanceFlags::NONE) return cout << "NONE"; if (iflags.triangle_cull_disable) cout << "TRIANGLE_CULL_DISABLE "; if (iflags.triangle_front_counterclockwise) cout << "TRIANGLE_FRONT_COUNTERCLOCKWISE "; if (iflags.force_opaque) cout << "FORCE_OPAQUE "; if (iflags.force_non_opaque) cout << "FORCE_NON_OPAQUE "; #endif return cout; } public: union { Flags flags; struct { bool triangle_cull_disable : 1; bool triangle_front_counterclockwise : 1; bool force_opaque : 1; bool force_non_opaque : 1; }; }; }; inline InstanceFlags::Flags operator| (InstanceFlags::Flags a,InstanceFlags::Flags b) { return (InstanceFlags::Flags)(int(a) | int(b)); } /* The instance leaf represent an instance. It essentially stores transformation matrices (local to world as well as world to local) of the instance as well as a pointer to the start node of some BVH. The instance leaf consists of two parts, part0 (first 64 bytes) and part1 (second 64 bytes). Part0 will only get accessed by hardware and stores the world to local transformation as well as the BVH node to start traversal. Part1 stores additional data that is only read by the shader, e.g. it stores the local to world transformation of the instance. The layout of the first part of the InstanceLeaf is compatible with a ProceduralLeaf, thus we can use the same layout for software instancing if we want. */ struct InstanceLeaf { InstanceLeaf() {} InstanceLeaf (AffineSpace3f obj2world, uint64_t startNodePtr, uint32_t instID, uint32_t instUserID, uint8_t instMask) { part0.shaderIndex = 0; //InstShaderRecordID; part0.geomMask = instMask; part0.instanceContributionToHitGroupIndex = 0; //desc.InstanceContributionToHitGroupIndex; part0.pad0 = 0; part0.type = PrimLeafDesc::TYPE_OPACITY_CULLING_ENABLED; part0.geomFlags = (uint32_t) GeometryFlags::NONE; part0.startNodePtr = startNodePtr; assert((startNodePtr >> 48) == 0); part0.instFlags = (InstanceFlags) 0; part0.pad1 = 0; part1.instanceID = instUserID; part1.instanceIndex = instID; part1.bvhPtr = (uint64_t) 0; part1.pad = 0; part1.obj2world_vx = obj2world.l.vx; part1.obj2world_vy = obj2world.l.vy; part1.obj2world_vz = obj2world.l.vz; part0.obj2world_p = obj2world.p; const AffineSpace3f world2obj = rcp(obj2world); part0.world2obj_vx = world2obj.l.vx; part0.world2obj_vy = world2obj.l.vy; part0.world2obj_vz = world2obj.l.vz; part1.world2obj_p = world2obj.p; } /* Returns the address of the start node pointer. We need this * address to calculate relocation tables when dumping the BVH to * disk. */ const uint64_t startNodePtrAddr() const { return (uint64_t)((char*)&part0 + 8); } /* Returns the address of the BVH that contains the start node. */ const uint64_t bvhPtrAddr() const { return (uint64_t)&part1; } /* returns the world to object space transformation matrix. */ const AffineSpace3f World2Obj() const { return AffineSpace3f(part0.world2obj_vx,part0.world2obj_vy,part0.world2obj_vz,part1.world2obj_p); } /* returns the object to world space transformation matrix. */ const AffineSpace3f Obj2World() const { return AffineSpace3f(part1.obj2world_vx,part1.obj2world_vy,part1.obj2world_vz,part0.obj2world_p); } /* output operator for instance leaf */ void print (std::ostream& cout, uint32_t depth) const { #if !defined(__SYCL_DEVICE_ONLY__) if (!part0.type) cout << tab(depth) << "InstanceLeaf {" << std::endl; else cout << tab(depth) << "ProceduralInstanceLeaf {" << std::endl; cout << tab(depth) << " addr = " << this << std::endl; cout << tab(depth) << " shaderIndex = " << part0.shaderIndex << std::endl; cout << tab(depth) << " geomMask = " << std::bitset<8>(part0.geomMask) << std::endl; cout << tab(depth) << " geomIndex = " << part1.instanceIndex << std::endl; cout << tab(depth) << " instanceID = " << part1.instanceID << std::endl; cout << tab(depth) << " instFlags = " << InstanceFlags(part0.instFlags) << std::endl; cout << tab(depth) << " startNodePtr = " << (void*)(size_t)part0.startNodePtr << std::endl; cout << tab(depth) << " obj2world.vx = " << part1.obj2world_vx << std::endl; cout << tab(depth) << " obj2world.vy = " << part1.obj2world_vy << std::endl; cout << tab(depth) << " obj2world.vz = " << part1.obj2world_vz << std::endl; cout << tab(depth) << " obj2world.p = " << part0.obj2world_p << std::endl; cout << tab(depth) << " world2obj.vx = " << part0.world2obj_vx << std::endl; cout << tab(depth) << " world2obj.vy = " << part0.world2obj_vy << std::endl; cout << tab(depth) << " world2obj.vz = " << part0.world2obj_vz << std::endl; cout << tab(depth) << " world2obj.p = " << part1.world2obj_p << std::endl; cout << tab(depth) << " instanceContributionToHitGroupIndex = " << part0.instanceContributionToHitGroupIndex << std::endl; cout << tab(depth) << "}"; #endif } /* output operator for InstanceLeaf */ friend inline std::ostream& operator<<(std::ostream& cout, const InstanceLeaf& leaf) { leaf.print(cout,0); return cout; } /* first 64 bytes accessed during traversal by hardware */ struct Part0 { /* Checks if opaque culling is enabled. */ bool opaqueCullingEnabled() const { return type == PrimLeafDesc::TYPE_OPACITY_CULLING_ENABLED; } public: uint32_t shaderIndex : 24; // shader index used to calculate instancing shader in case of software instancing uint32_t geomMask : 8; // geometry mask used for ray masking uint32_t instanceContributionToHitGroupIndex : 24; uint32_t pad0 : 5; /* the following two entries are only used for procedural instances */ /*PrimLeafDesc::Type*/ uint32_t type : 1; // enables/disables opaque culling /*GeometryFlags*/ uint32_t geomFlags : 2; // unused for instances uint64_t startNodePtr : 48; // start node where to continue traversal of the instanced object uint64_t instFlags : 8; // flags for the instance (see InstanceFlags) uint64_t pad1 : 8; // unused bits Vec3f world2obj_vx; // 1st column of Worl2Obj transform Vec3f world2obj_vy; // 2nd column of Worl2Obj transform Vec3f world2obj_vz; // 3rd column of Worl2Obj transform Vec3f obj2world_p; // translation of Obj2World transform (on purpose in first 64 bytes) } part0; /* second 64 bytes accessed during shading */ struct Part1 { uint64_t bvhPtr : 48; // pointer to BVH where start node belongs too uint64_t pad : 16; // unused bits uint32_t instanceID; // user defined value per DXR spec uint32_t instanceIndex; // geometry index of the instance (n'th geometry in scene) Vec3f obj2world_vx; // 1st column of Obj2World transform Vec3f obj2world_vy; // 2nd column of Obj2World transform Vec3f obj2world_vz; // 3rd column of Obj2World transform Vec3f world2obj_p; // translation of World2Obj transform } part1; }; static_assert(sizeof(InstanceLeaf) == 128, "InstanceLeaf must be 128 bytes large"); /* Leaf type for procedural geometry. This leaf only contains the leaf header (which identifices the geometry) and a list of primitive indices. The BVH will typically reference only some of the primitives stores inside this leaf. The range is specified by a start primitive and the last primitive is tagged with a bit. */ struct ProceduralLeaf { static const uint32_t N = 13; /* Creates an empty procedural leaf. */ ProceduralLeaf () : leafDesc(PrimLeafDesc::MAX_SHADER_INDEX,PrimLeafDesc::MAX_GEOM_INDEX,GeometryFlags::NONE,0), numPrimitives(0), pad(0), last(0) { for (auto& id : _primIndex) id = 0xFFFFFFFF; } /* Creates a procedural leaf with one primitive. More primitives * of the same geometry can get added later using the add * function. */ ProceduralLeaf (PrimLeafDesc leafDesc, uint32_t primIndex, bool last) : leafDesc(leafDesc), numPrimitives(1), pad(0), last(last ? 0xFFFFFFFF : 0xFFFFFFFE) { for (auto& id : _primIndex) id = 0xFFFFFFFF; _primIndex[0] = primIndex; } /* returns the number of primitives stored inside this leaf */ uint32_t size() const { return numPrimitives; } /* Calculates the effectively used bytes. */ size_t usedBytes() const { /*if (leafDesc.isProceduralInstance()) return sizeof(InstanceLeaf); else*/ return sizeof(PrimLeafDesc)+4+4*numPrimitives; } /* if possible adds a new primitive to this leaf */ bool add(PrimLeafDesc leafDesc_in, uint32_t primIndex_in, bool last_in) { assert(primIndex_in != 0xFFFFFFFF); if (numPrimitives >= N) return false; if (!numPrimitives) leafDesc = leafDesc_in; if (leafDesc != leafDesc_in) return false; _primIndex[numPrimitives] = primIndex_in; if (last_in) last |= 1 << numPrimitives; else last &= ~(1 << numPrimitives); numPrimitives++; return true; } /* returns the primitive index of the i'th primitive */ uint32_t primIndex(uint32_t i) const { assert(i < N); return _primIndex[i]; } /* checks if the i'th primitive is the last in a leaf list */ bool isLast(uint32_t i) const { if (i >= N) return true; // just to make some verify tests happy else return (last >> i) & 1; } /* output operator for procedural leaf */ void print (std::ostream& cout, uint32_t i, uint32_t depth) const { #if !defined(__SYCL_DEVICE_ONLY__) cout << tab(depth) << "ProceduralLeaf {" << std::endl; cout << tab(depth) << " addr = " << this << std::endl; cout << tab(depth) << " slot = " << i << std::endl; if (i < N) { cout << tab(depth) << " shaderIndex = " << leafDesc.shaderIndex << std::endl; cout << tab(depth) << " geomMask = " << std::bitset<8>(leafDesc.geomMask) << std::endl; cout << tab(depth) << " geomFlags = " << leafDesc.getGeomFlags() << std::endl; cout << tab(depth) << " geomIndex = " << leafDesc.geomIndex << std::endl; cout << tab(depth) << " primIndex = " << primIndex(i) << std::endl; } else { cout << tab(depth) << " INVALID" << std::endl; } cout << tab(depth) << "}"; #endif } public: PrimLeafDesc leafDesc; // leaf header identifying the geometry uint32_t numPrimitives : 4; // number of stored primitives uint32_t pad : 32-4-N; uint32_t last : N; // bit vector with a last bit per primitive uint32_t _primIndex[N]; // primitive indices of all primitives stored inside the leaf }; static_assert(sizeof(ProceduralLeaf) == 64, "ProceduralLeaf must be 64 bytes large"); } level-zero-raytracing-support-1.0.0/rtbuild/math/000077500000000000000000000000001450534701400220505ustar00rootroot00000000000000level-zero-raytracing-support-1.0.0/rtbuild/math/CMakeLists.txt000066400000000000000000000007261450534701400246150ustar00rootroot00000000000000## Copyright 2009-2021 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 ADD_LIBRARY(math STATIC constants.cpp) SET_PROPERTY(TARGET math PROPERTY FOLDER common) SET_PROPERTY(TARGET math APPEND PROPERTY COMPILE_FLAGS " ${FLAGS_LOWEST}") IF (EMBREE_STATIC_LIB) INSTALL(TARGETS math EXPORT math-targets ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT devel) INSTALL(EXPORT math-targets DESTINATION "${EMBREE_CMAKEEXPORT_DIR}" COMPONENT devel) ENDIF() level-zero-raytracing-support-1.0.0/rtbuild/math/affinespace.h000066400000000000000000000231701450534701400244700ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once //#include "linearspace2.h" #include "linearspace3.h" //#include "quaternion.h" #include "bbox.h" //#include "vec4.h" namespace embree { #define VectorT typename L::Vector #define ScalarT typename L::Vector::Scalar //////////////////////////////////////////////////////////////////////////////// // Affine Space //////////////////////////////////////////////////////////////////////////////// template struct AffineSpaceT { L l; /*< linear part of affine space */ VectorT p; /*< affine part of affine space */ //////////////////////////////////////////////////////////////////////////////// // Constructors, Assignment, Cast, Copy Operations //////////////////////////////////////////////////////////////////////////////// __forceinline AffineSpaceT ( ) { } __forceinline AffineSpaceT ( const AffineSpaceT& other ) { l = other.l; p = other.p; } __forceinline AffineSpaceT ( const L & other ) { l = other ; p = VectorT(zero); } __forceinline AffineSpaceT& operator=( const AffineSpaceT& other ) { l = other.l; p = other.p; return *this; } __forceinline AffineSpaceT( const VectorT& vx, const VectorT& vy, const VectorT& vz, const VectorT& p ) : l(vx,vy,vz), p(p) {} __forceinline AffineSpaceT( const L& l, const VectorT& p ) : l(l), p(p) {} template __forceinline AffineSpaceT( const AffineSpaceT& s ) : l(s.l), p(s.p) {} //////////////////////////////////////////////////////////////////////////////// // Constants //////////////////////////////////////////////////////////////////////////////// __forceinline AffineSpaceT( ZeroTy ) : l(zero), p(zero) {} __forceinline AffineSpaceT( OneTy ) : l(one), p(zero) {} /*! return matrix for scaling */ static __forceinline AffineSpaceT scale(const VectorT& s) { return L::scale(s); } /*! return matrix for translation */ static __forceinline AffineSpaceT translate(const VectorT& p) { return AffineSpaceT(one,p); } /*! return matrix for rotation, only in 2D */ static __forceinline AffineSpaceT rotate(const ScalarT& r) { return L::rotate(r); } /*! return matrix for rotation around arbitrary point (2D) or axis (3D) */ static __forceinline AffineSpaceT rotate(const VectorT& u, const ScalarT& r) { return L::rotate(u,r); } /*! return matrix for rotation around arbitrary axis and point, only in 3D */ static __forceinline AffineSpaceT rotate(const VectorT& p, const VectorT& u, const ScalarT& r) { return translate(+p) * rotate(u,r) * translate(-p); } /*! return matrix for looking at given point, only in 3D */ static __forceinline AffineSpaceT lookat(const VectorT& eye, const VectorT& point, const VectorT& up) { VectorT Z = normalize(point-eye); VectorT U = normalize(cross(up,Z)); VectorT V = normalize(cross(Z,U)); return AffineSpaceT(L(U,V,Z),eye); } }; // template specialization to get correct identity matrix for type AffineSpace3fa template<> __forceinline AffineSpaceT::AffineSpaceT( OneTy ) : l(one), p(0.f, 0.f, 0.f, 1.f) {} //////////////////////////////////////////////////////////////////////////////// // Unary Operators //////////////////////////////////////////////////////////////////////////////// template __forceinline AffineSpaceT operator -( const AffineSpaceT& a ) { return AffineSpaceT(-a.l,-a.p); } template __forceinline AffineSpaceT operator +( const AffineSpaceT& a ) { return AffineSpaceT(+a.l,+a.p); } template __forceinline AffineSpaceT rcp( const AffineSpaceT& a ) { L il = rcp(a.l); return AffineSpaceT(il,-(il*a.p)); } //////////////////////////////////////////////////////////////////////////////// // Binary Operators //////////////////////////////////////////////////////////////////////////////// template __forceinline const AffineSpaceT operator +( const AffineSpaceT& a, const AffineSpaceT& b ) { return AffineSpaceT(a.l+b.l,a.p+b.p); } template __forceinline const AffineSpaceT operator -( const AffineSpaceT& a, const AffineSpaceT& b ) { return AffineSpaceT(a.l-b.l,a.p-b.p); } template __forceinline const AffineSpaceT operator *( const ScalarT & a, const AffineSpaceT& b ) { return AffineSpaceT(a*b.l,a*b.p); } template __forceinline const AffineSpaceT operator *( const AffineSpaceT& a, const AffineSpaceT& b ) { return AffineSpaceT(a.l*b.l,a.l*b.p+a.p); } template __forceinline const AffineSpaceT operator /( const AffineSpaceT& a, const AffineSpaceT& b ) { return a * rcp(b); } template __forceinline const AffineSpaceT operator /( const AffineSpaceT& a, const ScalarT & b ) { return a * rcp(b); } template __forceinline AffineSpaceT& operator *=( AffineSpaceT& a, const AffineSpaceT& b ) { return a = a * b; } template __forceinline AffineSpaceT& operator *=( AffineSpaceT& a, const ScalarT & b ) { return a = a * b; } template __forceinline AffineSpaceT& operator /=( AffineSpaceT& a, const AffineSpaceT& b ) { return a = a / b; } template __forceinline AffineSpaceT& operator /=( AffineSpaceT& a, const ScalarT & b ) { return a = a / b; } template __forceinline VectorT xfmPoint (const AffineSpaceT& m, const VectorT& p) { return madd(VectorT(p.x),m.l.vx,madd(VectorT(p.y),m.l.vy,madd(VectorT(p.z),m.l.vz,m.p))); } template __forceinline VectorT xfmVector(const AffineSpaceT& m, const VectorT& v) { return xfmVector(m.l,v); } template __forceinline VectorT xfmNormal(const AffineSpaceT& m, const VectorT& n) { return xfmNormal(m.l,n); } __forceinline const BBox xfmBounds(const AffineSpaceT >& m, const BBox& b) { BBox3fa dst = empty; const Vec3fa p0(b.lower.x,b.lower.y,b.lower.z); dst.extend(xfmPoint(m,p0)); const Vec3fa p1(b.lower.x,b.lower.y,b.upper.z); dst.extend(xfmPoint(m,p1)); const Vec3fa p2(b.lower.x,b.upper.y,b.lower.z); dst.extend(xfmPoint(m,p2)); const Vec3fa p3(b.lower.x,b.upper.y,b.upper.z); dst.extend(xfmPoint(m,p3)); const Vec3fa p4(b.upper.x,b.lower.y,b.lower.z); dst.extend(xfmPoint(m,p4)); const Vec3fa p5(b.upper.x,b.lower.y,b.upper.z); dst.extend(xfmPoint(m,p5)); const Vec3fa p6(b.upper.x,b.upper.y,b.lower.z); dst.extend(xfmPoint(m,p6)); const Vec3fa p7(b.upper.x,b.upper.y,b.upper.z); dst.extend(xfmPoint(m,p7)); return dst; } //////////////////////////////////////////////////////////////////////////////// /// Comparison Operators //////////////////////////////////////////////////////////////////////////////// template __forceinline bool operator ==( const AffineSpaceT& a, const AffineSpaceT& b ) { return a.l == b.l && a.p == b.p; } template __forceinline bool operator !=( const AffineSpaceT& a, const AffineSpaceT& b ) { return a.l != b.l || a.p != b.p; } //////////////////////////////////////////////////////////////////////////////// /// Select //////////////////////////////////////////////////////////////////////////////// template __forceinline AffineSpaceT select ( const typename L::Vector::Scalar::Bool& s, const AffineSpaceT& t, const AffineSpaceT& f ) { return AffineSpaceT(select(s,t.l,f.l),select(s,t.p,f.p)); } //////////////////////////////////////////////////////////////////////////////// // Output Operators //////////////////////////////////////////////////////////////////////////////// template static embree_ostream operator<<(embree_ostream cout, const AffineSpaceT& m) { return cout << "{ l = " << m.l << ", p = " << m.p << " }"; } //////////////////////////////////////////////////////////////////////////////// // Template Instantiations //////////////////////////////////////////////////////////////////////////////// //typedef AffineSpaceT AffineSpace2f; typedef AffineSpaceT AffineSpace3f; typedef AffineSpaceT AffineSpace3fa; typedef AffineSpaceT AffineSpace3fx; typedef AffineSpaceT AffineSpace3ff; //typedef AffineSpaceT OrthonormalSpace3f; template using AffineSpace3vf = AffineSpaceT>>>; typedef AffineSpaceT>>> AffineSpace3vf4; typedef AffineSpaceT>>> AffineSpace3vf8; typedef AffineSpaceT>>> AffineSpace3vf16; //template using AffineSpace3vff = AffineSpaceT>>>; //typedef AffineSpaceT>>> AffineSpace3vfa4; //typedef AffineSpaceT>>> AffineSpace3vfa8; //typedef AffineSpaceT>>> AffineSpace3vfa16; ////////////////////////////////////////////////////////////////////////////// /// Interpolation ////////////////////////////////////////////////////////////////////////////// template __forceinline AffineSpaceT lerp(const AffineSpaceT& M0, const AffineSpaceT& M1, const R& t) { return AffineSpaceT(lerp(M0.l,M1.l,t),lerp(M0.p,M1.p,t)); } #undef VectorT #undef ScalarT } level-zero-raytracing-support-1.0.0/rtbuild/math/bbox.h000066400000000000000000000343551450534701400231650ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "vec2.h" #include "vec3.h" namespace embree { namespace internal { template __forceinline T divideByTwo(const T& v) { return v / T(2); } template <> __forceinline float divideByTwo(const float& v) { return v * 0.5f; } template <> __forceinline double divideByTwo(const double& v) { return v * 0.5; } } // namespace internal template struct BBox { T lower, upper; //////////////////////////////////////////////////////////////////////////////// /// Construction //////////////////////////////////////////////////////////////////////////////// __forceinline BBox ( ) { } template __forceinline BBox ( const BBox& other ) : lower(other.lower), upper(other.upper) {} __forceinline BBox& operator=( const BBox& other ) { lower = other.lower; upper = other.upper; return *this; } __forceinline BBox ( const T& v ) : lower(v), upper(v) {} __forceinline BBox ( const T& lower, const T& upper ) : lower(lower), upper(upper) {} //////////////////////////////////////////////////////////////////////////////// /// Extending Bounds //////////////////////////////////////////////////////////////////////////////// __forceinline const BBox& extend(const BBox& other) { lower = min(lower,other.lower); upper = max(upper,other.upper); return *this; } __forceinline const BBox& extend(const T & other) { lower = min(lower,other ); upper = max(upper,other ); return *this; } /*! tests if box is empty */ __forceinline bool empty() const { for (int i=0; i upper[i]) return true; return false; } /*! computes the size of the box */ __forceinline T size() const { return upper - lower; } /*! computes the center of the box */ __forceinline T center() const { return internal::divideByTwo(lower+upper); } /*! computes twice the center of the box */ __forceinline T center2() const { return lower+upper; } /*! merges two boxes */ __forceinline static const BBox merge (const BBox& a, const BBox& b) { return BBox(min(a.lower, b.lower), max(a.upper, b.upper)); } /*! intersects two boxes */ __forceinline static const BBox intersect (const BBox& a, const BBox& b) { return BBox(max(a.lower, b.lower), min(a.upper, b.upper)); } /*! enlarge box by some scaling factor */ __forceinline BBox enlarge_by(const float a) const { return BBox(lower - T(a)*abs(lower), upper + T(a)*abs(upper)); } //////////////////////////////////////////////////////////////////////////////// /// Constants //////////////////////////////////////////////////////////////////////////////// __forceinline BBox( EmptyTy ) : lower(pos_inf), upper(neg_inf) {} __forceinline BBox( FullTy ) : lower(neg_inf), upper(pos_inf) {} __forceinline BBox( FalseTy ) : lower(pos_inf), upper(neg_inf) {} __forceinline BBox( TrueTy ) : lower(neg_inf), upper(pos_inf) {} __forceinline BBox( NegInfTy ): lower(pos_inf), upper(neg_inf) {} __forceinline BBox( PosInfTy ): lower(neg_inf), upper(pos_inf) {} }; template<> __forceinline bool BBox::empty() const { return lower > upper; } #if defined(__SSE__) || defined(__ARM_NEON) template<> __forceinline bool BBox::empty() const { return !all(le_mask(lower,upper)); } template<> __forceinline bool BBox::empty() const { return !all(le_mask(lower,upper)); } #endif /*! tests if box is finite */ __forceinline bool isvalid( const BBox& v ) { return all(gt_mask(v.lower,Vec3fa_t(-FLT_LARGE)) & lt_mask(v.upper,Vec3fa_t(+FLT_LARGE))); } /*! tests if box is finite and non-empty*/ __forceinline bool isvalid_non_empty( const BBox& v ) { return all(gt_mask(v.lower,Vec3fa_t(-FLT_LARGE)) & lt_mask(v.upper,Vec3fa_t(+FLT_LARGE)) & le_mask(v.lower,v.upper)); } /*! tests if box has finite entries */ __forceinline bool is_finite( const BBox& b) { return is_finite(b.lower) && is_finite(b.upper); } /*! test if point contained in box */ __forceinline bool inside ( const BBox& b, const Vec3fa& p ) { return all(ge_mask(p,b.lower) & le_mask(p,b.upper)); } /*! computes the center of the box */ template __forceinline const T center2(const BBox& box) { return box.lower + box.upper; } template __forceinline const T center (const BBox& box) { return internal::divideByTwo(center2(box)); } /*! computes the volume of a bounding box */ __forceinline float volume ( const BBox& b ) { return reduce_mul(b.size()); } __forceinline float safeVolume( const BBox& b ) { if (b.empty()) return 0.0f; else return volume(b); } /*! computes the volume of a bounding box */ __forceinline float volume( const BBox& b ) { return reduce_mul(b.size()); } /*! computes the surface area of a bounding box */ template __forceinline const T area( const BBox >& b ) { const Vec2 d = b.size(); return d.x*d.y; } template __forceinline const T halfArea( const BBox >& b ) { return halfArea(b.size()); } template __forceinline const T area( const BBox >& b ) { return T(2)*halfArea(b); } __forceinline float halfArea( const BBox& b ) { return halfArea(b.size()); } __forceinline float area( const BBox& b ) { return 2.0f*halfArea(b); } __forceinline float halfArea( const BBox& b ) { return halfArea(b.size()); } __forceinline float area( const BBox& b ) { return 2.0f*halfArea(b); } template __forceinline float safeArea( const BBox& b ) { if (b.empty()) return 0.0f; else return area(b); } template __forceinline float expectedApproxHalfArea(const BBox& box) { return halfArea(box); } /*! merges bounding boxes and points */ template __forceinline const BBox merge( const BBox& a, const T& b ) { return BBox(min(a.lower, b ), max(a.upper, b )); } template __forceinline const BBox merge( const T& a, const BBox& b ) { return BBox(min(a , b.lower), max(a , b.upper)); } template __forceinline const BBox merge( const BBox& a, const BBox& b ) { return BBox(min(a.lower, b.lower), max(a.upper, b.upper)); } /*! Merges three boxes. */ template __forceinline const BBox merge( const BBox& a, const BBox& b, const BBox& c ) { return merge(a,merge(b,c)); } /*! Merges four boxes. */ template __forceinline BBox merge(const BBox& a, const BBox& b, const BBox& c, const BBox& d) { return merge(merge(a,b),merge(c,d)); } /*! Comparison Operators */ template __forceinline bool operator==( const BBox& a, const BBox& b ) { return a.lower == b.lower && a.upper == b.upper; } template __forceinline bool operator!=( const BBox& a, const BBox& b ) { return a.lower != b.lower || a.upper != b.upper; } /*! scaling */ template __forceinline BBox operator *( const float& a, const BBox& b ) { return BBox(a*b.lower,a*b.upper); } template __forceinline BBox operator *( const T& a, const BBox& b ) { return BBox(a*b.lower,a*b.upper); } /*! translations */ template __forceinline BBox operator +( const BBox& a, const BBox& b ) { return BBox(a.lower+b.lower,a.upper+b.upper); } template __forceinline BBox operator -( const BBox& a, const BBox& b ) { return BBox(a.lower-b.lower,a.upper-b.upper); } template __forceinline BBox operator +( const BBox& a, const T & b ) { return BBox(a.lower+b ,a.upper+b ); } template __forceinline BBox operator -( const BBox& a, const T & b ) { return BBox(a.lower-b ,a.upper-b ); } /*! extension */ template __forceinline BBox enlarge(const BBox& a, const T& b) { return BBox(a.lower-b, a.upper+b); } /*! intersect bounding boxes */ template __forceinline const BBox intersect( const BBox& a, const BBox& b ) { return BBox(max(a.lower, b.lower), min(a.upper, b.upper)); } template __forceinline const BBox intersect( const BBox& a, const BBox& b, const BBox& c ) { return intersect(a,intersect(b,c)); } template __forceinline const BBox intersect( const BBox& a, const BBox& b, const BBox& c, const BBox& d ) { return intersect(intersect(a,b),intersect(c,d)); } /*! subtract bounds from each other */ template __forceinline void subtract(const BBox& a, const BBox& b, BBox& c, BBox& d) { c.lower = a.lower; c.upper = min(a.upper,b.lower); d.lower = max(a.lower,b.upper); d.upper = a.upper; } /*! tests if bounding boxes (and points) are disjoint (empty intersection) */ template __inline bool disjoint( const BBox& a, const BBox& b ) { return intersect(a,b).empty(); } template __inline bool disjoint( const BBox& a, const T& b ) { return disjoint(a,BBox(b)); } template __inline bool disjoint( const T& a, const BBox& b ) { return disjoint(BBox(a),b); } /*! tests if bounding boxes (and points) are conjoint (non-empty intersection) */ template __inline bool conjoint( const BBox& a, const BBox& b ) { return !intersect(a,b).empty(); } template __inline bool conjoint( const BBox& a, const T& b ) { return conjoint(a,BBox(b)); } template __inline bool conjoint( const T& a, const BBox& b ) { return conjoint(BBox(a),b); } /*! subset relation */ template __inline bool subset( const BBox& a, const BBox& b ) { for ( size_t i = 0; i < T::N; i++ ) if ( a.lower[i] < b.lower[i] ) return false; for ( size_t i = 0; i < T::N; i++ ) if ( a.upper[i] > b.upper[i] ) return false; return true; } template<> __inline bool subset( const BBox& a, const BBox& b ) { return all(ge_mask(a.lower,b.lower)) && all(le_mask(a.upper,b.upper)); } template<> __inline bool subset( const BBox& a, const BBox& b ) { return all(ge_mask(a.lower,b.lower)) && all(le_mask(a.upper,b.upper)); } /*! blending */ template __forceinline BBox lerp(const BBox& b0, const BBox& b1, const float t) { return BBox(lerp(b0.lower,b1.lower,t),lerp(b0.upper,b1.upper,t)); } /*! output operator */ template __forceinline embree_ostream operator<<(embree_ostream cout, const BBox& box) { return cout << "[" << box.lower << "; " << box.upper << "]"; } /*! default template instantiations */ typedef BBox BBox1f; typedef BBox BBox2f; //typedef BBox BBox2fa; typedef BBox BBox3f; typedef BBox BBox3fa; typedef BBox BBox3fx; typedef BBox BBox3ff; } //////////////////////////////////////////////////////////////////////////////// /// SSE / AVX / MIC specializations //////////////////////////////////////////////////////////////////////////////// #if defined (__SSE__) || defined(__ARM_NEON) #include "../simd/sse.h" #endif #if defined (__AVX__) #include "../simd/avx.h" #endif #if defined(__AVX512F__) #include "../simd/avx512.h" #endif namespace embree { template __forceinline BBox>> transpose(const BBox3fa* bounds); template<> __forceinline BBox> transpose<4>(const BBox3fa* bounds) { BBox> dest; transpose((vfloat4&)bounds[0].lower, (vfloat4&)bounds[1].lower, (vfloat4&)bounds[2].lower, (vfloat4&)bounds[3].lower, dest.lower.x, dest.lower.y, dest.lower.z); transpose((vfloat4&)bounds[0].upper, (vfloat4&)bounds[1].upper, (vfloat4&)bounds[2].upper, (vfloat4&)bounds[3].upper, dest.upper.x, dest.upper.y, dest.upper.z); return dest; } #if defined(__AVX__) template<> __forceinline BBox> transpose<8>(const BBox3fa* bounds) { BBox> dest; transpose((vfloat4&)bounds[0].lower, (vfloat4&)bounds[1].lower, (vfloat4&)bounds[2].lower, (vfloat4&)bounds[3].lower, (vfloat4&)bounds[4].lower, (vfloat4&)bounds[5].lower, (vfloat4&)bounds[6].lower, (vfloat4&)bounds[7].lower, dest.lower.x, dest.lower.y, dest.lower.z); transpose((vfloat4&)bounds[0].upper, (vfloat4&)bounds[1].upper, (vfloat4&)bounds[2].upper, (vfloat4&)bounds[3].upper, (vfloat4&)bounds[4].upper, (vfloat4&)bounds[5].upper, (vfloat4&)bounds[6].upper, (vfloat4&)bounds[7].upper, dest.upper.x, dest.upper.y, dest.upper.z); return dest; } #endif template __forceinline BBox3fa merge(const BBox3fa* bounds); template<> __forceinline BBox3fa merge<4>(const BBox3fa* bounds) { const Vec3fa lower = min(min(bounds[0].lower,bounds[1].lower), min(bounds[2].lower,bounds[3].lower)); const Vec3fa upper = max(max(bounds[0].upper,bounds[1].upper), max(bounds[2].upper,bounds[3].upper)); return BBox3fa(lower,upper); } #if defined(__AVX__) template<> __forceinline BBox3fa merge<8>(const BBox3fa* bounds) { const Vec3fa lower = min(min(min(bounds[0].lower,bounds[1].lower),min(bounds[2].lower,bounds[3].lower)), min(min(bounds[4].lower,bounds[5].lower),min(bounds[6].lower,bounds[7].lower))); const Vec3fa upper = max(max(max(bounds[0].upper,bounds[1].upper),max(bounds[2].upper,bounds[3].upper)), max(max(bounds[4].upper,bounds[5].upper),max(bounds[6].upper,bounds[7].upper))); return BBox3fa(lower,upper); } #endif } level-zero-raytracing-support-1.0.0/rtbuild/math/constants.h000066400000000000000000000205021450534701400242340ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "../sys/platform.h" #include #define _USE_MATH_DEFINES #include // using cmath causes issues under Windows #include #include namespace embree { static MAYBE_UNUSED const float one_over_255 = 1.0f/255.0f; static MAYBE_UNUSED const float min_rcp_input = 1E-18f; // for abs(x) >= min_rcp_input the newton raphson rcp calculation does not fail /* we consider floating point numbers in that range as valid input numbers */ static MAYBE_UNUSED float FLT_LARGE = 1.844E18f; struct TrueTy { __forceinline operator bool( ) const { return true; } }; const constexpr TrueTy True = TrueTy(); struct FalseTy { __forceinline operator bool( ) const { return false; } }; const constexpr FalseTy False = FalseTy(); struct ZeroTy { __forceinline operator double ( ) const { return 0; } __forceinline operator float ( ) const { return 0; } __forceinline operator long long( ) const { return 0; } __forceinline operator unsigned long long( ) const { return 0; } __forceinline operator long ( ) const { return 0; } __forceinline operator unsigned long ( ) const { return 0; } __forceinline operator int ( ) const { return 0; } __forceinline operator unsigned int ( ) const { return 0; } __forceinline operator short ( ) const { return 0; } __forceinline operator unsigned short ( ) const { return 0; } __forceinline operator char ( ) const { return 0; } __forceinline operator unsigned char ( ) const { return 0; } }; const constexpr ZeroTy zero = ZeroTy(); struct OneTy { __forceinline operator double ( ) const { return 1; } __forceinline operator float ( ) const { return 1; } __forceinline operator long long( ) const { return 1; } __forceinline operator unsigned long long( ) const { return 1; } __forceinline operator long ( ) const { return 1; } __forceinline operator unsigned long ( ) const { return 1; } __forceinline operator int ( ) const { return 1; } __forceinline operator unsigned int ( ) const { return 1; } __forceinline operator short ( ) const { return 1; } __forceinline operator unsigned short ( ) const { return 1; } __forceinline operator char ( ) const { return 1; } __forceinline operator unsigned char ( ) const { return 1; } }; const constexpr OneTy one = OneTy(); struct NegInfTy { __forceinline operator double ( ) const { return -std::numeric_limits::infinity(); } __forceinline operator float ( ) const { return -std::numeric_limits::infinity(); } __forceinline operator long long( ) const { return std::numeric_limits::min(); } __forceinline operator unsigned long long( ) const { return std::numeric_limits::min(); } __forceinline operator long ( ) const { return std::numeric_limits::min(); } __forceinline operator unsigned long ( ) const { return std::numeric_limits::min(); } __forceinline operator int ( ) const { return std::numeric_limits::min(); } __forceinline operator unsigned int ( ) const { return std::numeric_limits::min(); } __forceinline operator short ( ) const { return std::numeric_limits::min(); } __forceinline operator unsigned short ( ) const { return std::numeric_limits::min(); } __forceinline operator char ( ) const { return std::numeric_limits::min(); } __forceinline operator unsigned char ( ) const { return std::numeric_limits::min(); } }; const constexpr NegInfTy neg_inf = NegInfTy(); struct PosInfTy { __forceinline operator double ( ) const { return std::numeric_limits::infinity(); } __forceinline operator float ( ) const { return std::numeric_limits::infinity(); } __forceinline operator long long( ) const { return std::numeric_limits::max(); } __forceinline operator unsigned long long( ) const { return std::numeric_limits::max(); } __forceinline operator long ( ) const { return std::numeric_limits::max(); } __forceinline operator unsigned long ( ) const { return std::numeric_limits::max(); } __forceinline operator int ( ) const { return std::numeric_limits::max(); } __forceinline operator unsigned int ( ) const { return std::numeric_limits::max(); } __forceinline operator short ( ) const { return std::numeric_limits::max(); } __forceinline operator unsigned short ( ) const { return std::numeric_limits::max(); } __forceinline operator char ( ) const { return std::numeric_limits::max(); } __forceinline operator unsigned char ( ) const { return std::numeric_limits::max(); } }; const constexpr PosInfTy inf = PosInfTy(); const constexpr PosInfTy pos_inf = PosInfTy(); struct NaNTy { __forceinline operator double( ) const { return std::numeric_limits::quiet_NaN(); } __forceinline operator float ( ) const { return std::numeric_limits::quiet_NaN(); } }; const constexpr NaNTy nan = NaNTy(); struct UlpTy { __forceinline operator double( ) const { return std::numeric_limits::epsilon(); } __forceinline operator float ( ) const { return std::numeric_limits::epsilon(); } }; const constexpr UlpTy ulp = UlpTy(); struct PiTy { __forceinline operator double( ) const { return double(M_PI); } __forceinline operator float ( ) const { return float(M_PI); } }; const constexpr PiTy pi = PiTy(); struct OneOverPiTy { __forceinline operator double( ) const { return double(M_1_PI); } __forceinline operator float ( ) const { return float(M_1_PI); } }; const constexpr OneOverPiTy one_over_pi = OneOverPiTy(); struct TwoPiTy { __forceinline operator double( ) const { return double(2.0*M_PI); } __forceinline operator float ( ) const { return float(2.0*M_PI); } }; const constexpr TwoPiTy two_pi = TwoPiTy(); struct OneOverTwoPiTy { __forceinline operator double( ) const { return double(0.5*M_1_PI); } __forceinline operator float ( ) const { return float(0.5*M_1_PI); } }; const constexpr OneOverTwoPiTy one_over_two_pi = OneOverTwoPiTy(); struct FourPiTy { __forceinline operator double( ) const { return double(4.0*M_PI); } __forceinline operator float ( ) const { return float(4.0*M_PI); } }; const constexpr FourPiTy four_pi = FourPiTy(); struct OneOverFourPiTy { __forceinline operator double( ) const { return double(0.25*M_1_PI); } __forceinline operator float ( ) const { return float(0.25*M_1_PI); } }; const constexpr OneOverFourPiTy one_over_four_pi = OneOverFourPiTy(); struct StepTy { __forceinline operator double ( ) const { return 0; } __forceinline operator float ( ) const { return 0; } __forceinline operator long long( ) const { return 0; } __forceinline operator unsigned long long( ) const { return 0; } __forceinline operator long ( ) const { return 0; } __forceinline operator unsigned long ( ) const { return 0; } __forceinline operator int ( ) const { return 0; } __forceinline operator unsigned int ( ) const { return 0; } __forceinline operator short ( ) const { return 0; } __forceinline operator unsigned short ( ) const { return 0; } __forceinline operator char ( ) const { return 0; } __forceinline operator unsigned char ( ) const { return 0; } }; const constexpr StepTy step = StepTy(); struct ReverseStepTy { }; const constexpr ReverseStepTy reverse_step = ReverseStepTy(); struct EmptyTy { }; const constexpr EmptyTy empty = EmptyTy(); struct FullTy { }; const constexpr FullTy full = FullTy(); struct UndefinedTy { }; const constexpr UndefinedTy undefined = UndefinedTy(); } level-zero-raytracing-support-1.0.0/rtbuild/math/emath.h000066400000000000000000000453621450534701400233310ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "../sys/platform.h" #include "../sys/intrinsics.h" #include "constants.h" #include #if defined(EMBREE_SYCL_SUPPORT) && defined(__SYCL_DEVICE_ONLY__) # include "math_sycl.h" #else #if defined(__ARM_NEON) #include "../simd/arm/emulation.h" #else #include #include #include #endif #if defined(__WIN32__) #if defined(_MSC_VER) && (_MSC_VER <= 1700) namespace std { __forceinline bool isinf ( const float x ) { return _finite(x) == 0; } __forceinline bool isnan ( const float x ) { return _isnan(x) != 0; } __forceinline bool isfinite (const float x) { return _finite(x) != 0; } } #endif #endif namespace embree { __forceinline bool isvalid ( const float& v ) { return (v > -FLT_LARGE) & (v < +FLT_LARGE); } __forceinline int cast_f2i(float f) { union { float f; int i; } v; v.f = f; return v.i; } __forceinline float cast_i2f(int i) { union { float f; int i; } v; v.i = i; return v.f; } __forceinline int toInt (const float& a) { return int(a); } __forceinline float toFloat(const int& a) { return float(a); } #if defined(__WIN32__) __forceinline bool finite ( const float x ) { return _finite(x) != 0; } #endif __forceinline float sign ( const float x ) { return x<0?-1.0f:1.0f; } __forceinline float sqr ( const float x ) { return x*x; } __forceinline float rcp ( const float x ) { #if defined(__aarch64__) // Move scalar to vector register and do rcp. __m128 a; a[0] = x; float32x4_t reciprocal = vrecpeq_f32(a); reciprocal = vmulq_f32(vrecpsq_f32(a, reciprocal), reciprocal); reciprocal = vmulq_f32(vrecpsq_f32(a, reciprocal), reciprocal); return reciprocal[0]; #else const __m128 a = _mm_set_ss(x); #if defined(__AVX512VL__) const __m128 r = _mm_rcp14_ss(_mm_set_ss(0.0f),a); #else const __m128 r = _mm_rcp_ss(a); #endif #if defined(__AVX2__) return _mm_cvtss_f32(_mm_mul_ss(r,_mm_fnmadd_ss(r, a, _mm_set_ss(2.0f)))); #else return _mm_cvtss_f32(_mm_mul_ss(r,_mm_sub_ss(_mm_set_ss(2.0f), _mm_mul_ss(r, a)))); #endif #endif //defined(__aarch64__) } __forceinline float signmsk ( const float x ) { #if defined(__aarch64__) // FP and Neon shares same vector register in arm64 __m128 a; __m128i b; a[0] = x; b[0] = 0x80000000; a = _mm_and_ps(a, vreinterpretq_f32_s32(b)); return a[0]; #else return _mm_cvtss_f32(_mm_and_ps(_mm_set_ss(x),_mm_castsi128_ps(_mm_set1_epi32(0x80000000)))); #endif } __forceinline float xorf( const float x, const float y ) { #if defined(__aarch64__) // FP and Neon shares same vector register in arm64 __m128 a; __m128 b; a[0] = x; b[0] = y; a = _mm_xor_ps(a, b); return a[0]; #else return _mm_cvtss_f32(_mm_xor_ps(_mm_set_ss(x),_mm_set_ss(y))); #endif } __forceinline float andf( const float x, const unsigned y ) { #if defined(__aarch64__) // FP and Neon shares same vector register in arm64 __m128 a; __m128i b; a[0] = x; b[0] = y; a = _mm_and_ps(a, vreinterpretq_f32_s32(b)); return a[0]; #else return _mm_cvtss_f32(_mm_and_ps(_mm_set_ss(x),_mm_castsi128_ps(_mm_set1_epi32(y)))); #endif } __forceinline float rsqrt( const float x ) { #if defined(__aarch64__) // FP and Neon shares same vector register in arm64 __m128 a; a[0] = x; __m128 value = _mm_rsqrt_ps(a); value = vmulq_f32(value, vrsqrtsq_f32(vmulq_f32(a, value), value)); value = vmulq_f32(value, vrsqrtsq_f32(vmulq_f32(a, value), value)); return value[0]; #else const __m128 a = _mm_set_ss(x); #if defined(__AVX512VL__) __m128 r = _mm_rsqrt14_ss(_mm_set_ss(0.0f),a); #else __m128 r = _mm_rsqrt_ss(a); #endif const __m128 c = _mm_add_ss(_mm_mul_ss(_mm_set_ss(1.5f), r), _mm_mul_ss(_mm_mul_ss(_mm_mul_ss(a, _mm_set_ss(-0.5f)), r), _mm_mul_ss(r, r))); return _mm_cvtss_f32(c); #endif } #if defined(__WIN32__) && defined(_MSC_VER) && (_MSC_VER <= 1700) __forceinline float nextafter(float x, float y) { if ((x0)) return x*(1.1f+float(ulp)); else return x*(0.9f-float(ulp)); } __forceinline double nextafter(double x, double y) { return _nextafter(x, y); } __forceinline int roundf(float f) { return (int)(f + 0.5f); } #else __forceinline float nextafter(float x, float y) { return ::nextafterf(x, y); } __forceinline double nextafter(double x, double y) { return ::nextafter(x, y); } #endif __forceinline float abs ( const float x ) { return ::fabsf(x); } __forceinline float acos ( const float x ) { return ::acosf (x); } __forceinline float asin ( const float x ) { return ::asinf (x); } __forceinline float atan ( const float x ) { return ::atanf (x); } __forceinline float atan2( const float y, const float x ) { return ::atan2f(y, x); } __forceinline float cos ( const float x ) { return ::cosf (x); } __forceinline float cosh ( const float x ) { return ::coshf (x); } __forceinline float exp ( const float x ) { return ::expf (x); } __forceinline float fmod ( const float x, const float y ) { return ::fmodf (x, y); } __forceinline float log ( const float x ) { return ::logf (x); } __forceinline float log10( const float x ) { return ::log10f(x); } __forceinline float pow ( const float x, const float y ) { return ::powf (x, y); } __forceinline float sin ( const float x ) { return ::sinf (x); } __forceinline float sinh ( const float x ) { return ::sinhf (x); } __forceinline float sqrt ( const float x ) { return ::sqrtf (x); } __forceinline float tan ( const float x ) { return ::tanf (x); } __forceinline float tanh ( const float x ) { return ::tanhf (x); } __forceinline float floor( const float x ) { return ::floorf (x); } __forceinline float ceil ( const float x ) { return ::ceilf (x); } __forceinline float frac ( const float x ) { return x-floor(x); } __forceinline double abs ( const double x ) { return ::fabs(x); } __forceinline double sign ( const double x ) { return x<0?-1.0:1.0; } __forceinline double acos ( const double x ) { return ::acos (x); } __forceinline double asin ( const double x ) { return ::asin (x); } __forceinline double atan ( const double x ) { return ::atan (x); } __forceinline double atan2( const double y, const double x ) { return ::atan2(y, x); } __forceinline double cos ( const double x ) { return ::cos (x); } __forceinline double cosh ( const double x ) { return ::cosh (x); } __forceinline double exp ( const double x ) { return ::exp (x); } __forceinline double fmod ( const double x, const double y ) { return ::fmod (x, y); } __forceinline double log ( const double x ) { return ::log (x); } __forceinline double log10( const double x ) { return ::log10(x); } __forceinline double pow ( const double x, const double y ) { return ::pow (x, y); } __forceinline double rcp ( const double x ) { return 1.0/x; } __forceinline double rsqrt( const double x ) { return 1.0/::sqrt(x); } __forceinline double sin ( const double x ) { return ::sin (x); } __forceinline double sinh ( const double x ) { return ::sinh (x); } __forceinline double sqr ( const double x ) { return x*x; } __forceinline double sqrt ( const double x ) { return ::sqrt (x); } __forceinline double tan ( const double x ) { return ::tan (x); } __forceinline double tanh ( const double x ) { return ::tanh (x); } __forceinline double floor( const double x ) { return ::floor (x); } __forceinline double ceil ( const double x ) { return ::ceil (x); } #if defined(__aarch64__) __forceinline float mini(float a, float b) { // FP and Neon shares same vector register in arm64 __m128 x; __m128 y; x[0] = a; y[0] = b; x = _mm_min_ps(x, y); return x[0]; } #elif defined(__SSE4_1__) __forceinline float mini(float a, float b) { const __m128i ai = _mm_castps_si128(_mm_set_ss(a)); const __m128i bi = _mm_castps_si128(_mm_set_ss(b)); const __m128i ci = _mm_min_epi32(ai,bi); return _mm_cvtss_f32(_mm_castsi128_ps(ci)); } #endif #if defined(__aarch64__) __forceinline float maxi(float a, float b) { // FP and Neon shares same vector register in arm64 __m128 x; __m128 y; x[0] = a; y[0] = b; x = _mm_max_ps(x, y); return x[0]; } #elif defined(__SSE4_1__) __forceinline float maxi(float a, float b) { const __m128i ai = _mm_castps_si128(_mm_set_ss(a)); const __m128i bi = _mm_castps_si128(_mm_set_ss(b)); const __m128i ci = _mm_max_epi32(ai,bi); return _mm_cvtss_f32(_mm_castsi128_ps(ci)); } #endif template __forceinline T twice(const T& a) { return a+a; } __forceinline int min(int a, int b) { return a __forceinline T min(const T& a, const T& b, const T& c) { return min(min(a,b),c); } template __forceinline T min(const T& a, const T& b, const T& c, const T& d) { return min(min(a,b),min(c,d)); } template __forceinline T min(const T& a, const T& b, const T& c, const T& d, const T& e) { return min(min(min(a,b),min(c,d)),e); } template __forceinline T mini(const T& a, const T& b, const T& c) { return mini(mini(a,b),c); } template __forceinline T mini(const T& a, const T& b, const T& c, const T& d) { return mini(mini(a,b),mini(c,d)); } template __forceinline T mini(const T& a, const T& b, const T& c, const T& d, const T& e) { return mini(mini(mini(a,b),mini(c,d)),e); } __forceinline int max(int a, int b) { return a __forceinline T max(const T& a, const T& b, const T& c) { return max(max(a,b),c); } template __forceinline T max(const T& a, const T& b, const T& c, const T& d) { return max(max(a,b),max(c,d)); } template __forceinline T max(const T& a, const T& b, const T& c, const T& d, const T& e) { return max(max(max(a,b),max(c,d)),e); } template __forceinline T maxi(const T& a, const T& b, const T& c) { return maxi(maxi(a,b),c); } template __forceinline T maxi(const T& a, const T& b, const T& c, const T& d) { return maxi(maxi(a,b),maxi(c,d)); } template __forceinline T maxi(const T& a, const T& b, const T& c, const T& d, const T& e) { return maxi(maxi(maxi(a,b),maxi(c,d)),e); } #if defined(__MACOSX__) __forceinline ssize_t min(ssize_t a, ssize_t b) { return a __forceinline T clamp(const T& x, const T& lower = T(zero), const T& upper = T(one)) { return max(min(x,upper),lower); } template __forceinline T clampz(const T& x, const T& upper) { return max(T(zero), min(x,upper)); } template __forceinline T deg2rad ( const T& x ) { return x * T(1.74532925199432957692e-2f); } template __forceinline T rad2deg ( const T& x ) { return x * T(5.72957795130823208768e1f); } template __forceinline T sin2cos ( const T& x ) { return sqrt(max(T(zero),T(one)-x*x)); } template __forceinline T cos2sin ( const T& x ) { return sin2cos(x); } #if defined(__AVX2__) __forceinline float madd ( const float a, const float b, const float c) { return _mm_cvtss_f32(_mm_fmadd_ss(_mm_set_ss(a),_mm_set_ss(b),_mm_set_ss(c))); } __forceinline float msub ( const float a, const float b, const float c) { return _mm_cvtss_f32(_mm_fmsub_ss(_mm_set_ss(a),_mm_set_ss(b),_mm_set_ss(c))); } __forceinline float nmadd ( const float a, const float b, const float c) { return _mm_cvtss_f32(_mm_fnmadd_ss(_mm_set_ss(a),_mm_set_ss(b),_mm_set_ss(c))); } __forceinline float nmsub ( const float a, const float b, const float c) { return _mm_cvtss_f32(_mm_fnmsub_ss(_mm_set_ss(a),_mm_set_ss(b),_mm_set_ss(c))); } #elif defined (__aarch64__) && defined(__clang__) #pragma clang fp contract(fast) __forceinline float madd ( const float a, const float b, const float c) { return a*b + c; } __forceinline float msub ( const float a, const float b, const float c) { return a*b - c; } __forceinline float nmadd ( const float a, const float b, const float c) { return c - a*b; } __forceinline float nmsub ( const float a, const float b, const float c) { return -(c + a*b); } #pragma clang fp contract(on) #else __forceinline float madd ( const float a, const float b, const float c) { return a*b+c; } __forceinline float msub ( const float a, const float b, const float c) { return a*b-c; } __forceinline float nmadd ( const float a, const float b, const float c) { return -a*b+c;} __forceinline float nmsub ( const float a, const float b, const float c) { return -a*b-c; } #endif /*! random functions */ template T random() { return T(0); } #if defined(_WIN32) template<> __forceinline int random() { return int(rand()) ^ (int(rand()) << 8) ^ (int(rand()) << 16); } template<> __forceinline uint32_t random() { return uint32_t(rand()) ^ (uint32_t(rand()) << 8) ^ (uint32_t(rand()) << 16); } #else template<> __forceinline int random() { return int(rand()); } template<> __forceinline uint32_t random() { return uint32_t(rand()) ^ (uint32_t(rand()) << 16); } #endif template<> __forceinline float random() { return rand()/float(RAND_MAX); } template<> __forceinline double random() { return rand()/double(RAND_MAX); } #if _WIN32 __forceinline double drand48() { return double(rand())/double(RAND_MAX); } __forceinline void srand48(long seed) { return srand(seed); } #endif /*! selects */ __forceinline bool select(bool s, bool t , bool f) { return s ? t : f; } __forceinline int select(bool s, int t, int f) { return s ? t : f; } __forceinline float select(bool s, float t, float f) { return s ? t : f; } __forceinline bool none(bool s) { return !s; } __forceinline bool all (bool s) { return s; } __forceinline bool any (bool s) { return s; } __forceinline unsigned movemask (bool s) { return (unsigned)s; } __forceinline float lerp(const float v0, const float v1, const float t) { return madd(1.0f-t,v0,t*v1); } template __forceinline T lerp2(const float x0, const float x1, const float x2, const float x3, const T& u, const T& v) { return madd((1.0f-u),madd((1.0f-v),T(x0),v*T(x2)),u*madd((1.0f-v),T(x1),v*T(x3))); } /*! exchange */ template __forceinline void xchg ( T& a, T& b ) { const T tmp = a; a = b; b = tmp; } /* load/store */ template struct mem; template<> struct mem { static __forceinline float load (bool mask, const void* ptr) { return mask ? *(float*)ptr : 0.0f; } static __forceinline float loadu(bool mask, const void* ptr) { return mask ? *(float*)ptr : 0.0f; } static __forceinline void store (bool mask, void* ptr, const float v) { if (mask) *(float*)ptr = v; } static __forceinline void storeu(bool mask, void* ptr, const float v) { if (mask) *(float*)ptr = v; } }; /*! bit reverse operation */ template __forceinline T bitReverse(const T& vin) { T v = vin; v = ((v >> 1) & 0x55555555) | ((v & 0x55555555) << 1); v = ((v >> 2) & 0x33333333) | ((v & 0x33333333) << 2); v = ((v >> 4) & 0x0F0F0F0F) | ((v & 0x0F0F0F0F) << 4); v = ((v >> 8) & 0x00FF00FF) | ((v & 0x00FF00FF) << 8); v = ( v >> 16 ) | ( v << 16); return v; } /*! bit interleave operation */ template __forceinline T bitInterleave(const T& xin, const T& yin, const T& zin) { T x = xin, y = yin, z = zin; x = (x | (x << 16)) & 0x030000FF; x = (x | (x << 8)) & 0x0300F00F; x = (x | (x << 4)) & 0x030C30C3; x = (x | (x << 2)) & 0x09249249; y = (y | (y << 16)) & 0x030000FF; y = (y | (y << 8)) & 0x0300F00F; y = (y | (y << 4)) & 0x030C30C3; y = (y | (y << 2)) & 0x09249249; z = (z | (z << 16)) & 0x030000FF; z = (z | (z << 8)) & 0x0300F00F; z = (z | (z << 4)) & 0x030C30C3; z = (z | (z << 2)) & 0x09249249; return x | (y << 1) | (z << 2); } #if defined(__AVX2__) && !defined(__aarch64__) template<> __forceinline unsigned int bitInterleave(const unsigned int &xi, const unsigned int& yi, const unsigned int& zi) { const unsigned int xx = pdep(xi,0x49249249 /* 0b01001001001001001001001001001001 */ ); const unsigned int yy = pdep(yi,0x92492492 /* 0b10010010010010010010010010010010 */); const unsigned int zz = pdep(zi,0x24924924 /* 0b00100100100100100100100100100100 */); return xx | yy | zz; } #endif /*! bit interleave operation for 64bit data types*/ template __forceinline T bitInterleave64(const T& xin, const T& yin, const T& zin){ T x = xin & 0x1fffff; T y = yin & 0x1fffff; T z = zin & 0x1fffff; x = (x | x << 32) & 0x1f00000000ffff; x = (x | x << 16) & 0x1f0000ff0000ff; x = (x | x << 8) & 0x100f00f00f00f00f; x = (x | x << 4) & 0x10c30c30c30c30c3; x = (x | x << 2) & 0x1249249249249249; y = (y | y << 32) & 0x1f00000000ffff; y = (y | y << 16) & 0x1f0000ff0000ff; y = (y | y << 8) & 0x100f00f00f00f00f; y = (y | y << 4) & 0x10c30c30c30c30c3; y = (y | y << 2) & 0x1249249249249249; z = (z | z << 32) & 0x1f00000000ffff; z = (z | z << 16) & 0x1f0000ff0000ff; z = (z | z << 8) & 0x100f00f00f00f00f; z = (z | z << 4) & 0x10c30c30c30c30c3; z = (z | z << 2) & 0x1249249249249249; return x | (y << 1) | (z << 2); } } #endif level-zero-raytracing-support-1.0.0/rtbuild/math/linearspace3.h000066400000000000000000000250311450534701400245730ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "vec3.h" //#include "quaternion.h" namespace embree { //////////////////////////////////////////////////////////////////////////////// /// 3D Linear Transform (3x3 Matrix) //////////////////////////////////////////////////////////////////////////////// template struct LinearSpace3 { typedef T Vector; typedef typename T::Scalar Scalar; /*! default matrix constructor */ __forceinline LinearSpace3 ( ) {} __forceinline LinearSpace3 ( const LinearSpace3& other ) { vx = other.vx; vy = other.vy; vz = other.vz; } __forceinline LinearSpace3& operator=( const LinearSpace3& other ) { vx = other.vx; vy = other.vy; vz = other.vz; return *this; } template __forceinline LinearSpace3( const LinearSpace3& s ) : vx(s.vx), vy(s.vy), vz(s.vz) {} /*! matrix construction from column vectors */ __forceinline LinearSpace3(const Vector& vx, const Vector& vy, const Vector& vz) : vx(vx), vy(vy), vz(vz) {} /*! construction from quaternion */ /*__forceinline LinearSpace3( const QuaternionT& q ) : vx((q.r*q.r + q.i*q.i - q.j*q.j - q.k*q.k), 2.0f*(q.i*q.j + q.r*q.k), 2.0f*(q.i*q.k - q.r*q.j)) , vy(2.0f*(q.i*q.j - q.r*q.k), (q.r*q.r - q.i*q.i + q.j*q.j - q.k*q.k), 2.0f*(q.j*q.k + q.r*q.i)) , vz(2.0f*(q.i*q.k + q.r*q.j), 2.0f*(q.j*q.k - q.r*q.i), (q.r*q.r - q.i*q.i - q.j*q.j + q.k*q.k)) {}*/ /*! matrix construction from row mayor data */ __forceinline LinearSpace3(const Scalar& m00, const Scalar& m01, const Scalar& m02, const Scalar& m10, const Scalar& m11, const Scalar& m12, const Scalar& m20, const Scalar& m21, const Scalar& m22) : vx(m00,m10,m20), vy(m01,m11,m21), vz(m02,m12,m22) {} /*! compute the determinant of the matrix */ __forceinline const Scalar det() const { return dot(vx,cross(vy,vz)); } /*! compute adjoint matrix */ __forceinline const LinearSpace3 adjoint() const { return LinearSpace3(cross(vy,vz),cross(vz,vx),cross(vx,vy)).transposed(); } /*! compute inverse matrix */ __forceinline const LinearSpace3 inverse() const { return adjoint()/det(); } /*! compute transposed matrix */ __forceinline const LinearSpace3 transposed() const { return LinearSpace3(vx.x,vx.y,vx.z,vy.x,vy.y,vy.z,vz.x,vz.y,vz.z); } /*! returns first row of matrix */ __forceinline Vector row0() const { return Vector(vx.x,vy.x,vz.x); } /*! returns second row of matrix */ __forceinline Vector row1() const { return Vector(vx.y,vy.y,vz.y); } /*! returns third row of matrix */ __forceinline Vector row2() const { return Vector(vx.z,vy.z,vz.z); } //////////////////////////////////////////////////////////////////////////////// /// Constants //////////////////////////////////////////////////////////////////////////////// __forceinline LinearSpace3( ZeroTy ) : vx(zero), vy(zero), vz(zero) {} __forceinline LinearSpace3( OneTy ) : vx(one, zero, zero), vy(zero, one, zero), vz(zero, zero, one) {} /*! return matrix for scaling */ static __forceinline LinearSpace3 scale(const Vector& s) { return LinearSpace3(s.x, 0, 0, 0 , s.y, 0, 0 , 0, s.z); } /*! return matrix for rotation around arbitrary axis */ static __forceinline LinearSpace3 rotate(const Vector& _u, const Scalar& r) { Vector u = normalize(_u); Scalar s = sin(r), c = cos(r); return LinearSpace3(u.x*u.x+(1-u.x*u.x)*c, u.x*u.y*(1-c)-u.z*s, u.x*u.z*(1-c)+u.y*s, u.x*u.y*(1-c)+u.z*s, u.y*u.y+(1-u.y*u.y)*c, u.y*u.z*(1-c)-u.x*s, u.x*u.z*(1-c)-u.y*s, u.y*u.z*(1-c)+u.x*s, u.z*u.z+(1-u.z*u.z)*c); } public: /*! the column vectors of the matrix */ Vector vx,vy,vz; }; #if !defined(__SYCL_DEVICE_ONLY__) /*! compute transposed matrix */ template<> __forceinline const LinearSpace3 LinearSpace3::transposed() const { vfloat4 rx,ry,rz; transpose((vfloat4&)vx,(vfloat4&)vy,(vfloat4&)vz,vfloat4(zero),rx,ry,rz); return LinearSpace3(Vec3fa(rx),Vec3fa(ry),Vec3fa(rz)); } #endif template __forceinline const LinearSpace3 transposed(const LinearSpace3& xfm) { return xfm.transposed(); } //////////////////////////////////////////////////////////////////////////////// // Unary Operators //////////////////////////////////////////////////////////////////////////////// template __forceinline LinearSpace3 operator -( const LinearSpace3& a ) { return LinearSpace3(-a.vx,-a.vy,-a.vz); } template __forceinline LinearSpace3 operator +( const LinearSpace3& a ) { return LinearSpace3(+a.vx,+a.vy,+a.vz); } template __forceinline LinearSpace3 rcp ( const LinearSpace3& a ) { return a.inverse(); } /* constructs a coordinate frame form a normalized normal */ template __forceinline LinearSpace3 frame(const T& N) { const T dx0(0,N.z,-N.y); const T dx1(-N.z,0,N.x); const T dx = normalize(select(dot(dx0,dx0) > dot(dx1,dx1),dx0,dx1)); const T dy = normalize(cross(N,dx)); return LinearSpace3(dx,dy,N); } /* constructs a coordinate frame from a normal and approximate x-direction */ template __forceinline LinearSpace3 frame(const T& N, const T& dxi) { if (abs(dot(dxi,N)) > 0.99f) return frame(N); // fallback in case N and dxi are very parallel const T dx = normalize(cross(dxi,N)); const T dy = normalize(cross(N,dx)); return LinearSpace3(dx,dy,N); } /* clamps linear space to range -1 to +1 */ template __forceinline LinearSpace3 clamp(const LinearSpace3& space) { return LinearSpace3(clamp(space.vx,T(-1.0f),T(1.0f)), clamp(space.vy,T(-1.0f),T(1.0f)), clamp(space.vz,T(-1.0f),T(1.0f))); } //////////////////////////////////////////////////////////////////////////////// // Binary Operators //////////////////////////////////////////////////////////////////////////////// template __forceinline LinearSpace3 operator +( const LinearSpace3& a, const LinearSpace3& b ) { return LinearSpace3(a.vx+b.vx,a.vy+b.vy,a.vz+b.vz); } template __forceinline LinearSpace3 operator -( const LinearSpace3& a, const LinearSpace3& b ) { return LinearSpace3(a.vx-b.vx,a.vy-b.vy,a.vz-b.vz); } template __forceinline LinearSpace3 operator*(const typename T::Scalar & a, const LinearSpace3& b) { return LinearSpace3(a*b.vx, a*b.vy, a*b.vz); } template __forceinline T operator*(const LinearSpace3& a, const T & b) { return madd(T(b.x),a.vx,madd(T(b.y),a.vy,T(b.z)*a.vz)); } template __forceinline LinearSpace3 operator*(const LinearSpace3& a, const LinearSpace3& b) { return LinearSpace3(a*b.vx, a*b.vy, a*b.vz); } template __forceinline LinearSpace3 operator/(const LinearSpace3& a, const typename T::Scalar & b) { return LinearSpace3(a.vx/b, a.vy/b, a.vz/b); } template __forceinline LinearSpace3 operator/(const LinearSpace3& a, const LinearSpace3& b) { return a * rcp(b); } template __forceinline LinearSpace3& operator *=( LinearSpace3& a, const LinearSpace3& b ) { return a = a * b; } template __forceinline LinearSpace3& operator /=( LinearSpace3& a, const LinearSpace3& b ) { return a = a / b; } template __forceinline T xfmPoint (const LinearSpace3& s, const T & a) { return madd(T(a.x),s.vx,madd(T(a.y),s.vy,T(a.z)*s.vz)); } template __forceinline T xfmVector(const LinearSpace3& s, const T & a) { return madd(T(a.x),s.vx,madd(T(a.y),s.vy,T(a.z)*s.vz)); } template __forceinline T xfmNormal(const LinearSpace3& s, const T & a) { return xfmVector(s.inverse().transposed(),a); } //////////////////////////////////////////////////////////////////////////////// /// Comparison Operators //////////////////////////////////////////////////////////////////////////////// template __forceinline bool operator ==( const LinearSpace3& a, const LinearSpace3& b ) { return a.vx == b.vx && a.vy == b.vy && a.vz == b.vz; } template __forceinline bool operator !=( const LinearSpace3& a, const LinearSpace3& b ) { return a.vx != b.vx || a.vy != b.vy || a.vz != b.vz; } //////////////////////////////////////////////////////////////////////////////// /// Select //////////////////////////////////////////////////////////////////////////////// template __forceinline LinearSpace3 select ( const typename T::Scalar::Bool& s, const LinearSpace3& t, const LinearSpace3& f ) { return LinearSpace3(select(s,t.vx,f.vx),select(s,t.vy,f.vy),select(s,t.vz,f.vz)); } /*! blending */ template __forceinline LinearSpace3 lerp(const LinearSpace3& l0, const LinearSpace3& l1, const float t) { return LinearSpace3(lerp(l0.vx,l1.vx,t), lerp(l0.vy,l1.vy,t), lerp(l0.vz,l1.vz,t)); } //////////////////////////////////////////////////////////////////////////////// /// Output Operators //////////////////////////////////////////////////////////////////////////////// template static embree_ostream operator<<(embree_ostream cout, const LinearSpace3& m) { return cout << "{ vx = " << m.vx << ", vy = " << m.vy << ", vz = " << m.vz << "}"; } /*! Shortcuts for common linear spaces. */ typedef LinearSpace3 LinearSpace3f; typedef LinearSpace3 LinearSpace3fa; typedef LinearSpace3 LinearSpace3fx; typedef LinearSpace3 LinearSpace3ff; template using LinearSpace3vf = LinearSpace3>>; typedef LinearSpace3>> LinearSpace3vf4; typedef LinearSpace3>> LinearSpace3vf8; typedef LinearSpace3>> LinearSpace3vf16; /*! blending */ template __forceinline LinearSpace3 lerp(const LinearSpace3& l0, const LinearSpace3& l1, const S& t) { return LinearSpace3(lerp(l0.vx,l1.vx,t), lerp(l0.vy,l1.vy,t), lerp(l0.vz,l1.vz,t)); } } level-zero-raytracing-support-1.0.0/rtbuild/math/range.h000066400000000000000000000071161450534701400233220ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "../sys/platform.h" #include "../math/emath.h" namespace embree { template struct range { __forceinline range() {} __forceinline range(const Ty& begin) : _begin(begin), _end(begin+1) {} __forceinline range(const Ty& begin, const Ty& end) : _begin(begin), _end(end) {} __forceinline range(const range& other) : _begin(other._begin), _end(other._end) {} template __forceinline range(const range& other) : _begin(Ty(other._begin)), _end(Ty(other._end)) {} template __forceinline range& operator =(const range& other) { _begin = other._begin; _end = other._end; return *this; } __forceinline Ty begin() const { return _begin; } __forceinline Ty end() const { return _end; } __forceinline range intersect(const range& r) const { return range (max(_begin,r._begin),min(_end,r._end)); } __forceinline Ty size() const { return _end - _begin; } __forceinline bool empty() const { return _end <= _begin; } __forceinline Ty center() const { return (_begin + _end)/2; } __forceinline std::pair split() const { const Ty _center = center(); return std::make_pair(range(_begin,_center),range(_center,_end)); } __forceinline void split(range& left_o, range& right_o) const { const Ty _center = center(); left_o = range(_begin,_center); right_o = range(_center,_end); } __forceinline friend bool operator< (const range& r0, const range& r1) { return r0.size() < r1.size(); } friend embree_ostream operator<<(embree_ostream cout, const range& r) { return cout << "range [" << r.begin() << ", " << r.end() << "]"; } Ty _begin, _end; }; template range make_range(const Ty& begin, const Ty& end) { return range(begin,end); } template struct extended_range : public range { __forceinline extended_range () {} __forceinline extended_range (const Ty& begin) : range(begin), _ext_end(begin+1) {} __forceinline extended_range (const Ty& begin, const Ty& end) : range(begin,end), _ext_end(end) {} __forceinline extended_range (const Ty& begin, const Ty& end, const Ty& ext_end) : range(begin,end), _ext_end(ext_end) {} __forceinline Ty ext_end() const { return _ext_end; } __forceinline Ty ext_size() const { return _ext_end - range::_begin; } __forceinline Ty ext_range_size() const { return _ext_end - range::_end; } __forceinline bool has_ext_range() const { assert(_ext_end >= range::_end); return (_ext_end - range::_end) > 0; } __forceinline void set_ext_range(const size_t ext_end){ assert(ext_end >= range::_end); _ext_end = ext_end; } __forceinline void move_right(const size_t plus){ range::_begin += plus; range::_end += plus; _ext_end += plus; } friend embree_ostream operator<<(embree_ostream cout, const extended_range& r) { return cout << "extended_range [" << r.begin() << ", " << r.end() << " (" << r.ext_end() << ")]"; } Ty _ext_end; }; } level-zero-raytracing-support-1.0.0/rtbuild/math/vec2.h000066400000000000000000000305441450534701400230660ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "emath.h" namespace embree { //struct Vec2fa; //////////////////////////////////////////////////////////////////////////////// /// Generic 2D vector Class //////////////////////////////////////////////////////////////////////////////// template struct Vec2 { enum { N = 2 }; union { struct { T x, y; }; #if !(defined(__WIN32__) && _MSC_VER == 1800) // workaround for older VS 2013 compiler T components[N]; #endif }; typedef T Scalar; //////////////////////////////////////////////////////////////////////////////// /// Construction //////////////////////////////////////////////////////////////////////////////// __forceinline Vec2( ) {} __forceinline explicit Vec2( const T& a ) : x(a), y(a) {} __forceinline Vec2( const T& x, const T& y ) : x(x), y(y) {} __forceinline Vec2( const Vec2& other ) { x = other.x; y = other.y; } //Vec2( const Vec2fa& other ); template __forceinline Vec2( const Vec2& a ) : x(T(a.x)), y(T(a.y)) {} template __forceinline Vec2& operator =( const Vec2& other ) { x = other.x; y = other.y; return *this; } __forceinline Vec2& operator =( const Vec2& other ) { x = other.x; y = other.y; return *this; } //////////////////////////////////////////////////////////////////////////////// /// Constants //////////////////////////////////////////////////////////////////////////////// __forceinline Vec2( ZeroTy ) : x(zero), y(zero) {} __forceinline Vec2( OneTy ) : x(one), y(one) {} __forceinline Vec2( PosInfTy ) : x(pos_inf), y(pos_inf) {} __forceinline Vec2( NegInfTy ) : x(neg_inf), y(neg_inf) {} #if defined(__WIN32__) && _MSC_VER == 1800 // workaround for older VS 2013 compiler __forceinline const T& operator [](const size_t axis) const { assert(axis < 2); return (&x)[axis]; } __forceinline T& operator [](const size_t axis) { assert(axis < 2); return (&x)[axis]; } #else __forceinline const T& operator [](const size_t axis) const { assert(axis < 2); return components[axis]; } __forceinline T& operator [](const size_t axis ) { assert(axis < 2); return components[axis]; } #endif }; //////////////////////////////////////////////////////////////////////////////// /// Unary Operators //////////////////////////////////////////////////////////////////////////////// template __forceinline Vec2 operator +( const Vec2& a ) { return Vec2(+a.x, +a.y); } template __forceinline Vec2 operator -( const Vec2& a ) { return Vec2(-a.x, -a.y); } template __forceinline Vec2 abs ( const Vec2& a ) { return Vec2(abs (a.x), abs (a.y)); } template __forceinline Vec2 rcp ( const Vec2& a ) { return Vec2(rcp (a.x), rcp (a.y)); } template __forceinline Vec2 rsqrt ( const Vec2& a ) { return Vec2(rsqrt(a.x), rsqrt(a.y)); } template __forceinline Vec2 sqrt ( const Vec2& a ) { return Vec2(sqrt (a.x), sqrt (a.y)); } template __forceinline Vec2 frac ( const Vec2& a ) { return Vec2(frac (a.x), frac (a.y)); } //////////////////////////////////////////////////////////////////////////////// /// Binary Operators //////////////////////////////////////////////////////////////////////////////// template __forceinline Vec2 operator +( const Vec2& a, const Vec2& b ) { return Vec2(a.x + b.x, a.y + b.y); } template __forceinline Vec2 operator +( const Vec2& a, const T& b ) { return Vec2(a.x + b , a.y + b ); } template __forceinline Vec2 operator +( const T& a, const Vec2& b ) { return Vec2(a + b.x, a + b.y); } template __forceinline Vec2 operator -( const Vec2& a, const Vec2& b ) { return Vec2(a.x - b.x, a.y - b.y); } template __forceinline Vec2 operator -( const Vec2& a, const T& b ) { return Vec2(a.x - b , a.y - b ); } template __forceinline Vec2 operator -( const T& a, const Vec2& b ) { return Vec2(a - b.x, a - b.y); } template __forceinline Vec2 operator *( const Vec2& a, const Vec2& b ) { return Vec2(a.x * b.x, a.y * b.y); } template __forceinline Vec2 operator *( const T& a, const Vec2& b ) { return Vec2(a * b.x, a * b.y); } template __forceinline Vec2 operator *( const Vec2& a, const T& b ) { return Vec2(a.x * b , a.y * b ); } template __forceinline Vec2 operator /( const Vec2& a, const Vec2& b ) { return Vec2(a.x / b.x, a.y / b.y); } template __forceinline Vec2 operator /( const Vec2& a, const T& b ) { return Vec2(a.x / b , a.y / b ); } template __forceinline Vec2 operator /( const T& a, const Vec2& b ) { return Vec2(a / b.x, a / b.y); } template __forceinline Vec2 min(const Vec2& a, const Vec2& b) { return Vec2(min(a.x, b.x), min(a.y, b.y)); } template __forceinline Vec2 max(const Vec2& a, const Vec2& b) { return Vec2(max(a.x, b.x), max(a.y, b.y)); } //////////////////////////////////////////////////////////////////////////////// /// Ternary Operators //////////////////////////////////////////////////////////////////////////////// template __forceinline Vec2 madd ( const Vec2& a, const Vec2& b, const Vec2& c) { return Vec2( madd(a.x,b.x,c.x), madd(a.y,b.y,c.y) ); } template __forceinline Vec2 msub ( const Vec2& a, const Vec2& b, const Vec2& c) { return Vec2( msub(a.x,b.x,c.x), msub(a.y,b.y,c.y) ); } template __forceinline Vec2 nmadd ( const Vec2& a, const Vec2& b, const Vec2& c) { return Vec2(nmadd(a.x,b.x,c.x),nmadd(a.y,b.y,c.y) ); } template __forceinline Vec2 nmsub ( const Vec2& a, const Vec2& b, const Vec2& c) { return Vec2(nmsub(a.x,b.x,c.x),nmsub(a.y,b.y,c.y) ); } template __forceinline Vec2 madd ( const T& a, const Vec2& b, const Vec2& c) { return Vec2( madd(a,b.x,c.x), madd(a,b.y,c.y) ); } template __forceinline Vec2 msub ( const T& a, const Vec2& b, const Vec2& c) { return Vec2( msub(a,b.x,c.x), msub(a,b.y,c.y) ); } template __forceinline Vec2 nmadd ( const T& a, const Vec2& b, const Vec2& c) { return Vec2(nmadd(a,b.x,c.x),nmadd(a,b.y,c.y) ); } template __forceinline Vec2 nmsub ( const T& a, const Vec2& b, const Vec2& c) { return Vec2(nmsub(a,b.x,c.x),nmsub(a,b.y,c.y) ); } //////////////////////////////////////////////////////////////////////////////// /// Assignment Operators //////////////////////////////////////////////////////////////////////////////// template __forceinline Vec2& operator +=( Vec2& a, const Vec2& b ) { a.x += b.x; a.y += b.y; return a; } template __forceinline Vec2& operator -=( Vec2& a, const Vec2& b ) { a.x -= b.x; a.y -= b.y; return a; } template __forceinline Vec2& operator *=( Vec2& a, const T& b ) { a.x *= b ; a.y *= b ; return a; } template __forceinline Vec2& operator /=( Vec2& a, const T& b ) { a.x /= b ; a.y /= b ; return a; } //////////////////////////////////////////////////////////////////////////////// /// Reduction Operators //////////////////////////////////////////////////////////////////////////////// template __forceinline T reduce_add( const Vec2& a ) { return a.x + a.y; } template __forceinline T reduce_mul( const Vec2& a ) { return a.x * a.y; } template __forceinline T reduce_min( const Vec2& a ) { return min(a.x, a.y); } template __forceinline T reduce_max( const Vec2& a ) { return max(a.x, a.y); } //////////////////////////////////////////////////////////////////////////////// /// Comparison Operators //////////////////////////////////////////////////////////////////////////////// template __forceinline bool operator ==( const Vec2& a, const Vec2& b ) { return a.x == b.x && a.y == b.y; } template __forceinline bool operator !=( const Vec2& a, const Vec2& b ) { return a.x != b.x || a.y != b.y; } template __forceinline bool operator < ( const Vec2& a, const Vec2& b ) { if (a.x != b.x) return a.x < b.x; if (a.y != b.y) return a.y < b.y; return false; } //////////////////////////////////////////////////////////////////////////////// /// Shift Operators //////////////////////////////////////////////////////////////////////////////// template __forceinline Vec2 shift_right_1( const Vec2& a ) { return Vec2(shift_right_1(a.x),shift_right_1(a.y)); } //////////////////////////////////////////////////////////////////////////////// /// Euclidean Space Operators //////////////////////////////////////////////////////////////////////////////// template __forceinline T dot ( const Vec2& a, const Vec2& b ) { return madd(a.x,b.x,a.y*b.y); } template __forceinline Vec2 cross ( const Vec2& a ) { return Vec2(-a.y,a.x); } template __forceinline T length ( const Vec2& a ) { return sqrt(dot(a,a)); } template __forceinline Vec2 normalize( const Vec2& a ) { return a*rsqrt(dot(a,a)); } template __forceinline T distance ( const Vec2& a, const Vec2& b ) { return length(a-b); } template __forceinline T det ( const Vec2& a, const Vec2& b ) { return a.x*b.y - a.y*b.x; } template __forceinline Vec2 normalize_safe( const Vec2& a ) { const T d = dot(a,a); return select(d == T( zero ),a, a*rsqrt(d) ); } //////////////////////////////////////////////////////////////////////////////// /// Select //////////////////////////////////////////////////////////////////////////////// template __forceinline Vec2 select ( bool s, const Vec2& t, const Vec2& f ) { return Vec2(select(s,t.x,f.x),select(s,t.y,f.y)); } template __forceinline Vec2 select ( const Vec2& s, const Vec2& t, const Vec2& f ) { return Vec2(select(s.x,t.x,f.x),select(s.y,t.y,f.y)); } template __forceinline Vec2 select ( const typename T::Bool& s, const Vec2& t, const Vec2& f ) { return Vec2(select(s,t.x,f.x),select(s,t.y,f.y)); } template __forceinline Vec2 lerp(const Vec2& v0, const Vec2& v1, const T& t) { return madd(Vec2(T(1.0f)-t),v0,t*v1); } template __forceinline int maxDim ( const Vec2& a ) { const Vec2 b = abs(a); if (b.x > b.y) return 0; else return 1; } //////////////////////////////////////////////////////////////////////////////// /// Output Operators //////////////////////////////////////////////////////////////////////////////// template __forceinline embree_ostream operator<<(embree_ostream cout, const Vec2& a) { return cout << "(" << a.x << ", " << a.y << ")"; } //////////////////////////////////////////////////////////////////////////////// /// Default template instantiations //////////////////////////////////////////////////////////////////////////////// typedef Vec2 Vec2b; typedef Vec2 Vec2i; typedef Vec2 Vec2f; } //#include "vec2fa.h" #if defined(__SSE__) || defined(__ARM_NEON) #include "../simd/sse.h" #endif #if defined(__AVX__) #include "../simd/avx.h" #endif #if defined(__AVX512F__) #include "../simd/avx512.h" #endif /*namespace embree { template<> __forceinline Vec2::Vec2(const Vec2fa& a) : x(a.x), y(a.y) {} #if defined(__SSE__) || defined(__ARM_NEON) template<> __forceinline Vec2::Vec2(const Vec2fa& a) : x(a.x), y(a.y) {} #endif #if defined(__AVX__) template<> __forceinline Vec2::Vec2(const Vec2fa& a) : x(a.x), y(a.y) {} #endif #if defined(__AVX512F__) template<> __forceinline Vec2::Vec2(const Vec2fa& a) : x(a.x), y(a.y) {} #endif }*/ level-zero-raytracing-support-1.0.0/rtbuild/math/vec3.h000066400000000000000000000440401450534701400230630ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "emath.h" namespace embree { struct Vec3fa; //////////////////////////////////////////////////////////////////////////////// /// Generic 3D vector Class //////////////////////////////////////////////////////////////////////////////// template struct Vec3 { enum { N = 3 }; union { struct { T x, y, z; }; #if !(defined(__WIN32__) && _MSC_VER == 1800) // workaround for older VS 2013 compiler T components[N]; #endif }; typedef T Scalar; //////////////////////////////////////////////////////////////////////////////// /// Construction //////////////////////////////////////////////////////////////////////////////// __forceinline Vec3( ) {} __forceinline explicit Vec3( const T& a ) : x(a), y(a), z(a) {} __forceinline Vec3( const T& x, const T& y, const T& z ) : x(x), y(y), z(z) {} __forceinline Vec3( const Vec3& other ) { x = other.x; y = other.y; z = other.z; } __forceinline Vec3( const Vec3fa& other ); template __forceinline Vec3( const Vec3& a ) : x(T(a.x)), y(T(a.y)), z(T(a.z)) {} template __forceinline Vec3& operator =(const Vec3& other) { x = other.x; y = other.y; z = other.z; return *this; } __forceinline Vec3& operator =(const Vec3& other) { x = other.x; y = other.y; z = other.z; return *this; } //////////////////////////////////////////////////////////////////////////////// /// Constants //////////////////////////////////////////////////////////////////////////////// __forceinline Vec3( ZeroTy ) : x(zero), y(zero), z(zero) {} __forceinline Vec3( OneTy ) : x(one), y(one), z(one) {} __forceinline Vec3( PosInfTy ) : x(pos_inf), y(pos_inf), z(pos_inf) {} __forceinline Vec3( NegInfTy ) : x(neg_inf), y(neg_inf), z(neg_inf) {} #if defined(__WIN32__) && (_MSC_VER == 1800) // workaround for older VS 2013 compiler __forceinline const T& operator []( const size_t axis ) const { assert(axis < 3); return (&x)[axis]; } __forceinline T& operator []( const size_t axis ) { assert(axis < 3); return (&x)[axis]; } #else __forceinline const T& operator [](const size_t axis) const { assert(axis < 3); return components[axis]; } __forceinline T& operator [](const size_t axis) { assert(axis < 3); return components[axis]; } #endif }; //////////////////////////////////////////////////////////////////////////////// /// Unary Operators //////////////////////////////////////////////////////////////////////////////// template __forceinline Vec3 operator +( const Vec3& a ) { return Vec3(+a.x, +a.y, +a.z); } template __forceinline Vec3 operator -( const Vec3& a ) { return Vec3(-a.x, -a.y, -a.z); } template __forceinline Vec3 abs ( const Vec3& a ) { return Vec3(abs (a.x), abs (a.y), abs (a.z)); } template __forceinline Vec3 rcp ( const Vec3& a ) { return Vec3(rcp (a.x), rcp (a.y), rcp (a.z)); } template __forceinline Vec3 rsqrt ( const Vec3& a ) { return Vec3(rsqrt(a.x), rsqrt(a.y), rsqrt(a.z)); } template __forceinline Vec3 sqrt ( const Vec3& a ) { return Vec3(sqrt (a.x), sqrt (a.y), sqrt (a.z)); } template __forceinline Vec3 zero_fix( const Vec3& a ) { return Vec3(select(abs(a.x) __forceinline Vec3 rcp_safe(const Vec3& a) { return rcp(zero_fix(a)); } //////////////////////////////////////////////////////////////////////////////// /// Binary Operators //////////////////////////////////////////////////////////////////////////////// template __forceinline Vec3 operator +( const Vec3& a, const Vec3& b ) { return Vec3(a.x + b.x, a.y + b.y, a.z + b.z); } template __forceinline Vec3 operator -( const Vec3& a, const Vec3& b ) { return Vec3(a.x - b.x, a.y - b.y, a.z - b.z); } template __forceinline Vec3 operator *( const Vec3& a, const Vec3& b ) { return Vec3(a.x * b.x, a.y * b.y, a.z * b.z); } template __forceinline Vec3 operator *( const T& a, const Vec3& b ) { return Vec3(a * b.x, a * b.y, a * b.z); } template __forceinline Vec3 operator *( const Vec3& a, const T& b ) { return Vec3(a.x * b , a.y * b , a.z * b ); } template __forceinline Vec3 operator /( const Vec3& a, const T& b ) { return Vec3(a.x / b , a.y / b , a.z / b ); } template __forceinline Vec3 operator /( const T& a, const Vec3& b ) { return Vec3(a / b.x, a / b.y, a / b.z); } template __forceinline Vec3 operator /( const Vec3& a, const Vec3& b ) { return Vec3(a.x / b.x, a.y / b.y, a.z / b.z); } template __forceinline Vec3 min(const Vec3& a, const Vec3& b) { return Vec3(min(a.x, b.x), min(a.y, b.y), min(a.z, b.z)); } template __forceinline Vec3 max(const Vec3& a, const Vec3& b) { return Vec3(max(a.x, b.x), max(a.y, b.y), max(a.z, b.z)); } template __forceinline Vec3 operator >>( const Vec3& a, const int b ) { return Vec3(a.x >> b, a.y >> b, a.z >> b); } template __forceinline Vec3 operator <<( const Vec3& a, const int b ) { return Vec3(a.x << b, a.y << b, a.z << b); } //////////////////////////////////////////////////////////////////////////////// /// Ternary Operators //////////////////////////////////////////////////////////////////////////////// template __forceinline Vec3 madd ( const Vec3& a, const Vec3& b, const Vec3& c) { return Vec3( madd(a.x,b.x,c.x), madd(a.y,b.y,c.y), madd(a.z,b.z,c.z)); } template __forceinline Vec3 msub ( const Vec3& a, const Vec3& b, const Vec3& c) { return Vec3( msub(a.x,b.x,c.x), msub(a.y,b.y,c.y), msub(a.z,b.z,c.z)); } template __forceinline Vec3 nmadd ( const Vec3& a, const Vec3& b, const Vec3& c) { return Vec3(nmadd(a.x,b.x,c.x),nmadd(a.y,b.y,c.y),nmadd(a.z,b.z,c.z));} template __forceinline Vec3 nmsub ( const Vec3& a, const Vec3& b, const Vec3& c) { return Vec3(nmsub(a.x,b.x,c.x),nmsub(a.y,b.y,c.y),nmsub(a.z,b.z,c.z)); } template __forceinline Vec3 madd ( const T& a, const Vec3& b, const Vec3& c) { return Vec3( madd(a,b.x,c.x), madd(a,b.y,c.y), madd(a,b.z,c.z)); } template __forceinline Vec3 msub ( const T& a, const Vec3& b, const Vec3& c) { return Vec3( msub(a,b.x,c.x), msub(a,b.y,c.y), msub(a,b.z,c.z)); } template __forceinline Vec3 nmadd ( const T& a, const Vec3& b, const Vec3& c) { return Vec3(nmadd(a,b.x,c.x),nmadd(a,b.y,c.y),nmadd(a,b.z,c.z));} template __forceinline Vec3 nmsub ( const T& a, const Vec3& b, const Vec3& c) { return Vec3(nmsub(a,b.x,c.x),nmsub(a,b.y,c.y),nmsub(a,b.z,c.z)); } //////////////////////////////////////////////////////////////////////////////// /// Assignment Operators //////////////////////////////////////////////////////////////////////////////// template __forceinline Vec3& operator +=( Vec3& a, const T b ) { a.x += b; a.y += b; a.z += b; return a; } template __forceinline Vec3& operator +=( Vec3& a, const Vec3& b ) { a.x += b.x; a.y += b.y; a.z += b.z; return a; } template __forceinline Vec3& operator -=( Vec3& a, const Vec3& b ) { a.x -= b.x; a.y -= b.y; a.z -= b.z; return a; } template __forceinline Vec3& operator *=( Vec3& a, const T& b ) { a.x *= b ; a.y *= b ; a.z *= b ; return a; } template __forceinline Vec3& operator /=( Vec3& a, const T& b ) { a.x /= b ; a.y /= b ; a.z /= b ; return a; } //////////////////////////////////////////////////////////////////////////////// /// Reduction Operators //////////////////////////////////////////////////////////////////////////////// template __forceinline T reduce_add( const Vec3& a ) { return a.x + a.y + a.z; } template __forceinline T reduce_mul( const Vec3& a ) { return a.x * a.y * a.z; } template __forceinline T reduce_min( const Vec3& a ) { return min(a.x, a.y, a.z); } template __forceinline T reduce_max( const Vec3& a ) { return max(a.x, a.y, a.z); } //////////////////////////////////////////////////////////////////////////////// /// Comparison Operators //////////////////////////////////////////////////////////////////////////////// template __forceinline bool operator ==( const Vec3& a, const Vec3& b ) { return a.x == b.x && a.y == b.y && a.z == b.z; } template __forceinline bool operator !=( const Vec3& a, const Vec3& b ) { return a.x != b.x || a.y != b.y || a.z != b.z; } template __forceinline bool operator < ( const Vec3& a, const Vec3& b ) { if (a.x != b.x) return a.x < b.x; if (a.y != b.y) return a.y < b.y; if (a.z != b.z) return a.z < b.z; return false; } //////////////////////////////////////////////////////////////////////////////// /// Shift Operators //////////////////////////////////////////////////////////////////////////////// template __forceinline Vec3 shift_right_1( const Vec3& a ) { return Vec3(shift_right_1(a.x),shift_right_1(a.y),shift_right_1(a.z)); } //////////////////////////////////////////////////////////////////////////////// /// Select //////////////////////////////////////////////////////////////////////////////// template __forceinline Vec3 select ( bool s, const Vec3& t, const Vec3& f ) { return Vec3(select(s,t.x,f.x),select(s,t.y,f.y),select(s,t.z,f.z)); } template __forceinline Vec3 select ( const Vec3& s, const Vec3& t, const Vec3& f ) { return Vec3(select(s.x,t.x,f.x),select(s.y,t.y,f.y),select(s.z,t.z,f.z)); } template __forceinline Vec3 select ( const typename T::Bool& s, const Vec3& t, const Vec3& f ) { return Vec3(select(s,t.x,f.x),select(s,t.y,f.y),select(s,t.z,f.z)); } template __forceinline Vec3 lerp(const Vec3& v0, const Vec3& v1, const T& t) { return madd(Vec3(T(1.0f)-t),v0,t*v1); } template __forceinline int maxDim ( const Vec3& a ) { const Vec3 b = abs(a); if (b.x > b.y) { if (b.x > b.z) return 0; else return 2; } else { if (b.y > b.z) return 1; else return 2; } } //////////////////////////////////////////////////////////////////////////////// /// Comparison Operators //////////////////////////////////////////////////////////////////////////////// template __forceinline Vec3 eq_mask( const Vec3& a, const Vec3& b ) { return Vec3(a.x==b.x,a.y==b.y,a.z==b.z); } template __forceinline Vec3 neq_mask(const Vec3& a, const Vec3& b ) { return Vec3(a.x!=b.x,a.y!=b.y,a.z!=b.z); } template __forceinline Vec3 lt_mask( const Vec3& a, const Vec3& b ) { return Vec3(a.x< b.x,a.y< b.y,a.z< b.z); } template __forceinline Vec3 le_mask( const Vec3& a, const Vec3& b ) { return Vec3(a.x<=b.x,a.y<=b.y,a.z<=b.z); } template __forceinline Vec3 gt_mask( const Vec3& a, const Vec3& b ) { return Vec3(a.x> b.x,a.y> b.y,a.z> b.z); } template __forceinline Vec3 ge_mask( const Vec3& a, const Vec3& b ) { return Vec3(a.x>=b.x,a.y>=b.y,a.z>=b.z); } //////////////////////////////////////////////////////////////////////////////// /// Euclidean Space Operators //////////////////////////////////////////////////////////////////////////////// template __forceinline T sqr ( const Vec3& a ) { return dot(a,a); } template __forceinline T dot ( const Vec3& a, const Vec3& b ) { return madd(a.x,b.x,madd(a.y,b.y,a.z*b.z)); } template __forceinline T length ( const Vec3& a ) { return sqrt(sqr(a)); } template __forceinline T rcp_length( const Vec3& a ) { return rsqrt(sqr(a)); } template __forceinline Vec3 normalize( const Vec3& a ) { return a*rsqrt(sqr(a)); } template __forceinline T distance ( const Vec3& a, const Vec3& b ) { return length(a-b); } template __forceinline Vec3 cross ( const Vec3& a, const Vec3& b ) { return Vec3(msub(a.y,b.z,a.z*b.y), msub(a.z,b.x,a.x*b.z), msub(a.x,b.y,a.y*b.x)); } template __forceinline Vec3 stable_triangle_normal( const Vec3& a, const Vec3& b, const Vec3& c ) { const T ab_x = a.z*b.y, ab_y = a.x*b.z, ab_z = a.y*b.x; const T bc_x = b.z*c.y, bc_y = b.x*c.z, bc_z = b.y*c.x; const Vec3 cross_ab(msub(a.y,b.z,ab_x), msub(a.z,b.x,ab_y), msub(a.x,b.y,ab_z)); const Vec3 cross_bc(msub(b.y,c.z,bc_x), msub(b.z,c.x,bc_y), msub(b.x,c.y,bc_z)); const auto sx = abs(ab_x) < abs(bc_x); const auto sy = abs(ab_y) < abs(bc_y); const auto sz = abs(ab_z) < abs(bc_z); return Vec3(select(sx,cross_ab.x,cross_bc.x), select(sy,cross_ab.y,cross_bc.y), select(sz,cross_ab.z,cross_bc.z)); } template __forceinline T sum ( const Vec3& a ) { return a.x+a.y+a.z; } template __forceinline T halfArea ( const Vec3& d ) { return madd(d.x,(d.y+d.z),d.y*d.z); } template __forceinline T area ( const Vec3& d ) { return 2.0f*halfArea(d); } template __forceinline Vec3 normalize_safe( const Vec3& a ) { const T d = dot(a,a); return select(d == T( zero ), a , a*rsqrt(d) ); } template __forceinline T sqr_point_to_line_distance(const Vec3& P, const Vec3& Q0, const Vec3& Q1) { const Vec3 N = cross(P-Q0,Q1-Q0); const Vec3 D = Q1-Q0; return dot(N,N)*rcp(dot(D,D)); } template __forceinline T sqr_point_to_line_distance(const Vec3& PmQ0, const Vec3& Q1mQ0) { const Vec3 N = cross(PmQ0,Q1mQ0); const Vec3 D = Q1mQ0; return dot(N,N)*rcp(dot(D,D)); } //////////////////////////////////////////////////////////////////////////////// /// Output Operators //////////////////////////////////////////////////////////////////////////////// template __forceinline embree_ostream operator<<(embree_ostream cout, const Vec3& a) { return cout << "(" << a.x << ", " << a.y << ", " << a.z << ")"; } typedef Vec3 Vec3b; typedef Vec3 Vec3i; typedef Vec3 Vec3f; } #include "vec3ba.h" #include "vec3ia.h" #include "vec3fa.h" //////////////////////////////////////////////////////////////////////////////// /// SSE / AVX / MIC specializations //////////////////////////////////////////////////////////////////////////////// #if defined(__SSE__) || defined(__ARM_NEON) #include "../simd/sse.h" #endif #if defined(__AVX__) #include "../simd/avx.h" #endif #if defined(__AVX512F__) #include "../simd/avx512.h" #endif namespace embree { template __forceinline Vec3 broadcast(const Vec3& a, const size_t k) { return Vec3(Out(a.x[k]), Out(a.y[k]), Out(a.z[k])); } template<> __forceinline Vec3::Vec3(const Vec3fa& a) { x = a.x; y = a.y; z = a.z; } #if !defined(__SYCL_DEVICE_ONLY__) #if defined(__AVX__) template<> __forceinline Vec3::Vec3(const Vec3fa& a) { x = a.x; y = a.y; z = a.z; } #elif defined(__SSE__) || defined(__ARM_NEON) template<> __forceinline Vec3::Vec3(const Vec3fa& a) { const vfloat4 v = vfloat4(a.m128); x = shuffle<0,0,0,0>(v); y = shuffle<1,1,1,1>(v); z = shuffle<2,2,2,2>(v); } #endif #if defined(__SSE__) || defined(__ARM_NEON) template<> __forceinline Vec3 broadcast(const Vec3& a, const size_t k) { return Vec3(vfloat4::broadcast(&a.x[k]), vfloat4::broadcast(&a.y[k]), vfloat4::broadcast(&a.z[k])); } template __forceinline Vec3 shuffle(const Vec3& b) { return Vec3(shuffle(b.x), shuffle(b.y), shuffle(b.z)); } #endif #if defined(__AVX__) template<> __forceinline Vec3::Vec3(const Vec3fa& a) { x = a.x; y = a.y; z = a.z; } template<> __forceinline Vec3 broadcast(const Vec3& a, const size_t k) { return Vec3(vfloat8::broadcast(&a.x[k]), vfloat8::broadcast(&a.y[k]), vfloat8::broadcast(&a.z[k])); } template<> __forceinline Vec3 broadcast(const Vec3& a, const size_t k) { return Vec3(vfloat8::broadcast(&a.x[k]), vfloat8::broadcast(&a.y[k]), vfloat8::broadcast(&a.z[k])); } template __forceinline Vec3 shuffle(const Vec3& b) { return Vec3(shuffle(b.x), shuffle(b.y), shuffle(b.z)); } #endif #if defined(__AVX512F__) template<> __forceinline Vec3::Vec3(const Vec3fa& a) : x(a.x), y(a.y), z(a.z) {} #endif #else #if defined(__SSE__) template<> __forceinline Vec3::Vec3(const Vec3fa& a) { x = a.x; y = a.y; z = a.z; } #endif #if defined(__AVX__) template<> __forceinline Vec3::Vec3(const Vec3fa& a) { x = a.x; y = a.y; z = a.z; } #endif #if defined(__AVX512F__) template<> __forceinline Vec3::Vec3(const Vec3fa& a) { x = a.x; y = a.y; z = a.z; } #endif #endif } level-zero-raytracing-support-1.0.0/rtbuild/math/vec3ba.h000066400000000000000000000127561450534701400233770ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "../sys/alloc.h" #include "emath.h" #if defined(EMBREE_SYCL_SUPPORT) && defined(__SYCL_DEVICE_ONLY__) # include "vec3ba_sycl.h" #else #include "../simd/sse.h" namespace embree { //////////////////////////////////////////////////////////////////////////////// /// SSE Vec3ba Type //////////////////////////////////////////////////////////////////////////////// struct __aligned(16) Vec3ba { ALIGNED_STRUCT_(16); union { __m128 m128; struct { int x,y,z; }; }; typedef int Scalar; enum { N = 3 }; //////////////////////////////////////////////////////////////////////////////// /// Constructors, Assignment & Cast Operators //////////////////////////////////////////////////////////////////////////////// __forceinline Vec3ba( ) {} __forceinline Vec3ba( const __m128 input ) : m128(input) {} __forceinline Vec3ba( const Vec3ba& other ) : m128(other.m128) {} __forceinline Vec3ba& operator =(const Vec3ba& other) { m128 = other.m128; return *this; } __forceinline explicit Vec3ba( bool a ) : m128(mm_lookupmask_ps[(size_t(a) << 3) | (size_t(a) << 2) | (size_t(a) << 1) | size_t(a)]) {} __forceinline Vec3ba( bool a, bool b, bool c) : m128(mm_lookupmask_ps[(size_t(c) << 2) | (size_t(b) << 1) | size_t(a)]) {} __forceinline operator const __m128&() const { return m128; } __forceinline operator __m128&() { return m128; } //////////////////////////////////////////////////////////////////////////////// /// Constants //////////////////////////////////////////////////////////////////////////////// __forceinline Vec3ba( FalseTy ) : m128(_mm_setzero_ps()) {} __forceinline Vec3ba( TrueTy ) : m128(_mm_castsi128_ps(_mm_cmpeq_epi32(_mm_setzero_si128(), _mm_setzero_si128()))) {} //////////////////////////////////////////////////////////////////////////////// /// Array Access //////////////////////////////////////////////////////////////////////////////// __forceinline const int& operator []( const size_t index ) const { assert(index < 3); return (&x)[index]; } __forceinline int& operator []( const size_t index ) { assert(index < 3); return (&x)[index]; } }; //////////////////////////////////////////////////////////////////////////////// /// Unary Operators //////////////////////////////////////////////////////////////////////////////// __forceinline Vec3ba operator !( const Vec3ba& a ) { return _mm_xor_ps(a.m128, Vec3ba(embree::True)); } //////////////////////////////////////////////////////////////////////////////// /// Binary Operators //////////////////////////////////////////////////////////////////////////////// __forceinline Vec3ba operator &( const Vec3ba& a, const Vec3ba& b ) { return _mm_and_ps(a.m128, b.m128); } __forceinline Vec3ba operator |( const Vec3ba& a, const Vec3ba& b ) { return _mm_or_ps (a.m128, b.m128); } __forceinline Vec3ba operator ^( const Vec3ba& a, const Vec3ba& b ) { return _mm_xor_ps(a.m128, b.m128); } //////////////////////////////////////////////////////////////////////////////// /// Assignment Operators //////////////////////////////////////////////////////////////////////////////// __forceinline Vec3ba& operator &=( Vec3ba& a, const Vec3ba& b ) { return a = a & b; } __forceinline Vec3ba& operator |=( Vec3ba& a, const Vec3ba& b ) { return a = a | b; } __forceinline Vec3ba& operator ^=( Vec3ba& a, const Vec3ba& b ) { return a = a ^ b; } //////////////////////////////////////////////////////////////////////////////// /// Comparison Operators + Select //////////////////////////////////////////////////////////////////////////////// __forceinline bool operator ==( const Vec3ba& a, const Vec3ba& b ) { return (_mm_movemask_ps(_mm_castsi128_ps(_mm_cmpeq_epi32(_mm_castps_si128(a.m128), _mm_castps_si128(b.m128)))) & 7) == 7; } __forceinline bool operator !=( const Vec3ba& a, const Vec3ba& b ) { return (_mm_movemask_ps(_mm_castsi128_ps(_mm_cmpeq_epi32(_mm_castps_si128(a.m128), _mm_castps_si128(b.m128)))) & 7) != 7; } __forceinline bool operator < ( const Vec3ba& a, const Vec3ba& b ) { if (a.x != b.x) return a.x < b.x; if (a.y != b.y) return a.y < b.y; if (a.z != b.z) return a.z < b.z; return false; } //////////////////////////////////////////////////////////////////////////////// /// Reduction Operations //////////////////////////////////////////////////////////////////////////////// __forceinline bool reduce_and( const Vec3ba& a ) { return (_mm_movemask_ps(a) & 0x7) == 0x7; } __forceinline bool reduce_or ( const Vec3ba& a ) { return (_mm_movemask_ps(a) & 0x7) != 0x0; } __forceinline bool all ( const Vec3ba& b ) { return (_mm_movemask_ps(b) & 0x7) == 0x7; } __forceinline bool any ( const Vec3ba& b ) { return (_mm_movemask_ps(b) & 0x7) != 0x0; } __forceinline bool none ( const Vec3ba& b ) { return (_mm_movemask_ps(b) & 0x7) == 0x0; } __forceinline size_t movemask(const Vec3ba& a) { return _mm_movemask_ps(a) & 0x7; } //////////////////////////////////////////////////////////////////////////////// /// Output Operators //////////////////////////////////////////////////////////////////////////////// __forceinline embree_ostream operator<<(embree_ostream cout, const Vec3ba& a) { return cout << "(" << (a.x ? "1" : "0") << ", " << (a.y ? "1" : "0") << ", " << (a.z ? "1" : "0") << ")"; } } #endif level-zero-raytracing-support-1.0.0/rtbuild/math/vec3fa.h000066400000000000000000001063431450534701400233770ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "../sys/alloc.h" #include "emath.h" #if defined(EMBREE_SYCL_SUPPORT) && defined(__SYCL_DEVICE_ONLY__) # include "vec3fa_sycl.h" #else #include "../simd/sse.h" namespace embree { //////////////////////////////////////////////////////////////////////////////// /// SSE Vec3fa Type //////////////////////////////////////////////////////////////////////////////// struct __aligned(16) Vec3fa { ALIGNED_STRUCT_(16); typedef float Scalar; enum { N = 3 }; union { __m128 m128; struct { float x,y,z; }; }; //////////////////////////////////////////////////////////////////////////////// /// Constructors, Assignment & Cast Operators //////////////////////////////////////////////////////////////////////////////// __forceinline Vec3fa( ) {} __forceinline Vec3fa( const __m128 a ) : m128(a) {} __forceinline Vec3fa ( const Vec3& other ) { m128 = _mm_set_ps(0, other.z, other.y, other.x); } //__forceinline Vec3fa& operator =( const Vec3& other ) { m128 = _mm_set_ps(0, other.z, other.y, other.x); return *this; } __forceinline Vec3fa ( const Vec3fa& other ) { m128 = other.m128; } __forceinline Vec3fa& operator =( const Vec3fa& other ) { m128 = other.m128; return *this; } __forceinline explicit Vec3fa( const float a ) : m128(_mm_set1_ps(a)) {} __forceinline Vec3fa( const float x, const float y, const float z) : m128(_mm_set_ps(0, z, y, x)) {} __forceinline explicit Vec3fa( const __m128i a ) : m128(_mm_cvtepi32_ps(a)) {} __forceinline explicit operator const vfloat4() const { return vfloat4(m128); } __forceinline explicit operator const vint4() const { return vint4(_mm_cvtps_epi32(m128)); } //__forceinline explicit operator const Vec2fa() const { return Vec2fa(m128); } __forceinline explicit operator const Vec3ia() const { return Vec3ia(_mm_cvtps_epi32(m128)); } //__forceinline operator const __m128&() const { return m128; } //__forceinline operator __m128&() { return m128; } //////////////////////////////////////////////////////////////////////////////// /// Loads and Stores //////////////////////////////////////////////////////////////////////////////// static __forceinline Vec3fa load( const void* const a ) { #if defined(__aarch64__) __m128 t = _mm_load_ps((float*)a); t[3] = 0.0f; return Vec3fa(t); #else return Vec3fa(_mm_and_ps(_mm_load_ps((float*)a),_mm_castsi128_ps(_mm_set_epi32(0, -1, -1, -1)))); #endif } static __forceinline Vec3fa loadu( const void* const a ) { return Vec3fa(_mm_loadu_ps((float*)a)); } static __forceinline void storeu ( void* ptr, const Vec3fa& v ) { _mm_storeu_ps((float*)ptr,v.m128); } //////////////////////////////////////////////////////////////////////////////// /// Constants //////////////////////////////////////////////////////////////////////////////// __forceinline Vec3fa( ZeroTy ) : m128(_mm_setzero_ps()) {} __forceinline Vec3fa( OneTy ) : m128(_mm_set1_ps(1.0f)) {} __forceinline Vec3fa( PosInfTy ) : m128(_mm_set1_ps(pos_inf)) {} __forceinline Vec3fa( NegInfTy ) : m128(_mm_set1_ps(neg_inf)) {} //////////////////////////////////////////////////////////////////////////////// /// Array Access //////////////////////////////////////////////////////////////////////////////// __forceinline const float& operator []( const size_t index ) const { assert(index < 3); return (&x)[index]; } __forceinline float& operator []( const size_t index ) { assert(index < 3); return (&x)[index]; } }; //////////////////////////////////////////////////////////////////////////////// /// Unary Operators //////////////////////////////////////////////////////////////////////////////// __forceinline Vec3fa operator +( const Vec3fa& a ) { return a; } __forceinline Vec3fa operator -( const Vec3fa& a ) { #if defined(__aarch64__) return vnegq_f32(a.m128); #else const __m128 mask = _mm_castsi128_ps(_mm_set1_epi32(0x80000000)); return _mm_xor_ps(a.m128, mask); #endif } __forceinline Vec3fa abs ( const Vec3fa& a ) { #if defined(__aarch64__) return _mm_abs_ps(a.m128); #else const __m128 mask = _mm_castsi128_ps(_mm_set1_epi32(0x7fffffff)); return _mm_and_ps(a.m128, mask); #endif } __forceinline Vec3fa sign ( const Vec3fa& a ) { return blendv_ps(Vec3fa(one).m128, (-Vec3fa(one)).m128, _mm_cmplt_ps (a.m128,Vec3fa(zero).m128)); } __forceinline Vec3fa rcp ( const Vec3fa& a ) { #if defined(__aarch64__) return vdivq_f32(vdupq_n_f32(1.0f),a.m128); #else #if defined(__AVX512VL__) const Vec3fa r = _mm_rcp14_ps(a.m128); #else const Vec3fa r = _mm_rcp_ps(a.m128); #endif #if defined(__AVX2__) const Vec3fa h_n = _mm_fnmadd_ps(a.m128, r.m128, vfloat4(1.0)); // First, compute 1 - a * r (which will be very close to 0) const Vec3fa res = _mm_fmadd_ps(r.m128, h_n.m128, r.m128); // Then compute r + r * h_n #else const Vec3fa h_n = _mm_sub_ps(vfloat4(1.0f), _mm_mul_ps(a.m128, r.m128)); // First, compute 1 - a * r (which will be very close to 0) const Vec3fa res = _mm_add_ps(r.m128,_mm_mul_ps(r.m128, h_n.m128)); // Then compute r + r * h_n #endif return res; #endif //defined(__aarch64__) } __forceinline Vec3fa sqrt ( const Vec3fa& a ) { return _mm_sqrt_ps(a.m128); } __forceinline Vec3fa sqr ( const Vec3fa& a ) { return _mm_mul_ps(a.m128,a.m128); } __forceinline Vec3fa rsqrt( const Vec3fa& a ) { #if defined(__aarch64__) __m128 r = _mm_rsqrt_ps(a.m128); r = vmulq_f32(r, vrsqrtsq_f32(vmulq_f32(a.m128, r), r)); r = vmulq_f32(r, vrsqrtsq_f32(vmulq_f32(a.m128, r), r)); return r; #else #if defined(__AVX512VL__) __m128 r = _mm_rsqrt14_ps(a.m128); #else __m128 r = _mm_rsqrt_ps(a.m128); #endif return _mm_add_ps(_mm_mul_ps(_mm_set1_ps(1.5f),r), _mm_mul_ps(_mm_mul_ps(_mm_mul_ps(a.m128, _mm_set1_ps(-0.5f)), r), _mm_mul_ps(r, r))); #endif } __forceinline Vec3fa zero_fix(const Vec3fa& a) { return blendv_ps(a.m128, _mm_set1_ps(min_rcp_input), _mm_cmplt_ps (abs(a).m128, _mm_set1_ps(min_rcp_input))); } __forceinline Vec3fa rcp_safe(const Vec3fa& a) { return rcp(zero_fix(a)); } __forceinline Vec3fa log ( const Vec3fa& a ) { return Vec3fa(logf(a.x),logf(a.y),logf(a.z)); } __forceinline Vec3fa exp ( const Vec3fa& a ) { return Vec3fa(expf(a.x),expf(a.y),expf(a.z)); } //////////////////////////////////////////////////////////////////////////////// /// Binary Operators //////////////////////////////////////////////////////////////////////////////// __forceinline Vec3fa operator +( const Vec3fa& a, const Vec3fa& b ) { return _mm_add_ps(a.m128, b.m128); } __forceinline Vec3fa operator -( const Vec3fa& a, const Vec3fa& b ) { return _mm_sub_ps(a.m128, b.m128); } __forceinline Vec3fa operator *( const Vec3fa& a, const Vec3fa& b ) { return _mm_mul_ps(a.m128, b.m128); } __forceinline Vec3fa operator *( const Vec3fa& a, const float b ) { return a * Vec3fa(b); } __forceinline Vec3fa operator *( const float a, const Vec3fa& b ) { return Vec3fa(a) * b; } __forceinline Vec3fa operator /( const Vec3fa& a, const Vec3fa& b ) { return _mm_div_ps(a.m128,b.m128); } __forceinline Vec3fa operator /( const Vec3fa& a, const float b ) { return _mm_div_ps(a.m128,_mm_set1_ps(b)); } __forceinline Vec3fa operator /( const float a, const Vec3fa& b ) { return _mm_div_ps(_mm_set1_ps(a),b.m128); } __forceinline Vec3fa min( const Vec3fa& a, const Vec3fa& b ) { return _mm_min_ps(a.m128,b.m128); } __forceinline Vec3fa max( const Vec3fa& a, const Vec3fa& b ) { return _mm_max_ps(a.m128,b.m128); } #if defined(__aarch64__) || defined(__SSE4_1__) __forceinline Vec3fa mini(const Vec3fa& a, const Vec3fa& b) { const vint4 ai = _mm_castps_si128(a.m128); const vint4 bi = _mm_castps_si128(b.m128); const vint4 ci = _mm_min_epi32(ai,bi); return _mm_castsi128_ps(ci); } #endif #if defined(__aarch64__) || defined(__SSE4_1__) __forceinline Vec3fa maxi(const Vec3fa& a, const Vec3fa& b) { const vint4 ai = _mm_castps_si128(a.m128); const vint4 bi = _mm_castps_si128(b.m128); const vint4 ci = _mm_max_epi32(ai,bi); return _mm_castsi128_ps(ci); } #endif __forceinline Vec3fa pow ( const Vec3fa& a, const float& b ) { return Vec3fa(powf(a.x,b),powf(a.y,b),powf(a.z,b)); } //////////////////////////////////////////////////////////////////////////////// /// Ternary Operators //////////////////////////////////////////////////////////////////////////////// #if defined(__AVX2__) || defined(__ARM_NEON) __forceinline Vec3fa madd ( const Vec3fa& a, const Vec3fa& b, const Vec3fa& c) { return _mm_fmadd_ps(a.m128,b.m128,c.m128); } __forceinline Vec3fa msub ( const Vec3fa& a, const Vec3fa& b, const Vec3fa& c) { return _mm_fmsub_ps(a.m128,b.m128,c.m128); } __forceinline Vec3fa nmadd ( const Vec3fa& a, const Vec3fa& b, const Vec3fa& c) { return _mm_fnmadd_ps(a.m128,b.m128,c.m128); } __forceinline Vec3fa nmsub ( const Vec3fa& a, const Vec3fa& b, const Vec3fa& c) { return _mm_fnmsub_ps(a.m128,b.m128,c.m128); } #else __forceinline Vec3fa madd ( const Vec3fa& a, const Vec3fa& b, const Vec3fa& c) { return a*b+c; } __forceinline Vec3fa nmadd ( const Vec3fa& a, const Vec3fa& b, const Vec3fa& c) { return -a*b+c;} __forceinline Vec3fa nmsub ( const Vec3fa& a, const Vec3fa& b, const Vec3fa& c) { return -a*b-c; } __forceinline Vec3fa msub ( const Vec3fa& a, const Vec3fa& b, const Vec3fa& c) { return a*b-c; } #endif __forceinline Vec3fa madd ( const float a, const Vec3fa& b, const Vec3fa& c) { return madd(Vec3fa(a),b,c); } __forceinline Vec3fa msub ( const float a, const Vec3fa& b, const Vec3fa& c) { return msub(Vec3fa(a),b,c); } __forceinline Vec3fa nmadd ( const float a, const Vec3fa& b, const Vec3fa& c) { return nmadd(Vec3fa(a),b,c); } __forceinline Vec3fa nmsub ( const float a, const Vec3fa& b, const Vec3fa& c) { return nmsub(Vec3fa(a),b,c); } //////////////////////////////////////////////////////////////////////////////// /// Assignment Operators //////////////////////////////////////////////////////////////////////////////// __forceinline Vec3fa& operator +=( Vec3fa& a, const Vec3fa& b ) { return a = a + b; } __forceinline Vec3fa& operator -=( Vec3fa& a, const Vec3fa& b ) { return a = a - b; } __forceinline Vec3fa& operator *=( Vec3fa& a, const Vec3fa& b ) { return a = a * b; } __forceinline Vec3fa& operator *=( Vec3fa& a, const float b ) { return a = a * b; } __forceinline Vec3fa& operator /=( Vec3fa& a, const Vec3fa& b ) { return a = a / b; } __forceinline Vec3fa& operator /=( Vec3fa& a, const float b ) { return a = a / b; } //////////////////////////////////////////////////////////////////////////////// /// Reductions //////////////////////////////////////////////////////////////////////////////// #if defined(__aarch64__) __forceinline float reduce_add(const Vec3fa& v) { float32x4_t t = v.m128; t[3] = 0.0f; return vaddvq_f32(t); } __forceinline float reduce_mul(const Vec3fa& v) { return v.x*v.y*v.z; } __forceinline float reduce_min(const Vec3fa& v) { float32x4_t t = v.m128; t[3] = t[2]; return vminvq_f32(t); } __forceinline float reduce_max(const Vec3fa& v) { float32x4_t t = v.m128; t[3] = t[2]; return vmaxvq_f32(t); } #else __forceinline float reduce_add(const Vec3fa& v) { const vfloat4 a(v.m128); const vfloat4 b = shuffle<1>(a); const vfloat4 c = shuffle<2>(a); return _mm_cvtss_f32(a+b+c); } __forceinline float reduce_mul(const Vec3fa& v) { return v.x*v.y*v.z; } __forceinline float reduce_min(const Vec3fa& v) { return min(v.x,v.y,v.z); } __forceinline float reduce_max(const Vec3fa& v) { return max(v.x,v.y,v.z); } #endif //////////////////////////////////////////////////////////////////////////////// /// Comparison Operators //////////////////////////////////////////////////////////////////////////////// __forceinline bool operator ==( const Vec3fa& a, const Vec3fa& b ) { return (_mm_movemask_ps(_mm_cmpeq_ps (a.m128, b.m128)) & 7) == 7; } __forceinline bool operator !=( const Vec3fa& a, const Vec3fa& b ) { return (_mm_movemask_ps(_mm_cmpneq_ps(a.m128, b.m128)) & 7) != 0; } __forceinline Vec3ba eq_mask( const Vec3fa& a, const Vec3fa& b ) { return _mm_cmpeq_ps (a.m128, b.m128); } __forceinline Vec3ba neq_mask(const Vec3fa& a, const Vec3fa& b ) { return _mm_cmpneq_ps(a.m128, b.m128); } __forceinline Vec3ba lt_mask( const Vec3fa& a, const Vec3fa& b ) { return _mm_cmplt_ps (a.m128, b.m128); } __forceinline Vec3ba le_mask( const Vec3fa& a, const Vec3fa& b ) { return _mm_cmple_ps (a.m128, b.m128); } #if defined(__aarch64__) __forceinline Vec3ba gt_mask( const Vec3fa& a, const Vec3fa& b ) { return _mm_cmpgt_ps (a.m128, b.m128); } __forceinline Vec3ba ge_mask( const Vec3fa& a, const Vec3fa& b ) { return _mm_cmpge_ps (a.m128, b.m128); } #else __forceinline Vec3ba gt_mask(const Vec3fa& a, const Vec3fa& b) { return _mm_cmpnle_ps(a.m128, b.m128); } __forceinline Vec3ba ge_mask(const Vec3fa& a, const Vec3fa& b) { return _mm_cmpnlt_ps(a.m128, b.m128); } #endif __forceinline bool isvalid ( const Vec3fa& v ) { return all(gt_mask(v,Vec3fa(-FLT_LARGE)) & lt_mask(v,Vec3fa(+FLT_LARGE))); } __forceinline bool is_finite ( const Vec3fa& a ) { return all(ge_mask(a,Vec3fa(-FLT_MAX)) & le_mask(a,Vec3fa(+FLT_MAX))); } __forceinline bool isvalid4 ( const Vec3fa& v ) { return all((vfloat4(v.m128) > vfloat4(-FLT_LARGE)) & (vfloat4(v.m128) < vfloat4(+FLT_LARGE))); } __forceinline bool is_finite4 ( const Vec3fa& a ) { return all((vfloat4(a.m128) >= vfloat4(-FLT_MAX)) & (vfloat4(a.m128) <= vfloat4(+FLT_MAX))); } //////////////////////////////////////////////////////////////////////////////// /// Euclidean Space Operators //////////////////////////////////////////////////////////////////////////////// #if defined(__SSE4_1__) __forceinline float dot ( const Vec3fa& a, const Vec3fa& b ) { return _mm_cvtss_f32(_mm_dp_ps(a.m128,b.m128,0x7F)); } #else __forceinline float dot ( const Vec3fa& a, const Vec3fa& b ) { return reduce_add(a*b); } #endif __forceinline Vec3fa cross ( const Vec3fa& a, const Vec3fa& b ) { vfloat4 a0 = vfloat4(a.m128); vfloat4 b0 = shuffle<1,2,0,3>(vfloat4(b.m128)); vfloat4 a1 = shuffle<1,2,0,3>(vfloat4(a.m128)); vfloat4 b1 = vfloat4(b.m128); return Vec3fa(shuffle<1,2,0,3>(msub(a0,b0,a1*b1))); } __forceinline float sqr_length ( const Vec3fa& a ) { return dot(a,a); } __forceinline float rcp_length ( const Vec3fa& a ) { return rsqrt(dot(a,a)); } __forceinline float rcp_length2( const Vec3fa& a ) { return rcp(dot(a,a)); } __forceinline float length ( const Vec3fa& a ) { return sqrt(dot(a,a)); } __forceinline Vec3fa normalize( const Vec3fa& a ) { return a*rsqrt(dot(a,a)); } __forceinline float distance ( const Vec3fa& a, const Vec3fa& b ) { return length(a-b); } __forceinline float halfArea ( const Vec3fa& d ) { return madd(d.x,(d.y+d.z),d.y*d.z); } __forceinline float area ( const Vec3fa& d ) { return 2.0f*halfArea(d); } __forceinline Vec3fa normalize_safe( const Vec3fa& a ) { const float d = dot(a,a); if (unlikely(d == 0.0f)) return a; else return a*rsqrt(d); } /*! differentiated normalization */ __forceinline Vec3fa dnormalize(const Vec3fa& p, const Vec3fa& dp) { const float pp = dot(p,p); const float pdp = dot(p,dp); return (pp*dp-pdp*p)*rcp(pp)*rsqrt(pp); } //////////////////////////////////////////////////////////////////////////////// /// Select //////////////////////////////////////////////////////////////////////////////// __forceinline Vec3fa select( bool s, const Vec3fa& t, const Vec3fa& f ) { __m128 mask = s ? _mm_castsi128_ps(_mm_cmpeq_epi32(_mm_setzero_si128(), _mm_setzero_si128())) : _mm_setzero_ps(); return blendv_ps(f.m128, t.m128, mask); } __forceinline Vec3fa select( const Vec3ba& s, const Vec3fa& t, const Vec3fa& f ) { return blendv_ps(f.m128, t.m128, s); } __forceinline Vec3fa lerp(const Vec3fa& v0, const Vec3fa& v1, const float t) { return madd(1.0f-t,v0,t*v1); } __forceinline int maxDim ( const Vec3fa& a ) { const Vec3fa b = abs(a); if (b.x > b.y) { if (b.x > b.z) return 0; else return 2; } else { if (b.y > b.z) return 1; else return 2; } } //////////////////////////////////////////////////////////////////////////////// /// Rounding Functions //////////////////////////////////////////////////////////////////////////////// #if defined(__aarch64__) __forceinline Vec3fa floor(const Vec3fa& a) { return vrndmq_f32(a.m128); } __forceinline Vec3fa ceil (const Vec3fa& a) { return vrndpq_f32(a.m128); } __forceinline Vec3fa trunc(const Vec3fa& a) { return vrndq_f32(a.m128); } #elif defined (__SSE4_1__) __forceinline Vec3fa trunc( const Vec3fa& a ) { return _mm_round_ps(a.m128, _MM_FROUND_TO_NEAREST_INT); } __forceinline Vec3fa floor( const Vec3fa& a ) { return _mm_round_ps(a.m128, _MM_FROUND_TO_NEG_INF ); } __forceinline Vec3fa ceil ( const Vec3fa& a ) { return _mm_round_ps(a.m128, _MM_FROUND_TO_POS_INF ); } #else __forceinline Vec3fa trunc( const Vec3fa& a ) { return Vec3fa(truncf(a.x),truncf(a.y),truncf(a.z)); } __forceinline Vec3fa floor( const Vec3fa& a ) { return Vec3fa(floorf(a.x),floorf(a.y),floorf(a.z)); } __forceinline Vec3fa ceil ( const Vec3fa& a ) { return Vec3fa(ceilf (a.x),ceilf (a.y),ceilf (a.z)); } #endif //////////////////////////////////////////////////////////////////////////////// /// Output Operators //////////////////////////////////////////////////////////////////////////////// __forceinline embree_ostream operator<<(embree_ostream cout, const Vec3fa& a) { return cout << "(" << a.x << ", " << a.y << ", " << a.z << ")"; } typedef Vec3fa Vec3fa_t; //////////////////////////////////////////////////////////////////////////////// /// SSE Vec3fx Type //////////////////////////////////////////////////////////////////////////////// struct __aligned(16) Vec3fx { ALIGNED_STRUCT_(16); typedef float Scalar; enum { N = 3 }; union { __m128 m128; struct { float x,y,z; union { int a; unsigned u; float w; }; }; }; //////////////////////////////////////////////////////////////////////////////// /// Constructors, Assignment & Cast Operators //////////////////////////////////////////////////////////////////////////////// __forceinline Vec3fx( ) {} __forceinline Vec3fx( const __m128 a ) : m128(a) {} __forceinline explicit Vec3fx(const Vec3fa& v) : m128(v.m128) {} __forceinline operator Vec3fa () const { return Vec3fa(m128); } __forceinline explicit Vec3fx ( const Vec3& other ) { m128 = _mm_set_ps(0, other.z, other.y, other.x); } //__forceinline Vec3fx& operator =( const Vec3& other ) { m128 = _mm_set_ps(0, other.z, other.y, other.x); return *this; } __forceinline Vec3fx ( const Vec3fx& other ) { m128 = other.m128; } __forceinline Vec3fx& operator =( const Vec3fx& other ) { m128 = other.m128; return *this; } __forceinline explicit Vec3fx( const float a ) : m128(_mm_set1_ps(a)) {} __forceinline Vec3fx( const float x, const float y, const float z) : m128(_mm_set_ps(0, z, y, x)) {} __forceinline Vec3fx( const Vec3fa& other, const int a1) { m128 = other.m128; a = a1; } __forceinline Vec3fx( const Vec3fa& other, const unsigned a1) { m128 = other.m128; u = a1; } __forceinline Vec3fx( const Vec3fa& other, const float w1) { #if defined (__aarch64__) m128 = other.m128; m128[3] = w1; #elif defined (__SSE4_1__) m128 = _mm_insert_ps(other.m128, _mm_set_ss(w1),3 << 4); #else const vint4 mask(-1,-1,-1,0); m128 = select(vboolf4(_mm_castsi128_ps(mask)),vfloat4(other.m128),vfloat4(w1)); #endif } //__forceinline Vec3fx( const float x, const float y, const float z, const int a) : x(x), y(y), z(z), a(a) {} // not working properly! //__forceinline Vec3fx( const float x, const float y, const float z, const unsigned a) : x(x), y(y), z(z), u(a) {} // not working properly! __forceinline Vec3fx( const float x, const float y, const float z, const float w) : m128(_mm_set_ps(w, z, y, x)) {} //__forceinline explicit Vec3fx( const __m128i a ) : m128(_mm_cvtepi32_ps(a)) {} __forceinline explicit operator const vfloat4() const { return vfloat4(m128); } __forceinline explicit operator const vint4() const { return vint4(_mm_cvtps_epi32(m128)); } //__forceinline explicit operator const Vec2fa() const { return Vec2fa(m128); } __forceinline explicit operator const Vec3ia() const { return Vec3ia(_mm_cvtps_epi32(m128)); } //__forceinline operator const __m128&() const { return m128; } //__forceinline operator __m128&() { return m128; } //////////////////////////////////////////////////////////////////////////////// /// Loads and Stores //////////////////////////////////////////////////////////////////////////////// static __forceinline Vec3fx load( const void* const a ) { return Vec3fx(_mm_and_ps(_mm_load_ps((float*)a),_mm_castsi128_ps(_mm_set_epi32(0, -1, -1, -1)))); } static __forceinline Vec3fx loadu( const void* const a ) { return Vec3fx(_mm_loadu_ps((float*)a)); } static __forceinline void storeu ( void* ptr, const Vec3fx& v ) { _mm_storeu_ps((float*)ptr,v.m128); } //////////////////////////////////////////////////////////////////////////////// /// Constants //////////////////////////////////////////////////////////////////////////////// __forceinline Vec3fx( ZeroTy ) : m128(_mm_setzero_ps()) {} __forceinline Vec3fx( OneTy ) : m128(_mm_set1_ps(1.0f)) {} __forceinline Vec3fx( PosInfTy ) : m128(_mm_set1_ps(pos_inf)) {} __forceinline Vec3fx( NegInfTy ) : m128(_mm_set1_ps(neg_inf)) {} //////////////////////////////////////////////////////////////////////////////// /// Array Access //////////////////////////////////////////////////////////////////////////////// __forceinline const float& operator []( const size_t index ) const { assert(index < 3); return (&x)[index]; } __forceinline float& operator []( const size_t index ) { assert(index < 3); return (&x)[index]; } }; //////////////////////////////////////////////////////////////////////////////// /// Unary Operators //////////////////////////////////////////////////////////////////////////////// __forceinline Vec3fx operator +( const Vec3fx& a ) { return a; } __forceinline Vec3fx operator -( const Vec3fx& a ) { const __m128 mask = _mm_castsi128_ps(_mm_set1_epi32(0x80000000)); return _mm_xor_ps(a.m128, mask); } __forceinline Vec3fx abs ( const Vec3fx& a ) { const __m128 mask = _mm_castsi128_ps(_mm_set1_epi32(0x7fffffff)); return _mm_and_ps(a.m128, mask); } __forceinline Vec3fx sign ( const Vec3fx& a ) { return blendv_ps(Vec3fx(one).m128, (-Vec3fx(one)).m128, _mm_cmplt_ps (a.m128,Vec3fx(zero).m128)); } __forceinline Vec3fx rcp ( const Vec3fx& a ) { #if defined(__AVX512VL__) const Vec3fx r = _mm_rcp14_ps(a.m128); #else const Vec3fx r = _mm_rcp_ps(a.m128); #endif #if defined(__AVX2__) const Vec3fx res = _mm_mul_ps(r.m128,_mm_fnmadd_ps(r.m128, a.m128, vfloat4(2.0f))); #else const Vec3fx res = _mm_mul_ps(r.m128,_mm_sub_ps(vfloat4(2.0f), _mm_mul_ps(r.m128, a.m128))); //return _mm_sub_ps(_mm_add_ps(r, r), _mm_mul_ps(_mm_mul_ps(r, r), a)); #endif return res; } __forceinline Vec3fx sqrt ( const Vec3fx& a ) { return _mm_sqrt_ps(a.m128); } __forceinline Vec3fx sqr ( const Vec3fx& a ) { return _mm_mul_ps(a.m128,a.m128); } __forceinline Vec3fx rsqrt( const Vec3fx& a ) { #if defined(__AVX512VL__) __m128 r = _mm_rsqrt14_ps(a.m128); #else __m128 r = _mm_rsqrt_ps(a.m128); #endif return _mm_add_ps(_mm_mul_ps(_mm_set1_ps(1.5f),r), _mm_mul_ps(_mm_mul_ps(_mm_mul_ps(a.m128, _mm_set1_ps(-0.5f)), r), _mm_mul_ps(r, r))); } __forceinline Vec3fx zero_fix(const Vec3fx& a) { return blendv_ps(a.m128, _mm_set1_ps(min_rcp_input), _mm_cmplt_ps (abs(a).m128, _mm_set1_ps(min_rcp_input))); } __forceinline Vec3fx rcp_safe(const Vec3fx& a) { return rcp(zero_fix(a)); } __forceinline Vec3fx log ( const Vec3fx& a ) { return Vec3fx(logf(a.x),logf(a.y),logf(a.z)); } __forceinline Vec3fx exp ( const Vec3fx& a ) { return Vec3fx(expf(a.x),expf(a.y),expf(a.z)); } //////////////////////////////////////////////////////////////////////////////// /// Binary Operators //////////////////////////////////////////////////////////////////////////////// __forceinline Vec3fx operator +( const Vec3fx& a, const Vec3fx& b ) { return _mm_add_ps(a.m128, b.m128); } __forceinline Vec3fx operator -( const Vec3fx& a, const Vec3fx& b ) { return _mm_sub_ps(a.m128, b.m128); } __forceinline Vec3fx operator *( const Vec3fx& a, const Vec3fx& b ) { return _mm_mul_ps(a.m128, b.m128); } __forceinline Vec3fx operator *( const Vec3fx& a, const float b ) { return a * Vec3fx(b); } __forceinline Vec3fx operator *( const float a, const Vec3fx& b ) { return Vec3fx(a) * b; } __forceinline Vec3fx operator /( const Vec3fx& a, const Vec3fx& b ) { return _mm_div_ps(a.m128,b.m128); } __forceinline Vec3fx operator /( const Vec3fx& a, const float b ) { return _mm_div_ps(a.m128,_mm_set1_ps(b)); } __forceinline Vec3fx operator /( const float a, const Vec3fx& b ) { return _mm_div_ps(_mm_set1_ps(a),b.m128); } __forceinline Vec3fx min( const Vec3fx& a, const Vec3fx& b ) { return _mm_min_ps(a.m128,b.m128); } __forceinline Vec3fx max( const Vec3fx& a, const Vec3fx& b ) { return _mm_max_ps(a.m128,b.m128); } #if defined(__SSE4_1__) || defined(__aarch64__) __forceinline Vec3fx mini(const Vec3fx& a, const Vec3fx& b) { const vint4 ai = _mm_castps_si128(a.m128); const vint4 bi = _mm_castps_si128(b.m128); const vint4 ci = _mm_min_epi32(ai,bi); return _mm_castsi128_ps(ci); } #endif #if defined(__SSE4_1__) || defined(__aarch64__) __forceinline Vec3fx maxi(const Vec3fx& a, const Vec3fx& b) { const vint4 ai = _mm_castps_si128(a.m128); const vint4 bi = _mm_castps_si128(b.m128); const vint4 ci = _mm_max_epi32(ai,bi); return _mm_castsi128_ps(ci); } #endif __forceinline Vec3fx pow ( const Vec3fx& a, const float& b ) { return Vec3fx(powf(a.x,b),powf(a.y,b),powf(a.z,b)); } //////////////////////////////////////////////////////////////////////////////// /// Ternary Operators //////////////////////////////////////////////////////////////////////////////// #if defined(__AVX2__) __forceinline Vec3fx madd ( const Vec3fx& a, const Vec3fx& b, const Vec3fx& c) { return _mm_fmadd_ps(a.m128,b.m128,c.m128); } __forceinline Vec3fx msub ( const Vec3fx& a, const Vec3fx& b, const Vec3fx& c) { return _mm_fmsub_ps(a.m128,b.m128,c.m128); } __forceinline Vec3fx nmadd ( const Vec3fx& a, const Vec3fx& b, const Vec3fx& c) { return _mm_fnmadd_ps(a.m128,b.m128,c.m128); } __forceinline Vec3fx nmsub ( const Vec3fx& a, const Vec3fx& b, const Vec3fx& c) { return _mm_fnmsub_ps(a.m128,b.m128,c.m128); } #else __forceinline Vec3fx madd ( const Vec3fx& a, const Vec3fx& b, const Vec3fx& c) { return a*b+c; } __forceinline Vec3fx msub ( const Vec3fx& a, const Vec3fx& b, const Vec3fx& c) { return a*b-c; } __forceinline Vec3fx nmadd ( const Vec3fx& a, const Vec3fx& b, const Vec3fx& c) { return -a*b+c;} __forceinline Vec3fx nmsub ( const Vec3fx& a, const Vec3fx& b, const Vec3fx& c) { return -a*b-c; } #endif __forceinline Vec3fx madd ( const float a, const Vec3fx& b, const Vec3fx& c) { return madd(Vec3fx(a),b,c); } __forceinline Vec3fx msub ( const float a, const Vec3fx& b, const Vec3fx& c) { return msub(Vec3fx(a),b,c); } __forceinline Vec3fx nmadd ( const float a, const Vec3fx& b, const Vec3fx& c) { return nmadd(Vec3fx(a),b,c); } __forceinline Vec3fx nmsub ( const float a, const Vec3fx& b, const Vec3fx& c) { return nmsub(Vec3fx(a),b,c); } //////////////////////////////////////////////////////////////////////////////// /// Assignment Operators //////////////////////////////////////////////////////////////////////////////// __forceinline Vec3fx& operator +=( Vec3fx& a, const Vec3fx& b ) { return a = a + b; } __forceinline Vec3fx& operator -=( Vec3fx& a, const Vec3fx& b ) { return a = a - b; } __forceinline Vec3fx& operator *=( Vec3fx& a, const Vec3fx& b ) { return a = a * b; } __forceinline Vec3fx& operator *=( Vec3fx& a, const float b ) { return a = a * b; } __forceinline Vec3fx& operator /=( Vec3fx& a, const Vec3fx& b ) { return a = a / b; } __forceinline Vec3fx& operator /=( Vec3fx& a, const float b ) { return a = a / b; } //////////////////////////////////////////////////////////////////////////////// /// Reductions //////////////////////////////////////////////////////////////////////////////// __forceinline float reduce_add(const Vec3fx& v) { const vfloat4 a(v.m128); const vfloat4 b = shuffle<1>(a); const vfloat4 c = shuffle<2>(a); return _mm_cvtss_f32(a+b+c); } __forceinline float reduce_mul(const Vec3fx& v) { return v.x*v.y*v.z; } __forceinline float reduce_min(const Vec3fx& v) { return min(v.x,v.y,v.z); } __forceinline float reduce_max(const Vec3fx& v) { return max(v.x,v.y,v.z); } //////////////////////////////////////////////////////////////////////////////// /// Comparison Operators //////////////////////////////////////////////////////////////////////////////// __forceinline bool operator ==( const Vec3fx& a, const Vec3fx& b ) { return (_mm_movemask_ps(_mm_cmpeq_ps (a.m128, b.m128)) & 7) == 7; } __forceinline bool operator !=( const Vec3fx& a, const Vec3fx& b ) { return (_mm_movemask_ps(_mm_cmpneq_ps(a.m128, b.m128)) & 7) != 0; } __forceinline Vec3ba eq_mask( const Vec3fx& a, const Vec3fx& b ) { return _mm_cmpeq_ps (a.m128, b.m128); } __forceinline Vec3ba neq_mask(const Vec3fx& a, const Vec3fx& b ) { return _mm_cmpneq_ps(a.m128, b.m128); } __forceinline Vec3ba lt_mask( const Vec3fx& a, const Vec3fx& b ) { return _mm_cmplt_ps (a.m128, b.m128); } __forceinline Vec3ba le_mask( const Vec3fx& a, const Vec3fx& b ) { return _mm_cmple_ps (a.m128, b.m128); } __forceinline Vec3ba gt_mask( const Vec3fx& a, const Vec3fx& b ) { return _mm_cmpnle_ps(a.m128, b.m128); } __forceinline Vec3ba ge_mask( const Vec3fx& a, const Vec3fx& b ) { return _mm_cmpnlt_ps(a.m128, b.m128); } __forceinline bool isvalid ( const Vec3fx& v ) { return all(gt_mask(v,Vec3fx(-FLT_LARGE)) & lt_mask(v,Vec3fx(+FLT_LARGE))); } __forceinline bool is_finite ( const Vec3fx& a ) { return all(ge_mask(a,Vec3fx(-FLT_MAX)) & le_mask(a,Vec3fx(+FLT_MAX))); } __forceinline bool isvalid4 ( const Vec3fx& v ) { return all((vfloat4(v.m128) > vfloat4(-FLT_LARGE)) & (vfloat4(v.m128) < vfloat4(+FLT_LARGE))); } __forceinline bool is_finite4 ( const Vec3fx& a ) { return all((vfloat4(a.m128) >= vfloat4(-FLT_MAX)) & (vfloat4(a.m128) <= vfloat4(+FLT_MAX))); } //////////////////////////////////////////////////////////////////////////////// /// Euclidean Space Operators //////////////////////////////////////////////////////////////////////////////// #if defined(__SSE4_1__) __forceinline float dot ( const Vec3fx& a, const Vec3fx& b ) { return _mm_cvtss_f32(_mm_dp_ps(a.m128,b.m128,0x7F)); } #else __forceinline float dot ( const Vec3fx& a, const Vec3fx& b ) { return reduce_add(a*b); } #endif __forceinline Vec3fx cross ( const Vec3fx& a, const Vec3fx& b ) { vfloat4 a0 = vfloat4(a.m128); vfloat4 b0 = shuffle<1,2,0,3>(vfloat4(b.m128)); vfloat4 a1 = shuffle<1,2,0,3>(vfloat4(a.m128)); vfloat4 b1 = vfloat4(b.m128); return Vec3fx(shuffle<1,2,0,3>(msub(a0,b0,a1*b1))); } __forceinline float sqr_length ( const Vec3fx& a ) { return dot(a,a); } __forceinline float rcp_length ( const Vec3fx& a ) { return rsqrt(dot(a,a)); } __forceinline float rcp_length2( const Vec3fx& a ) { return rcp(dot(a,a)); } __forceinline float length ( const Vec3fx& a ) { return sqrt(dot(a,a)); } __forceinline Vec3fx normalize( const Vec3fx& a ) { return a*rsqrt(dot(a,a)); } __forceinline float distance ( const Vec3fx& a, const Vec3fx& b ) { return length(a-b); } __forceinline float halfArea ( const Vec3fx& d ) { return madd(d.x,(d.y+d.z),d.y*d.z); } __forceinline float area ( const Vec3fx& d ) { return 2.0f*halfArea(d); } __forceinline Vec3fx normalize_safe( const Vec3fx& a ) { const float d = dot(a,a); if (unlikely(d == 0.0f)) return a; else return a*rsqrt(d); } /*! differentiated normalization */ __forceinline Vec3fx dnormalize(const Vec3fx& p, const Vec3fx& dp) { const float pp = dot(p,p); const float pdp = dot(p,dp); return (pp*dp-pdp*p)*rcp(pp)*rsqrt(pp); } //////////////////////////////////////////////////////////////////////////////// /// Select //////////////////////////////////////////////////////////////////////////////// __forceinline Vec3fx select( bool s, const Vec3fx& t, const Vec3fx& f ) { __m128 mask = s ? _mm_castsi128_ps(_mm_cmpeq_epi32(_mm_setzero_si128(), _mm_setzero_si128())) : _mm_setzero_ps(); return blendv_ps(f.m128, t.m128, mask); } __forceinline Vec3fx select( const Vec3ba& s, const Vec3fx& t, const Vec3fx& f ) { return blendv_ps(f.m128, t.m128, s); } __forceinline Vec3fx lerp(const Vec3fx& v0, const Vec3fx& v1, const float t) { return madd(1.0f-t,v0,t*v1); } __forceinline int maxDim ( const Vec3fx& a ) { const Vec3fx b = abs(a); if (b.x > b.y) { if (b.x > b.z) return 0; else return 2; } else { if (b.y > b.z) return 1; else return 2; } } //////////////////////////////////////////////////////////////////////////////// /// Rounding Functions //////////////////////////////////////////////////////////////////////////////// #if defined(__aarch64__) __forceinline Vec3fx trunc(const Vec3fx& a) { return vrndq_f32(a.m128); } __forceinline Vec3fx floor(const Vec3fx& a) { return vrndmq_f32(a.m128); } __forceinline Vec3fx ceil (const Vec3fx& a) { return vrndpq_f32(a.m128); } #elif defined (__SSE4_1__) __forceinline Vec3fx trunc( const Vec3fx& a ) { return _mm_round_ps(a.m128, _MM_FROUND_TO_NEAREST_INT); } __forceinline Vec3fx floor( const Vec3fx& a ) { return _mm_round_ps(a.m128, _MM_FROUND_TO_NEG_INF ); } __forceinline Vec3fx ceil ( const Vec3fx& a ) { return _mm_round_ps(a.m128, _MM_FROUND_TO_POS_INF ); } #else __forceinline Vec3fx trunc( const Vec3fx& a ) { return Vec3fx(truncf(a.x),truncf(a.y),truncf(a.z)); } __forceinline Vec3fx floor( const Vec3fx& a ) { return Vec3fx(floorf(a.x),floorf(a.y),floorf(a.z)); } __forceinline Vec3fx ceil ( const Vec3fx& a ) { return Vec3fx(ceilf (a.x),ceilf (a.y),ceilf (a.z)); } #endif //////////////////////////////////////////////////////////////////////////////// /// Output Operators //////////////////////////////////////////////////////////////////////////////// __forceinline embree_ostream operator<<(embree_ostream cout, const Vec3fx& a) { return cout << "(" << a.x << ", " << a.y << ", " << a.z << ")"; } typedef Vec3fx Vec3ff; } #endif level-zero-raytracing-support-1.0.0/rtbuild/math/vec3ia.h000066400000000000000000000241331450534701400233760ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "../sys/alloc.h" #include "emath.h" #if defined(EMBREE_SYCL_SUPPORT) && defined(__SYCL_DEVICE_ONLY__) # include "vec3ia_sycl.h" #else #include "../simd/sse.h" namespace embree { //////////////////////////////////////////////////////////////////////////////// /// SSE Vec3ia Type //////////////////////////////////////////////////////////////////////////////// struct __aligned(16) Vec3ia { ALIGNED_STRUCT_(16); union { __m128i m128; struct { int x,y,z; }; }; typedef int Scalar; enum { N = 3 }; //////////////////////////////////////////////////////////////////////////////// /// Constructors, Assignment & Cast Operators //////////////////////////////////////////////////////////////////////////////// __forceinline Vec3ia( ) {} __forceinline Vec3ia( const __m128i a ) : m128(a) {} __forceinline Vec3ia( const Vec3ia& other ) : m128(other.m128) {} __forceinline Vec3ia& operator =(const Vec3ia& other) { m128 = other.m128; return *this; } __forceinline explicit Vec3ia( const int a ) : m128(_mm_set1_epi32(a)) {} __forceinline Vec3ia( const int x, const int y, const int z) : m128(_mm_set_epi32(z, z, y, x)) {} __forceinline explicit Vec3ia( const __m128 a ) : m128(_mm_cvtps_epi32(a)) {} __forceinline operator const __m128i&() const { return m128; } __forceinline operator __m128i&() { return m128; } //////////////////////////////////////////////////////////////////////////////// /// Constants //////////////////////////////////////////////////////////////////////////////// __forceinline Vec3ia( ZeroTy ) : m128(_mm_setzero_si128()) {} __forceinline Vec3ia( OneTy ) : m128(_mm_set1_epi32(1)) {} __forceinline Vec3ia( PosInfTy ) : m128(_mm_set1_epi32(pos_inf)) {} __forceinline Vec3ia( NegInfTy ) : m128(_mm_set1_epi32(neg_inf)) {} //////////////////////////////////////////////////////////////////////////////// /// Array Access //////////////////////////////////////////////////////////////////////////////// __forceinline const int& operator []( const size_t index ) const { assert(index < 3); return (&x)[index]; } __forceinline int& operator []( const size_t index ) { assert(index < 3); return (&x)[index]; } }; //////////////////////////////////////////////////////////////////////////////// /// Unary Operators //////////////////////////////////////////////////////////////////////////////// __forceinline Vec3ia operator +( const Vec3ia& a ) { return a; } __forceinline Vec3ia operator -( const Vec3ia& a ) { return _mm_sub_epi32(_mm_setzero_si128(), a.m128); } #if (defined(__aarch64__)) __forceinline Vec3ia abs ( const Vec3ia& a ) { return vabsq_s32(a.m128); } #elif defined(__SSSE3__) __forceinline Vec3ia abs ( const Vec3ia& a ) { return _mm_abs_epi32(a.m128); } #endif //////////////////////////////////////////////////////////////////////////////// /// Binary Operators //////////////////////////////////////////////////////////////////////////////// __forceinline Vec3ia operator +( const Vec3ia& a, const Vec3ia& b ) { return _mm_add_epi32(a.m128, b.m128); } __forceinline Vec3ia operator +( const Vec3ia& a, const int b ) { return a+Vec3ia(b); } __forceinline Vec3ia operator +( const int a, const Vec3ia& b ) { return Vec3ia(a)+b; } __forceinline Vec3ia operator -( const Vec3ia& a, const Vec3ia& b ) { return _mm_sub_epi32(a.m128, b.m128); } __forceinline Vec3ia operator -( const Vec3ia& a, const int b ) { return a-Vec3ia(b); } __forceinline Vec3ia operator -( const int a, const Vec3ia& b ) { return Vec3ia(a)-b; } #if defined(__aarch64__) || defined(__SSE4_1__) __forceinline Vec3ia operator *( const Vec3ia& a, const Vec3ia& b ) { return _mm_mullo_epi32(a.m128, b.m128); } __forceinline Vec3ia operator *( const Vec3ia& a, const int b ) { return a * Vec3ia(b); } __forceinline Vec3ia operator *( const int a, const Vec3ia& b ) { return Vec3ia(a) * b; } #endif __forceinline Vec3ia operator &( const Vec3ia& a, const Vec3ia& b ) { return _mm_and_si128(a.m128, b.m128); } __forceinline Vec3ia operator &( const Vec3ia& a, const int b ) { return a & Vec3ia(b); } __forceinline Vec3ia operator &( const int a, const Vec3ia& b ) { return Vec3ia(a) & b; } __forceinline Vec3ia operator |( const Vec3ia& a, const Vec3ia& b ) { return _mm_or_si128(a.m128, b.m128); } __forceinline Vec3ia operator |( const Vec3ia& a, const int b ) { return a | Vec3ia(b); } __forceinline Vec3ia operator |( const int a, const Vec3ia& b ) { return Vec3ia(a) | b; } __forceinline Vec3ia operator ^( const Vec3ia& a, const Vec3ia& b ) { return _mm_xor_si128(a.m128, b.m128); } __forceinline Vec3ia operator ^( const Vec3ia& a, const int b ) { return a ^ Vec3ia(b); } __forceinline Vec3ia operator ^( const int a, const Vec3ia& b ) { return Vec3ia(a) ^ b; } __forceinline Vec3ia operator <<( const Vec3ia& a, const int n ) { return _mm_slli_epi32(a.m128, n); } __forceinline Vec3ia operator >>( const Vec3ia& a, const int n ) { return _mm_srai_epi32(a.m128, n); } __forceinline Vec3ia sll ( const Vec3ia& a, const int b ) { return _mm_slli_epi32(a.m128, b); } __forceinline Vec3ia sra ( const Vec3ia& a, const int b ) { return _mm_srai_epi32(a.m128, b); } __forceinline Vec3ia srl ( const Vec3ia& a, const int b ) { return _mm_srli_epi32(a.m128, b); } //////////////////////////////////////////////////////////////////////////////// /// Assignment Operators //////////////////////////////////////////////////////////////////////////////// __forceinline Vec3ia& operator +=( Vec3ia& a, const Vec3ia& b ) { return a = a + b; } __forceinline Vec3ia& operator +=( Vec3ia& a, const int& b ) { return a = a + b; } __forceinline Vec3ia& operator -=( Vec3ia& a, const Vec3ia& b ) { return a = a - b; } __forceinline Vec3ia& operator -=( Vec3ia& a, const int& b ) { return a = a - b; } #if defined(__aarch64__) || defined(__SSE4_1__) __forceinline Vec3ia& operator *=( Vec3ia& a, const Vec3ia& b ) { return a = a * b; } __forceinline Vec3ia& operator *=( Vec3ia& a, const int& b ) { return a = a * b; } #endif __forceinline Vec3ia& operator &=( Vec3ia& a, const Vec3ia& b ) { return a = a & b; } __forceinline Vec3ia& operator &=( Vec3ia& a, const int& b ) { return a = a & b; } __forceinline Vec3ia& operator |=( Vec3ia& a, const Vec3ia& b ) { return a = a | b; } __forceinline Vec3ia& operator |=( Vec3ia& a, const int& b ) { return a = a | b; } #if !defined(__ARM_NEON) __forceinline Vec3ia& operator <<=( Vec3ia& a, const int& b ) { return a = a << b; } __forceinline Vec3ia& operator >>=( Vec3ia& a, const int& b ) { return a = a >> b; } #endif //////////////////////////////////////////////////////////////////////////////// /// Select //////////////////////////////////////////////////////////////////////////////// __forceinline Vec3ia select( const Vec3ba& m, const Vec3ia& t, const Vec3ia& f ) { #if defined(__aarch64__) || defined(__SSE4_1__) return _mm_castps_si128(_mm_blendv_ps(_mm_castsi128_ps(f), _mm_castsi128_ps(t), m)); #else return _mm_or_si128(_mm_and_si128(_mm_castps_si128(m), t), _mm_andnot_si128(_mm_castps_si128(m), f)); #endif } //////////////////////////////////////////////////////////////////////////////// /// Reductions //////////////////////////////////////////////////////////////////////////////// #if defined(__aarch64__) __forceinline int reduce_add(const Vec3ia& v) { return vaddvq_s32(select(Vec3ba(1,1,1),v,Vec3ia(0))); } __forceinline int reduce_mul(const Vec3ia& v) { return v.x*v.y*v.z; } __forceinline int reduce_min(const Vec3ia& v) { return vminvq_s32(select(Vec3ba(1,1,1),v,Vec3ia(0x7FFFFFFF))); } __forceinline int reduce_max(const Vec3ia& v) { return vmaxvq_s32(select(Vec3ba(1,1,1),v,Vec3ia(0x80000000))); } #else __forceinline int reduce_add(const Vec3ia& v) { return v.x+v.y+v.z; } __forceinline int reduce_mul(const Vec3ia& v) { return v.x*v.y*v.z; } __forceinline int reduce_min(const Vec3ia& v) { return min(v.x,v.y,v.z); } __forceinline int reduce_max(const Vec3ia& v) { return max(v.x,v.y,v.z); } #endif //////////////////////////////////////////////////////////////////////////////// /// Comparison Operators //////////////////////////////////////////////////////////////////////////////// __forceinline bool operator ==( const Vec3ia& a, const Vec3ia& b ) { return (_mm_movemask_ps(_mm_castsi128_ps(_mm_cmpeq_epi32(a.m128, b.m128))) & 7) == 7; } __forceinline bool operator !=( const Vec3ia& a, const Vec3ia& b ) { return (_mm_movemask_ps(_mm_castsi128_ps(_mm_cmpeq_epi32(a.m128, b.m128))) & 7) != 7; } __forceinline bool operator < ( const Vec3ia& a, const Vec3ia& b ) { if (a.x != b.x) return a.x < b.x; if (a.y != b.y) return a.y < b.y; if (a.z != b.z) return a.z < b.z; return false; } __forceinline Vec3ba eq_mask( const Vec3ia& a, const Vec3ia& b ) { return _mm_castsi128_ps(_mm_cmpeq_epi32 (a.m128, b.m128)); } __forceinline Vec3ba lt_mask( const Vec3ia& a, const Vec3ia& b ) { return _mm_castsi128_ps(_mm_cmplt_epi32 (a.m128, b.m128)); } __forceinline Vec3ba gt_mask( const Vec3ia& a, const Vec3ia& b ) { return _mm_castsi128_ps(_mm_cmpgt_epi32 (a.m128, b.m128)); } #if defined(__aarch64__) || defined(__SSE4_1__) __forceinline Vec3ia min( const Vec3ia& a, const Vec3ia& b ) { return _mm_min_epi32(a.m128,b.m128); } __forceinline Vec3ia max( const Vec3ia& a, const Vec3ia& b ) { return _mm_max_epi32(a.m128,b.m128); } #else __forceinline Vec3ia min( const Vec3ia& a, const Vec3ia& b ) { return select(lt_mask(a,b),a,b); } __forceinline Vec3ia max( const Vec3ia& a, const Vec3ia& b ) { return select(gt_mask(a,b),a,b); } #endif //////////////////////////////////////////////////////////////////////////////// /// Output Operators //////////////////////////////////////////////////////////////////////////////// __forceinline embree_ostream operator<<(embree_ostream cout, const Vec3ia& a) { return cout << "(" << a.x << ", " << a.y << ", " << a.z << ")"; } } #endif level-zero-raytracing-support-1.0.0/rtbuild/node_type.h000066400000000000000000000031211450534701400232530ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include #include namespace embree { /* The type of a node. */ enum NodeType : uint8_t { NODE_TYPE_MIXED = 0x0, // identifies a mixed internal node where each child can have a different type NODE_TYPE_INTERNAL = 0x0, // internal BVH node with 6 children NODE_TYPE_INSTANCE = 0x1, // instance leaf NODE_TYPE_PROCEDURAL = 0x3, // procedural leaf NODE_TYPE_QUAD = 0x4, // quad leaf NODE_TYPE_INVALID = 0x7 // indicates invalid node }; /* output operator for NodeType */ inline std::ostream& operator<<(std::ostream& _cout, const NodeType& _type) { #if !defined(__RTRT_GSIM) switch (_type) { case NODE_TYPE_INTERNAL: _cout << "INTERNAL"; break; case NODE_TYPE_INSTANCE: _cout << "INSTANCE"; break; case NODE_TYPE_PROCEDURAL: _cout << "PROCEDURAL"; break; case NODE_TYPE_QUAD: _cout << "QUAD"; break; case NODE_TYPE_INVALID: _cout << "INVALID"; break; default: _cout << "INVALID NODE TYPE"; break; } #endif return _cout; }; /* Sub-type definition for each NodeType */ enum SubType : uint8_t { SUB_TYPE_NONE = 0, /* sub-type for NODE_TYPE_INTERNAL */ SUB_TYPE_INTERNAL6 = 0x00, // Xe+: internal node with 6 children /* Sub-type for NODE_TYPE_QUAD */ SUB_TYPE_QUAD = 0, // Xe+: standard quad leaf (64 bytes) /* Sub-type for NODE_TYPE_PROCEDURAL */ SUB_TYPE_PROCEDURAL = 0, // Xe+: standard procedural leaf }; } level-zero-raytracing-support-1.0.0/rtbuild/qbvh6.cpp000066400000000000000000000206121450534701400226520ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "qbvh6.h" namespace embree { template void computeInternalNodeStatistics(BVHStatistics& stats, QBVH6::Node node, const BBox1f time_range, const float node_bounds_area, const float root_bounds_area) { InternalNode* inner = node.innerNode(); size_t size = 0; for (uint32_t i = 0; i < InternalNode::NUM_CHILDREN; i++) { if (inner->valid(i)) { size++; computeStatistics(stats, inner->child(i), time_range, area(inner->bounds(i)), root_bounds_area, InternalNode::NUM_CHILDREN); } } /* update BVH statistics */ stats.internalNode.numNodes++; stats.internalNode.numChildrenUsed += size; stats.internalNode.numChildrenTotal += InternalNode::NUM_CHILDREN; stats.internalNode.nodeSAH += time_range.size() * node_bounds_area / root_bounds_area; stats.internalNode.numBytes += sizeof(InternalNode); } void computeStatistics(BVHStatistics& stats, QBVH6::Node node, const BBox1f time_range, const float node_bounds_area, const float root_bounds_area, uint32_t numChildren) { switch (node.type) { case NODE_TYPE_INSTANCE: { stats.instanceLeaf.numLeaves++; stats.instanceLeaf.numPrimsUsed++; stats.instanceLeaf.numPrimsTotal++; stats.instanceLeaf.leafSAH += time_range.size() * node_bounds_area / root_bounds_area; stats.instanceLeaf.numBytesUsed += sizeof(InstanceLeaf); stats.instanceLeaf.numBytesTotal += sizeof(InstanceLeaf); break; } case NODE_TYPE_QUAD: { bool last = false; stats.quadLeaf.numLeaves++; do { QuadLeaf* quad = node.leafNodeQuad(); node.node += sizeof(QuadLeaf); last = quad->isLast(); stats.quadLeaf.numPrimsUsed += quad->size(); stats.quadLeaf.numPrimsTotal += 2; stats.quadLeaf.numBytesUsed += quad->usedBytes(); stats.quadLeaf.numBytesTotal += sizeof(QuadLeaf); stats.quadLeaf.leafSAH += quad->size() * time_range.size() * node_bounds_area / root_bounds_area; } while (!last); break; } case NODE_TYPE_PROCEDURAL: { /*if (node.leafNodeProcedural()->leafDesc.isProceduralInstance()) // FIXME: for some reason we always to into this case!? { stats.proceduralLeaf.numLeaves++; stats.proceduralLeaf.numPrimsUsed += 1; stats.proceduralLeaf.numPrimsTotal += 1; stats.proceduralLeaf.leafSAH += time_range.size() * node_bounds_area / root_bounds_area; stats.proceduralLeaf.numBytesUsed += sizeof(InstanceLeaf); stats.proceduralLeaf.numBytesTotal += sizeof(InstanceLeaf); } else*/ { bool last = false; uint32_t currPrim = node.cur_prim; stats.proceduralLeaf.numLeaves++; do { ProceduralLeaf* leaf = node.leafNodeProcedural(); last = leaf->isLast(currPrim); if (currPrim == 0) { stats.proceduralLeaf.numBlocks++; stats.proceduralLeaf.numBytesUsed += leaf->usedBytes(); stats.proceduralLeaf.numBytesTotal += sizeof(ProceduralLeaf); } uint32_t primsInBlock = leaf->size(); stats.proceduralLeaf.numPrimsUsed++; stats.proceduralLeaf.numPrimsTotal++; stats.proceduralLeaf.leafSAH += time_range.size() * node_bounds_area / root_bounds_area; if (++currPrim >= primsInBlock) { currPrim = 0; node.node += sizeof(ProceduralLeaf); } } while (!last); } break; } case NODE_TYPE_INTERNAL: { computeInternalNodeStatistics(stats, node, time_range, node_bounds_area, root_bounds_area); break; } default: assert(false); } } BVHStatistics QBVH6::computeStatistics() const { BVHStatistics stats; if (empty()) return stats; embree::computeStatistics(stats,root(),BBox1f(0,1),area(bounds),area(bounds),6); return stats; } template void QBVH6::printInternalNodeStatistics(std::ostream& cout, QBVH6::Node node, uint32_t depth, uint32_t numChildren) { QInternalNode* inner = node.innerNode(); inner->print(cout, depth, false); std::cout << std::endl; for (uint32_t i = 0; i < QInternalNode::NUM_CHILDREN; i++) { if (inner->valid(i)) print(cout, inner->child(i), depth + 1, QInternalNode::NUM_CHILDREN); } cout << tab(depth) << "}" << std::endl; } void QBVH6::print( std::ostream& cout, QBVH6::Node node, uint32_t depth, uint32_t numChildren) { switch (node.type) { case NODE_TYPE_INSTANCE: { node.leafNodeInstance()->print(cout,depth); cout << std::endl; break; } case NODE_TYPE_QUAD: { std::cout << tab(depth) << "List {" << std::endl; bool last = false; do { QuadLeaf* quad = node.leafNodeQuad(); node.node += sizeof(QuadLeaf); last = quad->isLast(); quad->print(cout,depth+1); std::cout << std::endl; } while (!last); std::cout << tab(depth) << "}" << std::endl; break; } case NODE_TYPE_PROCEDURAL: { /*if (!node.leafNodeProcedural()->leafDesc.opaqueCullingEnabled()) { InstanceLeaf* leaf = (InstanceLeaf*) node.node; leaf->print(cout,depth+1); std::cout << std::endl; } else*/ { std::cout << tab(depth) << "List {" << std::endl; bool last = false; uint32_t currPrim = node.cur_prim; do { ProceduralLeaf* leaf = node.leafNodeProcedural(); last = leaf->isLast(currPrim); uint32_t primsInBlock = leaf->size(); leaf->print(cout,currPrim,depth+1); std::cout << std::endl; if (++currPrim >= primsInBlock) { currPrim = 0; node.node += sizeof(ProceduralLeaf); } } while (!last); std::cout << tab(depth) << "}" << std::endl; } break; } case NODE_TYPE_INTERNAL: { printInternalNodeStatistics(cout, node, depth, numChildren); break; } default: std::cout << "{ INVALID_NODE }" << std::endl; //assert(false); } } unsigned* getBackPointersData(const QBVH6* base) { // FIXME: should be member function return (unsigned*)(((const char*)base) + 64 * base->backPointerDataStart); } unsigned getNumBackpointers(const QBVH6* base) { // FIXME: should be member function return ((base->backPointerDataEnd - base->backPointerDataStart) * 64) / sizeof(unsigned); } uint64_t getBackpointerChildOffset(const QBVH6* base, unsigned idx) { // FIXME: should be member function return 64 * uint64_t(base->nodeDataStart + idx); } uint64_t getParentFromBackpointerOffset(const QBVH6* base, unsigned idx) { // FIXME: should be member function return 64 * uint64_t(base->nodeDataStart + (getBackPointersData(base)[idx] >> 6)); } void QBVH6::print ( std::ostream& cout ) const { cout << "QBVH @ "<< this <<" header: {\n"; cout << " rootNodeOffset = " << rootNodeOffset << std::endl; cout << " bounds = " << bounds << std::endl; cout << " nodeDataStart = " << nodeDataStart << std::endl; cout << " nodeDataCur = " << nodeDataCur << std::endl; cout << " leafDataStart = " << leafDataCur << std::endl; cout << " leafDataCur = " << leafDataCur << std::endl; cout << " proceduralDataStart = " << proceduralDataStart << std::endl; cout << " proceduralDataCur = " << proceduralDataCur << std::endl; cout << " backPointerDataStart = " << backPointerDataStart << std::endl; cout << " backPointerDataEnd = " << backPointerDataEnd << std::endl; cout << " numPrims = " << numPrims << std::endl; cout << "}" << std::endl; if (empty()) return; print(cout,root(),0,6); if (hasBackPointers()) { cout << "backpointers: {\n"; for (unsigned bp = 0; bp < getNumBackpointers(this); ++bp) { cout << " node @ offset " << (void*)getBackpointerChildOffset(this, bp) << " parent = " << (void*)getParentFromBackpointerOffset(this, bp) << ", num children = " << ((getBackPointersData(this)[bp] >> 3) & 0x7) << "\n"; } cout << "}\n"; } } } level-zero-raytracing-support-1.0.0/rtbuild/qbvh6.h000066400000000000000000000201221450534701400223130ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "qnode.h" #include "statistics.h" #include "rtbuild.h" namespace embree { /* The QBVH6 structure defines the bounding volume hierarchy (BVH) that is used by the hardware. It is a BVH with 6-wide branching factor, and quantized bounding boxes. At the leaf level quads (QuadLeaf type), procedural geometries (ProceduralLeaf type), and instances (InstanceLeaf type) can get referenced. */ inline constexpr size_t roundOffsetTo128(size_t offset) { return 2 * ((offset + 127) / 128); } struct QBVH6 { typedef NodeRef Node; typedef InternalNode InternalNode6; static constexpr uint64_t rootNodeOffset = 128; static_assert(sizeof(InternalNode6) == 64, "InternalNode6 must be 64 bytes large"); /* structure used to initialize the memory allocator inside the BVH */ struct SizeEstimate { SizeEstimate () : nodeBytes(0), leafBytes(0), proceduralBytes(0) {} SizeEstimate (size_t nodeBytes, size_t leafBytes, size_t proceduralBytes) : nodeBytes(nodeBytes), leafBytes(leafBytes), proceduralBytes(proceduralBytes) {} size_t bytes() const { return sizeof(QBVH6) + nodeBytes + leafBytes + proceduralBytes; } friend bool operator<= (SizeEstimate a, SizeEstimate b) { if (a.nodeBytes > b.nodeBytes) return false; if (a.leafBytes > b.leafBytes) return false; if (a.proceduralBytes > b.proceduralBytes) return false; return true; } friend SizeEstimate operator+ (const SizeEstimate& a, const SizeEstimate& b) { return SizeEstimate(a.nodeBytes + b.nodeBytes, a.leafBytes + b.leafBytes, a.proceduralBytes + b.proceduralBytes); } /* output operator */ friend inline std::ostream& operator<<(std::ostream& cout, const SizeEstimate& estimate) { cout << "SizeEstimate {" << std::endl; cout << " nodeBytes = " << estimate.nodeBytes << ", " << std::endl; cout << " leafBytes = " << estimate.leafBytes << ", " << std::endl; cout << " proceduralBytes = " << estimate.proceduralBytes << ", " << std::endl; return cout << "}"; } public: size_t nodeBytes; // bytes required to store internal nodes size_t leafBytes; // bytes required to store leaf nodes size_t proceduralBytes; // bytes required to store procedural leaf nodes }; /* Initializes a QBVH6 node with its provided size. The memory for * the QBVH6 structure is overallocated and the allocation size is * provided to the constructor, such that the allocator of the BVH * can get initialized properly. */ QBVH6(SizeEstimate size) : nodeDataStart((uint32_t)roundOffsetTo128(sizeof(QBVH6))), nodeDataCur(nodeDataStart), leafDataStart(nodeDataCur + (uint32_t)(size.nodeBytes / 64)), leafDataCur(leafDataStart), proceduralDataStart(leafDataCur + (uint32_t)(size.leafBytes / 64)), proceduralDataCur(proceduralDataStart), backPointerDataStart(proceduralDataCur + (uint32_t)(size.proceduralBytes/64)), backPointerDataEnd(backPointerDataStart) { assert(size.nodeBytes % 64 == 0); assert(size.leafBytes % 64 == 0); assert(size.proceduralBytes % 64 == 0); assert(size.bytes() <= (64LL << 32)); bounds = embree::empty; } /* Returns the root node of the BVH */ Node root() const { return Node(rootNodeOffset,(uint64_t)this); } /* sets root not offset to point to this specified node */ void setRootNodeOffset(Node node) { assert(node.cur_prim == 0); uint64_t MAYBE_UNUSED rootNodeOffset1 = (uint64_t)node - (uint64_t)this; assert(rootNodeOffset == rootNodeOffset1); } /* check if BVH is empty */ bool empty() const { return root().type == NODE_TYPE_INVALID; } /* pretty printing */ template static void printInternalNodeStatistics(std::ostream& cout, QBVH6::Node node, uint32_t depth, uint32_t numChildren = 6); static void print(std::ostream& cout, QBVH6::Node node, uint32_t depth, uint32_t numChildren=6); void print(std::ostream& cout = std::cout) const; /* output operator */ friend inline std::ostream& operator<<(std::ostream& cout, const QBVH6& qbvh) { qbvh.print(cout); return cout; } /* calculates BVH statistics */ BVHStatistics computeStatistics() const; /* This section implements a simple allocator for BVH data. The BVH data is separated into two section, a section where nodes and leaves in mixed mode are allocated, and a section where only leaves are allocate in fat-leaf mode. */ public: /* allocate data in the node memory section */ char* allocNode(size_t bytes) { assert(bytes % 64 == 0); uint32_t blocks = (uint32_t)bytes / 64; assert(nodeDataCur + blocks <= leafDataStart); char* ptr = (char*)this + 64 * (size_t)nodeDataCur; nodeDataCur += blocks; return ptr; } /* allocate memory in the leaf memory section */ char* allocLeaf(size_t bytes) { assert(bytes % 64 == 0); uint32_t blocks = (uint32_t)bytes / 64; assert(leafDataCur + blocks <= proceduralDataStart); char* ptr = (char*)this + 64 * (size_t)leafDataCur; leafDataCur += blocks; return ptr; } /* allocate memory in procedural leaf memory section */ char* allocProceduralLeaf(size_t bytes) { assert(bytes % 64 == 0); uint32_t blocks = (uint32_t)bytes / 64; assert(proceduralDataCur + blocks <= backPointerDataStart); char* ptr = (char*)this + 64 * (size_t)proceduralDataCur; proceduralDataCur += blocks; return ptr; } /* returns pointer to node address */ char* nodePtr(size_t ofs) { return (char*)this + 64 * size_t(nodeDataStart) + ofs; } /* returns pointer to address for next leaf allocation */ char* leafPtr() { return (char*)this + 64 * (size_t)leafDataCur; } /* returns the total number of bytes of the BVH */ size_t getTotalBytes() const { return 64 * (size_t)backPointerDataEnd; } /* returns number of bytes available for node allocations */ size_t getFreeNodeBytes() const { return 64 * (size_t)(leafDataStart - nodeDataCur); } /* returns number of bytes available for leaf allocations */ size_t getFreeLeafBytes() const { return 64 * (size_t)(proceduralDataStart - leafDataCur); } /* returns number of bytes available for procedural leaf allocations */ size_t getFreeProceduralLeafBytes() const { return 64 * (size_t)(backPointerDataStart - proceduralDataCur); } /* returns the bytes used by allocations */ size_t getUsedBytes() const { return getTotalBytes() - getFreeNodeBytes() - getFreeLeafBytes() - getFreeProceduralLeafBytes(); } bool hasBackPointers() const { return backPointerDataStart < backPointerDataEnd; } public: ze_raytracing_accel_format_internal_t rtas_format = ZE_RTAS_DEVICE_FORMAT_EXP_VERSION_1; uint32_t reserved1; BBox3f bounds; // bounding box of the BVH uint32_t nodeDataStart; // first 64 byte block of node data uint32_t nodeDataCur; // next free 64 byte block for node allocations uint32_t leafDataStart; // first 64 byte block of leaf data uint32_t leafDataCur; // next free 64 byte block for leaf allocations uint32_t proceduralDataStart; // first 64 byte block for procedural leaf data uint32_t proceduralDataCur; // next free 64 byte block for procedural leaf allocations uint32_t backPointerDataStart; // first 64 byte block for back pointers uint32_t backPointerDataEnd; // end of back pointer array uint32_t numTimeSegments = 1; uint32_t numPrims = 0; // number of primitives in this BVH uint32_t reserved[12]; uint64_t dispatchGlobalsPtr; }; static_assert(sizeof(QBVH6) == 128, "QBVH6 must be 128 bytes large"); } level-zero-raytracing-support-1.0.0/rtbuild/qbvh6_builder_sah.h000066400000000000000000001536731450534701400246760ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "qbvh6.h" #include "statistics.h" #include "quadifier.h" #include "rtbuild.h" #include #if defined(ZE_RAYTRACING) #include "builders/priminfo.h" #include "builders/primrefgen_presplit.h" #include "builders/heuristic_binning_array_aligned.h" #include "algorithms/parallel_for_for_prefix_sum.h" #else #include "../../builders/priminfo.h" #include "../../builders/primrefgen_presplit.h" #include "../../builders/heuristic_binning_array_aligned.h" #include "../../../common/algorithms/parallel_for_for_prefix_sum.h" #endif namespace embree { namespace isa { struct QBVH6BuilderSAH { static const size_t BVH_WIDTH = QBVH6::InternalNode6::NUM_CHILDREN; static const size_t MIN_LARGE_LEAF_LEVELS = 8; //!< create balanced tree of we are that many levels before the maximum tree depth /* the type of primitive that is referenced */ enum Type { TRIANGLE=0, QUAD=1, PROCEDURAL=2, INSTANCE=3, UNKNOWN=4, NUM_TYPES=5 }; /* check when we use spatial splits */ static bool useSpatialSplits(ze_rtas_builder_build_quality_hint_exp_t build_quality, ze_rtas_builder_build_op_exp_flags_t build_flags) { return build_quality == ZE_RTAS_BUILDER_BUILD_QUALITY_HINT_EXP_HIGH && !(build_flags & ZE_RTAS_BUILDER_BUILD_OP_EXP_FLAG_NO_DUPLICATE_ANYHIT_INVOCATION); } /* BVH allocator */ struct Allocator { Allocator() {} void init(char* data_in, size_t bytes_in) { ptr = data_in; end = bytes_in; cur.store(0); } size_t bytesAllocated() const { return cur.load(); } __forceinline void* malloc(size_t bytes, size_t align = 16) { assert(align <= 128); //ZE_RAYTRACING_ACCELERATION_STRUCTURE_ALIGNMENT_EXT if (unlikely(cur.load() >= end)) return nullptr; const size_t extra = (align - cur) & (align-1); const size_t bytes_align = bytes + extra; const size_t cur_old = cur.fetch_add(bytes_align); const size_t cur_new = cur_old + bytes_align; if (unlikely(cur_new >= end)) return nullptr; return &ptr[cur_old + extra]; } private: char* ptr; // data buffer pointer size_t end; // size of data buffer in bytes __aligned(64) std::atomic cur; // current pointer to allocate next data block from }; /* triangle data for leaf creation */ struct Triangle { Triangle () : gmask(0) {} Triangle (uint32_t i0, uint32_t i1, uint32_t i2, Vec3f p0, Vec3f p1, Vec3f p2, GeometryFlags gflags, uint8_t gmask) : i0(i0), i1(i1), i2(i2), p0(p0), p1(p1), p2(p2), gflags(gflags), gmask(gmask) {} __forceinline bool valid() const { return gmask != 0; } uint32_t i0,i1,i2; Vec3f p0,p1,p2; GeometryFlags gflags; uint8_t gmask; }; /* quad data for leaf creation */ struct Quad { Quad (Vec3f p0, Vec3f p1, Vec3f p2, Vec3f p3, GeometryFlags gflags, uint8_t gmask) : p0(p0), p1(p1), p2(p2), p3(p3), gflags(gflags), gmask(gmask) {} Vec3f p0,p1,p2,p3; GeometryFlags gflags; uint8_t gmask; }; /* procedural data for leaf creation */ struct Procedural { Procedural (uint8_t gmask) : gmask(gmask) {} PrimLeafDesc desc(uint32_t geomID) const { return PrimLeafDesc(0,geomID,GeometryFlags::NONE,gmask,PrimLeafDesc::TYPE_OPACITY_CULLING_ENABLED); } uint8_t gmask; }; /* instance data for leaf creation */ struct Instance { Instance (AffineSpace3f local2world, void* accel, uint8_t imask, uint32_t instanceUserID) : local2world(local2world), accel(accel), imask(imask), instanceUserID(instanceUserID) {} AffineSpace3f local2world; void* accel; uint8_t imask; uint32_t instanceUserID; }; struct Stats { size_t numTriangles = 0; size_t numQuads = 0; size_t numProcedurals = 0; size_t numInstances = 0; /* assume some reasonable quadification rate */ void estimate_quadification() { numQuads += (numTriangles+1)/2 + numTriangles/8; numTriangles = 0; } void estimate_presplits( double factor ) { numTriangles = max(numTriangles, size_t(numTriangles*factor)); numQuads = max(numQuads , size_t(numQuads*factor)); numInstances = max(numInstances, size_t(numInstances*factor)); } size_t size() { return numTriangles+numQuads+numProcedurals+numInstances; } size_t expected_bvh_bytes() { const size_t blocks = (size()+5)/6; const size_t expected_bytes = 128 + 64*size_t(1+1.5*blocks) + numTriangles*64 + numQuads*64 + numProcedurals*8 + numInstances*128; const size_t bytes = 2*4096 + size_t(1.1*expected_bytes); // FIXME: FastAllocator wastes memory and always allocates 4kB per thread return (bytes+127)&-128; } size_t worst_case_bvh_bytes() { const size_t numPrimitives = size(); const size_t blocks = (numPrimitives+5)/6; const size_t worst_case_bytes = 128 + 64*(1+blocks + numPrimitives) + numTriangles*64 + numQuads*64 + numProcedurals*64 + numInstances*128; const size_t bytes = 2*4096 + size_t(1.1*worst_case_bytes); // FIXME: FastAllocator wastes memory and always allocates 4kB per thread return (bytes+127)&-128; } size_t scratch_space_bytes() { return size()*sizeof(PrimRef)+64; // 64 to align to 64 bytes } }; /*! settings for SAH builder */ struct Settings { public: size_t maxDepth = 27; //!< maximum depth of BVH to build size_t sahBlockSize = 6; //!< blocksize for SAH heuristic size_t leafSize[NUM_TYPES] = { 9,9,6,6,6 }; //!< target size of a leaf size_t typeSplitSize = 128; //!< number of primitives when performing type splitting }; /*! recursive state of builder */ struct BuildRecord { public: __forceinline BuildRecord () {} __forceinline BuildRecord (size_t depth, const PrimInfoRange& prims, Type type) : depth(depth), prims(prims), type(type) {} __forceinline BBox3fa bounds() const { return prims.geomBounds; } __forceinline friend bool operator< (const BuildRecord& a, const BuildRecord& b) { return a.prims.size() < b.prims.size(); } __forceinline friend bool operator> (const BuildRecord& a, const BuildRecord& b) { return a.prims.size() > b.prims.size(); } __forceinline size_t begin() const { return prims.begin(); } __forceinline size_t end () const { return prims.end(); } __forceinline size_t size () const { return prims.size(); } __forceinline bool equalType() const { return type != UNKNOWN; } friend inline std::ostream& operator<<(std::ostream& cout, const BuildRecord& r) { return cout << "BuildRecord { depth = " << r.depth << ", pinfo = " << r.prims << ", type = " << r.type << " }"; } public: size_t depth; //!< Depth of the root of this subtree. PrimInfoRange prims; //!< The list of primitives. Type type; //!< shared type when type of primitives are equal otherwise UNKNOWN }; struct PrimRange { PrimRange () : block_delta(0), cur_prim(0) {} PrimRange (uint8_t block_delta, uint8_t start_prim = 0) : block_delta(block_delta), cur_prim(start_prim) { assert(block_delta < 4); assert(start_prim < 16); } friend std::ostream& operator<<(std::ostream& cout,const PrimRange& range) { return cout << "PrimRange { " << (int)range.block_delta << ", " << (int)range.cur_prim << " }"; } public: uint8_t block_delta; uint8_t cur_prim; }; struct ReductionTy { ReductionTy() : node(nullptr) {} ReductionTy (void* node, NodeType type, uint8_t nodeMask, PrimRange primRange) : node((char*)node), type(type), nodeMask(nodeMask), primRange(primRange) {} inline bool valid() { return node != nullptr; } public: char* node; NodeType type; uint8_t nodeMask; PrimRange primRange; }; class ProceduralLeafBuilder { public: ProceduralLeafBuilder (char* data, size_t numBlocks) : data(data), numBlocks(numBlocks), prevBlockID(0), currBlockID(0), currProcedural(nullptr) {} ProceduralLeaf* getCurProcedural() { if (!currProcedural) { assert(numBlocks); currProcedural = new (data) ProceduralLeaf(); data += sizeof(ProceduralLeaf); numBlocks--; } return currProcedural; } PrimRange addProcedural(uint32_t geomID, uint32_t primID, const Procedural* procedural, bool last) { assert(currProcedural); if (!currProcedural->add(procedural->desc(geomID),primID,last)) { assert(numBlocks); currProcedural = (ProceduralLeaf*) data; data += sizeof(ProceduralLeaf); numBlocks--; new (currProcedural) ProceduralLeaf(procedural->desc(geomID),primID,last); currBlockID+=1; } uint32_t blockDelta = currBlockID - prevBlockID; uint32_t currPrim = (uint32_t)currProcedural->size() - 1; prevBlockID = currBlockID; return PrimRange(blockDelta,currPrim); } protected: char* data; size_t numBlocks; uint32_t prevBlockID; uint32_t currBlockID; ProceduralLeaf* currProcedural; }; template class BuilderT { public: static const size_t BINS = 32; typedef HeuristicArrayBinningSAH CentroidBinner; BuilderT (Device* device, const getSizeFunc& getSize, const getTypeFunc& getType, const createPrimRefArrayFunc& createPrimRefArray, const getTriangleFunc& getTriangle, const getTriangleIndicesFunc& getTriangleIndices, const getQuadFunc& getQuad, const getProceduralFunc& getProcedural, const getInstanceFunc& getInstance, void* scratch_ptr, size_t scratch_bytes, ze_rtas_format_exp_t rtas_format, ze_rtas_builder_build_quality_hint_exp_t build_quality, ze_rtas_builder_build_op_exp_flags_t build_flags, bool verbose) : getSize(getSize), getType(getType), createPrimRefArray(createPrimRefArray), getTriangle(getTriangle), getTriangleIndices(getTriangleIndices), getQuad(getQuad), getProcedural(getProcedural), getInstance(getInstance), prims(scratch_ptr,scratch_bytes), rtas_format((ze_raytracing_accel_format_internal_t)rtas_format), build_quality(build_quality), build_flags(build_flags), verbose(verbose) {} ReductionTy setInternalNode(char* curAddr, size_t curBytes, NodeType nodeTy, char* childAddr, BuildRecord children[BVH_WIDTH], ReductionTy values[BVH_WIDTH], size_t numChildren) { assert(curBytes >= sizeof(QBVH6::InternalNode6)); assert(numChildren <= QBVH6::InternalNode6::NUM_CHILDREN); BBox3f bounds = empty; for (size_t i=0; isetChildOffset(childAddr); uint8_t nodeMask = 0; for (uint32_t i = 0; i < numChildren; i++) { qnode->setChild(i,children[i].bounds(),values[i].type,values[i].primRange.block_delta); nodeMask |= values[i].nodeMask; } qnode->nodeMask = nodeMask; return ReductionTy(curAddr, NODE_TYPE_INTERNAL, nodeMask, PrimRange(curBytes/64)); } ReductionTy setNode(char* curAddr, size_t curBytes, NodeType nodeTy, char* childAddr, BuildRecord children[BVH_WIDTH], ReductionTy values[BVH_WIDTH], size_t numChildren) { return setInternalNode(curAddr,curBytes,nodeTy,childAddr,children,values,numChildren); } QuadLeaf getTriangleInternal(unsigned int geomID, unsigned int primID) { QBVH6BuilderSAH::Triangle tri = getTriangle(geomID,primID); const Vec3f p0 = tri.p0; const Vec3f p1 = tri.p1; const Vec3f p2 = tri.p2; Vec3f p3 = p2; uint8_t lb0 = 0,lb1 = 0,lb2 = 0; uint16_t second = quadification[geomID][primID]; /* handle paired triangle */ if (second) { QBVH6BuilderSAH::Triangle tri1 = getTriangle(geomID,primID+second); assert(tri.gflags == tri1.gflags); assert(tri.gmask == tri1.gmask ); bool pair MAYBE_UNUSED = pair_triangles(Vec3(tri.i0,tri.i1,tri.i2),Vec3(tri1.i0,tri1.i1,tri1.i2),lb0,lb1,lb2); assert(pair); if (lb0 == 3) p3 = tri1.p0; if (lb1 == 3) p3 = tri1.p1; if (lb2 == 3) p3 = tri1.p2; } return QuadLeaf( p0,p1,p2,p3, lb0,lb1,lb2, 0, geomID, primID, primID+second, tri.gflags, tri.gmask, false ); }; QuadLeaf createQuadLeaf(Type ty, const PrimRef& prim) { const unsigned int geomID = prim.geomID(); const unsigned int primID = prim.primID(); if (ty == TRIANGLE) return getTriangleInternal(geomID, primID); else { assert(ty == QUAD); const Quad quad = getQuad(geomID,primID); return QuadLeaf(quad.p0,quad.p1,quad.p3,quad.p2, 3,2,1, 0, geomID, primID, primID, quad.gflags, quad.gmask, false ); } } const ReductionTy createQuads(Type ty, const BuildRecord& curRecord, char* curAddr_) { QuadLeaf* curAddr = (QuadLeaf*) curAddr_; uint8_t nodeMask = 0; for (size_t i = curRecord.begin(); i < curRecord.end(); i++, curAddr++) { *curAddr = createQuadLeaf(ty,prims[i]); curAddr->last = (i+1) == curRecord.end(); nodeMask |= curAddr->leafDesc.geomMask; } return ReductionTy(curAddr, NODE_TYPE_QUAD, nodeMask, PrimRange(curRecord.size()*sizeof(QuadLeaf)/64)); } const ReductionTy createFatQuadLeaf(Type ty, const BuildRecord& curRecord, char* curAddr, size_t curBytes, BuildRecord children[BVH_WIDTH], size_t numChildren) { /*! allocate data for all children */ char* childData = (char*) allocator.malloc(curRecord.prims.size()*sizeof(QuadLeaf), 64); if (!childData) return ReductionTy(); /* create each child */ ReductionTy values[BVH_WIDTH]; for (size_t i=0, j=0; isetChildOffset(first_procedural + ranges[0].block_delta); qnode->nodeMask = nodeMask; ranges[0].block_delta = 0; for (size_t i = curRecord.begin(), j=0; i < curRecord.end(); i++, j++) qnode->setChild(j,prims[i].bounds(),NODE_TYPE_PROCEDURAL,ranges[j+1].block_delta,ranges[j].cur_prim); return ReductionTy(curAddr, NODE_TYPE_INTERNAL, nodeMask, PrimRange(curBytes/64)); } template const ReductionTy createInstances(const BuildRecord& curRecord, char* curAddr, size_t curBytes) { uint32_t numPrimitives = curRecord.size(); assert(numPrimitives <= QBVH6::InternalNode6::NUM_CHILDREN); /* allocate data for all children */ InstanceLeaf* childData = (InstanceLeaf*) allocator.malloc(numPrimitives*sizeof(InstanceLeaf), 64); if (!childData) return ReductionTy(); QBVH6::InternalNode6* qnode = new (curAddr) QBVH6::InternalNode6(curRecord.bounds(),NODE_TYPE_INSTANCE); qnode->setChildOffset(childData); uint8_t nodeMask = 0; for (size_t i=curRecord.begin(), c=0; i(instance.accel)->root(); root += 64*rootOfs; // goto sub-BVH new (&childData[c]) InstanceLeaf(instance.local2world,root,geomID,instance.instanceUserID,instance.imask); qnode->setChild(c,prims[i].bounds(),NODE_TYPE_INSTANCE,sizeof(InstanceLeaf)/64,0); nodeMask |= instance.imask; } qnode->nodeMask = nodeMask; return ReductionTy(curAddr, NODE_TYPE_INTERNAL, nodeMask, PrimRange(curBytes/64)); } /* finds the index of the child with largest surface area */ int findChildWithLargestArea(BuildRecord children[BVH_WIDTH], size_t numChildren, size_t leafThreshold) { /*! find best child to split */ float bestArea = neg_inf; int bestChild = -1; for (uint32_t i=0; i<(uint32_t)numChildren; i++) { /* ignore leaves as they cannot get split */ if (children[i].prims.size() <= leafThreshold) continue; /* find child with largest surface area */ const float area = halfArea(children[i].prims.geomBounds); if (area > bestArea) { bestArea = area; bestChild = i; } } return bestChild; } /* finds the index of the child with most primitives */ int findChildWithMostPrimitives(BuildRecord children[BVH_WIDTH], size_t numChildren, size_t leafThreshold) { /* find best child with largest size */ size_t bestSize = 0; int bestChild = -1; for (uint32_t i=0; i<(uint32_t)numChildren; i++) { /* ignore leaves as they cannot get split */ if (children[i].prims.size() <= leafThreshold) continue; /* remember child with largest size */ if (children[i].prims.size() > bestSize) { bestSize = children[i].size(); bestChild = i; } } return bestChild; } /* finds the index of the child with most primitives */ int findChildWithNonEqualTypes(BuildRecord children[BVH_WIDTH], size_t numChildren) { for (uint32_t i=0; i<(uint32_t)numChildren; i++) if (!children[i].equalType()) return i; return -1; } void SAHSplit(size_t depth, size_t sahBlockSize, int bestChild, BuildRecord children[BVH_WIDTH], size_t& numChildren) { PrimInfoRange linfo, rinfo; BuildRecord brecord = children[bestChild]; /* first perform centroid binning */ CentroidBinner centroid_binner(prims.data()); CentroidBinner::Split bestSplit = centroid_binner.find_block_size(brecord.prims,sahBlockSize); /* now split the primitive list */ if (bestSplit.valid()) centroid_binner.split(bestSplit,brecord.prims,linfo,rinfo); /* the above techniques may fail, and we fall back to some brute force split in the middle */ else centroid_binner.splitFallback(brecord.prims,linfo,rinfo); children[bestChild ] = BuildRecord(depth+1, linfo, brecord.type); children[numChildren] = BuildRecord(depth+1, rinfo, brecord.type); numChildren++; } void TypeSplit(size_t depth, int bestChild, BuildRecord children[BVH_WIDTH], size_t& numChildren) { BuildRecord brecord = children[bestChild]; PrimInfoRange linfo, rinfo; auto type = getType(prims[brecord.prims.begin()].geomID()); performTypeSplit(getType,type,prims.data(),brecord.prims.get_range(),linfo,rinfo); for (size_t i=linfo.begin(); i cfg.maxDepth) throw std::runtime_error("BVH too deep"); /* there should be at least one primitive and not too many */ assert(curRecord.size() > 0); assert(curRecord.size() <= cfg.leafSize[curRecord.type]); /* all primitives have to have the same type */ Type ty = getType(prims[curRecord.begin()].geomID()); for (size_t i=curRecord.begin(); i 3) { children[0] = curRecord; numChildren = 1; /*! perform fallback splits until node is full */ while (numChildren < BVH_WIDTH) { const int bestChild = findChildWithMostPrimitives(children,numChildren,1); if (bestChild == -1) break; FallbackSplit(curRecord.depth,bestChild,children,numChildren); } } } /* sort build records for faster shadow ray traversal */ std::sort(children,children+numChildren, [](const BuildRecord& a,const BuildRecord& b) { return area(a.prims.geomBounds) > area(b.prims.geomBounds); }); /* create leaf of proper type */ if (ty == TRIANGLE || ty == QUAD) return createFatQuadLeaf(ty, curRecord, curAddr, curBytes, children, numChildren); else if (ty == PROCEDURAL) return createProcedurals(curRecord,curAddr,curBytes); else if (ty == INSTANCE) { if (rtas_format == ZE_RTAS_DEVICE_FORMAT_EXP_VERSION_1) return createInstances(curRecord,curAddr,curBytes); } assert(false); return ReductionTy(); } const ReductionTy createLargeLeaf(const BuildRecord& curRecord, char* curAddr, size_t curBytes) { /* this should never occur but is a fatal error */ if (curRecord.depth > cfg.maxDepth) throw std::runtime_error("BVH too deep"); /* all primitives have to have the same type */ Type ty MAYBE_UNUSED = getType(prims[curRecord.begin()].geomID()); for (size_t i=curRecord.begin(); i= cfg.maxDepth; bool performTypeSplit = !curRecord.equalType() && (createLeaf || curRecord.size() <= cfg.typeSplitSize); /* check if types are really not equal when we attempt to split by type */ if (performTypeSplit) { /* check if types are already equal */ bool equalTy = true; Type type = getType(prims[curRecord.begin()].geomID()); for (size_t i=curRecord.begin()+1; i()); /*! allocate data for all children */ size_t childrenBytes = numChildren*sizeof(QBVH6::InternalNode6); char* childBase = (char*) allocator.malloc(childrenBytes, 64); if (!childBase) return ReductionTy(); /* spawn tasks */ if (curRecord.size() > 1024) // cfg.singleThreadThreshold { std::atomic success = true; parallel_for(size_t(0), numChildren, [&] (const range& r) { if (!success) return; for (size_t i=r.begin(); i& r, size_t k, unsigned int geomID) { PrimInfo pinfo(empty); for (size_t j=r.begin(); j(prim.bounds(),dim,pos,v,left,right); if (pair != QUADIFIER_TRIANGLE) { const Triangle tri1 = getTriangle(geomID,primID+pair); const Vec3fa v[4] = { tri1.p0, tri1.p1, tri1.p2, tri1.p0 }; BBox3fa left1, right1; splitPolygon<3>(prim.bounds(),dim,pos,v,left1,right1); left.extend(left1); right.extend(right1); } left_o = PrimRef(left , geomID, primID); right_o = PrimRef(right, geomID, primID); } void splitQuad(const PrimRef& prim, const size_t dim, const float pos, PrimRef& left_o, PrimRef& right_o) const { const uint32_t geomID = prim.geomID(); const uint32_t primID = prim.primID(); const Quad quad = getQuad(geomID,primID); const Vec3fa v[5] = { quad.p0, quad.p1, quad.p2, quad.p3, quad.p0 }; splitPolygon<4>(prim,dim,pos,v,left_o,right_o); } void splitTriangleOrQuad(const PrimRef& prim, const size_t dim, const float pos, PrimRef& left_o, PrimRef& right_o) const { switch (getType(prim.geomID())) { case TRIANGLE: splitTrianglePair(prim,dim,pos,left_o,right_o); break; case QUAD : splitQuad (prim,dim,pos,left_o,right_o); break; default: assert(false); break; } } void openInstance(const PrimRef& prim, const unsigned int splitprims, PrimRef subPrims[MAX_PRESPLITS_PER_PRIMITIVE], unsigned int& numSubPrims) { struct Item { QBVH6::InternalNode6* node; float priority; Item () {} Item (QBVH6::InternalNode6* node) : node(node), priority(halfArea(node->bounds())) { /* fat leaves cannot get opened */ if (node->isFatLeaf()) priority = 0.0f; } inline bool operator< ( const Item& other) const { return priority < other.priority; } }; const uint32_t targetSubPrims = splitprims; const uint32_t geomID = prim.geomID(); const uint32_t primID MAYBE_UNUSED = prim.primID(); assert(primID == 0); // has to be zero as we encode root offset here const Instance instance = getInstance(geomID,0); QBVH6::InternalNode6* root = static_cast(instance.accel)->root().innerNode(); darray_t heap; heap.push_back(root); while (heap.size() + (QBVH6::InternalNode6::NUM_CHILDREN-1) <= MAX_PRESPLITS_PER_PRIMITIVE) { /* terminate when budget exceeded */ if (heap.size() >= targetSubPrims) break; /* get top heap element */ std::pop_heap(heap.begin(), heap.end()); auto top = heap.back(); /* if that happens there are only leaf nodes left that cannot get opened */ if (top.priority == 0.0f) break; heap.pop_back(); /* add all children to the heap */ for (uint32_t i=0; ivalid(i)) continue; heap.push_back(top.node->child(i).template innerNode()); std::push_heap(heap.begin(), heap.end()); } } /* create primrefs */ for (size_t i=0; ibounds()); int64_t ofs = ((int64_t)node-(int64_t)root)/64; assert(ofs >= INT_MIN && ofs <= INT_MAX); subPrims[numSubPrims++] = PrimRef(bounds,geomID,(int32_t)ofs); } } float primitiveAreaTrianglePair(const PrimRef& prim) { const uint32_t geomID = prim.geomID(); const uint32_t primID = prim.primID(); const uint16_t pair = quadification[geomID][primID]; assert(pair != QUADIFIER_PAIRED); const Triangle tri0 = getTriangle(geomID,primID); float A = areaProjectedTriangle(tri0.p0,tri0.p1,tri0.p2); if (pair == QUADIFIER_TRIANGLE) return A; const Triangle tri1 = getTriangle(geomID,primID+pair); A += areaProjectedTriangle(tri1.p0,tri1.p1,tri1.p2); return A; } float primitiveAreaQuad(const PrimRef& prim) { const uint32_t geomID = prim.geomID(); const uint32_t primID = prim.primID(); const Quad quad = getQuad(geomID,primID); const float A0 = areaProjectedTriangle(quad.p0,quad.p1,quad.p3); const float A1 = areaProjectedTriangle(quad.p2,quad.p3,quad.p1); return A0+A1; } float primitiveAreaInstance(const PrimRef& prim) { return halfArea(prim.bounds()); } float primitiveArea(const PrimRef& prim) { switch (getType(prim.geomID())) { case TRIANGLE: return primitiveAreaTrianglePair(prim); case QUAD : return primitiveAreaQuad(prim); case INSTANCE: return primitiveAreaInstance(prim); default : return 0.0f; } } ReductionTy build(uint32_t numGeometries, PrimInfo& pinfo_o, char* root) { double t1 = verbose ? getSeconds() : 0.0; /* quadify all triangles */ ParallelForForPrefixSumState pstate; pstate.init(numGeometries,getSize,size_t(1024)); PrimInfo pinfo = parallel_for_for_prefix_sum0_( pstate, size_t(1), getSize, PrimInfo(empty), [&](size_t geomID, const range& r, size_t k) -> PrimInfo { if (getType(geomID) == QBVH6BuilderSAH::TRIANGLE) return PrimInfo(pair_triangles(geomID,(QuadifierType*) quadification[geomID].data(), r.begin(), r.end(), getTriangleIndices)); else return PrimInfo(r.size()); }, [](const PrimInfo& a, const PrimInfo& b) -> PrimInfo { return PrimInfo::merge(a,b); }); double t2 = verbose ? getSeconds() : 0.0; if (verbose) std::cout << "quadification: " << std::setw(10) << (t2-t1)*1000.0 << "ms, " << std::endl; //<< std::setw(10) << 1E-6*double(numTriangles)/(t2-t1) << " Mtris/s" << std::endl; size_t numPrimitives = pinfo.size(); /* first try */ //pstate.init(numGeometries,getSize,size_t(1024)); pinfo = parallel_for_for_prefix_sum1_( pstate, size_t(1), getSize, PrimInfo(empty), [&](size_t geomID, const range& r, size_t k, const PrimInfo& base) -> PrimInfo { if (getType(geomID) == QBVH6BuilderSAH::TRIANGLE) return createTrianglePairPrimRefArray(prims.data(),r,base.size(),(unsigned)geomID); else return createPrimRefArray(prims,BBox1f(0,1),r,base.size(),(unsigned)geomID); }, [](const PrimInfo& a, const PrimInfo& b) -> PrimInfo { return PrimInfo::merge(a,b); }); double t3 = verbose ? getSeconds() : 0.0; if (verbose) std::cout << "primrefgen : " << std::setw(10) << (t3-t2)*1000.0 << "ms, " << std::setw(10) << 1E-6*double(numPrimitives)/(t3-t2) << " Mprims/s" << std::endl; /* if we need to filter out geometry, run again */ if (pinfo.size() != numPrimitives) { numPrimitives = pinfo.size(); pinfo = parallel_for_for_prefix_sum1_( pstate, size_t(1), getSize, PrimInfo(empty), [&](size_t geomID, const range& r, size_t k, const PrimInfo& base) -> PrimInfo { if (getType(geomID) == QBVH6BuilderSAH::TRIANGLE) { return createTrianglePairPrimRefArray(prims.data(),r,base.size(),(unsigned)geomID); } else return createPrimRefArray(prims,BBox1f(0,1),r,base.size(),(unsigned)geomID); }, [](const PrimInfo& a, const PrimInfo& b) -> PrimInfo { return PrimInfo::merge(a,b); }); } assert(pinfo.size() == numPrimitives); double t4 = verbose ? getSeconds() : 0.0; if (verbose) std::cout << "primrefgen2 : " << std::setw(10) << (t4-t3)*1000.0 << "ms, " << std::setw(10) << 1E-6*double(numPrimitives)/(t4-t3) << " Mprims/s" << std::endl; /* perform pre-splitting */ if (useSpatialSplits(build_quality,build_flags) && numPrimitives) { auto splitter = [this] (const PrimRef& prim, const size_t dim, const float pos, PrimRef& left_o, PrimRef& right_o) { splitTriangleOrQuad(prim,dim,pos,left_o,right_o); }; auto splitter1 = [&] (const PrimRef& prim, const unsigned int splitprims, const SplittingGrid& grid, PrimRef subPrims[MAX_PRESPLITS_PER_PRIMITIVE], unsigned int& numSubPrims) { if (getType(prim.geomID()) == QBVH6BuilderSAH::INSTANCE) { openInstance(prim,splitprims,subPrims,numSubPrims); } else { splitPrimitive(splitter,prim,splitprims,grid,subPrims,numSubPrims); } }; auto primitiveArea1 = [this] (const PrimRef& prim) -> float { return primitiveArea(prim); }; pinfo = createPrimRefArray_presplit(numPrimitives, prims, pinfo, splitter1, primitiveArea1); } /* exit early if scene is empty */ if (pinfo.size() == 0) { pinfo_o = pinfo; return createEmptyNode(root); } /* build hierarchy */ BuildRecord record(1,pinfo,UNKNOWN); ReductionTy r = createInternalNode(record,root,sizeof(QBVH6::InternalNode6)); double t5 = verbose ? getSeconds() : 0.0; if (verbose) std::cout << "bvh_build : " << std::setw(10) << (t5-t4)*1000.0 << "ms, " << std::setw(10) << 1E-6*double(numPrimitives)/(t5-t4) << " Mprims/s" << std::endl; pinfo_o = pinfo; return r; } bool build(size_t numGeometries, char* accel, size_t bytes, BBox3f* boundsOut, size_t* accelBufferBytesOut, void* dispatchGlobalsPtr) { double t0 = verbose ? getSeconds() : 0.0; Stats stats; size_t numPrimitives = 0; quadification.resize(numGeometries); for (size_t geomID=0; geomIDrtas_format = rtas_format; qbvh->numPrims = 0; //numPrimitives; uint64_t rootNodeOffset = QBVH6::Node((char*)(r.node - (char*)qbvh), r.type, r.primRange.cur_prim); assert(rootNodeOffset == QBVH6::rootNodeOffset); _unused(rootNodeOffset); qbvh->bounds = bounds; qbvh->numTimeSegments = 1; qbvh->dispatchGlobalsPtr = (uint64_t) dispatchGlobalsPtr; #if 0 BVHStatistics stats = qbvh->computeStatistics(); stats.print(std::cout); stats.print_raw(std::cout); qbvh->print(); /*std::cout << "#define bvh_bytes " << bytes << std::endl; std::cout << "const unsigned char bvh_data[bvh_bytes] = {"; for (size_t i=0; i prims; Allocator allocator; std::vector> quadification; ze_raytracing_accel_format_internal_t rtas_format; ze_rtas_builder_build_quality_hint_exp_t build_quality; ze_rtas_builder_build_op_exp_flags_t build_flags; bool verbose; }; template static void estimateSize(size_t numGeometries, const getSizeFunc& getSize, const getTypeFunc& getType, ze_rtas_format_exp_t rtas_format, ze_rtas_builder_build_quality_hint_exp_t build_quality, ze_rtas_builder_build_op_exp_flags_t build_flags, size_t& expectedBytes, size_t& worstCaseBytes, size_t& scratchBytes) { Stats stats; for (size_t geomID=0; geomID static bool build(size_t numGeometries, Device* device, const getSizeFunc& getSize, const getTypeFunc& getType, const createPrimRefArrayFunc& createPrimRefArray, const getTriangleFunc& getTriangle, const getTriangleIndicesFunc& getTriangleIndices, const getQuadFunc& getQuad, const getProceduralFunc& getProcedural, const getInstanceFunc& getInstance, char* accel_ptr, size_t accel_bytes, void* scratch_ptr, size_t scratch_bytes, BBox3f* boundsOut, size_t* accelBufferBytesOut, ze_rtas_format_exp_t rtas_format, ze_rtas_builder_build_quality_hint_exp_t build_quality, ze_rtas_builder_build_op_exp_flags_t build_flags, bool verbose, void* dispatchGlobalsPtr) { /* align scratch buffer to 64 bytes */ bool scratchAligned = std::align(64,0,scratch_ptr,scratch_bytes); if (!scratchAligned) throw std::runtime_error("scratch buffer cannot get aligned"); BuilderT builder (device, getSize, getType, createPrimRefArray, getTriangle, getTriangleIndices, getQuad, getProcedural, getInstance, scratch_ptr, scratch_bytes, rtas_format, build_quality, build_flags, verbose); return builder.build(numGeometries, accel_ptr, accel_bytes, boundsOut, accelBufferBytesOut, dispatchGlobalsPtr); } }; } } level-zero-raytracing-support-1.0.0/rtbuild/qnode.h000066400000000000000000000461441450534701400224070ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include #include #include "leaf.h" #if defined(__INTEL_LLVM_COMPILER) && defined(WIN32) inline float embree_frexp(float value, int* exp) { // using the Intel(R) oneAPI DPC++/C++ Compiler with -no-intel-libs results // in an unresolved external symbol "__imp_frexp" error and therefore we // provide a the manual implemetation referenced here // https://en.cppreference.com/w/c/numeric/math/frexp in this case static_assert(FLT_RADIX == 2, "custom implementation of frexp only works for base 2 floating point representations"); *exp = (value == 0) ? 0 : (int)(1 + logb(value)); return scalbn(value, -(*exp)); } #endif namespace embree { /* The NodeRef structure references a node of the BVH. It stores the * pointer to that node as well as the node's type. If a leaf node * is referenced the current primitive to intersect is also * stored. */ struct NodeRef { NodeRef () : node(nullptr), type(NODE_TYPE_INVALID), cur_prim(0) {} NodeRef (void* node, NodeType type, uint8_t cur_prim) : node((char*)node), type(type), cur_prim(cur_prim) { assert(cur_prim < 16); } /* decode from 64 bit encoding used in MemRay and Instances */ NodeRef (uint64_t nodePtr, uint64_t offset = 0) { node = (char*) (nodePtr & ~(uint64_t)0xF) + offset; //type = NODE_TYPE_INTERNAL; // we can only reference internal nodes inside ray and instances type = (NodeType) (nodePtr & 0xF); cur_prim = 0; } /* 64 bit encoding used in MemRay and Instances */ operator uint64_t() const { //assert(type == NODE_TYPE_INTERNAL); assert(((uint64_t)node & 0xF) == 0); assert(cur_prim == 0); return (uint64_t)node + (uint64_t) type; } /* returns the internal node that is referenced */ template InternalNode* innerNode() const { assert(type == NODE_TYPE_INTERNAL); return (InternalNode*)node; } /* returns the instance leaf node that is referenced */ InstanceLeaf* leafNodeInstance() const { assert(type == NODE_TYPE_INSTANCE); return (InstanceLeaf*)node; } /* returns the quad leaf node that is referenced */ QuadLeaf* leafNodeQuad() const { assert(type == NODE_TYPE_QUAD); return (QuadLeaf*)node; } /* returns the procedural leaf node that is referenced */ ProceduralLeaf* leafNodeProcedural() const { assert(type == NODE_TYPE_PROCEDURAL); return (ProceduralLeaf*)node; } friend bool operator ==(const NodeRef& a, const NodeRef& b) { return (a.node == b.node) && (a.type == b.type) && (a.cur_prim == b.cur_prim); } friend bool operator !=(const NodeRef& a, const NodeRef& b) { return !(a == b); } #if !defined(__RTRT_GSIM) friend inline std::ostream& operator<<(std::ostream& _cout, const NodeRef& node) { return _cout << "NodeRef { " << (void*)node.node << ", " << node.type << ", " << (int)node.cur_prim << " }"; } #endif public: char* node; // pointer to the referenced node NodeType type; // type of the node referenced uint8_t cur_prim : 4; // current primitive referenced in the leaf }; /* The internal nodes of the BVH store references to 6 children and quantized bounds for each of these children. All children are stored consecutively in memory at a location refered to by the childOffset. To calculate the relative location of the i'th child the size (as encoded in blockIncr) of all the children with index smaller than i has to get added to that childOffset. The calculated offset specifies the signed number of 64 bytes blocks relative to the node address to reach the child. If the nodeType is INTERNAL we are in mixed mode and the type of each child is encoded inside the startPrim member. Otherwise we are in fat leaf mode and each child has the same type 'nodeType' and startPrim identifies the primitive where the leaf starts. The leaf spans all primitives from this start primitive to the end primitive which is marked as 'last'. The bounding boxes of the children are quantized into a regular 3D grid. The world space position of the origin of that grid is stored at full precision in the lower member, while the step size is encoded in the exp_x, exp_y, and exp_z members as power of 2. Thus grid coordinates together with their exponent (xi,exp_x), (yi,exp_y), (zi,exp_z) correspond to the mantissa and exponent of a floating point number representation without leading zero. Thus the world space position of the bounding planes can get calculated as follows: x = lower.x + pow(2,exp_x) * 0.xi y = lower.y + pow(2,exp_y) * 0.yi z = lower.z + pow(2,exp_z) * 0.zi As the stored grid coordinates for child bounds are only unsigned 8-bit values, ray/box intersections can get performed with reduced precision. The node also stores a mask used for ray filtering. Only rays with (node.nodeMask & ray.rayMask) != 0 are traversed, all others are culled. */ struct InternalNode6Data { static constexpr uint32_t NUM_CHILDREN = 6; Vec3f lower; // world space origin of quantization grid int32_t childOffset; // offset to all children in 64B multiples NodeType nodeType; // the type of the node uint8_t pad; // unused byte int8_t exp_x; // 2^exp_x is the size of the grid in x dimension int8_t exp_y; // 2^exp_y is the size of the grid in y dimension int8_t exp_z; // 2^exp_z is the size of the grid in z dimension uint8_t nodeMask; // mask used for ray filtering struct ChildData { uint8_t blockIncr : 2; // size of child in 64 byte blocks uint8_t startPrim : 4; // start primitive in fat leaf mode or child type in mixed mode uint8_t pad : 2; // unused bits } childData[NUM_CHILDREN]; uint8_t lower_x[NUM_CHILDREN]; // the quantized lower bounds in x-dimension uint8_t upper_x[NUM_CHILDREN]; // the quantized upper bounds in x-dimension uint8_t lower_y[NUM_CHILDREN]; // the quantized lower bounds in y-dimension uint8_t upper_y[NUM_CHILDREN]; // the quantized upper bounds in y-dimension uint8_t lower_z[NUM_CHILDREN]; // the quantized lower bounds in z-dimension uint8_t upper_z[NUM_CHILDREN]; // the quantized upper bounds in z-dimension }; static_assert(sizeof(InternalNode6Data) == 64, "InternalNode6Data must be 64 bytes large"); template struct InternalNodeCommon : public InternalNodeData { using InternalNodeData::NUM_CHILDREN; InternalNodeCommon() { } InternalNodeCommon(NodeType type) { this->nodeType = type; this->childOffset = 0; this->nodeMask = 0xFF; for (uint32_t i = 0; i < InternalNodeData::NUM_CHILDREN; i++) this->childData[i] = { 0, 0, 0 }; this->lower = Vec3f(0.0f); this->exp_x = 0; this->exp_y = 0; this->exp_z = 0; /* set all child bounds to invalid */ for (uint32_t i = 0; i < InternalNodeData::NUM_CHILDREN; i++) { this->lower_x[i] = this->lower_y[i] = this->lower_z[i] = 0x80; this->upper_x[i] = this->upper_y[i] = this->upper_z[i] = 0x00; } } /* this function slightly enlarges bounds in order to make traversal watertight */ static const BBox3f conservativeBox(const BBox3f box, float ulps = 1.0f) { const float err = ulps*std::numeric_limits::epsilon() * std::max(reduce_max(abs(box.lower)), reduce_max(abs(box.upper))); return enlarge(box, Vec3f(err)); } /* this function quantizes the provided bounds */ const BBox3f quantize_bounds(BBox3f fbounds, Vec3f base) const { const Vec3f lower = fbounds.lower-base; const Vec3f upper = fbounds.upper-base; float qlower_x = ldexpf(lower.x, -this->exp_x + 8); float qlower_y = ldexpf(lower.y, -this->exp_y + 8); float qlower_z = ldexpf(lower.z, -this->exp_z + 8); float qupper_x = ldexpf(upper.x, -this->exp_x + 8); float qupper_y = ldexpf(upper.y, -this->exp_y + 8); float qupper_z = ldexpf(upper.z, -this->exp_z + 8); assert(qlower_x >= 0.0f && qlower_x <= 255.0f); assert(qlower_y >= 0.0f && qlower_y <= 255.0f); assert(qlower_z >= 0.0f && qlower_z <= 255.0f); assert(qupper_x >= 0.0f && qupper_x <= 255.0f); assert(qupper_y >= 0.0f && qupper_y <= 255.0f); assert(qupper_z >= 0.0f && qupper_z <= 255.0f); qlower_x = min(max(floorf(qlower_x),0.0f),255.0f); qlower_y = min(max(floorf(qlower_y),0.0f),255.0f); qlower_z = min(max(floorf(qlower_z),0.0f),255.0f); qupper_x = min(max(ceilf(qupper_x),0.0f),255.0f); qupper_y = min(max(ceilf(qupper_y),0.0f),255.0f); qupper_z = min(max(ceilf(qupper_z),0.0f),255.0f); BBox3f qbounds(Vec3f(qlower_x, qlower_y, qlower_z), Vec3f(qupper_x, qupper_y, qupper_z)); /* verify that quantized bounds are conservative */ BBox3f dbounds = dequantize_bounds(qbounds, base); dbounds.lower.x -= 2.0f*float(ulp) * (fabs(base.x) + ldexpf(255.0f,this->exp_x-8)); dbounds.lower.y -= 2.0f*float(ulp) * (fabs(base.y) + ldexpf(255.0f,this->exp_y-8)); dbounds.lower.z -= 2.0f*float(ulp) * (fabs(base.z) + ldexpf(255.0f,this->exp_z-8)); dbounds.upper.x += 2.0f*float(ulp) * (fabs(base.x) + ldexpf(255.0f,this->exp_x-8)); dbounds.upper.y += 2.0f*float(ulp) * (fabs(base.y) + ldexpf(255.0f,this->exp_y-8)); dbounds.upper.z += 2.0f*float(ulp) * (fabs(base.z) + ldexpf(255.0f,this->exp_z-8)); assert(subset(fbounds, dbounds)); return qbounds; } /* this function de-quantizes the provided bounds */ const BBox3f dequantize_bounds(const BBox3f& qbounds, Vec3f base) const { const float dlower_x = base.x + ldexpf(qbounds.lower.x, this->exp_x - 8); const float dlower_y = base.y + ldexpf(qbounds.lower.y, this->exp_y - 8); const float dlower_z = base.z + ldexpf(qbounds.lower.z, this->exp_z - 8); const float dupper_x = base.x + ldexpf(qbounds.upper.x, this->exp_x - 8); const float dupper_y = base.y + ldexpf(qbounds.upper.y, this->exp_y - 8); const float dupper_z = base.z + ldexpf(qbounds.upper.z, this->exp_z - 8); return BBox3f(Vec3f(dlower_x, dlower_y, dlower_z), Vec3f(dupper_x, dupper_y, dupper_z)); } /* Determines if a child is valid. We have only to look at the * topmost bit of lower_x and upper_x to determine if child is * valid */ bool valid(int i) const { return !(this->lower_x[i] & 0x80) || (this->upper_x[i] & 0x80); } /* Determines if the node is in fat leaf mode. */ bool isFatLeaf() const { return this->nodeType != NODE_TYPE_MIXED; } /* Sets the offset to the child memory. */ void setChildOffset(void* childDataPtr) { int64_t childDataOffset = childDataPtr ? (char*)childDataPtr - (char*)this : 0; assert(childDataOffset % 64 == 0); assert((int64_t)(int32_t)(childDataOffset / 64) == (childDataOffset / 64)); this->childOffset = (int32_t)(childDataOffset / 64); } /* Sets the type, size, and current primitive of a child */ void setChildType(uint32_t child, NodeType childType, uint32_t block_delta, uint32_t cur_prim) { // there is no need to store block_delta for last child if (child == NUM_CHILDREN-1) block_delta = 0; assert(block_delta < 4); assert(cur_prim < 16); if (isFatLeaf()) { assert(this->nodeType == childType); this->childData[child].startPrim = cur_prim; this->childData[child].blockIncr = block_delta; } else { assert(cur_prim == 0); this->childData[child].startPrim = childType; this->childData[child].blockIncr = block_delta; } } void invalidateChild(uint32_t childID) { /* set child bounds to invalid */ this->lower_x[childID] = this->lower_y[childID] = this->lower_z[childID] = 0x80; this->upper_x[childID] = this->upper_y[childID] = this->upper_z[childID] = 0x00; } /* Sets child bounds */ void setChildBounds(uint32_t childID, const BBox3f& fbounds) { assert(fbounds.lower.x <= fbounds.upper.x); assert(fbounds.lower.y <= fbounds.upper.y); assert(fbounds.lower.z <= fbounds.upper.z); const BBox3f qbounds = quantize_bounds(conservativeBox(fbounds), this->lower); this->lower_x[childID] = (uint8_t)qbounds.lower.x; this->lower_y[childID] = (uint8_t)qbounds.lower.y; this->lower_z[childID] = (uint8_t)qbounds.lower.z; this->upper_x[childID] = (uint8_t)qbounds.upper.x; this->upper_y[childID] = (uint8_t)qbounds.upper.y; this->upper_z[childID] = (uint8_t)qbounds.upper.z; assert(valid(childID)); } /* Sets an entire child, including bounds, type, size, and referenced primitive. */ void setChild(uint32_t childID, const BBox3f& fbounds, NodeType type, uint32_t block_delta, uint32_t cur_prim = 0) { setChildType(childID, type, block_delta, cur_prim); setChildBounds(childID, fbounds); } /* Calculates the byte offset to the child. The offset is * relative to the address this node. */ int64_t getChildOffset(uint32_t childID) const { int64_t ofs = this->childOffset; for (uint32_t j = 0; j < childID; j++) ofs += this->childData[j].blockIncr; return 64 * ofs; } /* Returns the type of the child. In fat leaf mode the type is * shared between all children, otherwise a per-child type is * encoded inside the startPrim member for each child. */ NodeType getChildType(uint32_t childID) const { if (isFatLeaf()) return this->nodeType; else return (NodeType)(this->childData[childID].startPrim); } /* Returns the start primitive of a child. In case of children * in fat-leaf mode, all children are leaves, and the start * primitive specifies the primitive in a leaf block where the * leaf start. */ uint32_t getChildStartPrim(uint32_t childID) const { if (isFatLeaf()) return this->childData[childID].startPrim; else return 0; } /* Returns a node reference for the given child. This reference * includes the node pointer, type, and start primitive. */ NodeRef child(void* This, int childID) const { return NodeRef((char*)This + getChildOffset(childID), getChildType(childID), getChildStartPrim(childID)); } NodeRef child(int i) const { return child((void*)this, i); } }; template struct InternalNode : public InternalNodeCommon { using InternalNodeCommon::valid; using InternalNodeCommon::getChildType; using InternalNodeCommon::getChildOffset; using InternalNodeCommon::getChildStartPrim; using InternalNodeCommon::conservativeBox; using InternalNodeCommon::dequantize_bounds; using InternalNodeCommon::NUM_CHILDREN; InternalNode() { } InternalNode (NodeType type) : InternalNodeCommon(type) {} /* Constructs an internal node. The quantization grid gets * initialized from the provided parent bounds. */ InternalNode (BBox3f box, NodeType type = NODE_TYPE_MIXED) : InternalNode(type) { setNodeBounds(box); } void setNodeBounds(BBox3f box) { /* initialize quantization grid */ box = conservativeBox(box); const float _ulp = std::numeric_limits::epsilon(); const float up = 1.0f + float(_ulp); Vec3f len = box.size() * up; this->lower = box.lower; #if defined(__INTEL_LLVM_COMPILER) && defined(WIN32) int _exp_x; float mant_x = embree_frexp(len.x, &_exp_x); _exp_x += (mant_x > 255.0f / 256.0f); int _exp_y; float mant_y = embree_frexp(len.y, &_exp_y); _exp_y += (mant_y > 255.0f / 256.0f); int _exp_z; float mant_z = embree_frexp(len.z, &_exp_z); _exp_z += (mant_z > 255.0f / 256.0f); #else int _exp_x; float mant_x = frexp(len.x, &_exp_x); _exp_x += (mant_x > 255.0f / 256.0f); int _exp_y; float mant_y = frexp(len.y, &_exp_y); _exp_y += (mant_y > 255.0f / 256.0f); int _exp_z; float mant_z = frexp(len.z, &_exp_z); _exp_z += (mant_z > 255.0f / 256.0f); #endif _exp_x = max(-128,_exp_x); // enlarge too tight bounds _exp_y = max(-128,_exp_y); _exp_z = max(-128,_exp_z); this->exp_x = _exp_x; assert(_exp_x >= -128 && _exp_x <= 127); this->exp_y = _exp_y; assert(_exp_y >= -128 && _exp_y <= 127); this->exp_z = _exp_z; assert(_exp_z >= -128 && _exp_z <= 127); } /* dequantizes the bounds of the specified child */ const BBox3f bounds(uint32_t childID) const { return dequantize_bounds(BBox3f(Vec3f(this->lower_x[childID], this->lower_y[childID], this->lower_z[childID]), Vec3f(this->upper_x[childID], this->upper_y[childID], this->upper_z[childID])), this->lower); } const BBox3f bounds() const { BBox3f b = empty; for (size_t i=0; isetChildOffset((char*)this + getChildOffset(0)); } #if !defined(__RTRT_GSIM) /* output of internal node */ void print(std::ostream& cout, uint32_t depth, bool close) const { cout << tab(depth) << "InternalNode" << NUM_CHILDREN << " {" << std::endl; cout << tab(depth) << " addr = " << this << std::endl; cout << tab(depth) << " childOffset = " << 64 * int64_t(this->childOffset) << std::endl; cout << tab(depth) << " nodeType = " << NodeType(this->nodeType) << std::endl; cout << tab(depth) << " nodeMask = " << std::bitset<8>(this->nodeMask) << std::endl; for (uint32_t i = 0; i < NUM_CHILDREN; i++) { cout << tab(depth) << " child" << i << " = { "; if (valid(i)) { cout << "type = " << getChildType(i); cout << ", offset = " << getChildOffset(i); cout << ", prim = " << getChildStartPrim(i); cout << ", bounds = " << bounds(i); } else { cout << "INVALID"; } cout << " }" << std::endl; } if (close) cout << tab(depth) << "}"; } /* output operator for internal node */ friend inline std::ostream& operator<<(std::ostream& cout, const InternalNode& node) { node.print(cout, 0, true); return cout; } #endif }; inline size_t GetInternalNodeSize(uint32_t numChildren) { if (numChildren <= 6) return sizeof(InternalNode6Data); else assert(false); return 0; } typedef InternalNode InternalNode6; } level-zero-raytracing-support-1.0.0/rtbuild/quadifier.h000066400000000000000000000107121450534701400232420ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #if defined(ZE_RAYTRACING) #include "sys/sysinfo.h" #include "sys/vector.h" #include "math/vec2.h" #include "math/vec3.h" #include "math/bbox.h" #include "math/affinespace.h" #else #include "../../common/default.h" #endif namespace embree { enum QuadifierType : uint16_t { QUADIFIER_PAIRED = 0xFFFF, // indicates that triangle is paired with a previous triangle QUADIFIER_TRIANGLE = 0, // indicates that this triangle cannot get paired QUADIFIER_QUAD = 1, // all values > 0 and != 0xFFFF indicate offset to paired triangle QUADIFIER_MAX_DISTANCE = 31, }; template struct static_deque { __forceinline Ty pop_front() { assert(size()); return operator[](begin++); } __forceinline void push_back(const Ty& v) { assert(size() < N); operator[](end++) = v; } __forceinline size_t size() const { assert(end >= begin); return end-begin; } __forceinline bool full() const { return size() == N; } __forceinline void erase( size_t j ) { assert(j >= begin && j < end); /* fast path as we mostly just merge with the subsequent triangle */ if (likely(j == begin)) begin++; /* fastest when left side is small */ else if (j-begin < end-j-1) { for (size_t i=j; i>=begin+1; i--) operator[](i) = operator[](i-1); begin++; } /* fastest if right side is small */ else { for (size_t i=j+1; i a, Vec3 b, uint8_t& lb0, uint8_t& lb1, uint8_t& lb2) { const vuint<4> va(a.x,a.y,a.z,0); const vboolf<4> mb0 = vboolf<4>(0x8) | vuint<4>(b.x) == va; const vboolf<4> mb1 = vboolf<4>(0x8) | vuint<4>(b.y) == va; const vboolf<4> mb2 = vboolf<4>(0x8) | vuint<4>(b.z) == va; lb0 = bsf(movemask(mb0)); lb1 = bsf(movemask(mb1)); lb2 = bsf(movemask(mb2)); return (lb0 == 3) + (lb1 == 3) + (lb2 == 3) <= 1; } template __forceinline void merge_triangle_window( uint32_t geomID, static_deque& triangleWindow, QuadifierType* quads_o, const GetTriangleFunc& getTriangle ) { uint32_t primID0 = triangleWindow.pop_front(); /* load first triangle */ Vec3 tri0 = getTriangle(geomID, primID0); /* find a second triangle in triangle window to pair with */ for ( size_t slot = triangleWindow.begin; slot != triangleWindow.end; ++slot ) { /* load second triangle */ uint32_t primID1 = triangleWindow[slot]; Vec3 tri1 = getTriangle(geomID, primID1); /* try to pair triangles */ uint8_t lb0,lb1,lb2; bool pair = pair_triangles(tri0,tri1,lb0,lb1,lb2); /* the offset between the triangles cannot be too large as hardware limits bits for offset encode */ uint32_t prim_offset = primID1 - primID0; pair &= prim_offset <= QUADIFIER_MAX_DISTANCE; /* store pairing if successful */ if (pair) { assert(prim_offset > 0 && prim_offset < QUADIFIER_PAIRED); quads_o[primID0] = (QuadifierType) prim_offset; quads_o[primID1] = QUADIFIER_PAIRED; triangleWindow.erase(slot); return; } } /* make a triangle if we fail to find a candiate to pair with */ quads_o[primID0] = QUADIFIER_TRIANGLE; } template inline size_t pair_triangles( uint32_t geomID, QuadifierType* quads_o, uint32_t primID0, uint32_t primID1, const GetTriangleFunc& getTriangle ) { static_deque triangleWindow; size_t numTrianglePairs = 0; for (uint32_t primID=primID0; primIDtriangleCount); return *(ze_rtas_triangle_indices_uint32_exp_t*)((char*)geom->pTriangleBuffer + uint64_t(primID)*geom->triangleStride); } inline Vec3f getVertex(const ze_rtas_builder_triangles_geometry_info_exp_t* geom, uint32_t vertexID) { assert(vertexID < geom->vertexCount); return *(Vec3f*)((char*)geom->pVertexBuffer + uint64_t(vertexID)*geom->vertexStride); } inline ze_rtas_quad_indices_uint32_exp_t getPrimitive(const ze_rtas_builder_quads_geometry_info_exp_t* geom, uint32_t primID) { assert(primID < geom->quadCount); return *(ze_rtas_quad_indices_uint32_exp_t*)((char*)geom->pQuadBuffer + uint64_t(primID)*geom->quadStride); } inline Vec3f getVertex(const ze_rtas_builder_quads_geometry_info_exp_t* geom, uint32_t vertexID) { assert(vertexID < geom->vertexCount); return *(Vec3f*)((char*)geom->pVertexBuffer + uint64_t(vertexID)*geom->vertexStride); } inline AffineSpace3fa getTransform(const ze_rtas_builder_instance_geometry_info_exp_t* geom) { switch (geom->transformFormat) { case ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_FLOAT3X4_COLUMN_MAJOR: { const ze_rtas_transform_float3x4_column_major_exp_t* xfm = (const ze_rtas_transform_float3x4_column_major_exp_t*) geom->pTransform; return { { xfm->vx_x, xfm->vx_y, xfm->vx_z }, { xfm->vy_x, xfm->vy_y, xfm->vy_z }, { xfm->vz_x, xfm->vz_y, xfm->vz_z }, { xfm-> p_x, xfm-> p_y, xfm-> p_z } }; } case ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_FLOAT3X4_ALIGNED_COLUMN_MAJOR: { const ze_rtas_transform_float3x4_aligned_column_major_exp_t* xfm = (const ze_rtas_transform_float3x4_aligned_column_major_exp_t*) geom->pTransform; return { { xfm->vx_x, xfm->vx_y, xfm->vx_z }, { xfm->vy_x, xfm->vy_y, xfm->vy_z }, { xfm->vz_x, xfm->vz_y, xfm->vz_z }, { xfm-> p_x, xfm-> p_y, xfm-> p_z } }; } case ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_FLOAT3X4_ROW_MAJOR: { const ze_rtas_transform_float3x4_row_major_exp_t* xfm = (const ze_rtas_transform_float3x4_row_major_exp_t*) geom->pTransform; return { { xfm->vx_x, xfm->vx_y, xfm->vx_z }, { xfm->vy_x, xfm->vy_y, xfm->vy_z }, { xfm->vz_x, xfm->vz_y, xfm->vz_z }, { xfm-> p_x, xfm-> p_y, xfm-> p_z } }; } default: throw std::runtime_error("invalid transform format"); } } inline void verifyGeometryDesc(const ze_rtas_builder_triangles_geometry_info_exp_t* geom) { if (geom->triangleFormat != ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_TRIANGLE_INDICES_UINT32) throw std::runtime_error("triangle format must be ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_TRIANGLE_INDICES_UINT32"); if (geom->vertexFormat != ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_FLOAT3) throw std::runtime_error("vertex format must be ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_FLOAT3"); if (geom->triangleCount && geom->pTriangleBuffer == nullptr) throw std::runtime_error("no triangle buffer specified"); if (geom->vertexCount && geom->pVertexBuffer == nullptr) throw std::runtime_error("no vertex buffer specified"); } inline void verifyGeometryDesc(const ze_rtas_builder_quads_geometry_info_exp_t* geom) { if (geom->quadFormat != ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_QUAD_INDICES_UINT32) throw std::runtime_error("quad format must be ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_QUAD_INDICES_UINT32"); if (geom->vertexFormat != ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_FLOAT3) throw std::runtime_error("vertex format must be ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_FLOAT3"); if (geom->quadCount && geom->pQuadBuffer == nullptr) throw std::runtime_error("no quad buffer specified"); if (geom->vertexCount && geom->pVertexBuffer == nullptr) throw std::runtime_error("no vertex buffer specified"); } inline void verifyGeometryDesc(const ze_rtas_builder_procedural_geometry_info_exp_t* geom) { if (geom->primCount && geom->pfnGetBoundsCb == nullptr) throw std::runtime_error("no bounds function specified"); if (geom->reserved != 0) throw std::runtime_error("reserved value must be zero"); } inline void verifyGeometryDesc(const ze_rtas_builder_instance_geometry_info_exp_t* geom) { if (geom->pTransform == nullptr) throw std::runtime_error("no instance transformation specified"); if (geom->pBounds == nullptr) throw std::runtime_error("no acceleration structure bounds specified"); if (geom->pAccelerationStructure == nullptr) throw std::runtime_error("no acceleration structure to instanciate specified"); } inline bool buildBounds(const ze_rtas_builder_triangles_geometry_info_exp_t* geom, uint32_t primID, BBox3fa& bbox, void* buildUserPtr) { if (primID >= geom->triangleCount) return false; const ze_rtas_triangle_indices_uint32_exp_t tri = getPrimitive(geom,primID); if (unlikely(tri.v0 >= geom->vertexCount)) return false; if (unlikely(tri.v1 >= geom->vertexCount)) return false; if (unlikely(tri.v2 >= geom->vertexCount)) return false; const Vec3f p0 = getVertex(geom,tri.v0); const Vec3f p1 = getVertex(geom,tri.v1); const Vec3f p2 = getVertex(geom,tri.v2); if (unlikely(!isvalid(p0))) return false; if (unlikely(!isvalid(p1))) return false; if (unlikely(!isvalid(p2))) return false; bbox = BBox3fa(min(p0,p1,p2),max(p0,p1,p2)); return true; } inline bool buildBounds(const ze_rtas_builder_quads_geometry_info_exp_t* geom, uint32_t primID, BBox3fa& bbox, void* buildUserPtr) { if (primID >= geom->quadCount) return false; const ze_rtas_quad_indices_uint32_exp_t tri = getPrimitive(geom,primID); if (unlikely(tri.v0 >= geom->vertexCount)) return false; if (unlikely(tri.v1 >= geom->vertexCount)) return false; if (unlikely(tri.v2 >= geom->vertexCount)) return false; if (unlikely(tri.v3 >= geom->vertexCount)) return false; const Vec3f p0 = getVertex(geom,tri.v0); const Vec3f p1 = getVertex(geom,tri.v1); const Vec3f p2 = getVertex(geom,tri.v2); const Vec3f p3 = getVertex(geom,tri.v3); if (unlikely(!isvalid(p0))) return false; if (unlikely(!isvalid(p1))) return false; if (unlikely(!isvalid(p2))) return false; if (unlikely(!isvalid(p3))) return false; bbox = BBox3fa(min(p0,p1,p2,p3),max(p0,p1,p2,p3)); return true; } inline bool buildBounds(const ze_rtas_builder_procedural_geometry_info_exp_t* geom, uint32_t primID, BBox3fa& bbox, void* buildUserPtr) { if (primID >= geom->primCount) return false; if (geom->pfnGetBoundsCb == nullptr) return false; BBox3f bounds; ze_rtas_geometry_aabbs_exp_cb_params_t params = { ZE_STRUCTURE_TYPE_RTAS_GEOMETRY_AABBS_EXP_CB_PARAMS }; params.primID = primID; params.primIDCount = 1; params.pGeomUserPtr = geom->pGeomUserPtr; params.pBuildUserPtr = buildUserPtr; params.pBoundsOut = (ze_rtas_aabb_exp_t*) &bounds; (geom->pfnGetBoundsCb)(¶ms); if (unlikely(!isvalid(bounds.lower))) return false; if (unlikely(!isvalid(bounds.upper))) return false; if (unlikely(bounds.empty())) return false; bbox = (BBox3f&) bounds; return true; } inline bool buildBounds(const ze_rtas_builder_instance_geometry_info_exp_t* geom, uint32_t primID, BBox3fa& bbox, void* buildUserPtr) { if (primID >= 1) return false; if (geom->pAccelerationStructure == nullptr) return false; if (geom->pTransform == nullptr) return false; const AffineSpace3fa local2world = getTransform(geom); const Vec3fa lower(geom->pBounds->lower.x,geom->pBounds->lower.y,geom->pBounds->lower.z); const Vec3fa upper(geom->pBounds->upper.x,geom->pBounds->upper.y,geom->pBounds->upper.z); const BBox3fa bounds = xfmBounds(local2world,BBox3fa(lower,upper)); if (unlikely(!isvalid(bounds.lower))) return false; if (unlikely(!isvalid(bounds.upper))) return false; if (unlikely(bounds.empty())) return false; bbox = bounds; return true; } template PrimInfo createGeometryPrimRefArray(const GeometryType* geom, void* buildUserPtr, evector& prims, const range& r, size_t k, unsigned int geomID) { PrimInfo pinfo(empty); for (uint32_t primID=r.begin(); primIDpNext == nullptr) return true; desc = (zet_base_desc_t_*) desc->pNext; } return false; } struct ze_rtas_builder { ze_rtas_builder () { } ~ze_rtas_builder() { magick = 0x0; } bool verify() const { return magick == MAGICK; } enum { MAGICK = 0x45FE67E1 }; uint32_t magick = MAGICK; }; ze_result_t validate(ze_rtas_builder_exp_handle_t hBuilder) { if (hBuilder == nullptr) return ZE_RESULT_ERROR_INVALID_NULL_HANDLE; if (!((ze_rtas_builder*)hBuilder)->verify()) return ZE_RESULT_ERROR_INVALID_ARGUMENT; return ZE_RESULT_SUCCESS; } struct ze_rtas_parallel_operation_t { ze_rtas_parallel_operation_t() { } ~ze_rtas_parallel_operation_t() { magick = 0x0; } ze_result_t verify() const { if (magick != MAGICK) return ZE_RESULT_ERROR_INVALID_ARGUMENT; return ZE_RESULT_SUCCESS; } enum { MAGICK = 0xE84567E1 }; uint32_t magick = MAGICK; std::atomic object_in_use = false; ze_result_t errorCode = ZE_RESULT_SUCCESS; tbb::task_group group; }; ze_result_t validate(ze_rtas_parallel_operation_exp_handle_t hParallelOperation) { if (hParallelOperation == nullptr) return ZE_RESULT_ERROR_INVALID_NULL_HANDLE; return ((ze_rtas_parallel_operation_t*)hParallelOperation)->verify(); } ze_result_t validate(const ze_rtas_builder_exp_desc_t* pDescriptor) { if (pDescriptor == nullptr) return ZE_RESULT_ERROR_INVALID_NULL_POINTER; if (pDescriptor->stype != ZE_STRUCTURE_TYPE_RTAS_BUILDER_EXP_DESC) return ZE_RESULT_ERROR_INVALID_ENUMERATION; if (!checkDescChain((zet_base_desc_t_*)pDescriptor)) return ZE_RESULT_ERROR_INVALID_ENUMERATION; if (uint32_t(ZE_RTAS_BUILDER_EXP_VERSION_CURRENT) < uint32_t(pDescriptor->builderVersion)) return ZE_RESULT_ERROR_INVALID_ENUMERATION; return ZE_RESULT_SUCCESS; } ze_result_t validate(ze_rtas_device_exp_properties_t* pProperties) { if (pProperties == nullptr) return ZE_RESULT_ERROR_INVALID_NULL_POINTER; if (pProperties->stype != ZE_STRUCTURE_TYPE_RTAS_DEVICE_EXP_PROPERTIES) return ZE_RESULT_ERROR_INVALID_ENUMERATION; if (!checkDescChain((zet_base_desc_t_*)pProperties)) return ZE_RESULT_ERROR_INVALID_ENUMERATION; return ZE_RESULT_SUCCESS; } ze_result_t validate(ze_rtas_format_exp_t rtasFormat) { if (rtasFormat == ZE_RTAS_FORMAT_EXP_INVALID) return ZE_RESULT_ERROR_INVALID_ENUMERATION; if (uint32_t(rtasFormat) > uint32_t(ZE_RTAS_DEVICE_FORMAT_EXP_VERSION_MAX)) return ZE_RESULT_ERROR_INVALID_ENUMERATION; return ZE_RESULT_SUCCESS; } ze_result_t validate(const ze_rtas_builder_build_op_exp_desc_t* args) { /* check for valid pointers */ if (args == nullptr) return ZE_RESULT_ERROR_INVALID_NULL_POINTER; /* check if input descriptor has proper type */ if (args->stype != ZE_STRUCTURE_TYPE_RTAS_BUILDER_BUILD_OP_EXP_DESC) return ZE_RESULT_ERROR_INVALID_ENUMERATION; /* check valid pNext chain */ if (!checkDescChain((zet_base_desc_t_*)args)) return ZE_RESULT_ERROR_INVALID_ENUMERATION; /* check if acceleration structure format is supported */ VALIDATE(args->rtasFormat); /* check for valid geometries array */ if (args->ppGeometries == nullptr && args->numGeometries > 0) return ZE_RESULT_ERROR_INVALID_NULL_POINTER; /* validate that number of geometries are in range */ if (args->numGeometries > 0x00FFFFFF) return ZE_RESULT_ERROR_INVALID_ENUMERATION; /* validate build quality */ if (args->buildQuality < 0 || ZE_RTAS_BUILDER_BUILD_QUALITY_HINT_EXP_HIGH < args->buildQuality) return ZE_RESULT_ERROR_INVALID_ENUMERATION; /* validate build flags */ if (args->buildFlags >= (ZE_RTAS_BUILDER_BUILD_OP_EXP_FLAG_NO_DUPLICATE_ANYHIT_INVOCATION<<1)) return ZE_RESULT_ERROR_INVALID_ENUMERATION; return ZE_RESULT_SUCCESS; } ze_result_t validate(ze_rtas_builder_exp_properties_t* pProp) { /* check for valid pointers */ if (pProp == nullptr) return ZE_RESULT_ERROR_INVALID_NULL_POINTER; /* check if return property has proper type */ if (pProp->stype != ZE_STRUCTURE_TYPE_RTAS_BUILDER_EXP_PROPERTIES) return ZE_RESULT_ERROR_INVALID_ENUMERATION; /* check valid pNext chain */ if (!checkDescChain((zet_base_desc_t_*)pProp)) return ZE_RESULT_ERROR_INVALID_ENUMERATION; return ZE_RESULT_SUCCESS; } ze_result_t validate(ze_rtas_parallel_operation_exp_properties_t* pProperties) { /* check for valid pointer */ if (pProperties == nullptr) return ZE_RESULT_ERROR_INVALID_NULL_POINTER; /* check for proper property */ if (pProperties->stype != ZE_STRUCTURE_TYPE_RTAS_PARALLEL_OPERATION_EXP_PROPERTIES) return ZE_RESULT_ERROR_INVALID_ENUMERATION; /* check valid pNext chain */ if (!checkDescChain((zet_base_desc_t_*)pProperties)) return ZE_RESULT_ERROR_INVALID_ENUMERATION; return ZE_RESULT_SUCCESS; } RTHWIF_API_EXPORT ze_result_t ZE_APICALL zeRTASBuilderCreateExpImpl(ze_driver_handle_t hDriver, const ze_rtas_builder_exp_desc_t *pDescriptor, ze_rtas_builder_exp_handle_t *phBuilder) { /* input validation */ VALIDATE(hDriver); VALIDATE(pDescriptor); VALIDATE_PTR(phBuilder); *phBuilder = (ze_rtas_builder_exp_handle_t) new ze_rtas_builder(); return ZE_RESULT_SUCCESS; } RTHWIF_API_EXPORT ze_result_t ZE_APICALL zeRTASBuilderDestroyExpImpl(ze_rtas_builder_exp_handle_t hBuilder) { VALIDATE(hBuilder); delete (ze_rtas_builder*) hBuilder; return ZE_RESULT_SUCCESS; } RTHWIF_API_EXPORT ze_result_t ZE_APICALL zeDriverRTASFormatCompatibilityCheckExpImpl( ze_driver_handle_t hDriver, const ze_rtas_format_exp_t accelFormat, const ze_rtas_format_exp_t otherAccelFormat ) { /* input validation */ VALIDATE(hDriver); VALIDATE(accelFormat); VALIDATE(otherAccelFormat); /* check if rtas formats are compatible */ if (accelFormat == otherAccelFormat) return ZE_RESULT_SUCCESS; /* report incompatible format */ return ZE_RESULT_EXP_ERROR_OPERANDS_INCOMPATIBLE; } uint32_t getNumPrimitives(const ze_rtas_builder_geometry_info_exp_t* geom) { switch (geom->geometryType) { case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_TRIANGLES : return ((ze_rtas_builder_triangles_geometry_info_exp_t*) geom)->triangleCount; case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL : return ((ze_rtas_builder_procedural_geometry_info_exp_t*) geom)->primCount; case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_QUADS : return ((ze_rtas_builder_quads_geometry_info_exp_t*) geom)->quadCount; case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_INSTANCE : return 1; default : return 0; }; } RTHWIF_API_EXPORT ze_result_t ZE_APICALL zeRTASBuilderGetBuildPropertiesExpImpl(ze_rtas_builder_exp_handle_t hBuilder, const ze_rtas_builder_build_op_exp_desc_t* args, ze_rtas_builder_exp_properties_t* pProp) { /* input validation */ VALIDATE(hBuilder); VALIDATE(args); VALIDATE(pProp); const ze_rtas_builder_geometry_info_exp_t** geometries = args->ppGeometries; const size_t numGeometries = args->numGeometries; auto getSize = [&](uint32_t geomID) -> size_t { const ze_rtas_builder_geometry_info_exp_t* geom = geometries[geomID]; if (geom == nullptr) return 0; return getNumPrimitives(geom); }; auto getType = [&](unsigned int geomID) { const ze_rtas_builder_geometry_info_exp_t* geom = geometries[geomID]; assert(geom); switch (geom->geometryType) { case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_TRIANGLES : return QBVH6BuilderSAH::TRIANGLE; case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_QUADS: return QBVH6BuilderSAH::QUAD; case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL: return QBVH6BuilderSAH::PROCEDURAL; case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_INSTANCE: return QBVH6BuilderSAH::INSTANCE; default: throw std::runtime_error("invalid geometry type"); }; }; /* query memory requirements from builder */ size_t expectedBytes = 0; size_t worstCaseBytes = 0; size_t scratchBytes = 0; QBVH6BuilderSAH::estimateSize(numGeometries, getSize, getType, args->rtasFormat, args->buildQuality, args->buildFlags, expectedBytes, worstCaseBytes, scratchBytes); /* fill return struct */ pProp->flags = 0; pProp->rtasBufferSizeBytesExpected = expectedBytes; pProp->rtasBufferSizeBytesMaxRequired = worstCaseBytes; pProp->scratchBufferSizeBytes = scratchBytes; return ZE_RESULT_SUCCESS; } ze_result_t zeRTASBuilderBuildExpBody(const ze_rtas_builder_build_op_exp_desc_t* args, void *pScratchBuffer, size_t scratchBufferSizeBytes, void *pRtasBuffer, size_t rtasBufferSizeBytes, void *pBuildUserPtr, ze_rtas_aabb_exp_t *pBounds, size_t *pRtasBufferSizeBytes) try { const ze_rtas_builder_geometry_info_exp_t** geometries = args->ppGeometries; const uint32_t numGeometries = args->numGeometries; /* verify input descriptors */ parallel_for(numGeometries,[&](uint32_t geomID) { const ze_rtas_builder_geometry_info_exp_t* geom = geometries[geomID]; if (geom == nullptr) return; switch (geom->geometryType) { case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_TRIANGLES : verifyGeometryDesc((ze_rtas_builder_triangles_geometry_info_exp_t*)geom); break; case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_QUADS : verifyGeometryDesc((ze_rtas_builder_quads_geometry_info_exp_t* )geom); break; case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL : verifyGeometryDesc((ze_rtas_builder_procedural_geometry_info_exp_t*)geom); break; case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_INSTANCE : verifyGeometryDesc((ze_rtas_builder_instance_geometry_info_exp_t* )geom); break; default: throw std::runtime_error("invalid geometry type"); }; }); auto getSize = [&](uint32_t geomID) -> size_t { const ze_rtas_builder_geometry_info_exp_t* geom = geometries[geomID]; if (geom == nullptr) return 0; return getNumPrimitives(geom); }; auto getType = [&](unsigned int geomID) { const ze_rtas_builder_geometry_info_exp_t* geom = geometries[geomID]; assert(geom); switch (geom->geometryType) { case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_TRIANGLES : return QBVH6BuilderSAH::TRIANGLE; case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_QUADS: return QBVH6BuilderSAH::QUAD; case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL: return QBVH6BuilderSAH::PROCEDURAL; case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_INSTANCE: return QBVH6BuilderSAH::INSTANCE; default: throw std::runtime_error("invalid geometry type"); }; }; auto createPrimRefArray = [&] (evector& prims, BBox1f time_range, const range& r, size_t k, unsigned int geomID) -> PrimInfo { const ze_rtas_builder_geometry_info_exp_t* geom = geometries[geomID]; assert(geom); switch (geom->geometryType) { case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_TRIANGLES : return createGeometryPrimRefArray((ze_rtas_builder_triangles_geometry_info_exp_t*)geom,pBuildUserPtr,prims,r,k,geomID); case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_QUADS : return createGeometryPrimRefArray((ze_rtas_builder_quads_geometry_info_exp_t* )geom,pBuildUserPtr,prims,r,k,geomID); case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL: return createGeometryPrimRefArray((ze_rtas_builder_procedural_geometry_info_exp_t*)geom,pBuildUserPtr,prims,r,k,geomID); case ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_INSTANCE: return createGeometryPrimRefArray((ze_rtas_builder_instance_geometry_info_exp_t* )geom,pBuildUserPtr,prims,r,k,geomID); default: throw std::runtime_error("invalid geometry type"); }; }; auto convertGeometryFlags = [&] (ze_rtas_builder_packed_geometry_exp_flags_t flags) -> GeometryFlags { return (flags & ZE_RTAS_BUILDER_GEOMETRY_EXP_FLAG_NON_OPAQUE) ? GeometryFlags::NONE : GeometryFlags::OPAQUE; }; auto getTriangle = [&](unsigned int geomID, unsigned int primID) { const ze_rtas_builder_triangles_geometry_info_exp_t* geom = (const ze_rtas_builder_triangles_geometry_info_exp_t*) geometries[geomID]; assert(geom); const ze_rtas_triangle_indices_uint32_exp_t tri = getPrimitive(geom,primID); if (unlikely(tri.v0 >= geom->vertexCount)) return QBVH6BuilderSAH::Triangle(); if (unlikely(tri.v1 >= geom->vertexCount)) return QBVH6BuilderSAH::Triangle(); if (unlikely(tri.v2 >= geom->vertexCount)) return QBVH6BuilderSAH::Triangle(); const Vec3f p0 = getVertex(geom,tri.v0); const Vec3f p1 = getVertex(geom,tri.v1); const Vec3f p2 = getVertex(geom,tri.v2); if (unlikely(!isvalid(p0))) return QBVH6BuilderSAH::Triangle(); if (unlikely(!isvalid(p1))) return QBVH6BuilderSAH::Triangle(); if (unlikely(!isvalid(p2))) return QBVH6BuilderSAH::Triangle(); const GeometryFlags gflags = convertGeometryFlags(geom->geometryFlags); return QBVH6BuilderSAH::Triangle(tri.v0,tri.v1,tri.v2,p0,p1,p2,gflags,geom->geometryMask); }; auto getTriangleIndices = [&] (uint32_t geomID, uint32_t primID) { const ze_rtas_builder_triangles_geometry_info_exp_t* geom = (const ze_rtas_builder_triangles_geometry_info_exp_t*) geometries[geomID]; assert(geom); const ze_rtas_triangle_indices_uint32_exp_t tri = getPrimitive(geom,primID); return Vec3(tri.v0,tri.v1,tri.v2); }; auto getQuad = [&](unsigned int geomID, unsigned int primID) { const ze_rtas_builder_quads_geometry_info_exp_t* geom = (const ze_rtas_builder_quads_geometry_info_exp_t*) geometries[geomID]; assert(geom); const ze_rtas_quad_indices_uint32_exp_t quad = getPrimitive(geom,primID); const Vec3f p0 = getVertex(geom,quad.v0); const Vec3f p1 = getVertex(geom,quad.v1); const Vec3f p2 = getVertex(geom,quad.v2); const Vec3f p3 = getVertex(geom,quad.v3); const GeometryFlags gflags = convertGeometryFlags(geom->geometryFlags); return QBVH6BuilderSAH::Quad(p0,p1,p2,p3,gflags,geom->geometryMask); }; auto getProcedural = [&](unsigned int geomID, unsigned int primID) { const ze_rtas_builder_procedural_geometry_info_exp_t* geom = (const ze_rtas_builder_procedural_geometry_info_exp_t*) geometries[geomID]; assert(geom); return QBVH6BuilderSAH::Procedural(geom->geometryMask); // FIXME: pass gflags }; auto getInstance = [&](unsigned int geomID, unsigned int primID) { assert(geometries[geomID]); assert(geometries[geomID]->geometryType == ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_INSTANCE); const ze_rtas_builder_instance_geometry_info_exp_t* geom = (const ze_rtas_builder_instance_geometry_info_exp_t*) geometries[geomID]; void* accel = geom->pAccelerationStructure; const AffineSpace3fa local2world = getTransform(geom); return QBVH6BuilderSAH::Instance(local2world,accel,geom->geometryMask,geom->instanceUserID); // FIXME: pass instance flags }; /* dispatch globals ptr for debugging purposes */ void* dispatchGlobalsPtr = nullptr; #if defined(EMBREE_SYCL_ALLOC_DISPATCH_GLOBALS) if (args->pNext) { zet_base_desc_t_* next = (zet_base_desc_t_*) args->pNext; if (next->stype == ZE_STRUCTURE_TYPE_RTAS_BUILDER_BUILD_OP_DEBUG_EXP_DESC) { ze_rtas_builder_build_op_debug_exp_desc_t* debug_ext = (ze_rtas_builder_build_op_debug_exp_desc_t*) next; dispatchGlobalsPtr = debug_ext->dispatchGlobalsPtr; } } #endif bool verbose = false; bool success = QBVH6BuilderSAH::build(numGeometries, nullptr, getSize, getType, createPrimRefArray, getTriangle, getTriangleIndices, getQuad, getProcedural, getInstance, (char*)pRtasBuffer, rtasBufferSizeBytes, pScratchBuffer, scratchBufferSizeBytes, (BBox3f*) pBounds, pRtasBufferSizeBytes, args->rtasFormat, args->buildQuality, args->buildFlags, verbose, dispatchGlobalsPtr); if (!success) { return ZE_RESULT_EXP_RTAS_BUILD_RETRY; } return ZE_RESULT_SUCCESS; } catch (std::exception& e) { //std::cerr << "caught exception during BVH build: " << e.what() << std::endl; return ZE_RESULT_ERROR_UNKNOWN; } RTHWIF_API_EXPORT ze_result_t ZE_APICALL zeRTASBuilderBuildExpImpl(ze_rtas_builder_exp_handle_t hBuilder, const ze_rtas_builder_build_op_exp_desc_t* args, void *pScratchBuffer, size_t scratchBufferSizeBytes, void *pRtasBuffer, size_t rtasBufferSizeBytes, ze_rtas_parallel_operation_exp_handle_t hParallelOperation, void *pBuildUserPtr, ze_rtas_aabb_exp_t *pBounds, size_t *pRtasBufferSizeBytes) { /* input validation */ VALIDATE(hBuilder); VALIDATE(args); VALIDATE_PTR(pScratchBuffer); VALIDATE_PTR(pRtasBuffer); /* if parallel operation is provided then execute using thread arena inside task group ... */ if (hParallelOperation) { VALIDATE(hParallelOperation); ze_rtas_parallel_operation_t* op = (ze_rtas_parallel_operation_t*) hParallelOperation; if (op->object_in_use.load()) return ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE; op->object_in_use.store(true); g_arena.execute([&](){ op->group.run([=](){ op->errorCode = zeRTASBuilderBuildExpBody(args, pScratchBuffer, scratchBufferSizeBytes, pRtasBuffer, rtasBufferSizeBytes, pBuildUserPtr, pBounds, pRtasBufferSizeBytes); }); }); return ZE_RESULT_EXP_RTAS_BUILD_DEFERRED; } /* ... otherwise we just execute inside task arena to avoid spawning of TBB worker threads */ else { ze_result_t errorCode = ZE_RESULT_SUCCESS; g_arena.execute([&](){ errorCode = zeRTASBuilderBuildExpBody(args, pScratchBuffer, scratchBufferSizeBytes, pRtasBuffer, rtasBufferSizeBytes, pBuildUserPtr, pBounds, pRtasBufferSizeBytes); }); return errorCode; } } RTHWIF_API_EXPORT ze_result_t ZE_APICALL zeRTASParallelOperationCreateExpImpl(ze_driver_handle_t hDriver, ze_rtas_parallel_operation_exp_handle_t* phParallelOperation) { /* input validation */ VALIDATE(hDriver); VALIDATE_PTR(phParallelOperation); /* create parallel operation object */ *phParallelOperation = (ze_rtas_parallel_operation_exp_handle_t) new ze_rtas_parallel_operation_t(); return ZE_RESULT_SUCCESS; } RTHWIF_API_EXPORT ze_result_t ZE_APICALL zeRTASParallelOperationDestroyExpImpl( ze_rtas_parallel_operation_exp_handle_t hParallelOperation ) { /* input validation */ VALIDATE(hParallelOperation); /* delete parallel operation */ delete (ze_rtas_parallel_operation_t*) hParallelOperation; return ZE_RESULT_SUCCESS; } RTHWIF_API_EXPORT ze_result_t ZE_APICALL zeRTASParallelOperationGetPropertiesExpImpl( ze_rtas_parallel_operation_exp_handle_t hParallelOperation, ze_rtas_parallel_operation_exp_properties_t* pProperties ) { /* input validation */ VALIDATE(hParallelOperation); VALIDATE(pProperties); ze_rtas_parallel_operation_t* op = (ze_rtas_parallel_operation_t*) hParallelOperation; if (!op->object_in_use.load()) return ZE_RESULT_ERROR_INVALID_ARGUMENT; /* return properties */ pProperties->flags = 0; pProperties->maxConcurrency = tbb::this_task_arena::max_concurrency(); return ZE_RESULT_SUCCESS; } RTHWIF_API_EXPORT ze_result_t ZE_APICALL zeRTASParallelOperationJoinExpImpl( ze_rtas_parallel_operation_exp_handle_t hParallelOperation) { /* check for valid handle */ VALIDATE(hParallelOperation); ze_rtas_parallel_operation_t* op = (ze_rtas_parallel_operation_t*) hParallelOperation; g_arena.execute([&](){ op->group.wait(); }); op->object_in_use.store(false); // this is slighty too early return op->errorCode; } } level-zero-raytracing-support-1.0.0/rtbuild/rtbuild.h000066400000000000000000000067731450534701400227520ustar00rootroot00000000000000// Copyright 2009-2022 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include #include #include "level_zero/ze_wrapper.h" #if defined(__cplusplus) # define RTHWIF_API_EXTERN_C extern "C" #else # define RTHWIF_API_EXTERN_C #endif #if defined(_WIN32) #if defined(EMBREE_RTHWIF_STATIC_LIB) # define RTHWIF_API_IMPORT RTHWIF_API_EXTERN_C # define RTHWIF_API_EXPORT RTHWIF_API_EXTERN_C #else # define RTHWIF_API_IMPORT RTHWIF_API_EXTERN_C __declspec(dllimport) # define RTHWIF_API_EXPORT RTHWIF_API_EXTERN_C __declspec(dllexport) #endif #else # define RTHWIF_API_IMPORT RTHWIF_API_EXTERN_C # define RTHWIF_API_EXPORT RTHWIF_API_EXTERN_C __attribute__ ((visibility ("default"))) #endif typedef enum _ze_raytracing_accel_format_internal_t { ZE_RTAS_DEVICE_FORMAT_EXP_INVALID = 0, // invalid acceleration structure format ZE_RTAS_DEVICE_FORMAT_EXP_VERSION_1 = 1, // acceleration structure format version 1 ZE_RTAS_DEVICE_FORMAT_EXP_VERSION_2 = 2, // acceleration structure format version 2 ZE_RTAS_DEVICE_FORMAT_EXP_VERSION_MAX = 2 } ze_raytracing_accel_format_internal_t; RTHWIF_API_EXPORT ze_result_t ZE_APICALL zeRTASBuilderCreateExpImpl(ze_driver_handle_t hDriver, const ze_rtas_builder_exp_desc_t *pDescriptor, ze_rtas_builder_exp_handle_t *phBuilder); RTHWIF_API_EXPORT ze_result_t ZE_APICALL zeRTASBuilderDestroyExpImpl(ze_rtas_builder_exp_handle_t hBuilder); RTHWIF_API_EXPORT ze_result_t ZE_APICALL zeDriverRTASFormatCompatibilityCheckExpImpl( ze_driver_handle_t hDriver, const ze_rtas_format_exp_t accelFormat, const ze_rtas_format_exp_t otherAccelFormat); RTHWIF_API_EXPORT ze_result_t ZE_APICALL zeRTASBuilderGetBuildPropertiesExpImpl(ze_rtas_builder_exp_handle_t hBuilder, const ze_rtas_builder_build_op_exp_desc_t* args, ze_rtas_builder_exp_properties_t* pProp); RTHWIF_API_EXPORT ze_result_t ZE_APICALL zeRTASBuilderBuildExpImpl(ze_rtas_builder_exp_handle_t hBuilder, const ze_rtas_builder_build_op_exp_desc_t* args, void *pScratchBuffer, size_t scratchBufferSizeBytes, void *pRtasBuffer, size_t rtasBufferSizeBytes, ze_rtas_parallel_operation_exp_handle_t hParallelOperation, void *pBuildUserPtr, ze_rtas_aabb_exp_t *pBounds, size_t *pRtasBufferSizeBytes); RTHWIF_API_EXPORT ze_result_t ZE_APICALL zeRTASParallelOperationCreateExpImpl(ze_driver_handle_t hDriver, ze_rtas_parallel_operation_exp_handle_t* phParallelOperation); RTHWIF_API_EXPORT ze_result_t ZE_APICALL zeRTASParallelOperationDestroyExpImpl( ze_rtas_parallel_operation_exp_handle_t hParallelOperation ); RTHWIF_API_EXPORT ze_result_t ZE_APICALL zeRTASParallelOperationGetPropertiesExpImpl( ze_rtas_parallel_operation_exp_handle_t hParallelOperation, ze_rtas_parallel_operation_exp_properties_t* pProperties ); RTHWIF_API_EXPORT ze_result_t ZE_APICALL zeRTASParallelOperationJoinExpImpl( ze_rtas_parallel_operation_exp_handle_t hParallelOperation); level-zero-raytracing-support-1.0.0/rtbuild/simd/000077500000000000000000000000001450534701400220535ustar00rootroot00000000000000level-zero-raytracing-support-1.0.0/rtbuild/simd/CMakeLists.txt000066400000000000000000000007171450534701400246200ustar00rootroot00000000000000## Copyright 2009-2021 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 ADD_LIBRARY(simd STATIC sse.cpp) SET_PROPERTY(TARGET simd PROPERTY FOLDER common) SET_PROPERTY(TARGET simd APPEND PROPERTY COMPILE_FLAGS " ${FLAGS_LOWEST}") IF (EMBREE_STATIC_LIB) INSTALL(TARGETS simd EXPORT simd-targets ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT devel) INSTALL(EXPORT simd-targets DESTINATION "${EMBREE_CMAKEEXPORT_DIR}" COMPONENT devel) ENDIF() level-zero-raytracing-support-1.0.0/rtbuild/simd/simd.h000066400000000000000000000061221450534701400231610ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "../math/emath.h" /* include SSE wrapper classes */ #if defined(__SSE__) || defined(__ARM_NEON) # include "sse.h" #endif /* include AVX wrapper classes */ #if defined(__AVX__) # include "avx.h" #endif /* include AVX512 wrapper classes */ #if defined (__AVX512F__) # include "avx512.h" #endif namespace embree { template __forceinline vbool isfinite(const vfloat& v) { return (v >= vfloat(-std::numeric_limits::max())) & (v <= vfloat( std::numeric_limits::max())); } /* foreach unique */ template __forceinline void foreach_unique(const vbool& valid0, const vint& vi, const Closure& closure) { vbool valid1 = valid0; while (any(valid1)) { const int j = int(bsf(movemask(valid1))); const int i = vi[j]; const vbool valid2 = valid1 & (i == vi); valid1 = andn(valid1, valid2); closure(valid2, i); } } /* returns the next unique value i in vi and the corresponding valid_i mask */ template __forceinline int next_unique(vbool& valid, const vint& vi, /*out*/ vbool& valid_i) { assert(any(valid)); const int j = int(bsf(movemask(valid))); const int i = vi[j]; valid_i = valid & (i == vi); valid = andn(valid, valid_i); return i; } /* foreach unique index */ template __forceinline void foreach_unique_index(const vbool& valid0, const vint& vi, const Closure& closure) { vbool valid1 = valid0; while (any(valid1)) { const int j = int(bsf(movemask(valid1))); const int i = vi[j]; const vbool valid2 = valid1 & (i == vi); valid1 = andn(valid1, valid2); closure(valid2, i, j); } } /* returns the index of the next unique value i in vi and the corresponding valid_i mask */ template __forceinline int next_unique_index(vbool& valid, const vint& vi, /*out*/ vbool& valid_i) { assert(any(valid)); const int j = int(bsf(movemask(valid))); const int i = vi[j]; valid_i = valid & (i == vi); valid = andn(valid, valid_i); return j; } template __forceinline void foreach2(int x0, int x1, int y0, int y1, const Closure& closure) { __aligned(64) int U[2*VSIZEX]; __aligned(64) int V[2*VSIZEX]; int index = 0; for (int y=y0; y=y1; const vintx vy = y; for (int x=x0; x= x1; vintx vx = x+vintx(step); vintx::storeu(&U[index], vx); vintx::storeu(&V[index], vy); const int dx = min(x1-x,VSIZEX); index += dx; x += dx; if (index >= VSIZEX || (lastx && lasty)) { const vboolx valid = vintx(step) < vintx(index); closure(valid, vintx::load(U), vintx::load(V)); x-= max(0, index-VSIZEX); index = 0; } } } } } level-zero-raytracing-support-1.0.0/rtbuild/simd/sse.cpp000066400000000000000000000022731450534701400233550ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "sse.h" namespace embree { const __m128 mm_lookupmask_ps[16] = { _mm_castsi128_ps(_mm_set_epi32( 0, 0, 0, 0)), _mm_castsi128_ps(_mm_set_epi32( 0, 0, 0,-1)), _mm_castsi128_ps(_mm_set_epi32( 0, 0,-1, 0)), _mm_castsi128_ps(_mm_set_epi32( 0, 0,-1,-1)), _mm_castsi128_ps(_mm_set_epi32( 0,-1, 0, 0)), _mm_castsi128_ps(_mm_set_epi32( 0,-1, 0,-1)), _mm_castsi128_ps(_mm_set_epi32( 0,-1,-1, 0)), _mm_castsi128_ps(_mm_set_epi32( 0,-1,-1,-1)), _mm_castsi128_ps(_mm_set_epi32(-1, 0, 0, 0)), _mm_castsi128_ps(_mm_set_epi32(-1, 0, 0,-1)), _mm_castsi128_ps(_mm_set_epi32(-1, 0,-1, 0)), _mm_castsi128_ps(_mm_set_epi32(-1, 0,-1,-1)), _mm_castsi128_ps(_mm_set_epi32(-1,-1, 0, 0)), _mm_castsi128_ps(_mm_set_epi32(-1,-1, 0,-1)), _mm_castsi128_ps(_mm_set_epi32(-1,-1,-1, 0)), _mm_castsi128_ps(_mm_set_epi32(-1,-1,-1,-1)) }; const __m128d mm_lookupmask_pd[4] = { _mm_castsi128_pd(_mm_set_epi32( 0, 0, 0, 0)), _mm_castsi128_pd(_mm_set_epi32( 0, 0,-1,-1)), _mm_castsi128_pd(_mm_set_epi32(-1,-1, 0, 0)), _mm_castsi128_pd(_mm_set_epi32(-1,-1,-1,-1)) }; } level-zero-raytracing-support-1.0.0/rtbuild/simd/sse.h000066400000000000000000000014721450534701400230220ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "../sys/platform.h" #include "../sys/intrinsics.h" #include "../sys/alloc.h" #include "../math/constants.h" #include "varying.h" namespace embree { #if defined(__aarch64__) || defined(__SSE4_1__) __forceinline __m128 blendv_ps(__m128 f, __m128 t, __m128 mask) { return _mm_blendv_ps(f,t,mask); } #else __forceinline __m128 blendv_ps(__m128 f, __m128 t, __m128 mask) { return _mm_or_ps(_mm_and_ps(mask, t), _mm_andnot_ps(mask, f)); } #endif extern const __m128 mm_lookupmask_ps[16]; extern const __m128d mm_lookupmask_pd[4]; } #if defined(__AVX512VL__) #include "vboolf4_avx512.h" #else #include "vboolf4_sse2.h" #endif #include "vint4_sse2.h" #include "vuint4_sse2.h" #include "vfloat4_sse2.h" level-zero-raytracing-support-1.0.0/rtbuild/simd/varying.h000066400000000000000000000105431450534701400237060ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "../sys/platform.h" namespace embree { /* Varying numeric types */ template struct vfloat_impl { union { float f[N]; int i[N]; }; __forceinline const float& operator [](size_t index) const { assert(index < N); return f[index]; } __forceinline float& operator [](size_t index) { assert(index < N); return f[index]; } }; template struct vdouble_impl { union { double f[N]; long long i[N]; }; __forceinline const double& operator [](size_t index) const { assert(index < N); return f[index]; } __forceinline double& operator [](size_t index) { assert(index < N); return f[index]; } }; template struct vint_impl { int i[N]; __forceinline const int& operator [](size_t index) const { assert(index < N); return i[index]; } __forceinline int& operator [](size_t index) { assert(index < N); return i[index]; } }; template struct vuint_impl { unsigned int i[N]; __forceinline const unsigned int& operator [](size_t index) const { assert(index < N); return i[index]; } __forceinline unsigned int& operator [](size_t index) { assert(index < N); return i[index]; } }; template struct vllong_impl { long long i[N]; __forceinline const long long& operator [](size_t index) const { assert(index < N); return i[index]; } __forceinline long long& operator [](size_t index) { assert(index < N); return i[index]; } }; /* Varying bool types */ template struct vboolf_impl { int i[N]; }; // for float/int template struct vboold_impl { long long i[N]; }; // for double/long long /* Varying size constants */ #if defined(__AVX512VL__) // SKX const int VSIZEX = 8; // default size const int VSIZEL = 16; // large size #elif defined(__AVX__) const int VSIZEX = 8; const int VSIZEL = 8; #else const int VSIZEX = 4; const int VSIZEL = 4; #endif template struct vtypes { using vbool = vboolf_impl; using vboolf = vboolf_impl; using vboold = vboold_impl; using vint = vint_impl; using vuint = vuint_impl; using vllong = vllong_impl; using vfloat = vfloat_impl; using vdouble = vdouble_impl; }; template<> struct vtypes<1> { using vbool = bool; using vboolf = bool; using vboold = bool; using vint = int; using vuint = unsigned int; using vllong = long long; using vfloat = float; using vdouble = double; }; /* Aliases to default types */ template using vbool = typename vtypes::vbool; template using vboolf = typename vtypes::vboolf; template using vboold = typename vtypes::vboold; template using vint = typename vtypes::vint; template using vuint = typename vtypes::vuint; template using vllong = typename vtypes::vllong; template using vreal = typename vtypes::vfloat; template using vfloat = typename vtypes::vfloat; template using vdouble = typename vtypes::vdouble; /* 4-wide shortcuts */ typedef vfloat<4> vfloat4; typedef vdouble<4> vdouble4; typedef vreal<4> vreal4; typedef vint<4> vint4; typedef vuint<4> vuint4; typedef vllong<4> vllong4; typedef vbool<4> vbool4; typedef vboolf<4> vboolf4; typedef vboold<4> vboold4; /* 8-wide shortcuts */ typedef vfloat<8> vfloat8; typedef vdouble<8> vdouble8; typedef vreal<8> vreal8; typedef vint<8> vint8; typedef vuint<8> vuint8; typedef vllong<8> vllong8; typedef vbool<8> vbool8; typedef vboolf<8> vboolf8; typedef vboold<8> vboold8; /* 16-wide shortcuts */ typedef vfloat<16> vfloat16; typedef vdouble<16> vdouble16; typedef vreal<16> vreal16; typedef vint<16> vint16; typedef vuint<16> vuint16; typedef vllong<16> vllong16; typedef vbool<16> vbool16; typedef vboolf<16> vboolf16; typedef vboold<16> vboold16; /* Default shortcuts */ typedef vfloat vfloatx; typedef vdouble vdoublex; typedef vreal vrealx; typedef vint vintx; typedef vuint vuintx; typedef vllong vllongx; typedef vbool vboolx; typedef vboolf vboolfx; typedef vboold vbooldx; } level-zero-raytracing-support-1.0.0/rtbuild/simd/vboolf4_sse2.h000066400000000000000000000221771450534701400245440ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #define vboolf vboolf_impl #define vboold vboold_impl #define vint vint_impl #define vuint vuint_impl #define vllong vllong_impl #define vfloat vfloat_impl #define vdouble vdouble_impl namespace embree { /* 4-wide SSE bool type */ template<> struct vboolf<4> { ALIGNED_STRUCT_(16); typedef vboolf4 Bool; typedef vint4 Int; typedef vfloat4 Float; enum { size = 4 }; // number of SIMD elements union { __m128 v; int i[4]; }; // data //////////////////////////////////////////////////////////////////////////////// /// Constructors, Assignment & Cast Operators //////////////////////////////////////////////////////////////////////////////// __forceinline vboolf() {} __forceinline vboolf(const vboolf4& other) { v = other.v; } __forceinline vboolf4& operator =(const vboolf4& other) { v = other.v; return *this; } __forceinline vboolf(__m128 input) : v(input) {} __forceinline operator const __m128&() const { return v; } #if !defined(__EMSCRIPTEN__) __forceinline operator const __m128i() const { return _mm_castps_si128(v); } __forceinline operator const __m128d() const { return _mm_castps_pd(v); } #endif __forceinline vboolf(bool a) : v(mm_lookupmask_ps[(size_t(a) << 3) | (size_t(a) << 2) | (size_t(a) << 1) | size_t(a)]) {} __forceinline vboolf(bool a, bool b) : v(mm_lookupmask_ps[(size_t(b) << 3) | (size_t(a) << 2) | (size_t(b) << 1) | size_t(a)]) {} __forceinline vboolf(bool a, bool b, bool c, bool d) : v(mm_lookupmask_ps[(size_t(d) << 3) | (size_t(c) << 2) | (size_t(b) << 1) | size_t(a)]) {} __forceinline vboolf(int mask) { assert(mask >= 0 && mask < 16); v = mm_lookupmask_ps[mask]; } __forceinline vboolf(unsigned int mask) { assert(mask < 16); v = mm_lookupmask_ps[mask]; } /* return int32 mask */ __forceinline __m128i mask32() const { return _mm_castps_si128(v); } //////////////////////////////////////////////////////////////////////////////// /// Constants //////////////////////////////////////////////////////////////////////////////// __forceinline vboolf(FalseTy) : v(_mm_setzero_ps()) {} __forceinline vboolf(TrueTy) : v(_mm_castsi128_ps(_mm_cmpeq_epi32(_mm_setzero_si128(), _mm_setzero_si128()))) {} //////////////////////////////////////////////////////////////////////////////// /// Array Access //////////////////////////////////////////////////////////////////////////////// __forceinline bool operator [](size_t index) const { assert(index < 4); return (_mm_movemask_ps(v) >> index) & 1; } __forceinline int& operator [](size_t index) { assert(index < 4); return i[index]; } }; //////////////////////////////////////////////////////////////////////////////// /// Unary Operators //////////////////////////////////////////////////////////////////////////////// __forceinline vboolf4 operator !(const vboolf4& a) { return _mm_xor_ps(a, vboolf4(embree::True)); } //////////////////////////////////////////////////////////////////////////////// /// Binary Operators //////////////////////////////////////////////////////////////////////////////// __forceinline vboolf4 operator &(const vboolf4& a, const vboolf4& b) { return _mm_and_ps(a, b); } __forceinline vboolf4 operator |(const vboolf4& a, const vboolf4& b) { return _mm_or_ps (a, b); } __forceinline vboolf4 operator ^(const vboolf4& a, const vboolf4& b) { return _mm_xor_ps(a, b); } __forceinline vboolf4 andn(const vboolf4& a, const vboolf4& b) { return _mm_andnot_ps(b, a); } //////////////////////////////////////////////////////////////////////////////// /// Assignment Operators //////////////////////////////////////////////////////////////////////////////// __forceinline vboolf4& operator &=(vboolf4& a, const vboolf4& b) { return a = a & b; } __forceinline vboolf4& operator |=(vboolf4& a, const vboolf4& b) { return a = a | b; } __forceinline vboolf4& operator ^=(vboolf4& a, const vboolf4& b) { return a = a ^ b; } //////////////////////////////////////////////////////////////////////////////// /// Comparison Operators + Select //////////////////////////////////////////////////////////////////////////////// __forceinline vboolf4 operator !=(const vboolf4& a, const vboolf4& b) { return _mm_xor_ps(a, b); } __forceinline vboolf4 operator ==(const vboolf4& a, const vboolf4& b) { return _mm_castsi128_ps(_mm_cmpeq_epi32(a, b)); } __forceinline vboolf4 select(const vboolf4& m, const vboolf4& t, const vboolf4& f) { #if defined(__aarch64__) || defined(__SSE4_1__) return _mm_blendv_ps(f, t, m); #else return _mm_or_ps(_mm_and_ps(m, t), _mm_andnot_ps(m, f)); #endif } //////////////////////////////////////////////////////////////////////////////// /// Movement/Shifting/Shuffling Functions //////////////////////////////////////////////////////////////////////////////// __forceinline vboolf4 unpacklo(const vboolf4& a, const vboolf4& b) { return _mm_unpacklo_ps(a, b); } __forceinline vboolf4 unpackhi(const vboolf4& a, const vboolf4& b) { return _mm_unpackhi_ps(a, b); } #if defined(__aarch64__) template __forceinline vboolf4 shuffle(const vboolf4& v) { return vreinterpretq_f32_u8(vqtbl1q_u8( vreinterpretq_u8_s32(v), _MN_SHUFFLE(i0, i1, i2, i3))); } template __forceinline vboolf4 shuffle(const vboolf4& a, const vboolf4& b) { return vreinterpretq_f32_u8(vqtbl2q_u8( (uint8x16x2_t){(uint8x16_t)a.v, (uint8x16_t)b.v}, _MF_SHUFFLE(i0, i1, i2, i3))); } #else template __forceinline vboolf4 shuffle(const vboolf4& v) { return _mm_castsi128_ps(_mm_shuffle_epi32(v, _MM_SHUFFLE(i3, i2, i1, i0))); } template __forceinline vboolf4 shuffle(const vboolf4& a, const vboolf4& b) { return _mm_shuffle_ps(a, b, _MM_SHUFFLE(i3, i2, i1, i0)); } #endif template __forceinline vboolf4 shuffle(const vboolf4& v) { return shuffle(v); } #if defined(__SSE3__) template<> __forceinline vboolf4 shuffle<0, 0, 2, 2>(const vboolf4& v) { return _mm_moveldup_ps(v); } template<> __forceinline vboolf4 shuffle<1, 1, 3, 3>(const vboolf4& v) { return _mm_movehdup_ps(v); } template<> __forceinline vboolf4 shuffle<0, 1, 0, 1>(const vboolf4& v) { return _mm_castpd_ps(_mm_movedup_pd(v)); } #endif #if defined(__SSE4_1__) && !defined(__aarch64__) template __forceinline vboolf4 insert(const vboolf4& a, const vboolf4& b) { return _mm_insert_ps(a, b, (dst << 4) | (src << 6) | clr); } template __forceinline vboolf4 insert(const vboolf4& a, const vboolf4& b) { return insert(a, b); } template __forceinline vboolf4 insert(const vboolf4& a, const bool b) { return insert(a, vboolf4(b)); } #endif //////////////////////////////////////////////////////////////////////////////// /// Reduction Operations //////////////////////////////////////////////////////////////////////////////// __forceinline bool reduce_and(const vboolf4& a) { return _mm_movemask_ps(a) == 0xf; } __forceinline bool reduce_or (const vboolf4& a) { return _mm_movemask_ps(a) != 0x0; } __forceinline bool all (const vboolf4& b) { return _mm_movemask_ps(b) == 0xf; } __forceinline bool any (const vboolf4& b) { return _mm_movemask_ps(b) != 0x0; } __forceinline bool none(const vboolf4& b) { return _mm_movemask_ps(b) == 0x0; } __forceinline bool all (const vboolf4& valid, const vboolf4& b) { return all((!valid) | b); } __forceinline bool any (const vboolf4& valid, const vboolf4& b) { return any(valid & b); } __forceinline bool none(const vboolf4& valid, const vboolf4& b) { return none(valid & b); } __forceinline size_t movemask(const vboolf4& a) { return _mm_movemask_ps(a); } #if defined(__aarch64__) __forceinline size_t popcnt(const vboolf4& a) { return vaddvq_s32(vandq_u32(vreinterpretq_u32_f32(a.v),_mm_set1_epi32(1))); } #elif defined(__SSE4_2__) __forceinline size_t popcnt(const vboolf4& a) { return popcnt((size_t)_mm_movemask_ps(a)); } #else __forceinline size_t popcnt(const vboolf4& a) { return bool(a[0])+bool(a[1])+bool(a[2])+bool(a[3]); } #endif //////////////////////////////////////////////////////////////////////////////// /// Get/Set Functions //////////////////////////////////////////////////////////////////////////////// __forceinline bool get(const vboolf4& a, size_t index) { return a[index]; } __forceinline void set(vboolf4& a, size_t index) { a[index] = -1; } __forceinline void clear(vboolf4& a, size_t index) { a[index] = 0; } //////////////////////////////////////////////////////////////////////////////// /// Output Operators //////////////////////////////////////////////////////////////////////////////// __forceinline embree_ostream operator <<(embree_ostream cout, const vboolf4& a) { return cout << "<" << a[0] << ", " << a[1] << ", " << a[2] << ", " << a[3] << ">"; } } #undef vboolf #undef vboold #undef vint #undef vuint #undef vllong #undef vfloat #undef vdouble level-zero-raytracing-support-1.0.0/rtbuild/simd/vfloat4_sse2.h000066400000000000000000001077061450534701400245520ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #define vboolf vboolf_impl #define vboold vboold_impl #define vint vint_impl #define vuint vuint_impl #define vllong vllong_impl #define vfloat vfloat_impl #define vdouble vdouble_impl namespace embree { /* 4-wide SSE float type */ template<> struct vfloat<4> { ALIGNED_STRUCT_(16); typedef vboolf4 Bool; typedef vint4 Int; typedef vfloat4 Float; enum { size = 4 }; // number of SIMD elements union { __m128 v; float f[4]; int i[4]; }; // data //////////////////////////////////////////////////////////////////////////////// /// Constructors, Assignment & Cast Operators //////////////////////////////////////////////////////////////////////////////// __forceinline vfloat() {} __forceinline vfloat(const vfloat4& other) { v = other.v; } //__forceinline vfloat(const vfloat4& other) = default; __forceinline vfloat4& operator =(const vfloat4& other) { v = other.v; return *this; } __forceinline vfloat(__m128 a) : v(a) {} __forceinline operator const __m128&() const { return v; } __forceinline operator __m128&() { return v; } __forceinline vfloat(float a) : v(_mm_set1_ps(a)) {} __forceinline vfloat(float a, float b, float c, float d) : v(_mm_set_ps(d, c, b, a)) {} __forceinline explicit vfloat(const vint4& a) : v(_mm_cvtepi32_ps(a)) {} #if defined(__aarch64__) __forceinline explicit vfloat(const vuint4& x) { v = vcvtq_f32_u32(vreinterpretq_u32_s32(x.v)); } #else __forceinline explicit vfloat(const vuint4& x) { const __m128i a = _mm_and_si128(x,_mm_set1_epi32(0x7FFFFFFF)); const __m128i b = _mm_and_si128(_mm_srai_epi32(x,31),_mm_set1_epi32(0x4F000000)); //0x4F000000 = 2^31 const __m128 af = _mm_cvtepi32_ps(a); const __m128 bf = _mm_castsi128_ps(b); v = _mm_add_ps(af,bf); } #endif //////////////////////////////////////////////////////////////////////////////// /// Constants //////////////////////////////////////////////////////////////////////////////// __forceinline vfloat(ZeroTy) : v(_mm_setzero_ps()) {} __forceinline vfloat(OneTy) : v(_mm_set1_ps(1.0f)) {} __forceinline vfloat(PosInfTy) : v(_mm_set1_ps(pos_inf)) {} __forceinline vfloat(NegInfTy) : v(_mm_set1_ps(neg_inf)) {} __forceinline vfloat(StepTy) : v(_mm_set_ps(3.0f, 2.0f, 1.0f, 0.0f)) {} __forceinline vfloat(NaNTy) : v(_mm_set1_ps(nan)) {} __forceinline vfloat(UndefinedTy) : v(_mm_undefined_ps()) {} //////////////////////////////////////////////////////////////////////////////// /// Loads and Stores //////////////////////////////////////////////////////////////////////////////// static __forceinline vfloat4 load (const void* a) { return _mm_load_ps((float*)a); } static __forceinline vfloat4 loadu(const void* a) { return _mm_loadu_ps((float*)a); } static __forceinline void store (void* ptr, const vfloat4& v) { _mm_store_ps((float*)ptr,v); } static __forceinline void storeu(void* ptr, const vfloat4& v) { _mm_storeu_ps((float*)ptr,v); } #if defined(__AVX512VL__) static __forceinline vfloat4 load (const vboolf4& mask, const void* ptr) { return _mm_mask_load_ps (_mm_setzero_ps(),mask,(float*)ptr); } static __forceinline vfloat4 loadu(const vboolf4& mask, const void* ptr) { return _mm_mask_loadu_ps(_mm_setzero_ps(),mask,(float*)ptr); } static __forceinline void store (const vboolf4& mask, void* ptr, const vfloat4& v) { _mm_mask_store_ps ((float*)ptr,mask,v); } static __forceinline void storeu(const vboolf4& mask, void* ptr, const vfloat4& v) { _mm_mask_storeu_ps((float*)ptr,mask,v); } #elif defined(__AVX__) static __forceinline vfloat4 load (const vboolf4& mask, const void* ptr) { return _mm_maskload_ps((float*)ptr,mask); } static __forceinline vfloat4 loadu(const vboolf4& mask, const void* ptr) { return _mm_maskload_ps((float*)ptr,mask); } static __forceinline void store (const vboolf4& mask, void* ptr, const vfloat4& v) { _mm_maskstore_ps((float*)ptr,(__m128i)mask,v); } static __forceinline void storeu(const vboolf4& mask, void* ptr, const vfloat4& v) { _mm_maskstore_ps((float*)ptr,(__m128i)mask,v); } #else static __forceinline vfloat4 load (const vboolf4& mask, const void* ptr) { return _mm_and_ps(_mm_load_ps ((float*)ptr),mask); } static __forceinline vfloat4 loadu(const vboolf4& mask, const void* ptr) { return _mm_and_ps(_mm_loadu_ps((float*)ptr),mask); } static __forceinline void store (const vboolf4& mask, void* ptr, const vfloat4& v) { store (ptr,select(mask,v,load (ptr))); } static __forceinline void storeu(const vboolf4& mask, void* ptr, const vfloat4& v) { storeu(ptr,select(mask,v,loadu(ptr))); } #endif #if defined(__AVX__) static __forceinline vfloat4 broadcast(const void* a) { return _mm_broadcast_ss((float*)a); } #else static __forceinline vfloat4 broadcast(const void* a) { return _mm_set1_ps(*(float*)a); } #endif static __forceinline vfloat4 load_nt (const float* ptr) { #if defined (__SSE4_1__) return _mm_castsi128_ps(_mm_stream_load_si128((__m128i*)ptr)); #else return _mm_load_ps(ptr); #endif } #if defined(__aarch64__) static __forceinline vfloat4 load(const char* ptr) { return __m128(_mm_load4epi8_f32(((__m128i*)ptr))); } #elif defined(__SSE4_1__) static __forceinline vfloat4 load(const char* ptr) { return _mm_cvtepi32_ps(_mm_cvtepi8_epi32(_mm_loadu_si128((__m128i*)ptr))); } #else static __forceinline vfloat4 load(const char* ptr) { return vfloat4(ptr[0],ptr[1],ptr[2],ptr[3]); } #endif #if defined(__aarch64__) static __forceinline vfloat4 load(const unsigned char* ptr) { return __m128(_mm_load4epu8_f32(((__m128i*)ptr))); } #elif defined(__SSE4_1__) static __forceinline vfloat4 load(const unsigned char* ptr) { return _mm_cvtepi32_ps(_mm_cvtepu8_epi32(_mm_loadu_si128((__m128i*)ptr))); } #else static __forceinline vfloat4 load(const unsigned char* ptr) { //return _mm_cvtpu8_ps(*(__m64*)ptr); // don't enable, will use MMX instructions return vfloat4(ptr[0],ptr[1],ptr[2],ptr[3]); } #endif #if defined(__aarch64__) static __forceinline vfloat4 load(const short* ptr) { return __m128(_mm_load4epi16_f32(((__m128i*)ptr))); } #elif defined(__SSE4_1__) static __forceinline vfloat4 load(const short* ptr) { return _mm_cvtepi32_ps(_mm_cvtepi16_epi32(_mm_loadu_si128((__m128i*)ptr))); } #else static __forceinline vfloat4 load(const short* ptr) { return vfloat4(ptr[0],ptr[1],ptr[2],ptr[3]); } #endif static __forceinline vfloat4 load(const unsigned short* ptr) { return _mm_mul_ps(vfloat4(vint4::load(ptr)),vfloat4(1.0f/65535.0f)); } static __forceinline void store_nt(void* ptr, const vfloat4& v) { #if defined (__SSE4_1__) #if defined(__aarch64__) _mm_stream_ps((float*)ptr,v); #else _mm_stream_ps((float*)ptr,v); #endif #else _mm_store_ps((float*)ptr,v); #endif } template static __forceinline vfloat4 gather(const float* ptr, const vint4& index) { #if defined(__AVX2__) && !defined(__aarch64__) return _mm_i32gather_ps(ptr, index, scale); #else return vfloat4( *(float*)(((char*)ptr)+scale*index[0]), *(float*)(((char*)ptr)+scale*index[1]), *(float*)(((char*)ptr)+scale*index[2]), *(float*)(((char*)ptr)+scale*index[3])); #endif } template static __forceinline vfloat4 gather(const vboolf4& mask, const float* ptr, const vint4& index) { vfloat4 r = zero; #if defined(__AVX512VL__) return _mm_mmask_i32gather_ps(r, mask, index, ptr, scale); #elif defined(__AVX2__) && !defined(__aarch64__) return _mm_mask_i32gather_ps(r, ptr, index, mask, scale); #else if (likely(mask[0])) r[0] = *(float*)(((char*)ptr)+scale*index[0]); if (likely(mask[1])) r[1] = *(float*)(((char*)ptr)+scale*index[1]); if (likely(mask[2])) r[2] = *(float*)(((char*)ptr)+scale*index[2]); if (likely(mask[3])) r[3] = *(float*)(((char*)ptr)+scale*index[3]); return r; #endif } template static __forceinline void scatter(void* ptr, const vint4& index, const vfloat4& v) { #if defined(__AVX512VL__) _mm_i32scatter_ps((float*)ptr, index, v, scale); #else *(float*)(((char*)ptr)+scale*index[0]) = v[0]; *(float*)(((char*)ptr)+scale*index[1]) = v[1]; *(float*)(((char*)ptr)+scale*index[2]) = v[2]; *(float*)(((char*)ptr)+scale*index[3]) = v[3]; #endif } template static __forceinline void scatter(const vboolf4& mask, void* ptr, const vint4& index, const vfloat4& v) { #if defined(__AVX512VL__) _mm_mask_i32scatter_ps((float*)ptr ,mask, index, v, scale); #else if (likely(mask[0])) *(float*)(((char*)ptr)+scale*index[0]) = v[0]; if (likely(mask[1])) *(float*)(((char*)ptr)+scale*index[1]) = v[1]; if (likely(mask[2])) *(float*)(((char*)ptr)+scale*index[2]) = v[2]; if (likely(mask[3])) *(float*)(((char*)ptr)+scale*index[3]) = v[3]; #endif } static __forceinline void store(const vboolf4& mask, char* ptr, const vint4& ofs, const vfloat4& v) { scatter<1>(mask,ptr,ofs,v); } static __forceinline void store(const vboolf4& mask, float* ptr, const vint4& ofs, const vfloat4& v) { scatter<4>(mask,ptr,ofs,v); } //////////////////////////////////////////////////////////////////////////////// /// Array Access //////////////////////////////////////////////////////////////////////////////// __forceinline const float& operator [](size_t index) const { assert(index < 4); return f[index]; } __forceinline float& operator [](size_t index) { assert(index < 4); return f[index]; } friend __forceinline vfloat4 select(const vboolf4& m, const vfloat4& t, const vfloat4& f) { #if defined(__AVX512VL__) return _mm_mask_blend_ps(m, f, t); #elif defined(__SSE4_1__) || (defined(__aarch64__)) return _mm_blendv_ps(f, t, m); #else return _mm_or_ps(_mm_and_ps(m, t), _mm_andnot_ps(m, f)); #endif } }; //////////////////////////////////////////////////////////////////////////////// /// Load/Store //////////////////////////////////////////////////////////////////////////////// template<> struct mem { static __forceinline vfloat4 load (const vboolf4& mask, const void* ptr) { return vfloat4::load (mask,ptr); } static __forceinline vfloat4 loadu(const vboolf4& mask, const void* ptr) { return vfloat4::loadu(mask,ptr); } static __forceinline void store (const vboolf4& mask, void* ptr, const vfloat4& v) { vfloat4::store (mask,ptr,v); } static __forceinline void storeu(const vboolf4& mask, void* ptr, const vfloat4& v) { vfloat4::storeu(mask,ptr,v); } }; //////////////////////////////////////////////////////////////////////////////// /// Unary Operators //////////////////////////////////////////////////////////////////////////////// __forceinline vfloat4 asFloat(const vint4& a) { return _mm_castsi128_ps(a); } __forceinline vint4 asInt (const vfloat4& a) { return _mm_castps_si128(a); } __forceinline vuint4 asUInt (const vfloat4& a) { return _mm_castps_si128(a); } __forceinline vint4 toInt (const vfloat4& a) { return vint4(a); } __forceinline vfloat4 toFloat(const vint4& a) { return vfloat4(a); } __forceinline vfloat4 operator +(const vfloat4& a) { return a; } #if defined(__aarch64__) __forceinline vfloat4 operator -(const vfloat4& a) { return vnegq_f32(a); } #else __forceinline vfloat4 operator -(const vfloat4& a) { return _mm_xor_ps(a, _mm_castsi128_ps(_mm_set1_epi32(0x80000000))); } #endif #if defined(__aarch64__) __forceinline vfloat4 abs(const vfloat4& a) { return _mm_abs_ps(a); } #else __forceinline vfloat4 abs(const vfloat4& a) { return _mm_and_ps(a, _mm_castsi128_ps(_mm_set1_epi32(0x7fffffff))); } #endif #if defined(__AVX512VL__) __forceinline vfloat4 sign(const vfloat4& a) { return _mm_mask_blend_ps(_mm_cmp_ps_mask(a, vfloat4(zero), _CMP_LT_OQ), vfloat4(one), -vfloat4(one)); } #else __forceinline vfloat4 sign(const vfloat4& a) { return blendv_ps(vfloat4(one), -vfloat4(one), _mm_cmplt_ps(a, vfloat4(zero))); } #endif __forceinline vfloat4 signmsk(const vfloat4& a) { return _mm_and_ps(a,_mm_castsi128_ps(_mm_set1_epi32(0x80000000))); } __forceinline vfloat4 rcp(const vfloat4& a) { #if defined(__aarch64__) return vfloat4(vdivq_f32(vdupq_n_f32(1.0f),a.v)); #else #if defined(__AVX512VL__) const vfloat4 r = _mm_rcp14_ps(a); #else const vfloat4 r = _mm_rcp_ps(a); #endif #if defined(__AVX2__) return _mm_fmadd_ps(r, _mm_fnmadd_ps(a, r, vfloat4(1.0f)), r); // computes r + r * (1 - a * r) #else return _mm_add_ps(r,_mm_mul_ps(r, _mm_sub_ps(vfloat4(1.0f), _mm_mul_ps(a, r)))); // computes r + r * (1 - a * r) #endif #endif //defined(__aarch64__) } __forceinline vfloat4 sqr (const vfloat4& a) { return _mm_mul_ps(a,a); } __forceinline vfloat4 sqrt(const vfloat4& a) { return _mm_sqrt_ps(a); } __forceinline vfloat4 rsqrt(const vfloat4& a) { #if defined(__aarch64__) vfloat4 r = _mm_rsqrt_ps(a); r = vmulq_f32(r, vrsqrtsq_f32(vmulq_f32(a, r), r)); r = vmulq_f32(r, vrsqrtsq_f32(vmulq_f32(a, r), r)); r = vmulq_f32(r, vrsqrtsq_f32(vmulq_f32(a, r), r)); return r; #else #if defined(__AVX512VL__) vfloat4 r = _mm_rsqrt14_ps(a); #else vfloat4 r = _mm_rsqrt_ps(a); #endif #if defined(__AVX2__) r = _mm_fmadd_ps(_mm_set1_ps(1.5f), r, _mm_mul_ps(_mm_mul_ps(_mm_mul_ps(a, _mm_set1_ps(-0.5f)), r), _mm_mul_ps(r, r))); #else r = _mm_add_ps(_mm_mul_ps(_mm_set1_ps(1.5f), r), _mm_mul_ps(_mm_mul_ps(_mm_mul_ps(a, _mm_set1_ps(-0.5f)), r), _mm_mul_ps(r, r))); #endif #endif return r; } __forceinline vboolf4 isnan(const vfloat4& a) { const vfloat4 b = _mm_and_ps(a, _mm_castsi128_ps(_mm_set1_epi32(0x7fffffff))); #if defined(__AVX512VL__) return _mm_cmp_epi32_mask(_mm_castps_si128(b), _mm_set1_epi32(0x7f800000), _MM_CMPINT_GT); #else return _mm_castsi128_ps(_mm_cmpgt_epi32(_mm_castps_si128(b), _mm_set1_epi32(0x7f800000))); #endif } //////////////////////////////////////////////////////////////////////////////// /// Binary Operators //////////////////////////////////////////////////////////////////////////////// __forceinline vfloat4 operator +(const vfloat4& a, const vfloat4& b) { return _mm_add_ps(a, b); } __forceinline vfloat4 operator +(const vfloat4& a, float b) { return a + vfloat4(b); } __forceinline vfloat4 operator +(float a, const vfloat4& b) { return vfloat4(a) + b; } __forceinline vfloat4 operator -(const vfloat4& a, const vfloat4& b) { return _mm_sub_ps(a, b); } __forceinline vfloat4 operator -(const vfloat4& a, float b) { return a - vfloat4(b); } __forceinline vfloat4 operator -(float a, const vfloat4& b) { return vfloat4(a) - b; } __forceinline vfloat4 operator *(const vfloat4& a, const vfloat4& b) { return _mm_mul_ps(a, b); } __forceinline vfloat4 operator *(const vfloat4& a, float b) { return a * vfloat4(b); } __forceinline vfloat4 operator *(float a, const vfloat4& b) { return vfloat4(a) * b; } __forceinline vfloat4 operator /(const vfloat4& a, const vfloat4& b) { return _mm_div_ps(a,b); } __forceinline vfloat4 operator /(const vfloat4& a, float b) { return a/vfloat4(b); } __forceinline vfloat4 operator /(float a, const vfloat4& b) { return vfloat4(a)/b; } __forceinline vfloat4 operator &(const vfloat4& a, const vfloat4& b) { return _mm_and_ps(a,b); } __forceinline vfloat4 operator |(const vfloat4& a, const vfloat4& b) { return _mm_or_ps(a,b); } __forceinline vfloat4 operator ^(const vfloat4& a, const vfloat4& b) { return _mm_xor_ps(a,b); } __forceinline vfloat4 operator ^(const vfloat4& a, const vint4& b) { return _mm_xor_ps(a,_mm_castsi128_ps(b)); } __forceinline vfloat4 min(const vfloat4& a, const vfloat4& b) { return _mm_min_ps(a,b); } __forceinline vfloat4 min(const vfloat4& a, float b) { return _mm_min_ps(a,vfloat4(b)); } __forceinline vfloat4 min(float a, const vfloat4& b) { return _mm_min_ps(vfloat4(a),b); } __forceinline vfloat4 max(const vfloat4& a, const vfloat4& b) { return _mm_max_ps(a,b); } __forceinline vfloat4 max(const vfloat4& a, float b) { return _mm_max_ps(a,vfloat4(b)); } __forceinline vfloat4 max(float a, const vfloat4& b) { return _mm_max_ps(vfloat4(a),b); } #if defined(__SSE4_1__) || defined(__aarch64__) __forceinline vfloat4 mini(const vfloat4& a, const vfloat4& b) { const vint4 ai = _mm_castps_si128(a); const vint4 bi = _mm_castps_si128(b); const vint4 ci = _mm_min_epi32(ai,bi); return _mm_castsi128_ps(ci); } __forceinline vfloat4 maxi(const vfloat4& a, const vfloat4& b) { const vint4 ai = _mm_castps_si128(a); const vint4 bi = _mm_castps_si128(b); const vint4 ci = _mm_max_epi32(ai,bi); return _mm_castsi128_ps(ci); } __forceinline vfloat4 minui(const vfloat4& a, const vfloat4& b) { const vint4 ai = _mm_castps_si128(a); const vint4 bi = _mm_castps_si128(b); const vint4 ci = _mm_min_epu32(ai,bi); return _mm_castsi128_ps(ci); } __forceinline vfloat4 maxui(const vfloat4& a, const vfloat4& b) { const vint4 ai = _mm_castps_si128(a); const vint4 bi = _mm_castps_si128(b); const vint4 ci = _mm_max_epu32(ai,bi); return _mm_castsi128_ps(ci); } #else __forceinline vfloat4 mini(const vfloat4& a, const vfloat4& b) { return min(a,b); } __forceinline vfloat4 maxi(const vfloat4& a, const vfloat4& b) { return max(a,b); } #endif //////////////////////////////////////////////////////////////////////////////// /// Ternary Operators //////////////////////////////////////////////////////////////////////////////// #if defined(__AVX2__) || defined(__ARM_NEON) __forceinline vfloat4 madd (const vfloat4& a, const vfloat4& b, const vfloat4& c) { return _mm_fmadd_ps(a,b,c); } __forceinline vfloat4 msub (const vfloat4& a, const vfloat4& b, const vfloat4& c) { return _mm_fmsub_ps(a,b,c); } __forceinline vfloat4 nmadd(const vfloat4& a, const vfloat4& b, const vfloat4& c) { return _mm_fnmadd_ps(a,b,c); } __forceinline vfloat4 nmsub(const vfloat4& a, const vfloat4& b, const vfloat4& c) { return _mm_fnmsub_ps(a,b,c); } #else __forceinline vfloat4 madd (const vfloat4& a, const vfloat4& b, const vfloat4& c) { return a*b+c; } __forceinline vfloat4 nmadd(const vfloat4& a, const vfloat4& b, const vfloat4& c) { return -a*b+c;} __forceinline vfloat4 nmsub(const vfloat4& a, const vfloat4& b, const vfloat4& c) { return -a*b-c; } __forceinline vfloat4 msub (const vfloat4& a, const vfloat4& b, const vfloat4& c) { return a*b-c; } #endif //////////////////////////////////////////////////////////////////////////////// /// Assignment Operators //////////////////////////////////////////////////////////////////////////////// __forceinline vfloat4& operator +=(vfloat4& a, const vfloat4& b) { return a = a + b; } __forceinline vfloat4& operator +=(vfloat4& a, float b) { return a = a + b; } __forceinline vfloat4& operator -=(vfloat4& a, const vfloat4& b) { return a = a - b; } __forceinline vfloat4& operator -=(vfloat4& a, float b) { return a = a - b; } __forceinline vfloat4& operator *=(vfloat4& a, const vfloat4& b) { return a = a * b; } __forceinline vfloat4& operator *=(vfloat4& a, float b) { return a = a * b; } __forceinline vfloat4& operator /=(vfloat4& a, const vfloat4& b) { return a = a / b; } __forceinline vfloat4& operator /=(vfloat4& a, float b) { return a = a / b; } //////////////////////////////////////////////////////////////////////////////// /// Comparison Operators + Select //////////////////////////////////////////////////////////////////////////////// #if defined(__AVX512VL__) __forceinline vboolf4 operator ==(const vfloat4& a, const vfloat4& b) { return _mm_cmp_ps_mask(a, b, _MM_CMPINT_EQ); } __forceinline vboolf4 operator !=(const vfloat4& a, const vfloat4& b) { return _mm_cmp_ps_mask(a, b, _MM_CMPINT_NE); } __forceinline vboolf4 operator < (const vfloat4& a, const vfloat4& b) { return _mm_cmp_ps_mask(a, b, _MM_CMPINT_LT); } __forceinline vboolf4 operator >=(const vfloat4& a, const vfloat4& b) { return _mm_cmp_ps_mask(a, b, _MM_CMPINT_GE); } __forceinline vboolf4 operator > (const vfloat4& a, const vfloat4& b) { return _mm_cmp_ps_mask(a, b, _MM_CMPINT_GT); } __forceinline vboolf4 operator <=(const vfloat4& a, const vfloat4& b) { return _mm_cmp_ps_mask(a, b, _MM_CMPINT_LE); } #else __forceinline vboolf4 operator ==(const vfloat4& a, const vfloat4& b) { return _mm_cmpeq_ps (a, b); } __forceinline vboolf4 operator !=(const vfloat4& a, const vfloat4& b) { return _mm_cmpneq_ps(a, b); } __forceinline vboolf4 operator < (const vfloat4& a, const vfloat4& b) { return _mm_cmplt_ps (a, b); } #if defined(__aarch64__) __forceinline vboolf4 operator >=(const vfloat4& a, const vfloat4& b) { return _mm_cmpge_ps (a, b); } __forceinline vboolf4 operator > (const vfloat4& a, const vfloat4& b) { return _mm_cmpgt_ps (a, b); } #else __forceinline vboolf4 operator >=(const vfloat4& a, const vfloat4& b) { return _mm_cmpnlt_ps(a, b); } __forceinline vboolf4 operator > (const vfloat4& a, const vfloat4& b) { return _mm_cmpnle_ps(a, b); } #endif __forceinline vboolf4 operator <=(const vfloat4& a, const vfloat4& b) { return _mm_cmple_ps (a, b); } #endif __forceinline vboolf4 operator ==(const vfloat4& a, float b) { return a == vfloat4(b); } __forceinline vboolf4 operator ==(float a, const vfloat4& b) { return vfloat4(a) == b; } __forceinline vboolf4 operator !=(const vfloat4& a, float b) { return a != vfloat4(b); } __forceinline vboolf4 operator !=(float a, const vfloat4& b) { return vfloat4(a) != b; } __forceinline vboolf4 operator < (const vfloat4& a, float b) { return a < vfloat4(b); } __forceinline vboolf4 operator < (float a, const vfloat4& b) { return vfloat4(a) < b; } __forceinline vboolf4 operator >=(const vfloat4& a, float b) { return a >= vfloat4(b); } __forceinline vboolf4 operator >=(float a, const vfloat4& b) { return vfloat4(a) >= b; } __forceinline vboolf4 operator > (const vfloat4& a, float b) { return a > vfloat4(b); } __forceinline vboolf4 operator > (float a, const vfloat4& b) { return vfloat4(a) > b; } __forceinline vboolf4 operator <=(const vfloat4& a, float b) { return a <= vfloat4(b); } __forceinline vboolf4 operator <=(float a, const vfloat4& b) { return vfloat4(a) <= b; } __forceinline vboolf4 eq(const vfloat4& a, const vfloat4& b) { return a == b; } __forceinline vboolf4 ne(const vfloat4& a, const vfloat4& b) { return a != b; } __forceinline vboolf4 lt(const vfloat4& a, const vfloat4& b) { return a < b; } __forceinline vboolf4 ge(const vfloat4& a, const vfloat4& b) { return a >= b; } __forceinline vboolf4 gt(const vfloat4& a, const vfloat4& b) { return a > b; } __forceinline vboolf4 le(const vfloat4& a, const vfloat4& b) { return a <= b; } #if defined(__AVX512VL__) __forceinline vboolf4 eq(const vboolf4& mask, const vfloat4& a, const vfloat4& b) { return _mm_mask_cmp_ps_mask(mask, a, b, _MM_CMPINT_EQ); } __forceinline vboolf4 ne(const vboolf4& mask, const vfloat4& a, const vfloat4& b) { return _mm_mask_cmp_ps_mask(mask, a, b, _MM_CMPINT_NE); } __forceinline vboolf4 lt(const vboolf4& mask, const vfloat4& a, const vfloat4& b) { return _mm_mask_cmp_ps_mask(mask, a, b, _MM_CMPINT_LT); } __forceinline vboolf4 ge(const vboolf4& mask, const vfloat4& a, const vfloat4& b) { return _mm_mask_cmp_ps_mask(mask, a, b, _MM_CMPINT_GE); } __forceinline vboolf4 gt(const vboolf4& mask, const vfloat4& a, const vfloat4& b) { return _mm_mask_cmp_ps_mask(mask, a, b, _MM_CMPINT_GT); } __forceinline vboolf4 le(const vboolf4& mask, const vfloat4& a, const vfloat4& b) { return _mm_mask_cmp_ps_mask(mask, a, b, _MM_CMPINT_LE); } #else __forceinline vboolf4 eq(const vboolf4& mask, const vfloat4& a, const vfloat4& b) { return mask & (a == b); } __forceinline vboolf4 ne(const vboolf4& mask, const vfloat4& a, const vfloat4& b) { return mask & (a != b); } __forceinline vboolf4 lt(const vboolf4& mask, const vfloat4& a, const vfloat4& b) { return mask & (a < b); } __forceinline vboolf4 ge(const vboolf4& mask, const vfloat4& a, const vfloat4& b) { return mask & (a >= b); } __forceinline vboolf4 gt(const vboolf4& mask, const vfloat4& a, const vfloat4& b) { return mask & (a > b); } __forceinline vboolf4 le(const vboolf4& mask, const vfloat4& a, const vfloat4& b) { return mask & (a <= b); } #endif template __forceinline vfloat4 select(const vfloat4& t, const vfloat4& f) { #if defined(__SSE4_1__) return _mm_blend_ps(f, t, mask); #else return select(vboolf4(mask), t, f); #endif } __forceinline vfloat4 lerp(const vfloat4& a, const vfloat4& b, const vfloat4& t) { return madd(t,b-a,a); } __forceinline bool isvalid(const vfloat4& v) { return all((v > vfloat4(-FLT_LARGE)) & (v < vfloat4(+FLT_LARGE))); } __forceinline bool is_finite(const vfloat4& a) { return all((a >= vfloat4(-FLT_MAX)) & (a <= vfloat4(+FLT_MAX))); } __forceinline bool is_finite(const vboolf4& valid, const vfloat4& a) { return all(valid, (a >= vfloat4(-FLT_MAX)) & (a <= vfloat4(+FLT_MAX))); } //////////////////////////////////////////////////////////////////////////////// /// Rounding Functions //////////////////////////////////////////////////////////////////////////////// #if defined(__aarch64__) __forceinline vfloat4 floor(const vfloat4& a) { return vrndmq_f32(a.v); } // towards -inf __forceinline vfloat4 ceil (const vfloat4& a) { return vrndpq_f32(a.v); } // toward +inf __forceinline vfloat4 trunc(const vfloat4& a) { return vrndq_f32(a.v); } // towards 0 __forceinline vfloat4 round(const vfloat4& a) { return vrndnq_f32(a.v); } // to nearest, ties to even. NOTE(LTE): arm clang uses vrndnq, old gcc uses vrndqn? #elif defined (__SSE4_1__) __forceinline vfloat4 floor(const vfloat4& a) { return _mm_round_ps(a, _MM_FROUND_TO_NEG_INF ); } __forceinline vfloat4 ceil (const vfloat4& a) { return _mm_round_ps(a, _MM_FROUND_TO_POS_INF ); } __forceinline vfloat4 trunc(const vfloat4& a) { return _mm_round_ps(a, _MM_FROUND_TO_ZERO ); } __forceinline vfloat4 round(const vfloat4& a) { return _mm_round_ps(a, _MM_FROUND_TO_NEAREST_INT); } #else __forceinline vfloat4 floor(const vfloat4& a) { return vfloat4(floorf(a[0]),floorf(a[1]),floorf(a[2]),floorf(a[3])); } __forceinline vfloat4 ceil (const vfloat4& a) { return vfloat4(ceilf (a[0]),ceilf (a[1]),ceilf (a[2]),ceilf (a[3])); } __forceinline vfloat4 trunc(const vfloat4& a) { return vfloat4(truncf(a[0]),truncf(a[1]),truncf(a[2]),truncf(a[3])); } __forceinline vfloat4 round(const vfloat4& a) { return vfloat4(roundf(a[0]),roundf(a[1]),roundf(a[2]),roundf(a[3])); } #endif __forceinline vfloat4 frac(const vfloat4& a) { return a-floor(a); } __forceinline vint4 floori(const vfloat4& a) { #if defined(__aarch64__) return vcvtq_s32_f32(floor(a)); #elif defined(__SSE4_1__) return vint4(floor(a)); #else return vint4(a-vfloat4(0.5f)); #endif } //////////////////////////////////////////////////////////////////////////////// /// Movement/Shifting/Shuffling Functions //////////////////////////////////////////////////////////////////////////////// __forceinline vfloat4 unpacklo(const vfloat4& a, const vfloat4& b) { return _mm_unpacklo_ps(a, b); } __forceinline vfloat4 unpackhi(const vfloat4& a, const vfloat4& b) { return _mm_unpackhi_ps(a, b); } #if defined(__aarch64__) template __forceinline vfloat4 shuffle(const vfloat4& v) { return vreinterpretq_f32_u8(vqtbl1q_u8( (uint8x16_t)v.v, _MN_SHUFFLE(i0, i1, i2, i3))); } template __forceinline vfloat4 shuffle(const vfloat4& a, const vfloat4& b) { return vreinterpretq_f32_u8(vqtbl2q_u8( (uint8x16x2_t){(uint8x16_t)a.v, (uint8x16_t)b.v}, _MF_SHUFFLE(i0, i1, i2, i3))); } #else template __forceinline vfloat4 shuffle(const vfloat4& v) { return _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(v), _MM_SHUFFLE(i3, i2, i1, i0))); } template __forceinline vfloat4 shuffle(const vfloat4& a, const vfloat4& b) { return _mm_shuffle_ps(a, b, _MM_SHUFFLE(i3, i2, i1, i0)); } #endif #if defined(__SSE3__) && !defined(__aarch64__) template<> __forceinline vfloat4 shuffle<0, 0, 2, 2>(const vfloat4& v) { return _mm_moveldup_ps(v); } template<> __forceinline vfloat4 shuffle<1, 1, 3, 3>(const vfloat4& v) { return _mm_movehdup_ps(v); } template<> __forceinline vfloat4 shuffle<0, 1, 0, 1>(const vfloat4& v) { return _mm_castpd_ps(_mm_movedup_pd(_mm_castps_pd(v))); } #endif template __forceinline vfloat4 shuffle(const vfloat4& v) { return shuffle(v); } #if defined(__aarch64__) template __forceinline float extract(const vfloat4& a) { return a[i]; } #else template __forceinline float extract (const vfloat4& a) { return _mm_cvtss_f32(shuffle(a)); } template<> __forceinline float extract<0>(const vfloat4& a) { return _mm_cvtss_f32(a); } #endif #if defined (__SSE4_1__) && !defined(__aarch64__) template __forceinline vfloat4 insert(const vfloat4& a, const vfloat4& b) { return _mm_insert_ps(a, b, (dst << 4) | (src << 6) | clr); } template __forceinline vfloat4 insert(const vfloat4& a, const vfloat4& b) { return insert(a, b); } template __forceinline vfloat4 insert(const vfloat4& a, const float b) { return insert(a, _mm_set_ss(b)); } #else template __forceinline vfloat4 insert(const vfloat4& a, const vfloat4& b) { vfloat4 c = a; c[dst&3] = b[src&3]; return c; } template __forceinline vfloat4 insert(const vfloat4& a, float b) { vfloat4 c = a; c[dst&3] = b; return c; } #endif __forceinline float toScalar(const vfloat4& v) { return _mm_cvtss_f32(v); } __forceinline vfloat4 shift_right_1(const vfloat4& x) { return _mm_castsi128_ps(_mm_srli_si128(_mm_castps_si128(x), 4)); } #if defined (__AVX2__) __forceinline vfloat4 permute(const vfloat4 &a, const __m128i &index) { return _mm_permutevar_ps(a,index); } __forceinline vfloat4 broadcast1f(const void* a) { return _mm_broadcast_ss((float*)a); } #endif #if defined(__AVX512VL__) template __forceinline vfloat4 align_shift_right(const vfloat4& a, const vfloat4& b) { return _mm_castsi128_ps(_mm_alignr_epi32(_mm_castps_si128(a), _mm_castps_si128(b), i)); } #endif //////////////////////////////////////////////////////////////////////////////// /// Sorting Network //////////////////////////////////////////////////////////////////////////////// __forceinline vfloat4 sort_ascending(const vfloat4& v) { const vfloat4 a0 = v; const vfloat4 b0 = shuffle<1,0,3,2>(a0); const vfloat4 c0 = min(a0,b0); const vfloat4 d0 = max(a0,b0); const vfloat4 a1 = select<0x5 /* 0b0101 */>(c0,d0); const vfloat4 b1 = shuffle<2,3,0,1>(a1); const vfloat4 c1 = min(a1,b1); const vfloat4 d1 = max(a1,b1); const vfloat4 a2 = select<0x3 /* 0b0011 */>(c1,d1); const vfloat4 b2 = shuffle<0,2,1,3>(a2); const vfloat4 c2 = min(a2,b2); const vfloat4 d2 = max(a2,b2); const vfloat4 a3 = select<0x2 /* 0b0010 */>(c2,d2); return a3; } __forceinline vfloat4 sort_descending(const vfloat4& v) { const vfloat4 a0 = v; const vfloat4 b0 = shuffle<1,0,3,2>(a0); const vfloat4 c0 = max(a0,b0); const vfloat4 d0 = min(a0,b0); const vfloat4 a1 = select<0x5 /* 0b0101 */>(c0,d0); const vfloat4 b1 = shuffle<2,3,0,1>(a1); const vfloat4 c1 = max(a1,b1); const vfloat4 d1 = min(a1,b1); const vfloat4 a2 = select<0x3 /* 0b0011 */>(c1,d1); const vfloat4 b2 = shuffle<0,2,1,3>(a2); const vfloat4 c2 = max(a2,b2); const vfloat4 d2 = min(a2,b2); const vfloat4 a3 = select<0x2 /* 0b0010 */>(c2,d2); return a3; } //////////////////////////////////////////////////////////////////////////////// /// Transpose //////////////////////////////////////////////////////////////////////////////// __forceinline void transpose(const vfloat4& r0, const vfloat4& r1, const vfloat4& r2, const vfloat4& r3, vfloat4& c0, vfloat4& c1, vfloat4& c2, vfloat4& c3) { vfloat4 l02 = unpacklo(r0,r2); vfloat4 h02 = unpackhi(r0,r2); vfloat4 l13 = unpacklo(r1,r3); vfloat4 h13 = unpackhi(r1,r3); c0 = unpacklo(l02,l13); c1 = unpackhi(l02,l13); c2 = unpacklo(h02,h13); c3 = unpackhi(h02,h13); } __forceinline void transpose(const vfloat4& r0, const vfloat4& r1, const vfloat4& r2, const vfloat4& r3, vfloat4& c0, vfloat4& c1, vfloat4& c2) { vfloat4 l02 = unpacklo(r0,r2); vfloat4 h02 = unpackhi(r0,r2); vfloat4 l13 = unpacklo(r1,r3); vfloat4 h13 = unpackhi(r1,r3); c0 = unpacklo(l02,l13); c1 = unpackhi(l02,l13); c2 = unpacklo(h02,h13); } //////////////////////////////////////////////////////////////////////////////// /// Reductions //////////////////////////////////////////////////////////////////////////////// #if defined(__aarch64__) __forceinline vfloat4 vreduce_min(const vfloat4& v) { float h = vminvq_f32(v); return vdupq_n_f32(h); } __forceinline vfloat4 vreduce_max(const vfloat4& v) { float h = vmaxvq_f32(v); return vdupq_n_f32(h); } __forceinline vfloat4 vreduce_add(const vfloat4& v) { float h = vaddvq_f32(v); return vdupq_n_f32(h); } #else __forceinline vfloat4 vreduce_min(const vfloat4& v) { vfloat4 h = min(shuffle<1,0,3,2>(v),v); return min(shuffle<2,3,0,1>(h),h); } __forceinline vfloat4 vreduce_max(const vfloat4& v) { vfloat4 h = max(shuffle<1,0,3,2>(v),v); return max(shuffle<2,3,0,1>(h),h); } __forceinline vfloat4 vreduce_add(const vfloat4& v) { vfloat4 h = shuffle<1,0,3,2>(v) + v ; return shuffle<2,3,0,1>(h) + h ; } #endif #if defined(__aarch64__) __forceinline float reduce_min(const vfloat4& v) { return vminvq_f32(v); } __forceinline float reduce_max(const vfloat4& v) { return vmaxvq_f32(v); } __forceinline float reduce_add(const vfloat4& v) { return vaddvq_f32(v); } #else __forceinline float reduce_min(const vfloat4& v) { return _mm_cvtss_f32(vreduce_min(v)); } __forceinline float reduce_max(const vfloat4& v) { return _mm_cvtss_f32(vreduce_max(v)); } __forceinline float reduce_add(const vfloat4& v) { return _mm_cvtss_f32(vreduce_add(v)); } #endif __forceinline size_t select_min(const vboolf4& valid, const vfloat4& v) { const vfloat4 a = select(valid,v,vfloat4(pos_inf)); const vbool4 valid_min = valid & (a == vreduce_min(a)); return bsf(movemask(any(valid_min) ? valid_min : valid)); } __forceinline size_t select_max(const vboolf4& valid, const vfloat4& v) { const vfloat4 a = select(valid,v,vfloat4(neg_inf)); const vbool4 valid_max = valid & (a == vreduce_max(a)); return bsf(movemask(any(valid_max) ? valid_max : valid)); } //////////////////////////////////////////////////////////////////////////////// /// Euclidean Space Operators //////////////////////////////////////////////////////////////////////////////// __forceinline float dot(const vfloat4& a, const vfloat4& b) { return reduce_add(a*b); } __forceinline vfloat4 cross(const vfloat4& a, const vfloat4& b) { const vfloat4 a0 = a; const vfloat4 b0 = shuffle<1,2,0,3>(b); const vfloat4 a1 = shuffle<1,2,0,3>(a); const vfloat4 b1 = b; return shuffle<1,2,0,3>(msub(a0,b0,a1*b1)); } //////////////////////////////////////////////////////////////////////////////// /// Output Operators //////////////////////////////////////////////////////////////////////////////// __forceinline embree_ostream operator <<(embree_ostream cout, const vfloat4& a) { return cout << "<" << a[0] << ", " << a[1] << ", " << a[2] << ", " << a[3] << ">"; } } #undef vboolf #undef vboold #undef vint #undef vuint #undef vllong #undef vfloat #undef vdouble level-zero-raytracing-support-1.0.0/rtbuild/simd/vint4_sse2.h000066400000000000000000000721211450534701400242270ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "../math/emath.h" #define vboolf vboolf_impl #define vboold vboold_impl #define vint vint_impl #define vuint vuint_impl #define vllong vllong_impl #define vfloat vfloat_impl #define vdouble vdouble_impl namespace embree { /* 4-wide SSE integer type */ template<> struct vint<4> { ALIGNED_STRUCT_(16); typedef vboolf4 Bool; typedef vint4 Int; typedef vfloat4 Float; enum { size = 4 }; // number of SIMD elements union { __m128i v; int i[4]; }; // data //////////////////////////////////////////////////////////////////////////////// /// Constructors, Assignment & Cast Operators //////////////////////////////////////////////////////////////////////////////// __forceinline vint() {} __forceinline vint(const vint4& a) { v = a.v; } __forceinline vint4& operator =(const vint4& a) { v = a.v; return *this; } __forceinline vint(__m128i a) : v(a) {} __forceinline operator const __m128i&() const { return v; } __forceinline operator __m128i&() { return v; } __forceinline vint(int a) : v(_mm_set1_epi32(a)) {} __forceinline vint(int a, int b, int c, int d) : v(_mm_set_epi32(d, c, b, a)) {} __forceinline explicit vint(__m128 a) : v(_mm_cvtps_epi32(a)) {} #if defined(__AVX512VL__) __forceinline explicit vint(const vboolf4& a) : v(_mm_movm_epi32(a)) {} #else __forceinline explicit vint(const vboolf4& a) : v(_mm_castps_si128((__m128)a)) {} #endif __forceinline vint(long long a, long long b) : v(_mm_set_epi64x(b,a)) {} //////////////////////////////////////////////////////////////////////////////// /// Constants //////////////////////////////////////////////////////////////////////////////// __forceinline vint(ZeroTy) : v(_mm_setzero_si128()) {} __forceinline vint(OneTy) : v(_mm_set_epi32(1, 1, 1, 1)) {} __forceinline vint(PosInfTy) : v(_mm_set_epi32(pos_inf, pos_inf, pos_inf, pos_inf)) {} __forceinline vint(NegInfTy) : v(_mm_set_epi32(neg_inf, neg_inf, neg_inf, neg_inf)) {} __forceinline vint(StepTy) : v(_mm_set_epi32(3, 2, 1, 0)) {} __forceinline vint(ReverseStepTy) : v(_mm_set_epi32(0, 1, 2, 3)) {} __forceinline vint(TrueTy) { v = _mm_cmpeq_epi32(v,v); } __forceinline vint(UndefinedTy) : v(_mm_castps_si128(_mm_undefined_ps())) {} //////////////////////////////////////////////////////////////////////////////// /// Loads and Stores //////////////////////////////////////////////////////////////////////////////// static __forceinline vint4 load (const void* a) { return _mm_load_si128((__m128i*)a); } static __forceinline vint4 loadu(const void* a) { return _mm_loadu_si128((__m128i*)a); } static __forceinline void store (void* ptr, const vint4& v) { _mm_store_si128((__m128i*)ptr,v); } static __forceinline void storeu(void* ptr, const vint4& v) { _mm_storeu_si128((__m128i*)ptr,v); } #if defined(__AVX512VL__) static __forceinline vint4 compact(const vboolf4& mask, vint4 &v) { return _mm_mask_compress_epi32(v, mask, v); } static __forceinline vint4 compact(const vboolf4& mask, vint4 &a, const vint4& b) { return _mm_mask_compress_epi32(a, mask, b); } static __forceinline vint4 load (const vboolf4& mask, const void* ptr) { return _mm_mask_load_epi32 (_mm_setzero_si128(),mask,ptr); } static __forceinline vint4 loadu(const vboolf4& mask, const void* ptr) { return _mm_mask_loadu_epi32(_mm_setzero_si128(),mask,ptr); } static __forceinline void store (const vboolf4& mask, void* ptr, const vint4& v) { _mm_mask_store_epi32 (ptr,mask,v); } static __forceinline void storeu(const vboolf4& mask, void* ptr, const vint4& v) { _mm_mask_storeu_epi32(ptr,mask,v); } #elif defined(__AVX__) static __forceinline vint4 load (const vbool4& mask, const void* a) { return _mm_castps_si128(_mm_maskload_ps((float*)a,mask)); } static __forceinline vint4 loadu(const vbool4& mask, const void* a) { return _mm_castps_si128(_mm_maskload_ps((float*)a,mask)); } static __forceinline void store (const vboolf4& mask, void* ptr, const vint4& i) { _mm_maskstore_ps((float*)ptr,(__m128i)mask,_mm_castsi128_ps(i)); } static __forceinline void storeu(const vboolf4& mask, void* ptr, const vint4& i) { _mm_maskstore_ps((float*)ptr,(__m128i)mask,_mm_castsi128_ps(i)); } #else static __forceinline vint4 load (const vbool4& mask, const void* a) { return _mm_and_si128(_mm_load_si128 ((__m128i*)a),mask); } static __forceinline vint4 loadu(const vbool4& mask, const void* a) { return _mm_and_si128(_mm_loadu_si128((__m128i*)a),mask); } static __forceinline void store (const vboolf4& mask, void* ptr, const vint4& i) { store (ptr,select(mask,i,load (ptr))); } static __forceinline void storeu(const vboolf4& mask, void* ptr, const vint4& i) { storeu(ptr,select(mask,i,loadu(ptr))); } #endif #if defined(__aarch64__) static __forceinline vint4 load(const unsigned char* ptr) { return _mm_load4epu8_epi32(((__m128i*)ptr)); } static __forceinline vint4 loadu(const unsigned char* ptr) { return _mm_load4epu8_epi32(((__m128i*)ptr)); } #elif defined(__SSE4_1__) static __forceinline vint4 load(const unsigned char* ptr) { return _mm_cvtepu8_epi32(_mm_loadl_epi64((__m128i*)ptr)); } static __forceinline vint4 loadu(const unsigned char* ptr) { return _mm_cvtepu8_epi32(_mm_loadl_epi64((__m128i*)ptr)); } #else static __forceinline vint4 load(const unsigned char* ptr) { return vint4(ptr[0],ptr[1],ptr[2],ptr[3]); } static __forceinline vint4 loadu(const unsigned char* ptr) { return vint4(ptr[0],ptr[1],ptr[2],ptr[3]); } #endif static __forceinline vint4 load(const unsigned short* ptr) { #if defined(__aarch64__) return __m128i(vmovl_u16(vld1_u16(ptr))); #elif defined (__SSE4_1__) return _mm_cvtepu16_epi32(_mm_loadu_si128((__m128i*)ptr)); #else return vint4(ptr[0],ptr[1],ptr[2],ptr[3]); #endif } static __forceinline void store(unsigned char* ptr, const vint4& v) { #if defined(__aarch64__) int32x4_t x = v; uint16x4_t y = vqmovn_u32(uint32x4_t(x)); uint8x8_t z = vqmovn_u16(vcombine_u16(y, y)); vst1_lane_u32((uint32_t *)ptr,uint32x2_t(z), 0); #elif defined(__SSE4_1__) __m128i x = v; x = _mm_packus_epi32(x, x); x = _mm_packus_epi16(x, x); *(int*)ptr = _mm_cvtsi128_si32(x); #else for (size_t i=0;i<4;i++) ptr[i] = (unsigned char)v[i]; #endif } static __forceinline void store(unsigned short* ptr, const vint4& v) { #if defined(__aarch64__) uint32x4_t x = uint32x4_t(v.v); uint16x4_t y = vqmovn_u32(x); vst1_u16(ptr, y); #else for (size_t i=0;i<4;i++) ptr[i] = (unsigned short)v[i]; #endif } static __forceinline vint4 load_nt(void* ptr) { #if defined(__aarch64__) || defined(__SSE4_1__) return _mm_stream_load_si128((__m128i*)ptr); #else return _mm_load_si128((__m128i*)ptr); #endif } static __forceinline void store_nt(void* ptr, const vint4& v) { #if !defined(__aarch64__) && defined(__SSE4_1__) _mm_stream_ps((float*)ptr, _mm_castsi128_ps(v)); #else _mm_store_si128((__m128i*)ptr,v); #endif } template static __forceinline vint4 gather(const int* ptr, const vint4& index) { #if defined(__AVX2__) && !defined(__aarch64__) return _mm_i32gather_epi32(ptr, index, scale); #else return vint4( *(int*)(((char*)ptr)+scale*index[0]), *(int*)(((char*)ptr)+scale*index[1]), *(int*)(((char*)ptr)+scale*index[2]), *(int*)(((char*)ptr)+scale*index[3])); #endif } template static __forceinline vint4 gather(const vboolf4& mask, const int* ptr, const vint4& index) { vint4 r = zero; #if defined(__AVX512VL__) return _mm_mmask_i32gather_epi32(r, mask, index, ptr, scale); #elif defined(__AVX2__) && !defined(__aarch64__) return _mm_mask_i32gather_epi32(r, ptr, index, mask, scale); #else if (likely(mask[0])) r[0] = *(int*)(((char*)ptr)+scale*index[0]); if (likely(mask[1])) r[1] = *(int*)(((char*)ptr)+scale*index[1]); if (likely(mask[2])) r[2] = *(int*)(((char*)ptr)+scale*index[2]); if (likely(mask[3])) r[3] = *(int*)(((char*)ptr)+scale*index[3]); return r; #endif } template static __forceinline void scatter(void* ptr, const vint4& index, const vint4& v) { #if defined(__AVX512VL__) _mm_i32scatter_epi32((int*)ptr, index, v, scale); #else *(int*)(((char*)ptr)+scale*index[0]) = v[0]; *(int*)(((char*)ptr)+scale*index[1]) = v[1]; *(int*)(((char*)ptr)+scale*index[2]) = v[2]; *(int*)(((char*)ptr)+scale*index[3]) = v[3]; #endif } template static __forceinline void scatter(const vboolf4& mask, void* ptr, const vint4& index, const vint4& v) { #if defined(__AVX512VL__) _mm_mask_i32scatter_epi32((int*)ptr, mask, index, v, scale); #else if (likely(mask[0])) *(int*)(((char*)ptr)+scale*index[0]) = v[0]; if (likely(mask[1])) *(int*)(((char*)ptr)+scale*index[1]) = v[1]; if (likely(mask[2])) *(int*)(((char*)ptr)+scale*index[2]) = v[2]; if (likely(mask[3])) *(int*)(((char*)ptr)+scale*index[3]) = v[3]; #endif } #if defined(__x86_64__) || defined(__aarch64__) static __forceinline vint4 broadcast64(long long a) { return _mm_set1_epi64x(a); } #endif //////////////////////////////////////////////////////////////////////////////// /// Array Access //////////////////////////////////////////////////////////////////////////////// __forceinline const int& operator [](size_t index) const { assert(index < 4); return i[index]; } __forceinline int& operator [](size_t index) { assert(index < 4); return i[index]; } friend __forceinline vint4 select(const vboolf4& m, const vint4& t, const vint4& f) { #if defined(__AVX512VL__) return _mm_mask_blend_epi32(m, (__m128i)f, (__m128i)t); #elif defined(__aarch64__) return _mm_castps_si128(_mm_blendv_ps((__m128)f.v,(__m128) t.v, (__m128)m.v)); #elif defined(__SSE4_1__) return _mm_castps_si128(_mm_blendv_ps(_mm_castsi128_ps(f), _mm_castsi128_ps(t), m)); #else return _mm_or_si128(_mm_and_si128(m, t), _mm_andnot_si128(m, f)); #endif } }; //////////////////////////////////////////////////////////////////////////////// /// Unary Operators //////////////////////////////////////////////////////////////////////////////// #if defined(__AVX512VL__) __forceinline vboolf4 asBool(const vint4& a) { return _mm_movepi32_mask(a); } #else __forceinline vboolf4 asBool(const vint4& a) { return _mm_castsi128_ps(a); } #endif __forceinline vint4 operator +(const vint4& a) { return a; } __forceinline vint4 operator -(const vint4& a) { return _mm_sub_epi32(_mm_setzero_si128(), a); } #if defined(__aarch64__) __forceinline vint4 abs(const vint4& a) { return vabsq_s32(a.v); } #elif defined(__SSSE3__) __forceinline vint4 abs(const vint4& a) { return _mm_abs_epi32(a); } #endif //////////////////////////////////////////////////////////////////////////////// /// Binary Operators //////////////////////////////////////////////////////////////////////////////// __forceinline vint4 operator +(const vint4& a, const vint4& b) { return _mm_add_epi32(a, b); } __forceinline vint4 operator +(const vint4& a, int b) { return a + vint4(b); } __forceinline vint4 operator +(int a, const vint4& b) { return vint4(a) + b; } __forceinline vint4 operator -(const vint4& a, const vint4& b) { return _mm_sub_epi32(a, b); } __forceinline vint4 operator -(const vint4& a, int b) { return a - vint4(b); } __forceinline vint4 operator -(int a, const vint4& b) { return vint4(a) - b; } #if (defined(__aarch64__)) || defined(__SSE4_1__) __forceinline vint4 operator *(const vint4& a, const vint4& b) { return _mm_mullo_epi32(a, b); } #else __forceinline vint4 operator *(const vint4& a, const vint4& b) { return vint4(a[0]*b[0],a[1]*b[1],a[2]*b[2],a[3]*b[3]); } #endif __forceinline vint4 operator *(const vint4& a, int b) { return a * vint4(b); } __forceinline vint4 operator *(int a, const vint4& b) { return vint4(a) * b; } __forceinline vint4 operator &(const vint4& a, const vint4& b) { return _mm_and_si128(a, b); } __forceinline vint4 operator &(const vint4& a, int b) { return a & vint4(b); } __forceinline vint4 operator &(int a, const vint4& b) { return vint4(a) & b; } __forceinline vint4 operator |(const vint4& a, const vint4& b) { return _mm_or_si128(a, b); } __forceinline vint4 operator |(const vint4& a, int b) { return a | vint4(b); } __forceinline vint4 operator |(int a, const vint4& b) { return vint4(a) | b; } __forceinline vint4 operator ^(const vint4& a, const vint4& b) { return _mm_xor_si128(a, b); } __forceinline vint4 operator ^(const vint4& a, int b) { return a ^ vint4(b); } __forceinline vint4 operator ^(int a, const vint4& b) { return vint4(a) ^ b; } __forceinline vint4 operator <<(const vint4& a, const int n) { return _mm_slli_epi32(a, n); } __forceinline vint4 operator >>(const vint4& a, const int n) { return _mm_srai_epi32(a, n); } __forceinline vint4 sll (const vint4& a, int b) { return _mm_slli_epi32(a, b); } __forceinline vint4 sra (const vint4& a, int b) { return _mm_srai_epi32(a, b); } __forceinline vint4 srl (const vint4& a, int b) { return _mm_srli_epi32(a, b); } //////////////////////////////////////////////////////////////////////////////// /// Assignment Operators //////////////////////////////////////////////////////////////////////////////// __forceinline vint4& operator +=(vint4& a, const vint4& b) { return a = a + b; } __forceinline vint4& operator +=(vint4& a, int b) { return a = a + b; } __forceinline vint4& operator -=(vint4& a, const vint4& b) { return a = a - b; } __forceinline vint4& operator -=(vint4& a, int b) { return a = a - b; } #if (defined(__aarch64__)) || defined(__SSE4_1__) __forceinline vint4& operator *=(vint4& a, const vint4& b) { return a = a * b; } __forceinline vint4& operator *=(vint4& a, int b) { return a = a * b; } #endif __forceinline vint4& operator &=(vint4& a, const vint4& b) { return a = a & b; } __forceinline vint4& operator &=(vint4& a, int b) { return a = a & b; } __forceinline vint4& operator |=(vint4& a, const vint4& b) { return a = a | b; } __forceinline vint4& operator |=(vint4& a, int b) { return a = a | b; } __forceinline vint4& operator <<=(vint4& a, int b) { return a = a << b; } __forceinline vint4& operator >>=(vint4& a, int b) { return a = a >> b; } //////////////////////////////////////////////////////////////////////////////// /// Comparison Operators + Select //////////////////////////////////////////////////////////////////////////////// #if defined(__AVX512VL__) __forceinline vboolf4 operator ==(const vint4& a, const vint4& b) { return _mm_cmp_epi32_mask(a,b,_MM_CMPINT_EQ); } __forceinline vboolf4 operator !=(const vint4& a, const vint4& b) { return _mm_cmp_epi32_mask(a,b,_MM_CMPINT_NE); } __forceinline vboolf4 operator < (const vint4& a, const vint4& b) { return _mm_cmp_epi32_mask(a,b,_MM_CMPINT_LT); } __forceinline vboolf4 operator >=(const vint4& a, const vint4& b) { return _mm_cmp_epi32_mask(a,b,_MM_CMPINT_GE); } __forceinline vboolf4 operator > (const vint4& a, const vint4& b) { return _mm_cmp_epi32_mask(a,b,_MM_CMPINT_GT); } __forceinline vboolf4 operator <=(const vint4& a, const vint4& b) { return _mm_cmp_epi32_mask(a,b,_MM_CMPINT_LE); } #else __forceinline vboolf4 operator ==(const vint4& a, const vint4& b) { return _mm_castsi128_ps(_mm_cmpeq_epi32(a, b)); } __forceinline vboolf4 operator !=(const vint4& a, const vint4& b) { return !(a == b); } __forceinline vboolf4 operator < (const vint4& a, const vint4& b) { return _mm_castsi128_ps(_mm_cmplt_epi32(a, b)); } __forceinline vboolf4 operator >=(const vint4& a, const vint4& b) { return !(a < b); } __forceinline vboolf4 operator > (const vint4& a, const vint4& b) { return _mm_castsi128_ps(_mm_cmpgt_epi32(a, b)); } __forceinline vboolf4 operator <=(const vint4& a, const vint4& b) { return !(a > b); } #endif __forceinline vboolf4 operator ==(const vint4& a, int b) { return a == vint4(b); } __forceinline vboolf4 operator ==(int a, const vint4& b) { return vint4(a) == b; } __forceinline vboolf4 operator !=(const vint4& a, int b) { return a != vint4(b); } __forceinline vboolf4 operator !=(int a, const vint4& b) { return vint4(a) != b; } __forceinline vboolf4 operator < (const vint4& a, int b) { return a < vint4(b); } __forceinline vboolf4 operator < (int a, const vint4& b) { return vint4(a) < b; } __forceinline vboolf4 operator >=(const vint4& a, int b) { return a >= vint4(b); } __forceinline vboolf4 operator >=(int a, const vint4& b) { return vint4(a) >= b; } __forceinline vboolf4 operator > (const vint4& a, int b) { return a > vint4(b); } __forceinline vboolf4 operator > (int a, const vint4& b) { return vint4(a) > b; } __forceinline vboolf4 operator <=(const vint4& a, int b) { return a <= vint4(b); } __forceinline vboolf4 operator <=(int a, const vint4& b) { return vint4(a) <= b; } __forceinline vboolf4 eq(const vint4& a, const vint4& b) { return a == b; } __forceinline vboolf4 ne(const vint4& a, const vint4& b) { return a != b; } __forceinline vboolf4 lt(const vint4& a, const vint4& b) { return a < b; } __forceinline vboolf4 ge(const vint4& a, const vint4& b) { return a >= b; } __forceinline vboolf4 gt(const vint4& a, const vint4& b) { return a > b; } __forceinline vboolf4 le(const vint4& a, const vint4& b) { return a <= b; } #if defined(__AVX512VL__) __forceinline vboolf4 eq(const vboolf4& mask, const vint4& a, const vint4& b) { return _mm_mask_cmp_epi32_mask(mask, a, b, _MM_CMPINT_EQ); } __forceinline vboolf4 ne(const vboolf4& mask, const vint4& a, const vint4& b) { return _mm_mask_cmp_epi32_mask(mask, a, b, _MM_CMPINT_NE); } __forceinline vboolf4 lt(const vboolf4& mask, const vint4& a, const vint4& b) { return _mm_mask_cmp_epi32_mask(mask, a, b, _MM_CMPINT_LT); } __forceinline vboolf4 ge(const vboolf4& mask, const vint4& a, const vint4& b) { return _mm_mask_cmp_epi32_mask(mask, a, b, _MM_CMPINT_GE); } __forceinline vboolf4 gt(const vboolf4& mask, const vint4& a, const vint4& b) { return _mm_mask_cmp_epi32_mask(mask, a, b, _MM_CMPINT_GT); } __forceinline vboolf4 le(const vboolf4& mask, const vint4& a, const vint4& b) { return _mm_mask_cmp_epi32_mask(mask, a, b, _MM_CMPINT_LE); } #else __forceinline vboolf4 eq(const vboolf4& mask, const vint4& a, const vint4& b) { return mask & (a == b); } __forceinline vboolf4 ne(const vboolf4& mask, const vint4& a, const vint4& b) { return mask & (a != b); } __forceinline vboolf4 lt(const vboolf4& mask, const vint4& a, const vint4& b) { return mask & (a < b); } __forceinline vboolf4 ge(const vboolf4& mask, const vint4& a, const vint4& b) { return mask & (a >= b); } __forceinline vboolf4 gt(const vboolf4& mask, const vint4& a, const vint4& b) { return mask & (a > b); } __forceinline vboolf4 le(const vboolf4& mask, const vint4& a, const vint4& b) { return mask & (a <= b); } #endif template __forceinline vint4 select(const vint4& t, const vint4& f) { #if defined(__SSE4_1__) return _mm_castps_si128(_mm_blend_ps(_mm_castsi128_ps(f), _mm_castsi128_ps(t), mask)); #else return select(vboolf4(mask), t, f); #endif } #if defined(__aarch64__) || defined(__SSE4_1__) __forceinline vint4 min(const vint4& a, const vint4& b) { return _mm_min_epi32(a, b); } __forceinline vint4 max(const vint4& a, const vint4& b) { return _mm_max_epi32(a, b); } __forceinline vint4 umin(const vint4& a, const vint4& b) { return _mm_min_epu32(a, b); } __forceinline vint4 umax(const vint4& a, const vint4& b) { return _mm_max_epu32(a, b); } #else __forceinline vint4 min(const vint4& a, const vint4& b) { return select(a < b,a,b); } __forceinline vint4 max(const vint4& a, const vint4& b) { return select(a < b,b,a); } #endif __forceinline vint4 min(const vint4& a, int b) { return min(a,vint4(b)); } __forceinline vint4 min(int a, const vint4& b) { return min(vint4(a),b); } __forceinline vint4 max(const vint4& a, int b) { return max(a,vint4(b)); } __forceinline vint4 max(int a, const vint4& b) { return max(vint4(a),b); } //////////////////////////////////////////////////////////////////////////////// // Movement/Shifting/Shuffling Functions //////////////////////////////////////////////////////////////////////////////// __forceinline vint4 unpacklo(const vint4& a, const vint4& b) { return _mm_castps_si128(_mm_unpacklo_ps(_mm_castsi128_ps(a), _mm_castsi128_ps(b))); } __forceinline vint4 unpackhi(const vint4& a, const vint4& b) { return _mm_castps_si128(_mm_unpackhi_ps(_mm_castsi128_ps(a), _mm_castsi128_ps(b))); } #if defined(__aarch64__) template __forceinline vint4 shuffle(const vint4& v) { return vreinterpretq_s32_u8(vqtbl1q_u8( (uint8x16_t)v.v, _MN_SHUFFLE(i0, i1, i2, i3))); } template __forceinline vint4 shuffle(const vint4& a, const vint4& b) { return vreinterpretq_s32_u8(vqtbl2q_u8( (uint8x16x2_t){(uint8x16_t)a.v, (uint8x16_t)b.v}, _MF_SHUFFLE(i0, i1, i2, i3))); } #else template __forceinline vint4 shuffle(const vint4& v) { return _mm_shuffle_epi32(v, _MM_SHUFFLE(i3, i2, i1, i0)); } template __forceinline vint4 shuffle(const vint4& a, const vint4& b) { return _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(a), _mm_castsi128_ps(b), _MM_SHUFFLE(i3, i2, i1, i0))); } #endif #if defined(__SSE3__) template<> __forceinline vint4 shuffle<0, 0, 2, 2>(const vint4& v) { return _mm_castps_si128(_mm_moveldup_ps(_mm_castsi128_ps(v))); } template<> __forceinline vint4 shuffle<1, 1, 3, 3>(const vint4& v) { return _mm_castps_si128(_mm_movehdup_ps(_mm_castsi128_ps(v))); } template<> __forceinline vint4 shuffle<0, 1, 0, 1>(const vint4& v) { return _mm_castpd_si128(_mm_movedup_pd (_mm_castsi128_pd(v))); } #endif template __forceinline vint4 shuffle(const vint4& v) { return shuffle(v); } #if defined(__SSE4_1__) && !defined(__aarch64__) template __forceinline int extract(const vint4& b) { return _mm_extract_epi32(b, src); } template __forceinline vint4 insert(const vint4& a, const int b) { return _mm_insert_epi32(a, b, dst); } #else template __forceinline int extract(const vint4& b) { return b[src&3]; } template __forceinline vint4 insert(const vint4& a, int b) { vint4 c = a; c[dst&3] = b; return c; } #endif template<> __forceinline int extract<0>(const vint4& b) { return _mm_cvtsi128_si32(b); } __forceinline int toScalar(const vint4& v) { return _mm_cvtsi128_si32(v); } #if defined(__aarch64__) __forceinline size_t toSizeT(const vint4& v) { uint64x2_t x = uint64x2_t(v.v); return x[0]; } #else __forceinline size_t toSizeT(const vint4& v) { #if defined(__WIN32__) && !defined(__X86_64__) // win32 workaround return toScalar(v); #elif defined(__ARM_NEON) // FIXME(LTE): Do we need a swap(i.e. use lane 1)? return vgetq_lane_u64(*(reinterpret_cast(&v)), 0); #else return _mm_cvtsi128_si64(v); #endif } #endif #if defined(__AVX512VL__) __forceinline vint4 permute(const vint4 &a, const vint4 &index) { return _mm_castps_si128(_mm_permutevar_ps(_mm_castsi128_ps(a),index)); } template __forceinline vint4 align_shift_right(const vint4& a, const vint4& b) { return _mm_alignr_epi32(a, b, i); } #endif //////////////////////////////////////////////////////////////////////////////// /// Reductions //////////////////////////////////////////////////////////////////////////////// #if defined(__aarch64__) || defined(__SSE4_1__) #if defined(__aarch64__) __forceinline vint4 vreduce_min(const vint4& v) { int h = vminvq_s32(v); return vdupq_n_s32(h); } __forceinline vint4 vreduce_max(const vint4& v) { int h = vmaxvq_s32(v); return vdupq_n_s32(h); } __forceinline vint4 vreduce_add(const vint4& v) { int h = vaddvq_s32(v); return vdupq_n_s32(h); } __forceinline int reduce_min(const vint4& v) { return vminvq_s32(v); } __forceinline int reduce_max(const vint4& v) { return vmaxvq_s32(v); } __forceinline int reduce_add(const vint4& v) { return vaddvq_s32(v); } #else __forceinline vint4 vreduce_min(const vint4& v) { vint4 h = min(shuffle<1,0,3,2>(v),v); return min(shuffle<2,3,0,1>(h),h); } __forceinline vint4 vreduce_max(const vint4& v) { vint4 h = max(shuffle<1,0,3,2>(v),v); return max(shuffle<2,3,0,1>(h),h); } __forceinline vint4 vreduce_add(const vint4& v) { vint4 h = shuffle<1,0,3,2>(v) + v ; return shuffle<2,3,0,1>(h) + h ; } __forceinline int reduce_min(const vint4& v) { return toScalar(vreduce_min(v)); } __forceinline int reduce_max(const vint4& v) { return toScalar(vreduce_max(v)); } __forceinline int reduce_add(const vint4& v) { return toScalar(vreduce_add(v)); } #endif __forceinline size_t select_min(const vint4& v) { return bsf(movemask(v == vreduce_min(v))); } __forceinline size_t select_max(const vint4& v) { return bsf(movemask(v == vreduce_max(v))); } __forceinline size_t select_min(const vboolf4& valid, const vint4& v) { const vint4 a = select(valid,v,vint4(pos_inf)); return bsf(movemask(valid & (a == vreduce_min(a)))); } __forceinline size_t select_max(const vboolf4& valid, const vint4& v) { const vint4 a = select(valid,v,vint4(neg_inf)); return bsf(movemask(valid & (a == vreduce_max(a)))); } #else __forceinline int reduce_min(const vint4& v) { return min(v[0],v[1],v[2],v[3]); } __forceinline int reduce_max(const vint4& v) { return max(v[0],v[1],v[2],v[3]); } __forceinline int reduce_add(const vint4& v) { return v[0]+v[1]+v[2]+v[3]; } #endif //////////////////////////////////////////////////////////////////////////////// /// Sorting networks //////////////////////////////////////////////////////////////////////////////// #if (defined(__aarch64__)) || defined(__SSE4_1__) __forceinline vint4 usort_ascending(const vint4& v) { const vint4 a0 = v; const vint4 b0 = shuffle<1,0,3,2>(a0); const vint4 c0 = umin(a0,b0); const vint4 d0 = umax(a0,b0); const vint4 a1 = select<0x5 /* 0b0101 */>(c0,d0); const vint4 b1 = shuffle<2,3,0,1>(a1); const vint4 c1 = umin(a1,b1); const vint4 d1 = umax(a1,b1); const vint4 a2 = select<0x3 /* 0b0011 */>(c1,d1); const vint4 b2 = shuffle<0,2,1,3>(a2); const vint4 c2 = umin(a2,b2); const vint4 d2 = umax(a2,b2); const vint4 a3 = select<0x2 /* 0b0010 */>(c2,d2); return a3; } __forceinline vint4 usort_descending(const vint4& v) { const vint4 a0 = v; const vint4 b0 = shuffle<1,0,3,2>(a0); const vint4 c0 = umax(a0,b0); const vint4 d0 = umin(a0,b0); const vint4 a1 = select<0x5 /* 0b0101 */>(c0,d0); const vint4 b1 = shuffle<2,3,0,1>(a1); const vint4 c1 = umax(a1,b1); const vint4 d1 = umin(a1,b1); const vint4 a2 = select<0x3 /* 0b0011 */>(c1,d1); const vint4 b2 = shuffle<0,2,1,3>(a2); const vint4 c2 = umax(a2,b2); const vint4 d2 = umin(a2,b2); const vint4 a3 = select<0x2 /* 0b0010 */>(c2,d2); return a3; } #else __forceinline vint4 usort_ascending(const vint4& v) { const vint4 a0 = v-vint4(0x80000000); const vint4 b0 = shuffle<1,0,3,2>(a0); const vint4 c0 = min(a0,b0); const vint4 d0 = max(a0,b0); const vint4 a1 = select<0x5 /* 0b0101 */>(c0,d0); const vint4 b1 = shuffle<2,3,0,1>(a1); const vint4 c1 = min(a1,b1); const vint4 d1 = max(a1,b1); const vint4 a2 = select<0x3 /* 0b0011 */>(c1,d1); const vint4 b2 = shuffle<0,2,1,3>(a2); const vint4 c2 = min(a2,b2); const vint4 d2 = max(a2,b2); const vint4 a3 = select<0x2 /* 0b0010 */>(c2,d2); return a3+vint4(0x80000000); } __forceinline vint4 usort_descending(const vint4& v) { const vint4 a0 = v-vint4(0x80000000); const vint4 b0 = shuffle<1,0,3,2>(a0); const vint4 c0 = max(a0,b0); const vint4 d0 = min(a0,b0); const vint4 a1 = select<0x5 /* 0b0101 */>(c0,d0); const vint4 b1 = shuffle<2,3,0,1>(a1); const vint4 c1 = max(a1,b1); const vint4 d1 = min(a1,b1); const vint4 a2 = select<0x3 /* 0b0011 */>(c1,d1); const vint4 b2 = shuffle<0,2,1,3>(a2); const vint4 c2 = max(a2,b2); const vint4 d2 = min(a2,b2); const vint4 a3 = select<0x2 /* 0b0010 */>(c2,d2); return a3+vint4(0x80000000); } #endif //////////////////////////////////////////////////////////////////////////////// /// Output Operators //////////////////////////////////////////////////////////////////////////////// __forceinline embree_ostream operator <<(embree_ostream cout, const vint4& a) { return cout << "<" << a[0] << ", " << a[1] << ", " << a[2] << ", " << a[3] << ">"; } } #undef vboolf #undef vboold #undef vint #undef vuint #undef vllong #undef vfloat #undef vdouble level-zero-raytracing-support-1.0.0/rtbuild/simd/vuint4_sse2.h000066400000000000000000000551711450534701400244220ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "../math/emath.h" #define vboolf vboolf_impl #define vboold vboold_impl #define vint vint_impl #define vuint vuint_impl #define vllong vllong_impl #define vfloat vfloat_impl #define vdouble vdouble_impl namespace embree { /* 4-wide SSE integer type */ template<> struct vuint<4> { ALIGNED_STRUCT_(16); typedef vboolf4 Bool; typedef vuint4 Int; typedef vfloat4 Float; enum { size = 4 }; // number of SIMD elements union { __m128i v; unsigned int i[4]; }; // data //////////////////////////////////////////////////////////////////////////////// /// Constructors, Assignment & Cast Operators //////////////////////////////////////////////////////////////////////////////// __forceinline vuint() {} __forceinline vuint(const vuint4& a) { v = a.v; } __forceinline vuint4& operator =(const vuint4& a) { v = a.v; return *this; } __forceinline vuint(const __m128i a) : v(a) {} __forceinline operator const __m128i&() const { return v; } __forceinline operator __m128i&() { return v; } __forceinline vuint(unsigned int a) : v(_mm_set1_epi32(a)) {} __forceinline vuint(unsigned int a, unsigned int b, unsigned int c, unsigned int d) : v(_mm_set_epi32(d, c, b, a)) {} #if defined(__AVX512VL__) __forceinline explicit vuint(__m128 a) : v(_mm_cvtps_epu32(a)) {} #endif #if defined(__AVX512VL__) __forceinline explicit vuint(const vboolf4& a) : v(_mm_movm_epi32(a)) {} #else __forceinline explicit vuint(const vboolf4& a) : v(_mm_castps_si128((__m128)a)) {} #endif //////////////////////////////////////////////////////////////////////////////// /// Constants //////////////////////////////////////////////////////////////////////////////// __forceinline vuint(ZeroTy) : v(_mm_setzero_si128()) {} __forceinline vuint(OneTy) : v(_mm_set1_epi32(1)) {} __forceinline vuint(PosInfTy) : v(_mm_set1_epi32(unsigned(pos_inf))) {} __forceinline vuint(StepTy) : v(_mm_set_epi32(3, 2, 1, 0)) {} __forceinline vuint(TrueTy) { v = _mm_cmpeq_epi32(v,v); } __forceinline vuint(UndefinedTy) : v(_mm_castps_si128(_mm_undefined_ps())) {} //////////////////////////////////////////////////////////////////////////////// /// Loads and Stores //////////////////////////////////////////////////////////////////////////////// static __forceinline vuint4 load (const void* a) { return _mm_load_si128((__m128i*)a); } static __forceinline vuint4 loadu(const void* a) { return _mm_loadu_si128((__m128i*)a); } static __forceinline void store (void* ptr, const vuint4& v) { _mm_store_si128((__m128i*)ptr,v); } static __forceinline void storeu(void* ptr, const vuint4& v) { _mm_storeu_si128((__m128i*)ptr,v); } #if defined(__AVX512VL__) static __forceinline vuint4 load (const vboolf4& mask, const void* ptr) { return _mm_mask_load_epi32 (_mm_setzero_si128(),mask,ptr); } static __forceinline vuint4 loadu(const vboolf4& mask, const void* ptr) { return _mm_mask_loadu_epi32(_mm_setzero_si128(),mask,ptr); } static __forceinline void store (const vboolf4& mask, void* ptr, const vuint4& v) { _mm_mask_store_epi32 (ptr,mask,v); } static __forceinline void storeu(const vboolf4& mask, void* ptr, const vuint4& v) { _mm_mask_storeu_epi32(ptr,mask,v); } #elif defined(__AVX__) static __forceinline vuint4 load (const vbool4& mask, const void* a) { return _mm_castps_si128(_mm_maskload_ps((float*)a,mask)); } static __forceinline vuint4 loadu(const vbool4& mask, const void* a) { return _mm_castps_si128(_mm_maskload_ps((float*)a,mask)); } static __forceinline void store (const vboolf4& mask, void* ptr, const vuint4& i) { _mm_maskstore_ps((float*)ptr,(__m128i)mask,_mm_castsi128_ps(i)); } static __forceinline void storeu(const vboolf4& mask, void* ptr, const vuint4& i) { _mm_maskstore_ps((float*)ptr,(__m128i)mask,_mm_castsi128_ps(i)); } #else static __forceinline vuint4 load (const vbool4& mask, const void* a) { return _mm_and_si128(_mm_load_si128 ((__m128i*)a),mask); } static __forceinline vuint4 loadu(const vbool4& mask, const void* a) { return _mm_and_si128(_mm_loadu_si128((__m128i*)a),mask); } static __forceinline void store (const vboolf4& mask, void* ptr, const vuint4& i) { store (ptr,select(mask,i,load (ptr))); } static __forceinline void storeu(const vboolf4& mask, void* ptr, const vuint4& i) { storeu(ptr,select(mask,i,loadu(ptr))); } #endif #if defined(__aarch64__) static __forceinline vuint4 load(const unsigned char* ptr) { return _mm_load4epu8_epi32(((__m128i*)ptr)); } static __forceinline vuint4 loadu(const unsigned char* ptr) { return _mm_load4epu8_epi32(((__m128i*)ptr)); } #elif defined(__SSE4_1__) static __forceinline vuint4 load(const unsigned char* ptr) { return _mm_cvtepu8_epi32(_mm_loadl_epi64((__m128i*)ptr)); } static __forceinline vuint4 loadu(const unsigned char* ptr) { return _mm_cvtepu8_epi32(_mm_loadl_epi64((__m128i*)ptr)); } #endif static __forceinline vuint4 load(const unsigned short* ptr) { #if defined(__aarch64__) return _mm_load4epu16_epi32(((__m128i*)ptr)); #elif defined (__SSE4_1__) return _mm_cvtepu16_epi32(_mm_loadu_si128((__m128i*)ptr)); #else return vuint4(ptr[0],ptr[1],ptr[2],ptr[3]); #endif } static __forceinline vuint4 load_nt(void* ptr) { #if (defined(__aarch64__)) || defined(__SSE4_1__) return _mm_stream_load_si128((__m128i*)ptr); #else return _mm_load_si128((__m128i*)ptr); #endif } static __forceinline void store_nt(void* ptr, const vuint4& v) { #if !defined(__aarch64__) && defined(__SSE4_1__) _mm_stream_ps((float*)ptr, _mm_castsi128_ps(v)); #else _mm_store_si128((__m128i*)ptr,v); #endif } template static __forceinline vuint4 gather(const unsigned int* ptr, const vint4& index) { #if defined(__AVX2__) && !defined(__aarch64__) return _mm_i32gather_epi32((const int*)ptr, index, scale); #else return vuint4( *(unsigned int*)(((char*)ptr)+scale*index[0]), *(unsigned int*)(((char*)ptr)+scale*index[1]), *(unsigned int*)(((char*)ptr)+scale*index[2]), *(unsigned int*)(((char*)ptr)+scale*index[3])); #endif } template static __forceinline vuint4 gather(const vboolf4& mask, const unsigned int* ptr, const vint4& index) { vuint4 r = zero; #if defined(__AVX512VL__) return _mm_mmask_i32gather_epi32(r, mask, index, ptr, scale); #elif defined(__AVX2__) && !defined(__aarch64__) return _mm_mask_i32gather_epi32(r, (const int*)ptr, index, mask, scale); #else if (likely(mask[0])) r[0] = *(unsigned int*)(((char*)ptr)+scale*index[0]); if (likely(mask[1])) r[1] = *(unsigned int*)(((char*)ptr)+scale*index[1]); if (likely(mask[2])) r[2] = *(unsigned int*)(((char*)ptr)+scale*index[2]); if (likely(mask[3])) r[3] = *(unsigned int*)(((char*)ptr)+scale*index[3]); return r; #endif } //////////////////////////////////////////////////////////////////////////////// /// Array Access //////////////////////////////////////////////////////////////////////////////// __forceinline const unsigned int& operator [](size_t index) const { assert(index < 4); return i[index]; } __forceinline unsigned int& operator [](size_t index) { assert(index < 4); return i[index]; } friend __forceinline vuint4 select(const vboolf4& m, const vuint4& t, const vuint4& f) { #if defined(__AVX512VL__) return _mm_mask_blend_epi32(m, (__m128i)f, (__m128i)t); #elif defined(__SSE4_1__) return _mm_castps_si128(_mm_blendv_ps(_mm_castsi128_ps(f), _mm_castsi128_ps(t), m)); #else return _mm_or_si128(_mm_and_si128(m, t), _mm_andnot_si128(m, f)); #endif } }; //////////////////////////////////////////////////////////////////////////////// /// Unary Operators //////////////////////////////////////////////////////////////////////////////// #if defined(__AVX512VL__) __forceinline vboolf4 asBool(const vuint4& a) { return _mm_movepi32_mask(a); } #else __forceinline vboolf4 asBool(const vuint4& a) { return _mm_castsi128_ps(a); } #endif __forceinline vuint4 operator +(const vuint4& a) { return a; } __forceinline vuint4 operator -(const vuint4& a) { return _mm_sub_epi32(_mm_setzero_si128(), a); } //////////////////////////////////////////////////////////////////////////////// /// Binary Operators //////////////////////////////////////////////////////////////////////////////// __forceinline vuint4 operator +(const vuint4& a, const vuint4& b) { return _mm_add_epi32(a, b); } __forceinline vuint4 operator +(const vuint4& a, unsigned int b) { return a + vuint4(b); } __forceinline vuint4 operator +(unsigned int a, const vuint4& b) { return vuint4(a) + b; } __forceinline vuint4 operator -(const vuint4& a, const vuint4& b) { return _mm_sub_epi32(a, b); } __forceinline vuint4 operator -(const vuint4& a, unsigned int b) { return a - vuint4(b); } __forceinline vuint4 operator -(unsigned int a, const vuint4& b) { return vuint4(a) - b; } //#if defined(__SSE4_1__) // __forceinline vuint4 operator *(const vuint4& a, const vuint4& b) { return _mm_mullo_epu32(a, b); } //#else // __forceinline vuint4 operator *(const vuint4& a, const vuint4& b) { return vuint4(a[0]*b[0],a[1]*b[1],a[2]*b[2],a[3]*b[3]); } //#endif // __forceinline vuint4 operator *(const vuint4& a, unsigned int b) { return a * vuint4(b); } // __forceinline vuint4 operator *(unsigned int a, const vuint4& b) { return vuint4(a) * b; } __forceinline vuint4 operator &(const vuint4& a, const vuint4& b) { return _mm_and_si128(a, b); } __forceinline vuint4 operator &(const vuint4& a, unsigned int b) { return a & vuint4(b); } __forceinline vuint4 operator &(unsigned int a, const vuint4& b) { return vuint4(a) & b; } __forceinline vuint4 operator |(const vuint4& a, const vuint4& b) { return _mm_or_si128(a, b); } __forceinline vuint4 operator |(const vuint4& a, unsigned int b) { return a | vuint4(b); } __forceinline vuint4 operator |(unsigned int a, const vuint4& b) { return vuint4(a) | b; } __forceinline vuint4 operator ^(const vuint4& a, const vuint4& b) { return _mm_xor_si128(a, b); } __forceinline vuint4 operator ^(const vuint4& a, unsigned int b) { return a ^ vuint4(b); } __forceinline vuint4 operator ^(unsigned int a, const vuint4& b) { return vuint4(a) ^ b; } __forceinline vuint4 operator <<(const vuint4& a, unsigned int n) { return _mm_slli_epi32(a, n); } __forceinline vuint4 operator >>(const vuint4& a, unsigned int n) { return _mm_srli_epi32(a, n); } __forceinline vuint4 sll (const vuint4& a, unsigned int b) { return _mm_slli_epi32(a, b); } __forceinline vuint4 sra (const vuint4& a, unsigned int b) { return _mm_srai_epi32(a, b); } __forceinline vuint4 srl (const vuint4& a, unsigned int b) { return _mm_srli_epi32(a, b); } //////////////////////////////////////////////////////////////////////////////// /// Assignment Operators //////////////////////////////////////////////////////////////////////////////// __forceinline vuint4& operator +=(vuint4& a, const vuint4& b) { return a = a + b; } __forceinline vuint4& operator +=(vuint4& a, unsigned int b) { return a = a + b; } __forceinline vuint4& operator -=(vuint4& a, const vuint4& b) { return a = a - b; } __forceinline vuint4& operator -=(vuint4& a, unsigned int b) { return a = a - b; } //#if defined(__SSE4_1__) // __forceinline vuint4& operator *=(vuint4& a, const vuint4& b) { return a = a * b; } // __forceinline vuint4& operator *=(vuint4& a, unsigned int b) { return a = a * b; } //#endif __forceinline vuint4& operator &=(vuint4& a, const vuint4& b) { return a = a & b; } __forceinline vuint4& operator &=(vuint4& a, unsigned int b) { return a = a & b; } __forceinline vuint4& operator |=(vuint4& a, const vuint4& b) { return a = a | b; } __forceinline vuint4& operator |=(vuint4& a, unsigned int b) { return a = a | b; } __forceinline vuint4& operator <<=(vuint4& a, unsigned int b) { return a = a << b; } __forceinline vuint4& operator >>=(vuint4& a, unsigned int b) { return a = a >> b; } //////////////////////////////////////////////////////////////////////////////// /// Comparison Operators + Select //////////////////////////////////////////////////////////////////////////////// #if defined(__AVX512VL__) __forceinline vboolf4 operator ==(const vuint4& a, const vuint4& b) { return _mm_cmp_epu32_mask(a,b,_MM_CMPINT_EQ); } __forceinline vboolf4 operator !=(const vuint4& a, const vuint4& b) { return _mm_cmp_epu32_mask(a,b,_MM_CMPINT_NE); } //__forceinline vboolf4 operator < (const vuint4& a, const vuint4& b) { return _mm_cmp_epu32_mask(a,b,_MM_CMPINT_LT); } //__forceinline vboolf4 operator >=(const vuint4& a, const vuint4& b) { return _mm_cmp_epu32_mask(a,b,_MM_CMPINT_GE); } //__forceinline vboolf4 operator > (const vuint4& a, const vuint4& b) { return _mm_cmp_epu32_mask(a,b,_MM_CMPINT_GT); } //__forceinline vboolf4 operator <=(const vuint4& a, const vuint4& b) { return _mm_cmp_epu32_mask(a,b,_MM_CMPINT_LE); } #else __forceinline vboolf4 operator ==(const vuint4& a, const vuint4& b) { return _mm_castsi128_ps(_mm_cmpeq_epi32(a, b)); } __forceinline vboolf4 operator !=(const vuint4& a, const vuint4& b) { return !(a == b); } //__forceinline vboolf4 operator < (const vuint4& a, const vuint4& b) { return _mm_castsi128_ps(_mm_cmplt_epu32(a, b)); } //__forceinline vboolf4 operator >=(const vuint4& a, const vuint4& b) { return !(a < b); } //__forceinline vboolf4 operator > (const vuint4& a, const vuint4& b) { return _mm_castsi128_ps(_mm_cmpgt_epu32(a, b)); } //__forceinline vboolf4 operator <=(const vuint4& a, const vuint4& b) { return !(a > b); } #endif __forceinline vboolf4 operator ==(const vuint4& a, unsigned int b) { return a == vuint4(b); } __forceinline vboolf4 operator ==(unsigned int a, const vuint4& b) { return vuint4(a) == b; } __forceinline vboolf4 operator !=(const vuint4& a, unsigned int b) { return a != vuint4(b); } __forceinline vboolf4 operator !=(unsigned int a, const vuint4& b) { return vuint4(a) != b; } //__forceinline vboolf4 operator < (const vuint4& a, unsigned int b) { return a < vuint4(b); } //__forceinline vboolf4 operator < (unsigned int a, const vuint4& b) { return vuint4(a) < b; } //__forceinline vboolf4 operator >=(const vuint4& a, unsigned int b) { return a >= vuint4(b); } //__forceinline vboolf4 operator >=(unsigned int a, const vuint4& b) { return vuint4(a) >= b; } //__forceinline vboolf4 operator > (const vuint4& a, unsigned int b) { return a > vuint4(b); } //__forceinline vboolf4 operator > (unsigned int a, const vuint4& b) { return vuint4(a) > b; } //__forceinline vboolf4 operator <=(const vuint4& a, unsigned int b) { return a <= vuint4(b); } //__forceinline vboolf4 operator <=(unsigned int a, const vuint4& b) { return vuint4(a) <= b; } __forceinline vboolf4 eq(const vuint4& a, const vuint4& b) { return a == b; } __forceinline vboolf4 ne(const vuint4& a, const vuint4& b) { return a != b; } //__forceinline vboolf4 lt(const vuint4& a, const vuint4& b) { return a < b; } //__forceinline vboolf4 ge(const vuint4& a, const vuint4& b) { return a >= b; } //__forceinline vboolf4 gt(const vuint4& a, const vuint4& b) { return a > b; } //__forceinline vboolf4 le(const vuint4& a, const vuint4& b) { return a <= b; } #if defined(__AVX512VL__) __forceinline vboolf4 eq(const vboolf4& mask, const vuint4& a, const vuint4& b) { return _mm_mask_cmp_epu32_mask(mask, a, b, _MM_CMPINT_EQ); } __forceinline vboolf4 ne(const vboolf4& mask, const vuint4& a, const vuint4& b) { return _mm_mask_cmp_epu32_mask(mask, a, b, _MM_CMPINT_NE); } //__forceinline vboolf4 lt(const vboolf4& mask, const vuint4& a, const vuint4& b) { return _mm_mask_cmp_epu32_mask(mask, a, b, _MM_CMPINT_LT); } //__forceinline vboolf4 ge(const vboolf4& mask, const vuint4& a, const vuint4& b) { return _mm_mask_cmp_epu32_mask(mask, a, b, _MM_CMPINT_GE); } //__forceinline vboolf4 gt(const vboolf4& mask, const vuint4& a, const vuint4& b) { return _mm_mask_cmp_epu32_mask(mask, a, b, _MM_CMPINT_GT); } //__forceinline vboolf4 le(const vboolf4& mask, const vuint4& a, const vuint4& b) { return _mm_mask_cmp_epu32_mask(mask, a, b, _MM_CMPINT_LE); } #else __forceinline vboolf4 eq(const vboolf4& mask, const vuint4& a, const vuint4& b) { return mask & (a == b); } __forceinline vboolf4 ne(const vboolf4& mask, const vuint4& a, const vuint4& b) { return mask & (a != b); } //__forceinline vboolf4 lt(const vboolf4& mask, const vuint4& a, const vuint4& b) { return mask & (a < b); } //__forceinline vboolf4 ge(const vboolf4& mask, const vuint4& a, const vuint4& b) { return mask & (a >= b); } //__forceinline vboolf4 gt(const vboolf4& mask, const vuint4& a, const vuint4& b) { return mask & (a > b); } //__forceinline vboolf4 le(const vboolf4& mask, const vuint4& a, const vuint4& b) { return mask & (a <= b); } #endif template __forceinline vuint4 select(const vuint4& t, const vuint4& f) { #if defined(__SSE4_1__) return _mm_castps_si128(_mm_blend_ps(_mm_castsi128_ps(f), _mm_castsi128_ps(t), mask)); #else return select(vboolf4(mask), t, f); #endif } /*#if defined(__SSE4_1__) __forceinline vuint4 min(const vuint4& a, const vuint4& b) { return _mm_min_epu32(a, b); } __forceinline vuint4 max(const vuint4& a, const vuint4& b) { return _mm_max_epu32(a, b); } #else __forceinline vuint4 min(const vuint4& a, const vuint4& b) { return select(a < b,a,b); } __forceinline vuint4 max(const vuint4& a, const vuint4& b) { return select(a < b,b,a); } #endif __forceinline vuint4 min(const vuint4& a, unsigned int b) { return min(a,vuint4(b)); } __forceinline vuint4 min(unsigned int a, const vuint4& b) { return min(vuint4(a),b); } __forceinline vuint4 max(const vuint4& a, unsigned int b) { return max(a,vuint4(b)); } __forceinline vuint4 max(unsigned int a, const vuint4& b) { return max(vuint4(a),b); }*/ //////////////////////////////////////////////////////////////////////////////// // Movement/Shifting/Shuffling Functions //////////////////////////////////////////////////////////////////////////////// __forceinline vuint4 unpacklo(const vuint4& a, const vuint4& b) { return _mm_castps_si128(_mm_unpacklo_ps(_mm_castsi128_ps(a), _mm_castsi128_ps(b))); } __forceinline vuint4 unpackhi(const vuint4& a, const vuint4& b) { return _mm_castps_si128(_mm_unpackhi_ps(_mm_castsi128_ps(a), _mm_castsi128_ps(b))); } #if defined(__aarch64__) template __forceinline vuint4 shuffle(const vuint4& v) { return vreinterpretq_s32_u8(vqtbl1q_u8( (uint8x16_t)v.v, _MN_SHUFFLE(i0, i1, i2, i3))); } template __forceinline vuint4 shuffle(const vuint4& a, const vuint4& b) { return vreinterpretq_s32_u8(vqtbl2q_u8( (uint8x16x2_t){(uint8x16_t)a.v, (uint8x16_t)b.v}, _MF_SHUFFLE(i0, i1, i2, i3))); } #else template __forceinline vuint4 shuffle(const vuint4& v) { return _mm_shuffle_epi32(v, _MM_SHUFFLE(i3, i2, i1, i0)); } template __forceinline vuint4 shuffle(const vuint4& a, const vuint4& b) { return _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(a), _mm_castsi128_ps(b), _MM_SHUFFLE(i3, i2, i1, i0))); } #endif #if defined(__SSE3__) template<> __forceinline vuint4 shuffle<0, 0, 2, 2>(const vuint4& v) { return _mm_castps_si128(_mm_moveldup_ps(_mm_castsi128_ps(v))); } template<> __forceinline vuint4 shuffle<1, 1, 3, 3>(const vuint4& v) { return _mm_castps_si128(_mm_movehdup_ps(_mm_castsi128_ps(v))); } template<> __forceinline vuint4 shuffle<0, 1, 0, 1>(const vuint4& v) { return _mm_castpd_si128(_mm_movedup_pd (_mm_castsi128_pd(v))); } #endif template __forceinline vuint4 shuffle(const vuint4& v) { return shuffle(v); } #if defined(__SSE4_1__) && !defined(__aarch64__) template __forceinline unsigned int extract(const vuint4& b) { return _mm_extract_epi32(b, src); } template __forceinline vuint4 insert(const vuint4& a, const unsigned b) { return _mm_insert_epi32(a, b, dst); } #else template __forceinline unsigned int extract(const vuint4& b) { return b[src&3]; } template __forceinline vuint4 insert(const vuint4& a, const unsigned b) { vuint4 c = a; c[dst&3] = b; return c; } #endif template<> __forceinline unsigned int extract<0>(const vuint4& b) { return _mm_cvtsi128_si32(b); } __forceinline unsigned int toScalar(const vuint4& v) { return _mm_cvtsi128_si32(v); } //////////////////////////////////////////////////////////////////////////////// /// Reductions //////////////////////////////////////////////////////////////////////////////// #if 0 #if defined(__SSE4_1__) __forceinline vuint4 vreduce_min(const vuint4& v) { vuint4 h = min(shuffle<1,0,3,2>(v),v); return min(shuffle<2,3,0,1>(h),h); } __forceinline vuint4 vreduce_max(const vuint4& v) { vuint4 h = max(shuffle<1,0,3,2>(v),v); return max(shuffle<2,3,0,1>(h),h); } __forceinline vuint4 vreduce_add(const vuint4& v) { vuint4 h = shuffle<1,0,3,2>(v) + v ; return shuffle<2,3,0,1>(h) + h ; } __forceinline unsigned int reduce_min(const vuint4& v) { return toScalar(vreduce_min(v)); } __forceinline unsigned int reduce_max(const vuint4& v) { return toScalar(vreduce_max(v)); } __forceinline unsigned int reduce_add(const vuint4& v) { return toScalar(vreduce_add(v)); } __forceinline size_t select_min(const vuint4& v) { return bsf(movemask(v == vreduce_min(v))); } __forceinline size_t select_max(const vuint4& v) { return bsf(movemask(v == vreduce_max(v))); } //__forceinline size_t select_min(const vboolf4& valid, const vuint4& v) { const vuint4 a = select(valid,v,vuint4(pos_inf)); return bsf(movemask(valid & (a == vreduce_min(a)))); } //__forceinline size_t select_max(const vboolf4& valid, const vuint4& v) { const vuint4 a = select(valid,v,vuint4(neg_inf)); return bsf(movemask(valid & (a == vreduce_max(a)))); } #else __forceinline unsigned int reduce_min(const vuint4& v) { return min(v[0],v[1],v[2],v[3]); } __forceinline unsigned int reduce_max(const vuint4& v) { return max(v[0],v[1],v[2],v[3]); } __forceinline unsigned int reduce_add(const vuint4& v) { return v[0]+v[1]+v[2]+v[3]; } #endif #endif //////////////////////////////////////////////////////////////////////////////// /// Output Operators //////////////////////////////////////////////////////////////////////////////// __forceinline embree_ostream operator <<(embree_ostream cout, const vuint4& a) { return cout << "<" << a[0] << ", " << a[1] << ", " << a[2] << ", " << a[3] << ">"; } } #undef vboolf #undef vboold #undef vint #undef vuint #undef vllong #undef vfloat #undef vdouble level-zero-raytracing-support-1.0.0/rtbuild/statistics.cpp000066400000000000000000000200051450534701400240120ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "statistics.h" namespace embree { class RestoreStreamState { public: RestoreStreamState(std::ostream& iostream) : iostream(iostream), flags(iostream.flags()), precision(iostream.precision()) { } ~RestoreStreamState() { iostream.flags(flags); iostream.precision(precision); } private: std::ostream& iostream; std::ios::fmtflags flags; std::streamsize precision; }; double ratio(double a, double b) { if (b == 0.0) return 0.0f; else return a/b; } double percent(double a, double b) { return 100.0*ratio(a,b); } double ratio(size_t a, size_t b) { return ratio(double(a), double(b)); } double percent(size_t a, size_t b) { return percent(double(a), double(b)); } void BVHStatistics::NodeStat::print(std::ostream& cout, double totalSAH, size_t totalBytes, size_t numPrimitives) const { RestoreStreamState iostate(cout); cout << std::setw(7) << numNodes << " "; cout << std::setw(7) << std::setprecision(3) << sah(); cout << std::setw(7) << std::setprecision(2) << percent(sah(),totalSAH) << "% "; cout << std::setw(8) << std::setprecision(2) << bytes()/1E6 << " MB "; cout << std::setw(7) << std::setprecision(2) << percent(numBytes,numBytes) << "% "; cout << std::setw(7) << std::setprecision(2) << percent(bytes(),totalBytes) << "% "; cout << std::setw(8) << std::setprecision(2) << ratio(bytes(),numNodes) << " "; cout << std::setw(8) << std::setprecision(2) << ratio(bytes(),numChildrenUsed) << " "; cout << std::setw(8) << std::setprecision(2) << ratio(bytes(),numPrimitives) << " "; cout << std::setw(7) << std::setprecision(2) << ratio(numChildrenUsed,numNodes) << " "; cout << std::setw(7) << std::setprecision(2) << 100.0*fillRate() << "% "; cout << std::endl; } void BVHStatistics::LeafStat::print(std::ostream& cout, double totalSAH, size_t totalBytes, size_t numPrimitives, bool blocks) const { RestoreStreamState iostate(cout); size_t N = blocks ? numBlocks : numLeaves; cout << std::setw(7) << N << " "; cout << std::setw(7) << std::setprecision(3) << sah(); cout << std::setw(7) << std::setprecision(2) << percent(sah(),totalSAH) << "% "; cout << std::setw(8) << std::setprecision(2) << double(bytes())/1E6 << " MB "; cout << std::setw(7) << std::setprecision(2) << percent(numBytesUsed,numBytesTotal) << "% "; cout << std::setw(7) << std::setprecision(2) << percent(bytes(),totalBytes) << "% "; cout << std::setw(8) << std::setprecision(2) << ratio(bytes(),N) << " "; cout << std::setw(8) << std::setprecision(2) << ratio(bytes(),numPrimsUsed) << " "; cout << std::setw(8) << std::setprecision(2) << ratio(bytes(),numPrimitives) << " "; cout << std::setw(7) << std::setprecision(2) << ratio(numPrimsUsed,N) << " "; cout << std::setw(7) << std::setprecision(2) << 100.0*fillRate() << "% "; cout << std::endl; } void BVHStatistics::print (std::ostream& cout) const { RestoreStreamState iostate(cout); cout.setf(std::ios::fixed, std::ios::floatfield); cout.fill(' '); double totalSAH = internalNode.nodeSAH + quadLeaf.leafSAH + proceduralLeaf.leafSAH + instanceLeaf.leafSAH; size_t totalBytes = internalNode.bytes() + quadLeaf.bytes() + proceduralLeaf.bytes() + instanceLeaf.bytes(); size_t totalNodes = internalNode.numNodes + quadLeaf.numLeaves + proceduralLeaf.numLeaves + instanceLeaf.numLeaves; size_t totalPrimitives = quadLeaf.numPrimsUsed + proceduralLeaf.numPrimsUsed + instanceLeaf.numPrimsUsed; cout << std::endl; cout << "BVH statistics:" << std::endl; cout << "---------------" << std::endl; cout << " numScenePrimitives = " << numScenePrimitives << std::endl; cout << " numBuildPrimitives = " << numBuildPrimitives << std::endl; cout << " numBuildPrimitivesPostSplit = " << numBuildPrimitivesPostSplit << std::endl; cout << " primRefSplits = " << std::setprecision(2) << percent(numBuildPrimitivesPostSplit,numBuildPrimitives) << "%" << std::endl; cout << " numBVHPrimitives = " << totalPrimitives << std::endl; cout << " spatialSplits = " << std::setprecision(2) << percent(totalPrimitives,numScenePrimitives) << "%" << std::endl; cout << std::endl; cout << " #nodes SAH total bytes used total b/node b/child b/prim #child fill" << std::endl; cout << "----------------------------------------------------------------------------------------------------------------------" << std::endl; cout << " total : "; cout << std::setw(7) << totalNodes << " "; cout << std::setw(7) << std::setprecision(3) << totalSAH; cout << " 100.00% "; cout << std::setw(8) << std::setprecision(2) << totalBytes/1E6 << " MB "; cout << " 100.00% "; cout << " 100.00% "; cout << " "; cout << " "; cout << std::setw(8) << std::setprecision(2) << ratio(totalBytes,totalPrimitives) << std::endl; LeafStat leaf = quadLeaf + proceduralLeaf + instanceLeaf; cout << " internalNode : "; internalNode .print(cout,totalSAH,totalBytes,totalPrimitives); cout << " leaves : "; leaf .print(cout,totalSAH,totalBytes,totalPrimitives); cout << " quadLeaf : "; quadLeaf .print(cout,totalSAH,totalBytes,totalPrimitives); cout << " proceduralLeaf : "; proceduralLeaf.print(cout,totalSAH,totalBytes,totalPrimitives); cout << " proceduralBlock: "; proceduralLeaf.print(cout,totalSAH,totalBytes,totalPrimitives,true); cout << " instanceLeaf : "; instanceLeaf .print(cout,totalSAH,totalBytes,totalPrimitives); } void BVHStatistics::print_raw(std::ostream& cout) const { RestoreStreamState iostate(cout); size_t totalPrimitives = quadLeaf.numPrimsUsed + proceduralLeaf.numPrimsUsed + instanceLeaf.numPrimsUsed; cout << "bvh_spatial_split_factor = " << percent(totalPrimitives,numBuildPrimitives) << std::endl; cout << "bvh_internal_sah = " << internalNode.nodeSAH << std::endl; cout << "bvh_internal_num = " << internalNode.numNodes << std::endl; cout << "bvh_internal_num_children_used = " << internalNode.numChildrenUsed << std::endl; cout << "bvh_internal_num_children_total = " << internalNode.numChildrenTotal << std::endl; cout << "bvh_internal_num_bytes = " << internalNode.bytes() << std::endl; cout << "bvh_quad_leaf_sah = " << quadLeaf.leafSAH << std::endl; cout << "bvh_quad_leaf_num = " << quadLeaf.numLeaves << std::endl; cout << "bvh_quad_leaf_num_prims_used = " << quadLeaf.numPrimsUsed << std::endl; cout << "bvh_quad_leaf_num_prims_total = " << quadLeaf.numPrimsTotal << std::endl; cout << "bvh_quad_leaf_num_bytes_used = " << quadLeaf.numBytesUsed << std::endl; cout << "bvh_quad_leaf_num_bytes_total = " << quadLeaf.numBytesTotal << std::endl; cout << "bvh_procedural_leaf_sah = " << proceduralLeaf.leafSAH << std::endl; cout << "bvh_procedural_leaf_num = " << proceduralLeaf.numLeaves << std::endl; cout << "bvh_procedural_leaf_num_prims_used = " << proceduralLeaf.numPrimsUsed << std::endl; cout << "bvh_procedural_leaf_num_prims_total = " << proceduralLeaf.numPrimsTotal << std::endl; cout << "bvh_procedural_leaf_num_bytes_used = " << proceduralLeaf.numBytesUsed << std::endl; cout << "bvh_procedural_leaf_num_bytes_total = " << proceduralLeaf.numBytesTotal << std::endl; cout << "bvh_instance_leaf_sah = " << instanceLeaf.leafSAH << std::endl; cout << "bvh_instance_leaf_num = " << instanceLeaf.numLeaves << std::endl; cout << "bvh_instance_leaf_num_prims_used = " << instanceLeaf.numPrimsUsed << std::endl; cout << "bvh_instance_leaf_num_prims_total = " << instanceLeaf.numPrimsTotal << std::endl; cout << "bvh_instance_leaf_num_bytes_used = " << instanceLeaf.numBytesUsed << std::endl; cout << "bvh_instance_leaf_num_bytes_total = " << instanceLeaf.numBytesTotal << std::endl; } } level-zero-raytracing-support-1.0.0/rtbuild/statistics.h000066400000000000000000000100341450534701400234600ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #if defined(ZE_RAYTRACING) #include "sys/platform.h" #else #include "../../../common/sys/platform.h" #endif namespace embree { struct BVHStatistics { struct NodeStat { NodeStat ( double nodeSAH = 0, size_t numNodes = 0, size_t numChildrenUsed = 0, size_t numChildrenTotal = 0, size_t numBytes = 0) : nodeSAH(nodeSAH), numNodes(numNodes), numChildrenUsed(numChildrenUsed), numChildrenTotal(numChildrenTotal), numBytes(numBytes) {} double sah() const { return nodeSAH; } size_t bytes() const { return numBytes; } size_t size() const { return numNodes; } double fillRateNom () const { return double(numChildrenUsed); } double fillRateDen () const { return double(numChildrenTotal); } double fillRate () const { return fillRateDen() ? fillRateNom()/fillRateDen() : 0.0; } friend NodeStat operator+ ( const NodeStat& a, const NodeStat& b) { return NodeStat(a.nodeSAH + b.nodeSAH, a.numNodes+b.numNodes, a.numChildrenUsed+b.numChildrenUsed, a.numChildrenTotal+b.numChildrenTotal, a.numBytes+b.numBytes); } void print(std::ostream& cout, double totalSAH, size_t totalBytes, size_t numPrimitives) const; public: double nodeSAH; size_t numNodes; size_t numChildrenUsed; size_t numChildrenTotal; size_t numBytes; }; struct LeafStat { LeafStat(double leafSAH = 0.0f, size_t numLeaves = 0, size_t numBlocks = 0, size_t numPrimsUsed = 0, size_t numPrimsTotal = 0, size_t numBytesUsed = 0, size_t numBytesTotal = 0) : leafSAH(leafSAH), numLeaves(numLeaves), numBlocks(numBlocks), numPrimsUsed(numPrimsUsed), numPrimsTotal(numPrimsTotal), numBytesUsed(numBytesUsed), numBytesTotal(numBytesTotal) {} double sah() const { return leafSAH; } size_t bytes() const { return numBytesTotal; } size_t size() const { return numLeaves; } double fillRateNom () const { return double(numPrimsUsed); } double fillRateDen () const { return double(numPrimsTotal); } double fillRate () const { return fillRateDen() ? fillRateNom()/fillRateDen() : 0.0; } friend LeafStat operator+ ( const LeafStat& a, const LeafStat& b) { return LeafStat(a.leafSAH + b.leafSAH, a.numLeaves+b.numLeaves, a.numBlocks+b.numBlocks, a.numPrimsUsed+b.numPrimsUsed, a.numPrimsTotal+b.numPrimsTotal, a.numBytesUsed+b.numBytesUsed, a.numBytesTotal+b.numBytesTotal); } void print(std::ostream& cout, double totalSAH, size_t totalBytes, size_t numPrimitives, bool blocks = false) const; public: double leafSAH; //!< SAH of the leaves only size_t numLeaves; //!< Number of leaf nodes. size_t numBlocks; //!< Number of blocks referenced size_t numPrimsUsed; //!< Number of active primitives size_t numPrimsTotal; //!< Number of active and inactive primitives size_t numBytesUsed; //!< Number of used bytes size_t numBytesTotal; //!< Number of total bytes of leaves. }; BVHStatistics () : numScenePrimitives(0), numBuildPrimitives(0), numBuildPrimitivesPostSplit(0) {} void print (std::ostream& cout) const; void print_raw(std::ostream& cout) const; size_t numScenePrimitives; size_t numBuildPrimitives; size_t numBuildPrimitivesPostSplit; NodeStat internalNode; LeafStat quadLeaf; LeafStat proceduralLeaf; LeafStat instanceLeaf; }; } level-zero-raytracing-support-1.0.0/rtbuild/sys/000077500000000000000000000000001450534701400217355ustar00rootroot00000000000000level-zero-raytracing-support-1.0.0/rtbuild/sys/CMakeLists.txt000066400000000000000000000012721450534701400244770ustar00rootroot00000000000000## Copyright 2009-2021 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 SET(CMAKE_THREAD_PREFER_PTHREAD TRUE) FIND_PACKAGE(Threads REQUIRED) ADD_LIBRARY(sys STATIC sysinfo.cpp alloc.cpp ) SET_PROPERTY(TARGET sys PROPERTY FOLDER common) SET_PROPERTY(TARGET sys APPEND PROPERTY COMPILE_FLAGS " ${FLAGS_LOWEST}") TARGET_LINK_LIBRARIES(sys ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS}) IF (EMBREE_SYCL_SUPPORT) TARGET_LINK_LIBRARIES(sys ${SYCL_LIB_NAME}) ENDIF() IF (EMBREE_STATIC_LIB) INSTALL(TARGETS sys EXPORT sys-targets ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT devel) INSTALL(EXPORT sys-targets DESTINATION "${EMBREE_CMAKEEXPORT_DIR}" COMPONENT devel) ENDIF() level-zero-raytracing-support-1.0.0/rtbuild/sys/alloc.cpp000066400000000000000000000232741450534701400235430ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "alloc.h" #include "intrinsics.h" #include "sysinfo.h" //////////////////////////////////////////////////////////////////////////////// /// All Platforms //////////////////////////////////////////////////////////////////////////////// namespace embree { size_t total_allocations = 0; #if defined(EMBREE_SYCL_SUPPORT) __thread sycl::context* tls_context_tutorial = nullptr; __thread sycl::device* tls_device_tutorial = nullptr; __thread sycl::context* tls_context_embree = nullptr; __thread sycl::device* tls_device_embree = nullptr; void enableUSMAllocEmbree(sycl::context* context, sycl::device* device) { if (tls_context_embree != nullptr) throw std::runtime_error("USM allocation already enabled"); if (tls_device_embree != nullptr) throw std::runtime_error("USM allocation already enabled"); tls_context_embree = context; tls_device_embree = device; } void disableUSMAllocEmbree() { if (tls_context_embree == nullptr) throw std::runtime_error("USM allocation not enabled"); if (tls_device_embree == nullptr) throw std::runtime_error("USM allocation not enabled"); tls_context_embree = nullptr; tls_device_embree = nullptr; } void enableUSMAllocTutorial(sycl::context* context, sycl::device* device) { //if (tls_context_tutorial != nullptr) throw std::runtime_error("USM allocation already enabled"); //if (tls_device_tutorial != nullptr) throw std::runtime_error("USM allocation already enabled"); tls_context_tutorial = context; tls_device_tutorial = device; } void disableUSMAllocTutorial() { if (tls_context_tutorial == nullptr) throw std::runtime_error("USM allocation not enabled"); if (tls_device_tutorial == nullptr) throw std::runtime_error("USM allocation not enabled"); tls_context_tutorial = nullptr; tls_device_tutorial = nullptr; } #endif void* alignedMalloc(size_t size, size_t align) { if (size == 0) return nullptr; assert((align & (align-1)) == 0); void* ptr = _mm_malloc(size,align); if (size != 0 && ptr == nullptr) throw std::bad_alloc(); return ptr; } void alignedFree(void* ptr) { if (ptr) _mm_free(ptr); } #if defined(EMBREE_SYCL_SUPPORT) void* alignedSYCLMalloc(sycl::context* context, sycl::device* device, size_t size, size_t align, EmbreeUSMMode mode) { assert(context); assert(device); if (size == 0) return nullptr; assert((align & (align-1)) == 0); total_allocations++; void* ptr = nullptr; if (mode == EMBREE_USM_SHARED_DEVICE_READ_ONLY) ptr = sycl::aligned_alloc_shared(align,size,*device,*context,sycl::ext::oneapi::property::usm::device_read_only()); else ptr = sycl::aligned_alloc_shared(align,size,*device,*context); if (size != 0 && ptr == nullptr) throw std::bad_alloc(); return ptr; } void* alignedSYCLMalloc(size_t size, size_t align, EmbreeUSMMode mode) { if (tls_context_tutorial) return alignedSYCLMalloc(tls_context_tutorial, tls_device_tutorial, size, align, mode); if (tls_context_embree ) return alignedSYCLMalloc(tls_context_embree, tls_device_embree, size, align, mode); return nullptr; } void alignedSYCLFree(sycl::context* context, void* ptr) { assert(context); if (ptr) { sycl::free(ptr,*context); } } void alignedSYCLFree(void* ptr) { if (tls_context_tutorial) return alignedSYCLFree(tls_context_tutorial, ptr); if (tls_context_embree ) return alignedSYCLFree(tls_context_embree, ptr); } #endif void* alignedUSMMalloc(size_t size, size_t align, EmbreeUSMMode mode) { #if defined(EMBREE_SYCL_SUPPORT) if (tls_context_embree || tls_context_tutorial) return alignedSYCLMalloc(size,align,mode); else #endif return alignedMalloc(size,align); } void alignedUSMFree(void* ptr) { #if defined(EMBREE_SYCL_SUPPORT) if (tls_context_embree || tls_context_tutorial) return alignedSYCLFree(ptr); else #endif return alignedFree(ptr); } static bool huge_pages_enabled = false; __forceinline bool isHugePageCandidate(const size_t bytes) { if (!huge_pages_enabled) return false; /* use huge pages only when memory overhead is low */ const size_t hbytes = (bytes+PAGE_SIZE_2M-1) & ~size_t(PAGE_SIZE_2M-1); return 66*(hbytes-bytes) < bytes; // at most 1.5% overhead } } //////////////////////////////////////////////////////////////////////////////// /// Windows Platform //////////////////////////////////////////////////////////////////////////////// #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN #include #include namespace embree { bool win_enable_selockmemoryprivilege (bool verbose) { HANDLE hToken; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken)) { if (verbose) std::cout << "WARNING: OpenProcessToken failed while trying to enable SeLockMemoryPrivilege: " << GetLastError() << std::endl; return false; } TOKEN_PRIVILEGES tp; tp.PrivilegeCount = 1; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if (!LookupPrivilegeValueW(nullptr, L"SeLockMemoryPrivilege", &tp.Privileges[0].Luid)) { if (verbose) std::cout << "WARNING: LookupPrivilegeValue failed while trying to enable SeLockMemoryPrivilege: " << GetLastError() << std::endl; return false; } SetLastError(ERROR_SUCCESS); if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), nullptr, 0)) { if (verbose) std::cout << "WARNING: AdjustTokenPrivileges failed while trying to enable SeLockMemoryPrivilege" << std::endl; return false; } if (GetLastError() == ERROR_NOT_ALL_ASSIGNED) { if (verbose) std::cout << "WARNING: AdjustTokenPrivileges failed to enable SeLockMemoryPrivilege: Add SeLockMemoryPrivilege for current user and run process in elevated mode (Run as administrator)." << std::endl; return false; } return true; } void* os_malloc(size_t bytes, bool& hugepages) { if (bytes == 0) { hugepages = false; return nullptr; } /* try direct huge page allocation first */ if (isHugePageCandidate(bytes)) { int flags = MEM_COMMIT | MEM_RESERVE | MEM_LARGE_PAGES; char* ptr = (char*) VirtualAlloc(nullptr,bytes,flags,PAGE_READWRITE); if (ptr != nullptr) { hugepages = true; return ptr; } } /* fall back to 4k pages */ int flags = MEM_COMMIT | MEM_RESERVE; char* ptr = (char*) VirtualAlloc(nullptr,bytes,flags,PAGE_READWRITE); if (ptr == nullptr) throw std::bad_alloc(); hugepages = false; return ptr; } size_t os_shrink(void* ptr, size_t bytesNew, size_t bytesOld, bool hugepages) { if (hugepages) // decommitting huge pages seems not to work under Windows return bytesOld; const size_t pageSize = hugepages ? PAGE_SIZE_2M : PAGE_SIZE_4K; bytesNew = (bytesNew+pageSize-1) & ~(pageSize-1); bytesOld = (bytesOld+pageSize-1) & ~(pageSize-1); if (bytesNew >= bytesOld) return bytesOld; if (!VirtualFree((char*)ptr+bytesNew,bytesOld-bytesNew,MEM_DECOMMIT)) throw std::bad_alloc(); return bytesNew; } void os_free(void* ptr, size_t bytes, bool hugepages) { if (bytes == 0) return; if (!VirtualFree(ptr,0,MEM_RELEASE)) throw std::bad_alloc(); } void os_advise(void *ptr, size_t bytes) { } } #endif //////////////////////////////////////////////////////////////////////////////// /// Unix Platform //////////////////////////////////////////////////////////////////////////////// #if defined(__UNIX__) #include #include #include #include #include #if defined(__MACOSX__) #include #endif namespace embree { void* os_malloc(size_t bytes, bool& hugepages) { if (bytes == 0) { hugepages = false; return nullptr; } /* try direct huge page allocation first */ if (isHugePageCandidate(bytes)) { #if defined(__MACOSX__) void* ptr = mmap(0, bytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, VM_FLAGS_SUPERPAGE_SIZE_2MB, 0); if (ptr != MAP_FAILED) { hugepages = true; return ptr; } #elif defined(MAP_HUGETLB) void* ptr = mmap(0, bytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON | MAP_HUGETLB, -1, 0); if (ptr != MAP_FAILED) { hugepages = true; return ptr; } #endif } /* fallback to 4k pages */ void* ptr = (char*) mmap(0, bytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); if (ptr == MAP_FAILED) throw std::bad_alloc(); hugepages = false; /* advise huge page hint for THP */ os_advise(ptr,bytes); return ptr; } size_t os_shrink(void* ptr, size_t bytesNew, size_t bytesOld, bool hugepages) { const size_t pageSize = hugepages ? PAGE_SIZE_2M : PAGE_SIZE_4K; bytesNew = (bytesNew+pageSize-1) & ~(pageSize-1); bytesOld = (bytesOld+pageSize-1) & ~(pageSize-1); if (bytesNew >= bytesOld) return bytesOld; if (munmap((char*)ptr+bytesNew,bytesOld-bytesNew) == -1) throw std::bad_alloc(); return bytesNew; } void os_free(void* ptr, size_t bytes, bool hugepages) { if (bytes == 0) return; /* for hugepages we need to also align the size */ const size_t pageSize = hugepages ? PAGE_SIZE_2M : PAGE_SIZE_4K; bytes = (bytes+pageSize-1) & ~(pageSize-1); if (munmap(ptr,bytes) == -1) throw std::bad_alloc(); } /* hint for transparent huge pages (THP) */ void os_advise(void* pptr, size_t bytes) { #if defined(MADV_HUGEPAGE) madvise(pptr,bytes,MADV_HUGEPAGE); #endif } } #endif level-zero-raytracing-support-1.0.0/rtbuild/sys/alloc.h000066400000000000000000000153641450534701400232110ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "platform.h" #include #include namespace embree { #if defined(EMBREE_SYCL_SUPPORT) /* enables SYCL USM allocation */ void enableUSMAllocEmbree(sycl::context* context, sycl::device* device); void enableUSMAllocTutorial(sycl::context* context, sycl::device* device); /* disables SYCL USM allocation */ void disableUSMAllocEmbree(); void disableUSMAllocTutorial(); #endif #define ALIGNED_STRUCT_(align) \ void* operator new(size_t size) { return alignedMalloc(size,align); } \ void operator delete(void* ptr) { alignedFree(ptr); } \ void* operator new[](size_t size) { return alignedMalloc(size,align); } \ void operator delete[](void* ptr) { alignedFree(ptr); } #define ALIGNED_STRUCT_USM_(align) \ void* operator new(size_t size) { return alignedUSMMalloc(size,align); } \ void operator delete(void* ptr) { alignedUSMFree(ptr); } \ void* operator new[](size_t size) { return alignedUSMMalloc(size,align); } \ void operator delete[](void* ptr) { alignedUSMFree(ptr); } #define ALIGNED_CLASS_(align) \ public: \ ALIGNED_STRUCT_(align) \ private: #define ALIGNED_CLASS_USM_(align) \ public: \ ALIGNED_STRUCT_USM_(align) \ private: enum EmbreeUSMMode { EMBREE_USM_SHARED = 0, EMBREE_USM_SHARED_DEVICE_READ_WRITE = 0, EMBREE_USM_SHARED_DEVICE_READ_ONLY = 1 }; /*! aligned allocation */ void* alignedMalloc(size_t size, size_t align); void alignedFree(void* ptr); /*! aligned allocation using SYCL USM */ void* alignedUSMMalloc(size_t size, size_t align = 16, EmbreeUSMMode mode = EMBREE_USM_SHARED_DEVICE_READ_ONLY); void alignedUSMFree(void* ptr); #if defined(EMBREE_SYCL_SUPPORT) /*! aligned allocation using SYCL USM */ void* alignedSYCLMalloc(sycl::context* context, sycl::device* device, size_t size, size_t align, EmbreeUSMMode mode); void alignedSYCLFree(sycl::context* context, void* ptr); // deleter functor to use as deleter in std unique or shared pointers that // capture raw pointers created by sycl::malloc and it's variants template struct sycl_deleter { void operator()(T const* ptr) { alignedUSMFree((void*)ptr); } }; #endif /*! allocator that performs aligned allocations */ template struct aligned_allocator { typedef T value_type; typedef T* pointer; typedef const T* const_pointer; typedef T& reference; typedef const T& const_reference; typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; __forceinline pointer allocate( size_type n ) { return (pointer) alignedMalloc(n*sizeof(value_type),alignment); } __forceinline void deallocate( pointer p, size_type n ) { return alignedFree(p); } __forceinline void construct( pointer p, const_reference val ) { new (p) T(val); } __forceinline void destroy( pointer p ) { p->~T(); } }; /*! allocates pages directly from OS */ bool win_enable_selockmemoryprivilege(bool verbose); bool os_init(bool hugepages, bool verbose); void* os_malloc (size_t bytes, bool& hugepages); size_t os_shrink (void* ptr, size_t bytesNew, size_t bytesOld, bool hugepages); void os_free (void* ptr, size_t bytes, bool hugepages); void os_advise (void* ptr, size_t bytes); /*! allocator that performs OS allocations */ template struct os_allocator { typedef T value_type; typedef T* pointer; typedef const T* const_pointer; typedef T& reference; typedef const T& const_reference; typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; __forceinline os_allocator () : hugepages(false) {} __forceinline pointer allocate( size_type n ) { return (pointer) os_malloc(n*sizeof(value_type),hugepages); } __forceinline void deallocate( pointer p, size_type n ) { return os_free(p,n*sizeof(value_type),hugepages); } __forceinline void construct( pointer p, const_reference val ) { new (p) T(val); } __forceinline void destroy( pointer p ) { p->~T(); } bool hugepages; }; /*! allocator that newer performs allocations */ template struct no_allocator { typedef T value_type; typedef T* pointer; typedef const T* const_pointer; typedef T& reference; typedef const T& const_reference; typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; __forceinline pointer allocate( size_type n ) { throw std::runtime_error("no allocation supported"); } __forceinline void deallocate( pointer p, size_type n ) { } __forceinline void construct( pointer p, const_reference val ) { new (p) T(val); } __forceinline void destroy( pointer p ) { p->~T(); } }; /*! allocator for IDs */ template struct IDPool { typedef T value_type; IDPool () : nextID(0) {} T allocate() { /* return ID from list */ if (!IDs.empty()) { T id = *IDs.begin(); IDs.erase(IDs.begin()); return id; } /* allocate new ID */ else { if (size_t(nextID)+1 > max_id) return -1; return nextID++; } } /* adds an ID provided by the user */ bool add(T id) { if (id > max_id) return false; /* check if ID should be in IDs set */ if (id < nextID) { auto p = IDs.find(id); if (p == IDs.end()) return false; IDs.erase(p); return true; } /* otherwise increase ID set */ else { for (T i=nextID; i IDs; //!< stores deallocated IDs to be reused T nextID; //!< next ID to use when IDs vector is empty }; } level-zero-raytracing-support-1.0.0/rtbuild/sys/array.h000066400000000000000000000153431450534701400232320ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "platform.h" #include "alloc.h" namespace embree { /*! static array with static size */ template class array_t { public: /********************** Iterators ****************************/ __forceinline T* begin() const { return items; }; __forceinline T* end () const { return items+N; }; /********************** Capacity ****************************/ __forceinline bool empty () const { return N == 0; } __forceinline size_t size () const { return N; } __forceinline size_t max_size () const { return N; } /******************** Element access **************************/ __forceinline T& operator[](size_t i) { assert(i < N); return items[i]; } __forceinline const T& operator[](size_t i) const { assert(i < N); return items[i]; } __forceinline T& at(size_t i) { assert(i < N); return items[i]; } __forceinline const T& at(size_t i) const { assert(i < N); return items[i]; } __forceinline T& front() const { assert(N > 0); return items[0]; }; __forceinline T& back () const { assert(N > 0); return items[N-1]; }; __forceinline T* data() { return items; }; __forceinline const T* data() const { return items; }; private: T items[N]; }; /*! static array with dynamic size */ template class darray_t { public: __forceinline darray_t () : M(0) {} __forceinline darray_t (const T& v) : M(0) { for (size_t i=0; i 0); return items[0]; }; __forceinline T& back () { assert(M > 0); return items[M-1]; }; __forceinline T* data() { return items; }; __forceinline const T* data() const { return items; }; private: size_t M; T items[N]; }; /*! dynamic sized array that is allocated on the stack */ #define dynamic_large_stack_array(Ty,Name,N,max_stack_bytes) StackArray Name(N) template struct __aligned(64) StackArray { __forceinline StackArray (const size_t N) : N(N) { if (N*sizeof(Ty) <= max_stack_bytes) data = &arr[0]; else data = (Ty*) alignedMalloc(N*sizeof(Ty),64); } __forceinline ~StackArray () { if (data != &arr[0]) alignedFree(data); } __forceinline operator Ty* () { return data; } __forceinline operator const Ty* () const { return data; } __forceinline Ty& operator[](const int i) { assert(i>=0 && i=0 && i struct __aligned(64) DynamicStackArray { __forceinline DynamicStackArray () : data(&arr[0]) {} __forceinline ~DynamicStackArray () { if (!isStackAllocated()) delete[] data; } __forceinline bool isStackAllocated() const { return data == &arr[0]; } __forceinline size_t size() const { if (isStackAllocated()) return max_stack_elements; else return max_total_elements; } __forceinline void resize(size_t M) { assert(M <= max_total_elements); if (likely(M <= max_stack_elements)) return; if (likely(!isStackAllocated())) return; data = new Ty[max_total_elements]; for (size_t i=0; i=0 && ioperator[] (i) = other[i]; } DynamicStackArray& operator= (const DynamicStackArray& other) { for (size_t i=0; ioperator[] (i) = other[i]; return *this; } private: Ty arr[max_stack_elements]; Ty* data; }; } level-zero-raytracing-support-1.0.0/rtbuild/sys/intrinsics.h000066400000000000000000000277531450534701400243110ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "platform.h" #if defined(__WIN32__) #include #endif #if defined(__ARM_NEON) #include "../simd/arm/emulation.h" #else #include #if defined(__EMSCRIPTEN__) #include "../simd/wasm/emulation.h" #endif #endif #if defined(__BMI__) && defined(__GNUC__) && !defined(__INTEL_COMPILER) #if !defined(_tzcnt_u32) #define _tzcnt_u32 __tzcnt_u32 #endif #if !defined(_tzcnt_u64) #define _tzcnt_u64 __tzcnt_u64 #endif #endif #if defined(__aarch64__) #if !defined(_lzcnt_u32) #define _lzcnt_u32 __builtin_clz #endif #else #if defined(__LZCNT__) #if !defined(_lzcnt_u32) #define _lzcnt_u32 __lzcnt32 #endif #if !defined(_lzcnt_u64) #define _lzcnt_u64 __lzcnt64 #endif #endif #endif #if defined(__WIN32__) # if !defined(NOMINMAX) # define NOMINMAX # endif # include #endif /* normally defined in pmmintrin.h, but we always need this */ #if !defined(_MM_SET_DENORMALS_ZERO_MODE) #define _MM_DENORMALS_ZERO_ON (0x0040) #define _MM_DENORMALS_ZERO_OFF (0x0000) #define _MM_DENORMALS_ZERO_MASK (0x0040) #define _MM_SET_DENORMALS_ZERO_MODE(x) (_mm_setcsr((_mm_getcsr() & ~_MM_DENORMALS_ZERO_MASK) | (x))) #endif namespace embree { //////////////////////////////////////////////////////////////////////////////// /// Windows Platform //////////////////////////////////////////////////////////////////////////////// #if defined(__WIN32__) && !defined(__INTEL_LLVM_COMPILER) __forceinline size_t read_tsc() { LARGE_INTEGER li; QueryPerformanceCounter(&li); return (size_t)li.QuadPart; } __forceinline int bsf(int v) { #if defined(__AVX2__) && !defined(__aarch64__) return _tzcnt_u32(v); #else unsigned long r = 0; _BitScanForward(&r,v); return r; #endif } __forceinline unsigned bsf(unsigned v) { #if defined(__AVX2__) && !defined(__aarch64__) return _tzcnt_u32(v); #else unsigned long r = 0; _BitScanForward(&r,v); return r; #endif } #if defined(__X86_64__) || defined (__aarch64__) __forceinline size_t bsf(size_t v) { #if defined(__AVX2__) return _tzcnt_u64(v); #else unsigned long r = 0; _BitScanForward64(&r,v); return r; #endif } #endif __forceinline int bscf(int& v) { int i = bsf(v); v &= v-1; return i; } __forceinline unsigned bscf(unsigned& v) { unsigned i = bsf(v); v &= v-1; return i; } #if defined(__X86_64__) || defined (__aarch64__) __forceinline size_t bscf(size_t& v) { size_t i = bsf(v); v &= v-1; return i; } #endif __forceinline int bsr(int v) { #if defined(__AVX2__) && !defined(__aarch64__) return 31 - _lzcnt_u32(v); #else unsigned long r = 0; _BitScanReverse(&r,v); return r; #endif } __forceinline unsigned bsr(unsigned v) { #if defined(__AVX2__) && !defined(__aarch64__) return 31 - _lzcnt_u32(v); #else unsigned long r = 0; _BitScanReverse(&r,v); return r; #endif } #if defined(__X86_64__) || defined (__aarch64__) __forceinline size_t bsr(size_t v) { #if defined(__AVX2__) return 63 -_lzcnt_u64(v); #else unsigned long r = 0; _BitScanReverse64(&r, v); return r; #endif } #endif __forceinline int lzcnt(const int x) { #if defined(__AVX2__) && !defined(__aarch64__) return _lzcnt_u32(x); #else if (unlikely(x == 0)) return 32; return 31 - bsr(x); #endif } __forceinline int32_t atomic_cmpxchg(volatile int32_t* p, const int32_t c, const int32_t v) { return _InterlockedCompareExchange((volatile long*)p,v,c); } //////////////////////////////////////////////////////////////////////////////// /// Unix Platform //////////////////////////////////////////////////////////////////////////////// #else __forceinline uint64_t read_tsc() { #if defined(__X86_ASM__) uint32_t high,low; asm volatile ("rdtsc" : "=d"(high), "=a"(low)); return (((uint64_t)high) << 32) + (uint64_t)low; #else /* Not supported yet, meaning measuring traversal cost per pixel does not work. */ return 0; #endif } __forceinline int bsf(int v) { #if defined(__ARM_NEON) return __builtin_ctz(v); #else #if defined(__AVX2__) return _tzcnt_u32(v); #elif defined(__X86_ASM__) int r = 0; asm ("bsf %1,%0" : "=r"(r) : "r"(v)); return r; #else return __builtin_ctz(v); #endif #endif } #if defined(EMBREE_SYCL_SUPPORT) && defined(__SYCL_DEVICE_ONLY__) __forceinline unsigned int bsf(unsigned v) { return SYCL_CTZ::ctz(v); } #else #if defined(__64BIT__) __forceinline unsigned bsf(unsigned v) { #if defined(__ARM_NEON) return __builtin_ctz(v); #else #if defined(__AVX2__) return _tzcnt_u32(v); #elif defined(__X86_ASM__) unsigned r = 0; asm ("bsf %1,%0" : "=r"(r) : "r"(v)); return r; #else return __builtin_ctz(v); #endif #endif } #endif #endif #if defined(EMBREE_SYCL_SUPPORT) && defined(__SYCL_DEVICE_ONLY__) __forceinline size_t bsf(size_t v) { return SYCL_CTZ::ctz(v); } #else __forceinline size_t bsf(size_t v) { #if defined(__AVX2__) && !defined(__aarch64__) #if defined(__X86_64__) return _tzcnt_u64(v); #else return _tzcnt_u32(v); #endif #elif defined(__X86_ASM__) size_t r = 0; asm ("bsf %1,%0" : "=r"(r) : "r"(v)); return r; #else return __builtin_ctzl(v); #endif } #endif __forceinline int bscf(int& v) { int i = bsf(v); v &= v-1; return i; } #if defined(__64BIT__) __forceinline unsigned int bscf(unsigned int& v) { unsigned int i = bsf(v); v &= v-1; return i; } #endif __forceinline size_t bscf(size_t& v) { size_t i = bsf(v); v &= v-1; return i; } __forceinline int bsr(int v) { #if defined(__AVX2__) && !defined(__aarch64__) return 31 - _lzcnt_u32(v); #elif defined(__X86_ASM__) int r = 0; asm ("bsr %1,%0" : "=r"(r) : "r"(v)); return r; #else return __builtin_clz(v) ^ 31; #endif } #if defined(__64BIT__) || defined(__EMSCRIPTEN__) __forceinline unsigned bsr(unsigned v) { #if defined(__AVX2__) return 31 - _lzcnt_u32(v); #elif defined(__X86_ASM__) unsigned r = 0; asm ("bsr %1,%0" : "=r"(r) : "r"(v)); return r; #else return __builtin_clz(v) ^ 31; #endif } #endif __forceinline size_t bsr(size_t v) { #if defined(__AVX2__) && !defined(__aarch64__) #if defined(__X86_64__) return 63 - _lzcnt_u64(v); #else return 31 - _lzcnt_u32(v); #endif #elif defined(__X86_ASM__) size_t r = 0; asm ("bsr %1,%0" : "=r"(r) : "r"(v)); return r; #else return (sizeof(v) * 8 - 1) - __builtin_clzl(v); #endif } __forceinline int lzcnt(const int x) { #if defined(__AVX2__) && !defined(__aarch64__) return _lzcnt_u32(x); #else if (unlikely(x == 0)) return 32; return 31 - bsr(x); #endif } __forceinline size_t blsr(size_t v) { #if defined(__AVX2__) && !defined(__aarch64__) #if defined(__INTEL_COMPILER) return _blsr_u64(v); #else #if defined(__X86_64__) return __blsr_u64(v); #else return __blsr_u32(v); #endif #endif #else return v & (v-1); #endif } __forceinline int32_t atomic_cmpxchg(int32_t volatile* value, int32_t comparand, const int32_t input) { return __sync_val_compare_and_swap(value, comparand, input); } #endif #if !defined(__WIN32__) #if defined(__i386__) && defined(__PIC__) __forceinline void __cpuid(int out[4], int op) { asm volatile ("xchg{l}\t{%%}ebx, %1\n\t" "cpuid\n\t" "xchg{l}\t{%%}ebx, %1\n\t" : "=a"(out[0]), "=r"(out[1]), "=c"(out[2]), "=d"(out[3]) : "0"(op)); } __forceinline void __cpuid_count(int out[4], int op1, int op2) { asm volatile ("xchg{l}\t{%%}ebx, %1\n\t" "cpuid\n\t" "xchg{l}\t{%%}ebx, %1\n\t" : "=a" (out[0]), "=r" (out[1]), "=c" (out[2]), "=d" (out[3]) : "0" (op1), "2" (op2)); } #elif defined(__X86_ASM__) __forceinline void __cpuid(int out[4], int op) { asm volatile ("cpuid" : "=a"(out[0]), "=b"(out[1]), "=c"(out[2]), "=d"(out[3]) : "a"(op)); } __forceinline void __cpuid_count(int out[4], int op1, int op2) { asm volatile ("cpuid" : "=a"(out[0]), "=b"(out[1]), "=c"(out[2]), "=d"(out[3]) : "a"(op1), "c"(op2)); } #endif #endif //////////////////////////////////////////////////////////////////////////////// /// All Platforms //////////////////////////////////////////////////////////////////////////////// #if defined(__clang__) || defined(__GNUC__) #if !defined(_mm_undefined_ps) __forceinline __m128 _mm_undefined_ps() { return _mm_setzero_ps(); } #endif #if !defined(_mm_undefined_si128) __forceinline __m128i _mm_undefined_si128() { return _mm_setzero_si128(); } #endif #if !defined(_mm256_undefined_ps) && defined(__AVX__) __forceinline __m256 _mm256_undefined_ps() { return _mm256_setzero_ps(); } #endif #if !defined(_mm256_undefined_si256) && defined(__AVX__) __forceinline __m256i _mm256_undefined_si256() { return _mm256_setzero_si256(); } #endif #if !defined(_mm512_undefined_ps) && defined(__AVX512F__) __forceinline __m512 _mm512_undefined_ps() { return _mm512_setzero_ps(); } #endif #if !defined(_mm512_undefined_epi32) && defined(__AVX512F__) __forceinline __m512i _mm512_undefined_epi32() { return _mm512_setzero_si512(); } #endif #endif #if defined(EMBREE_SYCL_SUPPORT) && defined(__SYCL_DEVICE_ONLY__) __forceinline unsigned int popcnt(unsigned int in) { return sycl::popcount(in); } #else #if defined(__SSE4_2__) || defined(__ARM_NEON) __forceinline int popcnt(int in) { return _mm_popcnt_u32(in); } __forceinline unsigned popcnt(unsigned in) { return _mm_popcnt_u32(in); } #if defined(__64BIT__) __forceinline size_t popcnt(size_t in) { return _mm_popcnt_u64(in); } #endif #endif #endif #if defined(__X86_ASM__) __forceinline uint64_t rdtsc() { int dummy[4]; __cpuid(dummy,0); uint64_t clock = read_tsc(); __cpuid(dummy,0); return clock; } #endif __forceinline void pause_cpu(const size_t N = 8) { for (size_t i=0; i #include #include #include #include #include #include #include #include #include #include #include #include #if defined(EMBREE_SYCL_SUPPORT) #define __SYCL_USE_NON_VARIADIC_SPIRV_OCL_PRINTF__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" #pragma clang diagnostic ignored "-W#pragma-messages" #include #pragma clang diagnostic pop #define SYCL_ONEAPI sycl #define SYCL_EXT_ONEAPI sycl::ext::oneapi #define SYCL_SUBGROUP sycl #define SYCL_EXPERIMENTAL sycl::ext::oneapi::experimental #define SYCL_INTEL sycl::ext::intel #define SYCL_CTZ sycl #include "sycl.h" #if defined(EMBREE_SYCL_SUPPORT) && defined(__SYCL_DEVICE_ONLY__) #define CONSTANT __attribute__((opencl_constant)) #else #define CONSTANT #endif #endif //////////////////////////////////////////////////////////////////////////////// /// detect platform //////////////////////////////////////////////////////////////////////////////// /* detect 32 or 64 Intel platform */ #if defined(__x86_64__) || defined(__ia64__) || defined(_M_X64) #define __X86_64__ #define __X86_ASM__ #elif defined(__i386__) || defined(_M_IX86) #define __X86_ASM__ #endif /* detect 64 bit platform */ #if defined(__X86_64__) || defined(__aarch64__) #define __64BIT__ #endif /* detect Linux platform */ #if defined(linux) || defined(__linux__) || defined(__LINUX__) # if !defined(__LINUX__) # define __LINUX__ # endif # if !defined(__UNIX__) # define __UNIX__ # endif #endif /* detect FreeBSD platform */ #if defined(__FreeBSD__) || defined(__FREEBSD__) # if !defined(__FREEBSD__) # define __FREEBSD__ # endif # if !defined(__UNIX__) # define __UNIX__ # endif #endif /* detect Windows 95/98/NT/2000/XP/Vista/7/8/10 platform */ #if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)) && !defined(__CYGWIN__) # if !defined(__WIN32__) # define __WIN32__ # endif #endif /* detect Cygwin platform */ #if defined(__CYGWIN__) # if !defined(__UNIX__) # define __UNIX__ # endif #endif /* detect MAC OS X platform */ #if defined(__APPLE__) || defined(MACOSX) || defined(__MACOSX__) # if !defined(__MACOSX__) # define __MACOSX__ # endif # if !defined(__UNIX__) # define __UNIX__ # endif #endif /* try to detect other Unix systems */ #if defined(__unix__) || defined (unix) || defined(__unix) || defined(_unix) # if !defined(__UNIX__) # define __UNIX__ # endif #endif //////////////////////////////////////////////////////////////////////////////// /// Macros //////////////////////////////////////////////////////////////////////////////// #ifdef __WIN32__ # if defined(EMBREE_STATIC_LIB) # define dll_export # define dll_import # else # define dll_export __declspec(dllexport) # define dll_import __declspec(dllimport) # endif #else # define dll_export __attribute__ ((visibility ("default"))) # define dll_import #endif #if defined(__WIN32__) && !defined(__MINGW32__) #if !defined(__noinline) #define __noinline __declspec(noinline) #endif //#define __forceinline __forceinline //#define __restrict __restrict #if defined(__INTEL_COMPILER) #define __restrict__ __restrict #else #define __restrict__ //__restrict // causes issues with MSVC #endif #if !defined(__thread) && !defined(__INTEL_LLVM_COMPILER) #define __thread __declspec(thread) #endif #if !defined(__aligned) #define __aligned(...) __declspec(align(__VA_ARGS__)) #endif //#define __FUNCTION__ __FUNCTION__ #define debugbreak() __debugbreak() #else #if !defined(__noinline) #define __noinline __attribute__((noinline)) #endif #if !defined(__forceinline) #define __forceinline inline __attribute__((always_inline)) #endif //#define __restrict __restrict //#define __thread __thread #if !defined(__aligned) #define __aligned(...) __attribute__((aligned(__VA_ARGS__))) #endif #if !defined(__FUNCTION__) #define __FUNCTION__ __PRETTY_FUNCTION__ #endif #define debugbreak() asm ("int $3") #endif #if defined(__clang__) || defined(__GNUC__) #define MAYBE_UNUSED __attribute__((unused)) #else #define MAYBE_UNUSED #endif #if !defined(_unused) #define _unused(x) ((void)(x)) #endif #if defined(_MSC_VER) && (_MSC_VER < 1900) // before VS2015 deleted functions are not supported properly #define DELETED #else #define DELETED = delete #endif #if !defined(likely) #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) || defined(__SYCL_DEVICE_ONLY__) #define likely(expr) (expr) #define unlikely(expr) (expr) #else #define likely(expr) __builtin_expect((bool)(expr),true ) #define unlikely(expr) __builtin_expect((bool)(expr),false) #endif #endif //////////////////////////////////////////////////////////////////////////////// /// Error handling and debugging //////////////////////////////////////////////////////////////////////////////// /* debug printing macros */ #define STRING(x) #x #define TOSTRING(x) STRING(x) #define PING embree_cout_uniform << __FILE__ << " (" << __LINE__ << "): " << __FUNCTION__ << embree_endl #define PRINT(x) embree_cout << STRING(x) << " = " << (x) << embree_endl #define PRINT2(x,y) embree_cout << STRING(x) << " = " << (x) << ", " << STRING(y) << " = " << (y) << embree_endl #define PRINT3(x,y,z) embree_cout << STRING(x) << " = " << (x) << ", " << STRING(y) << " = " << (y) << ", " << STRING(z) << " = " << (z) << embree_endl #define PRINT4(x,y,z,w) embree_cout << STRING(x) << " = " << (x) << ", " << STRING(y) << " = " << (y) << ", " << STRING(z) << " = " << (z) << ", " << STRING(w) << " = " << (w) << embree_endl #define UPRINT(x) embree_cout_uniform << STRING(x) << " = " << (x) << embree_endl #define UPRINT2(x,y) embree_cout_uniform << STRING(x) << " = " << (x) << ", " << STRING(y) << " = " << (y) << embree_endl #define UPRINT3(x,y,z) embree_cout_uniform << STRING(x) << " = " << (x) << ", " << STRING(y) << " = " << (y) << ", " << STRING(z) << " = " << (z) << embree_endl #define UPRINT4(x,y,z,w) embree_cout_uniform << STRING(x) << " = " << (x) << ", " << STRING(y) << " = " << (y) << ", " << STRING(z) << " = " << (z) << ", " << STRING(w) << " = " << (w) << embree_endl #if defined(DEBUG) // only report file and line in debug mode #define THROW_RUNTIME_ERROR(str) \ throw std::runtime_error(std::string(__FILE__) + " (" + toString(__LINE__) + "): " + std::string(str)); #else #define THROW_RUNTIME_ERROR(str) \ throw std::runtime_error(str); #endif #define FATAL(x) THROW_RUNTIME_ERROR(x) #define WARNING(x) { std::cerr << "Warning: " << x << embree_endl << std::flush; } #define NOT_IMPLEMENTED FATAL(std::string(__FUNCTION__) + " not implemented") //////////////////////////////////////////////////////////////////////////////// /// Basic types //////////////////////////////////////////////////////////////////////////////// /* default floating-point type */ namespace embree { typedef float real; } /* windows does not have ssize_t */ #if defined(__WIN32__) #if defined(__64BIT__) typedef int64_t ssize_t; #else typedef int32_t ssize_t; #endif #endif //////////////////////////////////////////////////////////////////////////////// /// Basic utility functions //////////////////////////////////////////////////////////////////////////////// __forceinline std::string toString(long long value) { return std::to_string(value); } //////////////////////////////////////////////////////////////////////////////// /// Disable some compiler warnings //////////////////////////////////////////////////////////////////////////////// #if defined(__INTEL_COMPILER) //#pragma warning(disable:265 ) // floating-point operation result is out of range //#pragma warning(disable:383 ) // value copied to temporary, reference to temporary used //#pragma warning(disable:869 ) // parameter was never referenced //#pragma warning(disable:981 ) // operands are evaluated in unspecified order //#pragma warning(disable:1418) // external function definition with no prior declaration //#pragma warning(disable:1419) // external declaration in primary source file //#pragma warning(disable:1572) // floating-point equality and inequality comparisons are unreliable //#pragma warning(disable:94 ) // the size of an array must be greater than zero //#pragma warning(disable:1599) // declaration hides parameter //#pragma warning(disable:424 ) // extra ";" ignored #pragma warning(disable:2196) // routine is both "inline" and "noinline" //#pragma warning(disable:177 ) // label was declared but never referenced //#pragma warning(disable:114 ) // function was referenced but not defined //#pragma warning(disable:819 ) // template nesting depth does not match the previous declaration of function #pragma warning(disable:15335) // was not vectorized: vectorization possible but seems inefficient #endif #if defined(_MSC_VER) //#pragma warning(disable:4200) // nonstandard extension used : zero-sized array in struct/union #pragma warning(disable:4800) // forcing value to bool 'true' or 'false' (performance warning) //#pragma warning(disable:4267) // '=' : conversion from 'size_t' to 'unsigned long', possible loss of data #pragma warning(disable:4244) // 'argument' : conversion from 'ssize_t' to 'unsigned int', possible loss of data #pragma warning(disable:4267) // conversion from 'size_t' to 'const int', possible loss of data //#pragma warning(disable:4355) // 'this' : used in base member initializer list //#pragma warning(disable:391 ) // '<=' : signed / unsigned mismatch //#pragma warning(disable:4018) // '<' : signed / unsigned mismatch //#pragma warning(disable:4305) // 'initializing' : truncation from 'double' to 'float' //#pragma warning(disable:4068) // unknown pragma //#pragma warning(disable:4146) // unary minus operator applied to unsigned type, result still unsigned //#pragma warning(disable:4838) // conversion from 'unsigned int' to 'const int' requires a narrowing conversion) //#pragma warning(disable:4227) // anachronism used : qualifiers on reference are ignored #pragma warning(disable:4503) // decorated name length exceeded, name was truncated #pragma warning(disable:4180) // qualifier applied to function type has no meaning; ignored #pragma warning(disable:4258) // definition from the for loop is ignored; the definition from the enclosing scope is used # if _MSC_VER < 1910 // prior to Visual studio 2017 (V141) # pragma warning(disable:4101) // warning C4101: 'x': unreferenced local variable // a compiler bug issues wrong warnings # pragma warning(disable:4789) // buffer '' of size 8 bytes will be overrun; 32 bytes will be written starting at offset 0 # endif #endif #if defined(__clang__) && !defined(__INTEL_COMPILER) //#pragma clang diagnostic ignored "-Wunknown-pragmas" //#pragma clang diagnostic ignored "-Wunused-variable" //#pragma clang diagnostic ignored "-Wreorder" //#pragma clang diagnostic ignored "-Wmicrosoft" //#pragma clang diagnostic ignored "-Wunused-private-field" //#pragma clang diagnostic ignored "-Wunused-local-typedef" //#pragma clang diagnostic ignored "-Wunused-function" //#pragma clang diagnostic ignored "-Wnarrowing" //#pragma clang diagnostic ignored "-Wc++11-narrowing" //#pragma clang diagnostic ignored "-Wdeprecated-register" //#pragma clang diagnostic ignored "-Wdeprecated-declarations" #endif #if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(__clang__) #pragma GCC diagnostic ignored "-Wpragmas" //#pragma GCC diagnostic ignored "-Wnarrowing" #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" //#pragma GCC diagnostic ignored "-Wdeprecated-declarations" //#pragma GCC diagnostic ignored "-Warray-bounds" #pragma GCC diagnostic ignored "-Wattributes" #pragma GCC diagnostic ignored "-Wmisleading-indentation" #pragma GCC diagnostic ignored "-Wsign-compare" #pragma GCC diagnostic ignored "-Wparentheses" #endif #if defined(__clang__) && defined(__WIN32__) #pragma clang diagnostic ignored "-Wunused-parameter" #pragma clang diagnostic ignored "-Wmicrosoft-cast" #pragma clang diagnostic ignored "-Wmicrosoft-enum-value" #pragma clang diagnostic ignored "-Wmicrosoft-include" #pragma clang diagnostic ignored "-Wunused-function" #pragma clang diagnostic ignored "-Wunknown-pragmas" #endif /* disabling deprecated warning, please use only where use of deprecated Embree API functions is desired */ #if defined(__WIN32__) && defined(__INTEL_COMPILER) #define DISABLE_DEPRECATED_WARNING __pragma(warning (disable: 1478)) // warning: function was declared deprecated #define ENABLE_DEPRECATED_WARNING __pragma(warning (enable: 1478)) // warning: function was declared deprecated #elif defined(__INTEL_COMPILER) #define DISABLE_DEPRECATED_WARNING _Pragma("warning (disable: 1478)") // warning: function was declared deprecated #define ENABLE_DEPRECATED_WARNING _Pragma("warning (enable : 1478)") // warning: function was declared deprecated #elif defined(__clang__) #define DISABLE_DEPRECATED_WARNING _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"") // warning: xxx is deprecated #define ENABLE_DEPRECATED_WARNING _Pragma("clang diagnostic warning \"-Wdeprecated-declarations\"") // warning: xxx is deprecated #elif defined(__GNUC__) #define DISABLE_DEPRECATED_WARNING _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") // warning: xxx is deprecated #define ENABLE_DEPRECATED_WARNING _Pragma("GCC diagnostic warning \"-Wdeprecated-declarations\"") // warning: xxx is deprecated #elif defined(_MSC_VER) #define DISABLE_DEPRECATED_WARNING __pragma(warning (disable: 4996)) // warning: function was declared deprecated #define ENABLE_DEPRECATED_WARNING __pragma(warning (enable : 4996)) // warning: function was declared deprecated #endif //////////////////////////////////////////////////////////////////////////////// /// SYCL specific //////////////////////////////////////////////////////////////////////////////// #if defined(EMBREE_SYCL_SUPPORT) && defined(__SYCL_DEVICE_ONLY__) #define sycl_printf0(format, ...) { \ static const CONSTANT char fmt[] = format; \ if (get_sub_group_local_id() == SYCL_CTZ::ctz(intel_sub_group_ballot(true))) \ SYCL_EXT_ONEAPI::experimental::printf(fmt, __VA_ARGS__ ); \ } #define sycl_printf0_(format) { \ static const CONSTANT char fmt[] = format; \ if (get_sub_group_local_id() == SYCL_CTZ::ctz(intel_sub_group_ballot(true))) \ SYCL_EXT_ONEAPI::experimental::printf(fmt); \ } #else #define sycl_printf0(format, ...) { \ static const CONSTANT char fmt[] = format; \ SYCL_EXT_ONEAPI::experimental::printf(fmt, __VA_ARGS__ ); \ } #define sycl_printf0_(format) { \ static const CONSTANT char fmt[] = format; \ SYCL_EXT_ONEAPI::experimental::printf(fmt); \ } #endif #define sycl_printf(format, ...) { \ static const CONSTANT char fmt[] = format; \ SYCL_EXT_ONEAPI::experimental::printf(fmt, __VA_ARGS__ ); \ } #define sycl_printf_(format) { \ static const CONSTANT char fmt[] = format; \ SYCL_EXT_ONEAPI::experimental::printf(fmt); \ } #if defined(EMBREE_SYCL_SUPPORT) && defined(__SYCL_DEVICE_ONLY__) namespace embree { struct sycl_ostream_ { sycl_ostream_ (bool uniform) : uniform(uniform) {} bool uniform = false; }; struct sycl_endl_ {}; #define embree_ostream embree::sycl_ostream_ #define embree_cout embree::sycl_ostream_(false) #define embree_cout_uniform embree::sycl_ostream_(true) #define embree_endl embree::sycl_endl_() inline sycl_ostream_ operator <<(sycl_ostream_ cout, int i) { if (cout.uniform) { if (get_sub_group_local_id() == SYCL_CTZ::ctz(intel_sub_group_ballot(true))) sycl_printf("%i",i); } else sycl_printf("%i ",i); return cout; } inline sycl_ostream_ operator <<(sycl_ostream_ cout, unsigned int i) { if (cout.uniform) { if (get_sub_group_local_id() == SYCL_CTZ::ctz(intel_sub_group_ballot(true))) sycl_printf("%u",i); } else sycl_printf("%u ",i); return cout; } #if defined(__WIN32__) and defined(__INTEL_LLVM_COMPILER) inline sycl_ostream_ operator <<(sycl_ostream_ cout, size_t i) { if (cout.uniform) { if (get_sub_group_local_id() == SYCL_CTZ::ctz(intel_sub_group_ballot(true))) sycl_printf("%i",i); } else { sycl_printf("%i ",i); } return cout; } #endif inline sycl_ostream_ operator <<(sycl_ostream_ cout, float f) { if (cout.uniform) { if (get_sub_group_local_id() == SYCL_CTZ::ctz(intel_sub_group_ballot(true))) sycl_printf("%f",f); } else sycl_printf("%f ",f); return cout; } inline sycl_ostream_ operator <<(sycl_ostream_ cout, double d) { if (cout.uniform) { if (get_sub_group_local_id() == SYCL_CTZ::ctz(intel_sub_group_ballot(true))) sycl_printf("%f",d); } else sycl_printf("%f ",d); return cout; } inline sycl_ostream_ operator <<(sycl_ostream_ cout, ulong l) { if (cout.uniform) { if (get_sub_group_local_id() == SYCL_CTZ::ctz(intel_sub_group_ballot(true))) sycl_printf("%lu",l); } else sycl_printf("%lu ",l); return cout; } inline sycl_ostream_ operator <<(sycl_ostream_ cout, long l) { if (cout.uniform) { if (get_sub_group_local_id() == SYCL_CTZ::ctz(intel_sub_group_ballot(true))) sycl_printf("%l",l); } else sycl_printf("%l ",l); return cout; } inline sycl_ostream_ operator <<(sycl_ostream_ cout, void* p) { if (cout.uniform) { if (get_sub_group_local_id() == SYCL_CTZ::ctz(intel_sub_group_ballot(true))) sycl_printf("%p",p); } else sycl_printf("%p ",p); return cout; } inline sycl_ostream_ operator <<(sycl_ostream_ cout, const char* c) { if (get_sub_group_local_id() == SYCL_CTZ::ctz(intel_sub_group_ballot(true))) sycl_printf("%s",c); return cout; } inline sycl_ostream_ operator <<(sycl_ostream_ cout, sycl_endl_) { if (get_sub_group_local_id() == SYCL_CTZ::ctz(intel_sub_group_ballot(true))) sycl_printf_("\n"); return cout; } } #else #define embree_ostream std::ostream& #define embree_cout std::cout #define embree_cout_uniform std::cout #define embree_endl std::endl #endif #if defined(EMBREE_SYCL_SUPPORT) /* printing out sycle vector types */ __forceinline embree_ostream operator<<(embree_ostream out, const sycl::float4& v) { return out << "(" << v.x() << "," << v.y() << "," << v.z() << "," << v.w() << ")"; } __forceinline embree_ostream operator<<(embree_ostream out, const sycl::float3& v) { return out << "(" << v.x() << "," << v.y() << "," << v.z() << ")"; } __forceinline embree_ostream operator<<(embree_ostream out, const sycl::float2& v) { return out << "(" << v.x() << "," << v.y() << ")"; } __forceinline embree_ostream operator<<(embree_ostream out, const sycl::int4& v) { return out << "(" << v.x() << "," << v.y() << "," << v.z() << "," << v.w() << ")"; } __forceinline embree_ostream operator<<(embree_ostream out, const sycl::int3& v) { return out << "(" << v.x() << "," << v.y() << "," << v.z() << ")"; } __forceinline embree_ostream operator<<(embree_ostream out, const sycl::int2& v) { return out << "(" << v.x() << "," << v.y() << ")"; } __forceinline embree_ostream operator<<(embree_ostream out, const sycl::uint4& v) { return out << "(" << v.x() << "," << v.y() << "," << v.z() << "," << v.w() << ")"; } __forceinline embree_ostream operator<<(embree_ostream out, const sycl::uint3& v) { return out << "(" << v.x() << "," << v.y() << "," << v.z() << ")"; } __forceinline embree_ostream operator<<(embree_ostream out, const sycl::uint2& v) { return out << "(" << v.x() << "," << v.y() << ")"; } #endif inline void tab(std::ostream& cout, int n) { for (int i=0; i struct OnScopeExitHelper { OnScopeExitHelper (const Closure f) : active(true), f(f) {} ~OnScopeExitHelper() { if (active) f(); } void deactivate() { active = false; } bool active; const Closure f; }; template OnScopeExitHelper OnScopeExit(const Closure f) { return OnScopeExitHelper(f); } #define STRING_JOIN2(arg1, arg2) DO_STRING_JOIN2(arg1, arg2) #define DO_STRING_JOIN2(arg1, arg2) arg1 ## arg2 #define ON_SCOPE_EXIT(code) \ auto STRING_JOIN2(on_scope_exit_, __LINE__) = OnScopeExit([&](){code;}) template std::unique_ptr make_unique(Ty* ptr) { return std::unique_ptr(ptr); } } level-zero-raytracing-support-1.0.0/rtbuild/sys/sysinfo.cpp000066400000000000000000000613171450534701400241430ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #if defined(__INTEL_LLVM_COMPILER) // prevents "'__thiscall' calling convention is not supported for this target" warning from TBB #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wignored-attributes" #endif #include "sysinfo.h" #include "intrinsics.h" #if defined(__FREEBSD__) #include #include typedef cpuset_t cpu_set_t; #endif //////////////////////////////////////////////////////////////////////////////// /// All Platforms //////////////////////////////////////////////////////////////////////////////// namespace embree { //NullTy null; std::string getPlatformName() { #if defined(__ANDROID__) && !defined(__64BIT__) return "Android (32bit)"; #elif defined(__ANDROID__) && defined(__64BIT__) return "Android (64bit)"; #elif defined(__LINUX__) && !defined(__64BIT__) return "Linux (32bit)"; #elif defined(__LINUX__) && defined(__64BIT__) return "Linux (64bit)"; #elif defined(__FREEBSD__) && !defined(__64BIT__) return "FreeBSD (32bit)"; #elif defined(__FREEBSD__) && defined(__64BIT__) return "FreeBSD (64bit)"; #elif defined(__CYGWIN__) && !defined(__64BIT__) return "Cygwin (32bit)"; #elif defined(__CYGWIN__) && defined(__64BIT__) return "Cygwin (64bit)"; #elif defined(__WIN32__) && !defined(__64BIT__) return "Windows (32bit)"; #elif defined(__WIN32__) && defined(__64BIT__) return "Windows (64bit)"; #elif defined(__MACOSX__) && !defined(__64BIT__) return "Mac OS X (32bit)"; #elif defined(__MACOSX__) && defined(__64BIT__) return "Mac OS X (64bit)"; #elif defined(__UNIX__) && !defined(__64BIT__) return "Unix (32bit)"; #elif defined(__UNIX__) && defined(__64BIT__) return "Unix (64bit)"; #else return "Unknown"; #endif } std::string getCompilerName() { #if defined(__INTEL_COMPILER) int icc_mayor = __INTEL_COMPILER / 100 % 100; int icc_minor = __INTEL_COMPILER % 100; std::string version = "Intel Compiler "; version += toString(icc_mayor); version += "." + toString(icc_minor); #if defined(__INTEL_COMPILER_UPDATE) version += "." + toString(__INTEL_COMPILER_UPDATE); #endif return version; #elif defined(__clang__) return "CLANG " __clang_version__; #elif defined (__GNUC__) return "GCC " __VERSION__; #elif defined(_MSC_VER) std::string version = toString(_MSC_FULL_VER); version.insert(4,"."); version.insert(9,"."); version.insert(2,"."); return "Visual C++ Compiler " + version; #else return "Unknown Compiler"; #endif } std::string getCPUVendor() { #if defined(__X86_ASM__) int cpuinfo[4]; __cpuid (cpuinfo, 0); int name[4]; name[0] = cpuinfo[1]; name[1] = cpuinfo[3]; name[2] = cpuinfo[2]; name[3] = 0; return (char*)name; #elif defined(__ARM_NEON) return "ARM"; #else return "Unknown"; #endif } CPU getCPUModel() { #if defined(__X86_ASM__) if (getCPUVendor() != "GenuineIntel") return CPU::UNKNOWN; int out[4]; __cpuid(out, 0); if (out[0] < 1) return CPU::UNKNOWN; __cpuid(out, 1); /* please see CPUID documentation for these formulas */ uint32_t family_ID = (out[0] >> 8) & 0x0F; uint32_t extended_family_ID = (out[0] >> 20) & 0xFF; uint32_t model_ID = (out[0] >> 4) & 0x0F; uint32_t extended_model_ID = (out[0] >> 16) & 0x0F; uint32_t DisplayFamily = family_ID; if (family_ID == 0x0F) DisplayFamily += extended_family_ID; uint32_t DisplayModel = model_ID; if (family_ID == 0x06 || family_ID == 0x0F) DisplayModel += extended_model_ID << 4; uint32_t DisplayFamily_DisplayModel = (DisplayFamily << 8) + (DisplayModel << 0); // Data from Intel® 64 and IA-32 Architectures, Volume 4, Chapter 2, Table 2-1 (CPUID Signature Values of DisplayFamily_DisplayModel) if (DisplayFamily_DisplayModel == 0x067D) return CPU::CORE_ICE_LAKE; if (DisplayFamily_DisplayModel == 0x067E) return CPU::CORE_ICE_LAKE; if (DisplayFamily_DisplayModel == 0x068C) return CPU::CORE_TIGER_LAKE; if (DisplayFamily_DisplayModel == 0x06A5) return CPU::CORE_COMET_LAKE; if (DisplayFamily_DisplayModel == 0x06A6) return CPU::CORE_COMET_LAKE; if (DisplayFamily_DisplayModel == 0x0666) return CPU::CORE_CANNON_LAKE; if (DisplayFamily_DisplayModel == 0x068E) return CPU::CORE_KABY_LAKE; if (DisplayFamily_DisplayModel == 0x069E) return CPU::CORE_KABY_LAKE; if (DisplayFamily_DisplayModel == 0x066A) return CPU::XEON_ICE_LAKE; if (DisplayFamily_DisplayModel == 0x066C) return CPU::XEON_ICE_LAKE; if (DisplayFamily_DisplayModel == 0x0655) return CPU::XEON_SKY_LAKE; if (DisplayFamily_DisplayModel == 0x064E) return CPU::CORE_SKY_LAKE; if (DisplayFamily_DisplayModel == 0x065E) return CPU::CORE_SKY_LAKE; if (DisplayFamily_DisplayModel == 0x0656) return CPU::XEON_BROADWELL; if (DisplayFamily_DisplayModel == 0x064F) return CPU::XEON_BROADWELL; if (DisplayFamily_DisplayModel == 0x0647) return CPU::CORE_BROADWELL; if (DisplayFamily_DisplayModel == 0x063D) return CPU::CORE_BROADWELL; if (DisplayFamily_DisplayModel == 0x063F) return CPU::XEON_HASWELL; if (DisplayFamily_DisplayModel == 0x063C) return CPU::CORE_HASWELL; if (DisplayFamily_DisplayModel == 0x0645) return CPU::CORE_HASWELL; if (DisplayFamily_DisplayModel == 0x0646) return CPU::CORE_HASWELL; if (DisplayFamily_DisplayModel == 0x063E) return CPU::XEON_IVY_BRIDGE; if (DisplayFamily_DisplayModel == 0x063A) return CPU::CORE_IVY_BRIDGE; if (DisplayFamily_DisplayModel == 0x062D) return CPU::SANDY_BRIDGE; if (DisplayFamily_DisplayModel == 0x062F) return CPU::SANDY_BRIDGE; if (DisplayFamily_DisplayModel == 0x062A) return CPU::SANDY_BRIDGE; if (DisplayFamily_DisplayModel == 0x062E) return CPU::NEHALEM; if (DisplayFamily_DisplayModel == 0x0625) return CPU::NEHALEM; if (DisplayFamily_DisplayModel == 0x062C) return CPU::NEHALEM; if (DisplayFamily_DisplayModel == 0x061E) return CPU::NEHALEM; if (DisplayFamily_DisplayModel == 0x061F) return CPU::NEHALEM; if (DisplayFamily_DisplayModel == 0x061A) return CPU::NEHALEM; if (DisplayFamily_DisplayModel == 0x061D) return CPU::NEHALEM; if (DisplayFamily_DisplayModel == 0x0617) return CPU::CORE2; if (DisplayFamily_DisplayModel == 0x060F) return CPU::CORE2; if (DisplayFamily_DisplayModel == 0x060E) return CPU::CORE1; if (DisplayFamily_DisplayModel == 0x0685) return CPU::XEON_PHI_KNIGHTS_MILL; if (DisplayFamily_DisplayModel == 0x0657) return CPU::XEON_PHI_KNIGHTS_LANDING; #elif defined(__ARM_NEON) return CPU::ARM; #endif return CPU::UNKNOWN; } std::string stringOfCPUModel(CPU model) { switch (model) { case CPU::XEON_ICE_LAKE : return "Xeon Ice Lake"; case CPU::CORE_ICE_LAKE : return "Core Ice Lake"; case CPU::CORE_TIGER_LAKE : return "Core Tiger Lake"; case CPU::CORE_COMET_LAKE : return "Core Comet Lake"; case CPU::CORE_CANNON_LAKE : return "Core Cannon Lake"; case CPU::CORE_KABY_LAKE : return "Core Kaby Lake"; case CPU::XEON_SKY_LAKE : return "Xeon Sky Lake"; case CPU::CORE_SKY_LAKE : return "Core Sky Lake"; case CPU::XEON_PHI_KNIGHTS_MILL : return "Xeon Phi Knights Mill"; case CPU::XEON_PHI_KNIGHTS_LANDING: return "Xeon Phi Knights Landing"; case CPU::XEON_BROADWELL : return "Xeon Broadwell"; case CPU::CORE_BROADWELL : return "Core Broadwell"; case CPU::XEON_HASWELL : return "Xeon Haswell"; case CPU::CORE_HASWELL : return "Core Haswell"; case CPU::XEON_IVY_BRIDGE : return "Xeon Ivy Bridge"; case CPU::CORE_IVY_BRIDGE : return "Core Ivy Bridge"; case CPU::SANDY_BRIDGE : return "Sandy Bridge"; case CPU::NEHALEM : return "Nehalem"; case CPU::CORE2 : return "Core2"; case CPU::CORE1 : return "Core"; case CPU::ARM : return "ARM"; case CPU::UNKNOWN : return "Unknown CPU"; } return "Unknown CPU (error)"; } #if defined(__X86_ASM__) /* constants to access destination registers of CPUID instruction */ static const int EAX = 0; static const int EBX = 1; static const int ECX = 2; static const int EDX = 3; /* cpuid[eax=1].ecx */ static const int CPU_FEATURE_BIT_SSE3 = 1 << 0; static const int CPU_FEATURE_BIT_SSSE3 = 1 << 9; static const int CPU_FEATURE_BIT_FMA3 = 1 << 12; static const int CPU_FEATURE_BIT_SSE4_1 = 1 << 19; static const int CPU_FEATURE_BIT_SSE4_2 = 1 << 20; //static const int CPU_FEATURE_BIT_MOVBE = 1 << 22; static const int CPU_FEATURE_BIT_POPCNT = 1 << 23; //static const int CPU_FEATURE_BIT_XSAVE = 1 << 26; static const int CPU_FEATURE_BIT_OXSAVE = 1 << 27; static const int CPU_FEATURE_BIT_AVX = 1 << 28; static const int CPU_FEATURE_BIT_F16C = 1 << 29; static const int CPU_FEATURE_BIT_RDRAND = 1 << 30; /* cpuid[eax=1].edx */ static const int CPU_FEATURE_BIT_SSE = 1 << 25; static const int CPU_FEATURE_BIT_SSE2 = 1 << 26; /* cpuid[eax=0x80000001].ecx */ static const int CPU_FEATURE_BIT_LZCNT = 1 << 5; /* cpuid[eax=7,ecx=0].ebx */ static const int CPU_FEATURE_BIT_BMI1 = 1 << 3; static const int CPU_FEATURE_BIT_AVX2 = 1 << 5; static const int CPU_FEATURE_BIT_BMI2 = 1 << 8; static const int CPU_FEATURE_BIT_AVX512F = 1 << 16; // AVX512F (foundation) static const int CPU_FEATURE_BIT_AVX512DQ = 1 << 17; // AVX512DQ (doubleword and quadword instructions) static const int CPU_FEATURE_BIT_AVX512PF = 1 << 26; // AVX512PF (prefetch gather/scatter instructions) static const int CPU_FEATURE_BIT_AVX512ER = 1 << 27; // AVX512ER (exponential and reciprocal instructions) static const int CPU_FEATURE_BIT_AVX512CD = 1 << 28; // AVX512CD (conflict detection instructions) static const int CPU_FEATURE_BIT_AVX512BW = 1 << 30; // AVX512BW (byte and word instructions) static const int CPU_FEATURE_BIT_AVX512VL = 1 << 31; // AVX512VL (vector length extensions) static const int CPU_FEATURE_BIT_AVX512IFMA = 1 << 21; // AVX512IFMA (integer fused multiple-add instructions) /* cpuid[eax=7,ecx=0].ecx */ static const int CPU_FEATURE_BIT_AVX512VBMI = 1 << 1; // AVX512VBMI (vector bit manipulation instructions) #endif #if defined(__X86_ASM__) __noinline int64_t get_xcr0() { #if defined (__WIN32__) && !defined (__MINGW32__) && defined(_XCR_XFEATURE_ENABLED_MASK) int64_t xcr0 = 0; // int64_t is workaround for compiler bug under VS2013, Win32 xcr0 = _xgetbv(0); return xcr0; #else int xcr0 = 0; __asm__ ("xgetbv" : "=a" (xcr0) : "c" (0) : "%edx" ); return xcr0; #endif } #endif int getCPUFeatures() { #if defined(__X86_ASM__) /* cache CPU features access */ static int cpu_features = 0; if (cpu_features) return cpu_features; /* get number of CPUID leaves */ int cpuid_leaf0[4]; __cpuid(cpuid_leaf0, 0x00000000); unsigned nIds = cpuid_leaf0[EAX]; /* get number of extended CPUID leaves */ int cpuid_leafe[4]; __cpuid(cpuid_leafe, 0x80000000); unsigned nExIds = cpuid_leafe[EAX]; /* get CPUID leaves for EAX = 1,7, and 0x80000001 */ int cpuid_leaf_1[4] = { 0,0,0,0 }; int cpuid_leaf_7[4] = { 0,0,0,0 }; int cpuid_leaf_e1[4] = { 0,0,0,0 }; if (nIds >= 1) __cpuid (cpuid_leaf_1,0x00000001); #if _WIN32 #if _MSC_VER && (_MSC_FULL_VER < 160040219) #else if (nIds >= 7) __cpuidex(cpuid_leaf_7,0x00000007,0); #endif #else if (nIds >= 7) __cpuid_count(cpuid_leaf_7,0x00000007,0); #endif if (nExIds >= 0x80000001) __cpuid(cpuid_leaf_e1,0x80000001); /* detect if OS saves XMM, YMM, and ZMM states */ bool xmm_enabled = true; bool ymm_enabled = false; bool zmm_enabled = false; if (cpuid_leaf_1[ECX] & CPU_FEATURE_BIT_OXSAVE) { int64_t xcr0 = get_xcr0(); xmm_enabled = ((xcr0 & 0x02) == 0x02); /* checks if xmm are enabled in XCR0 */ ymm_enabled = xmm_enabled && ((xcr0 & 0x04) == 0x04); /* checks if ymm state are enabled in XCR0 */ zmm_enabled = ymm_enabled && ((xcr0 & 0xE0) == 0xE0); /* checks if OPMASK state, upper 256-bit of ZMM0-ZMM15 and ZMM16-ZMM31 state are enabled in XCR0 */ } if (xmm_enabled) cpu_features |= CPU_FEATURE_XMM_ENABLED; if (ymm_enabled) cpu_features |= CPU_FEATURE_YMM_ENABLED; if (zmm_enabled) cpu_features |= CPU_FEATURE_ZMM_ENABLED; if (cpuid_leaf_1[EDX] & CPU_FEATURE_BIT_SSE ) cpu_features |= CPU_FEATURE_SSE; if (cpuid_leaf_1[EDX] & CPU_FEATURE_BIT_SSE2 ) cpu_features |= CPU_FEATURE_SSE2; if (cpuid_leaf_1[ECX] & CPU_FEATURE_BIT_SSE3 ) cpu_features |= CPU_FEATURE_SSE3; if (cpuid_leaf_1[ECX] & CPU_FEATURE_BIT_SSSE3 ) cpu_features |= CPU_FEATURE_SSSE3; if (cpuid_leaf_1[ECX] & CPU_FEATURE_BIT_SSE4_1) cpu_features |= CPU_FEATURE_SSE41; if (cpuid_leaf_1[ECX] & CPU_FEATURE_BIT_SSE4_2) cpu_features |= CPU_FEATURE_SSE42; if (cpuid_leaf_1[ECX] & CPU_FEATURE_BIT_POPCNT) cpu_features |= CPU_FEATURE_POPCNT; if (cpuid_leaf_1[ECX] & CPU_FEATURE_BIT_AVX ) cpu_features |= CPU_FEATURE_AVX; if (cpuid_leaf_1[ECX] & CPU_FEATURE_BIT_F16C ) cpu_features |= CPU_FEATURE_F16C; if (cpuid_leaf_1[ECX] & CPU_FEATURE_BIT_RDRAND) cpu_features |= CPU_FEATURE_RDRAND; if (cpuid_leaf_7[EBX] & CPU_FEATURE_BIT_AVX2 ) cpu_features |= CPU_FEATURE_AVX2; if (cpuid_leaf_1[ECX] & CPU_FEATURE_BIT_FMA3 ) cpu_features |= CPU_FEATURE_FMA3; if (cpuid_leaf_e1[ECX] & CPU_FEATURE_BIT_LZCNT) cpu_features |= CPU_FEATURE_LZCNT; if (cpuid_leaf_7 [EBX] & CPU_FEATURE_BIT_BMI1 ) cpu_features |= CPU_FEATURE_BMI1; if (cpuid_leaf_7 [EBX] & CPU_FEATURE_BIT_BMI2 ) cpu_features |= CPU_FEATURE_BMI2; if (cpuid_leaf_7[EBX] & CPU_FEATURE_BIT_AVX512F ) cpu_features |= CPU_FEATURE_AVX512F; if (cpuid_leaf_7[EBX] & CPU_FEATURE_BIT_AVX512DQ ) cpu_features |= CPU_FEATURE_AVX512DQ; if (cpuid_leaf_7[EBX] & CPU_FEATURE_BIT_AVX512PF ) cpu_features |= CPU_FEATURE_AVX512PF; if (cpuid_leaf_7[EBX] & CPU_FEATURE_BIT_AVX512ER ) cpu_features |= CPU_FEATURE_AVX512ER; if (cpuid_leaf_7[EBX] & CPU_FEATURE_BIT_AVX512CD ) cpu_features |= CPU_FEATURE_AVX512CD; if (cpuid_leaf_7[EBX] & CPU_FEATURE_BIT_AVX512BW ) cpu_features |= CPU_FEATURE_AVX512BW; if (cpuid_leaf_7[EBX] & CPU_FEATURE_BIT_AVX512IFMA) cpu_features |= CPU_FEATURE_AVX512IFMA; if (cpuid_leaf_7[EBX] & CPU_FEATURE_BIT_AVX512VL ) cpu_features |= CPU_FEATURE_AVX512VL; if (cpuid_leaf_7[ECX] & CPU_FEATURE_BIT_AVX512VBMI) cpu_features |= CPU_FEATURE_AVX512VBMI; return cpu_features; #elif defined(__ARM_NEON) || defined(__EMSCRIPTEN__) int cpu_features = CPU_FEATURE_NEON|CPU_FEATURE_SSE|CPU_FEATURE_SSE2; cpu_features |= CPU_FEATURE_SSE3|CPU_FEATURE_SSSE3|CPU_FEATURE_SSE42; cpu_features |= CPU_FEATURE_XMM_ENABLED; cpu_features |= CPU_FEATURE_YMM_ENABLED; cpu_features |= CPU_FEATURE_SSE41 | CPU_FEATURE_RDRAND | CPU_FEATURE_F16C; cpu_features |= CPU_FEATURE_POPCNT; cpu_features |= CPU_FEATURE_AVX; cpu_features |= CPU_FEATURE_AVX2; cpu_features |= CPU_FEATURE_FMA3; cpu_features |= CPU_FEATURE_LZCNT; cpu_features |= CPU_FEATURE_BMI1; cpu_features |= CPU_FEATURE_BMI2; cpu_features |= CPU_FEATURE_NEON_2X; return cpu_features; #else /* Unknown CPU. */ return 0; #endif } std::string stringOfCPUFeatures(int features) { std::string str; if (features & CPU_FEATURE_XMM_ENABLED) str += "XMM "; if (features & CPU_FEATURE_YMM_ENABLED) str += "YMM "; if (features & CPU_FEATURE_ZMM_ENABLED) str += "ZMM "; if (features & CPU_FEATURE_SSE ) str += "SSE "; if (features & CPU_FEATURE_SSE2 ) str += "SSE2 "; if (features & CPU_FEATURE_SSE3 ) str += "SSE3 "; if (features & CPU_FEATURE_SSSE3 ) str += "SSSE3 "; if (features & CPU_FEATURE_SSE41 ) str += "SSE4.1 "; if (features & CPU_FEATURE_SSE42 ) str += "SSE4.2 "; if (features & CPU_FEATURE_POPCNT) str += "POPCNT "; if (features & CPU_FEATURE_AVX ) str += "AVX "; if (features & CPU_FEATURE_F16C ) str += "F16C "; if (features & CPU_FEATURE_RDRAND) str += "RDRAND "; if (features & CPU_FEATURE_AVX2 ) str += "AVX2 "; if (features & CPU_FEATURE_FMA3 ) str += "FMA3 "; if (features & CPU_FEATURE_LZCNT ) str += "LZCNT "; if (features & CPU_FEATURE_BMI1 ) str += "BMI1 "; if (features & CPU_FEATURE_BMI2 ) str += "BMI2 "; if (features & CPU_FEATURE_AVX512F) str += "AVX512F "; if (features & CPU_FEATURE_AVX512DQ) str += "AVX512DQ "; if (features & CPU_FEATURE_AVX512PF) str += "AVX512PF "; if (features & CPU_FEATURE_AVX512ER) str += "AVX512ER "; if (features & CPU_FEATURE_AVX512CD) str += "AVX512CD "; if (features & CPU_FEATURE_AVX512BW) str += "AVX512BW "; if (features & CPU_FEATURE_AVX512VL) str += "AVX512VL "; if (features & CPU_FEATURE_AVX512IFMA) str += "AVX512IFMA "; if (features & CPU_FEATURE_AVX512VBMI) str += "AVX512VBMI "; if (features & CPU_FEATURE_NEON) str += "NEON "; if (features & CPU_FEATURE_NEON_2X) str += "2xNEON "; return str; } std::string stringOfISA (int isa) { if (isa == SSE) return "SSE"; if (isa == SSE2) return "SSE2"; if (isa == SSE3) return "SSE3"; if (isa == SSSE3) return "SSSE3"; if (isa == SSE41) return "SSE4.1"; if (isa == SSE42) return "SSE4.2"; if (isa == AVX) return "AVX"; if (isa == AVX2) return "AVX2"; if (isa == AVX512) return "AVX512"; if (isa == NEON) return "NEON"; if (isa == NEON_2X) return "2xNEON"; return "UNKNOWN"; } bool hasISA(int features, int isa) { return (features & isa) == isa; } std::string supportedTargetList (int features) { std::string v; if (hasISA(features,SSE)) v += "SSE "; if (hasISA(features,SSE2)) v += "SSE2 "; if (hasISA(features,SSE3)) v += "SSE3 "; if (hasISA(features,SSSE3)) v += "SSSE3 "; if (hasISA(features,SSE41)) v += "SSE4.1 "; if (hasISA(features,SSE42)) v += "SSE4.2 "; if (hasISA(features,AVX)) v += "AVX "; if (hasISA(features,AVXI)) v += "AVXI "; if (hasISA(features,AVX2)) v += "AVX2 "; if (hasISA(features,AVX512)) v += "AVX512 "; if (hasISA(features,NEON)) v += "NEON "; if (hasISA(features,NEON_2X)) v += "2xNEON "; return v; } } //////////////////////////////////////////////////////////////////////////////// /// Windows Platform //////////////////////////////////////////////////////////////////////////////// #if defined(__WIN32__) #define WIN32_LEAN_AND_MEAN #include #include namespace embree { std::string getExecutableFileName() { char filename[1024]; if (!GetModuleFileName(nullptr, filename, sizeof(filename))) return std::string(); return std::string(filename); } unsigned int getNumberOfLogicalThreads() { static int nThreads = -1; if (nThreads != -1) return nThreads; typedef WORD (WINAPI *GetActiveProcessorGroupCountFunc)(); typedef DWORD (WINAPI *GetActiveProcessorCountFunc)(WORD); HMODULE hlib = LoadLibrary("Kernel32"); GetActiveProcessorGroupCountFunc pGetActiveProcessorGroupCount = (GetActiveProcessorGroupCountFunc)GetProcAddress(hlib, "GetActiveProcessorGroupCount"); GetActiveProcessorCountFunc pGetActiveProcessorCount = (GetActiveProcessorCountFunc) GetProcAddress(hlib, "GetActiveProcessorCount"); if (pGetActiveProcessorGroupCount && pGetActiveProcessorCount) { int groups = pGetActiveProcessorGroupCount(); int totalProcessors = 0; for (int i = 0; i < groups; i++) totalProcessors += pGetActiveProcessorCount(i); nThreads = totalProcessors; } else { SYSTEM_INFO sysinfo; GetSystemInfo(&sysinfo); nThreads = sysinfo.dwNumberOfProcessors; } assert(nThreads); return nThreads; } int getTerminalWidth() { HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); if (handle == INVALID_HANDLE_VALUE) return 80; CONSOLE_SCREEN_BUFFER_INFO info; memset(&info,0,sizeof(info)); GetConsoleScreenBufferInfo(handle, &info); return info.dwSize.X; } double getSeconds() { LARGE_INTEGER freq, val; QueryPerformanceFrequency(&freq); QueryPerformanceCounter(&val); return (double)val.QuadPart / (double)freq.QuadPart; } void sleepSeconds(double t) { Sleep(DWORD(1000.0*t)); } size_t getVirtualMemoryBytes() { PROCESS_MEMORY_COUNTERS info; GetProcessMemoryInfo( GetCurrentProcess( ), &info, sizeof(info) ); return (size_t)info.QuotaPeakPagedPoolUsage; } size_t getResidentMemoryBytes() { PROCESS_MEMORY_COUNTERS info; GetProcessMemoryInfo( GetCurrentProcess( ), &info, sizeof(info) ); return (size_t)info.WorkingSetSize; } } #endif //////////////////////////////////////////////////////////////////////////////// /// Linux Platform //////////////////////////////////////////////////////////////////////////////// #if defined(__LINUX__) #include #include namespace embree { std::string getExecutableFileName() { std::string pid = "/proc/" + toString(getpid()) + "/exe"; char buf[4096]; memset(buf,0,sizeof(buf)); if (readlink(pid.c_str(), buf, sizeof(buf)-1) == -1) return std::string(); return std::string(buf); } size_t getVirtualMemoryBytes() { size_t virt, resident, shared; std::ifstream buffer("/proc/self/statm"); buffer >> virt >> resident >> shared; return virt*sysconf(_SC_PAGE_SIZE); } size_t getResidentMemoryBytes() { size_t virt, resident, shared; std::ifstream buffer("/proc/self/statm"); buffer >> virt >> resident >> shared; return resident*sysconf(_SC_PAGE_SIZE); } } #endif //////////////////////////////////////////////////////////////////////////////// /// FreeBSD Platform //////////////////////////////////////////////////////////////////////////////// #if defined (__FreeBSD__) #include namespace embree { std::string getExecutableFileName() { const int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 }; char buf[4096]; memset(buf,0,sizeof(buf)); size_t len = sizeof(buf)-1; if (sysctl(mib, 4, buf, &len, 0x0, 0) == -1) return std::string(); return std::string(buf); } size_t getVirtualMemoryBytes() { return 0; } size_t getResidentMemoryBytes() { return 0; } } #endif //////////////////////////////////////////////////////////////////////////////// /// Mac OS X Platform //////////////////////////////////////////////////////////////////////////////// #if defined(__MACOSX__) #include namespace embree { std::string getExecutableFileName() { char buf[4096]; uint32_t size = sizeof(buf); if (_NSGetExecutablePath(buf, &size) != 0) return std::string(); return std::string(buf); } size_t getVirtualMemoryBytes() { return 0; } size_t getResidentMemoryBytes() { return 0; } } #endif //////////////////////////////////////////////////////////////////////////////// /// Unix Platform //////////////////////////////////////////////////////////////////////////////// #if defined(__UNIX__) #include #include #include #include #if defined(__EMSCRIPTEN__) #include #endif namespace embree { unsigned int getNumberOfLogicalThreads() { static int nThreads = -1; if (nThreads != -1) return nThreads; #if defined(__MACOSX__) || defined(__ANDROID__) nThreads = sysconf(_SC_NPROCESSORS_ONLN); // does not work in Linux LXC container assert(nThreads); #elif defined(__EMSCRIPTEN__) // WebAssembly supports pthreads, but not pthread_getaffinity_np. Get the number of logical // threads from the browser or Node.js using JavaScript. nThreads = MAIN_THREAD_EM_ASM_INT({ const isBrowser = typeof window !== 'undefined'; const isNode = typeof process !== 'undefined' && process.versions != null && process.versions.node != null; if (isBrowser) { // Return 1 if the browser does not expose hardwareConcurrency. return window.navigator.hardwareConcurrency || 1; } else if (isNode) { return require('os').cpus().length; } else { return 1; } }); #else cpu_set_t set; if (pthread_getaffinity_np(pthread_self(), sizeof(set), &set) == 0) nThreads = CPU_COUNT(&set); #endif assert(nThreads); return nThreads; } int getTerminalWidth() { struct winsize info; if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &info) < 0) return 80; return info.ws_col; } double getSeconds() { struct timeval tp; gettimeofday(&tp,nullptr); return double(tp.tv_sec) + double(tp.tv_usec)/1E6; } void sleepSeconds(double t) { usleep(1000000.0*t); } } #endif #if defined(__INTEL_LLVM_COMPILER) #pragma clang diagnostic pop #endif level-zero-raytracing-support-1.0.0/rtbuild/sys/sysinfo.h000066400000000000000000000136031450534701400236030ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #define CACHELINE_SIZE 64 #if !defined(PAGE_SIZE) #define PAGE_SIZE 4096 #endif #define PAGE_SIZE_2M (2*1024*1024) #define PAGE_SIZE_4K (4*1024) #include "platform.h" #if !defined(__SSE__) #define __SSE__ #endif #if !defined(__SSE2__) #define __SSE2__ #endif /* define isa namespace and ISA bitvector */ #if defined (__AVX512VL__) # define isa avx512 # define ISA AVX512 # define ISA_STR "AVX512" #elif defined (__AVX2__) # define isa avx2 # define ISA AVX2 # define ISA_STR "AVX2" #elif defined(__AVXI__) # define isa avxi # define ISA AVXI # define ISA_STR "AVXI" #elif defined(__AVX__) # define isa avx # define ISA AVX # define ISA_STR "AVX" #elif defined (__SSE4_2__) # define isa sse42 # define ISA SSE42 # define ISA_STR "SSE4.2" //#elif defined (__SSE4_1__) // we demote this to SSE2, MacOSX code compiles with SSE41 by default with XCode 11 //# define isa sse41 //# define ISA SSE41 //# define ISA_STR "SSE4.1" //#elif defined(__SSSE3__) // we demote this to SSE2, MacOSX code compiles with SSSE3 by default with ICC //# define isa ssse3 //# define ISA SSSE3 //# define ISA_STR "SSSE3" //#elif defined(__SSE3__) // we demote this to SSE2, MacOSX code compiles with SSE3 by default with clang //# define isa sse3 //# define ISA SSE3 //# define ISA_STR "SSE3" #elif defined(__SSE2__) || defined(__SSE3__) || defined(__SSSE3__) # define isa sse2 # define ISA SSE2 # define ISA_STR "SSE2" #elif defined(__SSE__) # define isa sse # define ISA SSE # define ISA_STR "SSE" #elif defined(__ARM_NEON) // NOTE(LTE): Use sse2 for `isa` for the compatibility at the moment. #define isa sse2 #define ISA NEON #define ISA_STR "NEON" #else #error Unknown ISA #endif namespace embree { enum class CPU { XEON_ICE_LAKE, CORE_ICE_LAKE, CORE_TIGER_LAKE, CORE_COMET_LAKE, CORE_CANNON_LAKE, CORE_KABY_LAKE, XEON_SKY_LAKE, CORE_SKY_LAKE, XEON_PHI_KNIGHTS_MILL, XEON_PHI_KNIGHTS_LANDING, XEON_BROADWELL, CORE_BROADWELL, XEON_HASWELL, CORE_HASWELL, XEON_IVY_BRIDGE, CORE_IVY_BRIDGE, SANDY_BRIDGE, NEHALEM, CORE2, CORE1, ARM, UNKNOWN, }; /*! get the full path to the running executable */ std::string getExecutableFileName(); /*! return platform name */ std::string getPlatformName(); /*! get the full name of the compiler */ std::string getCompilerName(); /*! return the name of the CPU */ std::string getCPUVendor(); /*! get microprocessor model */ CPU getCPUModel(); /*! converts CPU model into string */ std::string stringOfCPUModel(CPU model); /*! CPU features */ static const int CPU_FEATURE_SSE = 1 << 0; static const int CPU_FEATURE_SSE2 = 1 << 1; static const int CPU_FEATURE_SSE3 = 1 << 2; static const int CPU_FEATURE_SSSE3 = 1 << 3; static const int CPU_FEATURE_SSE41 = 1 << 4; static const int CPU_FEATURE_SSE42 = 1 << 5; static const int CPU_FEATURE_POPCNT = 1 << 6; static const int CPU_FEATURE_AVX = 1 << 7; static const int CPU_FEATURE_F16C = 1 << 8; static const int CPU_FEATURE_RDRAND = 1 << 9; static const int CPU_FEATURE_AVX2 = 1 << 10; static const int CPU_FEATURE_FMA3 = 1 << 11; static const int CPU_FEATURE_LZCNT = 1 << 12; static const int CPU_FEATURE_BMI1 = 1 << 13; static const int CPU_FEATURE_BMI2 = 1 << 14; static const int CPU_FEATURE_AVX512F = 1 << 16; static const int CPU_FEATURE_AVX512DQ = 1 << 17; static const int CPU_FEATURE_AVX512PF = 1 << 18; static const int CPU_FEATURE_AVX512ER = 1 << 19; static const int CPU_FEATURE_AVX512CD = 1 << 20; static const int CPU_FEATURE_AVX512BW = 1 << 21; static const int CPU_FEATURE_AVX512VL = 1 << 22; static const int CPU_FEATURE_AVX512IFMA = 1 << 23; static const int CPU_FEATURE_AVX512VBMI = 1 << 24; static const int CPU_FEATURE_XMM_ENABLED = 1 << 25; static const int CPU_FEATURE_YMM_ENABLED = 1 << 26; static const int CPU_FEATURE_ZMM_ENABLED = 1 << 27; static const int CPU_FEATURE_NEON = 1 << 28; static const int CPU_FEATURE_NEON_2X = 1 << 29; /*! get CPU features */ int getCPUFeatures(); /*! convert CPU features into a string */ std::string stringOfCPUFeatures(int features); /*! creates a string of all supported targets that are supported */ std::string supportedTargetList (int isa); /*! ISAs */ static const int SSE = CPU_FEATURE_SSE | CPU_FEATURE_XMM_ENABLED; static const int SSE2 = SSE | CPU_FEATURE_SSE2; static const int SSE3 = SSE2 | CPU_FEATURE_SSE3; static const int SSSE3 = SSE3 | CPU_FEATURE_SSSE3; static const int SSE41 = SSSE3 | CPU_FEATURE_SSE41; static const int SSE42 = SSE41 | CPU_FEATURE_SSE42 | CPU_FEATURE_POPCNT; static const int AVX = SSE42 | CPU_FEATURE_AVX | CPU_FEATURE_YMM_ENABLED; static const int AVXI = AVX | CPU_FEATURE_F16C | CPU_FEATURE_RDRAND; static const int AVX2 = AVXI | CPU_FEATURE_AVX2 | CPU_FEATURE_FMA3 | CPU_FEATURE_BMI1 | CPU_FEATURE_BMI2 | CPU_FEATURE_LZCNT; static const int AVX512 = AVX2 | CPU_FEATURE_AVX512F | CPU_FEATURE_AVX512DQ | CPU_FEATURE_AVX512CD | CPU_FEATURE_AVX512BW | CPU_FEATURE_AVX512VL | CPU_FEATURE_ZMM_ENABLED; static const int NEON = CPU_FEATURE_NEON | CPU_FEATURE_SSE | CPU_FEATURE_SSE2; static const int NEON_2X = CPU_FEATURE_NEON_2X | AVX2; /*! converts ISA bitvector into a string */ std::string stringOfISA(int features); /*! return the number of logical threads of the system */ unsigned int getNumberOfLogicalThreads(); /*! returns the size of the terminal window in characters */ int getTerminalWidth(); /*! returns performance counter in seconds */ double getSeconds(); /*! sleeps the specified number of seconds */ void sleepSeconds(double t); /*! returns virtual address space occupied by process */ size_t getVirtualMemoryBytes(); /*! returns resident memory required by process */ size_t getResidentMemoryBytes(); } level-zero-raytracing-support-1.0.0/rtbuild/sys/vector.h000066400000000000000000000201031450534701400234040ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include "alloc.h" #include namespace embree { class Device; template class vector_t { public: typedef T value_type; typedef T* iterator; typedef const T* const_iterator; __forceinline vector_t () : size_active(0), size_alloced(0), items(nullptr) {} __forceinline explicit vector_t (size_t sz) : size_active(0), size_alloced(0), items(nullptr) { internal_resize_init(sz); } template __forceinline explicit vector_t (M alloc, size_t sz) : alloc(alloc), size_active(0), size_alloced(0), items(nullptr) { internal_resize_init(sz); } __forceinline vector_t (Device* alloc) : vector_t(alloc,0) {} __forceinline vector_t(void* data, size_t bytes) : size_active(0), size_alloced(bytes/sizeof(T)), items((T*)data) {} __forceinline ~vector_t() { clear(); } __forceinline vector_t (const vector_t& other) { size_active = other.size_active; size_alloced = other.size_alloced; items = alloc.allocate(size_alloced); for (size_t i=0; i 0); return items[0]; }; __forceinline T& back () const { assert(size_active > 0); return items[size_active-1]; }; __forceinline T* data() { return items; }; __forceinline const T* data() const { return items; }; /******************** Modifiers **************************/ __forceinline void push_back(const T& nt) { const T v = nt; // need local copy as input reference could point to this vector internal_resize(size_active,internal_grow_size(size_active+1)); ::new (&items[size_active++]) T(v); } __forceinline void pop_back() { assert(!empty()); size_active--; items[size_active].~T(); } __forceinline void clear() { /* destroy elements */ for (size_t i=0; i using vector = vector_t>; /*! vector class that performs aligned allocations */ template using avector = vector_t::value> >; /*! vector class that performs OS allocations */ template using ovector = vector_t >; /*! vector class with externally managed data buffer */ template using evector = vector_t>; } level-zero-raytracing-support-1.0.0/rttrace/000077500000000000000000000000001450534701400211165ustar00rootroot00000000000000level-zero-raytracing-support-1.0.0/rttrace/CMakeLists.txt000066400000000000000000000014011450534701400236520ustar00rootroot00000000000000## Copyright 2009-2021 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 GET_FILENAME_COMPONENT(SYCL_COMPILER_DIR ${CMAKE_CXX_COMPILER} PATH) SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -isystem \"${SYCL_COMPILER_DIR}/../include/sycl\" -isystem \"${SYCL_COMPILER_DIR}/../include/\"") # disable warning from SYCL header (FIXME: why required?) ADD_LIBRARY(embree_rthwif_sycl STATIC rttrace_validation.cpp) SET_PROPERTY(TARGET embree_rthwif_sycl APPEND PROPERTY COMPILE_FLAGS "-fsycl -fsycl-targets=spir64 -DEMBREE_SYCL_SUPPORT") INSTALL(TARGETS embree_rthwif_sycl EXPORT embree_rthwif_sycl-targets ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT lib) INSTALL(EXPORT embree_rthwif_sycl-targets DESTINATION "${EMBREE_CMAKEEXPORT_DIR}" COMPONENT devel) level-zero-raytracing-support-1.0.0/rttrace/rttrace.h000066400000000000000000000273321450534701400227420ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #if defined(ZE_RAYTRACING_RT_SIMULATION) #include "rtcore.h" #endif #if defined(EMBREE_SYCL_RT_VALIDATION_API) # include "rttrace_validation.h" #else #include #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" #pragma clang diagnostic ignored "-W#pragma-messages" #include #pragma clang diagnostic pop #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wreturn-type-c-linkage" enum intel_ray_flags_t { intel_ray_flags_none = 0x00, intel_ray_flags_force_opaque = 0x01, // forces geometry to be opaque (no anyhit shader invokation) intel_ray_flags_force_non_opaque = 0x02, // forces geometry to be non-opqaue (invoke anyhit shader) intel_ray_flags_accept_first_hit_and_end_search = 0x04, // terminates traversal on the first hit found (shadow rays) intel_ray_flags_skip_closest_hit_shader = 0x08, // skip execution of the closest hit shader intel_ray_flags_cull_back_facing_triangles = 0x10, // back facing triangles to not produce a hit intel_ray_flags_cull_front_facing_triangles = 0x20, // front facing triangles do not produce a hit intel_ray_flags_cull_opaque = 0x40, // opaque geometry does not produce a hit intel_ray_flags_cull_non_opaque = 0x80, // non-opaque geometry does not produce a hit intel_ray_flags_skip_triangles = 0x100, // treat all triangle intersections as misses. intel_ray_flags_skip_procedural_primitives = 0x200, // skip execution of intersection shaders }; enum intel_hit_type_t { intel_hit_type_committed_hit = 0, intel_hit_type_potential_hit = 1, }; enum intel_raytracing_ext_flag_t { intel_raytracing_ext_flag_ray_query = 1 << 0, // true if ray queries are supported }; // opaque types typedef __attribute__((opencl_private)) struct intel_ray_query_opaque_t* intel_ray_query_t; typedef __attribute__((opencl_global )) struct intel_raytracing_acceleration_structure_opaque_t* intel_raytracing_acceleration_structure_t; struct intel_float2 { float x, y; intel_float2() {} intel_float2(float x, float y) : x(x), y(y) {} intel_float2(sycl::float2 v) : x(v.x()), y(v.y()) {} operator sycl::float2() { return sycl::float2(x,y); } }; struct intel_float3 { float x, y, z; intel_float3() {} intel_float3(float x, float y, float z) : x(x), y(y), z(z) {} intel_float3(sycl::float3 v) : x(v.x()), y(v.y()), z(v.z()) {} operator sycl::float3() { return sycl::float3(x,y,z); } }; struct intel_float4x3 { intel_float3 vx, vy, vz, p; }; struct intel_ray_desc_t { intel_float3 origin; intel_float3 direction; float tmin; float tmax; unsigned int mask; intel_ray_flags_t flags; }; // if traversal returns one can test if a triangle or procedural is hit enum intel_candidate_type_t { intel_candidate_type_triangle, intel_candidate_type_procedural }; #ifdef __SYCL_DEVICE_ONLY__ // check supported ray tracing features SYCL_EXTERNAL extern "C" intel_raytracing_ext_flag_t intel_get_raytracing_ext_flag(); // initializes a ray query SYCL_EXTERNAL extern "C" intel_ray_query_t intel_ray_query_init( intel_ray_desc_t ray, intel_raytracing_acceleration_structure_t accel ); // setup for instance traversal using a transformed ray and bottom-level AS SYCL_EXTERNAL extern "C" void intel_ray_query_forward_ray( intel_ray_query_t query, intel_ray_desc_t ray, intel_raytracing_acceleration_structure_t accel ); // commit the potential hit SYCL_EXTERNAL extern "C" void intel_ray_query_commit_potential_hit( intel_ray_query_t query ); // commit the potential hit and override hit distance and UVs SYCL_EXTERNAL extern "C" void intel_ray_query_commit_potential_hit_override( intel_ray_query_t query, float override_hit_distance, intel_float2 override_uv ); // start traversal of a ray query SYCL_EXTERNAL extern "C" void intel_ray_query_start_traversal( intel_ray_query_t query ); // synchronize rayquery execution. If a ray was dispatched, // This must be called prior to calling any of the accessors below. SYCL_EXTERNAL extern "C" void intel_ray_query_sync( intel_ray_query_t query ); // signal that a ray query will not be used further. This is the moral equaivalent of a delete // this function does an implicit sync SYCL_EXTERNAL extern "C" void intel_ray_query_abandon( intel_ray_query_t query ); // read hit information during shader execution SYCL_EXTERNAL extern "C" unsigned int intel_get_hit_bvh_level( intel_ray_query_t query, intel_hit_type_t hit_type ); SYCL_EXTERNAL extern "C" float intel_get_hit_distance( intel_ray_query_t query, intel_hit_type_t hit_type ); SYCL_EXTERNAL extern "C" intel_float2 intel_get_hit_barycentrics( intel_ray_query_t query, intel_hit_type_t hit_type ); SYCL_EXTERNAL extern "C" bool intel_get_hit_front_face( intel_ray_query_t query, intel_hit_type_t hit_type ); SYCL_EXTERNAL extern "C" unsigned int intel_get_hit_geometry_id(intel_ray_query_t query, intel_hit_type_t hit_type ); SYCL_EXTERNAL extern "C" unsigned int intel_get_hit_primitive_id( intel_ray_query_t query, intel_hit_type_t hit_type ); SYCL_EXTERNAL extern "C" unsigned int intel_get_hit_triangle_primitive_id( intel_ray_query_t query, intel_hit_type_t hit_type ); // fast path for quad leaves SYCL_EXTERNAL extern "C" unsigned int intel_get_hit_procedural_primitive_id( intel_ray_query_t query, intel_hit_type_t hit_type ); // fast path for procedural leaves SYCL_EXTERNAL extern "C" unsigned int intel_get_hit_instance_id( intel_ray_query_t query, intel_hit_type_t hit_type ); SYCL_EXTERNAL extern "C" unsigned int intel_get_hit_instance_user_id( intel_ray_query_t query, intel_hit_type_t hit_type ); SYCL_EXTERNAL extern "C" intel_float4x3 intel_get_hit_world_to_object( intel_ray_query_t query, intel_hit_type_t hit_type ); SYCL_EXTERNAL extern "C" intel_float4x3 intel_get_hit_object_to_world( intel_ray_query_t query, intel_hit_type_t hit_type ); // fetch triangle vertices for a hit SYCL_EXTERNAL extern "C" void intel_get_hit_triangle_vertices( intel_ray_query_t query, intel_float3 vertices_out[3], intel_hit_type_t hit_type ); // Read ray-data. This is used to read transformed rays produced by HW instancing pipeline // during any-hit or intersection shader execution. SYCL_EXTERNAL extern "C" intel_float3 intel_get_ray_origin( intel_ray_query_t query, unsigned int bvh_level ); SYCL_EXTERNAL extern "C" intel_float3 intel_get_ray_direction( intel_ray_query_t query, unsigned int bvh_level ); SYCL_EXTERNAL extern "C" float intel_get_ray_tmin( intel_ray_query_t query, unsigned int bvh_level ); SYCL_EXTERNAL extern "C" intel_ray_flags_t intel_get_ray_flags( intel_ray_query_t query, unsigned int bvh_level ); SYCL_EXTERNAL extern "C" unsigned int intel_get_ray_mask( intel_ray_query_t query, unsigned int bvh_level ); SYCL_EXTERNAL extern "C" intel_candidate_type_t intel_get_hit_candidate( intel_ray_query_t query, intel_hit_type_t hit_type ); // test whether traversal has terminated. If false, the ray has reached // a procedural leaf or a non-opaque triangle leaf, and requires shader processing SYCL_EXTERNAL extern "C" bool intel_is_traversal_done( intel_ray_query_t query ); // if traversal is done one can test for the presence of a committed hit to either invoke miss or closest hit shader SYCL_EXTERNAL extern "C" bool intel_has_committed_hit( intel_ray_query_t query ); #else inline intel_raytracing_ext_flag_t intel_get_raytracing_ext_flag() { return intel_raytracing_ext_flag_ray_query; } inline intel_ray_query_t intel_ray_query_init( intel_ray_desc_t ray, intel_raytracing_acceleration_structure_t accel ) { return NULL; } // setup for instance traversal using a transformed ray and bottom-level AS inline void intel_ray_query_forward_ray( intel_ray_query_t query, intel_ray_desc_t ray, intel_raytracing_acceleration_structure_t accel ) {} // commit the potential hit inline void intel_ray_query_commit_potential_hit( intel_ray_query_t query ) {} // commit the potential hit and override hit distance and UVs inline void intel_ray_query_commit_potential_hit_override( intel_ray_query_t query, float override_hit_distance, intel_float2 override_uv ) {} // start traversal of a ray query inline void intel_ray_query_start_traversal( intel_ray_query_t query ) {} // synchronize rayquery execution. If a ray was dispatched, // This must be called prior to calling any of the accessors below. inline void intel_ray_query_sync( intel_ray_query_t query ) {} // signal that a ray query will not be used further. This is the moral equaivalent of a delete // this function does an implicit sync inline void intel_ray_query_abandon( intel_ray_query_t query ) {} // read hit information during shader execution inline unsigned int intel_get_hit_bvh_level( intel_ray_query_t query, intel_hit_type_t hit_type ) { return 0; } inline float intel_get_hit_distance( intel_ray_query_t query, intel_hit_type_t hit_type ) { return 0.0f; } inline intel_float2 intel_get_hit_barycentrics( intel_ray_query_t query, intel_hit_type_t hit_type ) { return { 0,0 }; } inline bool intel_get_hit_front_face( intel_ray_query_t query, intel_hit_type_t hit_type ) { return false; } inline unsigned int intel_get_hit_geometry_id(intel_ray_query_t query, intel_hit_type_t hit_type ) { return 0; } inline unsigned int intel_get_hit_primitive_id( intel_ray_query_t query, intel_hit_type_t hit_type ) { return 0; } inline unsigned int intel_get_hit_triangle_primitive_id( intel_ray_query_t query, intel_hit_type_t hit_type ) { return 0; } // fast path for quad leaves inline unsigned int intel_get_hit_procedural_primitive_id( intel_ray_query_t query, intel_hit_type_t hit_type ) { return 0; } // fast path for procedural leaves inline unsigned int intel_get_hit_instance_id( intel_ray_query_t query, intel_hit_type_t hit_type ) { return 0; } inline unsigned int intel_get_hit_instance_user_id( intel_ray_query_t query, intel_hit_type_t hit_type ) { return 0; } inline intel_float4x3 intel_get_hit_world_to_object( intel_ray_query_t query, intel_hit_type_t hit_type ) { return { {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0} }; } inline intel_float4x3 intel_get_hit_object_to_world( intel_ray_query_t query, intel_hit_type_t hit_type ) { return { {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0} }; } // fetch triangle vertices for a hit inline void intel_get_hit_triangle_vertices( intel_ray_query_t query, intel_float3 vertices_out[3], intel_hit_type_t hit_type ) {} // Read ray-data. This is used to read transformed rays produced by HW instancing pipeline // during any-hit or intersection shader execution. inline intel_float3 intel_get_ray_origin( intel_ray_query_t query, unsigned int bvh_level ) { return { 0,0,0 }; } inline intel_float3 intel_get_ray_direction( intel_ray_query_t query, unsigned int bvh_level ) { return { 0,0,0 }; } inline float intel_get_ray_tmin( intel_ray_query_t query, unsigned int bvh_level ) { return 0.0f; } inline intel_ray_flags_t intel_get_ray_flags( intel_ray_query_t query, unsigned int bvh_level ) { return intel_ray_flags_none; } inline unsigned int intel_get_ray_mask( intel_ray_query_t query, unsigned int bvh_level ) { return 0; } inline intel_candidate_type_t intel_get_hit_candidate( intel_ray_query_t query, intel_hit_type_t hit_type ) { return intel_candidate_type_triangle; } // test whether traversal has terminated. If false, the ray has reached // a procedural leaf or a non-opaque triangle leaf, and requires shader processing inline bool intel_is_traversal_done( intel_ray_query_t query ) { return false; } // if traversal is done one can test for the presence of a committed hit to either invoke miss or closest hit shader inline bool intel_has_committed_hit( intel_ray_query_t query ) { return false; } #endif #pragma clang diagnostic pop #endif level-zero-raytracing-support-1.0.0/rttrace/rttrace_internal.h000066400000000000000000000242431450534701400246340ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once # define MemRay MemRayV1 # define MemHit MemHitV1 # define QuadLeaf QuadLeafV1 # define InstanceLeaf InstanceLeafV1 #include enum TraceRayCtrl { TRACE_RAY_INITIAL = 0, // Initializes hit and initializes traversal state TRACE_RAY_INSTANCE = 1, // Loads committed hit and initializes traversal state TRACE_RAY_COMMIT = 2, // Loads potential hit and loads traversal state TRACE_RAY_CONTINUE = 3, // Loads committed hit and loads traversal state TRACE_RAY_DONE = 256, // for internal use only }; typedef __attribute__((opencl_global)) struct rtglobals_opaque_t* rtglobals_t; typedef __attribute__((opencl_private)) struct rtfence_opaque_t* rtfence_t; #if defined(__SYCL_DEVICE_ONLY__) || defined(EMBREE_SYCL_RT_SIMULATION) SYCL_EXTERNAL extern "C" __attribute__((opencl_global)) void* intel_get_implicit_dispatch_globals(); SYCL_EXTERNAL extern "C" void* intel_get_rt_stack(rtglobals_t rt_dispatch_globals); SYCL_EXTERNAL extern "C" void* intel_get_thread_btd_stack(rtglobals_t rt_dispatch_globals); SYCL_EXTERNAL extern "C" void* intel_get_global_btd_stack(rtglobals_t rt_dispatch_globals); SYCL_EXTERNAL extern "C" rtfence_t intel_dispatch_trace_ray_query(rtglobals_t rt_dispatch_globals, unsigned int bvh_level, unsigned int traceRayCtrl); SYCL_EXTERNAL extern "C" void intel_rt_sync(rtfence_t fence); #else inline void* intel_get_implicit_dispatch_globals() { return nullptr; } inline void* intel_get_rt_stack(rtglobals_t rt_dispatch_globals) { return nullptr; } inline void* intel_get_thread_btd_stack(rtglobals_t rt_dispatch_globals) { return nullptr; } inline void* intel_get_global_btd_stack(rtglobals_t rt_dispatch_globals) { return nullptr; } inline rtfence_t intel_dispatch_trace_ray_query(rtglobals_t rt_dispatch_globals, unsigned int bvh_level, unsigned int traceRayCtrl) { return nullptr; } inline void intel_rt_sync(rtfence_t fence) {} #endif enum NodeType { NODE_TYPE_MIXED = 0x0, // identifies a mixed internal node where each child can have a different type NODE_TYPE_INTERNAL = 0x0, // internal BVH node with 6 children NODE_TYPE_INSTANCE = 0x1, // instance leaf NODE_TYPE_PROCEDURAL = 0x3, // procedural leaf NODE_TYPE_QUAD = 0x4, // quad leaf NODE_TYPE_INVALID = 0x7 // indicates invalid node }; struct __attribute__ ((packed,aligned(32))) MemRayV1 { void init(intel_ray_desc_t ray, uint64_t rootNodePtr_i) { org[0] = ray.origin.x; org[1] = ray.origin.y; org[2] = ray.origin.z; dir[0] = ray.direction.x; dir[1] = ray.direction.y; dir[2] = ray.direction.z; tnear = ray.tmin; tfar = ray.tmax; rootNodePtr = rootNodePtr_i; rayFlags = ray.flags; hitGroupSRBasePtr = 0; hitGroupSRStride = 0; missSRPtr = 0; pad0 = 0; shaderIndexMultiplier = 0; instLeafPtr = 0; rayMask = ray.mask; pad1 = 0; } // 32 B float org[3]; float dir[3]; float tnear; float tfar; // 32 B struct { // FIXME: removing these anonymous structs triggers IGC bug uint64_t rootNodePtr : 48; // root node to start traversal at uint64_t rayFlags : 16; // ray flags (see RayFlag structure) }; struct { uint64_t hitGroupSRBasePtr : 48; // base of hit group shader record array (16-bytes alignment) uint64_t hitGroupSRStride : 16; // stride of hit group shader record array (16-bytes alignment) }; struct { uint64_t missSRPtr : 48; // pointer to miss shader record to invoke on a miss (8-bytes alignment) uint64_t pad0 : 8; // padding byte (has to be zero) uint64_t shaderIndexMultiplier : 8; // shader index multiplier }; struct { uint64_t instLeafPtr : 48; // the pointer to instance leaf in case we traverse an instance (64-bytes alignment) uint64_t rayMask : 8; // ray mask used for ray masking uint64_t pad1 : 8; // padding byte (has to be zero) }; }; struct __attribute__ ((packed,aligned(32))) MemHitV1 { inline float getT() const { return ft; } inline void setT(float t) { ft = t; } inline float getU() const { return fu; } inline void setU(float u) { fu = u; } inline float getV() const { return fv; } inline void setV(float v) { fv = v; } inline void* getPrimLeafPtr() { return sycl::global_ptr((void*)(uint64_t(primLeafPtr)*64)).get(); } inline void* getInstanceLeafPtr() { return sycl::global_ptr((void*)(uint64_t(instLeafPtr)*64)).get(); } public: float ft; // hit distance of current hit (or initial traversal distance) float fu,fv; // barycentric hit coordinates union { struct { uint32_t primIndexDelta : 16; // prim index delta for compressed meshlets and quads uint32_t valid : 1; // set if there is a hit uint32_t leafType : 3; // type of node primLeafPtr is pointing to uint32_t primLeafIndex : 4; // index of the hit primitive inside the leaf uint32_t bvhLevel : 3; // the instancing level at which the hit occured uint32_t frontFace : 1; // whether we hit the front-facing side of a triangle (also used to pass opaque flag when calling intersection shaders) uint32_t done : 1; // used in sync mode to indicate that traversal is done uint32_t pad0 : 3; // unused bits }; uint32_t data; }; struct { // FIXME: removing these anonymous structs triggers IGC bug uint64_t primLeafPtr : 42; // pointer to BVH leaf node (multiple of 64 bytes) uint64_t hitGroupRecPtr0 : 22; // LSB of hit group record of the hit triangle (multiple of 16 bytes) }; struct { uint64_t instLeafPtr : 42; // pointer to BVH instance leaf node (in multiple of 64 bytes) uint64_t hitGroupRecPtr1 : 22; // MSB of hit group record of the hit triangle (multiple of 16 bytes) }; void clear(bool _done, bool _valid) { //*(sycl::int8*) this = sycl::int8(0x7F800000 /* INFINITY */, 0, 0, (_done ? 0x10000000 : 0) | (_valid ? 0x10000), 0, 0, 0, 0); ft = fu = fv = 0.0f; data = 0; done = _done ? 1 : 0; valid = _valid ? 1 : 0; } }; struct __attribute__ ((packed,aligned(64))) RTStack { union { struct { struct MemHit committedHit; // stores committed hit struct MemHit potentialHit; // stores potential hit that is passed to any hit shader }; struct MemHit hit[2]; // committedHit, potentialHit }; struct MemRay ray[2]; char travStack[32*2]; }; struct __attribute__ ((packed)) HWAccel { uint64_t reserved; float bounds[2][3]; // bounding box of the BVH uint32_t reserved0[8]; uint32_t numTimeSegments; uint32_t reserved1[13]; uint64_t dispatchGlobalsPtr; }; struct __attribute__ ((packed,aligned(8))) PrimLeafDesc { struct { uint32_t shaderIndex : 24; // shader index used for shader record calculations uint32_t geomMask : 8; // geometry mask used for ray masking }; struct { uint32_t geomIndex : 29; // the geometry index specifies the n'th geometry of the scene uint32_t type : 1; // enable/disable culling for procedurals and instances uint32_t geomFlags : 2; // geometry flags of this geometry }; }; struct __attribute__ ((packed,aligned(64))) QuadLeafV1 { struct PrimLeafDesc leafDesc; unsigned int primIndex0; struct { uint32_t primIndex1Delta : 16; // delta encoded primitive index of second triangle uint32_t j0 : 2; // specifies first vertex of second triangle uint32_t j1 : 2; // specified second vertex of second triangle uint32_t j2 : 2; // specified third vertex of second triangle uint32_t last : 1; // true if the second triangle is the last triangle in a leaf list uint32_t pad : 9; // unused bits }; float v[4][3]; }; struct __attribute__ ((packed,aligned(64))) ProceduralLeaf { static const constexpr uint32_t N = 13; struct PrimLeafDesc leafDesc; // leaf header identifying the geometry struct { uint32_t numPrimitives : 4; // number of stored primitives uint32_t pad : 32-4-N; uint32_t last : N; // bit vector with a last bit per primitive }; uint32_t _primIndex[N]; // primitive indices of all primitives stored inside the leaf }; struct __attribute__ ((packed,aligned(64))) InstanceLeafV1 { /* first 64 bytes accessed during traversal by hardware */ struct Part0 { public: struct { uint32_t shaderIndex : 24; // shader index used to calculate instancing shader in case of software instancing uint32_t geomMask : 8; // geometry mask used for ray masking }; struct { uint32_t instanceContributionToHitGroupIndex : 24; uint32_t pad0 : 5; /* the following two entries are only used for procedural instances */ uint32_t type : 1; // enables/disables opaque culling uint32_t geomFlags : 2; // unused for instances }; struct { uint64_t startNodePtr : 48; // start node where to continue traversal of the instanced object uint64_t instFlags : 8; // flags for the instance (see InstanceFlags) uint64_t pad1 : 8; // unused bits }; float world2obj_vx[3]; // 1st column of Worl2Obj transform float world2obj_vy[3]; // 2nd column of Worl2Obj transform float world2obj_vz[3]; // 3rd column of Worl2Obj transform float obj2world_p[3]; // translation of Obj2World transform (on purpose in first 64 bytes) } part0; /* second 64 bytes accessed during shading */ struct Part1 { struct { uint64_t bvhPtr : 48; // pointer to BVH where start node belongs too uint64_t pad : 16; // unused bits }; uint32_t instanceID; // user defined value per DXR spec uint32_t instanceIndex; // geometry index of the instance (n'th geometry in scene) float obj2world_vx[3]; // 1st column of Obj2World transform float obj2world_vy[3]; // 2nd column of Obj2World transform float obj2world_vz[3]; // 3rd column of Obj2World transform float world2obj_p[3]; // translation of World2Obj transform } part1; }; level-zero-raytracing-support-1.0.0/rttrace/rttrace_validation.cpp000066400000000000000000000260551450534701400255100ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "rttrace_validation.h" #define sizeof_QBVH6_InternalNode6 64 #define QBVH6_rootNodeOffset 128 /*struct rayquery_impl_t { rtfence_t fence; rtglobals_t dispatchGlobalsPtr; struct RTStack* rtStack; TraceRayCtrl ctrl; unsigned int bvh_level; };*/ void use_rthwif_production() { } SYCL_EXTERNAL intel_raytracing_ext_flag_t intel_get_raytracing_ext_flag() { return intel_raytracing_ext_flag_ray_query; } SYCL_EXTERNAL intel_ray_query_t intel_ray_query_init(intel_ray_desc_t ray, intel_raytracing_acceleration_structure_t accel_i ) { unsigned int bvh_level = 0; //intel_raytracing_acceleration_structure_t* accel_i = sycl::global_ptr(_accel_i).get(); HWAccel* accel = (HWAccel*)accel_i; #if defined(EMBREE_SYCL_ALLOC_DISPATCH_GLOBALS) rtglobals_t dispatchGlobalsPtr = (rtglobals_t) accel->dispatchGlobalsPtr; #else rtglobals_t dispatchGlobalsPtr = (rtglobals_t) intel_get_implicit_dispatch_globals(); #endif struct RTStack* __restrict rtStack = sycl::global_ptr((struct RTStack*)intel_get_rt_stack( (rtglobals_t)dispatchGlobalsPtr )).get(); /* init ray */ rtStack->ray[bvh_level].init(ray,(uint64_t)accel + QBVH6_rootNodeOffset); rtStack->committedHit.setT(INFINITY); rtStack->committedHit.setU(0.0f); rtStack->committedHit.setV(0.0f); rtStack->committedHit.data = 0; rtStack->potentialHit.setT(INFINITY); rtStack->potentialHit.setU(0.0f); rtStack->potentialHit.setV(0.0f); rtStack->potentialHit.data = 0; rtStack->potentialHit.done = 1; rtStack->potentialHit.valid = 1; return { nullptr, (void*) dispatchGlobalsPtr, rtStack, TRACE_RAY_INITIAL, bvh_level }; } SYCL_EXTERNAL void intel_ray_query_forward_ray( intel_ray_query_t& query, intel_ray_desc_t ray, intel_raytracing_acceleration_structure_t accel_i) { HWAccel* accel = (HWAccel*)accel_i; struct RTStack* __restrict rtStack = sycl::global_ptr((struct RTStack*)query.opaque2).get(); /* init ray */ unsigned int bvh_level = query.bvh_level+1; rtStack->ray[bvh_level].init(ray,(uint64_t)accel + QBVH6_rootNodeOffset); query = { nullptr, query.opaque1, query.opaque2, TRACE_RAY_INSTANCE, bvh_level }; } SYCL_EXTERNAL void intel_ray_query_commit_potential_hit( intel_ray_query_t& query ) { struct RTStack* __restrict rtStack = sycl::global_ptr((struct RTStack*)query.opaque2).get(); unsigned int bvh_level = query.bvh_level; unsigned int rflags = rtStack->ray[bvh_level].rayFlags; if (rflags & intel_ray_flags_accept_first_hit_and_end_search) { rtStack->committedHit = rtStack->potentialHit; rtStack->committedHit.valid = 1; query = { nullptr, query.opaque1, query.opaque2, TRACE_RAY_DONE, bvh_level }; } else { rtStack->potentialHit.valid = 1; // FIXME: is this required? query = { nullptr, query.opaque1, query.opaque2, TRACE_RAY_COMMIT, bvh_level }; } } SYCL_EXTERNAL void intel_ray_query_commit_potential_hit_override( intel_ray_query_t& query, float override_hit_distance, intel_float2 override_uv ) { //struct RTStack* rtStack = (struct RTStack*) query.opaque2; struct RTStack* __restrict rtStack = sycl::global_ptr((struct RTStack*)query.opaque2).get(); rtStack->potentialHit.setT(override_hit_distance); rtStack->potentialHit.setU(override_uv.x); rtStack->potentialHit.setV(override_uv.y); intel_ray_query_commit_potential_hit(query); } SYCL_EXTERNAL void intel_ray_query_start_traversal( intel_ray_query_t& query ) { rtglobals_t dispatchGlobalsPtr = (rtglobals_t) query.opaque1; struct RTStack* __restrict rtStack = sycl::global_ptr((struct RTStack*)query.opaque2).get(); rtStack->potentialHit.done = 1; rtStack->potentialHit.valid = 1; if (query.ctrl == TRACE_RAY_DONE) return; rtfence_t fence = intel_dispatch_trace_ray_query(dispatchGlobalsPtr,query.bvh_level,query.ctrl); query = { (void*) fence, query.opaque1, query.opaque2, TRACE_RAY_INITIAL, 0 }; } SYCL_EXTERNAL void intel_ray_query_sync( intel_ray_query_t& query ) { intel_rt_sync((rtfence_t)query.opaque0); /* continue is default behaviour */ struct RTStack* __restrict rtStack = sycl::global_ptr((struct RTStack*)query.opaque2).get(); unsigned int bvh_level = rtStack->potentialHit.bvhLevel; query = { query.opaque0, query.opaque1, query.opaque2, TRACE_RAY_CONTINUE, bvh_level }; } SYCL_EXTERNAL void intel_sync_ray_query( intel_ray_query_t& query ) { intel_rt_sync((rtfence_t)query.opaque0); /* continue is default behaviour */ struct RTStack* __restrict rtStack = sycl::global_ptr((struct RTStack*)query.opaque2).get(); unsigned int bvh_level = rtStack->potentialHit.bvhLevel; query = { query.opaque0, query.opaque1, query.opaque2, TRACE_RAY_CONTINUE, bvh_level }; } SYCL_EXTERNAL void intel_ray_query_abandon( intel_ray_query_t& query ) { intel_ray_query_sync(query); query = { nullptr, nullptr, nullptr, TRACE_RAY_INITIAL, 0 }; } SYCL_EXTERNAL unsigned int intel_get_hit_bvh_level( intel_ray_query_t& query, intel_hit_type_t hit_type ) { return query.hit(hit_type).bvhLevel; } SYCL_EXTERNAL float intel_get_hit_distance( intel_ray_query_t& query, intel_hit_type_t hit_type ) { return query.hit(hit_type).getT(); } SYCL_EXTERNAL intel_float2 intel_get_hit_barycentrics( intel_ray_query_t& query, intel_hit_type_t hit_type ) { return { query.hit(hit_type).getU(), query.hit(hit_type).getV() }; } SYCL_EXTERNAL bool intel_get_hit_front_face( intel_ray_query_t& query, intel_hit_type_t hit_type ) { return query.hit(hit_type).frontFace; } SYCL_EXTERNAL unsigned int intel_get_hit_geometry_id(intel_ray_query_t& query, intel_hit_type_t hit_type ) { struct PrimLeafDesc* __restrict leaf = (struct PrimLeafDesc*)query.hit(hit_type).getPrimLeafPtr(); return leaf->geomIndex; } SYCL_EXTERNAL unsigned int intel_get_hit_primitive_id( intel_ray_query_t& query, intel_hit_type_t hit_type ) { MemHit& hit = query.hit(hit_type); void* __restrict leaf = hit.getPrimLeafPtr(); if (hit.leafType == NODE_TYPE_QUAD) return ((QuadLeaf*)leaf)->primIndex0 + hit.primIndexDelta; else return ((ProceduralLeaf*)leaf)->_primIndex[hit.primLeafIndex]; } SYCL_EXTERNAL unsigned int intel_get_hit_triangle_primitive_id( intel_ray_query_t& query, intel_hit_type_t hit_type ) { MemHit& hit = query.hit(hit_type); QuadLeaf* __restrict leaf = (QuadLeaf*) hit.getPrimLeafPtr(); return leaf->primIndex0 + hit.primIndexDelta; } SYCL_EXTERNAL unsigned int intel_get_hit_procedural_primitive_id( intel_ray_query_t& query, intel_hit_type_t hit_type ) { MemHit& hit = query.hit(hit_type); ProceduralLeaf* __restrict leaf = (ProceduralLeaf*) hit.getPrimLeafPtr(); return leaf->_primIndex[hit.primLeafIndex]; } SYCL_EXTERNAL unsigned int intel_get_hit_instance_id( intel_ray_query_t& query, intel_hit_type_t hit_type ) { MemHit& hit = query.hit(hit_type); InstanceLeaf* __restrict leaf = (InstanceLeaf*) hit.getInstanceLeafPtr(); if (leaf == nullptr) return -1; return leaf->part1.instanceIndex; } SYCL_EXTERNAL unsigned int intel_get_hit_instance_user_id( intel_ray_query_t& query, intel_hit_type_t hit_type ) { MemHit& hit = query.hit(hit_type); InstanceLeaf* __restrict leaf = (InstanceLeaf*) hit.getInstanceLeafPtr(); if (leaf == nullptr) return -1; return leaf->part1.instanceID; } SYCL_EXTERNAL intel_float4x3 intel_get_hit_world_to_object( intel_ray_query_t& query, intel_hit_type_t hit_type ) { MemHit& hit = query.hit(hit_type); InstanceLeaf* __restrict leaf = (InstanceLeaf*) hit.getInstanceLeafPtr(); if (leaf == nullptr) return { { 1,0,0 }, { 0,1,0 }, { 0,0,1 }, { 0,0,0 } }; return { { leaf->part0.world2obj_vx[0], leaf->part0.world2obj_vx[1], leaf->part0.world2obj_vx[2] }, { leaf->part0.world2obj_vy[0], leaf->part0.world2obj_vy[1], leaf->part0.world2obj_vy[2] }, { leaf->part0.world2obj_vz[0], leaf->part0.world2obj_vz[1], leaf->part0.world2obj_vz[2] }, { leaf->part1.world2obj_p [0], leaf->part1.world2obj_p [1], leaf->part1.world2obj_p [2] } }; } SYCL_EXTERNAL intel_float4x3 intel_get_hit_object_to_world( intel_ray_query_t& query, intel_hit_type_t hit_type ) { MemHit& hit = query.hit(hit_type); InstanceLeaf* __restrict leaf = (InstanceLeaf*) hit.getInstanceLeafPtr(); if (leaf == nullptr) return { { 1,0,0 }, { 0,1,0 }, { 0,0,1 }, { 0,0,0 } }; return { { leaf->part1.obj2world_vx[0], leaf->part1.obj2world_vx[1], leaf->part1.obj2world_vx[2] }, { leaf->part1.obj2world_vy[0], leaf->part1.obj2world_vy[1], leaf->part1.obj2world_vy[2] }, { leaf->part1.obj2world_vz[0], leaf->part1.obj2world_vz[1], leaf->part1.obj2world_vz[2] }, { leaf->part0.obj2world_p [0], leaf->part0.obj2world_p [1], leaf->part0.obj2world_p [2] } }; } SYCL_EXTERNAL void intel_get_hit_triangle_vertices( intel_ray_query_t& query, intel_float3 verts_out[3], intel_hit_type_t hit_type ) { const QuadLeaf* __restrict leaf = (const QuadLeaf*) query.hit(hit_type).getPrimLeafPtr(); unsigned int j0 = 0, j1 = 1, j2 = 2; if (query.hit(hit_type).primLeafIndex != 0) { j0 = leaf->j0; j1 = leaf->j1; j2 = leaf->j2; } verts_out[0] = { leaf->v[j0][0], leaf->v[j0][1], leaf->v[j0][2] }; verts_out[1] = { leaf->v[j1][0], leaf->v[j1][1], leaf->v[j1][2] }; verts_out[2] = { leaf->v[j2][0], leaf->v[j2][1], leaf->v[j2][2] }; } SYCL_EXTERNAL intel_float3 intel_get_ray_origin( intel_ray_query_t& query, unsigned int bvh_level) { struct RTStack* __restrict rtStack = sycl::global_ptr((struct RTStack*)query.opaque2).get(); MemRay& ray = rtStack->ray[bvh_level]; return { ray.org[0], ray.org[1], ray.org[2] }; } SYCL_EXTERNAL intel_float3 intel_get_ray_direction( intel_ray_query_t& query, unsigned int bvh_level) { struct RTStack* __restrict rtStack = sycl::global_ptr((struct RTStack*)query.opaque2).get(); MemRay& ray = rtStack->ray[bvh_level]; return { ray.dir[0], ray.dir[1], ray.dir[2] }; } SYCL_EXTERNAL float intel_get_ray_tmin( intel_ray_query_t& query, unsigned int bvh_level) { struct RTStack* __restrict rtStack = sycl::global_ptr((struct RTStack*)query.opaque2).get(); return rtStack->ray[bvh_level].tnear; } SYCL_EXTERNAL intel_ray_flags_t intel_get_ray_flags( intel_ray_query_t& query, unsigned int bvh_level) { struct RTStack* __restrict rtStack = sycl::global_ptr((struct RTStack*)query.opaque2).get(); return (intel_ray_flags_t) rtStack->ray[bvh_level].rayFlags; } SYCL_EXTERNAL unsigned int intel_get_ray_mask( intel_ray_query_t& query, unsigned int bvh_level) { struct RTStack* __restrict rtStack = sycl::global_ptr((struct RTStack*)query.opaque2).get(); return rtStack->ray[bvh_level].rayMask; } SYCL_EXTERNAL bool intel_is_traversal_done( intel_ray_query_t& query ) { return query.hit(intel_hit_type_potential_hit).done; } SYCL_EXTERNAL intel_candidate_type_t intel_get_hit_candidate( intel_ray_query_t& query, intel_hit_type_t hit_type) { return query.hit(hit_type).leafType == NODE_TYPE_QUAD ? intel_candidate_type_triangle : intel_candidate_type_procedural; } SYCL_EXTERNAL bool intel_has_committed_hit( intel_ray_query_t& query ) { return query.hit(intel_hit_type_committed_hit).valid; } level-zero-raytracing-support-1.0.0/rttrace/rttrace_validation.h000066400000000000000000000160241450534701400251500ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once #include #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" #pragma clang diagnostic ignored "-W#pragma-messages" #include #pragma clang diagnostic pop enum intel_ray_flags_t { intel_ray_flags_none = 0x00, intel_ray_flags_force_opaque = 0x01, // forces geometry to be opaque (no anyhit shader invokation) intel_ray_flags_force_non_opaque = 0x02, // forces geometry to be non-opqaue (invoke anyhit shader) intel_ray_flags_accept_first_hit_and_end_search = 0x04, // terminates traversal on the first hit found (shadow rays) intel_ray_flags_skip_closest_hit_shader = 0x08, // skip execution of the closest hit shader intel_ray_flags_cull_back_facing_triangles = 0x10, // back facing triangles to not produce a hit intel_ray_flags_cull_front_facing_triangles = 0x20, // front facing triangles do not produce a hit intel_ray_flags_cull_opaque = 0x40, // opaque geometry does not produce a hit intel_ray_flags_cull_non_opaque = 0x80, // non-opaque geometry does not produce a hit intel_ray_flags_skip_triangles = 0x100, // treat all triangle intersections as misses. intel_ray_flags_skip_procedural_primitives = 0x200, // skip execution of intersection shaders }; enum intel_hit_type_t { intel_hit_type_committed_hit = 0, intel_hit_type_potential_hit = 1, }; enum intel_raytracing_ext_flag_t { intel_raytracing_ext_flag_ray_query = 1 << 0, // true if ray queries are supported }; struct intel_float2 { float x, y; intel_float2() {} intel_float2(float x, float y) : x(x), y(y) {} intel_float2(sycl::float2 v) : x(v.x()), y(v.y()) {} operator sycl::float2() { return sycl::float2(x,y); } }; struct intel_float3 { float x, y, z; intel_float3() {} intel_float3(float x, float y, float z) : x(x), y(y), z(z) {} intel_float3(sycl::float3 v) : x(v.x()), y(v.y()), z(v.z()) {} operator sycl::float3() { return sycl::float3(x,y,z); } }; struct intel_float4x3 { intel_float3 vx, vy, vz, p; }; struct intel_ray_desc_t { intel_float3 origin; intel_float3 direction; float tmin; float tmax; unsigned int mask; intel_ray_flags_t flags; }; #include "rttrace_internal.h" // opaque types struct intel_ray_query_t { void* opaque0; void* opaque1; void* opaque2; uint32_t ctrl; uint32_t bvh_level; MemHit& hit(intel_hit_type_t ty) { struct RTStack* rtStack = (struct RTStack*) opaque2; return rtStack->hit[ty]; } }; typedef __attribute__((opencl_global )) struct intel_raytracing_acceleration_structure_opaque_t* intel_raytracing_acceleration_structure_t; // check supported ray tracing features SYCL_EXTERNAL intel_raytracing_ext_flag_t intel_get_raytracing_ext_flag(); // initializes a ray query SYCL_EXTERNAL intel_ray_query_t intel_ray_query_init( intel_ray_desc_t ray, intel_raytracing_acceleration_structure_t accel ); // setup for instance traversal using a transformed ray and bottom-level AS SYCL_EXTERNAL void intel_ray_query_forward_ray( intel_ray_query_t& query, intel_ray_desc_t ray, intel_raytracing_acceleration_structure_t accel ); // commit the potential hit SYCL_EXTERNAL void intel_ray_query_commit_potential_hit( intel_ray_query_t& query ); // commit the potential hit and override hit distance and UVs SYCL_EXTERNAL void intel_ray_query_commit_potential_hit_override( intel_ray_query_t& query, float override_hit_distance, intel_float2 override_uv ); // start traversal of a ray query SYCL_EXTERNAL void intel_ray_query_start_traversal( intel_ray_query_t& query ); // synchronize rayquery execution. If a ray was dispatched, // This must be called prior to calling any of the accessors below. SYCL_EXTERNAL void intel_ray_query_sync( intel_ray_query_t& query ); // signal that a ray query will not be used further. This is the moral equaivalent of a delete // this function does an implicit sync SYCL_EXTERNAL void intel_ray_query_abandon( intel_ray_query_t& query ); // read hit information during shader execution SYCL_EXTERNAL unsigned int intel_get_hit_bvh_level( intel_ray_query_t& query, intel_hit_type_t hit_type ); SYCL_EXTERNAL float intel_get_hit_distance( intel_ray_query_t& query, intel_hit_type_t hit_type ); SYCL_EXTERNAL intel_float2 intel_get_hit_barycentrics( intel_ray_query_t& query, intel_hit_type_t hit_type ); SYCL_EXTERNAL bool intel_get_hit_front_face( intel_ray_query_t& query, intel_hit_type_t hit_type ); SYCL_EXTERNAL unsigned int intel_get_hit_geometry_id(intel_ray_query_t& query, intel_hit_type_t hit_type ); SYCL_EXTERNAL unsigned int intel_get_hit_primitive_id( intel_ray_query_t& query, intel_hit_type_t hit_type ); SYCL_EXTERNAL unsigned int intel_get_hit_triangle_primitive_id( intel_ray_query_t& query, intel_hit_type_t hit_type ); // fast path for quad leaves SYCL_EXTERNAL unsigned int intel_get_hit_procedural_primitive_id( intel_ray_query_t& query, intel_hit_type_t hit_type ); // fast path for procedural leaves SYCL_EXTERNAL unsigned int intel_get_hit_instance_id( intel_ray_query_t& query, intel_hit_type_t hit_type ); SYCL_EXTERNAL unsigned int intel_get_hit_instance_user_id( intel_ray_query_t& query, intel_hit_type_t hit_type ); SYCL_EXTERNAL intel_float4x3 intel_get_hit_world_to_object( intel_ray_query_t& query, intel_hit_type_t hit_type ); SYCL_EXTERNAL intel_float4x3 intel_get_hit_object_to_world( intel_ray_query_t& query, intel_hit_type_t hit_type ); // fetch triangle vertices for a hit SYCL_EXTERNAL void intel_get_hit_triangle_vertices( intel_ray_query_t& query, intel_float3 vertices_out[3], intel_hit_type_t hit_type ); // Read ray-data. This is used to read transformed rays produced by HW instancing pipeline // during any-hit or intersection shader execution. SYCL_EXTERNAL intel_float3 intel_get_ray_origin( intel_ray_query_t& query, unsigned int bvh_level ); SYCL_EXTERNAL intel_float3 intel_get_ray_direction( intel_ray_query_t& query, unsigned int bvh_level ); SYCL_EXTERNAL float intel_get_ray_tmin( intel_ray_query_t& query, unsigned int bvh_level ); SYCL_EXTERNAL intel_ray_flags_t intel_get_ray_flags( intel_ray_query_t& query, unsigned int bvh_level ); SYCL_EXTERNAL unsigned int intel_get_ray_mask( intel_ray_query_t& query, unsigned int bvh_level ); // if traversal returns one can test if a triangle or procedural is hit enum intel_candidate_type_t { intel_candidate_type_triangle, intel_candidate_type_procedural }; SYCL_EXTERNAL intel_candidate_type_t intel_get_hit_candidate( intel_ray_query_t& query, intel_hit_type_t hit_type ); // test whether traversal has terminated. If false, the ray has reached // a procedural leaf or a non-opaque triangle leaf, and requires shader processing SYCL_EXTERNAL bool intel_is_traversal_done( intel_ray_query_t& query ); // if traversal is done one can test for the presence of a committed hit to either invoke miss or closest hit shader SYCL_EXTERNAL bool intel_has_committed_hit( intel_ray_query_t& query ); level-zero-raytracing-support-1.0.0/sle/000077500000000000000000000000001450534701400202355ustar00rootroot00000000000000level-zero-raytracing-support-1.0.0/sle/intel-level-zero-gpu-raytracing.spec000066400000000000000000000037461450534701400272520ustar00rootroot00000000000000# # spec file for package level-zero-raytracing # # Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed # upon. The license for this file, and modifications and additions to the # file, is the same license as for the pristine package itself (unless the # license for the pristine package is not an Open Source License, in which # case the license is the MIT License). An "Open Source License" is a # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. # Please submit bugfixes or comments via https://bugs.opensuse.org/ # #it's changed by external script %global ver 1.0.0 %global rel 1 Name: intel-level-zero-gpu-raytracing Version: %{ver} Release: %{rel}%{?dist} Summary: Level Zero Ray Tracing Support library Group: System Environment/Libraries License: Apache2 URL: https://github.com/oneapi-src/level-zero-raytracing Source0: %{url}/archive/%{ver}/intel-level-zero-gpu-raytracing-%{ver}.tar.gz BuildRequires: make gcc-c++ cmake git pkg-config %description The Level Zero Ray Tracing Support library implements high performance CPU based construction algorithms for 3D acceleration structures that are compatible with the ray tracing hardware of Intel GPUs. This library is used by Intel(R) oneAPI Level Zero to implement part of the RTAS builder extension. This library should not get used directly but only through Level Zero. . Level Zero Ray Tracing Support library %debug %prep %autosetup -p1 -n %{name}-%{ver} %build %cmake .. \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX=/usr %make_build %install cd build %make_install %files %defattr(-,root,root) %config(noreplace) %license LICENSE.txt %license third-party-programs* %{_libdir}/libze_intel_gpu_raytracing.so %doc %changelog * Thu Jun 8 2023 Pavel Androniychuk - 1.0.0 - Spec file init level-zero-raytracing-support-1.0.0/testing/000077500000000000000000000000001450534701400211275ustar00rootroot00000000000000level-zero-raytracing-support-1.0.0/testing/CMakeLists.txt000066400000000000000000000207121450534701400236710ustar00rootroot00000000000000## Copyright 2009-2022 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 #PROJECT(rthwif_testing) #CMAKE_MINIMUM_REQUIRED(VERSION 3.1.0) SET(CMAKE_CXX_STANDARD 17) SET(CMAKE_INSTALL_RPATH "$ORIGIN/../${CMAKE_INSTALL_LIBDIR}") SET(CTEST_TEST_FILE "${CMAKE_BINARY_DIR}/CTestTestfile.install") file(WRITE "${CTEST_TEST_FILE}" "# CTestTestfile.cmake self generated for package testing\n") IF (ZE_RAYTRACING_SYCL_TESTS STREQUAL "DEFAULT_RTAS_BUILDER") SET(RTAS_BUILDER_MODE "--default-rtas-builder") ELSEIF (ZE_RAYTRACING_SYCL_TESTS STREQUAL "INTERNAL_RTAS_BUILDER") SET(RTAS_BUILDER_MODE "--internal-rtas-builder") ELSEIF (ZE_RAYTRACING_SYCL_TESTS STREQUAL "LEVEL_ZERO_RTAS_BUILDER") SET(RTAS_BUILDER_MODE "--level-zero-rtas-builder") ELSE() MESSAGE(FATAL_ERROR "invalid test mode") ENDIF() MACRO(MY_ADD_TEST) CMAKE_PARSE_ARGUMENTS(MY_ADD_TEST "" "NAME;WORKING_DIRECTORY" "COMMAND" ${ARGN}) STRING(REPLACE ";" " " MY_ADD_TEST_COMMAND_STR "${MY_ADD_TEST_COMMAND}") FILE(APPEND "${CTEST_TEST_FILE}" "add_test(${MY_ADD_TEST_NAME} ./${MY_ADD_TEST_COMMAND_STR} ${RTAS_BUILDER_MODE})\n") #FILE(APPEND "${CTEST_TEST_FILE}" "set_tests_properties(${MY_ADD_TEST_NAME} PROPERTIES WORKING_DIRECTORY \"${MY_ADD_TEST_WORKING_DIRECTORY}\")\n") ADD_TEST(NAME ${MY_ADD_TEST_NAME} COMMAND ${MY_ADD_TEST_COMMAND} ${RTAS_BUILDER_MODE} WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) ENDMACRO() GET_FILENAME_COMPONENT(SYCL_COMPILER_DIR ${CMAKE_CXX_COMPILER} PATH) SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -isystem \"${SYCL_COMPILER_DIR}/../include/sycl\" -isystem \"${SYCL_COMPILER_DIR}/../include/\"") # disable warning from SYCL header (FIXME: why required?) #ADD_COMPILE_DEFINITIONS(EMBREE_SYCL_SUPPORT) IF (ZE_RAYTRACING_RT_SIMULATION) SET(RT_SIM_LIBRARY rtcore) ADD_COMPILE_DEFINITIONS(ZE_RAYTRACING_RT_SIMULATION) ENDIF() ADD_EXECUTABLE(embree_rthwif_cornell_box rthwif_cornell_box.cpp) TARGET_LINK_LIBRARIES(embree_rthwif_cornell_box sys simd tbb ze_wrapper ${RT_SIM_LIBRARY}) SET_PROPERTY(TARGET embree_rthwif_cornell_box APPEND PROPERTY COMPILE_FLAGS "-fsycl -fsycl-targets=spir64") SET_PROPERTY(TARGET embree_rthwif_cornell_box APPEND PROPERTY LINK_FLAGS "-fsycl -fsycl-targets=spir64 -Xsycl-target-backend=spir64 \" -cl-intel-greater-than-4GB-buffer-required \"") TARGET_COMPILE_DEFINITIONS(embree_rthwif_cornell_box PUBLIC EMBREE_LEVEL_ZERO ZE_RAYTRACING) ADD_CUSTOM_COMMAND(TARGET embree_rthwif_cornell_box POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/cornell_box_reference.tga" "$") ADD_EXECUTABLE(embree_rthwif_test rthwif_test.cpp) TARGET_LINK_LIBRARIES(embree_rthwif_test sys simd tbb ze_wrapper ${RT_SIM_LIBRARY}) SET_PROPERTY(TARGET embree_rthwif_test APPEND PROPERTY COMPILE_FLAGS "-fsycl -fsycl-targets=spir64") SET_PROPERTY(TARGET embree_rthwif_test APPEND PROPERTY LINK_FLAGS "-fsycl -fsycl-targets=spir64 -Xsycl-target-backend=spir64 \" -cl-intel-greater-than-4GB-buffer-required \"") TARGET_COMPILE_DEFINITIONS(embree_rthwif_test PUBLIC EMBREE_LEVEL_ZERO ZE_RAYTRACING) MY_ADD_TEST(NAME rthwif_cornell_box COMMAND embree_rthwif_cornell_box --compare cornell_box_reference.tga) MY_ADD_TEST(NAME rthwif_test_builder_triangles_expected COMMAND embree_rthwif_test --build_test_triangles --build_mode_expected) MY_ADD_TEST(NAME rthwif_test_builder_procedurals_expected COMMAND embree_rthwif_test --build_test_procedurals --build_mode_expected) MY_ADD_TEST(NAME rthwif_test_builder_instances_expected COMMAND embree_rthwif_test --build_test_instances --build_mode_expected) MY_ADD_TEST(NAME rthwif_test_builder_mixed_expected COMMAND embree_rthwif_test --build_test_mixed --build_mode_expected) MY_ADD_TEST(NAME rthwif_test_benchmark_triangles COMMAND embree_rthwif_test --benchmark_triangles) MY_ADD_TEST(NAME rthwif_test_benchmark_procedurals COMMAND embree_rthwif_test --benchmark_procedurals) MY_ADD_TEST(NAME rthwif_test_builder_triangles_worst_case COMMAND embree_rthwif_test --build_test_triangles --build_mode_worst_case) MY_ADD_TEST(NAME rthwif_test_builder_procedurals_worst_case COMMAND embree_rthwif_test --build_test_procedurals --build_mode_worst_case) MY_ADD_TEST(NAME rthwif_test_builder_instances_worst_case COMMAND embree_rthwif_test --build_test_instances --build_mode_worst_case) MY_ADD_TEST(NAME rthwif_test_builder_mixed_worst_case COMMAND embree_rthwif_test --build_test_mixed --build_mode_worst_case) MY_ADD_TEST(NAME rthwif_test_triangles_committed_hit COMMAND embree_rthwif_test --no-instancing --triangles-committed-hit) MY_ADD_TEST(NAME rthwif_test_triangles_potential_hit COMMAND embree_rthwif_test --no-instancing --triangles-potential-hit) MY_ADD_TEST(NAME rthwif_test_triangles_anyhit_shader_commit COMMAND embree_rthwif_test --no-instancing --triangles-anyhit-shader-commit) MY_ADD_TEST(NAME rthwif_test_triangles_anyhit_shader_reject COMMAND embree_rthwif_test --no-instancing --triangles-anyhit-shader-reject) MY_ADD_TEST(NAME rthwif_test_procedurals_committed_hit COMMAND embree_rthwif_test --no-instancing --procedurals-committed-hit) MY_ADD_TEST(NAME rthwif_test_hwinstancing_triangles_committed_hit COMMAND embree_rthwif_test --hw-instancing --triangles-committed-hit) MY_ADD_TEST(NAME rthwif_test_hwinstancing_triangles_potential_hit COMMAND embree_rthwif_test --hw-instancing --triangles-potential-hit) MY_ADD_TEST(NAME rthwif_test_hwinstancing_triangles_anyhit_shader_commit COMMAND embree_rthwif_test --hw-instancing --triangles-anyhit-shader-commit) MY_ADD_TEST(NAME rthwif_test_hwinstancing_triangles_anyhit_shader_reject COMMAND embree_rthwif_test --hw-instancing --triangles-anyhit-shader-reject) MY_ADD_TEST(NAME rthwif_test_hwinstancing_procedurals_committed_hit COMMAND embree_rthwif_test --hw-instancing --procedurals-committed-hit) MY_ADD_TEST(NAME rthwif_test_swinstancing_triangles_committed_hit COMMAND embree_rthwif_test --sw-instancing --triangles-committed-hit) MY_ADD_TEST(NAME rthwif_test_swinstancing_triangles_potential_hit COMMAND embree_rthwif_test --sw-instancing --triangles-potential-hit) MY_ADD_TEST(NAME rthwif_test_swinstancing_triangles_anyhit_shader_commit COMMAND embree_rthwif_test --sw-instancing --triangles-anyhit-shader-commit) MY_ADD_TEST(NAME rthwif_test_swinstancing_triangles_anyhit_shader_reject COMMAND embree_rthwif_test --sw-instancing --triangles-anyhit-shader-reject) MY_ADD_TEST(NAME rthwif_test_swinstancing_procedurals_committed_hit COMMAND embree_rthwif_test --sw-instancing --procedurals-committed-hit) INSTALL(TARGETS embree_rthwif_cornell_box RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT test) INSTALL(FILES "${CMAKE_CURRENT_SOURCE_DIR}/cornell_box_reference.tga" DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT test) INSTALL(TARGETS embree_rthwif_test RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT test) INSTALL(FILES "${CTEST_TEST_FILE}" DESTINATION "${CMAKE_INSTALL_BINDIR}" RENAME "CTestTestfile.cmake" COMPONENT test) ############################################################## # Install SYCL specific files ############################################################## IF (ZE_RAYTRACING_SYCL_TESTS) GET_FILENAME_COMPONENT(DPCPP_COMPILER_DIR ${CMAKE_CXX_COMPILER} PATH) IF (WIN32) FILE(GLOB_RECURSE LIB_SYCL_LIB_FILES "${DPCPP_COMPILER_DIR}/../lib/sycl?.lib") IF (NOT LIB_SYCL_LIB_FILES) SET(LIB_SYCL_LIB_FILES "${DPCPP_COMPILER_DIR}/../lib/sycl?.lib") ENDIF() INSTALL(FILES ${LIB_SYCL_LIB_FILES} DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT lib) FILE(GLOB_RECURSE LIB_SYCL_DLL_FILES "${DPCPP_COMPILER_DIR}/../bin/sycl?.dll") IF (NOT LIB_SYCL_DLL_FILES) SET(LIB_SYCL_DLL_FILES "${DPCPP_COMPILER_DIR}/../bin/sycl?.dll") ENDIF() INSTALL(FILES ${LIB_SYCL_DLL_FILES} DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT lib) INSTALL(FILES "${DPCPP_COMPILER_DIR}/../bin/pi_level_zero.dll" DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT lib) INSTALL(FILES "${DPCPP_COMPILER_DIR}/../bin/pi_win_proxy_loader.dll" DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT lib) ELSE() FILE(GLOB_RECURSE LIB_SYCL_FILES "${DPCPP_COMPILER_DIR}/../lib/libsycl.so.?") IF (NOT LIB_SYCL_FILES) SET(LIB_SYCL_FILES "${DPCPP_COMPILER_DIR}/../lib/libsycl.so.?") ENDIF() INSTALL(FILES ${LIB_SYCL_FILES} DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT lib) INSTALL(FILES "${DPCPP_COMPILER_DIR}/../lib/libpi_level_zero.so" DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT lib) ENDIF() ENDIF() level-zero-raytracing-support-1.0.0/testing/cornell_box.tga000066400000000000000000030000221450534701400241270ustar00rootroot00000000000000                                                          ! ! " " # # $ $ % % & & ' ' ( ( ) ) * * + + , , - - . . / / 0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 : : ; ; < < = = > > ? ? @ @ A A B B C C D D D E E F F G G H H I I J J K K L L M M N N O O P P Q Q R R S S T T U U V V W W X X Y Y Z Z [ [ \ \ ] ] ^ ^ _ _ ` ` a a b b c c d d e e f f g g h h i i j j k k l l m m n n n o o p p q q r r s s t t u~ u~ v} v} w| w| x{ x{ yz yz zy zy {x {x |w |w }v }v ~u ~u t t s s r r q q p p o o n n m m l l k k j j i i h h g g f f e e d d c c b b a a ` ` _ _ ^ ^ ] ] \ \ [ [ Z Z Y Y X X W W V V U U U T T S S R R Q Q P P O O N N M M L L K K J J I I H H G G F F E E D D C C B B A A @ @ ? ? > > = = < < ; ; : : 9 9 8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1 0 0 / / . . - - , , + + + * * ) ) ( ( ' ' & & % % $ $ # # " " ! !                                                                                                                   ! ! " " # # $ $ % % & & ' ' ( ( ) ) * * + + , , - - . . . / / 0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 : : ; ; < < = = > > ? ? @ @ A A B B C C D D E E F F G G H H I I J J K K L L M M N N O O P P Q Q R R S S T T U U V V W W X X Y Y Z Z [ [ \ \ ] ] ^ ^ _ _ ` ` a a b b c c d d e e f f g g h h i i j j k k l l m m m n n o o p p q q r r s s~ t~ t} u} u| v| v{ w{ wz xz xy yy yx zx zw {w {v |v |u }u }t ~t ~s s r r q q p p o o n n m m l l k k j j i i h h g g f f e e d d c c b b a a ` ` _ _ ^ ^ ] ] \ \ [ [ Z Z Y Y X X W W V V U U T T S S R R Q Q P P O O N N M M L L K K J J I I H H G G F F E E D D C C B B A A @ @ @ ? ? > > = = < < ; ; : : 9 9 8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1 0 0 / / . . - - , , + + * * ) ) ( ( ' ' & & % % $ $ # # " " ! !                                                                                  !!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??@@AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRRSSTTUUVVWWXXYYZZ[[\\]]^^__``aabbccddeeffgghhiiijjkkllmmnnooppqqr~r~s}s}t|t|u{u{vzvzwywyxxxxywywzvzv{u{u|t|t}s}s~r~rqqppoonnmmllkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!                                            !!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??@@AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRRSSTTUUVVWWXXYYZZ[[\\]]^^__``aabbccddeeffgghhiijjkkllmmnnoopp~q~q}r}r|s|s{t{tzuzuyvyvxwxwwxwxvyvyuzuzt{t{s|s|r}r}q~q~ppoonnmmllkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!                                            !!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??@@AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRRSSTTUUVVWWXXYYZZ[[\\]]^^__``aabbccddeeffgghhiijjkkllmmnn~o~o}p}p|q|q{r{rzszsytytxuxuwvwvvwvwuxuytytzszs{r{r|q|q}p}p~o~onnmmllkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!                                          !!""##$$%%&&''(())**++,,--..//0011223345566778899::;;<<==>>??@@AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRRSSTTUUVVWWXXYYZZ[[\\]]^^__``aabbccddeeffgghhiijjkkllm~m~n}n}o|o|p{p{qzqzryrysxsxtwuwuvvvvuwuwtxtxsysyrzrzq{q{p|p|o}o}n~n~mmllkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@?>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!                                    !!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??@@AABBCCDDEEFFGGHIIJJKKLLMMNNOOPPQQRRSSTTUUVVWWXXYYZZ[[\\]]^^__``aabbccddeeffgghhiijjkk~l~l}m}m|n|n{o{ozpzpyqyqxrxrwswtvtvuuuuvtvtwswsxrxryqyqzpzp{o{o|n|n}m}m~l~lkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::99887766554433221100//..--,,++*))((''&&%%$$##""!!                              !!""##$$%%&&''(())**++,,--..//0011223445566778899::;;<<==>>??@@AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRSSTTUUVVWWXXYYZZ[[\\]]^^__``aabbccddeeffgghhiij~j~k}k}l|l|m{m{nznzoyoypxpxqwqwrvsvsututtutusvsvrwrwqxqxpypyozozn{n{m|m|l}l}k~k~jjiihhggffeeddccbbaa``_^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@?>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!                        !!""##$$%%&''(())**++,,--..//00112233445566778899::;;<<==>>?@@AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRRSSTTUUVVWWXYYZZ[[\\]]^^__``aabbccddeeffgghh~i~i}j}j|k|k{l{lzmzmynynxoxowpwpvqvquruststtstsururvqvqwpwpxoxoynynzmzm{l{l|k|k}j}j~i~ihhggfeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::9988776655443221100//..--,,++**))((''&&%%$$##""!!                               !!""##$$%%&&''(())**++,,--..//0011233445566778899::;;<<==>>??@@AABBCCDDEEFFGHHIIJJKKLLMMNNOOPPQQRRSSTTUUVVWWXXYYZZ[[\]]^^__``aabbccddeeffg~g~h}h}i|i|j{j{kzkzlylymxmxnwnwovovpupuqtqtrssssrtrtququpvpvowownxnxmymylzlzk{k{j|i|i}h}h~g~gffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@??>>==<<;;::99887766554433221100//..--,,++*))((''&&%%$$##""!!                                     !!""##$$%%&&''(()**++,,--..//00112233445566778899::;<<==>>??@@AABBCCDDEEFFGGHHIIJJKKLLMNNOOPPQQRRSSTTUUVVWWXXYYZZ[[\\]]^^_``aabbccddee~f~f}g}g|h|h{i{izjzjykykxlxlwmwmvnvnuouotptpsqsrrrrsqsqtptpuouovnvnwmwlxlxkykyjzjzi{i{h|h|g}g}f~f~eeddccbbaa``__^^]]\\[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIHHGGFFEEDDCCBBAA@@??>>==<<;;::9988766554433221100//..--,,++**))((''&&%%$##""!!                                            !!"##$$%%&&''(())**++,,--..//0011233445566778899::;;<<==>>??@@AABCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRSSTTUUVVWWXXYYZZ[[\\]]^^__``abbccd~d~e}e}f|f|g{g{hzhziyiyjxjxkwkwlvlvmumuntntososprprqqrqrpspsotntnumumvlvlwkwkxjxjyiyizhzh{g{g|f|f}e}e~d~dccbbaa``_^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPONNMMLLKKJJIIHHGGFFEEDDCCBBAA@??>>==<<;;::9988776655443322110//..--,,++**))((''&&%%$$##""!!                                             !!""##$$%%&&''(())**+,,--..//0011223344556677889::;;<<==>>??@@AABBCCDDEEFFGHHIIJJKKLLMMNNOOPPQQRRSSTTUVVWWXXYYZZ[[\\]]^^__``aab~b~c}d}d|e|e{f{fzgzgyhyhxixiwjwjvkvkulultmtmsnsnroroqppppqorornsnsmtmtlulukvkvjwjwixixhyhygzgzf{f{e|e|d}d}c~b~baa``__^^]]\\[[ZZYYXXWWVVUTTSSRRQQPPOONNMMLLKKJJIIHHGFFEEDDCCBBAA@@??>>==<<;;::9887766554433221100//..--,,+**))((''&&%%$$##""!!                                            !!""##$$%&&''(())**++,,--..//0011233445566778899::;;<<==>??@@AABBCCDDEEFFGGHHIIJJKLLMMNNOOPPQQRRSSTTUUVVWWXYYZZ[[\\]]^^__``~a~a}b}b|c|c{d{ezezfyfygxgxhwhwivivjujuktktlslsmrmqnqnpopoopopnqnrmrmslsltktkujujviviwhwhxgxgyfyezezd{d{c|c|b}b}a~a``__^^]]\\[[ZZYXXWWVVUUTTSSRRQQPPOONNMMLKKJJIIHHGGFFEEDDCCBBAA@??>>==<<;;::9988776655443221100//..--,,++**))((''&%%$$##""!!                                                                                     ! ! " " # # $ $ % % & & ' ' ( ( ) ) * * + + , - - . . / / 0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 8 8 9 9 : : ; ; < < = = > > ? ? @ @ A A B B C D D E E F F G G H H I I J J K K L L M M N O O P P Q Q R R S S T T U U V V W W X X Y Y Z [ [ \ \ ] ] ^ ^ _~ _~ `} `} a| a| b{ b{ cz cz dy dy ex fx fw gw gv hv hu iu it jt js kr kr lq lq mp mp no no on on pm pm ql rl rk sk sj tj ti ui uh vg vg wf wf xe xe yd yd zc zc {b {b |a |a }` ~` ~_ _ ^ ^ ] ] \ [ [ Z Z Y Y X X W W V V U U T T S S R R Q P P O O N N M M L L K K J J I I H H G G F F E D D C C B B A A @ @ ? ? > > = = < < ; ; : 9 9 8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1 0 0 / / . - - , , + + * * ) ) ( ( ' ' & & % % $ $ # " " ! !                                                         "!!                     !!""""""""""""""""""" " " " " " " " " " """"""""""""""""""""""""""""""""""" " "!"!"""""#"#"$"$"%"%"&"&"'"("(")")"*"*"+"+",","-"-"."."/"/"0"0"1"1"2"3"3"4"4"5"5"6"6"7"7"8"8"9"9":":";";"<"="=">">"?"?"@"@"A"A"B"B"C"C"D"D"E"E"F"F"G"H"H"I"I"J"J"K"K"L"L"M"M"N"N"O"O"P"P"Q"R"R"S"S"T"T"U"U"V"V"W"W"X"X"Y"Y"Z"Z"["["\"]"]~"^~"^}"_}"_|"`|"`{"a{"az"bz"by"cy"cx"dx"dw"ew"ev"fv"gu"gu"ht"hs"is"ir"jr"jq"kq"kp"lp"lo"mo"mn"nn"nm"om"ol"pl"pk"qk"rj"ri"si"sh"th"tg"ug"uf"vf"ve"we"wd"xd"xc"yc"yb"zb"za"{a"|`"|`"}_"}^"~^"~]"]"\"\"["["Z"Z"Y"Y"X"X"W"W"V"V"U"T"T"S"S"R"R"Q"Q"P"P"O"O"N"N"M"M"L"L"K"K"J"I"I"H"H"G"G"F"F"E"E"D"D"C"C"B"B"A"A"@"?"?">">"="="<"<";";":":"9"9"8"8"7"7"6"6"5"4"4"3"3"2"2"1"1"0"0"/"/"."."-"-",","+"*"*")")"("("'"'"&"&"%"%"$"$"#"#"""""!"!" """""""""""""""""""""""""""""""""""" " " " " " " " " """"""""""""""""""      "###""!!                     !!""##$$$$$$$$$$$$$$$$$$ $ $ $ $ $ $ $ $ $ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $ $!$!$"$"$#$$$$$%$%$&$&$'$'$($($)$)$*$*$+$+$,$,$-$.$.$/$/$0$0$1$1$2$2$3$3$4$4$5$5$6$7$7$8$8$9$9$:$:$;$;$<$<$=$=$>$>$?$?$@$A$A$B$B$C$C$D$D$E$E$F$F$G$G$H$H$I$I$J$K$K$L$L$M$M$N$N$O$O$P$P$Q$Q$R$R$S$S$T$U$U$V$V$W$W$X$X$Y$Y$Z$Z$[$[~$\~$\}$]}$^|$^|$_{$_{$`z$`z$ay$ay$bx$bx$cw$cw$dv$dv$eu$et$ft$fs$gs$hr$hr$iq$iq$jp$jp$ko$ko$ln$ln$mm$mm$nl$nk$ok$oj$pj$pi$qi$rh$rh$sg$sg$tf$tf$ue$ue$vd$vd$wc$wc$xb$xa$ya$y`$z`$z_${_$|^$|^$}]$}]$~\$~\$[$[$Z$Z$Y$Y$X$W$W$V$V$U$U$T$T$S$S$R$R$Q$Q$P$P$O$O$N$M$M$L$L$K$K$J$J$I$I$H$H$G$G$F$F$E$D$D$C$C$B$B$A$A$@$@$?$?$>$>$=$=$<$<$;$:$:$9$9$8$8$7$7$6$6$5$5$4$4$3$3$2$2$1$0$0$/$/$.$.$-$-$,$,$+$+$*$*$)$)$($($'$&$&$%$%$$$$$#$#$"$"$!$!$ $ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $ $ $ $ $ $ $ $ $$$$$$$$$$$$$$$$$#!    "#%%$$##""!!                      !!""##$$%%%%%%%%%%%%%%%%%%% % % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % %!%!%"%"%#%#%$%$%%%%%&%&%'%'%(%)%)%*%*%+%+%,%,%-%-%.%.%/%/%0%0%1%1%2%3%3%4%4%5%5%6%6%7%7%8%8%9%9%:%:%;%<%<%=%=%>%>%?%?%@%@%A%A%B%B%C%C%D%E%E%F%F%G%G%H%H%I%I%J%J%K%K%L%L%M%N%N%O%O%P%P%Q%Q%R%R%S%S%T%T%U%U%V%W%W%X%X%Y%Y%Z~%Z~%[}%[}%\|%\|%]{%]{%^z%^z%_y%`y%`x%ax%aw%bw%bv%cu%cu%dt%dt%es%es%fr%fr%gq%gq%hp%ip%io%jo%jn%kn%km%ll%ll%mk%mk%nj%nj%oi%oi%ph%ph%qg%rg%rf%sf%se%te%td%uc%uc%vb%vb%wa%wa%x`%x`%y_%y_%z^%{^%{]%|]%|\%}\%}[%~Z%~Z%Y%Y%X%X%W%W%V%V%U%U%T%T%S%S%R%Q%Q%P%P%O%O%N%N%M%M%L%L%K%K%J%J%I%H%H%G%G%F%F%E%E%D%D%C%C%B%B%A%A%@%?%?%>%>%=%=%<%<%;%;%:%:%9%9%8%8%7%6%6%5%5%4%4%3%3%2%2%1%1%0%0%/%/%.%-%-%,%,%+%+%*%*%)%)%(%(%'%'%&%&%%%$%$%#%#%"%"%!%!% % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % % %%%%%%%%%%%%%%%%%%#!    "#%''&%%$$##""!!                      !!"##$$%%&&''''''''''''''''''' ' ' ' ' ' ' ' ' ''''''''''''''''''''''''''''''''''' ' '!'!'"'"'#'#'$'$'%'&'&'''''('(')')'*'*'+'+',','-'.'.'/'/'0'0'1'1'2'2'3'3'4'4'5'5'6'7'7'8'8'9'9':':';';'<'<'='='>'?'?'@'@'A'A'B'B'C'C'D'D'E'E'F'F'G'H'H'I'I'J'J'K'K'L'L'M'M'N'N'O'P'P'Q'Q'R'R'S'S'T'T'U'U'V'V'W'X'X~'Y~'Y}'Z}'Z|'[|'[{'\{'\z']z']y'^y'^x'_x'_w'`v'av'au'bu'bt'ct'cs'ds'dr'er'eq'fq'fp'gp'go'ho'in'im'jm'jl'kl'kk'lk'lj'mj'mi'ni'nh'oh'og'pg'pf'qe're'rd'sd'sc'tc'tb'ub'ua'va'v`'w`'w_'x_'x^'y^'z]'z\'{\'{['|['|Z'}Z'}Y'~Y'~X'X'W'W'V'V'U'T'T'S'S'R'R'Q'Q'P'P'O'O'N'N'M'M'L'K'K'J'J'I'I'H'H'G'G'F'F'E'E'D'C'C'B'B'A'A'@'@'?'?'>'>'='='<'<';':':'9'9'8'8'7'7'6'6'5'5'4'4'3'2'2'1'1'0'0'/'/'.'.'-'-',','+'*'*')')'('('''''&'&'%'%'$'$'#'#'"'!'!' ' ''''''''''''''''''''''''''''''''''' ' ' ' ' ' ' ' ' ''''''''''''''''''%"      "#%')((''&&%$$##""!!                     !!""##$$%%&&''())))))))))))))))))) ) ) ) ) ) ) ) ) ))))))))))))))))))))))))))))))))))) ) )!)!)")#)#)$)$)%)%)&)&)')')()()))))*)+)+),),)-)-).).)/)/)0)0)1)2)2)3)3)4)4)5)5)6)6)7)7)8)8)9):):););)<)<)=)=)>)>)?)?)@)@)A)B)B)C)C)D)D)E)E)F)F)G)G)H)H)I)J)J)K)K)L)L)M)M)N)N)O)O)P)P)Q)R)R)S)S)T)T)U)U)V)V~)W~)W})X})X|)Y|)Z{)Z{)[z)[z)\y)\y)]x)]x)^w)^v)_v)_u)`u)`t)at)bs)bs)cr)cr)dq)dq)ep)ep)fo)fn)gn)gm)hm)hl)il)jk)jk)kj)kj)li)li)mh)mh)ng)nf)of)oe)pe)pd)qd)rc)rc)sb)sb)ta)ta)u`)u`)v_)v^)w^)w])x])x\)y\)z[)z[){Z){Z)|Y)|Y)}X)}X)~W)~V)V)U)U)T)T)S)S)R)R)Q)Q)P)O)O)N)N)M)M)L)L)K)K)J)J)I)I)H)G)G)F)F)E)E)D)D)C)C)B)B)A)A)@)?)?)>)>)=)=)<)<););):):)9)9)8)7)7)6)6)5)5)4)4)3)3)2)2)1)1)0)/)/).).)-)-),),)+)+)*)*)))))()')')&)&)%)%)$)$)#)#)")")!)!) ))))))))))))))))))))))))))))))))))) ) ) ) ) ) ) ) ) ) ))))))))))))))))(&$"      "#%')**))((''&&%%$$#""! !             ! !""##$$%%&''(())******************* * * * * * * * * * ********************************** * *!*!*"*"*#*#*$*$*%*%*&*'*'*(*(*)*)*****+*+*,*,*-*-*.*/*/*0*0*1*1*2*2*3*3*4*4*5*6*6*7*7*8*8*9*9*:*:*;*;*<*<*=*>*>*?*?*@*@*A*A*B*B*C*C*D*E*E*F*F*G*G*H*H*I*I*J*J*K*K*L*M*M*N*N*O*O*P*P*Q*Q*R*R*S*T*T*U~*U~*V}*V}*W|*W|*X{*X{*Yz*Yz*Zy*[y*[x*\w*\w*]v*]v*^u*^u*_t*_t*`s*`s*ar*ar*bq*cq*cp*do*do*en*en*fm*fm*gl*gl*hk*hk*ij*jj*ji*kh*kh*lg*lg*mf*mf*ne*ne*od*od*pc*pc*qb*rb*ra*s`*s`*t_*t_*u^*u^*v]*v]*w\*w\*x[*y[*yZ*zY*zY*{X*{X*|W*|W*}V*}V*~U*~U*T*T*S*S*R*Q*Q*P*P*O*O*N*N*M*M*L*L*K*J*J*I*I*H*H*G*G*F*F*E*E*D*D*C*B*B*A*A*@*@*?*?*>*>*=*=*<*;*;*:*:*9*9*8*8*7*7*6*6*5*4*4*3*3*2*2*1*1*0*0*/*/*.*.*-*,*,*+*+*****)*)*(*(*'*'*&*%*%*$*$*#*#*"*"*!*!* * ********************************** * * * * * * * * * *****************(&#!     "#%'(*,,++**)((''&&%%$$# # " ! !       ! ! " " ##$%%&&''(())**+,,,,,,,,,,,,,,,,,,, , , , , , , , , , ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, , ,!,!,",",#,$,$,%,%,&,&,',',(,(,),),*,+,+,,,,,-,-,.,.,/,/,0,0,1,2,2,3,3,4,4,5,5,6,6,7,7,8,9,9,:,:,;,;,<,<,=,=,>,>,?,@,@,A,A,B,B,C,C,D,D,E,E,F,F,G,H,H,I,I,J,J,K,K,L,L,M,M,N,O,O,P,P,Q,Q,R,R,S~,S~,T},T},U|,V|,V{,W{,Wz,Xz,Xy,Yy,Yx,Zw,Zw,[v,[v,\u,]u,]t,^t,^s,_s,_r,`r,`q,ap,ap,bo,bo,cn,dn,dm,em,el,fl,fk,gk,gj,hi,hi,ih,ih,jg,kg,kf,lf,le,me,md,nd,nc,ob,ob,pa,pa,q`,r`,r_,s_,s^,t^,t],u],u\,v[,v[,wZ,wZ,xY,yY,yX,zX,zW,{W,{V,|V,|U,}T,}T,~S,~S,R,R,Q,Q,P,P,O,O,N,M,M,L,L,K,K,J,J,I,I,H,H,G,F,F,E,E,D,D,C,C,B,B,A,A,@,?,?,>,>,=,=,<,<,;,;,:,:,9,8,8,7,7,6,6,5,5,4,4,3,3,2,1,1,0,0,/,/,.,.,-,-,,,,,+,*,*,),),(,(,',',&,&,%,%,$,#,#,",",!,!, , ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, , , , , , , , , , ,,,,,,,,,,,,,,,,,*'%#!      "#%'(*,.--,,++**))(''&&%% $ $ # # " " !  ! ! " # # $ $ %%&&''())**++,,--.................. . . . . . . . . ................................... . .!.".".#.#.$.$.%.%.&.&.'.(.(.).).*.*.+.+.,.,.-.-..././.0.0.1.1.2.2.3.3.4.4.5.6.6.7.7.8.8.9.9.:.:.;.<.<.=.=.>.>.?.?.@.@.A.A.B.C.C.D.D.E.E.F.F.G.G.H.H.I.J.J.K.K.L.L.M.M.N.N.O.P.P.Q.Q~.R~.R}.S}.S|.T|.T{.U{.Uz.Vz.Wy.Wy.Xx.Xw.Yw.Yv.Zv.Zu.[u.[t.\t.\s.]s.^r.^q._q._p.`p.`o.ao.an.bn.bm.cm.dl.dl.ek.ej.fj.fi.gi.gh.hh.hg.ig.if.jf.ke.ke.ld.lc.mc.mb.nb.na.oa.o`.p`.p_.q_.r^.r].s].s\.t\.t[.u[.uZ.vZ.vY.wY.xX.xX.yW.yV.zV.zU.{U.{T.|T.|S.}S.}R.~R.Q.Q.P.O.O.N.N.M.M.L.L.K.K.J.I.I.H.H.G.G.F.F.E.E.D.D.C.B.B.A.A.@.@.?.?.>.>.=.=.<.;.;.:.:.9.9.8.8.7.7.6.5.5.4.4.3.3.2.2.1.1.0.0./.....-.-.,.,.+.+.*.*.).).(.'.'.&.&.%.%.$.$.#.#.".!.!. . .................................. . . . . . . . . . .................+)'%"          "#%'(*,.///..-,,++**))(('' & % % $ $ # # " "!!  !!" " # # $ $ % % & ''(())**++,,-..//000000000000000000 0 0 0 0 0 0 0 0 0000000000000000000000000000000000 0 0!0!0"0"0#0#0$0$0%0&0&0'0'0(0(0)0)0*0*0+0,0,0-0-0.0.0/0/0000010202030304040505060607070809090:0:0;0;0<0<0=0=0>0?0?0@0@0A0A0B0B0C0C0D0E0E0F0F0G0G0H0H0I0I0J0J0K0L0L0M0M0N0N0O0O~0P~0P}0Q}0R|0R|0S{0S{0Tz0Tz0Uy0Ux0Vx0Vw0Ww0Xv0Xv0Yu0Yu0Zt0Zt0[s0[s0\r0\q0]q0]p0^p0_o0_o0`n0`n0am0am0bl0bk0ck0cj0dj0ei0ei0fh0fh0gg0gg0hf0he0ie0id0jd0kc0kc0lb0lb0ma0ma0n`0n`0o_0o^0p^0p]0q]0r\0r\0s[0s[0tZ0tZ0uY0uX0vX0vW0wW0xV0xV0yU0yU0zT0zT0{S0{R0|R0|Q0}Q0~P0~P0O0O0N0N0M0M0L0K0K0J0J0I0I0H0H0G0G0F0E0E0D0D0C0C0B0B0A0A0@0?0?0>0>0=0=0<0<0;0;0:0:0908080707060605050404030202010100000/0/0.0.0-0,0,0+0+0*0*0)0)0(0(0'0'0&0%0%0$0$0#0#0"0"0!0!0 00000000000000000000000000000000000 0 0 0 0 0 0 0 0 0000000000000000/-+)&$"           "#%'(*,./1100//..--,,+**))( ( ' ' & & % $ $ ##""!!    !!""## $ $ % & & ' ' ( ())**+,,--..//001111111111111111111 1 1 1 1 1 1 1 1 1111111111111111111111111111111111 1 1!1!1"1#1#1$1$1%1%1&1&1'1'1(1)1)1*1*1+1+1,1,1-1-1.1/1/101011111212131314151516161717181819191:1;1;1<1<1=1=1>1>1?1?1@1A1A1B1B1C1C1D1D1E1E1F1G1G1H1H1I1I1J1J1K1K1L1L1M1N~1N~1O}1O}1P|1P|1Q{1Q{1Rz1Rz1Sy1Tx1Tx1Uw1Uw1Vv1Vv1Wu1Wu1Xt1Xt1Ys1Zr1Zr1[q1[q1\p1\p1]o1]o1^n1^n1_m1`l1`l1ak1ak1bj1bj1ci1ci1dh1dh1eg1ff1ff1ge1ge1hd1hd1ic1ic1jb1jb1ka1l`1l`1m_1m_1n^1n^1o]1o]1p\1p\1q[1rZ1rZ1sY1sY1tX1tX1uW1uW1vV1vV1wU1xT1xT1yS1yS1zR1zR1{Q1{Q1|P1|P1}O1~N1~N1M1M1L1L1K1K1J1J1I1H1H1G1G1F1F1E1E1D1D1C1B1B1A1A1@1@1?1?1>1>1=1<1<1;1;1:1:1919181817161615151414131312121110101/1/1.1.1-1-1,1,1+1*1*1)1)1(1(1'1'1&1&1%1$1$1#1#1"1"1!1!1 1 1111111111111111111111111111111111 1 1 1 1 1 1 1 1 11111111111111111/-*(&$!           "#%'(*,./133221100/..--,,++* ) ) ( ( ' ' & & %%$##""!!    !!""#$$%% & & ' ' ( ( ) * *++,,--.//0011223333333333333333333 3 3 3 3 3 3 3 3 3333333333333333333333333333333333 3!3!3"3"3#3#3$3$3%3%3&3'3'3(3(3)3)3*3*3+3+3,3-3-3.3.3/3/3030313232333334343535363637383839393:3:3;3;3<3<3=3>3>3?3?3@3@3A3A3B3B3C3D3D3E3E3F3F3G3G3H3I3I3J3J3K3K3L~3L~3M}3M}3N|3O|3O{3P{3Pz3Qz3Qy3Rx3Rx3Sw3Sw3Tv3Uv3Uu3Vu3Vt3Wt3Ws3Xr3Xr3Yq3Yq3Zp3[p3[o3\o3\n3]m3]m3^l3^l3_k3`k3`j3aj3ai3bi3bh3cg3cg3df3df3ee3fe3fd3gd3gc3hc3hb3ia3ia3j`3j`3k_3l_3l^3m^3m]3n]3n\3o[3o[3pZ3pZ3qY3rY3rX3sX3sW3tV3tV3uU3uU3vT3wT3wS3xS3xR3yR3yQ3zP3zP3{O3{O3|N3}N3}M3~M3~L3L3K3J3J3I3I3H3H3G3G3F3F3E3D3D3C3C3B3B3A3A3@3?3?3>3>3=3=3<3<3;3;3:393938383737363635353433333232313130303/3/3.3-3-3,3,3+3+3*3*3)3(3(3'3'3&3&3%3%3$3$3#3"3"3!3!3 3 3333333333333333333333333333333333 3 3 3 3 3 3 3 3 333333333333333331.,*'%#!           "#%'(*,./1355443221100//.--,, + + * * ) ) ( ' '&&%%$$#""!!    !""##$$%%&&' ( ( ) ) * * + + ,--..//001123344555555555555555555 5 5 5 5 5 5 5 5 5 555555555555555555555555555555555 5 5!5!5"5"5#5#5$5%5%5&5&5'5'5(5(5)5*5*5+5+5,5,5-5-5.5.5/505051515252535354555556565757585859595:5;5;5<5<5=5=5>5>5?5@5@5A5A5B5B5C5C5D5D5E5F5F5G5G5H5H5I5I5J~5K~5K}5L}5L|5M|5M{5N{5Nz5Oz5Oy5Px5Qx5Qw5Rw5Rv5Sv5Su5Tu5Tt5Us5Vs5Vr5Wr5Wq5Xq5Xp5Yp5Yo5Zo5Zn5[m5\m5\l5]l5]k5^k5^j5_j5_i5`h5ah5ag5bg5bf5cf5ce5de5dd5ed5ec5fb5gb5ga5ha5h`5i`5i_5j_5j^5k]5l]5l\5m\5m[5n[5nZ5oZ5oY5pY5pX5qW5rW5rV5sV5sU5tU5tT5uT5uS5vR5wR5wQ5xQ5xP5yP5yO5zO5zN5{N5{M5|L5}L5}K5~K5~J5J5I5I5H5G5G5F5F5E5E5D5D5C5C5B5A5A5@5@5?5?5>5>5=5<5<5;5;5:5:5959585857565655555454535352515150505/5/5.5.5-5-5,5+5+5*5*5)5)5(5(5'5&5&5%5%5$5$5#5#5"5"5!5 5 5555555555555555555555555555555555 5 5 5 5 5 5 5 5 5555555555555555520.+)'%"             "#%'(*,./13576655443321100//.. - , , + + * * ) )(('&&%%$$##"!!   !!""##$$%&&''(() ) * * + , , - - ..//011223344566777777777777777777 7 7 7 7 7 7 7 7 7777777777777777777777777777777777 7 7!7!7"7#7#7$7$7%7%7&7&7'7(7(7)7)7*7*7+7+7,7-7-7.7.7/7/7070717272737374747575767677787879797:7:7;7;7<7=7=7>7>7?7?7@7@7A7B7B7C7C7D7D7E7E7F7G7G7H7H~7I~7I}7J}7J|7K|7K{7L{7Mz7My7Ny7Nx7Ox7Ow7Pw7Pv7Qv7Ru7Ru7St7Ss7Ts7Tr7Ur7Uq7Vq7Wp7Wp7Xo7Xn7Yn7Ym7Zm7Zl7[l7[k7\k7]j7]i7^i7^h7_h7_g7`g7`f7af7be7bd7cd7cc7dc7db7eb7ea7fa7g`7g`7h_7h^7i^7i]7j]7j\7k\7l[7l[7mZ7mY7nY7nX7oX7oW7pW7pV7qV7rU7rT7sT7sS7tS7tR7uR7uQ7vQ7wP7wO7xO7xN7yN7yM7zM7zL7{L7|K7|K7}J7}I7~I7~H7H7G7G7F7F7E7D7D7C7C7B7B7A7A7@7?7?7>7>7=7=7<7<7;7;7:7979787877777676757474737372727171707/7/7.7.7-7-7,7,7+7*7*7)7)7(7(7'7'7&7&7%7$7$7#7#7"7"7!7!7 7777777777777777777777777777777777 7 7 7 7 7 7 7 7 7777777777777777642/-+)&$"              "#%'(*,./135788877665443322110/ / . . - - , , + **))((''&%%$$##""!    !!""##$%%&&''(()**+ + , , - - . / / 0011223445566778999999999999999999 9 9 9 9 9 9 9 9 9999999999999999999999999999999999 9!9!9"9"9#9#9$9$9%9&9&9'9'9(9(9)9)9*9+9+9,9,9-9-9.9.9/9090919192929393949595969697979898999:9:9;9;9<9<9=9=9>9?9?9@9@9A9A9B9B9C9D9D9E9E9F9F~9G~9G}9H}9I|9I|9J{9J{9Kz9Ky9Ly9Lx9Mx9Nw9Nw9Ov9Ov9Pu9Pt9Qt9Qs9Rs9Sr9Sr9Tq9Tq9Up9Uo9Vo9Vn9Wn9Xm9Xm9Yl9Yl9Zk9Zj9[j9[i9\i9]h9]h9^g9^g9_f9_e9`e9`d9ad9bc9bc9cb9cb9da9d`9e`9e_9f_9g^9g^9h]9h]9i\9i[9j[9jZ9kZ9kY9lY9mX9mX9nW9nW9oV9oU9pU9pT9qT9rS9rS9sR9sR9tQ9tP9uP9uO9vO9wN9wN9xM9xM9yL9yK9zK9zJ9{J9|I9|I9}H9}H9~G9~F9F9E9E9D9D9C9C9B9A9A9@9@9?9?9>9>9=9<9<9;9;9:9:9999989797969695959494939292919190909/9/9.9-9-9,9,9+9+9*9*9)9(9(9'9'9&9&9%9%9$9#9#9"9"9!9!9 9 999999999999999999999999999999999 9 9 9 9 9 9 9 9 99999999999999998641/-*(&$!                 "#%'(*,./13578:::988776655433221 1 0 0 / . . - - ,,++*))((''&&%$$##""!!   !!""#$$%%&&'(())**++,- - . . / / 0 0 1 223344556778899::;;;;;;;;;;;;;;;;; ; ; ; ; ; ; ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ;!;!;";";#;$;$;%;%;&;&;';';(;););*;*;+;+;,;-;-;.;.;/;/;0;0;1;2;2;3;3;4;4;5;5;6;7;7;8;8;9;9;:;:;;;<;<;=;=;>;>;?;?;@;A;A;B;B;C;C;D;D~;E~;F};F};G|;G|;H{;H{;Iz;Iy;Jy;Kx;Kx;Lw;Lw;Mv;Mv;Nu;Nt;Ot;Ps;Ps;Qr;Qr;Rq;Rq;Sp;To;To;Un;Un;Vm;Vm;Wl;Wk;Xk;Yj;Yj;Zi;Zi;[h;[h;\g;\f;]f;^e;^e;_d;_d;`c;`c;ab;aa;ba;c`;c`;d_;d_;e^;e^;f];f\;g\;h[;h[;iZ;iZ;jY;jY;kX;kW;lW;mV;mV;nU;nU;oT;oT;pS;pR;qR;rQ;rQ;sP;sP;tO;tO;uN;vM;vM;wL;wL;xK;xK;yJ;yJ;zI;{H;{H;|G;|G;}F;}F;~E;~D;D;C;C;B;B;A;A;@;?;?;>;>;=;=;<;<;;;:;:;9;9;8;8;7;7;6;5;5;4;4;3;3;2;2;1;0;0;/;/;.;.;-;-;,;+;+;*;*;););(;(;';&;&;%;%;$;$;#;";";!;!; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; ; ; ; ; ; ;;;;;;;;;;;;;;;;:8531.,*(%#!                  "#%'(*,./13578:<<;;::998876655443 3 2 1 1 0 0 / / .--,,++**)((''&&%%$##""!!   !""##$$%%&''(())**+,,--.. / 0 0 1 1 2 2 3 34556677889::;;<<<<<<<<<<<<<<<<<<< < < < < < < < < <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< < <><><=<<<<<;<;<:<:<9<8<8<7<7<6<6<5<5<4<3<3<2<2<1<1<0<0>==<<;;:998877655 4 4 3 3 2 2 1 0 0//..-,,++**))(''&&%%$##""!!   !!""##$$%&&''(()**++,,--.//00 1 1 2 3 3 4 4 5 56678899::;<<==>>>>>>>>>>>>>>>>>>> > > > > > > > >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> > >!>!>">">#>#>$>%>%>&>&>'>'>(>)>)>*>*>+>+>,>,>->.>.>/>/>0>0>1>2>2>3>3>4>4>5>5>6>7>7>8>8>9>9>:>;>;><><>=>=>>>>>?>@>@>A~>A~>B}>B}>C|>D|>D{>E{>Ez>Fy>Fy>Gx>Gx>Hw>Iw>Iv>Ju>Ju>Kt>Kt>Ls>Ms>Mr>Nr>Nq>Op>Op>Po>Po>Qn>Rn>Rm>Sl>Sl>Tk>Tk>Uj>Vj>Vi>Wi>Wh>Xg>Xg>Yf>Yf>Ze>[e>[d>\c>\c>]b>]b>^a>^a>_`>``>`_>a^>a^>b]>b]>c\>d\>d[>eZ>eZ>fY>fY>gX>gX>hW>iW>iV>jU>jU>kT>kT>lS>mS>mR>nQ>nQ>oP>oP>pO>pO>qN>rN>rM>sL>sL>tK>tK>uJ>vJ>vI>wH>wH>xG>xG>yF>yF>zE>{E>{D>|C>|C>}B>}B>~A>A>@>?>?>>>>>=>=><><>;>:>:>9>9>8>8>7>6>6>5>5>4>4>3>3>2>1>1>0>0>/>/>.>->->,>,>+>+>*>*>)>(>(>'>'>&>&>%>$>$>#>#>">">!>!> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> > > > > > > > > >>>>>>>>>>>>>>>>>;97420-+)&$"                   " #%'(*,./13578:<>@@??>>=<<;;::98877 6 6 5 5 4 3 3 2 2110//..--,++**))(('&&%%$$#""!! !!""#$$%%&&''())**++,--..//01122 3 3 4 4 5 6 6 77889::;;<<==>??@@@@@@@@@@@@@@@@@@ @ @ @ @ @ @ @ @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ @!@!@"@#@#@$@$@%@%@&@'@'@(@(@)@)@*@*@+@,@,@-@-@.@.@/@0@0@1@1@2@2@3@4@4@5@5@6@6@7@7@8@9@9@:@:@;@;@<@=@=@>@>@?~@?~@@}@@}@A|@B|@B{@Cz@Cz@Dy@Dy@Ex@Fx@Fw@Gw@Gv@Hu@Hu@It@Jt@Js@Ks@Kr@Lq@Lq@Mp@Mp@No@Oo@On@Pm@Pm@Ql@Ql@Rk@Sk@Sj@Tj@Ti@Uh@Uh@Vg@Wg@Wf@Xf@Xe@Yd@Yd@Zc@Zc@[b@\b@\a@]a@]`@^_@^_@_^@`^@`]@a]@a\@b[@b[@cZ@dZ@dY@eY@eX@fW@fW@gV@gV@hU@iU@iT@jT@jS@kR@kR@lQ@mQ@mP@nP@nO@oN@oN@pM@pM@qL@rL@rK@sJ@sJ@tI@tI@uH@vH@vG@wG@wF@xE@xE@yD@zD@zC@{C@{B@|A@|A@}@@}@@~?@?@>@=@=@<@<@;@;@:@:@9@8@8@7@7@6@6@5@4@4@3@3@2@2@1@1@0@/@/@.@.@-@-@,@+@+@*@*@)@)@(@'@'@&@&@%@%@$@$@#@"@"@!@!@ @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ @ @ @ @ @ @ @ @@@@@@@@@@@@@@@@@=;8641/-*(&$!                  " # %'(*,./13578:<>@BBAA@??>>==<<;::99 8 8 7 6 6 5 5 443221100/..--,,+**))((''&%%$$##" ! !! ! "##$$%%&''(())**+,,--../001122344 5 5 6 6 7 8 8 99::;<<==>>??@AABBBBBBBBBBBBBBBBBB B B B B B B B B BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB B!B!B"B"B#B#B$B$B%B&B&B'B'B(B(B)B*B*B+B+B,B,B-B.B.B/B/B0B0B1B2B2B3B3B4B4B5B5B6B7B7B8B8B9B9B:B;B;B}B?}B?|B@|B@{BAzBAzBByBCyBCxBDxBDwBEvBEvBFuBGuBGtBHtBHsBIsBIrBJqBJqBKpBLpBLoBMoBMnBNmBNmBOlBPlBPkBQkBQjBRiBRiBShBThBTgBUgBUfBVeBVeBWdBXdBXcBYcBYbBZbBZaB[`B\`B\_B]_B]^B^^B^]B_\B_\B`[Ba[BaZBbZBbYBcXBcXBdWBeWBeVBfVBfUBgTBgTBhSBiSBiRBjRBjQBkPBkPBlOBmOBmNBnNBnMBoMBoLBpKBpKBqJBrJBrIBsIBsHBtGBtGBuFBvFBvEBwEBwDBxCBxCByBBzBBzAB{AB{@B|?B|?B}>B~>B~=B=B@BDDCCBAA@@??>==<<;; : 9 9 8 8 7 7 655443321100//.--,,++*))((''&&%$$ # #!""""!# # $$%&&''(()**++,,-..//001223344556 7 7 8 8 9 9 : ;;<<==>??@@AABCCDDDDDDDDDDDDDDDDDD D D D D D D D D DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD D D!D!D"D"D#D$D$D%D%D&D&D'D(D(D)D)D*D*D+D,D,D-D-D.D.D/D0D0D1D1D2D2D3D4D4D5D5D6D6D7D8D8D9D9D:D:D;~D<~D<}D=}D=|D>|D>{D?zD?zD@yDAyDAxDBxDBwDCvDCvDDuDEuDEtDFtDFsDGrDGrDHqDIqDIpDJpDJoDKnDKnDLmDMmDMlDNlDNkDOjDOjDPiDQiDQhDRhDRgDSfDSfDTeDUeDUdDVdDVcDWcDWbDXaDYaDY`DZ`DZ_D[_D[^D\]D]]D]\D^\D^[D_[D_ZD`YDaYDaXDbXDbWDcWDcVDdUDeUDeTDfTDfSDgSDgRDhQDiQDiPDjPDjODkODkNDlMDmMDmLDnLDnKDoKDoJDpIDpIDqHDrHDrGDsGDsFDtEDtEDuDDvDDvCDwCDwBDxADxADy@Dz@Dz?D{?D{>D|=D|=D}@BDFFEEDCCBBAA@??>>= = < ; ; : : 9 8 877665443322100//..-,,++**)((''&& %!$!$"#"##"#"$!% % &&''())**++,--..//011223345566778 9 9 : : ; ; < ==>>??@AABBCCDEEFFFFFFFFFFFFFFFFFF F F F F F F F F FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF F F!F"F"F#F#F$F$F%F&F&F'F'F(F(F)F*F*F+F+F,F,F-F.F.F/F/F0F0F1F2F2F3F3F4F4F5F6F6F7F7F8F8F9~F:~F:}F;}F;|F<|F<{F=zF>zF>yF?yF?xF@xF@wFAvFBvFBuFCuFCtFDtFDsFErFFrFFqFGqFGpFHpFHoFInFJnFJmFKmFKlFLlFLkFMjFNjFNiFOiFOhFPhFPgFQfFRfFReFSeFSdFTdFTcFUbFVbFVaFWaFW`FX`FX_FY^FZ^FZ]F[]F[\F\\F\[F]ZF^ZF^YF_YF_XF`XF`WFaVFbVFbUFcUFcTFdTFdSFeRFfRFfQFgQFgPFhOFhOFiNFjNFjMFkMFkLFlKFlKFmJFnJFnIFoIFoHFpGFpGFqFFrFFrEFsEFsDFtCFtCFuBFvBFvAFwAFw@Fx?Fy?Fy>Fz>Fz=F{=F{<97420-+)&$"              " # % ' ( *,./13568:<>@BDFHHGFFEEDDCBBAA@@? > > = = < < ; : :99887665544322110//..--,++**))( ' '!&!&"%"%#$$#$#%"%"&!&!' (())**+,,--.//001123344556778899: ; ; < < = = > ??@@AABCCDDEFFGGHHHHHHHHHHHHHHHHHH H H H H H H H HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH H!H!H"H"H#H#H$H%H%H&H&H'H'H(H)H)H*H*H+H+H,H-H-H.H.H/H0H0H1H1H2H2H3H4H4H5H5H6H6H7~H8~H8}H9}H9|H:|H:{H;zHxH>wH?vH@vH@uHAuHAtHBtHBsHCrHDrHDqHEqHEpHFoHGoHGnHHnHHmHImHIlHJkHKkHKjHLjHLiHMiHMhHNgHOgHOfHPfHPeHQeHQdHRcHScHSbHTbHTaHUaHU`HV_HW_HW^HX^HX]HY]HY\HZ[H[[H[ZH\ZH\YH]XH^XH^WH_WH_VH`VH`UHaTHbTHbSHcSHcRHdRHdQHePHfPHfOHgOHgNHhNHhMHiLHjLHjKHkKHkJHlJHlIHmHHnHHnGHoGHoFHpFHpEHqDHrDHrCHsCHsBHtAHuAHu@Hv@Hv?Hw?Hw>Hx=Hy=Hy@BDFHJJIHHGGFFEDDCCBBA @ @ ? ? > > = < <;;:998877655443321100/..--,,+** ) )!(!("'#&#&$%$%%$%$&#'"'"(!(!) **++,,-..//00122334456677899::;;< = = > > ? ? @ AABBCDDEEFFGHHIIJJJJJJJJJJJJJJJJJ J J J J J J J J JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ J J!J!J"J#J#J$J$J%J%J&J'J'J(J(J)J)J*J+J+J,J,J-J-J.J/J/J0J0J1J2J2J3J3J4J4J5~J6~J6}J7}J7|J8|J8{J9zJ:zJ:yJ;yJ;xJvJ>uJ?uJ?tJ@sJAsJArJBrJBqJCqJCpJDoJEoJEnJFnJFmJGmJGlJHkJIkJIjJJjJJiJKhJLhJLgJMgJMfJNfJNeJOdJPdJPcJQcJQbJRbJRaJS`JT`JT_JU_JU^JV^JW]JW\JX\JX[JY[JYZJZYJ[YJ[XJ\XJ\WJ]WJ]VJ^UJ_UJ_TJ`TJ`SJaSJaRJbQJcQJcPJdPJdOJeNJfNJfMJgMJgLJhLJhKJiJJjJJjIJkIJkHJlHJlGJmFJnFJnEJoEJoDJpDJpCJqBJrBJrAJsAJs@Jt?Ju?Ju>Jv>Jv=Jw=Jw@BDFHJLLKKJIIHHGFFEEDDC B B A A @ ? ? > >==<;;::99877665443322100//.--,, + +!*")")#(#($'$'%&&%&%'$'$(#)")"*!*!+ + ,--../001122344556678899:;;<<==> ? ? @ @ A A B CCDDEFFGGHHIJJKKLLLLLLLLLLLLLLLLL L L L L L L L L LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL L L!L"L"L#L#L$L$L%L&L&L'L'L(L)L)L*L*L+L+L,L-L-L.L.L/L0L0L1L1L2L2L3~L4~L4}L5}L5|L6|L6{L7zL8zL8yL9yL9xL:wL;wL;vLsL?sL?rL@rL@qLApLApLBoLCoLCnLDnLDmLElLFlLFkLGkLGjLHjLHiLIhLJhLJgLKgLKfLLeLMeLMdLNdLNcLOcLObLPaLQaLQ`LR`LR_LS_LS^LT]LU]LU\LV\LV[LWZLXZLXYLYYLYXLZXLZWL[VL\VL\UL]UL]TL^SL_SL_RL`RL`QLaQLaPLbOLcOLcNLdNLdMLeMLeLLfKLgKLgJLhJLhILiHLjHLjGLkGLkFLlFLlELmDLnDLnCLoCLoBLpALpALq@Lr@Lr?Ls?Ls>Lt=Lu=Lu@BDFHJLNNMMLKKJJIHHGGFFE D D C C B A A @ @??>==<<;::99887665543322110//.. -!,!,"+"+#*#*$)%(%(&'&''&(%(%)$)$*#*#+",!,!- - .//00112334456677889::;;<==>>??@ A A B B C D D EEFFGHHIIJKKLLMMNNNNNNNNNNNNNNNNN N N N N N N N N NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN N!N!N"N"N#N$N$N%N%N&N&N'N(N(N)N)N*N+N+N,N,N-N-N.N/N/N0N0N1~N2~N2}N3}N3|N4|N4{N5zN6zN6yN7yN7xN8wN9wN9vN:vN:uN;uN;tNrN>qN?pN@pN@oNAoNAnNBnNBmNClNDlNDkNEkNEjNFiNGiNGhNHhNHgNIgNIfNJeNKeNKdNLdNLcNMbNNbNNaNOaNO`NP`NP_NQ^NR^NR]NS]NS\NT[NU[NUZNVZNVYNWYNWXNXWNYWNYVNZVNZUN[TN\TN\SN]SN]RN^RN^QN_PN`PN`ONaONaNNbMNcMNcLNdLNdKNeKNeJNfINgINgHNhHNhGNiFNiFNjENkENkDNlDNlCNmBNnBNnANoANo@Np?Np?Nq>Nr>Nr=Ns=Ns<97420-+)'$ "             " # % ' ( * , - / 13568:<>@BDFHJLNPPOONMMLLKJJIIHHG F F E E D C C B BAA@??>>=<<;;::9887765544322110 0 /!.!."-"-#,$+$+%*%*&)')'(('(')&*&*%+$+$,#,#-".!.!/ / 01122334556678899::;<<==>??@@ABB C C D D E F F GGHIIJJKKLMMNNOPPPPPPPPPPPPPPPPPP P P P P P P P PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP P P!P!P"P#P#P$P$P%P&P&P'P'P(P(P)P*P*P+P+P,P-P-P.P.P/~P/~P0}P1}P1|P2{P2{P3zP4zP4yP5yP5xP6wP7wP7vP8vP8uP9tP9tP:sP;sP;rPpP>oP?oP?nP@mP@mPAlPBlPBkPCkPCjPDiPEiPEhPFhPFgPGfPHfPHePIePIdPJcPJcPKbPLbPLaPMaPM`PN_PO_PO^PP^PP]PQ\PQ\PR[PS[PSZPTZPTYPUXPVXPVWPWWPWVPXUPXUPYTPZTPZSP[RP[RP\QP]QP]PP^PP^OP_NP`NP`MPaMPaLPbKPbKPcJPdJPdIPeIPeHPfGPgGPgFPhFPhEPiDPiDPjCPkCPkBPlBPlAPm@Pn@Pn?Po?Po>Pp=Pp=Pq;9642/-+(& $ "            " # % ' ( * , - / 1 3 568:<>@BDFHJLNPRRQQPOONNMMLKKJJI H H G G F E E D DCCBAA@@?>>==<;;::9987766544332 1 1!0!0"/#/#.$-$-%,&,&+'*'*())))(*'*'+&+&,%-%-$.#.#/"0"0!1 1 2334455677889::;;<==>>??@AABBCDD E E F G G H H IIJKKLLMNNOOPQQRRRRRRRRRRRRRRRRRR R R R R R R R RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR R R!R"R"R#R#R$R%R%R&R&R'R(R(R)R)R*R*R+R,R,R-~R-~R.}R/}R/|R0{R0{R1zR2zR2yR3yR3xR4wR4wR5vR6vR6uR7tR7tR8sR9sR9rR:qR:qR;pRmR>mR?lR@lR@kRAjRAjRBiRCiRChRDgRDgREfRFfRFeRGeRGdRHcRHcRIbRJbRJaRK`RK`RL_RM_RM^RN]RN]RO\RP\RP[RQ[RQZRRYRRYRSXRTXRTWRUVRUVRVURWURWTRXSRXSRYRRZRRZQR[QR[PR\OR\OR]NR^NR^MR_LR_LR`KRaKRaJRbIRbIRcHRdHRdGReGReFRfERfERgDRhDRhCRiBRiBRjARkARk@Rl?Rl?Rm>Rn>Rn=Ro=Ro@BDFHJLNPRTTSSRRQPPOONMMLLK J J I I H H G FFEEDCCBBA@@??>==<<;;:9988766554 3 3!2"2"1#0#0$/%/%.&.&-',(,(+)+)**)*)+(,(,'-&-&.%/%/$0#0#1"2"2!3!3 4556677899::;<<==>??@@ABBCCDDEFF G G H I I J J KLLMMNOOPPQQRSSTTTTTTTTTTTTTTTTTT T T T T T T T TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT T T!T!T"T"T#T$T$T%T%T&T'T'T(T(T)T*T*T+~T+~T,}T-}T-|T.{T.{T/zT/zT0yT1xT1xT2wT2wT3vT4vT4uT5tT5tT6sT7sT7rT8qT8qT9pT:pT:oT;nT;nTkT>kT?jT?jT@iTAiTAhTBgTBgTCfTDfTDeTEdTEdTFcTGcTGbTHaTHaTI`TI`TJ_TK^TK^TL]TL]TM\TN\TN[TOZTOZTPYTQYTQXTRWTRWTSVTTVTTUTUTTUTTVSTVSTWRTXQTXQTYPTYPTZOT[OT[NT\MT\MT]LT^LT^KT_JT_JT`ITaITaHTbGTbGTcFTcFTdETeDTeDTfCTfCTgBThBThATi@Ti@Tj?Tk?Tk>Tl=Tl=Tm@BDFHJLNPRTVVUUTTSRRQQPPONNM M L K K J J I HHGGFEEDDCBBAA@??>>==<;;::988776 5!5!4"4"3#2$2$1%1%0&/'/'.(.(-),),*++++*,),)-(.(.'/'/&0%1%1$2$2#3"4"4!5!5 677889::;;<<=>>??@AABBCDDEEFGGHH I J J K K L M MNNOOPQQRRSTTUUVVVVVVVVVVVVVVVVV V V V V V V V V VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV V V!V"V"V#V#V$V$V%V&V&V'V'V(V)~V)~V*}V*}V+|V,{V,{V-zV-zV.yV/xV/xV0wV0wV1vV2uV2uV3tV3tV4sV5sV5rV6qV6qV7pV7pV8oV9nV9nV:mV:mV;lViV?hV?hV@gV@gVAfVBeVBeVCdVCdVDcVEbVEbVFaVFaVG`VH`VH_VI^VI^VJ]VJ]VK\VL[VL[VMZVMZVNYVOXVOXVPWVPWVQVVRUVRUVSTVSTVTSVURVURVVQVVQVWPVXOVXOVYNVYNVZMV[MV[LV\KV\KV]JV]JV^IV_HV_HV`GV`GVaFVbEVbEVcDVcDVdCVeBVeBVfAVfAVg@Vh?Vh?Vi>Vi>Vj=Vk<97520. + ) ' $ "          "#%'( * , - / 1 3 5 6 8 :<>@BDFHIKNPRTVXXXWVVUUTSSRRQPPO O N M M L L K JJIIHGGFFEDDCCBAA@@??>==<<;::99 8 7!7!6"6#5#4$4$3%3&2&1'1'0(0(/).*.*-+-+,,+-+-*.*.)/(0(0'1'1&2%3%3$4$4#5"6"6!7!7 899::;<<==>??@@ABBCCDEEFFGHHIIJJ K L L M M N O OPPQRRSSTUUVVWXXYYYYYYYYYYYYYYYY Y Y Y Y Y Y Y Y YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY Y!Y!Y"Y"Y#Y$Y$Y%Y%Y&Y'~Y'~Y(}Y(}Y)|Y){Y*{Y+zY+zY,yY,xY-xY.wY.wY/vY/uY0uY1tY1tY2sY2rY3rY4qY4qY5pY5oY6oY7nY7nY8mY8mY9lY:kY:kY;jY;jYgY>gY?fY@eY@eYAdYAdYBcYCbYCbYDaYDaYE`YF_YF_YG^YG^YH]YI\YI\YJ[YJ[YKZYLYYLYYMXYMXYNWYNVYOVYPUYPUYQTYQSYRSYSRYSRYTQYTPYUPYVOYVOYWNYWMYXMYYLYYLYZKYZJY[JY\IY\IY]HY]HY^GY_FY_FY`EY`EYaDYbCYbCYcBYcBYdAYe@Ye@Yf?Yf?Yg>Yh=Yh=Yi;9642/ - + ( & $ "        "#%'(* , - / 1 3 5 6 8 : <>@BDFGIKNPRTVXZZZYYXWWVVUTTSSRQ Q P P O N N M MLKKJJIHHGGFEEDDCBBAA@??>>=<<;; : 9!9!8"8#7#6$6$5%5&4&3'3'2(2)1)0*0*/+/,.,----,.,/+/*0*0)1)2(2'3'3&4&5%5$6$6#7#8"8!9!9 : ;;<<=>>??@AABBCDDEEFGGHHIJJKKLM M N N O P P Q QRSSTTUVVWWXYYZZ[[[[[[[[[[[[[[[[ [ [ [ [ [ [ [ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [ [![!["[#[#[$[$~[%~[&}[&}['|['{[({[)z[)z[*y[*x[+x[,w[,w[-v[-u[.u[/t[/t[0s[0r[1r[2q[2q[3p[3o[4o[5n[5n[6m[6l[7l[8k[8k[9j[9i[:i[;h[;h[e[>e[?d[?c[@c[Ab[Ab[Ba[B`[C`[D_[D_[E^[E][F][G\[G\[H[[HZ[IZ[JY[JY[KX[KW[LW[MV[MV[NU[NT[OT[PS[PS[QR[QQ[RQ[SP[SP[TO[TN[UN[VM[VM[WL[WK[XK[YJ[YJ[ZI[ZH[[H[\G[\G[]F[]E[^E[_D[_D[`C[`B[aB[bA[bA[c@[c?[d?[e>[e>[f=[f<[g<[h;[h;[i:[i9[j9[k8[k8[l7[l6[m6[n5[n5[o4[o3[p3[p2[q2[r1[r0[s0[s/[t/[u.[u-[v-[v,[w,[x+[x*[y*[y)[z)[{([{'[|'[|&[}&[~%[~$[$[#[#["[![![ [ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [ [ [ [ [ [ [ [[[[[[[[[[[[[[[ZWTROLJGEB@=;8631 / , * ( & # !       "#%'(*, - / 1 3 5 6 8 : < >@BDFGIKMPRTVXZ\]\[[ZYYXXWVVUUTS S R R Q P P O ONMMLLKJJIIHGGFFEDDCCBAA@@?>>== < ;!;":":#9#8$8%7%7&6&5'5(4(4)3)2*2+1+1,0,/-/..../-/,0,1+1+2*3)3)4(4'5'6&6&7%7$8$9#9#:":!;!< < ==>??@@ABBCCDEEFFGHHIIJKKLLMNNO O P Q Q R R S TTUUVWWXXYZZ[[\]]]]]]]]]]]]]]]]] ] ] ] ] ] ] ] ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] ] ]!]"]"~]#~]#}]$}]%|]%{]&{]&z]'z](y](x])x])w]*w]+v]+u],u],t]-t].s].r]/r]/q]0q]1p]1o]2o]2n]3n]4m]4l]5l]5k]6k]7j]7i]8i]8h]9h]:g]:f];f];e]c]?b]?a]@a]@`]A`]B_]B^]C^]C]]D]]E\]E[]F[]FZ]GZ]HY]HX]IX]IW]JW]KV]KU]LU]LT]MT]NS]NR]OR]OQ]PQ]QP]QO]RO]RN]SN]TM]TL]UL]UK]VK]WJ]WI]XI]XH]YH]ZG]ZF][F][E]\E]]D]]C]^C]^B]_B]`A]`@]a@]a?]b?]c>]c=]d=]d<]e<]f;]f:]g:]g9]h9]i8]i7]j7]j6]k6]l5]l4]m4]m3]n3]o2]o1]p1]p0]q/]r/]r.]s.]t-]t,]u,]u+]v+]w*]w)]x)]x(]y(]z']z&]{&]{%]|%]}$]}#]~#]~"]"]!] ] ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] ] ] ] ] ] ] ] ]]]]]]]]]]]]]]]\YWTQOLIGDB?=:853 1 . , * ' % #       "#%'(*,- / 1 3 5 6 8 : < > @BDEGIKMPRTVXZ\^_^]]\\[ZZYYXWWVV U T T S S R Q QPPONNMMLKKJJIHHGFFEEDCCBBA@@?? >!=!="<"<#;$:$:%9%9&8'7'7(6(6)5*4*4+3+3,2-1-1.0////0.0.1-2,2,3+3+4*5)5)6(6(7'8&8&9%9%:$;#;#<"<"=!> > ??@AABBCDDEFFGGHIIJJKLLMMNOOPPQ R R S S T U U VVWXXYYZ[[\]]^^_________________ _ _ _ _ _ _ _ _______________________________ ~_!~_!}_"}_"|_#{_${_$z_%z_%y_&x_'x_'w_(w_(v_)u_*u_*t_+t_,s_,r_-r_-q_.p_/p_/o_0o_0n_1m_2m_2l_3l_3k_4j_5j_5i_6i_6h_7g_8g_8f_9f_9e_:d_;d_;c_a_>`_?`_?__@^_A^_A]_B]_C\_C[_D[_DZ_EY_FY_FX_GX_GW_HV_IV_IU_JU_JT_KS_LS_LR_MR_MQ_NP_OP_OO_PO_PN_QM_RM_RL_SL_SK_TJ_UJ_UI_VI_VH_WG_XG_XF_YF_ZE_ZD_[D_[C_\B_]B_]A_^A_^@__?_`?_`>_a>_a=_b<_c<_c;_d;_d:_e9_f9_f8_g8_g7_h6_i6_i5_j5_j4_k3_l3_l2_m2_m1_n0_o0_o/_p/_q._q-_r-_r,_s+_t+_t*_u*_u)_v(_w(_w'_x'_x&_y%_z%_z$_{$_{#_|"_}"_}!_~!_~ _______________________________ _ _ _ _ _ _ _ _______________^[YVSQNKIFDA?<:75 2 0 . + ) ' $ "      "#%'(*,-/ 1 3 5 6 8 : < > @ BDEGIKMPRTVXZ\^aa``_^^]]\[[ZZYXX W W V U U T T SRRQPPOONMMLLKJJIIHGGFFEDDCCBA A @!?!?">#>#=$<$<%;&;&:'9'9(8)8)7*6*6+5,5,4-3.3.2/1/100101/2.2.3-4-4,5+5+6*7*7)8(8(9':':&;%;%<$=#=#>"?"?!@ @ ABBCCDEEFFGHHIIJKKLMMNNOPPQQRSS T T U V V W W XYYZ[[\\]^^__`aaaaaaaaaaaaaaaaa a a a a a a a a aaaaaaaaaaaaaaaaaaaaaaaaaaa~a~a}a }a |a!{a!{a"za#za#ya$xa$xa%wa&va&va'ua(ua(ta)sa)sa*ra+ra+qa,pa,pa-oa.oa.na/ma/ma0la1la1ka2ja2ja3ia4ha4ha5ga6ga6fa7ea7ea8da9da9ca:ba:ba;aa^a?^a?]a@\a@\aA[aB[aBZaCYaCYaDXaEWaEWaFVaGVaGUaHTaHTaISaJSaJRaKQaKQaLPaMPaMOaNNaNNaOMaPMaPLaQKaQKaRJaSIaSIaTHaUHaUGaVFaVFaWEaXEaXDaYCaYCaZBa[Ba[Aa\@a\@a]?a^?a^>a_=a_=a`;97 4 2 / - + ( & $ "     "#%'(*,-/1 3 5 6 8 : < > @ B DEGIKMPRTVXZ\^acccbaa`__^^]\\[[Z Y Y X X W V V UTTSSRQQPPONNMMLKKJIIHHGFFEEDC C B!B"A"@#@#?$>%>%=&=&<';(;(:):)9*8+8+7,7-6-5.5.4/30302121120303/4/4.5-6-6,7,8+8*9*9):(;(;'<'<&=%>%>$?$?#@"A"A!B!C CDDEFFGGHIIJJKLLMNNOOPQQRRSTTUU V W W X Y Y Z Z[\\]]^__``abbcdddddddddddddddd d d d d d d d dddddddddddddddddddddddd~d~d}d}d|d{d{d zd zd!yd"xd"xd#wd$vd$vd%ud%ud&td'sd'sd(rd(rd)qd*pd*pd+od+od,nd-md-md.ld/kd/kd0jd0jd1id2hd2hd3gd3gd4fd5ed5ed6dd6dd7cd8bd8bd9ad:`d:`d;_d;_d<^d=]d=]d>\d>\d?[d@Zd@ZdAYdAYdBXdCWdCWdDVdEUdEUdFTdFTdGSdHRdHRdIQdIQdJPdKOdKOdLNdLNdMMdNLdNLdOKdPJdPJdQIdQIdRHdSGdSGdTFdTFdUEdVDdVDdWCdWCdXBdYAdYAdZ@d[?d[?d\>d\>d]=d^ @ B D EGIKMORTVXZ\^aceeeddcbba``__^]]\ \ [ Z Z Y Y X WWVUUTTSRRQQPOONMMLLKJJIIHGGFE E D!D"C"B#B$A$A%@%?&?'>'=(=(<)<*;*:+:+9,9-8-7.7/6/60504142322323141505/6/7.7.8-8,9,:+:*;*;)<)=(='>'?&?&@%@$A$B#B"C"C!D!E EFGGHHIJJKKLMMNNOPPQRRSSTUUVVWX X Y Z Z [ [ \ ]]^^_``abbccdeeffffffffffffffff f f f f f f f ffffffffffffffffffff~f~f}f}f|f{f{fzfyfyfxf xf!wf!vf"vf#uf#uf$tf$sf%sf&rf&qf'qf'pf(pf)of)nf*nf+mf+mf,lf,kf-kf.jf.jf/if/hf0hf1gf1ff2ff2ef3ef4df4cf5cf6bf6bf7af7`f8`f9_f9^f:^f:]f;]f<\f<[f=[f>Zf>Zf?Yf?Xf@XfAWfAVfBVfBUfCUfDTfDSfESfFRfFRfGQfGPfHPfIOfINfJNfJMfKMfLLfLKfMKfNJfNJfOIfOHfPHfQGfQGfRFfREfSEfTDfTCfUCfUBfVBfWAfW@fX@fY?fY?fZ>fZ=f[=f\ @ B C E GIKMORTVXZ\^aceghgffeedccbba``_ ^ ^ ] ] \ [ [ Z YYXXWVVUUTSSRQQPPONNMMLKKJIIHH G!F!F"E"E#D$C$C%B&A&A'@'@(?)>)>*=*<+<,;,;-:.9.9/8/8071616252434434352616170708/9.9.:-;,;,<+<+=*>)>)?(?(@'A&A&B%C$C$D#D#E"F!F!G GHIIJKKLLMNNOOPQQRSSTTUVVWXXYYZ [ [ \ \ ] ^ ^ _``aabccddeffghhhhhhhhhhhhhhhhh h h h h h h h hhhhhhhhhhhhhhhh~h~h}h}h|h{h{hzhyhyhxhxhwhvh vh uh!uh"th"sh#sh#rh$qh%qh%ph&ph&oh'nh(nh(mh)lh*lh*kh+kh+jh,ih-ih-hh.hh.gh/fh0fh0eh1dh2dh2ch3ch3bh4ah5ah5`h6`h7_h7^h8^h8]h9\h:\h:[h;[h;ZhXh?Wh?Vh@Vh@UhAThBThBShCShCRhDQhEQhEPhFOhGOhGNhHNhHMhILhJLhJKhKKhKJhLIhMIhMHhNGhOGhOFhPFhPEhQDhRDhRChSChTBhTAhUAhU@hV?hW?hW>hX>hX=hY @ B C E G IKMORTVXZ\^acegjjiihhgffeddccba a ` _ _ ^ ^ ] \\[ZZYYXWWVVUTTSRRQQPOONMMLLKJ J I!I!H"G#G#F$E$E%D&D&C'B(B(A)@)@*?+?+>,=-=-<.;.;/:0:091818273736455554636372828190:0:/;.;.<-=-=,>+?+?*@*@)A(B(B'C&C&D%E%E$F#G#G"H!H!I J JKLLMMNOOPPQRRSTTUUVWWXYYZZ[\\ ] ^ ^ _ _ ` a abbcddeffgghiijjjjjjjjjjjjjjjjj j j j j j j j jjjjjjjjjjjj~j~j}j}j|j{j{jzjyjyjxjxjwjvjvjujtjtj sj!sj!rj"qj"qj#pj$oj$oj%nj%nj&mj'lj'lj(kj)kj)jj*ij*ij+hj,gj,gj-fj.fj.ej/dj/dj0cj1bj1bj2aj2aj3`j4_j4_j5^j6^j6]j7\j7\j8[j9Zj9Zj:Yj;Yj;XjUj>Uj?Tj@Tj@SjARjARjBQjCPjCPjDOjDOjENjFMjFMjGLjHLjHKjIJjIJjJIjKHjKHjLGjMGjMFjNEjNEjODjPCjPCjQBjRBjRAjS@jS@jT?jU?jU>jV=jV=jW < 9 7 4 2 0 - + (&$"     !#%&(*,-/13468: < > @ B C E G I K MORTVXZ\^`cegjlllkjjiihggfeedd c b b a ` ` _ _^]]\[[ZZYXXWWVUUTSSRRQPPONNMM L K!K"J"I#I#H$H%G%F&F'E'D(D(C)C*B*A+A,@,?-?->.>/=/<0<0;1:2:293948475756657574849392:2:1;1<0.>-?-?,@,A+A*B*C)C(D(D'E'F&F%G%H$H#I#I"J"K!K L MMNNOPPQRRSSTUUVVWXXYZZ[[\]]^_ _ ` ` a b b c ddeefgghiijjkllmmmmmmmmmmmmmmmm m m m m m m m mmmmmmmm~m~m}m}m|m{m{mzmymymxmxmwmvmvmumtmtmsmsmrm qm qm!pm!om"om#nm#nm$mm$lm%lm&km&jm'jm(im(im)hm)gm*gm+fm+em,em-dm-dm.cm.bm/bm0am0`m1`m2_m2_m3^m3]m4]m5\m5[m6[m7Zm7Zm8Ym8Xm9Xm:Wm:Vm;VmSm?Rm?Rm@QmAPmAPmBOmBNmCNmDMmDMmELmFKmFKmGJmGImHImIHmIHmJGmJFmKFmLEmLDmMDmNCmNCmOBmOAmPAmQ@mQ?mR?mS>mS>mT=mT ; 9 6 4 1 / - *(&#!     !#%&(*,-/13468:< > @ B C E G I K M ORTVXZ\^`cegilnonmmllkjjihhggf e e d c c b b a``_^^]]\[[ZYYXXWVVUTTSRRQQPOO N M!M"L"L#K$J$J%I%H&H'G'G(F)E)E*D*C+C,B,B-A.@.@/?/>0>1=1=2<3;3;4:495968687786869594:4;3;3<2=1=1>0?/?/@.@.A-B,B,C+D*D*E)E)F(G'G'H&I%I%J$J$K#L"L"M!N N OOPQQRSSTTUVVWXXYYZ[[\]]^^_``a b b c c d e e fgghhijjkllmmnoooooooooooooooo o o o o o o o ooooo~o~o}o|o|o{o{ozoyoyoxowowovovouototosororoqoqopooo oo no!mo"mo"lo#lo#ko$jo%jo%io&ho'ho'go(go(fo)eo*eo*do+co,co,bo-bo.ao.`o/`o/_o0^o1^o1]o2]o3\o3[o4[o4Zo5Yo6Yo6Xo7Xo8Wo8Vo9Vo9Uo:To;To;SoQo>Po?Oo@Oo@NoANoBMoBLoCLoCKoDJoEJoEIoFIoGHoGGoHGoHFoIEoJEoJDoKDoLCoLBoMBoMAoN@oO@oO?oP?oQ>oQ=oR=oR @ B C E G I K M O QTVXZ\^`cegilnpqppoonmmlkkjiih h g f f e d d ccbaa`__^^]\\[ZZYYXWWVUUTSSRRQ P!P!O"N"N#M$M$L%K&K&J'I(I(H)H)G*F+F+E,D-D-C.B.B/A0A0@1?2?2>3=3=4<5<5;6:7:79889897:7:6;5<5<4=3>3>2?1?1@0A0A/B.C.C-D,D,E+F+F*G)H)H(I'J'J&K&K%L$M$M#N"O"O!P P QRRSTTUUVWWXYYZ[[\\]^^_``aabcc d e e f f g h hijjkklmmnoopqqqqqqqqqqqqqqqqq q q q q q q q q~q~q}q|q|q{q{qzqyqyqxqwqwqvqvquqtqtqsqrqrqqqqqpqoqoqnqmqmq lq!kq!kq"jq"jq#iq$hq$hq%gq&fq&fq'eq(eq(dq)cq)cq*bq+aq+aq,`q-`q-_q.^q.^q/]q0\q0\q1[q2[q2Zq3Yq3Yq4Xq5Wq5Wq6Vq7Uq7Uq8Tq8Tq9Sq:Rq:Rq;QqOq>Nq?Mq?Mq@LqAKqAKqBJqCJqCIqDHqDHqEGqFFqFFqGEqHDqHDqICqICqJBqKAqKAqL@qM?qM?qN>qO>qO=qP@ B C E G I K M O Q TVXZ\^`cegilnpsssrrqpponnmllkk j i i h g g f feddcbba``__^]]\[[ZZYXXWVVUTTS S!R!Q"Q#P#O$O%N%M&M&L'L(K(J)J*I*H+H,G,G-F-E.E/D/C0C1B1A2A2@3@4?4>5>6=6<7<8;8;9:99:9;8;7<7=6=5>5>4?4@3@2A2B1B0C0D/D/E.E-F-G,G+H+I*I)J)K(K(L'L&M&N%N$O$P#P"Q"Q!R!S STUUVWWXXYZZ[\\]]^__`aabccddef f g h h i i j kklmmnooppqrrstttttttttttttttt t t t t ~t ~t }t |t|t{t{tztytytxtwtwtvtvtutttttstrtrtqtptptototntmtmtltktkt jt it!it!ht"ht#gt#ft$ft%et%dt&dt'ct'ct(bt(at)at*`t*_t+_t,^t,]t-]t-\t.\t/[t/Zt0Zt1Yt1Xt2Xt3Wt3Wt4Vt4Ut5Ut6Tt6St7St8Rt8Qt9Qt9Pt:Pt;Ot;NtLt?Kt?Kt@Jt@ItAItBHtBGtCGtDFtDEtEEtFDtFDtGCtGBtHBtIAtI@tJ@tK?tK>tL>tL=tM=tN < 9 7 4 2 0-+)&$"      !#%&(*,-/13468:<>@A C E G I K M O Q T VXZ\^`cegilnpsuvuutssrqqpponnm l l k j j i i hggfeedccbba``_^^]\\[[ZYYXWWV U U!T"T"S#R#R$Q%P%P&O'N'N(M)M)L*K*K+J,I,I-H.G.G/F0F0E1D1D2C3B3B4A5@5@6?7?7>8=8=9<:;:;;:<9<9=8>8>7?6?6@5A4A4B3C2C2D1E1E0F/F/G.H-H-I,J+J+K*L*L)M(M(N'O&O&P%Q%Q$R#S#S"T!T!U VVWXXYYZ[[\]]^__``abbcddeffggh i i j k k l m mnnoppqrrsttuuvvvvvvvvvvvvvvvv ~v ~v }v |v |v {v {v zvyvyvxvwvwvvvuvuvtvtvsvrvrvqvpvpvovnvnvmvmvlvkvkvjvivivhv gv gv!fv"fv"ev#dv$dv$cv%bv&bv&av'`v'`v(_v)_v)^v*]v+]v+\v,[v,[v-Zv.Yv.Yv/Xv0Xv0Wv1Vv2Vv2Uv3Tv3Tv4Sv5Sv5Rv6Qv7Qv7Pv8Ov9Ov9Nv:Mv:Mv;LvJv>Iv?Hv@Hv@GvAFvAFvBEvCEvCDvDCvECvEBvFAvGAvG@vH?vH?vI>vJ>vJ=vK ; 9 6 4 1/-*(&#!      !#%&(*,-/13468:<>@ACE G I K M O Q T V XZ\^`cegilnpsuxxxwvvuttssrqqpo o n m m l l k jjihhgffeedccbaa`__^]]\\[ZZYX X W!V"V"U#U$T$S%S&R&Q'Q'P(O)O)N*N+M+L,L-K-J.J/I/H0H0G1F2F2E3E4D4C5C6B6A7A7@8?9?9>:>;=;<<<=;=:>:>9?8@8@7A7B6B5C5D4D3E3F2F1G1G0H/I/I.J.K-K,L,M+M*N*N)O(P(P'Q'R&R%S%T$T#U#U"V!W!W X YYZ[[\]]^^_``abbcddeefgghiijk k l l m n n o ppqrrsttuuvwwxyyyyyyyyyyyy~y~y}y|y |y {y {y zy yy yy xy wywyvyuyuytytysyryryqypypyoynynymylylykykyjyiyiyhygygyfyey ey!dy!dy"cy#by#by$ay$`y%`y&_y&^y'^y(]y(]y)\y*[y*[y+Zy,Yy,Yy-Xy-Wy.Wy/Vy/Uy0Uy1Ty1Ty2Sy3Ry3Ry4Qy4Py5Py6Oy6Ny7Ny8My8My9Ly:Ky:Ky;Jy;IyGy?Fy?Fy@EyADyADyBCyCByCByDAyD@yE@yF?yF>yG>yH=yH=yI@ACEG I K M O Q T V X Z\^`cegilnpsuxz{zyyxxwvvuttsrr q q p o o n m mlkkjiihhgffeddcbba``__^]]\[[ Z!Y!Y"X#W#W$V$V%U&T&T'S(R(R)Q*P*P+O,N,N-M-M.L/K/K0J1I1I2H3G3G4F5E5E6D6D7C8B8B9A:@:@;?<><>==><>E{>D{?C{@C{@B{AA{BA{B@{C?{D?{D>{E>{E={F<{G<{G;{H:{I:{I9{J8{K8{K7{L6{M6{M5{N5{N4{O3{P3{P2{Q1{R1{R0{S/{T/{T.{U-{V-{V,{W,{W+{X*{Y*{Y){Z({[({['{\&{]&{]%{^${_${_#{`#{`"{a!{b!{b {c{d{d{e{f{f{g{h{h{i{i{j{k{k{l{m{m{n{o{o{p{q{q{r{r{s{t{t{u {v {v {w {x {x {y {y {z{{{{{|{}{}{~{{{{{{{zwtqnkheb_\ZWTQO L I G D B ? = : 8530.,)'%"        !#%&(*,-/13468:<>@ACEGI K M O Q T V X Z \^`cegilnpsuxz}}}|{{zyyxwwvvut t s r r q p p onnmllkkjiihggfeedccbba``_^^] \!\!["Z#Z#Y$X%X%W&W'V'U(U)T)S*S*R+Q,Q,P-O.O.N/N0M0L1L2K2J3J3I4H5H5G6F7F7E8D9D9C:C;B;A?>>?=@=@B~>B~?A~?@~@@~A?~A>~B>~C=~C=~D<~E;~E;~F:~G9~G9~H8~H7~I7~J6~J5~K5~L4~L3~M3~N2~N2~O1~P0~P0~Q/~R.~R.~S-~S,~T,~U+~U*~V*~W)~W)~X(~Y'~Y'~Z&~[%~[%~\$~]#~]#~^"~^!~_!~` ~`~a~b~b~c~d~d~e~f~f~g~g~h~i~i~j~k~k~l~m~m~n~o~o~p~q~q~r~r ~s ~t ~t ~u ~v ~v ~w ~x~x~y~z~z~{~{~|~}~}~~~~~|yvspmjgda_\YVSQ N K I F D A > < 97520-+)&$"       !#%&(*,-/13468:<>@ACEGIK M O Q S V X Z \ ^`cegilnpsuxz}~~~~~~}~}~|~{~{~z~y~y~x~w~w ~v ~u ~u ~t ~s ~s ~r ~r~q~p~p~o~n~n~m~l~l~k~j~j~i~h~h~g~f~f~e~e~d~c~c~b~a~a~` ~_ ~_!~^"~]"~]#~\$~[$~[%~Z%~Z&~Y'~X'~X(~W)~V)~V*~U+~T+~T,~S-~R-~R.~Q/~P/~P0~O1~N1~N2~M2~M3~L4~K4~K5~J6~I6~I7~H8~G8~G9~F:~E:~E;~D<~C<~C=~B=~B>~A?~@?~@@~?A~>A~>B~=C~????>@=A=A ;9642/-*(&#!       !#%&(*,-/13468:<>@ACEGIKM O Q S V X Z \ ^ `cegilnpsuxz}~|{{{{{{~{~{}{|{|{{{{{z{y {y {x {w {w {v {u {u{t{s{s{r{q{q{p{o{o{n{m{m{l{l{k{j{j{i{h{h{g{f{f{e{d{d{c{b {b {a!{`"{`"{_#{^${^${]%{]&{\&{['{[({Z({Y){Y*{X*{W+{W,{V,{U-{U-{T.{S/{S/{R0{Q1{Q1{P2{O3{O3{N4{N5{M5{L6{L7{K7{J8{J9{I9{H:{H;{G;{F<{F<{E={D>{D>{C?{B@{B@{AA{@B{@B{?C{?D{>D{=E{=F{=>>=>@ACEGIKMO Q S V X Z \ ^ ` cegilnpsuxz}}|zyyyyyyyyyy~y~y}y|y| y{ yz yz yy yx yx ywyvyvyuyuytysysyryqyqypyoyoynymymylykykyjyiyiyhygygyfyeye yd!yc!yc"yb#yb#ya$y`%y`%y_&y^'y^'y](y\(y\)y[*yZ*yZ+yY,yX,yX-yW.yV.yV/yU0yT0yT1yS2yR2yR3yQ4yP4yP5yO6yO6yN7yM8yM8yL9yK:yK:yJ;yI;yIyF?yE?yE@yDAyCAyCByBCyACyADy@Ey?Ey?Fy>Gy=Gy=Hy;=;=<<=;=;>:?:?9@8A8A7B6C6C5D4E4E3F2G2G1H0I0I/J.K.K-L,L,M+N*N*O)P(P(Q'R'R&S%T%T$U#V#V"W!X!X YZZ[\\]^^__`aabccdeefgghiijkk l m m n o o pqqrrsttuvvwxxz|}zwtqnkheb`]ZW T R O L J G D B ?=:8530.,)'%"        !#%&(*,-/13468:<>@ACEGIKMOQ S V X Z \ ^ ` c egilnpsuxz|}{ywvvvvvvvvvvvvvv~ v~ v} v| v| v{ vz vzvyvxvxvwvvvvvuvtvtvsvrvrvqvpvpvovnvnvmvmvlvkvkvjvivivhvg vg!vf!ve"ve#vd#vc$vc%vb%va&va'v`'v_(v_)v^)v]*v]+v\+v[,v[-vZ-vY.vY/vX/vW0vW1vV1vU2vU3vT3vS4vS5vR5vQ6vQ7vP7vP8vO9vN9vN:vM:vL;vLvI>vH?vH@vG@vFAvFBvEBvDCvDDvCDvBEvBFvAFv@Gv@Hv?Hv>Iv>Jv=Jv8>9=9<:<:;;:<:<9=9>8>7?7@6@5A5B4B3C3D2D1E1F0F/G/H.H-I-J,J+K+L*L)M)N(N'O'P&P%Q%R$R#S#T"T!U!V VWWXYYZ[[\]]^__`aabccdeefgghi i j k k l m mnoopqqrrsttuvwz|}zwtpmkheb_\Y W T Q N L I F D A?<:7520-+)&$"        !#%&(*+-/13468:<>?ACEGIKMOQSV X Z \ ^ ` c e g ilnpsuxz|~|zxvttttttttttttttt t t t t~ t~ t} t|t|t{tztztytxtxtwtvtvtutttttstrtrtqtptptotntntmtltltktj tj ti!th"th"tg#tf$tf$te%td&td&tc'tb(tb(ta)t`*t`*t_+t^,t^,t]-t\.t\.t[/tZ0tZ0tY1tX2tX2tW3tV4tV4tU5tT5tT6tS7tS7tR8tQ9tQ9tP:tO;tO;tNtK?tK?tJ@tIAtIAtHBtGCtGCtFDtEEtEEtDFtCGtCGtBHtAItAIt@Jt?Kt?Kt>Lt=Mt=Mt6=6=7<8;8;9::9:9;8<7<7=6>5>5?4@4@3A2A2B1C0C0D/E.E.F-G,G,H+I*I*J)K(K(L'M&M&N%O$O$P#Q"Q"R!S S TUUVWWXYYZ[[\]]^__`aabccdeef g g h i i j kklmmnoopqqrssuwz||yvspmjgda^[ Y V S P N K H F CA><9742/-+(&$!         !#%&(*+-/13468:<>?ACEGIKMOQSVX Z \ ^ ` c e g i lnpsuxz|}{zxvtrqqqqqqqqqqqqqq q q q q q q qq~q}q}q|q{q{qzqyqyqxqwqwqvququqtqsqsqrqrqqqpqpqoqnqnqm ql ql!qk"qj"qj#qi$qh$qh%qg&qf&qf'qe(qd(qd)qc*qb*qb+qa,q`,q`-q_.q^.q^/q]0q\0q\1q[2qZ2qZ3qY4qX4qX5qW6qV6qV7qU8qT8qT9qS:qR:qR;qQqN>qN?qM@qL@qLAqKBqJBqJCqIDqHDqHEqGFqFFqFGqEHqDHqDIqCJqBJqBKqALq@Lq@Mq?Nq>Nq>Oq=Pq3>3=4<5<5;6:7:79889897:6;6;5<4=4=3>2?2?1@0A0A/B.C.C-D,E,E+F*G*G)H(I(I'J&K&K%L$M$M#N"O"O!P Q QRSSTUUVWWXYYZ[[\]]^__`aabcc d e e f g g hiijkklmmnoopqruwz|{xurolifca ^ [ X U S P M J H EC@=;8641/,*(%#!         !#%&(*+-/13468:<>?ACEGIKMOQSVXZ \ ^ ` c e g i l npsuxz|}{ywusqonnnnnnnnnnnnn n n n n n n n nnnnnn~n}n}n|n{n{nznynynxnwnwnvnununtnsnsnrnqnqnpno no!nn!nm"nm#nl#nk$nk%nj%ni&ni'nh'ng(ng)nf)ne*ne+nd+nc,nc-nb-na.na/n`/n_0n_1n^1n]2n]3n\3n[4n[5nZ5nY6nY7nX7nW8nW9nV9nU:nU;nT;nSnQ?nP?nO@nOAnNAnMBnMCnLCnKDnKEnJEnIFnIGnHGnGHnGInFInEJnEKnDKnCLnCMnBMnANnAOn@On?Pn>Qn>Qn=Rn0=1=2<2;3;4:4959686777868595:4:3;3<2<1=1>0>/?/@.@-A-B,B+C+D*D)E)F(F'G'H&H%I%J$J#K#L"L!M!N NOPPQRRSTTUVVWXXYZZ[\\]^^_`` a b b c d d e ffghhijjklmmnoruwz|~{xurolifc ` ] Z W U R O M JGEB?=:8531.,)'%"       !!   !#%&(*+-/13468:<>?ACEGIKMOQSVXZ\ ^ ` c e g i l n psuxz~||zxvtrpolkkkkkkkkkkkkk k k k k k k k kkkkkkkkkk~k}k}k|k{k{kzkykykxkwkwkvkukuktkskskr kq!kq!kp"ko#ko#kn$km%km&kl&kk'kj(kj(ki)kh*kh*kg+kf,kf,ke-kd.kd.kc/kb0kb0ka1k`2k`2k_3k^4k^4k]5k\6k\6k[7kZ8kZ8kY9kX:kX:kW;kVkT>kS?kR@kR@kQAkPBkPBkOCkNDkNDkMEkLFkLFkKGkJHkJIkIIkHJkHKkGKkFLkEMkEMkDNkCOkCOkBPkAQkAQk@Rk?Sk?Sk>Tk=Uk=Uk->.=/-?,?,@+A*A*B)C(C(D'E&E&F%G$G#H#I"I!J!K LLMNNOPPQRRSTTUVVWXXYZZ[\\]^ ^ _ ` ` a b b cddeffghhijjkmoruwz|}zwtqnkhe b _ \ Z W T Q O LIGDA?<:7520.+)&$"       !!!    !#%&(*+-/13468:<>?ACEGIKMOQSUXZ\^ ` c e g i l n p suwz}|{zxvtrpnljiiiiiiiiiiiii i i i i i i i iiiiiiiiiiiiii~i}i}i|i{i{iziyiyixiwiviviu it it!is"ir"ir#iq$ip$ip%io&in&in'im(il(il)ik*ij*ij+ii,ih,ih-ig.if/if/ie0id1id1ic2ib3ib3ia4i`5i_5i_6i^7i]7i]8i\9i[9i[:iZ;iY;iYiV?iU?iU@iTAiSAiSBiRCiQCiQDiPEiOFiOFiNGiMHiMHiLIiKJiKJiJKiILiHLiHMiGNiFNiFOiEPiDPiDQiCRiBRiBSiATi@Ti@Ui?Vi>Vi>Wi=Xi+=,=,<-;.;.:/909081727263545445363627181809/:/:.;-<,<,=+>*>*?)@(@(A'B&C&C%D$E$E#F"G"G!H I IJKKLMMNOOPQQRSSTUUVWWXYZZ[ \ \ ] ^ ^ _ ` `abbcddeffghhjmoruwz|}zvspmjg d b _ \ Y V S Q NKIFCA><9742/-+(&$!      ""!!    !#%&(*+-/12468:<>?ACEGIKMOQSUXZ\^` b e g i l n p s uw~z}|{ywusqomkigfffffffffffff f f f f f f f ffffffffffffffffff~f}f|f|f{fzfzfyfxfx fw fv!fv"fu#ft#ft$fs%fr%fr&fq'fp'fp(fo)fn)fn*fm+fl+fk,fk-fj-fi.fi/fh/fg0fg1ff1fe2fe3fd4fc4fc5fb6fa6fa7f`8f_8f_9f^:f]:f];f\fY>fX?fX@fW@fVAfVBfUBfTCfTDfSEfREfRFfQGfPGfPHfOIfNIfNJfMKfLKfLLfKMfJMfINfIOfHOfGPfGQfFQfERfESfDSfCTfCUfBVfAVfAWf@Xf?Xf?Yf>Zf=Zf=[f<\f;\f;]f:^f9^f8_f8`f7`f6af6bf5bf4cf4df3df2ef2ff1gf0gf0hf/if.if.jf-kf,kf,lf+mf*mf*nf)of(of'pf'qf&qf%rf%sf$sf#tf#uf"uf!vf!wf xfxfyfzfzf{f|f|f}f~f~ffffffffffffffffff f f f f f f fffffffffffffffeddcbba``_^^] \ \ [ Z Z Y XXWVVUTSSRQQPOONMMLKKJIIHGG F E!E"D"C#B$B$A%@&@&?'>(>(=)<*<*;+:,:-9-8.8/7/60615142433324151506/7/7.8-9-9,:+;+;*<)=)>(>'?'@&@%A%B$B#C#D"D!E F FGHHIJJKLLMNOOPQQRSSTUUVWWX Y Y Z [ [ \ ] ]^_``abbcddefgjmoruwz||yvspmj g d a ^ [ X V S PMKHEC@>;9641/,*(%#!      """!!!   !#%&(*+-/12468:<>?ACEGIKMOQSUXZ\^`b e g i l n p s u w~z||zxvtrpomjhfdccccccccccccc c c c c c c c ccccccccccccccccccccc~c~c}c|c|c{cz cz!cy!cx"cx#cw#cv$cv%cu%ct&ct'cs'cr(cq)cq*cp*co+co,cn,cm-cm.cl.ck/ck0cj0ci1ci2ch2cg3cg4cf4ce5cd6cd7cc7cb8cb9ca9c`:c`;c_;c^c\?c[?cZ@cZAcYAcXBcWCcWDcVDcUEcUFcTFcSGcSHcRHcQIcQJcPJcOKcOLcNLcMMcMNcLNcKOcKPcJQcIQcHRcHScGScFTcFUcEUcDVcDWcCWcBXcBYcAYc@Zc@[c?[c>\c>]c=]c<^c;_c;`c:`c9ac9bc8bc7cc7dc6dc5ec5fc4fc3gc3hc2hc1ic1jc0jc/kc.lc.mc-mc,nc,oc+oc*pc*qc)qc(rc(sc'sc&tc&uc%uc$vc$wc#wc"xc!yc!zc zc{c|c|c}c~c~cccccccccccccccccccccc c c c c c c cccccccccccccccbba``_^]]\[[ Z Y Y X W W V UUTSSRQQPONNMLLKJJIHHGFFEDD C!B!A"A#@#?$?%>%=&='<';(;):)9*9+8+7,7-6.5.4/40302122120304/4.5.6-6,7,8+8*9*:);(;'<'=&=%>%?$?#@#A"A!B!C CDEEFGGHIJJKLLMNNOPPQRRSTTU V W W X Y Y Z [[\]]^__`aabcegjmoruwz~|{xurol i f c ` ] [ X U ROMJGEB@=;8631.,)'%"       ##""!!!    !#%&(*+-/12468:<>?ACEGIKMOQSUXZ\^`be g i l n p s u w} z{|yxvtrpnljhfda````````````` ` ` ` ` ` ` ``````````````````````````~`~`} `|!`|"`{"`z#`z$`y$`x%`x&`w&`v'`u(`u(`t)`s*`s*`r+`q,`q-`p-`o.`o/`n/`m0`m1`l1`k2`j3`j3`i4`h5`h5`g6`f7`f8`e8`d9`d:`c:`b;`b<`a<``=`_>`_>`^?`]@`]@`\A`[B`[C`ZC`YD`YE`XE`WF`WG`VG`UH`TI`TI`SJ`RK`RK`QL`PM`PN`ON`NO`NP`MP`LQ`LR`KR`JS`IT`IT`HU`GV`GV`FW`EX`EY`DY`CZ`C[`B[`A\`A]`@]`?^`>_`>_`=``">#=$<$<%;&:&:'9(8(8)7*6*5+5,4,3-3.2/1/1001/1/2.3-3-4,5+5*6*7)7(8(9':&:&;%<$<$=#>">"?!@ @ABBCDEEFGGHIIJKKLMMNOPPQRRS T T U V V W XXYZ[[\]]^__`begjmoruwz~|{xtqn k h e c ` ] Z W TROLIGDB?<:7530.+)'$"       ###"""!!    !#%&(*+-/12468:<>?ACEGIKMOQSUXZ\^`begi l n p s u~ w} z{ |ywusqomkigeca_]]]]]]]]]]]]] ] ] ] ] ] ] ]]]]]]]]]]]]]]]]]]]]]]]]]]] ] ]!]~"]~"]}#]|$]|$]{%]z&]y']y']x(]w)]w)]v*]u+]u+]t,]s-]s-]r.]q/]q0]p0]o1]n2]n2]m3]l4]l4]k5]j6]j6]i7]h8]h8]g9]f:]e;]e;]d<]c=]c=]b>]a?]a?]`@]_A]_A]^B]]C]\D]\D][E]ZF]ZF]YG]XH]XH]WI]VJ]VJ]UK]TL]SM]SM]RN]QO]QO]PP]OQ]OQ]NR]MS]MS]LT]KU]JV]JV]IW]HX]HX]GY]FZ]FZ]E[]D\]D\]C]]B^]A_]A_]@`]?a]?a]>b]=c]=c] = =!<";";#:$9$8%8&7'6'6(5)4)4*3+2+2,1-0-0.//.0-0-1,2+2+3*4)4)5(6'6'7&8%9$9$:#;";"??@ABBCDDEFFGHHIJKKLMMNOOP Q Q R S S T UVVWXXYZZ[\\]_begjmoruwz}|zwtq n k h e b _ \ Y VTQNLIFDA><9742/-+(&$!      $$###""!!!  !#%&(*+-/12468:<=?ACEGIKMOQSUXZ\^`begil n p s u~ w| zz |x vtrpomkhfdb`^\[[[[[[[[[[[[[ [ [ [ [ [ [ [[[[[[[[[[[[[[[[[[[[[[[[[[[ [ [!["[#[#[$[~%[~%[}&[|'[{'[{([z)[y*[y*[x+[w,[w,[v-[u.[u.[t/[s0[r0[r1[q2[p3[p3[o4[n5[n5[m6[l7[k7[k8[j9[i9[i:[h;[g<[g<[f=[e>[e>[d?[c@[b@[bA[aB[`C[`C[_D[^E[^E[]F[\G[\G[[H[ZI[YI[YJ[XK[WL[WL[VM[UN[UN[TO[SP[RP[RQ[QR[PS[PS[OT[NU[NU[MV[LW[LW[KX[JY[IY[IZ[H[[G\[G\[F][E^[E^[D_[C`[B`[Ba[Ab[@c[@c[?d[>e[>e[=f[>=<<; :!9!9"8#7#7$6%5%5&4'3(3(2)1*0*0+/,.,.--.,.,/+0*1*1)2(3'3'4&5%5%6$7#8#8"9!: : ;<<=>>?@AABCCDEEFGHHIJJKLLM N N O P Q Q RSSTUUVWXXYZZ\_begjmoruwz}|yvs p m j g d a ^ \YVSPNKHFC@>;9641/,*(%#!       $$$###"""!! ! #%&(*+-/12468:<=?ACEGIKMOQSUXZ\^`begiln p s u} w{ zy |x v trpnljhfdb_][YXXXXXXXXXXXXX X X X X X X XXXXXXXXXXXXXXXXXXXXXXXXXXX X!X!X"X#X#X$X%X&X&X'X~(X}(X})X|*X{*X{+Xz,Xy-Xy-Xx.Xw/Xv/Xv0Xu1Xt1Xt2Xs3Xr4Xr4Xq5Xp6Xp6Xo7Xn8Xm8Xm9Xl:Xk;Xk;XjXg?Xf?Xf@XeAXdBXdBXcCXbDXbDXaEX`FX_FX_GX^HX]HX]IX\JX[KX[KXZLXYMXXMXXNXWOXVOXVPXUQXTRXTRXSSXRTXQTXQUXPVXOVXOWXNXXMYXMYXLZXK[XJ[XJ\XI]XH]XH^XG_XF`XF`XEaXDbXCbXCcXBdXAdXAeX@fX?gX?gX>hX=iX==<;;:988 7!6"6"5#4$4$3%2&1&1'0(/)/).*-+-+,,+-*-*.)/(0(0'1&2&2%3$4#4#5"6!7!7 899:;;<=>>?@@ABBCDDEFGGHIIJ K K L M N N OPPQRRSTUUVWWY\_begjmoruwz||yv r o l i f d a ^[XURPMJHEB@=;8631.,*'%"        %%$$$##"""!! !! # %&(*+-/12468:<=?ACEGIKMOQSUXZ\^`begilnp s~ u| w{ zy |w u s qomkigeca_]ZXVUUUUUUUUUUUUU U U U U U U UUUUUUUUUUUUUUUUUUUUUUUUUUU U!U"U"U#U$U$U%U&U&U'U(U)U)U*U~+U}+U},U|-U{-U{.Uz/Uy0Ux0Ux1Uw2Uv2Uv3Uu4Ut5Ut5Us6Ur7Uq7Uq8Up9Uo9Uo:Un;UmUj>Uj?Ui@Uh@UhAUgBUfCUfCUeDUdEUcEUcFUbGUaGUaHU`IU_JU^JU^KU]LU\LU\MU[NUZOUZOUYPUXQUWQUWRUVSUUSUUTUTUUSVUSVURWUQXUPXUPYUOZUNZUN[UM\UL]UL]UK^UJ_UI_UI`UHaUGaUGbUFcUEdUDdUDeUCfUBfUBgUAhU@iU@iU?jU>kU=kU=lU>=<<;:9987765 5 4!3"2#2#1$0%0%/&.'-'-(,)+*+**+),),(-'.&.&/%0$1$1#2"3"3!4 5567889::;<==>??@AABCDDEFFG H H I J K K LMMNOOPQRRSTTVY\_begjmoruw~z{|x u r o l i f c `]ZWUROLJGDB?=:8530.+)'$"         %%%$$$###""! !!!# % &(*+-/12468:<=?ACEGIKMOQSUXZ\^`begiknps~ u| wz zx |v t r p o mkifdb`^\ZXUSRRRRRRRRRRRRR R R R R R R RRRRRRRRRRRRRRRRRRRRRRRRRR R R!R"R"R#R$R%R%R&R'R'R(R)R)R*R+R,R,R-R~.R}.R}/R|0R{1Rz1Rz2Ry3Rx3Rx4Rw5Rv6Rv6Ru7Rt8Rs8Rs9Rr:Rq:Rq;RpRm?Rl?Rl@RkARjBRjBRiCRhDRgDRgERfFReFReGRdHRcIRbIRbJRaKR`KR`LR_MR^NR^NR]OR\PR[PR[QRZRRYRRYSRXTRWURVURVVRUWRTWRTXRSYRRZRRZRQ[RP\RO\RO]RN^RM^RM_RL`RKaRJaRJbRIcRHcRHdRGeRFfREfREgRDhRChRCiRBjRAkRAkR@lR?mR>mR>nR=oR==<;::98876654332 1!1!0"/#.$.$-%,&,&+'*()())(*'+'+&,%-%-$.#/"0"0!1 2 23445677899:;<<=>>?@@ABCCD E E F G H H IJJKLLMNOOPQQSVY\_begjmoruw~z{ |w t q n k h e b_\ZWTQOLIFDA?<:7520-+(&$!         &&%%%$$###"" "!!#!% & ( *+-/12468:<=?ACEGIKMOQSUXZ\^`begiknps}u{ wy zx |v t r p n l jhfdb`][YWURPOOOOOOOOOOOOO O O O O O O OOOOOOOOOOOOOOOOOOOOOOOOOO O O!O"O#O#O$O%O%O&O'O(O(O)O*O*O+O,O-O-O.O/O/O0O~1O}2O}2O|3O{4Oz4Oz5Oy6Ox7Ox7Ow8Ov9Ou9Ou:Ot;Os;OsOp>Op?Oo@On@OnAOmBOlCOkCOkDOjEOiEOiFOhGOgHOgHOfIOeJOdJOdKOcLObMObMOaNO`OO_OO_PO^QO]RO]RO\SO[TOZTOZUOYVOXVOXWOWXOVYOUYOUZOT[OS[OS\OR]OQ^OP^OP_OO`ON`ONaOMbOLcOKcOKdOJeOIeOIfOHgOGhOGhOFiOEjODjODkOClOBmOBmOAnO@oO?oO?pO>qO=qO=rO>=<;;:99877654432210/ / .!-"-",#+$*$*%)&('(''(&)%)%*$+#,#,"-!. . /01123345667889:;;<==>??@A B B C D D E FGGHIIJKLLMNNPSVY\_begjmoru w} zz |w t q m j g eb_\YVSQNKIFCA>;9641/-*(%#!     !!     &&&%%%$$$##" "!"#!%!&!( * +-/12468:<=?ACEGIKMOQSUWZ\^`begiknp~s|u{wy zw |u s q o m k i geca_][XVTROMLLLLLLLLLLLLL L L L L L L LLLLLLLLLLLLLLLLLLLLLLLLLL L!L!L"L#L$L$L%L&L&L'L(L)L)L*L+L+L,L-L.L.L/L0L0L1L2L3L3L~4L}5L|5L|6L{7Lz8Lz8Ly9Lx:Lw:Lw;LvLs?Lr?Lr@LqALpBLpBLoCLnDLmDLmELlFLkGLkGLjHLiILhILhJLgKLfLLfLLeMLdNLcNLcOLbPLaQLaQL`RL_SL^SL^TL]UL\VL\VL[WLZXLYXLYYLXZLW[LW[LV\LU]LT]LT^LS_LR`LR`LQaLPbLObLOcLNdLMeLMeLLfLKgLJgLJhLIiLHjLHjLGkLFlLElLEmLDnLCoLCoLBpLAqL@qL@rL?sL>tL>tL=uL==<;::98876554332100/..-, + +!*")#)#($'%&%&&%'$($(#)"*!*!+ ,--.//0122345567789::;<<=> ? ? @ A A B CDDEFFGHIIJKKMPSVY\_begjmor u w| zy |v s p m j gda^[XVSPMKHEC@=;8631.,*'%#     !!"     ''&&&%%%$$## #!"#"%!&!(!* + -/12468:<=?ACEGIKMOQSUWZ\^`begiknp~s|uzwxzv |t r p o m k i g db`^\ZXUSQOLJIIIIIIIIIIIII I I I I I I IIIIIIIIIIIIIIIIIIIIIIIIII I!I"I"I#I$I$I%I&I'I'I(I)I)I*I+I,I,I-I.I/I/I0I1I1I2I3I4I4I5I6I6I~7I}8I|9I|9I{:Iz;Iy;IyIw>Iv?Iu@It@ItAIsBIrCIrCIqDIpEIoFIoFInGImHImHIlIIkJIjKIjKIiLIhMIhMIgNIfOIePIePIdQIcRIbRIbSIaTI`UI`UI_VI^WI]WI]XI\YI[ZI[ZIZ[IY\IX]IX]IW^IV_IV_IU`ITaISbISbIRcIQdIQdIPeIOfINgINgIMhILiIKiIKjIJkIIlIIlIHmIGnIFnIFoIEpIDqIDqICrIBsIAtIAtI@uI?vI?vI>wI=xI > = < ; ;:99876654432110//.-,,+*)) (!'!'"&#%$$$$%#&"'"'!( ))*+,,-../01123345667889:; ; < = > > ? @@ABCCDEEFGHHJMPSVY\_begjmo r u w| zy |u r o l ifc`][XUROMJGEB?=:8530.+)'$"  !!!""    (''&&&%%%$$$ #!##"%"&"(!*!+ - / 12468:<=?ACEGIKMOQSUWZ\^`begiknp}r{uywwzv|tr p n l j h f d b`][YWUSPNLIGEEEEEEEEEEEEE E E E E E EEEEEEEEEEEEEEEEEEEEEEEEEE E E!E"E"E#E$E%E%E&E'E(E(E)E*E*E+E,E-E-E.E/E/E0E1E2E2E3E4E5E5E6E7E7E8E9E~:E~:E};E|Ey?Ey?Ex@EwAEvBEvBEuCEtDEtDEsEErFEqGEqGEpHEoIEoJEnJEmKElLElLEkMEjNEiOEiOEhPEgQEgQEfREeSEdTEdTEcUEbVEbWEaWE`XE_YE_YE^ZE][E\\E\\E[]EZ^EZ^EY_EX`EWaEWaEVbEUcEUdETdESeERfERfEQgEPhEOiEOiENjEMkEMkELlEKmEJnEJnEIoEHpEHqEGqEFrEEsEEsEDtECuEBvEBvEAwE@xE@xE?yE>zE={E={E<|E;}E:~E:~E9E8E8E7E6E5E5E4E3E3E2E1E0E0E/E.E-E-E,E+E+E*E)E(E(E'E&E&E%E$E#E#E"E!E E EEEEEEEEEEEEEEEEEEEEEEEEEE E E E E E E EEEEEEEEEEEEEEDDCBBA@??>== < ; : : 9 877655432210//.--,+**)(('& % %!$"#""#"$!% % &'(()**+,--.//012234556778 9 : : ; < <=>??@ABBCDDEGJMPSVY\_begjm o r u~ w{ zx |u r o lifc`]ZWTROLIGDA?<:7520-+(&$! !!!"""    (('''&&&%%$$ $!###%#&"("*!+!-!/ 1 2468:<=?ACEGIKMOQSUWZ\^`begikn~p|r{uywwzu|sqo m k i g e c a _][XVTRPMKIFDBBBBBBBBBBBB B B B B B B BBBBBBBBBBBBBBBBBBBBBBBBBB B B!B"B#B#B$B%B&B&B'B(B(B)B*B+B+B,B-B.B.B/B0B0B1B2B3B3B4B5B6B6B7B8B8B9B:B;B;BB}>B|?B{@B{@BzAByBByCBxCBwDBvEBvFBuFBtGBsHBsHBrIBqJBqKBpKBoLBnMBnNBmNBlOBkPBkPBjQBiRBiSBhSBgTBfUBfVBeVBdWBcXBcXBbYBaZBa[B`[B_\B^]B^^B]^B\_B[`B[`BZaBYbBYcBXcBWdBVeBVfBUfBTgBShBShBRiBQjBQkBPkBOlBNmBNnBMnBLoBKpBKpBJqBIrBIsBHsBGtBFuBFvBEvBDwBCxBCxBByBAzBA{B@{B?|B>}B>~B=~B<B;B;B:B9B9B8B7B6B6B5B4B3B3B2B1B1B0B/B.B.B-B,B+B+B*B)B)B(B'B&B&B%B$B#B#B"B!B!B BBBBBBBBBBBBBBBBBBBBBBBBBB B B B B B B BBBBBBBBBBBBBBA@@?>>=<;;: 9 8 8 7 6 6 54332100/..-,++*)(('&&%$## "!!! " ##$%&&'())*++,-../01123345 6 6 7 8 9 9 :;;<=>>?@AABDGJMPSVY\_begj m o r u~ wz zw |t qnkheb_\YVTQNKIFCA><9742/-*(&#!  ! !"""#"     )(('''&&&%%% $!$##%#&#("*"+"-!/!1 2 468:<=?ACEGIKMOQSUWZ\^`begikn~p|rzuxwvzt|rpom k i g e b ` ^ \ZXVSQOMJHECA???????????? ? ? ? ? ? ? ?????????????????????????? ?!?!?"?#?$?$?%?&?'?'?(?)?)?*?+?,?,?-?.?/?/?0?1?1?2?3?4?4?5?6?7?7?8?9?:?:?;??????~@?~A?}B?|B?{C?{D?zE?yE?xF?xG?wG?vH?vI?uJ?tJ?sK?sL?rM?qM?pN?pO?oO?nP?mQ?mR?lR?kS?kT?jU?iU?hV?hW?gX?fX?eY?eZ?dZ?c[?c\?b]?a]?`^?`_?_`?^`?]a?]b?\b?[c?Zd?Ze?Ye?Xf?Xg?Wh?Vh?Ui?Uj?Tk?Sk?Rl?Rm?Qm?Pn?Oo?Op?Np?Mq?Mr?Ls?Ks?Jt?Ju?Iu?Hv?Gw?Gx?Fx?Ey?Ez?D{?C{?B|?B}?A~?@~?????>?=?=<<;::9877 6 5 4 4 3 2 110//.-,,+*))(''&%$$#"!!  !""#$$%&''()**+,--.//012 2 3 4 5 5 6 7889::;<==>?ADGJMPSVY\_beg j m o r u} wz zw |spmjgda^\YVSPNKHEC@>;8631/,*'%#   ! ! !""###"     ))((('''&&%% %!$#$$$&#(#*"+"-"/!1!2 4 6 8:<=?ACEGIKMOQSUWZ\^`begikn}p{ryuwwvzt|rpnlj h f d b ` ^ [ YWUSPNLIGEB@=<<<<<<<<<<<< < < < < < < <<<<<<<<<<<<<<<<<<<<<<<<<< <><=<=<<<;<;<:<9<8<8<7<6<5<5<4<3<2<2<1<0<0ADGJMPSVY\_be g j m o r u| wy zv|spmjgda^[XURPMJHEB@=:8530.,)'$"   !! " ""####"    *)))(('''&&& %!%#%$$&$(#*#+#-"/"1!2!4!6 8 :;=?ACEGIKMOQSUWZ\^`begik~n|pzryuwwuzs|qomkig e c a _ ] [ Y VTRPMKIFDB?=:999999999999 9 9 9 9 9 9 9999999999999999999999999 9 9!9"9#9#9$9%9%9&9'9(9(9)9*9+9+9,9-9.9.9/90919192939494959697979899999:9;9<9<9=9>9?9?9@9A9B9B9C9D9E9E9F9~G9}H9}H9|I9{J9zJ9zK9yL9xM9wM9wN9vO9uP9uP9tQ9sR9rS9rS9qT9pU9oV9oV9nW9mX9lY9lY9kZ9j[9i[9i\9h]9g^9f^9f_9e`9da9da9cb9bc9ad9ad9`e9_f9^g9^g9]h9\i9[j9[j9Zk9Yl9Xm9Xm9Wn9Vo9Uo9Up9Tq9Sr9Rr9Rs9Qt9Pu9Pu9Ov9Nw9Mx9Mx9Ly9Kz9J{9J{9I|9H}9G~9G~9F9E9D9D9C9B9A9A9@9?9?9>9=9<9<9;9:99999897969695949393929190909/9.9.9-9,9+9+9*9)9(9(9'9&9%9%9$9#9"9"9!9 99999999999999999999999999 9 9 9 9 9 9 9999999999999877654432110 / . . - , + +*)(('&%%$##"!   !!"#$$%&''()**+ , , - . / / 012234556788;>ADGJMPSVY\_b e g j m o r u| wxzu|rolifc`]ZWUROLJGDB?<:7520-+)&$!   !! " " "##$$#"    **)))((('''& &!%#%$%&$($*$+#-#/"1"2"4!6!8 : ;=?ACEGIKMOQSUWZ\^`begik}n|pzrxuvwtzr|pomkige c ` ^ \ Z X V TQOMJHFCA><97555555555555 5 5 5 5 5 5 5555555555555555555555555 5!5!5"5#5#5$5%5&5&5'5(5)5)5*5+5,5,5-5.5/5/505152525354555556575858595:5;5;5<5=5>5>5?5@5@5A5B5C5C5D5E5F5F5G5H5I5I5~J5}K5}L5|L5{M5zN5zO5yO5xP5wQ5wR5vR5uS5tT5tU5sU5rV5qW5qX5pX5oY5nZ5n[5m[5l\5k]5k^5j^5i_5h`5h`5ga5fb5ec5ec5dd5ce5cf5bf5ag5`h5`i5_i5^j5]k5]l5\l5[m5Zn5Zo5Yo5Xp5Wq5Wr5Vr5Us5Tt5Tu5Su5Rv5Qw5Qx5Px5Oy5Nz5N{5M{5L|5K}5K~5J~5I5H5H5G5F5F5E5D5C5C5B5A5@5@5?5>5=5=5<5;5:5:595857575655545453525151505/5.5.5-5,5+5+5*5)5(5(5'5&5&5%5$5#5#5"5!5 5 5555555555555555555555555 5 5 5 5 5 555555555555555432210//.-, , + * ) ) ('&&%$##"!!  !""#$%%&'( ( ) * + + , -../011234457;>ADGJMPSVY\_ b e g j m o r~ u{wxzu|qnkheb_]ZWTQNLIFDA><9742/-*(&#!  !!!" " ###$$%#"     +***))(((''' &!&#&$%&%($*$+$-#/#1#2"4"6!8!: ; = ?ACEGIKMOQSUWZ\^`begik}n{pyrwuvwtzr|pnljhfdb ` ^ \ Y W U S QNLJGEC@>;964222222222222 2 2 2 2 2 2 2222222222222222222222222 2!2!2"2#2$2$2%2&2'2'2(2)2*2*2+2,2-2-2.2/20202122232324252626272829292:2;2<2<2=2>2?2?2@2A2B2B2C2D2E2E2F2G2H2H2I2J2K2K2L2M2~N2}N2|O2|P2{Q2zQ2yR2yS2xT2wT2vU2vV2uW2tW2sX2sY2rZ2qZ2p[2p\2o]2n]2n^2m_2l`2k`2ka2jb2ic2hc2hd2ge2ff2ef2eg2dh2ci2bi2bj2ak2`l2_l2_m2^n2]o2\o2\p2[q2Zr2Yr2Ys2Xt2Wu2Vu2Vv2Uw2Tx2Sx2Sy2Rz2Q{2P{2P|2O}2N~2M~2M2L2K2J2J2I2H2G2G2F2E2D2D2C2B2A2A2@2?2>2>2=2<2;2;2:292828272625252423222221202/2/2.2-2,2,2+2*2)2)2(2'2&2&2%2$2#2#2"2!2 2 2222222222222222222222222 2 2 2 2 2 22222222222222100/.--,+** ) ( ' ' & % $$#"!!   !"##$ % & & ' ( ) )*+,,-.//01247;>ADGJMPSVY\ _ b e g j m o r}uzwwzt|qnkheb_\YVSQNKHFC@>;9641/,*'%#   !!""" # #$$$%%#"     ++***)))(((''!'#&$&&%(%*%+$-$/#1#2#4"6"8!:!;!= ? ACEGIKMOQSUWZ\^`bdgi~k|nzpyrwuuwszq|omkigeca_] [ Y W T R P NKIGDB?=;8530//////////// / / / / / / ///////////////////////// /!/"/"/#/$/%/%/&/'/(/(/)/*/+/+/,/-/././//0/1/1/2/3/4/4/5/6/7/7/8/9/:/:/;//?/@/A/A/B/C/D/D/E/F/G/G/H/I/J/J/K/L/M/M/N/O/P/P/~Q/}R/|S/|S/{T/zU/yV/yV/xW/wX/vY/vY/uZ/t[/s\/s\/r]/q^/p_/p_/o`/na/mb/mb/lc/kd/je/je/if/hg/gh/gh/fi/ej/dk/dk/cl/bm/an/an/`o/_p/^q/^q/]r/\s/[t/[t/Zu/Yv/Xw/Ww/Wx/Vy/Uz/Tz/T{/S|/R}/Q}/Q~/P/O/N/N/M/L/K/K/J/I/H/H/G/F/E/E/D/C/B/B/A/@/?/?/>/=/ADGJMPSVY \ _ b e g j m or}uzwvzs|pmjgda^[XVSPMJHEB@=;8631.,)'$"   !!""## # $$$%%%#"    ,+++***))((('!'#'$&&&(&*%+%-$/$1$2#4#6"8":";!=!? A CEGIKMOQSUWZ\^`bdgi}k|nzpxrvutwrzp|omkigeca^\Z X V T Q O M K HFDA?<:7520-++++++++++++ + + + + + + ++++++++++++++++++++++++ + +!+"+#+#+$+%+&+&+'+(+)+)+*+++,+,+-+.+/+/+0+1+2+2+3+4+5+6+6+7+8+9+9+:+;+<+<+=+>+?+?+@+A+B+B+C+D+E+E+F+G+H+H+I+J+K+K+L+M+N+O+O+P+Q+R+R+S+T+~U+}U+|V+|W+{X+zX+yY+yZ+x[+w[+v\+u]+u^+t^+s_+r`+ra+qa+pb+oc+od+nd+me+lf+lg+kh+jh+ii+ij+hk+gk+fl+fm+en+dn+co+cp+bq+aq+`r+`s+_t+^t+]u+\v+\w+[w+Zx+Yy+Yz+Xz+W{+V|+V}+U}+T~+S+S+R+Q+P+P+O+N+M+M+L+K+J+J+I+H+G+G+F+E+D+C+C+B+A+@+@+?+>+=+=+<+;+:+:+9+8+7+7+6+5+4+4+3+2+1+1+0+/+.+.+-+,+++*+*+)+(+'+'+&+%+$+$+#+"+!+!+ +++++++++++++++++++++++++ + + + + + ++++++++++++++*))('&&%$## " !       ! " ##$%&&'())*+-147;>ADGJMPSV Y \ _ b e g jmor|uywvzs|olifc`][XUROMJGDB?=:7520-+)&$!  !!!""## # $ $%%%&%#"    ,,+++***)))((!(#'$'&&(&*&+%-%/%1$2$4#6#8#:";"=!?!A C E GIKMOQSUWY\^`bdgi}k{nypwrvutwrzp|nljhfdb`^\ZW U S Q O L J H EC@><9741/,)(((((((((((( ( ( ( ( ( ( (((((((((((((((((((((((( (!(!("(#($($(%(&('('((()(*(*(+(,(-(-(.(/(0(1(1(2(3(4(4(5(6(7(7(8(9(:(:(;(<(=(=(>(?(@(A(A(B(C(D(D(E(F(G(G(H(I(J(J(K(L(M(M(N(O(P(Q(Q(R(S(T(T(U(V(W(~W(~X(}Y(|Z({Z({[(z\(y](x](x^(w_(v`(ua(ua(tb(sc(rd(rd(qe(pf(og(ng(nh(mi(lj(kj(kk(jl(im(hm(hn(go(fp(eq(eq(dr(cs(bt(bt(au(`v(_w(^w(^x(]y(\z([z([{(Z|(Y}(X}(X~(W(V(U(U(T(S(R(R(Q(P(O(N(N(M(L(K(K(J(I(H(H(G(F(E(E(D(C(B(B(A(@(?(>(>(=(<(;(;(:(9(8(8(7(6(5(5(4(3(2(2(1(0(/(.(.(-(,(+(+(*()((((('(&(%(%($(#("("(!( ((((((((((((((((((((((((( ( ( ( ( ( (((((((((((((''&%$$#"!!                !!"#$$%&''*-147;>ADGJMP S V Y \ _ b e gjmor{uxwuzr|olifc`]ZWTQOLIGDA?<9742/-*(&# ! !!"""##$ $ $%%&&&%#"    -,,,+++***))(!(#($'&'('*&+&-%/%0%2$4$6$8#:#;"="?!A!C!E G IKMOQSUWY\^`bdg~i|kznypwruuswqzo|mkigeca_][YWU R P N L I G E B@=;8631.+)&$$$$$$$$$$$$ $ $ $ $ $ $$$$$$$$$$$$$$$$$$$$$$$$$ $!$!$"$#$$$%$%$&$'$($($)$*$+$+$,$-$.$/$/$0$1$2$2$3$4$5$5$6$7$8$8$9$:$;$<$<$=$>$?$?$@$A$B$B$C$D$E$F$F$G$H$I$I$J$K$L$L$M$N$O$O$P$Q$R$S$S$T$U$V$V$W$X$Y$Y$Z$~[$~\$}]$|]${^${_$z`$y`$xa$xb$wc$vc$ud$te$tf$sf$rg$qh$qi$pj$oj$nk$nl$mm$lm$kn$jo$jp$ip$hq$gr$gs$ft$et$du$dv$cw$bw$ax$ay$`z$_z$^{$]|$]}$\}$[~$Z$Z$Y$X$W$W$V$U$T$S$S$R$Q$P$P$O$N$M$M$L$K$J$J$I$H$G$F$F$E$D$C$C$B$A$@$@$?$>$=$<$<$;$:$9$9$8$7$6$6$5$4$3$3$2$1$0$/$/$.$-$,$,$+$*$)$)$($'$&$%$%$$$#$"$"$!$ $$$$$$$$$$$$$$$$$$$$$$$$$ $ $ $ $ $ $$$$$$$$$$$$$$#"!!              !""#$'*-147;>ADGJM P S V Y \ _ b egjmo~r{uxwtzq|nkheb_\YVTQNKIFCA>;9641/,*' % #! !!""###$$ % %%&&&'%#"    --,,,+++***))!)#($(&(('*'+&-&/&0%2%4$6$8$:#;#="?"A"C!E!G I KMOQSUWY\^`bdg}i|kznxpvrturwpzo|mkigeca_\ZXVTR O M K I F D A ?=:8530-+(%"!!!!!!!!!!!! ! ! ! ! ! !!!!!!!!!!!!!!!!!!!!!!!!! !!!"!"!#!$!%!&!&!'!(!)!)!*!+!,!,!-!.!/!0!0!1!2!3!3!4!5!6!6!7!8!9!:!:!;!!?!@!A!A!B!C!D!D!E!F!G!G!H!I!J!K!K!L!M!N!N!O!P!Q!Q!R!S!T!U!U!V!W!X!X!Y!Z![!\!\!]!^!~_!~_!}`!|a!{b!zb!zc!yd!xe!wf!wf!vg!uh!ti!ti!sj!rk!ql!pl!pm!on!no!mp!mp!lq!kr!js!is!it!hu!gv!fw!fw!ex!dy!cz!cz!b{!a|!`}!_}!_~!^!]!\!\![!Z!Y!Y!X!W!V!U!U!T!S!R!R!Q!P!O!O!N!M!L!K!K!J!I!H!H!G!F!E!D!D!C!B!A!A!@!?!>!>!=!ADGJ M P S V Y \ _ begjmo}rzuwwtzq|mjgda^\YVSPMKHEC@=;8631.,) ' $!"! !""##$$$% % &&&'''%#"   .---,,,+++***!)#)$(&((()'+'-'/&0&2%4%6%8$:$;#=#?#A"C"E!G!I!K M OQSUWY\^`bdg}i{kynwpurturwpzn|ljhfdb`^\ZXUSQO L J H E C A > <9742/-*'$"        !"##$%&''()**+,-../0112345567889:;;<=>??@ABBCDEFFGHIIJKLMMNOPPQRSTTUVWWXYZ[[\]^^_`ab~b}c}d|e{ezfzgyhxhwivjvkultlsmsnroqoppoqornsmsltlukvjviwixhygzfze{e|d}c}b~ba`_^^]\[[ZYXWWVUTTSRQPPONMMLKJIIHGFFEDCBBA@??>=<<;:9887655432110/..-,+**)(''&%$##"!                     #'*-147;>ADG J M P S V Y \ _begjmo}ryuvwszp|mjgda^[XURPMJGEB?=:8530. + ) &!$!""""##$$%% % & &&''('%#"   ..---,,,+++**!*#)$)&)(()(+(-'/'0&2&4&6%8%:$;$=$?#A#C"E"G"I!K!M O QSUWY\^`bd~g|izkynwpursuqwozm|kigeca_][YWURPNL I G E B @ > ; 9641.,)&$!       !!"#$$%&'(()*++,-.//012234566789::;<==>?@AABCDDEFGHHIJKKLMNOOPQRRSTUVVWXYZZ[\]]^_`aabcdde~f}g}h|h{izjykykxlwmvnvouotpsqrrrsqsptouovnvmwlxkykzjzi{h|h}g}f~eddcba``_^]]\[ZYYXWVVUTSRRQPOONMLKKJIHHGFEDDCBA@@?>==<;:9987665432210//.-,++*)(''&%$$#"!                #'*-147;>AD G J M P S V Y \_begjmo|ryuvwrzo|lifc`]ZWUROLIGDA?<:742/ - +!(!&!#"!"###$$%%% & &'''(('%#"   /...---,,,+++!*#*$*&)())(+(-(/'0'2'4&6&8%:%;%=$?$A#C#E#G"I"K!M!O Q S UWY\^`bd}g|izkxnvptrrupwozm|kigeca_]ZXVTRPMKI F D B ? = : 8 530.+(&#        !""#$%%&'())*+,--./0012344567889:;;<=>??@ABCCDEFFGHIJJKLMNNOPQQRSTUUVWXYYZ[\\]^_``abcddefgghi~j}k}k|l{mznyoyoxpwqvrurusttsurvrvqwpxoynznzm{l|k}j}j~ihggfedccba`__^]\\[ZYXXWVUTTSRQQPONMMLKJIIHGFFEDCBBA@?>>=<;;:9877654332100/.-,,+*)(('&%%$#"!!        #'*-147;>A D G J M P S V Y\_begjm~o{rxuuwrzo|lheb_]ZWTQNLIFCA><9641 / ,!*!("%"#" ##$$$%%&& & ''((()'%#"  //...---,,,++!+#*$*&*()))+)-(/(0'2'4'6&8&:&;%=%?$A$C$E#G#I"K"M!O!Q!S U WY\^`b~d}g{iykwnuptrrupwnzl|jhfdb`^\ZXVSQOMJHFC A ? < : 7 5 20-*(%"       !"##$%&&'()**+,-../0122345567899:;<==>?@AABCDDEFGHHIJKLLMNOPPQRSTTUVWWXYZ[[\]^__`abccdeffghijjklm~n}n|o|p{qzryrxsxtwuvvuvuwtxsyryqzq{p|o}n}m~mlkjiihgfeedcbba`_^^]\[ZZYXWVVUTSSRQPOONMLKKJIHGGFEDCCBA@@?>=<<;:9887654432110/.--,+*))('&%%$#"!!                  #'*-147;> A D G J M P S VY\_begjm~o{rwutwqzn|kheb_\YVSPNKHFC@>;86 3 1 .!,!)"'"%#"# #$$%%%&&' ' '((())'%#"  0///...---,,,!+#+$+&*(*)*+)-)/(0(2(4'6'8':&;&=%?%A%C$E$G#I#K"M"O"Q!S!U W Y\^`b~d|gzixkwnupsrquowmzk|igeca_][YWUSPNLJGEC@ > ; 9 6 4 1 /,*'$!        !"#$$%&''()*++,-.//012334567789:;;<=>??@ABCCDEFGGHIJJKLMNNOPQRRSTUVVWXYZZ[\]^^_`abbcdeffghijjklmmnopq~q}r|s|t{uzuyvxwxxwyvyuzt{t|s}r}q~pponmllkjihhgfeddcba``_^]\\[ZYYXWVUUTSRQQPONMMLKJIIHGFEEDCBAA@?>==<;:9987665432210/..-,+**)('&&%$#""!                   #'*-147; > A D G J M PSVY\_begjm}ozrwutwpzm|jgda^[XVSPMJHEB@=:8 5 3!0!.!+")"&#$#"$$$%%&&&' ' ( (())))'%# "   00////...---,!,#+$+&+(*)*+*-)/)0)2(4(6'8'9';&=&?%A%C%E$G$I#K#M#O"Q"S!U!W Y \ ^`b}d{gzixkvntprrpuowmzk|i~geca_][XVTRPNKIGDB@= ; 8 6 3 1 . +)&#!                                 ! ! " # $ % % & ' ( ) ) * + , - - . / 0 1 1 2 3 4 5 5 6 7 8 9 9 : ; < = = > ? @ A A B C D E E F G H I I J K L M M N O P Q Q R S T U U V W X Y Y Z [ \ ] ] ^ _ ` a a b c d e e f g h i i j k l m m n o p q q r s t u ~u }v |w {x {y zy yz x{ w| w} v} u~ t s s r q p o o n m l k k j i h g g f e d c c b a ` _ _ ^ ] \ [ [ Z Y X W W V U T S S R Q P O O N M L K K J I H G G F E D C C B A @ ? ? > = < ; ; : 9 8 7 7 6 5 4 3 3 2 1 0 / / . - , + + * ) ( ' ' & % $ # # " !                                     #'*-147 ; > A D G J MPSVY\_begjm|oyrvuswpzm|jfca^[XUROLJGDB?<: 7 5!2!0"-"+"(#&##$!$%%%&&''' ( (())**)'%# "   1000///...---!,#,$,&+(+)++*-*/*0)2)4(6(8(9';'=&?&A&C%E%G$I$K$M#O#Q"S"U!W!Y!\ ^ `~b}d{gyiwkuntprrpunwlzj|h~fdb`^\ZXVSQOMKHFDA?<: 8 5 3 0 - + (%#           !""#$%&&'()**+,-../012234566789:;;<=>??@ABCCDEFGGHIJKKLMNOOPQRSSTUVWXXYZ[\\]^_``abcddefghhijkllmnoppqrstuuvwxy~y}z|{{|{}z}y~xwvvutsrrqponnmlkjjihgffedcbba`_^^]\[ZYYXWVUUTSRQQPONMMLKJIIHGFEEDCBA@@?>=<<;:9887654432100/.-,,+*)(('&%$##"!        #'*-14 7 ; > A D G JMPSVY\_begjm|oyruurwozl|ifc`]ZWTQOLIFDA> < 9 7!4!1"/",#*#(#%$#$ %%&&&'''( ( )))***)'%# " ! 110000///...-!-#-$,&,(,)+++-*/*0*2)4)6)8(9(;'='?'A&C&E%G%I%K$M$O#Q#S#U"W"Y!\!^ `~ b|dzgxiwkunspqroumwkyi|h~fdb`][YWUSQNLJHECA><97 4 2 / - * ' %"         !"##$%&''()*++,-./0012344567889:;<==>?@AABCDEEFGHIIJKLMNNOPQRRSTUVVWXYZ[[\]^__`abccdefgghijkllmnoppqrsttuvwxyyz{|~}~}}~|{zzyxwvvutsrqqponmmlkjiihgfeedcba``_^]\\[ZYXXWVUTSSRQPOONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.--,+*))('&%$$#"!          #'*-1 4 7 ; > A D GJMPSVY\_begj~m{oxruurwnzk|heb_\YVTQNKHFC@ > ;!9!6!3"1".#,#)$'$%$"% %&&&''((( ) )***+*)'%# " ! 2111000///...!-#-$-&,(,),++-+/+0*2*4*6)8)9(;(=(?'A'C&E&G&I%K%M$O$Q$S#U#W"Y"\!^!`} b{ dz gxivktmrpproumwkyi|g~eca_][YVTRPNKIGEB@=;964 1 . , ) ' $ !     !"#$%%&'())*+,-../012234566789:;;<=>??@ABCDDEFGHHIJKLLMNOPQQRSTUUVWXYZZ[\]^^_`abbcdefgghijkklmnoppqrsttuvwxxyz{|}}~~}||{zyxwwvutssrqpoonmlkjjihgffedcbaa`_^]]\[ZYYXWVUTTSRQPPONMLKKJIHGGFEDCCBA@?>>=<;::987655432110/.--,+*)(('&%$$#"!    #'*- 1 4 7 ; > A DGJMPSVY\_begj~mzowrtuqwnzk|heb_\YVSPMKHEB @ =!:!8"5"3#0#.#+$)$&%$%"%&&'''(() ) ) ***++*)'% # "  " 222111000///.!.#.$-&-(-),+,-,/+0+2*4*6*8)9);)=(?(A'C'E'G&I&K%M%O%Q$S$U#W#Y"["^~"`}!b{!dy gw iuktmrpprnulwjyh|f~db`^\ZXVTQOMKIFDB?=:8530 . + ) & #            !"#$%%&'())*+,-../012234566789:;;<=>??@ABCDDEFGHHIJKLLMNOPQQRSTUUVWXYZZ[\]^^_`abbcdefgghijkklmnoppqrsttuvwxxyz{|}}~~}||{zyxwwvutssrqponnmlkjjihgffedcbaa`_^]]\[ZYYXWVUTTSRQPPONMLKKJIHGGFEDCCBA@?>>=<;::987655432110/.--,+*)(('&%$$#"!         #' * - 1 4 7 ; > ADGJMPSVY\_begj}mzowrsupwmzj|gda^[XURPMJG D B ?!=!:"7"5#2#0$-$+$(%&%#&!&&''((()) * **+++,*)'% # "  " 3222111000///!.#.$.&-(-)-+,-,/,0+2+4+6*8*9*;)=)?(A(C(E'G'I&K&M&O%Q%S$U$W#Y#[#^~"`|"bz!dx!gw iu ksmqpormukwjyh|f~db`^[YWUSQOLJHFCA><:7520- * ( % "             !"#$%%&'())*+,-../012234566789:;;<=>??@ABCDDEFGHHIJKLLMNOPQQRSTUUVWXYYZ[\]^^_`abbcdefgghijkklmnoopqrsttuvwxxyz{|}}~~}||{zyxwwvutssrqponnmlkjjihgffedcbaa`_^]]\[ZYYXWVUTTSRQPPONMLKKJIHGGFEDCCBA@?>>=<;::987655432110/.--,+*)(('&%$$#"!         # ' * - 1 4 7 ; >ADGJMPSVY\_begj|myovrsuowlzi|fc`]ZWUROLI G D!A!?"<"9"7#4#2$/$-%*%(%%&#& '''(()))* * *++,,,*)'% # " !# 333222111000/!/#/$.&.(.)-+---/,0,2,4+6+8*9*;*=)?)A)C(E(G'I'K'M&O&Q%S%U$W$Y$[#^}#`{"bz"dx!gv!it kr mp pormukwiyg|e~ca_][YWTRPNLIGEC@>;9641/,*' $ "              !"#$%%&'())*+,--./012234566789:;;<=>??@ABCCDEFGHHIJKLLMNOPQQRSTUUVWXYYZ[\]^^_`abbcdefgghijkklmnoopqrsttuvwxxyz{|}}~~}||{zyxwwvutssrqponnmlkjjihgffedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCCBA@?>>=<;::987655432110/.--,+*)(('&%$$#"!          # ' * - 1 4 7 ;>ADGJMPSVY\_begj|mxourruowlzi|fc`]ZWTQNK I F!C!A">";#9#6#4$1$.%,%*&'&%&"' '((())*** + ++,,,,*)' % # " !# 4333222111100!0#/$/&/(.).+.--/-0,2,4,6+8+9+;*=*?*A)C)E(G(I(K'M'O&Q&S&U%W%Y$[~$^}#`{#by"dw"gu"it!kr!mp pn rlujwhyf|d~b`^\ZXVTROMKIFDB?=;8631.,)&$ !                !"#$%%&'())*+,--./012234566789:;;<=>??@ABCCDEFGHHIJKLLMNOPQQRSTUUVWXYYZ[\]^^_`abbcdefgghijkklmnoopqrsttuvwxxyz{|}~}}~||{zyxwwvutssrqponnmlkjjihgffedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.--,+*)(('&%$$#"!           # ' * - 1 47;>ADGJMPSVY\_beg~j{mxotrqunwkzh|eb_\YVSP N K!H!E!C"@"=#;#8$5$3%0%.%+&)&&'$'"'(()))*** + + ,,,--,*)' % # "  "$ 4443332221110!0#0$/&/(/).+.-./-0-2-4,6,8,9+;+=*?*A*C)E)G)I(K(M'O'Q'S&U&W%Y%[~$^|$`z$bx#dw#gu"is"kq!mo!pm rk ujwhyf|d~b`^\ZWUSQOMJHFCA?<:7530-+(&#                !"#$%%&'())*+,--./012234566789:;;<=>??@ABCCDEFGHHIJKLLMNOPQQRSTUUVWXYYZ[\]^^_`abbcdefgghijkklmnoopqrsttuvwxxyz{|~}}}|~|{zyxwwvutssrqponnmlkjjihgffedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!            # ' * - 147;>ADGJMPSVY\_beg~jzmwotrqumwjzg|da^[XUS P M!J!G"E"B"?#=#:$7$5%2%0&-&+&('&'#(!(())***++ + ,,,--.,*)' % #" !"$ 5444333322211!1#0$0&0(/)/+/-./.0.2-4-6-8,9,;+=+?+A*C*E*G)I)K(M(O(Q'S'U&W&Y%[}%^{%`z$bx$dv#gt#ir"kp"mo!pm!rk!ui wg ye|c~a_][YWURPNLJGEC@><9742/-*'%"              !"#$%%&'())*+,--./012234566789:;;<=>??@ABCCDEFGHHIJKLLMNOPPQRSTUUVWXYYZ[\]^^_`abbcdeffghijkklmnoopqrsttuvwxxyz{~|}||}|~{zyxwwvutssrqponnmlkjjihgffedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!             # ' * -147;>ADGJMPSVY\_beg}jzmvosrpumwjzg|da^[XU R O!L!J"G"D#A#?$<$9$7%4%2&/&-'*'('%(#(!)))***++, , ,---..,*)' % #" !#% 5554443332221!1#1$0&0(0)/+/-//.0.2.4-6-8-9,;,=,?+A+C*E*G*I)K)M)O(Q(S'U'W&Y~&[|&^{%`y%bw$du$ft#ir#kp#mn"pl"rj!uh!wf yd |b~`^\ZXVTRPMKIGDB@=;9641/,)'$!              !"#$$%&'())*+,--./012234566789::;<=>??@ABCCDEFGHHIJKLLMNOPPQRSTUUVWXYYZ[\]^^_`abbcdeffghijkklmnoopqrsttuvwxxyz~{}||||}{~zyxwwvutssrqponnmlkjjihgffedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!              # ' *-147;>ADGJMPSVY\_beg|jymvorroulwizf|c`]Z W T!Q!O!L"I"F#C#A$>$;%9%6%4&1&/','*('(%(") )***+++,, - --....,*) ' % #"  "#% 6555444433322!2#1$1&1(0)0+0-///0/2.4.6.8-9-;-=,?,A+C+E+G*I*K*M)O)Q(S(U'W'Y~'[|&^z&`x%bw%du%fs$iq$ko#mm#pl"rj"uh!wf!yd |b ~`^\ZXUSQOMKHFDA?=:8530.+)&#!             !"#$$%&'())*+,--./012234566789::;<=>??@ABCCDEFGHHIJKLLMNOPPQRSTUUVWXYYZ[\]^^_`abbcdeffghijkklmnoopqrsttuvwxxy~z}{||||{}z~yxwwvutssrqponnmlkjjihgffedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!              # '*-147;>ADGJMPSVY\_beg{jxmuorroukwhze|b_\ Y V!T!Q"N"K#H#F#C$@$=%;%8&6&3'1'.'+()(')$)")**+++,,, - - -..//.,*) ' % #"  "$& 6665554443333!2#2$2&1(1)1+0-0/00/2/4/6.8.9-;-=-?,A,C,E+G+I*K*M*O)Q)S)U(W(Y}'[{'^z&`x&bv&dt%fr%ip$ko$mm#pk#ri"tg"we!yc!|a!~_ ] [YWUSPNLJHECA><:7520-+(%#             !"#$$%&'())*+,--./012234566789::;<=>??@ABCCDEFGHHIJKLLMNOPPQRSTUUVWXYYZ[\]^^_`abbcdeffghijkklmnoopqrsttuvwxx~y}z|{||{|z}y~xwwvutssrqponnmlkjjihgffedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!             #'*-147;>ADGJMPSVY\_be~g{jxmtoqrnukwhze|b_ \ Y!V!S"P"M#J#H$E$B%@%=%:&8&5'2'0(-(+(()&)$*!**+++,,-- - ...///.,*) ' %#" !#$& 7666655544433!3#2$2&2(1)1+1-0/0002/4/6/8.9.;.=-?-A-C,E,G+I+K+M*O*Q*S)U)W~(Y|([{'^y'`w'bu&dt&fr%ip%kn$ml$pj$rh#tf#wd"yb"|`!~^!\ Z XVTRPNKIGEB@>;9641/,*'%"            !"#$$%&'())*+,--./012234566789::;<=>??@ABCCDEFGGHIJKLLMNOPPQRSTUUVWXYYZ[\]]^_`abbcdeffghijkklmnoopqrsstuvwx~x}y|z|{{|z|y}x~wwvutssrqponnmlkjjihgffedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!            #'*-147;>ADGJMPSVY\_be}gzjwmtoprmujwgzd |a ^![!X"U"R"O#M#J$G$D%B%?&<&:&7'4'2(/(-)*)()%*#*!+++,,,--. . .///0/.,*) ' %#" !#%' 7776665555444!3#3$3&2(2)2+1-1/10020406/7/9/;.=.?.A-C-E,G,I,K+M+O*Q*S*U)W~)Y|([z(^x(`w'bu'ds&fq&io&km%ml%pj$rh$tf#wd#yb"|`"~^!\!Z X VSQOMKHFDB?=;8631.,)&$!                                       ! " # $ $ % & ' ( ) ) * + , - - . / 0 1 1 2 3 4 5 6 6 7 8 9 : : ; < = > ? ? @ A B C C D E F G G H I J K L L M N O P P Q R S T U U V W X Y Y Z [ \ ] ] ^ _ ` a b b c d e f f g h i j k k l m n o o p q r s s t u v w~ x} x| y| z{ {z |y |x }w ~w v u t s s r q p o n n m l k j j i h g f f e d c b a a ` _ ^ ] ] \ [ Z Y X X W V U T T S R Q P P O N M L K K J I H G G F E D C B B A @ ? > > = < ; : : 9 8 7 6 5 5 4 3 2 1 1 0 / . - , , + * ) ( ( ' & % $ $ # " !                                     #'*-147;>ADGJMPSVY\_be}gyjvmsoprmuiwf zc |`!]!Z"W"U#R#O$L$I$F%D%A&>&<'9'6'4(1(/),)**'*%*"+ ++,,---.. . ///00/.,* ) ' %#"  "$%' 8777766655544!4#4$3&3(3)2+2-2/101214060709/;/=.?.A.C-E-G-I,K,M+O+Q+S*U*W})Y{)[y)^x(`v(bt'dr'fp'io&km&mk%pi%rg$te$wc#ya#|_#~]"["Y!W!U S QNLJHFCA?<:7530-+(&#                                       ! " # $ $ % & ' ( ) ) * + , - - . / 0 1 1 2 3 4 5 6 6 7 8 9 : : ; < = > ? ? @ A B C C D E F G G H I J K L L M N O P P Q R S T U U V W X Y Y Z [ \ ] ] ^ _ ` a b b c d e f f g h i j k k l m n o o p q r s s t u v~ w} x| x| y{ zz {y |x |w }w ~v u t s s r q p o n n m l k j j i h g f f e d c b a a ` _ ^ ] ] \ [ Z Y X X W V U T T S R Q P P O N M L K K J I H G G F E D C B B A @ ? > > = < ; : : 9 8 7 6 5 5 4 3 2 1 1 0 / . - , , + * ) ( ( ' & % $ $ # " !                                     #'*-147;>ADGJMPSVY\_be|gyjumroorlui wf zc!|`!]"Z"W#T#Q$N$K%I%F&C&@&>';'8(6(3)1).),*)*'+$+"+,,,--... / / /0001/.,* ) ' %#"  "$&( 8887776666555!4#4$4&3(3)3+2-2.2012141607090;/=/?/A.C.E.G-I-K,M,O,Q+S+U~+W|*Y{*[y)^w)`u(bt(dr(fp'in'kl&mj&ph%rf%te%wc$ya$|_#~]#["X"V!T!R P NLIGEC@><9742/-*(%"                                      ! " # $ $ % & ' ( ) ) * + , - - . / 0 1 1 2 3 4 5 6 6 7 8 9 : : ; < = > ? ? @ A B C C D E F G G H I J K L L M N O P P Q R S T U U V W X Y Y Z [ \ ] ] ^ _ ` a b b c d e f f g h i j k k l m n o o p q r s s t u~ v} w| x| x{ yz zy {x |w |w }v ~u t s s r q p o n n m l k j j i h g f f e d c b a a ` _ ^ ] ] \ [ Z Y X X W V U T T S R Q P P O N M L K K J I H G G F E D C B B A @ ? > > = < ; : : 9 8 7 6 5 5 4 3 2 1 1 0 / . - , , + * ) ( ( ' & % $ $ # " !                                      #'*-147;>ADGJMPSVY\_be{gxjumron rk uh!we!zb"|_"\#Y#V#S$P$N%K%H&E&B'@'=':(8(5)3)0*-*+*)+&+$,!,,---.../ / 000111/.,* ) '%#" !#%&( 9888877766655!5#5$4&4(4)3+3-3.2022241617190;0=0?/A/C/E.G.I-K-M-O,Q,S+U}+W|+Yz*[x*^w)`u)bs)dq(fo(im'kl'mj'ph&rf&td%wb%y`$|^$~\#Z#X"V"T!Q!O M KIFDB@=;8641/,)'$"                                    ! " # $ $ % & ' ( ) ) * + , - - . / 0 1 1 2 3 4 5 6 6 7 8 9 : : ; < = > > ? @ A B C C D E F G G H I J K L L M N O P P Q R S T T U V W X Y Y Z [ \ ] ] ^ _ ` a b b c d e f f g h i j j k l m n o o p q r s s t~ u} v| w| x{ xz yy zx {w |w |v }u ~t s s r q p o n n m l k j j i h g f f e d c b a a ` _ ^ ] ] \ [ Z Y X X W V U T T S R Q P P O N M L K K J I H G G F E D C B B A @ ? > > = < ; : : 9 8 7 6 5 5 4 3 2 1 1 0 / . - , , + * ) ( ( ' & % $ $ # " !                                        #'*-147;>ADGJMPSVY\_b~e{gwjtmq on rk!ug!wd"za"|^#[#X$U$S%P%M%J&G&E'B'?(<(:)7)5)2*/*-+*+(+%,#,!,--.../// 0 001111/.,* ) '%#"  !#%') 9998887777666!5#5$5&4(4)4+4-3.3032242627191;1=0?0A/C/E/G.I.K.M-O-Q,S,U},W{+Yy+[x+]v*`t*br)dp)fo(im(kk(mi'pg're&tc&wa%y_%|]$~[$Y$W#U#S"Q"O!L!J H FDA?=:8530.+)&$!                                     ! " # $ $ % & ' ( ( ) * + , - - . / 0 1 1 2 3 4 5 6 6 7 8 9 : : ; < = > > ? @ A B C C D E F G G H I J K L L M N O P P Q R S T T U V W X Y Y Z [ \ ] ] ^ _ ` a b b c d e f f g h i j j k l m n o o p q r s s~ t} u| v| w{ xz xy yx zw {w |v |u }t ~s s r q p o n n m l k j j i h g f f e d c b a a ` _ ^ ] ] \ [ Z Y X X W V U T T S R Q P P O N M L K K J I H G G F E D C B B A @ ? > > = < ; : : 9 8 7 6 5 5 4 3 2 1 1 0 / . - , , + * ) ( ( ' & % $ $ # " !                                           #'*-147;>ADGJMPSVY\_b}ezgwjs mp om!rj!ug"wd"za#|^#[$X$U%R%O&L&I'G'D'A(>(<)9)7*4*1*/+,+*,',%,"- --..///0 0 0 111221/., * ) '%#"  "$&') :999988877776!6#6$5&5(5)4+4-4.3032342627291;1=1?0A0C0E/G/I/K.M.O-Q-S~-U|,W{,Yy,[w+]u+`t*br*dp)fn)il)kj(mh(pg're'tc&wa&y_&|]%~[%Y$V$T#R#P"N"L!J!G E CA><97520-+(%#                                      ! " # $ $ % & ' ( ( ) * + , - - . / 0 1 1 2 3 4 5 6 6 7 8 9 : : ; < = > > ? @ A B C C D E F G G H I J K L L M N O P P Q R S T T U V W X Y Y Z [ \ ] ] ^ _ ` a b b c d e f f g h i j j k l m n o o p q r s~ s} t| u| v{ wz xy xx yw zw {v |u |t }s ~s r q p o n n m l k j j i h g f f e d c b a a ` _ ^ ] ] \ [ Z Y X X W V U T T S R Q P P O N M L K K J I H G G F E D C B B A @ ? > > = < ; : : 9 8 7 6 5 5 4 3 2 1 1 0 / . - , , + * ) ( ( ' & % $ $ # " !                                             #'*-147;>ADGJMPSVY\_b}ey gv js!mp!ol"ri"uf#wc#z`$|]$Z%W%T%Q&N&L'I'F(C(A(>);)9*6*3+1+.+,,),'-$-"-...///00 1 1122231/., * )'%#" !"$&(* :::9999888777!6"6$6&6(5)5+5-4.4042343637292;2=1?1A1C0E0G0I/K/M.O.Q.S}-U|-Wz-Yx,[v,]u+`s+bq+do*fm*il)kj)mh(pf(rd(tb'w`'y^&|\&~Z%X%V$T$R#O#M"K"I!G!D B @>;9641/,*'%"            !"#$$%&'(()*+,--./011234566789::;<=>>?@ABCCDEFGGHIJKLLMNOPPQRSTTUVWXYYZ[\]]^_`abbcdeffghijjklmnoopqr~s}s|t|u{vzwyxxxwywzv{u|t|s}s~rqponnmlkjjihgffedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!                     #'*-147;>ADGJMPSVY\_b| ey gu!jr!mo"ol"ri#ue#wb$z_$|\%Y%V&T&Q'N'K'H(E(C)@)=*;*8*5+3+0,.,+,)-&-$.!..///0001 1 1222331/., * )'%#" !#%'(* ;::::99988887!7"7$6&6(6)5+5-5.5042444637393;2=2?2A1C1E0G0I0K/M/O/Q.S}.U{.Wy-Yx-[v,]t,`r,bp+do+fm*ik*ki)mg)pe)rc(ta(w_'y]'|[&~Y&W&U%S%Q$O$M#J#H"F"D!A!? = :8631.,)'$!          !"#$$%&'(()*+,--./011234556789::;<=>>?@ABCCDEFGGHIJKKLMNOPPQRSTTUVWXYYZ[\]]^_`aabcdeffghijjklmnoopq~r}s|s|t{uzvywxwwxwyvzu{t|s|s}r~qponnmlkjjihgffedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!                     #'*-147;>ADGJMPSVY\_~ b{!ex!gu"jq"mn#ok#rh#ue$wb$z_%|\%Y&V&S'P'M(J(H(E)B)?*=*:+7+5+2,0,--*-(-&.#.!.//000111 2 2233331/. , * )'%#"  "$%')+ ;;;::::999888!8"7$7&7(6)6+6-5.5052444647393;3=2?2A2C1E1G1I0K0M0O/Q~/S|.U{.Wy.Yw-[u-]t-`r,bp,dn+fl+ij+kh*mg*pe)rc)ta(w_(y](|['~Y'W&U&R%P%N$L$J#H#E"C"A!>!< : 7530.+(&#!           !"#$$%&'(()*+,--./011234556789::;<=>>?@ABCCDEFGGHIJKKLMNOPPQRSTTUVWXYYZ[\]]^_`aabcdeffghijjklmnoop~q}r|s|s{tzuyvxwwwwxvyuzt{s|s|r}q~ponnmlkjjihgffedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!                     #'*-147;>ADGJMPSVY \ _~!bz!ew"gt"jq#mm#oj$rg$ud%wa%z^&|[&X&U'R'O(L(J)G)D*A*?*<+9+7,4,1,/-,-*.'.%."/ //001112 2 2 3334431/. , * )'%#"  "$&()+ <;;;;::::9998!8"8$7&7(7)7+6-6.6052545647494;3=3?3A2C2E2G1I1K1M0O0Q}/S|/Uz/Wx.Yv.[u.]s-`q-bo,dm,fl,ij+kh+mf*pd*rb)t`)w^)y\(|Z(~X'V'T&R&P%N%K%I$G$E#B#@">";!9!7 42/-*(%#           !"#$$%&'(()*+,--./011234556789::;<=>>?@ABCCDEFGGHIJKKLMNOPPQRSTTUVWXYYZ[\]]^_`aabcdeffghijjklmnoo~p}q|r|s{sztyuxvwwwwvxuytzs{s|r|q}p~onnmlkjjihgffedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!                     #'*-147;>ADGJMPSV Y \!_}!bz"ev"gs#jp#mm$oj$rg%uc%w`&z]&|Z'W'T(R(O(L)I)F*C*A+>+;+9,6,3-1-.-,.).'/$/"/00011122 2 33444431/. , *)'%#" !#%&(*, <<<;;;;:::999!9"8$8&8'7)7+7-6.6062645657594;4=4?3A3C3E2G2I2K1M1O~0Q}0S{0Uy/Wx/Yv/[t.]r.`p-bo-dm-fk,ii,kg+me+pc+ra*t_*w])y[)|Y(~W(U'S'Q'O&M&K%H%F$D$B#?#=";"8!6!4 1 /,*'$"          !"#$$%&'(()*+,--./011234556789::;<=>>?@ABCCDEFGGHIJKKLMNOPPQRSTTUVWXYYZ[\]]^_`aabcdeffghijjklmno~o}p|q|r{szsytxuwvwwvwuxtyszs{r|q|p}o~nnmlkjjihgffedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!                     #'*-147;>ADGJMPS V!Y!\"_|"by#ev#gs$jo$ml%oi%rf%uc&w`&z]'|Z'W(T(Q)N)K*H*F*C+@+=,;,8,5-3-0...+.)/&/$0!001112223 3 34445531/. , *)'%#"  !#%')*, =<<<<;;;;:::9!9"9$9&8'8)8+7-7.7062646657595;4=4?4A3C3E3G2I2K2M1O~1Q|1Sz0Uy0Ww0Yu/[s/]r.`p.bn.dl-fj-ii,kg,me,pc+ra+t_*w]*y[)|Y)~W)U(S(P'N'L&J&H%F%C$A$?#<#:"8"5!3!0 . +)&$!         !"#$$%&'(()*+,,-./011234556789::;<=>>?@ABBCDEFGGHIJKKLMNOPPQRSTTUVWXXYZ[\]]^_`aabcdeffghijjklmn~n}o|p|q{rzsysxtwuwvvwuwtxsyszr{q|p|o}n~nmlkjjihgffedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!                    #'*-147;>ADGJM P S!V!Y"\"_|#bx#eu$gr$jo%mk%oh&re&ub'w_'z\(|Y(V(S)P)M*K*H+E+B+?,=,:-7-5-2.0.-/+/(/&0#0!011222333 4 44555531/ . , *)'%#"  "$&')+- ===<<<<;;;;::!:"9$9&9'8)8+8-8.7072746667695;5=5?4A4C4E3G3I3K2M2O}2Q|1Sz1Ux1Wv0Yu0[s/]q/`o/bm.dl.fj-ih-kf-md,pb,r`+t^+w\+yZ*|X*~V)T)R(P(N'L'I'G&E&C%@%>$<$9#7#5"2"0!-!+ (&#           !"#$$%&'(()*+,,-./011234556789::;<=>>?@ABBCDEFGGHIJKKLMNOPPQRSTTUVWXXYZ[\]]^_`aabcdeffghijjklm~n}n|o|p{qzrysxswtwuvvuwtwsxsyrzq{p|o|n}n~mlkjjihgffedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!                  #'*-147;>ADGJ M P!S!V"Y"\~#_{#bx$et$gq%jn%mk&oh&re'ua'w^(z[(|X)U)S*P*M*J+G+D,B,?,<-9-7.4.2.//,/*0'0%0#1 11222334 4 4 55566531/ . , *)'%#" !"$&(*+- >====<<<<;;;:!:":$:&9'9)9+8-8.8082747677696;6=5?5A5C4E4G4I3K3M~3O}2Q{2Sy1Ux1Wv1Yt0[r0]p0`o/bm/dk.fi.ig.ke-mc-pb,r`,t^,w\+yZ+|X*~U*S)Q)O)M(K(I'F'D&B&@%=%;$9$6#4#1"/"-!*!' % "           !"#$$%&'(()*+,,-./011234556789::;<=>>?@ABBCDEFGGHIJKKLMNOPPQRSTTUVWXXYZ[\]]^_`aabcdeffghijjkl~m}n|n|o{pzqyrxswswtvuuvtwswsxryqzp{o|n|n}m~lkjjihgffedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!                #'*-147;>AD G J!M!P"S"V#Y#\~$_z$bw%et%gp&jm&mj'og'rd(ua(w^(z[)|X)U*R*O+L+I+F,D,A->-<.9.6.4/1/./,0)0'1$1"122233344 4 555666531/ . ,*)'%#" !#%'(*,. >>>====<<<<;;!;":$:&:':)9+9-9.8082847677797;6=6?6A5C5E5G4I4K4M~3O|3Qz2Sy2Uw2Wu1Ys1[r1]p0`n0bl/dj/fi/ig.ke.mc.pa-r_-t],w[,yY+|W+~U+S*Q*O)L)J(H(F'D'A&?&=&:%8%6$3$1#.#,")!'!$ "           !"#$$%&'(()*+,,-./011234556789::;<=>>?@ABBCDEFGGHIJKKLMNOPPQRSTTUVWXXYZ[\]]^_`aabcdeffghijjk~l}m|n|n{ozpyqxrwswsvtuutvswswrxqypzo{n|n|m}l~kjjihgffedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!              #'*-147;>A D G!J!M"P"S#V#Y$\}$_z%bv%es&gp&jm'mi'of(rc(u`)w])zZ*|W*T*Q+N+K,I,F-C-@->.;.8/6/3/00.0+0)1&1$2!223334445 5 566677531/ . ,*)'%#"  "#%')+,. ?>>>>====<<<'<&:&7%5%3$0$.#+#)"&"#!!!            !"##$%&'(()*+,,-./0112345567899:;<=>>?@ABBCDEFGGHIJKKLMNOOPQRSTTUVWXXYZ[\]]^_`aabcdeefghijj~k}l|m|n{nzoypxqwrwsvsuttusvswrwqxpyozn{n{m|l}k~jjihgffedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!            #'*-147;> A D!G"J"M#P#S$V$Y%\|%_y&bv&er'go'jl'mi(of(rb)u_)w\*zY*|V+S+Q+N,K,H-E-B.@.=.:/8/502000-1+1(1&2#2!333444555 6 667777531 / . ,*)'%#"  "$&()+-/ ???>>>>====<';'9&7&4%2%/$-$*#(#%"#" !!              !"##$%&'(()*+,,-./0112345567899:;<=>>?@ABBCDEFGGHIJKKLMNOOPQRSTTUVWXXYZ[\]]^_`aabcdeefghij~j}k|l|m{nznyoxpwqwrvsusttsusvrwqwpxoynzn{m{l|k}j~jihgffedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!          #'*-147 ; >!A!D"G"J#M#P$S$V%Y%\|&_x&bu'er'gn(jk(mh)oe)rb*u_*w\*zY+|V+S,P,M-J-G-E.B.?/>>>====!<"<$<&;';);+;-:.:0:2949597998;8=8?7A7C7E6G6I6J~5M|5Oz5Qy4Sw4Uu4Ws3Yr3[p2]n2`l2bj1di1fg1he0kc0ma/o_/r]/t[.wY.yW-|U-~S-Q,O,M+J+H*F*D)B)?)=(;(8'6'4&1&/%,%*$'$%#"#""!              !"##$%&'(()*+,,-./0112345567899:;<=>>?@ABBCDEFGGHIJKKLMNOOPQRSTTUVWXXYZ[\]]^_`aabcdeefghi~j}j|k|l{mznynxowpwqvrustsstsurvqwpwoxnynzm{l{k|j}j~ihgffedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!          #'*-14 7 ;!>!A"D"G#J#M$P%S%V&Y~&\{&_x'bt'eq(gn(jk)mg)od*ra*u^+w[+zX,|U,R,O-L-J.G.D.A/>/<090604111/2,2)2'3$3"3 44455566 6 7778887531 / .,*)'%#" !#%')*,.0 @@@@???>>>>==!="=$<&<'<);+;-;.;0:2:4:597999;8=8?8A7C7E7G7H6J}6M{6Oz5Qx5Sv4Uu4Ws4Yq3[o3]m3`l2bj2dh2ff1hd1kb0m`0o^0r\/tZ/wX.yV.|T.~R-P-N,L,J+H+E+C*A*?)<):(8(5'3'0&.&+%)%&$$$!##""!!            !"##$%&'(()*+,,-./0112345567899:;<=>>?@ABBCDEFGGHIJKKLMNOOPQRSTTUVWXXYZ[\]]^_`aabcdeefgh~i}j|j|k{lzmynxnwowpvqurtsssstruqvpwownxnymzl{k{j|j}i~hgffedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!            #'*-1 4 7!;">"A#D#G$J$M%P%S&V&Y}'\z'_w(bt(ep)gm)jj*mg*od*r`+u]+wZ,zW,|T-R-O-L.I.F/C/A/>0;081613102.2+3)3&3$4!445556667 7 7888987531 / .,*)'%#"  "$&')+-/0 AA@@@@???>>>>!="=$=&='<)<+<-;.;0;2;4:5:7:99;9=9?8A8C8E7F7H~7J}6L{6Oy6Qx5Sv5Ut5Wr4Yp4[o4]m3_k3bi3dg2fe2hd1kb1m`1o^0r\0tZ/wX/yV/|T.~R.P-M-K-I,G,E+B+@*>*<)9)7)5(2(0'-'+&(&&%#%!$$#""!!            !"##$%&'(()*+,,-./0012345567899:;<=>>?@ABBCDEFFGHIJKKLMNOOPQRSTTUVWXXYZ[\\]^_`aabcdeefg~h}i|j|j{kzlymxnwnwovpuqtrsrssrtqupvownwnxmylzk{j{j|i}h~gffedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!              #'* - 1!4!7";">#A#D$G$J%M%P&S&V'Y}'\y(_v(bs)ep)gl*ji*mf+oc+r`,u],wZ,zW-|T-Q.N.K/H/E/C0@0=1:181522202-3+3(3&4#4!555666777 8 889998753 1 / .,*)'%#" !"$&(*+-/1 AAAA@@@@???>>!>">$=&='=)=+<-<.<0;2;4;5:7:9:;:=9?9A9C8E8F8H~7J|7Lz7Oy6Qw6Su6Us5Wr5Yp5[n4]l4_j4bi3dg3fe2hc2ka2m_1o]1r[1tY0wW0yU/|S/~Q/O.M.K-H-F,D,B,@+=+;*9*6)4)1(/(-'*'(&%&"% %$$##"" !             !"##$%&'(()*+,,-./0012345567899:;<=>>?@ABBCDEFFGHIJKKLMNOOPQRSTTUVWXXYZ[\\]^_`aabcdeef~g}h|i|j{jzkylxmwnwnvouptqsrsrrsqtpuovnwnwmxlykzj{j{i|h}g~ffedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!                #' * -!1!4"7#;#>$A$D%G%J&M&P'S'V(Y|(\y)_u)br*eo*gl*jh+me+ob,r_,u\-wY-zV.|S.P.M/J/H0E0B0?1=1:2724223/3-3*4(4%4#5 55667777 8 8 8999:8753 1 /.,*)'%#" !#%'(*,.01 BBAAAA@@@@???!>">$>&>'=)=+=-=.<0<2<4;5;7;9:;:=:?:A9C9E9F8H}8J{8Lz7Nx7Qv7Su6Us6Wq6Yo5[n5]l5_j4bh4df3fd3hb3k`2m^2o]2r[1tY1wW0yT0{R0~P/N/L.J.H-F-C-A,?,=+:+8*6*3)1).),()(''$'"&&%$$##" " !!           !"##$%&'(()*+,,-./0012345567899:;<=>>?@ABBCDEFFGHIJKKLMNOOPQRSTTUVWXXYZ[\\]^_`aabcdee~f}g|h{i{jzjykxlwmwnvnuotpsqsrrrqsptounvnwmwlxkyjzj{i{h|g}f~fedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!                  # '!*!-"1"4#7#;$>$A%D%G&J&M'P'S(V(Y{)\x)_u*bq*en+gk+jh,me,ob,r^-u[-wX.zU.|R/P/M/J0G0D1A1?1<292734313/4,4*4'5$5"5 66677788 8 999:::8753 1 /.,*)'%#" "#%')+-.02 BBBBAAAA@@@@?!?"?$>&>'>)>+=-=.=0<2<4<5<7;9;;;=:?:A:C9E9F~9H}9J{8Ly8Nw8Qv7St7Ur7Wp6Yo6[m5]k5_i5bg4df4fd4hb3k`3m^3o\2rZ2tX1wV1yT1{R0~P0N/K/I/G.E.C-@->,<,:,7+5+3*0*.)+))(&($'!'&&%%$$# #"!!           !"##$%&'(()*+,,-./0012345567899:;<=>>?@ABBCDEFFGHIJKKLMNOOPQRSTTUVWXXYZ[\\]^_`aabcde~e}f|g{h{izjyjxkwlwmvnuntospsqrrqrpsotnunvmwlwkxjyjzi{h{g|f}e~edcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!                      #!'!*"-"1#4#7$;%>%A&D&G'J'M(P(S)V~)Y{*\w*_t*bq+em+gj,jg,md-oa-r^.u[.wX.zU/|R/O0L0I0F1C1A2>2;293633414.4+5)5&5$6!667778889 9 9:::;:875 3 1 /.,*)'%#" "$&()+-/12 CCBBBBAAAA@@@!@"?$?&?'>)>+>->.=0=2=4<5<7<9<;;=;?;A:C:D:F~9H|9Jz9Ly8Nw8Qu8Ss7Ur7Wp7Yn6[l6]j6_i5bg5de5fc4ha4k_4m]3o[3rY2tW2wU2yS1{Q1~O0M0K0I/F/D.B.@.>-;-9,7,4+2+/*-**)()%(#( ('&&%%$ $ ##""            !"##$%&''()*+,,-./0012345567899:;<==>?@ABBCDEFFGHIJKKLMNOOPQRSSTUVWXXYZ[\\]^_`aabcd~e}e|f{g{hziyixjwkwlvmuntnsosprqqrprosntnumvlwkwjxjyizh{g{f|e}e~dcbaa`_^]]\[ZYXXWVUTTSRQPOONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!                       !#!'"*#-#1$4$7%;%>&A&D'G'J(M(P)S)V}*Yz*\w+_s+bp,em,gj-jf-mc-o`.r].uZ/wW/zT/|Q0N0K1H1F2C2@2=3;383543405-5+5(6&6#6!777888999 : :::;;:875 3 1 /.,*)'%#" !#$&(*,./13 CCCCBBBBAAAA@!@"@$@&?'?)?+>->.>0>2=4=5=7<9<;<=?@ABBCDEFFGHIJKKLMNOOPQRSSTUVWXXYZ[\\]^_`aabc~d}e|e{f{gzhyixiwjwkvlumtnsnsorpqqprornsntmulvkwjwjxiyhzg{f{e|e}d~cbaa`_^]]\[ZYXXWVUTTSRQPOONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!                      !!"#"'#*#-$1$4%7&;&>'A'D(G(J)M)P*S*V}*Yy+\v+_s,bo,el-gi-jf.mc.o`.r\/uY/wV0zS0|P1N1K1H2E2B3?3=3:4745425/5-5*6(6%7#7 7888999: : : :;;;<:875 3 1/.,*)'%#" !#%')*,.023 DDCCCCBBBBAAA!A"@$@&@'@)?+?-?.>0>2>4>5=7=9=;<=/<.:.8.5-3-0,.,,+)+'*$*!))((''&& % %$$#           !"##$%&''()*+,,-./0012345567899:;<==>?@ABBCDEFFGHIJKKLMNOOPQRSSTUVWXXYZ[\\]^_`aab~c}d|e{e{fzgyhxiwiwjvkultmsnsnroqppqornrnsmtlukvjwjwixhygzf{e{e|d}c~baa`_^]]\[ZYXXWVUTTSRQPOONMLKKJIHGGFEDCBBA@?>>=<;:9987655432110/.-,,+*)(('&%$$#"!                      !!""##'$*$-%1%4&7&;'>'A(D(G)J)M*P*S+V|+Yy,\u,_r-bo-ek-gh.je.mb/o_/r\0uY0wV0zS1|P1M2J2G2D3B3?4<494754515/6,6*6'7%7"7 888999:: : ;;;<<<:875 3 1/.,*)'%#" "$&')+-/024 DDDDCCCCBBBBA!A"A$A&@'@)@+@,?.?0?2>4>5>7>9=;===?0?@ABBCDEFFGHIJKKLMNOOPQRSSTUVWXXYZ[\\]^_`aa~b}c|d{e{ezfygxhwiwivjuktlsmsnrnqoppoqnrnrmsltkujvjviwhxgyfze{e{d|c}b~aa`_^]]\[ZYXXWVUTTSRQPOONMLKKJIHGGFEDCBBA@?>>=<;:9987655432110/.-,,+*)(('&%$##"!                    !""###$'$*%-%1&4'7';(>(A)D)G*J*M*P+S+V{,Yx,\u-_q-bn.ek.gh/jd/ma/o^0r[0uX1wU1zR1|O2L2I3G3D3A4>4;595653616.6,7)7&7$8!88999:::; ; ;<<<=<:87 5 3 1/.,*)'%#" "$&(*,-/134 EEDDDDCCCCBBB!B"A$A&A'A)@+@,@.@0?2?4?5>7>9>;>==?=A=C?@ABBCDEFFGHIJJKLMNOOPQRSSTUVWXXYZ[\\]^_``~a}b|c{d{ezeyfxgwhwiviujtkslsmrnqnpoopnqnrmrlsktjujvivhwgxfyeze{d{c|b}a~a`_^]]\[ZYXXWVUTTSRQPOONMLKKJIHGGFEDCBBA@?>>=<;:9987655432110/.-,,+*)(('&%$##"!                     ! !""##$#%'%*&-&1'4'7(;(>)A)D*G*J+M+P,S~,V{-Yw-\t._q.bm.ej/gg/jd0ma0o]1rZ1uW1wT2zQ2|O3L3I3F4C4@4>5;586563607.7+7(8&8#8!999:::;;; < <<<==<:87 5 3 1/.,*)'%#"! #%'(*,.0135 EEEEDDDDCCCCB!B"B$B&A'A)A+A,@.@0@2@4?5?7?9>;>=>?>A=B~=D|=F{ ? @ A B B C D E F F G H I J J K L M N O O P Q R S S T U V W X X Y Z [ \ \ ] ^ _ `~ `} a| b{ c{ dz ey ex fw gw hv iu it js ks lr mq np no on pn qm rl rk sj tj ui vh vg wf xe ye zd {c {b |a }a ~` _ ^ ] ] \ [ Z Y X X W V U T T S R Q P O O N M L K K J I H G G F E D C B B A @ ? > > = < ; : 9 9 8 7 6 5 5 4 3 2 1 1 0 / . - , , + * ) ( ( ' & % $ # # " !                                             ! ! "##$$%#%'&*&-'1(4(7);)>*A*D+G+J+M,P,S}-Vz-Yv.\s._p/bm/ei0gf0jc0m`1o]1rZ2uW2wT2zQ3|N3K4H4E4B5@5=5:6765727/7-8*8(8%9#9 9:::;;;< < < <===><:87 5 31/.,*)'%# "" #%')+-.0245 FFEEEEDDDDCCC!C"B$B&B'B)A+A,A.A0@2@4@5@7?9?;?=>?>A>B}>D|=Fz=Hy=Jw2<2:171503000./+/).&.$-!-,,++**) ) ((''$!  !!!!!!!!!!!! ! ! ! ! ! !!!!!!!!!!!!!!!!!!!!!!! !!!"!#!#!$!%!&!'!'!(!)!*!+!,!,!-!.!/!0!0!1!2!3!4!4!5!6!7!8!9!9!:!;!!?!@!A!B!B!C!D!E!F!F!G!H!I!J!J!K!L!M!N!O!O!P!Q!R!S!S!T!U!V!W!X!X!Y!Z![!\!\!]!^!_~!`}!`|!a{!b{!cz!dy!ex!ew!fw!gv!hu!it!is!js!kr!lq!mp!no!nn!on!pm!ql!rk!rj!sj!ti!uh!vg!vf!we!xe!yd!zc!{b!{a!|a!}`!~_!^!]!]!\![!Z!Y!X!X!W!V!U!T!T!S!R!Q!P!O!O!N!M!L!K!K!J!I!H!G!G!F!E!D!C!B!B!A!@!?!>!>!=!*A+D+G,J,M-P-S|.Vy.Yv.\r/_o/bl0ei0ge1jb1m_1o\2rY2uV3wS3zP3|M4J4G5E5B5?6<6:6774718/8,8*9'9%9": ::;;;<<< < ===>>><:87 5 31/.,*)'%# "" $&()+-/1246 FFFFEEEEDDDDC!C"C$C&B'B)B+B,A.A0A2A4@5@7@9@;?=???A>B}>D{>Fz>Hx=Jv=Lu=Ns"?"@"A"B"B"C"D"E"F"F"G"H"I"J"J"K"L"M"N"O"O"P"Q"R"S"S"T"U"V"W"W"X"Y"Z"["\"\"]"^~"_}"`|"`{"a{"bz"cy"dx"ew"ew"fv"gu"ht"is"is"jr"kq"lp"mo"mn"nn"om"pl"qk"rj"rj"si"th"ug"vf"ve"we"xd"yc"zb"{a"{a"|`"}_"~^"]"]"\"["Z"Y"X"X"W"V"U"T"T"S"R"Q"P"O"O"N"M"L"K"K"J"I"H"G"G"F"E"D"C"B"B"A"@"?">">"="<";":"9"9"8"7"6"5"5"4"3"2"1"1"0"/"."-",","+"*")"("("'"&"%"$"#"#"""!" """"""""""""""""""""""" " " " " " " """"""""""""!              !"" # $$%%&&#'''*(-)1)4*7*;+>+A,D,G,J-M-P.S|.Vx/Yu/\r0_n0bk0eh1ge1jb2m_2o[3rX3uU3wR4zO4|M5J5G5D6A6>6<797674818.9,9)9':$:":;;;;<<<= = =>>>>><:8 7 5 31/.,*)'%#!"# $&(*,./1356 GGFFFFEEEEDDD!D"D$C&C'C)C+B,B.B0A2A4A5A7@9@;@=@??A~?B|?D{>Fy>Hw>Jv=Lt=Nr=Pp=So"?"@"A"A"B"C"D"E"F"F"G"H"I"J"J"K"L"M"N"O"O"P"Q"R"S"S"T"U"V"W"W"X"Y"Z"["\"\"]~"^}"_|"`{"`{"az"by"cx"dw"ew"ev"fu"gt"hs"is"ir"jq"kp"lo"mn"mn"nm"ol"pk"qj"rj"ri"sh"tg"uf"ve"ve"wd"xc"yb"za"{a"{`"|_"}^"~]"]"\"["Z"Y"X"X"W"V"U"T"T"S"R"Q"P"O"O"N"M"L"K"K"J"I"H"G"G"F"E"D"C"B"B"A"@"?">">"="<";":"9"9"8"7"6"5"5"4"3"2"1"1"0"/"."-",","+"*")"("("'"&"%"$"#"#"""!" """"""""""""""""""""""" " " " " " " """""""""""""!              !"## $ $%&&''#('(*)-)1*4*7+;+>,A,D-G-J.M.P~/S{/Vx/Yt0\q0_n1bj1eg2gd2ja2m^3o[3rX4uU4wR4zO5|L5I6F6C6@7>7;788683809.9+9(:&:#:!;;;<<<=== > >>>??><:8 7 531/.,*)'%#!"# %')+,.02357 GGGGFFFFEEEEE!D"D$D&D'C)C+C,C.B0B2B4A5A7A9A;@=@?@A}@B|?Dz?Fx?Hw>Ju>Ls>Nr=Pp=Rn=Ul=Wk4<4:483533202.2,1)1'0$0"///..--, , ++**($!    ############ # # # # # ####################### #!#"#####$#%#&#'#'#(#)#*#+#+#,#-#.#/#0#0#1#2#3#4#4#5#6#7#8#9#9#:#;#<#=#=#>#?#@#A#A#B#C#D#E#F#F#G#H#I#J#J#K#L#M#N#O#O#P#Q#R#S#S#T#U#V#W#W#X#Y#Z#[#\#\~#]}#^|#_{#`{#`z#ay#bx#cw#dw#ev#eu#ft#gs#hs#ir#iq#jp#ko#ln#mn#mm#nl#ok#pj#qj#ri#rh#sg#tf#ue#ve#vd#wc#xb#ya#za#{`#{_#|^#}]#~]#\#[#Z#Y#X#X#W#V#U#T#T#S#R#Q#P#O#O#N#M#L#K#K#J#I#H#G#G#F#E#D#C#B#B#A#@#?#>#>#=#<#;#:#9#9#8#7#6#5#5#4#3#2#1#1#0#/#.#-#,#,#+#*#)#(#(#'#&#%#$#####"#!# ####################### # # # # # # #############"!               !"#$$ % %&&''(#(')**-*1+4+7,;,>-A-D-G.J.M/P~/Sz0Vw0Yt1\p1_m1bj2eg2gc3j`3m]4oZ4rW4uT5wQ5zN5|K6H6E7C7@7=8:888592909-:*:(:%;#; ;<<<===> > > >???@><:8 7 531/.,*)'% #""$ &')+-/02467 HHGGGGFFFFFEE!E"E$D&D'D)D+C,C.C0C2B4B5B7A9A;A=A?@A}@B{@Dz@Fx?Hv?Ju?Ls>Nq>Po>Rn=Ul=Wj=Yh=[f<]d<_c5;59474542303-2+2)1&1$1!00//..-- , ,++*($!  !$$$$$$$$$$$$ $ $ $ $ $ $$$$$$$$$$$$$$$$$$$$$$$ $!$"$#$#$$$%$&$'$'$($)$*$+$+$,$-$.$/$0$0$1$2$3$4$4$5$6$7$8$9$9$:$;$<$=$=$>$?$@$A$A$B$C$D$E$F$F$G$H$I$J$J$K$L$M$N$O$O$P$Q$R$S$S$T$U$V$W$W$X$Y$Z$[$\~$\}$]|$^{$_{$`z$`y$ax$bw$cw$dv$eu$et$fs$gs$hr$iq$ip$jo$kn$ln$mm$ml$nk$oj$pj$qi$rh$rg$sf$te$ue$vd$vc$wb$xa$ya$z`${_${^$|]$}]$~\$[$Z$Y$X$X$W$V$U$T$T$S$R$Q$P$O$O$N$M$L$K$K$J$I$H$G$G$F$E$D$C$B$B$A$@$?$>$>$=$<$;$:$9$9$8$7$6$5$5$4$3$2$1$1$0$/$.$-$,$,$+$*$)$($($'$&$%$$$#$#$"$!$ $$$$$$$$$$$$$$$$$$$$$$$ $ $ $ $ $ $ $$$$$$$$$$$$##"!               !"#$$% % &''(()#)'***-+1+4,7,;->-A.D.G/J/M0P}0Sz0Vv1Ys1\p2_l2bi3ef3gc3j`4m\4oY5rV5uS5wP6zM6|K6H7E7B8?8<8:979492:/:,:*;';%;"< <<===>>> > ???@@@><:8 7 531/.,*)'% #""$ &(*,-/13468 HHHHGGGGGFFFF!E"E$E&E'D)D+D,D.C0C2C3C5B7B9B;B=A?~AA|AB{@Dy@Fw@Hv@Jt?Lr?Np?Po>Rm>Uk>Wi=Yh=[f=]d<_b%?%@%A%A%B%C%D%E%F%F%G%H%I%J%J%K%L%M%N%N%O%P%Q%R%S%S%T%U%V%W%W%X%Y%Z%[~%\}%\|%]{%^{%_z%`y%`x%aw%bw%cv%du%dt%es%fs%gr%hq%ip%io%jn%kn%lm%ml%mk%nj%oj%pi%qh%rg%rf%se%te%ud%vc%vb%wa%xa%y`%z_%z^%{]%|]%}\%~[%Z%Y%X%X%W%V%U%T%T%S%R%Q%P%O%O%N%M%L%K%K%J%I%H%G%G%F%E%D%C%B%B%A%@%?%>%>%=%<%;%:%9%9%8%7%6%5%5%4%3%2%1%1%0%/%.%-%,%,%+%*%)%(%(%'%&%%%$%#%#%"%!% %%%%%%%%%%%%%%%%%%%%%%% % % % % % % %%%%%%%%%%%%$##"!               !"#$$%& & ''(()*#*'+*+-,1,4-7-;.>.A.D/G/J0M0P|1Sy1Vv2Yr2\o2_l3bh3ee4gb4j_4m\5oY5rV6uS6wP6zM7|J7G8D8A8?9<9996:4:1:.;,;);'<$<"<===>>>>? ? ?@@@@@><: 8 7 531/.,*)'%!##"% '(*,.013578 IIHHHHHGGGGFF!F"F$E&E'E)E+D,D.D0D2C3C5C7C9B;B=B?}B@|ABzADxAFw@Hu@Js@Lr@Np?Pn?Rl?Uk>Wi>Yg>[e=]c=_a=a`&?&@&A&A&B&C&D&E&F&F&G&H&I&J&J&K&L&M&N&N&O&P&Q&R&S&S&T&U&V&W&W&X&Y&Z~&[}&\|&\{&]{&^z&_y&`x&`w&aw&bv&cu&dt&ds&es&fr&gq&hp&io&in&jn&km&ll&mk&mj&nj&oi&ph&qg&rf&re&se&td&uc&vb&va&wa&x`&y_&z^&z]&{]&|\&}[&~Z&Y&X&X&W&V&U&T&T&S&R&Q&P&O&O&N&M&L&K&K&J&I&H&G&G&F&E&D&C&B&B&A&@&?&>&>&=&<&;&:&9&9&8&7&6&5&5&4&3&2&1&1&0&/&.&-&,&,&+&*&)&(&(&'&&&%&$&#&#&"&!& &&&&&&&&&&&&&&&&&&&&&&& & & & & & & &&&&&&&&&&&&%$##"!               !"#$$%&' ' (())**#+'+*,-,1-4-7.;.>/A/D0G0J1M1P|1Sx2Vu2Yq3\n3_k4bh4ee4ga5j^5m[6oX6rU6uR7wO7zL7|I8F8D9A9>9;:8:6:3;0;.;+<)<&<#=!==>>>>??? @ @@AAA@><: 8 7531/.,*)' %!##"% ')+-.024579 IIIIHHHHHGGGG!F"F$F&F'E)E+E,E.D0D2D3D5C7C9C;C=~B?}B@{BBzBDxAFvAHuAJs@Lq@No@Pn@Rl?Uj?Wh?Yf>[e>]c>_a=a_=d]=f[8<79776563605.5+4)4&4$3!32211100 / /..-+($ !  #&''''''''''' ' ' ' ' ' ''''''''''''''''''''''' '!'"'"'#'$'%'&'''''(')'*'+'+','-'.'/'0'0'1'2'3'4'4'5'6'7'8'8'9':';'<'='='>'?'@'A'A'B'C'D'E'F'F'G'H'I'J'J'K'L'M'N'N'O'P'Q'R'S'S'T'U'V'W'W'X'Y~'Z}'[|'\{'\{']z'^y'_x'`w'`w'av'bu'ct'ds'ds'er'fq'gp'ho'in'in'jm'kl'lk'mj'mj'ni'oh'pg'qf're're'sd'tc'ub'va'va'w`'x_'y^'z]'z]'{\'|['}Z'~Y'X'X'W'V'U'T'T'S'R'Q'P'O'O'N'M'L'K'K'J'I'H'G'G'F'E'D'C'B'B'A'@'?'>'>'='<';':'9'9'8'7'6'5'5'4'3'2'1'1'0'/'.'-',','+'*')'('('''&'%'$'#'#'"'!' ''''''''''''''''''''''' ' ' ' ' ' ' ''''''''''''&%$##"!               !"#$$%&'' ( ()**++#,',*---1.4.7/;/>/A0D0G1J1M~2P{2Sw3Vt3Yq3\m4_j4bg5ed5ga5j^6mZ6oW7rT7uQ7wN8zK8|I8F9C9@:=:::8;5;2;0<-<*<(=%=#= >>>>???@ @ @ AAAAB@><: 8 7531/.,*)' %"#$"& ()+-/124689 JJIIIIIHHHHGG!G"G$F&F'F)F+F,E.E0E2E3D5D7D9C;C=~C?|C@{BByBDwBFvBHtAJrALpANo@Pm@Rk@Ui@Wh?Yf?[d?]b>_`>a^>d\=fZ=hY=kW'?'@'A'A'B'C'D'E'F'F'G'H'I'J'J'K'L'M'N'N'O'P'Q'R'S'S'T'U'V'W'W'X~'Y}'Z|'[{'\{'\z']y'^x'_w'`w'`v'au'bt'cs'ds'dr'eq'fp'go'hn'in'im'jl'kk'lj'mj'mi'nh'og'pf'qe're'rd'sc'tb'ua'va'v`'w_'x^'y]'z]'z\'{['|Z'}Y'~X'X'W'V'U'T'T'S'R'Q'P'O'O'N'M'L'K'K'J'I'H'G'G'F'E'D'C'B'B'A'@'?'>'>'='<';':'9'9'8'7'6'5'5'4'3'2'1'1'0'/'.'-',','+'*')'('('''&'%'$'#'#'"'!' ''''''''''''''''''''''' ' ' ' ' ' ' '''''''''''''&%$##"!               !"#$$%&'(( ) )**++,#,'-*--.1.4/7/;0>0A1D1G2J2M~2Pz3Sw3Vs4Yp4\m5_j5bf5ec6g`6j]7mZ7oW7rT8uQ8wN8zK9|H9E9B:?:=;:;7;4<2"> >>???@@@ A AAABBB@>< : 8 7531/.,*)'!%##$"& (*,./13568: JJJJIIIIIHHHH!G"G$G&G'G)F+F,F.F0E2E3E5E7D9D;D=}D?|C@zCBxCDwBFuBHsBJrBLpANnAPlARk@Ui@Wg@Ye@[c?]a?_`?a^>d\>fZ>hX=kV=mT=oR(?(@(A(A(B(C(D(E(E(F(G(H(I(J(J(K(L(M(N(N(O(P(Q(R(S(S(T(U(V(W(W~(X}(Y|(Z{([{([z(\y(]x(^w(_w(`v(`u(at(bs(cs(dr(dq(ep(fo(gn(hn(im(il(jk(kj(lj(mi(mh(ng(of(pe(qe(qd(rc(sb(ta(ua(v`(v_(w^(x](y](z\(z[({Z(|Y(}X(~X(W(V(U(T(T(S(R(Q(P(O(O(N(M(L(K(K(J(I(H(G(G(F(E(D(C(B(B(A(@(?(>(>(=(<(;(:(9(9(8(7(6(5(5(4(3(2(1(1(0(/(.(-(,(,(+(*()((((('(&(%($(#(#("(!( ((((((((((((((((((((((( ( ( ( ( ( ( ((((((((((((''&%$##"!              !"#$$%&'(() * *++,,-#-'.*.-/1/4070;1>1A1D2G2J3M}3Py4Sv4Vs4Yo5\l5_i6bf6eb6g_7j\7mY8oV8rS8uP9wM9zJ9|G:D:B:?;<;9<6<4<1=.=,=)>'>$>">???@@@AA A ABBBCB@>< : 8 7531/.,*)'!%##%"' )+,.023579: KKJJJJJIIIIHH!H"H$H&G'G)G+G,F.F0F2F3E5E7E9E;~D=}D?{D@yDBxCDvCFtCHsBJqBLoBNnBPlARjAThAWf@Ye@[c@]a@__?a]?d[?fY>hW>jU>mS=oQ=rO=tM:<::979583818.7,7)7'6$6"55444332 2 1110/+( % ! "%)))))))))))) ) ) ) ) ) ))))))))))))))))))))))) )!)")")#)$)%)&)')')()))*)+)+),)-).)/)/)0)1)2)3)4)4)5)6)7)8)8)9):);)<)=)=)>)?)@)A)A)B)C)D)E)E)F)G)H)I)J)J)K)L)M)N)N)O)P)Q)R)S)S)T)U)V)W~)W})X|)Y{)Z{)[z)[y)\x)]w)^w)_v)`u)`t)as)bs)cr)dq)dp)eo)fn)gn)hm)il)ik)jj)kj)li)mh)mg)nf)oe)pe)qd)qc)rb)sa)ta)u`)v_)v^)w])x])y\)z[)zZ){Y)|X)}X)~W)V)U)T)T)S)R)Q)P)O)O)N)M)L)K)K)J)I)H)G)G)F)E)D)C)B)B)A)@)?)>)>)=)<);):)9)9)8)7)6)5)5)4)3)2)1)1)0)/).)-),),)+)*)))()()')&)%)$)#)#)")!) ))))))))))))))))))))))) ) ) ) ) ) ) ))))))))))))(''&%$##"!           !"#$$%&'())* * ++,,--#.'.*/-/104071;1>2A2D3G3J3M|4Py4Su5Vr5Yo6\k6_h6be7eb7g_8j[8mX8oU9rR9uO9wL:zI:|G:D;A;>;;<9<6=3=0=.=+>)>&>$?!??@@@AAAA B BBCCCB@>< : 87531/.,*) '"%$#%"' )+-/024679; KKKKKJJJJIIII!I"H$H&H'H)G+G,G.G0F2F3F5F7E9E;~E=|E?{D@yDBwDDvDFtCHrCJpCLoBNmBPkBRiBThAWfAYdA[b@]`@_^@a]@d[?fY?hW?jU>mS>oQ>rO=tM=vK=yH<{F<~D;;:9:79592908-8+8)7&7$6!66554443 3 2211/+( % ! #&)*********** * * * * * *********************** *!*"*"*#*$*%*&*'*'*(*)***+*+*,*-*.*/*/*0*1*2*3*4*4*5*6*7*8*8*9*:*;*<*=*=*>*?*@*A*A*B*C*D*E*E*F*G*H*I*J*J*K*L*M*N*N*O*P*Q*R*S*S*T*U*V~*W}*W|*X{*Y{*Zz*[y*[x*\w*]w*^v*_u*`t*`s*as*br*cq*dp*do*en*fn*gm*hl*ik*ij*jj*ki*lh*mg*mf*ne*oe*pd*qc*qb*ra*sa*t`*u_*v^*v]*w]*x\*y[*zZ*zY*{X*|X*}W*~V*U*T*T*S*R*Q*P*O*O*N*M*L*K*K*J*I*H*G*G*F*E*D*C*B*B*A*@*?*>*>*=*<*;*:*9*9*8*7*6*5*5*4*3*2*1*1*0*/*.*-*,*,*+***)*(*(*'*&*%*$*#*#*"*!* *********************** * * * * * * ************)(''&%$##"!         !"#$$%&'())*+ + ,,--..#/'/*0-0114172;2>2A3D3G4J4M{5Px5Su5Vq6Yn6\k7_g7bd7ea8g^8j[9mX9oU9rR:uO:wL:zI;|F;C;@<=<;<8=5=3=0>->+>(?%?#? @@@AAAAB B BCCCCDB@>< : 87531/.,*) '"%$#&"( *,-/13568:; LLKKKKKJJJJJI!I"I$I%H'H)H+H,G.G0G2G3F5F7F9F;}E=|E?zE@xEBwDDuDFsDHrDJpCLnCNlCPkCRiBTgBWeBYcA[bA]`A_^@a\@dZ@fX@hV?jT?mR?oP>qN>tL>vJ=yH={F=~D+?+@+A+A+B+C+D+E+E+F+G+H+I+J+J+K+L+M+N+N+O+P+Q+R+S+S+T+U~+V}+W|+W{+X{+Yz+Zy+[x+[w+\w+]v+^u+_t+`s+`s+ar+bq+cp+do+dn+en+fm+gl+hk+ij+ij+ji+kh+lg+mf+me+ne+od+pc+qb+qa+ra+s`+t_+u^+v]+v]+w\+x[+yZ+zY+zX+{X+|W+}V+~U+T+T+S+R+Q+P+O+O+N+M+L+K+K+J+I+H+G+G+F+E+D+C+B+B+A+@+?+>+>+=+<+;+:+9+9+8+7+6+5+5+4+3+2+1+1+0+/+.+-+,+,+++*+)+(+(+'+&+%+$+#+#+"+!+ +++++++++++++++++++++++ + + + + + + ++++++++++++*)(''&%$##" !       ! "#$$%&'())*++ , ,-..//#0'0*0-1114272;3>3A4D4G4J~5M{5Pw6St6Vq7Ym7\j7_g8bd8e`9g]9jZ9mW:oT:rQ:uN;wK;zH;|E<B<@<==:=7=5>2>/>-?*?'?%@"@ @AAAABBB C CCCDDDB@> < : 87531/.,*)!'#%%#'"( *,.013578:< LLLLLKKKKJJJJ!J"I$I%I'I)H+H,H.H0H2G3G5G7G9~F;}F={F?yF@xEBvEDtEFsDHqDJoDLnDNlCPjCRhCTfCWeBYcB[aB]_A_]Aa[AdY@fW@hU@jS@mQ?oO?qM?tK>vI>yG>{E=~C=A=?<<<:<8;6;3:1:.:,9*9'9%8"8 7776655 5 44332/+( %!! $(++++++++++++ + + + + + +++++++++++++++++++++++ +!+"+"+#+$+%+&+'+'+(+)+*+++++,+-+.+/+/+0+1+2+3+4+4+5+6+7+8+8+9+:+;+<+<+=+>+?+@+A+A+B+C+D+E+E+F+G+H+I+J+J+K+L+M+N+N+O+P+Q+R+R+S+T~+U}+V|+W{+W{+Xz+Yy+Zx+[w+[w+\v+]u+^t+_s+`s+`r+aq+bp+co+dn+dn+em+fl+gk+hj+hj+ii+jh+kg+lf+me+me+nd+oc+pb+qa+qa+r`+s_+t^+u]+v]+v\+w[+xZ+yY+zX+zX+{W+|V+}U+~T+~T+S+R+Q+P+O+O+N+M+L+K+K+J+I+H+G+G+F+E+D+C+B+B+A+@+?+>+>+=+<+;+:+9+9+8+7+6+5+5+4+3+2+1+1+0+/+.+-+,+,+++*+)+(+(+'+&+%+$+#+#+"+!+ +++++++++++++++++++++++ + + + + + + +++++++++++++*)(''&%$## " !     ! " #$$%&'())*+,, - -..//0#0'1*1-2124373;3>4A4D5G5J}6Mz6Pw6Ss7Vp7Ym8\i8_f8bc9e`9g]:jY:mV:oS;rP;uM;wJ7>4>1?/?,?)@'@$@"AAABBBBCC C CDDDEDB@> < : 87531/.,* )!'#%%#'") +-.024679;< MMLLLLLKKKKKJ J"J$J%I'I)I+I,I.H0H2H3H5G7G9~G;|G={F>yF@wFBvFDtEFrEHpEJoELmDNkDPiDRhCTfCWdCYbC[`B]_B_]Ba[AdYAfWAhUAjS@mQ@oO@qM?tK?vI?yG>{D>~B>@=>=<=9<7<5<3;0;.:+:):'9$9"98877766 5 54442/+ ( %!" %(,,,,,,,,,,,, , , , , , ,,,,,,,,,,,,,,,,,,,,,,, ,!,",",#,$,%,&,&,',(,),*,+,+,,,-,.,/,/,0,1,2,3,4,4,5,6,7,8,8,9,:,;,<,<,=,>,?,@,A,A,B,C,D,E,E,F,G,H,I,J,J,K,L,M,N,N,O,P,Q,R,R,S~,T},U|,V{,W{,Wz,Xy,Yx,Zw,[w,[v,\u,]t,^s,_s,`r,`q,ap,bo,cn,dn,dm,el,fk,gj,hj,hi,ih,jg,kf,le,me,md,nc,ob,pa,qa,q`,r_,s^,t],u],v\,v[,wZ,xY,yX,zX,zW,{V,|U,}T,~T,~S,R,Q,P,O,O,N,M,L,K,K,J,I,H,G,G,F,E,D,C,B,B,A,@,?,>,>,=,<,;,:,9,9,8,7,6,5,5,4,3,2,1,1,0,/,.,-,,,,,+,*,),(,(,',&,%,$,#,#,",!, ,,,,,,,,,,,,,,,,,,,,,,, , , , , , , ,,,,,,,,,,,,,+*)(''&%$# # " !   ! " # $$%&'())*+,-- . .//001#1'2*2-2134374;4>5A5D6G6J}6My7Pv7Sr8Vo8Yl8\i9_e9bb:e_:g\:jY;mV;oS;rP><>9>6?3?1?.@+@)@&A$A!ABBBBCCCD D DDEEEDB@> < :87531/.,* )"'$%&#(") +-/13468:;= MMMMMLLLLLKKK K"J$J%J'J)J+I,I.I0I2H3H5H7H9}G;|G=zG>xG@wFBuFDsFFrFHpEJnELlENkEPiDRgDTeDWcCYbC[`C]^C_\BaZBdXBfVAhTAjRAmPAoN@qL@tJ@vH?yF?{D?~B>?>=>;=9=6=4<2<0;-;+;(:&:#:!99888776 6 65542/, ( %!# &)------------ - - - - - ----------------------- -!-"-"-#-$-%-&-&-'-(-)-*-+-+-,---.-/-/-0-1-2-3-4-4-5-6-7-8-8-9-:-;-<-<-=->-?-@-A-A-B-C-D-E-E-F-G-H-I-J-J-K-L-M-N-N-O-P-Q-R-R~-S}-T|-U{-V{-Wz-Wy-Xx-Yw-Zw-[v-[u-\t-]s-^s-_r-`q-`p-ao-bn-cn-dm-dl-ek-fj-gj-hi-hh-ig-jf-ke-le-md-mc-nb-oa-pa-q`-q_-r^-s]-t]-u\-v[-vZ-wY-xX-yX-zW-zV-{U-|T-}T-~S-~R-Q-P-O-O-N-M-L-K-K-J-I-H-G-G-F-E-D-C-B-B-A-@-?->->-=-<-;-:-9-9-8-7-6-5-5-4-3-2-1-1-0-/-.---,-,-+-*-)-(-(-'-&-%-$-#-#-"-!- ----------------------- - - - - - - ------------,,+*)(''&%$ # # " !  ! " # $ $%&'())*+,--. . //0011#2'2*3-3144475;5>5A6D6G7J|7My7Pu8Sr8Vn9Yk9\h9_e:ba:e^;g[;jX;mU@>>>;?8?5?3@0@-@+A(A&A#B BBBCCCDD D DEEEEFDB@> < :87531/.,*!)#'$%&#("* ,./13578:<= NNMMMMMLLLLLK K"K$K%K'J)J+J,J.I0I2I3I5H7~H9}H;{H=yG>xG@vGBtGDsFFqFHoFJnFLlENjEPhERgETeDWcDYaD[_D]]C_[CaYCdXBfVBhTBjRAmPAoNAqLAtI@vG@yE@{C?~A???=>:>8>6=4=1=/<,<*;(;%;#: ::998887 766552/, (%! # '*-........... . . . . . ....................... .!.".".#.$.%.&.&.'.(.).*.+.+.,.-..././.0.1.2.3.4.4.5.6.7.8.8.9.:.;.<.<.=.>.?.@.A.A.B.C.D.E.E.F.G.H.I.J.J.K.L.M.N.N.O.P.Q.R~.R}.S|.T{.U{.Vz.Wy.Wx.Xw.Yw.Zv.[u.[t.\s.]s.^r._q.`p.`o.an.bn.cm.dl.dk.ej.fj.gi.hh.hg.if.je.ke.ld.mc.mb.na.oa.p`.q_.q^.r].s].t\.u[.vZ.vY.wX.xX.yW.zV.zU.{T.|T.}S.~R.~Q.P.O.O.N.M.L.K.K.J.I.H.G.G.F.E.D.C.B.B.A.@.?.>.>.=.<.;.:.9.9.8.7.6.5.5.4.3.2.1.1.0./...-.,.,.+.*.).(.(.'.&.%.$.#.#.".!. ....................... . . . . . . ............-,,+*)(''&% $ # # " !   ! " # $ $ %&'())*+,-../ / 001122#3'3*4-4144575;6>6A7D7G7J{8Mx8Pt9Sq9Vn9Yj:\g:_d;ba;e^;gZzF>|C>@?=?:?7@5@2@/A-A*A'B%B"B BCCCDDDD E EEFFFFDB@ > < :87531/.,*!)#'%%'#)"+ ,.024579;<> NNNNNMMMMMLLL L"L$K%K'K)K+J,J.J0J2J3I5I7~I9|I;zH=yH>wH@vHBtGDrGFpGHoGJmFLkFNjFPhERfETdEWbEY`D[_D]]D_[DaYCdWCfUChSBjQBmOBoMAqKAtIAvGAyE@{B@~@@>?5>3>1=.=,=)<'<%;"; ;:::998 8 777652/, (%!!$ '+./////////// / / / / / /////////////////////// /!/"/"/#/$/%/&/&/'/(/)/*/+/+/,/-/./////0/1/2/3/3/4/5/6/7/8/8/9/:/;//?/@/A/A/B/C/D/E/E/F/G/H/I/I/J/K/L/M/N/N/O/P/Q~/R}/R|/S{/T{/Uz/Vy/Wx/Ww/Xw/Yv/Zu/[t/[s/\s/]r/^q/_p/_o/`n/an/bm/cl/dk/dj/ej/fi/gh/hg/hf/ie/je/kd/lc/mb/ma/na/o`/p_/q^/q]/r]/s\/t[/uZ/uY/vX/wX/xW/yV/zU/zT/{T/|S/}R/~Q/~P/O/O/N/M/L/K/K/J/I/H/G/G/F/E/D/C/B/B/A/@/?/>/>/=/7A7D8G~8J{9Mw9Pt9Sp:Vm:Yj:\f;_c;b`uK>wH>zE?|B???<@:@7@4A1A/A,B)B'B$B"CCCDDDDEE E FFFFGFDB@ > <:87531/., *")$'%%'#)"+ -/124689;=> OONNNNNNMMMML L"L$L%L'K)K+K,K.K0J2J3J5J7}I9|I;zI=xI>wH@uHBsHDrHFpGHnGJlGLkGNiFPgFReFTdFWbEY`E[^E]\D_ZDaXDdVDfTChRCjPCmNBoLBqJBtHAvFAyDA{BA~@@=@;@9?7?4?2>0>.>+=)=&<$0?0@0A0A0B0C0D0E0E0F0G0H0I0I0J0K0L0M0N0N0O0P~0Q}0R|0R{0S{0Tz0Uy0Vx0Ww0Ww0Xv0Yu0Zt0[s0[s0\r0]q0^p0_o0_n0`n0am0bl0ck0dj0dj0ei0fh0gg0hf0he0ie0jd0kc0lb0ma0ma0n`0o_0p^0q]0q]0r\0s[0tZ0uY0uX0vX0wW0xV0yU0zT0zT0{S0|R0}Q0~P0~O0O0N0M0L0K0K0J0I0H0G0G0F0E0D0C0B0B0A0@0?0>0>0=0<0;0:090908070605050403020101000/0.0-0,0,0+0*0)0(0(0'0&0%0$0#0#0"0!0 00000000000000000000000 0 0 0 0 0 0 000000000000/.-,,+*)('' & % $ # # "!   !" # $ $ % & '())*+,-../00 1 122334#4'5*5-6164677;7>8A8D8G}9Jz9Mv:Ps:Sp:Vl;Yi;\f<_coP>rM>uJ?wG?zD?|A@>@<@9A6A3A1B.B+B)C&C$C!CDDDEEEEF F FFGGGFDB@ > <:87531/., *")$'&%(#*", -/13568:<=? OOOOONNNNNMMM M"M$L%L'L)L+L,K.K0K2K3J5~J7}J9{J;yI=xI>vI@tIBsHDqHFoHHnHJlGLjGNhGPgGReFTcFVaFY_F[]E]\E_ZEaXEdVDfTDhRDjPCmNCoLCqJBtHBvEByCB{AA~?A=A;@8@6@4?2?/?->*>(>&=#=!<<<;;;:: 9 998862/ , (%!"& ),000000000000 0 0 0 0 0 00000000000000000000000 0!0"0"0#0$0%0&0&0'0(0)0*0+0+0,0-0.0/0/0001020303040506070808090:0;0<0<0=0>0?0@0A0A0B0C0D0E0E0F0G0H0I0I0J0K0L0M0N0N0O~0P}0Q|0R{0R{0Sz0Ty0Ux0Vw0Ww0Wv0Xu0Yt0Zs0[s0[r0\q0]p0^o0_n0_n0`m0al0bk0cj0dj0di0eh0fg0gf0he0he0id0jc0kb0la0ma0m`0n_0o^0p]0q]0q\0r[0sZ0tY0uX0uX0vW0wV0xU0yT0zT0zS0{R0|Q0}P0~O0~O0N0M0L0K0K0J0I0H0G0G0F0E0D0C0B0B0A0@0?0>0>0=0<0;0:090908070605050403020101000/0.0-0,0,0+0*0)0(0(0'0&0%0$0#0#0"0!0 00000000000000000000000 0 0 0 0 0 0 0000000000000/.-,,+*)(' ' & % $ # #"!   !"# $ $ % & ' ())*+,-../011 2 233444#5'5*6-6174778;8>8A9D9G}:Jy:Mv:Pr;So;VljU>mR>oO?rL?uI?wF@zD@|A@>A;A8A6B3B0B-C+C(C&C#D DDEEEEFF F GGGGHHFDB@ > <:87531/.,!*#)%''%(#*", .023579:<>? PPPOOOOONNNNN M"M$M%M'L)L+L,L.L0K2K3K5~K7|J9zJ;yJ=wJ>vJ@tIBrIDpIFoIHmHJkHLjHNhHPfGRdGTbGVaFY_F[]F][F_YEaWEdUEfSEhQDjODmMDoKCqICtGCvEByCB{AB~>B%>"> ==<<<;;; ::99862/ ,(%! #' *-111111111111 1 1 1 1 1 11111111111111111111111 1!1"1"1#1$1%1&1&1'1(1)1*1+1+1,1-1.1/1/1011121313141516171818191:1;1<1<1=1>1?1@1A1A1B1C1D1E1E1F1G1H1I1I1J1K1L1M1N1N~1O}1P|1Q{1R{1Rz1Sy1Tx1Uw1Vw1Wv1Wu1Xt1Ys1Zs1[r1[q1\p1]o1^n1_n1_m1`l1ak1bj1cj1di1dh1eg1ff1ge1he1hd1ic1jb1ka1la1m`1m_1n^1o]1p]1q\1q[1rZ1sY1tX1uX1uW1vV1wU1xT1yT1zS1zR1{Q1|P1}O1~O1~N1M1L1K1K1J1I1H1G1G1F1E1D1C1B1B1A1@1?1>1>1=1<1;1:191918171615151413121111101/1.1-1,1,1+1*1)1(1(1'1&1%1$1#1#1"1!1 11111111111111111111111 1 1 1 1 1 1 11111111111110/.-,,+*)( ' ' & % $ ##"!   !"#$ $ % & ' ( ))*+,-../0112 2 334455#6'6*7-7174878;9>9A:D:G|:Jx;Mu;Pr;Sne[>gX>jU?mR?oO?rL@uI@wF@zCA|@A=A:B8B5B2C/C-C*C(D%D"D EEEEFFFG G GGHHHHFDB @ > <:87531/.,!*#)%''%)#+"- .024679;=>@ PPPPPOOOOONNN N"N$M%M'M)M+M,L.L0L2L3K5}K7|K9zK;xK=wJ>uJ@sJBrJDpIFnIHlIJkILiHNgHPeHRdHTbGV`GY^G[\G]ZF_XFaVFdUEfSEhQEjOEmMDoJDqHDtFCvDCyBC{@C~>B>===<<< ; ;:::962/ ,(%!!$' +.122222222222 2 2 2 2 2 22222222222222222222222 2!2"2"2#2$2%2&2&2'2(2)2*2*2+2,2-2.2/2/2021222323242526272828292:2;2<2<2=2>2?2@2@2A2B2C2D2E2E2F2G2H2I2I2J2K2L2M2N~2N}2O|2P{2Q{2Rz2Ry2Sx2Tw2Uw2Vv2Vu2Wt2Xs2Ys2Zr2[q2[p2\o2]n2^n2_m2_l2`k2aj2bj2ci2dh2dg2ef2fe2ge2hd2hc2ib2ja2ka2l`2l_2m^2n]2o]2p\2q[2qZ2rY2sX2tX2uW2uV2vU2wT2xT2yS2zR2zQ2{P2|O2}O2~N2~M2L2K2K2J2I2H2G2G2F2E2D2C2B2B2A2@2?2>2>2=2<2;2:292928272625252423222121202/2.2-2,2,2+2*2)2(2(2'2&2%2$2#2#2"2!2 22222222222222222222222 2 2 2 2 2 2 222222222222110/.-,,+*) ( ' ' & % $##"!   !"#$$ % & ' ( ) )*+,-../01223 3 445566#7'7*7-8184979;9>:A:D;G{;Jx;Mt_`>b]>eZ?gW?jT?mQ@oN@rK@uHAwEAzBA|?B=B:B7C4C2C/D,D*D'D$E"EEFFFFGGG G HHHHIHFDB @ ><:87531/. ,"*$)&'(%)#+"- /13468:;=?@ QQQPPPPPOOOOO N"N$N%N'N)M+M,M.M0L2L3~L5}L7{L9yK;xK=vK>tK@sJBqJDoJFnJHlIJjILhINgIPeHRcHTaHV_HY]G[\G]ZG_XGaVFdTFfRFhPFjNEmLEoJEqHDtFDvDDyAC{?C~=C;C9B6B4B2A0A-A+@(@&@$?!??>>===< < <;;:962 / ,(%""%( +/233333333333 3 3 3 3 3 33333333333333333333333 3!3"3"3#3$3%3&3&3'3(3)3*3*3+3,3-3.3/3/3031323333343536373838393:3;3<3<3=3>3?3@3@3A3B3C3D3E3E3F3G3H3I3I3J3K3L3M~3N}3N|3O{3P{3Qz3Ry3Rx3Sw3Tw3Uv3Vu3Vt3Ws3Xs3Yr3Zq3[p3[o3\n3]n3^m3_l3_k3`j3aj3bi3ch3dg3df3ee3fe3gd3hc3hb3ia3ja3k`3l_3l^3m]3n]3o\3p[3qZ3qY3rX3sX3tW3uV3uU3vT3wT3xS3yR3zQ3zP3{O3|O3}N3~M3~L3K3K3J3I3H3G3G3F3E3D3C3B3B3A3@3?3>3>3=3<3;3:393938373635353433323131303/3.3-3,3,3+3*3)3(3(3'3&3%3$3#3#3"3!3 33333333333333333333333 3 3 3 3 3 3 3333333333332110/.-,,+* ) ( ' ' & %$##"!   !"#$$% & ' ( ) ) *+,-../012234 4 555667#7'8*8-919497:;:>;A;D~;GzYf>\c>_`?b]?eY?gV@jS@mP@oMArJAuGAwDBzBB|?B<:87531/.!,"*$)&'(%*#,". 013578:<>?A QQQQQPPPPPPOO O"O$O%N'N)N*N,M.M0M2M3~M5|L7zL9yL;wL=vK>tK@rKBpKDoKFmJHkJJjJLhJNfIPdIRbITaIV_HY]H[[H]YH_WGaUGdSGfQFhOFjMFmKFoIEqGEtEEvCDyAD{?D~>== = <<<;962 / ,(%""&) ,/344444444444 4 4 4 4 4 44444444444444444444444 4!4"4"4#4$4%4&4&4'4(4)4*4*4+4,4-4.4/4/4041424343444546474848494:4;4<4<4=4>4?4@4@4A4B4C4D4E4E4F4G4H4I4I4J4K4L~4M}4N|4N{4O{4Pz4Qy4Rx4Rw4Sw4Tv4Uu4Vt4Vs4Ws4Xr4Yq4Zp4[o4[n4\n4]m4^l4_k4_j4`j4ai4bh4cg4df4de4ee4fd4gc4hb4ha4ia4j`4k_4l^4l]4m]4n\4o[4pZ4qY4qX4rX4sW4tV4uU4uT4vT4wS4xR4yQ4zP4zO4{O4|N4}M4~L4~K4K4J4I4H4G4G4F4E4D4C4B4B4A4@4?4>4>4=4<4;4:494948474645454443424141404/4.4-4,4,4+4*4)4(4(4'4&4%4$4#4#4"4!4 44444444444444444444444 4 4 4 4 4 4 44444444444432110/.-,,+ * ) ( ' ' &%$##"!   !"#$$%& ' ( ) ) * +,-../0122344 5 566778#8'8*9-91:4:7;;;>;ASl>Vi>Ye?\b?__?b\@eY@gV@jSAmPAoMArJBuGBwDBzAC|>C;C8D6D3D0E.E+E(E&F#F!FGGGGHHH H IIIIJJHFD B @ ><:87531/.!,#*%)'')%+#,". 024579;<>@A RRRQQQQQPPPPP O"O$O%O'O)N*N,N.N0N2M3}M5{M7zM9xL;wL
    sL@rLBpKDnKFmKHkKJiJLgJNeJPdJRbIT`IV^IY\I[ZH]YH_WHaUHcSGfQGhOGjMFmKFoIFqGFtDEvBEy@E{>D~> ===<<962 /,(%" #&* -0455555555555 5 5 5 5 5 55555555555555555555555 5!5"5"5#5$5%5&5&5'5(5)5*5*5+5,5-5.5/5/5051525353545556575858595:5;5<5<5=5>5?5@5@5A5B5C5D5E5E5F5G5H5I5I5J5K~5L}5M|5N{5N{5Oz5Py5Qx5Rw5Rw5Sv5Tu5Ut5Vs5Vr5Wr5Xq5Yp5Zo5[n5[n5\m5]l5^k5_j5_j5`i5ah5bg5cf5de5de5ed5fc5gb5ha5ha5i`5j_5k^5l]5l]5m\5n[5oZ5pY5qX5qX5rW5sV5tU5uT5uT5vS5wR5xQ5yP5zO5zO5{N5|M5}L5~K5~K5J5I5H5G5G5F5E5D5C5B5B5A5@5?5>5>5=5<5;5:595958575655555453525151505/5.5-5,5,5+5*5)5(5(5'5&5%5$5#5#5"5!5 55555555555555555555555 5 5 5 5 5 5 555555555555432110/.-,, + * ) ( ' '&%$##"!   !"#$$%&' ( ) ) * + ,-../01223455 6 677888#9'9*:-:1;4;7;;<>Mr>Po>Sk?Vh?Ye?\b@_^@b[@eXAgUAjRAmOBoLBrIBuFCwCCz@C|=D;D8D5E2E0E-E*F(F%F"G GGGHHHHI I IIJJJJHFD B @ ><:87531/ .",$*%)'')%+#-"/ 124689;=?@B RRRRRRQQQQQPP P"P$P%O'O)O*O,O.N0N1~N3|N5{N7yM9xM;vMsL@qLBoLDnLFlKHjKJhKLgKNeKPcJRaJT_JV^JY\I[ZI]XI_VHaTHcRHfPHhNGjLGmJGoHGqFFtDFvBFy@E{=E};E9E7D4D2D0C.C+C)B&B$B"AAA@@@?? ? >>==<963 /,)%"!$'* .1455555555555 5 5 5 5 5 55555555555555555555555 5!5!5"5#5$5%5&5&5'5(5)5*5*5+5,5-5.5/5/5051525353545556575758595:5;5<5<5=5>5?5@5@5A5B5C5D5E5E5F5G5H5I5I5J~5K}5L|5M{5M{5Nz5Oy5Px5Qw5Rw5Rv5Su5Tt5Us5Vr5Vr5Wq5Xp5Yo5Zn5[n5[m5\l5]k5^j5_j5_i5`h5ag5bf5ce5ce5dd5ec5fb5ga5ha5h`5i_5j^5k]5l\5l\5m[5nZ5oY5pX5qX5qW5rV5sU5tT5uT5uS5vR5wQ5xP5yO5yO5zN5{M5|L5}K5~K5~J5I5H5G5G5F5E5D5C5B5B5A5@5?5>5>5=5<5;5:595958575655555453525151505/5.5-5,5,5+5*5)5(5(5'5&5%5$5#5#5"5!5 55555555555555555555555 5 5 5 5 5 5 5555555555555432110/.-, , + * ) ( ''&%$##"!   !"#$$%&'( ) ) * + , -../012234566 7 778899#:':*:-;1;4<7<;<>=A=D|>Gx>Ju>Mq?Pn?Sk?Vg@Yd@\a@_^Ab[AeWAgTBjQBmNBoKCrHCuECwBDz@D|=D:E7E4E2F/F,F*F'G$G"GGHHHIIII J JJJKKJHFD B @><:87531/ .",$*&)('*%,#-"/ 13568:<=?AC SSSRRRRRQQQQQ Q"P$P%P'P)P*O,O.O0O1~N3|N5zN7yN9wN;uMrM@pMBoMDmLFkLHjLJhLLfKNdKPcKRaKT_JV]JY[J[YJ]WI_UIaSIcQIfOHhMHjKHmIGoGGqEGtCGvAFy?F{=F};E8E6E4E2D/D-D+C(C&C#B!BBAAA@@@ ? ??>><96 3 /,)%"!%(+ .2566666666666 6 6 6 6 6 66666666666666666666666 6!6!6"6#6$6%6&6&6'6(6)6*6*6+6,6-6.6/6/6061626363646566676768696:6;6<6<6=6>6?6@6@6A6B6C6D6E6E6F6G6H6I6I~6J}6K|6L{6M{6Mz6Ny6Ox6Pw6Qw6Rv6Ru6St6Ts6Ur6Vr6Vq6Wp6Xo6Yn6Zn6[m6[l6\k6]j6^j6_i6_h6`g6af6be6ce6cd6dc6eb6fa6ga6h`6h_6i^6j]6k\6l\6l[6mZ6nY6oX6pX6qW6qV6rU6sT6tT6uS6uR6vQ6wP6xO6yO6yN6zM6{L6|K6}K6~J6~I6H6G6F6F6E6D6C6B6B6A6@6?6>6>6=6<6;6:696968676665656463626161606/6.6-6,6,6+6*6)6(6(6'6&6%6$6#6#6"6!6 66666666666666666666666 6 6 6 6 6 6 66666666666655432110/.- , , + * ) (''&%$##"!   !"#$$%&'() ) * + , - ../0122345667 7 8899::#:';*;-<1<4<7=;=>>A~>D{>Gw?Jt?Mq?Pm@Sj@Vg@YcA\`A_]BbZBeWBgTBjQCmNCoKCrHDuEDwBDz?E|<:87531/!.#,%*')('*%,#."0 23579;<>@AC SSSSSSRRRRRQQ Q"Q$Q%P'P)P*P,P.O0O1}O3{O5zO7xN9wN;uNrN@pMBnMDmMFkMHiLJgLLfLNdLPbKR`KT^KV\KY[J[YJ]WJ_UJaSIcQIfOIhMIjKHmIHoGHqEHtCGv@Gy>G{7?7@7@7A7B7C7D7E7E7F7G7H7I~7I}7J|7K{7L{7Mz7My7Nx7Ow7Pw7Qv7Ru7Rt7Ss7Tr7Ur7Vq7Vp7Wo7Xn7Yn7Zm7[l7[k7\j7]j7^i7_h7_g7`f7ae7be7cd7cc7db7ea7fa7g`7h_7h^7i]7j\7k\7l[7lZ7mY7nX7oX7pW7qV7qU7rT7sT7tS7uR7uQ7vP7wO7xO7yN7yM7zL7{K7|K7}J7~I7~H7G7F7F7E7D7C7B7B7A7@7?7>7>7=7<7;7:797978777675757473727170707/7.7-7,7,7+7*7)7(7(7'7&7%7$7#7#7"7!7 77777777777777777777777 7 7 7 7 7 7 777777777777655432110/. - , , + * )(''&%$##"!   !"#$$%&'()) * + , - . ./01223456778 8 999::;#;'<*<-<1=4=7>;>>>A~?Dz?Gw?Js@Mp@Pm@SiAVfAYcB\_B_\BbYCeVCgSCjPDmMDoJDrGDuDEwAEz>E|;F9F6F3G0G.G+G(H&H#H!HIIIJJJJ K KKKLLLJHF D B @><:87531/!.#,%*'))'+%-#/"0 24689;=>@BD TTTSSSSSSRRRR R"Q$Q%Q'Q)Q*P,P.P0~P1|P3{O5yO7xO9vO;tOqN@oNBnNDlMFjMHhMJgMLeMNcLPaLR`LT^LV\KYZK[XK]VK_TJaRJcPJfNJhLIjJImHIoFHqDHtBHv@Hy>G{;G}9G7F5F3F0F.E,E)E'D$D"D CCCBBBA A A@@@?<96 3/,)%" #&)- 03788888888888 8 8 8 8 8 88888888888888888888888 8!8!8"8#8$8%8&8&8'8(8)8*8*8+8,8-8.8/8/8081828383848586878788898:8;8<8<8=8>8?8@8@8A8B8C8D8E8E8F8G8H~8I}8I|8J{8K{8Lz8My8Mx8Nw8Ow8Pv8Qu8Rt8Rs8Sr8Tr8Uq8Vp8Vo8Wn8Xn8Ym8Zl8[k8[j8\j8]i8^h8_g8_f8`e8ae8bd8cc8cb8da8ea8f`8g_8h^8h]8i\8j\8k[8lZ8lY8mX8nX8oW8pV8qU8qT8rT8sS8tR8uQ8uP8vO8wO8xN8yM8yL8zK8{K8|J8}I8~H8~G8F8F8E8D8C8B8B8A8@8?8>8>8=8<8;8:898988878685858483828180808/8.8-8,8,8+8*8)8(8(8'8&8%8$8#8#8"8!8 88888888888888888888888 8 8 8 8 8 8 8888888888887655432110/ . - , , + *)(''&%$##"!   !"#$$%&'())* + , - . . /012234567789 9 9::;;<#<'<*=-=1>4>7>;?>?A}?Dy@Gv@JsAMoAPlASiBVeBYbB\_C_\CbXCeUDgRDjODmLEoIErFEuCEw@Fz>F|;F8G5G2G0G-H*H(H%I"I IIJJJJKK K KLLLLLJHF D B@><:87531 /".$,&*())'+%-#/"1 3468:<=?ABD TTTTTTSSSSSRR R"R$R%R'Q)Q*Q,Q.Q0}P1|P3zP5yP7wP9uO;tOpO@oNBmNDkNFjNHhNJfMLdMNcMPaMR_LT]LV[LXYL[WK]VK_TKaRKcPJfNJhLJjJJmHIoEIqCItAIv?Hx=H{;H}9G6G4G2G0F-F+F)E&E$E!DDDCCCBB B AAA@@<96 3/,)%"!$'*- 14899999999999 9 9 9 9 9 99999999999999999999999 9!9!9"9#9$9%9&9&9'9(9)9*9*9+9,9-9.9.9/9091929393949596979798999:9;9<9<9=9>9?9@9@9A9B9C9D9D9E9F9G~9H}9I|9I{9J{9Kz9Ly9Mx9Mw9Nw9Ov9Pu9Qt9Rs9Rr9Sr9Tq9Up9Vo9Vn9Wn9Xm9Yl9Zk9Zj9[j9\i9]h9^g9_f9_e9`e9ad9bc9cb9ca9da9e`9f_9g^9h]9h\9i\9j[9kZ9lY9lX9mX9nW9oV9pU9pT9qT9rS9sR9tQ9uP9uO9vO9wN9xM9yL9yK9zK9{J9|I9}H9~G9~F9F9E9D9C9B9B9A9@9?9>9>9=9<9;9:999998979695959493929190909/9.9-9,9,9+9*9)9(9(9'9&9%9$9#9#9"9!9 99999999999999999999999 9 9 9 9 9 9 99999999999987655432110 / . - , , +*)(''&%$##"!   !"#$$%&'())*+ , - . . / 0122345677899 : :;;;<<#='=*>->1>4?7?;?>@A|@DyAGuAJrAMnBPkBShBVeCYaC\^C_[DbXDeUDgREjOEmKEoIErFFuCFw@Fz=G|:G7G5H2H/H,H*I'I$I"IJJJJKKKK L LLLMMLJHF D B@><:87531 /".$,&*()*',%.#0"1 3579:<>?ACE UUUTTTTTTSSSS S"R$R%R'R)R*Q,Q.~Q0}Q1{Q3zP5xP7wP9uP;sPpO@nOBmODkOFiNHgNJfNLdNNbMP`MR^MT\MV[MXYL[WL]UL_SLaQKcOKfMKhKKjIJmGJoEJqCItAIv?Ix9?9@9@9A9B9C9D9D9E9F~9G}9H|9I{9I{9Jz9Ky9Lx9Mw9Mw9Nv9Ou9Pt9Qs9Rr9Rr9Sq9Tp9Uo9Vn9Vn9Wm9Xl9Yk9Zj9Zj9[i9\h9]g9^f9_e9_e9`d9ac9bb9ca9ca9d`9e_9f^9g]9h\9h\9i[9jZ9kY9lX9lX9mW9nV9oU9pT9pT9qS9rR9sQ9tP9uO9uO9vN9wM9xL9yK9yK9zJ9{I9|H9}G9~F9~F9E9D9C9B9B9A9@9?9>9>9=9<9;9:999998979695959493929190909/9.9-9,9,9+9*9)9(9(9'9&9%9$9#9#9"9!9 99999999999999999999999 9 9 9 9 9 9 99999999999998765543211 0 / . - , ,+*)(''&%$##"!   !"#$$%&'())*+, - . . / 0 12234567789:: ; ;;<<==#>'>*>-?1?4?7@;@>AA|ADxAGuBJqBMnBPjCSgCVdCYaD\]D_ZDbWEeTEgQEjNFmKFoHFrEFuBGw?Gz<:87531!/#.%,'*))+',%.#0"2 4679;=>@BCE UUUUUUTTTTTTS S"S$S%S'R)R*R,R.~R0|Q1{Q3yQ5xQ7vQ9tP;sPoP@nPBlODjOFiOHgOJeOLcNNaNP`NR^NT\MVZMXXM[VM]TL_RLaPLcNLfLKhJKjHKmFKoDJqBJt@Jv>Jx:?:@:@:A:B:C:D:D:E~:F}:G|:H{:I{:Iz:Jy:Kx:Lw:Mw:Mv:Nu:Ot:Ps:Qr:Rr:Rq:Sp:To:Un:Vn:Vm:Wl:Xk:Yj:Zj:Zi:[h:\g:]f:^e:_e:_d:`c:ab:ba:ca:c`:d_:e^:f]:g\:h\:h[:iZ:jY:kX:lX:lW:mV:nU:oT:pT:pS:qR:rQ:sP:tO:uO:uN:vM:wL:xK:yK:yJ:zI:{H:|G:}F:~F:~E:D:C:B:B:A:@:?:>:>:=:<:;:::9:9:8:7:6:5:5:4:3:2:1:0:0:/:.:-:,:,:+:*:):(:(:':&:%:$:#:#:":!: ::::::::::::::::::::::: : : : : : : :::::::::::::9876554321 1 0 / . - ,,+*)(''&%$##"!   !"#$$%&'())*+,- . . / 0 1 2234567789:;; ; <<===>#>'?*?-?1@4@7A;A>~AA{BDwBGtBJpCMmCPjCSfDVcDY`D\]E_YEbVEeSFgPFjMFmJGoGGrDGuAGw>Hz<:8753 1"/#.%,'*))+'-%/#1"2 468:;=?ABDF VVVUUUUUUTTTT T"T$S%S'S)S*S,R.}R0|R1zR3yR5wQ7uQ9tQ;rQoP@mPBkPDjPFhPHfOJdOLcONaOP_NR]NT[NVYNXXM[VM]TM_RMaPMcNLfLLhJLjHLmFKoDKqBKt?Jv=Jx;J{9J}7I4I2I0I.H+H)H'G$G"GGFFFEEE D DDCCC@<9 630,)%" #&),0 3 6:;;;;;;;;;;; ; ; ; ; ; ;;;;;;;;;;;;;;;;;;;;;;; ;!;!;";#;$;%;&;&;';(;);*;*;+;,;-;.;.;/;0;1;2;3;3;4;5;6;7;7;8;9;:;;;<;<;=;>;?;@;@;A;B;C;D;D~;E};F|;G{;H{;Iz;Iy;Jx;Kw;Lw;Mv;Mu;Nt;Os;Pr;Qr;Rq;Rp;So;Tn;Un;Vm;Vl;Wk;Xj;Yj;Zi;Zh;[g;\f;]e;^e;_d;_c;`b;aa;ba;c`;c_;d^;e];f\;g\;h[;hZ;iY;jX;kX;lW;lV;mU;nT;oT;pS;pR;qQ;rP;sO;tO;uN;uM;vL;wK;xK;yJ;yI;zH;{G;|F;}F;}E;~D;C;B;B;A;@;?;>;>;=;<;;;:;9;9;8;7;6;5;5;4;3;2;1;0;0;/;.;-;,;,;+;*;);(;(;';&;%;$;#;#;";!; ;;;;;;;;;;;;;;;;;;;;;;; ; ; ; ; ; ; ;;;;;;;;;;;;::987655432 1 1 0 / . -,,+*)(''&%$##"!   !"#$$%&'())*+,-. . / 0 1 2 234567789:;;< < ===>>?#?'?*@-@1A4A7A;B>~BAzBDwCGsCJpCMlDPiDSfDVbEY_E\\E_YFbVFeSFgOGjLGmIGoFHrDHuAHw>Hz;I|8I5I3J0J-J*J(K%K#K KLLLLMMM M NNNNNNLJH F DB@><:8753 1"/$.&,(**),'.%/#1"3 578:<>?ACDF VVVVVVUUUUUUT T"T$T%T'S)S*S,~S.}S0{S1zR3xR5wR7uR9sR;rQnQ@mQBkQDiPFgPHfPJdPLbON`OP^OR]OT[OVYNXWN[UN]SN_QMaOMcMMfKMhILjGLmELoCLqAKt?Kv=Kx:K{8J}6J4J2J/I-I+I(H&H$H!GGGGFFFE E EDDDC@=9 630,)%" $'*-1 4 7;<<<<<<<<<<< < < < < < <<<<<<<<<<<<<<<<<<<<<<< <><=<<<;<:<9<9<8<7<6<5<5<4<3<2<1<0<0>???#@'@*A-A1A4B7B;B>}CAyCDvCGrDJoDMlDPhESeEVbEY^F\[F_XFbUGeRGgOGjLHmIHoFHrCHu@Iw=Iz:I|7J5J2J/J,K*K'K%K"LLLLMMMMN N NNOOONLJH F DB@><:8753!1#/%.',(**),'.%0#2"4 579;<>@BCEG WWWVVVVVVUUUU U"U$T%T'T)T*T,~S.|S0{S1yS3xS5vS7tR9sR;qRnR@lQBjQDiQFgQHePJcPLaPN`PP^PR\OTZOVXOXVO[TN]SN_QNaONcMNfKMhIMjGMlDMoBLq@Lt>Lv=?=@=@=A=B=C~=D}=D|=E{=F{=Gz=Hy=Ix=Iw=Jw=Kv=Lu=Mt=Ms=Nr=Or=Pq=Qp=Qo=Rn=Sn=Tm=Ul=Vk=Vj=Wj=Xi=Yh=Zg=Zf=[e=\e=]d=^c=_b=_a=`a=a`=b_=c^=c]=d\=e\=f[=gZ=gY=hX=iX=jW=kV=lU=lT=mT=nS=oR=pQ=pP=qO=rO=sN=tM=uL=uK=vK=wJ=xI=yH=yG=zF={F=|E=}D=}C=~B=B=A=@=?=>=>===<=;=:=9=9=8=7=6=5=5=4=3=2=1=0=0=/=.=-=,=,=+=*=)=(=(='=&=%=$=#=#="=!= ======================= = = = = = = ============<;::9876554 3 2 1 1 0 /.-,,+*)(''&%$##"!   !"#$$%&'())*+,-../ 0 1 2 2 3 4567789:;<<== > >???@@#A'A*A-B1B4B7C;C>|DAyDDuDGrEJnEMkEPhFSdFVaFY^F\[G_WGbTGeQHgNHjKHmHIoEIrBIu?Iw<:8753!1#/%.',)*+)-'/%0#2"4 689;=?@BDEG WWWWWWVVVVVVU U"U$U%U'U)T*T,}T.|T0zT1yS3wS5uS7tS9rS;pRmR@kRBjRDhQFfQHdQJcQLaQN_PP]PR[PTZPVXPXVO[TO]RO_POaNNcLNfJNhHNjFMlDMoBMq@Mt>Lv;Lx9L{7L}5K3K0K.K,J)J'J%I"I IIHHHGGG F FFEEC@= 9 630,)&""%(+/2 5 9<>>>>>>>>>>> > > > > > >>>>>>>>>>>>>>>>>>>>>>> >!>!>">#>$>%>%>&>'>(>)>*>*>+>,>->.>.>/>0>1>2>3>3>4>5>6>7>7>8>9>:>;>;><>=>>>?>@>@>A>B~>C}>D|>D{>E{>Fz>Gy>Hx>Iw>Iw>Jv>Ku>Lt>Ms>Mr>Nr>Oq>Pp>Qo>Qn>Rn>Sm>Tl>Uk>Vj>Vj>Wi>Xh>Yg>Zf>Ze>[e>\d>]c>^b>_a>_a>``>a_>b^>c]>c\>d\>e[>fZ>gY>gX>hX>iW>jV>kU>lT>lT>mS>nR>oQ>pP>pO>qO>rN>sM>tL>uK>uK>vJ>wI>xH>yG>yF>zF>{E>|D>}C>}B>~B>A>@>?>>>>>=><>;>:>9>9>8>7>6>5>5>4>3>2>1>0>0>/>.>->,>,>+>*>)>(>(>'>&>%>$>#>#>">!> >>>>>>>>>>>>>>>>>>>>>>> > > > > > > >>>>>>>>>>>>=<;::987655 4 3 2 1 1 0/.-,,+*)(''&%$##"!   !"#$$%&'())*+,-../0 1 2 2 3 4 567789:;<<=>> ? ??@@AA#A'B*B-C1C4C7D;D>{DAxEDtEGqEJmFMjFPgFSdGV`GY]G\ZG_WHbTHePHgMIjJImGIoDJrBJu?Jw<:875 3"1$/&.(,**+)-'/%1#3"5 68:<=?ACDFH XXXWWWWWWVVVV V"V$U%U'U)U*~U,}U.{T0zT1xT3vT5uT7sS9rS:pSmS@kRBiRDgRFfRHdRJbQL`QN_QP]QR[QTYPVWPXUP[SP]QO_OOaMOcKOfIOhGNjENlCNoANq?Mt=Mv;Mx9M{6L}4L2L0K-K+K)K&J$J"JJIIIHHH G GGGFFC@= 9 630,)&"#&),03 6 :=>>>>>>>>>>> > > > > > >>>>>>>>>>>>>>>>>>>>>>> >!>!>">#>$>%>%>&>'>(>)>*>*>+>,>->.>.>/>0>1>2>3>3>4>5>6>7>7>8>9>:>;>;><>=>>>?>@>@>A~>B}>C|>D{>D{>Ez>Fy>Gx>Hw>Iw>Iv>Ju>Kt>Ls>Mr>Mr>Nq>Op>Po>Qn>Qn>Rm>Sl>Tk>Uj>Vj>Vi>Wh>Xg>Yf>Ze>Ze>[d>\c>]b>^a>^a>_`>`_>a^>b]>c\>c\>d[>eZ>fY>gX>gX>hW>iV>jU>kT>lT>lS>mR>nQ>oP>pO>pO>qN>rM>sL>tK>tK>uJ>vI>wH>xG>yF>yF>zE>{D>|C>}B>}B>~A>@>?>>>>>=><>;>:>9>9>8>7>6>5>5>4>3>2>1>0>0>/>.>->,>,>+>*>)>(>(>'>&>%>$>#>#>">!> >>>>>>>>>>>>>>>>>>>>>>> > > > > > > >>>>>>>>>>>>>=<;::98765 5 4 3 2 1 10/.-,,+*)(''&%$##"!   !"#$$%&'())*+,-../01 2 2 3 4 5 67789:;<<=>?? ? @@AAAB#B'C*C-C1D4D7D;~E>{EAwEDtFGpFJmFMiGPfGScGV`HY\H\YH_VHbSIePIgMIjJJmGJoDJrAKu>Kw;Kz8K|5L3L0L-L+M(M%M#M NNNNOOOO P PPPPQPNLJ H FDB@><:875 3"1$/&.(,**,).'0%1#3"5 79:<>@ACEFH XXXXXXXWWWWWW V"V$V%V'V)U*~U,|U.{U0yU1xU3vT5tT7sT9qT:oTlS@jSBiSDgSFeRHcRJbRL`RN^RP\QRZQTXQVVQXUQ[SP]QP_OPaMPcKOfIOhGOjEOlCNoANq>Nt??????????? ? ? ? ? ? ??????????????????????? ?!?!?"?#?$?%?%?&?'?(?)?*?*?+?,?-?.?.?/?0?1?2?2?3?4?5?6?7?7?8?9?:?;?;????@?@~?A}?B|?C{?D{?Dz?Ey?Fx?Gw?Hw?Hv?Iu?Jt?Ks?Lr?Mr?Mq?Np?Oo?Pn?Qn?Qm?Rl?Sk?Tj?Uj?Vi?Vh?Wg?Xf?Ye?Ze?Zd?[c?\b?]a?^a?^`?__?`^?a]?b\?c\?c[?dZ?eY?fX?gX?gW?hV?iU?jT?kT?lS?lR?mQ?nP?oO?pO?pN?qM?rL?sK?tK?tJ?uI?vH?wG?xF?yF?yE?zD?{C?|B?}B?}A?~@???>?>?=?=<;::9876 5 5 4 3 2 110/.-,,+*)(''&%$##"!  !"#$$%&'())*+,-../012 2 3 4 5 6 7789:;<<=>??@ @ AAABBC#C'C*D-D1D4E7E;}E>zFAvFDsFGoGJlGMiGPeHSbHV_HY\I\XI_UIbRIeOJgLJjIJmFKoCKr@Ku=Kw:Lz8L|5L2M/M-M*M'N%N"NNOOOOOPP P PQQQQPNLJ H FDB@><:875!3#1%/'.),+*,).'0%2#4"6 79;=>@BDEGI YYYXXXXXXXWWW W"W$W%V'V)V*}V,|V.zU0yU1wU3uU5tU7rU9pT:oTkT@jTBhSDfSFeSHcSJaSL_RN]RP\RRZRTXRVVQXTQ[RQ]PQ_NPaLPcJPfHPhFPjDOlBOo@Oq>Ot@?@@~@@}@A|@B{@C{@Dz@Dy@Ex@Fw@Gw@Hv@Hu@It@Js@Kr@Lr@Mq@Mp@No@On@Pn@Qm@Ql@Rk@Sj@Tj@Ui@Vh@Vg@Wf@Xe@Ye@Zd@Zc@[b@\a@]a@^`@^_@_^@`]@a\@b\@c[@cZ@dY@eX@fX@gW@gV@hU@iT@jT@kS@lR@lQ@mP@nO@oO@pN@pM@qL@rK@sK@tJ@tI@uH@vG@wF@xF@yE@yD@zC@{B@|B@}A@}@@~?@>@>@=@<@;@:@9@9@8@7@6@5@5@4@3@2@1@0@0@/@.@-@,@,@+@*@)@(@(@'@&@%@$@#@#@"@!@ @@@@@@@@@@@@@@@@@@@@@@@ @ @ @ @ @ @ @@@@@@@@@@@@??>=<;::987 6 5 5 4 3 2110/.-,,+*)(''&%$##"! !"#$$%&'())*+,-../0123 3 4 5 6 7 789:;<<=>?@@A A ABBCCC#D'D*D-E1E4E7F;}F>yFAvGDrGGoGJkHMhHPeHSaIV^IY[I\XJ_UJbQJeNJgKKjHKmEKoBLr@Lu=Lw:Lz7M|4M1M/M,N)N'N$N!OOOOPPPP Q Q QQQRRPNL J H FDB@><:87 5!3#1%/'.),+*-)/'1%3#4"6 8:<=?ABDFGI YYYYYYYXXXXXX W"W$W%W'W)~W*}V,{V.zV0xV1vV3uU5sU7rU9pU:nUkT@iTBgTDfTFdTHbSJ`SL_SN]SP[SRYRTWRVURXSR[QR]PQ_NQaLQcJQfHPhFPjCPlAPo?Oq=Ot;Ov9Ox7N{4N}2N0N.M+M)M'M$L"L LLKKKJJJ JIIIHFC@ = :630,)&""%(+/25 9 <?AAAAAAAAAAA A A A A A AAAAAAAAAAAAAAAAAAAAAAA A!A!A"A#A$A%A%A&A'A(A)A*A*A+A,A-A.A.A/A0A1A2A2A3A4A5A6A7A7A8A9A:A;A;AA?~A@}A@|AA{AB{ACzADyADxAEwAFwAGvAHuAHtAIsAJrAKrALqAMpAMoANnAOnAPmAQlAQkARjASjATiAUhAVgAVfAWeAXeAYdAZcAZbA[aA\aA]`A^_A^^A_]A`\Aa\Ab[AcZAcYAdXAeXAfWAgVAgUAhTAiTAjSAkRAlQAlPAmOAnOAoNApMApLAqKArKAsJAtIAtHAuGAvFAwFAxEAyDAyCAzBA{BA|AA}@A}?A~>A>A=A=<;::98 7 6 5 5 4 32110/.-,,+*)(''&%$##" ! !"#$$%&'())*+,-../01233 4 5 6 7 7 89:;<<=>?@AAB B BCCCDD#E'E*E-F1F4F7G;|G>xGAuHDqHGnHJkHMgIPdISaIV]JYZJ\WJ_TKbQKeNKgKKjHLmELoBLr?Mu<:87 5"3$1&/(.*,,*.)/'1%3#5"7 9:<>@ACEFHJ ZZZZYYYYYYXXX X"X$X%W'W)~W*|W,{W.yW0xV1vV3tV5sV7qV9oV:nUjU@iUBgUDeTFcTHbTJ`TL^TN\SPZSRXSTWSVUSXSRZQR]OR_MRaKQcIQfGQhEQjCQlAPo?Pq=Ps:Pv8Ox6O{4O}2O/N-N+N(N&M$M!MMLLLKKK K JJJIIFC@ = :630,)&""&),/36 9 =@BBBBBBBBBBB B B B B B BBBBBBBBBBBBBBBBBBBBBBB B!B!B"B#B$B%B%B&B'B(B)B*B*B+B,B-B.B.B/B0B1B2B2B3B4B5B6B7B7B8B9B:B;B;B~B?}B@|B@{BA{BBzBCyBDxBDwBEwBFvBGuBHtBHsBIrBJrBKqBLpBMoBMnBNnBOmBPlBQkBQjBRjBSiBThBUgBUfBVeBWeBXdBYcBZbBZaB[aB\`B]_B^^B^]B_\B`\Ba[BbZBcYBcXBdXBeWBfVBgUBgTBhTBiSBjRBkQBkPBlOBmOBnNBoMBpLBpKBqKBrJBsIBtHBtGBuFBvFBwEBxDByCByBBzBB{AB|@B}?B}>B~>B=B=<;::9 8 7 6 5 5 432110/.-,,+*)(''&%$## " !! "#$$%&'())*+,-../012334 5 6 7 7 8 9:;<<=>?@AABB C CCDDEE#E'F*F-F1G4G7G;{H>xHAtHDqIGmIJjIMgJPcJS`JV]JYYK\VK_SKbPLeMLgJLjGLmDMoAMr>Mu;Mw8Nz6N|3N0N-O+O(O%O#P PPPQQQQR R RRRSSRPNL J HFDB@><:87!5#3%1&/(.*,,*.)0'2%4#5"7 9;=>@BCEGHJ Z ZZZZZZYYYYYY X"X$X%X'X)}X*|W,zW.yW0wW1uW3tW5rV7pV9oV:mVjV@hUBfUDeUFcUHaUJ_TL]TN\TPZTRXTTVSVTSXRSZPS]NS_LRaJRcHRfFRhDQjBQl@Qo>Qq}C?|C?{C@{CAzCByCCxCDwCDwCEvCFuCGtCHsCHrCIrCJqCKpCLoCMnCMnCNmCOlCPkCQjCQjCRiCShCTgCUfCUeCVeCWdCXcCYbCZaCZaC[`C\_C]^C^]C^\C_\C`[CaZCbYCcXCcXCdWCeVCfUCgTCgTChSCiRCjQCkPCkOClOCmNCnMCoLCpKCpKCqJCrICsHCtGCtFCuFCvECwDCxCCyBCyBCzAC{@C|?C}>C}>C~=C=<;:: 9 8 7 6 5 5432110/.-,,+*)(''&%$# # "!!" #$$%&'())*+,-../0123345 6 7 7 8 9 :;<<=>?@AABCC D DDEEEF#F'F*G-G1G4H7~H;zH>wIAsIDpIGmJJiJMfJPbKS_KV\KYYK\VL_RLbOLeLMgIMjFMmCMo@Nr=Nu;Nw8Nz5O|2O/O-O*P'P%P"PQQQQQRRR R SSSSSRPNL J HFDB@><:87!5#3%1'/).+,-*/)0'2%4#6"8 :;=?ABDFGIK [ [[[ZZZZZZYYY Y"Y$Y%Y'~X)}X*{X,zX.xX0vX1uW3sW5rW7pW9nW:mViV@hVBfVDdVFbUH`UJ_UL]UN[UPYTRWTTUTVTTXRTZPS]NS_LSaJScHRfFRhDRjBRl@Ro=Qq;Qs9Qv7Qx5P{3P}0P.P,O)O'O%O"N NNNMMMML L LKKKIFC @ =:630-)!&$"'*.147 ; >BCCCCCCCCCCC C C C C C CCCCCCCCCCCCCCCCCCCCCCC C!C!C"C#C$C%C%C&C'C(C)C)C*C+C,C-C.C.C/C0C1C2C2C3C4C5C6C7C7C8C9C:C;C;C<~C=}C>|C?{C?{C@zCAyCBxCCwCDwCDvCEuCFtCGsCHrCHrCIqCJpCKoCLnCMnCMmCNlCOkCPjCQjCQiCRhCSgCTfCUeCUeCVdCWcCXbCYaCZaCZ`C[_C\^C]]C^\C^\C_[C`ZCaYCbXCcXCcWCdVCeUCfTCgTCgSChRCiQCjPCkOCkOClNCmMCnLCoKCpKCpJCqICrHCsGCtFCtFCuECvDCwCCxBCyBCyACz@C{?C|>C}>C}=C~=<;: : 9 8 7 6 55432110/.-,,+*)(''&%$ # #!""!# $$%&'())*+,-../01233456 7 7 8 9 : ;<<=>?@AABCDD D EEEFFG#G'G*H-H1H4I7}I;zI>vIAsJDoJGlJJhKMeKPbKS_LV[LYXL\UL_RMbOMeLMgIMjFNmCNo@Nr=Ou:Ow7Oz4O|2P/P,P)P'Q$Q!QQQRRRRS S S SSTTTRPN L J HFDB@><:8 7"5$3&1(/*.+,-*/)1'3%5#7"8 :<>?ACDFHIK [ [[[[[[ZZZZZZ Z"Y$Y%Y'~Y)|Y*{Y,yX.wX0vX1tX3sX5qX7oW9nW:lWiW@gVBeVDcVFbVH`VJ^VL\UNZUPYURWUTUUVSTXQTZOT]MT_KTaIScGSeEShCSjARl?Ro=Rq;Rs8Rv6Qx4Q{2Q}0Q-P+P)P&P$O"OOONNNNMM MLLLLIFC @ =:630-)"&%"(+.258 < ?CDDDDDDDDDDD D D D D D DDDDDDDDDDDDDDDDDDDDDDD D!D!D"D#D$D%D%D&D'D(D)D)D*D+D,D-D.D.D/D0D1D2D2D3D4D5D6D7D7D8D9D:D;D;~D<}D=|D>{D?{D?zD@yDAxDBwDCwDDvDDuDEtDFsDGrDHrDHqDIpDJoDKnDLnDMmDMlDNkDOjDPjDQiDQhDRgDSfDTeDUeDUdDVcDWbDXaDYaDZ`DZ_D[^D\]D]\D^\D^[D_ZD`YDaXDbXDcWDcVDdUDeTDfTDgSDgRDhQDiPDjODkODkNDlMDmLDnKDoKDpJDpIDqHDrGDsFDtFDtEDuDDvCDwBDxBDyADy@Dz?D{>D|>D}=D}=<; : : 9 8 7 655432110/.-,,+*)(''&% $ #!#""#!$ $%&'())*+,-../012334567 7 8 9 : ; <<=>?@AABCDDE E FFFGGG#H'H*H-I1I4I7}J;yJ>uJArKDnKGkKJhKMdLPaLS^LV[MYWM\TM_QMbNNeKNgHNjENmBOo?Or<:8 7"5$3&1(/*.,,.*0)2'3%5#7"9 ;<>@BCEGHJL \ \\\[[[[[[[ZZ Z"Z$Z%Z'}Y)|Y*zY,yY.wY0uY1tX3rX5pX7oX9mX:lXhW@fWBeWDcWFaWH_VJ^VL\VNZVPXVRVUTTUVRUXPUZNU]MT_KTaITcGTeEThBSj@Sl>So{E?zE?yE@xEAwEBwECvEDuEDtEEsEFrEGrEHqEHpEIoEJnEKnELmELlEMkENjEOjEPiEQhEQgERfESeETeEUdEUcEVbEWaEXaEY`EZ_EZ^E[]E\\E]\E^[E^ZE_YE`XEaXEbWEbVEcUEdTEeTEfSEgREgQEhPEiOEjOEkNEkMElLEmKEnKEoJEpIEpHEqGErFEsFEtEEtDEuCEvBEwBExAEx@Ey?Ez>E{>E|=E}=< ; : : 9 8 7655432110/.-,,+*)(''& % $!#"##"$!$ %&'())*+,-../0123345677 8 9 : ; < <=>?@AABCDEEF F FGGGHH#H'I*I-I1J4J7|J;xK>uKAqKDnLGjLJgLMdLP`MS]MVZMYWN\TN_PNbMNeJOgGOjDOmAOo>Pr;Pu9Pw6Pz3Q|0Q-Q+Q(R%R#R RRSSSSTT T TTUUUTRPN L JHFDB@><:8!7#5%3'1)/+.-,.*0)2'4%6#8"9 ;=?@BDEGIJL \ \\\\\\[[[[[[ ["Z$Z%~Z'}Z){Z*zZ,xY.vY0uY1sY3rY5pY7nX9mX:kXhX@fXBdWDbWFaWH_WJ]WL[WNYVPWVRVVTTVVRVXPUZNU]LU_JUaHUcFTeDThBTj@Tl>SozF?yF?xF@wFAwFBvFCuFDtFDsFErFFrFGqFHpFHoFInFJnFKmFLlFLkFMjFNjFOiFPhFQgFQfFReFSeFTdFUcFUbFVaFWaFX`FY_FZ^FZ]F[\F\\F][F^ZF^YF_XF`XFaWFbVFbUFcTFdTFeSFfRFgQFgPFhOFiOFjNFkMFkLFlKFmKFnJFoIFpHFpGFqFFrFFsEFtDFtCFuBFvBFwAFx@Fx?Fy>Fz>F{=F|= < ; : : 9 87655432110/.-,,+*)('' & %!$"###$"$!% &'())*+,-../01233456778 9 : ; < < =>?@AABCDEEFF G GGHHII#I'J*J-J1J4K7{K;wK>tLApLDmLGjMJfMMcMP`MS\NVYNYVN\SO_PObMOeJOgGPjDPmAPo>Pr;Qu8Qw5Qz2Q|0R-R*R'R%R"SSSSTTTTT U UUUUVTRPN L JHFDB@><:8!7#5%3'1)/+.-,/*1)3'4%6#8": <=?ACDFHIKM ] ]]]\\\\\\\[[ ["[#[%~['|[){Z*yZ,wZ.vZ0tZ1sZ3qY5oY7nY9lY:jYgX@eXBdXDbXF`XH^WJ\WL[WNYWPWWRUWTSVVQVXOVZMV]KV_IUaGUcEUeCUhAUj?Tl=To;Tq9Ts7Sv4Sx2S{0S}.S+R)R'R$R"Q QQQPPPPO O OONNLIF C @=:730-!)$&'"*-147; > AEGGGGGGGGGGG G G G G G GGGGGGGGGGGGGGGGGGGGGGG G G!G"G#G$G%G%G&G'G(G)G)G*G+G,G-G.G.G/G0G1G2G2G3G4G5G6G6G7G8G9~G:}G;|G;{G<{G=zG>yG?xG?wG@wGAvGBuGCtGDsGDrGErGFqGGpGHoGHnGInGJmGKlGLkGLjGMjGNiGOhGPgGQfGQeGReGSdGTcGUbGUaGVaGW`GX_GY^GZ]GZ\G[\G\[G]ZG^YG^XG_XG`WGaVGbUGbTGcTGdSGeRGfQGgPGgOGhOGiNGjMGkLGkKGlKGmJGnIGoHGpGGpFGqFGrEGsDGtCGtBGuBGvAGw@Gx?Gx>Gy>Gz=G{ = < ; : : 987655432110/.-,,+*)(' ' &!%"$##$#$"%!& '())*+,-../012334567789 : ; < < = >?@AABCDEEFGG H HHIIIJ#J'J*K-K1K4~L7zL;wL>sLApMDlMGiMJfNMbNP_NS\NVXOYUO\RO_OObLPeIPgFPjCPm@Qo=Qr:Qu7Qw4Rz2R|/R,R)S'S$S!STTTTTUU U UUVVVVTRP N L JHFDB@><: 8"7$5&3(1*/,..,/*1)3'5%7#9": <>@ACEGHJLM ] ]]]]]]]\\\\\ \"\#[%}['|[)z[*y[,w[.uZ/tZ1rZ3pZ5oZ7mZ9lY:jYfY@eYBcYDaXF_XH^XJ\XLZXNXXPVWRTWTSWVQWXOWZMV]KV_IVaGVcEVeCUhAUj?UlxH?wH?wH@vHAuHBtHCsHDrHDrHEqHFpHGoHHnHHnHImHJlHKkHLjHLjHMiHNhHOgHPfHQeHQeHRdHScHTbHUaHUaHV`HW_HX^HY]HZ\HZ\H[[H\ZH]YH^XH^XH_WH`VHaUHbTHbTHcSHdRHeQHfPHgOHgOHhNHiMHjLHkKHkKHlJHmIHnHHoGHpFHpFHqEHrDHsCHtBHtBHuAHv@Hw?Hx>Hx>Hy=Hz = < ; : :987655432110/.-,,+*)( ' '!&"%#$$#$#%"&!' ())*+,-../012334567789: ; < < = > ?@AABCDEEFGHH H IIIJJJ#K'K*K-L1L4}L7zM;vM>rMAoMDlNGhNJeNMaOP^OS[OVXOYUP\QP_NPbKPeHQgEQjBQm?Qo<:!8#7%5&3(1*/,..,0*2)4'6%7#9"; =>@BDEGIJLN ^ ^^^]]]]]]]\\ \"\#~\%}\'{\)z[*x[,v[.u[/s[1r[3pZ5nZ7mZ9kZ:iZfZ@dYBbYDaYF_YH]YJ[XLYXNXXPVXRTXTRXVPWXNWZLW]JW_HWaFVcDVeBVh@Vj>VlwH?wH?vH@uHAtHBsHCrHCrHDqHEpHFoHGnHHnHHmHIlHJkHKjHLjHLiHMhHNgHOfHPeHQeHQdHRcHSbHTaHUaHU`HV_HW^HX]HY\HY\HZ[H[ZH\YH]XH^XH^WH_VH`UHaTHbTHbSHcRHdQHePHfOHgOHgNHhMHiLHjKHkKHkJHlIHmHHnGHoFHoFHpEHqDHrCHsBHtBHtAHu@Hv?Hw>Hx>Hx=Hy = < ; ::987655432110/.-,,+*) ( '!'"&#%$$%#%#&"'!( ))*+,-../012334567789:; < < = > ? @AABCDEEFGHII I JJJKKK#L'L*L-L1M4|M7yM;uN>rNAnNDkNGgOJdOMaOP]PSZPVWPYTP\QQ_NQbKQeGQgDRjBRm?Ro<:!8#7%5'3)1+/-./,1*2)4'6%8#:"; =?ABDFHIKMN ^ ^^^^^^^]]]]] ]"]#~\%|\'{\)y\*w\,v\.t\/s[1q[3o[5n[7l[8j[:iZeZ@dZBbZD`ZF^YH\YJ[YLYYNWYPUYRSXTQXVOXXMXZLX]JW_HWaFWcDWeAWh?Vj=Vl;Vo9Vq7Vs5Uv3Ux0U{.U},U*T'T%T#T SSSSRRRR Q QQQPOLIF C@=:730 -#)&&)#,0369= @ DGIIIIIIIIIII I I I I I IIIIIIIIIIIIIIIIIIIIIII I I!I"I#I$I%I%I&I'I(I)I)I*I+I,I-I-I.I/I0I1I2I2I3I4I5I6I6~I7}I8|I9{I:{I;zI;yIwI?vI?uI@tIAsIBrICrICqIDpIEoIFnIGnIHmIHlIIkIJjIKjILiILhIMgINfIOeIPeIQdIQcIRbISaITaIU`IU_IV^IW]IX\IY\IY[IZZI[YI\XI]XI^WI^VI_UI`TIaTIbSIbRIcQIdPIeOIfOIgNIgMIhLIiKIjKIkJIkIIlHImGInFIoFIoEIpDIqCIrBIsBItAIt@Iu?Iv>Iw>Ix=Ix = < ;::987655432110/.-,,+* ) (!'"'#&$%%$%#&#'"(!) )*+,-../012334567789:;< < = > ? @ AABCDEEFGHIIJ J JKKKLL#L'M*M-M1N4|N7xN;tN>qOAnODjOGgOJcPM`PP]PSZQVVQYSQ\PQ_MRbJReGRgDRjASm>So;Sr8Su5Sw2Tz0T|-T*T'U%U"U UUVVVVVW W WWWXXVTRP N LJHFDB@>< :"8$7&5(3*1+/-./,1*3)5'7%8#:"< >@ACEFHJKMO _ ___^^^^^^^^] ]"]#}]%|]'z])x]*w\,u\.t\/r\1p\3o\5m[7l[8j[:h[e[@cZBaZD_ZF^ZH\ZJZZLXYNVYPUYRSYTQYVOYXMXZKX]IX_GXaEXcCWeAWh?Wj=Wl;Wo8Vq6Vs4Vv2Vx0V{-U}+U)U'U$U"TTTTSSSSR R RRQQOMI F C@=:730!-$*'&*#-047:> A DHJJJJJJJJJJJ J J J J J JJJJJJJJJJJJJJJJJJJJJJJ J J!J"J#J$J%J%J&J'J(J)J)J*J+J,J-J-J.J/J0J1J2J2J3J4J5J6~J6}J7|J8{J9{J:zJ;yJ;xJvJ?uJ?tJ@sJArJBrJCqJCpJDoJEnJFnJGmJHlJHkJIjJJjJKiJLhJLgJMfJNeJOeJPdJQcJQbJRaJSaJT`JU_JU^JV]JW\JX\JY[JYZJZYJ[XJ\XJ]WJ^VJ^UJ_TJ`TJaSJbRJbQJcPJdOJeOJfNJgMJgLJhKJiKJjJJkIJkHJlGJmFJnFJoEJoDJpCJqBJrBJsAJt@Jt?Ju>Jv>Jw=Jx = <;::987655432110/.-,,+ * )!("'#'$&%%%$&#'#(")!) *+,-../012334567789:;<< = > ? @ A ABCDEEFGHIJJK K KLLLLM#M'M*N-N1~N4{O7wO;tO>pOAmPDiPGfPJcPM_QP\QSYQVVRYRR\OR_LRbISeFSgCSj@Sm=So:Tr7Tu5Tw2Tz/U|,U*U'U$U!VVVVVWWW W WXXXXXVTR P N LJHFDB@>< :"8$7&5(3*1,/..0,2*4)5'7%9#;"= >@BDEGIJLNO _ _______^^^^^ ^"~^#}]%{]'y])x]*v],u].s]/r\1p\3n\5m\7k\8i\:h\d[@b[Ba[D_[F][H[ZJZZLXZNVZPTZRRZTPYVNYXLYZJY]HY_FXaDXcBXe@Xh>Xj B EIKKKKKKKKKKK K K K K K KKKKKKKKKKKKKKKKKKKKKKK K K!K"K#K$K%K%K&K'K(K)K)K*K+K,K-K-K.K/K0K1K2K2K3K4K5~K6}K6|K7{K8{K9zK:yK;xK;wKuK?tK?sK@rKArKBqKCpKCoKDnKEnKFmKGlKHkKHjKIjKJiKKhKLgKLfKMeKNeKOdKPcKQbKQaKRaKS`KT_KU^KU]KV\KW\KX[KYZKYYKZXK[XK\WK]VK^UK^TK_TK`SKaRKbQKbPKcOKdOKeNKfMKgLKgKKhKKiJKjIKkHKkGKlFKmFKnEKoDKoCKpBKqBKrAKs@Kt?Kt>Ku>Kv=Kw =<;::987655432110/.-,, + *!)"(#'$'%&%%&$'#(#)")!* +,-../012334567789:;<<= > ? @ A A BCDEEFGHIJJKK L LLMMMN#N'N*N-O1~O4zO7wP;sP>oPAlPDiQGeQJbQM_QP[RSXRVURYRR\OS_LSbHSeESgBTj?Tm=To:Tr7Uu4Uw1Uz.U|,U)V&V#V!VWWWWWXX X XXXYYXVTR P NLJHFDB@>d\@b\B`[D^[F][H[[JY[LW[NUZPSZRQZTPZVNZXLZZJY]HY_FYaDYcBYe@Xh>Xj;Xl9Xo7Xq5Xs3Wv1Wx.W{,W}*W(V%V#V!VUUUUUTT T TSSSRPMJ G C@=:740"-%*(&+#/258<? C FJLLLLLLLLLLL L L L L L LLLLLLLLLLLLLLLLLLLLLLL L L!L"L#L$L%L%L&L'L(L)L)L*L+L,L-L-L.L/L0L1L2L2L3L4~L5}L6|L6{L7{L8zL9yL:xL:wL;wLtL?sL?rL@rLAqLBpLCoLCnLDnLEmLFlLGkLHjLHjLIiLJhLKgLLfLLeLMeLNdLOcLPbLPaLQaLR`LS_LT^LU]LU\LV\LW[LXZLYYLYXLZXL[WL\VL]UL^TL^TL_SL`RLaQLbPLbOLcOLdNLeMLfLLfKLgKLhJLiILjHLkGLkFLlFLmELnDLoCLoBLpBLqALr@Ls?Lt>Lt>Lu=Lv=<;::987655432110/.-, , +!*")#($'%'%&&%'$(#)#)"*!+ ,-../012334567789:;<<=> ? @ A A B CDEEFGHIJJKLL L MMMNNN#O'O*O-O1}P4yP7vP;rQ>oQAkQDhQGdRJaRM^RP[RSWSVTSYQS\NS_KTbHTeETgBTj?Um ?ACEFHJKMOP a ```````_____ _"}_#|_%z^'x^(w^*u^,t^.r^/p^1o]3m]5l]7j]8h]:g]c\@a\B`\D^\F\\HZ\JX[LW[NU[PS[RQ[TO[VMZXKZZIZ\GZ_EZaCYcAYe?Yh=Yj;Yl9Yo7Xq4Xs2Xv0Xx.X{,W})W'W%W"W VVVVUUUU U TTTTSPMJ GC@=:74 0#-&*)&,#/369<@ C GJLLLLLLLLLLL L L L L L LLLLLLLLLLLLLLLLLLLLLLL L L!L"L#L$L$L%L&L'L(L)L)L*L+L,L-L-L.L/L0L1L2L2L3~L4}L5|L6{L6{L7zL8yL9xL:wL:wL;vLsL?rL?rL@qLApLBoLCnLCnLDmLElLFkLGjLHjLHiLIhLJgLKfLLeLLeLMdLNcLObLPaLPaLQ`LR_LS^LT]LU\LU\LV[LWZLXYLYXLYXLZWL[VL\UL]TL^TL^SL_RL`QLaPLbOLbOLcNLdMLeLLfKLfKLgJLhILiHLjGLkFLkFLlELmDLnCLoBLoBLpALq@Lr?Ls>Lt>Lt=Lu=<;::987655432110/.- , ,!+"*#)$(%'%'&&'%($)#)#*"+!, -../012334567789:;<<=>? @ A A B C DEEFGHIJJKLMM M NNNOOO#O'P*P-P1|Q4yQ7uQ;qQ>nRAkRDgRGdRJ`SM]SPZSSWSVSTYPT\MT_JTbGUeDUgAUj>Um;Uo8Vr5Vu3Vw0Vz-W|*W(W%W"W XXXXXYYY Y YZZZZXVT R P NLJHFDB@> <":$8&7(5*3,1./0.1,3*5)7'9%;#<"> @BCEGHJLMOQ a aaaa```````_ ~_"}_#{_%y_'x_(v_*u_,s^.r^/p^1n^3m^5k^7i^8h]:f]c]@a]B_]D]\F[\HZ\JX\LV\NT\PR[RP[TN[VL[XK[ZI[\GZ_EZaCZc@Ze>ZhrM?rM?qM@pMAoMBnMCnMCmMDlMEkMFjMGjMHiMHhMIgMJfMKeMLeMLdMMcMNbMOaMPaMP`MQ_MR^MS]MT\MU\MU[MVZMWYMXXMYXMYWMZVM[UM\TM]TM^SM^RM_QM`PMaOMbOMbNMcMMdLMeKMfKMfJMgIMhHMiGMjFMkFMkEMlDMmCMnBMoBMoAMp@Mq?Mr>Ms>Mt=Mt=<;::987655432110/. - ,!,"+#*$)%(%'&''&(%)$)#*#+",!- ../012334567789:;<<=>?@ A A B C D EEFGHIJJKLMMN N NOOOPP#P'P*Q-Q1{Q4xR7tR;qR>mRAjSDfSGcSJ`SM\TPYTSVTVSTYPU\LU_IUbFUeCVg@Vj=Vm;Vo8Vr5Wu2Ww/Wz,W|*W'X$X"XXXYYYYY Z ZZZZZZXVT R PNLJHFDB@> <#:$8&7(5*3,1./0.2,4*6)7'9%;#="? @BDFGIKLNPQ b aaaaaaaa```` ~`"|`#z`%y_'w_(v_*t_,s_.q_/o_1n_3l^5j^7i^8g^:e^b^@`]B^]D]]F[]HY]JW]LU\NT\PR\RP\TN\VL\XJ[ZH[\F[_D[aB[c@[e>ZhA E HLNNNNNNNNNNN N N N N N NNNNNNNNNNNNNNNNNNNNNNN N N!N"N#N$N$N%N&N'N(N)N)N*N+N,N-N-N.N/N0N1N2~N2}N3|N4{N5{N6zN6yN7xN8wN9wN:vN:uN;tNrN?qN?pN@oNAnNBnNCmNClNDkNEjNFiNGiNHhNHgNIfNJeNKeNLdNLcNMbNNaNOaNP`NP_NQ^NR]NS\NT\NU[NUZNVYNWXNXXNYWNYVNZUN[TN\TN]SN^RN^QN_PN`ONaONbNNbMNcLNdKNeKNfJNfINgHNhGNiFNjFNkENkDNlCNmBNnBNoANo@Np?Nq>Nr>Ns=Nt=<;::987655432110/ . -!,",#+$*%)%(&'''(&)%)$*#+#,"-!. ./012334567789:;<<=>?@A A B C D E EFGHIJJKLMNNO O OPPPPQ#Q'Q*R-~R1{R4wR7tS;pS>mSAiSDfTGbTJ_TM\TPXUSUUVRUYOU\LV_IVbFVeCVg@Vj=Wm:Wo7Wr4Wu1Ww.Xz,X|)X&X$Y!YYYYYZZZ Z Z[[[[ZXVT R PNLJHFDB@>!<#:%8'7)5+3-1//1.3,4*6)8':%<#="? ACDFHIKMNPR b bbbbaaaaaaa~a }`"{`#z`%x`'w`(u`*t`,r_.p_/o_1m_3l_5j_7h_8g_:e^a^@`^B^^D\^FZ]HX]JW]LU]NS]PQ]RO]TM\VK\XI\ZG\\E\_C\aA[c?[e=[h;[j9[l7Zo5Zq3Zs0Zv.Zx,Z{*Y}'Y%Y#Y YXXXXWWW W WVVVVSPM J GD@=:74"0%-(*+&.#258;?B F IMOOOOOOOOOOO O O O O O OOOOOOOOOOOOOOOOOOOOOOO O O!O"O#O$O$O%O&O'O(O)O)O*O+O,O-O-O.O/O0O1~O1}O2|O3{O4{O5zO6yO6xO7wO8wO9vO:uO:tO;sOqO?pO?oO@nOAnOBmOClOCkODjOEiOFiOGhOGgOHfOIeOJeOKdOLcOLbOMaONaOO`OP_OP^OQ]OR\OS\OT[OUZOUYOVXOWXOXWOYVOYUOZTO[TO\SO]RO]QO^PO_OO`OOaNObMObLOcKOdKOeJOfIOfHOgGOhFOiFOjEOkDOkCOlBOmBOnAOo@Oo?Op>Oq>Or=Os=<;::987655432110 / .!-",#,$+%*%)&(''(')&)%*$+#,#-".!. /012334567789:;<<=>?@AA B C D E E FGHIJJKLMNOOO P PPQQQQ#R'R*R-~S1zS4vS7sS;oT>lTAhTDeTGbUJ^UM[UPXUSUVVQVYNV\KV_HVbEWeBWg?Wj"<$:&8(7*5+3-1//1.3,5*7)9':%<#>"@ ACEGHJLMOQR c bbbbbbbbaaa~a |a"{a#ya%xa'v`(u`*s`,r`.p`/n`1m`3k_5i_7h_8f_:d_a_@_^B]^D\^FZ^HX^JV^LT^NR]PP]RO]TM]VK]XI]ZG\\E\_C\aA\c?\e=\h:[j8[l6[o4[q2[s0[v-Zx+Z{)Z}'Z$Z"Y YYYYXXXX X WWWWVSPM JGDA=:7 4#0&-)*,&/#269<@C F JMPPPPPPPPPPP P P P P P PPPPPPPPPPPPPPPPPPPPPPP P P!P"P#P$P$P%P&P'P(P)P)P*P+P,P-P-P.P/P0~P1}P1|P2{P3{P4zP5yP6xP6wP7wP8vP9uP:tP:sP;rPpP?oP?nP@nPAmPBlPCkPCjPDiPEiPFhPGgPGfPHePIePJdPKcPLbPLaPMaPN`PO_PP^PP]PQ\PR\PS[PTZPUYPUXPVXPWWPXVPYUPYTPZSP[SP\RP]QP]PP^OP_OP`NPaMPbLPbKPcKPdJPeIPfHPfGPgFPhFPiEPjDPkCPkBPlBPmAPn@Po?Po>Pp>Pq=Pr=<;::98765543211 0 /!."-#,$,%+%*&)'((')')&*%+$,#-#.".!/ 012334567789:;<<=>?@AAB C D E E F GHIJJKLMNOOPP Q QQQRRR#S'S*S-}S1yT4vT7rT;nT>kUAhUDdUGaUJ^VMZVPWVSTVVQVYMW\JW_GWbDWeAXg>Xj;Xm8Xo6Xr3Yu0Yw-Yz*Y|(Y%Z"Z ZZZ[[[[[ [ \\\\\ZXV T R PNLJHFDB@ >"<$:&8(7*5,3.10/2.4,5*7)9';%=#>"@ BDEGIKLNOQS c ccccbbbbbbb}b |a"za#ya%wa'va(ta*sa,qa.o`/n`1l`3k`5i`7g`8e`:d_`_@__B]_D[_FY_HW^JU^LT^NR^PP^RN^TL^VJ]XH]ZF]\D]_B]a@]c>\e<\h:\j8\l6\o3\q1[s/[v-[x+[{([}&Z$Z!ZZZYYYYYX X XXXWVSP M JGDA=:7 4#1&-)*-&0#36:=@D G KNQQQQQQQQQQQ Q Q Q Q Q QQQQQQQQQQQQQQQQQQQQQQQ Q Q!Q"Q#Q$Q$Q%Q&Q'Q(Q)Q)Q*Q+Q,Q-Q-Q.Q/~Q0}Q1|Q1{Q2{Q3zQ4yQ5xQ6wQ6wQ7vQ8uQ9tQ:sQ:rQ;rQoQ?nQ?nQ@mQAlQBkQCjQCiQDiQEhQFgQGfQGeQHeQIdQJcQKbQLaQLaQM`QN_QO^QP]QP\QQ\QR[QSZQTYQUXQUXQVWQWVQXUQYTQYSQZSQ[RQ\QQ]PQ]OQ^OQ_NQ`MQaLQbKQbKQcJQdIQeHQfGQfFQgFQhEQiDQjCQkBQkBQlAQm@Qn?Qo>Qo=Qp=Qq=<;::9876554321 1 0!/".#-$,%,%+&*')(()')'*&+%,$-#.#."/!0 12334567789:;<<=>?@AABC D E E F G HIJJKLMNOOPQQ Q RRRRSS#S'T*T-|T1xT4uU7qU;nU>jUAgVDcVG`VJ]VMZWPVWSSWVPWYMW\JX_GXbDXeAXg>Xj;Ym8Yo5Yr2Yu/Zw,Zz*Z|'Z$Z"Z[[[[[\\ \ \\\]]\ZXV T RPNLJHFDB@!>#<%:'8)7+5-3.10/2.4,6*8):';%=#?"A CDFHIKMNPRS d ccccccccbb~b}b {b"zb#xb%wb'ub(ta*ra,pa.oa/ma1la3ja5h`7g`8e`:c```@^`B\_DZ_FY_HW_JU_LS_NQ_PO^RM^TK^VJ^XH^ZF^\D^_B]a@]c=]e;]h9]j7]l5\n3\q1\s.\v,\x*[{([}%[#[![[ZZZZZY Y YYXXXVSP M JGDA=:7!4$1'-**-&1#4 7:>AD H KOQQQQQQQQQQQ Q Q Q Q Q QQQQQQQQQQQQQQQQQQQQQQQ Q Q!Q"Q#Q$Q$Q%Q&Q'Q(Q)Q)Q*Q+Q,Q-Q-Q.~Q/}Q0|Q1{Q1{Q2zQ3yQ4xQ5wQ6wQ6vQ7uQ8tQ9sQ:rQ:rQ;qQnQ?nQ?mQ@lQAkQBjQCiQCiQDhQEgQFfQGeQGeQHdQIcQJbQKaQLaQL`QM_QN^QO]QP\QP\QQ[QRZQSYQTXQUXQUWQVVQWUQXTQYSQYSQZRQ[QQ\PQ]OQ]OQ^NQ_MQ`LQaKQbKQbJQcIQdHQeGQfFQfFQgEQhDQiCQjBQkBQkAQl@Qm?Qn>Qo=Qo=Qp=<;::987655432 1 1!0"/#.$-%,%,&+'*())()'*'+&,%-$.#.#/"0!1 2334567789:;<<=>?@AABCD E E F G H IJJKLMNOOPQRR R RSSSTT#T'T*U-{U1xU4tU7qV;mV>jVAfVDcWG_WJ\WMYWPVWSRXVOXYLX\IX_FYbCYe@Yg=Yj:Ym7Zo4Zr1Zu/Zw,Zz)[|&[$[![[[\\\\\ ] ]]]]]\ZXV T RPNLJHFDB@!>#<%:'8)7+5-3/11/3.5,7*8):'<%>#@"A CEFHJLMOPRT d ddddcccccc~c|c {c"yb#xb%vb'ub(sb*rb,pb.nb/ma1ka3ia5ha7fa8da:ca_`@]`B\`DZ`FX`HV`JT_LR_NQ_PO_RM_TK_VI_XG^ZE^\C^_A^a?^c=^e;]h9]j7]l4]n2]q0]s.\v,\x)\{'\}%\"\ [[[[[ZZZ Z ZYYYYVSP M JGDA>:7"4%1(-+*.'1#5 8;>BEI LPRRRRRRRRRRR R R R R R RRRRRRRRRRRRRRRRRRRRRRR R R!R"R#R$R$R%R&R'R(R(R)R*R+R,R-R-~R.}R/|R0{R1{R1zR2yR3xR4wR5wR6vR6uR7tR8sR9rR:rR:qR;pRnR>mR?lR@kRAjRBiRCiRChRDgREfRFeRGeRGdRHcRIbRJaRKaRL`RL_RM^RN]RO\RP\RP[RQZRRYRSXRTXRTWRUVRVURWTRXSRYSRYRRZQR[PR\OR]OR]NR^MR_LR`KRaKRbJRbIRcHRdGReFRfFRfERgDRhCRiBRjBRjARk@Rl?Rm>Rn=Ro=Ro=<;::98765543 2 1!1"0#/$.%-%,&,'+(*)))(*'+',&-%.$.#/#0"1!2 334567789:;<<=>?@AABCDE E F G H I JJKLMNOOPQRRS S STTTTU#U'U*~U-{V1wV4sV7pV;lW>iWAeWDbWG_XJ[XMXXPUXSRXVOYYKY\HY_EYbBYe?Zg$<&:(8*7,5.3011/3.5,7*9);'=%>#@"B DEGIJLNOQST e dddddddddc}c|c zc"yc#wc%vc'tc(sb*qb,ob.nb/lb1kb3ib5gb7fa8da:ba<`a>_a@]aB[aDYaFW`HV`JT`LR`NP`PN`RL_TJ_VH_XF_ZD_\B__@_a>^c<^e:^h8^j6^l4^n2]q/]s-]v+]x)]z&]}$\"\\\\[[[[[ [ ZZZZYVSP MJGDA>:7"4%1)-,*/'2#5 9<?CFJ MQSSSSSSSSSSS S S S S S SSSSSSSSSSSSSSSSSSSSSSS S S!S"S#S$S$S%S&S'S(S(S)S*S+S,S-~S-}S.|S/{S0{S1zS1yS2xS3wS4wS5vS6uS6tS7sS8rS9rS:qS:pS;oSmS>lS?kS@jSAiSBiSChSCgSDfSEeSFeSGdSGcSHbSIaSJaSK`SL_SL^SM]SN\SO\SP[SPZSQYSRXSSXSTWSTVSUUSVTSWSSXSSYRSYQSZPS[OS\OS]NS]MS^LS_KS`KSaJSbISbHScGSdFSeFSfESfDSgCShBSiBSjASj@Sk?Sl>Sm=Sn=So=<;::9876554 3 2!1"1#0$/%.%-&,',(+)*))*(+','-&.%.$/#0#1"2!3 34567789:;<<=>?@AABCDEE F G H I J JKLMNOOPQRSST T TTUUUU#V'V*}V-zV1vW4sW7oW;lW>hXAeXDaXG^XJ[XMWYPTYSQYVNYYKZ\HZ_EZbBZe?Zg<[j9[m6[o3[r0[u-\w*\z(\|%\"\ \]]]]]]^ ^ ^^^^^\ZX V T RPNLJHFDB @">$<&:(8*7,5.3012/4.6,8*9);'=%?#A"B DFHIKMNPRSU e eeeeddddd~d}d{d zd"xc#wc%uc'tc(rc*pc,oc.mc/lc1jb3hb5gb7eb8cb:bb<`b>^a@\aBZaDYaFWaHUaJSaLQaNO`PN`RL`TJ`VH`XF`ZD_\B__@_a>_c<_e:_h7_j5^l3^n1^q/^s-^v*^x(]z&]}#]!]]]\\\\\[ [ [[[ZYVS P MJGDA>: 7#4&1)-,*0'3#6 9=@CGJ NQTTTTTTTTTTT T T T T T TTTTTTTTTTTTTTTTTTTTTTT T T!T"T#T$T$T%T&T'T(T(T)T*T+T,~T-}T-|T.{T/{T0zT1yT1xT2wT3wT4vT5uT6tT6sT7rT8rT9qT:pT:oT;nTlT>kT?jT@iTAiTBhTCgTCfTDeTEeTFdTGcTGbTHaTIaTJ`TK_TL^TL]TM\TN\TO[TPZTPYTQXTRXTSWTTVTTUTUTTVSTWSTXRTYQTYPTZOT[OT\NT]MT]LT^KT_KT`JTaITbHTbGTcFTdFTeETfDTfCTgBThBTiATj@Tj?Tk>Tl=Tm=Tn=<;::987655 4 3!2"1#1$0%/%.&-',(,)+)**)+(,'-'.&.%/$0#1#2"3!3 4567789:;<<=>?@AABCDEEF G H I J J KLMNOOPQRSSTT U UUUVVV#V'W*}W-yW1uW4rX7nX;kX>gXAdYDaYG]YJZYMWYPSZSPZVMZYJZ\GZ_D[bA[e>[g;[j8[m5\o2\r/\u-\w*\z']|$]"]]]]^^^^ ^ ^____^\ZX V TRPNLJHFDB!@#>%<':)8+7-5/3113/4.6,8*:)<'>%?#A"C EFHJKMOPRTU f eeeeeeeee~d|d{d yd"xd#vd%ud'sd(rd*pc,nc.mc/kc1ic3hc5fc7dc8cb:ab<_b>]b@\bBZbDXbFVbHTaJSaLQaNOaPMaRKaTIaVG`XE`ZC`\A`_?`a=`c;_e9_g7_j5_l3_n0_q._s,^v*^x'^z%^}#^!^]]]]]\\ \ \\[[[YVS P MJGDA>:!7$4'1*--*0'4#7 :=ADHK ORUUUUUUUUUUU U U U U U UUUUUUUUUUUUUUUUUUUUUUU U U!U"U#U$U$U%U&U'U(U(U)U*U+~U,}U-|U-{U.{U/zU0yU1xU1wU2wU3vU4uU5tU6sU6rU7rU8qU9pU:oU:nU;nUkU>jU?iU@iUAhUBgUCfUCeUDeUEdUFcUGbUGaUHaUI`UJ_UK^UL]UL\UM\UN[UOZUPYUPXUQXURWUSVUTUUTTUUSUVSUWRUXQUYPUYOUZOU[NU\MU]LU]KU^KU_JU`IUaHUbGUbFUcFUdEUeDUfCUfBUgBUhAUi@Uj?Uj>Uk=Ul=Um=<;::98765 5 4!3"2#1$1%0%/&.'-(,),)+**+),(-'.'.&/%0$1#2#3"3!4 567789:;<<=>?@AABCDEEFG H I J J K LMNOOPQRSTTUU U VVVVWW#W'W*|X-xX1uX4qX7nY;jY>gYAcYD`YG\ZJYZMVZPSZSP[VL[YI[\F[_C[b@\e=\g:\j7\m4\o2\r/]u,]w)]z&]|$]!^^^^^^__ _ ___``^\ZX V TRPNLJHFD B"@$>&<(:*8+7-5/3113/5.7,9*;)<'>%@#B"C EGIJLNOQSTV f fffffeeee}e|eze ye"we#vd%td'sd(qd*od,nd.ld/kd1id3gc5fc7dc8bc:`c<_c>]c@[cBYbDXbFVbHTbJRbLPbNNbPLaRJaTIaVGaXEaZCa\Aa_?`a<`c:`e8`g6`j4`l2_n0_q._s+_v)_x'_z%_}"^ ^^^^]]]] ] ]\\\\YVS P MJGDA>:"7%4(1+-.*1'4#8 ;>AEHL OSVVVVVVVVVVV V V V V V VVVVVVVVVVVVVVVVVVVVVVVV V!V"V#V$V$V%V&V'V(V(V)V*~V+}V,|V-{V-{V.zV/yV0xV1wV1wV2vV3uV4tV5sV5rV6rV7qV8pV9oV:nV:nV;mVjV>iV?iV@hVAgVBfVCeVCeVDdVEcVFbVGaVGaVH`VI_VJ^VK]VK\VL\VM[VNZVOYVPXVPXVQWVRVVSUVTTVTSVUSVVRVWQVXPVYOVYOVZNV[MV\LV]KV]KV^JV_IV`HVaGVaFVbFVcEVdDVeCVfBVfBVgAVh@Vi?Vj>Vj=Vk=Vl=<;::9876 5 5!4"3#2$1%1%0&/'.(-),),*++*,)-(.'.'/&0%1$2#3#3"4!5 67789:;<<=>?@AABCDEEFGH I J J K L MNOOPQRSTTUVV V VWWWWX#X'X*{X-wY1tY4pY7mY;iZ>fZAbZD_ZG\ZJX[MU[PR[SO[VL[YI\\E\_B\b?\e<\g:]j7]m4]o1]r.]u+^w(^z&^|#^ ^^______ ` `````^\ZX V TRPNLJHFD B"@$>&<(:*8,7.503214/6.7,9*;)='?%@#B"D FGIKLNPQSUV g ffffffff~f}f{eze xe"we#ue%te're(pe*oe,md.ld/jd1hd3gd5ed6cd8bd:`c<^c>\c@[cBYcDWcFUcHScJQbLPbNNbPLbRJbTHbVFbXDaZBa\@a_>aa;"7%4(1+-/*2'5#8 <?BFIM PTVVVVVVVVVVV V V V V V VVVVVVVVVVVVVVVVVVVVVVVV V!V"V#V$V$V%V&V'V(V(V)~V*}V+|V,{V-{V-zV.yV/xV0wV1wV1vV2uV3tV4sV5rV5rV6qV7pV8oV9nV:nV:mV;lViV>iV?hV@gVAfVBeVCeVCdVDcVEbVFaVGaVG`VH_VI^VJ]VK\VK\VL[VMZVNYVOXVPXVPWVQVVRUVSTVTSVTSVURVVQVWPVXOVYOVYNVZMV[LV\KV]KV]JV^IV_HV`GVaFVaFVbEVcDVdCVeBVfBVfAVg@Vh?Vi>Vj=Vj=Vk=<;::987 6 5!5"4#3$2%1%1&0'/(.)-),*,++,*-).(.'/'0&1%2$3#3#4"5!6 7789:;<<=>?@AABCDEEFGHI J J K L M NOOPQRSTTUVWW W WXXXXY#Y'~Y*zY-wY1sZ4pZ7lZ;iZ>e[Ab[D^[G[[JX[MT\PQ\SN\VK\YH\\E]_B]b?]e<]g9]j6]m3^o0^r-^u+^w(^z%_|"_ ____```` ` ``aaa^\Z X VTRPNLJHFD!B#@%>'<):+8-7/503214/6.8,:*<)='?%A#C"D FHJKMOPRTUW g gggggfff~f|f{fyf xf"vf#uf%se're(pe*ne,me.ke/ie1he3fd5dd6cd8ad:_d<^d>\d@ZdBXdDVcFUcHScJQcLOcNMcPKcRIbTGbVEbXCbZAb\?b_=ba;ac9ae7ag5aj3al1an.aq,`s*`v(`x&`z#`}!`______^^ ^^^^]\YV S PMJGDA> ;#7&4)1,-/*3'6#9 <@CFJM QTWWWWWWWWWWW W W W W W WWWWWWWWWWWWWWWWWWWWWWWW W!W"W#W$W$W%W&W'W(W(~W)}W*|W+{W,{W-zW-yW.xW/wW0wW1vW1uW2tW3sW4rW5rW5qW6pW7oW8nW9nW:mW:lW;kWiW>hW?gW@fWAeWBeWCdWCcWDbWEaWFaWG`WG_WH^WI]WJ\WK\WK[WLZWMYWNXWOXWPWWPVWQUWRTWSSWTSWTRWUQWVPWWOWXOWYNWYMWZLW[KW\KW]JW]IW^HW_GW`FWaFWaEWbDWcCWdBWeBWfAWf@Wg?Wh>Wi=Wj=Wj=<;::98 7 6!5"5#4$3%2%1&1'0(/).)-*,+,,+-*.).(/'0'1&2%3$3#4#5"6!7 789:;<<=>?@AABCDEEFGHIJ J K L M N OOPQRSTTUVWWX X XXYYYY#Z'}Z*zZ-vZ1rZ4o[7k[;h[>d[Aa[D^\GZ\JW\MT\PQ\SM]VJ]YG]\D]_A]b>^e;^g8^j5^m2^o/_r-_u*_w'_z$_|"_``````` a aaaaaa^\Z X VTRPNLJHFD!B#@%>'<):+8-7/513315/7.9,:*<)>'@%B#C"E GHJLNOQRTVW h gggggggg}g|gzfyf wf"vf#tf%sf'qf(of*nf,le.ke/ie1ge3fe5de6be8`e:_e<]d>[d@YdBXdDVdFTdHRdJPdLNcNMcPKcRIcTGcVEcXCcZAc\?b_=ba;bc9be6bg4bj2bl0an.aq,as)av'ax%az#`} `````___ _ __^^^\YV S PMJGDA>!;$7'4*1-.0*3'6#: =@DGKN RUXXXXXXXXXXX X X X X X XXXXXXXXXXXXXXXXXXXXXXXX X!X"X#X$X$X%X&X'X(~X(}X)|X*{X+{X,zX-yX-xX.wX/wX0vX1uX1tX2sX3rX4rX5qX5pX6oX7nX8nX9mX:lX:kX;jXhX>gX?fX@eXAeXBdXCcXCbXDaXEaXF`XG_XG^XH]XI\XJ\XK[XKZXLYXMXXNXXOWXPVXPUXQTXRSXSSXTRXTQXUPXVOXWOXXNXYMXYLXZKX[KX\JX]IX]HX^GX_FX`FXaEXaDXbCXcBXdBXeAXf@Xf?Xg>Xh=Xi=Xj=<;::9 8 7!6"5#5$4%3%2&1'1(0)/).*-+,,,-+.*.)/(0'1'2&3%3$4#5#6"7!7 89:;<<=>?@AABCDEEFGHIJJ K L M N O OPQRSTTUVWXXX Y YYYZZZ#Z'|[*y[-u[1r[4n[7k\;g\>d\A`\D]\GZ]JV]MS]PP]SM]VJ^YF^\C^_@^b=^e:^g7_j5_m2_o/_r,_u)`w&`z$`|!````aaaa a abbbba^\Z X VTRPNLJHF D"B$@&>(<*:,8.70523315/7.9,;*=)>'@%B#D"F GIKLNPQSUVX h hhhhhgg~g}g{gzgxg wg"ug#tg%rf'pf(of*mf,lf.jf/hf1gf3ef5ce6be8`e:^e<\e>[e@YeBWeDUeFSdHRdJPdLNdNLdPJdRHdTFdVDcXBcZ@c\>c^!;$7'4+1..1*4'7#: >AEHKO RVYYYYYYYYYYY Y Y Y Y Y YYYYYYYYYYYYYYYYYYYYYYYY Y!Y"Y#Y$Y$Y%Y&Y'~Y(}Y(|Y){Y*{Y+zY,yY,xY-wY.wY/vY0uY1tY1sY2rY3rY4qY5pY5oY6nY7nY8mY9lY:kY:jY;iYgY>fY?eY@eYAdYBcYBbYCaYDaYE`YF_YG^YG]YH\YI\YJ[YKZYKYYLXYMXYNWYOVYPUYPTYQSYRSYSRYTQYTPYUOYVOYWNYXMYXLYYKYZKY[JY\IY]HY]GY^FY_FY`EYaDYaCYbBYcBYdAYe@Yf?Yf>Yg=Yh=Yi=<;:: 9 8!7"6#5$5%4%3&2'1(1)0)/*.+-,,-,.+.*/)0(1'2'3&3%4$5#6#7"7!8 9:;<<=>?@AABCDEEFGHIJJK L M N O O PQRSTTUVWXXYY Y ZZZZ[[#['|[*x\-t\1q\4m\7j\;f]>c]A_]D\]GY]JV^MR^PO^SL^VI^YF^\C__@_b=_e:_g7_j4`m1`o.`r+`u)`w&`z#a| aaaaaabb b bbbbca^\ Z X VTRPNLJHF D"B$@&>(<*:,8.70523416/8.:,;*=)?'A%C#D"F HIKMOPRSUWX i hhhhhhh~h|h{hyhxg vg"ug#sg%rg'pg(ng*mg,kg.jf/hf1ff3ef5cf6af8_f:^f<\f>Ze@XeBWeDUeFSeHQeJOeLMeNKePIdRHdTFdVDdXBdZ@d\>d^";%7(4+1..2*5'8#; ?BEILP SWZZZZZZZZZZZ Z Z Z Z Z ZZZZZZZZZZZZZZZZZZZZZZZZ Z!Z"Z#Z$Z$Z%Z&~Z'}Z(|Z({Z){Z*zZ+yZ,xZ,wZ-wZ.vZ/uZ0tZ1sZ1rZ2rZ3qZ4pZ5oZ5nZ6nZ7mZ8lZ9kZ:jZ:iZ;iZfZ>eZ?eZ@dZAcZBbZBaZCaZD`ZE_ZF^ZG]ZG\ZH\ZI[ZJZZKYZKXZLXZMWZNVZOUZPTZPSZQSZRRZSQZTPZTOZUOZVNZWMZXLZXKZYKZZJZ[IZ\HZ]GZ]FZ^FZ_EZ`DZaCZaBZbBZcAZd@Ze?Zf>Zf=Zg=Zh=<;: : 9!8"7#6$5%5%4&3'2(1)1)0*/+.,--,.,.+/*0)1(2'3'3&4%5$6#7#7"8!9 :;<<=>?@AABCDEEFGHIJJKL M N O O P QRSTTUVWXXYZZ Z [[[[[\#\'{\*w\-t\1p]4l]7i];f]>b^A_^D[^GX^JU^MR^PN_SK_VH_YE_\B__?`b<`e9`g6`j3`m0`o-ar+au(aw%az"a| aabbbbbb c ccccca^\ Z XVTRPNLJHF!D#B%@'>)<+:-8/71533516/8.:,<*>)@'A%C#E"G HJLMOQRTVWY i iiiiiih}h|hzhyhwh vh"th#sh%qh'og(ng*lg,kg-ig/gg1fg3dg5bg6af8_f:]f<[f>Zf@XfBVfDTfFRfHPeJOeLMeNKePIeRGeTEeVCeXAdZ?d\=d^;da9dc7de5dg3dj0cl.cn,cq*cs(cu%cx#cz!b}bbbbbba a aaaa`_\Y V SPMJGDA >#;&7)4,1/.2*5'9#< ?CFIMP TX[[[[[[[[[[[ [ [ [ [ [ [[[[[[[[[[[[[[[[[[[[[[[[ [!["[#[$[$[%~[&}['|[({[({[)z[*y[+x[,w[,w[-v[.u[/t[0s[1r[1r[2q[3p[4o[5n[5n[6m[7l[8k[9j[:i[:i[;h[e[>e[?d[@c[Ab[Ba[Ba[C`[D_[E^[F][G\[G\[H[[IZ[JY[KX[KX[LW[MV[NU[OT[PS[PS[QR[RQ[SP[TO[TO[UN[VM[WL[XK[XK[YJ[ZI[[H[\G[]F[]F[^E[_D[`C[aB[aB[bA[c@[d?[e>[f=[f=[g<[h;[i:[j9[j9[k8[l7[m6[n5[n5[o4[p3[q2[r1[s0[s0[t/[u.[v-[w,[w,[x+[y*[z)[{([|'[|'[}&[~%[$[#[#["[![ [[[[[[[[[[[[[[[[[[[[[[[ [ [ [ [ [ [ [[[[[[[[[[[[ZYXWVVUTSR R Q P O N M MLKJIHHGFEDCCBA@??>=<; : :!9"8#7$6%5%5&4'3(2)1)1*0+/,.--.,.,/+0*1)2(3'3'4&5%6$7#7#8"9!: ;<<=>?@AABCDEEFGHIJJKLM N O O P Q RSTTUVWXXYZ[[ [ [\\\\\#~]'z]*v]-s]1o]4l^7h^;e^>a^A^^D[_GW_JT_MQ_PN_SK`VG`YD`\A`_>`b;`e8ag5aj2am0ao-ar*au'bw$bz"b|bbbbccc c cccddca^\ Z XVTRPNLJHF"D$B&@(>*<,:-8/71533517/9.;,=*>)@'B%D#E"G IKLNPQSUVXY j iiiiii~i}i{izixiwh uh"th#rh%ph'oh(mh*lh,jh-hh/gg1eg3cg5bg6`g8^g:]g<[g>Yg@WgBUfDTfFRfHPfJNfLLfNJfPHfRFeTDeVBeX@eZ>e\$;'8*4-10.3*6'9$= @CGJNQ UX[[[[[[[[[[[ [ [ [ [ [ [[[[[[[[[[[[[[[[[[[[[[[[ [!["[#[$[$~[%}[&|['{[({[(z[)y[*x[+w[,w[,v[-u[.t[/s[0r[1r[1q[2p[3o[4n[5n[5m[6l[7k[8j[9i[:i[:h[;g[e[>d[?c[@b[Aa[Ba[B`[C_[D^[E][F\[G\[G[[HZ[IY[JX[KX[KW[LV[MU[NT[OS[PS[PR[QQ[RP[SO[TO[TN[UM[VL[WK[XK[XJ[YI[ZH[[G[\F[]F[]E[^D[_C[`B[aB[aA[b@[c?[d>[e=[f=[f<[g;[h:[i9[j9[j8[k7[l6[m5[n5[n4[o3[p2[q1[r0[s0[s/[t.[u-[v,[w,[w+[x*[y)[z([{'[{'[|&[}%[~$[#[#["[![ [[[[[[[[[[[[[[[[[[[[[[[ [ [ [ [ [ [ [[[[[[[[[[[[[ZYXWVVUTS R R Q P O N MMLKJIHHGFEDCCBA@??>=< ; :!:"9#8$7%6%5&5'4(3)2)1*1+0,/-..-.,/,0+1*2)3(3'4'5&6%7$7#8#9":!; <<=>?@AABCDEEFGHIJJKLMN O O P Q R STTUVWXXYZ[[\ \ \\]]]]#}]'y^*v^-r^1o^4k^7g_;d_>a_A]_DZ_GW`JS`MP`PM`SJ`VG`YDa\Aa_>ab;ae8ag5aj2bm/bo,br)bu'bw$bz!c|ccccccd d dddddca^\ Z XVTRPNLJH F"D$B&@(>*<,:.8072543618/9.;,=*?)A'B%D#F"H IKMNPRSUWXZ j jjjjjj~i|i{iyixivi ui"si#ri%pi'ni(mh*kh,jh-hh/fh1eh3ch5ah6_h8^h:\gXg@WgBUgDSgFQgHOgJMgLLfNJfPHfRFfTDfVBfX@fZ>f\$;'8*4-11.4*7':$= ADHKNR VY\\\\\\\\\\\ \ \ \ \ \ \ \\\\\\\\\\\\\\\\\\\\\\\ \!\"\#\#~\$}\%|\&{\'{\(z\(y\)x\*w\+w\,v\,u\-t\.s\/r\0r\1q\1p\2o\3n\4n\5m\5l\6k\7j\8i\9i\9h\:g\;f\d\>c\?b\@a\Aa\B`\B_\C^\D]\E\\F\\G[\GZ\HY\IX\JX\KW\KV\LU\MT\NS\OS\OR\PQ\QP\RO\SO\TN\TM\UL\VK\WK\XJ\XI\YH\ZG\[F\\F\]E\]D\^C\_B\`B\aA\a@\b?\c>\d=\e=\e<\f;\g:\h9\i9\j8\j7\k6\l5\m5\n4\n3\o2\p1\q0\r0\s/\s.\t-\u,\v,\w+\w*\x)\y(\z'\{'\{&\|%\}$\~#\#\"\!\ \\\\\\\\\\\\\\\\\\\\\\\ \ \ \ \ \ \ \\\\\\\\\\\\[[ZYXWVVUT S R R Q P O NMMLKJIHHGFEDCCBA@??>= < ;!:":#9$8%7%6&5'5(4)3)2*1+1,0-/...-/,0,1+2*3)3(4'5'6&7%7$8#9#:";!< <=>?@AABCDEEFGHIJJKLMNO O P Q R S TTUVWXXYZ[\\\ ] ]]]^^^#|^'y^*u_-q_1n_4j_7g_;c`>``A]`DY`GV`JS`MOaPLaSIaVFaYCa\@a_=bb:be7bg4bj1bm.bo+cr)cu&cw#cz c|ccddddd d deeeeca^ \ Z XVTRPNLJH!F#D%B'@)>+<-:/8172543618/:.<,>*?)A'C%E#F"H JLMOQRTVWYZ k jjjjjj}j|jzjyjwjvj ti"si#qi%oi'ni(li*ki,ii-gi/fi1dh3bh5ah6_h8]h:[hXh@VhBThDRgFQgHOgJMgLKgNIgPGgREgTCgVAfX?fZ=f\;f^9fa7fc5fe3fg1ej/el,en*eq(es&eu#ex!ezd}ddddddc c cccca_\ Y VSPMJGDA">%;(8+4.11.4*8';$> BEHLOS VZ]]]]]]]]]]] ] ] ] ] ] ] ]]]]]]]]]]]]]]]]]]]]]]] ]!]"]#~]#}]$|]%{]&{]'z](y](x])w]*w]+v],u],t]-s].r]/r]0q]1p]1o]2n]3n]4m]5l]5k]6j]7i]8i]9h]9g]:f];e]c]>b]?a]@a]A`]B_]B^]C]]D\]E\]F[]GZ]GY]HX]IX]JW]KV]KU]LT]MS]NS]OR]OQ]PP]QO]RO]SN]TM]TL]UK]VK]WJ]XI]XH]YG]ZF][F]\E]]D]]C]^B]_B]`A]a@]a?]b>]c=]d=]e<]e;]f:]g9]h9]i8]j7]j6]k5]l5]m4]n3]n2]o1]p0]q0]r/]s.]s-]t,]u,]v+]w*]w)]x(]y']z']{&]{%]|$]}#]~#]"]!] ]]]]]]]]]]]]]]]]]]]]]]] ] ] ] ] ] ] ]]]]]]]]]]]]\[[ZYXWVVU T S R R Q P ONMMLKJIHHGFEDCCBA@??> = ?@AABCDEFFGHIJJKLMNOO P Q R S T TUVWXXYZ[\]]] ^ ^^^^__#|_'x_*t_-q`1m`4i`7f`;c`>_`A\aDXaGUaJRaMOaPLbSHbVEbYBb\?b_+<-:/8173553719/:.<,>*@)B'C%E#G"I JLNOQSTVXY[ k kkkkk~k}j{jzjxjwjuj tj"rj#pj%oj'mj(lj*ji,hi-gi/ei1ci3bi5`i6^i8]i:[iWh@VhBThDRhFPhHNhILhLJhNIgPGgREgTCgVAgX?gZ=g\;g^9ga6fc4fe2fg0fj.fl,fn*fq'fs%eu#ex eze}eeeddd d dddcca_\ Y VSPMJGD A#>&;)8,4/12.5*8'<$? BFILPT W[^^^^^^^^^^^ ^ ^ ^ ^ ^ ^ ^^^^^^^^^^^^^^^^^^^^^^^ ^!^"~^#}^#|^${^%{^&z^  !#%(*,.02579;=@BDFHJMOQSUIW^JV^KU^KT^LS^MS^NR^OQ^OP^PO^QO^RN^SM^TL^TK^UK^VJ^WI^XH^XG^YF^ZF^[E^\D^]C^]B^^B^_A^`@^a?^a>^b=^c=^d<^e;^e:^f9^g9^h8^i7^j6^j5^k5^l4^m3^n2^n1^o0^p0^q/^r.^s-^s,^t,^u+^v*^w)^w(^x'^y'^z&^{%^{$^|#^}#^~"^!^ ^^^^^^^^^^^^^^^^^^^^^^^ ^ ^ ^ ^ ^ ^ ^^^^^^^^^^^^]\[[ZYXWVV U T S R R Q PONMMLKJIHHGFEDCCBA@?? > =!<";#:$:%9%8&7'6(5)5)4*3+2,1-1.0.//.0-1,2,3+3*4)5(6'7'7&8%9$:#;#<"?@AABCDEFFGHIJJKLMNOOP Q R S T T UVWXXYZ[\]]^^ ^ _____~`#{`'w`*s`-p`1l`4ia7ea;ba>^aA[aDXbGTbJQbMNbPKbSHbVEcYAc\>c_;cb8ce6cg3cj0dm-do*dr'du%dw"dzd|eeeeee e fffffeca^ \ ZXVTRPNLJ H"F$D&B(@*>,<.:08274553719/;.=,?*@)B'D%F#H"I KMNPRSUWXZ[ l kkkkk~k|k{kykxkvkuk sj"rj#pj%nj'mj(kj*jj,hj-fj/ej1cj3ai5`i6^i8\i:ZiWi@UiBSiDQiFOhGNhILhKJhNHhPFhRDhTBhV@hX>hZ&;)8-4013.6*9'<$@ CFJMQT X[___________ _ _ _ _ _ _ _______________________ _!~_"}_#|_C5(    "$')+-/1468:<>ACEGILNPRTWY[]_bdfhjmoqsvxz||zxvtqomkhfdb_][YWTRPMKIGDB@>;97520.+)'%" {#_|#_}"_~!_ _______________________ _ _ _ _ _ _ ____________^]\[[ZYXWV V U T S R R QPONMMLKJIHHGFEDCCBA@? ? >!="<#;$:%:%9&8'7(6)5)5*4+3,2-1.1.0//0.1-2,3,3+4*5)6(7'7'8&9%:$;#<#<"=!> ?@AABCDEFFGHIJJKLMNOOPQ R S T T U VWXXYZ[\]]^__ _ _````~`#za'va*sa-oa1ka4ha7db;ab>^bAZbDWbGTbJPcMMcPJcSGcVDcYAc\>d_;db8de5dg2dj/dm,do)er'eu$ew!eze|eeffff f fffggeca^ \ ZXVTRPNLJ H"F$D&B(@*>,<.:0827456381:/<.=,?*A)C'E%F#H"J KMOQRTUWYZ\ l lllll}l|lzkykwkvktk sk"qk#ok%nk'lk(kk*ij,gj-fj/dj1bj3aj5_j6]j8\j:ZjVi@TiBSiDQiFOiGMiIKiKIiNGiPEiRChTAhV?hX=hZ;h\9h^7ha5hc3he1gg/gj-gl+gn(gq&gs$gu"gxfzf}ffffff e eeeeda_\ Y VSPMJGD!A$>';*8-4013.7+:'=$@ DGKNRU Y\___________ _ _ _ _ _ _ _______________________ ~_n`QC5(   !#%(*,.02579;=@BDFHKMOQSVXZ\^acegilnpruwy{}|zxvtqomkhfdb_][YWTRPMKIGDB@>;97520.+)'%"  _____________ _ _ _ _ _ _ _____________^]\[[ZYXW V V U T S R RQPONMMLKJIHHGFEDCCBA@ ? ?!>"=#<$;%:%:&9'8(7)6)5*5+4,3-2.1.1/00/1.2-3,3,4+5*6)7(7'8'9&:%;$<#<#=">!? @AABCDEFFGHIJJKLMNOOPQR S T T U V WXXYZ[\]]^_`` ` ``aaa}a#ya'va*rb-nb1kb4gb7db;`c>]cAZcDVcGScJPcMMdPIdSFdVCdY@d\=d_:db7ee4eg1ej.em,eo)er&eu#fw fzf|fffffg g gggggeca ^ \ ZXVTRPNLJ!H#F%D'B)@+>-,@*B)C'E%G#I"J LNOQSTVXY[\ m llll~l}l{lzlxlwlultl rl"pk#ok%mk'lk(jk*ik,gk-ek/dk1bk3`k5^k6]j8[j:YjVj@TjBRjDPjFNjGLjIKiKIiMGiPEiRCiTAiV?iX=iZ;i\9h^7ha5hc3he0hg.hj,hl*hn(hq%gs#gu!gxgzg}gggfff f ffffdb_ \ YVSPMJGD"A%>(;+8.5114.7+;'>$A EHKORV Y]``````````` ` ` ` ` ` ` `````````````````````bq}n`QC5(    "$')+-/1468:<>ACEGILNPRTWY[]_bdfhkmoqsvxz||zxvtqomkhfdb_][YWTRPMKIGDB@>;97520.+)'%"   ```````````` ` ` ` ` ` ` `````````````_^]\[[ZYX W V V U T S RRQPONMMLKJIHHGFEDCCBA @ ?!?">#=$<%;%:&:'9(8)7)6*5+5,4-3.2.1/1001/2.3-3,4,5+6*7)7(8'9':&;%<$<#=#>"?!@ AABCDEFFGHIJJKLMNOOPQRS T T U V W XXYZ[\]]^_``a a aaabb|b#xb'ub*qb-nc1jc4fc7cc;`c>\cAYdDVdGRdJOdMLdPIdSFeVBeY?e\.,@*B)D'F%G#I"K MNPRSUVXZ[] m mmmm~m|m{mylxlvlulsl rl"pl#nl%ml'kl(jl*hl,fk-ek/ck1ak3`k5^k6\k8Zk:YkUk@SkBQjDPjENjGLjIJjKHjMFjPDjRBjT@jV>iX);,8/5215.8+;'?$B EILPSW Z^aaaaaaaaaaa a a a a a a aaaaaaaaaaaaaaaaaa3BRap}n`QC5(   !#%(*,.03579;=@BDFHKMOQSVXZ\^acegilnpruwy{~|zxvtqomkhfdb_][YWTRPMKIGDB@>;97520.+)'%"   aaaaaaaaaaa a a a a a a aaaaaaaaaaaa``_^]\[[ZY X W V V U T SRRQPONMMLKJIHHGFEDCCB A @!?"?#>$=%<%;&:':(9)8)7*6+5,5-4.3.2/101102/3.3-4,5,6+7*7)8(9':';&<%<$=#>#?"@!A ABCDEFFGHIJJKLMNOOPQRST T U V W X XYZ[\]]^_`aaa b bbbbc{c#xc'tc*pc-mc1id4fd7bd;_d>[dAXdDUdGReJNeMKePHeSEeVBeY?f\.<0:28476583:1;/=.?,A*C)D'F%H#J"K MOPRTUWYZ\] n nmmm}m|mzmymwmvmtmsm qm"om#nl%ll'kl(il*gl,fl-dl/bl1al3_l5]l6\l8Zk:XkUk@SkBQkDOkEMkGKkIIkKHkMFjPDjRBjT@jV>jX);,8/5316.9+<'?$C FIMPTW [_bbbbbbbbbbb b b b b b b bbbbbbbbbbbbbbb!2AQ`o~}n`QC5(    "$')+-/1468:<?ACEGILNPRTWY[]`bdfhkmoqtvxz||zxvtqomkhfdb_][YWTRPMKIGDB@>;97520.+)'%"   bbbbbbbbbb b b b b b b bbbbbbbbbbbba``_^]\[[Z Y X W V V U TSRRQPONMMLKJIHHGFEDCC B A!@"?#?$>%=%<&;':(:)9)8*7+6,5-5.4.3/20111203/3.4-5,6,7+7*8)9(:';'<&<%=$>#?#@"A!A BCDEFFGHIJJKLMNOOPQRSTT U V W X X YZ[\]]^_`abbb b cccc~c{c#wd'sd*pd-ld1hd4ed7ae;^e>[eAWeDTeGQeJNfMJfPGfSDfVAfY>f\;f_8gb5ge2gg/gj,gm*go'gr$gu!hwhzh|hhhhh i iiiiigeca ^ \ZXVTRPNL!J#H%F'D)B+@->/<1:38476583:1.@,A*C)E'G%H#J"L NOQSTVXY[\^ n nnn~n}n{nznxnwmumtmrm pm"om#mm%lm'jm(im*gm,em-dm/bl1`l3_l5]l6[l8Yl:XlTl@RlBPlDOkEMkGKkIIkKGkMEkOCkRAkT?kV=kX;kZ9j\7j^5ja3jc1je/jg,jj*jl(jn&iq$is!iuixizi}iiihh h hhhhgdb_ \ YVSQNKH!D$A'>*;-805316.:+='@$C GJNQUX \_ccccccccccc c c c c c c ccccccccccccccc 0@P_n}}n`QC5(   !#&(*,.03579;=@BDFHKMOQSVXZ\^acegjlnpruwy{|~zxvtqomkhfdb_][YWTRPMKIGDB@>;97520.+)'%"   ccccccccc c c c c c c ccccccccccccba``_^]\[[ Z Y X W V V UTSRRQPONMMLKJIHHGFEDC C B!A"@#?$?%>%=&<';(:):)9*8+7,6-5.5.4/3021121303/4.5-6,7,7+8*9):(;'<'<&=%>$?#@#A"A!B CDEFFGHIJJKLMNOOPQRSTTU V W X X Y Z[\]]^_`abbcc c cddd~dzd#vd're*oe-ke1he4de7ae;]f>ZfAWfDSfGPfJMfMJfPGgSCgV@gY=g\:g_7gb4ge1gg/hj,hm)ho&hr#hu!hwhzh|iiiii i iiijjgec a ^\ZXVTRPNL!J#H%F'D)B+@->/<1:38577593;1.@,B*D)E'G%I#K"L NPQSUVXZ[]^ o onn~n|n{nynxnvnunsnrn pn!nn#mn%km'jm(hm*fm,em-cm/am1`m3^m5\m6[m8Ym:Wl
      Sl@RlBPlDNlELlGJlIHlKFlMDlOClRAkT?kV=kX;kZ8k\6k^4ka2kc0ke.kg,jj*jl'jn%jq#js!jujxjzj}iiiii i iiihgdb _ \YVSQNKH"E%A(>+;.815417.:+>'A$D GKNRUY ]`ddddddddddd d d d d d d ddddddddddddddd/?N^m{}n`QC5(    "$')+-/1468:<?ACEGJLNPRUWY[]`bdfhkmoqtvxz|}zxvtqomkhfdb_][YWTRPMKIGDB@>;97520.+)'%"   dddddddd d d d d d d ddddddddddddcba``_^]\[ [ Z Y X W V VUTSRRQPONMMLKJIHHGFED C C!B"A#@$?%?%>&='<(;):):*9+8,7-6.5.5/403122131304/5.6-7,7,8+9*:);(<'<'=&>%?$@#A#A"B!C DEFFGHIJJKLMNOOPQRSTTUV W X X Y Z [\]]^_`abbcdd d ddee}eye#ue're*nf-jf1gf4cf7`f;]f>YfAVgDSgGOgJLgMIgPFgSCgV@hY=h\:h_7hb4he1hg.hj+hm(io%ir#iu iwizi|iiij j jjjjjjgec a ^\ZXVTRPN L"J$H&F(D*B,@.>0<2:48677593;1=/?.A,B*D)F'H%J#K"M OPRTUWYZ\]_ o oo~o}o|ozoyowovntnsnqn on!nn#ln%kn&in(gn*fn,dn-cn/an1_m3]m4\m6Zm8Xm:VmSm@QmBOmCMmELmGJlIHlKFlMDlOBlR@lT>lV+;.825518.;+>'B$E HLOSVZ ]addddddddddd d d d d d d ddddddddddddddd.>M]lz}n`QC5(       !#&(*,.03579;>@BDFHKMOQSVXZ\_acegjlnpruwy|{z~xvtqomkhfdb_][YWTRPMKIGDB@>;97520.+)'%"   ddddddd d d d d d d dddddddddddddcba``_^]\ [ [ Z Y X W VVUTSRRQPONMMLKJIHHGFE D C!C"B#A$@%?%?&>'=(<);):*:+9,8-7.6.5/50413223131405/6.7-7,8,9+:*;)<(<'='>&?%@$A#A#B"C!D EFFGHIJJKLMNOOPQRSTTUVW X X Y Z [ \]]^_`abbcdde e eeee|fxf#uf'qf*mf-jf1fg4cg7_g;\g>XgAUgDRgGOhJKhMHhPEhSBhV?hY0<2:486785:3<1>/?.A,C*E)G'H%J#L"M OQSTVWY[\^_ p po~o}o{ozoxowouotoropo oo!mo#lo%jo&in(gn*en,dn-bn/`n1_n3]n4[n6Yn8Xn:VnRm@PmBOmCMmEKmGImIGmKEmMCmOAmR?mT=mV;lX9lZ7l\5l^3l`1lc/le-lg+lj(ll&kn$kq"kskukxkzk}kkkj j jjjjjgdb _ \YVTQNK H#E&A)>,;/825519.<+?'B$F!ILPSWZ ^beeeeeeeeeee e e e e e e eeeeeeeeeeeeeee -=L[jy}n`QC5 (               " $ ' ) + - / 2 4 6 8 : < ? A C E G J L N P R U W Y [ ] ` b d f i k m o q t v x| zz }x v t q o m k h f d b _ ] [ Y W T R P M K I G D B @ > ;97520.+)'%"   eeeeee e e e e e e eeeeeeeeeeeeddcba``_^] \ [ [ Z Y X WVVUTSRRQPONMMLKJIHHGF E D!C"C#B$A%@%?&?'>(=)<);*:+:,9-8.7.6/5051423323141506/7.8-8,9,:+;*<)<(='>'?&@%A$A#B#C"D!E FFGHIJJKLMNOOPQRSTTUVWX X Y Z [ \ ]]^_`abbcdeee f ffff{fwg#tg'pg*lg-ig1eg4bg7^h;[h>XhAThDQhGNhJKhMGiPDiSAiV>iY;i\8i_5ib2ie/jg,jj*jm'jo$jr!jujwjzj|kkkk k kkkkkjge c a ^\ZXVTRPN!L#J%H'F)D+B-@/>1<3:587795:3<1>/@.B,D*E)G'I%K#L"N PQSUVXZ[]^` p pp}p|p{pypxpvpupsoropo no!mo#ko%jo&ho(fo*eo,co-ao/`o1^o3\n4[n6Yn8Wn:UnRn@PnBNnCLnEJnGHnIGnKEmMCmOAmR?mT=mV;mX9mZ7m\5m^3m`0mc.le,lg*lj(ll&ln#lq!lslulxlzl}kkkk k kkkkjgdb _ \YVTQNK!H$E'B*>-;0835629.=+@'C$F!JMQTX[ _bffffffffffff f f f f f fffffffffffffff ,;KZix}n ` Q C 5 (                ! # & ( * , . 0 3 5 7 9 ; > @ B D F I K M O Q T V X Z \ _ a c e g j l n p s u w| yz {x ~v t q o m k h f d b _ ] [ Y W T R P M K I G D B @ > ; 9 7 5 2 0 . + ) ' % "            fffff f f f f f f ffffffffffffeddcba``_^ ] \ [ [ Z Y XWVVUTSRRQPONMMLKJIHHG F E!D"C#C$B%A%@&?'?(>)=)<*;+:,:-9.8.7/605152433324151607/8.8-9,:,;+<*<)=(>'?'@&A%A$B#C#D"E!F FGHIJJKLMNOOPQRSTTUVWXX Y Z [ \ ] ]^_`abbcdefff f ggg~gzgwg#sh'oh*lh-hh1eh4ah7^h;Zi>WiATiDPiGMiJJiMGiPDiSAjV=jY:j\7j_4jb2je/jg,jj)jm&ko#kr!kukwkzk|kkkl l llllljge c a^\ZXVTRPN!L#J&H(F*D,B.@0>1<3:587795;3=1?/A.B,D*F)H'I%K#M"O PRTUWXZ\]_` q q~p}p|pzpypwpvptpspqpop np!lp#kp%ip&hp(fo*do,co-ao/_o1^o3\o4Zo6Xo8Wo:UoQo@OoBNnCLnEJnGHnIFnKDnMBnO@nQ>nT.;184572:.=+@'D$G!JNQUX\ `cgggggggggggg g g g g g gggggggggggggg~g *:J Y h w} n ` Q C 5 (               " % ' ) + - / 2 4 6 8 : < ? A C E G J L N P R U W Y [ ] ` b d f i k m o q t v| xz zx }v t q o m k h f d b _ ] [ Y W T R P M K I G D B @ > ; 9 7 5 2 0 . + ) ' % "            gggg g g g g g g ggggggggggggfeddcba``_ ^ ] \ [ [ Z YXWVVUTSRRQPONMMLKJIHH G F!E"D#C$C%B%A&@'?(?)>)=*<+;,:-:.9.8/70615253433425161708/8.9-:,;,<+<*=)>(?'@'A&A%B$C#D#E"F!F GHIJJKLMNOOPQRSTTUVWXXY Z [ \ ] ] ^_`abbcdeffgg g ghh}hzhvh#rh'oh*ki-gi1di4`i7]i;Zi>ViASjDPjGLjJIjMFjPCjS@jV=jY:j\7k_4kb1ke.kg+kj(km%ko#kr kulwlzl|lll l lllmmljge c a^\ZXVTRP N"L$J&H(F*D,B.@0>2<4:6887:5<3=1?/A.C,E*F)H'J%L#M"O QRTVWY[\^_a q q~q|q{qzqxqwquqtqrqppop mp!lp#jp%ip&gp(ep*dp,bp-`p/_p1]p3[p4Zp6Xo8Vo:ToQo@OoBMoCKoEIoGGoIEoKDoMBoO@nQ>nT.;184582;.>+A(E$H!KORVY] `dhhhhhhhhhhhh h h h h h hhhhhhhhhhhhh~h}h  ) 9 I X g v} n ` Q C 5 (                 ! # & ( * , . 0 3 5 7 9 ; > @ B D F I K M O Q T V X Z \ _ a c e g j l n p s u| wz yx |v ~t q o m k h f d b _ ] [ Y W T R P M K I G D B @ > ; 9 7 5 2 0 . + ) ' % "            hhh h h h h h h hhhhhhhhhhhhgfeddcba`` _ ^ ] \ [ [ ZYXWVVUTSRRQPONMMLKJIH H G!F"E#D$C%C%B&A'@(?)?)>*=+<,;-:.:.9/8071625353443526171808/9.:-;,<,<+=*>)?(@'A'A&B%C$D#E#F"F!G HIJJKLMNOOPQRSTTUVWXXYZ [ \ ] ] ^ _`abbcdeffghh h hhi}iyiui#qi'ni*ji-gi1cj4`j7\j;Yj>UjARjDOjGLjJHkMEkPBkS?kV3<5:6887:5<3>1@/B.C,E*G)I'J%L#N"P QSUVXZ[]^`a r r}q|q{qyqxqvquqsqrqpqnq mq!kq#jq%hq&fq(eq*cp,bp-`p/^p1\p3[p4Yp6Wp8Up:TpPp@NpBLpCKpEIoGGoIEoKCoMAoO?oQ=oT;oV9oX7oZ5o\3o^1o`/nc,ne*ng(ni&nl$nn!npnsnunxnzm}mmm m mmmmmjge b _\YWTQN K#H&E)B,>/;285582;.?+B(E$I!LOSVZ^ aeiiiiiiiiiiii i i i i i iiiiiiiiiiii~i}i|i  ( 8 G W f u} n ` Q C 5 (         "%')+-/2468:=?AC E G J L N P R U W Y [ ^ ` b d f i k m o r t| vz xx zv }t q o m k h f d b _ ] [ Y W T R P M K I G D B @ > ; 9 7 5 2 0 . + ) ' % "            ii i i i i i i iiiiiiiiiiiihgfeddcba` ` _ ^ ] \ [ [ZYXWVVUTSRRQPONMMLKJI H H!G"F#E$D%C%C&B'A(@)?)?*>+=,<-;.:.:/908172635354453627181809/:.;-<,<,=+>*?)@(A'A'B&C%D$E#F#F"G!H IJJKLMNOOPQRSTTUVWXXYZ[ \ ] ] ^ _ `abbcdeffghii i iii|ixjtj#qj'mj*ij-fj1bj4_j7[k;Xk>UkAQkDNkGKkJHkMEkPAlS>lV;lY8l\5l_2lb/le-lg*lj'mm$mo!mrmumwmzm|mmm m nnnnnljg e c a^\ZXVTRP!N#L%J'H)F+D-B/@1>3<5:7897;5=3?1@/B.D,F*G)I'K%M#N"P RSUWXZ\]_`b r ~r}r{rzryrwrvrtrsrqroqnq lq!kq#iq%hq&fq(dq*cq,aq-_q/^q1\q3Zq4Xq6Wq8Up:SpPp@NpALpCJpEHpGFpIDpKBpM@pO>pQ@BDFIKMOQTVXZ\_acehjlnps|uzwxyv|t~qomkhfdb_][YWTRPMKIGDB@>;97520.+)'%"   i i i i i i i iiiiiiiiiiiiihgfeddcba ` ` _ ^ ] \ [[ZYXWVVUTSRRQPONMMLKJ I H!H"G#F$E%D%C&C'B(A)@)?*?+>,=-<.;.:/:091827363545546372818190:/;.<-<,=,>+?*@)A(A'B'C&D%E$F#F#G"H!I JJKLMNOOPQRSTTUVWXXYZ[\ ] ] ^ _ ` abbcdeffghiij j jjj{jwjtk#pk'lk*ik-ek1bk4^k7[k;Wk>TlAQlDMlGJlJGlMDlPAlS>lV;lY8m\5m_2mb/me,mg)mj&mm#mo!mrmunwnzn|nnn n nnnnnljg e ca^\ZXVTR P"N$L&J(H*F,D.B0@2>4<6:8897;5=3?1A/C.D,F*H)J'L%M#O"Q RTVWY[\^_ab s ~s|r{rzrxrwrurtrrrprormr lr!jr#ir%gr&er(dr*br,`q-_q/]q1[q3Zq4Xq6Vq8Tq:SqOq@MqAKqCIqEHqGFqIDpKBpM@pO>pQ;97520.+)'%"    j j j j j j jjjjjjjjjjjjiihgfeddcb a ` ` _ ^ ] \[[ZYXWVVUTSRRQPONMMLK J I!H"H#G$F%E%D&C'C(B)A)@*?+?,>-=.<.;/:0:1928373645556473828191:0;/<.<-=,>,?+@*A)A(B'C'D&E%F$F#G#H"I!J JKLMNOOPQRSTTUVWXXYZ[\] ] ^ _ ` a bbcdeffghijjj k kk~kzkvksk#ok'kl*hl-dl1al4]l7Zl;Wl>SlAPlDMmGImJFmMCmP@mS=mV:mY7m\4m_1mb.ne+ng(nj%nm#no nrnunwnzn|oo o ooooonljg e ca^\ZXVTR P"N$L&J(H*F,D.B0@2>4<6:88:7<5>3@1A/C.E,G*I)J'L%N#O"Q SUVXY[]^`ac s }s|szsysxsvsusssrspsnsmr kr!jr#hr%gr&er(cr*br,`r-^r/]r1[r3Yr4Wr6Vr8Tr:RrNq@MqAKqCIqEGqGEqICqKAqM?qO=qQ;qT9qV7qX5qZ3p\1p^/p`-pc+pe(pg&pi$pl"pn pppspupxpzo}oo o ooooomjg e b_\ZWTQN"K%H(E+B.?1;4875:2>.A+D(G$K!NRUY\` cgkkkkkkkkkkkk k k k k k kkkkkkkkk~k}k|k{k{kzk  $4DSbq}n`QC5(        !$&(*,.13579;>@BDFIKMOQTVXZ]_acehjlnq|szuxwvyt|q~omkhfdb_][YWTRPMKIGDB@>;97520.+)'%"    k k k k k kkkkkkkkkkkkjiihgfeddc b a ` ` _ ^ ]\[[ZYXWVVUTSRRQPONMML K J!I"H#H$G%F%E&D'C(C)B)A*@+?,?->.=.,?,@+A*A)B(C'D'E&F%F$G#H#I"J!J KLMNOOPQRSTTUVWXXYZ[\]] ^ _ ` a b bcdeffghijkkk k kl}lylvlrl#nl'kl*gl-dm1`m4]m7Ym;Vm>SmAOmDLmGImJFnMBnP?nS5<7:98;7<5>3@1B/D.F,G*I)K'M%N#P"R SUWXZ\]_`bc ~t }t{tzsyswsvstsssqsosnsls ks!is#hs%fs&ds(cs*as,_s-^s/\r1Zr3Yr4Wr6Ur8Sr:QrNr@LrAJrCHrEFrGDrICrKArM?rO=qQ;qT9qV7qX5qZ3q\0q^.q`,qc*qe(qg&qi#ql!qnpppspupxpzp}pp p ppppomjg e b_\ZWTQ N#K&H)E,B/?2;5885;2>.B+E(H$L!ORVY]a dhllllllllllll l l l l l llllllll~l}l|l{l{lzlyl #3CRap}n`QC5(         "%')+-02468:=?ACEHJLNPSUWY[^`bdgikmo|rztxvvxt{q}omkhfdb_][YWTRPMKIGDB@>;97520.+)'%"    l l l l llllllllllllkjiihgfedd c b a ` ` _ ^]\[[ZYXWVVUTSRRQPONMM L K!J"I#H$H%G%F&E'D(C)C)B*A+@,?-?.>.=/<0;1:2:393847566575848392:1;1<0-?,@,A+A*B)C(D'E'F&F%G$H#I#J"J!K LMNOOPQRSTTUVWXXYZ[\]]^ _ ` a b b cdeffghijkkll l ll|mymumqm#nm'jm*fm-cm1_m4\n7Xn;Un>RnAOnDKnGHnJEnMBnP?nS5<7:98;7=5?3A1C/D.F,H*J)K'M%O#Q"R TVWYZ\^_abd ~t |t{tytxtwtutttrtptotmtlt js!is#gs%es&ds(bs*as,_s-]s/[s1Zs3Xs4Vs6Ts8Ss:QsMs@KsAJrCHrEFrGDrIBrK@rM>rO@BDGIKMORTVXZ]_acehjln|qzsxuvwtzq|o~mkhfdb_][YWTRPMKIGDB@>;97520.+)'%"    m m mmmmmmmmmmmmmlkjiihgfed d c b a ` ` _^]\[[ZYXWVVUTSRRQPONM M L!K"J#I$H%H%G&F'E(D)C)C*B+A,@-?.?.>/=0<1;2:3:3948576675858493:2;1<1<0=/>.?-@,A,A+B*C)D(E'F'F&G%H$I#J#J"K!L MNOOPQRSTTUVWXXYZ[\]]^_ ` a b b c deffghijkklmm m mm|mxmtnpn#mn'in*fn-bn1_n4[n7Xn;Tn>QoANoDKoGGoJDoMAoP>oS;oV8oY5o\2p_/pb,pe)pg&pj#pm!poprpupwpzp|pq q qqqqpnlj g eca^\ZXVT R"P$N&L(J*H,F.D0B2@4>6<8::8<7>5?3A1C/E.G,H*J)L'N%O#Q"S TVXY[]^`acd }u |uzuytxtvtutstrtptntmtkt jt!ht#gt%et&ct(bt*`t,^t-]t/[t1Yt3Ws4Vs6Ts8Rs:PsMs@KsAIsCGsEEsGCsIAsK?sM>sO;97520.+)'%"    m mmmmmmmmmmmmmmlkjiihgfe d d c b a ` `_^]\[[ZYXWVVUTSRRQPON M M!L"K#J$I%H%H&G'F(E)D*C*C+B,A-@.?.?/>0=1<2;3:3:49586776858594:3;2<1<1=0>/?.@-A,A,B+C*D)E(F'F'G&H%I$J#J#K"L!M NOOPQRSTTUVWXXYZ[\]]^_` a b b c d effghijkklmnn n nn{nwnsnpn#lo'ho*eo-ao1^o4Zo7Wo;To>PoAMoDJpGGpJCpM@pP=pS:pV7pY4p\1p_.pb+pe(pg&qj#qm qoqrquqwqzq|q q qqqrrpnlj g eca^\ZXVT R#P%N'L)J+H-F/D1B3@5>7<9::8<7>5@3B1D/E.G,I*K)L'N%P#R"S UWXZ\]_`bce }u {uzuxuwuvutusuquounuluku iu!hu#ft%dt&ct(at*_t,^t-\t/Zt1Yt3Wt4Ut6St8Rt:PtLt@JtAHtCGtEEsGCsIAsK?sM=sO;sQ9sS7sV5sX3sZ1s\/s^-s`*sc(se&sg$si"rlrnrprsrurxrzr|r r rrrrromj h eb_\ZWTQ"N%K(H+E.B1?4<78:5=2A/D+G(J$N!QUX\_c gjnnnnnnnnnnnn n n n n n nnnnn~n}n|n{n{nznynxnwnvn 0?O^m}{n`QC5(     !$&(*,.13579<>@BDGIKMORTVXZ]_acfhjl|nzqxsvutwqzo|m~khfdb_][YWTRPMKIGDB@>;97520.+)'%"    nnnnnnnnnnnnnnmlkjiihgf e d d c b a ``_^]\[[ZYXWVVUTSRRQPO N M!M"L#K$J%I%H&H'G(F)E*D*C+C,B-A.@.?/?0>1=2<3;3:4:596877868595:4;3<2<1=1>0?/@.A-A,B,C+D*E)F(F'G'H&I%J$J#K#L"M!N OOPQRSTTUVWXXYZ[\]]^_`a b b c d e ffghijkklmnnn o o~ozovosooo#ko'ho*dp-ap1]p4Zp7Vp;Sp>PpALpDIpGFpJCpM@pP7<9:;8=7?5A3B1D/F.H,J*K)M'O%P#R"T UWYZ\^_abde |v {vyvxuwuuuturupuoumuluju iu!gu#eu%du&bu(au*_u,]u-\u/Zu1Xu3Vu4Uu6St8Qt:OtLt?JtAHtCFtEDtGBtI@tK>tM2A/E+H(K$O!RUY\`d gkoooooooooooo o o o o o oooo~o}o|o{o{ozoyoxowovovo.>N]l}zn`QC5(      #%')+-02468;=?ACEHJLNPSUWY\^`bdgik|mzpxrvttvqyo{m}khfdb_][YWTRPMKIGDB@>;97520.+)'%"   oooooooooooonnmlkjiihg f e d d c b a``_^]\[[ZYXWVVUTSRRQP O N!M"M#L$K%J%I&H'H(G)F*E*D+C,C-B.A.@/?0?1>2=3<3;4:5:6978878695:5;4<3<2=1>1?0@/A.A-B,C,D+E*F)F(G'H'I&J%J$K#L#M"N!O OPQRSTTUVWXXYZ[\]]^_`ab b c d e f fghijkklmnooo o p}pypuprpnp#jp'gp*cp-`p1\p4Yq7Uq;Rq>OqALqDHqGEqJBqM?qP8<::<8=7?5A3C1E/G.H,J*L)N'O%Q#S"T VXY[]^`acdf |v zvyvwvvvuvsvrvpvnvmvkvjv hv!gv#ev%cu&bu(`u*^u+]u-[u/Yu1Xu3Vu4Tu6Ru8Qu:OuKu?IuAGuCEuEDuGBuI@uK>uM@BDGIKMORTVXZ]_acfhj|lznxqvstuqwozm|k~hfdb_][YWTRPMKIGDB@>;97520.+)'%"   ppppppppppponnmlkjiih g f e d d c ba``_^]\[[ZYXWVVUTSRRQ P O!N"M#M$L%K%J&I'H(H)G*F*E+D,C-C.B.A/@0?1?2>3=3<4;5:6:79888796:5;5<4<3=2>1?1@0A/A.B-C,D,E+F*F)G(H'I'J&J%K$L#M#N"O!O PQRSTTUVWXXYZ[\]]^_`abb c d e f f ghijkklmnoppp p p|pxquqqqmq#jq'fq*bq-_q1\q4Xq7Uq;Qq>NrAKrDHrGDrJArM>rP;rS8rV5rY2r\/r_,rb)re&sg$sj!smsosrsuswszs|s s ssssspnl j geca^\ZXV T"R$P&N(L*J,H/F0D2B4@6>8<::<8>7@5B3C1E/G.I,K*L)N'P%R#S"U WXZ[]_`bcef {w zwxwwwvvtvsvqvovnvlvkviv hv!fv#dv%cv&av(`v*^v+\v-Zv/Yv1Wv3Uv4Tv6Rv8Pv:NvKu?IuAGuCEuECuGAuI?uK=uM;uO9uQ7uS5uV3uX1uZ/u\-u^+u`)uc&ue$tg"ti tltntptstutxtzt| t tttttrpm j heb_]ZWT!Q$N'K*H-E0B3?6<99<5?2C/F+I(M%P!SWZ^be impqqqqqqqqqqq q q q q q qq~q}q|q{q{qzqyqxqwqvqvquqtq ,<KZi}xn`QC5(      #%')+-02468;=?ACFHJLNQSUWY\^`bdgi|kzmxpvrttqvoym{k}hfdb_][YWTRPMKIGDB@>;97520.+)'%"   qqqqqqqqqqponnmlkjii h g f e d d cba``_^]\[[ZYXWVVUTSRR Q P!O"N#M$M%L%K&J'I(H)H*G*F+E,D-C.C.B/A0@1?2?3>3=4<5;6:7:898897:6;5<5<4=3>2?1@1A0A/B.C-D,E,F+F*G)H(I'J'J&K%L$M#N#O"O!P QRSTTUVWXXYZ[\]]^_`abbc d e f f g hijkklmnoppqq q q{qxqtqpqlr#ir'er*br-^r1[r4Wr7Tr;Qr>MrAJrDGrGDsJAsM=sP:sS7sV4sY1s\.s_+sb)se&sg#sj smsosrtutwtzt| t tttttspnl j geca^\ZXV!T#R%P'N)L+J-H/F1D3B5@7>9<;:=8?7@5B3D1F/H.I,K*M)O'P%R#T"U WYZ\^_abdeg {w ywxwvwuwtwrwpwowmwlwjwiw gw!fw#dw%bw&aw(_v*]v+\v-Zv/Xv1Vv3Uv4Sv6Qv8Ov:NvJv?HvAFvCDvEBvGAvI?vK=vM;vO9vQ7vS5uV3uX0uZ.u\,u^*u`(uc&ue$ug!uiulunupusuuuxuzu| u uttttrpm j heb_]ZWT"Q%N(K+H.E1B4?7<:9=5@2C/G+J(M%Q!TX[_bf jmqrrrrrrrrrrr r r r r r r~r}r|r{r{rzryrxrwrvrvrurtrsr +;JYh}wn`QC5(     !$&(*,/13579<>@BDGIKMORTVX[]_acfh|jzlxovqtsquowmzk|h~fdb_][YWTRPMKIGDB@>;97520.+)'%"   rrrrrrrrrqponnmlkji i h g f e d dcba``_^]\[[ZYXWVVUTSR R Q!P"O#N$M%M%L&K'J(I)H*H*G+F,E-D.C.C/B0A1@2?3?3>4=5<6;7:8:8998:7;6<5<5=4>3?2@1A1A0B/C.D-E,F,F+G*H)I(J'J'K&L%M$N#O#O"P!Q RSTTUVWXXYZ[\]]^_`abbcd e f g g h ijkklmnoppqrr r ~r{rwrsrorlr#hr'ds*as-]s1Zs4Ws7Ss;Ps>MsAIsDFsGCsJ@sM=sP:sS7tV4tY1t\.t_+tb(te%tg"tjtmtotrtutwtzt| t uuuuuspn l j geca^\ZXV!T#R%P(N*L,J.H0F2D4B6@8>9<;:=8?7A5C3E1F/H.J,L*M)O'Q%S#T"V XY[]^`acdfg zx yxwxvxuwswrwpwnwmwkwjwhw gw!ew#cw%bw&`w(^w*]w+[w-Yw/Xw1Vw3Tw4Rw6Qw8Ow:MwIw?HwAFvCDvEBvG@vI>vK5A2D/G+K(N%Q!UX\_cg jnrrrrrrrrrrrr r r r r r ~r}r|r{r{rzryrxrwrvrvrurtrsrrr *9IXg}vn`QC5(        #%')+-02468;=?ACFHJLNQSUWY\^`beg|izkxmvptrqtovmyk{h}fdb_][YWTRPMKIGDB@>;97520.+)'%"   rrrrrrrrrqponnmlkj i i h g f e ddcba``_^]\[[ZYXWVVUTS R R!Q"P#O$N%M%M&L'K(J)I*H*H+G,F-E.D.C/C0B1A2@3?3?4>5=6<7;8:8:99:8;7<6<5=5>4?3@2A1A1B0C/D.E-F,F,G+H*I)J(J'K'L&M%N$O#O#P"Q!R STTUVWXXYZ[\]]^_`abbcde f g g h i jkklmnoppqrrs s ~szsvsrsosks#gs'ds*`s-]s1Ys4Vt7Rt;Ot>LtAItDEtGBtJ?tM:<<:>8@7A5C3E1G/I.J,L*N)P'Q%S#U"V XZ[]_`bcefh zx xxwxuxtxsxqxoxnxlxkxixhx fx!dx#cx%ax&`x(^x*\x+[w-Yw/Ww1Uw3Tw4Rw6Pw8Nw:MwIw?GwAEwCCwEAwG?wI=wK;wM9wO7wQ5wS3wU1wX/wZ-w\+w^)v`'vc%ve"vg vivlvnvpvsvuvwvzv| v vvvvurpm j heb_]ZW T#Q&N)K,H/E2B5?8<;9>5B2E/H+K(O%R!VY]`dg kossssssssssss s s s s ~s }s|s{s{szsysxswsvsvsustsssrsrs)8HWf}un`QC5(       "$&(*,/1357:<>@BDGIKMPRTVX[]_acf|hzjxlvotqqsoumxkzh|f~db_][YWTRPMKIGDB@>;97520.+)'%"   sssssssrrqponnmlk j i i h g f eddcba``_^]\[[ZYXWVVUT S R!R"Q#P$O%N%M&M'L(K)J*I*H+H,G-F.E.D/C0C1B2A3@3?4?5>6=7<8;8:9::9;8<7<6=5>5?4@3A2A1B1C0D/E.F-F,G,H+I*J)J(K'L'M&N%O$O#P#Q"R!S TTUVWXXYZ[\]]^_`abbcdef g g h i j kklmnoppqrsss s }tytutqtntjt#gt'ct*_t-\t1Xt4Ut7Rt;Nt>KuAHuDEuGAuJ>uM;uP8uS5uV2uY/u\,u_)ub&ue$ug!ujumuovrvuvwvzv| v vvvvuspn l jgeca^\ZX V"T%R'P)N+L-J/H1F3D5B7@9>;<<:>8@7B5D3F1G/I.K,M*O)P'R%T#U"W YZ\^_abdegh yy xyvyuytyrxpxoxmxlxjxixgx fx!dx#bx%ax&_x(]x*\x+Zx-Xx/Wx1Ux2Sx4Qx6Px8Nx:LxHx?FxAExCCxEAxG?xI=wK;wM9wO7wQ5wS3wU1wX/wZ-w\*w^(w`&wb$we"wg wiwlwnwpwswuwwwz w| wvvvvurp m jheb`]ZW!T$Q'N*K-H0E3B6?9<<9?5B2F/I,L(P%S!VZ]aeh lpsttttttttttt t t t ~t }t |t{t{tztytxtwtvtvtutttstrtrtqt'7GVe}sn`QC5(         #%')+.02468;=?ACFHJLNQSUWZ\^`be|gzixkvntpqrotmvkyh{f}db_][YWTRPMKIGDB@>;97520.+)'%"   ttttttsrrqponnml k j i i h g feddcba``_^]\[[ZYXWVVU T S!R"R#Q$P%O%N&M'M(L)K*J*I+H,H-G.F.E/D0C1C2B3A3@4?5?6>7=8<8;9:::;9<8<7=6>5?5@4A3A2B1C1D0E/F.F-G,H,I+J*J)K(L'M'N&O%O$P#Q#R"S!T TUVWXXYZ[\]]^_`abbcdefg g h i j k klmnoppqrsttt t |txtttqumuiu#fu'bu*_u-[u1Xu4Tu7Qu;Nu>JuAGuDDuGAuJ>uM;vP7vS4vV1vY.v\,v_)vb&ve#vg vjvmvovrvuvwvz v| vvwwwuspn l jgeca^\ZX!V#T%R'P)N+L-J/H1F3D5B7@9>;<=:?8A7C5D3F1H/J.L,M*O)Q'R%T#V"X Y[\^`acdfgi yy wyvytysyrypynymykyjyhygy ey!cy#by%`y&_y(]y*[y+Yy-Xy/Vy1Tx2Sx4Qx6Ox8Mx:KxHx?FxADxCBxE@xG>xI@BEGIKMPRTVX[]_ad|fzhxjvltoqqosmukxhzf|d~b_][YWTRPMKIGDB@>;97520.+)'%"   uuuuutsrrqponnm l k j i i h gfeddcba``_^]\[[ZYXWVV U T!S"R#R$Q%P%O&N'M(M)L*K*J+I,H-H.G.F/E0D1C2C3B3A4@5?6?7>8=8<9;::;:<9<8=7>6?5@5A4A3B2C1D1E0F/F.G-H,I,J+J*K)L(M'N'O&O%P$Q#R#S"T!T UVWXXYZ[\]]^_`abbcdefgg h i j k k lmnoppqrstuuu u {uwutupuluiu#ev'av*^v-Zv1Wv4Tv7Pv;Mv>JvAFvDCvG@vJ=vM:vP7vS4vV1vY.v\+w_(wb%we"wgwjwmwowrwuwwwz w| wwwwwusp n l jgeca^\ZX"V$T&R(P*N,L.J0H2F4D6B8@:><<>:?8A7C5E3G1I/J.L,N*P)Q'S%U#V"X Z[]_`bcefhj xz wzuztzszqzoynylykyiyhyfy ey!cy#ay%`y&^y(\y*[y+Yy-Wy/Vy1Ty2Ry4Py6Ny8My:KyGy?EyACyCByE@yG>yI;97520.+)'%"   vvvvutsrrqponn m l k j i i hgfeddcba``_^]\[[ZYXWV V U!T"S#R$R%Q%P&O'N(M)M*L*K+J,I-H.H.G/F0E1D2C3C3B4A5@6?7?8>8=9<:;;:<:<9=8>7?6@5A5A4B3C2D1E1F0F/G.H-I,J,J+K*L)M(N'O'O&P%Q$R#S#T"T!U VWXXYZ[\]]^_`abbcdefggh i j k k l mnoppqrstuuvv ~v zvwvsvovkvhv#dv'av*]v-Zv1Vw4Sw7Ow;Lw>IwAFwDBwG?wJ<<>:@8B7D5F3G1I/K.M,N*P)R'T%U#W"Y Z\]_abdeghj xz vzuzszrzpzozmzlzjzizgzfz dz!bz#az%_z&]z(\z*Zz+Xz-Wz/Uz1Sz2Qz4Pz6Nz8Ly:JyGy?EyACyCAyE?yG=yI;yK9yM7yO5yQ3yS1yU/yX-yZ+y\)y^'y`$yb"ye ygyiylynypysyuywyz y| xxxxxurp m kheb`]Z W#T&Q)N,K/H2E5B8?;<>9A6E2H/K,N(R%U!Y\`cgk nrvwwwwwwwwwww ~w }w |w {w {w zwywxwwwvwvwuwtwswrwrwqwpwownw $4CRa}pn~`QC5 (                    " $ & ( * , / 1 3 5 7 : < > @ B E G I K M P R T V X [ ] _ a| dz fx hv jt mq oo qm sk uh xf zd |b ~_ ] [ Y W T R P M K I G D B @ > ;97520.+)'%"   wwwvutsrrqpon n m l k j i ihgfeddcba``_^]\[[ZYXW V V!U"T#S$R%R%Q&P'O(N)M*M*L+K,J-I.H.H/G0F1E2D3C3C4B5A6@7?8?8>9=:<;;<:<:=9>8?7@6A5A5B4C3D2E1F1F0G/H.I-J,J,K+L*M)N(O'O'P&Q%R$S#T#T"U!V WXXYZ[\]]^_`abbcdefgghi j k k l m noppqrstuuvww }w zwvwrwnwkwgw#cw'`w*\w-Yw1Uw4Rw7Ow;Kw>HwAExDBxG?xJ;xM8xP5xS2xV/xY,x\)x_'xb$xe!xgxjxmxoxrxuxwxz x| xxxyxusp n ljgeca^\Z!X#V%T'R)P+N-L/J1H3F5D7B9@;>=zG=zI;zK9zM7zO5zQ3zS0zU.zX,zZ*z\(z^&z`$zb"yeygyiylynypysyuyw yz y|yyyyxur p mkheb`]Z!W$T'Q*N,K/H2E6B9?<!;!9!7!5!2!0!.!+!)!'!%!"! !!!!!!!!!    wwwvutsrrqpo n n m l k j iihgfeddcba``_^]\[[ZYX W V!V"U#T$S%R%R&Q'P(O)N*M*M+L,K-J.I.H/H0G1F2E3D3C4C5B6A7@8?8?9>:=;<<;<:=:>9?8@7A6A5B5C4D3E2F1F1G0H/I.J-J,K,L+M*N)O(O'P'Q&R%S$T#T#U"V!W XXYZ[\]]^_`abbcdefgghij k k l m n oppqrstuuvwww }x yxuxqxnxjxfx#cx'_x*\x-Xx1Ux4Qx7Nx;Kx>GxADxDAxG>xJ;xM8xP5xS2yV/yY,y\)y_&yb#ye ygyjymyoyryuyw yz y|yyyyxusp n ljgeca^\Z!X#V%T(R*P,N.L0J2H4F6D8B:@;>=zG"@"B"E"G"I"K"M"P"R"T"V"Y"["]"_|"az"dx"fv"ht"jq"mo"om"qk"sh"vf"xd"zb"|_"]"["Y"W"T"R"P"M"K"I"G"D"B"@">";"9"7"5"2"0"."+")"'"%""" """"""""" " """""xwwvutsrrqp o n n m l k jiihgfeddcba``_^]\[[ZY X W!V"V#U$T%S%R&R'Q(P)O*N*M+M,L-K.J.I/H0H1G2F3E3D4C5C6B7A8@8?9?:>;=<<<;=:>:?9@8A7A6B5C5D4E3F2F1G1H0I/J.J-K,L,M+N*O)O(P'Q'R&S%T$T#U#V"W!X XYZ[\]]^_`abbcdefgghijk k l m n o ppqrstuuvwxxx |x xxtxpxmyiyey#by'^y*[y-Wy1Ty4Qy7My;Jy>GyACyD@yG=yJ:yM7yP4yS1yV.yY+y\(y_%yb"yeygyjymzozrzuzw zz z|zzzzxus p nljgeca^\ Z"X$V&T(R*P,N.L0J2H4F6D8B:@<>><@:B8D7E5G3I1K/M.N,P*R)S'U%W#Y"Z \]_abdeghjl v| u|s|r|p|o|m|l|j|i{g{f{d{ b{!a{#_{%^{&\{(Z{*Y{+W{-U{/S{1R{2P{4N{6L{8J{:I{#;#9#7#5#2#0#.#+#)#'#%#"# ######### # #####xwwvutsrrq p o n n m l kjiihgfeddcba``_^]\[[Z Y X!W"V#V$U%T%S&R'R(Q)P*O*N+M,M-L.K.J/I0H1H2G3F3E4D5C6C7B8A8@9?:?;><=<<=;>:?:@9A8A7B6C5D5E4F3F2G1H1I0J/J.K-L,M,N+O*O)P(Q'R'S&T%T$U#V#W"X!X YZ[\]]^_`abbcdefgghijkk l m n o p pqrstuuvwxyyy {y wysypylyhyey#ay'^y*Zy-Wz1Sz4Pz7Lz;Iz>FzACzD@zG?<@:B8D7F5H3J1K/M.O,Q*R)T'V%W#Y"[ \^`acdfgikl v| t|s|q|p|n|m|k|j|h|g|e|d| b|!`|#_|%]|&[|(Z|*X|+V|-U|/S|1Q|2O|4N|6L|8J|:H|#N$]}$kn$z`$Q$C$5$($$ $$"      "$$$$$ $ $$$$$$$$$$"$$$&$($*$-$/$1$3$5$7$:$<$>$@$B$E$G$I$K$N$P$R$T$V$Y$[$]|$_z$ax$dv$ft$hq$jo$mm$ok$qh$sf$vd$xb$z_$|]$[$Y$W$T$R$P$M$K$I$G$D$B$@$>$;$9$7$5$2$0$.$+$)$'$%$"$ $$$$$$$$$ $ $$$$$xwwvutsrr q p o n n m lkjiihgfeddcba``_^]\[[ Z Y!X"W#V$V%U%T&S'R(R)Q*P*O+N,M-M.L.K/J0I1H2H3G3F4E5D6C7C8B8A9@:?;?<><==<>;?:@:A9A8B7C6D5E5F4F3G2H1I1J0J/K.L-M,N,O+O*P)Q(R'S'T&T%U$V#W#X"Y!Y Z[\]]^_`abbcdefgghijkkl m n o p p qrstuuvwxyyz~z zz vzszozkzgzdz#`z']z*Yz-Vz1Rz4Oz7Lz;Hz>EzABzD?{G<{J9{M5{P2{S/{V,{Y){\'{_${b!{e{g{j{m{o{r{u{w {z {|{{{zxus p nljgeca^\!Z#X%V'T)R+P-N/L1J3H5F7D9B;@=>?|E<|G:|I8|K6|M4|O2|Q0|S.|U,|W*|Z(|\&|^$|`!|b|e|g|i|k|n|p|s|u |w |z|||||zxu s pmkhec`]!Z$W&T)R,O/L2I5F8B;??%;%9%7%5%2%0%.%+%)%'%%%"% %%%%%%%%% % %%%%%xwwvutsr r q p o n n mlkjiihgfeddcba``_^]\[ [ Z!Y"X#W$V%V%U&T'S(R)R*Q*P+O,N-M.M.L/K0J1I2H3H3G4F5E6D7C8C8B9A:@;?==>D{AA{D>{G;{J8{M5{P2{S/{V,{Y){\&{_#{b {e|g|j|m|o|r|u |w |z|||||zxus p nljgeca^\!Z$X&V(T*R,P.N0L2J4H6F8D:B<@>>@}E<}G:}I8}K6}M4}O2}Q0}S.}U+}W)}Z'}\%}^#}`!}b}e}g}i}k}n|p|s|u |w |z|||||zxu s pmkhec`]!Z$W'T*R-O0L3I6F9B&@&C&E&G&I&K&N&P&R&T&V&Y&[|&]z&_x&bv&dt&fq&ho&jm&mk&oh&qf&sd&vb&x_&z]&|[&Y&W&T&R&P&M&K&I&G&D&B&@&>&;&9&7&5&2&0&.&+&)&'&%&"& &&&&&&&&& & &&&&&xwwvuts r r q p o n nmlkjiihgfeddcba``_^]\ [ [!Z"Y#X$W%V%V&U'T(S)R*R*Q+P,O-N.M.M/L0K1J2I3H3H4G5F6E7D8C8C9B:A;@>=?<@;A:A:B9C8D7E6F5F5G4H3I2J1J1K0L/M.N-O,O,P+Q*R)S(T'T'U&V%W$X#Y#Y"Z![ \]]^_`abbcdefgghijkklmn o p p q r stuuvwxyyz{|}| y| u|q|m|j|f|b|#_|'[|*X|-T|1Q|4N|7J|;G|>D|A@|D=|G:|J7|M4|P1|S.|V+|Y(|\%|_"|b|e|g|j|m|o|r|u |w |z|||||zxu s pnljgeca^ \"Z$X&V(T+R-P/N1L3J5H7F9D;B<@>>@';'9'7'5'2'0'.'+')'''%'"' ''''''''' ' '''''xwwvut s r r q p o nnmlkjiihgfeddcba``_^] \ [!["Z#Y$X%W%V&V'U(T)S*R*R+Q,P-O.N.M/M0L1K2J3I3H4H5G6F7E8D8C9C:B;A<@>?=@C}A@}D=}G9}J6}M3}P0}S-}V*}Y'}\$}_"}b}e}g}j}m}o}r}u }w }z}|}}}zxu s pnljgeca^!\#Z%X'V)T+R-P/N1L3J5H7F9D;B=@?>A~C<~E:~G9~I7~K5~M3~O1~Q.~S,~U*~W(~Z&~\$~^"~` ~b~e~g~i~k~n~p~r ~u ~w~z~|~~}zxu s pmkhec` ]#Z&W(U+R.O1L4I7F:C>?A(@(C(E(G(I(K(N(P(R(T(V(Y|([z(]x(_v(bt(dq(fo(hm(kk(mh(of(qd(sb(v_(x](z[(|Y(W(T(R(P(M(K(I(G(D(B(@(>(;(9(7(5(2(0(.(+()('(%("( ((((((((( ( (((((xwwvu t s r r q p onnmlkjiihgfeddcba``_^ ] \!["[#Z$Y%X%W&V'V(U)T*S*R+R,Q-P.O.N/M0M1L2K3J3I4H5H6G7F8E8D9C:C;B??>@=AB}A?}D<}G9}J6}M3}P0}S-~V*~Y'~\$~_!~b~e~g~j~m~o~r~u ~w ~z~|~~}zxu s pnljgeca^!\#Z%X(V*T,R.P0N2L4J6H8F:D@?>AC<~E:~G8~I6~K4~M2~O0~Q.~S,~U*~W(~Z%~\#~^!~`~b~e~g~i~k~n~p~r ~u ~w~z~|~~}zx u spmkhec`!]#Z&W)U,R/O2L5I8F;C>?A);)9)7)5)2)0).)+)))')%)") ))))))))) ) )))))xwwv u t s r r q ponnmlkjiihgfeddcba``_ ^ ]!\"[#[$Z%Y%X&W'V(V)U*T*S+R,R-Q.P.O/N0M1M2L3K3J4I5H6H7G8F8E9D:C;C???@>A=AA~A>~D;~G8~J5~M2~P/~S,~V)~Y&~\#~_ ~b~e~g~j~m~o~r ~u ~w~z~|~~}zx u s pnljgeca ^"\$Z&X(V*T,R.P0N2L4J6H8F:D<B>@@>B*@*C*E*G*I*K*N*P*R*T*W|*Yz*[x*]v*_t*bq*do*fm*hk*kh*mf*od*qb*t_*v]*x[*zY*}W*T*R*P*M*K*I*G*D*B*@*>*;*9*7*5*2*0*.*+*)*'*%*"* ********* * *****xww v u t s r rqponnmlkjiihgfeddcba`` _ ^!]"\#[$[%Z%Y&X'W(V)V*U*T+S,R-R.Q.P/O0N1M2M3L3K4J5I6H7H8G8F9E:D;C<C<B=A>@??@?A>A=BAA>D:G7J4M1P.S+V(Y%\"_ begjmor u wz|}zx u spnljgeca ^"\$Z'X)V+T-R/P1N3L5J7H9F;D=B?@A>B,;,9,7,5,2,0,.,+,),',%,", ,,,,,,,,, , ,,,,,~x~w ~w ~v ~u ~t ~s ~r~r~q~p~o~n~n~m~l~k~j~i~i~h~g~f~e~d~d~c~b~a~` ~` ~_!~^"~]#~\$~[%~[%~Z&~Y'~X(~W)~V*~V*~U+~T,~S-~R.~R.~Q/~P0~O1~N2~M3~M3~L4~K5~J6~I7~H8~H8~G9~F:~E;~D<~C<~C=~B>~A?~@@~?A~?A~>B~=C~@A=D:G7J3M0P-S*V'Y%\"_begjmor u wz|~~}~z~x ~u ~s~p~n~l~j~g~e~c~a!~^#~\%~Z'~X)~V+~T-~R0~P2~N4~L6~J8~H:~F;~D=~B?~@A~>C~A-@-C-E-G-I-L-N-P-R-T|-Wz-Yx-[v-]t-_q-bo-dm-fk-hh-kf-md-ob-q_-t]-v[-xY-zW-}T-R-P-M-K-I-G-D-B-@->-;-9-7-5-2-0-.-+-)-'-%-"- --------- - -----~x ~w ~w ~v ~u ~t ~s~r~r~q~p~o~n~n~m~l~k~j~i~i~h~g~f~e~d~d~c~b~a ~` ~`!~_"~^#~]$~\%~[%~[&~Z'~Y(~X)~W*~V*~V+~U,~T-~S.~R.~R/~Q0~P1~O2~N3~M3~M4~L5~K6~J7~I8~H8~H9~G:~F;~E<~D<~C=~C>~B?~A@~@A~?A~?B~>C~=D~?A~B@~@B~>D~}CA}@D}.;.9.7.5.2.0...+.).'.%.". ......... . ..... }x }w }w }v }u }t}s}r}r}q}p}o}n}n}m}l}k}j}i}i}h}g}f}e}d}d}c}b }a }`!}`"}_#}^$}]%}\%}[&}['}Z(}Y)}X*}W*}V+}V,}U-}T.}S.}R/}R0}Q1}P2}O3}N3}M4}M5}L6}K7}J8}I8}H9}H:}G;}F<}E<}D=}C>}C?}B@}AA}@A}?B}?C}>D}=E}>A;D8G5J2M/P,S)V&Y#\ _begjmo r uwz|}}}}z }x }u}s}p}n}l}j}g}e}c }a"}^$}\&}Z(}X+}V-}T/}R1}P3}N5}L7}J9}H;}F=}D?}B@}@B}>D}/A/C/E/G/I/L/N/P/R|/Tz/Wx/Yv/[t/]q/`o/bm/dk/fh/hf/kd/mb/o_/q]/t[/vY/xW/zT/}R/P/M/K/I/G/D/B/@/>/;/9/7/5/2/0/./+/)/'/%/"/ ///////// / ///// |x |w |w |v |u|t|s|r|r|q|p|o|n|n|m|l|k|j|i|i|h|g|f|e|d|d|c |b |a!|`"|`#|_$|^%|]%|\&|['|[(|Z)|Y*|X*|W+|V,|V-|U.|T.|S/|R0|R1|Q2|P3|O3|N4|M5|M6|L7|K8|J8|I9|H:|H;|G<|F<|E=|D>|C?|C@|BA|AA|@B|?C|?D|>E|=F|>A;D7G4J1M.P+S(V%Y"\ _begjmo r uwz|||}|z |x |u|s|p|n|l|j|g|e|c }a#}^%}\'}Z)}X+}V-}T/}R1}P3}N5}L7}J9}H;}F=}D?}BA}@C}>E}?0;09070502000.0+0)0'0%0"0 000000000 0 00000 {x {w {w {v{u{t{s{r{r{q{p{o{n{n{m{l{k{j{i{i{h{g{f{e{d{d {c {b!{a"{`#{`${_%{^%{]&{\'{[({[){Z*{Y*{X+{W,{V-{V.{U.{T/{S0{R1{R2{Q3{P3{O4{N5{M6{M7{L8{K8{J9{I:{H;{H<{G<{F={E>{D?{C@{CA{BA{AB{@C{?D{?E{>F{=F{=A:D7G4J1M.P+S(V%Y"\_begjmo r uwz|||}|z |x |u|s|p|n|l|j|g|e|c!|a#|^%|\(|Z*|X,|V.|T0|R2|P4|N6|L8|J:|H<|F>|D@|BB|@C|>E|?1A1C1E1G1I1L1N1P|1Rz1Tx1Wv1Yt1[q1]o1`m1bk1dh1ff1id1kb1m_1o]1r[1tY1vW1xT1zR1}P1M1K1I1G1D1B1@1>1;19171512101.1+1)1'1%1"1 111111111 1 11111 zx zw zwzvzuztzszrzrzqzpzoznznzmzlzkzjzizizhzgzfzezd zd zc!zb"za#z`$z`%z_%z^&z]'z\(z[)z[*zZ*zY+zX,zW-zV.zV.zU/zT0zS1zR2zR3zQ3zP4zO5zN6zM7zM8zL8zK9zJ:zI;zHzE?zD@zCAzCAzBBzACz@Dz?Ez?Fz>Fz=Gz{D@{BB{@D|>F|zFAzCDz@Gz=Jz9Mz6Qz3Tz0Wz,[z)^z&bz"ezizlzpztzxz {y yyyxwvvutsrrq p o n m m lkjiihgfeedcba`2 "33 3/2?2N}2]n2k`2zQ2C252(22 220.,*' % #!"$ & (*,.12222 2 2 222222222!2#2%2'2*2,2.20222427292;2=2?2B2D2F2H2K2M2O|2Qz2Sx2Vv2Xt2Zq2\o2_m2ak2ch2ef2gd2jb2l_2n]2p[2sY2uW2wT2yR2|P2~M2K2I2G2D2B2@2>2;29272522202.2+2)2'2%2"2 222222222 2 22222 yx ywywyvyuytysyryryqypyoynynymylykyjyiyiyhygyfye yd yd!yc"yb#ya$y`%y`%y_&y^'y](y\)y[*y[*yZ+yY,yX-yW.yV.yV/yU0yT1yS2yR3yR3yQ4yP5yO6yN7yM8yM8yL9yK:yJ;yIyF?yE@yDAyCAyCByBCyADy@Ey?Fy?Fy>Gy=HyF{==?;A9C7E5G3I1K/M-O+Q)S'U$W"Y \^`bdgikn p ruwzzzz} z{ zxzvzszpznzkzhzf!yc$y`'y])y[,yX/yU2yR5yO8yL;yI>yFAyCEy@Hy=Ky9Ny6Qy3Uy0Xy,\y)_y&cy"fyjymyqyuyxy |y yyxwvvutsrrqp o n m m l kjiihgfeedcba``3""344.4>4M}4\n3j`3yQ3C353(33 331/-+( & $" "$ & (*,.133333 3 333333333 3"3$3&3(3+3-3/313336383:3<3>3A3C3E3G3I3L3N|3Pz3Rx3Uv3Wt3Yq3[o3]m3`k3bh3df3fd3ib3k_3m]3o[3rY3tW3vT3xR3{P3}M3K3I3G3D3B3@3>3;39373532303.3+3)3'3%3"3 333333333 3 33333 yxywywyvyuytysyryryqypyoynynymylykyjyiyiyhygyf ye yd!yd"yc#yb$ya%y`%y`&y_'y^(y])y\*y[*y[+yZ,yY-yX.yW.yV/yV0yU1yT2yS3yR3yR4yQ5yP6yO7yN8yM8yM9yL:yK;yJyG?yF@yEAyDAyCByCCyBDyAEy@Fy?Fy?Gy>Hy=Iy>;A8D4G1J.M+P(S%V"Y \_begjm o ruwzzzz} zz zxzuzszpznzlzjzgze!zc#za%z^'z\)zZ+zX.zV0zT2zR4zP6zN8zL:zJzF?zDAzBCz@Ez>Gz=4;49474542404.4+4)4'4%4"4 444444444 4 44444xxxwxwxvxuxtxsxrxrxqxpxoxnxnxmxlxkxjxixixhxg xf xe!xd"xd#xc$xb%xa%x`&x`'x_(x^)x]*x\*x[+x[,xZ-xY.xX.xW/xV0xV1xU2xT3xS3xR4xR5xQ6xP7xO8xN8xM9xM:xL;xKxH?xG@xFAxEAxDBxCCxCDxBExAFx@Fx?Gx?Hx>Ix=Jx:A7D4G1J.M+P(S%V"Y\_begjm o ruwyyyy} yz yxyuysypynylyjygye!yc$ya&y^(y\*yZ,zX.zV0zT2zR4zP6zN8zL:zJzF@zDBzBDz@Fz>Hz5A5C5E5G5I5L|5Nz5Px5Rv5Ut5Wq5Yo5[m5]k5`h5bf5dd5fb5i_5k]5m[5oY5rW5tT5vR5xP5{M5}K5I5G5D5B5@5>5;59575552505.5+5)5'5%5"5 555555555 5 55566wxwwwwwvwuwtwswrwrwqwpwownwnwmwlwkwjwiwiwh wg wf!we"wd#wd$wc%wb%wa&w`'w`(w_)w^*w]*w\+w[,w[-wZ.wY.wX/wW0wV1wV2wU3wT3wS4wR5wR6wQ7wP8wO8wN9wM:wM;wLwH?wH@wGAwFAwEBwDCwCDwCEwBFwAFw@Gw?Hw?Iw>Jw=Kw9A6D3G0J-M*P'S$V!Y\_begjm oruwxxxx} yz yxyuysypynylyjyg ye"yc$ya&y^(y\+yZ-yX/yV1yT3yR5yP7yN9yL;yJ=yH?yFAyDCyBDy@Fy>Hy6;69777572707.7+7)7'7%7"7 777777777 7 77777vxvwvwvvvuvtvsvrvrvqvpvovnvnvmvlvkvjvivi vh vg!vf"ve#vd$vd%vc%vb&va'v`(v`)v_*v^*v]+v\,v[-v[.vZ.vY/vX0vW1vV2vV3vU3vT4vS5vR6vR7vQ8vP8vO9vN:vM;vMvI?vH@vHAvGAvFBvECvDDvCEvCFvBFvAGv@Hv?Iv?Jv>Kv=Kv9A5D2G/J,M)P&S#V Y\_begj m oruwxxx x} xzxxxuxsxpxnxlxjxg xe#xc%xa'x^)x\+xZ-xX/xV1xT3xR5xP7xN9xL;yJ=yH?yFAyDCyBEy@Gy>Iy;<=:?8A6C5E3G1I/K-M*O(Q&S$U"W Y\^`bdgik n pruwwww w} w{wxwvwswpwnwkwi!wf$wc&w`)w^,w[/wX2wU5vR8vO;vL>vIAvFDvCGv@Kv=Nv:Qv6Tv3Xv0[v,^v)bv&ev"ivmvpvtvxv{u u uuutsrrqponmm l k j i i hgfeedcba``_^]\8'"3 88*898H}8Wn8f`8tQ8C858(77 77531/- + (&$" "$&( * ,.13577777 7 777777777 7"7$7&7)7+7-7/717376787:7<7>7A7C7E7G7J|7Lz7Nx7Pv7Rt7Uq7Wo7Ym7[k7^h7`f8bd8db8f_8i]8k[8mY8oW8rT8tR8vP8xM8{K8}I8G8D8B8@8>8;89878582808.8+8)8'8%8"8 888888888 8 88888uxuwuwuvuuutusururuqupuoununumulukujui ui uh!ug"uf#ue$ud%ud%uc&ub'ua(u`)u`*u_*u^+u],u\-u[.u[.uZ/uY0uX1uW2uV3uV3uU4uT5uS6uR7uR8uQ8uP9uO:uN;uMuJ?uI@uHAuHAuGBuFCuEDuDEuCFuCFuBGuAHu@Iu?Ju?Ku>Ku=Lu;;>8A5D2G.J+M(P%S#V Y\_begj m oruwwww w} wzwxwuwswpwnwlwjwg!xe#xc%xa(x^*x\,xZ.xX0xV2xT4xR6xP8xN:xLxH@xFBxDDxBFx@Gx>Ix;<=:?8A6C4E2G0I.K,M*O(Q&S$U!WY\^`bdgi k n pruwwwv v} v{vxvvvsvpvnvkvi"vf$vc'v`*v^-v[0vX3vU6vR9vO9;99979592909.9+9)9'9%9"9 999999999 9 99999txtwtwtvtutttstrtrtqtptotntntmtltktj ti ti!th"tg#tf$te%td%td&tc'tb(ta)t`*t`*t_+t^,t]-t\.t[.t[/tZ0tY1tX2tW3tV3tV4tU5tT6tS7tR8tR8tQ9tP:tO;tNtK?tJ@tIAtHAtHBtGCtFDtEEtDFtCFtCGtBHtAIt@Jt?Kt?Kt>Lt=Mt7A4D1G.J+M(P%S"VY\_begj m oruvvvv w} wzwxwuwswpwnwlwjwg"we$wc&wa(w^*w\,wZ.wX1wV3wT5wR7wP9wN;wL=wJ?wH@wFBwDDwBFw@Hx>Jx:;:9:7:5:2:0:.:+:):':%:": ::::::::: : :::::txtwtwtvtutttstrtrtqtptotntntmtltk tj ti!ti"th#tg$tf%te%td&td'tc(tb)ta*t`*t`+t_,t^-t].t\.t[/t[0tZ1tY2tX3tW3tV4tV5tU6tT7tS8tR8tR9tQ:tP;tOtL?tK@tJAtIAtHBtHCtGDtFEtEFtDFtCGtCHtBItAJt@Kt?Kt?Lt>Mt=Nt6A3D0G-J*M'P$S!VY\_begj moruvvv v v} vzvxvuvsvpvnvlvj vg"ve$vc'va)v^+v\-vZ/wX1wV3wT5wR7wP9wN;wL=wJ?wHAwFCwDEwBGw@Iw>Jw9<;;=9?7A5C3E1G/I-K+M)O'Q%S"U WY\^`bdgi k npruuuu u u}u{uxuvusuqunuk ui#uf&uc(u`+u^.t[1tX4tU7tR:tO=tL@tICtFFtCIt@Mt=Pt:St6Wt3Zt0]t-at)dt&hs"ksosrsvszs~s s ssrrqponmmlkj i i h g f eedcba``_^]\\[Z;*" 3<<&<6;;;9;7;5;2;0;.;+;);';%;"; ;;;;;;;;; ; ;;;;;sxswswsvsustsssrsrsqspsosnsnsmsl sk sj!si"si#sh$sg%sf%se&sd'sd(sc)sb*sa*s`+s`,s_-s^.s].s\/s[0s[1sZ2sY3sX3sW4sV5sV6sU7sT8sS8sR9sR:sQ;sPsM?sL@sKAsJAsIBsHCsHDsGEsFFsEFsDGsCHsCIsBJsAKs@Ks?Ls?Ms>Ns=Os6A2D/G,J)M&P#S VY\_beg j moruuuu u u}uzuxuuusupunvlvj!vg#ve%vc'va)v^+v\.vZ0vX2vV4vT6vR8vP:vNvJ@vHBvFDvDEvBGv@Iv>Kv9<;:=8?6A4C2E0G.I,K*M(O&Q$S"U WY\^`bdgi k npruuuu u t}t{txtvtstqtntk!ti$tf&tc)t`,t^/t[2tX5tU8tR;tO>tLAsIDsFGsCJs@Ms=Qs:Ts7Ws3[s0^s-as)es&hs"lspssrwr{r~r r rrrqponmmlkji i h g f e edcba``_^]\\[ZY<+" 3==%=5=D}=Sn<;<9<7<5<2<0<.<+<)<'<%<"< <<<<<<<<< < <<<<<rxrwrwrvrurtrsrrrrrqrprornrnrm rl rk!rj"ri#ri$rh%rg%rf&re'rd(rd)rc*rb*ra+r`,r`-r_.r^.r]/r\0r[1r[2rZ3rY3rX4rW5rV6rV7rU8rT8rS9rR:rR;rQrM?rM@rLArKArJBrICrHDrHErGFrFFrEGrDHrCIrCJrBKrAKr@Lr?Mr?Nr>Or=Or7;;8>5A2D/G,J)M&P#S VY\_beg j mortttt u u}uzuxuuusupunuluj!ug#ue&uc(ua*u^,u\.uZ0uX2uV4uT6uR8uP:vNvJ@vHBvFDvDFvBHv@Jv>LvsLAsIEsFHsCKs@Nr=Qr:Ur7Xr3[r0_r-br)fr&ir"mrprtrxr{rq q qqqponmmlkjii h g f e e dcba``_^]\\[ZYX>-" 3>>$>3>C}>Rn>``=oQ=}C=5=(== =<:8642 0 .,)'%#!"$&(*,. 1 3579;==== = = =========!=#=%=(=*=,=.=0=2=5=7=9=;=>=@=B=D|=Fz=Ix=Kv=Mt=Oq=Qo=Tm=Vk=Xh=Zf=]d=_b=a_=c]=f[=hY=jW=lT=nR=qP=sM=uK=xI=zG=|D=~B=@=>=;=9=7=5=2=0=.=+=)='=%="= ========= = =====qxqwqwqvquqtqsqrqrqqqpqoqnqn qm ql!qk"qj#qi$qi%qh%qg&qf'qe(qd)qd*qc*qb+qa,q`-q`.q_.q^/q]0q\1q[2q[3qZ3qY4qX5qW6qV7qV8qU8qT9qS:qR;qRqN?qM@qMAqLAqKBqJCqIDqHEqHFqGFqFGqEHqDIqCJqCKqBKqALq@Mq?Nq?Oq>Oq=Pq7:;7>4A1D.G+J(M%P"SVY\_beg j mortttt t t}tztxtutstptntl tj"tg$te&tc(ua+u^-u\/uZ1uX3uV5uT7uR9uP;uN=uL?uJAuHCuFEuDGuBHu@Ju>Lu|C>5>(>> >>;9753 1 /-+(&$" "$&(*,. 1 3579;>>>>> > >>>>>>>>> >">$>&>)>+>->/>1>4>6>8>:><>?>A>C|>Ez>Gx>Jv>Lt>Nq>Po>Sm>Uk>Wh>Yf>[d>^b>`_>b]>d[>gY>iW>kT>mR>pP>rM>tK>vI>yG>{D>}B>@>>>;>9>7>5>2>0>.>+>)>'>%>"> >>>>>>>>> > >>>>>pxpwpwpvpuptpsprprpqpppopn pn pm!pl"pk#pj$pi%pi%ph&pg'pf(pe)pd*pd*pc+pb,pa-p`.p`.p_/p^0p]1p\2p[3p[3pZ4pY5pX6pW7pV8pV8pU9pT:pS;pRpO?pN@pMApMApLBpKCpJDpIEpHFpHFpGGpFHpEIpDJpCKpCKpBLpAMp@Np?Op?Op>Pp=Qp3A0D-G*J'M$P!SVY\_be g jmorsss s ss}szsxsusstptntl tj#tg%te'tc)ta+t^-t\/tZ1tX4tV6tT8tR:tPtL@tJAtHCuFEuDGuBIu@Ku>Mu8<9:;8=6?5A3C1E/G-I+K(M&O$Q"S UWY[^`bdg i kmprsss s ss}r{rxrvrsrqrn rk#ri&rf(rc+ra.r^1r[4rX7rU:qR=qO@qLCqIFqFIqCLq@Oq=Sq:Vq7Yq3]q0`q-dp)gp&kp#nprpupyp}pp p pponmmlkjiihg f e e d c ba``_^]\\[ZYXWW@/" 3AA"@1@@}@On@^`@mQ@{C?5?(?? ??=:864 2 0.,)'%#!"$&(*,.1 3 579;>???? ? ? ?????????!?#?%?(?*?,?.?0?3?5?7?9?;?>?@?B|?Dz?Fx?Iv?Kt?Mq?Oo?Qm?Tk?Vh?Xf?Zd?]b?__?a]?c[?fY?hW?jT?lR?oP?qM?sK?uI?xG?zD?|B?~@?>?;?9?7?5?2?0?.?+?)?'?%?"? ????????? ? ?????oxowowovouotosororoqopoo on on!om"ol#ok$oj%oi%oi&oh'og(of)oe*od*od+oc,ob-oa.o`.o`/o_0o^1o]2o\3o[3o[4oZ5oY6oX7oW8oV8oV9oU:oT;oSoP?oO@oNAoMAoMBoLCoKDoJEoIFoHFoHGoGHoFIoEJoDKoCKoCLoBMoANo@Oo?Oo?Po>Qo=Ro3A/D,G)J&M#P SVY\_be g jmorrrr r ss}szsxsussspsnsl!sj#sg%se(sc*sa,s^.s\0sZ2sX4tV6tT8tR:tPtL@tJBtHDtFFtDHtBJt@Kt>Mt;975 3 1/-+(&$" "$&(*,.1 3 579;>@@@@@ @ @@@@@@@@@ @"@$@&@)@+@-@/@1@4@6@8@:@<@?@A|@Cz@Ex@Hv@Jt@Lq@No@Pm@Sk@Uh@Wf@Yd@\b@^_@`]@b[@dY@gW@iT@kR@mP@pM@rK@tI@vG@yD@{B@}@@>@;@9@7@5@2@0@.@+@)@'@%@"@ @@@@@@AAA A AAAAAoxowowovouotosororoqop oo on!on"om#ol$ok%oj%oi&oi'oh(og)of*oe*od+od,oc-ob.oa.o`/o`0o_1o^2o]3o\3o[4o[5oZ6oY7oX8oW8oV9oV:oU;oToQ?oP@oOAoNAoMBoMCoLDoKEoJFoIFoHGoHHoGIoFJoEKoDKoCLoCMoBNoAOo@Oo?Po?Qo>Ro=So2A/D,G)J&M#P SVY\_be g jmorrrr r rr}rzrxrursrprnrl"rj$rg&se(sc*sa,s^/s\1sZ3sX5sV7sT9sR;sP=sN?sLAsJCsHEsFFsDHsBJs@Lt>NtpOApLDpIGpFJpCNp@Qo=To:Wo7[o3^o0bo-eo)io&lo#posown{n~nn n nnmmlkjiihgfe e d c b a ``_^]\\[ZYXWWVUC1 "3CCC/B>}BMnB\`BjQByCB5A(AA AA?=:86 4 20.,)'%#!"$&(*,.13 5 79;>@AAAA A A AAAAAAAAA!A#A%A(A*A,A.A0A3A5A7A9A;A>A@|ABzADxAFvAItAKqAMoAOmARkAThAVfAXdAZbA]_A_]Aa[AcYAfWAhTAjRAlPAoMAqKAsIAuGAxDAzBA|@A~>A;A9A7A5A2A0A.B+B)B'B%B"B BBBBBBBBB B BBBBBnxnwnwnvnuntnsnrnrnq np no!nn"nn#nm$nl%nk%nj&ni'ni(nh)ng*nf*ne+nd,nd-nc.nb.na/n`0n`1n_2n^3n]3n\4n[5n[6nZ7nY8nX8nW9nV:nV;nUnR?nQ@nPAnOAnNBnMCnMDnLEnKFnJFnIGnHHnHInGJnFKnEKnDLnCMnCNnBOnAOn@Pn?Qn?Rn>Sn=Tn4;77;4>1A.D+G(J%M"PSVY\_be g jmoqqqq q qq}qzqxqursrprn rl"rj$rg're)rc+ra-r^/r\1rZ3rX5rV7rT9rR;rP=sN?sLAsJCsHEsFGsDIsBKs@Ms>Ns6<8;99;7=5?3A1C/E-G+I)K'M%O#Q SUWY[^`bd g ikmpqqqq q qq}p{pxpvpspqpn"pl%pi'pf*pc-pa0p^3p[6oX9oU<97 5 31/-+(&$" "$&(*,.13 5 79;>@BBBBB B BBBBBBBBB B"B$B'B)B+B-B/B1B4B6B8B:B=B?|BAzBCxBEvBHtBJqBLoBNmBPkBShBUfBWdBYbB\_B^]B`[BbYBeWBgTBiRBkPBnMBpKBrIBtGCwDCyBC{@C}>C;C9C7C5C2C0C.C+C)C'C%C"C CCCCCCCCC C CCCCCmxmwmwmvmumtmsmrmr mq mp!mo"mn#mn$mm%ml%mk&mj'mi(mi)mh*mg*mf+me,md-md.mc.mb/ma0m`1m`2m_3m^3m]4m\5m[6m[7mZ8mY8mX9mW:mV;mVmR?mR@mQAmPAmOBmNCmMDmMEmLFmKFmJGmIHmHImHJmGKmFKmELmDMmCNmCOmBOmAPm@Qm?Rm?Sm>Tm=Tm0A-D*G'J$M!PSVY\_b e gjmoppp p qqq}qzqxquqsqpqn!ql#qj%qg'qe)qc,qa.q^0r\2rZ4rX6rV8rT:rRrN@rLBrJDrHFrFHrDIrBKr@Mr>Or6<8:98;6=4?2A0C.E,G*I(K&M$O"Q SUWY[^`bd g ikmpppp p ppp}p{pxpvpspq on#ol%oi(of+oc.oa1o^4o[6oX9oU@BCCCC C C CCCCCCCCC!C#C%C(C*C,C.C0C3C5C7C9C;C>|C@zCBxCDvCFtCIqCKoCMmCOkCRhCTfCVdCXbC[_C]]C_[DaYDcWDfTDhRDjPDlMDoKDqIDsGDuDDxBDz@D|>D~;D9D7D5D2D0D.D+D)D'D%D"D DDDDDDDDD D DDDDDlxlwlwlvlultlslr lr lq!lp"lo#ln$ln%lm%ll&lk'lj(li)li*lh*lg+lf,le-ld.ld.lc/lb0la1l`2l`3l_3l^4l]5l\6l[7l[8lZ8lY9lX:lW;lVlS?lR@lRAlQAlPBlOClNDlMElMFlLFlKGlJHlIIlHJlHKlGKlFLlEMlDNlCOlCOlBPlAQl@Rl?Sl?Tl>Tl=Ul0A-D)G&J#M!PSVY\_b e gjmoppp p ppp}pzpxpupspppn!pl#qj&qg(qe*qc,qa.q^0q\2qZ5qX7qV9qT;qR=qP?qN@qLBqJDrHFrFHrDJrBLr@Nr>Pr<9 7 531/-+(&$"" $&(*,.135 7 9;>@BDDDDD D DDDDDDDDD D"D$D'D)D+D-D/D2D4D6D8D:D=|D?zDAxDCvDEtDHqDJoELmENkEQhESfEUdEWbEY_E\]E^[E`YEbWEeTEgREiPEkMEnKEpIErGEtDEwBEy@E{>E};E9E7E5E2E0E.E+E)E'E%E"E EEEEEEEEE E EEEEEkxkwkwkvkuktks kr kr!kq"kp#ko$kn%kn%km&kl'kk(kj)ki*ki*kh+kg,kf-ke.kd.kd/kc0kb1ka2k`3k`3k_4k^5k]6k\7k[8k[8kZ9kY:kX;kWkT?kS@kRAkRAkQBkPCkODkNEkMFkMFkLGkKHkJIkIJkHKkHKkGLkFMkENkDOkCOkCPkBQkARk@Sk?Tk?Tk>Uk=Vk/A,D)G&J#M PSVY\_b e gjmoooo o ooo}ozoxpupspp pn"pl$pj&pg(pe+pc-pa/p^1p\3pZ5pX7qV9qT;qR=qP?qNAqLCqJEqHGqFIqDKqBLq@Nq>Pq4=6;8997;5=3?1A/C-E+G)I'K%M#O!QSUWY[^`b d fikmoooo o ooo~n{nynvnsnq!nn$nl'ni)nf,nd/na2n^5m[8mX;mU>mSAmPDmMGmJJmGMmDPm@Tm=Wl:Zl7^l4al0el-hl*kl&ol#slvkzk~kkk k kkjiihgfeedcb a ` ` _ ^ ]\\[ZYXWWVUTSSRG6%"3C HG*G:}GInGW`FfQFtCF5F(FE EECA?=: 8 6420.,)'%#"!$&(*,.1357 9 ;>@BDEEEE E E EEEEEEEEE!E#E%E(E*E,E.E0E3E5E7F9F;|F>zF@xFBvFDtFGqFIoFKmFMkFOhFRfFTdFVbFX_F[]F][F_YFaWFdTFfRFhPFjMFmKFoIFqGFsDFvBFx@Fz>F|;F9F7F5F2F0F.F+F)F'F%F"F FFFFFFFFF F FFFFFkxkwkwkvkukt ks kr!kr"kq#kp$ko%kn%kn&km'kl(kk)kj*ki*ki+kh,kg-kf.ke/kd/kd0kc1kb2ka3k`3k`4k_5k^6k]7k\8k[8k[9kZ:kY;kXkU?kT@kSAkRAkRBkQCkPDkOEkNFkMFkMGkLHkKIkJJkIKkHKkHLkGMkFNkEOkDOkCPkCQkBRkASk@Tk?Tk?Uk>Vk=Wk1;4874;1>.A+D(G%J"MPSVY\_b e gjmnnnn n ooo}ozoxouosop on"ol%oj'og)oe+pc-pa/p^2p\4pZ6pX8pV:pTpP@pNBpLDpJFpHGpFIqDKqBMq@Oq>Qq4<6:8896;4=3?1A/C-E+G)I'K$M"O QSUWY[^`b d fikmnnnn n nnn~n{nynvnsmq"mn%ml'mi*mf-md0ma3m^6m[8mX;mU>lSAlPElMHlJKlGNlDQl@Tl=Xl:[l7^k4bk0ek-ik*lk&pk#skwk{k~jjj j jjiihgfeedcba ` ` _ ^ ] \\[ZYXWWVUTSSRQI7&"3C IH)H8}HGnHV`GeQGsCG5G(GF FFDB@>< 9 7531/-+(&$""$ &(*,.1357 9 ;>@BDFFFFF F FFFFFFFFF F"F$G'G)G+G-G/G2G4G6G8G:|G=zG?xGAvGCtGEqGHoGJmGLkGNhGQfGSdGUbGW_GY]G\[G^YG`WGbTGeRGgPGiMGkKGnIGpGGrDGtBGw@Gy>G{;G}9G7G5G2G0G.G+G)G'G%G"G GGGGGGGGG G GGGGGjxjwjwjvju jt js!jr"jr#jq$jp%jo%jn&jn'jm(jl)jk*jj*ji+ji,jh-jg.jf/je/jd0jd1jc2jb3ja3j`4j`5j_6j^7j]8j\8j[9j[:jZ;jYjV?jU@jTAjSAjRBjRCjQDjPEjOFjNFjMGjMHjLIjKJjJKjIKjHLjHMjGNjFOjEOjDPjCQjCRjBSjATj@Tj?Uj?Vj>Wj=Xj-A*D'G$J!MPSVY\_ b egjmmnn n nnnn}nznxnunsnp!on#ol%oj'og*oe,oc.oa0o^2o\4oZ6oX8oV:oTpP@pNBpLDpJFpHHpFJpDLpBNp@Op>Qp@BDFGGGG G G GGGHHHHHH!H#H%H(H*H,H.H0H3H5H7H9|HxH@vHBtHDqHGoHImHKkHMhHOfHRdHTbHV_HX]H[[H]YH_WHaTHdRHfPHhMHjKHmIHoGHqDHsBHv@Hx>Hz;H|9H7H5H2H0H.H+H)H'H%H"H HHHHHHHHH H HHHHHixiwiwiv iu it!is"ir#ir$iq%ip%io&in'in(im)il*ik*ij+ii,ii-ih.ig/if/ie0id1id2ic3ib3ia4i`5i`6i_7i^8i]8i\9i[:i[;iZiV?iV@iUAiTAiSBiRCiRDiQEiPFiOFiNGiMHiMIiLJiKKiJKiILiHMiHNiGOiFOiEPiDQiCRiCSiBTiATi@Ui?Vi?Wi>Xi=Yi-A*D'G$J!MPSVY\_ b egjmmmm m mmmm}mznxnunsnp!nn$nl&nj(ng*ne,nc/na1n^3o\5oZ7oX9oV;oT=oR?oPAoNCoLEoJGoHIoFJoDLoBNo@Pp>Rp < 97531/-+(&"$$"& (*,.13579 ; >@BDFHHIII I IIIIIIIII I"I$I'I)I+I-I/I2I4I6I8|I:zI=xI?vIAtICqIFoIHmIJkILhINfIQdISbIU_IW]IZ[I\YI^WI`TIbRIePIgMIiKIkIInGIpDIrBIt@Iw>Iy;I{9I~7I5I2I0I.I+I)I'I%I"I IIIIIIIII I IIIIIhxhwhw hv hu!ht"hs#hr$hr%hq%hp&ho'hn(hn)hm*hl*hk+hj,hi-hi.hh/hg/hf0he1hd2hd3hc3hb4ha5h`6h`7h_8h^8h]9h\:h[;h[hW?hV@hVAhUAhTBhSChRDhREhQFhPFhOGhNHhMIhMJhLKhKKhJLhIMhHNhHOhGOhFPhEQhDRhCShCThBThAUh@Vh?Wh?Xh>Yh=Yh,A)D&G#J MPSVY\_ b egjllll l lmmm}mzmxmums mp"mn$ml'mj)ng+ne-nc/na1n^3n\5nZ8nX:nVnR@nPAnNCnLEoJGoHIoFKoDMoBOo@Qo>Ro2<4:697795;3=1?/A-C+E)G'I%K#M!OQSUWY[^` b dfikmmll l llll~l{lylvlt!kq$kn'kl)ki,kf/kd2ka5k^8k[;kX=jV@jSDjPGjMJjJMjGPjDSjAWj=Zi:]i7ai4di0gi-ki*ni&ri#vhyh}hhhh h gggfeedcba``_ ^ ] \ \ [ ZYXWWVUTSSRQPOOL;*"3 CLL&L5}KDnKS`KaQKpCJ~5J(JJ IIGECA? = :86420.,)'"%$#&!(*,.13579; > @BDFHJJJJ J JJJJJJJJJJ!J#J&J(J*J,J.J1J3J5J7|J9zJvJ@tJBqJDoJGmJIkJKhJMfJPdJRbJT_JV]JX[J[YJ]WJ_TJaRJdPJfMJhKJjIJmGJoDJqBJs@Jv>Jx;Jz9J|7J5J2J0J.J+J)J'J%J"J JJJJJJJJJ J JKKKKgxgw gw gv!gu"gt#gs$gr%gr%gq&gp'go(gn)gn*gm*gl+gk,gj-gi.gi/gh/gg0gf1ge2gd3gd3gc4gb5ga6g`7g`8g_8g^9g]:g\;g[gX?gW@gVAgVAgUBgTCgSDgREgRFgQFgPGgOHgNIgMJgMKgLKgKLgJMgINgHOgHOgGPgFQgERgDSgCTgCTgBUgAVg@Wg?Xg?Yg>Yg=Zg<[g;\g:]g:]g9^g8_g7`g6ag5bg5bg4cg3dg2eg1fg1gg0gg/hg.ig-jg,kg,kg+lg*mg)ng(og'pg'pg&qg%rg$sg#tg#ug"ug!vg wgxgygzgzg{g|g}g~g~gggggggggggggg g g g g g gggggggggggeb ^ ZWSOLH#E'B*>-;184571;.>+A(D%G"JMPSVY\_ b egjkkl l lllll}lzlxluls mp#mn%ml'mj)mg,me.mc0ma2m^4m\6mZ8mX:nVnR@nPBnNDnLFnJHnHJnFLnDMnBOn@Qn>Sn2<4:687694;2=0?.A,C*E(G&I$K"M OQSUWY[^` b dfikllll l lkkk~k{kykvkt"kq$kn'kl*ji-jf0jd2ja5j^8j[;jX>jVAjSDjPGiMJiJNiGQiDTiAWi=[i:^i7ah4eh1hh-lh*oh&sh#vh zh~gggg g ggfeedcba``_^ ] \ \ [ Z YXWWVUTSSRQPOONN<+"3 CMM$M4}MCnLR`L`QLoCK}5K(KK JJHFDB@ > <97531/-+("&$$&"( *,.13579; > @BDFHKKKKK K KKKKKKKKK K"K$K'K)K+K-K/K2K4K6|K8zK:xK=vK?tKAqKCoKFmKHkKJhKLfKNdKQbKS_KU]KW[KZYK\WK^TK`RKcPKeMKgKKiIKlGKnDKpBKr@Ku>Kw;Ky9K{7K~5K2K0K.K+K)K'K%K"K KKKLLLLLL L LLLLLfx fw fw!fv"fu#ft$fs%fr%fr&fq'fp(fo)fn*fn*fm+fl,fk-fj.fi/fi/fh0fg1ff2fe3fd3fd4fc5fb6fa7f`8f`8f_9f^:f];f\fY?fX@fWAfVAfVBfUCfTDfSEfRFfRFfQGfPHfOIfNJfMKfMKfLLfKMfJNfIOfHOfHPfGQfFRfESfDTfCTfCUfBVfAWf@Xf?Yf?Yf>Zf=[f<\f;]f:]f:^f9_f8`f7af6bf5bf5cf4df3ef2ff1gf1gf0hf/if.jf-kf,lf,lf+mf*nf)of(pf'pf'qf&rf%sf$tf#uf#uf"vf!wf xfyfzfzf{f|f}f~f~fffffffffffffff f f f f f fffffffffffda ] YVROKH#D'A*>-:174471;.>*A'D$G!JMPSVY\ _ begjkkk k kkkkk}lzlxluls!lp#ln&ll(lj*lg,le.lc0ma3m^5m\7mZ9mX;mV=mT?mRAmPCmNEmLGmJHmHJnFLnDNnBPn@Rn>Sn @ BDFHKLLLL L LLLLLLLLLL!L#L&L(L*L,L.L1L3L5|L7zL9xLtL@qLBoLDmLGkLIhLKfLMdLPbLR_LT]LV[LYYL[WL]TL_RLaPLdMLfKLhILjGLmDLoBLq@Ls>Lv;Lx9Lz7L}5L2L0L.L+L)M'M%M"M MMMMMMMMM M MMMMM fx fw!fw"fv#fu$ft%fs%fr&fr'fq(fp)fo*fn*fn+fm,fl-fk.fj/fi/fi0fh1fg2ff3fe3fd4fd5fc6fb7fa8f`8f`9f_:f^;f]fZ?fY@fXAfWAfVBfVCfUDfTEfSFfRFfRGfQHfPIfOJfNKfMKfMLfLMfKNfJOfIOfHPfHQfGRfFSfETfDTfCUfCVfBWfAXf@Yf?Yf?Zf>[f=\f<]f;]f:^f:_f9`f8af7bf6bf5cf5df4ef3ff2gf1gf1hf0if/jf.kf-lf,lf,mf+nf*of)pf(pf'qf'rf&sf%tf$uf#uf#vf"wf!xf yfzfzf{f|f}f~f~ffffffffffffffff f f f f f fffffffffffd` \ YUQNJG#C'@*=-:164370;->*A'D$G!JMPSVY\ _ begjjjj j jjkkk}kzkxkuks"kp$kn&kl(lj+lg-le/lc1la3l^5l\7lZ9lX;lV=lT?lRAmPCmNEmLGmJImHKmFMmDOmBPm@Rm>Tm0=2;49677593;1=/?-A+C)E'G%I#K!MOQSUWY[] ` b dfikkkk j jjjjj~j{jyjv jt#iq&in(il+ii.if1id4ia7i^:i[=hY@hVChSFhPIhMLhJOhGRhDUgAYg>\g:_g7cg4fg1jg-mg*qf'tf#xf {fffeee eeedcba``_^]\ \ [ Z Y X WWVUTSSRQPOONMLP?."3 CPO"O2}OAnNP`N^QNmCN{5M(MM MLJHFDB @ ><97531/-+"($&&$("* ,.13579;> @ BDFHKMMMMM M MMMMMMMMM M"M$M'M)M+M-M/M2M4|M6zM8xM;vM=tM?qMAoMCmMFkMHhMJfMLdMNbMQ_MS]MU[MWYMZWM\TM^RM`PMcMMeKMgIMiGMlDMnBMp@Mr>Mu;Mw9Ny7N{5N~2N0N.N+N)N'N%N"N NNNNNNNNN N NNNNN ex!ew"ew#ev$eu%et%es&er'er(eq)ep*eo*en+en,em-el.ek/ej/ei0ei1eh2eg3ef3ee4ed5ed6ec7eb8ea8e`9e`:e_;e^e[?eZ@eYAeXAeWBeVCeVDeUEeTFeSFeRGeRHeQIePJeOKeNKeMLeMMeLNeKOeJOeIPeHQeHReGSeFTeETeDUeCVeCWeBXeAYe@Ye?Ze?[e>\e=]e<]e;^e:_e:`e9ae8be7be6ce5de5ee4fe3ge2ge1he1ie0je/ke.le-le,me,ne+oe*pe)pe(qe're'se&te%ue$ue#ve#we"xe!ye zeze{e|e}e~e~eeeeeeeeeeeeeeeee e e e e e eeeeeeeeeeec_ [ XTQMJF#C'?*<-916427/;,>)A&D#G JMPSVY\ _ begiiii j jjjjj}jzjxju ks"kp%kn'kl)kj+kg-ke0kc2ka4k^6k\8lZ:lXlT@lRBlPDlNFlLHlJJlHKlFMlDOmBQm@Sm>Um0<2:48667493;1=/?-A+C)E'G%I#K MOQSUWY[] ` bdfijjjj j jjjii~i{iyiv!it$iq&in)il,hi/hf2hd4ha7h^:h[=hY@hVCgSFgPIgMLgJPgGSgDVgAYg>]f:`f7cf4gf1jf-nf*qf'ue#ye |eeeeed dddcba``_^]\\ [ Z Y X W WVUTSSRQPOONMLKQ@/"3CQQ!P0}P@nPN`O]QOkCOz5N(NN NMKIGEC A ?=:86420.,")$'&%(#*!,.13579;>@ B DFHKMNNNN N NNNNNNNNNN!N#N&N(N*N,N.N1N3|N5zN7xN9vNqN@oNBmNEkNGhNIfNKdNMbNP_NR]NT[NVYNYWN[TN]RN_PNbMNdKNfIOhGOkDOmBOo@Oq>Ot;Ov9Ox7Oz5O}2O0O.O+O)O'O%O"O OOOOOOOOO O OOOOO!dx"dw#dw$dv%du%dt&ds'dr(dr)dq*dp*do+dn,dn-dm.dl/dk/dj0di1di2dh3dg3df4de5dd6dd7dc8db8da9d`:d`;d_d[?d[@dZAdYAdXBdWCdVDdVEdUFdTFdSGdRHdRIdQJdPKdOKdNLdMMdMNdLOdKOdJPdIQdHRdHSdGTdFTdEUdDVdCWdCXdBYdAYd@Zd?[d?\d>]d=]d<^d;_d:`d:ad9bd8bd7cd6dd5ed5fd4gd3gd2hd1id1jd0kd/ld.ld-md,nd,od+pd*pd)qd(rd'sd'td&ud%ud$vd#wd#xd"yd!zd zd{d|d}d~d~dddddddddddddddddd d d d d d dddddddddddb^ [ WSPLIE#B'?*;-815427.;+>(A%D"GJMPSVY\ _beghii i iiiiii}jzjxju!js#jp%jn'jl*jj,jg.je0kc2ka4k^6k\9kZ;kX=kV?kTAkRBkPDkNFlLHlJJlHLlFNlDPlBRl@Sl>UlgYAgVDgSGgPJgMMfJPfGTfDWfAZf>]f:af7de4he1ke-oe*re've#ye }dddddd cccba``_^]\\[ Z Y X W W VUTSSRQPOONMLKJRA0"3CRR Q/}Q>nQM`P\QPjCPy5P(OO ONLJHFD B @><97531/-"+$(&&($*", .13579;>@ B DFHKMOOOOO O OOOOOOOOO O"O%O'O)O+O-O0O2|O4zO6xO8vO;tO=qO?oOAmOCkOFhOHfOJdOLbOO_OQ]OS[OUYPWWPZTP\RP^PP`MPcKPeIPgGPiDPlBPn@Pp>Pr;Pu9Pw7Py5P{2P~0P.P+P)P'P%P"P PPPPPPPPP P PPPPP"cx#cw$cw%cv%cu&ct'cs(cr)cr*cq*cp+co,cn-cn.cm/cl/ck0cj1ci2ci3ch3cg4cf5ce6cd7cd8cc8cb9ca:c`;c`c\?c[@c[AcZAcYBcXCcWDcVEcVFcUFcTGcSHcRIcRJcQKcPKcOLcNMcMNcMOcLOcKPcJQcIRcHScHTcGTcFUcEVcDWcCXcCYcBYcAZc@[c?\c?]c>]c=^c<_c;`c:ac:bc9bc8cc7dc6ec5fc5gc4gc3hc2ic1jc1kc0lc/lc.mc-nc,oc,pc+pc*qc)rc(sc'tc'uc&uc%vc$wc#xc#yc"zc!zc {c|c}c~c~ccccccccccccccccccc c c c c c ccccccccccca] Z VSOKHE#A'>*;-714417.;+>'A$D!GJMPSVY \ _beghhh h hhhiii}izixiu!is$ip&in(jl*jj,jg/je1jc3ja5j^7j\9jZ;jX=kV?kTAkRCkPEkNGkLIkJKkHMkFNkDPkBRk@Tl>Vl^e:ae7ee4he1ld-od*sd'vd#zd ~dccccc cbba``_^]\\[Z Y X W W V UTSSRQPOONMLKJJTB1" 3CSSS.}R=nRL`R[QQiCQw5Q(PP PPMKIGE C A?=:86420.",$)&'(%*#,!.13579;>@B D FHKMOPPPP P PPPPPPPPPP!P#P&P(P*P,P.P1|P3zP5xP7vP9tPoP@mPBkPEhPGfQIdQKbQM_QP]QR[QTYQVWQYTQ[RQ]PQ_MQbKQdIQfGQhDQkBQm@Qo>Qq;Qt9Qv7Qx5Qz2Q}0Q.Q+Q)Q'Q%Q"Q QQQQQQQQQ Q QQQQQ#bx$bw%bw%bv&bu'bt(bs)br*br*bq+bp,bo-bn.bn/bm/bl0bk1bj2bi3bi3bh4bg5bf6be7bd8bd8bc9bb:ba;b`b]?b\@b[Ab[AbZBbYCbXDbWEbVFbVFbUGbTHbSIbRJbRKbQKbPLbOMbNNbMObMObLPbKQbJRbISbHTbHTbGUbFVbEWbDXbCYbCYbBZbA[b@\b?]b?]b>^b=_b<`b;ab:bb:bb9cb8db7eb6fb5gb5gb4hb3ib2jb1kb1lb0lb/mb.nb-ob,pb,pb+qb*rb)sb(tb'ub'ub&vb%wb$xb#yb#zb"zb!{b |b}b~b~bbbbbbbbbbbbbbbbbbbb b b b b b bbbbbbbbbbb`] Y URNKGD#@'=*:-613407-;*>'A$D!GJMPSVY \ _begggg g hhhhhh}hzhx hu"is$ip'in)il+ij-ig/ie1ic4ia6j^8j\:jZjV@jTBjRDjPFjNHjLIjJKkHMkFOkDQkBSk@Uk>Vk.<0:2947657391;/=-?+A)C'E%G#I!KMOQSUWY[ ] ` bdfhhhh h hhhhgg~g{gy gv#gt&gq(go+gl.fi1fg4fd6fa9f^_d:bd7fd4id1ld-pc*tc'wc#{c ~ccbbbb bba``_^]\\[ZY X W W V U TSSRQPONNMLKJJIUC2""3CSTT-}S<97531/"-$+&((&*$,". 13579;>@B D FHKMOQQQQQ Q QQQQQQQQQ Q"Q%Q'Q)Q+Q-Q0|Q2zQ4xQ6vQ8tQ;qR=oR?mRAkRChRFfRHdRJbRL_RO]RQ[RSYRUWRXTRZRR\PR^MR`KRcIReGRgDRiBRl@Rn>Rp;Rs9Ru7Rw5Ry2R|0R~.R+R)R'R%R"R RRRRRRRRR R RRRRR$ax%aw%aw&av'au(at)as*ar*ar+aq,ap-ao.an/an/am0al1ak2aj3ai3ai4ah5ag6af7ae8ad8ad9ac:ab;aaa^?a]@a\Aa[Aa[BaZCaYDaXEaWFaVFaVGaUHaTIaSJaRKaRKaQLaPMaONaNOaMOaMPaLQaKRaJSaITaHTaHUaGVaFWaEXaDYaCYaCZaB[aA\a@]a?]a?^a>_a=`a&A#D GJMPSVY \ _beffgg g gggggh}hzhx hu#hs%hp'hn)hl,hj.ig0ie2ic4ia6i^8i\:iZiV@iTBjRDjPFjNHjLJjJLjHNjFPjDQjBSj@Uj>Wk.<0:2846647290;.=,?*A(C&E$G"I KMOQSUWY[ ] `bdfhhhg g gggggg~g{fy!fv#ft&fq)fo,fl.fi1fg4ed7ea:e^=e\@eYCeVFeSIdPLdMOdJRdGVdDYdA\d>`c;cc7fc4jc1mc-qc*tc'xb#|b bbbaaa aa``_^]\\[ZYX W W V U T SSRQPONNMLKJJIHVE4"#3CS UU,}T;nTJ`TYQSgCSu5S(SR RRPMKIG E CA?=:86420".$,&)('*%,#.!13579;>@BD F HKMOQRRRR R RRRRRRRRRR!R#R&R(R*R,S.|S1zS3xS5vS7tS:qSmS@kSBhSEfSGdSIbSK_SN]SP[SRYSTWSVTSYRS[PS]MS_KSbISdGSfDShBSk@Sm>So;Sq9St7Sv5Sx2Sz0S}.S+S)S'S%S"S SSSSSSSSS S SSSSS%ax%aw&aw'av(au)at*as*ar+ar,aq-ap.ao/an/an0am1al2ak3aj3ai4ai5ah6ag7af8ae8ad9ad:ac;aba_?a^@a]Aa\Aa[Ba[CaZDaYEaXFaWFaVGaVHaUIaTJaSKaRKaRLaQMaPNaOOaNOaMPaMQaLRaKSaJTaITaHUaHVaGWaFXaEYaDYaCZaC[aB\aA]a@]a?^a?_a>`a=aa%A"DGJMPSVY \_befff f fffgggg}gzgx!gu#gs&gp(hn*hl,hj.hg1he3hc5ha7h^9h\;iZ=iX?iVAiTCiREiPGiNIiLKiJMiHNiFPjDRjBTj@Vj>Wjd\AdYDdVGdSJdPMdMPcJScGVcDZcA]c>`c;dc7gb4jb1nb.qb*ub'yb#|a aaaaa` ```_^]\\[ZYXW W V U T S SRQPONNMLKJJIHGWF5"$3CS VV+}V:nUI`UWQUfCTt5T(TS SSQOLJH F DB@><97531"/$-&+((*&,$."1 3579;>@BD F HKMOQSSSSS S SSSSSSSSS T"T%T'T)T+T-|T0zT2xT4vT6tT8qT;oT=mT?kTAhTDfTFdTHbTJ_TL]TO[TQYTSWTUTTXRTZPT\MT^KTaITcGTeDTgBTj@Tl>Tn;Tp9Ts7Tu5Tw2Ty0T|.T~+T)T'T%T"T TTTTTTTTT T TTTTU%`x&`w'`w(`v)`u*`t*`s+`r,`r-`q.`p/`o/`n0`n1`m2`l3`k3`j4`i5`i6`h7`g8`f8`e9`d:`d;`c<`b=`a=``>``?`_@`^A`]A`\B`[C`[D`ZE`YF`XF`WG`VH`VI`UJ`TK`SK`RL`RM`QN`PO`OO`NP`MQ`MR`LS`KT`JT`IU`HV`HW`GX`FY`EY`DZ`C[`C\`B]`A]`@^`?_`?``>a`=b`';*7-4114.7+;(>%A!DGJMPSV Y \_beeee e effffff}fzfx"gu$gs&gp(gn+gl-gj/gg1ge3gc5ha7h^9h\hX@hVBhTDhREhPGiNIiLKiJMiHOiFQiDSiBTi@Vi>Xi-<.;09274563719/;-=+?)A'C%E#G!IKMOQSUWY[ ] `bdfgff f ffffffe~e{ey"ev%et'eq*eo-dl0di3dg5dd8da;d^>d\AdYDcVGcSJcPMcMQcJTcGWbDZbA^b>ab;db7hb4ka1oa.ra*va'ya#}a `````` ___^]\\[ZYXWW V U T S S RQPONNMLKJJIHGFXG6"%3CS WW*}W9nVH`VVQVeCUs5U(UT TTRPMKI G ECA?=:8642"0$.&,()*',%.#1!3579;>@BDF H KMOQSTTTT T TTTTUUUUUU!U$U&U(U*U,|U/zU1xU3vU5tU7qU:oUkU@hUBfUEdUGbUI_UK]UN[UPYURWUTTUVRUYPU[MU]KU_IUbGUdDUfBUh@Uk>Um;Uo9Uq7Ut5Uv2Ux0U{.U}+U)U'U%U"U UUUUUUUUV V VVVVV&_x'_w(_w)_v*_u*_t+_s,_r-_r._q/_p/_o0_n1_n2_m3_l3_k4_j5_i6_i7_h8_g8_f9_e:_d;_d<_c=_b=_a>_`?_`@__A_^A_]B_\C_[D_[E_ZF_YF_XG_WH_VI_VJ_UK_TK_SL_RM_RN_QO_PO_OP_NQ_MR_MS_LT_KT_JU_IV_HW_HX_GY_FY_EZ_D[_C\_C]_B]_A^_@__?`_?a_>b_=b_$A!DGJMPSV Y \_bddde e eeeeeef}fz fx"fu%fs'fp)fn+fl-gj0gg2ge4gc6ga8g^:g\gX@hVBhTDhRFhPHhNJhLLhJNhHPhFQhDSiBUi@Wi>Yi-<.:08264463719/;-=+?)A'C%E#G!IKMOQSUWY [ ] `bdffff f eeeeeee~e{ dy#dv%dt(dq+do.dl0di3dg6cd9caba;ea7ha4la1oa.s`*v`'z`#~` `_____ _^^]\\[ZYXWWV U T S S R QPONNMLKJJIHGFFZH7"&3CS YX(}X8nXG`WUQWdCVr5V(VU UUSQOLJ H FDB@><9753"1$/&-(+*(,&.$1"3 579;>@BDF H KMOQSUUUUV V VVVVVVVVV V"V%V'V)V+|V-zV0xV2vV4tV6qV8oV;mV=kV?hVAfVDdVFbVH_VJ]VL[VOYVQWVSTVURVXPVZMV\KV^IVaGVcDVeBVg@Vj>Vl;Vn9Vp7Vs5Vu2Vw0Vy.V|+V~)V'V%V"V VVWWWWWWW W WWWWW'^x(^w)^w*^v*^u+^t,^s-^r.^r/^q/^p0^o1^n2^n3^m3^l4^k5^j6^i7^i8^h8^g9^f:^e;^d<^d=^c=^b>^a?^`@^`A^_A^^B^]C^\D^[E^[F^ZF^YG^XH^WI^VJ^VK^UK^TL^SM^RN^RO^QO^PP^OQ^NR^MS^MT^LT^KU^JV^IW^HX^HY^GY^FZ^E[^D\^C]^C^^B^^A_^@`^?a^?b^>b^=c^#A DGJMPSV Y \_bcddd ddddeeee}ez!ex#eu%es'fp*fn,fl.fj0fg2fe4fc7fa9f^;g\=gZ?gXAgVCgTEgRGgPIgNJgLLhJNhHPhFRhDThBVh@Wh>Yh<[h:]h8^i7`i5bi3ci1ei/gi.hi,ji*li)mi'oi%pj#rj"tj ujwjxjzj{j}j~jjjkk _ ]\ZXWUTRPOMKJ!H"F$D&C'A)?+=-;.:08264462709.;,=*?(A&C$E"G IKMOQSUWY [ ]`bdeeee e eeedddd~d|!dy#dv&dt)cq,co.cl1ci4cg7cd:ca=b^@b\CbYFbVIbSLbPOaMRaJUaGXaD\aA_a>b`;f`7i`4m`1p`.t`*w_'{_#~_ __^^^^ ^]]\\[ZYXWWVU T S S R Q PONNMLKJJIHGFFE[J8"(3CSZY'}Y7nYE`XTQXcCXq5W(WW VVTRPNK I GECA?=:864"2$0&.(,*),'.%1#3!579;>@BDFH K MOQSUWWWW W WWWWWWWWWW!W$W&W(W*|W,zW/xW1vW3tW5qW7oW:mWhW@fWBdWEbWG_WI]WK[WNYWPWWRTWTRWWPWYMW[KW]IW`GWbDWdBWf@Wi>Wk;Wm9Wo7Wr5Wt2Wv0Wx.W{+W})W'X%X"X XXXXXXXXX X XXXXX(]x)]w*]w*]v+]u,]t-]s.]r/]r/]q0]p1]o2]n3]n3]m4]l5]k6]j7]i8]i8]h9]g:]f;]e<]d=]d=]c>]b?]a@]`A]`A]_B]^C]]D]\E][F][F]ZG]YH]XI]WJ]VK]VK]UL]TM]SN]RO]RO]QP]PQ]OR]NS]MT]MT]LU]KV]JW]IX]HY]HY]GZ]F[]E\]D]]C^]C^]B_]A`]@a]?b]?b]>c]=d]"ADGJMPSV Y\_bccc c ccdddddd}dz!ex$eu&es(ep*en-el/ej1eg3fe5fc7fa9f^;f\=fZ?fXAfVCfTEgRGgPIgNKgLMgJOgHQgFSgDTgBVg@Xh>Zh<[h:]h8_h7ah5bh3dh1fh/gh.ii,ki*li)ni'oi%qi#si"ti viwiyizj|j}jjjjjj ^ ][ZXVUSQPNLKI!G"F$D&B'@)>+=-;.907254361709.;,=*?(A&C$E"GIKMOQSUWY [ ]`bdeeed d ddddddc~c|!cy$cw'ct)cq,co/bl2bi5bg7bd:ba=b_@b\CaYFaVIaSLaPPaMSaJV`GY`D\`A``>c`;f`8j_4m_1q_.t_*x_'|^#^ ^^^]]] ]]\\[ZYXWWVUT S S R Q P ONNMLKJJIHGFFED\K:")3CS[[&}Z5nZD`YSQYbCYp5X~(XX WWUSQOL J HFDB@><975"3$1&/(-*+,(.&1$3"5 79;>@BDFH K MOQSUXXXXX X XXXXXXXXX X"X%X'X)|X+zX-xX0vX2tX4qX6oX9mX;kX=hX?fXAdXDbXF_XH]XJ[XMYXOWXQTXSRXUPXXMXZKX\IX^GXaDXcBXe@Xg>Xj;Xl9Xn7Xp5Ys2Yu0Yw.Yy+Y|)Y~'Y%Y"Y YYYYYYYYY Y YYYYY)]x*]w*]w+]v,]u-]t.]s/]r/]r0]q1]p2]o3]n3]n4]m5]l6]k7]j8]i8]i9]h:]g;]f<]e=]d=]d>]c?]b@]aA]`A]`B]_C]^D]]E]\F][F][G]ZH]YI]XJ]WK]VK]VL]UM]TN]SO]RO]RP]QQ]PR]OS]NT]MT]MU]LV]KW]JX]IY]HY]HZ]G[]F\]E]]D^]C^]C_]B`]Aa]@b]?b]?c]>d]=e]#;'8*4-11.4+7(;%>"ADGJMPS V Y\_bbbb b cccccccd} dz"dx$du'ds)dp+dn-el/ej1eg4ee6ec8ea:e^eZ@fXBfVDfTFfRHfPJfNLfLNfJOfHQgFSgDUgBWg@Yg>Zg<\g:^g8`g7ah5ch3eh1fh/hh.jh,kh*mh)nh'ph%rh#si"ui vixiyi{i|i~iiiiij ^ \[YWVTSQONLJI!G"E$C&B'@)>+<-:.8072543617/9-;+=)?'A%C#E!GIKMOQSUWY [ ]`bdddd d d dcccccc~c|"by%bw'bt*bq-bo0bl2bi5ag8ad;aa>a_Aa\DaYGaVJ`SM`PP`MS`JW`GZ`D]_A`_>d_;g_8k_4n^1r^.u^*y^'|^$^ ]]]]\\ \\\[ZYXWWVUTS S R Q P O NNMLKJJIHGFFEDC]L;"*3C S\\%}[4n[C`[RQZ`CZo5Y}(YY XXVTRPN K IGECA?=:86"4$2&0(.*,,).'1%3#5!79;>@BDFHK M OQSUXYYYY Y YYYYYYYYYY!Y$Y&Y(|Y*zY,xY/vY1tY3qY5oY7mY:kYfY@dYCbYE_YG]YI[YKYYNWYPTYRRYTPYWMYYKY[IY]GY`DYbBYd@Zf>Zi;Zk9Zm7Zo5Zr2Zt0Zv.Zx+Z{)Z}'Z%Z"Z ZZZZZZZZZ Z ZZZZZ*\x*\w+\w,\v-\u.\t/\s/\r0\r1\q2\p3\o3\n4\n5\m6\l7\k8\j8\i9\i:\h;\g<\f=\e=\d>\d?\c@\bA\aA\`B\`C\_D\^E\]F\\F\[G\[H\ZI\YJ\XK\WK\VL\VM\UN\TO\SO\RP\RQ\QR\PS\OT\NT\MU\MV\LW\KX\JY\IY\HZ\H[\G\\F]\E^\D^\C_\C`\Ba\Ab\@b\?c\?d\>e\=f\!ADGJMPS V Y\_aaab b bbbbcccc} cz#cx%cu'cs)dp,dn.dl0dj2dg4de6dc8ea:e^=e\?eZAeXCeVEeTFeRHePJfNLfLNfJPfHRfFTfDUfBWf@Yf>[g<]g:^g8`g7bg5cg3eg1gg/hg.jg,lh*mh)oh'qh%rh#th"uh whxhzh{h}i~iiiiii ] \ZYWUTRPOMKJH!F"E$C&A'?)=+<-:.8062442607.9,;+=)?'A%C"E GIKMOQSUW Y [ ]`bddcc c cccccbbb~ b|#by%bw(bt+aq-ao0al3aj6ag9ad<`a?`_B`\E`YH`VK`SN_PQ_MT_JW_G[_D^_Aa^>d^;h^8k^4o^1r^.v]*y]'}]$] ]\\\\[ [[[ZYXWWVUTSS R Q P O N N MLKJJIHGFFEDCB_M<"+3C S]]$}\3n\B`\QQ[_C[n5Z|(ZZ YYWUSQO L JHFDB@><97"5$3&1(/*-,+.(1&3$5"7 9;>@BDFHK M OQSUXZZZZZ Z ZZZZZZZZZ Z#Z%Z'|Z)zZ+xZ.vZ0tZ2qZ4oZ6mZ9kZ;hZ=fZ?dZAbZD_ZF]ZH[ZJYZMWZOTZQRZSPZVMZXK[ZI[\G[^D[aB[c@[e>[g;[j9[l7[n5[q2[s0[u.[w+[z)[|'[~%["[ [[[[[[[[[ [ [[[[[*[x+[w,[w-[v.[u/[t/[s0[r1[r2[q3[p3[o4[n5[n6[m7[l8[k8[j9[i:[i;[h<[g=[f=[e>[d?[d@[cA[bA[aB[`C[`D[_E[^F[]F[\G[[H[[I[ZJ[YK[XK[WL[VM[VN[UO[TO[SP[RQ[RR[QS[PT[OT[NU[MV[MW[LX[KY[JY[IZ[H[[H\[G][F^[E^[D_[C`[Ca[Bb[Ab[@c[?d[?e[>f[=g[ ADGJMPS V Y\_`aa a aaabbbbbb}!bz#cx&cu(cs*cp,cn.cl1cj3dg5de7dc9da;d^=d\?dZAdXCeVEeTGeRIePKeNMeLOeJQeHReFTfDVfBXf@Zf>[f<]f:_f8af7bf5dg3fg1gg/ig.kg,lg*ng)og'qg%sg#tg"vh whyhzh|h}hhhhhhi ] [ZXVUSRPNMKIH!F"D$B&@'?)=+;-9.7062442507.9,;*=(?&A$C"E GIKMOQSUW Y []`bcccc c bbbbbbba~!a|#ay&aw)at+aq.ao1`l4`j7`g9`d<`a?`_B_\E_YH_VK_SN_PR_MU^JX^G[^D^^Ab^>e^;i]8l]4o]1s].w]*z\'~\$\ \\[[[[ ZZZYXWWVUTSSR Q P O N N M LKJJIHGFFEDCBA`N=",3C S^^#}^2n]A`]PQ\^C\m5\{([[ ZZXVTRP N KIGECA?=:8"6$4&2(0*.,,.)1'3%5#7!9;>@BDFHKM O QSUXZ[[[[ [ [[[[[[[[[[![$[&|[(z[*x[,v[/t[1q[3o[5m[7k[:h[d[@b[C_[E][G[[IY[KW\NT\PR\RP\TM\WK\YI\[G\]D\`B\b@\d>\f;\i9\k7\m5\o2\r0\t.\v+\x)\{'\}%\"\ \\\\\\\\\ \ \\\\\+Zx,Zw-Zw.Zv/Zu/Zt0Zs1Zr2Zr3Zq3Zp4Zo5Zn6Zn7Zm8Zl8Zk9Zj:Zi;ZiZe?Zd@ZdAZcAZbBZaCZ`DZ`EZ_FZ^FZ]GZ\HZ[IZ[JZZKZYKZXLZWMZVNZVOZUOZTPZSQZRRZRSZQTZPTZOUZNVZMWZMXZLYZKYZJZZI[ZH\ZH]ZG^ZF^ZE_ZD`ZCaZCbZBbZAcZ@dZ?eZ?fZ>gZ=gZADGJMPS VY\_``` ` `aaaaaaab}"bz$bx&bu(bs+bp-bn/cl1cj3cg5ce8cc:cad\@dZBdXDdVFdTHdRJdPLdNMeLOeJQeHSeFUeDWeBXe@Ze>\e<^f:_f8af7cf5ef3ff1hf/jf.kf,mf*ng)pg'rg%sg#ug"vg xgyg{g|g~hhhhhhh \ [YXVTSQONLJIG!E"D$B&@'>)<+;-9.70523415/7-9+;)='?%A#C!EGHJMOQSUW Y []`bbbbb b bbbaaaaa~!a|$`y'`w)`t,`q/`o2`l4`j7_g:_d=_a@__C_\F_YI^VL^SO^PR^MU^JY^G\]D_]Ac]>f];i]8m\4p\1t\.w\*{\'~[$[ [[[ZZZ ZYYXWWVUTSSRQ P O N N M L KJJIHGFFEDCBAAaP>".3C S`_"}_1n^@`^OQ]]C]k5]y(\\ \[YWUSQ O LJHFDB@><9"7$5&3(1*/,-.+1(3&5$7"9 ;>@BDFHKM O QSUXZ\\\\\ \ \\\\\\\\\ \#\%|\'z\)x\+v\.t\0q\2o\4m\6k\9h\;f\=d\?b\A_]D]]F[]HY]JW]MT]OR]QP]SM]VK]XI]ZG]\D]_B]a@]c>]e;]h9]j7]l5]n2]q0]s.]u+]w)]z']|%]~"] ]]]]]]]]] ] ]]]]],Yx-Yw.Yw/Yv/Yu0Yt1Ys2Yr3Yr3Yq4Yp5Yo6Yn7Yn8Ym8Yl9Yk:Yj;YiYf?Ye@YdAYdAYcBYbCYaDY`EY`FY_FY^GY]HY\IY[JY[KYZKYYLYXMYWNYVOYVOYUPYTQYSRYRSYRTYQTYPUYOVYNWYMXYMYYLYYKZYJ[YI\YH]YH^YG^YF_YE`YDaYCbYCbYBcYAdY@eY?fY?gY>gY=hYADGJMP S VY\____ ` `````aaa a}"az%ax'au)bs+bp-bn0bl2bj4bg6be8cc:cac\@cZBcXDcVFcTHdRJdPLdNNdLPdJRdHTdFUdDWeBYe@[e>]e<^e:`e8be7ce5ee3gf1hf/jf.lf,mf*of)qf'rf%tf#uf"wg xgzg{g}g~ggggggh \ ZYWUTRQOMLJHF!E"C$A&?'>)<+:-8.60423415/7-9+;)='?%A#C!EGHJLOQSUW Y []_bbbb a a aaaaa```~"`|$`y'`w*`t-_r/_o2_l5_j8_g;_d>^aA^_D^\G^YJ^VM^SP]PS]MV]JY]G]]D`\Ac\>g\;j\8m\4q[1t[.x[+|['[$Z ZZZZYY YYXWWVUTSSRQP O N N M L K JJIHGFFEDCBAA@bQ@"/3CSa` }`0n_?`_NQ_\C^j5^x(]] ]\ZXVTR P NKIGECA?=:"8$6&4(2*0,..,1)3'5%7#9!;>@BDFHKM O Q SUXZ\]]]] ] ]]]]]]]]]]!]$|]&z](x]*v],t]/q]1o]3m]5k^8h^:f^b^@_^C]^E[^GY^IW^LT^NR^PP^RM^TK^WI^YG^[D^]B^`@^b>^d;^f9^i7^k5^m2^o0^r.^t+^v)^y'^{%^}"^ ^^^^^^^^^ ^ ^^^^^-Xx.Xw/Xw/Xv0Xu1Xt2Xs3Xr3Xr4Xq5Xp6Xo7Xn8Xn8Xm9Xl:Xk;XjXg?Xf@XeAXdAXdBXcCXbDXaEX`FX`FX_GX^HX]IX\JX[KX[KXZLXYMXXNXWOXVOXVPXUQXTRXSSXRTXRTXQUXPVXOWXNXXMYXMYXLZXK[XJ\XI]XH^XH^XG_XF`XEaXDbXCbXCcXBdXAeX@fX?gX?gX>hX=iX:#7'4*1--1*4'7$;!>ADGJMP S VY\^^__ _ ___`````!`}#`z%ax'au*as,ap.an0al2bj5bg7be9bc;ba=b^?b\AbZCcXEcVGcTIcRKcPMcNOcLPcJRdHTdFVdDXdBZd@[d>]d<_d:ae8be7de5fe3ge1ie/ke.le,ne*oe)qf'sf%tf#vf"wf yfzf|f}ffgggggg [ ZXWUSRPNMKIHF!D"B$A&?'=);+9-8.60422405.7,9*;(=&?$A"C EFHJLOQSU W Y[]_aaaa a aa`````` _~"_|%_y(_w+_t-_r0_o3^l6^j9^g;^d>^aA^_D]\G]YJ]VM]SQ]PT\MW\JZ\G]\Da\Ad[>g[;k[8n[4r[1uZ.yZ+|Z'Z$Z YYYYXX XXWWVUTSSRQPO N N M L K J JIHGFFEDCBAA@?cRA"03CSba}a/na>``LQ`[C_i5_w(^^ ^][YWUS Q OLJHFDB@><"9$7&5(3*1,/.-1*3(5&7$9"; >@BDFHKMO Q SUXZ\^^^^^ ^ ^^^^^^^^^ ^#|^%z^'x^)v^+t_.q_0o_2m_4k_6h_9f_;d_=b_?__B]_D[_FY_HW_JT_MR_OP_QM_SK_VI_XG_ZD_\B__@_a>_c;_e9_h7_j5_l2_n0_q._s+_u)_w'_z%_|"_~ _________ _ _````.Xx/Xw/Xw0Xv1Xu2Xt3Xs3Xr4Xr5Xq6Xp7Xo8Xn8Xn9Xm:Xl;XkXh?Xg@XfAXeAXdBXdCXcDXbEXaFX`FX`GX_HX^IX]JX\KX[KX[LXZMXYNXXOXWOXVPXVQXURXTSXSTXRTXRUXQVXPWXOXXNYXMYXMZXL[XK\XJ]XI^XH^XH_XG`XFaXEbXDbXCcXCdXBeXAfX@gX?gX?hX>iX=jXADGJMP S VY\^^^ ^ ^^______`!`}$`z&`x(`u*`s-`p/an1al3aj5ag7ae9ac;aa>b^@b\BbZDbXFbVHbTIbRKcPMcNOcLQcJScHUcFWcDXcBZc@\d>^d<_d:ad8cd7ed5fd3hd1je/ke.me,ne*pe)re'se%ue#ve"xe yf{f|f~fffffffg [ YXVTSQPNLKIGE!D"B$@&>'=);+9-7.50321405.7,9*;(=&?$A"C EFHJLOQSU W Y[]_aa`` ` ````____ _~#_|&_y(^w+^t.^r1^o3^l6^j9]g<]d?]bB]_E]\H\YK\VN\SQ\PT\MX\J[[G^[Da[Ae[>h[;kZ8oZ5rZ1vZ.yY+}Y'Y$Y YXXXXW WWWVUTSSRQPON N M L K J J IHGFFEDCBAA@?>eSB"13 CSbc}b-nb=`aKQaZC`h5`v(`_ _^\ZXVT R PNKIGECA?=":$8&6(4*2,0..1,3)5'7%9#;!>@BDFHKMO Q S UXZ\^____ _ __________!|`$z`&x`(v`*t`-q`/o`1m`3k`5h`8f`:d`_`@]`C[`EY`GW`IT`LR`NP`PM`RK`UI`WG`YD`[B`^@``>`b;`d9`g7`i5`k2`m0`p.`r+`t)`v'`y%`{"`} ``````aaa a aaaaa/Wx/Ww0Ww1Wv2Wu3Wt3Ws4Wr5Wr6Wq7Wp8Wo8Wn9Wn:Wm;WlWi?Wh@WgAWfAWeBWdCWdDWcEWbFWaFW`GW`HW_IW^JW]KW\KW[LW[MWZNWYOWXOWWPWVQWVRWUSWTTWSTWRUWRVWQWWPXWOYWNYWMZWM[WL\WK]WJ^WI^WH_WH`WGaWFbWEbWDcWCdWCeWBfWAgW@gW?hW?iW>jW=kWADGJMP SVY\]]] ] ^^^^^^__ _"_}$_z&_x)`u+`s-`p/`n2`l4`j6`g8ae:aca^@a\BaZDaXFbVHbTJbRLbPNbNPbLRbJSbHUcFWcDYcB[c@\c>^c<`c:bc8cd7ed5gd3hd1jd/ld.md,od*qd)re'te%ue#we"xe ze{e}e~eeffffff Z YWVTRQOMLJHGE!C"A$@&>'<):+8-7.503214/5-7+9);'=%?#A!CEFHJLNQSU W Y[]_```` ` ______^^!^~$^|&^y)^w,^t/]r1]o4]l7]j:]g=\d@\bC\_F\\I\YL\VO[SR[PU[MX[J[[G_ZDbZAeZ>iZ;lZ8pY5sY1wY.zY+~X'X$X XXWWWW VVVUTSSRQPONN M L K J J I HGFFEDCBAA@?>=fTC"23"CSbd}c,nc;`bJQbYCag5au(a` `_][YWU S QOMJHFDB@>"<$9&7(5*3,1./1-3*5(7&9$;"> @BDFHKMOQ S UXZ\^````` ` `````aaaa |a#za%xa'va)ta+qa.oa0ma2ka4ha6fa9da;ba=_a?]aB[aDYaFWaHTaJRaMPaOMaQKaSIaVGaXDaZBa\@a_>aa;ac9ae7ah5aj2al0an.aq+as)au'ax%az"a| a~abbbbbbb b bbbbb/Vx0Vw1Vw2Vv3Vu3Vt4Vs5Vr6Vr7Vq8Vp8Vo9Vn:Vn;VmVi?Vi@VhAVgAVfBVeCVdDVdEVcFVbFVaGV`HV`IV_JV^KV]KV\LV[MV[NVZOVYPVXPVWQVVRVVSVUTVTTVSUVRVVRWVQXVPYVOYVNZVM[VM\VL]VK^VJ^VI_VH`VHaVGbVFbVEcVDdVCeVCfVBgVAgV@hV?iV?jV>kV=lVADGJM P SVY\\\] ] ]]]]^^^^ ^#^}%_z'_x)_u,_s._p0_n2_l4`j6`g9`e;`c=`a?`^A`\CaZEaXGaVIaTKaRMaPNaNPbLRbJTbHVbFXbDZbB[b@]b>_ciY;mY8pY5tX1wX.{X+X'W$W WWWVVV VUUTSSRQPONNM L K J J I H GFFEDCBAA@?>==gVD"33#CSb e}d+nd:`cIQcXCcf5bt(ba a`^\ZXV T RPNKIGECA?"=$:&8(6*4,2.01.3,5)7'9%;#>!@BDFHKMOQ S U XZ\^`aaaa a abbbbbbbb|b"zb$xb&vb(tb*qb-ob/mb1kb3hb5fb8db:bb<_b>]b@[bCYbEWbGTbIRbLPbNMbPKbRIbUGbWDbYBb[@b^>b`;bb9bd7bg5bi2bk0bm.bp+br)bt'cv%cy"c{ c}cccccccc c ccccc0Ux1Uw2Uw3Uv3Uu4Ut5Us6Ur7Ur8Uq8Up9Uo:Un;UnUj?Ui@UiAUhAUgBUfCUeDUdEUdFUcFUbGUaHU`IU`JU_KU^KU]LU\MU[NU[OUZPUYPUXQUWRUVSUVTUUTUTUUSVURWURXUQYUPYUOZUN[UM\UM]UL^UK^UJ_UI`UHaUHbUGbUFcUEdUDeUCfUCgUBgUAhU@iU?jU?kU>lU=lU;7#4'1*--*1'4$7!;>ADGJM P SVY[[\\ \ \\]]]]]]!^#^}&^z(^x*^u,^s._p1_n3_l5_j7_g9_e;_c=`a?`^A`\C`ZE`XG`VI`TKaRMaPOaNQaLSaJUaHVaFXbDZbB\b@^b>_b==$<&9(7*5,3.11/3-5*7(9&;$>"@ BDFHKMOQS U XZ\^`bbbcc c cccccccc|c zc#xc%vc'tc)qc+oc.mc0kc2hc4fc7dc9bc;_c=]c?[cBYcDWcFTcHRcKPcMMcOKcQIcSGcVDcXBcZ@c\>c_;ca9cc7ce5ch2cj0dl.do+dq)ds'du%dx"dz d|d~ddddddd d ddddd1Tx2Tw3Tw3Tv4Tu5Tt6Ts7Tr8Tr8Tq9Tp:To;TnTk?Tj@TiATiAThBTgCTfDTeETdFTdFTcGTbHTaIT`JT`KT_KT^LT]MT\NT[OT[PTZPTYQTXRTWSTVTTVTTUUTTVTSWTRXTRYTQYTPZTO[TN\TM]TM^TL^TK_TJ`TIaTHbTHbTGcTFdTEeTDfTCgTCgTBhTAiT@jT?kT?lT>lT=mTADGJM P SVY[[[ [ [[\\\\\]]"]$]}&]z(]x+^u-^s/^p1^n3^l6^j8_g:_e<_c>_a@_^B_\D_ZF`XH`VJ`TL`RN`PP`NR`LSaJUaHWaFYaD[aB\a@^a>`a&<':)9+7-5.3012/4-5+7)9(;&=$?"ACDFHJLNQS U WY[]^^^^ ^ ^^]]]]]] \#\~&\|(\y+\w.\t0[r3[o6[l9[j<[g?ZdBZbEZ_HZ\KZYNYVQYSTYQWYNZYK^XHaXEdXAgX>kX;nW8rW5uW1yW.|V+V'V$V UUUUTT TTSSRQPONNMLK J J I H G F FEDCBAA@?>==<;jXG"63%CSb g}g)nf8`fGQeUCed5dr(dc cca^\ZX V TRPNKIGECA"?$=&:(8*6,4.2103.5,7)9';%>#@!BDFHKMOQS U X Z\^`cdddd d dddddddd|dzd"xd$vd&td(qd*od-md/kd1hd3fd5dd8bd:_d<]d>[dAYdCWdETdGRdIPdLMdNKdPIdRGdUDdWBdY@d[>d^;e`9eb7ed5eg2ei0ek.em+ep)er'et%ev"ey e{e}eeeeeee e eeeee2Sx3Sw3Sw4Sv5Su6St7Ss8Sr8Sr9Sq:Sp;SoSl?Sk@SjASiASiBShCSgDSfESeFSdFSdGScHSbISaJS`KS`KS_LS^MS]NS\OS[PS[PSZQSYRSXSSWTSVTSVUSUVSTWSSXSRYSRYSQZSP[SO\SN]SM^SM^SL_SK`SJaSIbSHbSHcSGdSFeSEfSDgSCgSChSBiSAjS@kS?lS?lS>mS=nSADGJM PSVYZZZ Z [[[[[\\\ \"\%\}']z)]x+]u.]s0]p2]n4^l6^j8^g:^e=^c?^aA_^C_\E_ZG_XI_VK_TL_RN`PP`NR`LT`JV`HX`FY`D[`B]a@_a>aa&<':)8+6-4.3012/4-5+7)9';%=#?!ACDFHJLNPS U WY[]^^^] ] ]]]]\\\\!\$\~&[|)[y,[w.[t1[r4Zo7Zl:ZjlW;oW8rV5vV1yV.}V+U'U$U UTTTTS SSSRQPONNMLKJ J I H G F F EDCBAA@?>==<;:kYH"73&CSb h}h(ng7`gFQfTCfc5eq(ed ddb_][Y W USQOMJHFDB"@$>&<(9*7,5.3113/5-7*9(;&>$@"B DFHKMOQSU X Z\^`ceeeee e eeeeeee|eze xe#ve%te'qe)oe+me.ke0he2fe4de7be9_e;]e=[e?YeBWeDTeFReHPeKMeMKeOIeQGeTDfVBfX@fZ>f];f_9fa7fc5ff2fh0fj.fl+fo)fq'fs%fu"fx fzf|f~ffffff f fffff3Sx3Sw4Sw5Sv6Su7St8Ss8Sr9Sr:Sq;SpSm?Sl@SkASjASiBSiCShDSgESfFSeFSdGSdHScISbJSaKS`KS`LS_MS^NS]OS\PS[PS[QSZRSYSSXTSWTSVUSVVSUWSTXSSYSRYSRZSQ[SP\SO]SN^SM^SM_SL`SKaSJbSIbSHcSHdSGeSFfSEgSDgSChSCiSBjSAkS@lS?lS?mS>nS=oSADGJ M PSVYYYZ Z ZZZ[[[[[![#\%\}'\z*\x,\u.\s0]p3]n5]l7]j9]g;]e=^c?^aA^^C^\E^ZG^XI_VK_TM_RO_PQ_NS_LU_JV`HX`FZ`D\`B^`@_`>a`lV;pV8sV5wU1zU.~U+U'T$T!TTSSSS RRRQPONNMLKJJ I H G F F E DCBAA@?>==<;:9lZI"83(CSbi}i'nh6`hEQgSCgb5fp(f~f eeca^\Z X VTRPNKIGEC"A$?&=(:*8,6.412305.7,9);'>%@#B!DFHKMOQSU X Z \^`ceffff f fffffff|fzfxf"vf$tf&qf(of*mf-kf/hf1ff3df5bf8_f:]f<[f>YfAWfCTfERfGPfJMgLKgNIgPGgRDgUBgW@gY>g[;g^9g`7gb5gd2gg0gi.gk+gm)gp'gr%gt"gw gyg{g}gggggg g ggggg3Rx4Rw5Rw6Rv7Ru8Rt8Rs9Rr:Rr;RqRn?Rm@RlARkARjBRiCRiDRhERgFRfFReGRdHRdIRcJRbKRaKR`LR`MR_NR^OR]PR\PR[QR[RRZSRYTRXTRWURVVRVWRUXRTYRSYRRZRR[RQ\RP]RO^RN^RM_RM`RLaRKbRJbRIcRHdRHeRGfRFgREgRDhRCiRCjRBkRAlR@lR?mR?nR>oR=pR;74#1'.**-'1$4!7;>ADGJ M PSVXXYY YYYZZZZZ[![$[&[}([z*[x-\u/\s1\p3\n5\l7\j:]g<]e>]c@]aB]^D]\F^ZH^XJ^VL^TN^RP^PQ^NS_LU_JW_HY_F[_D\_B^_@``>b`$=&;'9)7+5,3.1002.4,5*7(9&;$="? ABDFHJLNP S UWY[]]\\ \ \\\[[[[[ ["Z%Z~'Z|*Zy-Zw0Zt2Yr5Yo8Ym;Yj>YgAXdDXbGX_JX\MXYPWVSWTVWQYWN\VK`VHcVEfVBjV>mU;pU8tU5wU2{T.T+T'T$S!SSSRRR RQQPONNMLKJJIH G F F E D CBAA@?>==<;:98m\J"93)CSbk}j&nj5`iDQiRCh`5ho(g}g ffdb_][ Y WUSQOMJHFD"B$@&>(<*9,7.513315/7-9*;(>&@$B"D FHKMOQSUX Z \^`ceggggg g gggggg|gzgxg!vg#tg%qg'og)mg,kg.hg0fg2dg4bg7_g9]g;[g=Yg?WgBThDRhFPhHMhKKhMIhOGhQDhTBhV@hX>hZ;h]9h_7ha5hc2hf0hh.hj+hl)ho'hq%hs"hu hxhzh|hhhhhh h hhhhh4Qx5Qw6Qw7Qv8Qu8Qt9Qs:Qr;QrQn?Qn@QmAQlAQkBQjCQiDQiEQhFQgFQfGQeHQdIQdJQcKQbKQaLQ`MQ`NQ_OQ^PQ]PQ\QQ[RQ[SQZTQYTQXUQWVQVWQVXQUYQTYQSZQR[QR\QQ]QP^QO^QN_QM`QMaQLbQKbQJcQIdQHeQHfQGgQFgQEhQDiQCjQCkQBlQAlQ@mQ?nQ?oQ>pQ=pQADGJ M PSVXXX X XYYYYYZZZ"Z$Z&Z})[z+[x-[u/[s2[p4\n6\l8\j:\g<\e>\c@]aB]^D]\F]ZH]XJ]VL]TN^RP^PR^NT^LV^JX^HY^F[_D]_B__@`_>b_$<&:'8)7+5,3.10/2-4+5)7'9%;#=!?ABDFHJLNP S UWY[\\\\ \ [[[[[ZZZ Z#Z%Z~(Y|+Yy.Yw0Yt3Yr6Xo9XmXgAXeDWbGW_JW\MWYPWWSVTWVQZVN]VK`VHdUEgUBjU>nU;qT8uT5xT2|T.S+S(S$S!RRRRQQ QPPONNMLKJJIHG F F E D C BAA@?>==<;:988n]L";3*CS bl}k$nk4`jBQjQCi_5in(h{h ggeca^\ Z XVTRPNKIGE"C$A&?(=*:,8.61432507.9,;)>'@%B#D!FHKMOQSUX Z \ ^`ceghhhh h hhhhhh|hzhxhvh"th$qh&oh(mh*kh-hh/fh1dh3bh6_h8]i:[iWiATiCRiEPiGMiJKiLIiNGiPDiSBiU@iW>iY;i[9i^7i`5ib2ie0ig.ii+ik)in'ip%ir"it iwiyi{i}iiiii i iiijj5Px6Pw7Pw8Pv8Pu9Pt:Ps;PrPo?Pn@PnAPmAPlBPkCPjDPiEPiFPhFPgGPfHPeIPdJPdKPcKPbLPaMP`NP`OP_PP^PP]QP\RP[SP[TPZTPYUPXVPWWPVXPVYPUYPTZPS[PR\PR]PQ^PP^PO_PN`PMaPMbPLbPKcPJdPIePHfPHgPGgPFhPEiPDjPCkPClPBlPAmP@nP?oP?pP>pP=qPADGJ MPSVWWW W XXXXXYYY Y#Y%Z'Z})Zz,Zx.Zu0[s2[p4[n7[l9[j;[g=\e?\cA\aC\^E\\G\ZI]XK]VM]TO]RQ]PS]NT]LV^JX^HZ^F\^D^^B_^@a^>c_nT;rT8uS5yS2|S.S+R(R$R!RQQQPP PPONNMLKJJIHGF F E D C B AA@?>==<;:9887p^M"<3+CS bm}l#nl2`kAQkPCj^5jl(izi hhfdb`] [ YWUSQOMJHF"D$B&@(>*<,9.71533517/9-;*>(@&B$D"F HKMOQSUXZ \ ^`cegiiiii i iiiii|izixivi!ti#qi%oi'mi)ki,hi.fj0dj2bj4_j7]j9[j;Yj=Wj@TjBRjDPjFMjHKjKIjMGjODjQBjT@jV>jX;jZ9j]7j_5ja2jc0jf.jh+jj)jl'jo%jq"js jvjxjzj|jjjjj k kkkkk6Ox7Ow8Ow8Ov9Ou:Ot;OsOp?Oo@OnAOnAOmBOlCOkDOjEOiFOiFOhGOgHOfIOeJOdKOdKOcLObMOaNO`OO`PO_PO^QO]RO\SO[TO[TOZUOYVOXWOWXOVYOVYOUZOT[OS\OR]OR^OQ^OP_OO`ONaOMbOMbOLcOKdOJeOIfOHgOHgOGhOFiOEjODkOClOClOBmOAnO@oO?pO?pO>qO=rOADG J MPSVVVW W WWWXXXXX!Y#Y%Y(Y}*Yz,Zx/Zu1Zs3Zp5Zn7Zl9[j;[g>[e@[cB[aD[^F\\H\ZJ\XL\VN\TO\RQ]PS]NU]LW]JY]H[]F\]D^^B`^@b^>c^"=$;&9'7)5+4,2.00.2,4*5(7&9$;"= ?ABDFHJLN P S UWY[[[[ Z Z ZZZZYYYY!Y$X'X)X|,Xz/Xw2Xt4Wr7Wo:Wm=Wj@VgCVeFVbIV_LV\OUYRUWUUTXUQ[UN^TKbTHeTEhTBlS?oS;sS8vS5zR2}R.R+R(Q$Q!QPPPPO OONNMLKJJIHGFF E D C B A A@?>==<;:98876q_N"=3,CS bn}m"nm1`l@QlOCk]5kk(jyj iigeca^ \ ZXVTRPNKIG"E$C&A(?*=,;.8163452709.;,>)@'B%D#F!HKMOQSUXZ \ ^ `cegijjjj j jjjjj|jzjxjvjtj"qj$oj&mk(kk*hk-fk/dk1bk3_k6]k8[k:YkTkARkCPkEMkGKkJIkLGkNDkPBkS@kU>kW;kY9k\7k^5k`2kb0ke.kg+ki)kk'kn%kp"kr ktkwkyk{k~llll l lllll7Nx8Nw8Nw9Nv:Nu;NtNq?Np@NoANnANnBNmCNlDNkENjFNiFNiGNhHNgINfJNeKNdKNdLNcMNbNNaON`PN`PN_QN^RN]SN\TN[TN[UNZVNYWNXXNWYNVYNVZNU[NT\NS]NR^NR^NQ_NP`NOaNNbNMbNMcNLdNKeNJfNIgNHgNHhNGiNFjNEkNDlNClNCmNBnNAoN@pN?pN?qN>rN=sN;841#.'**'-$1!47;>ADG J MPSUUV V VVVWWWWXX!X$X&X(Y}+Yz-Yx/Yu1Ys4Yp6Zn8Zl:ZjZe@[cB[aD[^F[\H[ZJ[XL\VN\TP\RR\PT\NV\LW\JY]H[]F]]D_]B`]@b]>d]"<$:&9'7)5+3,1./0-2,4*5(7&9$;"= ?ABDFHJLN P RUWYZZZZ Z ZYYYYYYXX"X%X'X*W|-Wz/Ww2Wt5Wr8Vo;Vm=Vj@VgCVeFUbIU_LU\OUYRTWVTTYTQ\TN_TKbSHfSEiSBlS?pR;sR8wR5zR2~Q.Q+Q(Q$P!PPOOOO NNNMLKJJIHGFFE D C B A A @?>==<;:988765r`O">3-CS bo}o!nn0`n?QmNCl\5lj(kxk jjhfdb` ] [YWUSQOMJH"F$D&B(@*>,<.9173553719/;->*@(B&D$F"H KMOQSUXZ\ ^ `cegikkkkk k kkkk|kzkxkvktl!ql#ol%ml'kl)hl,fl.dl0bl2_l4]l7[l9Yl;Wl=Tl@RlBPlDMlFKlIIlKGlMDlOBlQ@lT>lV;lX9lZ7l]5l_2la0lc.lf+lh)lj'lm%lo"lq lsmvmxmzm|mmmm m mmmmm8Nx8Nw9Nw:Nv;NuNr?Nq@NpANoBNnBNnCNmDNlENkFNjFNiGNiHNhINgJNfKNeKNdLNdMNcNNbONaPN`PN`QN_RN^SN]TN\TN[UN[VNZWNYXNXYNWYNVZNV[NU\NT]NS^NR^NR_NQ`NPaNObNNbNMcNMdNLeNKfNJgNIgNHhNHiNGjNFkNElNDlNCmNCnNBoNApN@pN?qN?rN>sN=tN:730#-'**'-#1 47;>ADG J MPSTUU U UVVVVVWW W"W$W'X)X}+Xz.Xx0Xu2Ys4Yp6Yn9Yl;Yj=Zg?ZeAZcCZaEZ^GZ\I[ZK[XM[VO[TQ[RR[PT\NV\LX\JZ\H\\F]\D_\Ba]@c]>d]QnMCn[5mi(mwl lkigeca ^ \ZXVTRPNKI"G$E&C(A*?,=.;1836547290;.>,@)B'D%F#H!KMOQSUXZ\ ^ ` cegikllll l llll|mzmxmvmtmqm"om$mm&km(hm+fm-dm/bm1_m3]m6[m8Ym:WmRmAPmCMmEKmGImJGmLDmNBmP@mS>mU;mW9mY7m\5m^2m`0mb.me+mg)mi'nk%nn"np nrntnwnyn{n~nnn n nnnnn8Mx9Mw:Mw;MvMr?Mr@MqAMpBMoBMnCMnDMmEMlFMkFMjGMiHMiIMhJMgKMfKMeLMdMMdNMcOMbPMaPM`QM`RM_SM^TM]TM\UM[VM[WMZXMYYMXYMWZMV[MV\MU]MT^MS^MR_MR`MQaMPbMObMNcMMdMMeMLfMKgMJgMIhMHiMHjMGkMFlMElMDmMCnMCoMBpMApM@qM?rM?sM>tM=uMADG JMPSTTT T UUUUVVVV V#W%W'W*W},Wz.Xx0Xu3Xs5Xp7Xn9Yl;Yj=Yg?YeAYcCYaFZ^HZ\IZZKZXMZVOZTQ[RS[PU[NW[LY[JZ[H\\F^\D`\Bb\@c\>e\.<1937557391;/>-@*B(D&F$H"K MOQSUXZ\^ ` cegikmmmmm m nnn|nznxnvntnqn!on#mn%kn'hn)fn,dn.bn0_n2]n5[n7Yn9Wn;Tn=Rn@PnBMnDKnFInIGnKDnMBnO@nR>nT;nV9nX7n[5n]2n_0na.od+of)oh'oj%om"oo oqosovoxozo|ooo o ooooo9Lx:Lw;LwLs?Lr@LrALqBLpBLoCLnDLnELmFLlFLkGLjHLiILiJLhKLgKLfLLeMLdNLdOLcPLbPLaQL`RL`SL_TL^TL]UL\VL[WL[XLZYLYYLXZLW[LV\LV]LU^LT^LS_LR`LRaLQbLPbLOcLNdLMeLMfLLgLKgLJhLIiLHjLHkLGlLFlLEmLDnLCoLCpLBpLAqL@rL?sL?tL>uL=uLAD G JMPSSST T TTTUUUUV!V#V&V(V*W}-Wz/Wx1Wu3Ws5Xp8Xn:XlXg@XeBYcDYaFY^HY\JYZLZXNZVPZTRZRTZPVZNW[LY[J[[H][F_[D`[Bb[@d\>f\!<";$9&7'5)3+1,0..0,2*3(5&7$9"; =?@BDFHJL N P RUWYYYX X X XXWWWWWV!V$V'V)V,U|/Uz1Uw4Uu7Ur:To=Tm?TjBTgETeHSbKS_NS\QSZTRWXRT[RQ^RNaQKdQHhQEkQBnP?rP;uP8yP5|O2O.O+N(N$N!NMMMLL LLKJJIHGFFEDCB A A @ ? > ==<;:988765443vdS"B31C Sbr}rnq-`q.@,B)D'F%H#K!MOQSUXZ\^ ` c egiknnnoo o ooo|ozoxovotoqo oo"mo$ko&ho(fo+do-bo/_o1]o3[o6Yo8Wo:TooS;oU9oW7pY5p\2p^0p`.pb+pe)pg'pi%pk"pn ppprpupwpyp{p~pp p ppppp:Kx;KwKt?Ks@KrAKrBKqBKpCKoDKnEKnFKmFKlGKkHKjIKiJKiKKhKKgLKfMKeNKdOKdPKcPKbQKaRK`SK`TK_TK^UK]VK\WK[XK[YKZYKYZKX[KW\KV]KV^KU^KT_KS`KRaKRbKQbKPcKOdKNeKMfKMgKLgKKhKJiKIjKHkKHlKGlKFmKEnKDoKCpKCpKBqKArK@sK?tK?uK>uK=vKAD G JMPRRS S SSTTTTTUU"U$U&U)V+V}-Vz0Vx2Wu4Ws6Wp8Wn:Wlf[!<":$8&6'5)3+1,/.-0+2)3'5%7#9!;=?@BDFHJL N PRUWXXXX X WWWWWVVVV"V%U'U*U-U|/Uz2Tw5Tu8Tr:To=Tm@SjCSgFSeISbLR_OR\RRZURWXQT[QQ_QNbQKePHhPElPBoP?sO = =<;:9887654432weT"C32C"Sbr }sns,`r;QqICqX5pf(pto onljhfd b `][YWUSQOM"J$H&F(D*B,@.>1<39577593;1>/@-B*D(F&H$K"M OQSUXZ\^` c egiknppppp p pp|pzpxpvptpqpop!mp#kp%hp'fp)dp,bp._p0]p2[p5Yp7Wp9Tp;Rp=Pp@MpBKpDIpFGpIDpKBpM@pO>qR;qT9qV7qX5q[2q]0q_.qa+qd)qf'qh%qj"qm qoqqqsqvqxqzq}qq q qqqqq;JxJu?Jt@JsAJrBJrBJqCJpDJoEJnFJnFJmGJlHJkIJjJJiKJiKJhLJgMJfNJeOJdPJdPJcQJbRJaSJ`TJ`TJ_UJ^VJ]WJ\XJ[YJ[YJZZJY[JX\JW]JV^JV^JU_JT`JSaJRbJRbJQcJPdJOeJNfJMgJMgJLhJKiJJjJIkJHlJHlJGmJFnJEoJDpJCpJCqJBrJAsJ@tJ?uJ?uJ>vJ=wJ:740-#*''*#- 147;>AD G JMPQRR R RSSSSTTT T"T%U'U)U,U}.Uz0Vx2Vu5Vs7Vp9Vn;Wl=Wj?WgAWeCWcEXaGX^IX\KXZMXXOXVQYTSYRUYPWYNYYLZZJ\ZH^ZF`ZDbZBcZ@eZ>g[SmASjDRgGReJRbMR_PQ\SQZVQWYQT\PQ_PNcPKfPHiOElOBpO?sO = = <;:98876544321xfU"D33C#Sbr }tnt+`s:QsHCrW5qe(qsp pomkige c a_\ZXVTRPN"L$I&G(E*C,A.?1=3;587694;2>0@.B,D)F'H%K#M!OQSUXZ\^` c e giknpqqqq q qq|qzqxqvqtqqqoq mq"kq$hq&fq(dq+bq-_q/]q1[q3Yq6Wq8Tq:RqrP;rS9rU7rW5rY2r\0r^.r`+rb)re'rg%ri"rl rnrprrrurwryr{r~r r rrrrrJv?Ju@JtAJsBJrBJrCJqDJpEJoFJnFJnGJmHJlIJkJJjKJiKJiLJhMJgNJfOJePJdPJdQJcRJbSJaTJ`TJ`UJ_VJ^WJ]XJ\YJ[YJ[ZJZ[JY\JX]JW^JV^JV_JU`JTaJSbJRbJRcJQdJPeJOfJNgJMgJMhJLiJKjJJkJIlJHlJHmJGnJFoJEpJDpJCqJCrJBsJAtJ@uJ?uJ?vJ>wJ=xJAD GJMPQQQ Q RRRRSSSS!T#T%T(T*T,U}/Uz1Ux3Uu5Us7Vp:VnVj@VgBWeDWcFWaHW^JW\LXZNXXPXVRXTTXRUXPWYNYYL[YJ]YH_YF`YDbZBdZ@fZ>gZ=!;"9$7&5'4)2+0,..,0*2(3&5$7"9 ;=?@BDFHJL N PRUWWWWV V VVVVUUUU!U#T&T(T+T.S|0Sz3Sw6Su9SrRmARjDRhGQeJQbMQ_PQ]SQZVPWZPT]PQ`ONcOKfOHjOEmNBqN?tN = = < ;:988765443210yhV"E34C$Sbr }unu*`t8QtGCsV5rd(rrq qpnljhf d b`][YWUSQO"M$J&H(F*D,B.@1>3<597795;3>1@/B-D*F(H&K$M"O QSUXZ\^`c e giknprrrr r r r|rzrxrvrtrqrormr!kr#hr%fr'dr*br,_r.]r0[r2Yr5Wr7Tr9Rr;Pr=Ms@KsBIsDGsFDsIBsK@sM>sO;sR9sT7sV5sX2s[0s].s_+sa)sd'sf%sh"sj smsosqstsvsxszs}s s sssss=Ix=Iw>Iw?Iv@IuAItBIsBIrCIrDIqEIpFIoFInGInHImIIlJIkKIjKIiLIiMIhNIgOIfPIePIdQIdRIcSIbTIaTI`UI`VI_WI^XI]YI\YI[ZI[[IZ\IY]IX^IW^IV_IV`IUaITbISbIRcIRdIQeIPfIOgINgIMhIMiILjIKkIJlIIlIHmIHnIGoIFpIEpIDqICrICsIBtIAuI@uI?vI?wI>xI=yIA D GJMPPPP QQQQRRRRS!S$S&S(T+T-T}/Tz1Tx4Uu6Us8Up:Un
        Vj@VgCVeEVcGVaIW^KW\MWZNWXPWVRWTTXRVXPXXNZXL\XJ]YH_YFaYDcYBdY@fY>hZ = = < ; :9887654432100{iW"F36C%Sbr }wnv(`u7QuFCtT5tc(sqr rqomkig e ca_\ZXVTRP"N$L&I(G*E,C.A1?3=5;7896;4>2@0B.D,F)H'K%M#O!QSUXZ\^`c e g iknprssss s s|szsxsvstsqsosms ks"hs$fs&ds(bs+_s-]s/[s1Ys4Ws6Tt8Rt:PttN;tQ9tS7tU5tW2tZ0t\.t^+t`)tc'te%tg"ti tltntptrtutwtyt|t~ t tuuuu=Hx>Hw?Hw@HvAHuBHtBHsCHrDHrEHqFHpFHoGHnHHnIHmJHlKHkKHjLHiMHiNHhOHgPHfPHeQHdRHdSHcTHbTHaUH`VH`WH_XH^YH]YH\ZH[[H[\HZ]HY^HX^HW_HV`HVaHUbHTbHScHRdHReHQfHPgHOgHNhHMiHMjHLkHKlHJlHImHHnHHoHGpHFpHEqHDrHCsHCtHBuHAuH@vH?wH?xH>yH=zHA D GJMOOP P PPQQQQQR R"R$R'S)S+S.S}0Tz2Tx4Tu7Ts9Tp;Un=Ul?UjAUgCUeEVcGVaIV^KV\MVZOWXQWVSWTUWRWWPXWNZXL\XJ^XH`XFbXDcXBeY@gY>hY = = < ; : 9887654432100/|jY"H37C&Sbr }xnw'`v6QvECuS5ub(tpt} srpnljh f db`][YWUSQ"O$M&J(H*F,D.B1@3>5<7997;5>3@1B/D-F*H(K&M$O"Q SUXZ\^`ce g iknprtttt t t |tztxtvtttqtotmtkt!ht#ft%dt'bt*_t,]t.[u0Yu2Wu5Tu7Ru9Pu;Mu>Ku@IuBGuDDuFBuI@uK>uM;uO9uR7uT5uV2uX0u[.u]+u_)ua'ud%uf"uh ukumuouqutuvuxuzv} v vvvvv>Gx?Gw@GwAGvBGuBGtCGsDGrEGrFGqFGpGGoHGnIGnJGmKGlKGkLGjMGiNGiOGhPGgPGfQGeRGdSGdTGcTGbUGaVG`WG`XG_YG^YG]ZG\[G[\G[]GZ^GY^GX_GW`GVaGVbGUbGTcGSdGReGRfGQgGPgGOhGNiGMjGMkGLlGKlGJmGInGHoGHpGGpGFqGErGDsGCtGCuGBuGAvG@wG?xG?yG>zG=zG<{G;|G:}G:~G9G8G7G6G5G5G4G3G2G1G1G0G/G.G-G,G,G+G*G)G(G'G'G&G%G$G#G#G"G!G GGGGGGGGGGGGGGGGGGGGGGG G G G G G GGGGGGGGGGGEB > ;740-*#''$* -147;>A DGJMNOO O OPPPPQQQ Q#R%R'R*R,R.S}1Sz3Sx5Su7Ts9Tp;Tn>Tl@TjBUgDUeFUcHUaJU^LV\NVZPVXRVVSVTUVRWWPYWN[WL]WJ_WH`XFbXDdXBfX@gX>iXPp@PmCPjFPhIOeLObOO_RO]UNZXNW\NT_NQbMNeMKiMHlMEoLBsL?vL= = < ; : 9 88765443210//.}kZ"I38C'Sbr}ynx&`x5QwDCvR5va(uou| tsqomki g eca_\ZXVTR"P$N&L(I*G,E.C1A3?5=7;98;6>4@2B0D.F,H)K'M%O#Q!SUXZ\^`ce g i knprtuuuu u |uzuxuvutuquoumuku hu"fu$du&bv(_v+]v-[v/Yv1Wv4Tv6Rv8Pv:MvvL;vN9vQ7vS5vU2vW0vZ.v\+v^)v`'vc%ve"vg vivlvnvpwrwuwwwyw| w~ wwwww?Fx@FwAFwBFvBFuCFtDFsEFrFFrFFqGFpHFoIFnJFnKFmKFlLFkMFjNFiOFiPFhPFgQFfRFeSFdTFdTFcUFbVFaWF`XF`YF_YF^ZF][F\\F[]F[^FZ^FY_FX`FWaFVbFVbFUcFTdFSeFRfFRgFQgFPhFOiFNjFMkFMlFLlFKmFJnFIoFHpFHpFGqFFrFEsFDtFCuFCuFBvFAwF@xF?yF?zF>zF={F<|F;}F:~F:F9F8F7F6F5F5F4F3F2F1F1F0F/F.F-F,F,F+F*F)F(F'F'F&F%F$F#F#F"F!F FFFFFFFFFFFFFFFFFFFFFFF F F F F F FFFFFFFFFFFDA = :630,)#&'#* -147;> A DGJMNNN N OOOOPPPP!Q#Q&Q(Q*R-R/R}1Rz3Rx6Su8Ss:SpTl@TjBTgDTeFTcHUaJU^LU\NUZPUXRUVTVTVVRXVPZVN\VL]WJ_WHaWFcWDdWBfW@hX>jX<;!9"7$5%3'1)0+.,,.*0(2&3$5"7 9;=?@BDFH J L NPRTUUTT T TTSSSSSR R#R&R(R+Q.Q0Q|3Qz6Pw9Pu;Pr>PpAOmDOjGOhJOeMNbPN_SN]VNZYMW\MT_MQcMNfLKiLHmLEpLBsK?wK== < ; : 9 8 8765443210//.-~~l["J39C)Sbr}zny%`y4QxCCwQ5w_(vnv{ uuspnlj h fdb`^[YWUS"Q$O&M(J*H,F.D1B3@5>7<99;7>5@3B1D/F-H*K(M&O$Q"S UXZ\^`ceg i knprtvvvv v |v zvxvvvtvqvovmvkvhw!fw#dw%bw'_w*]w,[w.Yw0Ww2Tw5Rw7Pw9Mw;Kw>Iw@GwBDwDBwG@wI>wK;wM9wO7wR5wT2wV0wX.w[+w])w_'wb%wd"wf whxkxmxoxqxtxvxxxz x} xxxxx@ExAEwBEwBEvCEuDEtEEsFErFErGEqHEpIEoJEnKEnKEmLElMEkNEjOEiPEiPEhQEgREfSEeTEdTEdUEcVEbWEaXE`YE`YE_ZE^[E]\E\]E[^E[^EZ_EY`EXaEWbEVbEVcEUdETeESfERgERgEQhEPiEOjENkEMlEMlELmEKnEJoEIpEHpEHqEGrEFsEEtEDuECuECvEBwEAxE@yE?zE?zE>{E=|E<}E;~E:E:E9E8E7E6E5E5E4E3E2E1E1E0E/E.E-E,E,E+E*E)E(E'E'E&E%E$E#E#E"E!E EEEEEEEEEEEEEEEEEEEEEEE E E E E E EEEEEEEEEEED@ = 962/,(#%'"*-147;> A DGJMMM M NNNNOOOOP"P$P&P)Q+Q-Q0Q}2Rz4Rx6Ru8Rs;Rp=Sn?SlASjCSgESeGTcITaKT^MT\OUZQUXSUVUUTWURXUPZVN\VL^VJ`VHaVFcWDeWBgW@hW>jW<: 8"6$5%3'1)/+-,+.)0'2&3$5"7 9;=?@BDFH J LNPRTTTT T S SSSSRRRR!R$Q&Q)Q,Q.P1P|4Pz6Pw9Pu==< ; : 9 8 8 765443210//.-,}~n\"K3:C*Sb r}{nz$`z3QyBCyP5x^(wlwz vvtqomk i geca_\ZXVT"R$P&N(L*I,G.E1C3A5?7=9;;8>6@4B2D0F.H,K)M'O%Q#S!UXZ\^`ceg i k nprtvwwww |w zwxwvwtwqwoxmxkxhx fx"dx$bx&_x(]x+[x-Yx/Wx1Tx4Rx6Px8Mx:KxxJ;xL9xN7xQ5xS2xU0xW.xZ+x\)x^'x`%yc"ye ygyiylynypysyuywyy y| y~yyyyAExBEwBEwCEvDEuEEtFEsFErGErHEqIEpJEoKEnKEnLEmMElNEkOEjPEiPEiQEhREgSEfTEeTEdUEdVEcWEbXEaYE`YE`ZE_[E^\E]]E\^E[^E[_EZ`EYaEXbEWbEVcEVdEUeETfESgERgERhEQiEPjEOkENlEMlEMmELnEKoEJpEIpEHqEHrEGsEFtEEuEDuECvECwEBxEAyE@zE?zE?{E>|E=}E<~E;E:E:E9E8E7E6E5E5E4E3E2E1E1E0E/E.E-E,E,E+E*E)E(E'E'E&E%E$E#E#E"E!E EEEEEEEEEEEEEEEEEEEEEEE E E E E E EEEEEEEEEEEC? < 851.+(#$'!*-147;> A DGJLLL M MMMNNNOO O"O%O'P)P,P.P0Q}2Qz5Qx7Qu9Rs;Rp=Rn?RlBRjDSgFSeHScJSaLS^NT\PTZQTXSTVUTTWURYUP[UN]UL^UJ`VHbVFdVDfVBgV@iW>kW@BDFH J LNPRTTSS S SSRRRRRQQ"Q$Q'P)P,P/P2P|4Oz7Ow:Ou=Or?NpBNmENjHNhKMeNMbQM_TM]WLZZLW^LTaKQdKNgKKkKHnJEqJBuJ?xI<|I9I5I2H/H+H(G%G!GFFFEE EDDCBAA@?>==<; : 9 8 8 7 65443210//.-,+|}o~]"~L3;C+Sb r}|n|#`{2QzACzO5y](xkxy wwuspnl j hfdb`^[YWU"S$Q&O(M*J,H.F1D3B5@7>9<;9>7@5B3D1F/H-K*M(O&Q$S"U XZ\^`cegi k nprtvxxxx |x zx xxvytyqyoymykyhyfy!dy#by%_y']y*[y,Yy.Wy0Ty2Ry5Py7My9Ky;Iy>Gy@DyBByD@yG>yI;yK9yM7yP5yR2yT0yV.zY+z[)z]'z_%zb"zd zfzhzkzmzozqztzvzx z{ z}zzzzBDxBDwCDwDDvEDuFDtFDsGDrHDrIDqJDpKDoKDnLDnMDmNDlODkPDjPDiQDiRDhSDgTDfTDeUDdVDdWDcXDbYDaYD`ZD`[D_\D^]D]^D\^D[_D[`DZaDYbDXbDWcDVdDVeDUfDTgDSgDRhDRiDQjDPkDOlDNlDMmDMnDLoDKpDJpDIqDHrDHsDGtDFuDEuDDvDCwDCxDByDAzD@zD?{D?|D>}D=~D<D;D:D:D9D8D7D6D5D5D4D3D2D1D1D0D/D.D-D,D,D+D*D)D(D'D'D&D%D$D#D#D"D!D DDDDDDDDDDDDDDDDDDDDDDD D D D D D DDDDDDDDDDDB> ; 741-*'#$' *-147;> ADGJKKL L LMMMMNNN!N#O%O(O*O,P/P1P}3Pz5Px8Qu:QsQn@RlBRjDRgFReHRcJSaLS^NS\PSZRSXTTVVTTXTRZTP[TN]UL_UJaUHcUFdUDfVBhV@jV>kV=;9 7"5$4%2'0).+,,*.(0&2$3#5!79;=>@BDFH J LNPRSSSS R RRRRQQQQ Q"P%P'P*P-O/O2O|5Oz8Nw:Nu=Nr@NpCMmFMjIMhLMeOLbRL`UL]XLZ[KW^KTbKQeJNhJKkJHoJErIBuI?yI<|H9H5H2G/G,G(F%F!FEEEDD DCCBAA@?>==<;: 9 8 8 7 6 5443210//.-,++{|p|_"}N3~=C,Sb r}}n}"`|1Q{?C{N5z\(zjyx xxvtqom k igeca_\ZXV"T$R&P(N*L,I.G1E3C5A7?9=;;>8@6B4D2F0H.K,M)O'Q%S#U!XZ\^`cegi k n prtvyyyy|y zz xzvztzqzozmzkzhzfz dz"bz$_z&]z)[z+Yz-Wz/Tz1Rz4Pz6Mz8Kz:Iz=Gz?DzABzC@zE>zH;zJ9zL7zN5{Q2{S0{U.{W+{Z){\'{^%{`"{c {e{g{j{l{n{p{s{u{w {y {|{~{{{BCxCCwDCwECvFCuFCtGCsHCrICrJCqKCpKCoLCnMCnNCmOClPCkPCjQCiRCiSChTCgTCfUCeVCdWCdXCcYCbYCaZC`[C`\C_]C^^C]^C\_C[`C[aCZbCYbCXcCWdCVeCVfCUgCTgCShCRiCRjCQkCPlCOlCNmCMnCMoCLpCKpCJqCIrCHsCHtCGuCFuCEvCDwCCxCCyCBzCAzC@{C?|C?}C>~C=C<C;C:C:C9C8C7C6C5C5C4C3C2C1C1C0C/C.C-C,C,C+C*C)C(C'C'C&C%C$C#C#C"C!C CCCCCCCCCCCCCCCCCCCCCCC C C C C C CCCCCCCCCCCA> : 730-)&##' *-147; > ADGJJKK K LLLLMMMM!N$N&N(N+O-O/O2O}4Pz6Px8Pu:PslV<:9 7"5$3%1'/).+,,*.(0&2$3"5 79;=>@BDF H J LNPRSRRR R RQQQQQPP P#P%O(O+O-O0N3N|6Nz8Nw;Nu>MrAMpDMmGLjILhLLeOLbSK`VK]YKZ\KW_JTbJQeJNiIKlIHoIEsIBvH?zH<}H9G5G2G/F,F(F%E!EEDDDC CCBAA@?>==<;:9 8 8 7 6 5 443210//.-,++*zzq{`"|O3}>C}-S~b r}n~!`}0Q}>C|M5{[({izw yywuspn l jhfdb`^[YW"U$S&Q(O*M,J.H1F3D5B7@9>;<>9@7B5D3F1H/K-M*O(Q&S$U"X Z\^`cegik n prtvyz{{|{ z{ x{ v{t{q{o{m{k{h{f{d{!b{#_{%]{'[{*Y{,W{.T{0R{3P{5M{7K{9I{;G{>D{@B{B@{D>{G;|I9|K7|M5|P2|R0|T.|V+|Y)|['|]%|_"|b |d|f|h|k|m|o|r|t|v |x |{|}|||CBxDBwEBwFBvFBuGBtHBsIBrJBrKBqKBpLBoMBnNBnOBmPBlPBkQBjRBiSBiTBhTBgUBfVBeWBdXBdYBcYBbZBa[B`\B`]B_^B^^B]_B\`B[aB[bBZbBYcBXdBWeBVfBVgBUgBThBSiBRjBRkBQlBPlBOmBNnBMoBMpBLpBKqBJrBIsBHtBHuBGuBFvBEwBDxBCyBCzBBzBA{B@|B?}B?~B>B=B ADGIJJ J KKKKLLLL M"M$M'M)N+N.N0N2O}4Oz7Ox9Ou;Ps=Pp?PnAPlCQjEQgGQeIQcKQaMR^OR\QRZSRXURVWSTYSR[SP]SN^SL`TJbTHdTFfTDgTBiU@kU>lU@BDF H JLNPRRRR Q Q QQQPPPPO!O$O&O)O+N.N1N3N}6Mz9Mw==<;:98 8 7 6 5 4 43210//.-,++*)xysza"{P3{?C|.S}b~r}n`~.Q~=C}L5|Z(|h{v zzxvtro m kigeca_\ZX"V$T&R(P*N,L.I1G3E5C7A9?;=>;@8B6D4F2H0K.M,O)Q'S%U#X!Z\^`cegik n p rtvy{||||z| x| v|t|q|o|m|k|h|f|d| b|"_|$]|&[|)Y|+W|-T|/R|1P|4M|6K|8I|:G|=D|?B}A@}C>}F;}H9}J7}L5}O2}Q0}S.}U+}X)}Z'}\%}^"}a }c}e}g}j}l}n}p}s}u }w }z}|}~}}DAxEAwFAwFAvGAuHAtIAsJArKArKAqLApMAoNAnOAnPAmPAlQAkRAjSAiTAiTAhUAgVAfWAeXAdYAdYAcZAb[Aa\A`]A`^A_^A^_A]`A\aA[bA[bAZcAYdAXeAWfAVgAVgAUhATiASjARkARlAQlAPmAOnANoAMpAMqALqAKrAJsAItAHuAHuAGvAFwAExADyACzACzAB{AA|A@}A?~A?A>A=A ADGIII J JJJKKKLL L#L%M'M*M,M.N1N3N}5Nz7Ox9OuOp@OnBPlDPjFPgHPeJQcLQaNQ^PQ\RQZTRXVRVXRTZRR[SP]SN_SLaSJcSHdSFfTDhTBjT@kT>mT@BDF H JLNPRQQQ Q QPPPPPOOO"O$N'N)N,N/M1M4M}7Mz:Lx==<;:988 7 6 5 4 4 3210//.-,++*)(wxtyb"zQ3z@C{0S|b|r}n`-Q><@9B7D5F3H1K/M-O*Q(S&U$X"Z \^`cegikn p rtvy{}}|}z} x} v} t}q}o}m}k}h}f}d}b}!_}#]}%[}'Y}*W},T}.R}0P}3M}5K}7I}9G~;D~>B~@@~B>~D;~G9~I7~K5~M2~P0~R.~T+~V)~Y'~[%~]"~_ ~b~d~f~h~k~m~o~r~t ~v ~x~{~}E@xF@wF@wG@vH@uI@tJ@sK@rK@rL@qM@pN@oO@nP@nP@mQ@lR@kS@jT@iT@iU@hV@gW@fX@eY@dY@dZ@c[@b\@a]@`^@`^@__@^`@]a@\b@[b@[c@Zd@Ye@Xf@Wg@Vg@Vh@Ui@Tj@Sk@Rl@Rl@Qm@Pn@Oo@Np@Mq@Mq@Lr@Ks@Jt@Iu@Hu@Hv@Gw@Fx@Ey@Dz@Cz@C{@B|@A}@@~@?@?@>@=@<@;@:@:@9@8@7@6@5@5@4@3@2@1@1@0@/@.@-@,@,@+@*@)@(@'@'@&@%@$@#@#@"@!@ @@@@@@@@@@@@@@@@@@@@@@@ @ @ @ @ @ @@@@@@@@@@@?; 8 41-*'$# '*-147; >ADGHHI I IIJJJKKK!K#L&L(L*L-M/M1M4M}6Nz8Nx:NuOp@OnCOlEOjGPgIPeKPcMPaOP^QQ\SQZTQXVQVXQTZRR\RP^RN`RLaSJcSHeSFgSDhSBjS@lT>nT<;97 5"3$2%0'.),+*,(.&0$2"3 579;=>@BDF H JLNPQQQP P PPPOOOON N"N%N'N*M-M/M2M5L}7Lz:Lx=Lu@KrCKpFKmHJkKJhNJeQJbTI`XI][IZ^HWaHTdHQgHNkGKnGHqGEuFBxF?|F<E9E6E2D/D,D(C%C!CBBBAA @@@?>==<;:9887 6 5 4 4 3 210//.-,++*)('vwuxc"xR3yACz1S{ b{r|n`,Q;CJ5~X(~f}t }|zxvtr o mkigeca_]Z"X$V&T(R*P,N.L1I3G5E7C9A;?>=@;B8D6F4H2K0M.O,Q)S'U%X#Z!\^`cegikn p r tvy{}~|~z~x~ v~ t~q~o~m~k~h~f~d~b~ _~"]~$[~&Y~)W~+T~-R~/P~1M4K6I8G:D=B?@A>C;F9H7J5L2O0Q.S+U)X'Z%\"^ acegjlnps u wz|~F@xF@wG@wH@vI@uJ@tK@sK@rL@rM@qN@pO@oP@nP@nQ@mR@lS@kT@jT@iU@iV@hW@gX@fY@eY@dZ@d[@c\@b]@a^@`^@`_@_`@^a@]b@\b@[c@[d@Ze@Yf@Xg@Wg@Vh@Vi@Uj@Tk@Sl@Rl@Rm@Qn@Po@Op@Nq@Mq@Mr@Ls@Kt@Ju@Iu@Hv@Hw@Gx@Fy@Ez@Dz@C{@C|@B}@A~@@@?@?@>@=@<@;@:@:@9@8@7@6@5@5@4@3@2@1@1@0@/@.@-@,@,@+@*@)@(@'@'@&@%@$@#@#@"@!@ @@@@@@@@@@@@@@@@@@@@@@@ @ @ @ @ @ @@@@@@@@@@@>: 7 30-)&## '*-147 ; >ADGGHH H HIIIJJJJ"K$K&K)K+L-L0L2M4M}6Mz9Mx;Nu=Ns?NpANnCNlEOjGOgIOeKOcMPaOP^QP\SPZUPXWQVYQT[QR]QP^RN`RLbRJdRHfRFgSDiSBkS@lS>nS@BD F H JLNPPPPP P OOOONNNN N#M%M(M+M-L0L3L5L}8Kz;Kx>Ku@KrCJpFJmIJkLIhOIeRIbUI`XH][HZ^HWbGTeGQhGNkGKoFHrFEvFByE?|E==<;:98876 5 4 4 3 2 10//.-,++*)(''uvvve"wS3xCCy2Sy"bzr{ n`+Q:CH5W(e~s ~}{ywus q nljhfdb`^["Y$W&U(S*Q,O.M1K3H5F7D9B;@>>@@@>B;D9G7I5K2M0P.R+T)V'Y%["] _bdfikmor t vx{}F?xG?wH?wI?vJ?uK?tK?sL?rM?rN?qO?pP?oP?nQ?nR?mS?lT?kT?jU?iV?iW?hX?gY?fY?eZ?d[?d\?c]?b^?a^?`_?``?_a?^b?]b?\c?[d?[e?Zf?Yg?Xg?Wh?Vi?Vj?Uk?Tl?Sl?Rm?Rn?Qo?Pp?Oq?Nq?Mr?Ms?Lt?Ku?Ju?Iv?Hw?Hx?Gy?Fz?Ez?D{?C|?C}?B~?A?@?????>?=?ADFFG G GHHHIIII J"J%J'K)K,K.K0L3L5L}7Lz9Mx;Mu>Ms@MpBNnDNlFNjHNgJOeLOcNOaPO^RO\TPZVPXXPVYPT[QR]QP_QNaQLcQJdRHfRFhRDjRBkR@mS>oS@BD F HJLNPPPO O O OONNNNMM!M#M&L)L+L.L0K3K6K}9Kz;Jx>JuAJrDJpGImJIkMIhPIeSHbVH`YH]\GZ_GWbGTfFQiFNlFLoFHsEEvEBzE?}D>==<;:988765 4 4 3 2 1 0//.-,++*)(''&ttwuf"vU3wDCx3Sx#byrz n`*Q9CG5V(dr ~|zxvt r omkigeca_]"Z$X&V(T*R,P.N1L3I5G7E9C;A>?@=B;D8F6H4K2M0O.Q,S)U'X%Z#\!^`~c~e~g~i~k~n~p~ r~ t~ v~y~{~}~|zxv t qomkhfdb_ ]"[$Y&W)T+R-P/M2K4I6G8D:B=@?>A;C9F7H5J2L0O.Q+S)U'X%Z"\ ^acegjlnq s uwz|G>xH>wI>wJ>vK>uK>tL>sM>rN>rO>qP>pP>oQ>nR>nS>m           !$'),/1469<>ADp>Pq>Oq>Nr>Ms>Mt>Lu>Ku>Jv>Iw>Hx>Hy>Gz>Fz>E{>D|>C}>C~>B>A>@>?>?>>>=><>;>:>:>9>8>7>6>5>5>4>3>2>1>1>0>/>.>->,>,>+>*>)>(>'>'>&>%>$>#>#>">!> >>>>>>>>>>>>>>>>>>>>>>> > > > > > >>>>>>>>>>><9 5 2.+(%!#'*-147 ; >ADEFF F GGGHHHHI!I#I%J(J*J,J/K1K3K5K}8Lz:LxLs@MpBMnDMlGMjINgKNeMNcONaQO^RO\TOZVOXXOVZPT\PR^PP`PNaQLcQJeQHgQFhQDjRBlR@nR>oR<;975 4"2$0%.',)*+(,'.%0#2!3579;=>@BD F HJLNOOOO O NNNNMMMMM!L$L'L)L,K.K1K4K7J}9Jz >>==<;:9887654 4 3 2 1 0 //.-,++*)(''&%rsytg"uV3vECv4Sw$bxry n`)Q8CF5U(cq ~}{ywu s qnljhf~d~b~`~^"~[$~Y&~W(~U*~S,~Q.~O1~M3~K5~H7~F9~D;~B>~@@~>B~>@;B9E7G5I2K0N.P+R)T'W%Y"[ ]`bdfikmo r tvy{H=xI=wJ=wK=vK=uL=tM=sN=rO=rP=qP=pQ=o)&$!       "$'*,/2479<?ADFILNQ T V Y [ ^ a c fiknpsvx{~}{ywus=5=4=3=2=1=1=0=/=.=-=,=,=+=*=)=(='='=&=%=$=#=#="=!= ======================= = = = = = ===========;8 4 1.*'$!#'*-147 ;>ADEEE F FFGGGGHH!H$I&I(I+I-J/J2J4K6K}8Kz;Kx=Lu?LsALpCLnEMlGMjIMgKMeMNcONaQN^SN\UNZWOXYOV[OT]OR^PP`PNbPLdPJfPHgQFiQDkQBlQ@nQ>pR<:875 3"1$/%.',)**(,&.$0"2 3579;=>@BD F HJLNOONN N NNMMMMLL L"L%K'K*K,K/J2J4J7J}:Iz=Ix@IuBIsEHpHHmKHkNGhQGeTGcWG`ZF]]FZaFWdETgERjEOnDLqDItDFxCB{C?C>> ==<<;:98876544 3 2 1 0 / /.-,++*)(''&%$qrzsh"tW3tFCu5Sv%bwrx n`(Q7CE5T(bp }~~~|~z~x~v ~t ~r~o~m~k}i}g}e}c}a}_"}]$}Z&}X(}V*}T,}R.}P1}N3}L5}I7}G9}E;}C>}A@}?B}=D};F}8H}6K}4M}2O}0Q}.S},U|)X|'Z|%\|#^|!`|c|e|g|i|k|n|p|r| t| v| y|{|}||zxvt q omkhfdb_] ["Y$W&T)R+P-M/K2I4G6D8B:@=>?;A9C7F5H2J0L.O+Q)S'U%X"Z \^acehjln q suwzIADDDE EEFFFFGG G"H$H'H)I+I.I0I2J5J7J}9Jz;Kx=Ku?KsBKpDLnFLlHLjJLgLMeNMcPMaRM^TN\VNZXNXYNV[OT]OR_OPaONcOLdPJfPHhPFjPDkPBmQ@oQ>pQ@B D F HJLNNNNN M MMMLLLLL K#K%K(K*J-J0J2J5I8I};Iz=Hx@HuCHsFHpIGmLGkOGhRFeUFcXF`[F]^EZaEWdEThDRkDOnDLrCIuCFxCB|B?B>>== <<<;:988765443 2 1 0 / / .-,++*)(''&%$#pq{ri"rX3sGCt7Su&bvrvn`'Q6CD5R(ao |}}}}{}y}w }u }s}q}n|l|j|h|f|d|b|`"|^$|\&|Y(|W*|U,|S.|Q1|O3|M5|K7|H9|F;|D>|B@|@B|>D|>;@9B7E5G2I0K.N+P)R'T%W"Y []`bdfikm p rtvyJ;xK;wK;wL;vM;uN;tO;sQOLJG D B ?=:8530.+) &"#$!&(*,.013 5 79;=??>> = =<;;::99 8#7%7(6+6-504245373:2<2?1B0D0G/I/L.N-Q-S~,V|,Yz+[x+^v*`t)cr)ep(hn(jl'mj'ph&rf%ud%wb$z`$|^#\"Z"X!V!T R PNLJHFDBA?=;97531/-+)'%#!     ;;;;;;;;;;:6 3 /,)%"#'*-14 7 ;>ACCD D DEEEEFFF G#G%G'H*H,H.H1I3I5I7J}:JzJu@KsBKpDKnFKlHLjJLgLLeNLcPMaRM^TM\VMZXMXZNV\NT^NR`NPaONcOLeOJgOHhOFjPDlPBnP@oP>qP=;9764 2"0$.%-'+))*',%.#0!13579;<>@B D FHJLNNMM M M MLLLLKKK!K#J&J(J+J.I0I3I6I8H};Hz>HxAHuDGsGGpIGmLFkOFhRFeUEcXE`\E]_EZbDWeDThDRlCOoCLrCIvBFyBC|B?A">>==<< <;;:9887654432 1 0 / / . -,++*)(''&%$#"op|pk"qY3rHCs8St'btrun`&Q4CC5Q(`m {||~|||z|x |v |t{r{p{m{k{i{g{e{c{a"{_${]&{Z({X*{V,{T.{R1{P3{N5{L7{I9{G;{E>{C@{AB{?D{=F{;H{8K{6Mz4Oz2Qz0Sz.Uz,Xz)Zz'\z%^z#`z!czezgzizkznzpzrztz vz yz {z}zzzxvtq o mkhfdb_][ Y"W$T&R)P+M-K/I2G4D6B8@;>=;?9A7C5F2H0J.L+O)Q'S%U"X Z\_acehjl n qsuxK;xK;wL;wM;vfca^\Y W TROMJHEC@>;!9#6%4'1)/+,-*/'0%2"4 68:<>@BD F GIKMONMM L LKKJIIHH!G#G&F(E+E-D0D3C5C8B:A=A?~@B|@Dz?Gx?Iv>Lt=Nr=Qp-<-:,8,6+4*2*0).),(*(('&&$&"% %$$#""!!    ;;;;;;;;;;95 2 /+(%!#'*-14 7 ;>ABCC C DDDDEEEF!F#F&G(G*G-G/H1H4H6I8I}:IzrP<:9753 2"0$.%,'*)(*&,$."0 13579;<>@B D FHJLMMMM L LLLLKKKKJ!J$J&J)I,I.I1H4H6H9H})>%>"==<<<; ;::98876544321 0 / / . - ,++*)(''&%$#""mn}ol"p[3qJCr9Ss)bsrt n`$Q3CB5P(^l z{{{}{{{y zw zuzszqznzlzjzhzfzdzb"z`$z^&z\(zY*zW,zU.zS1zQ3zO5zM7zK9zH;zF>zD@zBBz@Dz>Fz<;>9@7B5E2G0I.K+N)P'R%T"W Y[]`bdfik m prtvK:xzwurpn k i fda_\ZWURP M"K$H&F(C*A,>.3>1=/<-<,;*;(:&:$9"9 8776655433 2 2 110//+::::::::::85 1 .*'$!#'*-14 7;>AABB B CCCDDDEE"E$F&F)F+G-G0G2G4H7H9H};Hz=Ix?IuAIsCJpFJnHJlJJjLKgNKePKcRKaTL^VL\WLZYLX[LV]MT_MRaMPcMNdNLfNJhNHjNFkNDmOBoO@pO>rO@B D FHJLMMLL L LKKKKJJJJ"I$I'I*I,H/H2H4H7G:G}/>,>)=%="<<<;;: ::988765443210 / / . - , ++*)(''&%$#""!lmnm"o\3pKCq:Sq*brrs n`#Q2CA5O(]k yzzz~y|yz yx yvytyrypymykyiygyeyc"ya$y_&y](yZ*yX,yV.yT1yR3yP5yN7yL9yI;yG>yE@yCByADx?Fx=Hx;Kx8Mx6Ox4Qx2Sx0Ux.Xx,Zx)\x'^x%`x#cx!exgxixkxnxpxrxtxvx yx {x }xxwwvtqo m khfdb_][Y W"T$R'P)M+K-I/G2D4B6@8>;;=9?7A5D2F0H.J+M)O'Q%S"V XZ\_acehj l nqpqqrrs t t| uzuxvuvswpxnxkyiyfzd {b!{_#|]%|Z'}X)}U+~S-P/N0K2I4G6D8B:?<==:?8A5C3E1G.I,K)L'N$P"RTVXY[]_a c eghjllkk j iihhgg}f{fye"wd$ud'sc)qc,pb.nb1la3ja6h`8f_;d_=b^?`^B^]D\]G[\IY\LW[NUZQSZSQYVOYXMX[KX]IW_HVbFVdDUgBUi@Tl>Tn+999999999974 0 -*&# #'*-1 4 7;>@AA A BBBCCCDD D"E%E'E)F,F.F0F3G5G7G9H}Hx@HuBIsDIpFInHIlJJjLJgNJePJcRKaTK^VK\XKZZLX\LV^LT_LRaMPcMNeMLgMJhMHjNFlNDnNBoN@qO>sO@ B D FHJLLLLK K KKKJJJJI I#I%I(H*H-H/G2G5G8G:F}=Fz@FxCFuFEsHEpKEmNDkQDhTDeWCcZC`^C]aBZdBWgBUjARnAOqALt@Ix@F{@C???6>3>/=,=)<%<"<;;::: 9988765443210/ / . - , + +*)(''&%$#""! klmn"n]3oLCo;Sp+bqrr n`"Q1C@5N(\j xyyxx}x{ xy xwxuxsxqxoxlxjxhxfxd"xb$x`&x^(x\*xY,xW.xU1xS3xQ5xO7xM9xK;xH>xF@wDBwBDw@Fw>Hw9;<9>7@5B2E0G.I+K)N'P%R"T WY[]`bdgi k ^^_`` a a bbcddeef|fzgxhu!hs#ip$in&jl(ji*kg,ld.lb/m_1m]3n[5nX7oV9pS;pQqL@rJBrGDsEFtBGt@Iu>Ku;Mv9Ov6Qw4Sx2Tx/Vy-Xy*Zz(\z%^{#_|!a|c}e}g~ikln p rtvwyzzy}y {x yxxwvvtvrupuntlt js"is%gr'eq*cq,ap/_p1]o3[o6Yn8Xn;Vm=Tm@RlBPkDNkGLjIJjLIiNGiQEhSChVAgX?fZ=f];e_9eb8dd6dg4ci2ck0bn.ap,as*`u(`x'_z%_}#^!^]\\[[ZZYYX X WVVUUTP>+888888888863 0 ,)%"#'*-1 4 7;>@@@ A AABBBCCC D#D%D(E*E,E/E1F3F6F8G:G}GxAHuCHsEHpGInIIlKIjMIgOJeQJcSJaUJ^WK\YKZ[KX\KV^LT`LRbLPdLNeLLgMJiMHkMFlMDnNBpN@rN>sN<;97542 0".$,%*'))'*%,#.!013579;<>@ B DFHJLLKK K K JJJJIIII!H#H&H(H+G-G0G3G5F8F;F}>EzAExCEuFEsIDpLDnODkRChUCeXCc[B`^B]aBZeAXhAUkARn@Or@Lu@Ix?F|?C?@><>9>6=3=/<,<)<%;";:::99 888765443210// . - , + + *)(''&%$#""! jklo"l^3mMCnvG@vEBvCDvAFv?Hv=Kv;Mv8Ov6Qv4Sv2Uv0Xv.Zv,\v)^v'`v%cv#ev!gvivkvnvpvrvtvvuyu {u }u uuuutqom k hfdb_][YW T"R$P'M)K+I-G/D2B4@6>8;;9=7?5A2D0F.H+J)M'O%Q"S VXZ\_acLLMMNN O OPQQRRSSTUU V"V$W%W'X})Yz+Yx-Zu.Zs0[q2[n4\l6\i8]g9^e;^b=_`?_]A`[C`YDaVFbTHbQJcOLcMNdJOdHQeFSfCUfAWg>XgxI+ 777777777762 / +(%!#'*-1 4 7;>??@ @ @AAABBBC!C$C&D(D+D-D/E2E4E6F9F;F}=Gz?GxAGuCGsEHpGHnJHlLHjNIgPIeRIcSIaUJ^WJ\YJZ[JX]KV_KTaKRbKPdLNfLLhLJjLHkMFmMDoMBpM@rM>tN<:87531 /".$,%*'()&*$,". 013579;<>@ B DFHJKKKK J JJJIIIIHH!H$H&G)G+G.F1F3F6F9EEzADxDDuGDsJDpMCnPCkSChVBfYBc\B`_A]bAZeAXh@Ul@Ro@Or?Lv?Iy?F|>C>@><=9=6<3Sn-borp n` Q/C>5L(Zh vvvvvv} v{ vyvwvuvsvqvovlvjvhvf"vd$vb&v`(v^*v\,vY.vW1vU3vS5vQ7uO9uM;uK>uH@uFBuDDuBFu@Hu>Ku7;:9<7>5@2B0E.G+I)K'N%P"R TWY[::;;<< = = >??@@AABCCD!D#E%E&F(F*G,H.H/I1I3J5J}7Kz8Kx:LuMq@NnANlCOjEOgGPeIPcJQ`LR^NR[PSYRSWSTTUTRWUPYVM[VK\WI^WF`XDbXAdY?eY=gZ:i[8k[6m\3o\1p]/r],t^*v^(x_%y`#{` }aabbcddee f fgghfdb ` _][YWUTRP!N#L&J(I+G-E/C2A4?6>9<;:>8@6B4E2G1I/L-N+Q)S'U&X$Z"\ _adfh~k~m}p}r|t|w {y z{z~yyxxraP>+  777777777751 . +'$!#'*-1 47;>>>? ? @@@AAABB"B$C'C)C+D.D0D2D5E7E9E;F}>Fz@FxBFuDGsFGpHGnJHlLHjNHgPHeRIcTIaVI^XI\ZJZ\JX^JV_JTaKRcKPeKNgKLhKJjLHlLFnLDoLBqM@sM>tM @ B DFHJKJJJ J IIIIHHHHG"G$G'G)F,F/F1F4E7E9EIz>F}>C=@=<<9<6<3;/;,;):%:"998887 7 665443210//.- , + + * ) (''&%$#""! ghir"j`3kOCl?Sm.bnrnn`Q.C<5K(Yg uuuuuu~ u| uzuxuvuturupumukuiug"ue$uc&ua(u_*u],uZ.uX1uV3tT5tR7tP9tN;tL>tJ@tGBtEDtCFtAHt?Kt=Mt;Ot8Qt6St4Ut2Xt0Zt.\t,^t)`t'ct%et#gt!itktnspsrstsvsys{s }s s ssssqomk h fdb_][YWT R"P$M'K)I+G-D0B2@4>6;89;7=5?2A0D.F+H)J'M%O"Q S())**+ + , ,-..//00112 3"3$4&4'5)5+6-6.7082849697:9:;;=;?<@<B=}D>zF>xG?vI?sK@qM@oOAlPAjRBhTCeVCcWDaYD^[E\]EZ_FW`FUbGSdHPfHNhILiIIkJGmJEoKBpK@rL>tM;vM9xN7yN4{O2}O0P-P+Q)Q&R$S"STTUUVVWX X YYZZZXVT S QOMKIHFDB!@$?&=);+9-7052442709.;,>+@)B'E%G#I!L NQSUXZ\_ac f h jmoqtzraP>+  666666666640 - *&# #'*- 1 47;==> > >??@@@AA A#B%B'B*C,C.C1C3D5D8D:EEz@FxBFuEFsGFpIGnKGlMGjOGgQHeSHcUHaWH^YI\ZIZ\IX^IV`JTbJRdJPeJNgKLiKJkKHlKFnLDpLBrL@sL>uL=;976420 ."-$+%)'')%*#,!.013579;<> @ B DFHJJJJI I IIHHHHGG G"G%F'F*F-E/E2E5E7D:D=D}@CzBCxECuHCsKBpNBnQBkTAhWAfZAc]@``@]c@Zg?Xj?Um?Rp>Ot>Lw>Iz=F~=C<@<<<9;6;3;0:,:)9%9"988776 6 65443210//.-, + + * ) ( ''&%$#""! fghs"ib3jQCk@Sl/blrmn`Q-C;5J(Xf tttttt t} t{tytwtutstqtotltjth"tf$td&tb(t`*t^,t\.sY1sW3sU5sS7sQ9sO;sM>sK@sHBsFDsDFsBHs@Ks>Ms5;79:7<5>2@0C.E+G)I'L%     !!!"#"%#'#($*%,%.&/&1'3'5(6(8):)<*=+?+A,C,D-F-H.J.L/M/O0}Q1zS1xT2vV2sX3qZ3o[4l]4j_5ha5fb6cd7af7_h8\j8Zk9Xm9Uo:Sq:Qr;NtC}>A?>?<@:@7A5B3B0C.C,D)D'E%E#F FGHHIIJJK K LLMNLJIG E CA@><:87 5"3$1'/).+,.*0(2&5%7#9!<>@CEGJLNPS U W Z\^acjxraP> + 555555555530 , )&"#'*- 1 47;<== = >>>??@@@!A#A&A(B*B-B/B1C4C6C8D:D=D}?EzAExCEuEEsGFpIFnKFlMGjOGgQGeSGcUHaWH^YH\[HZ]IX_IVaITbIRdJPfJNhJLjJJkKHmKFoKDpKBrK@tL>uL<:975320 .",$*%('&)%*#,!.013579;<> @ BDFHJIII I H HHHGGGGF F#F&F(E+E-E0E3D5D8D;C=C}@CzCBxFBuIBsLBpOAnRAkUAhX@f[@c^@`a?]d?[g?Xj>Un>Rq>Ot=Lx=I{rL@rJBrGDrEFrCHrAKr?Mr=Or;Qr8Sr6Ur4Xr2Zr0\r.^r,`r)cr'eq%gq#iq!kqnqpqrqtqvqyq{q}q q q qqqqomkh f db_][YWTR P"M$K'I)G+D-B0@2>4;6987;5=2?0A.D+F)       "$&')+-.024579;<>@BCEGIJLNP Q S!U!W"X"Z#\#}]$z_$xa%vc%td&qf'oh'mj(jk(hm)fo)dq*ar*_t+]v+Zx,Xy,V{-T}.Q.O/M/J0H0F1D1A2?2=3:484654516/6-7*7(8&8$9!9:;;<<==> > ??@AA?=; 9 86421/-+) ("&%$'")!,.03579<>@C E G JLNPSZhvraP > +44444444442/ + (%!#'*- 1 47;<<< = ==>>>??@!@$@&A)A+A.A0B2B4B7C9C;C=D}?DzBDxDEuFEsHEpJEnLFlNFjPFgRFeTGcVGaXG^ZH\\HZ^HX_HVaITcIReIPgINhJLjJJlJHnJFoJDqKBsK@tK>vK @ BDFHIIIH H HHGGGGFFF!F$E&E)E+D.D1D3D6C9C;C>B}AB{DBxGBuIAsLApOAnR@kU@hX@f[?c^?`b?]e>[h>Xk>Un=Rr=Ou=LxqM@qKBqHDqFFqDHqBKq@Mq>Oq3;5977:5<2>0@.  !#%'(*,./13468:; = ? A B D F G I KMNPRSUWYZ\^`acefh}jzlxmvotqqsotmvkxhyf{d}b_][Y V T!R"P"M#K#I$G$D%B%@&=&;'9'7(4)2)0*.*++)+',%,"- -..//0112 2 3344420. , +)'%$" !#%'*,.13 5 7 :<>@CJXftra P >+33333333331. + '$!#'*- 147:;;< <<===>>> ?"?%?'@)@,@.A1A3A5B7B:BC}@CzBDxDDuFDsIDpKEnMElOEjQFgSFeUFcWFaXG^ZG\\GZ^GX`HVbHTdHReHPgINiILkIJmIHnJFpJDrJBsJ@uK>wK @ BDFHIHHH H GGGGFFFEE"E$E'D)D,D.D1C4C6C9B`b>]e>[i=Xl=Uo=RrpN@pLBpJDpGFpEHpCKpAMp?Op=Qp;Sp8Up6Xp4Zp2\o0^o.`o,co)eo'go%io#ko!noporotovoyo{o}oo o o oooomkhf d b_][YWTRP M"K$I'G)D+B-@0>2;496795;2=0?.   "$&(*,.023579;=?ACEGIKMNPRTVWY[\^`bceghjlm o q s t }v {x xy v{ t} romkifdb`][YWURPNLIGEC@><:8531/,*(& # !!!"##$$%% & & ''(('%#" !# & ( *,/13:HVdsr a P>+22222222221- * &# #'* - 147::: ; ;<<<===> >#>%?(?*?-@/@1@3A6A8A:BwJ<;975420. ,"*$)%''%)#*!,.013579:< > @ BDFHHHGG G GFFFFEEE E"D%D'D*C,C/C2C4B7B:B=A?A}BA{EAxH@vK@sN@pQ?nT?kW?hZ>f]>c`>`c=]f=[i=XloO@oMBoKDoHFoFHoDKoBMo@Oo>Qo1;395775:2<0>.    "$&(*,.024679;=?ACEGIKMOPRTVXZ\^`bcegikmoqstvxz|~~|zxvtrpmkigdb`^\YWU S Q N L J H F C A ?=:8642/-+)'$"        "$+9FTbq r aP>+22222222220, ) &"#'* - 14799: : :;;<<<==!=$>&>(>+?-?0?2@4@6@9A;A=A?B}ABzDBxFCuHCsJCpLCnNDlPDjRDgTEeVEcXEaZE^\F\]FZ_FXaFVcGTeGRgGPhGNjHLlHJnHHoHFqIDsIBtI@vI>xJ<:87531/. ,"*$(%&'$)"* ,.013579:< > @BDFHGGG G F FFFEEEED D#D%C(C*C-C0B2B5B8A:A=A@@}C@{F@xH@vK?sN?pQ?nT>kW>hZ>f]=c`=`d=]g<[jnP@nNBnLDnJFnGHnEKnCMnAOn?Qn=Sm;Um8Xm6Zm4\m2^m0`m.cm,em)gm'im%km#nm!pmrmtmvmym{m}mmm m m mlllkhfd b _][YWTRPM K"I$G'D)B+@->0;29476592;0=.    "$&(*,.024689;=?ACEGIKMOQRTVXZ\^`bdegikmoqsuvxz|~~|zywusqpnljhgeca`^\ZXWUSQONLJHFDB@=;97520.,*(%# !             )7DR` o }raP>+1111111111/, ( %"#'* - 147899 9 ::;;;<<<"=$='=)>,>.>0?3?5?7@9@<@>A@A}BAzDBxFBuHBsJCpMCnOClQCjSDgUDeVDcXEaZE^\E\^EZ`FXbFVdFTeFRgGPiGNkGLmGJnHHpHFrHDsHBuI@wI>xI @BDFGGGF F FFEEEDDDD!C#C&C)C+B.B0B3A6A8A;@>@A@}C@{F?xI?vL?sO>pR>nU>kX=h[=f^=ca<`d<]g;[k;Xn;Uq:Rt:Ox:L{9I9F8C8@8=7:7663606,5)5&4"433322 1 10//.-,++*)(' ' & % $ # ""! _`az"bi3cXCdGSe6bf&rfg`Q&C55C(R` mnnnnn n nnn}n{nynwmumsmqmo"mm$mj&mh(mf*md,mb.m`1m^3m\5mY7mW9mU;mS>mQ@mOBmMDmKFmHHmFKmDMmBOl@Ql>Sl/;19375572:0<.    "$&(*,.02468:<=?ACEGIKMOQSTVXZ\^`bdfgikmoqsuwxz|~~|zywusqpnljhgeca`^\ZXWUSQONLJHGECA@><:975320.,+)'%$"   (5BP ^ m |raP>+0000000000.+ ' $!#'* -147788 999::;;; <#<%<'=*=,=/>1>3>5?8?:?<@>@A@}CAzEAxGAuIBsKBpMBnOBlQCjSCgUCeWDcYDa[D^]D\_EZaEXbEVdFTfFRhFPjFNkGLmGJoGHqGFrHDtHBvH@wH>yI=;976420.- +")$'%%'#)!*,.013579: < > @BDFFFFF E EEEDDDDCC"C$B'B)B,B.A1A4A6@9@<@>?A?}D?{G?xJ>vM>sP>pR=nU=kX=i\lR@lPBlNDlLFlJHlGKlEMkCOkAQk?Sk=Uk;Xk8Zk6\k4^k2`k0ck.ek+gk)ik'kk%nk#pk!rktkvkyk{k}kkjj j j jjjjhfdb _ ][YWTRPMK I"G%D'B)@+>-;0927456290;.            !"$&(*,.02468:<>?ACEGIKMOQSUVXZ\^`bdfhikmoqsuwyz~||~zywusqpnljhgeca`^\ZXWUSQONLJHGECA@><:975320.,+)'%$"     &3A N \ kzraP>+//////////-* ' # #' * -14677 7 88999::;!;#;&<(<+<-=/=2=4>6>8>;?=???A@}C@zE@xHAuJAsLApNBnPBlRBjTBgVCeXCcZCa\D^]D\_DZaDXcEVeETgERhEPjFNlFLnFJoFHqGFsGDtGBvG@xH>yH<{H:}H8~I7I5I3I1J/J.J,J*J)K'K%K#K"L LLLLMMMMMNN C A?><:975320., *"($'%%'#)!*,.013579: < >@BDFFFEE E EDDDDCCC B"B%B'B*A,A/A2@4@7@:?{G>xJ>vM=sP=pS=nVkS@kQBkODkMFkKHjHKjFMjDOjBQj@Sj>Uj,;/917355280:.               ! # % & ( * , . 0 2 4 6 8 : < > @ B C E G I KMOQSUWXZ\^`bdfhjkmoqsuwy~z||z~ywusqpnljhgeca`^\ZXWUSQONLJHGECA@><:975320.,+)'%$"     $1 ? M [ixraP>+!..........-) & "#' * -14666 7 788899::!:$;&;);+<.<0<2=5=7=9>;>>>@?B?}D?zF@xH@uJ@sLApNAnPAlRBjTBgVBeXBcZCa\C^^C\`DZbDXdDVeDTgERiEPkENmELnFJpFHrFFsFDuGBwG@xG>zG<|H:}H8H7H5I3I1I/I.I,J*J)J'J%K#K"K KKLLLLLMMMM B A ?=<:86531/-, *"($&%$'") *,.013579: < >@BDFEEE E D DDCCCCBB B#B%A(A*A-@0@2@5?7?:?=?@>B>}E>{H=xK=vN=sQjT@jRBjPDiNFiLHiJKiGMiEOiCQiASi?Ui=Xi;Zi8\i6^i4`i2ci0ei.gi+ii)ki'ni%pi#ri!tiviyh{h}hhhhh h h hhhhfdb_ ] [YWTRPMKI G"D%B'@)>+;-9072542609.                 ! # % ' ) * , . 0 2 4 6 8 : < > @ B D E G I K M O Q S U W Y Z \ ^ ` b d f h j k m o q s u w~ y| {z|y~wusqpnljhgeca`^\ZXWUSQONLJHGECA@><:975320.,+)'%$"     " / = KYgvraP>+ #----------,( % "#' * -14556 6 6778889 9":%:':);,;.;1<3<5<7=:=<=>>@>C>}E?zG?xI?uK@sM@pO@nQAlSAjUAgWAeYBc[Ba]B^_C\aCZbCXdCVfDThDRjDPkENmELoEJqEHrFFtFDvFBwF@yG>{G<|G:~G8H7H5H3H1H/I.I,I*I)J'J%J#J"J KKKKLLLLLMM B @ >=;986421/-+ )"'$%%$'") *,.013579: < >@BDEEDD D DCCCCBBBA!A#A&A(@+@.@0?3?5?8>;>>>@>C=}F={I=xLiU@hSBhQDhOFhMHhKKhHMhFOhDQhBSh@Uh>Xh*;,9/71532508.         !# % ' ) + - . 0 2 4 6 8 : < > @ B D F G I K M O Q S U W Y [ \ ^ ` b d f h j l m o q s u~ w| yz {y |w ~u s q p n l j h g e c a ` ^ \ Z X W U S Q O N L JHGECA@><:975320.,+)'%$"     . ;IWetraP>+ "%----------+' $ !#' *-1444 5 56677788 8#9%9(:*:-:/;1;4;6<8<:<==?=A=C>}E>zG>xJ?uL?sN?pP@nR@lT@jVAgXAeZAc[Aa]B^_B\aBZcCXeCVgCThCRjDPlDNnDLoDJqEHsEFuEDvFBxF@zF>{F<}G:~G8G7G5G3H1H/H.H,I*I)I'I%J#J"J JJKKKKKLLLL A @ ><;975420.,+ )"'$%%#'!)*,.013579 : < >@BDDDDD C CCCBBBAAA!A$@&@)@,?.?1?3>6>9>;>>=A=D=}G<{I(LZ hiiiii h hhhhh~h|hzhxhvht"hr$hp&hn(hl*hi,hg.he1hc3ha5h_7h]9h[;hX>gV@gTBgRDgPFgNHgLKgJMgGOgEQgCSgAUg?Xg=Zg;\g8^g6`g4cg2eg0gg.ig+kg)ng'pf%rf#tf!vfyf{f}ffffff f f ffffdb_] [ YWTRPMKIG D"B%@'>);+9.70522406.         !#%')+-/02468:<>@BDFHIKMOQS U W Y [ ] ^ ` b d f h j l n o q s~ u| wz yy {w }u ~s q p n l j h g e c a ` ^ \ Z X W U S Q O N L J H G E C A @ > < : 9 7 5 3 2 0 . , + ) ' % $ "        ,9GUcrraP> +"$',,,,,,,,,,*' # # ' *-1334 4 55566777!8$8&9(9+9-:0:2:4;7;9;;<=<@xJ>uL>sN?pP?nR?lT@jV@gX@eZAc\Aa^A^`A\bBZdBXeBVgCTiCRkCPmCNnDLpDJrDHsDFuEDwEBxE@zE>|F<}F:F8F7G5G3G1G/H.H,H*H)I'I%I#I"I JJJJJKKKKKL A ? =<:87531/.,* ("&$$%#'!)*,.013579 : <>@BDDDCC C BBBBAAAA @"@%@'?*?,?/>1>4>7>9=<=?=BfW@fUBfSDfQFfOHfMKfKMfHOfFQfDSfBUf@Xf>Zf<\f9^f7`f5cf3ef1gf/if-ke*ne(pe&re$te"ve ye{e}eeeeeee e eeeedb_] [ Y WTRPMKIGD!B$@&>(;*9,7/512305.       !#%')+-/13468:<>@BDFHJKMOQSUWY[]_`bdfhjlnpq~s|uzwyyw{u}sqp n l j h g e c a ` ^ \ Z X W U S Q O N L J H G E C A @ > < : 9 7 5 3 2 0 . , + ) ' % $ "                  *7ESapraP>"+$&)++++++++++)& # # ' *-1223 3 44555667"7$7'8)8,9.9093:5:7::;<;>;@sO>pQ>nS?lU?jW?gY@e[@c]@a_A^`A\bAZdAXfBVhBTjBRkCPmCNoCLqCJrDHtDFvDDwDByE@{E>|E<~E:F8F7F5F3G1G/G.G,H*H)H'H%H#I"I IIJJJJJKKKK @ ? =;:86431/-+* ("&#$%"' )*,.013579 : <>@BDCCC B B BBAAAA@@ @#?%?(?*>->/>2>5=7=:==b^.r__`QC-5<(JX fggfff f ffffff~f|fzfxfv"ft$fr&fp(fn*fl,fi.fg1fe3fc5ea7e_9e];e[>eX@eVBeTDeRFePHeNKeLMeJOeGQeESeCUeAXe?Ze=\e;^e8`e6ce4ee2ge0id.kd+nd)pd'rd%td#vd!yd{d}ddddddd d d ddddb_][ Y WTRPMKIGD B"@%>';)9+7.502204.     !#%')+-/13568:<>@BDFHJLMOQSUWY[]_abdfhjlnp~q|szuywwyu{s}qpnljhgeca`^\ZXWUSQONLJHGEC A @ > < : 9 7 5 3 2 0 . , + ) ' % $ "                 (6CQ_nr}aP!>$+&)+**********(% " # '*-1122 33344556 6"6%7'7*8,8/81939698:::<:?;A;C;E<}GnT>lV>jX?gY?e[?c]@a_@^a@\c@ZeAXgAVhATjBRlBPnBNoBLqCJsCHuCFvDDxDBzD@{D>}E<~E:E8E7F5F3F1F/G.G,G*G)G'H%H#H"H IIIIIJJJJJK @ > <;976420.-+) '"%##%!' )*,./13579 : <>@BCCBB B BAAA@@@@?!?#?&>(>+>->0=3=5=8<;<=<@;C;F;}H:{K:xN:vQ9sT9qW8nZ8k]8i`7fc7cf7ai6^m6[p5Xs5Uw5Rz4O}4L3I3F3C2@2=1:1703000-/)/&.#.--,,+ + **)('&&%$#""!     UVW"Xr3YaCZPS[@b\/r]^_QC,5;(IW eeeeee e eeeeeee}e{eyew"eu$es&eq(eo*em,ej.eh1ef3dd5db7d`9d^;d\>dZ@dWBdUDdSFdQHdOKdMMdKOdIQdFSdDUdBXd@Zd>\d<^d9`d7cd5ec3gc1ic/kc-nc*pc(rc&tc$vc"yc {c}cccccccc c ccbbb_][ Y W TRPMKIGDB!@$>&;(9*7,5/2103.   !#%')+-/13579:<>@BDFHJLNPQSUWY[]_abdfhjln~p|rzsyuwwuys{q}pnljhgeca`^\ZXWUSQONLJHGECA@><:975320.,+)'%$"            &4AO^lr{a!P#>&+(+-))))))))))($ ! # '*-011 1 22334445!5#6&6(6+7-7/828486999;9=:?:A:D;F;}H;zJjX>gZ>e\?c^?a`?^b@\d@Ze@Xg@ViATkARmAPnBNpBLrBJsBHuCFwCDyCBzC@|D>}D<D:E8E7E5E3E1F/F.F,F*G)G'G%G#H"H HHHIIIIJJJJ ? > <:975320.,*( '"%##%!')*,./1357 9 : <>@BBBBB A AA@@@@???!>$>&>)>+=.=1=3<6<8<;;>;A;C:F:}I:{L9xO9vR9sU8qX8n[7k^7ia7fd6cg6aj6^m5[q5Xt4Uw4R{4O~3L3I2F2C1@1=1:0703/0/-.).&-#-,,++* * ))('&&%$#""!      TUV"Ws3XbCYQSZAb[0r\ ]^ QC+5:(HV dddddd d ddddddd~d|dzdx"dv$dt&dr(dp*dn,dl.ci1cg3ce5cc7ca9c_;c]>c[@cXBcVDcTFcRHcPKcNMcLOcJQcGScEUcCXcAZc?\c=^c;`b8cb6eb4gb2ib0kb.nb+pb)rb'tb%vb#yb!{b}bbbbbbbb b a aaaa_][Y W TRPMKIGDB @">%;'9)7+5.2002.   !#%')+-/13579;<>@BDFHJLNPRSUWY[]_acdfhjl~n|pzrytwuuwsyq{p}nljhgeca`^\ZXWUSQONLJHGECA@><:975320.,+)'%$"      %2?M\jr!ya#P%>(+*-/))))))))))'#  # '*-/00 1 12223344!5$5&5)6+6.70727587898<9>9@9B:D:F;}I;zK;xMe]>c_>a`?^b?\d?Zf@Xh@Vj@Tk@RmAPoANqALrBJtBHvBFwBDyCB{C@|C>~C@BBBAA A @@@@???>>">$>'=)=,=/<1<4<6;9;<;>:A:D:G9}J9{M9xO8vR8sU8qX7n[7k^6ia6fe6ch5ak5^n4[q4Xu4Ux3R{3O2L2I2F1C1@0=0:/7/3.0.-.)-&-#,,++** ) )('&&%$#""!       STU"Vu3WcCXSSYBbZ2r["\] QC*58(GU cccccc c cccccccc}c{cy"cw$cu&cs(cq*co,bm.bk1bh3bf5bd7bb9b`;b^>b\@bZBbWDbUFbSHbQKbOMbMObKQbISbFUbDXbBZb@\a>^a<`a:ca7ea5ga3ia1ka/na-pa*ra(ta&va$ya"{a }aaaaaaaa` ` ````_][Y W T RPMKIGDB@!>$;&9(7*5,2/01.      "#%')+-/13579;=>@BDFHJLNPRTUWY[]_acefhj~l|nzpyrwtuuswqyp{n}ljhgeca`^\ZXWUSQONLJHGECA@><:975320.,+)'%$"     #0>LZ hr#wa%P'>*+,/1((((((((((&#   # '*-/// 0 0112233 3"4%4'5)5,5.616375787:8<8>8A9C9E:G:}I:zK;xM;uO;sQaa>^c>\e?Zg?Xh?Vj@Tl@Rn@Pp@NqALsAJuAHvBFxBDzBB{B@}C>C = ;986421/-+)' &"$#"% ')*,./1357 8 :<>@AAAA @ @ @@???>>> >"=%='=*<-a]@a[BaYDaVFaTHaRKaPMaNOaLQaJSaGUaEXaCZ`A\`?^`=``;c`8e`6g`4i`2k`0n`.p`+r`)t`'v`%y`#{`!}``````___ _ _ ____][YW T RPMKIGDB@ >";%9'7)5+2.00.       "$&')+-/13579;=?ABDFHJLNPRTVWY[]_acegh~j|lznypwrutsvqwpyn{l}jhgeca`^\ZXWUSQONLJHGECA@><:975320.,+)'%$"    !.<J X"fr%ua'P)>,+.13''''''''''%"   #'*-../ /0011122 3#3%4(4*4-5/516466687;7=7?8A8C8F9H9}J:zL:xN:uP;sR;pT;nV\e>Zg>Xi?Vk?Tm?Rn@Pp@Nr@Lt@JuAHwAFyADzAB|B@}B>B < :975420.,+)' %"##!%')*,./135 7 8 :<>@AA@@ @ @???>>>==!=#=&<(<+<-;0;2;5:8:::=9@9B9E8H8}K8{N7xQ7vT7sW6qZ6n]5l`5ic5ff4ci4al3^o3[s3Xv2Uy2R}1O1M1J0F0C/@/=.:.7-4-0,-,*,&+#+**)(( ' '&&%$#""!       PQR"Tw3UfCVUSWDbX4rY$Z[ QC(56(ES aaaaaa a aaaaaaaaa}a{"ay$aw&`u(`s*`q,`o.`m1`k3`h5`f7`d9`b;``>`^@`\B`ZD`WF`UH`SK`QM`OO`MQ`KS`IU_FX_DZ_B\_@^_>`_!;$9&7(5*2-0/.        "$&(*+-/13579;=?ACDFHJLNPRTVWY[]_aceg~i|jzlynwpurstqvpxnyl{j}hgeca`^\ZXWUSQONLJHGECA@><:975320.,+)'%$"    ,: H"V$dr'sa)P+>.+035&&&&&&&&&&$!   #'*--. . .//00112!2#2&3(3+4-40425457696;6>7@7B7D8F8H9}K9zM9xO:uQ:sS:pU;nW;lY;j[Xj>Vk>Tm?Ro?Pq?Nr@Lt@Jv@Hw@FyAD{AB|A@~A>B@@@@@ ? ??>>>====!<$<&<);+;.;0:3:6:89;9>9@8C8F8I7}L7{N7xQ6vT6sW5qZ5n]5l`4ic4ff4cj3am3^p2[s2Xw2Uz1R}1P0M0J/G/C/@.=.:-7-4,0,-+*+&*#*))((' ' &&%$#""!        OPQ"Rx3TgCUVSVEbW5rX%YZ QC'55(DR `````` ` ``````````|"_z$_x&_v(_t*_r,_p._n1_l3_i5_g7_e9_c;_a>__@_]B_[D_YF_VH_TK_RM_PO_NQ^LS^JU^GX^EZ^C\^A^^?`^=c^;e^8g^6i^4k^2n^0p^.r^+t^)v^'y^%{^#}^!^]]]]]]]] ] ] ]]]][YWT R PMKIGDB@> ;#9%7'5)2+0..          "$&(*,./13579;=?ACEFHJLNPRTVXY[]_ace~g|izjylwnupsrqtpvnxlyj{h}geca`^\ZXWUSQONLJHGECA@><:975320.,+)'%$"    * 8"F$T&cr(qa+P->0+257%%%%%%%%%%#    #'*,,- - ..//0001"1$2'2)3,3.304345575:5<6>6@6C7E7G8I8}K8zM9xO9uQ9sS:pU:nW:lY;j[;g];e_Tn>Rp>Pq?Ns?Lu?Jv@Hx@Fz@D{@B}A@A>A@@??? ? >>>====<<"<$;';);,:.:1:496999;8>8A8D7F7I7~L6{O6yR6vU5sX5q[4n^4la4id3fg3cj2am2^q2[t1Xw1U{0S~0P0M/J/G.C.@-=-:,7,4+0+-***&)#)((''& & %%$#""!         NOP"Qy3RhCSWSTGbV6rW&XYQC&54(CQ ______ _ _________^~"^{$^y&^w(^u*^s,^q.^o1^m3^k5^h7^f9^d;^b>^`@^^B^\D^ZF^WH^UK^SM^QO]OQ]MS]KU]IX]FZ]D\]B^]@`]>c];!9$7&5(2*0-."                 "$&(*,.013579;=?ACEGHJLNPRTVXZ[]_ac~e|gziykwlunspqrptnvlxjzh{g}eca`^\ZXWUSQONLJHGECA@><:975320.,+)'%$"     )!6$D&R(ar*oa-P/>2+479$$$$$$$$$$#    #'*+,, , --..//0 0"1%1'1*2,2/313336484:5=5?5A6C6E7H7J7}L8zN8xP8uR9sT9pV9nX:lZ:j\:g^;e`;cb;ad<^e<\gPr>Nt>Lu?Jw?Hy?Fz?D|@B~@@@>A???? > > >====<<< ;";%;':*:,:/929497898<8?7B7D7G6J6~M6{P5yS5vV5sX4q[4n_3lb3ie3fh2dk2an1^q1[u1Xx0U{0S/P/M.J.G.D-@-=,:,7+4+0*-**)&)#((''&& % $$#""!          MNO"P{3QiCRXSSHbT7rU'VWQC$53(AP ^^^^^^ ^ ^^^^^^^^]]"]|$]z&]x(]v*]t,]r.]p1]n3]l5]j7]g9]e;]c>]a@]_B]]D][F]YH]VK\TM\RO\PQ\NS\LU\JX\GZ\E\\C^\A`\?c\=e\;g\8i\6k\4n\2p\0r\.t\+v\)y\'{[%}[#[![[[[[[[[[ [ [ [[[[YWTR P MKIGDB@>; 9#7%5'2)0+.$"       """"" " " ""!!!!!!!! !"!$!&!(!* , . 0 2 4 5 7 9 ; = ? A CEGIJLNPRTVXZ\]_a~c|ezgyiwkumsnqpprntlvjxhzg|e}ca`^\ZXWUSQONLJHGECA@><:975320.,+)'%$"      !'#4%B(P*_r,ma/}P1>4+69<$$$$$$$$$$"   #'**++ ,,--..//!/#0&0(1+1-2/222436394;4=4@5B5D5F6H6J7}L7zO7xQ8uS8sU8pW9nY9l[9j]:g^:e`:cb;ad;^f;\hLv>Jx>Hy?F{?D}?B~?@@>@<@:A8A7A5A3B1B/B.B,C*C)C'C%D#D"D DEEEEFFFFFG < : 875320.,*)'% #"!#%'(*,./13 5 7 8:<>??>> > ====<<<;;!;#:%:(:*:-909295878:7=7?7B6E6H6K5~M5{P5yS4vV4sY3q\3n_3lb2ie2fh2dl1ao1^r0[u0Xy/U|/S/P.M.J-G-D,@,=+:+7*4*0)-)*(&(#''&&%% $ $#""!           KMN"O|3PkCQZSRIbS9rT(UV QC#52(@O ]]]]]] ] ]]]]]]\\\\"\~$\{&\y(\w*\u,\s.\q1\o3\m5\k7\h9\f;\d>\b@\`B\^D\\F\ZH[WK[UM[SO[QQ[OS[MU[KX[IZ[F\[D^[B`[@c[>e[;9!7$5&2(0*.%#!      "$$$$$ $ # ########## #"#$"&"("*","."0"2"4"6"7"9";!=!?!A!C!E!G!I!K!L!N!P!R!T V X Z \ ^ _~ a| cz ey gw iu ks mqnppnrltjvhxgze|c}a`^\ZXWUSQONLJHGECA@><:975320.,+)'%$"      !#%%2'@*N,]r.la1{P3>6+8;>##########!   #')** + ++,,--..!/$/&0)0+0.10122527293<3>4@4B4E5G5I6K6}M6zO7xQ7uS7sU8pW8nY8l[9j]9g_9ea:cc:ae:^g;\h;Zj;XlHz>F{>D}?B?@?>?<@:@8@7A5A3A1A/B.B,B*B)C'C%C#C"D DDDEEEEEFFF ; : 86531/-,*(&$ ""!#%'(*,./13 5 7 8:<>>>>= = ==<<<;;;:!:$:&:)9+9.908385887;7=7@6C6F5H5K5~N4{Q4yT4vW3tZ3q]2n`2lc2if1fi1dl0ao0^s0[v/Xy/V}.S.P-M-J-G,D,@+=+:*7*4)0)-(*(&'#'&&%%$ # #""!            JKM"N}3OlCP[SQJbR:rS*TU QC"51(?N [\\\\\ \ \\\\\[[[[["[$[}&[z([x*[v,[t.[r1[p3[n5[l7[j9[g;[e>[c@[aB[_DZ]FZ[HZYKZVMZTOZRQZPSZNUZLXZJZZG\ZE^ZC`ZAcZ?eZ=gZ;iZ8kZ6nZ4pZ2rY0tY.vY+yY){Y'}Y%Y#Y!YYYYYYYYY Y Y YYXXWTRP M KIGDB@>;9 7#5%2'0).'%#!       "$&&&%% % % %%%%%%%%$$ $"$$$&$($*$,$.$0$2$4$6#8#9#;#=#?#A#C#E#G#I#K#M"N"P"R"T"V"X"Z"\"^~"`|"az"cy"ew!gu!is!kq!mp!on!pl!rj!th!vg!xe!zc!|a!~` ^ \ Z X W U S Q O N L J HGECA@><:975320.,+)'%$"     #%#'1)>+L.[r0ja3yP5>8+:=@""""""""""     #'()) * *++,,--.".%.'/*/,0.011315182:2<3?3A3C4E4G5J5L5}N6zP6xR6uT7sV7pX7nZ8l\8j^8g`9eb9cc9ae:^g:\i:Zk;Xm;Vn;TpD~>B>@?>?>=== = <<<;;;;::":$9'9)9,8.818376797;6>6A6C5F5I4L4~O4{R3yT3vW3tZ2q]2n`1ld1ig1fj0dm0ap/^s/[w.Xz.V}.S-P-M,J,G+D+A*=*:)7)4(0(-'*'&&#&%%$$# # "!!             IJK"L~3NmCO\SPKbQ;rR+ST QC!50(>L Z[[[[[ [ [[[[ZZZZZZ"Z$Z~&Z{(Zy*Zw,Zu.Zs1Zq3Zo5Zm7Zk9Zh;Zf>Zd@ZbBY`DY^FY\HYZKYXMYUOYSQYQSYOUYMXYKZYI\YF^YD`YBcY@eY>gY;97!5$2&0(.)'%#!       "$&''''' ' ' '''''&&&&&!&"&$&&&(&*&,&.&0%2%4%6%8%:%<%=%?%A%C%E%G$I$K$M$O$P$R$T$V$X$Z$\~$^|$`z#by#cw#eu#gs#iq#kp#mn#ol#qj#rh#tg#ve"xc"za"|`"~^"\"Z"X"W"U"S"Q"O"N!L!J!H!G!E!C!A!@!>!:+<?B!!!!!!!!!!    #''(( ) )**++,, -#-%.(.*/-///10406191;2=2?2B3D3F3H4J4L5}N5zP5xS6uU6sW6pY7n[7l\7j^8g`8eb9cd9af9^h9\j:Zk:Xm:Vo;Tq;Rr;Pt@>>>Xe@XcBXaDX_FX]HX[KXYMXVOXTQXRSXPUXNXXLZXJ\XG^XE`XCcXAeX?gX=iX;kW8nW6pW4rW2tW0vW.yW+{W)}W'W%W#W!WWWWWWWWV V V VVVVTRPM K IGDB@>;97 5#2%0'.+)'%#!      "$&'))))) ) ) ))((((((((!(#(%(&(('*','.'0'2'4'6'8':'<'>'?'A&C&E&G&I&K&M&O&Q&R&T&V&X%Z~%\|%^z%`y%bw%cu%es%gq%ip%kn%ml%oj$qh$rg$te$vc$xa$z`$|^$~\$Z$X$W$U$S#Q#O#N#L#J#H#G#E#C#A#@#>#<":"9"7"5"3"2"0".","+")"'"%!$!"! !!!!!!!!!!      &(+--;/I2Wr4fa6uP9><+>AD             #&'' ( ())**++,!,#-&-(-+.-.0/2/507090;1>1@2B2D2G3I3K4M4}O4zQ5xS5uU5sW6pY6n[7l]7j_7ga8ec8ce8ag9^h9\j9Zl:Xn:Vp:Tq:Rs;Pu;Nw;Lx><>:>8?7?5?3?1@/@.@,@*A)A'A%A#B"B BBCCCCDDDDE : 8 75310.,*('%# !"#%'(*,./1 3 5 78:<==<< < ;;;;:::99 9#8%8(8*7-7/7265676:5<5?5B4E4G3J3M3~P2{S2yV2vY1t\1q_0nb0le0ih/fk/dn.aq.^u-[x-X{-V,S,P+M+J*G*D)A)=(:(7'4'1&-&*%&%#$ $##"" !              FHI"J3KoCL^SNNbO=rP-QR QC5.(<J XYYYYY Y YXXXXXXXXX"X$X&X~(X|*Xy,Xw.Xu1Xs3Xq5Xo7Xm9Xk;Wi>Wf@WdBWbDW`FW^HW\KWZMWXOWUQWSSWQUWOXWMZWK\WI^WF`WDcWBeW@gV>iV;975"2$0&.-+)'%# !    "$&')+++++ + * **********!*#)%)')))*),).)0)2)4)6)8):(<(>(@(A(C(E(G(I(K(M(O(Q'S'T'V'X~'Z|'\z'^y'`w'bu'ds'eq'gp'in&kl&mj&oh&qg&se&tc&va&x`&z^&|\&~Z&X%W%U%S%Q%O%N%L%J%H%G%E%C%A$@$>$<$:$9$7$5$3$2$0$.$,$+#)#'#%#$#"# #######"""" " " """""" (*,+/91G3Ur6da8sP;>>+@CF   #%&& ' '(())**+"+$,',)-,-..0.3.5/8/:0<0>1A1C1E2G2I3L3N3}P4zR4xT4uV5sX5pZ6n\6l^6j`7gb7ec7ce8ag8^i8\k9Zm9Xn9Vp:Tr:Rt:Pu;Nw;Ly;Jz;H|=<=:>8>7>5?3?1?/?.@,@*@)@'A%A#A"A BBBBCCCCDDD 9 8 6431/-+*(&$" "#%'(*,./1 3 5 78:<<<<; ; ;;:::9998!8#8&7(7+7-606365585:5=4@4B4E3H3K2N2~Q2{S1yV1vY1t\0q_0nb/le/ii.fl.do.ar-^u-[y,Y|,V+S+P+M*J*G)D)A(=(:'7'4&1&-%*%&$#$ #""!!             EGH"I3JpCK_SLObN>rO.PQQC5-(;I WXXXXX X WWWWWWWWWW"W$W&W(W}*Wz,Wx.Wv1Wt3Wr5Wp7Vn9Vl;Vj>Vg@VeBVcDVaFV_HV]KV[MVYOVVQVTSVRUVPXVNZVL\VJ^VG`VEcVCeUAgU?iU=kU;nU8pU6rU4tU2vU0yU.{U+}U)U'U%U#U!UUUUTTTTT T T TTTTRPMK I GDB@>;975 2#0%./-+)'% # !  " $&')+---,, , ,,,,,,,,,++!+#+%+'+)+++,+.+0+2+4*6*8*:*<*>*@*B*C*E*G*I*K)M)O)Q)S)U)V~)X|)Zz)\y)^w)`u)bs(dq(fp(gn(il(kj(mh(og(qe(sc(ua(v`(x^(z\'|Z'~X'W'U'S'Q'O'N'L'J'H'G&E&C&A&@&>&<&:&9&7&5&3&2&0%.%,%+%)%'%%%$%"% %%%%$$$$$$$ $ $ $$$###" *,.)173E5Sr8ba:qP=>@+BEH    #%%& & ''(())* *"+%+',*,,,/-1-4.6.8/;/=/?0A0D1F1H2J2L2N3}P3zR3xT4uV4sX5pZ5n\5l^6j`6gb6ed7cf7ah7^j8\k8Zm8Xo9Vq9Ts9Rt:Pv:Nx:Ly;J{;H};F~;D=<=:=8=7>5>3>1?/?.?,?*@)@'@%@#A"A AABBBBCCCCD 9 7 6420/-+)'%$" "#%'(*,./1 3 578:<<;;; ; :::999888"7$7&7)6+6.615356584;4>4@3C3F3I2K2N1~Q1{T1yW0vZ0t]/q`/nc/lf.ii.fl-dp-as-^v,[y,Y}+V+S*P*M)J)G(D(A'>':&7&4%1%-$*$'### ""!!              DEG"H3IrCJaSKPbL?rM/OPQC5,(:H VWWWWV V VVVVVVVVVV"V$V&V(V~*V|,Vy.Vw1Vu3Vs5Uq7Uo9Um;Uk>Ui@UfBUdDUbFU`HU^KU\MUZOUXQUUSUSUUQXUOZUM\UK^UI`TFcTDeTBgT@iT>kT;9752"0$.1/-+)' % # ! " $ &')+-..... . ......-----!-#-%-'-)-+---/,0,2,4,6,8,:,<,>,@,B,D,E+G+I+K+M+O+Q+S+U~+W|+Xz+Zy+\w*^u*`s*bq*dp*fn*hl*ij*kh*mg*oe*qc*sa)u`)v^)x\)zZ)|X)~W)U)S)Q)O)N)L(J(H(G(E(C(A(@(>(<(:(9(7(5'3'2'0'.','+')'''%'$'"' &&&&&&&&&&& & & %%%%%%$ , .0'255C7Qr:`aB+DGJ    #$$% %&&''(() )#*&*(+++-,/,2-4-7.9.;.>/@/B0D0F0I1K1M2O2}Q2zS3xU3uW4sY4p[4n]5l_5ja5gc6ee6cg6ah7^j7\l7Zn8Xp8Vq8Ts9Ru9Pw9Nx:Lz:J|:H};F;D;B;@<><<<:=8=7=5=3>1>/>.?,?*?)?'@%@#@"@ AAAABBBBCCC 8 7 5320.,*)'%#! "#%'(*,./1 3 578:<;;; : : :9998888 7"7%7'6*6,6/515446494<3>3A3D2F2I2L1O1~R0{U0yX0v[/t^/qa.nd.lg.ij-fm-dp,as,^w+[z+Y}*V*S*P)M)J(G(D'A'>&:&7%4%1$-$*#'##" !!               CDE"G3HsCIbSJQbKArL0M OP C5*(9G UVVVUU U UUUUUUUUUU"U$U&U(U*U},Uz.Ux1Uv3Tt5Tr7Tp9Tn;Tl>Tj@TgBTeDTcFTaHT_KT]MT[OTYQTVSTTUTRXTPZTN\TL^SJ`SGcSEeSCgSAiS?kS=nS;pS8rS6tS4vS2yS0{S.}S+S)S'S%S#R!RRRRRRRRR R R RRRRPMKI G DB@>;9752 0#.20.,*( & $ "  " $ & ')+-/00000 0 000////////!/#/%/'.).+.-./.1.2.4.6.8.:.<.>-@-B-D-F-G-I-K-M-O-Q-S~-U|,Wz,Yy,Zw,\u,^s,`q,bp,dn,fl,hj,ih,kg+me+oc+qa+s`+u^+w\+xZ+zX+|W+~U+S+Q+O*N*L*J*H*G*E*C*A*@*>*<*:)9)7)5)3)2)0).),)+)))')%($("( ((((((((((' ' ' ''''''& , 02%437A9Or<^a>mPA|>D+FIL   ##$ $ %%&&''((!)$)&*)*++.+0,3,5,7-:-<.>.@/C/E/G0I0K1M1P1}R2zT2xV3uX3sZ3p\4n^4l`4jb5gc5ee5cg6ai6^k6\m7Zn7Xp7Vr8Tt8Ru8Pw9Ny9L{9J|:H~:F:D;B;@;>;<<:<8<7=5=3=1=/>.>,>*?)?'?%?#@"@ @@AAAABBBBC 8 6 531/.,*(&$#! "#%'(*,./ 1 3 578:;;:: : 999988877 7#6%6(6*5-5/5244474:3<3?2B2D2G1J1M1P0~R0{U/yX/v[/t^.qa.od-lg-ik,gn,dq,at+^w+[{*Y~*V)S)P(M(J'G'D&A&>%:%7$4$1#-#*"'"#! !               BCD"E3GtCHcSIRbJBrK1L"MN C5)(8F TUUTTT T TTTTTTTTTT"T$T&T(T*T~,T|.Sy1Sw3Su5Ss7Sq9So;Sm>Sk@SiBSfDSdFSbHS`KS^MS\OSZQSXSSUUSSXSQZRO\RM^RK`RIcRFeRDgRBiR@kR>nR;97520".420.,* ( & $"  "$ & ' )+-/122222 1 11111111111!0#0%0'0)0+0-0/0103040608/://@/B/D/F/H/I/K/M/O.Q~.S|.Uz.Wy.Yw.[u.\s.^q.`p.bn.dl.fj-hh-jg-ke-mc-oa-q`-s^-u\-wZ-yX-zW-|U,~S,Q,O,N,L,J,H,G,E,C,A,@+>+<+:+9+7+5+3+2+0+.+,+++)*'*%*$*"* *******)))) ) ) ))))))', 24$619?;Mr>\a@kPCz>F+HKN   ""# # $$%%&''("($(')*),*.*1+3+6,8,:-=-?-A.C.F/H/J0L0N0P1}R1zT1xV2uX2sZ3p\3n^3l`4jb4gd4ef5ch5aj5^k6\m6Zo7Xq7Vs7Tt8Rv8Px8Ny8L{9J}9H~9F:D:B:@;>;<;:<8<7<5<3=1=/=.=,>*>)>'?%?#?"? @@@@AAAABBB 7 6 421/-+)(&$" "#%'(*,./ 1 3578::::9 9 998887776!6#6&5(5+5-404245383:3=2?2B1E1H1K0M0P/~S/{V/yY.v\.t_-qb-oe-lh,ik,gn+dr+au*^x*[{*Y)V)S(P(M'J'G&D&A%>%:$7$4#1#-"*"'!#              @BC"D3EuCGdSHSbICrJ3K#LM C5((7E STSSSS S SSSSSSSSSS"S$S&S(S*S,R}.R{1Rx3Rv5Rt7Rr9Rp;Rn>Rl@RjBRhDReFRcHRaKR_MR]OR[QRYSRVURTXQRZQP\QN^QL`QJcQHeQEgQCiQAkQ?nQ=pQ;rQ8tQ6vQ4yQ2{Q0}Q.Q+P)P'P%P#P!PPPPPPPPP P P PPPOMKIG D B@>;97520 .6420., * ( &$"  "$& ' )+-/1344333 3 33333333222!2#2%2'2)2+2-2/21231517181:1<1>1@1B1D1F1H0J0K0M0O~0Q|0Sz0Uy0Ww0Yu0[s0\q0^p/`n/bl/dj/fh/hg/je/lc/ma/o`/q^/s\/uZ.wX.yW.zU.|S.~Q.O.N.L.J.H.G.E-C-A-@->-<-:-9-7-5-3-2-0-.,,,+,),',%,$,", ,,,,+++++++ + + +++***),36"8/;==Kr@ZaBiPEx>H+JMP    !"" # #$$%%&& '#'%(((*)-)/*2*4+6+9+;,=,@-B-D.F.H.K/M/O0Q0}S0zU1xW1uY2s[2p]2n_3la3jc3ge4eg4ch5aj5^l5\n6Zp6Xq6Vs7Tu7Rw7Px8Nz8L|8J}9H9F9D9B:@:>:<;:;8;7<5<3<1'>%>#?"? ??@@@@AAAAB 7 5 420.-+)'%#" "#%'(*,./ 1 3568:::99 9 888777666!5$5&5)4+4.403335382;2=2@1C1F0H0K0N/Q/~T.{W.yZ.v]-t`-qc,of,li,il+go+dr*au*^y)\|)Y(V(S'P'M&J&G%D%A$>$:#7#4"1"-!*!' #             ?@B"C3DvCEeSGTbHDrI4J$KL C5'(6D RRRRRR R RRRRRRRRRR"R$R&R(R*Q,Q~.Q|1Qy3Qw5Qu7Qs9Qq;Qo>Qm@QkBQiDQfFQdHQbKQ`MQ^OQ\QQZSPXUPUXPSZPQ\PO^PM`PKcPIePFgPDiPBkP@nP>pP;97520.86420. , * (&$"  "$&' ) +-/13555555 5 5555544444 4!4#4%4'4)4+3-3/31333537393:3<3>3@3B2D2F2H2J2L2M~2O|2Qz2Sy2Uw2Wu2Ys1[q1]p1^n1`l1bj1dh1fg1he1jc1la1m`1o^0q\0sZ0uX0wW0yU0{S0|Q0~O0N0L0J0H/G/E/C/A/@/>/J+LOR     !! ""##$%%&!&#'&'((+(-(0)2)5*7*9+<+>,@,B-E-G-I.K.M/O/R/}T0zV0xX1uZ1s\1p^2n`2la2jc3ge3eg4ci4ak4^m5\n5Zp5Xr6Vt6Tv6Rw7Py7N{7L|8J~8H8F9D9B9@9>:<:::8;7;5;3<1#>"> ????@@@@AAA 6 5 310.,*('%#! "#%'(*,./ 1 3568:999 8 8 87776665 5"5$4'4)4,3.313326292;1>1A1C0F0I/L/O/Q.~T.{W-yZ-v]-t`,qc,of+li+il*gp*ds*av)^y)\}(Y(V'S'P&M&J%G%D$A$>#;#7"4"1!-!* '#           >?A"B3CwCDfSEVbGErH5I%JKC5&(5C QQQQQQ Q QQQQQQQQQQ"Q$Q&P(P*P,P.P}1P{3Px5Pv7Pt9Pr;Pp>Pn@PlBPjDPhFPeHPcKPaMP_OP]QO[SOYUOVXOTZOR\OP^ON`OLcOJeOHgOEiOCkOAnO?pO=rO;tO8vO6yO4{N2}N0N.N+N)N'N%N#N!NNNNNNNNN N M MMMMKIGD B @>;97520.:86420 . , *(&$"  "$&') + -/135677777 7 7766666666 6"6$6%5'5)5+5-5/51535557595;5<4>4@4B4D4F4H4J4L~4N|4Oz4Qy3Sw3Uu3Ws3Yq3[p3]n3_l3`j3bh3dg3fe3hc2ja2l`2n^2o\2qZ2sX2uW2wU2yS2{Q2|O2~N1L1J1H1G1E1C1A1@1>1<1:1907050302000.0,0+0)0'0%0$/"/ //////////. . . ......-!,79<,>9AHrCVaFePIt>L+NQT    ! !""##$$%"%$&'&)','.(1(3)5)8*:*<+?+A+C,E,H-J-L.N.P.R/}T/zV0xX0uZ0s\1p^1n`1lb2jd2gf3eh3cj3ak4^m4\o4Zq5Xs5Vt5Tv6Rx6Pz6N{7L}7J7H8F8D8B9@9>9<:::8:7:5;3;1;/<.<,<*<)='=%=#="> >>????@@@@A 6 4 31/-,*(&$"! "#%'(*,. / 1 35689988 8 777766655 5#4%4'4*3,3/222427191<1?0A0D0G/J/L.O.R.~U-{X-y[,v^,ta+qd+og+lj*im*gp)ds)aw(^z(\}'Y'V&S&P&M%J%G$D$A#>";"7!4!1 . *'#         =>?"A3ByCChSDWbEFrG6H&IJC5%(4B PPPPPP P PPPPPPPPPP"P$O&O(O*O,O.O~1O|3Oz5Ow7Ou9Os;Oq>Oo@OmBOkDOiFOfHOdKObMN`ON^QN\SNZUNXXNUZNS\NQ^NO`NMcNKeNIgNFiNDkNBnN@pN>rN;97520.<:8642 0 . ,*(&$"  "$&')+ - /135689999 9 8 8888888888 7"7$7&7(7)7+7-7/71737567696;6=6>6@6B6D6F6H6J~6L|5Nz5Py5Qw5Su5Us5Wq5Yp5[n5]l5_j5ah5bg4de4fc4ha4j`4l^4n\4pZ4qX4sW4uU4wS3yQ3{O3}N3~L3J3H3G3E3C3A3@3>2<2:2927252322202.2,2+2)1'1%1$1"1 11111110000 0 0 000000." ,9;>*@8CFrETaHcPKr>N+PSV    !!"##$ $"%%%'&*&,'/'1(4(6(8);)=*?*B+D+F,H,J,M-O-Q.S.}U/zW/xY/u[0s]0p_0na1lc1je2gg2eh2cj3al3^n3\p4Zq4Xs4Vu5Tw5Rx5Pz6N|6L}6J7H7F7D8B8@8>9<9:98:7:5:3:1;/;.;,<*<)<'<%=#="= =>>>????@@@ 6 4 20/-+)'&$"  "#%'(*,. / 135688888 7 776665554!4#4&3(3+3-202215171:0=0?0B/E/G.J.M.P-S-~V,{X,y[,v^+ta+qd*oh*lk)in)gq)dt(aw(^{'\~'Y&V&S%P%M$J$G#D#A">";!7!4 1 .*'#       <=>"?3AzCBiSCXbDGrF7G'HIC5$(2A OOOOOO O OOOOOOOOOO"N$N&N(N*N,N.N1N}3N{5Nx7Nv9Nt;Nr>Np@NnBNlDNjFNhHNeKMcMMaOM_QM]SM[UMYXMWZMT\MR^MP`MNcMLeMJgMHiMEkMCnMApM?rM=tL;vL8yL6{L4}L2L0L.L+L)L'L%L#L!LLLLLLKKK K K KKKKIGDB @ >;97520.=;9753 1 / -+)'&$"  "$&')+- / 13568:;;:: : : :::::::999 9"9$9&9(9*9+9-9/81838587898;8=8?8@8B8D8F7H~7J|7Lz7Ny7Pw7Ru7Ss7Uq7Wp7Yn7[l6]j6_h6ag6be6dc6fa6h`6j^6l\6nZ6pX6qW5sU5uS5wQ5yO5{N5}L5~J5H5G5E5C5A4@4>4<4:4947454342404.3,3+3)3'3%3$3"3 33332222222 2 2 2221110$ ,; =@(B6EDrGRaJaPMp>P+RUX      !!""# ##$&$(%+%-&0&2'4'7(9(;)>)@*B*E*G+I+K,M,O-Q-S-}V.zX.xZ/u\/s^/p`0na0lc1je1gg1ei2ck2am2^n3\p3Zr4Xt4Vv4Tw5Ry5P{5N|6L~6J6H7F7D7B7@8>8<8:989795:3:1:/:.;,;*;)<'<%<#<"= ==>>>>????@ 5 3 20.,+)'%#!  "#%'(*,. / 135688877 7 666555444!3$3&3)2+2.201315180:0=/@/C/E.H.K-N-P-S,~V,|Y+y\+v_+tb*qe*oh)lk)in(gr(du'ax'^{'\&Y&V%S%P$M$J#G#D"A">!; 7 41.*'#     :<=">3@{CAjSBYbCIrD8F(GH C5#(1@ NNNNNN N NNNNNNNNNM"M$M&M(M*M,M.M1M~3M|5Mz7Mw9Mu;Ms>Mq@MoBMmDMkFMiHLfKLdMLbOL`QL^SL\ULZXLXZLU\LS^LQ`LOcLMeLKgLIiLFkLDnLBpK@rK>tK;97520.?=;975 3 1 /-+)'%#! "$&')+-/ 1 3568:<<<<< < < <<<<;;;;;; ;";$;&;(;*:,:-:/:1:3:5:7:9:;:=:?9A9B9D9F~9H|9Jz9Ly9Nw9Pu9Rs9Tq9Up8Wn8Yl8[j8]h8_g8ae8cc8da8f`8h^8j\7lZ7nX7pW7rU7sS7uQ7wO7yN7{L7}J7H7G6E6C6A6@6>6<6:6967656362505.5,5+5)5'5%5$5"5 54444444444 4 4 3333332& ,; ?A&D4GBrIPaL_POn>R~+TWZ      !""!#$#&$)$+%.%0&3&5'7':(<(>(A)C)E*G*J+L+N,P,R,T-}V-zX.xZ.u\.s^/p`/nb0ld0jf0gh1ej1ck1am2^o2\q3Zs3Xt3Vv4Tx4Rz4P{5N}5L5J6H6F6D7B7@7>8<8:8887959391:/:.:,;*;);';%<#<"< <===>>>>??? 5 3 1/.,*(&%#! "#%'(*, . / 13568777 6 6 65554443 3"3$2'2)2,1.111306080;/>/@.C.F.I-K-N,Q,T,~W+|Z+y]*v`*tc)qf)oi)ll(io(gr'du'ay&^|&\%Y%V$S$P#M#J"G"D!A!> ; 741.*'#   9:<"=3>|C@kSAZbBJrC9D)FG C5"(0? MMMMMM M MMMMMMMLLL"L$L&L(L*L,L.L1L3L}5L{7Lx9Lv;Lt>Lr@LpBLnDKlFKjHKhKKeMKcOKaQK_SK]UK[XKYZKW\KT^KR`KPcKNeKLgKJiKHkKEnJCpJArJ?tJ=vJ;yJ8{J6}J4J2J0J.J+J)J'J%J#J!JIIIIIIII I I IIIIGDB@ > ;97520.A?=;97 5 3 1/-+)'%#! "$&')+-/1 3 568:<>>>>> > > >========= ="=$<&<(<*<,<.<0<1<3<5<7<9;;;=;?;A;C;D~;F|;Hz;Jy;Lw;Nu:Ps:Rq:Tp:Vn:Wl:Yj:[h:]g:_e:ac:ca:e`9f^9h\9jZ9lX9nW9pU9rS9sQ9uO9wN9yL8{J8}H8G8E8C8A8@8>8<8:8987757372707.7,7+7)7'7%7$7"6 66666666665 5 5 5555554(,; AC$F2H@rKNaN]PQl>T|+VY]      !!""$"'#*#,$/$1%3%6&8&:'='?(A(D)F)H*J*L*O+Q+S,U,}W-zY-x[-u].s_.pa/nc/le/jg0gh0ej0cl1an1^p2\r2Zs2Xu3Vw3Tx3Rz4P|4N~4L5J5H5F6D6B6@7>7<7:88878583919/9.:,:*:);';%;#;"< <<<===>>>>? 4 2 1/-+*(&$"  "#%'(*, - / 13567766 6 555544433 3"2%2'1*1,1/010406/9/.A.D-F-I-L,O,R+U+~W+|Z*y]*w`)tc)qf(oi(lm'ip'gs'dv&ay&_}%\%Y$V$S#P#M"J"G!D!A > ;841.*'#   89;"<3=}C>lS@[bAKrB;C+DF C5!(/> LLLLLL L LLLLLLKKKK"K$K&K(K*K,K.K1K3K~5K|7Kz9Kw;Ku>Ks@KqBJoDJmFJkHJiKJgMJdOJbQJ`SJ^UJ\XJZZJX\JU^JS`JQcJOeJMgJKiJIkIFnIDpIBrI@tI>vI ;97520.CA?=;9 7 5 31/-+)'%#! "$&')+-/1 3 5 68:<>@@@@@ ? ? ?????????> >">$>&>(>*>,>.>0>2>3=5=7=9=;===?=A=C~=E|=Fz=Hy:<9:9997959392909.9,9+9)9'8%8$8"8 88888887777 7 7 7777775*,;CE"H0J>rMLaP[PSj>Uz+X[_     !#!%"("*#-#/$2$4%6%9&;&>'@'B(D(G(I)K)M*O*Q+S+U+}W,zZ,x\-u^-s_.pa.nc.le/jg/gi/ek0cm0ao1^p1\r1Zt2Xv2Vw2Ty3R{3P|3N~4L4J4H5F5D5B6@6>6<7:78778583819/9.9,9*:):':%;#;"; ;<<<<===>>> 4 2 0.-+)'%$"  "#%'(*, - /13566666 5 554443332!2#2%1(1*1-0/02/4/7/:.<.?.B-D-G,J,M,O+R+U*~X*|[)y^)wa)td(qg(oj'lm'jp>&dw%az%_}$\$Y#V#S"P"M!J!G D A>;841.*'$     789";3<C=mS?]b@LrAJt@IrBIpDInFIlHIjKIhMIeOIcQIaSI_UI]XI[ZIY\IW^IT`IRcIPeINgHLiHJkHHnHEpHCrHAtH?vH=yH;{H8}H6H4H2H0H.H+H)H'G%G#G!GGGGGGGGG G GGGGGDB@> ; 97520.ECA?=; 9 7 531/-+)'%# !"$&')+-/13 5 6 8:<>@BBAAA A A AAAAAA@@@@ @"@$@&@(@*@,@.?0?2?4?5?7?9?;?=???A~?C|>Ez>Gy>Hw>Ju>Ls>Nq>Pp>Rn>Tl>Vj>Xh=Yg=[e=]c=_a=a`=c^=e\=gZ=hX=jW=lU;<;:;9;7;5;3;2;0;.;,:+:):':%:$:": :::::999999 9 9 9998887+,;DG J.LWx+Z^a  ! # &!(!+"-"0#2$5$7$:%<%>&@&C'E'G(I(L)N)P*R*T*V+}X+zZ,x\,u^,s`-pb-nd.lf.jh.gj/ek/cm0ao0^q0\s1Zt1Xv1Vx2Tz2R{3P}3N3L4J4H4F5D5B5@6>6<6:68777573818/8.9,9*9)9':%:#:"; ;;;<<<<===> 3 1 0.,*)'%#! "#%'(*, - /13566655 5 444333222!1$1&1(0+0-00/2/5.8.:.=-@-B,E,H,J+M+P*S*V*~Y)|\)y_(wb(te'qh'ok'ln&jq>%dw%a{$_~$\#Y#V"S"P!M!J G DA>;841.*'$        578":3;CHu@HsBHqDHoFHmHHkKHiMHgOHdQHbSH`UH^XH\ZHZ\HX^HU`HScHQeGOgGMiGKkGInGFpGDrGBtG@vG>yG<{G:}G7G5G3G1G/G-G*F(F&F$F"FFFFFFFFFF F FFFEDB@> ; 97520.GECA?= ; 9 7531/-+)'% #"!$&')+-/135 6 8 :<>@BCCCCC C C CCCBBBBBBB!B"B$B&B(A*A,A.A0A2A4A6A7A9A;A=@?~@A|@Cz@Ey@Gw@Iu@Js@Lq@Np@Pn@Rl?Tj?Vh?Xg?Ze?[c?]a?_`?a^?c\?eZ?gX>iW>jU>lS>nQ>pO>rN>tL>vJ>wH>yG>{E=}C=A=@=>=<=:=9=7=5=3=2<0<.<,<+<)<'<%<$<"< <<;;;;;;;;; ; ; ::::::9-!,;FIK,N:rQHaTWPWf>Yv+\`c   !$ ' )!,!."1"3#6#8$:$=%?%A&C&F'H'J(L(N(Q)S)U*W*}Y+z[+x]+u_,sa,pc-ne-lg-jh.gj.el/cn/ap/^r0\s0Zu0Xw1Vy1Tz2R|2P~2N3L3J3H4F4D4B5@5>5<6:68677573717/8.8,8*9)9'9%9#:": :;;;;<<<<== 3 1 /-,*(&$#! "#%'(* , - /1356555 4 4 433322211"1$0'0)0,/./1/3.6.8-;-=-@,C,F+H+K+N*Q*T)V)~Y)|\(y_(wb'te'qh&ok&lo%jr%gu$dx$a{$_#\#Y"V"S!P!M JGDA>;841.*'$          467"83:C;pS<_b=Nr?>@.ABC5(,: HIIIII I IIIHHHHHHH"H$H&H(H*H,H.H1H3H5H7H}9G{;Gy>Gv@GtBGrDGpFGnHGlKGjMGhOGeQGcSGaUG_XG]ZG[\GY^GW`FTcFReFPgFNiFLkFJnFHpFErFCtFAvF?yF={F;}F8F6F4F2F0E.E+E)E'E%E#E!EEEEEEEEE E EDDDDB@>; 9 7520.IGDB@> < : 87531/-+)' %"#$!&')+-/1356 8 : <>@BCEEEEE E E DDDDDDDDDD!C#C$C&C(C*C,C.C0C2C4C6B8B9B;B=~B?|BAzBCyBEwBGuBIsBKqALpANnAPlARjAThAVgAXeAZcA\aA]`A_^@a\@cZ@eX@gW@iU@kS@lQ@nO@pN@rL@tJ@vH?xG?yE?{C?}A?@?>?3>2>0>.>,>+>)>'>%>$>"= =========== < < <<<<<<;/#, ;HKM*P8rSGaVUPYd>[t+_be    "%'* ,!/!1"4"6#9#;$=$@%B%D&F&I&K'M'O(Q(S)U)W*}Y*z[*x]+u_+sa,pc,ne,lg-ji-gk.em.co.ap/^r/\t0Zv0Xw0Vy1T{1R}1P~2N2L2J3H3F3D4B4@4>5<5:58676563717/7.7,8*8)8'9%9#9": :::;;;;<<<< 2 0 /-+)(&$"  "#%'(* , - /1355554 4 433322211 0"0%0'/*/,//.1.4.6-9-;,>,A,C+F+I*L*N*Q)T)W(~Z(|]'y`'wc'tf&ri&ol%lo%jr$gv$dy#a|#_"\"Y!V!S P MJGDA>;841.*'$            346"738C:qS;`b??/@AB5(+9 GHHHHH H HHGGGGGGGG"G$G&G(G*G,G.G1G3G5G7F~9F|;Fz>Fx@FuBFsDFqFFoHFmKFkMFiOFgQFdSFbUF`XF^ZF\\FZ^EX`EUcESeEQgEOiEMkEKnEIpEFrEDtEBvE@yE>{E<}E:E7E5E3D1D/D-D*D(D&D$D"DDDDDDDDDC C CCCCB@>; 9 7520.JHFDB@ > < :86420.,*( &"$$#&!')+-/13568 : < >@BCEGGGGF F F FFFFFFFEEE!E#E%E&E(E*E,E.E0D2D4D6D8D:D<~D=|D?zDAyDCwDEuCGsCIqCKpCMnCNlCPjCRhCTgCVeCXcCZaB\`B^^B_\BaZBcXBeWBgUBiSBkQBlOBnNApLArJAtHAvGAxEAyCA{AA}@A>A>> > > >>>>>><1%, ;J MO(R6rUEaXSPZb>]r+adg    #&(+- 0 2!5!7"9"<#>#@$C$E%G%I&K&N'P'R(T(V(X)}Z)z\*x^*u`+sb+pd+nf,lh,jj-gl-em-co.aq.^s/\u/Zv/Xx0Vz0T{0R}1P1N1L2J2H2F3D3B3@4>4<4:58575563616/7.7,7*8)8'8%8#9"9 9::::;;;;<< 2 0 .,+)'%#"  "#%'(* , -/1355444 3 332221110!0#0%/(/*.-./.2-4-7-9,<,?+A+D+G*J*L)O)R)U(X(~['|^'y`&wc&tg%rj%om%lp$js$gv#dy#a}"_"\!Y!V S PMJGDA>;841.+'$              235"637C9rS:ab;Qr<@>0? @A 5(*8 FGGGGG G FFFFFFFFFF"F$F&F(F*F,F.F1F3F5E7E9E};E{>Ey@EvBEtDErFEpHEnKElMEjOEhQEfSEcUEaXE_ZE]\D[^DY`DWcDTeDRgDPiDNkDLnDJpDHrDEtDCvDAyD?{D=}D;D8C6C4C2C0C.C+C)C'C%C#C!CCCCCCCBB B BBBBB@>;9 7 520.LJHFDB @ > <:86420.,* ("&$$&"' )+-/13568: < > @BCEGIHHHH H HHHHHGGGGGG!G#G%G'G)G*F,F.F0F2F4F6F8F:~F<|F>zF?yEAwECuEEsEGqEIpEKnEMlEOjEPhERgETeDVcDXaDZ`D\^D^\D_ZDaXDcWDeUDgSDiQCkOCmNCnLCpJCrHCtGCvECxCCzAC{@C}>B2&,;K NQ&T4rWCaZQP\`>_o+cfi  !$&)+.0 3 5!8!:"<"?#A#C$E$H%J%L&N&P&S'U'W(Y(}[)z])x_*ua*sc*pe+nf+lh,jj,gl,en-cp-ar.^s.\u.Zw/Xy/Vz/T|0R~0P0N1L1J2H2F2D3B3@3>4<4:48575553516/6.6,7*7)7'8%8#8"8 999::::;;;; 1 / .,*('%#! "#%'(* , -/1344433 3 222111000!/#/&/(.+.--0-2-5,7,:,=+?+B*E*G*J)M)P(S(U'X'~['|^&ya&wd%tg%rj$om$lp#jt#gw"dz"b}!_!\ Y VSPMJGDA>;851.+'$               123"536C7sS9bb:Rr;A=1>"?@ 5()7 EFFFFF E EEEEEEEEEE"E$E&E(E*E,E.E1D3D5D7D9D~;D|>Dz@DxBDuDDsFDqHDoKDmMDkODiQDgSDdUDbXC`ZC^\C\^CZ`CXcCVeCSgCQiCOkCMnCKpCIrCFtCDvCByC@{C>}C<B:B7B5B3B1B/B-B*B(B&B$B"BBBBBAAAAA A AAAA@>;9 7 520.NLJHFD B @ ><:86420., *"($&&$'") +-/13568:< > @ BCEGIJJJJJ J JJIIIIIIIII!I#I%H'H)H+H,H.H0H2H4H6H8~H:|GyG@wGAuGCsGEqGGpGInGKlGMjFOhFQgFReFTcFVaFX`FZ^F\\F^ZF`XFaWEcUEeSEgQEiOEkNEmLEnJEpHErGEtEEvCDxADz@D{>D}am+e}hk   "$'*,/146 8 ;!=!?"B"D#F#H$K$M%O%Q&S&U'W'Y(}[(z](x_)ua)sc*pe*ng+li+jk+gm,eo,cp-ar-^t-\v.Zx.Xy.V{/T}/R~0P0N0L1J1H1F2D2B2@3>3<3:48474553515/6.6,6*6)7'7%7#8"8 89999::::;; 1 / -+*(&$"! "#%'( * , -/134333 2 2 2211000//"/$.&.).+-.-0,3,5,8+;+=+@*C*E)H)K)N(P(S'V'Y&~\&|_%yb%we%th$rk$on#lq#jt"gw"d{!b~!_ \ YVSPMJGDA>;851.+'$               /12"435C6tS8cb9Sr:C;2=#>? 5((6 DEEEED D DDDDDDDDDD"D$D&D(D*D,D.C1C3C5C7C9C;C}>C{@CyBCvDCtFCrHCpKCnMClOCjQChSCfUBcXBaZB_\B]^B[`BYcBWeBTgBRiBPkBNnBLpBJrBHtBEvBCyBA{A?}A=A;A8A6A4A2A0A.A+A)A'A%A#A!AAA@@@@@@ @ @@@@@>;97 5 20.PNLJHF D B @><:86420. ,"*$(&&'$)"+ -/13568:<> @ B CEGIKLLLLL K KKKKKKKKKKJ!J#J%J'J)J+J-J.J0J2I4I6~I8|I:zIwI@uIBsICqIEpIGnHIlHKjHMhHOgHQeHScHTaHV`HX^HZ\H\ZG^XG`WGbUGcSGeQGgOGiNGkLGmJGoHGpGFrEFtCFvAFx@Fz>F|ck+g{jm     #%(*-/2479 ; >!@!B"E"G#I#K$M$P%R%T&V&X&Z'}\'z^(x`(ub)sd)pf*nh*lj*jl+gm+eo,cq,as,^u-\v-Zx-Xz.V|.T}/R/P/N0L0J0H1F1D1B2@2>2<3:38374543415/5.5,6*6)6'7%7#7"7 8889999:::: 0 . -+)'&$"  "#%'( * , -/133332 2 2111000// .".%.'-)-,-.,1,3,6+9+;*>*@*C)F)I(K(N'Q'T'W&Z&~\%|_%yb$we$th#rl#oo"lr"ju"gx!d{!b _ \YVSPMKGDA>;851.+'$               .01"234C5vS6eb8Tr9D:4<$=> 5('5 CDDDCC C CCCCCCCCCC"C$C&C(C*C,B.B1B3B5B7B9B;B~>B|@BzBBxDBuFBsHBqKBoMBmOBkQBiSAgUAdXAbZA`\A^^A\`AZcAXeAVgASiAQkAOnAMpAKrAItAFvADy@B{@@}@>@<@:@7@5@3@1@/@-@*@(@&@$@"@????????? ? ????>;97 5 20.RPNLJH F D B@><:86420 .",$*&('&)$+"- /13568:<>@ B CEGIKMNNMMM M MMMMMMMLLLL!L#L%L'L)L+L-K/K1K2K4~K6|K8zK:yKuK@sKBqJDpJEnJGlJIjJKhJMgJOeJQcJSaJT`IV^IX\IZZI\XI^WI`UIbSIcQIeOIgNIiLHkJHmHHoGHqEHrCHtAHv@Hx>Hzei+iylo     !#&(+.0257:< > A!C!E"H"J#L#N$P$R$T%W%Y&[&}]'z_'xa(uc(se(pf)nh)lj*jl*gn+ep+cr+as,^u,\w,Zy-Xz-V|.T~.R.P/N/L/J0H0F0D1B1@2>2<2:38373543414/4.5,5*5)6'6%6#7"7 778889999:: 0 . ,*)'%#!  "#%'( * ,-/133222 1 11000///. .#.%-(-*,-,/,2+4+7+9*<*>)A)D(F(I(L'O'R&T&W%Z%~]%|`$yc$wf#ti#rl"oo"lr!jv!gy d| b_\YVSPNKHDA>;851.+'$                -.0"133C4wS5fb7Ur8E95:%<=5(&4 BCCBBB B BBBBBBBBBB"B$B&B(B*A,A.A1A3A5A7A9A;A>A}@A{BAyDAwFAtHArKApMAnO@lQ@jS@hU@fX@cZ@a\@_^@]`@[c@Ye@Wg@Ti@Rk@Pn@Np@Lr@Jt@Hv?Ey?C{?A}???=?;?8?6?4?2?0?.?+?)?'?%?#>!>>>>>>>>> > >>>>>;975 2 0.TRPNLJ H F DB@><:8642 0".$,&*'()&+$-"/ 13568:<>@B C EGIKMOOOOOO O OOOONNNNNNN!N#N%N'M)M+M-M/M1M3~M4|M6zM8yM:wM
          sL@qLBpLDnLFlLGjLIhLKgLMeLOcKQaKS`KU^KV\KXZKZXK\WK^UK`SKbQKdOJeNJgLJiJJkHJmGJoEJqCJrAJt@Jv>Jxgg+kwnq    !$'),.1368:=?A D F!H!J"M"O#Q#S$U$W%Y%[&}]&z_'xa'uc'se(pg(ni)lk)jm)go*ep*cr+at+^v+\x,Zy,X{-V}-T~-R.P.N.L/J/H0F0D0B1@1>1<2:28273533314/4.4,5*5)5'5%6#6"6 77788889999 / - ,*(&%#! "#%'( * ,-/122211 1 000///...!-#-&-(,+,-+0+2+5*7*:)<)?)B(D(G'J'M'O&R&U%X%[$~^$|a#yd#wg#tj"rm"op!ls!jv gy d}b_\YVSQNKHDA>;851.+'$                      ,-/"031C3xS4gb5Vr7F869&;<5($3 ABAAAA A AAAAAAAAAA"A$A&A(@*@,@.@1@3@5@7@9@;@>@~@@|B@zD@xF@uH@sK@qM?oO?mQ?kS?iU?gX?dZ?b\?`^?^`?\c?Ze?Xg?Vi?Sk?Qn?Op?Mr>Kt>Iv>Fy>D{>B}>@>>><>:>7>5>3>1>/>->*>(=&=$="========== = ===<;975 2 0.¨USQOMK I G ECA?=;9753 1"/$-&,'*)(+&-$/"1 3568:<>@BC E GIKMOPQQQQQ Q QPPPPPPPPP P!O#O%O'O)O+O-O/O1~O3|O5zO6yN8wN:uNqN@pNBnNDlNFjNGhNIgMKeMMcMOaMQ`MS^MU\MWZMXXMZWM\UL^SL`QLbOLdNLfLLgJLiHLkGLmELoCLqAKs@Kt>Kvie+mups               "%'*,/1469;>@BD G I!K!M"O"R#T#V$X$Z%\%}^%z`&xb&ud'sf'ph(nj(ll(jm)go)eq*cs*au*^v+\x+Zz,X|,V},T-R-P.N.L.J/H/F/D0B0@0>1<1:18272523313/3.4,4*4)5'5%5#6"6 66777888899 / - +)(&$"  !#%' ( * ,-/12211 1 0 00///..--"-$,&,),++.+0*3*5*8):)=(@(B(E'H'J&M&P&S%V%X$[$~^#|a#yd"wg"tj!rm!oq lt jwgzd}b_\YVSQNKHEA>;851.+'$                     *,-"/30C2yS3hb4Wr6G778'9;5(#2 @@@@@@ @ @@@@@@@@@@"@$@&?(?*?,?.?1?3?5?7?9?;?>?@?}B?{D?yF?wH?tK>rM>pO>nQ>lS>jU>hX>fZ>c\>a^>_`>]c>[e>Yg>Wi>Tk>Rn>Pp=Nr=Lt=Jv=Hy=E{=C}=A=?===;=8=6=4=2=0=.=+<)<'<%<#@BCE G IKMOPRSSSSR R RRRRRRRRQQ Q"Q#Q%Q'Q)Q+Q-Q/~P1|P3zP5yP7wP8uP:sPpP@nPBlPDjOFhOHgOIeOKcOMaOO`OQ^OS\OUZOWXNYWNZUN\SN^QN`ONbNNdLNfJNgHNiGNkEMmCMoAMq@Ms>Mtkc+osru                #%(+-02579<>ACEG J L!N!P"R"T"V#Y#[$]$}_%za%xc&ue&sf'ph'nj'll(jn(gp)er)cs)au*^w*\y+Z{+X|+V~,T,R-P-N-L.J.H.F/D/B/@0>0<1:18172523212/3.3,3*4)4'4%5#5"5 66667778888 . , +)'%$"  !#%& ( * ,-/11110 0 0///...-- -",%,'+)+,+.*1*3)6)8);(>(@'C'F'H&K&N%Q%S$V$Y$\#~_#|b"ye"wh!tk!rn oq mtjxg{d~b_\YVTQNKHEA>;851.+'$                   )+,".3/C0zS2ib3Yr4H687(8: 5("1 ?????? ? ??????????">$>&>(>*>,>.>1>3>5>7>9>;>>>@>~B>|D>zF>xH=vK=sM=qO=oQ=mS=kU=iX=gZ=e\=b^=``=^c=\e=Zg=Xi=Vk=Sn<<<:<7<5<3<1;/;-;*;(;&;$;";;;;;;;;;; : ::::9752 0 .ĥYWUSQO M K IGECA?=;97 5"3$1&/'-)++)-'/%1#3!568:<>@BCEG I KMOPRTUTTT T T TTTTTSSSSS S"S$S%S'S)R+R-~R/|R1zR3yR5wR7uR9sR:qRnQ@lQBjQDhQFgQHeQJcQKaQM`QO^QQ\PSZPUXPWWPYUPZSP\QP^OP`NPbLPdJOfHOhGOiEOkCOmAOo@Oq>Osma+qqtw               !$&)+.0358:=?ADFHJL O Q!S!U"W"Y#[#]$}_$za%xc%ue%sg&pi&nk'lm'jo(gp(er(ct)av)^x*\y*Z{*X}+V+T,R,P,N-L-J-H.F.D/B/@/>0<0:08171513212/2.3,3*3)4'4%4#4"5 55666777788 . , *('%#! !#%& ( *,-/11000 / //...---, ,#,%+'+**,*/*1)4)6(9(<(>'A'C&F&I&L%N%Q$T$W#Z#]"~`"|c"yf!wi!tl ro ormujxg{db_\YVTQNKHEA>;851.+'$!               (*+",3.C/{S1jb2Zr3I596)78 5(!0 >>>>>> > >>>>>>>>>="=$=&=(=*=,=.=1=3=5=7=9=;=>=@=B=}D<{F@BCEGI K MOPRTVVVVV V V VVUUUUUUUU U"U$T&T(T)T+~T-|T/zT1yT3wT5uT7sS9qS;pSlS@jSBhSDgSFeSHcSJaSL`RM^RO\RQZRSXRUWRWURYSR[QR\OR^NQ`LQbJQdHQfGQhEQjCQkAQm@Qo>Qqo_+sovy              "$'*,/1469;=@BDFIKMO Q T!V!X"Z"\#^#}`#zb$xd$uf%sh%pj&nl&lm'jo'gq'es(cu(av)^x)\z)Z|*X}*V+T+R+P,N,L-J-H-F.D.B.@/>/;852.+'$!               '(*"+3-C.}S/lb1[r2J4:5*67 5( / ====== = ========<<"<$<&<(<*<,<.<1<3<5<7<9<;<><@:<::979593919/9-9*9(9&9$9"9999998888 8 88887520 .ơ][YWUS Q O MKIGECA?=; 9"7$5&3'1)/+--+/)1'3%5#6!8:<>@BCEGI K M OPRTVXXXXX X W WWWWWWWWWV V"V$V&V(V*~V+|V-zV/yV1wU3uU5sU7qU9pU;nU=lU>jU@hUBgUDeTFcTHaTJ`TL^TN\TOZTQXTSWTUUTWSTYQS[OS]NS^LS`JSbHSdGSfEShCSjASk@Rm>Roq]+umx}{                "%(*-/2479<>@CEGILNPRT V X![!]"_"}a#zc#xe$uf$sh%pj%nl&ln&jp&gr'et'cu(aw(^y(\{)Z|)X~*V*T*R+P+N,L,J,H-F-D-B.@.>.;852.+($!                 &')"*3,C-~S.mb0\r1L2;4,56 5(. <<<<<< < <<<<<<<;;;";$;&;(;*;,;.;1;3;5;7;9;;;>;@:B:D:}F:{H:yK:wM:tO:rQ:pS:nU:lX:jZ:h\:f^:c`:ac:_e9]g9[i9Yk9Wn9Tp9Rr9Pt9Nv9Ly9J{9H}9E9C9A9?9=8;88868482808.8+8)8'8%8#8!888777777 7 77777520.ǟ_][YWU S Q OMKIGECA?= ;"9$7&5'3)1+/--/+1)3'5%6#8!:<>@BCEGIK M O PRTVXZZZYY Y Y YYYYYYXXXX X"X$X&X(~X*|X,zW-yW/wW1uW3sW5qW7pW9nW;lW=jW?hV@gVBeVDcVFaVH`VJ^VL\VNZVPXVQWUSUUUSUWQUYOU[NU]LU_JU`HUbGUdEUfCThATj@Tl>TmPpL>s[+wkz{~               !#&(+.0358:<?ACFHJLOQSUW Y [!]!_"}a"zc#xe#ug$si$pk$nm%lo%jq&gr&et'cv'ax'^y(\{(Z})X)V)T*R*P+N+L+J,H,F,D-B-@.>.<.:/8/7/503010/1.1,1*2)2'2%3#3"3 34445556666 , * )'%#!  !#% & (*,-////. . .---,,,++ +"*$*'))),).(1(3'6'8';&=&@%C%E%H$K$M#P#S"V"Y!\!_ a |d zgwjtnrqotmwjzg}eb_\YWTQNKHEB>;852.+($!            $&'")3*C,S-nb/]r0M1=3-455(, ;;;;;; ; ;;;;;;::::":$:&:(:*:,:.:1:3:5:7:9:;:>9@9B9D9~F9|H9zK9xM9vO9sQ9qS9oU9mX9kZ9i\9g^9e`8bc8`e8^g8\i8Zk8Xn8Vp8Sr8Qt8Ov8My8K{8I}8G8D8B8@7>7<7:777573717/7-7*7(7&7$7"7766666666 6 6666520.ɝa^\ZXV T R PNLJHFDB@> <":$8&6'5)3+1-//-1+3)5'6%8#:!<>@BCEGIKM O P RTVXZ[[[[[ [ [ [[[ZZZZZZZ Z"Z$Z&~Y(|Y*zY,yY.wY/uY1sY3qY5pY7nY9lX;jX=hX?gXAeXBcXDaXF`XH^XJ\XLZWNXWPWWQUWSSWUQWWOWYNW[LW]JW_HV`GVbEVdCVfAVh@Vj>VluY+yi|x    !$'),.1368;=?BDFIKMOQSVXZ \ ^!`!}b"zd"xf"uh#sj#pl$nm$lo%jq%gs&eu&cw&ax'^z'\|(Z~(X(V)T)R*P*N*L+J+H,F,D,B-@->-<.:.8.7/5/3/10/0.0,1*1)1'2%2#2"3 33444455566 , * (&%#! !#% & (*,-///.. . ---,,+++* *#*%)')*(,(/(1'4'6&9&;&>%A%C$F$I#K#N#Q"T"V!Y!\ _ b|ezhwktnrqotmxj{g~eb_\YWTQNKHEB?;852.+($!            #%&"(3)C+S,ob-^r/N0>1.345(+ :::::: : :::::99999"9$9&9(9*9,9.91939597999;8>8@8B8D8F8}H8{K8yM8wO8uQ8rS8pU8nX8lZ8j\8h^7f`7cc7ae7_g7]i7[k7Yn7Wp7Ur7Rt7Pv7Ny7L{7J}7H7E6C6A6?6=6;68666462606.6+6)6'6%6#5!555555555 5 5555520.ʜb`^\ZX V T RPNLJHFDB@ >"<$:&8'6)4+2-0/.1,3*5(6'8%:#@BCEGIKMO P R TVXZ[]]]]] ] ] \\\\\\\\\\ ["[$~[&|[(z[*y[,w[.u[0s[1q[3pZ5nZ7lZ9jZ;hZ=gZ?eZAcZCaZD`ZF^YH\YJZYLXYNWYPUYRSYSQYUOYWNYYLX[JX]HX_GXaEXbCXdAXf@Xh>XjwW+{g~v    "%'*-/2479;>@BEGIKNPRTVXZ]_ a }c!zd!xf"uh"sj#pl#nn$lp$jr$gt%eu%cw&ay&^{'\|'Z~'X(V(T)R)P)N*L*J+H+F+D,B,@,>-<-:-8.7.5/3/1//0.0,0*1)1'1%1#2"2 23334445555 + ) (&$"  !# % & (*,-/...- - -,,,+++**!)#)&)((*(-'/'2'4&7&9%<%>%A$D$F#I#L"O"Q"T!W!Z ] `c|fziwluorroumxj{geb_\YWTQNKHEB?;852.+($ !            "$%"'3(C)S+pb,_r.O/?0/234 (* 999999 9 9999888888"8$8&8(8*8,8.81838587897;7>7@7B7D7F7~H7|K7zM7xO7vQ7sS7qU7oX7mZ7k\6i^6g`6ec6be6`g6^i6\k6Zn6Xp6Vr6St6Qv6Oy6M{6K}6I5G5D5B5@5>5<5:575553515/5-5*5(5&4$4"4444444444 4 444320.˚db`^\Z X V TRPNLJHFDB @">$<&:'8)6+4-2/01.3,5*6(8&:$<"> @BCEGIKMOP R T VXZ[]____^ ^ ^ ^^^^^^^]]] ]"~]$|]&z](y]*w],u].s\0q\2p\4n\5l\7j\9h\;g\=e\?c\Aa[C`[E^[F\[HZ[JX[LW[NU[PS[RQ[TOZUNZWLZYJZ[HZ]GZ_EZaCZcAZd@Zf>Yh2,%;K Zjmrp)as8PvF>yU+}et      #%(+-0257:<>ACEHJLNQSUWY[]_a }c ze!xg!ui"sk"pm#no#lq#jr$gt$ev%cx%az&^{&\}&Z'X'V(T(R(P)N)L*J*H*F+D+B+@,>,<-:-8-7.5.3.1///./,0*0)0'1%1#1"2 22333344455 + ) '%$"  !# % & (*,-..-- - , ,,+++***)!)$(&(((+'-'0&2&5&7%:%<$?$B$D#G#J"L"O!R!U X []`c|fziwluorsovmyj|geb_\ZWTQNKHEB?;852.+( $ !            !"$"%3'C(S*qb+ar-P.@/01 23 () 888888 8 8887777777"7$7&7(7*7,7.71737567696;6>6@6B6D6F6H6}K6{M6yO6wQ6uS6rU6pX6nZ5l\5j^5h`5fc5de5ag5_i5]k5[n5Yp5Wr5Ut5Rv5Py5N{5L}4J4H4E4C4A4?4=4;48464442404.4+4)3'3%3#3!333333333 3 322220.̘fdb`^\ Z X VTRPNLJHFD B"@$>&<':)8+6-4/2103.5,6*8(:&<$>"@ BCEGIKMOPR T V XZ[]_aa``` ` ` ````______!~_"|_$z_&y_(w^*u^,s^.q^0p^2n^4l^6j^7h^9g^;e]=c]?a]A`]C^]E\]GZ]HX]JW]LU]NS\PQ\RO\TN\VL\WJ\YH\[G\]E\_C\aA[c@[d>[f<[h:[j9[l7[n5[p3[q2[s0Zu.Zw,Zy+Z{)Z}'Z~%Z$Z"Z ZYYYYYYYYYY X X XXXXXXWK?3,';KZj nrr'au6PxD>{S+cr     !$&)+.1368:=?ADFHKMOQSVXZ\^`b}d zf xh!uj!sl!pm"no"lq#js#gu$ew$cx%az%^|%\~&Z&X'V'T'R(P(N)L)J)H*F*D+B+@+>,<,:,8-7-5-3.1./../,/*/)0'0%0#1"1 12223334444 * ( '%#! !# % &(*,-.--- , ,,++***)) )"($('')'+'.&0&3%5%8%:$=$@#B#E"H"J"M!P!S U X[^ad|gzjwmuprsovmzj}geb_\ZWTQNKHEB?;852.+ ( $ !            !#"$3&C'S)rb*br+Q-A.1/"12 (( 677777 7 7766666666"6$6&6(6*6,6.61635557595;5>5@5B5D5F5H5~K5|M5zO5xQ5vS5sU4qX4oZ4m\4k^4i`4gc4ee4bg4`i4^k4\n4Zp4Xr4Vt4Sv4Qy3O{3M}3K3I3G3D3B3@3>3<3:373533313/2-2*2(2&2$2"2222222222 1 11110.͖hfdb`^ \ Z XVTRPNLJHF D"B$@&>'<):+8-6/412305.6,8*:(<&>$@"B CEGIKMOPRT V X Z[]_abbbbb b b baaaaaaaa~a!|a#z`$y`&w`(u`*s`,q`.p`0n`2l`4j`6h_8g_9e_;c_=a_?`_A^_C\_EZ_GX_HW^JU^LS^NQ^PO^RN^TL^VJ^WH^YG][E]]C]_A]a@]c>]e<]f:]h9]j7]l5\n3\p2\r0\s.\u,\w+\y)\{'\}%\~$["[ [[[[[[[[[ZZ Z Z ZZZZZZXMA5,);KZj prt%aw4PzB>}Q+ap       "$'*,/1469;=@BEGIKNPRTVXZ\^`b}dzfxh uj sl!pn!np"lr"jt#gu#ew#cy$a{$^}%\~%Z&X&V&T'R'P(N(L(J)H)F*D*B*@+>+<+:,8,7-5-3-1./...,/*/)/'0%0#0"1 11122233344 * ( &$#! !# % &(*,---,, , +++***))( ("(%'''*&,&.&1%3%6$8$;$>#@#C"F"H!K!N!P S VY\_be|hzkwnuqrtowmzj}geb_\ZWTQNKHEB?<852 . + ( $ !           !"#3$C&S'tb)cr*R,B-2.#01 (' 566666 6 6555555555"5$5&5(5*5,5.51434547494;4>4@4B4D4F4H4K4}M4{O4yQ4wS3uU3rX3pZ3n\3l^3j`3hc3fe3dg3ai3_k3]n3[p3Yr3Wt3Uv2Ry2P{2N}2L2J2H2E2C2A2?2=2;28262422101.1+1)1'1%1#1!111111100 0 00000.Δjhfdb` ^ \ ZXVTRPNLJH F"D$B&@'>)<+:-8/61432506.8,:*<(>&@$B"C EGIKMOPRTV X Z []_acddddd c ccccccccc~b|b!zb#yb%wb'ub(sb*qb,pb.nb0la2ja4ha6ga8ea:ca;aa=`a?^aA\`CZ`EX`GW`IU`JS`LQ`NO`PN`RL`TJ_VH_XG_YE_[C_]A__@_a>_c<_e:_f9^h7^j5^l3^n2^p0^r.^s,^u+^w)^y']{%]}$]~"] ]]]]]]\\\\\ \ \ \\\[[[ZOC7,+;KZjrru#ay2P|@>O+_n        "%(*-/2479<>ACEHJLNPSUWY[]_ac}ezgxiuk sm po!nq!lr"jt"gv"ex#cz#a{$^}$\%Z%X%V&T&R'P'N'L(J(H)F)D)B*@*>+<+:+8,7,5,3-1-/-..,.*.)/'/%/#0"0 01112222333 ) ' &$"  ! # % &(*,--,,+ + +***)))((!'#'%'(&*&-%/%2%4$7$9#<#>#A"C"F!I!L N QTWZ\_be|hzkwnuqrtoxm{j~geb_\ZWTQNKHEB?<85 2 / + ( $ !          ""3#C%S&ub(dr)T*C,3-$/0 (& 455555 5 4444444444"4$4&4(4*4,4.31333537393;3>3@3B3D3F3H3K3~M3|O3zQ2xS2vU2tX2qZ2o\2m^2k`2ic2ge2eg2bi2`k2^n2\p2Zr2Xt1Vv1Sy1Q{1O}1M1K1I1G1D1B1@1>1<1:170503010/0-0*0(0&0$0"000000//// / ////.ϒljhfda _ ] [YWUSQOMKI G"E$C&A'?)>+<-:/8163452608.:,<*>(@&B$C"E GIKMOPRTVX Z []_acefffee e eeeeeedd~d|dzd!yd#wd%ud'sd)qd*pc,nc.lc0jc2hc4gc6ec8cc:ac<`b=^b?\bAZbCXbEWbGUbISbKQbLObNNaPLaRJaTHaVGaXEaZCa[Aa]@a_>aa<`c:`e9`g7`h5`j3`l2`n0`p.`r,`t+_u)_w'_y%_{$_}"_ ____^^^^^^^ ^ ^ ^]]]]]\PE9,-; KZjtrw"a{0P~>>M+\l       # &(+.0358:=?ADFHJMOQSUXZ\^`bd}fzhxjulsm po nq ls!ju!gw"ex"cz#a|#^~$\$Z$X%V%T&R&P&N'L'J(H(F(D)B)@*>*<*:+8+7+5,3,1,/-.-,-*.).'.%/#/"/ 00011122233 ) ' %#"  ! # % &(*,,,,+ + + ***))((('!'$&&&(&+%-%0$2$5$7#:#<"?"A"D!G!I L ORTWZ]`cf|izlwourruoxm{jheb_\ZWTQNKHEB?<8 5 2 / + ( $ !        "!3"C$S%vb'er(U)D+5,%-/(% 344444 3 3333333333"3$3&3(3*3,2.21232527292;2>2@2B2D2F2H2K2M2}O1{Q1yS1wU1uX1rZ1p\1n^1l`1jc1he1fg1di1ak1_n1]p1[r0Yt0Wv0Uy0R{0P}0N0L0J0H0E0C0A0?0=0;/8/6/4/2/0/./+/)/'/%/#/ ///...... . .....Аmkigec a _ ][YWUSQOMK I"G$E&C'A)?+=-;/9173553618/:.<,>*@(B&C$E"G IKMOPRTVXZ [ ]_acefggggg g gggffff~f|fzfyf!wf#uf%se'qe)pe+ne,le.je0he2ge4ee6cd8ad:`d<^d=\d?ZdAXdCWdEUdGSdIQcKOcMNcNLcPJcRHcTGcVEcXCcZAc\@b]>b_K+Zj      ! $ ' ),.1368;=@BDGIKMPRTVXZ\^`bd}fzhxjulsnppnr lt ju!gw!ey"c{"a}#^~#\#Z$X$V%T%R%P&N&L'J'H'F(D(B)@)>)<*:*8*7+5+3,1,/,.-,-*-).'.%.#/"/ /0001111222 ( ' %#! ! # %&(*,,+++ * **)))(('''"&$&&&)%+%.$0$3#5#8#:"="?!B!E G J MORUX[^acf|izlwpusrvpym|jheb_]ZWTQNKHEB?< 8 5 2 / + ( $!       "3!C"S$wb%fr'V(F*6+&,.($ 233332 2 2222222222"2$2&2(2*1,1.11131517191;1>1@1B1D1F1H1K1M0~O0|Q0zS0xU0vX0tZ0q\0o^0m`0kc0ie0gg0ei0bk0`n/^p/\r/Zt/Xv/Vy/S{/Q}/O/M/K/I/G/D/B/@/>.<.:.7.5.3.1./.-.*.(.&.$."..-------- - ----Џomkige c a _][YWUSQOM K"I$G&E'C)A+?-=/;1937556381:/<->+@)B'C&E$G"I KMOPRTVXZ[ ] _acefhiiiii i hhhhhh~h|hzhyhwg!ug#sg%qg'pg)ng+lg-jg.hg0gf2ef4cf6af8`f:^f<\f>Zf?XfAWfCUeESeGQeIOeKNeMLeOJePHeRGeTEdVCdXAdZ@d\>d]I+Xh    " % ' * -/2479<>@CEGJLNPRUWY[]_ace}gzixkumsopqnrlt jv gx!ez!c{!a}"^"\#Z#X$V$T$R%P%N&L&J&H'F'D(B(@(>)<):*8*7*5+3+1+/,.,,,*-)-'-%.#.". ///00011122 ( & $"! ! # %&(*++++* * )))(((''& &"&%%'%)%,$.$1#3#6"8";"=!@!C E HKMPSVX[^adg|jzmwpusrvpzm}jheb_]ZWTQNKHEB? < 8 5 2 / + ($!       "3 C!S#xb$gr&W'G)7*'+-(# 122211 1 1111111111"1$1&1(0*0,0.01030507090;0>0@0B0D0F0H0K/M/O/}Q/{S/yU/wX/uZ/r\/p^/n`/lc/je/hg/fi/dk.an._p.]r.[t.Yv.Wy.U{.R}.P.N.L.J.H.E.C-A-?-=-;-8-6-4-2-0-.-+-)-'-%-#- ,,,,,,,,, , ,,,,Ѝqomkig e c a_][YWUSQO M"K$I&G'E)C+A-?/=1;39576583:1-@+B)C'E%G#I!KMOPRTVXZ[] _ acefhjkkkjj j jjjjj~j|jziyiwiui!si#qi%pi'ni)li+jh-hh/gh0eh2ch4ah6`h8^h:\hXg@WgAUgCSgEQgGOgINgKLgMJgOHfPGfREfTCfVAfX@fZ>f\,2;&KZ jzr}a*P8>G+Vf   # % ( + - 0257:<?ACFHJMOQSUWZ\^`bdf}hzjxlumsopqnslujwgy ez c|!a~!^"\"Z#X#V#T$R$P%N%L&J&H&F'D'B'@(>(<):)8)7*5*3*1+/+.,,,*,)-'-%-#.". .////000111 ' & $"  ! # %&(*++*** ) ))(('''&&!&#%%%($*$,$/#1#4"6"9!;!>!A C FIKNQSVY\_beh|kznwqutrwpzm}jheb_]ZWTQNKHEB ? < 8 5 2 / +(%!  "3C S"yb#ir%X&H'8)(*+ (" 011000 0 0000000000"0$0&/(/*/,/./1/3/5/7/9/;/>/@/B/D/F/H.K.M.O.~Q.|S.zU.xX.vZ.t\.q^.o`.mc.ke.ig.gi-ek-cn-`p-^r-\t-Zv-Xy-V{-S}-Q-O-M-K-I-G,D,B,@,>,<,:,7,5,3,1,/,-,*,(,&+$+"++++++++++ + ++*Ћsqomki g e ca_][YWUSQ O"M$K&I'G)E+C-A/?1=3;596785:3<1>/@-B+C)E'G%I#K!MOPRTVXZ[]_ a cefhjlmllll l llll~k|kzkykwkuksk!qk#pk%nj'lj)jj+hj-gj/ej1cj2aj4`j6^j8\i:ZiWi@UiBSiCQiEOiGNiILhKJhMHhOGhQEhRChTAhV@hX>hZE+Td  ! # & ) + . 1 3 68;=?BDFIKMORTVXZ\^`bdf}hzjxlunspprntlvjwgye{ c} a~!^!\"Z"X"V#T#R$P$N%L%J%H&F&D'B'@'>(<(:(8)7)5*3*1*/+.+,+*,),',%-#-"- ...///00011 ' % #!  ! # %&(*+**) ) ) ((('''&&%!%#%&$($+#-#/#2"4"7!9!< ? A DFILOQTWZ]_beh|kznwquurxp{m~jheb_]ZWTQNKHE B ? < 9 5 2 /+(%!       "3CS {b"jr#Y%I&9())* (! /0//// / //////////"/$.&.(.*.,...1.3.5.7.9.;.>.@.B.D-F-H-K-M-O-Q-}S-{U-yX-wZ-u\-s^-p`-nc-le-jg,hi,fk,dn,ap,_r,]t,[v,Yy,W{,U},R,P,N,L,J+H+E+C+A+?+=+;+8+6+4+2+0+.+++)*'*%*#* ********* * *))Љusqomk i g eca_][YWUS Q"O$M&K'I)G+E-C/A1?3=5;6987:5<3>1@/B-C+E)G'I%K#M!OPRTVXZ[]_a c efhjlnnnnn n n nmm~m|mzmymwmumsm ql!pl#nl%ll'jl)hl+gl-el/cl1al3`k4^k6\k8Zk:XkUk@SkBQkDOjENjGLjIJjKHjMGjOEjQCjSAjT@iV>iXC+Rb "$ ' * , / 1 4 6 9;>@BEGILNPRUWY[]_aceg}izkxmuosqpsntlvjxgze|c} a ^!\!Z!X"V"T#R#P$N$L$J%H%F&D&B&@'>'<':(8(7)5)3)1*/*.*,+*+)+',%,#,"- --...///000 & % #! ! #%&(***)) ) (('''&&&%%"$$$&$)#+#."0"2"5!7!: = ?BDGJLORUWZ]`cfi|lzowruurxp{mjheb_]ZWTQNK H E B ? < 9 5 2/+(%!       "3CS|b!kr"Z$J%:'*() ( ...... . .........."-$-&-(-*-,-.-1-3-5-7-9-;->-@-B,D,F,H,K,M,O,Q,~S,|U,zX,xZ,v\,t^,q`,oc,me+kg+ii+gk+en+cp+`r+^t+\v+Zy+X{+V}+T+Q+O+M*K*I*G*D*B*@*>*<*:*7*5*3*1*/)-)*)()&)$)")))))))))( ( ((Їwusqom k i gdb`^\ZXVT R"P$N&L'J)H+F-E/C1A3?5=6;89:7<5>3@1B/C-E+G)I'K%M#O!PRTVXZ[]_a c e fhjlnppppp o o oo~o|ozoyowounsnqn pn"nn$ln%jn'hn)gn+en-cm/am1`m3^m5\m6Zm8Xm:WmSl@QlBOlDNlFLlGJlIHlKGlMElOCkQAkS@kU>kVA+P`  "%( * - 0 2 5 7 : <>ACFHJLOQSUWY\^`bdfh}jzlxnuosqpsnulwjygze|c~a^ \ Z!X!V"T"R#P#N#L$J$H%F%D%B&@&>'<':'8(7(5(3)1)/*.*,**+)+'+%,#,", ---...///00 & $ "  ! #%&(*)))( ( ('''&&%%% $"$%#'#)#,"."1!3!6 8 ; =@BEHJMPRUX[^adgj|mzpwsuvryp|mjheb_]ZWTQN K H E B ? < 9 52/+(%!                          "3CS}b lr!\#K$;%+'( ( ------ - ---------,",$,&,(,*,,,.,1,3,5,7,9,;,>,@+B+D+F+H+K+M+O+Q+S+}U+{X+yZ+w\+u^+s`*pc*ne*lg*ji*hk*fn*dp*ar*_t*]v*[y*Y{*W}*U*R)P)N)L)J)H)E)C)A)?)=);)8)6)4)2(0(.(+()('(%(#( ((((((('' ' ''Ѕyvtrpn l j hfdb`^\ZXV T"R$P&N'L)J+H-F/D1B3@5>6<8::8<6>5@3B1C/E-G+I)K'M%O#P!RTVXZ[]_ac e f hjlnpqrqqq q q q~q|qzqypwpupspqppp np"lp$jp&hp'go)eo+co-ao/`o1^o3\o5Zo7Xo8Wn:UnQn@OnBNnDLnFJnHHnIGmKEmMCmOAmQ@mS>mU?+N^   #&(+ . 0 3 5 8 : = ?BDFIKMORTVXZ\^`bdfh}jzlxnupsrptnvlwjyg{e}ca^\ Z X!V!T!R"P"N#L#J$H$F$D%B%@&>&<&:'8'7'5(3(1)/).),***)*'+%+#+", ,,---.../// % $ "  ! #%&()))(( ' ''&&&%%$$ $##%#'"*","/!1!4 6 9;>@CFHKNPSVY\^adgj|mzpwsuvrzp}mjheb`]ZWTQ N K H E B ? < 952/+(%!                          "3CS~bmr ]!L#<$-&'( ,,,,,, , ,,,,,,,,++"+$+&+(+*+,+.+1+3+5+7+9+;+>*@*B*D*F*H*K*M*O*Q*S*~U*|X*zZ*x\*v^)t`)qc)oe)mg)ki)ik)gn)ep)cr)`t)^v)\y)Z{)X})V(T(Q(O(M(K(I(G(D(B(@(>(<(:(7(5'3'1'/'-'*'('&'$'"'''''&&&&& & &Єzxvtrp n l jhfdb`^\ZX V"T$R&P'N)L+J-H/F1D3B5@6>8<::<8>6@4B2C0E.G,I+K)M'O%P#R!TVXZ[]_ace f h jlnpqsssss s s ~s|szryrwrursrqrprnr lr"jq$hq&gq(eq)cq+aq-`q/^q1\q3Zp5Xp7Wp9Up:SpOp@NpBLpDJoFHoHGoIEoKCoMAoO@oQ>oS=+L\       !$'),.1 4 6 9 ; = @ BEGILNPRTWY[]_acegi}kzmxouqssptnvlxjzg|e}ca^\Z X V T!R!P"N"L#J#H#F$D$B%@%>%<&:&8'7'5'3(1(/(.),)*))*'*%+#+"+ ,,,---...// % # ! ! #%&()((( ' ' '&&%%%$$#!###&"("*!-!/!2 4 79<>ACFIKNQTVY\_behk|nzqwtuwrzp}mjheb`]ZWT Q N K H E B ? <952/,(%!       "3CSbnr^ N"=#.%&' ++++++ + +++++++***"*$*&*(***,*.*1*3*5*7*9*;)>)@)B)D)F)H)K)M)O)Q)S)U)}X){Z)y\(w^(u`(sc(pe(ng(li(jk(hn(fp(dr(at(_v(]y([{(Y}'W'U'R'P'N'L'J'H'F'C'A'?'=';'8&6&4&2&0&.&+&)&'&%&#& &&&%%%%%% % %Ђ|zxvtr p n ljhfdb`^\Z X"V$T&R'P)N+L-J/H1F3D5B6@8>:<<:>8@6B4C2E0G.I,K*M(O&P$R#T!VXZ[]_acef h j lnpqsuuuuu u ~t |tztytwtutstqtptnsls js"hs$gs&es(cs*as+`s-^r/\r1Zr3Xr5Wr7Ur9Sr;QrNq@LqBJqDHqFGqHEqJCqKAqM@qO>pQ;+JZ          "%'*-/24 7 9 < > A C EHJLNQSUWY[^`bdfhj}lznxouqsspunwlyjzg|e~ca^\ZXV T R!P!N"L"J"H#F#D$B$@$>%<%:&8&7&5'3'1(/(.(,)*)))'*%*#*"+ ++,,,---... $ # ! !#%&((('' ' &&&%%$$$##""$"&")!+!- 0 2 57:<?ADGILORTWZ]`cehk|nzrwuuxr{p~mjheb`]ZW T Q N K H E B ?<952/,(%!       "3CSbpr_O!?"/$%&  ****** * ******))))")$)&)()*),).)1)3)5)7)9(;(>(@(B(D(F(H(K(M(O(Q(S(U(~X(|Z'z\'x^'v`'tc're'og'mi'kk'in'gp'er'ct'`v'^y'\{&Z}&X&V&T&Q&O&M&K&I&G&D&B&@&>%<%:%7%5%3%1%/%-%*%(%&%$%"%%$$$$$$$$ $ Ѐ~|zxvt r p nljhfdb`^\ Z"X$V&T'R)P+N-L/J1H3F5D6B8@:><<>:@8B6C4E2G0I.K,M*O(P&R$T"V XZ[]_acefh j l npqsuwwwvv ~v |v zvyvwvuvsvqupunuluju hu"gu$eu&cu(at*`t,^t-\t/Zt1Xt3Wt5Ut7St9Qs;Os=Ns>Ls@JsBHsDGsFEsHCsJArL@rM>rO9+HW    #%(+-0358 : = ? A D F HKMOQTVXZ\^`bdfhj}lznxpurstpvnxlyj{g}eca^\ZXVT R P!N!L!J"H"F#D#B#@$>$<%:%8%7&5&3'1'/'.(,(*())')%)#*"* +++,,,----. $ "  !#%&((''' & &%%%$$$## """$!'!)!, . 0358:=?BEGJMORUX[]`cfil}ozrxuuxr|pmkheb`]Z W T Q N K H EB?<962/,(%!      "3CSbqr`P @!0" $%  )))))) ) )))))((((("($(&(((*(,(.(1(3(5(7'9';'>'@'B'D'F'H'K'M'O'Q'S'U'X&}Z&{\&y^&w`&uc&se&pg&ni&lk&jn&hp&fr&dt&bv&_y%]{%[}%Y%W%U%R%P%N%L%J%H%F%C%A$?$=$;$8$6$4$2$0$.$+$)$'$%$## ######### # ~~~~|~z~xv t r pnljhfdb`^ \"Z$X&V'T)R+P-N/L1J3H5F6D8B:@<>><@:B8C6E4G2I0K.M,O*P(R&T$V"X Z[]_acefhj l n pqsuwxxxx~x |x zx yxwxuwswqwpwnwlwjwhw gw"ev$cv&av(`v*^v,\v.Zv/Xv1Wv3Uu5Su7Qu9Ou;Nu=Lu?Ju@HuBGuDEtFCtHAtJ@tL>tN7+FU   !#&)+.1368; = @ B D G I K NPRTVY[]_acegik}mzoxqusstpvnxlzj|g~eca^\ZXVTR P N L!J!H"F"D"B#@#>$<$:$8%7%5&3&1&/'.',(*()(')%)#)"* **+++,,,--- # "   !#%&'''&& & %%$$$###" "#!%!'!* , /1368;=@CEHKMPSUX[^adgjm}pzsxvuyr|pmkheb` ] Z W T Q N K HEB?<962/,(%!      "3CSbrraQA 1!!#$  (((((( ( ((((''''''"'$'&'('*','.'1'3'5&7&9&;&>&@&B&D&F&H&K&M&O&Q&S&U%X%~Z%|\%z^%x`%vc%te%rg%oi%mk%kn%ip%gr%et$cv$`y$^{$\}$Z$X$V$T$Q$O$M$K$I$G$D#B#@#>#<#:#7#5#3#1#/#,#*#(#&"$"""""""""""" |||~}|}z}x }v }t }r}p}n}k~i~g~e~c~a~_ ~]"~[$Y&W'U)S+Q-O/M1K3J5H6F8D:B<@>>@vL5+DS      !$'*,/1479<> @ C E G J L N QSUWY[^`bdfhjl}nzoxqussupwnyl{j|g~eca^\ZXVTRPN L J!H!F"D"B"@#>#<$:$8$7%5%3%1&/&.','*')('(%(#)") )***+++,,,- # !   !#%&''&& % % %$$$##"""!!#!& ( * -/2469;>ACFHKNQSVY\_adgjm}pzsxwuzr}pmkheb ` ] Z W T Q N KHEB?<962/,(%!       "3CSbsrbRB2 #"#  '''''' ' '''&&&&&&&"&$&&&(&*&,&.&1&3%5%7%9%;%>%@%B%D%F%H%K%M%O%Q%S$U$X$Z$}\${^$y`$wc$ue$sg$pi$nk$ln$jp$hr#ft#dv#by#_{#]}#[#Y#W#U#R#P#N#L#J#H"F"C"A"?"=";"8"6"4"2"0"."+")!'!%!#! !!!!!!!!! zz{{}{{{y {w {u {s{q|o|m|k|i|g|e|c|a |_"}]$}[&}Y'}W)}U+}S-}Q/}O1~M3~K5~I6~G8~E:~C<~A>~?@~=B;C:E8G6I4K2M0O.P,R*T(V&X$Z"[ ]_acefhjln p q suwyz||~||{z{ y{ w{ u{s{q{p{n{lzjzhzgzez!cz"az$`z&^z(\y*Zy,Xy.Wy0Uy2Sy3Qy5Oy7Ny9Lx;Jx=Hx?GxAExBCxDAxF@xH>xJ3+BQ       "%(*-0257:<?A D F H K M O Q SVXZ\^`bdfhjl}nzpxrutsvpxnyl{j}geca^\ZXVTRPNL J H!F!D!B"@">#<#:#8$7$5%3%1%/&.&,&*')''(%(#(") ))***+++,,, " !   !#%&&&&% % %$$###""!!!!$ & (+-0257:<?ADFILNQTWZ\_behkn}qztxwuzr}pmkhe b ` ] Z W T Q NKHEB?<962/,(%############ # # # # # ###################### "3CSbtrcSC3$!"  &&&&&& & &&%%%%%%%%"%$%&%(%*%,%.%1$3$5$7$9$;$>$@$B$D$F$H$K$M$O$Q#S#U#X#Z#~\#|^#z`#xc#ve#tg#ri#ok#mn#kp"ir"gt"ev"cy"`{"^}"\"Z"X"V"T"Q"O"M!K!I!G!D!B!@!>!}A@}?B}=C};E}9G}7I}5K}3M}1O~0P~.R~,T~*V~(X~&Z~$[~"] _acefhjlnp q s uwyz|~~}|}z}y} w} u}s}q}p|n|l|j|h|g|e|c|!a|#`{$^{&\{(Z{*X{,W{.U{0S{2Q{4Oz5Nz7Lz9Jz;Hz=Gz?EzACzCAzD@yF>yH1+@O        !!"#&(+.0368;=?BD G I K M P R T VY[]_acegikm}ozqxsuusvpxnzl|j~geca^\ZXVTRPNLJ H F D!B!@">"<":#8#7$5$3$1%/%.&,&*&)'''%'#("( ()))***+++, "    !#%&&%%% $ $$##"""!! " $ ')+.0358:=?BDGJLORUWZ]`cfilo}rzuxxu{s~pmkh e c ` ] Z W T QOLIEB?<962/,('''''''''''' ' ' ' ' ' '''''''''''''''''''''''  "3CSbureTD4%! $%%%%% % %$$$$$$$$$"$$$&$($*$,$.#1#3#5#7#9#;#>#@#B#D#F#H#K#M#O"Q"S"U"X"Z"\"}^"{`"yc"we"ug"si"qk"nn!lp!jr!ht!fv!dy!b{!_}!]![!Y!W!U!R!P N L J H F C A ? = ; 8 6 4 20.+)'%# wwwwww} w{ wy xwxuxsxqxoxmxkxiygye yc"ya$y_&y]'y[)yY+zW-zU/zS1zQ3zO5zM6zK8zI:zG<{E>{C@{AB{?C{=E{;G{9I{7K|5M|3O|1P|/R|-T|+V|)X|(Z|&[}$]}"_} a}c}e}f}h}j~l~n~p~q~ s~ u~w~y~z|~~|zyw u sq~p~n~l~j~h~g~e~c}a}!`}#^}%\}&Z}(X}*W},U}.S|0Q|2O|4N|6L|7J|9H|;G|=E|?C{AA{C@{E>{F<{H:{J9{L7{N5{P3zR2zS0zU.zW,zY+z[)z]'z_%z`$yb"yd yfyhyjylymyoyqxsxuxwxx xz x| x~xxwwwvk_~T,zH;w/+>M         !"##$%&'),/1469;>@CEG J L N P S U W Y[]`bdfhjln}pzqxsuuswpyn{l|j~geca^\ZXVTRPNLJHF D B!@!>!<":"8#7#5#3$1$/%.%,%*&)&'&%'#'"( (()))***+++ !    !#%&%%%$ $ ###""!!! #%'*,.1368;=@BEHJMPRUX[^`cfilo}rzuxxu|spmk h e c ` ] Z W TQOLIEB?<962/,************ * * * * * ************************   "3CSbvrfUE5&  #$$$$$ $ $#########"#$#&#(#*#,"."1"3"5"7"9";">"@"B"D"F"H"K"M!O!Q!S!U!X!Z!\!~^!|`!zc!xe!vg!ti!rk on mp kr it gv ey c{ `} ^ \ Z X V TQOMKIGDB@><:7531/,*(&$"uuuuuu v} v{ vyvwvuvsvqvovmwkwiwg we"wc$wa&w_'w])x[+xY-xW/xU1xS3xQ5xO6xM8yK:yIyE@yCByACy?Ey=Gy;Iz9Kz7Mz5Oz3Pz1Rz/Tz-Vz+X{)Z{'[{%]{#_{"a{ c{e{f{h|j|l|n|p|q|s| u| w}y}z}|}~}|zywu s qpnljhgeca`!^#\%Z'X(W~*U~,S~.Q~0O~2N~4L~6J~8H~9G};E}=C}?A}A@}C>}E<}G:}H9}J7|L5|N3|P2|R0|T.|U,|W+|Y)|['{]%{_${a"{b {d{f{h{j{lzmzozqzszuzw zx zz z|y~yyyyxma|V,yJ;u>Kr1Zo$jk{h aP>-+<K     ! ""#$%%&'())*-/247:<>ACFHJ M O Q S V X Z \^`bdfhjln}pzrxtuvsxpyn{l}jgeca^\ZXVTRPNLJHFD B @ >!@CFHKNPSVY[^adgjmp}szvxyu|spm k h e c ` ] Z WTROLIFB?<962/............ . . . . . .........................  "3CSbxrgWF7'  "##### # """"""""""""$"&"("*!,!.!1!3!5!7!9!;!>!@!B!D!F!H!K M O Q S U X Z \ ^ }` {c ye wg uiskqnnplrjthvfyd{b}_][YWUSPNLJHFCA?=;86420.+)'%# ssssst t t} t{tytwtutsuquoumukui ug"ue$uc&va'v_)v]+v[-vY/vW1vU3vS5vQ6wO8wM:wKwG@wEBwCCwAEx?Gx=Ix;Kx9Mx7Ox5Px3Rx1Ty/Vy-Xy+Zy)[y']y%_y#ay!cyezfzhzjzlznzpzqzs{u{ w{ y{z{|{~{{zywus q pnljhgeca`^!\#Z%X'W)U*S,Q.O0N2L4J6H8G:E;C=A?@A>C<E:~G9~I7~J5~L3~N2~P0~R.~T,~V+}W)}Y'}[%}]$}_"}a }c}d}f|h|j|l|n|o|q|s|u |w {y {z{|{~{{{zn}czW,wL;t?Kp3Zm&ji{f aP>++:I ! ! " # $ $ %&''()**+,--0358:=?BDFIKM P R T V X [ ] _ acegikmo}qzsxuuvsxpzn|l~jgeca^\ZXVTRPNLJHFDB@ > ADFIKNQTVY\_begjmp}szwxzu}sp m k h e c ` ] ZWTROLIFB?<963111111111111 1 1 1 1 1 1111111111111111111111111 1  " 3CSbyrhXH8(  !""""" ! !!!!!!!!!!"!$!&!( * , . 1 3 5 7 9 ; > @ B D F HKMOQSUXZ\^~`|czexgvitkrnopmrktivgye{c}`^\ZXVTQOMKIGDB@><:7531/,*(&$"qqqqrr r r r}r{ryrwsusrspsnslsj sh"sf$td&tb't`)t^+t\-tZ/tX1tV3uT5uR6uP8uN:uMuI@uGBuECvCEvAGv?Iv=Kv;Mv9Ov7Pv5Rw3Tw1Vw/Xw-Zw+[w)]w'_w%ax#cx!exfxhxjxlxnxpxqysyuywy yy zy|y~yzzywusq p nljhgeca`^\!Z#X%W'U)S+Q,O.N0L2J4H6G8E:C;A=@?>A)+8G  !"## $ % & & ' ( ))*+,,-.//01369;=@BEGILNPS U W Y [ ] ` b dfhjlnp}qzsxuuwsyp{n}l~jgeca^\ZXVTRPNLJHFDB@> < :!8!7!5"3"1#/#.#,$*$)$'%%%#&"& &'''((()))*      !#$$$## # ""!!!   "$')+.0257:<?ADGILOQTWZ]_behknq}tzwxzu} s p m k h e c ` ]ZWUROLIFC?<96444444444444 4 4 4 4 4 4 444444444444444444444444 4 4 " 3 CSbzriYI9)  !!!!          " $ &(*,.13579;>@BDFHKMOQSUXZ\^`}c{eygwiuksnqpnrltjvhyf{d}b_][YWUSPNLJHFCA?=;86420.+)'%# oooppp p p p~p|pzqxqvqtqrqpqnql qj"rh$rf&rd'rb)r`+r^-r\/rZ1sX3sV5sT6sR8sP:sNsJ@tHBtFCtDEtBGt@It?Kt=Mt;Ou9Pu7Ru5Tu3Vu1Xu/Zu-[u+]u)_v'av%cv#ev!fvhvjvlvnwpwqwswuwwwyw zw |x~xxxxwusqp n ljhgeca`^\Z!X#W%U'S)Q+O-N.L0J2H4G6E8C:A<@=>?'+6E"#$%%&' ( ( ) * + + ,-../011234479<>ACEHJLOQSU X Z \ ^ ` b d fhjlnp}rztxvuxszp{n}ljgeca^\ZXVTRPNLJHFDB@>< : 8 7!5!3"1"/".#,#*$)$'$%%#%"% &&&''((()))       !#$$##" " "!!    "%'),.1358:=@BEGJMORUXZ]`cfilor}uzxx{ u~ s p m k h e c `]ZWUROLIFC?<9888888888888 8 8 8 8 8 8 8888888888888888888888888 8!8" 3 C Sb{rjZJ:*       "$&(*,.13579;>@BDFHKMOQSUXZ\^`~c|ezgxivktnrpprmtkviyg{e}ca^\ZXVTQOMKIGDB@><:7531/,*(&$"mnnnnn n n no~o|ozoxovotoroppn pl"pj$ph&pf'pd)pb+p`-q^/q\1qZ3qX5qV6qT8qR:qPrL@rJBrHCrFErDGrBIr@Kr>Ms>%+4C%&&'())* + , , - . / /01223455678:<?ADFIKMORTVX [ ] _ a c e g ikmoq}szuxwuxszp|n~ljgeca^\ZXVTRPNLJHFDB@><:8 7 5!3!1!/".",#*#)#'$%$#%"% %&&&'''((()      !####" " ! !!   !#%(*,/1469;>@CEHKMPSUX[^acfilor}uzx x| u s p m k h ec`]ZWUROLIFC?<;;;;;;;;;;;; ; ; ; ; ; ; ;;;;;;;;;;;;;;;;;;;;;;;;; ;!;!;" 3 C Sb|rk[K;+    "$&(*,.13579;>@BDFHKMOQSUXZ\^`c}e{gyiwkunspqrntlvjyh{f}db_][YWUSPNLJHFCA?=;96420.+)'%# llllll l l mmm~m|mzmxmvmtnrnp nn"nl$nj&nh'nf)nd+ob-o`/o^1o\3oZ5oX6oV8oT:pRpN@pLBpJCpHEpFGpDIqBKq@Mq>Oq<<>:@9A7C5E3G2I0K.M,N+P)R'T%V$X"Z []_aceghjln p r suwy{|yvvjs_,pS;lGKi:Ze.jb!{^[P>#+2A(()*++,-. . / 0 1 1 23445667899:;=@BEGILNPRUWY[ ] _ b d f h j lnpr}szuxwuys{p}n~ljgeca^\ZXVTRPNLJHFDB@><:87 5 3!1!/!.","*")#'#%$#$"$ %%%&&'''(((      !##""" ! ! !  !$&(+-/2479<>ACFHKNPSVY\^adgjmps}v zy x| u s p m k hec`]ZWUROLIFC@>>>>>>>>>>>> > > > > > > >>>>>>>>>>>>>>>>>>>>>>>>> >!>!>">"3 C S b}rm\L<,   "$&(*,.13579;>@BDFHKMOQSUXZ\^`c~e|gzixkvntprrptmvkyi{g}eca^\ZXVTQOMKIGDB@><:7531/,*(&$"jjjjjj j k kkkk~k|kzkxlvltlr lp"ln$ll&lj'lh)mf+md-mb/m`1m^3m\5mZ6mX8nV:nTnP@nNBnLCnJEnHGoFIoDKoBMo@Oo>Po:<<:>9@7B5C3E2G0I.K,M+O)P'R%T$V"X Z\]_aceghjl n p rsuwyzwwtlq`,nU;jIKg!+0?*+,--.//01 2 2 3 4 5 567889:;;<==>@CEHJLOQSUXZ\^ ` b d f h j l npr}tzvxxuzs{p}nljgeca^\ZXVTRPNLJHFDB@><:875 3 1 /!.!,"*")"'#%###"$ $%%%&&&'''(       !#"""! !    "$&)+-0257:<?ADFILNQTWY\_behknqt }w zz x} u s p n khec`]ZXUROLIFCBBBBBBBBBBBB B B B B B B BBBBBBBBBBBBBBBBBBBBBBBBB B B!B"B#B"3C S b ~rn]M=.   "$&(*,.13579;>@BDFHKMOQSUXZ\^`ce}g{iykwnupsrqtnvlyj{h}fdb_][YWUSPNLJHFCA?=;96420.+)'%# hhhhhi i i iiiii~j|jzjxjvjt jr"jp$jn&kl'kj)kh+kf-kd/kb1k`3k^5l\6lZ8lX:lVlR@lPBlNCmLEmJGmHImFKmDMmBOm@Pm>Rn8<::<9>7@5B3C2E0G.I,K+M)O'Q%R$T"V XZ\^_acegij l n prtuwyvyrnob,lV;iJKe>Zb2j^%{ZW P>+.=-../0112344 5 6 6 7 8 99:;<<=>??@AADFHKMORTVXZ]_a c e g i k m o qs}uzwxxuzs|p~nljgeca^\ZXVTRPNLJHFDB@><:87531 / .!,!*!)"'"%###"# $$$%%%&&'''       !""!!!  "%'),.0358:=?BDGJLORTWZ]`behknq t }w zz x} u s p nkhfc`]ZXUROLIFEEEEEEEEEEEE E E E E E E EEEEEEEEEEEEEEEEEEEEEEEEEE E!E"E"E#E"3C S b ro^N>/   "$&(*,.13579;>@BDFHKMOQSUXZ\^`ce~g|izkxnvptrrtpvmyk{i}geca^\ZXVTQOMKIGDB@><:7531/,*(&$"ffffgg g g gggghh~h{hyhwhu hs"hq$io&im'ik)ii+ig-ie/ic1ia3j_5j]6j[8jY:jWjS@jQBkPCkNEkLGkJIkHKkFMkDOkBPl@Rl>Tl6<8::9<7>5@3B2D0E.G,I+K)M'O%Q$R"T VXZ\^_acegi j l nprtuwt{qpmd,jX;gLKc@Z`3j\'{XU P>+,;00122345567 8 8 9 : : ; <==>?@@ABBCDEGIKNPRUWY[]_bd f h j l n p r s }uzwxyu{s}pnljgeca^\ZXVTRPNLJHFDB@><:87531/ . , *!)!'"%"#""# #$$$%%%&&&'      !"!! !#%'*,/1368;=@BEHJMPRUXZ]`cfil o r u }x z{ x~ u s pnkhfc`]ZXUROLIHHHHHHHHHHHH H H H H H H HHHHHHHHHHHHHHHHHHHHHHHHHH H!H!H"H#H$H$H"3CS b r p`O?0    "$&(*,.13579;>@BDFHKMOQSUXZ\^`ceg}i{kynwpurstqvnyl{j}hfdb_][YWUSPNLJHFCA?=;96420.+)'%# dddeee e e eeeffff}f{fyfw fu"gs$gq&go'gm)gk+gi-gg/ge1hc3ha5h_6h]8h[:hYiU@iSBiQCiOEiMGiKIiIKiGMjEOjCPjBRj@Tj>Vj5<7:89:7<5>3@2B0D.F,G+I)K'M%O$Q"S TVXZ\^`aceg i k lnprtur}oqlf,hZ;eNKaBZ^5jZ){WSO >+*923445667899: ; ; < = > > ?@AABCCDEFFGHJLNQSUWZ\^`bdf h j l n p r t }v zxxzu|s}pnljgeca^\ZXVTRPNLJHFDB@><:87531/. , * )!'!%!#""" ###$$$%%&&&     !!!   !#&(*-/2469;>@CFHKMPSVX[^adgi l o r u }x z| x u spnkhfc`]ZXUROLKKKKKKKKKKKK K K K K K K KKKKKKKKKKKKKKKKKKKKKKKKKK K!K!K"K#K#K$K%K&K"3CSb r q aPA1!   "$&(*,.13579;>@BDFHKMOQSUXZ\^`ceg~i|kznxpvrttrvpym{k}igeca^\ZXVTQOMKIGDB@><:7531/,*(&$"bbcccc c c ccdddddd}d{ey ew"eu$es&eq'eo)em+ek-fi/fg1fe3fc5fa6f_8f]:f[gW@gUBgSCgQEgOGgMIgKKhIMhGOhEPhCRhATh?Vh=Xh;Zi9[i8]i6_i4ai2ci0ei.fi,hj*jj(lj&nj$pj"qj sjujwkykzk|k~kkkk l l llllljhge c a `^\ZXWUSQO N"L$J&H(G*E+C-A/@1>3<5:7997:5<3>2@0B.D,F+H)I'K%M$O"Q SUVXZ\^`ace g i klnprsp~msjh,f\;cPK`DZ\7jX*{UQM >+'65567789::;<<= > ? ? @ A B BCDDEFGGHIIJKMOQTVXZ]_acegi k m o q s u }w zy xzu|s~pnljgeca^\ZXVTRPNLJHFDB@><:87531/.,* ) '!%!#!"" ""##$$$%%%&      !!    "$&)+-02479<>ADFIKNQSVY\_adg j m p s v }y z| x uspnkhfc`][XURONNNNNNNNNNNN N N N N N N NNNNNNNNNNNNNNNNNNNNNNNNNN N N!N"N#N#N$N%N%N&N"3CSb r r bRB2#   "$&(*,.13579;>@BDFHKMOQSUXZ\^`cegi}k{nypwrutsvqyo{l}jhfdb`][YWUSPNLJHFCA?=;96420.+)'%# `aaaaa a a bbbbbbbbc}c{ cy"cw$cu&cs'cq)co+dm-dk/di1dg3de5dc6da8d_:e]eY@eWBeUCeSEeQGeOIfMKfKMfIOfGPfERfCTfAVg?Xg=Zg;[g9]g7_g5ag3cg2eh0fh.hh,jh*lh(nh&ph$qh"si uiwiyizi|i~iiijj j j jjjjjhgec a ` ^\ZXWUSQON L"J$H&G(E*C,A-@/>1<3:597795;3<2>0@.B,D+F)H'I%K$M"O QSUVXZ\^`bc e g ikmnprnkuhi,e^;aRK^FZZ9jV,{SOK >+%47889:;;<=>>?@@ A B C C D E EFGHHIJJKLMMNPRTWY[]_adfhjl n p r t u }w zy x{ u}spnljgeca^\ZXVTRPNLJHFDB@><:87531/.,*) ' % #!"! """###$$$%%            "$')+.0358:<?BDGILOQTWY\_be h k n q t w }z {} xuspnkhfc`][XURQQQQQQQQQQQQ Q Q Q Q Q Q QQQQQQQQQQQQQQQQQQQQQQQQQQ Q Q!Q"Q"Q#Q$Q%Q%Q&Q'Q'Q3CSbr s c SC3$   "$&(*,.13579;>@BDFHKMOQSUXZ\^`cegik|nzpxrvttvryp{m}kigeca^\ZXVTQOMKIGDB@><:7531/,*(&$!______ _ ` ```````aaa} a{"ay$aw&au'as)bq+bo-bm/bk1bi3bg5be6cc8ca:c_c[@cYBcWCcUEdSGdQIdOKdMMdKOdIPdGRdETeCVeAXe?Ze=[e;]e9_e7ae5cf3ef1ff/hf-jf+lf*nf(pf&qg$sg"ug wgygzg|g~ghhhhh h h hiiihgeca ` ^ \ZXWUSQONL J"H$G&E(C*A,@.>/<1:39577593;2=0>.@,B+D)F'H%J$K"M OQSUWXZ\^`b c e gikmnpmiwfk,c`;_TK\GZX;jU.{Q!MI>+#2::;<<=>??@AABCC D E F F G H HIJKKLMMNOPPQSUWZ\^`bdfhjlnp r t v }x zz x| u} spnljgeca^\ZXVTRPNLJHFDB@><:87531/.,*)'% # "! !!""###$$$%           #%'*,.1368;=@BEGJMORUWZ]`c e h k n q t w }z {}xuspnkhfc`][XUTTTTTTTTTTTT T T T T T T TTTTTTTTTTTTTTTTTTTTTTTTTTT T!T"T"T#T$T$T%T&T&T'T(T)TCSbru d T D4%   "$&(*,.13579;>@BDFHKMOQSUXZ\^`cegik}n{pyrwtuvsyq{o}ljhfdb`][YWUSPNLJHFCA?=;96420.+)'%# ]]]]]] ^ ^ ^^^^^^____ _}"_{$_y&`w'`u)`s+`q-`o/`m1`k3`i5ag6ae8ac:aaa]@a[BaYCbWEbUGbSIbQKbOMbMObKPbIRcGTcEVcCXcAZc?[c=]c;_d9ad7cd5ed3fd1hd/jd-ld+ne)pe'qe&se$ue"we yeze|f~fffffff g ggggggeca` ^ \ ZXWUSQONLJ H"G$E&C(A*@,>.<0:1937557392;0=.?,@+B)D'F%H$J"L MOQSUWYZ\^` b d egikmnkhxdm,aa;]UKZIZV=jS0{O#KG>+!0<==>?@@ABBCDDEFG G H I I J K LLMNNOPPQRSSTVXZ\_acegikmoqs u w }y zz x| u~ s pnljgeca^\ZXVTRPNLJHFDB@><:87531/.,*)'%# " !!!"""###$$        !#&(*-/1469;>@CEHJMPRUX[]` c f i l o r u x }{{~xvspnkhfc`][XWWWWWWWWWWWW W W W W W W WWWWWWWWWWWWWWWWWWWWWWWWWWW W!W!W"W#W#W$W%W&W&W'W(W(~W)}WCSbrv e U E5&   "$&(*,.13579;>@BDFHKMOQSUXZ\^`cegikn|pzrxtvvtyr{p}mkigeca^\ZXVTROMKIGDB@><:7531/,*(&$![[[[[\ \ \ \\\\]]]]]] ]~"]|$^z&^x'^v)^t+^r-^p/^n1^l3_j5_h6_f8_d:_b<_`>_^@`\B`ZC`XE`VG`TI`RK`QM`OOaMPaKRaITaGVaEXaCZaA[a?]b=_b;ab9cb7eb5fb3hb1jb/lc-nc+pc)qc'sc%uc#wc!yc zd|d~ddddddee e eeeeeeca`^ \ ZXWUSQONLJH!G"E$C&A(@*>,<.:092735537290;.=,?+@)B'D%F$H"J LMOQSUWYZ\^ ` b degiklifzco,_c;\WKXKZT?jQ2{M%IE >+.>?@@ABCCDEEFGHHIJ J K L L M N OOPQQRSSTUVVWY[]_adfhjlnprtu w }y z{ x} u s p nljgeca^\ZXVTRPNLJHFDB@><:87531/.,*)'%#"  !!!""###$        "$&(+-/2479<>ACFHKNPSVY[^ a d g j l o r uy}|{xvspnkhfc`][ZZZZZZZZZZZZ Z Z Z Z Z Z Z ZZZZZZZZZZZZZZZZZZZZZZZZZZ Z Z!Z"Z#Z#Z$Z%Z%~Z&}Z'}Z'|Z({Z)zZ*zZ*yZSbrwf V F 6'    "$&(*,.13579;>@BDFHKMOQSUXZ\^`cegikn~p{rytwvuys{q}oljhfdb`][YWUSPNLJHFCA?=;964 2 0 . + ) ' % # YYYYZZ Z Z ZZZ[[[[[[[ ["\~$\|&\z'\x)\v+\t-\r/]p1]n3]l5]j6]h8]f:]d<]b>^`@^^B^\C^ZE^XG^VI^TK^RM_PO_NP_LR_JT_HV_FX_EZ`C[`A]`?_`=a`;c`9e`7f`5ha3ja1la/na-pa+qa)sa'ua%wb#yb!zb|b~bbbbccccc c ccdddca`^\ Z XWUSQONLJHG!E#C$A&@(>*<,:.907253352709.;,=+?)A'B%D$F"H JLNOQSUWY[\ ^ ` bdfgikgd|aq,]e;ZYKVMZSAjO4{K'GC >+,AABCDDEFFGHHIJKKLM M N O O P Q RRSTTUVVWXYYZ\^`bdfhjlnprtvx }z z| x~ u s p n l jgeca^\ZXVTRPNLJHFDB@><:87531/.,*)'%#"   !!!"""##         "$')+.0257:<?ADFILNQTVY \ _ b d g j m p svy}|{xvspnkhfc`]]]]]]]]]]]]]] ] ] ] ] ] ] ]]]]]]]]]]]]]]]]]]]]]]]]]] ] ]!]"]"~]#}]$}]$|]%{]&{]'z]'y](x])x])w]*v]+v]+u]brxgW G 7 (    "$&(*,.13579;>@BDFHKMOQSUXZ\^`cegiknp|rztxvvyt{r}pnkigeca^\ZXVT R O M K I G E B @ > < : 7 5 3 1 / , * ( & $ !WWXXXX X X XXYYYYYYYZ Z"Z$Z~&Z|'Zz)Zx+Zv-[t/[r1[p3[n5[l6[j8[h:[f<\d>\b@\`B\^C\\E\ZG\XI]VK]TM]RO]PP]NR]LT]JV]HX^FZ^D[^B]^@_^>a^(<*:,9.7052342507.9,;+=)?'A%C$D"F HJLNPQSUWY[ \ ^ `bdfgifb~_r,[g;X[KTOZQCjM6{I)EA= +*CDEEFGGHIIJKKLMNNOP P Q R R S T UUVWWXYYZ[[\]_acegikmoqsuwy}{ z| x~ u s p n l j geca^\ZXVTRPNLJHFDB@><:87531/.,*)'%#"    !!"""#         #%'*,.1358:=?BDGJLORTW Z \ _ b e h k n qtwz}}{xvspnkifc`````````````` ` ` ` ` ` ` ``````````````````````````~` }`!}`"|`"{`#{`$z`$y`%y`&x`&w`'v`(v`(u`)t`*t`+s`+r`,r`bryiX H 9 )     "$&(*,.13579;>@BDFHKMOQSUXZ\^`cegiknp~r{tyvwyu{s} q o l j h f d b ` ] [ Y W U S P N L J H F C A ? = ; 9 6 4 2 0 . + ) ' % #UVVVVV V V VWWWWWWWXX X"X$X&X~'X|)Xz+Yx-Yv/Yt1Yr3Yp5Yn6Yl8Zj:ZhZd@ZbBZ`CZ^EZ\G[ZI[XK[VM[TO[RP[PR[NT\LV\JX\HZ\F[\D]\B_\@a\>c]'<(:*9,7.50322406.7,9+;)='?%A$C"E FHJLNPQSUWY [ ] ^`bdfgda]t,Zi;V]KRQZODjK8{G+C?; +(EFGHHIJJKLLMNNOPQQRS S T U U V W WXYZZ[\\]^^_`adfhjlnprtvwy}{z} x u s p n l j g eca^\ZXVTRPNLJHFDB@><:87531/.,*)'%#"    !!!""         !#%(*,/1468;=@BEHJMORU X Z ] ` c f h k nqtwz}}{xvspnkifcccccccccccccc c c c c c c cccccccccccccccccccccc~c}c}c|c{c {c!zc!yc"yc#xc#wc$wc%vc%uc&tc'tc(sc(rc)rc*qc*pc+pc,oc,nc-ncrzjYI : *     "$&(*,.13579;>@BDFHKMOQSUXZ\^` c e g i k n p r |t zv xy v{ t} r p n k i g e c a ^ \ Z X V T R O M K I G E B @ > < : 7 5 3 1 / , * ( & $TTTTTT T U UUUUUUUVVV V"V$V&V'W~)W|+Wz-Wx/Wv1Wt3Wr5Wp6Xn8Xl:XjXf@XdBXbCY`EY^GY\IYZKYXMYVOYTPYRRZPTZNVZLXZJZZH[ZF]ZD_ZBa[@c[>e[%<':)9*7,5.302204.6,8+9);'=%?$A"C EFHJLNPRSUW Y [ ]^`bdeb_[v,Xj;T_KQSZMFjI:{E-A =9 +&HHIJJKLMMNOOPQQRSSTUV V W X X Y Z Z[\\]^^_`aabcdfhjlnprtvxz}|z~x u s p n l j g e ca^\ZXVTRPNLJHFDB@><:87531/.,*)'%#"   !!!"        !$&(+-/2479;>@CFHKMPS U X [ ^ ` c f i lorux{}~{xvsqnkiffffffffffffff f f f f f f ffffffffffffffffff~f~f}f|f{f{fzfyfyf xf wf!wf"vf#uf#uf$tf%sf%sf&rf'qf'pf(pf)of)nf*nf+mf,lf,lf-kf.jfr{k[K; +     "$&(*,.13579;>@B D F H K M O Q S U X Z \ ^ ` c e g i k n p r ~t {v yy w{ u} s q o l j h f d b ` ] [ Y W U S P N L J H F C A ? = ; 9 6 4 2 0 . + ) '%RRRRRR S S SSSSSSTTTT T"T$T&U'U)U~+U|-Uz/Ux1Uu3Us5Vq6Vo8Vm:VkVh@VfBWdCWbEW`GW^IW\KWZMWXOWVPXTRXRTXPVXNXXLZXJ[XH]YF_YDaYBcY@eY>fY#<%:'9)7+5,3.2002.4,6+8):';%=$?"A CEGHJLNPRTU W Y []_`bd`]Zx,Vl;RaKOTZKHjG<{C/?";7+$JKKLMMNOPPQRRSTTUVVWX X Y Z Z [ \ ] ]^__`aabccdeegikmoqsuwy{}|z~xu s p n l j g e c a^\ZXVTRPNLJHFDB@><:87531/.,*)'%#"    !!         "$')+-0257:<>ADFIKNQ S V Y [ ^ a d g jmpsvy|}{xvsqnkihhhhhhhhhhhhh h h h h h h hhhhhhhhhhhhhh~h~h}h|h|h{hzhzhyhxhwhwhvh uh uh!th"sh"sh#rh$qh$qh%ph&oh&oh'nh(mh)mh)lh*kh+jh+jh,ih-hh-hh.gh/fh|l\L< ,     "$ & ( * , . 1 3 5 7 9 ; > @ B D F H K M O Q S U X Z \ ^ ` c e g i k n p r t }v zy x{ v} t r p n k i g e c a _ \ Z X V T R O M K I GEB@><:7531/,*(&PPPPPQ Q Q QQQQRRRRRR R"R$S&S'S)S+S}-S{/Sy1Tw3Tu5Ts6Tq8To:TmTi@UgBUeCUcEUaGU_IU]KU[MVYOVWPVURVSTVRVVPXVNZVL[WJ]WH_WFaWDcWBeW@fW>hX!<#:%9'7)5+3-2.00.2,4+6)8':%;$="? ACEGIJLNPRT U W Y[]_ab_[Xz,Tn;QbKMVZIJjE={A1=$95+"LMNNOPPQRRSTTUVVWXYYZ[ [ \ ] ] ^ _ _ `aabccdeefghhjlnprtvxy{}}zxus p n l j g e c a ^\ZXVTRPNLJHFDB@><:87531/.,*)'%#"    !         #%'),.0358:=?BDGILO Q T W Y \ _ b e gjmpsvy|}{xvsqnkkkkkkkkkkkkkk k k k k k k kkkkkkkkkk~k~k}k|k|k{kzkzkykxkxkwkvkvkuktksksk rk!qk"qk"pk#ok$ok$nk%mk&mk&lk'kk(kk(jk)ik*ik*hk+gk,gk,fk-ek.dk.dk/ck0bkm]M=-              " $ & ( * , . 1 3 5 7 9 ; > @ B D F H K M O Q S U X Z \ ^ ` c e g i k n p r t ~v {y y{ w} u s q o l j h f db`][YWUSPNLJHFCA?=;96420.+)'NNNNOO O O OOOPPPPPPP P"Q$Q&Q'Q)Q+Q-Q}/R{1Ry3Rw5Ru6Rs8Rq:RoSk@SiBSgCSeEScGSaIS_KT]MT[OTYPTWRTUTTSVTQXUOZUM[UK]UI_UHaUFcUDeUBfV@hV>jV<:87531/.,*)'%#"            !#%(*,/1368;=@BEGJ L O R T W Z ] _ b ehknqtwz}}{xvsqnnnnnnnnnnnnnn n n n n n n nnnnnn~n~n}n|n|n{nznznynxnxnwnvnvnuntntnsnrnrnqnpn pn!on!nn"nn#mn#ln$kn%kn%jn&in'in'hn(gn)gn)fn*en+en,dn,cn-cn.bn.an/an0`n0_nn^N>/                " $ & ( * , . 1 3 5 7 9 ; > @ B D F H K M O Q S U X Z \ ^ ` c e g i k n p rtv}yz{x}vtrpnkigeca_\ZXVTROMKIGEB@><:7531/,*(LLLMMM M M MMNNNNNNNO O"O$O&O'O)O+O-P/P}1P{3Py5Pw6Pu8Ps:QqQm@QkBQiCQgEQeGRcIRaKR_MR]OR[PRYRRWTRUVSSXSQZSO[SM]SK_SIaSGcTEeTCfTAhT?jT>lT< :!9#7%5'3)2+0-./,0+2)4'6%8$:"< >?ACEGIKLNP R T VWY[]^[XT},Qr;MfKIZZENjAA{=59'51 +QQRSSTUUVWWXYYZ[[\]^^_`` a b b c d d e ffghhijjkllmnoqsuwy{}}~zxuspn l j g e c a ^ \ Z XVTRPNLJHFDB@><:87531/.,*)'%#"          !$&(*-/2469;>@CEH J M P R U X Z ] ` cfiknqtwz~}{xvsqqqqqqqqqqqqqq q q q q q q qq~q~q}q|q|q{qzqzqyqxqxqwqvqvquqtqtqsqrqrqqqpqpqoqnqnq mq!lq!lq"kq#jq#jq$iq%hq%hq&gq'fq'fq(eq)dq)dq*cq+bq+bq,aq-`q-`q._q/^q/]q0]q1\q1[q_O?0                " $ & ( * , . 1 3 5 7 9 ; > @ B D F H K M O Q S UXZ\^`cegiknprtv~y{{y}wusqomjhfdb`][YWUSPNLJHFCA?=;96420.+)JJKKKK K K KLLLLLLLMM M"M$M&M'M)N+N-N/N1N}3N{5Ny6Nw8Ou:OsOo@OmBOkCOiEPgGPeIPcKPaMP_OP]PP[RPYTQWVQUXQSZQQ[QO]QM_QKaRIcRGeREfRChRAjR?lR=nR;pS9qS8sS6uS4wS2yS0zS.|T,~T*T(T&T$T"T TUUUUUUUVV V V VVVVWUSQO N L JHGECA@><: 9"7#5%3'2)0+.-,/+1)2'4%6$8": <>@ACEGIKMN P R TVXY[]YVR,Ot;KhKG\ZCPj@C{<67)3/+ STTUVVWXXYZZ[\\]^^_``abbc d d e f f g h hijjkllmnnopprtvxy{}}zxuspnlj g e c a ^ \ Z X VTRPNLJHFDB@><:87531/.,*)'%#"          "$&)+-02479<>ACF H K N P S V X [ ^ acfilorux{~}{xvssssssssssssss s s s s s ~s }s}s|s{s{szsysysxswswsvsusustsssrsrsqspspsosnsnsmslslsks js js!is"hs"hs#gs$fs$fs%es&ds&ds'cs(bs(bs)as*`s*`s+_s,^s,^s-]s.\s.\s/[s0Zs0Zs1Ys2Xs2XsP@1!               " $ & ( * , . 1 3 5 79;>@BDFHKMOQSUXZ\^`cegiknprtvy}{z}xvtrpnkigeca_\ZXVTROMKIGEB@><:7531/,*HIIIII I I JJJJJJJKKK K"K$K&K'L)L+L-L/L1L3L}5M{6My8Mw:MuMq@MoBMmCNkENiGNgINeKNcMNaON_PO]RO[TOYVOWXOUZOS[OQ]OO_PMaPKcPIePGfPEhPCjPAlQ?nQ=pQ;qQ9sQ7uQ5wQ3yQ2zR0|R.~R,R*R(R&R$S"S SSSSSSTTTT T T TUUUUSQON L J HGECA@><:9 7"5$3%2'0).+,-+/)1'3%4$6"8 :<>@ACEGIKM N P RTVXZ[WTP,Mu;IjKE^ZBRj>E{:86+1-) UVVWXXYZZ[\\]^^_``abbcddef f g h h i j jkllmnnoppqrrstvxz|~}zxuspnljg e c a ^ \ Z X V TRPNLJHFDB@><:87531/.,*)'%#"          "%'),.0357:<?AD F I L N Q S V Y \^adgjmpsvy|}{xvvvvvvvvvvvvvv v ~v }v }v |v {v {vzvyvyvxvwvwvvvuvuvtvsvsvrvqvqvpvovovnvmvmvlvkvkvjviviv hv gv!gv"fv"ev#ev$dv$cv%cv&bv&av'av(`v(_v)_v*^v*]v+]v,\v,[v-[v.Zv.Yv/Yv0Xv0Wv1Wv2Vv2Uv3UvQA2#           "$&(*,.13579;>@BDFHKMOQSUXZ\^`cegiknprtvy~{|}ywusqomjhfdb`][YWUSPNLJHFCA?=;96420.+GGGGGG G H HHHHHHIIII I"I$I&J'J)J+J-J/J1J3K~5K|6Kz8Kx:KvKr@KpBLnCLlELjGLhILfKLdMLcOMaPM_RM]TM[VMYXMWZMU[NS]NQ_NOaNMcNKeNIfNGhNEjOClOAnO?pO=qO;sO9uO7wP5yP3zP1|P/~P-P,P*P(Q&Q$Q"Q QQQRRRRRRR R S SSSSSQONL J H GECA@><:97 5"3$2&0'.),++-)/'1%3$5"6 8:<>@BCEGIK M O PRTVXYVRO,Kw;GlKD`Z@Sj<:87531/.,*)'%#"          !#%'*,.1368:=?B D G J L O Q T W Y\_begjmpsvy|}{yyyyyyyyyyy~y}y}y |y {y {y zy yy yy xy wywyvyuyuytysysyryqyqypyoyoynymymylykykyjyiyiyhygygyfyey ey!dy!cy"cy#by#by$ay%`y%`y&_y'^y'^y(]y)\y)\y*[y+Zy+Zy,Yy-Xy-Xy.Wy/Vy/Vy0Uy1Ty1Ty2Sy3Ry3Ry4QyB3$  "$&(*,.13579;>@BDFHKMOQSUXZ\^`cegiknprtvy{}}zxvtrpnkigeca_\ZXVTROMKIGEB@><:7531/,EEEEEE F F FFFFFGGGGG G"G$H&H'H)H+H-H/H1I3I5I~6I|8Iz:IxJt@JrBJpCJnEJlGJjIJhKKfMKdOKbPK`RK^TK\VKZXKXZLV[LT]LS_LQaLOcLMeLKfMIhMGjMElMCnMApM?qM=sM;uN9wN7yN5zN3|N1~N/N-O+O)O(O&O$O"O PPPPPPPPQQ Q Q QQQQQONLJ H G ECA@><:975 3"2$0&.(,)++)-'/%1$3"5 78:<>@BDEGI K M OPRTVWTPM,Iy;FmKBbZ>Uj:I{6<2/-")%YZ[[\]]^__`aabccdeeffghhijjk l l m n n o ppqrrsttuvvwxxz{}}zxuspnljgec a ^ \ Z X V T R PNLJHFDB@><:87531/.,*)'%#"         !#&(*-/1469;=@ B E H J M O R U WZ]`behknqtwz}}{{{{{{{~{}{}{|{{{{{z{ y{ y{ x{ w{ w{ v{ v{ u{t{t{s{r{r{q{p{p{o{n{n{m{l{l{k{j{j{i{h{h{g{f{f{e{d{d{c{ b{!b{!a{"`{#`{#_{$^{%^{%]{&\{&\{'[{(Z{(Z{)Y{*X{*X{+W{,W{,V{-U{.U{.T{/S{0S{0R{1Q{2Q{2P{3O{4O{4N{5M{4%  "$&(*,.13579;>@BDFHKMOQSUXZ\^`cegiknprtvy{~}|ywusqomjhfdb`][YWUSQNLJHFCA?=;96420.CCCCDD D D DDDEEEEEEE E"F$F&F'F)F+F-F/G1G3G5G6G~8G|:GzHv@HtBHrCHpEHnGHlIIjKIhMIfOIdPIbRI`TI^VJ\XJZZJX[JV]JT_JRaJPcJNeKLfKJhKIjKGlKEnKCpKAqL?sL=uL;wL9yL7zL5|L3~M1M/M-M+M)M'M%M#N"N NNNNNOOOOO O O OPPPONLJH G E CA@><:9753 2"0$.&,(+*)+'-%/$1"3 578:<>@BDEG I K MOQRTVROK,G{;DoK@cZ01+$'#[\]]^__`aabccdeefgghiijjkllmn n o p p q r rsttuvvwxxyzz{|~}zxuspnljgeca ^ \ Z X V T R P NLJHFDB@><:87531/.,*)'%#"         "$&)+-02479<> @ C F H K M P S UX[]`cfilnqtwz~~~~~~}~}~|~|~{~z~z~y~x~x~ w~ v~ v~ u~ t~ t~ s~ r~r~q~p~p~o~n~n~m~l~l~k~j~j~i~h~h~g~g~f~e~e~d~c~c~b~a~a~ `~ _~!_~"^~"]~#]~$\~$[~%[~&Z~&Y~'Y~(X~(W~)W~*V~*U~+U~,T~,S~-S~.R~.R~/Q~/P~0P~1O~1N~2N~3M~3L~4L~5K~5J~5&  "$&(*,.13579;>@BDFHKMOQSUXZ\^`cegiknprtvy{}}zxvtrpnkigeca_\ZXVTROMKIp~p~q~r~r ~s ~t ~t ~u ~v ~v ~w ~AAABBB B B BBCCCCCCCD D"D$D&D'D)D+D-E/E1E3E5E6E8E~:F|Fx@FvBFtCFrEFpGGnIGlKGjMGhOGfPGdRGbTH`VH^XH\ZHZ[HX]HV_HTaIRcIPeINfILhIJjIHlIFnIDpJBqJAsJ?uJ=wJ;yJ9zJ7|K5~K3K1K/K-K+K)L'L%L#L!LLLLMMMMMMM N NNNNNNLJHG E C A@><:97532 0".$,&+()*',%-$/"1 3579:<>@BDF G I KMOQSTPMI,F};BqK>eZ:Yj6M{2@.3)&%! ] ^__`aabccdeefgghiijkkllmnnopp q r r s t t uvvwxxyzz{{|}}}zxuspnljgeca^ \ Z X V T R P N LJHFDB@><:87531/.,*)'%#"          "%')+.0257: < ? A D F I K N P SVY[^adfilorux{~}||{zzyxxwvvu t t s r r q q poonmmlkkjiihggfeedccbaa``_^ ^ ]!\"\"[#Z$Z$Y%X%X&W'V'V(U)T)T*S+R+R,Q-Q-P.O/O/N0M1M1L2K3K3J4I4I5H6G6G'   "$&(*,.13579;>@BDFHKMOQSUXZ\^`cegiknprtvy{}~|ywusqomjhfghiijkklmmnoop q q r s s t t uvvw??@@@@ @ @ @AAAAAAABB B"B$B&B'B)C+C-C/C1C3C5C6D8D:D~Dz@DxBDvCDtEErGEpIEnKElMEjOEhPEfRFdTFbVF`XF^ZF\[FZ]FX_GVaGTcGReGPfGNhGLjGJlHHnHFpHDqHBsH@uH>wH<:975320 .",$+&)('*%,$."/ 13579;<>@BD F H IKMOQROKG,D;@sK<:87531/.,*)'%#"          !#%'*,.1358 : = ? B D G I L N QTVY\_adgjmpsvy{zzyxxwvvuutss r q q p o o n mmlkkjiihhgffeddcbba``_^^]\\[ [!Z!Y"Y#X#W$W%V%U&U'T'S(S)R)Q*Q*P+P,O,N-N.M.L/L0K0J1J2I2H3H4G4F5F6E6D7D7C   "$&(*,.13579;>@BDFHKMOQSUXZ\^`cegiknprtvy{}``abbcddeffghhiijkklmm n o o p q q r sstuuvvw=>>>>> > > ???????@@@ @"@$@&@'A)A+A-A/A1A3A5B6B8B:BB|@BzBCxCCvECtGCrICpKCnMClODjPDhRDfTDdVDbXD`ZD^[D\]EZ_EXaEVcETeERfEPhENjFLlFJnFHpFFqFDsFBuF@wG>yG<:975320.!,"+$)&'(%*$,". /13579;=>@B D F HIKMOPMIF,B;>uK:iZ6]j2Q{.D*7&*! b{!b{ c{ c{d{e{e{f{g{g{h{i{i{j{k{k{l{m{m{n{n{o{p{p{q{r{r{s{t{t{u{ v{ v{ w{ x{ x{ y{ y{ z{{{{{|{}{}{~{{{{{{{{zxuspnljgeca^\Z X V T R P N L J H FDB@><:87531/.,*)'%#"         !#&(*,/146 8 ; = @ B E G J L ORTWZ\_behjmpsvyxwwvuutssrqqp o o n n m l l kjjihhgffeddccbaa`__^]]\[[ZZY X!X!W"V#V#U$T$T%S&R&R'Q(P(P)O*O*N+M,M,L-K.K.J/I/I0H1G1G2F3E3E4D5D5C6B7B7A8@   "$&(*,.13579;>@BDFHKMOQSUXZ\^`X!X YYZ[[\]]^__`aabccddeffghhijjk l l m m n o o pqqrsstuuvww<<<<<< < = ======>>>> >">$>&?'?)?+?-?/?1?3@5@6@8@:@<@>@}@A{BAyCAwEAuGAsIAqKAoMBmOBkPBiRBgTBeVBcXBaZC`[C^]C\_CZaCXcCVeCTfDRhDPjDNlDLnDJpDHqDFsDDuEBwE@yE>zE<|E:~E8E6F4F2F0F/F-F+F)G'G%G#G!GGGHHHHHHHH I IIIIIHGECA @ ><:975320.,!+")$'&%($*", .013579;=>@ B D FHJKMOKHD,@;<:87531/.,*)'%#"        "$&(+-/24 6 9 ; > @ C E H J MPRUXZ]`cehknqtvuutssrrqpponn m l l k j j i ihggfeedccbaa``_^^]\\[ZZYXXWW V U!U"T"S#S$R$Q%Q&P&O'O(N(N)M)L*L+K+J,J-I-H.H/G/F0F1E1E2D2C3C4B4A5A6@6?7?8>8=9=   "$&(*,.13579;>@BDO&P&Q%Q$R$S#S"T"U!U!V VWXXYZZ[\\]^^__`aabccdeefgghh i j j k l l m nnoppqqrsstuuvvv:::::: ; ; ;;;;;<<<<< <"<$=&='=)=+=-=/=1>3>5>6>8>:><>>?@?}B?{C?yE?wG?uI?sK@qM@oO@mP@kR@iT@gV@eXAcZAa[A_]A]_A[aAYcAWeBUfBThBRjBPlBNnBLpBJqCHsCFuCDwCByC@zC>|C<~D:D8D6D4D2D0D.D,E+E)E'E%E#E!EFFFFFFFGGG G GGGGHGECA@ > <:975320.,+!)#'$%&$("* ,.023579;=? @ B DFHJLMIFB,>;:xK7mZ3aj.T{*H&;".  fv"fv!gv gv hvivivjvkvkvlvmvmvnvnvovpvpvqvrvrvsvtvtvuvvvvvwvwvxvyvyvzv {v {v |v }v }v ~v ~v vvvvvvvvvvvvvvuspnljgeca^\ZXV T R P N L J H F D B@><:87531/.,*)'%#"          "$')+.02 5 7 9 < > A C F H KNPSUX[^`cfilortsrrqpponnmmlk k j i i h g g ffeddcbba``_^^]]\[[ZYYXWWVVUT T S!R"R"Q#P#P$O%N%N&M'M'L(K)K)J*I+I+H,G,G-F.F.E/D0D0C1B2B2A3@3@4?5>5>6=7=7<8;9;9::9  "$&(G,H+I+I*J)K)K(L'L'M&N&N%O$P$P#Q"R"R!S S TUUVWWXYYZZ[\\]^^_``abbccdeef g g h i i j j kllmnnoppqrrsstttttt888889 9 9 9999:::::: :";$;&;';);+;-=@=B=}C={E=yG>wI>uK>sM>qO>oP>mR>kT?iV?gX?eZ?c[?a]?__?]a?[c@Ye@Wf@Uh@Sj@Ql@On@MpAKqAJsAHuAFwADyABzA@|B>~B < :975320.,+)!'#%%$&"( *,.024579;= ? A BDFHJKHD@,<;9zK5oZ1cj-V{(J$= 0"ht"ht"it!it jt ktktltmtmtntototptptqtrtrtstttttutvtvtwtwtxtytytzt{t{t|t}t }t ~t ~t t t t t ttttttttttttttspnljgeca^\ZXVTR P N L J H F D B @><:87531/.,*)'%#"         !#%'),.0 3 5 8 : < ? A D FIKNQSVY[^adgiloqqpoonmmlkkjji h h g f f e d dccbaa`__^]]\\[ZZYXXWVVUUTSSRQ Q!P!O"O#N#N$M%L%L&K&J'J(I(H)H*G*G+F,E,E-D.C.C/B/A0A1@1@2?3>3>4=5<5<6;6:7:898998:7:7 ?2@1A0A0B/C.C.D-D,E,F+F+G*H)H)I(J'J'K&K%L%M$M#N#O"O"P!Q Q RRSTTUVVWXXYYZ[[\]]^__``abbcd d e f f g g h iijkklmmnnoppqqqqqqqqqqq666677 7 7 7778888889 9"9$9&9'9)9+:-:/:1:3:5:6:8;:;<;>;@;B;C;}E<{G_a>]c>[e>Yf>Wh>Uj>Sl?Qn?Op?Mq?Ks?Iu?Gw?Ey@Dz@B|@@~@>@<@:@8@6A4A2A0A.A,A*A(B&B$B#B!BBBCCCCCCC D D DDDDDCA@>< : 975320.,+)'!%#$%"' (*,.024679; = ? ABDFHIFB>,;;7|K3pZ/dj+X{&L"?2$iq#jq"kq!kq!lq mq mqnqoqoqpqpqqqrqrqsqtqtququqvqwqwqxqyqyqzq{q{q|q|q}q~q~qq q q q q q q q qqqqqqqqqqqqqqpnljgeca^\ZXVTRP N L J H F D B @ ><:87531/.,*)'%#"        !#%(*,/ 1 3 6 8 ; = ? B DGILOQTWY\_bdgjmonmmllkjjihhgg f e e d c c b aa``_^^]\\[ZZYYXWWVUUTTSRRQPPO N!N!M"M#L#K$K$J%I&I&H'G(G(F)F)E*D+D+C,B-B-A.A/@/?0?0>1=2=2<3;4;4:5:69687877869695:4;4;3<3<2=1>1>0?/@/@.A.B-B,C,C+D*E*E)F(G(G'H'I&I%J%J$K#L#L"M!N!N O OPQQRSSTUUVVWXXYZZ[\\]]^__`aa b b c d d e f fghhiijkklmmnooooooooooooooo444555 5 5 5666666677 7"7$7&7'7)8+8-8/81838586989:9<9>9@9B9C:E:}G:{I:yK:wM:uO:sP;qR;oT;mV;kX;iZ;g[;e]Gy>Ez>C|>A~>?>=>< : 9 75320.,+)'%!$#"% ')*,.024679 ; = ?ACDFHD@=,9;5~K1rZ-fj)Z{$N A4& ko#lo#mo"mo!no!oo oopopoqororosototououovowowoxoyoyozo{o{o|o|o}o~o~oooooo o o o o o o o oooooooooooooonljgeca^\ZXVTRPN L J H F D B @ > <:87531/.,*)'%#"       "$&(+ - / 2 4 6 9 ; > @ BEGJMORTWZ]_behkllkjjiihggfeed d c b b a ` ` _^^]]\[[ZYYXXWVVUTTSSRQQPOONMM L L!K"J"J#I$H$H%G&G&F'E'E(D)C)C*B+B+A,@,@-?.>.>/=0<0<1;1;2:3939485757667675848493:2:2;1<0<0=/=/>.?-?-@,A+A+B*B*C)D(D(E'F&F&G%H%H$I#I#J"K!K!L MMNNOPPQRRSTTUUVWWXYYZZ[\\]^^_ _ ` a a b c c deeffghhijjkklmmmmmmmmmmmmmmm m m m223333 3 3 4444444555 5"5$5&5'6)6+6-6/61636576787:7<7>7@7B8C8E8~G8|I8zK8xM8vO9tP9rR9qT9oV9mX9kZ9i[:g]:e_:ca:ac:_e:]f:[h;Yj;Wl;Un;Sp;Qq;Os;Mu0>.>,>*>(>&>$?"? ?????@@@@@ @ @ AAAAA@><: 9 7 5320.,+)'%$!"# %')+,.02468 9 ; =?ACEFB?;,7;3K/tZ+hj'\{#OC6( mm$nm#om"om"pm!pm!qm rmrmsmtmtmumumvmwmwmxmymymzmzm{m|m|m}m~m~mmmmmmmmmm m m m m m m m mmmmmmmmmmmmmmljgeca^\ZXVTRPNL J H F D B @ > < : 87531/.,*)'%#"        "$') + - 0 2 4 7 9 < > ACFHKMPRUXZ]`cfhjiihggffeddcbba a ` _ _ ^ ] ]\\[ZZYXXWWVUUTSSRRQPPONNMMLKK J I!I"H"H#G#F$F%E%D&D'C'B(B(A)A*@*?+?,>,=-=-<.,>+?+@*@)A)B(B(C'C&D&E%E$F$G#G#H"H!I!J JKLLMMNOOPQQRRSTTUVVWXXYYZ[[\] ] ^ ^ _ ` ` a bbccdeefgghhijjjjjjjjjjjjjjjj j j j j j j j011111 1 2 2222223333 3"3$3&4'4)4+4-4/41435556585:5<5>6@6B6C6E6G6~I6|K7zM7xO7vP7tR7rT7pV7nX8lZ8j[8h]8f_8da8bc8`e9_f9]h9[j9Yl9Wn9Up9Sq:Qs:Ou:Mw:Ky:Iz:G|:E~;C;A;?;=;;;9;7<5<3<2<0<.<,<*=(=&=$="= ===>>>>>>> ? ? ?????><:9 7 5 320.,+)'%$"! #%')+-.0246 8 : ;=?ACDA=9,5;1K-vZ)jj%^{!QE8* oj$pj#pj#qj"rj"rj!sj tj tjujujvjwjwjxjyjyjzjzj{j|j|j}j~j~jjjjjjjjjjjjjj j j j j j j j jjjjjjjjjjjjjjjgeca^\ZXVTRPNLJ H F D B @ > < : 8 7531/.,*)'%#"        #%' ) , . 0 3 5 7 : < ?ADFIKNPSVX[^acfhgffeedccbaa``_ ^ ^ ] \ \ [ [ ZYYXWWVVUTTSRRQQPOONMMLLKJJIH H G!G!F"E#E#D$C%C%B&B&A'@(@(?)>*>*=+=+<,;-;-:.9/9/808071626253544435352617170809/9.:.:-;,<,<+=+=*>)?)?(@'A'A&B&B%C$D$D#E"F"F!G!G HIIJKKLLMNNOPPQQRSSTUUVVWXXYZZ [ [ \ ] ] ^ _ _``abbcddeefgghhhhhhhhhhhhhhh h h h h h h h hhhh////// 0 0 0000011111 1"1$2&2'2)2+2-2/31333536383:3<4>4@4B4C4E4G4I5~K5|M5zO5xP5vR5tT5rV6pX6nZ6l[6j]6h_6fa6dc7be7`f7^h7\j7Zl7Xn7Vp8Tq8Ss8Qu8Ow8My8Kz8I|9G~9E9C9A9?9=9;:9:7:5:3:1:/:.;,;*;(;&;$;"; <<<<<<<=== = = ==>>><:97 5 3 20.,+)'%$" !#%')+-.024 6 8 :;=?AB?;7,3;/K+xZ'lj#`{SG:, qh%rh$rh#sh#th"th!uh!uh vh whwhxhyhyhzhzh{h|h|h}h}h~hhhhhhhhhhhhhhhhhh h h h h h h h hhhhhhhhhhhhhhgeca^\ZXVTRPNLJH F D B @ > < : 8 7 531/.,*)'%#"      !#% ( * , . 1 3 5 8 : =?BDGILNQTVY\^adeedccbba``__^]] \ [ [ Z Z Y X XWVVUUTSSRQQPPONNMMLKKJIIHHGFF E!D!D"C#C#B$A$A%@&?&?'>'>(=)<)<*;+;+:,9,9-8.7.7/6060514142332324151506/6/7.8-8-9,9,:+;*;*<)=)=(>'>'?&@%@%A$B$B#C"C"D!E E FGGHHIJJKKLMMNOOPPQRRSTTUUVWWX Y Y Z Z [ \ \ ]]^__`aabbcddefffffffffffffff f f f f f f f ffffffff-----. . . ....////// /"0$0&0'0)0+0-1/11131516181:2<2>2@2B2C2E2G3I3K3~M3|O3zP3xR3vT4tV4rX4pZ4n[4l]4j_4ha5fc5de5bf5`h5^j5\l6Zn6Xp6Vq6Ts6Ru6Pw6Ny7Lz7K|7I~7G7E7C7A8?8=8;89878583919/9-9+9*9(9&:$:": :::::;;;;; ; ; <<<<<:975 3 2 0.,+)'%$" "#%')+-/02 4 6 8:<=?A=95,2;.K*zZ%nj!b{UI;. !sf%tf$tf$uf#uf#vf"wf!wf!xf xfyfzfzf{f|f|f}f}f~ffffffffffffffffffffff f f f f f f f ffffffffffffffeca^\ZXVTRPNLJHF D B @ > < : 8 7 5 31/.,*)'%#"     !$ & ( * - / 1 4 6 8 ;=@BEGJLORTWY\_bcbbaa`__^^]\\[Z Z Y Y X W W V UUTTSRRQQPOONMMLLKJJIHHGGFEEDD C!B!B"A"@#@$?$?%>%=&='<'<(;):):*9*8+8,7,7-6-5.5/4/30312122120304/4/5.6-6-7,7+8+9*9*:):(;(<'<'=&>%>%?$?#@#A"A"B!B C DDEFFGGHIIJKKLLMNNOOPQQRSSTTUV V W W X Y Y Z [[\\]^^_``aabcccccccccccccccc c c c c c c c cccccccccccc++++,, , , ,,,------. .".$.&.'.).+/-///1/3/5/6/80:0<0>0@0B0C0E1G1I1K1M1~O1|P2zR2xT2vV2tX2rZ2p[2n]3l_3ja3hc3fe3df3bh3`j4^l4\n4Zp4Xq4Vs4Tu4Rw5Py5Nz5L|5J~5H5F5E6C6A6?6=6;69677573717/7-7+7)8'8&8$8"8 889999999: : : :::::9753 2 0 .,+)'%$"  "$%')+-/1 2 4 68:<>?;74,0;,K(|Z#pjd{WJ= 0#tc&uc%uc%vc$wc$wc#xc"xc"yc!zc!zc {c|c|c}c}c~ccccccccccccccccccccccccc c c c c c c c c ccccccccccccccca^\ZXVTRPNLJHFD B @ > < : 8 7 5 3 1/.,*)'%#"      " $ & ) + - 0 2 4 7 9;>@CEHJMORUWZ]`a``_^^]\\[[ZYYX X W V V U T T SSRQQPPONNMMLKKJIIHHGFFEEDCCBA A @!@"?">#>#=$=%<%;&;':'9(9(8)8*7*6+6+5,5-4-3.3.2/10100102/2.3.3-4-5,5+6+6*7)8)8(9(:':&;&;%<%=$=#>#>"?!@!@ A BBCCDEEFFGHHIJJKKLMMNNOPPQRRSS T U U V V W X XYZZ[[\]]^^_``aaaaaaaaaaaaaaa a a a a a a a a aaaaaaaaaaaaaaa)))*** * * **++++++,, ,",$,&,',)-+---/-1-3-5-6.8.:.<.>.@.B/C/E/G/I/K/M/O0~P0|R0zT0xV0vX0tZ0r[1p]1n_1la1jc1he1ff1dh2bj2`l2^n2\p2Zq2Xs2Vu3Tw3Ry3Pz3N|3L~3J4H4F4D4B4@4?4=5;59575553515/6-6+6)6'6%6#6"7 7777778888 8 8 889997532 0 . ,+)'%$"  "$%')+-/ 1 3 468:<=962,.;*K&}Z"rje{YL? 2%va&wa&wa%xa%xa$ya#za#za"{a"{a!|a }a }a~aaaaaaaaaaaaaaaaaaaaaaaaaaaaa a a a a a a a a aaaaaaaaaaaaaaa^\ZXVTRPNLJHFDB @ > < : 8 7 5 3 1 /.,*)'%#"      " % ' ) + . 0 2 5 7:<>ACFHKMPSUX[]_^]]\[[ZZYXXWWV U U T T S R R QPPOONMMLLKJJIIHGGFEEDDCBBAA@? ? >!>!="<#<#;$:$:%9&9&8'7(7(6)6)5*4+4+3,2,2-1.1.0//0/0.1.1-2,3,3+4+4*5)6)6(7'7'8&9&9%:$;$;#<#<"=!>!> ? ?@AABBCDDEFFGGHIIJJKLLMMNOOPQQ R R S T T U U VWWXYYZZ[\\]]^________________ _ _ _ _ _ _ _ ___________________''(((( ( ( ())))))*** *"*$*&*'+)+++-+/+1+3,5,6,8,:,<,>,@-B-C-E-G-I-K-M.O.P.}R.{T.yV.wX.uZ/s[/q]/o_/ma/kc/je0hf0fh0dj0bl0`n0^p0\q1Zs1Xu1Vw1Ty1Rz1P|1N~2L2J2H2F2D2B2@3>3<3:39373533414/4-4+4)4'4%5#5!55555666666 6 7 777775320 . , +)'%$"  "$&')+- / 1 3468:;840,,;(K$Z sjg{[NA 4'w_(x_'x_&y_&z_%z_${_${_#|_#}_"}_!~_!~_ _ ______________________________ _ _ _ _ _ _ _ _______________^\ZXVTRPNLJHFDB@ > < : 8 7 5 3 1 / .,*)'%#"      ! # % ' * , . 1 3 58:<?ADFIKNQSVY[\\[ZZYYXWWVVUTT S S R Q Q P P ONNMLLKKJIIHHGFFEEDCCBBA@@?>>== ??@@ABBCCDEEFFGHHIIJKKLMMNNO P P Q Q R S S TTUVVWWXYYZ[[\\]]]]]]]]]]]]]]] ] ] ] ] ] ] ] ]]]]]]]]]]]]]]]]]]]]]]]%&&&&& & & ''''''(((( ("($(&)')))+)-)/)1*3*5*6*8*:*<*>+@+B+C+E+G+I+K,M,O,P,R,}T,{V-yX-wZ-u[-s]-q_-oa-mc.ke.if.gh.ej.cl.an._p/^q/\s/Zu/Xw/Vy/Tz/R|0P~0N0L0J0H0F0D1B1@1>1<1:18262523212/2-2+3)3'3%3#3!33444444455 5 555565320. , + )'%$"  "$&()+ - / 13568:62.,*;&K"Zuji{]P C6)y](z]'z]'{]&{]&|]%}]$}]$~]#~]#]"]!]!] ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] ] ] ] ] ] ] ] ]]]]]]]]]]]]]]]\ZXVTRPNLJHFDB@> < : 8 7 5 3 1 / . , *)'%#"       ! $ & ( * - / 1368;=?BDGILOQTVYZZYXXWVVUUTSSRR Q P P O O N M MLLKJJIIHGGFFEDDCBBAA@??>>=<<;; :!9!9"8"8#7$6$6%5%5&4'3'3(2(2)1*0*0+/+.,.----.,.+/+0*0*1)2(2(3'3'4&5%5%6$6$7#8"8"9!9!: ;;<<=>>??@AABBCDDEFFGGHIIJJKLLM M N O O P P Q RRSSTUUVVWXXYZZZZZZZZZZZZZZZZZ Z Z Z Z Z Z Z ZZZZZZZZZZZZZZZZZZZZZZZZZZZ$$$$$$ $ % %%%%%&&&&& &"&$'&''')'+'-'/(1(3(5(6(8(:(<)>)@)B)C)E)G*I*K*M*O*P*R*T+}V+{X+yZ+w[+u]+s_+qa,oc,me,kf,ih,gj,el,cn-ap-_q-]s-[u-Yw-Wy.Uz.T|.R~.P.N.L.J/H/F/D/B/@/>/<0:08060402000/1-1+1)1'1%1#1!22222223333 3 33444320., + ) '%$"  "$&(* + - /1357840,,(;$K Zwjk{_R E8+{Z({Z(|Z'}Z'}Z&~Z%~Z%Z$Z$Z#Z"Z"Z!Z!Z ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ Z Z Z Z Z Z Z ZZZZZZZZZZZZZZZZXVTRPNLJHFDB@><: 8 7 5 3 1 / . , * )'%#"        " $ & ) + - /2469;>@BEGJMORTWXWWVVUTTSSRQQPO O N N M L L K KJIIHHGFFEEDCCBBA@@??>==<<;::99 8 7!7"6"6#5#4$4%3%3&2&1'1(0(0)/).*.+-+-,,,+-+.*.)/)/(0(1'1&2&2%3%4$4#5#6"6"7!7 8 99::;<<==>??@@ABBCCDEEFFGHHIIJK K L L M N N O OPQQRRSTTUUVWWXXXXXXXXXXXXXXXX X X X X X X X XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"""""" # # ####$$$$$$ $"%$%&%'%)%+%-&/&1&3&5&6&8&:'<'>'@'B'C'E(G(I(K(M(O(P(R)T)V)}X){Z)y[)w])u_*sa*qc*oe*mf*kh*ij+gl+en+cp+aq+_s+]u+[w,Yy,Wz,U|,S~,Q,O,M-L-J-H-F-D-B-@.>.<.:.8.6.4/2/0/./,/+/)/'0%0#0!00001111111 2 2222220.,+ ) '%$"  "$&( * , -/13562/+,';#KZyjm{a TG:|X)|X)}X(~X(~X'X&X&X%X%X$X#X#X"X"X!X X XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX X X X X X X X XXXXXXXXXXXXXXXXVTRPNLJHFDB@><:8 7 5 3 1 / . , * ) '%#"         " % ' ) + .02579<>ACFHKMPRUVUUTSSRRQPPOONM M L L K J J I IHGGFFEDDCCBAA@@?>>==<;;::98877 6 5!5!4"4#3#2$2$1%1&0&/'/'.(.)-),*,*+++,*,)-)-(.(/'/&0&0%1%2$2#3#3"4"5!5 6 678899:;;<<=>>??@AABBCDDEEFGGHH I J J K K L M MNNOPPQQRSSTTUVVVVVVVVVVVVVVVV V V V V V V V V VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV V V!V    ! ! ! !!!""""""# #"#$#&#'#)#+$-$/$1$3$5$6%8%:%<%>%@%B%C&E&G&I&K&M&O&P'R'T'V'X'}Z'{[(y](w_(ua(sc(qe(of(mh)kj)il)gn)ep)cq)as)_u*]w*[y*Yz*W|*U~*S+Q+O+M+K+I+G+F,D,B,@,>,<,:,8-6-4-2-0-.-,-*.(.'.%.#.!..///////00 0 000010.,+) ' %$"  "$& ( * ,-/1341-),%;!KZ{jo{c VI<~V*~V)V)V(V'V'V&V&V%V$V$V#V#V"V!V!V V VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV V V V V V V V VVVVVVVVVVVVVVVVTRPNLJHFDB@><:87 5 3 1 / . , * ) ' %#"         ! # % ' * ,.0357:<?ADFIKNPSTSRRQQPOONNMLLK K J I I H H G FFEEDDCBBAA@??>>=<<;;:998876655 4 3!3!2"2"1#0$0$/%/%.&-'-',(,(+)****)+)+(,'-'-&.&.%/$0$0#1#1"2!3!3 4 456677899::;<<==>??@@ABBCCDEEFF G H H I I J K KLLMNNOOPQQRRSSTTTTTTTTTTTTTTT T T T T T T T T TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT T T!T!T"T#T#T         !! !"!$!&!'!)"+"-"/"1"3"5#6#8#:#<#>#@#B$C$E$G$I$K$M%O%P%R%T%V%X%~Z&|[&z]&y_&wa&uc&se&qf'oh'mj'kl'in'gp'eq(cs(au(_w(]y([z(Y|(W~)U)S)Q)O)M)K)I*G*E*C*A*@*>+<+:+8+6+4+2+0,.,,,*,(,&,%,#-!------..... . .////.,+)' % $" !"$ & ( *,./13/+',#;KZ}jq{ e XKT+T*T*T)T(T(T'T'T&T%T%T$T$T#T"T"T!T!T T TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT T T T T T T T TTTTTTTTTTTTTTTTRPNLJHFDB@><:875 3 1 / . , * ) ' % #"           ! # & ( *,/1368:=?BDGILNQRQPPOONMMLLKJJI I H G G F F E DDCCBAA@@?>>==<<;::9987766544332 1!1!0"0"/#.$.$-%-%,&+'+'*(*())()(*'+'+&,&,%-$.$.#/#/"0!1!1 2 234455677889::;;<==>>??@AABBCDD E E F G G H H IJJKKLMMNNOPPQQRRRRRRRRRRRRRRRR R R R R R R R RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR R!R!R"R"R#R$R$R%R%R    "$&' ) + - / 1 3!5!6!8!:!!@"B"C"E"G"I"K#M#O#P#R#T#V#X$Z$~[$|]$z_$xa$vc%te%rf%ph%nj%ll%jn%hp&gq&es&cu&aw&_y&]z&[|'Y~'W'U'S'Q'O(M(K(I(G(E(C(A)?)=)<):)8)6)4*2*0*.*,***(*&+$+"+!+++,,,,,,, - - -----,+)'% $ " !# $ & (*,.01-)%,!;KZjs{ gZMR+R+R*R)R)R(R(R'R&R&R%R%R$R$R#R"R"R!R!R RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR R R R R R R R RRRRRRRRRRRRRRRRPNLJHFDB@><:8753 1 / . , * ) ' % # "             " $ & (+-/2469;=@BEGJLOOONNMLLKKJIIHHG G F E E D D C B BAA@??>>=<<;;::9887765544322110 / /!."."-#,#,$+%+%*&*&)'((((')')&*%*%+$,$,#-"-".!/!/ 00122334556678899::;<<==>??@@ABB C C D E E F F GGHIIJJKLLMMNOOPPPPPPPPPPPPPPPP P P P P P P P PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP P P!P"P"P#P#P$P%P%P&P&P'P(P    "$&')+-/13568:<> @ B C E G I!K!M!O!P!R!T!V"X"Z"["~]"|_"za#xc#ve#tf#rh#pj#nl#ln$jp$hq$fs$du$bw$`y%^z%]|%[~%Y%W%U%S&Q&O&M&K&I&G&E'C'A'?'=';'9(7(6(4(2(0(.(,)*)()&)$)") )*******++ + + +++,,+)'%$ " ! # % &(*,./+'#,;KZju{ h\OP,P+P*P*P)P)P(P'P'P&P&P%P%P$P#P#P"P"P!P P PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP P P P P P P P PPPPPPPPPPPPPPPPNLJHFDB@><:87531 / . , * ) ' % # "              " $ ')+-02479;>@CEHJMMMLLKJJIIHGGFFE D D C C B B A @ @??>==<<;::99887665543322100//. . -!,!,"+#+#*$)$)%(&(&''&'&(%)%)$*#*#+"+",!-!- ../00112334455677889::;;<==>>?@@ A A B B C D D EEFGGHHIJJKKLLMNNNNNNNNNNNNNNNN N N N N N N N N NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN N N!N!N"N#N#N$N$N%N&N&N'N'N(N(N)N*N    "$&')+-/13568:<>@BCEGIKMOPR T V X Z [ ] ~_!|a!zc!xe!vf!th!rj"pl"nn"lp"jq"hs"fu"dw#by#`z#^|#\~#Z#X#V$U$S$Q$O$M$K%I%G%E%C%A%?%=&;&9&7&5&3&2&0'.','*'('&'$("( ((((())))) ) ) *****)'%$ "  ! # %&(*,-*&",;KZj w{j^N-N,N+N+N*N*N)N(N(N'N'N&N&N%N$N$N#N#N"N!N!N N NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN N N N N N N N NNNNNNNNNNNNNNNNLJHFDB@><:87531/ . , * ) ' % # "                ! # %'),.0357:<>ACFHKKKJJIHHGGFEEDDC B B A A @ @ ? > >==<;;::98877665443321100//.--, , +!*!*")")#($'$'%&%&&%'%'$(#(#)"*"*!+ + ,,-..//01122334556678899:;;<<==> ? ? @ @ A B B CCDEEFFGGHIIJJKLLLLLLLLLLLLLLLL L L L L L L L L LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL L!L!L"L"L#L$L$L%L%L&L&L'L(L(L)L)L*L+L+L,L    "$&')+-/13568:<>@BCEGIKMOPRTVXZ[]_~a|czexfvh tj rl pn np lq js hu!fw!dy!bz!`|!^~!\"Z"X"V"T"R"P"N#M#K#I#G#E#C$A$?$=$;$9$7$5%3%1%/%.%,%*%(&&&$&"& &&&''''''( ( ( (((()'%$"    ! #%'(*,($ ,;KZj y{l`L-L,L,L+L+L*L)L)L(L(L'L'L&L%L%L$L$L#L"L"L!L!L L LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL L L L L L L L L LLLLLLLLLLLLLLLLJHFDB@><:87531/. , * ) ' % # "                 ! #&(*,/1358:=?ADFIIIHGGFFEEDCCBBA @ @ ? ? > > = < <;;:998877655443221100/..--,++** )!)!("'"'#&$&$%%$%$&#&#'"("(!) ) *++,,--.//00122334456677899::;;< = = > > ? @ @ AABBCDDEEFGGHHIIJJJJJJJJJJJJJJJ J J J J J J J J JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ J J!J"J"J#J#J$J$J%J&J&J'J'J(J)J)J*J*J+J+J,J-J-J.J    "$&')+-/13568:<>@BCEGIKMOPRTVXZ[]_a~c|ezfxhvjtlrnppnqlsjuhwfydzb|`~ ^ \ Z X V T!R!P!N!L!J!H!G"E"C"A"?"=";"9#7#5#3#1#/#-$+$*$($&$$$"$ %%%%%%%&&& & & &&'''%$"      !#%')*&",;KZ jz{nJ.J-J-J,J,J+J*J*J)J)J(J(J'J&J&J%J%J$J#J#J"J"J!J!J JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ J J J J J J J J JJJJJJJJJJJJJJJJHFDB@><:87531/., * ) ' % # "                  "$&(*-/1468;=@BDGGGFEEDDCCBAA@@? > > = = < < ; : :99887665543322110//..-,,++**)(( ' '!&"%"%#$#$$#%#%"&!&!' ' ())**++,--../001122344556778899: ; ; < < = > > ??@@ABBCCDDEFFGGHHHHHHHHHHHHHHH H H H H H H H H HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH H H!H!H"H#H#H$H$H%H%H&H'H'H(H(H)H)H*H+H+H,H,H-H-H.H/H/H0H    "$&')+-/13568:<>@BCEGIKMOPRTVXZ[]_ac}e{fyhwjulsnrppqnslujwhyfzd|b~`^\ZXVTRPNLJ H F D C A ?!=!;!9!7!5!3!1"/"-"+")"'"&"$#"# ####$$$$$$ $ % %%%%%$"       !#%'($ ,;KZ j|{pH.H.H-H-H,H+H+H*H*H)H)H(H'H'H&H&H%H$H$H#H#H"H"H!H H HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH H H H H H H H H HHHHHHHHHHHHHHHHFDB@><:87531/.,* ) ' % # "                 "$')+-02479;>@CEEEDCCBBAA@??>>= = < ; ; : : 9 8 877665443322100//.--,,++*))((''& % %!$!$"##"#"$!$!% & &''(()**++,,-..//011223345566778 9 9 : : ; ; < ==>>?@@AABBCDDEEFFFFFFFFFFFFFFFF F F F F F F F FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF F!F!F"F"F#F#F$F%F%F&F&F'F'F(F)F)F*F*F+F+F,F-F-F.F.F/F0F0F1F1F2F    "$&')+-/13568:<>@BCEGIKMOPRTVXZ[]_ace}f{hyjwlunspqqosmukwiygzf|d~b`^\ZXVTRPNLJHFDB@>=;97 5 3 1 / - + )!'!%!$!"! !!""""""## # # ###$$"       !#%&",;KZ j~{rF/F.F.F-F,F,F+F+F*F)F)F(F(F'F'F&F%F%F$F$F#F#F"F!F!F F FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF F F F F F F F F FFFFFFFFFFFFFFFFDB@><:87531/.,*)' % # "                  !#%'),.02579<>ACCCBAA@@??>==<<; ; : 9 9 8 8 7 7 655443321100/..--,,+**))(('&&%%$ $ #!"!""!"!# $ $%%&''(())*++,,--.//001123344556 7 7 8 8 9 : : ;;<<=>>??@@ABBCCDDDDDDDDDDDDDDDD D D D D D D D D DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD D D!D"D"D#D#D$D$D%D&D&D'D'D(D(D)D*D*D+D+D,D,D-D.D.D/D/D0D0D1D2D2D3D3D4D    "$&')+-/13568:<>@BCEGIKMOPRTVXZ[]_acef}h{jylwnupsqqsoumwkyizg|e~ca_]\ZXVTRPNLJHFDB@><:97531/-+)'%#!      !!!! ! ! !""""        !#%!,;K Zj{D0D/D.D.D-D-D,D,D+D*D*D)D)D(D(D'D&D&D%D%D$D$D#D"D"D!D!D D DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD D D D D D D D D DDDDDDDDDDDDDDDDB@><:87531/.,*)'% # "                   !#%(*,.1358:<?AAA@@?>>==<;;::9 9 8 7 7 6 6 5 5 43322110//..--,++**))(''&&%%$##"" !!!! ""##$%%&&''())**+,,--../001122344 5 5 6 6 7 8 8 99::;<<==>>?@@AABBBBBBBBBBBBBBBB B B B B B B B B BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB B B!B!B"B"B#B$B$B%B%B&B&B'B(B(B)B)B*B*B+B,B,B-B-B.B.B/B0B0B1B1B2B2B3B4B4B5B5B6B     "$&')+-/13568:<>@BCEGIKMOPRTVXZ[]_acefh}j{lynwpuqssquowmykzi|g~eca_][YWUTRPNLJHFDB@><:86531/-+)'%#!            "#,;K Zj{B0B/B/B.B.B-B-B,B+B+B*B*B)B)B(B'B'B&B&B%B%B$B#B#B"B"B!B!B BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB B B B B B B B B BBBBBBBBBBBBBBBB@><:87531/.,*)'%# "                   "$&(*-/1368:=???>>=<<;;::9887 7 6 6 5 4 4 3 3 22100//..-,,++**)((''&&%$$##""!   !""##$$%&&''(()**++,,-..//00122 3 3 4 4 5 6 6 7 7889::;;<<=>>??@@@@@@@@@@@@@@@@ @ @ @ @ @ @ @ @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @!@!@"@"@#@#@$@$@%@&@&@'@'@(@(@)@*@*@+@+@,@,@-@.@.@/@/@0@0@1@2@2@3@3@4@4@5@6@6@7@7@8@         "$&')+-/13568:<>@BCEGIKMOPRTVXZ[]_acefhj}l{nypwqussuqwoymzk|i~geca_][YWUSQONLJHFDB@><:86421/-+)'%#!         !,; KZj@1@0@0@/@/@.@-@-@,@,@+@+@*@*@)@(@(@'@'@&@&@%@$@$@#@#@"@"@!@ @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ @ @ @ @ @ @ @ @@@@@@@@@@@@@@@@><:87531/.,*)'%#"                      "$&)+-/2469;===<<;;:998877655 4 4 3 3 2 1 1 00//.--,,++*))((''&%%$$##""!    !!"##$$%%&''(())*++,,--.//00 1 1 2 3 3 4 4 5 56778899::;<<==>>>>>>>>>>>>>>>> > > > > > > > > >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> > >!>!>">#>#>$>$>%>%>&>'>'>(>(>)>)>*>*>+>,>,>->->.>.>/>0>0>1>1>2>2>3>4>4>5>5>6>6>7>7>8>9>9>:>              " $ & ' ) +-/13568:<>@BCEGIKMOPRTVXZ[]_acefhj~l|n{pyqwsuuswqyozm|k~igeca_][YWUSQOMKIHFDB@><:86420.-+)'%#!        ,; KZj>1>1>0>0>/>.>.>->->,>,>+>*>*>)>)>(>(>'>'>&>%>%>$>$>#>#>">!>!> > >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> > > > > > > > > >>>>>>>>>>>>>>>><:87531/.,*)'%#"                        #%')+.02579<;;::998776655443 2 2 1 1 0 0 / ..--,,+**))((''&%%$$##"!!    !!""#$$%%&&'(())**+,,--.. / / 0 1 1 2 2 3 34556677899::;;<<<<<<<<<<<<<<<< < < < < < < < < <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< < @BCEGIKMOPRTVXZ[]_acefhjl~n|pzqxsvutwrypzn|m~kigeca_][YWUSQOMKIGEDB@><:86420.,*)'%#!        , ; KZj<2<1<0<0:      " $ & ' ) + - / 1 3 5 6 8 : < > @ B C E G I K M O P R TVXZ[]_acefhjln~p|qzsxuvwtyrzp|n~ljhfdca_][YWUSQOMKIGECA?><:86420.,*(&%#!       , ;KZ:3:2:1:1:0:0:/:/:.:-:-:,:,:+:+:*:*:):(:(:':':&:&:%:%:$:#:#:":":!:!: :::::::::::::::::::::::::::::::::: : : : : : : : : ::::::::::::::::87531/.,*)'%#"                   !$&(*,/1368877655443321100/ / . . - , , + + **))(''&&%%$##""!!   !!""##$$%&&''(())*+ + , , - - . / / 00112234455667788888888888888888 8 8 8 8 8 8 8 8 888888888888888888888888888888888 8 8!8!8"8#8#8$8$8%8%8&8&8'8(8(8)8)8*8*8+8+8,8-8-8.8.8/8/8080818282838384848585868787888889898:8:8;8<8<8=8=8>8>8?8?8    "$&')+-/1 3 5 6 8 : < > @ B C E G I K M O P R T V X Z [ ] _ a c e f hjlnp~q|szuxwvytzr|p~nljhfdb`^\[YWUSQOMKIGECA?=;:86420.,*(&$#!      , ;KZ8382828181808/8/8.8.8-8-8,8,8+8*8*8)8)8(8(8'8'8&8%8%8$8$8#8#8"8"8!8 8 8888888888888888888888888888888888 8 8 8 8 8 8 8 888888888888888887531/.,*)'%#"                  "$&)+-/246655443221100//.- - , , + + * ) ) ((''&&%$$##""!!   !!"##$$%%&''(() ) * * + , , - - ..//0112233445666666666666666666 6 6 6 6 6 6 6 6 666666666666666666666666666666666 6 6!6!6"6"6#6#6$6%6%6&6&6'6'6(6(6)6*6*6+6+6,6,6-6-6.6/6/6060616162626364646565666667676868696:6:6;6;6<6<6=6=6>6?6?6@6@6A6A6    "$&')+-/13568:<>@BCE G I K M O P R T V X Z [ ] _ a c e f h j l n p q ~s |u zw xy vz t| r~pnljhfdb`^\ZXVUSQOMKIGECA?=;976420.,*(&$"       ,;K64636362626160606/6/6.6.6-6-6,6+6+6*6*6)6)6(6(6'6&6&6%6%6$6$6#6#6"6!6!6 6 666666666666666666666666666666666 6 6 6 6 6 6 6 6 66666666666666666531/.,*)'%#"                 "%')+-02443322110//..--,, + * * ) ) ( ( ' '&%%$$##""!    !!""#$$%%&&' ' ( ) ) * * + + ,,-..//0011233444444444444444444 4 4 4 4 4 4 4 4 4444444444444444444444444444444444 4 4!4"4"4#4#4$4$4%4%4&4'4'4(4(4)4)4*4*4+4+4,4-4-4.4.4/4/4040414242434344444545464747484849494:4:4;4<4<4=4=4>4>4?4?4@4@4A4B4B4C4C4    "$&')+-/13568:<>@BCEGIKMOPRTVXZ [ ] _ a c e f h j l n p q s ~u |w zy xz v| t~ r p n l j h f d b ` ^\ZXVTRPOMKIGECA?=;975320.,*(&$"      ,;K4444434242414140404/4/4.4-4-4,4,4+4+4*4*4)4(4(4'4'4&4&4%4%4$4#4#4"4"4!4!4 4 444444444444444444444444444444444 4 4 4 4 4 4 4 4 4444444444444444431/.,*)'%#"              !#%'*,.0322100//..--,++** ) ) ( ( ' & & % %$$##"!!    !!""##$%% & & ' ' ( ( ) * *++,,--../0011223333333333333333 3 3 3 3 3 3 3 3 3333333333333333333333333333333333 3 3!3!3"3"3#3$3$3%3%3&3&3'3'3(3(3)3*3*3+3+3,3,3-3-3.3/3/3030313132323333343535363637373838393:3:3;3;3<3<3=3=3>3>3?3@3@3A3A3B3B3C3C3D3E3E3F3F3G3G3H3H3  "$&')+-/13568:<>@BCEGIKMOPRTVXZ[]_acefhjln p q s u }w {y yz w| v~ t r p n l j h f d b ` ^ \ Z X V T R P N L JIGECA?=;97531/.,*(&$"       ,;K3434333332323131303/3/3.3.3-3-3,3,3+3+3*3)3)3(3(3'3'3&3&3%3$3$3#3#3"3"3!3!3 3 333333333333333333333333333333333 3 3 3 3 3 3 3 3 333333333333333331/.,*)'%#"            !$&(*,/100//..-,,++**))( ' ' & & % % $ $ #""!!   !!""## $ $ % % & ' ' ( ())**+,,--..//011111111111111111 1 1 1 1 1 1 1 1 1 111111111111111111111111111111111 1 1!1!1"1"1#1#1$1$1%1&1&1'1'1(1(1)1)1*1*1+1,1,1-1-1.1.1/1/1010111212131314141515161617181819191:1:1;1;1<1=1=1>1>1?1?1@1@1A1A1B1C1C1D1D1E1E1F1F1G1G1H1I1I1J1J1K1K1L1L1M1M1N1O1~O1~P1} "$&')+-/13568:<>@BCEGIKMOPRTVXZ[]_acefhjlnpqsuw}y{zy|w~us q o m k j h f d b ` ^ \ Z X V T R P N L J H F E C A ? = ; 9 7531/-,*(&$"        ,;15151414131312111110101/1/1.1.1-1-1,1+1+1*1*1)1)1(1(1'1&1&1%1%1$1$1#1#1"1"1!1 1 1111111111111111111111111111111111 1 1 1 1 1 1 1 1 11111111111111111/.,*)'%#"             "$&(+-/..--,,++**)((''& & % % $ # # " " !!    !" " # # $ $ % % & &'(())**++,,-..////////////////// / / / / / / / / ////////////////////////////////// / /!/!/"/#/#/$/$/%/%/&/&/'/'/(/)/)/*/*/+/+/,/,/-/-/./////0/0/1/1/2/2/3/3/4/5/5/6/6/7/7/8/8/9/9/:/;/;//>/?/?/@/A/A/B/B/C/C/D/D/E/E/F/G/G/H/H/I/I/J/J/K/K/L/M/M/N/N/O/O/P/P/~Q/~Q/}R/|S/|S/{T/{T/zU/zU/yV/yV/xW/xW/w3568:<>@BCEGIKMOPRTVXZ[]_acefhjlnpqsuwy}z{|y~wusqomkigecb` ^ \ Z X V T R P N L J H F D B A ? = ; 9 7 5 3 1 / - + ) ( & $ "           ,;/6/5/5/4/3/3/2/2/1/1/0/0/////./-/-/,/,/+/+/*/*/)/)/(/'/'/&/&/%/%/$/$/#/#/"/!/!/ / ////////////////////////////////// / / / / / / / / /////////////////.,*)'%#"           "%')+--,,+**))((''&&%$ $ # # " " ! !  ! ! " " # $ $ %%&&''(()**++,,------------------ - - - - - - - - ---------------------------------- - -!-!-"-"-#-#-$-%-%-&-&-'-'-(-(-)-)-*-+-+-,-,-----.-.-/-/-0-0-1-2-2-3-3-4-4-5-5-6-6-7-8-8-9-9-:-:-;-;-<-<-=->->-?-?-@-@-A-A-B-B-C-C-D-E-E-F-F-G-G-H-H-I-I-J-K-K-L-L-M-M-N-N-O-O-P-Q-Q-R-R-~S-~S-}T-|T-|U-{U-{V-zV-zW-yX-yX-xY-xY-wZ-wZ-v[-u[-u\-t\-t]-s^-s^-r_-r_-qGIKMOPRTVXZ[]_acefhjlnpqsuwyz}|{~ywusqomkigeca_]\ZXVTRPNL J H F D B @ > = ; 9 7 5 3 1 / - + ) ' & $ "                   ,-6-6-5-5-4-4-3-3-2-2-1-0-0-/-/-.-.-----,-,-+-+-*-)-)-(-(-'-'-&-&-%-%-$-#-#-"-"-!-!- - ---------------------------------- - - - - - - - - -----------------,*)'%#"        !#%')++**))((''&%%$$## " " ! !       ! ! " " ##$%%&&''(())**++++++++++++++++++ + + + + + + + + +++++++++++++++++++++++++++++++++++ +!+!+"+"+#+#+$+$+%+%+&+'+'+(+(+)+)+*+*+++++,+,+-+.+.+/+/+0+0+1+1+2+2+3+3+4+5+5+6+6+7+7+8+8+9+9+:+:+;+<+<+=+=+>+>+?+?+@+@+A+B+B+C+C+D+D+E+E+F+F+G+G+H+I+I+J+J+K+K+L+L+M+M+N+N+O+P+P+Q+Q+R+R+S+S+T+~T+~U+}V+|V+|W+{W+{X+zX+zY+yY+yZ+xZ+x[+w[+w\+v]+u]+u^+t^+t_+s_+s`+r`+ra+qa+qb+pb+pc+od+nd+ne+me+mf+lf+lg+k[]_acefhjlnpqsuwyz|}~{ywusqomkigeca_][YWVTRPNLJHFDB@><:9 7 5 3 1 / - + ) ' % # "                    ,+7+6+6+5+5+4+4+3+2+2+1+1+0+0+/+/+.+.+-+-+,+++++*+*+)+)+(+(+'+'+&+%+%+$+$+#+#+"+"+!+!+ + ++++++++++++++++++++++++++++++++++ + + + + + + + + +++++++++++++++++*)'%#"       !#&(*))(('&&%%$$##""!              ! !""##$$%%&''(())***************** * * * * * * * * *********************************** * *!*!*"*#*#*$*$*%*%*&*&*'*'*(*(*)*****+*+*,*,*-*-*.*.*/*/*0*1*1*2*2*3*3*4*4*5*5*6*6*7*8*8*9*9*:*:*;*;*<*<*=*=*>*>*?*@*@*A*A*B*B*C*C*D*D*E*E*F*G*G*H*H*I*I*J*J*K*K*L*L*M*N*N*O*O*P*P*Q*Q*R*R*S*S*T*U*U*V*~V*~W*}W*}X*|X*{Y*{Y*zZ*zZ*y[*y\*x\*x]*w]*w^*v^*v_*u_*t`*t`*sa*sa*rb*rc*qc*qd*pd*pe*oe*of*nf*mg*mg*lh*lh*ki*kj*jj*jk*ik*il*hl*hm*gm*fn*fn*epqsuwyz|~~}{ywusqomkigeca_][YWUSQPNLJHFDB@><:86531/-+)'%# !                  *8*7*7*6*5*5*4*4*3*3*2*2*1*1*0*0*/*.*.*-*-*,*,*+*+*****)*)*(*'*'*&*&*%*%*$*$*#*#*"*"*!* * *********************************** * * * * * * * * *****************)'%#"       "$&(''&&%%$$##"!!                      !""##$$%%&&''((((((((((((((((( ( ( ( ( ( ( ( ( ( (((((((((((((((((((((((((((((((((( ( (!(!("("(#(#($($(%(&(&('('((((()()(*(*(+(+(,(,(-(.(.(/(/(0(0(1(1(2(2(3(3(4(5(5(6(6(7(7(8(8(9(9(:(:(;(<(<(=(=(>(>(?(?(@(@(A(A(B(B(C(D(D(E(E(F(F(G(G(H(H(I(I(J(K(K(L(L(M(M(N(N(O(O(P(P(Q(Q(R(S(S(T(T(U(U(V(V(W(W(~X(~X(}Y(}Z(|Z({[({[(z\(z\(y](y](x^(x^(w_(w_(v`(v`(ua(tb(tb(sc(sc(rd(rd(qe(qe(pf(pf(og(og(nh(ni(mi(lj(lj(kk(kk(jl(jl(im(im(hn(hn(go(go(fp(eq(eq(dr(dr(cs(cs(bt(bt(au(au(`v(`zxvtrqomkigeca_][YWUSQOMKJHFDB@><:86421/-+)'%#!        (8(7(7(6(6(5(5(4(4(3(3(2(1(1(0(0(/(/(.(.(-(-(,(,(+(+(*()()((((('('(&(&(%(%($($(#("("(!(!( ( ((((((((((((((((((((((((((((((((((( ( ( ( ( ( ( ( ( ((((((((((((((((('%#"     "$&&%%$$#""!!                      !!""#$$%%&&&&&&&&&&&&&&&&&& & & & & & & & & & &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& &!&!&"&"&#&#&$&$&%&%&&&&&'&'&(&)&)&*&*&+&+&,&,&-&-&.&.&/&/&0&1&1&2&2&3&3&4&4&5&5&6&6&7&7&8&9&9&:&:&;&;&<&<&=&=&>&>&?&?&@&A&A&B&B&C&C&D&D&E&E&F&F&G&G&H&I&I&J&J&K&K&L&L&M&M&N&N&O&O&P&Q&Q&R&R&S&S&T&T&U&U&V&V&W&W&X&Y&Y&~Z&~Z&}[&}[&|\&{\&{]&z]&z^&y^&y_&x_&x`&wa&wa&vb&vb&uc&uc&td&sd&se&re&rf&qf&qg&pg&ph&oi&oi&nj&nj&mk&mk&ll&kl&km&jm&jn&in&io&ho&hp&gq&gq&fr&fr&es&es&dt&ct&cu&bu&bv&av&aw&`w&`x&_y&_y&^z&^z&]{&]{&\|&[|&[}&Z}&Zgeca_][YWUSQOMKIGFDB@><:86420.-+)'%#!    &8&8&7&7&6&6&5&4&4&3&3&2&2&1&1&0&0&/&/&.&.&-&,&,&+&+&*&*&)&)&(&(&'&'&&&&&%&$&$&#&#&"&"&!&!& & &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& & & & & & & & & &&&&&&&&&&&&&&&&&%#"   !#$$##""!!                       !!""##$$%%%%%%%%%%%%%%%%% % % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % %!%!%"%"%#%$%$%%%%%&%&%'%'%(%(%)%)%*%*%+%+%,%-%-%.%.%/%/%0%0%1%1%2%2%3%3%4%5%5%6%6%7%7%8%8%9%9%:%:%;%;%<%<%=%>%>%?%?%@%@%A%A%B%B%C%C%D%D%E%F%F%G%G%H%H%I%I%J%J%K%K%L%L%M%M%N%O%O%P%P%Q%Q%R%R%S%S%T%T%U%U%V%W%W%X%X%Y%Y%Z%Z%[%~[%~\%}\%}]%|]%{^%{^%z_%z`%y`%ya%xa%xb%wb%wc%vc%vd%ud%ue%te%tf%sf%rg%rh%qh%qi%pi%pj%oj%ok%nk%nl%ml%mm%lm%ln%kn%jo%jo%ip%iq%hq%hr%gr%gs%fs%ft%et%eu%du%dv%cv%cw%bw%ax%ay%`y%`z%_z%_{%^{%^|%]|%]}%\}%\~%[~%[%Z%Y%Y%X%X%W%W%V%V%U%U%TSQOMKIGECB@><:86420.,+)'%#!  %9%9%8%7%7%6%6%5%5%4%4%3%3%2%2%1%1%0%0%/%.%.%-%-%,%,%+%+%*%*%)%)%(%(%'%&%&%%%%%$%$%#%#%"%"%!%!% % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % % % %%%%%%%%%%%%%%%%%#"    !#""!!                       !!""################## # # # # # # # # ################################### # #!#!#"#"#####$#$#%#%#&#&#'#(#(#)#)#*#*#+#+#,#,#-#-#.#.#/#/#0#1#1#2#2#3#3#4#4#5#5#6#6#7#7#8#8#9#:#:#;#;#<#<#=#=#>#>#?#?#@#@#A#A#B#C#C#D#D#E#E#F#F#G#G#H#H#I#I#J#J#K#L#L#M#M#N#N#O#O#P#P#Q#Q#R#R#S#S#T#U#U#V#V#W#W#X#X#Y#Y#Z#Z#[#[#\#\#~]#~^#}^#}_#|_#|`#{`#za#za#yb#yb#xc#xc#wd#wd#ve#ve#uf#ug#tg#th#sh#si#ri#qj#qj#pk#pk#ol#ol#nm#nm#mn#mn#lo#lp#kp#kq#jq#jr#ir#hs#hs#gt#gt#fu#fu#ev#ev#dw#dw#cx#cx#by#bz#az#a{#`{#_|#_|#^}#^}#]~#]~#\#\#[#[#Z#Z#Y#Y#X#X#W#V#V#U#U#T#T#S#S#R#R#Q#Q#P#P#O#O?><:86420.,*('%#!  #9#9#8#8#7#7#6#6#5#5#4#4#3#2#2#1#1#0#0#/#/#.#.#-#-#,#,#+#+#*#)#)#(#(#'#'#&#&#%#%#$#$#####"#"#!# # ################################### # # # # # # # # # #################"     !!                       !!!!!!!!!!!!!!!!!! ! ! ! ! ! ! ! ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! !!!"!"!#!#!$!$!%!%!&!&!'!'!(!(!)!)!*!*!+!,!,!-!-!.!.!/!/!0!0!1!1!2!2!3!3!4!4!5!6!6!7!7!8!8!9!9!:!:!;!;!!?!?!@!@!A!A!B!B!C!C!D!D!E!E!F!F!G!G!H!I!I!J!J!K!K!L!L!M!M!N!N!O!O!P!P!Q!Q!R!S!S!T!T!U!U!V!V!W!W!X!X!Y!Y!Z!Z![![!\!]!]!^!^!~_!~_!}`!}`!|a!|a!{b!zb!zc!yc!yd!xd!xe!we!wf!vg!vg!uh!uh!ti!ti!sj!sj!rk!rk!ql!pl!pm!om!on!nn!no!mp!mp!lq!lq!kr!kr!js!js!it!it!hu!hu!gv!fv!fw!ew!ex!dx!dy!cz!cz!b{!b{!a|!a|!`}!`}!_~!_~!^!]!]!\!\![![!Z!Z!Y!Y!X!X!W!W!V!V!U!U!T!S!S!R!R!Q!Q!P!P!O!O!N!N!M!M!L!L!K!K!J!I.,*(&%#!  !:!:!9!9!8!8!7!6!6!5!5!4!4!3!3!2!2!1!1!0!0!/!/!.!.!-!,!,!+!+!*!*!)!)!(!(!'!'!&!&!%!%!$!$!#!"!"!!!!! ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! ! ! ! ! ! ! ! ! !!!!!!!!!!!!!!!!!                                                                         ! ! " " # # $ $ % & & ' ' ( ( ) ) * * + + , , - - . . / 0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 : ; ; < < = = > > ? ? @ @ A A B B C C D D E F F G G H H I I J J K K L L M M N N O P P Q Q R R S S T T U U V V W W X X Y Y Z [ [ \ \ ] ] ^ ^ _ _ ` ~` ~a }a }b |b |c {c zd zd ye yf xf xg wg wh vh vi ui uj tj tk sk sl rl rm qm qn pn oo op np nq mq mr lr ls ks kt jt ju iu iv hv hw gw gx fx fy ey dz d{ c{ c| b| b} a} a~ `~ ` _ _ ^ ^ ] ] \ \ [ Z Z Y Y X X W W V V U U T T S S R R Q Q P O O N N M M L L K K J J I I H H G G F E E D D   : : 9 9 8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1 0 / / . . - - , , + + * * ) ) ( ( ' ' & % % $ $ # # " " ! !                                                                                    !!""##$$%%&&''(()**++,,--..//0011223344566778899::;;<<==>>??@@ABBCCDDEEFFGGHHIIJJKKLMMNNOOPPQQRRSSTTUUVVWWXYYZZ[[\\]]^^__``aa~b~b}c}d|d|e{e{fzfygygxhxhwiwivjvjukuktltlsmsmrnrnqoqppppqoqnrnrmsmsltltkukujvjviwiwhxhxgygyfzfze{e|d|d}c}b~b~aa``__^^]]\\[[ZZYYXXWVVUUTTSSRRQQPPOONNMMLKKJJIIHHGGFFEEDDCCBBAA@??>;::9988776654433221100//..--,,++**)((''&&%%$$##""!!                                              !!"##$$%%&&''(())**++,,--../00112233445566778899::;;<==>>??@@AABBCCDDEEFFGGHIIJJKKLLMMNNOOPPQQRRSSTTUVVWWXXYYZZ[[\\]]^^__``aabcc~d~d}e}e|f|f{g{gzhyhyixixjwjwkvkvlulumtmtnsnsorprpqqqqprprososntntmululvkvkwjwjxixiyhyhzgzg{f|f|e}e}d~d~ccbbaa`__^^]]\\[[ZZYYXXWWVVUUTTSRRQQPPOONNMMLLKKJJIIHHGFFEEDDCCBBAA@@??>>==<<;;:99887766554433221100//..-,,++**))((''&&%%$$##""!!                                          !!""##$$%%&&'(())**++,,--..//0011223344556778899::;;<<==>>??@@AABBCCDEEFFGGHHIIJJKKLLMMNNOOPPQQRSSTTUUVVWWXXYYZZ[[\\]]^^__`aabbccdde~e~f}f}g|g|h{h{izizjyjxkxkwlwlvmvmunuototpspsqrqrrqrqspsptotoununvmvmwlwlxkxjyjyizizh{h{g|g|f}f~e~eddccbbaa``__^^]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONMMLLKKJJIIHHGGFFEEDDCCBBAA@??>>==<<;;::9988776655443321100//..--,,++**))((''&&%%$##""!!                                    !!""##$$%%&&''(())**++,,--.//00112233445566778899::;;<<==>??@@AABBCCDDEEFFGGHHIIJJKKLLMMNOOPPQQRRSSTTUUVVWWXXYYZZ[[\\]]^__``aabbccddeeff~g~g}h}h|i|i{j{jzkzkylylxmwmwnvovoupuptqtqsrsrrsrsqtqtpupuovovnwnwmxmxlylykzkzj{j{i|i|h}g}g~ffeeddccbbaa``__^^]]\\[[ZZYYXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHGGFFEEDDCCBBAA@@??>>==<<;;::9987766554433221100//..--,,++**))(''&&%%$$##""!!                              !!""##$%%&&''(())**++,,--..//0011223344556678899::;;<<==>>??@@AABBCCDDEEFFGGHHIJJKKLLMMNNOOPPQQRRSSTTUUVVWWXXYYZZ[\\]]^^__``aabbccddeeffggh~h~i}i}j|j|k{k{lzlzmymynxoxowpvpvququrtrtsssstrtruquqvpvpwowoxnxnymymzlzl{k{k|j|j}i}i~h~hggffeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@??>>==<<;;::99887766554433221100//.--,,++**))((''&&%%$$##""!!                            !!""##$$%%&&''(())**++,,-..//00112233445566778899::;;<<==>>??@@AABCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRRSSTTUUVVWXXYYZZ[[\\]]^^__``aabbccddeeffgghhii~j~j}k}k|l|l{m{nznzoyoypxpxqwqwrvrususttttsusurvrvqwqwpxpxoyoynznzm{m{l|l|k}k}j~j~iihhggffeeddccbbaa`__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::9988776654433221100//..--,,++**))((''&&%%$$##""!!                                 !!""##$$%%&&''(())**++,,--..//0011223344556677899::;;<<==>>??@@AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRSSTTUUVVWWXXYYZZ[[\\]]^^__``aabbccddeeffgghhiijjk~k~l}m}m|n|n{o{ozpzpyqyqxrxrwswsvtvtuuuutvtvswrwrxqxqypypzozo{n{n|m|m}l}l~k~kjjiihhggffeeddccbbaa``__^^]]\\[[ZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@??>>==<<;;::99887766554433221100//..--,,++**))((''&%%$$##""!!                                      !!""##$$%%&&''(())*++,,--..//00112233445566778899::;;<<==>>??@@AABBCCDDEEFFGGHHIIJKKLLMMNNOOPPQQRRSSTTUUVVWWXXYYZZ[[\\]]^^__``aabbccddeeffgghhiijjkllm~m~n}n}o|o|p{p{qzqzryrysxsxtwtwuvuvvuvuwtwtxsxsyryrzqzq{p{o|o|n}n}m~m~llkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::99887766554433221100/..--,,++**))((''&&%%$$##""!!                                              !!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<==>>??@@AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRRSSTTUUVVWWXXYYZZ[[\\]]^^__``aabbccddeeffgghiijjkkllmmnn~o~o}p}p|q|q{r{rzszsytytxuxuwvwvvwvwuxuxtytyszszr{r{q|q|p}p}o~o~nnmmllkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@?>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!                                              !!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??@@AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRRSSTTUUVVWWXXYYZZ[[\\]]^^__``aabbccdeeffgghhiijjkkllmmnnoop~p~q}q}r|r|s{s{tztzuyuyvxvxwwwwxvxvyuyuztzt{s{s|r|r}q}q~p~poonnmmllkkjjiihhggffeeddccbbaa`__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!                                              !!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??@@AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRRSSTUUVVWWXXYYZZ[[\\]]^^__``aabbccddeeffgghhiijjkkllmmnnooppqq~r~r}s}s|t|t{u{uzvzvywywxxxxwywyvzvzu{u{t|t|s}s}r~r~qqppoonnmmllkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;:99887766554433221100//..--,,++**))((''&&%%$$##""!!                                                                              ! ! " " # # $ $ % % & & ' ' ( ( ) ) * * + + , , - - . . / / 0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 : : ; ; < < = = > > ? ? @ @ A A B B C C D D E E F F G G H H I I J J K K L L M M N N O O P P Q Q R R S S T T U U V V W W X X Y Y Z Z [ [ \ \ ] ] ^ ^ _ _ ` ` a a b b c c d d e e f f g g h h i i j j k k l l m m n n o o p p q q r r s ~s ~t }t }u |u |v {v {w zw zx yx yy xy xz wz w{ v{ v| u| u} t} t~ s~ s r r q q p p o o n n m m l l k k j j i i h h g g f f e e d d c c b b a a ` ` _ _ ^ ^ ] ] \ \ [ [ Z Z Y Y X X W W V V U U T T S S R R Q Q P P O O N N M M L L K K J J I I H H G G F F E E D D C C B B A A @ @ ? ? > > = = < < ; ; : : 9 9 8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1 0 0 / / . . - - , , + + * * ) ) ( ( ' ' & & % % $ $ # # " " ! !                                                                                                                  ! ! " " # # $ $ % % & & ' ' ( ( ) ) * * + + , , - - . . / / 0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 : : ; ; < < = = > > ? ? @ @ A A B B C C D D E E F F G G H H I I J J K K L L M M N N O O P P Q Q R R S S T T U U V V W W X X Y Y Z Z [ [ \ \ ] ] ^ ^ _ _ ` ` a a b b c c d d e e f f g g h h i i j j k k l l m m n n o o p p q q r r s s t t ~u ~u }v }v |w |w {x {x zy zy yz yz x{ x{ w| w| v} v} u~ u~ t t s s r r q q p p o o n n m m l l k k j j i i h h g g f f e e d d c c b b a a ` ` _ _ ^ ^ ] ] \ \ [ [ Z Z Y Y X X W W V V U U T T S S R R Q Q P P O O N N M M L L K K J J I I H H G G F F F E E D D C C B B A A @ @ ? ? > > = = < < ; ; : : 9 9 8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1 0 0 / / . . - - , , + + * * ) ) ( ( ' ' & & % % $ $ # # " " ! !                                                                                                           ! ! " " # # $ $ % % & & ' ' ( ( ) ) * * + + , , - - . . / / 0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 : : ; ; < < = = > > ? ? @ @ A A B B B C C D D E E F F G G H H I I J J K K L L M M N N O O P P Q Q R R S S T T U U V V W W X X Y Y Z Z [ [ \ \ ] ] ^ ^ _ _ ` ` a a b b c c d d e e f f g g h h i i j j k k l l m m n n o o p p q q r r s s t t u u v ~v ~w }w }x |x |y {y {z zz z{ y{ y| x| x} w} w} v~ v~ u u t t s s r r q q p p o o n n m m l l k k j j i i h h g g f f e e d d c c b b a a a ` ` _ _ ^ ^ ] ] \ \ [ [ Z Z Y Y X X W W V V U U T T S S R R Q Q P P O O N N M M L L K K J J I I H H G G F F E E D D C C B B A A @ @ ? ? > > = = < < ; ; : : 9 9 8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1 0 0 / / . . - - , , + + * * ) ) ( ( ' ' & & & % % $ $ # # " " ! !                                                               !!""##$$%%&&''(()))**++,,--..//00112233445566778899::;;<<==>>??@@AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQQRRSSTTUUVVWWXXYYZZ[[\\]]^^__``aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvww~x~x}y}y|y|z{z{{z{z|y|y}x}x~w~wvvuuttssrrqqppoonnmmllkkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCCBBAA@@??>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!            level-zero-raytracing-support-1.0.0/testing/cornell_box_reference.tga000066400000000000000000030000221450534701400261450ustar00rootroot00000000000000                                                          ! ! " " # # $ $ % % & & ' ' ( ( ) ) * * + + , , - - . . / / 0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 : : ; ; < < = = > > ? ? @ @ A A B B C C D D D E E F F G G H H I I J J K K L L M M N N O O P P Q Q R R S S T T U U V V W W X X Y Y Z Z [ [ \ \ ] ] ^ ^ _ _ ` ` a a b b c c d d e e f f g g h h i i j j k k l l m m n n n o o p p q q r r s s t t u~ u~ v} v} w| w| x{ x{ yz yz zy zy {x {x |w |w }v }v ~u ~u t t s s r r q q p p o o n n m m l l k k j j i i h h g g f f e e d d c c b b a a ` ` _ _ ^ ^ ] ] \ \ [ [ Z Z Y Y X X W W V V U U U T T S S R R Q Q P P O O N N M M L L K K J J I I H H G G F F E E D D C C B B A A @ @ ? ? > > = = < < ; ; : : 9 9 8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1 0 0 / / . . - - , , + + + * * ) ) ( ( ' ' & & % % $ $ # # " " ! !                                                                                                                   ! ! " " # # $ $ % % & & ' ' ( ( ) ) * * + + , , - - . . . / / 0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 : : ; ; < < = = > > ? ? @ @ A A B B C C D D E E F F G G H H I I J J K K L L M M N N O O P P Q Q R R S S T T U U V V W W X X Y Y Z Z [ [ \ \ ] ] ^ ^ _ _ ` ` a a b b c c d d e e f f g g h h i i j j k k l l m m m n n o o p p q q r r s s~ t~ t} u} u| v| v{ w{ wz xz xy yy yx zx zw {w {v |v |u }u }t ~t ~s s r r q q p p o o n n m m l l k k j j i i h h g g f f e e d d c c b b a a ` ` _ _ ^ ^ ] ] \ \ [ [ Z Z Y Y X X W W V V U U T T S S R R Q Q P P O O N N M M L L K K J J I I H H G G F F E E D D C C B B A A @ @ @ ? ? > > = = < < ; ; : : 9 9 8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1 0 0 / / . . - - , , + + * * ) ) ( ( ' ' & & % % $ $ # # " " ! !                                                                                  !!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??@@AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRRSSTTUUVVWWXXYYZZ[[\\]]^^__``aabbccddeeffgghhiiijjkkllmmnnooppqqr~r~s}s}t|t|u{u{vzvzwywyxxxxywywzvzv{u{u|t|t}s}s~r~rqqppoonnmmllkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!                                            !!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??@@AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRRSSTTUUVVWWXXYYZZ[[\\]]^^__``aabbccddeeffgghhiijjkkllmmnnoopp~q~q}r}r|s|s{t{tzuzuyvyvxwxwwxwxvyvyuzuzt{t{s|s|r}r}q~q~ppoonnmmllkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!                                            !!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??@@AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRRSSTTUUVVWWXXYYZZ[[\\]]^^__``aabbccddeeffgghhiijjkkllmmnn~o~o}p}p|q|q{r{rzszsytytxuxuwvwvvwvwuxuytytzszs{r{r|q|q}p}p~o~onnmmllkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!                                          !!""##$$%%&&''(())**++,,--..//0011223345566778899::;;<<==>>??@@AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRRSSTTUUVVWWXXYYZZ[[\\]]^^__``aabbccddeeffgghhiijjkkllm~m~n}n}o|o|p{p{qzqzryrysxsxtwuwuvvvvuwuwtxtxsysyrzrzq{q{p|p|o}o}n~n~mmllkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@?>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!                                    !!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??@@AABBCCDDEEFFGGHIIJJKKLLMMNNOOPPQQRRSSTTUUVVWWXXYYZZ[[\\]]^^__``aabbccddeeffgghhiijjkk~l~l}m}m|n|n{o{ozpzpyqyqxrxrwswtvtvuuuuvtvtwswsxrxryqyqzpzp{o{o|n|n}m}m~l~lkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::99887766554433221100//..--,,++*))((''&&%%$$##""!!                              !!""##$$%%&&''(())**++,,--..//0011223445566778899::;;<<==>>??@@AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRSSTTUUVVWWXXYYZZ[[\\]]^^__``aabbccddeeffgghhiij~j~k}k}l|l|m{m{nznzoyoypxpxqwqwrvsvsututtutusvsvrwrwqxqxpypyozozn{n{m|m|l}l}k~k~jjiihhggffeeddccbbaa``_^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@?>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!                        !!""##$$%%&''(())**++,,--..//00112233445566778899::;;<<==>>?@@AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRRSSTTUUVVWWXYYZZ[[\\]]^^__``aabbccddeeffgghh~i~i}j}j|k|k{l{lzmzmynynxoxowpwpvqvquruststtstsururvqvqwpwpxoxoynynzmzm{l{l|k|k}j}j~i~ihhggfeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::9988776655443221100//..--,,++**))((''&&%%$$##""!!                               !!""##$$%%&&''(())**++,,--..//0011233445566778899::;;<<==>>??@@AABBCCDDEEFFGHHIIJJKKLLMMNNOOPPQQRRSSTTUUVVWWXXYYZZ[[\]]^^__``aabbccddeeffg~g~h}h}i|i|j{j{kzkzlylymxmxnwnwovovpupuqtqtrssssrtrtququpvpvowownxnxmymylzlzk{k{j|i|i}h}h~g~gffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@??>>==<<;;::99887766554433221100//..--,,++*))((''&&%%$$##""!!                                     !!""##$$%%&&''(()**++,,--..//00112233445566778899::;<<==>>??@@AABBCCDDEEFFGGHHIIJJKKLLMNNOOPPQQRRSSTTUUVVWWXXYYZZ[[\\]]^^_``aabbccddee~f~f}g}g|h|h{i{izjzjykykxlxlwmwmvnvnuouotptpsqsrrrrsqsqtptpuouovnvnwmwlxlxkykyjzjzi{i{h|h|g}g}f~f~eeddccbbaa``__^^]]\\[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIHHGGFFEEDDCCBBAA@@??>>==<<;;::9988766554433221100//..--,,++**))((''&&%%$##""!!                                            !!"##$$%%&&''(())**++,,--..//0011233445566778899::;;<<==>>??@@AABCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRSSTTUUVVWWXXYYZZ[[\\]]^^__``abbccd~d~e}e}f|f|g{g{hzhziyiyjxjxkwkwlvlvmumuntntososprprqqrqrpspsotntnumumvlvlwkwkxjxjyiyizhzh{g{g|f|f}e}e~d~dccbbaa``_^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPONNMMLLKKJJIIHHGGFFEEDDCCBBAA@??>>==<<;;::9988776655443322110//..--,,++**))((''&&%%$$##""!!                                             !!""##$$%%&&''(())**+,,--..//0011223344556677889::;;<<==>>??@@AABBCCDDEEFFGHHIIJJKKLLMMNNOOPPQQRRSSTTUVVWWXXYYZZ[[\\]]^^__``aab~b~c}d}d|e|e{f{fzgzgyhyhxixiwjwjvkvkulultmtmsnsnroroqppppqorornsnsmtmtlulukvkvjwjwixixhyhygzgzf{f{e|e|d}d}c~b~baa``__^^]]\\[[ZZYYXXWWVVUTTSSRRQQPPOONNMMLLKKJJIIHHGFFEEDDCCBBAA@@??>>==<<;;::9887766554433221100//..--,,+**))((''&&%%$$##""!!                                            !!""##$$%&&''(())**++,,--..//0011233445566778899::;;<<==>??@@AABBCCDDEEFFGGHHIIJJKLLMMNNOOPPQQRRSSTTUUVVWWXYYZZ[[\\]]^^__``~a~a}b}b|c|c{d{ezezfyfygxgxhwhwivivjujuktktlslsmrmqnqnpopoopopnqnrmrmslsltktkujujviviwhwhxgxgyfyezezd{d{c|c|b}b}a~a``__^^]]\\[[ZZYXXWWVVUUTTSSRRQQPPOONNMMLKKJJIIHHGGFFEEDDCCBBAA@??>>==<<;;::9988776655443221100//..--,,++**))((''&%%$$##""!!                                                                                     ! ! " " # # $ $ % % & & ' ' ( ( ) ) * * + + , - - . . / / 0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 8 8 9 9 : : ; ; < < = = > > ? ? @ @ A A B B C D D E E F F G G H H I I J J K K L L M M N O O P P Q Q R R S S T T U U V V W W X X Y Y Z [ [ \ \ ] ] ^ ^ _~ _~ `} `} a| a| b{ b{ cz cz dy dy ex fx fw gw gv hv hu iu it jt js kr kr lq lq mp mp no no on on pm pm ql rl rk sk sj tj ti ui uh vg vg wf wf xe xe yd yd zc zc {b {b |a |a }` ~` ~_ _ ^ ^ ] ] \ [ [ Z Z Y Y X X W W V V U U T T S S R R Q P P O O N N M M L L K K J J I I H H G G F F E D D C C B B A A @ @ ? ? > > = = < < ; ; : 9 9 8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1 0 0 / / . - - , , + + * * ) ) ( ( ' ' & & % % $ $ # " " ! !                                                         "!!                     !!""""""""""""""""""" " " " " " " " " " """"""""""""""""""""""""""""""""""" " "!"!"""""#"#"$"$"%"%"&"&"'"("(")")"*"*"+"+",","-"-"."."/"/"0"0"1"1"2"3"3"4"4"5"5"6"6"7"7"8"8"9"9":":";";"<"="=">">"?"?"@"@"A"A"B"B"C"C"D"D"E"E"F"F"G"H"H"I"I"J"J"K"K"L"L"M"M"N"N"O"O"P"P"Q"R"R"S"S"T"T"U"U"V"V"W"W"X"X"Y"Y"Z"Z"["["\"]"]~"^~"^}"_}"_|"`|"`{"a{"az"bz"by"cy"cx"dx"dw"ew"ev"fv"gu"gu"ht"hs"is"ir"jr"jq"kq"kp"lp"lo"mo"mn"nn"nm"om"ol"pl"pk"qk"rj"ri"si"sh"th"tg"ug"uf"vf"ve"we"wd"xd"xc"yc"yb"zb"za"{a"|`"|`"}_"}^"~^"~]"]"\"\"["["Z"Z"Y"Y"X"X"W"W"V"V"U"T"T"S"S"R"R"Q"Q"P"P"O"O"N"N"M"M"L"L"K"K"J"I"I"H"H"G"G"F"F"E"E"D"D"C"C"B"B"A"A"@"?"?">">"="="<"<";";":":"9"9"8"8"7"7"6"6"5"4"4"3"3"2"2"1"1"0"0"/"/"."."-"-",","+"*"*")")"("("'"'"&"&"%"%"$"$"#"#"""""!"!" """""""""""""""""""""""""""""""""""" " " " " " " " " """"""""""""""""""      "###""!!                     !!""##$$$$$$$$$$$$$$$$$$ $ $ $ $ $ $ $ $ $ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $ $!$!$"$"$#$$$$$%$%$&$&$'$'$($($)$)$*$*$+$+$,$,$-$.$.$/$/$0$0$1$1$2$2$3$3$4$4$5$5$6$7$7$8$8$9$9$:$:$;$;$<$<$=$=$>$>$?$?$@$A$A$B$B$C$C$D$D$E$E$F$F$G$G$H$H$I$I$J$K$K$L$L$M$M$N$N$O$O$P$P$Q$Q$R$R$S$S$T$U$U$V$V$W$W$X$X$Y$Y$Z$Z$[$[~$\~$\}$]}$^|$^|$_{$_{$`z$`z$ay$ay$bx$bx$cw$cw$dv$dv$eu$et$ft$fs$gs$hr$hr$iq$iq$jp$jp$ko$ko$ln$ln$mm$mm$nl$nk$ok$oj$pj$pi$qi$rh$rh$sg$sg$tf$tf$ue$ue$vd$vd$wc$wc$xb$xa$ya$y`$z`$z_${_$|^$|^$}]$}]$~\$~\$[$[$Z$Z$Y$Y$X$W$W$V$V$U$U$T$T$S$S$R$R$Q$Q$P$P$O$O$N$M$M$L$L$K$K$J$J$I$I$H$H$G$G$F$F$E$D$D$C$C$B$B$A$A$@$@$?$?$>$>$=$=$<$<$;$:$:$9$9$8$8$7$7$6$6$5$5$4$4$3$3$2$2$1$0$0$/$/$.$.$-$-$,$,$+$+$*$*$)$)$($($'$&$&$%$%$$$$$#$#$"$"$!$!$ $ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $ $ $ $ $ $ $ $ $$$$$$$$$$$$$$$$$#!    "#%%$$##""!!                      !!""##$$%%%%%%%%%%%%%%%%%%% % % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % %!%!%"%"%#%#%$%$%%%%%&%&%'%'%(%)%)%*%*%+%+%,%,%-%-%.%.%/%/%0%0%1%1%2%3%3%4%4%5%5%6%6%7%7%8%8%9%9%:%:%;%<%<%=%=%>%>%?%?%@%@%A%A%B%B%C%C%D%E%E%F%F%G%G%H%H%I%I%J%J%K%K%L%L%M%N%N%O%O%P%P%Q%Q%R%R%S%S%T%T%U%U%V%W%W%X%X%Y%Y%Z~%Z~%[}%[}%\|%\|%]{%]{%^z%^z%_y%`y%`x%ax%aw%bw%bv%cu%cu%dt%dt%es%es%fr%fr%gq%gq%hp%ip%io%jo%jn%kn%km%ll%ll%mk%mk%nj%nj%oi%oi%ph%ph%qg%rg%rf%sf%se%te%td%uc%uc%vb%vb%wa%wa%x`%x`%y_%y_%z^%{^%{]%|]%|\%}\%}[%~Z%~Z%Y%Y%X%X%W%W%V%V%U%U%T%T%S%S%R%Q%Q%P%P%O%O%N%N%M%M%L%L%K%K%J%J%I%H%H%G%G%F%F%E%E%D%D%C%C%B%B%A%A%@%?%?%>%>%=%=%<%<%;%;%:%:%9%9%8%8%7%6%6%5%5%4%4%3%3%2%2%1%1%0%0%/%/%.%-%-%,%,%+%+%*%*%)%)%(%(%'%'%&%&%%%$%$%#%#%"%"%!%!% % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % % %%%%%%%%%%%%%%%%%%#!    "#%''&%%$$##""!!                      !!"##$$%%&&''''''''''''''''''' ' ' ' ' ' ' ' ' ''''''''''''''''''''''''''''''''''' ' '!'!'"'"'#'#'$'$'%'&'&'''''('(')')'*'*'+'+',','-'.'.'/'/'0'0'1'1'2'2'3'3'4'4'5'5'6'7'7'8'8'9'9':':';';'<'<'='='>'?'?'@'@'A'A'B'B'C'C'D'D'E'E'F'F'G'H'H'I'I'J'J'K'K'L'L'M'M'N'N'O'P'P'Q'Q'R'R'S'S'T'T'U'U'V'V'W'X'X~'Y~'Y}'Z}'Z|'[|'[{'\{'\z']z']y'^y'^x'_x'_w'`v'av'au'bu'bt'ct'cs'ds'dr'er'eq'fq'fp'gp'go'ho'in'im'jm'jl'kl'kk'lk'lj'mj'mi'ni'nh'oh'og'pg'pf'qe're'rd'sd'sc'tc'tb'ub'ua'va'v`'w`'w_'x_'x^'y^'z]'z\'{\'{['|['|Z'}Z'}Y'~Y'~X'X'W'W'V'V'U'T'T'S'S'R'R'Q'Q'P'P'O'O'N'N'M'M'L'K'K'J'J'I'I'H'H'G'G'F'F'E'E'D'C'C'B'B'A'A'@'@'?'?'>'>'='='<'<';':':'9'9'8'8'7'7'6'6'5'5'4'4'3'2'2'1'1'0'0'/'/'.'.'-'-',','+'*'*')')'('('''''&'&'%'%'$'$'#'#'"'!'!' ' ''''''''''''''''''''''''''''''''''' ' ' ' ' ' ' ' ' ''''''''''''''''''%"      "#%')((''&&%$$##""!!                     !!""##$$%%&&''())))))))))))))))))) ) ) ) ) ) ) ) ) ))))))))))))))))))))))))))))))))))) ) )!)!)")#)#)$)$)%)%)&)&)')')()()))))*)+)+),),)-)-).).)/)/)0)0)1)2)2)3)3)4)4)5)5)6)6)7)7)8)8)9):):););)<)<)=)=)>)>)?)?)@)@)A)B)B)C)C)D)D)E)E)F)F)G)G)H)H)I)J)J)K)K)L)L)M)M)N)N)O)O)P)P)Q)R)R)S)S)T)T)U)U)V)V~)W~)W})X})X|)Y|)Z{)Z{)[z)[z)\y)\y)]x)]x)^w)^v)_v)_u)`u)`t)at)bs)bs)cr)cr)dq)dq)ep)ep)fo)fn)gn)gm)hm)hl)il)jk)jk)kj)kj)li)li)mh)mh)ng)nf)of)oe)pe)pd)qd)rc)rc)sb)sb)ta)ta)u`)u`)v_)v^)w^)w])x])x\)y\)z[)z[){Z){Z)|Y)|Y)}X)}X)~W)~V)V)U)U)T)T)S)S)R)R)Q)Q)P)O)O)N)N)M)M)L)L)K)K)J)J)I)I)H)G)G)F)F)E)E)D)D)C)C)B)B)A)A)@)?)?)>)>)=)=)<)<););):):)9)9)8)7)7)6)6)5)5)4)4)3)3)2)2)1)1)0)/)/).).)-)-),),)+)+)*)*)))))()')')&)&)%)%)$)$)#)#)")")!)!) ))))))))))))))))))))))))))))))))))) ) ) ) ) ) ) ) ) ) ))))))))))))))))(&$"      "#%')**))((''&&%%$$#""! !             ! !""##$$%%&''(())******************* * * * * * * * * * ********************************** * *!*!*"*"*#*#*$*$*%*%*&*'*'*(*(*)*)*****+*+*,*,*-*-*.*/*/*0*0*1*1*2*2*3*3*4*4*5*6*6*7*7*8*8*9*9*:*:*;*;*<*<*=*>*>*?*?*@*@*A*A*B*B*C*C*D*E*E*F*F*G*G*H*H*I*I*J*J*K*K*L*M*M*N*N*O*O*P*P*Q*Q*R*R*S*T*T*U~*U~*V}*V}*W|*W|*X{*X{*Yz*Yz*Zy*[y*[x*\w*\w*]v*]v*^u*^u*_t*_t*`s*`s*ar*ar*bq*cq*cp*do*do*en*en*fm*fm*gl*gl*hk*hk*ij*jj*ji*kh*kh*lg*lg*mf*mf*ne*ne*od*od*pc*pc*qb*rb*ra*s`*s`*t_*t_*u^*u^*v]*v]*w\*w\*x[*y[*yZ*zY*zY*{X*{X*|W*|W*}V*}V*~U*~U*T*T*S*S*R*Q*Q*P*P*O*O*N*N*M*M*L*L*K*J*J*I*I*H*H*G*G*F*F*E*E*D*D*C*B*B*A*A*@*@*?*?*>*>*=*=*<*;*;*:*:*9*9*8*8*7*7*6*6*5*4*4*3*3*2*2*1*1*0*0*/*/*.*.*-*,*,*+*+*****)*)*(*(*'*'*&*%*%*$*$*#*#*"*"*!*!* * ********************************** * * * * * * * * * *****************(&#!     "#%'(*,,++**)((''&&%%$$# # " ! !       ! ! " " ##$%%&&''(())**+,,,,,,,,,,,,,,,,,,, , , , , , , , , , ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, , ,!,!,",",#,$,$,%,%,&,&,',',(,(,),),*,+,+,,,,,-,-,.,.,/,/,0,0,1,2,2,3,3,4,4,5,5,6,6,7,7,8,9,9,:,:,;,;,<,<,=,=,>,>,?,@,@,A,A,B,B,C,C,D,D,E,E,F,F,G,H,H,I,I,J,J,K,K,L,L,M,M,N,O,O,P,P,Q,Q,R,R,S~,S~,T},T},U|,V|,V{,W{,Wz,Xz,Xy,Yy,Yx,Zw,Zw,[v,[v,\u,]u,]t,^t,^s,_s,_r,`r,`q,ap,ap,bo,bo,cn,dn,dm,em,el,fl,fk,gk,gj,hi,hi,ih,ih,jg,kg,kf,lf,le,me,md,nd,nc,ob,ob,pa,pa,q`,r`,r_,s_,s^,t^,t],u],u\,v[,v[,wZ,wZ,xY,yY,yX,zX,zW,{W,{V,|V,|U,}T,}T,~S,~S,R,R,Q,Q,P,P,O,O,N,M,M,L,L,K,K,J,J,I,I,H,H,G,F,F,E,E,D,D,C,C,B,B,A,A,@,?,?,>,>,=,=,<,<,;,;,:,:,9,8,8,7,7,6,6,5,5,4,4,3,3,2,1,1,0,0,/,/,.,.,-,-,,,,,+,*,*,),),(,(,',',&,&,%,%,$,#,#,",",!,!, , ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, , , , , , , , , , ,,,,,,,,,,,,,,,,,*'%#!      "#%'(*,.--,,++**))(''&&%% $ $ # # " " !  ! ! " # # $ $ %%&&''())**++,,--.................. . . . . . . . . ................................... . .!.".".#.#.$.$.%.%.&.&.'.(.(.).).*.*.+.+.,.,.-.-..././.0.0.1.1.2.2.3.3.4.4.5.6.6.7.7.8.8.9.9.:.:.;.<.<.=.=.>.>.?.?.@.@.A.A.B.C.C.D.D.E.E.F.F.G.G.H.H.I.J.J.K.K.L.L.M.M.N.N.O.P.P.Q.Q~.R~.R}.S}.S|.T|.T{.U{.Uz.Vz.Wy.Wy.Xx.Xw.Yw.Yv.Zv.Zu.[u.[t.\t.\s.]s.^r.^q._q._p.`p.`o.ao.an.bn.bm.cm.dl.dl.ek.ej.fj.fi.gi.gh.hh.hg.ig.if.jf.ke.ke.ld.lc.mc.mb.nb.na.oa.o`.p`.p_.q_.r^.r].s].s\.t\.t[.u[.uZ.vZ.vY.wY.xX.xX.yW.yV.zV.zU.{U.{T.|T.|S.}S.}R.~R.Q.Q.P.O.O.N.N.M.M.L.L.K.K.J.I.I.H.H.G.G.F.F.E.E.D.D.C.B.B.A.A.@.@.?.?.>.>.=.=.<.;.;.:.:.9.9.8.8.7.7.6.5.5.4.4.3.3.2.2.1.1.0.0./.....-.-.,.,.+.+.*.*.).).(.'.'.&.&.%.%.$.$.#.#.".!.!. . .................................. . . . . . . . . . .................+)'%"          "#%'(*,.///..-,,++**))(('' & % % $ $ # # " "!!  !!" " # # $ $ % % & ''(())**++,,-..//000000000000000000 0 0 0 0 0 0 0 0 0000000000000000000000000000000000 0 0!0!0"0"0#0#0$0$0%0&0&0'0'0(0(0)0)0*0*0+0,0,0-0-0.0.0/0/0000010202030304040505060607070809090:0:0;0;0<0<0=0=0>0?0?0@0@0A0A0B0B0C0C0D0E0E0F0F0G0G0H0H0I0I0J0J0K0L0L0M0M0N0N0O0O~0P~0P}0Q}0R|0R|0S{0S{0Tz0Tz0Uy0Ux0Vx0Vw0Ww0Xv0Xv0Yu0Yu0Zt0Zt0[s0[s0\r0\q0]q0]p0^p0_o0_o0`n0`n0am0am0bl0bk0ck0cj0dj0ei0ei0fh0fh0gg0gg0hf0he0ie0id0jd0kc0kc0lb0lb0ma0ma0n`0n`0o_0o^0p^0p]0q]0r\0r\0s[0s[0tZ0tZ0uY0uX0vX0vW0wW0xV0xV0yU0yU0zT0zT0{S0{R0|R0|Q0}Q0~P0~P0O0O0N0N0M0M0L0K0K0J0J0I0I0H0H0G0G0F0E0E0D0D0C0C0B0B0A0A0@0?0?0>0>0=0=0<0<0;0;0:0:0908080707060605050404030202010100000/0/0.0.0-0,0,0+0+0*0*0)0)0(0(0'0'0&0%0%0$0$0#0#0"0"0!0!0 00000000000000000000000000000000000 0 0 0 0 0 0 0 0 0000000000000000/-+)&$"           "#%'(*,./1100//..--,,+**))( ( ' ' & & % $ $ ##""!!    !!""## $ $ % & & ' ' ( ())**+,,--..//001111111111111111111 1 1 1 1 1 1 1 1 1111111111111111111111111111111111 1 1!1!1"1#1#1$1$1%1%1&1&1'1'1(1)1)1*1*1+1+1,1,1-1-1.1/1/101011111212131314151516161717181819191:1;1;1<1<1=1=1>1>1?1?1@1A1A1B1B1C1C1D1D1E1E1F1G1G1H1H1I1I1J1J1K1K1L1L1M1N~1N~1O}1O}1P|1P|1Q{1Q{1Rz1Rz1Sy1Tx1Tx1Uw1Uw1Vv1Vv1Wu1Wu1Xt1Xt1Ys1Zr1Zr1[q1[q1\p1\p1]o1]o1^n1^n1_m1`l1`l1ak1ak1bj1bj1ci1ci1dh1dh1eg1ff1ff1ge1ge1hd1hd1ic1ic1jb1jb1ka1l`1l`1m_1m_1n^1n^1o]1o]1p\1p\1q[1rZ1rZ1sY1sY1tX1tX1uW1uW1vV1vV1wU1xT1xT1yS1yS1zR1zR1{Q1{Q1|P1|P1}O1~N1~N1M1M1L1L1K1K1J1J1I1H1H1G1G1F1F1E1E1D1D1C1B1B1A1A1@1@1?1?1>1>1=1<1<1;1;1:1:1919181817161615151414131312121110101/1/1.1.1-1-1,1,1+1*1*1)1)1(1(1'1'1&1&1%1$1$1#1#1"1"1!1!1 1 1111111111111111111111111111111111 1 1 1 1 1 1 1 1 11111111111111111/-*(&$!           "#%'(*,./133221100/..--,,++* ) ) ( ( ' ' & & %%$##""!!    !!""#$$%% & & ' ' ( ( ) * *++,,--.//0011223333333333333333333 3 3 3 3 3 3 3 3 3333333333333333333333333333333333 3!3!3"3"3#3#3$3$3%3%3&3'3'3(3(3)3)3*3*3+3+3,3-3-3.3.3/3/3030313232333334343535363637383839393:3:3;3;3<3<3=3>3>3?3?3@3@3A3A3B3B3C3D3D3E3E3F3F3G3G3H3I3I3J3J3K3K3L~3L~3M}3M}3N|3O|3O{3P{3Pz3Qz3Qy3Rx3Rx3Sw3Sw3Tv3Uv3Uu3Vu3Vt3Wt3Ws3Xr3Xr3Yq3Yq3Zp3[p3[o3\o3\n3]m3]m3^l3^l3_k3`k3`j3aj3ai3bi3bh3cg3cg3df3df3ee3fe3fd3gd3gc3hc3hb3ia3ia3j`3j`3k_3l_3l^3m^3m]3n]3n\3o[3o[3pZ3pZ3qY3rY3rX3sX3sW3tV3tV3uU3uU3vT3wT3wS3xS3xR3yR3yQ3zP3zP3{O3{O3|N3}N3}M3~M3~L3L3K3J3J3I3I3H3H3G3G3F3F3E3D3D3C3C3B3B3A3A3@3?3?3>3>3=3=3<3<3;3;3:393938383737363635353433333232313130303/3/3.3-3-3,3,3+3+3*3*3)3(3(3'3'3&3&3%3%3$3$3#3"3"3!3!3 3 3333333333333333333333333333333333 3 3 3 3 3 3 3 3 333333333333333331.,*'%#!           "#%'(*,./1355443221100//.--,, + + * * ) ) ( ' '&&%%$$#""!!    !""##$$%%&&' ( ( ) ) * * + + ,--..//001123344555555555555555555 5 5 5 5 5 5 5 5 5 555555555555555555555555555555555 5 5!5!5"5"5#5#5$5%5%5&5&5'5'5(5(5)5*5*5+5+5,5,5-5-5.5.5/505051515252535354555556565757585859595:5;5;5<5<5=5=5>5>5?5@5@5A5A5B5B5C5C5D5D5E5F5F5G5G5H5H5I5I5J~5K~5K}5L}5L|5M|5M{5N{5Nz5Oz5Oy5Px5Qx5Qw5Rw5Rv5Sv5Su5Tu5Tt5Us5Vs5Vr5Wr5Wq5Xq5Xp5Yp5Yo5Zo5Zn5[m5\m5\l5]l5]k5^k5^j5_j5_i5`h5ah5ag5bg5bf5cf5ce5de5dd5ed5ec5fb5gb5ga5ha5h`5i`5i_5j_5j^5k]5l]5l\5m\5m[5n[5nZ5oZ5oY5pY5pX5qW5rW5rV5sV5sU5tU5tT5uT5uS5vR5wR5wQ5xQ5xP5yP5yO5zO5zN5{N5{M5|L5}L5}K5~K5~J5J5I5I5H5G5G5F5F5E5E5D5D5C5C5B5A5A5@5@5?5?5>5>5=5<5<5;5;5:5:5959585857565655555454535352515150505/5/5.5.5-5-5,5+5+5*5*5)5)5(5(5'5&5&5%5%5$5$5#5#5"5"5!5 5 5555555555555555555555555555555555 5 5 5 5 5 5 5 5 5555555555555555520.+)'%"             "#%'(*,./13576655443321100//.. - , , + + * * ) )(('&&%%$$##"!!   !!""##$$%&&''(() ) * * + , , - - ..//011223344566777777777777777777 7 7 7 7 7 7 7 7 7777777777777777777777777777777777 7 7!7!7"7#7#7$7$7%7%7&7&7'7(7(7)7)7*7*7+7+7,7-7-7.7.7/7/7070717272737374747575767677787879797:7:7;7;7<7=7=7>7>7?7?7@7@7A7B7B7C7C7D7D7E7E7F7G7G7H7H~7I~7I}7J}7J|7K|7K{7L{7Mz7My7Ny7Nx7Ox7Ow7Pw7Pv7Qv7Ru7Ru7St7Ss7Ts7Tr7Ur7Uq7Vq7Wp7Wp7Xo7Xn7Yn7Ym7Zm7Zl7[l7[k7\k7]j7]i7^i7^h7_h7_g7`g7`f7af7be7bd7cd7cc7dc7db7eb7ea7fa7g`7g`7h_7h^7i^7i]7j]7j\7k\7l[7l[7mZ7mY7nY7nX7oX7oW7pW7pV7qV7rU7rT7sT7sS7tS7tR7uR7uQ7vQ7wP7wO7xO7xN7yN7yM7zM7zL7{L7|K7|K7}J7}I7~I7~H7H7G7G7F7F7E7D7D7C7C7B7B7A7A7@7?7?7>7>7=7=7<7<7;7;7:7979787877777676757474737372727171707/7/7.7.7-7-7,7,7+7*7*7)7)7(7(7'7'7&7&7%7$7$7#7#7"7"7!7!7 7777777777777777777777777777777777 7 7 7 7 7 7 7 7 7777777777777777642/-+)&$"              "#%'(*,./135788877665443322110/ / . . - - , , + **))((''&%%$$##""!    !!""##$%%&&''(()**+ + , , - - . / / 0011223445566778999999999999999999 9 9 9 9 9 9 9 9 9999999999999999999999999999999999 9!9!9"9"9#9#9$9$9%9&9&9'9'9(9(9)9)9*9+9+9,9,9-9-9.9.9/9090919192929393949595969697979898999:9:9;9;9<9<9=9=9>9?9?9@9@9A9A9B9B9C9D9D9E9E9F9F~9G~9G}9H}9I|9I|9J{9J{9Kz9Ky9Ly9Lx9Mx9Nw9Nw9Ov9Ov9Pu9Pt9Qt9Qs9Rs9Sr9Sr9Tq9Tq9Up9Uo9Vo9Vn9Wn9Xm9Xm9Yl9Yl9Zk9Zj9[j9[i9\i9]h9]h9^g9^g9_f9_e9`e9`d9ad9bc9bc9cb9cb9da9d`9e`9e_9f_9g^9g^9h]9h]9i\9i[9j[9jZ9kZ9kY9lY9mX9mX9nW9nW9oV9oU9pU9pT9qT9rS9rS9sR9sR9tQ9tP9uP9uO9vO9wN9wN9xM9xM9yL9yK9zK9zJ9{J9|I9|I9}H9}H9~G9~F9F9E9E9D9D9C9C9B9A9A9@9@9?9?9>9>9=9<9<9;9;9:9:9999989797969695959494939292919190909/9/9.9-9-9,9,9+9+9*9*9)9(9(9'9'9&9&9%9%9$9#9#9"9"9!9!9 9 999999999999999999999999999999999 9 9 9 9 9 9 9 9 99999999999999998641/-*(&$!                 "#%'(*,./13578:::988776655433221 1 0 0 / . . - - ,,++*))((''&&%$$##""!!   !!""#$$%%&&'(())**++,- - . . / / 0 0 1 223344556778899::;;;;;;;;;;;;;;;;; ; ; ; ; ; ; ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ;!;!;";";#;$;$;%;%;&;&;';';(;););*;*;+;+;,;-;-;.;.;/;/;0;0;1;2;2;3;3;4;4;5;5;6;7;7;8;8;9;9;:;:;;;<;<;=;=;>;>;?;?;@;A;A;B;B;C;C;D;D~;E~;F};F};G|;G|;H{;H{;Iz;Iy;Jy;Kx;Kx;Lw;Lw;Mv;Mv;Nu;Nt;Ot;Ps;Ps;Qr;Qr;Rq;Rq;Sp;To;To;Un;Un;Vm;Vm;Wl;Wk;Xk;Yj;Yj;Zi;Zi;[h;[h;\g;\f;]f;^e;^e;_d;_d;`c;`c;ab;aa;ba;c`;c`;d_;d_;e^;e^;f];f\;g\;h[;h[;iZ;iZ;jY;jY;kX;kW;lW;mV;mV;nU;nU;oT;oT;pS;pR;qR;rQ;rQ;sP;sP;tO;tO;uN;vM;vM;wL;wL;xK;xK;yJ;yJ;zI;{H;{H;|G;|G;}F;}F;~E;~D;D;C;C;B;B;A;A;@;?;?;>;>;=;=;<;<;;;:;:;9;9;8;8;7;7;6;5;5;4;4;3;3;2;2;1;0;0;/;/;.;.;-;-;,;+;+;*;*;););(;(;';&;&;%;%;$;$;#;";";!;!; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; ; ; ; ; ; ;;;;;;;;;;;;;;;;:8531.,*(%#!                  "#%'(*,./13578:<<;;::998876655443 3 2 1 1 0 0 / / .--,,++**)((''&&%%$##""!!   !""##$$%%&''(())**+,,--.. / 0 0 1 1 2 2 3 34556677889::;;<<<<<<<<<<<<<<<<<<< < < < < < < < < <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< < <><><=<<<<<;<;<:<:<9<8<8<7<7<6<6<5<5<4<3<3<2<2<1<1<0<0>==<<;;:998877655 4 4 3 3 2 2 1 0 0//..-,,++**))(''&&%%$##""!!   !!""##$$%&&''(()**++,,--.//00 1 1 2 3 3 4 4 5 56678899::;<<==>>>>>>>>>>>>>>>>>>> > > > > > > > >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> > >!>!>">">#>#>$>%>%>&>&>'>'>(>)>)>*>*>+>+>,>,>->.>.>/>/>0>0>1>2>2>3>3>4>4>5>5>6>7>7>8>8>9>9>:>;>;><><>=>=>>>>>?>@>@>A~>A~>B}>B}>C|>D|>D{>E{>Ez>Fy>Fy>Gx>Gx>Hw>Iw>Iv>Ju>Ju>Kt>Kt>Ls>Ms>Mr>Nr>Nq>Op>Op>Po>Po>Qn>Rn>Rm>Sl>Sl>Tk>Tk>Uj>Vj>Vi>Wi>Wh>Xg>Xg>Yf>Yf>Ze>[e>[d>\c>\c>]b>]b>^a>^a>_`>``>`_>a^>a^>b]>b]>c\>d\>d[>eZ>eZ>fY>fY>gX>gX>hW>iW>iV>jU>jU>kT>kT>lS>mS>mR>nQ>nQ>oP>oP>pO>pO>qN>rN>rM>sL>sL>tK>tK>uJ>vJ>vI>wH>wH>xG>xG>yF>yF>zE>{E>{D>|C>|C>}B>}B>~A>A>@>?>?>>>>>=>=><><>;>:>:>9>9>8>8>7>6>6>5>5>4>4>3>3>2>1>1>0>0>/>/>.>->->,>,>+>+>*>*>)>(>(>'>'>&>&>%>$>$>#>#>">">!>!> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> > > > > > > > > >>>>>>>>>>>>>>>>>;97420-+)&$"                   " #%'(*,./13578:<>@@??>>=<<;;::98877 6 6 5 5 4 3 3 2 2110//..--,++**))(('&&%%$$#""!! !!""#$$%%&&''())**++,--..//01122 3 3 4 4 5 6 6 77889::;;<<==>??@@@@@@@@@@@@@@@@@@ @ @ @ @ @ @ @ @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ @!@!@"@#@#@$@$@%@%@&@'@'@(@(@)@)@*@*@+@,@,@-@-@.@.@/@0@0@1@1@2@2@3@4@4@5@5@6@6@7@7@8@9@9@:@:@;@;@<@=@=@>@>@?~@?~@@}@@}@A|@B|@B{@Cz@Cz@Dy@Dy@Ex@Fx@Fw@Gw@Gv@Hu@Hu@It@Jt@Js@Ks@Kr@Lq@Lq@Mp@Mp@No@Oo@On@Pm@Pm@Ql@Ql@Rk@Sk@Sj@Tj@Ti@Uh@Uh@Vg@Wg@Wf@Xf@Xe@Yd@Yd@Zc@Zc@[b@\b@\a@]a@]`@^_@^_@_^@`^@`]@a]@a\@b[@b[@cZ@dZ@dY@eY@eX@fW@fW@gV@gV@hU@iU@iT@jT@jS@kR@kR@lQ@mQ@mP@nP@nO@oN@oN@pM@pM@qL@rL@rK@sJ@sJ@tI@tI@uH@vH@vG@wG@wF@xE@xE@yD@zD@zC@{C@{B@|A@|A@}@@}@@~?@?@>@=@=@<@<@;@;@:@:@9@8@8@7@7@6@6@5@4@4@3@3@2@2@1@1@0@/@/@.@.@-@-@,@+@+@*@*@)@)@(@'@'@&@&@%@%@$@$@#@"@"@!@!@ @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ @ @ @ @ @ @ @ @@@@@@@@@@@@@@@@@=;8641/-*(&$!                  " # %'(*,./13578:<>@BBAA@??>>==<<;::99 8 8 7 6 6 5 5 443221100/..--,,+**))((''&%%$$##" ! !! ! "##$$%%&''(())**+,,--../001122344 5 5 6 6 7 8 8 99::;<<==>>??@AABBBBBBBBBBBBBBBBBB B B B B B B B B BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB B!B!B"B"B#B#B$B$B%B&B&B'B'B(B(B)B*B*B+B+B,B,B-B.B.B/B/B0B0B1B2B2B3B3B4B4B5B5B6B7B7B8B8B9B9B:B;B;B}B?}B?|B@|B@{BAzBAzBByBCyBCxBDxBDwBEvBEvBFuBGuBGtBHtBHsBIsBIrBJqBJqBKpBLpBLoBMoBMnBNmBNmBOlBPlBPkBQkBQjBRiBRiBShBThBTgBUgBUfBVeBVeBWdBXdBXcBYcBYbBZbBZaB[`B\`B\_B]_B]^B^^B^]B_\B_\B`[Ba[BaZBbZBbYBcXBcXBdWBeWBeVBfVBfUBgTBgTBhSBiSBiRBjRBjQBkPBkPBlOBmOBmNBnNBnMBoMBoLBpKBpKBqJBrJBrIBsIBsHBtGBtGBuFBvFBvEBwEBwDBxCBxCByBBzBBzAB{AB{@B|?B|?B}>B~>B~=B=B@BDDCCBAA@@??>==<<;; : 9 9 8 8 7 7 655443321100//.--,,++*))((''&&%$$ # #!""""!# # $$%&&''(()**++,,-..//001223344556 7 7 8 8 9 9 : ;;<<==>??@@AABCCDDDDDDDDDDDDDDDDDD D D D D D D D D DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD D D!D!D"D"D#D$D$D%D%D&D&D'D(D(D)D)D*D*D+D,D,D-D-D.D.D/D0D0D1D1D2D2D3D4D4D5D5D6D6D7D8D8D9D9D:D:D;~D<~D<}D=}D=|D>|D>{D?zD?zD@yDAyDAxDBxDBwDCvDCvDDuDEuDEtDFtDFsDGrDGrDHqDIqDIpDJpDJoDKnDKnDLmDMmDMlDNlDNkDOjDOjDPiDQiDQhDRhDRgDSfDSfDTeDUeDUdDVdDVcDWcDWbDXaDYaDY`DZ`DZ_D[_D[^D\]D]]D]\D^\D^[D_[D_ZD`YDaYDaXDbXDbWDcWDcVDdUDeUDeTDfTDfSDgSDgRDhQDiQDiPDjPDjODkODkNDlMDmMDmLDnLDnKDoKDoJDpIDpIDqHDrHDrGDsGDsFDtEDtEDuDDvDDvCDwCDwBDxADxADy@Dz@Dz?D{?D{>D|=D|=D}@BDFFEEDCCBBAA@??>>= = < ; ; : : 9 8 877665443322100//..-,,++**)((''&& %!$!$"#"##"#"$!% % &&''())**++,--..//011223345566778 9 9 : : ; ; < ==>>??@AABBCCDEEFFFFFFFFFFFFFFFFFF F F F F F F F F FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF F F!F"F"F#F#F$F$F%F&F&F'F'F(F(F)F*F*F+F+F,F,F-F.F.F/F/F0F0F1F2F2F3F3F4F4F5F6F6F7F7F8F8F9~F:~F:}F;}F;|F<|F<{F=zF>zF>yF?yF?xF@xF@wFAvFBvFBuFCuFCtFDtFDsFErFFrFFqFGqFGpFHpFHoFInFJnFJmFKmFKlFLlFLkFMjFNjFNiFOiFOhFPhFPgFQfFRfFReFSeFSdFTdFTcFUbFVbFVaFWaFW`FX`FX_FY^FZ^FZ]F[]F[\F\\F\[F]ZF^ZF^YF_YF_XF`XF`WFaVFbVFbUFcUFcTFdTFdSFeRFfRFfQFgQFgPFhOFhOFiNFjNFjMFkMFkLFlKFlKFmJFnJFnIFoIFoHFpGFpGFqFFrFFrEFsEFsDFtCFtCFuBFvBFvAFwAFw@Fx?Fy?Fy>Fz>Fz=F{=F{<97420-+)&$"              " # % ' ( *,./13568:<>@BDFHHGFFEEDDCBBAA@@? > > = = < < ; : :99887665544322110//..--,++**))( ' '!&!&"%"%#$$#$#%"%"&!&!' (())**+,,--.//001123344556778899: ; ; < < = = > ??@@AABCCDDEFFGGHHHHHHHHHHHHHHHHHH H H H H H H H HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH H!H!H"H"H#H#H$H%H%H&H&H'H'H(H)H)H*H*H+H+H,H-H-H.H.H/H0H0H1H1H2H2H3H4H4H5H5H6H6H7~H8~H8}H9}H9|H:|H:{H;zHxH>wH?vH@vH@uHAuHAtHBtHBsHCrHDrHDqHEqHEpHFoHGoHGnHHnHHmHImHIlHJkHKkHKjHLjHLiHMiHMhHNgHOgHOfHPfHPeHQeHQdHRcHScHSbHTbHTaHUaHU`HV_HW_HW^HX^HX]HY]HY\HZ[H[[H[ZH\ZH\YH]XH^XH^WH_WH_VH`VH`UHaTHbTHbSHcSHcRHdRHdQHePHfPHfOHgOHgNHhNHhMHiLHjLHjKHkKHkJHlJHlIHmHHnHHnGHoGHoFHpFHpEHqDHrDHrCHsCHsBHtAHuAHu@Hv@Hv?Hw?Hw>Hx=Hy=Hy@BDFHJJIHHGGFFEDDCCBBA @ @ ? ? > > = < <;;:998877655443321100/..--,,+** ) )!(!("'#&#&$%$%%$%$&#'"'"(!(!) **++,,-..//00122334456677899::;;< = = > > ? ? @ AABBCDDEEFFGHHIIJJJJJJJJJJJJJJJJJ J J J J J J J J JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ J J!J!J"J#J#J$J$J%J%J&J'J'J(J(J)J)J*J+J+J,J,J-J-J.J/J/J0J0J1J2J2J3J3J4J4J5~J6~J6}J7}J7|J8|J8{J9zJ:zJ:yJ;yJ;xJvJ>uJ?uJ?tJ@sJAsJArJBrJBqJCqJCpJDoJEoJEnJFnJFmJGmJGlJHkJIkJIjJJjJJiJKhJLhJLgJMgJMfJNfJNeJOdJPdJPcJQcJQbJRbJRaJS`JT`JT_JU_JU^JV^JW]JW\JX\JX[JY[JYZJZYJ[YJ[XJ\XJ\WJ]WJ]VJ^UJ_UJ_TJ`TJ`SJaSJaRJbQJcQJcPJdPJdOJeNJfNJfMJgMJgLJhLJhKJiJJjJJjIJkIJkHJlHJlGJmFJnFJnEJoEJoDJpDJpCJqBJrBJrAJsAJs@Jt?Ju?Ju>Jv>Jv=Jw=Jw@BDFHJLLKKJIIHHGFFEEDDC B B A A @ ? ? > >==<;;::99877665443322100//.--,, + +!*")")#(#($'$'%&&%&%'$'$(#)")"*!*!+ + ,--../001122344556678899:;;<<==> ? ? @ @ A A B CCDDEFFGGHHIJJKKLLLLLLLLLLLLLLLLL L L L L L L L L LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL L L!L"L"L#L#L$L$L%L&L&L'L'L(L)L)L*L*L+L+L,L-L-L.L.L/L0L0L1L1L2L2L3~L4~L4}L5}L5|L6|L6{L7zL8zL8yL9yL9xL:wL;wL;vLsL?sL?rL@rL@qLApLApLBoLCoLCnLDnLDmLElLFlLFkLGkLGjLHjLHiLIhLJhLJgLKgLKfLLeLMeLMdLNdLNcLOcLObLPaLQaLQ`LR`LR_LS_LS^LT]LU]LU\LV\LV[LWZLXZLXYLYYLYXLZXLZWL[VL\VL\UL]UL]TL^SL_SL_RL`RL`QLaQLaPLbOLcOLcNLdNLdMLeMLeLLfKLgKLgJLhJLhILiHLjHLjGLkGLkFLlFLlELmDLnDLnCLoCLoBLpALpALq@Lr@Lr?Ls?Ls>Lt=Lu=Lu@BDFHJLNNMMLKKJJIHHGGFFE D D C C B A A @ @??>==<<;::99887665543322110//.. -!,!,"+"+#*#*$)%(%(&'&''&(%(%)$)$*#*#+",!,!- - .//00112334456677889::;;<==>>??@ A A B B C D D EEFFGHHIIJKKLLMMNNNNNNNNNNNNNNNNN N N N N N N N N NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN N!N!N"N"N#N$N$N%N%N&N&N'N(N(N)N)N*N+N+N,N,N-N-N.N/N/N0N0N1~N2~N2}N3}N3|N4|N4{N5zN6zN6yN7yN7xN8wN9wN9vN:vN:uN;uN;tNrN>qN?pN@pN@oNAoNAnNBnNBmNClNDlNDkNEkNEjNFiNGiNGhNHhNHgNIgNIfNJeNKeNKdNLdNLcNMbNNbNNaNOaNO`NP`NP_NQ^NR^NR]NS]NS\NT[NU[NUZNVZNVYNWYNWXNXWNYWNYVNZVNZUN[TN\TN\SN]SN]RN^RN^QN_PN`PN`ONaONaNNbMNcMNcLNdLNdKNeKNeJNfINgINgHNhHNhGNiFNiFNjENkENkDNlDNlCNmBNnBNnANoANo@Np?Np?Nq>Nr>Nr=Ns=Ns<97420-+)'$ "             " # % ' ( * , - / 13568:<>@BDFHJLNPPOONMMLLKJJIIHHG F F E E D C C B BAA@??>>=<<;;::9887765544322110 0 /!.!."-"-#,$+$+%*%*&)')'(('(')&*&*%+$+$,#,#-".!.!/ / 01122334556678899::;<<==>??@@ABB C C D D E F F GGHIIJJKKLMMNNOPPPPPPPPPPPPPPPPPP P P P P P P P PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP P P!P!P"P#P#P$P$P%P&P&P'P'P(P(P)P*P*P+P+P,P-P-P.P.P/~P/~P0}P1}P1|P2{P2{P3zP4zP4yP5yP5xP6wP7wP7vP8vP8uP9tP9tP:sP;sP;rPpP>oP?oP?nP@mP@mPAlPBlPBkPCkPCjPDiPEiPEhPFhPFgPGfPHfPHePIePIdPJcPJcPKbPLbPLaPMaPM`PN_PO_PO^PP^PP]PQ\PQ\PR[PS[PSZPTZPTYPUXPVXPVWPWWPWVPXUPXUPYTPZTPZSP[RP[RP\QP]QP]PP^PP^OP_NP`NP`MPaMPaLPbKPbKPcJPdJPdIPeIPeHPfGPgGPgFPhFPhEPiDPiDPjCPkCPkBPlBPlAPm@Pn@Pn?Po?Po>Pp=Pp=Pq;9642/-+(& $ "            " # % ' ( * , - / 1 3 568:<>@BDFHJLNPRRQQPOONNMMLKKJJI H H G G F E E D DCCBAA@@?>>==<;;::9987766544332 1 1!0!0"/#/#.$-$-%,&,&+'*'*())))(*'*'+&+&,%-%-$.#.#/"0"0!1 1 2334455677889::;;<==>>??@AABBCDD E E F G G H H IIJKKLLMNNOOPQQRRRRRRRRRRRRRRRRRR R R R R R R R RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR R R!R"R"R#R#R$R%R%R&R&R'R(R(R)R)R*R*R+R,R,R-~R-~R.}R/}R/|R0{R0{R1zR2zR2yR3yR3xR4wR4wR5vR6vR6uR7tR7tR8sR9sR9rR:qR:qR;pRmR>mR?lR@lR@kRAjRAjRBiRCiRChRDgRDgREfRFfRFeRGeRGdRHcRHcRIbRJbRJaRK`RK`RL_RM_RM^RN]RN]RO\RP\RP[RQ[RQZRRYRRYRSXRTXRTWRUVRUVRVURWURWTRXSRXSRYRRZRRZQR[QR[PR\OR\OR]NR^NR^MR_LR_LR`KRaKRaJRbIRbIRcHRdHRdGReGReFRfERfERgDRhDRhCRiBRiBRjARkARk@Rl?Rl?Rm>Rn>Rn=Ro=Ro@BDFHJLNPRTTSSRRQPPOONMMLLK J J I I H H G FFEEDCCBBA@@??>==<<;;:9988766554 3 3!2"2"1#0#0$/%/%.&.&-',(,(+)+)**)*)+(,(,'-&-&.%/%/$0#0#1"2"2!3!3 4556677899::;<<==>??@@ABBCCDDEFF G G H I I J J KLLMMNOOPPQQRSSTTTTTTTTTTTTTTTTTT T T T T T T T TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT T T!T!T"T"T#T$T$T%T%T&T'T'T(T(T)T*T*T+~T+~T,}T-}T-|T.{T.{T/zT/zT0yT1xT1xT2wT2wT3vT4vT4uT5tT5tT6sT7sT7rT8qT8qT9pT:pT:oT;nT;nTkT>kT?jT?jT@iTAiTAhTBgTBgTCfTDfTDeTEdTEdTFcTGcTGbTHaTHaTI`TI`TJ_TK^TK^TL]TL]TM\TN\TN[TOZTOZTPYTQYTQXTRWTRWTSVTTVTTUTUTTUTTVSTVSTWRTXQTXQTYPTYPTZOT[OT[NT\MT\MT]LT^LT^KT_JT_JT`ITaITaHTbGTbGTcFTcFTdETeDTeDTfCTfCTgBThBThATi@Ti@Tj?Tk?Tk>Tl=Tl=Tm@BDFHJLNPRTVVUUTTSRRQQPPONNM M L K K J J I HHGGFEEDDCBBAA@??>>==<;;::988776 5!5!4"4"3#2$2$1%1%0&/'/'.(.(-),),*++++*,),)-(.(.'/'/&0%1%1$2$2#3"4"4!5!5 677889::;;<<=>>??@AABBCDDEEFGGHH I J J K K L M MNNOOPQQRRSTTUUVVVVVVVVVVVVVVVVV V V V V V V V V VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV V V!V"V"V#V#V$V$V%V&V&V'V'V(V)~V)~V*}V*}V+|V,{V,{V-zV-zV.yV/xV/xV0wV0wV1vV2uV2uV3tV3tV4sV5sV5rV6qV6qV7pV7pV8oV9nV9nV:mV:mV;lViV?hV?hV@gV@gVAfVBeVBeVCdVCdVDcVEbVEbVFaVFaVG`VH`VH_VI^VI^VJ]VJ]VK\VL[VL[VMZVMZVNYVOXVOXVPWVPWVQVVRUVRUVSTVSTVTSVURVURVVQVVQVWPVXOVXOVYNVYNVZMV[MV[LV\KV\KV]JV]JV^IV_HV_HV`GV`GVaFVbEVbEVcDVcDVdCVeBVeBVfAVfAVg@Vh?Vh?Vi>Vi>Vj=Vk<97520. + ) ' $ "          "#%'( * , - / 1 3 5 6 8 :<>@BDFHIKNPRTVXXXWVVUUTSSRRQPPO O N M M L L K JJIIHGGFFEDDCCBAA@@??>==<<;::99 8 7!7!6"6#5#4$4$3%3&2&1'1'0(0(/).*.*-+-+,,+-+-*.*.)/(0(0'1'1&2%3%3$4$4#5"6"6!7!7 899::;<<==>??@@ABBCCDEEFFGHHIIJJ K L L M M N O OPPQRRSSTUUVVWXXYYYYYYYYYYYYYYYY Y Y Y Y Y Y Y Y YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY Y!Y!Y"Y"Y#Y$Y$Y%Y%Y&Y'~Y'~Y(}Y(}Y)|Y){Y*{Y+zY+zY,yY,xY-xY.wY.wY/vY/uY0uY1tY1tY2sY2rY3rY4qY4qY5pY5oY6oY7nY7nY8mY8mY9lY:kY:kY;jY;jYgY>gY?fY@eY@eYAdYAdYBcYCbYCbYDaYDaYE`YF_YF_YG^YG^YH]YI\YI\YJ[YJ[YKZYLYYLYYMXYMXYNWYNVYOVYPUYPUYQTYQSYRSYSRYSRYTQYTPYUPYVOYVOYWNYWMYXMYYLYYLYZKYZJY[JY\IY\IY]HY]HY^GY_FY_FY`EY`EYaDYbCYbCYcBYcBYdAYe@Ye@Yf?Yf?Yg>Yh=Yh=Yi;9642/ - + ( & $ "        "#%'(* , - / 1 3 5 6 8 : <>@BDFGIKNPRTVXZZZYYXWWVVUTTSSRQ Q P P O N N M MLKKJJIHHGGFEEDDCBBAA@??>>=<<;; : 9!9!8"8#7#6$6$5%5&4&3'3'2(2)1)0*0*/+/,.,----,.,/+/*0*0)1)2(2'3'3&4&5%5$6$6#7#8"8!9!9 : ;;<<=>>??@AABBCDDEEFGGHHIJJKKLM M N N O P P Q QRSSTTUVVWWXYYZZ[[[[[[[[[[[[[[[[ [ [ [ [ [ [ [ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [ [![!["[#[#[$[$~[%~[&}[&}['|['{[({[)z[)z[*y[*x[+x[,w[,w[-v[-u[.u[/t[/t[0s[0r[1r[2q[2q[3p[3o[4o[5n[5n[6m[6l[7l[8k[8k[9j[9i[:i[;h[;h[e[>e[?d[?c[@c[Ab[Ab[Ba[B`[C`[D_[D_[E^[E][F][G\[G\[H[[HZ[IZ[JY[JY[KX[KW[LW[MV[MV[NU[NT[OT[PS[PS[QR[QQ[RQ[SP[SP[TO[TN[UN[VM[VM[WL[WK[XK[YJ[YJ[ZI[ZH[[H[\G[\G[]F[]E[^E[_D[_D[`C[`B[aB[bA[bA[c@[c?[d?[e>[e>[f=[f<[g<[h;[h;[i:[i9[j9[k8[k8[l7[l6[m6[n5[n5[o4[o3[p3[p2[q2[r1[r0[s0[s/[t/[u.[u-[v-[v,[w,[x+[x*[y*[y)[z)[{([{'[|'[|&[}&[~%[~$[$[#[#["[![![ [ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [ [ [ [ [ [ [ [[[[[[[[[[[[[[[ZWTROLJGEB@=;8631 / , * ( & # !       "#%'(*, - / 1 3 5 6 8 : < >@BDFGIKMPRTVXZ\]\[[ZYYXXWVVUUTS S R R Q P P O ONMMLLKJJIIHGGFFEDDCCBAA@@?>>== < ;!;":":#9#8$8%7%7&6&5'5(4(4)3)2*2+1+1,0,/-/..../-/,0,1+1+2*3)3)4(4'5'6&6&7%7$8$9#9#:":!;!< < ==>??@@ABBCCDEEFFGHHIIJKKLLMNNO O P Q Q R R S TTUUVWWXXYZZ[[\]]]]]]]]]]]]]]]]] ] ] ] ] ] ] ] ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] ] ]!]"]"~]#~]#}]$}]%|]%{]&{]&z]'z](y](x])x])w]*w]+v]+u],u],t]-t].s].r]/r]/q]0q]1p]1o]2o]2n]3n]4m]4l]5l]5k]6k]7j]7i]8i]8h]9h]:g]:f];f];e]c]?b]?a]@a]@`]A`]B_]B^]C^]C]]D]]E\]E[]F[]FZ]GZ]HY]HX]IX]IW]JW]KV]KU]LU]LT]MT]NS]NR]OR]OQ]PQ]QP]QO]RO]RN]SN]TM]TL]UL]UK]VK]WJ]WI]XI]XH]YH]ZG]ZF][F][E]\E]]D]]C]^C]^B]_B]`A]`@]a@]a?]b?]c>]c=]d=]d<]e<]f;]f:]g:]g9]h9]i8]i7]j7]j6]k6]l5]l4]m4]m3]n3]o2]o1]p1]p0]q/]r/]r.]s.]t-]t,]u,]u+]v+]w*]w)]x)]x(]y(]z']z&]{&]{%]|%]}$]}#]~#]~"]"]!] ] ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] ] ] ] ] ] ] ] ]]]]]]]]]]]]]]]\YWTQOLIGDB?=:853 1 . , * ' % #       "#%'(*,- / 1 3 5 6 8 : < > @BDEGIKMPRTVXZ\^_^]]\\[ZZYYXWWVV U T T S S R Q QPPONNMMLKKJJIHHGFFEEDCCBBA@@?? >!=!="<"<#;$:$:%9%9&8'7'7(6(6)5*4*4+3+3,2-1-1.0////0.0.1-2,2,3+3+4*5)5)6(6(7'8&8&9%9%:$;#;#<"<"=!> > ??@AABBCDDEFFGGHIIJJKLLMMNOOPPQ R R S S T U U VVWXXYYZ[[\]]^^_________________ _ _ _ _ _ _ _ _______________________________ ~_!~_!}_"}_"|_#{_${_$z_%z_%y_&x_'x_'w_(w_(v_)u_*u_*t_+t_,s_,r_-r_-q_.p_/p_/o_0o_0n_1m_2m_2l_3l_3k_4j_5j_5i_6i_6h_7g_8g_8f_9f_9e_:d_;d_;c_a_>`_?`_?__@^_A^_A]_B]_C\_C[_D[_DZ_EY_FY_FX_GX_GW_HV_IV_IU_JU_JT_KS_LS_LR_MR_MQ_NP_OP_OO_PO_PN_QM_RM_RL_SL_SK_TJ_UJ_UI_VI_VH_WG_XG_XF_YF_ZE_ZD_[D_[C_\B_]B_]A_^A_^@__?_`?_`>_a>_a=_b<_c<_c;_d;_d:_e9_f9_f8_g8_g7_h6_i6_i5_j5_j4_k3_l3_l2_m2_m1_n0_o0_o/_p/_q._q-_r-_r,_s+_t+_t*_u*_u)_v(_w(_w'_x'_x&_y%_z%_z$_{$_{#_|"_}"_}!_~!_~ _______________________________ _ _ _ _ _ _ _ _______________^[YVSQNKIFDA?<:75 2 0 . + ) ' $ "      "#%'(*,-/ 1 3 5 6 8 : < > @ BDEGIKMPRTVXZ\^aa``_^^]]\[[ZZYXX W W V U U T T SRRQPPOONMMLLKJJIIHGGFFEDDCCBA A @!?!?">#>#=$<$<%;&;&:'9'9(8)8)7*6*6+5,5,4-3.3.2/1/100101/2.2.3-4-4,5+5+6*7*7)8(8(9':':&;%;%<$=#=#>"?"?!@ @ ABBCCDEEFFGHHIIJKKLMMNNOPPQQRSS T T U V V W W XYYZ[[\\]^^__`aaaaaaaaaaaaaaaaa a a a a a a a a aaaaaaaaaaaaaaaaaaaaaaaaaaa~a~a}a }a |a!{a!{a"za#za#ya$xa$xa%wa&va&va'ua(ua(ta)sa)sa*ra+ra+qa,pa,pa-oa.oa.na/ma/ma0la1la1ka2ja2ja3ia4ha4ha5ga6ga6fa7ea7ea8da9da9ca:ba:ba;aa^a?^a?]a@\a@\aA[aB[aBZaCYaCYaDXaEWaEWaFVaGVaGUaHTaHTaISaJSaJRaKQaKQaLPaMPaMOaNNaNNaOMaPMaPLaQKaQKaRJaSIaSIaTHaUHaUGaVFaVFaWEaXEaXDaYCaYCaZBa[Ba[Aa\@a\@a]?a^?a^>a_=a_=a`;97 4 2 / - + ( & $ "     "#%'(*,-/1 3 5 6 8 : < > @ B DEGIKMPRTVXZ\^acccbaa`__^^]\\[[Z Y Y X X W V V UTTSSRQQPPONNMMLKKJIIHHGFFEEDC C B!B"A"@#@#?$>%>%=&=&<';(;(:):)9*8+8+7,7-6-5.5.4/30302121120303/4/4.5-6-6,7,8+8*9*9):(;(;'<'<&=%>%>$?$?#@"A"A!B!C CDDEFFGGHIIJJKLLMNNOOPQQRRSTTUU V W W X Y Y Z Z[\\]]^__``abbcdddddddddddddddd d d d d d d d dddddddddddddddddddddddd~d~d}d}d|d{d{d zd zd!yd"xd"xd#wd$vd$vd%ud%ud&td'sd'sd(rd(rd)qd*pd*pd+od+od,nd-md-md.ld/kd/kd0jd0jd1id2hd2hd3gd3gd4fd5ed5ed6dd6dd7cd8bd8bd9ad:`d:`d;_d;_d<^d=]d=]d>\d>\d?[d@Zd@ZdAYdAYdBXdCWdCWdDVdEUdEUdFTdFTdGSdHRdHRdIQdIQdJPdKOdKOdLNdLNdMMdNLdNLdOKdPJdPJdQIdQIdRHdSGdSGdTFdTFdUEdVDdVDdWCdWCdXBdYAdYAdZ@d[?d[?d\>d\>d]=d^ @ B D EGIKMORTVXZ\^aceeeddcbba``__^]]\ \ [ Z Z Y Y X WWVUUTTSRRQQPOONMMLLKJJIIHGGFE E D!D"C"B#B$A$A%@%?&?'>'=(=(<)<*;*:+:+9,9-8-7.7/6/60504142322323141505/6/7.7.8-8,9,:+:*;*;)<)=(='>'?&?&@%@$A$B#B"C"C!D!E EFGGHHIJJKKLMMNNOPPQRRSSTUUVVWX X Y Z Z [ [ \ ]]^^_``abbccdeeffffffffffffffff f f f f f f f ffffffffffffffffffff~f~f}f}f|f{f{fzfyfyfxf xf!wf!vf"vf#uf#uf$tf$sf%sf&rf&qf'qf'pf(pf)of)nf*nf+mf+mf,lf,kf-kf.jf.jf/if/hf0hf1gf1ff2ff2ef3ef4df4cf5cf6bf6bf7af7`f8`f9_f9^f:^f:]f;]f<\f<[f=[f>Zf>Zf?Yf?Xf@XfAWfAVfBVfBUfCUfDTfDSfESfFRfFRfGQfGPfHPfIOfINfJNfJMfKMfLLfLKfMKfNJfNJfOIfOHfPHfQGfQGfRFfREfSEfTDfTCfUCfUBfVBfWAfW@fX@fY?fY?fZ>fZ=f[=f\ @ B C E GIKMORTVXZ\^aceghgffeedccbba``_ ^ ^ ] ] \ [ [ Z YYXXWVVUUTSSRQQPPONNMMLKKJIIHH G!F!F"E"E#D$C$C%B&A&A'@'@(?)>)>*=*<+<,;,;-:.9.9/8/8071616252434434352616170708/9.9.:-;,;,<+<+=*>)>)?(?(@'A&A&B%C$C$D#D#E"F!F!G GHIIJKKLLMNNOOPQQRSSTTUVVWXXYYZ [ [ \ \ ] ^ ^ _``aabccddeffghhhhhhhhhhhhhhhhh h h h h h h h hhhhhhhhhhhhhhhh~h~h}h}h|h{h{hzhyhyhxhxhwhvh vh uh!uh"th"sh#sh#rh$qh%qh%ph&ph&oh'nh(nh(mh)lh*lh*kh+kh+jh,ih-ih-hh.hh.gh/fh0fh0eh1dh2dh2ch3ch3bh4ah5ah5`h6`h7_h7^h8^h8]h9\h:\h:[h;[h;ZhXh?Wh?Vh@Vh@UhAThBThBShCShCRhDQhEQhEPhFOhGOhGNhHNhHMhILhJLhJKhKKhKJhLIhMIhMHhNGhOGhOFhPFhPEhQDhRDhRChSChTBhTAhUAhU@hV?hW?hW>hX>hX=hY @ B C E G IKMORTVXZ\^acegjjiihhgffeddccba a ` _ _ ^ ^ ] \\[ZZYYXWWVVUTTSRRQQPOONMMLLKJ J I!I!H"G#G#F$E$E%D&D&C'B(B(A)@)@*?+?+>,=-=-<.;.;/:0:091818273736455554636372828190:0:/;.;.<-=-=,>+?+?*@*@)A(B(B'C&C&D%E%E$F#G#G"H!H!I J JKLLMMNOOPPQRRSTTUUVWWXYYZZ[\\ ] ^ ^ _ _ ` a abbcddeffgghiijjjjjjjjjjjjjjjjj j j j j j j j jjjjjjjjjjjj~j~j}j}j|j{j{jzjyjyjxjxjwjvjvjujtjtj sj!sj!rj"qj"qj#pj$oj$oj%nj%nj&mj'lj'lj(kj)kj)jj*ij*ij+hj,gj,gj-fj.fj.ej/dj/dj0cj1bj1bj2aj2aj3`j4_j4_j5^j6^j6]j7\j7\j8[j9Zj9Zj:Yj;Yj;XjUj>Uj?Tj@Tj@SjARjARjBQjCPjCPjDOjDOjENjFMjFMjGLjHLjHKjIJjIJjJIjKHjKHjLGjMGjMFjNEjNEjODjPCjPCjQBjRBjRAjS@jS@jT?jU?jU>jV=jV=jW < 9 7 4 2 0 - + (&$"     !#%&(*,-/13468: < > @ B C E G I K MORTVXZ\^`cegjlllkjjiihggfeedd c b b a ` ` _ _^]]\[[ZZYXXWWVUUTSSRRQPPONNMM L K!K"J"I#I#H$H%G%F&F'E'D(D(C)C*B*A+A,@,?-?->.>/=/<0<0;1:2:293948475756657574849392:2:1;1<0.>-?-?,@,A+A*B*C)C(D(D'E'F&F%G%H$H#I#I"J"K!K L MMNNOPPQRRSSTUUVVWXXYZZ[[\]]^_ _ ` ` a b b c ddeefgghiijjkllmmmmmmmmmmmmmmmm m m m m m m m mmmmmmmm~m~m}m}m|m{m{mzmymymxmxmwmvmvmumtmtmsmsmrm qm qm!pm!om"om#nm#nm$mm$lm%lm&km&jm'jm(im(im)hm)gm*gm+fm+em,em-dm-dm.cm.bm/bm0am0`m1`m2_m2_m3^m3]m4]m5\m5[m6[m7Zm7Zm8Ym8Xm9Xm:Wm:Vm;VmSm?Rm?Rm@QmAPmAPmBOmBNmCNmDMmDMmELmFKmFKmGJmGImHImIHmIHmJGmJFmKFmLEmLDmMDmNCmNCmOBmOAmPAmQ@mQ?mR?mS>mS>mT=mT ; 9 6 4 1 / - *(&#!     !#%&(*,-/13468:< > @ B C E G I K M ORTVXZ\^`cegilnonmmllkjjihhggf e e d c c b b a``_^^]]\[[ZYYXXWVVUTTSRRQQPOO N M!M"L"L#K$J$J%I%H&H'G'G(F)E)E*D*C+C,B,B-A.@.@/?/>0>1=1=2<3;3;4:495968687786869594:4;3;3<2=1=1>0?/?/@.@.A-B,B,C+D*D*E)E)F(G'G'H&I%I%J$J$K#L"L"M!N N OOPQQRSSTTUVVWXXYYZ[[\]]^^_``a b b c c d e e fgghhijjkllmmnoooooooooooooooo o o o o o o o ooooo~o~o}o|o|o{o{ozoyoyoxowowovovouototosororoqoqopooo oo no!mo"mo"lo#lo#ko$jo%jo%io&ho'ho'go(go(fo)eo*eo*do+co,co,bo-bo.ao.`o/`o/_o0^o1^o1]o2]o3\o3[o4[o4Zo5Yo6Yo6Xo7Xo8Wo8Vo9Vo9Uo:To;To;SoQo>Po?Oo@Oo@NoANoBMoBLoCLoCKoDJoEJoEIoFIoGHoGGoHGoHFoIEoJEoJDoKDoLCoLBoMBoMAoN@oO@oO?oP?oQ>oQ=oR=oR @ B C E G I K M O QTVXZ\^`cegilnpqppoonmmlkkjiih h g f f e d d ccbaa`__^^]\\[ZZYYXWWVUUTSSRRQ P!P!O"N"N#M$M$L%K&K&J'I(I(H)H)G*F+F+E,D-D-C.B.B/A0A0@1?2?2>3=3=4<5<5;6:7:79889897:7:6;5<5<4=3>3>2?1?1@0A0A/B.C.C-D,D,E+F+F*G)H)H(I'J'J&K&K%L$M$M#N"O"O!P P QRRSTTUUVWWXYYZ[[\\]^^_``aabcc d e e f f g h hijjkklmmnoopqqqqqqqqqqqqqqqqq q q q q q q q q~q~q}q|q|q{q{qzqyqyqxqwqwqvqvquqtqtqsqrqrqqqqqpqoqoqnqmqmq lq!kq!kq"jq"jq#iq$hq$hq%gq&fq&fq'eq(eq(dq)cq)cq*bq+aq+aq,`q-`q-_q.^q.^q/]q0\q0\q1[q2[q2Zq3Yq3Yq4Xq5Wq5Wq6Vq7Uq7Uq8Tq8Tq9Sq:Rq:Rq;QqOq>Nq?Mq?Mq@LqAKqAKqBJqCJqCIqDHqDHqEGqFFqFFqGEqHDqHDqICqICqJBqKAqKAqL@qM?qM?qN>qO>qO=qP@ B C E G I K M O Q TVXZ\^`cegilnpsssrrqpponnmllkk j i i h g g f feddcbba``__^]]\[[ZZYXXWVVUTTS S!R!Q"Q#P#O$O%N%M&M&L'L(K(J)J*I*H+H,G,G-F-E.E/D/C0C1B1A2A2@3@4?4>5>6=6<7<8;8;9:99:9;8;7<7=6=5>5>4?4@3@2A2B1B0C0D/D/E.E-F-G,G+H+I*I)J)K(K(L'L&M&N%N$O$P#P"Q"Q!R!S STUUVWWXXYZZ[\\]]^__`aabccddef f g h h i i j kklmmnooppqrrstttttttttttttttt t t t t ~t ~t }t |t|t{t{tztytytxtwtwtvtvtutttttstrtrtqtptptototntmtmtltktkt jt it!it!ht"ht#gt#ft$ft%et%dt&dt'ct'ct(bt(at)at*`t*_t+_t,^t,]t-]t-\t.\t/[t/Zt0Zt1Yt1Xt2Xt3Wt3Wt4Vt4Ut5Ut6Tt6St7St8Rt8Qt9Qt9Pt:Pt;Ot;NtLt?Kt?Kt@Jt@ItAItBHtBGtCGtDFtDEtEEtFDtFDtGCtGBtHBtIAtI@tJ@tK?tK>tL>tL=tM=tN < 9 7 4 2 0-+)&$"      !#%&(*,-/13468:<>@A C E G I K M O Q T VXZ\^`cegilnpsuvuutssrqqpponnm l l k j j i i hggfeedccbba``_^^]\\[[ZYYXWWV U U!T"T"S#R#R$Q%P%P&O'N'N(M)M)L*K*K+J,I,I-H.G.G/F0F0E1D1D2C3B3B4A5@5@6?7?7>8=8=9<:;:;;:<9<9=8>8>7?6?6@5A4A4B3C2C2D1E1E0F/F/G.H-H-I,J+J+K*L*L)M(M(N'O&O&P%Q%Q$R#S#S"T!T!U VVWXXYYZ[[\]]^__``abbcddeffggh i i j k k l m mnnoppqrrsttuuvvvvvvvvvvvvvvvv ~v ~v }v |v |v {v {v zvyvyvxvwvwvvvuvuvtvtvsvrvrvqvpvpvovnvnvmvmvlvkvkvjvivivhv gv gv!fv"fv"ev#dv$dv$cv%bv&bv&av'`v'`v(_v)_v)^v*]v+]v+\v,[v,[v-Zv.Yv.Yv/Xv0Xv0Wv1Vv2Vv2Uv3Tv3Tv4Sv5Sv5Rv6Qv7Qv7Pv8Ov9Ov9Nv:Mv:Mv;LvJv>Iv?Hv@Hv@GvAFvAFvBEvCEvCDvDCvECvEBvFAvGAvG@vH?vH?vI>vJ>vJ=vK ; 9 6 4 1/-*(&#!      !#%&(*,-/13468:<>@ACE G I K M O Q T V XZ\^`cegilnpsuxxxwvvuttssrqqpo o n m m l l k jjihhgffeedccbaa`__^]]\\[ZZYX X W!V"V"U#U$T$S%S&R&Q'Q'P(O)O)N*N+M+L,L-K-J.J/I/H0H0G1F2F2E3E4D4C5C6B6A7A7@8?9?9>:>;=;<<<=;=:>:>9?8@8@7A7B6B5C5D4D3E3F2F1G1G0H/I/I.J.K-K,L,M+M*N*N)O(P(P'Q'R&R%S%T$T#U#U"V!W!W X YYZ[[\]]^^_``abbcddeefgghiijk k l l m n n o ppqrrsttuuvwwxyyyyyyyyyyyy~y~y}y|y |y {y {y zy yy yy xy wywyvyuyuytytysyryryqypypyoynynymylylykykyjyiyiyhygygyfyey ey!dy!dy"cy#by#by$ay$`y%`y&_y&^y'^y(]y(]y)\y*[y*[y+Zy,Yy,Yy-Xy-Wy.Wy/Vy/Uy0Uy1Ty1Ty2Sy3Ry3Ry4Qy4Py5Py6Oy6Ny7Ny8My8My9Ly:Ky:Ky;Jy;IyGy?Fy?Fy@EyADyADyBCyCByCByDAyD@yE@yF?yF>yG>yH=yH=yI@ACEG I K M O Q T V X Z\^`cegilnpsuxz{zyyxxwvvuttsrr q q p o o n m mlkkjiihhgffeddcbba``__^]]\[[ Z!Y!Y"X#W#W$V$V%U&T&T'S(R(R)Q*P*P+O,N,N-M-M.L/K/K0J1I1I2H3G3G4F5E5E6D6D7C8B8B9A:@:@;?<><>==><>E{>D{?C{@C{@B{AA{BA{B@{C?{D?{D>{E>{E={F<{G<{G;{H:{I:{I9{J8{K8{K7{L6{M6{M5{N5{N4{O3{P3{P2{Q1{R1{R0{S/{T/{T.{U-{V-{V,{W,{W+{X*{Y*{Y){Z({[({['{\&{]&{]%{^${_${_#{`#{`"{a!{b!{b {c{d{d{e{f{f{g{h{h{i{i{j{k{k{l{m{m{n{o{o{p{q{q{r{r{s{t{t{u {v {v {w {x {x {y {y {z{{{{{|{}{}{~{{{{{{{zwtqnkheb_\ZWTQO L I G D B ? = : 8530.,)'%"        !#%&(*,-/13468:<>@ACEGI K M O Q T V X Z \^`cegilnpsuxz}}}|{{zyyxwwvvut t s r r q p p onnmllkkjiihggfeedccbba``_^^] \!\!["Z#Z#Y$X%X%W&W'V'U(U)T)S*S*R+Q,Q,P-O.O.N/N0M0L1L2K2J3J3I4H5H5G6F7F7E8D9D9C:C;B;A?>>?=@=@B~>B~?A~?@~@@~A?~A>~B>~C=~C=~D<~E;~E;~F:~G9~G9~H8~H7~I7~J6~J5~K5~L4~L3~M3~N2~N2~O1~P0~P0~Q/~R.~R.~S-~S,~T,~U+~U*~V*~W)~W)~X(~Y'~Y'~Z&~[%~[%~\$~]#~]#~^"~^!~_!~` ~`~a~b~b~c~d~d~e~f~f~g~g~h~i~i~j~k~k~l~m~m~n~o~o~p~q~q~r~r ~s ~t ~t ~u ~v ~v ~w ~x~x~y~z~z~{~{~|~}~}~~~~~|yvspmjgda_\YVSQ N K I F D A > < 97520-+)&$"       !#%&(*,-/13468:<>@ACEGIK M O Q S V X Z \ ^`cegilnpsuxz}~~~~~~}~}~|~{~{~z~y~y~x~w~w ~v ~u ~u ~t ~s ~s ~r ~r~q~p~p~o~n~n~m~l~l~k~j~j~i~h~h~g~f~f~e~e~d~c~c~b~a~a~` ~_ ~_!~^"~]"~]#~\$~[$~[%~Z%~Z&~Y'~X'~X(~W)~V)~V*~U+~T+~T,~S-~R-~R.~Q/~P/~P0~O1~N1~N2~M2~M3~L4~K4~K5~J6~I6~I7~H8~G8~G9~F:~E:~E;~D<~C<~C=~B=~B>~A?~@?~@@~?A~>A~>B~=C~????>@=A=A ;9642/-*(&#!       !#%&(*,-/13468:<>@ACEGIKM O Q S V X Z \ ^ `cegilnpsuxz}~|{{{{{{~{~{}{|{|{{{{{z{y {y {x {w {w {v {u {u{t{s{s{r{q{q{p{o{o{n{m{m{l{l{k{j{j{i{h{h{g{f{f{e{d{d{c{b {b {a!{`"{`"{_#{^${^${]%{]&{\&{['{[({Z({Y){Y*{X*{W+{W,{V,{U-{U-{T.{S/{S/{R0{Q1{Q1{P2{O3{O3{N4{N5{M5{L6{L7{K7{J8{J9{I9{H:{H;{G;{F<{F<{E={D>{D>{C?{B@{B@{AA{@B{@B{?C{?D{>D{=E{=F{=>>=>@ACEGIKMO Q S V X Z \ ^ ` cegilnpsuxz}}|zyyyyyyyyyy~y~y}y|y| y{ yz yz yy yx yx ywyvyvyuyuytysysyryqyqypyoyoynymymylykykyjyiyiyhygygyfyeye yd!yc!yc"yb#yb#ya$y`%y`%y_&y^'y^'y](y\(y\)y[*yZ*yZ+yY,yX,yX-yW.yV.yV/yU0yT0yT1yS2yR2yR3yQ4yP4yP5yO6yO6yN7yM8yM8yL9yK:yK:yJ;yI;yIyF?yE?yE@yDAyCAyCByBCyACyADy@Ey?Ey?Fy>Gy=Gy=Hy;=;=<<=;=;>:?:?9@8A8A7B6C6C5D4E4E3F2G2G1H0I0I/J.K.K-L,L,M+N*N*O)P(P(Q'R'R&S%T%T$U#V#V"W!X!X YZZ[\\]^^__`aabccdeefgghiijkk l m m n o o pqqrrsttuvvwxxz|}zwtqnkheb`]ZW T R O L J G D B ?=:8530.,)'%"        !#%&(*,-/13468:<>@ACEGIKMOQ S V X Z \ ^ ` c egilnpsuxz|}{ywvvvvvvvvvvvvvv~ v~ v} v| v| v{ vz vzvyvxvxvwvvvvvuvtvtvsvrvrvqvpvpvovnvnvmvmvlvkvkvjvivivhvg vg!vf!ve"ve#vd#vc$vc%vb%va&va'v`'v_(v_)v^)v]*v]+v\+v[,v[-vZ-vY.vY/vX/vW0vW1vV1vU2vU3vT3vS4vS5vR5vQ6vQ7vP7vP8vO9vN9vN:vM:vL;vLvI>vH?vH@vG@vFAvFBvEBvDCvDDvCDvBEvBFvAFv@Gv@Hv?Hv>Iv>Jv=Jv8>9=9<:<:;;:<:<9=9>8>7?7@6@5A5B4B3C3D2D1E1F0F/G/H.H-I-J,J+K+L*L)M)N(N'O'P&P%Q%R$R#S#T"T!U!V VWWXYYZ[[\]]^__`aabccdeefgghi i j k k l m mnoopqqrrsttuvwz|}zwtpmkheb_\Y W T Q N L I F D A?<:7520-+)&$"        !#%&(*+-/13468:<>?ACEGIKMOQSV X Z \ ^ ` c e g ilnpsuxz|~|zxvttttttttttttttt t t t t~ t~ t} t|t|t{tztztytxtxtwtvtvtutttttstrtrtqtptptotntntmtltltktj tj ti!th"th"tg#tf$tf$te%td&td&tc'tb(tb(ta)t`*t`*t_+t^,t^,t]-t\.t\.t[/tZ0tZ0tY1tX2tX2tW3tV4tV4tU5tT5tT6tS7tS7tR8tQ9tQ9tP:tO;tO;tNtK?tK?tJ@tIAtIAtHBtGCtGCtFDtEEtEEtDFtCGtCGtBHtAItAIt@Jt?Kt?Kt>Lt=Mt=Mt6=6=7<8;8;9::9:9;8<7<7=6>5>5?4@4@3A2A2B1C0C0D/E.E.F-G,G,H+I*I*J)K(K(L'M&M&N%O$O$P#Q"Q"R!S S TUUVWWXYYZ[[\]]^__`aabccdeef g g h i i j kklmmnoopqqrssuwz||yvspmjgda^[ Y V S P N K H F CA><9742/-+(&$!         !#%&(*+-/13468:<>?ACEGIKMOQSVX Z \ ^ ` c e g i lnpsuxz|}{zxvtrqqqqqqqqqqqqqq q q q q q q qq~q}q}q|q{q{qzqyqyqxqwqwqvququqtqsqsqrqrqqqpqpqoqnqnqm ql ql!qk"qj"qj#qi$qh$qh%qg&qf&qf'qe(qd(qd)qc*qb*qb+qa,q`,q`-q_.q^.q^/q]0q\0q\1q[2qZ2qZ3qY4qX4qX5qW6qV6qV7qU8qT8qT9qS:qR:qR;qQqN>qN?qM@qL@qLAqKBqJBqJCqIDqHDqHEqGFqFFqFGqEHqDHqDIqCJqBJqBKqALq@Lq@Mq?Nq>Nq>Oq=Pq3>3=4<5<5;6:7:79889897:6;6;5<4=4=3>2?2?1@0A0A/B.C.C-D,E,E+F*G*G)H(I(I'J&K&K%L$M$M#N"O"O!P Q QRSSTUUVWWXYYZ[[\]]^__`aabcc d e e f g g hiijkklmmnoopqruwz|{xurolifca ^ [ X U S P M J H EC@=;8641/,*(%#!         !#%&(*+-/13468:<>?ACEGIKMOQSVXZ \ ^ ` c e g i l npsuxz|}{ywusqonnnnnnnnnnnnn n n n n n n n nnnnnn~n}n}n|n{n{nznynynxnwnwnvnununtnsnsnrnqnqnpno no!nn!nm"nm#nl#nk$nk%nj%ni&ni'nh'ng(ng)nf)ne*ne+nd+nc,nc-nb-na.na/n`/n_0n_1n^1n]2n]3n\3n[4n[5nZ5nY6nY7nX7nW8nW9nV9nU:nU;nT;nSnQ?nP?nO@nOAnNAnMBnMCnLCnKDnKEnJEnIFnIGnHGnGHnGInFInEJnEKnDKnCLnCMnBMnANnAOn@On?Pn>Qn>Qn=Rn0=1=2<2;3;4:4959686777868595:4:3;3<2<1=1>0>/?/@.@-A-B,B+C+D*D)E)F(F'G'H&H%I%J$J#K#L"L!M!N NOPPQRRSTTUVVWXXYZZ[\\]^^_`` a b b c d d e ffghhijjklmmnoruwz|~{xurolifc ` ] Z W U R O M JGEB?=:8531.,)'%"       !!   !#%&(*+-/13468:<>?ACEGIKMOQSVXZ\ ^ ` c e g i l n psuxz~||zxvtrpolkkkkkkkkkkkkk k k k k k k k kkkkkkkkkk~k}k}k|k{k{kzkykykxkwkwkvkukuktkskskr kq!kq!kp"ko#ko#kn$km%km&kl&kk'kj(kj(ki)kh*kh*kg+kf,kf,ke-kd.kd.kc/kb0kb0ka1k`2k`2k_3k^4k^4k]5k\6k\6k[7kZ8kZ8kY9kX:kX:kW;kVkT>kS?kR@kR@kQAkPBkPBkOCkNDkNDkMEkLFkLFkKGkJHkJIkIIkHJkHKkGKkFLkEMkEMkDNkCOkCOkBPkAQkAQk@Rk?Sk?Sk>Tk=Uk=Uk->.=/-?,?,@+A*A*B)C(C(D'E&E&F%G$G#H#I"I!J!K LLMNNOPPQRRSTTUVVWXXYZZ[\\]^ ^ _ ` ` a b b cddeffghhijjkmoruwz|}zwtqnkhe b _ \ Z W T Q O LIGDA?<:7520.+)&$"       !!!    !#%&(*+-/13468:<>?ACEGIKMOQSUXZ\^ ` c e g i l n p suwz}|{zxvtrpnljiiiiiiiiiiiii i i i i i i i iiiiiiiiiiiiii~i}i}i|i{i{iziyiyixiwiviviu it it!is"ir"ir#iq$ip$ip%io&in&in'im(il(il)ik*ij*ij+ii,ih,ih-ig.if/if/ie0id1id1ic2ib3ib3ia4i`5i_5i_6i^7i]7i]8i\9i[9i[:iZ;iY;iYiV?iU?iU@iTAiSAiSBiRCiQCiQDiPEiOFiOFiNGiMHiMHiLIiKJiKJiJKiILiHLiHMiGNiFNiFOiEPiDPiDQiCRiBRiBSiATi@Ti@Ui?Vi>Vi>Wi=Xi+=,=,<-;.;.:/909081727263545445363627181809/:/:.;-<,<,=+>*>*?)@(@(A'B&C&C%D$E$E#F"G"G!H I IJKKLMMNOOPQQRSSTUUVWWXYZZ[ \ \ ] ^ ^ _ ` `abbcddeffghhjmoruwz|}zvspmjg d b _ \ Y V S Q NKIFCA><9742/-+(&$!      ""!!    !#%&(*+-/12468:<>?ACEGIKMOQSUXZ\^` b e g i l n p s uw~z}|{ywusqomkigfffffffffffff f f f f f f f ffffffffffffffffff~f}f|f|f{fzfzfyfxfx fw fv!fv"fu#ft#ft$fs%fr%fr&fq'fp'fp(fo)fn)fn*fm+fl+fk,fk-fj-fi.fi/fh/fg0fg1ff1fe2fe3fd4fc4fc5fb6fa6fa7f`8f_8f_9f^:f]:f];f\fY>fX?fX@fW@fVAfVBfUBfTCfTDfSEfREfRFfQGfPGfPHfOIfNIfNJfMKfLKfLLfKMfJMfINfIOfHOfGPfGQfFQfERfESfDSfCTfCUfBVfAVfAWf@Xf?Xf?Yf>Zf=Zf=[f<\f;\f;]f:^f9^f8_f8`f7`f6af6bf5bf4cf4df3df2ef2ff1gf0gf0hf/if.if.jf-kf,kf,lf+mf*mf*nf)of(of'pf'qf&qf%rf%sf$sf#tf#uf"uf!vf!wf xfxfyfzfzf{f|f|f}f~f~ffffffffffffffffff f f f f f f fffffffffffffffeddcbba``_^^] \ \ [ Z Z Y XXWVVUTSSRQQPOONMMLKKJIIHGG F E!E"D"C#B$B$A%@&@&?'>(>(=)<*<*;+:,:-9-8.8/7/60615142433324151506/7/7.8-9-9,:+;+;*<)=)>(>'?'@&@%A%B$B#C#D"D!E F FGHHIJJKLLMNOOPQQRSSTUUVWWX Y Y Z [ [ \ ] ]^_``abbcddefgjmoruwz||yvspmj g d a ^ [ X V S PMKHEC@>;9641/,*(%#!      """!!!   !#%&(*+-/12468:<>?ACEGIKMOQSUXZ\^`b e g i l n p s u w~z||zxvtrpomjhfdccccccccccccc c c c c c c c ccccccccccccccccccccc~c~c}c|c|c{cz cz!cy!cx"cx#cw#cv$cv%cu%ct&ct'cs'cr(cq)cq*cp*co+co,cn,cm-cm.cl.ck/ck0cj0ci1ci2ch2cg3cg4cf4ce5cd6cd7cc7cb8cb9ca9c`:c`;c_;c^c\?c[?cZ@cZAcYAcXBcWCcWDcVDcUEcUFcTFcSGcSHcRHcQIcQJcPJcOKcOLcNLcMMcMNcLNcKOcKPcJQcIQcHRcHScGScFTcFUcEUcDVcDWcCWcBXcBYcAYc@Zc@[c?[c>\c>]c=]c<^c;_c;`c:`c9ac9bc8bc7cc7dc6dc5ec5fc4fc3gc3hc2hc1ic1jc0jc/kc.lc.mc-mc,nc,oc+oc*pc*qc)qc(rc(sc'sc&tc&uc%uc$vc$wc#wc"xc!yc!zc zc{c|c|c}c~c~cccccccccccccccccccccc c c c c c c cccccccccccccccbba``_^]]\[[ Z Y Y X W W V UUTSSRQQPONNMLLKJJIHHGFFEDD C!B!A"A#@#?$?%>%=&='<';(;):)9*9+8+7,7-6.5.4/40302122120304/4.5.6-6,7,8+8*9*:);(;'<'=&=%>%?$?#@#A"A!B!C CDEEFGGHIJJKLLMNNOPPQRRSTTU V W W X Y Y Z [[\]]^__`aabcegjmoruwz~|{xurol i f c ` ] [ X U ROMJGEB@=;8631.,)'%"       ##""!!!    !#%&(*+-/12468:<>?ACEGIKMOQSUXZ\^`be g i l n p s u w} z{|yxvtrpnljhfda````````````` ` ` ` ` ` ` ``````````````````````````~`~`} `|!`|"`{"`z#`z$`y$`x%`x&`w&`v'`u(`u(`t)`s*`s*`r+`q,`q-`p-`o.`o/`n/`m0`m1`l1`k2`j3`j3`i4`h5`h5`g6`f7`f8`e8`d9`d:`c:`b;`b<`a<``=`_>`_>`^?`]@`]@`\A`[B`[C`ZC`YD`YE`XE`WF`WG`VG`UH`TI`TI`SJ`RK`RK`QL`PM`PN`ON`NO`NP`MP`LQ`LR`KR`JS`IT`IT`HU`GV`GV`FW`EX`EY`DY`CZ`C[`B[`A\`A]`@]`?^`>_`>_`=``">#=$<$<%;&:&:'9(8(8)7*6*5+5,4,3-3.2/1/1001/1/2.3-3-4,5+5*6*7)7(8(9':&:&;%<$<$=#>">"?!@ @ABBCDEEFGGHIIJKKLMMNOPPQRRS T T U V V W XXYZ[[\]]^__`begjmoruwz~|{xtqn k h e c ` ] Z W TROLIGDB?<:7530.+)'$"       ###"""!!    !#%&(*+-/12468:<>?ACEGIKMOQSUXZ\^`begi l n p s u~ w} z{ |ywusqomkigeca_]]]]]]]]]]]]] ] ] ] ] ] ] ]]]]]]]]]]]]]]]]]]]]]]]]]]] ] ]!]~"]~"]}#]|$]|$]{%]z&]y']y']x(]w)]w)]v*]u+]u+]t,]s-]s-]r.]q/]q0]p0]o1]n2]n2]m3]l4]l4]k5]j6]j6]i7]h8]h8]g9]f:]e;]e;]d<]c=]c=]b>]a?]a?]`@]_A]_A]^B]]C]\D]\D][E]ZF]ZF]YG]XH]XH]WI]VJ]VJ]UK]TL]SM]SM]RN]QO]QO]PP]OQ]OQ]NR]MS]MS]LT]KU]JV]JV]IW]HX]HX]GY]FZ]FZ]E[]D\]D\]C]]B^]A_]A_]@`]?a]?a]>b]=c]=c] = =!<";";#:$9$8%8&7'6'6(5)4)4*3+2+2,1-0-0.//.0-0-1,2+2+3*4)4)5(6'6'7&8%9$9$:#;";"??@ABBCDDEFFGHHIJKKLMMNOOP Q Q R S S T UVVWXXYZZ[\\]_begjmoruwz}|zwtq n k h e b _ \ Y VTQNLIFDA><9742/-+(&$!      $$###""!!!  !#%&(*+-/12468:<=?ACEGIKMOQSUXZ\^`begil n p s u~ w| zz |x vtrpomkhfdb`^\[[[[[[[[[[[[[ [ [ [ [ [ [ [[[[[[[[[[[[[[[[[[[[[[[[[[[ [ [!["[#[#[$[~%[~%[}&[|'[{'[{([z)[y*[y*[x+[w,[w,[v-[u.[u.[t/[s0[r0[r1[q2[p3[p3[o4[n5[n5[m6[l7[k7[k8[j9[i9[i:[h;[g<[g<[f=[e>[e>[d?[c@[b@[bA[aB[`C[`C[_D[^E[^E[]F[\G[\G[[H[ZI[YI[YJ[XK[WL[WL[VM[UN[UN[TO[SP[RP[RQ[QR[PS[PS[OT[NU[NU[MV[LW[LW[KX[JY[IY[IZ[H[[G\[G\[F][E^[E^[D_[C`[B`[Ba[Ab[@c[@c[?d[>e[>e[=f[>=<<; :!9!9"8#7#7$6%5%5&4'3(3(2)1*0*0+/,.,.--.,.,/+0*1*1)2(3'3'4&5%5%6$7#8#8"9!: : ;<<=>>?@AABCCDEEFGHHIJJKLLM N N O P Q Q RSSTUUVWXXYZZ\_begjmoruwz}|yvs p m j g d a ^ \YVSPNKHFC@>;9641/,*(%#!       $$$###"""!! ! #%&(*+-/12468:<=?ACEGIKMOQSUXZ\^`begiln p s u} w{ zy |x v trpnljhfdb_][YXXXXXXXXXXXXX X X X X X X XXXXXXXXXXXXXXXXXXXXXXXXXXX X!X!X"X#X#X$X%X&X&X'X~(X}(X})X|*X{*X{+Xz,Xy-Xy-Xx.Xw/Xv/Xv0Xu1Xt1Xt2Xs3Xr4Xr4Xq5Xp6Xp6Xo7Xn8Xm8Xm9Xl:Xk;Xk;XjXg?Xf?Xf@XeAXdBXdBXcCXbDXbDXaEX`FX_FX_GX^HX]HX]IX\JX[KX[KXZLXYMXXMXXNXWOXVOXVPXUQXTRXTRXSSXRTXQTXQUXPVXOVXOWXNXXMYXMYXLZXK[XJ[XJ\XI]XH]XH^XG_XF`XF`XEaXDbXCbXCcXBdXAdXAeX@fX?gX?gX>hX=iX==<;;:988 7!6"6"5#4$4$3%2&1&1'0(/)/).*-+-+,,+-*-*.)/(0(0'1&2&2%3$4#4#5"6!7!7 899:;;<=>>?@@ABBCDDEFGGHIIJ K K L M N N OPPQRRSTUUVWWY\_begjmoruwz||yv r o l i f d a ^[XURPMJHEB@=;8631.,*'%"        %%$$$##"""!! !! # %&(*+-/12468:<=?ACEGIKMOQSUXZ\^`begilnp s~ u| w{ zy |w u s qomkigeca_]ZXVUUUUUUUUUUUUU U U U U U U UUUUUUUUUUUUUUUUUUUUUUUUUUU U!U"U"U#U$U$U%U&U&U'U(U)U)U*U~+U}+U},U|-U{-U{.Uz/Uy0Ux0Ux1Uw2Uv2Uv3Uu4Ut5Ut5Us6Ur7Uq7Uq8Up9Uo9Uo:Un;UmUj>Uj?Ui@Uh@UhAUgBUfCUfCUeDUdEUcEUcFUbGUaGUaHU`IU_JU^JU^KU]LU\LU\MU[NUZOUZOUYPUXQUWQUWRUVSUUSUUTUTUUSVUSVURWUQXUPXUPYUOZUNZUN[UM\UL]UL]UK^UJ_UI_UI`UHaUGaUGbUFcUEdUDdUDeUCfUBfUBgUAhU@iU@iU?jU>kU=kU=lU>=<<;:9987765 5 4!3"2#2#1$0%0%/&.'-'-(,)+*+**+),),(-'.&.&/%0$1$1#2"3"3!4 5567889::;<==>??@AABCDDEFFG H H I J K K LMMNOOPQRRSTTVY\_begjmoruw~z{|x u r o l i f c `]ZWUROLJGDB?=:8530.+)'$"         %%%$$$###""! !!!# % &(*+-/12468:<=?ACEGIKMOQSUXZ\^`begiknps~ u| wz zx |v t r p o mkifdb`^\ZXUSRRRRRRRRRRRRR R R R R R R RRRRRRRRRRRRRRRRRRRRRRRRRR R R!R"R"R#R$R%R%R&R'R'R(R)R)R*R+R,R,R-R~.R}.R}/R|0R{1Rz1Rz2Ry3Rx3Rx4Rw5Rv6Rv6Ru7Rt8Rs8Rs9Rr:Rq:Rq;RpRm?Rl?Rl@RkARjBRjBRiCRhDRgDRgERfFReFReGRdHRcIRbIRbJRaKR`KR`LR_MR^NR^NR]OR\PR[PR[QRZRRYRRYSRXTRWURVURVVRUWRTWRTXRSYRRZRRZRQ[RP\RO\RO]RN^RM^RM_RL`RKaRJaRJbRIcRHcRHdRGeRFfREfREgRDhRChRCiRBjRAkRAkR@lR?mR>mR>nR=oR==<;::98876654332 1!1!0"/#.$.$-%,&,&+'*()())(*'+'+&,%-%-$.#/"0"0!1 2 23445677899:;<<=>>?@@ABCCD E E F G H H IJJKLLMNOOPQQSVY\_begjmoruw~z{ |w t q n k h e b_\ZWTQOLIFDA?<:7520-+(&$!         &&%%%$$###"" "!!#!% & ( *+-/12468:<=?ACEGIKMOQSUXZ\^`begiknps}u{ wy zx |v t r p n l jhfdb`][YWURPOOOOOOOOOOOOO O O O O O O OOOOOOOOOOOOOOOOOOOOOOOOOO O O!O"O#O#O$O%O%O&O'O(O(O)O*O*O+O,O-O-O.O/O/O0O~1O}2O}2O|3O{4Oz4Oz5Oy6Ox7Ox7Ow8Ov9Ou9Ou:Ot;Os;OsOp>Op?Oo@On@OnAOmBOlCOkCOkDOjEOiEOiFOhGOgHOgHOfIOeJOdJOdKOcLObMObMOaNO`OO_OO_PO^QO]RO]RO\SO[TOZTOZUOYVOXVOXWOWXOVYOUYOUZOT[OS[OS\OR]OQ^OP^OP_OO`ON`ONaOMbOLcOKcOKdOJeOIeOIfOHgOGhOGhOFiOEjODjODkOClOBmOBmOAnO@oO?oO?pO>qO=qO=rO>=<;;:99877654432210/ / .!-"-",#+$*$*%)&('(''(&)%)%*$+#,#,"-!. . /01123345667889:;;<==>??@A B B C D D E FGGHIIJKLLMNNPSVY\_begjmoru w} zz |w t q m j g eb_\YVSQNKIFCA>;9641/-*(%#!     !!     &&&%%%$$$##" "!"#!%!&!( * +-/12468:<=?ACEGIKMOQSUWZ\^`begiknp~s|u{wy zw |u s q o m k i geca_][XVTROMLLLLLLLLLLLLL L L L L L L LLLLLLLLLLLLLLLLLLLLLLLLLL L!L!L"L#L$L$L%L&L&L'L(L)L)L*L+L+L,L-L.L.L/L0L0L1L2L3L3L~4L}5L|5L|6L{7Lz8Lz8Ly9Lx:Lw:Lw;LvLs?Lr?Lr@LqALpBLpBLoCLnDLmDLmELlFLkGLkGLjHLiILhILhJLgKLfLLfLLeMLdNLcNLcOLbPLaQLaQL`RL_SL^SL^TL]UL\VL\VL[WLZXLYXLYYLXZLW[LW[LV\LU]LT]LT^LS_LR`LR`LQaLPbLObLOcLNdLMeLMeLLfLKgLJgLJhLIiLHjLHjLGkLFlLElLEmLDnLCoLCoLBpLAqL@qL@rL?sL>tL>tL=uL==<;::98876554332100/..-, + +!*")#)#($'%&%&&%'$($(#)"*!*!+ ,--.//0122345567789::;<<=> ? ? @ A A B CDDEFFGHIIJKKMPSVY\_begjmor u w| zy |v s p m j gda^[XVSPMKHEC@=;8631.,*'%#     !!"     ''&&&%%%$$## #!"#"%!&!(!* + -/12468:<=?ACEGIKMOQSUWZ\^`begiknp~s|uzwxzv |t r p o m k i g db`^\ZXUSQOLJIIIIIIIIIIIII I I I I I I IIIIIIIIIIIIIIIIIIIIIIIIII I!I"I"I#I$I$I%I&I'I'I(I)I)I*I+I,I,I-I.I/I/I0I1I1I2I3I4I4I5I6I6I~7I}8I|9I|9I{:Iz;Iy;IyIw>Iv?Iu@It@ItAIsBIrCIrCIqDIpEIoFIoFInGImHImHIlIIkJIjKIjKIiLIhMIhMIgNIfOIePIePIdQIcRIbRIbSIaTI`UI`UI_VI^WI]WI]XI\YI[ZI[ZIZ[IY\IX]IX]IW^IV_IV_IU`ITaISbISbIRcIQdIQdIPeIOfINgINgIMhILiIKiIKjIJkIIlIIlIHmIGnIFnIFoIEpIDqIDqICrIBsIAtIAtI@uI?vI?vI>wI=xI > = < ; ;:99876654432110//.-,,+*)) (!'!'"&#%$$$$%#&"'"'!( ))*+,,-../01123345667889:; ; < = > > ? @@ABCCDEEFGHHJMPSVY\_begjmo r u w| zy |u r o l ifc`][XUROMJGEB?=:8530.+)'$"  !!!""    (''&&&%%%$$$ #!##"%"&"(!*!+ - / 12468:<=?ACEGIKMOQSUWZ\^`begiknp}r{uywwzv|tr p n l j h f d b`][YWUSPNLIGEEEEEEEEEEEEE E E E E E EEEEEEEEEEEEEEEEEEEEEEEEEE E E!E"E"E#E$E%E%E&E'E(E(E)E*E*E+E,E-E-E.E/E/E0E1E2E2E3E4E5E5E6E7E7E8E9E~:E~:E};E|Ey?Ey?Ex@EwAEvBEvBEuCEtDEtDEsEErFEqGEqGEpHEoIEoJEnJEmKElLElLEkMEjNEiOEiOEhPEgQEgQEfREeSEdTEdTEcUEbVEbWEaWE`XE_YE_YE^ZE][E\\E\\E[]EZ^EZ^EY_EX`EWaEWaEVbEUcEUdETdESeERfERfEQgEPhEOiEOiENjEMkEMkELlEKmEJnEJnEIoEHpEHqEGqEFrEEsEEsEDtECuEBvEBvEAwE@xE@xE?yE>zE={E={E<|E;}E:~E:~E9E8E8E7E6E5E5E4E3E3E2E1E0E0E/E.E-E-E,E+E+E*E)E(E(E'E&E&E%E$E#E#E"E!E E EEEEEEEEEEEEEEEEEEEEEEEEEE E E E E E E EEEEEEEEEEEEEEDDCBBA@??>== < ; : : 9 877655432210//.--,+**)(('& % %!$"#""#"$!% % &'(()**+,--.//012234556778 9 : : ; < <=>??@ABBCDDEGJMPSVY\_begjm o r u~ w{ zx |u r o lifc`]ZWTROLIGDA?<:7520-+(&$! !!!"""    (('''&&&%%$$ $!###%#&"("*!+!-!/ 1 2468:<=?ACEGIKMOQSUWZ\^`begikn~p|r{uywwzu|sqo m k i g e c a _][XVTRPMKIFDBBBBBBBBBBBB B B B B B B BBBBBBBBBBBBBBBBBBBBBBBBBB B B!B"B#B#B$B%B&B&B'B(B(B)B*B+B+B,B-B.B.B/B0B0B1B2B3B3B4B5B6B6B7B8B8B9B:B;B;BB}>B|?B{@B{@BzAByBByCBxCBwDBvEBvFBuFBtGBsHBsHBrIBqJBqKBpKBoLBnMBnNBmNBlOBkPBkPBjQBiRBiSBhSBgTBfUBfVBeVBdWBcXBcXBbYBaZBa[B`[B_\B^]B^^B]^B\_B[`B[`BZaBYbBYcBXcBWdBVeBVfBUfBTgBShBShBRiBQjBQkBPkBOlBNmBNnBMnBLoBKpBKpBJqBIrBIsBHsBGtBFuBFvBEvBDwBCxBCxBByBAzBA{B@{B?|B>}B>~B=~B<B;B;B:B9B9B8B7B6B6B5B4B3B3B2B1B1B0B/B.B.B-B,B+B+B*B)B)B(B'B&B&B%B$B#B#B"B!B!B BBBBBBBBBBBBBBBBBBBBBBBBBB B B B B B B BBBBBBBBBBBBBBA@@?>>=<;;: 9 8 8 7 6 6 54332100/..-,++*)(('&&%$## "!!! " ##$%&&'())*++,-../01123345 6 6 7 8 9 9 :;;<=>>?@AABDGJMPSVY\_begj m o r u~ wz zw |t qnkheb_\YVTQNKIFCA><9742/-*(&#!  ! !"""#"     )(('''&&&%%% $!$##%#&#("*"+"-!/!1 2 468:<=?ACEGIKMOQSUWZ\^`begikn~p|rzuxwvzt|rpom k i g e b ` ^ \ZXVSQOMJHECA???????????? ? ? ? ? ? ? ?????????????????????????? ?!?!?"?#?$?$?%?&?'?'?(?)?)?*?+?,?,?-?.?/?/?0?1?1?2?3?4?4?5?6?7?7?8?9?:?:?;??????~@?~A?}B?|B?{C?{D?zE?yE?xF?xG?wG?vH?vI?uJ?tJ?sK?sL?rM?qM?pN?pO?oO?nP?mQ?mR?lR?kS?kT?jU?iU?hV?hW?gX?fX?eY?eZ?dZ?c[?c\?b]?a]?`^?`_?_`?^`?]a?]b?\b?[c?Zd?Ze?Ye?Xf?Xg?Wh?Vh?Ui?Uj?Tk?Sk?Rl?Rm?Qm?Pn?Oo?Op?Np?Mq?Mr?Ls?Ks?Jt?Ju?Iu?Hv?Gw?Gx?Fx?Ey?Ez?D{?C{?B|?B}?A~?@~?????>?=?=<<;::9877 6 5 4 4 3 2 110//.-,,+*))(''&%$$#"!!  !""#$$%&''()**+,--.//012 2 3 4 5 5 6 7889::;<==>?ADGJMPSVY\_beg j m o r u} wz zw |spmjgda^\YVSPNKHEC@>;8631/,*'%#   ! ! !""###"     ))((('''&&%% %!$#$$$&#(#*"+"-"/!1!2 4 6 8:<=?ACEGIKMOQSUWZ\^`begikn}p{ryuwwvzt|rpnlj h f d b ` ^ [ YWUSPNLIGEB@=<<<<<<<<<<<< < < < < < < <<<<<<<<<<<<<<<<<<<<<<<<<< <><=<=<<<;<;<:<9<8<8<7<6<5<5<4<3<2<2<1<0<0ADGJMPSVY\_be g j m o r u| wy zv|spmjgda^[XURPMJHEB@=:8530.,)'$"   !! " ""####"    *)))(('''&&& %!%#%$$&$(#*#+#-"/"1!2!4!6 8 :;=?ACEGIKMOQSUWZ\^`begik~n|pzryuwwuzs|qomkig e c a _ ] [ Y VTRPMKIFDB?=:999999999999 9 9 9 9 9 9 9999999999999999999999999 9 9!9"9#9#9$9%9%9&9'9(9(9)9*9+9+9,9-9.9.9/90919192939494959697979899999:9;9<9<9=9>9?9?9@9A9B9B9C9D9E9E9F9~G9}H9}H9|I9{J9zJ9zK9yL9xM9wM9wN9vO9uP9uP9tQ9sR9rS9rS9qT9pU9oV9oV9nW9mX9lY9lY9kZ9j[9i[9i\9h]9g^9f^9f_9e`9da9da9cb9bc9ad9ad9`e9_f9^g9^g9]h9\i9[j9[j9Zk9Yl9Xm9Xm9Wn9Vo9Uo9Up9Tq9Sr9Rr9Rs9Qt9Pu9Pu9Ov9Nw9Mx9Mx9Ly9Kz9J{9J{9I|9H}9G~9G~9F9E9D9D9C9B9A9A9@9?9?9>9=9<9<9;9:99999897969695949393929190909/9.9.9-9,9+9+9*9)9(9(9'9&9%9%9$9#9"9"9!9 99999999999999999999999999 9 9 9 9 9 9 9999999999999877654432110 / . . - , + +*)(('&%%$##"!   !!"#$$%&''()**+ , , - . / / 012234556788;>ADGJMPSVY\_b e g j m o r u| wxzu|rolifc`]ZWUROLJGDB?<:7520-+)&$!   !! " " "##$$#"    **)))((('''& &!%#%$%&$($*$+#-#/"1"2"4!6!8 : ;=?ACEGIKMOQSUWZ\^`begik}n|pzrxuvwtzr|pomkige c ` ^ \ Z X V TQOMJHFCA><97555555555555 5 5 5 5 5 5 5555555555555555555555555 5!5!5"5#5#5$5%5&5&5'5(5)5)5*5+5,5,5-5.5/5/505152525354555556575858595:5;5;5<5=5>5>5?5@5@5A5B5C5C5D5E5F5F5G5H5I5I5~J5}K5}L5|L5{M5zN5zO5yO5xP5wQ5wR5vR5uS5tT5tU5sU5rV5qW5qX5pX5oY5nZ5n[5m[5l\5k]5k^5j^5i_5h`5h`5ga5fb5ec5ec5dd5ce5cf5bf5ag5`h5`i5_i5^j5]k5]l5\l5[m5Zn5Zo5Yo5Xp5Wq5Wr5Vr5Us5Tt5Tu5Su5Rv5Qw5Qx5Px5Oy5Nz5N{5M{5L|5K}5K~5J~5I5H5H5G5F5F5E5D5C5C5B5A5@5@5?5>5=5=5<5;5:5:595857575655545453525151505/5.5.5-5,5+5+5*5)5(5(5'5&5&5%5$5#5#5"5!5 5 5555555555555555555555555 5 5 5 5 5 555555555555555432210//.-, , + * ) ) ('&&%$##"!!  !""#$%%&'( ( ) * + + , -../011234457;>ADGJMPSVY\_ b e g j m o r~ u{wxzu|qnkheb_]ZWTQNLIFDA><9742/-*(&#!  !!!" " ###$$%#"     +***))(((''' &!&#&$%&%($*$+$-#/#1#2"4"6!8!: ; = ?ACEGIKMOQSUWZ\^`begik}n{pyrwuvwtzr|pnljhfdb ` ^ \ Y W U S QNLJGEC@>;964222222222222 2 2 2 2 2 2 2222222222222222222222222 2!2!2"2#2$2$2%2&2'2'2(2)2*2*2+2,2-2-2.2/20202122232324252626272829292:2;2<2<2=2>2?2?2@2A2B2B2C2D2E2E2F2G2H2H2I2J2K2K2L2M2~N2}N2|O2|P2{Q2zQ2yR2yS2xT2wT2vU2vV2uW2tW2sX2sY2rZ2qZ2p[2p\2o]2n]2n^2m_2l`2k`2ka2jb2ic2hc2hd2ge2ff2ef2eg2dh2ci2bi2bj2ak2`l2_l2_m2^n2]o2\o2\p2[q2Zr2Yr2Ys2Xt2Wu2Vu2Vv2Uw2Tx2Sx2Sy2Rz2Q{2P{2P|2O}2N~2M~2M2L2K2J2J2I2H2G2G2F2E2D2D2C2B2A2A2@2?2>2>2=2<2;2;2:292828272625252423222221202/2/2.2-2,2,2+2*2)2)2(2'2&2&2%2$2#2#2"2!2 2 2222222222222222222222222 2 2 2 2 2 22222222222222100/.--,+** ) ( ' ' & % $$#"!!   !"##$ % & & ' ( ) )*+,,-.//01247;>ADGJMPSVY\ _ b e g j m o r}uzwwzt|qnkheb_\YVSQNKHFC@>;9641/,*'%#   !!""" # #$$$%%#"     ++***)))(((''!'#&$&&%(%*%+$-$/#1#2#4"6"8!:!;!= ? ACEGIKMOQSUWZ\^`bdgi~k|nzpyrwuuwszq|omkigeca_] [ Y W T R P NKIGDB?=;8530//////////// / / / / / / ///////////////////////// /!/"/"/#/$/%/%/&/'/(/(/)/*/+/+/,/-/././//0/1/1/2/3/4/4/5/6/7/7/8/9/:/:/;//?/@/A/A/B/C/D/D/E/F/G/G/H/I/J/J/K/L/M/M/N/O/P/P/~Q/}R/|S/|S/{T/zU/yV/yV/xW/wX/vY/vY/uZ/t[/s\/s\/r]/q^/p_/p_/o`/na/mb/mb/lc/kd/je/je/if/hg/gh/gh/fi/ej/dk/dk/cl/bm/an/an/`o/_p/^q/^q/]r/\s/[t/[t/Zu/Yv/Xw/Ww/Wx/Vy/Uz/Tz/T{/S|/R}/Q}/Q~/P/O/N/N/M/L/K/K/J/I/H/H/G/F/E/E/D/C/B/B/A/@/?/?/>/=/ADGJMPSVY \ _ b e g j m or}uzwvzs|pmjgda^[XVSPMJHEB@=;8631.,)'$"   !!""## # $$$%%%#"    ,+++***))((('!'#'$&&&(&*%+%-$/$1$2#4#6"8":";!=!? A CEGIKMOQSUWZ\^`bdgi}k|nzpxrvutwrzp|omkigeca^\Z X V T Q O M K HFDA?<:7520-++++++++++++ + + + + + + ++++++++++++++++++++++++ + +!+"+#+#+$+%+&+&+'+(+)+)+*+++,+,+-+.+/+/+0+1+2+2+3+4+5+6+6+7+8+9+9+:+;+<+<+=+>+?+?+@+A+B+B+C+D+E+E+F+G+H+H+I+J+K+K+L+M+N+O+O+P+Q+R+R+S+T+~U+}U+|V+|W+{X+zX+yY+yZ+x[+w[+v\+u]+u^+t^+s_+r`+ra+qa+pb+oc+od+nd+me+lf+lg+kh+jh+ii+ij+hk+gk+fl+fm+en+dn+co+cp+bq+aq+`r+`s+_t+^t+]u+\v+\w+[w+Zx+Yy+Yz+Xz+W{+V|+V}+U}+T~+S+S+R+Q+P+P+O+N+M+M+L+K+J+J+I+H+G+G+F+E+D+C+C+B+A+@+@+?+>+=+=+<+;+:+:+9+8+7+7+6+5+4+4+3+2+1+1+0+/+.+.+-+,+++*+*+)+(+'+'+&+%+$+$+#+"+!+!+ +++++++++++++++++++++++++ + + + + + ++++++++++++++*))('&&%$## " !       ! " ##$%&&'())*+-147;>ADGJMPSV Y \ _ b e g jmor|uywvzs|olifc`][XUROMJGDB?=:7520-+)&$!  !!!""## # $ $%%%&%#"    ,,+++***)))((!(#'$'&&(&*&+%-%/%1$2$4#6#8#:";"=!?!A C E GIKMOQSUWY\^`bdgi}k{nypwrvutwrzp|nljhfdb`^\ZW U S Q O L J H EC@><9741/,)(((((((((((( ( ( ( ( ( ( (((((((((((((((((((((((( (!(!("(#($($(%(&('('((()(*(*(+(,(-(-(.(/(0(1(1(2(3(4(4(5(6(7(7(8(9(:(:(;(<(=(=(>(?(@(A(A(B(C(D(D(E(F(G(G(H(I(J(J(K(L(M(M(N(O(P(Q(Q(R(S(T(T(U(V(W(~W(~X(}Y(|Z({Z({[(z\(y](x](x^(w_(v`(ua(ua(tb(sc(rd(rd(qe(pf(og(ng(nh(mi(lj(kj(kk(jl(im(hm(hn(go(fp(eq(eq(dr(cs(bt(bt(au(`v(_w(^w(^x(]y(\z([z([{(Z|(Y}(X}(X~(W(V(U(U(T(S(R(R(Q(P(O(N(N(M(L(K(K(J(I(H(H(G(F(E(E(D(C(B(B(A(@(?(>(>(=(<(;(;(:(9(8(8(7(6(5(5(4(3(2(2(1(0(/(.(.(-(,(+(+(*()((((('(&(%(%($(#("("(!( ((((((((((((((((((((((((( ( ( ( ( ( (((((((((((((''&%$$#"!!                !!"#$$%&''*-147;>ADGJMP S V Y \ _ b e gjmor{uxwuzr|olifc`]ZWTQOLIGDA?<9742/-*(&# ! !!"""##$ $ $%%&&&%#"    -,,,+++***))(!(#($'&'('*&+&-%/%0%2$4$6$8#:#;"="?!A!C!E G IKMOQSUWY\^`bdg~i|kznypwruuswqzo|mkigeca_][YWU R P N L I G E B@=;8631.+)&$$$$$$$$$$$$ $ $ $ $ $ $$$$$$$$$$$$$$$$$$$$$$$$$ $!$!$"$#$$$%$%$&$'$($($)$*$+$+$,$-$.$/$/$0$1$2$2$3$4$5$5$6$7$8$8$9$:$;$<$<$=$>$?$?$@$A$B$B$C$D$E$F$F$G$H$I$I$J$K$L$L$M$N$O$O$P$Q$R$S$S$T$U$V$V$W$X$Y$Y$Z$~[$~\$}]$|]${^${_$z`$y`$xa$xb$wc$vc$ud$te$tf$sf$rg$qh$qi$pj$oj$nk$nl$mm$lm$kn$jo$jp$ip$hq$gr$gs$ft$et$du$dv$cw$bw$ax$ay$`z$_z$^{$]|$]}$\}$[~$Z$Z$Y$X$W$W$V$U$T$S$S$R$Q$P$P$O$N$M$M$L$K$J$J$I$H$G$F$F$E$D$C$C$B$A$@$@$?$>$=$<$<$;$:$9$9$8$7$6$6$5$4$3$3$2$1$0$/$/$.$-$,$,$+$*$)$)$($'$&$%$%$$$#$"$"$!$ $$$$$$$$$$$$$$$$$$$$$$$$$ $ $ $ $ $ $$$$$$$$$$$$$$#"!!              !""#$'*-147;>ADGJM P S V Y \ _ b egjmo~r{uxwtzq|nkheb_\YVTQNKIFCA>;9641/,*' % #! !!""###$$ % %%&&&'%#"    --,,,+++***))!)#($(&(('*'+&-&/&0%2%4$6$8$:#;#="?"A"C!E!G I KMOQSUWY\^`bdg}i|kznxpvrturwpzo|mkigeca_\ZXVTR O M K I F D A ?=:8530-+(%"!!!!!!!!!!!! ! ! ! ! ! !!!!!!!!!!!!!!!!!!!!!!!!! !!!"!"!#!$!%!&!&!'!(!)!)!*!+!,!,!-!.!/!0!0!1!2!3!3!4!5!6!6!7!8!9!:!:!;!!?!@!A!A!B!C!D!D!E!F!G!G!H!I!J!K!K!L!M!N!N!O!P!Q!Q!R!S!T!U!U!V!W!X!X!Y!Z![!\!\!]!^!~_!~_!}`!|a!{b!zb!zc!yd!xe!wf!wf!vg!uh!ti!ti!sj!rk!ql!pl!pm!on!no!mp!mp!lq!kr!js!is!it!hu!gv!fw!fw!ex!dy!cz!cz!b{!a|!`}!_}!_~!^!]!\!\![!Z!Y!Y!X!W!V!U!U!T!S!R!R!Q!P!O!O!N!M!L!K!K!J!I!H!H!G!F!E!D!D!C!B!A!A!@!?!>!>!=!ADGJ M P S V Y \ _ begjmo}rzuwwtzq|mjgda^\YVSPMKHEC@=;8631.,) ' $!"! !""##$$$% % &&&'''%#"   .---,,,+++***!)#)$(&((()'+'-'/&0&2%4%6%8$:$;#=#?#A"C"E!G!I!K M OQSUWY\^`bdg}i{kynwpurturwpzn|ljhfdb`^\ZXUSQO L J H E C A > <9742/-*'$"        !"##$%&''()**+,-../0112345567889:;;<=>??@ABBCDEFFGHIIJKLMMNOPPQRSTTUVWWXYZ[[\]^^_`ab~b}c}d|e{ezfzgyhxhwivjvkultlsmsnroqoppoqornsmsltlukvjviwixhygzfze{e|d}c}b~ba`_^^]\[[ZYXWWVUTTSRQPPONMMLKJIIHGFFEDCBBA@??>=<<;:9887655432110/..-,+**)(''&%$##"!                     #'*-147;>ADG J M P S V Y \ _begjmo}ryuvwszp|mjgda^[XURPMJGEB?=:8530. + ) &!$!""""##$$%% % & &&''('%#"   ..---,,,+++**!*#)$)&)(()(+(-'/'0&2&4&6%8%:$;$=$?#A#C"E"G"I!K!M O QSUWY\^`bd~g|izkynwpursuqwozm|kigeca_][YWURPNL I G E B @ > ; 9641.,)&$!       !!"#$$%&'(()*++,-.//012234566789::;<==>?@AABCDDEFGHHIJKKLMNOOPQRRSTUVVWXYZZ[\]]^_`aabcdde~f}g}h|h{izjykykxlwmvnvouotpsqrrrsqsptouovnvmwlxkykzjzi{h|h}g}f~eddcba``_^]]\[ZYYXWVVUTSRRQPOONMLKKJIHHGFEDDCBA@@?>==<;:9987665432210//.-,++*)(''&%$$#"!                #'*-147;>AD G J M P S V Y \_begjmo|ryuvwrzo|lifc`]ZWUROLIGDA?<:742/ - +!(!&!#"!"###$$%%% & &'''(('%#"   /...---,,,+++!*#*$*&)())(+(-(/'0'2'4&6&8%:%;%=$?$A#C#E#G"I"K!M!O Q S UWY\^`bd}g|izkxnvptrrupwozm|kigeca_]ZXVTRPMKI F D B ? = : 8 530.+(&#        !""#$%%&'())*+,--./0012344567889:;;<=>??@ABCCDEFFGHIJJKLMNNOPQQRSTUUVWXYYZ[\\]^_``abcddefgghi~j}k}k|l{mznyoyoxpwqvrurusttsurvrvqwpxoynznzm{l|k}j}j~ihggfedccba`__^]\\[ZYXXWVUTTSRQQPONMMLKJIIHGFFEDCBBA@?>>=<;;:9877654332100/.-,,+*)(('&%%$#"!!        #'*-147;>A D G J M P S V Y\_begjm~o{rxuuwrzo|lheb_]ZWTQNLIFCA><9641 / ,!*!("%"#" ##$$$%%&& & ''((()'%#"  //...---,,,++!+#*$*&*()))+)-(/(0'2'4'6&8&:&;%=%?$A$C$E#G#I"K"M!O!Q!S U WY\^`b~d}g{iykwnuptrrupwnzl|jhfdb`^\ZXVSQOMJHFC A ? < : 7 5 20-*(%"       !"##$%&&'()**+,-../0122345567899:;<==>?@AABCDDEFGHHIJKLLMNOPPQRSTTUVWWXYZ[[\]^__`abccdeffghijjklm~n}n|o|p{qzryrxsxtwuvvuvuwtxsyryqzq{p|o}n}m~mlkjiihgfeedcbba`_^^]\[ZZYXWVVUTSSRQPOONMLKKJIHGGFEDCCBA@@?>=<<;:9887654432110/.--,+*))('&%%$#"!!                  #'*-147;> A D G J M P S VY\_begjm~o{rwutwqzn|kheb_\YVSPNKHFC@>;86 3 1 .!,!)"'"%#"# #$$%%%&&' ' '((())'%#"  0///...---,,,!+#+$+&*(*)*+)-)/(0(2(4'6'8':&;&=%?%A%C$E$G#I#K"M"O"Q!S!U W Y\^`b~d|gzixkwnupsrquowmzk|igeca_][YWUSPNLJGEC@ > ; 9 6 4 1 /,*'$!        !"#$$%&''()*++,-.//012334567789:;;<=>??@ABCCDEFGGHIJJKLMNNOPQRRSTUVVWXYZZ[\]^^_`abbcdeffghijjklmmnopq~q}r|s|t{uzuyvxwxxwyvyuzt{t|s}r}q~pponmllkjihhgfeddcba``_^]\\[ZYYXWVUUTSRQQPONMMLKJIIHGFEEDCBAA@?>==<;:9987665432210/..-,+**)('&&%$#""!                   #'*-147; > A D G J M PSVY\_begjm}ozrwutwpzm|jgda^[XVSPMJHEB@=:8 5 3!0!.!+")"&#$#"$$$%%&&&' ' ( (())))'%# "   00////...---,!,#+$+&+(*)*+*-)/)0)2(4(6'8'9';&=&?%A%C%E$G$I#K#M#O"Q"S!U!W Y \ ^`b}d{gzixkvntprrpuowmzk|i~geca_][XVTRPNKIGDB@= ; 8 6 3 1 . +)&#!                                 ! ! " # $ % % & ' ( ) ) * + , - - . / 0 1 1 2 3 4 5 5 6 7 8 9 9 : ; < = = > ? @ A A B C D E E F G H I I J K L M M N O P Q Q R S T U U V W X Y Y Z [ \ ] ] ^ _ ` a a b c d e e f g h i i j k l m m n o p q q r s t u ~u }v |w {x {y zy yz x{ w| w} v} u~ t s s r q p o o n m l k k j i h g g f e d c c b a ` _ _ ^ ] \ [ [ Z Y X W W V U T S S R Q P O O N M L K K J I H G G F E D C C B A @ ? ? > = < ; ; : 9 8 7 7 6 5 4 3 3 2 1 0 / / . - , + + * ) ( ' ' & % $ # # " !                                     #'*-147 ; > A D G J MPSVY\_begjm|oyrvuswpzm|jfca^[XUROLJGDB?<: 7 5!2!0"-"+"(#&##$!$%%%&&''' ( (())**)'%# "   1000///...---!,#,$,&+(+)++*-*/*0)2)4(6(8(9';'=&?&A&C%E%G$I$K$M#O#Q"S"U!W!Y!\ ^ `~b}d{gyiwkuntprrpunwlzj|h~fdb`^\ZXVSQOMKHFDA?<: 8 5 3 0 - + (%#           !""#$%&&'()**+,-../012234566789:;;<=>??@ABCCDEFGGHIJKKLMNOOPQRSSTUVWXXYZ[\\]^_``abcddefghhijkllmnoppqrstuuvwxy~y}z|{{|{}z}y~xwvvutsrrqponnmlkjjihgffedcbba`_^^]\[ZYYXWVUUTSRQQPONMMLKJIIHGFEEDCBA@@?>=<<;:9887654432100/.-,,+*)(('&%$##"!        #'*-14 7 ; > A D G JMPSVY\_begjm|oyruurwozl|ifc`]ZWTQOLIFDA> < 9 7!4!1"/",#*#(#%$#$ %%&&&'''( ( )))***)'%# " ! 110000///...-!-#-$,&,(,)+++-*/*0*2)4)6)8(9(;'='?'A&C&E%G%I%K$M$O#Q#S#U"W"Y!\!^ `~ b|dzgxiwkunspqroumwkyi|h~fdb`][YWUSQNLJHECA><97 4 2 / - * ' %"         !"##$%&''()*++,-./0012344567889:;<==>?@AABCDEEFGHIIJKLMNNOPQRRSTUVVWXYZ[[\]^__`abccdefgghijkllmnoppqrsttuvwxyyz{|~}~}}~|{zzyxwvvutsrqqponmmlkjiihgfeedcba``_^]\\[ZYXXWVUTSSRQPOONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.--,+*))('&%$$#"!          #'*-1 4 7 ; > A D GJMPSVY\_begj~m{oxruurwnzk|heb_\YVTQNKHFC@ > ;!9!6!3"1".#,#)$'$%$"% %&&&''((( ) )***+*)'%# " ! 2111000///...!-#-$-&,(,),++-+/+0*2*4*6)8)9(;(=(?'A'C&E&G&I%K%M$O$Q$S#U#W"Y"\!^!`} b{ dz gxivktmrpproumwkyi|g~eca_][YVTRPNKIGEB@=;964 1 . , ) ' $ !     !"#$%%&'())*+,-../012234566789:;;<=>??@ABCDDEFGHHIJKLLMNOPQQRSTUUVWXYZZ[\]^^_`abbcdefgghijkklmnoppqrsttuvwxxyz{|}}~~}||{zyxwwvutssrqpoonmlkjjihgffedcbaa`_^]]\[ZYYXWVUTTSRQPPONMLKKJIHGGFEDCCBA@?>>=<;::987655432110/.--,+*)(('&%$$#"!    #'*- 1 4 7 ; > A DGJMPSVY\_begj~mzowrtuqwnzk|heb_\YVSPMKHEB @ =!:!8"5"3#0#.#+$)$&%$%"%&&'''(() ) ) ***++*)'% # "  " 222111000///.!.#.$-&-(-),+,-,/+0+2*4*6*8)9);)=(?(A'C'E'G&I&K%M%O%Q$S$U#W#Y"["^~"`}!b{!dy gw iuktmrpprnulwjyh|f~db`^\ZXVTQOMKIFDB?=:8530 . + ) & #            !"#$%%&'())*+,-../012234566789:;;<=>??@ABCDDEFGHHIJKLLMNOPQQRSTUUVWXYZZ[\]^^_`abbcdefgghijkklmnoppqrsttuvwxxyz{|}}~~}||{zyxwwvutssrqponnmlkjjihgffedcbaa`_^]]\[ZYYXWVUTTSRQPPONMLKKJIHGGFEDCCBA@?>>=<;::987655432110/.--,+*)(('&%$$#"!         #' * - 1 4 7 ; > ADGJMPSVY\_begj}mzowrsupwmzj|gda^[XURPMJG D B ?!=!:"7"5#2#0$-$+$(%&%#&!&&''((()) * **+++,*)'% # "  " 3222111000///!.#.$.&-(-)-+,-,/,0+2+4+6*8*9*;)=)?(A(C(E'G'I&K&M&O%Q%S$U$W#Y#[#^~"`|"bz!dx!gw iu ksmqpormukwjyh|f~db`^[YWUSQOLJHFCA><:7520- * ( % "             !"#$%%&'())*+,-../012234566789:;;<=>??@ABCDDEFGHHIJKLLMNOPQQRSTUUVWXYYZ[\]^^_`abbcdefgghijkklmnoopqrsttuvwxxyz{|}}~~}||{zyxwwvutssrqponnmlkjjihgffedcbaa`_^]]\[ZYYXWVUTTSRQPPONMLKKJIHGGFEDCCBA@?>>=<;::987655432110/.--,+*)(('&%$$#"!         # ' * - 1 4 7 ; >ADGJMPSVY\_begj|myovrsuowlzi|fc`]ZWUROLI G D!A!?"<"9"7#4#2$/$-%*%(%%&#& '''(()))* * *++,,,*)'% # " !# 333222111000/!/#/$.&.(.)-+---/,0,2,4+6+8*9*;*=)?)A)C(E(G'I'K'M&O&Q%S%U$W$Y$[#^}#`{"bz"dx!gv!it kr mp pormukwiyg|e~ca_][YWTRPNLIGEC@>;9641/,*' $ "              !"#$%%&'())*+,--./012234566789:;;<=>??@ABCCDEFGHHIJKLLMNOPQQRSTUUVWXYYZ[\]^^_`abbcdefgghijkklmnoopqrsttuvwxxyz{|}}~~}||{zyxwwvutssrqponnmlkjjihgffedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCCBA@?>>=<;::987655432110/.--,+*)(('&%$$#"!          # ' * - 1 4 7 ;>ADGJMPSVY\_begj|mxourruowlzi|fc`]ZWTQNK I F!C!A">";#9#6#4$1$.%,%*&'&%&"' '((())*** + ++,,,,*)' % # " !# 4333222111100!0#/$/&/(.).+.--/-0,2,4,6+8+9+;*=*?*A)C)E(G(I(K'M'O&Q&S&U%W%Y$[~$^}#`{#by"dw"gu"it!kr!mp pn rlujwhyf|d~b`^\ZXVTROMKIFDB?=;8631.,)&$ !                !"#$%%&'())*+,--./012234566789:;;<=>??@ABCCDEFGHHIJKLLMNOPQQRSTUUVWXYYZ[\]^^_`abbcdefgghijkklmnoopqrsttuvwxxyz{|}~}}~||{zyxwwvutssrqponnmlkjjihgffedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.--,+*)(('&%$$#"!           # ' * - 1 47;>ADGJMPSVY\_beg~j{mxotrqunwkzh|eb_\YVSP N K!H!E!C"@"=#;#8$5$3%0%.%+&)&&'$'"'(()))*** + + ,,,--,*)' % # "  "$ 4443332221110!0#0$/&/(/).+.-./-0-2-4,6,8,9+;+=*?*A*C)E)G)I(K(M'O'Q'S&U&W%Y%[~$^|$`z$bx#dw#gu"is"kq!mo!pm rk ujwhyf|d~b`^\ZWUSQOMJHFCA?<:7530-+(&#                !"#$%%&'())*+,--./012234566789:;;<=>??@ABCCDEFGHHIJKLLMNOPQQRSTUUVWXYYZ[\]^^_`abbcdefgghijkklmnoopqrsttuvwxxyz{|~}}}|~|{zyxwwvutssrqponnmlkjjihgffedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!            # ' * - 147;>ADGJMPSVY\_beg~jzmwotrqumwjzg|da^[XUS P M!J!G"E"B"?#=#:$7$5%2%0&-&+&('&'#(!(())***++ + ,,,--.,*)' % #" !"$ 5444333322211!1#0$0&0(/)/+/-./.0.2-4-6-8,9,;+=+?+A*C*E*G)I)K(M(O(Q'S'U&W&Y%[}%^{%`z$bx$dv#gt#ir"kp"mo!pm!rk!ui wg ye|c~a_][YWURPNLJGEC@><9742/-*'%"              !"#$%%&'())*+,--./012234566789:;;<=>??@ABCCDEFGHHIJKLLMNOPPQRSTUUVWXYYZ[\]^^_`abbcdeffghijkklmnoopqrsttuvwxxyz{~|}||}|~{zyxwwvutssrqponnmlkjjihgffedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!             # ' * -147;>ADGJMPSVY\_beg}jzmvosrpumwjzg|da^[XU R O!L!J"G"D#A#?$<$9$7%4%2&/&-'*'('%(#(!)))***++, , ,---..,*)' % #" !#% 5554443332221!1#1$0&0(0)/+/-//.0.2.4-6-8-9,;,=,?+A+C*E*G*I)K)M)O(Q(S'U'W&Y~&[|&^{%`y%bw$du$ft#ir#kp#mn"pl"rj!uh!wf yd |b~`^\ZXVTRPMKIGDB@=;9641/,)'$!              !"#$$%&'())*+,--./012234566789::;<=>??@ABCCDEFGHHIJKLLMNOPPQRSTUUVWXYYZ[\]^^_`abbcdeffghijkklmnoopqrsttuvwxxyz~{}||||}{~zyxwwvutssrqponnmlkjjihgffedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!              # ' *-147;>ADGJMPSVY\_beg|jymvorroulwizf|c`]Z W T!Q!O!L"I"F#C#A$>$;%9%6%4&1&/','*('(%(") )***+++,, - --....,*) ' % #"  "#% 6555444433322!2#1$1&1(0)0+0-///0/2.4.6.8-9-;-=,?,A+C+E+G*I*K*M)O)Q(S(U'W'Y~'[|&^z&`x%bw%du%fs$iq$ko#mm#pl"rj"uh!wf!yd |b ~`^\ZXUSQOMKHFDA?=:8530.+)&#!             !"#$$%&'())*+,--./012234566789::;<=>??@ABCCDEFGHHIJKLLMNOPPQRSTUUVWXYYZ[\]^^_`abbcdeffghijkklmnoopqrsttuvwxxy~z}{||||{}z~yxwwvutssrqponnmlkjjihgffedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!              # '*-147;>ADGJMPSVY\_beg{jxmuorroukwhze|b_\ Y V!T!Q"N"K#H#F#C$@$=%;%8&6&3'1'.'+()(')$)")**+++,,, - - -..//.,*) ' % #"  "$& 6665554443333!2#2$2&1(1)1+0-0/00/2/4/6.8.9-;-=-?,A,C,E+G+I*K*M*O)Q)S)U(W(Y}'[{'^z&`x&bv&dt%fr%ip$ko$mm#pk#ri"tg"we!yc!|a!~_ ] [YWUSPNLJHECA><:7520-+(%#             !"#$$%&'())*+,--./012234566789::;<=>??@ABCCDEFGHHIJKLLMNOPPQRSTUUVWXYYZ[\]^^_`abbcdeffghijkklmnoopqrsttuvwxx~y}z|{||{|z}y~xwwvutssrqponnmlkjjihgffedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!             #'*-147;>ADGJMPSVY\_be~g{jxmtoqrnukwhze|b_ \ Y!V!S"P"M#J#H$E$B%@%=%:&8&5'2'0(-(+(()&)$*!**+++,,-- - ...///.,*) ' %#" !#$& 7666655544433!3#2$2&2(1)1+1-0/0002/4/6/8.9.;.=-?-A-C,E,G+I+K+M*O*Q*S)U)W~(Y|([{'^y'`w'bu&dt&fr%ip%kn$ml$pj$rh#tf#wd"yb"|`!~^!\ Z XVTRPNKIGEB@>;9641/,*'%"            !"#$$%&'())*+,--./012234566789::;<=>??@ABCCDEFGGHIJKLLMNOPPQRSTUUVWXYYZ[\]]^_`abbcdeffghijkklmnoopqrsstuvwx~x}y|z|{{|z|y}x~wwvutssrqponnmlkjjihgffedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!            #'*-147;>ADGJMPSVY\_be}gzjwmtoprmujwgzd |a ^![!X"U"R"O#M#J$G$D%B%?&<&:&7'4'2(/(-)*)()%*#*!+++,,,--. . .///0/.,*) ' %#" !#%' 7776665555444!3#3$3&2(2)2+1-1/10020406/7/9/;.=.?.A-C-E,G,I,K+M+O*Q*S*U)W~)Y|([z(^x(`w'bu'ds&fq&io&km%ml%pj$rh$tf#wd#yb"|`"~^!\!Z X VSQOMKHFDB?=;8631.,)&$!                                       ! " # $ $ % & ' ( ) ) * + , - - . / 0 1 1 2 3 4 5 6 6 7 8 9 : : ; < = > ? ? @ A B C C D E F G G H I J K L L M N O P P Q R S T U U V W X Y Y Z [ \ ] ] ^ _ ` a b b c d e f f g h i j k k l m n o o p q r s s t u v w~ x} x| y| z{ {z |y |x }w ~w v u t s s r q p o n n m l k j j i h g f f e d c b a a ` _ ^ ] ] \ [ Z Y X X W V U T T S R Q P P O N M L K K J I H G G F E D C B B A @ ? > > = < ; : : 9 8 7 6 5 5 4 3 2 1 1 0 / . - , , + * ) ( ( ' & % $ $ # " !                                     #'*-147;>ADGJMPSVY\_be}gyjvmsoprmuiwf zc |`!]!Z"W"U#R#O$L$I$F%D%A&>&<'9'6'4(1(/),)**'*%*"+ ++,,---.. . ///00/.,* ) ' %#"  "$%' 8777766655544!4#4$3&3(3)2+2-2/101214060709/;/=.?.A.C-E-G-I,K,M+O+Q+S*U*W})Y{)[y)^x(`v(bt'dr'fp'io&km&mk%pi%rg$te$wc#ya#|_#~]"["Y!W!U S QNLJHFCA?<:7530-+(&#                                       ! " # $ $ % & ' ( ) ) * + , - - . / 0 1 1 2 3 4 5 6 6 7 8 9 : : ; < = > ? ? @ A B C C D E F G G H I J K L L M N O P P Q R S T U U V W X Y Y Z [ \ ] ] ^ _ ` a b b c d e f f g h i j k k l m n o o p q r s s t u v~ w} x| x| y{ zz {y |x |w }w ~v u t s s r q p o n n m l k j j i h g f f e d c b a a ` _ ^ ] ] \ [ Z Y X X W V U T T S R Q P P O N M L K K J I H G G F E D C B B A @ ? > > = < ; : : 9 8 7 6 5 5 4 3 2 1 1 0 / . - , , + * ) ( ( ' & % $ $ # " !                                     #'*-147;>ADGJMPSVY\_be|gyjumroorlui wf zc!|`!]"Z"W#T#Q$N$K%I%F&C&@&>';'8(6(3)1).),*)*'+$+"+,,,--... / / /0001/.,* ) ' %#"  "$&( 8887776666555!4#4$4&3(3)3+2-2.2012141607090;/=/?/A.C.E.G-I-K,M,O,Q+S+U~+W|*Y{*[y)^w)`u(bt(dr(fp'in'kl&mj&ph%rf%te%wc$ya$|_#~]#["X"V!T!R P NLIGEC@><9742/-*(%"                                      ! " # $ $ % & ' ( ) ) * + , - - . / 0 1 1 2 3 4 5 6 6 7 8 9 : : ; < = > ? ? @ A B C C D E F G G H I J K L L M N O P P Q R S T U U V W X Y Y Z [ \ ] ] ^ _ ` a b b c d e f f g h i j k k l m n o o p q r s s t u~ v} w| x| x{ yz zy {x |w |w }v ~u t s s r q p o n n m l k j j i h g f f e d c b a a ` _ ^ ] ] \ [ Z Y X X W V U T T S R Q P P O N M L K K J I H G G F E D C B B A @ ? > > = < ; : : 9 8 7 6 5 5 4 3 2 1 1 0 / . - , , + * ) ( ( ' & % $ $ # " !                                      #'*-147;>ADGJMPSVY\_be{gxjumron rk uh!we!zb"|_"\#Y#V#S$P$N%K%H&E&B'@'=':(8(5)3)0*-*+*)+&+$,!,,---.../ / 000111/.,* ) '%#" !#%&( 9888877766655!5#5$4&4(4)3+3-3.2022241617190;0=0?/A/C/E.G.I-K-M-O,Q,S+U}+W|+Yz*[x*^w)`u)bs)dq(fo(im'kl'mj'ph&rf&td%wb%y`$|^$~\#Z#X"V"T!Q!O M KIFDB@=;8641/,)'$"                                    ! " # $ $ % & ' ( ) ) * + , - - . / 0 1 1 2 3 4 5 6 6 7 8 9 : : ; < = > > ? @ A B C C D E F G G H I J K L L M N O P P Q R S T T U V W X Y Y Z [ \ ] ] ^ _ ` a b b c d e f f g h i j j k l m n o o p q r s s t~ u} v| w| x{ xz yy zx {w |w |v }u ~t s s r q p o n n m l k j j i h g f f e d c b a a ` _ ^ ] ] \ [ Z Y X X W V U T T S R Q P P O N M L K K J I H G G F E D C B B A @ ? > > = < ; : : 9 8 7 6 5 5 4 3 2 1 1 0 / . - , , + * ) ( ( ' & % $ $ # " !                                        #'*-147;>ADGJMPSVY\_b~e{gwjtmq on rk!ug!wd"za"|^#[#X$U$S%P%M%J&G&E'B'?(<(:)7)5)2*/*-+*+(+%,#,!,--.../// 0 001111/.,* ) '%#"  !#%') 9998887777666!5#5$5&4(4)4+4-3.3032242627191;1=0?0A/C/E/G.I.K.M-O-Q,S,U},W{+Yy+[x+]v*`t*br)dp)fo(im(kk(mi'pg're&tc&wa%y_%|]$~[$Y$W#U#S"Q"O!L!J H FDA?=:8530.+)&$!                                     ! " # $ $ % & ' ( ( ) * + , - - . / 0 1 1 2 3 4 5 6 6 7 8 9 : : ; < = > > ? @ A B C C D E F G G H I J K L L M N O P P Q R S T T U V W X Y Y Z [ \ ] ] ^ _ ` a b b c d e f f g h i j j k l m n o o p q r s s~ t} u| v| w{ xz xy yx zw {w |v |u }t ~s s r q p o n n m l k j j i h g f f e d c b a a ` _ ^ ] ] \ [ Z Y X X W V U T T S R Q P P O N M L K K J I H G G F E D C B B A @ ? > > = < ; : : 9 8 7 6 5 5 4 3 2 1 1 0 / . - , , + * ) ( ( ' & % $ $ # " !                                           #'*-147;>ADGJMPSVY\_b}ezgwjs mp om!rj!ug"wd"za#|^#[$X$U%R%O&L&I'G'D'A(>(<)9)7*4*1*/+,+*,',%,"- --..///0 0 0 111221/., * ) '%#"  "$&') :999988877776!6#6$5&5(5)4+4-4.3032342627291;1=1?0A0C0E/G/I/K.M.O-Q-S~-U|,W{,Yy,[w+]u+`t*br*dp)fn)il)kj(mh(pg're'tc&wa&y_&|]%~[%Y$V$T#R#P"N"L!J!G E CA><97520-+(%#                                      ! " # $ $ % & ' ( ( ) * + , - - . / 0 1 1 2 3 4 5 6 6 7 8 9 : : ; < = > > ? @ A B C C D E F G G H I J K L L M N O P P Q R S T T U V W X Y Y Z [ \ ] ] ^ _ ` a b b c d e f f g h i j j k l m n o o p q r s~ s} t| u| v{ wz xy xx yw zw {v |u |t }s ~s r q p o n n m l k j j i h g f f e d c b a a ` _ ^ ] ] \ [ Z Y X X W V U T T S R Q P P O N M L K K J I H G G F E D C B B A @ ? > > = < ; : : 9 8 7 6 5 5 4 3 2 1 1 0 / . - , , + * ) ( ( ' & % $ $ # " !                                             #'*-147;>ADGJMPSVY\_b}ey gv js!mp!ol"ri"uf#wc#z`$|]$Z%W%T%Q&N&L'I'F(C(A(>);)9*6*3+1+.+,,),'-$-"-...///00 1 1122231/., * )'%#" !"$&(* :::9999888777!6"6$6&6(5)5+5-4.4042343637292;2=1?1A1C0E0G0I/K/M.O.Q.S}-U|-Wz-Yx,[v,]u+`s+bq+do*fm*il)kj)mh(pf(rd(tb'w`'y^&|\&~Z%X%V$T$R#O#M"K"I!G!D B @>;9641/,*'%"            !"#$$%&'(()*+,--./011234566789::;<=>>?@ABCCDEFGGHIJKLLMNOPPQRSTTUVWXYYZ[\]]^_`abbcdeffghijjklmnoopqr~s}s|t|u{vzwyxxxwywzv{u|t|s}s~rqponnmlkjjihgffedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!                     #'*-147;>ADGJMPSVY\_b| ey gu!jr!mo"ol"ri#ue#wb$z_$|\%Y%V&T&Q'N'K'H(E(C)@)=*;*8*5+3+0,.,+,)-&-$.!..///0001 1 1222331/., * )'%#" !#%'(* ;::::99988887!7"7$6&6(6)5+5-5.5042444637393;2=2?2A1C1E0G0I0K/M/O/Q.S}.U{.Wy-Yx-[v,]t,`r,bp+do+fm*ik*ki)mg)pe)rc(ta(w_'y]'|[&~Y&W&U%S%Q$O$M#J#H"F"D!A!? = :8631.,)'$!          !"#$$%&'(()*+,--./011234556789::;<=>>?@ABCCDEFGGHIJKKLMNOPPQRSTTUVWXYYZ[\]]^_`aabcdeffghijjklmnoopq~r}s|s|t{uzvywxwwxwyvzu{t|s|s}r~qponnmlkjjihgffedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!                     #'*-147;>ADGJMPSVY\_~ b{!ex!gu"jq"mn#ok#rh#ue$wb$z_%|\%Y&V&S'P'M(J(H(E)B)?*=*:+7+5+2,0,--*-(-&.#.!.//000111 2 2233331/. , * )'%#"  "$%')+ ;;;::::999888!8"7$7&7(6)6+6-5.5052444647393;3=2?2A2C1E1G1I0K0M0O/Q~/S|.U{.Wy.Yw-[u-]t-`r,bp,dn+fl+ij+kh*mg*pe)rc)ta(w_(y](|['~Y'W&U&R%P%N$L$J#H#E"C"A!>!< : 7530.+(&#!           !"#$$%&'(()*+,--./011234556789::;<=>>?@ABCCDEFGGHIJKKLMNOPPQRSTTUVWXYYZ[\]]^_`aabcdeffghijjklmnoop~q}r|s|s{tzuyvxwwwwxvyuzt{s|s|r}q~ponnmlkjjihgffedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!                     #'*-147;>ADGJMPSVY \ _~!bz!ew"gt"jq#mm#oj$rg$ud%wa%z^&|[&X&U'R'O(L(J)G)D*A*?*<+9+7,4,1,/-,-*.'.%."/ //001112 2 2 3334431/. , * )'%#"  "$&()+ <;;;;::::9998!8"8$7&7(7)7+6-6.6052545647494;3=3?3A2C2E2G1I1K1M0O0Q}/S|/Uz/Wx.Yv.[u.]s-`q-bo,dm,fl,ij+kh+mf*pd*rb)t`)w^)y\(|Z(~X'V'T&R&P%N%K%I$G$E#B#@">";!9!7 42/-*(%#           !"#$$%&'(()*+,--./011234556789::;<=>>?@ABCCDEFGGHIJKKLMNOPPQRSTTUVWXYYZ[\]]^_`aabcdeffghijjklmnoo~p}q|r|s{sztyuxvwwwwvxuytzs{s|r|q}p~onnmlkjjihgffedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!                     #'*-147;>ADGJMPSV Y \!_}!bz"ev"gs#jp#mm$oj$rg%uc%w`&z]&|Z'W'T(R(O(L)I)F*C*A+>+;+9,6,3-1-.-,.).'/$/"/00011122 2 33444431/. , *)'%#" !#%&(*, <<<;;;;:::999!9"8$8&8'7)7+7-6.6062645657594;4=4?3A3C3E2G2I2K1M1O~0Q}0S{0Uy/Wx/Yv/[t.]r.`p-bo-dm-fk,ii,kg+me+pc+ra*t_*w])y[)|Y(~W(U'S'Q'O&M&K%H%F$D$B#?#=";"8!6!4 1 /,*'$"          !"#$$%&'(()*+,--./011234556789::;<=>>?@ABCCDEFGGHIJKKLMNOPPQRSTTUVWXYYZ[\]]^_`aabcdeffghijjklmno~o}p|q|r{szsytxuwvwwvwuxtyszs{r|q|p}o~nnmlkjjihgffedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!                     #'*-147;>ADGJMPS V!Y!\"_|"by#ev#gs$jo$ml%oi%rf%uc&w`&z]'|Z'W(T(Q)N)K*H*F*C+@+=,;,8,5-3-0...+.)/&/$0!001112223 3 34445531/. , *)'%#"  !#%')*, =<<<<;;;;:::9!9"9$9&8'8)8+7-7.7062646657595;4=4?4A3C3E3G2I2K2M1O~1Q|1Sz0Uy0Ww0Yu/[s/]r.`p.bn.dl-fj-ii,kg,me,pc+ra+t_*w]*y[)|Y)~W)U(S(P'N'L&J&H%F%C$A$?#<#:"8"5!3!0 . +)&$!         !"#$$%&'(()*+,,-./011234556789::;<=>>?@ABBCDEFGGHIJKKLMNOPPQRSTTUVWXXYZ[\]]^_`aabcdeffghijjklmn~n}o|p|q{rzsysxtwuwvvwuwtxsyszr{q|p|o}n~nmlkjjihgffedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!                    #'*-147;>ADGJM P S!V!Y"\"_|#bx#eu$gr$jo%mk%oh&re&ub'w_'z\(|Y(V(S)P)M*K*H+E+B+?,=,:-7-5-2.0.-/+/(/&0#0!011222333 4 44555531/ . , *)'%#"  "$&')+- ===<<<<;;;;::!:"9$9&9'8)8+8-8.7072746667695;5=5?4A4C4E3G3I3K2M2O}2Q|1Sz1Ux1Wv0Yu0[s/]q/`o/bm.dl.fj-ih-kf-md,pb,r`+t^+w\+yZ*|X*~V)T)R(P(N'L'I'G&E&C%@%>$<$9#7#5"2"0!-!+ (&#           !"#$$%&'(()*+,,-./011234556789::;<=>>?@ABBCDEFGGHIJKKLMNOPPQRSTTUVWXXYZ[\]]^_`aabcdeffghijjklm~n}n|o|p{qzrysxswtwuvvuwtwsxsyrzq{p|o|n}n~mlkjjihgffedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!                  #'*-147;>ADGJ M P!S!V"Y"\~#_{#bx$et$gq%jn%mk&oh&re'ua'w^(z[(|X)U)S*P*M*J+G+D,B,?,<-9-7.4.2.//,/*0'0%0#1 11222334 4 4 55566531/ . , *)'%#" !"$&(*+- >====<<<<;;;:!:":$:&9'9)9+8-8.8082747677696;6=5?5A5C4E4G4I3K3M~3O}2Q{2Sy1Ux1Wv1Yt0[r0]p0`o/bm/dk.fi.ig.ke-mc-pb,r`,t^,w\+yZ+|X*~U*S)Q)O)M(K(I'F'D&B&@%=%;$9$6#4#1"/"-!*!' % "           !"#$$%&'(()*+,,-./011234556789::;<=>>?@ABBCDEFGGHIJKKLMNOPPQRSTTUVWXXYZ[\]]^_`aabcdeffghijjkl~m}n|n|o{pzqyrxswswtvuuvtwswsxryqzp{o|n|n}m~lkjjihgffedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!                #'*-147;>AD G J!M!P"S"V#Y#\~$_z$bw%et%gp&jm&mj'og'rd(ua(w^(z[)|X)U*R*O+L+I+F,D,A->-<.9.6.4/1/./,0)0'1$1"122233344 4 555666531/ . ,*)'%#" !#%'(*,. >>>====<<<<;;!;":$:&:':)9+9-9.8082847677797;6=6?6A5C5E5G4I4K4M~3O|3Qz2Sy2Uw2Wu1Ys1[r1]p0`n0bl/dj/fi/ig.ke.mc.pa-r_-t],w[,yY+|W+~U+S*Q*O)L)J(H(F'D'A&?&=&:%8%6$3$1#.#,")!'!$ "           !"#$$%&'(()*+,,-./011234556789::;<=>>?@ABBCDEFGGHIJKKLMNOPPQRSTTUVWXXYZ[\]]^_`aabcdeffghijjk~l}m|n|n{ozpyqxrwswsvtuutvswswrxqypzo{n|n|m}l~kjjihgffedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!              #'*-147;>A D G!J!M"P"S#V#Y$\}$_z%bv%es&gp&jm'mi'of(rc(u`)w])zZ*|W*T*Q+N+K,I,F-C-@->.;.8/6/3/00.0+0)1&1$2!223334445 5 566677531/ . ,*)'%#"  "#%')+,. ?>>>>====<<<'<&:&7%5%3$0$.#+#)"&"#!!!            !"##$%&'(()*+,,-./0112345567899:;<=>>?@ABBCDEFGGHIJKKLMNOOPQRSTTUVWXXYZ[\]]^_`aabcdeefghijj~k}l|m|n{nzoypxqwrwsvsuttusvswrwqxpyozn{n{m|l}k~jjihgffedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!            #'*-147;> A D!G"J"M#P#S$V$Y%\|%_y&bv&er'go'jl'mi(of(rb)u_)w\*zY*|V+S+Q+N,K,H-E-B.@.=.:/8/502000-1+1(1&2#2!333444555 6 667777531 / . ,*)'%#"  "$&()+-/ ???>>>>====<';'9&7&4%2%/$-$*#(#%"#" !!              !"##$%&'(()*+,,-./0112345567899:;<=>>?@ABBCDEFGGHIJKKLMNOOPQRSTTUVWXXYZ[\]]^_`aabcdeefghij~j}k|l|m{nznyoxpwqwrvsusttsusvrwqwpxoynzn{m{l|k}j~jihgffedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!          #'*-147 ; >!A!D"G"J#M#P$S$V%Y%\|&_x&bu'er'gn(jk(mh)oe)rb*u_*w\*zY+|V+S,P,M-J-G-E.B.?/>>>====!<"<$<&;';);+;-:.:0:2949597998;8=8?7A7C7E6G6I6J~5M|5Oz5Qy4Sw4Uu4Ws3Yr3[p2]n2`l2bj1di1fg1he0kc0ma/o_/r]/t[.wY.yW-|U-~S-Q,O,M+J+H*F*D)B)?)=(;(8'6'4&1&/%,%*$'$%#"#""!              !"##$%&'(()*+,,-./0112345567899:;<=>>?@ABBCDEFGGHIJKKLMNOOPQRSTTUVWXXYZ[\]]^_`aabcdeefghi~j}j|k|l{mznynxowpwqvrustsstsurvqwpwoxnynzm{l{k|j}j~ihgffedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!          #'*-14 7 ;!>!A"D"G#J#M$P%S%V&Y~&\{&_x'bt'eq(gn(jk)mg)od*ra*u^+w[+zX,|U,R,O-L-J.G.D.A/>/<090604111/2,2)2'3$3"3 44455566 6 7778887531 / .,*)'%#" !#%')*,.0 @@@@???>>>>==!="=$<&<'<);+;-;.;0:2:4:597999;8=8?8A7C7E7G7H6J}6M{6Oz5Qx5Sv4Uu4Ws4Yq3[o3]m3`l2bj2dh2ff1hd1kb0m`0o^0r\/tZ/wX.yV.|T.~R-P-N,L,J+H+E+C*A*?)<):(8(5'3'0&.&+%)%&$$$!##""!!            !"##$%&'(()*+,,-./0112345567899:;<=>>?@ABBCDEFGGHIJKKLMNOOPQRSTTUVWXXYZ[\]]^_`aabcdeefgh~i}j|j|k{lzmynxnwowpvqurtsssstruqvpwownxnymzl{k{j|j}i~hgffedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!            #'*-1 4 7!;">"A#D#G$J$M%P%S&V&Y}'\z'_w(bt(ep)gm)jj*mg*od*r`+u]+wZ,zW,|T-R-O-L.I.F/C/A/>0;081613102.2+3)3&3$4!445556667 7 7888987531 / .,*)'%#"  "$&')+-/0 AA@@@@???>>>>!="=$=&='<)<+<-;.;0;2;4:5:7:99;9=9?8A8C8E7F7H~7J}6L{6Oy6Qx5Sv5Ut5Wr4Yp4[o4]m3_k3bi3dg2fe2hd1kb1m`1o^0r\0tZ/wX/yV/|T.~R.P-M-K-I,G,E+B+@*>*<)9)7)5(2(0'-'+&(&&%#%!$$#""!!            !"##$%&'(()*+,,-./0012345567899:;<=>>?@ABBCDEFFGHIJKKLMNOOPQRSTTUVWXXYZ[\\]^_`aabcdeefg~h}i|j|j{kzlymxnwnwovpuqtrsrssrtqupvownwnxmylzk{j{j|i}h~gffedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!              #'* - 1!4!7";">#A#D$G$J%M%P&S&V'Y}'\y(_v(bs)ep)gl*ji*mf+oc+r`,u],wZ,zW-|T-Q.N.K/H/E/C0@0=1:181522202-3+3(3&4#4!555666777 8 889998753 1 / .,*)'%#" !"$&(*+-/1 AAAA@@@@???>>!>">$=&='=)=+<-<.<0;2;4;5:7:9:;:=9?9A9C8E8F8H~7J|7Lz7Oy6Qw6Su6Us5Wr5Yp5[n4]l4_j4bi3dg3fe2hc2ka2m_1o]1r[1tY0wW0yU/|S/~Q/O.M.K-H-F,D,B,@+=+;*9*6)4)1(/(-'*'(&%&"% %$$##"" !             !"##$%&'(()*+,,-./0012345567899:;<=>>?@ABBCDEFFGHIJKKLMNOOPQRSTTUVWXXYZ[\\]^_`aabcdeef~g}h|i|j{jzkylxmwnwnvouptqsrsrrsqtpuovnwnwmxlykzj{j{i|h}g~ffedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!                #' * -!1!4"7#;#>$A$D%G%J&M&P'S'V(Y|(\y)_u)br*eo*gl*jh+me+ob,r_,u\-wY-zV.|S.P.M/J/H0E0B0?1=1:2724223/3-3*4(4%4#5 55667777 8 8 8999:8753 1 /.,*)'%#" !#%'(*,.01 BBAAAA@@@@???!>">$>&>'=)=+=-=.<0<2<4;5;7;9:;:=:?:A9C9E9F8H}8J{8Lz7Nx7Qv7Su6Us6Wq6Yo5[n5]l5_j4bh4df3fd3hb3k`2m^2o]2r[1tY1wW0yT0{R0~P/N/L.J.H-F-C-A,?,=+:+8*6*3)1).),()(''$'"&&%$$##" " !!           !"##$%&'(()*+,,-./0012345567899:;<=>>?@ABBCDEFFGHIJKKLMNOOPQRSTTUVWXXYZ[\\]^_`aabcdee~f}g|h{i{jzjykxlwmwnvnuotpsqsrrrqsptounvnwmwlxkyjzj{i{h|g}f~fedcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!                  # '!*!-"1"4#7#;$>$A%D%G&J&M'P'S(V(Y{)\x)_u*bq*en+gk+jh,me,ob,r^-u[-wX.zU.|R/P/M/J0G0D1A1?1<292734313/4,4*4'5$5"5 66677788 8 999:::8753 1 /.,*)'%#" "#%')+-.02 BBBBAAAA@@@@?!?"?$>&>'>)>+=-=.=0<2<4<5<7;9;;;=:?:A:C9E9F~9H}9J{8Ly8Nw8Qv7St7Ur7Wp6Yo6[m5]k5_i5bg4df4fd4hb3k`3m^3o\2rZ2tX1wV1yT1{R0~P0N/K/I/G.E.C-@->,<,:,7+5+3*0*.)+))(&($'!'&&%%$$# #"!!           !"##$%&'(()*+,,-./0012345567899:;<=>>?@ABBCDEFFGHIJKKLMNOOPQRSTTUVWXXYZ[\\]^_`aabcde~e}f|g{h{izjyjxkwlwmvnuntospsqrrqrpsotnunvmwlwkxjyjzi{h{g|f}e~edcbaa`_^]]\[ZYXXWVUTTSRQPPONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!                      #!'!*"-"1#4#7$;%>%A&D&G'J'M(P(S)V~)Y{*\w*_t*bq+em+gj,jg,md-oa-r^.u[.wX.zU/|R/O0L0I0F1C1A2>2;293633414.4+5)5&5$6!667778889 9 9:::;:875 3 1 /.,*)'%#" "$&()+-/12 CCBBBBAAAA@@@!@"?$?&?'>)>+>->.=0=2=4<5<7<9<;;=;?;A:C:D:F~9H|9Jz9Ly8Nw8Qu8Ss7Ur7Wp7Yn6[l6]j6_i5bg5de5fc4ha4k_4m]3o[3rY2tW2wU2yS1{Q1~O0M0K0I/F/D.B.@.>-;-9,7,4+2+/*-**)()%(#( ('&&%%$ $ ##""            !"##$%&''()*+,,-./0012345567899:;<==>?@ABBCDEFFGHIJKKLMNOOPQRSSTUVWXXYZ[\\]^_`aabcd~e}e|f{g{hziyixjwkwlvmuntnsosprqqrprosntnumvlwkwjxjyizh{g{f|e}e~dcbaa`_^]]\[ZYXXWVUTTSRQPOONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!                       !#!'"*#-#1$4$7%;%>&A&D'G'J(M(P)S)V}*Yz*\w+_s+bp,em,gj-jf-mc-o`.r].uZ/wW/zT/|Q0N0K1H1F2C2@2=3;383543405-5+5(6&6#6!777888999 : :::;;:875 3 1 /.,*)'%#" !#$&(*,./13 CCCCBBBBAAAA@!@"@$@&?'?)?+>->.>0>2=4=5=7<9<;<=?@ABBCDEFFGHIJKKLMNOOPQRSSTUVWXXYZ[\\]^_`aabc~d}e|e{f{gzhyixiwjwkvlumtnsnsorpqqprornsntmulvkwjwjxiyhzg{f{e|e}d~cbaa`_^]]\[ZYXXWVUTTSRQPOONMLKKJIHGGFEDCBBA@?>>=<;::987655432110/.-,,+*)(('&%$$#"!                      !!"#"'#*#-$1$4%7&;&>'A'D(G(J)M)P*S*V}*Yy+\v+_s,bo,el-gi-jf.mc.o`.r\/uY/wV0zS0|P1N1K1H2E2B3?3=3:4745425/5-5*6(6%7#7 7888999: : : :;;;<:875 3 1/.,*)'%#" !#%')*,.023 DDCCCCBBBBAAA!A"@$@&@'@)?+?-?.>0>2>4>5=7=9=;<=/<.:.8.5-3-0,.,,+)+'*$*!))((''&& % %$$#           !"##$%&''()*+,,-./0012345567899:;<==>?@ABBCDEFFGHIJKKLMNOOPQRSSTUVWXXYZ[\\]^_`aab~c}d|e{e{fzgyhxiwiwjvkultmsnsnroqppqornrnsmtlukvjwjwixhygzf{e{e|d}c~baa`_^]]\[ZYXXWVUTTSRQPOONMLKKJIHGGFEDCBBA@?>>=<;:9987655432110/.-,,+*)(('&%$$#"!                      !!""##'$*$-%1%4&7&;'>'A(D(G)J)M*P*S+V|+Yy,\u,_r-bo-ek-gh.je.mb/o_/r\0uY0wV0zS1|P1M2J2G2D3B3?4<494754515/6,6*6'7%7"7 888999:: : ;;;<<<:875 3 1/.,*)'%#" "$&')+-/024 DDDDCCCCBBBBA!A"A$A&@'@)@+@,?.?0?2>4>5>7>9=;===?0?@ABBCDEFFGHIJKKLMNOOPQRSSTUVWXXYZ[\\]^_`aa~b}c|d{e{ezfygxhwiwivjuktlsmsnrnqoppoqnrnrmsltkujvjviwhxgyfze{e{d|c}b~aa`_^]]\[ZYXXWVUTTSRQPOONMLKKJIHGGFEDCBBA@?>>=<;:9987655432110/.-,,+*)(('&%$##"!                    !""###$'$*%-%1&4'7';(>(A)D)G*J*M*P+S+V{,Yx,\u-_q-bn.ek.gh/jd/ma/o^0r[0uX1wU1zR1|O2L2I3G3D3A4>4;595653616.6,7)7&7$8!88999:::; ; ;<<<=<:87 5 3 1/.,*)'%#" "$&(*,-/134 EEDDDDCCCCBBB!B"A$A&A'A)@+@,@.@0?2?4?5>7>9>;>==?=A=C?@ABBCDEFFGHIJJKLMNOOPQRSSTUVWXXYZ[\\]^_``~a}b|c{d{ezeyfxgwhwiviujtkslsmrnqnpoopnqnrmrlsktjujvivhwgxfyeze{d{c|b}a~a`_^]]\[ZYXXWVUTTSRQPOONMLKKJIHGGFEDCBBA@?>>=<;:9987655432110/.-,,+*)(('&%$##"!                     ! !""##$#%'%*&-&1'4'7(;(>)A)D*G*J+M+P,S~,V{-Yw-\t._q.bm.ej/gg/jd0ma0o]1rZ1uW1wT2zQ2|O3L3I3F4C4@4>5;586563607.7+7(8&8#8!999:::;;; < <<<==<:87 5 3 1/.,*)'%#"! #%'(*,.0135 EEEEDDDDCCCCB!B"B$B&A'A)A+A,@.@0@2@4?5?7?9>;>=>?>A=B~=D|=F{ ? @ A B B C D E F F G H I J J K L M N O O P Q R S S T U V W X X Y Z [ \ \ ] ^ _ `~ `} a| b{ c{ dz ey ex fw gw hv iu it js ks lr mq np no on pn qm rl rk sj tj ui vh vg wf xe ye zd {c {b |a }a ~` _ ^ ] ] \ [ Z Y X X W V U T T S R Q P O O N M L K K J I H G G F E D C B B A @ ? > > = < ; : 9 9 8 7 6 5 5 4 3 2 1 1 0 / . - , , + * ) ( ( ' & % $ # # " !                                             ! ! "##$$%#%'&*&-'1(4(7);)>*A*D+G+J+M,P,S}-Vz-Yv.\s._p/bm/ei0gf0jc0m`1o]1rZ2uW2wT2zQ3|N3K4H4E4B5@5=5:6765727/7-8*8(8%9#9 9:::;;;< < < <===><:87 5 31/.,*)'%# "" #%')+-.0245 FFEEEEDDDDCCC!C"B$B&B'B)A+A,A.A0@2@4@5@7?9?;?=>?>A>B}>D|=Fz=Hy=Jw2<2:171503000./+/).&.$-!-,,++**) ) ((''$!  !!!!!!!!!!!! ! ! ! ! ! !!!!!!!!!!!!!!!!!!!!!!! !!!"!#!#!$!%!&!'!'!(!)!*!+!,!,!-!.!/!0!0!1!2!3!4!4!5!6!7!8!9!9!:!;!!?!@!A!B!B!C!D!E!F!F!G!H!I!J!J!K!L!M!N!O!O!P!Q!R!S!S!T!U!V!W!X!X!Y!Z![!\!\!]!^!_~!`}!`|!a{!b{!cz!dy!ex!ew!fw!gv!hu!it!is!js!kr!lq!mp!no!nn!on!pm!ql!rk!rj!sj!ti!uh!vg!vf!we!xe!yd!zc!{b!{a!|a!}`!~_!^!]!]!\![!Z!Y!X!X!W!V!U!T!T!S!R!Q!P!O!O!N!M!L!K!K!J!I!H!G!G!F!E!D!C!B!B!A!@!?!>!>!=!*A+D+G,J,M-P-S|.Vy.Yv.\r/_o/bl0ei0ge1jb1m_1o\2rY2uV3wS3zP3|M4J4G5E5B5?6<6:6774718/8,8*9'9%9": ::;;;<<< < ===>>><:87 5 31/.,*)'%# "" $&()+-/1246 FFFFEEEEDDDDC!C"C$C&B'B)B+B,A.A0A2A4@5@7@9@;?=???A>B}>D{>Fz>Hx=Jv=Lu=Ns"?"@"A"B"B"C"D"E"F"F"G"H"I"J"J"K"L"M"N"O"O"P"Q"R"S"S"T"U"V"W"W"X"Y"Z"["\"\"]"^~"_}"`|"`{"a{"bz"cy"dx"ew"ew"fv"gu"ht"is"is"jr"kq"lp"mo"mn"nn"om"pl"qk"rj"rj"si"th"ug"vf"ve"we"xd"yc"zb"{a"{a"|`"}_"~^"]"]"\"["Z"Y"X"X"W"V"U"T"T"S"R"Q"P"O"O"N"M"L"K"K"J"I"H"G"G"F"E"D"C"B"B"A"@"?">">"="<";":"9"9"8"7"6"5"5"4"3"2"1"1"0"/"."-",","+"*")"("("'"&"%"$"#"#"""!" """"""""""""""""""""""" " " " " " " """"""""""""!              !"" # $$%%&&#'''*(-)1)4*7*;+>+A,D,G,J-M-P.S|.Vx/Yu/\r0_n0bk0eh1ge1jb2m_2o[3rX3uU3wR4zO4|M5J5G5D6A6>6<797674818.9,9)9':$:":;;;;<<<= = =>>>>><:8 7 5 31/.,*)'%#!"# $&(*,./1356 GGFFFFEEEEDDD!D"D$C&C'C)C+B,B.B0A2A4A5A7@9@;@=@??A~?B|?D{>Fy>Hw>Jv=Lt=Nr=Pp=So"?"@"A"A"B"C"D"E"F"F"G"H"I"J"J"K"L"M"N"O"O"P"Q"R"S"S"T"U"V"W"W"X"Y"Z"["\"\"]~"^}"_|"`{"`{"az"by"cx"dw"ew"ev"fu"gt"hs"is"ir"jq"kp"lo"mn"mn"nm"ol"pk"qj"rj"ri"sh"tg"uf"ve"ve"wd"xc"yb"za"{a"{`"|_"}^"~]"]"\"["Z"Y"X"X"W"V"U"T"T"S"R"Q"P"O"O"N"M"L"K"K"J"I"H"G"G"F"E"D"C"B"B"A"@"?">">"="<";":"9"9"8"7"6"5"5"4"3"2"1"1"0"/"."-",","+"*")"("("'"&"%"$"#"#"""!" """"""""""""""""""""""" " " " " " " """""""""""""!              !"## $ $%&&''#('(*)-)1*4*7+;+>,A,D-G-J.M.P~/S{/Vx/Yt0\q0_n1bj1eg2gd2ja2m^3o[3rX4uU4wR4zO5|L5I6F6C6@7>7;788683809.9+9(:&:#:!;;;<<<=== > >>>??><:8 7 531/.,*)'%#!"# %')+,.02357 GGGGFFFFEEEEE!D"D$D&D'C)C+C,C.B0B2B4A5A7A9A;@=@?@A}@B|?Dz?Fx?Hw>Ju>Ls>Nr=Pp=Rn=Ul=Wk4<4:483533202.2,1)1'0$0"///..--, , ++**($!    ############ # # # # # ####################### #!#"#####$#%#&#'#'#(#)#*#+#+#,#-#.#/#0#0#1#2#3#4#4#5#6#7#8#9#9#:#;#<#=#=#>#?#@#A#A#B#C#D#E#F#F#G#H#I#J#J#K#L#M#N#O#O#P#Q#R#S#S#T#U#V#W#W#X#Y#Z#[#\#\~#]}#^|#_{#`{#`z#ay#bx#cw#dw#ev#eu#ft#gs#hs#ir#iq#jp#ko#ln#mn#mm#nl#ok#pj#qj#ri#rh#sg#tf#ue#ve#vd#wc#xb#ya#za#{`#{_#|^#}]#~]#\#[#Z#Y#X#X#W#V#U#T#T#S#R#Q#P#O#O#N#M#L#K#K#J#I#H#G#G#F#E#D#C#B#B#A#@#?#>#>#=#<#;#:#9#9#8#7#6#5#5#4#3#2#1#1#0#/#.#-#,#,#+#*#)#(#(#'#&#%#$#####"#!# ####################### # # # # # # #############"!               !"#$$ % %&&''(#(')**-*1+4+7,;,>-A-D-G.J.M/P~/Sz0Vw0Yt1\p1_m1bj2eg2gc3j`3m]4oZ4rW4uT5wQ5zN5|K6H6E7C7@7=8:888592909-:*:(:%;#; ;<<<===> > > >???@><:8 7 531/.,*)'% #""$ &')+-/02467 HHGGGGFFFFFEE!E"E$D&D'D)D+C,C.C0C2B4B5B7A9A;A=A?@A}@B{@Dz@Fx?Hv?Ju?Ls>Nq>Po>Rn=Ul=Wj=Yh=[f<]d<_c5;59474542303-2+2)1&1$1!00//..-- , ,++*($!  !$$$$$$$$$$$$ $ $ $ $ $ $$$$$$$$$$$$$$$$$$$$$$$ $!$"$#$#$$$%$&$'$'$($)$*$+$+$,$-$.$/$0$0$1$2$3$4$4$5$6$7$8$9$9$:$;$<$=$=$>$?$@$A$A$B$C$D$E$F$F$G$H$I$J$J$K$L$M$N$O$O$P$Q$R$S$S$T$U$V$W$W$X$Y$Z$[$\~$\}$]|$^{$_{$`z$`y$ax$bw$cw$dv$eu$et$fs$gs$hr$iq$ip$jo$kn$ln$mm$ml$nk$oj$pj$qi$rh$rg$sf$te$ue$vd$vc$wb$xa$ya$z`${_${^$|]$}]$~\$[$Z$Y$X$X$W$V$U$T$T$S$R$Q$P$O$O$N$M$L$K$K$J$I$H$G$G$F$E$D$C$B$B$A$@$?$>$>$=$<$;$:$9$9$8$7$6$5$5$4$3$2$1$1$0$/$.$-$,$,$+$*$)$($($'$&$%$$$#$#$"$!$ $$$$$$$$$$$$$$$$$$$$$$$ $ $ $ $ $ $ $$$$$$$$$$$$##"!               !"#$$% % &''(()#)'***-+1+4,7,;->-A.D.G/J/M0P}0Sz0Vv1Ys1\p2_l2bi3ef3gc3j`4m\4oY5rV5uS5wP6zM6|K6H7E7B8?8<8:979492:/:,:*;';%;"< <<===>>> > ???@@@><:8 7 531/.,*)'% #""$ &(*,-/13468 HHHHGGGGGFFFF!E"E$E&E'D)D+D,D.C0C2C3C5B7B9B;B=A?~AA|AB{@Dy@Fw@Hv@Jt?Lr?Np?Po>Rm>Uk>Wi=Yh=[f=]d<_b%?%@%A%A%B%C%D%E%F%F%G%H%I%J%J%K%L%M%N%N%O%P%Q%R%S%S%T%U%V%W%W%X%Y%Z%[~%\}%\|%]{%^{%_z%`y%`x%aw%bw%cv%du%dt%es%fs%gr%hq%ip%io%jn%kn%lm%ml%mk%nj%oj%pi%qh%rg%rf%se%te%ud%vc%vb%wa%xa%y`%z_%z^%{]%|]%}\%~[%Z%Y%X%X%W%V%U%T%T%S%R%Q%P%O%O%N%M%L%K%K%J%I%H%G%G%F%E%D%C%B%B%A%@%?%>%>%=%<%;%:%9%9%8%7%6%5%5%4%3%2%1%1%0%/%.%-%,%,%+%*%)%(%(%'%&%%%$%#%#%"%!% %%%%%%%%%%%%%%%%%%%%%%% % % % % % % %%%%%%%%%%%%$##"!               !"#$$%& & ''(()*#*'+*+-,1,4-7-;.>.A.D/G/J0M0P|1Sy1Vv2Yr2\o2_l3bh3ee4gb4j_4m\5oY5rV6uS6wP6zM7|J7G8D8A8?9<9996:4:1:.;,;);'<$<"<===>>>>? ? ?@@@@@><: 8 7 531/.,*)'%!##"% '(*,.013578 IIHHHHHGGGGFF!F"F$E&E'E)E+D,D.D0D2C3C5C7C9B;B=B?}B@|ABzADxAFw@Hu@Js@Lr@Np?Pn?Rl?Uk>Wi>Yg>[e=]c=_a=a`&?&@&A&A&B&C&D&E&F&F&G&H&I&J&J&K&L&M&N&N&O&P&Q&R&S&S&T&U&V&W&W&X&Y&Z~&[}&\|&\{&]{&^z&_y&`x&`w&aw&bv&cu&dt&ds&es&fr&gq&hp&io&in&jn&km&ll&mk&mj&nj&oi&ph&qg&rf&re&se&td&uc&vb&va&wa&x`&y_&z^&z]&{]&|\&}[&~Z&Y&X&X&W&V&U&T&T&S&R&Q&P&O&O&N&M&L&K&K&J&I&H&G&G&F&E&D&C&B&B&A&@&?&>&>&=&<&;&:&9&9&8&7&6&5&5&4&3&2&1&1&0&/&.&-&,&,&+&*&)&(&(&'&&&%&$&#&#&"&!& &&&&&&&&&&&&&&&&&&&&&&& & & & & & & &&&&&&&&&&&&%$##"!               !"#$$%&' ' (())**#+'+*,-,1-4-7.;.>/A/D0G0J1M1P|1Sx2Vu2Yq3\n3_k4bh4ee4ga5j^5m[6oX6rU6uR7wO7zL7|I8F8D9A9>9;:8:6:3;0;.;+<)<&<#=!==>>>>??? @ @@AAA@><: 8 7531/.,*)' %!##"% ')+-.024579 IIIIHHHHHGGGG!F"F$F&F'E)E+E,E.D0D2D3D5C7C9C;C=~B?}B@{BBzBDxAFvAHuAJs@Lq@No@Pn@Rl?Uj?Wh?Yf>[e>]c>_a=a_=d]=f[8<79776563605.5+4)4&4$3!32211100 / /..-+($ !  #&''''''''''' ' ' ' ' ' ''''''''''''''''''''''' '!'"'"'#'$'%'&'''''(')'*'+'+','-'.'/'0'0'1'2'3'4'4'5'6'7'8'8'9':';'<'='='>'?'@'A'A'B'C'D'E'F'F'G'H'I'J'J'K'L'M'N'N'O'P'Q'R'S'S'T'U'V'W'W'X'Y~'Z}'[|'\{'\{']z'^y'_x'`w'`w'av'bu'ct'ds'ds'er'fq'gp'ho'in'in'jm'kl'lk'mj'mj'ni'oh'pg'qf're're'sd'tc'ub'va'va'w`'x_'y^'z]'z]'{\'|['}Z'~Y'X'X'W'V'U'T'T'S'R'Q'P'O'O'N'M'L'K'K'J'I'H'G'G'F'E'D'C'B'B'A'@'?'>'>'='<';':'9'9'8'7'6'5'5'4'3'2'1'1'0'/'.'-',','+'*')'('('''&'%'$'#'#'"'!' ''''''''''''''''''''''' ' ' ' ' ' ' ''''''''''''&%$##"!               !"#$$%&'' ( ()**++#,',*---1.4.7/;/>/A0D0G1J1M~2P{2Sw3Vt3Yq3\m4_j4bg5ed5ga5j^6mZ6oW7rT7uQ7wN8zK8|I8F9C9@:=:::8;5;2;0<-<*<(=%=#= >>>>???@ @ @ AAAAB@><: 8 7531/.,*)' %"#$"& ()+-/124689 JJIIIIIHHHHGG!G"G$F&F'F)F+F,E.E0E2E3D5D7D9C;C=~C?|C@{BByBDwBFvBHtAJrALpANo@Pm@Rk@Ui@Wh?Yf?[d?]b>_`>a^>d\=fZ=hY=kW'?'@'A'A'B'C'D'E'F'F'G'H'I'J'J'K'L'M'N'N'O'P'Q'R'S'S'T'U'V'W'W'X~'Y}'Z|'[{'\{'\z']y'^x'_w'`w'`v'au'bt'cs'ds'dr'eq'fp'go'hn'in'im'jl'kk'lj'mj'mi'nh'og'pf'qe're'rd'sc'tb'ua'va'v`'w_'x^'y]'z]'z\'{['|Z'}Y'~X'X'W'V'U'T'T'S'R'Q'P'O'O'N'M'L'K'K'J'I'H'G'G'F'E'D'C'B'B'A'@'?'>'>'='<';':'9'9'8'7'6'5'5'4'3'2'1'1'0'/'.'-',','+'*')'('('''&'%'$'#'#'"'!' ''''''''''''''''''''''' ' ' ' ' ' ' '''''''''''''&%$##"!               !"#$$%&'(( ) )**++,#,'-*--.1.4/7/;0>0A1D1G2J2M~2Pz3Sw3Vs4Yp4\m5_j5bf5ec6g`6j]7mZ7oW7rT8uQ8wN8zK9|H9E9B:?:=;:;7;4<2"> >>???@@@ A AAABBB@>< : 8 7531/.,*)'!%##$"& (*,./13568: JJJJIIIIIHHHH!G"G$G&G'G)F+F,F.F0E2E3E5E7D9D;D=}D?|C@zCBxCDwBFuBHsBJrBLpANnAPlARk@Ui@Wg@Ye@[c?]a?_`?a^>d\>fZ>hX=kV=mT=oR(?(@(A(A(B(C(D(E(E(F(G(H(I(J(J(K(L(M(N(N(O(P(Q(R(S(S(T(U(V(W(W~(X}(Y|(Z{([{([z(\y(]x(^w(_w(`v(`u(at(bs(cs(dr(dq(ep(fo(gn(hn(im(il(jk(kj(lj(mi(mh(ng(of(pe(qe(qd(rc(sb(ta(ua(v`(v_(w^(x](y](z\(z[({Z(|Y(}X(~X(W(V(U(T(T(S(R(Q(P(O(O(N(M(L(K(K(J(I(H(G(G(F(E(D(C(B(B(A(@(?(>(>(=(<(;(:(9(9(8(7(6(5(5(4(3(2(1(1(0(/(.(-(,(,(+(*()((((('(&(%($(#(#("(!( ((((((((((((((((((((((( ( ( ( ( ( ( ((((((((((((''&%$##"!              !"#$$%&'(() * *++,,-#-'.*.-/1/4070;1>1A1D2G2J3M}3Py4Sv4Vs4Yo5\l5_i6bf6eb6g_7j\7mY8oV8rS8uP9wM9zJ9|G:D:B:?;<;9<6<4<1=.=,=)>'>$>">???@@@AA A ABBBCB@>< : 8 7531/.,*)'!%##%"' )+,.023579: KKJJJJJIIIIHH!H"H$H&G'G)G+G,F.F0F2F3E5E7E9E;~D=}D?{D@yDBxCDvCFtCHsBJqBLoBNnBPlARjAThAWf@Ye@[c@]a@__?a]?d[?fY>hW>jU>mS=oQ=rO=tM:<::979583818.7,7)7'6$6"55444332 2 1110/+( % ! "%)))))))))))) ) ) ) ) ) ))))))))))))))))))))))) )!)")")#)$)%)&)')')()))*)+)+),)-).)/)/)0)1)2)3)4)4)5)6)7)8)8)9):);)<)=)=)>)?)@)A)A)B)C)D)E)E)F)G)H)I)J)J)K)L)M)N)N)O)P)Q)R)S)S)T)U)V)W~)W})X|)Y{)Z{)[z)[y)\x)]w)^w)_v)`u)`t)as)bs)cr)dq)dp)eo)fn)gn)hm)il)ik)jj)kj)li)mh)mg)nf)oe)pe)qd)qc)rb)sa)ta)u`)v_)v^)w])x])y\)z[)zZ){Y)|X)}X)~W)V)U)T)T)S)R)Q)P)O)O)N)M)L)K)K)J)I)H)G)G)F)E)D)C)B)B)A)@)?)>)>)=)<);):)9)9)8)7)6)5)5)4)3)2)1)1)0)/).)-),),)+)*)))()()')&)%)$)#)#)")!) ))))))))))))))))))))))) ) ) ) ) ) ) ))))))))))))(''&%$##"!           !"#$$%&'())* * ++,,--#.'.*/-/104071;1>2A2D3G3J3M|4Py4Su5Vr5Yo6\k6_h6be7eb7g_8j[8mX8oU9rR9uO9wL:zI:|G:D;A;>;;<9<6=3=0=.=+>)>&>$?!??@@@AAAA B BBCCCB@>< : 87531/.,*) '"%$#%"' )+-/024679; KKKKKJJJJIIII!I"H$H&H'H)G+G,G.G0F2F3F5F7E9E;~E=|E?{D@yDBwDDvDFtCHrCJpCLoBNmBPkBRiBThAWfAYdA[b@]`@_^@a]@d[?fY?hW?jU>mS>oQ>rO=tM=vK=yH<{F<~D;;:9:79592908-8+8)7&7$6!66554443 3 2211/+( % ! #&)*********** * * * * * *********************** *!*"*"*#*$*%*&*'*'*(*)***+*+*,*-*.*/*/*0*1*2*3*4*4*5*6*7*8*8*9*:*;*<*=*=*>*?*@*A*A*B*C*D*E*E*F*G*H*I*J*J*K*L*M*N*N*O*P*Q*R*S*S*T*U*V~*W}*W|*X{*Y{*Zz*[y*[x*\w*]w*^v*_u*`t*`s*as*br*cq*dp*do*en*fn*gm*hl*ik*ij*jj*ki*lh*mg*mf*ne*oe*pd*qc*qb*ra*sa*t`*u_*v^*v]*w]*x\*y[*zZ*zY*{X*|X*}W*~V*U*T*T*S*R*Q*P*O*O*N*M*L*K*K*J*I*H*G*G*F*E*D*C*B*B*A*@*?*>*>*=*<*;*:*9*9*8*7*6*5*5*4*3*2*1*1*0*/*.*-*,*,*+***)*(*(*'*&*%*$*#*#*"*!* *********************** * * * * * * ************)(''&%$##"!         !"#$$%&'())*+ + ,,--..#/'/*0-0114172;2>2A3D3G4J4M{5Px5Su5Vq6Yn6\k7_g7bd7ea8g^8j[9mX9oU9rR:uO:wL:zI;|F;C;@<=<;<8=5=3=0>->+>(?%?#? @@@AAAAB B BCCCCDB@>< : 87531/.,*) '"%$#&"( *,-/13568:; LLKKKKKJJJJJI!I"I$I%H'H)H+H,G.G0G2G3F5F7F9F;}E=|E?zE@xEBwDDuDFsDHrDJpCLnCNlCPkCRiBTgBWeBYcA[bA]`A_^@a\@dZ@fX@hV?jT?mR?oP>qN>tL>vJ=yH={F=~D+?+@+A+A+B+C+D+E+E+F+G+H+I+J+J+K+L+M+N+N+O+P+Q+R+S+S+T+U~+V}+W|+W{+X{+Yz+Zy+[x+[w+\w+]v+^u+_t+`s+`s+ar+bq+cp+do+dn+en+fm+gl+hk+ij+ij+ji+kh+lg+mf+me+ne+od+pc+qb+qa+ra+s`+t_+u^+v]+v]+w\+x[+yZ+zY+zX+{X+|W+}V+~U+T+T+S+R+Q+P+O+O+N+M+L+K+K+J+I+H+G+G+F+E+D+C+B+B+A+@+?+>+>+=+<+;+:+9+9+8+7+6+5+5+4+3+2+1+1+0+/+.+-+,+,+++*+)+(+(+'+&+%+$+#+#+"+!+ +++++++++++++++++++++++ + + + + + + ++++++++++++*)(''&%$##" !       ! "#$$%&'())*++ , ,-..//#0'0*0-1114272;3>3A4D4G4J~5M{5Pw6St6Vq7Ym7\j7_g8bd8e`9g]9jZ9mW:oT:rQ:uN;wK;zH;|E<B<@<==:=7=5>2>/>-?*?'?%@"@ @AAAABBB C CCCDDDB@> < : 87531/.,*)!'#%%#'"( *,.013578:< LLLLLKKKKJJJJ!J"I$I%I'I)H+H,H.H0H2G3G5G7G9~F;}F={F?yF@xEBvEDtEFsDHqDJoDLnDNlCPjCRhCTfCWeBYcB[aB]_A_]Aa[AdY@fW@hU@jS@mQ?oO?qM?tK>vI>yG>{E=~C=A=?<<<:<8;6;3:1:.:,9*9'9%8"8 7776655 5 44332/+( %!! $(++++++++++++ + + + + + +++++++++++++++++++++++ +!+"+"+#+$+%+&+'+'+(+)+*+++++,+-+.+/+/+0+1+2+3+4+4+5+6+7+8+8+9+:+;+<+<+=+>+?+@+A+A+B+C+D+E+E+F+G+H+I+J+J+K+L+M+N+N+O+P+Q+R+R+S+T~+U}+V|+W{+W{+Xz+Yy+Zx+[w+[w+\v+]u+^t+_s+`s+`r+aq+bp+co+dn+dn+em+fl+gk+hj+hj+ii+jh+kg+lf+me+me+nd+oc+pb+qa+qa+r`+s_+t^+u]+v]+v\+w[+xZ+yY+zX+zX+{W+|V+}U+~T+~T+S+R+Q+P+O+O+N+M+L+K+K+J+I+H+G+G+F+E+D+C+B+B+A+@+?+>+>+=+<+;+:+9+9+8+7+6+5+5+4+3+2+1+1+0+/+.+-+,+,+++*+)+(+(+'+&+%+$+#+#+"+!+ +++++++++++++++++++++++ + + + + + + +++++++++++++*)(''&%$## " !     ! " #$$%&'())*+,, - -..//0#0'1*1-2124373;3>4A4D5G5J}6Mz6Pw6Ss7Vp7Ym8\i8_f8bc9e`9g]:jY:mV:oS;rP;uM;wJ7>4>1?/?,?)@'@$@"AAABBBBCC C CDDDEDB@> < : 87531/.,* )!'#%%#'") +-.024679;< MMLLLLLKKKKKJ J"J$J%I'I)I+I,I.H0H2H3H5G7G9~G;|G={F>yF@wFBvFDtEFrEHpEJoELmDNkDPiDRhCTfCWdCYbC[`B]_B_]Ba[AdYAfWAhUAjS@mQ@oO@qM?tK?vI?yG>{D>~B>@=>=<=9<7<5<3;0;.:+:):'9$9"98877766 5 54442/+ ( %!" %(,,,,,,,,,,,, , , , , , ,,,,,,,,,,,,,,,,,,,,,,, ,!,",",#,$,%,&,&,',(,),*,+,+,,,-,.,/,/,0,1,2,3,4,4,5,6,7,8,8,9,:,;,<,<,=,>,?,@,A,A,B,C,D,E,E,F,G,H,I,J,J,K,L,M,N,N,O,P,Q,R,R,S~,T},U|,V{,W{,Wz,Xy,Yx,Zw,[w,[v,\u,]t,^s,_s,`r,`q,ap,bo,cn,dn,dm,el,fk,gj,hj,hi,ih,jg,kf,le,me,md,nc,ob,pa,qa,q`,r_,s^,t],u],v\,v[,wZ,xY,yX,zX,zW,{V,|U,}T,~T,~S,R,Q,P,O,O,N,M,L,K,K,J,I,H,G,G,F,E,D,C,B,B,A,@,?,>,>,=,<,;,:,9,9,8,7,6,5,5,4,3,2,1,1,0,/,.,-,,,,,+,*,),(,(,',&,%,$,#,#,",!, ,,,,,,,,,,,,,,,,,,,,,,, , , , , , , ,,,,,,,,,,,,,+*)(''&%$# # " !   ! " # $$%&'())*+,-- . .//001#1'2*2-2134374;4>5A5D6G6J}6My7Pv7Sr8Vo8Yl8\i9_e9bb:e_:g\:jY;mV;oS;rP><>9>6?3?1?.@+@)@&A$A!ABBBBCCCD D DDEEEDB@> < :87531/.,* )"'$%&#(") +-/13468:;= MMMMMLLLLLKKK K"J$J%J'J)J+I,I.I0I2H3H5H7H9}G;|G=zG>xG@wFBuFDsFFrFHpEJnELlENkEPiDRgDTeDWcCYbC[`C]^C_\BaZBdXBfVAhTAjRAmPAoN@qL@tJ@vH?yF?{D?~B>?>=>;=9=6=4<2<0;-;+;(:&:#:!99888776 6 65542/, ( %!# &)------------ - - - - - ----------------------- -!-"-"-#-$-%-&-&-'-(-)-*-+-+-,---.-/-/-0-1-2-3-4-4-5-6-7-8-8-9-:-;-<-<-=->-?-@-A-A-B-C-D-E-E-F-G-H-I-J-J-K-L-M-N-N-O-P-Q-R-R~-S}-T|-U{-V{-Wz-Wy-Xx-Yw-Zw-[v-[u-\t-]s-^s-_r-`q-`p-ao-bn-cn-dm-dl-ek-fj-gj-hi-hh-ig-jf-ke-le-md-mc-nb-oa-pa-q`-q_-r^-s]-t]-u\-v[-vZ-wY-xX-yX-zW-zV-{U-|T-}T-~S-~R-Q-P-O-O-N-M-L-K-K-J-I-H-G-G-F-E-D-C-B-B-A-@-?->->-=-<-;-:-9-9-8-7-6-5-5-4-3-2-1-1-0-/-.---,-,-+-*-)-(-(-'-&-%-$-#-#-"-!- ----------------------- - - - - - - ------------,,+*)(''&%$ # # " !  ! " # $ $%&'())*+,--. . //0011#2'2*3-3144475;5>5A6D6G7J|7My7Pu8Sr8Vn9Yk9\h9_e:ba:e^;g[;jX;mU@>>>;?8?5?3@0@-@+A(A&A#B BBBCCCDD D DEEEEFDB@> < :87531/.,*!)#'$%&#("* ,./13578:<= NNMMMMMLLLLLK K"K$K%K'J)J+J,J.I0I2I3I5H7~H9}H;{H=yG>xG@vGBtGDsFFqFHoFJnFLlENjEPhERgETeDWcDYaD[_D]]C_[CaYCdXBfVBhTBjRAmPAoNAqLAtI@vG@yE@{C?~A???=>:>8>6=4=1=/<,<*;(;%;#: ::998887 766552/, (%! # '*-........... . . . . . ....................... .!.".".#.$.%.&.&.'.(.).*.+.+.,.-..././.0.1.2.3.4.4.5.6.7.8.8.9.:.;.<.<.=.>.?.@.A.A.B.C.D.E.E.F.G.H.I.J.J.K.L.M.N.N.O.P.Q.R~.R}.S|.T{.U{.Vz.Wy.Wx.Xw.Yw.Zv.[u.[t.\s.]s.^r._q.`p.`o.an.bn.cm.dl.dk.ej.fj.gi.hh.hg.if.je.ke.ld.mc.mb.na.oa.p`.q_.q^.r].s].t\.u[.vZ.vY.wX.xX.yW.zV.zU.{T.|T.}S.~R.~Q.P.O.O.N.M.L.K.K.J.I.H.G.G.F.E.D.C.B.B.A.@.?.>.>.=.<.;.:.9.9.8.7.6.5.5.4.3.2.1.1.0./...-.,.,.+.*.).(.(.'.&.%.$.#.#.".!. ....................... . . . . . . ............-,,+*)(''&% $ # # " !   ! " # $ $ %&'())*+,-../ / 001122#3'3*4-4144575;6>6A7D7G7J{8Mx8Pt9Sq9Vn9Yj:\g:_d;ba;e^;gZzF>|C>@?=?:?7@5@2@/A-A*A'B%B"B BCCCDDDD E EEFFFFDB@ > < :87531/.,*!)#'%%'#)"+ ,.024579;<> NNNNNMMMMMLLL L"L$K%K'K)K+J,J.J0J2J3I5I7~I9|I;zH=yH>wH@vHBtGDrGFpGHoGJmFLkFNjFPhERfETdEWbEY`D[_D]]D_[DaYCdWCfUChSBjQBmOBoMAqKAtIAvGAyE@{B@~@@>?5>3>1=.=,=)<'<%;"; ;:::998 8 777652/, (%!!$ '+./////////// / / / / / /////////////////////// /!/"/"/#/$/%/&/&/'/(/)/*/+/+/,/-/./////0/1/2/3/3/4/5/6/7/8/8/9/:/;//?/@/A/A/B/C/D/E/E/F/G/H/I/I/J/K/L/M/N/N/O/P/Q~/R}/R|/S{/T{/Uz/Vy/Wx/Ww/Xw/Yv/Zu/[t/[s/\s/]r/^q/_p/_o/`n/an/bm/cl/dk/dj/ej/fi/gh/hg/hf/ie/je/kd/lc/mb/ma/na/o`/p_/q^/q]/r]/s\/t[/uZ/uY/vX/wX/xW/yV/zU/zT/{T/|S/}R/~Q/~P/O/O/N/M/L/K/K/J/I/H/G/G/F/E/D/C/B/B/A/@/?/>/>/=/7A7D8G~8J{9Mw9Pt9Sp:Vm:Yj:\f;_c;b`uK>wH>zE?|B???<@:@7@4A1A/A,B)B'B$B"CCCDDDDEE E FFFFGFDB@ > <:87531/., *")$'%%'#)"+ -/124689;=> OONNNNNNMMMML L"L$L%L'K)K+K,K.K0J2J3J5J7}I9|I;zI=xI>wH@uHBsHDrHFpGHnGJlGLkGNiFPgFReFTdFWbEY`E[^E]\D_ZDaXDdVDfTChRCjPCmNBoLBqJBtHAvFAyDA{BA~@@=@;@9?7?4?2>0>.>+=)=&<$0?0@0A0A0B0C0D0E0E0F0G0H0I0I0J0K0L0M0N0N0O0P~0Q}0R|0R{0S{0Tz0Uy0Vx0Ww0Ww0Xv0Yu0Zt0[s0[s0\r0]q0^p0_o0_n0`n0am0bl0ck0dj0dj0ei0fh0gg0hf0he0ie0jd0kc0lb0ma0ma0n`0o_0p^0q]0q]0r\0s[0tZ0uY0uX0vX0wW0xV0yU0zT0zT0{S0|R0}Q0~P0~O0O0N0M0L0K0K0J0I0H0G0G0F0E0D0C0B0B0A0@0?0>0>0=0<0;0:090908070605050403020101000/0.0-0,0,0+0*0)0(0(0'0&0%0$0#0#0"0!0 00000000000000000000000 0 0 0 0 0 0 000000000000/.-,,+*)('' & % $ # # "!   !" # $ $ % & '())*+,-../00 1 122334#4'5*5-6164677;7>8A8D8G}9Jz9Mv:Ps:Sp:Vl;Yi;\f<_coP>rM>uJ?wG?zD?|A@>@<@9A6A3A1B.B+B)C&C$C!CDDDEEEEF F FFGGGFDB@ > <:87531/., *")$'&%(#*", -/13568:<=? OOOOONNNNNMMM M"M$L%L'L)L+L,K.K0K2K3J5~J7}J9{J;yI=xI>vI@tIBsHDqHFoHHnHJlGLjGNhGPgGReFTcFVaFY_F[]E]\E_ZEaXEdVDfTDhRDjPCmNCoLCqJBtHBvEByCB{AA~?A=A;@8@6@4?2?/?->*>(>&=#=!<<<;;;:: 9 998862/ , (%!"& ),000000000000 0 0 0 0 0 00000000000000000000000 0!0"0"0#0$0%0&0&0'0(0)0*0+0+0,0-0.0/0/0001020303040506070808090:0;0<0<0=0>0?0@0A0A0B0C0D0E0E0F0G0H0I0I0J0K0L0M0N0N0O~0P}0Q|0R{0R{0Sz0Ty0Ux0Vw0Ww0Wv0Xu0Yt0Zs0[s0[r0\q0]p0^o0_n0_n0`m0al0bk0cj0dj0di0eh0fg0gf0he0he0id0jc0kb0la0ma0m`0n_0o^0p]0q]0q\0r[0sZ0tY0uX0uX0vW0wV0xU0yT0zT0zS0{R0|Q0}P0~O0~O0N0M0L0K0K0J0I0H0G0G0F0E0D0C0B0B0A0@0?0>0>0=0<0;0:090908070605050403020101000/0.0-0,0,0+0*0)0(0(0'0&0%0$0#0#0"0!0 00000000000000000000000 0 0 0 0 0 0 0000000000000/.-,,+*)(' ' & % $ # #"!   !"# $ $ % & ' ())*+,-../011 2 233444#5'5*6-6174778;8>8A9D9G}:Jy:Mv:Pr;So;VljU>mR>oO?rL?uI?wF@zD@|A@>A;A8A6B3B0B-C+C(C&C#D DDEEEEFF F GGGGHHFDB@ > <:87531/.,!*#)%''%(#*", .023579:<>? PPPOOOOONNNNN M"M$M%M'L)L+L,L.L0K2K3K5~K7|J9zJ;yJ=wJ>vJ@tIBrIDpIFoIHmHJkHLjHNhHPfGRdGTbGVaFY_F[]F][F_YEaWEdUEfSEhQDjODmMDoKCqICtGCvEByCB{AB~>B%>"> ==<<<;;; ::99862/ ,(%! #' *-111111111111 1 1 1 1 1 11111111111111111111111 1!1"1"1#1$1%1&1&1'1(1)1*1+1+1,1-1.1/1/1011121313141516171818191:1;1<1<1=1>1?1@1A1A1B1C1D1E1E1F1G1H1I1I1J1K1L1M1N1N~1O}1P|1Q{1R{1Rz1Sy1Tx1Uw1Vw1Wv1Wu1Xt1Ys1Zs1[r1[q1\p1]o1^n1_n1_m1`l1ak1bj1cj1di1dh1eg1ff1ge1he1hd1ic1jb1ka1la1m`1m_1n^1o]1p]1q\1q[1rZ1sY1tX1uX1uW1vV1wU1xT1yT1zS1zR1{Q1|P1}O1~O1~N1M1L1K1K1J1I1H1G1G1F1E1D1C1B1B1A1@1?1>1>1=1<1;1:191918171615151413121111101/1.1-1,1,1+1*1)1(1(1'1&1%1$1#1#1"1!1 11111111111111111111111 1 1 1 1 1 1 11111111111110/.-,,+*)( ' ' & % $ ##"!   !"#$ $ % & ' ( ))*+,-../0112 2 334455#6'6*7-7174878;9>9A:D:G|:Jx;Mu;Pr;Sne[>gX>jU?mR?oO?rL@uI@wF@zCA|@A=A:B8B5B2C/C-C*C(D%D"D EEEEFFFG G GGHHHHFDB @ > <:87531/.,!*#)%''%)#+"- .024679;=>@ PPPPPOOOOONNN N"N$M%M'M)M+M,L.L0L2L3K5}K7|K9zK;xK=wJ>uJ@sJBrJDpIFnIHlIJkILiHNgHPeHRdHTbGV`GY^G[\G]ZF_XFaVFdUEfSEhQEjOEmMDoJDqHDtFCvDCyBC{@C~>B>===<<< ; ;:::962/ ,(%!!$' +.122222222222 2 2 2 2 2 22222222222222222222222 2!2"2"2#2$2%2&2&2'2(2)2*2*2+2,2-2.2/2/2021222323242526272828292:2;2<2<2=2>2?2@2@2A2B2C2D2E2E2F2G2H2I2I2J2K2L2M2N~2N}2O|2P{2Q{2Rz2Ry2Sx2Tw2Uw2Vv2Vu2Wt2Xs2Ys2Zr2[q2[p2\o2]n2^n2_m2_l2`k2aj2bj2ci2dh2dg2ef2fe2ge2hd2hc2ib2ja2ka2l`2l_2m^2n]2o]2p\2q[2qZ2rY2sX2tX2uW2uV2vU2wT2xT2yS2zR2zQ2{P2|O2}O2~N2~M2L2K2K2J2I2H2G2G2F2E2D2C2B2B2A2@2?2>2>2=2<2;2:292928272625252423222121202/2.2-2,2,2+2*2)2(2(2'2&2%2$2#2#2"2!2 22222222222222222222222 2 2 2 2 2 2 222222222222110/.-,,+*) ( ' ' & % $##"!   !"#$$ % & ' ( ) )*+,-../01223 3 445566#7'7*7-8184979;9>:A:D;G{;Jx;Mt_`>b]>eZ?gW?jT?mQ@oN@rK@uHAwEAzBA|?B=B:B7C4C2C/D,D*D'D$E"EEFFFFGGG G HHHHIHFDB @ ><:87531/. ,"*$)&'(%)#+"- /13468:;=?@ QQQPPPPPOOOOO N"N$N%N'N)M+M,M.M0L2L3~L5}L7{L9yK;xK=vK>tK@sJBqJDoJFnJHlIJjILhINgIPeHRcHTaHV_HY]G[\G]ZG_XGaVFdTFfRFhPFjNEmLEoJEqHDtFDvDDyAC{?C~=C;C9B6B4B2A0A-A+@(@&@$?!??>>===< < <;;:962 / ,(%""%( +/233333333333 3 3 3 3 3 33333333333333333333333 3!3"3"3#3$3%3&3&3'3(3)3*3*3+3,3-3.3/3/3031323333343536373838393:3;3<3<3=3>3?3@3@3A3B3C3D3E3E3F3G3H3I3I3J3K3L3M~3N}3N|3O{3P{3Qz3Ry3Rx3Sw3Tw3Uv3Vu3Vt3Ws3Xs3Yr3Zq3[p3[o3\n3]n3^m3_l3_k3`j3aj3bi3ch3dg3df3ee3fe3gd3hc3hb3ia3ja3k`3l_3l^3m]3n]3o\3p[3qZ3qY3rX3sX3tW3uV3uU3vT3wT3xS3yR3zQ3zP3{O3|O3}N3~M3~L3K3K3J3I3H3G3G3F3E3D3C3B3B3A3@3?3>3>3=3<3;3:393938373635353433323131303/3.3-3,3,3+3*3)3(3(3'3&3%3$3#3#3"3!3 33333333333333333333333 3 3 3 3 3 3 3333333333332110/.-,,+* ) ( ' ' & %$##"!   !"#$$% & ' ( ) ) *+,-../012234 4 555667#7'8*8-919497:;:>;A;D~;GzYf>\c>_`?b]?eY?gV@jS@mP@oMArJAuGAwDBzBB|?B<:87531/.!,"*$)&'(%*#,". 013578:<>?A QQQQQPPPPPPOO O"O$O%N'N)N*N,M.M0M2M3~M5|L7zL9yL;wL=vK>tK@rKBpKDoKFmJHkJJjJLhJNfIPdIRbITaIV_HY]H[[H]YH_WGaUGdSGfQFhOFjMFmKFoIEqGEtEEvCDyAD{?D~>== = <<<;962 / ,(%""&) ,/344444444444 4 4 4 4 4 44444444444444444444444 4!4"4"4#4$4%4&4&4'4(4)4*4*4+4,4-4.4/4/4041424343444546474848494:4;4<4<4=4>4?4@4@4A4B4C4D4E4E4F4G4H4I4I4J4K4L~4M}4N|4N{4O{4Pz4Qy4Rx4Rw4Sw4Tv4Uu4Vt4Vs4Ws4Xr4Yq4Zp4[o4[n4\n4]m4^l4_k4_j4`j4ai4bh4cg4df4de4ee4fd4gc4hb4ha4ia4j`4k_4l^4l]4m]4n\4o[4pZ4qY4qX4rX4sW4tV4uU4uT4vT4wS4xR4yQ4zP4zO4{O4|N4}M4~L4~K4K4J4I4H4G4G4F4E4D4C4B4B4A4@4?4>4>4=4<4;4:494948474645454443424141404/4.4-4,4,4+4*4)4(4(4'4&4%4$4#4#4"4!4 44444444444444444444444 4 4 4 4 4 4 44444444444432110/.-,,+ * ) ( ' ' &%$##"!   !"#$$%& ' ( ) ) * +,-../0122344 5 566778#8'8*9-91:4:7;;;>;ASl>Vi>Ye?\b?__?b\@eY@gV@jSAmPAoMArJBuGBwDBzAC|>C;C8D6D3D0E.E+E(E&F#F!FGGGGHHH H IIIIJJHFD B @ ><:87531/.!,#*%)'')%+#,". 024579;<>@A RRRQQQQQPPPPP O"O$O%O'O)N*N,N.N0N2M3}M5{M7zM9xL;wL
            sL@rLBpKDnKFmKHkKJiJLgJNeJPdJRbIT`IV^IY\I[ZH]YH_WHaUHcSGfQGhOGjMFmKFoIFqGFtDEvBEy@E{>D~> ===<<962 /,(%" #&* -0455555555555 5 5 5 5 5 55555555555555555555555 5!5"5"5#5$5%5&5&5'5(5)5*5*5+5,5-5.5/5/5051525353545556575858595:5;5<5<5=5>5?5@5@5A5B5C5D5E5E5F5G5H5I5I5J5K~5L}5M|5N{5N{5Oz5Py5Qx5Rw5Rw5Sv5Tu5Ut5Vs5Vr5Wr5Xq5Yp5Zo5[n5[n5\m5]l5^k5_j5_j5`i5ah5bg5cf5de5de5ed5fc5gb5ha5ha5i`5j_5k^5l]5l]5m\5n[5oZ5pY5qX5qX5rW5sV5tU5uT5uT5vS5wR5xQ5yP5zO5zO5{N5|M5}L5~K5~K5J5I5H5G5G5F5E5D5C5B5B5A5@5?5>5>5=5<5;5:595958575655555453525151505/5.5-5,5,5+5*5)5(5(5'5&5%5$5#5#5"5!5 55555555555555555555555 5 5 5 5 5 5 555555555555432110/.-,, + * ) ( ' '&%$##"!   !"#$$%&' ( ) ) * + ,-../01223455 6 677888#9'9*:-:1;4;7;;<>Mr>Po>Sk?Vh?Ye?\b@_^@b[@eXAgUAjRAmOBoLBrIBuFCwCCz@C|=D;D8D5E2E0E-E*F(F%F"G GGGHHHHI I IIJJJJHFD B @ ><:87531/ .",$*%)'')%+#-"/ 124689;=?@B RRRRRRQQQQQPP P"P$P%O'O)O*O,O.N0N1~N3|N5{N7yM9xM;vMsL@qLBoLDnLFlKHjKJhKLgKNeKPcJRaJT_JV^JY\I[ZI]XI_VHaTHcRHfPHhNGjLGmJGoHGqFFtDFvBFy@E{=E};E9E7D4D2D0C.C+C)B&B$B"AAA@@@?? ? >>==<963 /,)%"!$'* .1455555555555 5 5 5 5 5 55555555555555555555555 5!5!5"5#5$5%5&5&5'5(5)5*5*5+5,5-5.5/5/5051525353545556575758595:5;5<5<5=5>5?5@5@5A5B5C5D5E5E5F5G5H5I5I5J~5K}5L|5M{5M{5Nz5Oy5Px5Qw5Rw5Rv5Su5Tt5Us5Vr5Vr5Wq5Xp5Yo5Zn5[n5[m5\l5]k5^j5_j5_i5`h5ag5bf5ce5ce5dd5ec5fb5ga5ha5h`5i_5j^5k]5l\5l\5m[5nZ5oY5pX5qX5qW5rV5sU5tT5uT5uS5vR5wQ5xP5yO5yO5zN5{M5|L5}K5~K5~J5I5H5G5G5F5E5D5C5B5B5A5@5?5>5>5=5<5;5:595958575655555453525151505/5.5-5,5,5+5*5)5(5(5'5&5%5$5#5#5"5!5 55555555555555555555555 5 5 5 5 5 5 5555555555555432110/.-, , + * ) ( ''&%$##"!   !"#$$%&'( ) ) * + , -../012234566 7 778899#:':*:-;1;4<7<;<>=A=D|>Gx>Ju>Mq?Pn?Sk?Vg@Yd@\a@_^Ab[AeWAgTBjQBmNBoKCrHCuECwBDz@D|=D:E7E4E2F/F,F*F'G$G"GGHHHIIII J JJJKKJHFD B @><:87531/ .",$*&)('*%,#-"/ 13568:<=?AC SSSRRRRRQQQQQ Q"P$P%P'P)P*O,O.O0O1~N3|N5zN7yN9wN;uMrM@pMBoMDmLFkLHjLJhLLfKNdKPcKRaKT_JV]JY[J[YJ]WI_UIaSIcQIfOHhMHjKHmIGoGGqEGtCGvAFy?F{=F};E8E6E4E2D/D-D+C(C&C#B!BBAAA@@@ ? ??>><96 3 /,)%"!%(+ .2566666666666 6 6 6 6 6 66666666666666666666666 6!6!6"6#6$6%6&6&6'6(6)6*6*6+6,6-6.6/6/6061626363646566676768696:6;6<6<6=6>6?6@6@6A6B6C6D6E6E6F6G6H6I6I~6J}6K|6L{6M{6Mz6Ny6Ox6Pw6Qw6Rv6Ru6St6Ts6Ur6Vr6Vq6Wp6Xo6Yn6Zn6[m6[l6\k6]j6^j6_i6_h6`g6af6be6ce6cd6dc6eb6fa6ga6h`6h_6i^6j]6k\6l\6l[6mZ6nY6oX6pX6qW6qV6rU6sT6tT6uS6uR6vQ6wP6xO6yO6yN6zM6{L6|K6}K6~J6~I6H6G6F6F6E6D6C6B6B6A6@6?6>6>6=6<6;6:696968676665656463626161606/6.6-6,6,6+6*6)6(6(6'6&6%6$6#6#6"6!6 66666666666666666666666 6 6 6 6 6 6 66666666666655432110/.- , , + * ) (''&%$##"!   !"#$$%&'() ) * + , - ../0122345667 7 8899::#:';*;-<1<4<7=;=>>A~>D{>Gw?Jt?Mq?Pm@Sj@Vg@YcA\`A_]BbZBeWBgTBjQCmNCoKCrHDuEDwBDz?E|<:87531/!.#,%*')('*%,#."0 23579;<>@AC SSSSSSRRRRRQQ Q"Q$Q%P'P)P*P,P.O0O1}O3{O5zO7xN9wN;uNrN@pMBnMDmMFkMHiLJgLLfLNdLPbKR`KT^KV\KY[J[YJ]WJ_UJaSIcQIfOIhMIjKHmIHoGHqEHtCGv@Gy>G{7?7@7@7A7B7C7D7E7E7F7G7H7I~7I}7J|7K{7L{7Mz7My7Nx7Ow7Pw7Qv7Ru7Rt7Ss7Tr7Ur7Vq7Vp7Wo7Xn7Yn7Zm7[l7[k7\j7]j7^i7_h7_g7`f7ae7be7cd7cc7db7ea7fa7g`7h_7h^7i]7j\7k\7l[7lZ7mY7nX7oX7pW7qV7qU7rT7sT7tS7uR7uQ7vP7wO7xO7yN7yM7zL7{K7|K7}J7~I7~H7G7F7F7E7D7C7B7B7A7@7?7>7>7=7<7;7:797978777675757473727170707/7.7-7,7,7+7*7)7(7(7'7&7%7$7#7#7"7!7 77777777777777777777777 7 7 7 7 7 7 777777777777655432110/. - , , + * )(''&%$##"!   !"#$$%&'()) * + , - . ./01223456778 8 999::;#;'<*<-<1=4=7>;>>>A~?Dz?Gw?Js@Mp@Pm@SiAVfAYcB\_B_\BbYCeVCgSCjPDmMDoJDrGDuDEwAEz>E|;F9F6F3G0G.G+G(H&H#H!HIIIJJJJ K KKKLLLJHF D B @><:87531/!.#,%*'))'+%-#/"0 24689;=>@BD TTTSSSSSSRRRR R"Q$Q%Q'Q)Q*P,P.P0~P1|P3{O5yO7xO9vO;tOqN@oNBnNDlMFjMHhMJgMLeMNcLPaLR`LT^LV\KYZK[XK]VK_TJaRJcPJfNJhLIjJImHIoFHqDHtBHv@Hy>G{;G}9G7F5F3F0F.E,E)E'D$D"D CCCBBBA A A@@@?<96 3/,)%" #&)- 03788888888888 8 8 8 8 8 88888888888888888888888 8!8!8"8#8$8%8&8&8'8(8)8*8*8+8,8-8.8/8/8081828383848586878788898:8;8<8<8=8>8?8@8@8A8B8C8D8E8E8F8G8H~8I}8I|8J{8K{8Lz8My8Mx8Nw8Ow8Pv8Qu8Rt8Rs8Sr8Tr8Uq8Vp8Vo8Wn8Xn8Ym8Zl8[k8[j8\j8]i8^h8_g8_f8`e8ae8bd8cc8cb8da8ea8f`8g_8h^8h]8i\8j\8k[8lZ8lY8mX8nX8oW8pV8qU8qT8rT8sS8tR8uQ8uP8vO8wO8xN8yM8yL8zK8{K8|J8}I8~H8~G8F8F8E8D8C8B8B8A8@8?8>8>8=8<8;8:898988878685858483828180808/8.8-8,8,8+8*8)8(8(8'8&8%8$8#8#8"8!8 88888888888888888888888 8 8 8 8 8 8 8888888888887655432110/ . - , , + *)(''&%$##"!   !"#$$%&'())* + , - . . /012234567789 9 9::;;<#<'<*=-=1>4>7>;?>?A}?Dy@Gv@JsAMoAPlASiBVeBYbB\_C_\CbXCeUDgRDjODmLEoIErFEuCEw@Fz>F|;F8G5G2G0G-H*H(H%I"I IIJJJJKK K KLLLLLJHF D B@><:87531 /".$,&*())'+%-#/"1 3468:<=?ABD TTTTTTSSSSSRR R"R$R%R'Q)Q*Q,Q.Q0}P1|P3zP5yP7wP9uO;tOpO@oNBmNDkNFjNHhNJfMLdMNcMPaMR_LT]LV[LXYL[WK]VK_TKaRKcPJfNJhLJjJJmHIoEIqCItAIv?Hx=H{;H}9G6G4G2G0F-F+F)E&E$E!DDDCCCBB B AAA@@<96 3/,)%"!$'*- 14899999999999 9 9 9 9 9 99999999999999999999999 9!9!9"9#9$9%9&9&9'9(9)9*9*9+9,9-9.9.9/9091929393949596979798999:9;9<9<9=9>9?9@9@9A9B9C9D9D9E9F9G~9H}9I|9I{9J{9Kz9Ly9Mx9Mw9Nw9Ov9Pu9Qt9Rs9Rr9Sr9Tq9Up9Vo9Vn9Wn9Xm9Yl9Zk9Zj9[j9\i9]h9^g9_f9_e9`e9ad9bc9cb9ca9da9e`9f_9g^9h]9h\9i\9j[9kZ9lY9lX9mX9nW9oV9pU9pT9qT9rS9sR9tQ9uP9uO9vO9wN9xM9yL9yK9zK9{J9|I9}H9~G9~F9F9E9D9C9B9B9A9@9?9>9>9=9<9;9:999998979695959493929190909/9.9-9,9,9+9*9)9(9(9'9&9%9$9#9#9"9!9 99999999999999999999999 9 9 9 9 9 9 99999999999987655432110 / . - , , +*)(''&%$##"!   !"#$$%&'())*+ , - . . / 0122345677899 : :;;;<<#='=*>->1>4?7?;?>@A|@DyAGuAJrAMnBPkBShBVeCYaC\^C_[DbXDeUDgREjOEmKEoIErFFuCFw@Fz=G|:G7G5H2H/H,H*I'I$I"IJJJJKKKK L LLLMMLJHF D B@><:87531 /".$,&*()*',%.#0"1 3579:<>?ACE UUUTTTTTTSSSS S"R$R%R'R)R*Q,Q.~Q0}Q1{Q3zP5xP7wP9uP;sPpO@nOBmODkOFiNHgNJfNLdNNbMP`MR^MT\MV[MXYL[WL]UL_SLaQKcOKfMKhKKjIJmGJoEJqCItAIv?Ix9?9@9@9A9B9C9D9D9E9F~9G}9H|9I{9I{9Jz9Ky9Lx9Mw9Mw9Nv9Ou9Pt9Qs9Rr9Rr9Sq9Tp9Uo9Vn9Vn9Wm9Xl9Yk9Zj9Zj9[i9\h9]g9^f9_e9_e9`d9ac9bb9ca9ca9d`9e_9f^9g]9h\9h\9i[9jZ9kY9lX9lX9mW9nV9oU9pT9pT9qS9rR9sQ9tP9uO9uO9vN9wM9xL9yK9yK9zJ9{I9|H9}G9~F9~F9E9D9C9B9B9A9@9?9>9>9=9<9;9:999998979695959493929190909/9.9-9,9,9+9*9)9(9(9'9&9%9$9#9#9"9!9 99999999999999999999999 9 9 9 9 9 9 99999999999998765543211 0 / . - , ,+*)(''&%$##"!   !"#$$%&'())*+, - . . / 0 12234567789:: ; ;;<<==#>'>*>-?1?4?7@;@>AA|ADxAGuBJqBMnBPjCSgCVdCYaD\]D_ZDbWEeTEgQEjNFmKFoHFrEFuBGw?Gz<:87531!/#.%,'*))+',%.#0"2 4679;=>@BCE UUUUUUTTTTTTS S"S$S%S'R)R*R,R.~R0|Q1{Q3yQ5xQ7vQ9tP;sPoP@nPBlODjOFiOHgOJeOLcNNaNP`NR^NT\MVZMXXM[VM]TL_RLaPLcNLfLKhJKjHKmFKoDJqBJt@Jv>Jx:?:@:@:A:B:C:D:D:E~:F}:G|:H{:I{:Iz:Jy:Kx:Lw:Mw:Mv:Nu:Ot:Ps:Qr:Rr:Rq:Sp:To:Un:Vn:Vm:Wl:Xk:Yj:Zj:Zi:[h:\g:]f:^e:_e:_d:`c:ab:ba:ca:c`:d_:e^:f]:g\:h\:h[:iZ:jY:kX:lX:lW:mV:nU:oT:pT:pS:qR:rQ:sP:tO:uO:uN:vM:wL:xK:yK:yJ:zI:{H:|G:}F:~F:~E:D:C:B:B:A:@:?:>:>:=:<:;:::9:9:8:7:6:5:5:4:3:2:1:0:0:/:.:-:,:,:+:*:):(:(:':&:%:$:#:#:":!: ::::::::::::::::::::::: : : : : : : :::::::::::::9876554321 1 0 / . - ,,+*)(''&%$##"!   !"#$$%&'())*+,- . . / 0 1 2234567789:;; ; <<===>#>'?*?-?1@4@7A;A>~AA{BDwBGtBJpCMmCPjCSfDVcDY`D\]E_YEbVEeSFgPFjMFmJGoGGrDGuAGw>Hz<:8753 1"/#.%,'*))+'-%/#1"2 468:;=?ABDF VVVUUUUUUTTTT T"T$S%S'S)S*S,R.}R0|R1zR3yR5wQ7uQ9tQ;rQoP@mPBkPDjPFhPHfOJdOLcONaOP_NR]NT[NVYNXXM[VM]TM_RMaPMcNLfLLhJLjHLmFKoDKqBKt?Jv=Jx;J{9J}7I4I2I0I.H+H)H'G$G"GGFFFEEE D DDCCC@<9 630,)%" #&),0 3 6:;;;;;;;;;;; ; ; ; ; ; ;;;;;;;;;;;;;;;;;;;;;;; ;!;!;";#;$;%;&;&;';(;);*;*;+;,;-;.;.;/;0;1;2;3;3;4;5;6;7;7;8;9;:;;;<;<;=;>;?;@;@;A;B;C;D;D~;E};F|;G{;H{;Iz;Iy;Jx;Kw;Lw;Mv;Mu;Nt;Os;Pr;Qr;Rq;Rp;So;Tn;Un;Vm;Vl;Wk;Xj;Yj;Zi;Zh;[g;\f;]e;^e;_d;_c;`b;aa;ba;c`;c_;d^;e];f\;g\;h[;hZ;iY;jX;kX;lW;lV;mU;nT;oT;pS;pR;qQ;rP;sO;tO;uN;uM;vL;wK;xK;yJ;yI;zH;{G;|F;}F;}E;~D;C;B;B;A;@;?;>;>;=;<;;;:;9;9;8;7;6;5;5;4;3;2;1;0;0;/;.;-;,;,;+;*;);(;(;';&;%;$;#;#;";!; ;;;;;;;;;;;;;;;;;;;;;;; ; ; ; ; ; ; ;;;;;;;;;;;;::987655432 1 1 0 / . -,,+*)(''&%$##"!   !"#$$%&'())*+,-. . / 0 1 2 234567789:;;< < ===>>?#?'?*@-@1A4A7A;B>~BAzBDwCGsCJpCMlDPiDSfDVbEY_E\\E_YFbVFeSFgOGjLGmIGoFHrDHuAHw>Hz;I|8I5I3J0J-J*J(K%K#K KLLLLMMM M NNNNNNLJH F DB@><:8753 1"/$.&,(**),'.%/#1"3 578:<>?ACDF VVVVVVUUUUUUT T"T$T%T'S)S*S,~S.}S0{S1zR3xR5wR7uR9sR;rQnQ@mQBkQDiPFgPHfPJdPLbON`OP^OR]OT[OVYNXWN[UN]SN_QMaOMcMMfKMhILjGLmELoCLqAKt?Kv=Kx:K{8J}6J4J2J/I-I+I(H&H$H!GGGGFFFE E EDDDC@=9 630,)%" $'*-1 4 7;<<<<<<<<<<< < < < < < <<<<<<<<<<<<<<<<<<<<<<< <><=<<<;<:<9<9<8<7<6<5<5<4<3<2<1<0<0>???#@'@*A-A1A4B7B;B>}CAyCDvCGrDJoDMlDPhESeEVbEY^F\[F_XFbUGeRGgOGjLHmIHoFHrCHu@Iw=Iz:I|7J5J2J/J,K*K'K%K"LLLLMMMMN N NNOOONLJH F DB@><:8753!1#/%.',(**),'.%0#2"4 579;<>@BCEG WWWVVVVVVUUUU U"U$T%T'T)T*T,~S.|S0{S1yS3xS5vS7tR9sR;qRnR@lQBjQDiQFgQHePJcPLaPN`PP^PR\OTZOVXOXVO[TN]SN_QNaONcMNfKMhIMjGMlDMoBLq@Lt>Lv=?=@=@=A=B=C~=D}=D|=E{=F{=Gz=Hy=Ix=Iw=Jw=Kv=Lu=Mt=Ms=Nr=Or=Pq=Qp=Qo=Rn=Sn=Tm=Ul=Vk=Vj=Wj=Xi=Yh=Zg=Zf=[e=\e=]d=^c=_b=_a=`a=a`=b_=c^=c]=d\=e\=f[=gZ=gY=hX=iX=jW=kV=lU=lT=mT=nS=oR=pQ=pP=qO=rO=sN=tM=uL=uK=vK=wJ=xI=yH=yG=zF={F=|E=}D=}C=~B=B=A=@=?=>=>===<=;=:=9=9=8=7=6=5=5=4=3=2=1=0=0=/=.=-=,=,=+=*=)=(=(='=&=%=$=#=#="=!= ======================= = = = = = = ============<;::9876554 3 2 1 1 0 /.-,,+*)(''&%$##"!   !"#$$%&'())*+,-../ 0 1 2 2 3 4567789:;<<== > >???@@#A'A*A-B1B4B7C;C>|DAyDDuDGrEJnEMkEPhFSdFVaFY^F\[G_WGbTGeQHgNHjKHmHIoEIrBIu?Iw<:8753!1#/%.',)*+)-'/%0#2"4 689;=?@BDEG WWWWWWVVVVVVU U"U$U%U'U)T*T,}T.|T0zT1yS3wS5uS7tS9rS;pRmR@kRBjRDhQFfQHdQJcQLaQN_PP]PR[PTZPVXPXVO[TO]RO_POaNNcLNfJNhHNjFMlDMoBMq@Mt>Lv;Lx9L{7L}5K3K0K.K,J)J'J%I"I IIHHHGGG F FFEEC@= 9 630,)&""%(+/2 5 9<>>>>>>>>>>> > > > > > >>>>>>>>>>>>>>>>>>>>>>> >!>!>">#>$>%>%>&>'>(>)>*>*>+>,>->.>.>/>0>1>2>3>3>4>5>6>7>7>8>9>:>;>;><>=>>>?>@>@>A>B~>C}>D|>D{>E{>Fz>Gy>Hx>Iw>Iw>Jv>Ku>Lt>Ms>Mr>Nr>Oq>Pp>Qo>Qn>Rn>Sm>Tl>Uk>Vj>Vj>Wi>Xh>Yg>Zf>Ze>[e>\d>]c>^b>_a>_a>``>a_>b^>c]>c\>d\>e[>fZ>gY>gX>hX>iW>jV>kU>lT>lT>mS>nR>oQ>pP>pO>qO>rN>sM>tL>uK>uK>vJ>wI>xH>yG>yF>zF>{E>|D>}C>}B>~B>A>@>?>>>>>=><>;>:>9>9>8>7>6>5>5>4>3>2>1>0>0>/>.>->,>,>+>*>)>(>(>'>&>%>$>#>#>">!> >>>>>>>>>>>>>>>>>>>>>>> > > > > > > >>>>>>>>>>>>=<;::987655 4 3 2 1 1 0/.-,,+*)(''&%$##"!   !"#$$%&'())*+,-../0 1 2 2 3 4 567789:;<<=>> ? ??@@AA#A'B*B-C1C4C7D;D>{DAxEDtEGqEJmFMjFPgFSdGV`GY]G\ZG_WHbTHePHgMIjJImGIoDJrBJu?Jw<:875 3"1$/&.(,**+)-'/%1#3"5 68:<=?ACDFH XXXWWWWWWVVVV V"V$U%U'U)U*~U,}U.{T0zT1xT3vT5uT7sS9rS:pSmS@kRBiRDgRFfRHdRJbQL`QN_QP]QR[QTYPVWPXUP[SP]QO_OOaMOcKOfIOhGNjENlCNoANq?Mt=Mv;Mx9M{6L}4L2L0K-K+K)K&J$J"JJIIIHHH G GGGFFC@= 9 630,)&"#&),03 6 :=>>>>>>>>>>> > > > > > >>>>>>>>>>>>>>>>>>>>>>> >!>!>">#>$>%>%>&>'>(>)>*>*>+>,>->.>.>/>0>1>2>3>3>4>5>6>7>7>8>9>:>;>;><>=>>>?>@>@>A~>B}>C|>D{>D{>Ez>Fy>Gx>Hw>Iw>Iv>Ju>Kt>Ls>Mr>Mr>Nq>Op>Po>Qn>Qn>Rm>Sl>Tk>Uj>Vj>Vi>Wh>Xg>Yf>Ze>Ze>[d>\c>]b>^a>^a>_`>`_>a^>b]>c\>c\>d[>eZ>fY>gX>gX>hW>iV>jU>kT>lT>lS>mR>nQ>oP>pO>pO>qN>rM>sL>tK>tK>uJ>vI>wH>xG>yF>yF>zE>{D>|C>}B>}B>~A>@>?>>>>>=><>;>:>9>9>8>7>6>5>5>4>3>2>1>0>0>/>.>->,>,>+>*>)>(>(>'>&>%>$>#>#>">!> >>>>>>>>>>>>>>>>>>>>>>> > > > > > > >>>>>>>>>>>>>=<;::98765 5 4 3 2 1 10/.-,,+*)(''&%$##"!   !"#$$%&'())*+,-../01 2 2 3 4 5 67789:;<<=>?? ? @@AAAB#B'C*C-C1D4D7D;~E>{EAwEDtFGpFJmFMiGPfGScGV`HY\H\YH_VHbSIePIgMIjJJmGJoDJrAKu>Kw;Kz8K|5L3L0L-L+M(M%M#M NNNNOOOO P PPPPQPNLJ H FDB@><:875 3"1$/&.(,**,).'0%1#3"5 79:<>@ACEFH XXXXXXXWWWWWW V"V$V%V'V)U*~U,|U.{U0yU1xU3vT5tT7sT9qT:oTlS@jSBiSDgSFeRHcRJbRL`RN^RP\QRZQTXQVVQXUQ[SP]QP_OPaMPcKOfIOhGOjEOlCNoANq>Nt??????????? ? ? ? ? ? ??????????????????????? ?!?!?"?#?$?%?%?&?'?(?)?*?*?+?,?-?.?.?/?0?1?2?2?3?4?5?6?7?7?8?9?:?;?;????@?@~?A}?B|?C{?D{?Dz?Ey?Fx?Gw?Hw?Hv?Iu?Jt?Ks?Lr?Mr?Mq?Np?Oo?Pn?Qn?Qm?Rl?Sk?Tj?Uj?Vi?Vh?Wg?Xf?Ye?Ze?Zd?[c?\b?]a?^a?^`?__?`^?a]?b\?c\?c[?dZ?eY?fX?gX?gW?hV?iU?jT?kT?lS?lR?mQ?nP?oO?pO?pN?qM?rL?sK?tK?tJ?uI?vH?wG?xF?yF?yE?zD?{C?|B?}B?}A?~@???>?>?=?=<;::9876 5 5 4 3 2 110/.-,,+*)(''&%$##"!  !"#$$%&'())*+,-../012 2 3 4 5 6 7789:;<<=>??@ @ AAABBC#C'C*D-D1D4E7E;}E>zFAvFDsFGoGJlGMiGPeHSbHV_HY\I\XI_UIbRIeOJgLJjIJmFKoCKr@Ku=Kw:Lz8L|5L2M/M-M*M'N%N"NNOOOOOPP P PQQQQPNLJ H FDB@><:875!3#1%/'.),+*,).'0%2#4"6 79;=>@BDEGI YYYXXXXXXXWWW W"W$W%V'V)V*}V,|V.zU0yU1wU3uU5tU7rU9pT:oTkT@jTBhSDfSFeSHcSJaSL_RN]RP\RRZRTXRVVQXTQ[RQ]PQ_NPaLPcJPfHPhFPjDOlBOo@Oq>Ot@?@@~@@}@A|@B{@C{@Dz@Dy@Ex@Fw@Gw@Hv@Hu@It@Js@Kr@Lr@Mq@Mp@No@On@Pn@Qm@Ql@Rk@Sj@Tj@Ui@Vh@Vg@Wf@Xe@Ye@Zd@Zc@[b@\a@]a@^`@^_@_^@`]@a\@b\@c[@cZ@dY@eX@fX@gW@gV@hU@iT@jT@kS@lR@lQ@mP@nO@oO@pN@pM@qL@rK@sK@tJ@tI@uH@vG@wF@xF@yE@yD@zC@{B@|B@}A@}@@~?@>@>@=@<@;@:@9@9@8@7@6@5@5@4@3@2@1@0@0@/@.@-@,@,@+@*@)@(@(@'@&@%@$@#@#@"@!@ @@@@@@@@@@@@@@@@@@@@@@@ @ @ @ @ @ @ @@@@@@@@@@@@??>=<;::987 6 5 5 4 3 2110/.-,,+*)(''&%$##"! !"#$$%&'())*+,-../0123 3 4 5 6 7 789:;<<=>?@@A A ABBCCC#D'D*D-E1E4E7F;}F>yFAvGDrGGoGJkHMhHPeHSaIV^IY[I\XJ_UJbQJeNJgKKjHKmEKoBLr@Lu=Lw:Lz7M|4M1M/M,N)N'N$N!OOOOPPPP Q Q QQQRRPNL J H FDB@><:87 5!3#1%/'.),+*-)/'1%3#4"6 8:<=?ABDFGI YYYYYYYXXXXXX W"W$W%W'W)~W*}V,{V.zV0xV1vV3uU5sU7rU9pU:nUkT@iTBgTDfTFdTHbSJ`SL_SN]SP[SRYRTWRVURXSR[QR]PQ_NQaLQcJQfHPhFPjCPlAPo?Oq=Ot;Ov9Ox7N{4N}2N0N.M+M)M'M$L"L LLKKKJJJ JIIIHFC@ = :630,)&""%(+/25 9 <?AAAAAAAAAAA A A A A A AAAAAAAAAAAAAAAAAAAAAAA A!A!A"A#A$A%A%A&A'A(A)A*A*A+A,A-A.A.A/A0A1A2A2A3A4A5A6A7A7A8A9A:A;A;AA?~A@}A@|AA{AB{ACzADyADxAEwAFwAGvAHuAHtAIsAJrAKrALqAMpAMoANnAOnAPmAQlAQkARjASjATiAUhAVgAVfAWeAXeAYdAZcAZbA[aA\aA]`A^_A^^A_]A`\Aa\Ab[AcZAcYAdXAeXAfWAgVAgUAhTAiTAjSAkRAlQAlPAmOAnOAoNApMApLAqKArKAsJAtIAtHAuGAvFAwFAxEAyDAyCAzBA{BA|AA}@A}?A~>A>A=A=<;::98 7 6 5 5 4 32110/.-,,+*)(''&%$##" ! !"#$$%&'())*+,-../01233 4 5 6 7 7 89:;<<=>?@AAB B BCCCDD#E'E*E-F1F4F7G;|G>xGAuHDqHGnHJkHMgIPdISaIV]JYZJ\WJ_TKbQKeNKgKKjHLmELoBLr?Mu<:87 5"3$1&/(.*,,*.)/'1%3#5"7 9:<>@ACEFHJ ZZZZYYYYYYXXX X"X$X%W'W)~W*|W,{W.yW0xV1vV3tV5sV7qV9oV:nUjU@iUBgUDeTFcTHbTJ`TL^TN\SPZSRXSTWSVUSXSRZQR]OR_MRaKQcIQfGQhEQjCQlAPo?Pq=Ps:Pv8Ox6O{4O}2O/N-N+N(N&M$M!MMLLLKKK K JJJIIFC@ = :630,)&""&),/36 9 =@BBBBBBBBBBB B B B B B BBBBBBBBBBBBBBBBBBBBBBB B!B!B"B#B$B%B%B&B'B(B)B*B*B+B,B-B.B.B/B0B1B2B2B3B4B5B6B7B7B8B9B:B;B;B~B?}B@|B@{BA{BBzBCyBDxBDwBEwBFvBGuBHtBHsBIrBJrBKqBLpBMoBMnBNnBOmBPlBQkBQjBRjBSiBThBUgBUfBVeBWeBXdBYcBZbBZaB[aB\`B]_B^^B^]B_\B`\Ba[BbZBcYBcXBdXBeWBfVBgUBgTBhTBiSBjRBkQBkPBlOBmOBnNBoMBpLBpKBqKBrJBsIBtHBtGBuFBvFBwEBxDByCByBBzBB{AB|@B}?B}>B~>B=B=<;::9 8 7 6 5 5 432110/.-,,+*)(''&%$## " !! "#$$%&'())*+,-../012334 5 6 7 7 8 9:;<<=>?@AABB C CCDDEE#E'F*F-F1G4G7G;{H>xHAtHDqIGmIJjIMgJPcJS`JV]JYYK\VK_SKbPLeMLgJLjGLmDMoAMr>Mu;Mw8Nz6N|3N0N-O+O(O%O#P PPPQQQQR R RRRSSRPNL J HFDB@><:87!5#3%1&/(.*,,*.)0'2%4#5"7 9;=>@BCEGHJ Z ZZZZZZYYYYYY X"X$X%X'X)}X*|W,zW.yW0wW1uW3tW5rV7pV9oV:mVjV@hUBfUDeUFcUHaUJ_TL]TN\TPZTRXTTVSVTSXRSZPS]NS_LRaJRcHRfFRhDQjBQl@Qo>Qq}C?|C?{C@{CAzCByCCxCDwCDwCEvCFuCGtCHsCHrCIrCJqCKpCLoCMnCMnCNmCOlCPkCQjCQjCRiCShCTgCUfCUeCVeCWdCXcCYbCZaCZaC[`C\_C]^C^]C^\C_\C`[CaZCbYCcXCcXCdWCeVCfUCgTCgTChSCiRCjQCkPCkOClOCmNCnMCoLCpKCpKCqJCrICsHCtGCtFCuFCvECwDCxCCyBCyBCzAC{@C|?C}>C}>C~=C=<;:: 9 8 7 6 5 5432110/.-,,+*)(''&%$# # "!!" #$$%&'())*+,-../0123345 6 7 7 8 9 :;<<=>?@AABCC D DDEEEF#F'F*G-G1G4H7~H;zH>wIAsIDpIGmJJiJMfJPbKS_KV\KYYK\VL_RLbOLeLMgIMjFMmCMo@Nr=Nu;Nw8Nz5O|2O/O-O*P'P%P"PQQQQQRRR R SSSSSRPNL J HFDB@><:87!5#3%1'/).+,-*/)0'2%4#6"8 :;=?ABDFGIK [ [[[ZZZZZZYYY Y"Y$Y%Y'~X)}X*{X,zX.xX0vX1uW3sW5rW7pW9nW:mViV@hVBfVDdVFbUH`UJ_UL]UN[UPYTRWTTUTVTTXRTZPS]NS_LSaJScHRfFRhDRjBRl@Ro=Qq;Qs9Qv7Qx5P{3P}0P.P,O)O'O%O"N NNNMMMML L LKKKIFC @ =:630-)!&$"'*.147 ; >BCCCCCCCCCCC C C C C C CCCCCCCCCCCCCCCCCCCCCCC C!C!C"C#C$C%C%C&C'C(C)C)C*C+C,C-C.C.C/C0C1C2C2C3C4C5C6C7C7C8C9C:C;C;C<~C=}C>|C?{C?{C@zCAyCBxCCwCDwCDvCEuCFtCGsCHrCHrCIqCJpCKoCLnCMnCMmCNlCOkCPjCQjCQiCRhCSgCTfCUeCUeCVdCWcCXbCYaCZaCZ`C[_C\^C]]C^\C^\C_[C`ZCaYCbXCcXCcWCdVCeUCfTCgTCgSChRCiQCjPCkOCkOClNCmMCnLCoKCpKCpJCqICrHCsGCtFCtFCuECvDCwCCxBCyBCyACz@C{?C|>C}>C}=C~=<;: : 9 8 7 6 55432110/.-,,+*)(''&%$ # #!""!# $$%&'())*+,-../01233456 7 7 8 9 : ;<<=>?@AABCDD D EEEFFG#G'G*H-H1H4I7}I;zI>vIAsJDoJGlJJhKMeKPbKS_LV[LYXL\UL_RMbOMeLMgIMjFNmCNo@Nr=Ou:Ow7Oz4O|2P/P,P)P'Q$Q!QQQRRRRS S S SSTTTRPN L J HFDB@><:8 7"5$3&1(/*.+,-*/)1'3%5#7"8 :<>?ACDFHIK [ [[[[[[ZZZZZZ Z"Y$Y%Y'~Y)|Y*{Y,yX.wX0vX1tX3sX5qX7oW9nW:lWiW@gVBeVDcVFbVH`VJ^VL\UNZUPYURWUTUUVSTXQTZOT]MT_KTaIScGSeEShCSjARl?Ro=Rq;Rs8Rv6Qx4Q{2Q}0Q-P+P)P&P$O"OOONNNNMM MLLLLIFC @ =:630-)"&%"(+.258 < ?CDDDDDDDDDDD D D D D D DDDDDDDDDDDDDDDDDDDDDDD D!D!D"D#D$D%D%D&D'D(D)D)D*D+D,D-D.D.D/D0D1D2D2D3D4D5D6D7D7D8D9D:D;D;~D<}D=|D>{D?{D?zD@yDAxDBwDCwDDvDDuDEtDFsDGrDHrDHqDIpDJoDKnDLnDMmDMlDNkDOjDPjDQiDQhDRgDSfDTeDUeDUdDVcDWbDXaDYaDZ`DZ_D[^D\]D]\D^\D^[D_ZD`YDaXDbXDcWDcVDdUDeTDfTDgSDgRDhQDiPDjODkODkNDlMDmLDnKDoKDpJDpIDqHDrGDsFDtFDtEDuDDvCDwBDxBDyADy@Dz?D{>D|>D}=D}=<; : : 9 8 7 655432110/.-,,+*)(''&% $ #!#""#!$ $%&'())*+,-../012334567 7 8 9 : ; <<=>?@AABCDDE E FFFGGG#H'H*H-I1I4I7}J;yJ>uJArKDnKGkKJhKMdLPaLS^LV[MYWM\TM_QMbNNeKNgHNjENmBOo?Or<:8 7"5$3&1(/*.,,.*0)2'3%5#7"9 ;<>@BCEGHJL \ \\\[[[[[[[ZZ Z"Z$Z%Z'}Y)|Y*zY,yY.wY0uY1tX3rX5pX7oX9mX:lXhW@fWBeWDcWFaWH_VJ^VL\VNZVPXVRVUTTUVRUXPUZNU]MT_KTaITcGTeEThBSj@Sl>So{E?zE?yE@xEAwEBwECvEDuEDtEEsEFrEGrEHqEHpEIoEJnEKnELmELlEMkENjEOjEPiEQhEQgERfESeETeEUdEUcEVbEWaEXaEY`EZ_EZ^E[]E\\E]\E^[E^ZE_YE`XEaXEbWEbVEcUEdTEeTEfSEgREgQEhPEiOEjOEkNEkMElLEmKEnKEoJEpIEpHEqGErFEsFEtEEtDEuCEvBEwBExAEx@Ey?Ez>E{>E|=E}=< ; : : 9 8 7655432110/.-,,+*)(''& % $!#"##"$!$ %&'())*+,-../0123345677 8 9 : ; < <=>?@AABCDEEF F FGGGHH#H'I*I-I1J4J7|J;xK>uKAqKDnLGjLJgLMdLP`MS]MVZMYWN\TN_PNbMNeJOgGOjDOmAOo>Pr;Pu9Pw6Pz3Q|0Q-Q+Q(R%R#R RRSSSSTT T TTUUUTRPN L JHFDB@><:8!7#5%3'1)/+.-,.*0)2'4%6#8"9 ;=?@BDEGIJL \ \\\\\\[[[[[[ ["Z$Z%~Z'}Z){Z*zZ,xY.vY0uY1sY3rY5pY7nX9mX:kXhX@fXBdWDbWFaWH_WJ]WL[WNYVPWVRVVTTVVRVXPUZNU]LU_JUaHUcFTeDThBTj@Tl>SozF?yF?xF@wFAwFBvFCuFDtFDsFErFFrFGqFHpFHoFInFJnFKmFLlFLkFMjFNjFOiFPhFQgFQfFReFSeFTdFUcFUbFVaFWaFX`FY_FZ^FZ]F[\F\\F][F^ZF^YF_XF`XFaWFbVFbUFcTFdTFeSFfRFgQFgPFhOFiOFjNFkMFkLFlKFmKFnJFoIFpHFpGFqFFrFFsEFtDFtCFuBFvBFwAFx@Fx?Fy>Fz>F{=F|= < ; : : 9 87655432110/.-,,+*)('' & %!$"###$"$!% &'())*+,-../01233456778 9 : ; < < =>?@AABCDEEFF G GGHHII#I'J*J-J1J4K7{K;wK>tLApLDmLGjMJfMMcMP`MS\NVYNYVN\SO_PObMOeJOgGPjDPmAPo>Pr;Qu8Qw5Qz2Q|0R-R*R'R%R"SSSSTTTTT U UUUUVTRPN L JHFDB@><:8!7#5%3'1)/+.-,/*1)3'4%6#8": <=?ACDFHIKM ] ]]]\\\\\\\[[ ["[#[%~['|[){Z*yZ,wZ.vZ0tZ1sZ3qY5oY7nY9lY:jYgX@eXBdXDbXF`XH^WJ\WL[WNYWPWWRUWTSVVQVXOVZMV]KV_IUaGUcEUeCUhAUj?Tl=To;Tq9Ts7Sv4Sx2S{0S}.S+R)R'R$R"Q QQQPPPPO O OONNLIF C @=:730-!)$&'"*-147; > AEGGGGGGGGGGG G G G G G GGGGGGGGGGGGGGGGGGGGGGG G G!G"G#G$G%G%G&G'G(G)G)G*G+G,G-G.G.G/G0G1G2G2G3G4G5G6G6G7G8G9~G:}G;|G;{G<{G=zG>yG?xG?wG@wGAvGBuGCtGDsGDrGErGFqGGpGHoGHnGInGJmGKlGLkGLjGMjGNiGOhGPgGQfGQeGReGSdGTcGUbGUaGVaGW`GX_GY^GZ]GZ\G[\G\[G]ZG^YG^XG_XG`WGaVGbUGbTGcTGdSGeRGfQGgPGgOGhOGiNGjMGkLGkKGlKGmJGnIGoHGpGGpFGqFGrEGsDGtCGtBGuBGvAGw@Gx?Gx>Gy>Gz=G{ = < ; : : 987655432110/.-,,+*)(' ' &!%"$##$#$"%!& '())*+,-../012334567789 : ; < < = >?@AABCDEEFGG H HHIIIJ#J'J*K-K1K4~L7zL;wL>sLApMDlMGiMJfNMbNP_NS\NVXOYUO\RO_OObLPeIPgFPjCPm@Qo=Qr:Qu7Qw4Rz2R|/R,R)S'S$S!STTTTTUU U UUVVVVTRP N L JHFDB@><: 8"7$5&3(1*/,..,/*1)3'5%7#9": <>@ACEGHJLM ] ]]]]]]]\\\\\ \"\#[%}['|[)z[*y[,w[.uZ/tZ1rZ3pZ5oZ7mZ9lY:jYfY@eYBcYDaXF_XH^XJ\XLZXNXXPVWRTWTSWVQWXOWZMV]KV_IVaGVcEVeCUhAUj?UlxH?wH?wH@vHAuHBtHCsHDrHDrHEqHFpHGoHHnHHnHImHJlHKkHLjHLjHMiHNhHOgHPfHQeHQeHRdHScHTbHUaHUaHV`HW_HX^HY]HZ\HZ\H[[H\ZH]YH^XH^XH_WH`VHaUHbTHbTHcSHdRHeQHfPHgOHgOHhNHiMHjLHkKHkKHlJHmIHnHHoGHpFHpFHqEHrDHsCHtBHtBHuAHv@Hw?Hx>Hx>Hy=Hz = < ; : :987655432110/.-,,+*)( ' '!&"%#$$#$#%"&!' ())*+,-../012334567789: ; < < = > ?@AABCDEEFGHH H IIIJJJ#K'K*K-L1L4}L7zM;vM>rMAoMDlNGhNJeNMaOP^OS[OVXOYUP\QP_NPbKPeHQgEQjBQm?Qo<:!8#7%5&3(1*/,..,0*2)4'6%7#9"; =>@BDEGIJLN ^ ^^^]]]]]]]\\ \"\#~\%}\'{\)z[*x[,v[.u[/s[1r[3pZ5nZ7mZ9kZ:iZfZ@dYBbYDaYF_YH]YJ[XLYXNXXPVXRTXTRXVPWXNWZLW]JW_HWaFVcDVeBVh@Vj>VlwH?wH?vH@uHAtHBsHCrHCrHDqHEpHFoHGnHHnHHmHIlHJkHKjHLjHLiHMhHNgHOfHPeHQeHQdHRcHSbHTaHUaHU`HV_HW^HX]HY\HY\HZ[H[ZH\YH]XH^XH^WH_VH`UHaTHbTHbSHcRHdQHePHfOHgOHgNHhMHiLHjKHkKHkJHlIHmHHnGHoFHoFHpEHqDHrCHsBHtBHtAHu@Hv?Hw>Hx>Hx=Hy = < ; ::987655432110/.-,,+*) ( '!'"&#%$$%#%#&"'!( ))*+,-../012334567789:; < < = > ? @AABCDEEFGHII I JJJKKK#L'L*L-L1M4|M7yM;uN>rNAnNDkNGgOJdOMaOP]PSZPVWPYTP\QQ_NQbKQeGQgDRjBRm?Ro<:!8#7%5'3)1+/-./,1*2)4'6%8#:"; =?ABDFHIKMN ^ ^^^^^^^]]]]] ]"]#~\%|\'{\)y\*w\,v\.t\/s[1q[3o[5n[7l[8j[:iZeZ@dZBbZD`ZF^YH\YJ[YLYYNWYPUYRSXTQXVOXXMXZLX]JW_HWaFWcDWeAWh?Vj=Vl;Vo9Vq7Vs5Uv3Ux0U{.U},U*T'T%T#T SSSSRRRR Q QQQPOLIF C@=:730 -#)&&)#,0369= @ DGIIIIIIIIIII I I I I I IIIIIIIIIIIIIIIIIIIIIII I I!I"I#I$I%I%I&I'I(I)I)I*I+I,I-I-I.I/I0I1I2I2I3I4I5I6I6~I7}I8|I9{I:{I;zI;yIwI?vI?uI@tIAsIBrICrICqIDpIEoIFnIGnIHmIHlIIkIJjIKjILiILhIMgINfIOeIPeIQdIQcIRbISaITaIU`IU_IV^IW]IX\IY\IY[IZZI[YI\XI]XI^WI^VI_UI`TIaTIbSIbRIcQIdPIeOIfOIgNIgMIhLIiKIjKIkJIkIIlHImGInFIoFIoEIpDIqCIrBIsBItAIt@Iu?Iv>Iw>Ix=Ix = < ;::987655432110/.-,,+* ) (!'"'#&$%%$%#&#'"(!) )*+,-../012334567789:;< < = > ? @ AABCDEEFGHIIJ J JKKKLL#L'M*M-M1N4|N7xN;tN>qOAnODjOGgOJcPM`PP]PSZQVVQYSQ\PQ_MRbJReGRgDRjASm>So;Sr8Su5Sw2Tz0T|-T*T'U%U"U UUVVVVVW W WWWXXVTRP N LJHFDB@>< :"8$7&5(3*1+/-./,1*3)5'7%8#:"< >@ACEFHJKMO _ ___^^^^^^^^] ]"]#}]%|]'z])x]*w\,u\.t\/r\1p\3o\5m[7l[8j[:h[e[@cZBaZD_ZF^ZH\ZJZZLXYNVYPUYRSYTQYVOYXMXZKX]IX_GXaEXcCWeAWh?Wj=Wl;Wo8Vq6Vs4Vv2Vx0V{-U}+U)U'U$U"TTTTSSSSR R RRQQOMI F C@=:730!-$*'&*#-047:> A DHJJJJJJJJJJJ J J J J J JJJJJJJJJJJJJJJJJJJJJJJ J J!J"J#J$J%J%J&J'J(J)J)J*J+J,J-J-J.J/J0J1J2J2J3J4J5J6~J6}J7|J8{J9{J:zJ;yJ;xJvJ?uJ?tJ@sJArJBrJCqJCpJDoJEnJFnJGmJHlJHkJIjJJjJKiJLhJLgJMfJNeJOeJPdJQcJQbJRaJSaJT`JU_JU^JV]JW\JX\JY[JYZJZYJ[XJ\XJ]WJ^VJ^UJ_TJ`TJaSJbRJbQJcPJdOJeOJfNJgMJgLJhKJiKJjJJkIJkHJlGJmFJnFJoEJoDJpCJqBJrBJsAJt@Jt?Ju>Jv>Jw=Jx = <;::987655432110/.-,,+ * )!("'#'$&%%%$&#'#(")!) *+,-../012334567789:;<< = > ? @ A ABCDEEFGHIJJK K KLLLLM#M'M*N-N1~N4{O7wO;tO>pOAmPDiPGfPJcPM_QP\QSYQVVRYRR\OR_LRbISeFSgCSj@Sm=So:Tr7Tu5Tw2Tz/U|,U*U'U$U!VVVVVWWW W WXXXXXVTR P N LJHFDB@>< :"8$7&5(3*1,/..0,2*4)5'7%9#;"= >@BDEGIJLNO _ _______^^^^^ ^"~^#}]%{]'y])x]*v],u].s]/r\1p\3n\5m\7k\8i\:h\d[@b[Ba[D_[F][H[ZJZZLXZNVZPTZRRZTPYVNYXLYZJY]HY_FXaDXcBXe@Xh>Xj B EIKKKKKKKKKKK K K K K K KKKKKKKKKKKKKKKKKKKKKKK K K!K"K#K$K%K%K&K'K(K)K)K*K+K,K-K-K.K/K0K1K2K2K3K4K5~K6}K6|K7{K8{K9zK:yK;xK;wKuK?tK?sK@rKArKBqKCpKCoKDnKEnKFmKGlKHkKHjKIjKJiKKhKLgKLfKMeKNeKOdKPcKQbKQaKRaKS`KT_KU^KU]KV\KW\KX[KYZKYYKZXK[XK\WK]VK^UK^TK_TK`SKaRKbQKbPKcOKdOKeNKfMKgLKgKKhKKiJKjIKkHKkGKlFKmFKnEKoDKoCKpBKqBKrAKs@Kt?Kt>Ku>Kv=Kw =<;::987655432110/.-,, + *!)"(#'$'%&%%&$'#(#)")!* +,-../012334567789:;<<= > ? @ A A BCDEEFGHIJJKK L LLMMMN#N'N*N-O1~O4zO7wP;sP>oPAlPDiQGeQJbQM_QP[RSXRVURYRR\OS_LSbHSeESgBTj?Tm=To:Tr7Uu4Uw1Uz.U|,U)V&V#V!VWWWWWXX X XXXYYXVTR P NLJHFDB@>d\@b\B`[D^[F][H[[JY[LW[NUZPSZRQZTPZVNZXLZZJY]HY_FYaDYcBYe@Xh>Xj;Xl9Xo7Xq5Xs3Wv1Wx.W{,W}*W(V%V#V!VUUUUUTT T TSSSRPMJ G C@=:740"-%*(&+#/258<? C FJLLLLLLLLLLL L L L L L LLLLLLLLLLLLLLLLLLLLLLL L L!L"L#L$L%L%L&L'L(L)L)L*L+L,L-L-L.L/L0L1L2L2L3L4~L5}L6|L6{L7{L8zL9yL:xL:wL;wLtL?sL?rL@rLAqLBpLCoLCnLDnLEmLFlLGkLHjLHjLIiLJhLKgLLfLLeLMeLNdLOcLPbLPaLQaLR`LS_LT^LU]LU\LV\LW[LXZLYYLYXLZXL[WL\VL]UL^TL^TL_SL`RLaQLbPLbOLcOLdNLeMLfLLfKLgKLhJLiILjHLkGLkFLlFLmELnDLoCLoBLpBLqALr@Ls?Lt>Lt>Lu=Lv=<;::987655432110/.-, , +!*")#($'%'%&&%'$(#)#)"*!+ ,-../012334567789:;<<=> ? @ A A B CDEEFGHIJJKLL L MMMNNN#O'O*O-O1}P4yP7vP;rQ>oQAkQDhQGdRJaRM^RP[RSWSVTSYQS\NS_KTbHTeETgBTj?Um ?ACEFHJKMOP a ```````_____ _"}_#|_%z^'x^(w^*u^,t^.r^/p^1o]3m]5l]7j]8h]:g]c\@a\B`\D^\F\\HZ\JX[LW[NU[PS[RQ[TO[VMZXKZZIZ\GZ_EZaCYcAYe?Yh=Yj;Yl9Yo7Xq4Xs2Xv0Xx.X{,W})W'W%W"W VVVVUUUU U TTTTSPMJ GC@=:74 0#-&*)&,#/369<@ C GJLLLLLLLLLLL L L L L L LLLLLLLLLLLLLLLLLLLLLLL L L!L"L#L$L$L%L&L'L(L)L)L*L+L,L-L-L.L/L0L1L2L2L3~L4}L5|L6{L6{L7zL8yL9xL:wL:wL;vLsL?rL?rL@qLApLBoLCnLCnLDmLElLFkLGjLHjLHiLIhLJgLKfLLeLLeLMdLNcLObLPaLPaLQ`LR_LS^LT]LU\LU\LV[LWZLXYLYXLYXLZWL[VL\UL]TL^TL^SL_RL`QLaPLbOLbOLcNLdMLeLLfKLfKLgJLhILiHLjGLkFLkFLlELmDLnCLoBLoBLpALq@Lr?Ls>Lt>Lt=Lu=<;::987655432110/.- , ,!+"*#)$(%'%'&&'%($)#)#*"+!, -../012334567789:;<<=>? @ A A B C DEEFGHIJJKLMM M NNNOOO#O'P*P-P1|Q4yQ7uQ;qQ>nRAkRDgRGdRJ`SM]SPZSSWSVSTYPT\MT_JTbGUeDUgAUj>Um;Uo8Vr5Vu3Vw0Vz-W|*W(W%W"W XXXXXYYY Y YZZZZXVT R P NLJHFDB@> <":$8&7(5*3,1./0.1,3*5)7'9%;#<"> @BCEGHJLMOQ a aaaa```````_ ~_"}_#{_%y_'x_(v_*u_,s^.r^/p^1n^3m^5k^7i^8h]:f]c]@a]B_]D]\F[\HZ\JX\LV\NT\PR[RP[TN[VL[XK[ZI[\GZ_EZaCZc@Ze>ZhrM?rM?qM@pMAoMBnMCnMCmMDlMEkMFjMGjMHiMHhMIgMJfMKeMLeMLdMMcMNbMOaMPaMP`MQ_MR^MS]MT\MU\MU[MVZMWYMXXMYXMYWMZVM[UM\TM]TM^SM^RM_QM`PMaOMbOMbNMcMMdLMeKMfKMfJMgIMhHMiGMjFMkFMkEMlDMmCMnBMoBMoAMp@Mq?Mr>Ms>Mt=Mt=<;::987655432110/. - ,!,"+#*$)%(%'&''&(%)$)#*#+",!- ../012334567789:;<<=>?@ A A B C D EEFGHIJJKLMMN N NOOOPP#P'P*Q-Q1{Q4xR7tR;qR>mRAjSDfSGcSJ`SM\TPYTSVTVSTYPU\LU_IUbFUeCVg@Vj=Vm;Vo8Vr5Wu2Ww/Wz,W|*W'X$X"XXXYYYYY Z ZZZZZZXVT R PNLJHFDB@> <#:$8&7(5*3,1./0.2,4*6)7'9%;#="? @BDFGIKLNPQ b aaaaaaaa```` ~`"|`#z`%y_'w_(v_*t_,s_.q_/o_1n_3l^5j^7i^8g^:e^b^@`]B^]D]]F[]HY]JW]LU\NT\PR\RP\TN\VL\XJ[ZH[\F[_D[aB[c@[e>ZhA E HLNNNNNNNNNNN N N N N N NNNNNNNNNNNNNNNNNNNNNNN N N!N"N#N$N$N%N&N'N(N)N)N*N+N,N-N-N.N/N0N1N2~N2}N3|N4{N5{N6zN6yN7xN8wN9wN:vN:uN;tNrN?qN?pN@oNAnNBnNCmNClNDkNEjNFiNGiNHhNHgNIfNJeNKeNLdNLcNMbNNaNOaNP`NP_NQ^NR]NS\NT\NU[NUZNVYNWXNXXNYWNYVNZUN[TN\TN]SN^RN^QN_PN`ONaONbNNbMNcLNdKNeKNfJNfINgHNhGNiFNjFNkENkDNlCNmBNnBNoANo@Np?Nq>Nr>Ns=Nt=<;::987655432110/ . -!,",#+$*%)%(&'''(&)%)$*#+#,"-!. ./012334567789:;<<=>?@A A B C D E EFGHIJJKLMNNO O OPPPPQ#Q'Q*R-~R1{R4wR7tS;pS>mSAiSDfTGbTJ_TM\TPXUSUUVRUYOU\LV_IVbFVeCVg@Vj=Wm:Wo7Wr4Wu1Ww.Xz,X|)X&X$Y!YYYYYZZZ Z Z[[[[ZXVT R PNLJHFDB@>!<#:%8'7)5+3-1//1.3,4*6)8':%<#="? ACDFHIKMNPR b bbbbaaaaaaa~a }`"{`#z`%x`'w`(u`*t`,r_.p_/o_1m_3l_5j_7h_8g_:e^a^@`^B^^D\^FZ]HX]JW]LU]NS]PQ]RO]TM\VK\XI\ZG\\E\_C\aA[c?[e=[h;[j9[l7Zo5Zq3Zs0Zv.Zx,Z{*Y}'Y%Y#Y YXXXXWWW W WVVVVSPM J GD@=:74"0%-(*+&.#258;?B F IMOOOOOOOOOOO O O O O O OOOOOOOOOOOOOOOOOOOOOOO O O!O"O#O$O$O%O&O'O(O)O)O*O+O,O-O-O.O/O0O1~O1}O2|O3{O4{O5zO6yO6xO7wO8wO9vO:uO:tO;sOqO?pO?oO@nOAnOBmOClOCkODjOEiOFiOGhOGgOHfOIeOJeOKdOLcOLbOMaONaOO`OP_OP^OQ]OR\OS\OT[OUZOUYOVXOWXOXWOYVOYUOZTO[TO\SO]RO]QO^PO_OO`OOaNObMObLOcKOdKOeJOfIOfHOgGOhFOiFOjEOkDOkCOlBOmBOnAOo@Oo?Op>Oq>Or=Os=<;::987655432110 / .!-",#,$+%*%)&(''(')&)%*$+#,#-".!. /012334567789:;<<=>?@AA B C D E E FGHIJJKLMNOOO P PPQQQQ#R'R*R-~S1zS4vS7sS;oT>lTAhTDeTGbUJ^UM[UPXUSUVVQVYNV\KV_HVbEWeBWg?Wj"<$:&8(7*5+3-1//1.3,5*7)9':%<#>"@ ACEGHJLMOQR c bbbbbbbbaaa~a |a"{a#ya%xa'v`(u`*s`,r`.p`/n`1m`3k_5i_7h_8f_:d_a_@_^B]^D\^FZ^HX^JV^LT^NR]PP]RO]TM]VK]XI]ZG\\E\_C\aA\c?\e=\h:[j8[l6[o4[q2[s0[v-Zx+Z{)Z}'Z$Z"Y YYYYXXXX X WWWWVSPM JGDA=:7 4#0&-)*,&/#269<@C F JMPPPPPPPPPPP P P P P P PPPPPPPPPPPPPPPPPPPPPPP P P!P"P#P$P$P%P&P'P(P)P)P*P+P,P-P-P.P/P0~P1}P1|P2{P3{P4zP5yP6xP6wP7wP8vP9uP:tP:sP;rPpP?oP?nP@nPAmPBlPCkPCjPDiPEiPFhPGgPGfPHePIePJdPKcPLbPLaPMaPN`PO_PP^PP]PQ\PR\PS[PTZPUYPUXPVXPWWPXVPYUPYTPZSP[SP\RP]QP]PP^OP_OP`NPaMPbLPbKPcKPdJPeIPfHPfGPgFPhFPiEPjDPkCPkBPlBPmAPn@Po?Po>Pp>Pq=Pr=<;::98765543211 0 /!."-#,$,%+%*&)'((')')&*%+$,#-#.".!/ 012334567789:;<<=>?@AAB C D E E F GHIJJKLMNOOPP Q QQQRRR#S'S*S-}S1yT4vT7rT;nT>kUAhUDdUGaUJ^VMZVPWVSTVVQVYMW\JW_GWbDWeAXg>Xj;Xm8Xo6Xr3Yu0Yw-Yz*Y|(Y%Z"Z ZZZ[[[[[ [ \\\\\ZXV T R PNLJHFDB@ >"<$:&8(7*5,3.10/2.4,5*7)9';%=#>"@ BDEGIKLNOQS c ccccbbbbbbb}b |a"za#ya%wa'va(ta*sa,qa.o`/n`1l`3k`5i`7g`8e`:d_`_@__B]_D[_FY_HW^JU^LT^NR^PP^RN^TL^VJ]XH]ZF]\D]_B]a@]c>\e<\h:\j8\l6\o3\q1[s/[v-[x+[{([}&Z$Z!ZZZYYYYYX X XXXWVSP M JGDA=:7 4#1&-)*-&0#36:=@D G KNQQQQQQQQQQQ Q Q Q Q Q QQQQQQQQQQQQQQQQQQQQQQQ Q Q!Q"Q#Q$Q$Q%Q&Q'Q(Q)Q)Q*Q+Q,Q-Q-Q.Q/~Q0}Q1|Q1{Q2{Q3zQ4yQ5xQ6wQ6wQ7vQ8uQ9tQ:sQ:rQ;rQoQ?nQ?nQ@mQAlQBkQCjQCiQDiQEhQFgQGfQGeQHeQIdQJcQKbQLaQLaQM`QN_QO^QP]QP\QQ\QR[QSZQTYQUXQUXQVWQWVQXUQYTQYSQZSQ[RQ\QQ]PQ]OQ^OQ_NQ`MQaLQbKQbKQcJQdIQeHQfGQfFQgFQhEQiDQjCQkBQkBQlAQm@Qn?Qo>Qo=Qp=Qq=<;::9876554321 1 0!/".#-$,%,%+&*')(()')'*&+%,$-#.#."/!0 12334567789:;<<=>?@AABC D E E F G HIJJKLMNOOPQQ Q RRRRSS#S'T*T-|T1xT4uU7qU;nU>jUAgVDcVG`VJ]VMZWPVWSSWVPWYMW\JX_GXbDXeAXg>Xj;Ym8Yo5Yr2Yu/Zw,Zz*Z|'Z$Z"Z[[[[[\\ \ \\\]]\ZXV T RPNLJHFDB@!>#<%:'8)7+5-3.10/2.4,6*8):';%=#?"A CDFHIKMNPRS d ccccccccbb~b}b {b"zb#xb%wb'ub(ta*ra,pa.oa/ma1la3ja5h`7g`8e`:c```@^`B\_DZ_FY_HW_JU_LS_NQ_PO^RM^TK^VJ^XH^ZF^\D^_B]a@]c=]e;]h9]j7]l5\n3\q1\s.\v,\x*[{([}%[#[![[ZZZZZY Y YYXXXVSP M JGDA=:7!4$1'-**-&1#4 7:>AD H KOQQQQQQQQQQQ Q Q Q Q Q QQQQQQQQQQQQQQQQQQQQQQQ Q Q!Q"Q#Q$Q$Q%Q&Q'Q(Q)Q)Q*Q+Q,Q-Q-Q.~Q/}Q0|Q1{Q1{Q2zQ3yQ4xQ5wQ6wQ6vQ7uQ8tQ9sQ:rQ:rQ;qQnQ?nQ?mQ@lQAkQBjQCiQCiQDhQEgQFfQGeQGeQHdQIcQJbQKaQLaQL`QM_QN^QO]QP\QP\QQ[QRZQSYQTXQUXQUWQVVQWUQXTQYSQYSQZRQ[QQ\PQ]OQ]OQ^NQ_MQ`LQaKQbKQbJQcIQdHQeGQfFQfFQgEQhDQiCQjBQkBQkAQl@Qm?Qn>Qo=Qo=Qp=<;::987655432 1 1!0"/#.$-%,%,&+'*())()'*'+&,%-$.#.#/"0!1 2334567789:;<<=>?@AABCD E E F G H IJJKLMNOOPQRR R RSSSTT#T'T*U-{U1xU4tU7qV;mV>jVAfVDcWG_WJ\WMYWPVWSRXVOXYLX\IX_FYbCYe@Yg=Yj:Ym7Zo4Zr1Zu/Zw,Zz)[|&[$[![[[\\\\\ ] ]]]]]\ZXV T RPNLJHFDB@!>#<%:'8)7+5-3/11/3.5,7*8):'<%>#@"A CEFHJLMOPRT d ddddcccccc~c|c {c"yb#xb%vb'ub(sb*rb,pb.nb/ma1ka3ia5ha7fa8da:ca_`@]`B\`DZ`FX`HV`JT_LR_NQ_PO_RM_TK_VI_XG^ZE^\C^_A^a?^c=^e;]h9]j7]l4]n2]q0]s.\v,\x)\{'\}%\"\ [[[[[ZZZ Z ZYYYYVSP M JGDA>:7"4%1(-+*.'1#5 8;>BEI LPRRRRRRRRRRR R R R R R RRRRRRRRRRRRRRRRRRRRRRR R R!R"R#R$R$R%R&R'R(R(R)R*R+R,R-R-~R.}R/|R0{R1{R1zR2yR3xR4wR5wR6vR6uR7tR8sR9rR:rR:qR;pRnR>mR?lR@kRAjRBiRCiRChRDgREfRFeRGeRGdRHcRIbRJaRKaRL`RL_RM^RN]RO\RP\RP[RQZRRYRSXRTXRTWRUVRVURWTRXSRYSRYRRZQR[PR\OR]OR]NR^MR_LR`KRaKRbJRbIRcHRdGReFRfFRfERgDRhCRiBRjBRjARk@Rl?Rm>Rn=Ro=Ro=<;::98765543 2 1!1"0#/$.%-%,&,'+(*)))(*'+',&-%.$.#/#0"1!2 334567789:;<<=>?@AABCDE E F G H I JJKLMNOOPQRRS S STTTTU#U'U*~U-{V1wV4sV7pV;lW>iWAeWDbWG_XJ[XMXXPUXSRXVOYYKY\HY_EYbBYe?Zg$<&:(8*7,5.3011/3.5,7*9);'=%>#@"B DEGIJLNOQST e dddddddddc}c|c zc"yc#wc%vc'tc(sb*qb,ob.nb/lb1kb3ib5gb7fa8da:ba<`a>_a@]aB[aDYaFW`HV`JT`LR`NP`PN`RL_TJ_VH_XF_ZD_\B__@_a>^c<^e:^h8^j6^l4^n2]q/]s-]v+]x)]z&]}$\"\\\\[[[[[ [ ZZZZYVSP MJGDA>:7"4%1)-,*/'2#5 9<?CFJ MQSSSSSSSSSSS S S S S S SSSSSSSSSSSSSSSSSSSSSSS S S!S"S#S$S$S%S&S'S(S(S)S*S+S,S-~S-}S.|S/{S0{S1zS1yS2xS3wS4wS5vS6uS6tS7sS8rS9rS:qS:pS;oSmS>lS?kS@jSAiSBiSChSCgSDfSEeSFeSGdSGcSHbSIaSJaSK`SL_SL^SM]SN\SO\SP[SPZSQYSRXSSXSTWSTVSUUSVTSWSSXSSYRSYQSZPS[OS\OS]NS]MS^LS_KS`KSaJSbISbHScGSdFSeFSfESfDSgCShBSiBSjASj@Sk?Sl>Sm=Sn=So=<;::9876554 3 2!1"1#0$/%.%-&,',(+)*))*(+','-&.%.$/#0#1"2!3 34567789:;<<=>?@AABCDEE F G H I J JKLMNOOPQRSST T TTUUUU#V'V*}V-zV1vW4sW7oW;lW>hXAeXDaXG^XJ[XMWYPTYSQYVNYYKZ\HZ_EZbBZe?Zg<[j9[m6[o3[r0[u-\w*\z(\|%\"\ \]]]]]]^ ^ ^^^^^\ZX V T RPNLJHFDB @">$<&:(8*7,5.3012/4.6,8*9);'=%?#A"B DFHIKMNPRSU e eeeeddddd~d}d{d zd"xc#wc%uc'tc(rc*pc,oc.mc/lc1jb3hb5gb7eb8cb:bb<`b>^a@\aBZaDYaFWaHUaJSaLQaNO`PN`RL`TJ`VH`XF`ZD_\B__@_a>_c<_e:_h7_j5^l3^n1^q/^s-^v*^x(]z&]}#]!]]]\\\\\[ [ [[[ZYVS P MJGDA>: 7#4&1)-,*0'3#6 9=@CGJ NQTTTTTTTTTTT T T T T T TTTTTTTTTTTTTTTTTTTTTTT T T!T"T#T$T$T%T&T'T(T(T)T*T+T,~T-}T-|T.{T/{T0zT1yT1xT2wT3wT4vT5uT6tT6sT7rT8rT9qT:pT:oT;nTlT>kT?jT@iTAiTBhTCgTCfTDeTEeTFdTGcTGbTHaTIaTJ`TK_TL^TL]TM\TN\TO[TPZTPYTQXTRXTSWTTVTTUTUTTVSTWSTXRTYQTYPTZOT[OT\NT]MT]LT^KT_KT`JTaITbHTbGTcFTdFTeETfDTfCTgBThBTiATj@Tj?Tk>Tl=Tm=Tn=<;::987655 4 3!2"1#1$0%/%.&-',(,)+)**)+(,'-'.&.%/$0#1#2"3!3 4567789:;<<=>?@AABCDEEF G H I J J KLMNOOPQRSSTT U UUUVVV#V'W*}W-yW1uW4rX7nX;kX>gXAdYDaYG]YJZYMWYPSZSPZVMZYJZ\GZ_D[bA[e>[g;[j8[m5\o2\r/\u-\w*\z']|$]"]]]]^^^^ ^ ^____^\ZX V TRPNLJHFDB!@#>%<':)8+7-5/3113/4.6,8*:)<'>%?#A"C EFHJKMOPRTU f eeeeeeeee~d|d{d yd"xd#vd%ud'sd(rd*pc,nc.mc/kc1ic3hc5fc7dc8cb:ab<_b>]b@\bBZbDXbFVbHTaJSaLQaNOaPMaRKaTIaVG`XE`ZC`\A`_?`a=`c;_e9_g7_j5_l3_n0_q._s,^v*^x'^z%^}#^!^]]]]]\\ \ \\[[[YVS P MJGDA>:!7$4'1*--*0'4#7 :=ADHK ORUUUUUUUUUUU U U U U U UUUUUUUUUUUUUUUUUUUUUUU U U!U"U#U$U$U%U&U'U(U(U)U*U+~U,}U-|U-{U.{U/zU0yU1xU1wU2wU3vU4uU5tU6sU6rU7rU8qU9pU:oU:nU;nUkU>jU?iU@iUAhUBgUCfUCeUDeUEdUFcUGbUGaUHaUI`UJ_UK^UL]UL\UM\UN[UOZUPYUPXUQXURWUSVUTUUTTUUSUVSUWRUXQUYPUYOUZOU[NU\MU]LU]KU^KU_JU`IUaHUbGUbFUcFUdEUeDUfCUfBUgBUhAUi@Uj?Uj>Uk=Ul=Um=<;::98765 5 4!3"2#1$1%0%/&.'-(,),)+**+),(-'.'.&/%0$1#2#3"3!4 567789:;<<=>?@AABCDEEFG H I J J K LMNOOPQRSTTUU U VVVVWW#W'W*|X-xX1uX4qX7nY;jY>gYAcYD`YG\ZJYZMVZPSZSP[VL[YI[\F[_C[b@\e=\g:\j7\m4\o2\r/]u,]w)]z&]|$]!^^^^^^__ _ ___``^\ZX V TRPNLJHFD B"@$>&<(:*8+7-5/3113/5.7,9*;)<'>%@#B"C EGIJLNOQSTV f fffffeeee}e|eze ye"we#vd%td'sd(qd*od,nd.ld/kd1id3gc5fc7dc8bc:`c<_c>]c@[cBYbDXbFVbHTbJRbLPbNNbPLaRJaTIaVGaXEaZCa\Aa_?`a<`c:`e8`g6`j4`l2_n0_q._s+_v)_x'_z%_}"^ ^^^^]]]] ] ]\\\\YVS P MJGDA>:"7%4(1+-.*1'4#8 ;>AEHL OSVVVVVVVVVVV V V V V V VVVVVVVVVVVVVVVVVVVVVVVV V!V"V#V$V$V%V&V'V(V(V)V*~V+}V,|V-{V-{V.zV/yV0xV1wV1wV2vV3uV4tV5sV5rV6rV7qV8pV9oV:nV:nV;mVjV>iV?iV@hVAgVBfVCeVCeVDdVEcVFbVGaVGaVH`VI_VJ^VK]VK\VL\VM[VNZVOYVPXVPXVQWVRVVSUVTTVTSVUSVVRVWQVXPVYOVYOVZNV[MV\LV]KV]KV^JV_IV`HVaGVaFVbFVcEVdDVeCVfBVfBVgAVh@Vi?Vj>Vj=Vk=Vl=<;::9876 5 5!4"3#2$1%1%0&/'.(-),),*++*,)-(.'.'/&0%1$2#3#3"4!5 67789:;<<=>?@AABCDEEFGH I J J K L MNOOPQRSTTUVV V VWWWWX#X'X*{X-wY1tY4pY7mY;iZ>fZAbZD_ZG\ZJX[MU[PR[SO[VL[YI\\E\_B\b?\e<\g:]j7]m4]o1]r.]u+^w(^z&^|#^ ^^______ ` `````^\ZX V TRPNLJHFD B"@$>&<(:*8,7.503214/6.7,9*;)='?%@#B"D FGIKLNPQSUV g ffffffff~f}f{eze xe"we#ue%te're(pe*oe,md.ld/jd1hd3gd5ed6cd8bd:`c<^c>\c@[cBYcDWcFUcHScJQbLPbNNbPLbRJbTHbVFbXDaZBa\@a_>aa;"7%4(1+-/*2'5#8 <?BFIM PTVVVVVVVVVVV V V V V V VVVVVVVVVVVVVVVVVVVVVVVV V!V"V#V$V$V%V&V'V(V(V)~V*}V+|V,{V-{V-zV.yV/xV0wV1wV1vV2uV3tV4sV5rV5rV6qV7pV8oV9nV:nV:mV;lViV>iV?hV@gVAfVBeVCeVCdVDcVEbVFaVGaVG`VH_VI^VJ]VK\VK\VL[VMZVNYVOXVPXVPWVQVVRUVSTVTSVTSVURVVQVWPVXOVYOVYNVZMV[LV\KV]KV]JV^IV_HV`GVaFVaFVbEVcDVdCVeBVfBVfAVg@Vh?Vi>Vj=Vj=Vk=<;::987 6 5!5"4#3$2%1%1&0'/(.)-),*,++,*-).(.'/'0&1%2$3#3#4"5!6 7789:;<<=>?@AABCDEEFGHI J J K L M NOOPQRSTTUVWW W WXXXXY#Y'~Y*zY-wY1sZ4pZ7lZ;iZ>e[Ab[D^[G[[JX[MT\PQ\SN\VK\YH\\E]_B]b?]e<]g9]j6]m3^o0^r-^u+^w(^z%_|"_ ____```` ` ``aaa^\Z X VTRPNLJHFD!B#@%>'<):+8-7/503214/6.8,:*<)='?%A#C"D FHJKMOPRTUW g gggggfff~f|f{fyf xf"vf#uf%se're(pe*ne,me.ke/ie1he3fd5dd6cd8ad:_d<^d>\d@ZdBXdDVcFUcHScJQcLOcNMcPKcRIbTGbVEbXCbZAb\?b_=ba;ac9ae7ag5aj3al1an.aq,`s*`v(`x&`z#`}!`______^^ ^^^^]\YV S PMJGDA> ;#7&4)1,-/*3'6#9 <@CFJM QTWWWWWWWWWWW W W W W W WWWWWWWWWWWWWWWWWWWWWWWW W!W"W#W$W$W%W&W'W(W(~W)}W*|W+{W,{W-zW-yW.xW/wW0wW1vW1uW2tW3sW4rW5rW5qW6pW7oW8nW9nW:mW:lW;kWiW>hW?gW@fWAeWBeWCdWCcWDbWEaWFaWG`WG_WH^WI]WJ\WK\WK[WLZWMYWNXWOXWPWWPVWQUWRTWSSWTSWTRWUQWVPWWOWXOWYNWYMWZLW[KW\KW]JW]IW^HW_GW`FWaFWaEWbDWcCWdBWeBWfAWf@Wg?Wh>Wi=Wj=Wj=<;::98 7 6!5"5#4$3%2%1&1'0(/).)-*,+,,+-*.).(/'0'1&2%3$3#4#5"6!7 789:;<<=>?@AABCDEEFGHIJ J K L M N OOPQRSTTUVWWX X XXYYYY#Z'}Z*zZ-vZ1rZ4o[7k[;h[>d[Aa[D^\GZ\JW\MT\PQ\SM]VJ]YG]\D]_A]b>^e;^g8^j5^m2^o/_r-_u*_w'_z$_|"_``````` a aaaaaa^\Z X VTRPNLJHFD!B#@%>'<):+8-7/513315/7.9,:*<)>'@%B#C"E GHJLNOQRTVW h gggggggg}g|gzfyf wf"vf#tf%sf'qf(of*nf,le.ke/ie1ge3fe5de6be8`e:_e<]d>[d@YdBXdDVdFTdHRdJPdLNcNMcPKcRIcTGcVEcXCcZAc\?b_=ba;bc9be6bg4bj2bl0an.aq,as)av'ax%az#`} `````___ _ __^^^\YV S PMJGDA>!;$7'4*1-.0*3'6#: =@DGKN RUXXXXXXXXXXX X X X X X XXXXXXXXXXXXXXXXXXXXXXXX X!X"X#X$X$X%X&X'X(~X(}X)|X*{X+{X,zX-yX-xX.wX/wX0vX1uX1tX2sX3rX4rX5qX5pX6oX7nX8nX9mX:lX:kX;jXhX>gX?fX@eXAeXBdXCcXCbXDaXEaXF`XG_XG^XH]XI\XJ\XK[XKZXLYXMXXNXXOWXPVXPUXQTXRSXSSXTRXTQXUPXVOXWOXXNXYMXYLXZKX[KX\JX]IX]HX^GX_FX`FXaEXaDXbCXcBXdBXeAXf@Xf?Xg>Xh=Xi=Xj=<;::9 8 7!6"5#5$4%3%2&1'1(0)/).*-+,,,-+.*.)/(0'1'2&3%3$4#5#6"7!7 89:;<<=>?@AABCDEEFGHIJJ K L M N O OPQRSTTUVWXXX Y YYYZZZ#Z'|[*y[-u[1r[4n[7k\;g\>d\A`\D]\GZ]JV]MS]PP]SM]VJ^YF^\C^_@^b=^e:^g7_j5_m2_o/_r,_u)`w&`z$`|!````aaaa a abbbba^\Z X VTRPNLJHF D"B$@&>(<*:,8.70523315/7.9,;*=)>'@%B#D"F GIKLNPQSUVX h hhhhhgg~g}g{gzgxg wg"ug#tg%rf'pf(of*mf,lf.jf/hf1gf3ef5ce6be8`e:^e<\e>[e@YeBWeDUeFSdHRdJPdLNdNLdPJdRHdTFdVDcXBcZ@c\>c^!;$7'4+1..1*4'7#: >AEHKO RVYYYYYYYYYYY Y Y Y Y Y YYYYYYYYYYYYYYYYYYYYYYYY Y!Y"Y#Y$Y$Y%Y&Y'~Y(}Y(|Y){Y*{Y+zY,yY,xY-wY.wY/vY0uY1tY1sY2rY3rY4qY5pY5oY6nY7nY8mY9lY:kY:jY;iYgY>fY?eY@eYAdYBcYBbYCaYDaYE`YF_YG^YG]YH\YI\YJ[YKZYKYYLXYMXYNWYOVYPUYPTYQSYRSYSRYTQYTPYUOYVOYWNYXMYXLYYKYZKY[JY\IY]HY]GY^FY_FY`EYaDYaCYbBYcBYdAYe@Yf?Yf>Yg=Yh=Yi=<;:: 9 8!7"6#5$5%4%3&2'1(1)0)/*.+-,,-,.+.*/)0(1'2'3&3%4$5#6#7"7!8 9:;<<=>?@AABCDEEFGHIJJK L M N O O PQRSTTUVWXXYY Y ZZZZ[[#['|[*x\-t\1q\4m\7j\;f]>c]A_]D\]GY]JV^MR^PO^SL^VI^YF^\C__@_b=_e:_g7_j4`m1`o.`r+`u)`w&`z#a| aaaaaabb b bbbbca^\ Z X VTRPNLJHF D"B$@&>(<*:,8.70523416/8.:,;*=)?'A%C#D"F HIKMOPRSUWX i hhhhhhh~h|h{hyhxg vg"ug#sg%rg'pg(ng*mg,kg.jf/hf1ff3ef5cf6af8_f:^f<\f>Ze@XeBWeDUeFSeHQeJOeLMeNKePIdRHdTFdVDdXBdZ@d\>d^";%7(4+1..2*5'8#; ?BEILP SWZZZZZZZZZZZ Z Z Z Z Z ZZZZZZZZZZZZZZZZZZZZZZZZ Z!Z"Z#Z$Z$Z%Z&~Z'}Z(|Z({Z){Z*zZ+yZ,xZ,wZ-wZ.vZ/uZ0tZ1sZ1rZ2rZ3qZ4pZ5oZ5nZ6nZ7mZ8lZ9kZ:jZ:iZ;iZfZ>eZ?eZ@dZAcZBbZBaZCaZD`ZE_ZF^ZG]ZG\ZH\ZI[ZJZZKYZKXZLXZMWZNVZOUZPTZPSZQSZRRZSQZTPZTOZUOZVNZWMZXLZXKZYKZZJZ[IZ\HZ]GZ]FZ^FZ_EZ`DZaCZaBZbBZcAZd@Ze?Zf>Zf=Zg=Zh=<;: : 9!8"7#6$5%5%4&3'2(1)1)0*/+.,--,.,.+/*0)1(2'3'3&4%5$6#7#7"8!9 :;<<=>?@AABCDEEFGHIJJKL M N O O P QRSTTUVWXXYZZ Z [[[[[\#\'{\*w\-t\1p]4l]7i];f]>b^A_^D[^GX^JU^MR^PN_SK_VH_YE_\B__?`b<`e9`g6`j3`m0`o-ar+au(aw%az"a| aabbbbbb c ccccca^\ Z XVTRPNLJHF!D#B%@'>)<+:-8/71533516/8.:,<*>)@'A%C#E"G HJLMOQRTVWY i iiiiiih}h|hzhyhwh vh"th#sh%qh'og(ng*lg,kg-ig/gg1fg3dg5bg6af8_f:]f<[f>Zf@XfBVfDTfFRfHPeJOeLMeNKePIeRGeTEeVCeXAdZ?d\=d^;da9dc7de5dg3dj0cl.cn,cq*cs(cu%cx#cz!b}bbbbbba a aaaa`_\Y V SPMJGDA >#;&7)4,1/.2*5'9#< ?CFIMP TX[[[[[[[[[[[ [ [ [ [ [ [[[[[[[[[[[[[[[[[[[[[[[[ [!["[#[$[$[%~[&}['|[({[({[)z[*y[+x[,w[,w[-v[.u[/t[0s[1r[1r[2q[3p[4o[5n[5n[6m[7l[8k[9j[:i[:i[;h[e[>e[?d[@c[Ab[Ba[Ba[C`[D_[E^[F][G\[G\[H[[IZ[JY[KX[KX[LW[MV[NU[OT[PS[PS[QR[RQ[SP[TO[TO[UN[VM[WL[XK[XK[YJ[ZI[[H[\G[]F[]F[^E[_D[`C[aB[aB[bA[c@[d?[e>[f=[f=[g<[h;[i:[j9[j9[k8[l7[m6[n5[n5[o4[p3[q2[r1[s0[s0[t/[u.[v-[w,[w,[x+[y*[z)[{([|'[|'[}&[~%[$[#[#["[![ [[[[[[[[[[[[[[[[[[[[[[[ [ [ [ [ [ [ [[[[[[[[[[[[ZYXWVVUTSR R Q P O N M MLKJIHHGFEDCCBA@??>=<; : :!9"8#7$6%5%5&4'3(2)1)1*0+/,.--.,.,/+0*1)2(3'3'4&5%6$7#7#8"9!: ;<<=>?@AABCDEEFGHIJJKLM N O O P Q RSTTUVWXXYZ[[ [ [\\\\\#~]'z]*v]-s]1o]4l^7h^;e^>a^A^^D[_GW_JT_MQ_PN_SK`VG`YD`\A`_>`b;`e8ag5aj2am0ao-ar*au'bw$bz"b|bbbbccc c cccddca^\ Z XVTRPNLJHF"D$B&@(>*<,:-8/71533517/9.;,=*>)@'B%D#E"G IKLNPQSUVXY j iiiiii~i}i{izixiwh uh"th#rh%ph'oh(mh*lh,jh-hh/gg1eg3cg5bg6`g8^g:]g<[g>Yg@WgBUfDTfFRfHPfJNfLLfNJfPHfRFeTDeVBeX@eZ>e\$;'8*4-10.3*6'9$= @CGJNQ UX[[[[[[[[[[[ [ [ [ [ [ [[[[[[[[[[[[[[[[[[[[[[[[ [!["[#[$[$~[%}[&|['{[({[(z[)y[*x[+w[,w[,v[-u[.t[/s[0r[1r[1q[2p[3o[4n[5n[5m[6l[7k[8j[9i[:i[:h[;g[e[>d[?c[@b[Aa[Ba[B`[C_[D^[E][F\[G\[G[[HZ[IY[JX[KX[KW[LV[MU[NT[OS[PS[PR[QQ[RP[SO[TO[TN[UM[VL[WK[XK[XJ[YI[ZH[[G[\F[]F[]E[^D[_C[`B[aB[aA[b@[c?[d>[e=[f=[f<[g;[h:[i9[j9[j8[k7[l6[m5[n5[n4[o3[p2[q1[r0[s0[s/[t.[u-[v,[w,[w+[x*[y)[z([{'[{'[|&[}%[~$[#[#["[![ [[[[[[[[[[[[[[[[[[[[[[[ [ [ [ [ [ [ [[[[[[[[[[[[[ZYXWVVUTS R R Q P O N MMLKJIHHGFEDCCBA@??>=< ; :!:"9#8$7%6%5&5'4(3)2)1*1+0,/-..-.,/,0+1*2)3(3'4'5&6%7$7#8#9":!; <<=>?@AABCDEEFGHIJJKLMN O O P Q R STTUVWXXYZ[[\ \ \\]]]]#}]'y^*v^-r^1o^4k^7g_;d_>a_A]_DZ_GW`JS`MP`PM`SJ`VG`YDa\Aa_>ab;ae8ag5aj2bm/bo,br)bu'bw$bz!c|ccccccd d dddddca^\ Z XVTRPNLJH F"D$B&@(>*<,:.8072543618/9.;,=*?)A'B%D#F"H IKMNPRSUWXZ j jjjjjj~i|i{iyixivi ui"si#ri%pi'ni(mh*kh,jh-hh/fh1eh3ch5ah6_h8^h:\gXg@WgBUgDSgFQgHOgJMgLLfNJfPHfRFfTDfVBfX@fZ>f\$;'8*4-11.4*7':$= ADHKNR VY\\\\\\\\\\\ \ \ \ \ \ \ \\\\\\\\\\\\\\\\\\\\\\\ \!\"\#\#~\$}\%|\&{\'{\(z\(y\)x\*w\+w\,v\,u\-t\.s\/r\0r\1q\1p\2o\3n\4n\5m\5l\6k\7j\8i\9i\9h\:g\;f\d\>c\?b\@a\Aa\B`\B_\C^\D]\E\\F\\G[\GZ\HY\IX\JX\KW\KV\LU\MT\NS\OS\OR\PQ\QP\RO\SO\TN\TM\UL\VK\WK\XJ\XI\YH\ZG\[F\\F\]E\]D\^C\_B\`B\aA\a@\b?\c>\d=\e=\e<\f;\g:\h9\i9\j8\j7\k6\l5\m5\n4\n3\o2\p1\q0\r0\s/\s.\t-\u,\v,\w+\w*\x)\y(\z'\{'\{&\|%\}$\~#\#\"\!\ \\\\\\\\\\\\\\\\\\\\\\\ \ \ \ \ \ \ \\\\\\\\\\\\[[ZYXWVVUT S R R Q P O NMMLKJIHHGFEDCCBA@??>= < ;!:":#9$8%7%6&5'5(4)3)2*1+1,0-/...-/,0,1+2*3)3(4'5'6&7%7$8#9#:";!< <=>?@AABCDEEFGHIJJKLMNO O P Q R S TTUVWXXYZ[\\\ ] ]]]^^^#|^'y^*u_-q_1n_4j_7g_;c`>``A]`DY`GV`JS`MOaPLaSIaVFaYCa\@a_=bb:be7bg4bj1bm.bo+cr)cu&cw#cz c|ccddddd d deeeeca^ \ Z XVTRPNLJH!F#D%B'@)>+<-:/8172543618/:.<,>*?)A'C%E#F"H JLMOQRTVWYZ k jjjjjj}j|jzjyjwjvj ti"si#qi%oi'ni(li*ki,ii-gi/fi1dh3bh5ah6_h8]h:[hXh@VhBThDRgFQgHOgJMgLKgNIgPGgREgTCgVAfX?fZ=f\;f^9fa7fc5fe3fg1ej/el,en*eq(es&eu#ex!ezd}ddddddc c cccca_\ Y VSPMJGDA">%;(8+4.11.4*8';$> BEHLOS VZ]]]]]]]]]]] ] ] ] ] ] ] ]]]]]]]]]]]]]]]]]]]]]]] ]!]"]#~]#}]$|]%{]&{]'z](y](x])w]*w]+v],u],t]-s].r]/r]0q]1p]1o]2n]3n]4m]5l]5k]6j]7i]8i]9h]9g]:f];e]c]>b]?a]@a]A`]B_]B^]C]]D\]E\]F[]GZ]GY]HX]IX]JW]KV]KU]LT]MS]NS]OR]OQ]PP]QO]RO]SN]TM]TL]UK]VK]WJ]XI]XH]YG]ZF][F]\E]]D]]C]^B]_B]`A]a@]a?]b>]c=]d=]e<]e;]f:]g9]h9]i8]j7]j6]k5]l5]m4]n3]n2]o1]p0]q0]r/]s.]s-]t,]u,]v+]w*]w)]x(]y']z']{&]{%]|$]}#]~#]"]!] ]]]]]]]]]]]]]]]]]]]]]]] ] ] ] ] ] ] ]]]]]]]]]]]]\[[ZYXWVVU T S R R Q P ONMMLKJIHHGFEDCCBA@??> = ?@AABCDEFFGHIJJKLMNOO P Q R S T TUVWXXYZ[\]]] ^ ^^^^__#|_'x_*t_-q`1m`4i`7f`;c`>_`A\aDXaGUaJRaMOaPLbSHbVEbYBb\?b_+<-:/8173553719/:.<,>*@)B'C%E#G"I JLNOQSTVXY[ k kkkkk~k}j{jzjxjwjuj tj"rj#pj%oj'mj(lj*ji,hi-gi/ei1ci3bi5`i6^i8]i:[iWh@VhBThDRhFPhHNhILhLJhNIgPGgREgTCgVAgX?gZ=g\;g^9ga6fc4fe2fg0fj.fl,fn*fq'fs%eu#ex eze}eeeddd d dddcca_\ Y VSPMJGD A#>&;)8,4/12.5*8'<$? BFILPT W[^^^^^^^^^^^ ^ ^ ^ ^ ^ ^ ^^^^^^^^^^^^^^^^^^^^^^^ ^!^"~^#}^#|^${^%{^&z^  !#%(*,.02579;=@BDFHJMOQSUIW^JV^KU^KT^LS^MS^NR^OQ^OP^PO^QO^RN^SM^TL^TK^UK^VJ^WI^XH^XG^YF^ZF^[E^\D^]C^]B^^B^_A^`@^a?^a>^b=^c=^d<^e;^e:^f9^g9^h8^i7^j6^j5^k5^l4^m3^n2^n1^o0^p0^q/^r.^s-^s,^t,^u+^v*^w)^w(^x'^y'^z&^{%^{$^|#^}#^~"^!^ ^^^^^^^^^^^^^^^^^^^^^^^ ^ ^ ^ ^ ^ ^ ^^^^^^^^^^^^]\[[ZYXWVV U T S R R Q PONMMLKJIHHGFEDCCBA@?? > =!<";#:$:%9%8&7'6(5)5)4*3+2,1-1.0.//.0-1,2,3+3*4)5(6'7'7&8%9$:#;#<"?@AABCDEFFGHIJJKLMNOOP Q R S T T UVWXXYZ[\]]^^ ^ _____~`#{`'w`*s`-p`1l`4ia7ea;ba>^aA[aDXbGTbJQbMNbPKbSHbVEcYAc\>c_;cb8ce6cg3cj0dm-do*dr'du%dw"dzd|eeeeee e fffffeca^ \ ZXVTRPNLJ H"F$D&B(@*>,<.:08274553719/;.=,?*@)B'D%F#H"I KMNPRSUWXZ[ l kkkkk~k|k{kykxkvkuk sj"rj#pj%nj'mj(kj*jj,hj-fj/ej1cj3ai5`i6^i8\i:ZiWi@UiBSiDQiFOhGNhILhKJhNHhPFhRDhTBhV@hX>hZ&;)8-4013.6*9'<$@ CFJMQT X[___________ _ _ _ _ _ _ _______________________ _!~_"}_#|_C5(    "$')+-/1468:<>ACEGILNPRTWY[]_bdfhjmoqsvxz||zxvtqomkhfdb_][YWTRPMKIGDB@>;97520.+)'%" {#_|#_}"_~!_ _______________________ _ _ _ _ _ _ ____________^]\[[ZYXWV V U T S R R QPONMMLKJIHHGFEDCCBA@? ? >!="<#;$:%:%9&8'7(6)5)5*4+3,2-1.1.0//0.1-2,3,3+4*5)6(7'7'8&9%:$;#<#<"=!> ?@AABCDEFFGHIJJKLMNOOPQ R S T T U VWXXYZ[\]]^__ _ _````~`#za'va*sa-oa1ka4ha7db;ab>^bAZbDWbGTbJPcMMcPJcSGcVDcYAc\>d_;db8de5dg2dj/dm,do)er'eu$ew!eze|eeffff f fffggeca^ \ ZXVTRPNLJ H"F$D&B(@*>,<.:0827456381:/<.=,?*A)C'E%F#H"J KMOQRTUWYZ\ l lllll}l|lzkykwkvktk sk"qk#ok%nk'lk(kk*ij,gj-fj/dj1bj3aj5_j6]j8\j:ZjVi@TiBSiDQiFOiGMiIKiKIiNGiPEiRChTAhV?hX=hZ;h\9h^7ha5hc3he1gg/gj-gl+gn(gq&gs$gu"gxfzf}ffffff e eeeeda_\ Y VSPMJGD!A$>';*8-4013.7+:'=$@ DGKNRU Y\___________ _ _ _ _ _ _ _______________________ ~_n`QC5(   !#%(*,.02579;=@BDFHKMOQSVXZ\^acegilnpruwy{}|zxvtqomkhfdb_][YWTRPMKIGDB@>;97520.+)'%"  _____________ _ _ _ _ _ _ _____________^]\[[ZYXW V V U T S R RQPONMMLKJIHHGFEDCCBA@ ? ?!>"=#<$;%:%:&9'8(7)6)5*5+4,3-2.1.1/00/1.2-3,3,4+5*6)7(7'8'9&:%;$<#<#=">!? @AABCDEFFGHIJJKLMNOOPQR S T T U V WXXYZ[\]]^_`` ` ``aaa}a#ya'va*rb-nb1kb4gb7db;`c>]cAZcDVcGScJPcMMdPIdSFdVCdY@d\=d_:db7ee4eg1ej.em,eo)er&eu#fw fzf|fffffg g gggggeca ^ \ ZXVTRPNLJ!H#F%D'B)@+>-,@*B)C'E%G#I"J LNOQSTVXY[\ m llll~l}l{lzlxlwlultl rl"pk#ok%mk'lk(jk*ik,gk-ek/dk1bk3`k5^k6]j8[j:YjVj@TjBRjDPjFNjGLjIKiKIiMGiPEiRCiTAiV?iX=iZ;i\9h^7ha5hc3he0hg.hj,hl*hn(hq%gs#gu!gxgzg}gggfff f ffffdb_ \ YVSPMJGD"A%>(;+8.5114.7+;'>$A EHKORV Y]``````````` ` ` ` ` ` ` `````````````````````bq}n`QC5(    "$')+-/1468:<>ACEGILNPRTWY[]_bdfhkmoqsvxz||zxvtqomkhfdb_][YWTRPMKIGDB@>;97520.+)'%"   ```````````` ` ` ` ` ` ` `````````````_^]\[[ZYX W V V U T S RRQPONMMLKJIHHGFEDCCBA @ ?!?">#=$<%;%:&:'9(8)7)6*5+5,4-3.2.1/1001/2.3-3,4,5+6*7)7(8'9':&;%<$<#=#>"?!@ AABCDEFFGHIJJKLMNOOPQRS T T U V W XXYZ[\]]^_``a a aaabb|b#xb'ub*qb-nc1jc4fc7cc;`c>\cAYdDVdGRdJOdMLdPIdSFeVBeY?e\.,@*B)D'F%G#I"K MNPRSUVXZ[] m mmmm~m|m{mylxlvlulsl rl"pl#nl%ml'kl(jl*hl,fk-ek/ck1ak3`k5^k6\k8Zk:YkUk@SkBQjDPjENjGLjIJjKHjMFjPDjRBjT@jV>iX);,8/5215.8+;'?$B EILPSW Z^aaaaaaaaaaa a a a a a a aaaaaaaaaaaaaaaaaa3BRap}n`QC5(   !#%(*,.03579;=@BDFHKMOQSVXZ\^acegilnpruwy{~|zxvtqomkhfdb_][YWTRPMKIGDB@>;97520.+)'%"   aaaaaaaaaaa a a a a a a aaaaaaaaaaaa``_^]\[[ZY X W V V U T SRRQPONMMLKJIHHGFEDCCB A @!?"?#>$=%<%;&:':(9)8)7*6+5,5-4.3.2/101102/3.3-4,5,6+7*7)8(9':';&<%<$=#>#?"@!A ABCDEFFGHIJJKLMNOOPQRST T U V W X XYZ[\]]^_`aaa b bbbbc{c#xc'tc*pc-mc1id4fd7bd;_d>[dAXdDUdGReJNeMKePHeSEeVBeY?f\.<0:28476583:1;/=.?,A*C)D'F%H#J"K MOPRTUWYZ\] n nmmm}m|mzmymwmvmtmsm qm"om#nl%ll'kl(il*gl,fl-dl/bl1al3_l5]l6\l8Zk:XkUk@SkBQkDOkEMkGKkIIkKHkMFjPDjRBjT@jV>jX);,8/5316.9+<'?$C FIMPTW [_bbbbbbbbbbb b b b b b b bbbbbbbbbbbbbbb!2AQ`o~}n`QC5(    "$')+-/1468:<?ACEGILNPRTWY[]`bdfhkmoqtvxz||zxvtqomkhfdb_][YWTRPMKIGDB@>;97520.+)'%"   bbbbbbbbbb b b b b b b bbbbbbbbbbbba``_^]\[[Z Y X W V V U TSRRQPONMMLKJIHHGFEDCC B A!@"?#?$>%=%<&;':(:)9)8*7+6,5-5.4.3/20111203/3.4-5,6,7+7*8)9(:';'<&<%=$>#?#@"A!A BCDEFFGHIJJKLMNOOPQRSTT U V W X X YZ[\]]^_`abbb b cccc~c{c#wd'sd*pd-ld1hd4ed7ae;^e>[eAWeDTeGQeJNfMJfPGfSDfVAfY>f\;f_8gb5ge2gg/gj,gm*go'gr$gu!hwhzh|hhhhh i iiiiigeca ^ \ZXVTRPNL!J#H%F'D)B+@->/<1:38476583:1.@,A*C)E'G%H#J"L NOQSTVXY[\^ n nnn~n}n{nznxnwmumtmrm pm"om#mm%lm'jm(im*gm,em-dm/bl1`l3_l5]l6[l8Yl:XlTl@RlBPlDOkEMkGKkIIkKGkMEkOCkRAkT?kV=kX;kZ9j\7j^5ja3jc1je/jg,jj*jl(jn&iq$is!iuixizi}iiihh h hhhhgdb_ \ YVSQNKH!D$A'>*;-805316.:+='@$C GJNQUX \_ccccccccccc c c c c c c ccccccccccccccc 0@P_n}}n`QC5(   !#&(*,.03579;=@BDFHKMOQSVXZ\^acegjlnpruwy{|~zxvtqomkhfdb_][YWTRPMKIGDB@>;97520.+)'%"   ccccccccc c c c c c c ccccccccccccba``_^]\[[ Z Y X W V V UTSRRQPONMMLKJIHHGFEDC C B!A"@#?$?%>%=&<';(:):)9*8+7,6-5.5.4/3021121303/4.5-6,7,7+8*9):(;'<'<&=%>$?#@#A"A!B CDEFFGHIJJKLMNOOPQRSTTU V W X X Y Z[\]]^_`abbcc c cddd~dzd#vd're*oe-ke1he4de7ae;]f>ZfAWfDSfGPfJMfMJfPGgSCgV@gY=g\:g_7gb4ge1gg/hj,hm)ho&hr#hu!hwhzh|iiiii i iiijjgec a ^\ZXVTRPNL!J#H%F'D)B+@->/<1:38577593;1.@,B*D)E'G%I#K"L NPQSUVXZ[]^ o onn~n|n{nynxnvnunsnrn pn!nn#mn%km'jm(hm*fm,em-cm/am1`m3^m5\m6[m8Ym:Wl
              Sl@RlBPlDNlELlGJlIHlKFlMDlOClRAkT?kV=kX;kZ8k\6k^4ka2kc0ke.kg,jj*jl'jn%jq#js!jujxjzj}iiiii i iiihgdb _ \YVSQNKH"E%A(>+;.815417.:+>'A$D GKNRUY ]`ddddddddddd d d d d d d ddddddddddddddd/?N^m{}n`QC5(    "$')+-/1468:<?ACEGJLNPRUWY[]`bdfhkmoqtvxz|}zxvtqomkhfdb_][YWTRPMKIGDB@>;97520.+)'%"   dddddddd d d d d d d ddddddddddddcba``_^]\[ [ Z Y X W V VUTSRRQPONMMLKJIHHGFED C C!B"A#@$?%?%>&='<(;):):*9+8,7-6.5.5/403122131304/5.6-7,7,8+9*:);(<'<'=&>%?$@#A#A"B!C DEFFGHIJJKLMNOOPQRSTTUV W X X Y Z [\]]^_`abbcdd d ddee}eye#ue're*nf-jf1gf4cf7`f;]f>YfAVgDSgGOgJLgMIgPFgSCgV@hY=h\:h_7hb4he1hg.hj+hm(io%ir#iu iwizi|iiij j jjjjjjgec a ^\ZXVTRPN L"J$H&F(D*B,@.>0<2:48677593;1=/?.A,B*D)F'H%J#K"M OPRTUWYZ\]_ o oo~o}o|ozoyowovntnsnqn on!nn#ln%kn&in(gn*fn,dn-cn/an1_m3]m4\m6Zm8Xm:VmSm@QmBOmCMmELmGJlIHlKFlMDlOBlR@lT>lV+;.825518.;+>'B$E HLOSVZ ]addddddddddd d d d d d d ddddddddddddddd.>M]lz}n`QC5(       !#&(*,.03579;>@BDFHKMOQSVXZ\_acegjlnpruwy|{z~xvtqomkhfdb_][YWTRPMKIGDB@>;97520.+)'%"   ddddddd d d d d d d dddddddddddddcba``_^]\ [ [ Z Y X W VVUTSRRQPONMMLKJIHHGFE D C!C"B#A$@%?%?&>'=(<);):*:+9,8-7.6.5/50413223131405/6.7-7,8,9+:*;)<(<'='>&?%@$A#A#B"C!D EFFGHIJJKLMNOOPQRSTTUVW X X Y Z [ \]]^_`abbcdde e eeee|fxf#uf'qf*mf-jf1fg4cg7_g;\g>XgAUgDRgGOhJKhMHhPEhSBhV?hY0<2:486785:3<1>/?.A,C*E)G'H%J#L"M OQSTVWY[\^_ p po~o}o{ozoxowouotoropo oo!mo#lo%jo&in(gn*en,dn-bn/`n1_n3]n4[n6Yn8Xn:VnRm@PmBOmCMmEKmGImIGmKEmMCmOAmR?mT=mV;lX9lZ7l\5l^3l`1lc/le-lg+lj(ll&kn$kq"kskukxkzk}kkkj j jjjjjgdb _ \YVTQNK H#E&A)>,;/825519.<+?'B$F!ILPSWZ ^beeeeeeeeeee e e e e e e eeeeeeeeeeeeeee -=L[jy}n`QC5 (               " $ ' ) + - / 2 4 6 8 : < ? A C E G J L N P R U W Y [ ] ` b d f i k m o q t v x| zz }x v t q o m k h f d b _ ] [ Y W T R P M K I G D B @ > ;97520.+)'%"   eeeeee e e e e e e eeeeeeeeeeeeddcba``_^] \ [ [ Z Y X WVVUTSRRQPONMMLKJIHHGF E D!C"C#B$A%@%?&?'>(=)<);*:+:,9-8.7.6/5051423323141506/7.8-8,9,:+;*<)<(='>'?&@%A$A#B#C"D!E FFGHIJJKLMNOOPQRSTTUVWX X Y Z [ \ ]]^_`abbcdeee f ffff{fwg#tg'pg*lg-ig1eg4bg7^h;[h>XhAThDQhGNhJKhMGiPDiSAiV>iY;i\8i_5ib2ie/jg,jj*jm'jo$jr!jujwjzj|kkkk k kkkkkjge c a ^\ZXVTRPN!L#J%H'F)D+B-@/>1<3:587795:3<1>/@.B,D*E)G'I%K#L"N PQSUVXZ[]^` p pp}p|p{pypxpvpupsoropo no!mo#ko%jo&ho(fo*eo,co-ao/`o1^o3\n4[n6Yn8Wn:UnRn@PnBNnCLnEJnGHnIGnKEmMCmOAmR?mT=mV;mX9mZ7m\5m^3m`0mc.le,lg*lj(ll&ln#lq!lslulxlzl}kkkk k kkkkjgdb _ \YVTQNK!H$E'B*>-;0835629.=+@'C$F!JMQTX[ _bffffffffffff f f f f f fffffffffffffff ,;KZix}n ` Q C 5 (                ! # & ( * , . 0 3 5 7 9 ; > @ B D F I K M O Q T V X Z \ _ a c e g j l n p s u w| yz {x ~v t q o m k h f d b _ ] [ Y W T R P M K I G D B @ > ; 9 7 5 2 0 . + ) ' % "            fffff f f f f f f ffffffffffffeddcba``_^ ] \ [ [ Z Y XWVVUTSRRQPONMMLKJIHHG F E!D"C#C$B%A%@&?'?(>)=)<*;+:,:-9.8.7/605152433324151607/8.8-9,:,;+<*<)=(>'?'@&A%A$B#C#D"E!F FGHIJJKLMNOOPQRSTTUVWXX Y Z [ \ ] ]^_`abbcdefff f ggg~gzgwg#sh'oh*lh-hh1eh4ah7^h;Zi>WiATiDPiGMiJJiMGiPDiSAjV=jY:j\7j_4jb2je/jg,jj)jm&ko#kr!kukwkzk|kkkl l llllljge c a^\ZXVTRPN!L#J&H(F*D,B.@0>1<3:587795;3=1?/A.B,D*F)H'I%K#M"O PRTUWXZ\]_` q q~p}p|pzpypwpvptpspqpop np!lp#kp%ip&hp(fo*do,co-ao/_o1^o3\o4Zo6Xo8Wo:UoQo@OoBNnCLnEJnGHnIFnKDnMBnO@nQ>nT.;184572:.=+@'D$G!JNQUX\ `cgggggggggggg g g g g g gggggggggggggg~g *:J Y h w} n ` Q C 5 (               " % ' ) + - / 2 4 6 8 : < ? A C E G J L N P R U W Y [ ] ` b d f i k m o q t v| xz zx }v t q o m k h f d b _ ] [ Y W T R P M K I G D B @ > ; 9 7 5 2 0 . + ) ' % "            gggg g g g g g g ggggggggggggfeddcba``_ ^ ] \ [ [ Z YXWVVUTSRRQPONMMLKJIHH G F!E"D#C$C%B%A&@'?(?)>)=*<+;,:-:.9.8/70615253433425161708/8.9-:,;,<+<*=)>(?'@'A&A%B$C#D#E"F!F GHIJJKLMNOOPQRSTTUVWXXY Z [ \ ] ] ^_`abbcdeffgg g ghh}hzhvh#rh'oh*ki-gi1di4`i7]i;Zi>ViASjDPjGLjJIjMFjPCjS@jV=jY:j\7k_4kb1ke.kg+kj(km%ko#kr kulwlzl|lll l lllmmljge c a^\ZXVTRP N"L$J&H(F*D,B.@0>2<4:6887:5<3=1?/A.C,E*F)H'J%L#M"O QRTVWY[\^_a q q~q|q{qzqxqwquqtqrqppop mp!lp#jp%ip&gp(ep*dp,bp-`p/_p1]p3[p4Zp6Xo8Vo:ToQo@OoBMoCKoEIoGGoIEoKDoMBoO@nQ>nT.;184582;.>+A(E$H!KORVY] `dhhhhhhhhhhhh h h h h h hhhhhhhhhhhhh~h}h  ) 9 I X g v} n ` Q C 5 (                 ! # & ( * , . 0 3 5 7 9 ; > @ B D F I K M O Q T V X Z \ _ a c e g j l n p s u| wz yx |v ~t q o m k h f d b _ ] [ Y W T R P M K I G D B @ > ; 9 7 5 2 0 . + ) ' % "            hhh h h h h h h hhhhhhhhhhhhgfeddcba`` _ ^ ] \ [ [ ZYXWVVUTSRRQPONMMLKJIH H G!F"E#D$C%C%B&A'@(?)?)>*=+<,;-:.:.9/8071625353443526171808/9.:-;,<,<+=*>)?(@'A'A&B%C$D#E#F"F!G HIJJKLMNOOPQRSTTUVWXXYZ [ \ ] ] ^ _`abbcdeffghh h hhi}iyiui#qi'ni*ji-gi1cj4`j7\j;Yj>UjARjDOjGLjJHkMEkPBkS?kV3<5:6887:5<3>1@/B.C,E*G)I'J%L#N"P QSUVXZ[]^`a r r}q|q{qyqxqvquqsqrqpqnq mq!kq#jq%hq&fq(eq*cp,bp-`p/^p1\p3[p4Yp6Wp8Up:TpPp@NpBLpCKpEIoGGoIEoKCoMAoO?oQ=oT;oV9oX7oZ5o\3o^1o`/nc,ne*ng(ni&nl$nn!npnsnunxnzm}mmm m mmmmmjge b _\YWTQN K#H&E)B,>/;285582;.?+B(E$I!LOSVZ^ aeiiiiiiiiiiii i i i i i iiiiiiiiiiii~i}i|i  ( 8 G W f u} n ` Q C 5 (         "%')+-/2468:=?AC E G J L N P R U W Y [ ^ ` b d f i k m o r t| vz xx zv }t q o m k h f d b _ ] [ Y W T R P M K I G D B @ > ; 9 7 5 2 0 . + ) ' % "            ii i i i i i i iiiiiiiiiiiihgfeddcba` ` _ ^ ] \ [ [ZYXWVVUTSRRQPONMMLKJI H H!G"F#E$D%C%C&B'A(@)?)?*>+=,<-;.:.:/908172635354453627181809/:.;-<,<,=+>*?)@(A'A'B&C%D$E#F#F"G!H IJJKLMNOOPQRSTTUVWXXYZ[ \ ] ] ^ _ `abbcdeffghii i iii|ixjtj#qj'mj*ij-fj1bj4_j7[k;Xk>UkAQkDNkGKkJHkMEkPAlS>lV;lY8l\5l_2lb/le-lg*lj'mm$mo!mrmumwmzm|mmm m nnnnnljg e c a^\ZXVTRP!N#L%J'H)F+D-B/@1>3<5:7897;5=3?1@/B.D,F*G)I'K%M#N"P RSUWXZ\]_`b r ~r}r{rzryrwrvrtrsrqroqnq lq!kq#iq%hq&fq(dq*cq,aq-_q/^q1\q3Zq4Xq6Wq8Up:SpPp@NpALpCJpEHpGFpIDpKBpM@pO>pQ@BDFIKMOQTVXZ\_acehjlnps|uzwxyv|t~qomkhfdb_][YWTRPMKIGDB@>;97520.+)'%"   i i i i i i i iiiiiiiiiiiiihgfeddcba ` ` _ ^ ] \ [[ZYXWVVUTSRRQPONMMLKJ I H!H"G#F$E%D%C&C'B(A)@)?*?+>,=-<.;.:/:091827363545546372818190:/;.<-<,=,>+?*@)A(A'B'C&D%E$F#F#G"H!I JJKLMNOOPQRSTTUVWXXYZ[\ ] ] ^ _ ` abbcdeffghiij j jjj{jwjtk#pk'lk*ik-ek1bk4^k7[k;Wk>TlAQlDMlGJlJGlMDlPAlS>lV;lY8m\5m_2mb/me,mg)mj&mm#mo!mrmunwnzn|nnn n nnnnnljg e ca^\ZXVTR P"N$L&J(H*F,D.B0@2>4<6:8897;5=3?1A/C.D,F*H)J'L%M#O"Q RTVWY[\^_ab s ~s|r{rzrxrwrurtrrrprormr lr!jr#ir%gr&er(dr*br,`q-_q/]q1[q3Zq4Xq6Vq8Tq:SqOq@MqAKqCIqEHqGFqIDpKBpM@pO>pQ;97520.+)'%"    j j j j j j jjjjjjjjjjjjiihgfeddcb a ` ` _ ^ ] \[[ZYXWVVUTSRRQPONMMLK J I!H"H#G$F%E%D&C'C(B)A)@*?+?,>-=.<.;/:0:1928373645556473828191:0;/<.<-=,>,?+@*A)A(B'C'D&E%F$F#G#H"I!J JKLMNOOPQRSTTUVWXXYZ[\] ] ^ _ ` a bbcdeffghijjj k kk~kzkvksk#ok'kl*hl-dl1al4]l7Zl;Wl>SlAPlDMmGImJFmMCmP@mS=mV:mY7m\4m_1mb.ne+ng(nj%nm#no nrnunwnzn|oo o ooooonljg e ca^\ZXVTR P"N$L&J(H*F,D.B0@2>4<6:88:7<5>3@1A/C.E,G*I)J'L%N#O"Q SUVXY[]^`ac s }s|szsysxsvsusssrspsnsmr kr!jr#hr%gr&er(cr*br,`r-^r/]r1[r3Yr4Wr6Vr8Tr:RrNq@MqAKqCIqEGqGEqICqKAqM?qO=qQ;qT9qV7qX5qZ3p\1p^/p`-pc+pe(pg&pi$pl"pn pppspupxpzo}oo o ooooomjg e b_\ZWTQN"K%H(E+B.?1;4875:2>.A+D(G$K!NRUY\` cgkkkkkkkkkkkk k k k k k kkkkkkkkk~k}k|k{k{kzk  $4DSbq}n`QC5(        !$&(*,.13579;>@BDFIKMOQTVXZ]_acehjlnq|szuxwvyt|q~omkhfdb_][YWTRPMKIGDB@>;97520.+)'%"    k k k k k kkkkkkkkkkkkjiihgfeddc b a ` ` _ ^ ]\[[ZYXWVVUTSRRQPONMML K J!I"H#H$G%F%E&D'C(C)B)A*@+?,?->.=.,?,@+A*A)B(C'D'E&F%F$G#H#I"J!J KLMNOOPQRSTTUVWXXYZ[\]] ^ _ ` a b bcdeffghijkkk k kl}lylvlrl#nl'kl*gl-dm1`m4]m7Ym;Vm>SmAOmDLmGImJFnMBnP?nS5<7:98;7<5>3@1B/D.F,G*I)K'M%N#P"R SUWXZ\]_`bc ~t }t{tzsyswsvstsssqsosnsls ks!is#hs%fs&ds(cs*as,_s-^s/\r1Zr3Yr4Wr6Ur8Sr:QrNr@LrAJrCHrEFrGDrICrKArM?rO=qQ;qT9qV7qX5qZ3q\0q^.q`,qc*qe(qg&qi#ql!qnpppspupxpzp}pp p ppppomjg e b_\ZWTQ N#K&H)E,B/?2;5885;2>.B+E(H$L!ORVY]a dhllllllllllll l l l l l llllllll~l}l|l{l{lzlyl #3CRap}n`QC5(         "%')+-02468:=?ACEHJLNPSUWY[^`bdgikmo|rztxvvxt{q}omkhfdb_][YWTRPMKIGDB@>;97520.+)'%"    l l l l llllllllllllkjiihgfedd c b a ` ` _ ^]\[[ZYXWVVUTSRRQPONMM L K!J"I#H$H%G%F&E'D(C)C)B*A+@,?-?.>.=/<0;1:2:393847566575848392:1;1<0-?,@,A+A*B)C(D'E'F&F%G$H#I#J"J!K LMNOOPQRSTTUVWXXYZ[\]]^ _ ` a b b cdeffghijkkll l ll|mymumqm#nm'jm*fm-cm1_m4\n7Xn;Un>RnAOnDKnGHnJEnMBnP?nS5<7:98;7=5?3A1C/D.F,H*J)K'M%O#Q"R TVWYZ\^_abd ~t |t{tytxtwtutttrtptotmtlt js!is#gs%es&ds(bs*as,_s-]s/[s1Zs3Xs4Vs6Ts8Ss:QsMs@KsAJrCHrEFrGDrIBrK@rM>rO@BDGIKMORTVXZ]_acehjln|qzsxuvwtzq|o~mkhfdb_][YWTRPMKIGDB@>;97520.+)'%"    m m mmmmmmmmmmmmmlkjiihgfed d c b a ` ` _^]\[[ZYXWVVUTSRRQPONM M L!K"J#I$H%H%G&F'E(D)C)C*B+A,@-?.?.>/=0<1;2:3:3948576675858493:2;1<1<0=/>.?-@,A,A+B*C)D(E'F'F&G%H$I#J#J"K!L MNOOPQRSTTUVWXXYZ[\]]^_ ` a b b c deffghijkklmm m mm|mxmtnpn#mn'in*fn-bn1_n4[n7Xn;Tn>QoANoDKoGGoJDoMAoP>oS;oV8oY5o\2p_/pb,pe)pg&pj#pm!poprpupwpzp|pq q qqqqpnlj g eca^\ZXVT R"P$N&L(J*H,F.D0B2@4>6<8::8<7>5?3A1C/E.G,H*J)L'N%O#Q"S TVXY[]^`acd }u |uzuytxtvtutstrtptntmtkt jt!ht#gt%et&ct(bt*`t,^t-]t/[t1Yt3Ws4Vs6Ts8Rs:PsMs@KsAIsCGsEEsGCsIAsK?sM>sO;97520.+)'%"    m mmmmmmmmmmmmmmlkjiihgfe d d c b a ` `_^]\[[ZYXWVVUTSRRQPON M M!L"K#J$I%H%H&G'F(E)D*C*C+B,A-@.?.?/>0=1<2;3:3:49586776858594:3;2<1<1=0>/?.@-A,A,B+C*D)E(F'F'G&H%I$J#J#K"L!M NOOPQRSTTUVWXXYZ[\]]^_` a b b c d effghijkklmnn n nn{nwnsnpn#lo'ho*eo-ao1^o4Zo7Wo;To>PoAMoDJpGGpJCpM@pP=pS:pV7pY4p\1p_.pb+pe(pg&qj#qm qoqrquqwqzq|q q qqqrrpnlj g eca^\ZXVT R#P%N'L)J+H-F/D1B3@5>7<9::8<7>5@3B1D/E.G,I*K)L'N%P#R"S UWXZ\]_`bce }u {uzuxuwuvutusuquounuluku iu!hu#ft%dt&ct(at*_t,^t-\t/Zt1Yt3Wt4Ut6St8Rt:PtLt@JtAHtCGtEEsGCsIAsK?sM=sO;sQ9sS7sV5sX3sZ1s\/s^-s`*sc(se&sg$si"rlrnrprsrurxrzr|r r rrrrromj h eb_\ZWTQ"N%K(H+E.B1?4<78:5=2A/D+G(J$N!QUX\_c gjnnnnnnnnnnnn n n n n n nnnnn~n}n|n{n{nznynxnwnvn 0?O^m}{n`QC5(     !$&(*,.13579<>@BDGIKMORTVXZ]_acfhjl|nzqxsvutwqzo|m~khfdb_][YWTRPMKIGDB@>;97520.+)'%"    nnnnnnnnnnnnnnmlkjiihgf e d d c b a ``_^]\[[ZYXWVVUTSRRQPO N M!M"L#K$J%I%H&H'G(F)E*D*C+C,B-A.@.?/?0>1=2<3;3:4:596877868595:4;3<2<1=1>0?/@.A-A,B,C+D*E)F(F'G'H&I%J$J#K#L"M!N OOPQRSTTUVWXXYZ[\]]^_`a b b c d e ffghijkklmnnn o o~ozovosooo#ko'ho*dp-ap1]p4Zp7Vp;Sp>PpALpDIpGFpJCpM@pP7<9:;8=7?5A3B1D/F.H,J*K)M'O%P#R"T UWYZ\^_abde |v {vyvxuwuuuturupuoumuluju iu!gu#eu%du&bu(au*_u,]u-\u/Zu1Xu3Vu4Uu6St8Qt:OtLt?JtAHtCFtEDtGBtI@tK>tM2A/E+H(K$O!RUY\`d gkoooooooooooo o o o o o oooo~o}o|o{o{ozoyoxowovovo.>N]l}zn`QC5(      #%')+-02468;=?ACEHJLNPSUWY\^`bdgik|mzpxrvttvqyo{m}khfdb_][YWTRPMKIGDB@>;97520.+)'%"   oooooooooooonnmlkjiihg f e d d c b a``_^]\[[ZYXWVVUTSRRQP O N!M"M#L$K%J%I&H'H(G)F*E*D+C,C-B.A.@/?0?1>2=3<3;4:5:6978878695:5;4<3<2=1>1?0@/A.A-B,C,D+E*F)F(G'H'I&J%J$K#L#M"N!O OPQRSTTUVWXXYZ[\]]^_`ab b c d e f fghijkklmnooo o p}pypuprpnp#jp'gp*cp-`p1\p4Yq7Uq;Rq>OqALqDHqGEqJBqM?qP8<::<8=7?5A3C1E/G.H,J*L)N'O%Q#S"T VXY[]^`acdf |v zvyvwvvvuvsvrvpvnvmvkvjv hv!gv#ev%cu&bu(`u*^u+]u-[u/Yu1Xu3Vu4Tu6Ru8Qu:OuKu?IuAGuCEuEDuGBuI@uK>uM@BDGIKMORTVXZ]_acfhj|lznxqvstuqwozm|k~hfdb_][YWTRPMKIGDB@>;97520.+)'%"   ppppppppppponnmlkjiih g f e d d c ba``_^]\[[ZYXWVVUTSRRQ P O!N"M#M$L%K%J&I'H(H)G*F*E+D,C-C.B.A/@0?1?2>3=3<4;5:6:79888796:5;5<4<3=2>1?1@0A/A.B-C,D,E+F*F)G(H'I'J&J%K$L#M#N"O!O PQRSTTUVWXXYZ[\]]^_`abb c d e f f ghijkklmnoppp p p|pxquqqqmq#jq'fq*bq-_q1\q4Xq7Uq;Qq>NrAKrDHrGDrJArM>rP;rS8rV5rY2r\/r_,rb)re&sg$sj!smsosrsuswszs|s s ssssspnl j geca^\ZXV T"R$P&N(L*J,H/F0D2B4@6>8<::<8>7@5B3C1E/G.I,K*L)N'P%R#S"U WXZ[]_`bcef {w zwxwwwvvtvsvqvovnvlvkviv hv!fv#dv%cv&av(`v*^v+\v-Zv/Yv1Wv3Uv4Tv6Rv8Pv:NvKu?IuAGuCEuECuGAuI?uK=uM;uO9uQ7uS5uV3uX1uZ/u\-u^+u`)uc&ue$tg"ti tltntptstutxtzt| t tttttrpm j heb_]ZWT!Q$N'K*H-E0B3?6<99<5?2C/F+I(M%P!SWZ^be impqqqqqqqqqqq q q q q q qq~q}q|q{q{qzqyqxqwqvqvquqtq ,<KZi}xn`QC5(      #%')+-02468;=?ACFHJLNQSUWY\^`bdgi|kzmxpvrttqvoym{k}hfdb_][YWTRPMKIGDB@>;97520.+)'%"   qqqqqqqqqqponnmlkjii h g f e d d cba``_^]\[[ZYXWVVUTSRR Q P!O"N#M$M%L%K&J'I(H)H*G*F+E,D-C.C.B/A0@1?2?3>3=4<5;6:7:898897:6;5<5<4=3>2?1@1A0A/B.C-D,E,F+F*G)H(I'J'J&K%L$M#N#O"O!P QRSTTUVWXXYZ[\]]^_`abbc d e f f g hijkklmnoppqq q q{qxqtqpqlr#ir'er*br-^r1[r4Wr7Tr;Qr>MrAJrDGrGDsJAsM=sP:sS7sV4sY1s\.s_+sb)se&sg#sj smsosrtutwtzt| t tttttspnl j geca^\ZXV!T#R%P'N)L+J-H/F1D3B5@7>9<;:=8?7@5B3D1F/H.I,K*M)O'P%R#T"U WYZ\^_abdeg {w ywxwvwuwtwrwpwowmwlwjwiw gw!fw#dw%bw&aw(_v*]v+\v-Zv/Xv1Vv3Uv4Sv6Qv8Ov:NvJv?HvAFvCDvEBvGAvI?vK=vM;vO9vQ7vS5uV3uX0uZ.u\,u^*u`(uc&ue$ug!uiulunupusuuuxuzu| u uttttrpm j heb_]ZWT"Q%N(K+H.E1B4?7<:9=5@2C/G+J(M%Q!TX[_bf jmqrrrrrrrrrrr r r r r r r~r}r|r{r{rzryrxrwrvrvrurtrsr +;JYh}wn`QC5(     !$&(*,/13579<>@BDGIKMORTVX[]_acfh|jzlxovqtsquowmzk|h~fdb_][YWTRPMKIGDB@>;97520.+)'%"   rrrrrrrrrqponnmlkji i h g f e d dcba``_^]\[[ZYXWVVUTSR R Q!P"O#N$M%M%L&K'J(I)H*H*G+F,E-D.C.C/B0A1@2?3?3>4=5<6;7:8:8998:7;6<5<5=4>3?2@1A1A0B/C.D-E,F,F+G*H)I(J'J'K&L%M$N#O#O"P!Q RSTTUVWXXYZ[\]]^_`abbcd e f g g h ijkklmnoppqrr r ~r{rwrsrorlr#hr'ds*as-]s1Zs4Ws7Ss;Ps>MsAIsDFsGCsJ@sM=sP:sS7tV4tY1t\.t_+tb(te%tg"tjtmtotrtutwtzt| t uuuuuspn l j geca^\ZXV!T#R%P(N*L,J.H0F2D4B6@8>9<;:=8?7A5C3E1F/H.J,L*M)O'Q%S#T"V XY[]^`acdfg zx yxwxvxuwswrwpwnwmwkwjwhw gw!ew#cw%bw&`w(^w*]w+[w-Yw/Xw1Vw3Tw4Rw6Qw8Ow:MwIw?HwAFvCDvEBvG@vI>vK5A2D/G+K(N%Q!UX\_cg jnrrrrrrrrrrrr r r r r r ~r}r|r{r{rzryrxrwrvrvrurtrsrrr *9IXg}vn`QC5(        #%')+-02468;=?ACFHJLNQSUWY\^`beg|izkxmvptrqtovmyk{h}fdb_][YWTRPMKIGDB@>;97520.+)'%"   rrrrrrrrrqponnmlkj i i h g f e ddcba``_^]\[[ZYXWVVUTS R R!Q"P#O$N%M%M&L'K(J)I*H*H+G,F-E.D.C/C0B1A2@3?3?4>5=6<7;8:8:99:8;7<6<5=5>4?3@2A1A1B0C/D.E-F,F,G+H*I)J(J'K'L&M%N$O#O#P"Q!R STTUVWXXYZ[\]]^_`abbcde f g g h i jkklmnoppqrrs s ~szsvsrsosks#gs'ds*`s-]s1Ys4Vt7Rt;Ot>LtAItDEtGBtJ?tM:<<:>8@7A5C3E1G/I.J,L*N)P'Q%S#U"V XZ[]_`bcefh zx xxwxuxtxsxqxoxnxlxkxixhx fx!dx#cx%ax&`x(^x*\x+[w-Yw/Ww1Uw3Tw4Rw6Pw8Nw:MwIw?GwAEwCCwEAwG?wI=wK;wM9wO7wQ5wS3wU1wX/wZ-w\+w^)v`'vc%ve"vg vivlvnvpvsvuvwvzv| v vvvvurpm j heb_]ZW T#Q&N)K,H/E2B5?8<;9>5B2E/H+K(O%R!VY]`dg kossssssssssss s s s s ~s }s|s{s{szsysxswsvsvsustsssrsrs)8HWf}un`QC5(       "$&(*,/1357:<>@BDGIKMPRTVX[]_acf|hzjxlvotqqsoumxkzh|f~db_][YWTRPMKIGDB@>;97520.+)'%"   sssssssrrqponnmlk j i i h g f eddcba``_^]\[[ZYXWVVUT S R!R"Q#P$O%N%M&M'L(K)J*I*H+H,G-F.E.D/C0C1B2A3@3?4?5>6=7<8;8:9::9;8<7<6=5>5?4@3A2A1B1C0D/E.F-F,G,H+I*J)J(K'L'M&N%O$O#P#Q"R!S TTUVWXXYZ[\]]^_`abbcdef g g h i j kklmnoppqrsss s }tytutqtntjt#gt'ct*_t-\t1Xt4Ut7Rt;Nt>KuAHuDEuGAuJ>uM;uP8uS5uV2uY/u\,u_)ub&ue$ug!ujumuovrvuvwvzv| v vvvvuspn l jgeca^\ZX V"T%R'P)N+L-J/H1F3D5B7@9>;<<:>8@7B5D3F1G/I.K,M*O)P'R%T#U"W YZ\^_abdegh yy xyvyuytyrxpxoxmxlxjxixgx fx!dx#bx%ax&_x(]x*\x+Zx-Xx/Wx1Ux2Sx4Qx6Px8Nx:LxHx?FxAExCCxEAxG?xI=wK;wM9wO7wQ5wS3wU1wX/wZ-w\*w^(w`&wb$we"wg wiwlwnwpwswuwwwz w| wvvvvurp m jheb`]ZW!T$Q'N*K-H0E3B6?9<<9?5B2F/I,L(P%S!VZ]aeh lpsttttttttttt t t t ~t }t |t{t{tztytxtwtvtvtutttstrtrtqt'7GVe}sn`QC5(         #%')+.02468;=?ACFHJLNQSUWZ\^`be|gzixkvntpqrotmvkyh{f}db_][YWTRPMKIGDB@>;97520.+)'%"   ttttttsrrqponnml k j i i h g feddcba``_^]\[[ZYXWVVU T S!R"R#Q$P%O%N&M'M(L)K*J*I+H,H-G.F.E/D0C1C2B3A3@4?5?6>7=8<8;9:::;9<8<7=6>5?5@4A3A2B1C1D0E/F.F-G,H,I+J*J)K(L'M'N&O%O$P#Q#R"S!T TUVWXXYZ[\]]^_`abbcdefg g h i j k klmnoppqrsttt t |txtttqumuiu#fu'bu*_u-[u1Xu4Tu7Qu;Nu>JuAGuDDuGAuJ>uM;vP7vS4vV1vY.v\,v_)vb&ve#vg vjvmvovrvuvwvz v| vvwwwuspn l jgeca^\ZX!V#T%R'P)N+L-J/H1F3D5B7@9>;<=:?8A7C5D3F1H/J.L,M*O)Q'R%T#V"X Y[\^`acdfgi yy wyvytysyrypynymykyjyhygy ey!cy#by%`y&_y(]y*[y+Yy-Xy/Vy1Tx2Sx4Qx6Ox8Mx:KxHx?FxADxCBxE@xG>xI@BEGIKMPRTVX[]_ad|fzhxjvltoqqosmukxhzf|d~b_][YWTRPMKIGDB@>;97520.+)'%"   uuuuutsrrqponnm l k j i i h gfeddcba``_^]\[[ZYXWVV U T!S"R#R$Q%P%O&N'M(M)L*K*J+I,H-H.G.F/E0D1C2C3B3A4@5?6?7>8=8<9;::;:<9<8=7>6?5@5A4A3B2C1D1E0F/F.G-H,I,J+J*K)L(M'N'O&O%P$Q#R#S"T!T UVWXXYZ[\]]^_`abbcdefgg h i j k k lmnoppqrstuuu u {uwutupuluiu#ev'av*^v-Zv1Wv4Tv7Pv;Mv>JvAFvDCvG@vJ=vM:vP7vS4vV1vY.v\+w_(wb%we"wgwjwmwowrwuwwwz w| wwwwwusp n l jgeca^\ZX"V$T&R(P*N,L.J0H2F4D6B8@:><<>:?8A7C5E3G1I/J.L,N*P)Q'S%U#V"X Z[]_`bcefhj xz wzuztzszqzoynylykyiyhyfy ey!cy#ay%`y&^y(\y*[y+Yy-Wy/Vy1Ty2Ry4Py6Ny8My:KyGy?EyACyCByE@yG>yI;97520.+)'%"   vvvvutsrrqponn m l k j i i hgfeddcba``_^]\[[ZYXWV V U!T"S#R$R%Q%P&O'N(M)M*L*K+J,I-H.H.G/F0E1D2C3C3B4A5@6?7?8>8=9<:;;:<:<9=8>7?6@5A5A4B3C2D1E1F0F/G.H-I,J,J+K*L)M(N'O'O&P%Q$R#S#T"T!U VWXXYZ[\]]^_`abbcdefggh i j k k l mnoppqrstuuvv ~v zvwvsvovkvhv#dv'av*]v-Zv1Vw4Sw7Ow;Lw>IwAFwDBwG?wJ<<>:@8B7D5F3G1I/K.M,N*P)R'T%U#W"Y Z\]_abdeghj xz vzuzszrzpzozmzlzjzizgzfz dz!bz#az%_z&]z(\z*Zz+Xz-Wz/Uz1Sz2Qz4Pz6Nz8Ly:JyGy?EyACyCAyE?yG=yI;yK9yM7yO5yQ3yS1yU/yX-yZ+y\)y^'y`$yb"ye ygyiylynypysyuywyz y| xxxxxurp m kheb`]Z W#T&Q)N,K/H2E5B8?;<>9A6E2H/K,N(R%U!Y\`cgk nrvwwwwwwwwwww ~w }w |w {w {w zwywxwwwvwvwuwtwswrwrwqwpwownw $4CRa}pn~`QC5 (                    " $ & ( * , / 1 3 5 7 : < > @ B E G I K M P R T V X [ ] _ a| dz fx hv jt mq oo qm sk uh xf zd |b ~_ ] [ Y W T R P M K I G D B @ > ;97520.+)'%"   wwwvutsrrqpon n m l k j i ihgfeddcba``_^]\[[ZYXW V V!U"T#S$R%R%Q&P'O(N)M*M*L+K,J-I.H.H/G0F1E2D3C3C4B5A6@7?8?8>9=:<;;<:<:=9>8?7@6A5A5B4C3D2E1F1F0G/H.I-J,J,K+L*M)N(O'O'P&Q%R$S#T#T"U!V WXXYZ[\]]^_`abbcdefgghi j k k l m noppqrstuuvww }w zwvwrwnwkwgw#cw'`w*\w-Yw1Uw4Rw7Ow;Kw>HwAExDBxG?xJ;xM8xP5xS2xV/xY,x\)x_'xb$xe!xgxjxmxoxrxuxwxz x| xxxyxusp n ljgeca^\Z!X#V%T'R)P+N-L/J1H3F5D7B9@;>=zG=zI;zK9zM7zO5zQ3zS0zU.zX,zZ*z\(z^&z`$zb"yeygyiylynypysyuyw yz y|yyyyxur p mkheb`]Z!W$T'Q*N,K/H2E6B9?<!;!9!7!5!2!0!.!+!)!'!%!"! !!!!!!!!!    wwwvutsrrqpo n n m l k j iihgfeddcba``_^]\[[ZYX W V!V"U#T$S%R%R&Q'P(O)N*M*M+L,K-J.I.H/H0G1F2E3D3C4C5B6A7@8?8?9>:=;<<;<:=:>9?8@7A6A5B5C4D3E2F1F1G0H/I.J-J,K,L+M*N)O(O'P'Q&R%S$T#T#U"V!W XXYZ[\]]^_`abbcdefgghij k k l m n oppqrstuuvwww }x yxuxqxnxjxfx#cx'_x*\x-Xx1Ux4Qx7Nx;Kx>GxADxDAxG>xJ;xM8xP5xS2yV/yY,y\)y_&yb#ye ygyjymyoyryuyw yz y|yyyyxusp n ljgeca^\Z!X#V%T(R*P,N.L0J2H4F6D8B:@;>=zG"@"B"E"G"I"K"M"P"R"T"V"Y"["]"_|"az"dx"fv"ht"jq"mo"om"qk"sh"vf"xd"zb"|_"]"["Y"W"T"R"P"M"K"I"G"D"B"@">";"9"7"5"2"0"."+")"'"%""" """"""""" " """""xwwvutsrrqp o n n m l k jiihgfeddcba``_^]\[[ZY X W!V"V#U$T%S%R&R'Q(P)O*N*M+M,L-K.J.I/H0H1G2F3E3D4C5C6B7A8@8?9?:>;=<<<;=:>:?9@8A7A6B5C5D4E3F2F1G1H0I/J.J-K,L,M+N*O)O(P'Q'R&S%T$T#U#V"W!X XYZ[\]]^_`abbcdefgghijk k l m n o ppqrstuuvwxxx |x xxtxpxmyiyey#by'^y*[y-Wy1Ty4Qy7My;Jy>GyACyD@yG=yJ:yM7yP4yS1yV.yY+y\(y_%yb"yeygyjymzozrzuzw zz z|zzzzxus p nljgeca^\ Z"X$V&T(R*P,N.L0J2H4F6D8B:@<>><@:B8D7E5G3I1K/M.N,P*R)S'U%W#Y"Z \]_abdeghjl v| u|s|r|p|o|m|l|j|i{g{f{d{ b{!a{#_{%^{&\{(Z{*Y{+W{-U{/S{1R{2P{4N{6L{8J{:I{#;#9#7#5#2#0#.#+#)#'#%#"# ######### # #####xwwvutsrrq p o n n m l kjiihgfeddcba``_^]\[[Z Y X!W"V#V$U%T%S&R'R(Q)P*O*N+M,M-L.K.J/I0H1H2G3F3E4D5C6C7B8A8@9?:?;><=<<=;>:?:@9A8A7B6C5D5E4F3F2G1H1I0J/J.K-L,M,N+O*O)P(Q'R'S&T%T$U#V#W"X!X YZ[\]]^_`abbcdefgghijkk l m n o p pqrstuuvwxyyy {y wysypylyhyey#ay'^y*Zy-Wz1Sz4Pz7Lz;Iz>FzACzD@zG?<@:B8D7F5H3J1K/M.O,Q*R)T'V%W#Y"[ \^`acdfgikl v| t|s|q|p|n|m|k|j|h|g|e|d| b|!`|#_|%]|&[|(Z|*X|+V|-U|/S|1Q|2O|4N|6L|8J|:H|#N$]}$kn$z`$Q$C$5$($$ $$"      "$$$$$ $ $$$$$$$$$$"$$$&$($*$-$/$1$3$5$7$:$<$>$@$B$E$G$I$K$N$P$R$T$V$Y$[$]|$_z$ax$dv$ft$hq$jo$mm$ok$qh$sf$vd$xb$z_$|]$[$Y$W$T$R$P$M$K$I$G$D$B$@$>$;$9$7$5$2$0$.$+$)$'$%$"$ $$$$$$$$$ $ $$$$$xwwvutsrr q p o n n m lkjiihgfeddcba``_^]\[[ Z Y!X"W#V$V%U%T&S'R(R)Q*P*O+N,M-M.L.K/J0I1H2H3G3F4E5D6C7C8B8A9@:?;?<><==<>;?:@:A9A8B7C6D5E5F4F3G2H1I1J0J/K.L-M,N,O+O*P)Q(R'S'T&T%U$V#W#X"Y!Y Z[\]]^_`abbcdefgghijkkl m n o p p qrstuuvwxyyz~z zz vzszozkzgzdz#`z']z*Yz-Vz1Rz4Oz7Lz;Hz>EzABzD?{G<{J9{M5{P2{S/{V,{Y){\'{_${b!{e{g{j{m{o{r{u{w {z {|{{{zxus p nljgeca^\!Z#X%V'T)R+P-N/L1J3H5F7D9B;@=>?|E<|G:|I8|K6|M4|O2|Q0|S.|U,|W*|Z(|\&|^$|`!|b|e|g|i|k|n|p|s|u |w |z|||||zxu s pmkhec`]!Z$W&T)R,O/L2I5F8B;??%;%9%7%5%2%0%.%+%)%'%%%"% %%%%%%%%% % %%%%%xwwvutsr r q p o n n mlkjiihgfeddcba``_^]\[ [ Z!Y"X#W$V%V%U&T'S(R)R*Q*P+O,N-M.M.L/K0J1I2H3H3G4F5E6D7C8C8B9A:@;?==>D{AA{D>{G;{J8{M5{P2{S/{V,{Y){\&{_#{b {e|g|j|m|o|r|u |w |z|||||zxus p nljgeca^\!Z$X&V(T*R,P.N0L2J4H6F8D:B<@>>@}E<}G:}I8}K6}M4}O2}Q0}S.}U+}W)}Z'}\%}^#}`!}b}e}g}i}k}n|p|s|u |w |z|||||zxu s pmkhec`]!Z$W'T*R-O0L3I6F9B&@&C&E&G&I&K&N&P&R&T&V&Y&[|&]z&_x&bv&dt&fq&ho&jm&mk&oh&qf&sd&vb&x_&z]&|[&Y&W&T&R&P&M&K&I&G&D&B&@&>&;&9&7&5&2&0&.&+&)&'&%&"& &&&&&&&&& & &&&&&xwwvuts r r q p o n nmlkjiihgfeddcba``_^]\ [ [!Z"Y#X$W%V%V&U'T(S)R*R*Q+P,O-N.M.M/L0K1J2I3H3H4G5F6E7D8C8C9B:A;@>=?<@;A:A:B9C8D7E6F5F5G4H3I2J1J1K0L/M.N-O,O,P+Q*R)S(T'T'U&V%W$X#Y#Y"Z![ \]]^_`abbcdefgghijkklmn o p p q r stuuvwxyyz{|}| y| u|q|m|j|f|b|#_|'[|*X|-T|1Q|4N|7J|;G|>D|A@|D=|G:|J7|M4|P1|S.|V+|Y(|\%|_"|b|e|g|j|m|o|r|u |w |z|||||zxu s pnljgeca^ \"Z$X&V(T+R-P/N1L3J5H7F9D;B<@>>@';'9'7'5'2'0'.'+')'''%'"' ''''''''' ' '''''xwwvut s r r q p o nnmlkjiihgfeddcba``_^] \ [!["Z#Y$X%W%V&V'U(T)S*R*R+Q,P-O.N.M/M0L1K2J3I3H4H5G6F7E8D8C9C:B;A<@>?=@C}A@}D=}G9}J6}M3}P0}S-}V*}Y'}\$}_"}b}e}g}j}m}o}r}u }w }z}|}}}zxu s pnljgeca^!\#Z%X'V)T+R-P/N1L3J5H7F9D;B=@?>A~C<~E:~G9~I7~K5~M3~O1~Q.~S,~U*~W(~Z&~\$~^"~` ~b~e~g~i~k~n~p~r ~u ~w~z~|~~}zxu s pmkhec` ]#Z&W(U+R.O1L4I7F:C>?A(@(C(E(G(I(K(N(P(R(T(V(Y|([z(]x(_v(bt(dq(fo(hm(kk(mh(of(qd(sb(v_(x](z[(|Y(W(T(R(P(M(K(I(G(D(B(@(>(;(9(7(5(2(0(.(+()('(%("( ((((((((( ( (((((xwwvu t s r r q p onnmlkjiihgfeddcba``_^ ] \!["[#Z$Y%X%W&V'V(U)T*S*R+R,Q-P.O.N/M0M1L2K3J3I4H5H6G7F8E8D9C:C;B??>@=AB}A?}D<}G9}J6}M3}P0}S-~V*~Y'~\$~_!~b~e~g~j~m~o~r~u ~w ~z~|~~}zxu s pnljgeca^!\#Z%X(V*T,R.P0N2L4J6H8F:D@?>AC<~E:~G8~I6~K4~M2~O0~Q.~S,~U*~W(~Z%~\#~^!~`~b~e~g~i~k~n~p~r ~u ~w~z~|~~}zx u spmkhec`!]#Z&W)U,R/O2L5I8F;C>?A);)9)7)5)2)0).)+)))')%)") ))))))))) ) )))))xwwv u t s r r q ponnmlkjiihgfeddcba``_ ^ ]!\"[#[$Z%Y%X&W'V(V)U*T*S+R,R-Q.P.O/N0M1M2L3K3J4I5H6H7G8F8E9D:C;C???@>A=AA~A>~D;~G8~J5~M2~P/~S,~V)~Y&~\#~_ ~b~e~g~j~m~o~r ~u ~w~z~|~~}zx u s pnljgeca ^"\$Z&X(V*T,R.P0N2L4J6H8F:D<B>@@>B*@*C*E*G*I*K*N*P*R*T*W|*Yz*[x*]v*_t*bq*do*fm*hk*kh*mf*od*qb*t_*v]*x[*zY*}W*T*R*P*M*K*I*G*D*B*@*>*;*9*7*5*2*0*.*+*)*'*%*"* ********* * *****xww v u t s r rqponnmlkjiihgfeddcba`` _ ^!]"\#[$[%Z%Y&X'W(V)V*U*T+S,R-R.Q.P/O0N1M2M3L3K4J5I6H7H8G8F9E:D;C<C<B=A>@??@?A>A=BAA>D:G7J4M1P.S+V(Y%\"_ begjmor u wz|}zx u spnljgeca ^"\$Z'X)V+T-R/P1N3L5J7H9F;D=B?@A>B,;,9,7,5,2,0,.,+,),',%,", ,,,,,,,,, , ,,,,,~x~w ~w ~v ~u ~t ~s ~r~r~q~p~o~n~n~m~l~k~j~i~i~h~g~f~e~d~d~c~b~a~` ~` ~_!~^"~]#~\$~[%~[%~Z&~Y'~X(~W)~V*~V*~U+~T,~S-~R.~R.~Q/~P0~O1~N2~M3~M3~L4~K5~J6~I7~H8~H8~G9~F:~E;~D<~C<~C=~B>~A?~@@~?A~?A~>B~=C~@A=D:G7J3M0P-S*V'Y%\"_begjmor u wz|~~}~z~x ~u ~s~p~n~l~j~g~e~c~a!~^#~\%~Z'~X)~V+~T-~R0~P2~N4~L6~J8~H:~F;~D=~B?~@A~>C~A-@-C-E-G-I-L-N-P-R-T|-Wz-Yx-[v-]t-_q-bo-dm-fk-hh-kf-md-ob-q_-t]-v[-xY-zW-}T-R-P-M-K-I-G-D-B-@->-;-9-7-5-2-0-.-+-)-'-%-"- --------- - -----~x ~w ~w ~v ~u ~t ~s~r~r~q~p~o~n~n~m~l~k~j~i~i~h~g~f~e~d~d~c~b~a ~` ~`!~_"~^#~]$~\%~[%~[&~Z'~Y(~X)~W*~V*~V+~U,~T-~S.~R.~R/~Q0~P1~O2~N3~M3~M4~L5~K6~J7~I8~H8~H9~G:~F;~E<~D<~C=~C>~B?~A@~@A~?A~?B~>C~=D~?A~B@~@B~>D~}CA}@D}.;.9.7.5.2.0...+.).'.%.". ......... . ..... }x }w }w }v }u }t}s}r}r}q}p}o}n}n}m}l}k}j}i}i}h}g}f}e}d}d}c}b }a }`!}`"}_#}^$}]%}\%}[&}['}Z(}Y)}X*}W*}V+}V,}U-}T.}S.}R/}R0}Q1}P2}O3}N3}M4}M5}L6}K7}J8}I8}H9}H:}G;}F<}E<}D=}C>}C?}B@}AA}@A}?B}?C}>D}=E}>A;D8G5J2M/P,S)V&Y#\ _begjmo r uwz|}}}}z }x }u}s}p}n}l}j}g}e}c }a"}^$}\&}Z(}X+}V-}T/}R1}P3}N5}L7}J9}H;}F=}D?}B@}@B}>D}/A/C/E/G/I/L/N/P/R|/Tz/Wx/Yv/[t/]q/`o/bm/dk/fh/hf/kd/mb/o_/q]/t[/vY/xW/zT/}R/P/M/K/I/G/D/B/@/>/;/9/7/5/2/0/./+/)/'/%/"/ ///////// / ///// |x |w |w |v |u|t|s|r|r|q|p|o|n|n|m|l|k|j|i|i|h|g|f|e|d|d|c |b |a!|`"|`#|_$|^%|]%|\&|['|[(|Z)|Y*|X*|W+|V,|V-|U.|T.|S/|R0|R1|Q2|P3|O3|N4|M5|M6|L7|K8|J8|I9|H:|H;|G<|F<|E=|D>|C?|C@|BA|AA|@B|?C|?D|>E|=F|>A;D7G4J1M.P+S(V%Y"\ _begjmo r uwz|||}|z |x |u|s|p|n|l|j|g|e|c }a#}^%}\'}Z)}X+}V-}T/}R1}P3}N5}L7}J9}H;}F=}D?}BA}@C}>E}?0;09070502000.0+0)0'0%0"0 000000000 0 00000 {x {w {w {v{u{t{s{r{r{q{p{o{n{n{m{l{k{j{i{i{h{g{f{e{d{d {c {b!{a"{`#{`${_%{^%{]&{\'{[({[){Z*{Y*{X+{W,{V-{V.{U.{T/{S0{R1{R2{Q3{P3{O4{N5{M6{M7{L8{K8{J9{I:{H;{H<{G<{F={E>{D?{C@{CA{BA{AB{@C{?D{?E{>F{=F{=A:D7G4J1M.P+S(V%Y"\_begjmo r uwz|||}|z |x |u|s|p|n|l|j|g|e|c!|a#|^%|\(|Z*|X,|V.|T0|R2|P4|N6|L8|J:|H<|F>|D@|BB|@C|>E|?1A1C1E1G1I1L1N1P|1Rz1Tx1Wv1Yt1[q1]o1`m1bk1dh1ff1id1kb1m_1o]1r[1tY1vW1xT1zR1}P1M1K1I1G1D1B1@1>1;19171512101.1+1)1'1%1"1 111111111 1 11111 zx zw zwzvzuztzszrzrzqzpzoznznzmzlzkzjzizizhzgzfzezd zd zc!zb"za#z`$z`%z_%z^&z]'z\(z[)z[*zZ*zY+zX,zW-zV.zV.zU/zT0zS1zR2zR3zQ3zP4zO5zN6zM7zM8zL8zK9zJ:zI;zHzE?zD@zCAzCAzBBzACz@Dz?Ez?Fz>Fz=Gz{D@{BB{@D|>F|zFAzCDz@Gz=Jz9Mz6Qz3Tz0Wz,[z)^z&bz"ezizlzpztzxz {y yyyxwvvutsrrq p o n m m lkjiihgfeedcba`2 "33 3/2?2N}2]n2k`2zQ2C252(22 220.,*' % #!"$ & (*,.12222 2 2 222222222!2#2%2'2*2,2.20222427292;2=2?2B2D2F2H2K2M2O|2Qz2Sx2Vv2Xt2Zq2\o2_m2ak2ch2ef2gd2jb2l_2n]2p[2sY2uW2wT2yR2|P2~M2K2I2G2D2B2@2>2;29272522202.2+2)2'2%2"2 222222222 2 22222 yx ywywyvyuytysyryryqypyoynynymylykyjyiyiyhygyfye yd yd!yc"yb#ya$y`%y`%y_&y^'y](y\)y[*y[*yZ+yY,yX-yW.yV.yV/yU0yT1yS2yR3yR3yQ4yP5yO6yN7yM8yM8yL9yK:yJ;yIyF?yE@yDAyCAyCByBCyADy@Ey?Fy?Fy>Gy=HyF{==?;A9C7E5G3I1K/M-O+Q)S'U$W"Y \^`bdgikn p ruwzzzz} z{ zxzvzszpznzkzhzf!yc$y`'y])y[,yX/yU2yR5yO8yL;yI>yFAyCEy@Hy=Ky9Ny6Qy3Uy0Xy,\y)_y&cy"fyjymyqyuyxy |y yyxwvvutsrrqp o n m m l kjiihgfeedcba``3""344.4>4M}4\n3j`3yQ3C353(33 331/-+( & $" "$ & (*,.133333 3 333333333 3"3$3&3(3+3-3/313336383:3<3>3A3C3E3G3I3L3N|3Pz3Rx3Uv3Wt3Yq3[o3]m3`k3bh3df3fd3ib3k_3m]3o[3rY3tW3vT3xR3{P3}M3K3I3G3D3B3@3>3;39373532303.3+3)3'3%3"3 333333333 3 33333 yxywywyvyuytysyryryqypyoynynymylykyjyiyiyhygyf ye yd!yd"yc#yb$ya%y`%y`&y_'y^(y])y\*y[*y[+yZ,yY-yX.yW.yV/yV0yU1yT2yS3yR3yR4yQ5yP6yO7yN8yM8yM9yL:yK;yJyG?yF@yEAyDAyCByCCyBDyAEy@Fy?Fy?Gy>Hy=Iy>;A8D4G1J.M+P(S%V"Y \_begjm o ruwzzzz} zz zxzuzszpznzlzjzgze!zc#za%z^'z\)zZ+zX.zV0zT2zR4zP6zN8zL:zJzF?zDAzBCz@Ez>Gz=4;49474542404.4+4)4'4%4"4 444444444 4 44444xxxwxwxvxuxtxsxrxrxqxpxoxnxnxmxlxkxjxixixhxg xf xe!xd"xd#xc$xb%xa%x`&x`'x_(x^)x]*x\*x[+x[,xZ-xY.xX.xW/xV0xV1xU2xT3xS3xR4xR5xQ6xP7xO8xN8xM9xM:xL;xKxH?xG@xFAxEAxDBxCCxCDxBExAFx@Fx?Gx?Hx>Ix=Jx:A7D4G1J.M+P(S%V"Y\_begjm o ruwyyyy} yz yxyuysypynylyjygye!yc$ya&y^(y\*yZ,zX.zV0zT2zR4zP6zN8zL:zJzF@zDBzBDz@Fz>Hz5A5C5E5G5I5L|5Nz5Px5Rv5Ut5Wq5Yo5[m5]k5`h5bf5dd5fb5i_5k]5m[5oY5rW5tT5vR5xP5{M5}K5I5G5D5B5@5>5;59575552505.5+5)5'5%5"5 555555555 5 55566wxwwwwwvwuwtwswrwrwqwpwownwnwmwlwkwjwiwiwh wg wf!we"wd#wd$wc%wb%wa&w`'w`(w_)w^*w]*w\+w[,w[-wZ.wY.wX/wW0wV1wV2wU3wT3wS4wR5wR6wQ7wP8wO8wN9wM:wM;wLwH?wH@wGAwFAwEBwDCwCDwCEwBFwAFw@Gw?Hw?Iw>Jw=Kw9A6D3G0J-M*P'S$V!Y\_begjm oruwxxxx} yz yxyuysypynylyjyg ye"yc$ya&y^(y\+yZ-yX/yV1yT3yR5yP7yN9yL;yJ=yH?yFAyDCyBDy@Fy>Hy6;69777572707.7+7)7'7%7"7 777777777 7 77777vxvwvwvvvuvtvsvrvrvqvpvovnvnvmvlvkvjvivi vh vg!vf"ve#vd$vd%vc%vb&va'v`(v`)v_*v^*v]+v\,v[-v[.vZ.vY/vX0vW1vV2vV3vU3vT4vS5vR6vR7vQ8vP8vO9vN:vM;vMvI?vH@vHAvGAvFBvECvDDvCEvCFvBFvAGv@Hv?Iv?Jv>Kv=Kv9A5D2G/J,M)P&S#V Y\_begj m oruwxxx x} xzxxxuxsxpxnxlxjxg xe#xc%xa'x^)x\+xZ-xX/xV1xT3xR5xP7xN9xL;yJ=yH?yFAyDCyBEy@Gy>Iy;<=:?8A6C5E3G1I/K-M*O(Q&S$U"W Y\^`bdgik n pruwwww w} w{wxwvwswpwnwkwi!wf$wc&w`)w^,w[/wX2wU5vR8vO;vL>vIAvFDvCGv@Kv=Nv:Qv6Tv3Xv0[v,^v)bv&ev"ivmvpvtvxv{u u uuutsrrqponmm l k j i i hgfeedcba``_^]\8'"3 88*898H}8Wn8f`8tQ8C858(77 77531/- + (&$" "$&( * ,.13577777 7 777777777 7"7$7&7)7+7-7/717376787:7<7>7A7C7E7G7J|7Lz7Nx7Pv7Rt7Uq7Wo7Ym7[k7^h7`f8bd8db8f_8i]8k[8mY8oW8rT8tR8vP8xM8{K8}I8G8D8B8@8>8;89878582808.8+8)8'8%8"8 888888888 8 88888uxuwuwuvuuutusururuqupuoununumulukujui ui uh!ug"uf#ue$ud%ud%uc&ub'ua(u`)u`*u_*u^+u],u\-u[.u[.uZ/uY0uX1uW2uV3uV3uU4uT5uS6uR7uR8uQ8uP9uO:uN;uMuJ?uI@uHAuHAuGBuFCuEDuDEuCFuCFuBGuAHu@Iu?Ju?Ku>Ku=Lu;;>8A5D2G.J+M(P%S#V Y\_begj m oruwwww w} wzwxwuwswpwnwlwjwg!xe#xc%xa(x^*x\,xZ.xX0xV2xT4xR6xP8xN:xLxH@xFBxDDxBFx@Gx>Ix;<=:?8A6C4E2G0I.K,M*O(Q&S$U!WY\^`bdgi k n pruwwwv v} v{vxvvvsvpvnvkvi"vf$vc'v`*v^-v[0vX3vU6vR9vO9;99979592909.9+9)9'9%9"9 999999999 9 99999txtwtwtvtutttstrtrtqtptotntntmtltktj ti ti!th"tg#tf$te%td%td&tc'tb(ta)t`*t`*t_+t^,t]-t\.t[.t[/tZ0tY1tX2tW3tV3tV4tU5tT6tS7tR8tR8tQ9tP:tO;tNtK?tJ@tIAtHAtHBtGCtFDtEEtDFtCFtCGtBHtAIt@Jt?Kt?Kt>Lt=Mt7A4D1G.J+M(P%S"VY\_begj m oruvvvv w} wzwxwuwswpwnwlwjwg"we$wc&wa(w^*w\,wZ.wX1wV3wT5wR7wP9wN;wL=wJ?wH@wFBwDDwBFw@Hx>Jx:;:9:7:5:2:0:.:+:):':%:": ::::::::: : :::::txtwtwtvtutttstrtrtqtptotntntmtltk tj ti!ti"th#tg$tf%te%td&td'tc(tb)ta*t`*t`+t_,t^-t].t\.t[/t[0tZ1tY2tX3tW3tV4tV5tU6tT7tS8tR8tR9tQ:tP;tOtL?tK@tJAtIAtHBtHCtGDtFEtEFtDFtCGtCHtBItAJt@Kt?Kt?Lt>Mt=Nt6A3D0G-J*M'P$S!VY\_begj moruvvv v v} vzvxvuvsvpvnvlvj vg"ve$vc'va)v^+v\-vZ/wX1wV3wT5wR7wP9wN;wL=wJ?wHAwFCwDEwBGw@Iw>Jw9<;;=9?7A5C3E1G/I-K+M)O'Q%S"U WY\^`bdgi k npruuuu u u}u{uxuvusuqunuk ui#uf&uc(u`+u^.t[1tX4tU7tR:tO=tL@tICtFFtCIt@Mt=Pt:St6Wt3Zt0]t-at)dt&hs"ksosrsvszs~s s ssrrqponmmlkj i i h g f eedcba``_^]\\[Z;*" 3<<&<6;;;9;7;5;2;0;.;+;);';%;"; ;;;;;;;;; ; ;;;;;sxswswsvsustsssrsrsqspsosnsnsmsl sk sj!si"si#sh$sg%sf%se&sd'sd(sc)sb*sa*s`+s`,s_-s^.s].s\/s[0s[1sZ2sY3sX3sW4sV5sV6sU7sT8sS8sR9sR:sQ;sPsM?sL@sKAsJAsIBsHCsHDsGEsFFsEFsDGsCHsCIsBJsAKs@Ks?Ls?Ms>Ns=Os6A2D/G,J)M&P#S VY\_beg j moruuuu u u}uzuxuuusupunvlvj!vg#ve%vc'va)v^+v\.vZ0vX2vV4vT6vR8vP:vNvJ@vHBvFDvDEvBGv@Iv>Kv9<;:=8?6A4C2E0G.I,K*M(O&Q$S"U WY\^`bdgi k npruuuu u t}t{txtvtstqtntk!ti$tf&tc)t`,t^/t[2tX5tU8tR;tO>tLAsIDsFGsCJs@Ms=Qs:Ts7Ws3[s0^s-as)es&hs"lspssrwr{r~r r rrrqponmmlkji i h g f e edcba``_^]\\[ZY<+" 3==%=5=D}=Sn<;<9<7<5<2<0<.<+<)<'<%<"< <<<<<<<<< < <<<<<rxrwrwrvrurtrsrrrrrqrprornrnrm rl rk!rj"ri#ri$rh%rg%rf&re'rd(rd)rc*rb*ra+r`,r`-r_.r^.r]/r\0r[1r[2rZ3rY3rX4rW5rV6rV7rU8rT8rS9rR:rR;rQrM?rM@rLArKArJBrICrHDrHErGFrFFrEGrDHrCIrCJrBKrAKr@Lr?Mr?Nr>Or=Or7;;8>5A2D/G,J)M&P#S VY\_beg j mortttt u u}uzuxuuusupunuluj!ug#ue&uc(ua*u^,u\.uZ0uX2uV4uT6uR8uP:vNvJ@vHBvFDvDFvBHv@Jv>LvsLAsIEsFHsCKs@Nr=Qr:Ur7Xr3[r0_r-br)fr&ir"mrprtrxr{rq q qqqponmmlkjii h g f e e dcba``_^]\\[ZYX>-" 3>>$>3>C}>Rn>``=oQ=}C=5=(== =<:8642 0 .,)'%#!"$&(*,. 1 3579;==== = = =========!=#=%=(=*=,=.=0=2=5=7=9=;=>=@=B=D|=Fz=Ix=Kv=Mt=Oq=Qo=Tm=Vk=Xh=Zf=]d=_b=a_=c]=f[=hY=jW=lT=nR=qP=sM=uK=xI=zG=|D=~B=@=>=;=9=7=5=2=0=.=+=)='=%="= ========= = =====qxqwqwqvquqtqsqrqrqqqpqoqnqn qm ql!qk"qj#qi$qi%qh%qg&qf'qe(qd)qd*qc*qb+qa,q`-q`.q_.q^/q]0q\1q[2q[3qZ3qY4qX5qW6qV7qV8qU8qT9qS:qR;qRqN?qM@qMAqLAqKBqJCqIDqHEqHFqGFqFGqEHqDIqCJqCKqBKqALq@Mq?Nq?Oq>Oq=Pq7:;7>4A1D.G+J(M%P"SVY\_beg j mortttt t t}tztxtutstptntl tj"tg$te&tc(ua+u^-u\/uZ1uX3uV5uT7uR9uP;uN=uL?uJAuHCuFEuDGuBHu@Ju>Lu|C>5>(>> >>;9753 1 /-+(&$" "$&(*,. 1 3579;>>>>> > >>>>>>>>> >">$>&>)>+>->/>1>4>6>8>:><>?>A>C|>Ez>Gx>Jv>Lt>Nq>Po>Sm>Uk>Wh>Yf>[d>^b>`_>b]>d[>gY>iW>kT>mR>pP>rM>tK>vI>yG>{D>}B>@>>>;>9>7>5>2>0>.>+>)>'>%>"> >>>>>>>>> > >>>>>pxpwpwpvpuptpsprprpqpppopn pn pm!pl"pk#pj$pi%pi%ph&pg'pf(pe)pd*pd*pc+pb,pa-p`.p`.p_/p^0p]1p\2p[3p[3pZ4pY5pX6pW7pV8pV8pU9pT:pS;pRpO?pN@pMApMApLBpKCpJDpIEpHFpHFpGGpFHpEIpDJpCKpCKpBLpAMp@Np?Op?Op>Pp=Qp3A0D-G*J'M$P!SVY\_be g jmorsss s ss}szsxsusstptntl tj#tg%te'tc)ta+t^-t\/tZ1tX4tV6tT8tR:tPtL@tJAtHCuFEuDGuBIu@Ku>Mu8<9:;8=6?5A3C1E/G-I+K(M&O$Q"S UWY[^`bdg i kmprsss s ss}r{rxrvrsrqrn rk#ri&rf(rc+ra.r^1r[4rX7rU:qR=qO@qLCqIFqFIqCLq@Oq=Sq:Vq7Yq3]q0`q-dp)gp&kp#nprpupyp}pp p pponmmlkjiihg f e e d c ba``_^]\\[ZYXWW@/" 3AA"@1@@}@On@^`@mQ@{C?5?(?? ??=:864 2 0.,)'%#!"$&(*,.1 3 579;>???? ? ? ?????????!?#?%?(?*?,?.?0?3?5?7?9?;?>?@?B|?Dz?Fx?Iv?Kt?Mq?Oo?Qm?Tk?Vh?Xf?Zd?]b?__?a]?c[?fY?hW?jT?lR?oP?qM?sK?uI?xG?zD?|B?~@?>?;?9?7?5?2?0?.?+?)?'?%?"? ????????? ? ?????oxowowovouotosororoqopoo on on!om"ol#ok$oj%oi%oi&oh'og(of)oe*od*od+oc,ob-oa.o`.o`/o_0o^1o]2o\3o[3o[4oZ5oY6oX7oW8oV8oV9oU:oT;oSoP?oO@oNAoMAoMBoLCoKDoJEoIFoHFoHGoGHoFIoEJoDKoCKoCLoBMoANo@Oo?Oo?Po>Qo=Ro3A/D,G)J&M#P SVY\_be g jmorrrr r ss}szsxsussspsnsl!sj#sg%se(sc*sa,s^.s\0sZ2sX4tV6tT8tR:tPtL@tJBtHDtFFtDHtBJt@Kt>Mt;975 3 1/-+(&$" "$&(*,.1 3 579;>@@@@@ @ @@@@@@@@@ @"@$@&@)@+@-@/@1@4@6@8@:@<@?@A|@Cz@Ex@Hv@Jt@Lq@No@Pm@Sk@Uh@Wf@Yd@\b@^_@`]@b[@dY@gW@iT@kR@mP@pM@rK@tI@vG@yD@{B@}@@>@;@9@7@5@2@0@.@+@)@'@%@"@ @@@@@@AAA A AAAAAoxowowovouotosororoqop oo on!on"om#ol$ok%oj%oi&oi'oh(og)of*oe*od+od,oc-ob.oa.o`/o`0o_1o^2o]3o\3o[4o[5oZ6oY7oX8oW8oV9oV:oU;oToQ?oP@oOAoNAoMBoMCoLDoKEoJFoIFoHGoHHoGIoFJoEKoDKoCLoCMoBNoAOo@Oo?Po?Qo>Ro=So2A/D,G)J&M#P SVY\_be g jmorrrr r rr}rzrxrursrprnrl"rj$rg&se(sc*sa,s^/s\1sZ3sX5sV7sT9sR;sP=sN?sLAsJCsHEsFFsDHsBJs@Lt>NtpOApLDpIGpFJpCNp@Qo=To:Wo7[o3^o0bo-eo)io&lo#posown{n~nn n nnmmlkjiihgfe e d c b a ``_^]\\[ZYXWWVUC1 "3CCC/B>}BMnB\`BjQByCB5A(AA AA?=:86 4 20.,)'%#!"$&(*,.13 5 79;>@AAAA A A AAAAAAAAA!A#A%A(A*A,A.A0A3A5A7A9A;A>A@|ABzADxAFvAItAKqAMoAOmARkAThAVfAXdAZbA]_A_]Aa[AcYAfWAhTAjRAlPAoMAqKAsIAuGAxDAzBA|@A~>A;A9A7A5A2A0A.B+B)B'B%B"B BBBBBBBBB B BBBBBnxnwnwnvnuntnsnrnrnq np no!nn"nn#nm$nl%nk%nj&ni'ni(nh)ng*nf*ne+nd,nd-nc.nb.na/n`0n`1n_2n^3n]3n\4n[5n[6nZ7nY8nX8nW9nV:nV;nUnR?nQ@nPAnOAnNBnMCnMDnLEnKFnJFnIGnHHnHInGJnFKnEKnDLnCMnCNnBOnAOn@Pn?Qn?Rn>Sn=Tn4;77;4>1A.D+G(J%M"PSVY\_be g jmoqqqq q qq}qzqxqursrprn rl"rj$rg're)rc+ra-r^/r\1rZ3rX5rV7rT9rR;rP=sN?sLAsJCsHEsFGsDIsBKs@Ms>Ns6<8;99;7=5?3A1C/E-G+I)K'M%O#Q SUWY[^`bd g ikmpqqqq q qq}p{pxpvpspqpn"pl%pi'pf*pc-pa0p^3p[6oX9oU<97 5 31/-+(&$" "$&(*,.13 5 79;>@BBBBB B BBBBBBBBB B"B$B'B)B+B-B/B1B4B6B8B:B=B?|BAzBCxBEvBHtBJqBLoBNmBPkBShBUfBWdBYbB\_B^]B`[BbYBeWBgTBiRBkPBnMBpKBrIBtGCwDCyBC{@C}>C;C9C7C5C2C0C.C+C)C'C%C"C CCCCCCCCC C CCCCCmxmwmwmvmumtmsmrmr mq mp!mo"mn#mn$mm%ml%mk&mj'mi(mi)mh*mg*mf+me,md-md.mc.mb/ma0m`1m`2m_3m^3m]4m\5m[6m[7mZ8mY8mX9mW:mV;mVmR?mR@mQAmPAmOBmNCmMDmMEmLFmKFmJGmIHmHImHJmGKmFKmELmDMmCNmCOmBOmAPm@Qm?Rm?Sm>Tm=Tm0A-D*G'J$M!PSVY\_b e gjmoppp p qqq}qzqxquqsqpqn!ql#qj%qg'qe)qc,qa.q^0r\2rZ4rX6rV8rT:rRrN@rLBrJDrHFrFHrDIrBKr@Mr>Or6<8:98;6=4?2A0C.E,G*I(K&M$O"Q SUWY[^`bd g ikmpppp p ppp}p{pxpvpspq on#ol%oi(of+oc.oa1o^4o[6oX9oU@BCCCC C C CCCCCCCCC!C#C%C(C*C,C.C0C3C5C7C9C;C>|C@zCBxCDvCFtCIqCKoCMmCOkCRhCTfCVdCXbC[_C]]C_[DaYDcWDfTDhRDjPDlMDoKDqIDsGDuDDxBDz@D|>D~;D9D7D5D2D0D.D+D)D'D%D"D DDDDDDDDD D DDDDDlxlwlwlvlultlslr lr lq!lp"lo#ln$ln%lm%ll&lk'lj(li)li*lh*lg+lf,le-ld.ld.lc/lb0la1l`2l`3l_3l^4l]5l\6l[7l[8lZ8lY9lX:lW;lVlS?lR@lRAlQAlPBlOClNDlMElMFlLFlKGlJHlIIlHJlHKlGKlFLlEMlDNlCOlCOlBPlAQl@Rl?Sl?Tl>Tl=Ul0A-D)G&J#M!PSVY\_b e gjmoppp p ppp}pzpxpupspppn!pl#qj&qg(qe*qc,qa.q^0q\2qZ5qX7qV9qT;qR=qP?qN@qLBqJDrHFrFHrDJrBLr@Nr>Pr<9 7 531/-+(&$"" $&(*,.135 7 9;>@BDDDDD D DDDDDDDDD D"D$D'D)D+D-D/D2D4D6D8D:D=|D?zDAxDCvDEtDHqDJoELmENkEQhESfEUdEWbEY_E\]E^[E`YEbWEeTEgREiPEkMEnKEpIErGEtDEwBEy@E{>E};E9E7E5E2E0E.E+E)E'E%E"E EEEEEEEEE E EEEEEkxkwkwkvkuktks kr kr!kq"kp#ko$kn%kn%km&kl'kk(kj)ki*ki*kh+kg,kf-ke.kd.kd/kc0kb1ka2k`3k`3k_4k^5k]6k\7k[8k[8kZ9kY:kX;kWkT?kS@kRAkRAkQBkPCkODkNEkMFkMFkLGkKHkJIkIJkHKkHKkGLkFMkENkDOkCOkCPkBQkARk@Sk?Tk?Tk>Uk=Vk/A,D)G&J#M PSVY\_b e gjmoooo o ooo}ozoxpupspp pn"pl$pj&pg(pe+pc-pa/p^1p\3pZ5pX7qV9qT;qR=qP?qNAqLCqJEqHGqFIqDKqBLq@Nq>Pq4=6;8997;5=3?1A/C-E+G)I'K%M#O!QSUWY[^`b d fikmoooo o ooo~n{nynvnsnq!nn$nl'ni)nf,nd/na2n^5m[8mX;mU>mSAmPDmMGmJJmGMmDPm@Tm=Wl:Zl7^l4al0el-hl*kl&ol#slvkzk~kkk k kkjiihgfeedcb a ` ` _ ^ ]\\[ZYXWWVUTSSRG6%"3C HG*G:}GInGW`FfQFtCF5F(FE EECA?=: 8 6420.,)'%#"!$&(*,.1357 9 ;>@BDEEEE E E EEEEEEEEE!E#E%E(E*E,E.E0E3E5E7F9F;|F>zF@xFBvFDtFGqFIoFKmFMkFOhFRfFTdFVbFX_F[]F][F_YFaWFdTFfRFhPFjMFmKFoIFqGFsDFvBFx@Fz>F|;F9F7F5F2F0F.F+F)F'F%F"F FFFFFFFFF F FFFFFkxkwkwkvkukt ks kr!kr"kq#kp$ko%kn%kn&km'kl(kk)kj*ki*ki+kh,kg-kf.ke/kd/kd0kc1kb2ka3k`3k`4k_5k^6k]7k\8k[8k[9kZ:kY;kXkU?kT@kSAkRAkRBkQCkPDkOEkNFkMFkMGkLHkKIkJJkIKkHKkHLkGMkFNkEOkDOkCPkCQkBRkASk@Tk?Tk?Uk>Vk=Wk1;4874;1>.A+D(G%J"MPSVY\_b e gjmnnnn n ooo}ozoxouosop on"ol%oj'og)oe+pc-pa/p^2p\4pZ6pX8pV:pTpP@pNBpLDpJFpHGpFIqDKqBMq@Oq>Qq4<6:8896;4=3?1A/C-E+G)I'K$M"O QSUWY[^`b d fikmnnnn n nnn~n{nynvnsmq"mn%ml'mi*mf-md0ma3m^6m[8mX;mU>lSAlPElMHlJKlGNlDQl@Tl=Xl:[l7^k4bk0ek-ik*lk&pk#skwk{k~jjj j jjiihgfeedcba ` ` _ ^ ] \\[ZYXWWVUTSSRQI7&"3C IH)H8}HGnHV`GeQGsCG5G(GF FFDB@>< 9 7531/-+(&$""$ &(*,.1357 9 ;>@BDFFFFF F FFFFFFFFF F"F$G'G)G+G-G/G2G4G6G8G:|G=zG?xGAvGCtGEqGHoGJmGLkGNhGQfGSdGUbGW_GY]G\[G^YG`WGbTGeRGgPGiMGkKGnIGpGGrDGtBGw@Gy>G{;G}9G7G5G2G0G.G+G)G'G%G"G GGGGGGGGG G GGGGGjxjwjwjvju jt js!jr"jr#jq$jp%jo%jn&jn'jm(jl)jk*jj*ji+ji,jh-jg.jf/je/jd0jd1jc2jb3ja3j`4j`5j_6j^7j]8j\8j[9j[:jZ;jYjV?jU@jTAjSAjRBjRCjQDjPEjOFjNFjMGjMHjLIjKJjJKjIKjHLjHMjGNjFOjEOjDPjCQjCRjBSjATj@Tj?Uj?Vj>Wj=Xj-A*D'G$J!MPSVY\_ b egjmmnn n nnnn}nznxnunsnp!on#ol%oj'og*oe,oc.oa0o^2o\4oZ6oX8oV:oTpP@pNBpLDpJFpHHpFJpDLpBNp@Op>Qp@BDFGGGG G G GGGHHHHHH!H#H%H(H*H,H.H0H3H5H7H9|HxH@vHBtHDqHGoHImHKkHMhHOfHRdHTbHV_HX]H[[H]YH_WHaTHdRHfPHhMHjKHmIHoGHqDHsBHv@Hx>Hz;H|9H7H5H2H0H.H+H)H'H%H"H HHHHHHHHH H HHHHHixiwiwiv iu it!is"ir#ir$iq%ip%io&in'in(im)il*ik*ij+ii,ii-ih.ig/if/ie0id1id2ic3ib3ia4i`5i`6i_7i^8i]8i\9i[:i[;iZiV?iV@iUAiTAiSBiRCiRDiQEiPFiOFiNGiMHiMIiLJiKKiJKiILiHMiHNiGOiFOiEPiDQiCRiCSiBTiATi@Ui?Vi?Wi>Xi=Yi-A*D'G$J!MPSVY\_ b egjmmmm m mmmm}mznxnunsnp!nn$nl&nj(ng*ne,nc/na1n^3o\5oZ7oX9oV;oT=oR?oPAoNCoLEoJGoHIoFJoDLoBNo@Pp>Rp < 97531/-+(&"$$"& (*,.13579 ; >@BDFHHIII I IIIIIIIII I"I$I'I)I+I-I/I2I4I6I8|I:zI=xI?vIAtICqIFoIHmIJkILhINfIQdISbIU_IW]IZ[I\YI^WI`TIbRIePIgMIiKIkIInGIpDIrBIt@Iw>Iy;I{9I~7I5I2I0I.I+I)I'I%I"I IIIIIIIII I IIIIIhxhwhw hv hu!ht"hs#hr$hr%hq%hp&ho'hn(hn)hm*hl*hk+hj,hi-hi.hh/hg/hf0he1hd2hd3hc3hb4ha5h`6h`7h_8h^8h]9h\:h[;h[hW?hV@hVAhUAhTBhSChRDhREhQFhPFhOGhNHhMIhMJhLKhKKhJLhIMhHNhHOhGOhFPhEQhDRhCShCThBThAUh@Vh?Wh?Xh>Yh=Yh,A)D&G#J MPSVY\_ b egjllll l lmmm}mzmxmums mp"mn$ml'mj)ng+ne-nc/na1n^3n\5nZ8nX:nVnR@nPAnNCnLEoJGoHIoFKoDMoBOo@Qo>Ro2<4:697795;3=1?/A-C+E)G'I%K#M!OQSUWY[^` b dfikmmll l llll~l{lylvlt!kq$kn'kl)ki,kf/kd2ka5k^8k[;kX=jV@jSDjPGjMJjJMjGPjDSjAWj=Zi:]i7ai4di0gi-ki*ni&ri#vhyh}hhhh h gggfeedcba``_ ^ ] \ \ [ ZYXWWVUTSSRQPOOL;*"3 CLL&L5}KDnKS`KaQKpCJ~5J(JJ IIGECA? = :86420.,)'"%$#&!(*,.13579; > @BDFHJJJJ J JJJJJJJJJJ!J#J&J(J*J,J.J1J3J5J7|J9zJvJ@tJBqJDoJGmJIkJKhJMfJPdJRbJT_JV]JX[J[YJ]WJ_TJaRJdPJfMJhKJjIJmGJoDJqBJs@Jv>Jx;Jz9J|7J5J2J0J.J+J)J'J%J"J JJJJJJJJJ J JKKKKgxgw gw gv!gu"gt#gs$gr%gr%gq&gp'go(gn)gn*gm*gl+gk,gj-gi.gi/gh/gg0gf1ge2gd3gd3gc4gb5ga6g`7g`8g_8g^9g]:g\;g[gX?gW@gVAgVAgUBgTCgSDgREgRFgQFgPGgOHgNIgMJgMKgLKgKLgJMgINgHOgHOgGPgFQgERgDSgCTgCTgBUgAVg@Wg?Xg?Yg>Yg=Zg<[g;\g:]g:]g9^g8_g7`g6ag5bg5bg4cg3dg2eg1fg1gg0gg/hg.ig-jg,kg,kg+lg*mg)ng(og'pg'pg&qg%rg$sg#tg#ug"ug!vg wgxgygzgzg{g|g}g~g~gggggggggggggg g g g g g gggggggggggeb ^ ZWSOLH#E'B*>-;184571;.>+A(D%G"JMPSVY\_ b egjkkl l lllll}lzlxluls mp#mn%ml'mj)mg,me.mc0ma2m^4m\6mZ8mX:nVnR@nPBnNDnLFnJHnHJnFLnDMnBOn@Qn>Sn2<4:687694;2=0?.A,C*E(G&I$K"M OQSUWY[^` b dfikllll l lkkk~k{kykvkt"kq$kn'kl*ji-jf0jd2ja5j^8j[;jX>jVAjSDjPGiMJiJNiGQiDTiAWi=[i:^i7ah4eh1hh-lh*oh&sh#vh zh~gggg g ggfeedcba``_^ ] \ \ [ Z YXWWVUTSSRQPOONN<+"3 CMM$M4}MCnLR`L`QLoCK}5K(KK JJHFDB@ > <97531/-+("&$$&"( *,.13579; > @BDFHKKKKK K KKKKKKKKK K"K$K'K)K+K-K/K2K4K6|K8zK:xK=vK?tKAqKCoKFmKHkKJhKLfKNdKQbKS_KU]KW[KZYK\WK^TK`RKcPKeMKgKKiIKlGKnDKpBKr@Ku>Kw;Ky9K{7K~5K2K0K.K+K)K'K%K"K KKKLLLLLL L LLLLLfx fw fw!fv"fu#ft$fs%fr%fr&fq'fp(fo)fn*fn*fm+fl,fk-fj.fi/fi/fh0fg1ff2fe3fd3fd4fc5fb6fa7f`8f`8f_9f^:f];f\fY?fX@fWAfVAfVBfUCfTDfSEfRFfRFfQGfPHfOIfNJfMKfMKfLLfKMfJNfIOfHOfHPfGQfFRfESfDTfCTfCUfBVfAWf@Xf?Yf?Yf>Zf=[f<\f;]f:]f:^f9_f8`f7af6bf5bf5cf4df3ef2ff1gf1gf0hf/if.jf-kf,lf,lf+mf*nf)of(pf'pf'qf&rf%sf$tf#uf#uf"vf!wf xfyfzfzf{f|f}f~f~fffffffffffffff f f f f f fffffffffffda ] YVROKH#D'A*>-:174471;.>*A'D$G!JMPSVY\ _ begjkkk k kkkkk}lzlxluls!lp#ln&ll(lj*lg,le.lc0ma3m^5m\7mZ9mX;mV=mT?mRAmPCmNEmLGmJHmHJnFLnDNnBPn@Rn>Sn @ BDFHKLLLL L LLLLLLLLLL!L#L&L(L*L,L.L1L3L5|L7zL9xLtL@qLBoLDmLGkLIhLKfLMdLPbLR_LT]LV[LYYL[WL]TL_RLaPLdMLfKLhILjGLmDLoBLq@Ls>Lv;Lx9Lz7L}5L2L0L.L+L)M'M%M"M MMMMMMMMM M MMMMM fx fw!fw"fv#fu$ft%fs%fr&fr'fq(fp)fo*fn*fn+fm,fl-fk.fj/fi/fi0fh1fg2ff3fe3fd4fd5fc6fb7fa8f`8f`9f_:f^;f]fZ?fY@fXAfWAfVBfVCfUDfTEfSFfRFfRGfQHfPIfOJfNKfMKfMLfLMfKNfJOfIOfHPfHQfGRfFSfETfDTfCUfCVfBWfAXf@Yf?Yf?Zf>[f=\f<]f;]f:^f:_f9`f8af7bf6bf5cf5df4ef3ff2gf1gf1hf0if/jf.kf-lf,lf,mf+nf*of)pf(pf'qf'rf&sf%tf$uf#uf#vf"wf!xf yfzfzf{f|f}f~f~ffffffffffffffff f f f f f fffffffffffd` \ YUQNJG#C'@*=-:164370;->*A'D$G!JMPSVY\ _ begjjjj j jjkkk}kzkxkuks"kp$kn&kl(lj+lg-le/lc1la3l^5l\7lZ9lX;lV=lT?lRAmPCmNEmLGmJImHKmFMmDOmBPm@Rm>Tm0=2;49677593;1=/?-A+C)E'G%I#K!MOQSUWY[] ` b dfikkkk j jjjjj~j{jyjv jt#iq&in(il+ii.if1id4ia7i^:i[=hY@hVChSFhPIhMLhJOhGRhDUgAYg>\g:_g7cg4fg1jg-mg*qf'tf#xf {fffeee eeedcba``_^]\ \ [ Z Y X WWVUTSSRQPOONMLP?."3 CPO"O2}OAnNP`N^QNmCN{5M(MM MLJHFDB @ ><97531/-+"($&&$("* ,.13579;> @ BDFHKMMMMM M MMMMMMMMM M"M$M'M)M+M-M/M2M4|M6zM8xM;vM=tM?qMAoMCmMFkMHhMJfMLdMNbMQ_MS]MU[MWYMZWM\TM^RM`PMcMMeKMgIMiGMlDMnBMp@Mr>Mu;Mw9Ny7N{5N~2N0N.N+N)N'N%N"N NNNNNNNNN N NNNNN ex!ew"ew#ev$eu%et%es&er'er(eq)ep*eo*en+en,em-el.ek/ej/ei0ei1eh2eg3ef3ee4ed5ed6ec7eb8ea8e`9e`:e_;e^e[?eZ@eYAeXAeWBeVCeVDeUEeTFeSFeRGeRHeQIePJeOKeNKeMLeMMeLNeKOeJOeIPeHQeHReGSeFTeETeDUeCVeCWeBXeAYe@Ye?Ze?[e>\e=]e<]e;^e:_e:`e9ae8be7be6ce5de5ee4fe3ge2ge1he1ie0je/ke.le-le,me,ne+oe*pe)pe(qe're'se&te%ue$ue#ve#we"xe!ye zeze{e|e}e~e~eeeeeeeeeeeeeeeee e e e e e eeeeeeeeeeec_ [ XTQMJF#C'?*<-916427/;,>)A&D#G JMPSVY\ _ begiiii j jjjjj}jzjxju ks"kp%kn'kl)kj+kg-ke0kc2ka4k^6k\8lZ:lXlT@lRBlPDlNFlLHlJJlHKlFMlDOmBQm@Sm>Um0<2:48667493;1=/?-A+C)E'G%I#K MOQSUWY[] ` bdfijjjj j jjjii~i{iyiv!it$iq&in)il,hi/hf2hd4ha7h^:h[=hY@hVCgSFgPIgMLgJPgGSgDVgAYg>]f:`f7cf4gf1jf-nf*qf'ue#ye |eeeeed dddcba``_^]\\ [ Z Y X W WVUTSSRQPOONMLKQ@/"3CQQ!P0}P@nPN`O]QOkCOz5N(NN NMKIGEC A ?=:86420.,")$'&%(#*!,.13579;>@ B DFHKMNNNN N NNNNNNNNNN!N#N&N(N*N,N.N1N3|N5zN7xN9vNqN@oNBmNEkNGhNIfNKdNMbNP_NR]NT[NVYNYWN[TN]RN_PNbMNdKNfIOhGOkDOmBOo@Oq>Ot;Ov9Ox7Oz5O}2O0O.O+O)O'O%O"O OOOOOOOOO O OOOOO!dx"dw#dw$dv%du%dt&ds'dr(dr)dq*dp*do+dn,dn-dm.dl/dk/dj0di1di2dh3dg3df4de5dd6dd7dc8db8da9d`:d`;d_d[?d[@dZAdYAdXBdWCdVDdVEdUFdTFdSGdRHdRIdQJdPKdOKdNLdMMdMNdLOdKOdJPdIQdHRdHSdGTdFTdEUdDVdCWdCXdBYdAYd@Zd?[d?\d>]d=]d<^d;_d:`d:ad9bd8bd7cd6dd5ed5fd4gd3gd2hd1id1jd0kd/ld.ld-md,nd,od+pd*pd)qd(rd'sd'td&ud%ud$vd#wd#xd"yd!zd zd{d|d}d~d~dddddddddddddddddd d d d d d dddddddddddb^ [ WSPLIE#B'?*;-815427.;+>(A%D"GJMPSVY\ _beghii i iiiiii}jzjxju!js#jp%jn'jl*jj,jg.je0kc2ka4k^6k\9kZ;kX=kV?kTAkRBkPDkNFlLHlJJlHLlFNlDPlBRl@Sl>UlgYAgVDgSGgPJgMMfJPfGTfDWfAZf>]f:af7de4he1ke-oe*re've#ye }dddddd cccba``_^]\\[ Z Y X W W VUTSSRQPOONMLKJRA0"3CRR Q/}Q>nQM`P\QPjCPy5P(OO ONLJHFD B @><97531/-"+$(&&($*", .13579;>@ B DFHKMOOOOO O OOOOOOOOO O"O%O'O)O+O-O0O2|O4zO6xO8vO;tO=qO?oOAmOCkOFhOHfOJdOLbOO_OQ]OS[OUYPWWPZTP\RP^PP`MPcKPeIPgGPiDPlBPn@Pp>Pr;Pu9Pw7Py5P{2P~0P.P+P)P'P%P"P PPPPPPPPP P PPPPP"cx#cw$cw%cv%cu&ct'cs(cr)cr*cq*cp+co,cn-cn.cm/cl/ck0cj1ci2ci3ch3cg4cf5ce6cd7cd8cc8cb9ca:c`;c`c\?c[@c[AcZAcYBcXCcWDcVEcVFcUFcTGcSHcRIcRJcQKcPKcOLcNMcMNcMOcLOcKPcJQcIRcHScHTcGTcFUcEVcDWcCXcCYcBYcAZc@[c?\c?]c>]c=^c<_c;`c:ac:bc9bc8cc7dc6ec5fc5gc4gc3hc2ic1jc1kc0lc/lc.mc-nc,oc,pc+pc*qc)rc(sc'tc'uc&uc%vc$wc#xc#yc"zc!zc {c|c}c~c~ccccccccccccccccccc c c c c c ccccccccccca] Z VSOKHE#A'>*;-714417.;+>'A$D!GJMPSVY \ _beghhh h hhhiii}izixiu!is$ip&in(jl*jj,jg/je1jc3ja5j^7j\9jZ;jX=kV?kTAkRCkPEkNGkLIkJKkHMkFNkDPkBRk@Tl>Vl^e:ae7ee4he1ld-od*sd'vd#zd ~dccccc cbba``_^]\\[Z Y X W W V UTSSRQPOONMLKJJTB1" 3CSSS.}R=nRL`R[QQiCQw5Q(PP PPMKIGE C A?=:86420.",$)&'(%*#,!.13579;>@B D FHKMOPPPP P PPPPPPPPPP!P#P&P(P*P,P.P1|P3zP5xP7vP9tPoP@mPBkPEhPGfQIdQKbQM_QP]QR[QTYQVWQYTQ[RQ]PQ_MQbKQdIQfGQhDQkBQm@Qo>Qq;Qt9Qv7Qx5Qz2Q}0Q.Q+Q)Q'Q%Q"Q QQQQQQQQQ Q QQQQQ#bx$bw%bw%bv&bu'bt(bs)br*br*bq+bp,bo-bn.bn/bm/bl0bk1bj2bi3bi3bh4bg5bf6be7bd8bd8bc9bb:ba;b`b]?b\@b[Ab[AbZBbYCbXDbWEbVFbVFbUGbTHbSIbRJbRKbQKbPLbOMbNNbMObMObLPbKQbJRbISbHTbHTbGUbFVbEWbDXbCYbCYbBZbA[b@\b?]b?]b>^b=_b<`b;ab:bb:bb9cb8db7eb6fb5gb5gb4hb3ib2jb1kb1lb0lb/mb.nb-ob,pb,pb+qb*rb)sb(tb'ub'ub&vb%wb$xb#yb#zb"zb!{b |b}b~b~bbbbbbbbbbbbbbbbbbbb b b b b b bbbbbbbbbbb`] Y URNKGD#@'=*:-613407-;*>'A$D!GJMPSVY \ _begggg g hhhhhh}hzhx hu"is$ip'in)il+ij-ig/ie1ic4ia6j^8j\:jZjV@jTBjRDjPFjNHjLIjJKkHMkFOkDQkBSk@Uk>Vk.<0:2947657391;/=-?+A)C'E%G#I!KMOQSUWY[ ] ` bdfhhhh h hhhhgg~g{gy gv#gt&gq(go+gl.fi1fg4fd6fa9f^_d:bd7fd4id1ld-pc*tc'wc#{c ~ccbbbb bba``_^]\\[ZY X W W V U TSSRQPONNMLKJJIUC2""3CSTT-}S<97531/"-$+&((&*$,". 13579;>@B D FHKMOQQQQQ Q QQQQQQQQQ Q"Q%Q'Q)Q+Q-Q0|Q2zQ4xQ6vQ8tQ;qR=oR?mRAkRChRFfRHdRJbRL_RO]RQ[RSYRUWRXTRZRR\PR^MR`KRcIReGRgDRiBRl@Rn>Rp;Rs9Ru7Rw5Ry2R|0R~.R+R)R'R%R"R RRRRRRRRR R RRRRR$ax%aw%aw&av'au(at)as*ar*ar+aq,ap-ao.an/an/am0al1ak2aj3ai3ai4ah5ag6af7ae8ad8ad9ac:ab;aaa^?a]@a\Aa[Aa[BaZCaYDaXEaWFaVFaVGaUHaTIaSJaRKaRKaQLaPMaONaNOaMOaMPaLQaKRaJSaITaHTaHUaGVaFWaEXaDYaCYaCZaB[aA\a@]a?]a?^a>_a=`a&A#D GJMPSVY \ _beffgg g gggggh}hzhx hu#hs%hp'hn)hl,hj.ig0ie2ic4ia6i^8i\:iZiV@iTBjRDjPFjNHjLJjJLjHNjFPjDQjBSj@Uj>Wk.<0:2846647290;.=,?*A(C&E$G"I KMOQSUWY[ ] `bdfhhhg g gggggg~g{fy!fv#ft&fq)fo,fl.fi1fg4ed7ea:e^=e\@eYCeVFeSIdPLdMOdJRdGVdDYdA\d>`c;cc7fc4jc1mc-qc*tc'xb#|b bbbaaa aa``_^]\\[ZYX W W V U T SSRQPONNMLKJJIHVE4"#3CS UU,}T;nTJ`TYQSgCSu5S(SR RRPMKIG E CA?=:86420".$,&)('*%,#.!13579;>@BD F HKMOQRRRR R RRRRRRRRRR!R#R&R(R*R,S.|S1zS3xS5vS7tS:qSmS@kSBhSEfSGdSIbSK_SN]SP[SRYSTWSVTSYRS[PS]MS_KSbISdGSfDShBSk@Sm>So;Sq9St7Sv5Sx2Sz0S}.S+S)S'S%S"S SSSSSSSSS S SSSSS%ax%aw&aw'av(au)at*as*ar+ar,aq-ap.ao/an/an0am1al2ak3aj3ai4ai5ah6ag7af8ae8ad9ad:ac;aba_?a^@a]Aa\Aa[Ba[CaZDaYEaXFaWFaVGaVHaUIaTJaSKaRKaRLaQMaPNaOOaNOaMPaMQaLRaKSaJTaITaHUaHVaGWaFXaEYaDYaCZaC[aB\aA]a@]a?^a?_a>`a=aa%A"DGJMPSVY \_befff f fffgggg}gzgx!gu#gs&gp(hn*hl,hj.hg1he3hc5ha7h^9h\;iZ=iX?iVAiTCiREiPGiNIiLKiJMiHNiFPjDRjBTj@Vj>Wjd\AdYDdVGdSJdPMdMPcJScGVcDZcA]c>`c;dc7gb4jb1nb.qb*ub'yb#|a aaaaa` ```_^]\\[ZYXW W V U T S SRQPONNMLKJJIHGWF5"$3CS VV+}V:nUI`UWQUfCTt5T(TS SSQOLJH F DB@><97531"/$-&+((*&,$."1 3579;>@BD F HKMOQSSSSS S SSSSSSSSS T"T%T'T)T+T-|T0zT2xT4vT6tT8qT;oT=mT?kTAhTDfTFdTHbTJ_TL]TO[TQYTSWTUTTXRTZPT\MT^KTaITcGTeDTgBTj@Tl>Tn;Tp9Ts7Tu5Tw2Ty0T|.T~+T)T'T%T"T TTTTTTTTT T TTTTU%`x&`w'`w(`v)`u*`t*`s+`r,`r-`q.`p/`o/`n0`n1`m2`l3`k3`j4`i5`i6`h7`g8`f8`e9`d:`d;`c<`b=`a=``>``?`_@`^A`]A`\B`[C`[D`ZE`YF`XF`WG`VH`VI`UJ`TK`SK`RL`RM`QN`PO`OO`NP`MQ`MR`LS`KT`JT`IU`HV`HW`GX`FY`EY`DZ`C[`C\`B]`A]`@^`?_`?``>a`=b`';*7-4114.7+;(>%A!DGJMPSV Y \_beeee e effffff}fzfx"gu$gs&gp(gn+gl-gj/gg1ge3gc5ha7h^9h\hX@hVBhTDhREhPGiNIiLKiJMiHOiFQiDSiBTi@Vi>Xi-<.;09274563719/;-=+?)A'C%E#G!IKMOQSUWY[ ] `bdfgff f ffffffe~e{ey"ev%et'eq*eo-dl0di3dg5dd8da;d^>d\AdYDcVGcSJcPMcMQcJTcGWbDZbA^b>ab;db7hb4ka1oa.ra*va'ya#}a `````` ___^]\\[ZYXWW V U T S S RQPONNMLKJJIHGFXG6"%3CS WW*}W9nVH`VVQVeCUs5U(UT TTRPMKI G ECA?=:8642"0$.&,()*',%.#1!3579;>@BDF H KMOQSTTTT T TTTTUUUUUU!U$U&U(U*U,|U/zU1xU3vU5tU7qU:oUkU@hUBfUEdUGbUI_UK]UN[UPYURWUTTUVRUYPU[MU]KU_IUbGUdDUfBUh@Uk>Um;Uo9Uq7Ut5Uv2Ux0U{.U}+U)U'U%U"U UUUUUUUUV V VVVVV&_x'_w(_w)_v*_u*_t+_s,_r-_r._q/_p/_o0_n1_n2_m3_l3_k4_j5_i6_i7_h8_g8_f9_e:_d;_d<_c=_b=_a>_`?_`@__A_^A_]B_\C_[D_[E_ZF_YF_XG_WH_VI_VJ_UK_TK_SL_RM_RN_QO_PO_OP_NQ_MR_MS_LT_KT_JU_IV_HW_HX_GY_FY_EZ_D[_C\_C]_B]_A^_@__?`_?a_>b_=b_$A!DGJMPSV Y \_bddde e eeeeeef}fz fx"fu%fs'fp)fn+fl-gj0gg2ge4gc6ga8g^:g\gX@hVBhTDhRFhPHhNJhLLhJNhHPhFQhDSiBUi@Wi>Yi-<.:08264463719/;-=+?)A'C%E#G!IKMOQSUWY [ ] `bdffff f eeeeeee~e{ dy#dv%dt(dq+do.dl0di3dg6cd9caba;ea7ha4la1oa.s`*v`'z`#~` `_____ _^^]\\[ZYXWWV U T S S R QPONNMLKJJIHGFFZH7"&3CS YX(}X8nXG`WUQWdCVr5V(VU UUSQOLJ H FDB@><9753"1$/&-(+*(,&.$1"3 579;>@BDF H KMOQSUUUUV V VVVVVVVVV V"V%V'V)V+|V-zV0xV2vV4tV6qV8oV;mV=kV?hVAfVDdVFbVH_VJ]VL[VOYVQWVSTVURVXPVZMV\KV^IVaGVcDVeBVg@Vj>Vl;Vn9Vp7Vs5Vu2Vw0Vy.V|+V~)V'V%V"V VVWWWWWWW W WWWWW'^x(^w)^w*^v*^u+^t,^s-^r.^r/^q/^p0^o1^n2^n3^m3^l4^k5^j6^i7^i8^h8^g9^f:^e;^d<^d=^c=^b>^a?^`@^`A^_A^^B^]C^\D^[E^[F^ZF^YG^XH^WI^VJ^VK^UK^TL^SM^RN^RO^QO^PP^OQ^NR^MS^MT^LT^KU^JV^IW^HX^HY^GY^FZ^E[^D\^C]^C^^B^^A_^@`^?a^?b^>b^=c^#A DGJMPSV Y \_bcddd ddddeeee}ez!ex#eu%es'fp*fn,fl.fj0fg2fe4fc7fa9f^;g\=gZ?gXAgVCgTEgRGgPIgNJgLLhJNhHPhFRhDThBVh@Wh>Yh<[h:]h8^i7`i5bi3ci1ei/gi.hi,ji*li)mi'oi%pj#rj"tj ujwjxjzj{j}j~jjjkk _ ]\ZXWUTRPOMKJ!H"F$D&C'A)?+=-;.:08264462709.;,=*?(A&C$E"G IKMOQSUWY [ ]`bdeeee e eeedddd~d|!dy#dv&dt)cq,co.cl1ci4cg7cd:ca=b^@b\CbYFbVIbSLbPOaMRaJUaGXaD\aA_a>b`;f`7i`4m`1p`.t`*w_'{_#~_ __^^^^ ^]]\\[ZYXWWVU T S S R Q PONNMLKJJIHGFFE[J8"(3CSZY'}Y7nYE`XTQXcCXq5W(WW VVTRPNK I GECA?=:864"2$0&.(,*),'.%1#3!579;>@BDFH K MOQSUWWWW W WWWWWWWWWW!W$W&W(W*|W,zW/xW1vW3tW5qW7oW:mWhW@fWBdWEbWG_WI]WK[WNYWPWWRTWTRWWPWYMW[KW]IW`GWbDWdBWf@Wi>Wk;Wm9Wo7Wr5Wt2Wv0Wx.W{+W})W'X%X"X XXXXXXXXX X XXXXX(]x)]w*]w*]v+]u,]t-]s.]r/]r/]q0]p1]o2]n3]n3]m4]l5]k6]j7]i8]i8]h9]g:]f;]e<]d=]d=]c>]b?]a@]`A]`A]_B]^C]]D]\E][F][F]ZG]YH]XI]WJ]VK]VK]UL]TM]SN]RO]RO]QP]PQ]OR]NS]MT]MT]LU]KV]JW]IX]HY]HY]GZ]F[]E\]D]]C^]C^]B_]A`]@a]?b]?b]>c]=d]"ADGJMPSV Y\_bccc c ccdddddd}dz!ex$eu&es(ep*en-el/ej1eg3fe5fc7fa9f^;f\=fZ?fXAfVCfTEgRGgPIgNKgLMgJOgHQgFSgDTgBVg@Xh>Zh<[h:]h8_h7ah5bh3dh1fh/gh.ii,ki*li)ni'oi%qi#si"ti viwiyizj|j}jjjjjj ^ ][ZXVUSQPNLKI!G"F$D&B'@)>+=-;.907254361709.;,=*?(A&C$E"GIKMOQSUWY [ ]`bdeeed d ddddddc~c|!cy$cw'ct)cq,co/bl2bi5bg7bd:ba=b_@b\CaYFaVIaSLaPPaMSaJV`GY`D\`A``>c`;f`8j_4m_1q_.t_*x_'|^#^ ^^^]]] ]]\\[ZYXWWVUT S S R Q P ONNMLKJJIHGFFED\K:")3CS[[&}Z5nZD`YSQYbCYp5X~(XX WWUSQOL J HFDB@><975"3$1&/(-*+,(.&1$3"5 79;>@BDFH K MOQSUXXXXX X XXXXXXXXX X"X%X'X)|X+zX-xX0vX2tX4qX6oX9mX;kX=hX?fXAdXDbXF_XH]XJ[XMYXOWXQTXSRXUPXXMXZKX\IX^GXaDXcBXe@Xg>Xj;Xl9Xn7Xp5Ys2Yu0Yw.Yy+Y|)Y~'Y%Y"Y YYYYYYYYY Y YYYYY)]x*]w*]w+]v,]u-]t.]s/]r/]r0]q1]p2]o3]n3]n4]m5]l6]k7]j8]i8]i9]h:]g;]f<]e=]d=]d>]c?]b@]aA]`A]`B]_C]^D]]E]\F][F][G]ZH]YI]XJ]WK]VK]VL]UM]TN]SO]RO]RP]QQ]PR]OS]NT]MT]MU]LV]KW]JX]IY]HY]HZ]G[]F\]E]]D^]C^]C_]B`]Aa]@b]?b]?c]>d]=e]#;'8*4-11.4+7(;%>"ADGJMPS V Y\_bbbb b cccccccd} dz"dx$du'ds)dp+dn-el/ej1eg4ee6ec8ea:e^eZ@fXBfVDfTFfRHfPJfNLfLNfJOfHQgFSgDUgBWg@Yg>Zg<\g:^g8`g7ah5ch3eh1fh/hh.jh,kh*mh)nh'ph%rh#si"ui vixiyi{i|i~iiiiij ^ \[YWVTSQONLJI!G"E$C&B'@)>+<-:.8072543617/9-;+=)?'A%C#E!GIKMOQSUWY [ ]`bdddd d d dcccccc~c|"by%bw'bt*bq-bo0bl2bi5ag8ad;aa>a_Aa\DaYGaVJ`SM`PP`MS`JW`GZ`D]_A`_>d_;g_8k_4n^1r^.u^*y^'|^$^ ]]]]\\ \\\[ZYXWWVUTS S R Q P O NNMLKJJIHGFFEDC]L;"*3C S\\%}[4n[C`[RQZ`CZo5Y}(YY XXVTRPN K IGECA?=:86"4$2&0(.*,,).'1%3#5!79;>@BDFHK M OQSUXYYYY Y YYYYYYYYYY!Y$Y&Y(|Y*zY,xY/vY1tY3qY5oY7mY:kYfY@dYCbYE_YG]YI[YKYYNWYPTYRRYTPYWMYYKY[IY]GY`DYbBYd@Zf>Zi;Zk9Zm7Zo5Zr2Zt0Zv.Zx+Z{)Z}'Z%Z"Z ZZZZZZZZZ Z ZZZZZ*\x*\w+\w,\v-\u.\t/\s/\r0\r1\q2\p3\o3\n4\n5\m6\l7\k8\j8\i9\i:\h;\g<\f=\e=\d>\d?\c@\bA\aA\`B\`C\_D\^E\]F\\F\[G\[H\ZI\YJ\XK\WK\VL\VM\UN\TO\SO\RP\RQ\QR\PS\OT\NT\MU\MV\LW\KX\JY\IY\HZ\H[\G\\F]\E^\D^\C_\C`\Ba\Ab\@b\?c\?d\>e\=f\!ADGJMPS V Y\_aaab b bbbbcccc} cz#cx%cu'cs)dp,dn.dl0dj2dg4de6dc8ea:e^=e\?eZAeXCeVEeTFeRHePJfNLfLNfJPfHRfFTfDUfBWf@Yf>[g<]g:^g8`g7bg5cg3eg1gg/hg.jg,lh*mh)oh'qh%rh#th"uh whxhzh{h}i~iiiiii ] \ZYWUTRPOMKJH!F"E$C&A'?)=+<-:.8062442607.9,;+=)?'A%C"E GIKMOQSUW Y [ ]`bddcc c cccccbbb~ b|#by%bw(bt+aq-ao0al3aj6ag9ad<`a?`_B`\E`YH`VK`SN_PQ_MT_JW_G[_D^_Aa^>d^;h^8k^4o^1r^.v]*y]'}]$] ]\\\\[ [[[ZYXWWVUTSS R Q P O N N MLKJJIHGFFEDCB_M<"+3C S]]$}\3n\B`\QQ[_C[n5Z|(ZZ YYWUSQO L JHFDB@><97"5$3&1(/*-,+.(1&3$5"7 9;>@BDFHK M OQSUXZZZZZ Z ZZZZZZZZZ Z#Z%Z'|Z)zZ+xZ.vZ0tZ2qZ4oZ6mZ9kZ;hZ=fZ?dZAbZD_ZF]ZH[ZJYZMWZOTZQRZSPZVMZXK[ZI[\G[^D[aB[c@[e>[g;[j9[l7[n5[q2[s0[u.[w+[z)[|'[~%["[ [[[[[[[[[ [ [[[[[*[x+[w,[w-[v.[u/[t/[s0[r1[r2[q3[p3[o4[n5[n6[m7[l8[k8[j9[i:[i;[h<[g=[f=[e>[d?[d@[cA[bA[aB[`C[`D[_E[^F[]F[\G[[H[[I[ZJ[YK[XK[WL[VM[VN[UO[TO[SP[RQ[RR[QS[PT[OT[NU[MV[MW[LX[KY[JY[IZ[H[[H\[G][F^[E^[D_[C`[Ca[Bb[Ab[@c[?d[?e[>f[=g[ ADGJMPS V Y\_`aa a aaabbbbbb}!bz#cx&cu(cs*cp,cn.cl1cj3dg5de7dc9da;d^=d\?dZAdXCeVEeTGeRIePKeNMeLOeJQeHReFTfDVfBXf@Zf>[f<]f:_f8af7bf5dg3fg1gg/ig.kg,lg*ng)og'qg%sg#tg"vh whyhzh|h}hhhhhhi ] [ZXVUSRPNMKIH!F"D$B&@'?)=+;-9.7062442507.9,;*=(?&A$C"E GIKMOQSUW Y []`bcccc c bbbbbbba~!a|#ay&aw)at+aq.ao1`l4`j7`g9`d<`a?`_B_\E_YH_VK_SN_PR_MU^JX^G[^D^^Ab^>e^;i]8l]4o]1s].w]*z\'~\$\ \\[[[[ ZZZYXWWVUTSSR Q P O N N M LKJJIHGFFEDCBA`N=",3C S^^#}^2n]A`]PQ\^C\m5\{([[ ZZXVTRP N KIGECA?=:8"6$4&2(0*.,,.)1'3%5#7!9;>@BDFHKM O QSUXZ[[[[ [ [[[[[[[[[[![$[&|[(z[*x[,v[/t[1q[3o[5m[7k[:h[d[@b[C_[E][G[[IY[KW\NT\PR\RP\TM\WK\YI\[G\]D\`B\b@\d>\f;\i9\k7\m5\o2\r0\t.\v+\x)\{'\}%\"\ \\\\\\\\\ \ \\\\\+Zx,Zw-Zw.Zv/Zu/Zt0Zs1Zr2Zr3Zq3Zp4Zo5Zn6Zn7Zm8Zl8Zk9Zj:Zi;ZiZe?Zd@ZdAZcAZbBZaCZ`DZ`EZ_FZ^FZ]GZ\HZ[IZ[JZZKZYKZXLZWMZVNZVOZUOZTPZSQZRRZRSZQTZPTZOUZNVZMWZMXZLYZKYZJZZI[ZH\ZH]ZG^ZF^ZE_ZD`ZCaZCbZBbZAcZ@dZ?eZ?fZ>gZ=gZADGJMPS VY\_``` ` `aaaaaaab}"bz$bx&bu(bs+bp-bn/cl1cj3cg5ce8cc:cad\@dZBdXDdVFdTHdRJdPLdNMeLOeJQeHSeFUeDWeBXe@Ze>\e<^f:_f8af7cf5ef3ff1hf/jf.kf,mf*ng)pg'rg%sg#ug"vg xgyg{g|g~hhhhhhh \ [YXVTSQONLJIG!E"D$B&@'>)<+;-9.70523415/7-9+;)='?%A#C!EGHJMOQSUW Y []`bbbbb b bbbaaaaa~!a|$`y'`w)`t,`q/`o2`l4`j7_g:_d=_a@__C_\F_YI^VL^SO^PR^MU^JY^G\]D_]Ac]>f];i]8m\4p\1t\.w\*{\'~[$[ [[[ZZZ ZYYXWWVUTSSRQ P O N N M L KJJIHGFFEDCBAAaP>".3C S`_"}_1n^@`^OQ]]C]k5]y(\\ \[YWUSQ O LJHFDB@><9"7$5&3(1*/,-.+1(3&5$7"9 ;>@BDFHKM O QSUXZ\\\\\ \ \\\\\\\\\ \#\%|\'z\)x\+v\.t\0q\2o\4m\6k\9h\;f\=d\?b\A_]D]]F[]HY]JW]MT]OR]QP]SM]VK]XI]ZG]\D]_B]a@]c>]e;]h9]j7]l5]n2]q0]s.]u+]w)]z']|%]~"] ]]]]]]]]] ] ]]]]],Yx-Yw.Yw/Yv/Yu0Yt1Ys2Yr3Yr3Yq4Yp5Yo6Yn7Yn8Ym8Yl9Yk:Yj;YiYf?Ye@YdAYdAYcBYbCYaDY`EY`FY_FY^GY]HY\IY[JY[KYZKYYLYXMYWNYVOYVOYUPYTQYSRYRSYRTYQTYPUYOVYNWYMXYMYYLYYKZYJ[YI\YH]YH^YG^YF_YE`YDaYCbYCbYBcYAdY@eY?fY?gY>gY=hYADGJMP S VY\____ ` `````aaa a}"az%ax'au)bs+bp-bn0bl2bj4bg6be8cc:cac\@cZBcXDcVFcTHdRJdPLdNNdLPdJRdHTdFUdDWeBYe@[e>]e<^e:`e8be7ce5ee3gf1hf/jf.lf,mf*of)qf'rf%tf#uf"wg xgzg{g}g~ggggggh \ ZYWUTRQOMLJHF!E"C$A&?'>)<+:-8.60423415/7-9+;)='?%A#C!EGHJLOQSUW Y []_bbbb a a aaaaa```~"`|$`y'`w*`t-_r/_o2_l5_j8_g;_d>^aA^_D^\G^YJ^VM^SP]PS]MV]JY]G]]D`\Ac\>g\;j\8m\4q[1t[.x[+|['[$Z ZZZZYY YYXWWVUTSSRQP O N N M L K JJIHGFFEDCBAA@bQ@"/3CSa` }`0n_?`_NQ_\C^j5^x(]] ]\ZXVTR P NKIGECA?=:"8$6&4(2*0,..,1)3'5%7#9!;>@BDFHKM O Q SUXZ\]]]] ] ]]]]]]]]]]!]$|]&z](x]*v],t]/q]1o]3m]5k^8h^:f^b^@_^C]^E[^GY^IW^LT^NR^PP^RM^TK^WI^YG^[D^]B^`@^b>^d;^f9^i7^k5^m2^o0^r.^t+^v)^y'^{%^}"^ ^^^^^^^^^ ^ ^^^^^-Xx.Xw/Xw/Xv0Xu1Xt2Xs3Xr3Xr4Xq5Xp6Xo7Xn8Xn8Xm9Xl:Xk;XjXg?Xf@XeAXdAXdBXcCXbDXaEX`FX`FX_GX^HX]IX\JX[KX[KXZLXYMXXNXWOXVOXVPXUQXTRXSSXRTXRTXQUXPVXOWXNXXMYXMYXLZXK[XJ\XI]XH^XH^XG_XF`XEaXDbXCbXCcXBdXAeX@fX?gX?gX>hX=iX:#7'4*1--1*4'7$;!>ADGJMP S VY\^^__ _ ___`````!`}#`z%ax'au*as,ap.an0al2bj5bg7be9bc;ba=b^?b\AbZCcXEcVGcTIcRKcPMcNOcLPcJRdHTdFVdDXdBZd@[d>]d<_d:ae8be7de5fe3ge1ie/ke.le,ne*oe)qf'sf%tf#vf"wf yfzf|f}ffgggggg [ ZXWUSRPNMKIHF!D"B$A&?'=);+9-8.60422405.7,9*;(=&?$A"C EFHJLOQSU W Y[]_aaaa a aa`````` _~"_|%_y(_w+_t-_r0_o3^l6^j9^g;^d>^aA^_D]\G]YJ]VM]SQ]PT\MW\JZ\G]\Da\Ad[>g[;k[8n[4r[1uZ.yZ+|Z'Z$Z YYYYXX XXWWVUTSSRQPO N N M L K J JIHGFFEDCBAA@?cRA"03CSba}a/na>``LQ`[C_i5_w(^^ ^][YWUS Q OLJHFDB@><"9$7&5(3*1,/.-1*3(5&7$9"; >@BDFHKMO Q SUXZ\^^^^^ ^ ^^^^^^^^^ ^#|^%z^'x^)v^+t_.q_0o_2m_4k_6h_9f_;d_=b_?__B]_D[_FY_HW_JT_MR_OP_QM_SK_VI_XG_ZD_\B__@_a>_c;_e9_h7_j5_l2_n0_q._s+_u)_w'_z%_|"_~ _________ _ _````.Xx/Xw/Xw0Xv1Xu2Xt3Xs3Xr4Xr5Xq6Xp7Xo8Xn8Xn9Xm:Xl;XkXh?Xg@XfAXeAXdBXdCXcDXbEXaFX`FX`GX_HX^IX]JX\KX[KX[LXZMXYNXXOXWOXVPXVQXURXTSXSTXRTXRUXQVXPWXOXXNYXMYXMZXL[XK\XJ]XI^XH^XH_XG`XFaXEbXDbXCcXCdXBeXAfX@gX?gX?hX>iX=jXADGJMP S VY\^^^ ^ ^^______`!`}$`z&`x(`u*`s-`p/an1al3aj5ag7ae9ac;aa>b^@b\BbZDbXFbVHbTIbRKcPMcNOcLQcJScHUcFWcDXcBZc@\d>^d<_d:ad8cd7ed5fd3hd1je/ke.me,ne*pe)re'se%ue#ve"xe yf{f|f~fffffffg [ YXVTSQPNLKIGE!D"B$@&>'=);+9-7.50321405.7,9*;(=&?$A"C EFHJLOQSU W Y[]_aa`` ` ````____ _~#_|&_y(^w+^t.^r1^o3^l6^j9]g<]d?]bB]_E]\H\YK\VN\SQ\PT\MX\J[[G^[Da[Ae[>h[;kZ8oZ5rZ1vZ.yY+}Y'Y$Y YXXXXW WWWVUTSSRQPON N M L K J J IHGFFEDCBAA@?>eSB"13 CSbc}b-nb=`aKQaZC`h5`v(`_ _^\ZXVT R PNKIGECA?=":$8&6(4*2,0..1,3)5'7%9#;!>@BDFHKMO Q S UXZ\^____ _ __________!|`$z`&x`(v`*t`-q`/o`1m`3k`5h`8f`:d`_`@]`C[`EY`GW`IT`LR`NP`PM`RK`UI`WG`YD`[B`^@``>`b;`d9`g7`i5`k2`m0`p.`r+`t)`v'`y%`{"`} ``````aaa a aaaaa/Wx/Ww0Ww1Wv2Wu3Wt3Ws4Wr5Wr6Wq7Wp8Wo8Wn9Wn:Wm;WlWi?Wh@WgAWfAWeBWdCWdDWcEWbFWaFW`GW`HW_IW^JW]KW\KW[LW[MWZNWYOWXOWWPWVQWVRWUSWTTWSTWRUWRVWQWWPXWOYWNYWMZWM[WL\WK]WJ^WI^WH_WH`WGaWFbWEbWDcWCdWCeWBfWAgW@gW?hW?iW>jW=kWADGJMP SVY\]]] ] ^^^^^^__ _"_}$_z&_x)`u+`s-`p/`n2`l4`j6`g8ae:aca^@a\BaZDaXFbVHbTJbRLbPNbNPbLRbJSbHUcFWcDYcB[c@\c>^c<`c:bc8cd7ed5gd3hd1jd/ld.md,od*qd)re'te%ue#we"xe ze{e}e~eeffffff Z YWVTRQOMLJHGE!C"A$@&>'<):+8-7.503214/5-7+9);'=%?#A!CEFHJLNQSU W Y[]_```` ` ______^^!^~$^|&^y)^w,^t/]r1]o4]l7]j:]g=\d@\bC\_F\\I\YL\VO[SR[PU[MX[J[[G_ZDbZAeZ>iZ;lZ8pY5sY1wY.zY+~X'X$X XXWWWW VVVUTSSRQPONN M L K J J I HGFFEDCBAA@?>=fTC"23"CSbd}c,nc;`bJQbYCag5au(a` `_][YWU S QOMJHFDB@>"<$9&7(5*3,1./1-3*5(7&9$;"> @BDFHKMOQ S UXZ\^````` ` `````aaaa |a#za%xa'va)ta+qa.oa0ma2ka4ha6fa9da;ba=_a?]aB[aDYaFWaHTaJRaMPaOMaQKaSIaVGaXDaZBa\@a_>aa;ac9ae7ah5aj2al0an.aq+as)au'ax%az"a| a~abbbbbbb b bbbbb/Vx0Vw1Vw2Vv3Vu3Vt4Vs5Vr6Vr7Vq8Vp8Vo9Vn:Vn;VmVi?Vi@VhAVgAVfBVeCVdDVdEVcFVbFVaGV`HV`IV_JV^KV]KV\LV[MV[NVZOVYPVXPVWQVVRVVSVUTVTTVSUVRVVRWVQXVPYVOYVNZVM[VM\VL]VK^VJ^VI_VH`VHaVGbVFbVEcVDdVCeVCfVBgVAgV@hV?iV?jV>kV=lVADGJM P SVY\\\] ] ]]]]^^^^ ^#^}%_z'_x)_u,_s._p0_n2_l4`j6`g9`e;`c=`a?`^A`\CaZEaXGaVIaTKaRMaPNaNPbLRbJTbHVbFXbDZbB[b@]b>_ciY;mY8pY5tX1wX.{X+X'W$W WWWVVV VUUTSSRQPONNM L K J J I H GFFEDCBAA@?>==gVD"33#CSb e}d+nd:`cIQcXCcf5bt(ba a`^\ZXV T RPNKIGECA?"=$:&8(6*4,2.01.3,5)7'9%;#>!@BDFHKMOQ S U XZ\^`aaaa a abbbbbbbb|b"zb$xb&vb(tb*qb-ob/mb1kb3hb5fb8db:bb<_b>]b@[bCYbEWbGTbIRbLPbNMbPKbRIbUGbWDbYBb[@b^>b`;bb9bd7bg5bi2bk0bm.bp+br)bt'cv%cy"c{ c}cccccccc c ccccc0Ux1Uw2Uw3Uv3Uu4Ut5Us6Ur7Ur8Uq8Up9Uo:Un;UnUj?Ui@UiAUhAUgBUfCUeDUdEUdFUcFUbGUaHU`IU`JU_KU^KU]LU\MU[NU[OUZPUYPUXQUWRUVSUVTUUTUTUUSVURWURXUQYUPYUOZUN[UM\UM]UL^UK^UJ_UI`UHaUHbUGbUFcUEdUDeUCfUCgUBgUAhU@iU?jU?kU>lU=lU;7#4'1*--*1'4$7!;>ADGJM P SVY[[\\ \ \\]]]]]]!^#^}&^z(^x*^u,^s._p1_n3_l5_j7_g9_e;_c=`a?`^A`\C`ZE`XG`VI`TKaRMaPOaNQaLSaJUaHVaFXbDZbB\b@^b>_b==$<&9(7*5,3.11/3-5*7(9&;$>"@ BDFHKMOQS U XZ\^`bbbcc c cccccccc|c zc#xc%vc'tc)qc+oc.mc0kc2hc4fc7dc9bc;_c=]c?[cBYcDWcFTcHRcKPcMMcOKcQIcSGcVDcXBcZ@c\>c_;ca9cc7ce5ch2cj0dl.do+dq)ds'du%dx"dz d|d~ddddddd d ddddd1Tx2Tw3Tw3Tv4Tu5Tt6Ts7Tr8Tr8Tq9Tp:To;TnTk?Tj@TiATiAThBTgCTfDTeETdFTdFTcGTbHTaIT`JT`KT_KT^LT]MT\NT[OT[PTZPTYQTXRTWSTVTTVTTUUTTVTSWTRXTRYTQYTPZTO[TN\TM]TM^TL^TK_TJ`TIaTHbTHbTGcTFdTEeTDfTCgTCgTBhTAiT@jT?kT?lT>lT=mTADGJM P SVY[[[ [ [[\\\\\]]"]$]}&]z(]x+^u-^s/^p1^n3^l6^j8_g:_e<_c>_a@_^B_\D_ZF`XH`VJ`TL`RN`PP`NR`LSaJUaHWaFYaD[aB\a@^a>`a&<':)9+7-5.3012/4-5+7)9(;&=$?"ACDFHJLNQS U WY[]^^^^ ^ ^^]]]]]] \#\~&\|(\y+\w.\t0[r3[o6[l9[j<[g?ZdBZbEZ_HZ\KZYNYVQYSTYQWYNZYK^XHaXEdXAgX>kX;nW8rW5uW1yW.|V+V'V$V UUUUTT TTSSRQPONNMLK J J I H G F FEDCBAA@?>==<;jXG"63%CSb g}g)nf8`fGQeUCed5dr(dc cca^\ZX V TRPNKIGECA"?$=&:(8*6,4.2103.5,7)9';%>#@!BDFHKMOQS U X Z\^`cdddd d dddddddd|dzd"xd$vd&td(qd*od-md/kd1hd3fd5dd8bd:_d<]d>[dAYdCWdETdGRdIPdLMdNKdPIdRGdUDdWBdY@d[>d^;e`9eb7ed5eg2ei0ek.em+ep)er'et%ev"ey e{e}eeeeeee e eeeee2Sx3Sw3Sw4Sv5Su6St7Ss8Sr8Sr9Sq:Sp;SoSl?Sk@SjASiASiBShCSgDSfESeFSdFSdGScHSbISaJS`KS`KS_LS^MS]NS\OS[PS[PSZQSYRSXSSWTSVTSVUSUVSTWSSXSRYSRYSQZSP[SO\SN]SM^SM^SL_SK`SJaSIbSHbSHcSGdSFeSEfSDgSCgSChSBiSAjS@kS?lS?lS>mS=nSADGJM PSVYZZZ Z [[[[[\\\ \"\%\}']z)]x+]u.]s0]p2]n4^l6^j8^g:^e=^c?^aA_^C_\E_ZG_XI_VK_TL_RN`PP`NR`LT`JV`HX`FY`D[`B]a@_a>aa&<':)8+6-4.3012/4-5+7)9';%=#?!ACDFHJLNPS U WY[]^^^] ] ]]]]\\\\!\$\~&[|)[y,[w.[t1[r4Zo7Zl:ZjlW;oW8rV5vV1yV.}V+U'U$U UTTTTS SSSRQPONNMLKJ J I H G F F EDCBAA@?>==<;:kYH"73&CSb h}h(ng7`gFQfTCfc5eq(ed ddb_][Y W USQOMJHFDB"@$>&<(9*7,5.3113/5-7*9(;&>$@"B DFHKMOQSU X Z\^`ceeeee e eeeeeee|eze xe#ve%te'qe)oe+me.ke0he2fe4de7be9_e;]e=[e?YeBWeDTeFReHPeKMeMKeOIeQGeTDfVBfX@fZ>f];f_9fa7fc5ff2fh0fj.fl+fo)fq'fs%fu"fx fzf|f~ffffff f fffff3Sx3Sw4Sw5Sv6Su7St8Ss8Sr9Sr:Sq;SpSm?Sl@SkASjASiBSiCShDSgESfFSeFSdGSdHScISbJSaKS`KS`LS_MS^NS]OS\PS[PS[QSZRSYSSXTSWTSVUSVVSUWSTXSSYSRYSRZSQ[SP\SO]SN^SM^SM_SL`SKaSJbSIbSHcSHdSGeSFfSEgSDgSChSCiSBjSAkS@lS?lS?mS>nS=oSADGJ M PSVYYYZ Z ZZZ[[[[[![#\%\}'\z*\x,\u.\s0]p3]n5]l7]j9]g;]e=^c?^aA^^C^\E^ZG^XI_VK_TM_RO_PQ_NS_LU_JV`HX`FZ`D\`B^`@_`>a`lV;pV8sV5wU1zU.~U+U'T$T!TTSSSS RRRQPONNMLKJJ I H G F F E DCBAA@?>==<;:9lZI"83(CSbi}i'nh6`hEQgSCgb5fp(f~f eeca^\Z X VTRPNKIGEC"A$?&=(:*8,6.412305.7,9);'>%@#B!DFHKMOQSU X Z \^`ceffff f fffffff|fzfxf"vf$tf&qf(of*mf-kf/hf1ff3df5bf8_f:]f<[f>YfAWfCTfERfGPfJMgLKgNIgPGgRDgUBgW@gY>g[;g^9g`7gb5gd2gg0gi.gk+gm)gp'gr%gt"gw gyg{g}gggggg g ggggg3Rx4Rw5Rw6Rv7Ru8Rt8Rs9Rr:Rr;RqRn?Rm@RlARkARjBRiCRiDRhERgFRfFReGRdHRdIRcJRbKRaKR`LR`MR_NR^OR]PR\PR[QR[RRZSRYTRXTRWURVVRVWRUXRTYRSYRRZRR[RQ\RP]RO^RN^RM_RM`RLaRKbRJbRIcRHdRHeRGfRFgREgRDhRCiRCjRBkRAlR@lR?mR?nR>oR=pR;74#1'.**-'1$4!7;>ADGJ M PSVXXYY YYYZZZZZ[![$[&[}([z*[x-\u/\s1\p3\n5\l7\j:]g<]e>]c@]aB]^D]\F^ZH^XJ^VL^TN^RP^PQ^NS_LU_JW_HY_F[_D\_B^_@``>b`$=&;'9)7+5,3.1002.4,5*7(9&;$="? ABDFHJLNP S UWY[]]\\ \ \\\[[[[[ ["Z%Z~'Z|*Zy-Zw0Zt2Yr5Yo8Ym;Yj>YgAXdDXbGX_JX\MXYPWVSWTVWQYWN\VK`VHcVEfVBjV>mU;pU8tU5wU2{T.T+T'T$S!SSSRRR RQQPONNMLKJJIH G F F E D CBAA@?>==<;:98m\J"93)CSbk}j&nj5`iDQiRCh`5ho(g}g ffdb_][ Y WUSQOMJHFD"B$@&>(<*9,7.513315/7-9*;(>&@$B"D FHKMOQSUX Z \^`ceggggg g gggggg|gzgxg!vg#tg%qg'og)mg,kg.hg0fg2dg4bg7_g9]g;[g=Yg?WgBThDRhFPhHMhKKhMIhOGhQDhTBhV@hX>hZ;h]9h_7ha5hc2hf0hh.hj+hl)ho'hq%hs"hu hxhzh|hhhhhh h hhhhh4Qx5Qw6Qw7Qv8Qu8Qt9Qs:Qr;QrQn?Qn@QmAQlAQkBQjCQiDQiEQhFQgFQfGQeHQdIQdJQcKQbKQaLQ`MQ`NQ_OQ^PQ]PQ\QQ[RQ[SQZTQYTQXUQWVQVWQVXQUYQTYQSZQR[QR\QQ]QP^QO^QN_QM`QMaQLbQKbQJcQIdQHeQHfQGgQFgQEhQDiQCjQCkQBlQAlQ@mQ?nQ?oQ>pQ=pQADGJ M PSVXXX X XYYYYYZZZ"Z$Z&Z})[z+[x-[u/[s2[p4\n6\l8\j:\g<\e>\c@]aB]^D]\F]ZH]XJ]VL]TN^RP^PR^NT^LV^JX^HY^F[_D]_B__@`_>b_$<&:'8)7+5,3.10/2-4+5)7'9%;#=!?ABDFHJLNP S UWY[\\\\ \ [[[[[ZZZ Z#Z%Z~(Y|+Yy.Yw0Yt3Yr6Xo9XmXgAXeDWbGW_JW\MWYPWWSVTWVQZVN]VK`VHdUEgUBjU>nU;qT8uT5xT2|T.S+S(S$S!RRRRQQ QPPONNMLKJJIHG F F E D C BAA@?>==<;:988n]L";3*CS bl}k$nk4`jBQjQCi_5in(h{h ggeca^\ Z XVTRPNKIGE"C$A&?(=*:,8.61432507.9,;)>'@%B#D!FHKMOQSUX Z \ ^`ceghhhh h hhhhhh|hzhxhvh"th$qh&oh(mh*kh-hh/fh1dh3bh6_h8]i:[iWiATiCRiEPiGMiJKiLIiNGiPDiSBiU@iW>iY;i[9i^7i`5ib2ie0ig.ii+ik)in'ip%ir"it iwiyi{i}iiiii i iiijj5Px6Pw7Pw8Pv8Pu9Pt:Ps;PrPo?Pn@PnAPmAPlBPkCPjDPiEPiFPhFPgGPfHPeIPdJPdKPcKPbLPaMP`NP`OP_PP^PP]QP\RP[SP[TPZTPYUPXVPWWPVXPVYPUYPTZPS[PR\PR]PQ^PP^PO_PN`PMaPMbPLbPKcPJdPIePHfPHgPGgPFhPEiPDjPCkPClPBlPAmP@nP?oP?pP>pP=qPADGJ MPSVWWW W XXXXXYYY Y#Y%Z'Z})Zz,Zx.Zu0[s2[p4[n7[l9[j;[g=\e?\cA\aC\^E\\G\ZI]XK]VM]TO]RQ]PS]NT]LV^JX^HZ^F\^D^^B_^@a^>c_nT;rT8uS5yS2|S.S+R(R$R!RQQQPP PPONNMLKJJIHGF F E D C B AA@?>==<;:9887p^M"<3+CS bm}l#nl2`kAQkPCj^5jl(izi hhfdb`] [ YWUSQOMJHF"D$B&@(>*<,9.71533517/9-;*>(@&B$D"F HKMOQSUXZ \ ^`cegiiiii i iiiii|izixivi!ti#qi%oi'mi)ki,hi.fj0dj2bj4_j7]j9[j;Yj=Wj@TjBRjDPjFMjHKjKIjMGjODjQBjT@jV>jX;jZ9j]7j_5ja2jc0jf.jh+jj)jl'jo%jq"js jvjxjzj|jjjjj k kkkkk6Ox7Ow8Ow8Ov9Ou:Ot;OsOp?Oo@OnAOnAOmBOlCOkDOjEOiFOiFOhGOgHOfIOeJOdKOdKOcLObMOaNO`OO`PO_PO^QO]RO\SO[TO[TOZUOYVOXWOWXOVYOVYOUZOT[OS\OR]OR^OQ^OP_OO`ONaOMbOMbOLcOKdOJeOIfOHgOHgOGhOFiOEjODkOClOClOBmOAnO@oO?pO?pO>qO=rOADG J MPSVVVW W WWWXXXXX!Y#Y%Y(Y}*Yz,Zx/Zu1Zs3Zp5Zn7Zl9[j;[g>[e@[cB[aD[^F\\H\ZJ\XL\VN\TO\RQ]PS]NU]LW]JY]H[]F\]D^^B`^@b^>c^"=$;&9'7)5+4,2.00.2,4*5(7&9$;"= ?ABDFHJLN P S UWY[[[[ Z Z ZZZZYYYY!Y$X'X)X|,Xz/Xw2Xt4Wr7Wo:Wm=Wj@VgCVeFVbIV_LV\OUYRUWUUTXUQ[UN^TKbTHeTEhTBlS?oS;sS8vS5zR2}R.R+R(Q$Q!QPPPPO OONNMLKJJIHGFF E D C B A A@?>==<;:98876q_N"=3,CS bn}m"nm1`l@QlOCk]5kk(jyj iigeca^ \ ZXVTRPNKIG"E$C&A(?*=,;.8163452709.;,>)@'B%D#F!HKMOQSUXZ \ ^ `cegijjjj j jjjjj|jzjxjvjtj"qj$oj&mk(kk*hk-fk/dk1bk3_k6]k8[k:YkTkARkCPkEMkGKkJIkLGkNDkPBkS@kU>kW;kY9k\7k^5k`2kb0ke.kg+ki)kk'kn%kp"kr ktkwkyk{k~llll l lllll7Nx8Nw8Nw9Nv:Nu;NtNq?Np@NoANnANnBNmCNlDNkENjFNiFNiGNhHNgINfJNeKNdKNdLNcMNbNNaON`PN`PN_QN^RN]SN\TN[TN[UNZVNYWNXXNWYNVYNVZNU[NT\NS]NR^NR^NQ_NP`NOaNNbNMbNMcNLdNKeNJfNIgNHgNHhNGiNFjNEkNDlNClNCmNBnNAoN@pN?pN?qN>rN=sN;841#.'**'-$1!47;>ADG J MPSUUV V VVVWWWWXX!X$X&X(Y}+Yz-Yx/Yu1Ys4Yp6Zn8Zl:ZjZe@[cB[aD[^F[\H[ZJ[XL\VN\TP\RR\PT\NV\LW\JY]H[]F]]D_]B`]@b]>d]"<$:&9'7)5+3,1./0-2,4*5(7&9$;"= ?ABDFHJLN P RUWYZZZZ Z ZYYYYYYXX"X%X'X*W|-Wz/Ww2Wt5Wr8Vo;Vm=Vj@VgCVeFUbIU_LU\OUYRTWVTTYTQ\TN_TKbSHfSEiSBlS?pR;sR8wR5zR2~Q.Q+Q(Q$P!PPOOOO NNNMLKJJIHGFFE D C B A A @?>==<;:988765r`O">3-CS bo}o!nn0`n?QmNCl\5lj(kxk jjhfdb` ] [YWUSQOMJH"F$D&B(@*>,<.9173553719/;->*@(B&D$F"H KMOQSUXZ\ ^ `cegikkkkk k kkkk|kzkxkvktl!ql#ol%ml'kl)hl,fl.dl0bl2_l4]l7[l9Yl;Wl=Tl@RlBPlDMlFKlIIlKGlMDlOBlQ@lT>lV;lX9lZ7l]5l_2la0lc.lf+lh)lj'lm%lo"lq lsmvmxmzm|mmmm m mmmmm8Nx8Nw9Nw:Nv;NuNr?Nq@NpANoBNnBNnCNmDNlENkFNjFNiGNiHNhINgJNfKNeKNdLNdMNcNNbONaPN`PN`QN_RN^SN]TN\TN[UN[VNZWNYXNXYNWYNVZNV[NU\NT]NS^NR^NR_NQ`NPaNObNNbNMcNMdNLeNKfNJgNIgNHhNHiNGjNFkNElNDlNCmNCnNBoNApN@pN?qN?rN>sN=tN:730#-'**'-#1 47;>ADG J MPSTUU U UVVVVVWW W"W$W'X)X}+Xz.Xx0Xu2Ys4Yp6Yn9Yl;Yj=Zg?ZeAZcCZaEZ^GZ\I[ZK[XM[VO[TQ[RR[PT\NV\LX\JZ\H\\F]\D_\Ba]@c]>d]QnMCn[5mi(mwl lkigeca ^ \ZXVTRPNKI"G$E&C(A*?,=.;1836547290;.>,@)B'D%F#H!KMOQSUXZ\ ^ ` cegikllll l llll|mzmxmvmtmqm"om$mm&km(hm+fm-dm/bm1_m3]m6[m8Ym:WmRmAPmCMmEKmGImJGmLDmNBmP@mS>mU;mW9mY7m\5m^2m`0mb.me+mg)mi'nk%nn"np nrntnwnyn{n~nnn n nnnnn8Mx9Mw:Mw;MvMr?Mr@MqAMpBMoBMnCMnDMmEMlFMkFMjGMiHMiIMhJMgKMfKMeLMdMMdNMcOMbPMaPM`QM`RM_SM^TM]TM\UM[VM[WMZXMYYMXYMWZMV[MV\MU]MT^MS^MR_MR`MQaMPbMObMNcMMdMMeMLfMKgMJgMIhMHiMHjMGkMFlMElMDmMCnMCoMBpMApM@qM?rM?sM>tM=uMADG JMPSTTT T UUUUVVVV V#W%W'W*W},Wz.Xx0Xu3Xs5Xp7Xn9Yl;Yj=Yg?YeAYcCYaFZ^HZ\IZZKZXMZVOZTQ[RS[PU[NW[LY[JZ[H\\F^\D`\Bb\@c\>e\.<1937557391;/>-@*B(D&F$H"K MOQSUXZ\^ ` cegikmmmmm m nnn|nznxnvntnqn!on#mn%kn'hn)fn,dn.bn0_n2]n5[n7Yn9Wn;Tn=Rn@PnBMnDKnFInIGnKDnMBnO@nR>nT;nV9nX7n[5n]2n_0na.od+of)oh'oj%om"oo oqosovoxozo|ooo o ooooo9Lx:Lw;LwLs?Lr@LrALqBLpBLoCLnDLnELmFLlFLkGLjHLiILiJLhKLgKLfLLeMLdNLdOLcPLbPLaQL`RL`SL_TL^TL]UL\VL[WL[XLZYLYYLXZLW[LV\LV]LU^LT^LS_LR`LRaLQbLPbLOcLNdLMeLMfLLgLKgLJhLIiLHjLHkLGlLFlLEmLDnLCoLCpLBpLAqL@rL?sL?tL>uL=uLAD G JMPSSST T TTTUUUUV!V#V&V(V*W}-Wz/Wx1Wu3Ws5Xp8Xn:XlXg@XeBYcDYaFY^HY\JYZLZXNZVPZTRZRTZPVZNW[LY[J[[H][F_[D`[Bb[@d\>f\!<";$9&7'5)3+1,0..0,2*3(5&7$9"; =?@BDFHJL N P RUWYYYX X X XXWWWWWV!V$V'V)V,U|/Uz1Uw4Uu7Ur:To=Tm?TjBTgETeHSbKS_NS\QSZTRWXRT[RQ^RNaQKdQHhQEkQBnP?rP;uP8yP5|O2O.O+N(N$N!NMMMLL LLKJJIHGFFEDCB A A @ ? > ==<;:988765443vdS"B31C Sbr}rnq-`q.@,B)D'F%H#K!MOQSUXZ\^ ` c egiknnnoo o ooo|ozoxovotoqo oo"mo$ko&ho(fo+do-bo/_o1]o3[o6Yo8Wo:TooS;oU9oW7pY5p\2p^0p`.pb+pe)pg'pi%pk"pn ppprpupwpyp{p~pp p ppppp:Kx;KwKt?Ks@KrAKrBKqBKpCKoDKnEKnFKmFKlGKkHKjIKiJKiKKhKKgLKfMKeNKdOKdPKcPKbQKaRK`SK`TK_TK^UK]VK\WK[XK[YKZYKYZKX[KW\KV]KV^KU^KT_KS`KRaKRbKQbKPcKOdKNeKMfKMgKLgKKhKJiKIjKHkKHlKGlKFmKEnKDoKCpKCpKBqKArK@sK?tK?uK>uK=vKAD G JMPRRS S SSTTTTTUU"U$U&U)V+V}-Vz0Vx2Wu4Ws6Wp8Wn:Wlf[!<":$8&6'5)3+1,/.-0+2)3'5%7#9!;=?@BDFHJL N PRUWXXXX X WWWWWVVVV"V%U'U*U-U|/Uz2Tw5Tu8Tr:To=Tm@SjCSgFSeISbLR_OR\RRZURWXQT[QQ_QNbQKePHhPElPBoP?sO = =<;:9887654432weT"C32C"Sbr }sns,`r;QqICqX5pf(pto onljhfd b `][YWUSQOM"J$H&F(D*B,@.>1<39577593;1>/@-B*D(F&H$K"M OQSUXZ\^` c egiknppppp p pp|pzpxpvptpqpop!mp#kp%hp'fp)dp,bp._p0]p2[p5Yp7Wp9Tp;Rp=Pp@MpBKpDIpFGpIDpKBpM@pO>qR;qT9qV7qX5q[2q]0q_.qa+qd)qf'qh%qj"qm qoqqqsqvqxqzq}qq q qqqqq;JxJu?Jt@JsAJrBJrBJqCJpDJoEJnFJnFJmGJlHJkIJjJJiKJiKJhLJgMJfNJeOJdPJdPJcQJbRJaSJ`TJ`TJ_UJ^VJ]WJ\XJ[YJ[YJZZJY[JX\JW]JV^JV^JU_JT`JSaJRbJRbJQcJPdJOeJNfJMgJMgJLhJKiJJjJIkJHlJHlJGmJFnJEoJDpJCpJCqJBrJAsJ@tJ?uJ?uJ>vJ=wJ:740-#*''*#- 147;>AD G JMPQRR R RSSSSTTT T"T%U'U)U,U}.Uz0Vx2Vu5Vs7Vp9Vn;Wl=Wj?WgAWeCWcEXaGX^IX\KXZMXXOXVQYTSYRUYPWYNYYLZZJ\ZH^ZF`ZDbZBcZ@eZ>g[SmASjDRgGReJRbMR_PQ\SQZVQWYQT\PQ_PNcPKfPHiOElOBpO?sO = = <;:98876544321xfU"D33C#Sbr }tnt+`s:QsHCrW5qe(qsp pomkige c a_\ZXVTRPN"L$I&G(E*C,A.?1=3;587694;2>0@.B,D)F'H%K#M!OQSUXZ\^` c e giknpqqqq q qq|qzqxqvqtqqqoq mq"kq$hq&fq(dq+bq-_q/]q1[q3Yq6Wq8Tq:RqrP;rS9rU7rW5rY2r\0r^.r`+rb)re'rg%ri"rl rnrprrrurwryr{r~r r rrrrrJv?Ju@JtAJsBJrBJrCJqDJpEJoFJnFJnGJmHJlIJkJJjKJiKJiLJhMJgNJfOJePJdPJdQJcRJbSJaTJ`TJ`UJ_VJ^WJ]XJ\YJ[YJ[ZJZ[JY\JX]JW^JV^JV_JU`JTaJSbJRbJRcJQdJPeJOfJNgJMgJMhJLiJKjJJkJIlJHlJHmJGnJFoJEpJDpJCqJCrJBsJAtJ@uJ?uJ?vJ>wJ=xJAD GJMPQQQ Q RRRRSSSS!T#T%T(T*T,U}/Uz1Ux3Uu5Us7Vp:VnVj@VgBWeDWcFWaHW^JW\LXZNXXPXVRXTTXRUXPWYNYYL[YJ]YH_YF`YDbZBdZ@fZ>gZ=!;"9$7&5'4)2+0,..,0*2(3&5$7"9 ;=?@BDFHJL N PRUWWWWV V VVVVUUUU!U#T&T(T+T.S|0Sz3Sw6Su9SrRmARjDRhGQeJQbMQ_PQ]SQZVPWZPT]PQ`ONcOKfOHjOEmNBqN?tN = = < ;:988765443210yhV"E34C$Sbr }unu*`t8QtGCsV5rd(rrq qpnljhf d b`][YWUSQO"M$J&H(F*D,B.@1>3<597795;3>1@/B-D*F(H&K$M"O QSUXZ\^`c e giknprrrr r r r|rzrxrvrtrqrormr!kr#hr%fr'dr*br,_r.]r0[r2Yr5Wr7Tr9Rr;Pr=Ms@KsBIsDGsFDsIBsK@sM>sO;sR9sT7sV5sX2s[0s].s_+sa)sd'sf%sh"sj smsosqstsvsxszs}s s sssss=Ix=Iw>Iw?Iv@IuAItBIsBIrCIrDIqEIpFIoFInGInHImIIlJIkKIjKIiLIiMIhNIgOIfPIePIdQIdRIcSIbTIaTI`UI`VI_WI^XI]YI\YI[ZI[[IZ\IY]IX^IW^IV_IV`IUaITbISbIRcIRdIQeIPfIOgINgIMhIMiILjIKkIJlIIlIHmIHnIGoIFpIEpIDqICrICsIBtIAuI@uI?vI?wI>xI=yIA D GJMPPPP QQQQRRRRS!S$S&S(T+T-T}/Tz1Tx4Uu6Us8Up:Un
                Vj@VgCVeEVcGVaIW^KW\MWZNWXPWVRWTTXRVXPXXNZXL\XJ]YH_YFaYDcYBdY@fY>hZ = = < ; :9887654432100{iW"F36C%Sbr }wnv(`u7QuFCtT5tc(sqr rqomkig e ca_\ZXVTRP"N$L&I(G*E,C.A1?3=5;7896;4>2@0B.D,F)H'K%M#O!QSUXZ\^`c e g iknprssss s s|szsxsvstsqsosms ks"hs$fs&ds(bs+_s-]s/[s1Ys4Ws6Tt8Rt:PttN;tQ9tS7tU5tW2tZ0t\.t^+t`)tc'te%tg"ti tltntptrtutwtyt|t~ t tuuuu=Hx>Hw?Hw@HvAHuBHtBHsCHrDHrEHqFHpFHoGHnHHnIHmJHlKHkKHjLHiMHiNHhOHgPHfPHeQHdRHdSHcTHbTHaUH`VH`WH_XH^YH]YH\ZH[[H[\HZ]HY^HX^HW_HV`HVaHUbHTbHScHRdHReHQfHPgHOgHNhHMiHMjHLkHKlHJlHImHHnHHoHGpHFpHEqHDrHCsHCtHBuHAuH@vH?wH?xH>yH=zHA D GJMOOP P PPQQQQQR R"R$R'S)S+S.S}0Tz2Tx4Tu7Ts9Tp;Un=Ul?UjAUgCUeEVcGVaIV^KV\MVZOWXQWVSWTUWRWWPXWNZXL\XJ^XH`XFbXDcXBeY@gY>hY = = < ; : 9887654432100/|jY"H37C&Sbr }xnw'`v6QvECuS5ub(tpt} srpnljh f db`][YWUSQ"O$M&J(H*F,D.B1@3>5<7997;5>3@1B/D-F*H(K&M$O"Q SUXZ\^`ce g iknprtttt t t |tztxtvtttqtotmtkt!ht#ft%dt'bt*_t,]t.[u0Yu2Wu5Tu7Ru9Pu;Mu>Ku@IuBGuDDuFBuI@uK>uM;uO9uR7uT5uV2uX0u[.u]+u_)ua'ud%uf"uh ukumuouqutuvuxuzv} v vvvvv>Gx?Gw@GwAGvBGuBGtCGsDGrEGrFGqFGpGGoHGnIGnJGmKGlKGkLGjMGiNGiOGhPGgPGfQGeRGdSGdTGcTGbUGaVG`WG`XG_YG^YG]ZG\[G[\G[]GZ^GY^GX_GW`GVaGVbGUbGTcGSdGReGRfGQgGPgGOhGNiGMjGMkGLlGKlGJmGInGHoGHpGGpGFqGErGDsGCtGCuGBuGAvG@wG?xG?yG>zG=zG<{G;|G:}G:~G9G8G7G6G5G5G4G3G2G1G1G0G/G.G-G,G,G+G*G)G(G'G'G&G%G$G#G#G"G!G GGGGGGGGGGGGGGGGGGGGGGG G G G G G GGGGGGGGGGGEB > ;740-*#''$* -147;>A DGJMNOO O OPPPPQQQ Q#R%R'R*R,R.S}1Sz3Sx5Su7Ts9Tp;Tn>Tl@TjBUgDUeFUcHUaJU^LV\NVZPVXRVVSVTUVRWWPYWN[WL]WJ_WH`XFbXDdXBfX@gX>iXPp@PmCPjFPhIOeLObOO_RO]UNZXNW\NT_NQbMNeMKiMHlMEoLBsL?vL= = < ; : 9 88765443210//.}kZ"I38C'Sbr}ynx&`x5QwDCvR5va(uou| tsqomki g eca_\ZXVTR"P$N&L(I*G,E.C1A3?5=7;98;6>4@2B0D.F,H)K'M%O#Q!SUXZ\^`ce g i knprtuuuu u |uzuxuvutuquoumuku hu"fu$du&bv(_v+]v-[v/Yv1Wv4Tv6Rv8Pv:MvvL;vN9vQ7vS5vU2vW0vZ.v\+v^)v`'vc%ve"vg vivlvnvpwrwuwwwyw| w~ wwwww?Fx@FwAFwBFvBFuCFtDFsEFrFFrFFqGFpHFoIFnJFnKFmKFlLFkMFjNFiOFiPFhPFgQFfRFeSFdTFdTFcUFbVFaWF`XF`YF_YF^ZF][F\\F[]F[^FZ^FY_FX`FWaFVbFVbFUcFTdFSeFRfFRgFQgFPhFOiFNjFMkFMlFLlFKmFJnFIoFHpFHpFGqFFrFEsFDtFCuFCuFBvFAwF@xF?yF?zF>zF={F<|F;}F:~F:F9F8F7F6F5F5F4F3F2F1F1F0F/F.F-F,F,F+F*F)F(F'F'F&F%F$F#F#F"F!F FFFFFFFFFFFFFFFFFFFFFFF F F F F F FFFFFFFFFFFDA = :630,)#&'#* -147;> A DGJMNNN N OOOOPPPP!Q#Q&Q(Q*R-R/R}1Rz3Rx6Su8Ss:SpTl@TjBTgDTeFTcHUaJU^LU\NUZPUXRUVTVTVVRXVPZVN\VL]WJ_WHaWFcWDdWBfW@hX>jX<;!9"7$5%3'1)0+.,,.*0(2&3$5"7 9;=?@BDFH J L NPRTUUTT T TTSSSSSR R#R&R(R+Q.Q0Q|3Qz6Pw9Pu;Pr>PpAOmDOjGOhJOeMNbPN_SN]VNZYMW\MT_MQcMNfLKiLHmLEpLBsK?wK== < ; : 9 8 8765443210//.-~~l["J39C)Sbr}zny%`y4QxCCwQ5w_(vnv{ uuspnlj h fdb`^[YWUS"Q$O&M(J*H,F.D1B3@5>7<99;7>5@3B1D/F-H*K(M&O$Q"S UXZ\^`ceg i knprtvvvv v |v zvxvvvtvqvovmvkvhw!fw#dw%bw'_w*]w,[w.Yw0Ww2Tw5Rw7Pw9Mw;Kw>Iw@GwBDwDBwG@wI>wK;wM9wO7wR5wT2wV0wX.w[+w])w_'wb%wd"wf whxkxmxoxqxtxvxxxz x} xxxxx@ExAEwBEwBEvCEuDEtEEsFErFErGEqHEpIEoJEnKEnKEmLElMEkNEjOEiPEiPEhQEgREfSEeTEdTEdUEcVEbWEaXE`YE`YE_ZE^[E]\E\]E[^E[^EZ_EY`EXaEWbEVbEVcEUdETeESfERgERgEQhEPiEOjENkEMlEMlELmEKnEJoEIpEHpEHqEGrEFsEEtEDuECuECvEBwEAxE@yE?zE?zE>{E=|E<}E;~E:E:E9E8E7E6E5E5E4E3E2E1E1E0E/E.E-E,E,E+E*E)E(E'E'E&E%E$E#E#E"E!E EEEEEEEEEEEEEEEEEEEEEEE E E E E E EEEEEEEEEEED@ = 962/,(#%'"*-147;> A DGJMMM M NNNNOOOOP"P$P&P)Q+Q-Q0Q}2Rz4Rx6Ru8Rs;Rp=Sn?SlASjCSgESeGTcITaKT^MT\OUZQUXSUVUUTWURXUPZVN\VL^VJ`VHaVFcWDeWBgW@hW>jW<: 8"6$5%3'1)/+-,+.)0'2&3$5"7 9;=?@BDFH J LNPRTTTT T S SSSSRRRR!R$Q&Q)Q,Q.P1P|4Pz6Pw9Pu==< ; : 9 8 8 765443210//.-,}~n\"K3:C*Sb r}{nz$`z3QyBCyP5x^(wlwz vvtqomk i geca_\ZXVT"R$P&N(L*I,G.E1C3A5?7=9;;8>6@4B2D0F.H,K)M'O%Q#S!UXZ\^`ceg i k nprtvwwww |w zwxwvwtwqwoxmxkxhx fx"dx$bx&_x(]x+[x-Yx/Wx1Tx4Rx6Px8Mx:KxxJ;xL9xN7xQ5xS2xU0xW.xZ+x\)x^'x`%yc"ye ygyiylynypysyuywyy y| y~yyyyAExBEwBEwCEvDEuEEtFEsFErGErHEqIEpJEoKEnKEnLEmMElNEkOEjPEiPEiQEhREgSEfTEeTEdUEdVEcWEbXEaYE`YE`ZE_[E^\E]]E\^E[^E[_EZ`EYaEXbEWbEVcEVdEUeETfESgERgERhEQiEPjEOkENlEMlEMmELnEKoEJpEIpEHqEHrEGsEFtEEuEDuECvECwEBxEAyE@zE?zE?{E>|E=}E<~E;E:E:E9E8E7E6E5E5E4E3E2E1E1E0E/E.E-E,E,E+E*E)E(E'E'E&E%E$E#E#E"E!E EEEEEEEEEEEEEEEEEEEEEEE E E E E E EEEEEEEEEEEC? < 851.+(#$'!*-147;> A DGJLLL M MMMNNNOO O"O%O'P)P,P.P0Q}2Qz5Qx7Qu9Rs;Rp=Rn?RlBRjDSgFSeHScJSaLS^NT\PTZQTXSTVUTTWURYUP[UN]UL^UJ`VHbVFdVDfVBgV@iW>kW@BDFH J LNPRTTSS S SSRRRRRQQ"Q$Q'P)P,P/P2P|4Oz7Ow:Ou=Or?NpBNmENjHNhKMeNMbQM_TM]WLZZLW^LTaKQdKNgKKkKHnJEqJBuJ?xI<|I9I5I2H/H+H(G%G!GFFFEE EDDCBAA@?>==<; : 9 8 8 7 65443210//.-,+|}o~]"~L3;C+Sb r}|n|#`{2QzACzO5y](xkxy wwuspnl j hfdb`^[YWU"S$Q&O(M*J,H.F1D3B5@7>9<;9>7@5B3D1F/H-K*M(O&Q$S"U XZ\^`cegi k nprtvxxxx |x zx xxvytyqyoymykyhyfy!dy#by%_y']y*[y,Yy.Wy0Ty2Ry5Py7My9Ky;Iy>Gy@DyBByD@yG>yI;yK9yM7yP5yR2yT0yV.zY+z[)z]'z_%zb"zd zfzhzkzmzozqztzvzx z{ z}zzzzBDxBDwCDwDDvEDuFDtFDsGDrHDrIDqJDpKDoKDnLDnMDmNDlODkPDjPDiQDiRDhSDgTDfTDeUDdVDdWDcXDbYDaYD`ZD`[D_\D^]D]^D\^D[_D[`DZaDYbDXbDWcDVdDVeDUfDTgDSgDRhDRiDQjDPkDOlDNlDMmDMnDLoDKpDJpDIqDHrDHsDGtDFuDEuDDvDCwDCxDByDAzD@zD?{D?|D>}D=~D<D;D:D:D9D8D7D6D5D5D4D3D2D1D1D0D/D.D-D,D,D+D*D)D(D'D'D&D%D$D#D#D"D!D DDDDDDDDDDDDDDDDDDDDDDD D D D D D DDDDDDDDDDDB> ; 741-*'#$' *-147;> ADGJKKL L LMMMMNNN!N#O%O(O*O,P/P1P}3Pz5Px8Qu:QsQn@RlBRjDRgFReHRcJSaLS^NS\PSZRSXTTVVTTXTRZTP[TN]UL_UJaUHcUFdUDfVBhV@jV>kV=;9 7"5$4%2'0).+,,*.(0&2$3#5!79;=>@BDFH J LNPRSSSS R RRRRQQQQ Q"P%P'P*P-O/O2O|5Oz8Nw:Nu=Nr@NpCMmFMjIMhLMeOLbRL`UL]XLZ[KW^KTbKQeJNhJKkJHoJErIBuI?yI<|H9H5H2G/G,G(F%F!FEEEDD DCCBAA@?>==<;: 9 8 8 7 6 5443210//.-,++{|p|_"}N3~=C,Sb r}}n}"`|1Q{?C{N5z\(zjyx xxvtqom k igeca_\ZXV"T$R&P(N*L,I.G1E3C5A7?9=;;>8@6B4D2F0H.K,M)O'Q%S#U!XZ\^`cegi k n prtvyyyy|y zz xzvztzqzozmzkzhzfz dz"bz$_z&]z)[z+Yz-Wz/Tz1Rz4Pz6Mz8Kz:Iz=Gz?DzABzC@zE>zH;zJ9zL7zN5{Q2{S0{U.{W+{Z){\'{^%{`"{c {e{g{j{l{n{p{s{u{w {y {|{~{{{BCxCCwDCwECvFCuFCtGCsHCrICrJCqKCpKCoLCnMCnNCmOClPCkPCjQCiRCiSChTCgTCfUCeVCdWCdXCcYCbYCaZC`[C`\C_]C^^C]^C\_C[`C[aCZbCYbCXcCWdCVeCVfCUgCTgCShCRiCRjCQkCPlCOlCNmCMnCMoCLpCKpCJqCIrCHsCHtCGuCFuCEvCDwCCxCCyCBzCAzC@{C?|C?}C>~C=C<C;C:C:C9C8C7C6C5C5C4C3C2C1C1C0C/C.C-C,C,C+C*C)C(C'C'C&C%C$C#C#C"C!C CCCCCCCCCCCCCCCCCCCCCCC C C C C C CCCCCCCCCCCA> : 730-)&##' *-147; > ADGJJKK K LLLLMMMM!N$N&N(N+O-O/O2O}4Pz6Px8Pu:PslV<:9 7"5$3%1'/).+,,*.(0&2$3"5 79;=>@BDF H J LNPRSRRR R RQQQQQPP P#P%O(O+O-O0N3N|6Nz8Nw;Nu>MrAMpDMmGLjILhLLeOLbSK`VK]YKZ\KW_JTbJQeJNiIKlIHoIEsIBvH?zH<}H9G5G2G/F,F(F%E!EEDDDC CCBAA@?>==<;:9 8 8 7 6 5 443210//.-,++*zzq{`"|O3}>C}-S~b r}n~!`}0Q}>C|M5{[({izw yywuspn l jhfdb`^[YW"U$S&Q(O*M,J.H1F3D5B7@9>;<>9@7B5D3F1H/K-M*O(Q&S$U"X Z\^`cegik n prtvyz{{|{ z{ x{ v{t{q{o{m{k{h{f{d{!b{#_{%]{'[{*Y{,W{.T{0R{3P{5M{7K{9I{;G{>D{@B{B@{D>{G;|I9|K7|M5|P2|R0|T.|V+|Y)|['|]%|_"|b |d|f|h|k|m|o|r|t|v |x |{|}|||CBxDBwEBwFBvFBuGBtHBsIBrJBrKBqKBpLBoMBnNBnOBmPBlPBkQBjRBiSBiTBhTBgUBfVBeWBdXBdYBcYBbZBa[B`\B`]B_^B^^B]_B\`B[aB[bBZbBYcBXdBWeBVfBVgBUgBThBSiBRjBRkBQlBPlBOmBNnBMoBMpBLpBKqBJrBIsBHtBHuBGuBFvBEwBDxBCyBCzBBzBA{B@|B?}B?~B>B=B ADGIJJ J KKKKLLLL M"M$M'M)N+N.N0N2O}4Oz7Ox9Ou;Ps=Pp?PnAPlCQjEQgGQeIQcKQaMR^OR\QRZSRXURVWSTYSR[SP]SN^SL`TJbTHdTFfTDgTBiU@kU>lU@BDF H JLNPRRRR Q Q QQQPPPPO!O$O&O)O+N.N1N3N}6Mz9Mw==<;:98 8 7 6 5 4 43210//.-,++*)xysza"{P3{?C|.S}b~r}n`~.Q~=C}L5|Z(|h{v zzxvtro m kigeca_\ZX"V$T&R(P*N,L.I1G3E5C7A9?;=>;@8B6D4F2H0K.M,O)Q'S%U#X!Z\^`cegik n p rtvy{||||z| x| v|t|q|o|m|k|h|f|d| b|"_|$]|&[|)Y|+W|-T|/R|1P|4M|6K|8I|:G|=D|?B}A@}C>}F;}H9}J7}L5}O2}Q0}S.}U+}X)}Z'}\%}^"}a }c}e}g}j}l}n}p}s}u }w }z}|}~}}DAxEAwFAwFAvGAuHAtIAsJArKArKAqLApMAoNAnOAnPAmPAlQAkRAjSAiTAiTAhUAgVAfWAeXAdYAdYAcZAb[Aa\A`]A`^A_^A^_A]`A\aA[bA[bAZcAYdAXeAWfAVgAVgAUhATiASjARkARlAQlAPmAOnANoAMpAMqALqAKrAJsAItAHuAHuAGvAFwAExADyACzACzAB{AA|A@}A?~A?A>A=A ADGIII J JJJKKKLL L#L%M'M*M,M.N1N3N}5Nz7Ox9OuOp@OnBPlDPjFPgHPeJQcLQaNQ^PQ\RQZTRXVRVXRTZRR[SP]SN_SLaSJcSHdSFfTDhTBjT@kT>mT@BDF H JLNPRQQQ Q QPPPPPOOO"O$N'N)N,N/M1M4M}7Mz:Lx==<;:988 7 6 5 4 4 3210//.-,++*)(wxtyb"zQ3z@C{0S|b|r}n`-Q><@9B7D5F3H1K/M-O*Q(S&U$X"Z \^`cegikn p rtvy{}}|}z} x} v} t}q}o}m}k}h}f}d}b}!_}#]}%[}'Y}*W},T}.R}0P}3M}5K}7I}9G~;D~>B~@@~B>~D;~G9~I7~K5~M2~P0~R.~T+~V)~Y'~[%~]"~_ ~b~d~f~h~k~m~o~r~t ~v ~x~{~}E@xF@wF@wG@vH@uI@tJ@sK@rK@rL@qM@pN@oO@nP@nP@mQ@lR@kS@jT@iT@iU@hV@gW@fX@eY@dY@dZ@c[@b\@a]@`^@`^@__@^`@]a@\b@[b@[c@Zd@Ye@Xf@Wg@Vg@Vh@Ui@Tj@Sk@Rl@Rl@Qm@Pn@Oo@Np@Mq@Mq@Lr@Ks@Jt@Iu@Hu@Hv@Gw@Fx@Ey@Dz@Cz@C{@B|@A}@@~@?@?@>@=@<@;@:@:@9@8@7@6@5@5@4@3@2@1@1@0@/@.@-@,@,@+@*@)@(@'@'@&@%@$@#@#@"@!@ @@@@@@@@@@@@@@@@@@@@@@@ @ @ @ @ @ @@@@@@@@@@@?; 8 41-*'$# '*-147; >ADGHHI I IIJJJKKK!K#L&L(L*L-M/M1M4M}6Nz8Nx:NuOp@OnCOlEOjGPgIPeKPcMPaOP^QQ\SQZTQXVQVXQTZRR\RP^RN`RLaSJcSHeSFgSDhSBjS@lT>nT<;97 5"3$2%0'.),+*,(.&0$2"3 579;=>@BDF H JLNPQQQP P PPPOOOON N"N%N'N*M-M/M2M5L}7Lz:Lx=Lu@KrCKpFKmHJkKJhNJeQJbTI`XI][IZ^HWaHTdHQgHNkGKnGHqGEuFBxF?|F<E9E6E2D/D,D(C%C!CBBBAA @@@?>==<;:9887 6 5 4 4 3 210//.-,++*)('vwuxc"xR3yACz1S{ b{r|n`,Q;CJ5~X(~f}t }|zxvtr o mkigeca_]Z"X$V&T(R*P,N.L1I3G5E7C9A;?>=@;B8D6F4H2K0M.O,Q)S'U%X#Z!\^`cegikn p r tvy{}~|~z~x~ v~ t~q~o~m~k~h~f~d~b~ _~"]~$[~&Y~)W~+T~-R~/P~1M4K6I8G:D=B?@A>C;F9H7J5L2O0Q.S+U)X'Z%\"^ acegjlnps u wz|~F@xF@wG@wH@vI@uJ@tK@sK@rL@rM@qN@pO@oP@nP@nQ@mR@lS@kT@jT@iU@iV@hW@gX@fY@eY@dZ@d[@c\@b]@a^@`^@`_@_`@^a@]b@\b@[c@[d@Ze@Yf@Xg@Wg@Vh@Vi@Uj@Tk@Sl@Rl@Rm@Qn@Po@Op@Nq@Mq@Mr@Ls@Kt@Ju@Iu@Hv@Hw@Gx@Fy@Ez@Dz@C{@C|@B}@A~@@@?@?@>@=@<@;@:@:@9@8@7@6@5@5@4@3@2@1@1@0@/@.@-@,@,@+@*@)@(@'@'@&@%@$@#@#@"@!@ @@@@@@@@@@@@@@@@@@@@@@@ @ @ @ @ @ @@@@@@@@@@@>: 7 30-)&## '*-147 ; >ADGGHH H HIIIJJJJ"K$K&K)K+L-L0L2M4M}6Mz9Mx;Nu=Ns?NpANnCNlEOjGOgIOeKOcMPaOP^QP\SPZUPXWQVYQT[QR]QP^RN`RLbRJdRHfRFgSDiSBkS@lS>nS@BD F H JLNPPPPP P OOOONNNN N#M%M(M+M-L0L3L5L}8Kz;Kx>Ku@KrCJpFJmIJkLIhOIeRIbUI`XH][HZ^HWbGTeGQhGNkGKoFHrFEvFByE?|E==<;:98876 5 4 4 3 2 10//.-,++*)(''uvvve"wS3xCCy2Sy"bzr{ n`+Q:CH5W(e~s ~}{ywus q nljhfdb`^["Y$W&U(S*Q,O.M1K3H5F7D9B;@>>@@@>B;D9G7I5K2M0P.R+T)V'Y%["] _bdfikmor t vx{}F?xG?wH?wI?vJ?uK?tK?sL?rM?rN?qO?pP?oP?nQ?nR?mS?lT?kT?jU?iV?iW?hX?gY?fY?eZ?d[?d\?c]?b^?a^?`_?``?_a?^b?]b?\c?[d?[e?Zf?Yg?Xg?Wh?Vi?Vj?Uk?Tl?Sl?Rm?Rn?Qo?Pp?Oq?Nq?Mr?Ms?Lt?Ku?Ju?Iv?Hw?Hx?Gy?Fz?Ez?D{?C|?C}?B~?A?@?????>?=?ADFFG G GHHHIIII J"J%J'K)K,K.K0L3L5L}7Lz9Mx;Mu>Ms@MpBNnDNlFNjHNgJOeLOcNOaPO^RO\TPZVPXXPVYPT[QR]QP_QNaQLcQJdRHfRFhRDjRBkR@mS>oS@BD F HJLNPPPO O O OONNNNMM!M#M&L)L+L.L0K3K6K}9Kz;Jx>JuAJrDJpGImJIkMIhPIeSHbVH`YH]\GZ_GWbGTfFQiFNlFLoFHsEEvEBzE?}D>==<;:988765 4 4 3 2 1 0//.-,++*)(''&ttwuf"vU3wDCx3Sx#byrz n`*Q9CG5V(dr ~|zxvt r omkigeca_]"Z$X&V(T*R,P.N1L3I5G7E9C;A>?@=B;D8F6H4K2M0O.Q,S)U'X%Z#\!^`~c~e~g~i~k~n~p~ r~ t~ v~y~{~}~|zxv t qomkhfdb_ ]"[$Y&W)T+R-P/M2K4I6G8D:B=@?>A;C9F7H5J2L0O.Q+S)U'X%Z"\ ^acegjlnq s uwz|G>xH>wI>wJ>vK>uK>tL>sM>rN>rO>qP>pP>oQ>nR>nS>m           !$'),/1469<>ADp>Pq>Oq>Nr>Ms>Mt>Lu>Ku>Jv>Iw>Hx>Hy>Gz>Fz>E{>D|>C}>C~>B>A>@>?>?>>>=><>;>:>:>9>8>7>6>5>5>4>3>2>1>1>0>/>.>->,>,>+>*>)>(>'>'>&>%>$>#>#>">!> >>>>>>>>>>>>>>>>>>>>>>> > > > > > >>>>>>>>>>><9 5 2.+(%!#'*-147 ; >ADEFF F GGGHHHHI!I#I%J(J*J,J/K1K3K5K}8Lz:LxLs@MpBMnDMlGMjINgKNeMNcONaQO^RO\TOZVOXXOVZPT\PR^PP`PNaQLcQJeQHgQFhQDjRBlR@nR>oR<;975 4"2$0%.',)*+(,'.%0#2!3579;=>@BD F HJLNOOOO O NNNNMMMMM!L$L'L)L,K.K1K4K7J}9Jz >>==<;:9887654 4 3 2 1 0 //.-,++*)(''&%rsytg"uV3vECv4Sw$bxry n`)Q8CF5U(cq ~}{ywu s qnljhf~d~b~`~^"~[$~Y&~W(~U*~S,~Q.~O1~M3~K5~H7~F9~D;~B>~@@~>B~>@;B9E7G5I2K0N.P+R)T'W%Y"[ ]`bdfikmo r tvy{H=xI=wJ=wK=vK=uL=tM=sN=rO=rP=qP=pQ=o)&$!       "$'*,/2479<?ADFILNQ T V Y [ ^ a c fiknpsvx{~}{ywus=5=4=3=2=1=1=0=/=.=-=,=,=+=*=)=(='='=&=%=$=#=#="=!= ======================= = = = = = ===========;8 4 1.*'$!#'*-147 ;>ADEEE F FFGGGGHH!H$I&I(I+I-J/J2J4K6K}8Kz;Kx=Lu?LsALpCLnEMlGMjIMgKMeMNcONaQN^SN\UNZWOXYOV[OT]OR^PP`PNbPLdPJfPHgQFiQDkQBlQ@nQ>pR<:875 3"1$/%.',)**(,&.$0"2 3579;=>@BD F HJLNOONN N NNMMMMLL L"L%K'K*K,K/J2J4J7J}:Iz=Ix@IuBIsEHpHHmKHkNGhQGeTGcWG`ZF]]FZaFWdETgERjEOnDLqDItDFxCB{C?C>> ==<<;:98876544 3 2 1 0 / /.-,++*)(''&%$qrzsh"tW3tFCu5Sv%bwrx n`(Q7CE5T(bp }~~~|~z~x~v ~t ~r~o~m~k}i}g}e}c}a}_"}]$}Z&}X(}V*}T,}R.}P1}N3}L5}I7}G9}E;}C>}A@}?B}=D};F}8H}6K}4M}2O}0Q}.S},U|)X|'Z|%\|#^|!`|c|e|g|i|k|n|p|r| t| v| y|{|}||zxvt q omkhfdb_] ["Y$W&T)R+P-M/K2I4G6D8B:@=>?;A9C7F5H2J0L.O+Q)S'U%X"Z \^acehjln q suwzIADDDE EEFFFFGG G"H$H'H)I+I.I0I2J5J7J}9Jz;Kx=Ku?KsBKpDLnFLlHLjJLgLMeNMcPMaRM^TN\VNZXNXYNV[OT]OR_OPaONcOLdPJfPHhPFjPDkPBmQ@oQ>pQ@B D F HJLNNNNN M MMMLLLLL K#K%K(K*J-J0J2J5I8I};Iz=Hx@HuCHsFHpIGmLGkOGhRFeUFcXF`[F]^EZaEWdEThDRkDOnDLrCIuCFxCB|B?B>>== <<<;:988765443 2 1 0 / / .-,++*)(''&%$#pq{ri"rX3sGCt7Su&bvrvn`'Q6CD5R(ao |}}}}{}y}w }u }s}q}n|l|j|h|f|d|b|`"|^$|\&|Y(|W*|U,|S.|Q1|O3|M5|K7|H9|F;|D>|B@|@B|>D|>;@9B7E5G2I0K.N+P)R'T%W"Y []`bdfikm p rtvyJ;xK;wK;wL;vM;uN;tO;sQOLJG D B ?=:8530.+) &"#$!&(*,.013 5 79;=??>> = =<;;::99 8#7%7(6+6-504245373:2<2?1B0D0G/I/L.N-Q-S~,V|,Yz+[x+^v*`t)cr)ep(hn(jl'mj'ph&rf%ud%wb$z`$|^#\"Z"X!V!T R PNLJHFDBA?=;97531/-+)'%#!     ;;;;;;;;;;:6 3 /,)%"#'*-14 7 ;>ACCD D DEEEEFFF G#G%G'H*H,H.H1I3I5I7J}:JzJu@KsBKpDKnFKlHLjJLgLLeNLcPMaRM^TM\VMZXMXZNV\NT^NR`NPaONcOLeOJgOHhOFjPDlPBnP@oP>qP=;9764 2"0$.%-'+))*',%.#0!13579;<>@B D FHJLNNMM M M MLLLLKKK!K#J&J(J+J.I0I3I6I8H};Hz>HxAHuDGsGGpIGmLFkOFhRFeUEcXE`\E]_EZbDWeDThDRlCOoCLrCIvBFyBC|B?A">>==<< <;;:9887654432 1 0 / / . -,++*)(''&%$#"op|pk"qY3rHCs8St'btrun`&Q4CC5Q(`m {||~|||z|x |v |t{r{p{m{k{i{g{e{c{a"{_${]&{Z({X*{V,{T.{R1{P3{N5{L7{I9{G;{E>{C@{AB{?D{=F{;H{8K{6Mz4Oz2Qz0Sz.Uz,Xz)Zz'\z%^z#`z!czezgzizkznzpzrztz vz yz {z}zzzxvtq o mkhfdb_][ Y"W$T&R)P+M-K/I2G4D6B8@;>=;?9A7C5F2H0J.L+O)Q'S%U"X Z\_acehjl n qsuxK;xK;wL;wM;vfca^\Y W TROMJHEC@>;!9#6%4'1)/+,-*/'0%2"4 68:<>@BD F GIKMONMM L LKKJIIHH!G#G&F(E+E-D0D3C5C8B:A=A?~@B|@Dz?Gx?Iv>Lt=Nr=Qp-<-:,8,6+4*2*0).),(*(('&&$&"% %$$#""!!    ;;;;;;;;;;95 2 /+(%!#'*-14 7 ;>ABCC C DDDDEEEF!F#F&G(G*G-G/H1H4H6I8I}:IzrP<:9753 2"0$.%,'*)(*&,$."0 13579;<>@B D FHJLMMMM L LLLLKKKKJ!J$J&J)I,I.I1H4H6H9H})>%>"==<<<; ;::98876544321 0 / / . - ,++*)(''&%$#""mn}ol"p[3qJCr9Ss)bsrt n`$Q3CB5P(^l z{{{}{{{y zw zuzszqznzlzjzhzfzdzb"z`$z^&z\(zY*zW,zU.zS1zQ3zO5zM7zK9zH;zF>zD@zBBz@Dz>Fz<;>9@7B5E2G0I.K+N)P'R%T"W Y[]`bdfik m prtvK:xzwurpn k i fda_\ZWURP M"K$H&F(C*A,>.3>1=/<-<,;*;(:&:$9"9 8776655433 2 2 110//+::::::::::85 1 .*'$!#'*-14 7;>AABB B CCCDDDEE"E$F&F)F+G-G0G2G4H7H9H};Hz=Ix?IuAIsCJpFJnHJlJJjLKgNKePKcRKaTL^VL\WLZYLX[LV]MT_MRaMPcMNdNLfNJhNHjNFkNDmOBoO@pO>rO@B D FHJLMMLL L LKKKKJJJJ"I$I'I*I,H/H2H4H7G:G}/>,>)=%="<<<;;: ::988765443210 / / . - , ++*)(''&%$#""!lmnm"o\3pKCq:Sq*brrs n`#Q2CA5O(]k yzzz~y|yz yx yvytyrypymykyiygyeyc"ya$y_&y](yZ*yX,yV.yT1yR3yP5yN7yL9yI;yG>yE@yCByADx?Fx=Hx;Kx8Mx6Ox4Qx2Sx0Ux.Xx,Zx)\x'^x%`x#cx!exgxixkxnxpxrxtxvx yx {x }xxwwvtqo m khfdb_][Y W"T$R'P)M+K-I/G2D4B6@8>;;=9?7A5D2F0H.J+M)O'Q%S"V XZ\_acehj l nqpqqrrs t t| uzuxvuvswpxnxkyiyfzd {b!{_#|]%|Z'}X)}U+~S-P/N0K2I4G6D8B:?<==:?8A5C3E1G.I,K)L'N$P"RTVXY[]_a c eghjllkk j iihhgg}f{fye"wd$ud'sc)qc,pb.nb1la3ja6h`8f_;d_=b^?`^B^]D\]G[\IY\LW[NUZQSZSQYVOYXMX[KX]IW_HVbFVdDUgBUi@Tl>Tn+999999999974 0 -*&# #'*-1 4 7;>@AA A BBBCCCDD D"E%E'E)F,F.F0F3G5G7G9H}Hx@HuBIsDIpFInHIlJJjLJgNJePJcRKaTK^VK\XKZZLX\LV^LT_LRaMPcMNeMLgMJhMHjNFlNDnNBoN@qO>sO@ B D FHJLLLLK K KKKJJJJI I#I%I(H*H-H/G2G5G8G:F}=Fz@FxCFuFEsHEpKEmNDkQDhTDeWCcZC`^C]aBZdBWgBUjARnAOqALt@Ix@F{@C???6>3>/=,=)<%<"<;;::: 9988765443210/ / . - , + +*)(''&%$#""! klmn"n]3oLCo;Sp+bqrr n`"Q1C@5N(\j xyyxx}x{ xy xwxuxsxqxoxlxjxhxfxd"xb$x`&x^(x\*xY,xW.xU1xS3xQ5xO7xM9xK;xH>xF@wDBwBDw@Fw>Hw9;<9>7@5B2E0G.I+K)N'P%R"T WY[]`bdgi k ^^_`` a a bbcddeef|fzgxhu!hs#ip$in&jl(ji*kg,ld.lb/m_1m]3n[5nX7oV9pS;pQqL@rJBrGDsEFtBGt@Iu>Ku;Mv9Ov6Qw4Sx2Tx/Vy-Xy*Zz(\z%^{#_|!a|c}e}g~ikln p rtvwyzzy}y {x yxxwvvtvrupuntlt js"is%gr'eq*cq,ap/_p1]o3[o6Yn8Xn;Vm=Tm@RlBPkDNkGLjIJjLIiNGiQEhSChVAgX?fZ=f];e_9eb8dd6dg4ci2ck0bn.ap,as*`u(`x'_z%_}#^!^]\\[[ZZYYX X WVVUUTP>+888888888863 0 ,)%"#'*-1 4 7;>@@@ A AABBBCCC D#D%D(E*E,E/E1F3F6F8G:G}GxAHuCHsEHpGInIIlKIjMIgOJeQJcSJaUJ^WK\YKZ[KX\KV^LT`LRbLPdLNeLLgMJiMHkMFlMDnNBpN@rN>sN<;97542 0".$,%*'))'*%,#.!013579;<>@ B DFHJLLKK K K JJJJIIII!H#H&H(H+G-G0G3G5F8F;F}>EzAExCEuFEsIDpLDnODkRChUCeXCc[B`^B]aBZeAXhAUkARn@Or@Lu@Ix?F|?C?@><>9>6=3=/<,<)<%;";:::99 888765443210// . - , + + *)(''&%$#""! jklo"l^3mMCnvG@vEBvCDvAFv?Hv=Kv;Mv8Ov6Qv4Sv2Uv0Xv.Zv,\v)^v'`v%cv#ev!gvivkvnvpvrvtvvuyu {u }u uuuutqom k hfdb_][YW T"R$P'M)K+I-G/D2B4@6>8;;9=7?5A2D0F.H+J)M'O%Q"S VXZ\_acLLMMNN O OPQQRRSSTUU V"V$W%W'X})Yz+Yx-Zu.Zs0[q2[n4\l6\i8]g9^e;^b=_`?_]A`[C`YDaVFbTHbQJcOLcMNdJOdHQeFSfCUfAWg>XgxI+ 777777777762 / +(%!#'*-1 4 7;>??@ @ @AAABBBC!C$C&D(D+D-D/E2E4E6F9F;F}=Gz?GxAGuCGsEHpGHnJHlLHjNIgPIeRIcSIaUJ^WJ\YJZ[JX]KV_KTaKRbKPdLNfLLhLJjLHkMFmMDoMBpM@rM>tN<:87531 /".$,%*'()&*$,". 013579;<>@ B DFHJKKKK J JJJIIIIHH!H$H&G)G+G.F1F3F6F9EEzADxDDuGDsJDpMCnPCkSChVBfYBc\B`_A]bAZeAXh@Ul@Ro@Or?Lv?Iy?F|>C>@><=9=6<3Sn-borp n` Q/C>5L(Zh vvvvvv} v{ vyvwvuvsvqvovlvjvhvf"vd$vb&v`(v^*v\,vY.vW1vU3vS5vQ7uO9uM;uK>uH@uFBuDDuBFu@Hu>Ku7;:9<7>5@2B0E.G+I)K'N%P"R TWY[::;;<< = = >??@@AABCCD!D#E%E&F(F*G,H.H/I1I3J5J}7Kz8Kx:LuMq@NnANlCOjEOgGPeIPcJQ`LR^NR[PSYRSWSTTUTRWUPYVM[VK\WI^WF`XDbXAdY?eY=gZ:i[8k[6m\3o\1p]/r],t^*v^(x_%y`#{` }aabbcddee f fgghfdb ` _][YWUTRP!N#L&J(I+G-E/C2A4?6>9<;:>8@6B4E2G1I/L-N+Q)S'U&X$Z"\ _adfh~k~m}p}r|t|w {y z{z~yyxxraP>+  777777777751 . +'$!#'*-1 47;>>>? ? @@@AAABB"B$C'C)C+D.D0D2D5E7E9E;F}>Fz@FxBFuDGsFGpHGnJHlLHjNHgPHeRIcTIaVI^XI\ZJZ\JX^JV_JTaKRcKPeKNgKLhKJjLHlLFnLDoLBqM@sM>tM @ B DFHJKJJJ J IIIIHHHHG"G$G'G)F,F/F1F4E7E9EIz>F}>C=@=<<9<6<3;/;,;):%:"998887 7 665443210//.- , + + * ) (''&%$#""! ghir"j`3kOCl?Sm.bnrnn`Q.C<5K(Yg uuuuuu~ u| uzuxuvuturupumukuiug"ue$uc&ua(u_*u],uZ.uX1uV3tT5tR7tP9tN;tL>tJ@tGBtEDtCFtAHt?Kt=Mt;Ot8Qt6St4Ut2Xt0Zt.\t,^t)`t'ct%et#gt!itktnspsrstsvsys{s }s s ssssqomk h fdb_][YWT R"P$M'K)I+G-D0B2@4>6;89;7=5?2A0D.F+H)J'M%O"Q S())**+ + , ,-..//00112 3"3$4&4'5)5+6-6.7082849697:9:;;=;?<@<B=}D>zF>xG?vI?sK@qM@oOAlPAjRBhTCeVCcWDaYD^[E\]EZ_FW`FUbGSdHPfHNhILiIIkJGmJEoKBpK@rL>tM;vM9xN7yN4{O2}O0P-P+Q)Q&R$S"STTUUVVWX X YYZZZXVT S QOMKIHFDB!@$?&=);+9-7052442709.;,>+@)B'E%G#I!L NQSUXZ\_ac f h jmoqtzraP>+  666666666640 - *&# #'*- 1 47;==> > >??@@@AA A#B%B'B*C,C.C1C3D5D8D:EEz@FxBFuEFsGFpIGnKGlMGjOGgQHeSHcUHaWH^YI\ZIZ\IX^IV`JTbJRdJPeJNgKLiKJkKHlKFnLDpLBrL@sL>uL=;976420 ."-$+%)'')%*#,!.013579;<> @ B DFHJJJJI I IIHHHHGG G"G%F'F*F-E/E2E5E7D:D=D}@CzBCxECuHCsKBpNBnQBkTAhWAfZAc]@``@]c@Zg?Xj?Um?Rp>Ot>Lw>Iz=F~=C<@<<<9;6;3;0:,:)9%9"988776 6 65443210//.-, + + * ) ( ''&%$#""! fghs"ib3jQCk@Sl/blrmn`Q-C;5J(Xf tttttt t} t{tytwtutstqtotltjth"tf$td&tb(t`*t^,t\.sY1sW3sU5sS7sQ9sO;sM>sK@sHBsFDsDFsBHs@Ks>Ms5;79:7<5>2@0C.E+G)I'L%     !!!"#"%#'#($*%,%.&/&1'3'5(6(8):)<*=+?+A,C,D-F-H.J.L/M/O0}Q1zS1xT2vV2sX3qZ3o[4l]4j_5ha5fb6cd7af7_h8\j8Zk9Xm9Uo:Sq:Qr;NtC}>A?>?<@:@7A5B3B0C.C,D)D'E%E#F FGHHIIJJK K LLMNLJIG E CA@><:87 5"3$1'/).+,.*0(2&5%7#9!<>@CEGJLNPS U W Z\^acjxraP> + 555555555530 , )&"#'*- 1 47;<== = >>>??@@@!A#A&A(B*B-B/B1C4C6C8D:D=D}?EzAExCEuEEsGFpIFnKFlMGjOGgQGeSGcUHaWH^YH\[HZ]IX_IVaITbIRdJPfJNhJLjJJkKHmKFoKDpKBrK@tL>uL<:975320 .",$*%('&)%*#,!.013579;<> @ BDFHJIII I H HHHGGGGF F#F&F(E+E-E0E3D5D8D;C=C}@CzCBxFBuIBsLBpOAnRAkUAhX@f[@c^@`a?]d?[g?Xj>Un>Rq>Ot=Lx=I{rL@rJBrGDrEFrCHrAKr?Mr=Or;Qr8Sr6Ur4Xr2Zr0\r.^r,`r)cr'eq%gq#iq!kqnqpqrqtqvqyq{q}q q q qqqqomkh f db_][YWTR P"M$K'I)G+D-B0@2>4;6987;5=2?0A.D+F)       "$&')+-.024579;<>@BCEGIJLNP Q S!U!W"X"Z#\#}]$z_$xa%vc%td&qf'oh'mj(jk(hm)fo)dq*ar*_t+]v+Zx,Xy,V{-T}.Q.O/M/J0H0F1D1A2?2=3:484654516/6-7*7(8&8$9!9:;;<<==> > ??@AA?=; 9 86421/-+) ("&%$'")!,.03579<>@C E G JLNPSZhvraP > +44444444442/ + (%!#'*- 1 47;<<< = ==>>>??@!@$@&A)A+A.A0B2B4B7C9C;C=D}?DzBDxDEuFEsHEpJEnLFlNFjPFgRFeTGcVGaXG^ZH\\HZ^HX_HVaITcIReIPgINhJLjJJlJHnJFoJDqKBsK@tK>vK @ BDFHIIIH H HHGGGGFFF!F$E&E)E+D.D1D3D6C9C;C>B}AB{DBxGBuIAsLApOAnR@kU@hX@f[?c^?`b?]e>[h>Xk>Un=Rr=Ou=LxqM@qKBqHDqFFqDHqBKq@Mq>Oq3;5977:5<2>0@.  !#%'(*,./13468:; = ? A B D F G I KMNPRSUWYZ\^`acefh}jzlxmvotqqsotmvkxhyf{d}b_][Y V T!R"P"M#K#I$G$D%B%@&=&;'9'7(4)2)0*.*++)+',%,"- -..//0112 2 3344420. , +)'%$" !#%'*,.13 5 7 :<>@CJXftra P >+33333333331. + '$!#'*- 147:;;< <<===>>> ?"?%?'@)@,@.A1A3A5B7B:BC}@CzBDxDDuFDsIDpKEnMElOEjQFgSFeUFcWFaXG^ZG\\GZ^GX`HVbHTdHReHPgINiILkIJmIHnJFpJDrJBsJ@uK>wK @ BDFHIHHH H GGGGFFFEE"E$E'D)D,D.D1C4C6C9B`b>]e>[i=Xl=Uo=RrpN@pLBpJDpGFpEHpCKpAMp?Op=Qp;Sp8Up6Xp4Zp2\o0^o.`o,co)eo'go%io#ko!noporotovoyo{o}oo o o oooomkhf d b_][YWTRP M"K$I'G)D+B-@0>2;496795;2=0?.   "$&(*,.023579;=?ACEGIKMNPRTVWY[\^`bceghjlm o q s t }v {x xy v{ t} romkifdb`][YWURPNLIGEC@><:8531/,*(& # !!!"##$$%% & & ''(('%#" !# & ( *,/13:HVdsr a P>+22222222221- * &# #'* - 147::: ; ;<<<===> >#>%?(?*?-@/@1@3A6A8A:BwJ<;975420. ,"*$)%''%)#*!,.013579:< > @ BDFHHHGG G GFFFFEEE E"D%D'D*C,C/C2C4B7B:B=A?A}BA{EAxH@vK@sN@pQ?nT?kW?hZ>f]>c`>`c=]f=[i=XloO@oMBoKDoHFoFHoDKoBMo@Oo>Qo1;395775:2<0>.    "$&(*,.024679;=?ACEGIKMOPRTVXZ\^`bcegikmoqstvxz|~~|zxvtrpmkigdb`^\YWU S Q N L J H F C A ?=:8642/-+)'$"        "$+9FTbq r aP>+22222222220, ) &"#'* - 14799: : :;;<<<==!=$>&>(>+?-?0?2@4@6@9A;A=A?B}ABzDBxFCuHCsJCpLCnNDlPDjRDgTEeVEcXEaZE^\F\]FZ_FXaFVcGTeGRgGPhGNjHLlHJnHHoHFqIDsIBtI@vI>xJ<:87531/. ,"*$(%&'$)"* ,.013579:< > @BDFHGGG G F FFFEEEED D#D%C(C*C-C0B2B5B8A:A=A@@}C@{F@xH@vK?sN?pQ?nT>kW>hZ>f]=c`=`d=]g<[jnP@nNBnLDnJFnGHnEKnCMnAOn?Qn=Sm;Um8Xm6Zm4\m2^m0`m.cm,em)gm'im%km#nm!pmrmtmvmym{m}mmm m m mlllkhfd b _][YWTRPM K"I$G'D)B+@->0;29476592;0=.    "$&(*,.024689;=?ACEGIKMOQRTVXZ\^`bdegikmoqsuvxz|~~|zywusqpnljhgeca`^\ZXWUSQONLJHFDB@=;97520.,*(%# !             )7DR` o }raP>+1111111111/, ( %"#'* - 147899 9 ::;;;<<<"=$='=)>,>.>0?3?5?7@9@<@>A@A}BAzDBxFBuHBsJCpMCnOClQCjSDgUDeVDcXEaZE^\E\^EZ`FXbFVdFTeFRgGPiGNkGLmGJnHHpHFrHDsHBuI@wI>xI @BDFGGGF F FFEEEDDDD!C#C&C)C+B.B0B3A6A8A;@>@A@}C@{F?xI?vL?sO>pR>nU>kX=h[=f^=ca<`d<]g;[k;Xn;Uq:Rt:Ox:L{9I9F8C8@8=7:7663606,5)5&4"433322 1 10//.-,++*)(' ' & % $ # ""! _`az"bi3cXCdGSe6bf&rfg`Q&C55C(R` mnnnnn n nnn}n{nynwmumsmqmo"mm$mj&mh(mf*md,mb.m`1m^3m\5mY7mW9mU;mS>mQ@mOBmMDmKFmHHmFKmDMmBOl@Ql>Sl/;19375572:0<.    "$&(*,.02468:<=?ACEGIKMOQSTVXZ\^`bdfgikmoqsuwxz|~~|zywusqpnljhgeca`^\ZXWUSQONLJHGECA@><:975320.,+)'%$"   (5BP ^ m |raP>+0000000000.+ ' $!#'* -147788 999::;;; <#<%<'=*=,=/>1>3>5?8?:?<@>@A@}CAzEAxGAuIBsKBpMBnOBlQCjSCgUCeWDcYDa[D^]D\_EZaEXbEVdFTfFRhFPjFNkGLmGJoGHqGFrHDtHBvH@wH>yI=;976420.- +")$'%%'#)!*,.013579: < > @BDFFFFF E EEEDDDDCC"C$B'B)B,B.A1A4A6@9@<@>?A?}D?{G?xJ>vM>sP>pR=nU=kX=i\lR@lPBlNDlLFlJHlGKlEMkCOkAQk?Sk=Uk;Xk8Zk6\k4^k2`k0ck.ek+gk)ik'kk%nk#pk!rktkvkyk{k}kkjj j j jjjjhfdb _ ][YWTRPMK I"G%D'B)@+>-;0927456290;.            !"$&(*,.02468:<>?ACEGIKMOQSUVXZ\^`bdfhikmoqsuwyz~||~zywusqpnljhgeca`^\ZXWUSQONLJHGECA@><:975320.,+)'%$"     &3A N \ kzraP>+//////////-* ' # #' * -14677 7 88999::;!;#;&<(<+<-=/=2=4>6>8>;?=???A@}C@zE@xHAuJAsLApNBnPBlRBjTBgVCeXCcZCa\D^]D\_DZaDXcEVeETgERhEPjFNlFLnFJoFHqGFsGDtGBvG@xH>yH<{H:}H8~I7I5I3I1J/J.J,J*J)K'K%K#K"L LLLLMMMMMNN C A?><:975320., *"($'%%'#)!*,.013579: < >@BDFFFEE E EDDDDCCC B"B%B'B*A,A/A2@4@7@:?{G>xJ>vM=sP=pS=nVkS@kQBkODkMFkKHjHKjFMjDOjBQj@Sj>Uj,;/917355280:.               ! # % & ( * , . 0 2 4 6 8 : < > @ B C E G I KMOQSUWXZ\^`bdfhjkmoqsuwy~z||z~ywusqpnljhgeca`^\ZXWUSQONLJHGECA@><:975320.,+)'%$"     $1 ? M [ixraP>+!..........-) & "#' * -14666 7 788899::!:$;&;);+<.<0<2=5=7=9>;>>>@?B?}D?zF@xH@uJ@sLApNAnPAlRBjTBgVBeXBcZCa\C^^C\`DZbDXdDVeDTgERiEPkENmELnFJpFHrFFsFDuGBwG@xG>zG<|H:}H8H7H5I3I1I/I.I,J*J)J'J%K#K"K KKLLLLLMMMM B A ?=<:86531/-, *"($&%$'") *,.013579: < >@BDFEEE E D DDCCCCBB B#B%A(A*A-@0@2@5?7?:?=?@>B>}E>{H=xK=vN=sQjT@jRBjPDiNFiLHiJKiGMiEOiCQiASi?Ui=Xi;Zi8\i6^i4`i2ci0ei.gi+ii)ki'ni%pi#ri!tiviyh{h}hhhhh h h hhhhfdb_ ] [YWTRPMKI G"D%B'@)>+;-9072542609.                 ! # % ' ) * , . 0 2 4 6 8 : < > @ B D E G I K M O Q S U W Y Z \ ^ ` b d f h j k m o q s u w~ y| {z|y~wusqpnljhgeca`^\ZXWUSQONLJHGECA@><:975320.,+)'%$"     " / = KYgvraP>+ #----------,( % "#' * -14556 6 6778889 9":%:':);,;.;1<3<5<7=:=<=>>@>C>}E?zG?xI?uK@sM@pO@nQAlSAjUAgWAeYBc[Ba]B^_C\aCZbCXdCVfDThDRjDPkENmELoEJqEHrFFtFDvFBwF@yG>{G<|G:~G8H7H5H3H1H/I.I,I*I)J'J%J#J"J KKKKLLLLLMM B @ >=;986421/-+ )"'$%%$'") *,.013579: < >@BDEEDD D DCCCCBBBA!A#A&A(@+@.@0?3?5?8>;>>>@>C=}F={I=xLiU@hSBhQDhOFhMHhKKhHMhFOhDQhBSh@Uh>Xh*;,9/71532508.         !# % ' ) + - . 0 2 4 6 8 : < > @ B D F G I K M O Q S U W Y [ \ ^ ` b d f h j l m o q s u~ w| yz {y |w ~u s q p n l j h g e c a ` ^ \ Z X W U S Q O N L JHGECA@><:975320.,+)'%$"     . ;IWetraP>+ "%----------+' $ !#' *-1444 5 56677788 8#9%9(:*:-:/;1;4;6<8<:<==?=A=C>}E>zG>xJ?uL?sN?pP@nR@lT@jVAgXAeZAc[Aa]B^_B\aBZcCXeCVgCThCRjDPlDNnDLoDJqEHsEFuEDvFBxF@zF>{F<}G:~G8G7G5G3H1H/H.H,I*I)I'I%J#J"J JJKKKKKLLLL A @ ><;975420.,+ )"'$%%#'!)*,.013579 : < >@BDDDDD C CCCBBBAAA!A$@&@)@,?.?1?3>6>9>;>>=A=D=}G<{I(LZ hiiiii h hhhhh~h|hzhxhvht"hr$hp&hn(hl*hi,hg.he1hc3ha5h_7h]9h[;hX>gV@gTBgRDgPFgNHgLKgJMgGOgEQgCSgAUg?Xg=Zg;\g8^g6`g4cg2eg0gg.ig+kg)ng'pf%rf#tf!vfyf{f}ffffff f f ffffdb_] [ YWTRPMKIG D"B%@'>);+9.70522406.         !#%')+-/02468:<>@BDFHIKMOQS U W Y [ ] ^ ` b d f h j l n o q s~ u| wz yy {w }u ~s q p n l j h g e c a ` ^ \ Z X W U S Q O N L J H G E C A @ > < : 9 7 5 3 2 0 . , + ) ' % $ "        ,9GUcrraP> +"$',,,,,,,,,,*' # # ' *-1334 4 55566777!8$8&9(9+9-:0:2:4;7;9;;<=<@xJ>uL>sN?pP?nR?lT@jV@gX@eZAc\Aa^A^`A\bBZdBXeBVgCTiCRkCPmCNnDLpDJrDHsDFuEDwEBxE@zE>|F<}F:F8F7G5G3G1G/H.H,H*H)I'I%I#I"I JJJJJKKKKKL A ? =<:87531/.,* ("&$$%#'!)*,.013579 : <>@BDDDCC C BBBBAAAA @"@%@'?*?,?/>1>4>7>9=<=?=BfW@fUBfSDfQFfOHfMKfKMfHOfFQfDSfBUf@Xf>Zf<\f9^f7`f5cf3ef1gf/if-ke*ne(pe&re$te"ve ye{e}eeeeeee e eeeedb_] [ Y WTRPMKIGD!B$@&>(;*9,7/512305.       !#%')+-/13468:<>@BDFHJKMOQSUWY[]_`bdfhjlnpq~s|uzwyyw{u}sqp n l j h g e c a ` ^ \ Z X W U S Q O N L J H G E C A @ > < : 9 7 5 3 2 0 . , + ) ' % $ "                  *7ESapraP>"+$&)++++++++++)& # # ' *-1223 3 44555667"7$7'8)8,9.9093:5:7::;<;>;@sO>pQ>nS?lU?jW?gY@e[@c]@a_A^`A\bAZdAXfBVhBTjBRkCPmCNoCLqCJrDHtDFvDDwDByE@{E>|E<~E:F8F7F5F3G1G/G.G,H*H)H'H%H#I"I IIJJJJJKKKK @ ? =;:86431/-+* ("&#$%"' )*,.013579 : <>@BDCCC B B BBAAAA@@ @#?%?(?*>->/>2>5=7=:==b^.r__`QC-5<(JX fggfff f ffffff~f|fzfxfv"ft$fr&fp(fn*fl,fi.fg1fe3fc5ea7e_9e];e[>eX@eVBeTDeRFePHeNKeLMeJOeGQeESeCUeAXe?Ze=\e;^e8`e6ce4ee2ge0id.kd+nd)pd'rd%td#vd!yd{d}ddddddd d d ddddb_][ Y WTRPMKIGD B"@%>';)9+7.502204.     !#%')+-/13568:<>@BDFHJLMOQSUWY[]_abdfhjlnp~q|szuywwyu{s}qpnljhgeca`^\ZXWUSQONLJHGEC A @ > < : 9 7 5 3 2 0 . , + ) ' % $ "                 (6CQ_nr}aP!>$+&)+**********(% " # '*-1122 33344556 6"6%7'7*8,8/81939698:::<:?;A;C;E<}GnT>lV>jX?gY?e[?c]@a_@^a@\c@ZeAXgAVhATjBRlBPnBNoBLqCJsCHuCFvDDxDBzD@{D>}E<~E:E8E7F5F3F1F/G.G,G*G)G'H%H#H"H IIIIIJJJJJK @ > <;976420.-+) '"%##%!' )*,./13579 : <>@BCCBB B BAAA@@@@?!?#?&>(>+>->0=3=5=8<;<=<@;C;F;}H:{K:xN:vQ9sT9qW8nZ8k]8i`7fc7cf7ai6^m6[p5Xs5Uw5Rz4O}4L3I3F3C2@2=1:1703000-/)/&.#.--,,+ + **)('&&%$#""!     UVW"Xr3YaCZPS[@b\/r]^_QC,5;(IW eeeeee e eeeeeee}e{eyew"eu$es&eq(eo*em,ej.eh1ef3dd5db7d`9d^;d\>dZ@dWBdUDdSFdQHdOKdMMdKOdIQdFSdDUdBXd@Zd>\d<^d9`d7cd5ec3gc1ic/kc-nc*pc(rc&tc$vc"yc {c}cccccccc c ccbbb_][ Y W TRPMKIGDB!@$>&;(9*7,5/2103.   !#%')+-/13579:<>@BDFHJLNPQSUWY[]_abdfhjln~p|rzsyuwwuys{q}pnljhgeca`^\ZXWUSQONLJHGECA@><:975320.,+)'%$"            &4AO^lr{a!P#>&+(+-))))))))))($ ! # '*-011 1 22334445!5#6&6(6+7-7/828486999;9=:?:A:D;F;}H;zJjX>gZ>e\?c^?a`?^b@\d@Ze@Xg@ViATkARmAPnBNpBLrBJsBHuCFwCDyCBzC@|D>}D<D:E8E7E5E3E1F/F.F,F*G)G'G%G#H"H HHHIIIIJJJJ ? > <:975320.,*( '"%##%!')*,./1357 9 : <>@BBBBB A AA@@@@???!>$>&>)>+=.=1=3<6<8<;;>;A;C:F:}I:{L9xO9vR9sU8qX8n[7k^7ia7fd6cg6aj6^m5[q5Xt4Uw4R{4O~3L3I2F2C1@1=1:0703/0/-.).&-#-,,++* * ))('&&%$#""!      TUV"Ws3XbCYQSZAb[0r\ ]^ QC+5:(HV dddddd d ddddddd~d|dzdx"dv$dt&dr(dp*dn,dl.ci1cg3ce5cc7ca9c_;c]>c[@cXBcVDcTFcRHcPKcNMcLOcJQcGScEUcCXcAZc?\c=^c;`b8cb6eb4gb2ib0kb.nb+pb)rb'tb%vb#yb!{b}bbbbbbbb b a aaaa_][Y W TRPMKIGDB @">%;'9)7+5.2002.   !#%')+-/13579;<>@BDFHJLNPRSUWY[]_acdfhjl~n|pzrytwuuwsyq{p}nljhgeca`^\ZXWUSQONLJHGECA@><:975320.,+)'%$"      %2?M\jr!ya#P%>(+*-/))))))))))'#  # '*-/00 1 12223344!5$5&5)6+6.70727587898<9>9@9B:D:F;}I;zK;xMe]>c_>a`?^b?\d?Zf@Xh@Vj@Tk@RmAPoANqALrBJtBHvBFwBDyCB{C@|C>~C@BBBAA A @@@@???>>">$>'=)=,=/<1<4<6;9;<;>:A:D:G9}J9{M9xO8vR8sU8qX7n[7k^6ia6fe6ch5ak5^n4[q4Xu4Ux3R{3O2L2I2F1C1@0=0:/7/3.0.-.)-&-#,,++** ) )('&&%$#""!       STU"Vu3WcCXSSYBbZ2r["\] QC*58(GU cccccc c cccccccc}c{cy"cw$cu&cs(cq*co,bm.bk1bh3bf5bd7bb9b`;b^>b\@bZBbWDbUFbSHbQKbOMbMObKQbISbFUbDXbBZb@\a>^a<`a:ca7ea5ga3ia1ka/na-pa*ra(ta&va$ya"{a }aaaaaaaa` ` ````_][Y W T RPMKIGDB@!>$;&9(7*5,2/01.      "#%')+-/13579;=>@BDFHJLNPRTUWY[]_acefhj~l|nzpyrwtuuswqyp{n}ljhgeca`^\ZXWUSQONLJHGECA@><:975320.,+)'%$"     #0>LZ hr#wa%P'>*+,/1((((((((((&#   # '*-/// 0 0112233 3"4%4'5)5,5.616375787:8<8>8A9C9E:G:}I:zK;xM;uO;sQaa>^c>\e?Zg?Xh?Vj@Tl@Rn@Pp@NqALsAJuAHvBFxBDzBB{B@}C>C = ;986421/-+)' &"$#"% ')*,./1357 8 :<>@AAAA @ @ @@???>>> >"=%='=*<-a]@a[BaYDaVFaTHaRKaPMaNOaLQaJSaGUaEXaCZ`A\`?^`=``;c`8e`6g`4i`2k`0n`.p`+r`)t`'v`%y`#{`!}``````___ _ _ ____][YW T RPMKIGDB@ >";%9'7)5+2.00.       "$&')+-/13579;=?ABDFHJLNPRTVWY[]_acegh~j|lznypwrutsvqwpyn{l}jhgeca`^\ZXWUSQONLJHGECA@><:975320.,+)'%$"    !.<J X"fr%ua'P)>,+.13''''''''''%"   #'*-../ /0011122 3#3%4(4*4-5/516466687;7=7?8A8C8F9H9}J:zL:xN:uP;sR;pT;nV\e>Zg>Xi?Vk?Tm?Rn@Pp@Nr@Lt@JuAHwAFyADzAB|B@}B>B < :975420.,+)' %"##!%')*,./135 7 8 :<>@AA@@ @ @???>>>==!=#=&<(<+<-;0;2;5:8:::=9@9B9E8H8}K8{N7xQ7vT7sW6qZ6n]5l`5ic5ff4ci4al3^o3[s3Xv2Uy2R}1O1M1J0F0C/@/=.:.7-4-0,-,*,&+#+**)(( ' '&&%$#""!       PQR"Tw3UfCVUSWDbX4rY$Z[ QC(56(ES aaaaaa a aaaaaaaaa}a{"ay$aw&`u(`s*`q,`o.`m1`k3`h5`f7`d9`b;``>`^@`\B`ZD`WF`UH`SK`QM`OO`MQ`KS`IU_FX_DZ_B\_@^_>`_!;$9&7(5*2-0/.        "$&(*+-/13579;=?ACDFHJLNPRTVWY[]_aceg~i|jzlynwpurstqvpxnyl{j}hgeca`^\ZXWUSQONLJHGECA@><:975320.,+)'%$"    ,: H"V$dr'sa)P+>.+035&&&&&&&&&&$!   #'*--. . .//00112!2#2&3(3+4-40425457696;6>7@7B7D8F8H9}K9zM9xO:uQ:sS:pU;nW;lY;j[Xj>Vk>Tm?Ro?Pq?Nr@Lt@Jv@Hw@FyAD{AB|A@~A>B@@@@@ ? ??>>>====!<$<&<);+;.;0:3:6:89;9>9@8C8F8I7}L7{N7xQ6vT6sW5qZ5n]5l`4ic4ff4cj3am3^p2[s2Xw2Uz1R}1P0M0J/G/C/@.=.:-7-4,0,-+*+&*#*))((' ' &&%$#""!        OPQ"Rx3TgCUVSVEbW5rX%YZ QC'55(DR `````` ` ``````````|"_z$_x&_v(_t*_r,_p._n1_l3_i5_g7_e9_c;_a>__@_]B_[D_YF_VH_TK_RM_PO_NQ^LS^JU^GX^EZ^C\^A^^?`^=c^;e^8g^6i^4k^2n^0p^.r^+t^)v^'y^%{^#}^!^]]]]]]]] ] ] ]]]][YWT R PMKIGDB@> ;#9%7'5)2+0..          "$&(*,./13579;=?ACEFHJLNPRTVXY[]_ace~g|izjylwnupsrqtpvnxlyj{h}geca`^\ZXWUSQONLJHGECA@><:975320.,+)'%$"    * 8"F$T&cr(qa+P->0+257%%%%%%%%%%#    #'*,,- - ..//0001"1$2'2)3,3.304345575:5<6>6@6C7E7G8I8}K8zM9xO9uQ9sS:pU:nW:lY;j[;g];e_Tn>Rp>Pq?Ns?Lu?Jv@Hx@Fz@D{@B}A@A>A@@??? ? >>>====<<"<$;';);,:.:1:496999;8>8A8D7F7I7~L6{O6yR6vU5sX5q[4n^4la4id3fg3cj2am2^q2[t1Xw1U{0S~0P0M/J/G.C.@-=-:,7,4+0+-***&)#)((''& & %%$#""!         NOP"Qy3RhCSWSTGbV6rW&XYQC&54(CQ ______ _ _________^~"^{$^y&^w(^u*^s,^q.^o1^m3^k5^h7^f9^d;^b>^`@^^B^\D^ZF^WH^UK^SM^QO]OQ]MS]KU]IX]FZ]D\]B^]@`]>c];!9$7&5(2*0-."                 "$&(*,.013579;=?ACEGHJLNPRTVXZ[]_ac~e|gziykwlunspqrptnvlxjzh{g}eca`^\ZXWUSQONLJHGECA@><:975320.,+)'%$"     )!6$D&R(ar*oa-P/>2+479$$$$$$$$$$#    #'*+,, , --..//0 0"1%1'1*2,2/313336484:5=5?5A6C6E7H7J7}L8zN8xP8uR9sT9pV9nX:lZ:j\:g^;e`;cb;ad<^e<\gPr>Nt>Lu?Jw?Hy?Fz?D|@B~@@@>A???? > > >====<<< ;";%;':*:,:/929497898<8?7B7D7G6J6~M6{P5yS5vV5sX4q[4n_3lb3ie3fh2dk2an1^q1[u1Xx0U{0S/P/M.J.G.D-@-=,:,7+4+0*-**)&)#((''&& % $$#""!          MNO"P{3QiCRXSSHbT7rU'VWQC$53(AP ^^^^^^ ^ ^^^^^^^^]]"]|$]z&]x(]v*]t,]r.]p1]n3]l5]j7]g9]e;]c>]a@]_B]]D][F]YH]VK\TM\RO\PQ\NS\LU\JX\GZ\E\\C^\A`\?c\=e\;g\8i\6k\4n\2p\0r\.t\+v\)y\'{[%}[#[![[[[[[[[[ [ [ [[[[YWTR P MKIGDB@>; 9#7%5'2)0+.$"       """"" " " ""!!!!!!!! !"!$!&!(!* , . 0 2 4 5 7 9 ; = ? A CEGIJLNPRTVXZ\]_a~c|ezgyiwkumsnqpprntlvjxhzg|e}ca`^\ZXWUSQONLJHGECA@><:975320.,+)'%$"      !'#4%B(P*_r,ma/}P1>4+69<$$$$$$$$$$"   #'**++ ,,--..//!/#0&0(1+1-2/222436394;4=4@5B5D5F6H6J7}L7zO7xQ8uS8sU8pW9nY9l[9j]:g^:e`:cb;ad;^f;\hLv>Jx>Hy?F{?D}?B~?@@>@<@:A8A7A5A3B1B/B.B,C*C)C'C%D#D"D DEEEEFFFFFG < : 875320.,*)'% #"!#%'(*,./13 5 7 8:<>??>> > ====<<<;;!;#:%:(:*:-909295878:7=7?7B6E6H6K5~M5{P5yS4vV4sY3q\3n_3lb2ie2fh2dl1ao1^r0[u0Xy/U|/S/P.M.J-G-D,@,=+:+7*4*0)-)*(&(#''&&%% $ $#""!           KMN"O|3PkCQZSRIbS9rT(UV QC#52(@O ]]]]]] ] ]]]]]]\\\\"\~$\{&\y(\w*\u,\s.\q1\o3\m5\k7\h9\f;\d>\b@\`B\^D\\F\ZH[WK[UM[SO[QQ[OS[MU[KX[IZ[F\[D^[B`[@c[>e[;9!7$5&2(0*.%#!      "$$$$$ $ # ########## #"#$"&"("*","."0"2"4"6"7"9";!=!?!A!C!E!G!I!K!L!N!P!R!T V X Z \ ^ _~ a| cz ey gw iu ks mqnppnrltjvhxgze|c}a`^\ZXWUSQONLJHGECA@><:975320.,+)'%$"      !#%%2'@*N,]r.la1{P3>6+8;>##########!   #')** + ++,,--..!/$/&0)0+0.10122527293<3>4@4B4E5G5I6K6}M6zO7xQ7uS7sU8pW8nY8l[9j]9g_9ea:cc:ae:^g;\h;Zj;XlHz>F{>D}?B?@?>?<@:@8@7A5A3A1A/B.B,B*B)C'C%C#C"D DDDEEEEEFFF ; : 86531/-,*(&$ ""!#%'(*,./13 5 7 8:<>>>>= = ==<<<;;;:!:$:&:)9+9.908385887;7=7@6C6F5H5K5~N4{Q4yT4vW3tZ3q]2n`2lc2if1fi1dl0ao0^s0[v/Xy/V}.S.P-M-J-G,D,@+=+:*7*4)0)-(*(&'#'&&%%$ # #""!            JKM"N}3OlCP[SQJbR:rS*TU QC"51(?N [\\\\\ \ \\\\\[[[[["[$[}&[z([x*[v,[t.[r1[p3[n5[l7[j9[g;[e>[c@[aB[_DZ]FZ[HZYKZVMZTOZRQZPSZNUZLXZJZZG\ZE^ZC`ZAcZ?eZ=gZ;iZ8kZ6nZ4pZ2rY0tY.vY+yY){Y'}Y%Y#Y!YYYYYYYYY Y Y YYXXWTRP M KIGDB@>;9 7#5%2'0).'%#!       "$&&&%% % % %%%%%%%%$$ $"$$$&$($*$,$.$0$2$4$6#8#9#;#=#?#A#C#E#G#I#K#M"N"P"R"T"V"X"Z"\"^~"`|"az"cy"ew!gu!is!kq!mp!on!pl!rj!th!vg!xe!zc!|a!~` ^ \ Z X W U S Q O N L J HGECA@><:975320.,+)'%$"     #%#'1)>+L.[r0ja3yP5>8+:=@""""""""""     #'()) * *++,,--.".%.'/*/,0.011315182:2<3?3A3C4E4G5J5L5}N6zP6xR6uT7sV7pX7nZ8l\8j^8g`9eb9cc9ae:^g:\i:Zk;Xm;Vn;TpD~>B>@?>?>=== = <<<;;;;::":$9'9)9,8.818376797;6>6A6C5F5I4L4~O4{R3yT3vW3tZ2q]2n`1ld1ig1fj0dm0ap/^s/[w.Xz.V}.S-P-M,J,G+D+A*=*:)7)4(0(-'*'&&#&%%$$# # "!!             IJK"L~3NmCO\SPKbQ;rR+ST QC!50(>L Z[[[[[ [ [[[[ZZZZZZ"Z$Z~&Z{(Zy*Zw,Zu.Zs1Zq3Zo5Zm7Zk9Zh;Zf>Zd@ZbBY`DY^FY\HYZKYXMYUOYSQYQSYOUYMXYKZYI\YF^YD`YBcY@eY>gY;97!5$2&0(.)'%#!       "$&''''' ' ' '''''&&&&&!&"&$&&&(&*&,&.&0%2%4%6%8%:%<%=%?%A%C%E%G$I$K$M$O$P$R$T$V$X$Z$\~$^|$`z#by#cw#eu#gs#iq#kp#mn#ol#qj#rh#tg#ve"xc"za"|`"~^"\"Z"X"W"U"S"Q"O"N!L!J!H!G!E!C!A!@!>!:+<?B!!!!!!!!!!    #''(( ) )**++,, -#-%.(.*/-///10406191;2=2?2B3D3F3H4J4L5}N5zP5xS6uU6sW6pY7n[7l\7j^8g`8eb9cd9af9^h9\j:Zk:Xm:Vo;Tq;Rr;Pt@>>>Xe@XcBXaDX_FX]HX[KXYMXVOXTQXRSXPUXNXXLZXJ\XG^XE`XCcXAeX?gX=iX;kW8nW6pW4rW2tW0vW.yW+{W)}W'W%W#W!WWWWWWWWV V V VVVVTRPM K IGDB@>;97 5#2%0'.+)'%#!      "$&'))))) ) ) ))((((((((!(#(%(&(('*','.'0'2'4'6'8':'<'>'?'A&C&E&G&I&K&M&O&Q&R&T&V&X%Z~%\|%^z%`y%bw%cu%es%gq%ip%kn%ml%oj$qh$rg$te$vc$xa$z`$|^$~\$Z$X$W$U$S#Q#O#N#L#J#H#G#E#C#A#@#>#<":"9"7"5"3"2"0".","+")"'"%!$!"! !!!!!!!!!!      &(+--;/I2Wr4fa6uP9><+>AD             #&'' ( ())**++,!,#-&-(-+.-.0/2/507090;1>1@2B2D2G3I3K4M4}O4zQ5xS5uU5sW6pY6n[7l]7j_7ga8ec8ce8ag9^h9\j9Zl:Xn:Vp:Tq:Rs;Pu;Nw;Lx><>:>8?7?5?3?1@/@.@,@*A)A'A%A#B"B BBCCCCDDDDE : 8 75310.,*('%# !"#%'(*,./1 3 5 78:<==<< < ;;;;:::99 9#8%8(8*7-7/7265676:5<5?5B4E4G3J3M3~P2{S2yV2vY1t\1q_0nb0le0ih/fk/dn.aq.^u-[x-X{-V,S,P+M+J*G*D)A)=(:(7'4'1&-&*%&%#$ $##"" !              FHI"J3KoCL^SNNbO=rP-QR QC5.(<J XYYYYY Y YXXXXXXXXX"X$X&X~(X|*Xy,Xw.Xu1Xs3Xq5Xo7Xm9Xk;Wi>Wf@WdBWbDW`FW^HW\KWZMWXOWUQWSSWQUWOXWMZWK\WI^WF`WDcWBeW@gV>iV;975"2$0&.-+)'%# !    "$&')+++++ + * **********!*#)%)')))*),).)0)2)4)6)8):(<(>(@(A(C(E(G(I(K(M(O(Q'S'T'V'X~'Z|'\z'^y'`w'bu'ds'eq'gp'in&kl&mj&oh&qg&se&tc&va&x`&z^&|\&~Z&X%W%U%S%Q%O%N%L%J%H%G%E%C%A$@$>$<$:$9$7$5$3$2$0$.$,$+#)#'#%#$#"# #######"""" " " """""" (*,+/91G3Ur6da8sP;>>+@CF   #%&& ' '(())**+"+$,',)-,-..0.3.5/8/:0<0>1A1C1E2G2I3L3N3}P4zR4xT4uV5sX5pZ6n\6l^6j`7gb7ec7ce8ag8^i8\k9Zm9Xn9Vp:Tr:Rt:Pu;Nw;Ly;Jz;H|=<=:>8>7>5?3?1?/?.@,@*@)@'A%A#A"A BBBBCCCCDDD 9 8 6431/-+*(&$" "#%'(*,./1 3 5 78:<<<<; ; ;;:::9998!8#8&7(7+7-606365585:5=4@4B4E3H3K2N2~Q2{S1yV1vY1t\0q_0nb/le/ii.fl.do.ar-^u-[y,Y|,V+S+P+M*J*G)D)A(=(:'7'4&1&-%*%&$#$ #""!!             EGH"I3JpCK_SLObN>rO.PQQC5-(;I WXXXXX X WWWWWWWWWW"W$W&W(W}*Wz,Wx.Wv1Wt3Wr5Wp7Vn9Vl;Vj>Vg@VeBVcDVaFV_HV]KV[MVYOVVQVTSVRUVPXVNZVL\VJ^VG`VEcVCeUAgU?iU=kU;nU8pU6rU4tU2vU0yU.{U+}U)U'U%U#U!UUUUTTTTT T T TTTTRPMK I GDB@>;975 2#0%./-+)'% # !  " $&')+---,, , ,,,,,,,,,++!+#+%+'+)+++,+.+0+2+4*6*8*:*<*>*@*B*C*E*G*I*K)M)O)Q)S)U)V~)X|)Zz)\y)^w)`u)bs(dq(fp(gn(il(kj(mh(og(qe(sc(ua(v`(x^(z\'|Z'~X'W'U'S'Q'O'N'L'J'H'G&E&C&A&@&>&<&:&9&7&5&3&2&0%.%,%+%)%'%%%$%"% %%%%$$$$$$$ $ $ $$$###" *,.)173E5Sr8ba:qP=>@+BEH    #%%& & ''(())* *"+%+',*,,,/-1-4.6.8/;/=/?0A0D1F1H2J2L2N3}P3zR3xT4uV4sX5pZ5n\5l^6j`6gb6ed7cf7ah7^j8\k8Zm8Xo9Vq9Ts9Rt:Pv:Nx:Ly;J{;H};F~;D=<=:=8=7>5>3>1?/?.?,?*@)@'@%@#A"A AABBBBCCCCD 9 7 6420/-+)'%$" "#%'(*,./1 3 578:<<;;; ; :::999888"7$7&7)6+6.615356584;4>4@3C3F3I2K2N1~Q1{T1yW0vZ0t]/q`/nc/lf.ii.fl-dp-as-^v,[y,Y}+V+S*P*M)J)G(D(A'>':&7&4%1%-$*$'### ""!!              DEG"H3IrCJaSKPbL?rM/OPQC5,(:H VWWWWV V VVVVVVVVVV"V$V&V(V~*V|,Vy.Vw1Vu3Vs5Uq7Uo9Um;Uk>Ui@UfBUdDUbFU`HU^KU\MUZOUXQUUSUSUUQXUOZUM\UK^UI`TFcTDeTBgT@iT>kT;9752"0$.1/-+)' % # ! " $ &')+-..... . ......-----!-#-%-'-)-+---/,0,2,4,6,8,:,<,>,@,B,D,E+G+I+K+M+O+Q+S+U~+W|+Xz+Zy+\w*^u*`s*bq*dp*fn*hl*ij*kh*mg*oe*qc*sa)u`)v^)x\)zZ)|X)~W)U)S)Q)O)N)L(J(H(G(E(C(A(@(>(<(:(9(7(5'3'2'0'.','+')'''%'$'"' &&&&&&&&&&& & & %%%%%%$ , .0'255C7Qr:`aB+DGJ    #$$% %&&''(() )#*&*(+++-,/,2-4-7.9.;.>/@/B0D0F0I1K1M2O2}Q2zS3xU3uW4sY4p[4n]5l_5ja5gc6ee6cg6ah7^j7\l7Zn8Xp8Vq8Ts9Ru9Pw9Nx:Lz:J|:H};F;D;B;@<><<<:=8=7=5=3>1>/>.?,?*?)?'@%@#@"@ AAAABBBBCCC 8 7 5320.,*)'%#! "#%'(*,./1 3 578:<;;; : : :9998888 7"7%7'6*6,6/515446494<3>3A3D2F2I2L1O1~R0{U0yX0v[/t^/qa.nd.lg.ij-fm-dp,as,^w+[z+Y}*V*S*P)M)J(G(D'A'>&:&7%4%1$-$*#'##" !!               CDE"G3HsCIbSJQbKArL0M OP C5*(9G UVVVUU U UUUUUUUUUU"U$U&U(U*U},Uz.Ux1Uv3Tt5Tr7Tp9Tn;Tl>Tj@TgBTeDTcFTaHT_KT]MT[OTYQTVSTTUTRXTPZTN\TL^SJ`SGcSEeSCgSAiS?kS=nS;pS8rS6tS4vS2yS0{S.}S+S)S'S%S#R!RRRRRRRRR R R RRRRPMKI G DB@>;9752 0#.20.,*( & $ "  " $ & ')+-/00000 0 000////////!/#/%/'.).+.-./.1.2.4.6.8.:.<.>-@-B-D-F-G-I-K-M-O-Q-S~-U|,Wz,Yy,Zw,\u,^s,`q,bp,dn,fl,hj,ih,kg+me+oc+qa+s`+u^+w\+xZ+zX+|W+~U+S+Q+O*N*L*J*H*G*E*C*A*@*>*<*:)9)7)5)3)2)0).),)+)))')%($("( ((((((((((' ' ' ''''''& , 02%437A9Or<^a>mPA|>D+FIL   ##$ $ %%&&''((!)$)&*)*++.+0,3,5,7-:-<.>.@/C/E/G0I0K1M1P1}R2zT2xV3uX3sZ3p\4n^4l`4jb5gc5ee5cg6ai6^k6\m7Zn7Xp7Vr8Tt8Ru8Pw9Ny9L{9J|:H~:F:D;B;@;>;<<:<8<7=5=3=1=/>.>,>*?)?'?%?#@"@ @@AAAABBBBC 8 6 531/.,*(&$#! "#%'(*,./ 1 3 578:;;:: : 999988877 7#6%6(6*5-5/5244474:3<3?2B2D2G1J1M1P0~R0{U/yX/v[/t^.qa.od-lg-ik,gn,dq,at+^w+[{*Y~*V)S)P(M(J'G'D&A&>%:%7$4$1#-#*"'"#! !               BCD"E3GtCHcSIRbJBrK1L"MN C5)(8F TUUTTT T TTTTTTTTTT"T$T&T(T*T~,T|.Sy1Sw3Su5Ss7Sq9So;Sm>Sk@SiBSfDSdFSbHS`KS^MS\OSZQSXSSUUSSXSQZRO\RM^RK`RIcRFeRDgRBiR@kR>nR;97520".420.,* ( & $"  "$ & ' )+-/122222 1 11111111111!0#0%0'0)0+0-0/0103040608/://@/B/D/F/H/I/K/M/O.Q~.S|.Uz.Wy.Yw.[u.\s.^q.`p.bn.dl.fj-hh-jg-ke-mc-oa-q`-s^-u\-wZ-yX-zW-|U,~S,Q,O,N,L,J,H,G,E,C,A,@+>+<+:+9+7+5+3+2+0+.+,+++)*'*%*$*"* *******)))) ) ) ))))))', 24$619?;Mr>\a@kPCz>F+HKN   ""# # $$%%&''("($(')*),*.*1+3+6,8,:-=-?-A.C.F/H/J0L0N0P1}R1zT1xV2uX2sZ3p\3n^3l`4jb4gd4ef5ch5aj5^k6\m6Zo7Xq7Vs7Tt8Rv8Px8Ny8L{9J}9H~9F:D:B:@;>;<;:<8<7<5<3=1=/=.=,>*>)>'?%?#?"? @@@@AAAABBB 7 6 421/-+)(&$" "#%'(*,./ 1 3578::::9 9 998887776!6#6&5(5+5-404245383:3=2?2B1E1H1K0M0P/~S/{V/yY.v\.t_-qb-oe-lh,ik,gn+dr+au*^x*[{*Y)V)S(P(M'J'G&D&A%>%:$7$4#1#-"*"'!#              @BC"D3EuCGdSHSbICrJ3K#LM C5((7E STSSSS S SSSSSSSSSS"S$S&S(S*S,R}.R{1Rx3Rv5Rt7Rr9Rp;Rn>Rl@RjBRhDReFRcHRaKR_MR]OR[QRYSRVURTXQRZQP\QN^QL`QJcQHeQEgQCiQAkQ?nQ=pQ;rQ8tQ6vQ4yQ2{Q0}Q.Q+P)P'P%P#P!PPPPPPPPP P P PPPOMKIG D B@>;97520 .6420., * ( &$"  "$& ' )+-/1344333 3 33333333222!2#2%2'2)2+2-2/21231517181:1<1>1@1B1D1F1H0J0K0M0O~0Q|0Sz0Uy0Ww0Yu0[s0\q0^p/`n/bl/dj/fh/hg/je/lc/ma/o`/q^/s\/uZ.wX.yW.zU.|S.~Q.O.N.L.J.H.G.E-C-A-@->-<-:-9-7-5-3-2-0-.,,,+,),',%,$,", ,,,,+++++++ + + +++***),36"8/;==Kr@ZaBiPEx>H+JMP    !"" # #$$%%&& '#'%(((*)-)/*2*4+6+9+;,=,@-B-D.F.H.K/M/O0Q0}S0zU1xW1uY2s[2p]2n_3la3jc3ge4eg4ch5aj5^l5\n6Zp6Xq6Vs7Tu7Rw7Px8Nz8L|8J}9H9F9D9B:@:>:<;:;8;7<5<3<1'>%>#?"? ??@@@@AAAAB 7 5 420.-+)'%#" "#%'(*,./ 1 3568:::99 9 888777666!5$5&5)4+4.403335382;2=2@1C1F0H0K0N/Q/~T.{W.yZ.v]-t`-qc,of,li,il+go+dr*au*^y)\|)Y(V(S'P'M&J&G%D%A$>$:#7#4"1"-!*!' #             ?@B"C3DvCEeSGTbHDrI4J$KL C5'(6D RRRRRR R RRRRRRRRRR"R$R&R(R*Q,Q~.Q|1Qy3Qw5Qu7Qs9Qq;Qo>Qm@QkBQiDQfFQdHQbKQ`MQ^OQ\QQZSPXUPUXPSZPQ\PO^PM`PKcPIePFgPDiPBkP@nP>pP;97520.86420. , * (&$"  "$&' ) +-/13555555 5 5555544444 4!4#4%4'4)4+3-3/31333537393:3<3>3@3B2D2F2H2J2L2M~2O|2Qz2Sy2Uw2Wu2Ys1[q1]p1^n1`l1bj1dh1fg1he1jc1la1m`1o^0q\0sZ0uX0wW0yU0{S0|Q0~O0N0L0J0H/G/E/C/A/@/>/J+LOR     !! ""##$%%&!&#'&'((+(-(0)2)5*7*9+<+>,@,B-E-G-I.K.M/O/R/}T0zV0xX1uZ1s\1p^2n`2la2jc3ge3eg4ci4ak4^m5\n5Zp5Xr6Vt6Tv6Rw7Py7N{7L|8J~8H8F9D9B9@9>:<:::8;7;5;3<1#>"> ????@@@@AAA 6 5 310.,*('%#! "#%'(*,./ 1 3568:999 8 8 87776665 5"5$4'4)4,3.313326292;1>1A1C0F0I/L/O/Q.~T.{W-yZ-v]-t`,qc,of+li+il*gp*ds*av)^y)\}(Y(V'S'P&M&J%G%D$A$>#;#7"4"1!-!* '#           >?A"B3CwCDfSEVbGErH5I%JKC5&(5C QQQQQQ Q QQQQQQQQQQ"Q$Q&P(P*P,P.P}1P{3Px5Pv7Pt9Pr;Pp>Pn@PlBPjDPhFPeHPcKPaMP_OP]QO[SOYUOVXOTZOR\OP^ON`OLcOJeOHgOEiOCkOAnO?pO=rO;tO8vO6yO4{N2}N0N.N+N)N'N%N#N!NNNNNNNNN N M MMMMKIGD B @>;97520.:86420 . , *(&$"  "$&') + -/135677777 7 7766666666 6"6$6%5'5)5+5-5/51535557595;5<4>4@4B4D4F4H4J4L~4N|4Oz4Qy3Sw3Uu3Ws3Yq3[p3]n3_l3`j3bh3dg3fe3hc2ja2l`2n^2o\2qZ2sX2uW2wU2yS2{Q2|O2~N1L1J1H1G1E1C1A1@1>1<1:1907050302000.0,0+0)0'0%0$/"/ //////////. . . ......-!,79<,>9AHrCVaFePIt>L+NQT    ! !""##$$%"%$&'&)','.(1(3)5)8*:*<+?+A+C,E,H-J-L.N.P.R/}T/zV0xX0uZ0s\1p^1n`1lb2jd2gf3eh3cj3ak4^m4\o4Zq5Xs5Vt5Tv6Rx6Pz6N{7L}7J7H8F8D8B9@9>9<:::8:7:5;3;1;/<.<,<*<)='=%=#="> >>????@@@@A 6 4 31/-,*(&$"! "#%'(*,. / 1 35689988 8 777766655 5#4%4'4*3,3/222427191<1?0A0D0G/J/L.O.R.~U-{X-y[,v^,ta+qd+og+lj*im*gp)ds)aw(^z(\}'Y'V&S&P&M%J%G$D$A#>";"7!4!1 . *'#         =>?"A3ByCChSDWbEFrG6H&IJC5%(4B PPPPPP P PPPPPPPPPP"P$O&O(O*O,O.O~1O|3Oz5Ow7Ou9Os;Oq>Oo@OmBOkDOiFOfHOdKObMN`ON^QN\SNZUNXXNUZNS\NQ^NO`NMcNKeNIgNFiNDkNBnN@pN>rN;97520.<:8642 0 . ,*(&$"  "$&')+ - /135689999 9 8 8888888888 7"7$7&7(7)7+7-7/71737567696;6=6>6@6B6D6F6H6J~6L|5Nz5Py5Qw5Su5Us5Wq5Yp5[n5]l5_j5ah5bg4de4fc4ha4j`4l^4n\4pZ4qX4sW4uU4wS3yQ3{O3}N3~L3J3H3G3E3C3A3@3>2<2:2927252322202.2,2+2)1'1%1$1"1 11111110000 0 0 000000." ,9;>*@8CFrETaHcPKr>N+PSV    !!"##$ $"%%%'&*&,'/'1(4(6(8);)=*?*B+D+F,H,J,M-O-Q.S.}U/zW/xY/u[0s]0p_0na1lc1je2gg2eh2cj3al3^n3\p4Zq4Xs4Vu5Tw5Rx5Pz6N|6L}6J7H7F7D8B8@8>9<9:98:7:5:3:1;/;.;,<*<)<'<%=#="= =>>>????@@@ 6 4 20/-+)'&$"  "#%'(*,. / 135688888 7 776665554!4#4&3(3+3-202215171:0=0?0B/E/G.J.M.P-S-~V,{X,y[,v^+ta+qd*oh*lk)in)gq)dt(aw(^{'\~'Y&V&S%P%M$J$G#D#A">";!7!4 1 .*'#       <=>"?3AzCBiSCXbDGrF7G'HIC5$(2A OOOOOO O OOOOOOOOOO"N$N&N(N*N,N.N1N}3N{5Nx7Nv9Nt;Nr>Np@NnBNlDNjFNhHNeKMcMMaOM_QM]SM[UMYXMWZMT\MR^MP`MNcMLeMJgMHiMEkMCnMApM?rM=tL;vL8yL6{L4}L2L0L.L+L)L'L%L#L!LLLLLLKKK K K KKKKIGDB @ >;97520.=;9753 1 / -+)'&$"  "$&')+- / 13568:;;:: : : :::::::999 9"9$9&9(9*9+9-9/81838587898;8=8?8@8B8D8F7H~7J|7Lz7Ny7Pw7Ru7Ss7Uq7Wp7Yn7[l6]j6_h6ag6be6dc6fa6h`6j^6l\6nZ6pX6qW5sU5uS5wQ5yO5{N5}L5~J5H5G5E5C5A4@4>4<4:4947454342404.3,3+3)3'3%3$3"3 33332222222 2 2 2221110$ ,; =@(B6EDrGRaJaPMp>P+RUX      !!""# ##$&$(%+%-&0&2'4'7(9(;)>)@*B*E*G+I+K,M,O-Q-S-}V.zX.xZ/u\/s^/p`0na0lc1je1gg1ei2ck2am2^n3\p3Zr4Xt4Vv4Tw5Ry5P{5N|6L~6J6H7F7D7B7@8>8<8:989795:3:1:/:.;,;*;)<'<%<#<"= ==>>>>????@ 5 3 20.,+)'%#!  "#%'(*,. / 135688877 7 666555444!3$3&3)2+2.201315180:0=/@/C/E.H.K-N-P-S,~V,|Y+y\+v_+tb*qe*oh)lk)in(gr(du'ax'^{'\&Y&V%S%P$M$J#G#D"A">!; 7 41.*'#     :<=">3@{CAjSBYbCIrD8F(GH C5#(1@ NNNNNN N NNNNNNNNNM"M$M&M(M*M,M.M1M~3M|5Mz7Mw9Mu;Ms>Mq@MoBMmDMkFMiHLfKLdMLbOL`QL^SL\ULZXLXZLU\LS^LQ`LOcLMeLKgLIiLFkLDnLBpK@rK>tK;97520.?=;975 3 1 /-+)'%#! "$&')+-/ 1 3568:<<<<< < < <<<<;;;;;; ;";$;&;(;*:,:-:/:1:3:5:7:9:;:=:?9A9B9D9F~9H|9Jz9Ly9Nw9Pu9Rs9Tq9Up8Wn8Yl8[j8]h8_g8ae8cc8da8f`8h^8j\7lZ7nX7pW7rU7sS7uQ7wO7yN7{L7}J7H7G6E6C6A6@6>6<6:6967656362505.5,5+5)5'5%5$5"5 54444444444 4 4 3333332& ,; ?A&D4GBrIPaL_POn>R~+TWZ      !""!#$#&$)$+%.%0&3&5'7':(<(>(A)C)E*G*J+L+N,P,R,T-}V-zX.xZ.u\.s^/p`/nb0ld0jf0gh1ej1ck1am2^o2\q3Zs3Xt3Vv4Tx4Rz4P{5N}5L5J6H6F6D7B7@7>8<8:8887959391:/:.:,;*;);';%<#<"< <===>>>>??? 5 3 1/.,*(&%#! "#%'(*, . / 13568777 6 6 65554443 3"3$2'2)2,1.111306080;/>/@.C.F.I-K-N,Q,T,~W+|Z+y]*v`*tc)qf)oi)ll(io(gr'du'ay&^|&\%Y%V$S$P#M#J"G"D!A!> ; 741.*'#   9:<"=3>|C@kSAZbBJrC9D)FG C5"(0? MMMMMM M MMMMMMMLLL"L$L&L(L*L,L.L1L3L}5L{7Lx9Lv;Lt>Lr@LpBLnDKlFKjHKhKKeMKcOKaQK_SK]UK[XKYZKW\KT^KR`KPcKNeKLgKJiKHkKEnJCpJArJ?tJ=vJ;yJ8{J6}J4J2J0J.J+J)J'J%J#J!JIIIIIIII I I IIIIGDB@ > ;97520.A?=;97 5 3 1/-+)'%#! "$&')+-/1 3 568:<>>>>> > > >========= ="=$<&<(<*<,<.<0<1<3<5<7<9;;;=;?;A;C;D~;F|;Hz;Jy;Lw;Nu:Ps:Rq:Tp:Vn:Wl:Yj:[h:]g:_e:ac:ca:e`9f^9h\9jZ9lX9nW9pU9rS9sQ9uO9wN9yL8{J8}H8G8E8C8A8@8>8<8:8987757372707.7,7+7)7'7%7$7"6 66666666665 5 5 5555554(,; AC$F2H@rKNaN]PQl>T|+VY]      !!""$"'#*#,$/$1%3%6&8&:'='?(A(D)F)H*J*L*O+Q+S,U,}W-zY-x[-u].s_.pa/nc/le/jg0gh0ej0cl1an1^p2\r2Zs2Xu3Vw3Tx3Rz4P|4N~4L5J5H5F6D6B6@7>7<7:88878583919/9.:,:*:);';%;#;"< <<<===>>>>? 4 2 1/-+*(&$"  "#%'(*, - / 13567766 6 555544433 3"2%2'1*1,1/010406/9/.A.D-F-I-L,O,R+U+~W+|Z*y]*w`)tc)qf(oi(lm'ip'gs'dv&ay&_}%\%Y$V$S#P#M"J"G!D!A > ;841.*'#   89;"<3=}C>lS@[bAKrB;C+DF C5!(/> LLLLLL L LLLLLLKKKK"K$K&K(K*K,K.K1K3K~5K|7Kz9Kw;Ku>Ks@KqBJoDJmFJkHJiKJgMJdOJbQJ`SJ^UJ\XJZZJX\JU^JS`JQcJOeJMgJKiJIkIFnIDpIBrI@tI>vI ;97520.CA?=;9 7 5 31/-+)'%#! "$&')+-/1 3 5 68:<>@@@@@ ? ? ?????????> >">$>&>(>*>,>.>0>2>3=5=7=9=;===?=A=C~=E|=Fz=Hy:<9:9997959392909.9,9+9)9'8%8$8"8 88888887777 7 7 7777775*,;CE"H0J>rMLaP[PSj>Uz+X[_     !#!%"("*#-#/$2$4%6%9&;&>'@'B(D(G(I)K)M*O*Q+S+U+}W,zZ,x\-u^-s_.pa.nc.le/jg/gi/ek0cm0ao1^p1\r1Zt2Xv2Vw2Ty3R{3P|3N~4L4J4H5F5D5B6@6>6<7:78778583819/9.9,9*:):':%;#;"; ;<<<<===>>> 4 2 0.-+)'%$"  "#%'(*, - /13566666 5 554443332!2#2%1(1*1-0/02/4/7/:.<.?.B-D-G,J,M,O+R+U*~X*|[)y^)wa)td(qg(oj'lm'jp>&dw%az%_}$\$Y#V#S"P"M!J!G D A>;841.*'$     789";3<C=mS?]b@LrAJt@IrBIpDInFIlHIjKIhMIeOIcQIaSI_UI]XI[ZIY\IW^IT`IRcIPeINgHLiHJkHHnHEpHCrHAtH?vH=yH;{H8}H6H4H2H0H.H+H)H'G%G#G!GGGGGGGGG G GGGGGDB@> ; 97520.ECA?=; 9 7 531/-+)'%# !"$&')+-/13 5 6 8:<>@BBAAA A A AAAAAA@@@@ @"@$@&@(@*@,@.?0?2?4?5?7?9?;?=???A~?C|>Ez>Gy>Hw>Ju>Ls>Nq>Pp>Rn>Tl>Vj>Xh=Yg=[e=]c=_a=a`=c^=e\=gZ=hX=jW=lU;<;:;9;7;5;3;2;0;.;,:+:):':%:$:": :::::999999 9 9 9998887+,;DG J.LWx+Z^a  ! # &!(!+"-"0#2$5$7$:%<%>&@&C'E'G(I(L)N)P*R*T*V+}X+zZ,x\,u^,s`-pb-nd.lf.jh.gj/ek/cm0ao0^q0\s1Zt1Xv1Vx2Tz2R{3P}3N3L4J4H4F5D5B5@6>6<6:68777573818/8.9,9*9)9':%:#:"; ;;;<<<<===> 3 1 0.,*)'%#! "#%'(*, - /13566655 5 444333222!1$1&1(0+0-00/2/5.8.:.=-@-B,E,H,J+M+P*S*V*~Y)|\)y_(wb(te'qh'ok'ln&jq>%dw%a{$_~$\#Y#V"S"P!M!J G DA>;841.*'$        578":3;CHu@HsBHqDHoFHmHHkKHiMHgOHdQHbSH`UH^XH\ZHZ\HX^HU`HScHQeGOgGMiGKkGInGFpGDrGBtG@vG>yG<{G:}G7G5G3G1G/G-G*F(F&F$F"FFFFFFFFFF F FFFEDB@> ; 97520.GECA?= ; 9 7531/-+)'% #"!$&')+-/135 6 8 :<>@BCCCCC C C CCCBBBBBBB!B"B$B&B(A*A,A.A0A2A4A6A7A9A;A=@?~@A|@Cz@Ey@Gw@Iu@Js@Lq@Np@Pn@Rl?Tj?Vh?Xg?Ze?[c?]a?_`?a^?c\?eZ?gX>iW>jU>lS>nQ>pO>rN>tL>vJ>wH>yG>{E=}C=A=@=>=<=:=9=7=5=3=2<0<.<,<+<)<'<%<$<"< <<;;;;;;;;; ; ; ::::::9-!,;FIK,N:rQHaTWPWf>Yv+\`c   !$ ' )!,!."1"3#6#8$:$=%?%A&C&F'H'J(L(N(Q)S)U*W*}Y+z[+x]+u_,sa,pc-ne-lg-jh.gj.el/cn/ap/^r0\s0Zu0Xw1Vy1Tz2R|2P~2N3L3J3H4F4D4B5@5>5<6:68677573717/8.8,8*9)9'9%9#:": :;;;;<<<<== 3 1 /-,*(&$#! "#%'(* , - /1356555 4 4 433322211"1$0'0)0,/./1/3.6.8-;-=-@,C,F+H+K+N*Q*T)V)~Y)|\(y_(wb'te'qh&ok&lo%jr%gu$dx$a{$_#\#Y"V"S!P!M JGDA>;841.*'$          467"83:C;pS<_b=Nr?>@.ABC5(,: HIIIII I IIIHHHHHHH"H$H&H(H*H,H.H1H3H5H7H}9G{;Gy>Gv@GtBGrDGpFGnHGlKGjMGhOGeQGcSGaUG_XG]ZG[\GY^GW`FTcFReFPgFNiFLkFJnFHpFErFCtFAvF?yF={F;}F8F6F4F2F0E.E+E)E'E%E#E!EEEEEEEEE E EDDDDB@>; 9 7520.IGDB@> < : 87531/-+)' %"#$!&')+-/1356 8 : <>@BCEEEEE E E DDDDDDDDDD!C#C$C&C(C*C,C.C0C2C4C6B8B9B;B=~B?|BAzBCyBEwBGuBIsBKqALpANnAPlARjAThAVgAXeAZcA\aA]`A_^@a\@cZ@eX@gW@iU@kS@lQ@nO@pN@rL@tJ@vH?xG?yE?{C?}A?@?>?3>2>0>.>,>+>)>'>%>$>"= =========== < < <<<<<<;/#, ;HKM*P8rSGaVUPYd>[t+_be    "%'* ,!/!1"4"6#9#;$=$@%B%D&F&I&K'M'O(Q(S)U)W*}Y*z[*x]+u_+sa,pc,ne,lg-ji-gk.em.co.ap/^r/\t0Zv0Xw0Vy1T{1R}1P~2N2L2J3H3F3D4B4@4>5<5:58676563717/7.7,8*8)8'9%9#9": :::;;;;<<<< 2 0 /-+)(&$"  "#%'(* , - /1355554 4 433322211 0"0%0'/*/,//.1.4.6-9-;,>,A,C+F+I*L*N*Q)T)W(~Z(|]'y`'wc'tf&ri&ol%lo%jr$gv$dy#a|#_"\"Y!V!S P MJGDA>;841.*'$            346"738C:qS;`b??/@AB5(+9 GHHHHH H HHGGGGGGGG"G$G&G(G*G,G.G1G3G5G7F~9F|;Fz>Fx@FuBFsDFqFFoHFmKFkMFiOFgQFdSFbUF`XF^ZF\\FZ^EX`EUcESeEQgEOiEMkEKnEIpEFrEDtEBvE@yE>{E<}E:E7E5E3D1D/D-D*D(D&D$D"DDDDDDDDDC C CCCCB@>; 9 7520.JHFDB@ > < :86420.,*( &"$$#&!')+-/13568 : < >@BCEGGGGF F F FFFFFFFEEE!E#E%E&E(E*E,E.E0D2D4D6D8D:D<~D=|D?zDAyDCwDEuCGsCIqCKpCMnCNlCPjCRhCTgCVeCXcCZaB\`B^^B_\BaZBcXBeWBgUBiSBkQBlOBnNApLArJAtHAvGAxEAyCA{AA}@A>A>> > > >>>>>><1%, ;J MO(R6rUEaXSPZb>]r+adg    #&(+- 0 2!5!7"9"<#>#@$C$E%G%I&K&N'P'R(T(V(X)}Z)z\*x^*u`+sb+pd+nf,lh,jj-gl-em-co.aq.^s/\u/Zv/Xx0Vz0T{0R}1P1N1L2J2H2F3D3B3@4>4<4:58575563616/7.7,7*8)8'8%8#9"9 9::::;;;;<< 2 0 .,+)'%#"  "#%'(* , -/1355444 3 332221110!0#0%/(/*.-./.2-4-7-9,<,?+A+D+G*J*L)O)R)U(X(~['|^'y`&wc&tg%rj%om%lp$js$gv#dy#a}"_"\!Y!V S PMJGDA>;841.+'$              235"637C9rS:ab;Qr<@>0? @A 5(*8 FGGGGG G FFFFFFFFFF"F$F&F(F*F,F.F1F3F5E7E9E};E{>Ey@EvBEtDErFEpHEnKElMEjOEhQEfSEcUEaXE_ZE]\D[^DY`DWcDTeDRgDPiDNkDLnDJpDHrDEtDCvDAyD?{D=}D;D8C6C4C2C0C.C+C)C'C%C#C!CCCCCCCBB B BBBBB@>;9 7 520.LJHFDB @ > <:86420.,* ("&$$&"' )+-/13568: < > @BCEGIHHHH H HHHHHGGGGGG!G#G%G'G)G*F,F.F0F2F4F6F8F:~F<|F>zF?yEAwECuEEsEGqEIpEKnEMlEOjEPhERgETeDVcDXaDZ`D\^D^\D_ZDaXDcWDeUDgSDiQCkOCmNCnLCpJCrHCtGCvECxCCzAC{@C}>B2&,;K NQ&T4rWCaZQP\`>_o+cfi  !$&)+.0 3 5!8!:"<"?#A#C$E$H%J%L&N&P&S'U'W(Y(}[)z])x_*ua*sc*pe+nf+lh,jj,gl,en-cp-ar.^s.\u.Zw/Xy/Vz/T|0R~0P0N1L1J2H2F2D3B3@3>4<4:48575553516/6.6,7*7)7'8%8#8"8 999::::;;;; 1 / .,*('%#! "#%'(* , -/1344433 3 222111000!/#/&/(.+.--0-2-5,7,:,=+?+B*E*G*J)M)P(S(U'X'~['|^&ya&wd%tg%rj$om$lp#jt#gw"dz"b}!_!\ Y VSPMJGDA>;851.+'$               123"536C7sS9bb:Rr;A=1>"?@ 5()7 EFFFFF E EEEEEEEEEE"E$E&E(E*E,E.E1D3D5D7D9D~;D|>Dz@DxBDuDDsFDqHDoKDmMDkODiQDgSDdUDbXC`ZC^\C\^CZ`CXcCVeCSgCQiCOkCMnCKpCIrCFtCDvCByC@{C>}C<B:B7B5B3B1B/B-B*B(B&B$B"BBBBBAAAAA A AAAA@>;9 7 520.NLJHFD B @ ><:86420., *"($&&$'") +-/13568:< > @ BCEGIJJJJJ J JJIIIIIIIII!I#I%H'H)H+H,H.H0H2H4H6H8~H:|GyG@wGAuGCsGEqGGpGInGKlGMjFOhFQgFReFTcFVaFX`FZ^F\\F^ZF`XFaWEcUEeSEgQEiOEkNEmLEnJEpHErGEtEEvCDxADz@D{>D}am+e}hk   "$'*,/146 8 ;!=!?"B"D#F#H$K$M%O%Q&S&U'W'Y(}[(z](x_)ua)sc*pe*ng+li+jk+gm,eo,cp-ar-^t-\v.Zx.Xy.V{/T}/R~0P0N0L1J1H1F2D2B2@3>3<3:48474553515/6.6,6*6)7'7%7#8"8 89999::::;; 1 / -+*(&$"! "#%'( * , -/134333 2 2 2211000//"/$.&.).+-.-0,3,5,8+;+=+@*C*E)H)K)N(P(S'V'Y&~\&|_%yb%we%th$rk$on#lq#jt"gw"d{!b~!_ \ YVSPMJGDA>;851.+'$               /12"435C6tS8cb9Sr:C;2=#>? 5((6 DEEEED D DDDDDDDDDD"D$D&D(D*D,D.C1C3C5C7C9C;C}>C{@CyBCvDCtFCrHCpKCnMClOCjQChSCfUBcXBaZB_\B]^B[`BYcBWeBTgBRiBPkBNnBLpBJrBHtBEvBCyBA{A?}A=A;A8A6A4A2A0A.A+A)A'A%A#A!AAA@@@@@@ @ @@@@@>;97 5 20.PNLJHF D B @><:86420. ,"*$(&&'$)"+ -/13568:<> @ B CEGIKLLLLL K KKKKKKKKKKJ!J#J%J'J)J+J-J.J0J2I4I6~I8|I:zIwI@uIBsICqIEpIGnHIlHKjHMhHOgHQeHScHTaHV`HX^HZ\H\ZG^XG`WGbUGcSGeQGgOGiNGkLGmJGoHGpGFrEFtCFvAFx@Fz>F|ck+g{jm     #%(*-/2479 ; >!@!B"E"G#I#K$M$P%R%T&V&X&Z'}\'z^(x`(ub)sd)pf*nh*lj*jl+gm+eo,cq,as,^u-\v-Zx-Xz.V|.T}/R/P/N0L0J0H1F1D1B2@2>2<3:38374543415/5.5,6*6)6'7%7#7"7 8889999:::: 0 . -+)'&$"  "#%'( * , -/133332 2 2111000// .".%.'-)-,-.,1,3,6+9+;*>*@*C)F)I(K(N'Q'T'W&Z&~\%|_%yb$we$th#rl#oo"lr"ju"gx!d{!b _ \YVSPMKGDA>;851.+'$               .01"234C5vS6eb8Tr9D:4<$=> 5('5 CDDDCC C CCCCCCCCCC"C$C&C(C*C,B.B1B3B5B7B9B;B~>B|@BzBBxDBuFBsHBqKBoMBmOBkQBiSAgUAdXAbZA`\A^^A\`AZcAXeAVgASiAQkAOnAMpAKrAItAFvADy@B{@@}@>@<@:@7@5@3@1@/@-@*@(@&@$@"@????????? ? ????>;97 5 20.RPNLJH F D B@><:86420 .",$*&('&)$+"- /13568:<>@ B CEGIKMNNMMM M MMMMMMMLLLL!L#L%L'L)L+L-K/K1K2K4~K6|K8zK:yKuK@sKBqJDpJEnJGlJIjJKhJMgJOeJQcJSaJT`IV^IX\IZZI\XI^WI`UIbSIcQIeOIgNIiLHkJHmHHoGHqEHrCHtAHv@Hx>Hzei+iylo     !#&(+.0257:< > A!C!E"H"J#L#N$P$R$T%W%Y&[&}]'z_'xa(uc(se(pf)nh)lj*jl*gn+ep+cr+as,^u,\w,Zy-Xz-V|.T~.R.P/N/L/J0H0F0D1B1@2>2<2:38373543414/4.5,5*5)6'6%6#7"7 778889999:: 0 . ,*)'%#!  "#%'( * ,-/133222 1 11000///. .#.%-(-*,-,/,2+4+7+9*<*>)A)D(F(I(L'O'R&T&W%Z%~]%|`$yc$wf#ti#rl"oo"lr!jv!gy d| b_\YVSPNKHDA>;851.+'$                -.0"133C4wS5fb7Ur8E95:%<=5(&4 BCCBBB B BBBBBBBBBB"B$B&B(B*A,A.A1A3A5A7A9A;A>A}@A{BAyDAwFAtHArKApMAnO@lQ@jS@hU@fX@cZ@a\@_^@]`@[c@Ye@Wg@Ti@Rk@Pn@Np@Lr@Jt@Hv?Ey?C{?A}???=?;?8?6?4?2?0?.?+?)?'?%?#>!>>>>>>>>> > >>>>>;975 2 0.TRPNLJ H F DB@><:8642 0".$,&*'()&+$-"/ 13568:<>@B C EGIKMOOOOOO O OOOONNNNNNN!N#N%N'M)M+M-M/M1M3~M4|M6zM8yM:wM
                  sL@qLBpLDnLFlLGjLIhLKgLMeLOcKQaKS`KU^KV\KXZKZXK\WK^UK`SKbQKdOJeNJgLJiJJkHJmGJoEJqCJrAJt@Jv>Jxgg+kwnq    !$'),.1368:=?A D F!H!J"M"O#Q#S$U$W%Y%[&}]&z_'xa'uc'se(pg(ni)lk)jm)go*ep*cr+at+^v+\x,Zy,X{-V}-T~-R.P.N.L/J/H0F0D0B1@1>1<2:28273533314/4.4,5*5)5'5%6#6"6 77788889999 / - ,*(&%#! "#%'( * ,-/122211 1 000///...!-#-&-(,+,-+0+2+5*7*:)<)?)B(D(G'J'M'O&R&U%X%[$~^$|a#yd#wg#tj"rm"op!ls!jv gy d}b_\YVSQNKHDA>;851.+'$                      ,-/"031C3xS4gb5Vr7F869&;<5($3 ABAAAA A AAAAAAAAAA"A$A&A(@*@,@.@1@3@5@7@9@;@>@~@@|B@zD@xF@uH@sK@qM?oO?mQ?kS?iU?gX?dZ?b\?`^?^`?\c?Ze?Xg?Vi?Sk?Qn?Op?Mr>Kt>Iv>Fy>D{>B}>@>>><>:>7>5>3>1>/>->*>(=&=$="========== = ===<;975 2 0.¨USQOMK I G ECA?=;9753 1"/$-&,'*)(+&-$/"1 3568:<>@BC E GIKMOPQQQQQ Q QPPPPPPPPP P!O#O%O'O)O+O-O/O1~O3|O5zO6yN8wN:uNqN@pNBnNDlNFjNGhNIgMKeMMcMOaMQ`MS^MU\MWZMXXMZWM\UL^SL`QLbOLdNLfLLgJLiHLkGLmELoCLqAKs@Kt>Kvie+mups               "%'*,/1469;>@BD G I!K!M"O"R#T#V$X$Z%\%}^%z`&xb&ud'sf'ph(nj(ll(jm)go)eq*cs*au*^v+\x+Zz,X|,V},T-R-P.N.L.J/H/F/D0B0@0>1<1:18272523313/3.4,4*4)5'5%5#6"6 66777888899 / - +)(&$"  !#%' ( * ,-/12211 1 0 00///..--"-$,&,),++.+0*3*5*8):)=(@(B(E'H'J&M&P&S%V%X$[$~^#|a#yd"wg"tj!rm!oq lt jwgzd}b_\YVSQNKHEA>;851.+'$                     *,-"/30C2yS3hb4Wr6G778'9;5(#2 @@@@@@ @ @@@@@@@@@@"@$@&?(?*?,?.?1?3?5?7?9?;?>?@?}B?{D?yF?wH?tK>rM>pO>nQ>lS>jU>hX>fZ>c\>a^>_`>]c>[e>Yg>Wi>Tk>Rn>Pp=Nr=Lt=Jv=Hy=E{=C}=A=?===;=8=6=4=2=0=.=+<)<'<%<#@BCE G IKMOPRSSSSR R RRRRRRRRQQ Q"Q#Q%Q'Q)Q+Q-Q/~P1|P3zP5yP7wP8uP:sPpP@nPBlPDjOFhOHgOIeOKcOMaOO`OQ^OS\OUZOWXNYWNZUN\SN^QN`ONbNNdLNfJNgHNiGNkEMmCMoAMq@Ms>Mtkc+osru                #%(+-02579<>ACEG J L!N!P"R"T"V#Y#[$]$}_%za%xc&ue&sf'ph'nj'll(jn(gp)er)cs)au*^w*\y+Z{+X|+V~,T,R-P-N-L.J.H.F/D/B/@0>0<1:18172523212/3.3,3*4)4'4%5#5"5 66667778888 . , +)'%$"  !#%& ( * ,-/11110 0 0///...-- -",%,'+)+,+.*1*3)6)8);(>(@'C'F'H&K&N%Q%S$V$Y$\#~_#|b"ye"wh!tk!rn oq mtjxg{d~b_\YVTQNKHEA>;851.+'$                   )+,".3/C0zS2ib3Yr4H687(8: 5("1 ?????? ? ??????????">$>&>(>*>,>.>1>3>5>7>9>;>>>@>~B>|D>zF>xH=vK=sM=qO=oQ=mS=kU=iX=gZ=e\=b^=``=^c=\e=Zg=Xi=Vk=Sn<<<:<7<5<3<1;/;-;*;(;&;$;";;;;;;;;;; : ::::9752 0 .ĥYWUSQO M K IGECA?=;97 5"3$1&/'-)++)-'/%1#3!568:<>@BCEG I KMOPRTUTTT T T TTTTTSSSSS S"S$S%S'S)R+R-~R/|R1zR3yR5wR7uR9sR:qRnQ@lQBjQDhQFgQHeQJcQKaQM`QO^QQ\PSZPUXPWWPYUPZSP\QP^OP`NPbLPdJOfHOhGOiEOkCOmAOo@Oq>Osma+qqtw               !$&)+.0358:=?ADFHJL O Q!S!U"W"Y#[#]$}_$za%xc%ue%sg&pi&nk'lm'jo(gp(er(ct)av)^x*\y*Z{*X}+V+T,R,P,N-L-J-H.F.D/B/@/>0<0:08171513212/2.3,3*3)4'4%4#4"5 55666777788 . , *('%#! !#%& ( *,-/11000 / //...---, ,#,%+'+**,*/*1)4)6(9(<(>'A'C&F&I&L%N%Q$T$W#Z#]"~`"|c"yf!wi!tl ro ormujxg{db_\YVTQNKHEA>;851.+'$!               (*+",3.C/{S1jb2Zr3I596)78 5(!0 >>>>>> > >>>>>>>>>="=$=&=(=*=,=.=1=3=5=7=9=;=>=@=B=}D<{F@BCEGI K MOPRTVVVVV V V VVUUUUUUUU U"U$T&T(T)T+~T-|T/zT1yT3wT5uT7sS9qS;pSlS@jSBhSDgSFeSHcSJaSL`RM^RO\RQZRSXRUWRWURYSR[QR\OR^NQ`LQbJQdHQfGQhEQjCQkAQm@Qo>Qqo_+sovy              "$'*,/1469;=@BDFIKMO Q T!V!X"Z"\#^#}`#zb$xd$uf%sh%pj&nl&lm'jo'gq'es(cu(av)^x)\z)Z|*X}*V+T+R+P,N,L-J-H-F.D.B.@/>/;852.+'$!               '(*"+3-C.}S/lb1[r2J4:5*67 5( / ====== = ========<<"<$<&<(<*<,<.<1<3<5<7<9<;<><@:<::979593919/9-9*9(9&9$9"9999998888 8 88887520 .ơ][YWUS Q O MKIGECA?=; 9"7$5&3'1)/+--+/)1'3%5#6!8:<>@BCEGI K M OPRTVXXXXX X W WWWWWWWWWV V"V$V&V(V*~V+|V-zV/yV1wU3uU5sU7qU9pU;nU=lU>jU@hUBgUDeTFcTHaTJ`TL^TN\TOZTQXTSWTUUTWSTYQS[OS]NS^LS`JSbHSdGSfEShCSjASk@Rm>Roq]+umx}{                "%(*-/2479<>@CEGILNPRT V X![!]"_"}a#zc#xe$uf$sh%pj%nl&ln&jp&gr'et'cu(aw(^y(\{)Z|)X~*V*T*R+P+N,L,J,H-F-D-B.@.>.;852.+($!                 &')"*3,C-~S.mb0\r1L2;4,56 5(. <<<<<< < <<<<<<<;;;";$;&;(;*;,;.;1;3;5;7;9;;;>;@:B:D:}F:{H:yK:wM:tO:rQ:pS:nU:lX:jZ:h\:f^:c`:ac:_e9]g9[i9Yk9Wn9Tp9Rr9Pt9Nv9Ly9J{9H}9E9C9A9?9=8;88868482808.8+8)8'8%8#8!888777777 7 77777520.ǟ_][YWU S Q OMKIGECA?= ;"9$7&5'3)1+/--/+1)3'5%6#8!:<>@BCEGIK M O PRTVXZZZYY Y Y YYYYYYXXXX X"X$X&X(~X*|X,zW-yW/wW1uW3sW5qW7pW9nW;lW=jW?hV@gVBeVDcVFaVH`VJ^VL\VNZVPXVQWUSUUUSUWQUYOU[NU]LU_JU`HUbGUdEUfCThATj@Tl>TmPpL>s[+wkz{~               !#&(+.0358:<?ACFHJLOQSUW Y [!]!_"}a"zc#xe#ug$si$pk$nm%lo%jq&gr&et'cv'ax'^y(\{(Z})X)V)T*R*P+N+L+J,H,F,D-B-@.>.<.:/8/7/503010/1.1,1*2)2'2%3#3"3 34445556666 , * )'%#!  !#% & (*,-////. . .---,,,++ +"*$*'))),).(1(3'6'8';&=&@%C%E%H$K$M#P#S"V"Y!\!_ a |d zgwjtnrqotmwjzg}eb_\YWTQNKHEB>;852.+($!            $&'")3*C,S-nb/]r0M1=3-455(, ;;;;;; ; ;;;;;;::::":$:&:(:*:,:.:1:3:5:7:9:;:>9@9B9D9~F9|H9zK9xM9vO9sQ9qS9oU9mX9kZ9i\9g^9e`8bc8`e8^g8\i8Zk8Xn8Vp8Sr8Qt8Ov8My8K{8I}8G8D8B8@7>7<7:777573717/7-7*7(7&7$7"7766666666 6 6666520.ɝa^\ZXV T R PNLJHFDB@> <":$8&6'5)3+1-//-1+3)5'6%8#:!<>@BCEGIKM O P RTVXZ[[[[[ [ [ [[[ZZZZZZZ Z"Z$Z&~Y(|Y*zY,yY.wY/uY1sY3qY5pY7nY9lX;jX=hX?gXAeXBcXDaXF`XH^XJ\XLZWNXWPWWQUWSSWUQWWOWYNW[LW]JW_HV`GVbEVdCVfAVh@Vj>VluY+yi|x    !$'),.1368;=?BDFIKMOQSVXZ \ ^!`!}b"zd"xf"uh#sj#pl$nm$lo%jq%gs&eu&cw&ax'^z'\|(Z~(X(V)T)R*P*N*L+J+H,F,D,B-@->-<.:.8.7/5/3/10/0.0,1*1)1'2%2#2"3 33444455566 , * (&%#! !#% & (*,-///.. . ---,,+++* *#*%)')*(,(/(1'4'6&9&;&>%A%C$F$I#K#N#Q"T"V!Y!\ _ b|ezhwktnrqotmxj{g~eb_\YWTQNKHEB?;852.+($!            #%&"(3)C+S,ob-^r/N0>1.345(+ :::::: : :::::99999"9$9&9(9*9,9.91939597999;8>8@8B8D8F8}H8{K8yM8wO8uQ8rS8pU8nX8lZ8j\8h^7f`7cc7ae7_g7]i7[k7Yn7Wp7Ur7Rt7Pv7Ny7L{7J}7H7E6C6A6?6=6;68666462606.6+6)6'6%6#5!555555555 5 5555520.ʜb`^\ZX V T RPNLJHFDB@ >"<$:&8'6)4+2-0/.1,3*5(6'8%:#@BCEGIKMO P R TVXZ[]]]]] ] ] \\\\\\\\\\ ["[$~[&|[(z[*y[,w[.u[0s[1q[3pZ5nZ7lZ9jZ;hZ=gZ?eZAcZCaZD`ZF^YH\YJZYLXYNWYPUYRSYSQYUOYWNYYLX[JX]HX_GXaEXbCXdAXf@Xh>XjwW+{g~v    "%'*-/2479;>@BEGIKNPRTVXZ]_ a }c!zd!xf"uh"sj#pl#nn$lp$jr$gt%eu%cw&ay&^{'\|'Z~'X(V(T)R)P)N*L*J+H+F+D,B,@,>-<-:-8.7.5/3/1//0.0,0*1)1'1%1#2"2 23334445555 + ) (&$"  !# % & (*,-/...- - -,,,+++**!)#)&)((*(-'/'2'4&7&9%<%>%A$D$F#I#L"O"Q"T!W!Z ] `c|fziwluorroumxj{geb_\YWTQNKHEB?;852.+($ !            "$%"'3(C)S+pb,_r.O/?0/234 (* 999999 9 9999888888"8$8&8(8*8,8.81838587897;7>7@7B7D7F7~H7|K7zM7xO7vQ7sS7qU7oX7mZ7k\6i^6g`6ec6be6`g6^i6\k6Zn6Xp6Vr6St6Qv6Oy6M{6K}6I5G5D5B5@5>5<5:575553515/5-5*5(5&4$4"4444444444 4 444320.˚db`^\Z X V TRPNLJHFDB @">$<&:'8)6+4-2/01.3,5*6(8&:$<"> @BCEGIKMOP R T VXZ[]____^ ^ ^ ^^^^^^^]]] ]"~]$|]&z](y]*w],u].s\0q\2p\4n\5l\7j\9h\;g\=e\?c\Aa[C`[E^[F\[HZ[JX[LW[NU[PS[RQ[TOZUNZWLZYJZ[HZ]GZ_EZaCZcAZd@Zf>Yh2,%;K Zjmrp)as8PvF>yU+}et      #%(+-0257:<>ACEHJLNQSUWY[]_a }c ze!xg!ui"sk"pm#no#lq#jr$gt$ev%cx%az&^{&\}&Z'X'V(T(R(P)N)L*J*H*F+D+B+@,>,<-:-8-7.5.3.1///./,0*0)0'1%1#1"2 22333344455 + ) '%$"  !# % & (*,-..-- - , ,,+++***)!)$(&(((+'-'0&2&5&7%:%<$?$B$D#G#J"L"O!R!U X []`c|fziwluorsovmyj|geb_\ZWTQNKHEB?;852.+( $ !            !"$"%3'C(S*qb+ar-P.@/01 23 () 888888 8 8887777777"7$7&7(7*7,7.71737567696;6>6@6B6D6F6H6}K6{M6yO6wQ6uS6rU6pX6nZ5l\5j^5h`5fc5de5ag5_i5]k5[n5Yp5Wr5Ut5Rv5Py5N{5L}4J4H4E4C4A4?4=4;48464442404.4+4)3'3%3#3!333333333 3 322220.̘fdb`^\ Z X VTRPNLJHFD B"@$>&<':)8+6-4/2103.5,6*8(:&<$>"@ BCEGIKMOPR T V XZ[]_aa``` ` ` ````______!~_"|_$z_&y_(w^*u^,s^.q^0p^2n^4l^6j^7h^9g^;e]=c]?a]A`]C^]E\]GZ]HX]JW]LU]NS\PQ\RO\TN\VL\WJ\YH\[G\]E\_C\aA[c@[d>[f<[h:[j9[l7[n5[p3[q2[s0Zu.Zw,Zy+Z{)Z}'Z~%Z$Z"Z ZYYYYYYYYYY X X XXXXXXWK?3,';KZj nrr'au6PxD>{S+cr     !$&)+.1368:=?ADFHKMOQSVXZ\^`b}d zf xh!uj!sl!pm"no"lq#js#gu$ew$cx%az%^|%\~&Z&X'V'T'R(P(N)L)J)H*F*D+B+@+>,<,:,8-7-5-3.1./../,/*/)0'0%0#1"1 12223334444 * ( '%#! !# % &(*,-.--- , ,,++***)) )"($('')'+'.&0&3%5%8%:$=$@#B#E"H"J"M!P!S U X[^ad|gzjwmuprsovmzj}geb_\ZWTQNKHEB?;852.+ ( $ !            !#"$3&C'S)rb*br+Q-A.1/"12 (( 677777 7 7766666666"6$6&6(6*6,6.61635557595;5>5@5B5D5F5H5~K5|M5zO5xQ5vS5sU4qX4oZ4m\4k^4i`4gc4ee4bg4`i4^k4\n4Zp4Xr4Vt4Sv4Qy3O{3M}3K3I3G3D3B3@3>3<3:373533313/2-2*2(2&2$2"2222222222 1 11110.͖hfdb`^ \ Z XVTRPNLJHF D"B$@&>'<):+8-6/412305.6,8*:(<&>$@"B CEGIKMOPRT V X Z[]_abbbbb b b baaaaaaaa~a!|a#z`$y`&w`(u`*s`,q`.p`0n`2l`4j`6h_8g_9e_;c_=a_?`_A^_C\_EZ_GX_HW^JU^LS^NQ^PO^RN^TL^VJ^WH^YG][E]]C]_A]a@]c>]e<]f:]h9]j7]l5\n3\p2\r0\s.\u,\w+\y)\{'\}%\~$["[ [[[[[[[[[ZZ Z Z ZZZZZZXMA5,);KZj prt%aw4PzB>}Q+ap       "$'*,/1469;=@BEGIKNPRTVXZ\^`b}dzfxh uj sl!pn!np"lr"jt#gu#ew#cy$a{$^}%\~%Z&X&V&T'R'P(N(L(J)H)F*D*B*@+>+<+:,8,7-5-3-1./...,/*/)/'0%0#0"1 11122233344 * ( &$#! !# % &(*,---,, , +++***))( ("(%'''*&,&.&1%3%6$8$;$>#@#C"F"H!K!N!P S VY\_be|hzkwnuqrtowmzj}geb_\ZWTQNKHEB?<852 . + ( $ !           !"#3$C&S'tb)cr*R,B-2.#01 (' 566666 6 6555555555"5$5&5(5*5,5.51434547494;4>4@4B4D4F4H4K4}M4{O4yQ4wS3uU3rX3pZ3n\3l^3j`3hc3fe3dg3ai3_k3]n3[p3Yr3Wt3Uv2Ry2P{2N}2L2J2H2E2C2A2?2=2;28262422101.1+1)1'1%1#1!111111100 0 00000.Δjhfdb` ^ \ ZXVTRPNLJH F"D$B&@'>)<+:-8/61432506.8,:*<(>&@$B"C EGIKMOPRTV X Z []_acddddd c ccccccccc~b|b!zb#yb%wb'ub(sb*qb,pb.nb0la2ja4ha6ga8ea:ca;aa=`a?^aA\`CZ`EX`GW`IU`JS`LQ`NO`PN`RL`TJ_VH_XG_YE_[C_]A__@_a>_c<_e:_f9^h7^j5^l3^n2^p0^r.^s,^u+^w)^y']{%]}$]~"] ]]]]]]\\\\\ \ \ \\\[[[ZOC7,+;KZjrru#ay2P|@>O+_n        "%(*-/2479<>ACEHJLNPSUWY[]_ac}ezgxiuk sm po!nq!lr"jt"gv"ex#cz#a{$^}$\%Z%X%V&T&R'P'N'L(J(H)F)D)B*@*>+<+:+8,7,5,3-1-/-..,.*.)/'/%/#0"0 01112222333 ) ' &$"  ! # % &(*,--,,+ + +***)))((!'#'%'(&*&-%/%2%4$7$9#<#>#A"C"F!I!L N QTWZ\_be|hzkwnuqrtoxm{j~geb_\ZWTQNKHEB?<85 2 / + ( $ !          ""3#C%S&ub(dr)T*C,3-$/0 (& 455555 5 4444444444"4$4&4(4*4,4.31333537393;3>3@3B3D3F3H3K3~M3|O3zQ2xS2vU2tX2qZ2o\2m^2k`2ic2ge2eg2bi2`k2^n2\p2Zr2Xt1Vv1Sy1Q{1O}1M1K1I1G1D1B1@1>1<1:170503010/0-0*0(0&0$0"000000//// / ////.ϒljhfda _ ] [YWUSQOMKI G"E$C&A'?)>+<-:/8163452608.:,<*>(@&B$C"E GIKMOPRTVX Z []_acefffee e eeeeeedd~d|dzd!yd#wd%ud'sd)qd*pc,nc.lc0jc2hc4gc6ec8cc:ac<`b=^b?\bAZbCXbEWbGUbISbKQbLObNNaPLaRJaTHaVGaXEaZCa[Aa]@a_>aa<`c:`e9`g7`h5`j3`l2`n0`p.`r,`t+_u)_w'_y%_{$_}"_ ____^^^^^^^ ^ ^ ^]]]]]\PE9,-; KZjtrw"a{0P~>>M+\l       # &(+.0358:=?ADFHJMOQSUXZ\^`bd}fzhxjulsm po nq ls!ju!gw"ex"cz#a|#^~$\$Z$X%V%T&R&P&N'L'J(H(F(D)B)@*>*<*:+8+7+5,3,1,/-.-,-*.).'.%/#/"/ 00011122233 ) ' %#"  ! # % &(*,,,,+ + + ***))((('!'$&&&(&+%-%0$2$5$7#:#<"?"A"D!G!I L ORTWZ]`cf|izlwourruoxm{jheb_\ZWTQNKHEB?<8 5 2 / + ( $ !        "!3"C$S%vb'er(U)D+5,%-/(% 344444 3 3333333333"3$3&3(3*3,2.21232527292;2>2@2B2D2F2H2K2M2}O1{Q1yS1wU1uX1rZ1p\1n^1l`1jc1he1fg1di1ak1_n1]p1[r0Yt0Wv0Uy0R{0P}0N0L0J0H0E0C0A0?0=0;/8/6/4/2/0/./+/)/'/%/#/ ///...... . .....Аmkigec a _ ][YWUSQOMK I"G$E&C'A)?+=-;/9173553618/:.<,>*@(B&C$E"G IKMOPRTVXZ [ ]_acefggggg g gggffff~f|fzfyf!wf#uf%se'qe)pe+ne,le.je0he2ge4ee6cd8ad:`d<^d=\d?ZdAXdCWdEUdGSdIQcKOcMNcNLcPJcRHcTGcVEcXCcZAc\@b]>b_K+Zj      ! $ ' ),.1368;=@BDGIKMPRTVXZ\^`bd}fzhxjulsnppnr lt ju!gw!ey"c{"a}#^~#\#Z$X$V%T%R%P&N&L'J'H'F(D(B)@)>)<*:*8*7+5+3,1,/,.-,-*-).'.%.#/"/ /0001111222 ( ' %#! ! # %&(*,,+++ * **)))(('''"&$&&&)%+%.$0$3#5#8#:"="?!B!E G J MORUX[^acf|izlwpusrvpym|jheb_]ZWTQNKHEB?< 8 5 2 / + ( $!       "3!C"S$wb%fr'V(F*6+&,.($ 233332 2 2222222222"2$2&2(2*1,1.11131517191;1>1@1B1D1F1H1K1M0~O0|Q0zS0xU0vX0tZ0q\0o^0m`0kc0ie0gg0ei0bk0`n/^p/\r/Zt/Xv/Vy/S{/Q}/O/M/K/I/G/D/B/@/>.<.:.7.5.3.1./.-.*.(.&.$."..-------- - ----Џomkige c a _][YWUSQOM K"I$G&E'C)A+?-=/;1937556381:/<->+@)B'C&E$G"I KMOPRTVXZ[ ] _acefhiiiii i hhhhhh~h|hzhyhwg!ug#sg%qg'pg)ng+lg-jg.hg0gf2ef4cf6af8`f:^f<\f>Zf?XfAWfCUeESeGQeIOeKNeMLeOJePHeRGeTEdVCdXAdZ@d\>d]I+Xh    " % ' * -/2479<>@CEGJLNPRUWY[]_ace}gzixkumsopqnrlt jv gx!ez!c{!a}"^"\#Z#X$V$T$R%P%N&L&J&H'F'D(B(@(>)<):*8*7*5+3+1+/,.,,,*-)-'-%.#.". ///00011122 ( & $"! ! # %&(*++++* * )))(((''& &"&%%'%)%,$.$1#3#6"8";"=!@!C E HKMPSVX[^adg|jzmwpusrvpzm}jheb_]ZWTQNKHEB? < 8 5 2 / + ($!       "3 C!S#xb$gr&W'G)7*'+-(# 122211 1 1111111111"1$1&1(0*0,0.01030507090;0>0@0B0D0F0H0K/M/O/}Q/{S/yU/wX/uZ/r\/p^/n`/lc/je/hg/fi/dk.an._p.]r.[t.Yv.Wy.U{.R}.P.N.L.J.H.E.C-A-?-=-;-8-6-4-2-0-.-+-)-'-%-#- ,,,,,,,,, , ,,,,Ѝqomkig e c a_][YWUSQO M"K$I&G'E)C+A-?/=1;39576583:1-@+B)C'E%G#I!KMOPRTVXZ[] _ acefhjkkkjj j jjjjj~j|jziyiwiui!si#qi%pi'ni)li+jh-hh/gh0eh2ch4ah6`h8^h:\hXg@WgAUgCSgEQgGOgINgKLgMJgOHfPGfREfTCfVAfX@fZ>f\,2;&KZ jzr}a*P8>G+Vf   # % ( + - 0257:<?ACFHJMOQSUWZ\^`bdf}hzjxlumsopqnslujwgy ez c|!a~!^"\"Z#X#V#T$R$P%N%L&J&H&F'D'B'@(>(<):)8)7*5*3*1+/+.,,,*,)-'-%-#.". .////000111 ' & $"  ! # %&(*++*** ) ))(('''&&!&#%%%($*$,$/#1#4"6"9!;!>!A C FIKNQSVY\_beh|kznwqutrwpzm}jheb_]ZWTQNKHEB ? < 8 5 2 / +(%!  "3C S"yb#ir%X&H'8)(*+ (" 011000 0 0000000000"0$0&/(/*/,/./1/3/5/7/9/;/>/@/B/D/F/H.K.M.O.~Q.|S.zU.xX.vZ.t\.q^.o`.mc.ke.ig.gi-ek-cn-`p-^r-\t-Zv-Xy-V{-S}-Q-O-M-K-I-G,D,B,@,>,<,:,7,5,3,1,/,-,*,(,&+$+"++++++++++ + ++*Ћsqomki g e ca_][YWUSQ O"M$K&I'G)E+C-A/?1=3;596785:3<1>/@-B+C)E'G%I#K!MOPRTVXZ[]_ a cefhjlmllll l llll~k|kzkykwkuksk!qk#pk%nj'lj)jj+hj-gj/ej1cj2aj4`j6^j8\i:ZiWi@UiBSiCQiEOiGNiILhKJhMHhOGhQEhRChTAhV@hX>hZE+Td  ! # & ) + . 1 3 68;=?BDFIKMORTVXZ\^`bdf}hzjxlunspprntlvjwgye{ c} a~!^!\"Z"X"V#T#R$P$N%L%J%H&F&D'B'@'>(<(:(8)7)5*3*1*/+.+,+*,),',%-#-"- ...///00011 ' % #!  ! # %&(*+**) ) ) ((('''&&%!%#%&$($+#-#/#2"4"7!9!< ? A DFILOQTWZ]_beh|kznwquurxp{m~jheb_]ZWTQNKHE B ? < 9 5 2 /+(%!       "3CS {b"jr#Y%I&9())* (! /0//// / //////////"/$.&.(.*.,...1.3.5.7.9.;.>.@.B.D-F-H-K-M-O-Q-}S-{U-yX-wZ-u\-s^-p`-nc-le-jg,hi,fk,dn,ap,_r,]t,[v,Yy,W{,U},R,P,N,L,J+H+E+C+A+?+=+;+8+6+4+2+0+.+++)*'*%*#* ********* * *))Љusqomk i g eca_][YWUS Q"O$M&K'I)G+E-C/A1?3=5;6987:5<3>1@/B-C+E)G'I%K#M!OPRTVXZ[]_a c efhjlnnnnn n n nmm~m|mzmymwmumsm ql!pl#nl%ll'jl)hl+gl-el/cl1al3`k4^k6\k8Zk:XkUk@SkBQkDOjENjGLjIJjKHjMGjOEjQCjSAjT@iV>iXC+Rb "$ ' * , / 1 4 6 9;>@BEGILNPRUWY[]_aceg}izkxmuosqpsntlvjxgze|c} a ^!\!Z!X"V"T#R#P$N$L$J%H%F&D&B&@'>'<':(8(7)5)3)1*/*.*,+*+)+',%,#,"- --...///000 & % #! ! #%&(***)) ) (('''&&&%%"$$$&$)#+#."0"2"5!7!: = ?BDGJLORUWZ]`cfi|lzowruurxp{mjheb_]ZWTQNK H E B ? < 9 5 2/+(%!       "3CS|b!kr"Z$J%:'*() ( ...... . .........."-$-&-(-*-,-.-1-3-5-7-9-;->-@-B,D,F,H,K,M,O,Q,~S,|U,zX,xZ,v\,t^,q`,oc,me+kg+ii+gk+en+cp+`r+^t+\v+Zy+X{+V}+T+Q+O+M*K*I*G*D*B*@*>*<*:*7*5*3*1*/)-)*)()&)$)")))))))))( ( ((Їwusqom k i gdb`^\ZXVT R"P$N&L'J)H+F-E/C1A3?5=6;89:7<5>3@1B/C-E+G)I'K%M#O!PRTVXZ[]_a c e fhjlnppppp o o oo~o|ozoyowounsnqn pn"nn$ln%jn'hn)gn+en-cm/am1`m3^m5\m6Zm8Xm:WmSl@QlBOlDNlFLlGJlIHlKGlMElOCkQAkS@kU>kVA+P`  "%( * - 0 2 5 7 : <>ACFHJLOQSUWY\^`bdfh}jzlxnuosqpsnulwjygze|c~a^ \ Z!X!V"T"R#P#N#L$J$H%F%D%B&@&>'<':'8(7(5(3)1)/*.*,**+)+'+%,#,", ---...///00 & $ "  ! #%&(*)))( ( ('''&&%%% $"$%#'#)#,"."1!3!6 8 ; =@BEHJMPRUX[^adgj|mzpwsuvryp|mjheb_]ZWTQN K H E B ? < 9 52/+(%!                          "3CS}b lr!\#K$;%+'( ( ------ - ---------,",$,&,(,*,,,.,1,3,5,7,9,;,>,@+B+D+F+H+K+M+O+Q+S+}U+{X+yZ+w\+u^+s`*pc*ne*lg*ji*hk*fn*dp*ar*_t*]v*[y*Y{*W}*U*R)P)N)L)J)H)E)C)A)?)=);)8)6)4)2(0(.(+()('(%(#( ((((((('' ' ''Ѕyvtrpn l j hfdb`^\ZXV T"R$P&N'L)J+H-F/D1B3@5>6<8::8<6>5@3B1C/E-G+I)K'M%O#P!RTVXZ[]_ac e f hjlnpqrqqq q q q~q|qzqypwpupspqppp np"lp$jp&hp'go)eo+co-ao/`o1^o3\o5Zo7Xo8Wn:UnQn@OnBNnDLnFJnHHnIGmKEmMCmOAmQ@mS>mU?+N^   #&(+ . 0 3 5 8 : = ?BDFIKMORTVXZ\^`bdfh}jzlxnupsrptnvlwjyg{e}ca^\ Z X!V!T!R"P"N#L#J$H$F$D%B%@&>&<&:'8'7'5(3(1)/).),***)*'+%+#+", ,,---.../// % $ "  ! #%&()))(( ' ''&&&%%$$ $##%#'"*","/!1!4 6 9;>@CFHKNPSVY\^adgj|mzpwsuvrzp}mjheb`]ZWTQ N K H E B ? < 952/+(%!                          "3CS~bmr ]!L#<$-&'( ,,,,,, , ,,,,,,,,++"+$+&+(+*+,+.+1+3+5+7+9+;+>*@*B*D*F*H*K*M*O*Q*S*~U*|X*zZ*x\*v^)t`)qc)oe)mg)ki)ik)gn)ep)cr)`t)^v)\y)Z{)X})V(T(Q(O(M(K(I(G(D(B(@(>(<(:(7(5'3'1'/'-'*'('&'$'"'''''&&&&& & &Єzxvtrp n l jhfdb`^\ZX V"T$R&P'N)L+J-H/F1D3B5@6>8<::<8>6@4B2C0E.G,I+K)M'O%P#R!TVXZ[]_ace f h jlnpqsssss s s ~s|szryrwrursrqrprnr lr"jq$hq&gq(eq)cq+aq-`q/^q1\q3Zp5Xp7Wp9Up:SpOp@NpBLpDJoFHoHGoIEoKCoMAoO@oQ>oS=+L\       !$'),.1 4 6 9 ; = @ BEGILNPRTWY[]_acegi}kzmxouqssptnvlxjzg|e}ca^\Z X V T!R!P"N"L#J#H#F$D$B%@%>%<&:&8'7'5'3(1(/(.),)*))*'*%+#+"+ ,,,---...// % # ! ! #%&()((( ' ' '&&%%%$$#!###&"("*!-!/!2 4 79<>ACFIKNQTVY\_behk|nzqwtuwrzp}mjheb`]ZWT Q N K H E B ? <952/,(%!       "3CSbnr^ N"=#.%&' ++++++ + +++++++***"*$*&*(***,*.*1*3*5*7*9*;)>)@)B)D)F)H)K)M)O)Q)S)U)}X){Z)y\(w^(u`(sc(pe(ng(li(jk(hn(fp(dr(at(_v(]y([{(Y}'W'U'R'P'N'L'J'H'F'C'A'?'=';'8&6&4&2&0&.&+&)&'&%&#& &&&%%%%%% % %Ђ|zxvtr p n ljhfdb`^\Z X"V$T&R'P)N+L-J/H1F3D5B6@8>:<<:>8@6B4C2E0G.I,K*M(O&P$R#T!VXZ[]_acef h j lnpqsuuuuu u ~t |tztytwtutstqtptnsls js"hs$gs&es(cs*as+`s-^r/\r1Zr3Xr5Wr7Ur9Sr;QrNq@LqBJqDHqFGqHEqJCqKAqM@qO>pQ;+JZ          "%'*-/24 7 9 < > A C EHJLNQSUWY[^`bdfhj}lznxouqsspunwlyjzg|e~ca^\ZXV T R!P!N"L"J"H#F#D$B$@$>%<%:&8&7&5'3'1(/(.(,)*)))'*%*#*"+ ++,,,---... $ # ! !#%&((('' ' &&&%%$$$##""$"&")!+!- 0 2 57:<?ADGILORTWZ]`cehk|nzrwuuxr{p~mjheb`]ZW T Q N K H E B ?<952/,(%!       "3CSbpr_O!?"/$%&  ****** * ******))))")$)&)()*),).)1)3)5)7)9(;(>(@(B(D(F(H(K(M(O(Q(S(U(~X(|Z'z\'x^'v`'tc're'og'mi'kk'in'gp'er'ct'`v'^y'\{&Z}&X&V&T&Q&O&M&K&I&G&D&B&@&>%<%:%7%5%3%1%/%-%*%(%&%$%"%%$$$$$$$$ $ Ѐ~|zxvt r p nljhfdb`^\ Z"X$V&T'R)P+N-L/J1H3F5D6B8@:><<>:@8B6C4E2G0I.K,M*O(P&R$T"V XZ[]_acefh j l npqsuwwwvv ~v |v zvyvwvuvsvqupunuluju hu"gu$eu&cu(at*`t,^t-\t/Zt1Xt3Wt5Ut7St9Qs;Os=Ns>Ls@JsBHsDGsFEsHCsJArL@rM>rO9+HW    #%(+-0358 : = ? A D F HKMOQTVXZ\^`bdfhj}lznxpurstpvnxlyj{g}eca^\ZXVT R P!N!L!J"H"F#D#B#@$>$<%:%8%7&5&3'1'/'.(,(*())')%)#*"* +++,,,----. $ "  !#%&((''' & &%%%$$$## """$!'!)!, . 0358:=?BEGJMORUX[]`cfil}ozrxuuxr|pmkheb`]Z W T Q N K H EB?<962/,(%!      "3CSbqr`P @!0" $%  )))))) ) )))))((((("($(&(((*(,(.(1(3(5(7'9';'>'@'B'D'F'H'K'M'O'Q'S'U'X&}Z&{\&y^&w`&uc&se&pg&ni&lk&jn&hp&fr&dt&bv&_y%]{%[}%Y%W%U%R%P%N%L%J%H%F%C%A$?$=$;$8$6$4$2$0$.$+$)$'$%$## ######### # ~~~~|~z~xv t r pnljhfdb`^ \"Z$X&V'T)R+P-N/L1J3H5F6D8B:@<>><@:B8C6E4G2I0K.M,O*P(R&T$V"X Z[]_acefhj l n pqsuwxxxx~x |x zx yxwxuwswqwpwnwlwjwhw gw"ev$cv&av(`v*^v,\v.Zv/Xv1Wv3Uu5Su7Qu9Ou;Nu=Lu?Ju@HuBGuDEtFCtHAtJ@tL>tN7+FU   !#&)+.1368; = @ B D G I K NPRTVY[]_acegik}mzoxqusstpvnxlzj|g~eca^\ZXVTR P N L!J!H"F"D"B#@#>$<$:$8%7%5&3&1&/'.',(*()(')%)#)"* **+++,,,--- # "   !#%&'''&& & %%$$$###" "#!%!'!* , /1368;=@CEHKMPSUX[^adgjm}pzsxvuyr|pmkheb` ] Z W T Q N K HEB?<962/,(%!      "3CSbrraQA 1!!#$  (((((( ( ((((''''''"'$'&'('*','.'1'3'5&7&9&;&>&@&B&D&F&H&K&M&O&Q&S&U%X%~Z%|\%z^%x`%vc%te%rg%oi%mk%kn%ip%gr%et$cv$`y$^{$\}$Z$X$V$T$Q$O$M$K$I$G$D#B#@#>#<#:#7#5#3#1#/#,#*#(#&"$"""""""""""" |||~}|}z}x }v }t }r}p}n}k~i~g~e~c~a~_ ~]"~[$Y&W'U)S+Q-O/M1K3J5H6F8D:B<@>>@vL5+DS      !$'*,/1479<> @ C E G J L N QSUWY[^`bdfhjl}nzoxqussupwnyl{j|g~eca^\ZXVTRPN L J!H!F"D"B"@#>#<$:$8$7%5%3%1&/&.','*')('(%(#)") )***+++,,,- # !   !#%&''&& % % %$$$##"""!!#!& ( * -/2469;>ACFHKNQSVY\_adgjm}pzsxwuzr}pmkheb ` ] Z W T Q N KHEB?<962/,(%!       "3CSbsrbRB2 #"#  '''''' ' '''&&&&&&&"&$&&&(&*&,&.&1&3%5%7%9%;%>%@%B%D%F%H%K%M%O%Q%S$U$X$Z$}\${^$y`$wc$ue$sg$pi$nk$ln$jp$hr#ft#dv#by#_{#]}#[#Y#W#U#R#P#N#L#J#H"F"C"A"?"=";"8"6"4"2"0"."+")!'!%!#! !!!!!!!!! zz{{}{{{y {w {u {s{q|o|m|k|i|g|e|c|a |_"}]$}[&}Y'}W)}U+}S-}Q/}O1~M3~K5~I6~G8~E:~C<~A>~?@~=B;C:E8G6I4K2M0O.P,R*T(V&X$Z"[ ]_acefhjln p q suwyz||~||{z{ y{ w{ u{s{q{p{n{lzjzhzgzez!cz"az$`z&^z(\y*Zy,Xy.Wy0Uy2Sy3Qy5Oy7Ny9Lx;Jx=Hx?GxAExBCxDAxF@xH>xJ3+BQ       "%(*-0257:<?A D F H K M O Q SVXZ\^`bdfhjl}nzpxrutsvpxnyl{j}geca^\ZXVTRPNL J H!F!D!B"@">#<#:#8$7$5%3%1%/&.&,&*')''(%(#(") ))***+++,,, " !   !#%&&&&% % %$$###""!!!!$ & (+-0257:<?ADFILNQTWZ\_behkn}qztxwuzr}pmkhe b ` ] Z W T Q NKHEB?<962/,(%############ # # # # # ###################### "3CSbtrcSC3$!"  &&&&&& & &&%%%%%%%%"%$%&%(%*%,%.%1$3$5$7$9$;$>$@$B$D$F$H$K$M$O$Q#S#U#X#Z#~\#|^#z`#xc#ve#tg#ri#ok#mn#kp"ir"gt"ev"cy"`{"^}"\"Z"X"V"T"Q"O"M!K!I!G!D!B!@!>!}A@}?B}=C};E}9G}7I}5K}3M}1O~0P~.R~,T~*V~(X~&Z~$[~"] _acefhjlnp q s uwyz|~~}|}z}y} w} u}s}q}p|n|l|j|h|g|e|c|!a|#`{$^{&\{(Z{*X{,W{.U{0S{2Q{4Oz5Nz7Lz9Jz;Hz=Gz?EzACzCAzD@yF>yH1+@O        !!"#&(+.0368;=?BD G I K M P R T VY[]_acegikm}ozqxsuusvpxnzl|j~geca^\ZXVTRPNLJ H F D!B!@">"<":#8#7$5$3$1%/%.&,&*&)'''%'#("( ()))***+++, "    !#%&&%%% $ $$##"""!! " $ ')+.0358:=?BDGJLORUWZ]`cfilo}rzuxxu{s~pmkh e c ` ] Z W T QOLIEB?<962/,('''''''''''' ' ' ' ' ' '''''''''''''''''''''''  "3CSbureTD4%! $%%%%% % %$$$$$$$$$"$$$&$($*$,$.#1#3#5#7#9#;#>#@#B#D#F#H#K#M#O"Q"S"U"X"Z"\"}^"{`"yc"we"ug"si"qk"nn!lp!jr!ht!fv!dy!b{!_}!]![!Y!W!U!R!P N L J H F C A ? = ; 8 6 4 20.+)'%# wwwwww} w{ wy xwxuxsxqxoxmxkxiygye yc"ya$y_&y]'y[)yY+zW-zU/zS1zQ3zO5zM6zK8zI:zG<{E>{C@{AB{?C{=E{;G{9I{7K|5M|3O|1P|/R|-T|+V|)X|(Z|&[}$]}"_} a}c}e}f}h}j~l~n~p~q~ s~ u~w~y~z|~~|zyw u sq~p~n~l~j~h~g~e~c}a}!`}#^}%\}&Z}(X}*W},U}.S|0Q|2O|4N|6L|7J|9H|;G|=E|?C{AA{C@{E>{F<{H:{J9{L7{N5{P3zR2zS0zU.zW,zY+z[)z]'z_%z`$yb"yd yfyhyjylymyoyqxsxuxwxx xz x| x~xxwwwvk_~T,zH;w/+>M         !"##$%&'),/1469;>@CEG J L N P S U W Y[]`bdfhjln}pzqxsuuswpyn{l|j~geca^\ZXVTRPNLJHF D B!@!>!<":"8#7#5#3$1$/%.%,%*&)&'&%'#'"( (()))***+++ !    !#%&%%%$ $ ###""!!! #%'*,.1368;=@BEHJMPRUX[^`cfilo}rzuxxu|spmk h e c ` ] Z W TQOLIEB?<962/,************ * * * * * ************************   "3CSbvrfUE5&  #$$$$$ $ $#########"#$#&#(#*#,"."1"3"5"7"9";">"@"B"D"F"H"K"M!O!Q!S!U!X!Z!\!~^!|`!zc!xe!vg!ti!rk on mp kr it gv ey c{ `} ^ \ Z X V TQOMKIGDB@><:7531/,*(&$"uuuuuu v} v{ vyvwvuvsvqvovmwkwiwg we"wc$wa&w_'w])x[+xY-xW/xU1xS3xQ5xO6xM8yK:yIyE@yCByACy?Ey=Gy;Iz9Kz7Mz5Oz3Pz1Rz/Tz-Vz+X{)Z{'[{%]{#_{"a{ c{e{f{h|j|l|n|p|q|s| u| w}y}z}|}~}|zywu s qpnljhgeca`!^#\%Z'X(W~*U~,S~.Q~0O~2N~4L~6J~8H~9G};E}=C}?A}A@}C>}E<}G:}H9}J7|L5|N3|P2|R0|T.|U,|W+|Y)|['{]%{_${a"{b {d{f{h{j{lzmzozqzszuzw zx zz z|y~yyyyxma|V,yJ;u>Kr1Zo$jk{h aP>-+<K     ! ""#$%%&'())*-/247:<>ACFHJ M O Q S V X Z \^`bdfhjln}pzrxtuvsxpyn{l}jgeca^\ZXVTRPNLJHFD B @ >!@CFHKNPSVY[^adgjmp}szvxyu|spm k h e c ` ] Z WTROLIFB?<962/............ . . . . . .........................  "3CSbxrgWF7'  "##### # """"""""""""$"&"("*!,!.!1!3!5!7!9!;!>!@!B!D!F!H!K M O Q S U X Z \ ^ }` {c ye wg uiskqnnplrjthvfyd{b}_][YWUSPNLJHFCA?=;86420.+)'%# ssssst t t} t{tytwtutsuquoumukui ug"ue$uc&va'v_)v]+v[-vY/vW1vU3vS5vQ6wO8wM:wKwG@wEBwCCwAEx?Gx=Ix;Kx9Mx7Ox5Px3Rx1Ty/Vy-Xy+Zy)[y']y%_y#ay!cyezfzhzjzlznzpzqzs{u{ w{ y{z{|{~{{zywus q pnljhgeca`^!\#Z%X'W)U*S,Q.O0N2L4J6H8G:E;C=A?@A>C<E:~G9~I7~J5~L3~N2~P0~R.~T,~V+}W)}Y'}[%}]$}_"}a }c}d}f|h|j|l|n|o|q|s|u |w {y {z{|{~{{{zn}czW,wL;t?Kp3Zm&ji{f aP>++:I ! ! " # $ $ %&''()**+,--0358:=?BDFIKM P R T V X [ ] _ acegikmo}qzsxuuvsxpzn|l~jgeca^\ZXVTRPNLJHFDB@ > ADFIKNQTVY\_begjmp}szwxzu}sp m k h e c ` ] ZWTROLIFB?<963111111111111 1 1 1 1 1 1111111111111111111111111 1  " 3CSbyrhXH8(  !""""" ! !!!!!!!!!!"!$!&!( * , . 1 3 5 7 9 ; > @ B D F HKMOQSUXZ\^~`|czexgvitkrnopmrktivgye{c}`^\ZXVTQOMKIGDB@><:7531/,*(&$"qqqqrr r r r}r{ryrwsusrspsnslsj sh"sf$td&tb't`)t^+t\-tZ/tX1tV3uT5uR6uP8uN:uMuI@uGBuECvCEvAGv?Iv=Kv;Mv9Ov7Pv5Rw3Tw1Vw/Xw-Zw+[w)]w'_w%ax#cx!exfxhxjxlxnxpxqysyuywy yy zy|y~yzzywusq p nljhgeca`^\!Z#X%W'U)S+Q,O.N0L2J4H6G8E:C;A=@?>A)+8G  !"## $ % & & ' ( ))*+,,-.//01369;=@BEGILNPS U W Y [ ] ` b dfhjlnp}qzsxuuwsyp{n}l~jgeca^\ZXVTRPNLJHFDB@> < :!8!7!5"3"1#/#.#,$*$)$'%%%#&"& &'''((()))*      !#$$$## # ""!!!   "$')+.0257:<?ADGILOQTWZ]_behknq}tzwxzu} s p m k h e c ` ]ZWUROLIFC?<96444444444444 4 4 4 4 4 4 444444444444444444444444 4 4 " 3 CSbzriYI9)  !!!!          " $ &(*,.13579;>@BDFHKMOQSUXZ\^`}c{eygwiuksnqpnrltjvhyf{d}b_][YWUSPNLJHFCA?=;86420.+)'%# oooppp p p p~p|pzqxqvqtqrqpqnql qj"rh$rf&rd'rb)r`+r^-r\/rZ1sX3sV5sT6sR8sP:sNsJ@tHBtFCtDEtBGt@It?Kt=Mt;Ou9Pu7Ru5Tu3Vu1Xu/Zu-[u+]u)_v'av%cv#ev!fvhvjvlvnwpwqwswuwwwyw zw |x~xxxxwusqp n ljhgeca`^\Z!X#W%U'S)Q+O-N.L0J2H4G6E8C:A<@=>?'+6E"#$%%&' ( ( ) * + + ,-../011234479<>ACEHJLOQSU X Z \ ^ ` b d fhjlnp}rztxvuxszp{n}ljgeca^\ZXVTRPNLJHFDB@>< : 8 7!5!3"1"/".#,#*$)$'$%%#%"% &&&''((()))       !#$$##" " "!!    "%'),.1358:=@BEGJMORUXZ]`cfilor}uzxx{ u~ s p m k h e c `]ZWUROLIFC?<9888888888888 8 8 8 8 8 8 8888888888888888888888888 8!8" 3 C Sb{rjZJ:*       "$&(*,.13579;>@BDFHKMOQSUXZ\^`~c|ezgxivktnrpprmtkviyg{e}ca^\ZXVTQOMKIGDB@><:7531/,*(&$"mnnnnn n n no~o|ozoxovotoroppn pl"pj$ph&pf'pd)pb+p`-q^/q\1qZ3qX5qV6qT8qR:qPrL@rJBrHCrFErDGrBIr@Kr>Ms>%+4C%&&'())* + , , - . / /01223455678:<?ADFIKMORTVX [ ] _ a c e g ikmoq}szuxwuxszp|n~ljgeca^\ZXVTRPNLJHFDB@><:8 7 5!3!1!/".",#*#)#'$%$#%"% %&&&'''((()      !####" " ! !!   !#%(*,/1469;>@CEHKMPSUX[^acfilor}uzx x| u s p m k h ec`]ZWUROLIFC?<;;;;;;;;;;;; ; ; ; ; ; ; ;;;;;;;;;;;;;;;;;;;;;;;;; ;!;!;" 3 C Sb|rk[K;+    "$&(*,.13579;>@BDFHKMOQSUXZ\^`c}e{gyiwkunspqrntlvjyh{f}db_][YWUSPNLJHFCA?=;96420.+)'%# llllll l l mmm~m|mzmxmvmtnrnp nn"nl$nj&nh'nf)nd+ob-o`/o^1o\3oZ5oX6oV8oT:pRpN@pLBpJCpHEpFGpDIqBKq@Mq>Oq<<>:@9A7C5E3G2I0K.M,N+P)R'T%V$X"Z []_aceghjln p r suwy{|yvvjs_,pS;lGKi:Ze.jb!{^[P>#+2A(()*++,-. . / 0 1 1 23445667899:;=@BEGILNPRUWY[ ] _ b d f h j lnpr}szuxwuys{p}n~ljgeca^\ZXVTRPNLJHFDB@><:87 5 3!1!/!.","*")#'#%$#$"$ %%%&&'''(((      !##""" ! ! !  !$&(+-/2479<>ACFHKNPSVY\^adgjmps}v zy x| u s p m k hec`]ZWUROLIFC@>>>>>>>>>>>> > > > > > > >>>>>>>>>>>>>>>>>>>>>>>>> >!>!>">"3 C S b}rm\L<,   "$&(*,.13579;>@BDFHKMOQSUXZ\^`c~e|gzixkvntprrptmvkyi{g}eca^\ZXVTQOMKIGDB@><:7531/,*(&$"jjjjjj j k kkkk~k|kzkxlvltlr lp"ln$ll&lj'lh)mf+md-mb/m`1m^3m\5mZ6mX8nV:nTnP@nNBnLCnJEnHGoFIoDKoBMo@Oo>Po:<<:>9@7B5C3E2G0I.K,M+O)P'R%T$V"X Z\]_aceghjl n p rsuwyzwwtlq`,nU;jIKg!+0?*+,--.//01 2 2 3 4 5 567889:;;<==>@CEHJLOQSUXZ\^ ` b d f h j l npr}tzvxxuzs{p}nljgeca^\ZXVTRPNLJHFDB@><:875 3 1 /!.!,"*")"'#%###"$ $%%%&&&'''(       !#"""! !    "$&)+-0257:<?ADFILNQTWY\_behknqt }w zz x} u s p n khec`]ZXUROLIFCBBBBBBBBBBBB B B B B B B BBBBBBBBBBBBBBBBBBBBBBBBB B B!B"B#B"3C S b ~rn]M=.   "$&(*,.13579;>@BDFHKMOQSUXZ\^`ce}g{iykwnupsrqtnvlyj{h}fdb_][YWUSPNLJHFCA?=;96420.+)'%# hhhhhi i i iiiii~j|jzjxjvjt jr"jp$jn&kl'kj)kh+kf-kd/kb1k`3k^5l\6lZ8lX:lVlR@lPBlNCmLEmJGmHImFKmDMmBOm@Pm>Rn8<::<9>7@5B3C2E0G.I,K+M)O'Q%R$T"V XZ\^_acegij l n prtuwyvyrnob,lV;iJKe>Zb2j^%{ZW P>+.=-../0112344 5 6 6 7 8 99:;<<=>??@AADFHKMORTVXZ]_a c e g i k m o qs}uzwxxuzs|p~nljgeca^\ZXVTRPNLJHFDB@><:87531 / .!,!*!)"'"%###"# $$$%%%&&'''       !""!!!  "%'),.0358:=?BDGJLORTWZ]`behknq t }w zz x} u s p nkhfc`]ZXUROLIFEEEEEEEEEEEE E E E E E E EEEEEEEEEEEEEEEEEEEEEEEEEE E!E"E"E#E"3C S b ro^N>/   "$&(*,.13579;>@BDFHKMOQSUXZ\^`ce~g|izkxnvptrrtpvmyk{i}geca^\ZXVTQOMKIGDB@><:7531/,*(&$"ffffgg g g gggghh~h{hyhwhu hs"hq$io&im'ik)ii+ig-ie/ic1ia3j_5j]6j[8jY:jWjS@jQBkPCkNEkLGkJIkHKkFMkDOkBPl@Rl>Tl6<8::9<7>5@3B2D0E.G,I+K)M'O%Q$R"T VXZ\^_acegi j l nprtuwt{qpmd,jX;gLKc@Z`3j\'{XU P>+,;00122345567 8 8 9 : : ; <==>?@@ABBCDEGIKNPRUWY[]_bd f h j l n p r s }uzwxyu{s}pnljgeca^\ZXVTRPNLJHFDB@><:87531/ . , *!)!'"%"#""# #$$$%%%&&&'      !"!! !#%'*,/1368;=@BEHJMPRUXZ]`cfil o r u }x z{ x~ u s pnkhfc`]ZXUROLIHHHHHHHHHHHH H H H H H H HHHHHHHHHHHHHHHHHHHHHHHHHH H!H!H"H#H$H$H"3CS b r p`O?0    "$&(*,.13579;>@BDFHKMOQSUXZ\^`ceg}i{kynwpurstqvnyl{j}hfdb_][YWUSPNLJHFCA?=;96420.+)'%# dddeee e e eeeffff}f{fyfw fu"gs$gq&go'gm)gk+gi-gg/ge1hc3ha5h_6h]8h[:hYiU@iSBiQCiOEiMGiKIiIKiGMjEOjCPjBRj@Tj>Vj5<7:89:7<5>3@2B0D.F,G+I)K'M%O$Q"S TVXZ\^`aceg i k lnprtur}oqlf,hZ;eNKaBZ^5jZ){WSO >+*923445667899: ; ; < = > > ?@AABCCDEFFGHJLNQSUWZ\^`bdf h j l n p r t }v zxxzu|s}pnljgeca^\ZXVTRPNLJHFDB@><:87531/. , * )!'!%!#""" ###$$$%%&&&     !!!   !#&(*-/2469;>@CFHKMPSVX[^adgi l o r u }x z| x u spnkhfc`]ZXUROLKKKKKKKKKKKK K K K K K K KKKKKKKKKKKKKKKKKKKKKKKKKK K!K!K"K#K#K$K%K&K"3CSb r q aPA1!   "$&(*,.13579;>@BDFHKMOQSUXZ\^`ceg~i|kznxpvrttrvpym{k}igeca^\ZXVTQOMKIGDB@><:7531/,*(&$"bbcccc c c ccdddddd}d{ey ew"eu$es&eq'eo)em+ek-fi/fg1fe3fc5fa6f_8f]:f[gW@gUBgSCgQEgOGgMIgKKhIMhGOhEPhCRhATh?Vh=Xh;Zi9[i8]i6_i4ai2ci0ei.fi,hj*jj(lj&nj$pj"qj sjujwkykzk|k~kkkk l l llllljhge c a `^\ZXWUSQO N"L$J&H(G*E+C-A/@1>3<5:7997:5<3>2@0B.D,F+H)I'K%M$O"Q SUVXZ\^`ace g i klnprsp~msjh,f\;cPK`DZ\7jX*{UQM >+'65567789::;<<= > ? ? @ A B BCDDEFGGHIIJKMOQTVXZ]_acegi k m o q s u }w zy xzu|s~pnljgeca^\ZXVTRPNLJHFDB@><:87531/.,* ) '!%!#!"" ""##$$$%%%&      !!    "$&)+-02479<>ADFIKNQSVY\_adg j m p s v }y z| x uspnkhfc`][XURONNNNNNNNNNNN N N N N N N NNNNNNNNNNNNNNNNNNNNNNNNNN N N!N"N#N#N$N%N%N&N"3CSb r r bRB2#   "$&(*,.13579;>@BDFHKMOQSUXZ\^`cegi}k{nypwrutsvqyo{l}jhfdb`][YWUSPNLJHFCA?=;96420.+)'%# `aaaaa a a bbbbbbbbc}c{ cy"cw$cu&cs'cq)co+dm-dk/di1dg3de5dc6da8d_:e]eY@eWBeUCeSEeQGeOIfMKfKMfIOfGPfERfCTfAVg?Xg=Zg;[g9]g7_g5ag3cg2eh0fh.hh,jh*lh(nh&ph$qh"si uiwiyizi|i~iiijj j j jjjjjhgec a ` ^\ZXWUSQON L"J$H&G(E*C,A-@/>1<3:597795;3<2>0@.B,D+F)H'I%K$M"O QSUVXZ\^`bc e g ikmnprnkuhi,e^;aRK^FZZ9jV,{SOK >+%47889:;;<=>>?@@ A B C C D E EFGHHIJJKLMMNPRTWY[]_adfhjl n p r t u }w zy x{ u}spnljgeca^\ZXVTRPNLJHFDB@><:87531/.,*) ' % #!"! """###$$$%%            "$')+.0358:<?BDGILOQTWY\_be h k n q t w }z {} xuspnkhfc`][XURQQQQQQQQQQQQ Q Q Q Q Q Q QQQQQQQQQQQQQQQQQQQQQQQQQQ Q Q!Q"Q"Q#Q$Q%Q%Q&Q'Q'Q3CSbr s c SC3$   "$&(*,.13579;>@BDFHKMOQSUXZ\^`cegik|nzpxrvttvryp{m}kigeca^\ZXVTQOMKIGDB@><:7531/,*(&$!______ _ ` ```````aaa} a{"ay$aw&au'as)bq+bo-bm/bk1bi3bg5be6cc8ca:c_c[@cYBcWCcUEdSGdQIdOKdMMdKOdIPdGRdETeCVeAXe?Ze=[e;]e9_e7ae5cf3ef1ff/hf-jf+lf*nf(pf&qg$sg"ug wgygzg|g~ghhhhh h h hiiihgeca ` ^ \ZXWUSQONL J"H$G&E(C*A,@.>/<1:39577593;2=0>.@,B+D)F'H%J$K"M OQSUWXZ\^`b c e gikmnpmiwfk,c`;_TK\GZX;jU.{Q!MI>+#2::;<<=>??@AABCC D E F F G H HIJKKLMMNOPPQSUWZ\^`bdfhjlnp r t v }x zz x| u} spnljgeca^\ZXVTRPNLJHFDB@><:87531/.,*)'% # "! !!""###$$$%           #%'*,.1368;=@BEGJMORUWZ]`c e h k n q t w }z {}xuspnkhfc`][XUTTTTTTTTTTTT T T T T T T TTTTTTTTTTTTTTTTTTTTTTTTTTT T!T"T"T#T$T$T%T&T&T'T(T)TCSbru d T D4%   "$&(*,.13579;>@BDFHKMOQSUXZ\^`cegik}n{pyrwtuvsyq{o}ljhfdb`][YWUSPNLJHFCA?=;96420.+)'%# ]]]]]] ^ ^ ^^^^^^____ _}"_{$_y&`w'`u)`s+`q-`o/`m1`k3`i5ag6ae8ac:aaa]@a[BaYCbWEbUGbSIbQKbOMbMObKPbIRcGTcEVcCXcAZc?[c=]c;_d9ad7cd5ed3fd1hd/jd-ld+ne)pe'qe&se$ue"we yeze|f~fffffff g ggggggeca` ^ \ ZXWUSQONLJ H"G$E&C(A*@,>.<0:1937557392;0=.?,@+B)D'F%H$J"L MOQSUWYZ\^` b d egikmnkhxdm,aa;]UKZIZV=jS0{O#KG>+!0<==>?@@ABBCDDEFG G H I I J K LLMNNOPPQRSSTVXZ\_acegikmoqs u w }y zz x| u~ s pnljgeca^\ZXVTRPNLJHFDB@><:87531/.,*)'%# " !!!"""###$$        !#&(*-/1469;>@CEHJMPRUX[]` c f i l o r u x }{{~xvspnkhfc`][XWWWWWWWWWWWW W W W W W W WWWWWWWWWWWWWWWWWWWWWWWWWWW W!W!W"W#W#W$W%W&W&W'W(W(~W)}WCSbrv e U E5&   "$&(*,.13579;>@BDFHKMOQSUXZ\^`cegikn|pzrxtvvtyr{p}mkigeca^\ZXVTROMKIGDB@><:7531/,*(&$![[[[[\ \ \ \\\\]]]]]] ]~"]|$^z&^x'^v)^t+^r-^p/^n1^l3_j5_h6_f8_d:_b<_`>_^@`\B`ZC`XE`VG`TI`RK`QM`OOaMPaKRaITaGVaEXaCZaA[a?]b=_b;ab9cb7eb5fb3hb1jb/lc-nc+pc)qc'sc%uc#wc!yc zd|d~ddddddee e eeeeeeca`^ \ ZXWUSQONLJH!G"E$C&A(@*>,<.:092735537290;.=,?+@)B'D%F$H"J LMOQSUWYZ\^ ` b degiklifzco,_c;\WKXKZT?jQ2{M%IE >+.>?@@ABCCDEEFGHHIJ J K L L M N OOPQQRSSTUVVWY[]_adfhjlnprtu w }y z{ x} u s p nljgeca^\ZXVTRPNLJHFDB@><:87531/.,*)'%#"  !!!""###$        "$&(+-/2479<>ACFHKNPSVY[^ a d g j l o r uy}|{xvspnkhfc`][ZZZZZZZZZZZZ Z Z Z Z Z Z Z ZZZZZZZZZZZZZZZZZZZZZZZZZZ Z Z!Z"Z#Z#Z$Z%Z%~Z&}Z'}Z'|Z({Z)zZ*zZ*yZSbrwf V F 6'    "$&(*,.13579;>@BDFHKMOQSUXZ\^`cegikn~p{rytwvuys{q}oljhfdb`][YWUSPNLJHFCA?=;964 2 0 . + ) ' % # YYYYZZ Z Z ZZZ[[[[[[[ ["\~$\|&\z'\x)\v+\t-\r/]p1]n3]l5]j6]h8]f:]d<]b>^`@^^B^\C^ZE^XG^VI^TK^RM_PO_NP_LR_JT_HV_FX_EZ`C[`A]`?_`=a`;c`9e`7f`5ha3ja1la/na-pa+qa)sa'ua%wb#yb!zb|b~bbbbccccc c ccdddca`^\ Z XWUSQONLJHG!E#C$A&@(>*<,:.907253352709.;,=+?)A'B%D$F"H JLNOQSUWY[\ ^ ` bdfgikgd|aq,]e;ZYKVMZSAjO4{K'GC >+,AABCDDEFFGHHIJKKLM M N O O P Q RRSTTUVVWXYYZ\^`bdfhjlnprtvx }z z| x~ u s p n l jgeca^\ZXVTRPNLJHFDB@><:87531/.,*)'%#"   !!!"""##         "$')+.0257:<?ADFILNQTVY \ _ b d g j m p svy}|{xvspnkhfc`]]]]]]]]]]]]]] ] ] ] ] ] ] ]]]]]]]]]]]]]]]]]]]]]]]]]] ] ]!]"]"~]#}]$}]$|]%{]&{]'z]'y](x])x])w]*v]+v]+u]brxgW G 7 (    "$&(*,.13579;>@BDFHKMOQSUXZ\^`cegiknp|rztxvvyt{r}pnkigeca^\ZXVT R O M K I G E B @ > < : 7 5 3 1 / , * ( & $ !WWXXXX X X XXYYYYYYYZ Z"Z$Z~&Z|'Zz)Zx+Zv-[t/[r1[p3[n5[l6[j8[h:[f<\d>\b@\`B\^C\\E\ZG\XI]VK]TM]RO]PP]NR]LT]JV]HX^FZ^D[^B]^@_^>a^(<*:,9.7052342507.9,;+=)?'A%C$D"F HJLNPQSUWY[ \ ^ `bdfgifb~_r,[g;X[KTOZQCjM6{I)EA= +*CDEEFGGHIIJKKLMNNOP P Q R R S T UUVWWXYYZ[[\]_acegikmoqsuwy}{ z| x~ u s p n l j geca^\ZXVTRPNLJHFDB@><:87531/.,*)'%#"    !!"""#         #%'*,.1358:=?BDGJLORTW Z \ _ b e h k n qtwz}}{xvspnkifc`````````````` ` ` ` ` ` ` ``````````````````````````~` }`!}`"|`"{`#{`$z`$y`%y`&x`&w`'v`(v`(u`)t`*t`+s`+r`,r`bryiX H 9 )     "$&(*,.13579;>@BDFHKMOQSUXZ\^`cegiknp~r{tyvwyu{s} q o l j h f d b ` ] [ Y W U S P N L J H F C A ? = ; 9 6 4 2 0 . + ) ' % #UVVVVV V V VWWWWWWWXX X"X$X&X~'X|)Xz+Yx-Yv/Yt1Yr3Yp5Yn6Yl8Zj:ZhZd@ZbBZ`CZ^EZ\G[ZI[XK[VM[TO[RP[PR[NT\LV\JX\HZ\F[\D]\B_\@a\>c]'<(:*9,7.50322406.7,9+;)='?%A$C"E FHJLNPQSUWY [ ] ^`bdfgda]t,Zi;V]KRQZODjK8{G+C?; +(EFGHHIJJKLLMNNOPQQRS S T U U V W WXYZZ[\\]^^_`adfhjlnprtvwy}{z} x u s p n l j g eca^\ZXVTRPNLJHFDB@><:87531/.,*)'%#"    !!!""         !#%(*,/1468;=@BEHJMORU X Z ] ` c f h k nqtwz}}{xvspnkifcccccccccccccc c c c c c c cccccccccccccccccccccc~c}c}c|c{c {c!zc!yc"yc#xc#wc$wc%vc%uc&tc'tc(sc(rc)rc*qc*pc+pc,oc,nc-ncrzjYI : *     "$&(*,.13579;>@BDFHKMOQSUXZ\^` c e g i k n p r |t zv xy v{ t} r p n k i g e c a ^ \ Z X V T R O M K I G E B @ > < : 7 5 3 1 / , * ( & $TTTTTT T U UUUUUUUVVV V"V$V&V'W~)W|+Wz-Wx/Wv1Wt3Wr5Wp6Xn8Xl:XjXf@XdBXbCY`EY^GY\IYZKYXMYVOYTPYRRZPTZNVZLXZJZZH[ZF]ZD_ZBa[@c[>e[%<':)9*7,5.302204.6,8+9);'=%?$A"C EFHJLNPRSUW Y [ ]^`bdeb_[v,Xj;T_KQSZMFjI:{E-A =9 +&HHIJJKLMMNOOPQQRSSTUV V W X X Y Z Z[\\]^^_`aabcdfhjlnprtvxz}|z~x u s p n l j g e ca^\ZXVTRPNLJHFDB@><:87531/.,*)'%#"   !!!"        !$&(+-/2479;>@CFHKMPS U X [ ^ ` c f i lorux{}~{xvsqnkiffffffffffffff f f f f f f ffffffffffffffffff~f~f}f|f{f{fzfyfyf xf wf!wf"vf#uf#uf$tf%sf%sf&rf'qf'pf(pf)of)nf*nf+mf,lf,lf-kf.jfr{k[K; +     "$&(*,.13579;>@B D F H K M O Q S U X Z \ ^ ` c e g i k n p r ~t {v yy w{ u} s q o l j h f d b ` ] [ Y W U S P N L J H F C A ? = ; 9 6 4 2 0 . + ) '%RRRRRR S S SSSSSSTTTT T"T$T&U'U)U~+U|-Uz/Ux1Uu3Us5Vq6Vo8Vm:VkVh@VfBWdCWbEW`GW^IW\KWZMWXOWVPXTRXRTXPVXNXXLZXJ[XH]YF_YDaYBcY@eY>fY#<%:'9)7+5,3.2002.4,6+8):';%=$?"A CEGHJLNPRTU W Y []_`bd`]Zx,Vl;RaKOTZKHjG<{C/?";7+$JKKLMMNOPPQRRSTTUVVWX X Y Z Z [ \ ] ]^__`aabccdeegikmoqsuwy{}|z~xu s p n l j g e c a^\ZXVTRPNLJHFDB@><:87531/.,*)'%#"    !!         "$')+-0257:<>ADFIKNQ S V Y [ ^ a d g jmpsvy|}{xvsqnkihhhhhhhhhhhhh h h h h h h hhhhhhhhhhhhhh~h~h}h|h|h{hzhzhyhxhwhwhvh uh uh!th"sh"sh#rh$qh$qh%ph&oh&oh'nh(mh)mh)lh*kh+jh+jh,ih-hh-hh.gh/fh|l\L< ,     "$ & ( * , . 1 3 5 7 9 ; > @ B D F H K M O Q S U X Z \ ^ ` c e g i k n p r t }v zy x{ v} t r p n k i g e c a _ \ Z X V T R O M K I GEB@><:7531/,*(&PPPPPQ Q Q QQQQRRRRRR R"R$S&S'S)S+S}-S{/Sy1Tw3Tu5Ts6Tq8To:TmTi@UgBUeCUcEUaGU_IU]KU[MVYOVWPVURVSTVRVVPXVNZVL[WJ]WH_WFaWDcWBeW@fW>hX!<#:%9'7)5+3-2.00.2,4+6)8':%;$="? ACEGIJLNPRT U W Y[]_ab_[Xz,Tn;QbKMVZIJjE={A1=$95+"LMNNOPPQRRSTTUVVWXYYZ[ [ \ ] ] ^ _ _ `aabccdeefghhjlnprtvxy{}}zxus p n l j g e c a ^\ZXVTRPNLJHFDB@><:87531/.,*)'%#"    !         #%'),.0358:=?BDGILO Q T W Y \ _ b e gjmpsvy|}{xvsqnkkkkkkkkkkkkkk k k k k k k kkkkkkkkkk~k~k}k|k|k{kzkzkykxkxkwkvkvkuktksksk rk!qk"qk"pk#ok$ok$nk%mk&mk&lk'kk(kk(jk)ik*ik*hk+gk,gk,fk-ek.dk.dk/ck0bkm]M=-              " $ & ( * , . 1 3 5 7 9 ; > @ B D F H K M O Q S U X Z \ ^ ` c e g i k n p r t ~v {y y{ w} u s q o l j h f db`][YWUSPNLJHFCA?=;96420.+)'NNNNOO O O OOOPPPPPPP P"Q$Q&Q'Q)Q+Q-Q}/R{1Ry3Rw5Ru6Rs8Rq:RoSk@SiBSgCSeEScGSaIS_KT]MT[OTYPTWRTUTTSVTQXUOZUM[UK]UI_UHaUFcUDeUBfV@hV>jV<:87531/.,*)'%#"            !#%(*,/1368;=@BEGJ L O R T W Z ] _ b ehknqtwz}}{xvsqnnnnnnnnnnnnnn n n n n n n nnnnnn~n~n}n|n|n{nznznynxnxnwnvnvnuntntnsnrnrnqnpn pn!on!nn"nn#mn#ln$kn%kn%jn&in'in'hn(gn)gn)fn*en+en,dn,cn-cn.bn.an/an0`n0_nn^N>/                " $ & ( * , . 1 3 5 7 9 ; > @ B D F H K M O Q S U X Z \ ^ ` c e g i k n p rtv}yz{x}vtrpnkigeca_\ZXVTROMKIGEB@><:7531/,*(LLLMMM M M MMNNNNNNNO O"O$O&O'O)O+O-P/P}1P{3Py5Pw6Pu8Ps:QqQm@QkBQiCQgEQeGRcIRaKR_MR]OR[PRYRRWTRUVSSXSQZSO[SM]SK_SIaSGcTEeTCfTAhT?jT>lT< :!9#7%5'3)2+0-./,0+2)4'6%8$:"< >?ACEGIKLNP R T VWY[]^[XT},Qr;MfKIZZENjAA{=59'51 +QQRSSTUUVWWXYYZ[[\]^^_`` a b b c d d e ffghhijjkllmnoqsuwy{}}~zxuspn l j g e c a ^ \ Z XVTRPNLJHFDB@><:87531/.,*)'%#"          !$&(*-/2469;>@CEH J M P R U X Z ] ` cfiknqtwz~}{xvsqqqqqqqqqqqqqq q q q q q q qq~q~q}q|q|q{qzqzqyqxqxqwqvqvquqtqtqsqrqrqqqpqpqoqnqnq mq!lq!lq"kq#jq#jq$iq%hq%hq&gq'fq'fq(eq)dq)dq*cq+bq+bq,aq-`q-`q._q/^q/]q0]q1\q1[q_O?0                " $ & ( * , . 1 3 5 7 9 ; > @ B D F H K M O Q S UXZ\^`cegiknprtv~y{{y}wusqomjhfdb`][YWUSPNLJHFCA?=;96420.+)JJKKKK K K KLLLLLLLMM M"M$M&M'M)N+N-N/N1N}3N{5Ny6Nw8Ou:OsOo@OmBOkCOiEPgGPeIPcKPaMP_OP]PP[RPYTQWVQUXQSZQQ[QO]QM_QKaRIcRGeREfRChRAjR?lR=nR;pS9qS8sS6uS4wS2yS0zS.|T,~T*T(T&T$T"T TUUUUUUUVV V V VVVVWUSQO N L JHGECA@><: 9"7#5%3'2)0+.-,/+1)2'4%6$8": <>@ACEGIKMN P R TVXY[]YVR,Ot;KhKG\ZCPj@C{<67)3/+ STTUVVWXXYZZ[\\]^^_``abbc d d e f f g h hijjkllmnnopprtvxy{}}zxuspnlj g e c a ^ \ Z X VTRPNLJHFDB@><:87531/.,*)'%#"          "$&)+-02479<>ACF H K N P S V X [ ^ acfilorux{~}{xvssssssssssssss s s s s s ~s }s}s|s{s{szsysysxswswsvsusustsssrsrsqspspsosnsnsmslslsks js js!is"hs"hs#gs$fs$fs%es&ds&ds'cs(bs(bs)as*`s*`s+_s,^s,^s-]s.\s.\s/[s0Zs0Zs1Ys2Xs2XsP@1!               " $ & ( * , . 1 3 5 79;>@BDFHKMOQSUXZ\^`cegiknprtvy}{z}xvtrpnkigeca_\ZXVTROMKIGEB@><:7531/,*HIIIII I I JJJJJJJKKK K"K$K&K'L)L+L-L/L1L3L}5M{6My8Mw:MuMq@MoBMmCNkENiGNgINeKNcMNaON_PO]RO[TOYVOWXOUZOS[OQ]OO_PMaPKcPIePGfPEhPCjPAlQ?nQ=pQ;qQ9sQ7uQ5wQ3yQ2zR0|R.~R,R*R(R&R$S"S SSSSSSTTTT T T TUUUUSQON L J HGECA@><:9 7"5$3%2'0).+,-+/)1'3%4$6"8 :<>@ACEGIKM N P RTVXZ[WTP,Mu;IjKE^ZBRj>E{:86+1-) UVVWXXYZZ[\\]^^_``abbcddef f g h h i j jkllmnnoppqrrstvxz|~}zxuspnljg e c a ^ \ Z X V TRPNLJHFDB@><:87531/.,*)'%#"          "%'),.0357:<?AD F I L N Q S V Y \^adgjmpsvy|}{xvvvvvvvvvvvvvv v ~v }v }v |v {v {vzvyvyvxvwvwvvvuvuvtvsvsvrvqvqvpvovovnvmvmvlvkvkvjviviv hv gv!gv"fv"ev#ev$dv$cv%cv&bv&av'av(`v(_v)_v*^v*]v+]v,\v,[v-[v.Zv.Yv/Yv0Xv0Wv1Wv2Vv2Uv3UvQA2#           "$&(*,.13579;>@BDFHKMOQSUXZ\^`cegiknprtvy~{|}ywusqomjhfdb`][YWUSPNLJHFCA?=;96420.+GGGGGG G H HHHHHHIIII I"I$I&J'J)J+J-J/J1J3K~5K|6Kz8Kx:KvKr@KpBLnCLlELjGLhILfKLdMLcOMaPM_RM]TM[VMYXMWZMU[NS]NQ_NOaNMcNKeNIfNGhNEjOClOAnO?pO=qO;sO9uO7wP5yP3zP1|P/~P-P,P*P(Q&Q$Q"Q QQQRRRRRRR R S SSSSSQONL J H GECA@><:97 5"3$2&0'.),++-)/'1%3$5"6 8:<>@BCEGIK M O PRTVXYVRO,Kw;GlKD`Z@Sj<:87531/.,*)'%#"          !#%'*,.1368:=?B D G J L O Q T W Y\_begjmpsvy|}{yyyyyyyyyyy~y}y}y |y {y {y zy yy yy xy wywyvyuyuytysysyryqyqypyoyoynymymylykykyjyiyiyhygygyfyey ey!dy!cy"cy#by#by$ay%`y%`y&_y'^y'^y(]y)\y)\y*[y+Zy+Zy,Yy-Xy-Xy.Wy/Vy/Vy0Uy1Ty1Ty2Sy3Ry3Ry4QyB3$  "$&(*,.13579;>@BDFHKMOQSUXZ\^`cegiknprtvy{}}zxvtrpnkigeca_\ZXVTROMKIGEB@><:7531/,EEEEEE F F FFFFFGGGGG G"G$H&H'H)H+H-H/H1I3I5I~6I|8Iz:IxJt@JrBJpCJnEJlGJjIJhKKfMKdOKbPK`RK^TK\VKZXKXZLV[LT]LS_LQaLOcLMeLKfMIhMGjMElMCnMApM?qM=sM;uN9wN7yN5zN3|N1~N/N-O+O)O(O&O$O"O PPPPPPPPQQ Q Q QQQQQONLJ H G ECA@><:975 3"2$0&.(,)++)-'/%1$3"5 78:<>@BDEGI K M OPRTVWTPM,Iy;FmKBbZ>Uj:I{6<2/-")%YZ[[\]]^__`aabccdeeffghhijjk l l m n n o ppqrrsttuvvwxxz{}}zxuspnljgec a ^ \ Z X V T R PNLJHFDB@><:87531/.,*)'%#"         !#&(*-/1469;=@ B E H J M O R U WZ]`behknqtwz}}{{{{{{{~{}{}{|{{{{{z{ y{ y{ x{ w{ w{ v{ v{ u{t{t{s{r{r{q{p{p{o{n{n{m{l{l{k{j{j{i{h{h{g{f{f{e{d{d{c{ b{!b{!a{"`{#`{#_{$^{%^{%]{&\{&\{'[{(Z{(Z{)Y{*X{*X{+W{,W{,V{-U{.U{.T{/S{0S{0R{1Q{2Q{2P{3O{4O{4N{5M{4%  "$&(*,.13579;>@BDFHKMOQSUXZ\^`cegiknprtvy{~}|ywusqomjhfdb`][YWUSQNLJHFCA?=;96420.CCCCDD D D DDDEEEEEEE E"F$F&F'F)F+F-F/G1G3G5G6G~8G|:GzHv@HtBHrCHpEHnGHlIIjKIhMIfOIdPIbRI`TI^VJ\XJZZJX[JV]JT_JRaJPcJNeKLfKJhKIjKGlKEnKCpKAqL?sL=uL;wL9yL7zL5|L3~M1M/M-M+M)M'M%M#N"N NNNNNOOOOO O O OPPPONLJH G E CA@><:9753 2"0$.&,(+*)+'-%/$1"3 578:<>@BDEG I K MOQRTVROK,G{;DoK@cZ01+$'#[\]]^__`aabccdeefgghiijjkllmn n o p p q r rsttuvvwxxyzz{|~}zxuspnljgeca ^ \ Z X V T R P NLJHFDB@><:87531/.,*)'%#"         "$&)+-02479<> @ C F H K M P S UX[]`cfilnqtwz~~~~~~}~}~|~|~{~z~z~y~x~x~ w~ v~ v~ u~ t~ t~ s~ r~r~q~p~p~o~n~n~m~l~l~k~j~j~i~h~h~g~g~f~e~e~d~c~c~b~a~a~ `~ _~!_~"^~"]~#]~$\~$[~%[~&Z~&Y~'Y~(X~(W~)W~*V~*U~+U~,T~,S~-S~.R~.R~/Q~/P~0P~1O~1N~2N~3M~3L~4L~5K~5J~5&  "$&(*,.13579;>@BDFHKMOQSUXZ\^`cegiknprtvy{}}zxvtrpnkigeca_\ZXVTROMKIp~p~q~r~r ~s ~t ~t ~u ~v ~v ~w ~AAABBB B B BBCCCCCCCD D"D$D&D'D)D+D-E/E1E3E5E6E8E~:F|Fx@FvBFtCFrEFpGGnIGlKGjMGhOGfPGdRGbTH`VH^XH\ZHZ[HX]HV_HTaIRcIPeINfILhIJjIHlIFnIDpJBqJAsJ?uJ=wJ;yJ9zJ7|K5~K3K1K/K-K+K)L'L%L#L!LLLLMMMMMMM N NNNNNNLJHG E C A@><:97532 0".$,&+()*',%-$/"1 3579:<>@BDF G I KMOQSTPMI,F};BqK>eZ:Yj6M{2@.3)&%! ] ^__`aabccdeefgghiijkkllmnnopp q r r s t t uvvwxxyzz{{|}}}zxuspnljgeca^ \ Z X V T R P N LJHFDB@><:87531/.,*)'%#"          "%')+.0257: < ? A D F I K N P SVY[^adfilorux{~}||{zzyxxwvvu t t s r r q q poonmmlkkjiihggfeedccbaa``_^ ^ ]!\"\"[#Z$Z$Y%X%X&W'V'V(U)T)T*S+R+R,Q-Q-P.O/O/N0M1M1L2K3K3J4I4I5H6G6G'   "$&(*,.13579;>@BDFHKMOQSUXZ\^`cegiknprtvy{}~|ywusqomjhfghiijkklmmnoop q q r s s t t uvvw??@@@@ @ @ @AAAAAAABB B"B$B&B'B)C+C-C/C1C3C5C6D8D:D~Dz@DxBDvCDtEErGEpIEnKElMEjOEhPEfRFdTFbVF`XF^ZF\[FZ]FX_GVaGTcGReGPfGNhGLjGJlHHnHFpHDqHBsH@uH>wH<:975320 .",$+&)('*%,$."/ 13579;<>@BD F H IKMOQROKG,D;@sK<:87531/.,*)'%#"          !#%'*,.1358 : = ? B D G I L N QTVY\_adgjmpsvy{zzyxxwvvuutss r q q p o o n mmlkkjiihhgffeddcbba``_^^]\\[ [!Z!Y"Y#X#W$W%V%U&U'T'S(S)R)Q*Q*P+P,O,N-N.M.L/L0K0J1J2I2H3H4G4F5F6E6D7D7C   "$&(*,.13579;>@BDFHKMOQSUXZ\^`cegiknprtvy{}``abbcddeffghhiijkklmm n o o p q q r sstuuvvw=>>>>> > > ???????@@@ @"@$@&@'A)A+A-A/A1A3A5B6B8B:BB|@BzBCxCCvECtGCrICpKCnMClODjPDhRDfTDdVDbXD`ZD^[D\]EZ_EXaEVcETeERfEPhENjFLlFJnFHpFFqFDsFBuF@wG>yG<:975320.!,"+$)&'(%*$,". /13579;=>@B D F HIKMOPMIF,B;>uK:iZ6]j2Q{.D*7&*! b{!b{ c{ c{d{e{e{f{g{g{h{i{i{j{k{k{l{m{m{n{n{o{p{p{q{r{r{s{t{t{u{ v{ v{ w{ x{ x{ y{ y{ z{{{{{|{}{}{~{{{{{{{{zxuspnljgeca^\Z X V T R P N L J H FDB@><:87531/.,*)'%#"         !#&(*,/146 8 ; = @ B E G J L ORTWZ\_behjmpsvyxwwvuutssrqqp o o n n m l l kjjihhgffeddccbaa`__^]]\[[ZZY X!X!W"V#V#U$T$T%S&R&R'Q(P(P)O*O*N+M,M,L-K.K.J/I/I0H1G1G2F3E3E4D5D5C6B7B7A8@   "$&(*,.13579;>@BDFHKMOQSUXZ\^`X!X YYZ[[\]]^__`aabccddeffghhijjk l l m m n o o pqqrsstuuvww<<<<<< < = ======>>>> >">$>&?'?)?+?-?/?1?3@5@6@8@:@<@>@}@A{BAyCAwEAuGAsIAqKAoMBmOBkPBiRBgTBeVBcXBaZC`[C^]C\_CZaCXcCVeCTfDRhDPjDNlDLnDJpDHqDFsDDuEBwE@yE>zE<|E:~E8E6F4F2F0F/F-F+F)G'G%G#G!GGGHHHHHHHH I IIIIIHGECA @ ><:975320.,!+")$'&%($*", .013579;=>@ B D FHJKMOKHD,@;<:87531/.,*)'%#"        "$&(+-/24 6 9 ; > @ C E H J MPRUXZ]`cehknqtvuutssrrqpponn m l l k j j i ihggfeedccbaa``_^^]\\[ZZYXXWW V U!U"T"S#S$R$Q%Q&P&O'O(N(N)M)L*L+K+J,J-I-H.H/G/F0F1E1E2D2C3C4B4A5A6@6?7?8>8=9=   "$&(*,.13579;>@BDO&P&Q%Q$R$S#S"T"U!U!V VWXXYZZ[\\]^^__`aabccdeefgghh i j j k l l m nnoppqqrsstuuvvv:::::: ; ; ;;;;;<<<<< <"<$=&='=)=+=-=/=1>3>5>6>8>:><>>?@?}B?{C?yE?wG?uI?sK@qM@oO@mP@kR@iT@gV@eXAcZAa[A_]A]_A[aAYcAWeBUfBThBRjBPlBNnBLpBJqCHsCFuCDwCByC@zC>|C<~D:D8D6D4D2D0D.D,E+E)E'E%E#E!EFFFFFFFGGG G GGGGHGECA@ > <:975320.,+!)#'$%&$("* ,.023579;=? @ B DFHJLMIFB,>;:xK7mZ3aj.T{*H&;".  fv"fv!gv gv hvivivjvkvkvlvmvmvnvnvovpvpvqvrvrvsvtvtvuvvvvvwvwvxvyvyvzv {v {v |v }v }v ~v ~v vvvvvvvvvvvvvvuspnljgeca^\ZXV T R P N L J H F D B@><:87531/.,*)'%#"          "$')+.02 5 7 9 < > A C F H KNPSUX[^`cfilortsrrqpponnmmlk k j i i h g g ffeddcbba``_^^]]\[[ZYYXWWVVUT T S!R"R"Q#P#P$O%N%N&M'M'L(K)K)J*I+I+H,G,G-F.F.E/D0D0C1B2B2A3@3@4?5>5>6=7=7<8;9;9::9  "$&(G,H+I+I*J)K)K(L'L'M&N&N%O$P$P#Q"R"R!S S TUUVWWXYYZZ[\\]^^_``abbccdeef g g h i i j j kllmnnoppqrrsstttttt888889 9 9 9999:::::: :";$;&;';);+;-=@=B=}C={E=yG>wI>uK>sM>qO>oP>mR>kT?iV?gX?eZ?c[?a]?__?]a?[c@Ye@Wf@Uh@Sj@Ql@On@MpAKqAJsAHuAFwADyABzA@|B>~B < :975320.,+)!'#%%$&"( *,.024579;= ? A BDFHJKHD@,<;9zK5oZ1cj-V{(J$= 0"ht"ht"it!it jt ktktltmtmtntototptptqtrtrtstttttutvtvtwtwtxtytytzt{t{t|t}t }t ~t ~t t t t t ttttttttttttttspnljgeca^\ZXVTR P N L J H F D B @><:87531/.,*)'%#"         !#%'),.0 3 5 8 : < ? A D FIKNQSVY[^adgiloqqpoonmmlkkjji h h g f f e d dccbaa`__^]]\\[ZZYXXWVVUUTSSRQ Q!P!O"O#N#N$M%L%L&K&J'J(I(H)H*G*G+F,E,E-D.C.C/B/A0A1@1@2?3>3>4=5<5<6;6:7:898998:7:7 ?2@1A0A0B/C.C.D-D,E,F+F+G*H)H)I(J'J'K&K%L%M$M#N#O"O"P!Q Q RRSTTUVVWXXYYZ[[\]]^__``abbcd d e f f g g h iijkklmmnnoppqqqqqqqqqqq666677 7 7 7778888889 9"9$9&9'9)9+:-:/:1:3:5:6:8;:;<;>;@;B;C;}E<{G_a>]c>[e>Yf>Wh>Uj>Sl?Qn?Op?Mq?Ks?Iu?Gw?Ey@Dz@B|@@~@>@<@:@8@6A4A2A0A.A,A*A(B&B$B#B!BBBCCCCCCC D D DDDDDCA@>< : 975320.,+)'!%#$%"' (*,.024679; = ? ABDFHIFB>,;;7|K3pZ/dj+X{&L"?2$iq#jq"kq!kq!lq mq mqnqoqoqpqpqqqrqrqsqtqtququqvqwqwqxqyqyqzq{q{q|q|q}q~q~qq q q q q q q q qqqqqqqqqqqqqqpnljgeca^\ZXVTRP N L J H F D B @ ><:87531/.,*)'%#"        !#%(*,/ 1 3 6 8 ; = ? B DGILOQTWY\_bdgjmonmmllkjjihhgg f e e d c c b aa``_^^]\\[ZZYYXWWVUUTTSRRQPPO N!N!M"M#L#K$K$J%I&I&H'G(G(F)F)E*D+D+C,B-B-A.A/@/?0?0>1=2=2<3;4;4:5:69687877869695:4;4;3<3<2=1>1>0?/@/@.A.B-B,C,C+D*E*E)F(G(G'H'I&I%J%J$K#L#L"M!N!N O OPQQRSSTUUVVWXXYZZ[\\]]^__`aa b b c d d e f fghhiijkklmmnooooooooooooooo444555 5 5 5666666677 7"7$7&7'7)8+8-8/81838586989:9<9>9@9B9C:E:}G:{I:yK:wM:uO:sP;qR;oT;mV;kX;iZ;g[;e]Gy>Ez>C|>A~>?>=>< : 9 75320.,+)'%!$#"% ')*,.024679 ; = ?ACDFHD@=,9;5~K1rZ-fj)Z{$N A4& ko#lo#mo"mo!no!oo oopopoqororosototououovowowoxoyoyozo{o{o|o|o}o~o~oooooo o o o o o o o oooooooooooooonljgeca^\ZXVTRPN L J H F D B @ > <:87531/.,*)'%#"       "$&(+ - / 2 4 6 9 ; > @ BEGJMORTWZ]_behkllkjjiihggfeed d c b b a ` ` _^^]]\[[ZYYXXWVVUTTSSRQQPOONMM L L!K"J"J#I$H$H%G&G&F'E'E(D)C)C*B+B+A,@,@-?.>.>/=0<0<1;1;2:3939485757667675848493:2:2;1<0<0=/=/>.?-?-@,A+A+B*B*C)D(D(E'F&F&G%H%H$I#I#J"K!K!L MMNNOPPQRRSTTUUVWWXYYZZ[\\]^^_ _ ` a a b c c deeffghhijjkklmmmmmmmmmmmmmmm m m m223333 3 3 4444444555 5"5$5&5'6)6+6-6/61636576787:7<7>7@7B8C8E8~G8|I8zK8xM8vO9tP9rR9qT9oV9mX9kZ9i[:g]:e_:ca:ac:_e:]f:[h;Yj;Wl;Un;Sp;Qq;Os;Mu0>.>,>*>(>&>$?"? ?????@@@@@ @ @ AAAAA@><: 9 7 5320.,+)'%$!"# %')+,.02468 9 ; =?ACEFB?;,7;3K/tZ+hj'\{#OC6( mm$nm#om"om"pm!pm!qm rmrmsmtmtmumumvmwmwmxmymymzmzm{m|m|m}m~m~mmmmmmmmmm m m m m m m m mmmmmmmmmmmmmmljgeca^\ZXVTRPNL J H F D B @ > < : 87531/.,*)'%#"        "$') + - 0 2 4 7 9 < > ACFHKMPRUXZ]`cfhjiihggffeddcbba a ` _ _ ^ ] ]\\[ZZYXXWWVUUTSSRRQPPONNMMLKK J I!I"H"H#G#F$F%E%D&D'C'B(B(A)A*@*?+?,>,=-=-<.,>+?+@*@)A)B(B(C'C&D&E%E$F$G#G#H"H!I!J JKLLMMNOOPQQRRSTTUVVWXXYYZ[[\] ] ^ ^ _ ` ` a bbccdeefgghhijjjjjjjjjjjjjjjj j j j j j j j011111 1 2 2222223333 3"3$3&4'4)4+4-4/41435556585:5<5>6@6B6C6E6G6~I6|K7zM7xO7vP7tR7rT7pV7nX8lZ8j[8h]8f_8da8bc8`e9_f9]h9[j9Yl9Wn9Up9Sq:Qs:Ou:Mw:Ky:Iz:G|:E~;C;A;?;=;;;9;7<5<3<2<0<.<,<*=(=&=$="= ===>>>>>>> ? ? ?????><:9 7 5 320.,+)'%$"! #%')+-.0246 8 : ;=?ACDA=9,5;1K-vZ)jj%^{!QE8* oj$pj#pj#qj"rj"rj!sj tj tjujujvjwjwjxjyjyjzjzj{j|j|j}j~j~jjjjjjjjjjjjjj j j j j j j j jjjjjjjjjjjjjjjgeca^\ZXVTRPNLJ H F D B @ > < : 8 7531/.,*)'%#"        #%' ) , . 0 3 5 7 : < ?ADFIKNPSVX[^acfhgffeedccbaa``_ ^ ^ ] \ \ [ [ ZYYXWWVVUTTSRRQQPOONMMLLKJJIH H G!G!F"E#E#D$C%C%B&B&A'@(@(?)>*>*=+=+<,;-;-:.9/9/808071626253544435352617170809/9.:.:-;,<,<+=+=*>)?)?(@'A'A&B&B%C$D$D#E"F"F!G!G HIIJKKLLMNNOPPQQRSSTUUVVWXXYZZ [ [ \ ] ] ^ _ _``abbcddeefgghhhhhhhhhhhhhhh h h h h h h h hhhh////// 0 0 0000011111 1"1$2&2'2)2+2-2/31333536383:3<4>4@4B4C4E4G4I5~K5|M5zO5xP5vR5tT5rV6pX6nZ6l[6j]6h_6fa6dc7be7`f7^h7\j7Zl7Xn7Vp8Tq8Ss8Qu8Ow8My8Kz8I|9G~9E9C9A9?9=9;:9:7:5:3:1:/:.;,;*;(;&;$;"; <<<<<<<=== = = ==>>><:97 5 3 20.,+)'%$" !#%')+-.024 6 8 :;=?AB?;7,3;/K+xZ'lj#`{SG:, qh%rh$rh#sh#th"th!uh!uh vh whwhxhyhyhzhzh{h|h|h}h}h~hhhhhhhhhhhhhhhhhh h h h h h h h hhhhhhhhhhhhhhgeca^\ZXVTRPNLJH F D B @ > < : 8 7 531/.,*)'%#"      !#% ( * , . 1 3 5 8 : =?BDGILNQTVY\^adeedccbba``__^]] \ [ [ Z Z Y X XWVVUUTSSRQQPPONNMMLKKJIIHHGFF E!D!D"C#C#B$A$A%@&?&?'>'>(=)<)<*;+;+:,9,9-8.7.7/6060514142332324151506/6/7.8-8-9,9,:+;*;*<)=)=(>'>'?&@%@%A$B$B#C"C"D!E E FGGHHIJJKKLMMNOOPPQRRSTTUUVWWX Y Y Z Z [ \ \ ]]^__`aabbcddefffffffffffffff f f f f f f f ffffffff-----. . . ....////// /"0$0&0'0)0+0-1/11131516181:2<2>2@2B2C2E2G3I3K3~M3|O3zP3xR3vT4tV4rX4pZ4n[4l]4j_4ha5fc5de5bf5`h5^j5\l6Zn6Xp6Vq6Ts6Ru6Pw6Ny7Lz7K|7I~7G7E7C7A8?8=8;89878583919/9-9+9*9(9&:$:": :::::;;;;; ; ; <<<<<:975 3 2 0.,+)'%$" "#%')+-/02 4 6 8:<=?A=95,2;.K*zZ%nj!b{UI;. !sf%tf$tf$uf#uf#vf"wf!wf!xf xfyfzfzf{f|f|f}f}f~ffffffffffffffffffffff f f f f f f f ffffffffffffffeca^\ZXVTRPNLJHF D B @ > < : 8 7 5 31/.,*)'%#"     !$ & ( * - / 1 4 6 8 ;=@BEGJLORTWY\_bcbbaa`__^^]\\[Z Z Y Y X W W V UUTTSRRQQPOONMMLLKJJIHHGGFEEDD C!B!B"A"@#@$?$?%>%=&='<'<(;):):*9*8+8,7,7-6-5.5/4/30312122120304/4/5.6-6-7,7+8+9*9*:):(;(<'<'=&>%>%?$?#@#A"A"B!B C DDEFFGGHIIJKKLLMNNOOPQQRSSTTUV V W W X Y Y Z [[\\]^^_``aabcccccccccccccccc c c c c c c c cccccccccccc++++,, , , ,,,------. .".$.&.'.).+/-///1/3/5/6/80:0<0>0@0B0C0E1G1I1K1M1~O1|P2zR2xT2vV2tX2rZ2p[2n]3l_3ja3hc3fe3df3bh3`j4^l4\n4Zp4Xq4Vs4Tu4Rw5Py5Nz5L|5J~5H5F5E6C6A6?6=6;69677573717/7-7+7)8'8&8$8"8 889999999: : : :::::9753 2 0 .,+)'%$"  "$%')+-/1 2 4 68:<>?;74,0;,K(|Z#pjd{WJ= 0#tc&uc%uc%vc$wc$wc#xc"xc"yc!zc!zc {c|c|c}c}c~ccccccccccccccccccccccccc c c c c c c c c ccccccccccccccca^\ZXVTRPNLJHFD B @ > < : 8 7 5 3 1/.,*)'%#"      " $ & ) + - 0 2 4 7 9;>@CEHJMORUWZ]`a``_^^]\\[[ZYYX X W V V U T T SSRQQPPONNMMLKKJIIHHGFFEEDCCBA A @!@"?">#>#=$=%<%;&;':'9(9(8)8*7*6+6+5,5-4-3.3.2/10100102/2.3.3-4-5,5+6+6*7)8)8(9(:':&;&;%<%=$=#>#>"?!@!@ A BBCCDEEFFGHHIJJKKLMMNNOPPQRRSS T U U V V W X XYZZ[[\]]^^_``aaaaaaaaaaaaaaa a a a a a a a a aaaaaaaaaaaaaaa)))*** * * **++++++,, ,",$,&,',)-+---/-1-3-5-6.8.:.<.>.@.B/C/E/G/I/K/M/O0~P0|R0zT0xV0vX0tZ0r[1p]1n_1la1jc1he1ff1dh2bj2`l2^n2\p2Zq2Xs2Vu3Tw3Ry3Pz3N|3L~3J4H4F4D4B4@4?4=5;59575553515/6-6+6)6'6%6#6"7 7777778888 8 8 889997532 0 . ,+)'%$"  "$%')+-/ 1 3 468:<=962,.;*K&}Z"rje{YL? 2%va&wa&wa%xa%xa$ya#za#za"{a"{a!|a }a }a~aaaaaaaaaaaaaaaaaaaaaaaaaaaaa a a a a a a a a aaaaaaaaaaaaaaa^\ZXVTRPNLJHFDB @ > < : 8 7 5 3 1 /.,*)'%#"      " % ' ) + . 0 2 5 7:<>ACFHKMPSUX[]_^]]\[[ZZYXXWWV U U T T S R R QPPOONMMLLKJJIIHGGFEEDDCBBAA@? ? >!>!="<#<#;$:$:%9&9&8'7(7(6)6)5*4+4+3,2,2-1.1.0//0/0.1.1-2,3,3+4+4*5)6)6(7'7'8&9&9%:$;$;#<#<"=!>!> ? ?@AABBCDDEFFGGHIIJJKLLMMNOOPQQ R R S T T U U VWWXYYZZ[\\]]^________________ _ _ _ _ _ _ _ ___________________''(((( ( ( ())))))*** *"*$*&*'+)+++-+/+1+3,5,6,8,:,<,>,@-B-C-E-G-I-K-M.O.P.}R.{T.yV.wX.uZ/s[/q]/o_/ma/kc/je0hf0fh0dj0bl0`n0^p0\q1Zs1Xu1Vw1Ty1Rz1P|1N~2L2J2H2F2D2B2@3>3<3:39373533414/4-4+4)4'4%5#5!55555666666 6 7 777775320 . , +)'%$"  "$&')+- / 1 3468:;840,,;(K$Z sjg{[NA 4'w_(x_'x_&y_&z_%z_${_${_#|_#}_"}_!~_!~_ _ ______________________________ _ _ _ _ _ _ _ _______________^\ZXVTRPNLJHFDB@ > < : 8 7 5 3 1 / .,*)'%#"      ! # % ' * , . 1 3 58:<?ADFIKNQSVY[\\[ZZYYXWWVVUTT S S R Q Q P P ONNMLLKKJIIHHGFFEEDCCBBA@@?>>== ??@@ABBCCDEEFFGHHIIJKKLMMNNO P P Q Q R S S TTUVVWWXYYZ[[\\]]]]]]]]]]]]]]] ] ] ] ] ] ] ] ]]]]]]]]]]]]]]]]]]]]]]]%&&&&& & & ''''''(((( ("($(&)')))+)-)/)1*3*5*6*8*:*<*>+@+B+C+E+G+I+K,M,O,P,R,}T,{V-yX-wZ-u[-s]-q_-oa-mc.ke.if.gh.ej.cl.an._p/^q/\s/Zu/Xw/Vy/Tz/R|0P~0N0L0J0H0F0D1B1@1>1<1:18262523212/2-2+3)3'3%3#3!33444444455 5 555565320. , + )'%$"  "$&()+ - / 13568:62.,*;&K"Zuji{]P C6)y](z]'z]'{]&{]&|]%}]$}]$~]#~]#]"]!]!] ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] ] ] ] ] ] ] ] ]]]]]]]]]]]]]]]\ZXVTRPNLJHFDB@> < : 8 7 5 3 1 / . , *)'%#"       ! $ & ( * - / 1368;=?BDGILOQTVYZZYXXWVVUUTSSRR Q P P O O N M MLLKJJIIHGGFFEDDCBBAA@??>>=<<;; :!9!9"8"8#7$6$6%5%5&4'3'3(2(2)1*0*0+/+.,.----.,.+/+0*0*1)2(2(3'3'4&5%5%6$6$7#8"8"9!9!: ;;<<=>>??@AABBCDDEFFGGHIIJJKLLM M N O O P P Q RRSSTUUVVWXXYZZZZZZZZZZZZZZZZZ Z Z Z Z Z Z Z ZZZZZZZZZZZZZZZZZZZZZZZZZZZ$$$$$$ $ % %%%%%&&&&& &"&$'&''')'+'-'/(1(3(5(6(8(:(<)>)@)B)C)E)G*I*K*M*O*P*R*T+}V+{X+yZ+w[+u]+s_+qa,oc,me,kf,ih,gj,el,cn-ap-_q-]s-[u-Yw-Wy.Uz.T|.R~.P.N.L.J/H/F/D/B/@/>/<0:08060402000/1-1+1)1'1%1#1!22222223333 3 33444320., + ) '%$"  "$&(* + - /1357840,,(;$K Zwjk{_R E8+{Z({Z(|Z'}Z'}Z&~Z%~Z%Z$Z$Z#Z"Z"Z!Z!Z ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ Z Z Z Z Z Z Z ZZZZZZZZZZZZZZZZXVTRPNLJHFDB@><: 8 7 5 3 1 / . , * )'%#"        " $ & ) + - /2469;>@BEGJMORTWXWWVVUTTSSRQQPO O N N M L L K KJIIHHGFFEEDCCBBA@@??>==<<;::99 8 7!7"6"6#5#4$4%3%3&2&1'1(0(0)/).*.+-+-,,,+-+.*.)/)/(0(1'1&2&2%3%4$4#5#6"6"7!7 8 99::;<<==>??@@ABBCCDEEFFGHHIIJK K L L M N N O OPQQRRSTTUUVWWXXXXXXXXXXXXXXXX X X X X X X X XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"""""" # # ####$$$$$$ $"%$%&%'%)%+%-&/&1&3&5&6&8&:'<'>'@'B'C'E(G(I(K(M(O(P(R)T)V)}X){Z)y[)w])u_*sa*qc*oe*mf*kh*ij+gl+en+cp+aq+_s+]u+[w,Yy,Wz,U|,S~,Q,O,M-L-J-H-F-D-B-@.>.<.:.8.6.4/2/0/./,/+/)/'0%0#0!00001111111 2 2222220.,+ ) '%$"  "$&( * , -/13562/+,';#KZyjm{a TG:|X)|X)}X(~X(~X'X&X&X%X%X$X#X#X"X"X!X X XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX X X X X X X X XXXXXXXXXXXXXXXXVTRPNLJHFDB@><:8 7 5 3 1 / . , * ) '%#"         " % ' ) + .02579<>ACFHKMPRUVUUTSSRRQPPOONM M L L K J J I IHGGFFEDDCCBAA@@?>>==<;;::98877 6 5!5!4"4#3#2$2$1%1&0&/'/'.(.)-),*,*+++,*,)-)-(.(/'/&0&0%1%2$2#3#3"4"5!5 6 678899:;;<<=>>??@AABBCDDEEFGGHH I J J K K L M MNNOPPQQRSSTTUVVVVVVVVVVVVVVVV V V V V V V V V VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV V V!V    ! ! ! !!!""""""# #"#$#&#'#)#+$-$/$1$3$5$6%8%:%<%>%@%B%C&E&G&I&K&M&O&P'R'T'V'X'}Z'{[(y](w_(ua(sc(qe(of(mh)kj)il)gn)ep)cq)as)_u*]w*[y*Yz*W|*U~*S+Q+O+M+K+I+G+F,D,B,@,>,<,:,8-6-4-2-0-.-,-*.(.'.%.#.!..///////00 0 000010.,+) ' %$"  "$& ( * ,-/1341-),%;!KZ{jo{c VI<~V*~V)V)V(V'V'V&V&V%V$V$V#V#V"V!V!V V VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV V V V V V V V VVVVVVVVVVVVVVVVTRPNLJHFDB@><:87 5 3 1 / . , * ) ' %#"         ! # % ' * ,.0357:<?ADFIKNPSTSRRQQPOONNMLLK K J I I H H G FFEEDDCBBAA@??>>=<<;;:998876655 4 3!3!2"2"1#0$0$/%/%.&-'-',(,(+)****)+)+(,'-'-&.&.%/$0$0#1#1"2!3!3 4 456677899::;<<==>??@@ABBCCDEEFF G H H I I J K KLLMNNOOPQQRRSSTTTTTTTTTTTTTTT T T T T T T T T TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT T T!T!T"T#T#T         !! !"!$!&!'!)"+"-"/"1"3"5#6#8#:#<#>#@#B$C$E$G$I$K$M%O%P%R%T%V%X%~Z&|[&z]&y_&wa&uc&se&qf'oh'mj'kl'in'gp'eq(cs(au(_w(]y([z(Y|(W~)U)S)Q)O)M)K)I*G*E*C*A*@*>+<+:+8+6+4+2+0,.,,,*,(,&,%,#-!------..... . .////.,+)' % $" !"$ & ( *,./13/+',#;KZ}jq{ e XKT+T*T*T)T(T(T'T'T&T%T%T$T$T#T"T"T!T!T T TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT T T T T T T T TTTTTTTTTTTTTTTTRPNLJHFDB@><:875 3 1 / . , * ) ' % #"           ! # & ( *,/1368:=?BDGILNQRQPPOONMMLLKJJI I H G G F F E DDCCBAA@@?>>==<<;::9987766544332 1!1!0"0"/#.$.$-%-%,&+'+'*(*())()(*'+'+&,&,%-$.$.#/#/"0!1!1 2 234455677889::;;<==>>??@AABBCDD E E F G G H H IJJKKLMMNNOPPQQRRRRRRRRRRRRRRRR R R R R R R R RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR R!R!R"R"R#R$R$R%R%R    "$&' ) + - / 1 3!5!6!8!:!!@"B"C"E"G"I"K#M#O#P#R#T#V#X$Z$~[$|]$z_$xa$vc%te%rf%ph%nj%ll%jn%hp&gq&es&cu&aw&_y&]z&[|'Y~'W'U'S'Q'O(M(K(I(G(E(C(A)?)=)<):)8)6)4*2*0*.*,***(*&+$+"+!+++,,,,,,, - - -----,+)'% $ " !# $ & (*,.01-)%,!;KZjs{ gZMR+R+R*R)R)R(R(R'R&R&R%R%R$R$R#R"R"R!R!R RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR R R R R R R R RRRRRRRRRRRRRRRRPNLJHFDB@><:8753 1 / . , * ) ' % # "             " $ & (+-/2469;=@BEGJLOOONNMLLKKJIIHHG G F E E D D C B BAA@??>>=<<;;::9887765544322110 / /!."."-#,#,$+%+%*&*&)'((((')')&*%*%+$,$,#-"-".!/!/ 00122334556678899::;<<==>??@@ABB C C D E E F F GGHIIJJKLLMMNOOPPPPPPPPPPPPPPPP P P P P P P P PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP P P!P"P"P#P#P$P%P%P&P&P'P(P    "$&')+-/13568:<> @ B C E G I!K!M!O!P!R!T!V"X"Z"["~]"|_"za#xc#ve#tf#rh#pj#nl#ln$jp$hq$fs$du$bw$`y%^z%]|%[~%Y%W%U%S&Q&O&M&K&I&G&E'C'A'?'=';'9(7(6(4(2(0(.(,)*)()&)$)") )*******++ + + +++,,+)'%$ " ! # % &(*,./+'#,;KZju{ h\OP,P+P*P*P)P)P(P'P'P&P&P%P%P$P#P#P"P"P!P P PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP P P P P P P P PPPPPPPPPPPPPPPPNLJHFDB@><:87531 / . , * ) ' % # "              " $ ')+-02479;>@CEHJMMMLLKJJIIHGGFFE D D C C B B A @ @??>==<<;::99887665543322100//. . -!,!,"+#+#*$)$)%(&(&''&'&(%)%)$*#*#+"+",!-!- ../00112334455677889::;;<==>>?@@ A A B B C D D EEFGGHHIJJKKLLMNNNNNNNNNNNNNNNN N N N N N N N N NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN N N!N!N"N#N#N$N$N%N&N&N'N'N(N(N)N*N    "$&')+-/13568:<>@BCEGIKMOPR T V X Z [ ] ~_!|a!zc!xe!vf!th!rj"pl"nn"lp"jq"hs"fu"dw#by#`z#^|#\~#Z#X#V$U$S$Q$O$M$K%I%G%E%C%A%?%=&;&9&7&5&3&2&0'.','*'('&'$("( ((((())))) ) ) *****)'%$ "  ! # %&(*,-*&",;KZj w{j^N-N,N+N+N*N*N)N(N(N'N'N&N&N%N$N$N#N#N"N!N!N N NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN N N N N N N N NNNNNNNNNNNNNNNNLJHFDB@><:87531/ . , * ) ' % # "                ! # %'),.0357:<>ACFHKKKJJIHHGGFEEDDC B B A A @ @ ? > >==<;;::98877665443321100//.--, , +!*!*")")#($'$'%&%&&%'%'$(#(#)"*"*!+ + ,,-..//01122334556678899:;;<<==> ? ? @ @ A B B CCDEEFFGGHIIJJKLLLLLLLLLLLLLLLL L L L L L L L L LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL L!L!L"L"L#L$L$L%L%L&L&L'L(L(L)L)L*L+L+L,L    "$&')+-/13568:<>@BCEGIKMOPRTVXZ[]_~a|czexfvh tj rl pn np lq js hu!fw!dy!bz!`|!^~!\"Z"X"V"T"R"P"N#M#K#I#G#E#C$A$?$=$;$9$7$5%3%1%/%.%,%*%(&&&$&"& &&&''''''( ( ( (((()'%$"    ! #%'(*,($ ,;KZj y{l`L-L,L,L+L+L*L)L)L(L(L'L'L&L%L%L$L$L#L"L"L!L!L L LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL L L L L L L L L LLLLLLLLLLLLLLLLJHFDB@><:87531/. , * ) ' % # "                 ! #&(*,/1358:=?ADFIIIHGGFFEEDCCBBA @ @ ? ? > > = < <;;:998877655443221100/..--,++** )!)!("'"'#&$&$%%$%$&#&#'"("(!) ) *++,,--.//00122334456677899::;;< = = > > ? @ @ AABBCDDEEFGGHHIIJJJJJJJJJJJJJJJ J J J J J J J J JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ J J!J"J"J#J#J$J$J%J&J&J'J'J(J)J)J*J*J+J+J,J-J-J.J    "$&')+-/13568:<>@BCEGIKMOPRTVXZ[]_a~c|ezfxhvjtlrnppnqlsjuhwfydzb|`~ ^ \ Z X V T!R!P!N!L!J!H!G"E"C"A"?"=";"9#7#5#3#1#/#-$+$*$($&$$$"$ %%%%%%%&&& & & &&'''%$"      !#%')*&",;KZ jz{nJ.J-J-J,J,J+J*J*J)J)J(J(J'J&J&J%J%J$J#J#J"J"J!J!J JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ J J J J J J J J JJJJJJJJJJJJJJJJHFDB@><:87531/., * ) ' % # "                  "$&(*-/1468;=@BDGGGFEEDDCCBAA@@? > > = = < < ; : :99887665543322110//..-,,++**)(( ' '!&"%"%#$#$$#%#%"&!&!' ' ())**++,--../001122344556778899: ; ; < < = > > ??@@ABBCCDDEFFGGHHHHHHHHHHHHHHH H H H H H H H H HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH H H!H!H"H#H#H$H$H%H%H&H'H'H(H(H)H)H*H+H+H,H,H-H-H.H/H/H0H    "$&')+-/13568:<>@BCEGIKMOPRTVXZ[]_ac}e{fyhwjulsnrppqnslujwhyfzd|b~`^\ZXVTRPNLJ H F D C A ?!=!;!9!7!5!3!1"/"-"+")"'"&"$#"# ####$$$$$$ $ % %%%%%$"       !#%'($ ,;KZ j|{pH.H.H-H-H,H+H+H*H*H)H)H(H'H'H&H&H%H$H$H#H#H"H"H!H H HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH H H H H H H H H HHHHHHHHHHHHHHHHFDB@><:87531/.,* ) ' % # "                 "$')+-02479;>@CEEEDCCBBAA@??>>= = < ; ; : : 9 8 877665443322100//.--,,++*))((''& % %!$!$"##"#"$!$!% & &''(()**++,,-..//011223345566778 9 9 : : ; ; < ==>>?@@AABBCDDEEFFFFFFFFFFFFFFFF F F F F F F F FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF F!F!F"F"F#F#F$F%F%F&F&F'F'F(F)F)F*F*F+F+F,F-F-F.F.F/F0F0F1F1F2F    "$&')+-/13568:<>@BCEGIKMOPRTVXZ[]_ace}f{hyjwlunspqqosmukwiygzf|d~b`^\ZXVTRPNLJHFDB@>=;97 5 3 1 / - + )!'!%!$!"! !!""""""## # # ###$$"       !#%&",;KZ j~{rF/F.F.F-F,F,F+F+F*F)F)F(F(F'F'F&F%F%F$F$F#F#F"F!F!F F FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF F F F F F F F F FFFFFFFFFFFFFFFFDB@><:87531/.,*)' % # "                  !#%'),.02579<>ACCCBAA@@??>==<<; ; : 9 9 8 8 7 7 655443321100/..--,,+**))(('&&%%$ $ #!"!""!"!# $ $%%&''(())*++,,--.//001123344556 7 7 8 8 9 : : ;;<<=>>??@@ABBCCDDDDDDDDDDDDDDDD D D D D D D D D DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD D D!D"D"D#D#D$D$D%D&D&D'D'D(D(D)D*D*D+D+D,D,D-D.D.D/D/D0D0D1D2D2D3D3D4D    "$&')+-/13568:<>@BCEGIKMOPRTVXZ[]_acef}h{jylwnupsqqsoumwkyizg|e~ca_]\ZXVTRPNLJHFDB@><:97531/-+)'%#!      !!!! ! ! !""""        !#%!,;K Zj{D0D/D.D.D-D-D,D,D+D*D*D)D)D(D(D'D&D&D%D%D$D$D#D"D"D!D!D D DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD D D D D D D D D DDDDDDDDDDDDDDDDB@><:87531/.,*)'% # "                   !#%(*,.1358:<?AAA@@?>>==<;;::9 9 8 7 7 6 6 5 5 43322110//..--,++**))(''&&%%$##"" !!!! ""##$%%&&''())**+,,--../001122344 5 5 6 6 7 8 8 99::;<<==>>?@@AABBBBBBBBBBBBBBBB B B B B B B B B BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB B B!B!B"B"B#B$B$B%B%B&B&B'B(B(B)B)B*B*B+B,B,B-B-B.B.B/B0B0B1B1B2B2B3B4B4B5B5B6B     "$&')+-/13568:<>@BCEGIKMOPRTVXZ[]_acefh}j{lynwpuqssquowmykzi|g~eca_][YWUTRPNLJHFDB@><:86531/-+)'%#!            "#,;K Zj{B0B/B/B.B.B-B-B,B+B+B*B*B)B)B(B'B'B&B&B%B%B$B#B#B"B"B!B!B BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB B B B B B B B B BBBBBBBBBBBBBBBB@><:87531/.,*)'%# "                   "$&(*-/1368:=???>>=<<;;::9887 7 6 6 5 4 4 3 3 22100//..-,,++**)((''&&%$$##""!   !""##$$%&&''(()**++,,-..//00122 3 3 4 4 5 6 6 7 7889::;;<<=>>??@@@@@@@@@@@@@@@@ @ @ @ @ @ @ @ @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @!@!@"@"@#@#@$@$@%@&@&@'@'@(@(@)@*@*@+@+@,@,@-@.@.@/@/@0@0@1@2@2@3@3@4@4@5@6@6@7@7@8@         "$&')+-/13568:<>@BCEGIKMOPRTVXZ[]_acefhj}l{nypwqussuqwoymzk|i~geca_][YWUSQONLJHFDB@><:86421/-+)'%#!         !,; KZj@1@0@0@/@/@.@-@-@,@,@+@+@*@*@)@(@(@'@'@&@&@%@$@$@#@#@"@"@!@ @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ @ @ @ @ @ @ @ @@@@@@@@@@@@@@@@><:87531/.,*)'%#"                      "$&)+-/2469;===<<;;:998877655 4 4 3 3 2 1 1 00//.--,,++*))((''&%%$$##""!    !!"##$$%%&''(())*++,,--.//00 1 1 2 3 3 4 4 5 56778899::;<<==>>>>>>>>>>>>>>>> > > > > > > > > >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> > >!>!>">#>#>$>$>%>%>&>'>'>(>(>)>)>*>*>+>,>,>->->.>.>/>0>0>1>1>2>2>3>4>4>5>5>6>6>7>7>8>9>9>:>              " $ & ' ) +-/13568:<>@BCEGIKMOPRTVXZ[]_acefhj~l|n{pyqwsuuswqyozm|k~igeca_][YWUSQOMKIHFDB@><:86420.-+)'%#!        ,; KZj>1>1>0>0>/>.>.>->->,>,>+>*>*>)>)>(>(>'>'>&>%>%>$>$>#>#>">!>!> > >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> > > > > > > > > >>>>>>>>>>>>>>>><:87531/.,*)'%#"                        #%')+.02579<;;::998776655443 2 2 1 1 0 0 / ..--,,+**))((''&%%$$##"!!    !!""#$$%%&&'(())**+,,--.. / / 0 1 1 2 2 3 34556677899::;;<<<<<<<<<<<<<<<< < < < < < < < < <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< < @BCEGIKMOPRTVXZ[]_acefhjl~n|pzqxsvutwrypzn|m~kigeca_][YWUSQOMKIGEDB@><:86420.,*)'%#!        , ; KZj<2<1<0<0:      " $ & ' ) + - / 1 3 5 6 8 : < > @ B C E G I K M O P R TVXZ[]_acefhjln~p|qzsxuvwtyrzp|n~ljhfdca_][YWUSQOMKIGECA?><:86420.,*(&%#!       , ;KZ:3:2:1:1:0:0:/:/:.:-:-:,:,:+:+:*:*:):(:(:':':&:&:%:%:$:#:#:":":!:!: :::::::::::::::::::::::::::::::::: : : : : : : : : ::::::::::::::::87531/.,*)'%#"                   !$&(*,/1368877655443321100/ / . . - , , + + **))(''&&%%$##""!!   !!""##$$%&&''(())*+ + , , - - . / / 00112234455667788888888888888888 8 8 8 8 8 8 8 8 888888888888888888888888888888888 8 8!8!8"8#8#8$8$8%8%8&8&8'8(8(8)8)8*8*8+8+8,8-8-8.8.8/8/8080818282838384848585868787888889898:8:8;8<8<8=8=8>8>8?8?8    "$&')+-/1 3 5 6 8 : < > @ B C E G I K M O P R T V X Z [ ] _ a c e f hjlnp~q|szuxwvytzr|p~nljhfdb`^\[YWUSQOMKIGECA?=;:86420.,*(&$#!      , ;KZ8382828181808/8/8.8.8-8-8,8,8+8*8*8)8)8(8(8'8'8&8%8%8$8$8#8#8"8"8!8 8 8888888888888888888888888888888888 8 8 8 8 8 8 8 888888888888888887531/.,*)'%#"                  "$&)+-/246655443221100//.- - , , + + * ) ) ((''&&%$$##""!!   !!"##$$%%&''(() ) * * + , , - - ..//0112233445666666666666666666 6 6 6 6 6 6 6 6 666666666666666666666666666666666 6 6!6!6"6"6#6#6$6%6%6&6&6'6'6(6(6)6*6*6+6+6,6,6-6-6.6/6/6060616162626364646565666667676868696:6:6;6;6<6<6=6=6>6?6?6@6@6A6A6    "$&')+-/13568:<>@BCE G I K M O P R T V X Z [ ] _ a c e f h j l n p q ~s |u zw xy vz t| r~pnljhfdb`^\ZXVUSQOMKIGECA?=;976420.,*(&$"       ,;K64636362626160606/6/6.6.6-6-6,6+6+6*6*6)6)6(6(6'6&6&6%6%6$6$6#6#6"6!6!6 6 666666666666666666666666666666666 6 6 6 6 6 6 6 6 66666666666666666531/.,*)'%#"                 "%')+-02443322110//..--,, + * * ) ) ( ( ' '&%%$$##""!    !!""#$$%%&&' ' ( ) ) * * + + ,,-..//0011233444444444444444444 4 4 4 4 4 4 4 4 4444444444444444444444444444444444 4 4!4"4"4#4#4$4$4%4%4&4'4'4(4(4)4)4*4*4+4+4,4-4-4.4.4/4/4040414242434344444545464747484849494:4:4;4<4<4=4=4>4>4?4?4@4@4A4B4B4C4C4    "$&')+-/13568:<>@BCEGIKMOPRTVXZ [ ] _ a c e f h j l n p q s ~u |w zy xz v| t~ r p n l j h f d b ` ^\ZXVTRPOMKIGECA?=;975320.,*(&$"      ,;K4444434242414140404/4/4.4-4-4,4,4+4+4*4*4)4(4(4'4'4&4&4%4%4$4#4#4"4"4!4!4 4 444444444444444444444444444444444 4 4 4 4 4 4 4 4 4444444444444444431/.,*)'%#"              !#%'*,.0322100//..--,++** ) ) ( ( ' & & % %$$##"!!    !!""##$%% & & ' ' ( ( ) * *++,,--../0011223333333333333333 3 3 3 3 3 3 3 3 3333333333333333333333333333333333 3 3!3!3"3"3#3$3$3%3%3&3&3'3'3(3(3)3*3*3+3+3,3,3-3-3.3/3/3030313132323333343535363637373838393:3:3;3;3<3<3=3=3>3>3?3@3@3A3A3B3B3C3C3D3E3E3F3F3G3G3H3H3  "$&')+-/13568:<>@BCEGIKMOPRTVXZ[]_acefhjln p q s u }w {y yz w| v~ t r p n l j h f d b ` ^ \ Z X V T R P N L JIGECA?=;97531/.,*(&$"       ,;K3434333332323131303/3/3.3.3-3-3,3,3+3+3*3)3)3(3(3'3'3&3&3%3$3$3#3#3"3"3!3!3 3 333333333333333333333333333333333 3 3 3 3 3 3 3 3 333333333333333331/.,*)'%#"            !$&(*,/100//..-,,++**))( ' ' & & % % $ $ #""!!   !!""## $ $ % % & ' ' ( ())**+,,--..//011111111111111111 1 1 1 1 1 1 1 1 1 111111111111111111111111111111111 1 1!1!1"1"1#1#1$1$1%1&1&1'1'1(1(1)1)1*1*1+1,1,1-1-1.1.1/1/1010111212131314141515161617181819191:1:1;1;1<1=1=1>1>1?1?1@1@1A1A1B1C1C1D1D1E1E1F1F1G1G1H1I1I1J1J1K1K1L1L1M1M1N1O1~O1~P1} "$&')+-/13568:<>@BCEGIKMOPRTVXZ[]_acefhjlnpqsuw}y{zy|w~us q o m k j h f d b ` ^ \ Z X V T R P N L J H F E C A ? = ; 9 7531/-,*(&$"        ,;15151414131312111110101/1/1.1.1-1-1,1+1+1*1*1)1)1(1(1'1&1&1%1%1$1$1#1#1"1"1!1 1 1111111111111111111111111111111111 1 1 1 1 1 1 1 1 11111111111111111/.,*)'%#"             "$&(+-/..--,,++**)((''& & % % $ # # " " !!    !" " # # $ $ % % & &'(())**++,,-..////////////////// / / / / / / / / ////////////////////////////////// / /!/!/"/#/#/$/$/%/%/&/&/'/'/(/)/)/*/*/+/+/,/,/-/-/./////0/0/1/1/2/2/3/3/4/5/5/6/6/7/7/8/8/9/9/:/;/;//>/?/?/@/A/A/B/B/C/C/D/D/E/E/F/G/G/H/H/I/I/J/J/K/K/L/M/M/N/N/O/O/P/P/~Q/~Q/}R/|S/|S/{T/{T/zU/zU/yV/yV/xW/xW/w3568:<>@BCEGIKMOPRTVXZ[]_acefhjlnpqsuwy}z{|y~wusqomkigecb` ^ \ Z X V T R P N L J H F D B A ? = ; 9 7 5 3 1 / - + ) ( & $ "           ,;/6/5/5/4/3/3/2/2/1/1/0/0/////./-/-/,/,/+/+/*/*/)/)/(/'/'/&/&/%/%/$/$/#/#/"/!/!/ / ////////////////////////////////// / / / / / / / / /////////////////.,*)'%#"           "%')+--,,+**))((''&&%$ $ # # " " ! !  ! ! " " # $ $ %%&&''(()**++,,------------------ - - - - - - - - ---------------------------------- - -!-!-"-"-#-#-$-%-%-&-&-'-'-(-(-)-)-*-+-+-,-,-----.-.-/-/-0-0-1-2-2-3-3-4-4-5-5-6-6-7-8-8-9-9-:-:-;-;-<-<-=->->-?-?-@-@-A-A-B-B-C-C-D-E-E-F-F-G-G-H-H-I-I-J-K-K-L-L-M-M-N-N-O-O-P-Q-Q-R-R-~S-~S-}T-|T-|U-{U-{V-zV-zW-yX-yX-xY-xY-wZ-wZ-v[-u[-u\-t\-t]-s^-s^-r_-r_-qGIKMOPRTVXZ[]_acefhjlnpqsuwyz}|{~ywusqomkigeca_]\ZXVTRPNL J H F D B @ > = ; 9 7 5 3 1 / - + ) ' & $ "                   ,-6-6-5-5-4-4-3-3-2-2-1-0-0-/-/-.-.-----,-,-+-+-*-)-)-(-(-'-'-&-&-%-%-$-#-#-"-"-!-!- - ---------------------------------- - - - - - - - - -----------------,*)'%#"        !#%')++**))((''&%%$$## " " ! !       ! ! " " ##$%%&&''(())**++++++++++++++++++ + + + + + + + + +++++++++++++++++++++++++++++++++++ +!+!+"+"+#+#+$+$+%+%+&+'+'+(+(+)+)+*+*+++++,+,+-+.+.+/+/+0+0+1+1+2+2+3+3+4+5+5+6+6+7+7+8+8+9+9+:+:+;+<+<+=+=+>+>+?+?+@+@+A+B+B+C+C+D+D+E+E+F+F+G+G+H+I+I+J+J+K+K+L+L+M+M+N+N+O+P+P+Q+Q+R+R+S+S+T+~T+~U+}V+|V+|W+{W+{X+zX+zY+yY+yZ+xZ+x[+w[+w\+v]+u]+u^+t^+t_+s_+s`+r`+ra+qa+qb+pb+pc+od+nd+ne+me+mf+lf+lg+k[]_acefhjlnpqsuwyz|}~{ywusqomkigeca_][YWVTRPNLJHFDB@><:9 7 5 3 1 / - + ) ' % # "                    ,+7+6+6+5+5+4+4+3+2+2+1+1+0+0+/+/+.+.+-+-+,+++++*+*+)+)+(+(+'+'+&+%+%+$+$+#+#+"+"+!+!+ + ++++++++++++++++++++++++++++++++++ + + + + + + + + +++++++++++++++++*)'%#"       !#&(*))(('&&%%$$##""!              ! !""##$$%%&''(())***************** * * * * * * * * *********************************** * *!*!*"*#*#*$*$*%*%*&*&*'*'*(*(*)*****+*+*,*,*-*-*.*.*/*/*0*1*1*2*2*3*3*4*4*5*5*6*6*7*8*8*9*9*:*:*;*;*<*<*=*=*>*>*?*@*@*A*A*B*B*C*C*D*D*E*E*F*G*G*H*H*I*I*J*J*K*K*L*L*M*N*N*O*O*P*P*Q*Q*R*R*S*S*T*U*U*V*~V*~W*}W*}X*|X*{Y*{Y*zZ*zZ*y[*y\*x\*x]*w]*w^*v^*v_*u_*t`*t`*sa*sa*rb*rc*qc*qd*pd*pe*oe*of*nf*mg*mg*lh*lh*ki*kj*jj*jk*ik*il*hl*hm*gm*fn*fn*epqsuwyz|~~}{ywusqomkigeca_][YWUSQPNLJHFDB@><:86531/-+)'%# !                  *8*7*7*6*5*5*4*4*3*3*2*2*1*1*0*0*/*.*.*-*-*,*,*+*+*****)*)*(*'*'*&*&*%*%*$*$*#*#*"*"*!* * *********************************** * * * * * * * * *****************)'%#"       "$&(''&&%%$$##"!!                      !""##$$%%&&''((((((((((((((((( ( ( ( ( ( ( ( ( ( (((((((((((((((((((((((((((((((((( ( (!(!("("(#(#($($(%(&(&('('((((()()(*(*(+(+(,(,(-(.(.(/(/(0(0(1(1(2(2(3(3(4(5(5(6(6(7(7(8(8(9(9(:(:(;(<(<(=(=(>(>(?(?(@(@(A(A(B(B(C(D(D(E(E(F(F(G(G(H(H(I(I(J(K(K(L(L(M(M(N(N(O(O(P(P(Q(Q(R(S(S(T(T(U(U(V(V(W(W(~X(~X(}Y(}Z(|Z({[({[(z\(z\(y](y](x^(x^(w_(w_(v`(v`(ua(tb(tb(sc(sc(rd(rd(qe(qe(pf(pf(og(og(nh(ni(mi(lj(lj(kk(kk(jl(jl(im(im(hn(hn(go(go(fp(eq(eq(dr(dr(cs(cs(bt(bt(au(au(`v(`zxvtrqomkigeca_][YWUSQOMKJHFDB@><:86421/-+)'%#!        (8(7(7(6(6(5(5(4(4(3(3(2(1(1(0(0(/(/(.(.(-(-(,(,(+(+(*()()((((('('(&(&(%(%($($(#("("(!(!( ( ((((((((((((((((((((((((((((((((((( ( ( ( ( ( ( ( ( ((((((((((((((((('%#"     "$&&%%$$#""!!                      !!""#$$%%&&&&&&&&&&&&&&&&&& & & & & & & & & & &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& &!&!&"&"&#&#&$&$&%&%&&&&&'&'&(&)&)&*&*&+&+&,&,&-&-&.&.&/&/&0&1&1&2&2&3&3&4&4&5&5&6&6&7&7&8&9&9&:&:&;&;&<&<&=&=&>&>&?&?&@&A&A&B&B&C&C&D&D&E&E&F&F&G&G&H&I&I&J&J&K&K&L&L&M&M&N&N&O&O&P&Q&Q&R&R&S&S&T&T&U&U&V&V&W&W&X&Y&Y&~Z&~Z&}[&}[&|\&{\&{]&z]&z^&y^&y_&x_&x`&wa&wa&vb&vb&uc&uc&td&sd&se&re&rf&qf&qg&pg&ph&oi&oi&nj&nj&mk&mk&ll&kl&km&jm&jn&in&io&ho&hp&gq&gq&fr&fr&es&es&dt&ct&cu&bu&bv&av&aw&`w&`x&_y&_y&^z&^z&]{&]{&\|&[|&[}&Z}&Zgeca_][YWUSQOMKIGFDB@><:86420.-+)'%#!    &8&8&7&7&6&6&5&4&4&3&3&2&2&1&1&0&0&/&/&.&.&-&,&,&+&+&*&*&)&)&(&(&'&'&&&&&%&$&$&#&#&"&"&!&!& & &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& & & & & & & & & &&&&&&&&&&&&&&&&&%#"   !#$$##""!!                       !!""##$$%%%%%%%%%%%%%%%%% % % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % %!%!%"%"%#%$%$%%%%%&%&%'%'%(%(%)%)%*%*%+%+%,%-%-%.%.%/%/%0%0%1%1%2%2%3%3%4%5%5%6%6%7%7%8%8%9%9%:%:%;%;%<%<%=%>%>%?%?%@%@%A%A%B%B%C%C%D%D%E%F%F%G%G%H%H%I%I%J%J%K%K%L%L%M%M%N%O%O%P%P%Q%Q%R%R%S%S%T%T%U%U%V%W%W%X%X%Y%Y%Z%Z%[%~[%~\%}\%}]%|]%{^%{^%z_%z`%y`%ya%xa%xb%wb%wc%vc%vd%ud%ue%te%tf%sf%rg%rh%qh%qi%pi%pj%oj%ok%nk%nl%ml%mm%lm%ln%kn%jo%jo%ip%iq%hq%hr%gr%gs%fs%ft%et%eu%du%dv%cv%cw%bw%ax%ay%`y%`z%_z%_{%^{%^|%]|%]}%\}%\~%[~%[%Z%Y%Y%X%X%W%W%V%V%U%U%TSQOMKIGECB@><:86420.,+)'%#!  %9%9%8%7%7%6%6%5%5%4%4%3%3%2%2%1%1%0%0%/%.%.%-%-%,%,%+%+%*%*%)%)%(%(%'%&%&%%%%%$%$%#%#%"%"%!%!% % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % % % %%%%%%%%%%%%%%%%%#"    !#""!!                       !!""################## # # # # # # # # ################################### # #!#!#"#"#####$#$#%#%#&#&#'#(#(#)#)#*#*#+#+#,#,#-#-#.#.#/#/#0#1#1#2#2#3#3#4#4#5#5#6#6#7#7#8#8#9#:#:#;#;#<#<#=#=#>#>#?#?#@#@#A#A#B#C#C#D#D#E#E#F#F#G#G#H#H#I#I#J#J#K#L#L#M#M#N#N#O#O#P#P#Q#Q#R#R#S#S#T#U#U#V#V#W#W#X#X#Y#Y#Z#Z#[#[#\#\#~]#~^#}^#}_#|_#|`#{`#za#za#yb#yb#xc#xc#wd#wd#ve#ve#uf#ug#tg#th#sh#si#ri#qj#qj#pk#pk#ol#ol#nm#nm#mn#mn#lo#lp#kp#kq#jq#jr#ir#hs#hs#gt#gt#fu#fu#ev#ev#dw#dw#cx#cx#by#bz#az#a{#`{#_|#_|#^}#^}#]~#]~#\#\#[#[#Z#Z#Y#Y#X#X#W#V#V#U#U#T#T#S#S#R#R#Q#Q#P#P#O#O?><:86420.,*('%#!  #9#9#8#8#7#7#6#6#5#5#4#4#3#2#2#1#1#0#0#/#/#.#.#-#-#,#,#+#+#*#)#)#(#(#'#'#&#&#%#%#$#$#####"#"#!# # ################################### # # # # # # # # # #################"     !!                       !!!!!!!!!!!!!!!!!! ! ! ! ! ! ! ! ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! !!!"!"!#!#!$!$!%!%!&!&!'!'!(!(!)!)!*!*!+!,!,!-!-!.!.!/!/!0!0!1!1!2!2!3!3!4!4!5!6!6!7!7!8!8!9!9!:!:!;!;!!?!?!@!@!A!A!B!B!C!C!D!D!E!E!F!F!G!G!H!I!I!J!J!K!K!L!L!M!M!N!N!O!O!P!P!Q!Q!R!S!S!T!T!U!U!V!V!W!W!X!X!Y!Y!Z!Z![![!\!]!]!^!^!~_!~_!}`!}`!|a!|a!{b!zb!zc!yc!yd!xd!xe!we!wf!vg!vg!uh!uh!ti!ti!sj!sj!rk!rk!ql!pl!pm!om!on!nn!no!mp!mp!lq!lq!kr!kr!js!js!it!it!hu!hu!gv!fv!fw!ew!ex!dx!dy!cz!cz!b{!b{!a|!a|!`}!`}!_~!_~!^!]!]!\!\![![!Z!Z!Y!Y!X!X!W!W!V!V!U!U!T!S!S!R!R!Q!Q!P!P!O!O!N!N!M!M!L!L!K!K!J!I.,*(&%#!  !:!:!9!9!8!8!7!6!6!5!5!4!4!3!3!2!2!1!1!0!0!/!/!.!.!-!,!,!+!+!*!*!)!)!(!(!'!'!&!&!%!%!$!$!#!"!"!!!!! ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! ! ! ! ! ! ! ! ! !!!!!!!!!!!!!!!!!                                                                         ! ! " " # # $ $ % & & ' ' ( ( ) ) * * + + , , - - . . / 0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 : ; ; < < = = > > ? ? @ @ A A B B C C D D E F F G G H H I I J J K K L L M M N N O P P Q Q R R S S T T U U V V W W X X Y Y Z [ [ \ \ ] ] ^ ^ _ _ ` ~` ~a }a }b |b |c {c zd zd ye yf xf xg wg wh vh vi ui uj tj tk sk sl rl rm qm qn pn oo op np nq mq mr lr ls ks kt jt ju iu iv hv hw gw gx fx fy ey dz d{ c{ c| b| b} a} a~ `~ ` _ _ ^ ^ ] ] \ \ [ Z Z Y Y X X W W V V U U T T S S R R Q Q P O O N N M M L L K K J J I I H H G G F E E D D   : : 9 9 8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1 0 / / . . - - , , + + * * ) ) ( ( ' ' & % % $ $ # # " " ! !                                                                                    !!""##$$%%&&''(()**++,,--..//0011223344566778899::;;<<==>>??@@ABBCCDDEEFFGGHHIIJJKKLMMNNOOPPQQRRSSTTUUVVWWXYYZZ[[\\]]^^__``aa~b~b}c}d|d|e{e{fzfygygxhxhwiwivjvjukuktltlsmsmrnrnqoqppppqoqnrnrmsmsltltkukujvjviwiwhxhxgygyfzfze{e|d|d}c}b~b~aa``__^^]]\\[[ZZYYXXWVVUUTTSSRRQQPPOONNMMLKKJJIIHHGGFFEEDDCCBBAA@??>;::9988776654433221100//..--,,++**)((''&&%%$$##""!!                                              !!"##$$%%&&''(())**++,,--../00112233445566778899::;;<==>>??@@AABBCCDDEEFFGGHIIJJKKLLMMNNOOPPQQRRSSTTUVVWWXXYYZZ[[\\]]^^__``aabcc~d~d}e}e|f|f{g{gzhyhyixixjwjwkvkvlulumtmtnsnsorprpqqqqprprososntntmululvkvkwjwjxixiyhyhzgzg{f|f|e}e}d~d~ccbbaa`__^^]]\\[[ZZYYXXWWVVUUTTSRRQQPPOONNMMLLKKJJIIHHGFFEEDDCCBBAA@@??>>==<<;;:99887766554433221100//..-,,++**))((''&&%%$$##""!!                                          !!""##$$%%&&'(())**++,,--..//0011223344556778899::;;<<==>>??@@AABBCCDEEFFGGHHIIJJKKLLMMNNOOPPQQRSSTTUUVVWWXXYYZZ[[\\]]^^__`aabbccdde~e~f}f}g|g|h{h{izizjyjxkxkwlwlvmvmunuototpspsqrqrrqrqspsptotoununvmvmwlwlxkxjyjyizizh{h{g|g|f}f~e~eddccbbaa``__^^]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONMMLLKKJJIIHHGGFFEEDDCCBBAA@??>>==<<;;::9988776655443321100//..--,,++**))((''&&%%$##""!!                                    !!""##$$%%&&''(())**++,,--.//00112233445566778899::;;<<==>??@@AABBCCDDEEFFGGHHIIJJKKLLMMNOOPPQQRRSSTTUUVVWWXXYYZZ[[\\]]^__``aabbccddeeff~g~g}h}h|i|i{j{jzkzkylylxmwmwnvovoupuptqtqsrsrrsrsqtqtpupuovovnwnwmxmxlylykzkzj{j{i|i|h}g}g~ffeeddccbbaa``__^^]]\\[[ZZYYXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHGGFFEEDDCCBBAA@@??>>==<<;;::9987766554433221100//..--,,++**))(''&&%%$$##""!!                              !!""##$%%&&''(())**++,,--..//0011223344556678899::;;<<==>>??@@AABBCCDDEEFFGGHHIJJKKLLMMNNOOPPQQRRSSTTUUVVWWXXYYZZ[\\]]^^__``aabbccddeeffggh~h~i}i}j|j|k{k{lzlzmymynxoxowpvpvququrtrtsssstrtruquqvpvpwowoxnxnymymzlzl{k{k|j|j}i}i~h~hggffeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@??>>==<<;;::99887766554433221100//.--,,++**))((''&&%%$$##""!!                            !!""##$$%%&&''(())**++,,-..//00112233445566778899::;;<<==>>??@@AABCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRRSSTTUUVVWXXYYZZ[[\\]]^^__``aabbccddeeffgghhii~j~j}k}k|l|l{m{nznzoyoypxpxqwqwrvrususttttsusurvrvqwqwpxpxoyoynznzm{m{l|l|k}k}j~j~iihhggffeeddccbbaa`__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::9988776654433221100//..--,,++**))((''&&%%$$##""!!                                 !!""##$$%%&&''(())**++,,--..//0011223344556677899::;;<<==>>??@@AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRSSTTUUVVWWXXYYZZ[[\\]]^^__``aabbccddeeffgghhiijjk~k~l}m}m|n|n{o{ozpzpyqyqxrxrwswsvtvtuuuutvtvswrwrxqxqypypzozo{n{n|m|m}l}l~k~kjjiihhggffeeddccbbaa``__^^]]\\[[ZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@??>>==<<;;::99887766554433221100//..--,,++**))((''&%%$$##""!!                                      !!""##$$%%&&''(())*++,,--..//00112233445566778899::;;<<==>>??@@AABBCCDDEEFFGGHHIIJKKLLMMNNOOPPQQRRSSTTUUVVWWXXYYZZ[[\\]]^^__``aabbccddeeffgghhiijjkllm~m~n}n}o|o|p{p{qzqzryrysxsxtwtwuvuvvuvuwtwtxsxsyryrzqzq{p{o|o|n}n}m~m~llkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::99887766554433221100/..--,,++**))((''&&%%$$##""!!                                              !!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<==>>??@@AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRRSSTTUUVVWWXXYYZZ[[\\]]^^__``aabbccddeeffgghiijjkkllmmnn~o~o}p}p|q|q{r{rzszsytytxuxuwvwvvwvwuxuxtytyszszr{r{q|q|p}p}o~o~nnmmllkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@?>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!                                              !!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??@@AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRRSSTTUUVVWWXXYYZZ[[\\]]^^__``aabbccdeeffgghhiijjkkllmmnnoop~p~q}q}r|r|s{s{tztzuyuyvxvxwwwwxvxvyuyuztzt{s{s|r|r}q}q~p~poonnmmllkkjjiihhggffeeddccbbaa`__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!                                              !!""##$$%%&&''(())**++,,--..//00112233445566778899::;;<<==>>??@@AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRRSSTUUVVWWXXYYZZ[[\\]]^^__``aabbccddeeffgghhiijjkkllmmnnooppqq~r~r}s}s|t|t{u{uzvzvywywxxxxwywyvzvzu{u{t|t|s}s}r~r~qqppoonnmmllkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCBBAA@@??>>==<<;;:99887766554433221100//..--,,++**))((''&&%%$$##""!!                                                                              ! ! " " # # $ $ % % & & ' ' ( ( ) ) * * + + , , - - . . / / 0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 : : ; ; < < = = > > ? ? @ @ A A B B C C D D E E F F G G H H I I J J K K L L M M N N O O P P Q Q R R S S T T U U V V W W X X Y Y Z Z [ [ \ \ ] ] ^ ^ _ _ ` ` a a b b c c d d e e f f g g h h i i j j k k l l m m n n o o p p q q r r s ~s ~t }t }u |u |v {v {w zw zx yx yy xy xz wz w{ v{ v| u| u} t} t~ s~ s r r q q p p o o n n m m l l k k j j i i h h g g f f e e d d c c b b a a ` ` _ _ ^ ^ ] ] \ \ [ [ Z Z Y Y X X W W V V U U T T S S R R Q Q P P O O N N M M L L K K J J I I H H G G F F E E D D C C B B A A @ @ ? ? > > = = < < ; ; : : 9 9 8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1 0 0 / / . . - - , , + + * * ) ) ( ( ' ' & & % % $ $ # # " " ! !                                                                                                                  ! ! " " # # $ $ % % & & ' ' ( ( ) ) * * + + , , - - . . / / 0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 : : ; ; < < = = > > ? ? @ @ A A B B C C D D E E F F G G H H I I J J K K L L M M N N O O P P Q Q R R S S T T U U V V W W X X Y Y Z Z [ [ \ \ ] ] ^ ^ _ _ ` ` a a b b c c d d e e f f g g h h i i j j k k l l m m n n o o p p q q r r s s t t ~u ~u }v }v |w |w {x {x zy zy yz yz x{ x{ w| w| v} v} u~ u~ t t s s r r q q p p o o n n m m l l k k j j i i h h g g f f e e d d c c b b a a ` ` _ _ ^ ^ ] ] \ \ [ [ Z Z Y Y X X W W V V U U T T S S R R Q Q P P O O N N M M L L K K J J I I H H G G F F F E E D D C C B B A A @ @ ? ? > > = = < < ; ; : : 9 9 8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1 0 0 / / . . - - , , + + * * ) ) ( ( ' ' & & % % $ $ # # " " ! !                                                                                                           ! ! " " # # $ $ % % & & ' ' ( ( ) ) * * + + , , - - . . / / 0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 : : ; ; < < = = > > ? ? @ @ A A B B B C C D D E E F F G G H H I I J J K K L L M M N N O O P P Q Q R R S S T T U U V V W W X X Y Y Z Z [ [ \ \ ] ] ^ ^ _ _ ` ` a a b b c c d d e e f f g g h h i i j j k k l l m m n n o o p p q q r r s s t t u u v ~v ~w }w }x |x |y {y {z zz z{ y{ y| x| x} w} w} v~ v~ u u t t s s r r q q p p o o n n m m l l k k j j i i h h g g f f e e d d c c b b a a a ` ` _ _ ^ ^ ] ] \ \ [ [ Z Z Y Y X X W W V V U U T T S S R R Q Q P P O O N N M M L L K K J J I I H H G G F F E E D D C C B B A A @ @ ? ? > > = = < < ; ; : : 9 9 8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1 0 0 / / . . - - , , + + * * ) ) ( ( ' ' & & & % % $ $ # # " " ! !                                                               !!""##$$%%&&''(()))**++,,--..//00112233445566778899::;;<<==>>??@@AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQQRRSSTTUUVVWWXXYYZZ[[\\]]^^__``aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvww~x~x}y}y|y|z{z{{z{z|y|y}x}x~w~wvvuuttssrrqqppoonnmmllkkkjjiihhggffeeddccbbaa``__^^]]\\[[ZZYYXXWWVVUUTTSSRRQQPPOONNMMLLKKJJIIHHGGFFEEDDCCCBBAA@@??>>==<<;;::99887766554433221100//..--,,++**))((''&&%%$$##""!!            level-zero-raytracing-support-1.0.0/testing/rthwif_cornell_box.cpp000066400000000000000000000512441450534701400255320ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include #include "tbb/tbb.h" #include "../rttrace/rttrace.h" #include #include #include #include void* dispatchGlobalsPtr = nullptr; static uint32_t global_width = 512; static uint32_t global_height = 512; void exception_handler(sycl::exception_list exceptions) { for (std::exception_ptr const& e : exceptions) { try { std::rethrow_exception(e); } catch(sycl::exception const& e) { std::cout << "Caught asynchronous SYCL exception: " << e.what() << std::endl; } } }; inline void fwrite_uchar (unsigned char v, std::fstream& file) { file.write((const char*)&v,sizeof(v)); } inline void fwrite_ushort(unsigned short v, std::fstream& file) { file.write((const char*)&v,sizeof(v)); } void storeTga(uint32_t* pixels, uint32_t width, uint32_t height, const std::string& fileName) try { std::fstream file; file.exceptions (std::fstream::failbit | std::fstream::badbit); file.open (fileName.c_str(), std::fstream::out | std::fstream::binary); fwrite_uchar(0x00, file); fwrite_uchar(0x00, file); fwrite_uchar(0x02, file); fwrite_ushort(0x0000, file); fwrite_ushort(0x0000, file); fwrite_uchar(0x00, file); fwrite_ushort(0x0000, file); fwrite_ushort(0x0000, file); fwrite_ushort((unsigned short)width , file); fwrite_ushort((unsigned short)height, file); fwrite_uchar(0x18, file); fwrite_uchar(0x20, file); for (size_t y=0; y>0)&0xFF), file); fwrite_uchar((unsigned char)((c>>8)&0xFF), file); fwrite_uchar((unsigned char)((c>>16)&0xFF), file); } } } catch (std::exception const& e) { std::cout << "Error: Cannot write file " << fileName << std::endl; throw; } std::vector readFile(const std::string& fileName) try { std::fstream file; file.exceptions (std::fstream::failbit | std::fstream::badbit); file.open (fileName.c_str(), std::fstream::in | std::fstream::binary); file.seekg (0, std::ios::end); std::streampos size = file.tellg(); std::vector data(size); file.seekg (0, std::ios::beg); file.read (data.data(), size); file.close(); return data; } catch (std::exception const& e) { std::cout << "Error: Cannot read file " << fileName << std::endl; throw; } bool compareTga(const std::string& fileNameA, const std::string& fileNameB) { const std::vector dataA = readFile(fileNameA); const std::vector dataB = readFile(fileNameB); return dataA == dataB; } /* Properly allocates an acceleration structure buffer using ze_raytracing_mem_alloc_ext_desc_t property. */ void* alloc_accel_buffer(size_t bytes, sycl::device device, sycl::context context) { ze_context_handle_t hContext = sycl::get_native(context); ze_device_handle_t hDevice = sycl::get_native(device); ze_rtas_device_exp_properties_t rtasProp = { ZE_STRUCTURE_TYPE_RTAS_DEVICE_EXP_PROPERTIES }; ze_device_properties_t devProp = { ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES, &rtasProp }; ze_result_t err = ZeWrapper::zeDeviceGetProperties(hDevice, &devProp ); if (err != ZE_RESULT_SUCCESS) throw std::runtime_error("zeDeviceGetProperties failed"); ze_raytracing_mem_alloc_ext_desc_t rt_desc; rt_desc.stype = ZE_STRUCTURE_TYPE_RAYTRACING_MEM_ALLOC_EXT_DESC; rt_desc.pNext = nullptr; rt_desc.flags = 0; ze_device_mem_alloc_desc_t device_desc; device_desc.stype = ZE_STRUCTURE_TYPE_DEVICE_MEM_ALLOC_DESC; device_desc.pNext = &rt_desc; device_desc.flags = ZE_DEVICE_MEM_ALLOC_FLAG_BIAS_CACHED; device_desc.ordinal = 0; ze_host_mem_alloc_desc_t host_desc; host_desc.stype = ZE_STRUCTURE_TYPE_HOST_MEM_ALLOC_DESC; host_desc.pNext = nullptr; host_desc.flags = ZE_HOST_MEM_ALLOC_FLAG_BIAS_CACHED; void* ptr = nullptr; ze_result_t result = ZeWrapper::zeMemAllocShared(hContext,&device_desc,&host_desc,bytes,rtasProp.rtasBufferAlignment,hDevice,&ptr); if (result != ZE_RESULT_SUCCESS) throw std::runtime_error("acceleration buffer allocation failed"); return ptr; } void free_accel_buffer(void* ptr, sycl::context context) { ze_context_handle_t hContext = sycl::get_native(context); ze_result_t result = ZeWrapper::zeMemFree(hContext,ptr); if (result != ZE_RESULT_SUCCESS) throw std::runtime_error("acceleration buffer free failed"); } /* dispatch globals allocation is for debugging only */ enum Flags : uint32_t { FLAGS_NONE, DEPTH_TEST_LESS_EQUAL = 1 << 0 // when set we use <= for depth test, otherwise < }; struct DispatchGlobals { uint64_t rtMemBasePtr; // base address of the allocated stack memory uint64_t callStackHandlerKSP; // this is the KSP of the continuation handler that is invoked by BTD when the read KSP is 0 uint32_t asyncStackSize; // async-RT stack size in 64 byte blocks uint32_t numDSSRTStacks : 16; // number of stacks per DSS uint32_t syncRayQueryCount : 4; // number of ray queries in the sync-RT stack: 0-15 mapped to: 1-16 unsigned _reserved_mbz : 12; uint32_t maxBVHLevels; // the maximal number of supported instancing levels (0->8, 1->1, 2->2, ...) Flags flags; // per context control flags }; void* allocDispatchGlobals(sycl::device device, sycl::context context) { size_t maxBVHLevels = 2; //RTC_MAX_INSTANCE_LEVEL_COUNT+1; size_t rtstack_bytes = (64+maxBVHLevels*(64+32)+63)&-64; size_t num_rtstacks = 1<<17; // this is sufficiently large also for PVC size_t dispatchGlobalSize = 128+num_rtstacks*rtstack_bytes; void* dispatchGlobalsPtr = alloc_accel_buffer(dispatchGlobalSize,device,context); memset(dispatchGlobalsPtr, 0, dispatchGlobalSize); DispatchGlobals* dg = (DispatchGlobals*) dispatchGlobalsPtr; dg->rtMemBasePtr = (uint64_t) dispatchGlobalsPtr + dispatchGlobalSize; dg->callStackHandlerKSP = 0; dg->asyncStackSize = 0; dg->numDSSRTStacks = 0; dg->syncRayQueryCount = 0; dg->_reserved_mbz = 0; dg->maxBVHLevels = maxBVHLevels; dg->flags = DEPTH_TEST_LESS_EQUAL; return dispatchGlobalsPtr; } /* vertex indices for cornell_box model */ ze_rtas_triangle_indices_uint32_exp_t indices[] = { { 0, 1, 2 }, { 0, 2, 3 }, { 4, 5, 6 }, { 4, 6, 7 }, { 8, 9, 10 }, { 8, 10, 11 }, { 12, 13, 14 }, { 12, 14, 15 }, { 16, 17, 18 }, { 16, 18, 19 }, { 20, 21, 22 }, { 20, 22, 23 }, { 24, 25, 26 }, { 24, 26, 27 }, { 28, 29, 30 }, { 28, 30, 31 }, { 32, 33, 34 }, { 32, 34, 35 }, { 36, 37, 38 }, { 36, 38, 39 }, { 40, 41, 42 }, { 40, 42, 43 }, { 44, 45, 46 }, { 44, 46, 47 }, { 48, 49, 50 }, { 48, 50, 51 }, { 52, 53, 54 }, { 52, 54, 55 }, { 56, 57, 58 }, { 56, 58, 59 }, { 60, 61, 62 }, { 60, 62, 63 }, { 64, 65, 66 }, { 64, 66, 67 } }; /* vertex positions for cornell_box model */ ze_rtas_float3_exp_t vertices[] = { { 552.8, 0, 0 }, { 0, 0, 0 }, { 0, 0, 559.2 }, { 549.6, 0, 559.2 }, { 290, 0, 114 }, { 240, 0, 272 }, { 82, 0, 225 }, { 130, 0, 65 }, { 472, 0, 406 }, { 314, 0, 456 }, { 265, 0, 296 }, { 423, 0, 247 }, { 556, 548.8, 0 }, { 556, 548.8, 559.2 }, { 0, 548.8, 559.2 }, { 0, 548.8, 0 }, { 549.6, 0, 559.2 }, { 0, 0, 559.2 }, { 0, 548.8, 559.2 }, { 556, 548.8, 559.2 }, { 0, 0, 559.2 }, { 0, 0, 0 }, { 0, 548.8, 0 }, { 0, 548.8, 559.2 }, { 552.8, 0, 0 }, { 549.6, 0, 559.2 }, { 556, 548.8, 559.2 }, { 556, 548.8, 0 }, { 130, 165, 65 }, { 82, 165, 225 }, { 240, 165, 272 }, { 290, 165, 114 }, { 290, 0, 114 }, { 290, 165, 114 }, { 240, 165, 272 }, { 240, 0, 272 }, { 130, 0, 65 }, { 130, 165, 65 }, { 290, 165, 114 }, { 290, 0, 114 }, { 82, 0, 225 }, { 82, 165, 225 }, { 130, 165, 65 }, { 130, 0, 65 }, { 240, 0, 272 }, { 240, 165, 272 }, { 82, 165, 225 }, { 82, 0, 225 }, { 423, 330, 247 }, { 265, 330, 296 }, { 314, 330, 456 }, { 472, 330, 406 }, { 423, 0, 247 }, { 423, 330, 247 }, { 472, 330, 406 }, { 472, 0, 406 }, { 472, 0, 406 }, { 472, 330, 406 }, { 314, 330, 456 }, { 314, 0, 456 }, { 314, 0, 456 }, { 314, 330, 456 }, { 265, 330, 296 }, { 265, 0, 296 }, { 265, 0, 296 }, { 265, 330, 296 }, { 423, 330, 247 }, { 423, 0, 247 }, }; /* builds acceleration structure */ void* build_rtas(sycl::device device, sycl::context context) { /* get L0 handles */ ze_driver_handle_t hDriver = sycl::get_native(device.get_platform()); ze_device_handle_t hDevice = sycl::get_native(device); /* create rtas builder object */ ze_rtas_builder_exp_desc_t builderDesc = { ZE_STRUCTURE_TYPE_RTAS_BUILDER_EXP_DESC }; ze_rtas_builder_exp_handle_t hBuilder = nullptr; ze_result_t err = ZeWrapper::zeRTASBuilderCreateExp(hDriver, &builderDesc, &hBuilder); if (err != ZE_RESULT_SUCCESS) throw std::runtime_error("ze_rtas_builder creation failed"); /* create geometry descriptor for single triangle mesh */ ze_rtas_builder_triangles_geometry_info_exp_t mesh = {}; mesh.geometryType = ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_TRIANGLES; mesh.geometryFlags = 0; mesh.geometryMask = 0xFF; mesh.triangleFormat = ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_TRIANGLE_INDICES_UINT32; mesh.triangleCount = sizeof(indices)/sizeof(ze_rtas_triangle_indices_uint32_exp_t); mesh.triangleStride = sizeof(ze_rtas_triangle_indices_uint32_exp_t); mesh.pTriangleBuffer = indices; mesh.vertexFormat = ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_FLOAT3; mesh.vertexCount = sizeof(vertices)/sizeof(ze_rtas_float3_exp_t); mesh.vertexStride = sizeof(ze_rtas_float3_exp_t); mesh.pVertexBuffer = vertices; /* fill geometry descriptor array with pointer to single geometry descriptor */ std::vector descs; descs.push_back((ze_rtas_builder_geometry_info_exp_t*)&mesh); /* get acceleration structure format for this device */ ze_rtas_device_exp_properties_t rtasProp = { ZE_STRUCTURE_TYPE_RTAS_DEVICE_EXP_PROPERTIES }; ze_device_properties_t devProp = { ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES, &rtasProp }; err = ZeWrapper::zeDeviceGetProperties(hDevice, &devProp ); if (err != ZE_RESULT_SUCCESS) throw std::runtime_error("zeDeviceGetProperties failed"); /* create parallel operation for parallel build */ ze_rtas_parallel_operation_exp_handle_t hParallelOperation = nullptr; err = ZeWrapper::zeRTASParallelOperationCreateExp(hDriver, &hParallelOperation); if (err != ZE_RESULT_SUCCESS) throw std::runtime_error("zeRTASParallelOperationCreateExp failed"); /* create descriptor of build operation */ size_t accelBufferBytesOut = 0; ze_rtas_aabb_exp_t bounds; ze_rtas_builder_build_op_exp_desc_t buildOp = {}; buildOp.stype = ZE_STRUCTURE_TYPE_RTAS_BUILDER_BUILD_OP_EXP_DESC; buildOp.pNext = nullptr; buildOp.rtasFormat = rtasProp.rtasFormat; buildOp.buildQuality = ZE_RTAS_BUILDER_BUILD_QUALITY_HINT_EXP_MEDIUM; buildOp.buildFlags = 0; buildOp.ppGeometries = (const ze_rtas_builder_geometry_info_exp_t **) descs.data(); buildOp.numGeometries = descs.size(); /* just for debugging purposes */ #if defined(EMBREE_SYCL_ALLOC_DISPATCH_GLOBALS) ze_rtas_builder_build_op_debug_exp_desc_t buildOpDebug = { ZE_STRUCTURE_TYPE_RTAS_BUILDER_BUILD_OP_DEBUG_EXP_DESC }; buildOpDebug.dispatchGlobalsPtr = dispatchGlobalsPtr; buildOp.pNext = &buildOpDebug; #endif /* query required buffer sizes */ ze_rtas_builder_exp_properties_t buildProps = { ZE_STRUCTURE_TYPE_RTAS_BUILDER_EXP_PROPERTIES }; err = ZeWrapper::zeRTASBuilderGetBuildPropertiesExp(hBuilder,&buildOp,&buildProps); if (err != ZE_RESULT_SUCCESS) throw std::runtime_error("zeRTASBuilderGetBuildPropertiesExp failed"); /* allocate scratch buffer */ std::vector scratchBuffer(buildProps.scratchBufferSizeBytes); memset(scratchBuffer.data(),0,scratchBuffer.size()); /* allocate acceleration structure buffer */ size_t accelBytes = buildProps.rtasBufferSizeBytesMaxRequired; void* accel = alloc_accel_buffer(accelBytes,device,context); memset(accel,0,accelBytes); // optional /* build acceleration strucuture multi threaded */ err = ZeWrapper::zeRTASBuilderBuildExp(hBuilder,&buildOp, scratchBuffer.data(),scratchBuffer.size(), accel, accelBytes, hParallelOperation, nullptr, &bounds, &accelBufferBytesOut); if (err != ZE_RESULT_EXP_RTAS_BUILD_DEFERRED) throw std::runtime_error("zeRTASBuilderBuildExp failed"); /* after the build is started one can query number of threads to use for the build */ ze_rtas_parallel_operation_exp_properties_t prop = { ZE_STRUCTURE_TYPE_RTAS_PARALLEL_OPERATION_EXP_PROPERTIES }; err = ZeWrapper::zeRTASParallelOperationGetPropertiesExp(hParallelOperation,&prop); if (err != ZE_RESULT_SUCCESS) throw std::runtime_error("zeRTASParallelOperationGetPropertiesExp failed"); /* build in parallel using maximal number of build threads */ tbb::parallel_for(0u, prop.maxConcurrency, 1u, [&](uint32_t) { err = ZeWrapper::zeRTASParallelOperationJoinExp(hParallelOperation); }); if (err != ZE_RESULT_SUCCESS) throw std::runtime_error("zeRTASParallelOperationJoinExp failed"); /* destroy parallel operation again */ err = ZeWrapper::zeRTASParallelOperationDestroyExp(hParallelOperation); if (err != ZE_RESULT_SUCCESS) throw std::runtime_error("zeRTASParallelOperationDestroyExp failed"); /* destroy rtas builder again */ err = ZeWrapper::zeRTASBuilderDestroyExp(hBuilder); if (err != ZE_RESULT_SUCCESS) throw std::runtime_error("zeRTASBuilderDestroyExp failed"); return accel; } /* render using simple UV shading */ void render(unsigned int x, unsigned int y, void* bvh, unsigned int* pixels, unsigned int width, unsigned int height) { /* write zero image if ray tracing extension is not supported */ intel_raytracing_ext_flag_t flags = intel_get_raytracing_ext_flag(); if (!(flags & intel_raytracing_ext_flag_ray_query)) { pixels[y*width+x] = 0; return; } /* fixed camera */ sycl::float3 vx(-1, -0, -0); sycl::float3 vy(-0, -1, -0); sycl::float3 vz(32, 32, 95.6379f); sycl::float3 p(278, 273, -800); /* compute primary ray */ intel_ray_desc_t ray; ray.origin = p; ray.direction = float(x)*vx*64.0f/float(width) + float(y)*vy*64/float(height) + vz; ray.tmin = 0.0f; ray.tmax = INFINITY; ray.mask = 0xFF; ray.flags = intel_ray_flags_none; /* trace ray */ intel_ray_query_t query = intel_ray_query_init(ray,(intel_raytracing_acceleration_structure_t)bvh); intel_ray_query_start_traversal(query); intel_ray_query_sync(query); /* get UVs of hit point */ float u = 0, v = 0; if (intel_has_committed_hit(query)) { sycl::float2 uv = intel_get_hit_barycentrics( query, intel_hit_type_committed_hit ); u = uv.x(); v = uv.y(); } /* write color to framebuffer */ sycl::float3 color(u,v,1.0f-u-v); unsigned int r = (unsigned int) (255.0f * color.x()); unsigned int g = (unsigned int) (255.0f * color.y()); unsigned int b = (unsigned int) (255.0f * color.z()); pixels[y*width+x] = (b << 16) + (g << 8) + r; } int main(int argc, char* argv[]) { /* use can specify reference image to compare against */ #if defined(EMBREE_SYCL_L0_RTAS_BUILDER) ZeWrapper::RTAS_BUILD_MODE rtas_build_mode = ZeWrapper::RTAS_BUILD_MODE::AUTO; #else ZeWrapper::RTAS_BUILD_MODE rtas_build_mode = ZeWrapper::RTAS_BUILD_MODE::INTERNAL; #endif char* reference_img = NULL; for (int i=1; i= argc) throw std::runtime_error("--compare: filename expected"); reference_img = argv[i]; } else if (strcmp(argv[i], "--internal-rtas-builder") == 0) { rtas_build_mode = ZeWrapper::RTAS_BUILD_MODE::INTERNAL; } else if (strcmp(argv[i], "--level-zero-rtas-builder") == 0) { rtas_build_mode = ZeWrapper::RTAS_BUILD_MODE::LEVEL_ZERO; } else if (strcmp(argv[i], "--default-rtas-builder") == 0) { rtas_build_mode = ZeWrapper::RTAS_BUILD_MODE::AUTO; } else if (strcmp(argv[i], "--size") == 0) { if (++i >= argc) throw std::runtime_error("--size: width expected"); global_width = atoi(argv[i]); if (++i >= argc) throw std::runtime_error("--size: height expected"); global_height = atoi(argv[i]); if (global_width == 0) throw std::runtime_error("--size: width is zero"); if (global_height == 0) throw std::runtime_error("--size: height is zero"); if (global_width > 4096) throw std::runtime_error("--size: width too large"); if (global_height > 4096) throw std::runtime_error("--size: height too large"); } else { throw std::runtime_error("unknown command line argument"); } } /* create SYCL objects */ sycl::device device = sycl::device(sycl::gpu_selector_v); sycl::queue queue = sycl::queue(device,exception_handler); sycl::context context = queue.get_context(); if (ZeWrapper::init() != ZE_RESULT_SUCCESS) { std::cerr << "ZeWrapper not successfully initialized" << std::endl; return 1; } sycl::platform platform = device.get_platform(); ze_driver_handle_t hDriver = sycl::get_native(platform); /* enable RTAS extension only when enabled */ if (rtas_build_mode == ZeWrapper::RTAS_BUILD_MODE::AUTO) { uint32_t count = 0; std::vector extensions; ze_result_t result = ZeWrapper::zeDriverGetExtensionProperties(hDriver,&count,extensions.data()); if (result != ZE_RESULT_SUCCESS) throw std::runtime_error("zeDriverGetExtensionProperties failed"); extensions.resize(count); result = ZeWrapper::zeDriverGetExtensionProperties(hDriver,&count,extensions.data()); if (result != ZE_RESULT_SUCCESS) throw std::runtime_error("zeDriverGetExtensionProperties failed"); bool ze_rtas_builder = false; for (uint32_t i=0; i(0,height,0,width), [&](const tbb::blocked_range2d& r) { for (int y=r.rows().begin(); y range(width,height); cgh.parallel_for(range, [=](sycl::item<2> item) { const uint32_t x = item.get_id(0); const uint32_t y = item.get_id(1); render(x,y,bvh,pixels,width,height); }); }); queue.wait_and_throw(); #endif /* free acceleration structure again */ free_accel_buffer(bvh,context); #if defined(EMBREE_SYCL_ALLOC_DISPATCH_GLOBALS) free_accel_buffer(dispatchGlobalsPtr, context); #endif #if defined(ZE_RAYTRACING_RT_SIMULATION) RTCore::Cleanup(); #endif /* store image to disk */ storeTga(pixels,width,height,"cornell_box.tga"); if (!reference_img) return 0; /* compare to reference image */ const bool ok = compareTga("cornell_box.tga", reference_img); std::cout << "cornell_box "; if (ok) std::cout << "[PASSED]" << std::endl; else std::cout << "[FAILED]" << std::endl; return ok ? 0 : 1; } level-zero-raytracing-support-1.0.0/testing/rthwif_test.cpp000066400000000000000000002373711450534701400242120ustar00rootroot00000000000000// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #define NOMINMAX // prevents "'__thiscall' calling convention is not supported for this target" warning from TBB #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wignored-attributes" #include #include "tbb/tbb.h" #if defined(ZE_RAYTRACING) #include "../rtbuild/sys/sysinfo.h" #include "../rtbuild/sys/vector.h" #include "../rtbuild/math/vec2.h" #include "../rtbuild/math/vec3.h" #include "../rtbuild/math/bbox.h" #include "../rtbuild/math/affinespace.h" #else #include "../../../common/sys/sysinfo.h" #include "../../../common/sys/vector.h" #include "../../../common/math/vec2.h" #include "../../../common/math/vec3.h" #include "../../../common/math/bbox.h" #include "../../../common/math/lbbox.h" #include "../../../common/math/affinespace.h" #endif #define _USE_MATH_DEFINES #include #include "../rttrace/rttrace.h" #include #include #include #include #include namespace embree { double getSeconds(); } sycl::device device; sycl::context context; void* dispatchGlobalsPtr = nullptr; struct RandomSampler { unsigned int s; }; unsigned int MurmurHash3_mix(unsigned int hash, unsigned int k) { const unsigned int c1 = 0xcc9e2d51; const unsigned int c2 = 0x1b873593; const unsigned int r1 = 15; const unsigned int r2 = 13; const unsigned int m = 5; const unsigned int n = 0xe6546b64; k *= c1; k = (k << r1) | (k >> (32 - r1)); k *= c2; hash ^= k; hash = ((hash << r2) | (hash >> (32 - r2))) * m + n; return hash; } unsigned int MurmurHash3_finalize(unsigned int hash) { hash ^= hash >> 16; hash *= 0x85ebca6b; hash ^= hash >> 13; hash *= 0xc2b2ae35; hash ^= hash >> 16; return hash; } unsigned int LCG_next(unsigned int value) { const unsigned int m = 1664525; const unsigned int n = 1013904223; return value * m + n; } void RandomSampler_init(RandomSampler& self, int id) { unsigned int hash = 0; hash = MurmurHash3_mix(hash, id); hash = MurmurHash3_finalize(hash); self.s = hash; } int RandomSampler_getInt(RandomSampler& self) { self.s = LCG_next(self.s); return self.s >> 1; } unsigned int RandomSampler_getUInt(RandomSampler& self) { self.s = LCG_next(self.s); return self.s; } float RandomSampler_getFloat(RandomSampler& self) { return (float)RandomSampler_getInt(self) * 4.656612873077392578125e-10f; } sycl::float3 RandomSampler_getFloat3(RandomSampler& self) { const float x = RandomSampler_getFloat(self); const float y = RandomSampler_getFloat(self); const float z = RandomSampler_getFloat(self); return sycl::float3(x,y,z); } RandomSampler rng; ze_rtas_builder_exp_handle_t hBuilder = nullptr; ze_rtas_parallel_operation_exp_handle_t parallelOperation = nullptr; enum class InstancingType { NONE, SW_INSTANCING, HW_INSTANCING }; enum class TestType { TRIANGLES_COMMITTED_HIT, // triangles TRIANGLES_POTENTIAL_HIT, // triangles + filter + check potential hit TRIANGLES_ANYHIT_SHADER_COMMIT, // triangles + filter + commit TRIANGLES_ANYHIT_SHADER_REJECT, // triangles + filter + reject PROCEDURALS_COMMITTED_HIT, // procedural triangles BUILD_TEST_TRIANGLES, // test BVH builder with triangles BUILD_TEST_PROCEDURALS, // test BVH builder with procedurals BUILD_TEST_INSTANCES, // test BVH builder with instances BUILD_TEST_MIXED, // test BVH builder with mixed scene (triangles, procedurals, and instances) BENCHMARK_TRIANGLES, // benchmark BVH builder with triangles BENCHMARK_PROCEDURALS, // benchmark BVH builder with procedurals }; enum class BuildMode { BUILD_EXPECTED_SIZE, BUILD_WORST_CASE_SIZE }; struct TestInput { sycl::float3 org; sycl::float3 dir; float tnear; float tfar; uint32_t mask; uint32_t flags; }; enum TestHitType { TEST_COMMITTED_HIT, TEST_POTENTIAL_HIT, TEST_MISS }; struct TestOutput { // Ray data at level 0 sycl::float3 ray0_org; sycl::float3 ray0_dir; float ray0_tnear; uint32_t ray0_mask; uint32_t ray0_flags; // Ray data at hit bvh_level sycl::float3 rayN_org; sycl::float3 rayN_dir; float rayN_tnear; uint32_t rayN_mask; uint32_t rayN_flags; // Hit data TestHitType hit_type; uint32_t bvh_level; uint32_t hit_candidate; float t; float u; float v; bool front_face; uint32_t geomID; uint32_t primID; uint32_t instID; uint32_t instUserID; sycl::float3 v0; sycl::float3 v1; sycl::float3 v2; intel_float4x3 world_to_object; intel_float4x3 object_to_world; }; std::ostream& operator<<(std::ostream& out, const intel_float3& v) { return out << "(" << v.x << "," << v.y << "," << v.z << ")"; } void compareTestOutput(uint32_t tid, uint32_t& errors, const TestOutput& test, const TestOutput& expected) { #define COMPARE(member) \ if (test.member != expected.member) { \ if (errors < 16) \ std::cout << "test" << tid << " " #member " mismatch: output " << test.member << " != expected " << expected.member << std::endl; \ errors++; \ } #define COMPARE1(member,eps) \ if (fabs(test.member-expected.member) > eps) { \ if (errors < 16) \ std::cout << "test" << tid << " " #member " mismatch: output " << test.member << " != expected " << expected.member << std::endl; \ errors++; \ } #define COMPARE3(member,eps) { \ const bool x = fabs(test.member.x()-expected.member.x()) > eps; \ const bool y = fabs(test.member.y()-expected.member.y()) > eps; \ const bool z = fabs(test.member.z()-expected.member.z()) > eps; \ if (x || y || z) { \ if (errors < 16) \ std::cout << "test" << tid << " " #member " mismatch: output " << test.member << " != expected " << expected.member << std::endl; \ errors++; \ } \ } #define COMPARE3I(member,eps) { \ const bool x = test.member.x != expected.member.x; \ const bool y = test.member.y != expected.member.y; \ const bool z = test.member.z != expected.member.z; \ if (x || y || z) { \ if (errors < 16) \ std::cout << "test" << tid << " " #member " mismatch: output " << test.member << " != expected " << expected.member << std::endl; \ errors++; \ } \ } float eps = 2E-4; COMPARE3(ray0_org,0); COMPARE3(ray0_dir,0); COMPARE1(ray0_tnear,0); COMPARE(ray0_mask); COMPARE(ray0_flags); COMPARE3(rayN_org,eps); COMPARE3(rayN_dir,eps); COMPARE1(rayN_tnear,eps); COMPARE(rayN_mask); COMPARE(rayN_flags); COMPARE(hit_type); COMPARE(bvh_level); COMPARE(hit_candidate); COMPARE1(t,eps); COMPARE1(u,eps); COMPARE1(v,eps); COMPARE(front_face); COMPARE(geomID); COMPARE(primID); COMPARE(instID); COMPARE(instUserID); COMPARE3(v0,eps); COMPARE3(v1,eps); COMPARE3(v2,eps); COMPARE3I(world_to_object.vx,eps); COMPARE3I(world_to_object.vy,eps); COMPARE3I(world_to_object.vz,eps); COMPARE3I(world_to_object.p ,eps); COMPARE3I(object_to_world.vx,eps); COMPARE3I(object_to_world.vy,eps); COMPARE3I(object_to_world.vz,eps); COMPARE3I(object_to_world.p ,eps); } struct LinearSpace3f { /*! matrix construction from column vectors */ LinearSpace3f(const sycl::float3& vx, const sycl::float3& vy, const sycl::float3& vz) : vx(vx), vy(vy), vz(vz) {} /*! matrix construction from row mayor data */ LinearSpace3f(const float m00, const float m01, const float m02, const float m10, const float m11, const float m12, const float m20, const float m21, const float m22) : vx(m00,m10,m20), vy(m01,m11,m21), vz(m02,m12,m22) {} /*! compute the determinant of the matrix */ const float det() const { return sycl::dot(vx,sycl::cross(vy,vz)); } /*! compute adjoint matrix */ const LinearSpace3f adjoint() const { return LinearSpace3f(sycl::cross(vy,vz),sycl::cross(vz,vx),sycl::cross(vx,vy)).transposed(); } /*! compute inverse matrix */ const LinearSpace3f inverse() const { const float d = det(); const LinearSpace3f a = adjoint(); return { a.vx/d, a.vy/d, a.vz/d }; } /*! compute transposed matrix */ const LinearSpace3f transposed() const { return LinearSpace3f(vx.x(),vx.y(),vx.z(),vy.x(),vy.y(),vy.z(),vz.x(),vz.y(),vz.z()); } /*! return matrix for rotation around arbitrary axis */ static LinearSpace3f rotate(const sycl::float3 _u, const float r) { sycl::float3 u = normalize(_u); float s = sinf(r), c = cosf(r); return LinearSpace3f(u.x()*u.x()+(1-u.x()*u.x())*c, u.x()*u.y()*(1-c)-u.z()*s, u.x()*u.z()*(1-c)+u.y()*s, u.x()*u.y()*(1-c)+u.z()*s, u.y()*u.y()+(1-u.y()*u.y())*c, u.y()*u.z()*(1-c)-u.x()*s, u.x()*u.z()*(1-c)-u.y()*s, u.y()*u.z()*(1-c)+u.x()*s, u.z()*u.z()+(1-u.z()*u.z())*c); } public: sycl::float3 vx,vy,vz; }; sycl::float3 xfmPoint (const LinearSpace3f& m, const sycl::float3& p) { return p.x()*m.vx + (p.y()*m.vy + p.z()*m.vz); } struct Transform { Transform () : vx(1,0,0), vy(0,1,0), vz(0,0,1), p(0,0,0) {} Transform ( sycl::float3 vx, sycl::float3 vy, sycl::float3 vz, sycl::float3 p ) : vx(vx), vy(vy), vz(vz), p(p) {} Transform ( intel_float4x3 xfm ) : vx(xfm.vx), vy(xfm.vy), vz(xfm.vz), p(xfm.p) {} operator intel_float4x3 () const { return { vx, vy, vz, p }; } sycl::float3 vx,vy,vz,p; }; std::ostream& operator<<(std::ostream& out, const Transform& t) { return out << " Transform {" << t.vx << ", " << t.vy << ", " << t.vz << ", " << t.p << "}"; } sycl::float3 xfmPoint (const Transform& m, const sycl::float3& p) { return p.x()*m.vx + (p.y()*m.vy + (p.z()*m.vz + m.p)); } sycl::float3 xfmVector (const Transform& m, const sycl::float3& v) { return v.x()*m.vx + (v.y()*m.vy + v.z()*m.vz); } Transform operator* (const Transform& a, const Transform& b) { return Transform(xfmVector(a,b.vx),xfmVector(a,b.vy),xfmVector(a,b.vz),xfmPoint(a,b.p)); } Transform rcp( const Transform& a ) { #if 1 // match builder math for rcp to have bit accurate data to compare against embree::Vec3f vx(a.vx.x(), a.vx.y(), a.vx.z()); embree::Vec3f vy(a.vy.x(), a.vy.y(), a.vy.z()); embree::Vec3f vz(a.vz.x(), a.vz.y(), a.vz.z()); embree::Vec3f p(a. p.x(), a. p.y(), a. p.z()); embree::AffineSpace3f l(embree::LinearSpace3f(vx,vy,vz),p); embree::AffineSpace3f il = rcp(l); sycl::float3 ivx(il.l.vx.x, il.l.vx.y, il.l.vx.z); sycl::float3 ivy(il.l.vy.x, il.l.vy.y, il.l.vy.z); sycl::float3 ivz(il.l.vz.x, il.l.vz.y, il.l.vz.z); sycl::float3 ip(il.p.x, il.p.y, il.p.z); return Transform(ivx,ivy,ivz,ip); #else const LinearSpace3f l = { a.vx, a.vy, a.vz }; const LinearSpace3f il = l.inverse(); return Transform(il.vx, il.vy, il.vz, -xfmPoint(il,a.p)); #endif } Transform RandomSampler_getTransform(RandomSampler& self) { const sycl::float3 u = RandomSampler_getFloat3(self) + sycl::float3(0.01f); const float r = 2.0f*M_PI*RandomSampler_getFloat(self); const sycl::float3 p = 10.0f*RandomSampler_getFloat3(self); const LinearSpace3f xfm = LinearSpace3f::rotate(u,r); return Transform(xfm.vx,xfm.vy,xfm.vz,p); } struct Bounds3f { void extend( sycl::float3 p ) { lower = sycl::min(lower,p); upper = sycl::max(upper,p); } static Bounds3f empty() { return { sycl::float3(INFINITY), sycl::float3(-INFINITY) }; } operator ze_rtas_aabb_exp_t () const { return { { lower.x(), lower.y(), lower.z() }, { upper.x(), upper.y(), upper.z() } }; } sycl::float3 lower; sycl::float3 upper; }; std::ostream& operator<<(std::ostream& out, const Bounds3f& b) { return out << "Bounds3f {" << b.lower << "," << b.upper << "}"; } const Bounds3f xfmBounds(const Transform& m, const Bounds3f& b) { Bounds3f dst = Bounds3f::empty(); const sycl::float3 p0(b.lower.x(),b.lower.y(),b.lower.z()); dst.extend(xfmPoint(m,p0)); const sycl::float3 p1(b.lower.x(),b.lower.y(),b.upper.z()); dst.extend(xfmPoint(m,p1)); const sycl::float3 p2(b.lower.x(),b.upper.y(),b.lower.z()); dst.extend(xfmPoint(m,p2)); const sycl::float3 p3(b.lower.x(),b.upper.y(),b.upper.z()); dst.extend(xfmPoint(m,p3)); const sycl::float3 p4(b.upper.x(),b.lower.y(),b.lower.z()); dst.extend(xfmPoint(m,p4)); const sycl::float3 p5(b.upper.x(),b.lower.y(),b.upper.z()); dst.extend(xfmPoint(m,p5)); const sycl::float3 p6(b.upper.x(),b.upper.y(),b.lower.z()); dst.extend(xfmPoint(m,p6)); const sycl::float3 p7(b.upper.x(),b.upper.y(),b.upper.z()); dst.extend(xfmPoint(m,p7)); return dst; } struct Triangle { Triangle() : v0(0,0,0), v1(0,0,0), v2(0,0,0), index(0) {} Triangle (sycl::float3 v0, sycl::float3 v1, sycl::float3 v2, uint32_t index) : v0(v0), v1(v1), v2(v2), index(index) {} sycl::float3 sample(float u, float v) const { return (1.0f-u-v)*v0 + u*v1 + v*v2; } sycl::float3 center() const { return (v0+v1+v2)/3.0f; } Bounds3f bounds() const { const sycl::float3 lower = sycl::min(v0,sycl::min(v1,v2)); const sycl::float3 upper = sycl::max(v0,sycl::max(v1,v2)); return { lower, upper }; } const Triangle transform( Transform xfm ) const { return Triangle(xfmPoint(xfm,v0), xfmPoint(xfm,v1), xfmPoint(xfm,v2), index); } sycl::float3 v0; sycl::float3 v1; sycl::float3 v2; uint32_t index; }; struct less_float3 { bool operator() ( const sycl::float3& a, const sycl::float3& b ) const { if (a.x() != b.x()) return a.x() < b.x(); if (a.y() != b.y()) return a.y() < b.y(); if (a.z() != b.z()) return a.z() < b.z(); return false; } }; std::ostream& operator<<(std::ostream& out, const Triangle& tri) { return out << "Triangle {" << tri.v0 << "," << tri.v1 << "," << tri.v2 << "}"; } struct Hit { Transform local_to_world; Triangle triangle; bool procedural_triangle = false; bool procedural_instance = false; uint32_t instUserID = -1; uint32_t instID = -1; uint32_t geomID = -1; uint32_t primID = -1; }; struct GEOMETRY_INSTANCE_DESC : ze_rtas_builder_instance_geometry_info_exp_t { ze_rtas_transform_float3x4_aligned_column_major_exp_t xfmdata; }; typedef union GEOMETRY_DESC { ze_rtas_builder_geometry_type_exp_t geometryType; ze_rtas_builder_triangles_geometry_info_exp_t Triangles; ze_rtas_builder_quads_geometry_info_exp_t Quads; ze_rtas_builder_procedural_geometry_info_exp_t AABBs; GEOMETRY_INSTANCE_DESC Instance; } GEOMETRY_DESC; struct Geometry { enum Type { TRIANGLE_MESH, INSTANCE }; Geometry (Type type) : type(type) {} virtual void getDesc(GEOMETRY_DESC* desc) = 0; virtual void transform( const Transform xfm) { throw std::runtime_error("Geometry::transform not implemented"); } virtual void buildAccel(sycl::device& device, sycl::context& context, BuildMode buildMode, ze_rtas_builder_build_quality_hint_exp_t quality) { }; virtual void buildTriMap(Transform local_to_world, std::vector id_stack, uint32_t instUserID, bool procedural_instance, std::vector& tri_map) = 0; virtual size_t getNumPrimitives() const = 0; Type type; }; struct TriangleMesh : public Geometry { public: TriangleMesh (ze_rtas_builder_geometry_exp_flags_t gflags = 0, bool procedural = false) : Geometry(Type::TRIANGLE_MESH), gflags(gflags), procedural(procedural), triangles_alloc(context,device,sycl::ext::oneapi::property::usm::device_read_only()), triangles(0,triangles_alloc), vertices_alloc (context,device,sycl::ext::oneapi::property::usm::device_read_only()), vertices(0,vertices_alloc) {} virtual ~TriangleMesh() {} void* operator new(size_t size) { return sycl::aligned_alloc_shared(64,size,device,context,sycl::ext::oneapi::property::usm::device_read_only()); } void operator delete(void* ptr) { sycl::free(ptr,context); } size_t size() const { return triangles.size(); } virtual void transform( const Transform xfm) override { for (size_t i=0; istype == ZE_STRUCTURE_TYPE_RTAS_GEOMETRY_AABBS_EXP_CB_PARAMS); const TriangleMesh* mesh = (TriangleMesh*) params->pGeomUserPtr; for (uint32_t i=0; iprimIDCount; i++) { const uint32_t primID = params->primID+i; const Bounds3f bounds = mesh->getBounds(primID); ze_rtas_aabb_exp_t* boundsOut = params->pBoundsOut; boundsOut[i].lower.x = bounds.lower.x(); boundsOut[i].lower.y = bounds.lower.y(); boundsOut[i].lower.z = bounds.lower.z(); boundsOut[i].upper.x = bounds.upper.x(); boundsOut[i].upper.y = bounds.upper.y(); boundsOut[i].upper.z = bounds.upper.z(); } } virtual void getDesc(GEOMETRY_DESC* desc) override { if (procedural) { ze_rtas_builder_procedural_geometry_info_exp_t& out = desc->AABBs; memset(&out,0,sizeof(out)); out.geometryType = ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL; out.geometryFlags = gflags; out.geometryMask = 0xFF; out.primCount = triangles.size(); out.pfnGetBoundsCb = TriangleMesh::getBoundsCallback; out.pGeomUserPtr = this; } else { ze_rtas_builder_triangles_geometry_info_exp_t& out = desc->Triangles; memset(&out,0,sizeof(out)); out.geometryType = ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_TRIANGLES; out.geometryFlags = gflags; out.geometryMask = 0xFF; out.triangleFormat = ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_TRIANGLE_INDICES_UINT32; out.vertexFormat = ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_FLOAT3; out.pTriangleBuffer = (ze_rtas_triangle_indices_uint32_exp_t*) triangles.data(); out.triangleCount = triangles.size(); out.triangleStride = sizeof(sycl::int4); out.pVertexBuffer = (ze_rtas_float3_exp_t*) vertices.data(); out.vertexCount = vertices.size(); out.vertexStride = sizeof(sycl::float3); } } Triangle getTriangle( const uint32_t primID ) const { const sycl::float3 v0 = vertices[triangles[primID].x()]; const sycl::float3 v1 = vertices[triangles[primID].y()]; const sycl::float3 v2 = vertices[triangles[primID].z()]; const uint32_t index = triangles[primID].w(); return Triangle(v0,v1,v2,index); } Bounds3f getBounds( const uint32_t primID ) const { return getTriangle(primID).bounds(); } uint32_t addVertex( const sycl::float3& v ) { auto e = vertex_map.find(v); if (e != vertex_map.end()) return e->second; vertices.push_back(v); vertex_map[v] = vertices.size()-1; return vertices.size()-1; } void addTriangle( const Triangle& tri ) { const uint32_t v0 = addVertex(tri.v0); const uint32_t v1 = addVertex(tri.v1); const uint32_t v2 = addVertex(tri.v2); triangles.push_back(sycl::int4(v0,v1,v2,tri.index)); } void split(const sycl::float3 P, const sycl::float3 N, std::shared_ptr& mesh0, std::shared_ptr& mesh1) { mesh0 = std::shared_ptr(new TriangleMesh(gflags,procedural)); mesh1 = std::shared_ptr(new TriangleMesh(gflags,procedural)); for (uint32_t primID=0; primID<(uint32_t) size(); primID++) { const Triangle tri = getTriangle(primID); if (sycl::dot(tri.center()-P,N) < 0.0f) mesh0->addTriangle(tri); else mesh1->addTriangle(tri); } } void split(std::shared_ptr& mesh0, std::shared_ptr& mesh1) { uint32_t N = (uint32_t) size(); mesh0 = std::shared_ptr(new TriangleMesh(gflags,procedural)); mesh1 = std::shared_ptr(new TriangleMesh(gflags,procedural)); mesh0->triangles.reserve(triangles.size()/2+1); mesh1->triangles.reserve(triangles.size()/2+1); mesh0->vertices.reserve(vertices.size()/2+8); mesh1->vertices.reserve(vertices.size()/2+8); for (uint32_t primID=0; primIDaddTriangle(tri); else mesh1->addTriangle(tri); } } /* selects random sub-set of triangles */ void selectRandom(const uint32_t numTriangles) { assert(numTriangles <= size()); /* first randomize triangles */ for (size_t i=0; i id_stack, uint32_t instUserID, bool procedural_instance, std::vector& tri_map) override { uint32_t instID = -1; uint32_t geomID = -1; if (id_stack.size()) { geomID = id_stack.back(); id_stack.pop_back(); } if (id_stack.size()) { instID = id_stack.back(); id_stack.pop_back(); } assert(id_stack.size() == 0); for (uint32_t primID=0; primID triangles_alloc_ty; triangles_alloc_ty triangles_alloc; std::vector triangles; typedef sycl::usm_allocator vertices_alloc_ty; vertices_alloc_ty vertices_alloc; std::vector vertices; std::map vertex_map; }; template struct InstanceGeometryT : public Geometry { InstanceGeometryT(const Transform& local2world, std::shared_ptr scene, bool procedural, uint32_t instUserID) : Geometry(Type::INSTANCE), procedural(procedural), instUserID(instUserID), local2world(local2world), scene(scene) {} virtual ~InstanceGeometryT() {} void* operator new(size_t size) { return sycl::aligned_alloc_shared(64,size,device,context,sycl::ext::oneapi::property::usm::device_read_only()); } void operator delete(void* ptr) { sycl::free(ptr,context); } static void getBoundsCallback (ze_rtas_geometry_aabbs_exp_cb_params_t* params) { assert(params->stype == ZE_STRUCTURE_TYPE_RTAS_GEOMETRY_AABBS_EXP_CB_PARAMS); assert(params->primID == 0); assert(params->primIDCount == 1); const InstanceGeometryT* inst = (InstanceGeometryT*) params->pGeomUserPtr; const Bounds3f scene_bounds = inst->scene->getBounds(); const Bounds3f bounds = xfmBounds(inst->local2world, scene_bounds); ze_rtas_aabb_exp_t* boundsOut = params->pBoundsOut; boundsOut->lower.x = bounds.lower.x(); boundsOut->lower.y = bounds.lower.y(); boundsOut->lower.z = bounds.lower.z(); boundsOut->upper.x = bounds.upper.x(); boundsOut->upper.y = bounds.upper.y(); boundsOut->upper.z = bounds.upper.z(); } virtual void getDesc(GEOMETRY_DESC* desc) override { if (procedural) { ze_rtas_builder_procedural_geometry_info_exp_t& out = desc->AABBs; memset(&out,0,sizeof(out)); out.geometryType = ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_PROCEDURAL; out.geometryFlags = 0; out.geometryMask = 0xFF; out.primCount = 1; out.pfnGetBoundsCb = InstanceGeometryT::getBoundsCallback; out.pGeomUserPtr = this; } else { GEOMETRY_INSTANCE_DESC& out = desc->Instance; memset(&out,0,sizeof(GEOMETRY_INSTANCE_DESC)); out.geometryType = ZE_RTAS_BUILDER_GEOMETRY_TYPE_EXP_INSTANCE; out.instanceFlags = 0; out.geometryMask = 0xFF; out.instanceUserID = instUserID; out.transformFormat = ZE_RTAS_BUILDER_INPUT_DATA_FORMAT_EXP_FLOAT3X4_ALIGNED_COLUMN_MAJOR; out.pTransform = (float*)&out.xfmdata; out.xfmdata.vx_x = local2world.vx.x(); out.xfmdata.vx_y = local2world.vx.y(); out.xfmdata.vx_z = local2world.vx.z(); out.xfmdata.pad0 = 0.0f; out.xfmdata.vy_x = local2world.vy.x(); out.xfmdata.vy_y = local2world.vy.y(); out.xfmdata.vy_z = local2world.vy.z(); out.xfmdata.pad1 = 0.0f; out.xfmdata.vz_x = local2world.vz.x(); out.xfmdata.vz_y = local2world.vz.y(); out.xfmdata.vz_z = local2world.vz.z(); out.xfmdata.pad2 = 0.0f; out.xfmdata.p_x = local2world.p.x(); out.xfmdata.p_y = local2world.p.y(); out.xfmdata.p_z = local2world.p.z(); out.xfmdata.pad3 = 0.0f; out.pBounds = &scene->bounds; out.pAccelerationStructure = scene->getAccel(); } } virtual void buildAccel(sycl::device& device, sycl::context& context, BuildMode buildMode, ze_rtas_builder_build_quality_hint_exp_t quality) override { scene->buildAccel(device,context,buildMode); } virtual void buildTriMap(Transform local_to_world_in, std::vector id_stack, uint32_t instUserID, bool procedural_instance, std::vector& tri_map) override { instUserID = this->instUserID; scene->buildTriMap(local_to_world_in * local2world, id_stack, instUserID, procedural, tri_map); } size_t getNumPrimitives() const override { return 1; } bool procedural; uint32_t instUserID = -1; Transform local2world; std::shared_ptr scene; }; std::shared_ptr createTrianglePlane (const sycl::float3& p0, const sycl::float3& dx, const sycl::float3& dy, size_t width, size_t height) { std::shared_ptr mesh(new TriangleMesh); mesh->triangles.resize(2*width*height); mesh->vertices.resize((width+1)*(height+1)); for (size_t y=0; y<=height; y++) { for (size_t x=0; x<=width; x++) { sycl::float3 p = p0+float(x)/float(width)*dx+float(y)/float(height)*dy; size_t i = y*(width+1)+x; mesh->vertices[i] = p; } } for (size_t y=0; ytriangles[i+0] = sycl::int4((int)p00,(int)p01,(int)p10,i+0); mesh->triangles[i+1] = sycl::int4((int)p11,(int)p10,(int)p01,i+1); } } return mesh; } void* alloc_accel_buffer_internal(size_t bytes, sycl::device device, sycl::context context) { ze_context_handle_t hContext = sycl::get_native(context); ze_device_handle_t hDevice = sycl::get_native(device); ze_rtas_device_exp_properties_t rtasProp = { ZE_STRUCTURE_TYPE_RTAS_DEVICE_EXP_PROPERTIES }; ze_device_properties_t devProp = { ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES, &rtasProp }; ze_result_t err = ZeWrapper::zeDeviceGetProperties(hDevice, &devProp ); if (err != ZE_RESULT_SUCCESS) throw std::runtime_error("zeDeviceGetProperties failed"); ze_raytracing_mem_alloc_ext_desc_t rt_desc; rt_desc.stype = ZE_STRUCTURE_TYPE_RAYTRACING_MEM_ALLOC_EXT_DESC; rt_desc.pNext = nullptr; rt_desc.flags = 0; ze_device_mem_alloc_desc_t device_desc; device_desc.stype = ZE_STRUCTURE_TYPE_DEVICE_MEM_ALLOC_DESC; device_desc.pNext = &rt_desc; device_desc.flags = ZE_DEVICE_MEM_ALLOC_FLAG_BIAS_CACHED; device_desc.ordinal = 0; ze_host_mem_alloc_desc_t host_desc; host_desc.stype = ZE_STRUCTURE_TYPE_HOST_MEM_ALLOC_DESC; host_desc.pNext = nullptr; host_desc.flags = ZE_HOST_MEM_ALLOC_FLAG_BIAS_CACHED; void* ptr = nullptr; ze_result_t result = ZeWrapper::zeMemAllocShared(hContext,&device_desc,&host_desc,bytes,rtasProp.rtasBufferAlignment,hDevice,&ptr); if (result != ZE_RESULT_SUCCESS) throw std::runtime_error("accel allocation failed"); return ptr; } void free_accel_buffer_internal(void* ptr, sycl::context context) { if (ptr == nullptr) return; ze_context_handle_t hContext = sycl::get_native(context); ze_result_t result = ZeWrapper::zeMemFree(hContext,ptr); if (result != ZE_RESULT_SUCCESS) throw std::runtime_error("accel free failed"); } struct Block { Block (size_t bytes, sycl::device device, sycl::context context) : base((char*)alloc_accel_buffer_internal(bytes,device,context)), total(bytes), cur(0) {} ~Block() { free_accel_buffer_internal((void*)base,context); } void* alloc(size_t bytes) { bytes &= -128; if (cur+bytes > total) return nullptr; void* ptr = &base[cur]; cur += bytes; return ptr; } char* base = nullptr; size_t total = 0; size_t cur = 0; }; bool g_use_accel_blocks = true; std::vector> g_blocks; void* alloc_accel_buffer(size_t bytes, sycl::device device, sycl::context context) { if (!g_use_accel_blocks) return alloc_accel_buffer_internal(bytes,device,context); if (g_blocks.size() == 0) g_blocks.push_back(std::shared_ptr(new Block(1024*1024,device,context))); if (bytes > 1024*1024) { g_blocks.push_back(std::shared_ptr(new Block(bytes,device,context))); void* ptr = g_blocks.back()->alloc(bytes); assert(ptr); return ptr; } void* ptr = g_blocks.back()->alloc(bytes); if (ptr) return ptr; g_blocks.push_back(std::shared_ptr(new Block(1024*1024,device,context))); ptr = g_blocks.back()->alloc(bytes); assert(ptr); return ptr; } void free_accel_buffer(void* ptr, sycl::context context) { if (!g_use_accel_blocks) return free_accel_buffer_internal(ptr,context); } struct Scene { typedef InstanceGeometryT InstanceGeometry; Scene() : geometries_alloc(context,device,sycl::ext::oneapi::property::usm::device_read_only()), geometries(0,geometries_alloc), bounds(Bounds3f::empty()), accel(nullptr) {} Scene(uint32_t width, uint32_t height, bool opaque, bool procedural) : geometries_alloc(context,device,sycl::ext::oneapi::property::usm::device_read_only()), geometries(0,geometries_alloc), bounds(Bounds3f::empty()), accel(nullptr) { std::shared_ptr plane = createTrianglePlane(sycl::float3(0,0,0), sycl::float3(width,0,0), sycl::float3(0,height,0), width, height); plane->gflags = opaque ? (ze_rtas_builder_geometry_exp_flag_t) 0 : ZE_RTAS_BUILDER_GEOMETRY_EXP_FLAG_NON_OPAQUE; plane->procedural = procedural; geometries.push_back(plane); } ~Scene() { free_accel_buffer(accel,context); } void* operator new(size_t size) { return sycl::aligned_alloc_shared(64,size,device,context,sycl::ext::oneapi::property::usm::device_read_only()); } void operator delete(void* ptr) { sycl::free(ptr,context); } void add(std::shared_ptr mesh) { geometries.push_back(mesh); } void splitIntoGeometries(uint32_t numGeometries) { bool progress = true; while (progress) { size_t N = geometries.size(); progress = false; for (uint32_t i=0; i mesh = std::dynamic_pointer_cast(geometries[i])) { if (mesh->size() <= 1) continue; progress = true; /*const Triangle tri = mesh->getTriangle(RandomSampler_getUInt(rng)%mesh->size()); const float u = 2.0f*M_PI*RandomSampler_getFloat(rng); const sycl::float3 P = tri.center(); const sycl::float3 N(cosf(u),sinf(u),0.0f); std::shared_ptr mesh0, mesh1; mesh->split(P,N,mesh0,mesh1);*/ std::shared_ptr mesh0, mesh1; mesh->split(mesh0,mesh1); geometries[i] = std::dynamic_pointer_cast(mesh0); geometries.push_back(std::dynamic_pointer_cast(mesh1)); if (geometries.size() >= numGeometries) return; } } } assert(geometries.size() == numGeometries); } /* splits each primitive into a geometry */ void splitIntoGeometries() { /* count number of triangles */ uint32_t numTriangles = 0; for (uint32_t i=0; i mesh = std::dynamic_pointer_cast(geometries[i])) { numTriangles++; } } std::vector, geometries_alloc_ty> new_geometries(0,geometries_alloc); new_geometries.reserve(numTriangles); for (uint32_t i=0; i mesh = std::dynamic_pointer_cast(geometries[i])) { if (mesh->size() <= 1) { new_geometries.push_back(geometries[i]); continue; } for (uint32_t j=0; jsize(); j++) { std::shared_ptr mesh0(new TriangleMesh(mesh->gflags,mesh->procedural)); mesh0->triangles.reserve(1); mesh->vertices.reserve(3); mesh0->addTriangle(mesh->getTriangle(j)); new_geometries.push_back(mesh0); } } } geometries = new_geometries; } void createInstances(uint32_t maxInstances, uint32_t blockSize = 1, bool procedural = false) { std::vector, geometries_alloc_ty> instances(0,geometries_alloc); for (uint32_t i=0; i= maxInstances) { for (uint32_t j=begin; j scene(new Scene); for (size_t j=begin; jtransform(world2local); scene->geometries.push_back(geometries[j]); } //std::shared_ptr instance = std::make_shared(local2world,scene,procedural); uint32_t instUserID = RandomSampler_getUInt(rng); std::shared_ptr instance(new InstanceGeometry(local2world,scene,procedural,instUserID)); instances.push_back(instance); } geometries = instances; } void mixTrianglesAndProcedurals() { for (uint32_t i=0; i mesh = std::dynamic_pointer_cast(geometries[i])) mesh->procedural = i%2; } void addNullGeometries(uint32_t D) { size_t N = geometries.size(); geometries.resize(N+D); if (N == 0) return; for (size_t g=N; g desc(size()); std::vector geom(size()); size_t numPrimitives = 0; for (size_t geomID=0; geomID& g = geometries[geomID]; /* skip NULL geometries */ if (g == nullptr) { geom[geomID] = nullptr; continue; } numPrimitives += g->getNumPrimitives(); g->buildAccel(device,context,buildMode,quality); g->getDesc(&desc[geomID]); geom[geomID] = (const ze_rtas_builder_geometry_info_exp_t*) &desc[geomID]; } ze_device_handle_t hDevice = sycl::get_native(device); ze_rtas_device_exp_properties_t rtasProp = { ZE_STRUCTURE_TYPE_RTAS_DEVICE_EXP_PROPERTIES }; ze_device_properties_t devProp = { ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES, &rtasProp }; ze_result_t err = ZeWrapper::zeDeviceGetProperties(hDevice, &devProp ); if (err != ZE_RESULT_SUCCESS) throw std::runtime_error("zeDeviceGetProperties failed"); /* estimate accel size */ size_t accelBufferBytesOut = 0; ze_rtas_aabb_exp_t bounds; ze_rtas_builder_build_op_exp_desc_t args; memset(&args,0,sizeof(args)); args.stype = ZE_STRUCTURE_TYPE_RTAS_BUILDER_BUILD_OP_EXP_DESC; args.pNext = nullptr; args.rtasFormat = rtasProp.rtasFormat; args.buildQuality = quality; args.buildFlags = 0; args.ppGeometries = (const ze_rtas_builder_geometry_info_exp_t**) geom.data(); args.numGeometries = geom.size(); /* just for debugging purposes */ #if defined(EMBREE_SYCL_ALLOC_DISPATCH_GLOBALS) ze_rtas_builder_build_op_debug_exp_desc_t buildOpDebug = { ZE_STRUCTURE_TYPE_RTAS_BUILDER_BUILD_OP_DEBUG_EXP_DESC }; buildOpDebug.dispatchGlobalsPtr = dispatchGlobalsPtr; args.pNext = &buildOpDebug; #endif ze_rtas_builder_exp_properties_t size = { ZE_STRUCTURE_TYPE_RTAS_BUILDER_EXP_PROPERTIES }; err = ZeWrapper::zeRTASBuilderGetBuildPropertiesExp(hBuilder,&args,&size); if (err != ZE_RESULT_SUCCESS) throw std::runtime_error("BVH size estimate failed"); if (size.rtasBufferSizeBytesExpected > size.rtasBufferSizeBytesMaxRequired) throw std::runtime_error("expected larger than worst case"); /* allocate scratch buffer */ size_t sentinelBytes = 1024; // add that many zero bytes to catch buffer overruns std::vector scratchBuffer(size.scratchBufferSizeBytes+sentinelBytes); memset(scratchBuffer.data(),0,scratchBuffer.size()); accel = nullptr; size_t accelBytes = 0; /* build with different modes */ switch (buildMode) { case BuildMode::BUILD_WORST_CASE_SIZE: { accelBytes = size.rtasBufferSizeBytesMaxRequired; accel = alloc_accel_buffer(accelBytes+sentinelBytes,device,context); memset(accel,0,accelBytes+sentinelBytes); /* build accel */ double t0 = embree::getSeconds(); size_t numIterations = benchmark ? 16 : 1; for (size_t i=0; ibounds = bounds; if (!benchmark) { /* scratch buffer bounds check */ for (size_t i=size.scratchBufferSizeBytes; i id_stack, uint32_t instUserID, bool procedural_instance, std::vector& tri_map) { for (uint32_t geomID=0; geomIDbuildTriMap(local_to_world,id_stack,instUserID,procedural_instance,tri_map); id_stack.pop_back(); } } size_t size() const { return geometries.size(); } Bounds3f getBounds() { return { { bounds.lower.x, bounds.lower.y, bounds.lower.z }, { bounds.upper.x, bounds.upper.y, bounds.upper.z } }; } void* getAccel() { return accel; } std::shared_ptr operator[] ( size_t i ) { return geometries[i]; } typedef sycl::usm_allocator, sycl::usm::alloc::shared> geometries_alloc_ty; geometries_alloc_ty geometries_alloc; std::vector, geometries_alloc_ty> geometries; ze_rtas_aabb_exp_t bounds; void* accel; }; void exception_handler(sycl::exception_list exceptions) { for (std::exception_ptr const& e : exceptions) { try { std::rethrow_exception(e); } catch(sycl::exception const& e) { std::cout << "Caught asynchronous SYCL exception: " << e.what() << std::endl; } } }; void render(uint32_t i, const TestInput& in, TestOutput& out, intel_raytracing_acceleration_structure_t accel) { intel_raytracing_ext_flag_t flags = intel_get_raytracing_ext_flag(); if (!(flags & intel_raytracing_ext_flag_ray_query)) return; /* setup ray */ intel_ray_desc_t ray; ray.origin = in.org; ray.direction = in.dir; ray.tmin = in.tnear; ray.tmax = in.tfar; ray.mask = in.mask; ray.flags = (intel_ray_flags_t) in.flags; /* trace ray */ intel_ray_query_t query = intel_ray_query_init(ray,accel); intel_ray_query_start_traversal(query); intel_ray_query_sync(query); /* return ray data of level 0 */ out.ray0_org = intel_get_ray_origin(query,0); out.ray0_dir = intel_get_ray_direction(query,0); out.ray0_tnear = intel_get_ray_tmin(query,0); out.ray0_mask = intel_get_ray_mask(query,0); out.ray0_flags = intel_get_ray_flags(query,0); /* clear ray data of level N */ out.rayN_org = sycl::float3(0,0,0); out.rayN_dir = sycl::float3(0,0,0); out.rayN_tnear = 0.0f; out.rayN_mask = 0; out.rayN_flags = 0; /* potential hit */ if (!intel_is_traversal_done(query)) { out.hit_type = TEST_POTENTIAL_HIT; out.bvh_level = intel_get_hit_bvh_level( query, intel_hit_type_potential_hit ); out.hit_candidate = intel_get_hit_candidate( query, intel_hit_type_potential_hit ); out.t = intel_get_hit_distance(query, intel_hit_type_potential_hit); out.u = intel_get_hit_barycentrics(query, intel_hit_type_potential_hit).x; out.v = intel_get_hit_barycentrics(query, intel_hit_type_potential_hit).y; out.front_face = intel_get_hit_front_face( query, intel_hit_type_potential_hit ); out.instUserID = intel_get_hit_instance_user_id( query, intel_hit_type_potential_hit ); out.instID = intel_get_hit_instance_id( query, intel_hit_type_potential_hit ); out.geomID = intel_get_hit_geometry_id( query, intel_hit_type_potential_hit ); if (i%2) out.primID = intel_get_hit_triangle_primitive_id( query, intel_hit_type_potential_hit ); else out.primID = intel_get_hit_primitive_id ( query, intel_hit_type_potential_hit ); intel_float3 vertex_out[3]; intel_get_hit_triangle_vertices(query, vertex_out, intel_hit_type_potential_hit); out.v0 = vertex_out[0]; out.v1 = vertex_out[1]; out.v2 = vertex_out[2]; /* return ray data at current level */ uint32_t bvh_level = intel_get_hit_bvh_level( query, intel_hit_type_potential_hit ); out.rayN_org = intel_get_ray_origin(query,bvh_level); out.rayN_dir = intel_get_ray_direction(query,bvh_level); out.rayN_tnear = intel_get_ray_tmin(query,bvh_level); out.rayN_mask = intel_get_ray_mask(query,bvh_level); out.rayN_flags = intel_get_ray_flags(query,bvh_level); /* return instance transformations */ out.world_to_object = intel_get_hit_world_to_object(query,intel_hit_type_potential_hit); out.object_to_world = intel_get_hit_object_to_world(query,intel_hit_type_potential_hit); } /* committed hit */ else if (intel_has_committed_hit(query)) { out.hit_type = TEST_COMMITTED_HIT; out.bvh_level = intel_get_hit_bvh_level( query, intel_hit_type_committed_hit ); out.hit_candidate = intel_get_hit_candidate( query, intel_hit_type_committed_hit ); out.t = intel_get_hit_distance(query, intel_hit_type_committed_hit); out.u = intel_get_hit_barycentrics(query, intel_hit_type_committed_hit).x; out.v = intel_get_hit_barycentrics(query, intel_hit_type_committed_hit).y; out.front_face = intel_get_hit_front_face( query, intel_hit_type_committed_hit ); out.instUserID = intel_get_hit_instance_user_id( query, intel_hit_type_committed_hit ); out.instID = intel_get_hit_instance_id( query, intel_hit_type_committed_hit ); out.geomID = intel_get_hit_geometry_id( query, intel_hit_type_committed_hit ); if (i%2) out.primID = intel_get_hit_triangle_primitive_id( query, intel_hit_type_committed_hit ); else out.primID = intel_get_hit_primitive_id ( query, intel_hit_type_committed_hit ); intel_float3 vertex_out[3]; intel_get_hit_triangle_vertices(query, vertex_out, intel_hit_type_committed_hit); out.v0 = vertex_out[0]; out.v1 = vertex_out[1]; out.v2 = vertex_out[2]; /* return instance transformations */ out.world_to_object = intel_get_hit_world_to_object(query,intel_hit_type_committed_hit); out.object_to_world = intel_get_hit_object_to_world(query,intel_hit_type_committed_hit); } /* miss */ else { out.hit_type = TEST_MISS; } /* abandon ray query */ intel_ray_query_abandon(query); } void render_loop(uint32_t i, const TestInput& in, TestOutput& out, size_t scene_in, intel_raytracing_acceleration_structure_t accel, TestType test) { intel_raytracing_ext_flag_t flags = intel_get_raytracing_ext_flag(); if (!(flags & intel_raytracing_ext_flag_ray_query)) return; /* setup ray */ intel_ray_desc_t ray; ray.origin = in.org; ray.direction = in.dir; ray.tmin = in.tnear; ray.tmax = in.tfar; ray.mask = in.mask; ray.flags = (intel_ray_flags_t) in.flags; /* trace ray */ intel_ray_query_t query = intel_ray_query_init(ray,accel); intel_ray_query_start_traversal(query); intel_ray_query_sync(query); /* return ray data of level 0 */ out.ray0_org = intel_get_ray_origin(query,0); out.ray0_dir = intel_get_ray_direction(query,0); out.ray0_tnear = intel_get_ray_tmin(query,0); out.ray0_mask = intel_get_ray_mask(query,0); out.ray0_flags = intel_get_ray_flags(query,0); /* clear ray data of level N */ out.rayN_org = sycl::float3(0,0,0); out.rayN_dir = sycl::float3(0,0,0); out.rayN_tnear = 0.0f; out.rayN_mask = 0; out.rayN_flags = 0; Scene* scenes[2]; scenes[0] = (Scene*) scene_in; scenes[1] = nullptr; /* traversal loop */ while (!intel_is_traversal_done(query)) { const intel_candidate_type_t candidate = intel_get_hit_candidate(query, intel_hit_type_potential_hit); if (candidate == intel_candidate_type_triangle) { if (test == TestType::TRIANGLES_POTENTIAL_HIT) { out.hit_type = TEST_POTENTIAL_HIT; out.bvh_level = intel_get_hit_bvh_level( query, intel_hit_type_potential_hit ); out.hit_candidate = intel_get_hit_candidate( query, intel_hit_type_potential_hit ); out.t = intel_get_hit_distance(query, intel_hit_type_potential_hit); out.u = intel_get_hit_barycentrics(query, intel_hit_type_potential_hit).x; out.v = intel_get_hit_barycentrics(query, intel_hit_type_potential_hit).y; out.front_face = intel_get_hit_front_face( query, intel_hit_type_potential_hit ); out.instUserID = intel_get_hit_instance_user_id( query, intel_hit_type_potential_hit ); out.instID = intel_get_hit_instance_id( query, intel_hit_type_potential_hit ); out.geomID = intel_get_hit_geometry_id( query, intel_hit_type_potential_hit ); if (i%2) out.primID = intel_get_hit_triangle_primitive_id( query, intel_hit_type_potential_hit ); else out.primID = intel_get_hit_primitive_id ( query, intel_hit_type_potential_hit ); intel_float3 vertex_out[3]; intel_get_hit_triangle_vertices(query, vertex_out, intel_hit_type_potential_hit); out.v0 = vertex_out[0]; out.v1 = vertex_out[1]; out.v2 = vertex_out[2]; /* return instance transformations */ out.world_to_object = intel_get_hit_world_to_object(query,intel_hit_type_committed_hit); out.object_to_world = intel_get_hit_object_to_world(query,intel_hit_type_committed_hit); /* return ray data at current level */ uint32_t bvh_level = intel_get_hit_bvh_level( query, intel_hit_type_potential_hit ); out.rayN_org = intel_get_ray_origin(query,bvh_level); out.rayN_dir = intel_get_ray_direction(query,bvh_level); out.rayN_tnear = intel_get_ray_tmin(query,bvh_level); out.rayN_mask = intel_get_ray_mask(query,bvh_level); out.rayN_flags = intel_get_ray_flags(query,bvh_level); return; } if (test == TestType::TRIANGLES_ANYHIT_SHADER_COMMIT) intel_ray_query_commit_potential_hit(query); } else if (candidate == intel_candidate_type_procedural) { const uint32_t bvh_level = intel_get_hit_bvh_level( query, intel_hit_type_potential_hit ); const uint32_t instID = intel_get_hit_instance_id( query, intel_hit_type_potential_hit ); const uint32_t geomID = intel_get_hit_geometry_id( query, intel_hit_type_potential_hit ); const uint32_t primID = intel_get_hit_primitive_id( query, intel_hit_type_potential_hit ); Geometry* geom = nullptr; if (instID != -1) { Scene::InstanceGeometry* instance = (Scene::InstanceGeometry*) (scenes[0]->geometries.data() + instID)->get(); geom = (instance->scene->geometries.data() + geomID)->get(); } else { geom = (scenes[bvh_level]->geometries.data() + geomID)->get(); } if (geom->type == Geometry::TRIANGLE_MESH) { const TriangleMesh* mesh = (TriangleMesh*) geom; const sycl::int4 tri = *(mesh->triangles.data() + primID); const sycl::float3 tri_v0 = *(mesh->vertices.data() + tri.x()); const sycl::float3 tri_v1 = *(mesh->vertices.data() + tri.y()); const sycl::float3 tri_v2 = *(mesh->vertices.data() + tri.z()); /* calculate vertices relative to ray origin */ const sycl::float3 O = intel_get_ray_origin(query,bvh_level); const sycl::float3 D = intel_get_ray_direction(query,bvh_level); const float tnear = intel_get_ray_tmin(query,bvh_level); const float tfar = intel_get_hit_distance(query, intel_hit_type_committed_hit); const sycl::float3 v0 = tri_v0-O; const sycl::float3 v1 = tri_v1-O; const sycl::float3 v2 = tri_v2-O; /* calculate triangle edges */ const sycl::float3 e0 = v2-v0; const sycl::float3 e1 = v0-v1; const sycl::float3 e2 = v1-v2; /* perform edge tests */ const float U = sycl::dot(cross(e0,v2+v0),D); const float V = sycl::dot(cross(e1,v0+v1),D); const float W = sycl::dot(cross(e2,v1+v2),D); const float UVW = U+V+W; bool valid = (std::min(U,std::min(V,W)) >= -0.0f) || (std::max(U,std::max(V,W)) <= 0.0f); /* calculate geometry normal and denominator */ const sycl::float3 Ng = sycl::cross(e2,e1); const float den = 2.0f*(dot(Ng,D)); /* perform depth test */ const float T = 2.0f*dot(v0,Ng); const float t = T/den; const float u = U/UVW; const float v = V/UVW; valid &= tnear <= t & t <= tfar; valid &= den != 0.0f; /* commit hit */ if (valid) intel_ray_query_commit_potential_hit_override(query,t,sycl::float2(u,v)); } else if (geom->type == Geometry::INSTANCE) { const Scene::InstanceGeometry* inst = (Scene::InstanceGeometry*) geom; const Transform local2world = inst->local2world; const Transform world2local = rcp(local2world); /* load ray */ const uint32_t bvh_level = intel_get_hit_bvh_level( query, intel_hit_type_potential_hit ); const sycl::float3 O = intel_get_ray_origin(query,bvh_level); const sycl::float3 D = intel_get_ray_direction(query,bvh_level); /* transform ray */ const sycl::float3 O1 = xfmPoint(world2local, O); const sycl::float3 D1 = xfmVector(world2local, D); scenes[bvh_level+1] = inst->scene.get(); intel_raytracing_acceleration_structure_t inst_accel = (intel_raytracing_acceleration_structure_t) inst->scene->getAccel(); /* continue traversal */ intel_ray_desc_t ray; ray.origin = O1; ray.direction = D1; ray.tmin = intel_get_ray_tmin(query,bvh_level); ray.tmax = 0.0f; // unused ray.mask = intel_get_ray_mask(query,bvh_level); ray.flags = intel_get_ray_flags(query,bvh_level); intel_ray_query_forward_ray(query, ray, inst_accel); } } intel_ray_query_start_traversal(query); intel_ray_query_sync(query); } /* committed hit */ if (intel_has_committed_hit(query)) { out.hit_type = TEST_COMMITTED_HIT; out.bvh_level = intel_get_hit_bvh_level( query, intel_hit_type_committed_hit ); out.hit_candidate = intel_get_hit_candidate( query, intel_hit_type_committed_hit ); out.t = intel_get_hit_distance(query, intel_hit_type_committed_hit); out.u = intel_get_hit_barycentrics(query, intel_hit_type_committed_hit).x; out.v = intel_get_hit_barycentrics(query, intel_hit_type_committed_hit).y; out.front_face = intel_get_hit_front_face( query, intel_hit_type_committed_hit ); out.instUserID = intel_get_hit_instance_user_id( query, intel_hit_type_committed_hit ); out.instID = intel_get_hit_instance_id( query, intel_hit_type_committed_hit ); out.geomID = intel_get_hit_geometry_id( query, intel_hit_type_committed_hit ); out.primID = intel_get_hit_primitive_id( query, intel_hit_type_committed_hit ); out.v0 = sycl::float3(0,0,0); out.v1 = sycl::float3(0,0,0); out.v2 = sycl::float3(0,0,0); if (intel_get_hit_candidate( query, intel_hit_type_committed_hit ) == intel_candidate_type_triangle) { intel_float3 vertex_out[3]; intel_get_hit_triangle_vertices(query, vertex_out, intel_hit_type_committed_hit); out.v0 = vertex_out[0]; out.v1 = vertex_out[1]; out.v2 = vertex_out[2]; } /* return instance transformations */ out.world_to_object = intel_get_hit_world_to_object(query,intel_hit_type_committed_hit); out.object_to_world = intel_get_hit_object_to_world(query,intel_hit_type_committed_hit); } /* miss */ else { out.hit_type = TEST_MISS; } /* abandon ray query */ intel_ray_query_abandon(query); } void buildTestExpectedInputAndOutput(std::shared_ptr scene, size_t numTests, TestType test, TestInput* in, TestOutput* out_expected) { std::vector tri_map; tri_map.resize(numTests); std::vector id_stack; Transform local_to_world; scene->buildTriMap(local_to_world,id_stack,-1,false,tri_map); TestHitType hit_type = TEST_MISS; switch (test) { case TestType::TRIANGLES_COMMITTED_HIT: hit_type = TEST_COMMITTED_HIT; break; case TestType::TRIANGLES_POTENTIAL_HIT: hit_type = TEST_POTENTIAL_HIT; break; case TestType::TRIANGLES_ANYHIT_SHADER_COMMIT: hit_type = TEST_COMMITTED_HIT; break; case TestType::TRIANGLES_ANYHIT_SHADER_REJECT: hit_type = TEST_MISS; break; case TestType::PROCEDURALS_COMMITTED_HIT: hit_type = TEST_COMMITTED_HIT; break; default: assert(false); break; }; //for (size_t y=0; y scene = std::make_shared(width,height,opaque,procedural); std::shared_ptr scene(new Scene(width,height,opaque,procedural)); scene->splitIntoGeometries(16); if (inst != InstancingType::NONE) scene->createInstances(scene->size(),3, inst == InstancingType::SW_INSTANCING); scene->addNullGeometries(16); scene->buildAccel(device,context,BuildMode::BUILD_EXPECTED_SIZE,false); /* calculate test input and expected output */ TestInput* in = (TestInput*) sycl::aligned_alloc(64,numTests*sizeof(TestInput),device,context,sycl::usm::alloc::shared); memset(in, 0, numTests*sizeof(TestInput)); TestOutput* out_test = (TestOutput*) sycl::aligned_alloc(64,numTests*sizeof(TestOutput),device,context,sycl::usm::alloc::shared); memset(out_test, 0, numTests*sizeof(TestOutput)); TestOutput* out_expected = (TestOutput*) sycl::aligned_alloc(64,numTests*sizeof(TestOutput),device,context,sycl::usm::alloc::shared); memset(out_expected, 0, numTests*sizeof(TestOutput)); buildTestExpectedInputAndOutput(scene,numTests,test,in,out_expected); /* execute test */ intel_raytracing_acceleration_structure_t accel = (intel_raytracing_acceleration_structure_t) scene->getAccel(); size_t scene_ptr = (size_t) scene.get(); if (inst != InstancingType::SW_INSTANCING && (test == TestType::TRIANGLES_COMMITTED_HIT || test == TestType::TRIANGLES_POTENTIAL_HIT)) { #if defined(ZE_RAYTRACING_RT_SIMULATION) tbb::parallel_for(size_t(0),numTests, [&](size_t i) { render(i,in[i],out_test[i],accel); }); #else queue.submit([&](sycl::handler& cgh) { const sycl::range<1> range(numTests); cgh.parallel_for(range, [=](sycl::item<1> item) { const uint32_t i = item.get_id(0); render(i,in[i],out_test[i],accel); }); }); queue.wait_and_throw(); #endif } else { #if defined(ZE_RAYTRACING_RT_SIMULATION) tbb::parallel_for(size_t(0),numTests, [&](size_t i) { render_loop(i,in[i],out_test[i],scene_ptr,accel,test); }); #else queue.submit([&](sycl::handler& cgh) { const sycl::range<1> range(numTests); cgh.parallel_for(range, [=](sycl::item<1> item) { const uint32_t i = item.get_id(0); render_loop(i,in[i],out_test[i],scene_ptr,accel,test); }); }); queue.wait_and_throw(); #endif } /* verify result */ uint32_t numErrors = 0; for (size_t tid=0; tid plane = createTrianglePlane(sycl::float3(0,0,0), sycl::float3(width,0,0), sycl::float3(0,width,0), width, width); if (test == TestType::BUILD_TEST_PROCEDURALS) plane->procedural = true; plane->selectRandom(numPrimitives); if (testID%2) plane->unshareVertices(); std::shared_ptr scene(new Scene); scene->add(plane); if (test == TestType::BUILD_TEST_PROCEDURALS) { if (testID%3==0) scene->splitIntoGeometries(); } else if (test == TestType::BUILD_TEST_MIXED) { scene->splitIntoGeometries(std::max(1u,std::min(1024u,numPrimitives))); scene->mixTrianglesAndProcedurals(); scene->createInstances(scene->size()/2); } else if (test == TestType::BUILD_TEST_INSTANCES) { scene->splitIntoGeometries(std::max(1u,std::min(1024u,numPrimitives))); scene->createInstances(scene->size()); } scene->addNullGeometries(16); scene->buildAccel(device,context,buildMode,false); /* calculate test input and expected output */ TestInput* in = (TestInput*) sycl::aligned_alloc(64,numPrimitives*sizeof(TestInput),device,context,sycl::usm::alloc::shared); memset(in, 0, numPrimitives*sizeof(TestInput)); TestOutput* out_test = (TestOutput*) sycl::aligned_alloc(64,numPrimitives*sizeof(TestOutput),device,context,sycl::usm::alloc::shared); memset(out_test, 0, numPrimitives*sizeof(TestOutput)); TestOutput* out_expected = (TestOutput*) sycl::aligned_alloc(64,numPrimitives*sizeof(TestOutput),device,context,sycl::usm::alloc::shared); memset(out_expected, 0, numPrimitives*sizeof(TestOutput)); buildTestExpectedInputAndOutput(scene,numPrimitives,TestType::TRIANGLES_COMMITTED_HIT,in,out_expected); /* execute test */ intel_raytracing_acceleration_structure_t accel = (intel_raytracing_acceleration_structure_t) scene->getAccel(); size_t scene_ptr = (size_t) scene.get(); if (numPrimitives) { #if defined(ZE_RAYTRACING_RT_SIMULATION) tbb::parallel_for(size_t(0),size_t(numPrimitives), [&](size_t i) { render_loop(i,in[i],out_test[i],scene_ptr,accel,TestType::TRIANGLES_COMMITTED_HIT); }); #else queue.submit([&](sycl::handler& cgh) { const sycl::range<1> range(numPrimitives); cgh.parallel_for(range, [=](sycl::item<1> item) { const uint32_t i = item.get_id(0); render_loop(i,in[i],out_test[i],scene_ptr,accel,TestType::TRIANGLES_COMMITTED_HIT); }); }); queue.wait_and_throw(); #endif } /* verify result */ uint32_t numErrors = 0; for (size_t tid=0; tid10 ? i*i : i; std::cout << "testing " << numPrimitives << " primitives" << std::endl; numErrors += executeBuildTest(device,queue,context,test,buildMode,numPrimitives,i); } return numErrors; } uint32_t executeBenchmark(sycl::device& device, sycl::queue& queue, sycl::context& context, TestType test) { for (uint32_t i=0; i<=20; i++) { const uint32_t numPrimitives = 1< plane = createTrianglePlane(sycl::float3(0,0,0), sycl::float3(width,0,0), sycl::float3(0,width,0), width, width); if (test == TestType::BENCHMARK_PROCEDURALS) plane->procedural = true; plane->selectSequential(numPrimitives); std::shared_ptr scene(new Scene); scene->add(plane); scene->buildAccel(device,context,BuildMode::BUILD_WORST_CASE_SIZE,true); } return 0; } enum Flags : uint32_t { FLAGS_NONE, DEPTH_TEST_LESS_EQUAL = 1 << 0 // when set we use <= for depth test, otherwise < }; struct DispatchGlobals { uint64_t rtMemBasePtr; // base address of the allocated stack memory uint64_t callStackHandlerKSP; // this is the KSP of the continuation handler that is invoked by BTD when the read KSP is 0 uint32_t asyncStackSize; // async-RT stack size in 64 byte blocks uint32_t numDSSRTStacks : 16; // number of stacks per DSS uint32_t syncRayQueryCount : 4; // number of ray queries in the sync-RT stack: 0-15 mapped to: 1-16 unsigned _reserved_mbz : 12; uint32_t maxBVHLevels; // the maximal number of supported instancing levels (0->8, 1->1, 2->2, ...) Flags flags; // per context control flags }; void* allocDispatchGlobals(sycl::device device, sycl::context context) { size_t maxBVHLevels = 2; //RTC_MAX_INSTANCE_LEVEL_COUNT+1; size_t rtstack_bytes = (64+maxBVHLevels*(64+32)+63)&-64; size_t num_rtstacks = 1<<17; // this is sufficiently large also for PVC size_t dispatchGlobalSize = 128+num_rtstacks*rtstack_bytes; void* dispatchGlobalsPtr = alloc_accel_buffer(dispatchGlobalSize,device,context); memset(dispatchGlobalsPtr, 0, dispatchGlobalSize); DispatchGlobals* dg = (DispatchGlobals*) dispatchGlobalsPtr; dg->rtMemBasePtr = (uint64_t) dispatchGlobalsPtr + dispatchGlobalSize; dg->callStackHandlerKSP = 0; dg->asyncStackSize = 0; dg->numDSSRTStacks = 0; dg->syncRayQueryCount = 0; dg->_reserved_mbz = 0; dg->maxBVHLevels = maxBVHLevels; dg->flags = DEPTH_TEST_LESS_EQUAL; return dispatchGlobalsPtr; } int main(int argc, char* argv[]) { TestType test = TestType::TRIANGLES_COMMITTED_HIT; InstancingType inst = InstancingType::NONE; BuildMode buildMode = BuildMode::BUILD_EXPECTED_SIZE; #if defined(EMBREE_SYCL_L0_RTAS_BUILDER) ZeWrapper::RTAS_BUILD_MODE rtas_build_mode = ZeWrapper::RTAS_BUILD_MODE::AUTO; #else ZeWrapper::RTAS_BUILD_MODE rtas_build_mode = ZeWrapper::RTAS_BUILD_MODE::INTERNAL; #endif bool jit_cache = false; uint32_t numThreads = tbb::this_task_arena::max_concurrency(); /* command line parsing */ if (argc == 1) { std::cout << "ERROR: no test specified" << std::endl; return 1; } /* parse all command line options */ for (size_t i=1; i= argc) throw std::runtime_error("Error: --jit-cache : syntax error"); jit_cache = atoi(argv[i]); } else if (strcmp(argv[i], "--threads") == 0) { if (++i >= argc) throw std::runtime_error("Error: --threads : syntax error"); numThreads = atoi(argv[i]); } else { std::cout << "ERROR: invalid command line option " << argv[i] << std::endl; return 1; } } if (jit_cache) std::cout << "WARNING: JIT caching is not supported!" << std::endl; if (ZeWrapper::init() != ZE_RESULT_SUCCESS) { std::cerr << "ZeWrapper not successfully initialized" << std::endl; return 1; } #if defined(ZE_RAYTRACING_RT_SIMULATION) RTCore::Init(); RTCore::SetXeVersion((RTCore::XeVersion)ZE_RAYTRACING_DEVICE); #endif tbb::global_control tbb_threads(tbb::global_control::max_allowed_parallelism,numThreads); /* initialize SYCL device */ device = sycl::device(sycl::gpu_selector_v); sycl::queue queue = sycl::queue(device,exception_handler); context = queue.get_context(); #if defined(EMBREE_SYCL_ALLOC_DISPATCH_GLOBALS) dispatchGlobalsPtr = allocDispatchGlobals(device,context); #endif /* execute test */ RandomSampler_init(rng,0x56FE238A); sycl::platform platform = device.get_platform(); ze_driver_handle_t hDriver = sycl::get_native(platform); /* enable RTAS extension only when enabled */ if (rtas_build_mode == ZeWrapper::RTAS_BUILD_MODE::AUTO) { uint32_t count = 0; std::vector extensions; ze_result_t result = ZeWrapper::zeDriverGetExtensionProperties(hDriver,&count,extensions.data()); if (result != ZE_RESULT_SUCCESS) throw std::runtime_error("zeDriverGetExtensionProperties failed"); extensions.resize(count); result = ZeWrapper::zeDriverGetExtensionProperties(hDriver,&count,extensions.data()); if (result != ZE_RESULT_SUCCESS) throw std::runtime_error("zeDriverGetExtensionProperties failed"); bool ze_rtas_builder = false; for (uint32_t i=0; i= TestType::BENCHMARK_TRIANGLES) numErrors = executeBenchmark(device,queue,context,test); else if (test >= TestType::BUILD_TEST_TRIANGLES) numErrors = executeBuildTest(device,queue,context,test,buildMode); else numErrors = executeTest(device,queue,context,inst,test); err = ZeWrapper::zeRTASParallelOperationDestroyExp(parallelOperation); if (err != ZE_RESULT_SUCCESS) throw std::runtime_error("parallel operation destruction failed"); /* destroy rtas builder again */ err = ZeWrapper::zeRTASBuilderDestroyExp(hBuilder); if (err != ZE_RESULT_SUCCESS) throw std::runtime_error("ze_rtas_builder destruction failed"); #if defined(EMBREE_SYCL_ALLOC_DISPATCH_GLOBALS) free_accel_buffer(dispatchGlobalsPtr, context); #endif #if defined(ZE_RAYTRACING_RT_SIMULATION) RTCore::Cleanup(); #endif return numErrors ? 1 : 0; } #pragma clang diagnostic pop level-zero-raytracing-support-1.0.0/third-party-programs-TBB.txt000066400000000000000000001336031450534701400247250ustar00rootroot00000000000000oneAPI Threading Building Blocks (oneTBB) Third Party Programs File This file contains the list of third party software ("third party programs") contained in the Intel software and their required notices and/or license terms. This third party software, even if included with the distribution of the Intel software, may be governed by separate license terms, including without limitation, third party license terms, other Intel software license terms, and open source software license terms. These separate license terms govern your use of the third party programs as set forth in the "third-party-programs.txt" or other similarlynamed text file. The third party programs and their corresponding required notices and/or license terms are listed below. _______________________________________________________________________________________________________ 1. Intel(R) Instrumentation and Tracing Technology (ITT) Copyright (c) 2019 Intel Corporation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. _______________________________________________________________________________________________________ 2. ActiveState Thread pool with same API as (multi) processing.Pool (Python recipe): Copyright (c) 2008,2016 david decotigny (this file) Copyright (c) 2006-2008, R Oudkerk (multiprocessing.Pool) Portable Hardware Locality (hwloc) Copyright (c) 2004-2006 The Trustees of Indiana University and Indiana University Research and Technology Corporation. All rights reserved. Copyright (c) 2004-2005 The University of Tennessee and The University of Tennessee Research Foundation. All rights reserved. Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, University of Stuttgart. All rights reserved. Copyright (c) 2004-2005 The Regents of the University of California. All rights reserved. Copyright (c) 2009 CNRS Copyright (c) 2009-2016 Inria. All rights reserved. Copyright (c) 2009-2015 Universit Bordeaux Copyright (c) 2009-2015 Cisco Systems, Inc. All rights reserved. Copyright (c) 2009-2012 Oracle and/or its affiliates. All rights reserved. Copyright (c) 2010 IBM Copyright (c) 2010 Jirka Hladky Copyright (c) 2012 Aleksej Saushev, The NetBSD Foundation Copyright (c) 2012 Blue Brain Project, EPFL. All rights reserved. Copyright (c) 2013-2014 University of Wisconsin-La Crosse. All rights reserved. Copyright (c) 2015 Research Organization for Information Science and Technology (RIST). All rights reserved. Copyright (c) 2015-2016 Intel, Inc. All rights reserved. BSD 3-clause "New" or "Revised" License Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. _______________________________________________________________________________________________________ 3. gperftools: Copyright (c) 2011, Google Inc. Tachyon: Copyright (c) 1994-2008 John E. Stone. All rights reserved. BSD 3-Clause "New" or "Revised" License Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. _______________________________________________________________________________________________________ 4. Mateusz Kwiatkowski Workaround for bug 62258 in libstdc++ GPL 3.0 with GCC Runtime Library Exception 3.1 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (c) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . GCC RUNTIME LIBRARY EXCEPTION Version 3.1, 31 March 2009 Copyright (c) 2009 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This GCC Runtime Library Exception ("Exception") is an additional permission under section 7 of the GNU General Public License, version 3 ("GPLv3"). It applies to a given file (the "Runtime Library") that bears a notice placed by the copyright holder of the file stating that the file is governed by GPLv3 along with this Exception. When you use GCC to compile a program, GCC may combine portions of certain GCC header files and runtime libraries with the compiled program. The purpose of this Exception is to allow compilation of non-GPL (including proprietary) programs to use, in this way, the header files and runtime libraries covered by this Exception. 0. Definitions. A file is an "Independent Module" if it either requires the Runtime Library for execution after a Compilation Process, or makes use of an interface provided by the Runtime Library, but is not otherwise based on the Runtime Library. "GCC" means a version of the GNU Compiler Collection, with or without modifications, governed by version 3 (or a specified later version) of the GNU General Public License (GPL) with the option of using any subsequent versions published by the FSF. "GPL-compatible Software" is software whose conditions of propagation, modification and use would permit combination with GCC in accord with the license of GCC. "Target Code" refers to output from any compiler for a real or virtual target processor architecture, in executable form or suitable for input to an assembler, loader, linker and/or execution phase. Notwithstanding that, Target Code does not include data in any format that is used as a compiler intermediate representation, or used for producing a compiler intermediate representation. The "Compilation Process" transforms code entirely represented in non-intermediate languages designed for human-written code, and/or in Java Virtual Machine byte code, into Target Code. Thus, for example, use of source code generators and preprocessors need not be considered part of the Compilation Process, since the Compilation Process can be understood as starting with the output of the generators or preprocessors. A Compilation Process is "Eligible" if it is done using GCC, alone or with other GPL-compatible software, or if it is done without using any work based on GCC. For example, using non-GPL-compatible Software to optimize any GCC intermediate representations would not qualify as an Eligible Compilation Process. 1. Grant of Additional Permission. You have permission to propagate a work of Target Code formed by combining the Runtime Library with Independent Modules, even if such propagation would otherwise violate the terms of GPLv3, provided that all Target Code was generated by Eligible Compilation Processes. You may then convey such a combination under terms of your choice, consistent with the licensing of the Independent Modules. 2. No Weakening of GCC Copyleft. The availability of this Exception does not imply any general presumption that third-party software is unaffected by the copyleft requirements of the license of GCC. _______________________________________________________________________________________________________ 5. Doctest Copyright (c) 2016-2019 Viktor Kirilov The MIT License (MIT) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. _______________________________________________________________________________________________________ *Other names and brands may be claimed as the property of others. level-zero-raytracing-support-1.0.0/third-party-programs.txt000066400000000000000000000306461450534701400243230ustar00rootroot00000000000000 oneAPI Level Zero Ray Tracing Support Third Party Programs File ================================================================ This file contains the list of third party software (third party programs) contained in the Intel software and their required notices and/or license terms. This third party software, even if included with the distribution of the Intel software, may be governed by separate license terms, including without limitation, third party license terms, other Intel software license terms, and open source software license terms. These separate license terms govern your use of the third party programs as set forth in the third-party-programs.txt or other similarly-named text file. Third party programs and their corresponding required notices and/or license terms are listed below. 1. Apache License 2.0 ------------------------------------------------------------- 1.1. Intel(R) oneAPI Threading Building Blocks (TBB) https://github.com/oneapi-src/oneTBB Copyright Intel Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 12. Additional Third Party Program Files ------------------------------------------------------------- The following third party programs have their own third party program files. These additional third party program files are as follows: 12.1. Intel(R) oneAPI Threading Building Blocks (TBB) third-party-programs-TBB.txt