diff options
author | Thomas White <taw@physics.org> | 2021-02-18 11:22:13 +0100 |
---|---|---|
committer | Thomas White <taw@physics.org> | 2021-02-18 11:22:13 +0100 |
commit | a9584e4fd46cad8bb88d31629e9b9a31ce8e46f8 (patch) | |
tree | ec8f77cc157f7e79ae6f70db97196425f0b20ddb | |
parent | 240f9e7311497c15386d0b62242f6747a24ac7bc (diff) |
SLURM: Submit merging and ambigator jobs via script
-rw-r--r-- | src/gui_ambi.c | 2 | ||||
-rw-r--r-- | src/gui_backend_slurm.c | 204 | ||||
-rw-r--r-- | src/gui_merge.c | 183 | ||||
-rw-r--r-- | src/gui_merge.h | 4 |
4 files changed, 151 insertions, 242 deletions
diff --git a/src/gui_ambi.c b/src/gui_ambi.c index 9050eb5c..d29ce6b0 100644 --- a/src/gui_ambi.c +++ b/src/gui_ambi.c @@ -476,6 +476,8 @@ int write_ambigator_script(const char *filename, fh = fopen(filename, "w"); if ( fh == NULL ) return 1; + fprintf(fh, "#!/bin/sh\n"); + fprintf(fh, "cat \\\n"); for ( i=0; i<input->n_streams; i++ ) { fprintf(fh, "%s \\\n", input->streams[i]); diff --git a/src/gui_backend_slurm.c b/src/gui_backend_slurm.c index c8572d5d..c75d6ab8 100644 --- a/src/gui_backend_slurm.c +++ b/src/gui_backend_slurm.c @@ -318,6 +318,73 @@ static uint32_t submit_batch_job(const char *geom_filename, } +/* For submitting a single script to the SLURM cluster. + * Used for merging and ambigator, but not for indexing - that needs something + * more sophisticated. */ +static struct slurm_job *start_slurm_job(enum slurm_job_type type, + const char *script_filename, + const char *jobname, + const char *workdir, + const char *partition, + const char *email_address) +{ + char **env; + int n_env; + char *script; + struct slurm_job *job; + job_desc_msg_t job_desc_msg; + submit_response_msg_t *resp; + int r; + + script = load_entire_file(script_filename); + if ( script == NULL ) return NULL; + + job = malloc(sizeof(struct slurm_job)); + if ( job == NULL ) return NULL; + + job->type = type; + + env = create_env(&n_env, NULL); + + slurm_init_job_desc_msg(&job_desc_msg); + job_desc_msg.user_id = getuid(); + job_desc_msg.group_id = getgid(); + job_desc_msg.mail_user = safe_strdup(email_address); + job_desc_msg.mail_type = MAIL_JOB_FAIL; + job_desc_msg.comment = "Submitted via CrystFEL GUI"; + job_desc_msg.shared = 0; + job_desc_msg.time_limit = 60; + job_desc_msg.partition = safe_strdup(partition); + job_desc_msg.min_nodes = 1; + job_desc_msg.max_nodes = 1; + job_desc_msg.name = safe_strdup(jobname); + job_desc_msg.std_err = strdup("stderr.log"); + job_desc_msg.std_out = strdup("stdout.log"); + job_desc_msg.work_dir = strdup(workdir); + job_desc_msg.script = script; + job_desc_msg.environment = env; + job_desc_msg.env_size = n_env; + + r = slurm_submit_batch_job(&job_desc_msg, &resp); + if ( r ) { + ERROR("Couldn't submit job: %i\n", errno); + return NULL; + } + + free(job_desc_msg.mail_user); + free(job_desc_msg.partition); + free(job_desc_msg.name); + free(job_desc_msg.work_dir); + free(job_desc_msg.std_err); + free(job_desc_msg.std_out); + + job->job_id = resp->job_id; + slurm_free_submit_response_response_msg(resp); + + return job; +} + + static void write_partial_file_list(GFile *workdir, const char *list_filename, int j, @@ -694,7 +761,49 @@ static void *run_ambi(const char *job_title, struct gui_indexing_result *input, void *opts_priv) { - return NULL; + struct slurm_job *job; + struct slurm_ambi_opts *opts = opts_priv; + GFile *workdir; + GFile *sc_gfile; + char *sc_filename; + GFile *stream_gfile; + char *stream_str; + + workdir = make_job_folder(job_title, job_notes); + if ( workdir == NULL ) return NULL; + + stream_gfile = g_file_get_child(workdir, "ambi.stream"); + stream_str = g_file_get_path(stream_gfile); + g_object_unref(stream_gfile); + + sc_gfile = g_file_get_child(workdir, "run_ambigator.sh"); + sc_filename = g_file_get_path(sc_gfile); + g_object_unref(sc_gfile); + if ( sc_filename == NULL ) return NULL; + + if ( !write_merge_script(sc_filename, input, "`nproc`", + &proj->merging_params, "crystfel.hkl") ) + { + char *workdir_str = g_file_get_path(workdir); + job = start_slurm_job(SLURM_JOB_AMBIGATOR, + sc_filename, job_title, workdir_str, + opts->partition, opts->email_address); + g_free(workdir_str); + } else { + job = NULL; + } + g_free(sc_filename); + + if ( job != NULL ) { + char **streams = malloc(sizeof(char *)); + if ( streams != NULL ) { + streams[0] = stream_str; + add_indexing_result(proj, strdup(job_title), streams, 1); + } + } + + g_object_unref(workdir); + return job; } @@ -705,74 +814,55 @@ static void *run_merging(const char *job_title, void *opts_priv) { struct slurm_job *job; - job_desc_msg_t job_desc_msg; - submit_response_msg_t *resp; - char **cmdline; - char *cmdline_all; - char *script; - char **env; - int n_env; struct slurm_merging_opts *opts = opts_priv; - GFile *workdir_gfile; - int r; + GFile *workdir; + GFile *sc_gfile; + char *sc_filename; - workdir_gfile = make_job_folder(job_title, job_notes); - if ( workdir_gfile == NULL ) return NULL; + workdir = make_job_folder(job_title, job_notes); + if ( workdir == NULL ) return NULL; - job = malloc(sizeof(struct slurm_job)); - if ( job == NULL ) return NULL; + sc_gfile = g_file_get_child(workdir, "run_merge.sh"); + sc_filename = g_file_get_path(sc_gfile); + g_object_unref(sc_gfile); + if ( sc_filename == NULL ) return NULL; - cmdline = merging_command_line("`nproc`", - input, - &proj->merging_params); + if ( !write_merge_script(sc_filename, input, "`nproc`", + &proj->merging_params, "crystfel.hkl") ) + { + char *workdir_str = g_file_get_path(workdir); + job = start_slurm_job(SLURM_JOB_MERGING, + sc_filename, job_title, workdir_str, + opts->partition, opts->email_address); + g_free(workdir_str); + } else { + job = NULL; + } + g_free(sc_filename); - cmdline_all = g_strjoinv(" ", cmdline); + if ( job != NULL ) { - script = malloc(strlen(cmdline_all)+16); - if ( script == NULL ) return 0; + GFile *hkl_gfile; + char *hkl; + char *hkl1; + char *hkl2; - strcpy(script, "#!/bin/sh\n"); - strcat(script, cmdline_all); - g_free(cmdline_all); + hkl_gfile = g_file_get_child(workdir, "crystfel.hkl"); + hkl = g_file_get_path(hkl_gfile); + g_object_unref(hkl_gfile); - env = create_env(&n_env, NULL); + hkl_gfile = g_file_get_child(workdir, "crystfel.hkl1"); + hkl1 = g_file_get_path(hkl_gfile); + g_object_unref(hkl_gfile); - slurm_init_job_desc_msg(&job_desc_msg); - job_desc_msg.user_id = getuid(); - job_desc_msg.group_id = getgid(); - job_desc_msg.mail_user = safe_strdup(opts->email_address); - job_desc_msg.mail_type = MAIL_JOB_FAIL; - job_desc_msg.comment = "Submitted via CrystFEL GUI"; - job_desc_msg.shared = 0; - job_desc_msg.time_limit = 60; - job_desc_msg.partition = safe_strdup(opts->partition); - job_desc_msg.min_nodes = 1; - job_desc_msg.max_nodes = 1; - job_desc_msg.name = safe_strdup(job_title); - job_desc_msg.std_err = strdup("stderr.log"); - job_desc_msg.std_out = strdup("stdout.log"); - job_desc_msg.work_dir = g_file_get_path(workdir_gfile); - job_desc_msg.script = script; - job_desc_msg.environment = env; - job_desc_msg.env_size = n_env; + hkl_gfile = g_file_get_child(workdir, "crystfel.hkl2"); + hkl2 = g_file_get_path(hkl_gfile); + g_object_unref(hkl_gfile); - r = slurm_submit_batch_job(&job_desc_msg, &resp); - if ( r ) { - ERROR("Couldn't submit job: %i\n", errno); - return 0; + add_merge_result(proj, strdup(job_title), hkl, hkl1, hkl2); } - free(job_desc_msg.mail_user); - free(job_desc_msg.partition); - free(job_desc_msg.name); - free(job_desc_msg.work_dir); - free(job_desc_msg.std_err); - free(job_desc_msg.std_out); - - job->job_id = resp->job_id; - job->type = SLURM_JOB_MERGING; - slurm_free_submit_response_response_msg(resp); - + g_object_unref(workdir); return job; } diff --git a/src/gui_merge.c b/src/gui_merge.c index 11d48117..d561c2da 100644 --- a/src/gui_merge.c +++ b/src/gui_merge.c @@ -343,187 +343,6 @@ gint merge_sig(GtkWidget *widget, struct crystfelproject *proj) } -static GSList *append_arg_str(GSList *args, - const char *label, - const char *val) -{ - size_t len; - char *str; - - len = strlen(label)+strlen(val)+4; - str = malloc(len); - if ( str == NULL ) return args; - snprintf(str, 63, "--%s=%s", label, val); - - return g_slist_append(args, str); -} - - -static GSList *append_arg_int(GSList *args, - const char *label, - int val) -{ - char *str = malloc(64); - if ( str == NULL ) return args; - snprintf(str, 63, "--%s=%i", label, val); - return g_slist_append(args, str); -} - - -static GSList *append_arg_float(GSList *args, - const char *label, - float val) -{ - char *str = malloc(64); - if ( str == NULL ) return args; - snprintf(str, 63, "--%s=%f", label, val); - return g_slist_append(args, str); -} - - -static GSList *process_hkl_command_line(struct gui_indexing_result *input, - struct merging_params *params) -{ - GSList *args = NULL; - char *exe_path; - int i; - - exe_path = get_crystfel_exe("process_hkl"); - if ( exe_path == NULL ) return NULL; - args = g_slist_append(args, exe_path); - - for ( i=0; i<input->n_streams; i++ ) { - args = g_slist_append(args, input->streams[i]); - } - - args = g_slist_append(args, "-o"); - args = g_slist_append(args, "crystfel.hkl"); - - args = append_arg_str(args, "symmetry", params->symmetry); - - if ( params->scale ) { - args = g_slist_append(args, strdup("--scale")); - } - - args = append_arg_str(args, "polarisation", - params->polarisation); - - args = append_arg_int(args, "min-measurements", - params->min_measurements); - - args = append_arg_float(args, "max-adu", params->max_adu); - - args = append_arg_float(args, "min-res", params->min_res); - - args = append_arg_float(args, "push-res", params->push_res); - - return args; -} - - -static GSList *partialator_command_line(const char *n_thread_str, - struct gui_indexing_result *input, - struct merging_params *params) -{ - GSList *args = NULL; - char *exe_path; - int i; - - exe_path = get_crystfel_exe("partialator"); - if ( exe_path == NULL ) return NULL; - args = g_slist_append(args, exe_path); - - for ( i=0; i<input->n_streams; i++ ) { - args = g_slist_append(args, input->streams[i]); - } - - args = g_slist_append(args, "-o"); - args = g_slist_append(args, "crystfel.hkl"); - - args = append_arg_str(args, "symmetry", params->symmetry); - - args = g_slist_append(args, "-j"); - args = g_slist_append(args, strdup(n_thread_str)); - - if ( params->twin_sym != NULL ) { - args = g_slist_append(args, "-w"); - args = g_slist_append(args, strdup(params->twin_sym)); - } - - if ( params->custom_split != NULL ) { - args = append_arg_str(args, "custom-split", - params->custom_split); - } - - if ( !params->scale ) { - args = g_slist_append(args, "--no-scale"); - } - - if ( !params->bscale ) { - args = g_slist_append(args, "--no-bscale"); - } - - if ( !params->postref ) { - args = g_slist_append(args, "--no-pr"); - } - - if ( !params->deltacchalf ) { - args = g_slist_append(args, "--no-deltacchalf"); - } - - args = append_arg_int(args, "iterations", params->niter); - - args = append_arg_str(args, "polarisation", - params->polarisation); - - args = append_arg_int(args, "min-measurements", - params->min_measurements); - - args = append_arg_float(args, "max-adu", params->max_adu); - - args = append_arg_float(args, "min-res", params->min_res); - - args = append_arg_float(args, "push-res", params->push_res); - - return args; -} - - -char **merging_command_line(const char *n_thread_str, - struct gui_indexing_result *input, - struct merging_params *params) -{ - GSList *args; - char **arg_strings; - GSList *args2; - int i, n; - - if ( strcmp(params->model, "process_hkl") == 0 ) { - args = process_hkl_command_line(input, params); - } else { - args = partialator_command_line(n_thread_str, - input, - params); - } - - if ( args == NULL ) return NULL; - - n = g_slist_length(args); - arg_strings = malloc((n+1)*sizeof(char *)); - if ( arg_strings == NULL ) return NULL; - - args2 = args; - for ( i=0; i<n; i++ ) { - arg_strings[i] = args2->data; - args2 = args2->next; - } - arg_strings[n] = NULL; - g_slist_free(args); - - return arg_strings; -} - - static int write_partialator_script(const char *filename, struct gui_indexing_result *input, const char *n_thread_str, @@ -537,6 +356,8 @@ static int write_partialator_script(const char *filename, fh = fopen(filename, "w"); if ( fh == NULL ) return 1; + fprintf(fh, "#!/bin/sh\n"); + exe_path = get_crystfel_exe("partialator"); if ( exe_path == NULL ) return 1; fprintf(fh, "%s \\\n", exe_path); diff --git a/src/gui_merge.h b/src/gui_merge.h index 46d6dcaf..460c5fce 100644 --- a/src/gui_merge.h +++ b/src/gui_merge.h @@ -36,10 +36,6 @@ extern gint merge_sig(GtkWidget *widget, struct crystfelproject *proj); -extern char **merging_command_line(const char *n_thread_str, - struct gui_indexing_result *input, - struct merging_params *params); - extern int write_merge_script(const char *filename, struct gui_indexing_result *input, const char *n_thread_str, |