-
Notifications
You must be signed in to change notification settings - Fork 122
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use connected lists for tape data structure
Instead of a single list use mutliple connected lists to store elements. This allows to dynamically increase the size of tape without the need of relocating elements.
- Loading branch information
1 parent
f03fc98
commit 3fe7769
Showing
5 changed files
with
135 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
#ifndef CLAD_DIFFERENTIATOR_NEWTAPE_H | ||
#define CLAD_DIFFERENTIATOR_NEWTAPE_H | ||
|
||
#include <cassert> | ||
#include <cstdio> | ||
#include <type_traits> | ||
#include <utility> | ||
|
||
#include "clad/Differentiator/CladConfig.h" | ||
|
||
namespace clad { | ||
|
||
static const int capacity = 32; | ||
|
||
template <typename T> class Block { | ||
public: | ||
T data[capacity]; | ||
Block<T>* next; | ||
Block<T>* prev; | ||
using pointer = T*; | ||
using iterator = pointer; | ||
|
||
CUDA_HOST_DEVICE Block() : next(nullptr), prev(nullptr) {} | ||
|
||
CUDA_HOST_DEVICE ~Block() { destroy(block_begin(), block_end()); } | ||
|
||
Block(const Block& other) = delete; | ||
Block& operator=(const Block& other) = delete; | ||
|
||
Block(Block&& other) = delete; | ||
Block& operator=(const Block&& other) = delete; | ||
|
||
CUDA_HOST_DEVICE iterator block_begin() { return data; } | ||
|
||
CUDA_HOST_DEVICE iterator block_end() { return data + capacity; } | ||
|
||
template <typename It> using value_type_of = decltype(*std::declval<It>()); | ||
|
||
template <typename It> | ||
static typename std::enable_if< | ||
!std::is_trivially_destructible<value_type_of<It>>::value>::type | ||
destroy(It B, It E) { | ||
for (It I = E - 1; I >= B; --I) | ||
I->~value_type_of<It>(); | ||
} | ||
|
||
template <typename It> | ||
static typename std::enable_if< | ||
std::is_trivially_destructible<value_type_of<It>>::value>::type | ||
CUDA_HOST_DEVICE | ||
destroy(It B, It E) {} | ||
}; | ||
|
||
template <typename T> class new_tape_impl { | ||
using NonConstT = typename std::remove_cv<T>::type; | ||
|
||
Block<NonConstT>* m_cur_block = nullptr; | ||
std::size_t m_size = 0; | ||
|
||
public: | ||
new_tape_impl() = default; | ||
|
||
~new_tape_impl() { | ||
if (m_cur_block) { | ||
// destroy(); | ||
} | ||
} | ||
|
||
new_tape_impl(new_tape_impl& other) = delete; | ||
new_tape_impl operator=(new_tape_impl& other) = delete; | ||
|
||
new_tape_impl(new_tape_impl&& other) = delete; | ||
new_tape_impl& operator=(new_tape_impl&& other) = delete; | ||
|
||
template <typename... ArgsT> | ||
|
||
CUDA_HOST_DEVICE void emplace_back(ArgsT&&... args) { | ||
if (!m_cur_block || m_size >= capacity) { | ||
Block<NonConstT>* prev_block = m_cur_block; | ||
m_cur_block = new Block<NonConstT>(); | ||
if (prev_block != nullptr) { | ||
prev_block->next = m_cur_block; | ||
m_cur_block->prev = prev_block; | ||
} | ||
m_size = 0; | ||
} | ||
m_size += 1; | ||
::new (const_cast<void*>(static_cast<const volatile void*>(end()))) | ||
T(std::forward<ArgsT>(args)...); | ||
} | ||
|
||
[[nodiscard]] CUDA_HOST_DEVICE std::size_t size() const { return m_size; } | ||
|
||
CUDA_HOST_DEVICE T* end() { return m_cur_block->data + (m_size - 1); } | ||
|
||
CUDA_HOST_DEVICE T& back() { | ||
assert(m_size || m_cur_block->prev); | ||
return *end(); | ||
} | ||
|
||
CUDA_HOST_DEVICE void pop_back() { | ||
assert(m_size || m_cur_block->prev); | ||
m_size -= 1; | ||
if (m_size == 0) { | ||
Block<NonConstT>* temp = m_cur_block; | ||
m_cur_block = m_cur_block->prev; | ||
temp->~Block<NonConstT>(); | ||
m_size = capacity; | ||
} | ||
} | ||
|
||
void destroy() { | ||
while (m_cur_block != nullptr) { | ||
Block<NonConstT>* prev_block = m_cur_block->prev; | ||
delete m_cur_block; | ||
m_cur_block = prev_block; | ||
} | ||
} | ||
}; | ||
} // namespace clad | ||
|
||
#endif // CLAD_DIFFERENTIATOR_NEWTAPE_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters