public OperatorEnqArgs(int threadId, Dataflow.Stage stage, int shardId, Pointstamp pointstamp) { this.ThreadId = threadId; this.Stage = stage; this.ShardId = shardId; this.Pointstamp = pointstamp; }
public int Populate(ref Scheduling.Pointstamp version) { if (0 < version.Timestamp.Length) { version.Timestamp[0] = t; } return(1); }
public static Pointstamp ToPointstamp <T>(this T latticeElement, int graphObjectID) where T : Time <T> { var version = new Pointstamp(); version.Location = graphObjectID; version.Timestamp.Length = latticeElement.Coordinates(); latticeElement.Populate(ref version); return(version); }
public int Populate(ref Scheduling.Pointstamp version) { var position = s.Populate(ref version); if (position < version.Timestamp.Length) { version.Timestamp[position] = t; } return(position + 1); }
public bool LessThan(Pointstamp a, Pointstamp b) { // early exit if this.epoch > that.epoch if (a.Timestamp[0] > b.Timestamp[0]) { return(false); } var depth = ComparisonDepth.Array[a.Location].Array[b.Location]; if (depth == 0) { return(false); } else { var increment = depth < 0; depth = Math.Abs(depth); for (int i = 1; i < depth; i++) { if (a.Timestamp[i] > b.Timestamp[i]) { return(false); } if (i + 1 == depth && increment && a.Timestamp[i] + 1 > b.Timestamp[i]) { return(false); } if (a.Timestamp[i] < b.Timestamp[i]) { return(true); } } return(true); } }
public IEnumerable <Pointstamp> EnumerateImpersonations(Pointstamp time) { var limits = this.Impersonations[time.Location]; if (limits == null) { yield break; } else { for (int i = 0; i < limits.Length; i++) { var depths = this.ComparisonDepth.Array[time.Location][limits[i]]; var coords = this.Graph[limits[i]].Depth; var newVersion = new Pointstamp(); newVersion.Location = limits[i]; newVersion.Timestamp.Length = coords; for (int j = 0; j < newVersion.Timestamp.Length; j++) { if (j < Math.Abs(depths)) { newVersion.Timestamp[j] = time.Timestamp[j]; } else { newVersion.Timestamp[j] = 0; } } if (depths < 0) { newVersion.Timestamp[Math.Abs(depths) - 1] = newVersion.Timestamp[Math.Abs(depths) - 1] + 1; } yield return(newVersion); } } }
// compares two causal orders for reachability. uses controller to determine which lattice elements correspond to loops, and which to prioritizations. // for now, the assumption is that the first int is always the input lattice, which has no back edge. // for now, this only works if a and b correspond to the same stage. public bool ProductOrderLessThan(Pointstamp a, Pointstamp b) { if (a.Timestamp.Length != b.Timestamp.Length) { Console.WriteLine("should have same length!"); } if (a.Location != b.Location) { Console.WriteLine("meant to be called on pointstamps of the same stage"); } for (int i = 0; i < a.Timestamp.Length; i++) { if (a.Timestamp[i] > b.Timestamp[i]) { return(false); } } return(true); }
public bool AddToAntiChain(NaiadList <Pointstamp> list, Pointstamp time) { // bail if time can be reached by any element of list for (int i = 0; i < list.Count; i++) { if (ProductOrderLessThan(list.Array[i], time)) { return(false); } } // belongs in; clean out reachable times. for (int i = 0; i < list.Count; i++) { if (ProductOrderLessThan(time, list.Array[i])) { list.RemoveAt(i); i--; } } list.Add(time); return(true); }
public int CompareTo(Pointstamp a, Pointstamp b) { if (a.Timestamp[0] != b.Timestamp[0]) { return(a.Timestamp[0] - b.Timestamp[0]); } if (a.Equals(b)) { return(0); } if (this.LessThan(a, b)) { return(-1); } if (this.LessThan(a, b)) { return(1); } return(a.Location - b.Location); }
// Returns a list (indexed by graph identifier) of lists of Pointstamps that can be reached at each collection, for the // given array of times. Each sub-list will be a minimal antichain of Pointstamps at which a collection is reachable. // // If the sublist for a collection is null, that collection is not reachable from the given array of times. public NaiadList <Pointstamp>[] DetermineReachabilityList(Pointstamp[] times) { // Initially, the result for each collection is null, which corresponds to it not being reachable from the given times. var result = new NaiadList <Pointstamp> [this.Graph.Length]; // For each time, perform breadth-first search from that time to each reachable collection. for (int time = 0; time < times.Length; time++) { // To perform the BFS, we need a list, which will act like a FIFO queue. var queue = new List <int>(); // The BFS starts from the current time's stage var index = times[time].Location; if (result[index] == null) { result[index] = new NaiadList <Pointstamp>(0); } // Attempt to add the current time to the antichain for its own collection. if (AddToAntiChain(result[index], times[time])) { // If this succeeds, commence BFS from that collection. queue.Add(index); // While we haven't visited every element of the queue, move to the next element. for (int i = 0; i < queue.Count; i++) { var collectionId = queue[i]; // For each immediately downstream collection from the current collection, attempt to improve the antichain for the downstream. for (int k = 0; k < this.Graph[collectionId].Neighbors.Length; k++) { var target = this.Graph[collectionId].Neighbors[k]; var updated = false; if (result[target] == null) { result[target] = new NaiadList <Pointstamp>(0); } // For each element of the current collection's antichain, evaluate the minimal caused version at the downstream collection. for (int j = 0; j < result[collectionId].Count; j++) { // make a new copy so that we can tamper with the contents var localtime = new Pointstamp(result[collectionId].Array[j]); localtime.Location = target; // If the target is a feedback stage, we must increment the last coordinate. if (this.Graph[target].Advance) { localtime.Timestamp[localtime.Timestamp.Length - 1]++; } // If the target is an egress stage, we must strip off the last coordinate. if (this.Graph[target].Egress) { localtime.Timestamp.Length--; localtime.Timestamp[localtime.Timestamp.Length] = 0; } // If the target is an ingress stage, we must add a new coordinate. if (this.Graph[target].Ingress) { localtime.Timestamp.Length++; } if (localtime.Timestamp.Length != this.Graph[target].Depth) { throw new Exception("Something is horribly wrong in Reachability"); } // If the computed minimal time for the downstream collection becomes a member of its antichain, we have updated it // (and must search forward from that collection). if (AddToAntiChain(result[target], localtime)) { updated = true; } } // Where the antichain has been updated, we must search forward from the downstream collection. if (updated) { queue.Add(target); } } } } } return(result); }
// populates this.ComparisonDepth, indexed by collection and channel identifiers. public void UpdateReachabilityPartialOrder(Runtime.InternalGraphManager graphManager) { RegenerateGraph(graphManager); var reachableDepths = new NaiadList <NaiadList <int> >(this.Graph.Length); var magicNumber = 37; //Console.Error.WriteLine("Updating reachability with {0} objects", Reachability.Graph.Length); for (int i = 0; i < this.Graph.Length; i++) { var reachable = new NaiadList <int>(this.Graph.Length); var versionList = new Pointstamp[] { new Pointstamp(i, Enumerable.Repeat(magicNumber, this.Graph[i].Depth).ToArray()) }; var reachabilityResults = this.DetermineReachabilityList(versionList); for (int j = 0; j < reachabilityResults.Length; j++) { var depth = 0; var increment = false; // for each element of the reachable set if (reachabilityResults[j] != null) { for (int k = 0; k < reachabilityResults[j].Count; k++) { for (int l = 0; l < reachabilityResults[j].Array[k].Timestamp.Length && reachabilityResults[j].Array[k].Timestamp[l] >= magicNumber; l++) { if (l + 1 > depth || l + 1 == depth && increment) { depth = l + 1; increment = (reachabilityResults[j].Array[k].Timestamp[l] > magicNumber); } } } } reachable.Array[j] = increment ? -depth : depth; } reachableDepths.Array[i] = reachable; } this.ComparisonDepth = reachableDepths; #region Set up impersonation // consider each stage / edge this.Impersonations = new int[this.Graph.Length][]; for (int i = 0; i < this.Graph.Length; i++) { // not applicable to exchange edges. if (!this.Graph[i].Exchanges && !this.NoImpersonation.Contains(i)) { var reached = new HashSet <int>(); var limits = new HashSet <int>(); var queue = new List <int>(); //reached.Add(i); queue.Add(i); for (int j = 0; j < queue.Count; j++) { var candidate = queue[j]; // check if queue[j] is interested in masquerading var available = true; for (int k = 0; k < this.Graph[candidate].Neighbors.Length; k++) { var target = this.Graph[candidate].Neighbors[k]; if (this.Graph[target].Exchanges) { available = false; } } if (!reached.Contains(candidate)) { reached.Add(candidate); if (available) { for (int k = 0; k < this.Graph[candidate].Neighbors.Length; k++) { queue.Add(this.Graph[candidate].Neighbors[k]); } } else { limits.Add(candidate); } } } // if we found someone who wants to masquerade if (!limits.Contains(i) && limits.Count > 0) { Impersonations[i] = limits.ToArray(); } else { Impersonations[i] = null; } } } #endregion }
public IterationIn <S> InitializeFrom(Scheduling.Pointstamp version, int length) { t = version.Timestamp[length - 1]; s = s.InitializeFrom(version, length - 1); return(this); }
public Epoch InitializeFrom(Scheduling.Pointstamp version, int length) { t = version.Timestamp[0]; return(this); }