Appearance
fundal_registry
FUNDAL, allocation registry module: device and size of every structured allocation.
Host-side open-addressing hash table (linear probing, backward-shift deletion, doubling at load 0.5) keyed by the base address of the buffer; key 0 marks an empty slot (a successful allocation never returns a null address). The registry owns the live-allocation totals and mirrors them into the fundal_env counters (dev_allocs_live, dev_bytes_live). A second structure, the base addresses sorted in ascending order, finds the allocation containing an address (a section of a buffer) by binary search: O(log n) lookup, O(n) insertion and removal. Updates are serialized by an OpenMP critical section: thread-safe only when the library is compiled with OpenMP.
Source: src/lib/fundal_registry.F90
Dependencies
Contents
- registry_entry
- registry_insert
- registry_remove
- registry_lookup
- registry_lookup_range
- registry_stats
- registry_report
- registry_clear
- dev_set_registry_policy
- registry_misuse
- set_policy
- totals_update
- sorted_insert
- sorted_remove
- table_init
- table_find
- table_delete
- table_resize
- registry_address
- registry_policy
- home_slot
- sorted_position
Variables
| Name | Type | Attributes | Description |
|---|---|---|---|
FUNDAL_REGISTRY_OFF | integer(kind=I4P) | parameter | Registry checks disabled: today's behaviour, no warnings. |
FUNDAL_REGISTRY_WARN | integer(kind=I4P) | parameter | Misuse is reported on stderr, behaviour unchanged (default). |
FUNDAL_REGISTRY_ERROR | integer(kind=I4P) | parameter | Misuse is an error (error code or error stop). |
LABEL_LEN | integer(kind=I4P) | parameter | Length of allocation labels. |
INITIAL_CAPACITY | integer(kind=I8P) | parameter | Initial number of slots (power of 2). |
table | type(registry_entry) | allocatable, save | Hash table, slots 0:capacity-1. |
sorted | integer(kind=c_intptr_t) | allocatable, save | Base addresses in ascending order, sorted(1:used). |
used | integer(kind=I8P) | save | Number of occupied slots. |
policy_ | integer(kind=I4P) | save | Registry policy, -1 = not yet resolved. |
Derived Types
registry_entry
Registered allocation.
Components
| Name | Type | Attributes | Description |
|---|---|---|---|
addr | integer(kind=c_intptr_t) | Base address of the buffer (0 = empty slot). | |
bytes | integer(kind=I8P) | Size of the buffer [bytes]. | |
dev_id | integer(kind=I4P) | Device where the buffer lives. | |
label | character(len=LABEL_LEN) | Optional user label. |
Subroutines
registry_insert
Register an allocation. If the address is already registered (its buffer was released outside FUNDAL and the address reused), the old entry is replaced and replaced is set to true.
fortran
subroutine registry_insert(addr, bytes, dev_id, label, replaced)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
addr | integer(kind=c_intptr_t) | in | Base address. | |
bytes | integer(kind=I8P) | in | Size [bytes]. | |
dev_id | integer(kind=I4P) | in | Device. | |
label | character(len=*) | in | optional | Label. |
replaced | logical | out | optional | Address was already registered. |
Call graph
registry_remove
Unregister an allocation, returning its entry.
fortran
subroutine registry_remove(addr, found, entry)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
addr | integer(kind=c_intptr_t) | in | Base address. | |
found | logical | out | Address was registered. | |
entry | type(registry_entry) | out | optional | Removed entry. |
Call graph
registry_lookup
Look an allocation up.
fortran
subroutine registry_lookup(addr, found, entry)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
addr | integer(kind=c_intptr_t) | in | Base address. | |
found | logical | out | Address is registered. | |
entry | type(registry_entry) | out | optional | Entry. |
Call graph
registry_lookup_range
Look up the allocation containing the range [addr, addr+bytes): the whole buffer (exact hash lookup) or a part of it (binary search of the sorted base addresses). A range that starts inside an allocation but ends beyond it is not found and sets overflow.
fortran
subroutine registry_lookup_range(addr, bytes, found, entry, overflow)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
addr | integer(kind=c_intptr_t) | in | Start address of the range. | |
bytes | integer(kind=I8P) | in | Size of the range [bytes]. | |
found | logical | out | The range lies inside a registered allocation. | |
entry | type(registry_entry) | out | optional | Entry of the containing allocation. |
overflow | logical | out | optional | The range starts inside an allocation but ends beyond it. |
Call graph
registry_stats
Return the number and the bytes of live allocations, optionally only those on one device.
fortran
subroutine registry_stats(allocs, bytes, dev_id)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
allocs | integer(kind=I8P) | out | optional | Number of live allocations. |
bytes | integer(kind=I8P) | out | optional | Bytes of live allocations. |
dev_id | integer(kind=I4P) | in | optional | Count only allocations on this device. |
Call graph
registry_report
Write the live allocations (address, bytes, device, label), one per line in ascending address order, followed by a summary line.
fortran
subroutine registry_report(unit)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
unit | integer(kind=I4P) | in | optional | Output unit (default standard output). |
Call graph
registry_clear
Forget every allocation (without freeing any memory) and reset the totals. Meant for tests.
fortran
subroutine registry_clear()dev_set_registry_policy
Set the registry policy: 'off', 'warn' or 'error' (case insensitive). It overrides FUNDAL_REGISTRY.
fortran
subroutine dev_set_registry_policy(policy, ierr)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
policy | character(len=*) | in | Policy name. | |
ierr | integer(kind=I4P) | out | optional | Error status: 1 if the name is not valid (policy unchanged). |
Call graph
registry_misuse
Report a misuse according to the policy: error stop with policy error, warning on stderr with policy warn (followed by the action taken, the caller then proceeds), nothing with policy off.
fortran
subroutine registry_misuse(msg, action)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
msg | character(len=*) | in | Description of the misuse. | |
action | character(len=*) | in | What is done anyway under policy warn. |
Call graph
set_policy
Set the policy from its name, leaving it unchanged if the name is not valid.
fortran
subroutine set_policy(name, valid)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
name | character(len=*) | in | Policy name. | |
valid | logical | out | optional | Valid name. |
Call graph
totals_update
Update the live totals (mirrored in fundal_env).
fortran
subroutine totals_update(dn, db)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
dn | integer(kind=I8P) | in | Allocations increment. | |
db | integer(kind=I8P) | in | Bytes increment. |
Call graph
sorted_insert
Insert a new base address in the sorted list (called before used is incremented).
fortran
subroutine sorted_insert(addr)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
addr | integer(kind=c_intptr_t) | in | Address. |
Call graph
sorted_remove
Remove a base address from the sorted list (called before used is decremented).
fortran
subroutine sorted_remove(addr)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
addr | integer(kind=c_intptr_t) | in | Address. |
Call graph
table_init
Allocate an empty table.
fortran
subroutine table_init(capacity)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
capacity | integer(kind=I8P) | in | Number of slots (power of 2). |
Call graph
table_find
Find the slot of an address, or the empty slot where it would be inserted.
fortran
subroutine table_find(addr, slot, found)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
addr | integer(kind=c_intptr_t) | in | Address. | |
slot | integer(kind=I8P) | out | Slot. | |
found | logical | out | Address present. |
Call graph
table_delete
Empty a slot with backward-shift deletion, so that no tombstones are needed: entries of the following cluster that may move closer to their home slot are shifted into the hole.
fortran
subroutine table_delete(slot)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
slot | integer(kind=I8P) | in | Slot to empty. |
Call graph
table_resize
Rehash every entry into a table of the given capacity.
fortran
subroutine table_resize(capacity)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
capacity | integer(kind=I8P) | in | New number of slots (power of 2). |
Call graph
Functions
registry_address
Return the address held by a C pointer as an integer key.
Returns: integer(kind=c_intptr_t)
fortran
function registry_address(cptr) result(addr)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
cptr | type(c_ptr) | in | C pointer. |
Call graph
registry_policy
Return the registry policy; on first use it is read from the environment variable FUNDAL_REGISTRY (off, warn or error; default warn) unless already set by dev_set_registry_policy.
Returns: integer(kind=I4P)
fortran
function registry_policy() result(policy)Call graph
home_slot
Return the home slot of an address: shift-xor mixing (no multiplication, so no integer overflow) of the address, whose low bits are zero for aligned device buffers, reduced modulo the power-of-2 capacity.
Attributes: pure
Returns: integer(kind=I8P)
fortran
function home_slot(addr, capacity) result(slot)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
addr | integer(kind=c_intptr_t) | in | Address. | |
capacity | integer(kind=I8P) | in | Number of slots (power of 2). |
Call graph
sorted_position
Return the position of the first sorted base address >= addr (used + 1 if none), by binary search.
Attributes: pure
Returns: integer(kind=I8P)
fortran
function sorted_position(addr) result(pos)Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
addr | integer(kind=c_intptr_t) | in | Address. |
Call graph