memory
Memory-block simulation and pluggable allocation algorithms.
Examples:
>>> from ures.memory import DeviceMemorySimulator
>>> sim = DeviceMemorySimulator(device_id=0, total_memory=256)
>>> sim.allocate(32).success
True
TraceInfo
dataclass
TraceInfo(timestamp_ns: int, operation: str, filename: Optional[str] = None, line_number: Optional[int] = None, function_name: Optional[str] = None, code_context: Optional[str] = None, stack_trace: Optional[List[str]] = None, additional_info: Optional[Dict[str, Any]] = dict())
Represents trace information for memory operations.
This class captures execution context and timing information for debugging and profiling memory allocation/deallocation operations. It records stack traces, function names, and additional metadata to help track memory usage patterns.
Attributes:
-
timestamp_ns(int) –Timestamp in nanoseconds when the operation occurred
-
operation(str) –Type of operation ("create", "alloc", "free_request", etc.)
-
filename(Optional[str]) –Source file where the operation was initiated
-
line_number(Optional[int]) –Line number in the source file
-
function_name(Optional[str]) –Name of the function that initiated the operation
-
code_context(Optional[str]) –The actual line of code that was executed
-
stack_trace(Optional[List[str]]) –Full stack trace if capture_full_stack was enabled
-
additional_info(Optional[Dict[str, Any]]) –Dictionary containing operation-specific metadata
capture_current_trace
classmethod
capture_current_trace(operation: str, stack_depth: int = 2, capture_full_stack: bool = False, additional_info: Optional[Dict[str, Any]] = None) -> 'TraceInfo'
Capture current execution trace information.
This method inspects the current call stack to gather context information about where a memory operation was initiated. It's useful for debugging memory leaks and understanding allocation patterns.
Parameters:
-
operation(str) –String describing the type of operation being traced
-
stack_depth(int, default:2) –How many frames up the stack to look for the caller
-
capture_full_stack(bool, default:False) –Whether to capture the complete stack trace
-
additional_info(Optional[Dict[str, Any]], default:None) –Optional dictionary with operation-specific data
Returns:
-
'TraceInfo'–TraceInfo object containing the captured trace information
Source code in ures/memory/blocks.py
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | |
to_dict
to_dict() -> Dict[str, Any]
Export trace data in dictionary form.
Converts the TraceInfo object to a dictionary format suitable for JSON serialization, logging, or analysis tools.
Returns:
Source code in ures/memory/blocks.py
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | |
MemoryBlock
MemoryBlock(addr: int, size: int, device: Optional[int] = None, stream: Optional[int] = None, pool: Optional[BlockPool] = None, segment_id: Optional[int] = None, capture_trace: bool = True)
Bases: NonCircularBiLink
Represents a memory block that can be split, allocated, and coalesced.
This class extends NonCircularBiLink to implement a doubly-linked list of memory blocks. Each block represents a contiguous region of memory that can be allocated to users or kept free for future allocations. Blocks can be split into smaller pieces or coalesced with adjacent free blocks to reduce fragmentation.
Attributes:
-
device(Optional[int]) –Device ID for the memory block (e.g., GPU device number)
-
stream(Optional[int]) –Stream ID for CUDA operations
-
pool(Optional[BlockPool]) –Reference to the BlockPool that manages this block
-
segment_id–ID of the segment this block belongs to
Create a memory block with the given address, size, stream, and time.
Parameters:
-
addr(int) –The starting address of the memory block.
-
size(int) –The size of the memory block in bytes.
-
device(int, default:None) –The device identifier for the memory block.
-
stream(int, default:None) –The stream identifier for the memory block.
-
pool(BlockPool, default:None) –The pool this block belongs to.
-
segment_id(int, default:None) –The ID of the segment this block belongs to.
-
capture_trace(bool, default:True) –Whether to capture creation trace.
Source code in ures/memory/blocks.py
448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 | |
value
property
value: MemoryInfo
Get the MemoryInfo object associated with this block.
end_addr
property
end_addr: int
Get the end address of the block.
is_head
property
is_head: bool
Check if this block is the head of the linked list.
is_split
property
is_split: bool
Check if this block is part of a split (has neighbors in linked list).
addr
property
addr: int
Get the starting address of the block.
addr_hex
property
addr_hex: str
Get the starting address of the block in hexadecimal format.
is_segment_start
property
is_segment_start: bool
Check if this block is the first block of a segment.
Returns:
-
bool–True if this block is the first block of its segment
request_alloc
request_alloc(time_ns: Optional[int] = None, capture_trace: bool = True)
Request allocation of this memory block.
Marks the block as allocated if it's currently free. Updates the allocation timestamp and captures trace information.
Parameters:
-
time_ns(Optional[int], default:None) –Optional timestamp for the allocation (uses current time if None)
-
capture_trace(bool, default:True) –Whether to capture trace information for this operation
Source code in ures/memory/blocks.py
539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 | |
request_free
request_free(time_ns: Optional[int] = None, capture_trace: bool = True)
Request to free the memory block.
Initiates the free process by marking the block as "free_requested". This allows for asynchronous freeing patterns where the actual free operation might be deferred.
Parameters:
-
time_ns(Optional[int], default:None) –Optional timestamp for the free request
-
capture_trace(bool, default:True) –Whether to capture trace information for this operation
Source code in ures/memory/blocks.py
568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 | |
complete_free
complete_free(time_ns: Optional[int] = None, capture_trace: bool = True)
Complete the free operation.
Finalizes the freeing process for blocks that were previously marked as "free_requested". This completes the asynchronous free pattern.
Parameters:
-
time_ns(Optional[int], default:None) –Optional timestamp for the free completion
-
capture_trace(bool, default:True) –Whether to capture trace information for this operation
Source code in ures/memory/blocks.py
597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 | |
free_block
free_block(time_ns: Optional[int] = None, capture_trace: bool = True)
Immediately free the memory block (skips free_requested state).
Performs an immediate synchronous free operation, bypassing the "free_requested" intermediate state.
Parameters:
-
time_ns(Optional[int], default:None) –Optional timestamp for the free operation
-
capture_trace(bool, default:True) –Whether to capture trace information for this operation
Source code in ures/memory/blocks.py
626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 | |
force_reset_memory_info
force_reset_memory_info()
Force reset the memory info to a clean state.
Creates a new MemoryInfo object with the same address and size, effectively clearing all allocation history and traces.
Source code in ures/memory/blocks.py
654 655 656 657 658 659 660 661 662 | |
insert_block
insert_block(block: MemoryBlock) -> MemoryBlock
Insert a block into this block's address space.
This method handles the complex operation of inserting a new block within the address range of this block. It performs necessary splitting operations to accommodate the new block.
Parameters:
-
block(MemoryBlock) –The MemoryBlock to insert
Returns:
-
MemoryBlock–The MemoryBlock that was created or modified during insertion
Raises:
-
MemoryError–If trying to insert into an allocated block
-
ValueError–If the block doesn't fit or is already split
Source code in ures/memory/blocks.py
664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 | |
splice
splice(memory_size: int, capture_trace: bool = True) -> Optional[MemoryBlock]
Split the block.
Creates a new block of the specified size from the beginning of this block and adjusts this block to represent the remaining memory. This is the fundamental operation for memory allocation.
Parameters:
-
memory_size(int) –The size of the memory to split off.
-
capture_trace(bool, default:True) –Whether to capture split trace.
Returns:
-
MemoryBlock(Optional[MemoryBlock]) –The new block that was created.
Raises:
-
MemoryError–If trying to split an allocated block
-
ValueError–If the requested size is larger than available
Source code in ures/memory/blocks.py
734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 | |
coalesce
coalesce(capture_trace: bool = True) -> MemoryBlock
Coalesce the block with adjacent free blocks.
Merges this block with any adjacent free blocks in the same segment to reduce fragmentation. This is a critical operation for maintaining memory efficiency.
Parameters:
-
capture_trace(bool, default:True) –Whether to capture trace information for this operation
Returns:
-
MemoryBlock–The coalesced MemoryBlock (may be self or a neighboring block)
Raises:
-
MemoryError–If trying to coalesce an allocated block
Source code in ures/memory/blocks.py
807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 | |
contains_address
contains_address(addr: int, size: int = 1) -> bool
Check if the specified address range is within the segment.
Parameters:
-
addr(int) –Starting address to check
-
size(int, default:1) –Size of the range to check (default: 1)
Returns:
-
bool–True if the entire range is within this block's bounds
Source code in ures/memory/blocks.py
908 909 910 911 912 913 914 915 916 917 918 919 | |
to_dict
to_dict() -> Dict[str, Any]
Export block data in dictionary form.
Creates a comprehensive dictionary representation of the block including all state information and traces.
Returns:
Source code in ures/memory/blocks.py
921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 | |
MemoryInfo
dataclass
MemoryInfo(addr: int, size: int, action: str = 'free', allocated: bool = False, alloc_time_ns: Optional[int] = None, free_requested_time_ns: Optional[int] = None, free_completed_time_ns: Optional[int] = None, traces: List[TraceInfo] = list())
Represents a memory block within a segment.
This class tracks the state and lifecycle of a memory block, including allocation status, timing information, and operation traces. It maintains the core information needed for memory management operations.
Attributes:
-
addr(int) –Starting address of the memory block
-
size(int) –Size of the memory block in bytes
-
action(str) –Current state ("free", "alloc", "free_requested", "free_completed")
-
allocated(bool) –Boolean flag indicating if the block is currently allocated
-
alloc_time_ns(Optional[int]) –Timestamp when the block was allocated
-
free_requested_time_ns(Optional[int]) –Timestamp when free was requested
-
free_completed_time_ns(Optional[int]) –Timestamp when free was completed
-
traces(List[TraceInfo]) –List of TraceInfo objects tracking operations on this block
is_allocated
is_allocated() -> bool
Check if the memory block is currently allocated.
A block is considered allocated if it's marked as allocated and its action is either "alloc" or "free_requested" (pending free).
Returns:
-
bool–True if the block is allocated, False otherwise
Source code in ures/memory/blocks.py
167 168 169 170 171 172 173 174 175 176 177 | |
is_free_requested
is_free_requested() -> bool
Check if a free operation has been requested but not completed.
Returns:
-
bool–True if free has been requested but not completed
Source code in ures/memory/blocks.py
179 180 181 182 183 184 185 186 | |
is_free_completed
is_free_completed() -> bool
Check if the memory block has been completely freed.
Returns:
-
bool–True if the block is fully freed and available for reuse
Source code in ures/memory/blocks.py
188 189 190 191 192 193 194 195 | |
get_end_addr
get_end_addr() -> int
Get the end address of the block.
Calculates the first address after the end of this memory block.
Returns:
-
int–The address immediately following this block
Source code in ures/memory/blocks.py
197 198 199 200 201 202 203 204 205 206 | |
add_trace
add_trace(trace: TraceInfo)
Add a trace to this memory info.
Appends a TraceInfo object to track operations performed on this block.
Parameters:
-
trace(TraceInfo) –TraceInfo object containing operation details
Source code in ures/memory/blocks.py
208 209 210 211 212 213 214 215 216 217 | |
Segment
dataclass
Segment(segment_id: int, start_addr: int, original_size: int, device: Optional[int] = None, stream: Optional[int] = None, creation_time_ns: Optional[int] = None, first_block: Optional[MemoryBlock] = None, traces: List[TraceInfo] = list())
Represents an original memory segment before any splitting.
A segment represents a contiguous block of memory that was originally allocated from the system. It can be split into multiple smaller blocks but maintains information about the original allocation for tracking fragmentation and utilization.
Attributes:
-
segment_id(int) –Unique identifier for this segment
-
start_addr(int) –Starting address of the original segment
-
original_size(int) –Original size of the segment when first created
-
device(Optional[int]) –Device ID where this memory resides (e.g., GPU device)
-
stream(Optional[int]) –Stream ID for CUDA operations
-
creation_time_ns(Optional[int]) –Timestamp when the segment was created
-
first_block(Optional[MemoryBlock]) –Reference to the first block in the linked list
-
traces(List[TraceInfo]) –List of TraceInfo objects for segment-level operations
end_addr
property
end_addr: int
Get the end address of the original segment.
Returns:
-
int–The address immediately following the original segment
add_trace
add_trace(trace: TraceInfo)
Add a trace to this segment.
Parameters:
-
trace(TraceInfo) –TraceInfo object containing operation details
Source code in ures/memory/blocks.py
265 266 267 268 269 270 271 272 | |
get_blocks
get_blocks() -> List[MemoryBlock]
Get all blocks belonging to this segment in address order.
Traverses the linked list starting from first_block and collects all blocks that belong to this segment, then sorts them by address.
Returns:
-
List[MemoryBlock]–List of MemoryBlock objects sorted by address
Source code in ures/memory/blocks.py
274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 | |
get_block_count
get_block_count() -> int
Get the number of blocks this segment has been split into.
Returns:
-
int–Number of blocks in this segment
Source code in ures/memory/blocks.py
298 299 300 301 302 303 304 305 | |
get_allocated_bytes
get_allocated_bytes() -> int
Get total allocated bytes in this segment.
Sums up the sizes of all allocated blocks within this segment.
Returns:
-
int–Total bytes currently allocated in this segment
Source code in ures/memory/blocks.py
307 308 309 310 311 312 313 314 315 316 317 318 319 320 | |
get_free_bytes
get_free_bytes() -> int
Get total free bytes in this segment.
Sums up the sizes of all free blocks within this segment.
Returns:
-
int–Total bytes currently free in this segment
Source code in ures/memory/blocks.py
322 323 324 325 326 327 328 329 330 331 332 333 334 335 | |
get_utilization_ratio
get_utilization_ratio() -> float
Get the utilization ratio (0.0 to 1.0).
Calculates what fraction of the segment is currently allocated.
Returns:
-
float–Ratio of allocated bytes to original segment size
Source code in ures/memory/blocks.py
337 338 339 340 341 342 343 344 345 346 347 348 | |
get_fragmentation_ratio
get_fragmentation_ratio() -> float
Get the fragmentation ratio (0.0 = no fragmentation, 1.0 = highly fragmented).
Measures how fragmented the segment is based on the number of blocks. More blocks indicate higher fragmentation.
Returns:
-
float–Fragmentation ratio where 0.0 means no fragmentation
Source code in ures/memory/blocks.py
350 351 352 353 354 355 356 357 358 359 360 361 362 363 | |
is_fully_free
is_fully_free() -> bool
Check if all blocks in the segment are free.
Returns:
-
bool–True if every block in the segment is free
Source code in ures/memory/blocks.py
365 366 367 368 369 370 371 372 | |
is_fully_allocated
is_fully_allocated() -> bool
Check if all blocks in the segment are allocated.
Returns:
-
bool–True if every block in the segment is allocated
Source code in ures/memory/blocks.py
374 375 376 377 378 379 380 381 | |
contains_address
contains_address(addr: int, size: int = 1) -> bool
Check if the specified address range is within the segment.
Parameters:
Returns:
-
bool–True if the entire range is within the segment bounds
Source code in ures/memory/blocks.py
383 384 385 386 387 388 389 390 391 392 393 394 | |
to_dict
to_dict() -> Dict[str, Any]
Export segment data in dictionary form.
Creates a comprehensive dictionary representation of the segment including all metrics and trace information.
Returns:
Source code in ures/memory/blocks.py
396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 | |
BlockPool
BlockPool()
Manages a pool of memory blocks and segments.
BlockPool is the main memory management class that maintains collections of memory blocks and segments. It provides functionality for creating segments, tracking memory usage, analyzing allocation patterns, and detecting memory overlaps. The pool uses a SortedSet for efficient block lookups and maintains segment metadata for comprehensive memory analysis.
Attributes:
-
blocks–SortedSet of MemoryBlock objects sorted by (stream, size, address)
-
segments(Dict[int, Segment]) –Dictionary mapping segment IDs to Segment objects
-
next_segment_id(int) –Counter for generating unique segment IDs
Initialize a new BlockPool.
Creates empty collections for blocks and segments, and initializes the segment ID counter.
Source code in ures/memory/blocks.py
1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 | |
lower_bound
lower_bound(search_key: MemoryBlock, releaseable=False) -> Optional[MemoryBlock]
Find the first block that is >= search_key.
Performs efficient lookup in the sorted blocks collection. Can optionally filter for blocks that are not part of a split (releaseable blocks).
Parameters:
-
search_key(MemoryBlock) –Block used as the search bound.
-
releaseable(bool, default:False) –If True, skip blocks that are part of a split.
Returns:
-
Optional[MemoryBlock]–First MemoryBlock >= search_key, or None if not found
Source code in ures/memory/blocks.py
1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 | |
is_end_block
is_end_block(search_key: MemoryBlock) -> bool
Check if search_key would be at the end of the sorted collection.
Parameters:
-
search_key(MemoryBlock) –MemoryBlock to check
Returns:
-
bool–True if search_key would be inserted at the end
Source code in ures/memory/blocks.py
1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 | |
is_begin_block
is_begin_block(search_key: MemoryBlock) -> bool
Check if search_key would be at the beginning of the sorted collection.
Parameters:
-
search_key(MemoryBlock) –MemoryBlock to check
Returns:
-
bool–True if search_key would be inserted at the beginning
Source code in ures/memory/blocks.py
1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 | |
insert_into_blocks
insert_into_blocks(block: MemoryBlock) -> None
Insert a block into the sorted blocks collection.
Parameters:
-
block(MemoryBlock) –MemoryBlock to insert
Source code in ures/memory/blocks.py
1142 1143 1144 1145 1146 1147 1148 1149 | |
check_segment_overlap
check_segment_overlap(start_addr: int, size: int, device: Optional[int] = None, stream: Optional[int] = None) -> Dict[str, Any]
Check if a proposed segment would overlap with any existing segments.
Analyzes the proposed segment against all existing segments to detect any address space conflicts. This is crucial for preventing memory corruption and ensuring safe segment creation.
Parameters:
-
start_addr(int) –Starting address of the proposed segment
-
size(int) –Size of the proposed segment
-
device(Optional[int], default:None) –Device ID (optional filter)
-
stream(Optional[int], default:None) –Stream ID (optional filter)
Returns:
-
Dict[str, Any]–Dict[str, Any]: Dictionary containing overlap information: - 'has_overlap': bool indicating if any overlap exists - 'overlapping_segments': list of overlapping segment details - 'overlap_type': type of overlap ('none', 'partial', 'complete', 'contains', 'contained') - 'safe_to_create': bool indicating if it's safe to create the segment
Source code in ures/memory/blocks.py
1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 | |
find_safe_address_range
find_safe_address_range(size: int, device: Optional[int] = None, stream: Optional[int] = None, min_addr: int = 4096, max_addr: int = 4294967295, alignment: int = 1) -> Optional[Dict[str, Any]]
Find a safe address range where a new segment can be created without overlap.
Searches through the address space to find a suitable location for a new segment of the specified size. Considers alignment requirements and avoids existing segments.
Parameters:
-
size(int) –Required size for the new segment
-
device(Optional[int], default:None) –Device ID filter
-
stream(Optional[int], default:None) –Stream ID filter
-
min_addr(int, default:4096) –Minimum address to consider
-
max_addr(int, default:4294967295) –Maximum address to consider
-
alignment(int, default:1) –Address alignment requirement
Returns:
-
Optional[Dict[str, Any]]–Optional[Dict[str, Any]]: Safe address range info or None if no space found
Source code in ures/memory/blocks.py
1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 | |
create_segment
create_segment(start_addr: int, size: int, device: Optional[int] = None, stream: Optional[int] = None, capture_trace: bool = True) -> Segment
Create a new segment and its initial block.
Creates a new memory segment with the specified parameters after checking for overlaps. This is the primary method for adding new memory regions to the pool.
Parameters:
-
start_addr(int) –Starting address for the new segment
-
size(int) –Size of the segment in bytes
-
device(Optional[int], default:None) –Optional device ID
-
stream(Optional[int], default:None) –Optional stream ID
-
capture_trace(bool, default:True) –Whether to capture creation traces
Returns:
-
Segment–The newly created Segment object
Raises:
-
MemoryError–If the segment would overlap with existing segments
Source code in ures/memory/blocks.py
1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 | |
get_segment
get_segment(segment_id: int) -> Optional[Segment]
Get segment by ID.
Parameters:
-
segment_id(int) –ID of the segment to retrieve
Returns:
Source code in ures/memory/blocks.py
1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 | |
list_all_segments
list_all_segments() -> List[Dict[str, Any]]
Swift listing of all segments with original information - O(segments) complexity.
Provides an efficient way to get summary information about all segments without traversing the block linked lists.
Returns:
Source code in ures/memory/blocks.py
1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 | |
list_blocks_in_segment
list_blocks_in_segment(segment_id: int) -> List[Dict[str, Any]]
List all blocks within a specific segment in address order.
Parameters:
-
segment_id(int) –ID of the segment to examine
Returns:
Source code in ures/memory/blocks.py
1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 | |
get_segment_by_address
get_segment_by_address(addr: int) -> Optional[Segment]
Find which segment contains the given address.
Parameters:
-
addr(int) –Address to search for
Returns:
Source code in ures/memory/blocks.py
1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 | |
remove_segment
remove_segment(segment_id: int, force: bool = True) -> bool
Remove a segment and all its blocks.
Removes a segment and all associated blocks from the pool. Can optionally check for allocated blocks before removal.
Parameters:
-
segment_id(int) –ID of the segment to remove
-
force(bool, default:True) –If False, will not remove segments with allocated blocks
Returns:
-
bool–True if segment was removed, False otherwise
Source code in ures/memory/blocks.py
1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 | |
get_traces_by_operation
get_traces_by_operation(operation: str) -> List[Dict[str, Any]]
Get all traces of a specific operation across all segments and blocks.
Searches through all segments and blocks to find traces matching the specified operation type.
Parameters:
-
operation(str) –Operation type to search for
Returns:
Source code in ures/memory/blocks.py
1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 | |
get_all_traces
get_all_traces() -> List[Dict[str, Any]]
Get all traces from all segments and blocks, sorted by timestamp.
Collects every trace from every segment and block in the pool, providing a complete timeline of memory operations.
Returns:
Source code in ures/memory/blocks.py
1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 | |
analyze_memory_patterns
analyze_memory_patterns() -> Dict[str, Any]
Analyze memory allocation patterns based on traces.
Processes all trace information to provide insights into memory usage patterns, operation frequencies, and timing behavior.
Returns:
Source code in ures/memory/blocks.py
1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 | |
get_memory_summary
get_memory_summary() -> Dict[str, Any]
Get overall memory summary across all segments.
Provides high-level statistics about memory usage, fragmentation, and utilization across the entire pool.
Returns:
Source code in ures/memory/blocks.py
1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 | |
print_memory_status
print_memory_status()
Print detailed memory status for debugging.
Outputs a comprehensive report of the current memory state including segment information, block details, and utilization statistics.
Source code in ures/memory/blocks.py
1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 | |
AllocationRequest
dataclass
AllocationRequest(size: int, alignment: int = 1, stream: Optional[int] = None, priority: int = 0, metadata: Optional[Dict[str, Any]] = None)
Represents a memory allocation request
AllocationResult
dataclass
AllocationResult(success: bool, block: Optional[MemoryBlock] = None, address: Optional[int] = None, actual_size: Optional[int] = None, allocation_time_ns: Optional[int] = None, error_message: Optional[str] = None, strategy_info: Optional[Dict[str, Any]] = None)
Represents the result of an allocation attempt
AllocationStrategy
FreeResult
dataclass
FreeResult(success: bool, address: Optional[int] = None, freed_size: Optional[int] = None, free_time_ns: Optional[int] = None, coalesced: bool = False, coalesced_size: Optional[int] = None, error_message: Optional[str] = None, strategy_info: Optional[Dict[str, Any]] = None)
Represents the result of a deallocation attempt
FreeRequest
dataclass
FreeRequest(address: int, expected_size: Optional[int] = None, metadata: Optional[Dict[str, Any]] = None)
Represents a memory deallocation request
MemoryAllocator
MemoryAllocator(name: str)
Bases: ABC
Abstract base class for memory allocation algorithms
Source code in ures/memory/allocator.py
72 73 74 75 76 77 78 79 80 81 82 | |
allocate
abstractmethod
allocate(pool: BlockPool, request: AllocationRequest) -> AllocationResult
Allocate memory according to the algorithm's strategy
Source code in ures/memory/allocator.py
84 85 86 87 | |
free
abstractmethod
free(pool: BlockPool, request: FreeRequest) -> FreeResult
Free memory according to the algorithm's strategy
Source code in ures/memory/allocator.py
89 90 91 92 | |
can_allocate
abstractmethod
can_allocate(pool: BlockPool, request: AllocationRequest) -> bool
Check if allocation is possible without actually allocating
Source code in ures/memory/allocator.py
94 95 96 97 | |
can_free
can_free(pool: BlockPool, request: FreeRequest) -> bool
Check if deallocation is possible
Source code in ures/memory/allocator.py
99 100 101 | |
get_statistics
get_statistics() -> Dict[str, Any]
Get allocator statistics
Source code in ures/memory/allocator.py
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | |
FirstFitAllocator
FirstFitAllocator()
Bases: MemoryAllocator
First-fit allocation algorithm
Source code in ures/memory/allocator.py
132 133 | |
BestFitAllocator
BestFitAllocator()
Bases: MemoryAllocator
Best-fit allocation algorithm
Source code in ures/memory/allocator.py
254 255 | |
WorstFitAllocator
WorstFitAllocator()
Bases: MemoryAllocator
Worst-fit allocation algorithm
Source code in ures/memory/allocator.py
382 383 | |
NextFitAllocator
NextFitAllocator()
Bases: MemoryAllocator
Next-fit allocation algorithm
Source code in ures/memory/allocator.py
510 511 512 | |
BuddySystemAllocator
BuddySystemAllocator()
Bases: MemoryAllocator
Buddy system allocation algorithm
Source code in ures/memory/allocator.py
675 676 677 | |
DeviceMemorySimulator
DeviceMemorySimulator(device_id: int, total_memory: int, base_address: int = 268435456)
Simulate a device heap and swap among allocation algorithms.
Examples:
>>> from ures.memory import DeviceMemorySimulator
>>> sim = DeviceMemorySimulator(device_id=0, total_memory=1024)
>>> result = sim.allocate(size=64)
>>> result.success
True
>>> sim.free(result.address).success
True
Source code in ures/memory/allocator.py
900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 | |
register_allocator
register_allocator(allocator: MemoryAllocator)
Register a new allocation algorithm
Source code in ures/memory/allocator.py
927 928 929 | |
set_allocator
set_allocator(allocator_name: str) -> bool
Set the active allocation algorithm
Source code in ures/memory/allocator.py
931 932 933 934 935 936 | |
get_available_allocators
get_available_allocators() -> List[str]
Get list of available allocator names
Source code in ures/memory/allocator.py
938 939 940 | |
allocate
allocate(size: int, alignment: int = 1, stream: Optional[int] = None, priority: int = 0, metadata: Optional[Dict[str, Any]] = None) -> AllocationResult
Allocate memory using the current algorithm
Source code in ures/memory/allocator.py
942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 | |
free
free(address: int, expected_size: Optional[int] = None) -> FreeResult
Free memory at the given address using the current allocator
Source code in ures/memory/allocator.py
967 968 969 970 971 972 973 974 975 976 977 978 979 | |
can_allocate
can_allocate(size: int, stream: Optional[int] = None) -> bool
Check if allocation is possible without actually allocating
Source code in ures/memory/allocator.py
981 982 983 984 985 986 987 | |
get_memory_info
get_memory_info() -> Dict[str, Any]
Get current memory status information
Source code in ures/memory/allocator.py
989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 | |
get_allocator_statistics
get_allocator_statistics() -> Dict[str, Dict[str, Any]]
Get statistics for all allocators
Source code in ures/memory/allocator.py
1007 1008 1009 1010 1011 1012 | |
reset_device
reset_device()
Reset device to initial state
Source code in ures/memory/allocator.py
1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 | |
simulate_workload
simulate_workload(num_operations: int = 100, size_range: Tuple[int, int] = (64, 4096), free_probability: float = 0.3) -> Dict[str, Any]
Simulate a random workload
Source code in ures/memory/allocator.py
1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 | |
print_status
print_status()
Print current device status
Source code in ures/memory/allocator.py
1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 | |