DistSIIterBot.h

Go to the documentation of this file.
00001 /* -*- mode: c++ -*- */
00002 //# DistSIIterBot.h: Parallel imaging iteration control
00003 //# Copyright (C) 2016
00004 //# Associated Universities, Inc. Washington DC, USA.
00005 //#
00006 //# This library is free software; you can redistribute it and/or modify it
00007 //# under the terms of the GNU Library General Public License as published by
00008 //# the Free Software Foundation; either version 2 of the License, or (at your
00009 //# option) any later version.
00010 //#
00011 //# This library is distributed in the hope that it will be useful, but WITHOUT
00012 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00013 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00014 //# License for more details.
00015 //#
00016 //# You should have received a copy of the GNU Library General Public License
00017 //# along with this library; if not, write to the Free Software Foundation,
00018 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00019 //#
00020 //# Correspondence concerning AIPS++ should be addressed as follows:
00021 //#        Internet email: aips2-request@nrao.edu.
00022 //#        Postal address: AIPS++ Project Office
00023 //#                        National Radio Astronomy Observatory
00024 //#                        520 Edgemont Road
00025 //#                        Charlottesville, VA 22903-2475 USA
00026 //#
00027 #ifndef DIST_S_I_ITER_BOT_H_
00028 #define DIST_S_I_ITER_BOT_H_
00029 
00030 #include <casadbus/utilities/BusAccess.h>
00031 // .casarc interface
00032 #include <casa/System/AipsrcValue.h>
00033 
00034 // System utilities (for profiling macros)
00035 #include <casa/OS/HostInfo.h>
00036 #include <sys/time.h>
00037 #if defined(DBUS_CPP)
00038 #include <dbus-cpp/dbus.h> /*for DBus::Variant... probably can be removed with *_adaptor class*/
00039 #else
00040 #include <dbus-c++/dbus.h>
00041 #endif
00042 
00043 // Include files for the DBus Service
00044 //#include <casadbus/interfaces/SynthImager.adaptor.h>
00045 
00046 #ifdef INTERACTIVE_ITERATION
00047 #include <casadbus/interfaces/SynthImager.adaptor.h>
00048 #endif
00049 #include <synthesis/ImagerObjects/SIIterBot.h>
00050 #include <synthesis/ImagerObjects/MPIGlue.h>
00051 #include <mutex>
00052 
00053 namespace casa { //# NAMESPACE CASA - BEGIN
00054 
00055 class DistSIIterBot_state
00056         : public SIIterBot_state {
00057 private:
00058         // make DistSIIterBot_state uncopyable...
00059         DistSIIterBot_state(const DistSIIterBot_state &);
00060         DistSIIterBot_state &operator=(const DistSIIterBot_state &);
00061 
00062 public:
00063         DistSIIterBot_state(SHARED_PTR<SIIterBot_callback>, MPI_Comm);
00064         ~DistSIIterBot_state( );
00065 
00066         bool interactiveInputRequired();
00067         void waitForInteractiveInput(); 
00068         int cleanComplete();
00069         Record getMinorCycleControls();
00070         void mergeCycleInitializationRecord(Record&);
00071         void mergeCycleExecutionRecord(Record&);
00072         Record getSummaryRecord();
00073         Record getDetailsRecord();
00074 
00075         void mergeCycleInitializationRecords(const Vector<Record> &);
00076         void mergeCycleExecutionRecords(const Vector<Record> &);
00077 
00078         int rank;
00079         int commSize;
00080 
00081 protected:
00082         void mergeMinorCycleSummary(const Array<Double>&);
00083 
00084         MPI_Comm comm;
00085 
00086         MPI_Datatype execRecordDatatype;
00087         MPI_Op execRecordReduceOp;
00088         MPI_Datatype detailsRecordDatatype;
00089         MPI_Datatype controlRecordDatatype;
00090 };
00091 
00092 struct ExecRecord {
00093         ExecRecord(int iterDone, int maxCycleIterDone, float peakResidual,
00094                    bool updatedModelFlag);
00095 
00096         ExecRecord(const Record &rec);
00097 
00098         Record asRecord();
00099 
00100         // Don't modify the following fields, including their order, without a
00101         // corresponding change in the computation of datatype()!
00102         float peakResidual;
00103         int iterDone;
00104         int maxCycleIterDone;
00105         MPI_BOOL_TYPE updatedModelFlag;
00106 
00107         void reduce(const ExecRecord *rec) {
00108                 iterDone += rec->iterDone;
00109                 maxCycleIterDone = std::max(maxCycleIterDone, rec->maxCycleIterDone);
00110                 peakResidual = std::max(peakResidual, rec->peakResidual);
00111                 updatedModelFlag |= rec->updatedModelFlag;
00112         };
00113 
00114         // It might be nice to have static class members to hold the MPI datatype
00115         // and reduction op, but since they can only be computed at run-time, that
00116         // would require a mutex and lock (the computation would have to be in a
00117         // critical section). In turn that would require acquiring the lock every
00118         // time the datatype is accessed, which is something that we'd like to
00119         // avoid.
00120         static MPI_Datatype datatype() {
00121                 int blocklengths[3] UNUSED_WITHOUT_MPI = { 1, 2, 1 };
00122                 MPI_Aint displacements[3] UNUSED_WITHOUT_MPI = {
00123                         offsetof(struct ExecRecord, peakResidual),
00124                         offsetof(struct ExecRecord, iterDone),
00125                         offsetof(struct ExecRecord, updatedModelFlag) };
00126                 MPI_Datatype types[3] UNUSED_WITHOUT_MPI =
00127                         { MPI_FLOAT, MPI_INT, MPI_BOOL };
00128                 MPI_Datatype dt;
00129                 MPI_Type_create_struct(3, blocklengths, displacements, types, &dt);
00130                 MPI_Datatype result;
00131                 // to capture padding for alignment of structures, we resize dt
00132                 MPI_Type_create_resized(dt, 0, sizeof(struct ExecRecord),
00133                                         &result);
00134                 MPI_Type_free(&dt);
00135                 return result;
00136         };
00137 
00138         static MPI_Op reduceOp() {
00139                 MPI_Op result;
00140                 MPI_Op_create(
00141                         static_cast<MPI_User_function *>(ExecRecord::reduceOpFun),
00142                         true,
00143                         &result);
00144                 return result;
00145         };
00146 
00147         static void reduceOpFun(void *invec, void *inoutvec, int *len,
00148                                 MPI_Datatype *datatype __attribute__((unused))) {
00149                 const ExecRecord *exin = static_cast<const ExecRecord *>(invec);
00150                 ExecRecord *exinout = static_cast<ExecRecord *>(inoutvec);
00151                 int cnt = *len; // OpenMPI at least doesn't like it if you directly
00152                                                 // decrement the value pointed to by *len -- not sure
00153                                                 // that the standard says anything about doing that
00154                 while (cnt-- > 0) {
00155                         exinout->reduce(exin);
00156                         ++exinout;
00157                         ++exin;
00158                 }
00159         };
00160 };
00161 
00162 struct DetailsRecord {
00163         DetailsRecord(const Record &rec);
00164 
00165         Record asRecord();
00166 
00167         // Don't modify the following fields, including their order, without a
00168         // corresponding change in the computation of datatype()!
00169         float threshold;
00170         float cycleThreshold;
00171         float interactiveThreshold;
00172         float loopGain;
00173         float cycleFactor;
00174         float maxPsfSidelobe;
00175         float maxPsfFraction;
00176         float minPsfFraction;
00177         int niter;
00178         int cycleNiter;
00179         int interactiveNiter;
00180         int iterDone;
00181         int maxCycleIterDone;
00182         int interactiveIterDone;
00183         int majorDone;
00184         int cleanState; // 0: stopped, 1: paused, 2: running
00185         MPI_BOOL_TYPE interactiveMode;
00186 
00187         static MPI_Datatype datatype() {
00188                 int blocklengths[3] UNUSED_WITHOUT_MPI = { 8, 8, 1 };
00189                 MPI_Aint displacements[3] UNUSED_WITHOUT_MPI = {
00190                         offsetof(struct DetailsRecord, threshold),
00191                         offsetof(struct DetailsRecord, niter),
00192                         offsetof(struct DetailsRecord, interactiveMode) };
00193                 MPI_Datatype types[3] UNUSED_WITHOUT_MPI =
00194                         { MPI_FLOAT, MPI_INT, MPI_BOOL };
00195                 MPI_Datatype dt;
00196                 MPI_Type_create_struct(3, blocklengths, displacements, types, &dt);
00197                 MPI_Datatype result;
00198                 // to capture padding for alignment of structures, we resize dt
00199                 MPI_Type_create_resized(dt, 0, sizeof(struct DetailsRecord),
00200                                         &result);
00201                 MPI_Type_free(&dt);
00202                 return result;
00203         };
00204 };
00205 
00206 struct ControlRecord {
00207         ControlRecord(int niter, int cycleNiter,
00208                       float threshold, float cycleThreshold,
00209                       float loopGain, bool stopFlag);
00210 
00211         ControlRecord(const Record &rec);
00212 
00213         Record asRecord();
00214 
00215         // Don't modify the following fields, including their order, without a
00216         // corresponding change in the computation of datatype()!
00217         float threshold;
00218         float cycleThreshold;
00219         float loopGain;
00220         int niter;
00221         int cycleNiter;
00222         MPI_BOOL_TYPE stopFlag;
00223 
00224         // It might be nice to have static class members to hold the MPI datatype
00225         // and reduction op, but since they can only be computed at run-time, that
00226         // would require a mutex and lock, since the computation would have to be in
00227         // a critical section. In turn that would require acquiring the lock every
00228         // time the datatype is accessed, which is something that we'd like to
00229         // avoid.
00230         static MPI_Datatype datatype() {
00231                 int blocklengths[3] UNUSED_WITHOUT_MPI = { 3, 2, 1 };
00232                 MPI_Aint displacements[3] UNUSED_WITHOUT_MPI = {
00233                         offsetof(struct ControlRecord, threshold),
00234                         offsetof(struct ControlRecord, niter),
00235                         offsetof(struct ControlRecord, stopFlag)};
00236                 MPI_Datatype types[3] UNUSED_WITHOUT_MPI =
00237                         { MPI_FLOAT, MPI_INT, MPI_BOOL };
00238                 MPI_Datatype dt;
00239                 MPI_Type_create_struct(3, blocklengths, displacements, types, &dt);
00240                 MPI_Datatype result;
00241                 // to capture padding for alignment of structures, we resize dt
00242                 MPI_Type_create_resized(dt, 0, sizeof(struct ControlRecord),
00243                                         &result);
00244                 MPI_Type_free(&dt);
00245                 return result;
00246         };
00247 };
00248 
00249 } //# NAMESPACE CASA - END
00250 
00251 #endif // DIST_S_I_ITER_BOT_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 31 Aug 2016 for casa by  doxygen 1.6.1