Skip to content

Commit fc6d176

Browse files
committed
update tests
1 parent a860436 commit fc6d176

File tree

8 files changed

+564
-0
lines changed

8 files changed

+564
-0
lines changed

cuda_core/tests/test_context.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from cuda.core.experimental._context import Context
2+
3+
def test_context_initialization():
4+
try:
5+
context = Context()
6+
except NotImplementedError as e:
7+
assert True
8+
else:
9+
assert False, "Expected NotImplementedError was not raised"

cuda_core/tests/test_device.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
from cuda import cuda, cudart
2+
from cuda.core.experimental._device import Device
3+
from cuda.core.experimental._utils import handle_return, ComputeCapability, CUDAError, \
4+
precondition
5+
import pytest
6+
7+
@pytest.fixture(scope='module')
8+
def init_cuda():
9+
Device().set_current()
10+
11+
def test_device_initialization():
12+
device = Device()
13+
assert device is not None
14+
15+
def test_device_repr():
16+
device = Device()
17+
assert str(device).startswith('<Device 0')
18+
19+
def test_device_alloc():
20+
device = Device()
21+
device.set_current()
22+
buffer = device.allocate(1024)
23+
device.sync()
24+
assert buffer.handle != 0
25+
assert buffer.size == 1024
26+
assert buffer.device_id == 0
27+
28+
def test_device_set_current():
29+
device = Device()
30+
device.set_current()
31+
32+
def test_device_create_stream():
33+
device = Device()
34+
stream = device.create_stream()
35+
assert stream is not None
36+
37+
def test_pci_bus_id():
38+
device = Device()
39+
bus_id = handle_return(cudart.cudaDeviceGetPCIBusId(13, device.device_id))
40+
assert device.pci_bus_id == bus_id[:12].decode()
41+
42+
def test_uuid():
43+
device = Device()
44+
driver_ver = handle_return(cuda.cuDriverGetVersion())
45+
if driver_ver >= 11040:
46+
uuid = handle_return(cuda.cuDeviceGetUuid_v2(device.device_id))
47+
else:
48+
uuid = handle_return(cuda.cuDeviceGetUuid(device.device_id))
49+
uuid = uuid.bytes.hex()
50+
expected_uuid = f"{uuid[:8]}-{uuid[8:12]}-{uuid[12:16]}-{uuid[16:20]}-{uuid[20:]}"
51+
assert device.uuid == expected_uuid
52+
53+
def test_name():
54+
device = Device()
55+
name = handle_return(cuda.cuDeviceGetName(128, device.device_id))
56+
name = name.split(b'\0')[0]
57+
assert device.name == name.decode()
58+
59+
def test_compute_capability():
60+
device = Device()
61+
major = handle_return(cudart.cudaDeviceGetAttribute(
62+
cudart.cudaDeviceAttr.cudaDevAttrComputeCapabilityMajor, device.device_id))
63+
minor = handle_return(cudart.cudaDeviceGetAttribute(
64+
cudart.cudaDeviceAttr.cudaDevAttrComputeCapabilityMinor, device.device_id))
65+
expected_cc = ComputeCapability(major, minor)
66+
assert device.compute_capability == expected_cc

cuda_core/tests/test_event.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
from cuda import cuda
2+
from cuda.core.experimental._event import EventOptions, Event
3+
from cuda.core.experimental._utils import handle_return
4+
5+
def test_is_timing_disabled():
6+
options = EventOptions(enable_timing=False)
7+
event = Event._init(options)
8+
assert event.is_timing_disabled == True
9+
10+
def test_is_sync_busy_waited():
11+
options = EventOptions(busy_waited_sync=True)
12+
event = Event._init(options)
13+
assert event.is_sync_busy_waited == True
14+
15+
def test_is_ipc_supported():
16+
options = EventOptions(support_ipc=True)
17+
try:
18+
event = Event._init(options)
19+
except NotImplementedError:
20+
assert True
21+
else:
22+
assert False
23+
24+
def test_sync():
25+
options = EventOptions()
26+
event = Event._init(options)
27+
event.sync()
28+
assert event.is_done == True
29+
30+
def test_is_done():
31+
options = EventOptions()
32+
event = Event._init(options)
33+
assert event.is_done == True
34+
35+
def test_handle():
36+
options = EventOptions()
37+
event = Event._init(options)
38+
assert isinstance(event.handle, int)

cuda_core/tests/test_launcher.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
from cuda.core.experimental._launcher import LaunchConfig
2+
from cuda.core.experimental._stream import Stream
3+
from cuda.core.experimental._device import Device
4+
from cuda.core.experimental._utils import handle_return
5+
from cuda import cuda
6+
7+
def test_launch_config_init():
8+
config = LaunchConfig(grid=(1, 1, 1), block=(1, 1, 1), stream=None, shmem_size=0)
9+
assert config.grid == (1, 1, 1)
10+
assert config.block == (1, 1, 1)
11+
assert config.stream is None
12+
assert config.shmem_size == 0
13+
14+
config = LaunchConfig(grid=(2, 2, 2), block=(2, 2, 2), stream=Device().create_stream(), shmem_size=1024)
15+
assert config.grid == (2, 2, 2)
16+
assert config.block == (2, 2, 2)
17+
assert isinstance(config.stream, Stream)
18+
assert config.shmem_size == 1024
19+
20+
def test_launch_config_cast_to_3_tuple():
21+
config = LaunchConfig(grid=1, block=1)
22+
assert config._cast_to_3_tuple(1) == (1, 1, 1)
23+
assert config._cast_to_3_tuple((1, 2)) == (1, 2, 1)
24+
assert config._cast_to_3_tuple((1, 2, 3)) == (1, 2, 3)
25+
26+
# Edge cases
27+
assert config._cast_to_3_tuple(999) == (999, 1, 1)
28+
assert config._cast_to_3_tuple((999, 888)) == (999, 888, 1)
29+
assert config._cast_to_3_tuple((999, 888, 777)) == (999, 888, 777)
30+
31+
def test_launch_config_invalid_values():
32+
try:
33+
LaunchConfig(grid=0, block=1)
34+
except ValueError:
35+
assert True
36+
else:
37+
assert False
38+
39+
try:
40+
LaunchConfig(grid=(0, 1), block=1)
41+
except ValueError:
42+
assert True
43+
else:
44+
assert False
45+
46+
try:
47+
LaunchConfig(grid=(1, 1, 1), block=0)
48+
except ValueError:
49+
assert True
50+
else:
51+
assert False
52+
53+
try:
54+
LaunchConfig(grid=(1, 1, 1), block=(0, 1))
55+
except ValueError:
56+
assert True
57+
else:
58+
assert False
59+
60+
def test_launch_config_stream():
61+
stream = Device().create_stream()
62+
config = LaunchConfig(grid=(1, 1, 1), block=(1, 1, 1), stream=stream, shmem_size=0)
63+
assert config.stream == stream
64+
65+
try:
66+
LaunchConfig(grid=(1, 1, 1), block=(1, 1, 1), stream="invalid_stream", shmem_size=0)
67+
except ValueError:
68+
assert True
69+
else:
70+
assert False
71+
72+
def test_launch_config_shmem_size():
73+
config = LaunchConfig(grid=(1, 1, 1), block=(1, 1, 1), stream=None, shmem_size=2048)
74+
assert config.shmem_size == 2048
75+
76+
config = LaunchConfig(grid=(1, 1, 1), block=(1, 1, 1), stream=None)
77+
assert config.shmem_size == 0

cuda_core/tests/test_memory.py

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
# FILE: test_memory.py
2+
3+
from cuda.core.experimental._memory import Buffer, MemoryResource
4+
from cuda.core.experimental._device import Device
5+
from cuda import cuda
6+
from cuda.core.experimental._utils import handle_return
7+
import ctypes
8+
9+
@pytest.fixture(scope='module')
10+
def init_cuda():
11+
Device().set_current()
12+
13+
class DummyDeviceMemoryResource(MemoryResource):
14+
def __init__(self, device):
15+
self.device = device
16+
pass
17+
18+
def allocate(self, size, stream=None) -> Buffer:
19+
ptr = handle_return(cuda.cuMemAlloc(size))
20+
return Buffer(ptr=ptr, size=size, mr=self)
21+
22+
def deallocate(self, ptr, size, stream=None):
23+
cuda.cuMemFree(ptr)
24+
25+
@property
26+
def is_device_accessible(self) -> bool:
27+
return True
28+
29+
@property
30+
def is_host_accessible(self) -> bool:
31+
return False
32+
33+
@property
34+
def device_id(self) -> int:
35+
return 0
36+
37+
class DummyHostMemoryResource(MemoryResource):
38+
def __init__(self):
39+
pass
40+
41+
def allocate(self, size, stream=None) -> Buffer:
42+
# Allocate a ctypes buffer of size `size`
43+
ptr = (ctypes.c_byte * size)()
44+
return Buffer(ptr=ptr, size=size, mr=self)
45+
46+
def deallocate(self, ptr, size, stream=None):
47+
#the memory is deallocated per the ctypes deallocation at garbage collection time
48+
pass
49+
50+
@property
51+
def is_device_accessible(self) -> bool:
52+
return False
53+
54+
@property
55+
def is_host_accessible(self) -> bool:
56+
return True
57+
58+
@property
59+
def device_id(self) -> int:
60+
raise RuntimeError("the pinned memory resource is not bound to any GPU")
61+
62+
class DummyUnifiedMemoryResource(MemoryResource):
63+
def __init__(self, device):
64+
self.device = device
65+
pass
66+
67+
def allocate(self, size, stream=None) -> Buffer:
68+
ptr = handle_return(cuda.cuMemAllocManaged(size, cuda.CUmemAttach_flags.CU_MEM_ATTACH_GLOBAL.value))
69+
return Buffer(ptr=ptr, size=size, mr=self)
70+
71+
def deallocate(self, ptr, size, stream=None):
72+
cuda.cuMemFree(ptr)
73+
74+
@property
75+
def is_device_accessible(self) -> bool:
76+
return True
77+
78+
@property
79+
def is_host_accessible(self) -> bool:
80+
return True
81+
82+
@property
83+
def device_id(self) -> int:
84+
return 0
85+
86+
class DummyPinnedMemoryResource(MemoryResource):
87+
def __init__(self, device):
88+
self.device = device
89+
pass
90+
91+
def allocate(self, size, stream=None) -> Buffer:
92+
ptr = handle_return(cuda.cuMemAllocHost(size))
93+
return Buffer(ptr=ptr, size=size, mr=self)
94+
95+
def deallocate(self, ptr, size, stream=None):
96+
cuda.cuMemFreeHost(ptr)
97+
98+
@property
99+
def is_device_accessible(self) -> bool:
100+
return True
101+
102+
@property
103+
def is_host_accessible(self) -> bool:
104+
return True
105+
106+
@property
107+
def device_id(self) -> int:
108+
raise RuntimeError("the pinned memory resource is not bound to any GPU")
109+
110+
def buffer_initialization(dummy_mr : MemoryResource):
111+
buffer = dummy_mr.allocate(size=1024)
112+
assert buffer.handle != 0
113+
assert buffer.size == 1024
114+
assert buffer.memory_resource == dummy_mr
115+
assert buffer.is_device_accessible == dummy_mr.is_device_accessible
116+
assert buffer.is_host_accessible == dummy_mr.is_host_accessible
117+
dummy_mr.deallocate(buffer.handle, buffer.size)
118+
119+
def test_buffer_initialization():
120+
device = Device()
121+
device.set_current()
122+
buffer_initialization(DummyDeviceMemoryResource(device))
123+
buffer_initialization(DummyHostMemoryResource())
124+
buffer_initialization(DummyUnifiedMemoryResource(device))
125+
buffer_initialization(DummyPinnedMemoryResource(device))
126+
127+
def buffer_copy_to(dummy_mr : MemoryResource, device : Device, check = False):
128+
src_buffer = dummy_mr.allocate(size=1024)
129+
dst_buffer = dummy_mr.allocate(size=1024)
130+
stream = device.create_stream()
131+
132+
if check:
133+
src_ptr = ctypes.cast(src_buffer.handle, ctypes.POINTER(ctypes.c_byte))
134+
for i in range(1024):
135+
src_ptr[i] = ctypes.c_byte(i)
136+
137+
src_buffer.copy_to(dst_buffer, stream=stream)
138+
device.sync()
139+
140+
if check:
141+
dst_ptr = ctypes.cast(dst_buffer.handle, ctypes.POINTER(ctypes.c_byte))
142+
143+
for i in range(10):
144+
assert dst_ptr[i] == src_ptr[i]
145+
146+
dummy_mr.deallocate(src_buffer.handle, src_buffer.size)
147+
dummy_mr.deallocate(dst_buffer.handle, dst_buffer.size)
148+
149+
def test_buffer_copy_to():
150+
device = Device()
151+
device.set_current()
152+
buffer_copy_to(DummyDeviceMemoryResource(device), device)
153+
buffer_copy_to(DummyUnifiedMemoryResource(device), device)
154+
buffer_copy_to(DummyPinnedMemoryResource(device), device, check = True)
155+
156+
def buffer_copy_from(dummy_mr : MemoryResource, device, check = False):
157+
src_buffer = dummy_mr.allocate(size=1024)
158+
dst_buffer = dummy_mr.allocate(size=1024)
159+
stream = device.create_stream()
160+
161+
if check:
162+
src_ptr = ctypes.cast(src_buffer.handle, ctypes.POINTER(ctypes.c_byte))
163+
for i in range(1024):
164+
src_ptr[i] = ctypes.c_byte(i)
165+
166+
dst_buffer.copy_from(src_buffer, stream=stream)
167+
device.sync()
168+
169+
if check:
170+
dst_ptr = ctypes.cast(dst_buffer.handle, ctypes.POINTER(ctypes.c_byte))
171+
172+
for i in range(10):
173+
assert dst_ptr[i] == src_ptr[i]
174+
175+
dummy_mr.deallocate(src_buffer.handle, src_buffer.size)
176+
dummy_mr.deallocate(dst_buffer.handle, dst_buffer.size)
177+
178+
def test_buffer_copy_from():
179+
device = Device()
180+
device.set_current()
181+
buffer_copy_from(DummyDeviceMemoryResource(device), device)
182+
buffer_copy_from(DummyUnifiedMemoryResource(device), device)
183+
buffer_copy_from(DummyPinnedMemoryResource(device), device, check = True)
184+
185+
def buffer_close(dummy_mr : MemoryResource):
186+
buffer = dummy_mr.allocate(size=1024)
187+
buffer.close()
188+
assert buffer.handle == 0
189+
assert buffer.memory_resource == None
190+
191+
def test_buffer_close():
192+
device = Device()
193+
device.set_current()
194+
buffer_close(DummyDeviceMemoryResource(device))
195+
buffer_close(DummyHostMemoryResource())
196+
buffer_close(DummyUnifiedMemoryResource(device))
197+
buffer_close(DummyPinnedMemoryResource(device))
198+
199+
test_buffer_copy_to()

0 commit comments

Comments
 (0)