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_ */
|