nd4j-backends/nd4j-backend-impls/nd4j-cuda/src/main/java/org/nd4j/jita/concurrency/CudaAffinityManager.java
protected Integer getNextDevice(long threadId) {
        Integer device = null;
        if (!CudaEnvironment.getInstance().getConfiguration().isForcedSingleGPU() && getNumberOfDevices() > 0) {
            // simple round-robin here
            synchronized (this) {
                device = CudaEnvironment.getInstance().getConfiguration().getAvailableDevices().get(devPtr.getAndIncrement());

                // We check only for number of entries here, not their actual values
                if (devPtr.get() >= CudaEnvironment.getInstance().getConfiguration().getAvailableDevices().size())
                    devPtr.set(0);

                logger.debug("Mapping thread [{}] to device [{}], out of [{}] devices...", threadId, device,
                        CudaEnvironment.getInstance().getConfiguration().getAvailableDevices().size());
            }
        } else {
            device = CudaEnvironment.getInstance().getConfiguration().getAvailableDevices().get(0);
            logger.debug("Single device is forced, mapping to device [{}]", device);
        }

        return device;
    }
protected Integer getNextDevice(long threadId) {
        Integer device = null;
        if (!CudaEnvironment.getInstance().getConfiguration().isForcedSingleGPU() && getNumberOfDevices() > 0) {
            // simple round-robin here
            synchronized (this) {
                device = CudaEnvironment.getInstance().getConfiguration().getAvailableDevices().get(devPtr.getAndIncrement());

                // We check only for number of entries here, not their actual values
                if (devPtr.get() >= CudaEnvironment.getInstance().getConfiguration().getAvailableDevices().size())
                    devPtr.set(0);

                logger.debug("Mapping thread [{}] to device [{}], out of [{}] devices...", threadId, device,
                        CudaEnvironment.getInstance().getConfiguration().getAvailableDevices().size());
            }
        } else {
            device = CudaEnvironment.getInstance().getConfiguration().getAvailableDevices().get(0);
            logger.debug("Single device is forced, mapping to device [{}]", device);
        }

        return device;
    }
protected Integer getNextDevice ( long threadId ) { Integer device = null ; if ( ! CudaEnvironment . getInstance ( ) . getConfiguration ( ) . isForcedSingleGPU ( ) && getNumberOfDevices ( ) > 0 ) { // simple round-robin here synchronized ( this ) { device = CudaEnvironment . getInstance ( ) . getConfiguration ( ) . getAvailableDevices ( ) . get ( devPtr . getAndIncrement ( ) ) ; // We check only for number of entries here, not their actual values if ( devPtr . get ( ) >= CudaEnvironment . getInstance ( ) . getConfiguration ( ) . getAvailableDevices ( ) . size ( ) ) devPtr . set ( 0 ) ; logger . debug ( "Mapping thread [{}] to device [{}], out of [{}] devices..." , threadId , device , CudaEnvironment . getInstance ( ) . getConfiguration ( ) . getAvailableDevices ( ) . size ( ) ) ; } } else { device = CudaEnvironment . getInstance ( ) . getConfiguration ( ) . getAvailableDevices ( ) . get ( 0 ) ; logger . debug ( "Single device is forced, mapping to device [{}]" , device ) ; } return device ; }
This method returns device id available. Round-robin balancing used here.

@param threadId this parameter can be anything, it's used for logging only.
@return
This method returns device id available . Round - robin balancing used here .