Skip to content
Snippets Groups Projects
Commit 5e4868a1 authored by git_unspecified's avatar git_unspecified
Browse files

Add working dc array

parent 550cebaa
No related branches found
No related tags found
No related merge requests found
---
Language: Cpp
# BasedOnStyle: Google
AccessModifierOffset: -1
AlignAfterOpenBracket: Align
AlignArrayOfStructures: None
AlignConsecutiveMacros: None
AlignConsecutiveAssignments: None
AlignConsecutiveBitFields: None
AlignConsecutiveDeclarations: None
AlignEscapedNewlines: Left
AlignOperands: Align
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortEnumsOnASingleLine: true
AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortLambdasOnASingleLine: All
AllowShortIfStatementsOnASingleLine: WithoutElse
AllowShortLoopsOnASingleLine: true
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: Yes
AttributeMacros:
- __capability
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: Never
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
BeforeLambdaBody: false
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeConceptDeclarations: true
BreakBeforeBraces: Attach
BreakBeforeInheritanceComma: false
BreakInheritanceList: BeforeColon
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:'
QualifierAlignment: Leave
CompactNamespaces: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DeriveLineEnding: true
DerivePointerAlignment: true
DisableFormat: false
EmptyLineAfterAccessModifier: Never
EmptyLineBeforeAccessModifier: LogicalBlock
ExperimentalAutoDetectBinPacking: false
PackConstructorInitializers: NextLine
BasedOnStyle: ''
ConstructorInitializerAllOnOneLineOrOnePerLine: false
AllowAllConstructorInitializersOnNextLine: true
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IfMacros:
- KJ_IF_MAYBE
IncludeBlocks: Regroup
IncludeCategories:
- Regex: '^<ext/.*\.h>'
Priority: 2
SortPriority: 0
CaseSensitive: false
- Regex: '^<.*\.h>'
Priority: 1
SortPriority: 0
CaseSensitive: false
- Regex: '^<.*'
Priority: 2
SortPriority: 0
CaseSensitive: false
- Regex: '.*'
Priority: 3
SortPriority: 0
CaseSensitive: false
IncludeIsMainRegex: '([-_](test|unittest))?$'
IncludeIsMainSourceRegex: ''
IndentAccessModifiers: false
IndentCaseLabels: true
IndentCaseBlocks: false
IndentGotoLabels: true
IndentPPDirectives: None
IndentExternBlock: AfterExternBlock
IndentRequires: false
IndentWidth: 2
IndentWrappedFunctionNames: false
InsertTrailingCommas: None
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: false
LambdaBodyIndentation: Signature
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Never
ObjCBlockIndentWidth: 2
ObjCBreakBeforeNestedBlockParam: true
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 1
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakOpenParenthesis: 0
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 200
PenaltyIndentedWhitespace: 0
PointerAlignment: Left
PPIndentWidth: -1
RawStringFormats:
- Language: Cpp
Delimiters:
- cc
- CC
- cpp
- Cpp
- CPP
- 'c++'
- 'C++'
CanonicalDelimiter: ''
BasedOnStyle: google
- Language: TextProto
Delimiters:
- pb
- PB
- proto
- PROTO
EnclosingFunctions:
- EqualsProto
- EquivToProto
- PARSE_PARTIAL_TEXT_PROTO
- PARSE_TEST_PROTO
- PARSE_TEXT_PROTO
- ParseTextOrDie
- ParseTextProtoOrDie
- ParseTestProto
- ParsePartialTestProto
CanonicalDelimiter: pb
BasedOnStyle: google
ReferenceAlignment: Pointer
ReflowComments: true
RemoveBracesLLVM: false
SeparateDefinitionBlocks: Leave
ShortNamespaceLines: 1
SortIncludes: CaseSensitive
SortJavaStaticImport: Before
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeCaseColon: false
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeParensOptions:
AfterControlStatements: true
AfterForeachMacros: true
AfterFunctionDefinitionName: false
AfterFunctionDeclarationName: false
AfterIfMacros: true
AfterOverloadedOperator: false
BeforeNonEmptyParentheses: false
SpaceAroundPointerQualifiers: Default
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 2
SpacesInAngles: Never
SpacesInConditionalStatement: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInLineCommentPrefix:
Minimum: 1
Maximum: -1
SpacesInParentheses: false
SpacesInSquareBrackets: false
SpaceBeforeSquareBrackets: false
BitFieldColonSpacing: Both
Standard: Auto
StatementAttributeLikeMacros:
- Q_EMIT
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TabWidth: 8
UseCRLF: false
UseTab: Never
WhitespaceSensitiveMacros:
- STRINGIZE
- PP_STRINGIZE
- BOOST_PP_STRINGIZE
- NS_SWIFT_NAME
- CF_SWIFT_NAME
...
......@@ -11,196 +11,34 @@
#include <unordered_map>
#include <vector>
#include "./pinnedVector/pinnedVector/PinnedVector.h"
#define USE_HPVM
#ifdef USE_HPVM
#include "heterocc.h"
#endif
// [cpp obj {ptr 1, ptr2}, ptr1{ptr3}.. ] -> Buffer[ cpp obj{ptr->relative
// address}, *ptr1, *ptr2 ] Library:
// memory_map: tracking allocation type/size/meta_info
// Helper functions: do buffer management
// Codegen:
// Enumerate member, call library
// User code:
// Tell library/Codegen we want to serialize object
using byte = char;
// In a separate file ----------------------
static std::unordered_map<void*, std::pair<const std::type_info*, size_t>>
hpvm_allocation_record;
// Lib header provides ---------------------
extern std::unordered_map<void*, std::pair<const std::type_info*, size_t>>
hpvm_allocation_record;
bool is_allocated_memory(void* ptr) {
return hpvm_allocation_record.count(ptr);
}
size_t allocation_size(void* ptr) {
if (is_allocated_memory(ptr)) return hpvm_allocation_record[ptr].second;
return 0;
}
template <class T, class... Args>
T* hpvm_new(Args... args) {
T* obj = new T(args...);
hpvm_allocation_record[obj] = {&typeid(T), sizeof(T)};
return obj;
}
template <class T, class... Args>
void hpvm_delete(T* obj) {
hpvm_allocation_record.erase(obj);
delete obj;
}
// Hpvm Buf layout:
// [header, pointer_recover_list(size_t[]), obj_buf]
template <typename T>
class HpvmBufHeader {
public:
size_t pointer_recover_list_size;
size_t obj_size;
byte buf[];
void* get_obj_start() {
return buf + pointer_recover_list_size * sizeof(size_t);
}
size_t* get_pointer_list_start() { return (size_t*)buf; }
size_t* get_pointer_at(size_t offset) {
size_t* sub_ptr = (size_t*)((char*)get_obj_start() + offset);
return sub_ptr;
}
void to_relative_pointer(void* base) {
for (int i = 0; i < pointer_recover_list_size; i++) {
size_t pointer_offset = get_pointer_list_start()[i];
size_t* sub_ptr = get_pointer_at(pointer_offset);
#ifndef USE_HPVM
std::cout << "To relative: " << (void*)sub_ptr[0];
#endif
sub_ptr[0] -= (size_t)base;
#ifndef USE_HPVM
std::cout << " -> " << (void*)sub_ptr[0] << "\n";
#endif
}
}
void to_absolute_pointer(void* base, bool device = false) {
to_relative_pointer((void*)(-(size_t)base));
}
size_t total_size() {
return sizeof(*this) + pointer_recover_list_size * sizeof(size_t) +
obj_size;
}
};
template <typename T>
class HpvmBuf {
public:
HpvmBufHeader<T>* buf = nullptr;
std::vector<size_t> rel_pointer_list;
PinnedVector<byte> obj_data;
HpvmBuf() {
rel_pointer_list.reserve(1);
obj_data.reserve(1);
}
HpvmBufHeader<T>* formulate_device_buffer() {
if (buf) free(buf);
size_t buf_size = sizeof(*buf) + rel_pointer_list.size() * sizeof(size_t) +
obj_data.size();
buf = (HpvmBufHeader<T>*)calloc(buf_size, 1);
buf->pointer_recover_list_size = rel_pointer_list.size();
buf->obj_size = obj_data.size();
std::cout << "Formulating buffer \n";
memcpy(buf->get_pointer_list_start(), rel_pointer_list.data(),
buf->pointer_recover_list_size * sizeof(size_t));
memcpy(buf->get_obj_start(), obj_data.data(), buf->obj_size);
std::cout << "We will have pointers at offsets: ";
for (auto i : rel_pointer_list) std::cout << (void*)i << ",";
std::cout << "\n";
buf->to_relative_pointer(obj_data.data());
return buf;
}
T* recover_host_accessible_obj() {
buf->to_absolute_pointer(buf->get_obj_start());
return (T*)buf->get_obj_start();
}
template <class AllocType = void>
AllocType* allocate(size_t size) {
if (size == 0) return nullptr;
size_t old_size = obj_data.size();
obj_data.resize(obj_data.size() + size);
std::cout << "Allocate up to:" << obj_data.size() << " bytes" << std::endl;
return (AllocType*)(obj_data.data() + old_size);
}
void register_pointer_in_buf(void* ptr_addr_in_buf) {
rel_pointer_list.push_back((size_t)(ptr_addr_in_buf) -
(size_t)obj_data.data());
}
};
// Main user entry to snapshot an object into a buffer
template <class T>
HpvmBuf<T> hpvm_snapshot(T* original_obj) {
std::cout << "Snapshot: " << (void*)original_obj << std::endl;
HpvmBuf<T> buf;
hpvm_snapshot_internal(buf, original_obj);
std::cout << "Snapshot Done\n";
buf.formulate_device_buffer();
return buf;
}
// Allocated space at end of buffer and do trivial copy
template <class T, class Buf>
T* snapshot_trivial(Buf& buf, T* src) {
auto* dst = buf.template allocate<T>(sizeof(T));
memcpy(dst, src, sizeof(T));
return dst;
}
// User can implement this specialization for deep copy
template <class Buf, class T>
extern void hpvm_snapshot_custom(Buf& buf, T* dst_obj,
T* original_obj) {}
// Snapshot function used internally
template <class Buf, class T>
extern T* hpvm_snapshot_internal(Buf& buf, T* original_obj) {
auto* dst = snapshot_trivial(buf, original_obj);
hpvm_snapshot_custom(buf, dst, original_obj);
return dst;
}
// Snapshot an (array of) pointer(s)
template <class T, class Buf>
void* snapshot_pointer(Buf& buf, T* src_ptr) {
if (is_allocated_memory(src_ptr)) {
auto* dst = hpvm_snapshot_internal(buf, src_ptr);
buf.register_pointer_in_buf(&dst_ptr);
return dst;
} else
return nullptr;
}
// Library function
// ends----------------------------------------------------------
#include "hpvm_dclib.hpp"
// User code
// A linked list:
class LNode {
public:
int val;
int* other_vals = nullptr; // arbitrary long array
LNode* next = nullptr;
inline LNode(int v) { val = v; }
inline LNode(int v) {
val = v;
other_vals = hpvm_new_arr<int>(5);
for (int i = 0; i < 5; i++) other_vals[i] = i + 1;
}
void delta(int x) {
val += x;
for (int i = 0; i < 5; i++) other_vals[i] += x;
}
void print() {
std::cout << "[Node " << val << "] -> ";
std::cout << "[Node " << val << ": ";
for (int i = 0; i < 5; i++) std::cout << other_vals[i] << ",";
std::cout << "] -> ";
if (next)
next->print();
else
......@@ -227,14 +65,12 @@ void stencil(HpvmBufHeader<LNode>* buf_header, size_t header_size) {
(void*)buf_header, header_size);
__hpvm__hint(hpvm::GPU_TARGET);
auto* root = (LNode*)(buf_header->get_obj_start());
buf_header->to_absolute_pointer(buf_header->get_obj_start(), true);
buf_header->to_absolute_pointer(buf_header->get_obj_start());
auto* root = (LNode*)(buf_header->get_obj_start());
root->next->val = 100;
while (root) {
root->val += 1;
root->delta(1);
// root->val = (size_t)root->next;
root = root->next;
}
......@@ -251,26 +87,28 @@ int main(int argc, char* argv[]) {
host_obj->print();
auto host_buf = hpvm_snapshot(host_obj);
size_t buf_size = host_buf.buf->total_size();
#ifdef USE_HPVM
std::cout << "Kernel launch!" << std::endl;
void* DFG = __hetero_launch((void*)stencil, 1, host_buf.buf, buf_size, 1,
host_buf.buf, buf_size);
void* DFG = __hetero_launch((void*)stencil, 1, host_buf.buf,
host_buf.buf->total_size(), 1, host_buf.buf,
host_buf.buf->total_size());
__hetero_wait(DFG);
#else
/*
auto* buf_header = host_buf.buf;
host_buf.buf->to_absolute_pointer(buf_header->get_obj_start());
buf_header->to_absolute_pointer(buf_header->get_obj_start());
LNode* root = (LNode*)buf_header->get_obj_start();
while (root) {
root->val += 1;
root->delta(1);
// root->val = (size_t)root->next;
root = root->next;
}
host_buf.buf->to_relative_pointer(host_buf.buf->get_obj_start());
buf_header->to_relative_pointer(buf_header->get_obj_start());
*/
#endif
std::cout << "After kernel in buffer:\n";
......@@ -279,12 +117,13 @@ int main(int argc, char* argv[]) {
return 0;
}
// User code end---------------------
// HPVM Codegen generates:
// User / HPVM Codegen provides:
template <>
void hpvm_snapshot_custom<HpvmBuf<LNode>, LNode>(HpvmBuf<LNode>& buf,
LNode* dst_obj,
LNode* original_obj) {
// recursive allocation & copies
dst_obj->next = snapshot_pointer(buf, original_obj->next);
snapshot_pointer(buf, dst_obj->next, original_obj->next);
snapshot_pointer(buf, dst_obj->other_vals, original_obj->other_vals);
}
// HPVM Codegen end ------------
// User / HPVM Codegen end ------------
#include <argp.h>
#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <functional>
#include <iostream>
#include <typeinfo>
#include <unordered_map>
#include <vector>
#include "./pinnedVector/pinnedVector/PinnedVector.h"
// [cpp obj {ptr 1, ptr2}, ptr1{ptr3}.. ] -> Buffer[ cpp obj{ptr->relative
// address}, *ptr1, *ptr2 ] Library:
// memory_map: tracking allocation type/size/meta_info
// Helper functions: do buffer management
// Codegen:
// Enumerate member, call library
// User code:
// Tell library/Codegen we want to serialize object
using byte = char;
// In a separate file ----------------------
static std::unordered_map<void*, std::pair<const std::type_info*, size_t>>
hpvm_allocation_record;
// Lib header provides ---------------------
extern std::unordered_map<void*, std::pair<const std::type_info*, size_t>>
hpvm_allocation_record;
bool is_allocated_memory(void* ptr) {
return hpvm_allocation_record.count(ptr);
}
size_t allocation_size(void* ptr) {
if (is_allocated_memory(ptr)) return hpvm_allocation_record[ptr].second;
return 0;
}
template <class T, class... Args>
T* hpvm_new(Args... args) {
T* obj = new T(args...);
hpvm_allocation_record[obj] = {&typeid(T), sizeof(T)};
return obj;
}
template <class T>
T* hpvm_new_arr(size_t num_obj) {
T* obj = new T[num_obj];
hpvm_allocation_record[obj] = {&typeid(T), num_obj * sizeof(T)};
return obj;
}
template <class T, class... Args>
void hpvm_delete(T* obj) {
hpvm_allocation_record.erase(obj);
delete obj;
}
template <class T, class... Args>
void hpvm_delete_arr(T* obj) {
hpvm_allocation_record.erase(obj);
delete[] obj;
}
// Hpvm Buf layout:
// [header, pointer_recover_list(size_t[]), obj_buf]
template <typename T>
class HpvmBufHeader {
public:
size_t pointer_recover_list_size;
size_t obj_size;
byte buf[];
void* get_obj_start() {
return buf + pointer_recover_list_size * sizeof(size_t);
}
size_t* get_pointer_list_start() { return (size_t*)buf; }
size_t* get_pointer_at(size_t offset) {
size_t* sub_ptr = (size_t*)((char*)get_obj_start() + offset);
return sub_ptr;
}
void to_relative_pointer(void* base) {
for (int i = 0; i < pointer_recover_list_size; i++) {
size_t pointer_offset = get_pointer_list_start()[i];
size_t* sub_ptr = get_pointer_at(pointer_offset);
#ifndef USE_HPVM
std::cout << "To relative: " << (void*)sub_ptr[0];
#endif
sub_ptr[0] -= (size_t)base;
#ifndef USE_HPVM
std::cout << " -> " << (void*)sub_ptr[0] << "\n";
#endif
}
}
void to_absolute_pointer(void* base) {
to_relative_pointer((void*)(-(long long)base));
}
size_t total_size() {
return sizeof(*this) + pointer_recover_list_size * sizeof(size_t) +
obj_size;
}
};
template <typename T>
class HpvmBuf {
public:
HpvmBufHeader<T>* buf = nullptr;
std::vector<size_t> rel_pointer_list;
PinnedVector<byte> obj_data;
HpvmBuf() {
rel_pointer_list.reserve(1);
obj_data.reserve(1);
}
HpvmBufHeader<T>* formulate_device_buffer() {
if (buf) free(buf);
size_t buf_size = sizeof(*buf) + rel_pointer_list.size() * sizeof(size_t) +
obj_data.size();
buf = (HpvmBufHeader<T>*)calloc(buf_size, 1);
buf->pointer_recover_list_size = rel_pointer_list.size();
buf->obj_size = obj_data.size();
std::cout << "Formulating buffer \n";
memcpy(buf->get_pointer_list_start(), rel_pointer_list.data(),
buf->pointer_recover_list_size * sizeof(size_t));
memcpy(buf->get_obj_start(), obj_data.data(), buf->obj_size);
std::cout << "We will have pointers at offsets: ";
for (auto i : rel_pointer_list) std::cout << (void*)i << ",";
std::cout << "\n";
buf->to_relative_pointer(obj_data.data());
return buf;
}
T* recover_host_accessible_obj() {
buf->to_absolute_pointer(buf->get_obj_start());
return (T*)buf->get_obj_start();
}
template <class AllocType = void>
AllocType* allocate(size_t size) {
if (size == 0) return nullptr;
size_t old_size = obj_data.size();
obj_data.resize(obj_data.size() + size);
std::cout << "Allocate up to:" << obj_data.size() << " bytes" << std::endl;
return (AllocType*)(obj_data.data() + old_size);
}
void register_pointer_in_buf(void* ptr_addr_in_buf) {
rel_pointer_list.push_back((size_t)(ptr_addr_in_buf) -
(size_t)obj_data.data());
}
};
// Main user entry to snapshot an object into a buffer
template <class T>
HpvmBuf<T> hpvm_snapshot(T* original_obj) {
std::cout << "Snapshot: " << (void*)original_obj << std::endl;
HpvmBuf<T> buf;
hpvm_snapshot_internal(buf, original_obj);
std::cout << "Snapshot Done\n";
buf.formulate_device_buffer();
return buf;
}
// Allocated space at end of buffer and do trivial copy
template <class T, class Buf>
T* snapshot_trivial(Buf& buf, T* src) {
auto* dst = buf.template allocate<T>(sizeof(T));
memcpy(dst, src, sizeof(T));
return dst;
}
// User can implement this specialization for deep copy
template <class Buf, class T>
extern void hpvm_snapshot_custom(Buf& buf, T* dst_obj, T* original_obj) {}
// Snapshot function used internally
template <class Buf, class T>
extern T* hpvm_snapshot_internal(Buf& buf, T* original_obj) {
auto* dst = snapshot_trivial(buf, original_obj);
hpvm_snapshot_custom(buf, dst, original_obj);
return dst;
}
// Snapshot an (array of) pointer(s)
template <class T, class Buf>
void snapshot_pointer(Buf& buf, T*& dst_ptr, T* src_ptr) {
if (int num_allocation = allocation_size(src_ptr) / sizeof(T)) {
std::cout << "Snapshot pointer to buffer of " << num_allocation
<< " elems\n";
// Ensure array allocation is continuous
T* dst = nullptr;
for (int i = 0; i < num_allocation; i++) {
auto* alloc = snapshot_trivial(buf, src_ptr + i);
if (!dst) dst = alloc;
}
// Only do deep copy after continuous buffer have been allocated
for (int i = 0; i < num_allocation; i++)
hpvm_snapshot_custom(buf, dst + i, src_ptr + i);
dst_ptr = dst;
buf.register_pointer_in_buf(&dst_ptr);
} else
dst_ptr = nullptr;
}
// Library function
// ends----------------------------------------------------------
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment