Commit 33251a05 authored by Martin Reinecke's avatar Martin Reinecke
Browse files

stage 2

parent d73de808
......@@ -498,9 +498,9 @@ template<typename I> template<typename I2>
double dr=base[o].max_pixrad(); // safety distance
for (size_t i=0; i<nv; ++i)
{
crlimit(o,i,0) = (rad[i]+dr>pi) ? -1. : cos(rad[i]+dr);
crlimit(o,i,1) = (o==0) ? cos(rad[i]) : crlimit(0,i,1);
crlimit(o,i,2) = (rad[i]-dr<0.) ? 1. : cos(rad[i]-dr);
crlimit.v(o,i,0) = (rad[i]+dr>pi) ? -1. : cos(rad[i]+dr);
crlimit.v(o,i,1) = (o==0) ? cos(rad[i]) : crlimit(0,i,1);
crlimit.v(o,i,2) = (rad[i]-dr<0.) ? 1. : cos(rad[i]-dr);
}
}
......@@ -563,9 +563,9 @@ template<typename I> void T_Healpix_Base<I>::query_multidisc_general
double dr=base[o].max_pixrad(); // safety distance
for (size_t i=0; i<nv; ++i)
{
crlimit(o,i,0) = (rad[i]+dr>pi) ? -1. : cos(rad[i]+dr);
crlimit(o,i,1) = (o==0) ? cos(rad[i]) : crlimit(0,i,1);
crlimit(o,i,2) = (rad[i]-dr<0.) ? 1. : cos(rad[i]-dr);
crlimit.v(o,i,0) = (rad[i]+dr>pi) ? -1. : cos(rad[i]+dr);
crlimit.v(o,i,1) = (o==0) ? cos(rad[i]) : crlimit(0,i,1);
crlimit.v(o,i,2) = (rad[i]-dr<0.) ? 1. : cos(rad[i]-dr);
}
}
......
......@@ -650,25 +650,28 @@ template <typename T, size_t vlen> void copy_input(const multi_iter<vlen> &it,
template<typename T, size_t vlen> void copy_output(const multi_iter<vlen> &it,
const Cmplx<native_simd<T>> *MRUTIL_RESTRICT src, fmav<Cmplx<T>> &dst)
{
auto ptr=dst.vdata();
for (size_t i=0; i<it.length_out(); ++i)
for (size_t j=0; j<vlen; ++j)
dst[it.oofs(j,i)].Set(src[i].r[j],src[i].i[j]);
ptr[it.oofs(j,i)].Set(src[i].r[j],src[i].i[j]);
}
template<typename T, size_t vlen> void copy_output(const multi_iter<vlen> &it,
const native_simd<T> *MRUTIL_RESTRICT src, fmav<T> &dst)
{
auto ptr=dst.vdata();
for (size_t i=0; i<it.length_out(); ++i)
for (size_t j=0; j<vlen; ++j)
dst[it.oofs(j,i)] = src[i][j];
ptr[it.oofs(j,i)] = src[i][j];
}
template<typename T, size_t vlen> void copy_output(const multi_iter<vlen> &it,
const T *MRUTIL_RESTRICT src, fmav<T> &dst)
{
auto ptr=dst.vdata();
if (src == &dst[it.oofs(0)]) return; // in-place
for (size_t i=0; i<it.length_out(); ++i)
dst[it.oofs(i)] = src[i];
ptr[it.oofs(i)] = src[i];
}
template <typename T> struct add_vec { using type = native_simd<T>; };
......@@ -709,7 +712,7 @@ MRUTIL_NOINLINE void general_nd(const fmav<T> &in, fmav<T> &out,
{
it.advance(1);
auto buf = allow_inplace && it.stride_out() == 1 ?
&out[it.oofs(0)] : reinterpret_cast<T *>(storage.data());
&out.vraw(it.oofs(0)) : reinterpret_cast<T *>(storage.data());
exec(it, tin, out, buf, *plan, fct);
}
}); // end of parallel region
......@@ -734,32 +737,34 @@ struct ExecC2C
template <typename T, size_t vlen> void copy_hartley(const multi_iter<vlen> &it,
const native_simd<T> *MRUTIL_RESTRICT src, fmav<T> &dst)
{
auto ptr = dst.vdata();
for (size_t j=0; j<vlen; ++j)
dst[it.oofs(j,0)] = src[0][j];
ptr[it.oofs(j,0)] = src[0][j];
size_t i=1, i1=1, i2=it.length_out()-1;
for (i=1; i<it.length_out()-1; i+=2, ++i1, --i2)
for (size_t j=0; j<vlen; ++j)
{
dst[it.oofs(j,i1)] = src[i][j]+src[i+1][j];
dst[it.oofs(j,i2)] = src[i][j]-src[i+1][j];
ptr[it.oofs(j,i1)] = src[i][j]+src[i+1][j];
ptr[it.oofs(j,i2)] = src[i][j]-src[i+1][j];
}
if (i<it.length_out())
for (size_t j=0; j<vlen; ++j)
dst[it.oofs(j,i1)] = src[i][j];
ptr[it.oofs(j,i1)] = src[i][j];
}
template <typename T, size_t vlen> void copy_hartley(const multi_iter<vlen> &it,
const T *MRUTIL_RESTRICT src, fmav<T> &dst)
{
dst[it.oofs(0)] = src[0];
auto ptr = dst.vdata();
ptr[it.oofs(0)] = src[0];
size_t i=1, i1=1, i2=it.length_out()-1;
for (i=1; i<it.length_out()-1; i+=2, ++i1, --i2)
{
dst[it.oofs(i1)] = src[i]+src[i+1];
dst[it.oofs(i2)] = src[i]-src[i+1];
ptr[it.oofs(i1)] = src[i]+src[i+1];
ptr[it.oofs(i2)] = src[i]-src[i+1];
}
if (i<it.length_out())
dst[it.oofs(i1)] = src[i];
ptr[it.oofs(i1)] = src[i];
}
struct ExecHartley
......@@ -810,20 +815,21 @@ template<typename T> MRUTIL_NOINLINE void general_r2c(
auto tdatav = reinterpret_cast<native_simd<T> *>(storage.data());
copy_input(it, in, tdatav);
plan->exec(tdatav, fct, true);
auto vout = out.vdata();
for (size_t j=0; j<vlen; ++j)
out[it.oofs(j,0)].Set(tdatav[0][j]);
vout[it.oofs(j,0)].Set(tdatav[0][j]);
size_t i=1, ii=1;
if (forward)
for (; i<len-1; i+=2, ++ii)
for (size_t j=0; j<vlen; ++j)
out[it.oofs(j,ii)].Set(tdatav[i][j], tdatav[i+1][j]);
vout[it.oofs(j,ii)].Set(tdatav[i][j], tdatav[i+1][j]);
else
for (; i<len-1; i+=2, ++ii)
for (size_t j=0; j<vlen; ++j)
out[it.oofs(j,ii)].Set(tdatav[i][j], -tdatav[i+1][j]);
vout[it.oofs(j,ii)].Set(tdatav[i][j], -tdatav[i+1][j]);
if (i<len)
for (size_t j=0; j<vlen; ++j)
out[it.oofs(j,ii)].Set(tdatav[i][j]);
vout[it.oofs(j,ii)].Set(tdatav[i][j]);
}
#endif
while (it.remaining()>0)
......@@ -832,16 +838,17 @@ template<typename T> MRUTIL_NOINLINE void general_r2c(
auto tdata = reinterpret_cast<T *>(storage.data());
copy_input(it, in, tdata);
plan->exec(tdata, fct, true);
out[it.oofs(0)].Set(tdata[0]);
auto vout = out.vdata();
vout[it.oofs(0)].Set(tdata[0]);
size_t i=1, ii=1;
if (forward)
for (; i<len-1; i+=2, ++ii)
out[it.oofs(ii)].Set(tdata[i], tdata[i+1]);
vout[it.oofs(ii)].Set(tdata[i], tdata[i+1]);
else
for (; i<len-1; i+=2, ++ii)
out[it.oofs(ii)].Set(tdata[i], -tdata[i+1]);
vout[it.oofs(ii)].Set(tdata[i], -tdata[i+1]);
if (i<len)
out[it.oofs(ii)].Set(tdata[i]);
vout[it.oofs(ii)].Set(tdata[i]);
}
}); // end of parallel region
}
......@@ -944,7 +951,7 @@ template<typename T> void c2c(const fmav<std::complex<T>> &in,
util::sanity_check_onetype(in, out, in.data()==out.data(), axes);
if (in.size()==0) return;
fmav<Cmplx<T>> in2(reinterpret_cast<const Cmplx<T> *>(in.data()), in);
fmav<Cmplx<T>> out2(reinterpret_cast<Cmplx<T> *>(out.data()), out, out.writable());
fmav<Cmplx<T>> out2(reinterpret_cast<Cmplx<T> *>(out.vdata()), out, out.writable());
general_nd<pocketfft_c<T>>(in2, out2, axes, fct, nthreads, ExecC2C{forward});
}
......@@ -983,7 +990,7 @@ template<typename T> void r2c(const fmav<T> &in,
{
util::sanity_check_cr(out, in, axis);
if (in.size()==0) return;
fmav<Cmplx<T>> out2(reinterpret_cast<Cmplx<T> *>(out.data()), out, out.writable());
fmav<Cmplx<T>> out2(reinterpret_cast<Cmplx<T> *>(out.vdata()), out, out.writable());
general_r2c(in, out2, axis, forward, fct, nthreads);
}
......@@ -1055,11 +1062,12 @@ template<typename T> void r2r_genuine_hartley(const fmav<T> &in,
r2c(in, atmp, axes, true, fct, nthreads);
simple_iter iin(atmp);
rev_iter iout(out, axes);
auto vout = out.vdata();
while(iin.remaining()>0)
{
auto v = atmp[iin.ofs()];
out[iout.ofs()] = v.real()+v.imag();
out[iout.rev_ofs()] = v.real()-v.imag();
vout[iout.ofs()] = v.real()+v.imag();
vout[iout.rev_ofs()] = v.real()-v.imag();
iin.advance(); iout.advance();
}
}
......
......@@ -107,33 +107,27 @@ template<typename T> class membuf
membuf(size_t sz)
: ptr(make_unique<vector<T>>(sz)), d(ptr->data()), rw(true) {}
membuf(const membuf &other) = default;
membuf(membuf &other) = default;
membuf(membuf &&other) = default;
// Not for public use!
membuf(T *d_, const Tsp &p, bool rw_)
: ptr(p), d(d_), rw(rw_) {}
template<typename I> const T &val(I i) const
{ return d[i]; }
template<typename I> T &val(I i)
template<typename I> T &vraw(I i)
{
MR_assert(rw, "array is nor writable");
MR_assert(rw, "array is not writable");
return const_cast<T *>(d)[i];
}
template<typename I> const T &operator[](I i) const
{ return d[i]; }
template<typename I> T &operator[](I i)
{
MR_assert(rw, "array is nor writable");
return const_cast<T *>(d)[i];
}
const T *data() const
{ return d; }
T *data()
T *vdata()
{
MR_assert(rw, "array is nor writable");
MR_assert(rw, "array is not writable");
return const_cast<T *>(d);
}
bool writable() const { return rw; }
bool writable() { return rw; }
};
// "mav" stands for "multidimensional array view"
......@@ -157,11 +151,11 @@ template<typename T> class fmav: public fmav_info, public membuf<T>
: fmav_info(info), membuf<T>(d_, rw_) {}
fmav(const T* d_, const fmav_info &info)
: fmav_info(info), membuf<T>(d_) {}
fmav(const fmav &other) = delete;
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_, bool rw_)
: fmav_info(shp_, str_), membuf<T>(d_, p, rw_) {}
fmav(membuf<T> &buf, const shape_t &shp_, const stride_t &str_)
: fmav_info(shp_, str_), membuf<T>(buf) {}
};
template<size_t ndim> class mav_info
......@@ -194,7 +188,6 @@ template<size_t ndim> class mav_info
for (size_t i=2; i<=ndim; ++i)
str[ndim-i] = str[ndim-i+1]*ptrdiff_t(shp[ndim-i+1]);
}
// size_t ndim() const { return shp.size(); }
size_t size() const { return sz; }
const shape_t &shape() const { return shp; }
size_t shape(size_t i) const { return shp[i]; }
......@@ -214,6 +207,21 @@ template<size_t ndim> class mav_info
}
bool conformable(const mav_info &other) const
{ return shp==other.shp; }
ptrdiff_t idx(size_t i) const
{
static_assert(ndim==1, "ndim must be 1");
return str[0]*i;
}
ptrdiff_t idx(size_t i, size_t j) const
{
static_assert(ndim==2, "ndim must be 2");
return str[0]*i + str[1]*j;
}
ptrdiff_t idx(size_t i, size_t j, size_t k) const
{
static_assert(ndim==3, "ndim must be 3");
return str[0]*i + str[1]*j + str[2]*k;
}
};
template<typename T, size_t ndim> class mav: public mav_info<ndim>, public membuf<T>
......@@ -223,16 +231,21 @@ template<typename T, size_t ndim> class mav: public mav_info<ndim>, public membu
using typename mav_info<ndim>::stride_t;
protected:
using membuf<T>::Tsp;
using mav_info<ndim>::size;
// using membuf<T>::Tsp;
using membuf<T>::d;
using membuf<T>::ptr;
using mav_info<ndim>::shp;
using mav_info<ndim>::str;
using membuf<T>::rw;
using membuf<T>::val;
using membuf<T>::vraw;
public:
using membuf<T>::operator[];
using membuf<T>::vdata;
using membuf<T>::data;
using mav_info<ndim>::size;
using mav_info<ndim>::idx;
mav(const T *d_, const shape_t &shp_, const stride_t &str_)
: mav_info<ndim>(shp_, str_), membuf<T>(d_) {}
mav(T *d_, const shape_t &shp_, const stride_t &str_, bool rw_=false)
......@@ -243,58 +256,44 @@ template<typename T, size_t ndim> class mav: public mav_info<ndim>, public membu
: mav_info<ndim>(shp_), membuf<T>(d_, rw_) {}
mav(const array<size_t,ndim> &shp_)
: mav_info<ndim>(shp_), membuf<T>(size()) {}
mav(const mav &other) = delete;
mav(const mav &other) = default;
mav(mav &&other) = default;
operator fmav<T>() const
{
return fmav<T>(const_cast<T *>(d), ptr, {shp.begin(), shp.end()}, {str.begin(), str.end()}, rw);
return fmav<T>(data(), {shp.begin(), shp.end()}, {str.begin(), str.end()});
}
const T &operator()(size_t i) const
operator fmav<T>()
{
static_assert(ndim==1, "ndim must be 1");
return val(str[0]*i);
return fmav<T>(*this, {shp.begin(), shp.end()}, {str.begin(), str.end()});
}
const T &operator()(size_t i) const
{ return operator[](idx(i)); }
const T &operator()(size_t i, size_t j) const
{
static_assert(ndim==2, "ndim must be 2");
return val(str[0]*i + str[1]*j);
}
{ return operator[](idx(i,j)); }
const T &operator()(size_t i, size_t j, size_t k) const
{
static_assert(ndim==3, "ndim must be 3");
return val(str[0]*i + str[1]*j + str[2]*k);
}
T &operator()(size_t i)
{
static_assert(ndim==1, "ndim must be 1");
return val(str[0]*i);
}
T &operator()(size_t i, size_t j)
{
static_assert(ndim==2, "ndim must be 2");
return val(str[0]*i + str[1]*j);
}
T &operator()(size_t i, size_t j, size_t k)
{
static_assert(ndim==3, "ndim must be 3");
return val(str[0]*i + str[1]*j + str[2]*k);
}
{ return operator[](idx(i,j,k)); }
T &v(size_t i)
{ return vraw(idx(i)); }
T &v(size_t i, size_t j)
{ return vraw(idx(i,j)); }
T &v(size_t i, size_t j, size_t k)
{ return vraw(idx(i,j,k)); }
void fill(const T &val)
{
MR_assert(rw, "array is nor writable");
T *d2 = vdata();
// FIXME: special cases for contiguous arrays and/or zeroing?
if (ndim==1)
for (size_t i=0; i<shp[0]; ++i)
d[str[0]*i]=val;
d2[str[0]*i]=val;
else if (ndim==2)
for (size_t i=0; i<shp[0]; ++i)
for (size_t j=0; j<shp[1]; ++j)
d[str[0]*i + str[1]*j] = val;
d2[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;
d2[str[0]*i + str[1]*j + str[2]*k] = val;
}
};
......@@ -302,6 +301,7 @@ template<typename T, size_t ndim> class mav: public mav_info<ndim>, public membu
using detail_mav::shape_t;
using detail_mav::stride_t;
using detail_mav::fmav_info;
using detail_mav::fmav;
using detail_mav::mav;
......
......@@ -64,9 +64,10 @@ template<typename T> inline T fmod1 (T v)
//
template<typename T> void complex2hartley
(const cmav<complex<T>, 2> &grid, const mav<T,2> &grid2, size_t nthreads)
(const mav<complex<T>, 2> &grid, mav<T,2> &grid2, size_t nthreads)
{
checkShape(grid.shape(), grid2.shape());
auto g2w = grid2.vdata();
size_t nu=grid.shape(0), nv=grid.shape(1);
execStatic(nu, nthreads, 0, [&](Scheduler &sched)
......@@ -77,17 +78,18 @@ template<typename T> void complex2hartley
for (size_t v=0; v<nv; ++v)
{
size_t xv = (v==0) ? 0 : nv-v;
grid2(u,v) = T(0.5)*(grid( u, v).real()+grid( u, v).imag()+
grid(xu,xv).real()-grid(xu,xv).imag());
g2w[grid2.idx(u,v)] = T(0.5)*(grid( u, v).real()+grid( u, v).imag()+
grid(xu,xv).real()-grid(xu,xv).imag());
}
}
});
}
template<typename T> void hartley2complex
(const cmav<T,2> &grid, const mav<complex<T>,2> &grid2, size_t nthreads)
(const mav<T,2> &grid, mav<complex<T>,2> &grid2, size_t nthreads)
{
checkShape(grid.shape(), grid2.shape());
auto g2w = grid2.vdata();
size_t nu=grid.shape(0), nv=grid.shape(1);
execStatic(nu, nthreads, 0, [&](Scheduler &sched)
......@@ -100,32 +102,33 @@ template<typename T> void hartley2complex
size_t xv = (v==0) ? 0 : nv-v;
T v1 = T(0.5)*grid( u, v);
T v2 = T(0.5)*grid(xu,xv);
grid2(u,v) = std::complex<T>(v1+v2, v1-v2);
g2w[grid2.idx(u,v)] = std::complex<T>(v1+v2, v1-v2);
}
}
});
}
template<typename T> void hartley2_2D(const cmav<T,2> &in,
const mav<T,2> &out, size_t nthreads)
template<typename T> void hartley2_2D(const mav<T,2> &in,
mav<T,2> &out, size_t nthreads)
{
checkShape(in.shape(), out.shape());
auto vout = out.vdata();
size_t nu=in.shape(0), nv=in.shape(1);
auto ptmp = out.data();
r2r_separable_hartley(cfmav<T>(in), fmav<T>(out), {0,1}, T(1), nthreads);
fmav<T> fin(in), fout(out);
r2r_separable_hartley(fin, fout, {0,1}, T(1), nthreads);
execStatic((nu+1)/2-1, nthreads, 0, [&](Scheduler &sched)
{
while (auto rng=sched.getNext()) for(auto i=rng.lo+1; i<rng.hi+1; ++i)
for(size_t j=1; j<(nv+1)/2; ++j)
{
T a = ptmp[i*nv+j];
T b = ptmp[(nu-i)*nv+j];
T c = ptmp[i*nv+nv-j];
T d = ptmp[(nu-i)*nv+nv-j];
ptmp[i*nv+j] = T(0.5)*(a+b+c-d);
ptmp[(nu-i)*nv+j] = T(0.5)*(a+b+d-c);
ptmp[i*nv+nv-j] = T(0.5)*(a+c+d-b);
ptmp[(nu-i)*nv+nv-j] = T(0.5)*(b+c+d-a);
T a = out(i,j);
T b = out(nu-i,j);
T c = out(i,nv-j);
T d = out(nu-i,nv-j);
vout[out.idx(i,j)] = T(0.5)*(a+b+c-d);
vout[out.idx(nu-i,j)] = T(0.5)*(a+b+d-c);
vout[out.idx(i,nv-j)] = T(0.5)*(a+c+d-b);
vout[out.idx(nu-i,nv-j)] = T(0.5)*(b+c+d-a);
}
});
}
......@@ -259,8 +262,8 @@ class Baselines
idx_t shift, mask;
public:
template<typename T> Baselines(const cmav<T,2> &coord_,
const cmav<T,1> &freq, bool negate_v=false)
template<typename T> Baselines(const mav<T,2> &coord_,
const mav<T,1> &freq, bool negate_v=false)
{
constexpr double speedOfLight = 299792458.;
MR_assert(coord_.shape(1)==3, "dimension mismatch");
......@@ -277,7 +280,7 @@ class Baselines
f_over_c.resize(nchan);
for (size_t i=0; i<nchan; ++i)
{
MR_assert(freq[i]>0, "negative channel frequency encountered");
MR_assert(freq(i)>0, "negative channel frequency encountered");
f_over_c[i] = freq(i)/speedOfLight;
}
coord.resize(nrows);
......@@ -367,10 +370,11 @@ class GridderConfig
size_t Nthreads() const { return nthreads; }
double Ofactor() const{ return ofactor; }
template<typename T> void grid2dirty_post(const mav<T,2> &tmav,
const mav<T,2> &dirty) const
template<typename T> void grid2dirty_post(mav<T,2> &tmav,
mav<T,2> &dirty) const
{
checkShape(dirty.shape(), {nx_dirty,ny_dirty});
auto vdirty =dirty.vdata();
auto cfu = correction_factors(nu, ofactor, nx_dirty/2+1, supp, nthreads);
auto cfv = correction_factors(nv, ofactor, ny_dirty/2+1, supp, nthreads);
execStatic(nx_dirty, nthreads, 0, [&](Scheduler &sched)
......@@ -387,15 +391,16 @@ class GridderConfig
if (j2>=nv) j2-=nv;
// FIXME: for some reason g++ warns about double-to-float conversion
// here, even though there is an explicit cast...
dirty(i,j) = tmav(i2,j2)*T(cfu[icfu]*cfv[icfv]);
vdirty[dirty.idx(i,j)] = tmav(i2,j2)*T(cfu[icfu]*cfv[icfv]);
}
}
});
}
template<typename T> void grid2dirty_post2(
const mav<complex<T>,2> &tmav, const mav<T,2> &dirty, T w) const
mav<complex<T>,2> &tmav, mav<T,2> &dirty, T w) const
{
checkShape(dirty.shape(), {nx_dirty,ny_dirty});
auto vdirty = dirty.vdata();
double x0 = -0.5*nx_dirty*psx,
y0 = -0.5*ny_dirty*psy;
execStatic(nx_dirty/2+1, nthreads, 0, [&](Scheduler &sched)
......@@ -412,7 +417,7 @@ class GridderConfig
if (ix>=nu) ix-=nu;
size_t jx = nv-ny_dirty/2+j;
if (jx>=nv) jx-=nv;
dirty(i,j) += (tmav(ix,jx)*ws).real(); // lower left
vdirty[dirty.idx(i,j)] += (tmav(ix,jx)*ws).real(); // lower left
size_t i2 = nx_dirty-i, j2 = ny_dirty-j;
size_t ix2 = nu-nx_dirty/2+i2;
if (ix2>=nu) ix2-=nu;
......@@ -420,19 +425,19 @@ class GridderConfig
if (jx2>=nv) jx2-=nv;
if ((i>0)&&(i<i2))
{
dirty(i2,j) += (tmav(ix2,jx)*ws).real(); // lower right
vdirty[dirty.idx(i2,j)] += (tmav(ix2,jx)*ws).real(); // lower right
if ((j>0)&&(j<j2))
dirty(i2,j2) += (tmav(ix2,jx2)*ws).real(); // upper right
vdirty[dirty.idx(i2,j2)] += (tmav(ix2,jx2)*ws).real(); // upper right
}
if ((j>0)&&(j<j2))
dirty(i,j2) += (tmav(ix,jx2)*ws).real(); // upper left
vdirty[dirty.idx(i,j2)] += (tmav(ix,jx2)*ws).real(); // upper left
}
}
});
}
template<typename T> void grid2dirty(const cmav<T,2> &grid,
const mav<T,2> &dirty) const
template<typename T> void grid2dirty(const mav<T,2> &grid,
mav<T,2> &dirty) const
{
checkShape(grid.shape(), {nu,nv});
mav<T,2> tmav({nu,nv});
......@@ -441,7 +446,7 @@ class GridderConfig
}
template<typename T> void grid2dirty_c_overwrite_wscreen_add
(const mav<complex<T>,2> &grid, const mav<T,2> &dirty, T w) const
(mav<complex<T>,2> &grid, mav<T,2> &dirty, T w) const
{
checkShape(grid.shape(), {nu,nv});
fmav<complex<T>> inout(grid);
......@@ -449,14 +454,15 @@ class GridderConfig
grid2dirty_post2(grid, dirty, w);
}
template<typename T> void dirty2grid_pre(const cmav<T,2> &dirty,
const mav<T,2> &grid) const
template<typename T> void dirty2grid_pre(const mav<T,2> &dirty,
mav<T,2> &grid) const
{
checkShape(dirty.shape(), {nx_dirty, ny_dirty});
checkShape(grid.shape(), {nu, nv});
auto cfu = correction_factors(nu, ofactor, nx_dirty/2+1, supp, nthreads);
auto cfv = correction_factors(nv, ofactor, ny_dirty/2+1, supp, nthreads);
grid.fill(0);
auto vgrid = grid.vdata();
<