LCOV - code coverage report
Current view: top level - msvis/MSVis - VLAT.h (source / functions) Hit Total Coverage
Test: ctest_coverage.info Lines: 0 27 0.0 %
Date: 2023-11-02 14:27:30 Functions: 0 128 0.0 %

          Line data    Source code
       1             : //# VLAT.h: Visibility lookahead concurrency definitions (classes VlaDatum, VlaData, VLAT)
       2             : //# Copyright (C) 2011
       3             : //# Associated Universities, Inc. Washington DC, USA.
       4             : //#
       5             : //# This library is free software; you can redistribute it and/or modify it
       6             : //# under the terms of the GNU Library General Public License as published by
       7             : //# the Free Software Foundation; either version 2 of the License, or (at your
       8             : //# option) any later version.
       9             : //#
      10             : //# This library is distributed in the hope that it will be useful, but WITHOUT
      11             : //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
      12             : //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
      13             : //# License for more details.
      14             : //#
      15             : //# You should have received a copy of the GNU Library General Public License
      16             : //# along with this library; if not, write to the Free Software Foundation,
      17             : //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
      18             : //#
      19             : //# Correspondence concerning CASA should be addressed as follows:
      20             : //#        Internet email: CASA-request@nrao.edu.
      21             : //#        Postal address: CASA Project Office
      22             : //#                        National Radio Astronomy Observatory
      23             : //#                        520 Edgemont Road
      24             : //#                        Charlottesville, VA 22903-2475 USA
      25             : //#
      26             : //#
      27             : //# $Id$
      28             : 
      29             : #ifndef VLAT_H_
      30             : #define VLAT_H_
      31             : 
      32             : #include <stdcasa/thread/AsynchronousTools.h>
      33             : #include <stdcasa/UtilJ.h>
      34             : 
      35             : #include <tuple>
      36             : #include <msvis/MSVis/AsynchronousInterface.h>
      37             : #include <msvis/MSVis/VisBuffer.h>
      38             : #include <msvis/MSVis/VisBufferAsync.h>
      39             : #include <msvis/MSVis/VisBufferComponents.h>
      40             : #include <msvis/MSVis/VisibilityIterator.h>
      41             : #include <msvis/MSVis/VisibilityIteratorImplAsync.h>
      42             : 
      43             : #include <map>
      44             : 
      45             : namespace casacore{
      46             : 
      47             : template<typename T> class Block;
      48             : class MeasurementSet;
      49             : }
      50             : 
      51             : namespace casa {
      52             : 
      53             : //using namespace casa::async;
      54             : using casa::asyncio::RoviaModifiers;
      55             : using casa::utilj::ThreadTimes;
      56             : using casa::utilj::DeltaThreadTimes;
      57             : 
      58             : 
      59             : class VisBuffer;
      60             : 
      61             : namespace asyncio {
      62             : 
      63             : class AsynchronousInterface;
      64             : class InterfaceController;
      65             : 
      66             : // VlatFunctor is an abstract class for functor objects used to encapsulate the various
      67             : // filling methods (e.g., fillVis, fillAnt1, etc.).  This allows the various functions
      68             : // to be put into a list of fill methods that are used by the VLAT everytime the VLAT's
      69             : // visibliity iterator is advanced.  There are two subclasses VlatFunctor0 and VlatFunctor1
      70             : // which support nullar and unary fill methods.  The fillers for visibility-related data
      71             : // (e.g., fillVis and fillVisCube) take a parameter to indicate which sort of visibility
      72             : // (e.g., actual, model, corrected) is to be filled.
      73             : 
      74             : class VlatFunctor {
      75             : 
      76             : public:
      77             : 
      78             : 
      79           0 :     VlatFunctor (const casacore::String & name, casacore::Int precedence = 0)
      80           0 :     : id_p (VisBufferComponents::N_VisBufferComponents), name_p (name), precedence_p (precedence)
      81           0 :     {}
      82           0 :     VlatFunctor (casacore::Int precedence = 0)
      83           0 :     : id_p (VisBufferComponents::N_VisBufferComponents), name_p ("NotSpecified"), precedence_p (precedence)
      84           0 :     {}
      85           0 :     virtual ~VlatFunctor () {}
      86             : 
      87             :     virtual void operator() (VisBuffer *); // Throws an error if not overridden
      88           0 :     virtual VlatFunctor * clone () { return new VlatFunctor (* this);}
      89             : 
      90           0 :     VisBufferComponents::EnumType getId () const { return id_p;}
      91           0 :     void setId (VisBufferComponents::EnumType id) { id_p = id;}
      92             :     void setPrecedence (casacore::Int precedence) { precedence_p = precedence; }
      93             : 
      94             :     static casacore::Bool byDecreasingPrecedence (const VlatFunctor * a, const VlatFunctor * b)
      95             :     {   // First by increasing precedence and then by decreasing id (make deterministic)
      96             :         casacore::Bool result = (a->precedence_p > b->precedence_p) ||
      97             :                       (a->precedence_p == b->precedence_p && a->id_p < b->id_p);
      98             :         return result;
      99             :     }
     100             : private:
     101             : 
     102             :     VisBufferComponents::EnumType id_p;
     103             :     casacore::String name_p;
     104             :     casacore::Int precedence_p;
     105             : 
     106             : };
     107             : 
     108             : template <typename Ret, typename VbType>
     109             : class VlatFunctor0 : public VlatFunctor {
     110             : 
     111             : public:
     112             : 
     113             :     typedef Ret (VbType::* Nullary) ();
     114             : 
     115           0 :     VlatFunctor0 (Nullary nullary, casacore::Int precedence = 0) : VlatFunctor (precedence), f_p (nullary) {}
     116           0 :     virtual ~VlatFunctor0 () {}
     117             : 
     118           0 :     void operator() (VisBuffer * c) { (dynamic_cast<VbType *> (c)->*f_p)(); }
     119           0 :     virtual VlatFunctor * clone () { return new VlatFunctor0 (* this); }
     120             : 
     121             : private:
     122             : 
     123             :     Nullary f_p;
     124             : };
     125             : 
     126             : template <typename Ret, typename VbType>
     127           0 : VlatFunctor0<Ret, VbType> * vlatFunctor0 (Ret (VbType::* f) ())
     128           0 : { return new VlatFunctor0<Ret, VbType> (f);}
     129             : 
     130             : template <typename Ret, typename Arg>
     131             : class VlatFunctor1 : public VlatFunctor {
     132             : 
     133             : public:
     134             : 
     135             :     typedef Ret (VisBuffer::* Unary) (Arg);
     136             : 
     137           0 :     VlatFunctor1 (Unary unary, Arg arg, casacore::Int precedence = 0) : VlatFunctor (precedence) { f_p = unary; arg_p = arg;}
     138           0 :     virtual ~VlatFunctor1 () {}
     139             : 
     140           0 :     void operator() (VisBuffer * c) { (c->*f_p)(arg_p); }
     141           0 :     virtual VlatFunctor * clone () { return new VlatFunctor1 (* this); }
     142             : 
     143             : private:
     144             : 
     145             :     Unary f_p;
     146             :     Arg arg_p;
     147             : };
     148             : 
     149             : template <typename Ret, typename Arg>
     150           0 : VlatFunctor1<Ret, Arg> * vlatFunctor1 (Ret (VisBuffer::* f) (Arg), Arg i)
     151           0 : { return new VlatFunctor1<Ret, Arg> (f, i);}
     152             : 
     153             : // <summary>
     154             : // VLAT is the Visibility LookAhead Thread.  This thread advances a visibility iterator
     155             : // and fills the data indicated by the visibility iterator into the VlaData buffer ring.
     156             : // </summary>
     157             : 
     158             : // <use visibility=local>
     159             : 
     160             : // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos="">
     161             : // </reviewed>
     162             : 
     163             : // <prerequisite>
     164             : //   <li> VisBuffer
     165             : //   <li> VisBufferAsync
     166             : //   <li> ROVisibilityIteratorAsync
     167             : //   <li> VlaData
     168             : //   <li> VLAT
     169             : // </prerequisite>
     170             : //
     171             : // <etymology>
     172             : //    VLAT is the Visibility LookAhead Thread.  It is not related to the more common NRAO
     173             : //    acronym VLA.
     174             : // </etymology>
     175             : //
     176             : // <synopsis>
     177             : //
     178             : //    The VLAT is a thread object that buffers up data from successive visibility iterator positions
     179             : //    in a MeasurementSet.  It is part of the backend to a ROVisibilityIteratorAsync (ROVIA)
     180             : //    object used by the main thread to replace the normal, synchronous ROVisibilityIterator.
     181             : //    When the user creates a ROVIA object the information normally used to create a ROVisibilityIterator
     182             : //    is passed to the VLAT which uses it to create a ROVisibilityIterator local to itself.  The VLAT then
     183             : //    uses this ROVisibilityIterator to fill buffers in the VlaData-managed buffer ring (this interaction
     184             : //    is described in VlaData).  Filling consists of attaching VLAT's ROVisibilityIterator to the
     185             : //    VisBufferAsync object associated with a buffer and then calling the fill operations for the data
     186             : //    items (e.g., visCube, Ant1, etc.) which the user has requested be prefetched.  The fill operations
     187             : //    will likely result in synchronous I/O operations being performed by the column access methods
     188             : //    related to the casacore::Table system (memory-resident tables, columns, etc., may be able to satisfy a fill
     189             : //    operation without performing I/O).
     190             : //
     191             : //    The thread may be terminated by calling the terminate method.  This will cause the VLAT to terminate
     192             : //    when it notices the termination request.  The termination may not be immediate since the VLAT may
     193             : //    be engaged in a syncrhonous I/O operation and is uanble to detect the termination request until
     194             : //    that I/O has completed.
     195             : //
     196             : //    Normally the VLAT sweeps the VI to the end of the measurement set and then awaits further instructions.
     197             : //    The main thread may stop the sweep early by calling VlaData::terminateSweep which will eventually be
     198             : //    detected by the VLAT and result in a coordinated reset of the sweep.  When the sweep reset is applied
     199             : //    the VLAT will also detect visibility iterator modification requests (e.g., setRowBlocking, selectChannel,
     200             : //    setInterval, etc.) that were queued up in VlaData; for the set of available VI modification requests
     201             : //    supported see ROVisibilityIteratorAsync.
     202             : //
     203             : // </synopsis>
     204             : //
     205             : // <example>
     206             : // </example>
     207             : //
     208             : // <motivation>
     209             : // </motivation>
     210             : //
     211             : // <thrown>
     212             : //    <li> casacore::AipsError for unrecoverable errors.  These will not be caught (in C++ anyway) and cause
     213             : //         application termination.
     214             : // </thrown>
     215             : //
     216             : // <todo asof="yyyy/mm/dd">
     217             : // </todo>
     218             : 
     219             : class VLAT : public casa::async::Thread {
     220             : 
     221             : public:
     222             : 
     223             :     VLAT (AsynchronousInterface *);
     224             :     ~VLAT ();
     225             : 
     226             :     void clearFillTerminationRequest ();
     227             :     void initialize (const ROVisibilityIterator & rovi);
     228             :     void initialize (const casacore::Block<casacore::MeasurementSet> & mss,
     229             :                      const casacore::Block<casacore::Int> & sortColumns,
     230             :                      casacore::Bool addDefaultSortCols,
     231             :                      casacore::Double timeInterval,
     232             :                      casacore::Bool writable);
     233             :     casacore::Bool isTerminated () const;
     234             :     void setModifiers (RoviaModifiers & modifiers);
     235             :     void setPrefetchColumns (const PrefetchColumns & prefetchColumns);
     236             :     void requestSweepTermination ();
     237             :     void terminate ();
     238             : 
     239             : protected:
     240             : 
     241             :     class FillerDictionary : public std::map<VisBufferComponents::EnumType, VlatFunctor *> {
     242             : 
     243             :     public:
     244             : 
     245           0 :     void add (VisBufferComponents::EnumType id, VlatFunctor * f)
     246             :     {
     247           0 :         f->setId (id);
     248           0 :         assert (find(id) == end()); // shouldn't already have one for this ID
     249           0 :         (* this)[id] =  f;
     250           0 :     }
     251             : 
     252             :         //void setPrecedences (const FillerDependencies & dependencies);
     253             :     };
     254             :     typedef std::vector<VlatFunctor *> Fillers;
     255             : 
     256             :     void applyModifiers (ROVisibilityIterator * rovi, VisibilityIterator * vi);
     257             :     void alignWriteIterator (SubChunkPair subchunk);
     258             :     void checkFiller (VisBufferComponents::EnumType id);
     259             :     void createFillerDictionary ();
     260             :     void fillDatum (VlaDatum * datum);
     261             :     void fillDatumMiscellanyAfter (VlaDatum * datum);
     262             :     void fillDatumMiscellanyBefore (VlaDatum * datum);
     263             :     void fillLsrInfo (VlaDatum * datum);
     264             :     void flushWrittenData ();
     265             :     void handleWrite ();
     266             :     void * run ();
     267             :     casacore::Bool sweepTerminationRequested () const;
     268             :     void sweepVi ();
     269             :     void throwIfSweepTerminated ();
     270             :     casacore::Bool waitForViReset ();
     271             :     void waitUntilFillCanStart ();
     272             : 
     273             : private:
     274             : 
     275             :     class SweepTerminated : public std::exception {};
     276             : 
     277             : //    class NullaryPredicate {
     278             : //    public:
     279             : //
     280             : //        virtual ~NullaryPredicate () {}
     281             : //        virtual casacore::Bool operator () () const = 0;
     282             : //    };
     283             : //
     284             : //    class FillCanStartOrSweepTermination : public NullaryPredicate {
     285             : //
     286             : //    public:
     287             : //
     288             : //        FillCanStartOrSweepTermination (VlaData * vlaData, AsynchronousInterface * interface)
     289             : //        : interface_p (interface),
     290             : //          vlaData_p (vlaData)
     291             : //        {}
     292             : //
     293             : //        casacore::Bool operator() () const
     294             : //        {
     295             : //            return vlaData_p->fillCanStart () || interface_p->isSweepTerminationRequested ();
     296             : //        }
     297             : //
     298             : //    private:
     299             : //
     300             : //        AsynchronousInterface * interface_p;
     301             : //        VlaData * vlaData_p;
     302             : //    };
     303             : //
     304             : //    class ViResetOrLookaheadTermination : public NullaryPredicate {
     305             : //
     306             : //    public:
     307             : //
     308             : //        ViResetOrLookaheadTermination (AsynchronousInterface * interface)
     309             : //        : interface_p (interface)
     310             : //        {}
     311             : //
     312             : //        casacore::Bool operator() () const
     313             : //        {
     314             : //            casacore::Bool viWasReset_p = interface_p->viResetRequested;
     315             : //
     316             : //            return viWasReset_p || interface_p->isLookaheadTerminationRequested ();
     317             : //        }
     318             : //
     319             : //    private:
     320             : //
     321             : //        AsynchronousInterface * interface_p;
     322             : //    };
     323             : 
     324             :     const InterfaceController * controller_p; // [use]
     325             :     FillerDictionary            fillerDictionary_p;
     326             :     Fillers                     fillers_p;
     327             :     AsynchronousInterface *     interface_p; // [use]
     328             :     casacore::Block<casacore::MeasurementSet>       measurementSets_p;
     329             :     SubChunkPair                readSubchunk_p;
     330             :     RoviaModifiers              roviaModifiers_p;
     331             :     volatile casacore::Bool               sweepTerminationRequested_p;
     332             :     casacore::Bool                        threadTerminated_p;
     333             :     ROVisibilityIterator *      visibilityIterator_p; // [own]
     334             :     VlaData *                   vlaData_p; // [use]
     335             :     VisibilityIterator *        writeIterator_p; // [own]
     336             :     SubChunkPair                writeSubchunk_p;
     337             : 
     338             : };
     339             : 
     340             : class VlatAndData {
     341             : 
     342             :     friend class ViReadImplAsync;
     343             : 
     344             : public:
     345             : 
     346             : protected:
     347             : 
     348             :     VlatAndData ();
     349             :     ~VlatAndData (){}
     350             : 
     351             : private:
     352             : 
     353             :     VlaData * vlaData_p;
     354             :     VLAT * vlat_p;
     355             : };
     356             : 
     357             : } // end namespace asyncio
     358             : 
     359             : } // end namespace casa
     360             : 
     361             : 
     362             : #endif /* VLAT_H_ */

Generated by: LCOV version 1.16