def test_complex_gate_optimization(complex_gate, complex_gate_opt):
    """Make sure the optimized version runs identically to the unoptimized."""

    sg, sg_opt = complex_gate, complex_gate_opt

    sim1 = SensorGraphSimulator(sg)
    sim1.stop_condition("run_time 10 minutes")

    sg.load_constants()
    sim1.record_trace()
    sim1.run()

    sim2 = SensorGraphSimulator(sg_opt)
    sim2.stop_condition("run_time 10 minutes")

    sg_opt.load_constants()
    sim2.record_trace()
    sim2.run()

    assert len(sim1.trace) == 0
    assert len(sim2.trace) == 0

    sim1.step(DataStream.FromString("system input 1034"), 1)
    sim2.step(DataStream.FromString("system input 1034"), 1)

    sim1.run()
    sim2.run()

    print("Unoptimized Output")
    for x in sim1.trace:
        print("%08d %s: %d" %
              (x.raw_time, DataStream.FromEncoded(x.stream), x.value))

    print("\nOptimized Output")
    for x in sim2.trace:
        print("%08d %s: %d" %
              (x.raw_time, DataStream.FromEncoded(x.stream), x.value))

    assert len(sim1.trace) == 4
    assert len(sim2.trace) == 4
    assert sim1.trace == sim2.trace

    #Check that number of trigger streamer commands is same for optimized and unoptimized
    trigger_nodes = [
        node for node in complex_gate.nodes
        if node.func_name == 'trigger_streamer'
    ]
    trigger_nodes_opt = [
        node for node in complex_gate_opt.nodes
        if node.func_name == 'trigger_streamer'
    ]

    assert len(trigger_nodes) == len(trigger_nodes_opt)
Example #2
0
    def inspect_virtual(self, stream_id):
        """Inspect the last value written into a virtual stream.

        Args:
            stream_id (int): The virtual stream was want to inspect.

        Returns:
            (int, int): An error code and the stream value.
        """

        stream = DataStream.FromEncoded(stream_id)

        if stream.buffered:
            return [
                pack_error(ControllerSubsystem.SENSOR_LOG,
                           SensorLogError.VIRTUAL_STREAM_NOT_FOUND), 0
            ]

        try:
            reading = self.storage.inspect_last(stream, only_allocated=True)
            return [Error.NO_ERROR, reading.value]
        except StreamEmptyError:
            return [Error.NO_ERROR, 0]
        except UnresolvedIdentifierError:
            return [
                pack_error(ControllerSubsystem.SENSOR_LOG,
                           SensorLogError.VIRTUAL_STREAM_NOT_FOUND), 0
            ]
Example #3
0
def stream_name(stream_id):
    """Map a stream id to a human readable name.

    The mapping process is as follows:

    If the stream id is globally known, its global name is used as <name>
    otherwise a string representation of the stream is used as <name>.

    In both cases the hex representation of the stream id is appended as a
    number:

    <name> (0x<stream id in hex>)

    Args:
        stream_id (int): An integer stream id.

    Returns:
        str: The nice name of the stream.
    """

    name = _STREAM_NAME_MAP.get(stream_id)
    if name is None:
        name = str(DataStream.FromEncoded(stream_id))

    return "{} (0x{:04X})".format(name, stream_id)
Example #4
0
    def FromBinary(cls, record_data, record_count=1):
        """Create an UpdateRecord subclass from binary record data.

        This should be called with a binary record blob (NOT including the
        record type header) and it will decode it into a SetConstantRecord.

        Args:
            record_data (bytearray): The raw record data that we wish to parse
                into an UpdateRecord subclass NOT including its 8 byte record header.
            record_count (int): The number of records included in record_data.

        Raises:
            ArgumentError: If the record_data is malformed and cannot be parsed.

        Returns:
            SetConstantRecord: The decoded reflash tile record.
        """

        _cmd, address, _resp_length, payload = cls._parse_rpc_info(record_data)

        try:
            value, encoded_stream = struct.unpack("<LH", payload)
            stream = DataStream.FromEncoded(encoded_stream)
        except ValueError:
            raise ArgumentError("Could not parse set_constant payload",
                                payload=payload)

        return SetConstantRecord(stream, value, address=address)
Example #5
0
    def count_matching(self, selector, offset=0):
        """Count the number of readings matching selector.

        Args:
            selector (DataStreamSelector): The selector that we want to
                count matching readings for.
            offset (int): The starting offset that we should begin counting at.

        Returns:
            int: The number of matching readings.
        """

        if selector.output:
            data = self.streaming_data
        elif selector.buffered:
            data = self.storage_data
        else:
            raise ArgumentError(
                "You can only pass a buffered selector to count_matching",
                selector=selector)

        count = 0
        for i in range(offset, len(data)):
            reading = data[i]

            stream = DataStream.FromEncoded(reading.stream)
            if selector.matches(stream):
                count += 1

        return count
def test_user_tick_optimization(usertick_gate, usertick_gate_opt):
    """Make sure the optimized version runs identically to the unoptimized."""

    sg, sg_opt = usertick_gate, usertick_gate_opt

    for node in sg_opt.nodes:
        print(node)

    sim1 = SensorGraphSimulator(sg)
    sim1.stop_condition("run_time 10 minutes")

    sg.load_constants()
    sim1.record_trace()
    sim1.run()

    sim2 = SensorGraphSimulator(sg_opt)
    sim2.stop_condition("run_time 10 minutes")

    sg_opt.load_constants()
    sim2.record_trace()
    sim2.run()

    assert len(sim1.trace) == 0
    assert len(sim2.trace) == 0

    sim1.step(DataStream.FromString("system input 1034"), 1)
    sim2.step(DataStream.FromString("system input 1034"), 1)

    sim1.run()
    sim2.run()

    print("Unoptimized Output")
    for x in sim1.trace:
        print("%08d %s: %d" %
              (x.raw_time, DataStream.FromEncoded(x.stream), x.value))

    print("\nOptimized Output")
    for x in sim2.trace:
        print("%08d %s: %d" %
              (x.raw_time, DataStream.FromEncoded(x.stream), x.value))

    assert len(sim1.trace) == 4
    assert len(sim2.trace) == 4
    assert sim1.trace == sim2.trace
Example #7
0
    def process_input(self, encoded_stream, value):
        """Process or drop a graph input.

        This must not be called directly from an RPC but always via a deferred
        task.
        """

        if not self.enabled:
            return

        stream = DataStream.FromEncoded(encoded_stream)
        reading = IOTileReading(self.get_timestamp(), encoded_stream, value)

        self.graph.process_input(stream, reading, None)  #FIXME: add in an rpc executor for this device.

        self.process_streamers()
Example #8
0
    def push(self, value):
        """Store a new value for the given stream.

        Args:
            value (IOTileReading): The value to store.  The stream
                parameter must have the correct value
        """

        stream = DataStream.FromEncoded(value.stream)

        if stream.stream_type == DataStream.OutputType:
            if len(self.streaming_data) == self.streaming_length:
                raise StorageFullError('Streaming buffer full')

            self.streaming_data.append(value)
        else:
            if len(self.storage_data) == self.storage_length:
                raise StorageFullError('Storage buffer full')

            self.storage_data.append(value)
Example #9
0
    def push(self, stream_id, timestamp, value):
        """Push a value to a stream.

        Args:
            stream_id (int): The stream we want to push to.
            timestamp (int): The raw timestamp of the value we want to
                store.
            value (int): The 32-bit integer value we want to push.
        Returns:
            int: Packed 32-bit error code.
        """

        stream = DataStream.FromEncoded(stream_id)
        reading = IOTileReading(stream_id, timestamp, value)

        try:
            self.storage.push(stream, reading)

            return Error.NO_ERROR
        except StorageFullError:
            return pack_error(ControllerSubsystem.SENSOR_LOG, SensorLogError.RING_BUFFER_FULL)
Example #10
0
    def process_input(self, encoded_stream, value):
        """Process or drop a graph input.

        This method asynchronously queued an item to be processed by the
        sensorgraph worker task in _reset_vector.  It must be called from
        inside the emulation loop and returns immediately before the input is
        processed.
        """

        if not self.enabled:
            return

        if isinstance(encoded_stream, str):
            stream = DataStream.FromString(encoded_stream)
            encoded_stream = stream.encode()
        elif isinstance(encoded_stream, DataStream):
            stream = encoded_stream
            encoded_stream = stream.encode()
        else:
            stream = DataStream.FromEncoded(encoded_stream)

        reading = IOTileReading(self.get_timestamp(), encoded_stream, value)

        self._inputs.put_nowait((stream, reading))