Docker-in-Docker (DinD) capabilities of public runners deactivated. More info

main_intrinsics.cpp 6.54 KB
Newer Older
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
/***************************************
	Auteur : Pierre Aubert
	Mail : aubertp7@gmail.com
	Licence : CeCILL-C
****************************************/

#include "OptionParser.h"
#include "temporary_alloc.h"

#include "ProgressTime.h"
#include "intrinsics_propagation.h"
#include "MatrixHdf5.h"

///Create the OptionParser of this program
/**	@return OptionParser of this program
*/
OptionParser createOptionParser(){
	OptionParser parser(true, __PROGRAM_VERSION__);
	parser.setExampleLongOption("intrinsics_gray_scott --killrate=0.062 --feedrate=0.03 --nbimage=100 --nbrow=1080 --nbcol=1920 --output=outputFile.hdf5");
	parser.setExampleShortOption("intrinsics_gray_scott -k 0.062 -f 0.03 -n 100 -r 1080 -c 1920 -o outputFile.hdf5");
	
	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("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");
	
// 	0.014,0.054,
// 	0,#000000,0.2,#00FF00,0.21,#FFFF00,0.4,#FF0000,0.6,#FFFFFF
	
	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 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, float killRate, float feedRate, float dt, const std::string & outputFile){
Pierre Aubert's avatar
Pierre Aubert committed
56
	std::cout << "simulateImage : nbImage = "<<nbImage<<", nbRow = " << nbRow << ", nbCol = " << nbCol << std::endl;
57 58 59 60 61
	
	MatrixHdf5 fullMat;
	fullMat.setAllDim(nbCol, nbRow);
	fullMat.resize(nbImage);
	
Pierre Aubert's avatar
Pierre Aubert committed
62 63
	//TODO : create an other MatrixHdf5 to store the vectorial matrices and see what's going on
	
64
	
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
	PTensor<float> tmpInU, tmpInV, tmpOutU, tmpOutV;
	float *tmpU1 = NULL, *tmpU2 = NULL, *tmpV1 = NULL, *tmpV2 = NULL;
	allocate_temporary(tmpU1, tmpU2, tmpV1, tmpV2, tmpInU, tmpInV, tmpOutU, tmpOutV, nbRow, nbCol);
	
	long nbStencilRow(3l), nbStencilCol(3l);
	
	float diffudionRateU(0.1f), diffusionRateV(0.05f);
	//This matrix of neigbour exchange is quite accurate but gives not so fun results
// 	float matDeltaSquare[] = 	{0.05f, 0.2f, 0.05f,
// 					0.2f, 0.0f, 0.2f,
// 					0.05f, 0.2f, 0.05f};
	float matDeltaSquare[] = 	{1.0f, 1.0f, 1.0f,
					1.0f, 1.0f, 1.0f,
					1.0f, 1.0f, 1.0f};
	//Let's convert these temporaries into intrinsics temporaries
	PTensor<float> tmpVecInU(AllocMode::ALIGNED), tmpVecInV(AllocMode::ALIGNED), tmpVecOutU(AllocMode::ALIGNED), tmpVecOutV(AllocMode::ALIGNED);
	tmpVecInU.fromScalToVecNeigbhour(tmpInU, PLIB_VECTOR_SIZE_FLOAT);
	tmpVecOutU.fromScalToVecNeigbhour(tmpOutU, PLIB_VECTOR_SIZE_FLOAT);
Pierre Aubert's avatar
Pierre Aubert committed
83
	tmpVecInV.fromScalToVecNeigbhour(tmpInV, PLIB_VECTOR_SIZE_FLOAT);
84 85 86 87 88
	tmpVecOutV.fromScalToVecNeigbhour(tmpOutV, PLIB_VECTOR_SIZE_FLOAT);
	
	PTensor<float> vecMatDeltaSquare(AllocMode::ALIGNED, nbStencilRow, nbStencilCol*PLIB_VECTOR_SIZE_FLOAT);
	reshuffle_broadcastTensor(vecMatDeltaSquare.getData(), matDeltaSquare, nbStencilRow, nbStencilCol, 0lu, PLIB_VECTOR_SIZE_FLOAT);
	
89 90 91 92
	float * tmpVecU1 = tmpVecInU.getData();
	float * tmpVecU2 = tmpVecOutU.getData();
	float * tmpVecV1 = tmpVecInV.getData();
	float * tmpVecV2 = tmpVecOutV.getData();
93 94 95 96
	float * ptrVecMatStencil = vecMatDeltaSquare.getData();
	
	size_t nbVecRow(tmpVecInV.getFullNbRow()), nbVecCol(tmpVecInV.getNbCol());
	
97 98 99 100 101 102
	MatrixHdf5 fullVecMat;
	fullVecMat.setAllDim(nbVecCol, nbVecRow);
	fullVecMat.resize(nbImage);
	
	//TODO : create an other MatrixHdf5 to store the vectorial matrices and see what's going on
	
103 104 105 106 107 108 109
	PTensor<float> tmpScalOutV(AllocMode::ALIGNED);
	
	ProgressTime progress(nbImage);
	progress.start();
	for(size_t i(0lu); i < nbImage; ++i){
		progress.print();
		for(size_t j(0lu); j < nbExtraStep; ++j){
110
			grayscott_propagation(tmpVecU2, tmpVecV2, tmpVecU1, tmpVecV1, nbVecRow, nbVecCol,
111 112 113
					ptrVecMatStencil, nbStencilRow, nbStencilCol,
					diffudionRateU, diffusionRateV, feedRate, killRate, dt);
			//Let's update the dupplicated values
114 115
			reshuffle_updateDupplicateVecNeighbour(tmpVecU2, nbVecRow, nbVecCol, PLIB_VECTOR_SIZE_FLOAT);
			reshuffle_updateDupplicateVecNeighbour(tmpVecV2, nbVecRow, nbVecCol, PLIB_VECTOR_SIZE_FLOAT);
116 117
			
			///Let's swap the pointer
118 119
			swapValue(tmpVecU1, tmpVecU2);
			swapValue(tmpVecV1, tmpVecV2);
120
		}
121
		if(tmpVecV1 != tmpVecOutV.getData()){
122
			tmpScalOutV.fromVecToScalNeigbhour(tmpVecOutV);
123
			fullVecMat.setRow(i, tmpVecOutV.getData());
124 125
		}else{
			tmpScalOutV.fromVecToScalNeigbhour(tmpVecInV);	//The pointers were swaped
126
			fullVecMat.setRow(i, tmpVecInV.getData());
127
		}
Pierre Aubert's avatar
Pierre Aubert committed
128
		
129
		fullMat.setRow(i, tmpScalOutV.getData());
130
		
131
// 		fullMat.setRow(i, tmpVecV1);
132
// 		fullMat.setRow(i, tmpV2);
133 134 135 136 137
	}
	progress.finish();
	std::cerr << "Done" << std::endl;
	//Let's save the output file
	fullMat.write(outputFile);
138
	fullVecMat.write("./output_vec.h5");
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
	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(100lu), nbRow(1080lu), nbCol(1920lu), nbExtraStep(1lu);
	defaultMode.getValue(killRate, "killrate");
	defaultMode.getValue(feedRate, "feedrate");
	defaultMode.getValue(nbImage, "nbimage");
	defaultMode.getValue(nbExtraStep, "nbextrastep");
	defaultMode.getValue(nbRow, "nbrow");
	defaultMode.getValue(nbCol, "nbcol");
	defaultMode.getValue(dt, "deltat");
	
	
	std::string outputFile("");
	defaultMode.getValue(outputFile, "output");
	
	bool b(simulateImage(nbRow, nbCol, nbImage, nbExtraStep, killRate, feedRate, dt, outputFile));
	return b - 1;
}