/* Convert a cpu_freq number to its equivalent string */ extern void cpu_freq_to_string(char *buf, int buf_size, uint32_t cpu_freq) { if (cpu_freq == CPU_FREQ_LOW) snprintf(buf, buf_size, "Low"); else if (cpu_freq == CPU_FREQ_MEDIUM) snprintf(buf, buf_size, "Medium"); else if (cpu_freq == CPU_FREQ_HIGHM1) snprintf(buf, buf_size, "Highm1"); else if (cpu_freq == CPU_FREQ_HIGH) snprintf(buf, buf_size, "High"); else if (cpu_freq == CPU_FREQ_CONSERVATIVE) snprintf(buf, buf_size, "Conservative"); else if (cpu_freq == CPU_FREQ_PERFORMANCE) snprintf(buf, buf_size, "Performance"); else if (cpu_freq == CPU_FREQ_POWERSAVE) snprintf(buf, buf_size, "PowerSave"); else if (cpu_freq == CPU_FREQ_USERSPACE) snprintf(buf, buf_size, "UserSpace"); else if (cpu_freq == CPU_FREQ_ONDEMAND) snprintf(buf, buf_size, "OnDemand"); else if (cpu_freq & CPU_FREQ_RANGE_FLAG) snprintf(buf, buf_size, "Unknown"); else if (fuzzy_equal(cpu_freq, NO_VAL)) { if (buf_size > 0) buf[0] = '\0'; } else convert_num_unit2((double)cpu_freq, buf, buf_size, UNIT_KILO, 1000, false); }
extern double priority_p_calc_fs_factor(long double usage_efctv, long double shares_norm) { /* This calculation is needed for sshare when ran from a * non-multifactor machine to a multifactor machine. It * doesn't do anything on regular systems, it should always * return 0 since shares_norm will always be NO_VAL. */ double priority_fs; xassert(!fuzzy_equal(usage_efctv, NO_VAL)); if ((shares_norm <= 0.0) || fuzzy_equal(shares_norm, NO_VAL)) priority_fs = 0.0; else priority_fs = pow(2.0, -(usage_efctv / shares_norm)); return priority_fs; }
static void _print_small_double( char *outbuf, int buf_size, double dub, int units) { if (fuzzy_equal(dub, NO_VAL)) return; if (dub > 1) _local_convert_num_unit((double)dub, outbuf, buf_size, units); else if (dub > 0) snprintf(outbuf, buf_size, "%.2fM", dub); else snprintf(outbuf, buf_size, "0"); }
extern double priority_p_calc_fs_factor(long double usage_efctv, long double shares_norm) { double priority_fs; xassert(!fuzzy_equal(usage_efctv, NO_VAL)); if (shares_norm > 0.0) priority_fs = pow(2.0, -(usage_efctv / shares_norm)); else priority_fs = 0.0; return priority_fs; }
/* job_ptr should already have the partition priority and such added * here before had we will be adding to it */ static double _get_fairshare_priority( struct job_record *job_ptr) { slurmdb_association_rec_t *job_assoc = (slurmdb_association_rec_t *)job_ptr->assoc_ptr; slurmdb_association_rec_t *fs_assoc = NULL; double priority_fs = 0.0; assoc_mgr_lock_t locks = { READ_LOCK, NO_LOCK, NO_LOCK, NO_LOCK, NO_LOCK }; if (!calc_fairshare) return 0; if (!job_assoc) { error("Job %u has no association. Unable to " "compute fairshare.", job_ptr->job_id); return 0; } fs_assoc = job_assoc; assoc_mgr_lock(&locks); /* Use values from parent when FairShare=SLURMDB_FS_USE_PARENT */ while ((fs_assoc->shares_raw == SLURMDB_FS_USE_PARENT) && fs_assoc->usage->parent_assoc_ptr && (fs_assoc != assoc_mgr_root_assoc)) { fs_assoc = fs_assoc->usage->parent_assoc_ptr; } if (fuzzy_equal(fs_assoc->usage->usage_efctv, NO_VAL)) priority_p_set_assoc_usage(fs_assoc); /* Priority is 0 -> 1 */ priority_fs = priority_p_calc_fs_factor( fs_assoc->usage->usage_efctv, (long double)fs_assoc->usage->shares_norm); if (priority_debug) { info("Fairshare priority of job %u for user %s in acct" " %s is 2**(-%Lf/%f) = %f", job_ptr->job_id, job_assoc->user, job_assoc->acct, fs_assoc->usage->usage_efctv, fs_assoc->usage->shares_norm, priority_fs); } assoc_mgr_unlock(&locks); return priority_fs; }
static int chk_contour_kind(cntr_struct *p_cntr, TBOOLEAN contr_isclosed) { cntr_struct *pc_tail = NULL; TBOOLEAN current_contr_isclosed; current_contr_isclosed = contr_isclosed; if (! contr_isclosed) { pc_tail = p_cntr; while (pc_tail->next) pc_tail = pc_tail->next; /* Find last point. */ /* test if first and last point are equal */ if (fuzzy_equal(pc_tail, p_cntr)) current_contr_isclosed = TRUE; } return (current_contr_isclosed); }
void print_fields(slurmdb_step_rec_t *step) { print_field_t *field = NULL; int curr_inx = 1; char outbuf[FORMAT_STRING_SIZE]; list_iterator_reset(print_fields_itr); while ((field = list_next(print_fields_itr))) { char *tmp_char = NULL; memset(&outbuf, 0, sizeof(outbuf)); switch(field->type) { case PRINT_AVECPU: tmp_char = _elapsed_time((long)step->stats.cpu_ave, 0); field->print_routine(field, tmp_char, (curr_inx == field_count)); xfree(tmp_char); break; case PRINT_ACT_CPUFREQ: convert_num_unit2((double)step->stats.act_cpufreq, outbuf, sizeof(outbuf), UNIT_KILO, NO_VAL, 1000, params.convert_flags & (~CONVERT_NUM_UNIT_EXACT)); field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_CONSUMED_ENERGY: if (!fuzzy_equal(step->stats.consumed_energy, NO_VAL)) { convert_num_unit2((double) step->stats.consumed_energy, outbuf, sizeof(outbuf), UNIT_NONE, NO_VAL, 1000, params.convert_flags & (~CONVERT_NUM_UNIT_EXACT)); } field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_CONSUMED_ENERGY_RAW: field->print_routine(field, step->stats.consumed_energy, (curr_inx == field_count)); break; case PRINT_AVEDISKREAD: _print_small_double(outbuf, sizeof(outbuf), step->stats.disk_read_ave, UNIT_MEGA); field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_AVEDISKWRITE: _print_small_double(outbuf, sizeof(outbuf), step->stats.disk_write_ave, UNIT_MEGA); field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_AVEPAGES: convert_num_unit((double)step->stats.pages_ave, outbuf, sizeof(outbuf), UNIT_KILO, NO_VAL, params.convert_flags); field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_AVERSS: convert_num_unit((double)step->stats.rss_ave, outbuf, sizeof(outbuf), UNIT_KILO, NO_VAL, params.convert_flags); field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_AVEVSIZE: convert_num_unit((double)step->stats.vsize_ave, outbuf, sizeof(outbuf), UNIT_KILO, NO_VAL, params.convert_flags); field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_JOBID: if (step->stepid == SLURM_BATCH_SCRIPT) snprintf(outbuf, sizeof(outbuf), "%u.batch", step->job_ptr->jobid); else if (step->stepid == SLURM_EXTERN_CONT) snprintf(outbuf, sizeof(outbuf), "%u.extern", step->job_ptr->jobid); else snprintf(outbuf, sizeof(outbuf), "%u.%u", step->job_ptr->jobid, step->stepid); field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_MAXDISKREAD: _print_small_double(outbuf, sizeof(outbuf), step->stats.disk_read_max, UNIT_MEGA); field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_MAXDISKREADNODE: tmp_char = find_hostname( step->stats.disk_read_max_nodeid, step->nodes); field->print_routine(field, tmp_char, (curr_inx == field_count)); xfree(tmp_char); break; case PRINT_MAXDISKREADTASK: field->print_routine(field, step->stats.disk_read_max_taskid, (curr_inx == field_count)); break; case PRINT_MAXDISKWRITE: _print_small_double(outbuf, sizeof(outbuf), step->stats.disk_write_max, UNIT_MEGA); field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_MAXDISKWRITENODE: tmp_char = find_hostname( step->stats.disk_write_max_nodeid, step->nodes); field->print_routine(field, tmp_char, (curr_inx == field_count)); xfree(tmp_char); break; case PRINT_MAXDISKWRITETASK: field->print_routine(field, step->stats.disk_write_max_taskid, (curr_inx == field_count)); break; case PRINT_MAXPAGES: convert_num_unit((double)step->stats.pages_max, outbuf, sizeof(outbuf), UNIT_KILO, NO_VAL, params.convert_flags); field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_MAXPAGESNODE: tmp_char = find_hostname( step->stats.pages_max_nodeid, step->nodes); field->print_routine(field, tmp_char, (curr_inx == field_count)); xfree(tmp_char); break; case PRINT_MAXPAGESTASK: field->print_routine(field, step->stats.pages_max_taskid, (curr_inx == field_count)); break; case PRINT_MAXRSS: convert_num_unit((double)step->stats.rss_max, outbuf, sizeof(outbuf), UNIT_KILO, NO_VAL, params.convert_flags); field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_MAXRSSNODE: tmp_char = find_hostname( step->stats.rss_max_nodeid, step->nodes); field->print_routine(field, tmp_char, (curr_inx == field_count)); xfree(tmp_char); break; case PRINT_MAXRSSTASK: field->print_routine(field, step->stats.rss_max_taskid, (curr_inx == field_count)); break; case PRINT_MAXVSIZE: convert_num_unit((double)step->stats.vsize_max, outbuf, sizeof(outbuf), UNIT_KILO, NO_VAL, params.convert_flags); field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_MAXVSIZENODE: tmp_char = find_hostname( step->stats.vsize_max_nodeid, step->nodes); field->print_routine(field, tmp_char, (curr_inx == field_count)); xfree(tmp_char); break; case PRINT_MAXVSIZETASK: field->print_routine(field, step->stats.vsize_max_taskid, (curr_inx == field_count)); break; case PRINT_MINCPU: tmp_char = _elapsed_time((long)step->stats.cpu_min, 0); field->print_routine(field, tmp_char, (curr_inx == field_count)); xfree(tmp_char); break; case PRINT_MINCPUNODE: tmp_char = find_hostname( step->stats.cpu_min_nodeid, step->nodes); field->print_routine(field, tmp_char, (curr_inx == field_count)); xfree(tmp_char); break; case PRINT_MINCPUTASK: field->print_routine(field, step->stats.cpu_min_taskid, (curr_inx == field_count)); break; case PRINT_NODELIST: field->print_routine(field, step->nodes, (curr_inx == field_count)); break; case PRINT_NTASKS: field->print_routine(field, step->ntasks, (curr_inx == field_count)); break; case PRINT_PIDS: field->print_routine(field, step->pid_str, (curr_inx == field_count)); break; case PRINT_REQ_CPUFREQ_MIN: cpu_freq_to_string(outbuf, sizeof(outbuf), step->req_cpufreq_min); field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_REQ_CPUFREQ_MAX: cpu_freq_to_string(outbuf, sizeof(outbuf), step->req_cpufreq_max); field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_REQ_CPUFREQ_GOV: cpu_freq_to_string(outbuf, sizeof(outbuf), step->req_cpufreq_gov); field->print_routine(field, outbuf, (curr_inx == field_count)); break; default: break; } curr_inx++; } printf("\n"); }
static int _setup_qos_limits(slurmdb_qos_rec_t *qos, char **cols, char **vals, char **extra, char **added_preempt, bool for_add) { if (!qos) return SLURM_ERROR; if (for_add) { /* If we are adding we should make sure we don't get old reside sitting around from a former life. */ if (!qos->description) qos->description = xstrdup(""); if (qos->flags & QOS_FLAG_NOTSET) qos->flags = 0; if (qos->grp_cpu_mins == (uint64_t)NO_VAL) qos->grp_cpu_mins = (uint64_t)INFINITE; if (qos->grp_cpu_run_mins == (uint64_t)NO_VAL) qos->grp_cpu_run_mins = (uint64_t)INFINITE; if (qos->grp_cpus == NO_VAL) qos->grp_cpus = INFINITE; if (qos->grp_jobs == NO_VAL) qos->grp_jobs = INFINITE; if (qos->grp_nodes == NO_VAL) qos->grp_nodes = INFINITE; if (qos->grp_submit_jobs == NO_VAL) qos->grp_submit_jobs = INFINITE; if (qos->grp_wall == NO_VAL) qos->grp_wall = INFINITE; if (qos->max_cpu_mins_pj == (uint64_t)NO_VAL) qos->max_cpu_mins_pj = (uint64_t)INFINITE; if (qos->grp_cpu_run_mins == (uint64_t)NO_VAL) qos->grp_cpu_run_mins = (uint64_t)INFINITE; if (qos->max_cpus_pj == NO_VAL) qos->max_cpus_pj = INFINITE; if (qos->max_jobs_pu == NO_VAL) qos->max_jobs_pu = INFINITE; if (qos->max_nodes_pj == NO_VAL) qos->max_nodes_pj = INFINITE; if (qos->max_submit_jobs_pu == NO_VAL) qos->max_submit_jobs_pu = INFINITE; if (qos->max_wall_pj == NO_VAL) qos->max_wall_pj = INFINITE; if (qos->preempt_mode == (uint16_t)NO_VAL) qos->preempt_mode = (uint16_t)INFINITE; if (fuzzy_equal(qos->usage_factor, NO_VAL)) qos->usage_factor = (double)INFINITE; if (fuzzy_equal(qos->usage_thres, NO_VAL)) qos->usage_thres = (double)INFINITE; } if (qos->description) { xstrcat(*cols, ", description"); xstrfmtcat(*vals, ", '%s'", qos->description); xstrfmtcat(*extra, ", description='%s'", qos->description); } if (!(qos->flags & QOS_FLAG_NOTSET)) { if (qos->flags & QOS_FLAG_REMOVE) { if (qos->flags) xstrfmtcat(*extra, ", flags=(flags & ~%u)", qos->flags & ~QOS_FLAG_REMOVE); } else { /* If we are only removing there is no reason to set up the cols and vals. */ if (qos->flags & QOS_FLAG_ADD) { if (qos->flags) { xstrfmtcat(*extra, ", flags=(flags | %u)", qos->flags & ~QOS_FLAG_ADD); } } else xstrfmtcat(*extra, ", flags=%u", qos->flags); xstrcat(*cols, ", flags"); xstrfmtcat(*vals, ", '%u'", qos->flags & ~QOS_FLAG_ADD); } } if (qos->grace_time == INFINITE) { xstrcat(*cols, ", grace_time"); xstrcat(*vals, ", NULL"); xstrcat(*extra, ", grace_time=NULL"); } else if ((qos->grace_time != NO_VAL) && ((int32_t)qos->grace_time >= 0)) { xstrcat(*cols, ", grace_time"); xstrfmtcat(*vals, ", %u", qos->grace_time); xstrfmtcat(*extra, ", grace_time=%u", qos->grace_time); } if (qos->grp_cpu_mins == (uint64_t)INFINITE) { xstrcat(*cols, ", grp_cpu_mins"); xstrcat(*vals, ", NULL"); xstrcat(*extra, ", grp_cpu_mins=NULL"); } else if ((qos->grp_cpu_mins != (uint64_t)NO_VAL) && ((int64_t)qos->grp_cpu_mins >= 0)) { xstrcat(*cols, ", grp_cpu_mins"); xstrfmtcat(*vals, ", %"PRIu64"", qos->grp_cpu_mins); xstrfmtcat(*extra, ", grp_cpu_mins=%"PRIu64"", qos->grp_cpu_mins); } if (qos->grp_cpu_run_mins == (uint64_t)INFINITE) { xstrcat(*cols, ", grp_cpu_run_mins"); xstrcat(*vals, ", NULL"); xstrcat(*extra, ", grp_cpu_run_mins=NULL"); } else if ((qos->grp_cpu_run_mins != (uint64_t)NO_VAL) && (int64_t)qos->grp_cpu_run_mins >= 0) { xstrcat(*cols, ", grp_cpu_run_mins"); xstrfmtcat(*vals, ", %"PRIu64"", qos->grp_cpu_run_mins); xstrfmtcat(*extra, ", grp_cpu_run_mins=%"PRIu64"", qos->grp_cpu_run_mins); } if (qos->grp_cpus == INFINITE) { xstrcat(*cols, ", grp_cpus"); xstrcat(*vals, ", NULL"); xstrcat(*extra, ", grp_cpus=NULL"); } else if ((qos->grp_cpus != NO_VAL) && ((int32_t)qos->grp_cpus >= 0)) { xstrcat(*cols, ", grp_cpus"); xstrfmtcat(*vals, ", %u", qos->grp_cpus); xstrfmtcat(*extra, ", grp_cpus=%u", qos->grp_cpus); } if (qos->grp_jobs == INFINITE) { xstrcat(*cols, ", grp_jobs"); xstrcat(*vals, ", NULL"); xstrcat(*extra, ", grp_jobs=NULL"); } else if ((qos->grp_jobs != NO_VAL) && ((int32_t)qos->grp_jobs >= 0)) { xstrcat(*cols, ", grp_jobs"); xstrfmtcat(*vals, ", %u", qos->grp_jobs); xstrfmtcat(*extra, ", grp_jobs=%u", qos->grp_jobs); } if (qos->grp_nodes == INFINITE) { xstrcat(*cols, ", grp_nodes"); xstrcat(*vals, ", NULL"); xstrcat(*extra, ", grp_nodes=NULL"); } else if ((qos->grp_nodes != NO_VAL) && ((int32_t)qos->grp_nodes >= 0)) { xstrcat(*cols, ", grp_nodes"); xstrfmtcat(*vals, ", %u", qos->grp_nodes); xstrfmtcat(*extra, ", grp_nodes=%u", qos->grp_nodes); } if (qos->grp_submit_jobs == INFINITE) { xstrcat(*cols, ", grp_submit_jobs"); xstrcat(*vals, ", NULL"); xstrcat(*extra, ", grp_submit_jobs=NULL"); } else if ((qos->grp_submit_jobs != NO_VAL) && ((int32_t)qos->grp_submit_jobs >= 0)) { xstrcat(*cols, ", grp_submit_jobs"); xstrfmtcat(*vals, ", %u", qos->grp_submit_jobs); xstrfmtcat(*extra, ", grp_submit_jobs=%u", qos->grp_submit_jobs); } if (qos->grp_wall == INFINITE) { xstrcat(*cols, ", grp_wall"); xstrcat(*vals, ", NULL"); xstrcat(*extra, ", grp_wall=NULL"); } else if ((qos->grp_wall != NO_VAL) && ((int32_t)qos->grp_wall >= 0)) { xstrcat(*cols, ", grp_wall"); xstrfmtcat(*vals, ", %u", qos->grp_wall); xstrfmtcat(*extra, ", grp_wall=%u", qos->grp_wall); } if (qos->max_cpu_mins_pj == (uint64_t)INFINITE) { xstrcat(*cols, ", max_cpu_mins_per_job"); xstrcat(*vals, ", NULL"); xstrcat(*extra, ", max_cpu_mins_per_job=NULL"); } else if ((qos->max_cpu_mins_pj != (uint64_t)NO_VAL) && ((int64_t)qos->max_cpu_mins_pj >= 0)) { xstrcat(*cols, ", max_cpu_mins_per_job"); xstrfmtcat(*vals, ", %"PRIu64"", qos->max_cpu_mins_pj); xstrfmtcat(*extra, ", max_cpu_mins_per_job=%"PRIu64"", qos->max_cpu_mins_pj); } if (qos->max_cpu_run_mins_pu == (uint64_t)INFINITE) { xstrcat(*cols, ", max_cpu_run_mins_per_user"); xstrcat(*vals, ", NULL"); xstrcat(*extra, ", max_cpu_run_mins_per_user=NULL"); } else if ((qos->max_cpu_run_mins_pu != (uint64_t)NO_VAL) && ((int64_t)qos->max_cpu_run_mins_pu >= 0)) { xstrcat(*cols, ", max_cpu_run_mins_per_user"); xstrfmtcat(*vals, ", %"PRIu64"", qos->max_cpu_run_mins_pu); xstrfmtcat(*extra, ", max_cpu_run_mins_per_user=%"PRIu64"", qos->max_cpu_run_mins_pu); } if (qos->max_cpus_pj == INFINITE) { xstrcat(*cols, ", max_cpus_per_job"); xstrcat(*vals, ", NULL"); xstrcat(*extra, ", max_cpus_per_job=NULL"); } else if ((qos->max_cpus_pj != NO_VAL) && ((int32_t)qos->max_cpus_pj >= 0)) { xstrcat(*cols, ", max_cpus_per_job"); xstrfmtcat(*vals, ", %u", qos->max_cpus_pj); xstrfmtcat(*extra, ", max_cpus_per_job=%u", qos->max_cpus_pj); } if (qos->max_jobs_pu == INFINITE) { xstrcat(*cols, ", max_jobs_per_user"); xstrcat(*vals, ", NULL"); xstrcat(*extra, ", max_jobs_per_user=NULL"); } else if ((qos->max_jobs_pu != NO_VAL) && ((int32_t)qos->max_jobs_pu >= 0)) { xstrcat(*cols, ", max_jobs_per_user"); xstrfmtcat(*vals, ", %u", qos->max_jobs_pu); xstrfmtcat(*extra, ", max_jobs_per_user=%u", qos->max_jobs_pu); } if (qos->max_nodes_pj == INFINITE) { xstrcat(*cols, ", max_nodes_per_job"); xstrcat(*vals, ", NULL"); xstrcat(*extra, ", max_nodes_per_job=NULL"); } else if ((qos->max_nodes_pj != NO_VAL) && ((int32_t)qos->max_nodes_pj >= 0)) { xstrcat(*cols, ", max_nodes_per_job"); xstrfmtcat(*vals, ", %u", qos->max_nodes_pj); xstrfmtcat(*extra, ", max_nodes_per_job=%u", qos->max_nodes_pj); } if (qos->max_submit_jobs_pu == INFINITE) { xstrcat(*cols, ", max_submit_jobs_per_user"); xstrcat(*vals, ", NULL"); xstrcat(*extra, ", max_submit_jobs_per_user=NULL"); } else if ((qos->max_submit_jobs_pu != NO_VAL) && ((int32_t)qos->max_submit_jobs_pu >= 0)) { xstrcat(*cols, ", max_submit_jobs_per_user"); xstrfmtcat(*vals, ", %u", qos->max_submit_jobs_pu); xstrfmtcat(*extra, ", max_submit_jobs_per_user=%u", qos->max_submit_jobs_pu); } if ((qos->max_wall_pj != NO_VAL) && ((int32_t)qos->max_wall_pj >= 0)) { xstrcat(*cols, ", max_wall_duration_per_job"); xstrfmtcat(*vals, ", %u", qos->max_wall_pj); xstrfmtcat(*extra, ", max_wall_duration_per_job=%u", qos->max_wall_pj); } else if (qos->max_wall_pj == INFINITE) { xstrcat(*cols, ", max_wall_duration_per_job"); xstrcat(*vals, ", NULL"); xstrcat(*extra, ", max_wall_duration_per_job=NULL"); } if (qos->preempt_list && list_count(qos->preempt_list)) { char *preempt_val = NULL; char *tmp_char = NULL, *begin_preempt = NULL; ListIterator preempt_itr = list_iterator_create(qos->preempt_list); xstrcat(*cols, ", preempt"); begin_preempt = xstrdup("preempt"); while ((tmp_char = list_next(preempt_itr))) { if (tmp_char[0] == '-') { xstrfmtcat(preempt_val, "replace(%s, ',%s', '')", begin_preempt, tmp_char+1); xfree(begin_preempt); begin_preempt = preempt_val; } else if (tmp_char[0] == '+') { xstrfmtcat(preempt_val, "concat(" "replace(%s, ',%s', ''), ',%s')", begin_preempt, tmp_char+1, tmp_char+1); if (added_preempt) xstrfmtcat(*added_preempt, ",%s", tmp_char+1); xfree(begin_preempt); begin_preempt = preempt_val; } else if (tmp_char[0]) { xstrfmtcat(preempt_val, ",%s", tmp_char); if (added_preempt) xstrfmtcat(*added_preempt, ",%s", tmp_char); } else xstrcat(preempt_val, ""); } list_iterator_destroy(preempt_itr); xfree(begin_preempt); xstrfmtcat(*vals, ", '%s'", preempt_val); xstrfmtcat(*extra, ", preempt='%s'", preempt_val); xfree(preempt_val); } if ((qos->preempt_mode != (uint16_t)NO_VAL) && ((int16_t)qos->preempt_mode >= 0)) { qos->preempt_mode &= (~PREEMPT_MODE_GANG); xstrcat(*cols, ", preempt_mode"); xstrfmtcat(*vals, ", %u", qos->preempt_mode); xstrfmtcat(*extra, ", preempt_mode=%u", qos->preempt_mode); } if (qos->priority == INFINITE) { xstrcat(*cols, ", priority"); xstrcat(*vals, ", NULL"); xstrcat(*extra, ", priority=NULL"); } else if ((qos->priority != NO_VAL) && ((int32_t)qos->priority >= 0)) { xstrcat(*cols, ", priority"); xstrfmtcat(*vals, ", %u", qos->priority); xstrfmtcat(*extra, ", priority=%u", qos->priority); } if (fuzzy_equal(qos->usage_factor, INFINITE)) { xstrcat(*cols, ", usage_factor"); xstrcat(*vals, ", 1"); xstrcat(*extra, ", usage_factor=1"); } else if (!fuzzy_equal(qos->usage_factor, NO_VAL) && (qos->usage_factor >= 0)) { xstrcat(*cols, ", usage_factor"); xstrfmtcat(*vals, ", %f", qos->usage_factor); xstrfmtcat(*extra, ", usage_factor=%f", qos->usage_factor); } if (fuzzy_equal(qos->usage_thres, INFINITE)) { xstrcat(*cols, ", usage_thres"); xstrcat(*vals, ", NULL"); xstrcat(*extra, ", usage_thres=NULL"); } else if (!fuzzy_equal(qos->usage_thres, NO_VAL) && (qos->usage_thres >= 0)) { xstrcat(*cols, ", usage_thres"); xstrfmtcat(*vals, ", %f", qos->usage_thres); xstrfmtcat(*extra, ", usage_thres=%f", qos->usage_thres); } return SLURM_SUCCESS; }
void print_fields(slurmdb_step_rec_t *step) { // print_field_t *field = NULL; // int curr_inx = 1; // char outbuf[FORMAT_STRING_SIZE]; list_iterator_reset(print_fields_itr); while ((field = list_next(print_fields_itr))) { char *tmp_char = NULL; uint64_t tmp_uint64 = NO_VAL64; memset(&outbuf, 0, sizeof(outbuf)); switch(field->type) { case PRINT_AVECPU: tmp_uint64 = slurmdb_find_tres_count_in_string( step->stats.tres_usage_in_ave, TRES_CPU); if (tmp_uint64 != NO_VAL64) { tmp_uint64 /= CPU_TIME_ADJ; tmp_char = _elapsed_time((long)tmp_uint64, 0); } field->print_routine(field, tmp_char, (curr_inx == field_count)); xfree(tmp_char); break; case PRINT_ACT_CPUFREQ: convert_num_unit2((double)step->stats.act_cpufreq, outbuf, sizeof(outbuf), UNIT_KILO, NO_VAL, 1000, params.convert_flags & (~CONVERT_NUM_UNIT_EXACT)); field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_CONSUMED_ENERGY: if (!fuzzy_equal(step->stats.consumed_energy, NO_VAL64)) { convert_num_unit2((double) step->stats.consumed_energy, outbuf, sizeof(outbuf), UNIT_NONE, NO_VAL, 1000, params.convert_flags & (~CONVERT_NUM_UNIT_EXACT)); } field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_CONSUMED_ENERGY_RAW: field->print_routine(field, step->stats.consumed_energy, (curr_inx == field_count)); break; case PRINT_AVEDISKREAD: if ((tmp_uint64 = slurmdb_find_tres_count_in_string( step->stats.tres_usage_in_ave, TRES_FS_DISK)) == INFINITE64) tmp_uint64 = NO_VAL64; if (tmp_uint64 != NO_VAL64) _print_small_double(outbuf, sizeof(outbuf), (double)tmp_uint64, UNIT_NONE); field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_AVEDISKWRITE: if ((tmp_uint64 = slurmdb_find_tres_count_in_string( step->stats.tres_usage_out_ave, TRES_FS_DISK)) == INFINITE64) tmp_uint64 = NO_VAL64; if (tmp_uint64 != NO_VAL64) _print_small_double(outbuf, sizeof(outbuf), (double)tmp_uint64, UNIT_NONE); field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_AVEPAGES: if ((tmp_uint64 = slurmdb_find_tres_count_in_string( step->stats.tres_usage_in_ave, TRES_PAGES)) == INFINITE64) tmp_uint64 = NO_VAL64; if (tmp_uint64 != NO_VAL64) convert_num_unit((double)tmp_uint64, outbuf, sizeof(outbuf), UNIT_NONE, NO_VAL, params.convert_flags); field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_AVERSS: if ((tmp_uint64 = slurmdb_find_tres_count_in_string( step->stats.tres_usage_in_ave, TRES_MEM)) == INFINITE64) tmp_uint64 = NO_VAL64; if (tmp_uint64 != NO_VAL64) convert_num_unit((double)tmp_uint64, outbuf, sizeof(outbuf), UNIT_NONE, NO_VAL, params.convert_flags); field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_AVEVSIZE: if ((tmp_uint64 = slurmdb_find_tres_count_in_string( step->stats.tres_usage_in_ave, TRES_VMEM)) == INFINITE64) tmp_uint64 = NO_VAL64; if (tmp_uint64 != NO_VAL64) convert_num_unit((double)tmp_uint64, outbuf, sizeof(outbuf), UNIT_NONE, NO_VAL, params.convert_flags); field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_JOBID: if (step->stepid == SLURM_BATCH_SCRIPT) snprintf(outbuf, sizeof(outbuf), "%u.batch", step->job_ptr->jobid); else if (step->stepid == SLURM_EXTERN_CONT) snprintf(outbuf, sizeof(outbuf), "%u.extern", step->job_ptr->jobid); else snprintf(outbuf, sizeof(outbuf), "%u.%u", step->job_ptr->jobid, step->stepid); field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_MAXDISKREAD: if ((tmp_uint64 = slurmdb_find_tres_count_in_string( step->stats.tres_usage_in_max, TRES_FS_DISK)) == INFINITE64) tmp_uint64 = NO_VAL64; if (tmp_uint64 != NO_VAL64) _print_small_double(outbuf, sizeof(outbuf), (double)tmp_uint64, UNIT_NONE); field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_MAXDISKREADNODE: tmp_char = find_hostname( slurmdb_find_tres_count_in_string( step->stats. tres_usage_in_max_nodeid, TRES_FS_DISK), step->nodes); field->print_routine(field, tmp_char, (curr_inx == field_count)); xfree(tmp_char); break; case PRINT_MAXDISKREADTASK: if ((tmp_uint64 = slurmdb_find_tres_count_in_string( step->stats. tres_usage_in_max_taskid, TRES_FS_DISK)) == INFINITE64) tmp_uint64 = NO_VAL64; field->print_routine(field, tmp_uint64, (curr_inx == field_count)); break; case PRINT_MAXDISKWRITE: if ((tmp_uint64 = slurmdb_find_tres_count_in_string( step->stats.tres_usage_out_max, TRES_FS_DISK)) == INFINITE64) tmp_uint64 = NO_VAL64; if (tmp_uint64 != NO_VAL64) _print_small_double(outbuf, sizeof(outbuf), (double)tmp_uint64, UNIT_NONE); field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_MAXDISKWRITENODE: tmp_char = find_hostname( slurmdb_find_tres_count_in_string( step->stats. tres_usage_out_max_nodeid, TRES_FS_DISK), step->nodes); field->print_routine(field, tmp_char, (curr_inx == field_count)); xfree(tmp_char); break; case PRINT_MAXDISKWRITETASK: if ((tmp_uint64 = slurmdb_find_tres_count_in_string( step->stats. tres_usage_out_max_taskid, TRES_FS_DISK)) == INFINITE64) tmp_uint64 = NO_VAL64; field->print_routine(field, tmp_uint64, (curr_inx == field_count)); break; case PRINT_MAXPAGES: if ((tmp_uint64 = slurmdb_find_tres_count_in_string( step->stats.tres_usage_in_max, TRES_PAGES)) == INFINITE64) tmp_uint64 = NO_VAL64; if (tmp_uint64 != NO_VAL64) convert_num_unit((double)tmp_uint64, outbuf, sizeof(outbuf), UNIT_NONE, NO_VAL, params.convert_flags); field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_MAXPAGESNODE: tmp_char = find_hostname( slurmdb_find_tres_count_in_string( step->stats. tres_usage_out_max_nodeid, TRES_PAGES), step->nodes); field->print_routine(field, tmp_char, (curr_inx == field_count)); xfree(tmp_char); break; case PRINT_MAXPAGESTASK: if ((tmp_uint64 = slurmdb_find_tres_count_in_string( step->stats. tres_usage_in_max_taskid, TRES_PAGES)) == INFINITE64) tmp_uint64 = NO_VAL64; field->print_routine(field, tmp_uint64, (curr_inx == field_count)); break; case PRINT_MAXRSS: if ((tmp_uint64 = slurmdb_find_tres_count_in_string( step->stats.tres_usage_in_max, TRES_MEM)) == INFINITE64) tmp_uint64 = NO_VAL64; if (tmp_uint64 != NO_VAL64) convert_num_unit((double)tmp_uint64, outbuf, sizeof(outbuf), UNIT_NONE, NO_VAL, params.convert_flags); field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_MAXRSSNODE: tmp_char = find_hostname( slurmdb_find_tres_count_in_string( step->stats. tres_usage_in_max_nodeid, TRES_MEM), step->nodes); field->print_routine(field, tmp_char, (curr_inx == field_count)); xfree(tmp_char); break; case PRINT_MAXRSSTASK: if ((tmp_uint64 = slurmdb_find_tres_count_in_string( step->stats. tres_usage_in_max_taskid, TRES_MEM)) == INFINITE64) tmp_uint64 = NO_VAL64; field->print_routine(field, tmp_uint64, (curr_inx == field_count)); break; case PRINT_MAXVSIZE: if ((tmp_uint64 = slurmdb_find_tres_count_in_string( step->stats.tres_usage_in_max, TRES_VMEM)) == INFINITE64) tmp_uint64 = NO_VAL64; if (tmp_uint64 != NO_VAL64) convert_num_unit((double)tmp_uint64, outbuf, sizeof(outbuf), UNIT_NONE, NO_VAL, params.convert_flags); field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_MAXVSIZENODE: tmp_char = find_hostname( slurmdb_find_tres_count_in_string( step->stats. tres_usage_in_max_nodeid, TRES_VMEM), step->nodes); field->print_routine(field, tmp_char, (curr_inx == field_count)); xfree(tmp_char); break; case PRINT_MAXVSIZETASK: if ((tmp_uint64 = slurmdb_find_tres_count_in_string( step->stats. tres_usage_in_max_taskid, TRES_VMEM)) == INFINITE64) tmp_uint64 = NO_VAL64; field->print_routine(field, tmp_uint64, (curr_inx == field_count)); break; case PRINT_MINCPU: if ((tmp_uint64 = slurmdb_find_tres_count_in_string( step->stats.tres_usage_in_min, TRES_CPU)) == INFINITE64) tmp_uint64 = NO_VAL64; if (tmp_uint64 != NO_VAL64) { tmp_uint64 /= CPU_TIME_ADJ; tmp_char = _elapsed_time((long)tmp_uint64, 0); } field->print_routine(field, tmp_char, (curr_inx == field_count)); xfree(tmp_char); break; case PRINT_MINCPUNODE: tmp_char = find_hostname( slurmdb_find_tres_count_in_string( step->stats. tres_usage_in_min_nodeid, TRES_CPU), step->nodes); field->print_routine(field, tmp_char, (curr_inx == field_count)); xfree(tmp_char); break; case PRINT_MINCPUTASK: if ((tmp_uint64 = slurmdb_find_tres_count_in_string( step->stats. tres_usage_in_min_taskid, TRES_CPU)) == INFINITE64) tmp_uint64 = NO_VAL64; field->print_routine(field, tmp_uint64, (curr_inx == field_count)); break; case PRINT_TRESUIA: _print_tres_field(step->stats.tres_usage_in_ave, NULL, 1); break; case PRINT_TRESUIM: _print_tres_field(step->stats.tres_usage_in_max, NULL, 1); break; case PRINT_TRESUIMN: _print_tres_field(step->stats.tres_usage_in_max_nodeid, step->nodes, 0); break; case PRINT_TRESUIMT: _print_tres_field(step->stats.tres_usage_in_max_taskid, NULL, 0); break; case PRINT_TRESUIMI: _print_tres_field(step->stats.tres_usage_in_min, NULL, 1); break; case PRINT_TRESUIMIN: _print_tres_field(step->stats.tres_usage_in_min_nodeid, step->nodes, 0); break; case PRINT_TRESUIMIT: _print_tres_field(step->stats.tres_usage_in_min_taskid, NULL, 0); break; case PRINT_TRESUIT: _print_tres_field(step->stats.tres_usage_in_tot, NULL, 1); break; case PRINT_TRESUOA: _print_tres_field(step->stats.tres_usage_out_ave, NULL, 1); break; case PRINT_TRESUOM: _print_tres_field(step->stats.tres_usage_out_max, NULL, 1); break; case PRINT_TRESUOMN: _print_tres_field(step->stats.tres_usage_out_max_nodeid, step->nodes, 0); break; case PRINT_TRESUOMT: _print_tres_field(step->stats.tres_usage_out_max_taskid, NULL, 0); break; case PRINT_TRESUOMI: _print_tres_field(step->stats.tres_usage_out_min, NULL, 1); break; case PRINT_TRESUOMIN: _print_tres_field(step->stats.tres_usage_out_min_nodeid, step->nodes, 0); break; case PRINT_TRESUOMIT: _print_tres_field(step->stats.tres_usage_out_min_taskid, NULL, 0); break; case PRINT_TRESUOT: _print_tres_field(step->stats.tres_usage_out_tot, NULL, 1); break; case PRINT_NODELIST: field->print_routine(field, step->nodes, (curr_inx == field_count)); break; case PRINT_NTASKS: field->print_routine(field, step->ntasks, (curr_inx == field_count)); break; case PRINT_PIDS: field->print_routine(field, step->pid_str, (curr_inx == field_count)); break; case PRINT_REQ_CPUFREQ_MIN: cpu_freq_to_string(outbuf, sizeof(outbuf), step->req_cpufreq_min); field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_REQ_CPUFREQ_MAX: cpu_freq_to_string(outbuf, sizeof(outbuf), step->req_cpufreq_max); field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_REQ_CPUFREQ_GOV: cpu_freq_to_string(outbuf, sizeof(outbuf), step->req_cpufreq_gov); field->print_routine(field, outbuf, (curr_inx == field_count)); break; default: break; } curr_inx++; } printf("\n"); }
void print_fields(type_t type, void *object) { if (!object) { fatal ("Job or step record is NULL"); return; } slurmdb_job_rec_t *job = (slurmdb_job_rec_t *)object; slurmdb_step_rec_t *step = (slurmdb_step_rec_t *)object; jobcomp_job_rec_t *job_comp = (jobcomp_job_rec_t *)object; print_field_t *field = NULL; int curr_inx = 1; struct passwd *pw = NULL; struct group *gr = NULL; char outbuf[FORMAT_STRING_SIZE]; bool got_stats = false; int cpu_tres_rec_count = 0; int step_cpu_tres_rec_count = 0; switch(type) { case JOB: step = NULL; if (!job->track_steps) step = (slurmdb_step_rec_t *)job->first_step_ptr; /* set this to avoid printing out info for things that don't mean anything. Like an allocation that never ran anything. */ if (!step) job->track_steps = 1; else step_cpu_tres_rec_count = slurmdb_find_tres_count_in_string( step->tres_alloc_str, TRES_CPU); if (job->stats.cpu_min != NO_VAL) got_stats = true; job_comp = NULL; cpu_tres_rec_count = slurmdb_find_tres_count_in_string( (job->tres_alloc_str && job->tres_alloc_str[0]) ? job->tres_alloc_str : job->tres_req_str, TRES_CPU); break; case JOBSTEP: job = step->job_ptr; if (step->stats.cpu_min != NO_VAL) got_stats = true; if ((step_cpu_tres_rec_count = slurmdb_find_tres_count_in_string( step->tres_alloc_str, TRES_CPU)) == INFINITE64) step_cpu_tres_rec_count = slurmdb_find_tres_count_in_string( (job->tres_alloc_str && job->tres_alloc_str[0]) ? job->tres_alloc_str : job->tres_req_str, TRES_CPU); job_comp = NULL; break; case JOBCOMP: job = NULL; step = NULL; break; default: break; } if ((uint64_t)cpu_tres_rec_count == INFINITE64) cpu_tres_rec_count = 0; if ((uint64_t)step_cpu_tres_rec_count == INFINITE64) step_cpu_tres_rec_count = 0; list_iterator_reset(print_fields_itr); while((field = list_next(print_fields_itr))) { char *tmp_char = NULL, id[FORMAT_STRING_SIZE]; int tmp_int = NO_VAL, tmp_int2 = NO_VAL; double tmp_dub = (double)NO_VAL; /* don't use NO_VAL64 unless we can confirm the values coming in are NO_VAL64 */ uint32_t tmp_uint32 = NO_VAL; uint64_t tmp_uint64 = NO_VAL64; memset(&outbuf, 0, sizeof(outbuf)); switch(field->type) { case PRINT_ALLOC_CPUS: switch(type) { case JOB: tmp_int = cpu_tres_rec_count; // we want to use the step info if (!step) break; case JOBSTEP: tmp_int = step_cpu_tres_rec_count; break; case JOBCOMP: default: tmp_int = job_comp->proc_cnt; break; } field->print_routine(field, tmp_int, (curr_inx == field_count)); break; case PRINT_ALLOC_GRES: switch(type) { case JOB: tmp_char = job->alloc_gres; break; case JOBSTEP: tmp_char = step->job_ptr->alloc_gres; break; case JOBCOMP: default: tmp_char = NULL; break; } field->print_routine(field, tmp_char, (curr_inx == field_count)); break; case PRINT_ALLOC_NODES: switch(type) { case JOB: tmp_int = job->alloc_nodes; tmp_char = job->tres_alloc_str; break; case JOBSTEP: tmp_int = step->nnodes; tmp_char = step->tres_alloc_str; break; case JOBCOMP: tmp_int = job_comp->node_cnt; break; default: break; } if (!tmp_int && tmp_char) { if ((tmp_uint64 = slurmdb_find_tres_count_in_string( tmp_char, TRES_NODE)) != INFINITE64) tmp_int = tmp_uint64; } convert_num_unit((double)tmp_int, outbuf, sizeof(outbuf), UNIT_NONE, NO_VAL, params.convert_flags); field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_ACCOUNT: switch(type) { case JOB: tmp_char = job->account; break; case JOBSTEP: tmp_char = step->job_ptr->account; break; case JOBCOMP: default: tmp_char = "n/a"; break; } field->print_routine(field, tmp_char, (curr_inx == field_count)); break; case PRINT_ACT_CPUFREQ: if (got_stats) { switch (type) { case JOB: if (!job->track_steps) tmp_dub = step->stats.act_cpufreq; break; case JOBSTEP: tmp_dub = step->stats.act_cpufreq; break; default: break; } } if (!fuzzy_equal(tmp_dub, NO_VAL)) convert_num_unit2((double)tmp_dub, outbuf, sizeof(outbuf), UNIT_KILO, params.units, 1000, params.convert_flags & (~CONVERT_NUM_UNIT_EXACT)); field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_ASSOCID: switch(type) { case JOB: tmp_int = job->associd; break; case JOBSTEP: tmp_int = step->job_ptr->associd; break; case JOBCOMP: default: tmp_int = NO_VAL; break; } field->print_routine(field, tmp_int, (curr_inx == field_count)); break; case PRINT_AVECPU: if (got_stats) { switch(type) { case JOB: if (!job->track_steps) tmp_dub = job->stats.cpu_ave; break; case JOBSTEP: tmp_dub = step->stats.cpu_ave; break; case JOBCOMP: default: break; } } if (!fuzzy_equal(tmp_dub, NO_VAL)) tmp_char = _elapsed_time((long)tmp_dub, 0); field->print_routine(field, tmp_char, (curr_inx == field_count)); xfree(tmp_char); break; case PRINT_AVEDISKREAD: if (got_stats) { switch(type) { case JOB: if (!job->track_steps) tmp_dub = job-> stats.disk_read_ave; break; case JOBSTEP: tmp_dub = step->stats.disk_read_ave; break; case JOBCOMP: default: break; } } _print_small_double(outbuf, sizeof(outbuf), tmp_dub, UNIT_MEGA); field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_AVEDISKWRITE: if (got_stats) { switch(type) { case JOB: if (!job->track_steps) tmp_dub = job-> stats.disk_write_ave; break; case JOBSTEP: tmp_dub = step->stats.disk_write_ave; break; case JOBCOMP: default: break; } } _print_small_double(outbuf, sizeof(outbuf), tmp_dub, UNIT_MEGA); field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_AVEPAGES: if (got_stats) { switch(type) { case JOB: if (!job->track_steps) tmp_dub = job->stats.pages_ave; break; case JOBSTEP: tmp_dub = step->stats.pages_ave; break; case JOBCOMP: default: break; } } if (!fuzzy_equal(tmp_dub, NO_VAL)) convert_num_unit((double)tmp_dub, outbuf, sizeof(outbuf), UNIT_KILO, params.units, params.convert_flags); field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_AVERSS: if (got_stats) { switch(type) { case JOB: if (!job->track_steps) tmp_dub = job->stats.rss_ave; break; case JOBSTEP: tmp_dub = step->stats.rss_ave; break; case JOBCOMP: default: break; } } if (!fuzzy_equal(tmp_dub, NO_VAL)) convert_num_unit((double)tmp_dub, outbuf, sizeof(outbuf), UNIT_KILO, params.units, params.convert_flags); field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_AVEVSIZE: if (got_stats) { switch(type) { case JOB: if (!job->track_steps) tmp_dub = job->stats.vsize_ave; break; case JOBSTEP: tmp_dub = step->stats.vsize_ave; break; case JOBCOMP: default: break; } } if (!fuzzy_equal(tmp_dub, NO_VAL)) convert_num_unit((double)tmp_dub, outbuf, sizeof(outbuf), UNIT_KILO, params.units, params.convert_flags); field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_BLOCKID: switch(type) { case JOB: tmp_char = job->blockid; break; case JOBSTEP: break; case JOBCOMP: tmp_char = job_comp->blockid; break; default: break; } field->print_routine(field, tmp_char, (curr_inx == field_count)); break; case PRINT_CLUSTER: switch(type) { case JOB: tmp_char = job->cluster; break; case JOBSTEP: tmp_char = step->job_ptr->cluster; break; case JOBCOMP: default: break; } field->print_routine(field, tmp_char, (curr_inx == field_count)); break; case PRINT_COMMENT: switch(type) { case JOB: tmp_char = job->derived_es; break; case JOBSTEP: case JOBCOMP: default: tmp_char = NULL; break; } field->print_routine(field, tmp_char, (curr_inx == field_count)); break; case PRINT_CONSUMED_ENERGY: if (got_stats) { switch (type) { case JOB: if (!job->track_steps) tmp_dub = step-> stats.consumed_energy; break; case JOBSTEP: tmp_dub = step->stats.consumed_energy; break; default: break; } } if (!fuzzy_equal(tmp_dub, NO_VAL)) convert_num_unit2((double)tmp_dub, outbuf, sizeof(outbuf), UNIT_NONE, params.units, 1000, params.convert_flags & (~CONVERT_NUM_UNIT_EXACT)); field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_CONSUMED_ENERGY_RAW: if (got_stats) { switch (type) { case JOB: if (!job->track_steps) tmp_dub = step-> stats.consumed_energy; break; case JOBSTEP: tmp_dub = step->stats.consumed_energy; break; default: break; } } field->print_routine(field, tmp_dub, (curr_inx == field_count)); break; case PRINT_CPU_TIME: switch(type) { case JOB: tmp_uint64 = (uint64_t)job->elapsed * (uint64_t)cpu_tres_rec_count; break; case JOBSTEP: tmp_uint64 = (uint64_t)step->elapsed * (uint64_t)step_cpu_tres_rec_count; break; case JOBCOMP: break; default: break; } field->print_routine(field, tmp_uint64, (curr_inx == field_count)); break; case PRINT_CPU_TIME_RAW: switch(type) { case JOB: tmp_uint64 = (uint64_t)job->elapsed * (uint64_t)cpu_tres_rec_count; break; case JOBSTEP: tmp_uint64 = (uint64_t)step->elapsed * (uint64_t)step_cpu_tres_rec_count; break; case JOBCOMP: break; default: break; } field->print_routine(field, tmp_uint64, (curr_inx == field_count)); break; case PRINT_DERIVED_EC: tmp_int2 = 0; switch(type) { case JOB: tmp_int = job->derived_ec; if (tmp_int == NO_VAL) tmp_int = 0; if (WIFSIGNALED(tmp_int)) tmp_int2 = WTERMSIG(tmp_int); snprintf(outbuf, sizeof(outbuf), "%d:%d", WEXITSTATUS(tmp_int), tmp_int2); break; case JOBSTEP: case JOBCOMP: default: outbuf[0] = '\0'; break; } field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_ELAPSED: switch(type) { case JOB: tmp_int = job->elapsed; break; case JOBSTEP: tmp_int = step->elapsed; break; case JOBCOMP: tmp_int = job_comp->elapsed_time; break; default: tmp_int = NO_VAL; break; } field->print_routine(field, (uint64_t)tmp_int, (curr_inx == field_count)); break; case PRINT_ELIGIBLE: switch(type) { case JOB: tmp_int = job->eligible; break; case JOBSTEP: tmp_int = step->start; break; case JOBCOMP: break; default: break; } field->print_routine(field, tmp_int, (curr_inx == field_count)); break; case PRINT_END: switch(type) { case JOB: tmp_int = job->end; break; case JOBSTEP: tmp_int = step->end; break; case JOBCOMP: tmp_int = parse_time(job_comp->end_time, 1); break; default: tmp_int = NO_VAL; break; } field->print_routine(field, tmp_int, (curr_inx == field_count)); break; case PRINT_EXITCODE: tmp_int = 0; tmp_int2 = 0; switch(type) { case JOB: tmp_int = job->exitcode; break; case JOBSTEP: tmp_int = step->exitcode; break; case JOBCOMP: default: break; } if (tmp_int != NO_VAL) { if (WIFSIGNALED(tmp_int)) tmp_int2 = WTERMSIG(tmp_int); tmp_int = WEXITSTATUS(tmp_int); if (tmp_int >= 128) tmp_int -= 128; } snprintf(outbuf, sizeof(outbuf), "%d:%d", tmp_int, tmp_int2); field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_GID: switch(type) { case JOB: tmp_int = job->gid; break; case JOBSTEP: tmp_int = NO_VAL; break; case JOBCOMP: tmp_int = job_comp->gid; break; default: tmp_int = NO_VAL; break; } field->print_routine(field, tmp_int, (curr_inx == field_count)); break; case PRINT_GROUP: switch(type) { case JOB: tmp_int = job->gid; break; case JOBSTEP: tmp_int = NO_VAL; break; case JOBCOMP: tmp_int = job_comp->gid; break; default: tmp_int = NO_VAL; break; } tmp_char = NULL; if ((gr=getgrgid(tmp_int))) tmp_char=gr->gr_name; field->print_routine(field, tmp_char, (curr_inx == field_count)); break; case PRINT_JOBID: if (type == JOBSTEP) job = step->job_ptr; if (job) { if (job->array_task_str) { _xlate_task_str(job); snprintf(id, FORMAT_STRING_SIZE, "%u_[%s]", job->array_job_id, job->array_task_str); } else if (job->array_task_id != NO_VAL) snprintf(id, FORMAT_STRING_SIZE, "%u_%u", job->array_job_id, job->array_task_id); else snprintf(id, FORMAT_STRING_SIZE, "%u", job->jobid); } switch (type) { case JOB: tmp_char = xstrdup(id); break; case JOBSTEP: if (step->stepid == SLURM_BATCH_SCRIPT) { tmp_char = xstrdup_printf( "%s.batch", id); } else if (step->stepid == SLURM_EXTERN_CONT) { tmp_char = xstrdup_printf( "%s.extern", id); } else { tmp_char = xstrdup_printf( "%s.%u", id, step->stepid); } break; case JOBCOMP: tmp_char = xstrdup_printf("%u", job_comp->jobid); break; default: break; } field->print_routine(field, tmp_char, (curr_inx == field_count)); xfree(tmp_char); break; case PRINT_JOBIDRAW: switch (type) { case JOB: tmp_char = xstrdup_printf("%u", job->jobid); break; case JOBSTEP: if (step->stepid == SLURM_BATCH_SCRIPT) { tmp_char = xstrdup_printf( "%u.batch", step->job_ptr->jobid); } else if (step->stepid == SLURM_EXTERN_CONT) { tmp_char = xstrdup_printf( "%u.extern", step->job_ptr->jobid); } else { tmp_char = xstrdup_printf( "%u.%u", step->job_ptr->jobid, step->stepid); } break; case JOBCOMP: tmp_char = xstrdup_printf("%u", job_comp->jobid); break; default: break; } field->print_routine(field, tmp_char, (curr_inx == field_count)); xfree(tmp_char); break; case PRINT_JOBNAME: switch(type) { case JOB: tmp_char = job->jobname; break; case JOBSTEP: tmp_char = step->stepname; break; case JOBCOMP: tmp_char = job_comp->jobname; break; default: tmp_char = NULL; break; } field->print_routine(field, tmp_char, (curr_inx == field_count)); break; case PRINT_LAYOUT: switch(type) { case JOB: /* below really should be step. It is not a typo */ if (!job->track_steps) tmp_char = slurm_step_layout_type_name( step->task_dist); break; case JOBSTEP: tmp_char = slurm_step_layout_type_name( step->task_dist); break; case JOBCOMP: break; default: tmp_char = NULL; break; } field->print_routine(field, tmp_char, (curr_inx == field_count)); break; case PRINT_MAXDISKREAD: if (got_stats) { switch(type) { case JOB: if (!job->track_steps) tmp_dub = job-> stats.disk_read_max; break; case JOBSTEP: tmp_dub = step->stats.disk_read_max; break; case JOBCOMP: default: break; } } _print_small_double(outbuf, sizeof(outbuf), tmp_dub, UNIT_MEGA); field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_MAXDISKREADNODE: if (got_stats) { switch(type) { case JOB: if (!job->track_steps) tmp_char = find_hostname( job->stats. disk_read_max_nodeid, job->nodes); break; case JOBSTEP: tmp_char = find_hostname( step->stats. disk_read_max_nodeid, step->nodes); break; case JOBCOMP: default: tmp_char = NULL; break; } } field->print_routine(field, tmp_char, (curr_inx == field_count)); xfree(tmp_char); break; case PRINT_MAXDISKREADTASK: if (got_stats) { switch(type) { case JOB: if (!job->track_steps) tmp_uint32 = job->stats. disk_read_max_taskid; break; case JOBSTEP: tmp_uint32 = step->stats. disk_read_max_taskid; break; case JOBCOMP: default: tmp_uint32 = NO_VAL; break; } } if (tmp_uint32 == (uint32_t)NO_VAL) tmp_uint32 = NO_VAL; field->print_routine(field, tmp_uint32, (curr_inx == field_count)); break; case PRINT_MAXDISKWRITE: if (got_stats) { switch(type) { case JOB: if (!job->track_steps) tmp_dub = job->stats. disk_write_max; break; case JOBSTEP: tmp_dub = step->stats.disk_write_max; break; case JOBCOMP: default: break; } } _print_small_double(outbuf, sizeof(outbuf), tmp_dub, UNIT_MEGA); field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_MAXDISKWRITENODE: if (got_stats) { switch(type) { case JOB: if (!job->track_steps) tmp_char = find_hostname( job->stats. disk_write_max_nodeid, job->nodes); break; case JOBSTEP: tmp_char = find_hostname( step->stats. disk_write_max_nodeid, step->nodes); break; case JOBCOMP: default: tmp_char = NULL; break; } } field->print_routine(field, tmp_char, (curr_inx == field_count)); xfree(tmp_char); break; case PRINT_MAXDISKWRITETASK: if (got_stats) { switch(type) { case JOB: if (!job->track_steps) tmp_uint32 = job->stats. disk_write_max_taskid; break; case JOBSTEP: tmp_uint32 = step->stats. disk_write_max_taskid; break; case JOBCOMP: default: tmp_uint32 = NO_VAL; break; } if (tmp_uint32 == (uint32_t)NO_VAL) tmp_uint32 = NO_VAL; } field->print_routine(field, tmp_uint32, (curr_inx == field_count)); break; case PRINT_MAXPAGES: if (got_stats) { switch(type) { case JOB: if (!job->track_steps) tmp_uint64 = job->stats.pages_max; break; case JOBSTEP: tmp_uint64 = step->stats.pages_max; break; case JOBCOMP: default: break; } if (tmp_uint64 != (uint64_t)NO_VAL64) convert_num_unit( (double)tmp_uint64, outbuf, sizeof(outbuf), UNIT_KILO, params.units, params.convert_flags); } field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_MAXPAGESNODE: if (got_stats) { switch(type) { case JOB: if (!job->track_steps) tmp_char = find_hostname( job->stats. pages_max_nodeid, job->nodes); break; case JOBSTEP: tmp_char = find_hostname( step->stats.pages_max_nodeid, step->nodes); break; case JOBCOMP: default: tmp_char = NULL; break; } } field->print_routine(field, tmp_char, (curr_inx == field_count)); xfree(tmp_char); break; case PRINT_MAXPAGESTASK: if (got_stats) { switch(type) { case JOB: if (!job->track_steps) tmp_uint32 = job->stats. pages_max_taskid; break; case JOBSTEP: tmp_uint32 = step->stats. pages_max_taskid; break; case JOBCOMP: default: tmp_uint32 = NO_VAL; break; } if (tmp_uint32 == (uint32_t)NO_VAL) tmp_uint32 = NO_VAL; } field->print_routine(field, tmp_uint32, (curr_inx == field_count)); break; case PRINT_MAXRSS: if (got_stats) { switch(type) { case JOB: if (!job->track_steps) tmp_uint64 = job->stats.rss_max; break; case JOBSTEP: tmp_uint64 = step->stats.rss_max; break; case JOBCOMP: default: break; } if (tmp_uint64 != (uint64_t)NO_VAL64) convert_num_unit( (double)tmp_uint64, outbuf, sizeof(outbuf), UNIT_KILO, params.units, params.convert_flags); } field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_MAXRSSNODE: if (got_stats) { switch(type) { case JOB: if (!job->track_steps) tmp_char = find_hostname( job->stats. rss_max_nodeid, job->nodes); break; case JOBSTEP: tmp_char = find_hostname( step->stats.rss_max_nodeid, step->nodes); break; case JOBCOMP: default: tmp_char = NULL; break; } } field->print_routine(field, tmp_char, (curr_inx == field_count)); xfree(tmp_char); break; case PRINT_MAXRSSTASK: if (got_stats) { switch(type) { case JOB: if (!job->track_steps) tmp_uint32 = job->stats. rss_max_taskid; break; case JOBSTEP: tmp_uint32 = step->stats.rss_max_taskid; break; case JOBCOMP: default: tmp_uint32 = NO_VAL; break; } if (tmp_uint32 == (uint32_t)NO_VAL) tmp_uint32 = NO_VAL; } field->print_routine(field, tmp_uint32, (curr_inx == field_count)); break; case PRINT_MAXVSIZE: if (got_stats) { switch(type) { case JOB: if (!job->track_steps) tmp_uint64 = job->stats. vsize_max; break; case JOBSTEP: tmp_uint64 = step->stats.vsize_max; break; case JOBCOMP: default: tmp_uint64 = (uint64_t)NO_VAL64; break; } if (tmp_uint64 != (uint64_t)NO_VAL64) convert_num_unit( (double)tmp_uint64, outbuf, sizeof(outbuf), UNIT_KILO, params.units, params.convert_flags); } field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_MAXVSIZENODE: if (got_stats) { switch(type) { case JOB: if (!job->track_steps) tmp_char = find_hostname( job->stats. vsize_max_nodeid, job->nodes); break; case JOBSTEP: tmp_char = find_hostname( step->stats.vsize_max_nodeid, step->nodes); break; case JOBCOMP: default: tmp_char = NULL; break; } } field->print_routine(field, tmp_char, (curr_inx == field_count)); xfree(tmp_char); break; case PRINT_MAXVSIZETASK: if (got_stats) { switch(type) { case JOB: if (!job->track_steps) tmp_uint32 = job->stats. vsize_max_taskid; break; case JOBSTEP: tmp_uint32 = step->stats. vsize_max_taskid; break; case JOBCOMP: default: tmp_uint32 = NO_VAL; break; } if (tmp_uint32 == (uint32_t)NO_VAL) tmp_uint32 = NO_VAL; } field->print_routine(field, tmp_uint32, (curr_inx == field_count)); break; case PRINT_MINCPU: if (got_stats) { switch(type) { case JOB: if (!job->track_steps) tmp_dub = job->stats.cpu_min; break; case JOBSTEP: tmp_dub = step->stats.cpu_min; break; case JOBCOMP: default: break; } if (!fuzzy_equal(tmp_dub, NO_VAL)) tmp_char = _elapsed_time( (long)tmp_dub, 0); } field->print_routine(field, tmp_char, (curr_inx == field_count)); xfree(tmp_char); break; case PRINT_MINCPUNODE: if (got_stats) { switch(type) { case JOB: if (!job->track_steps) tmp_char = find_hostname( job->stats. cpu_min_nodeid, job->nodes); break; case JOBSTEP: tmp_char = find_hostname( step->stats.cpu_min_nodeid, step->nodes); break; case JOBCOMP: default: tmp_char = NULL; break; } } field->print_routine(field, tmp_char, (curr_inx == field_count)); xfree(tmp_char); break; case PRINT_MINCPUTASK: if (got_stats) { switch(type) { case JOB: if (!job->track_steps) tmp_uint32 = job->stats. cpu_min_taskid; break; case JOBSTEP: tmp_uint32 = step->stats.cpu_min_taskid; break; case JOBCOMP: default: tmp_uint32 = NO_VAL; break; } if (tmp_uint32 == (uint32_t)NO_VAL) tmp_uint32 = NO_VAL; } field->print_routine(field, tmp_uint32, (curr_inx == field_count)); break; case PRINT_NODELIST: switch(type) { case JOB: tmp_char = job->nodes; break; case JOBSTEP: tmp_char = step->nodes; break; case JOBCOMP: tmp_char = job_comp->nodelist; break; default: break; } field->print_routine(field, tmp_char, (curr_inx == field_count)); break; case PRINT_NNODES: switch(type) { case JOB: tmp_int = job->alloc_nodes; tmp_char = (job->tres_alloc_str && job->tres_alloc_str[0]) ? job->tres_alloc_str : job->tres_req_str; break; case JOBSTEP: tmp_int = step->nnodes; tmp_char = step->tres_alloc_str; break; case JOBCOMP: tmp_int = job_comp->node_cnt; break; default: break; } if (!tmp_int && tmp_char) { if ((tmp_uint64 = slurmdb_find_tres_count_in_string( tmp_char, TRES_NODE)) != INFINITE64) tmp_int = tmp_uint64; } convert_num_unit((double)tmp_int, outbuf, sizeof(outbuf), UNIT_NONE, params.units, params.convert_flags); field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_NTASKS: switch(type) { case JOB: if (!job->track_steps && !step) tmp_int = cpu_tres_rec_count; // we want to use the step info if (!step) break; case JOBSTEP: tmp_int = step->ntasks; break; case JOBCOMP: default: break; } field->print_routine(field, tmp_int, (curr_inx == field_count)); break; case PRINT_PRIO: switch(type) { case JOB: tmp_int = job->priority; break; case JOBSTEP: break; case JOBCOMP: break; default: break; } field->print_routine(field, tmp_int, (curr_inx == field_count)); break; case PRINT_PARTITION: switch(type) { case JOB: tmp_char = job->partition; break; case JOBSTEP: break; case JOBCOMP: tmp_char = job_comp->partition; break; default: break; } field->print_routine(field, tmp_char, (curr_inx == field_count)); break; case PRINT_QOS: switch(type) { case JOB: tmp_int = job->qosid; break; case JOBSTEP: break; case JOBCOMP: break; default: break; } if (!g_qos_list) { slurmdb_qos_cond_t qos_cond; memset(&qos_cond, 0, sizeof(slurmdb_qos_cond_t)); qos_cond.with_deleted = 1; g_qos_list = slurmdb_qos_get( acct_db_conn, &qos_cond); } tmp_char = _find_qos_name_from_list(g_qos_list, tmp_int); field->print_routine(field, tmp_char, (curr_inx == field_count)); break; case PRINT_QOSRAW: switch(type) { case JOB: tmp_int = job->qosid; break; case JOBSTEP: break; case JOBCOMP: break; default: break; } field->print_routine(field, tmp_int, (curr_inx == field_count)); break; case PRINT_REQ_CPUFREQ_MIN: switch (type) { case JOB: if (!job->track_steps && !step) tmp_dub = NO_VAL; // we want to use the step info if (!step) break; case JOBSTEP: tmp_dub = step->req_cpufreq_min; break; default: break; } cpu_freq_to_string(outbuf, sizeof(outbuf), tmp_dub); field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_REQ_CPUFREQ_MAX: switch (type) { case JOB: if (!job->track_steps && !step) tmp_dub = NO_VAL; // we want to use the step info if (!step) break; case JOBSTEP: tmp_dub = step->req_cpufreq_max; break; default: break; } cpu_freq_to_string(outbuf, sizeof(outbuf), tmp_dub); field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_REQ_CPUFREQ_GOV: switch (type) { case JOB: if (!job->track_steps && !step) tmp_dub = NO_VAL; // we want to use the step info if (!step) break; case JOBSTEP: tmp_dub = step->req_cpufreq_gov; break; default: break; } cpu_freq_to_string(outbuf, sizeof(outbuf), tmp_dub); field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_REQ_CPUS: switch(type) { case JOB: tmp_int = job->req_cpus; break; case JOBSTEP: tmp_int = step_cpu_tres_rec_count; break; case JOBCOMP: break; default: break; } field->print_routine(field, tmp_int, (curr_inx == field_count)); break; case PRINT_REQ_GRES: switch(type) { case JOB: tmp_char = job->req_gres; break; case JOBSTEP: tmp_char = step->job_ptr->req_gres; break; case JOBCOMP: default: tmp_char = NULL; break; } field->print_routine(field, tmp_char, (curr_inx == field_count)); break; case PRINT_REQ_MEM: switch(type) { case JOB: tmp_uint32 = job->req_mem; break; case JOBSTEP: tmp_uint32 = step->job_ptr->req_mem; break; case JOBCOMP: default: tmp_uint32 = NO_VAL; break; } if (tmp_uint32 != (uint32_t)NO_VAL) { bool per_cpu = false; if (tmp_uint32 & MEM_PER_CPU) { tmp_uint32 &= (~MEM_PER_CPU); per_cpu = true; } convert_num_unit((double)tmp_uint32, outbuf, sizeof(outbuf), UNIT_MEGA, params.units, params.convert_flags); if (per_cpu) sprintf(outbuf+strlen(outbuf), "c"); else sprintf(outbuf+strlen(outbuf), "n"); } field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_REQ_NODES: switch(type) { case JOB: tmp_int = 0; tmp_char = job->tres_req_str; break; case JOBSTEP: tmp_int = step->nnodes; tmp_char = step->tres_alloc_str; break; case JOBCOMP: tmp_int = job_comp->node_cnt; break; default: break; } if (!tmp_int && tmp_char) { if ((tmp_uint64 = slurmdb_find_tres_count_in_string( tmp_char, TRES_NODE)) != INFINITE64) tmp_int = tmp_uint64; } convert_num_unit((double)tmp_int, outbuf, sizeof(outbuf), UNIT_NONE, params.units, params.convert_flags); field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_RESERVATION: switch(type) { case JOB: if (job->resv_name) { tmp_char = job->resv_name; } else { tmp_char = NULL; } break; case JOBSTEP: tmp_char = NULL; break; case JOBCOMP: tmp_char = NULL; break; default: tmp_char = NULL; break; } field->print_routine(field, tmp_char, (curr_inx == field_count)); break; case PRINT_RESERVATION_ID: switch(type) { case JOB: if (job->resvid) tmp_uint32 = job->resvid; else tmp_uint32 = NO_VAL; break; case JOBSTEP: tmp_uint32 = NO_VAL; break; case JOBCOMP: tmp_uint32 = NO_VAL; break; default: tmp_uint32 = NO_VAL; break; } if (tmp_uint32 == (uint32_t)NO_VAL) tmp_uint32 = NO_VAL; field->print_routine(field, tmp_uint32, (curr_inx == field_count)); break; case PRINT_RESV: switch(type) { case JOB: if (job->start) tmp_int = job->start - job->eligible; else tmp_int = time(NULL) - job->eligible; break; case JOBSTEP: break; case JOBCOMP: break; default: break; } field->print_routine(field, (uint64_t)tmp_int, (curr_inx == field_count)); break; case PRINT_RESV_CPU: switch(type) { case JOB: if (job->start) tmp_int = (job->start - job->eligible) * job->req_cpus; else tmp_int = (time(NULL) - job->eligible) * job->req_cpus; break; case JOBSTEP: break; case JOBCOMP: break; default: break; } field->print_routine(field, (uint64_t)tmp_int, (curr_inx == field_count)); break; case PRINT_RESV_CPU_RAW: switch(type) { case JOB: if (job->start) tmp_int = (job->start - job->eligible) * job->req_cpus; else tmp_int = (time(NULL) - job->eligible) * job->req_cpus; break; case JOBSTEP: break; case JOBCOMP: break; default: break; } field->print_routine(field, tmp_int, (curr_inx == field_count)); break; case PRINT_START: switch(type) { case JOB: tmp_int = job->start; break; case JOBSTEP: tmp_int = step->start; break; case JOBCOMP: tmp_int = parse_time(job_comp->start_time, 1); break; default: break; } field->print_routine(field, tmp_int, (curr_inx == field_count)); break; case PRINT_STATE: switch(type) { case JOB: tmp_int = job->state; tmp_int2 = job->requid; break; case JOBSTEP: tmp_int = step->state; tmp_int2 = step->requid; break; case JOBCOMP: tmp_char = job_comp->state; break; default: break; } if (((tmp_int & JOB_STATE_BASE) == JOB_CANCELLED) && (tmp_int2 != -1)) snprintf(outbuf, FORMAT_STRING_SIZE, "%s by %d", job_state_string(tmp_int), tmp_int2); else if (tmp_int != NO_VAL) snprintf(outbuf, FORMAT_STRING_SIZE, "%s", job_state_string(tmp_int)); else if (tmp_char) snprintf(outbuf, FORMAT_STRING_SIZE, "%s", tmp_char); field->print_routine(field, outbuf, (curr_inx == field_count)); break; case PRINT_SUBMIT: switch(type) { case JOB: tmp_int = job->submit; break; case JOBSTEP: tmp_int = step->start; break; case JOBCOMP: tmp_int = parse_time(job_comp->start_time, 1); break; default: break; } field->print_routine(field, tmp_int, (curr_inx == field_count)); break; case PRINT_SUSPENDED: switch(type) { case JOB: tmp_int = job->suspended; break; case JOBSTEP: tmp_int = step->suspended; break; case JOBCOMP: break; default: break; } field->print_routine(field, (uint64_t)tmp_int, (curr_inx == field_count)); break; case PRINT_SYSTEMCPU: if (got_stats) { switch(type) { case JOB: tmp_int = job->sys_cpu_sec; tmp_int2 = job->sys_cpu_usec; break; case JOBSTEP: tmp_int = step->sys_cpu_sec; tmp_int2 = step->sys_cpu_usec; break; case JOBCOMP: default: break; } tmp_char = _elapsed_time(tmp_int, tmp_int2); } field->print_routine(field, tmp_char, (curr_inx == field_count)); xfree(tmp_char); break; case PRINT_TIMELIMIT: switch(type) { case JOB: if (job->timelimit == INFINITE) tmp_char = "UNLIMITED"; else if (job->timelimit == NO_VAL) tmp_char = "Partition_Limit"; else if (job->timelimit) { char tmp1[128]; mins2time_str(job->timelimit, tmp1, sizeof(tmp1)); tmp_char = tmp1; } break; case JOBSTEP: break; case JOBCOMP: tmp_char = job_comp->timelimit; break; default: break; } field->print_routine(field, tmp_char, (curr_inx == field_count)); break; case PRINT_TOTALCPU: switch(type) { case JOB: tmp_int = job->tot_cpu_sec; tmp_int2 = job->tot_cpu_usec; break; case JOBSTEP: tmp_int = step->tot_cpu_sec; tmp_int2 = step->tot_cpu_usec; break; case JOBCOMP: break; default: break; } tmp_char = _elapsed_time(tmp_int, tmp_int2); field->print_routine(field, tmp_char, (curr_inx == field_count)); xfree(tmp_char); break; case PRINT_TRESA: switch(type) { case JOB: tmp_char = job->tres_alloc_str; break; case JOBSTEP: tmp_char = step->tres_alloc_str; break; case JOBCOMP: default: tmp_char = NULL; break; } if (!g_tres_list) { slurmdb_tres_cond_t tres_cond; memset(&tres_cond, 0, sizeof(slurmdb_tres_cond_t)); tres_cond.with_deleted = 1; g_tres_list = slurmdb_tres_get( acct_db_conn, &tres_cond); } tmp_char = slurmdb_make_tres_string_from_simple( tmp_char, g_tres_list, params.units, params.convert_flags); field->print_routine(field, tmp_char, (curr_inx == field_count)); xfree(tmp_char); break; case PRINT_TRESR: switch(type) { case JOB: tmp_char = job->tres_req_str; break; case JOBSTEP: case JOBCOMP: default: tmp_char = NULL; break; } if (!g_tres_list) { slurmdb_tres_cond_t tres_cond; memset(&tres_cond, 0, sizeof(slurmdb_tres_cond_t)); tres_cond.with_deleted = 1; g_tres_list = slurmdb_tres_get( acct_db_conn, &tres_cond); } tmp_char = slurmdb_make_tres_string_from_simple( tmp_char, g_tres_list, params.units, params.convert_flags); field->print_routine(field, tmp_char, (curr_inx == field_count)); xfree(tmp_char); break; case PRINT_UID: switch(type) { case JOB: if (job->user) { if ((pw=getpwnam(job->user))) tmp_int = pw->pw_uid; } else tmp_int = job->uid; break; case JOBSTEP: break; case JOBCOMP: tmp_int = job_comp->uid; break; default: break; } field->print_routine(field, tmp_int, (curr_inx == field_count)); break; case PRINT_USER: switch(type) { case JOB: if (job->user) tmp_char = job->user; else if (job->uid != -1) { if ((pw=getpwuid(job->uid))) tmp_char = pw->pw_name; } break; case JOBSTEP: break; case JOBCOMP: tmp_char = job_comp->uid_name; break; default: break; } field->print_routine(field, tmp_char, (curr_inx == field_count)); break; case PRINT_USERCPU: if (got_stats) { switch(type) { case JOB: tmp_int = job->user_cpu_sec; tmp_int2 = job->user_cpu_usec; break; case JOBSTEP: tmp_int = step->user_cpu_sec; tmp_int2 = step->user_cpu_usec; break; case JOBCOMP: default: break; } tmp_char = _elapsed_time(tmp_int, tmp_int2); } field->print_routine(field, tmp_char, (curr_inx == field_count)); xfree(tmp_char); break; case PRINT_WCKEY: switch(type) { case JOB: tmp_char = job->wckey; break; case JOBSTEP: break; case JOBCOMP: break; default: break; } field->print_routine(field, tmp_char, (curr_inx == field_count)); break; case PRINT_WCKEYID: switch(type) { case JOB: tmp_int = job->wckeyid; break; case JOBSTEP: break; case JOBCOMP: break; default: break; } field->print_routine(field, tmp_int, (curr_inx == field_count)); break; default: break; } curr_inx++; } printf("\n"); }
static int _setup_qos_limits(slurmdb_qos_rec_t *qos, char **cols, char **vals, char **extra, char **added_preempt, bool for_add) { uint32_t tres_str_flags = TRES_STR_FLAG_REMOVE | TRES_STR_FLAG_SORT_ID | TRES_STR_FLAG_SIMPLE | TRES_STR_FLAG_NO_NULL; if (!qos) return SLURM_ERROR; if (for_add) { /* If we are adding we should make sure we don't get old reside sitting around from a former life. */ if (!qos->description) qos->description = xstrdup(""); if (qos->flags & QOS_FLAG_NOTSET) qos->flags = 0; if (qos->grace_time == NO_VAL) qos->grace_time = 0; if (qos->grp_jobs == NO_VAL) qos->grp_jobs = INFINITE; if (qos->grp_submit_jobs == NO_VAL) qos->grp_submit_jobs = INFINITE; if (qos->grp_wall == NO_VAL) qos->grp_wall = INFINITE; if (qos->max_jobs_pa == NO_VAL) qos->max_jobs_pa = INFINITE; if (qos->max_jobs_pu == NO_VAL) qos->max_jobs_pu = INFINITE; if (qos->max_submit_jobs_pa == NO_VAL) qos->max_submit_jobs_pa = INFINITE; if (qos->max_submit_jobs_pu == NO_VAL) qos->max_submit_jobs_pu = INFINITE; if (qos->max_wall_pj == NO_VAL) qos->max_wall_pj = INFINITE; if (qos->preempt_mode == (uint16_t)NO_VAL) qos->preempt_mode = 0; if (qos->priority == NO_VAL) qos->priority = 0; if (fuzzy_equal(qos->usage_factor, NO_VAL)) qos->usage_factor = 1; if (fuzzy_equal(qos->usage_thres, NO_VAL)) qos->usage_thres = (double)INFINITE; } if (qos->description) { xstrcat(*cols, ", description"); xstrfmtcat(*vals, ", '%s'", qos->description); xstrfmtcat(*extra, ", description='%s'", qos->description); } if (!(qos->flags & QOS_FLAG_NOTSET)) { if (qos->flags & QOS_FLAG_REMOVE) { if (qos->flags) xstrfmtcat(*extra, ", flags=(flags & ~%u)", qos->flags & ~QOS_FLAG_REMOVE); } else { /* If we are only removing there is no reason to set up the cols and vals. */ if (qos->flags & QOS_FLAG_ADD) { if (qos->flags) { xstrfmtcat(*extra, ", flags=(flags | %u)", qos->flags & ~QOS_FLAG_ADD); } } else xstrfmtcat(*extra, ", flags=%u", qos->flags); xstrcat(*cols, ", flags"); xstrfmtcat(*vals, ", '%u'", qos->flags & ~QOS_FLAG_ADD); } } if (qos->grace_time == INFINITE) { xstrcat(*cols, ", grace_time"); xstrcat(*vals, ", NULL"); xstrcat(*extra, ", grace_time=NULL"); } else if ((qos->grace_time != NO_VAL) && ((int32_t)qos->grace_time >= 0)) { xstrcat(*cols, ", grace_time"); xstrfmtcat(*vals, ", %u", qos->grace_time); xstrfmtcat(*extra, ", grace_time=%u", qos->grace_time); } if (qos->grp_jobs == INFINITE) { xstrcat(*cols, ", grp_jobs"); xstrcat(*vals, ", NULL"); xstrcat(*extra, ", grp_jobs=NULL"); } else if ((qos->grp_jobs != NO_VAL) && ((int32_t)qos->grp_jobs >= 0)) { xstrcat(*cols, ", grp_jobs"); xstrfmtcat(*vals, ", %u", qos->grp_jobs); xstrfmtcat(*extra, ", grp_jobs=%u", qos->grp_jobs); } if (qos->grp_submit_jobs == INFINITE) { xstrcat(*cols, ", grp_submit_jobs"); xstrcat(*vals, ", NULL"); xstrcat(*extra, ", grp_submit_jobs=NULL"); } else if ((qos->grp_submit_jobs != NO_VAL) && ((int32_t)qos->grp_submit_jobs >= 0)) { xstrcat(*cols, ", grp_submit_jobs"); xstrfmtcat(*vals, ", %u", qos->grp_submit_jobs); xstrfmtcat(*extra, ", grp_submit_jobs=%u", qos->grp_submit_jobs); } if (qos->grp_wall == INFINITE) { xstrcat(*cols, ", grp_wall"); xstrcat(*vals, ", NULL"); xstrcat(*extra, ", grp_wall=NULL"); } else if ((qos->grp_wall != NO_VAL) && ((int32_t)qos->grp_wall >= 0)) { xstrcat(*cols, ", grp_wall"); xstrfmtcat(*vals, ", %u", qos->grp_wall); xstrfmtcat(*extra, ", grp_wall=%u", qos->grp_wall); } if (qos->max_jobs_pa == INFINITE) { xstrcat(*cols, ", max_jobs_pa"); xstrcat(*vals, ", NULL"); xstrcat(*extra, ", max_jobs_pa=NULL"); } else if ((qos->max_jobs_pa != NO_VAL) && ((int32_t)qos->max_jobs_pa >= 0)) { xstrcat(*cols, ", max_jobs_pa"); xstrfmtcat(*vals, ", %u", qos->max_jobs_pa); xstrfmtcat(*extra, ", max_jobs_pa=%u", qos->max_jobs_pa); } if (qos->max_jobs_pu == INFINITE) { xstrcat(*cols, ", max_jobs_per_user"); xstrcat(*vals, ", NULL"); xstrcat(*extra, ", max_jobs_per_user=NULL"); } else if ((qos->max_jobs_pu != NO_VAL) && ((int32_t)qos->max_jobs_pu >= 0)) { xstrcat(*cols, ", max_jobs_per_user"); xstrfmtcat(*vals, ", %u", qos->max_jobs_pu); xstrfmtcat(*extra, ", max_jobs_per_user=%u", qos->max_jobs_pu); } if (qos->max_submit_jobs_pa == INFINITE) { xstrcat(*cols, ", max_submit_jobs_pa"); xstrcat(*vals, ", NULL"); xstrcat(*extra, ", max_submit_jobs_pa=NULL"); } else if ((qos->max_submit_jobs_pa != NO_VAL) && ((int32_t)qos->max_submit_jobs_pa >= 0)) { xstrcat(*cols, ", max_submit_jobs_pa"); xstrfmtcat(*vals, ", %u", qos->max_submit_jobs_pa); xstrfmtcat(*extra, ", max_submit_jobs_pa=%u", qos->max_submit_jobs_pa); } if (qos->max_submit_jobs_pu == INFINITE) { xstrcat(*cols, ", max_submit_jobs_per_user"); xstrcat(*vals, ", NULL"); xstrcat(*extra, ", max_submit_jobs_per_user=NULL"); } else if ((qos->max_submit_jobs_pu != NO_VAL) && ((int32_t)qos->max_submit_jobs_pu >= 0)) { xstrcat(*cols, ", max_submit_jobs_per_user"); xstrfmtcat(*vals, ", %u", qos->max_submit_jobs_pu); xstrfmtcat(*extra, ", max_submit_jobs_per_user=%u", qos->max_submit_jobs_pu); } if ((qos->max_wall_pj != NO_VAL) && ((int32_t)qos->max_wall_pj >= 0)) { xstrcat(*cols, ", max_wall_duration_per_job"); xstrfmtcat(*vals, ", %u", qos->max_wall_pj); xstrfmtcat(*extra, ", max_wall_duration_per_job=%u", qos->max_wall_pj); } else if (qos->max_wall_pj == INFINITE) { xstrcat(*cols, ", max_wall_duration_per_job"); xstrcat(*vals, ", NULL"); xstrcat(*extra, ", max_wall_duration_per_job=NULL"); } if (qos->preempt_list && list_count(qos->preempt_list)) { char *preempt_val = NULL; char *tmp_char = NULL, *last_preempt = NULL; bool adding_straight = 0; ListIterator preempt_itr = list_iterator_create(qos->preempt_list); xstrcat(*cols, ", preempt"); while ((tmp_char = list_next(preempt_itr))) { if (tmp_char[0] == '-') { preempt_val = xstrdup_printf( "replace(%s, ',%s,', ',')", last_preempt ? last_preempt : "preempt", tmp_char+1); xfree(last_preempt); last_preempt = preempt_val; preempt_val = NULL; } else if (tmp_char[0] == '+') { preempt_val = xstrdup_printf( "replace(concat(replace(%s, " "',%s,', ''), ',%s,'), ',,', ',')", last_preempt ? last_preempt : "preempt", tmp_char+1, tmp_char+1); if (added_preempt) xstrfmtcat(*added_preempt, ",%s", tmp_char+1); xfree(last_preempt); last_preempt = preempt_val; preempt_val = NULL; } else if (tmp_char[0]) { xstrfmtcat(preempt_val, ",%s", tmp_char); if (added_preempt) xstrfmtcat(*added_preempt, ",%s", tmp_char); adding_straight = 1; } else xstrcat(preempt_val, ""); } list_iterator_destroy(preempt_itr); if (last_preempt) { preempt_val = last_preempt; last_preempt = NULL; } if (adding_straight) { xstrfmtcat(*vals, ", \'%s,\'", preempt_val); xstrfmtcat(*extra, ", preempt=\'%s,\'", preempt_val); } else if (preempt_val && preempt_val[0]) { xstrfmtcat(*vals, ", %s", preempt_val); xstrfmtcat(*extra, ", preempt=if(%s=',', '', %s)", preempt_val, preempt_val); } else { xstrcat(*vals, ", ''"); xstrcat(*extra, ", preempt=''"); } xfree(preempt_val); } if ((qos->preempt_mode != (uint16_t)NO_VAL) && ((int16_t)qos->preempt_mode >= 0)) { qos->preempt_mode &= (~PREEMPT_MODE_GANG); xstrcat(*cols, ", preempt_mode"); xstrfmtcat(*vals, ", %u", qos->preempt_mode); xstrfmtcat(*extra, ", preempt_mode=%u", qos->preempt_mode); } if (qos->priority == INFINITE) { xstrcat(*cols, ", priority"); xstrcat(*vals, ", NULL"); xstrcat(*extra, ", priority=NULL"); } else if ((qos->priority != NO_VAL) && ((int32_t)qos->priority >= 0)) { xstrcat(*cols, ", priority"); xstrfmtcat(*vals, ", %u", qos->priority); xstrfmtcat(*extra, ", priority=%u", qos->priority); } if (fuzzy_equal(qos->usage_factor, INFINITE)) { xstrcat(*cols, ", usage_factor"); xstrcat(*vals, ", 1"); xstrcat(*extra, ", usage_factor=1"); } else if (!fuzzy_equal(qos->usage_factor, NO_VAL) && (qos->usage_factor >= 0)) { xstrcat(*cols, ", usage_factor"); xstrfmtcat(*vals, ", %f", qos->usage_factor); xstrfmtcat(*extra, ", usage_factor=%f", qos->usage_factor); } if (fuzzy_equal(qos->usage_thres, INFINITE)) { xstrcat(*cols, ", usage_thres"); xstrcat(*vals, ", NULL"); xstrcat(*extra, ", usage_thres=NULL"); } else if (!fuzzy_equal(qos->usage_thres, NO_VAL) && (qos->usage_thres >= 0)) { xstrcat(*cols, ", usage_thres"); xstrfmtcat(*vals, ", %f", qos->usage_thres); xstrfmtcat(*extra, ", usage_thres=%f", qos->usage_thres); } /* When modifying anything below this comment it happens in * the actual function since we have to wait until we hear * about the original first. * What we do to make it known something needs to be changed * is we cat "" onto extra which will inform the caller * something needs changing. */ if (qos->grp_tres) { if (!for_add) { xstrcat(*extra, ""); goto end_modify; } xstrcat(*cols, ", grp_tres"); slurmdb_combine_tres_strings( &qos->grp_tres, NULL, tres_str_flags); xstrfmtcat(*vals, ", '%s'", qos->grp_tres); xstrfmtcat(*extra, ", grp_tres='%s'", qos->grp_tres); } if (qos->grp_tres_mins) { if (!for_add) { xstrcat(*extra, ""); goto end_modify; } xstrcat(*cols, ", grp_tres_mins"); slurmdb_combine_tres_strings( &qos->grp_tres_mins, NULL, tres_str_flags); xstrfmtcat(*vals, ", '%s'", qos->grp_tres_mins); xstrfmtcat(*extra, ", grp_tres_mins='%s'", qos->grp_tres_mins); } if (qos->grp_tres_run_mins) { if (!for_add) { xstrcat(*extra, ""); goto end_modify; } xstrcat(*cols, ", grp_tres_run_mins"); slurmdb_combine_tres_strings( &qos->grp_tres_run_mins, NULL, tres_str_flags); xstrfmtcat(*vals, ", '%s'", qos->grp_tres_run_mins); xstrfmtcat(*extra, ", grp_tres_run_mins='%s'", qos->grp_tres_run_mins); } if (qos->max_tres_pa) { if (!for_add) { xstrcat(*extra, ""); goto end_modify; } xstrcat(*cols, ", max_tres_pa"); slurmdb_combine_tres_strings( &qos->max_tres_pa, NULL, tres_str_flags); xstrfmtcat(*vals, ", '%s'", qos->max_tres_pa); xstrfmtcat(*extra, ", max_tres_pa='%s'", qos->max_tres_pa); } if (qos->max_tres_pj) { if (!for_add) { xstrcat(*extra, ""); goto end_modify; } xstrcat(*cols, ", max_tres_pj"); slurmdb_combine_tres_strings( &qos->max_tres_pj, NULL, tres_str_flags); xstrfmtcat(*vals, ", '%s'", qos->max_tres_pj); xstrfmtcat(*extra, ", max_tres_pj='%s'", qos->max_tres_pj); } if (qos->max_tres_pn) { if (!for_add) { xstrcat(*extra, ""); goto end_modify; } xstrcat(*cols, ", max_tres_pn"); slurmdb_combine_tres_strings( &qos->max_tres_pn, NULL, tres_str_flags); xstrfmtcat(*vals, ", '%s'", qos->max_tres_pn); xstrfmtcat(*extra, ", max_tres_pn='%s'", qos->max_tres_pn); } if (qos->max_tres_pu) { if (!for_add) { xstrcat(*extra, ""); goto end_modify; } xstrcat(*cols, ", max_tres_pu"); slurmdb_combine_tres_strings( &qos->max_tres_pu, NULL, tres_str_flags); xstrfmtcat(*vals, ", '%s'", qos->max_tres_pu); xstrfmtcat(*extra, ", max_tres_pu='%s'", qos->max_tres_pu); } if (qos->max_tres_mins_pj) { if (!for_add) { xstrcat(*extra, ""); goto end_modify; } xstrcat(*cols, ", max_tres_mins_pj"); slurmdb_combine_tres_strings( &qos->max_tres_mins_pj, NULL, tres_str_flags); xstrfmtcat(*vals, ", '%s'", qos->max_tres_mins_pj); xstrfmtcat(*extra, ", max_tres_mins_pj='%s'", qos->max_tres_mins_pj); } if (qos->max_tres_run_mins_pa) { if (!for_add) { xstrcat(*extra, ""); goto end_modify; } xstrcat(*cols, ", max_tres_run_mins_pa"); slurmdb_combine_tres_strings( &qos->max_tres_run_mins_pa, NULL, tres_str_flags); xstrfmtcat(*vals, ", '%s'", qos->max_tres_run_mins_pa); xstrfmtcat(*extra, ", max_tres_run_mins_pa='%s'", qos->max_tres_run_mins_pa); } if (qos->max_tres_run_mins_pu) { if (!for_add) { xstrcat(*extra, ""); goto end_modify; } xstrcat(*cols, ", max_tres_run_mins_pu"); slurmdb_combine_tres_strings( &qos->max_tres_run_mins_pu, NULL, tres_str_flags); xstrfmtcat(*vals, ", '%s'", qos->max_tres_run_mins_pu); xstrfmtcat(*extra, ", max_tres_run_mins_pu='%s'", qos->max_tres_run_mins_pu); } if (qos->min_tres_pj) { if (!for_add) { xstrcat(*extra, ""); goto end_modify; } xstrcat(*cols, ", min_tres_pj"); slurmdb_combine_tres_strings( &qos->min_tres_pj, NULL, tres_str_flags); xstrfmtcat(*vals, ", '%s'", qos->min_tres_pj); xstrfmtcat(*extra, ", min_tres_pj='%s'", qos->min_tres_pj); } end_modify: return SLURM_SUCCESS; }
/* * Generate a cubic spline curve through the points (x_i,y_i) which are * stored in the linked list p_cntr. * The spline is defined as a 2d-function s(t) = (x(t),y(t)), where the * parameter t is the length of the linear stroke. */ static void put_contour_cubic( cntr_struct *p_cntr, double xx_min, double xx_max, double yy_min, double yy_max, TBOOLEAN contr_isclosed) { int num_pts, num_intpol; double unit_x, unit_y; /* To define norm (x,y)-plane */ double *delta_t; /* Interval length t_{i+1}-t_i */ double *d2x, *d2y; /* Second derivatives x''(t_i), y''(t_i) */ cntr_struct *pc_tail; num_pts = count_contour(p_cntr); /* Number of points in contour. */ pc_tail = p_cntr; /* Find last point. */ while (pc_tail->next) pc_tail = pc_tail->next; if (contr_isclosed) { /* Test if first and last point are equal (should be) */ if (!fuzzy_equal(pc_tail, p_cntr)) { pc_tail->next = p_cntr; /* Close contour list - make it circular. */ num_pts++; } } delta_t = gp_alloc(num_pts * sizeof(double), "contour delta_t"); d2x = gp_alloc(num_pts * sizeof(double), "contour d2x"); d2y = gp_alloc(num_pts * sizeof(double), "contour d2y"); /* Width and height of the grid is used as a unit length (2d-norm) */ unit_x = xx_max - xx_min; unit_y = yy_max - yy_min; /* FIXME HBB 20010121: 'zero' should not be used as an absolute * figure to compare to data */ unit_x = (unit_x > zero ? unit_x : zero); /* should not be zero */ unit_y = (unit_y > zero ? unit_y : zero); if (num_pts > 2) { /* * Calculate second derivatives d2x[], d2y[] and interval lengths delta_t[]: */ if (!gen_cubic_spline(num_pts, p_cntr, d2x, d2y, delta_t, contr_isclosed, unit_x, unit_y)) { free(delta_t); free(d2x); free(d2y); if (contr_isclosed) pc_tail->next = NULL; /* Un-circular list */ return; } } /* If following (num_pts > 1) is TRUE then exactly 2 points in contour. */ else if (num_pts > 1) { /* set all second derivatives to zero, interval length to 1 */ d2x[0] = 0.; d2y[0] = 0.; d2x[1] = 0.; d2y[1] = 0.; delta_t[0] = 1.; } else { /* Only one point ( ?? ) - ignore it. */ free(delta_t); free(d2x); free(d2y); if (contr_isclosed) pc_tail->next = NULL; /* Un-circular list */ return; } /* Calculate "num_intpol" interpolated values */ num_intpol = 1 + (num_pts - 1) * contour_pts; /* global: contour_pts */ intp_cubic_spline(num_pts, p_cntr, d2x, d2y, delta_t, num_intpol); free(delta_t); free(d2x); free(d2y); if (contr_isclosed) pc_tail->next = NULL; /* Un-circular list */ end_crnt_cntr(); }
/* * Search the data base along a contour starts at the edge pe_start until * a boundary edge is detected or until we close the loop back to pe_start. * Returns a linked list of all the points on the contour * Also decreases num_active by the number of points on contour. */ static cntr_struct * trace_contour( edge_struct *pe_start, /* edge to start contour input */ double z_level, /* Z level of contour input */ int *num_active, /* number of active edges in/out */ TBOOLEAN contr_isclosed) /* open or closed contour line (input) */ { cntr_struct *p_cntr, *pc_tail; edge_struct *p_edge, *p_next_edge; poly_struct *p_poly, *PLastpoly = NULL; int i; p_edge = pe_start; /* first edge to start contour */ /* Generate the header of the contour - the point on pe_start. */ if (! contr_isclosed) { pe_start->is_active = FALSE; (*num_active)--; } if (p_edge->poly[0] || p_edge->poly[1]) { /* more than one point */ p_cntr = pc_tail = update_cntr_pt(pe_start, z_level); /* first point */ do { /* Find polygon to continue (Not where we came from - PLastpoly): */ if (p_edge->poly[0] == PLastpoly) p_poly = p_edge->poly[1]; else p_poly = p_edge->poly[0]; p_next_edge = NULL; /* In case of error, remains NULL. */ for (i = 0; i < 3; i++) /* Test the 3 edges of the polygon: */ if (p_poly->edge[i] != p_edge) if (p_poly->edge[i]->is_active) p_next_edge = p_poly->edge[i]; if (!p_next_edge) { /* Error exit */ pc_tail->next = NULL; free_contour(p_cntr); fprintf(stderr, "trace_contour: unexpected end of contour\n"); return NULL; } p_edge = p_next_edge; PLastpoly = p_poly; p_edge->is_active = FALSE; (*num_active)--; /* Do not allocate contour points on diagonal edges */ if (p_edge->position != DIAGONAL) { pc_tail->next = update_cntr_pt(p_edge, z_level); /* Remove nearby points */ if (fuzzy_equal(pc_tail, pc_tail->next)) { free(pc_tail->next); } else pc_tail = pc_tail->next; } } while ((p_edge != pe_start) && (p_edge->position != BOUNDARY)); pc_tail->next = NULL; /* For closed contour the first and last point should be equal */ if (pe_start == p_edge) { (p_cntr->X) = (pc_tail->X); (p_cntr->Y) = (pc_tail->Y); } } else { /* only one point, forget it */ p_cntr = NULL; } return p_cntr; }
/* * Generate a Bspline curve defined by all the points given in linked list p: * Algorithm: using deBoor algorithm * Note: if Curvekind is open contour than Open end knot vector is assumed, * else (closed contour) Float end knot vector is assumed. * It is assumed that num_of_points is at least 2, and order of Bspline is less * than num_of_points! */ static void gen_bspline_approx( cntr_struct *p_cntr, int num_of_points, int order, TBOOLEAN contr_isclosed) { int knot_index = 0, pts_count = 1; double dt, t, next_t, t_min, t_max, x, y; cntr_struct *pc_temp = p_cntr, *pc_tail = NULL; /* If the contour is Closed one we must update few things: * 1. Make the list temporary circular, so we can close the contour. * 2. Update num_of_points - increase it by "order-1" so contour will be * closed. This will evaluate order more sections to close it! */ if (contr_isclosed) { pc_tail = p_cntr; while (pc_tail->next) pc_tail = pc_tail->next; /* Find last point. */ /* test if first and last point are equal */ if (fuzzy_equal(pc_tail, p_cntr)) { /* Close contour list - make it circular. */ pc_tail->next = p_cntr->next; num_of_points += order - 1; } else { pc_tail->next = p_cntr; num_of_points += order; } } /* Find first (t_min) and last (t_max) t value to eval: */ t = t_min = fetch_knot(contr_isclosed, num_of_points, order, order); t_max = fetch_knot(contr_isclosed, num_of_points, order, num_of_points); next_t = t_min + 1.0; knot_index = order; dt = 1.0 / contour_pts; /* Number of points per one section. */ while (t < t_max) { if (t > next_t) { pc_temp = pc_temp->next; /* Next order ctrl. pt. to blend. */ knot_index++; next_t += 1.0; } eval_bspline(t, pc_temp, num_of_points, order, knot_index, contr_isclosed, &x, &y); /* Next pt. */ add_cntr_point(x, y); pts_count++; /* As we might have some real number round off problems we do */ /* the last point outside the loop */ if (pts_count == contour_pts * (num_of_points - order) + 1) break; t += dt; } /* Now do the last point */ eval_bspline(t_max - EPSILON, pc_temp, num_of_points, order, knot_index, contr_isclosed, &x, &y); add_cntr_point(x, y); /* Complete the contour. */ if (contr_isclosed) /* Update list - un-circular it. */ pc_tail->next = NULL; }