From d49116bfca747d136ac0a6c8b8bfc1d07d48d0e8 Mon Sep 17 00:00:00 2001 From: Anton Volkov Date: Wed, 5 Nov 2025 14:20:42 +0100 Subject: [PATCH 1/4] Add implementation of dpnp.ndarray.tolist method --- dpnp/dpnp_array.py | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/dpnp/dpnp_array.py b/dpnp/dpnp_array.py index e8902a77eb1..3d2fb2f7d3d 100644 --- a/dpnp/dpnp_array.py +++ b/dpnp/dpnp_array.py @@ -2013,7 +2013,34 @@ def to_device(self, device, /, *, stream=None): return dpnp_array._create_from_usm_ndarray(usm_res) # 'tobytes', - # 'tofile', + + def tofile(self, fid, sep="", format=""): + """ + Writes the array to a file as text or binary (default). + + For full documentation refer to :obj:`numpy.ndarray.tofile`. + + Parameters + ---------- + fid : {file. str, path} + An open file object, or a string containing a filename. + sep : str, optional + Separator between array items for text output. If ``""`` (empty), + a binary file is written. + + Default: ``""``. + format : str, optional + Format string for text file output (when non-empty `sep` is passed). + Each entry in the array is formatted to text by first converting it + to the closest Python type, and then using ``format % item``. If + ``""`` (empty), no formatting is used while converting to the + string. + + Default: ``""``. + + """ + + self.asnumpy().tofile(fid, sep=sep, format=format) def tolist(self): """ From 7c5328976504ba67616ece2356360bb9f01e55a6 Mon Sep 17 00:00:00 2001 From: Anton Volkov Date: Wed, 5 Nov 2025 14:22:17 +0100 Subject: [PATCH 2/4] Add tests to cover the new method --- dpnp/tests/test_ndarray.py | 59 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/dpnp/tests/test_ndarray.py b/dpnp/tests/test_ndarray.py index 7aa7ac699e4..2aa6c0f49ac 100644 --- a/dpnp/tests/test_ndarray.py +++ b/dpnp/tests/test_ndarray.py @@ -11,6 +11,7 @@ import dpnp from .helper import ( + generate_random_numpy_array, get_abs_array, get_all_dtypes, get_complex_dtypes, @@ -107,6 +108,64 @@ def test_strides(self): assert xp.full_like(a, fill_value=6) not in a +class TestToFile: + def _create_data(self): + x = generate_random_numpy_array((2, 4, 3), dtype=complex) + x[0, :, 1] = [numpy.nan, numpy.inf, -numpy.inf, numpy.nan] + return dpnp.array(x) + + @pytest.fixture(params=["string", "path_obj"]) + def tmp_filename(self, tmp_path, request): + # This fixture covers two cases: + # one where the filename is a string and + # another where it is a pathlib object + filename = tmp_path / "file" + if request.param == "string": + filename = str(filename) + yield filename + + def test_roundtrip_file(self, tmp_filename): + a = self._create_data() + + with open(tmp_filename, "wb") as f: + a.tofile(f) + + # reconstruct the array back from the file + with open(tmp_filename, "rb") as f: + b = dpnp.fromfile(f, dtype=a.dtype) + assert_array_equal(b, a.asnumpy().flat) + + def test_roundtrip(self, tmp_filename): + a = self._create_data() + + a.tofile(tmp_filename) + b = dpnp.fromfile(tmp_filename, dtype=a.dtype) + assert_array_equal(b, a.asnumpy().flat) + + def test_sep(self, tmp_filename): + a = dpnp.array([1.51, 2, 3.51, 4]) + + with open(tmp_filename, "w") as f: + a.tofile(f, sep=",") + + # reconstruct the array + with open(tmp_filename, "r") as f: + s = f.read() + b = dpnp.array([float(p) for p in s.split(",")], dtype=a.dtype) + assert_array_equal(a, b.asnumpy()) + + def test_format(self, tmp_filename): + a = dpnp.array([1.51, 2, 3.51, 4]) + + with open(tmp_filename, "w") as f: + a.tofile(f, sep=",", format="%.2f") + + # reconstruct the array as a string + with open(tmp_filename, "r") as f: + s = f.read() + assert_equal(s, "1.51,2.00,3.51,4.00") + + class TestToList: @pytest.mark.parametrize( "data", [[1, 2], [[1, 2], [3, 4]]], ids=["1d", "2d"] From 05617643370f7e25dcd0d7e28222593a47d39668 Mon Sep 17 00:00:00 2001 From: Anton Volkov Date: Thu, 6 Nov 2025 16:14:42 +0100 Subject: [PATCH 3/4] Add see also to dpnp.fromfile function --- dpnp/dpnp_array.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/dpnp/dpnp_array.py b/dpnp/dpnp_array.py index 3d2fb2f7d3d..456cc84b5b2 100644 --- a/dpnp/dpnp_array.py +++ b/dpnp/dpnp_array.py @@ -2038,6 +2038,11 @@ def tofile(self, fid, sep="", format=""): Default: ``""``. + See Also + -------- + :obj:`dpnp.fromfile` : Construct an array from data in a text or binary + file. + """ self.asnumpy().tofile(fid, sep=sep, format=format) From cb346fbf509fb9f55e7c3dab569ec4c781e545df Mon Sep 17 00:00:00 2001 From: Anton Volkov Date: Thu, 6 Nov 2025 16:15:27 +0100 Subject: [PATCH 4/4] Add PR to the changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 79feecded40..5ee91edfa53 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ Also, that release drops support for Python 3.9, making Python 3.10 the minimum * Added implementation of `dpnp.scipy.special.erfinv` and `dpnp.scipy.special.erfcinv` [#2624](https://github.com/IntelPython/dpnp/pull/2624) * Enabled support of Python 3.14 [#2631](https://github.com/IntelPython/dpnp/pull/2631) * Added implementation of `dpnp.ndarray.tolist` method [#2652](https://github.com/IntelPython/dpnp/pull/2652) +* Added implementation of `dpnp.ndarray.tofile` method [#2635](https://github.com/IntelPython/dpnp/pull/2635) ### Changed