Planned maintenance on Wednesday, 2021-01-20, 17:00-18:00. Expect some interruptions during that time

Commit 9b34409f authored by Martin Reinecke's avatar Martin Reinecke

MAVs can manage their own memory if requested

parent 1d0a0e1d
...@@ -2898,8 +2898,7 @@ template<typename T> void c2r(const cfmav<std::complex<T>> &in, ...@@ -2898,8 +2898,7 @@ template<typename T> void c2r(const cfmav<std::complex<T>> &in,
return c2r(in, out, axes[0], forward, fct, nthreads); return c2r(in, out, axes[0], forward, fct, nthreads);
util::sanity_check_cr(in, out, axes); util::sanity_check_cr(in, out, axes);
if (in.size()==0) return; if (in.size()==0) return;
aligned_array<std::complex<T>> tmp(in.size()); fmav<std::complex<T>> atmp(in.shape());
fmav<std::complex<T>> atmp(tmp.data(), in);
auto newaxes = shape_t({axes.begin(), --axes.end()}); auto newaxes = shape_t({axes.begin(), --axes.end()});
c2c(in, atmp, newaxes, forward, T(1), nthreads); c2c(in, atmp, newaxes, forward, T(1), nthreads);
c2r(atmp, out, axes.back(), forward, fct, nthreads); c2r(atmp, out, axes.back(), forward, fct, nthreads);
...@@ -2933,9 +2932,7 @@ template<typename T> void r2r_genuine_hartley(const cfmav<T> &in, ...@@ -2933,9 +2932,7 @@ template<typename T> void r2r_genuine_hartley(const cfmav<T> &in,
if (in.size()==0) return; if (in.size()==0) return;
shape_t tshp(in.shape()); shape_t tshp(in.shape());
tshp[axes.back()] = tshp[axes.back()]/2+1; tshp[axes.back()] = tshp[axes.back()]/2+1;
auto tinfo = fmav_info(tshp); fmav<std::complex<T>> atmp(tshp);
aligned_array<std::complex<T>> tdata(tinfo.size());
fmav<std::complex<T>> atmp(tdata.data(), tinfo);
r2c(in, atmp, axes, true, fct, nthreads); r2c(in, atmp, axes, true, fct, nthreads);
simple_iter iin(atmp); simple_iter iin(atmp);
rev_iter iout(out, axes); rev_iter iout(out, axes);
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <cstdlib> #include <cstdlib>
#include <array> #include <array>
#include <vector> #include <vector>
#include <memory>
#include "mr_util/error_handling.h" #include "mr_util/error_handling.h"
namespace mr { namespace mr {
...@@ -85,10 +86,14 @@ class fmav_info ...@@ -85,10 +86,14 @@ class fmav_info
{ return shp==other.shp; } { return shp==other.shp; }
}; };
template<typename T, size_t ndim> class cmav;
// "mav" stands for "multidimensional array view" // "mav" stands for "multidimensional array view"
template<typename T> class cfmav: public fmav_info template<typename T> class cfmav: public fmav_info
{ {
protected: protected:
using Tsp = shared_ptr<vector<T>>;
Tsp ptr;
T *d; T *d;
public: public:
...@@ -96,16 +101,26 @@ template<typename T> class cfmav: public fmav_info ...@@ -96,16 +101,26 @@ template<typename T> class cfmav: public fmav_info
: fmav_info(shp_, str_), d(const_cast<T *>(d_)) {} : fmav_info(shp_, str_), d(const_cast<T *>(d_)) {}
cfmav(const T *d_, const shape_t &shp_) cfmav(const T *d_, const shape_t &shp_)
: fmav_info(shp_), d(const_cast<T *>(d_)) {} : fmav_info(shp_), d(const_cast<T *>(d_)) {}
cfmav(const shape_t &shp_)
: fmav_info(shp_), ptr(make_unique<vector<T>>(size())),
d(const_cast<T *>(ptr->data())) {}
cfmav(const T* d_, const fmav_info &info) cfmav(const T* d_, const fmav_info &info)
: fmav_info(info), d(const_cast<T *>(d_)) {} : fmav_info(info), d(const_cast<T *>(d_)) {}
cfmav(const cfmav &other) = default;
cfmav(cfmav &&other) = default;
// Not for public use!
cfmav(const T *d_, const Tsp &p, const shape_t &shp_, const stride_t &str_)
: fmav_info(shp_, str_), ptr(p), d(const_cast<T *>(d_)) {}
template<typename I> const T &operator[](I i) const template<typename I> const T &operator[](I i) const
{ return d[i]; } { return d[i]; }
const T *data() const const T *data() const
{ return d; } { return d; }
}; };
template<typename T> class fmav: public cfmav<T> template<typename T> class fmav: public cfmav<T>
{ {
protected: protected:
using Tsp = shared_ptr<vector<T>>;
using parent = cfmav<T>; using parent = cfmav<T>;
using parent::d; using parent::d;
using parent::shp; using parent::shp;
...@@ -116,8 +131,16 @@ template<typename T> class fmav: public cfmav<T> ...@@ -116,8 +131,16 @@ template<typename T> class fmav: public cfmav<T>
: parent(d_, shp_, str_) {} : parent(d_, shp_, str_) {}
fmav(T *d_, const shape_t &shp_) fmav(T *d_, const shape_t &shp_)
: parent(d_, shp_) {} : parent(d_, shp_) {}
fmav(const shape_t &shp_)
: parent(shp_) {}
fmav(T* d_, const fmav_info &info) fmav(T* d_, const fmav_info &info)
: parent(d_, info) {} : parent(d_, info) {}
fmav(const fmav &other) = default;
fmav(fmav &&other) = default;
// Not for public use!
fmav(T *d_, const Tsp &p, const shape_t &shp_, const stride_t &str_)
: parent(d_, p, shp_, str_) {}
template<typename I> T &operator[](I i) const template<typename I> T &operator[](I i) const
{ return d[i]; } { return d[i]; }
using parent::shape; using parent::shape;
...@@ -129,31 +152,40 @@ template<typename T> class fmav: public cfmav<T> ...@@ -129,31 +152,40 @@ template<typename T> class fmav: public cfmav<T>
using parent::conformable; using parent::conformable;
}; };
template<typename T, size_t ndim> class cmav template<typename T, size_t ndim> class cmav
{ {
static_assert((ndim>0) && (ndim<3), "only supports 1D and 2D arrays"); static_assert((ndim>0) && (ndim<4), "only supports 1D, 2D, and 3D arrays");
protected: protected:
T *d; using Tsp = shared_ptr<vector<T>>;
array<size_t, ndim> shp; array<size_t, ndim> shp;
array<ptrdiff_t, ndim> str; array<ptrdiff_t, ndim> str;
Tsp ptr;
T *d;
public: public:
cmav(const T *d_, const array<size_t,ndim> &shp_, cmav(const T *d_, const array<size_t,ndim> &shp_,
const array<ptrdiff_t,ndim> &str_) const array<ptrdiff_t,ndim> &str_)
: d(const_cast<T *>(d_)), shp(shp_), str(str_) {} : shp(shp_), str(str_), d(const_cast<T *>(d_)) {}
cmav(const T *d_, const array<size_t,ndim> &shp_) cmav(const T *d_, const array<size_t,ndim> &shp_)
: d(const_cast<T *>(d_)), shp(shp_) : shp(shp_), d(const_cast<T *>(d_))
{
str[ndim-1]=1;
for (size_t i=2; i<=ndim; ++i)
str[ndim-i] = str[ndim-i+1]*shp[ndim-i+1];
}
cmav(const array<size_t,ndim> &shp_)
: shp(shp_), ptr(make_unique<vector<T>>(size())), d(ptr->data())
{ {
str[ndim-1]=1; str[ndim-1]=1;
for (size_t i=2; i<=ndim; ++i) for (size_t i=2; i<=ndim; ++i)
str[ndim-i] = str[ndim-i+1]*shp[ndim-i+1]; str[ndim-i] = str[ndim-i+1]*shp[ndim-i+1];
} }
cmav(const cmav &other) = default;
cmav(cmav &&other) = default;
operator cfmav<T>() const operator cfmav<T>() const
{ {
return cfmav<T>(d, {shp.begin(), shp.end()}, {str.begin(), str.end()}); return cfmav<T>(d, ptr, {shp.begin(), shp.end()}, {str.begin(), str.end()});
} }
const T &operator[](size_t i) const const T &operator[](size_t i) const
{ return operator()(i); } { return operator()(i); }
...@@ -167,6 +199,11 @@ template<typename T, size_t ndim> class cmav ...@@ -167,6 +199,11 @@ template<typename T, size_t ndim> class cmav
static_assert(ndim==2, "ndim must be 2"); static_assert(ndim==2, "ndim must be 2");
return d[str[0]*i + str[1]*j]; return d[str[0]*i + str[1]*j];
} }
const T &operator()(size_t i, size_t j, size_t k) const
{
static_assert(ndim==3, "ndim must be 3");
return d[str[0]*i + str[1]*j + str[2]*k];
}
size_t shape(size_t i) const { return shp[i]; } size_t shape(size_t i) const { return shp[i]; }
const array<size_t,ndim> &shape() const { return shp; } const array<size_t,ndim> &shape() const { return shp; }
size_t size() const size_t size() const
...@@ -196,8 +233,10 @@ template<typename T, size_t ndim> class cmav ...@@ -196,8 +233,10 @@ template<typename T, size_t ndim> class cmav
template<typename T, size_t ndim> class mav: public cmav<T, ndim> template<typename T, size_t ndim> class mav: public cmav<T, ndim>
{ {
protected: protected:
using Tsp = shared_ptr<vector<T>>;
using parent = cmav<T, ndim>; using parent = cmav<T, ndim>;
using parent::d; using parent::d;
using parent::ptr;
using parent::shp; using parent::shp;
using parent::str; using parent::str;
...@@ -207,9 +246,13 @@ template<typename T, size_t ndim> class mav: public cmav<T, ndim> ...@@ -207,9 +246,13 @@ template<typename T, size_t ndim> class mav: public cmav<T, ndim>
: parent(d_, shp_, str_) {} : parent(d_, shp_, str_) {}
mav(T *d_, const array<size_t,ndim> &shp_) mav(T *d_, const array<size_t,ndim> &shp_)
: parent(d_, shp_) {} : parent(d_, shp_) {}
mav(const array<size_t,ndim> &shp_)
: parent(shp_) {}
mav(const mav &other) = default;
mav(mav &&other) = default;
operator fmav<T>() const operator fmav<T>() const
{ {
return fmav<T>(d, {shp.begin(), shp.end()}, {str.begin(), str.end()}); return fmav<T>(d, ptr, {shp.begin(), shp.end()}, {str.begin(), str.end()});
} }
T &operator[](size_t i) const T &operator[](size_t i) const
{ return operator()(i); } { return operator()(i); }
...@@ -223,6 +266,11 @@ template<typename T, size_t ndim> class mav: public cmav<T, ndim> ...@@ -223,6 +266,11 @@ template<typename T, size_t ndim> class mav: public cmav<T, ndim>
static_assert(ndim==2, "ndim must be 2"); static_assert(ndim==2, "ndim must be 2");
return d[str[0]*i + str[1]*j]; return d[str[0]*i + str[1]*j];
} }
T &operator()(size_t i, size_t j, size_t k) const
{
static_assert(ndim==3, "ndim must be 3");
return d[str[0]*i + str[1]*j + str[2]*k];
}
using parent::shape; using parent::shape;
using parent::stride; using parent::stride;
using parent::size; using parent::size;
...@@ -240,6 +288,11 @@ template<typename T, size_t ndim> class mav: public cmav<T, ndim> ...@@ -240,6 +288,11 @@ template<typename T, size_t ndim> class mav: public cmav<T, ndim>
for (size_t i=0; i<shp[0]; ++i) for (size_t i=0; i<shp[0]; ++i)
for (size_t j=0; j<shp[1]; ++j) for (size_t j=0; j<shp[1]; ++j)
d[str[0]*i + str[1]*j] = val; d[str[0]*i + str[1]*j] = val;
else if (ndim==3)
for (size_t i=0; i<shp[0]; ++i)
for (size_t j=0; j<shp[1]; ++j)
for (size_t k=0; k<shp[2]; ++k)
d[str[0]*i + str[1]*j + str[2]*k] = val;
} }
using parent::conformable; using parent::conformable;
}; };
......
...@@ -59,27 +59,6 @@ template<size_t ndim> void checkShape ...@@ -59,27 +59,6 @@ template<size_t ndim> void checkShape
template<typename T> inline T fmod1 (T v) template<typename T> inline T fmod1 (T v)
{ return v-floor(v); } { return v-floor(v); }
template<typename T, size_t ndim> class tmpStorage
{
private:
vector<T> d;
mav<T,ndim> mav_;
static size_t prod(const array<size_t,ndim> &shp)
{
size_t res=1;
for (auto v: shp) res*=v;
return res;
}
public:
tmpStorage(const array<size_t,ndim> &shp)
: d(prod(shp)), mav_(d.data(), shp) {}
mav<T,ndim> &getMav() { return mav_; }
void fill(const T & val)
{ std::fill(d.begin(), d.end(), val); }
};
// //
// Start of real gridder functionality // Start of real gridder functionality
// //
...@@ -98,8 +77,8 @@ template<typename T> void complex2hartley ...@@ -98,8 +77,8 @@ template<typename T> void complex2hartley
for (size_t v=0; v<nv; ++v) for (size_t v=0; v<nv; ++v)
{ {
size_t xv = (v==0) ? 0 : nv-v; size_t xv = (v==0) ? 0 : nv-v;
grid2(u,v) += T(0.5)*(grid( u, v).real()+grid( u, v).imag()+ grid2(u,v) = T(0.5)*(grid( u, v).real()+grid( u, v).imag()+
grid(xu,xv).real()-grid(xu,xv).imag()); grid(xu,xv).real()-grid(xu,xv).imag());
} }
} }
}); });
...@@ -456,8 +435,7 @@ class GridderConfig ...@@ -456,8 +435,7 @@ class GridderConfig
const mav<T,2> &dirty) const const mav<T,2> &dirty) const
{ {
checkShape(grid.shape(), {nu,nv}); checkShape(grid.shape(), {nu,nv});
tmpStorage<T,2> tmpdat({nu,nv}); mav<T,2> tmav({nu,nv});
auto tmav = tmpdat.getMav();
hartley2_2D<T>(grid, tmav, nthreads); hartley2_2D<T>(grid, tmav, nthreads);
grid2dirty_post(tmav, dirty); grid2dirty_post(tmav, dirty);
} }
...@@ -1080,8 +1058,7 @@ template<typename T, typename Serv> void x2dirty( ...@@ -1080,8 +1058,7 @@ template<typename T, typename Serv> void x2dirty(
WgridHelper<Serv> hlp(gconf, srv, verbosity); WgridHelper<Serv> hlp(gconf, srv, verbosity);
double dw = hlp.DW(); double dw = hlp.DW();
dirty.fill(0); dirty.fill(0);
tmpStorage<complex<T>,2> grid_({gconf.Nu(),gconf.Nv()}); mav<complex<T>,2> grid({gconf.Nu(),gconf.Nv()});
auto grid=grid_.getMav();
while(hlp.advance()) // iterate over w planes while(hlp.advance()) // iterate over w planes
{ {
if (hlp.Nvis()==0) continue; if (hlp.Nvis()==0) continue;
...@@ -1099,12 +1076,10 @@ template<typename T, typename Serv> void x2dirty( ...@@ -1099,12 +1076,10 @@ template<typename T, typename Serv> void x2dirty(
<< " visibilities" << endl; << " visibilities" << endl;
if (verbosity>0) cout << "Using " << gconf.Nthreads() << " threads" << endl; if (verbosity>0) cout << "Using " << gconf.Nthreads() << " threads" << endl;
tmpStorage<complex<T>,2> grid_({gconf.Nu(), gconf.Nv()}); mav<complex<T>,2> grid({gconf.Nu(), gconf.Nv()});
auto grid=grid_.getMav(); grid.fill(0.);
grid_.fill(0.);
x2grid_c(gconf, srv, grid); x2grid_c(gconf, srv, grid);
tmpStorage<T,2> rgrid_(grid.shape()); mav<T,2> rgrid(grid.shape());
auto rgrid=rgrid_.getMav();
complex2hartley(grid, rgrid, gconf.Nthreads()); complex2hartley(grid, rgrid, gconf.Nthreads());
gconf.grid2dirty(rgrid, dirty); gconf.grid2dirty(rgrid, dirty);
} }
...@@ -1121,15 +1096,13 @@ template<typename T, typename Serv> void dirty2x( ...@@ -1121,15 +1096,13 @@ template<typename T, typename Serv> void dirty2x(
if (verbosity>0) cout << "Degridding using improved w-stacking" << endl; if (verbosity>0) cout << "Degridding using improved w-stacking" << endl;
WgridHelper<Serv> hlp(gconf, srv, verbosity); WgridHelper<Serv> hlp(gconf, srv, verbosity);
double dw = hlp.DW(); double dw = hlp.DW();
tmpStorage<T,2> tdirty_({nx_dirty,ny_dirty}); mav<T,2> tdirty({nx_dirty,ny_dirty});
auto tdirty=tdirty_.getMav();
for (size_t i=0; i<nx_dirty; ++i) for (size_t i=0; i<nx_dirty; ++i)
for (size_t j=0; j<ny_dirty; ++j) for (size_t j=0; j<ny_dirty; ++j)
tdirty(i,j) = dirty(i,j); tdirty(i,j) = dirty(i,j);
// correct for w gridding etc. // correct for w gridding etc.
apply_global_corrections(gconf, tdirty, ES_Kernel(gconf.Supp(), gconf.Ofactor(), nthreads), dw, true); apply_global_corrections(gconf, tdirty, ES_Kernel(gconf.Supp(), gconf.Ofactor(), nthreads), dw, true);
tmpStorage<complex<T>,2> grid_({gconf.Nu(),gconf.Nv()}); mav<complex<T>,2> grid({gconf.Nu(),gconf.Nv()});
auto grid=grid_.getMav();
while(hlp.advance()) // iterate over w planes while(hlp.advance()) // iterate over w planes
{ {
if (hlp.Nvis()==0) continue; if (hlp.Nvis()==0) continue;
...@@ -1144,11 +1117,9 @@ template<typename T, typename Serv> void dirty2x( ...@@ -1144,11 +1117,9 @@ template<typename T, typename Serv> void dirty2x(
<< " visibilities" << endl; << " visibilities" << endl;
if (verbosity>0) cout << "Using " << gconf.Nthreads() << " threads" << endl; if (verbosity>0) cout << "Using " << gconf.Nthreads() << " threads" << endl;
tmpStorage<T,2> grid_({gconf.Nu(), gconf.Nv()}); mav<T,2> grid({gconf.Nu(), gconf.Nv()});
auto grid=grid_.getMav();
gconf.dirty2grid(dirty, grid); gconf.dirty2grid(dirty, grid);
tmpStorage<complex<T>,2> grid2_(grid.shape()); mav<complex<T>,2> grid2(grid.shape());
auto grid2=grid2_.getMav();
hartley2complex(grid, grid2, gconf.Nthreads()); hartley2complex(grid, grid2, gconf.Nthreads());
grid2x_c(gconf, grid2, srv); grid2x_c(gconf, grid2, srv);
} }
......
...@@ -19,12 +19,12 @@ python_module_link_args = [] ...@@ -19,12 +19,12 @@ python_module_link_args = []
if sys.platform == 'darwin': if sys.platform == 'darwin':
import distutils.sysconfig import distutils.sysconfig
extra_compile_args += ['--std=c++11', '--stdlib=libc++', '-mmacosx-version-min=10.9'] extra_compile_args += ['--std=c++14', '--stdlib=libc++', '-mmacosx-version-min=10.9']
vars = distutils.sysconfig.get_config_vars() vars = distutils.sysconfig.get_config_vars()
vars['LDSHARED'] = vars['LDSHARED'].replace('-bundle', '') vars['LDSHARED'] = vars['LDSHARED'].replace('-bundle', '')
python_module_link_args+=['-bundle'] python_module_link_args+=['-bundle']
else: else:
extra_compile_args += ['--std=c++11', '-march=native', '-O3', '-ffast-math'] extra_compile_args += ['--std=c++14', '-march=native', '-O3', '-ffast-math']
python_module_link_args += ['-march=native', '-Wl,-rpath,$ORIGIN', '-ffast-math'] python_module_link_args += ['-march=native', '-Wl,-rpath,$ORIGIN', '-ffast-math']
# if you don't want debugging info, add "-s" to python_module_link_args # if you don't want debugging info, add "-s" to python_module_link_args
......
...@@ -13,7 +13,7 @@ class _deferred_pybind11_include(object): ...@@ -13,7 +13,7 @@ class _deferred_pybind11_include(object):
include_dirs = ['..', _deferred_pybind11_include(True), include_dirs = ['..', _deferred_pybind11_include(True),
_deferred_pybind11_include()] _deferred_pybind11_include()]
extra_compile_args = ['--std=c++11', '-march=native', '-ffast-math', '-O3'] extra_compile_args = ['--std=c++14', '-march=native', '-ffast-math', '-O3']
python_module_link_args = [] python_module_link_args = []
define_macros = [] define_macros = []
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment