// MultipleGPU.cpp : Defines the entry point for the console application.
//

/*
 * Copyright 1993-2009 NVIDIA Corporation.  All rights reserved.
 *
 * NVIDIA Corporation and its licensors retain all intellectual property and 
 * proprietary rights in and to this software and related documentation and 
 * any modifications thereto.  Any use, reproduction, disclosure, or distribution 
 * of this software and related documentation without an express license 
 * agreement from NVIDIA Corporation is strictly prohibited.
 * 
 */

#include <stdio.h>
#include <stdlib.h>

//CUDA
#include <cuda.h>
#include <cuda_runtime.h>
#include <device_launch_parameters.h> 
//OpenMP
#include <omp.h>

int main (void){
	int num_gpus = 0;

	cudaGetDeviceCount(&num_gpus);//How many devices are there?
	if(num_gpus < 1) 
	{
		printf("There are not enabled CUDA devices...\n");
		return 1;
	}
	printf("Number of Host CPUs:\t%d\n", omp_get_num_procs());
    printf("Number of Devices CUDA:\t%d\n", num_gpus);
	for(int i = 0; i < num_gpus; i++)
    {
        cudaDeviceProp dprop;
        cudaGetDeviceProperties(&dprop, i);
		printf("   %d: %s\n", i, dprop.name);
    }
	printf("---------------------------\n");
	printf("---------------------------\n");

	omp_set_num_threads(num_gpus);//Creating threads in the host, many as GPUs
	
#pragma omp parallel
	{
		unsigned int cpu_thread_id = omp_get_thread_num();
		unsigned int num_cpu_threads = omp_get_num_threads();
		int gpu_id = -1;
		cudaSetDevice(cpu_thread_id % num_gpus);
		cudaGetDevice(&gpu_id);
		printf("CPU thread %d (of %d) uses CUDA device %d\n", 
			   cpu_thread_id, num_cpu_threads, gpu_id);
	}
	printf("---------------------------\n");
	return(0);
}



