Revert "Add option to checkpoint every evaluation"
[openmx:openmx.git] / src / omxState.h
1 /*
2  *  Copyright 2007-2014 The OpenMx Project
3  *
4  *  Licensed under the Apache License, Version 2.0 (the "License");
5  *  you may not use this file except in compliance with the License.
6  *  You may obtain a copy of the License at
7  *
8  *       http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *   Unless required by applicable law or agreed to in writing, software
11  *   distributed under the License is distributed on an "AS IS" BASIS,
12  *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License.
15  */
16
17 /***********************************************************
18 *
19 *  omxState.h
20 *
21 *  Created: Timothy R. Brick    Date: 2009-05-23
22 *
23 *       Contains header information for the omxState structure
24 *   omxStates keep the current optimization state.
25 *
26 **********************************************************/
27
28 #ifndef _OMXSTATE_H_
29 #define _OMXSTATE_H_
30
31 #define R_NO_REMAP
32 #include <R.h>
33 #include <Rinternals.h>
34 #include <R_ext/Rdynload.h>
35 #include <R_ext/BLAS.h>
36 #include <R_ext/Lapack.h>
37 #include <sys/types.h>
38
39 #ifdef WIN32
40
41 #else
42
43 #include <sys/socket.h>
44 #include <netinet/in.h>
45 #include <netdb.h>
46
47 #endif
48
49 #include <time.h>
50 #include <unistd.h>
51 #include <string>
52 #include <stdarg.h>
53
54 #include "omxDefines.h"
55
56 /* Forward declarations for later includes */
57 typedef struct omxState omxState;
58 typedef struct omxFreeVar omxFreeVar;
59 typedef struct omxConstraint omxConstraint;
60 typedef struct omxConfidenceInterval omxConfidenceInterval;
61
62 #include "omxMatrix.h"
63 #include "omxAlgebra.h"
64 #include "omxExpectation.h"
65 #include "omxFitFunction.h"
66 #include "omxData.h"
67
68 struct omxFreeVarLocation {
69         int matrix;
70         int row, col;
71 };
72
73 struct omxFreeVar {
74         int id;
75         double lbound, ubound;
76         std::vector<omxFreeVarLocation> locations;
77         int numDeps;            // number of algebra/matrix dependencies
78         int *deps;              // indices of algebra/matrix dependencies
79         const char* name;
80         
81         omxFreeVarLocation *getLocation(int matrix);
82 };
83
84 #define FREEVARGROUP_ALL      0
85 #define FREEVARGROUP_NONE    -1
86 #define FREEVARGROUP_INVALID -2
87
88 struct FreeVarGroup {
89         std::vector<int> id;
90         std::vector< omxFreeVar* > vars;
91
92         // see cacheDependencies
93         std::vector<bool> dependencies;
94         std::vector<bool> locations;
95
96         int lookupVar(const char *name);  // index or -1 if not found
97         void cacheDependencies();
98         void markDirty(omxState *os);
99         void log();
100         bool hasSameVars(FreeVarGroup *g2);
101 };
102
103 #define NEG_INF -2e20
104 #define INF 2e20
105
106 struct omxConstraint {          // Free Variable Constraints
107         int size;
108         int opCode;
109         double* lbound;
110         double* ubound;
111         omxMatrix* result;
112 };
113
114 enum omxCheckpointType {
115         OMX_FILE_CHECKPOINT,
116         OMX_CONNECTION_CHECKPOINT
117 };
118 typedef enum omxCheckpointType omxCheckpointType;
119
120 class omxCheckpoint {
121         bool wroteHeader;
122         time_t lastCheckpoint;  // FIXME: Cannot update at sub-second times.
123         int lastIterations;
124         bool fitPending;
125
126         void omxWriteCheckpointHeader();
127         void _prefit(FitContext *fc, double *est, bool force, const char *context);
128
129  public:
130         omxCheckpointType type;
131         time_t timePerCheckpoint;
132         int iterPerCheckpoint;
133         FILE* file;
134
135         omxCheckpoint();
136         void message(FitContext *fc, double *est, const char *msg);
137         void prefit(FitContext *fc, double *est, bool force);
138         void postfit(FitContext *fc);
139         ~omxCheckpoint();
140 };
141
142 struct omxConfidenceInterval {          // For Confidence interval request
143         omxMatrix* matrix;                              // The matrix
144         int row, col;                                   // Location of element to calculate
145         double ubound;                                  // Fit-space upper boundary
146         double lbound;                                  // Fit-space lower boundary
147         double max;                                             // Value at upper bound
148         double min;                                             // Value at lower bound
149         int lCode;                                              // Optimizer code at lower bound
150         int uCode;                                              // Optimizer code at upper bound
151         unsigned short calcLower;               // Are we currently calculating lbound?
152 };
153
154 #define MAX_STRING_LEN 250
155
156 // omxGlobal is for state that is read-only during parallel sections.
157 class omxGlobal {
158  public:
159         int ciMaxIterations;
160         int numThreads;
161         int analyticGradients;
162         int numChildren;  // == globalState->childList.size()
163         double llScale;
164
165         double maxptsa;
166         double maxptsb;
167         double maxptsc;
168         double absEps;
169         double relEps;
170
171         int maxStackDepth;
172
173         int numIntervals;
174         omxConfidenceInterval* intervalList;
175
176         std::vector< FreeVarGroup* > freeGroup;
177
178         FreeVarGroup *findOrCreateVarGroup(int id);
179         FreeVarGroup *findVarGroup(int id);
180
181         // These lists exist only to free memory
182         std::vector< omxCompute* > computeList;
183         std::vector< omxAlgebra* > algebraList;
184
185         std::vector< std::string > bads;
186
187         // Will need revision if multiple optimizers are running in parallel
188         std::vector< omxCheckpoint* > checkpointList;
189
190         omxGlobal();
191         void deduplicateVarGroups();
192         const char *getBads();
193         void checkpointMessage(FitContext *fc, double *est, const char *fmt, ...) __attribute__((format (printf, 4, 5)));
194         void checkpointPrefit(FitContext *fc, double *est, bool force);
195         void checkpointPostfit(FitContext *fc);
196
197         ~omxGlobal();
198 };
199
200 // Use a pointer to ensure correct initialization and destruction
201 extern struct omxGlobal *Global;
202
203 // omxState is for stuff that must be duplicated for thread safety.
204 struct omxState {
205         bool stale;
206
207         // move to FitContext? TOOD
208         std::vector< omxMatrix* > matrixList;
209         std::vector< omxMatrix* > algebraList;
210         std::vector< omxExpectation* > expectationList;
211         std::vector< omxData* > dataList;
212         std::vector< omxState* > childList;
213
214         // move all constraint stuff to omxGlobal TODO
215         int numConstraints;
216         int ncnln;                                               // Number of linear and nonlinear constraints
217         omxConstraint* conList;                                                                                 // List of constraints
218
219 /* Data members for use by Fit Function and Algebra Calculations */
220         long int computeCount;                                                                                  // How many times have things been evaluated so far?
221         long int currentRow;                                                                                    // If we're calculating row-by-row, what row are we on?
222 };
223
224 extern omxState* globalState;
225
226 /* Initialize and Destroy */
227         void omxInitState(omxState* state);
228         void omxFillState(omxState* state, /*omxOptimizer *oo,*/ omxMatrix** matrixList, omxMatrix** algebraList, omxData** dataList, omxMatrix* fitFunction);
229 void omxFreeChildStates(omxState *state);
230 void omxFreeState(omxState *state);
231         void omxDuplicateState(omxState *tgt, omxState* src); 
232
233         omxMatrix* omxLookupDuplicateElement(omxState* os, omxMatrix* element);
234
235 inline bool isErrorRaised(omxState *) { return Global->bads.size() != 0; }
236 void omxRaiseError(const char* Rf_errorMsg); // DEPRECATED
237 void omxRaiseErrorf(const char* Rf_errorMsg, ...) __attribute__((format (printf, 1, 2)));
238
239 /* Advance a step */
240         void omxStateNextRow(omxState *state);                                                          // Advance Row
241         void omxStateNextEvaluation(omxState *state);                                           // Advance Evaluation count
242
243 void mxLog(const char* msg, ...) __attribute__((format (printf, 1, 2)));   // thread-safe
244 void mxLogBig(const std::string str);
245 std::string string_snprintf(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
246 std::string string_vsnprintf(const char *fmt, va_list ap);
247
248 #endif /* _OMXSTATE_H_ */
249
250