Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added pod local storage #1

Merged
merged 1 commit into from
Mar 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading