From 227e2adf43673f0e34e15507f6843ab5ae03da98 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Wed, 24 Jul 2024 13:37:19 -0400 Subject: [PATCH] Add trunc cuda testing --- test/cuda_jamfile | 2 + test/test_trunc_double.cu | 97 +++++++++++++++++++++++++++++++++++++++ test/test_trunc_float.cu | 97 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 196 insertions(+) create mode 100644 test/test_trunc_double.cu create mode 100644 test/test_trunc_float.cu diff --git a/test/cuda_jamfile b/test/cuda_jamfile index 2494853a9..a350e037e 100644 --- a/test/cuda_jamfile +++ b/test/cuda_jamfile @@ -38,3 +38,5 @@ run test_cbrt_double.cu ; run test_cbrt_float.cu ; run test_changesign_double.cu ; run test_changesign_float.cu ; +run test_trunc_double.cu ; +run test_trunc_float.cu ; diff --git a/test/test_trunc_double.cu b/test/test_trunc_double.cu new file mode 100644 index 000000000..5a2d7b622 --- /dev/null +++ b/test/test_trunc_double.cu @@ -0,0 +1,97 @@ +// Copyright John Maddock 2016. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include +#include +#include +#include +#include +#include "cuda_managed_ptr.hpp" +#include "stopwatch.hpp" + +// For the CUDA runtime routines (prefixed with "cuda_") +#include + +typedef double float_type; + +/** + * CUDA Kernel Device code + * + */ +__global__ void cuda_test(const float_type *in, float_type *out, int numElements) +{ + using std::cos; + int i = blockDim.x * blockIdx.x + threadIdx.x; + + if (i < numElements) + { + out[i] = boost::math::trunc(in[i]) + boost::math::itrunc(in[i]) + boost::math::ltrunc(in[i]) + boost::math::lltrunc(in[i]); + } +} + +/** + * Host main routine + */ +int main(void) +{ + // Error code to check return values for CUDA calls + cudaError_t err = cudaSuccess; + + // Print the vector length to be used, and compute its size + int numElements = 50000; + std::cout << "[Vector addition of " << numElements << " elements]" << std::endl; + + // Allocate the managed input vector A + cuda_managed_ptr h_A(numElements); + + // Allocate the managed output vector C + cuda_managed_ptr h_C(numElements); + + // Initialize the input vectors + for (int i = 0; i < numElements; ++i) + { + h_A[i] = rand()/(float_type)RAND_MAX; + } + + // Launch the Vector Add CUDA Kernel + int threadsPerBlock = 1024; + int blocksPerGrid =(numElements + threadsPerBlock - 1) / threadsPerBlock; + std::cout << "CUDA kernel launch with " << blocksPerGrid << " blocks of " << threadsPerBlock << " threads" << std::endl; + + watch w; + cuda_test<<>>(h_A.get(), h_C.get(), numElements); + cudaDeviceSynchronize(); + std::cout << "CUDA kernal done in " << w.elapsed() << "s" << std::endl; + + err = cudaGetLastError(); + + if (err != cudaSuccess) + { + std::cerr << "Failed to launch vectorAdd kernel (error code " << cudaGetErrorString(err) << ")!" << std::endl; + return EXIT_FAILURE; + } + + // Verify that the result vector is correct + std::vector results; + results.reserve(numElements); + w.reset(); + for(int i = 0; i < numElements; ++i) + results.push_back(4 * boost::math::trunc(h_A[i])); + double t = w.elapsed(); + // check the results + for(int i = 0; i < numElements; ++i) + { + if (boost::math::epsilon_difference(h_C[i], results[i]) > 10) + { + std::cerr << "Result verification failed at element " << i << "!" << std::endl; + return EXIT_FAILURE; + } + } + + std::cout << "Test PASSED with calculation time: " << t << "s" << std::endl; + std::cout << "Done\n"; + + return 0; +} diff --git a/test/test_trunc_float.cu b/test/test_trunc_float.cu new file mode 100644 index 000000000..d6fe4d352 --- /dev/null +++ b/test/test_trunc_float.cu @@ -0,0 +1,97 @@ +// Copyright John Maddock 2016. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include +#include +#include +#include +#include +#include "cuda_managed_ptr.hpp" +#include "stopwatch.hpp" + +// For the CUDA runtime routines (prefixed with "cuda_") +#include + +typedef float float_type; + +/** + * CUDA Kernel Device code + * + */ +__global__ void cuda_test(const float_type *in, float_type *out, int numElements) +{ + using std::cos; + int i = blockDim.x * blockIdx.x + threadIdx.x; + + if (i < numElements) + { + out[i] = boost::math::trunc(in[i]) + boost::math::itrunc(in[i]) + boost::math::ltrunc(in[i]) + boost::math::lltrunc(in[i]); + } +} + +/** + * Host main routine + */ +int main(void) +{ + // Error code to check return values for CUDA calls + cudaError_t err = cudaSuccess; + + // Print the vector length to be used, and compute its size + int numElements = 50000; + std::cout << "[Vector addition of " << numElements << " elements]" << std::endl; + + // Allocate the managed input vector A + cuda_managed_ptr h_A(numElements); + + // Allocate the managed output vector C + cuda_managed_ptr h_C(numElements); + + // Initialize the input vectors + for (int i = 0; i < numElements; ++i) + { + h_A[i] = rand()/(float_type)RAND_MAX; + } + + // Launch the Vector Add CUDA Kernel + int threadsPerBlock = 1024; + int blocksPerGrid =(numElements + threadsPerBlock - 1) / threadsPerBlock; + std::cout << "CUDA kernel launch with " << blocksPerGrid << " blocks of " << threadsPerBlock << " threads" << std::endl; + + watch w; + cuda_test<<>>(h_A.get(), h_C.get(), numElements); + cudaDeviceSynchronize(); + std::cout << "CUDA kernal done in " << w.elapsed() << "s" << std::endl; + + err = cudaGetLastError(); + + if (err != cudaSuccess) + { + std::cerr << "Failed to launch vectorAdd kernel (error code " << cudaGetErrorString(err) << ")!" << std::endl; + return EXIT_FAILURE; + } + + // Verify that the result vector is correct + std::vector results; + results.reserve(numElements); + w.reset(); + for(int i = 0; i < numElements; ++i) + results.push_back(4 * boost::math::trunc(h_A[i])); + double t = w.elapsed(); + // check the results + for(int i = 0; i < numElements; ++i) + { + if (boost::math::epsilon_difference(h_C[i], results[i]) > 10) + { + std::cerr << "Result verification failed at element " << i << "!" << std::endl; + return EXIT_FAILURE; + } + } + + std::cout << "Test PASSED with calculation time: " << t << "s" << std::endl; + std::cout << "Done\n"; + + return 0; +}