Program Listing for File attributed_edge_index.h¶
↰ Return to documentation for file (include/shad/extensions/graph_library/attributed_edge_index.h
)
//===------------------------------------------------------------*- C++ -*-===//
//
// SHAD
//
// The Scalable High-performance Algorithms and Data Structure Library
//
//===----------------------------------------------------------------------===//
//
// Copyright 2018 Battelle Memorial Institute
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
// of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
//
//===----------------------------------------------------------------------===//
#ifndef INCLUDE_SHAD_EXTENSIONS_GRAPH_LIBRARY_ATTRIBUTED_EDGE_INDEX_H_
#define INCLUDE_SHAD_EXTENSIONS_GRAPH_LIBRARY_ATTRIBUTED_EDGE_INDEX_H_
#include <algorithm>
#include <atomic>
#include <memory>
#include <tuple>
#include <utility>
#include <vector>
#include "shad/data_structures/compare_and_hash_utils.h"
#include "shad/data_structures/local_hashmap.h"
#include "shad/data_structures/local_set.h"
#include "shad/extensions/graph_library/edge_index.h"
#include "shad/extensions/graph_library/local_edge_index.h"
#include "shad/runtime/runtime.h"
namespace shad {
template <typename SrcAttrT, typename DestT>
class AttrEdgesPair {
public:
SrcAttrT attributes_;
LocalSet<DestT> neighbors_;
size_t Size() { return neighbors_.Size(); }
void Erase(const DestT &dest) { neighbors_.Erase(dest); }
void AsyncErase(rt::Handle &handle, const DestT &dest) {
neighbors_.Erase(handle, dest);
}
void Insert(const DestT &dest) { neighbors_.Insert(dest); }
void AsyncInsert(rt::Handle &handle, const DestT &dest) {
neighbors_.AsyncInsert(handle, dest);
}
template <typename ApplyFunT, typename... Args>
void ForEachNeighbor(ApplyFunT &&function, Args &... args) {
neighbors_.ForEachNeighbor(function, args...);
}
template <typename ApplyFunT, typename... Args>
void AsyncForEachNeighbor(rt::Handle &handle, ApplyFunT &&function,
Args &... args) {
neighbors_.AsyncForEachNeighbor(handle, function, args...);
}
};
template <typename SrcT, typename DestT, typename SrcAttrT,
typename NeighborsStorageT = AttrEdgesPair<SrcAttrT, DestT>>
class AttributedEdgeIndexStorage {
public:
using SrcAttributesT = SrcAttrT;
explicit AttributedEdgeIndexStorage(const size_t numVertices)
: edgeList_(std::max(numVertices / constants::kDefaultNumEntriesPerBucket,
1lu)) {}
static constexpr size_t kEdgeListChunkSize_ = 3072 / sizeof(DestT);
struct LocalEdgeListChunk {
LocalEdgeListChunk(size_t _numDest, bool _ow, DestT *_dest)
: numDest(_numDest), overwrite(_ow) {
memcpy(destinations.data(), _dest,
std::min(numDest, destinations.size()) * sizeof(DestT));
}
size_t numDest;
size_t chunkSize;
bool overwrite;
std::array<DestT, kEdgeListChunkSize_> destinations;
};
struct FlatEdgeList {
const DestT *values;
size_t numValues;
bool overwrite;
};
struct ElementInserter {
void operator()(NeighborsStorageT *const lhs, const NeighborsStorageT &) {}
static void Insert(NeighborsStorageT *const lhs, const DestT value) {
lhs->neighbors_.Insert(value);
}
static void Insert(NeighborsStorageT *const lhs,
const FlatEdgeList values) {
if (values.overwrite) lhs->neighbors_.Reset(values.numValues);
for (size_t i = 0; i < values.numValues; i++) {
lhs->neighbors_.Insert(values.values[i]);
}
}
static void Insert(NeighborsStorageT *const lhs,
const LocalEdgeListChunk &chunk) {
if (chunk.overwrite) lhs->neighbors_.Reset(chunk.numDest);
size_t chunkSize = std::min(chunk.numDest, chunk.destinations.size());
for (size_t i = 0; i < chunkSize; i++) {
lhs->neighbors_.Insert(chunk.destinations[i]);
}
}
};
SrcAttributesT *GetVertexAttributes(const SrcT &src) {
SrcAttributesT *res = nullptr;
NeighborsStorageT *entry = edgeList_.Lookup(src);
if (entry != nullptr) {
return entry->attributes_;
}
return res;
}
bool GetVertexAttributes(const SrcT &src, SrcAttributesT *attr) {
NeighborsStorageT *entry = edgeList_.Lookup(src);
if (entry != nullptr) {
*attr = entry->attributes_;
return true;
}
return false;
}
template <typename ApplyFunT, typename... Args>
void VertexAttributesApply(const SrcT &src, ApplyFunT &&function,
Args &... args) {
NeighborsStorageT *entry = edgeList_.Lookup(src);
if (entry != nullptr) {
function(src, entry->attributes_, args...);
}
}
using NeighborListStorageT = NeighborsStorageT;
using EdgeListStorageT =
LocalHashmap<SrcT, NeighborsStorageT, IDCmp<SrcT>, ElementInserter>;
EdgeListStorageT edgeList_;
template <typename ApplyFunT, typename... Args, std::size_t... is>
static void CallVertexAttributesApplyFun(
AttributedEdgeIndexStorage<SrcT, DestT, SrcAttrT, NeighborListStorageT>
*stPtr,
const SrcT &src, ApplyFunT function, std::tuple<Args...> &args,
std::index_sequence<is...>) {
NeighborsStorageT *entry = stPtr->edgeList_.Lookup(src);
if (entry != nullptr) {
function(src, entry->attributes_, std::get<is>(args)...);
}
}
};
template <typename SrcT, typename SrcAttrT, typename DestT>
using LocalAttributedEdgeIndex =
LocalEdgeIndex<SrcT, DestT,
AttributedEdgeIndexStorage<SrcT, DestT, SrcAttrT>>;
template <typename SrcT, typename SrcAttrT, typename DestT>
using AttributedEdgeIndex =
EdgeIndex<SrcT, DestT, AttributedEdgeIndexStorage<SrcT, DestT, SrcAttrT>>;
} // namespace shad
#endif // INCLUDE_SHAD_EXTENSIONS_GRAPH_LIBRARY_ATTRIBUTED_EDGE_INDEX_H_