11.2.4.3 : Le fichier main.cpp



1
2
3
4
5
#include <iostream>
#include <cufft.h>
#include <cuda.h>
#include <cuda_runtime.h>
#include <curand.h>


Les includes de Thrust pour manipuler des vecteurs sur le CPU et le GPU
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <thrust/host_vector.h>
#include <thrust/device_vector.h>

#include "RawHdf5_hdf5.h"

///Compute the FFT on the given data
/**	@param[out] data : Data to be computed
 * 	@param nbBatch : number of batch to be used to compute the FFT
*/
void computeFFT(RawHdf5 & data, int nbBatch){
	int rank = 1;
	int istride = 1, idist = 1;
	int ostride = 1, odist = 1;
	
	size_t nbEvent = data.getNbEntries();		//Get the number of event or points in the input file
	int batchSize = nbEvent/nbBatch;		//If it is not a multiple, I am sorry
	std::cout << "computeFFT : Initialised vectors, nbEvent = " << nbEvent << ", nbBatch = " << nbBatch << ", batchSize = " << batchSize << std::endl;


Pour une raison obscure, thrust ne veut pas m'allouer mon vecteur directemenr sur le GPU, donc, on l'alloue vite fait sur le CPU et on le copie :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
	thrust::host_vector<float> hSignal(nbEvent*RAWHDF5_SIGNAL_0);
	thrust::device_vector<float> dSignal = hSignal;
	
	std::cout << "computeFFT : sending data to the GPU" << std::endl;
	float * host_signal = data.getSignalFull();
	thrust::copy(host_signal, host_signal +RAWHDF5_SIGNAL_0*nbEvent , dSignal.begin());
	
	std::cout << "computeFFT : Initialisation plan of FFT" << std::endl;
	cufftHandle plan;
	cufftPlanMany(&plan, rank, &batchSize, NULL, istride, idist,
		NULL, ostride, odist, CUFFT_C2C, nbBatch);
	std::cout << "computeFFT : Execution of the FFT" << std::endl;
	cufftComplex* device_signal = (cufftComplex*)dSignal.data().get();
	cufftExecC2C(plan, device_signal, device_signal, CUFFT_FORWARD);	//FFT computing
	cudaDeviceSynchronize();					//Synchronisation barrier
	std::cout << "computeFFT : End of computation" << std::endl;
	
	std::cout << "computeFFT : getting back data from the GPU" << std::endl;
	thrust::copy(dSignal.begin(), dSignal.end(), data.getSignalFull());
	
	//Let's free ressources
	cufftDestroy(plan);
}

///Load the input file
/**	@param outputFileName : name of the file to be created
 * 	@param inputFileName : name of the input file to be analysed
 * 	@param nbBatch : number of batch to be used to compute the FFT
 * 	@return true on success, false otherwise
*/
bool processInputFile(const std::string & outputFileName, const std::string & inputFileName, int nbBatch){
	std::cout << "processInputFile : loading file '" << inputFileName << "'" << std::endl;
	RawHdf5H5 hfile;
	hfile.read(inputFileName);			//Read input file
	
	computeFFT(hfile, nbBatch);
	std::cout << "processInputFile : savind file '" << outputFileName << "'" << std::endl;
	hfile.write(outputFileName);
	std::cout << "Done" << std::endl;
	return true;
}

int main(int argc, char** argv){
	int nbBatch = 1;
	if(argc < 3 || argc > 5){
		std::cout << "Usage :" << std::endl;
		std::cout << "\tcompute_cufft_on_hdf5 outputFile.h5 inputFile.h5" << std::endl;
		std::cout << "\tcompute_cufft_on_hdf5 outputFile.h5 inputFile.h5 10" << std::endl;
		std::cout << "Parameters :" << std::endl;
		std::cout << "\tHDF5 output file to be created" << std::endl;
		std::cout << "\tHDF5 input file to be read" << std::endl;
		std::cout << "\tNumber of batch to be used to perform the FFT" << std::endl;
		return 0;
	}
	std::string outputFileName(argv[1]), inputFileName(argv[2]);
	if(argc >= 4){
		nbBatch = atoi(argv[3]);
	}
	bool b(processInputFile(outputFileName, inputFileName, nbBatch));
	return b - 1;
}


Le main.cpp complet :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
/***************************************
	Auteur : Pierre Aubert
	Mail : pierre.aubert@lapp.in2p3.fr
	Licence : CeCILL-C
****************************************/

#include <iostream>
#include <cufft.h>
#include <cuda.h>
#include <cuda_runtime.h>
#include <curand.h>

#include <thrust/host_vector.h>
#include <thrust/device_vector.h>

#include "RawHdf5_hdf5.h"

///Compute the FFT on the given data
/**	@param[out] data : Data to be computed
 * 	@param nbBatch : number of batch to be used to compute the FFT
*/
void computeFFT(RawHdf5 & data, int nbBatch){
	int rank = 1;
	int istride = 1, idist = 1;
	int ostride = 1, odist = 1;
	
	size_t nbEvent = data.getNbEntries();		//Get the number of event or points in the input file
	int batchSize = nbEvent/nbBatch;		//If it is not a multiple, I am sorry
	std::cout << "computeFFT : Initialised vectors, nbEvent = " << nbEvent << ", nbBatch = " << nbBatch << ", batchSize = " << batchSize << std::endl;
	thrust::host_vector<float> hSignal(nbEvent*RAWHDF5_SIGNAL_0);
	thrust::device_vector<float> dSignal = hSignal;
	
	std::cout << "computeFFT : sending data to the GPU" << std::endl;
	float * host_signal = data.getSignalFull();
	thrust::copy(host_signal, host_signal +RAWHDF5_SIGNAL_0*nbEvent , dSignal.begin());
	
	std::cout << "computeFFT : Initialisation plan of FFT" << std::endl;
	cufftHandle plan;
	cufftPlanMany(&plan, rank, &batchSize, NULL, istride, idist,
		NULL, ostride, odist, CUFFT_C2C, nbBatch);
	std::cout << "computeFFT : Execution of the FFT" << std::endl;
	cufftComplex* device_signal = (cufftComplex*)dSignal.data().get();
	cufftExecC2C(plan, device_signal, device_signal, CUFFT_FORWARD);	//FFT computing
	cudaDeviceSynchronize();					//Synchronisation barrier
	std::cout << "computeFFT : End of computation" << std::endl;
	
	std::cout << "computeFFT : getting back data from the GPU" << std::endl;
	thrust::copy(dSignal.begin(), dSignal.end(), data.getSignalFull());
	
	//Let's free ressources
	cufftDestroy(plan);
}

///Load the input file
/**	@param outputFileName : name of the file to be created
 * 	@param inputFileName : name of the input file to be analysed
 * 	@param nbBatch : number of batch to be used to compute the FFT
 * 	@return true on success, false otherwise
*/
bool processInputFile(const std::string & outputFileName, const std::string & inputFileName, int nbBatch){
	std::cout << "processInputFile : loading file '" << inputFileName << "'" << std::endl;
	RawHdf5H5 hfile;
	hfile.read(inputFileName);			//Read input file
	
	computeFFT(hfile, nbBatch);
	std::cout << "processInputFile : savind file '" << outputFileName << "'" << std::endl;
	hfile.write(outputFileName);
	std::cout << "Done" << std::endl;
	return true;
}

int main(int argc, char** argv){
	int nbBatch = 1;
	if(argc < 3 || argc > 5){
		std::cout << "Usage :" << std::endl;
		std::cout << "\tcompute_cufft_on_hdf5 outputFile.h5 inputFile.h5" << std::endl;
		std::cout << "\tcompute_cufft_on_hdf5 outputFile.h5 inputFile.h5 10" << std::endl;
		std::cout << "Parameters :" << std::endl;
		std::cout << "\tHDF5 output file to be created" << std::endl;
		std::cout << "\tHDF5 input file to be read" << std::endl;
		std::cout << "\tNumber of batch to be used to perform the FFT" << std::endl;
		return 0;
	}
	std::string outputFileName(argv[1]), inputFileName(argv[2]);
	if(argc >= 4){
		nbBatch = atoi(argv[3]);
	}
	bool b(processInputFile(outputFileName, inputFileName, nbBatch));
	return b - 1;
}
Le fichier main.cpp est disponible ici.