1- # SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
1+ # SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
22# SPDX-License-Identifier: Apache-2.0
33
44"""
12125. Hash/equality contract compliance (if a == b, then hash(a) must equal hash(b))
1313"""
1414
15- from cuda .core import Device
15+ import pytest
16+ from cuda .core import Device , LaunchConfig , Program
1617from cuda .core ._stream import Stream , StreamOptions
1718
19+ # ============================================================================
20+ # Fixtures for parameterized tests
21+ # ============================================================================
22+
23+
24+ @pytest .fixture
25+ def sample_device (init_cuda ):
26+ return Device ()
27+
28+
29+ @pytest .fixture
30+ def sample_stream (sample_device ):
31+ return sample_device .create_stream ()
32+
33+
34+ @pytest .fixture
35+ def sample_event (sample_device ):
36+ return sample_device .create_event ()
37+
38+
39+ @pytest .fixture
40+ def sample_context (sample_device ):
41+ return sample_device .context
42+
43+
44+ @pytest .fixture
45+ def sample_buffer (sample_device ):
46+ return sample_device .allocate (1024 )
47+
48+
49+ @pytest .fixture
50+ def sample_launch_config ():
51+ return LaunchConfig (grid = (1 ,), block = (1 ,))
52+
53+
54+ @pytest .fixture
55+ def sample_object_code (init_cuda ):
56+ prog = Program ('extern "C" __global__ void test_kernel() {}' , "c++" )
57+ return prog .compile ("cubin" )
58+
59+
60+ @pytest .fixture
61+ def sample_kernel (sample_object_code ):
62+ return sample_object_code .get_kernel ("test_kernel" )
63+
64+
65+ # All hashable classes
66+ HASHABLE = [
67+ "sample_device" ,
68+ "sample_stream" ,
69+ "sample_event" ,
70+ "sample_context" ,
71+ "sample_buffer" ,
72+ "sample_launch_config" ,
73+ "sample_object_code" ,
74+ "sample_kernel" ,
75+ ]
76+
77+
78+ # ============================================================================
79+ # Parameterized Hash Tests
80+ # ============================================================================
81+
82+
83+ @pytest .mark .parametrize ("fixture_name" , HASHABLE )
84+ def test_hash_consistency (fixture_name , request ):
85+ """Hash of same object is consistent across calls."""
86+ obj = request .getfixturevalue (fixture_name )
87+ assert hash (obj ) == hash (obj )
88+
89+
90+ @pytest .mark .parametrize ("fixture_name" , HASHABLE )
91+ def test_set_membership (fixture_name , request ):
92+ """Objects work correctly in sets."""
93+ obj = request .getfixturevalue (fixture_name )
94+ s = {obj }
95+ assert obj in s
96+ assert len (s ) == 1
97+
98+
99+ @pytest .mark .parametrize ("fixture_name" , HASHABLE )
100+ def test_dict_key (fixture_name , request ):
101+ """Objects work correctly as dict keys."""
102+ obj = request .getfixturevalue (fixture_name )
103+ d = {obj : "value" }
104+ assert d [obj ] == "value"
105+
106+
18107# ============================================================================
19108# Integration Tests
20109# ============================================================================
21110
22111
23- def test_hash_type_disambiguation_and_mixed_dict (init_cuda ):
24- """Test that hash salt (type(self)) prevents collisions between different types
25- and that different object types can coexist in dictionaries.
112+ def test_mixed_type_dict (init_cuda ):
113+ """Test that different object types can coexist in dictionaries.
26114
27- This test validates that:
28- 1. Including type(self) in the hash calculation ensures different types with
29- potentially similar underlying values (like monotonically increasing handles
30- or IDs) produce different hashes and don't collide.
31- 2. Different object types can be used together in the same dictionary without
32- conflicts.
115+ Since each CUDA handle type has unique values within its type (handles are
116+ memory addresses or unique identifiers), hash collisions between different
117+ types are unlikely in practice.
33118 """
34119 device = Device (0 )
35120 device .set_current ()
@@ -42,10 +127,7 @@ def test_hash_type_disambiguation_and_mixed_dict(init_cuda):
42127 # Test 1: Verify all hashes are unique (no collisions between different types)
43128 hashes = {hash (device ), hash (stream ), hash (event ), hash (context )}
44129
45- assert len (hashes ) == 4 , (
46- f"Hash collision detected! Expected 4 unique hashes, got { len (hashes )} . "
47- f"This indicates the type salt is not working correctly."
48- )
130+ assert len (hashes ) == 4 , f"Hash collision detected! Expected 4 unique hashes, got { len (hashes )} . "
49131
50132 # Test 2: Verify all types can coexist in same dict without conflicts
51133 mixed_cache = {stream : "stream_data" , event : "event_data" , context : "context_data" , device : "device_data" }
0 commit comments