Skip to content

Commit 22a3d74

Browse files
authored
cleanup readme
Cleanup docs and logging
2 parents 891ef7d + 863c08c commit 22a3d74

6 files changed

Lines changed: 20 additions & 26 deletions

File tree

README.md

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# numba cfunc compiler
22

3-
Generic, framework-agnostic infrastructure for compiling Python functions to Numba @cfunc via AST transformation
3+
Extensible compiler for producing native C-callable functions from Python source with stateful variables, typed containers, and pluggable type systems built on Numba @cfunc
44

55
[![Build Status](https://github.com/Point72/numba-cfunc-compiler/actions/workflows/build.yaml/badge.svg?branch=main&event=push)](https://github.com/Point72/numba-cfunc-compiler/actions/workflows/build.yaml)
66
[![codecov](https://codecov.io/gh/Point72/numba-cfunc-compiler/branch/main/graph/badge.svg)](https://codecov.io/gh/Point72/numba-cfunc-compiler)
@@ -9,15 +9,14 @@ Generic, framework-agnostic infrastructure for compiling Python functions to Num
99

1010
## Overview
1111

12-
Generic, framework-agnostic infrastructure for compiling Python functions to Numba `@cfunc` via AST transformation. All domain-specific behavior is injected through registration APIs.
12+
A compilation framework that transforms Python functions into native C-callable functions using Numba `@cfunc` and AST rewriting. Unlike using `@cfunc` directly, it provides:
1313

14-
The distribution is published as `numba-cfunc-compiler` and imported in Python as `numba_cfunc_compiler`.
15-
16-
This package is intended for applications that need to:
14+
- **Stateful variables** — declare persistent state with natural syntax that survives across calls with automatic lifecycle management (start/execute/stop)
15+
- **Standalone typed containers** — lists and dicts that work inside compiled functions without Numba's runtime overhead
16+
- **Extensible type resolution** — register custom types that map Python syntax to numba-compatible lowering
17+
- **Plugin architecture** — all domain-specific behavior (input handlers, output handlers, AST transforms, type inference) is injected through registration APIs
1718

18-
- transform Python functions into fixed-signature Numba entry points
19-
- inject domain-specific typing, AST lowering, and runtime behavior through registrations
20-
- ship a small native runtime alongside the Python package
19+
The distribution is published as `numba-cfunc-compiler` and imported in Python as `numba_cfunc_compiler`.
2120

2221
## Installation
2322

@@ -301,8 +300,8 @@ Registered by `defaults.register_all()`:
301300
- **Primitives**`int` (int64), `float` (float64), `bool` (int8). Support `State[int]`, etc.
302301
- **DateTime** — Stored as nanoseconds (int64). Constructor calls like `datetime(2020,1,1,tzinfo=timezone.utc)` are lowered to constants at compile time. Must be timezone-aware.
303302
- **TimeDelta** — Stored as nanoseconds (int64). `timedelta(seconds=5)` lowered to constants.
304-
- **NumbaList**NRT-free typed list (`int`/`float`/`bool` elements). Supports `len`, indexing, `append`, `pop`, `clear`, iteration. Created with `create_new_list(int)`.
305-
- **NumbaDict**NRT-free typed dict (`int` keys, `int`/`float`/`bool` values). Supports `len`, `[]`, `in`/`not in`, `get`, `pop`, `clear`, `items()`, `keys()`. Created with `create_new_dict(int, float)`.
303+
- **NumbaList**Standalone typed list (`int`/`float`/`bool` elements). Supports `len`, indexing, `append`, `pop`, `clear`, iteration. Created with `create_new_list(int)`.
304+
- **NumbaDict**Standalone typed dict (`int` keys, `int`/`float`/`bool` values). Supports `len`, `[]`, `in`/`not in`, `get`, `pop`, `clear`, `items()`, `keys()`. Created with `create_new_dict(int, float)`.
306305
- **Structs** — Opaque void pointers with field metadata. Read/write fields via pointer arithmetic. Base `StructType` must be subclassed with `is_type_supported()`, `_get_struct_fields()`, `_get_struct_size()`.
307306

308307
## Compilation Options & Post-Compilation Transforms
@@ -323,7 +322,7 @@ result = create_compiled_func(func, *args, options=opts, ...)
323322

324323
**`fastmath`** *(compilation)* — Passes `fastmath=True` to the Numba `@cfunc` decorator, enabling aggressive floating-point optimizations (reassociation, no-NaN, etc.).
325324

326-
**`force_inline`** *(post-compilation)* — Replaces Numba's `noinline` attribute on the cfunc wrapper → native call with `alwaysinline`, letting the LLVM optimizer merge them. Safe with `error_model='numpy'` and `_nrt=False`.
325+
**`force_inline`** *(post-compilation)* — Replaces Numba's `noinline` attribute on the cfunc wrapper with `alwaysinline`, letting the LLVM optimizer inline the function body into the wrapper and eliminate the extra call.
327326

328327
Regardless of options, the exported wrapper symbol is renamed to `_gc_numba_<semantic_key>`. `result.native_name`, `result.semantic_key`, and `result.llvm_ir` all reflect that final compiled form.
329328

@@ -405,6 +404,6 @@ def compiled_func(outputs, output_ticked, state, lifecycle_phase, ...):
405404
...
406405
```
407406

408-
### NRT-free Containers
407+
### Standalone Containers
409408

410409
`NumbaList` and `NumbaDict` use standalone C implementations (`numba_rt/_py_nrt_init.so`) instead of Numba's reference-counted runtime. Memory is owned by the host framework via state slots. The C library is loaded lazily on first compilation via `CompilationContext.ensure_nrt_loaded()`.

numba_cfunc_compiler/defaults/struct_support.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ def register():
241241
242242
Note: Base StructType returns False for is_type_supported(), so it won't
243243
match any types by default. Client code should register their own StructType
244-
subclasses (e.g., CspStructType) for struct support.
244+
subclasses for struct support.
245245
"""
246246
from numba_cfunc_compiler.numba_type_inference import NumbaTypeInference
247247

numba_cfunc_compiler/numba_core.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
import hashlib
33
import inspect
44
import json
5-
import logging
65
from dataclasses import dataclass
76
from typing import Any, Callable, List, Optional
87

@@ -78,9 +77,6 @@ def __getattr__(self, name: str) -> Any:
7877
raise AttributeError(f"'{type(self).__name__}' has no attribute '{name}'")
7978

8079

81-
logger = logging.getLogger("graph_compute")
82-
83-
8480
def _build_semantic_key(
8581
new_func_code: str,
8682
cfunc_sig: str,
@@ -231,7 +227,6 @@ def create_compiled_func(
231227
)
232228
new_tree = transformer.visit(tree)
233229
new_func_code = ast.unparse(new_tree)
234-
logger.debug(f"generated code for {name}:\n{new_func_code}")
235230

236231
cfunc_sig = SourceRegistry.build_cfunc_signature()
237232
cfunc_kwargs = "nopython=True, nogil=True, _nrt=False, error_model='numpy'"

numba_cfunc_compiler/post_compilation.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"link_ffi_bitcode",
1010
]
1111

12-
logger = logging.getLogger("graph_compute")
12+
log = logging.getLogger("numba_cfunc_compiler")
1313

1414

1515
@dataclass(frozen=True)
@@ -108,6 +108,6 @@ def link_ffi_bitcode(module: Any, bitcode: bytes) -> Any:
108108
module.verify()
109109

110110
except Exception as e:
111-
logger.warning(f"Failed to link FFI bitcode for inlining (falling back to external calls): {e}")
111+
log.warning(f"Failed to link FFI bitcode for inlining (falling back to external calls): {e}")
112112

113113
return module

numba_cfunc_compiler/utils/ast.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,14 @@
1717
"AST",
1818
]
1919

20-
logger = logging.getLogger("graph_compute")
20+
log = logging.getLogger("numba_cfunc_compiler")
2121

2222

2323
def print_ast(value) -> None:
2424
ast.fix_missing_locations(value)
2525
tree = ast.parse(value)
2626
src = ast.unparse(tree)
27-
logger.info(src)
27+
log.info(src)
2828

2929

3030
def add_statement_to_list(node_list: List[ast.stmt], node: Union[ast.stmt, List[ast.stmt], None]) -> None:

numba_cfunc_compiler/variable_factory.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ def read(self):
130130
# ContainerType handles its own read logic (e.g. list/dict from voidptr)
131131
if isinstance(self.type, ContainerType):
132132
return self.type.read(self.local_variable_name(), self.name, loaded_value)
133-
# Allow types to prepare themselves before reading (e.g., OrderBookType loads from book_ptrs)
133+
# Allow types to prepare themselves before reading
134134
self.type = self.type.prepare_voidptr_read(self)
135135
value = AST.cast_from_voidptr(loaded_value, self.type.get_numba_type_name())
136136
return AST.assignment(self.local_variable_name(), value)
@@ -158,7 +158,7 @@ def __init__(self, array_idx: int, type: VariableType, name: str):
158158
def local_variable_name(self):
159159
return f"output_{self.array_idx}_ptr"
160160

161-
def write(self, value: any):
161+
def write(self, value: Any):
162162
"""
163163
Create: output_(output_idx)_ptr[0] = value
164164
"""
@@ -205,7 +205,7 @@ def get(self):
205205
class LocalConstantSource(VariableSource):
206206
"""Local constants created inside the node (mainly used when returning a constant value)"""
207207

208-
def __init__(self, type: VariableType, name: str, var_value: any):
208+
def __init__(self, type: VariableType, name: str, var_value: Any):
209209
super().__init__(type, name)
210210
self.var_value = var_value
211211

@@ -321,7 +321,7 @@ def _visit_and_create_temp_var(self, visitor, ast_node, statements: List[ast.stm
321321
self.add_variable(var)
322322
return var
323323

324-
def _get_static_key(self, key_node) -> any:
324+
def _get_static_key(self, key_node) -> Any:
325325
"""Extract a static key value from an AST node, or return None if dynamic."""
326326
if isinstance(key_node, ast.Constant):
327327
return key_node.value

0 commit comments

Comments
 (0)