public void OnPrimitiveOperation(int id, object[] qubitsTraceData, double primitiveOperationDuration) { IEnumerable <QubitTimeMetrics> qubitsMetrics = qubitsTraceData.Cast <QubitTimeMetrics>(); if (optimizeDepth) { // When we optimize for depth we may need to adjust qubit start times in addition to qubit end times. if (qubitsTraceData.Length == 1) { // Single qubit gate always advances end time by operation duration // in case qubit is fixed or not fixed in time. ((QubitTimeMetrics)qubitsTraceData[0]).EndTime = ((QubitTimeMetrics)qubitsTraceData[0]).EndTime.AdvanceBy(primitiveOperationDuration); } else { // Multi-qubit gate fixes all qubits in time and advances end time // First, figure out what time it is. It's max over fixed and not fixed times. ComplexTime maxEndTime = ComplexTime.Zero; foreach (QubitTimeMetrics q in qubitsMetrics) { maxEndTime = ComplexTime.Max(maxEndTime, q.EndTime); } // Now we fix qubits that are not yet fixed by adjusting their start time. // And adjust end time for all qubits involved. foreach (QubitTimeMetrics q in qubitsMetrics) { if (q.StartTime.IsEqualTo(ComplexTime.MinValue)) { q.StartTime = maxEndTime.Subtract(q.EndTime); } q.EndTime = maxEndTime.AdvanceBy(primitiveOperationDuration); } } } else { // When we don't optimize for depth we use max availability time // as gate execution time and then adjust availability time of qubits involved double startTime = MaxAvailableTime(qubitsMetrics); foreach (QubitTimeMetrics q in qubitsMetrics) { qubitAvailabilityTime[q.QubitId] = startTime + primitiveOperationDuration; } } }
/// <summary> /// Compares Time field of two nodes. Also updates MaxLowerBound and MinUpperBound. /// </summary> /// <returns>Result of comparison of Time field of QubitTimeNode</returns> public int Compare(QubitTimeNode a, QubitTimeNode b) { // Note that comparison of a and b nodes to Sample is "by reference" in this function. int result = ComplexTime.Compare(a.Time, b.Time); if (result > 0) { if (a == Sample && b != Sample) { MaxLowerBound = ComplexTime.Max(MaxLowerBound, b.Time); } else if (a != Sample && b == Sample) { MinUpperBound = ComplexTime.Min(MinUpperBound, a.Time); } } else if (result < 0) { if (a == Sample && b != Sample) { MinUpperBound = ComplexTime.Min(MinUpperBound, b.Time); } else if (a != Sample && b == Sample) { MaxLowerBound = ComplexTime.Max(MaxLowerBound, a.Time); } } else { // We found the value if one argument is the sample and the other is not. if ((a == Sample) != (b == Sample)) { MaxLowerBound = b.Time; MinUpperBound = b.Time; } } return(result); }