10#if !defined(ampcor_correlators_Sequential_icc)
11#error This header is an implementation detail of ampcor::correlators::Sequential
15template <
typename raster_t>
21 cell_type * support = _arena + pid*(_refCells + _tgtCells);
23 tile_type tile(_refLayout, support);
25 std::copy(ref.begin(), ref.end(), tile.view().begin());
31template <
typename raster_t>
37 cell_type * support = _arena + pid*(_refCells + _tgtCells) + _refCells;
39 tile_type tile(_tgtLayout, support);
41 std::copy(tgt.begin(), tgt.end(), tile.view().begin());
47template <
typename raster_t>
50adjust() ->
const value_type *
53 pyre::journal::debug_t channel(
"ampcor");
56 auto refDim = _refLayout.shape()[0];
58 auto tgtDim = _tgtLayout.shape()[0];
60 auto corDim = _corLayout.shape()[0];
63 auto coarseArena = _arena;
65 auto amplitudes = _detect(coarseArena, refDim, tgtDim);
67 auto refStatistics = _refStats(amplitudes, refDim, tgtDim);
69 auto sat = _sat(amplitudes, refDim, tgtDim);
71 auto tgtStatistics = _tgtStats(sat, refDim, tgtDim, corDim);
73 auto gamma = _correlate(amplitudes, refStatistics, tgtStatistics, refDim, tgtDim, corDim);
75 auto maxcor = _maxcor(gamma, corDim);
79 delete [] tgtStatistics;
81 delete [] refStatistics;
87 auto refRefinedDim = _refRefinedLayout.shape()[0];
89 auto tgtRefinedDim = _tgtRefinedLayout.shape()[0];
91 auto corRefinedDim = _corRefinedLayout.shape()[0];
93 auto corZoomedDim = _corZoomedLayout.shape()[0];
96 _nudge(maxcor, refDim, tgtDim);
98 auto refinedArena = _refinedArena();
100 _refRefine(coarseArena, refinedArena);
102 _tgtMigrate(coarseArena, maxcor, refinedArena);
104 _tgtRefine(refinedArena);
106 amplitudes = _detect(refinedArena, refRefinedDim, tgtRefinedDim);
108 refStatistics = _refStats(amplitudes, refRefinedDim, tgtRefinedDim);
110 sat = _sat(amplitudes, refRefinedDim, tgtRefinedDim);
112 tgtStatistics = _tgtStats(sat, refRefinedDim, tgtRefinedDim, corRefinedDim);
114 gamma = _correlate(amplitudes, refStatistics, tgtStatistics,
115 refRefinedDim, tgtRefinedDim, corRefinedDim);
117 auto zoomed = _zoomcor(gamma);
119 auto maxcorZoomed = _maxcor(zoomed, corZoomedDim);
121 auto offsets = _offsetField(maxcorZoomed);
124 delete [] maxcorZoomed;
128 delete [] tgtStatistics;
130 delete [] refStatistics;
131 delete [] amplitudes;
132 delete [] refinedArena;
140template <
typename raster_t>
143arena() const -> cell_type *
149template <
typename raster_t>
152pairs() const -> size_type
159template <
typename raster_t>
168template <
typename raster_t>
171 const layout_type & refLayout,
const layout_type & tgtLayout,
172 size_type refineFactor, size_type refineMargin, size_type zoomFactor) :
174 _refineFactor{ refineFactor },
175 _refineMargin{ refineMargin },
176 _zoomFactor{ zoomFactor },
177 _refLayout{ refLayout },
178 _tgtLayout{ tgtLayout },
179 _corLayout{ tgtLayout.shape() - refLayout.shape() + index_type::fill(1) },
180 _refRefinedLayout{ refineFactor * _refLayout.shape() },
181 _tgtRefinedLayout{ refineFactor * (_refLayout.shape() + index_type::fill(2*refineMargin)) },
182 _corRefinedLayout{ index_type::fill(2*refineFactor*refineMargin+1) },
183 _corZoomedLayout { zoomFactor * _corRefinedLayout.shape() },
184 _refCells{ _refLayout.size() },
185 _tgtCells{ _tgtLayout.size() },
186 _corCells{ _corLayout.size() },
187 _refRefinedCells{ _refRefinedLayout.size() },
188 _tgtRefinedCells{ _tgtRefinedLayout.size() },
189 _refFootprint{ _refCells * sizeof(cell_type) },
190 _tgtFootprint{ _tgtCells * sizeof(cell_type) },
191 _corFootprint{ _corCells * sizeof(value_type) },
192 _refRefinedFootprint{ _refRefinedCells * sizeof(cell_type) },
193 _tgtRefinedFootprint{ _tgtRefinedCells * sizeof(cell_type) },
194 _arena{ new cell_type[ _pairs * (_refCells+_tgtCells) ] },
195 _offsets{ new value_type[ 2 * _pairs ] }
198 auto footprint = _pairs*(_refFootprint + _tgtFootprint);
199 auto refinedFootprint = _pairs*(_refRefinedFootprint + _tgtRefinedFootprint);
201 pyre::journal::debug_t channel(
"ampcor");
204 << pyre::journal::at(__HERE__)
205 <<
"new Sequential worker:"
206 << pyre::journal::newline
207 <<
" pairs: " << _pairs
208 << pyre::journal::newline
209 <<
" ref shape: " << _refLayout <<
", " << _refCells <<
" cells"
210 << pyre::journal::newline
211 <<
" tgt shape: " << _tgtLayout <<
", " << _tgtCells <<
" cells"
212 << pyre::journal::newline
213 <<
" footprint: " << (_refCells+_tgtCells) <<
" cells in "
214 << (footprint/1024/1024) <<
" Mb"
215 << pyre::journal::newline
216 <<
" refine factor: " << refineFactor
217 << pyre::journal::newline
218 <<
" refine margin: " << refineMargin
219 << pyre::journal::newline
220 <<
" refined ref shape: " << _refRefinedLayout <<
", " << _refRefinedCells <<
" cells"
221 << pyre::journal::newline
222 <<
" refined tgt shape: " << _tgtRefinedLayout <<
", " << _tgtRefinedCells <<
" cells"
223 << pyre::journal::newline
224 <<
" footprint: " << (_refRefinedCells+_tgtRefinedCells) <<
" cells in "
225 << (refinedFootprint/1024/1024) <<
" Mb"
226 << pyre::journal::newline
227 <<
" arena: " << _arena
228 << pyre::journal::endl;
233template <
typename raster_t>
239 pyre::journal::debug_t channel(
"ampcor");
242 channel << pyre::journal::at(__HERE__);
244 for (
auto pid = 0; pid < _pairs; ++pid) {
246 channel <<
"pid: " << pid << pyre::journal::newline;
248 cell_type * refLoc = _arena + pid*(_refCells + _tgtCells);
250 tile_type ref(_refLayout, refLoc);
252 channel <<
"reference: " << pyre::journal::newline;
253 for (
auto idx = 0; idx < _refLayout.shape()[0]; ++idx) {
254 for (
auto jdx = 0; jdx < _refLayout.shape()[1]; ++jdx) {
255 channel << ref[{idx, jdx}] <<
" ";
257 channel << pyre::journal::newline;
261 cell_type * tgtLoc = refLoc + _refCells;
263 tile_type tgt(_tgtLayout, tgtLoc);
266 channel <<
"target: " << pyre::journal::newline;
267 for (
auto idx = 0; idx < _tgtLayout.shape()[0]; ++idx) {
268 for (
auto jdx = 0; jdx < _tgtLayout.shape()[1]; ++jdx) {
269 channel << tgt[{idx, jdx}] <<
" ";
271 channel << pyre::journal::newline;
276 channel << pyre::journal::endl;
288template <
typename raster_t>
291_detect(
const cell_type * cArena, size_type refDim, size_type tgtDim)
const -> value_type *
294 auto refCells = refDim * refDim;
296 auto tgtCells = tgtDim * tgtDim;
299 value_type * rArena =
nullptr;
301 auto cells = _pairs * (refCells + tgtCells);
303 rArena =
new (std::nothrow) value_type[cells]();
306 if (rArena ==
nullptr) {
308 pyre::journal::error_t error(
"ampcor");
311 << pyre::journal::at(__HERE__)
312 <<
"Error while allocating memory for the tile amplitudes"
313 << pyre::journal::endl;
315 throw std::bad_alloc();
319 kernels::detect(cArena, cells, rArena);
329template <
typename raster_t>
332_refStats(value_type * rArena, size_type refDim, size_type tgtDim)
const -> value_type *
335 auto refCells = refDim * refDim;
337 auto tgtCells = tgtDim * tgtDim;
340 value_type * stats =
nullptr;
342 stats =
new (std::nothrow) value_type[_pairs]();
345 if (stats ==
nullptr) {
347 pyre::journal::error_t error(
"ampcor");
350 << pyre::journal::at(__HERE__)
351 <<
"Error while allocating memory for the variances of "
352 <<
"the reference tiles "
353 << pyre::journal::endl;
355 throw std::bad_alloc();
359 kernels::refStats(rArena, _pairs, refDim, refCells + tgtCells, stats);
369template <
typename raster_t>
372_sat(
const value_type * rArena, size_type refDim, size_type tgtDim)
const -> value_type *
376 auto refCells = refDim * refDim;
378 auto tgtCells = tgtDim * tgtDim;
381 value_type * sat =
nullptr;
383 sat =
new (std::nothrow) value_type[_pairs*tgtCells]();
386 if (sat ==
nullptr) {
388 pyre::journal::error_t error(
"ampcor");
391 << pyre::journal::at(__HERE__)
392 <<
"Error while allocating memory for the sum area tables "
393 << pyre::journal::endl;
395 throw std::bad_alloc();
399 kernels::sat(rArena, _pairs, refCells, tgtCells, tgtDim, sat);
408template <
typename raster_t>
412 size_type refDim, size_type tgtDim, size_type corDim)
const -> value_type *
415 value_type * stats =
nullptr;
417 stats =
new (std::nothrow) value_type[_pairs*corDim*corDim];
420 if (stats ==
nullptr) {
422 pyre::journal::error_t error(
"ampcor");
425 << pyre::journal::at(__HERE__)
426 <<
"Error while allocating memory for the table of target amplitude averages "
427 << pyre::journal::endl;
429 throw std::bad_alloc();
433 kernels::tgtStats(dSAT, _pairs, refDim, tgtDim, corDim, stats);
441template <
typename raster_t>
445 const value_type * refStats,
const value_type * tgtSat,
446 size_type refDim, size_type tgtDim, size_type corDim)
const -> value_type *
450 auto refCells = refDim * refDim;
452 auto tgtCells = tgtDim * tgtDim;
454 auto corCells = corDim * corDim;
457 value_type * dCorrelation =
nullptr;
459 auto size = _pairs * corCells;
461 dCorrelation =
new (std::nothrow) value_type[size]();
464 if (dCorrelation ==
nullptr) {
466 pyre::journal::error_t error(
"ampcor");
469 << pyre::journal::at(__HERE__)
470 <<
"Error while allocating memory for the correlation matrix "
471 << pyre::journal::endl;
473 throw std::bad_alloc();
477 kernels::correlate(rArena, refStats, tgtSat,
479 refCells, tgtCells, corCells, refDim, tgtDim, corDim,
488template <
typename raster_t>
491_maxcor(
const value_type * gamma, size_type corDim)
const ->
int *
495 auto corCells = corDim * corDim;
500 loc =
new (std::nothrow)
int[2 * _pairs]();
502 if (loc ==
nullptr) {
504 pyre::journal::error_t error(
"ampcor");
507 << pyre::journal::at(__HERE__)
508 <<
"Error while allocating device memory for the location of the correlation maxima "
509 << pyre::journal::endl;
511 throw std::bad_alloc();
515 kernels::maxcor(gamma, _pairs, corCells, corDim, loc);
524template <
typename raster_t>
527_nudge(
int * locations, size_type refDim, size_type tgtDim)
const
531 kernels::nudge(_pairs, refDim, tgtDim, _refineMargin, locations, _offsets);
539template <
typename raster_t>
545 cell_type * arena =
nullptr;
547 arena =
new (std::nothrow) cell_type[_pairs * (_refRefinedFootprint + _tgtRefinedFootprint)]();
549 if (arena ==
nullptr) {
551 pyre::journal::error_t error(
"ampcor");
554 << pyre::journal::at(__HERE__)
555 <<
"while allocating memory for the refined tile hyper-grid "
556 << pyre::journal::endl;
558 throw std::bad_alloc();
567template <
typename raster_t>
570_refRefine(cell_type * coarseArena, cell_type * refinedArena)
const
573 pyre::journal::debug_t channel(
"ampcor");
576 auto rshape = _refLayout.shape();
578 auto tshape = _refRefinedLayout.shape();
583 #pragma omp parallel reduction(+:nthreads)
591 if (procFFT ==
nullptr) {
593 pyre::journal::error_t error(
"ampcor");
596 << pyre::journal::at(__HERE__)
597 <<
"while instanciating a isce3::signal::Signal FFT processor"
598 << pyre::journal::endl;
600 throw std::runtime_error(
"while instanciating a isce3::signal::Signal FFT processor");
607 int fwdRanks[] = {
static_cast<int>(rshape[0]),
static_cast<int>(rshape[1]) };
610 int fwdIEmbed[] = {
static_cast<int>(rshape[0]),
static_cast<int>(rshape[1]) };
614 int fwdIDist = _refCells + _tgtCells;
617 int fwdOEmbed[] = {
static_cast<int>(tshape[0]),
static_cast<int>(tshape[1]) };
621 int fwdODist = _refRefinedCells + _tgtRefinedCells;
625 procFFT->
fftPlanForward(
reinterpret_cast<std::complex<float> *
>(coarseArena),
626 reinterpret_cast<std::complex<float> *
>(refinedArena),
627 dim, fwdRanks, _pairs,
628 fwdIEmbed, fwdIStride, fwdIDist,
629 fwdOEmbed, fwdOStride, fwdODist, -1);
636 int revRanks[] = {
static_cast<int>(tshape[0]),
static_cast<int>(tshape[1]) };
638 int revIEmbed[] = {
static_cast<int>(tshape[0]),
static_cast<int>(tshape[1]) };
642 int revIDist = _refRefinedCells + _tgtRefinedCells;
644 int revOEmbed[] = {
static_cast<int>(tshape[0]),
static_cast<int>(tshape[1]) };
648 int revODist = _refRefinedCells + _tgtRefinedCells;
650 procFFT->
fftPlanBackward(
reinterpret_cast<std::complex<float> *
>(refinedArena),
651 reinterpret_cast<std::complex<float> *
>(refinedArena),
653 dim, revRanks, _pairs,
654 revIEmbed, revIStride, revIDist,
655 revOEmbed, revOStride, revODist, 1);
660 procFFT->
upsample2D(
reinterpret_cast<std::complex<float> *
>(coarseArena),
661 reinterpret_cast<std::complex<float> *
>(refinedArena),
677template <
typename raster_t>
680_tgtMigrate(cell_type * coarseArena,
int * locations, cell_type * refinedArena)
const
683 pyre::journal::debug_t channel(
"ampcor");
686 auto refShape = _refLayout.shape();
688 auto tgtShape = _tgtLayout.shape();
690 auto refRefinedShape = _refRefinedLayout.shape();
692 auto tgtRefinedShape = _tgtRefinedLayout.shape();
695 auto refDim = refShape[0];
696 auto tgtDim = tgtShape[0];
697 auto refRefinedDim = refRefinedShape[0];
698 auto tgtRefinedDim = tgtRefinedShape[0];
701 auto expDim = refDim + 2 * _refineMargin;
704 kernels::migrate(coarseArena, _pairs,
705 refDim, tgtDim, expDim,
706 refRefinedDim, tgtRefinedDim,
716template <
typename raster_t>
723 pyre::journal::debug_t channel(
"ampcor");
728 auto tgtRefShape = _tgtRefinedLayout.shape();
730 auto expShape = _refLayout.shape() + index_type::fill(2*_refineMargin);
738 #pragma omp parallel reduction(+:nthreads)
746 if (procFFT ==
nullptr) {
748 pyre::journal::error_t error(
"ampcor");
751 << pyre::journal::at(__HERE__)
752 <<
"while instanciating a isce3::signal::Signal FFT processor"
753 << pyre::journal::endl;
755 throw std::runtime_error(
"while instanciating a isce3::signal::Signal FFT processor");
764 int fwdRanks[] = {
static_cast<int>(expShape[0]),
static_cast<int>(expShape[1]) };
766 int fwdIEmbed[] = {
static_cast<int>(tgtRefShape[0]),
static_cast<int>(tgtRefShape[1]) };
770 int fwdIDist = _refRefinedCells + _tgtRefinedCells;
772 int fwdOEmbed[] = {
static_cast<int>(tgtRefShape[0]),
static_cast<int>(tgtRefShape[1]) };
776 int fwdODist = _refRefinedCells + _tgtRefinedCells;
779 auto firstTile =
reinterpret_cast<std::complex<float> *
>(refinedArena + _refRefinedCells);
782 dim, fwdRanks, _pairs,
783 fwdIEmbed, fwdIStride, fwdIDist,
784 fwdOEmbed, fwdOStride, fwdODist, -1);
790 int revRanks[] = {
static_cast<int>(tgtRefShape[0]),
static_cast<int>(tgtRefShape[1]) };
792 int revIEmbed[] = {
static_cast<int>(tgtRefShape[0]),
static_cast<int>(tgtRefShape[1]) };
796 int revIDist = _refRefinedCells + _tgtRefinedCells;
798 int revOEmbed[] = {
static_cast<int>(tgtRefShape[0]),
static_cast<int>(tgtRefShape[1]) };
802 int revODist = _refRefinedCells + _tgtRefinedCells;
805 dim, revRanks, _pairs,
806 revIEmbed, revIStride, revIDist,
807 revOEmbed, revOStride, revODist, 1);
811 procFFT->
upsample2D(firstTile, firstTile, _refineFactor);
830template <
typename raster_t>
833_zoomcor(value_type * gamma)
const -> value_type *
836 pyre::journal::debug_t channel(
"ampcor");
839 auto corShape = _corRefinedLayout.shape();
841 int corDim = corShape[0];
843 auto zmdShape = _corZoomedLayout.shape();
845 auto zmdCells = _corZoomedLayout.size();
847 int zmdDim = zmdShape[0];
850 auto scratch = kernels::r2c(gamma, _pairs, corDim, zmdDim);
856 int ranks[] = { corDim, corDim };
858 int iEmbed[] = { zmdDim, zmdDim };
862 int iDist = zmdCells;
864 int oEmbed[] = { zmdDim, zmdDim };
868 int oDist = zmdCells;
872 #pragma omp parallel reduction(+:nthreads)
880 if (procFFT ==
nullptr) {
882 pyre::journal::error_t error(
"ampcor");
885 << pyre::journal::at(__HERE__)
886 <<
"while instanciating a isce3::signal::Signal FFT processor"
887 << pyre::journal::endl;
889 throw std::runtime_error(
"while instanciating a isce3::signal::Signal FFT processor");
896 iEmbed, iStride, iDist,
897 oEmbed, oStride, oDist, -1);
904 oEmbed, oStride, oDist,
905 oEmbed, oStride, oDist, 1);
909 procFFT->
upsample2D(scratch, scratch, _zoomFactor);
916 auto zoomed = kernels::c2r(scratch, _pairs, zmdDim);
929template <
typename raster_t>
935 auto margin = (_tgtLayout.shape()[0] - _refLayout.shape()[0]) / 2;
937 auto zoom = _refineFactor * _zoomFactor;
940 kernels::offsetField(fine, _pairs, margin, _refineMargin, zoom, _offsets);
Definition Sequential.h:18
A class to handle 2D FFT or 1D FFT in range or azimuth directions.
Definition Signal.h:22
void fftPlanForward(std::valarray< std::complex< T > > &input, std::valarray< std::complex< T > > &output, int rank, int *n, int howmany, int *inembed, int istride, int idist, int *onembed, int ostride, int odist, int sign)
initiate forward FFTW3 plan for a block of complex data input parameters follow FFTW3 interface for f...
Definition Signal.cpp:39
void fftPlanBackward(std::valarray< std::complex< T > > &input, std::valarray< std::complex< T > > &output, int rank, int *n, int howmany, int *inembed, int istride, int idist, int *onembed, int ostride, int odist, int sign)
initiate iverse FFTW3 plan for a block of spectrum input parameters follow FFTW3 interface for fftw_p...
Definition Signal.cpp:164
void upsample2D(std::valarray< std::complex< T > > &signal, std::valarray< std::complex< T > > &signalOversampled, int oversampleFactor)
2D upsampling a block of 2D data
Definition Signal.cpp:1097