Esempio n. 1
0
def main():
    MAX_CHUNKS = 4
    place_callback = scipy.LowLevelCallable(chunk_place.ctypes,
                                            signature='void (void *, size_t)')
    chunk_config = spead2.recv.ChunkStreamConfig(
        items=[spead2.HEAP_CNT_ID, spead2.HEAP_LENGTH_ID],
        max_chunks=MAX_CHUNKS,
        place=place_callback)
    data_ring = spead2.recv.ChunkRingbuffer(MAX_CHUNKS)
    free_ring = spead2.recv.ChunkRingbuffer(MAX_CHUNKS)
    stream = spead2.recv.ChunkRingStream(spead2.ThreadPool(),
                                         spead2.recv.StreamConfig(),
                                         chunk_config, data_ring, free_ring)
    for i in range(MAX_CHUNKS):
        chunk = spead2.recv.Chunk(present=np.empty(HEAPS_PER_CHUNK, np.uint8),
                                  data=np.empty(CHUNK_PAYLOAD_SIZE, np.uint8))
        stream.add_free_chunk(chunk)
    stream.add_udp_reader(8888,
                          buffer_size=1024 * 1024,
                          bind_hostname='127.0.0.1')
    for chunk in data_ring:
        n_present = np.sum(chunk.present)
        print(f"Received chunk {chunk.chunk_id} with "
              f"{n_present} / {HEAPS_PER_CHUNK} heaps")
        stream.add_free_chunk(chunk)
Esempio n. 2
0
 def test_set_place_bad_signature(self):
     place = scipy.LowLevelCallable(place_plain.ctypes,
                                    signature='void (void)')
     # One might expect TypeError, but ValueError is what scipy uses for
     # invalid signatures.
     with pytest.raises(ValueError):
         recv.ChunkStreamConfig(place=place)
Esempio n. 3
0
    def test_packet_presence(self, data_ring, queue):
        """Test packet presence feature."""
        # Each heap is split into two packets. Create a free ring where the
        # chunks have space for this.
        free_ring = spead2.recv.ChunkRingbuffer(4)
        while not free_ring.full():
            free_ring.put(
                recv.Chunk(present=np.zeros(HEAPS_PER_CHUNK * PACKETS_PER_HEAP,
                                            np.uint8),
                           data=np.zeros(CHUNK_PAYLOAD_SIZE, np.uint8)))

        stream_config = spead2.recv.StreamConfig(max_heaps=128,
                                                 allow_out_of_order=True)
        # Note: user_data is deliberately not assigned to a local variable, so
        # that reference-counting errors are more likely to be detected.
        user_data = np.zeros(1, dtype=user_data_type.dtype)
        user_data["scale"] = PACKETS_PER_HEAP
        user_data["placed_heaps_index"] = stream_config.add_stat(
            "placed_heaps")
        place_bind_llc = scipy.LowLevelCallable(
            place_bind.ctypes,
            user_data=user_data.ctypes.data_as(ctypes.c_void_p),
            signature='void (void *, size_t, void *)')
        stream = spead2.recv.ChunkRingStream(
            spead2.ThreadPool(), stream_config,
            spead2.recv.ChunkStreamConfig(
                items=[
                    0x1000, spead2.HEAP_LENGTH_ID, spead2.PAYLOAD_LENGTH_ID
                ],
                max_chunks=4,
                place=place_bind_llc,
            ).enable_packet_presence(PACKET_SIZE), data_ring, free_ring)
        stream.add_inproc_reader(queue)

        queue.add_packet(self.make_packet(4, 0, PACKET_SIZE))
        queue.add_packet(self.make_packet(4, PACKET_SIZE, 2 * PACKET_SIZE))
        queue.add_packet(self.make_packet(17, PACKET_SIZE, 2 * PACKET_SIZE))
        queue.stop()
        chunks = list(stream.data_ringbuffer)
        assert len(chunks) == 2
        self.check_chunk_packets(
            chunks[0], 0,
            np.array(
                [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                np.uint8))
        self.check_chunk_packets(
            chunks[1], 1,
            np.array(
                [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
                np.uint8))
        assert stream.stats["placed_heaps"] == 2
Esempio n. 4
0
        class ScipyModule:
            """Converts c_capsules into a set of scipy.LowLevelCallable"""

            n = c_capsules.n
            f = scipy.LowLevelCallable(c_capsules.f)
            grad_f = scipy.LowLevelCallable(c_capsules.grad_f)
            g = scipy.LowLevelCallable(c_capsules.g)
            jac_g = scipy.LowLevelCallable(c_capsules.jac_g)
            h = scipy.LowLevelCallable(c_capsules.h)
            intermediate_callback = scipy.LowLevelCallable(
                c_capsules.intermediate_callback)
Esempio n. 5
0
def make_integrand():
    global _integrand
    import numba
    import numba.types as nt
    import scipy

    @numba.cfunc(nt.double(nt.intc, nt.CPointer(nt.double)),
                 nopython=True, nogil=True)
    def _fn(n, xx):
        if n != 4:
            return np.nan
        y = xx[0]
        k = xx[1]
        sigma2 = xx[2]
        z = xx[3]
        return y ** (k/2 - 1) * np.exp(-(k * y + (z-y)**2 / sigma2) / 2)
    _integrand = scipy.LowLevelCallable(_fn.ctypes)
Esempio n. 6
0
def A_x(xi, xi2, h_nodes, num_nodes):
    # From fn_Qx_matrix
    # Notes: the longest in this function is the numerical integration with scipy.integrate.quad.
    # To speed it up, the integrand is compiled with numba. The quad function requires
    # a function f8(f8, voidptr) so the arguments xi, xi2, h_nodes and z, needed for the
    # calculation of the integrand, are packed.

    # integral around branch point
    z_1 = xi2 * h_nodes * np.arange(num_nodes)

    # Pack arguments for LowLevelCallable.
    # data is updated at every loop. The main loop is NOT thread-safe. If the main loop
    # becomes parallel some day, make "data" local.
    data = np.array([xi, xi2, h_nodes, 0.0])
    data_ptr = ctypes.cast(data.ctypes, ctypes.c_void_p)

    quad_args = dict(limit=200)

    # For num_nodes = 4, I_12 looks like [a3, a2, a1, a0, a1, a2, a3] (size: 2*num_nodes-1)
    # Build the second half first, then copy it to the first half
    I_12 = np.zeros(2 * num_nodes - 1, np.complex)
    for i, z in enumerate(z_1):
        data[3] = z

        if i < 2:  # two first iterations, coefficients a0 and a1
            int_F1_real = scipy.LowLevelCallable(A_x_F1_real.ctypes, data_ptr)
            int_F1_imag = scipy.LowLevelCallable(A_x_F1_imag.ctypes, data_ptr)
            int_F2_real = scipy.LowLevelCallable(A_x_F2_real.ctypes, data_ptr)
            int_F2_imag = scipy.LowLevelCallable(A_x_F2_imag.ctypes, data_ptr)
            I_12[i + num_nodes - 1] = 4j * (
                si.quad(int_F1_real, 0, 1, **quad_args)[0] +
                1j * si.quad(int_F1_imag, 0, 1, **quad_args)[0]) + 4 * (
                    si.quad(int_F2_real, 0, 50, **quad_args)[0] +
                    1j * si.quad(int_F2_imag, 0, 50, **quad_args)[0])
        else:
            int_F_real = scipy.LowLevelCallable(A_x_F_real.ctypes, data_ptr)
            int_F_imag = scipy.LowLevelCallable(A_x_F_imag.ctypes, data_ptr)

            I_12[i + num_nodes -
                 1] = 4j * (si.quad(int_F_real, 0, 70, **quad_args)[0] +
                            1j * si.quad(int_F_imag, 0, 70, **quad_args)[0])
    I_12[:num_nodes - 1] = I_12[:num_nodes - 1:-1]

    v_ind = np.arange(num_nodes)
    m_ind = (np.full(
        (num_nodes, num_nodes), num_nodes - 1) + v_ind[:, np.newaxis] - v_ind)
    return I_12[m_ind]
Esempio n. 7
0
def A_z(xi, xi2, h_nodes, num_nodes):
    # from fn_Qz_matrix

    # integral around branch point
    z_1 = xi2 * h_nodes * np.arange(num_nodes)

    # Pack arguments for LowLevelCallable.
    # data is updated at every loop. The main loop is NOT thread-safe. If the main loop
    # becomes parallel some day, make "data" local.
    data = np.array([xi, xi2, h_nodes, 0.0])
    data_ptr = ctypes.cast(data.ctypes, ctypes.c_void_p)

    quad_args = dict(limit=200)

    # For num_nodes = 4, I_12 looks like [a3, a2, a1, a0, a1, a2, a3] (size: 2*num_nodes-1)
    # Build the second half first, then copy it to the first half
    I_12 = np.zeros(2 * num_nodes - 1, np.complex)
    for i, z in enumerate(z_1):
        data[3] = z
        if i < 2:  # two first iterations, coefficients a0 and a1
            int_F1_real = scipy.LowLevelCallable(A_z_F1_real.ctypes, data_ptr)
            int_F1_imag = scipy.LowLevelCallable(A_z_F1_imag.ctypes, data_ptr)
            int_F2_real = scipy.LowLevelCallable(A_z_F2_real.ctypes, data_ptr)
            int_F2_imag = scipy.LowLevelCallable(A_z_F2_imag.ctypes, data_ptr)

            I_12[i + num_nodes - 1] = 4j * (
                si.quad(int_F1_real, 0, sqrt(xi), **quad_args)[0] +
                1j * si.quad(int_F1_imag, 0, sqrt(xi), **quad_args)[0]) + 4 * (
                    si.quad(int_F2_real, 0, 50, **quad_args)[0] +
                    1j * si.quad(int_F2_imag, 0, 50, **quad_args)[0])
        else:
            int_F_real = scipy.LowLevelCallable(A_z_F_real.ctypes, data_ptr)
            int_F_imag = scipy.LowLevelCallable(A_z_F_imag.ctypes, data_ptr)

            I_12[i + num_nodes -
                 1] = 4j * (si.quad(int_F_real, 0, 70, **quad_args)[0] +
                            1j * si.quad(int_F_imag, 0, 70, **quad_args)[0])
    I_12[:num_nodes - 1] = I_12[:num_nodes - 1:-1]

    v_ind = np.arange(num_nodes)
    m_ind = (np.full(
        (num_nodes, num_nodes), num_nodes - 1) + v_ind[:, np.newaxis] - v_ind)
    return I_12[m_ind]
Esempio n. 8
0
    packet_size = items[2]
    user_data = numba.carray(user_data_ptr, 1)
    if payload_size == HEAP_PAYLOAD_SIZE and packet_size == PACKET_SIZE:
        data[0].chunk_id = heap_cnt // HEAPS_PER_CHUNK
        heap_index = heap_cnt % HEAPS_PER_CHUNK
        data[0].heap_index = heap_index * user_data[0].scale
        data[0].heap_offset = heap_index * HEAP_PAYLOAD_SIZE
        batch_stats = numba.carray(intp_to_voidptr(data[0].batch_stats),
                                   user_data[0].placed_heaps_index + 1,
                                   dtype=np.uint64)
        batch_stats[user_data[0].placed_heaps_index] += 1


# ctypes doesn't distinguish equivalent integer types, so we have to
# specify the signature explicitly.
place_plain_llc = scipy.LowLevelCallable(place_plain.ctypes,
                                         signature='void (void *, size_t)')
place_bind_llc = scipy.LowLevelCallable(
    place_bind.ctypes, signature='void (void *, size_t, void *)')


class TestChunkStreamConfig:
    def test_default_construct(self):
        config = recv.ChunkStreamConfig()
        assert config.items == []
        assert config.max_chunks == config.DEFAULT_MAX_CHUNKS
        assert config.place is None
        assert config.packet_presence_payload_size == 0

    def test_zero_max_chunks(self):
        config = recv.ChunkStreamConfig()
        with pytest.raises(ValueError):