Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F64209463
ref_subset.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
Sat, May 25, 08:27
Size
11 KB
Mime Type
text/x-c++
Expires
Mon, May 27, 08:27 (1 d, 23 h)
Engine
blob
Format
Raw Data
Handle
17868016
Attached To
rLIBMULTISCALE LibMultiScale
ref_subset.cc
View Options
/**
* @file ref_subset.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
* @date Mon Sep 08 23:40:22 2014
*
* @brief This file contains the interface of containers of references 4 the
* migration system
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* LibMultiScale is free software: you can redistribute it and/or modify it
* under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* LibMultiScale is distributed in the hope that it will be useful, but
* WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with LibMultiScale. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include <boost/preprocessor.hpp>
/* -------------------------------------------------------------------------- */
#include "lib_continuum.hh"
#include "lib_dd.hh"
#include "lib_md.hh"
#include "lm_common.hh"
#include "ref_subset.hh"
#include "trace_atom.hh"
#include <boost/preprocessor.hpp>
/* -------------------------------------------------------------------------- */
__BEGIN_LIBMULTISCALE__
/* -------------------------------------------------------------------------- */
template
<
typename
Ref
,
bool
is_subset
>
void
RefSubset
<
Ref
,
is_subset
>::
declareSentRefs
(
MapRefToUInt
&
sent_refs
,
MapUIntToRefList
&
sent_reverse
)
{
DUMP
(
"declare refs sent for subset "
<<
container
.
getID
(),
DBG_INFO
);
// clear maps
sent
.
clear
();
sent_indexes
.
clear
();
MapRefToUInt
sent_index_in_subset
;
// loop over subset refs
if
constexpr
(
is_subset
)
{
for
(
auto
&&
[
i
,
ref
]
:
enumerate
(
container
))
{
// get the reference to the ref "i" in subset
if
(
sent_refs
.
count
(
ref
)
>
0
)
{
if
(
sent_refs
[
ref
]
==
UINT_MAX
)
continue
;
sent_index_in_subset
[
ref
]
=
i
;
holes
.
push_back
(
i
);
}
}
}
// loop over the sent refs to build ordered buffer list
UInt
idx
;
for
(
auto
&&
[
proc
,
listsent
]
:
sent_reverse
)
{
for
(
auto
&&
ref
:
listsent
)
{
if
(
is_subset
and
not
sent_index_in_subset
.
count
(
ref
))
continue
;
if
constexpr
(
not
is_subset
)
{
idx
=
ref
.
getIndex
();
}
else
{
idx
=
sent_index_in_subset
[
ref
];
}
sent
[
proc
].
push_back
(
ref
);
sent_indexes
[
proc
].
push_back
(
idx
);
IF_REF_TRACED
(
ref
,
"traced ref sent to "
<<
proc
<<
" for container "
<<
container
.
getID
());
}
for
(
auto
&&
[
proc
,
list_sent
]
:
sent
)
{
DUMP
(
"I am supposed to send "
<<
list_sent
.
size
()
<<
" refs to proc "
<<
proc
<<
" for subset "
<<
container
.
getID
()
<<
"("
<<
subset_id
<<
")"
,
DBG_INFO
);
}
}
}
/* ------------------------------------------------------------------------ */
template
<
typename
Ref
,
bool
is_subset
>
void
RefSubset
<
Ref
,
is_subset
>::
declareRecvRefs
(
MapRefToUInt
&
masks
,
MapUIntToRefList
&
recv_refs
)
{
DUMP
(
"declare refs received for subset "
<<
container
.
getID
(),
DBG_INFO
);
UInt
mask
[[
gnu
::
unused
]]
=
1
<<
subset_id
;
// clear maps
recv
.
clear
();
recv_indexes
.
clear
();
auto
register_newref
=
[
&
](
auto
proc
,
auto
new_index
,
auto
&
ref
)
{
IF_REF_TRACED
(
ref
,
"traced ref received from "
<<
proc
<<
" for container "
<<
container
.
getID
()
<<
" (index is now "
<<
new_index
<<
")"
);
recv_indexes
[
proc
].
push_back
(
new_index
);
recv
[
proc
].
push_back
(
ref
);
};
for
(
auto
&&
[
proc
,
recvlist
]
:
recv_refs
)
{
for
(
auto
&&
ref
:
recvlist
)
{
if
constexpr
(
is_subset
)
{
// check if concerned with ref => register
if
(
masks
[
ref
]
&
mask
)
{
UInt
new_index
;
// find a new index (if possible within holes)
if
(
!
holes
.
empty
())
{
new_index
=
holes
.
back
();
container
.
get
(
new_index
)
=
ref
;
holes
.
pop_back
();
}
else
{
new_index
=
container
.
size
();
container
.
push_back
(
ref
);
}
register_newref
(
proc
,
new_index
,
ref
);
}
}
else
{
register_newref
(
proc
,
ref
.
getIndex
(),
ref
);
}
}
}
for
(
auto
&&
[
proc
,
recvlist
]
:
recv_indexes
)
{
DUMP
(
"I am supposed to recv "
<<
recvlist
.
size
()
<<
" refs from proc "
<<
proc
<<
" for subset "
<<
container
.
getID
()
<<
"("
<<
subset_id
<<
")"
,
DBG_INFO
);
}
}
/* ----------------------------------------------------------------------- */
template
<
typename
Ref
,
bool
is_subset
>
void
RefSubset
<
Ref
,
is_subset
>::
buildMasksForSentRefs
(
MapRefToUInt
&
masks
)
{
if
constexpr
(
not
is_subset
)
return
;
UInt
mask
=
1
<<
subset_id
;
for
(
auto
&&
[
proc
,
reflist
]
:
sent
)
{
UInt
nRefs
=
reflist
.
size
();
for
(
UInt
i
=
0
;
i
<
nRefs
;
++
i
)
{
Ref
ref
=
reflist
[
i
];
if
(
!
masks
.
count
(
ref
))
masks
[
ref
]
=
mask
;
else
masks
[
ref
]
|=
mask
;
}
}
}
/* ----------------------------------------------------------------------- */
template
<
typename
Ref
,
bool
is_subset
>
void
RefSubset
<
Ref
,
is_subset
>::
packAttachedData
(
std
::
map
<
UInt
,
PackBuffer
>
&
buffer
)
{
for
(
auto
&&
[
proc
,
listsent
]
:
sent_indexes
)
{
if
(
proc
==
UINT_MAX
)
continue
;
for
(
auto
&&
[
i
,
sent_index
]
:
enumerate
(
listsent
))
{
if
(
this
->
attached_objects
.
size
()
>
0
)
DUMP
(
container
.
getID
()
<<
" prepares to pack to proc "
<<
proc
<<
" subset index "
<<
i
<<
" ref index "
<<
sent_index
,
DBG_MESSAGE
);
for
(
auto
&&
[
ptr
,
att_obj
]
:
this
->
attached_objects
)
{
DUMP
(
"prepares to pack obj "
<<
att_obj
->
getID
(),
DBG_MESSAGE
);
att_obj
->
packData
(
sent_index
,
buffer
[
proc
],
proc
,
true
);
}
}
}
}
/* ------------------------------------------------------------------------ */
template
<
typename
Ref
,
bool
is_subset
>
void
RefSubset
<
Ref
,
is_subset
>::
unpackAttachedData
(
std
::
map
<
UInt
,
PackBuffer
>
&
buffer
)
{
for
(
auto
&&
[
proc
,
listrecv
]
:
recv_indexes
)
{
if
(
proc
==
UINT_MAX
)
continue
;
for
(
auto
&&
[
i
,
recv_index
]
:
enumerate
(
listrecv
))
{
if
(
CHECK_REF_TRACED
(
recv
[
proc
][
i
]))
DUMP
(
container
.
getID
()
<<
" prepares to unpack from proc "
<<
proc
<<
" subset index "
<<
i
<<
" ref index "
<<
recv_index
,
DBG_MESSAGE
);
for
(
auto
&&
[
ptr
,
att_obj
]
:
this
->
attached_objects
)
{
if
(
CHECK_REF_TRACED
(
recv
[
proc
][
i
]))
DUMP
(
"prepares to pack obj "
<<
att_obj
->
getID
(),
DBG_MESSAGE
);
att_obj
->
unpackData
(
recv_index
,
buffer
[
proc
],
proc
,
CHECK_REF_TRACED
(
recv
[
proc
][
i
]));
}
}
}
}
/* --------------------------------------------------------------------------
*/
template
<
typename
Ref
,
bool
is_subset
>
void
RefSubset
<
Ref
,
is_subset
>::
translateMovingReferences
(
MapRefToRef
&
moved
)
{
if
constexpr
(
not
is_subset
)
return
;
// loop over the contained refs and shift references of moved refs
UInt
nRefs
=
container
.
size
();
for
(
UInt
i
=
0
;
i
<
nRefs
;
++
i
)
{
// get the reference to the ref "i"
Ref
&
ref
=
container
.
get
(
i
);
if
(
moved
.
count
(
ref
))
{
DUMP
(
"translating ref in subset "
<<
subset_id
<<
" numero "
<<
i
<<
" from position "
<<
ref
<<
" to position "
<<
moved
[
ref
],
DBG_INFO
);
IF_REF_TRACED
(
ref
,
container
.
getID
()
<<
": translate ref("
<<
i
<<
") "
<<
ref
<<
" to ref "
<<
moved
[
ref
]);
ref
=
moved
[
ref
];
}
}
}
/* --------------------------------------------------------------------------
*/
template
<
typename
Ref
,
bool
is_subset
>
void
RefSubset
<
Ref
,
is_subset
>::
fillRemainingHoles
()
{
if
constexpr
(
not
is_subset
)
return
;
// checks if there are remaining holes for which we need to displace
// the references order and attached values
while
(
!
holes
.
empty
())
{
UInt
index
=
holes
.
back
();
holes
.
pop_back
();
UInt
nRefs
=
container
.
size
();
if
(
index
==
nRefs
-
1
)
// container.resize(nRefs-1);
resize
(
nRefs
-
1
);
else
moveLastReference
(
index
);
}
}
/* --------------------------------------------------------------------------
*/
template
<
typename
Ref
,
bool
is_subset
>
void
RefSubset
<
Ref
,
is_subset
>::
moveReference
(
UInt
i_src
,
UInt
i_dest
)
{
if
(
i_src
==
i_dest
)
return
;
IF_REF_TRACED
(
container
.
get
(
i_src
),
"traced ref moved from index "
<<
i_src
<<
" to index "
<<
i_dest
<<
" for container "
<<
&
container
);
DUMP
(
"ref moved from index "
<<
i_src
<<
" to index "
<<
i_dest
<<
" for container "
<<
&
container
,
DBG_INFO
);
if
constexpr
(
is_subset
)
container
.
get
(
i_dest
)
=
container
.
get
(
i_src
);
for
(
auto
&&
[
ptr
,
att_obj
]
:
this
->
attached_objects
)
{
att_obj
->
moveAttachedValues
(
i_src
,
i_dest
);
}
}
/* ------------------------------------------------------------------------ */
template
<
typename
Ref
,
bool
is_subset
>
void
RefSubset
<
Ref
,
is_subset
>::
moveLastReference
(
UInt
i_dest
)
{
if
constexpr
(
not
is_subset
)
return
;
UInt
nRefs
=
container
.
size
();
if
(
nRefs
-
1
==
i_dest
)
return
;
moveReference
(
nRefs
-
1
,
i_dest
);
// container.resize(nRefs-1);
resize
(
nRefs
-
1
);
}
/* --------------------------------------------------------------------------
*/
template
<
typename
Ref
,
bool
is_subset
>
UInt
RefSubset
<
Ref
,
is_subset
>::
resize
(
UInt
sz
)
{
if
constexpr
(
is_subset
)
{
if
(
sz
==
UInt
(
-
1
))
LM_FATAL
(
"this should not happen"
);
container
.
resize
(
sz
);
}
else
{
if
(
sz
!=
UInt
(
-
1
))
LM_FATAL
(
"this should not happen"
);
sz
=
container
.
size
();
}
DUMP
(
container
.
getID
()
<<
" resizes from "
<<
container
.
size
()
<<
" to "
<<
sz
,
DBG_INFO
);
for
(
auto
&&
[
ptr
,
att_obj
]
:
this
->
attached_objects
)
{
att_obj
->
resize
(
sz
);
}
return
sz
;
}
/* --------------------------------------------------------------------------
*/
#define DECLARE_REF_SUBSET(n, data, obj) \
template class RefSubset<ContainerArray<typename BOOST_PP_TUPLE_ELEM( \
3, 0, obj)::ContainerPoints::Ref>, \
true>; \
template class RefSubset< \
typename BOOST_PP_TUPLE_ELEM(3, 0, obj)::ContainerPoints, false>;
BOOST_PP_SEQ_FOR_EACH
(
DECLARE_REF_SUBSET
,
f
,
LIST_ATOM_MODEL
)
BOOST_PP_SEQ_FOR_EACH
(
DECLARE_REF_SUBSET
,
f
,
LIST_DD_MODEL
)
BOOST_PP_SEQ_FOR_EACH
(
DECLARE_REF_SUBSET
,
f
,
LIST_CONTINUUM_MODEL
)
#undef DECLARE_REF_SUBSET
__END_LIBMULTISCALE__
Event Timeline
Log In to Comment