mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
GPU: Raise CUDA/HIP minimum and remove legacy guards
- Raise CUDA minimum from 9.0 to 11.4 (sm_70/Volta).
- Raise HIP minimum to GFX906 (Vega 20/MI50) / ROCm 5.6.
- Remove EIGEN_HAS_{CUDA,HIP,GPU}_FP16 guards — FP16 is always available
on sm_70+ and GFX906+.
- Remove obsolete __HIP_ARCH_HAS_* preprocessor branches.
- C++14 cleanup: remove pre-C++14 workarounds in GPU code.
- Fix NVCC warnings (deprecated register keyword, unreachable code,
tautological comparisons).
- Fix HIP test execution on gfx1151.
- Update CI configuration for new minimum versions.
This commit is contained in:
@@ -433,7 +433,7 @@ if(EIGEN_TEST_CUDA_NVC AND NOT CMAKE_CXX_COMPILER_ID MATCHES "NVHPC")
|
||||
message(WARNING "EIGEN_TEST_CUDA_NVC is set, but CMAKE_CXX_COMPILER does not appear to be nvc++.")
|
||||
endif()
|
||||
|
||||
find_package(CUDA 9.0)
|
||||
find_package(CUDA 11.4)
|
||||
if(CUDA_FOUND AND EIGEN_TEST_CUDA)
|
||||
# Make sure to compile without the -pedantic, -Wundef, -Wnon-virtual-dtor
|
||||
# and -fno-check-new flags since they trigger thousands of compilation warnings
|
||||
@@ -502,6 +502,9 @@ if (EIGEN_TEST_HIP)
|
||||
endif()
|
||||
|
||||
find_package(HIP REQUIRED)
|
||||
if (HIP_FOUND AND HIP_VERSION VERSION_LESS "5.6")
|
||||
message(FATAL_ERROR "Eigen requires ROCm/HIP >= 5.6, found ${HIP_VERSION}")
|
||||
endif()
|
||||
if (HIP_FOUND)
|
||||
execute_process(COMMAND ${HIP_PATH}/bin/hipconfig --platform OUTPUT_VARIABLE HIP_PLATFORM)
|
||||
|
||||
|
||||
@@ -7,12 +7,6 @@
|
||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
// workaround issue between gcc >= 4.7 and cuda 5.5
|
||||
#if (defined __GNUC__) && (__GNUC__ > 4 || __GNUC_MINOR__ >= 7)
|
||||
#undef _GLIBCXX_ATOMIC_BUILTINS
|
||||
#undef _GLIBCXX_USE_INT128
|
||||
#endif
|
||||
|
||||
#define EIGEN_TEST_NO_LONGDOUBLE
|
||||
#define EIGEN_DEFAULT_DENSE_INDEX_TYPE int
|
||||
|
||||
|
||||
@@ -6,10 +6,8 @@
|
||||
// Allow gpu** macros for generic tests.
|
||||
#include <Eigen/src/Core/util/GpuHipCudaDefines.inc>
|
||||
|
||||
// std::tuple cannot be used on device, and there is a bug in cuda < 9.2 that
|
||||
// doesn't allow std::tuple to compile for host code either. In these cases,
|
||||
// use our custom implementation.
|
||||
#if defined(EIGEN_GPU_COMPILE_PHASE) || (defined(EIGEN_CUDACC) && EIGEN_CUDA_SDK_VER < 92000)
|
||||
// std::tuple cannot be used on device, so use our custom implementation there.
|
||||
#if defined(EIGEN_GPU_COMPILE_PHASE)
|
||||
#define EIGEN_USE_CUSTOM_TUPLE 1
|
||||
#else
|
||||
#define EIGEN_USE_CUSTOM_TUPLE 0
|
||||
@@ -42,6 +40,12 @@ using tuple_impl::tuple;
|
||||
#undef EIGEN_USE_CUSTOM_TUPLE
|
||||
} // namespace test_detail
|
||||
|
||||
template <typename T>
|
||||
using decay_t = typename std::decay<T>::type;
|
||||
|
||||
template <typename Func, typename... Args>
|
||||
using kernel_result_t = decltype(std::declval<Func>()(std::declval<Args>()...));
|
||||
|
||||
template <size_t N, size_t Idx, typename OutputIndexSequence, typename... Ts>
|
||||
struct extract_output_indices_helper;
|
||||
|
||||
@@ -90,14 +94,15 @@ struct void_helper {
|
||||
// Non-void return value.
|
||||
template <typename Func, typename... Args>
|
||||
static EIGEN_ALWAYS_INLINE EIGEN_DEVICE_FUNC auto call(Func&& func, Args&&... args)
|
||||
-> std::enable_if_t<!std::is_same<decltype(func(args...)), void>::value, decltype(func(args...))> {
|
||||
-> std::enable_if_t<!std::is_same<kernel_result_t<Func&&, Args&&...>, void>::value,
|
||||
kernel_result_t<Func&&, Args&&...>> {
|
||||
return func(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
// Void return value.
|
||||
template <typename Func, typename... Args>
|
||||
static EIGEN_ALWAYS_INLINE EIGEN_DEVICE_FUNC auto call(Func&& func, Args&&... args)
|
||||
-> std::enable_if_t<std::is_same<decltype(func(args...)), void>::value, Void> {
|
||||
-> std::enable_if_t<std::is_same<kernel_result_t<Func&&, Args&&...>, void>::value, Void> {
|
||||
func(std::forward<Args>(args)...);
|
||||
return Void{};
|
||||
}
|
||||
@@ -135,18 +140,18 @@ EIGEN_DEVICE_FUNC void run_serialized(std::index_sequence<Indices...>, std::inde
|
||||
const uint8_t* read_end = buffer + capacity;
|
||||
read_ptr = Eigen::deserialize(read_ptr, read_end, input_size);
|
||||
// Create value-type instances to populate.
|
||||
auto args = make_tuple(typename std::decay<Args>::type{}...);
|
||||
auto args = make_tuple(decay_t<Args>{}...);
|
||||
EIGEN_UNUSED_VARIABLE(args); // Avoid NVCC compile warning.
|
||||
// NVCC 9.1 requires us to spell out the template parameters explicitly.
|
||||
read_ptr = Eigen::deserialize(read_ptr, read_end, get<Indices, typename std::decay<Args>::type...>(args)...);
|
||||
read_ptr = Eigen::deserialize(read_ptr, read_end, get<Indices, decay_t<Args>...>(args)...);
|
||||
|
||||
// Call function, with void->Void conversion so we are guaranteed a complete
|
||||
// output type.
|
||||
auto result = void_helper::call(kernel, get<Indices, typename std::decay<Args>::type...>(args)...);
|
||||
auto result = void_helper::call(kernel, get<Indices, decay_t<Args>...>(args)...);
|
||||
|
||||
// Determine required output size.
|
||||
size_t output_size = Eigen::serialize_size(capacity);
|
||||
output_size += Eigen::serialize_size(get<OutputIndices, typename std::decay<Args>::type...>(args)...);
|
||||
output_size += Eigen::serialize_size(get<OutputIndices, decay_t<Args>...>(args)...);
|
||||
output_size += Eigen::serialize_size(result);
|
||||
|
||||
// Always serialize required buffer size.
|
||||
@@ -157,7 +162,7 @@ EIGEN_DEVICE_FUNC void run_serialized(std::index_sequence<Indices...>, std::inde
|
||||
// Serialize outputs if they fit in the buffer.
|
||||
if (output_size <= capacity) {
|
||||
// Collect outputs and result.
|
||||
write_ptr = Eigen::serialize(write_ptr, write_end, get<OutputIndices, typename std::decay<Args>::type...>(args)...);
|
||||
write_ptr = Eigen::serialize(write_ptr, write_end, get<OutputIndices, decay_t<Args>...>(args)...);
|
||||
write_ptr = Eigen::serialize(write_ptr, write_end, result);
|
||||
}
|
||||
}
|
||||
@@ -282,7 +287,7 @@ auto run_serialized_on_gpu(size_t buffer_capacity_hint, std::index_sequence<Indi
|
||||
* \return kernel(args...).
|
||||
*/
|
||||
template <typename Kernel, typename... Args>
|
||||
auto run_on_cpu(Kernel kernel, Args&&... args) -> decltype(kernel(args...)) {
|
||||
auto run_on_cpu(Kernel kernel, Args&&... args) -> internal::kernel_result_t<Kernel, Args&&...> {
|
||||
return kernel(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
@@ -301,7 +306,7 @@ auto run_on_cpu(Kernel kernel, Args&&... args) -> decltype(kernel(args...)) {
|
||||
* \return kernel(args...).
|
||||
*/
|
||||
template <typename Kernel, typename... Args>
|
||||
auto run_on_gpu(Kernel kernel, Args&&... args) -> decltype(kernel(args...)) {
|
||||
auto run_on_gpu(Kernel kernel, Args&&... args) -> internal::kernel_result_t<Kernel, Args&&...> {
|
||||
return internal::run_serialized_on_gpu<Kernel, Args...>(
|
||||
/*buffer_capacity_hint=*/0, std::make_index_sequence<sizeof...(Args)>{},
|
||||
internal::extract_output_indices<Args...>{}, kernel, std::forward<Args>(args)...);
|
||||
@@ -322,7 +327,8 @@ auto run_on_gpu(Kernel kernel, Args&&... args) -> decltype(kernel(args...)) {
|
||||
* \sa run_on_gpu
|
||||
*/
|
||||
template <typename Kernel, typename... Args>
|
||||
auto run_on_gpu_with_hint(size_t buffer_capacity_hint, Kernel kernel, Args&&... args) -> decltype(kernel(args...)) {
|
||||
auto run_on_gpu_with_hint(size_t buffer_capacity_hint, Kernel kernel, Args&&... args)
|
||||
-> internal::kernel_result_t<Kernel, Args&&...> {
|
||||
return internal::run_serialized_on_gpu<Kernel, Args...>(
|
||||
buffer_capacity_hint, std::make_index_sequence<sizeof...(Args)>{}, internal::extract_output_indices<Args...>{},
|
||||
kernel, std::forward<Args>(args)...);
|
||||
@@ -409,7 +415,7 @@ void print_gpu_device_info() {
|
||||
* \return kernel(args...).
|
||||
*/
|
||||
template <typename Kernel, typename... Args>
|
||||
auto run(Kernel kernel, Args&&... args) -> decltype(kernel(args...)) {
|
||||
auto run(Kernel kernel, Args&&... args) -> internal::kernel_result_t<Kernel, Args&&...> {
|
||||
#ifdef EIGEN_GPUCC
|
||||
return run_on_gpu(kernel, std::forward<Args>(args)...);
|
||||
#else
|
||||
@@ -432,7 +438,8 @@ auto run(Kernel kernel, Args&&... args) -> decltype(kernel(args...)) {
|
||||
* \sa run
|
||||
*/
|
||||
template <typename Kernel, typename... Args>
|
||||
auto run_with_hint(size_t buffer_capacity_hint, Kernel kernel, Args&&... args) -> decltype(kernel(args...)) {
|
||||
auto run_with_hint(size_t buffer_capacity_hint, Kernel kernel, Args&&... args)
|
||||
-> internal::kernel_result_t<Kernel, Args&&...> {
|
||||
#ifdef EIGEN_GPUCC
|
||||
return run_on_gpu_with_hint(buffer_capacity_hint, kernel, std::forward<Args>(args)...);
|
||||
#else
|
||||
|
||||
40
test/main.h
40
test/main.h
@@ -76,10 +76,8 @@
|
||||
#include <cuda.h>
|
||||
#include <cuda_runtime.h>
|
||||
#include <cuda_runtime_api.h>
|
||||
#if CUDA_VERSION >= 7050
|
||||
#include <cuda_fp16.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(EIGEN_CUDACC) || defined(EIGEN_HIPCC)
|
||||
#define EIGEN_TEST_NO_LONGDOUBLE
|
||||
@@ -949,6 +947,37 @@ inline void set_seed_from_time() {
|
||||
g_seed = static_cast<decltype(g_seed)>(ns);
|
||||
}
|
||||
|
||||
#if defined(EIGEN_USE_GPU)
|
||||
inline int maybe_skip_gpu_tests() {
|
||||
#if defined(EIGEN_USE_HIP)
|
||||
int device_count = 0;
|
||||
hipError_t status = hipGetDeviceCount(&device_count);
|
||||
if (status != hipSuccess) {
|
||||
std::cout << "SKIP: HIP GPU tests require a visible ROCm device. hipGetDeviceCount failed with: "
|
||||
<< hipGetErrorString(status) << std::endl;
|
||||
return 77;
|
||||
}
|
||||
if (device_count <= 0) {
|
||||
std::cout << "SKIP: HIP GPU tests require a visible ROCm device." << std::endl;
|
||||
return 77;
|
||||
}
|
||||
#elif defined(EIGEN_CUDACC)
|
||||
int device_count = 0;
|
||||
cudaError_t status = cudaGetDeviceCount(&device_count);
|
||||
if (status != cudaSuccess) {
|
||||
std::cout << "SKIP: CUDA GPU tests require a visible CUDA device. cudaGetDeviceCount failed with: "
|
||||
<< cudaGetErrorString(status) << std::endl;
|
||||
return 77;
|
||||
}
|
||||
if (device_count <= 0) {
|
||||
std::cout << "SKIP: CUDA GPU tests require a visible CUDA device." << std::endl;
|
||||
return 77;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
g_has_set_repeat = false;
|
||||
g_has_set_seed = false;
|
||||
@@ -997,6 +1026,13 @@ int main(int argc, char* argv[]) {
|
||||
srand(g_seed);
|
||||
std::cout << "Repeating each test " << g_repeat << " times" << std::endl;
|
||||
|
||||
#if defined(EIGEN_USE_GPU)
|
||||
{
|
||||
const int skip_code = maybe_skip_gpu_tests();
|
||||
if (skip_code != 0) return skip_code;
|
||||
}
|
||||
#endif
|
||||
|
||||
VERIFY(EigenTest::all().size() > 0);
|
||||
|
||||
for (std::size_t i = 0; i < EigenTest::all().size(); ++i) {
|
||||
|
||||
Reference in New Issue
Block a user