23template<
class T,
size_t d>
31 fill(
e.begin(),
e.end(), 0);
52 cudaMemcpyDeviceToDevice);
54 cout <<
"ERROR: compiled without GPU support" << __FILE__ <<
":"
66 }
else if(
e != ma.
e) {
67 cout <<
"ERROR: array dimensions do not match in assignment" << endl;
77 cudaMemcpyDeviceToHost);
80 cudaMemcpyHostToDevice);
83 cudaMemcpyDeviceToDevice);
86 cout <<
"ERROR: compiled without GPU support" << endl;
110 cout <<
"ERROR: compiled without GPU support" << __FILE__ <<
":"
118 void reserve(array<Index,d> _emax, array<Index,d> _e) {
135 cout <<
"ERROR: compiled without GPU support" << __FILE__ <<
":"
145 cout <<
"ERROR: can't swap DEVICE and HOST multi_arrays" << __FILE__ <<
":"
166 cout <<
"ERROR: compiled without GPU support" << __FILE__ <<
":"
177 for(
Index i=0;i<n;i++)
189 for(
size_t i=0;i<d;i++) {
198 std::transform(
begin(),
end(), out.begin(), [](
const T& c){return complex<T>(c,T(0.0));} );
202 std::ofstream fs(fn.c_str(), std::ios::binary);
216 template<
typename... Ints>
218 static_assert(
sizeof...(Ints) == d,
"wrong number of arguments to ().");
222 template<
typename... Ints>
224 static_assert(
sizeof...(Ints) == d,
"wrong number of arguments to ().");
231 std::copy(std::begin(idx_r), std::end(idx_r), std::begin(idx)+1);
236 const T*
extract(array<Index,d-1> idx_r)
const {
238 std::copy(std::begin(idx_r), std::end(idx_r), std::begin(idx)+1);
254 cout <<
"ERROR: data() called on an uninitialized multi_array" << endl;
262 cout <<
"ERROR: data() called on an uninitialized multi_array" << endl;
270 cout <<
"ERROR: begin() called on an uninitialized multi_array" << endl;
278 cout <<
"ERROR: begin() called on an uninitialized multi_array" << endl;
286 cout <<
"ERROR: end() called on an uninitialized multi_array" << endl;
295 #pragma omp parallel for simd
301 if(std::is_same<T, complex<double>>::value)
303 else if(std::is_same<T, double>::value)
306 cout <<
"ERROR: single precision in operator+= currently not implemented" << endl;
311 cout <<
"ERROR: for operator+= both operands need to be either on the device or on the host." << endl;
320 #pragma omp parallel for simd
335 #pragma omp parallel for simd
341 if(std::is_same<T, double>::value)
344 cout <<
"ERROR: attempted operation not implemented on device (operator+=)" << endl;
355 #pragma omp parallel for simd
370 #pragma omp parallel for simd
375 cout <<
"ERROR: operator/= is not implemented on the device." << endl;
385 #pragma omp parallel for simd
388 out.
v[i] =
v[i] + lhs.
v[i];
391 cout <<
"ERROR: operator+ is not implemented on the device." << endl;
400 #pragma omp parallel for simd
403 out.
v[i] =
v[i] - lhs.
v[i];
406 cout <<
"ERROR: operator- is not implemented on the device." << endl;
415 #pragma omp parallel for simd
418 out.
v[i] =
v[i]*scalar;
421 cout <<
"ERROR: operator* is not implemented on the device." << endl;
428 if(A.
shape().size() == 1){
430 os << A.
v[i] <<
'\n';
432 }
else if(A.
shape().size() == 2){
435 os << std::setw(20) << A.
v[i + j*A.
shape()[0]];
440 cout <<
"ERROR: dimension for cout not yet supported" << endl;
446 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
448 if(
v ==
nullptr || lhs.
v ==
nullptr) {
449 cout <<
"ERROR: comparison == for two multi_array where one is not initialized" << endl;
455 if(std::isnan(lhs.
v[i]) || std::isnan(
v[i]))
457 if(std::abs((lhs.
v[i] -
v[i])) > T(10000)*std::numeric_limits<T>::epsilon())
468 v[i] += scalar*ma.
v[i];
471 cout <<
"ERROR: multi_array::sadd is not implemented for GPUs" << endl;
479 void run_ptw_mult_scal(
Index n,
double*
v,
double scalar) {
480 ptw_mult_scal<<<(n+n_threads-1)/n_threads,n_threads>>>(n,
v, scalar);
483 void run_ptw_mult_scal(
Index n,
float*
v,
float scalar) {
484 ptw_mult_scal<<<(n+n_threads-1)/n_threads,n_threads>>>(n,
v, scalar);
487 void run_ptw_mult_scal(
Index n, complex<double>*
v, complex<double> scalar) {
488 ptw_mult_scal_cplx<<<(n+n_threads-1)/n_threads,n_threads>>>(n, (cuDoubleComplex*)
v, make_cuDoubleComplex(scalar.real(), scalar.imag()));
501 fs << h_ma.
v[idx] << endl;
512 for(
Index idx=0;idx<ma.num_elements();idx++)
513 fs << h_ma.
v[idx].real() <<
" " << h_ma.
v[idx].imag() << endl;
521 cout << ma(i,j) <<
" ";
Provides shared types, platform headers, and basic definitions.
Declares CUDA kernels for elementwise operations and numerical updates.
Core namespace for Ensign's numerical algorithms and data structures.
void print(const multi_array< T, 2 > &ma)
void dump(string fn, const multi_array< double, d > &ma)
Dense d-dimensional array stored contiguously in column-major order (i.e.
void save_vector(std::string fn)
array< Index, d > shape() const
const T & operator()(Ints &&... idx) const
void update_shape(array< Index, d > _e)
void swap(multi_array &ma)
void to_cplx(multi_array< complex< T >, d > &out) const
array< Index, d > shape_alloc() const
void sadd(const T scalar, const multi_array &ma)
multi_array operator*(const T scalar)
T & operator()(Ints &&... idx)
Index num_elements() const
multi_array & operator+=(const multi_array &lhs)
multi_array(stloc _sl=stloc::host)
multi_array(const multi_array &ma)
const T * extract(array< Index, d-1 > idx_r) const
multi_array operator+(const multi_array &lhs)
multi_array & operator+=(const T scalar)
multi_array & operator/=(const T scalar)
void reserve(array< Index, d > _emax, array< Index, d > _e)
Index linear_idx(array< Index, d > idx) const
T & operator()(array< Index, d > idx)
multi_array & operator-=(const multi_array &lhs)
void resize(array< Index, d > _e)
T * extract(array< Index, d-1 > idx_r)
const T & operator()(array< Index, d > idx) const
multi_array(array< Index, d > _e, stloc _sl=stloc::host)
multi_array(array< Index, d > _emax, array< Index, d > _e, stloc _sl=stloc::host)
T * begin() const noexcept
multi_array & operator*=(T scalar)
friend std::ostream & operator<<(std::ostream &os, const multi_array &A)
bool operator==(const multi_array &lhs) const
multi_array & operator=(const multi_array &ma)
multi_array operator-(const multi_array &lhs)
Provides numerical helpers and utilities for arrays and indices.