// Suma_Uno.cu : Defines the entry point for the console application.
//


#include <stdio.h>
#include <math.h>
#include <cutil.h>

// Suma 1 a cada elemento del vector
__global__  void suma1(float * d_vector, int N)
{
	int index = blockIdx.x*blockDim.x + threadIdx.x;
	if(index<N){
		//printf("\n%d ", threadIdx.x);
		d_vector[index] += 1.0f;
	}
}

int main(void)
{
	int lengthvector = 24; //Tamaņo del vector
	int block_size=8;
	dim3 threads(block_size,1,1);  //Hilos por bloque 
	int n_blocks=lengthvector/threads.x;
	//int n_blocks=lengthvector/threads.x+(lengthvector % threads.x == 0 ? 0:1);			
	dim3 grid(n_blocks,1,1); //Malla de bloques de hilos

	size_t memSize = lengthvector*sizeof(float);

	// Creamos memoria en el host
	float* vector_h = (float*) malloc(memSize);

	// Inicializamos el vector 
	for(int i=0;i<lengthvector;i++) {
		vector_h[i] = (float)(i%10);
	}
	printf("Antes: \n");
	for(int i=0;i<lengthvector;i++) { // Desplegamos el vector
		printf("%f ", vector_h[i]);
	}

	float *vector_d;  // vector en el device

	// Creamos memoria en el device
	CUDA_SAFE_CALL(cudaMalloc((void**)&vector_d, memSize ));
	

	// Copiamos memoria del host al device 
	CUDA_SAFE_CALL(cudaMemcpy(vector_d, vector_h, memSize, cudaMemcpyHostToDevice));

	// Llamamos al kernel
	
	suma1<<<grid,threads>>> (vector_d,lengthvector);

	// Copiamos memoria del device al host 
	CUDA_SAFE_CALL(cudaMemcpy(vector_h, vector_d, memSize, cudaMemcpyDeviceToHost));

	// Checamos si se generķ algun error...
	CUT_CHECK_ERROR("Error...");

	printf("\n\nDespues: \n");
	for(int i=0;i<lengthvector;i++) { // Desplegamos el vector
		printf("%f ", vector_h[i]);
	}

	// Liberamos la memoria en el device
	CUDA_SAFE_CALL(cudaFree(vector_d));
	// Liberamos la memoria en el host
	free(vector_h);
	system("pause");
	return(0);
}

