Commit bb067178 authored by Haocheng LIU's avatar Haocheng LIU

Make RuntimeDeviceInformation class template independent

By making RuntimeDeviceInformation class template independent, vtkm is
able to detect
device info at runtime with a runtime specified deviceId. In the past
it's impossible
because the CRTP pattern does not allow function overloading(compiler
would complain
that DeviceAdapterRuntimeDetector does not have Exists() function
defined).
parent 5ded6352
# Make RuntimeDeviceInformation class template independent
By making RuntimeDeviceInformation class template independent, vtkm is able to detect
device info at runtime with a runtime specified deviceId. In the past it's impossible
because the CRTP pattern does not allow function overloading(compiler would complain
that DeviceAdapterRuntimeDetector does not have Exists() function defined).
......@@ -28,6 +28,8 @@
#include <vtkm/cont/ExecutionAndControlObjectBase.h>
#include <vtkm/cont/RuntimeDeviceTracker.h>
#include <vtkm/cont/serial/internal/DeviceAdapterRuntimeDetectorSerial.h>
namespace vtkm
{
namespace cont
......
......@@ -146,6 +146,7 @@ set(sources
Logging.cxx
MultiBlock.cxx
PresetColorTables.cxx
RuntimeDeviceInformation.cxx
RuntimeDeviceTracker.cxx
StorageBasic.cxx
TryExecute.cxx
......
//============================================================================
// 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 2016 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2016 UT-Battelle, LLC.
// Copyright 2016 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 <vtkm/cont/RuntimeDeviceInformation.h>
#include <vtkm/ListTag.h>
#include <vtkm/cont/DeviceAdapter.h>
#include <vtkm/cont/DeviceAdapterListTag.h>
//Bring in each device adapters runtime class
#include <vtkm/cont/cuda/internal/DeviceAdapterRuntimeDetectorCuda.h>
#include <vtkm/cont/internal/DeviceAdapterError.h>
#include <vtkm/cont/openmp/internal/DeviceAdapterRuntimeDetectorOpenMP.h>
#include <vtkm/cont/serial/internal/DeviceAdapterRuntimeDetectorSerial.h>
#include <vtkm/cont/tbb/internal/DeviceAdapterRuntimeDetectorTBB.h>
namespace vtkm
{
namespace cont
{
namespace detail
{
struct RuntimeDeviceInformationFunctor
{
bool Exists = false;
template <typename DeviceAdapter>
VTKM_CONT void operator()(DeviceAdapter, DeviceAdapterId device)
{
if (DeviceAdapter() == device)
{
this->Exists = vtkm::cont::DeviceAdapterRuntimeDetector<DeviceAdapter>().Exists();
}
}
};
}
VTKM_CONT
bool RuntimeDeviceInformation::Exists(DeviceAdapterId id) const
{
detail::RuntimeDeviceInformationFunctor functor;
vtkm::ListForEach(functor, VTKM_DEFAULT_DEVICE_ADAPTER_LIST_TAG(), id);
return functor.Exists;
}
}
} // namespace vtkm::cont
......@@ -20,14 +20,8 @@
#ifndef vtk_m_cont_RuntimeDeviceInformation_h
#define vtk_m_cont_RuntimeDeviceInformation_h
#include <vtkm/cont/DeviceAdapter.h>
//Bring in each device adapters runtime class
#include <vtkm/cont/cuda/internal/DeviceAdapterRuntimeDetectorCuda.h>
#include <vtkm/cont/internal/DeviceAdapterError.h>
#include <vtkm/cont/openmp/internal/DeviceAdapterRuntimeDetectorOpenMP.h>
#include <vtkm/cont/serial/internal/DeviceAdapterRuntimeDetectorSerial.h>
#include <vtkm/cont/tbb/internal/DeviceAdapterRuntimeDetectorTBB.h>
#include <vtkm/cont/internal/DeviceAdapterTag.h>
#include <vtkm/internal/ExportMacros.h>
namespace vtkm
{
......@@ -40,24 +34,18 @@ namespace cont
/// or a Accelerator Card.
///
///
template <class Device>
class RuntimeDeviceInformation
class VTKM_CONT_EXPORT RuntimeDeviceInformation
{
public:
VTKM_CONT
RuntimeDeviceInformation()
: RuntimeImplementation()
{
}
RuntimeDeviceInformation() {}
/// Returns true if the given device adapter is supported on the current
/// machine.
///
VTKM_CONT
bool Exists() const { return this->RuntimeImplementation.Exists(); }
private:
vtkm::cont::DeviceAdapterRuntimeDetector<Device> RuntimeImplementation;
bool Exists(DeviceAdapterId id) const;
};
}
} // namespace vtkm::cont
......
......@@ -23,6 +23,7 @@
#include <vtkm/cont/DeviceAdapter.h>
#include <vtkm/cont/DeviceAdapterListTag.h>
#include <vtkm/cont/ErrorBadValue.h>
#include <vtkm/cont/internal/DeviceAdapterError.h>
#include <vtkm/cont/cuda/DeviceAdapterCuda.h>
#include <vtkm/cont/serial/DeviceAdapterSerial.h>
......
......@@ -109,8 +109,8 @@ public:
template <typename DeviceAdapterTag>
VTKM_CONT void ResetDevice(DeviceAdapterTag device)
{
vtkm::cont::RuntimeDeviceInformation<DeviceAdapterTag> runtimeDevice;
this->SetDeviceState(device, runtimeDevice.Exists());
vtkm::cont::RuntimeDeviceInformation runtimeDevice;
this->SetDeviceState(device, runtimeDevice.Exists(DeviceAdapterTag()));
}
/// Reset the tracker to its default state for default devices.
......@@ -192,8 +192,8 @@ public:
template <typename DeviceAdapterTag>
VTKM_CONT void ForceDevice(DeviceAdapterTag device)
{
vtkm::cont::RuntimeDeviceInformation<DeviceAdapterTag> runtimeDevice;
this->ForceDeviceImpl(device, runtimeDevice.Exists());
vtkm::cont::RuntimeDeviceInformation runtimeDevice;
this->ForceDeviceImpl(device, runtimeDevice.Exists(DeviceAdapterTag()));
}
VTKM_CONT_EXPORT
......
......@@ -608,18 +608,6 @@ private:
VTKM_TEST_ASSERT(elapsedTime < 2.0, "Timer counted too far or system really busy.");
}
VTKM_CONT
static void TestRuntime()
{
std::cout << "-------------------------------------------" << std::endl;
std::cout << "Testing RuntimeDeviceInformation" << std::endl;
vtkm::cont::RuntimeDeviceInformation<DeviceAdapterTag> runtime;
const bool valid_runtime = runtime.Exists();
VTKM_TEST_ASSERT(valid_runtime, "runtime detection failed for device");
}
VTKM_CONT
static void TestVirtualObjectTransfer()
{
......@@ -2416,7 +2404,6 @@ private:
TestArrayManagerExecution();
TestOutOfMemory();
TestTimer();
TestRuntime();
TestVirtualObjectTransfer();
TestAlgorithmSchedule();
......
......@@ -22,6 +22,7 @@
//include all backends
#include <vtkm/cont/cuda/DeviceAdapterCuda.h>
#include <vtkm/cont/openmp/DeviceAdapterOpenMP.h>
#include <vtkm/cont/serial/DeviceAdapterSerial.h>
#include <vtkm/cont/tbb/DeviceAdapterTBB.h>
......@@ -50,8 +51,8 @@ struct DoesExist<false>
{
//runtime information for this device should return false
vtkm::cont::RuntimeDeviceInformation<DeviceAdapterTag> runtime;
VTKM_TEST_ASSERT(runtime.Exists() == false,
vtkm::cont::RuntimeDeviceInformation runtime;
VTKM_TEST_ASSERT(runtime.Exists(DeviceAdapterTag()) == false,
"A backend with zero compile time support, can't have runtime support");
}
......@@ -60,12 +61,12 @@ struct DoesExist<false>
//Since we are in a C++ compilation unit the Device Adapter
//trait should be false. But CUDA could still be enabled.
//That is why we check VTKM_ENABLE_CUDA.
vtkm::cont::RuntimeDeviceInformation<vtkm::cont::DeviceAdapterTagCuda> runtime;
vtkm::cont::RuntimeDeviceInformation runtime;
#ifdef VTKM_ENABLE_CUDA
VTKM_TEST_ASSERT(runtime.Exists() == true,
VTKM_TEST_ASSERT(runtime.Exists(vtkm::cont::DeviceAdapterTagCuda()) == true,
"with cuda backend enabled, runtime support should be enabled");
#else
VTKM_TEST_ASSERT(runtime.Exists() == false,
VTKM_TEST_ASSERT(runtime.Exists(vtkm::cont::DeviceAdapterTagCuda()) == false,
"with cuda backend disabled, runtime support should be disabled");
#endif
}
......@@ -78,8 +79,8 @@ struct DoesExist<true>
void Exist(DeviceAdapterTag) const
{
//runtime information for this device should return true
vtkm::cont::RuntimeDeviceInformation<DeviceAdapterTag> runtime;
VTKM_TEST_ASSERT(runtime.Exists() == true,
vtkm::cont::RuntimeDeviceInformation runtime;
VTKM_TEST_ASSERT(runtime.Exists(DeviceAdapterTag()) == true,
"A backend with compile time support, should have runtime support");
}
};
......@@ -87,14 +88,16 @@ struct DoesExist<true>
void Detection()
{
using SerialTag = ::vtkm::cont::DeviceAdapterTagSerial;
using OpenMPTag = ::vtkm::cont::DeviceAdapterTagOpenMP;
using TBBTag = ::vtkm::cont::DeviceAdapterTagTBB;
using CudaTag = ::vtkm::cont::DeviceAdapterTagCuda;
//Verify that for each device adapter we compile code for, that it
//has valid runtime support.
detect_if_exists(SerialTag());
detect_if_exists(OpenMPTag());
detect_if_exists(CudaTag());
detect_if_exists(TBBTag());
detect_if_exists(SerialTag());
}
} // anonymous namespace
......
......@@ -19,6 +19,8 @@
//============================================================================
#include <vtkm/cont/Error.h>
#include <vtkm/cont/ErrorBadValue.h>
#include <vtkm/cont/RuntimeDeviceInformation.h>
#include <vtkm/cont/RuntimeDeviceTracker.h>
#include <vtkm/cont/internal/DeviceAdapterError.h>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment