static int do_utilization_test(lListElem *cr, test_array_t *ta)
{
   int ret = 0;
   double uti;
   int i;

   for (i = 0; ta[i].start_time != 0; i++) {
      uti = utilization_max(cr, ta[i].start_time, ta[i].duration, false);
      if (uti != ta[i].uti) {
         printf("failed: utilization(cr, "sge_U32CFormat", "sge_U32CFormat") returned %f, expected %f\n",
                sge_u32c(ta[i].start_time), sge_u32c(ta[i].duration), uti, ta[i].uti);
         ret++;
      } else {
         printf("success: utilization(cr, "sge_U32CFormat", "sge_U32CFormat") returned %f\n",
                sge_u32c(ta[i].start_time), sge_u32c(ta[i].duration), uti);
      }
   }

   return ret;
}
示例#2
0
/****** sge_select_queue/get_attribute() ***************************************
*  NAME
*     get_attribute() -- looks for an attribut, but only for one level (for host, global, or queue)  
*
*  SYNOPSIS
*     static lListElem* get_attribute(const char *attrname, lList *config_attr, 
*     lList *actual_attr, lList *load_attr, lList *centry_list, lListElem 
*     *queue, lListElem *rep, u_long32 layer, double lc_factor, dstring *reason) 
*
*  FUNCTION
*     Extracts the attribut specified with 'attrname' and finds the 
*     more important one, if it is defined multiple times on the same 
*     level. It only cares about one level.
*     If the attribute is a consumable, one can specify a point in time and a duration.
*     This will get the caller the min amount of that resource during the time frame.
*
*  INPUTS
*     const char *attrname - attribute name one is looking for 
*     lList *config_attr   - user defined attributes (CE_Type)
*     lList *actual_attr   - current usage of consumables (RUE_Type)
*     lList *load_attr     - load attributes 
*     lList *centry_list   - the system wide attribute configuration 
*     lListElem *queue     - the current queue, or null, if one works on hosts 
*     u_long32 layer       - the current layer 
*     double lc_factor     - the load correction value 
*     dstring *reason      - space for error messages or NULL 
*     bool zero_utilization - ???
*     u_long32 start_time  - begin of the time interval, one asks for the resource
*     u_long32 duration    - the duration the interval
*
*  RESULT
*     static lListElem* - the element one was looking for or NULL
*
*******************************************************************************/
lListElem* get_attribute(const char *attrname, lList *config_attr, lList *actual_attr, lList *load_attr, 
   const lList *centry_list, lListElem *queue, u_long32 layer, double lc_factor, dstring *reason,
   bool zero_utilization, u_long32 start_time, u_long32 duration)
{
   lListElem *actual_el=NULL;
   lListElem *load_el=NULL;
   lListElem *cplx_el=NULL;

   DENTER(BASIS_LAYER, "get_attribute");

   /* resource_attr is a complex_entry (CE_Type) */
   if (config_attr) {
      lListElem *temp = lGetElemStr(config_attr, CE_name, attrname);

      if (temp){ 

         cplx_el = lCopyElem(lGetElemStr(centry_list, CE_name, attrname));
         if(!cplx_el){
            /* error */
            DRETURN(NULL);
         }
         lSetUlong(cplx_el, CE_dominant, layer | DOMINANT_TYPE_FIXED);
         lSetUlong(cplx_el, CE_pj_dominant, DOMINANT_TYPE_VALUE);  /* default, no value set */ 
         lSetDouble(cplx_el, CE_doubleval, lGetDouble(temp,CE_doubleval) ); 
         lSetString(cplx_el, CE_stringval, lGetString(temp,CE_stringval) ); 
      }
   }

   if (cplx_el && lGetUlong(cplx_el, CE_consumable) != CONSUMABLE_NO) {
      lSetUlong(cplx_el, CE_pj_dominant, layer | DOMINANT_TYPE_CONSUMABLE);
      lSetUlong(cplx_el, CE_dominant, DOMINANT_TYPE_VALUE);
      /* treat also consumables as fixed attributes when assuming an empty queuing system */
      if (sconf_get_qs_state() == QS_STATE_FULL) {
         if (actual_attr && (actual_el = lGetElemStr(actual_attr, RUE_name, attrname))){
            dstring ds;
            char as_str[20];
            double utilized = zero_utilization ? 0 : utilization_max(actual_el, start_time, duration, false);

            switch (lGetUlong(cplx_el, CE_relop)) {
               case CMPLXGE_OP:
               case CMPLXGT_OP:
                     lSetDouble(cplx_el, CE_pj_doubleval, utilized); 
               break;

               case CMPLXEQ_OP:
               case CMPLXLT_OP:
               case CMPLXLE_OP:
               case CMPLXNE_OP:
               default:
                     lSetDouble(cplx_el, CE_pj_doubleval, lGetDouble(cplx_el, CE_doubleval) - utilized); 
                  break;
            }
            sge_dstring_init(&ds, as_str, sizeof(as_str));
            sge_dstring_sprintf(&ds, "%8.3f", (float)lGetDouble(cplx_el, CE_pj_doubleval));
            lSetString(cplx_el,CE_pj_stringval, as_str);
         } else{
            sge_dstring_sprintf(reason, MSG_ATTRIB_ACTUALELEMENTTOATTRIBXMISSING_S, attrname);
            lFreeElem(&cplx_el);
            DRETURN(NULL);
         }
      } else{
         lSetDouble(cplx_el, CE_pj_doubleval, lGetDouble(cplx_el, CE_doubleval)); 
         lSetString(cplx_el,CE_pj_stringval, lGetString(cplx_el, CE_stringval));
      }
   }

   /** check for a load value */
   if (load_attr && 
       (load_el = lGetElemStr(load_attr, HL_name, attrname)) &&
       (sconf_get_qs_state()==QS_STATE_FULL || lGetBool(load_el, HL_static)) &&
        (!is_attr_prior(cplx_el, cplx_el)))
   {
         lListElem *ep_nproc=NULL;
         int nproc=1;

         if (!cplx_el){
            cplx_el = lCopyElem(lGetElemStr(centry_list, CE_name, attrname));
               if (!cplx_el){
                  /* error */
                  DRETURN(NULL);
               }         
            lSetUlong(cplx_el, CE_dominant, DOMINANT_TYPE_VALUE);
            lSetUlong(cplx_el, CE_pj_dominant, DOMINANT_TYPE_VALUE);
         }

         if ((ep_nproc = lGetElemStr(load_attr, HL_name, LOAD_ATTR_NUM_PROC))) {
            const char *cp = lGetString(ep_nproc, HL_value);
            if (cp)
               nproc = MAX(1, atoi(lGetString(ep_nproc, HL_value)));
         }

         {
            const char *load_value=NULL;
            u_long32 type;
            double dval;

            load_value = lGetString(load_el, HL_value);

            /* are we working on string values? if though, than it is easy */
            if ( (type = lGetUlong(cplx_el, CE_valtype)) == TYPE_STR || type == TYPE_CSTR || type == TYPE_HOST || type == TYPE_RESTR) {
               lSetString(cplx_el, CE_stringval, load_value);
               lSetUlong(cplx_el, CE_dominant, layer | DOMINANT_TYPE_LOAD);
            } else { /* working on numerical values */
               lListElem *job_load;
               char err_str[256];
               char sval[100];
               u_long32 dom_type = DOMINANT_TYPE_LOAD;
               lList *load_adjustments = sconf_get_job_load_adjustments();
 
               job_load=lGetElemStr(load_adjustments, CE_name, attrname);

               if (parse_ulong_val(&dval, NULL, type, load_value, NULL, 0)) {

               sge_strlcpy(sval, load_value, 100);
               /* --------------------------------
                  look for 'name' in our load_adjustments list
               */
               if (job_load) {
                  const char *s;
                  double load_correction;

                  s = lGetString(job_load, CE_stringval);
                  if (!parse_ulong_val(&load_correction, NULL, type, s, err_str, 255)) {
                     ERROR((SGE_EVENT, MSG_SCHEDD_LOADADJUSTMENTSVALUEXNOTNUMERIC_S , attrname));
                  } else if (lc_factor) {
                     double old_dval;
                     u_long32 relop;
                     if (!strncmp(attrname, "np_", 3) && nproc != 1 ) {
                        DPRINTF(("fillComplexFromHost: dividing lc_factor for \"%s\" with value %f by %d to %f\n",
                                 attrname, lc_factor, nproc, lc_factor / nproc));
                        lc_factor /= nproc;
                     }
                     load_correction *= lc_factor;

                     /* it depends on relop in complex config whether load_correction is pos/neg */
                     if ( (relop = lGetUlong(cplx_el, CE_relop)) == CMPLXGE_OP || relop == CMPLXGT_OP){
                        old_dval = dval;
                        dval += load_correction;
                     }   
                     else{
                        old_dval = dval;
                        dval -= load_correction;
                     }

                     sprintf(sval, "%8.3f", dval);
                     DPRINTF(("%s: uc: %f c(%f): %f\n", attrname, old_dval, lc_factor, dval));
                     dom_type = DOMINANT_TYPE_CLOAD;
                  }
               }

               /* we can have a user, who wants to override the incomming load value. This is no
                  problem for consumables, but for fixed values. A custom fixed value is a per
                  slot value (stored in CE_doubleval) and a load value is a per job value (stored
                  in CE_pj_doubleval). 
   
                  This code changes a fixed custom value from a per slot to a per job value!!
               */
               if ( !(lGetUlong(cplx_el, CE_dominant) == DOMINANT_TYPE_VALUE) && 
                     (lGetUlong(cplx_el, CE_pj_dominant) == DOMINANT_TYPE_VALUE)){
                  lSetDouble(cplx_el, CE_pj_doubleval, lGetDouble(cplx_el, CE_doubleval));
                  lSetString(cplx_el, CE_pj_stringval, lGetString(cplx_el, CE_stringval));
                  lSetUlong(cplx_el, CE_dominant, DOMINANT_TYPE_VALUE);
                  lSetUlong(cplx_el, CE_pj_dominant, layer | DOMINANT_TYPE_FIXED);
               } 
 
               if (!is_attr_prior2(cplx_el, dval, CE_pj_doubleval, CE_pj_dominant)){
                  lSetString(cplx_el, CE_pj_stringval, load_value);
                  lSetUlong(cplx_el, CE_pj_dominant, layer | dom_type);
                  lSetDouble(cplx_el, CE_pj_doubleval, dval );
               }
            } /* end numerical load value */
            lFreeList(&load_adjustments);
         }/* end block */
      }
   }

   /* we are working on queue level, so we have to check for queue resource values */
   if (queue){
      bool created=false;
      if(!cplx_el){
         cplx_el = lCopyElem(lGetElemStr(centry_list, CE_name, attrname));
         if(!cplx_el){
            /* error */
            DRETURN(NULL);
         }         
         lSetUlong(cplx_el, CE_dominant, DOMINANT_TYPE_VALUE);
         lSetUlong(cplx_el, CE_pj_dominant, DOMINANT_TYPE_VALUE);
         created = true;
      }
      if (!get_queue_resource(cplx_el, queue, attrname) && created) {
         lFreeElem(&cplx_el);
      }
   }
   DRETURN(cplx_el);
}