Initial import: grid-bot — grid trading bot for BTC-USDT on Cifra Markets
This commit is contained in:
+111
@@ -0,0 +1,111 @@
|
||||
#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION)
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <mutex>
|
||||
|
||||
#include <c10/macros/Export.h>
|
||||
#include <c10/util/SmallVector.h>
|
||||
#include <c10/util/flat_hash_map.h>
|
||||
|
||||
/*
|
||||
* CPUCachingAllocator:
|
||||
* DISCLAIMER:
|
||||
* This is subject to change (beta) and only supported on mobile builds.
|
||||
* If code snippet such as in 'Usage pattern' is used outside of mobile
|
||||
* build you will not observe the intended behavior.
|
||||
* See below for more information.
|
||||
* Why?
|
||||
* It has been observed that some mobile platforms, such as pixel 3, return
|
||||
* memory aggressively to the system. This results in page faults in some
|
||||
* cases and ends up hurting performance. This caching allocator aims to address
|
||||
* that. Furthermore it also allows users to specify their own allocator by
|
||||
* implementing allocate/free virtual interfaces. What are the cons? There are
|
||||
* some cons that were observed where use of caching allocator led to worse
|
||||
* performance on some platforms. Reason being that the caching mechanism used
|
||||
* by this allocator left us worse off compared to the corresponding platform's
|
||||
* tuned memory allocator. In that case it seemed better to not use this
|
||||
* allocator. Note there are some ideas to fix this in the works.
|
||||
*
|
||||
* Usage:
|
||||
* Usage pattern:
|
||||
* Instantiate and own the caching allocator.
|
||||
* std::unique_ptr<c10::CPUCachingAllocator> caching_allocator =
|
||||
* std::make_unique<c10::CPUCachingAllocator>();
|
||||
* Use caching allocator with a scoped guard at inference time.
|
||||
* {
|
||||
* WithCPUCachingAllocatorGuard(caching_allocator.get());
|
||||
* ... model.forward(...);
|
||||
* }
|
||||
*/
|
||||
|
||||
namespace c10 {
|
||||
|
||||
class C10_API CPUCachingAllocator {
|
||||
/*
|
||||
* What it does:
|
||||
* Caches all the allocations carried out by this allocator.
|
||||
* Cache key is the size of the allocation.
|
||||
* If requested size is found in the cache returns the cached pointer.
|
||||
* What it does not do:
|
||||
* No speculative allocation for any future allocations.
|
||||
*/
|
||||
private:
|
||||
inline void* allocate_and_cache(const size_t bytes);
|
||||
void free_cached();
|
||||
|
||||
protected:
|
||||
// Invariants.
|
||||
// 1. If memory is ever allocated via this allocator then
|
||||
// the pointer will exist in allocation_map_, unless the allocator
|
||||
// returned the memory to OS via free_cached.
|
||||
// 1.1. Therefore even when the said memory is "freed" via this
|
||||
// allocator (and thus cached), it will continue to stay
|
||||
// in allocation_map_. Furthermore it will also exist in
|
||||
// available_map_. Thus an allocated memory pointer can be in both
|
||||
// allocation_map_ and available_map_ simultaneously.
|
||||
// 2. Memory pointer maybe removed from allocation_map_, when it
|
||||
// is freed outside of the scope of this allocator, but was allocated
|
||||
// by this allocator.
|
||||
// 3. Available map only contains that memory which was allocated
|
||||
// by this allocator and subsequently freed by this allocator.
|
||||
// As a result of above invariants, allocated memory ptr cannot be in
|
||||
// available_map_ unless it is in allocation_map_ as well.
|
||||
ska::flat_hash_map<size_t, c10::SmallVector<void*, 16>> available_map_;
|
||||
static ska::flat_hash_map<void*, size_t> allocation_map_;
|
||||
// Since allocation_map, which is a global instance, is mutated/read via
|
||||
// all public APIs we need a global mutex.
|
||||
static std::mutex mutex_;
|
||||
|
||||
public:
|
||||
static void record_free(void* ptr);
|
||||
virtual ~CPUCachingAllocator();
|
||||
// Checks the cache to see if allocation of size bytes can be found.
|
||||
// If so return cached memory, else
|
||||
// allocates memory, records it for caching and returns.
|
||||
virtual void* allocate(const size_t bytes);
|
||||
// Checks if the memory being freed is was marked for allocation by
|
||||
// an earlier call to allocate. If so cache the allocation.
|
||||
// Otherwise free.
|
||||
virtual void free(void* ptr);
|
||||
};
|
||||
|
||||
CPUCachingAllocator* GetDefaultCPUCachingAllocator();
|
||||
|
||||
bool ThreadLocalCachingAllocatorEnabled();
|
||||
CPUCachingAllocator* GetThreadLocalCachingAllocator();
|
||||
|
||||
class C10_API WithCPUCachingAllocatorGuard {
|
||||
public:
|
||||
WithCPUCachingAllocatorGuard(CPUCachingAllocator* allocator);
|
||||
~WithCPUCachingAllocatorGuard();
|
||||
|
||||
private:
|
||||
CPUCachingAllocator* prev_caching_allocator_ptr_{nullptr};
|
||||
};
|
||||
|
||||
} // namespace c10
|
||||
|
||||
#else
|
||||
#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined."
|
||||
#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION)
|
||||
+157
@@ -0,0 +1,157 @@
|
||||
#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION)
|
||||
#pragma once
|
||||
|
||||
#include <c10/macros/Export.h>
|
||||
#include <c10/util/flat_hash_map.h>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace c10 {
|
||||
|
||||
/*
|
||||
* Given a sequence of allocations in a thread, AllocationPlan records
|
||||
* 1. size of each allocation
|
||||
* 2. Lifetime of each allocation.
|
||||
* 3. allocation offsets: Memory offset for each allocation in a single blob of
|
||||
* memory
|
||||
* 4. Total size of a blob of memory required to satisfy all the allocations.
|
||||
*/
|
||||
class C10_API AllocationPlan {
|
||||
private:
|
||||
// Records size of each allocation by their sequential allocation ids.
|
||||
std::vector<uint64_t> allocation_sizes;
|
||||
// This maps one allocation id (X) to another allocation id (Y).
|
||||
// Allocation X is alive until allocation Y. From allocation Y onwards
|
||||
// allocation X is not referenced.
|
||||
// Thus Y is the id of the first allocation after X is freed.
|
||||
// NB: When an allocation is recorded, along with recording its size,
|
||||
// we also set the lifetime to be numeric_limits::max()
|
||||
// This is to track allocations that are made during the scope of
|
||||
// profiling but were not freed until after the scope ended.
|
||||
// Such allocations are not managed by profiling allocator.
|
||||
std::vector<uint64_t> allocation_lifetimes;
|
||||
// Maps an allocation to some offset in a blob of memory.
|
||||
std::vector<uint64_t> allocation_offsets;
|
||||
uint64_t total_size{0};
|
||||
void clear();
|
||||
friend class AllocationPlanner;
|
||||
friend class CPUProfilingAllocator;
|
||||
};
|
||||
|
||||
/*
|
||||
* Map of memory ptr to allocation id. This is auxiliary information only
|
||||
* used to establish lifetime of allocations.
|
||||
*/
|
||||
class C10_API AllocationPlanner {
|
||||
private:
|
||||
AllocationPlan* allocation_plan_{nullptr};
|
||||
// Maps allocated ptr to its allocation id.
|
||||
// This is used when freeing the memory to look up the allocation id
|
||||
// in order to establish the lifetime of a particular allocation.
|
||||
ska::flat_hash_map<const void*, uint64_t> allocation_ptr_to_id_;
|
||||
uint64_t allocation_id_{0};
|
||||
bool validation_mode_{false};
|
||||
|
||||
bool validate_allocation(const uint64_t size, const void* ptr);
|
||||
bool validate_free(const void* ptr);
|
||||
|
||||
public:
|
||||
bool validation_success{true};
|
||||
|
||||
AllocationPlanner() = delete;
|
||||
AllocationPlanner(AllocationPlan* plan, bool validate = false)
|
||||
: allocation_plan_(plan), validation_mode_(validate) {}
|
||||
void record_allocation(const uint64_t size, const void* ptr);
|
||||
void record_free(const void* ptr);
|
||||
void formulate_plan();
|
||||
void clear();
|
||||
};
|
||||
|
||||
// NOT THREAD SAFE profiling allocator.
|
||||
class C10_API CPUProfilingAllocator {
|
||||
private:
|
||||
const AllocationPlan* plan_{nullptr};
|
||||
uint64_t allocation_id_{0};
|
||||
uint64_t current_size_{0};
|
||||
void* blob_{nullptr};
|
||||
ska::flat_hash_map<const void*, uint64_t> allocation_ptr_to_id_;
|
||||
|
||||
public:
|
||||
~CPUProfilingAllocator();
|
||||
void set_plan(const AllocationPlan* plan);
|
||||
void unset_plan();
|
||||
void* allocate(const size_t bytes);
|
||||
void free(void* const ptr);
|
||||
};
|
||||
|
||||
/*
|
||||
* Usage: Profile allocations made by one run of the model.
|
||||
* AllocationPlan plan;
|
||||
* {
|
||||
* WithProfileAllocationGuard profile_guard(&plan);
|
||||
* module.forward(...);
|
||||
* }
|
||||
* plan now contains allocation plan.
|
||||
*/
|
||||
class C10_API WithProfileAllocationsGuard {
|
||||
public:
|
||||
WithProfileAllocationsGuard(AllocationPlan* plan);
|
||||
~WithProfileAllocationsGuard();
|
||||
|
||||
private:
|
||||
std::unique_ptr<AllocationPlanner> planner_;
|
||||
};
|
||||
|
||||
/*
|
||||
* Usage: Validate allocation plan made with WithProfileAllocationGuard
|
||||
* bool plan_validation_success, success = true;
|
||||
* for (some number of representative inputs)
|
||||
* {
|
||||
* WithValidateAllocationPlanGuard(&plan, &plan_validation_success);
|
||||
* module.forward(...);
|
||||
* success = success && plan_validation_success;
|
||||
* }
|
||||
* success == true means allocations are according to plan
|
||||
* else for some inputs allocation pattern changed.
|
||||
*/
|
||||
class C10_API WithValidateAllocationPlanGuard {
|
||||
public:
|
||||
WithValidateAllocationPlanGuard(AllocationPlan* plan, bool* success);
|
||||
~WithValidateAllocationPlanGuard();
|
||||
|
||||
private:
|
||||
std::unique_ptr<AllocationPlanner> planner_;
|
||||
bool* success_;
|
||||
};
|
||||
|
||||
AllocationPlanner* GetThreadLocalAllocationPlanner();
|
||||
|
||||
/*
|
||||
* Usage: Allocate tensors accordingly to allocation plan
|
||||
* First make allocation plan.
|
||||
* See WithProfileAllocationsGuard usage.
|
||||
* Second validate allocation plan.
|
||||
* See WithValidateAllocationPlanGuard usage.
|
||||
* CPUProfilingAllocator profiling_allocator;
|
||||
* {
|
||||
* WithProfilingAllocatorGuard allocator_guard(&profiling_allocator, &plan);
|
||||
* module.forward(...);
|
||||
* }
|
||||
*/
|
||||
class C10_API WithProfilingAllocatorGuard {
|
||||
public:
|
||||
WithProfilingAllocatorGuard(
|
||||
CPUProfilingAllocator* allocator,
|
||||
const AllocationPlan* plan);
|
||||
~WithProfilingAllocatorGuard();
|
||||
};
|
||||
|
||||
CPUProfilingAllocator* GetThreadLocalProfilingAllocator();
|
||||
|
||||
} // namespace c10
|
||||
|
||||
#else
|
||||
#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined."
|
||||
#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION)
|
||||
Reference in New Issue
Block a user