internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: mlcommons/GaNDLF

Issue:
Allow different grid aggregation strategies
**Is your feature request related to a problem? Please describe.**
Currently, GaNDLF does not allow the parameterization of the [GridAggregator](https://torchio.readthedocs.io/patches/patch_inference.html#grid-aggregator) during inference. 

**Describe the solution you'd like**
Providing the options for `'crop'` or `'average'` would be good.

**Describe alternatives you've considered**
N.A.

**Additional context**
N.A.



Discussion:
[Join the discussion on DagsHub!](https://dagshub.com/CBICA/GaNDLF/issues/391)

Resolving patch:
diff --git a/GANDLF/compute/forward_pass.py b/GANDLF/compute/forward_pass.py
--- a/GANDLF/compute/forward_pass.py
+++ b/GANDLF/compute/forward_pass.py
@@ -204,11 +204,13 @@ def validate_network(
                 torchio.Subject(subject_dict), params["patch_size"]
             )
             patch_loader = torch.utils.data.DataLoader(grid_sampler, batch_size=1)
-            aggregator = torchio.inference.GridAggregator(grid_sampler)
+            aggregator = torchio.inference.GridAggregator(
+                grid_sampler, overlap_mode=params["grid_aggregator_overlap"]
+            )
 
             if params["medcam_enabled"]:
                 attention_map_aggregator = torchio.inference.GridAggregator(
-                    grid_sampler
+                    grid_sampler, overlap_mode=params["grid_aggregator_overlap"]
                 )
 
             output_prediction = 0  # this is used for regression/classification
diff --git a/GANDLF/parseConfig.py b/GANDLF/parseConfig.py
--- a/GANDLF/parseConfig.py
+++ b/GANDLF/parseConfig.py
@@ -27,6 +27,7 @@
     "track_memory_usage": False,  # default memory tracking
     "print_rgb_label_warning": True,  # default memory tracking
     "data_postprocessing": {},  # default data postprocessing
+    "grid_aggregator_overlap": "crop",  # default grid aggregator overlap strategy
 }
 
 ## dictionary to define string defaults for appropriate options


Test patch:
diff --git a/testing/config_classification.yaml b/testing/config_classification.yaml
--- a/testing/config_classification.yaml
+++ b/testing/config_classification.yaml
@@ -36,6 +36,7 @@ model:
 nested_training:
   testing: -5
   validation: -5
+grid_aggregator_overlap: crop
 num_epochs: 1
 optimizer: adam
 parallel_compute_command: ''
diff --git a/testing/config_regression.yaml b/testing/config_regression.yaml
--- a/testing/config_regression.yaml
+++ b/testing/config_regression.yaml
@@ -21,6 +21,7 @@ model:
 nested_training:
   testing: -5
   validation: -5
+grid_aggregator_overlap: crop
 num_epochs: 1
 optimizer: adam
 parallel_compute_command: ''
diff --git a/testing/config_segmentation.yaml b/testing/config_segmentation.yaml
--- a/testing/config_segmentation.yaml
+++ b/testing/config_segmentation.yaml
@@ -24,6 +24,7 @@ metrics:
   - recall: {
       average: macro,
     }
+grid_aggregator_overlap: crop
 # Patch size during training - 2D patch for breast images since third dimension is not patched 
 patch_size: [128,128]
 # Number of epochs
Repository: mlcommons/GaNDLF

Issue:
Per-label accuracy does not work for multiple batches
**Describe the bug**
When `batch_size > 1`, `per_label_accuracy` computation fails.

**To Reproduce**
Steps to reproduce the behavior:
1. Set `batch_size = 4` in any classification unit test
2. See error

**Expected behavior**
The function should compute multiple batches of accuracies.

**Screenshots**
N.A.

**GaNDLF Version**
<!-- Put the output of the following command:
python -c 'import GANDLF as g;print(g.__version__)'
-->
0.0.15-dev

**Desktop (please complete the following information):**
N.A.

**Additional context**
Reported by @brandon-edwards


Discussion:

Resolving patch:
diff --git a/GANDLF/metrics/regression.py b/GANDLF/metrics/regression.py
--- a/GANDLF/metrics/regression.py
+++ b/GANDLF/metrics/regression.py
@@ -62,10 +62,14 @@ def per_label_accuracy(output, label, params):
         torch.Tensor: The per class accuracy.
     """
     if params["problem_type"] == "classification":
-        predicted_classes = np.array([0] * len(params["model"]["class_list"]))
-        label_cpu = np.array([0] * len(params["model"]["class_list"]))
-        predicted_classes[torch.argmax(output, 1).cpu().item()] = 1
-        label_cpu[label.cpu().item()] = 1
-        return torch.from_numpy((predicted_classes == label_cpu).astype(float))
+        # ensure this works for multiple batches
+        output_accuracy = torch.zeros(len(params["model"]["class_list"]))
+        for output_batch, label_batch in zip(output, label):
+            predicted_classes = torch.Tensor([0] * len(params["model"]["class_list"]))
+            label_cpu = torch.Tensor([0] * len(params["model"]["class_list"]))
+            predicted_classes[torch.argmax(output_batch, 0).cpu().item()] = 1
+            label_cpu[label_batch.cpu().item()] = 1
+            output_accuracy += (predicted_classes == label_cpu).type(torch.float)
+        return output_accuracy / len(output)
     else:
         return balanced_acc_score(output, label, params)


Test patch:
Repository: mlcommons/GaNDLF

Issue:
Radiology DataLoader takes up a *lot* memory during certain conditions
**Describe the bug**
During sanity checking of subjects, the queue construction seems to take up a lot of memory.

**To Reproduce**
Steps to reproduce the behavior:
1. Have a ridiculous number of subjects on a small machine (e.g., 10k on a machine with 16G RAM)
2. Start training on rad mode
4. See error sometime during/after queue construction:
```bash
## last message
Constructing queue for train data: 100%|██████████| 8681/8681 [07:57<00:00, 18.19it/s]
## failure with message related to exceeded RAM usage
```

**Expected behavior**
There should not be any failure at this stage.

**Screenshots**
N.A>

**GaNDLF Version**
<!-- Put the output of the following command:
python -c 'import GANDLF as g;print(g.__version__)'
-->
0.0.16-dev

**Desktop (please complete the following information):**
CentOS 7

**Additional context**
N.A.


Discussion:
This issue is apparent on the CUBIC cluster, but I am unable to reproduce this either on my local native Windows or multiple WSLs (Ubuntu, Mint, OpenSUSE). 
This seems to be coming from the [sanity checking](https://github.com/mlcommons/GaNDLF/blob/fec207fd2c258d2d18d9c6eb11e21a8a122906ed/GANDLF/utils/imaging.py#L112), since commenting out [this line](https://github.com/mlcommons/GaNDLF/blob/fec207fd2c258d2d18d9c6eb11e21a8a122906ed/GANDLF/data/ImagesFromDataFrame.py#L182) seems to ensure that training starts.
Can reproduce using `SimpleITK==2.2.1` but not on `SimpleITK==2.1.1.2`. I am going to try with `SimpleITK==2.2.0` as a workaround, but might end up going with a hard requirement on `SimpleITK==2.1.1.2`.

Update: `2.2.1` seems to be problematic, since `2.2.0` worked as expected. 

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -53,6 +53,7 @@ def run(self):
     "numpy==1.22.0",
     "scipy",
     "SimpleITK!=2.0.*",
+    "SimpleITK!=2.2.1",  # https://github.com/mlcommons/GaNDLF/issues/536
     "torchvision",
     "tqdm",
     "torchio==0.18.75",


Test patch:
Repository: mlcommons/GaNDLF

Issue:
Save `initial` and `latest` models in addition to `best`
**Is your feature request related to a problem? Please describe.**
In a lot of cases, the `latest` model might be more informative WRT how the training loss has been behaving as compared to the `latest`. Also, the `initial` model can give greater insight into post-training data.

**Describe the solution you'd like**
In addition to the `best` model, save `initial` (i.e., the model right before any training has occurred) and `latest` models.

**Describe alternatives you've considered**
N.A.

**Additional context**
N.A.


Discussion:

Resolving patch:
diff --git a/GANDLF/compute/training_loop.py b/GANDLF/compute/training_loop.py
--- a/GANDLF/compute/training_loop.py
+++ b/GANDLF/compute/training_loop.py
@@ -496,19 +496,19 @@ def training_loop(
         # save the latest model
         if os.path.exists(model_paths["latest"]):
             os.remove(model_paths["latest"])
-            save_model(
-                {
-                    "epoch": 0,
-                    "model_state_dict": model_dict,
-                    "optimizer_state_dict": optimizer.state_dict(),
-                    "loss": best_loss,
-                },
-                model,
-                params,
-                model_paths["latest"],
-                onnx_export=False,
-            )
-            print("Latest model saved.")
+        save_model(
+            {
+                "epoch": 0,
+                "model_state_dict": model_dict,
+                "optimizer_state_dict": optimizer.state_dict(),
+                "loss": best_loss,
+            },
+            model,
+            params,
+            model_paths["latest"],
+            onnx_export=False,
+        )
+        print("Latest model saved.")
         print("Current Best epoch: ", best_train_idx)
 
         if patience > params["patience"]:


Test patch:
Repository: mlcommons/GaNDLF

Issue:
PyTorch security vulnerability
See https://github.com/advisories/GHSA-47fc-vmwq-366v

Need to upgrade to PyTorch 1.13.1


Discussion:
The trouble here is going to be our Docker builds, where we are specifying a torch version (example [here](https://github.com/mlcommons/GaNDLF/blob/master/Dockerfile-CUDA11.3#L12)). Currently, the [installation instructions for `pytorch==1.13.1` are](https://pytorch.org/get-started/locally/):
```bash
pip3 install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu116
```
Which will change the version getting installed when a new one is released by PyTorch in the future. So we have the following options:

1. Shall we ensure the security vulnerability in question is fixed in a timely manner, which ensures that we will need a patch fix in the future to ensure our Docker builds remain okay?
2. Shall we keep this issue in our radar until the next version of PyTorch is released, which will ensure a fixed link for installation, which will require less maintenance in the future? 

Pinging @AlexanderGetka-cbica @hasan7n @aristizabal95 for clarification.

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -42,6 +42,7 @@ def run(self):
     sys.stderr.write("Warning: Could not open '%s' due %s\n" % (filepath, error))
 
 requirements = [
+    "torch==1.13.1",
     "black",
     "numpy==1.22.0",
     "scipy",
@@ -80,12 +81,6 @@ def run(self):
     "keyring",
 ]
 
-# pytorch doesn't have LTS support on OSX - https://github.com/mlcommons/GaNDLF/issues/389
-if sys.platform == "darwin":
-    requirements.append("torch==1.11.0")
-else:
-    requirements.append("torch==1.11.0")
-
 if __name__ == "__main__":
     setup(
         name="GANDLF",


Test patch:
Repository: mlcommons/GaNDLF

Issue:
Some required modules are missing from pip
**Describe the bug**
The current pip package is missing some required files.

**To Reproduce**
Steps to reproduce the behavior:
1. Install GaNDLF from pip (currently, it is via `pip install GANDLF --pre`)
2. Try to run `python .\venv_temp\Scripts\gandlf_run -h` (or the analogous from Linux)
3. See error:
```powershell
Traceback (most recent call last):
  File ".\venv_temp\Scripts\gandlf_run", line 11, in <module>
    from GANDLF.cli import main_run, copyrightMessage
  File "C:\venv_temp\lib\site-packages\GANDLF\cli\__init__.py", line 1, in <module>
    from .patch_extraction import patch_extraction
  File "C:\venv_temp\lib\site-packages\GANDLF\cli\patch_extraction.py", line 7, in <module>
    from GANDLF.data.patch_miner.opm.patch_manager import PatchManager
ModuleNotFoundError: No module named 'GANDLF.data.patch_miner.opm'
(C:\venv_temp) PS C:> ls .\venv_temp\Lib\site-packages\GANDLF\data\
```

**Expected behavior**
The usage message should come up.

**Screenshots**
N.A.

**GaNDLF Version**
<!-- Put the output of the following command:
python -c 'import GANDLF as g;print(g.__version__)'
-->
0.0.16.dev20230329

**Desktop (please complete the following information):**
 - OS: Windows
 - Version: N.A.

**Additional context**
N.A.


Discussion:

Resolving patch:
diff --git a/GANDLF/data/patch_miner/opm/__init__.py b/GANDLF/data/patch_miner/opm/__init__.py
new file mode 100644


Test patch:
Repository: mlcommons/GaNDLF

Issue:
CCA failure when enabled
**Describe the bug**
The CCA (Largest Connected Component Analysis) function was implemented as a standalone function, which causes it to fail when called in the segmentation pipeline with post-processing enabled. The expected behavior is a likely failure due to this issue.

**To Reproduce**
Run a segmentation pipeline with CCA enabled for the post-processing.

**Expected behavior**
The CCA function should be corrected and integrated with the segmentation pipeline to work correctly and tested

**GaNDLF Version**
<!-- Put the output of the following command:
python -c 'import GANDLF as g;print(g.__version__)'
-->
Version information of the GaNDLF package in the virtual environment. 0.0.16-dev

**Desktop (please complete the following information):**
 - OS: Linux, Ubuntu
 - Version (including Build information, if any): 22.04

**Additional context**
None



Discussion:

Resolving patch:
diff --git a/GANDLF/data/post_process/morphology.py b/GANDLF/data/post_process/morphology.py
--- a/GANDLF/data/post_process/morphology.py
+++ b/GANDLF/data/post_process/morphology.py
@@ -71,7 +71,7 @@ def fill_holes(input_image, params=None):
     return torch.from_numpy(output_array)
 
 
-def cca(input_image):
+def cca(input_image, params=None):
     """
     This function performs connected component analysis on the input image.
 
@@ -85,11 +85,15 @@ def cca(input_image):
     seg = get_array_from_image_or_tensor(input_image)
     mask = seg != 0
 
-    connectivity = input_image.dim() - 1
+    connectivity = input_image.ndim - 1
     labels_connected = label(mask, connectivity=connectivity)
     labels_connected_sizes = [
         np.sum(labels_connected == i) for i in np.unique(labels_connected)
     ]
-    largest_region = np.argmax(labels_connected_sizes[1:]) + 1
+    largest_region = 0
+    if len(labels_connected_sizes) > 1:
+        largest_region = np.argmax(labels_connected_sizes[1:]) + 1
     seg[labels_connected != largest_region] = 0
+
     return seg
+


Test patch:
diff --git a/testing/test_full.py b/testing/test_full.py
--- a/testing/test_full.py
+++ b/testing/test_full.py
@@ -1530,6 +1530,7 @@ def test_dataloader_construction_train_segmentation_3d(device):
     parameters["model"]["print_summary"] = False
     parameters["data_postprocessing"]["mapping"] = {0: 0, 1: 1}
     parameters["data_postprocessing"]["fill_holes"] = True
+    parameters["data_postprocessing"]["cca"] = True
     parameters = populate_header_in_parameters(parameters, parameters["headers"])
     # loop through selected models and train for single epoch
     sanitize_outputDir()
Repository: mlcommons/GaNDLF

Issue:
Port to Pandas 2.0
**Describe the bug**
when running `gandlf_run`, I am encountering:

`ERROR: 'DataFrame' object has no attribute 'append'`

**To Reproduce**

Train a model using `gandlf_run`.

I trained using `2d_rad_segmentation` data from `https://upenn.box.com/shared/static/y8162xkq1zz5555ye3pwadry2m2e39bs.zip` and the config file from samples in the repo `config_classification.yaml`

**Additional context**
- check the changelog of pandas [here](https://pandas.pydata.org/pandas-docs/stable/whatsnew/v2.0.0.html#removal-of-prior-version-deprecations-changes:~:text=Removed%20deprecated%20Series.append()%2C%20DataFrame.append()%2C%20use%20concat()%20instead%20(GH35407))
- The training runs successfully when downgrading `pandas` to `1.5.3`





Discussion:

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -51,7 +51,7 @@ def run(self):
     "torchvision",
     "tqdm",
     "torchio==0.18.75",
-    "pandas",
+    "pandas<2.0.0",
     "scikit-learn>=0.23.2",
     "scikit-image>=0.19.1",
     "setuptools",


Test patch:
Repository: mlcommons/GaNDLF

Issue:
Per label and global metrics return 0
**Describe the bug**
During training most metrics return 0 instead of actual value.

**To Reproduce**
Steps to reproduce the behavior:
1. Use this metrics setting in config.yaml: 
```
metrics:
- classification_accuracy
- f1:
    average: weighted
- accuracy
- balanced_accuracy
- per_label_accuracy
```
3. Run training of imagenet_vgg16 (binary classification task)
4. Check job output
5. See error

**Expected behavior**
Metrics should return actual values instead of 0.

**Screenshots**
![image](https://user-images.githubusercontent.com/22845598/234021488-85907e09-ee00-4bd1-9100-2eced9692da7.png)

**GaNDLF Version**
0.0.16-dev
Version information of the GaNDLF package in the virtual environment.

**Desktop (please complete the following information):**
 - OS: Linux



Discussion:
@sarthakpati please assign it to me

Resolving patch:
diff --git a/GANDLF/compute/training_loop.py b/GANDLF/compute/training_loop.py
--- a/GANDLF/compute/training_loop.py
+++ b/GANDLF/compute/training_loop.py
@@ -306,22 +306,25 @@ def training_loop(
         )
         # original number of classes are restored
         params["model"]["num_classes"] = org_num_classes
+
+    metrics_log = params["metrics"].copy()
+
     if calculate_overall_metrics:
         for metric in overall_metrics:
-            params["metrics"][metric] = 0
+            metrics_log[metric] = 0
 
     # Setup a few loggers for tracking
     train_logger = Logger(
         logger_csv_filename=os.path.join(output_dir, "logs_training.csv"),
-        metrics=params["metrics"],
+        metrics=metrics_log,
     )
     valid_logger = Logger(
         logger_csv_filename=os.path.join(output_dir, "logs_validation.csv"),
-        metrics=params["metrics"],
+        metrics=metrics_log,
     )
     test_logger = Logger(
         logger_csv_filename=os.path.join(output_dir, "logs_testing.csv"),
-        metrics=params["metrics"],
+        metrics=metrics_log,
     )
     train_logger.write_header(mode="train")
     valid_logger.write_header(mode="valid")


Test patch:
Repository: mlcommons/GaNDLF

Issue:
Perform penalty calculation after all sanity checks are completed
**Is your feature request related to a problem? Please describe.**
The penalty calculation takes a long time, and there are sanity checks that happen after this, which can be a pain.

**Describe the solution you'd like**
It would be great to have these checks before the penalty calculation for quality-of-life improvements.

**Describe alternatives you've considered**
N.A.

**Additional context**
From Evan C.


Discussion:

Resolving patch:
diff --git a/GANDLF/compute/generic.py b/GANDLF/compute/generic.py
--- a/GANDLF/compute/generic.py
+++ b/GANDLF/compute/generic.py
@@ -47,12 +47,6 @@ def create_pytorch_objects(parameters, train_csv=None, val_csv=None, device="cpu
         train_loader = get_train_loader(parameters)
         parameters["training_samples_size"] = len(train_loader)
 
-        # Calculate the weights here
-        (
-            parameters["weights"],
-            parameters["class_weights"],
-        ) = get_class_imbalance_weights(parameters["training_data"], parameters)
-
     if val_csv is not None:
         parameters["validation_data"], headers_to_populate_val = parseTrainingCSV(
             val_csv, train=False
@@ -90,6 +84,13 @@ def create_pytorch_objects(parameters, train_csv=None, val_csv=None, device="cpu
             )
 
         scheduler = get_scheduler(parameters)
+
+        # Calculate the weights here
+        (
+            parameters["weights"],
+            parameters["class_weights"],
+        ) = get_class_imbalance_weights(parameters["training_data"], parameters)
+
     else:
         scheduler = None
 


Test patch:
Repository: mlcommons/GaNDLF

Issue:
Move unit testing data to the MLCommons Storage
**Is your feature request related to a problem? Please describe.**
Currently, the unit testing data is on UPenn Box - which is inconvenient for someone without access who wants to make any updates. 

**Describe the solution you'd like**
Changing this to the MLCommons storage would make things much easier from an admin perspective.

**Describe alternatives you've considered**
N.A.

**Additional context**
N.A.



Discussion:

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -92,7 +92,7 @@ def run(self):
     "pyyaml",
     "tiffslide",
     "matplotlib",
-    "requests>=2.25.0",
+    "gdown",
     "pytest",
     "coverage",
     "pytest-cov",


Test patch:
diff --git a/testing/test_full.py b/testing/test_full.py
--- a/testing/test_full.py
+++ b/testing/test_full.py
@@ -1,5 +1,5 @@
 from pathlib import Path
-import requests, zipfile, io, os, csv, random, copy, shutil, yaml, torch, pytest
+import gdown, zipfile, os, csv, random, copy, shutil, yaml, torch, pytest
 import SimpleITK as sitk
 import numpy as np
 import pandas as pd
@@ -109,9 +109,7 @@
 
 def test_generic_download_data():
     print("00: Downloading the sample data")
-    urlToDownload = (
-        "https://upenn.box.com/shared/static/y8162xkq1zz5555ye3pwadry2m2e39bs.zip"
-    )
+    urlToDownload = "https://drive.google.com/uc?id=1c4Yrv-jnK6Tk7Ne1HmMTChv-4nYk43NT"
 
     files_check = [
         os.path.join(inputDir, "2d_histo_segmentation", "1", "image.tiff"),
@@ -122,9 +120,11 @@ def test_generic_download_data():
     for file in files_check:
         if not os.path.isfile(file):
             print("Downloading and extracting sample data")
-            r = requests.get(urlToDownload)
-            z = zipfile.ZipFile(io.BytesIO(r.content))
-            z.extractall(testingDir)
+            output = os.path.join(testingDir, "gandlf_unit_test_data.tgz")
+            gdown.download(urlToDownload, output, quiet=False)
+            with zipfile.ZipFile(output, "r") as zip_ref:
+                zip_ref.extractall(testingDir)
+            os.remove(output)
             break
 
     sanitize_outputDir()