CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
192 lines
5.8 KiB
ReStructuredText
192 lines
5.8 KiB
ReStructuredText
.. meta::
|
|
:description: Tutorial walking through direct-to-GPU I/O using the hipFile Python bindings, covering Driver, FileHandle, Buffer, read, write, and error handling.
|
|
:keywords: hipFile, Python, GPU I/O, tutorial, ROCm, direct I/O, Buffer, Driver, FileHandle
|
|
|
|
*****************************************
|
|
Perform GPU I/O with the Python bindings
|
|
*****************************************
|
|
|
|
This tutorial walks you through a complete example that uses the hipFile Python
|
|
bindings to read data from a file directly into GPU memory and write it back to
|
|
a different file. You will learn how to:
|
|
|
|
- Initialize the hipFile driver with the ``Driver`` context manager
|
|
- Open and register files with ``FileHandle``
|
|
- Register GPU memory with ``Buffer``
|
|
- Perform synchronous ``read()`` and ``write()`` operations
|
|
- Handle errors with ``HipFileException``
|
|
- Clean up resources automatically through context managers
|
|
|
|
This workflow is useful whenever you need to move large datasets between
|
|
storage and GPU memory without an intermediate copy through host RAM.
|
|
|
|
Prerequisites
|
|
===============
|
|
|
|
Verify you have:
|
|
|
|
- An AMD GPU supported by ROCm.
|
|
- ROCm installed and configured.
|
|
- The hipFile C library built and installed.
|
|
- The hipFile Python package installed in a virtual environment.
|
|
|
|
See :doc:`/install/python-bindings` for installation.
|
|
|
|
Complete example
|
|
==================
|
|
|
|
The following script reads a source file into GPU memory and writes its
|
|
contents to a destination file. It uses the same API sequence as
|
|
``python/main.py`` in the hipFile source tree, adapted for chunked copying
|
|
with CLI arguments. Save it as ``gpu_copy.py``:
|
|
|
|
.. code-block:: python
|
|
|
|
#!/usr/bin/env python3
|
|
"""Copy a file through GPU memory using hipFile."""
|
|
|
|
import os
|
|
import sys
|
|
|
|
from hipfile import Buffer, Driver, FileHandle, HipFileException
|
|
|
|
CHUNK_SIZE = 64 * 1024 # 64 KiB per I/O operation
|
|
|
|
def gpu_copy(src_path: str, dst_path: str) -> None:
|
|
gpu_ptr = hipMalloc(CHUNK_SIZE)
|
|
|
|
with Driver():
|
|
with Buffer.from_ctypes_void_p(gpu_ptr, CHUNK_SIZE, 0) as buf:
|
|
with FileHandle(
|
|
src_path, os.O_RDONLY | os.O_DIRECT
|
|
) as src, FileHandle(
|
|
dst_path,
|
|
os.O_WRONLY | os.O_DIRECT | os.O_CREAT | os.O_TRUNC,
|
|
) as dst:
|
|
file_offset = 0
|
|
while True:
|
|
bytes_read = src.read(
|
|
buf, CHUNK_SIZE, file_offset, 0
|
|
)
|
|
if bytes_read == 0:
|
|
break
|
|
dst.write(buf, bytes_read, file_offset, 0)
|
|
file_offset += bytes_read
|
|
|
|
hipFree(gpu_ptr)
|
|
print(f"Copied {file_offset} bytes from {src_path} to {dst_path}")
|
|
|
|
if __name__ == "__main__":
|
|
if len(sys.argv) != 3:
|
|
print(f"Usage: {sys.argv[0]} SOURCE DEST", file=sys.stderr)
|
|
sys.exit(1)
|
|
try:
|
|
gpu_copy(sys.argv[1], sys.argv[2])
|
|
except HipFileException as exc:
|
|
print(f"hipFile error: {exc}", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
Step-by-step walkthrough
|
|
==========================
|
|
|
|
Import modules
|
|
--------------
|
|
|
|
.. code-block:: python
|
|
|
|
import os
|
|
from hipfile import Buffer, Driver, FileHandle, HipFileException
|
|
|
|
The Python package name is ``hipfile``. For the full API, see
|
|
:doc:`/reference/api-python`.
|
|
|
|
Initialize the driver
|
|
---------------------
|
|
|
|
.. code-block:: python
|
|
|
|
with Driver():
|
|
...
|
|
|
|
``Driver`` is a context manager that calls ``hipFileDriverOpen()`` on entry and
|
|
``hipFileDriverClose()`` on exit.
|
|
|
|
Open files with FileHandle
|
|
--------------------------
|
|
|
|
.. code-block:: python
|
|
|
|
with FileHandle(src_path, os.O_RDONLY | os.O_DIRECT) as src, \
|
|
FileHandle(dst_path, os.O_WRONLY | os.O_DIRECT | os.O_CREAT | os.O_TRUNC) as dst:
|
|
...
|
|
|
|
``FileHandle`` takes a file system path and ``os.open()`` flags. Include
|
|
``os.O_DIRECT`` for direct I/O. It opens the file, registers the handle with
|
|
hipFile, and deregisters on exit.
|
|
|
|
Allocate and register GPU memory
|
|
--------------------------------
|
|
|
|
.. code-block:: python
|
|
|
|
gpu_ptr = hipMalloc(CHUNK_SIZE)
|
|
with Buffer.from_ctypes_void_p(gpu_ptr, CHUNK_SIZE, 0) as buf:
|
|
...
|
|
|
|
``hipMalloc()`` allocates device memory. ``Buffer.from_ctypes_void_p()`` wraps the
|
|
pointer for registration with hipFile. ``Buffer`` doesn't free the allocation.
|
|
Call ``hipFree()`` after the buffer is deregistered.
|
|
|
|
Read data into the GPU buffer
|
|
-----------------------------
|
|
|
|
.. code-block:: python
|
|
|
|
bytes_read = src.read(buf, CHUNK_SIZE, file_offset, 0)
|
|
|
|
``read()`` performs a synchronous read from the registered file into device
|
|
memory. It returns the number of bytes read. A return value of ``0`` indicates
|
|
end-of-file.
|
|
|
|
Write data from the GPU buffer
|
|
------------------------------
|
|
|
|
.. code-block:: python
|
|
|
|
dst.write(buf, bytes_read, file_offset, 0)
|
|
|
|
``write()`` performs a synchronous write from device memory to the registered
|
|
file. It returns the number of bytes written.
|
|
|
|
Handle errors
|
|
-------------
|
|
|
|
.. code-block:: python
|
|
|
|
except HipFileException as exc:
|
|
print(f"hipFile error: {exc}", file=sys.stderr)
|
|
|
|
hipFile C API failures raise ``HipFileException``. ``FileHandle.read()`` and
|
|
``FileHandle.write()`` may also raise ``RuntimeError`` when the handle isn't open
|
|
or ``OSError`` when the platform sets ``errno``.
|
|
|
|
Clean up resources
|
|
------------------
|
|
|
|
``Driver``, ``FileHandle``, and ``Buffer`` are context managers. Call
|
|
``hipFree()`` to release the GPU allocation after the ``Buffer`` context exits.
|
|
|
|
Running the example
|
|
*******************
|
|
|
|
.. code:: shell
|
|
|
|
python gpu_copy.py /path/to/source_file /path/to/dest_file
|
|
|
|
On success, the script prints the number of bytes copied:
|
|
|
|
.. code-block:: text
|
|
|
|
Copied 1048576 bytes from /path/to/source_file to /path/to/dest_file
|
|
|