Skip to content

Commit a9eb595

Browse files
committed
Add copilot instructions
1 parent 22d1ec7 commit a9eb595

File tree

1 file changed

+196
-0
lines changed

1 file changed

+196
-0
lines changed

.github/copilot-instructions.md

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
# Copilot Instructions for OpenVINO Model Server (OVMS)
2+
3+
## Project Overview
4+
5+
OpenVINO Model Server (OVMS) is a high-performance inference serving platform built on top of **OpenVINO** and **OpenVINO GenAI**. The codebase is primarily **C++** with **Bazel** as the build system. Supporting infrastructure uses **Makefiles**, **Dockerfiles** (Ubuntu & Red Hat), and **batch files** (Windows).
6+
7+
**Performance is a top priority** — both **throughput** and **latency** are critical. Code changes should be evaluated for their performance impact. Avoid unnecessary copies, allocations, and blocking operations on the hot path.
8+
9+
## Repository Structure
10+
11+
- `src/` — Main C++ source code (server, gRPC/REST handlers, model management, pipelines, mediapipe, LLM, C API)
12+
- `src/test/` — C++ unit tests (gtest-based); this is where most developer tests live
13+
- `src/python/` — Python bindings and related code
14+
- `demos/` — End-user demo applications
15+
- `client/` — Client libraries (C++, Python, Go, Java)
16+
- `docs/` — Documentation
17+
- `third_party/` — Third-party dependency definitions for Bazel
18+
- `Dockerfile.ubuntu` / `Dockerfile.redhat` — Multi-stage Dockerfiles for Linux builds
19+
- `Makefile` — Orchestrates Docker-based builds and test runs
20+
- `*.bat` files — Windows build and setup scripts
21+
22+
## Build System
23+
24+
### Bazel (primary build tool)
25+
26+
Building and testing is done **inside a Docker `-build` container** with the repository mounted. Developers do not run Bazel on the host directly.
27+
28+
**Important:** Building the `-build` image from scratch is time-expensive, but may be required if dependencies or the build environment change. Before building a new one, check if one already exists:
29+
```bash
30+
docker images | grep -build
31+
```
32+
If a `-build` image exists, start a container from it with the repository mounted:
33+
```bash
34+
docker run -it -v $(pwd):/ovms \
35+
-e http_proxy=$http_proxy -e https_proxy=$https_proxy -e no_proxy=$no_proxy \
36+
<image_name> bash
37+
```
38+
If a container from a previous session is still available (`docker ps -a`), reuse it with `docker start -i <container>` or `docker exec -it <container> bash`.
39+
40+
**Key Bazel targets:**
41+
42+
| Target | Description |
43+
|--------|-------------|
44+
| `//src:ovms` | Main OVMS server binary |
45+
| `//src:ovms_test` | C++ unit tests (gtest) |
46+
| `//src:ovms_shared` | C API shared library (`libovms_shared.so`) |
47+
| `//src:capi_benchmark` | C API benchmark application |
48+
| `//src:capi_cpp_example` | C API C++ example |
49+
| `//src:release_custom_nodes` | Custom node plugins |
50+
| `//src/python/binding:test_python_binding` | Python binding tests |
51+
52+
**Build the server:**
53+
```bash
54+
bazel build //src:ovms
55+
```
56+
57+
**Build and run unit tests:**
58+
```bash
59+
bazel build //src:ovms_test
60+
bazel test --test_summary=detailed --test_output=streamed //src:ovms_test
61+
```
62+
63+
### Red Hat builds — distro flag
64+
65+
For Red Hat (UBI9) builds, the `--//:distro=redhat` flag must be passed to all Bazel commands:
66+
```bash
67+
bazel build --//:distro=redhat //src:ovms
68+
bazel test --//:distro=redhat //src:ovms_test
69+
```
70+
71+
The default distro is `ubuntu`. Inside the `-build` container, the distro is auto-detected from `/etc/redhat-release`.
72+
73+
### Makefile (Docker-based workflow)
74+
75+
The Makefile orchestrates full Docker-based builds. Key targets:
76+
77+
| Target | Description |
78+
|--------|-------------|
79+
| `make docker_build` | Full build: builder image → package → release images (default target) |
80+
| `make ovms_builder_image` | Build the `-build` Docker image (compilation container) |
81+
| `make targz_package` | Extract `.tar.gz` release package |
82+
| `make ovms_release_images` | Build CPU and GPU release Docker images |
83+
| `make run_unit_tests` | Run C++ unit tests in the `-build` container |
84+
| `make test_functional` | Run Python functional tests |
85+
| `make style` / `make cpplint` | Code style checks |
86+
87+
**Red Hat build via Make:**
88+
```bash
89+
make docker_build BASE_OS=redhat
90+
```
91+
92+
**Supported `BASE_OS` values:** `ubuntu24`, `ubuntu22`, `redhat`
93+
94+
### Dockerfile stages
95+
96+
Both `Dockerfile.ubuntu` and `Dockerfile.redhat` use multi-stage builds:
97+
98+
| Stage | Purpose |
99+
|-------|---------|
100+
| `base_build` | System dependencies, Boost, Azure SDK, OpenCV |
101+
| `build` | Bazel + OpenVINO setup, compiles OVMS (the `-build` container) |
102+
| `capi-build` | Builds C API shared library and examples |
103+
| `pkg` | Packages everything into a `.tar.gz` |
104+
| `release` | Minimal runtime image with entrypoint |
105+
106+
### Windows builds
107+
108+
Windows builds use batch files in the repository root:
109+
- `windows_install_build_dependencies.bat` — Install build dependencies (MSVC 2022 Build Tools, etc.)
110+
- `windows_build.bat` — Main build script
111+
- `windows_test.bat` — Run tests
112+
113+
Windows-specific Bazel config: `--config=win_mp_on_py_off` (or `--config=win_mp_on_py_on` for Python support).
114+
115+
## Testing
116+
117+
### Test setup
118+
119+
Before running tests, test models must be prepared:
120+
```bash
121+
make prepare_models
122+
```
123+
124+
Models are exported using the `demos/common/export_models/export_model.py` script (used internally by the test setup).
125+
126+
If LLM test models change (e.g., new model version, openvino version change or config update), you may need to remove and regenerate the LLM test data:
127+
```bash
128+
rm -rf src/test/llm_testing
129+
make prepare_models
130+
```
131+
132+
### Running tests
133+
134+
Running the full `//src:ovms_test` suite is **time-consuming**. During development, always run only the test fixtures relevant to your changes first using `--test_filter`:
135+
```bash
136+
bazel test --test_summary=detailed --test_output=streamed --test_filter="SuiteName.TestName" //src:ovms_test
137+
```
138+
Run the full test suite only after the targeted tests pass.
139+
140+
### Test structure
141+
142+
- **Unit tests** are in `src/test/` — gtest-based C++ tests covering all server components
143+
- Test files follow the `*_test.cpp` naming convention
144+
- Test utilities: `test_utils.hpp`, `light_test_utils.hpp`, `c_api_test_utils.hpp`
145+
- Test models are stored in `src/test/` subdirectories (e.g., `dummy/`, `passthrough/`, `summator/`)
146+
- Specialized test areas: `src/test/llm/`, `src/test/mediapipe/`, `src/test/python/`, `src/test/embeddings/`
147+
148+
## Code Style
149+
150+
- C++ style is enforced via `cpplint` and `clang-format`
151+
- Run `make style` to check formatting
152+
- Apache 2.0 license headers are required on all source files
153+
154+
## Expertise Areas
155+
156+
1. **OpenVINO Expertise:**
157+
- Proficient with OpenVINO core libraries and `ov::genai` components
158+
- Familiar with OpenVINO performance optimization techniques
159+
2. **C++ Proficiency:**
160+
- Strong C++17 skills
161+
- Familiar with best practices in memory management, concurrency, and template programming
162+
3. **Serving Infrastructure:**
163+
- gRPC and REST API handler design
164+
- Model management, pipeline orchestration, and MediaPipe integration
165+
- C API (`libovms_shared.so`) surface and bindings
166+
4. **Build System Awareness:**
167+
- Bazel build configuration and dependency management
168+
- Minimizing C++ build times: forward declarations, include-what-you-use, avoiding transitive header leakage
169+
- Understanding of Bazel targets, build flags (`--//:distro`), and multi-stage Docker builds
170+
171+
## Code Review Instructions for PRs
172+
173+
When analyzing a Pull Request, follow this protocol:
174+
175+
1. Follow **C++ Core Guidelines** strictly. Include references in review comments.
176+
2. Check for **hidden performance costs**: avoid `dynamic_cast` on the hot path; suggest `static_cast` or redesign if the type is known.
177+
3. **Avoid copies**: ensure large data structures (tensors, buffers) are passed by reference or moved, not copied.
178+
4. **Python bindings**: if C++ APIs change, check whether the corresponding pybind11 wrappers in `src/python/` need updates.
179+
5. **Assertions**: use project assertion macros for checks instead of `if` + `throw` where applicable.
180+
6. **Documentation**: ensure new public APIs have docstrings in C++ headers and Python bindings; update `docs/` as needed.
181+
7. **Test coverage**: ensure that new features or changes have corresponding tests in `src/test/`.
182+
8. **Formatting & safety:**
183+
- No `using namespace std; using namespace ov;`. Prefer explicit using with specific symbols if needed, for readability.
184+
- No `auto` for primitive types where it obscures readability.
185+
- Use `const` and `constexpr` wherever possible.
186+
9. Pass non-fundamental values by `const` reference wherever possible.
187+
10. Prefer member initializer lists over direct assignments in constructor bodies.
188+
11. Verify that the result of every newly introduced function is used in at least one call site (except `void` functions).
189+
12. Use descriptive function and variable names. Avoid duplicate code — extract common functionality into reusable utilities.
190+
13. When initial container values are known upfront, prefer initializer-list / brace-initialization over constructing an empty container and inserting.
191+
14. Unused functions and includes are not allowed. Build times are already long — do not add unnecessary `#include` directives. Prefer forward declarations where possible and follow the include-what-you-use principle.
192+
- **Forward-declare in headers, include in `.cpp`**: if a header only uses pointers or references to a type, use a forward declaration (`class Foo;`) instead of `#include "foo.hpp"`. Move the full `#include` to the `.cpp` file where the type is actually used.
193+
- **Keep headers self-contained but minimal**: each header must compile on its own, but should not pull in transitive dependencies that callers don't need.
194+
- **Prefer opaque types / Pimpl**: for complex implementation details, consider the Pimpl idiom to keep implementation-only types out of the public header entirely.
195+
- **Never include a header solely for a typedef or enum**: forward-declare the enum (`enum class Foo;` in C++17) or relocate the typedef to a lightweight `fwd.hpp`-style header.
196+
15. Be mindful when accepting `const T&` in constructors or functions that store the reference: verify that the referenced object's lifetime outlaps the usage to avoid dangling references.

0 commit comments

Comments
 (0)