#! /usr/bin/env isis-script % -*- mode: SLang; mode: fold -*- % cl_slave: Slave program for parallel computation of single-parameter % confidence limits in ISIS, using PVM, as described in % "Using the Parallel Virtual Machine for Everyday Analysis," % by Noble et al 2006 (http://arxiv.org/abs/astro-ph/0510688) % % Authors: John C. Houck % Michael S. Noble % % Version: 0.3.0 (Fri Oct 3 11:53:50 EDT 2008) require ("pvm_ms"); require ("pvm_msgid"); pvm_sigterm_enable (1); variable Sub_Dir; variable Level = 1; variable Tolerance = 10^-3; define exit_slave (status) %{{{ { pvm_ms_slave_exit (status); exit (status); } %}}} define initialize (argc, argv) %{{{ { if (argc < 3) { usage ("cl_slave param_name subdir [conf_level] [tolerance]"); exit_slave (1); } variable conf_info = struct { name, value, lo, hi, hostname, params, statistic }; conf_info.name = argv[1]; conf_info.hostname = uname().nodename; Sub_Dir = argv[2]; if (argc > 3) Level = integer(argv[3]); if (argc > 4) Tolerance = eval(argv[4]); % eval(10^-3) better than atof(10^-3) return conf_info; } %}}} variable Conf_Info = initialize (__argc, __argv); define load_file (file) %{{{ { ERROR_BLOCK { exit_slave (1); } () = evalfile (file); } %}}} if (-1 == chdir (Sub_Dir)) { vmessage ("couldnt chdir to %s", Sub_Dir); exit_slave (1); } % Look for code first in the target directory, % then in the parent directory. prepend_to_isis_load_path (path_dirname(Sub_Dir)); prepend_to_isis_load_path (Sub_Dir); % load all data files load_file ("init.sl"); variable Have_New_Params = 0; define doit (info, level, tolerance) %{{{ { (info.lo, info.hi) = conf (info.name, level, tolerance); info.value = get_par (info.name); if (Have_New_Params) return; variable parent_tid = pvm_parent (); if (info.lo == info.hi) % Found better fit { variable x; () = fit_counts(&x); info.statistic = x.statistic; info.params = get_params(); pvm_send_obj (parent_tid, USER_SLAVE_NEWTASK, info); return; } info.params = NULL; info.statistic = NULL; pvm_send_obj (parent_tid, USER_SLAVE_RESULT, info); } %}}} public define isis_fit_improved_hook () %{{{ { % Non-blocking receive variable bufid = pvm_nrecv(pvm_parent(), USER_SLAVE_NEWTASK); if (bufid > 0) { Have_New_Params = 1; return 1; } return 0; } %}}} define slave_next_task (); define slave_next_task () %{{{ { variable parent_tid, bufid, msgid; parent_tid = pvm_parent (); % Blocking receive bufid = pvm_recv (parent_tid, -1); (,msgid,) = pvm_bufinfo (bufid); switch (msgid) { case USER_SLAVE_RESULT: variable params = pvm_recv_obj (); set_params (params); return 1; } { case USER_SLAVE_NEWTASK: return slave_next_task (); } return 0; } %}}} define isis_main () % {{{ { variable status = 1; ERROR_BLOCK { exit_slave (status); } forever { Have_New_Params = 0; doit (Conf_Info, Level, Tolerance); if (0 == slave_next_task ()) break; } status = 0; EXECUTE_ERROR_BLOCK; } % }}}