hipfile 0.0.1.dev0__tar.gz → 0.2.0.dev1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,32 @@
1
+ # Changelog
2
+
3
+ All notable changes to the hipFile Python bindings will be documented in this file.
4
+
5
+ ## [Unreleased]
6
+
7
+ ## [0.2.0.dev1]
8
+
9
+ ### Fixed
10
+
11
+ - Release the Python GIL during all C function calls to prevent blocking other
12
+ threads during GPU IO operations. This resolves a performance regression
13
+ observed in multi-threaded applications (e.g., LMCache) when switching from
14
+ ctypes-based bindings to the Cython bindings.
15
+
16
+ ### Added
17
+
18
+ - Complete typing hints for the public API.
19
+
20
+ ## [0.2.0.dev0]
21
+
22
+ ### Added
23
+
24
+ - Initial release of the hipFile Python bindings.
25
+ - Cython-based low-level wrappers for the hipFile C API (`_hipfile.pyx`).
26
+ - High-level Pythonic API: `Driver`, `FileHandle`, `Buffer` classes with
27
+ context manager support.
28
+ - `hipMalloc` / `hipFree` helpers for GPU memory allocation.
29
+ - Error handling via `HipFileException` with hipFile and HIP driver error codes.
30
+ - `FileHandleType` and `OpError` enums.
31
+ - `get_version()` and `driver_get_properties()` utility functions.
32
+ - scikit-build-core based build system.
@@ -0,0 +1,76 @@
1
+ cmake_minimum_required(VERSION 3.21)
2
+ project(hipfile-python LANGUAGES C)
3
+
4
+ # ---- Python & Cython -----------------------------------------------------
5
+
6
+ find_package(Python REQUIRED COMPONENTS Interpreter Development.Module)
7
+ find_program(CYTHON_EXECUTABLE cython REQUIRED)
8
+
9
+ # ---- hipFile library & headers --------------------------------------------
10
+
11
+ # hipfile.h location (prefer sibling include/ from source, fall back to installed)
12
+ find_path(HIPFILE_INCLUDE_DIR hipfile.h
13
+ HINTS
14
+ "${CMAKE_CURRENT_SOURCE_DIR}/../include"
15
+ "/opt/rocm/include"
16
+ PATH "Path to directory containing hipfile.h"
17
+ )
18
+ if(NOT HIPFILE_INCLUDE_DIR)
19
+ message(FATAL_ERROR
20
+ "Could not find hipfile.h. Set -DHIPFILE_INCLUDE_DIR=<path> or "
21
+ "install hipfile to /opt/rocm.")
22
+ endif()
23
+
24
+ # libhipfile.so location
25
+ find_library(HIPFILE_LIBRARY hipfile
26
+ HINTS
27
+ "${CMAKE_CURRENT_SOURCE_DIR}/../build/src/amd_detail"
28
+ "/opt/rocm/lib"
29
+ )
30
+ if(NOT HIPFILE_LIBRARY)
31
+ message(FATAL_ERROR
32
+ "Could not find libhipfile. Set -DHIPFILE_LIBRARY=<path> or "
33
+ "install hipfile to /opt/rocm.")
34
+ endif()
35
+
36
+ # HIP runtime headers (needed because hipfile.h includes hip/hip_runtime_api.h)
37
+ find_path(HIP_INCLUDE_DIR hip/hip_runtime_api.h
38
+ HINTS
39
+ "/opt/rocm/include"
40
+ "/opt/rocm/hip/include"
41
+ )
42
+ if(NOT HIP_INCLUDE_DIR)
43
+ message(FATAL_ERROR
44
+ "Could not find hip/hip_runtime_api.h. Set -DHIP_INCLUDE_DIR=<path> "
45
+ "or install HIP development headers.")
46
+ endif()
47
+
48
+ # ---- Cythonize ------------------------------------------------------------
49
+
50
+ set(_PYX_SRC "${CMAKE_CURRENT_SOURCE_DIR}/hipfile/_hipfile.pyx")
51
+ set(_C_OUT "${CMAKE_CURRENT_BINARY_DIR}/_hipfile.c")
52
+
53
+ add_custom_command(
54
+ OUTPUT "${_C_OUT}"
55
+ COMMAND "${CYTHON_EXECUTABLE}" "${_PYX_SRC}" -o "${_C_OUT}" -3
56
+ DEPENDS
57
+ "${_PYX_SRC}"
58
+ "${CMAKE_CURRENT_SOURCE_DIR}/hipfile/_chipfile.pxd"
59
+ COMMENT "Cythonizing _hipfile.pyx"
60
+ )
61
+
62
+ # ---- Build extension module -----------------------------------------------
63
+ # lint_cmake: -readability/wonkycase
64
+ Python_add_library(_hipfile MODULE "${_C_OUT}" WITH_SOABI)
65
+ # lint_cmake: +readability/wonkycase
66
+ target_include_directories(_hipfile PRIVATE
67
+ "${HIPFILE_INCLUDE_DIR}"
68
+ "${HIP_INCLUDE_DIR}"
69
+ )
70
+
71
+ target_link_libraries(_hipfile PRIVATE "${HIPFILE_LIBRARY}")
72
+
73
+ # _hipfile bindings only support AMD for now
74
+ target_compile_definitions(_hipfile PRIVATE __HIP_PLATFORM_AMD__)
75
+
76
+ install(TARGETS _hipfile DESTINATION hipfile)
@@ -0,0 +1,53 @@
1
+ Metadata-Version: 2.2
2
+ Name: hipfile
3
+ Version: 0.2.0.dev1
4
+ Summary: Python bindings for hipFile — direct-to-GPU file IO via AMD Infinity Storage (AIS)
5
+ Keywords: hipfile,rocm,amd,hip,AIS
6
+ Maintainer-Email: AMD hipFile Team <hipfile-maintainer@amd.com>, Riley Dixon <riley.dixon@amd.com>
7
+ License: MIT
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Project-URL: Homepage, https://github.com/ROCm/rocm-systems/tree/develop/projects/hipfile
10
+ Project-URL: Changelog, https://github.com/ROCm/rocm-systems/blob/develop/projects/hipfile/python/CHANGELOG.md
11
+ Requires-Python: >=3.10
12
+ Description-Content-Type: text/markdown
13
+
14
+ # hipFile Python Bindings
15
+
16
+ Python bindings for the [hipFile](https://github.com/ROCm/rocm-systems/tree/develop/projects/hipfile) C library.
17
+
18
+ > [!CAUTION]
19
+ > These bindings in particular are *experimental* and the API will change.
20
+
21
+ ## Building & Installing
22
+
23
+ 1. Setup a Python virtual environment.
24
+ ```bash
25
+ $ python3 -m venv .venv
26
+ ```
27
+ 2. Activate the Python virtual environment.
28
+ ```bash
29
+ $ source .venv/bin/activate
30
+ ```
31
+ 3. Build or install the C hipFile library. See [INSTALL.md](../INSTALL.md).
32
+ 4. Build the hipFile package.\
33
+ and shared library using its configured search paths, including the
34
+ source `../include` location for headers, a CMake build-directory
35
+ hint for the shared library, and the default ROCm install location.
36
+ The search path can be overridden by setting `HIPFILE_INCLUDE_DIR`,
37
+ `HIPFILE_LIBRARY`, or `HIP_INCLUDE_DIR` via the build arg
38
+ `-Ccmake.define.<KEY>=<VALUE>`.
39
+ ```bash
40
+ (.venv) $ cd projects/hipfile/python
41
+ (.venv) $ python -m build --wheel
42
+ ```
43
+ Or to install an editable version of the Python package:
44
+ ```bash
45
+ (.venv) $ cd projects/hipfile/python
46
+ (.venv) $ pip install -e .
47
+ ```
48
+
49
+ An editable Python package is a development package that allows for
50
+ live changes to the <ins>Python</ins> source code to be applied
51
+ immediately without needing to rebuild or reinstall the Python
52
+ package under development. Any changes to the <ins>Cython</ins>
53
+ source code will require a rebuild step.
@@ -0,0 +1,40 @@
1
+ # hipFile Python Bindings
2
+
3
+ Python bindings for the [hipFile](https://github.com/ROCm/rocm-systems/tree/develop/projects/hipfile) C library.
4
+
5
+ > [!CAUTION]
6
+ > These bindings in particular are *experimental* and the API will change.
7
+
8
+ ## Building & Installing
9
+
10
+ 1. Setup a Python virtual environment.
11
+ ```bash
12
+ $ python3 -m venv .venv
13
+ ```
14
+ 2. Activate the Python virtual environment.
15
+ ```bash
16
+ $ source .venv/bin/activate
17
+ ```
18
+ 3. Build or install the C hipFile library. See [INSTALL.md](../INSTALL.md).
19
+ 4. Build the hipFile package.\
20
+ and shared library using its configured search paths, including the
21
+ source `../include` location for headers, a CMake build-directory
22
+ hint for the shared library, and the default ROCm install location.
23
+ The search path can be overridden by setting `HIPFILE_INCLUDE_DIR`,
24
+ `HIPFILE_LIBRARY`, or `HIP_INCLUDE_DIR` via the build arg
25
+ `-Ccmake.define.<KEY>=<VALUE>`.
26
+ ```bash
27
+ (.venv) $ cd projects/hipfile/python
28
+ (.venv) $ python -m build --wheel
29
+ ```
30
+ Or to install an editable version of the Python package:
31
+ ```bash
32
+ (.venv) $ cd projects/hipfile/python
33
+ (.venv) $ pip install -e .
34
+ ```
35
+
36
+ An editable Python package is a development package that allows for
37
+ live changes to the <ins>Python</ins> source code to be applied
38
+ immediately without needing to rebuild or reinstall the Python
39
+ package under development. Any changes to the <ins>Cython</ins>
40
+ source code will require a rebuild step.
@@ -0,0 +1,27 @@
1
+ # pylint: disable=C0114
2
+
3
+ from hipfile._hipfile import ( # pylint: disable=E0401,E0611
4
+ # Constants
5
+ VERSION_MAJOR as _VERSION_MAJOR,
6
+ VERSION_MINOR as _VERSION_MINOR,
7
+ VERSION_PATCH as _VERSION_PATCH,
8
+ )
9
+ from hipfile.buffer import Buffer
10
+ from hipfile.driver import Driver
11
+ from hipfile.enums import FileHandleType, OpError
12
+ from hipfile.error import HipFileException
13
+ from hipfile.file import FileHandle
14
+ from hipfile.properties import driver_get_properties, get_version
15
+
16
+ __all__ = [
17
+ "__version__",
18
+ "Driver",
19
+ "FileHandle",
20
+ "Buffer",
21
+ "HipFileException",
22
+ "FileHandleType",
23
+ "OpError",
24
+ "driver_get_properties",
25
+ "get_version",
26
+ ]
27
+ __version__ = f"{_VERSION_MAJOR}.{_VERSION_MINOR}.{_VERSION_PATCH}"
@@ -0,0 +1,190 @@
1
+ # cython: language_level=3
2
+ """
3
+ C declarations for hipFile API (extern from hipfile.h).
4
+
5
+ This .pxd file declares the subset of the hipFile C API that is
6
+ wrapped by the low-level Cython bindings.
7
+ """
8
+
9
+ from libc.stdint cimport int64_t, uint64_t
10
+ from posix.types cimport off_t
11
+
12
+
13
+ # ---------------------------------------------------------------------------
14
+ # HIP runtime stub — only hipError_t is needed
15
+ # ---------------------------------------------------------------------------
16
+
17
+ cdef extern from "hip/hip_runtime_api.h":
18
+ ctypedef enum hipError_t:
19
+ hipSuccess = 0
20
+
21
+ hipError_t hipPeekAtLastError()
22
+
23
+
24
+ # ---------------------------------------------------------------------------
25
+ # hipFile public API
26
+ # ---------------------------------------------------------------------------
27
+
28
+ cdef extern from "hipfile.h":
29
+
30
+ # -- Version constants --------------------------------------------------
31
+
32
+ int HIPFILE_VERSION_MAJOR
33
+ int HIPFILE_VERSION_MINOR
34
+ int HIPFILE_VERSION_PATCH
35
+ int HIPFILE_BASE_ERR
36
+
37
+ # -- Platform-independent types -----------------------------------------
38
+
39
+ ctypedef off_t hoff_t
40
+
41
+ # -- Error handling -----------------------------------------------------
42
+
43
+ ctypedef enum hipFileOpError_t:
44
+ hipFileSuccess
45
+ hipFileDriverNotInitialized
46
+ hipFileDriverInvalidProps
47
+ hipFileDriverUnsupportedLimit
48
+ hipFileDriverVersionMismatch
49
+ hipFileDriverVersionReadError
50
+ hipFileDriverClosing
51
+ hipFilePlatformNotSupported
52
+ hipFileIONotSupported
53
+ hipFileDeviceNotSupported
54
+ hipFileDriverError
55
+ hipFileHipDriverError
56
+ hipFileHipPointerInvalid
57
+ hipFileHipMemoryTypeInvalid
58
+ hipFileHipPointerRangeError
59
+ hipFileHipContextMismatch
60
+ hipFileInvalidMappingSize
61
+ hipFileInvalidMappingRange
62
+ hipFileInvalidFileType
63
+ hipFileInvalidFileOpenFlag
64
+ hipFileDIONotSet
65
+ # 5021 intentionally unused
66
+ hipFileInvalidValue
67
+ hipFileMemoryAlreadyRegistered
68
+ hipFileMemoryNotRegistered
69
+ hipFilePermissionDenied
70
+ hipFileDriverAlreadyOpen
71
+ hipFileHandleNotRegistered
72
+ hipFileHandleAlreadyRegistered
73
+ hipFileDeviceNotFound
74
+ hipFileInternalError
75
+ hipFileGetNewFDFailed
76
+ # 5032 intentionally unused
77
+ hipFileDriverSetupError
78
+ hipFileIODisabled
79
+ hipFileBatchSubmitFailed
80
+ hipFileGPUMemoryPinningFailed
81
+ hipFileBatchFull
82
+ hipFileAsyncNotSupported
83
+ hipFileIOMaxError
84
+
85
+ ctypedef struct hipFileError_t:
86
+ hipFileOpError_t err
87
+ hipError_t hip_drv_err
88
+
89
+ # -- Opaque handles -----------------------------------------------------
90
+
91
+ ctypedef void *hipFileHandle_t
92
+
93
+ # -- File handle types --------------------------------------------------
94
+
95
+ ctypedef enum hipFileFileHandleType_t:
96
+ hipFileHandleTypeOpaqueFD
97
+ hipFileHandleTypeOpaqueWin32
98
+ hipFileHandleTypeUserspaceFS
99
+
100
+ # -- Userspace FS ops (opaque — only needed as pointer type) ------------
101
+
102
+ ctypedef struct hipFileFSOps_t:
103
+ pass
104
+
105
+ # -- File descriptor ----------------------------------------------------
106
+ # The anonymous union is accessed via Cython C-name strings.
107
+
108
+ ctypedef struct hipFileDescr_t:
109
+ hipFileFileHandleType_t type
110
+ int fd "handle.fd"
111
+ void *hFile "handle.hFile"
112
+ const hipFileFSOps_t *fs_ops
113
+
114
+ # -- Driver status / control / feature flag enums -----------------------
115
+
116
+ ctypedef enum hipFileDriverStatusFlags_t:
117
+ hipFileLustreSupported
118
+ hipFileWekaFSSupported
119
+ hipFileNFSSupported
120
+ hipFileGPFSSupported
121
+ hipFileNVMeSupported
122
+ hipFileNVMeoFSupported
123
+ hipFileSCSISupported
124
+ hipFileScaleFluxCSDSupported
125
+ hipFileNVMeshSupported
126
+ hipFileBeeGFSSupported
127
+ # 10 reserved for YRCloudFile
128
+ hipFileNVMeP2PSupported
129
+ hipFileScatefsSupported
130
+
131
+ ctypedef enum hipFileDriverControlFlags_t:
132
+ hipFileUsePollMode
133
+ hipFileAllowCompatMode
134
+
135
+ ctypedef enum hipFileFeatureFlags_t:
136
+ hipFileDynRoutingSupported
137
+ hipFileBatchIOSupported
138
+ hipFileStreamsSupported
139
+ hipFileParallelIOSupported
140
+
141
+ # -- Driver properties --------------------------------------------------
142
+ # Nested anonymous struct ``nvfs`` is flattened with C-name strings.
143
+
144
+ ctypedef struct hipFileDriverProps_t:
145
+ unsigned int nvfs_major_version "nvfs.major_version"
146
+ unsigned int nvfs_minor_version "nvfs.minor_version"
147
+ uint64_t nvfs_poll_thresh_size "nvfs.poll_thresh_size"
148
+ uint64_t nvfs_max_direct_io_size "nvfs.max_direct_io_size"
149
+ unsigned int nvfs_driver_status_flags "nvfs.driver_status_flags"
150
+ unsigned int nvfs_driver_control_flags "nvfs.driver_control_flags"
151
+ unsigned int feature_flags
152
+ uint64_t max_device_cache_size
153
+ uint64_t per_buffer_cache_size
154
+ uint64_t max_device_pinned_mem_size
155
+ unsigned int max_batch_io_count
156
+ unsigned int max_batch_io_timeout_msecs
157
+
158
+ # -- Function declarations ----------------------------------------------
159
+
160
+ # Error
161
+ const char *hipFileGetOpErrorString(hipFileOpError_t status)
162
+
163
+ # File handles
164
+ hipFileError_t hipFileHandleRegister(hipFileHandle_t *fh,
165
+ hipFileDescr_t *descr)
166
+ void hipFileHandleDeregister(hipFileHandle_t fh)
167
+
168
+ # Buffer registration
169
+ hipFileError_t hipFileBufRegister(const void *buffer_base,
170
+ size_t length, int flags)
171
+ hipFileError_t hipFileBufDeregister(const void *buffer_base)
172
+
173
+ # Synchronous I/O
174
+ ssize_t hipFileRead(hipFileHandle_t fh, void *buffer_base, size_t size,
175
+ hoff_t file_offset, hoff_t buffer_offset)
176
+ ssize_t hipFileWrite(hipFileHandle_t fh, const void *buffer_base,
177
+ size_t size, hoff_t file_offset,
178
+ hoff_t buffer_offset)
179
+
180
+ # Driver lifecycle
181
+ hipFileError_t hipFileDriverOpen()
182
+ hipFileError_t hipFileDriverClose()
183
+ int64_t hipFileUseCount()
184
+
185
+ # Driver properties
186
+ hipFileError_t hipFileDriverGetProperties(hipFileDriverProps_t *props)
187
+
188
+ # Version
189
+ hipFileError_t hipFileGetVersion(unsigned *major, unsigned *minor,
190
+ unsigned *patch)
@@ -0,0 +1,284 @@
1
+ # cython: language_level=3
2
+ """
3
+ Low-level Cython wrappers for the hipFile C API.
4
+
5
+ Every function mirrors the C API as closely as possible.
6
+ Functions that return ``hipFileError_t`` in C return a
7
+ ``(hipFileOpError_t, hipError_t)`` 2-tuple here.
8
+ """
9
+
10
+ from libc.errno cimport errno
11
+ from libc.string cimport memset
12
+ from libc.stdint cimport uintptr_t
13
+
14
+ cimport hipfile._chipfile as _c
15
+
16
+
17
+ # ---------------------------------------------------------------------------
18
+ # Module-level constants
19
+ # ---------------------------------------------------------------------------
20
+
21
+ VERSION_MAJOR = _c.HIPFILE_VERSION_MAJOR
22
+ VERSION_MINOR = _c.HIPFILE_VERSION_MINOR
23
+ VERSION_PATCH = _c.HIPFILE_VERSION_PATCH
24
+ BASE_ERR = _c.HIPFILE_BASE_ERR
25
+
26
+ # ---------------------------------------------------------------------------
27
+ # Enum re-exports (C → Python)
28
+ #
29
+ # ctypedef enum values from _chipfile.pxd are C-level only after cimport.
30
+ # These assignments create Python-visible module attributes whose values
31
+ # are resolved from the C enum at compile time.
32
+ # ---------------------------------------------------------------------------
33
+
34
+ # hipFileOpError_t
35
+ hipFileSuccess = <int>_c.hipFileSuccess
36
+ hipFileDriverNotInitialized = <int>_c.hipFileDriverNotInitialized
37
+ hipFileDriverInvalidProps = <int>_c.hipFileDriverInvalidProps
38
+ hipFileDriverUnsupportedLimit = <int>_c.hipFileDriverUnsupportedLimit
39
+ hipFileDriverVersionMismatch = <int>_c.hipFileDriverVersionMismatch
40
+ hipFileDriverVersionReadError = <int>_c.hipFileDriverVersionReadError
41
+ hipFileDriverClosing = <int>_c.hipFileDriverClosing
42
+ hipFilePlatformNotSupported = <int>_c.hipFilePlatformNotSupported
43
+ hipFileIONotSupported = <int>_c.hipFileIONotSupported
44
+ hipFileDeviceNotSupported = <int>_c.hipFileDeviceNotSupported
45
+ hipFileDriverError = <int>_c.hipFileDriverError
46
+ hipFileHipDriverError = <int>_c.hipFileHipDriverError
47
+ hipFileHipPointerInvalid = <int>_c.hipFileHipPointerInvalid
48
+ hipFileHipMemoryTypeInvalid = <int>_c.hipFileHipMemoryTypeInvalid
49
+ hipFileHipPointerRangeError = <int>_c.hipFileHipPointerRangeError
50
+ hipFileHipContextMismatch = <int>_c.hipFileHipContextMismatch
51
+ hipFileInvalidMappingSize = <int>_c.hipFileInvalidMappingSize
52
+ hipFileInvalidMappingRange = <int>_c.hipFileInvalidMappingRange
53
+ hipFileInvalidFileType = <int>_c.hipFileInvalidFileType
54
+ hipFileInvalidFileOpenFlag = <int>_c.hipFileInvalidFileOpenFlag
55
+ hipFileDIONotSet = <int>_c.hipFileDIONotSet
56
+ hipFileInvalidValue = <int>_c.hipFileInvalidValue
57
+ hipFileMemoryAlreadyRegistered = <int>_c.hipFileMemoryAlreadyRegistered
58
+ hipFileMemoryNotRegistered = <int>_c.hipFileMemoryNotRegistered
59
+ hipFilePermissionDenied = <int>_c.hipFilePermissionDenied
60
+ hipFileDriverAlreadyOpen = <int>_c.hipFileDriverAlreadyOpen
61
+ hipFileHandleNotRegistered = <int>_c.hipFileHandleNotRegistered
62
+ hipFileHandleAlreadyRegistered = <int>_c.hipFileHandleAlreadyRegistered
63
+ hipFileDeviceNotFound = <int>_c.hipFileDeviceNotFound
64
+ hipFileInternalError = <int>_c.hipFileInternalError
65
+ hipFileGetNewFDFailed = <int>_c.hipFileGetNewFDFailed
66
+ hipFileDriverSetupError = <int>_c.hipFileDriverSetupError
67
+ hipFileIODisabled = <int>_c.hipFileIODisabled
68
+ hipFileBatchSubmitFailed = <int>_c.hipFileBatchSubmitFailed
69
+ hipFileGPUMemoryPinningFailed = <int>_c.hipFileGPUMemoryPinningFailed
70
+ hipFileBatchFull = <int>_c.hipFileBatchFull
71
+ hipFileAsyncNotSupported = <int>_c.hipFileAsyncNotSupported
72
+ hipFileIOMaxError = <int>_c.hipFileIOMaxError
73
+
74
+ # hipFileFileHandleType_t
75
+ hipFileHandleTypeOpaqueFD = <int>_c.hipFileHandleTypeOpaqueFD
76
+ hipFileHandleTypeOpaqueWin32 = <int>_c.hipFileHandleTypeOpaqueWin32
77
+ hipFileHandleTypeUserspaceFS = <int>_c.hipFileHandleTypeUserspaceFS
78
+
79
+
80
+ # ---------------------------------------------------------------------------
81
+ # Internal helpers
82
+ # ---------------------------------------------------------------------------
83
+
84
+ cdef inline tuple _err(_c.hipFileError_t e):
85
+ return (<int>e.err, <int>e.hip_drv_err)
86
+
87
+
88
+ # ---------------------------------------------------------------------------
89
+ # Error-handling helpers (replacements for C macros)
90
+ # ---------------------------------------------------------------------------
91
+
92
+ def is_hipfile_err(int err_code):
93
+ """Equivalent of the ``IS_HIPFILE_ERR`` C macro."""
94
+ return abs(err_code) > _c.HIPFILE_BASE_ERR
95
+
96
+
97
+ def hipfile_errstr(int err_code):
98
+ """Equivalent of the ``HIPFILE_ERRSTR`` C macro."""
99
+ cdef const char *s = _c.hipFileGetOpErrorString(<_c.hipFileOpError_t>abs(err_code))
100
+ if s == NULL:
101
+ return ""
102
+ return s.decode("utf-8")
103
+
104
+
105
+ def is_hip_drv_err(tuple err):
106
+ """Equivalent of the ``IS_HIP_DRV_ERR`` C macro.
107
+
108
+ Takes an error tuple as returned by the wrapper functions.
109
+ """
110
+ return err[0] == <int>_c.hipFileHipDriverError
111
+
112
+
113
+ def hip_drv_err(tuple err):
114
+ """Equivalent of the ``HIP_DRV_ERR`` C macro.
115
+
116
+ Takes an error tuple and returns the ``hipError_t`` component.
117
+ """
118
+ return err[1]
119
+
120
+
121
+ def hipFileGetOpErrorString(int status):
122
+ """Wrapper for ``hipFileGetOpErrorString``."""
123
+ cdef const char *s = _c.hipFileGetOpErrorString(<_c.hipFileOpError_t>status)
124
+ if s == NULL:
125
+ return ""
126
+ return s.decode("utf-8")
127
+
128
+
129
+ # ---------------------------------------------------------------------------
130
+ # Driver lifecycle
131
+ # ---------------------------------------------------------------------------
132
+
133
+ def hipFileDriverOpen():
134
+ """Wrapper for ``hipFileDriverOpen``."""
135
+ return _err(_c.hipFileDriverOpen())
136
+
137
+
138
+ def hipFileDriverClose():
139
+ """Wrapper for ``hipFileDriverClose``."""
140
+ return _err(_c.hipFileDriverClose())
141
+
142
+
143
+ def hipFileUseCount():
144
+ """Wrapper for ``hipFileUseCount``."""
145
+ return <int>_c.hipFileUseCount()
146
+
147
+
148
+ # ---------------------------------------------------------------------------
149
+ # Version
150
+ # ---------------------------------------------------------------------------
151
+
152
+ def hipFileGetVersion():
153
+ """Wrapper for ``hipFileGetVersion``.
154
+
155
+ Returns ``((major, minor, patch), error_tuple)``.
156
+ """
157
+ cdef unsigned major = 0, minor = 0, patch = 0
158
+ cdef _c.hipFileError_t e = _c.hipFileGetVersion(&major, &minor, &patch)
159
+ return ((major, minor, patch), _err(e))
160
+
161
+
162
+ # ---------------------------------------------------------------------------
163
+ # File handles
164
+ # ---------------------------------------------------------------------------
165
+
166
+ def hipFileHandleRegister(uintptr_t handle_value, int handle_type):
167
+ """Wrapper for ``hipFileHandleRegister``.
168
+
169
+ Parameters
170
+ ----------
171
+ handle_value : int
172
+ POSIX file descriptor or Win32 HANDLE, depending on *handle_type*.
173
+ handle_type : int
174
+ Value from ``hipFileFileHandleType_t``.
175
+
176
+ Returns ``(handle_int, error_tuple)``. The handle is an opaque
177
+ integer that must be passed back to other hipFile calls.
178
+ """
179
+ cdef _c.hipFileHandle_t fh = NULL
180
+ cdef _c.hipFileDescr_t descr
181
+ memset(&descr, 0, sizeof(descr))
182
+ descr.type = <_c.hipFileFileHandleType_t>handle_type
183
+ if handle_type == <int>_c.hipFileHandleTypeOpaqueWin32:
184
+ descr.hFile = <void *>handle_value
185
+ else:
186
+ descr.fd = <int>handle_value
187
+ cdef _c.hipFileError_t e = _c.hipFileHandleRegister(&fh, &descr)
188
+ return (<uintptr_t>fh, _err(e))
189
+
190
+
191
+ def hipFileHandleDeregister(uintptr_t handle):
192
+ """Wrapper for ``hipFileHandleDeregister``."""
193
+ _c.hipFileHandleDeregister(<_c.hipFileHandle_t>handle)
194
+
195
+
196
+ # ---------------------------------------------------------------------------
197
+ # Buffer registration
198
+ # ---------------------------------------------------------------------------
199
+
200
+ def hipFileBufRegister(uintptr_t buffer_base, size_t length, int flags=0):
201
+ """Wrapper for ``hipFileBufRegister``."""
202
+ return _err(_c.hipFileBufRegister(<const void *>buffer_base, length, flags))
203
+
204
+
205
+ def hipFileBufDeregister(uintptr_t buffer_base):
206
+ """Wrapper for ``hipFileBufDeregister``."""
207
+ return _err(_c.hipFileBufDeregister(<const void *>buffer_base))
208
+
209
+
210
+ # ---------------------------------------------------------------------------
211
+ # Synchronous I/O
212
+ # ---------------------------------------------------------------------------
213
+
214
+ def hipFileRead(uintptr_t handle, uintptr_t buffer_base, size_t size,
215
+ _c.hoff_t file_offset, _c.hoff_t buffer_offset):
216
+ """Wrapper for ``hipFileRead``.
217
+
218
+ Returns ``(result, extra)``:
219
+ * ``result >= 0`` — number of bytes read, ``extra = 0``
220
+ * ``result == -1`` — system error, ``extra = errno``
221
+ * ``result < -1`` — negated ``hipFileOpError_t``; if
222
+ ``-hipFileHipDriverError``, ``extra = hipError_t`` from
223
+ ``hipPeekAtLastError()``, otherwise ``extra = 0``
224
+ """
225
+ cdef ssize_t ret = _c.hipFileRead(<_c.hipFileHandle_t>handle,
226
+ <void *>buffer_base, size,
227
+ file_offset, buffer_offset)
228
+ cdef int extra = 0
229
+ if ret == -1:
230
+ extra = errno
231
+ elif ret == -<int>_c.hipFileHipDriverError:
232
+ extra = <int>_c.hipPeekAtLastError()
233
+ return (ret, extra)
234
+
235
+
236
+ def hipFileWrite(uintptr_t handle, uintptr_t buffer_base, size_t size,
237
+ _c.hoff_t file_offset, _c.hoff_t buffer_offset):
238
+ """Wrapper for ``hipFileWrite``.
239
+
240
+ Returns ``(result, extra)``:
241
+ * ``result >= 0`` — number of bytes written, ``extra = 0``
242
+ * ``result == -1`` — system error, ``extra = errno``
243
+ * ``result < -1`` — negated ``hipFileOpError_t``; if
244
+ ``-hipFileHipDriverError``, ``extra = hipError_t`` from
245
+ ``hipPeekAtLastError()``, otherwise ``extra = 0``
246
+ """
247
+ cdef ssize_t ret = _c.hipFileWrite(<_c.hipFileHandle_t>handle,
248
+ <const void *>buffer_base, size,
249
+ file_offset, buffer_offset)
250
+ cdef int extra = 0
251
+ if ret == -1:
252
+ extra = errno
253
+ elif ret == -<int>_c.hipFileHipDriverError:
254
+ extra = <int>_c.hipPeekAtLastError()
255
+ return (ret, extra)
256
+
257
+
258
+ # ---------------------------------------------------------------------------
259
+ # Driver properties
260
+ # ---------------------------------------------------------------------------
261
+
262
+ def hipFileDriverGetProperties():
263
+ """Wrapper for ``hipFileDriverGetProperties``.
264
+
265
+ Returns ``(props_dict, error_tuple)``.
266
+ """
267
+ cdef _c.hipFileDriverProps_t props
268
+ memset(&props, 0, sizeof(props))
269
+ cdef _c.hipFileError_t e = _c.hipFileDriverGetProperties(&props)
270
+ d = {
271
+ "nvfs_major_version": props.nvfs_major_version,
272
+ "nvfs_minor_version": props.nvfs_minor_version,
273
+ "nvfs_poll_thresh_size": props.nvfs_poll_thresh_size,
274
+ "nvfs_max_direct_io_size": props.nvfs_max_direct_io_size,
275
+ "nvfs_driver_status_flags": props.nvfs_driver_status_flags,
276
+ "nvfs_driver_control_flags": props.nvfs_driver_control_flags,
277
+ "feature_flags": props.feature_flags,
278
+ "max_device_cache_size": props.max_device_cache_size,
279
+ "per_buffer_cache_size": props.per_buffer_cache_size,
280
+ "max_device_pinned_mem_size": props.max_device_pinned_mem_size,
281
+ "max_batch_io_count": props.max_batch_io_count,
282
+ "max_batch_io_timeout_msecs": props.max_batch_io_timeout_msecs,
283
+ }
284
+ return (d, _err(e))
@@ -0,0 +1,59 @@
1
+ # pylint: disable=C0114,C0115,C0116
2
+ from __future__ import annotations
3
+ from typing import TYPE_CHECKING
4
+ from sys import stderr
5
+
6
+ from hipfile._hipfile import ( # pylint: disable=E0401,E0611
7
+ hipFileBufDeregister,
8
+ hipFileBufRegister,
9
+ )
10
+ from hipfile.error import HipFileException
11
+
12
+ if TYPE_CHECKING:
13
+ from ctypes import c_void_p
14
+
15
+
16
+ class Buffer:
17
+
18
+ @classmethod
19
+ def from_ctypes_void_p(cls, ctypes_void_p: c_void_p, length, flags):
20
+ return cls(ctypes_void_p.value, length, flags)
21
+
22
+ def __init__(self, buffer_ptr, length, flags) -> None:
23
+ self._buffer_ptr = buffer_ptr
24
+ self._flags = flags
25
+ self._length = length
26
+ self._registered = False
27
+
28
+ def __del__(self):
29
+ # We did not create the underlying buffer. Don't try to free it.
30
+ try:
31
+ self.deregister()
32
+ except Exception: # pylint: disable=W0718 # Suppress exceptions in a dtor
33
+ print(
34
+ "Failed to deregister hipFile.Buffer at destruction time.", file=stderr
35
+ )
36
+
37
+ def __enter__(self):
38
+ self.register()
39
+ return self
40
+
41
+ def __exit__(self, exc_type, exc, tb):
42
+ self.deregister()
43
+
44
+ @property
45
+ def ptr(self):
46
+ return self._buffer_ptr
47
+
48
+ def deregister(self):
49
+ if self._registered:
50
+ err = hipFileBufDeregister(self._buffer_ptr)
51
+ if err[0] != 0:
52
+ raise HipFileException(err[0], err[1])
53
+ self._registered = False
54
+
55
+ def register(self):
56
+ err = hipFileBufRegister(self._buffer_ptr, self._length, self._flags)
57
+ if err[0] != 0:
58
+ raise HipFileException(err[0], err[1])
59
+ self._registered = True
@@ -0,0 +1,31 @@
1
+ # pylint: disable=C0114,C0115,C0116
2
+ from hipfile._hipfile import ( # pylint: disable=E0401,E0611
3
+ hipFileDriverOpen,
4
+ hipFileDriverClose,
5
+ hipFileUseCount,
6
+ )
7
+ from hipfile.error import HipFileException
8
+
9
+
10
+ class Driver:
11
+
12
+ @staticmethod
13
+ def use_count():
14
+ return hipFileUseCount()
15
+
16
+ def __enter__(self):
17
+ self.open()
18
+ return self
19
+
20
+ def __exit__(self, exc_type, exc_value, traceback):
21
+ self.close()
22
+
23
+ def close(self):
24
+ err = hipFileDriverClose()
25
+ if err[0] != 0:
26
+ raise HipFileException(err[0], err[1])
27
+
28
+ def open(self):
29
+ err = hipFileDriverOpen()
30
+ if err[0] != 0:
31
+ raise HipFileException(err[0], err[1])
@@ -0,0 +1,107 @@
1
+ # pylint: disable=C0114,C0115,C0116
2
+ from enum import IntEnum
3
+
4
+ from hipfile._hipfile import ( # pylint: disable=E0401,E0611
5
+ # hipFileOpError_t values (resolved from C at build time)
6
+ hipFileSuccess,
7
+ hipFileDriverNotInitialized,
8
+ hipFileDriverInvalidProps,
9
+ hipFileDriverUnsupportedLimit,
10
+ hipFileDriverVersionMismatch,
11
+ hipFileDriverVersionReadError,
12
+ hipFileDriverClosing,
13
+ hipFilePlatformNotSupported,
14
+ hipFileIONotSupported,
15
+ hipFileDeviceNotSupported,
16
+ hipFileDriverError,
17
+ hipFileHipDriverError,
18
+ hipFileHipPointerInvalid,
19
+ hipFileHipMemoryTypeInvalid,
20
+ hipFileHipPointerRangeError,
21
+ hipFileHipContextMismatch,
22
+ hipFileInvalidMappingSize,
23
+ hipFileInvalidMappingRange,
24
+ hipFileInvalidFileType,
25
+ hipFileInvalidFileOpenFlag,
26
+ hipFileDIONotSet,
27
+ hipFileInvalidValue,
28
+ hipFileMemoryAlreadyRegistered,
29
+ hipFileMemoryNotRegistered,
30
+ hipFilePermissionDenied,
31
+ hipFileDriverAlreadyOpen,
32
+ hipFileHandleNotRegistered,
33
+ hipFileHandleAlreadyRegistered,
34
+ hipFileDeviceNotFound,
35
+ hipFileInternalError,
36
+ hipFileGetNewFDFailed,
37
+ hipFileDriverSetupError,
38
+ hipFileIODisabled,
39
+ hipFileBatchSubmitFailed,
40
+ hipFileGPUMemoryPinningFailed,
41
+ hipFileBatchFull,
42
+ hipFileAsyncNotSupported,
43
+ hipFileIOMaxError,
44
+ # hipFileFileHandleType_t values (resolved from C at build time)
45
+ hipFileHandleTypeOpaqueFD,
46
+ hipFileHandleTypeOpaqueWin32,
47
+ hipFileHandleTypeUserspaceFS,
48
+ )
49
+
50
+
51
+ class OpError(IntEnum):
52
+ """Python enum mirroring hipFileOpError_t.
53
+
54
+ Values are sourced from the C enum via the Cython layer, not
55
+ redefined. Rebuilding the extension picks up any value changes
56
+ in hipfile.h automatically.
57
+ """
58
+
59
+ SUCCESS = hipFileSuccess
60
+ DRIVER_NOT_INITIALIZED = hipFileDriverNotInitialized
61
+ DRIVER_INVALID_PROPS = hipFileDriverInvalidProps
62
+ DRIVER_UNSUPPORTED_LIMIT = hipFileDriverUnsupportedLimit
63
+ DRIVER_VERSION_MISMATCH = hipFileDriverVersionMismatch
64
+ DRIVER_VERSION_READ_ERROR = hipFileDriverVersionReadError
65
+ DRIVER_CLOSING = hipFileDriverClosing
66
+ PLATFORM_NOT_SUPPORTED = hipFilePlatformNotSupported
67
+ IO_NOT_SUPPORTED = hipFileIONotSupported
68
+ DEVICE_NOT_SUPPORTED = hipFileDeviceNotSupported
69
+ DRIVER_ERROR = hipFileDriverError
70
+ HIP_DRIVER_ERROR = hipFileHipDriverError
71
+ HIP_POINTER_INVALID = hipFileHipPointerInvalid
72
+ HIP_MEMORY_TYPE_INVALID = hipFileHipMemoryTypeInvalid
73
+ HIP_POINTER_RANGE_ERROR = hipFileHipPointerRangeError
74
+ HIP_CONTEXT_MISMATCH = hipFileHipContextMismatch
75
+ INVALID_MAPPING_SIZE = hipFileInvalidMappingSize
76
+ INVALID_MAPPING_RANGE = hipFileInvalidMappingRange
77
+ INVALID_FILE_TYPE = hipFileInvalidFileType
78
+ INVALID_FILE_OPEN_FLAG = hipFileInvalidFileOpenFlag
79
+ DIO_NOT_SET = hipFileDIONotSet
80
+ INVALID_VALUE = hipFileInvalidValue
81
+ MEMORY_ALREADY_REGISTERED = hipFileMemoryAlreadyRegistered
82
+ MEMORY_NOT_REGISTERED = hipFileMemoryNotRegistered
83
+ PERMISSION_DENIED = hipFilePermissionDenied
84
+ DRIVER_ALREADY_OPEN = hipFileDriverAlreadyOpen
85
+ HANDLE_NOT_REGISTERED = hipFileHandleNotRegistered
86
+ HANDLE_ALREADY_REGISTERED = hipFileHandleAlreadyRegistered
87
+ DEVICE_NOT_FOUND = hipFileDeviceNotFound
88
+ INTERNAL_ERROR = hipFileInternalError
89
+ GET_NEW_FD_FAILED = hipFileGetNewFDFailed
90
+ DRIVER_SETUP_ERROR = hipFileDriverSetupError
91
+ IO_DISABLED = hipFileIODisabled
92
+ BATCH_SUBMIT_FAILED = hipFileBatchSubmitFailed
93
+ GPU_MEMORY_PINNING_FAILED = hipFileGPUMemoryPinningFailed
94
+ BATCH_FULL = hipFileBatchFull
95
+ ASYNC_NOT_SUPPORTED = hipFileAsyncNotSupported
96
+ IO_MAX_ERROR = hipFileIOMaxError
97
+
98
+
99
+ class FileHandleType(IntEnum):
100
+ """Python enum mirroring hipFileFileHandleType_t.
101
+
102
+ Values are sourced from the C enum via the Cython layer.
103
+ """
104
+
105
+ OPAQUE_FD = hipFileHandleTypeOpaqueFD
106
+ OPAQUE_WIN32 = hipFileHandleTypeOpaqueWin32
107
+ USERSPACE_FS = hipFileHandleTypeUserspaceFS
@@ -0,0 +1,23 @@
1
+ # pylint: disable=C0114,C0115,C0116
2
+ from hipfile._hipfile import hipFileGetOpErrorString # pylint: disable=E0401,E0611
3
+ from hipfile.enums import OpError
4
+
5
+
6
+ class HipFileException(Exception):
7
+ def __init__(self, hipfile_err, hip_err):
8
+ self._hipfile_err = hipfile_err
9
+ self._hip_err = hip_err
10
+
11
+ @property
12
+ def hipfile_err(self):
13
+ return self._hipfile_err
14
+
15
+ @property
16
+ def hip_err(self):
17
+ return self._hip_err
18
+
19
+ def __str__(self):
20
+ err_msg = f"{self._hipfile_err} - {hipFileGetOpErrorString(self._hipfile_err)}"
21
+ if self._hipfile_err == OpError.HIP_DRIVER_ERROR:
22
+ err_msg += f" {self._hip_err}"
23
+ return err_msg
@@ -0,0 +1,128 @@
1
+ # pylint: disable=C0114,C0115,C0116
2
+ import os
3
+ import stat
4
+ from sys import stderr
5
+
6
+ from hipfile._hipfile import ( # pylint: disable=E0401,E0611
7
+ hipFileHandleRegister,
8
+ hipFileHandleDeregister,
9
+ hipFileRead,
10
+ hipFileWrite,
11
+ )
12
+ from hipfile.enums import FileHandleType
13
+ from hipfile.error import HipFileException
14
+
15
+
16
+ class FileHandle:
17
+ DEFAULT_MODE = stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH
18
+
19
+ def __init__(
20
+ self, path, flags, mode=DEFAULT_MODE, handle_type=FileHandleType.OPAQUE_FD
21
+ ):
22
+ self._fd = None
23
+ self._flags = flags
24
+ self._handle = None
25
+ self._handle_type = None
26
+ self._mode = mode
27
+ self._path = path
28
+
29
+ self.handle_type = handle_type
30
+
31
+ def __del__(self):
32
+ try:
33
+ self.close()
34
+ except Exception: # pylint: disable=W0718 # Suppress exceptions in a dtor
35
+ print(
36
+ "Failed to deregister hipFile.FileHandle at destruction time.",
37
+ file=stderr,
38
+ )
39
+
40
+ def __enter__(self):
41
+ self.open()
42
+ return self
43
+
44
+ def __exit__(self, exc_type, exc_value, traceback):
45
+ self.close()
46
+
47
+ @property
48
+ def flags(self):
49
+ return self._flags
50
+
51
+ @property
52
+ def handle(self):
53
+ return self._handle
54
+
55
+ @property
56
+ def handle_type(self):
57
+ return self._handle_type
58
+
59
+ @handle_type.setter
60
+ def handle_type(self, _handle_type):
61
+ if self._handle is not None:
62
+ raise RuntimeError("Cannot modify handle_type while FileHandle is open")
63
+ if _handle_type not in FileHandleType:
64
+ raise ValueError(f"'{_handle_type}' is not a member of enum FileHandleType")
65
+ if _handle_type == FileHandleType.OPAQUE_WIN32:
66
+ raise NotImplementedError(
67
+ "FileHandle does not currently support Win32 Handles"
68
+ )
69
+ self._handle_type = _handle_type
70
+
71
+ @property
72
+ def mode(self):
73
+ return self._mode
74
+
75
+ @property
76
+ def path(self):
77
+ return self._path
78
+
79
+ def open(self):
80
+ if self._handle is not None:
81
+ raise RuntimeError("The FileHandle is already open.")
82
+ self._fd = os.open(self._path, self._flags, self._mode)
83
+ handle, err = hipFileHandleRegister(self._fd, self._handle_type)
84
+ if err[0] != 0:
85
+ os.close(self._fd)
86
+ self._fd = None
87
+ raise HipFileException(err[0], err[1])
88
+ self._handle = handle
89
+
90
+ def close(self):
91
+ if self._handle is not None:
92
+ hipFileHandleDeregister(self._handle)
93
+ self._handle = None
94
+ if self._fd is not None:
95
+ os.close(self._fd)
96
+ self._fd = None
97
+
98
+ def read(self, buffer, size, file_offset, buffer_offset):
99
+ if self._handle is None:
100
+ raise RuntimeError("The FileHandle is not open.")
101
+ bytes_read, extra_err = hipFileRead(
102
+ self._handle, buffer.ptr, size, file_offset, buffer_offset
103
+ )
104
+ if bytes_read == -1:
105
+ # extra_err is errno
106
+ raise OSError(extra_err, os.strerror(extra_err))
107
+ if bytes_read < -1:
108
+ # hipFile Error
109
+ # If -bytes_read == OpError.HIP_DRIVER_ERROR, extra_err is hipError_t.
110
+ # Otherwise, extra_err is 0.
111
+ raise HipFileException(-bytes_read, extra_err)
112
+ return bytes_read
113
+
114
+ def write(self, buffer, size, file_offset, buffer_offset):
115
+ if self._handle is None:
116
+ raise RuntimeError("The FileHandle is not open.")
117
+ bytes_written, extra_err = hipFileWrite(
118
+ self._handle, buffer.ptr, size, file_offset, buffer_offset
119
+ )
120
+ if bytes_written == -1:
121
+ # extra_err is errno
122
+ raise OSError(extra_err, os.strerror(extra_err))
123
+ if bytes_written < -1:
124
+ # hipFile Error
125
+ # If -bytes_written == OpError.HIP_DRIVER_ERROR, extra_err is hipError_t.
126
+ # Otherwise, extra_err is 0.
127
+ raise HipFileException(-bytes_written, extra_err)
128
+ return bytes_written
@@ -0,0 +1,41 @@
1
+ # pylint: disable=all
2
+ """
3
+ This is a hack to have some semblance of GPU memory management
4
+ without introducing a dependency at this early stage of
5
+ development. Do not rely upon anything in this module.
6
+ """
7
+
8
+ import ctypes
9
+ import sys
10
+
11
+ # Load the HIP runtime library
12
+ if sys.platform.startswith("linux"):
13
+ _hip_lib_name = "libamdhip64.so"
14
+ elif sys.platform == "win32":
15
+ _hip_lib_name = "amdhip64.dll"
16
+ else:
17
+ raise OSError("Unsupported platform for HIP runtime")
18
+
19
+ _hip = ctypes.CDLL(_hip_lib_name)
20
+
21
+ # hipError_t hipMalloc(void** ptr, size_t size);
22
+ _hip.hipMalloc.argtypes = [ctypes.POINTER(ctypes.c_void_p), ctypes.c_size_t]
23
+ _hip.hipMalloc.restype = ctypes.c_int
24
+
25
+ # hipError_t hipFree(void* ptr);
26
+ _hip.hipFree.argtypes = [ctypes.c_void_p]
27
+ _hip.hipFree.restype = ctypes.c_int
28
+
29
+
30
+ def hipMalloc(size_bytes: int) -> ctypes.c_void_p:
31
+ d_ptr = ctypes.c_void_p()
32
+ status = _hip.hipMalloc(ctypes.byref(d_ptr), ctypes.c_size_t(size_bytes))
33
+ if status != 0:
34
+ raise RuntimeError(f"hipMalloc failed ({status})")
35
+ return d_ptr
36
+
37
+
38
+ def hipFree(ptr: ctypes.c_void_p) -> None:
39
+ status = _hip.hipFree(ptr)
40
+ if status != 0:
41
+ raise RuntimeError(f"hipFree failed ({status})")
@@ -0,0 +1,20 @@
1
+ # pylint: disable=C0114,C0116
2
+ from hipfile._hipfile import ( # pylint: disable=E0401,E0611
3
+ hipFileDriverGetProperties,
4
+ hipFileGetVersion,
5
+ )
6
+ from hipfile.error import HipFileException
7
+
8
+
9
+ def driver_get_properties():
10
+ _props, err = hipFileDriverGetProperties()
11
+ if err[0] != 0:
12
+ raise HipFileException(err[0], err[1])
13
+ return _props
14
+
15
+
16
+ def get_version():
17
+ version_tuple, err = hipFileGetVersion()
18
+ if err[0] != 0:
19
+ raise HipFileException(err[0], err[1])
20
+ return version_tuple
@@ -0,0 +1,70 @@
1
+ """
2
+ A quick & rough script for testing the Cython bindings to the
3
+ hipFile C library. Reads a given file and copies it to an
4
+ output file, and then prints the hashes of the files.
5
+ """
6
+
7
+ import hashlib
8
+ import os
9
+ import pathlib
10
+
11
+ from hipfile.hipMalloc import hipFree, hipMalloc
12
+
13
+ from hipfile import (
14
+ Driver,
15
+ FileHandle,
16
+ Buffer,
17
+ FileHandleType,
18
+ get_version,
19
+ )
20
+
21
+ hipfile_version = get_version()
22
+
23
+ input_path = pathlib.Path("/mnt/ais/ext4/random_2MiB.bin")
24
+ output_path = pathlib.Path("/mnt/ais/ext4/output.bin")
25
+
26
+ print(f"hipFile Version: {hipfile_version}")
27
+ print(f"Driver Use Count Before: {Driver.use_count()}")
28
+
29
+ # Max to a 2GiB - 4KiB Buffer
30
+ # Note: Max IO in a single transaction is 2GiB - 4KiB as set by the Linux Kernel
31
+ # Larger IOs will be quietly truncated.
32
+ size = min(input_path.stat().st_size, 2 * 1024 * 1024 * 1024 - 4 * 1024)
33
+ buffer = hipMalloc(size)
34
+ buffer_ptr = buffer.value # pylint: disable=C0103 # False Positive
35
+ print(f"Buffer located at: {buffer_ptr} | {hex(buffer_ptr)}")
36
+
37
+ with Driver() as hipfile_driver:
38
+ print(f"Driver Use Count After: {hipfile_driver.use_count()}")
39
+ with Buffer.from_ctypes_void_p(buffer, size, 0) as registered_buffer:
40
+ with FileHandle(
41
+ input_path,
42
+ os.O_RDWR | os.O_DIRECT | os.O_CREAT,
43
+ handle_type=FileHandleType.OPAQUE_FD,
44
+ ) as fh_input:
45
+ with FileHandle(
46
+ output_path, os.O_RDWR | os.O_DIRECT | os.O_CREAT | os.O_TRUNC
47
+ ) as fh_output:
48
+ print(f"Transferring {size} bytes...")
49
+ bytes_read = fh_input.read(registered_buffer, size, 0, 0)
50
+ print(f"Bytes Read: {bytes_read}")
51
+ bytes_written = fh_output.write(registered_buffer, size, 0, 0)
52
+ print(f"Bytes Written: {bytes_written}")
53
+
54
+ hipFree(buffer)
55
+
56
+ with open(input_path, "br") as file_in:
57
+ hash_in = hashlib.sha256()
58
+ chunk = file_in.read(1 * 1024 * 1024) # 1 MiB
59
+ while len(chunk) != 0:
60
+ hash_in.update(chunk)
61
+ chunk = file_in.read(1 * 1024 * 1024) # 1 MiB
62
+ print(f"Input File Hash: {hash_in.hexdigest()}")
63
+
64
+ with open(output_path, "br") as file_out:
65
+ hash_out = hashlib.sha256()
66
+ chunk = file_out.read(1 * 1024 * 1024) # 1 MiB
67
+ while len(chunk) != 0:
68
+ hash_out.update(chunk)
69
+ chunk = file_out.read(1 * 1024 * 1024) # 1 MiB
70
+ print(f"Output File Hash: {hash_out.hexdigest()}")
@@ -0,0 +1,27 @@
1
+ [build-system]
2
+ requires = ["scikit-build-core>=0.10", "cython>=3.0"]
3
+ build-backend = "scikit_build_core.build"
4
+
5
+ [project]
6
+ name = "hipfile"
7
+ version = "0.2.0.dev1"
8
+ classifiers = [
9
+ "Development Status :: 3 - Alpha",
10
+ ]
11
+ description = "Python bindings for hipFile — direct-to-GPU file IO via AMD Infinity Storage (AIS)"
12
+ keywords = ["hipfile", "rocm", "amd", "hip", "AIS"]
13
+ license = { text = "MIT" }
14
+ maintainers = [
15
+ { name = "AMD hipFile Team", email = "hipfile-maintainer@amd.com" },
16
+ { name="Riley Dixon", email="riley.dixon@amd.com" }
17
+ ]
18
+ readme = "README.md"
19
+ requires-python = ">=3.10"
20
+
21
+ [project.urls]
22
+ Homepage = "https://github.com/ROCm/rocm-systems/tree/develop/projects/hipfile"
23
+ Changelog = "https://github.com/ROCm/rocm-systems/blob/develop/projects/hipfile/python/CHANGELOG.md"
24
+
25
+ [tool.scikit-build]
26
+ cmake.build-type = "Release"
27
+ wheel.packages = ["hipfile"]
@@ -1,17 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: hipfile
3
- Version: 0.0.1.dev0
4
- Summary: Placeholder for AMD ROCm hipFile
5
- Maintainer-email: Riley Dixon <riley.dixon@amd.com>, AMD hipFile Team <hipfile-maintainer@amd.com>
6
- License-Expression: MIT
7
- Project-URL: Homepage, https://github.com/ROCm/rocm-systems/tree/develop/projects/hipfile
8
- Keywords: hipfile,rocm,amd,hip,AIS
9
- Classifier: Development Status :: 3 - Alpha
10
- Requires-Python: >=3.8
11
- Description-Content-Type: text/markdown
12
-
13
- # hipfile
14
-
15
- Placeholder for AMD ROCm hipFile
16
-
17
- Uploaded using Twine.
@@ -1,5 +0,0 @@
1
- # hipfile
2
-
3
- Placeholder for AMD ROCm hipFile
4
-
5
- Uploaded using Twine.
@@ -1,22 +0,0 @@
1
- [build-system]
2
- requires = ["setuptools>=61.0", "wheel"]
3
- build-backend = "setuptools.build_meta"
4
-
5
- [project]
6
- name = "hipfile"
7
- version = "0.0.1.dev0"
8
- description = "Placeholder for AMD ROCm hipFile"
9
- readme = "README.md"
10
- requires-python = ">=3.8"
11
- keywords = ["hipfile", "rocm", "amd", "hip", "AIS"]
12
- classifiers = [
13
- "Development Status :: 3 - Alpha",
14
- ]
15
- license = "MIT"
16
- maintainers = [
17
- {name="Riley Dixon", email="riley.dixon@amd.com"},
18
- {name="AMD hipFile Team", email="hipfile-maintainer@amd.com"}
19
- ]
20
-
21
- [project.urls]
22
- Homepage = "https://github.com/ROCm/rocm-systems/tree/develop/projects/hipfile"
@@ -1,4 +0,0 @@
1
- [egg_info]
2
- tag_build =
3
- tag_date = 0
4
-
@@ -1,4 +0,0 @@
1
- __version__ = "0.0.1"
2
-
3
- def hello():
4
- return 'Hello from hipfile!'
@@ -1,17 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: hipfile
3
- Version: 0.0.1.dev0
4
- Summary: Placeholder for AMD ROCm hipFile
5
- Maintainer-email: Riley Dixon <riley.dixon@amd.com>, AMD hipFile Team <hipfile-maintainer@amd.com>
6
- License-Expression: MIT
7
- Project-URL: Homepage, https://github.com/ROCm/rocm-systems/tree/develop/projects/hipfile
8
- Keywords: hipfile,rocm,amd,hip,AIS
9
- Classifier: Development Status :: 3 - Alpha
10
- Requires-Python: >=3.8
11
- Description-Content-Type: text/markdown
12
-
13
- # hipfile
14
-
15
- Placeholder for AMD ROCm hipFile
16
-
17
- Uploaded using Twine.
@@ -1,7 +0,0 @@
1
- README.md
2
- pyproject.toml
3
- src/hipfile/__init__.py
4
- src/hipfile.egg-info/PKG-INFO
5
- src/hipfile.egg-info/SOURCES.txt
6
- src/hipfile.egg-info/dependency_links.txt
7
- src/hipfile.egg-info/top_level.txt
@@ -1 +0,0 @@
1
- hipfile