/// <summary> /// Do following steps for capacities /// - Load capacities from configuration /// - Update absolute capacities for new capacities /// - Check if capacities/absolute-capacities legal /// </summary> public static void LoadUpdateAndCheckCapacities(string queuePath, CapacitySchedulerConfiguration csConf, QueueCapacities queueCapacities, QueueCapacities parentQueueCapacities) { LoadCapacitiesByLabelsFromConf(queuePath, queueCapacities, csConf); UpdateAbsoluteCapacitiesByNodeLabels(queueCapacities, parentQueueCapacities); CapacitiesSanityCheck(queuePath, queueCapacities); }
/// <summary> /// Check sanity of capacities: /// - capacity <= maxCapacity /// - absCapacity <= absMaximumCapacity /// </summary> private static void CapacitiesSanityCheck(string queueName, QueueCapacities queueCapacities ) { foreach (string label in queueCapacities.GetExistingNodeLabels()) { float capacity = queueCapacities.GetCapacity(label); float maximumCapacity = queueCapacities.GetMaximumCapacity(label); if (capacity > maximumCapacity) { throw new ArgumentException("Illegal queue capacity setting, " + "(capacity=" + capacity + ") > (maximum-capacity=" + maximumCapacity + "). When label=[" + label + "]"); } // Actually, this may not needed since we have verified capacity <= // maximumCapacity. And the way we compute absolute capacity (abs(x) = // cap(x) * cap(x.parent) * ...) is a monotone increasing function. But // just keep it here to make sure our compute abs capacity method works // correctly. float absCapacity = queueCapacities.GetAbsoluteCapacity(label); float absMaxCapacity = queueCapacities.GetAbsoluteMaximumCapacity(label); if (absCapacity > absMaxCapacity) { throw new ArgumentException("Illegal queue capacity setting, " + "(abs-capacity=" + absCapacity + ") > (abs-maximum-capacity=" + absMaxCapacity + "). When label=[" + label + "]"); } } }
private static void LoadCapacitiesByLabelsFromConf(string queuePath, QueueCapacities queueCapacities, CapacitySchedulerConfiguration csConf) { queueCapacities.ClearConfigurableFields(); ICollection <string> configuredNodelabels = csConf.GetConfiguredNodeLabels(queuePath ); foreach (string label in configuredNodelabels) { if (label.Equals(CommonNodeLabelsManager.NoLabel)) { queueCapacities.SetCapacity(CommonNodeLabelsManager.NoLabel, csConf.GetNonLabeledQueueCapacity (queuePath) / 100); queueCapacities.SetMaximumCapacity(CommonNodeLabelsManager.NoLabel, csConf.GetNonLabeledQueueMaximumCapacity (queuePath) / 100); } else { queueCapacities.SetCapacity(label, csConf.GetLabeledQueueCapacity(queuePath, label ) / 100); queueCapacities.SetMaximumCapacity(label, csConf.GetLabeledQueueMaximumCapacity(queuePath , label) / 100); } } }
/// <exception cref="System.Exception"/> private void InternalTestModifyAndRead(string label) { QueueCapacities qc = new QueueCapacities(false); // First get returns 0 always NUnit.Framework.Assert.AreEqual(0f, Get(qc, suffix, label), 1e-8); // Set to 1, and check Set(qc, suffix, label, 1f); NUnit.Framework.Assert.AreEqual(1f, Get(qc, suffix, label), 1e-8); // Set to 2, and check Set(qc, suffix, label, 2f); NUnit.Framework.Assert.AreEqual(2f, Get(qc, suffix, label), 1e-8); }
// Use reflection to avoid too much avoid code /// <exception cref="System.Exception"/> private static float ExecuteByName(QueueCapacities obj, string methodName, string label, float value) { // We have 4 kinds of method // 1. getXXX() : float // 2. getXXX(label) : float // 3. setXXX(float) : void // 4. setXXX(label, float) : void if (methodName.StartsWith("get")) { float result; if (label == null) { // 1. MethodInfo method = Sharpen.Runtime.GetDeclaredMethod(typeof(QueueCapacities), methodName ); result = (float)method.Invoke(obj); } else { // 2. MethodInfo method = Sharpen.Runtime.GetDeclaredMethod(typeof(QueueCapacities), methodName , typeof(string)); result = (float)method.Invoke(obj, label); } return(result); } else { if (label == null) { // 3. MethodInfo method = Sharpen.Runtime.GetDeclaredMethod(typeof(QueueCapacities), methodName , typeof(float)); method.Invoke(obj, value); } else { // 4. MethodInfo method = Sharpen.Runtime.GetDeclaredMethod(typeof(QueueCapacities), methodName , typeof(string), typeof(float)); method.Invoke(obj, label, value); } return(-1f); } }
// Set absolute capacities for {capacity, maximum-capacity} private static void UpdateAbsoluteCapacitiesByNodeLabels(QueueCapacities queueCapacities , QueueCapacities parentQueueCapacities) { foreach (string label in queueCapacities.GetExistingNodeLabels()) { float capacity = queueCapacities.GetCapacity(label); if (capacity > 0f) { queueCapacities.SetAbsoluteCapacity(label, capacity * (parentQueueCapacities == null ? 1 : parentQueueCapacities.GetAbsoluteCapacity(label))); } float maxCapacity = queueCapacities.GetMaximumCapacity(label); if (maxCapacity > 0f) { queueCapacities.SetAbsoluteMaximumCapacity(label, maxCapacity * (parentQueueCapacities == null ? 1 : parentQueueCapacities.GetAbsoluteMaximumCapacity(label))); } } }
/// <exception cref="System.IO.IOException"/> public AbstractCSQueue(CapacitySchedulerContext cs, string queueName, CSQueue parent , CSQueue old) { // Track resource usage-by-label like used-resource/pending-resource, etc. // Track capacities like used-capcity/abs-used-capacity/capacity/abs-capacity, // etc. this.labelManager = cs.GetRMContext().GetNodeLabelManager(); this.parent = parent; this.queueName = queueName; this.resourceCalculator = cs.GetResourceCalculator(); // must be called after parent and queueName is set this.metrics = old != null?old.GetMetrics() : QueueMetrics.ForQueue(GetQueuePath (), parent, cs.GetConfiguration().GetEnableUserMetrics(), cs.GetConf()); this.csContext = cs; this.minimumAllocation = csContext.GetMinimumResourceCapability(); // initialize ResourceUsage queueUsage = new ResourceUsage(); queueEntity = new PrivilegedEntity(PrivilegedEntity.EntityType.Queue, GetQueuePath ()); // initialize QueueCapacities queueCapacities = new QueueCapacities(parent == null); }
/// <summary> /// This method intends to be used by ReservationQueue, ReservationQueue will /// not appear in configuration file, so we shouldn't do load capacities /// settings in configuration for reservation queue. /// </summary> public static void UpdateAndCheckCapacitiesByLabel(string queuePath, QueueCapacities queueCapacities, QueueCapacities parentQueueCapacities) { UpdateAbsoluteCapacitiesByNodeLabels(queueCapacities, parentQueueCapacities); CapacitiesSanityCheck(queuePath, queueCapacities); }
/// <exception cref="System.Exception"/> private static void Set(QueueCapacities obj, string suffix, string label, float value ) { ExecuteByName(obj, "set" + suffix, label, value); }
/// <exception cref="System.Exception"/> private static float Get(QueueCapacities obj, string suffix, string label) { return(ExecuteByName(obj, "get" + suffix, label, -1f)); }