From e92e7188f8664b7b961338a650870b0597bae5f7 Mon Sep 17 00:00:00 2001 From: Anthony Berg Date: Sun, 10 Aug 2025 12:43:48 +0200 Subject: [PATCH] feat(test): create unit test for HIPArray2D --- GPUSimulators/common/arrays/hip/array2d.py | 4 - tests/__init__.py | 0 tests/common/__init__.py | 0 tests/common/arrays/__init__.py | 0 tests/common/arrays/hiparray2d.py | 119 +++++++++++++++++++++ 5 files changed, 119 insertions(+), 4 deletions(-) create mode 100644 tests/__init__.py create mode 100644 tests/common/__init__.py create mode 100644 tests/common/arrays/__init__.py create mode 100644 tests/common/arrays/hiparray2d.py diff --git a/GPUSimulators/common/arrays/hip/array2d.py b/GPUSimulators/common/arrays/hip/array2d.py index 444a618..7f8bf0d 100644 --- a/GPUSimulators/common/arrays/hip/array2d.py +++ b/GPUSimulators/common/arrays/hip/array2d.py @@ -39,10 +39,6 @@ class HIPArray2D(BaseArray2D): self.data, self.pitch_d = hip_check(hip.hipMallocPitch(self.width, self.height)) - # TODO fix hipMallocPitch and remove this - # self.pitch_d = self.width - # self.data = hip_check(hip.hipMalloc(self.width * self.height)) - # Initialise the memory with an array of zeros. init_h = np.zeros(self.shape, self.dtype) self.pitch_h = shape_x * init_h.itemsize diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/common/__init__.py b/tests/common/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/common/arrays/__init__.py b/tests/common/arrays/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/common/arrays/hiparray2d.py b/tests/common/arrays/hiparray2d.py new file mode 100644 index 0000000..533182f --- /dev/null +++ b/tests/common/arrays/hiparray2d.py @@ -0,0 +1,119 @@ +import unittest + +from hip import hip +import numpy as np + +from GPUSimulators.common.hip_check import hip_check +from GPUSimulators.common.arrays.hip.array2d import HIPArray2D + + +class TestHIPArray2D(unittest.TestCase): + def setUp(self): + # Array parameters + self.nx = 1024 + self.ny = 1024 + self.x_halo = 2 + self.y_halo = 2 + + self.shape = (self.nx, self.ny) + self.extent = (self.x_halo, self.y_halo, self.nx, self.ny) + self.dtype = np.float32() + + self.stream = hip_check(hip.hipStreamCreate()) + + def tearDown(self): + hip_check(hip.hipStreamDestroy(self.stream)) + + def test_zeros_transfer(self): + upload = np.zeros(shape=self.shape, dtype=self.dtype) + + array = HIPArray2D(stream=self.stream, nx=self.nx, ny=self.ny, x_halo=self.x_halo, y_halo=self.y_halo, + dtype=self.dtype) + + array.upload(stream=self.stream, cpu_data=upload, extent=self.extent) + + # Download to check the data is sane + # Download without passing an array + download = array.download(stream=self.stream, asynch=False, extent=self.extent) + + self.assertTrue(np.allclose(upload, download), "Download without cpu_data does not provide equal arrays.") + + # Download with passing an array + download_array = np.zeros_like(upload) + array.download(stream=self.stream, cpu_data=download_array, asynch=False, extent=self.extent) + self.assertTrue(np.allclose(upload, download_array), + "Download with cpu_data does not provide equal arrays.") + + def test_int_transfer(self): + upload = np.ones(shape=self.shape, dtype=self.dtype) + array = HIPArray2D(stream=self.stream, nx=self.nx, ny=self.ny, x_halo=self.x_halo, y_halo=self.y_halo, + dtype=self.dtype) + + array.upload(stream=self.stream, cpu_data=upload, extent=self.extent) + + # Download to check the data is sane + # Download without passing an array + download = array.download(stream=self.stream, asynch=False, extent=self.extent) + + self.assertTrue(np.allclose(upload, download), "Download without cpu_data does not provide equal arrays.") + + # Download with passing an array + download_array = np.zeros_like(upload) + array.download(stream=self.stream, cpu_data=download_array, asynch=False, extent=self.extent) + self.assertTrue(np.allclose(upload, download_array), + "Download with cpu_data does not provide equal arrays.") + + def test_random_transfer(self): + rng = np.random.default_rng(seed=42) + + upload = rng.random(size=self.shape, dtype=self.dtype) + + array = HIPArray2D(stream=self.stream, nx=self.nx, ny=self.ny, x_halo=self.x_halo, y_halo=self.y_halo, + dtype=self.dtype) + + array.upload(stream=self.stream, cpu_data=upload, extent=self.extent) + + # Download to check the data is sane + # Download without passing an array + download = array.download(stream=self.stream, asynch=False, extent=self.extent) + + self.assertTrue(np.allclose(upload, download), "Download without cpu_data does not provide equal arrays.") + + # Download with passing an array + download_array = np.zeros_like(upload) + array.download(stream=self.stream, cpu_data=download_array, asynch=False, extent=self.extent) + self.assertTrue(np.allclose(upload, download_array), + "Download with cpu_data does not provide equal arrays.") + + def test_async(self): + rng = np.random.default_rng(seed=42) + + upload = rng.random(size=self.shape, dtype=self.dtype) + array = HIPArray2D(stream=self.stream, nx=self.nx, ny=self.ny, x_halo=self.x_halo, y_halo=self.y_halo, + dtype=self.dtype) + + array.upload(stream=self.stream, cpu_data=upload, extent=self.extent) + + # Download without passing an array + download = array.download(stream=self.stream, asynch=True, extent=self.extent) + hip_check(hip.hipStreamSynchronize(self.stream)) + + self.assertTrue(np.allclose(upload, download), "Download without cpu_data does not provide equal arrays.") + + # Redo test but passing an array this time + upload = rng.random(size=self.shape, dtype=self.dtype) + + array.upload(stream=self.stream, cpu_data=upload, extent=self.extent) + + # Download by passing an array + download_array = np.zeros_like(upload) + array.download(stream=self.stream, cpu_data=download_array, asynch=True, extent=self.extent) + hip_check(hip.hipStreamSynchronize(self.stream)) + + self.assertTrue(np.allclose(upload, download_array), + "Download with cpu_data does not provide equal arrays.") + + + +if __name__ == '__main__': + unittest.main()