0
# Low-level LibJulia API
1
2
Direct access to Julia's C API for advanced users who need fine-grained control over the Julia runtime, memory management, and performance-critical operations. This provides the foundation for the high-level PyJulia interface.
3
4
## Capabilities
5
6
### LibJulia Interface Classes
7
8
Core classes providing direct access to Julia's C API functionality.
9
10
```python { .api }
11
class LibJulia:
12
"""Low-level interface to libjulia C-API."""
13
14
def __init__(self, **kwargs):
15
"""
16
Initialize LibJulia instance.
17
18
Parameters:
19
- julia: Path to Julia executable
20
- sysimage: Path to Julia system image
21
- Various other Julia runtime options
22
"""
23
24
class BaseLibJulia:
25
"""Base class for LibJulia implementations."""
26
27
class InProcessLibJulia(BaseLibJulia):
28
"""LibJulia implementation for in-process Julia instances."""
29
```
30
31
### LibJulia Global Management
32
33
Functions for managing the global LibJulia instance used throughout PyJulia.
34
35
```python { .api }
36
def get_libjulia():
37
"""Get the currently active global libjulia instance."""
38
39
def set_libjulia(libjulia):
40
"""
41
Set the global libjulia instance.
42
43
Parameters:
44
- libjulia: LibJulia instance to set as global
45
"""
46
47
def get_inprocess_libjulia(**kwargs):
48
"""
49
Get in-process libjulia instance with options.
50
51
Parameters:
52
- **kwargs: Julia runtime configuration options
53
54
Returns:
55
- InProcessLibJulia instance
56
"""
57
```
58
59
### LibJulia Setup and Configuration
60
61
Configure the ctypes interfaces and function signatures for libjulia.
62
63
```python { .api }
64
def setup_libjulia(libjulia):
65
"""
66
Configure libjulia ctypes interfaces and function signatures.
67
68
Parameters:
69
- libjulia: LibJulia instance to configure
70
"""
71
```
72
73
### Julia Runtime Information
74
75
Access detailed information about the Julia runtime and configuration.
76
77
```python { .api }
78
class JuliaInfo:
79
"""Container for information required to initialize Julia runtime."""
80
81
def __init__(self, **kwargs):
82
"""
83
Initialize with Julia runtime configuration.
84
85
Contains information about:
86
- Julia executable path
87
- System image location
88
- Library paths
89
- Version information
90
- Compilation settings
91
"""
92
93
def is_compatible_exe(jl_libpython: str) -> bool:
94
"""
95
Check if Julia executable is compatible with current Python.
96
97
Parameters:
98
- jl_libpython: Path to Julia's libpython
99
100
Returns:
101
- True if compatible, False otherwise
102
"""
103
```
104
105
### LibPython Discovery
106
107
Find and validate libpython library paths for Julia integration.
108
109
```python { .api }
110
def find_libpython():
111
"""
112
Find all possible libpython library candidates.
113
114
Returns:
115
- List of potential libpython library paths
116
"""
117
118
def linked_libpython():
119
"""
120
Find path to currently linked libpython library.
121
122
Returns:
123
- Path to linked libpython or None
124
"""
125
126
def library_name(name: str, suffix: str = None, is_windows: bool = None) -> str:
127
"""
128
Generate platform-specific library name.
129
130
Parameters:
131
- name: Base library name
132
- suffix: Platform-specific suffix (.so, .dll, .dylib)
133
- is_windows: Override Windows detection
134
135
Returns:
136
- Platform-appropriate library filename
137
"""
138
139
def candidate_names(suffix: str = None) -> list:
140
"""Get candidate libpython library names."""
141
142
def candidate_paths(suffix: str = None) -> list:
143
"""Get candidate libpython library paths."""
144
145
def finding_libpython():
146
"""Generator yielding all libpython candidates."""
147
```
148
149
### Memory Management and Type Conversion
150
151
Low-level utilities for working with Julia values and memory management.
152
153
```python { .api }
154
# Supported C types for unboxing Julia values to Python
155
UNBOXABLE_TYPES = (
156
'bool', 'int8', 'uint8', 'int16', 'uint16',
157
'int32', 'uint32', 'int64', 'uint64',
158
'float32', 'float64'
159
)
160
```
161
162
### Platform Detection
163
164
Constants for platform-specific behavior and library handling.
165
166
```python { .api }
167
# Platform detection constants
168
is_linux: bool # True if running on Linux
169
is_windows: bool # True if running on Windows
170
is_apple: bool # True if running on macOS
171
172
# Platform-specific shared library suffix
173
SHLIB_SUFFIX: str # '.so' on Linux, '.dll' on Windows, '.dylib' on macOS
174
```
175
176
### Low-level Execution Utilities
177
178
Platform-specific program execution utilities.
179
180
```python { .api }
181
def execprog(cmd: list):
182
"""
183
Execute program with platform-specific implementation.
184
185
Parameters:
186
- cmd: Command and arguments as list
187
"""
188
```
189
190
## Usage Examples
191
192
### Basic LibJulia Setup
193
194
```python
195
from julia.libjulia import get_inprocess_libjulia, setup_libjulia
196
197
# Get a configured LibJulia instance
198
libjulia = get_inprocess_libjulia(
199
sysimage="/path/to/custom.so",
200
threads=4
201
)
202
203
# Set it as the global instance
204
from julia.libjulia import set_libjulia
205
set_libjulia(libjulia)
206
207
# Setup ctypes interfaces
208
setup_libjulia(libjulia)
209
```
210
211
### Direct C API Access
212
213
```python
214
from julia.libjulia import get_libjulia
215
216
# Get the current LibJulia instance
217
libjulia = get_libjulia()
218
219
# Access Julia C API functions directly
220
# (Advanced usage - requires knowledge of Julia's C API)
221
result = libjulia.jl_eval_string(b"2 + 3")
222
print(libjulia.jl_unbox_int64(result)) # 5
223
```
224
225
### LibPython Discovery
226
227
```python
228
from julia.find_libpython import find_libpython, linked_libpython
229
230
# Find all possible libpython paths
231
candidates = find_libpython()
232
print("LibPython candidates:", candidates)
233
234
# Get currently linked libpython
235
linked = linked_libpython()
236
print("Currently linked:", linked)
237
238
# Check specific library name format
239
from julia.find_libpython import library_name
240
lib_name = library_name("python3.9")
241
print("Library name:", lib_name) # e.g., "libpython3.9.so" on Linux
242
```
243
244
### Runtime Information Access
245
246
```python
247
from julia.juliainfo import JuliaInfo
248
249
# Create Julia runtime info
250
info = JuliaInfo(
251
julia="/usr/local/bin/julia",
252
sysimage="/usr/local/lib/julia/sys.so"
253
)
254
255
# Check compatibility
256
from julia.juliainfo import is_compatible_exe
257
compatible = is_compatible_exe(info.libpython_path)
258
print("Compatible:", compatible)
259
```
260
261
### Advanced Memory Management
262
263
```python
264
from julia.libjulia import get_libjulia, UNBOXABLE_TYPES
265
266
libjulia = get_libjulia()
267
268
# Create Julia array and access raw data
269
jl_array = libjulia.jl_eval_string(b"[1.0, 2.0, 3.0]")
270
271
# Check if type is unboxable
272
print("Unboxable types:", UNBOXABLE_TYPES)
273
274
# Access array data directly (advanced usage)
275
# Requires careful memory management
276
data_ptr = libjulia.jl_array_data(jl_array)
277
length = libjulia.jl_array_len(jl_array)
278
```
279
280
### Platform-Specific Operations
281
282
```python
283
from julia.utils import is_linux, is_windows, is_apple, execprog
284
285
# Platform detection
286
if is_linux:
287
print("Running on Linux")
288
elif is_windows:
289
print("Running on Windows")
290
elif is_apple:
291
print("Running on macOS")
292
293
# Execute platform-specific commands
294
try:
295
execprog(["julia", "--version"])
296
except Exception as e:
297
print(f"Failed to execute: {e}")
298
```
299
300
### Custom LibJulia Implementation
301
302
```python
303
from julia.libjulia import BaseLibJulia, setup_libjulia
304
305
class CustomLibJulia(BaseLibJulia):
306
"""Custom LibJulia implementation for specialized use cases."""
307
308
def __init__(self, **kwargs):
309
super().__init__(**kwargs)
310
# Custom initialization logic
311
312
def custom_operation(self):
313
"""Custom low-level operation."""
314
# Implementation specific to your use case
315
pass
316
317
# Use custom implementation
318
custom_jl = CustomLibJulia()
319
setup_libjulia(custom_jl)
320
```
321
322
## Error Handling
323
324
The low-level API provides minimal error handling - users must handle Julia exceptions and memory management carefully:
325
326
```python
327
from julia.libjulia import get_libjulia
328
329
libjulia = get_libjulia()
330
331
try:
332
# Direct C API calls may crash if not handled properly
333
result = libjulia.jl_eval_string(b"undefined_function()")
334
# Check for exceptions before using result
335
if libjulia.jl_exception_occurred():
336
exception = libjulia.jl_exception_in_transit()
337
# Handle exception appropriately
338
raise RuntimeError("Julia exception occurred")
339
except Exception as e:
340
print(f"Low-level error: {e}")
341
```
342
343
## Performance Considerations
344
345
The low-level API is designed for performance-critical applications:
346
347
- Minimal Python overhead for Julia function calls
348
- Direct memory access to Julia arrays
349
- Bypasses high-level type conversion when not needed
350
- Suitable for embedding Julia in performance-critical Python applications
351
- Requires careful memory management to avoid crashes