LALInference 4.1.9.1-eeff03c
LALInferenceKombine.c
Go to the documentation of this file.
1/*
2 * LALInferenceKombine.c: Bayesian Followup function testing site
3 *
4 * Copyright (C) 2014 Ben Farr
5 *
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with with program; see the file COPYING. If not, write to the
19 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20 * MA 02110-1301 USA
21 */
22
23
24#include <stdio.h>
25#include <lal/LALInference.h>
27#include <lal/LALInferencePrior.h>
28#include <lal/LALInferenceProposal.h>
29#include <lal/LALInferenceLikelihood.h>
30#include <lal/LALInferenceReadData.h>
31#include <lal/LALInferenceInit.h>
32#include <lal/LALInferenceCalibrationErrors.h>
33
34#include <mpi.h>
35
36#ifndef _OPENMP
37#define omp ignore
38#endif
39
40
45
46/* Set the starting seed of rank 0, and give the rest of the threads
47 a seed based on it. This is a cut-and-paste from PTMCMC, which needs
48 to be unified in LALInference when MPI-enabled.*/
50 INT4 i, randomseed;
51 INT4 mpi_rank;
52
53 mpi_rank = LALInferenceGetINT4Variable(run_state->algorithmParams, "mpirank");
54
55 /* Broadcast rank=0's randomseed to everyone */
56 randomseed = LALInferenceGetINT4Variable(run_state->algorithmParams, "random_seed");
57 MPI_Bcast(&randomseed, 1, MPI_INT, 0, MPI_COMM_WORLD);
58 LALInferenceSetVariable(run_state->algorithmParams, "random_seed", &randomseed);
59
60 if (mpi_rank == 0)
61 printf(" initialize(): random seed: %u\n", randomseed);
62
63 /* Now make sure each MPI-thread is running with un-correlated
64 jumps. Re-seed this process with the ith output of
65 the RNG stream from the rank 0 thread. Otherwise the
66 random stream is the same across all threads. */
67 for (i = 0; i < mpi_rank; i++)
68 randomseed = gsl_rng_get(run_state->GSLrandom);
69
70 gsl_rng_set(run_state->GSLrandom, randomseed);
71
72 return XLAL_SUCCESS;
73}
74
75/* Initialize ensemble randomly or from file */
78 ProcessParamsTable *ppt = NULL;
79 REAL8 *sampleArray = NULL;
80 INT4 i=0;
81
82 ProcessParamsTable *command_line = run_state->commandLine;
83
84 LALInferenceThreadState *thread = &run_state->threads[0];
85 LALInferenceVariables *current_param = thread->currentParams;
87
88 /* Determine number of MPI threads, and the
89 * number of walkers run by each thread */
90 INT4 nwalkers_per_thread = run_state->nthreads;
91
92 INT4 mpi_rank, walker;
93 MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
94
95 ppt = LALInferenceGetProcParamVal(command_line, "--init-samples");
96 if (ppt) {
97 char *infile = ppt->value;
98 FILE *input = fopen(infile, "r");
99
100 char params[128][VARNAME_MAX];
101 INT4 *col_order = XLALCalloc(ndim, sizeof(INT4));
102 INT4 ncols;
103
104 /* Parse parameter names */
105 LALInferenceReadAsciiHeader(input, params, &ncols);
106
107 /* Only cluster parameters that are being sampled */
108 INT4 nvalid_cols=0, j=0;
109 INT4 *valid_cols = XLALCalloc(ncols, sizeof(INT4));
110
111 for (j = 0; j < ncols; j++) {
112 char* internal_pname = XLALCalloc(512, sizeof(char));
114 params[j]);
115
116 i=0;
117 valid_cols[j] = 0;
118 for (item = current_param->head; item; item = item->next) {
119 if (LALInferenceCheckVariableNonFixed(current_param,
120 item->name)) {
121 if (!strcmp(item->name, internal_pname)) {
122 col_order[i] = nvalid_cols;
123 nvalid_cols++;
124 valid_cols[j] = 1;
125 break;
126 }
127 i++;
128 }
129 }
130
131 XLALFree(internal_pname);
132 }
133
134 /* Double check dimensions */
135 if (nvalid_cols != ndim) {
136 fprintf(stderr, "Inconsistent dimensions for starting state!\n");
137 fprintf(stderr, "Sampling in %i dimensions, %i read from file!\n",
138 ndim, nvalid_cols);
139 exit(1);
140 }
141
142 /* Give a different chunk of samples to each MPI thread */
143 INT4 ch, nsamples = 0;
144 while ( nsamples < mpi_rank*nwalkers_per_thread &&
145 (ch = getc(input)) != EOF) {
146 if (ch=='\n')
147 ++nsamples;
148 }
149
150 INT4 nlines = (INT4) nwalkers_per_thread;
151 sampleArray = LALInferenceParseDelimitedAscii(input,
152 ncols, valid_cols,
153 &nlines);
154
155
156 REAL8 *parameters = XLALCalloc(ndim, sizeof(REAL8));
157 for (walker=0; walker<run_state->nthreads; walker++) {
158 thread = &run_state->threads[walker];
159
160 for (i = 0; i < ndim; i++)
161 parameters[i] = sampleArray[mpi_rank*nwalkers_per_thread*ndim + walker*ndim + col_order[i]];
162
164 }
165
166 /* Cleanup */
167 XLALFree(col_order);
168 XLALFree(valid_cols);
170 XLALFree(sampleArray);
171 } else
172 LALInferenceDrawThreads(run_state);
173
174 /* Distribute ensemble according to prior when randomly initializing */
175 if (!LALInferenceGetProcParamVal(command_line, "--init-samples") &&
176 !LALInferenceGetProcParamVal(command_line, "--skip-prior")) {
177
178 if (mpi_rank == 0)
179 printf("Distributing ensemble according to prior.\n");
180
181 sample_prior(run_state);
182
183 if (mpi_rank == 0)
184 printf("Completed prior sampling.\n");
185 }
186
187 /* Set starting likelihood values (prior function hasn't changed) */
188 #pragma omp parallel for
189 for (walker = 0; walker < nwalkers_per_thread; walker++)
190 thread = &run_state->threads[walker];
191
192 thread->currentLikelihood = run_state->likelihood(thread->currentParams,
193 run_state->data,
194 thread->model);
195
196 return XLAL_SUCCESS;
197}
198
199/********** Initialise MCMC structures *********/
200
202 char help[]="\
203 ----------------------------------------------\n\
204 --- General Algorithm Parameters -------------\n\
205 ----------------------------------------------\n\
206 (--nwalkers n) Number of MCMC walkers to sample with (1000).\n\
207 (--nsteps n) Total number of steps for all walkers to make (10000).\n\
208 (--skip n) Number of steps between writing samples to file (100).\n\
209 (--update-interval n) Number of steps between ensemble updates (100).\n\
210 (--randomseed seed) Random seed of sampling distribution (random).\n\
211 \n\
212 ----------------------------------------------\n\
213 --- Output -----------------------------------\n\
214 ----------------------------------------------\n\
215 (--data-dump) Output waveforms to file.\n\
216 (--outfile file) Write output files <file>.<chain_number>\n\
217 (ensemble.output.<random_seed>.<mpi_thread>).\n";
218 INT4 mpi_rank, mpi_size, i;
219 ProcessParamsTable *command_line=NULL, *ppt=NULL;
221
222 MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
223 MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
224
225 /* Print command line arguments if help requested */
226 if (run_state == NULL || LALInferenceGetProcParamVal(run_state->commandLine, "--help")) {
227 if (mpi_rank == 0)
228 printf("%s", help);
229
230 /* Print other help messages */
232
233 return XLAL_FAILURE;
234 }
235
236 command_line = run_state->commandLine;
237
238 /* Set up the appropriate functions for the MCMC algorithm */
239 run_state->algorithm = &ensemble_sampler;
240
241 /* Determine number of walkers */
242 INT4 nwalkers = 1000;
243 INT4 nwalkers_per_thread = nwalkers;
244 ppt = LALInferenceGetProcParamVal(command_line, "--nwalkers");
245 if (ppt) {
246 nwalkers = atoi(ppt->value);
247 nwalkers_per_thread = nwalkers / mpi_size;
248
249 if (nwalkers % mpi_size != 0.0) {
250 /* Round up to have consistent number of walkers across MPI threads */
251 nwalkers_per_thread = (INT4)ceil((REAL8)nwalkers / (REAL8)mpi_size);
252 nwalkers = mpi_size * nwalkers_per_thread;
253
254 if (mpi_rank == 0)
255 printf("Rounding up number of walkers to %i to provide \
256 consistent performance across the %i available \
257 MPI threads.\n", nwalkers, mpi_size);
258 }
259 }
260
261 /* Step counter */
262 INT4 step = 0;
263
264 /* Number of steps between ensemble updates */
265 INT4 nsteps = 10000;
266 ppt = LALInferenceGetProcParamVal(command_line, "--nsteps");
267 if (ppt)
268 nsteps = atoi(ppt->value);
269
270 /* Print sample every skip iterations */
271 INT4 skip = 100;
272 ppt = LALInferenceGetProcParamVal(command_line, "--skip");
273 if (ppt)
274 skip = atoi(ppt->value);
275
276 /* Update ensemble every *update_interval* iterations */
277 INT4 update_interval = 1000;
278 ppt = LALInferenceGetProcParamVal(command_line, "--update-interval");
279 if (ppt)
280 update_interval = atoi(ppt->value);
281
282 /* Impose cyclic/reflective bounds in KDE */
283 INT4 cyclic_reflective = 0;
284 if (LALInferenceGetProcParamVal(command_line, "--cyclic-reflective-kde"))
285 cyclic_reflective = 1;
286
287 /* Print more stuff */
288 INT4 verbose = 0;
289 if (LALInferenceGetProcParamVal(command_line, "--verbose"))
290 verbose = 1;
291
292 /* Keep track of time if benchmarking */
293 INT4 benchmark = 0;
294 if (LALInferenceGetProcParamVal(command_line, "--benchmark"))
295 benchmark = 1;
296
297 /* Save everything in the run state */
298 LALInferenceVariables *algorithm_params = run_state->algorithmParams;
299
300 LALInferenceAddINT4Variable(algorithm_params, "step",
302
303 LALInferenceAddINT4Variable(algorithm_params, "verbose",
305
306 LALInferenceAddINT4Variable(algorithm_params, "benchmark",
307 benchmark, LALINFERENCE_PARAM_OUTPUT);
308
309 LALInferenceAddINT4Variable(algorithm_params, "mpirank",
310 mpi_rank, LALINFERENCE_PARAM_OUTPUT);
311
312 LALInferenceAddINT4Variable(algorithm_params, "cyclic_reflective",
313 cyclic_reflective, LALINFERENCE_PARAM_OUTPUT);
314
315 LALInferenceAddINT4Variable(algorithm_params, "nwalkers_per_thread",
316 nwalkers_per_thread, LALINFERENCE_PARAM_OUTPUT);
317
318 LALInferenceAddINT4Variable(algorithm_params, "nwalkers",
319 nwalkers, LALINFERENCE_PARAM_OUTPUT);
320
321 LALInferenceAddINT4Variable(algorithm_params, "nsteps",
323
324 LALInferenceAddINT4Variable(algorithm_params, "skip",
326
327 LALInferenceAddINT4Variable(algorithm_params, "update_interval",
328 update_interval, LALINFERENCE_PARAM_OUTPUT);
329
330 /* Initialize the walkers on this MPI thread */
331 LALInferenceInitCBCThreads(run_state, nwalkers_per_thread);
332
333 /* Establish the random state across MPI threads */
334 init_mpi_randomstate(run_state);
335
336 for (i=0; i<run_state->nthreads; i++) {
337 thread = &run_state->threads[i];
338
339 thread->id = mpi_rank*nwalkers_per_thread + i;
340 thread->proposalArgs = LALInferenceParseProposalArgs(run_state);
341 }
342
343 return XLAL_SUCCESS;
344}
345
346
347/* Sample the prior. Useful for defining an initial state for the ensemble */
349 INT4 update_interval, nprior_steps, nsteps;
350
351 LALInferenceVariables *algorithm_params = run_state->algorithmParams;
352
353 /* Store old algorithm parameters for later restoration */
354 nsteps = LALInferenceGetINT4Variable(algorithm_params, "nsteps");
355 update_interval = LALInferenceGetINT4Variable(algorithm_params, "update_interval");
356
357 /* Sample prior for two update intervals */
358 nprior_steps = 2 * update_interval - 1;
359 LALInferenceSetVariable(algorithm_params, "nsteps", &nprior_steps);
360
361 /* Use the "null" likelihood function in order to sample the prior */
363
364 /* Run the sampler to completion */
365 run_state->algorithm(run_state);
366
367 /* Restore algorithm parameters and likelihood function */
368 LALInferenceSetVariable(algorithm_params, "nsteps", &nsteps);
370
371 return XLAL_SUCCESS;
372}
373
374int main(int argc, char *argv[]){
375 INT4 mpi_rank;
376 ProcessParamsTable *proc_params;
377 LALInferenceRunState *run_state = NULL;
379
380 /* Initialize MPI parallelization */
381 MPI_Init(&argc, &argv);
382 MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
383
384 if (mpi_rank == 0)
385 printf(" ========== lalinference_kombine ==========\n");
386
387 /* Read command line and parse */
388 proc_params = LALInferenceParseCommandLine(argc, argv);
389
390 /* Initialise run_state based on command line. This includes allocating
391 * memory, reading data, and performing any injections specified. */
392 run_state = LALInferenceInitRunState(proc_params);
393
394 /* Build the ensemble based on command line args */
395 init_ensemble(run_state);
396
397 if (run_state == NULL) {
398 if (!LALInferenceGetProcParamVal(proc_params, "--help")) {
399 fprintf(stderr, "run_state not allocated (%s, line %d).\n",
400 __FILE__, __LINE__);
401 }
402 } else {
403 data = run_state->data;
404 }
405
406 /* Perform injections if data successful read or created */
407 if (run_state)
409
410 /* Simulate calibration errors.
411 * NOTE: this must be called after both ReadData and (if relevant)
412 * injectInspiralTD/FD are called! */
414
415 /* Choose the prior */
416 LALInferenceInitCBCPrior(run_state);
417
418 /* Choose the likelihood */
420
421 /* If just asking for --help, stop here */
422 if (LALInferenceGetProcParamVal(proc_params, "--help")) {
423 return XLAL_SUCCESS;
424 }
425
426 if (run_state == NULL)
427 return XLAL_FAILURE;
428
429 /* Setup the initial state of the walkers */
430 on_your_marks(run_state);
431
432 /* Run the sampler to completion */
433 run_state->algorithm(run_state);
434
435 if (mpi_rank == 0)
436 printf(" ========== sampling complete ==========\n");
437
438 /* Close down MPI parallelization and return */
439 MPI_Finalize();
440
441 return XLAL_SUCCESS;
442}
ProcessParamsTable * LALInferenceParseCommandLine(int argc, char *argv[])
void LALInferenceApplyCalibrationErrors(LALInferenceIFOData *IFOdata, ProcessParamsTable *commandLine)
LALInferenceRunState * LALInferenceInitRunState(ProcessParamsTable *command_line)
void LALInferenceInitCBCThreads(LALInferenceRunState *run_state, INT4 nthreads)
void LALInferenceDrawThreads(LALInferenceRunState *run_state)
int main(int argc, char *argv[])
INT4 on_your_marks(LALInferenceRunState *run_state)
INT4 sample_prior(LALInferenceRunState *run_state)
INT4 init_ensemble(LALInferenceRunState *run_state)
INT4 init_mpi_randomstate(LALInferenceRunState *run_state)
void ensemble_sampler(struct tagLALInferenceRunState *run_state)
Ensemble Markov-Chain Monte Carlo sampler written for LALInference.
REAL8 LALInferenceZeroLogLikelihood(LALInferenceVariables *currentParams, LALInferenceIFOData UNUSED *data, LALInferenceModel UNUSED *model)
For testing purposes (for instance sampling the prior), likelihood that returns 0....
void LALInferenceInjectInspiralSignal(LALInferenceIFOData *IFOdata, ProcessParamsTable *commandLine)
ProcessParamsTable * ppt
int j
#define fprintf
sigmaKerr data[0]
double REAL8
int32_t INT4
void LALInferenceReadAsciiHeader(FILE *input, char params[][VARNAME_MAX], INT4 *nCols)
Read column names from an ASCII file.
#define VARNAME_MAX
Definition: LALInference.h:50
INT4 LALInferenceGetVariableDimensionNonFixed(LALInferenceVariables *vars)
Get number of dimensions in vars which are not fixed to a certain value.
Definition: LALInference.c:255
INT4 LALInferenceGetINT4Variable(LALInferenceVariables *vars, const char *name)
ProcessParamsTable * LALInferenceGetProcParamVal(ProcessParamsTable *procparams, const char *name)
Returns the element of the process params table with "name".
void LALInferenceAddINT4Variable(LALInferenceVariables *vars, const char *name, INT4 value, LALInferenceParamVaryType vary)
REAL8 * LALInferenceParseDelimitedAscii(FILE *input, INT4 nCols, INT4 *wantedCols, INT4 *nLines)
Utility for readling in delimited ASCII files.
void LALInferenceCopyArrayToVariables(REAL8 *origin, LALInferenceVariables *target)
void LALInferenceTranslateExternalToInternalParamName(char *outName, const char *inName)
Converts between externally used parameter names and those internal.
void LALInferenceSetVariable(LALInferenceVariables *vars, const char *name, const void *value)
Set a variable named name in vars with a value.
Definition: LALInference.c:352
int LALInferenceCheckVariableNonFixed(LALInferenceVariables *vars, const char *name)
Checks for name being present in vars and having type LINEAR or CIRCULAR.
Definition: LALInference.c:503
@ LALINFERENCE_PARAM_OUTPUT
A parameter that never changes, functions should respect this.
Definition: LALInference.h:131
void LALInferenceInitLikelihood(LALInferenceRunState *runState)
Initialisation function which reads runState->commaneLine and sets up the likelihood function accordi...
void LALInferenceInitCBCPrior(LALInferenceRunState *runState)
Initialize the prior based on command line arguments.
LALInferenceVariables * LALInferenceParseProposalArgs(LALInferenceRunState *runState)
Go through all logic for deciding proposals to use.
void * XLALCalloc(size_t m, size_t n)
void XLALFree(void *p)
XLAL_SUCCESS
XLAL_FAILURE
help
Structure to contain IFO data.
Definition: LALInference.h:625
Structure containing inference run state This includes pointers to the function types required to run...
Definition: LALInference.h:592
ProcessParamsTable * commandLine
Definition: LALInference.h:593
LALInferenceVariables * algorithmParams
Any special arguments for the prior function.
Definition: LALInference.h:604
INT4 nthreads
Array of live points for Nested Sampling.
Definition: LALInference.h:606
struct tagLALInferenceIFOData * data
Log sample, i.e.
Definition: LALInference.h:601
LALInferenceThreadState * threads
Definition: LALInference.h:612
LALInferenceAlgorithm algorithm
A function that returns a new set of variables for the model.
Definition: LALInference.h:595
LALInferenceLikelihoodFunction likelihood
MultiNest prior for the parameters.
Definition: LALInference.h:599
Structure containing chain-specific variables.
Definition: LALInference.h:541
LALInferenceVariables * currentParams
Prior boundaries, etc.
Definition: LALInference.h:556
LALInferenceModel * model
Cycle of proposals to call.
Definition: LALInference.h:548
LALInferenceVariables * proposalArgs
Definition: LALInference.h:551
The LALInferenceVariableItem list node structure This should only be accessed using the accessor func...
Definition: LALInference.h:154
char name[VARNAME_MAX]
Definition: LALInference.h:155
struct tagVariableItem * next
Definition: LALInference.h:159
The LALInferenceVariables structure to contain a set of parameters Implemented as a linked list of LA...
Definition: LALInference.h:170
LALInferenceVariableItem * head
Definition: LALInference.h:171
CHAR value[LIGOMETA_VALUE_MAX]