#include <ostream>
#include <vector>
+
DEAL_II_NAMESPACE_OPEN
// Forward declarations:
/**
* Constructor. Set to zero.
+ *
+ * @ingroup CUDAWrappers
*/
- Tensor ();
+ DEAL_II_CUDA_HOST_DEV Tensor ();
/**
* Constructor from tensors with different underlying scalar type. This
*
* This is the non-const conversion operator that returns a writable
* reference.
+ *
+ * @ingroup CUDAWrappers
*/
- operator Number &();
+ DEAL_II_CUDA_HOST_DEV operator Number &();
/**
* Return a reference to the encapsulated Number object. Since rank-0
* tensors are scalars, this is a natural operation.
*
* This is the const conversion operator that returns a read-only reference.
+ *
+ * @ingroup CUDAWrappers
*/
- operator const Number &() const;
+ DEAL_II_CUDA_HOST_DEV operator const Number &() const;
/**
* Assignment from tensors with different underlying scalar type. This
/**
* Multiply the scalar with a <tt>factor</tt>.
+ *
+ * @ingroup CUDAWrappers
*/
template<typename OtherNumber>
- Tensor<0,dim,Number> &operator *= (const OtherNumber factor);
+ DEAL_II_CUDA_HOST_DEV Tensor<0,dim,Number> &operator *= (const OtherNumber factor);
/**
* Divide the scalar by <tt>factor</tt>.
/**
* Return the square of the Frobenius-norm of a tensor, i.e. the sum of the
* absolute squares of all entries.
+ *
+ * @ingroup CUDAWrappers
*/
- real_type norm_square () const;
+ DEAL_II_CUDA_HOST_DEV real_type norm_square () const;
/**
* Read or write the data of this object to or from a stream for the purpose
/**
* Constructor. Initialize all entries to zero.
+ *
+ * @ingroup CUDAWrappers
*/
- Tensor ();
+ DEAL_II_CUDA_HOST_DEV Tensor ();
/**
* Constructor, where the data is copied from a C-style array.
/**
* Read-Write access operator.
+ *
+ * @ingroup CUDAWrappers
*/
- value_type &operator [] (const unsigned int i);
+ DEAL_II_CUDA_HOST_DEV value_type &operator [] (const unsigned int i);
/**
* Read-only access operator.
+ *
+ * @ingroup CUDAWrappers
*/
- const value_type &operator[](const unsigned int i) const;
+ DEAL_II_CUDA_HOST_DEV const value_type &operator[](const unsigned int i) const;
/**
* Read access using TableIndices <tt>indices</tt>
/**
* Scale the tensor by <tt>factor</tt>, i.e. multiply all components by
* <tt>factor</tt>.
+ *
+ * @ingroup CUDAWrappers
*/
template <typename OtherNumber>
- Tensor<rank_,dim,Number> &operator *= (const OtherNumber factor);
+ DEAL_II_CUDA_HOST_DEV Tensor<rank_,dim,Number> &operator *= (const OtherNumber factor);
/**
* Scale the vector by <tt>1/factor</tt>.
/**
* Return the square of the Frobenius-norm of a tensor, i.e. the sum of the
* absolute squares of all entries.
+ *
+ * @ingroup CUDAWrappers
*/
- typename numbers::NumberTraits<Number>::real_type norm_square() const;
+ DEAL_II_CUDA_HOST_DEV typename numbers::NumberTraits<Number>::real_type norm_square() const;
/**
* Fill a vector with all tensor elements.
template <int dim,typename Number>
inline
-Tensor<0,dim,Number>::Tensor ()
+DEAL_II_CUDA_HOST_DEV Tensor<0,dim,Number>::Tensor ()
: value()
{
}
template <int dim, typename Number>
inline
-Tensor<0,dim,Number>::operator Number &()
+DEAL_II_CUDA_HOST_DEV Tensor<0,dim,Number>::operator Number &()
{
Assert(dim != 0, ExcMessage("Cannot access an object of type Tensor<0,0,Number>"));
return value;
template <int dim, typename Number>
inline
-Tensor<0,dim,Number>::operator const Number &() const
+DEAL_II_CUDA_HOST_DEV Tensor<0,dim,Number>::operator const Number &() const
{
Assert(dim != 0, ExcMessage("Cannot access an object of type Tensor<0,0,Number>"));
return value;
template <int dim, typename Number>
template <typename OtherNumber>
inline
-Tensor<0,dim,Number> &Tensor<0,dim,Number>::operator *= (const OtherNumber s)
+DEAL_II_CUDA_HOST_DEV Tensor<0,dim,Number> &Tensor<0,dim,Number>::operator *= (const OtherNumber s)
{
value *= s;
return *this;
template <int dim, typename Number>
inline
typename Tensor<0,dim,Number>::real_type
-Tensor<0,dim,Number>::norm_square () const
+DEAL_II_CUDA_HOST_DEV Tensor<0,dim,Number>::norm_square () const
{
Assert(dim != 0, ExcMessage("Cannot access an object of type Tensor<0,0,Number>"));
return numbers::NumberTraits<Number>::abs_square (value);
template <int rank_, int dim, typename Number>
inline
-Tensor<rank_,dim,Number>::Tensor ()
+DEAL_II_CUDA_HOST_DEV Tensor<rank_,dim,Number>::Tensor ()
{
// All members of the c-style array values are already default initialized
// and thus all values are already set to zero recursively.
{
template <typename ArrayElementType, int dim>
inline DEAL_II_ALWAYS_INLINE
+ DEAL_II_CUDA_HOST_DEV
ArrayElementType &
subscript (ArrayElementType *values,
const unsigned int i,
template <typename ArrayElementType>
+ DEAL_II_CUDA_HOST_DEV
ArrayElementType &
subscript (ArrayElementType *,
const unsigned int,
template <int rank_, int dim, typename Number>
inline DEAL_II_ALWAYS_INLINE
+DEAL_II_CUDA_HOST_DEV
typename Tensor<rank_,dim,Number>::value_type &
Tensor<rank_,dim,Number>::operator[] (const unsigned int i)
{
template <int rank_, int dim, typename Number>
inline DEAL_II_ALWAYS_INLINE
+DEAL_II_CUDA_HOST_DEV
const typename Tensor<rank_,dim,Number>::value_type &
Tensor<rank_,dim,Number>::operator[] (const unsigned int i) const
{
template <int rank_, int dim, typename Number>
template <typename OtherNumber>
inline
+DEAL_II_CUDA_HOST_DEV
Tensor<rank_,dim,Number> &
Tensor<rank_,dim,Number>::operator *= (const OtherNumber s)
{
template <int rank_, int dim, typename Number>
inline
+DEAL_II_CUDA_HOST_DEV
typename numbers::NumberTraits<Number>::real_type
Tensor<rank_,dim,Number>::norm_square () const
{
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 2016 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE at
+// the top level of the deal.II distribution.
+//
+// ---------------------------------------------------------------------
+
+// Test operator[] and norm_square of cuda_tensor.
+
+#include "../tests.h"
+#include <deal.II/base/tensor.h>
+#include <deal.II/base/logstream.h>
+#include <fstream>
+#include <iomanip>
+
+void test_cpu()
+{
+ double a[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
+ const unsigned int dim=3;
+ Tensor<2,dim> t;
+ for (unsigned int i=0; i<dim; ++i)
+ for (unsigned int j=0; j<dim; ++j)
+ t[i][j] = a[i][j];
+
+
+ deallog.push("values");
+ for (unsigned int i=0; i<dim; ++i)
+ for (unsigned int j=0; j<dim; ++j)
+ deallog << t[i][j] << std::endl;
+ deallog.pop();
+
+ deallog.push("norm_square");
+ deallog << t.norm_square() << std::endl;
+ deallog.pop();
+}
+
+__global__ void init_kernel(Tensor<2,3> *t,
+ const unsigned int N)
+{
+ const unsigned int i = threadIdx.y;
+ const unsigned int j = threadIdx.x;
+ if ((i < N) && (j < N))
+ (*t)[i][j] = j + i*N + 1.;
+}
+
+__global__ void norm_kernel(Tensor<2,3> *t, double *norm)
+{
+ if (threadIdx.x == 0)
+ *norm = t->norm_square();
+}
+
+void test_gpu()
+{
+ const unsigned int dim=3;
+ double *norm_dev;
+ double norm_host;
+ Tensor<2,dim> *t_dev;
+
+ // Allocate objects on the device
+ cudaError_t cuda_error = cudaMalloc(&t_dev, sizeof(Tensor<2,dim>));
+ AssertCuda(cuda_error);
+ cuda_error = cudaMalloc(&norm_dev, sizeof(double));
+ AssertCuda(cuda_error);
+
+ // Launch the kernels.
+ dim3 block_dim(dim, dim);
+ init_kernel<<<1,block_dim>>>(t_dev, dim);
+ norm_kernel<<<1,1>>>(t_dev, norm_dev);
+
+ // Copy the result to the device
+ cuda_error = cudaMemcpy(&norm_host, norm_dev, sizeof(double),
+ cudaMemcpyDeviceToHost);
+ AssertCuda(cuda_error);
+
+ // Free memory
+ cuda_error = cudaFree(t_dev);
+ AssertCuda(cuda_error);
+ cuda_error = cudaFree(norm_dev);
+ AssertCuda(cuda_error);
+
+ // Output result
+ deallog.push("norm_square GPU");
+ deallog << norm_host << std::endl;
+}
+
+int main ()
+{
+ std::ofstream logfile("output");
+ deallog << std::setprecision(5);
+ deallog.attach(logfile);
+ deallog.threshold_double(1.e-10);
+
+ test_cpu();
+
+ test_gpu();
+}