atlas
Vector.h
1 /*
2 * (C) Copyright 2013 ECMWF.
3 *
4 * This software is licensed under the terms of the Apache Licence Version 2.0
5 * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
6 * In applying this licence, ECMWF does not waive the privileges and immunities
7 * granted to it by virtue of its status as an intergovernmental organisation nor
8 * does it submit to any jurisdiction.
9 */
10 
11 #pragma once
12 
13 #include <cassert>
14 #include <cstddef>
15 
16 #include "atlas/library/config.h"
17 #include "atlas/runtime/Exception.h"
18 
19 #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA
20 #include <cuda_runtime.h>
21 #endif
22 
23 namespace atlas {
24 namespace array {
25 
26 //------------------------------------------------------------------------------
27 
28 template <typename T>
29 class Vector {
30 public:
31  Vector( idx_t N = 0 ) : data_( N ? new T[N] : nullptr ), data_gpu_( nullptr ), size_( N ) {}
32 
33  void resize_impl( idx_t N ) {
34  ATLAS_ASSERT( not data_gpu_, "we can not resize a vector after has been cloned to device" );
35  ATLAS_ASSERT( N >= size_ );
36  if ( N == size_ )
37  return;
38 
39  T* d_ = new T[N];
40  for ( idx_t c = 0; c < size_; ++c ) {
41  d_[c] = data_[c];
42  }
43  if ( data_ )
44  delete[] data_;
45  data_ = d_;
46  }
47 
48  void resize( idx_t N ) {
49  resize_impl( N );
50  size_ = N;
51  }
52 
53  void resize( idx_t N, T val ) {
54  resize_impl( N );
55  for ( idx_t c = size_; c < N; ++c ) {
56  data_[c] = val;
57  }
58 
59  size_ = N;
60  }
61 
62  void updateDevice() {
63  if ( !data_gpu_ ) {
64 #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA
65  ::cudaMalloc( (void**)( &data_gpu_ ), sizeof( T* ) * size_ );
66 
67  T* buff = new T[size_];
68 
69  for ( idx_t i = 0; i < size(); ++i ) {
70  data_[i]->updateDevice();
71  buff[i] = data_[i]->gpu_object_ptr();
72  }
73  ::cudaMemcpy( data_gpu_, buff, sizeof( T* ) * size_, cudaMemcpyHostToDevice );
74  delete buff;
75 #else
76  data_gpu_ = data_;
77 #endif
78  size_gpu_ = size_;
79  }
80  else {
81  ATLAS_ASSERT( size_gpu_ == size_ );
82 #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA
83  for ( idx_t i = 0; i < size(); ++i ) {
84  data_[i]->updateDevice();
85  assert( data_gpu_[i] == data_[i]->gpu_object_ptr() );
86  }
87 #endif
88  }
89  }
90  void updateHost() {
91  ATLAS_ASSERT( data_gpu_ != nullptr );
92 
93 #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA
94 
95  for ( idx_t i = 0; i < size(); ++i ) {
96  data_[i]->updateHost();
97  }
98 #endif
99  }
100 
101  T* gpu_object_ptr() { return data_gpu_; }
102 
103  T* data() { return data_; }
104  T* data_gpu() { return data_gpu_; }
105 
106  idx_t size() const { return size_; }
107 
108 private:
109  T* data_;
110  T* data_gpu_;
111  idx_t size_;
112  idx_t size_gpu_;
113 };
114 
115 template <typename T>
116 class VectorView {
117 public:
118  VectorView() : vector_( nullptr ), data_( nullptr ), size_( 0 ) {}
119  VectorView( Vector<T> const& vector, T* data ) : vector_( &vector ), data_( data ), size_( vector.size() ) {}
120 
121  ATLAS_HOST_DEVICE
122  T& operator[]( idx_t idx ) {
123  assert( idx < size_ );
124 
125  return data_[idx];
126  }
127 
128  ATLAS_HOST_DEVICE
129  T const& operator[]( idx_t idx ) const {
130  assert( idx < size_ );
131  return data_[idx];
132  }
133  ATLAS_HOST_DEVICE
134  T base() { return *data_; }
135 
136  ATLAS_HOST_DEVICE
137  idx_t size() const { return size_; }
138 
139  bool is_valid( Vector<T>& vector ) { return ( &vector ) == vector_ && ( data_ != nullptr ); }
140 
141 public:
142  Vector<T> const* vector_;
143  T* data_;
144  idx_t size_;
145 };
146 
147 template <typename T>
148 VectorView<T> make_host_vector_view( Vector<T> vector_ ) {
149  return VectorView<T>( vector_, vector_.data() );
150 }
151 
152 template <typename T>
153 VectorView<T> make_device_vector_view( Vector<T> vector_ ) {
154  return VectorView<T>( vector_, vector_.data_gpu() );
155 }
156 
157 //------------------------------------------------------------------------------
158 
159 } // namespace array
160 } // namespace atlas
Definition: CubedSphereMeshGenerator.h:25
Definition: Vector.h:29
Contains all atlas classes and methods.
Definition: atlas-grids.cc:33
long idx_t
Integer type for indices in connectivity tables.
Definition: config.h:42
Definition: Vector.h:116