]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Allow using float shape functions 9104/head
authorDaniel Arndt <arndtd@ornl.gov>
Wed, 27 Nov 2019 23:42:45 +0000 (18:42 -0500)
committerDaniel Arndt <arndtd@ornl.gov>
Mon, 2 Dec 2019 19:17:20 +0000 (19:17 +0000)
include/deal.II/matrix_free/cuda_matrix_free.templates.h
include/deal.II/matrix_free/cuda_tensor_product_kernels.h
tests/cuda/cuda_evaluate_1d_shape.cu
tests/cuda/cuda_evaluate_2d_shape.cu

index f7ac0f58d56cb9b9ebd3c2100ee0ba44b34eb107..9900fe10e2a648141f480e238789ba7b75a3b24c 100644 (file)
@@ -46,16 +46,80 @@ namespace CUDAWrappers
   namespace internal
   {
     // These variables are stored in the device constant memory.
-    // TODO: use a template parameter
     constexpr unsigned int max_elem_degree = 10;
+
+    template <typename NumberType>
+    using DataArray = NumberType[(max_elem_degree + 1) * (max_elem_degree + 1)];
+
     __constant__ double
-      global_shape_values[(max_elem_degree + 1) * (max_elem_degree + 1)];
+      global_shape_values_d[(max_elem_degree + 1) * (max_elem_degree + 1)];
+    __constant__ float
+      global_shape_values_f[(max_elem_degree + 1) * (max_elem_degree + 1)];
+
+    template <typename Number>
+    __host__ __device__ inline DataArray<Number> &
+             get_global_shape_values();
+
+    template <>
+    __host__ __device__ inline DataArray<double> &
+             get_global_shape_values<double>()
+    {
+      return global_shape_values_d;
+    }
+
+    template <>
+    __host__ __device__ inline DataArray<float> &
+             get_global_shape_values<float>()
+    {
+      return global_shape_values_f;
+    }
+
     __constant__ double
-      global_shape_gradients[(max_elem_degree + 1) * (max_elem_degree + 1)];
+      global_shape_gradients_d[(max_elem_degree + 1) * (max_elem_degree + 1)];
+    __constant__ float
+      global_shape_gradients_f[(max_elem_degree + 1) * (max_elem_degree + 1)];
+
+    template <typename Number>
+    __host__ __device__ inline DataArray<Number> &
+             get_global_shape_gradients();
+
+    template <>
+    __host__ __device__ inline DataArray<double> &
+             get_global_shape_gradients<double>()
+    {
+      return global_shape_gradients_d;
+    }
+
+    template <>
+    __host__ __device__ inline DataArray<float> &
+             get_global_shape_gradients<float>()
+    {
+      return global_shape_gradients_f;
+    }
 
     // for collocation methods
-    __constant__ double
-      global_co_shape_gradients[(max_elem_degree + 1) * (max_elem_degree + 1)];
+    __constant__ double global_co_shape_gradients_d[(max_elem_degree + 1) *
+                                                    (max_elem_degree + 1)];
+    __constant__ float  global_co_shape_gradients_f[(max_elem_degree + 1) *
+                                                   (max_elem_degree + 1)];
+
+    template <typename Number>
+    __host__ __device__ inline DataArray<Number> &
+             get_global_co_shape_gradients();
+
+    template <>
+    __host__ __device__ inline DataArray<double> &
+             get_global_co_shape_gradients<double>()
+    {
+      return global_co_shape_gradients_d;
+    }
+
+    template <>
+    __host__ __device__ inline DataArray<float> &
+             get_global_co_shape_gradients<float>()
+    {
+      return global_co_shape_gradients_f;
+    }
 
     template <typename Number>
     using CUDAVector = ::dealii::LinearAlgebra::CUDAWrappers::Vector<Number>;
@@ -805,27 +869,30 @@ namespace CUDAWrappers
     unsigned int size_co_shape_values =
       n_q_points_1d * n_q_points_1d * sizeof(Number);
 
-    cudaError_t cuda_error = cudaMemcpyToSymbol(internal::global_shape_values,
-                                                shape_info.shape_values.data(),
-                                                size_shape_values,
-                                                0,
-                                                cudaMemcpyHostToDevice);
+    cudaError_t cuda_error =
+      cudaMemcpyToSymbol(internal::get_global_shape_values<Number>(),
+                         shape_info.shape_values.data(),
+                         size_shape_values,
+                         0,
+                         cudaMemcpyHostToDevice);
     AssertCuda(cuda_error);
 
     if (update_flags & update_gradients)
       {
-        cuda_error = cudaMemcpyToSymbol(internal::global_shape_gradients,
-                                        shape_info.shape_gradients.data(),
-                                        size_shape_values,
-                                        0,
-                                        cudaMemcpyHostToDevice);
+        cuda_error =
+          cudaMemcpyToSymbol(internal::get_global_shape_gradients<Number>(),
+                             shape_info.shape_gradients.data(),
+                             size_shape_values,
+                             0,
+                             cudaMemcpyHostToDevice);
         AssertCuda(cuda_error);
 
-        cuda_error = cudaMemcpyToSymbol(internal::global_co_shape_gradients,
-                                        shape_info_co.shape_gradients.data(),
-                                        size_co_shape_values,
-                                        0,
-                                        cudaMemcpyHostToDevice);
+        cuda_error =
+          cudaMemcpyToSymbol(internal::get_global_co_shape_gradients<Number>(),
+                             shape_info_co.shape_gradients.data(),
+                             size_co_shape_values,
+                             0,
+                             cudaMemcpyHostToDevice);
         AssertCuda(cuda_error);
       }
 
index bf9a4a3d9a2590b94a24bb77aaa371e9a39b77f7..a5871e13778c3794caecc48c8f40b0c8634790f7 100644 (file)
@@ -256,25 +256,37 @@ namespace CUDAWrappers
         {
           case 1:
             {
-              values<0, true, false, true>(global_shape_values, u, u);
+              values<0, true, false, true>(get_global_shape_values<Number>(),
+                                           u,
+                                           u);
 
               break;
             }
           case 2:
             {
-              values<0, true, false, true>(global_shape_values, u, u);
+              values<0, true, false, true>(get_global_shape_values<Number>(),
+                                           u,
+                                           u);
               __syncthreads();
-              values<1, true, false, true>(global_shape_values, u, u);
+              values<1, true, false, true>(get_global_shape_values<Number>(),
+                                           u,
+                                           u);
 
               break;
             }
           case 3:
             {
-              values<0, true, false, true>(global_shape_values, u, u);
+              values<0, true, false, true>(get_global_shape_values<Number>(),
+                                           u,
+                                           u);
               __syncthreads();
-              values<1, true, false, true>(global_shape_values, u, u);
+              values<1, true, false, true>(get_global_shape_values<Number>(),
+                                           u,
+                                           u);
               __syncthreads();
-              values<2, true, false, true>(global_shape_values, u, u);
+              values<2, true, false, true>(get_global_shape_values<Number>(),
+                                           u,
+                                           u);
 
               break;
             }
@@ -300,25 +312,37 @@ namespace CUDAWrappers
         {
           case 1:
             {
-              values<0, false, false, true>(global_shape_values, u, u);
+              values<0, false, false, true>(get_global_shape_values<Number>(),
+                                            u,
+                                            u);
 
               break;
             }
           case 2:
             {
-              values<0, false, false, true>(global_shape_values, u, u);
+              values<0, false, false, true>(get_global_shape_values<Number>(),
+                                            u,
+                                            u);
               __syncthreads();
-              values<1, false, false, true>(global_shape_values, u, u);
+              values<1, false, false, true>(get_global_shape_values<Number>(),
+                                            u,
+                                            u);
 
               break;
             }
           case 3:
             {
-              values<0, false, false, true>(global_shape_values, u, u);
+              values<0, false, false, true>(get_global_shape_values<Number>(),
+                                            u,
+                                            u);
               __syncthreads();
-              values<1, false, false, true>(global_shape_values, u, u);
+              values<1, false, false, true>(get_global_shape_values<Number>(),
+                                            u,
+                                            u);
               __syncthreads();
-              values<2, false, false, true>(global_shape_values, u, u);
+              values<2, false, false, true>(get_global_shape_values<Number>(),
+                                            u,
+                                            u);
 
               break;
             }
@@ -345,61 +369,61 @@ namespace CUDAWrappers
         {
           case 1:
             {
-              gradients<0, true, false, false>(global_shape_gradients,
-                                               u,
-                                               grad_u[0]);
+              gradients<0, true, false, false>(
+                get_global_shape_gradients<Number>(), u, grad_u[0]);
 
               break;
             }
           case 2:
             {
-              gradients<0, true, false, false>(global_shape_gradients,
-                                               u,
-                                               grad_u[0]);
-              values<0, true, false, false>(global_shape_values, u, grad_u[1]);
+              gradients<0, true, false, false>(
+                get_global_shape_gradients<Number>(), u, grad_u[0]);
+              values<0, true, false, false>(get_global_shape_values<Number>(),
+                                            u,
+                                            grad_u[1]);
 
               __syncthreads();
 
-              values<1, true, false, true>(global_shape_values,
+              values<1, true, false, true>(get_global_shape_values<Number>(),
                                            grad_u[0],
                                            grad_u[0]);
-              gradients<1, true, false, true>(global_shape_gradients,
-                                              grad_u[1],
-                                              grad_u[1]);
+              gradients<1, true, false, true>(
+                get_global_shape_gradients<Number>(), grad_u[1], grad_u[1]);
 
               break;
             }
           case 3:
             {
-              gradients<0, true, false, false>(global_shape_gradients,
-                                               u,
-                                               grad_u[0]);
-              values<0, true, false, false>(global_shape_values, u, grad_u[1]);
-              values<0, true, false, false>(global_shape_values, u, grad_u[2]);
+              gradients<0, true, false, false>(
+                get_global_shape_gradients<Number>(), u, grad_u[0]);
+              values<0, true, false, false>(get_global_shape_values<Number>(),
+                                            u,
+                                            grad_u[1]);
+              values<0, true, false, false>(get_global_shape_values<Number>(),
+                                            u,
+                                            grad_u[2]);
 
               __syncthreads();
 
-              values<1, true, false, true>(global_shape_values,
+              values<1, true, false, true>(get_global_shape_values<Number>(),
                                            grad_u[0],
                                            grad_u[0]);
-              gradients<1, true, false, true>(global_shape_gradients,
-                                              grad_u[1],
-                                              grad_u[1]);
-              values<1, true, false, true>(global_shape_values,
+              gradients<1, true, false, true>(
+                get_global_shape_gradients<Number>(), grad_u[1], grad_u[1]);
+              values<1, true, false, true>(get_global_shape_values<Number>(),
                                            grad_u[2],
                                            grad_u[2]);
 
               __syncthreads();
 
-              values<2, true, false, true>(global_shape_values,
+              values<2, true, false, true>(get_global_shape_values<Number>(),
                                            grad_u[0],
                                            grad_u[0]);
-              values<2, true, false, true>(global_shape_values,
+              values<2, true, false, true>(get_global_shape_values<Number>(),
                                            grad_u[1],
                                            grad_u[1]);
-              gradients<2, true, false, true>(global_shape_gradients,
-                                              grad_u[2],
-                                              grad_u[2]);
+              gradients<2, true, false, true>(
+                get_global_shape_gradients<Number>(), grad_u[2], grad_u[2]);
 
               break;
             }
@@ -427,49 +451,55 @@ namespace CUDAWrappers
         {
           case 1:
             {
-              values<0, true, false, true>(global_shape_values, u, u);
+              values<0, true, false, true>(get_global_shape_values<Number>(),
+                                           u,
+                                           u);
               __syncthreads();
 
-              gradients<0, true, false, false>(global_co_shape_gradients,
-                                               u,
-                                               grad_u[0]);
+              gradients<0, true, false, false>(
+                get_global_co_shape_gradients<Number>(), u, grad_u[0]);
 
               break;
             }
           case 2:
             {
-              values<0, true, false, true>(global_shape_values, u, u);
+              values<0, true, false, true>(get_global_shape_values<Number>(),
+                                           u,
+                                           u);
               __syncthreads();
-              values<1, true, false, true>(global_shape_values, u, u);
+              values<1, true, false, true>(get_global_shape_values<Number>(),
+                                           u,
+                                           u);
               __syncthreads();
 
-              gradients<0, true, false, false>(global_co_shape_gradients,
-                                               u,
-                                               grad_u[0]);
-              gradients<1, true, false, false>(global_co_shape_gradients,
-                                               u,
-                                               grad_u[1]);
+              gradients<0, true, false, false>(
+                get_global_co_shape_gradients<Number>(), u, grad_u[0]);
+              gradients<1, true, false, false>(
+                get_global_co_shape_gradients<Number>(), u, grad_u[1]);
 
               break;
             }
           case 3:
             {
-              values<0, true, false, true>(global_shape_values, u, u);
+              values<0, true, false, true>(get_global_shape_values<Number>(),
+                                           u,
+                                           u);
               __syncthreads();
-              values<1, true, false, true>(global_shape_values, u, u);
+              values<1, true, false, true>(get_global_shape_values<Number>(),
+                                           u,
+                                           u);
               __syncthreads();
-              values<2, true, false, true>(global_shape_values, u, u);
+              values<2, true, false, true>(get_global_shape_values<Number>(),
+                                           u,
+                                           u);
               __syncthreads();
 
-              gradients<0, true, false, false>(global_co_shape_gradients,
-                                               u,
-                                               grad_u[0]);
-              gradients<1, true, false, false>(global_co_shape_gradients,
-                                               u,
-                                               grad_u[1]);
-              gradients<2, true, false, false>(global_co_shape_gradients,
-                                               u,
-                                               grad_u[2]);
+              gradients<0, true, false, false>(
+                get_global_co_shape_gradients<Number>(), u, grad_u[0]);
+              gradients<1, true, false, false>(
+                get_global_co_shape_gradients<Number>(), u, grad_u[1]);
+              gradients<2, true, false, false>(
+                get_global_co_shape_gradients<Number>(), u, grad_u[2]);
 
               break;
             }
@@ -497,64 +527,64 @@ namespace CUDAWrappers
         {
           case 1:
             {
-              gradients<0, false, add, false>(global_shape_gradients,
-                                              grad_u[dim],
-                                              u);
+              gradients<0, false, add, false>(
+                get_global_shape_gradients<Number>(), grad_u[dim], u);
 
               break;
             }
           case 2:
             {
-              gradients<0, false, false, true>(global_shape_gradients,
-                                               grad_u[0],
-                                               grad_u[0]);
-              values<0, false, false, true>(global_shape_values,
+              gradients<0, false, false, true>(
+                get_global_shape_gradients<Number>(), grad_u[0], grad_u[0]);
+              values<0, false, false, true>(get_global_shape_values<Number>(),
                                             grad_u[1],
                                             grad_u[1]);
 
               __syncthreads();
 
-              values<1, false, add, false>(global_shape_values, grad_u[0], u);
+              values<1, false, add, false>(get_global_shape_values<Number>(),
+                                           grad_u[0],
+                                           u);
               __syncthreads();
-              gradients<1, false, true, false>(global_shape_gradients,
-                                               grad_u[1],
-                                               u);
+              gradients<1, false, true, false>(
+                get_global_shape_gradients<Number>(), grad_u[1], u);
 
               break;
             }
           case 3:
             {
-              gradients<0, false, false, true>(global_shape_gradients,
-                                               grad_u[0],
-                                               grad_u[0]);
-              values<0, false, false, true>(global_shape_values,
+              gradients<0, false, false, true>(
+                get_global_shape_gradients<Number>(), grad_u[0], grad_u[0]);
+              values<0, false, false, true>(get_global_shape_values<Number>(),
                                             grad_u[1],
                                             grad_u[1]);
-              values<0, false, false, true>(global_shape_values,
+              values<0, false, false, true>(get_global_shape_values<Number>(),
                                             grad_u[2],
                                             grad_u[2]);
 
               __syncthreads();
 
-              values<1, false, false, true>(global_shape_values,
+              values<1, false, false, true>(get_global_shape_values<Number>(),
                                             grad_u[0],
                                             grad_u[0]);
-              gradients<1, false, false, true>(global_shape_gradients,
-                                               grad_u[1],
-                                               grad_u[1]);
-              values<1, false, false, true>(global_shape_values,
+              gradients<1, false, false, true>(
+                get_global_shape_gradients<Number>(), grad_u[1], grad_u[1]);
+              values<1, false, false, true>(get_global_shape_values<Number>(),
                                             grad_u[2],
                                             grad_u[2]);
 
               __syncthreads();
 
-              values<2, false, add, false>(global_shape_values, grad_u[0], u);
+              values<2, false, add, false>(get_global_shape_values<Number>(),
+                                           grad_u[0],
+                                           u);
               __syncthreads();
-              values<2, false, true, false>(global_shape_values, grad_u[1], u);
+              values<2, false, true, false>(get_global_shape_values<Number>(),
+                                            grad_u[1],
+                                            u);
               __syncthreads();
-              gradients<2, false, true, false>(global_shape_gradients,
-                                               grad_u[2],
-                                               u);
+              gradients<2, false, true, false>(
+                get_global_shape_gradients<Number>(), grad_u[2], u);
 
               break;
             }
@@ -582,53 +612,59 @@ namespace CUDAWrappers
         {
           case 1:
             {
-              gradients<0, false, true, false>(global_co_shape_gradients,
-                                               grad_u[0],
-                                               u);
+              gradients<0, false, true, false>(
+                get_global_co_shape_gradients<Number>(), grad_u[0], u);
               __syncthreads();
 
-              values<0, false, false, true>(global_shape_values, u, u);
+              values<0, false, false, true>(get_global_shape_values<Number>(),
+                                            u,
+                                            u);
 
               break;
             }
           case 2:
             {
-              gradients<1, false, true, false>(global_co_shape_gradients,
-                                               grad_u[1],
-                                               u);
+              gradients<1, false, true, false>(
+                get_global_co_shape_gradients<Number>(), grad_u[1], u);
               __syncthreads();
-              gradients<0, false, true, false>(global_co_shape_gradients,
-                                               grad_u[0],
-                                               u);
+              gradients<0, false, true, false>(
+                get_global_co_shape_gradients<Number>(), grad_u[0], u);
               __syncthreads();
 
-              values<1, false, false, true>(global_shape_values, u, u);
+              values<1, false, false, true>(get_global_shape_values<Number>(),
+                                            u,
+                                            u);
               __syncthreads();
-              values<0, false, false, true>(global_shape_values, u, u);
+              values<0, false, false, true>(get_global_shape_values<Number>(),
+                                            u,
+                                            u);
               __syncthreads();
 
               break;
             }
           case 3:
             {
-              gradients<2, false, true, false>(global_co_shape_gradients,
-                                               grad_u[2],
-                                               u);
+              gradients<2, false, true, false>(
+                get_global_co_shape_gradients<Number>(), grad_u[2], u);
               __syncthreads();
-              gradients<1, false, true, false>(global_co_shape_gradients,
-                                               grad_u[1],
-                                               u);
+              gradients<1, false, true, false>(
+                get_global_co_shape_gradients<Number>(), grad_u[1], u);
               __syncthreads();
-              gradients<0, false, true, false>(global_co_shape_gradients,
-                                               grad_u[0],
-                                               u);
+              gradients<0, false, true, false>(
+                get_global_co_shape_gradients<Number>(), grad_u[0], u);
               __syncthreads();
 
-              values<2, false, false, true>(global_shape_values, u, u);
+              values<2, false, false, true>(get_global_shape_values<Number>(),
+                                            u,
+                                            u);
               __syncthreads();
-              values<1, false, false, true>(global_shape_values, u, u);
+              values<1, false, false, true>(get_global_shape_values<Number>(),
+                                            u,
+                                            u);
               __syncthreads();
-              values<0, false, false, true>(global_shape_values, u, u);
+              values<0, false, false, true>(get_global_shape_values<Number>(),
+                                            u,
+                                            u);
               __syncthreads();
 
               break;
index 23a7ba1c4f36d3ef459cf0f87bef93572df2a69f..e6e0a2fc8f2b945b467474bd4b1a4f98c61f5d06 100644 (file)
@@ -46,10 +46,10 @@ evaluate_tensor_product(double *dst, double *src)
 
   if (type == 0)
     evaluator.template values<0, dof_to_quad, add, false>(
-      CUDAWrappers::internal::global_shape_values, src, dst);
+      CUDAWrappers::internal::get_global_shape_values<double>(), src, dst);
   if (type == 1)
     evaluator.template gradients<0, dof_to_quad, add, false>(
-      CUDAWrappers::internal::global_shape_values, src, dst);
+      CUDAWrappers::internal::get_global_shape_values<double>(), src, dst);
 }
 
 template <int M, int N, int type, bool add>
@@ -98,20 +98,20 @@ test()
 
   unsigned int size_shape_values = M * N * sizeof(double);
 
-  cudaError_t cuda_error =
-    cudaMemcpyToSymbol(CUDAWrappers::internal::global_shape_values,
-                       shape_host.begin(),
-                       size_shape_values,
-                       0,
-                       cudaMemcpyHostToDevice);
+  cudaError_t cuda_error = cudaMemcpyToSymbol(
+    CUDAWrappers::internal::get_global_shape_values<double>(),
+    shape_host.begin(),
+    size_shape_values,
+    0,
+    cudaMemcpyHostToDevice);
   AssertCuda(cuda_error);
 
-  cuda_error =
-    cudaMemcpyToSymbol(CUDAWrappers::internal::global_shape_gradients,
-                       shape_host.begin(),
-                       size_shape_values,
-                       0,
-                       cudaMemcpyHostToDevice);
+  cuda_error = cudaMemcpyToSymbol(
+    CUDAWrappers::internal::get_global_shape_gradients<double>(),
+    shape_host.begin(),
+    size_shape_values,
+    0,
+    cudaMemcpyHostToDevice);
   AssertCuda(cuda_error);
 
   // Launch the kernel
index 24a8d992d1646a273ea390f7810b9a57d91f5b20..b424baceb8a3a5ad33f19bf38ef5cefd96f33fa0 100644 (file)
@@ -47,18 +47,18 @@ evaluate_tensor_product(double *dst, double *src)
   if (type == 0)
     {
       evaluator.template values<0, dof_to_quad, false, false>(
-        CUDAWrappers::internal::global_shape_values, src, src);
+        CUDAWrappers::internal::get_global_shape_values<double>(), src, src);
       __syncthreads();
       evaluator.template values<1, dof_to_quad, add, false>(
-        CUDAWrappers::internal::global_shape_values, src, dst);
+        CUDAWrappers::internal::get_global_shape_values<double>(), src, dst);
     }
   if (type == 1)
     {
       evaluator.template gradients<0, dof_to_quad, false, false>(
-        CUDAWrappers::internal::global_shape_values, src, src);
+        CUDAWrappers::internal::get_global_shape_values<double>(), src, src);
       __syncthreads();
       evaluator.template gradients<1, dof_to_quad, add, false>(
-        CUDAWrappers::internal::global_shape_values, src, dst);
+        CUDAWrappers::internal::get_global_shape_values<double>(), src, dst);
     }
 }
 
@@ -123,20 +123,20 @@ test()
 
   unsigned int size_shape_values = M * N * sizeof(double);
 
-  cudaError_t cuda_error =
-    cudaMemcpyToSymbol(CUDAWrappers::internal::global_shape_values,
-                       shape_host.begin(),
-                       size_shape_values,
-                       0,
-                       cudaMemcpyHostToDevice);
+  cudaError_t cuda_error = cudaMemcpyToSymbol(
+    CUDAWrappers::internal::get_global_shape_values<double>(),
+    shape_host.begin(),
+    size_shape_values,
+    0,
+    cudaMemcpyHostToDevice);
   AssertCuda(cuda_error);
 
-  cuda_error =
-    cudaMemcpyToSymbol(CUDAWrappers::internal::global_shape_gradients,
-                       shape_host.begin(),
-                       size_shape_values,
-                       0,
-                       cudaMemcpyHostToDevice);
+  cuda_error = cudaMemcpyToSymbol(
+    CUDAWrappers::internal::get_global_shape_gradients<double>(),
+    shape_host.begin(),
+    size_shape_values,
+    0,
+    cudaMemcpyHostToDevice);
   AssertCuda(cuda_error);
 
   // Launch the kernel

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.