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
Drivercontext managerOpen and register files with
FileHandleRegister GPU memory with
BufferPerform synchronous
read()andwrite()operationsHandle errors with
HipFileExceptionClean 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 Install the hipFile 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:
#!/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#
import os
from hipfile import Buffer, Driver, FileHandle, HipFileException
The Python package name is hipfile. For the full API, see
Python API reference.
Initialize the driver#
with Driver():
...
Driver is a context manager that calls hipFileDriverOpen() on entry and
hipFileDriverClose() on exit.
Open files with FileHandle#
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#
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#
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#
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#
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#
python gpu_copy.py /path/to/source_file /path/to/dest_file
On success, the script prints the number of bytes copied:
Copied 1048576 bytes from /path/to/source_file to /path/to/dest_file