def _get_image_depth(self):
        """Get depth information for the circuit.

        Returns:
            int: number of columns in the circuit
            int: total size of columns in the circuit
        """

        max_column_widths = []

        for layer in self.ops:

            # store the max width for the layer
            current_max = 0

            for op in layer:

                # update current op width
                arg_str_len = 0

                # the wide gates
                for arg in op.op.params:
                    arg_str = re.sub(r'[-+]?\d*\.\d{2,}|\d{2,}',
                                     _truncate_float, str(arg))
                    arg_str_len += len(arg_str)

                # the width of the column is the max of all the gates in the column
                current_max = max(arg_str_len, current_max)

            max_column_widths.append(current_max)

        # wires in the beginning and end
        columns = 2
        # each layer is one column
        columns += len(self.ops)

        # every 3 characters is roughly one extra 'unit' of width in the cell
        # the gate name is 1 extra 'unit'
        # the qubit/cbit labels plus initial states is 2 more
        # the wires poking out at the ends is 2 more
        sum_column_widths = sum(1 + v / 3 for v in max_column_widths)

        # could be a fraction so ceil
        return columns, math.ceil(sum_column_widths) + 4

def _get_image_depth ( self ) : max_column_widths = [ ] for layer in self . ops : current_max = 0 for op in layer : arg_str_len = 0 for arg in op . op . params : arg_str = re . sub ( r'[-+]?\d*\.\d{2,}|\d{2,}' , _truncate_float , str ( arg ) ) arg_str_len += len ( arg_str ) current_max = max ( arg_str_len , current_max ) max_column_widths . append ( current_max ) columns = 2 columns += len ( self . ops ) sum_column_widths = sum ( 1 + v / 3 for v in max_column_widths ) return columns , math . ceil ( sum_column_widths ) + 4


def _get_beamer_page(self):
        """Get height, width & scale attributes for the beamer page.

        Returns:
            tuple: (height, width, scale) desirable page attributes
        """
        # PIL python package limits image size to around a quarter gigabyte
        # this means the beamer image should be limited to < 50000
        # if you want to avoid a "warning" too, set it to < 25000
        PIL_limit = 40000

        # the beamer latex template limits each dimension to < 19 feet
        # (i.e. 575cm)
        beamer_limit = 550

        # columns are roughly twice as big as rows
        aspect_ratio = self.sum_row_heights / self.sum_column_widths

        # choose a page margin so circuit is not cropped
        margin_factor = 1.5
        height = min(self.sum_row_heights * margin_factor, beamer_limit)
        width = min(self.sum_column_widths * margin_factor, beamer_limit)

        # if too large, make it fit
        if height * width > PIL_limit:
            height = min(np.sqrt(PIL_limit * aspect_ratio), beamer_limit)
            width = min(np.sqrt(PIL_limit / aspect_ratio), beamer_limit)

        # if too small, give it a minimum size
        height = max(height, 10)
        width = max(width, 10)

        return (height, width, self.scale)

def _get_beamer_page ( self ) : PIL_limit = 40000 beamer_limit = 550 aspect_ratio = self . sum_row_heights / self . sum_column_widths margin_factor = 1.5 height = min ( self . sum_row_heights * margin_factor , beamer_limit ) width = min ( self . sum_column_widths * margin_factor , beamer_limit ) if height * width > PIL_limit : height = min ( np . sqrt ( PIL_limit * aspect_ratio ) , beamer_limit ) width = min ( np . sqrt ( PIL_limit / aspect_ratio ) , beamer_limit ) height = max ( height , 10 ) width = max ( width , 10 ) return ( height , width , self . scale )

Get height width & scale attributes for the beamer page .


def _load_schema(file_path, name=None):
    """Loads the QObj schema for use in future validations.

   Caches schema in _SCHEMAS module attribute.

   Args:
        file_path(str): Path to schema.
        name(str): Given name for schema. Defaults to file_path filename
            without schema.
   Return:
        schema(dict): Loaded schema.
    """
    if name is None:
        # filename without extension
        name = os.path.splitext(os.path.basename(file_path))[0]
    if name not in _SCHEMAS:
        with open(file_path, 'r') as schema_file:
            _SCHEMAS[name] = json.load(schema_file)

    return _SCHEMAS[name]

def _load_schema ( file_path , name = None ) : if name is None : name = os . path . splitext ( os . path . basename ( file_path ) ) [ 0 ] if name not in _SCHEMAS : with open ( file_path , 'r' ) as schema_file : _SCHEMAS [ name ] = json . load ( schema_file ) return _SCHEMAS [ name ]

Loads the QObj schema for use in future validations .


def _get_validator(name, schema=None, check_schema=True,
                   validator_class=None, **validator_kwargs):
    """Generate validator for JSON schema.

    Args:
        name (str): Name for validator. Will be validator key in
            `_VALIDATORS` dict.
        schema (dict): JSON schema `dict`. If not provided searches for schema
            in `_SCHEMAS`.
        check_schema (bool): Verify schema is valid.
        validator_class (jsonschema.IValidator): jsonschema IValidator instance.
            Default behavior is to determine this from the schema `$schema`
            field.
        **validator_kwargs (dict): Additional keyword arguments for validator.

    Return:
        jsonschema.IValidator: Validator for JSON schema.

    Raises:
        SchemaValidationError: Raised if validation fails.
    """
    if schema is None:
        try:
            schema = _SCHEMAS[name]
        except KeyError:
            raise SchemaValidationError("Valid schema name or schema must "
                                        "be provided.")

    if name not in _VALIDATORS:

        # Resolve JSON spec from schema if needed
        if validator_class is None:
            validator_class = jsonschema.validators.validator_for(schema)

        # Generate and store validator in _VALIDATORS
        _VALIDATORS[name] = validator_class(schema, **validator_kwargs)

    validator = _VALIDATORS[name]

    if check_schema:
        validator.check_schema(schema)

    return validator

def
_get_validator
(
name
,
schema
=
,
check_schema
=
True
,
validator_class
=
,
**
validator_kwargs
)
:
if
schema
is
:
try
:
schema
=
_SCHEMAS
[
name
]
except
KeyError
:
raise
SchemaValidationError
(
"Valid schema name or schema must "
"be provided."
)
if
name
not
in
_VALIDATORS
:
if
validator_class
is
:
validator_class
=
jsonschema
.
validators
.
validator_for
(
schema
)
_VALIDATORS
[
name
]
=
validator_class
(
schema
,
**
validator_kwargs
)
validator
=
_VALIDATORS
[
name
]
if
check_schema
:
validator
.
check_schema
(
schema
)
return
validator


def _load_schemas_and_validators():
    """Load all default schemas into `_SCHEMAS`."""
    schema_base_path = os.path.join(os.path.dirname(__file__), '../..')
    for name, path in _DEFAULT_SCHEMA_PATHS.items():
        _load_schema(os.path.join(schema_base_path, path), name)
        _get_validator(name)

def _load_schemas_and_validators ( ) : schema_base_path = os . path . join ( os . path . dirname ( __file__ ) , '../..' ) for name , path in _DEFAULT_SCHEMA_PATHS . items ( ) : _load_schema ( os . path . join ( schema_base_path , path ) , name ) _get_validator ( name )

Load all default schemas into _SCHEMAS .


def validate_json_against_schema(json_dict, schema,
                                 err_msg=None):
    """Validates JSON dict against a schema.

    Args:
        json_dict (dict): JSON to be validated.
        schema (dict or str): JSON schema dictionary or the name of one of the
            standards schemas in Qiskit to validate against it. The list of
            standard schemas is: ``backend_configuration``,
            ``backend_properties``, ``backend_status``,
            ``default_pulse_configuration``, ``job_status``, ``qobj``,
            ``result``.
        err_msg (str): Optional error message.

    Raises:
        SchemaValidationError: Raised if validation fails.
    """

    try:
        if isinstance(schema, str):
            schema_name = schema
            schema = _SCHEMAS[schema_name]
            validator = _get_validator(schema_name)
            validator.validate(json_dict)
        else:
            jsonschema.validate(json_dict, schema)
    except jsonschema.ValidationError as err:
        if err_msg is None:
            err_msg = "JSON failed validation. Set Qiskit log level to DEBUG " \
                      "for further information."
        newerr = SchemaValidationError(err_msg)
        newerr.__cause__ = _SummaryValidationError(err)
        logger.debug('%s', _format_causes(err))
        raise newerr


def _format_causes(err, level=0):
    """Return a cascading explanation of the validation error.

    Returns a cascading explanation of the validation error in the form of::

        <validator> failed @ <subfield_path> because of:
            <validator> failed @ <subfield_path> because of:
                ...
            <validator> failed @ <subfield_path> because of:
                ...
            ...

    For example::

        'oneOf' failed @ '<root>' because of:
            'required' failed @ '<root>.config' because of:
                'meas_level' is a required property

    Meaning the validator 'oneOf' failed while validating the whole object
    because of the validator 'required' failing while validating the property
    'config' because its 'meas_level' field is missing.

    The cascade repeats the format "<validator> failed @ <path> because of"
    until there are no deeper causes. In this case, the string representation
    of the error is shown.

    Args:
        err (jsonschema.ValidationError): the instance to explain.
        level (int): starting level of indentation for the cascade of
            explanations.

    Return:
        str: a formatted string with the explanation of the error.

    """
    lines = []

    def _print(string, offset=0):
        lines.append(_pad(string, offset=offset))

    def _pad(string, offset=0):
        padding = '  ' * (level + offset)
        padded_lines = [padding + line for line in string.split('\n')]
        return '\n'.join(padded_lines)

    def _format_path(path):
        def _format(item):
            if isinstance(item, str):
                return '.{}'.format(item)

            return '[{}]'.format(item)

        return ''.join(['<root>'] + list(map(_format, path)))

    _print('\'{}\' failed @ \'{}\' because of:'.format(
        err.validator, _format_path(err.absolute_path)))

    if not err.context:
        _print(str(err.message), offset=1)
    else:
        for suberr in err.context:
            lines.append(_format_causes(suberr, level+1))

    return '\n'.join(lines)

def
_format_causes
(
err
,
level
=
0
)
:
lines
=
[
]
def
_print
(
string
,
offset
=
0
)
:
lines
.
append
(
_pad
(
string
,
offset
=
offset
)
)
def
_pad
(
string
,
offset
=
0
)
:
padding
=
'  '
*
(
level
+
offset
)
padded_lines
=
[
padding
+
line
for
line
in
string
.
split
(
'\n'
)
]
return
'\n'
.
join
(
padded_lines
)
def
_format_path
(
path
)
:
def
_format
(
item
)
:
if
isinstance
(
item
,
str
)
:
return
'.{}'
.
format
(
item
)
return
'[{}]'
.
format
(
item
)
return
''
.
join
(
[
'<root>'
]
+
list
(
map
(
_format
,
path
)
)
)
_print
(
'\'{}\' failed @ \'{}\' because of:'
.
format
(
err
.
validator
,
_format_path
(
err
.
absolute_path
)
)
)
if
not
err
.
context
:
_print
(
str
(
err
.
message
)
,
offset
=
1
)
else
:
for
suberr
in
err
.
context
:
lines
.
append
(
_format_causes
(
suberr
,
level
+
1
)
)
return
'\n'
.
join
(
lines
)

Return a cascading explanation of the validation error .


def majority(p, a, b, c):
    """Majority gate."""
    p.cx(c, b)
    p.cx(c, a)
    p.ccx(a, b, c)

def majority ( p , a , b , c ) : p . cx ( c , b ) p . cx ( c , a ) p . ccx ( a , b , c )


def unmajority(p, a, b, c):
    """Unmajority gate."""
    p.ccx(a, b, c)
    p.cx(c, a)
    p.cx(a, b)

def unmajority ( p , a , b , c ) : p . ccx ( a , b , c ) p . cx ( c , a ) p . cx ( a , b )


def _generate_latex_source(circuit, filename=None,
                           scale=0.7, style=None, reverse_bits=False,
                           plot_barriers=True, justify=None):
    """Convert QuantumCircuit to LaTeX string.

    Args:
        circuit (QuantumCircuit): input circuit
        scale (float): image scaling
        filename (str): optional filename to write latex
        style (dict or str): dictionary of style or file name of style file
        reverse_bits (bool): When set to True reverse the bit order inside
            registers for the output visualization.
        plot_barriers (bool): Enable/disable drawing barriers in the output
            circuit. Defaults to True.
        justify (str) : `left`, `right` or `none`. Defaults to `left`. Says how
                        the circuit should be justified.

    Returns:
        str: Latex string appropriate for writing to file.
    """
    qregs, cregs, ops = utils._get_layered_instructions(circuit,
                                                        reverse_bits=reverse_bits,
                                                        justify=justify)

    qcimg = _latex.QCircuitImage(qregs, cregs, ops, scale, style=style,
                                 plot_barriers=plot_barriers,
                                 reverse_bits=reverse_bits)
    latex = qcimg.latex()
    if filename:
        with open(filename, 'w') as latex_file:
            latex_file.write(latex)

    return latex

def _generate_latex_source ( circuit , filename = None , scale = 0.7 , style = None , reverse_bits = False , plot_barriers = True , justify = None ) : qregs , cregs , ops = utils . _get_layered_instructions ( circuit , reverse_bits = reverse_bits , justify = justify ) qcimg = _latex . QCircuitImage ( qregs , cregs , ops , scale , style = style , plot_barriers = plot_barriers , reverse_bits = reverse_bits ) latex = qcimg . latex ( ) if filename : with open ( filename , 'w' ) as latex_file : latex_file . write ( latex ) return latex

Convert QuantumCircuit to LaTeX string .


def _matplotlib_circuit_drawer(circuit,
                               scale=0.7,
                               filename=None,
                               style=None,
                               plot_barriers=True,
                               reverse_bits=False,
                               justify=None):
    """Draw a quantum circuit based on matplotlib.
    If `%matplotlib inline` is invoked in a Jupyter notebook, it visualizes a circuit inline.
    We recommend `%config InlineBackend.figure_format = 'svg'` for the inline visualization.

    Args:
        circuit (QuantumCircuit): a quantum circuit
        scale (float): scaling factor
        filename (str): file path to save image to
        style (dict or str): dictionary of style or file name of style file
        reverse_bits (bool): When set to True reverse the bit order inside
            registers for the output visualization.
        plot_barriers (bool): Enable/disable drawing barriers in the output
            circuit. Defaults to True.
        justify (str) : `left`, `right` or `none`. Defaults to `left`. Says how
            the circuit should be justified.

    Returns:
        matplotlib.figure: a matplotlib figure object for the circuit diagram
    """

    qregs, cregs, ops = utils._get_layered_instructions(circuit,
                                                        reverse_bits=reverse_bits,
                                                        justify=justify)
    qcd = _matplotlib.MatplotlibDrawer(qregs, cregs, ops, scale=scale, style=style,
                                       plot_barriers=plot_barriers,
                                       reverse_bits=reverse_bits)
    return qcd.draw(filename)

def _matplotlib_circuit_drawer ( circuit , scale = 0.7 , filename = None , style = None , plot_barriers = True , reverse_bits = False , justify = None ) : qregs , cregs , ops = utils . _get_layered_instructions ( circuit , reverse_bits = reverse_bits , justify = justify ) qcd = _matplotlib . MatplotlibDrawer ( qregs , cregs , ops , scale = scale , style = style , plot_barriers = plot_barriers , reverse_bits = reverse_bits ) return qcd . draw ( filename )

Draw a quantum circuit based on matplotlib . If %matplotlib inline is invoked in a Jupyter notebook it visualizes a circuit inline . We recommend %config InlineBackend . figure_format = svg for the inline visualization .


def random_unitary(dim, seed=None):
    """
    Return a random dim x dim unitary Operator from the Haar measure.

    Args:
        dim (int): the dim of the state space.
        seed (int): Optional. To set a random seed.

    Returns:
        Operator: (dim, dim) unitary operator.

    Raises:
        QiskitError: if dim is not a positive power of 2.
    """
    if dim == 0 or not math.log2(dim).is_integer():
        raise QiskitError("Desired unitary dimension not a positive power of 2.")
    matrix = np.zeros([dim, dim], dtype=complex)
    for j in range(dim):
        if j == 0:
            a = random_state(dim, seed)
        else:
            a = random_state(dim)
        matrix[:, j] = np.copy(a)
        # Grahm-Schmidt Orthogonalize
        i = j-1
        while i >= 0:
            dc = np.vdot(matrix[:, i], a)
            matrix[:, j] = matrix[:, j]-dc*matrix[:, i]
            i = i - 1
        # normalize
        matrix[:, j] = matrix[:, j] * (1.0 / np.sqrt(np.vdot(matrix[:, j], matrix[:, j])))
    return Operator(matrix)

Return a random dim x dim unitary Operator from the Haar measure .


def random_density_matrix(length, rank=None, method='Hilbert-Schmidt', seed=None):
    """
    Generate a random density matrix rho.

    Args:
        length (int): the length of the density matrix.
        rank (int or None): the rank of the density matrix. The default
            value is full-rank.
        method (string): the method to use.
            'Hilbert-Schmidt': sample rho from the Hilbert-Schmidt metric.
            'Bures': sample rho from the Bures metric.
        seed (int): Optional. To set a random seed.
    Returns:
        ndarray: rho (length, length) a density matrix.
    Raises:
        QiskitError: if the method is not valid.
    """
    if method == 'Hilbert-Schmidt':
        return __random_density_hs(length, rank, seed)
    elif method == 'Bures':
        return __random_density_bures(length, rank, seed)
    else:
        raise QiskitError('Error: unrecognized method {}'.format(method))

def
random_density_matrix
(
length
,
rank
=
,
method
=
'Hilbert-Schmidt'
,
seed
=
)
:
if
method
==
'Hilbert-Schmidt'
:
return
__random_density_hs
(
length
,
rank
,
seed
)
elif
method
==
'Bures'
:
return
__random_density_bures
(
length
,
rank
,
seed
)
else
:
raise
QiskitError
(
'Error: unrecognized method {}'
.
format
(
method
)
)


def __ginibre_matrix(nrow, ncol=None, seed=None):
    """
    Return a normally distributed complex random matrix.

    Args:
        nrow (int): number of rows in output matrix.
        ncol (int): number of columns in output matrix.
        seed (int): Optional. To set a random seed.
    Returns:
        ndarray: A complex rectangular matrix where each real and imaginary
            entry is sampled from the normal distribution.
    """
    if ncol is None:
        ncol = nrow
    if seed is not None:
        np.random.seed(seed)
    G = np.random.normal(size=(nrow, ncol)) + \
        np.random.normal(size=(nrow, ncol)) * 1j
    return G

def __ginibre_matrix ( nrow , ncol = None , seed = None ) : if ncol is None : ncol = nrow if seed is not None : np . random . seed ( seed ) G = np . random . normal ( size = ( nrow , ncol ) ) + np . random . normal ( size = ( nrow , ncol ) ) * 1j return G

Return a normally distributed complex random matrix .


def __random_density_hs(N, rank=None, seed=None):
    """
    Generate a random density matrix from the Hilbert-Schmidt metric.

    Args:
        N (int): the length of the density matrix.
        rank (int or None): the rank of the density matrix. The default
            value is full-rank.
        seed (int): Optional. To set a random seed.
    Returns:
        ndarray: rho (N,N  a density matrix.
    """
    G = __ginibre_matrix(N, rank, seed)
    G = G.dot(G.conj().T)
    return G / np.trace(G)

def __random_density_hs ( N , rank = None , seed = None ) : G = __ginibre_matrix ( N , rank , seed ) G = G . dot ( G . conj ( ) . T ) return G / np . trace ( G )

Generate a random density matrix from the Hilbert - Schmidt metric .


def __random_density_bures(N, rank=None, seed=None):
    """
    Generate a random density matrix from the Bures metric.

    Args:
        N (int): the length of the density matrix.
        rank (int or None): the rank of the density matrix. The default
            value is full-rank.
        seed (int): Optional. To set a random seed.
    Returns:
        ndarray: rho (N,N) a density matrix.
    """
    P = np.eye(N) + random_unitary(N).data
    G = P.dot(__ginibre_matrix(N, rank, seed))
    G = G.dot(G.conj().T)
    return G / np.trace(G)

def __random_density_bures ( N , rank = None , seed = None ) : P = np . eye ( N ) + random_unitary ( N ) . data G = P . dot ( __ginibre_matrix ( N , rank , seed ) ) G = G . dot ( G . conj ( ) . T ) return G / np . trace ( G )

Generate a random density matrix from the Bures metric .


def calls(self):
        """Return a list of custom gate names in this gate body."""
        lst = []
        for children in self.children:
            if children.type == "custom_unitary":
                lst.append(children.name)
        return lst

def calls ( self ) : lst = [ ] for children in self . children : if children . type == "custom_unitary" : lst . append ( children . name ) return lst

Return a list of custom gate names in this gate body .


def power(self, n):
        """Return the compose of a QuantumChannel with itself n times.

        Args:
            n (int): compute the matrix power of the superoperator matrix.

        Returns:
            SuperOp: the n-times composition channel as a SuperOp object.

        Raises:
            QiskitError: if the input and output dimensions of the
            QuantumChannel are not equal, or the power is not an integer.
        """
        if not isinstance(n, (int, np.integer)):
            raise QiskitError("Can only power with integer powers.")
        if self._input_dim != self._output_dim:
            raise QiskitError("Can only power with input_dim = output_dim.")
        # Override base class power so we can implement more efficiently
        # using Numpy.matrix_power
        return SuperOp(
            np.linalg.matrix_power(self._data, n), self.input_dims(),
            self.output_dims())

Return the compose of a QuantumChannel with itself n times .


def _compose_subsystem(self, other, qargs, front=False):
        """Return the composition channel."""
        # Compute tensor contraction indices from qargs
        input_dims = list(self.input_dims())
        output_dims = list(self.output_dims())
        if front:
            num_indices = len(self.input_dims())
            shift = 2 * len(self.output_dims())
            right_mul = True
            for pos, qubit in enumerate(qargs):
                input_dims[qubit] = other._input_dims[pos]
        else:
            num_indices = len(self.output_dims())
            shift = 0
            right_mul = False
            for pos, qubit in enumerate(qargs):
                output_dims[qubit] = other._output_dims[pos]
        # Reshape current matrix
        # Note that we must reverse the subsystem dimension order as
        # qubit 0 corresponds to the right-most position in the tensor
        # product, which is the last tensor wire index.
        tensor = np.reshape(self.data, self._shape)
        mat = np.reshape(other.data, other._shape)
        # Add first set of indicies
        indices = [2 * num_indices - 1 - qubit for qubit in qargs
                   ] + [num_indices - 1 - qubit for qubit in qargs]
        final_shape = [np.product(output_dims)**2, np.product(input_dims)**2]
        data = np.reshape(
            self._einsum_matmul(tensor, mat, indices, shift, right_mul),
            final_shape)
        return SuperOp(data, input_dims, output_dims)

def _compose_subsystem ( self , other , qargs , front = False ) : input_dims = list ( self . input_dims ( ) ) output_dims = list ( self . output_dims ( ) ) if front : num_indices = len ( self . input_dims ( ) ) shift = 2 * len ( self . output_dims ( ) ) right_mul = True for pos , qubit in enumerate ( qargs ) : input_dims [ qubit ] = other . _input_dims [ pos ] else : num_indices = len ( self . output_dims ( ) ) shift = 0 right_mul = False for pos , qubit in enumerate ( qargs ) : output_dims [ qubit ] = other . _output_dims [ pos ] tensor = np . reshape ( self . data , self . _shape ) mat = np . reshape ( other . data , other . _shape ) indices = [ 2 * num_indices - 1 - qubit for qubit in qargs ] + [ num_indices - 1 - qubit for qubit in qargs ] final_shape = [ np . product ( output_dims ) ** 2 , np . product ( input_dims ) ** 2 ] data = np . reshape ( self . _einsum_matmul ( tensor , mat , indices , shift , right_mul ) , final_shape ) return SuperOp ( data , input_dims , output_dims )


def _instruction_to_superop(cls, instruction):
        """Convert a QuantumCircuit or Instruction to a SuperOp."""
        # Convert circuit to an instruction
        if isinstance(instruction, QuantumCircuit):
            instruction = instruction.to_instruction()
        # Initialize an identity superoperator of the correct size
        # of the circuit
        op = SuperOp(np.eye(4 ** instruction.num_qubits))
        op._append_instruction(instruction)
        return op

def _instruction_to_superop ( cls , instruction ) : if isinstance ( instruction , QuantumCircuit ) : instruction = instruction . to_instruction ( ) op = SuperOp ( np . eye ( 4 ** instruction . num_qubits ) ) op . _append_instruction ( instruction ) return op

Convert a QuantumCircuit or Instruction to a SuperOp .


def run(self, dag):
        """Return a circuit with a barrier before last measurements."""

        # Collect DAG nodes which are followed only by barriers or other measures.
        final_op_types = ['measure', 'barrier']
        final_ops = []
        for candidate_node in dag.named_nodes(*final_op_types):
            is_final_op = True

            for _, child_successors in dag.bfs_successors(candidate_node):

                if any(suc.type == 'op' and suc.name not in final_op_types
                       for suc in child_successors):
                    is_final_op = False
                    break

            if is_final_op:
                final_ops.append(candidate_node)

        if not final_ops:
            return dag

        # Create a layer with the barrier and add registers from the original dag.
        barrier_layer = DAGCircuit()
        for qreg in dag.qregs.values():
            barrier_layer.add_qreg(qreg)
        for creg in dag.cregs.values():
            barrier_layer.add_creg(creg)

        final_qubits = set(final_op.qargs[0] for final_op in final_ops)

        barrier_layer.apply_operation_back(
            Barrier(len(final_qubits)), list(final_qubits), [])

        # Preserve order of final ops collected earlier from the original DAG.
        ordered_final_nodes = [node for node in dag.topological_op_nodes()
                               if node in set(final_ops)]

        # Move final ops to the new layer and append the new layer to the DAG.
        for final_node in ordered_final_nodes:
            barrier_layer.apply_operation_back(final_node.op,
                                               final_node.qargs,
                                               final_node.cargs)

        for final_op in final_ops:
            dag.remove_op_node(final_op)

        dag.extend_back(barrier_layer)

        # Merge the new barrier into any other barriers
        adjacent_pass = MergeAdjacentBarriers()
        return adjacent_pass.run(dag)

def run ( self , dag ) : final_op_types = [ 'measure' , 'barrier' ] final_ops = [ ] for candidate_node in dag . named_nodes ( * final_op_types ) : is_final_op = True for _ , child_successors in dag . bfs_successors ( candidate_node ) : if any ( suc . type == 'op' and suc . name not in final_op_types for suc in child_successors ) : is_final_op = False break if is_final_op : final_ops . append ( candidate_node ) if not final_ops : return dag barrier_layer = DAGCircuit ( ) for qreg in dag . qregs . values ( ) : barrier_layer . add_qreg ( qreg ) for creg in dag . cregs . values ( ) : barrier_layer . add_creg ( creg ) final_qubits = set ( final_op . qargs [ 0 ] for final_op in final_ops ) barrier_layer . apply_operation_back ( Barrier ( len ( final_qubits ) ) , list ( final_qubits ) , [ ] ) ordered_final_nodes = [ node for node in dag . topological_op_nodes ( ) if node in set ( final_ops ) ] for final_node in ordered_final_nodes : barrier_layer . apply_operation_back ( final_node . op , final_node . qargs , final_node . cargs ) for final_op in final_ops : dag . remove_op_node ( final_op ) dag . extend_back ( barrier_layer ) adjacent_pass = MergeAdjacentBarriers ( ) return adjacent_pass . run ( dag )

Return a circuit with a barrier before last measurements .


def circuits_to_qobj(circuits, qobj_header=None,
                     qobj_id=None, backend_name=None,
                     config=None, shots=None, max_credits=None,
                     basis_gates=None,
                     coupling_map=None, seed=None, memory=None):
    """Convert a list of circuits into a qobj.

    Args:
        circuits (list[QuantumCircuits] or QuantumCircuit): circuits to compile
        qobj_header (QobjHeader): header to pass to the results
        qobj_id (int): TODO: delete after qiskit-terra 0.8
        backend_name (str): TODO: delete after qiskit-terra 0.8
        config (dict): TODO: delete after qiskit-terra 0.8
        shots (int): TODO: delete after qiskit-terra 0.8
        max_credits (int): TODO: delete after qiskit-terra 0.8
        basis_gates (str): TODO: delete after qiskit-terra 0.8
        coupling_map (list): TODO: delete after qiskit-terra 0.8
        seed (int): TODO: delete after qiskit-terra 0.8
        memory (bool): TODO: delete after qiskit-terra 0.8

    Returns:
        Qobj: the Qobj to be run on the backends
    """
    warnings.warn('circuits_to_qobj is deprecated and will be removed in Qiskit Terra 0.9. '
                  'Use qiskit.compiler.assemble() to serialize circuits into a qobj.',
                  DeprecationWarning)

    qobj_header = qobj_header or QobjHeader()

    if backend_name:
        qobj_header.backend_name = backend_name
    if basis_gates:
        warnings.warn('basis_gates was unused and will be removed.', DeprecationWarning)
    if coupling_map:
        warnings.warn('coupling_map was unused and will be removed.', DeprecationWarning)

    qobj = assemble(experiments=circuits,
                    qobj_id=qobj_id,
                    qobj_header=qobj_header,
                    shots=shots,
                    memory=memory,
                    max_credits=max_credits,
                    seed_simulator=seed,
                    config=config)

    return qobj

Convert a list of circuits into a qobj .


def run(self, dag):
        """Expand 3+ qubit gates using their decomposition rules.

        Args:
            dag(DAGCircuit): input dag
        Returns:
            DAGCircuit: output dag with maximum node degrees of 2
        Raises:
            QiskitError: if a 3q+ gate is not decomposable
        """
        for node in dag.threeQ_or_more_gates():
            # TODO: allow choosing other possible decompositions
            rule = node.op.definition
            if not rule:
                raise QiskitError("Cannot unroll all 3q or more gates. "
                                  "No rule to expand instruction %s." %
                                  node.op.name)

            # hacky way to build a dag on the same register as the rule is defined
            # TODO: need anonymous rules to address wires by index
            decomposition = DAGCircuit()
            decomposition.add_qreg(rule[0][1][0][0])
            for inst in rule:
                decomposition.apply_operation_back(*inst)
            decomposition = self.run(decomposition)  # recursively unroll
            dag.substitute_node_with_dag(node, decomposition)
        return dag

def
run
(
self
,
dag
)
:
for
node
in
dag
.
threeQ_or_more_gates
(
)
:
rule
=
node
.
op
.
definition
if
not
rule
:
raise
QiskitError
(
"Cannot unroll all 3q or more gates. "
"No rule to expand instruction %s."
%
node
.
op
.
name
)
decomposition
=
DAGCircuit
(
)
decomposition
.
add_qreg
(
rule
[
0
]
[
1
]
[
0
]
[
0
]
)
for
inst
in
rule
:
decomposition
.
apply_operation_back
(
*
inst
)
decomposition
=
self
.
run
(
decomposition
)
dag
.
substitute_node_with_dag
(
node
,
decomposition
)
return
dag

Expand 3 + qubit gates using their decomposition rules .


def run(self, dag):
        """Expand a given gate into its decomposition.

        Args:
            dag(DAGCircuit): input dag
        Returns:
            DAGCircuit: output dag where gate was expanded.
        """
        # Walk through the DAG and expand each non-basis node
        for node in dag.op_nodes(self.gate):
            # opaque or built-in gates are not decomposable
            if not node.op.definition:
                continue
            # TODO: allow choosing among multiple decomposition rules
            rule = node.op.definition
            # hacky way to build a dag on the same register as the rule is defined
            # TODO: need anonymous rules to address wires by index
            decomposition = DAGCircuit()
            decomposition.add_qreg(rule[0][1][0][0])
            if rule[0][2]:
                decomposition.add_creg(rule[0][2][0][0])
            for inst in rule:
                decomposition.apply_operation_back(*inst)
            dag.substitute_node_with_dag(node, decomposition)
        return dag

def run ( self , dag ) : for node in dag . op_nodes ( self . gate ) : if not node . op . definition : continue rule = node . op . definition decomposition = DAGCircuit ( ) decomposition . add_qreg ( rule [ 0 ] [ 1 ] [ 0 ] [ 0 ] ) if rule [ 0 ] [ 2 ] : decomposition . add_creg ( rule [ 0 ] [ 2 ] [ 0 ] [ 0 ] ) for inst in rule : decomposition . apply_operation_back ( * inst ) dag . substitute_node_with_dag ( node , decomposition ) return dag

Expand a given gate into its decomposition .


def _define(self):
        """Calculate a subcircuit that implements this unitary."""
        if self.num_qubits == 1:
            q = QuantumRegister(1, "q")
            angles = euler_angles_1q(self.to_matrix())
            self.definition = [(U3Gate(*angles), [q[0]], [])]
        if self.num_qubits == 2:
            self.definition = two_qubit_kak(self.to_matrix())

def _define ( self ) : if self . num_qubits == 1 : q = QuantumRegister ( 1 , "q" ) angles = euler_angles_1q ( self . to_matrix ( ) ) self . definition = [ ( U3Gate ( * angles ) , [ q [ 0 ] ] , [ ] ) ] if self . num_qubits == 2 : self . definition = two_qubit_kak ( self . to_matrix ( ) )

Calculate a subcircuit that implements this unitary .


def check_type(self, value, attr, data):
        """Validate if the value is of the type of the schema's model.

        Assumes the nested schema is a ``BaseSchema``.
        """
        if self.many and not is_collection(value):
            raise self._not_expected_type(
                value, Iterable, fields=[self], field_names=attr, data=data)

        _check_type = super().check_type

        errors = []
        values = value if self.many else [value]
        for idx, v in enumerate(values):
            try:
                _check_type(v, idx, values)
            except ValidationError as err:
                errors.append(err.messages)

        if errors:
            errors = errors if self.many else errors[0]
            raise ValidationError(errors)

        return value

def check_type ( self , value , attr , data ) : if self . many and not is_collection ( value ) : raise self . _not_expected_type ( value , Iterable , fields = [ self ] , field_names = attr , data = data ) _check_type = super ( ) . check_type errors = [ ] values = value if self . many else [ value ] for idx , v in enumerate ( values ) : try : _check_type ( v , idx , values ) except ValidationError as err : errors . append ( err . messages ) if errors : errors = errors if self . many else errors [ 0 ] raise ValidationError ( errors ) return value

Validate if the value is of the type of the schema s model .


def check_type(self, value, attr, data):
        """Validate if it's a list of valid item-field values.

        Check if each element in the list can be validated by the item-field
        passed during construction.
        """
        super().check_type(value, attr, data)

        errors = []
        for idx, v in enumerate(value):
            try:
                self.container.check_type(v, idx, value)
            except ValidationError as err:
                errors.append(err.messages)

        if errors:
            raise ValidationError(errors)

        return value

def check_type ( self , value , attr , data ) : super ( ) . check_type ( value , attr , data ) errors = [ ] for idx , v in enumerate ( value ) : try : self . container . check_type ( v , idx , value ) except ValidationError as err : errors . append ( err . messages ) if errors : raise ValidationError ( errors ) return value

Validate if it s a list of valid item - field values .


def _atol(self, atol):
        """Set the absolute tolerence parameter for float comparisons."""
        # NOTE: that this overrides the class value so applies to all
        # instances of the class.
        max_tol = self.__class__.MAX_TOL
        if atol < 0:
            raise QiskitError("Invalid atol: must be non-negative.")
        if atol > max_tol:
            raise QiskitError(
                "Invalid atol: must be less than {}.".format(max_tol))
        self.__class__.ATOL = atol

def
_atol
(
self
,
atol
)
:
max_tol
=
self
.
__class__
.
MAX_TOL
if
atol
<
0
:
raise
QiskitError
(
"Invalid atol: must be non-negative."
)
if
atol
>
max_tol
:
raise
QiskitError
(
"Invalid atol: must be less than {}."
.
format
(
max_tol
)
)
self
.
__class__
.
ATOL
=
atol

Set the absolute tolerence parameter for float comparisons .


def _rtol(self, rtol):
        """Set the relative tolerence parameter for float comparisons."""
        # NOTE: that this overrides the class value so applies to all
        # instances of the class.
        max_tol = self.__class__.MAX_TOL
        if rtol < 0:
            raise QiskitError("Invalid rtol: must be non-negative.")
        if rtol > max_tol:
            raise QiskitError(
                "Invalid rtol: must be less than {}.".format(max_tol))
        self.__class__.RTOL = rtol

def
_rtol
(
self
,
rtol
)
:
max_tol
=
self
.
__class__
.
MAX_TOL
if
rtol
<
0
:
raise
QiskitError
(
"Invalid rtol: must be non-negative."
)
if
rtol
>
max_tol
:
raise
QiskitError
(
"Invalid rtol: must be less than {}."
.
format
(
max_tol
)
)
self
.
__class__
.
RTOL
=
rtol

Set the relative tolerence parameter for float comparisons .


def _reshape(self, input_dims=None, output_dims=None):
        """Reshape input and output dimensions of operator.

        Arg:
            input_dims (tuple): new subsystem input dimensions.
            output_dims (tuple): new subsystem output dimensions.

        Returns:
            Operator: returns self with reshaped input and output dimensions.

        Raises:
            QiskitError: if combined size of all subsystem input dimension or
            subsystem output dimensions is not constant.
        """
        if input_dims is not None:
            if np.product(input_dims) != self._input_dim:
                raise QiskitError(
                    "Reshaped input_dims are incompatible with combined input dimension."
                )
            self._input_dims = tuple(input_dims)
        if output_dims is not None:
            if np.product(output_dims) != self._output_dim:
                raise QiskitError(
                    "Reshaped input_dims are incompatible with combined input dimension."
                )
            self._output_dims = tuple(output_dims)
        return self

Reshape input and output dimensions of operator .


def input_dims(self, qargs=None):
        """Return tuple of input dimension for specified subsystems."""
        if qargs is None:
            return self._input_dims
        return tuple(self._input_dims[i] for i in qargs)

def input_dims ( self , qargs = None ) : if qargs is None : return self . _input_dims return tuple ( self . _input_dims [ i ] for i in qargs )

Return tuple of input dimension for specified subsystems .


def output_dims(self, qargs=None):
        """Return tuple of output dimension for specified subsystems."""
        if qargs is None:
            return self._output_dims
        return tuple(self._output_dims[i] for i in qargs)

def output_dims ( self , qargs = None ) : if qargs is None : return self . _output_dims return tuple ( self . _output_dims [ i ] for i in qargs )

Return tuple of output dimension for specified subsystems .


def copy(self):
        """Make a copy of current operator."""
        # pylint: disable=no-value-for-parameter
        # The constructor of subclasses from raw data should be a copy
        return self.__class__(self.data, self.input_dims(), self.output_dims())

def copy ( self ) : return self . __class__ ( self . data , self . input_dims ( ) , self . output_dims ( ) )


def power(self, n):
        """Return the compose of a operator with itself n times.

        Args:
            n (int): the number of times to compose with self (n>0).

        Returns:
            BaseOperator: the n-times composed operator.

        Raises:
            QiskitError: if the input and output dimensions of the operator
            are not equal, or the power is not a positive integer.
        """
        # NOTE: if a subclass can have negative or non-integer powers
        # this method should be overriden in that class.
        if not isinstance(n, (int, np.integer)) or n < 1:
            raise QiskitError("Can only power with positive integer powers.")
        if self._input_dim != self._output_dim:
            raise QiskitError("Can only power with input_dim = output_dim.")
        ret = self.copy()
        for _ in range(1, n):
            ret = ret.compose(self)
        return ret

Return the compose of a operator with itself n times .


def _automatic_dims(cls, dims, size):
        """Check if input dimension corresponds to qubit subsystems."""
        if dims is None:
            dims = size
        elif np.product(dims) != size:
            raise QiskitError("dimensions do not match size.")
        if isinstance(dims, (int, np.integer)):
            num_qubits = int(np.log2(dims))
            if 2 ** num_qubits == size:
                return num_qubits * (2,)
            return (dims,)
        return tuple(dims)

def
_automatic_dims
(
cls
,
dims
,
size
)
:
if
dims
is
:
dims
=
size
elif
np
.
product
(
dims
)
!=
size
:
raise
QiskitError
(
"dimensions do not match size."
)
if
isinstance
(
dims
,
(
int
,
np
.
integer
)
)
:
num_qubits
=
int
(
np
.
log2
(
dims
)
)
if
2
**
num_qubits
==
size
:
return
num_qubits
*
(
2
,
)
return
(
dims
,
)
return
tuple
(
dims
)

Check if input dimension corresponds to qubit subsystems .


def _einsum_matmul(cls, tensor, mat, indices, shift=0, right_mul=False):
        """Perform a contraction using Numpy.einsum

        Args:
            tensor (np.array): a vector or matrix reshaped to a rank-N tensor.
            mat (np.array): a matrix reshaped to a rank-2M tensor.
            indices (list): tensor indices to contract with mat.
            shift (int): shift for indicies of tensor to contract [Default: 0].
            right_mul (bool): if True right multiply tensor by mat
                              (else left multiply) [Default: False].

        Returns:
            Numpy.ndarray: the matrix multiplied rank-N tensor.

        Raises:
            QiskitError: if mat is not an even rank tensor.
        """
        rank = tensor.ndim
        rank_mat = mat.ndim
        if rank_mat % 2 != 0:
            raise QiskitError(
                "Contracted matrix must have an even number of indices.")
        # Get einsum indices for tensor
        indices_tensor = list(range(rank))
        for j, index in enumerate(indices):
            indices_tensor[index + shift] = rank + j
        # Get einsum indces for mat
        mat_contract = list(reversed(range(rank, rank + len(indices))))
        mat_free = [index + shift for index in reversed(indices)]
        if right_mul:
            indices_mat = mat_contract + mat_free
        else:
            indices_mat = mat_free + mat_contract
        return np.einsum(tensor, indices_tensor, mat, indices_mat)

Perform a contraction using Numpy . einsum


def _deserialize(self, value, attr, data):
        """Override ``_deserialize`` for customizing the exception raised."""
        try:
            return super()._deserialize(value, attr, data)
        except ValidationError as ex:
            if 'deserialization_schema_selector' in ex.messages[0]:
                ex.messages[0] = 'Cannot find a valid schema among the choices'
            raise

Override _deserialize for customizing the exception raised .


def _serialize(self, value, key, obj):
        """Override ``_serialize`` for customizing the exception raised."""
        try:
            return super()._serialize(value, key, obj)
        except TypeError as ex:
            if 'serialization_schema_selector' in str(ex):
                raise ValidationError('Data from an invalid schema')
            raise

def
_serialize
(
self
,
value
,
key
,
obj
)
:
try
:
return
super
(
)
.
_serialize
(
value
,
key
,
obj
)
except
TypeError
as
ex
:
if
'serialization_schema_selector'
in
str
(
ex
)
:
raise
ValidationError
(
'Data from an invalid schema'
)
raise

Override _serialize for customizing the exception raised .


def check_type(self, value, attr, data):
        """Check if at least one of the possible choices validates the value.

        Possible choices are assumed to be ``ModelTypeValidator`` fields.
        """
        for field in self.choices:
            if isinstance(field, ModelTypeValidator):
                try:
                    return field.check_type(value, attr, data)
                except ValidationError:
                    pass

        raise self._not_expected_type(
            value, [field.__class__ for field in self.choices],
            fields=[self], field_names=attr, data=data)

def check_type ( self , value , attr , data ) : for field in self . choices : if isinstance ( field , ModelTypeValidator ) : try : return field . check_type ( value , attr , data ) except ValidationError : pass raise self . _not_expected_type ( value , [ field . __class__ for field in self . choices ] , fields = [ self ] , field_names = attr , data = data )

Check if at least one of the possible choices validates the value .


def state_fidelity(state1, state2):
    """Return the state fidelity between two quantum states.

    Either input may be a state vector, or a density matrix. The state
    fidelity (F) for two density matrices is defined as::

        F(rho1, rho2) = Tr[sqrt(sqrt(rho1).rho2.sqrt(rho1))] ^ 2

    For a pure state and mixed state the fidelity is given by::

        F(|psi1>, rho2) = <psi1|rho2|psi1>

    For two pure states the fidelity is given by::

        F(|psi1>, |psi2>) = |<psi1|psi2>|^2

    Args:
        state1 (array_like): a quantum state vector or density matrix.
        state2 (array_like): a quantum state vector or density matrix.

    Returns:
        array_like: The state fidelity F(state1, state2).
    """
    # convert input to numpy arrays
    s1 = np.array(state1)
    s2 = np.array(state2)

    # fidelity of two state vectors
    if s1.ndim == 1 and s2.ndim == 1:
        return np.abs(s2.conj().dot(s1)) ** 2
    # fidelity of vector and density matrix
    elif s1.ndim == 1:
        # psi = s1, rho = s2
        return np.abs(s1.conj().dot(s2).dot(s1))
    elif s2.ndim == 1:
        # psi = s2, rho = s1
        return np.abs(s2.conj().dot(s1).dot(s2))
    # fidelity of two density matrices
    s1sq = _funm_svd(s1, np.sqrt)
    s2sq = _funm_svd(s2, np.sqrt)
    return np.linalg.norm(s1sq.dot(s2sq), ord='nuc') ** 2

def state_fidelity ( state1 , state2 ) : s1 = np . array ( state1 ) s2 = np . array ( state2 ) if s1 . ndim == 1 and s2 . ndim == 1 : return np . abs ( s2 . conj ( ) . dot ( s1 ) ) ** 2 elif s1 . ndim == 1 : return np . abs ( s1 . conj ( ) . dot ( s2 ) . dot ( s1 ) ) elif s2 . ndim == 1 : return np . abs ( s2 . conj ( ) . dot ( s1 ) . dot ( s2 ) ) s1sq = _funm_svd ( s1 , np . sqrt ) s2sq = _funm_svd ( s2 , np . sqrt ) return np . linalg . norm ( s1sq . dot ( s2sq ) , ord = 'nuc' ) ** 2

Return the state fidelity between two quantum states .


def _funm_svd(a, func):
    """Apply real scalar function to singular values of a matrix.

    Args:
        a (array_like): (N, N) Matrix at which to evaluate the function.
        func (callable): Callable object that evaluates a scalar function f.

    Returns:
        ndarray: funm (N, N) Value of the matrix function specified by func
        evaluated at `A`.
    """
    U, s, Vh = la.svd(a, lapack_driver='gesvd')
    S = np.diag(func(s))
    return U.dot(S).dot(Vh)

def _funm_svd ( a , func ) : U , s , Vh = la . svd ( a , lapack_driver = 'gesvd' ) S = np . diag ( func ( s ) ) return U . dot ( S ) . dot ( Vh )

Apply real scalar function to singular values of a matrix .


def inverse(self):
        """Special case. Return self."""
        return Snapshot(self.num_qubits, self.num_clbits, self.params[0],
                        self.params[1])

def inverse ( self ) : return Snapshot ( self . num_qubits , self . num_clbits , self . params [ 0 ] , self . params [ 1 ] )


def label(self, name):
        """Set snapshot label to name

        Args:
            name (str or None): label to assign unitary

        Raises:
            TypeError: name is not string or None.
        """
        if isinstance(name, str):
            self._label = name
        else:
            raise TypeError('label expects a string')

def
label
(
self
,
name
)
:
if
isinstance
(
name
,
str
)
:
self
.
_label
=
name
else
:
raise
TypeError
(
'label expects a string'
)


def is_unitary(self, atol=None, rtol=None):
        """Return True if QuantumChannel is a unitary channel."""
        try:
            op = self.to_operator()
            return op.is_unitary(atol=atol, rtol=rtol)
        except QiskitError:
            return False

def is_unitary ( self , atol = None , rtol = None ) : try : op = self . to_operator ( ) return op . is_unitary ( atol = atol , rtol = rtol ) except QiskitError : return False

Return True if QuantumChannel is a unitary channel .


def to_operator(self):
        """Try to convert channel to a unitary representation Operator."""
        mat = _to_operator(self.rep, self._data, *self.dim)
        return Operator(mat, self.input_dims(), self.output_dims())

def to_operator ( self ) : mat = _to_operator ( self . rep , self . _data , * self . dim ) return Operator ( mat , self . input_dims ( ) , self . output_dims ( ) )

Try to convert channel to a unitary representation Operator .


def to_instruction(self):
        """Convert to a Kraus or UnitaryGate circuit instruction.

        If the channel is unitary it will be added as a unitary gate,
        otherwise it will be added as a kraus simulator instruction.

        Returns:
            Instruction: A kraus instruction for the channel.

        Raises:
            QiskitError: if input data is not an N-qubit CPTP quantum channel.
        """
        from qiskit.circuit.instruction import Instruction
        # Check if input is an N-qubit CPTP channel.
        n_qubits = int(np.log2(self._input_dim))
        if self._input_dim != self._output_dim or 2**n_qubits != self._input_dim:
            raise QiskitError(
                'Cannot convert QuantumChannel to Instruction: channel is not an N-qubit channel.'
            )
        if not self.is_cptp():
            raise QiskitError(
                'Cannot convert QuantumChannel to Instruction: channel is not CPTP.'
            )
        # Next we convert to the Kraus representation. Since channel is CPTP we know
        # that there is only a single set of Kraus operators
        kraus, _ = _to_kraus(self.rep, self._data, *self.dim)
        # If we only have a single Kraus operator then the channel is
        # a unitary channel so can be converted to a UnitaryGate. We do this by
        # converting to an Operator and using its to_instruction method
        if len(kraus) == 1:
            return Operator(kraus[0]).to_instruction()
        return Instruction('kraus', n_qubits, 0, kraus)

Convert to a Kraus or UnitaryGate circuit instruction .


def _init_transformer(cls, data):
        """Convert input into a QuantumChannel subclass object or Operator object"""
        # This handles common conversion for all QuantumChannel subclasses.
        # If the input is already a QuantumChannel subclass it will return
        # the original object
        if isinstance(data, QuantumChannel):
            return data
        if hasattr(data, 'to_quantumchannel'):
            # If the data object is not a QuantumChannel it will give
            # preference to a 'to_quantumchannel' attribute that allows
            # an arbitrary object to define its own conversion to any
            # quantum channel subclass.
            return data.to_channel()
        if hasattr(data, 'to_channel'):
            # TODO: this 'to_channel' method is the same case as the above
            # but is used by current version of Aer. It should be removed
            # once Aer is nupdated to use `to_quantumchannel`
            # instead of `to_channel`,
            return data.to_channel()
        # Finally if the input is not a QuantumChannel and doesn't have a
        # 'to_quantumchannel' conversion method we try and initialize it as a
        # regular matrix Operator which can be converted into a QuantumChannel.
        return Operator(data)

def _init_transformer ( cls , data ) : if isinstance ( data , QuantumChannel ) : return data if hasattr ( data , 'to_quantumchannel' ) : return data . to_channel ( ) if hasattr ( data , 'to_channel' ) : return data . to_channel ( ) return Operator ( data )


def sort_enum_for_model(cls, name=None, symbol_name=_symbol_name):
    """Create Graphene Enum for sorting a SQLAlchemy class query

    Parameters
    - cls : Sqlalchemy model class
        Model used to create the sort enumerator
    - name : str, optional, default None
        Name to use for the enumerator. If not provided it will be set to `cls.__name__ + 'SortEnum'`
    - symbol_name : function, optional, default `_symbol_name`
        Function which takes the column name and a boolean indicating if the sort direction is ascending,
        and returns the symbol name for the current column and sort direction.
        The default function will create, for a column named 'foo', the symbols 'foo_asc' and 'foo_desc'

    Returns
    - Enum
        The Graphene enumerator
    """
    enum, _ = _sort_enum_for_model(cls, name, symbol_name)
    return enum

def sort_enum_for_model ( cls , name = None , symbol_name = _symbol_name ) : enum , _ = _sort_enum_for_model ( cls , name , symbol_name ) return enum


def patch_strptime():
    """Monkey patching _strptime to avoid problems related with non-english
    locale changes on the system.

    For example, if system's locale is set to fr_FR. Parser won't recognize
    any date since all languages are translated to english dates.
    """

    _strptime = imp.load_module(
        'strptime_patched', *imp.find_module('_strptime')
    )

    _calendar = imp.load_module(
        'calendar_patched', *imp.find_module('_strptime')
    )

    _strptime._getlang = lambda: ('en_US', 'UTF-8')
    _strptime.calendar = _calendar
    _strptime.calendar.day_abbr = [
        'mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun'
    ]
    _strptime.calendar.day_name = [
        'monday', 'tuesday', 'wednesday', 'thursday',
        'friday', 'saturday', 'sunday'
    ]
    _strptime.calendar.month_abbr = [
        '', 'jan', 'feb', 'mar', 'apr', 'may', 'jun',
        'jul', 'aug', 'sep', 'oct', 'nov', 'dec'
    ]
    _strptime.calendar.month_name = [
        '', 'january', 'february', 'march', 'april',
        'may', 'june', 'july', 'august', 'september',
        'october', 'november', 'december'
    ]

    return _strptime._strptime_time

def patch_strptime ( ) : _strptime = imp . load_module ( 'strptime_patched' , * imp . find_module ( '_strptime' ) ) _calendar = imp . load_module ( 'calendar_patched' , * imp . find_module ( '_strptime' ) ) _strptime . _getlang = lambda : ( 'en_US' , 'UTF-8' ) _strptime . calendar = _calendar _strptime . calendar . day_abbr = [ 'mon' , 'tue' , 'wed' , 'thu' , 'fri' , 'sat' , 'sun' ] _strptime . calendar . day_name = [ 'monday' , 'tuesday' , 'wednesday' , 'thursday' , 'friday' , 'saturday' , 'sunday' ] _strptime . calendar . month_abbr = [ '' , 'jan' , 'feb' , 'mar' , 'apr' , 'may' , 'jun' , 'jul' , 'aug' , 'sep' , 'oct' , 'nov' , 'dec' ] _strptime . calendar . month_name = [ '' , 'january' , 'february' , 'march' , 'april' , 'may' , 'june' , 'july' , 'august' , 'september' , 'october' , 'november' , 'december' ] return _strptime . _strptime_time

Monkey patching _strptime to avoid problems related with non - english locale changes on the system .


def get_locale_map(self, languages=None, locales=None, region=None,
                       use_given_order=False, allow_conflicting_locales=False):
        """
        Get an ordered mapping with locale codes as keys
        and corresponding locale instances as values.

        :param languages:
            A list of language codes, e.g. ['en', 'es', 'zh-Hant'].
            If locales are not given, languages and region are
            used to construct locales to load.
        :type languages: list

        :param locales:
            A list of codes of locales which are to be loaded,
            e.g. ['fr-PF', 'qu-EC', 'af-NA']
        :type locales: list

        :param region:
            A region code, e.g. 'IN', '001', 'NE'.
            If locales are not given, languages and region are
            used to construct locales to load.
        :type region: str|unicode

        :param use_given_order:
            If True, the returned mapping is ordered in the order locales are given.
        :type allow_redetect_language: bool

        :param allow_conflicting_locales:
            if True, locales with same language and different region can be loaded.
        :type allow_conflicting_locales: bool

        :return: ordered locale code to locale instance mapping
        """
        return OrderedDict(self._load_data(
            languages=languages, locales=locales, region=region, use_given_order=use_given_order,
            allow_conflicting_locales=allow_conflicting_locales))

def get_locale_map ( self , languages = None , locales = None , region = None , use_given_order = False , allow_conflicting_locales = False ) : return OrderedDict ( self . _load_data ( languages = languages , locales = locales , region = region , use_given_order = use_given_order , allow_conflicting_locales = allow_conflicting_locales ) )

Get an ordered mapping with locale codes as keys and corresponding locale instances as values .


def get_locales(self, languages=None, locales=None, region=None,
                    use_given_order=False, allow_conflicting_locales=False):
        """
        Yield locale instances.

        :param languages:
            A list of language codes, e.g. ['en', 'es', 'zh-Hant'].
            If locales are not given, languages and region are
            used to construct locales to load.
        :type languages: list

        :param locales:
            A list of codes of locales which are to be loaded,
            e.g. ['fr-PF', 'qu-EC', 'af-NA']
        :type locales: list

        :param region:
            A region code, e.g. 'IN', '001', 'NE'.
            If locales are not given, languages and region are
            used to construct locales to load.
        :type region: str|unicode

        :param use_given_order:
            If True, the returned mapping is ordered in the order locales are given.
        :type allow_redetect_language: bool

        :param allow_conflicting_locales:
            if True, locales with same language and different region can be loaded.
        :type allow_conflicting_locales: bool

        :yield: locale instances
        """
        for _, locale in self._load_data(
                languages=languages, locales=locales, region=region,
                use_given_order=use_given_order,
                allow_conflicting_locales=allow_conflicting_locales):
            yield locale

def get_locales ( self , languages = None , locales = None , region = None , use_given_order = False , allow_conflicting_locales = False ) : for _ , locale in self . _load_data ( languages = languages , locales = locales , region = region , use_given_order = use_given_order , allow_conflicting_locales = allow_conflicting_locales ) : yield locale


def are_tokens_valid(self, tokens):
        """
        Check if tokens are valid tokens for the locale.

        :param tokens:
            a list of string or unicode tokens.
        :type tokens: list

        :return: True if tokens are valid, False otherwise.
        """
        match_relative_regex = self._get_match_relative_regex_cache()
        for token in tokens:
            if any([match_relative_regex.match(token),
                    token in self, token.isdigit()]):
                continue
            else:
                return False
        else:
            return True

def are_tokens_valid ( self , tokens ) : match_relative_regex = self . _get_match_relative_regex_cache ( ) for token in tokens : if any ( [ match_relative_regex . match ( token ) , token in self , token . isdigit ( ) ] ) : continue else : return False else : return True

Check if tokens are valid tokens for the locale .


def split(self, string, keep_formatting=False):
        """
        Split the date string using translations in locale info.

        :param string:
            Date string to be splitted.
        :type string:
            str|unicode

        :param keep_formatting:
            If True, retain formatting of the date string.
        :type keep_formatting: bool

        :return: A list of string tokens formed after splitting the date string.
        """
        if not string:
            return string

        split_relative_regex = self._get_split_relative_regex_cache()
        match_relative_regex = self._get_match_relative_regex_cache()

        tokens = split_relative_regex.split(string)

        for i, token in enumerate(tokens):
            if match_relative_regex.match(token):
                tokens[i] = [token]
                continue
            tokens[i] = self._split_by_known_words(token, keep_formatting)

        return list(filter(bool, chain(*tokens)))

def split ( self , string , keep_formatting = False ) : if not string : return string split_relative_regex = self . _get_split_relative_regex_cache ( ) match_relative_regex = self . _get_match_relative_regex_cache ( ) tokens = split_relative_regex . split ( string ) for i , token in enumerate ( tokens ) : if match_relative_regex . match ( token ) : tokens [ i ] = [ token ] continue tokens [ i ] = self . _split_by_known_words ( token , keep_formatting ) return list ( filter ( bool , chain ( * tokens ) ) )

Split the date string using translations in locale info .


def parse(date_string, date_formats=None, languages=None, locales=None, region=None, settings=None):
    """Parse date and time from given date string.

    :param date_string:
        A string representing date and/or time in a recognizably valid format.
    :type date_string: str|unicode

    :param date_formats:
        A list of format strings using directives as given
        `here <https://docs.python.org/2/library/datetime.html#strftime-and-strptime-behavior>`_.
        The parser applies formats one by one, taking into account the detected languages/locales.
    :type date_formats: list

    :param languages:
        A list of language codes, e.g. ['en', 'es', 'zh-Hant'].
        If locales are not given, languages and region are used to construct locales for translation.
    :type languages: list

    :param locales:
        A list of locale codes, e.g. ['fr-PF', 'qu-EC', 'af-NA'].
        The parser uses locales to translate date string.
    :type locales: list

    :param region:
        A region code, e.g. 'IN', '001', 'NE'.
        If locales are not given, languages and region are used to construct locales for translation.
    :type region: str|unicode

    :param settings:
        Configure customized behavior using settings defined in :mod:`dateparser.conf.Settings`.
    :type settings: dict

    :return: Returns :class:`datetime <datetime.datetime>` representing parsed date if successful, else returns None
    :rtype: :class:`datetime <datetime.datetime>`.
    :raises: ValueError - Unknown Language
    """
    parser = _default_parser

    if any([languages, locales, region, not settings._default]):
        parser = DateDataParser(languages=languages, locales=locales,
                                region=region, settings=settings)

    data = parser.get_date_data(date_string, date_formats)

    if data:
        return data['date_obj']

def parse ( date_string , date_formats = None , languages = None , locales = None , region = None , settings = None ) : parser = _default_parser if any ( [ languages , locales , region , not settings . _default ] ) : parser = DateDataParser ( languages = languages , locales = locales , region = region , settings = settings ) data = parser . get_date_data ( date_string , date_formats ) if data : return data [ 'date_obj' ]

Parse date and time from given date string .


def _parse_time(self, date_string, settings):
        """Attemps to parse time part of date strings like '1 day ago, 2 PM' """
        date_string = PATTERN.sub('', date_string)
        date_string = re.sub(r'\b(?:ago|in)\b', '', date_string)
        try:
            return time_parser(date_string)
        except:
            pass

def _parse_time ( self , date_string , settings ) : date_string = PATTERN . sub ( '' , date_string ) date_string = re . sub ( r'\b(?:ago|in)\b' , '' , date_string ) try : return time_parser ( date_string ) except : pass

Attemps to parse time part of date strings like 1 day ago 2 PM


def is_applicable(self, date_string, strip_timezone=False, settings=None):
        """
        Check if the locale is applicable to translate date string.

        :param date_string:
            A string representing date and/or time in a recognizably valid format.
        :type date_string: str|unicode

        :param strip_timezone:
            If True, timezone is stripped from date string.
        :type strip_timezone: bool

        :return: boolean value representing if the locale is applicable for the date string or not.
        """
        if strip_timezone:
            date_string, _ = pop_tz_offset_from_string(date_string, as_offset=False)

        date_string = self._translate_numerals(date_string)
        if settings.NORMALIZE:
            date_string = normalize_unicode(date_string)
        date_string = self._simplify(date_string, settings=settings)
        dictionary = self._get_dictionary(settings)
        date_tokens = dictionary.split(date_string)

        return dictionary.are_tokens_valid(date_tokens)

def is_applicable ( self , date_string , strip_timezone = False , settings = None ) : if strip_timezone : date_string , _ = pop_tz_offset_from_string ( date_string , as_offset = False ) date_string = self . _translate_numerals ( date_string ) if settings . NORMALIZE : date_string = normalize_unicode ( date_string ) date_string = self . _simplify ( date_string , settings = settings ) dictionary = self . _get_dictionary ( settings ) date_tokens = dictionary . split ( date_string ) return dictionary . are_tokens_valid ( date_tokens )

Check if the locale is applicable to translate date string .


def translate(self, date_string, keep_formatting=False, settings=None):
        """
        Translate the date string to its English equivalent.

        :param date_string:
            A string representing date and/or time in a recognizably valid format.
        :type date_string: str|unicode

        :param keep_formatting:
            If True, retain formatting of the date string after translation.
        :type keep_formatting: bool

        :return: translated date string.
        """
        date_string = self._translate_numerals(date_string)
        if settings.NORMALIZE:
            date_string = normalize_unicode(date_string)
        date_string = self._simplify(date_string, settings=settings)
        dictionary = self._get_dictionary(settings)
        date_string_tokens = dictionary.split(date_string, keep_formatting)

        relative_translations = self._get_relative_translations(settings=settings)

        for i, word in enumerate(date_string_tokens):
            word = word.lower()
            for pattern, replacement in relative_translations.items():
                if pattern.match(word):
                    date_string_tokens[i] = pattern.sub(replacement, word)
            else:
                if word in dictionary:
                    date_string_tokens[i] = dictionary[word] or ''
        if "in" in date_string_tokens:
            date_string_tokens = self._clear_future_words(date_string_tokens)

        return self._join(list(filter(bool, date_string_tokens)),
                          separator="" if keep_formatting else " ", settings=settings)

def
translate
(
self
,
date_string
,
keep_formatting
=
False
,
settings
=
)
:
date_string
=
self
.
_translate_numerals
(
date_string
)
if
settings
.
NORMALIZE
:
date_string
=
normalize_unicode
(
date_string
)
date_string
=
self
.
_simplify
(
date_string
,
settings
=
settings
)
dictionary
=
self
.
_get_dictionary
(
settings
)
date_string_tokens
=
dictionary
.
split
(
date_string
,
keep_formatting
)
relative_translations
=
self
.
_get_relative_translations
(
settings
=
settings
)
for
i
,
word
in
enumerate
(
date_string_tokens
)
:
word
=
word
.
lower
(
)
for
pattern
,
replacement
in
relative_translations
.
items
(
)
:
if
pattern
.
match
(
word
)
:
date_string_tokens
[
i
]
=
pattern
.
sub
(
replacement
,
word
)
else
:
if
word
in
dictionary
:
date_string_tokens
[
i
]
=
dictionary
[
word
]
or
''
if
"in"
in
date_string_tokens
:
date_string_tokens
=
self
.
_clear_future_words
(
date_string_tokens
)
return
self
.
_join
(
list
(
filter
(
bool
,
date_string_tokens
)
)
,
separator
=
""
if
keep_formatting
else
" "
,
settings
=
settings
)

Translate the date string to its English equivalent .


def parse_with_formats(date_string, date_formats, settings):
    """ Parse with formats and return a dictionary with 'period' and 'obj_date'.

    :returns: :class:`datetime.datetime`, dict or None

    """
    period = 'day'
    for date_format in date_formats:
        try:
            date_obj = datetime.strptime(date_string, date_format)
        except ValueError:
            continue
        else:
            # If format does not include the day, use last day of the month
            # instead of first, because the first is usually out of range.
            if '%d' not in date_format:
                period = 'month'
                date_obj = date_obj.replace(
                    day=get_last_day_of_month(date_obj.year, date_obj.month))

            if not ('%y' in date_format or '%Y' in date_format):
                today = datetime.today()
                date_obj = date_obj.replace(year=today.year)

            date_obj = apply_timezone_from_settings(date_obj, settings)

            return {'date_obj': date_obj, 'period': period}
    else:
        return {'date_obj': None, 'period': period}

def parse_with_formats ( date_string , date_formats , settings ) : period = 'day' for date_format in date_formats : try : date_obj = datetime . strptime ( date_string , date_format ) except ValueError : continue else : if '%d' not in date_format : period = 'month' date_obj = date_obj . replace ( day = get_last_day_of_month ( date_obj . year , date_obj . month ) ) if not ( '%y' in date_format or '%Y' in date_format ) : today = datetime . today ( ) date_obj = date_obj . replace ( year = today . year ) date_obj = apply_timezone_from_settings ( date_obj , settings ) return { 'date_obj' : date_obj , 'period' : period } else : return { 'date_obj' : None , 'period' : period }

Parse with formats and return a dictionary with period and obj_date .


def get_ammo_generator(self):
        """
        return ammo generator
        """
        af_readers = {
            'phantom': missile.AmmoFileReader,
            'slowlog': missile.SlowLogReader,
            'line': missile.LineReader,
            'uri': missile.UriReader,
            'uripost': missile.UriPostReader,
            'access': missile.AccessLogReader,
            'caseline': missile.CaseLineReader,
        }
        if self.uris and self.ammo_file:
            raise StepperConfigurationError(
                'Both uris and ammo file specified. You must specify only one of them'
            )
        elif self.uris:
            ammo_gen = missile.UriStyleGenerator(
                self.uris, self.headers, http_ver=self.http_ver)
        elif self.ammo_file:
            if self.ammo_type in af_readers:
                if self.ammo_type == 'phantom':
                    opener = resource.get_opener(self.ammo_file)
                    with opener(self.use_cache) as ammo:
                        try:
                            if not ammo.next()[0].isdigit():
                                self.ammo_type = 'uri'
                                self.log.info(
                                    "Setting ammo_type 'uri' because ammo is not started with digit and you did not specify ammo format"
                                )
                            else:
                                self.log.info(
                                    "Default ammo type ('phantom') used, use 'phantom.ammo_type' option to override it"
                                )
                        except StopIteration:
                            self.log.exception(
                                "Couldn't read first line of ammo file")
                            raise AmmoFileError(
                                "Couldn't read first line of ammo file")
            else:
                raise NotImplementedError(
                    'No such ammo type implemented: "%s"' % self.ammo_type)
            ammo_gen = af_readers[self.ammo_type](
                self.ammo_file, headers=self.headers, http_ver=self.http_ver, use_cache=self.use_cache)
        else:
            raise StepperConfigurationError(
                'Ammo not found. Specify uris or ammo file')
        self.log.info("Using %s ammo reader" % type(ammo_gen).__name__)
        return ammo_gen


def _exc_to_net(param1, success):
    """ translate http code to net code. if accertion failed, set net code to 314 """
    if len(param1) <= 3:
        # FIXME: we're unable to use better logic here, because we should support non-http codes
        # but, we should look for core.util.HTTP or some other common logic
        # here
        if success:
            return 0
        else:
            return 314

    exc = param1.split(' ')[-1]
    if exc in KNOWN_EXC.keys():
        return KNOWN_EXC[exc]
    else:
        logger.warning(
            "Unknown Java exception, consider adding it to dictionary: %s",
            param1)
        return 41

translate http code to net code . if accertion failed set net code to 314


def _exc_to_http(param1):
    """ translate exception str to http code"""
    if len(param1) <= 3:
        try:
            int(param1)
        except BaseException:
            logger.error(
                "JMeter wrote some strange data into codes column: %s", param1)
        else:
            return int(param1)

    exc = param1.split(' ')[-1]
    if exc in KNOWN_EXC.keys():
        return 0
    else:
        logger.warning("Unknown Java exception. %s", param1)
        return 0


def read_config(self):
        """        Read phantom tool specific options        """
        self.threads = self.cfg["threads"] or str(int(multiprocessing.cpu_count() / 2) + 1)
        self.phantom_modules_path = self.cfg["phantom_modules_path"]
        self.additional_libs = ' '.join(self.cfg["additional_libs"])
        self.answ_log_level = self.cfg["writelog"]
        if self.answ_log_level.lower() in ['0', 'false']:
            self.answ_log_level = 'none'
        elif self.answ_log_level.lower() in ['1', 'true']:
            self.answ_log_level = 'all'
        self.timeout = parse_duration(self.cfg["timeout"])
        if self.timeout > 120000:
            logger.warning(
                "You've set timeout over 2 minutes."
                " Are you a functional tester?")
        self.answ_log = self.core.mkstemp(".log", "answ_")
        self.core.add_artifact_file(self.answ_log)
        self.core.add_artifact_file(self.phout_file)
        self.core.add_artifact_file(self.stat_log)
        self.phantom_log = self.core.mkstemp(".log", "phantom_")
        self.core.add_artifact_file(self.phantom_log)

        main_stream = StreamConfig(
            self.core,
            len(self.streams), self.phout_file, self.answ_log,
            self.answ_log_level, self.timeout, self.cfg, True)
        self.streams.append(main_stream)

        for section in self.multi():
            self.streams.append(
                StreamConfig(
                    self.core,
                    len(self.streams), self.phout_file, self.answ_log,
                    self.answ_log_level, self.timeout, section))

        for stream in self.streams:
            stream.read_config()

        if any(stream.ssl for stream in self.streams):
            self.additional_libs += ' ssl io_benchmark_method_stream_transport_ssl'


def compose_config(self):
        """        Generate phantom tool run config        """
        streams_config = ''
        stat_benchmarks = ''
        for stream in self.streams:
            streams_config += stream.compose_config()
            if not stream.is_main:
                stat_benchmarks += " " + "benchmark_io%s" % stream.sequence_no

        kwargs = {}
        kwargs['threads'] = self.threads
        kwargs['phantom_log'] = self.phantom_log
        kwargs['stat_log'] = self.stat_log
        kwargs['benchmarks_block'] = streams_config
        kwargs['stat_benchmarks'] = stat_benchmarks
        kwargs['additional_libs'] = self.additional_libs
        kwargs['phantom_modules_path'] = self.phantom_modules_path
        filename = self.core.mkstemp(".conf", "phantom_")
        self.core.add_artifact_file(filename)
        logger.debug("Generating phantom config: %s", filename)
        template_str = resource_string(__name__, "config/phantom.conf.tpl")
        tpl = string.Template(template_str)
        config = tpl.substitute(kwargs)

        with open(filename, 'w') as conffile:
            conffile.write(config)
        return filename

def
compose_config
(
self
)
:
streams_config
=
''
stat_benchmarks
=
''
for
stream
in
self
.
streams
:
streams_config
+=
stream
.
compose_config
(
)
if
not
stream
.
is_main
:
stat_benchmarks
+=
" "
+
"benchmark_io%s"
%
stream
.
sequence_no
kwargs
=
{
}
kwargs
[
'threads'
]
=
self
.
threads
kwargs
[
'phantom_log'
]
=
self
.
phantom_log
kwargs
[
'stat_log'
]
=
self
.
stat_log
kwargs
[
'benchmarks_block'
]
=
streams_config
kwargs
[
'stat_benchmarks'
]
=
stat_benchmarks
kwargs
[
'additional_libs'
]
=
self
.
additional_libs
kwargs
[
'phantom_modules_path'
]
=
self
.
phantom_modules_path
filename
=
self
.
core
.
mkstemp
(
".conf"
,
"phantom_"
)
self
.
core
.
add_artifact_file
(
filename
)
logger
.
debug
(
"Generating phantom config: %s"
,
filename
)
template_str
=
resource_string
(
__name__
,
"config/phantom.conf.tpl"
)
tpl
=
string
.
Template
(
template_str
)
config
=
tpl
.
substitute
(
kwargs
)
with
open
(
filename
,
'w'
)
as
conffile
:
conffile
.
write
(
config
)
return
filename


def get_info(self):
        """ get merged info about phantom conf """
        result = copy.copy(self.streams[0])
        result.stat_log = self.stat_log
        result.steps = []
        result.ammo_file = ''
        result.rps_schedule = None
        result.ammo_count = 0
        result.duration = 0

        result.instances = 0
        result.loadscheme = []
        result.loop_count = 0

        for stream in self.streams:
            sec_no = 0
            logger.debug("Steps: %s", stream.stepper_wrapper.steps)
            for item in stream.stepper_wrapper.steps:
                for x in range(0, item[1]):
                    if len(result.steps) > sec_no:
                        result.steps[sec_no][0] += item[0]
                    else:
                        result.steps.append([item[0], 1])
                    sec_no += 1

            if result.rps_schedule:
                result.rps_schedule = []
            else:
                result.rps_schedule = stream.stepper_wrapper.loadscheme
            if result.loadscheme:
                result.loadscheme = ''
            else:
                # FIXME: add formatted load scheme for server:
                # <step_size,step_type,first_rps,last_rps,original_step_params>
                # as a string
                result.loadscheme = ''

            if result.loop_count:
                result.loop_count = u'0'
            else:
                result.loop_count = stream.stepper_wrapper.loop_count

            result.ammo_file += '{} '.format(stream.stepper_wrapper.ammo_file)
            result.ammo_count += stream.stepper_wrapper.ammo_count
            result.duration = max(
                result.duration, stream.stepper_wrapper.duration)
            result.instances += stream.instances

        if not result.ammo_count:
            raise ValueError("Total ammo count cannot be zero")
        return result

def
get_info
(
self
)
:
result
=
copy
.
copy
(
self
.
streams
[
0
]
)
result
.
stat_log
=
self
.
stat_log
result
.
steps
=
[
]
result
.
ammo_file
=
''
result
.
rps_schedule
=
result
.
ammo_count
=
0
result
.
duration
=
0
result
.
instances
=
0
result
.
loadscheme
=
[
]
result
.
loop_count
=
0
for
stream
in
self
.
streams
:
sec_no
=
0
logger
.
debug
(
"Steps: %s"
,
stream
.
stepper_wrapper
.
steps
)
for
item
in
stream
.
stepper_wrapper
.
steps
:
for
x
in
range
(
0
,
item
[
1
]
)
:
if
len
(
result
.
steps
)
>
sec_no
:
result
.
steps
[
sec_no
]
[
0
]
+=
item
[
0
]
else
:
result
.
steps
.
append
(
[
item
[
0
]
,
1
]
)
sec_no
+=
1
if
result
.
rps_schedule
:
result
.
rps_schedule
=
[
]
else
:
result
.
rps_schedule
=
stream
.
stepper_wrapper
.
loadscheme
if
result
.
loadscheme
:
result
.
loadscheme
=
''
else
:
result
.
loadscheme
=
''
if
result
.
loop_count
:
result
.
loop_count
=
u'0'
else
:
result
.
loop_count
=
stream
.
stepper_wrapper
.
loop_count
result
.
ammo_file
+=
'{} '
.
format
(
stream
.
stepper_wrapper
.
ammo_file
)
result
.
ammo_count
+=
stream
.
stepper_wrapper
.
ammo_count
result
.
duration
=
max
(
result
.
duration
,
stream
.
stepper_wrapper
.
duration
)
result
.
instances
+=
stream
.
instances
if
not
result
.
ammo_count
:
raise
ValueError
(
"Total ammo count cannot be zero"
)
return
result


def compose_config(self):
        """ compose benchmark block """
        # step file
        self.stepper_wrapper.prepare_stepper()
        self.stpd = self.stepper_wrapper.stpd
        if self.stepper_wrapper.instances:
            self.instances = self.stepper_wrapper.instances

        if not self.stpd:
            raise RuntimeError("Cannot proceed with no STPD file")

        kwargs = {}
        kwargs['sequence_no'] = self.sequence_no
        if self.ssl:
            _auth_section = ''
            _ciphers = ''
            ssl_template = "transport_t ssl_transport = transport_ssl_t {\n" \
                           "                timeout = 1s\n" \
                           "                %s\n" \
                           "                %s}\n" \
                           "                transport = ssl_transport"

            if self.client_certificate or self.client_key:
                _auth_section = 'auth_t def_auth = auth_t { key = "%s" cert = "%s"} auth = def_auth' \
                                % (self.client_key, self.client_certificate)
            if self.client_cipher_suites:
                _ciphers = 'ciphers = "%s"' % self.client_cipher_suites
            kwargs['ssl_transport'] = ssl_template % (_auth_section, _ciphers)
        else:
            kwargs['ssl_transport'] = ""
        kwargs['method_stream'] = self.method_prefix + \
            "_ipv6_t" if self.ipv6 else self.method_prefix + "_ipv4_t"
        kwargs['phout'] = self.phout_file
        kwargs['answ_log'] = self.answ_log
        kwargs['answ_log_level'] = self.answ_log_level
        kwargs['comment_answ'] = "# " if self.answ_log_level == 'none' else ''
        kwargs['stpd'] = self.stpd
        kwargs['source_log_prefix'] = self.source_log_prefix
        kwargs['method_options'] = self.method_options
        if self.tank_type:
            kwargs[
                'proto'] = "proto=http_proto%s" % self.sequence_no if self.tank_type == 'http' else "proto=none_proto"
            kwargs['comment_proto'] = ""
        else:
            kwargs['proto'] = ""
            kwargs['comment_proto'] = "#"

        if self.gatling:
            kwargs['bind'] = 'bind={ ' + self.gatling + ' }'
        else:
            kwargs['bind'] = ''
        kwargs['ip'] = self.resolved_ip
        kwargs['port'] = self.port
        kwargs['timeout'] = self.timeout
        kwargs['instances'] = self.instances
        tune = ''
        if self.phantom_http_entity:
            tune += "entity = " + self.phantom_http_entity + "\n"
        if self.phantom_http_field:
            tune += "field = " + self.phantom_http_field + "\n"
        if self.phantom_http_field_num:
            tune += "field_num = {}\n".format(self.phantom_http_field_num)
        if self.phantom_http_line:
            tune += "line = " + self.phantom_http_line + "\n"
        if tune:
            kwargs['reply_limits'] = 'reply_limits = {\n' + tune + "}"
        else:
            kwargs['reply_limits'] = ''

        if self.is_main:
            fname = 'phantom_benchmark_main.tpl'
        else:
            fname = 'phantom_benchmark_additional.tpl'
        template_str = resource_string(
            __name__, "config/" + fname)
        tpl = string.Template(template_str)
        config = tpl.substitute(kwargs)

        return config

"                transport = ssl_transport"


def log_stdout_stderr(log, stdout, stderr, comment=""):
    """
    This function polls stdout and stderr streams and writes their contents
    to log
    """
    readable = select.select([stdout], [], [], 0)[0]
    if stderr:
        exceptional = select.select([stderr], [], [], 0)[0]
    else:
        exceptional = []

    log.debug("Selected: %s, %s", readable, exceptional)

    for handle in readable:
        line = handle.read()
        readable.remove(handle)
        if line:
            log.debug("%s stdout: %s", comment, line.strip())

    for handle in exceptional:
        line = handle.read()
        exceptional.remove(handle)
        if line:
            log.warn("%s stderr: %s", comment, line.strip())

def
log_stdout_stderr
(
log
,
stdout
,
stderr
,
comment
=
""
)
:
readable
=
select
.
select
(
[
stdout
]
,
[
]
,
[
]
,
0
)
[
0
]
if
stderr
:
exceptional
=
select
.
select
(
[
stderr
]
,
[
]
,
[
]
,
0
)
[
0
]
else
:
exceptional
=
[
]
log
.
debug
(
"Selected: %s, %s"
,
readable
,
exceptional
)
for
handle
in
readable
:
line
=
handle
.
read
(
)
readable
.
remove
(
handle
)
if
line
:
log
.
debug
(
"%s stdout: %s"
,
comment
,
line
.
strip
(
)
)
for
handle
in
exceptional
:
line
=
handle
.
read
(
)
exceptional
.
remove
(
handle
)
if
line
:
log
.
warn
(
"%s stderr: %s"
,
comment
,
line
.
strip
(
)
)


def expand_time(str_time, default_unit='s', multiplier=1):
    """
    helper for above functions
    """
    parser = re.compile(r'(\d+)([a-zA-Z]*)')
    parts = parser.findall(str_time)
    result = 0.0
    for value, unit in parts:
        value = int(value)
        unit = unit.lower()
        if unit == '':
            unit = default_unit

        if unit == 'ms':
            result += value * 0.001
            continue
        elif unit == 's':
            result += value
            continue
        elif unit == 'm':
            result += value * 60
            continue
        elif unit == 'h':
            result += value * 60 * 60
            continue
        elif unit == 'd':
            result += value * 60 * 60 * 24
            continue
        elif unit == 'w':
            result += value * 60 * 60 * 24 * 7
            continue
        else:
            raise ValueError(
                "String contains unsupported unit %s: %s" % (unit, str_time))
    return int(result * multiplier)


def read_config(self):
        ''' stepper part of reading options '''
        self.log.info("Configuring StepperWrapper...")
        self.ammo_file = self.get_option(self.OPTION_AMMOFILE)
        self.ammo_type = self.get_option('ammo_type')
        if self.ammo_file:
            self.ammo_file = os.path.expanduser(self.ammo_file)
        self.loop_limit = self.get_option(self.OPTION_LOOP)
        self.ammo_limit = self.get_option("ammo_limit")

        self.load_profile = LoadProfile(**self.get_option('load_profile'))

        self.instances = int(
            self.get_option(self.OPTION_INSTANCES_LIMIT, '1000'))
        self.uris = self.get_option("uris", [])
        while '' in self.uris:
            self.uris.remove('')
        self.headers = self.get_option("headers")
        self.http_ver = self.get_option("header_http")
        self.autocases = self.get_option("autocases")
        self.enum_ammo = self.get_option("enum_ammo")
        self.use_caching = self.get_option("use_caching")

        self.file_cache = self.get_option('file_cache')
        cache_dir = self.get_option("cache_dir") or self.core.artifacts_base_dir
        self.cache_dir = os.path.expanduser(cache_dir)
        self.force_stepping = self.get_option("force_stepping")
        if self.get_option(self.OPTION_LOAD)[self.OPTION_LOAD_TYPE] == 'stpd_file':
            self.stpd = self.get_option(self.OPTION_LOAD)[self.OPTION_SCHEDULE]

        self.chosen_cases = self.get_option("chosen_cases").split()
        if self.chosen_cases:
            self.log.info("chosen_cases LIMITS: %s", self.chosen_cases)

def
read_config
(
self
)
:
self
.
log
.
info
(
"Configuring StepperWrapper..."
)
self
.
ammo_file
=
self
.
get_option
(
self
.
OPTION_AMMOFILE
)
self
.
ammo_type
=
self
.
get_option
(
'ammo_type'
)
if
self
.
ammo_file
:
self
.
ammo_file
=
os
.
path
.
expanduser
(
self
.
ammo_file
)
self
.
loop_limit
=
self
.
get_option
(
self
.
OPTION_LOOP
)
self
.
ammo_limit
=
self
.
get_option
(
"ammo_limit"
)
self
.
load_profile
=
LoadProfile
(
**
self
.
get_option
(
'load_profile'
)
)
self
.
instances
=
int
(
self
.
get_option
(
self
.
OPTION_INSTANCES_LIMIT
,
'1000'
)
)
self
.
uris
=
self
.
get_option
(
"uris"
,
[
]
)
while
''
in
self
.
uris
:
self
.
uris
.
remove
(
''
)
self
.
headers
=
self
.
get_option
(
"headers"
)
self
.
http_ver
=
self
.
get_option
(
"header_http"
)
self
.
autocases
=
self
.
get_option
(
"autocases"
)
self
.
enum_ammo
=
self
.
get_option
(
"enum_ammo"
)
self
.
use_caching
=
self
.
get_option
(
"use_caching"
)
self
.
file_cache
=
self
.
get_option
(
'file_cache'
)
cache_dir
=
self
.
get_option
(
"cache_dir"
)
or
self
.
core
.
artifacts_base_dir
self
.
cache_dir
=
os
.
path
.
expanduser
(
cache_dir
)
self
.
force_stepping
=
self
.
get_option
(
"force_stepping"
)
if
self
.
get_option
(
self
.
OPTION_LOAD
)
[
self
.
OPTION_LOAD_TYPE
]
==
'stpd_file'
:
self
.
stpd
=
self
.
get_option
(
self
.
OPTION_LOAD
)
[
self
.
OPTION_SCHEDULE
]
self
.
chosen_cases
=
self
.
get_option
(
"chosen_cases"
)
.
split
(
)
if
self
.
chosen_cases
:
self
.
log
.
info
(
"chosen_cases LIMITS: %s"
,
self
.
chosen_cases
)


def prepare_stepper(self):
        ''' Generate test data if necessary '''

        def publish_info(stepper_info):
            info.status.publish('loadscheme', stepper_info.loadscheme)
            info.status.publish('loop_count', stepper_info.loop_count)
            info.status.publish('steps', stepper_info.steps)
            info.status.publish('duration', stepper_info.duration)
            info.status.ammo_count = stepper_info.ammo_count
            info.status.publish('instances', stepper_info.instances)
            self.core.publish('stepper', 'loadscheme', stepper_info.loadscheme)
            self.core.publish('stepper', 'loop_count', stepper_info.loop_count)
            self.core.publish('stepper', 'steps', stepper_info.steps)
            self.core.publish('stepper', 'duration', stepper_info.duration)
            self.core.publish('stepper', 'ammo_count', stepper_info.ammo_count)
            self.core.publish('stepper', 'instances', stepper_info.instances)
            return stepper_info

        if not self.stpd:
            self.stpd = self.__get_stpd_filename()
            if self.use_caching and not self.force_stepping and os.path.exists(
                    self.stpd) and os.path.exists(self.__si_filename()):
                self.log.info("Using cached stpd-file: %s", self.stpd)
                stepper_info = self.__read_cached_options()
                if self.instances and self.load_profile.is_rps():
                    self.log.info(
                        "rps_schedule is set. Overriding cached instances param from config: %s",
                        self.instances)
                    stepper_info = stepper_info._replace(
                        instances=self.instances)
                publish_info(stepper_info)
            else:
                if (
                        self.force_stepping and os.path.exists(self.__si_filename())):
                    os.remove(self.__si_filename())
                self.__make_stpd_file()
                stepper_info = info.status.get_info()
                self.__write_cached_options(stepper_info)
        else:
            self.log.info("Using specified stpd-file: %s", self.stpd)
            stepper_info = publish_info(self.__read_cached_options())
        self.ammo_count = stepper_info.ammo_count
        self.duration = stepper_info.duration
        self.loop_count = stepper_info.loop_count
        self.loadscheme = stepper_info.loadscheme
        self.steps = stepper_info.steps
        if stepper_info.instances:
            self.instances = stepper_info.instances


def __get_stpd_filename(self):
        ''' Choose the name for stepped data file '''
        if self.use_caching:
            sep = "|"
            hasher = hashlib.md5()
            hashed_str = "cache version 6" + sep + \
                ';'.join(self.load_profile.schedule) + sep + str(self.loop_limit)
            hashed_str += sep + str(self.ammo_limit) + sep + ';'.join(
                self.load_profile.schedule) + sep + str(self.autocases)
            hashed_str += sep + ";".join(self.uris) + sep + ";".join(
                self.headers) + sep + self.http_ver + sep + ";".join(
                    self.chosen_cases)
            hashed_str += sep + str(self.enum_ammo) + sep + str(self.ammo_type)
            if self.load_profile.is_instances():
                hashed_str += sep + str(self.instances)
            if self.ammo_file:
                opener = resource.get_opener(self.ammo_file)
                hashed_str += sep + opener.hash
            else:
                if not self.uris:
                    raise RuntimeError("Neither ammofile nor uris specified")
                hashed_str += sep + \
                    ';'.join(self.uris) + sep + ';'.join(self.headers)
            self.log.debug("stpd-hash source: %s", hashed_str)
            hasher.update(hashed_str.encode('utf8'))
            if not os.path.exists(self.cache_dir):
                os.makedirs(self.cache_dir)
            stpd = self.cache_dir + '/' + \
                os.path.basename(self.ammo_file) + \
                "_" + hasher.hexdigest() + ".stpd"
        else:
            stpd = os.path.realpath("ammo.stpd")
        self.log.debug("Generated cache file name: %s", stpd)
        return stpd

def
__get_stpd_filename
(
self
)
:
if
self
.
use_caching
:
sep
=
"|"
hasher
=
hashlib
.
md5
(
)
hashed_str
=
"cache version 6"
+
sep
+
';'
.
join
(
self
.
load_profile
.
schedule
)
+
sep
+
str
(
self
.
loop_limit
)
hashed_str
+=
sep
+
str
(
self
.
ammo_limit
)
+
sep
+
';'
.
join
(
self
.
load_profile
.
schedule
)
+
sep
+
str
(
self
.
autocases
)
hashed_str
+=
sep
+
";"
.
join
(
self
.
uris
)
+
sep
+
";"
.
join
(
self
.
headers
)
+
sep
+
self
.
http_ver
+
sep
+
";"
.
join
(
self
.
chosen_cases
)
hashed_str
+=
sep
+
str
(
self
.
enum_ammo
)
+
sep
+
str
(
self
.
ammo_type
)
if
self
.
load_profile
.
is_instances
(
)
:
hashed_str
+=
sep
+
str
(
self
.
instances
)
if
self
.
ammo_file
:
opener
=
resource
.
get_opener
(
self
.
ammo_file
)
hashed_str
+=
sep
+
opener
.
hash
else
:
if
not
self
.
uris
:
raise
RuntimeError
(
"Neither ammofile nor uris specified"
)
hashed_str
+=
sep
+
';'
.
join
(
self
.
uris
)
+
sep
+
';'
.
join
(
self
.
headers
)
self
.
log
.
debug
(
"stpd-hash source: %s"
,
hashed_str
)
hasher
.
update
(
hashed_str
.
encode
(
'utf8'
)
)
if
not
os
.
path
.
exists
(
self
.
cache_dir
)
:
os
.
makedirs
(
self
.
cache_dir
)
stpd
=
self
.
cache_dir
+
'/'
+
os
.
path
.
basename
(
self
.
ammo_file
)
+
"_"
+
hasher
.
hexdigest
(
)
+
".stpd"
else
:
stpd
=
os
.
path
.
realpath
(
"ammo.stpd"
)
self
.
log
.
debug
(
"Generated cache file name: %s"
,
stpd
)
return
stpd


def __read_cached_options(self):
        '''
        Read stepper info from json
        '''
        self.log.debug("Reading cached stepper info: %s", self.__si_filename())
        with open(self.__si_filename(), 'r') as si_file:
            si = info.StepperInfo(**json.load(si_file))
        return si

def
__read_cached_options
(
self
)
:
self
.
log
.
debug
(
"Reading cached stepper info: %s"
,
self
.
__si_filename
(
)
)
with
open
(
self
.
__si_filename
(
)
,
'r'
)
as
si_file
:
si
=
info
.
StepperInfo
(
**
json
.
load
(
si_file
)
)
return
si