diff --git a/benchmark/AlgorithmicComplexity.cpp b/benchmark/AlgorithmicComplexity.cpp index 9717cb0cd..15089a24e 100644 --- a/benchmark/AlgorithmicComplexity.cpp +++ b/benchmark/AlgorithmicComplexity.cpp @@ -19,7 +19,7 @@ static void BM_NumericGausP(benchmark::State& state) { double p[] = {1, 2, 3, 4, 5}; double dx[5] = {0, 0, 0, 0, 0}; double dp[5] = {0, 0, 0, 0, 0}; - clad::tape> results = {}; + clad::old_tape> results = {}; int dim = 5; results.emplace_back(dx, dim); results.emplace_back(dp, dim); diff --git a/demos/CustomTypeNumDiff.cpp b/demos/CustomTypeNumDiff.cpp index 0f92c22f9..33bc6adb1 100644 --- a/demos/CustomTypeNumDiff.cpp +++ b/demos/CustomTypeNumDiff.cpp @@ -134,7 +134,7 @@ int main() { // This is how we return the derivative with respect to all arguments. // The order of being placed in this tape should be the same as the order of // the arguments being passed to the function. - clad::tape> grad = {}; // Place the l-value reference of the variables in the tape. diff --git a/include/clad/Differentiator/Differentiator.h b/include/clad/Differentiator/Differentiator.h index 4a089c095..d35114fe1 100644 --- a/include/clad/Differentiator/Differentiator.h +++ b/include/clad/Differentiator/Differentiator.h @@ -14,6 +14,7 @@ #include "DynamicGraph.h" #include "FunctionTraits.h" #include "Matrix.h" +#include "NewTape.h" #include "NumericalDiff.h" #include "Tape.h" @@ -43,15 +44,16 @@ inline CUDA_HOST_DEVICE unsigned int GetLength(const char* code) { } /// Tape type used for storing values in reverse-mode AD inside loops. - template - using tape = tape_impl; +template using tape = new_tape_impl; - /// Add value to the end of the tape, return the same value. - template - CUDA_HOST_DEVICE T push(tape& to, ArgsT... val) { - to.emplace_back(std::forward(val)...); - return to.back(); - } +template using old_tape = tape_impl; + +/// Add value to the end of the tape, return the same value. +template +CUDA_HOST_DEVICE T push(tape& to, ArgsT... val) { + to.emplace_back(std::forward(val)...); + return to.back(); +} /// Add value to the end of the tape, return the same value. /// A specialization for clad::array_ref types to use in reverse mode. diff --git a/include/clad/Differentiator/NewTape.h b/include/clad/Differentiator/NewTape.h new file mode 100644 index 000000000..56a311243 --- /dev/null +++ b/include/clad/Differentiator/NewTape.h @@ -0,0 +1,87 @@ +#ifndef CLAD_NEWTAPE_H +#define CLAD_NEWTAPE_H + +#include +#include +#include +#include +#include + +namespace clad { + +template class Block { +public: + T* _data; + Block* next; + Block* prev; + + Block(std::size_t& _capacity) + : next(nullptr), prev(nullptr), + _data(static_cast( + ::operator new(_capacity * sizeof(T), std::nothrow))) {} + + ~Block() = default; + Block(const Block& other) = delete; + Block& operator=(const Block& other) = delete; + + Block(Block&& other) = delete; + Block& operator=(const Block&& other) = delete; +}; + +template class new_tape_impl { + Block* m_cur_block = nullptr; + std::size_t _capacity = 32; + std::size_t m_size = 0; + using pointer = T*; + using reference = T&; + + using iterator = pointer; + +public: + template + + void emplace_back(ArgsT&&... args) { + if (!m_cur_block || m_size >= _capacity) { + Block* prev_block = m_cur_block; + m_cur_block = new Block(_capacity); + if (prev_block) { + prev_block->next = m_cur_block; + m_cur_block->prev = prev_block; + } + m_size = 0; + } + m_size += 1; + ::new (const_cast(static_cast(block_end()))) + T(std::forward(args)...); + } + + [[nodiscard]] std::size_t size() const { return m_size; } + + iterator block_begin() { + return reinterpret_cast(m_cur_block->_data); + } + + iterator block_end() { + return reinterpret_cast(m_cur_block->_data + m_size - 1); + } + + reference back() { + assert(m_size || m_cur_block->prev); + return block_begin()[m_size - 1]; + } + + void pop_back() { + assert(m_size || m_cur_block->prev); + block_end()->~T(); + m_size -= 1; + if (m_size == 0) { + Block* temp = m_cur_block; + m_cur_block = m_cur_block->prev; + temp->~Block(); + m_size = _capacity; + } + } +}; +} // namespace clad + +#endif // CLAD_NEWTAPE_H diff --git a/test/NumericalDiff/PureCentralDiffCalls.C b/test/NumericalDiff/PureCentralDiffCalls.C index b96b13515..fdbbb582b 100644 --- a/test/NumericalDiff/PureCentralDiffCalls.C +++ b/test/NumericalDiff/PureCentralDiffCalls.C @@ -75,7 +75,7 @@ int main() { // expected-no-diagnostics printf("Result is = %f\n", func1_res); // CHECK-EXEC: Result is = 2.000000 // Gradients, derivative wrt all args - clad::tape> grad = {}; + clad::old_tape> grad = {}; grad.emplace_back(dx, 3); grad.emplace_back(&dy); grad.emplace_back(&dz);