diff --git a/RenderingToolkit/GettingStarted/03_openvkl_gsg/CMakeLists.txt b/RenderingToolkit/GettingStarted/03_openvkl_gsg/CMakeLists.txt deleted file mode 100644 index 862e41d23d..0000000000 --- a/RenderingToolkit/GettingStarted/03_openvkl_gsg/CMakeLists.txt +++ /dev/null @@ -1,35 +0,0 @@ -cmake_minimum_required(VERSION 3.16) -project(OPENVKL_GSG LANGUAGES C CXX) - -set(ONEAPI_ROOT "") -if(DEFINED ENV{ONEAPI_ROOT}) - set(ONEAPI_ROOT "$ENV{ONEAPI_ROOT}") - message(STATUS "ONEAPI_ROOT FROM ENVIRONMENT: ${ONEAPI_ROOT}") -else() - if(WIN32) - set(ONEAPI_ROOT "C:/Program Files (x86)/Intel/oneAPI") - else() - set(ONEAPI_ROOT /opt/intel/oneapi) - endif() - message(STATUS "ONEAPI_ROOT DEFAULT: ${ONEAPI_ROOT}") -endif(DEFINED ENV{ONEAPI_ROOT}) - -set(OPENVKL_ROOT ${ONEAPI_ROOT}/openvkl/latest) -set(OPENVKL_INCLUDE_DIR ${OPENVKL_ROOT}/include) -message(STATUS "OPENVKL_INCLUDE_DIR: ${OPENVKL_INCLUDE_DIR}") -find_package(openvkl REQUIRED PATHS ${ONEAPI_ROOT}) - -if(MSVC) - set(CMAKE_CXX_STANDARD 11) - set(CMAKE_CXX_STANDARD_REQUIRED ON) - set(CMAKE_CXX_EXTENSIONS OFF) -else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") -endif(MSVC) - -include_directories(${OPENVKL_INCLUDE_DIR}) -link_directories(${OPENVKL_ROOT}/lib) - -add_executable(vklTutorial src/vklTutorial.c) -target_link_libraries(vklTutorial PRIVATE openvkl) -install(TARGETS vklTutorial RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/RenderingToolkit/GettingStarted/03_openvkl_gsg/README.md b/RenderingToolkit/GettingStarted/03_openvkl_gsg/README.md index 5b22f353a1..8aa6b400b0 100644 --- a/RenderingToolkit/GettingStarted/03_openvkl_gsg/README.md +++ b/RenderingToolkit/GettingStarted/03_openvkl_gsg/README.md @@ -5,63 +5,12 @@ high-performance volume computation kernels. Improve performance of volume rendering applications by using performance optimized volume traversal and sampling functionality for a variety of data formats. -| Minimum Requirements | Description -|:--- |:--- -| OS | Linux* Ubuntu* 18.04
CentOS 8 (or compatible)
Windows* 10
macOS* 10.15+ -| Hardware | Intel 64 Penryn or newer with SSE4.1 extensions, ARM64 with NEON extensions
(Optimized requirements: Intel 64 Skylake or newer with AVX512 extentions, ARM64 with NEON extensions) -| Compiler Toolchain | Windows OS: MSVS 2019 installed with Windows* SDK and CMake*; Other platforms: C++11 compiler, a C99 compiler (for example. gcc/c++/clang), and CMake* -| Libraries | Install Intel® oneAPI Rendering Toolkit (Render Kit), including Intel® Embree and Intel® Open VKL +## Versions -| Objective | Description -|:--- |:--- -| What you will learn | How to build and run a basic rendering program using the Intel® Open VKL API from the Render Kit. -| Time to complete | 5 minutes - -## Purpose - -This sample program, `vklTutorial`, shows sampling amongst a proceedurally -generated volume the different volumetric sampling capabilities with Intel® -Open VKL. Output is written to the console (stdout). - -## Key Implementation Details - -`vklTutorial` is written in C99 and is constructed to compile with a C++ or C99 -compiler. - -## Build and Run - -### Windows - -1. Run a new **x64 Native Tools Command Prompt for MSVS 2019**. - -``` -call \setvars.bat -cd \RenderingToolkit\GettingStarted\03_openvkl_gsg -mkdir build -cd build -cmake .. -cmake --build . --config Release -cd Release -vklTutorial.exe -``` - -2. Review the terminal output (stdout). - - -### Linux and macOS - -1. Start a new Terminal session. -``` -source /setvars.sh -cd /RenderingToolkit/GettingStarted/03_openvkl_gsg -mkdir build -cd build -cmake .. -cmake --build . -./vklTutorial -``` - -2. Review the terminal output (stdout). +1. [CPU](./cpu/) - for Intel64 (x86-64) Host +- This version of the `vklTutorialCPU` program uses a C++11 (or C99) system compiler to target the host processor. +2. [GPU](./gpu/) - for Intel® Arc™ Graphics, Intel® Data Center Flex Series, or Intel® Data Center Max Series or higher (Xe-HPG, DG2-128, DG2-512 or higher) +- This `vklTutorialGPU` program uses Intel® oneAPI DPC/C++ Compiler and SYCL* Runtimes to target the GPU. ## License @@ -70,4 +19,4 @@ This code sample is licensed under the Apache 2.0 license. See [LICENSE.txt](LICENSE.txt) for details. Third party program Licenses can be found here: -[third-party-programs.txt](https://github.com/oneapi-src/oneAPI-samples/blob/master/third-party-programs.txt). \ No newline at end of file +[third-party-programs.txt](https://github.com/oneapi-src/oneAPI-samples/blob/master/third-party-programs.txt). diff --git a/RenderingToolkit/GettingStarted/03_openvkl_gsg/cpu/CMakeLists.txt b/RenderingToolkit/GettingStarted/03_openvkl_gsg/cpu/CMakeLists.txt new file mode 100644 index 0000000000..676a8956e3 --- /dev/null +++ b/RenderingToolkit/GettingStarted/03_openvkl_gsg/cpu/CMakeLists.txt @@ -0,0 +1,31 @@ +cmake_minimum_required(VERSION 3.16) +project(OPENVKL_CPU_GSG LANGUAGES C CXX) + +set(ONEAPI_ROOT "") +if(DEFINED ENV{ONEAPI_ROOT}) + set(ONEAPI_ROOT "$ENV{ONEAPI_ROOT}") + message(STATUS "ONEAPI_ROOT FROM ENVIRONMENT: ${ONEAPI_ROOT}") +else() + message(FATAL_ERROR "ONEAPI_ROOT DEFAULT: ${ONEAPI_ROOT}") +endif(DEFINED ENV{ONEAPI_ROOT}) + +set(OPENVKL_BASE_DIR "") +if(EXISTS ${ONEAPI_ROOT}/oneapi-vars.sh OR EXISTS ${ONEAPI_ROOT}/oneapi-vars.bat) + set(OPENVKL_BASE_DIR ${ONEAPI_ROOT}) +else() + set(OPENVKL_BASE_DIR ${ONEAPI_ROOT}/openvkl/latest) +endif(EXISTS ${ONEAPI_ROOT}/oneapi-vars.sh OR EXISTS ${ONEAPI_ROOT}/oneapi-vars.bat) + +find_package(openvkl REQUIRED PATHS ${ONEAPI_ROOT}) + +if(MSVC) + set(CMAKE_CXX_STANDARD 11) + set(CMAKE_CXX_STANDARD_REQUIRED ON) + set(CMAKE_CXX_EXTENSIONS OFF) +else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") +endif(MSVC) + +add_executable(vklTutorialCPU src/vklTutorialCPU.c) +target_link_libraries(vklTutorialCPU PRIVATE openvkl::openvkl openvkl::openvkl_module_cpu_device) +install(TARGETS vklTutorialCPU RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/RenderingToolkit/GettingStarted/03_openvkl_gsg/cpu/README.md b/RenderingToolkit/GettingStarted/03_openvkl_gsg/cpu/README.md new file mode 100644 index 0000000000..05e42385b9 --- /dev/null +++ b/RenderingToolkit/GettingStarted/03_openvkl_gsg/cpu/README.md @@ -0,0 +1,75 @@ +# Getting Started Sample for Intel® Rendering Toolkit (Render Kit): Intel® Open Volume Kernel Library (Intel® Open VKL) on CPU + +Intel® Open Volume Kernel Library (Intel® Open VKL) is a collection of +high-performance volume computation kernels. Improve performance of volume +rendering applications by using performance optimized volume traversal and +sampling functionality for a variety of data formats. + +| Minimum Requirements | Description +|:--- |:--- +| OS | Linux* Ubuntu* 22.04
CentOS 8 (or compatible)
Windows* 10 or 11
macOS* 10.15+ +| Hardware | Intel 64 Penryn or newer with SSE4.1 extensions, ARM64 with NEON extensions
(Optimized requirements: Intel 64 Skylake or newer with AVX512 extentions, ARM64 with NEON extensions) +| Compiler Toolchain | Windows OS: MSVS 2022 (or 2019) installed with Windows* SDK and CMake*; Other platforms: C++11 compiler, a C99 compiler (for example. gcc/c++/clang), and CMake* +| Libraries | Install Intel® Rendering Toolkit (Render Kit), including Intel® Embree and Intel® Open VKL + +| Objective | Description +|:--- |:--- +| What you will learn | How to build and run a basic rendering program using the Intel® Open VKL API from the Render Kit. +| Time to complete | 5 minutes + +## Purpose + +This sample program, `vklTutorialCPU`, shows sampling amongst a proceedurally +generated volume the different volumetric sampling capabilities with Intel® +Open VKL. Output is written to the console (stdout). + +## Key Implementation Details + +`vklTutorialCPU` is written in C99 and is constructed to compile with a C++ or C99 +compiler. + +## Build and Run + +### Windows + +1. Run a new **x64 Native Tools Command Prompt for MSVS 2022**. + +``` +call \setvars.bat +cd \RenderingToolkit\GettingStarted\03_openvkl_gsg +mkdir build +cd build +cmake .. +cmake --build . --config Release +cd Release +vklTutorialCPU.exe +``` + +Note: MSVS 2019 should use an **x64 Native Tools Command Prompt for MSVS 2019** + +2. Review the terminal output (stdout). + + +### Linux and macOS + +1. Start a new Terminal session. +``` +source /setvars.sh +cd /RenderingToolkit/GettingStarted/03_openvkl_gsg +mkdir build +cd build +cmake -DCMAKE_BUILD_TYPE=Release .. +cmake --build . +./vklTutorialCPU +``` + +2. Review the terminal output (stdout). + + +## License + +This code sample is licensed under the Apache 2.0 license. See +[LICENSE.txt](LICENSE.txt) for details. + +Third party program Licenses can be found here: +[third-party-programs.txt](https://github.com/oneapi-src/oneAPI-samples/blob/master/third-party-programs.txt). diff --git a/RenderingToolkit/GettingStarted/03_openvkl_gsg/src/vklTutorial.c b/RenderingToolkit/GettingStarted/03_openvkl_gsg/cpu/src/vklTutorialCPU.c similarity index 89% rename from RenderingToolkit/GettingStarted/03_openvkl_gsg/src/vklTutorial.c rename to RenderingToolkit/GettingStarted/03_openvkl_gsg/cpu/src/vklTutorialCPU.c index 438ece4447..91212f31ec 100644 --- a/RenderingToolkit/GettingStarted/03_openvkl_gsg/src/vklTutorial.c +++ b/RenderingToolkit/GettingStarted/03_openvkl_gsg/cpu/src/vklTutorialCPU.c @@ -1,7 +1,8 @@ -// Copyright 2019-2021 Intel Corporation +// Copyright 2019 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include +#include #include #if defined(_MSC_VER) @@ -39,8 +40,8 @@ void demoScalarAPI(VKLDevice device, VKLVolume volume) { // sample, gradient (first attribute) unsigned int attributeIndex = 0; float time = 0.f; - float sample = vklComputeSample(sampler, &coord, attributeIndex, time); - vkl_vec3f grad = vklComputeGradient(sampler, &coord, attributeIndex, time); + float sample = vklComputeSample(&sampler, &coord, attributeIndex, time); + vkl_vec3f grad = vklComputeGradient(&sampler, &coord, attributeIndex, time); printf("\tsampling and gradient computation (first attribute)\n"); printf("\t\tsample = %f\n", sample); printf("\t\tgrad = %f %f %f\n\n", grad.x, grad.y, grad.z); @@ -49,7 +50,7 @@ void demoScalarAPI(VKLDevice device, VKLVolume volume) { unsigned int M = 3; unsigned int attributeIndices[] = {0, 1, 2}; float samples[3]; - vklComputeSampleM(sampler, &coord, samples, M, attributeIndices, time); + vklComputeSampleM(&sampler, &coord, samples, M, attributeIndices, time); printf("\tsampling (multiple attributes)\n"); printf("\t\tsamples = %f %f %f\n\n", samples[0], samples[1], samples[2]); @@ -99,12 +100,12 @@ void demoScalarAPI(VKLDevice device, VKLVolume volume) { #if defined(_MSC_VER) // MSVC does not support variable length arrays, but provides a // safer version of alloca. - char *buffer = _malloca(vklGetIntervalIteratorSize(intervalContext)); + char *buffer = _malloca(vklGetIntervalIteratorSize(&intervalContext)); #else - char buffer[vklGetIntervalIteratorSize(intervalContext)]; + char buffer[vklGetIntervalIteratorSize(&intervalContext)]; #endif VKLIntervalIterator intervalIterator = vklInitIntervalIterator( - intervalContext, &rayOrigin, &rayDirection, &rayTRange, time, buffer); + &intervalContext, &rayOrigin, &rayDirection, &rayTRange, time, buffer); printf("\n\tinterval iterator for value ranges {%f %f} {%f %f}\n", ranges[0].lower, ranges[0].upper, ranges[1].lower, ranges[1].upper); @@ -130,12 +131,12 @@ void demoScalarAPI(VKLDevice device, VKLVolume volume) { #if defined(_MSC_VER) // MSVC does not support variable length arrays, but provides a // safer version of alloca. - char *buffer = _malloca(vklGetHitIteratorSize(hitContext)); + char *buffer = _malloca(vklGetHitIteratorSize(&hitContext)); #else - char buffer[vklGetHitIteratorSize(hitContext)]; + char buffer[vklGetHitIteratorSize(&hitContext)]; #endif VKLHitIterator hitIterator = vklInitHitIterator( - hitContext, &rayOrigin, &rayDirection, &rayTRange, time, buffer); + &hitContext, &rayOrigin, &rayDirection, &rayTRange, time, buffer); printf("\thit iterator for values %f %f\n", values[0], values[1]); @@ -182,8 +183,8 @@ void demoVectorAPI(VKLVolume volume) { float time4[4] = {0.f}; float sample4[4]; vkl_vvec3f4 grad4; - vklComputeSample4(valid, sampler, &coord4, sample4, attributeIndex, time4); - vklComputeGradient4(valid, sampler, &coord4, &grad4, attributeIndex, time4); + vklComputeSample4(valid, &sampler, &coord4, sample4, attributeIndex, time4); + vklComputeGradient4(valid, &sampler, &coord4, &grad4, attributeIndex, time4); printf("\n\tsampling and gradient computation (first attribute)\n"); @@ -197,7 +198,7 @@ void demoVectorAPI(VKLVolume volume) { unsigned int M = 3; unsigned int attributeIndices[] = {0, 1, 2}; float samples[3 * 4]; - vklComputeSampleM4(valid, sampler, &coord4, samples, M, attributeIndices, + vklComputeSampleM4(valid, &sampler, &coord4, samples, M, attributeIndices, time4); printf("\n\tsampling (multiple attributes)\n"); @@ -240,8 +241,8 @@ void demoStreamAPI(VKLVolume volume) { float time[5] = {0.f}; float sample[5]; vkl_vec3f grad[5]; - vklComputeSampleN(sampler, 5, coord, sample, attributeIndex, time); - vklComputeGradientN(sampler, 5, coord, grad, attributeIndex, time); + vklComputeSampleN(&sampler, 5, coord, sample, attributeIndex, time); + vklComputeGradientN(&sampler, 5, coord, grad, attributeIndex, time); for (int i = 0; i < 5; i++) { printf("\t\tsample[%d] = %f\n", i, sample[i]); @@ -252,7 +253,7 @@ void demoStreamAPI(VKLVolume volume) { unsigned int M = 3; unsigned int attributeIndices[] = {0, 1, 2}; float samples[3 * 5]; - vklComputeSampleMN(sampler, 5, coord, samples, M, attributeIndices, time); + vklComputeSampleMN(&sampler, 5, coord, samples, M, attributeIndices, time); printf("\n\tsampling (multiple attributes)\n"); @@ -271,7 +272,7 @@ void demoStreamAPI(VKLVolume volume) { } int main() { - vklLoadModule("cpu_device"); + vklInit(); VKLDevice device = vklNewDevice("cpu"); vklCommitDevice(device); diff --git a/RenderingToolkit/GettingStarted/03_openvkl_gsg/gpu/CMakeLists.txt b/RenderingToolkit/GettingStarted/03_openvkl_gsg/gpu/CMakeLists.txt new file mode 100644 index 0000000000..189de83e09 --- /dev/null +++ b/RenderingToolkit/GettingStarted/03_openvkl_gsg/gpu/CMakeLists.txt @@ -0,0 +1,77 @@ +cmake_minimum_required(VERSION 3.25) +project(OPENVKL_GPU_GSG LANGUAGES CXX) + +set(ONEAPI_ROOT "") +if(DEFINED ENV{ONEAPI_ROOT}) + set(ONEAPI_ROOT "$ENV{ONEAPI_ROOT}") + message(STATUS "ONEAPI_ROOT FROM ENVIRONMENT: ${ONEAPI_ROOT}") +else() + message(FATAL_ERROR "ONEAPI_ROOT NOT set. Please source environment variables.") +endif(DEFINED ENV{ONEAPI_ROOT}) + +#lots of helper variables to get access to other components +set(OPENVKL_BASE_DIR "") +set(COMPILER_SYCL_INCLUDE "") +set(COMPILER_CL_INCLUDE "") +set(COMPILER_PATH "") +set(RKCOMMON_BASE_DIR "") +set(ISPCRT_BASE_DIR "") +set(TBB_BASE_DIR "") +set(EMBREE_BASE_DIR "") +if(EXISTS ${ONEAPI_ROOT}/oneapi-vars.sh OR EXISTS ${ONEAPI_ROOT}/oneapi-bars.bat) + set(OPENVKL_BASE_DIR ${ONEAPI_ROOT}) + set(RKCOMMON_BASE_DIR ${ONEAPI_ROOT}) + set(ISPCRT_BASE_DIR ${ONEAPI_ROOT}) + set(TBB_BASE_DIR ${ONEAPI_ROOT}) + set(EMBREE_BASE_DIR ${ONEAPI_ROOT}) + if(MSVC) + + set(COMPILER_SYCL_INCLUDE ${ONEAPI_ROOT}/include) + set(COMPILER_CL_INCLUDE ${ONEAPI_ROOT}/include/sycl) + # set(ONEAPI_INCLUDE_DIR ${ONEAPI_ROOT}/include + set(COMPILER_PATH ${ONEAPI_ROOT}/bin/compiler) + else() + set(COMPILER_SYCL_INCLUDE ${ONEAPI_ROOT}/opt/compiler/include/sycl) + set(COMPILER_CL_INCLUDE ${ONEAPI_ROOT}/opt/compiler/include/sycl/sycl) + # set(ONEAPI_INCLUDE_DIR ${ONEAPI_ROOT}/include + set(COMPILER_PATH ${ONEAPI_ROOT}/bin/compiler) + endif(MSVC) + +else() + set(OPENVKL_BASE_DIR ${ONEAPI_ROOT}/openvkl/latest) + set(RKCOMMON_BASE_DIR ${ONEAPI_ROOT}/rkcommon/latest) + set(ISPCRT_BASE_DIR ${ONEAPI_ROOT}/ispc/latest) + set(TBB_BASE_DIR ${ONEAPI_ROOT}/tbb/latest) + set(EMBREE_BASE_DIR ${ONEAPI_ROOT}/embree/latest) + if(MSVC) + set(COMPILER_SYCL_INCLUDE ${ONEAPI_ROOT}/compiler/latest/include) + set(COMPILER_CL_INCLUDE ${ONEAPI_ROOT}/compiler/latest/include/sycl) + set(COMPILER_PATH ${ONEAPI_ROOT}/compiler/latest/bin/compiler) + else() + set(COMPILER_SYCL_INCLUDE ${ONEAPI_ROOT}/compiler/latest/linux/include) + set(COMPILER_CL_INCLUDE ${ONEAPI_ROOT}/compiler/latest/linux/include/sycl) + set(COMPILER_PATH ${ONEAPI_ROOT}/compiler/latest/bin/compiler) + endif(MSVC) +endif(EXISTS ${ONEAPI_ROOT}/oneapi-vars.sh OR EXISTS ${ONEAPI_ROOT}/oneapi-bars.bat) + +if(NOT DEFINED CMAKE_CXX_COMPILER) + message(FATAL_ERROR "CMAKE_CXX_COMPILER not set use icpx") +endif(NOT DEFINED CMAKE_CXX_COMPILER) + +set(OPENVKL_INCLUDE_DIR ${OPENVKL_BASE_DIR}/include) +#target headers +set(OPENVKL_GPU_INCLUDE_DIR ${OPENVKL_INCLUDE_DIR}/openvkl/devices/gpu) + +find_package(openvkl 2.0 REQUIRED PATHS ${OPENVKL_BASE_DIR}) + +find_package(rkcommon REQUIRED PATHS ${RKCOMMON_BASE_DIR}) + +find_package(TBB REQUIRED PATHS ${TBB_BASE_DIR}/lib/cmake/tbb) + +find_package(embree 4.0 REQUIRED PATHS ${EMBREE_BASE_DIR}) + +link_directories(${OPENVKL_BASE_DIR}/lib ${RKCOMMON_BASE_DIR}/lib ${ISPCRT_BASE_DIR}/lib) + +add_executable(vklTutorialGPU src/vklTutorialGPU.cpp) +target_link_libraries(vklTutorialGPU PRIVATE openvkl::openvkl openvkl::openvkl_module_gpu_device rkcommon ispcrt tbb embree) +install(TARGETS vklTutorialGPU RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/RenderingToolkit/GettingStarted/03_openvkl_gsg/gpu/README.md b/RenderingToolkit/GettingStarted/03_openvkl_gsg/gpu/README.md new file mode 100644 index 0000000000..876cf02976 --- /dev/null +++ b/RenderingToolkit/GettingStarted/03_openvkl_gsg/gpu/README.md @@ -0,0 +1,76 @@ +# Getting Started Sample for Intel® Rendering Toolkit (Render Kit): Intel® Open Volume Kernel Library (Intel® Open VKL) for GPU + +Intel® Open Volume Kernel Library (Intel® Open VKL) is a collection of +high-performance volume computation kernels. Improve performance of volume +rendering applications by using performance optimized volume traversal and +sampling functionality for a variety of data formats. + +| Minimum Requirements | Description +|:--- |:--- +| OS | Linux* Ubuntu* 22.04
CentOS 8 (or compatible)
Windows* 10 or 11 +| Hardware | Intel® Arc Graphics (Xe-HPG architecture, DG2-128, DG2-512) or higher +| Compiler Toolchain | Windows OS: MSVS 2022 (or 2019) installed with Windows* SDK and CMake*; All Platforms: Intel® oneAPI DPC++ Compiler from the Intel® oneAPI Base Toolkit +| SYCL Compiler | oneAPI DPC++ 2024.0.0 compiler or higher +| Libraries | Install Intel® Rendering Toolkit (Render Kit), including Intel® Embree and Intel® Open VKL +| Knowledge | First, build and run the [CPU](../cpu) get started program `vklTutorialCPU` + +| Objective | Description +|:--- |:--- +| What you will learn | How to build and run a basic rendering program using the Intel® Open VKL API from the Render Kit targeting GPU +| Time to complete | 5 minutes + +## Purpose + +This sample program, `vklTutorialGPU`, shows sampling amongst a proceedurally +generated volume the different volumetric sampling capabilities with Intel® +Open VKL. Output is written to the console (stdout). + +## Key Implementation Details + +`vklTutorialGPU` is written for C++17 with SYCL. It is constructed to build with the Intel® oneAPI DPC++ Compiler. On Windows* OS it must also build with MSVS system libraries. + +## Build and Run + +### Windows + +1. Run a new **x64 Native Tools Command Prompt for MSVS 2022**. + +``` +call \setvars.bat +cd \RenderingToolkit\GettingStarted\03_openvkl_gsg\gpu +mkdir build +cd build +cmake -G"NMake Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER=icx-cl .. +cmake --build . --config Release +cd Release +.\vklTutorialGPU.exe +``` + +Note: MSVS 2019 users should use a **x64 Native Tools Command Prompt for MSVS 2019** + +2. Review the terminal output (stdout). + + +### Linux + +1. Start a new Terminal session. +``` +source /setvars.sh +cd /RenderingToolkit/GettingStarted/03_openvkl_gsg/gpu +mkdir build +cd build +cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER=icpx .. +cmake --build . +./vklTutorialGPU +``` + +2. Review the terminal output (stdout). + + +## License + +This code sample is licensed under the Apache 2.0 license. See +[LICENSE.txt](LICENSE.txt) for details. + +Third party program Licenses can be found here: +[third-party-programs.txt](https://github.com/oneapi-src/oneAPI-samples/blob/master/third-party-programs.txt). diff --git a/RenderingToolkit/GettingStarted/03_openvkl_gsg/gpu/src/vklTutorialGPU.cpp b/RenderingToolkit/GettingStarted/03_openvkl_gsg/gpu/src/vklTutorialGPU.cpp new file mode 100644 index 0000000000..25583d00a0 --- /dev/null +++ b/RenderingToolkit/GettingStarted/03_openvkl_gsg/gpu/src/vklTutorialGPU.cpp @@ -0,0 +1,379 @@ +// Copyright 2022 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + + +#include +#include + +#include +#include + +// setup specialization constant for feature flags +static_assert(std::is_trivially_copyable::value); + +constexpr static sycl::specialization_id samplerSpecId{ + VKL_FEATURE_FLAGS_DEFAULT}; + +void demoGpuAPI(sycl::queue &syclQueue, VKLDevice device, VKLVolume volume) { + std::cout << "demo of GPU API" << std::endl; + + std::cout << std::fixed << std::setprecision(6); + + VKLSampler sampler = vklNewSampler(volume); + vklCommit(sampler); + + // feature flags improve performance on GPU, as well as JIT times + const VKLFeatureFlags requiredFeatures = vklGetFeatureFlags(sampler); + + // bounding box + vkl_box3f bbox = vklGetBoundingBox(volume); + std::cout << "\tbounding box" << std::endl; + std::cout << "\t\tlower = " << bbox.lower.x << " " << bbox.lower.y << " " + << bbox.lower.z << std::endl; + std::cout << "\t\tupper = " << bbox.upper.x << " " << bbox.upper.y << " " + << bbox.upper.z << std::endl + << std::endl; + + // number of attributes + unsigned int numAttributes = vklGetNumAttributes(volume); + std::cout << "\tnum attributes = " << numAttributes << std::endl; + + // value range for all attributes + for (unsigned int i = 0; i < numAttributes; i++) { + vkl_range1f valueRange = vklGetValueRange(volume, i); + std::cout << "\tvalue range (attribute " << i << ") = (" << valueRange.lower + << " " << valueRange.upper << ")" << std::endl; + } + + std::cout << std::endl << "\tsampling" << std::endl; + + // coordinate for sampling / gradients + vkl_vec3f coord = {1.f, 2.f, 3.f}; + std::cout << "\n\tcoord = " << coord.x << " " << coord.y << " " << coord.z + << std::endl + << std::endl; + + // sample, gradient (first attribute) + const unsigned int attributeIndex = 0; + const float time = 0.f; + + // USM shared allocations, required when we want to pass results back from GPU + float *sample = sycl::malloc_shared(1, syclQueue); + vkl_vec3f *grad = sycl::malloc_shared(1, syclQueue); + + syclQueue + .submit([=](sycl::handler &cgh) { + cgh.set_specialization_constant(requiredFeatures); + + cgh.single_task([=](sycl::kernel_handler kh) { + const VKLFeatureFlags featureFlags = + kh.get_specialization_constant(); + + *sample = vklComputeSample(&sampler, &coord, attributeIndex, time, + featureFlags); + *grad = vklComputeGradient(&sampler, &coord, attributeIndex, time, + featureFlags); + }); + }) + .wait(); + + std::cout << "\tsampling and gradient computation (first attribute)" + << std::endl; + std::cout << "\t\tsample = " << *sample << std::endl; + std::cout << "\t\tgrad = " << grad->x << " " << grad->y << " " << grad->z + << std::endl + << std::endl; + + sycl::free(sample, syclQueue); + sycl::free(grad, syclQueue); + + // sample (multiple attributes) + const unsigned int M = 3; + const unsigned int attributeIndices[] = {0, 1, 2}; + + float *samples = sycl::malloc_shared(M, syclQueue); + + syclQueue + .submit([=](sycl::handler &cgh) { + cgh.set_specialization_constant(requiredFeatures); + + cgh.single_task([=](sycl::kernel_handler kh) { + const VKLFeatureFlags featureFlags = + kh.get_specialization_constant(); + + vklComputeSampleM(&sampler, &coord, samples, M, attributeIndices, + time, featureFlags); + }); + }) + .wait(); + + std::cout << "\tsampling (multiple attributes)" << std::endl; + std::cout << "\t\tsamples = " << samples[0] << " " << samples[1] << " " + << samples[2] << std::endl; + + sycl::free(samples, syclQueue); + + // interval iterator context setup + std::cout << std::endl << "\tinterval iteration" << std::endl << std::endl; + + std::vector ranges{{10, 20}, {50, 75}}; + VKLData rangesData = + vklNewData(device, ranges.size(), VKL_BOX1F, ranges.data()); + + VKLIntervalIteratorContext intervalContext = + vklNewIntervalIteratorContext(sampler); + + vklSetInt(intervalContext, "attributeIndex", 0); + + vklSetData(intervalContext, "valueRanges", rangesData); + vklRelease(rangesData); + + vklCommit(intervalContext); + + // ray definition for iterators + vkl_vec3f rayOrigin{0.f, 1.f, 1.f}; + vkl_vec3f rayDirection{1.f, 0.f, 0.f}; + vkl_range1f rayTRange{0.f, 200.f}; + std::cout << "\trayOrigin = " << rayOrigin.x << " " << rayOrigin.y << " " + << rayOrigin.z << std::endl; + std::cout << "\trayDirection = " << rayDirection.x << " " << rayDirection.y + << " " << rayDirection.z << std::endl; + std::cout << "\trayTRange = " << rayTRange.lower << " " << rayTRange.upper + << std::endl + << std::endl; + + // interval iteration + char *iteratorBuffer = sycl::malloc_device( + vklGetIntervalIteratorSize(&intervalContext), syclQueue); + + int *numIntervals = sycl::malloc_shared(1, syclQueue); + *numIntervals = 0; + + const size_t maxNumIntervals = 999; + + VKLInterval *intervalsBuffer = + sycl::malloc_shared(maxNumIntervals, syclQueue); + memset(intervalsBuffer, 0, maxNumIntervals * sizeof(VKLInterval)); + + std::cout << "\tinterval iterator for value ranges"; + + for (const auto &r : ranges) { + std::cout << " {" << r.lower << " " << r.upper << "}"; + } + std::cout << std::endl << std::endl; + + syclQueue + .submit([=](sycl::handler &cgh) { + cgh.set_specialization_constant(requiredFeatures); + + cgh.single_task([=](sycl::kernel_handler kh) { + const VKLFeatureFlags featureFlags = + kh.get_specialization_constant(); + + VKLIntervalIterator intervalIterator = vklInitIntervalIterator( + &intervalContext, &rayOrigin, &rayDirection, &rayTRange, time, + (void *)iteratorBuffer, featureFlags); + + for (;;) { + VKLInterval interval; + int result = + vklIterateInterval(intervalIterator, &interval, featureFlags); + if (!result) { + break; + } + intervalsBuffer[*numIntervals] = interval; + + *numIntervals = *numIntervals + 1; + if (*numIntervals >= maxNumIntervals) break; + } + }); + }) + .wait(); + + for (int i = 0; i < *numIntervals; ++i) { + std::cout << "\t\ttRange (" << intervalsBuffer[i].tRange.lower << " " + << intervalsBuffer[i].tRange.upper << ")" << std::endl; + std::cout << "\t\tvalueRange (" << intervalsBuffer[i].valueRange.lower + << " " << intervalsBuffer[i].valueRange.upper << ")" << std::endl; + std::cout << "\t\tnominalDeltaT " << intervalsBuffer[i].nominalDeltaT + << std::endl + << std::endl; + } + + sycl::free(iteratorBuffer, syclQueue); + sycl::free(numIntervals, syclQueue); + sycl::free(intervalsBuffer, syclQueue); + + vklRelease(intervalContext); + + // hit iteration + std::cout << std::endl << "\thit iteration" << std::endl << std::endl; + + // hit iterator context setup + float values[2] = {32.f, 96.f}; + int num_values = 2; + VKLData valuesData = vklNewData(device, num_values, VKL_FLOAT, values); + + VKLHitIteratorContext hitContext = vklNewHitIteratorContext(sampler); + + vklSetInt(hitContext, "attributeIndex", 0); + + vklSetData(hitContext, "values", valuesData); + vklRelease(valuesData); + + vklCommit(hitContext); + + // ray definition for iterators + // see rayOrigin, Direction and TRange above + + char *hitIteratorBuffer = + sycl::malloc_device(vklGetHitIteratorSize(&hitContext), syclQueue); + + int *numHits = sycl::malloc_shared(1, syclQueue); + *numHits = 0; + + const size_t maxNumHits = 999; + + VKLHit *hitBuffer = sycl::malloc_shared(maxNumHits, syclQueue); + memset(hitBuffer, 0, maxNumHits * sizeof(VKLHit)); + + std::cout << "\thit iterator for values"; + + for (const auto &r : values) { + std::cout << " " << r << " "; + } + std::cout << std::endl << std::endl; + + syclQueue + .submit([=](sycl::handler &cgh) { + cgh.set_specialization_constant(requiredFeatures); + + cgh.single_task([=](sycl::kernel_handler kh) { + const VKLFeatureFlags featureFlags = + kh.get_specialization_constant(); + + VKLHitIterator hitIterator = vklInitHitIterator( + &hitContext, &rayOrigin, &rayDirection, &rayTRange, time, + (void *)hitIteratorBuffer, featureFlags); + + for (;;) { + VKLHit hit; + int result = vklIterateHit(hitIterator, &hit, featureFlags); + if (!result) { + break; + } + hitBuffer[*numHits] = hit; + + *numHits = *numHits + 1; + if (*numHits >= maxNumHits) break; + } + }); + }) + .wait(); + + for (int i = 0; i < *numHits; ++i) { + std::cout << "\t\tt " << hitBuffer[i].t << std::endl; + std::cout << "\t\tsample " << hitBuffer[i].sample << std::endl; + std::cout << "\t\tepsilon " << hitBuffer[i].epsilon << std::endl + << std::endl; + } + + sycl::free(hitIteratorBuffer, syclQueue); + sycl::free(numHits, syclQueue); + sycl::free(hitBuffer, syclQueue); + + vklRelease(hitContext); + + vklRelease(sampler); +} + +int main() { + auto IntelGPUDeviceSelector = [](const sycl::device &device) { + using namespace sycl::info; + const std::string deviceName = device.get_info(); + bool match = device.is_gpu() && + device.get_info() == 0x8086 && + device.get_backend() == sycl::backend::ext_oneapi_level_zero; + return match ? 1 : -1; + }; + + sycl::queue syclQueue(IntelGPUDeviceSelector); + + sycl::context syclContext = syclQueue.get_context(); + + std::cout << "Target SYCL device: " + << syclQueue.get_device().get_info() + << std::endl + << std::endl; + + vklInit(); + + VKLDevice device = vklNewDevice("gpu"); + vklDeviceSetVoidPtr(device, "syclContext", static_cast(&syclContext)); + vklCommitDevice(device); + + const int dimensions[] = {128, 128, 128}; + + const int numVoxels = dimensions[0] * dimensions[1] * dimensions[2]; + + const int numAttributes = 3; + + VKLVolume volume = vklNewVolume(device, "structuredRegular"); + vklSetVec3i(volume, "dimensions", dimensions[0], dimensions[1], + dimensions[2]); + vklSetVec3f(volume, "gridOrigin", 0, 0, 0); + vklSetVec3f(volume, "gridSpacing", 1, 1, 1); + + std::vector voxels(numVoxels); + + // volume attribute 0: x-grad + for (int k = 0; k < dimensions[2]; k++) + for (int j = 0; j < dimensions[1]; j++) + for (int i = 0; i < dimensions[0]; i++) + voxels[k * dimensions[0] * dimensions[1] + j * dimensions[2] + i] = + (float)i; + + VKLData data0 = vklNewData(device, numVoxels, VKL_FLOAT, voxels.data()); + + // volume attribute 1: y-grad + for (int k = 0; k < dimensions[2]; k++) + for (int j = 0; j < dimensions[1]; j++) + for (int i = 0; i < dimensions[0]; i++) + voxels[k * dimensions[0] * dimensions[1] + j * dimensions[2] + i] = + (float)j; + + VKLData data1 = vklNewData(device, numVoxels, VKL_FLOAT, voxels.data()); + + // volume attribute 2: z-grad + for (int k = 0; k < dimensions[2]; k++) + for (int j = 0; j < dimensions[1]; j++) + for (int i = 0; i < dimensions[0]; i++) + voxels[k * dimensions[0] * dimensions[1] + j * dimensions[2] + i] = + (float)k; + + VKLData data2 = vklNewData(device, numVoxels, VKL_FLOAT, voxels.data()); + + VKLData attributes[] = {data0, data1, data2}; + + VKLData attributesData = + vklNewData(device, numAttributes, VKL_DATA, attributes); + + vklRelease(data0); + vklRelease(data1); + vklRelease(data2); + + vklSetData(volume, "data", attributesData); + vklRelease(attributesData); + + vklCommit(volume); + + demoGpuAPI(syclQueue, device, volume); + + vklRelease(volume); + + vklReleaseDevice(device); + + std::cout << "complete." << std::endl; + + return 0; +} diff --git a/RenderingToolkit/GettingStarted/03_openvkl_gsg/sample.json b/RenderingToolkit/GettingStarted/03_openvkl_gsg/sample.json index bff4cae380..f93a4b22a1 100644 --- a/RenderingToolkit/GettingStarted/03_openvkl_gsg/sample.json +++ b/RenderingToolkit/GettingStarted/03_openvkl_gsg/sample.json @@ -4,20 +4,27 @@ "categories": ["Toolkit/oneAPI Libraries/Open VKL"], "description": "This introductory hello rendering toolkit sample program demonstrates how to sample into volumes with Intel Open VKL", "builder": ["cli"], - "languages": [{"c":{}}], + "languages": [{"cpp":{}}], "dependencies": ["tbb","openvkl","embree","rkcommon"], "os":["linux", "windows", "darwin"], - "targetDevice": ["CPU"], + "targetDevice": ["CPU","GPU"], "ciTests": { "linux": [ { "id": "Intel_OpenVKL_vklTutorial_lin", "steps": [ + "cd cpu", "mkdir build", "cd build", "cmake ..", "cmake --build . ", - "./vklTutorial" + "./vklTutorialCPU", + "cd ../gpu", + "mkdir build", + "cd build", + "cmake -DCMAKE_CXX_COMPILER=icpx ..", + "cmake --build .", + "./vklTutorialGPU" ] } ], @@ -25,12 +32,20 @@ { "id": "Intel_OpenVKL_vklTutorial_win", "steps":[ + "cd cpu", "mkdir build", "cd build", "cmake ..", "cmake --build . --config Release", "cd Release", - ".\\vklTutorial.exe" + ".\\vklTutorialCPU.exe", + "cd ..", + "cd gpu", + "mkdir build", + "cd build", + "cmake -G\"NMake Makefiles\" -DCMAKE_CXX_COMPILER=icx-cl ..", + "cmake --build . --config Release", + ".\\vklTutorialGPU.exe" ] } @@ -39,11 +54,13 @@ { "id": "Intel_OpenVKL_vklTutorial_mac", "steps": [ + "cd cpu", "mkdir build", "cd build", "cmake ..", "cmake --build . ", - "export DYLD_LIBRARY_PATH=${ONEAPI_ROOT}/openvkl/latest/lib:${ONEAPI_ROOT}/rkcommon/latest/lib:${ONEAPI_ROOT}/tbb/latest/lib:${ONEAPI_ROOT}/embree/latest/lib && ./vklTutorial" + "export DYLD_LIBRARY_PATH=${ONEAPI_ROOT}/lib && ./vklTutorialCPU", + "export DYLD_LIBRARY_PATH=${ONEAPI_ROOT}/openvkl/latest/lib:${ONEAPI_ROOT}/rkcommon/latest/lib:${ONEAPI_ROOT}/tbb/latest/lib:${ONEAPI_ROOT}/embree/latest/lib && ./vklTutorialCPU" ] } ]