Skip to content

Commit

Permalink
Added pod local storage
Browse files Browse the repository at this point in the history
Former-commit-id: 8201ee32e016d394bd1f90af23bf9d26ef16074c
  • Loading branch information
tewaro committed Mar 30, 2024
1 parent 30b5e8f commit 7be7882
Show file tree
Hide file tree
Showing 6 changed files with 441 additions and 1 deletion.
300 changes: 300 additions & 0 deletions include/pando-lib-galois/containers/pod_local_storage.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,300 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2023. University of Texas at Austin. All rights reserved.

// SPDX-License-Identifier: MIT
// Copyright (c) 2023-2024. University of Texas at Austin. All rights reserved.

#ifndef PANDO_LIB_GALOIS_CONTAINERS_POD_LOCAL_STORAGE_HPP_
#define PANDO_LIB_GALOIS_CONTAINERS_POD_LOCAL_STORAGE_HPP_

#include <pando-rt/export.h>

#include <utility>

#include <pando-lib-galois/loops/do_all.hpp>
#include <pando-rt/memory/allocate_memory.hpp>
#include <pando-rt/pando-rt.hpp>
#include <pando-rt/specific_storage.hpp>
#include <pando-rt/utility/expected.hpp>

namespace galois {

namespace PodLocalStorageHeap {

constexpr std::uint64_t Size = 1 << 10;
constexpr std::uint64_t Granule = 128;
struct ModestArray {
std::byte arr[Size];
};

extern pando::PodSpecificStorage<ModestArray> heap;
extern pando::SlabMemoryResource<Granule>* LocalHeapSlab;

void HeapInit();

template <typename T>
[[nodiscard]] pando::Expected<pando::PodSpecificStorageAlias<T>> allocate() {
auto ptr = LocalHeapSlab->allocate(sizeof(T));
if (ptr == nullptr) {
return pando::Status::BadAlloc;
}
pando::GlobalPtr<T> ptrT = static_cast<pando::GlobalPtr<T>>(ptr);
auto heapAlias = pando::PodSpecificStorageAlias<ModestArray>(heap);
return heapAlias.getStorageAliasAt(ptrT);
}

template <typename T>
void deallocate(pando::PodSpecificStorageAlias<T> toDeAlloc) {
auto size = sizeof(T);
auto ptrStartTyped = toDeAlloc.getPointerAt(pando::NodeIndex{0}, pando::PodIndex{0, 0});
pando::GlobalPtr<void> ptrStartVoid = static_cast<pando::GlobalPtr<void>>(ptrStartTyped);
LocalHeapSlab->deallocate(ptrStartVoid, size);
}
} // namespace PodLocalStorageHeap

template <typename T>
class PodLocalStorageIt;

template <typename T>
class PodLocalStorage {
pando::PodSpecificStorageAlias<T> m_items{};

public:
PodLocalStorage() noexcept = default;
PodLocalStorage(const PodLocalStorage&) = default;
PodLocalStorage(PodLocalStorage&&) = default;

~PodLocalStorage() = default;

PodLocalStorage& operator=(const PodLocalStorage&) = default;
PodLocalStorage& operator=(PodLocalStorage&&) = default;

using iterator = PodLocalStorageIt<T>;
using reverse_iterator = std::reverse_iterator<iterator>;

[[nodiscard]] constexpr std::uint64_t getNumPods() const noexcept {
const auto p = pando::getPlaceDims();
return static_cast<std::uint64_t>(p.node.id * p.pod.x * p.pod.y);
}

[[nodiscard]] constexpr std::uint64_t getCurrentPodIdx() const noexcept {
const auto dim = pando::getPlaceDims();
const auto cur = pando::getCurrentPlace();
return static_cast<std::uint64_t>(cur.node.id * dim.pod.x * dim.pod.y + cur.pod.x * dim.pod.y +
cur.pod.y);
}

[[nodiscard]] constexpr pando::Place getPlaceFromPodIdx(std::uint64_t idx) const noexcept {
const auto dim = pando::getPlaceDims();
const auto pods = dim.pod.x * dim.pod.y;
const pando::NodeIndex node = pando::NodeIndex(idx / pods);
const std::int16_t localPodIdx = idx % pods;
const pando::PodIndex pod = pando::PodIndex(localPodIdx / dim.pod.x, localPodIdx % dim.pod.x);
return pando::Place(node, pod, pando::anyCore);
}

std::uint64_t size() {
return getNumPods();
}

[[nodiscard]] pando::Status initialize() {
m_items = PANDO_EXPECT_RETURN(PodLocalStorageHeap::allocate<T>());
return pando::Status::Success;
}

void deinitialize() {
PodLocalStorageHeap::deallocate(m_items);
}

pando::GlobalRef<T> getLocal() noexcept {
return *m_items.getPointer();
}

pando::GlobalRef<T> get(std::uint64_t i) noexcept {
auto place = getPlaceFromPodIdx(i);
return *m_items.getPointerAt(place.node, place.pod);
}

template <typename Y>
pando::GlobalRef<T> getFromPtr(pando::GlobalPtr<Y> ptr) {
std::uint64_t i = static_cast<std::uint64_t>(pando::localityOf(ptr).node.id);
return this->get(i);
}

iterator begin() noexcept {
return iterator(*this, 0);
}

iterator begin() const noexcept {
return iterator(*this, 0);
}

iterator end() noexcept {
return iterator(*this, getNumPods());
}

iterator end() const noexcept {
return iterator(*this, getNumPods());
}

/**
* @brief reverse iterator to the first element
*/
reverse_iterator rbegin() noexcept {
return reverse_iterator(end()--);
}

/**
* @copydoc rbegin()
*/
reverse_iterator rbegin() const noexcept {
return reverse_iterator(end()--);
}

/**
* @brief reverse iterator to the last element
*/
reverse_iterator rend() noexcept {
return reverse_iterator(begin()--);
}

/**
* @copydoc rend()
*/
reverse_iterator rend() const noexcept {
return reverse_iterator(begin()--);
}

friend bool operator==(const PodLocalStorage& a, const PodLocalStorage& b) {
const pando::NodeIndex node(0);
const pando::PodIndex pod(0, 0);
return a.m_items.getPointerAt(node, pod) == b.m_items.getPointerAt(node, pod);
}

friend bool operator!=(const PodLocalStorage& a, const PodLocalStorage& b) {
return !(a == b);
}
};

template <typename T>
class PodLocalStorageIt {
PodLocalStorage<T> m_curr;
std::uint64_t m_loc;

public:
using iterator_category = std::random_access_iterator_tag;
using difference_type = std::int64_t;
using value_type = T;
using pointer = pando::GlobalPtr<T>;
using reference = pando::GlobalRef<T>;

PodLocalStorageIt(PodLocalStorage<T> curr, std::uint64_t loc) : m_curr(curr), m_loc(loc) {}

constexpr PodLocalStorageIt() noexcept = default;
constexpr PodLocalStorageIt(PodLocalStorageIt&&) noexcept = default;
constexpr PodLocalStorageIt(const PodLocalStorageIt&) noexcept = default;
~PodLocalStorageIt() = default;

constexpr PodLocalStorageIt& operator=(const PodLocalStorageIt&) noexcept = default;
constexpr PodLocalStorageIt& operator=(PodLocalStorageIt&&) noexcept = default;

reference operator*() const noexcept {
return m_curr.get(m_loc);
}

reference operator*() noexcept {
return m_curr.get(m_loc);
}

pointer operator->() {
return &m_curr.get(m_loc);
}

PodLocalStorageIt& operator++() {
m_loc++;
return *this;
}

PodLocalStorageIt operator++(int) {
PodLocalStorageIt tmp = *this;
++(*this);
return tmp;
}

PodLocalStorageIt& operator--() {
m_loc--;
return *this;
}

PodLocalStorageIt operator--(int) {
PodLocalStorageIt tmp = *this;
--(*this);
return tmp;
}

constexpr PodLocalStorageIt operator+(std::uint64_t n) const noexcept {
return PodLocalStorageIt(m_curr, m_loc + n);
}

constexpr PodLocalStorageIt& operator+=(std::uint64_t n) noexcept {
m_loc += n;
return *this;
}

constexpr PodLocalStorageIt operator-(std::uint64_t n) const noexcept {
return PodLocalStorageIt(m_curr, m_loc - n);
}

constexpr difference_type operator-(PodLocalStorageIt b) const noexcept {
return m_loc - b.loc;
}

friend bool operator==(const PodLocalStorageIt& a, const PodLocalStorageIt& b) {
return a.m_loc == b.m_loc;
}

friend bool operator!=(const PodLocalStorageIt& a, const PodLocalStorageIt& b) {
return !(a == b);
}

friend bool operator<(const PodLocalStorageIt& a, const PodLocalStorageIt& b) {
return a.m_loc < b.m_loc;
}

friend bool operator<=(const PodLocalStorageIt& a, const PodLocalStorageIt& b) {
return a.m_loc <= b.m_loc;
}

friend bool operator>(const PodLocalStorageIt& a, const PodLocalStorageIt& b) {
return a.m_loc > b.m_loc;
}

friend bool operator>=(const PodLocalStorageIt& a, const PodLocalStorageIt& b) {
return a.m_loc >= b.m_loc;
}

friend pando::Place localityOf(PodLocalStorageIt& a) {
return a.m_curr.getPlaceFromPodIdx(a.m_loc);
}
};

template <typename T>
[[nodiscard]] pando::Expected<galois::PodLocalStorage<T>> copyToAllPods(T& cont) {
galois::PodLocalStorage<T> ret{};
PANDO_CHECK_RETURN(ret.initialize());
PANDO_CHECK_RETURN(galois::doAll(
cont, ret, +[](T cont, pando::GlobalRef<T> refcopy) {
T copy;
const std::uint64_t size = cont.size();
PANDO_CHECK(copy.initialize(size));
for (std::uint64_t i = 0; i < cont.size(); i++) {
copy.get(i) = cont.get(i);
}
refcopy = copy;
}));
return ret;
}

} // namespace galois

#endif // PANDO_LIB_GALOIS_CONTAINERS_POD_LOCAL_STORAGE_HPP_
2 changes: 1 addition & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ target_sources(pando-lib-galois
${CMAKE_CURRENT_LIST_DIR}/wmd_graph_importer.cpp
${CMAKE_CURRENT_LIST_DIR}/ingest_wmd_csv.cpp
${CMAKE_CURRENT_LIST_DIR}/ingest_rmat_el.cpp
${CMAKE_CURRENT_LIST_DIR}/host_local_storage.cpp
${CMAKE_CURRENT_LIST_DIR}/local_storage.cpp
)

pando_compiler_options(pando-lib-galois)
Expand Down
25 changes: 25 additions & 0 deletions src/host_local_storage.cpp → src/local_storage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Copyright (c) 2023. University of Texas at Austin. All rights reserved.

#include <pando-lib-galois/containers/host_local_storage.hpp>
#include <pando-lib-galois/containers/pod_local_storage.hpp>

pando::NodeSpecificStorage<galois::HostLocalStorageHeap::ModestArray>
galois::HostLocalStorageHeap::heap;
Expand All @@ -24,3 +25,27 @@ void galois::HostLocalStorageHeap::HeapInit() {
}
LocalHeapSlab = new pando::SlabMemoryResource<Granule>(heapStartByte, Size);
}

pando::PodSpecificStorage<galois::PodLocalStorageHeap::ModestArray>
galois::PodLocalStorageHeap::heap;

pando::SlabMemoryResource<galois::PodLocalStorageHeap::Granule>*
galois::PodLocalStorageHeap::LocalHeapSlab;

void galois::PodLocalStorageHeap::HeapInit() {
using galois::PodLocalStorageHeap::Granule;
using galois::PodLocalStorageHeap::heap;
using galois::PodLocalStorageHeap::LocalHeapSlab;
using galois::PodLocalStorageHeap::ModestArray;
using galois::PodLocalStorageHeap::Size;
pando::GlobalPtr<ModestArray> heapStartTyped =
heap.getPointerAt(pando::NodeIndex{0}, pando::PodIndex{0, 0});
pando::GlobalPtr<void> heapStartNoType = static_cast<pando::GlobalPtr<void>>(heapStartTyped);
pando::GlobalPtr<std::byte> heapStartByte =
static_cast<pando::GlobalPtr<std::byte>>(heapStartNoType);
std::uint64_t diff = heapStartNoType.address % Granule;
if (diff != 0) {
heapStartByte += Granule - diff;
}
LocalHeapSlab = new pando::SlabMemoryResource<Granule>(heapStartByte, Size);
}
1 change: 1 addition & 0 deletions test/containers/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ pando_add_driver_test(test_per_thread test_per_thread.cpp)
pando_add_driver_test(test_stack test_stack.cpp)
pando_add_driver_test(test_host_indexed_map test_host_indexed_map.cpp)
pando_add_driver_test(test_host_local_storage test_host_local_storage.cpp)
pando_add_driver_test(test_pod_local_storage test_pod_local_storage.cpp)
Loading

0 comments on commit 7be7882

Please sign in to comment.