Exemple #1
0
def _read_custom_operations(file_obj, version, vectors):
    custom_operations = {}
    custom_definition_header = formats.CUSTOM_CIRCUIT_DEF_HEADER._make(
        struct.unpack(
            formats.CUSTOM_CIRCUIT_DEF_HEADER_PACK,
            file_obj.read(formats.CUSTOM_CIRCUIT_DEF_HEADER_SIZE),
        ))
    if custom_definition_header.size > 0:
        for _ in range(custom_definition_header.size):
            if version < 5:
                data = formats.CUSTOM_CIRCUIT_INST_DEF._make(
                    struct.unpack(
                        formats.CUSTOM_CIRCUIT_INST_DEF_PACK,
                        file_obj.read(formats.CUSTOM_CIRCUIT_INST_DEF_SIZE),
                    ))
            else:
                data = formats.CUSTOM_CIRCUIT_INST_DEF_V2._make(
                    struct.unpack(
                        formats.CUSTOM_CIRCUIT_INST_DEF_V2_PACK,
                        file_obj.read(formats.CUSTOM_CIRCUIT_INST_DEF_V2_SIZE),
                    ))

            name = file_obj.read(data.gate_name_size).decode(common.ENCODE)
            type_str = data.type
            definition_circuit = None
            if data.custom_definition:
                def_binary = file_obj.read(data.size)
                if version < 3 or not name.startswith(
                        r"###PauliEvolutionGate_"):
                    definition_circuit = common.data_from_binary(
                        def_binary, read_circuit, version=version)
                elif name.startswith(r"###PauliEvolutionGate_"):
                    definition_circuit = common.data_from_binary(
                        def_binary,
                        _read_pauli_evolution_gate,
                        version=version,
                        vectors=vectors)
            if version < 5:
                data_payload = (type_str, data.num_qubits, data.num_clbits,
                                definition_circuit)
            else:
                base_gate = file_obj.read(data.base_gate_size)
                data_payload = (
                    type_str,
                    data.num_qubits,
                    data.num_clbits,
                    definition_circuit,
                    data.num_ctrl_qubits,
                    data.ctrl_state,
                    base_gate,
                )
            custom_operations[name] = data_payload
    return custom_operations
Exemple #2
0
def loads_value(type_key, binary_data, version, vectors):
    """Deserialize input binary data to value object.

    Args:
        type_key (ValueTypeKey): Type enum information.
        binary_data (bytes): Data to deserialize.
        version (int): QPY version.
        vectors (dict): ParameterVector in current scope.

    Returns:
        any: Deserialized value object.

    Raises:
        QpyError: Serializer for given format is not ready.
    """
    # pylint: disable=too-many-return-statements

    if isinstance(type_key, bytes):
        type_key = type_keys.Value(type_key)

    if type_key == type_keys.Value.INTEGER:
        return struct.unpack("!q", binary_data)[0]
    if type_key == type_keys.Value.FLOAT:
        return struct.unpack("!d", binary_data)[0]
    if type_key == type_keys.Value.COMPLEX:
        return complex(*struct.unpack(formats.COMPLEX_PACK, binary_data))
    if type_key == type_keys.Value.NUMPY_OBJ:
        return common.data_from_binary(binary_data, np.load)
    if type_key == type_keys.Value.STRING:
        return binary_data.decode(common.ENCODE)
    if type_key == type_keys.Value.NULL:
        return None
    if type_key == type_keys.Value.PARAMETER_VECTOR:
        return common.data_from_binary(binary_data,
                                       _read_parameter_vec,
                                       vectors=vectors)
    if type_key == type_keys.Value.PARAMETER:
        return common.data_from_binary(binary_data, _read_parameter)
    if type_key == type_keys.Value.PARAMETER_EXPRESSION:
        if version < 3:
            return common.data_from_binary(binary_data,
                                           _read_parameter_expression)
        else:
            return common.data_from_binary(binary_data,
                                           _read_parameter_expression_v3,
                                           vectors=vectors)

    raise exceptions.QpyError(
        f"Serialization for {type_key} is not implemented in value I/O.")
Exemple #3
0
def loads_value(type_key, binary_data, version, vectors):
    """Deserialize input binary data to value object.

    Args:
        type_key (ValueTypeKey): Type enum information.
        binary_data (bytes): Data to deserialize.
        version (int): QPY version.
        vectors (dict): ParameterVector in current scope.

    Returns:
        any: Deserialized value object.

    Raises:
        QpyError: Serializer for given format is not ready.
    """
    if isinstance(type_key, bytes):
        type_key = TypeKey(type_key)

    if type_key == TypeKey.INTEGER:
        obj = struct.unpack("!q", binary_data)[0]
    elif type_key == TypeKey.FLOAT:
        obj = struct.unpack("!d", binary_data)[0]
    elif type_key == TypeKey.COMPLEX:
        obj = complex(*struct.unpack(formats.COMPLEX_PACK, binary_data))
    elif type_key == TypeKey.NUMPY_OBJ:
        obj = common.data_from_binary(binary_data, np.load)
    elif type_key == TypeKey.STRING:
        obj = binary_data.decode(ENCODE)
    elif type_key == TypeKey.NULL:
        obj = None
    elif type_key == TypeKey.PARAMETER_VECTOR:
        obj = common.data_from_binary(binary_data,
                                      _read_parameter_vec,
                                      vectors=vectors)
    elif type_key == TypeKey.PARAMETER:
        obj = common.data_from_binary(binary_data, _read_parameter)
    elif type_key == TypeKey.PARAMETER_EXPRESSION:
        if version < 3:
            obj = common.data_from_binary(binary_data,
                                          _read_parameter_expression)
        else:
            obj = common.data_from_binary(binary_data,
                                          _read_parameter_expression_v3,
                                          vectors=vectors)
    else:
        raise exceptions.QpyError(
            f"Serialization for {type_key} is not implemented in value I/O.")

    return obj
def _loads_operand(type_key, data_bytes, version):
    if type_key == type_keys.ScheduleOperand.WAVEFORM:
        return common.data_from_binary(data_bytes,
                                       _read_waveform,
                                       version=version)
    if type_key == type_keys.ScheduleOperand.SYMBOLIC_PULSE:
        return common.data_from_binary(data_bytes,
                                       _read_symbolic_pulse,
                                       version=version)
    if type_key == type_keys.ScheduleOperand.CHANNEL:
        return common.data_from_binary(data_bytes,
                                       _read_channel,
                                       version=version)

    return value.loads_value(type_key, data_bytes, version, {})
Exemple #5
0
def _read_instruction_parameter(file_obj, version, vectors):
    type_key, bin_data = common.read_instruction_param(file_obj)

    if type_key == common.ProgramTypeKey.CIRCUIT:
        param = common.data_from_binary(bin_data,
                                        read_circuit,
                                        version=version)
    elif type_key == common.ContainerTypeKey.RANGE:
        data = formats.RANGE._make(struct.unpack(formats.RANGE_PACK, bin_data))
        param = range(data.start, data.stop, data.step)
    elif type_key == common.ContainerTypeKey.TUPLE:
        param = tuple(
            common.sequence_from_binary(
                bin_data,
                _read_instruction_parameter,
                version=version,
                vectors=vectors,
            ))
    elif type_key == common.ValueTypeKey.INTEGER:
        # TODO This uses little endian. Should be fixed in the next QPY version.
        param = struct.unpack("<q", bin_data)[0]
    elif type_key == common.ValueTypeKey.FLOAT:
        # TODO This uses little endian. Should be fixed in the next QPY version.
        param = struct.unpack("<d", bin_data)[0]
    else:
        param = value.loads_value(type_key, bin_data, version, vectors)

    return param
Exemple #6
0
def _loads_instruction_parameter(type_key, data_bytes, version, vectors):
    if type_key == type_keys.Program.CIRCUIT:
        param = common.data_from_binary(data_bytes,
                                        read_circuit,
                                        version=version)
    elif type_key == type_keys.Container.RANGE:
        data = formats.RANGE._make(
            struct.unpack(formats.RANGE_PACK, data_bytes))
        param = range(data.start, data.stop, data.step)
    elif type_key == type_keys.Container.TUPLE:
        param = tuple(
            common.sequence_from_binary(
                data_bytes,
                _loads_instruction_parameter,
                version=version,
                vectors=vectors,
            ))
    elif type_key == type_keys.Value.INTEGER:
        # TODO This uses little endian. Should be fixed in the next QPY version.
        param = struct.unpack("<q", data_bytes)[0]
    elif type_key == type_keys.Value.FLOAT:
        # TODO This uses little endian. Should be fixed in the next QPY version.
        param = struct.unpack("<d", data_bytes)[0]
    else:
        param = value.loads_value(type_key, data_bytes, version, vectors)

    return param
Exemple #7
0
def _read_parameter_expression_v3(file_obj, vectors):
    data = formats.PARAMETER_EXPR(
        *struct.unpack(formats.PARAMETER_EXPR_PACK,
                       file_obj.read(formats.PARAMETER_EXPR_SIZE)))
    from sympy.parsing.sympy_parser import parse_expr

    if _optional.HAS_SYMENGINE:
        import symengine

        expr = symengine.sympify(
            parse_expr(file_obj.read(data.expr_size).decode(common.ENCODE)))
    else:
        expr = parse_expr(file_obj.read(data.expr_size).decode(common.ENCODE))
    symbol_map = {}
    for _ in range(data.map_elements):
        elem_data = formats.PARAM_EXPR_MAP_ELEM_V3(*struct.unpack(
            formats.PARAM_EXPR_MAP_ELEM_V3_PACK,
            file_obj.read(formats.PARAM_EXPR_MAP_ELEM_V3_SIZE),
        ))
        symbol_key = type_keys.Value(elem_data.symbol_type)

        if symbol_key == type_keys.Value.PARAMETER:
            symbol = _read_parameter(file_obj)
        elif symbol_key == type_keys.Value.PARAMETER_VECTOR:
            symbol = _read_parameter_vec(file_obj, vectors)
        else:
            raise exceptions.QpyError(
                "Invalid parameter expression map type: %s" % symbol_key)

        elem_key = type_keys.Value(elem_data.type)
        binary_data = file_obj.read(elem_data.size)
        if elem_key == type_keys.Value.INTEGER:
            value = struct.unpack("!q", binary_data)
        elif elem_key == type_keys.Value.FLOAT:
            value = struct.unpack("!d", binary_data)
        elif elem_key == type_keys.Value.COMPLEX:
            value = complex(*struct.unpack(formats.COMPLEX_PACK, binary_data))
        elif elem_key in (type_keys.Value.PARAMETER,
                          type_keys.Value.PARAMETER_VECTOR):
            value = symbol._symbol_expr
        elif elem_key == type_keys.Value.PARAMETER_EXPRESSION:
            value = common.data_from_binary(binary_data,
                                            _read_parameter_expression_v3,
                                            vectors=vectors)
        else:
            raise exceptions.QpyError(
                "Invalid parameter expression map type: %s" % elem_key)
        symbol_map[symbol] = value

    return ParameterExpression(symbol_map, expr)
def _read_waveform(file_obj, version):
    header = formats.WAVEFORM._make(
        struct.unpack(
            formats.WAVEFORM_PACK,
            file_obj.read(formats.WAVEFORM_SIZE),
        ))
    samples_raw = file_obj.read(header.data_size)
    samples = common.data_from_binary(samples_raw, np.load)
    name = value.read_value(file_obj, version, {})

    return library.Waveform(
        samples=samples,
        name=name,
        epsilon=header.epsilon,
        limit_amplitude=header.amp_limited,
    )
Exemple #9
0
def _read_pauli_evolution_gate(file_obj, version, vectors):
    pauli_evolution_def = formats.PAULI_EVOLUTION_DEF._make(
        struct.unpack(formats.PAULI_EVOLUTION_DEF_PACK,
                      file_obj.read(formats.PAULI_EVOLUTION_DEF_SIZE)))
    if pauli_evolution_def.operator_size != 1 and pauli_evolution_def.standalone_op:
        raise ValueError(
            "Can't have a standalone operator with {pauli_evolution_raw[0]} operators in the payload"
        )

    operator_list = []
    for _ in range(pauli_evolution_def.operator_size):
        op_elem = formats.SPARSE_PAULI_OP_LIST_ELEM._make(
            struct.unpack(
                formats.SPARSE_PAULI_OP_LIST_ELEM_PACK,
                file_obj.read(formats.SPARSE_PAULI_OP_LIST_ELEM_SIZE),
            ))
        op_raw_data = common.data_from_binary(file_obj.read(op_elem.size),
                                              np.load)
        operator_list.append(SparsePauliOp.from_list(op_raw_data))

    if pauli_evolution_def.standalone_op:
        pauli_op = operator_list[0]
    else:
        pauli_op = operator_list

    time = value.loads_value(
        common.ValueTypeKey(pauli_evolution_def.time_type),
        file_obj.read(pauli_evolution_def.time_size),
        version=version,
        vectors=vectors,
    )
    synth_data = json.loads(
        file_obj.read(pauli_evolution_def.synth_method_size))
    synthesis = getattr(evo_synth,
                        synth_data["class"])(**synth_data["settings"])
    return_gate = library.PauliEvolutionGate(pauli_op,
                                             time=time,
                                             synthesis=synthesis)
    return return_gate