limit batchsize of sending from a line

Signed-off-by: Csaba Kiraly <csaba.kiraly@gmail.com>
This commit is contained in:
Csaba Kiraly 2023-02-03 23:07:55 +01:00
parent 07437ddde8
commit eb277d9b43
No known key found for this signature in database
GPG Key ID: 0FE274EE8C95166E
1 changed files with 33 additions and 3 deletions

View File

@ -3,6 +3,7 @@
import random import random
import collections import collections
import logging import logging
import sys
from DAS.block import * from DAS.block import *
from bitarray import bitarray from bitarray import bitarray
from bitarray.util import zeros from bitarray.util import zeros
@ -12,6 +13,34 @@ def shuffled(lis):
for index in random.sample(range(len(lis)), len(lis)): for index in random.sample(range(len(lis)), len(lis)):
yield lis[index] yield lis[index]
def sampleLine(line, limit):
""" sample up to 'limit' bits from a bitarray
Since this is quite expensive, we use a number of heuristics to get it fast.
"""
if limit == sys.maxsize :
return line
else:
w = line.count(1)
if limit >= w :
return line
else:
l = len(line)
r = zeros(l)
if w < l/10 or limit > l/2 :
indices = [ i for i in range(l) if line[i] ]
sample = random.sample(indices, limit)
for i in sample:
r[i] = 1
return r
else:
while limit:
i = random.randrange(0, l)
if line[i] and not r[i]:
r[i] = 1
limit -= 1
return r
class NextToSend: class NextToSend:
def __init__(self, neigh, toSend, id, dim): def __init__(self, neigh, toSend, id, dim):
self.neigh = neigh self.neigh = neigh
@ -177,8 +206,7 @@ class Validator:
self.statsRxInSlot = 0 self.statsRxInSlot = 0
self.statsTxInSlot = 0 self.statsTxInSlot = 0
def nextColumnToSend(self, columnID, limit = sys.maxsize):
def nextColumnToSend(self, columnID):
line = self.getColumn(columnID) line = self.getColumn(columnID)
if line.any(): if line.any():
self.logger.debug("col %d -> %s", columnID, self.columnNeighbors[columnID] , extra=self.format) self.logger.debug("col %d -> %s", columnID, self.columnNeighbors[columnID] , extra=self.format)
@ -187,9 +215,10 @@ class Validator:
# if there is anything new to send, send it # if there is anything new to send, send it
toSend = line & ~n.sent & ~n.received toSend = line & ~n.sent & ~n.received
if (toSend).any(): if (toSend).any():
toSend = sampleLine(toSend, limit)
yield NextToSend(n, toSend, columnID, 1) yield NextToSend(n, toSend, columnID, 1)
def nextRowToSend(self, rowID): def nextRowToSend(self, rowID, limit = sys.maxsize):
line = self.getRow(rowID) line = self.getRow(rowID)
if line.any(): if line.any():
self.logger.debug("row %d -> %s", rowID, self.rowNeighbors[rowID], extra=self.format) self.logger.debug("row %d -> %s", rowID, self.rowNeighbors[rowID], extra=self.format)
@ -198,6 +227,7 @@ class Validator:
# if there is anything new to send, send it # if there is anything new to send, send it
toSend = line & ~n.sent & ~n.received toSend = line & ~n.sent & ~n.received
if (toSend).any(): if (toSend).any():
toSend = sampleLine(toSend, limit)
yield NextToSend(n, toSend, rowID, 0) yield NextToSend(n, toSend, rowID, 0)
def nextToSend(self): def nextToSend(self):