Skip to content

Commit df34696

Browse files
author
Axel Dahlberg
committed
Continued with tests for WFQ
1 parent 0f0b93e commit df34696

File tree

2 files changed

+71
-18
lines changed

2 files changed

+71
-18
lines changed

qlinklayer/scheduler.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ class StrictPriorityRequestScheduler(Scheduler):
5252
# The scheduler request named tuple to use
5353
_scheduler_request_named_tuple = SchedulerRequest
5454

55-
def __init__(self, distQueue, qmm, feu=None):
55+
def __init__(self, distQueue, qmm, feu):
5656
"""
5757
Stub for a scheduler to decide how we assign and consume elements of the queue.
5858
This scheduler puts requests in queues depending on only their specified priority
@@ -797,7 +797,7 @@ class WFQRequestScheduler(StrictPriorityRequestScheduler):
797797
# The scheduler request named tuple to use
798798
_scheduler_request_named_tuple = WFQSchedulerRequest
799799

800-
def __init__(self, distQueue, qmm, feu=None, weights=None):
800+
def __init__(self, distQueue, qmm, feu, weights=None):
801801
"""
802802
Stub for a scheduler to decide how we assign and consume elements of the queue.
803803
This weighted fair queue (WFQ) scheduler implements a weighted fair queue where queue i
@@ -810,7 +810,7 @@ def __init__(self, distQueue, qmm, feu=None, weights=None):
810810
:param feu: :obj:`~qlinklayer.feu.FidelityEstimationUnit`
811811
(optional) The fidelity estimation unit
812812
:param weights: None, list of floats
813-
* If None, a fair queue with equal weights will be used.
813+
* If None, a strict priority queue will be used, with the queue IDs as priorities
814814
* If list of floats, the length of the list needs to equal the number of queues in the distributed queue.
815815
The floats need to be non-zero. If a weight is zero, this is seen as infinite weight and queues with zero
816816
weight will always be scheduled before other queues. If multiple queues have weight zero, then
@@ -820,7 +820,7 @@ def __init__(self, distQueue, qmm, feu=None, weights=None):
820820

821821
self.relative_weights = self._get_relative_weights(weights)
822822

823-
self.last_virt_finish = [-1] * len(weights)
823+
self.last_virt_finish = [-1] * len(self.relative_weights)
824824

825825
def _compare_mhp_cycle(self, cycle1, cycle2):
826826
"""
@@ -853,9 +853,9 @@ def _compare_mhp_cycle(self, cycle1, cycle2):
853853

854854
def _get_relative_weights(self, weights):
855855
if weights is None:
856-
return
856+
return [0] * len(self.distQueue.queueList)
857857
if not isinstance(weights, list) or isinstance(weights, tuple):
858-
raise ValueError("Weights need to be None or list")
858+
raise TypeError("Weights need to be None or list")
859859
if not len(weights) == len(self.distQueue.queueList):
860860
raise ValueError("Number of weights must equal number of queues")
861861
for weight in weights:

tests/test_scheduler.py

+65-12
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import unittest
22
import logging
3+
from util.config_paths import ConfigPathStorage
34
from easysquid.easyfibre import ClassicalFibreConnection
4-
from easysquid.easynetwork import EasyNetwork
5+
from easysquid.easynetwork import EasyNetwork, setup_physical_network
56
from easysquid.qnode import QuantumNode
67
from easysquid.quantumMemoryDevice import NVCommunicationDevice
78
from easysquid.easyprotocol import TimedProtocol
89
from easysquid.toolbox import logger
10+
from easysquid.quantumMemoryDevice import NVCommunicationDevice
911
from netsquid.simutil import sim_run, sim_reset
1012
from qlinklayer.distQueue import EGPDistributedQueue, WFQDistributedQueue
1113
from qlinklayer.scheduler import StrictPriorityRequestScheduler, WFQRequestScheduler
@@ -155,24 +157,75 @@ def test_priority(self):
155157

156158
class TestWFQRequestScheduler(unittest.TestCase):
157159
def setUp(self):
158-
alice = QuantumNode("alice", 0)
159-
bob = QuantumNode("bob", 0)
160-
conn = ClassicalFibreConnection(alice, bob, length=0.001)
160+
sim_reset()
161+
162+
network = setup_physical_network(ConfigPathStorage.NETWORK_NV_LAB_NOCAV_NOCONV)
163+
alice, bob = network.all_nodes()
164+
dqp_conn = network.get_connection(alice, bob, "dqp_conn")
165+
mhp_conn = network.get_connection(alice, bob, "mhp_conn")
161166

162-
distQueueA = WFQDistributedQueue(alice, numQueues=3, accept_all=True)
163-
distQueueB = WFQDistributedQueue(bob, numQueues=3, accept_all=True)
164-
distQueueA.connect_to_peer_protocol(distQueueB, conn=conn)
167+
self.num_queues = 3
165168

166-
qmmA = QuantumMemoryManagement(alice)
169+
self.distQueueA = WFQDistributedQueue(alice, numQueues=self.num_queues, accept_all=True)
170+
distQueueB = WFQDistributedQueue(bob, numQueues=self.num_queues, accept_all=True)
171+
self.distQueueA.connect_to_peer_protocol(distQueueB, conn=dqp_conn)
172+
173+
self.qmmA = QuantumMemoryManagement(alice)
167174
qmmB = QuantumMemoryManagement(bob)
168175

169-
# mhp_service = SimulatedNodeCentricMHPService("mhp_service", alice, bob)
170-
#
171-
# feuA = SingleClickFidelityEstimationUnit(alice, )
172-
# self.schedulerA = WFQRequestScheduler(distQueueA, qmmA, feuA)
176+
mhp_service = SimulatedNodeCentricMHPService("mhp_service", alice, bob, conn=mhp_conn)
177+
178+
self.feuA = SingleClickFidelityEstimationUnit(alice, mhp_service)
179+
feuB = SingleClickFidelityEstimationUnit(bob, mhp_service)
180+
181+
self.schedulerA = WFQRequestScheduler(self.distQueueA, self.qmmA, self.feuA)
182+
173183
def test_init(self):
184+
# Test default
185+
scheduler = WFQRequestScheduler(self.distQueueA, self.qmmA, self.feuA)
186+
self.assertEqual(scheduler.relative_weights, [0] * self.num_queues)
187+
188+
# Test wrong type
189+
with self.assertRaises(TypeError):
190+
WFQRequestScheduler(self.distQueueA, self.qmmA, self.feuA, 0)
191+
with self.assertRaises(TypeError):
192+
WFQRequestScheduler(self.distQueueA, self.qmmA, self.feuA, {})
193+
194+
# Test wrong length
195+
with self.assertRaises(ValueError):
196+
WFQRequestScheduler(self.distQueueA, self.qmmA, self.feuA, [0] * (self.num_queues + 1))
197+
198+
# Test negative weights
199+
with self.assertRaises(ValueError):
200+
WFQRequestScheduler(self.distQueueA, self.qmmA, self.feuA, [0, 0, -1])
201+
202+
# Test non-comparable weights
203+
with self.assertRaises(ValueError):
204+
WFQRequestScheduler(self.distQueueA, self.qmmA, self.feuA, [0, [], False])
205+
206+
# Test non-trivial weights
207+
scheduler = WFQRequestScheduler(self.distQueueA, self.qmmA, self.feuA, [0, 5, 15])
208+
self.assertEqual(scheduler.relative_weights, [0, 0.25, 0.75])
209+
210+
def test_compare_cycle_odd(self):
211+
scheduler = WFQRequestScheduler(self.distQueueA, self.qmmA, self.feuA)
212+
scheduler.max_mhp_cycle_number = 5
213+
scheduler.mhp_cycle_number = 0
214+
215+
cycle1 = 0
216+
cycle2 = 1
217+
218+
for _ in range(scheduler.max_mhp_cycle_number):
219+
print(scheduler._compare_mhp_cycle(cycle1, cycle2))
220+
scheduler.mhp_cycle_number += 1
221+
222+
def test_set_virtual_finish(self):
174223
pass
175224

225+
def test_scheduling(self):
226+
pass
227+
228+
176229

177230
class TestTimings(unittest.TestCase):
178231
def setUp(self):

0 commit comments

Comments
 (0)