/*
# cufft : $Revision$  
# $Date$ 
# Created by $Author$
# Usage : cufft
# Attention
#   $Loccker$
#  	$State$ 
#
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>                  
#define GLOBAL_DECLARATION
#include "../inc/config.h"

#define DEBUG
#include "genUtil.h"

/*
Example:
typedef struct lcufftInfo {
	float a;
	int   b;
} lcufftInfo;

typedef enum lcufftMode {
	a=0,
	b=1
} lcufftMode;
*/
#include <iostream>
#include <string.h>
#include <math.h>
//#include <cutil.h>

// デバイス関数(GPU側で実行する処理を記述)
// この例は
// GPUメモリからデータを取ってきて 平方根してGPUメモリに戻す
// という処理です
__global__ void calc_on_gpu(float* y)
{
  int i = threadIdx.x;
  y[i] = sqrt(y[i]);
}


// main関数.
// ちなみに __global__が付いていない関数は全て通常のC++コードとしてCPU側で実行されます.
// (つまり __global__な関数がなければ単なるC++コードなのでg++でコンパイル可能です)

int
main(int argc, char* argv[]) 
{
    int n = 500;
    int nb = sizeof(float)*n;
    float *x = (float*) malloc(nb);
    float *y;

	cufftInfo info;

	init0(&info);
    argCheck(&info, argc, argv);
    init1(&info);

	DEBUGPRINT("Program Start\n");

	printf("n=%d\n", n);

    cudaMalloc((void**)&y, nb);
  
    for(int i=0; i<n; i++) x[i] = i;
  
    // データ転送:   ホストメモリ -----> デバイスメモリ(GPU上のメモリ)
    cudaMemcpy(y, x, nb, cudaMemcpyHostToDevice);
  
    // カーネル (500個のスレッドでcalc_on_gpuを処理)
    calc_on_gpu <<<1, n>>>(y); 
  
    // データ転送:  デバイスメモリ(GPU上のメモリ) -----> ホストメモリ
    cudaMemcpy(x, y, nb, cudaMemcpyDeviceToHost);
  
    // 計算結果の表示
    for(int i=0; i<n; i++){
      printf("%d\t%f\n", i, x[i]);
    }


	exit(EXIT_SUCCESS);
}

void
additionalUsage()
{
	fprintf(stderr, "----- Additional Usage -----\n");
}
