payload: {"action":"created","comment":{"url":"https://api.github.com/repos/arrayfire/arrayfire/pulls/comments/310433753","pull_request_review_id":270549981,"id":310433753,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDMxMDQzMzc1Mw==","diff_hunk":"@@ -61,29 +57,37 @@ void printMemInfo(const char *msg, const int device) {\n \n template<typename T>\n uptr<T> memAlloc(const size_t &elements) {\n-    size_t size                = elements * sizeof(T);\n-    MemoryEventPair me = memoryManager().alloc(size, false);\n-    cudaStream_t stream        = getActiveStream();\n-    if (me.e) me.e.enqueueWait(stream);\n-    return uptr<T>(static_cast<T *>(me.ptr), memFree<T>);\n+    size_t size = elements * sizeof(T);\n+    memory_event_pair pair =\n+        memory_event_pair(memoryManager().alloc(elements * sizeof(T), false));\n+    event ev            = event(pair.getEvent());\n+    Event &e            = getEvent(ev.get());","path":"src/backend/cuda/memory.cpp","position":31,"original_position":31,"commit_id":"0a1c6535aedb33e1e4ac4b8fa31be44f61f9c395","original_commit_id":"d5f3447d7e968a94f8d440fb3100c2a847cf47f0","user":{"login":"jacobkahn","id":7871817,"node_id":"MDQ6VXNlcjc4NzE4MTc=","avatar_url":"https://avatars1.githubusercontent.com/u/7871817?v=4","gravatar_id":"","url":"https://api.github.com/users/jacobkahn","html_url":"https://github.com/jacobkahn","followers_url":"https://api.github.com/users/jacobkahn/followers","following_url":"https://api.github.com/users/jacobkahn/following{/other_user}","gists_url":"https://api.github.com/users/jacobkahn/gists{/gist_id}","starred_url":"https://api.github.com/users/jacobkahn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jacobkahn/subscriptions","organizations_url":"https://api.github.com/users/jacobkahn/orgs","repos_url":"https://api.github.com/users/jacobkahn/repos","events_url":"https://api.github.com/users/jacobkahn/events{/privacy}","received_events_url":"https://api.github.com/users/jacobkahn/received_events","type":"User","site_admin":false},"body":"You don't have to - you could just write `Event &e = getEvent(pair.getEvent())` here, but I'm creating an `af::event` so we get the RAII benefit/the event is automatically released when `ev` is out of scope.\r\n\r\nOne alternative would be to add `enqueueWait` etc to the `af::event` API, but that seems like it might make it too heavyweight.","created_at":"2019-08-05T04:16:19Z","updated_at":"2019-08-05T04:27:51Z","html_url":"https://github.com/arrayfire/arrayfire/pull/2461#discussion_r310433753","pull_request_url":"https://api.github.com/repos/arrayfire/arrayfire/pulls/2461","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/arrayfire/arrayfire/pulls/comments/310433753"},"html":{"href":"https://github.com/arrayfire/arrayfire/pull/2461#discussion_r310433753"},"pull_request":{"href":"https://api.github.com/repos/arrayfire/arrayfire/pulls/2461"}},"in_reply_to_id":310417300},"pull_request":{"url":"https://api.github.com/repos/arrayfire/arrayfire/pulls/2461","id":262267443,"node_id":"MDExOlB1bGxSZXF1ZXN0MjYyMjY3NDQz","html_url":"https://github.com/arrayfire/arrayfire/pull/2461","diff_url":"https://github.com/arrayfire/arrayfire/pull/2461.diff","patch_url":"https://github.com/arrayfire/arrayfire/pull/2461.patch","issue_url":"https://api.github.com/repos/arrayfire/arrayfire/issues/2461","number":2461,"state":"open","locked":false,"title":"Add framework for extensible ArrayFire memory managers","user":{"login":"jacobkahn","id":7871817,"node_id":"MDQ6VXNlcjc4NzE4MTc=","avatar_url":"https://avatars1.githubusercontent.com/u/7871817?v=4","gravatar_id":"","url":"https://api.github.com/users/jacobkahn","html_url":"https://github.com/jacobkahn","followers_url":"https://api.github.com/users/jacobkahn/followers","following_url":"https://api.github.com/users/jacobkahn/following{/other_user}","gists_url":"https://api.github.com/users/jacobkahn/gists{/gist_id}","starred_url":"https://api.github.com/users/jacobkahn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jacobkahn/subscriptions","organizations_url":"https://api.github.com/users/jacobkahn/orgs","repos_url":"https://api.github.com/users/jacobkahn/repos","events_url":"https://api.github.com/users/jacobkahn/events{/privacy}","received_events_url":"https://api.github.com/users/jacobkahn/received_events","type":"User","site_admin":false},"body":"## Motivation\r\nMany different use cases require performance across many different memory allocation patterns. Even different devices/backends have different costs associated with memory allocations/manipulations. Having the flexibility to implement different memory management schemes can help optimize performance for the use case and backend.\r\n\r\n\r\n## Framework\r\n- The basic interface lives in a new header: `include/af/memory.h` and includes two interfaces:\r\n  - A C-style interface defined in the `af_memory_manager` struct, which includes function pointers to which custom memory manager implementations should be defined along with device/backend-specific functions that can be called by the implementation (e.g. `nativeAlloc`) and will be dynamically set. Typesafe C-style struct inheritance should be used.\r\n  - A C++ style interface using `MemoryManagerBase`, which defines pure-virtual methods for the API along with device/backend-specific functions as above.\r\n\r\nA C++ implementation is simple, and requires only:\r\n```c++\r\n#include <af/memory.h>\r\n...\r\nclass MyCustomMemoryManager : public af::MemoryManagerBase {\r\n...\r\n  void* alloc(const size_t size, bool user_lock) override {\r\n    ...\r\n    void* ptr = this->nativeAlloc(...);\r\n    ...\r\n  }\r\n};\r\n\r\n// In some code run at startup:\r\naf::MemoryManagerBase* p = new MyCustomMemoryManager();\r\naf::setMemoryManager(p);\r\n```\r\n\r\nFor the C API:\r\n```C\r\n#include <af/memory.h>\r\n...\r\naf_memory_manager_impl_alloc(const size_t size, bool user_lock) {\r\n  ...\r\n}\r\n\r\ntypedef struct af_memory_manager_impl {\r\n  af_memory_manager manager; // inherit base methods\r\n  // define custom implementation\r\n} af_memory_manager_impl;\r\n\r\n// In some code run at startup:\r\n...\r\naf_memory_manager* p = (af_memory_manager*)malloc(sizeof(af_memory_manager_impl));\r\np->af_memory_manager_alloc = &af_memory_manager_impl_alloc;\r\n...\r\naf_set_memory_manager(p);\r\n\r\n```\r\n\r\n### Details\r\n- The F-bound polymorphism pattern present in the existing `MemoryManager` implementation is removed; removing this was required as it precludes dynamically dispatching to a derived implementation.\r\n- New interfaces are defined for C/C++ (see below)\r\n- `MemoryManagerCWrapper` wraps a C struct implementation of a memory manager and facilitates using the same backend and `DeviceManager` APIs to manipulate a manager implemented in C.\r\n\r\n### API Design Decisions\r\n  - If a custom memory manager is not defined or set, the default memory manager will be used. While the default memory manager implements the new existing interface, behavior is completely identical to existing behavior by default (as verified by tests)\r\n  - Memory managers should be stored on the existing `DeviceManager` framework so as to preserve the integrity of existing backend APIs; memory managers can exist on a per-backend basis and work with the unified backend.\r\n  - Existing ArrayFire APIs expect garbage collection and memory step sizing to be implemented in a memory manager. These and a few other slightly opinionated methods are included in the overall API.\r\n    - That said, these methods can be noops or throw exceptions (e.g. garbage collection) if the style of custom memory manager implementation doesn't implement those facilities.\r\n  - Setting a memory manager should use one API in the same C/C++ fashion so as to be compatible with the unified backend via dynamic invocation of symbols in a shared object. The C and C++ APIs should have a polymorphic relationship such that either can be passed to the public API (`af::MemoryManagerBase` is this a subtype of `af_memory_manager`, a C struct)\r\n\r\n<hr/>\r\n\r\n- Adds tests defining custom memory manager implementations in both the C++ and C API and testing end-to-end Array allocations and public AF API calls (e.g. garbage collection, step size).\r\n","created_at":"2019-03-19T00:03:08Z","updated_at":"2019-08-05T04:27:51Z","closed_at":null,"merged_at":null,"merge_commit_sha":"14993e8a2b036ab6cdf8c4a45c59e8db0921b348","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/arrayfire/arrayfire/pulls/2461/commits","review_comments_url":"https://api.github.com/repos/arrayfire/arrayfire/pulls/2461/comments","review_comment_url":"https://api.github.com/repos/arrayfire/arrayfire/pulls/comments{/number}","comments_url":"https://api.github.com/repos/arrayfire/arrayfire/issues/2461/comments","statuses_url":"https://api.github.com/repos/arrayfire/arrayfire/statuses/0a1c6535aedb33e1e4ac4b8fa31be44f61f9c395","head":{"label":"jacobkahn:master","ref":"master","sha":"0a1c6535aedb33e1e4ac4b8fa31be44f61f9c395","user":{"login":"jacobkahn","id":7871817,"node_id":"MDQ6VXNlcjc4NzE4MTc=","avatar_url":"https://avatars1.githubusercontent.com/u/7871817?v=4","gravatar_id":"","url":"https://api.github.com/users/jacobkahn","html_url":"https://github.com/jacobkahn","followers_url":"https://api.github.com/users/jacobkahn/followers","following_url":"https://api.github.com/users/jacobkahn/following{/other_user}","gists_url":"https://api.github.com/users/jacobkahn/gists{/gist_id}","starred_url":"https://api.github.com/users/jacobkahn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jacobkahn/subscriptions","organizations_url":"https://api.github.com/users/jacobkahn/orgs","repos_url":"https://api.github.com/users/jacobkahn/repos","events_url":"https://api.github.com/users/jacobkahn/events{/privacy}","received_events_url":"https://api.github.com/users/jacobkahn/received_events","type":"User","site_admin":false},"repo":{"id":151323371,"node_id":"MDEwOlJlcG9zaXRvcnkxNTEzMjMzNzE=","name":"arrayfire","full_name":"jacobkahn/arrayfire","private":false,"owner":{"login":"jacobkahn","id":7871817,"node_id":"MDQ6VXNlcjc4NzE4MTc=","avatar_url":"https://avatars1.githubusercontent.com/u/7871817?v=4","gravatar_id":"","url":"https://api.github.com/users/jacobkahn","html_url":"https://github.com/jacobkahn","followers_url":"https://api.github.com/users/jacobkahn/followers","following_url":"https://api.github.com/users/jacobkahn/following{/other_user}","gists_url":"https://api.github.com/users/jacobkahn/gists{/gist_id}","starred_url":"https://api.github.com/users/jacobkahn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jacobkahn/subscriptions","organizations_url":"https://api.github.com/users/jacobkahn/orgs","repos_url":"https://api.github.com/users/jacobkahn/repos","events_url":"https://api.github.com/users/jacobkahn/events{/privacy}","received_events_url":"https://api.github.com/users/jacobkahn/received_events","type":"User","site_admin":false},"html_url":"https://github.com/jacobkahn/arrayfire","description":"ArrayFire: a general purpose GPU library.","fork":true,"url":"https://api.github.com/repos/jacobkahn/arrayfire","forks_url":"https://api.github.com/repos/jacobkahn/arrayfire/forks","keys_url":"https://api.github.com/repos/jacobkahn/arrayfire/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jacobkahn/arrayfire/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jacobkahn/arrayfire/teams","hooks_url":"https://api.github.com/repos/jacobkahn/arrayfire/hooks","issue_events_url":"https://api.github.com/repos/jacobkahn/arrayfire/issues/events{/number}","events_url":"https://api.github.com/repos/jacobkahn/arrayfire/events","assignees_url":"https://api.github.com/repos/jacobkahn/arrayfire/assignees{/user}","branches_url":"https://api.github.com/repos/jacobkahn/arrayfire/branches{/branch}","tags_url":"https://api.github.com/repos/jacobkahn/arrayfire/tags","blobs_url":"https://api.github.com/repos/jacobkahn/arrayfire/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jacobkahn/arrayfire/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jacobkahn/arrayfire/git/refs{/sha}","trees_url":"https://api.github.com/repos/jacobkahn/arrayfire/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jacobkahn/arrayfire/statuses/{sha}","languages_url":"https://api.github.com/repos/jacobkahn/arrayfire/languages","stargazers_url":"https://api.github.com/repos/jacobkahn/arrayfire/stargazers","contributors_url":"https://api.github.com/repos/jacobkahn/arrayfire/contributors","subscribers_url":"https://api.github.com/repos/jacobkahn/arrayfire/subscribers","subscription_url":"https://api.github.com/repos/jacobkahn/arrayfire/subscription","commits_url":"https://api.github.com/repos/jacobkahn/arrayfire/commits{/sha}","git_commits_url":"https://api.github.com/repos/jacobkahn/arrayfire/git/commits{/sha}","comments_url":"https://api.github.com/repos/jacobkahn/arrayfire/comments{/number}","issue_comment_url":"https://api.github.com/repos/jacobkahn/arrayfire/issues/comments{/number}","contents_url":"https://api.github.com/repos/jacobkahn/arrayfire/contents/{+path}","compare_url":"https://api.github.com/repos/jacobkahn/arrayfire/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jacobkahn/arrayfire/merges","archive_url":"https://api.github.com/repos/jacobkahn/arrayfire/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jacobkahn/arrayfire/downloads","issues_url":"https://api.github.com/repos/jacobkahn/arrayfire/issues{/number}","pulls_url":"https://api.github.com/repos/jacobkahn/arrayfire/pulls{/number}","milestones_url":"https://api.github.com/repos/jacobkahn/arrayfire/milestones{/number}","notifications_url":"https://api.github.com/repos/jacobkahn/arrayfire/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jacobkahn/arrayfire/labels{/name}","releases_url":"https://api.github.com/repos/jacobkahn/arrayfire/releases{/id}","deployments_url":"https://api.github.com/repos/jacobkahn/arrayfire/deployments","created_at":"2018-10-02T21:05:28Z","updated_at":"2019-08-05T04:27:08Z","pushed_at":"2019-08-05T04:27:05Z","git_url":"git://github.com/jacobkahn/arrayfire.git","ssh_url":"git@github.com:jacobkahn/arrayfire.git","clone_url":"https://github.com/jacobkahn/arrayfire.git","svn_url":"https://github.com/jacobkahn/arrayfire","homepage":"https://arrayfire.com","size":14088,"stargazers_count":0,"watchers_count":0,"language":"C++","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":0,"license":{"key":"other","name":"Other","spdx_id":"NOASSERTION","url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"arrayfire:master","ref":"master","sha":"9b307e73f852afeae092f71378ceb9afc1af27d8","user":{"login":"arrayfire","id":5395442,"node_id":"MDEyOk9yZ2FuaXphdGlvbjUzOTU0NDI=","avatar_url":"https://avatars0.githubusercontent.com/u/5395442?v=4","gravatar_id":"","url":"https://api.github.com/users/arrayfire","html_url":"https://github.com/arrayfire","followers_url":"https://api.github.com/users/arrayfire/followers","following_url":"https://api.github.com/users/arrayfire/following{/other_user}","gists_url":"https://api.github.com/users/arrayfire/gists{/gist_id}","starred_url":"https://api.github.com/users/arrayfire/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/arrayfire/subscriptions","organizations_url":"https://api.github.com/users/arrayfire/orgs","repos_url":"https://api.github.com/users/arrayfire/repos","events_url":"https://api.github.com/users/arrayfire/events{/privacy}","received_events_url":"https://api.github.com/users/arrayfire/received_events","type":"Organization","site_admin":false},"repo":{"id":25889802,"node_id":"MDEwOlJlcG9zaXRvcnkyNTg4OTgwMg==","name":"arrayfire","full_name":"arrayfire/arrayfire","private":false,"owner":{"login":"arrayfire","id":5395442,"node_id":"MDEyOk9yZ2FuaXphdGlvbjUzOTU0NDI=","avatar_url":"https://avatars0.githubusercontent.com/u/5395442?v=4","gravatar_id":"","url":"https://api.github.com/users/arrayfire","html_url":"https://github.com/arrayfire","followers_url":"https://api.github.com/users/arrayfire/followers","following_url":"https://api.github.com/users/arrayfire/following{/other_user}","gists_url":"https://api.github.com/users/arrayfire/gists{/gist_id}","starred_url":"https://api.github.com/users/arrayfire/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/arrayfire/subscriptions","organizations_url":"https://api.github.com/users/arrayfire/orgs","repos_url":"https://api.github.com/users/arrayfire/repos","events_url":"https://api.github.com/users/arrayfire/events{/privacy}","received_events_url":"https://api.github.com/users/arrayfire/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/arrayfire/arrayfire","description":"ArrayFire: a general purpose GPU library.","fork":false,"url":"https://api.github.com/repos/arrayfire/arrayfire","forks_url":"https://api.github.com/repos/arrayfire/arrayfire/forks","keys_url":"https://api.github.com/repos/arrayfire/arrayfire/keys{/key_id}","collaborators_url":"https://api.github.com/repos/arrayfire/arrayfire/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/arrayfire/arrayfire/teams","hooks_url":"https://api.github.com/repos/arrayfire/arrayfire/hooks","issue_events_url":"https://api.github.com/repos/arrayfire/arrayfire/issues/events{/number}","events_url":"https://api.github.com/repos/arrayfire/arrayfire/events","assignees_url":"https://api.github.com/repos/arrayfire/arrayfire/assignees{/user}","branches_url":"https://api.github.com/repos/arrayfire/arrayfire/branches{/branch}","tags_url":"https://api.github.com/repos/arrayfire/arrayfire/tags","blobs_url":"https://api.github.com/repos/arrayfire/arrayfire/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/arrayfire/arrayfire/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/arrayfire/arrayfire/git/refs{/sha}","trees_url":"https://api.github.com/repos/arrayfire/arrayfire/git/trees{/sha}","statuses_url":"https://api.github.com/repos/arrayfire/arrayfire/statuses/{sha}","languages_url":"https://api.github.com/repos/arrayfire/arrayfire/languages","stargazers_url":"https://api.github.com/repos/arrayfire/arrayfire/stargazers","contributors_url":"https://api.github.com/repos/arrayfire/arrayfire/contributors","subscribers_url":"https://api.github.com/repos/arrayfire/arrayfire/subscribers","subscription_url":"https://api.github.com/repos/arrayfire/arrayfire/subscription","commits_url":"https://api.github.com/repos/arrayfire/arrayfire/commits{/sha}","git_commits_url":"https://api.github.com/repos/arrayfire/arrayfire/git/commits{/sha}","comments_url":"https://api.github.com/repos/arrayfire/arrayfire/comments{/number}","issue_comment_url":"https://api.github.com/repos/arrayfire/arrayfire/issues/comments{/number}","contents_url":"https://api.github.com/repos/arrayfire/arrayfire/contents/{+path}","compare_url":"https://api.github.com/repos/arrayfire/arrayfire/compare/{base}...{head}","merges_url":"https://api.github.com/repos/arrayfire/arrayfire/merges","archive_url":"https://api.github.com/repos/arrayfire/arrayfire/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/arrayfire/arrayfire/downloads","issues_url":"https://api.github.com/repos/arrayfire/arrayfire/issues{/number}","pulls_url":"https://api.github.com/repos/arrayfire/arrayfire/pulls{/number}","milestones_url":"https://api.github.com/repos/arrayfire/arrayfire/milestones{/number}","notifications_url":"https://api.github.com/repos/arrayfire/arrayfire/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/arrayfire/arrayfire/labels{/name}","releases_url":"https://api.github.com/repos/arrayfire/arrayfire/releases{/id}","deployments_url":"https://api.github.com/repos/arrayfire/arrayfire/deployments","created_at":"2014-10-28T20:58:33Z","updated_at":"2019-08-04T17:12:05Z","pushed_at":"2019-08-05T04:27:07Z","git_url":"git://github.com/arrayfire/arrayfire.git","ssh_url":"git@github.com:arrayfire/arrayfire.git","clone_url":"https://github.com/arrayfire/arrayfire.git","svn_url":"https://github.com/arrayfire/arrayfire","homepage":"https://arrayfire.com","size":14247,"stargazers_count":2768,"watchers_count":2768,"language":"C++","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":389,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":228,"license":{"key":"other","name":"Other","spdx_id":"NOASSERTION","url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":389,"open_issues":228,"watchers":2768,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/arrayfire/arrayfire/pulls/2461"},"html":{"href":"https://github.com/arrayfire/arrayfire/pull/2461"},"issue":{"href":"https://api.github.com/repos/arrayfire/arrayfire/issues/2461"},"comments":{"href":"https://api.github.com/repos/arrayfire/arrayfire/issues/2461/comments"},"review_comments":{"href":"https://api.github.com/repos/arrayfire/arrayfire/pulls/2461/comments"},"review_comment":{"href":"https://api.github.com/repos/arrayfire/arrayfire/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/arrayfire/arrayfire/pulls/2461/commits"},"statuses":{"href":"https://api.github.com/repos/arrayfire/arrayfire/statuses/0a1c6535aedb33e1e4ac4b8fa31be44f61f9c395"}},"author_association":"CONTRIBUTOR"}}
other: {"actor":{"display_login":"jacobkahn"}}