def find_tensors(sources, predicate):
    """
    find all the tensors that are used for computing grads and has been
    computed during forward
    :param grads:
    :param forward_ops:
    :return:
    """
    from collections import deque
    import tensorflow as tf
    queue = deque([])
    for source in sources:
        queue.append(source)
    results = set()
    visited = set()
    while len(queue) > 0:
        node = queue.popleft()
        if node is None:
            continue
        else:
            visited.add(node.name)
            if predicate(node):
                results.add(node)
            if isinstance(node, tf.Tensor):
                inputs = list(node.op.inputs) + list(node.op.control_inputs)
            elif isinstance(node, tf.Operation):
                inputs = list(node.inputs) + list(node.control_inputs)
            else:
                raise ValueError('Unrecognized Node: {}'.format(node))
            for input_tensor in inputs:
                if input_tensor.name not in visited:
                    queue.append(input_tensor)
    return list(results)
