Page MenuHomec4science

ref_subset.hh
No OneTemporary

File Metadata

Created
Mon, Sep 2, 00:26

ref_subset.hh

/**
* @file ref_subset.hh
*
* @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/>.
*
*/
#ifndef __LIBMULTISCALE_REF_SUBSET_HH__
#define __LIBMULTISCALE_REF_SUBSET_HH__
/* -------------------------------------------------------------------------- */
#include <map>
#include <vector>
/* -------------------------------------------------------------------------- */
#include "attached_object.hh"
#include "pack_buffer.hh"
/* -------------------------------------------------------------------------- */
__BEGIN_LIBMULTISCALE__
/* -------------------------------------------------------------------------- */
class ContainerInterface;
/* -------------------------------------------------------------------------- */
template <typename Ref> class RefSubsetInterface {
public:
using MapUIntToUIntList = std::map<UInt, std::vector<UInt>>;
using MapRefToRef = std::map<Ref, Ref, typename Ref::RefComparator>;
using MapRefToUInt = std::map<Ref, UInt, typename Ref::RefComparator>;
using MapUIntToRefList = std::map<UInt, std::vector<Ref>>;
//! return the container being this reference set
virtual ContainerInterface &getContainer() = 0;
//! declare the refs sent to other processors
virtual void declareSentRefs(MapRefToUInt &sent_refs,
MapUIntToRefList &sent_reverse) = 0;
//! declare the refs received from other processors
virtual void declareRecvRefs(MapRefToUInt &masks,
MapUIntToRefList &recv_refs) = 0;
//! build the mask for the sent refs
virtual void buildMasksForSentRefs(MapRefToUInt &masks) = 0;
//! translate the internal references
virtual void translateMovingReferences(MapRefToRef &moved) = 0;
//! pack attached data
virtual void packAttachedData(std::map<UInt, PackBuffer> &buffer) = 0;
//! unpack attached data
virtual void unpackAttachedData(std::map<UInt, PackBuffer> &buffer) = 0;
//! fill remaining holes so that container is one pack
virtual void fillRemainingHoles() = 0;
//! resize container and attached values
virtual UInt resize(UInt sz = -1) = 0;
//! attach a vector of data to the subset
void attachData(std::shared_ptr<AttachedObject> &obj);
//! detach a vector of data from the subset
void detachData(std::shared_ptr<AttachedObject> &obj);
virtual bool isSubset() = 0;
protected:
//! list of attached objects
std::map<LMID, std::shared_ptr<AttachedObject>> attached_objects;
};
/* -------------------------------------------------------------------------- */
template <typename Cont, bool is_subset>
class RefSubset : public RefSubsetInterface<typename Cont::Ref> {
using Ref = typename Cont::Ref;
using MapRefToUInt = std::map<Ref, UInt, typename Ref::RefComparator>;
using MapRefToRef = std::map<Ref, Ref, typename Ref::RefComparator>;
using MapUIntToRefList = std::map<UInt, std::vector<Ref>>;
using MapUIntToUIntList = std::map<UInt, std::vector<UInt>>;
public:
RefSubset(Cont &cont, UInt subset_id)
: container(cont), subset_id(subset_id){};
virtual ~RefSubset(){};
bool isSubset() override { return is_subset; }
//! declare the refs sent to other processors
void declareSentRefs(MapRefToUInt &sent_refs, MapUIntToRefList &sent_reverse);
//! declare the refs received from other processors
void declareRecvRefs(MapRefToUInt &masks, MapUIntToRefList &recv_refs);
//! translate the internal references
void translateMovingReferences(MapRefToRef &moved);
//! fill remaining holes so that container is one pack
void fillRemainingHoles() override;
//! build the mask for the sent refs
void buildMasksForSentRefs(MapRefToUInt &masks);
//! pack attached data
void packAttachedData(std::map<UInt, PackBuffer> &buffer);
//! unpack attached data
void unpackAttachedData(std::map<UInt, PackBuffer> &buffer);
//! move last reference in the array (useful to fill holes)
void moveLastReference(UInt i_dest);
//! move reference in the array
void moveReference(UInt i_src, UInt i_dest);
//! resize container and attached values
UInt resize(UInt sz = -1);
//! return the container being this reference set
ContainerInterface &getContainer() { return container; };
private:
// list of holes created by the gone refs
std::vector<int> holes;
//! container of references that constitutes the subset
Cont &container;
//! map new proc to the list of refs that have been sent
MapUIntToRefList sent;
//! map old proc to the list of refs that have been received
MapUIntToRefList recv;
//! map new proc to the list of refs indexes that have been sent
MapUIntToUIntList sent_indexes;
//! map old proc to the list of refs indexes that have been received
MapUIntToUIntList recv_indexes;
// id of the subset
UInt subset_id;
};
/* -------------------------------------------------------------------------- */
// attach a vector of data to the subset
template <typename Ref>
void RefSubsetInterface<Ref>::attachData(std::shared_ptr<AttachedObject> &obj) {
DUMP("want to register obj " << &obj, DBG_DETAIL);
for (auto &&[name, att_obj] : attached_objects) {
if (name == obj->getID()) {
LM_FATAL("obj " << obj->getID() << " was already attached in the past");
}
}
attached_objects[obj->getID()] = obj;
}
/* -------------------------------------------------------------------------- */
// detach a vector of data from the subset
template <typename Ref>
void RefSubsetInterface<Ref>::detachData(std::shared_ptr<AttachedObject> &obj) {
attached_objects.erase(obj->getID());
}
/* -------------------------------------------------------------------------- */
template <bool is_subset, typename Cont>
auto make_subset(Cont &cont, UInt subset_id) {
static_assert(is_subset ==
std::is_same_v<typename Cont::ContainerSubset, Cont>,
"This situation should not happen");
return std::make_shared<RefSubset<Cont, is_subset>>(cont, subset_id);
}
__END_LIBMULTISCALE__
#endif /* __LIBMULTISCALE_REF_SUBSET_HH__ */

Event Timeline