forked from ossimlabs/ossim
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathossimMpiMasterOverviewSequencer.cpp
More file actions
144 lines (119 loc) · 3.63 KB
/
Copy pathossimMpiMasterOverviewSequencer.cpp
File metadata and controls
144 lines (119 loc) · 3.63 KB
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
//----------------------------------------------------------------------------
//
// License: See top level LICENSE.txt file.
//
// Author: David Burken
//
// Description: Class definition for mpi master sequencer for building
// overview files.
//
//----------------------------------------------------------------------------
// $Id: ossimMpiMasterOverviewSequencer.cpp 17870 2010-08-12 13:12:32Z sbortman $
#include <ossim/parallel/ossimMpiMasterOverviewSequencer.h>
#include <ossim/ossimConfig.h> /* To pick up OSSIM_HAS_MPI. */
#include <ossim/base/ossimEndian.h>
#if OSSIM_HAS_MPI
# include <mpi.h>
#endif
ossimMpiMasterOverviewSequencer::ossimMpiMasterOverviewSequencer()
:
ossimOverviewSequencer(),
m_rank(0),
m_numberOfProcessors(1)
{
#if OSSIM_HAS_MPI
MPI_Comm_rank(MPI_COMM_WORLD, &m_rank);
MPI_Comm_size(MPI_COMM_WORLD, &m_numberOfProcessors);
#endif
//---
// Since this is the master sequencer it should always be rank 0; else,
// we have a coding error. Since we have the getNextTile implemented to
// recieve from the slave processes we always start the tile count at 0.
//---
m_currentTileNumber = 0;
}
ossimMpiMasterOverviewSequencer::~ossimMpiMasterOverviewSequencer()
{
}
void ossimMpiMasterOverviewSequencer::initialize()
{
ossimOverviewSequencer::initialize();
}
void ossimMpiMasterOverviewSequencer::setToStartOfSequence()
{
m_currentTileNumber = 0;
}
ossimRefPtr<ossimImageData> ossimMpiMasterOverviewSequencer::getNextTile()
{
if ( m_dirtyFlag )
{
//---
// If this happens we have a coding error. Someone started sequencing
// without initializing us properly.
//---
return ossimRefPtr<ossimImageData>();
}
#if OSSIM_HAS_MPI
//---
// Using mpi. The slaves will send us tiles to be returned by this method.
// They will alway be sent in big endian (network byte order) so we must
// swap back if the scalar type is not 8 bit and the system byte order is
// little endian. We will use the endian pointer itself as a flag to swap.
//---
ossimEndian* endian = 0;
if (m_imageHandler.valid())
{
if (m_imageHandler->getOutputScalarType() != OSSIM_UINT8)
{
if (ossim::byteOrder() != OSSIM_BIG_ENDIAN)
{
endian = new ossimEndian();
}
}
}
int errorValue;
// Buffer to receive the data from slaves.
void* buf = m_tile->getBuf();
// Total number of tiles to process...
ossim_uint32 numberOfTiles = getNumberOfTiles();
if(m_currentTileNumber >= numberOfTiles)
{
return ossimRefPtr<ossimImageData>();
}
errorValue = MPI_Recv(buf,
m_tile->getSizeInBytes(),
MPI_UNSIGNED_CHAR,
m_currentTileNumber%(m_numberOfProcessors-1)+1,
0,
MPI_COMM_WORLD,
MPI_STATUS_IGNORE);
// Data always sent in big endian order.
if ( endian )
{
endian->swap(m_tile->getScalarType(), buf, m_tile->getSize());
}
// Get the output rectangle.
ossimIrect outputRect;
getOutputTileRectangle(outputRect);
// Capture the output rectangle.
m_tile->setImageRectangle(outputRect);
// Set the tile status.
m_tile->validate();
if(m_tile->getDataObjectStatus() != OSSIM_EMPTY)
{
populateStats(m_tile.get());
}
// Increment the tile index.
++m_currentTileNumber;
// cleanup...
if ( endian )
{
delete endian;
endian = 0;
}
return m_tile;
#else
// Not compiled with mpi.
return ossimOverviewSequencer::getNextTile();
#endif /* End of #if OSSIM_HAS_MPI */
}