5.8.7.1.4 : La fonction principale du programme
Maintenant, implémentons la fonctions principale :
1 |
int main(int argc, char** argv){ |
On créé notre parseur d'argument avec la fonction createOptionParser définie plus tôt :
1 2 |
OptionParser parser = createOptionParser();
parser.parseArgument(argc, argv);
|
On récupère les arguments qui ont été passés au programme (les valeurs par défauts sont gérées automatiquement) :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
const OptionMode & defaultMode = parser.getDefaultMode(); float killRate(0.062f), feedRate(0.03f), dt(1.0f); size_t nbImage(10lu), nbRow(1080lu), nbCol(1920lu), nbExtraStep(34lu), nbGpuCall(1lu);; defaultMode.getValue(killRate, "killrate"); defaultMode.getValue(feedRate, "feedrate"); defaultMode.getValue(nbImage, "nbimage"); defaultMode.getValue(nbExtraStep, "nbextrastep"); defaultMode.getValue(nbGpuCall, "nbgpucall"); defaultMode.getValue(nbRow, "nbrow"); defaultMode.getValue(nbCol, "nbcol"); defaultMode.getValue(dt, "deltat"); std::string outputFile("output.h5"); defaultMode.getValue(outputFile, "output"); |
On appelle notre fonction générale :
1 2 3 |
std::cout << "nbImage = " << nbImage << ", nbRow = " << nbRow << ", nbCol = " << nbCol << ", nbExtraStep = " << nbExtraStep << ", nbGpuCall = " << nbGpuCall << std::endl; std::cout << "killRate = " << killRate << ", feedRate = " << feedRate << ", dt = " << dt << std::endl; bool b(simulateImage(nbRow, nbCol, nbImage, nbExtraStep, nbGpuCall, killRate, feedRate, dt, outputFile)); |
On retourne 0 en cas de succès et -1 en cas d'erreur :
1 |
return b - 1; |
On finit la fonction principale :
1 |
} |
Le fichier 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 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
/*************************************** Auteur : Pierre Aubert Mail : pierre.aubert@lapp.in2p3.fr Licence : CeCILL-C ****************************************/ #include "OptionParser.h" #include "temporary_alloc.h" #include "gray_scott_nvcpp.h" #include "MatrixHdf5.h" ///Create the OptionParser of this program /** @return OptionParser of this program */ OptionParser createOptionParser(){ OptionParser parser(true, __PROGRAM_VERSION__); parser.setExampleLongOption("gray_scott_gpu_nvcpp_vector --killrate=0.062 --feedrate=0.03 --nbimage=100 --nbrow=1080 --nbcol=1920 --output=outputFile.h5"); parser.setExampleShortOption("gray_scott_gpu_nvcpp_vector -k 0.062 -f 0.03 -n 100 -r 1080 -c 1920 -o outputFile.h5"); float killRate(0.054f), feedRate(0.014f); size_t nbImage(100lu), nbRow(100lu), nbCol(200lu); parser.addOption("killrate", "k", killRate, "rate of the process which converts V into P"); parser.addOption("feedrate", "f", feedRate, "rate of the process which feeds U and drains U, V and P"); parser.addOption("nbimage", "n", nbImage, "number of images to be created"); size_t nbExtraStep(1lu); parser.addOption("nbextrastep", "e", nbExtraStep, "number of extra steps to be computed between images"); parser.addOption("nbgpucall", "g", nbExtraStep, "number of GPU calls which compute nbimage"); parser.addOption("nbrow", "r", nbRow, "number of rows of the images to be created"); parser.addOption("nbcol", "c", nbCol, "number of columns of the images to be created"); float dt(1.0f); parser.addOption("deltat", "t", dt, "time interval between two computation"); std::string defaultOutputFile("output.h5"); parser.addOption("output", "o", defaultOutputFile, "Output file to be created with results"); return parser; } ///Simulate the images /** @param nbRow : number of rows of the images to be created * @param nbCol : number of columns of the images to be created * @param nbImage : number of images to be created * @param nbExtraStep : number of extra steps to be computed between images * @param nbGpuCall : number of time to call the GPU to create nbImage * @param killRate : rate of the process which converts V into P * @param feedRate : rate of the process which feeds U and drains U, V and P * @param dt : time interval between two computation * @param outputFile : name of the file to be created * @return true on succsess, false otherwise */ bool simulateImage(size_t nbRow, size_t nbCol, size_t nbImage, size_t nbExtraStep, size_t nbGpuCall, float killRate, float feedRate, float dt, const std::string & outputFile){ std::cout << "simulateImage : nbRow = " << nbRow << ", nbCol = " << nbCol << std::endl; std::vector<float> tmpImage; tmpImage.resize(nbImage*nbRow*nbCol); size_t paddedNbRow(nbRow + 2l), paddedNbCol(nbCol + 2l); std::vector<float> tmpInU, tmpInV, tmpOutU, tmpOutV; allocate_temporary(tmpInU, tmpInV, tmpOutU, tmpOutV, paddedNbRow, paddedNbCol); long nbStencilRow(3l), nbStencilCol(3l); float diffusionRateU(0.1f), diffusionRateV(0.05f); //This matrix of neigbour exchange is quite accurate but gives not so fun results // std::vector<float> matDeltaSquare[] = {0.05f, 0.2f, 0.05f, // 0.2f, 0.0f, 0.2f, // 0.05f, 0.2f, 0.05f}; std::vector<float> matDeltaSquare{1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f}; float * ptrMatDeltaSquare = matDeltaSquare.data(); float * matOutV = tmpImage.data(); float *tmpU1 = tmpInU.data(), *tmpU2 = tmpOutU.data(), *tmpV1 = tmpInV.data(), *tmpV2 = tmpOutV.data(); std::cout << "matOutV = " << matOutV << ", tmpU1 = " << tmpU1 << ", tmpU2 = " << tmpU2 << ", tmpV1 = " << tmpV1 << ", tmpV2 = " << tmpV2 << std::endl; std::cout << "nbImage = " << nbImage << ", nbExtraStep = " << nbExtraStep << ", nbGpuCall = " << nbGpuCall << ", nbRow = " << nbRow << ", nbCol = " << nbCol << std::endl; std::cout << "paddedNbRow = " << paddedNbRow << ", paddedNbCol = " << paddedNbCol << std::endl; std::cout << "ptrMatDeltaSquare = " << ptrMatDeltaSquare << ", nbStencilRow = " << nbStencilRow << ", nbStencilCol = " << nbStencilCol << std::endl; std::cout << "diffusionRateU = " << diffusionRateU << ", diffusionRateV = " << diffusionRateV << ", feedRate = " << feedRate << ", killRate = " << killRate << ", dt = " << dt << std::endl; gray_scott_nvcpp(matOutV, tmpU1, tmpV1, tmpU2, tmpV2, nbImage, nbExtraStep - (nbExtraStep % 2lu), nbGpuCall, nbRow, nbCol, paddedNbRow, paddedNbCol, ptrMatDeltaSquare, nbStencilRow, nbStencilCol, diffusionRateU, diffusionRateV, feedRate, killRate, dt); std::cerr << "Done" << std::endl; MatrixHdf5 fullMat; fullMat.setAllDim(nbCol, nbRow); fullMat.resize(nbImage); for(size_t i(0lu); i < nbImage; ++i){ fullMat.setRow(i, matOutV + i*nbRow*nbCol); } //Let's save the output file fullMat.write(outputFile); return true; } int main(int argc, char** argv){ OptionParser parser = createOptionParser(); parser.parseArgument(argc, argv); const OptionMode & defaultMode = parser.getDefaultMode(); float killRate(0.062f), feedRate(0.03f), dt(1.0f); size_t nbImage(10lu), nbRow(1080lu), nbCol(1920lu), nbExtraStep(34lu), nbGpuCall(1lu);; defaultMode.getValue(killRate, "killrate"); defaultMode.getValue(feedRate, "feedrate"); defaultMode.getValue(nbImage, "nbimage"); defaultMode.getValue(nbExtraStep, "nbextrastep"); defaultMode.getValue(nbGpuCall, "nbgpucall"); defaultMode.getValue(nbRow, "nbrow"); defaultMode.getValue(nbCol, "nbcol"); defaultMode.getValue(dt, "deltat"); std::string outputFile("output.h5"); defaultMode.getValue(outputFile, "output"); std::cout << "nbImage = " << nbImage << ", nbRow = " << nbRow << ", nbCol = " << nbCol << ", nbExtraStep = " << nbExtraStep << ", nbGpuCall = " << nbGpuCall << std::endl; std::cout << "killRate = " << killRate << ", feedRate = " << feedRate << ", dt = " << dt << std::endl; bool b(simulateImage(nbRow, nbCol, nbImage, nbExtraStep, nbGpuCall, killRate, feedRate, dt, outputFile)); return b - 1; } |
Vous pouvez le télécharger ici.