Skip to content

Commit 60728da

Browse files
committed
reference exposed classes for stats tests
1 parent 9883354 commit 60728da

1 file changed

Lines changed: 33 additions & 80 deletions

File tree

cuda_bindings/tests/test_cufile.py

Lines changed: 33 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -2175,40 +2175,26 @@ def test_get_stats_l1():
21752175
cufile.write(handle, buf_ptr_int, buffer_size, 0, 0)
21762176
cufile.read(handle, buf_ptr_int, buffer_size, 0, 0)
21772177

2178-
# Allocate buffer for L1 statistics
2179-
stats_buffer = ctypes.create_string_buffer(1024) # Allocate sufficient space
2180-
stats_ptr = ctypes.addressof(stats_buffer)
2181-
2178+
# Use the exposed StatsLevel1 class from cufile module
2179+
stats = cufile.StatsLevel1()
2180+
21822181
# Get L1 statistics (basic operation counts)
2183-
cufile.get_stats_l1(stats_ptr)
2184-
2185-
# Define ctypes structure matching CUfileStatsLevel1_t
2186-
class OpCounter(ctypes.Structure):
2187-
_fields_ = [("ok", ctypes.c_uint64), ("err", ctypes.c_uint64)]
2188-
2189-
class StatsL1(ctypes.Structure):
2190-
_fields_ = [
2191-
("read_ops", OpCounter), ("write_ops", OpCounter),
2192-
("hdl_register_ops", OpCounter), ("hdl_deregister_ops", OpCounter),
2193-
("buf_register_ops", OpCounter), ("buf_deregister_ops", OpCounter),
2194-
("read_bytes", ctypes.c_uint64), ("write_bytes", ctypes.c_uint64),
2195-
("read_bw_bytes_per_sec", ctypes.c_uint64), ("write_bw_bytes_per_sec", ctypes.c_uint64),
2196-
("read_lat_avg_us", ctypes.c_uint64), ("write_lat_avg_us", ctypes.c_uint64),
2197-
("read_ops_per_sec", ctypes.c_uint64), ("write_ops_per_sec", ctypes.c_uint64),
2198-
("read_lat_sum_us", ctypes.c_uint64), ("write_lat_sum_us", ctypes.c_uint64),
2199-
]
2200-
2201-
# Cast buffer to structure and examine fields
2202-
stats = ctypes.cast(stats_ptr, ctypes.POINTER(StatsL1)).contents
2182+
cufile.get_stats_l1(stats.ptr)
22032183

22042184
# Verify actual field values
2205-
assert stats.read_ops.ok > 0, f"Expected read operations, got {stats.read_ops.ok}"
2206-
assert stats.write_ops.ok > 0, f"Expected write operations, got {stats.write_ops.ok}"
2207-
assert stats.read_bytes > 0, f"Expected read bytes, got {stats.read_bytes}"
2208-
assert stats.write_bytes > 0, f"Expected write bytes, got {stats.write_bytes}"
2209-
2210-
logging.info(f"Stats: reads={stats.read_ops.ok}, writes={stats.write_ops.ok}, "
2211-
f"read_bytes={stats.read_bytes}, write_bytes={stats.write_bytes}")
2185+
# Access numpy recarray fields: read_ops returns a recarray with 'ok' and 'err' fields
2186+
read_ops_ok = int(stats.read_ops['ok'][0])
2187+
write_ops_ok = int(stats.write_ops['ok'][0])
2188+
read_bytes = int(stats.read_bytes)
2189+
write_bytes = int(stats.write_bytes)
2190+
2191+
assert read_ops_ok > 0, f"Expected read operations, got {read_ops_ok}"
2192+
assert write_ops_ok > 0, f"Expected write operations, got {write_ops_ok}"
2193+
assert read_bytes > 0, f"Expected read bytes, got {read_bytes}"
2194+
assert write_bytes > 0, f"Expected write bytes, got {write_bytes}"
2195+
2196+
logging.info(f"Stats: reads={read_ops_ok}, writes={write_ops_ok}, "
2197+
f"read_bytes={read_bytes}, write_bytes={write_bytes}")
22122198

22132199
# Stop statistics collection
22142200
cufile.stats_stop()
@@ -2286,27 +2272,16 @@ def test_get_stats_l2():
22862272
cufile.write(handle, buf_ptr_int, buffer_size, buffer_size, 0) # Different offset
22872273
cufile.read(handle, buf_ptr_int, buffer_size, buffer_size, 0)
22882274

2289-
# Allocate buffer for L2 statistics
2290-
stats_buffer = ctypes.create_string_buffer(2048) # Larger buffer for detailed stats
2291-
stats_ptr = ctypes.addressof(stats_buffer)
2275+
# Use the exposed StatsLevel2 class from cufile module
2276+
stats = cufile.StatsLevel2()
22922277

22932278
# Get L2 statistics (detailed performance metrics)
2294-
cufile.get_stats_l2(stats_ptr)
2295-
2296-
# Define ctypes structure matching CUfileStatsLevel2_t
2297-
class StatsL2(ctypes.Structure):
2298-
_fields_ = [
2299-
("basic", ctypes.c_byte * 512), # L1 data (simplified)
2300-
("read_size_kb_hist", ctypes.c_uint64 * 32),
2301-
("write_size_kb_hist", ctypes.c_uint64 * 32),
2302-
]
2303-
2304-
# Cast buffer to structure and examine L2-specific fields
2305-
stats = ctypes.cast(stats_ptr, ctypes.POINTER(StatsL2)).contents
2279+
cufile.get_stats_l2(stats.ptr)
23062280

23072281
# Verify L2 histogram fields contain data
2308-
read_hist_total = sum(stats.read_size_kb_hist)
2309-
write_hist_total = sum(stats.write_size_kb_hist)
2282+
# Access numpy array fields: histograms are numpy arrays
2283+
read_hist_total = int(stats.read_size_kb_hist.sum())
2284+
write_hist_total = int(stats.write_size_kb_hist.sum())
23102285
assert read_hist_total > 0 or write_hist_total > 0, "Expected L2 histogram data"
23112286

23122287
logging.info(f"L2 Stats: read_hist_total={read_hist_total}, write_hist_total={write_hist_total}")
@@ -2391,49 +2366,27 @@ def test_get_stats_l3():
23912366
cufile.write(handle, buf_ptr_int, buffer_size // 2, buffer_size * 2, 0) # Partial write
23922367
cufile.read(handle, buf_ptr_int, buffer_size // 2, buffer_size * 2, 0) # Partial read
23932368

2394-
# Allocate buffer for L3 statistics
2395-
stats_buffer = ctypes.create_string_buffer(4096) # Largest buffer for comprehensive stats
2396-
stats_ptr = ctypes.addressof(stats_buffer)
2369+
# Use the exposed StatsLevel3 class from cufile module
2370+
stats = cufile.StatsLevel3()
23972371

23982372
# Get L3 statistics (comprehensive diagnostic data)
2399-
cufile.get_stats_l3(stats_ptr)
2400-
2401-
# Define ctypes structure matching CUfileStatsLevel3_t
2402-
class PerGpuStats(ctypes.Structure):
2403-
_fields_ = [
2404-
("uuid", ctypes.c_char * 16),
2405-
("read_bytes", ctypes.c_uint64),
2406-
("read_bw_bytes_per_sec", ctypes.c_uint64),
2407-
("read_utilization", ctypes.c_uint64),
2408-
("read_duration_us", ctypes.c_uint64),
2409-
("n_total_reads", ctypes.c_uint64),
2410-
("n_p2p_reads", ctypes.c_uint64),
2411-
("n_nvfs_reads", ctypes.c_uint64),
2412-
("n_posix_reads", ctypes.c_uint64),
2413-
]
2414-
2415-
class StatsL3(ctypes.Structure):
2416-
_fields_ = [
2417-
("detailed", ctypes.c_byte * 2048), # L2 data (simplified)
2418-
("num_gpus", ctypes.c_uint32),
2419-
("per_gpu_stats", PerGpuStats * 16),
2420-
]
2421-
2422-
# Cast buffer to structure and examine L3-specific fields
2423-
stats = ctypes.cast(stats_ptr, ctypes.POINTER(StatsL3)).contents
2373+
cufile.get_stats_l3(stats.ptr)
24242374

24252375
# Verify L3-specific fields
2426-
assert stats.num_gpus >= 0, f"Expected valid GPU count, got {stats.num_gpus}"
2376+
num_gpus = int(stats.num_gpus)
2377+
assert num_gpus >= 0, f"Expected valid GPU count, got {num_gpus}"
24272378

24282379
# Check if we have at least one GPU with stats
2380+
# per_gpu_stats is a numpy recarray with shape (16,)
24292381
gpu_with_data = False
2430-
for i in range(min(stats.num_gpus, 16)):
2382+
for i in range(min(num_gpus, 16)):
24312383
gpu_stats = stats.per_gpu_stats[i]
2432-
if gpu_stats.n_total_reads > 0 or gpu_stats.read_bytes > 0:
2384+
# Access scalar values from the recarray element
2385+
if int(gpu_stats['n_total_reads'][0]) > 0 or int(gpu_stats['read_bytes'][0]) > 0:
24332386
gpu_with_data = True
24342387
break
24352388

2436-
logging.info(f"L3 Stats: num_gpus={stats.num_gpus}, gpu_with_data={gpu_with_data}")
2389+
logging.info(f"L3 Stats: num_gpus={num_gpus}, gpu_with_data={gpu_with_data}")
24372390

24382391
# Stop statistics collection
24392392
cufile.stats_stop()

0 commit comments

Comments
 (0)