Commit 61654bc5 authored by remicres's avatar remicres
Browse files

MPI implementation of step 1,2,3. Some work is needed for step 4...

parent 7836b7d8
......@@ -4,58 +4,71 @@
int main(int argc, char *argv[])
{
if(argc != 8)
{
// img/test.tif tiles/ 125 125 4 tmp/
std::cerr << "[input image] [tile directory] [tile width] [tile height] [number of first iterations] [temporary directory] [output directory]"
<< std::endl;
return 1;
}
/* Parse command line arguments */
const std::string imagePath = argv[1];
std::string tileDir = argv[2]; // May be corrected if badly written.
const unsigned int tileWidth = atoi(argv[3]);
const unsigned int tileHeight = atoi(argv[4]);
const unsigned int niter = atoi(argv[5]);
std::string tmpDir = argv[6]; // May be corrected if badly written.
std::string outDir = argv[7];
/*
int myrank, nprocs;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
if (myrank==0)
std::cout << "Number of MPI process : " << nprocs << std::endl;
if(argc != 8)
{
// img/test.tif tiles/ 125 125 4 tmp/
std::cerr << "[input image] [tile directory] [tile width] [tile height] [number of first iterations] [temporary directory] [output directory]"
<< std::endl;
return 1;
}
/* Parse command line arguments */
const std::string imagePath = argv[1];
std::string tileDir = argv[2]; // May be corrected if badly written.
const unsigned int tileWidth = atoi(argv[3]);
const unsigned int tileHeight = atoi(argv[4]);
const unsigned int niter = atoi(argv[5]);
std::string tmpDir = argv[6]; // May be corrected if badly written.
std::string outDir = argv[7];
/*
To add:
internal memory available
If we have to do the image division
if we have to clean up the directory
the output directory in case the global graph cannot fit in memory
*/
using ImageType = otb::VectorImage<float, 2>;
using SegmenterType = lsrm::BaatzSegmenter<ImageType>;
using ControllerType = lsgrm::Controller<SegmenterType>;
ControllerType controller;
controller.SetInputImage(imagePath);
controller.SetTileDirectory(tileDir);
controller.SetTemporaryDirectory(tmpDir);
controller.SetOutputGraphDirectory(outDir);
// Memory configuration
controller.SetInternalMemoryAvailable(512ul);
controller.SetTileWidth(500);
controller.SetTileHeight(500);
controller.SetNumberOfFirstIterations(6);
// Specific parameters
lsrm::BaatzParam params;
params.m_SpectralWeight = 0.7;
params.m_ShapeWeight = 0.3;
controller.SetSpecificParameters(params);
controller.SetThreshold(60*60);
controller.RunSegmentation();
return 0;
*/
using ImageType = otb::VectorImage<float, 2>;
using SegmenterType = lsrm::BaatzSegmenter<ImageType>;
using ControllerType = lsgrm::Controller<SegmenterType>;
ControllerType controller;
controller.SetInputImage(imagePath);
controller.SetTileDirectory(tileDir);
controller.SetTemporaryDirectory(tmpDir);
controller.SetOutputGraphDirectory(outDir);
// Memory configuration
controller.SetInternalMemoryAvailable(4096ul);
controller.SetTileWidth(tileWidth);
controller.SetTileHeight(tileHeight);
controller.SetNumberOfFirstIterations(niter);
// MPI configuration
controller.SetNumberOfProcess(nprocs);
controller.SetProcessRank(myrank);
// Specific parameters
lsrm::BaatzParam params;
params.m_SpectralWeight = 0.7;
params.m_ShapeWeight = 0.3;
controller.SetSpecificParameters(params);
controller.SetThreshold(60*60);
controller.RunSegmentation();
MPI_Finalize();
return 0;
}
......@@ -33,6 +33,8 @@ namespace lsgrm
void SetSpecificParameters(const SegmentationParameterType& params);
void SetThreshold(const float& t);
void SetInternalMemoryAvailable(long long unsigned int v); // expecting a value in Mbytes.
void SetNumberOfProcess(int n) {m_NumberOfProcess = n;} ;
void SetProcessRank(int i) {m_ProcessRank = i;} ;
private:
......@@ -66,6 +68,8 @@ namespace lsgrm
unsigned int m_Margin;
unsigned int m_TileWidth;
unsigned int m_TileHeight;
int m_NumberOfProcess;
int m_ProcessRank;
std::vector<ProcessingTile> m_Tiles;
};
} // end of namespace lsgrm
......
......@@ -28,21 +28,29 @@ namespace lsgrm
}
// Divide the input image if necessary
if(m_ImageDivisionActivated)
SplitOTBImage<ImageType>(m_InputImage, m_TileDirectory, m_TileWidth,
m_TileHeight, m_Margin, m_NumberOfFirstIterations);
if(m_ImageDivisionActivated && (m_ProcessRank == 0))
{
std::cout << "Splitting tiles in " << m_TileDirectory << std::endl;
boost::timer t; t.restart();
SplitOTBImage<ImageType>(m_InputImage, m_TileDirectory, m_TileWidth,
m_TileHeight, m_Margin, m_NumberOfFirstIterations);
ShowTime(t);
}
MPI_Barrier(MPI_COMM_WORLD);
// Retrieve the problem configuration
RetrieveProblemConfiguration();
// Print values
std::cout << m_Memory << " bytes, tile dimension " << m_TileWidth << " X " << m_TileHeight
<< ", margin" << m_Margin << " niter " << m_NumberOfFirstIterations << std::endl;
<< ", margin " << m_Margin << " niter " << m_NumberOfFirstIterations << std::endl;
// Boolean indicating if there are remaining fusions
bool isFusion = false;
// Run first partial segmentation
MPI_Barrier(MPI_COMM_WORLD);
boost::timer t; t.restart();
auto accumulatedMemory = RunFirstPartialSegmentation<TSegmenter>(m_SpecificParameters,
m_Threshold,
m_NumberOfFirstIterations,
......@@ -57,12 +65,20 @@ namespace lsgrm
m_ImageWidth,
m_ImageHeight,
m_TemporaryDirectory,
isFusion);
std::cout << "Accumulated memory " << accumulatedMemory << " bytes, there is fusion "<< isFusion << std::endl;
isFusion,
m_ProcessRank,
m_NumberOfProcess);
// Gathering useful variables
GatherUsefulVariables(accumulatedMemory, isFusion, m_ProcessRank, m_NumberOfProcess);
// Time monitoring
if (m_ProcessRank == 0)
ShowTime(t);
while(accumulatedMemory > m_Memory && isFusion)
{
isFusion = false;
accumulatedMemory = RunPartialSegmentation<TSegmenter>(m_SpecificParameters,
m_Threshold,
......@@ -76,12 +92,20 @@ namespace lsgrm
m_ImageWidth,
m_ImageHeight,
m_ImageBands,
isFusion);
std::cout << "Accumulated memory " << accumulatedMemory << " bytes, there is fusion "
<< isFusion << std::endl;
isFusion,
m_ProcessRank,
m_NumberOfProcess);
// Gathering useful variables
GatherUsefulVariables(accumulatedMemory, isFusion, m_ProcessRank, m_NumberOfProcess);
}
if(accumulatedMemory <= m_Memory)
// Time monitoring
if (m_ProcessRank == 0)
ShowTime(t);
if(accumulatedMemory <= m_Memory && m_ProcessRank == 0)
{
// Merge all the graphs
MergeAllGraphsAndAchieveSegmentation<TSegmenter>(m_SpecificParameters,
......@@ -96,7 +120,12 @@ namespace lsgrm
m_ImageHeight,
m_ImageBands,
isFusion,
m_OutputGraphDirectory);
m_OutputGraphDirectory,
m_ProcessRank,
m_NumberOfProcess);
ShowTime(t);
}
else
{
......
......@@ -28,7 +28,9 @@ namespace lsgrm
const unsigned int imageHeight,
const unsigned int imageBands,
bool& isFusion,
const std::string& outputGraphDirectory);
const std::string& outputGraphDirectory,
int myrank,
int nprocs);
template<class TSegmenter>
long long unsigned int RunFirstPartialSegmentation(const typename TSegmenter::ParameterType& params,
......@@ -44,7 +46,9 @@ namespace lsgrm
const unsigned int imageWidth,
const unsigned int imageHeight,
const std::string& tmpDir,
bool& isFusion);
bool& isFusion,
int myrank,
int nprocs);
template<class TSegmenter>
long long unsigned int RunPartialSegmentation(const typename TSegmenter::ParameterType& params,
......@@ -60,7 +64,9 @@ namespace lsgrm
const unsigned int imageWidth,
const unsigned int imageHeight,
const unsigned int imageBands,
bool& isFusion);
bool& isFusion,
int myrank,
int nprocs);
template<class TSegmenter>
void RemoveUselessNodes(ProcessingTile& tile,
......
This diff is collapsed.
......@@ -11,4 +11,79 @@
#include <stack>
#include <boost/algorithm/string.hpp>
#include <boost/progress.hpp>
#include "mpi/mpi.h"
#define TAG_SUM 0
#define TAG_AVERAGE 1
#define TAG_BORDER 2
#define TAG_PIECE 3
/*
* This function returns TRUE if it's to the process #myrank to do the
* work on the yard #div in a pool of #nprocs threads
*/
bool MyTurn(int myrank, int nprocs, int div)
{
int proc = 0;
if (nprocs != 0)
proc = div % nprocs;
return (proc == myrank);
}
/*
* This function gather the given value in other process, and update it
*/
template<typename T>
void GatherMe(T& x, MPI_Datatype dataType, int myrank, int nprocs)
{
if (myrank == 0)
{
// Master process
// Gather
for (unsigned int p = 1 ; p < nprocs ; p++)
{
T partial_sum;
MPI_Recv( &partial_sum, 1, dataType, p, TAG_PIECE, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
x += partial_sum;
}
// Dispatch
for (unsigned int p = 1 ; p < nprocs ; p++)
MPI_Send(&x, 1, dataType, p, TAG_PIECE, MPI_COMM_WORLD);
}
else
{
// Slave process
MPI_Send(&x, 1, dataType, 0, TAG_PIECE, MPI_COMM_WORLD);
MPI_Recv(&x, 1, dataType, 0, TAG_PIECE, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
}
}
/*
* Gather accumulatedMemory and isFusion variables
*/
void GatherUsefulVariables(unsigned long long int& accumulatedMemory, bool& isFusion, int myrank, int nprocs)
{
MPI_Barrier(MPI_COMM_WORLD);
int isFusionInteger = 0;
long long int accumulatedMemoryLLI = static_cast<long long int>(accumulatedMemory);
if (isFusion)
isFusionInteger = 1;
GatherMe<int>(isFusionInteger, MPI_INT, myrank, nprocs);
GatherMe<long long int>(accumulatedMemoryLLI, MPI_LONG_LONG_INT, myrank, nprocs);
accumulatedMemory = static_cast<long long unsigned int>(accumulatedMemoryLLI);
if (isFusionInteger>0)
isFusion = true;
if (myrank == 0)
std::cout << "Accumulated memory " << accumulatedMemory << " bytes, there is fusion "<< isFusion << std::endl;
}
/*
* Print time elapsed
*/
void ShowTime(boost::timer t)
{
std::cout << "--- Process duration : " << t.elapsed() << std::endl;
t.restart();
}
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment