@@ -125,6 +125,8 @@ pub fn error_correction<T, U, V>(
125125 U : AsRef < Path > + Send + Sync ,
126126 V : AsRef < Path > + Send ,
127127{
128+ let devices = prepare_cuda_devices ( & devices) ;
129+
128130 tch:: set_num_threads ( 1 ) ;
129131
130132 let ( core, neighbour) = read_cluster ( & cluster_path) ;
@@ -313,3 +315,46 @@ fn write_sequence<W: Write>(
313315
314316 Ok ( ( ) )
315317}
318+
319+ fn prepare_cuda_devices ( devices : & [ usize ] ) -> Vec < usize > {
320+ // Try to read CUDA_VISIBLE_DEVICES
321+ if let Ok ( cvd) = std:: env:: var ( "CUDA_VISIBLE_DEVICES" ) {
322+ // CUDA_VISIBLE_DEVICES is set, map real device IDs to logical
323+ let map: Vec < usize > = cvd
324+ . split ( ',' )
325+ . filter_map ( |s| s. trim ( ) . parse :: < usize > ( ) . ok ( ) )
326+ . collect ( ) ;
327+
328+ // For each requested device, find its index in the mask
329+ let mapped: Vec < usize > = devices
330+ . iter ( )
331+ . map ( |dev| {
332+ map. iter ( )
333+ . position ( |& d| d == * dev)
334+ . unwrap_or_else ( || panic ! ( "Device {} not in CUDA_VISIBLE_DEVICES={}" , dev, cvd) )
335+ } )
336+ . collect ( ) ;
337+
338+ println ! (
339+ "Using CUDA_VISIBLE_DEVICES='{}'; mapped devices {:?} to logical IDs {:?}" ,
340+ cvd, devices, mapped
341+ ) ;
342+ mapped
343+ } else {
344+ // Not set; set CUDA_VISIBLE_DEVICES to requested devices
345+ let device_list = devices
346+ . iter ( )
347+ . map ( |d| d. to_string ( ) )
348+ . collect :: < Vec < _ > > ( )
349+ . join ( "," ) ;
350+ std:: env:: set_var ( "CUDA_VISIBLE_DEVICES" , & device_list) ;
351+
352+ println ! (
353+ "Set CUDA_VISIBLE_DEVICES='{}' (for requested devices {:?})" ,
354+ device_list, devices
355+ ) ;
356+
357+ // Logical IDs match order of requested devices
358+ ( 0 ..devices. len ( ) ) . collect ( )
359+ }
360+ }
0 commit comments