Skip to content

Commit 3cee4a5

Browse files
authored
Merge pull request #1527 from lukaszstolarczuk/support-versioning-zip
Support versioning in git archives
2 parents b7c37b0 + b9c94bb commit 3cee4a5

File tree

4 files changed

+157
-7
lines changed

4 files changed

+157
-7
lines changed

.github/copilot-instructions.md

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
# UMF (Unified Memory Framework) - AI Coding Guide
2+
3+
## Project Architecture
4+
5+
UMF is a C library for constructing memory allocators and pools, built around a two-layer architecture:
6+
7+
- **Memory Providers** (`src/provider/`): Handle coarse-grained OS-level memory allocation (mmap, CUDA, Level Zero, etc.)
8+
- **Memory Pools** (`src/pool/`): Handle fine-grained allocation using providers as backing store (jemalloc, scalable, disjoint)
9+
10+
Key architectural patterns:
11+
- Provider/pool separation enables mixing any provider with any pool allocator
12+
- Operations structures (`*_ops_t`) define plugin interfaces for extensibility
13+
- Handle-based API (`*_handle_t`) abstracts implementation details
14+
- Result codes (`umf_result_t`) for consistent error handling
15+
16+
## Development Workflows
17+
18+
### Build System
19+
```bash
20+
# Standard build
21+
cmake -B build -DCMAKE_BUILD_TYPE=Release
22+
cmake --build build -j $(nproc)
23+
24+
# Enable all features for development
25+
# GPU tests will work only in an environment with proper hardware and drivers
26+
cmake -B build -DCMAKE_BUILD_TYPE=Debug \
27+
-DUMF_BUILD_TESTS=ON -DUMF_BUILD_GPU_TESTS=OFF \
28+
-DUMF_BUILD_EXAMPLES=ON -DUMF_DEVELOPER_MODE=ON \
29+
-DUMF_FORMAT_CODE_STYLE=ON
30+
```
31+
32+
### Version Management
33+
- Version determined by:
34+
1. `git describe` (preferred)
35+
2. `VERSION` file fallback
36+
3. "0.0.0" default
37+
- `set_version_variables()` in `cmake/helpers.cmake` handles version detection
38+
- For releases: create `VERSION` file with semver format (e.g., "1.0.3")
39+
40+
### Code Formatting
41+
- **Always format code before committing**: `make format-apply`
42+
- Requires build with `-DUMF_FORMAT_CODE_STYLE=ON`
43+
- Uses clang-format-15.0, cmake-format-0.6, and black for Python
44+
45+
### Testing Patterns
46+
- Use `build_umf_test()` CMake function in `test/CMakeLists.txt`
47+
- GPU tests require `UMF_BUILD_GPU_TESTS=ON` and hardware/drivers
48+
- IPC tests use producer/consumer pattern with shell scripts
49+
- Platform-specific tests: `.c` files for portability, `.cpp` for C++ features, utils, and selected tests
50+
51+
### CI/CD Structure
52+
- `pr_push.yml`: Main workflow calling reusable workflows. It's called for each PR change or push to main/stable branches
53+
- Separate workflows for different configurations: `reusable_gpu.yml`, `reusable_sanitizers.yml`, etc.
54+
- Provider-specific testing: Level Zero, CUDA runners with actual hardware
55+
56+
## Coding Conventions
57+
58+
### Naming Patterns
59+
- Public API: `umf*` prefix (e.g., `umfMemoryProviderCreate`)
60+
- Internal functions: `snake_case` without prefix
61+
- Structures: `*_t` suffix for types, `*_handle_t` for opaque handles
62+
- Constants: `UMF_*` uppercase with underscores
63+
64+
### Memory Management Patterns
65+
- Always pair create/destroy functions (e.g., `umfMemoryProviderCreate`/`umfMemoryProviderDestroy`)
66+
- Use `umf_result_t` return codes, never throw exceptions
67+
- Provider params have separate create/destroy lifecycle
68+
- Thread-local storage (`__TLS`) for error state in providers
69+
70+
### Provider Implementation Pattern
71+
```c
72+
// Standard provider structure
73+
typedef struct my_provider_t {
74+
// Provider-specific state
75+
} my_provider_t;
76+
77+
static umf_result_t my_initialize(const void *params, void **provider);
78+
static umf_result_t my_finalize(void *provider);
79+
static umf_result_t my_alloc(void *provider, size_t size, size_t alignment, void **ptr);
80+
static umf_result_t my_free(void *provider, void *ptr, size_t size);
81+
82+
static const umf_memory_provider_ops_t MY_PROVIDER_OPS = {
83+
.version = UMF_PROVIDER_OPS_VERSION_CURRENT,
84+
.initialize = my_initialize,
85+
.finalize = my_finalize,
86+
.alloc = my_alloc,
87+
.free = my_free,
88+
// ... other required ops
89+
};
90+
```
91+
92+
## Key Files and Patterns
93+
94+
### Core APIs
95+
- `include/umf.h`: Main header, include this for basic usage
96+
- `include/umf/memory_provider_ops.h`: Provider plugin interface
97+
- `include/umf/memory_pool_ops.h`: Pool plugin interface
98+
99+
### Common Utilities
100+
- `src/utils/`: Logging (`utils_log.h`), concurrency (`utils_concurrency.h`), assertions
101+
- `src/critnib/`: Concurrent radix tree for address tracking
102+
- `src/base_alloc/`: Base allocation utilities
103+
104+
### Platform Abstractions
105+
- `libumf_linux.c`/`libumf_windows.c`: OS-specific implementations
106+
- `topology.c`: HWLOC integration for NUMA topology discovery
107+
- Provider files handle platform-specific allocation (CUDA, Level Zero, OS memory)
108+
109+
## Integration Points
110+
111+
### NUMA Support
112+
- Uses HWLOC for topology discovery (`topology.c`, `umf_hwloc.h`)
113+
- NUMA policies in `mempolicy.c`: bind, interleave, split modes
114+
- Memory spaces (`memspace.c`) and targets (`memtarget.c`) for NUMA abstraction
115+
116+
### GPU Integration
117+
- Level Zero provider: `provider_level_zero.c` for Intel GPUs
118+
- CUDA provider: `provider_cuda.c` for NVIDIA GPUs
119+
- Examples in `examples/level_zero_shared_memory/` and `examples/cuda_shared_memory/`
120+
121+
### IPC (Inter-Process Communication)
122+
- Linux-specific implementation using file descriptor passing
123+
- Requires `PTRACE_MODE_ATTACH_REALCREDS` permission
124+
- Uses `memfd_create()` or `memfd_secret()` for anonymous shared memory
125+
126+
When implementing new providers or pools, follow the existing patterns in
127+
`src/provider/provider_os_memory.c` and `src/pool/pool_scalable.c` as reference implementations.

CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ if(UMF_CMAKE_VERSION VERSION_EQUAL "0.0.0")
3232
message(
3333
WARNING
3434
"UMF version is set to 0.0.0, which most likely is not expected! "
35-
"Please checkout the git tags to get a proper version.")
35+
"Please install git and checkout the git tags to get a proper version."
36+
)
3637
endif()
3738

3839
if(PROJECT_VERSION_PATCH GREATER 0)

RELEASE_STEPS.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,11 @@ Prepare changes for the release:
5050
- Once all changes are done, build locally (and/or verify changes on CI), including:
5151
- Verify if scanners/linters/checkers passed
5252
- Verify if version is set properly, especially in `.dll` and `.so` files
53+
- Create/update a VERSION file for GitHub ZIP downloads (users without git):
54+
- `echo "$VERSION" > VERSION`
55+
- It will always contain "the last released version". In logs/CMake build it will introduce itself as `$VERSION-dev`, only if git is not available
5356
- Commit these changes and tag the release:
57+
- `git add VERSION`
5458
- `git commit -a -S -m "$VERSION release"`
5559
- `git tag -a -s -m "Version $VERSION" v$VERSION`
5660
- Verify if commit and tag are properly signed:

cmake/helpers.cmake

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@ include(CheckCCompilerFlag)
1111
include(CheckCXXCompilerFlag)
1212

1313
# This function establishes version variables based on the git describe output.
14-
# If there's no git available in the system, the version will be set to "0.0.0".
15-
# If git reports only a hash, the version will be set to "0.0.0.git.<hash>".
16-
# Otherwise we'll use 3-component version: major.minor.patch, just for CMake's
17-
# sake. A few extra variables will be set for Win dll metadata.
14+
# If there's no git available in the system, it falls back to reading a VERSION
15+
# file from the project root. If neither git nor VERSION file is available, the
16+
# version will be set to "0.0.0". If git reports only a hash, the version will
17+
# be set to "0.0.0.git.<hash>". Otherwise we'll use 3-component version:
18+
# major.minor.patch, just for CMake's sake. A few extra variables will be set
19+
# for Win dll metadata.
1820
#
1921
# Important note: CMake does not support rc or git information. According to
2022
# semver rules, 1.5.1-rc1 should be less than 1.5.1, but it seems hard to
@@ -78,8 +80,24 @@ function(set_version_variables)
7880
OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET)
7981

8082
if(NOT GIT_VERSION)
81-
# no git or it reported no version. Use default ver: "0.0.0"
82-
return()
83+
# no git or it reported no version. Try fallback to VERSION file
84+
if(EXISTS "${UMF_CMAKE_SOURCE_DIR}/VERSION")
85+
file(READ "${UMF_CMAKE_SOURCE_DIR}/VERSION" FILE_VERSION)
86+
string(STRIP ${FILE_VERSION} FILE_VERSION)
87+
if(FILE_VERSION)
88+
set(GIT_VERSION "v${FILE_VERSION}-dev")
89+
message(
90+
STATUS
91+
"Using version from VERSION file: ${FILE_VERSION}. To get detailed version, use git and fetch tags."
92+
)
93+
else()
94+
# VERSION file exists but is empty, use default ver: "0.0.0"
95+
return()
96+
endif()
97+
else()
98+
# no git and no VERSION file. Use default ver: "0.0.0"
99+
return()
100+
endif()
83101
endif()
84102

85103
# v1.5.0 - we're exactly on a tag -> UMF ver: "1.5.0"

0 commit comments

Comments
 (0)