RuntimeError: stack expects a non-empty TensorList with pytorch

first of all I thank , I tried to train model with pytorch but I got the following error: RuntimeError: stack expects a non-empty TensorList .I am trying to model a extract features point cloud using deep learning in pytorch. I get the following error . Could anyone help on this? ************** *************** Thanks!

def training_loop(gpu, training_dataloader, model, loss_fn, optimizer):
    losses = []
    correct = 0
    batch_results = dict()
    conf_mat = np.zeros((10,10))
    for batch_n, batch in enumerate(training_dataloader): #batch[batch, pos, ptr, y]
        batch_size = int(batch.batch.size()[0] / sample_points)        
        
        if dimensionality == 3:
            # Input dim [:,3] for your geometry x,y,z
            X = batch.pos.cuda(non_blocking=True).view(batch_size, sample_points, -1) + torch.normal(
                torch.zeros(batch_size, sample_points, dimensionality), torch.full((batch_size, sample_points,
                                                                                   dimensionality), fill_value=0.1)).cuda(gpu)
        else:
            # Input dim [:,6] for your geometry x,y,z and normals nx,ny,nz
            X = torch.cat((batch.pos.cuda(non_blocking=True), batch.normal.cuda(non_blocking=True)), 1).view(batch_size, sample_points, -1) + torch.normal(
                torch.zeros(batch_size, sample_points, dimensionality), torch.full((batch_size, sample_points,
                                                                                   dimensionality), fill_value=0.1)).cuda(gpu)
        
        y = batch.y.cuda(non_blocking=True).flatten() #size (batch_size) --> torch.Size([8])
        
        # Compute predictions
        pred = model(None, X) #size (batch_size,classes) --> torch.Size([8, 10])
        
        if overall_classes_loss:
            # weighted CE Loss over all classes
            loss = loss_fn(pred, y)
        else:
            # weighted batchwise Loss
            sample_count = np.array([[x, batch.y.tolist().count(x)] for x in batch.y])[:,1]
            batch_weights = 1. / sample_count
            batch_weights = torch.from_numpy(batch_weights)
            batch_weights = batch_weights.double()
            loss = element_weighted_loss(pred, batch.y, batch_weights, gpu)
        
        correct += (pred.argmax(1) == y).type(torch.float).sum().item()
        print(f"Loss: {loss}")

        tensor_list_y =  [torch.ones_like(y) for _ in range(dist.get_world_size())]
        tensor_list_pred = [torch.ones_like(y) for _ in range(dist.get_world_size())]
        torch.distributed.all_gather(tensor_list_y, y, group=None, async_op=False)
        torch.distributed.all_gather(tensor_list_pred, pred.argmax(1), group=None, async_op=False)
        tensor_list_y = torch.cat(tensor_list_y)
        tensor_list_pred = torch.cat(tensor_list_pred)
        
        # Confusion Matrix
        conf_mat += confusion_matrix(tensor_list_y.cpu().detach().numpy(), tensor_list_pred.cpu().detach().numpy(), labels=np.arange(0,10))
        
        # Backpropagation
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        losses.append(loss.item())
        
        # Save batch predictions
        batch_results[batch_n] = {'true':tensor_list_y, 'pred':tensor_list_pred}
        
        if verbosity == True:
            print(f"\n\nTRAIN on GPU:{gpu}: True Label {y} - Prediction {pred.argmax(1)} - Loss {loss}")
            truevalue = '\t\t'.join(classes[items] for items in y.tolist())
            predvalues = '\t\t'.join(classes[items] for items in pred.argmax(1).tolist())
            print(f"INFO on GPU:{gpu}: TRAIN - True Value\t {truevalue}")
            print(f"INFO on GPU:{gpu}: TRAIN - Predictions\t {predvalues}")
        
        if batch_n % 25 == 0:
            torch.distributed.reduce(loss, 0)
            """if gpu == 0:
                # print predictions and true values
                #truevalue = '\t\t'.join(classes[items] for items in y.tolist())
                #predvalues = '\t\t'.join(classes[items] for items in pred.argmax(1).tolist())
                #print(f"\n\nINFO on GPU{gpu}: TRAIN - True Value\t {truevalue}")
                #print(f"INFO on GPU{gpu}: TRAIN - Predictions\t {predvalues}")
                #print("INFO: TRAIN - Correctness\t", pred.argmax(1) == y)
                #print(f"INFO: TRAIN - Single Batch Test Accuracy {correct * 100 / batch_size}\n\n")
                loss, current = loss.item(), batch_n * len(X)
                #print(f"loss: {loss:>7f}")"""
        #print(f"conf_mat: {conf_mat}")
        #print(f"batch_results: {batch_results}")

    return torch.tensor(losses, device=f"cuda:{gpu}"), torch.tensor(correct, device=f"cuda:{gpu}"), batch_results, conf_mat


def train_optimisation(gpu, gpus, training_dataloader, test_dataloader, model, loss_fn, optimizer, scheduler, dir_path, initial_epoch):
    epoch_losses = []
    training_accuracies = []
    test_losses = []
    test_accuracies = []
    learning_rates = []
    counter = 0 #early stopping counter
    batchwise_results = dict()
    
    # Learning Rate Scheduler
    scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='min', patience=20)

    for i in range(initial_epoch, initial_epoch + epochs):
        if gpu == 0:
            if initial_epoch > 0:
                print(f"\n\nEpoch {i}\n-------------------------------")
            else:
                print(f"\n\nEpoch {i + 1}\n-------------------------------")

        # TRAIN
        losses, training_accuracy, train_batch_result, train_conf_mat = training_loop(gpu, training_dataloader, model, loss_fn, optimizer)
        average_loss = torch.mean(losses)
        torch.distributed.reduce(average_loss, 0, torch.distributed.ReduceOp.SUM)
        torch.distributed.reduce(training_accuracy, 0, torch.distributed.ReduceOp.SUM)
        
        # TEST
        test_accuracy, test_loss, test_batch_result, test_conf_mat = test_loop(gpu, test_dataloader, model, loss_fn)
        torch.distributed.reduce(test_accuracy, 0, torch.distributed.ReduceOp.SUM)
        torch.distributed.reduce(test_loss, 0, torch.distributed.ReduceOp.SUM)
                
        # save results
        batchwise_results[i] = {'train':train_batch_result, 'test':test_batch_result}
        if gpu == 0:  # the following operations are performed only by the process running in the first gpu
            average_loss = average_loss / torch.tensor(gpus, dtype=torch.float)  # average loss among all gpus
            test_accuracy = test_accuracy / torch.tensor(len(test_dataloader.dataset),
                                                         dtype=torch.float) * torch.tensor(100.0)
            training_accuracy = training_accuracy / torch.tensor(len(training_dataloader.dataset),
                                                                 dtype=torch.float) * torch.tensor(100.0)
            test_loss = test_loss / torch.tensor(gpus, dtype=torch.float)
            epoch_losses.append(average_loss.item())
            training_accuracies.append(training_accuracy.item())
            test_losses.append(test_loss.item())
            test_accuracies.append(test_accuracy.item())
            learning_rates.append((optimizer.param_groups[0])["lr"])
            print(f"\nBatch size: {batch_size * int(gpus)}")
            print(f"average Training Loss: {average_loss.item():.6f}")
            print(f"average Test Loss: {test_loss.item():.6f}")
            print(f"\naverage Training Acc: {training_accuracy.item():.6f}")
            print(f"average Test Acc: {test_accuracy.item():.6f}")
            printLearningRate(optimizer)
            scheduler.step(test_loss)
            
            """# stepwise learning rate decay
            if average_loss.item() <= 0.35:
                for param_group in optimizer.param_groups:
                    print("Learning rate changed to 0.007")
                    param_group['lr'] = 0.007
            if average_loss.item() <= 0.30:
                for param_group in optimizer.param_groups:
                    print("Learning rate changed to 0.004")
                    param_group['lr'] = 0.004"""
            
            # saving model checkpoint
            save_checkpoint(model, optimizer, scheduler, i, epoch_losses, training_accuracies, test_losses, test_accuracies, learning_rates,
                            os.path.join(dir_path, f"epoch{i}.pth"), {key: value for key, value in batchwise_results[i].items() if key == 'train'}, {key: value for key, value in batchwise_results[i].items() if key == 'test'}, train_conf_mat, test_conf_mat)
            #TODO: implement ONNX Export
            # early stopping scheduler
            if early_stopping(test_losses) == True:
                counter += 1
                print(f"Early Stopping counter: {counter} of {patience}")
            else:
                counter += 0                        
            if counter < patience:
                pass
            else:
                print("\n\nEarly Stopping activated")
                print(f"Training stopped at Epoch{i + 1}")
                dist.destroy_process_group()
                exit()
class DistributedWeightedSampler(Sampler):
    def __init__(self, dataset, data_source: Optional[Sized], num_replicas: Optional[int] = None,
                 rank: Optional[int] = None, shuffle: bool = True, seed: int = 0, replacement: bool = True):
        super().__init__(data_source)
        if num_replicas is None:
            if not dist.is_available():
                raise RuntimeError("Requires distributed package to be available")
            num_replicas = dist.get_world_size()
        if rank is None:
            if not dist.is_available():
                raise RuntimeError("Requires distributed package to be available")
            rank = dist.get_rank()
        if rank >= num_replicas or rank < 0:
            raise ValueError("Invalid rank {}, rank should be in the interval [0, {}]".format(rank, num_replicas - 1))
        self.dataset = dataset
        self.num_replicas = num_replicas
        self.rank = rank
        self.epoch = 0
        self.num_samples = int(math.ceil(len(self.dataset) * 1.0 / self.num_replicas))
        self.total_size = self.num_samples * self.num_replicas
        self.shuffle = shuffle
        self.seed = seed
        self.replacement = replacement #sample can be drown again in that row if True

    def calculate_weights(self, targets):
        class_sample_count = np.array([len(np.where(self.dataset.data.y == t)[0]) for t in np.unique(self.dataset.data.y)])
        weight = 1. / class_sample_count
        samples_weight = np.array([weight[t] for t in self.dataset.data.y])
        samples_weight = torch.from_numpy(samples_weight)
        samples_weigth = samples_weight.double()
        return samples_weigth

    def __iter__(self):
        # deterministically shuffle based on epoch
        if self.shuffle:
            g = torch.Generator()
            g.manual_seed(self.seed + self.epoch)
            indices = torch.randperm(len(self.dataset), generator=g).tolist()
        else:
            indices = list(range(len(self.dataset)))

        # add extra samples to make it evenly divisible
        indices += indices[:(self.total_size - len(indices))]
        assert len(indices) == self.total_size

        # subsample
        indices = indices[self.rank:self.total_size:self.num_replicas]
        assert len(indices) == self.num_samples

        # get targets (you can alternatively pass them in __init__, if this op is expensive)
        # data.data.y == labels
        targets = self.dataset.data.y
        targets = targets[self.rank:self.total_size:self.num_replicas]
        #assert len(targets) == self.num_samples
        weights = self.calculate_weights(targets)
        weighted_indices = torch.multinomial(weights, self.num_samples, self.replacement).tolist()

        return iter(weighted_indices)

    def __len__(self):
        return self.num_samples

    def set_epoch(self, epoch):
        self.epoch = epoch
def train(gpu, gpus, world_size):
    torch.manual_seed(0)
    torch.cuda.set_device(gpu)
    try:
        #dist.init_process_group(backend='nccl', world_size=world_size, rank=gpu) #for distributed GPU training
        dist.init_process_group(backend='gloo', world_size=world_size, rank=gpu) #as a fallback option
    except RuntimeError:
        print("\n\nINFO:RuntimeError is raised >> Used gloo backend instead of nccl!\n")
        dist.init_process_group(backend='gloo', world_size=world_size, rank=gpu) #as a fallback option
    
    dir_path = None
    if gpu == 0:
        dir_path = "stackgraphConvPool3DPnet"
        createdir(dir_path)
        training_number = next_training_number(dir_path)
        dir_path = os.path.join(dir_path, f"train{training_number}")
        createdir(dir_path)
        #save hyper-parameters in txt protocol file
        save_hyperparameters(dir_path, 'hyperparameters.txt')
        print("\nINFO: Protocol File saved successfully . . .")
        
        #copy crucial py-files in current train folder
        #shutil.copy2(os.path.basename('__file__'), dir_path)
        #shutil.copy2('stackGraphConvPool3DPnet.py', dir_path)
        #shutil.copy2('shrinkingunit.py', dir_path)
        #shutil.copy2('utilities.py', dir_path)
        #print("\nINFO: Script Files copied successfully . . .")

    model = Classifier(shrinkingLayers, mlpClassifier)

    torch.cuda.set_device(gpu)
    model.cuda(gpu)
    
    #setting up optimizer
    if optimizer_str == "SGD":
        optimizer = torch.optim.SGD(model.parameters(), learning_rate, momentum=momentum, weight_decay=weight_decay)
    elif optimizer_str == "RMSprop":
        optimizer = torch.optim.RMSprop(model.parameters(), learning_rate, weight_decay=weight_decay)
    else:
        optimizer = torch.optim.Adam(model.parameters(), learning_rate, weight_decay=weight_decay)
    
    # single-program multiple-data training paradigm (Distributed Data-Parallel Training)
    model = DDP(model, device_ids=[gpu])
    
    if dimensionality == 3:
        training_data = ModelNet("ModelNet10_train_data", transform=lambda x: NormalizeScale()(SamplePoints(num=sample_points)(x)))
    else:
        training_data = ModelNet("ModelNet10_train_data", transform=lambda x: NormalizeScale()(NormalizeRotation()(SamplePoints(num=sample_points, remove_faces=True, include_normals=True)(x))))
    
    training_sampler = DistributedWeightedSampler(training_data, data_source=None, num_replicas=world_size) #weight unbalanced classes by 1/cls_count
    training_dataloader = DataLoader(dataset=training_data, batch_size=batch_size, shuffle=data_shuffle, num_workers=0,
                                          pin_memory=True, sampler=training_sampler)
    
    if dimensionality == 3:
        test_data = ModelNet("ModelNet10_test_data", train=False, transform=lambda x: NormalizeScale()(SamplePoints(num=sample_points)(x)))
    else:
        test_data = ModelNet("ModelNet10_test_data", train=False, transform=lambda x: NormalizeScale()(NormalizeRotation()(SamplePoints(num=sample_points, remove_faces=True, include_normals=True)(x))))
    
    test_sampler = DistributedWeightedSampler(test_data,data_source=None, num_replicas=world_size) #weight unbalanced classes by 1/cls_count
    test_dataloader = DataLoader(dataset=test_data, batch_size=batch_size, shuffle=data_shuffle, num_workers=0,
                                      pin_memory=True, sampler=test_sampler)
    
    """# save sampled data for later result visualisation
    try:
        #export_path = os.path.join("stackgraphConvPool3DPnet", "train" + str(next_training_number("stackgraphConvPool3DPnet")-1))
        #export_sampled_data(training_dataloader, os.path.join(export_path, "train_sampledPoints.pth"))
        #export_sampled_data(test_dataloader, os.path.join(export_path, "test_sampledPoints.pth"))
        print("\nINFO: Sampled 3D data successfully saved . . .")
    except Exception as e:
        print(f"\nERROR: Sampled 3D data could not saved successfully . . . - this process does not executed - caused by {e}")"""
    
    # weighted CE Loss over all Classes C
    class_sample_count = np.array([len(np.where(training_data.data.y == t)[0]) for t in np.unique(training_data.data.y)])
    weight = 1. / class_sample_count
    weight = torch.from_numpy(weight)
    weight = weight.float()
    loss_fn = nn.CrossEntropyLoss(weight=weight).cuda(gpu)
    
    # continue training from certain checkpoint
    continue_from_scratch = True if args.resume is None else False
    if continue_from_scratch: 
        if gpu == 0:
            print("\nINFO: Train from scratch has started . . .")
        train_optimisation(gpu, gpus, training_dataloader, test_dataloader, model, loss_fn, optimizer, None, dir_path, 0)
    else:
        checkpoint_path = "stackgraphConvPool3DPnet/" + args.resume
        if gpu == 0:
            print(f"\nINFO: Train has started from certain checkpoint {checkpoint_path.split('/')[2].split('.')[0]} in {checkpoint_path.split('/')[1]} . . .")
        model.load_state_dict(torch.load(checkpoint_path)['model_state_dict'], strict=False)
        optimizer.load_state_dict(torch.load(checkpoint_path)['optimizer_state_dict'])
        final_epoch = (torch.load("stackgraphConvPool3DPnet/" + args.resume)['epoch'])+1
        train_optimisation(gpu, gpus, training_dataloader, test_dataloader, model, loss_fn, optimizer, None, dir_path, final_epoch)
INFO: Train from scratch has started . . .


Epoch 1
-------------------------------
Exception in thread Exception in thread Thread-8:
Traceback (most recent call last):
  File "C:\ProgramData\Anaconda3\lib\threading.py", line 973, in _bootstrap_inner
Thread-7:
Traceback (most recent call last):
  File "C:\ProgramData\Anaconda3\lib\threading.py", line 973, in _bootstrap_inner
    self.run()
  File "C:\ProgramData\Anaconda3\lib\threading.py", line 910, in run
    self.run()
  File "C:\ProgramData\Anaconda3\lib\threading.py", line 910, in run
    self._target(*self._args, **self._kwargs)
  File ~\Desktop\Forum\unit.py", line 615, in kmeansAppender
    self._target(*self._args, **self._kwargs)
  File ~\Desktop\Forum\unit.py", line 615, in kmeansAppender
    x, y, z = module(input)
  File "C:\ProgramData\Anaconda3\lib\site-packages\torch\nn\modules\module.py", line 1130, in _call_impl
    x, y, z = module(input)
  File "C:\ProgramData\Anaconda3\lib\site-packages\torch\nn\modules\module.py", line 1130, in _call_impl
    return forward_call(*input, **kwargs)
  File ~\Desktop\Forum\unit.py", line 148, in forward
    labels = np.apply_along_axis(lambda x: x + (i*self.k), axis=0, arr=kmeans.labels_)
AttributeError: 'KMeans' object has no attribute 'labels_'
    return forward_call(*input, **kwargs)
  File ~\Desktop\Forum\unit.py", line 148, in forward
    labels = np.apply_along_axis(lambda x: x + (i*self.k), axis=0, arr=kmeans.labels_)
AttributeError: 'KMeans' object has no attribute 'labels_'
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
Input In [1], in <cell line: 720>()
    734 #change state
    735 if args.train_state == True:
--> 736     train(args.local_rank, gpus, world_size)
    737 else:
    738     infer(args.local_rank, gpus, world_size, args.checkpoint, args.data)

Input In [1], in train(gpu, gpus, world_size)
    672     if gpu == 0:
    673         print("\nINFO: Train from scratch has started . . .")
--> 674     train_optimisation(gpu, gpus, training_dataloader, test_dataloader, model, loss_fn, optimizer, None, dir_path, 0)
    675 else:
    676     checkpoint_path = "stackgraphConvPool3DPnet/" + args.resume

Input In [1], in train_optimisation(gpu, gpus, training_dataloader, test_dataloader, model, loss_fn, optimizer, scheduler, dir_path, initial_epoch)
    454         print(f"\n\nEpoch {i + 1}\n-------------------------------")
    456 # TRAIN
--> 457 losses, training_accuracy, train_batch_result, train_conf_mat = training_loop(gpu, training_dataloader, model, loss_fn, optimizer)
    458 average_loss = torch.mean(losses)
    459 torch.distributed.reduce(average_loss, 0, torch.distributed.ReduceOp.SUM)

Input In [1], in training_loop(gpu, training_dataloader, model, loss_fn, optimizer)
    249 y = batch.y.cuda(non_blocking=True).flatten() #size (batch_size) --> torch.Size([8])
    251 # Compute predictions
--> 252 pred = model(None, X) #size (batch_size,classes) --> torch.Size([8, 10])
    254 if overall_classes_loss:
    255     # weighted CE Loss over all classes
    256     loss = loss_fn(pred, y)

File C:\ProgramData\Anaconda3\lib\site-packages\torch\nn\modules\module.py:1130, in Module._call_impl(self, *input, **kwargs)
   1126 # If we don't have any hooks, we want to skip the rest of the logic in
   1127 # this function, and just call forward.
   1128 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
   1129         or _global_forward_hooks or _global_forward_pre_hooks):
-> 1130     return forward_call(*input, **kwargs)
   1131 # Do not call functions when jit is used
   1132 full_backward_hooks, non_full_backward_hooks = [], []

File C:\ProgramData\Anaconda3\lib\site-packages\torch\nn\parallel\distributed.py:1008, in DistributedDataParallel.forward(self, *inputs, **kwargs)
   1004 if self._join_config.enable:
   1005     # Notify joined ranks whether they should sync in backwards pass or not.
   1006     self._check_global_requires_backward_grad_sync(is_joined_rank=False)
-> 1008 output = self._run_ddp_forward(*inputs, **kwargs)
   1010 # sync params according to location (before/after forward) user
   1011 # specified as part of hook, if hook was specified.
   1012 if self._check_sync_bufs_post_fwd():

File C:\ProgramData\Anaconda3\lib\site-packages\torch\nn\parallel\distributed.py:969, in DistributedDataParallel._run_ddp_forward(self, *inputs, **kwargs)
    962 if self.device_ids:
    963     inputs, kwargs = _to_kwargs(
    964         inputs,
    965         kwargs,
    966         self.device_ids[0],
    967         self.use_side_stream_for_tensor_copies
    968     )
--> 969     return module_to_run(*inputs[0], **kwargs[0])
    970 else:
    971     return module_to_run(*inputs, **kwargs)

File C:\ProgramData\Anaconda3\lib\site-packages\torch\nn\modules\module.py:1130, in Module._call_impl(self, *input, **kwargs)
   1126 # If we don't have any hooks, we want to skip the rest of the logic in
   1127 # this function, and just call forward.
   1128 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
   1129         or _global_forward_hooks or _global_forward_pre_hooks):
-> 1130     return forward_call(*input, **kwargs)
   1131 # Do not call functions when jit is used
   1132 full_backward_hooks, non_full_backward_hooks = [], []

File ~\Desktop\Forum\unit.py:657, in Classifier.forward(self, x, pos)
    655 feature_matrix_batch = pos.unsqueeze(0)
    656 # feature_matrix_batch size = (1,N,I,D) where N=batch number, I=members, D=member dimensionality
--> 657 output = self.neuralNet(feature_matrix_batch)
    658 # output size = (S,N,D) where S= stack size, N=batch number, D'=member dimensionality
    659 output = torch.mean(output, dim=0)

File C:\ProgramData\Anaconda3\lib\site-packages\torch\nn\modules\module.py:1130, in Module._call_impl(self, *input, **kwargs)
   1126 # If we don't have any hooks, we want to skip the rest of the logic in
   1127 # this function, and just call forward.
   1128 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
   1129         or _global_forward_hooks or _global_forward_pre_hooks):
-> 1130     return forward_call(*input, **kwargs)
   1131 # Do not call functions when jit is used
   1132 full_backward_hooks, non_full_backward_hooks = [], []

File C:\ProgramData\Anaconda3\lib\site-packages\torch\nn\modules\container.py:139, in Sequential.forward(self, input)
    137 def forward(self, input):
    138     for module in self:
--> 139         input = module(input)
    140     return input

File C:\ProgramData\Anaconda3\lib\site-packages\torch\nn\modules\module.py:1130, in Module._call_impl(self, *input, **kwargs)
   1126 # If we don't have any hooks, we want to skip the rest of the logic in
   1127 # this function, and just call forward.
   1128 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
   1129         or _global_forward_hooks or _global_forward_pre_hooks):
-> 1130     return forward_call(*input, **kwargs)
   1131 # Do not call functions when jit is used
   1132 full_backward_hooks, non_full_backward_hooks = [], []

File ~\Desktop\Forum\unit.py:448, in ShrinkingUnitStack.forward(self, feature_matrix_batch)
    446 feature_matrix_batch = self.selfCorrStack(feature_matrix_batch)
    447 # feature_matrix_batch size = (S',N,I,D) where S'=stack_size, N=batch number, I=members, D=member dimensionality
--> 448 feature_matrix_batch_, conv_feature_matrix_batch, cluster_index = self.kmeansConvStack(feature_matrix_batch)
    449 feature_matrix_batch = self.localAdaptFeaAggreStack(feature_matrix_batch, conv_feature_matrix_batch)
    450 output = self.graphMaxPoolStack(feature_matrix_batch, cluster_index)

File C:\ProgramData\Anaconda3\lib\site-packages\torch\nn\modules\module.py:1130, in Module._call_impl(self, *input, **kwargs)
   1126 # If we don't have any hooks, we want to skip the rest of the logic in
   1127 # this function, and just call forward.
   1128 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
   1129         or _global_forward_hooks or _global_forward_pre_hooks):
-> 1130     return forward_call(*input, **kwargs)
   1131 # Do not call functions when jit is used
   1132 full_backward_hooks, non_full_backward_hooks = [], []

File ~\Desktop\Forum\unit.py:519, in KMeansConvStack.forward(self, feature_matrix_batch)
    517 def forward(self, feature_matrix_batch: torch.Tensor):
    518     # feature_matrix_batch size = (S,N,I,D) where S=stack size, N=batch number, I=members, D=member dimensionality
--> 519     feature_matrix_batch, conv_feature_matrix_batch, cluster_index = kmeansConvThreader(self.kmeansConvStack,
    520                                                                                         feature_matrix_batch)
    521     # feature_matrix_batch size = (S,N,I,D) where where S=stack_size, N=batch number, I=members, D=member dimensionality
    522     # conv_feature_matrix_batch size = (S,N,I,D) where where S=stack_size, N=batch number, I=members, D=member dimensionality
    523     # cluster_index size = (S,M) where S=stack_size, M=N*I
    524     return feature_matrix_batch, conv_feature_matrix_batch, cluster_index

File ~\Desktop\Forum\unit.py:611, in kmeansConvThreader(modules, input_tensor)
    609 list2_append = list(map(lambda x: x[1], list2_append))
    610 list3_append = list(map(lambda x: x[1], list3_append))
--> 611 return torch.stack(list1_append), torch.stack(list2_append), torch.stack(list3_append)

RuntimeError: stack expects a non-empty TensorList

Thanks for your help

Is this a double post from here or what is the difference?

thank you very much yes the same code I reformatted the code correctly