diff --git a/doc/RTD/source/ParameterFiles/parameter_description.rst b/doc/RTD/source/ParameterFiles/parameter_description.rst index 089d3538b16e39005ee1f7f72e18cea57a1d3897..bc33c5397f426a19ed7157dc8b5a1827a4de80a2 100644 --- a/doc/RTD/source/ParameterFiles/parameter_description.rst +++ b/doc/RTD/source/ParameterFiles/parameter_description.rst @@ -774,6 +774,19 @@ the SHUFFLE filter is also applied to get higher compression rates. Note that up until HDF5 1.10.x this option is not available when using the MPI-parallel version of the i/o routines. +Users can run a program after a snapshot is dumped to disk using the following +parameters: + +* Use the extra command after snapshot creation: ``run_on_dump`` (default :``0``) +* Command to run after snapshot creation: ``dump_command`` (default: nothing) + +These are particularly useful should you wish to submit a job for postprocessing +the snapshot after it has just been created. Your script will be invoked with +two parameters, the snapshot base-name, and the snapshot number that was just +output as a zero-padded integer. For example, if the base-name is "eagle" and +snapshot 7 was just dumped, with ``dump_command`` set to ``./postprocess.sh``, +then SWIFT will run ``./postprocess.sh eagle 0007``. + Finally, it is possible to specify a different system of units for the snapshots than the one that was used internally by SWIFT. The format is identical to the one described above (See the :ref:`Parameters_units` section) and read: diff --git a/examples/parameter_example.yml b/examples/parameter_example.yml index 6a881d5a4409ffe64542c540a90116f8b62c7390..d89758b4af0a0456f324b0fc682609cb47f8a839 100644 --- a/examples/parameter_example.yml +++ b/examples/parameter_example.yml @@ -156,6 +156,9 @@ Snapshots: output_list: snaplist.txt # (Optional) File containing the output times (see documentation in "Parameter File" section) select_output_on: 0 # (Optional) Enable the output selection behaviour select_output: selectoutput.yml # (Optional) File containing information to select outputs with (see documentation in the "Output Selection" section) + run_on_dump: 0 # (Optional) Run the dump_command each time that a snapshot is dumped? + dump_command: ./submit_velociraptor.sh # (Optional) Command to run each time that a snapshot is dumped. + # Parameters governing the logger snapshot system Logger: diff --git a/src/engine.c b/src/engine.c index e9662b226766a11ae5e3cea032f34b18fec59302..d0de2005b58101a1cbd5200b2f4f277b330d70a1 100644 --- a/src/engine.c +++ b/src/engine.c @@ -2711,6 +2711,12 @@ void engine_init(struct engine *e, struct space *s, struct swift_params *params, parser_get_param_string(params, "Snapshots:basename", e->snapshot_base_name); parser_get_opt_param_string(params, "Snapshots:subdir", e->snapshot_subdir, engine_default_snapshot_subdir); + e->snapshot_run_on_dump = + parser_get_opt_param_int(params, "Snapshots:run_on_dump", 0); + if (e->snapshot_run_on_dump) { + parser_get_param_string(params, "Snapshots:dump_command", + e->snapshot_dump_command); + } e->snapshot_compression = parser_get_opt_param_int(params, "Snapshots:compression", 0); e->snapshot_distributed = diff --git a/src/engine.h b/src/engine.h index a4a5bcf160937fe1bb0e60ee360e62c36af8fada..ef3a0ece8d2e8324ec48adf36a1dd445304fd7c8 100644 --- a/src/engine.h +++ b/src/engine.h @@ -311,6 +311,8 @@ struct engine { char snapshot_base_name[PARSER_MAX_LINE_SIZE]; char snapshot_subdir[PARSER_MAX_LINE_SIZE]; + char snapshot_dump_command[PARSER_MAX_LINE_SIZE]; + int snapshot_run_on_dump; int snapshot_distributed; int snapshot_compression; int snapshot_int_time_label_on; @@ -565,6 +567,7 @@ void engine_check_for_dumps(struct engine *e); void engine_check_for_index_dump(struct engine *e); void engine_collect_end_of_step(struct engine *e, int apply); void engine_dump_snapshot(struct engine *e); +void engine_run_on_dump(struct engine *e); void engine_init_output_lists(struct engine *e, struct swift_params *params); void engine_init(struct engine *e, struct space *s, struct swift_params *params, struct output_options *output_options, long long Ngas, diff --git a/src/engine_io.c b/src/engine_io.c index 0355c69c9d10ffc84a405e5d6ea36fdd0ae14c88..58a05e0f668bf28d5e48595c08764eb2e8fac7d4 100644 --- a/src/engine_io.c +++ b/src/engine_io.c @@ -39,6 +39,8 @@ #include "serial_io.h" #include "single_io.h" +#include <stdio.h> + /** * @brief Check whether an index file has to be written during this * step. @@ -214,6 +216,34 @@ void engine_dump_snapshot(struct engine *e) { if (e->verbose) message("writing particle properties took %.3f %s.", (float)clocks_diff(&time1, &time2), clocks_getunit()); + + /* Run the post-dump command if required */ + engine_run_on_dump(e); +} + +/** + * @brief Runs the snapshot_dump_command if relevant. Note that we + * perform no error checking on this command, and assume + * it works fine. + * + * @param e The #engine. + */ +void engine_run_on_dump(struct engine *e) { + if (e->snapshot_run_on_dump) { + /* Generate a string containing (optionally) the snapshot number. + * Note that -1 is used because snapshot_output_count was just + * increased when the write_output_* functions are called. */ + const int buf_size = PARSER_MAX_LINE_SIZE * 3; + char dump_command_buf[buf_size]; + snprintf(dump_command_buf, buf_size, "%s %s %04d", e->snapshot_dump_command, + e->snapshot_base_name, e->snapshot_output_count - 1); + + /* Let's trust the user's command... */ + const int result = system(dump_command_buf); + if (result != 0) { + message("Snapshot dump command returned error code %d", result); + } + } } /** diff --git a/src/restart.c b/src/restart.c index 63d1bee0345cb378f098218fdcd0e061bdc33bf9..9e913240ba5af3d3f415c5d449b362574391f510 100644 --- a/src/restart.c +++ b/src/restart.c @@ -358,5 +358,7 @@ void restart_resubmit(const char *command) { /* Let's trust the user's command... */ const int result = system(command); - if (result != 0) message("Command returned error code %d", result); + if (result != 0) { + message("Restart resubmit command returned error code %d", result); + } }