diff --git a/src/core/array.hh b/src/core/array.hh index 0fe12c0..d123773 100644 --- a/src/core/array.hh +++ b/src/core/array.hh @@ -1,169 +1,169 @@ /** * * @author Guillaume Anciaux * * @section LICENSE * * Copyright (©) 2016 EPFL (Ecole Polytechnique Fédérale de * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des * Solides) * * Tamaas is free software: you can 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 3 of the License, or (at your option) any * later version. * * Tamaas is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Tamaas. If not, see . * */ /* -------------------------------------------------------------------------- */ #ifndef __ARRAY__HH__ #define __ARRAY__HH__ /* -------------------------------------------------------------------------- */ #include "tamaas.hh" #include #include /* -------------------------------------------------------------------------- */ __BEGIN_TAMAAS__ template class Array { public: /// Default Array(): _data(nullptr), _size(0), wrapped(false), _alloc(DEFAULT_ALLOCATOR()) {} /// Empty array of given size Array(UInt size): Array(DEFAULT_ALLOCATOR()) { this->resize(size); } /// Copy constructor (deep) Array(const Array & v): Array() { this->resize(v._size); std::copy(v._data, v._data+v._size, this->_data); } /// Move constructor (transfers data ownership) Array(Array&& v): Array() { - _data = exchange(v._data, nullptr); - _size = exchange(v._size, 0); - wrapped = exchange(v.wrapped, false); + _data = std::exchange(v._data, nullptr); + _size = std::exchange(v._size, 0); + wrapped = std::exchange(v.wrapped, false); } /// Wrap array on data Array(T * data, UInt size): Array(DEFAULT_ALLOCATOR()) { this->wrapMemory(data, size); } /// Destructor virtual ~Array(){ if (wrapped == false) _alloc.deallocate(_data, _size); } public: /// Copy operator Array & operator=(const Array & v){ this->wrapped = false; if (v.size() != this->size()) this->resize(v.size()); #pragma omp parallel for for (UInt i = 0 ; i < this->_size ; ++i) { _data[i] = v._data[i]; } return *this; } /// Move operator Array & operator=(Array && v) { if (this != &v) { if (!wrapped) _alloc.deallocate(_data, _size); _data = v._data; _size = v._size; wrapped = v.wrapped; v._data = nullptr; v._size = 0; v.wrapped = false; } return *this; } /// Wrap a memory pointer void wrapMemory(T * data, UInt size) { this->_data = data; this->_size = size; this->wrapped = true; } /// Assign a sigle value to the array void assign(UInt size, const T & value){ this->resize(size); #pragma omp parallel for for (UInt i = 0; i < size; i++) { _data[i] = value; } } void setWrapped(bool w) { wrapped = w; } /// Data pointer access (const) const T * data() const{ return _data; } /// Data pointer access (non-const) T * data() { return _data; } /// Data pointer setter void setData(T * new_ptr) { _data = new_ptr;} /// Resize array void resize(UInt size){ if (wrapped == true) TAMAAS_EXCEPTION("cannot resize wrapped array"); // Erase array if (size == 0) { _alloc.deallocate(_data, _size); this->_data = nullptr; this->_size = 0; return; } // Do nothing if (size == this->_size) return; // Allocate new data _alloc.deallocate(_data, _size); this->_data = _alloc.allocate(size); this->_size = size; } /// Access operator inline T & operator[] (UInt i) { TAMAAS_ASSERT(i < _size, "memory overflow"); return _data[i]; } /// Access operator (const) inline const T & operator[] (UInt i) const { TAMAAS_ASSERT(i < _size, "memory overflow"); return _data[i]; } /// Get size of array inline UInt size() const {return _size;} private: T * _data = nullptr; UInt _size = 0; bool wrapped = false; std::allocator _alloc; }; __END_TAMAAS__ /* -------------------------------------------------------------------------- */ #endif /* __ARRAY__HH__ */ diff --git a/src/core/fft_plan_manager.hh b/src/core/fft_plan_manager.hh index 2b7060c..235a6e7 100644 --- a/src/core/fft_plan_manager.hh +++ b/src/core/fft_plan_manager.hh @@ -1,132 +1,132 @@ /** * * @author Guillaume Anciaux * @author Lucas Frérot * * @section LICENSE * * Copyright (©) 2016 EPFL (Ecole Polytechnique Fédérale de * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des * Solides) * * Tamaas is free software: you can 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 3 of the License, or (at your option) any * later version. * * Tamaas is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Tamaas. If not, see . * */ /* -------------------------------------------------------------------------- */ #ifndef FFT_PLAN_MANAGER_H #define FFT_PLAN_MANAGER_H /* -------------------------------------------------------------------------- */ #include #include "fftransform.hh" #include "fftransform_fftw.hh" #ifdef USE_CUDA #include "fftransform_cufft.hh" #endif /* -------------------------------------------------------------------------- */ __BEGIN_TAMAAS__ /* -------------------------------------------------------------------------- */ class FFTPlanManager { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ protected: FFTPlanManager(); public: virtual ~FFTPlanManager(); public: /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ /// Get singleton instance static FFTPlanManager & get(); /// Create/retrieve a plan from two surfaces template FFTransform & createPlan(Grid & input, GridHermitian & output); /// Remove all plans void clean(); /// Destroy a plan from two surfaces template void destroyPlan(Grid & input, GridHermitian & output); /// Destroy any plan containing a given data pointer template void destroyPlan(const T * some); /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ private: - typedef std::map, - std::tuple *, - FFTransform *, - FFTransform *> - > FFTMap; + using FFTMap = std::map, + std::tuple *, + FFTransform *, + FFTransform *> + >; FFTMap plans; static FFTPlanManager * singleton; }; /* -------------------------------------------------------------------------- */ template FFTransform & FFTPlanManager::createPlan(Grid & input, GridHermitian & output){ static_assert(dim <= 3, "Cannot do FFT of dimension higher than 3"); auto index = std::make_pair(const_cast(input.getInternalData()), const_cast(output.getInternalData())); auto it = plans.find(index); auto end = plans.end(); if (it == end) { #ifdef USE_CUDA - //std::get(plans[index]) = new FFTransformCUFFT(input,output); + std::get(plans[index]) = new FFTransformFFTW(input,output); // TODO cuda #else std::get(plans[index]) = new FFTransformFFTW(input,output); #endif } return *std::get(plans[index]); } /* -------------------------------------------------------------------------- */ template void FFTPlanManager::destroyPlan(Grid & input, GridHermitian & output){ auto index = std::make_pair(const_cast(input.getInternalData()), const_cast(output.getInternalData())); auto it = plans.find(index); auto end = plans.end(); if (it != end){ delete std::get(plans[index]); plans.erase(index); } } /* -------------------------------------------------------------------------- */ __END_TAMAAS__ /* -------------------------------------------------------------------------- */ #endif /* FFT_PLAN_MANAGER_H */ diff --git a/src/core/grid_base.hh b/src/core/grid_base.hh index 373bccf..7cd0e48 100644 --- a/src/core/grid_base.hh +++ b/src/core/grid_base.hh @@ -1,318 +1,326 @@ /** * * @author Lucas Frérot * * @section LICENSE * * Copyright (©) 2016 EPFL (Ecole Polytechnique Fédérale de * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des * Solides) * * Tamaas is free software: you can 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 3 of the License, or (at your option) any * later version. * * Tamaas is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Tamaas. If not, see . * */ /* -------------------------------------------------------------------------- */ #ifndef __GRID_BASE_HH__ #define __GRID_BASE_HH__ /* -------------------------------------------------------------------------- */ #include "tamaas.hh" #include "array.hh" #include "iterator.hh" +#include "loop.hh" #include #include #include #include /* -------------------------------------------------------------------------- */ __BEGIN_TAMAAS__ /// Namespace for view index classes namespace view { /// Index class struct index { index(Int i = -1):i(i){} Int i; }; /// Blocked index class struct blocked : public index { blocked(Int i):index(i){} }; /// Free index class struct free : public index { free():index(-1){} }; } template class GridBase { public: /// Constructor by default GridBase() = default; /// Copy constructor GridBase(const GridBase & o): data(o.data), nb_components(o.nb_components), offset(o.offset) {} /// Move constructor (transfers data ownership) GridBase(GridBase&& o): data(std::move(o.data)), - nb_components(exchange(o.nb_components, 1)), - offset(exchange(o.offset, 0)) {} + nb_components(std::exchange(o.nb_components, 1)), + offset(std::exchange(o.offset, 0)) {} /// Destructor virtual ~GridBase() = default; /* -------------------------------------------------------------------------- */ /* Iterator class */ /* -------------------------------------------------------------------------- */ public: using iterator = iterator_::iterator; using const_iterator = iterator_::iterator; public: /// Compute size virtual UInt computeSize() const = 0; /// Get internal data pointer (const) const T * getInternalData() const {return this->data.data();} /// Get internal data pointer (non-const) T * getInternalData() {return this->data.data();} /// Get number of components UInt getNbComponents() const {return nb_components;} /// Set number of components void setNbComponents(UInt n) {nb_components = n;} /// Get offset UInt getOffset() const {return offset;} /// Get total size virtual UInt dataSize() const {return this->data.size(); } /// Get number of points UInt getNbPoints() const {return this->computeSize() / this->getNbComponents(); } /// Set components void uniformSetComponents(const GridBase & vec); /* -------------------------------------------------------------------------- */ /* Iterator methods */ /* -------------------------------------------------------------------------- */ virtual iterator begin(UInt n = 1) = 0; virtual iterator end(UInt n = 1) = 0; virtual const_iterator begin(UInt n = 1) const = 0; virtual const_iterator end(UInt n = 1) const = 0; /* -------------------------------------------------------------------------- */ /* Operators */ /* -------------------------------------------------------------------------- */ + inline T & operator()(UInt i) { + return this->data[i]; + } + + inline const T & operator()(UInt i) const { + return this->data[i]; + } + #define VEC_OPERATOR(op) \ template \ GridBase & operator op(const GridBase & other) \ VEC_OPERATOR(+=); VEC_OPERATOR(*=); VEC_OPERATOR(-=); VEC_OPERATOR(/=); #undef VEC_OPERATOR template T dot(const GridBase & other); #define SCALAR_OPERATOR(op) \ GridBase & operator op(const T & e) \ SCALAR_OPERATOR(+=); SCALAR_OPERATOR(*=); SCALAR_OPERATOR(-=); SCALAR_OPERATOR(/=); SCALAR_OPERATOR(=); #undef SCALAR_OPERATOR GridBase & operator=(const GridBase & o); /* -------------------------------------------------------------------------- */ /* Min/max */ /* -------------------------------------------------------------------------- */ T min() const; T max() const; T sum() const; T mean() const { return sum() / dataSize(); } T var() const; /* -------------------------------------------------------------------------- */ /* Move/Copy */ /* -------------------------------------------------------------------------- */ public: template void copy(const GridBase & other) { data = other.data; nb_components = other.nb_components; offset = other.offset; } template void move(GridBase && other) { data = std::move(other.data); - nb_components = exchange(other.nb_components, 1); - offset = exchange(other.offset, 0); + nb_components = std::exchange(other.nb_components, 1); + offset = std::exchange(other.offset, 0); } protected: Array data; UInt nb_components = 1; UInt offset = 0; }; /* -------------------------------------------------------------------------- */ template void GridBase::uniformSetComponents(const GridBase &vec) { if (!(vec.dataSize() == this->nb_components)) TAMAAS_EXCEPTION("Cannot set grid field with values of vector"); auto begin_it(begin()); auto end_it(end()); // silencing nvcc warnings #pragma omp parallel for for (auto it = begin() ; it < end_it ; ++it) { UInt i = it - begin_it; *it = vec.data[i % this->nb_components]; } } /* -------------------------------------------------------------------------- */ #define SCALAR_OPERATOR_IMPL(op) \ template \ inline GridBase & GridBase::operator op(const T & e) { \ - _Pragma("omp parallel for") \ - for (auto it = this->begin() ; it < this->end() ; ++it) { \ - *it op e; \ - } \ + Loop::get().loop([&](T & val) { \ + val op e; \ + }, *this); \ return *this; \ } \ SCALAR_OPERATOR_IMPL(+=); SCALAR_OPERATOR_IMPL(*=); SCALAR_OPERATOR_IMPL(-=); SCALAR_OPERATOR_IMPL(/=); SCALAR_OPERATOR_IMPL(=); #undef SCALAR_OPERATOR_IMPL /* -------------------------------------------------------------------------- */ #define VEC_OPERATOR_IMPL(op) \ template \ template \ inline GridBase & GridBase::operator op(const GridBase & other) { \ TAMAAS_ASSERT(other.computeSize() == this->computeSize(), \ "surface size does not match"); \ auto begin_it(begin()); auto end_it(end()); \ auto other_begin(other.begin()); auto other_it(other.begin()); \ _Pragma("omp parallel for firstprivate(other_it)") \ for (auto it = begin() ; it < end_it ; ++it) { \ other_it = other_begin; \ other_it += it - begin_it; \ *it op *other_it; \ } \ return *this; \ } \ VEC_OPERATOR_IMPL(+=); VEC_OPERATOR_IMPL(-=); VEC_OPERATOR_IMPL(*=); VEC_OPERATOR_IMPL(/=); #undef VEC_OPERATOR /* -------------------------------------------------------------------------- */ template GridBase & GridBase::operator=(const GridBase & o) { this->copy(o); return *this; } /* -------------------------------------------------------------------------- */ template inline T GridBase::min() const { T val = std::numeric_limits::max(); auto begin_it(begin()); auto end_it(end()); #pragma omp parallel for reduction(min:val) for (auto it = begin_it ; it < end_it ; ++it) { val = std::min(*it, val); } return val; } /* -------------------------------------------------------------------------- */ template inline T GridBase::max() const { T val = std::numeric_limits::lowest(); auto begin_it = begin(); auto end_it = end(); #pragma omp parallel for reduction(max:val) for (auto it = begin_it ; it < end_it ; ++it) { val = std::max(*it, val); } return val; } /* -------------------------------------------------------------------------- */ template inline T GridBase::sum() const { T val = 0; auto begin_it(begin()); auto end_it(end()); #pragma omp parallel for reduction(+:val) for (auto it = begin_it ; it < end_it ; ++it) { val += *it; } return val; } /* -------------------------------------------------------------------------- */ template inline T GridBase::var() const { T var = 0; const T mu = mean(); auto begin_it(begin()); auto end_it(end()); #pragma omp parallel for reduction(+:var) for (auto it = begin_it ; it < end_it ; ++it) { var += (*it - mu) * (*it - mu); } return var / (dataSize() - 1); } /* -------------------------------------------------------------------------- */ template template T GridBase::dot(const GridBase & other) { T res = 0; auto begin_it(begin()); auto end_it(end()); auto other_b(other.begin()); auto other_it(other.begin()); #pragma omp parallel for firstprivate(other_it) reduction(+: res) for (auto it = begin_it ; it < end_it ; ++it) { other_it = other_b; other_it += it - begin_it; res += *it * *other_it; } return res; } __END_TAMAAS__ #endif // __GRID_BASE_HH__ diff --git a/src/core/grid_view.hh b/src/core/grid_view.hh index 4b3ee58..7d80aaa 100644 --- a/src/core/grid_view.hh +++ b/src/core/grid_view.hh @@ -1,265 +1,265 @@ /** * * @author Lucas Frérot * * @section LICENSE * * Copyright (©) 2016 EPFL (Ecole Polytechnique Fédérale de * Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des * Solides) * * Tamaas is free software: you can 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 3 of the License, or (at your option) any * later version. * * Tamaas is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Tamaas. If not, see . * */ /* -------------------------------------------------------------------------- */ #ifndef __GRID_VIEW_HH__ #define __GRID_VIEW_HH__ /* -------------------------------------------------------------------------- */ #include "tamaas.hh" #include "grid.hh" #include /* -------------------------------------------------------------------------- */ __BEGIN_TAMAAS__ /* -------------------------------------------------------------------------- */ /** * @brief View type on grid * /!\ iterators do not work on this type of grid * */ template