Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
CodeVault
hpc-kernels
structured_grids
Commits
6849bfea
Commit
6849bfea
authored
Dec 14, 2016
by
Thomas Steinreiter
Browse files
* renaming to more save convention
parent
395099d0
Changes
14
Hide whitespace changes
Inline
Side-by-side
cellular_automaton/wireworld_c++/CollectiveCommunicator.cpp
View file @
6849bfea
#include
"CollectiveCommunicator.hpp"
void
CollectiveCommunicator
::
Communicate
(
State
*
model
)
{
if
(
_
commDistGraph
==
MPI_COMM_NULL
)
if
(
commDistGraph
_
==
MPI_COMM_NULL
)
MpiReportErrorAbort
(
"Communicator not initialized"
);
MPI_Neighbor_alltoallw
(
model
,
// sendbuf
_
sizes
.
data
(),
// sendcounts
_
sendDisplacements
.
data
(),
// sdispl
_
sendTypes
.
data
(),
// sendtypes
sizes
_
.
data
(),
// sendcounts
sendDisplacements
_
.
data
(),
// sdispl
sendTypes
_
.
data
(),
// sendtypes
model
,
// recvbuf
_
sizes
.
data
(),
// recvcounts
_
recvDisplacements
.
data
(),
// rdispls
_
recvTypes
.
data
(),
// recvtypes
_
commDistGraph
// comm
sizes
_
.
data
(),
// recvcounts
recvDisplacements
_
.
data
(),
// rdispls
recvTypes
_
.
data
(),
// recvtypes
commDistGraph
_
// comm
);
}
Communicator
::
MpiRequest
CollectiveCommunicator
::
AsyncCommunicate
(
State
*
model
)
{
if
(
_
commDistGraph
==
MPI_COMM_NULL
)
if
(
commDistGraph
_
==
MPI_COMM_NULL
)
MpiReportErrorAbort
(
"Communicator not initialized"
);
MPI_Request
req
;
MPI_Ineighbor_alltoallw
(
model
,
// sendbuf
_
sizes
.
data
(),
// sendcounts
_
sendDisplacements
.
data
(),
// sdispl
_
sendTypes
.
data
(),
// sendtypes
sizes
_
.
data
(),
// sendcounts
sendDisplacements
_
.
data
(),
// sdispl
sendTypes
_
.
data
(),
// sendtypes
model
,
// recvbuf
_
sizes
.
data
(),
// recvcounts
_
recvDisplacements
.
data
(),
// rdispls
_
recvTypes
.
data
(),
// recvtypes
_
commDistGraph
,
// comm
sizes
_
.
data
(),
// recvcounts
recvDisplacements
_
.
data
(),
// rdispls
recvTypes
_
.
data
(),
// recvtypes
commDistGraph
_
,
// comm
&
req
);
// request
return
MpiRequest
{{
req
}};
}
cellular_automaton/wireworld_c++/Communicator.cpp
View file @
6849bfea
...
...
@@ -5,11 +5,11 @@
#include
"Communicator.hpp"
Communicator
::
MpiRequest
::
MpiRequest
(
DoubleVector
<
MPI_Request
>
reqs
)
:
_
reqs
(
reqs
)
{}
:
reqs
_
(
reqs
)
{}
void
Communicator
::
MpiRequest
::
Wait
()
{
MPI_Waitall
(
static_cast
<
int
>
(
_
reqs
.
size
()),
//
_
reqs
.
data
(),
//
MPI_Waitall
(
static_cast
<
int
>
(
reqs
_
.
size
()),
//
reqs
_
.
data
(),
//
MPI_STATUSES_IGNORE
);
//
finished
=
true
;
}
...
...
@@ -21,24 +21,24 @@ Communicator::MpiRequest::~MpiRequest() {
Communicator
::
Communicator
(
const
MpiEnvironment
&
env
,
CommunicationMode
commMode
,
const
Size
&
procsSize
,
const
Size
&
tileSize
)
:
_
commMode
(
commMode
)
{
:
commMode
_
(
commMode
)
{
// Begin definition of basic types
MPI_Type_contiguous
(
static_cast
<
int
>
(
tileSize
.
Cols
),
MPI_CHAR
,
&
_
haloRowType
);
MPI_Type_commit
(
&
_
haloRowType
);
&
haloRowType
_
);
MPI_Type_commit
(
&
haloRowType
_
);
MPI_Type_vector
(
static_cast
<
int
>
(
tileSize
.
Rows
),
1
,
static_cast
<
int
>
(
tileSize
.
Cols
+
2
),
MPI_CHAR
,
&
_
haloColumnType
);
MPI_Type_commit
(
&
_
haloColumnType
);
&
haloColumnType
_
);
MPI_Type_commit
(
&
haloColumnType
_
);
// End definition of basic types
// Begin definition of types/displacements for a general cell somewhere in
// the middle of the procs grid
const
std
::
array
<
MPI_Datatype
,
NoNeighbors
>
generalSendTypes
{{
_
haloCornerType
,
_
haloRowType
,
_
haloCornerType
,
//
_
haloColumnType
,
_
haloColumnType
,
//
_
haloCornerType
,
_
haloRowType
,
_
haloCornerType
//
haloCornerType
_
,
haloRowType
_
,
haloCornerType
_
,
//
haloColumnType
_
,
haloColumnType
_
,
//
haloCornerType
_
,
haloRowType
_
,
haloCornerType
_
//
}};
const
auto
tCols
=
tileSize
.
Cols
;
const
auto
tRows
=
tileSize
.
Rows
;
...
...
@@ -97,49 +97,49 @@ Communicator::Communicator(const MpiEnvironment& env,
for
(
std
::
size_t
i
{
0
};
i
<
NoNeighbors
;
++
i
)
{
const
auto
nbrCoord
=
generalNeighborCoords
[
i
];
if
(
isInsideProcsGrid
(
nbrCoord
))
{
_
neighbors
.
push_back
(
coord2rank
(
nbrCoord
));
_
sendTypes
.
push_back
(
generalSendTypes
[
i
]);
_
sendDisplacements
.
push_back
(
generalSendDisplacements
[
i
]);
_
recvDisplacements
.
push_back
(
generalRecvDisplacements
[
i
]);
_
sizes
.
push_back
(
generalSizes
[
i
]);
neighbors
_
.
push_back
(
coord2rank
(
nbrCoord
));
sendTypes
_
.
push_back
(
generalSendTypes
[
i
]);
sendDisplacements
_
.
push_back
(
generalSendDisplacements
[
i
]);
recvDisplacements
_
.
push_back
(
generalRecvDisplacements
[
i
]);
sizes
_
.
push_back
(
generalSizes
[
i
]);
}
}
MPI_Dist_graph_create_adjacent
(
MPI_COMM_WORLD
,
// comm_old
static_cast
<
int
>
(
_
neighbors
.
size
()),
// indegree
_
neighbors
.
data
(),
// sources
static_cast
<
int
>
(
neighbors
_
.
size
()),
// indegree
neighbors
_
.
data
(),
// sources
reinterpret_cast
<
int
*>
(
MPI_UNWEIGHTED
),
// sourceweights
static_cast
<
int
>
(
_
neighbors
.
size
()),
// outdegree
_
neighbors
.
data
(),
// destinations
static_cast
<
int
>
(
neighbors
_
.
size
()),
// outdegree
neighbors
_
.
data
(),
// destinations
reinterpret_cast
<
int
*>
(
MPI_UNWEIGHTED
),
// destweights
MPI_INFO_NULL
,
// info
0
,
// reorder
&
_
commDistGraph
// comm_dist_graph
&
commDistGraph
_
// comm_dist_graph
);
// End definition of datastructures for this particular cell
}
Communicator
::~
Communicator
()
{
if
(
_
commDistGraph
!=
MPI_COMM_NULL
)
{
MPI_Comm_free
(
&
_
commDistGraph
);
MPI_Type_free
(
&
_
haloColumnType
);
MPI_Type_free
(
&
_
haloRowType
);
if
(
commDistGraph
_
!=
MPI_COMM_NULL
)
{
MPI_Comm_free
(
&
commDistGraph
_
);
MPI_Type_free
(
&
haloColumnType
_
);
MPI_Type_free
(
&
haloRowType
_
);
}
}
void
Communicator
::
swap
(
Communicator
&
first
,
Communicator
&
second
)
{
using
std
::
swap
;
swap
(
first
.
_
commMode
,
second
.
_
commMode
);
swap
(
first
.
_
neighbors
,
second
.
_
neighbors
);
swap
(
first
.
_
sizes
,
second
.
_
sizes
);
swap
(
first
.
_
sendTypes
,
second
.
_
sendTypes
);
swap
(
first
.
_
sendDisplacements
,
second
.
_
sendDisplacements
);
swap
(
first
.
_
recvDisplacements
,
second
.
_
recvDisplacements
);
swap
(
first
.
_
commDistGraph
,
second
.
_
commDistGraph
);
swap
(
first
.
_
haloRowType
,
second
.
_
haloRowType
);
swap
(
first
.
_
haloColumnType
,
second
.
_
haloColumnType
);
swap
(
first
.
_
haloCornerType
,
second
.
_
haloCornerType
);
swap
(
first
.
commMode
_
,
second
.
commMode
_
);
swap
(
first
.
neighbors
_
,
second
.
neighbors
_
);
swap
(
first
.
sizes
_
,
second
.
sizes
_
);
swap
(
first
.
sendTypes
_
,
second
.
sendTypes
_
);
swap
(
first
.
sendDisplacements
_
,
second
.
sendDisplacements
_
);
swap
(
first
.
recvDisplacements
_
,
second
.
recvDisplacements
_
);
swap
(
first
.
commDistGraph
_
,
second
.
commDistGraph
_
);
swap
(
first
.
haloRowType
_
,
second
.
haloRowType
_
);
swap
(
first
.
haloColumnType
_
,
second
.
haloColumnType
_
);
swap
(
first
.
haloCornerType
_
,
second
.
haloCornerType
_
);
}
Communicator
::
Communicator
(
Communicator
&&
other
)
noexcept
{
...
...
cellular_automaton/wireworld_c++/Communicator.hpp
View file @
6849bfea
...
...
@@ -26,7 +26,7 @@ class Communicator {
boost
::
container
::
static_vector
<
T
,
NoNeighbors
*
2
>
;
private:
DoubleVector
<
MPI_Request
>
_
reqs
;
DoubleVector
<
MPI_Request
>
reqs
_
;
bool
finished
{};
public:
...
...
@@ -40,21 +40,21 @@ class Communicator {
};
protected:
CommunicationMode
_
commMode
;
CommunicationMode
commMode
_
;
// data members for graph topology
Vector
<
int
>
_
neighbors
;
Vector
<
int
>
_
sizes
;
Vector
<
MPI_Datatype
>
_
sendTypes
;
const
Vector
<
MPI_Datatype
>&
_
recvTypes
{
_sendTypes
};
Vector
<
MPI_Aint
>
_
sendDisplacements
;
Vector
<
MPI_Aint
>
_
recvDisplacements
;
MPI_Comm
_
commDistGraph
{
MPI_COMM_NULL
};
Vector
<
int
>
neighbors
_
;
Vector
<
int
>
sizes
_
;
Vector
<
MPI_Datatype
>
sendTypes
_
;
const
Vector
<
MPI_Datatype
>&
recvTypes_
{
sendTypes
_
};
Vector
<
MPI_Aint
>
sendDisplacements
_
;
Vector
<
MPI_Aint
>
recvDisplacements
_
;
MPI_Comm
commDistGraph
_
{
MPI_COMM_NULL
};
// data types
MPI_Datatype
_
haloRowType
{};
MPI_Datatype
_
haloColumnType
{};
MPI_Datatype
_
haloCornerType
{
MPI_CHAR
};
MPI_Datatype
haloRowType
_
{};
MPI_Datatype
haloColumnType
_
{};
MPI_Datatype
haloCornerType
_
{
MPI_CHAR
};
public:
Communicator
()
=
default
;
...
...
cellular_automaton/wireworld_c++/FileIO.cpp
View file @
6849bfea
...
...
@@ -78,54 +78,54 @@ TileInfo FileIO::GetTileInfo(Size globalSize, Size procsSize,
FileIO
::
Tile
::
Tile
(
const
std
::
string
&
path
,
HeaderInfo
header
,
Size
procsSize
,
std
::
size_t
rank
,
State
*
buf
)
:
_
path
(
path
),
_
headerLength
(
header
.
HeaderLength
),
_
srcSize
(
header
.
GlobalSize
),
_
procsSize
(
procsSize
),
_
buf
(
buf
),
_
tileInfo
(
FileIO
::
GetTileInfo
(
header
.
GlobalSize
,
procsSize
,
rank
)),
_
tileSize
(
_tileInfo
.
Size
),
_
tileCoord
(
_tileInfo
.
GlobalCoord
),
_
tileType
(
MpiSubarray
({{
header
.
GlobalSize
.
Rows
,
_
tileSize
.
Rows
,
0
},
{
header
.
GlobalSize
.
Cols
+
LF
,
_
tileSize
.
Cols
,
0
}})),
_
bufType
(
MpiSubarray
({{
_
tileSize
.
Rows
+
2
,
_
tileSize
.
Rows
,
1
},
{
_
tileSize
.
Cols
+
2
,
_
tileSize
.
Cols
,
1
}})),
_
displ
(
header
.
HeaderLength
+
(
header
.
GlobalSize
.
Cols
+
LF
)
*
_
tileCoord
.
Y
+
_
tileCoord
.
X
)
{}
:
path
_
(
path
),
headerLength
_
(
header
.
HeaderLength
),
srcSize
_
(
header
.
GlobalSize
),
procsSize
_
(
procsSize
),
buf
_
(
buf
),
tileInfo
_
(
FileIO
::
GetTileInfo
(
header
.
GlobalSize
,
procsSize
,
rank
)),
tileSize_
(
tileInfo
_
.
Size
),
tileCoord_
(
tileInfo
_
.
GlobalCoord
),
tileType
_
(
MpiSubarray
({{
header
.
GlobalSize
.
Rows
,
tileSize
_
.
Rows
,
0
},
{
header
.
GlobalSize
.
Cols
+
LF
,
tileSize
_
.
Cols
,
0
}})),
bufType
_
(
MpiSubarray
({{
tileSize
_
.
Rows
+
2
,
tileSize
_
.
Rows
,
1
},
{
tileSize
_
.
Cols
+
2
,
tileSize
_
.
Cols
,
1
}})),
displ
_
(
header
.
HeaderLength
+
(
header
.
GlobalSize
.
Cols
+
LF
)
*
tileCoord
_
.
Y
+
tileCoord
_
.
X
)
{}
void
FileIO
::
Tile
::
Read
()
{
MPI_File
file
;
MPI_File_open
(
MPI_COMM_WORLD
,
_
path
.
c_str
(),
MPI_File_open
(
MPI_COMM_WORLD
,
path
_
.
c_str
(),
MPI_MODE_RDONLY
|
MPI_MODE_UNIQUE_OPEN
,
MPI_INFO_NULL
,
&
file
);
MPI_File_set_view
(
file
,
static_cast
<
MPI_Offset
>
(
_
displ
),
MPI_CHAR
,
_
tileType
.
type
(),
"native"
,
MPI_INFO_NULL
);
MPI_File_set_view
(
file
,
static_cast
<
MPI_Offset
>
(
displ
_
),
MPI_CHAR
,
tileType
_
.
type
(),
"native"
,
MPI_INFO_NULL
);
MPI_File_read_all
(
file
,
_
buf
,
1
,
_
bufType
.
type
(),
MPI_STATUS_IGNORE
);
MPI_File_read_all
(
file
,
buf
_
,
1
,
bufType
_
.
type
(),
MPI_STATUS_IGNORE
);
MPI_File_close
(
&
file
);
}
void
FileIO
::
Tile
::
Write
()
const
{
MPI_File
file
;
MPI_File_open
(
MPI_COMM_WORLD
,
_
path
.
c_str
(),
MPI_File_open
(
MPI_COMM_WORLD
,
path
_
.
c_str
(),
MPI_MODE_CREATE
|
MPI_MODE_WRONLY
,
MPI_INFO_NULL
,
&
file
);
MPI_File_set_view
(
file
,
static_cast
<
MPI_Offset
>
(
_
displ
),
MPI_CHAR
,
_
tileType
.
type
(),
"native"
,
MPI_INFO_NULL
);
MPI_File_set_view
(
file
,
static_cast
<
MPI_Offset
>
(
displ
_
),
MPI_CHAR
,
tileType
_
.
type
(),
"native"
,
MPI_INFO_NULL
);
MPI_File_write_all
(
file
,
_
buf
,
1
,
_
bufType
.
type
(),
MPI_STATUS_IGNORE
);
MPI_File_write_all
(
file
,
buf
_
,
1
,
bufType
_
.
type
(),
MPI_STATUS_IGNORE
);
/// fix line feeds
// this is done with an collective call, but only the rightmost
// ranks actually write line feeds
// are we a rightMost tile?
const
auto
rightMost
=
_
tileInfo
.
ProcCoord
.
X
==
_
procsSize
.
Cols
-
1
;
const
auto
noLfNeeded
=
rightMost
?
_
tileSize
.
Rows
:
0
;
const
auto
rightMost
=
tileInfo
_
.
ProcCoord
.
X
==
procsSize
_
.
Cols
-
1
;
const
auto
noLfNeeded
=
rightMost
?
tileSize
_
.
Rows
:
0
;
const
auto
lfType
=
MpiSubarray
(
// subsize must be > 0
{{
_
srcSize
.
Rows
,
std
::
max
<
std
::
size_t
>
(
noLfNeeded
,
1
),
0
},
{
_
srcSize
.
Cols
+
LF
,
1
,
0
}});
{{
srcSize
_
.
Rows
,
std
::
max
<
std
::
size_t
>
(
noLfNeeded
,
1
),
0
},
{
srcSize
_
.
Cols
+
LF
,
1
,
0
}});
const
std
::
vector
<
char
>
lfs
(
noLfNeeded
,
'\n'
);
const
auto
lfDisp
=
_
headerLength
+
_
tileInfo
.
GlobalCoord
.
Y
*
(
_
srcSize
.
Cols
+
LF
)
+
_
srcSize
.
Cols
;
const
auto
lfDisp
=
headerLength
_
+
tileInfo
_
.
GlobalCoord
.
Y
*
(
srcSize
_
.
Cols
+
LF
)
+
srcSize
_
.
Cols
;
MPI_File_set_view
(
file
,
static_cast
<
MPI_Offset
>
(
lfDisp
),
MPI_CHAR
,
lfType
.
type
(),
"native"
,
MPI_INFO_NULL
);
...
...
cellular_automaton/wireworld_c++/FileIO.hpp
View file @
6849bfea
...
...
@@ -26,18 +26,18 @@ struct FileIO {
// helper class to share commonly used data for reading and writing
class
Tile
{
static
constexpr
std
::
size_t
LF
=
1
;
// linefeed chars
const
std
::
string
&
_
path
;
const
std
::
size_t
_
headerLength
;
const
Size
_
srcSize
;
const
Size
_
procsSize
;
State
*
_
buf
;
const
TileInfo
_
tileInfo
;
const
Size
_
tileSize
;
const
Coord
_
tileCoord
;
const
MpiSubarray
_
tileType
;
const
MpiSubarray
_
bufType
;
const
std
::
size_t
_
displ
;
const
std
::
string
&
path
_
;
const
std
::
size_t
headerLength
_
;
const
Size
srcSize
_
;
const
Size
procsSize
_
;
State
*
buf
_
;
const
TileInfo
tileInfo
_
;
const
Size
tileSize
_
;
const
Coord
tileCoord
_
;
const
MpiSubarray
tileType
_
;
const
MpiSubarray
bufType
_
;
const
std
::
size_t
displ
_
;
public:
Tile
(
const
std
::
string
&
path
,
HeaderInfo
header
,
Size
procsSize
,
...
...
cellular_automaton/wireworld_c++/MpiEnvironment.cpp
View file @
6849bfea
...
...
@@ -5,21 +5,21 @@
void
MpiEnvironment
::
swap
(
MpiEnvironment
&
first
,
MpiEnvironment
&
second
)
noexcept
{
using
std
::
swap
;
swap
(
first
.
_
worldRank
,
second
.
_
worldRank
);
swap
(
first
.
_
worldSize
,
second
.
_
worldSize
);
swap
(
first
.
_
isMaster
,
second
.
_
isMaster
);
swap
(
first
.
worldRank
_
,
second
.
worldRank
_
);
swap
(
first
.
worldSize
_
,
second
.
worldSize
_
);
swap
(
first
.
isMaster
_
,
second
.
isMaster
_
);
}
MpiEnvironment
::
MpiEnvironment
(
int
&
argc
,
char
*
argv
[])
{
MPI_Init
(
&
argc
,
&
argv
);
_
worldRank
=
[]
{
int
r
;
MPI_Comm_rank
(
MPI_COMM_WORLD
,
&
r
);
return
static_cast
<
std
::
size_t
>
(
r
);
}();
_
worldSize
=
[]
{
int
s
;
MPI_Comm_size
(
MPI_COMM_WORLD
,
&
s
);
return
static_cast
<
std
::
size_t
>
(
s
);
}();
_
isMaster
=
{
_
worldRank
==
0
};
worldRank
_
=
[]
{
int
r
;
MPI_Comm_rank
(
MPI_COMM_WORLD
,
&
r
);
return
static_cast
<
std
::
size_t
>
(
r
);
}();
worldSize
_
=
[]
{
int
s
;
MPI_Comm_size
(
MPI_COMM_WORLD
,
&
s
);
return
static_cast
<
std
::
size_t
>
(
s
);
}();
isMaster
_
=
{
worldRank
_
==
0
};
// We want the program to stop on I/O errors
MPI_File_set_errhandler
(
MPI_FILE_NULL
,
MPI_ERRORS_ARE_FATAL
);
}
MpiEnvironment
::~
MpiEnvironment
()
{
if
(
_
worldRank
!=
std
::
numeric_limits
<
std
::
size_t
>::
max
())
{
MPI_Finalize
();
}
if
(
worldRank
_
!=
std
::
numeric_limits
<
std
::
size_t
>::
max
())
{
MPI_Finalize
();
}
}
MpiEnvironment
::
MpiEnvironment
(
MpiEnvironment
&&
other
)
noexcept
{
...
...
cellular_automaton/wireworld_c++/MpiEnvironment.hpp
View file @
6849bfea
...
...
@@ -5,14 +5,14 @@
#include
<mpi.h>
class
MpiEnvironment
{
// wrapper for creating and destroying the environment
std
::
size_t
_
worldRank
{
std
::
numeric_limits
<
std
::
size_t
>::
max
()};
std
::
size_t
_
worldSize
{
0
};
bool
_
isMaster
{
false
};
std
::
size_t
worldRank
_
{
std
::
numeric_limits
<
std
::
size_t
>::
max
()};
std
::
size_t
worldSize
_
{
0
};
bool
isMaster
_
{
false
};
public:
std
::
size_t
worldRank
()
const
{
return
_
worldRank
;
}
std
::
size_t
worldSize
()
const
{
return
_
worldSize
;
}
bool
isMaster
()
const
{
return
_
isMaster
;
}
std
::
size_t
worldRank
()
const
{
return
worldRank
_
;
}
std
::
size_t
worldSize
()
const
{
return
worldSize
_
;
}
bool
isMaster
()
const
{
return
isMaster
_
;
}
void
swap
(
MpiEnvironment
&
first
,
MpiEnvironment
&
second
)
noexcept
;
...
...
cellular_automaton/wireworld_c++/MpiSubarray.cpp
View file @
6849bfea
...
...
@@ -3,15 +3,15 @@
SubarrayDefinition
::
SubarrayDefinition
(
std
::
initializer_list
<
SubarrayDimensionDefinition
>
saDimDefs
)
{
for
(
const
auto
&
dd
:
saDimDefs
)
{
_
sizes
.
push_back
(
static_cast
<
int
>
(
dd
.
size
));
_
subSizes
.
push_back
(
static_cast
<
int
>
(
dd
.
subSize
));
_
starts
.
push_back
(
static_cast
<
int
>
(
dd
.
start
));
sizes
_
.
push_back
(
static_cast
<
int
>
(
dd
.
size
));
subSizes
_
.
push_back
(
static_cast
<
int
>
(
dd
.
subSize
));
starts
_
.
push_back
(
static_cast
<
int
>
(
dd
.
start
));
}
}
void
MpiSubarray
::
swap
(
MpiSubarray
&
first
,
MpiSubarray
&
second
)
noexcept
{
using
std
::
swap
;
swap
(
first
.
_
type
,
second
.
_
type
);
swap
(
first
.
type
_
,
second
.
type
_
);
}
MpiSubarray
::
MpiSubarray
(
SubarrayDefinition
sd
)
{
...
...
@@ -21,12 +21,12 @@ MpiSubarray::MpiSubarray(SubarrayDefinition sd) {
sd
.
starts
(),
// array_of_starts
MPI_ORDER_C
,
// order
MPI_CHAR
,
// oldtype
&
_
type
// newtype
&
type
_
// newtype
);
MPI_Type_commit
(
&
_
type
);
MPI_Type_commit
(
&
type
_
);
}
MpiSubarray
::~
MpiSubarray
()
{
if
(
_
type
!=
MPI_DATATYPE_NULL
)
{
MPI_Type_free
(
&
_
type
);
}
if
(
type
_
!=
MPI_DATATYPE_NULL
)
{
MPI_Type_free
(
&
type
_
);
}
}
MpiSubarray
::
MpiSubarray
(
MpiSubarray
&&
other
)
noexcept
{
swap
(
*
this
,
other
);
}
MpiSubarray
&
MpiSubarray
::
operator
=
(
MpiSubarray
&&
other
)
noexcept
{
...
...
cellular_automaton/wireworld_c++/MpiSubarray.hpp
View file @
6849bfea
...
...
@@ -11,26 +11,26 @@ struct SubarrayDimensionDefinition { // helper container
};
class
SubarrayDefinition
{
// helper container for MPI Datatype creation
std
::
vector
<
int
>
_
sizes
;
std
::
vector
<
int
>
_
subSizes
;
std
::
vector
<
int
>
_
starts
;
std
::
vector
<
int
>
sizes
_
;
std
::
vector
<
int
>
subSizes
_
;
std
::
vector
<
int
>
starts
_
;
public:
auto
dims
()
const
{
return
_
sizes
.
size
();
}
auto
sizes
()
{
return
_
sizes
.
data
();
}
auto
subSizes
()
{
return
_
subSizes
.
data
();
}
auto
starts
()
{
return
_
starts
.
data
();
}
auto
dims
()
const
{
return
sizes
_
.
size
();
}
auto
sizes
()
{
return
sizes
_
.
data
();
}
auto
subSizes
()
{
return
subSizes
_
.
data
();
}
auto
starts
()
{
return
starts
_
.
data
();
}
SubarrayDefinition
(
std
::
initializer_list
<
SubarrayDimensionDefinition
>
saDimDefs
);
};
class
MpiSubarray
{
// wrapper for creating and destroying the type
MPI_Datatype
_
type
{
MPI_DATATYPE_NULL
};
MPI_Datatype
type
_
{
MPI_DATATYPE_NULL
};
public:
void
swap
(
MpiSubarray
&
first
,
MpiSubarray
&
second
)
noexcept
;
MPI_Datatype
type
()
const
{
return
_
type
;
}
MPI_Datatype
type
()
const
{
return
type
_
;
}
MpiSubarray
(
SubarrayDefinition
sd
);
~
MpiSubarray
();
...
...
cellular_automaton/wireworld_c++/MpiWireworld.cpp
View file @
6849bfea
...
...
@@ -16,9 +16,9 @@
#include
"Util.hpp"
void
MpiWireworld
::
processArea
(
Coord
start
,
Size
size
)
{
auto
&
_
model
=
_
tile
.
model
();
auto
&
_
nextModel
=
_
tile
.
nextModel
();
const
auto
modelWidth
=
_
tile
.
modelWidth
();
auto
&
model
_
=
tile
_
.
model
();
auto
&
nextModel
_
=
tile
_
.
nextModel
();
const
auto
modelWidth
=
tile
_
.
modelWidth
();
// std::size_t is unsigned. modulo arithmetics is used for calculating the
// index
...
...
@@ -31,8 +31,8 @@ void MpiWireworld::processArea(Coord start, Size size) {
for
(
std
::
size_t
x
{
start
.
X
};
x
<
start
.
X
+
size
.
Cols
;
++
x
)
{
const
auto
idx
=
y
*
modelWidth
+
x
;
const
auto
currentState
=
_
model
[
idx
];
_
nextModel
[
idx
]
=
[
&
]()
{
const
auto
currentState
=
model
_
[
idx
];
nextModel
_
[
idx
]
=
[
&
]()
{
switch
(
currentState
)
{
case
State
::
ElectronHead
:
return
State
::
ElectronTail
;
...
...
@@ -40,7 +40,7 @@ void MpiWireworld::processArea(Coord start, Size size) {
return
State
::
Conductor
;
case
State
::
Conductor
:
{
const
auto
isHead
=
[
&
](
std
::
size_t
i
)
{
return
_
model
[
i
]
==
State
::
ElectronHead
?
1
:
0
;
return
model
_
[
i
]
==
State
::
ElectronHead
?
1
:
0
;
};
const
auto
headCount
=
isHead
(
idx
+
leftOffset
+
upOffset
)
+
//
...
...
@@ -65,54 +65,54 @@ void MpiWireworld::processArea(Coord start, Size size) {
}
MpiWireworld
::
MpiWireworld
(
const
MpiEnvironment
&
env
,
const
Configuration
&
cfg
)
:
_
tile
(
Tile
::
Read
(
cfg
,
env
)),
_
comm
([
&
]()
->
std
::
unique_ptr
<
Communicator
>
{
:
tile
_
(
Tile
::
Read
(
cfg
,
env
)),
comm
_
([
&
]()
->
std
::
unique_ptr
<
Communicator
>
{
switch
(
cfg
.
CommMode
)
{
case
CommunicationMode
::
Collective
:
return
std
::
make_unique
<
CollectiveCommunicator
>
(
env
,
cfg
.
CommMode
,
cfg
.
Procs
,
_
tile
.
tileSize
());
env
,
cfg
.
CommMode
,
cfg
.
Procs
,
tile
_
.
tileSize
());
case
CommunicationMode
::
P2P
:
return
std
::
make_unique
<
P2PCommunicator
>
(
env
,
cfg
.
CommMode
,
cfg
.
Procs
,
_
tile
.
tileSize
());
env
,
cfg
.
CommMode
,
cfg
.
Procs
,
tile
_
.
tileSize
());
}
}())
{
_
comm
->
Communicate
(
_
tile
.
model
());
comm
_
->
Communicate
(
tile
_
.
model
());
}
std
::
ostream
&
operator
<<
(
std
::
ostream
&
out
,
const
MpiWireworld
&
g
)
{
// for now, put only our local tile
out
<<
g
.
_
tile
;
out
<<
g
.
tile
_
;
return
out
;
}
void
MpiWireworld
::
write
()
const
{
_
tile
.
write
();
}
void
MpiWireworld
::
write
()
const
{
tile
_
.
write
();
}
void
MpiWireworld
::
simulateStep
()
{
auto
&
_
model
=
_
tile
.
model
();
auto
&
_
nextModel
=
_
tile
.
nextModel
();
const
auto
_
tileSize
=
_
tile
.
tileSize
();
auto
&
model
_
=
tile
_
.
model
();
auto
&
nextModel
_
=
tile
_
.
nextModel
();
const
auto
tileSize
_
=
tile
_
.
tileSize
();
//// compute the border area first, then comm
//// and compute the core async
/// border area
// top
processArea
({
1
,
1
},
{
_
tileSize
.
Cols
,
1
});
processArea
({
1
,
1
},
{
tileSize
_
.
Cols
,
1
});
// left and right
processArea
({
1
,
2
},
{
1
,
_
tileSize
.
Rows
-
2
});
processArea
({
_
tileSize
.
Cols
,
2
},
{
1
,
_
tileSize
.
Rows
-
2
});
processArea
({
1
,
2
},
{
1
,
tileSize
_
.
Rows
-
2
});
processArea
({
tileSize
_
.
Cols
,
2
},
{
1
,
tileSize
_
.
Rows
-
2
});
// bottom
processArea
({
1
,
_
tileSize
.
Rows
},
{
_
tileSize
.
Cols
,
1
});
processArea
({
1
,
tileSize
_
.
Rows
},
{
tileSize
_
.
Cols
,
1
});
// start communication of border while processing the core
auto
req
=
_
comm
->
AsyncCommunicate
(
_
nextModel
);
auto
req
=
comm
_
->
AsyncCommunicate
(
nextModel
_
);
/// core
processArea
({
2
,
2
},
{
_
tileSize
.
Cols
-
2
,
_
tileSize
.
Rows
-
2
});
processArea
({
2
,
2
},
{
tileSize
_
.
Cols
-
2
,
tileSize
_
.
Rows
-
2
});
req
.
Wait
();
std
::
swap
(
_
model
,
_
nextModel
);
std
::
swap
(
model
_
,
nextModel
_
);
}
cellular_automaton/wireworld_c++/MpiWireworld.hpp
View file @
6849bfea
...
...
@@ -9,8 +9,8 @@
#include
"Tile.hpp"
class
MpiWireworld
{
Tile
_
tile
;
std
::
unique_ptr
<
Communicator
>
_
comm
;