From c0bbf5454c96c4ae4baad503851c43d235c12acd Mon Sep 17 00:00:00 2001 From: Jieyang Chen Date: Tue, 1 Dec 2020 18:59:44 -0500 Subject: [PATCH] Add smoke test to VTK-m package (#19816) * add smoke test * remove whitespaces * fix minimum version issue * reorder decorators & replace make with cmake build * merge cmake build into one line * reorganize smoke test function Co-authored-by: Jieyang Chen --- .../repos/builtin/packages/vtk-m/package.py | 169 ++++++++++++++++++ 1 file changed, 169 insertions(+) diff --git a/var/spack/repos/builtin/packages/vtk-m/package.py b/var/spack/repos/builtin/packages/vtk-m/package.py index 79437e01cb..63ee64c0a5 100644 --- a/var/spack/repos/builtin/packages/vtk-m/package.py +++ b/var/spack/repos/builtin/packages/vtk-m/package.py @@ -6,6 +6,7 @@ from spack import * import os +import shutil import sys @@ -187,3 +188,171 @@ def cmake_args(self): options.append("-DVTKm_ENABLE_TBB:BOOL=OFF") return options + + def smoke_test(self): + print("Checking VTK-m installation...") + spec = self.spec + checkdir = "spack-check" + with working_dir(checkdir, create=True): + source = r""" +#include +#include +#include + +#include +#include + +struct NoArgKernel { + VTKM_EXEC void operator()(vtkm::Id) const {} + + void SetErrorMessageBuffer( + const vtkm::exec::internal::ErrorMessageBuffer &errorMessage) { + this->ErrorMessage = errorMessage; + } + + vtkm::exec::internal::ErrorMessageBuffer ErrorMessage; +}; + +template struct FillArrayKernel { + using ValueType = typename PortalType::ValueType; + + FillArrayKernel(const PortalType &array, ValueType fill) + : Array(array), FillValue(fill) {} + + VTKM_EXEC void operator()(vtkm::Id index) const { + this->Array.Set(index, this->FillValue); + } + void SetErrorMessageBuffer( + const vtkm::exec::internal::ErrorMessageBuffer &) { + } + + PortalType Array; + ValueType FillValue; +}; + + +int main() { + vtkm::cont::Initialize(); + + constexpr vtkm::Id size = 1000000; +#if defined(VTKM_ENABLE_KOKKOS) + constexpr vtkm::cont::DeviceAdapterTagKokkos desired_device; +#elif defined(VTKM_ENABLE_CUDA) + constexpr vtkm::cont::DeviceAdapterTagCuda desired_device; +#elif defined(VTKM_ENABLE_TBB) + constexpr vtkm::cont::DeviceAdapterTagTBB desired_device; +#elif defined(VTKM_ENABLE_OPENMP) + constexpr vtkm::cont::DeviceAdapterTagOpenMP desired_device; +#else + #error "No VTK-m Device Adapter enabled" +#endif + + std::cout << "-------------------------------------------\n"; + std::cout << "Testing No Argument Kernel" << std::endl; + vtkm::cont::Algorithm::Schedule(desired_device, NoArgKernel(), size); + + vtkm::cont::ArrayHandle handle; + { + std::cout << "-------------------------------------------\n"; + std::cout << "Testing Kernel + ArrayHandle PrepareForOutput" << std::endl; + vtkm::cont::Token token; + auto portal = handle.PrepareForOutput(size, desired_device, token); + vtkm::cont::Algorithm::Schedule(desired_device, + FillArrayKernel{portal, 1}, size); + } + + { + std::cout << "-------------------------------------------\n"; + std::cout << "Testing Kernel + ArrayHandle PrepareForInPlace" << std::endl; + vtkm::cont::Token token; + auto portal = handle.PrepareForInPlace(desired_device, token); + vtkm::cont::Algorithm::Schedule(desired_device, + FillArrayKernel{portal, 2}, size); + } + + std::cout << "-------------------------------------------\n"; + std::cout << "Ran tests on: " << desired_device.GetName() << std::endl; + + return 0; +} +""" + + cmakelists = r""" +##============================================================================ +## Copyright (c) Kitware, Inc. +## All rights reserved. +## See LICENSE.txt for details. +## +## This software is distributed WITHOUT ANY WARRANTY; without even +## the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +## PURPOSE. See the above copyright notice for more information. +##============================================================================ +cmake_minimum_required(VERSION 3.12...3.18 FATAL_ERROR) +project(VTKmSmokeTest CXX) + +#Find the VTK-m package +find_package(VTKm REQUIRED QUIET) + +add_executable(VTKmSmokeTest main.cxx) +target_link_libraries(VTKmSmokeTest PRIVATE vtkm_cont) +vtkm_add_target_information(VTKmSmokeTest + DROP_UNUSED_SYMBOLS MODIFY_CUDA_FLAGS + DEVICE_SOURCES main.cxx) +""" + + with open("main.cxx", 'w') as f: + f.write(source) + with open("CMakeLists.txt", 'w') as f: + f.write(cmakelists) + builddir = "build" + with working_dir(builddir, create=True): + cmake = Executable(spec['cmake'].prefix.bin + "/cmake") + cmakefiledir = spec['vtk-m'].prefix.lib + "/cmake" + cmakefiledir = cmakefiledir + "/" + os.listdir(cmakefiledir)[0] + cmake(*(["..", "-DVTKm_DIR=" + cmakefiledir])) + cmake(*(["--build", "."])) + try: + test = Executable('./VTKmSmokeTest') + output = test(output=str) + except ProcessError: + output = "" + print(output) + if "+hip" in spec: + expected_device = 'Kokkos' + elif "+cuda" in spec: + expected_device = 'Cuda' + elif "+tbb" in spec: + expected_device = 'TBB' + elif "+openmp" in spec: + expected_device = 'OpenMP' + expected = """\ +------------------------------------------- +Testing No Argument Kernel +------------------------------------------- +Testing Kernel + ArrayHandle PrepareForOutput +------------------------------------------- +Testing Kernel + ArrayHandle PrepareForInPlace +------------------------------------------- +Ran tests on: """ + expected_device + "\n" + success = output == expected + if success: + print("Test success") + if not success: + print("Produced output does not match expected output.") + print("Expected output:") + print('-' * 80) + print(expected) + print('-' * 80) + print("Produced output:") + print('-' * 80) + print(output) + print('-' * 80) + raise RuntimeError("VTK-m install check failed") + shutil.rmtree(checkdir) + + @run_after('install') + @on_package_attributes(run_tests=True) + def check_install(self): + spec = self.spec + if "@master" in spec: + self.smoke_test()