

#include <stdio.h>

// For the CUDA runtime routines (prefixed with "cuda_")
#include <cuda_runtime.h>
#include <curand.h>
#include <curand_kernel.h>

__global__ void add(int *a, int *b,int n,int r) 
{
	int index = threadIdx.x + blockIdx.x * blockDim.x;
	if(index < n-r && index >= r)
	{
		b[index] = 0;
		for(int i = index-r; i <= index+r; i++)
		b[index] += a[i];
	}
}

#define N (2048*2048)
#define THREADS_PER_BLOCK 512

void redom(int* x, int size)
{
	int i;
	for (i = 0; i < size; i++) 
	{
		x[i] = i % 100;
	}
}

int main(void)
{
	int *a, *b; // host copies of a, b, c
	int *d_a, *d_b; // device copies of a, b, c
	int size = N * sizeof(int);
	
	// Allocate space for device copies of a, b, c
	cudaMalloc((void **)&d_a, size);
	cudaMalloc((void **)&d_b, size);
	
	a = (int *)malloc(size); redom(a, N);
	b = (int *)malloc(size);
	
	// Copy inputs to device
	cudaMemcpy(d_a, a, size, cudaMemcpyHostToDevice);
	
	int radius = 3;
	
	// Launch add() kernel on GPU
	add<<<(N+THREADS_PER_BLOCK-1)/THREADS_PER_BLOCK,THREADS_PER_BLOCK>>>(d_a, d_b, N, radius);
	// Copy result back to host
	cudaMemcpy(b, d_b, size, cudaMemcpyDeviceToHost);
	// Cleanup
	cudaFree(d_a); cudaFree(d_b);

	FILE *f = fopen("rezultat.txt","wt");
	for(int i = radius; i < N-radius; i++)
		fprintf(f, "b[%d] =  %d ....... %d\n", i, b[i], a[i]);
	fclose(f);
	
    return 0;
}

