def caa_attack(self, images: "torch.Tensor", labels: "torch.Tensor") -> "torch.Tensor":
        """
        The main algorithm to generate the adversarial examples for composite adversarial attack.

        :param images: A tensor of a batch of original inputs to be attacked.
        :param labels: A tensor of a batch of the original labels to be predicted.
        :return: The perturbed data.
        """
        import torch

        adv_img = images.detach().clone()
        adv_val_saved = torch.zeros((self.seq_num, self.batch_size), device=self.device)
        adv_val = [self.adv_val_space[idx] for idx in range(self.seq_num)]

        if self.is_attacked.sum() > 0:
            for att_id in range(self.seq_num):
                if att_id == self.linf_idx:
                    continue
                adv_val[att_id].detach()
                adv_val[att_id][self.is_attacked] = adv_val_saved[att_id][self.is_attacked]
                adv_val[att_id].requires_grad_()

        for _ in range(self.max_iter):
            self.update_attack_order(images, labels, adv_val)

            adv_img = adv_img.detach().clone()
            self.is_not_attacked = torch.logical_not(self.is_attacked)
            adv_img[self.is_not_attacked] = images[self.is_not_attacked].clone()
            adv_img.requires_grad = True

            for tdx in range(self.seq_num):
                idx = self.curr_seq[tdx]
                adv_img, adv_val_updated = self.attack_dict[idx](adv_img, adv_val[idx], labels)  # type: ignore
                if idx != self.linf_idx:
                    adv_val[idx] = adv_val_updated

            outputs = self.model(adv_img)
            cur_pred = outputs.max(1, keepdim=True)[1].squeeze()
            self.is_attacked = torch.logical_or(self.is_attacked, cur_pred != labels.max(1, keepdim=True)[1].squeeze())

            if self.is_attacked.sum() > 0:
                for att_id in range(self.seq_num):
                    if att_id == self.linf_idx:
                        continue
                    adv_val_saved[att_id][self.is_attacked] = adv_val[att_id][self.is_attacked].detach()

            if self.is_attacked.sum() == self.batch_size:
                break

        return adv_img

        The main algorithm to generate the adversarial examples for composite adversarial attack.

        :param images: A tensor of a batch of original inputs to be attacked.
        :param labels: A tensor of a batch of the original labels to be predicted.
        :return: The perturbed data.
        
art/attacks/evasion/composite_adversarial_attack.py