Example #1
0
File: job.py Project: oar-team/oar3
def extract_scheduled_jobs(result, resource_set, job_security_time, now):

    jids = []
    jobs_lst = []
    jobs = {}
    prev_jid = 0
    roids = []
    rid2jid = {}

    global job

    # (job, a, b, c) = req[0]
    if result:
        for x in result:
            j, moldable_id, start_time, walltime, r_id = x
            if j.id != prev_jid:
                if prev_jid != 0:
                    job.res_set = unordered_ids2itvs(roids)
                    jobs_lst.append(job)
                    jids.append(job.id)
                    jobs[job.id] = job
                    roids = []

                prev_jid = j.id
                job = j
                job.start_time = start_time
                job.walltime = walltime + job_security_time
                job.moldable_id = moldable_id
                job.ts = False
                job.ph = NO_PLACEHOLDER
                job.assign = False
                job.find = False
                if job.suspended == "YES":
                    job.walltime += get_job_suspended_sum_duration(job.id, now)

            roid = resource_set.rid_i2o[r_id]
            roids.append(roid)
            rid2jid[roid] = j.id

        job.res_set = unordered_ids2itvs(roids)
        if job.state == "Suspended":
            job.res_set = sub_intervals(
                job.res_set, resource_set.suspendable_roid_itvs)

        jobs_lst.append(job)
        jids.append(job.id)
        jobs[job.id] = job
        get_jobs_types(jids, jobs)

    return (jobs, jobs_lst, jids, rid2jid)
Example #2
0
File: job.py Project: oar-team/oar3
def get_waiting_reservations_already_scheduled(resource_set, job_security_time):

    result = db.query(Job,
                      GanttJobsPrediction.start_time, GanttJobsResource.resource_id,
                      MoldableJobDescription.walltime, MoldableJobDescription.id)\
        .filter((Job.state == 'Waiting') | (Job.state == 'toAckReservation'))\
        .filter(Job.reservation == 'Scheduled')\
        .filter(Job.id == MoldableJobDescription.job_id)\
        .filter(GanttJobsPrediction.moldable_id == MoldableJobDescription.id)\
        .filter(GanttJobsResource.moldable_id == MoldableJobDescription.id)\
        .order_by(Job.id).all()

    first_job = True
    jobs = {}
    jids = []

    prev_jid = 0
    roids = []

    global job
    if result:
        for x in result:
            j, start_time, resource_id, walltime, moldable_id = x

            if j.id != prev_jid:
                if first_job:
                    first_job = False
                else:
                    job.res_set = unordered_ids2itvs(roids)
                    jids.append(job.id)
                    jobs[job.id] = job
                    roids = []

                prev_jid = j.id
                job = j
                job.start_time = start_time
                job.walltime = walltime + job_security_time

            roids.append(resource_set.rid_i2o[resource_id])

        job.res_set = unordered_ids2itvs(roids)

        jids.append(job.id)
        jobs[job.id] = job

        get_jobs_types(jids, jobs)

    return (jids, jobs)
Example #3
0
    def save_assigns_simu(self, jobs, resource_set):
        print("save_assigns_simu")

        for jid, job in iteritems(jobs):
            jres_set = job.res_set
            print("job.res_set before", jid, job.res_set)
            r_ids = [resource_set.rid_o2i[roid] for roid in itvs2ids(jres_set)]
            job.res_set = unordered_ids2itvs(r_ids)
        self.assigned_jobs = jobs
Example #4
0
File: job.py Project: oar-team/oar3
def get_jobs_in_multiple_states(states, resource_set):

    result = db.query(Job, AssignedResource.moldable_id, AssignedResource.resource_id)\
               .filter(Job.state.in_(tuple(states)))\
               .filter(Job.assigned_moldable_job == AssignedResource.moldable_id)\
               .order_by(Job.id).all()

    first_job = True
    jobs = {}

    prev_jid = 0
    roids = []

    global job

    if result:
        for x in result:
            j, moldable_id, resource_id = x

            if j.id != prev_jid:
                if first_job:
                    first_job = False
                else:
                    job.res_set = unordered_ids2itvs(roids)
                    jobs[job.id] = job
                    roids = []

                prev_jid = j.id
                job = j
                job.moldable_id = moldable_id

            roids.append(resource_set.rid_i2o[resource_id])

        job.res_set = unordered_ids2itvs(roids)
        jobs[job.id] = job

    return jobs
Example #5
0
    def save_assigns_simu_and_default(self, jobs, resource_set):
        print("save_assigns_simu_and_default........................")
        # assigned_jobs = {}
        for jid, job in iteritems(jobs):
            sid = self.db_jid2s_jid[jid]
            jobsimu = self.jobs[sid]
            jres_set = job.res_set
            r_ids = [resource_set.rid_o2i[roid] for roid in itvs2ids(jres_set)]
            jobsimu.res_set = unordered_ids2itvs(r_ids)
            print("save assign jid, sid, res_set: ", jid, " ", sid, " ", jobsimu.res_set)
            jobsimu.start_time = job.start_time
            jobsimu.walltime = job.walltime
            # assigned_jobs[sid] = jobsimu

        # self.assigned_jobs = assigned_jobs

        return save_assigns(jobs, resource_set)
Example #6
0
File: job.py Project: oar-team/oar3
def get_data_jobs(jobs, jids, resource_set, job_security_time,
                  besteffort_duration=0):
    """
    oarsub -q test \
        -l "nodes=1+{network_address='node3'}/nodes=1/resource_id=1" \
        sleep

    job_id: 12 [(16L,
                 7200,
                 [
                     (
                         [(u'network_address', 1)],
                         [(0, 7)]
                     ),
                     (
                         [(u'network_address', 1), (u'resource_id', 1)],
                         [(4, 7)]
                     )
                 ])]

    """

    result = db.query(Job.id,
                      Job.properties,
                      MoldableJobDescription.id,
                      MoldableJobDescription.walltime,
                      JobResourceGroup.id,
                      JobResourceGroup.property,
                      JobResourceDescription.group_id,
                      JobResourceDescription.resource_type,
                      JobResourceDescription.value)\
        .filter(MoldableJobDescription.index == 'CURRENT')\
        .filter(JobResourceGroup.index == 'CURRENT')\
        .filter(JobResourceDescription.index == 'CURRENT')\
        .filter(Job.id.in_(tuple(jids)))\
        .filter(Job.id == MoldableJobDescription.job_id)\
        .filter(JobResourceGroup.moldable_id == MoldableJobDescription.id)\
        .filter(JobResourceDescription.group_id == JobResourceGroup.id)\
        .order_by(MoldableJobDescription.id,
                  JobResourceGroup.id,
                  JobResourceDescription.order)\
        .all()
    #            .join(MoldableJobDescription)\
    #            .join(JobResourceGroup)\
    #            .join(JobResourceDescription)\

    cache_constraints = {}

    first_job = True
    prev_j_id = 0
    prev_mld_id = 0
    prev_jrg_id = 0
    prev_res_jrg_id = 0
    mld_res_rqts = []
    jrg = []
    jr_descriptions = []
    res_constraints = []
    prev_mld_id_walltime = 0

    global job

    for x in result:
        # remove res_order
        (j_id, j_properties,
         moldable_id,
         mld_id_walltime,
         jrg_id,
         jrg_grp_property,
         res_jrg_id,
         res_type,
         res_value) = x
        #
        # new job
        #
        if j_id != prev_j_id:
            if first_job:
                first_job = False
            else:
                jrg.append((jr_descriptions, res_constraints))
                mld_res_rqts.append((prev_mld_id, prev_mld_id_walltime, jrg))
                job.mld_res_rqts = mld_res_rqts
                mld_res_rqts = []
                jrg = []
                jr_descriptions = []
                job.key_cache = {}
                job.deps = []
                job.ts = False
                job.ph = NO_PLACEHOLDER
                job.assign = False
                job.find = False

            prev_mld_id = moldable_id
            prev_j_id = j_id
            job = jobs[j_id]
            if besteffort_duration:
                prev_mld_id_walltime = besteffort_duration
            else:
                prev_mld_id_walltime = mld_id_walltime + job_security_time

        else:
            #
            # new moldable_id
            #

            if moldable_id != prev_mld_id:
                if jrg != []:
                    jrg.append((jr_descriptions, res_constraints))
                    mld_res_rqts.append(
                        (prev_mld_id, prev_mld_id_walltime, jrg))

                prev_mld_id = moldable_id
                jrg = []
                jr_descriptions = []
                if besteffort_duration:
                    prev_mld_id_walltime = besteffort_duration
                else:
                    prev_mld_id_walltime = mld_id_walltime + job_security_time
        #
        # new job resources groupe_id
        #
        if jrg_id != prev_jrg_id:
            prev_jrg_id = jrg_id
            if jr_descriptions != []:
                jrg.append((jr_descriptions, res_constraints))
                jr_descriptions = []

        #
        # new set job descriptions
        #
        if res_jrg_id != prev_res_jrg_id:
            prev_res_jrg_id = res_jrg_id
            jr_descriptions = [(res_type, res_value)]

            #
            # determine resource constraints
            #
            if (j_properties == "" and (jrg_grp_property == "" or jrg_grp_property == "type = 'default'")):
                res_constraints = deepcopy(resource_set.roid_itvs)
            else:
                if j_properties == "" or jrg_grp_property == "":
                    and_sql = ""
                else:
                    and_sql = " AND "

                sql_constraints = j_properties + and_sql + jrg_grp_property
                if sql_constraints in cache_constraints:
                    res_constraints = cache_constraints[sql_constraints]
                else:
                    request_constraints = db.query(
                        Resource.id).filter(text(sql_constraints)).all()
                    roids = [resource_set.rid_i2o[int(y[0])]
                             for y in request_constraints]
                    res_constraints = unordered_ids2itvs(roids)
                    cache_constraints[sql_constraints] = res_constraints
        else:
            # add next res_type , res_value
            jr_descriptions.append((res_type, res_value))

    # complete the last job
    jrg.append((jr_descriptions, res_constraints))
    mld_res_rqts.append((prev_mld_id, prev_mld_id_walltime, jrg))

    job.mld_res_rqts = mld_res_rqts
    job.key_cache = {}
    job.deps = []
    job.ts = False
    job.ph = NO_PLACEHOLDER
    job.assign = False
    job.find = False

    get_jobs_types(jids, jobs)
    get_current_jobs_dependencies(jobs)
    set_jobs_cache_keys(jobs)
Example #7
0
def schedule_fifo_cycle(plt, queue="default", hierarchy_use=False):

    assigned_jobs = {}

    now = plt.get_time()

    logger.info("Begin scheduling....now: " + str(now) + ", queue: " + queue)

    #
    # Retrieve waiting jobs
    #
    waiting_jobs, waiting_jids, nb_waiting_jobs = plt.get_waiting_jobs(queue)

    if nb_waiting_jobs > 0:
        logger.info("nb_waiting_jobs:" + str(nb_waiting_jobs))
        for jid in waiting_jids:
            logger.debug("waiting_jid: " + str(jid))

        #
        # Determine Global Resource Intervals
        #
        resource_set = plt.resource_set()
        res_itvs = deepcopy(resource_set.roid_itvs)

        #
        # Get  additional waiting jobs' data
        #
        job_security_time = int(config["SCHEDULER_JOB_SECURITY_TIME"])
        plt.get_data_jobs(waiting_jobs, waiting_jids, resource_set, job_security_time)

        #
        # Remove resources used by running job
        #
        for job in plt.get_scheduled_jobs(resource_set, job_security_time, now):
            if job.state == "Running":
                res_itvs = sub_intervals(res_itvs, job.res_itvs)

        #
        # Assign resource to jobs
        #

        for jid in waiting_jids:
            job = waiting_jobs[jid]

            # We consider only one instance of resources request (no support for moldable)
            (mld_id, walltime, hy_res_rqts) = job.mld_res_rqts[0]

            if hierarchy_use:
                # Assign resources which hierarchy support (uncomment)
                itvs = find_resource_hierarchies_job(res_itvs, hy_res_rqts, resource_set.hierarchy)
            else:
                # OR assign resource by considering only resource_id (no hierarchy)
                # and only one type of resource
                (hy_level_nbs, constraints) = hy_res_rqts[0]
                (h_name, nb_asked_res) = hy_level_nbs[0]
                itvs_avail = intersec(constraints, res_itvs)
                ids_avail = itvs2ids(itvs_avail)

                if len(ids_avail) < nb_asked_res:
                    itvs = []
                else:
                    itvs = unordered_ids2itvs(ids_avail[:nb_asked_res])

            if (itvs != []):
                job.moldable_id = mld_id
                job.res_set = itvs
                assigned_jobs[job.id] = job
                res_itvs = sub_intervals(res_itvs, itvs)
            else:
                logger.debug("Not enough available resources, it's a FIFO scheduler, we stop here.")
                break

        #
        # Save assignement
        #
        logger.info("save assignement")
        plt.save_assigns(assigned_jobs, resource_set)

    else:
        logger.info("no waiting jobs")
Example #8
0
    def __init__(self):

        # prepare resource order/indirection stuff
        order_by_clause = config["SCHEDULER_RESOURCE_ORDER"]
        self.rid_i2o = array("i", [0] * MAX_NB_RESOURCES)
        self.rid_o2i = array("i", [0] * MAX_NB_RESOURCES)

        # suspend
        suspendable_roids = []
        if "SCHEDULER_AVAILABLE_SUSPENDED_RESOURCE_TYPE" not in config:
            config["SCHEDULER_AVAILABLE_SUSPENDED_RESOURCE_TYPE"] = "default"

        res_suspend_types = (
            config["SCHEDULER_AVAILABLE_SUSPENDED_RESOURCE_TYPE"]).split()

        # prepare hierarchy stuff
        # "HIERARCHY_LABELS" = "resource_id,network_address"
        conf_hy_labels = config[
            "HIERARCHY_LABELS"] if "HIERARCHY_LABELS" in config else "resource_id,network_address"

        hy_labels = conf_hy_labels.split(",")
        hy_labels_w_id = ["id" if v == "resource_id" else v for v in hy_labels]

        hy_roid = {}
        for hy_label in hy_labels_w_id:
            hy_roid[hy_label] = OrderedDict()

        # available_upto for pseudo job in slot
        available_upto = {}
        self.available_upto = {}

        roids = []

        default_rids = []

        # retreive resource in order from DB
        self.resources_db = db.query(Resource).order_by(text(order_by_clause)).all()

        # fill the different structures
        for roid, r in enumerate(self.resources_db):
            if (r.state == "Alive") or (r.state == "Absent"):
                rid = int(r.id)
                roids.append(roid)
                if r.type == 'default':
                    default_rids.append(rid)

                self.rid_i2o[rid] = roid
                self.rid_o2i[roid] = rid

                # fill hy_rid structure
                for hy_label in hy_labels_w_id:
                    v = getattr(r, hy_label)
                    if v in hy_roid[hy_label]:
                        hy_roid[hy_label][v].append(roid)
                    else:
                        hy_roid[hy_label][v] = [roid]

                # fill available_upto structure
                if r.available_upto in available_upto:
                    available_upto[r.available_upto].append(roid)
                else:
                    available_upto[r.available_upto] = [roid]

                # fill resource available for suspended job
                if r.type in res_suspend_types:
                    suspendable_roids.append(roid)

        # global ordered resources intervals
        # print roids
        self.roid_itvs = ordered_ids2itvs(roids)

        if "id" in hy_roid:
            hy_roid["resource_id"] = hy_roid["id"]
            del hy_roid["id"]

        # create hierarchy
        self.hierarchy = Hierarchy(hy_rid=hy_roid).hy

        # transform available_upto
        for k, v in iteritems(available_upto):
            self.available_upto[k] = ordered_ids2itvs(v)

        #
        self.suspendable_roid_itvs = ordered_ids2itvs(suspendable_roids)

        default_roids = [self.rid_i2o[i] for i in default_rids]
        self.default_resource_itvs = unordered_ids2itvs(default_roids)
        # update global variable
        default_resource_itvs = self.default_resource_itvs
Example #9
0
def test_unordered_ids2itvs():
    y = [12, 23, 7, 5, 4, 11, 10, 1, 3]
    r = [(1, 1), (3, 5), (7, 7), (10, 12), (23, 23)]
    a = unordered_ids2itvs(y)
    assert a == r
Example #10
0
def estimate_job_nb_resources(resource_request, j_properties):
    '''returns an array with an estimation of the number of resources that can be  used by a job:
    (resources_available, [(nbresources => int, walltime => int)])
    '''
    # estimate_job_nb_resources
    estimated_nb_resources = []
    resource_available = False
    resource_set = ResourceSet()
    resources_itvs = resource_set.roid_itvs

    for mld_idx, mld_resource_request in enumerate(resource_request):

        resource_desc, walltime = mld_resource_request

        if not walltime:
            walltime = default_job_walltime

        result = []

        for prop_res in resource_desc:
            jrg_grp_property = prop_res['property']
            resource_value_lst = prop_res['resources']

            #
            # determine resource constraints
            #
            if (not j_properties) and (not jrg_grp_property or (jrg_grp_property == "type = 'default'")):
                constraints = deepcopy(resource_set.roid_itvs)
            else:
                if not j_properties or not jrg_grp_property:
                    and_sql = ""
                else:
                    and_sql = " AND "

                sql_constraints = j_properties + and_sql + jrg_grp_property

                try:
                    request_constraints = db.query(Resource.id).filter(text(sql_constraints)).all()
                except exc.SQLAlchemyError:
                    print_error('Bad resource SQL constraints request:', sql_constraints)
                    print_error('SQLAlchemyError: ', exc)
                    result = []
                    break

                roids = [resource_set.rid_i2o[int(y[0])] for y in request_constraints]
                constraints = unordered_ids2itvs(roids)

            hy_levels = []
            hy_nbs = []
            for resource_value in resource_value_lst:
                res_name = resource_value['resource']
                value = resource_value['value']
                hy_levels.append(resource_set.hierarchy[res_name])
                hy_nbs.append(int(value))

            cts_resources_itvs = intersec(constraints, resources_itvs)
            res_itvs = find_resource_hierarchies_scattered(cts_resources_itvs, hy_levels, hy_nbs)
            if res_itvs:
                result.extend(res_itvs)
            else:
                result = []
            break

        if result:
            resource_available = True

        estimated_nb_res = itvs_size(result)
        estimated_nb_resources.append((estimated_nb_res, walltime))
        print_info('Moldable instance: ', mld_idx,
                   ' Estimated nb resources: ', estimated_nb_res,
                   ' Walltime: ', walltime)

    if not resource_available:
        print_error("There are not enough resources for your request")
        sub_exit(-5)

    return(resource_available, estimated_nb_resources)