xlog_cuda_tests/categories/
c01_toolchain.rs1use crate::harness::{CategoryResult, TestContext, TestResult};
11use std::time::Instant;
12use xlog_cuda::{join_kernels, JOIN_MODULE};
13
14pub fn run_all(ctx: &TestContext) -> CategoryResult {
16 let mut results = CategoryResult::new("c01_toolchain");
17 let start = Instant::now();
18
19 results.add_result(test_ptx_loads_successfully(ctx));
20 results.add_result(test_compute_capability_check(ctx));
21 results.add_result(test_kernel_function_resolution(ctx));
22 results.add_result(test_ptx_module_attributes(ctx));
23 results.add_result(test_repeated_jit_compilation(ctx));
24
25 results.set_duration(start.elapsed());
26 results
27}
28
29fn test_ptx_loads_successfully(ctx: &TestContext) -> TestResult {
35 let start = Instant::now();
36
37 if let Err(e) = ctx.sync_and_check() {
41 return TestResult::error(
42 "test_ptx_loads_successfully",
43 start.elapsed(),
44 format!("Device sync after PTX load failed: {}", e),
45 );
46 }
47
48 let device_ordinal = ctx.device.ordinal();
50 if device_ordinal > 100 {
51 return TestResult::error(
53 "test_ptx_loads_successfully",
54 start.elapsed(),
55 format!("Invalid device ordinal: {}", device_ordinal),
56 );
57 }
58
59 TestResult::passed("test_ptx_loads_successfully", start.elapsed())
60}
61
62fn test_compute_capability_check(ctx: &TestContext) -> TestResult {
67 let start = Instant::now();
68
69 let (major, minor) = match ctx.compute_capability() {
70 Ok(v) => v,
71 Err(e) => {
72 return TestResult::error(
73 "test_compute_capability_check",
74 start.elapsed(),
75 format!("Failed to query compute capability: {}", e),
76 );
77 }
78 };
79
80 let meets_minimum = major >= 7;
83
84 if !meets_minimum {
85 return TestResult::error(
86 "test_compute_capability_check",
87 start.elapsed(),
88 format!(
89 "Compute capability {}.{} does not meet minimum sm_70 requirement",
90 major, minor
91 ),
92 );
93 }
94
95 if let Err(e) = ctx.sync_and_check() {
96 return TestResult::error(
97 "test_compute_capability_check",
98 start.elapsed(),
99 format!("Sync failed: {}", e),
100 );
101 }
102
103 TestResult::passed("test_compute_capability_check", start.elapsed())
104}
105
106fn test_kernel_function_resolution(ctx: &TestContext) -> TestResult {
112 let start = Instant::now();
113
114 let device = ctx.device.inner();
115
116 let mut total_functions = 0;
117 let mut resolved_functions = 0;
118
119 for spec in xlog_cuda::kernel_manifest_data::KERNEL_MODULES {
120 let module_name = spec.module_name;
121
122 for entry in spec.kernels {
123 total_functions += 1;
124 if device.get_func(module_name, entry).is_some() {
125 resolved_functions += 1;
126 } else {
127 return TestResult::error(
128 "test_kernel_function_resolution",
129 start.elapsed(),
130 format!(
131 "{}: failed to resolve canonical kernel function '{}' from module '{}'",
132 spec.cu_name, entry, module_name
133 ),
134 );
135 }
136 }
137 }
138
139 if let Err(e) = ctx.sync_and_check() {
140 return TestResult::error(
141 "test_kernel_function_resolution",
142 start.elapsed(),
143 format!("Sync failed after function resolution: {}", e),
144 );
145 }
146
147 if resolved_functions != total_functions {
148 return TestResult::error(
149 "test_kernel_function_resolution",
150 start.elapsed(),
151 format!(
152 "Not all functions resolved: {}/{}",
153 resolved_functions, total_functions
154 ),
155 );
156 }
157
158 TestResult::passed("test_kernel_function_resolution", start.elapsed())
159}
160
161fn test_ptx_module_attributes(ctx: &TestContext) -> TestResult {
167 let start = Instant::now();
168
169 let num_elements = 16;
171 let test_values: Vec<u64> = vec![u64::MAX; num_elements];
172
173 let mut gpu_buffer = match ctx.memory.alloc::<u64>(num_elements) {
175 Ok(buf) => buf,
176 Err(e) => {
177 return TestResult::error(
178 "test_ptx_module_attributes",
179 start.elapsed(),
180 format!("Failed to allocate GPU buffer: {}", e),
181 );
182 }
183 };
184
185 if let Err(e) = ctx
187 .device
188 .inner()
189 .htod_sync_copy_into(&test_values, &mut gpu_buffer)
190 {
191 return TestResult::error(
192 "test_ptx_module_attributes",
193 start.elapsed(),
194 format!("Failed to upload data to GPU: {}", e),
195 );
196 }
197
198 if let Err(e) = ctx.sync_and_check() {
200 return TestResult::error(
201 "test_ptx_module_attributes",
202 start.elapsed(),
203 format!("Sync failed after upload: {}", e),
204 );
205 }
206
207 let downloaded: Vec<u64> = match ctx.device.inner().dtoh_sync_copy(&gpu_buffer) {
209 Ok(data) => data,
210 Err(e) => {
211 return TestResult::error(
212 "test_ptx_module_attributes",
213 start.elapsed(),
214 format!("Failed to download data from GPU: {}", e),
215 );
216 }
217 };
218
219 for (i, &val) in downloaded.iter().enumerate() {
221 if val != u64::MAX {
222 return TestResult::error(
223 "test_ptx_module_attributes",
224 start.elapsed(),
225 format!(
226 "64-bit value mismatch at index {}: expected {}, got {}",
227 i,
228 u64::MAX,
229 val
230 ),
231 );
232 }
233 }
234
235 let patterns: Vec<u64> = vec![
237 0x0000_0000_0000_0001,
238 0x0000_0000_FFFF_FFFF,
239 0xFFFF_FFFF_0000_0000,
240 0x8000_0000_0000_0000,
241 0xDEAD_BEEF_CAFE_BABE,
242 0x0123_4567_89AB_CDEF,
243 ];
244
245 let mut pattern_buffer = match ctx.memory.alloc::<u64>(patterns.len()) {
246 Ok(buf) => buf,
247 Err(e) => {
248 return TestResult::error(
249 "test_ptx_module_attributes",
250 start.elapsed(),
251 format!("Failed to allocate pattern buffer: {}", e),
252 );
253 }
254 };
255
256 if let Err(e) = ctx
257 .device
258 .inner()
259 .htod_sync_copy_into(&patterns, &mut pattern_buffer)
260 {
261 return TestResult::error(
262 "test_ptx_module_attributes",
263 start.elapsed(),
264 format!("Failed to upload patterns: {}", e),
265 );
266 }
267
268 let downloaded_patterns: Vec<u64> = match ctx.device.inner().dtoh_sync_copy(&pattern_buffer) {
269 Ok(data) => data,
270 Err(e) => {
271 return TestResult::error(
272 "test_ptx_module_attributes",
273 start.elapsed(),
274 format!("Failed to download patterns: {}", e),
275 );
276 }
277 };
278
279 for (i, (&expected, &actual)) in patterns.iter().zip(downloaded_patterns.iter()).enumerate() {
280 if expected != actual {
281 return TestResult::error(
282 "test_ptx_module_attributes",
283 start.elapsed(),
284 format!(
285 "64-bit pattern mismatch at index {}: expected 0x{:016X}, got 0x{:016X}",
286 i, expected, actual
287 ),
288 );
289 }
290 }
291
292 if let Err(e) = ctx.sync_and_check() {
293 return TestResult::error(
294 "test_ptx_module_attributes",
295 start.elapsed(),
296 format!("Final sync failed: {}", e),
297 );
298 }
299
300 TestResult::passed("test_ptx_module_attributes", start.elapsed())
301}
302
303fn test_repeated_jit_compilation(ctx: &TestContext) -> TestResult {
309 let start = Instant::now();
310
311 const NUM_ITERATIONS: usize = 15;
312 const BUFFER_SIZE: usize = 1024;
313
314 for iteration in 0..NUM_ITERATIONS {
315 let test_data: Vec<u32> = (0..BUFFER_SIZE)
317 .map(|i| (i + iteration * 1000) as u32)
318 .collect();
319
320 let mut gpu_buffer = match ctx.memory.alloc::<u32>(BUFFER_SIZE) {
322 Ok(buf) => buf,
323 Err(e) => {
324 return TestResult::error(
325 "test_repeated_jit_compilation",
326 start.elapsed(),
327 format!("Allocation failed at iteration {}: {}", iteration, e),
328 );
329 }
330 };
331
332 if let Err(e) = ctx
334 .device
335 .inner()
336 .htod_sync_copy_into(&test_data, &mut gpu_buffer)
337 {
338 return TestResult::error(
339 "test_repeated_jit_compilation",
340 start.elapsed(),
341 format!("Upload failed at iteration {}: {}", iteration, e),
342 );
343 }
344
345 let downloaded: Vec<u32> = match ctx.device.inner().dtoh_sync_copy(&gpu_buffer) {
347 Ok(data) => data,
348 Err(e) => {
349 return TestResult::error(
350 "test_repeated_jit_compilation",
351 start.elapsed(),
352 format!("Download failed at iteration {}: {}", iteration, e),
353 );
354 }
355 };
356
357 for (i, (&expected, &actual)) in test_data.iter().zip(downloaded.iter()).enumerate() {
359 if expected != actual {
360 return TestResult::error(
361 "test_repeated_jit_compilation",
362 start.elapsed(),
363 format!(
364 "Data mismatch at iteration {}, index {}: expected {}, got {}",
365 iteration, i, expected, actual
366 ),
367 );
368 }
369 }
370
371 if let Err(e) = ctx.sync_and_check() {
373 return TestResult::error(
374 "test_repeated_jit_compilation",
375 start.elapsed(),
376 format!("Sync failed at iteration {}: {}", iteration, e),
377 );
378 }
379
380 }
382
383 let device = ctx.device.inner();
385 if device
386 .get_func(JOIN_MODULE, join_kernels::HASH_JOIN_BUILD)
387 .is_none()
388 {
389 return TestResult::error(
390 "test_repeated_jit_compilation",
391 start.elapsed(),
392 "Failed to resolve kernel after repeated iterations".to_string(),
393 );
394 }
395
396 if let Err(e) = ctx.sync_and_check() {
397 return TestResult::error(
398 "test_repeated_jit_compilation",
399 start.elapsed(),
400 format!("Final sync failed: {}", e),
401 );
402 }
403
404 TestResult::passed("test_repeated_jit_compilation", start.elapsed())
405}