internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: microsoft/hi-ml

Issue:
Handle the "v" in version numbering 
Our code in `setup.py` will trigger with new tags. `setuptools.setup` will reject tags that are not release versions but we could do more to make that explicit by checking for the leading "v".

Also when we tag releases as, say, "v0.1.1" the leading "v" is carried through `setuptools.setup` so it becomes part of the pip test download

> Successfully installed pip-21.2.4
> Collecting hi-ml==v0.1.0
>   Downloading hi_ml-0.1.0-py3-none-any.whl (25 kB)

(from [here](https://github.com/microsoft/hi-ml/runs/3362573497?check_suite_focus=true#step:6:29))

This works, but it would be cleaner to submit the version number using the public version identifier format mandated in [PEP 440](https://www.python.org/dev/peps/pep-0440/#public-version-identifiers), i.e. without the leading "v"


Discussion:

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -31,7 +31,7 @@
 # See also:
 # https://packaging.python.org/guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows/
 # https://github.com/pypa/gh-action-pypi-publish
-GITHUB_REF_TAG_COMMIT = 'refs/tags/'
+GITHUB_REF_TAG_COMMIT = 'refs/tags/v'
 
 github_ref = os.getenv('GITHUB_REF')
 if github_ref and github_ref.startswith(GITHUB_REF_TAG_COMMIT):


Test patch:
Repository: microsoft/hi-ml

Issue:
Why do we need a `compute_cluster_name` for purely local runs?
`submit_to_azure_if_needed` has just one parameter which has no default, `compute_cluster_name`. But some consumers of our package (e.g. InnerEye) may have the option to train a model locally. In that situation we intend them to still call `submit_to_azure_if_needed` (that's why it is called _if_needed_) but for a purely local run why should they have a  `compute_cluster_name`? It should also have a default, `""`.


Discussion:

Resolving patch:
diff --git a/src/health/azure/himl.py b/src/health/azure/himl.py
--- a/src/health/azure/himl.py
+++ b/src/health/azure/himl.py
@@ -250,7 +250,7 @@ def _str_to_path(s: Optional[PathOrString]) -> Optional[Path]:
 
 def submit_to_azure_if_needed(  # type: ignore
         # ignore missing return statement since we 'exit' instead when submitting to AzureML
-        compute_cluster_name: str,
+        compute_cluster_name: str = "",
         entry_script: Optional[PathOrString] = None,
         aml_workspace: Optional[Workspace] = None,
         workspace_config_path: Optional[PathOrString] = None,
@@ -366,6 +366,7 @@ def submit_to_azure_if_needed(  # type: ignore
             output_folder=Path.cwd() / OUTPUT_FOLDER,
             logs_folder=Path.cwd() / LOGS_FOLDER
         )
+
     if snapshot_root_directory is None:
         logging.info(f"No snapshot root directory given. Uploading all files in the current directory {Path.cwd()}")
         snapshot_root_directory = Path.cwd()


Test patch:
Repository: microsoft/hi-ml

Issue:
Default padding color is black when loading slides
When a WSI is loaded, the corresponding mask is used to load only the region of interest. If a `margin` > 0 is passed to `LoadPandaROId`, the slides are padded by MONAI's `WSIReader` using black as default color.

https://github.com/microsoft/hi-ml/blob/8722c8b574286f0a6eb182990742b2850512c762/hi-ml-histopathology/src/histopathology/datasets/panda_dataset.py#L110-L123

The background in WSIs is normally almost white, so padding with black might mess up the preprocessing.


Discussion:
Example of a tile (from PANDA) from a padded region:

![00856x_14992y](https://user-images.githubusercontent.com/12688084/164431888-70322fc4-cc6a-41c5-ac22-77e2ddc19098.png)


A quick fix for this should be setting margin to 0.
The default margin was accidentally set to 64 in #321, not 0.

Resolving patch:
diff --git a/hi-ml-histopathology/src/histopathology/datasets/default_paths.py b/hi-ml-histopathology/src/histopathology/datasets/default_paths.py
--- a/hi-ml-histopathology/src/histopathology/datasets/default_paths.py
+++ b/hi-ml-histopathology/src/histopathology/datasets/default_paths.py
@@ -4,7 +4,7 @@
 #  ------------------------------------------------------------------------------------------
 
 PANDA_DATASET_ID = "PANDA"
-PANDA_TILES_DATASET_ID = "PANDA_tiles_20220427"
+PANDA_TILES_DATASET_ID = "PANDA_tiles_20220530"
 TCGA_CRCK_DATASET_ID = "TCGA-CRCk"
 TCGA_PRAD_DATASET_ID = "TCGA-PRAD"
 
diff --git a/hi-ml-histopathology/src/histopathology/preprocessing/create_panda_tiles_dataset.py b/hi-ml-histopathology/src/histopathology/preprocessing/create_panda_tiles_dataset.py
--- a/hi-ml-histopathology/src/histopathology/preprocessing/create_panda_tiles_dataset.py
+++ b/hi-ml-histopathology/src/histopathology/preprocessing/create_panda_tiles_dataset.py
@@ -288,7 +288,7 @@ def main(panda_dir: Union[str, Path], root_output_dir: Union[str, Path], level:
     parser.add_argument(
         "--margin",
         type=int,
-        default=64,
+        default=0,
     )
     parser.add_argument(
         "--min-occupancy",


Test patch:
Repository: microsoft/hi-ml

Issue:
Clean up console logging for runner
Starting the runner prints out "sys.path at container level" twice.


Discussion:

Resolving patch:
diff --git a/hi-ml-histopathology/src/histopathology/configs/SSL/CRCK_SimCLRContainer.py b/hi-ml-histopathology/src/histopathology/configs/SSL/CRCK_SimCLRContainer.py
--- a/hi-ml-histopathology/src/histopathology/configs/SSL/CRCK_SimCLRContainer.py
+++ b/hi-ml-histopathology/src/histopathology/configs/SSL/CRCK_SimCLRContainer.py
@@ -3,19 +3,13 @@
 #  Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
 #  ------------------------------------------------------------------------------------------
 from enum import Enum
-from pathlib import Path
 from typing import Any
-import sys
 
 from SSL.lightning_containers.ssl_container import EncoderName, SSLContainer, SSLDatasetName
 from SSL.utils import SSLTrainingType
 from histopathology.datasets.tcga_crck_tiles_dataset import TcgaCrck_TilesDatasetWithReturnIndex
 from histopathology.configs.SSL.HistoSimCLRContainer import HistoSSLContainer
 
-current_file = Path(__file__)
-print(f"Running container from {current_file}")
-print(f"Sys path container level {sys.path}")
-
 
 class SSLDatasetNameHiml(SSLDatasetName, Enum):  # type: ignore
     TCGA_CRCK = "CRCKTilesDataset"
diff --git a/hi-ml-histopathology/src/histopathology/configs/SSL/PANDA_SimCLRContainer.py b/hi-ml-histopathology/src/histopathology/configs/SSL/PANDA_SimCLRContainer.py
--- a/hi-ml-histopathology/src/histopathology/configs/SSL/PANDA_SimCLRContainer.py
+++ b/hi-ml-histopathology/src/histopathology/configs/SSL/PANDA_SimCLRContainer.py
@@ -3,9 +3,7 @@
 #  Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
 #  ------------------------------------------------------------------------------------------
 from enum import Enum
-from pathlib import Path
 from typing import Any
-import sys
 
 from SSL.lightning_containers.ssl_container import EncoderName, SSLContainer, SSLDatasetName
 from SSL.utils import SSLTrainingType
@@ -15,11 +13,6 @@
 from histopathology.datasets.default_paths import PANDA_TILES_DATASET_ID
 
 
-current_file = Path(__file__)
-print(f"Running container from {current_file}")
-print(f"Sys path container level {sys.path}")
-
-
 class SSLDatasetNameHiml(SSLDatasetName, Enum):  # type: ignore
     PANDA = "PandaTilesDataset"
 


Test patch:
Repository: microsoft/hi-ml

Issue:
Histo dataset mounting script does not show files permanently
Files are only visible while the script is running, but disappear once terminated. 
This could be a consequence of the library updates in #455.


Discussion:

Resolving patch:
diff --git a/hi-ml-histopathology/src/histopathology/scripts/mount_azure_dataset.py b/hi-ml-histopathology/src/histopathology/scripts/mount_azure_dataset.py
--- a/hi-ml-histopathology/src/histopathology/scripts/mount_azure_dataset.py
+++ b/hi-ml-histopathology/src/histopathology/scripts/mount_azure_dataset.py
@@ -4,6 +4,8 @@
 #  ------------------------------------------------------------------------------------------
 from pathlib import Path
 import sys
+import time
+from typing import Any
 
 himl_histo_root_dir = Path(__file__).parent.parent.parent
 himl_root = himl_histo_root_dir.parent.parent
@@ -14,14 +16,14 @@
 from health_azure.utils import get_workspace  # noqa: E402
 
 
-def mount_dataset(dataset_id: str) -> str:
+def mount_dataset(dataset_id: str) -> Any:
     ws = get_workspace()
     target_folder = "/tmp/datasets/" + dataset_id
     dataset = DatasetConfig(name=dataset_id, target_folder=target_folder, use_mounting=True)
-    dataset_mount_folder, mount_ctx = dataset.to_input_dataset_local(ws)
+    _, mount_ctx = dataset.to_input_dataset_local(ws)
     assert mount_ctx is not None  # for mypy
     mount_ctx.start()
-    return str(dataset_mount_folder)
+    return mount_ctx
 
 
 if __name__ == '__main__':
@@ -31,4 +33,9 @@ def mount_dataset(dataset_id: str) -> str:
     parser.add_argument('--dataset_id', type=str,
                         help='Name of the Azure dataset e.g. PANDA or TCGA-CRCk')
     args = parser.parse_args()
-    mount_dataset(args.dataset_id)
+    # It is essential that the mount context is returned from the mounting function and referenced here.
+    # If not, mounting will be stopped, and the files are no longer available.
+    _ = mount_dataset(args.dataset_id)
+    print("The mounted dataset will only be available while this script is running. Press Ctrl-C to terminate it.`")
+    while True:
+        time.sleep(60)


Test patch:
Repository: microsoft/hi-ml

Issue:
submit_to_azure is removing arguments called "conda_env" when using SDK v2
If there is a script parameter that contains the string "conda_env" it gets removed, including prefixes. This causes problems when the argument list is `--arg1 bar --conda_env foo`, which is then turned into `--arg1 bar foo`, which will not parse.


Discussion:

Resolving patch:
diff --git a/hi-ml-azure/src/health_azure/himl.py b/hi-ml-azure/src/health_azure/himl.py
--- a/hi-ml-azure/src/health_azure/himl.py
+++ b/hi-ml-azure/src/health_azure/himl.py
@@ -522,9 +522,7 @@ def submit_run_v2(workspace: Optional[Workspace],
     entry_script = Path(entry_script).relative_to(root_dir).as_posix()
 
     script_params = script_params or []
-    args = [p for p in script_params if "conda_env" not in p]
-    arg_str = " ".join(args)
-    cmd = "python " + str(entry_script) + " " + arg_str
+    cmd = " ".join(["python", str(entry_script), *script_params])
 
     if input_datasets_v2:
         cmd += _generate_input_dataset_command(input_datasets_v2)
diff --git a/hi-ml/src/health_ml/runner.py b/hi-ml/src/health_ml/runner.py
--- a/hi-ml/src/health_ml/runner.py
+++ b/hi-ml/src/health_ml/runner.py
@@ -9,7 +9,7 @@
 import param
 import sys
 from pathlib import Path
-from typing import Dict, List, Optional, Tuple
+from typing import Any, Dict, List, Optional, Tuple
 
 from azureml.core import Workspace, Run
 
@@ -186,9 +186,10 @@ def submit_to_azureml_if_needed(self) -> AzureRunInfo:
             about datasets etc
         """
 
-        def after_submission_hook(azure_run: Run) -> None:
+        def after_submission_hook(azure_run: Run, *args: Any) -> None:
             """
-            A function that will be called right after job submission.
+            A function that will be called right after job submission. The function has a second unused argument
+            to support both the required signatures for AzureML SDK v1 and v2.
             """
             # Set the default display name to what was provided as the "tag". This will affect single runs
             # and Hyperdrive parent runs


Test patch:
diff --git a/hi-ml-azure/testazure/testazure/test_himl.py b/hi-ml-azure/testazure/testazure/test_himl.py
--- a/hi-ml-azure/testazure/testazure/test_himl.py
+++ b/hi-ml-azure/testazure/testazure/test_himl.py
@@ -779,7 +779,7 @@ def _mock_sweep(*args: Any, **kwargs: Any) -> MagicMock:
                 hyperparam_args=None
             )
 
-            expected_arg_str = " ".join([p for p in dummy_script_params if "conda_env" not in p])
+            expected_arg_str = " ".join(dummy_script_params)
             expected_inputs_str = "--INPUT_0=${{inputs.INPUT_0}}"
             expected_outputs_str = "--OUTPUT_0=${{outputs.OUTPUT_0}}"
             relative_entry_script = dummy_entry_script.relative_to(dummy_root_directory)
Repository: microsoft/hi-ml

Issue:
Workspace config path argument in runner is not used consistently
When providing the `workspace_config_path` argument to the runner, some of the methods still try to use the default location for `config.json`

log:
```
Found the config file in: /home/antonsc/cpath/cyted_config.json
Logged into AzureML workspace Cyted as specified in config file /home/antonsc/cpath/cyted_config.json
No environment configuration found.
ManagedIdentityCredential will use IMDS
DefaultAzureCredential acquired a token from AzureCliCredential
Trying to locate the workspace config file 'config.json' in the current folder and its parent folders
Using the workspace config file /home/antonsc/cpath/config.json
Using interactive login to Azure. To use Service Principal authentication, set the environment variables HIML_SERVICE_PRINCIPAL_ID, HIML_SERVICE_PRINCIPAL_PASSWORD, and HIML_TENANT_ID
Found the config file in: /home/antonsc/cpath/config.json
Logged into AzureML workspace hai4 as specified in config file /home/antonsc/cpath/config.json
Logged into AzureML workspace hai4
Using this Conda environment definition: hi-ml/hi-ml-cpath/environment.yml
```


Discussion:

Resolving patch:
diff --git a/hi-ml/src/health_ml/runner.py b/hi-ml/src/health_ml/runner.py
--- a/hi-ml/src/health_ml/runner.py
+++ b/hi-ml/src/health_ml/runner.py
@@ -238,7 +238,7 @@ def after_submission_hook(azure_run: Run, *args: Any) -> None:
             else:
                 hyperparam_args = self.lightning_container.get_hyperparam_args()
                 hyperdrive_config = None
-            ml_client = get_ml_client() if not self.experiment_config.strictly_aml_v1 else None
+            ml_client = get_ml_client(aml_workspace=workspace) if not self.experiment_config.strictly_aml_v1 else None
 
             env_file = choose_conda_env_file(env_file=self.experiment_config.conda_env)
             logging.info(f"Using this Conda environment definition: {env_file}")


Test patch:
Repository: microsoft/hi-ml

Issue:
BaseMIL output files no longer contain the "bottom" column
In the datafiles that are output for test set predictions, we seem to have lost the "bottom" column. "left", "right", "top" are still present. Hence, we can't create attention heatmap plots.


Discussion:
On it!

Resolving patch:
diff --git a/hi-ml-cpath/src/health_cpath/models/deepmil.py b/hi-ml-cpath/src/health_cpath/models/deepmil.py
--- a/hi-ml-cpath/src/health_cpath/models/deepmil.py
+++ b/hi-ml-cpath/src/health_cpath/models/deepmil.py
@@ -299,7 +299,7 @@ def update_results_with_metadata(self, batch: Dict, results: Dict) -> None:
         results.update({ResultsKey.SLIDE_ID: batch[SlideKey.SLIDE_ID],
                         ResultsKey.TILE_ID: batch[TileKey.TILE_ID]})
         # Add tiles coordinates if available
-        coordinates_keys = [TileKey.TILE_TOP, TileKey.TILE_LEFT, TileKey.TILE_RIGHT, TileKey.TILE_LEFT]
+        coordinates_keys = [TileKey.TILE_TOP, TileKey.TILE_BOTTOM, TileKey.TILE_RIGHT, TileKey.TILE_LEFT]
         if all([key in batch for key in coordinates_keys]):
             for key in coordinates_keys:
                 results[key] = batch[key]


Test patch:
Repository: microsoft/hi-ml

Issue:
Links to BioViL paper need to be updated
We are still using the arXiv preprint. But this should be solved first:
- https://github.com/microsoft/hi-ml/pull/730#issuecomment-1419298653


Discussion:

Resolving patch:
diff --git a/hi-ml-multimodal/src/health_multimodal/text/model/modelling_cxrbert.py b/hi-ml-multimodal/src/health_multimodal/text/model/modelling_cxrbert.py
--- a/hi-ml-multimodal/src/health_multimodal/text/model/modelling_cxrbert.py
+++ b/hi-ml-multimodal/src/health_multimodal/text/model/modelling_cxrbert.py
@@ -53,7 +53,7 @@ class CXRBertModel(BertForMaskedLM):
     """
     Implements the CXR-BERT model outlined in the manuscript:
     Boecking et al. "Making the Most of Text Semantics to Improve Biomedical Vision-Language Processing", 2022
-    https://arxiv.org/abs/2204.09817
+    https://link.springer.com/chapter/10.1007/978-3-031-20059-5_1
 
     Extends the HuggingFace BertForMaskedLM model by adding a separate projection head. The projection "[CLS]" token is
     used to align the latent vectors of image and text modalities.


Test patch:
Repository: microsoft/hi-ml

Issue:
Expose overwrite option for output datasets in SDK v1



Discussion:
https://learn.microsoft.com/en-us/python/api/azureml-core/azureml.data.outputfiledatasetconfig?view=azure-ml-py#azureml-data-outputfiledatasetconfig-as-upload

Resolving patch:
diff --git a/hi-ml-azure/src/health_azure/datasets.py b/hi-ml-azure/src/health_azure/datasets.py
--- a/hi-ml-azure/src/health_azure/datasets.py
+++ b/hi-ml-azure/src/health_azure/datasets.py
@@ -301,6 +301,7 @@ def __init__(
         self,
         name: str,
         datastore: str = "",
+        overwrite_existing: bool = True,
         version: Optional[int] = None,
         use_mounting: Optional[bool] = None,
         target_folder: Optional[PathOrString] = None,
@@ -311,6 +312,8 @@ def __init__(
             this will be the name given to the newly created dataset.
         :param datastore: The name of the AzureML datastore that holds the dataset. This can be empty if the AzureML
             workspace has only a single datastore, or if the default datastore should be used.
+        :param overwrite_existing: Only applies to uploading datasets. If True, the dataset will be overwritten if it
+            already exists. If False, the dataset creation will fail if the dataset already exists.
         :param version: The version of the dataset that should be used. This is only used for input datasets.
             If the version is not specified, the latest version will be used.
         :param use_mounting: If True, the dataset will be "mounted", that is, individual files will be read
@@ -331,6 +334,7 @@ def __init__(
             raise ValueError("The name of the dataset must be a non-empty string.")
         self.name = name
         self.datastore = datastore
+        self.overwrite_existing = overwrite_existing
         self.version = version
         self.use_mounting = use_mounting
         # If target_folder is "" then convert to None
@@ -447,7 +451,7 @@ def to_output_dataset(self, workspace: Workspace, dataset_index: int) -> OutputF
 
         :param workspace: The AzureML workspace to read from.
         :param dataset_index: Suffix for using datasets as named inputs, the dataset will be marked OUTPUT_{index}
-        :return:
+        :return: An AzureML OutputFileDatasetConfig object, representing the output dataset.
         """
         status = f"Output dataset {self.name} (index {dataset_index}) will be "
         datastore = get_datastore(workspace, self.datastore)
@@ -464,7 +468,7 @@ def to_output_dataset(self, workspace: Workspace, dataset_index: int) -> OutputF
             result = dataset.as_mount()
         else:
             status += "uploaded when the job completes."
-            result = dataset.as_upload()
+            result = dataset.as_upload(overwrite=self.overwrite_existing)
         logging.info(status)
         return result
 


Test patch:
Repository: IntelPython/dpnp

Issue:
dpctl library name update - libDPPLSyclInterface.so --> libDPCTLSyclInterface.so 
The dpctl library names need to be updated (https://github.com/IntelPython/dpnp/blob/master/setup.py#L156) from `libDPPLSyclInterface.so` -> `libDPCTLSyclInterface.so`.

@shssf @Alexander-Makaryev 


Discussion:

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -153,7 +153,7 @@
     _dpctrl_include += [dpctl.get_include()]
     # _dpctrl_libpath = for package build + for local build
     _dpctrl_libpath += ["$ORIGIN/../dpctl"] + [os.path.join(dpctl.get_include(), '..')]
-    _dpctrl_lib += ["DPPLSyclInterface"]
+    _dpctrl_lib += ["DPCTLSyclInterface"]
 except ImportError:
     """
     Set local SYCL queue handler


Test patch:
Repository: IntelPython/dpnp

Issue:
dpnp.sum() for empty array crashes.
```python
import dpnp
x = dpnp.ones(0)
>>> x.sum()
terminate called after throwing an instance of 'oneapi::mkl::invalid_argument'
  what():  oneapi::mkl::stats::dataset: invalid argument: number of observations <= 0
Aborted (core dumped)
```


Discussion:

Resolving patch:
diff --git a/dpnp/dpnp_iface_mathematical.py b/dpnp/dpnp_iface_mathematical.py
--- a/dpnp/dpnp_iface_mathematical.py
+++ b/dpnp/dpnp_iface_mathematical.py
@@ -1629,10 +1629,16 @@ def sum(x1, axis=None, dtype=None, out=None, keepdims=False, initial=None, where
         if where is not True:
             pass
         else:
+            if dpnp.isscalar(out):
+                raise TypeError("output must be an array")
             out_desc = dpnp.get_dpnp_descriptor(out, copy_when_nondefault_queue=False) if out is not None else None
             result_obj = dpnp_sum(x1_desc, axis, dtype, out_desc, keepdims, initial, where).get_pyobj()
             result = dpnp.convert_single_elem_array_to_scalar(result_obj, keepdims)
 
+            if x1_desc.size == 0 and axis is None:
+                result = dpnp.zeros_like(result)
+                if out is not None:
+                    out[...] = result
             return result
 
     return call_origin(numpy.sum, x1, axis=axis, dtype=dtype, out=out, keepdims=keepdims, initial=initial, where=where)


Test patch:
diff --git a/tests/test_mathematical.py b/tests/test_mathematical.py
--- a/tests/test_mathematical.py
+++ b/tests/test_mathematical.py
@@ -923,3 +923,35 @@ def test_float_to_inf(self):
         dpnp_res = dpnp.array(a) ** dpnp.array(b)
 
         assert_allclose(numpy_res, dpnp_res.asnumpy())
+
+
+@pytest.mark.parametrize("dtype", get_all_dtypes(no_complex=True, no_bool=True))
+@pytest.mark.parametrize("axis", [None, 0, 1, 2, 3])
+def test_sum_empty(dtype, axis):
+    a = numpy.empty((1, 2, 0, 4), dtype=dtype)
+    numpy_res = a.sum(axis=axis)
+    dpnp_res = dpnp.array(a).sum(axis=axis)
+    assert_array_equal(numpy_res, dpnp_res.asnumpy())
+
+
+@pytest.mark.parametrize("dtype", get_all_dtypes(no_complex=True, no_bool=True))
+def test_sum_empty_out(dtype):
+    a = dpnp.empty((1, 2, 0, 4), dtype=dtype)
+    out = dpnp.ones(())
+    res = a.sum(out=out)
+    assert_array_equal(out.asnumpy(), res.asnumpy())
+    assert_array_equal(out.asnumpy(), numpy.array(0, dtype=dtype))
+
+
+@pytest.mark.parametrize("shape", [(), (1, 2, 3), (1, 0, 2), (10), (3, 3, 3), (5, 5), (0, 6)])
+@pytest.mark.parametrize("dtype_in", get_all_dtypes(no_complex=True, no_bool=True))
+@pytest.mark.parametrize("dtype_out", get_all_dtypes(no_complex=True, no_bool=True))
+def test_sum(shape, dtype_in, dtype_out):
+    a_np = numpy.ones(shape, dtype=dtype_in)
+    a = dpnp.ones(shape, dtype=dtype_in)
+    axes = [None, 0, 1, 2]
+    for axis in axes:
+        if axis is None or axis < a.ndim:
+            numpy_res = a_np.sum(axis=axis, dtype=dtype_out)
+            dpnp_res = a.sum(axis=axis, dtype=dtype_out)
+            assert_array_equal(numpy_res, dpnp_res.asnumpy())