//============================================================================ // 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. // // Copyright 2017 National Technology & Engineering Solutions of Sandia, LLC (NTESS). // Copyright 2017 UT-Battelle, LLC. // Copyright 2017 Los Alamos National Security. // // Under the terms of Contract DE-NA0003525 with NTESS, // the U.S. Government retains certain rights in this software. // // Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National // Laboratory (LANL), the U.S. Government retains certain rights in // this software. //============================================================================ #include #include #include #include #include #include #include #include #include namespace UnitTestArrayHandleDiscardDetail { template struct Test { static const vtkm::Id ARRAY_SIZE = 100; static const vtkm::Id NUM_KEYS = 3; using DeviceTag = vtkm::cont::DeviceAdapterTagSerial; using Algorithm = vtkm::cont::DeviceAdapterAlgorithm; using Handle = vtkm::cont::ArrayHandle; using DiscardHandle = vtkm::cont::ArrayHandleDiscard; using OutputPortal = typename Handle::PortalControl; using ReduceOp = vtkm::Add; // Test discard arrays by using the ReduceByKey algorithm. Two regular arrays // handles are provided as inputs, but the keys_output array is a discard // array handle. The values_output array should still be populated correctly. void TestReduceByKey() { // The reduction operator: ReduceOp op; // Prepare inputs / reference data: ValueType keyData[ARRAY_SIZE]; ValueType valueData[ARRAY_SIZE]; ValueType refData[NUM_KEYS]; std::fill(refData, refData + NUM_KEYS, ValueType(0)); for (vtkm::Id i = 0; i < ARRAY_SIZE; ++i) { const vtkm::Id key = i % NUM_KEYS; keyData[i] = static_cast(key); valueData[i] = static_cast(i * 2); refData[key] = op(refData[key], valueData[i]); } // Prepare array handles: Handle keys = vtkm::cont::make_ArrayHandle(keyData, ARRAY_SIZE); Handle values = vtkm::cont::make_ArrayHandle(valueData, ARRAY_SIZE); DiscardHandle output_keys; Handle output_values; Algorithm::SortByKey(keys, values); Algorithm::ReduceByKey(keys, values, output_keys, output_values, op); OutputPortal outputs = output_values.GetPortalControl(); VTKM_TEST_ASSERT(outputs.GetNumberOfValues() == NUM_KEYS, "Unexpected number of output values from ReduceByKey."); for (vtkm::Id i = 0; i < NUM_KEYS; ++i) { VTKM_TEST_ASSERT(outputs.Get(i) == refData[i], "Unexpected output value after ReduceByKey."); } } void TestPrepareExceptions() { DiscardHandle handle; handle.Allocate(50); try { handle.PrepareForInput(DeviceTag()); } catch (vtkm::cont::ErrorBadValue&) { // Expected failure. } try { handle.PrepareForInPlace(DeviceTag()); } catch (vtkm::cont::ErrorBadValue&) { // Expected failure. } // Shouldn't fail: handle.PrepareForOutput(ARRAY_SIZE, DeviceTag()); } void operator()() { TestReduceByKey(); TestPrepareExceptions(); } }; void TestArrayHandleDiscard() { Test()(); Test()(); Test()(); Test()(); Test()(); Test()(); } } // end namespace UnitTestArrayHandleDiscardDetail int UnitTestArrayHandleDiscard(int, char* []) { using namespace UnitTestArrayHandleDiscardDetail; return vtkm::cont::testing::Testing::Run(TestArrayHandleDiscard); }