# Buggy code
def generate(self, x, **kwargs):
    """
    Generate adversarial samples and return them in an array.

    :param x: An array with the original inputs.
    :type x: `np.ndarray`
    :param norm: Order of the norm. Possible values: np.inf, 1 or 2.
    :type norm: `int`
    :param eps: Maximum perturbation that the attacker can introduce.
    :type eps: `float`
    :param eps_step: Attack step size (input variation) at each iteration.
    :type eps_step: `float`
    :param y: The labels for the data `x`. Only provide this parameter if you'd like to use true
              labels when crafting adversarial samples. Otherwise, model predictions are used as labels to avoid the
              "label leaking" effect (explained in this paper: https://arxiv.org/abs/1611.01236). Default is `None`.
              Labels should be one-hot-encoded.
    :type y: `np.ndarray`
    :return: An array holding the adversarial examples.
    :rtype: `np.ndarray`
    """
    from art.utils import projection

    self.set_params(**kwargs)

    adv_x = x.copy()
    if "y" not in kwargs or kwargs[str("y")] is None:
        # Throw error if attack is targeted, but no targets are provided
        if self.targeted:
            raise ValueError(
                "Target labels `y` need to be provided for a targeted attack."
            )

        # Use model predictions as correct outputs
        targets = get_labels_np_array(self.classifier.predict(x))
    else:
        targets = kwargs["y"]
    target_labels = np.argmax(targets, axis=1)

    for i in range(self.max_iter):
        # Adversarial crafting
        adv_x = self._compute(
            adv_x, targets, self.eps_step, self.random_init and i == 0
        )

        if self._project:
            noise = projection(adv_x - x, self.eps, self.norm)
            adv_x = x + noise

    adv_preds = np.argmax(self.classifier.predict(adv_x), axis=1)
    if self.targeted:
        rate = np.sum(adv_preds == target_labels) / adv_x.shape[0]
    else:
        rate = np.sum(adv_preds != target_labels) / adv_x.shape[0]
    logger.info("Success rate of BIM attack: %.2f%%", rate)

    return adv_x


# Traceback (IndexError)
Traceback (most recent call last):
File "cw_pytorch.py", line 172, in <module>
x_test_adv = cl2m.generate(inputs, **params)
File "/home/weitian/anaconda3/envs/xnor/lib/python3.6/site-packages/art/attacks/carlini.py", line 380, in generate
x_adv_batch_tanh[active_and_update_adv] = x_adv_batch_tanh[update_adv] + \
IndexError: boolean index did not match indexed array along dimension 0; dimension is 18 but corresponding boolean dimension is 17

# Fixed code
def generate(self, x, **kwargs):
    """
    Generate adversarial samples and return them in an array.

    :param x: An array with the original inputs.
    :type x: `np.ndarray`
    :param norm: Order of the norm. Possible values: np.inf, 1 or 2.
    :type norm: `int`
    :param eps: Maximum perturbation that the attacker can introduce.
    :type eps: `float`
    :param eps_step: Attack step size (input variation) at each iteration.
    :type eps_step: `float`
    :param y: The labels for the data `x`. Only provide this parameter if you'd like to use true
              labels when crafting adversarial samples. Otherwise, model predictions are used as labels to avoid the
              "label leaking" effect (explained in this paper: https://arxiv.org/abs/1611.01236). Default is `None`.
              Labels should be one-hot-encoded.
    :type y: `np.ndarray`
    :param random_init: Whether to start at the original input or a random point within the epsilon ball
    :type random_init: `bool`
    :param batch_size: Batch size
    :type batch_size: `int`
    :return: An array holding the adversarial examples.
    :rtype: `np.ndarray`
    """
    from art.utils import projection

    self.set_params(**kwargs)

    adv_x = x.copy()
    if "y" not in kwargs or kwargs[str("y")] is None:
        # Throw error if attack is targeted, but no targets are provided
        if self.targeted:
            raise ValueError(
                "Target labels `y` need to be provided for a targeted attack."
            )

        # Use model predictions as correct outputs
        targets = get_labels_np_array(self._predict(x))
    else:
        targets = kwargs["y"]
    target_labels = np.argmax(targets, axis=1)

    for i in range(self.max_iter):
        # Adversarial crafting
        adv_x = self._compute(
            adv_x, targets, self.eps_step, self.random_init and i == 0
        )

        if self._project:
            noise = projection(adv_x - x, self.eps, self.norm)
            adv_x = x + noise

    adv_preds = np.argmax(self._predict(adv_x), axis=1)
    if self.targeted:
        rate = np.sum(adv_preds == target_labels) / adv_x.shape[0]
    else:
        rate = np.sum(adv_preds != target_labels) / adv_x.shape[0]
    logger.info("Success rate of BIM attack: %.2f%%", rate)

    return adv_x