Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F85537024
dumper_restart.cc
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Sun, Sep 29, 18:48
Size
10 KB
Mime Type
text/x-c++
Expires
Tue, Oct 1, 18:48 (2 d)
Engine
blob
Format
Raw Data
Handle
21196885
Attached To
rLIBMULTISCALE LibMultiScale
dumper_restart.cc
View Options
/**
* @file dumper_restart.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
* @date Wed Aug 20 16:58:08 2014
*
* @brief This dumper saves the state of the simulation
*
* @section LICENSE
*
* Copyright INRIA and CEA
*
* The LibMultiScale is a C++ parallel framework for the multiscale
* coupling methods dedicated to material simulations. This framework
* provides an API which makes it possible to program coupled simulations
* and integration of already existing codes.
*
* This Project was initiated in a collaboration between INRIA Futurs Bordeaux
* within ScAlApplix team and CEA/DPTA Ile de France.
* The project is now continued at the Ecole Polytechnique Fédérale de Lausanne
* within the LSMS/ENAC laboratory.
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*
*/
/* ------------------------------------------------------------------------ */
#include "dumper_restart.hh"
#include "communicator.hh"
#include "lib_continuum.hh"
#include "lib_dd.hh"
#include "lib_md.hh"
#include "lm_common.hh"
#include "ref_point_data.hh"
#include <iomanip>
#include <mpi.h>
/* ------------------------------------------------------------------------ */
__BEGIN_LIBMULTISCALE__
/* ------------------------------------------------------------------------ */
//! local number of Dofs per proc. Only valid for root (rank = 0) processor
static
std
::
vector
<
UInt
>
nb_local_per_proc
;
//! buffer data used to gather information on the one that will write to disk.
//! Only valid for root
static
std
::
vector
<
Real
*>
data_per_proc
;
/* ------------------------------------------------------------------------ */
DumperRestart
::
DumperRestart
(
const
std
::
string
&
name
)
:
LMObject
(
name
)
{
nb_local_dofs
=
0
;
allocated_size
=
0
;
data
=
NULL
;
text_flag
=
false
;
}
/* ------------------------------------------------------------------------ */
DumperRestart
::~
DumperRestart
()
{
// if (lm_my_proc_id == 0){
// //liberation de la memoire que je veux pas maintenir en parallel
// DUMP("freeing data_per_proc",DBG_INFO);
// for (UInt i = 1 ; i < lm_world_size ; ++i){
// DUMP("freeing ptr[" << i << "] " << data_per_proc[i],DBG_INFO);
// if (data_per_proc[i] != NULL){
// delete (data_per_proc[i]);
// data_per_proc[i] = NULL;
// }
// }
// nb_local_per_proc.clear();
// data_per_proc.clear();
// requests.clear();
// }
// if (data) delete(data);
}
/* ------------------------------------------------------------------------ */
void
DumperRestart
::
initVectors
(
CommGroup
&
group
)
{
UInt
my_rank
=
group
.
getMyRank
();
UInt
group_size
=
group
.
size
();
if
(
my_rank
==
0
)
{
nb_local_per_proc
.
resize
(
group_size
);
data_per_proc
.
resize
(
group_size
);
nb_local_per_proc
.
assign
(
group_size
,
0
);
data_per_proc
.
assign
(
group_size
,
0
);
for
(
UInt
i
=
0
;
i
<
group_size
;
++
i
)
data_per_proc
[
i
]
=
NULL
;
}
}
/* ------------------------------------------------------------------------ */
template
<
typename
Cont
>
void
DumperRestart
::
dump
(
Cont
&
cont
)
{
CommGroup
&
group
=
cont
.
getCommGroup
();
this
->
initVectors
(
group
);
UInt
my_rank
=
group
.
getMyRank
();
UInt
group_size
=
group
.
size
();
// MPI_Comm mpi_group = comm.getMpiGroup(group);
// UInt real_rank = group.absoluteRank(0);
// UInt mpi_root_rank = comm.real2groupRank(real_rank, group);
constexpr
UInt
Dim
=
Cont
::
Dim
;
LMFile
file
;
UInt
nbTotalDofs
=
0
;
if
(
my_rank
==
0
)
{
std
::
stringstream
temp
;
temp
<<
this
->
getBaseName
()
<<
"_restart-"
<<
std
::
setfill
(
'0'
)
<<
std
::
setw
(
4
)
<<
this
->
action_step
<<
".xml"
;
file
.
open
(
temp
.
str
(),
"wb"
,
true
);
b64
.
setOutputFile
(
file
);
}
bool
need_reallocate
=
false
;
if
(
allocated_size
<
cont
.
size
()
&&
cont
.
size
()
!=
0
)
need_reallocate
=
true
;
nb_local_dofs
=
cont
.
size
();
group
.
gather
(
&
nb_local_dofs
,
1
,
&
nb_local_per_proc
[
0
],
0
,
"gather nb local dofs"
);
DUMP
(
"Gather done"
,
DBG_INFO
);
if
(
my_rank
==
0
)
{
for
(
UInt
i
=
0
;
i
<
group_size
;
++
i
)
{
DUMP
(
"nb_local["
<<
i
<<
"]="
<<
nb_local_per_proc
[
i
]
<<
" "
<<
nb_local_dofs
,
DBG_INFO
);
nbTotalDofs
+=
nb_local_per_proc
[
i
];
}
printHeaders
(
nbTotalDofs
,
Dim
,
file
);
}
// allocation des array de stockage
if
(
need_reallocate
)
{
allocated_size
=
nb_local_dofs
;
DUMP
(
"(re)allocating for size = "
<<
nb_local_dofs
,
DBG_INFO
);
if
(
data
!=
NULL
)
data
=
(
Real
*
)
realloc
(
data
,
nb_local_dofs
*
sizeof
(
Real
)
*
Dim
);
else
{
data
=
(
Real
*
)
malloc
(
nb_local_dofs
*
sizeof
(
Real
)
*
Dim
);
memset
(
data
,
0
,
sizeof
(
Real
)
*
nb_local_dofs
*
Dim
);
}
}
if
(
my_rank
==
0
)
{
// je switch le pointeur pour les donnees locales
data_per_proc
[
0
]
=
data
;
for
(
UInt
i
=
1
;
i
<
group_size
;
++
i
)
{
if
(
nb_local_per_proc
[
i
]
==
0
)
continue
;
if
(
data_per_proc
[
i
]
!=
NULL
)
data_per_proc
[
i
]
=
(
Real
*
)
realloc
(
data_per_proc
[
i
],
sizeof
(
Real
)
*
nb_local_per_proc
[
i
]
*
Dim
);
else
{
data_per_proc
[
i
]
=
(
Real
*
)
malloc
(
sizeof
(
Real
)
*
nb_local_per_proc
[
i
]
*
Dim
);
memset
(
data_per_proc
[
i
],
0
,
sizeof
(
Real
)
*
nb_local_per_proc
[
i
]
*
Dim
);
}
}
}
// chaqun construit en parallele les data qu'il veut envoyer
UInt
cpt
=
0
;
for
(
auto
&&
at
:
cont
)
{
auto
X
=
at
.
position0
();
for
(
UInt
i
=
0
;
i
<
Dim
;
++
i
)
data
[
cpt
*
Dim
+
i
]
=
X
[
i
];
++
cpt
;
}
DUMP
(
"a la fin cpt = "
<<
cpt
,
DBG_INFO
);
DUMP
(
"local P0 construction done"
,
DBG_INFO
);
DumpField
<
Dim
>
(
"P0"
,
file
,
group
);
cpt
=
0
;
for
(
auto
&&
at
:
cont
)
{
auto
U
=
at
.
displacement
();
for
(
UInt
i
=
0
;
i
<
Dim
;
++
i
)
data
[
cpt
*
Dim
+
i
]
=
U
[
i
];
++
cpt
;
}
DUMP
(
"local U construction done"
,
DBG_INFO
);
DumpField
<
Dim
>
(
"U"
,
file
,
group
);
cpt
=
0
;
for
(
auto
&&
at
:
cont
)
{
auto
V
=
at
.
velocity
();
for
(
UInt
i
=
0
;
i
<
Dim
;
++
i
)
data
[
cpt
*
Dim
+
i
]
=
V
[
i
];
++
cpt
;
}
DUMP
(
"local V construction done"
,
DBG_INFO
);
DumpField
<
Dim
>
(
"V"
,
file
,
group
);
// on fait le champ de position P0
// je rassemble le tout en local
if
(
my_rank
==
0
)
{
printTail
(
file
);
file
.
close
();
}
group
.
synchronize
();
}
/* ------------------------------------------------------------------------ */
template
<
UInt
Dim
>
inline
void
DumperRestart
::
DumpField
(
const
std
::
string
&
fieldName
,
LMFile
&
file
,
CommGroup
&
group
)
{
UInt
group_size
=
group
.
size
();
UInt
my_rank
=
group
.
getMyRank
();
// MPI_Comm mpi_group = comm.getMpiGroup(group);
// MPI_Status status;
if
(
my_rank
==
0
)
{
// I switch the pointer for local data
for
(
UInt
i
=
1
;
i
<
group_size
;
++
i
)
{
if
(
nb_local_per_proc
[
i
]
==
0
)
continue
;
DUMP
(
"pending recv from "
<<
i
<<
" of size "
<<
nb_local_per_proc
[
i
]
<<
" ..."
,
DBG_INFO
);
group
.
receive
(
data_per_proc
[
i
],
nb_local_per_proc
[
i
]
*
Dim
,
i
,
"restart data per proc"
);
DUMP
(
"pending recv from "
<<
i
<<
" of size "
<<
nb_local_per_proc
[
i
]
<<
" ... done"
,
DBG_INFO
);
}
}
else
if
(
nb_local_dofs
!=
0
)
{
DUMP
(
"sending to root "
<<
nb_local_dofs
<<
" ..."
,
DBG_INFO
);
group
.
send
(
data
,
nb_local_dofs
*
Dim
,
0
,
"restart data per proc"
);
DUMP
(
"sending to root "
<<
nb_local_dofs
<<
" ... done"
,
DBG_INFO
);
}
if
(
my_rank
==
0
)
{
if
(
!
text_flag
)
b64
.
clearBuffer
();
file
.
printf
(
"<%s>
\n
"
,
fieldName
.
c_str
());
for
(
int
i
=
group_size
-
1
;
i
>
-
1
;
--
i
)
{
DUMP
(
"waiting com from "
<<
i
,
DBG_INFO
);
// attend les coms avant d'ecrire sur disque
if
(
i
>
0
&&
nb_local_per_proc
[
i
]
>
0
)
{
LM_TOIMPLEMENT
;
// MPI_Wait(&requests[i], &status);
}
DUMP
(
"reception from "
<<
i
<<
" complete"
,
DBG_INFO
);
for
(
UInt
j
=
0
;
j
<
nb_local_per_proc
[
i
];
++
j
)
{
if
(
text_flag
)
{
for
(
UInt
k
=
0
;
k
<
Dim
;
++
k
)
{
file
.
printf
(
"%.15e"
,
data_per_proc
[
i
][
j
*
Dim
+
k
]);
if
(
k
!=
Dim
-
1
)
file
.
printf
(
"
\t
"
);
}
file
.
printf
(
"
\n
"
);
}
else
{
for
(
UInt
k
=
0
;
k
<
Dim
;
++
k
)
{
b64
.
pushRealInBase64
(
data_per_proc
[
i
][
j
*
Dim
+
k
]);
}
}
}
}
if
(
!
text_flag
)
{
b64
.
finish
();
b64
.
dumpToFile
();
}
file
.
printf
(
"</%s>
\n
"
,
fieldName
.
c_str
());
}
}
/* ------------------------------------------------------------------------ */
void
DumperRestart
::
printHeaders
(
UInt
nbDofs
,
const
UInt
Dim
,
LMFile
&
file
)
{
file
.
printf
(
"<?xml version=
\"
1.0
\"
encoding=
\"
UTF-8
\"
?>
\n
"
);
file
.
printf
(
"<SimulationData nbDofs=
\"
%d
\"
dim=
\"
%d
\"
timestep=
\"
%d
\"
"
,
nbDofs
,
Dim
,
current_step
);
if
(
text_flag
==
true
)
file
.
printf
(
" dataType=
\"
TEXT
\"
>
\n
"
);
else
file
.
printf
(
" dataType=
\"
BINARY
\"
>
\n
"
);
}
/* ------------------------------------------------------------------------ */
void
DumperRestart
::
printTail
(
LMFile
&
file
)
{
file
.
printf
(
"</SimulationData>
\n
"
);
}
/* ------------------------------------------------------------------------ */
/* LMDESC RESTART
This dumper saves the state of the simulation in order to allow
restarting
simulations from
*/
/* LMEXAMPLE DUMPER res RESTART INPUT md PREFIX /home/titeuf */
/* LMHERITANCE dumper */
void
DumperRestart
::
declareParams
()
{
DumperInterface
::
declareParams
();
/* LMKEYWORD TEXT
Flag to request human-readable text output instead of binary.
*/
this
->
parseTag
(
"TEXT"
,
text_flag
,
false
);
}
/* ------------------------------------------------------------------------ */
DECLARE_DUMPER_MAKE_CALL
(
DumperRestart
);
__END_LIBMULTISCALE__
Event Timeline
Log In to Comment