17 inline void munmap(
void* addr, std::size_t
size);
22 std::size_t alignment =
alignof(max_align_t));
46 void*
addr()
const {
return addr_; }
47 std::size_t
size()
const {
return size_; }
56 if (curr_page_end > next_page_end) {
57 munmap(
reinterpret_cast<std::byte*
>(addr_) + next_page_end,
58 curr_page_end - next_page_end);
71 void* addr_ =
nullptr;
75 ITYR_TEST_CASE(
"[ityr::common::virtual_mem] allocate virtual memory") {
79 virtual_mem vm(32 * pagesize);
84 virtual_mem vm_longlived;
87 virtual_mem vm(addr, 16 * pagesize);
97 virtual_mem vm4(addr, pagesize);
103 "The address passed to munmap() must be page-aligned");
106 die(
"[ityr::common::virtual_mem] munmap(%p, %lu) failed", addr,
size);
113 std::size_t alignment) {
114 int flags = MAP_PRIVATE | MAP_ANONYMOUS;
116 std::size_t alloc_size;
117 if (addr ==
nullptr) {
118 alloc_size =
size + alignment;
120 ITYR_CHECK(
reinterpret_cast<uintptr_t
>(addr) % alignment == 0);
123 flags |= MAP_FIXED_NOREPLACE;
129 void* allocated_p = mmap(addr, alloc_size, PROT_NONE, flags, -1, 0);
130 if (allocated_p == MAP_FAILED) {
131 if (errno == EEXIST) {
136 die(
"[ityr::common::virtual_mem] mmap(%p, %lu, ...) failed", addr, alloc_size);
140 if (addr ==
nullptr) {
143 uintptr_t allocated_addr =
reinterpret_cast<uintptr_t
>(allocated_p);
146 uintptr_t ret_addr =
round_up_pow2(allocated_addr, alignment);
151 if (ret_addr - allocated_addr > 0) {
152 munmap(allocated_p, ret_addr - allocated_addr);
156 uintptr_t allocated_addr_end = allocated_addr + alloc_size;
158 ITYR_CHECK(allocated_addr_end >= ret_page_end);
159 if (allocated_addr_end - ret_page_end > 0) {
160 munmap(
reinterpret_cast<std::byte*
>(ret_page_end), allocated_addr_end - ret_page_end);
163 return reinterpret_cast<std::byte*
>(ret_addr);
171 std::size_t alignment =
alignof(max_align_t)) {
174 uintptr_t vm_addr = 0;
177 std::vector<virtual_mem> prev_vms;
182 std::size_t alloc_size_max =
std::max(alloc_size, std::size_t(1) << 40);
186 for (
int n_trial = 0; n_trial <= max_trial; n_trial++) {
189 vm_addr =
reinterpret_cast<uintptr_t
>(vm.
addr());
197 for (
auto&& prev_vm : prev_vms) {
198 if (
reinterpret_cast<uint64_t
>(prev_vm.addr()) < vm_addr + alloc_size &&
199 vm_addr <
reinterpret_cast<uint64_t
>(prev_vm.addr()) + prev_vm.size()) {
206 vm =
virtual_mem(
reinterpret_cast<void*
>(vm_addr), alloc_size, alignment);
215 if (failed_rank_max == -1) {
221 if (failed_rank == -1) {
227 leader_rank = failed_rank_max;
228 alloc_size =
std::min(alloc_size_max, 2 * alloc_size);;
231 die(
"Reservation of virtual memory address failed (size=%ld, max_trial=%d)",
size, max_trial);
234 ITYR_TEST_CASE(
"[ityr::common::virtual_mem] allocate the same virtual memory across processes") {
235 runtime_options opts;
236 singleton_initializer<topology::instance> topo;
242 uintptr_t vm_addr =
reinterpret_cast<uintptr_t
>(vm.addr());
243 std::size_t vm_size = vm.size();
Definition: virtual_mem.hpp:15
Definition: virtual_mem.hpp:24
virtual_mem(std::size_t size, std::size_t alignment=alignof(max_align_t))
Definition: virtual_mem.hpp:27
virtual_mem & operator=(const virtual_mem &)=delete
~virtual_mem()
Definition: virtual_mem.hpp:32
void * addr() const
Definition: virtual_mem.hpp:46
virtual_mem(virtual_mem &&vm)
Definition: virtual_mem.hpp:37
virtual_mem(void *addr, std::size_t size, std::size_t alignment=alignof(max_align_t))
Definition: virtual_mem.hpp:29
std::size_t size() const
Definition: virtual_mem.hpp:47
virtual_mem(const virtual_mem &)=delete
void shrink(std::size_t to_size)
Definition: virtual_mem.hpp:49
virtual_mem()
Definition: virtual_mem.hpp:26
virtual_mem & operator=(virtual_mem &&vm)
Definition: virtual_mem.hpp:38
#define ITYR_CHECK_THROWS_AS(exp, exception)
Definition: util.hpp:51
#define ITYR_CHECK_MESSAGE(cond,...)
Definition: util.hpp:49
#define ITYR_CHECK(cond)
Definition: util.hpp:48
int rank_t
Definition: topology.hpp:12
MPI_Comm mpicomm()
Definition: topology.hpp:206
rank_t my_rank()
Definition: topology.hpp:207
Definition: allocator.hpp:16
T round_up_pow2(T x, T alignment)
Definition: util.hpp:142
T mpi_bcast_value(const T &value, int root_rank, MPI_Comm comm)
Definition: mpi_util.hpp:145
T mpi_allreduce_value(const T &value, MPI_Comm comm, MPI_Op op=MPI_SUM)
Definition: mpi_util.hpp:194
void * mmap_no_physical_mem(void *addr, std::size_t size, bool replace=false, std::size_t alignment=alignof(max_align_t))
Definition: virtual_mem.hpp:110
std::size_t get_page_size()
Definition: util.hpp:170
void munmap(void *addr, std::size_t size)
Definition: virtual_mem.hpp:100
virtual_mem reserve_same_vm_coll(std::size_t size, std::size_t alignment=alignof(max_align_t))
Definition: virtual_mem.hpp:170
constexpr auto size(const span< T > &s) noexcept
Definition: span.hpp:61
monoid< T, min_functor<>, highest< T > > min
Definition: reducer.hpp:101
monoid< T, max_functor<>, lowest< T > > max
Definition: reducer.hpp:104
ForwardIteratorD move(const ExecutionPolicy &policy, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIteratorD first_d)
Move a range to another.
Definition: parallel_loop.hpp:934