{"action":"created","comment":{"url":"https://api.github.com/repos/gcp/leela-zero/pulls/comments/177398445","pull_request_review_id":107257982,"id":177398445,"diff_hunk":"@@ -24,20 +24,97 @@\n #include <atomic>\n #include <memory>\n #include <vector>\n+#include <cassert>\n+#include <cstring>\n \n #include \"GameState.h\"\n #include \"Network.h\"\n #include \"SMP.h\"\n \n+class UCTNode;\n+\n+// 'lazy-initializable' version of std::unique_ptr<UCTNode>.\n+// When a UCTNodePointer is constructed, the constructor arguments are stored instead\n+// of constructing the actual UCTNode instance.  Later when the UCTNode is needed,\n+// the external code calls expand() which actually constructs the UCTNode.\n+// Basically, this is a 'tagged union' of:\n+//  - std::unique_ptr<UCTNode> pointer;\n+//  - std::pair<float, std::int16_t> args;\n+\n+// WARNING : expand() is not thread-safe and hence has to be protected by an external lock.\n+\n+class UCTNodePointer {\n+private:\n+    // the raw storage used here.\n+    // if bit 0 is 0, m_data is the actual pointer.\n+    // if bit 0 is 1, bit [31:16] is the vertex value, bit [63:32] is the score.\n+    // (I really wanted to use C-style bit fields and unions, but those aren't portable)\n+    mutable uint64_t m_data = 1;\n+\n+    bool _expanded() const {\n+        return (m_data & 1ULL) == 0;\n+    } \n+    UCTNode * _readptr() const {\n+        assert(_expanded());\n+        return reinterpret_cast<UCTNode*>(m_data);\n+    }\n+\n+    std::int16_t _vertex() const {\n+        assert(!_expanded());\n+        std::uint16_t x = static_cast<std::uint16_t>( (m_data >> 16) & 0xffff);","path":"src/UCTNode.h","position":41,"original_position":41,"commit_id":"06f6bc94e3138f94d000c8c219f5b6a0eaf9963c","original_commit_id":"06f6bc94e3138f94d000c8c219f5b6a0eaf9963c","user":{"login":"gcp","id":1104290,"avatar_url":"https://avatars2.githubusercontent.com/u/1104290?v=4","gravatar_id":"","url":"https://api.github.com/users/gcp","html_url":"https://github.com/gcp","followers_url":"https://api.github.com/users/gcp/followers","following_url":"https://api.github.com/users/gcp/following{/other_user}","gists_url":"https://api.github.com/users/gcp/gists{/gist_id}","starred_url":"https://api.github.com/users/gcp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gcp/subscriptions","organizations_url":"https://api.github.com/users/gcp/orgs","repos_url":"https://api.github.com/users/gcp/repos","events_url":"https://api.github.com/users/gcp/events{/privacy}","received_events_url":"https://api.github.com/users/gcp/received_events","type":"User","site_admin":false},"body":"auto x =\r\n\r\nDo you need the -> uint -> int cast sequence? (You need it in the other direction to tackle the sign bit, but not here I think)","created_at":"2018-03-27T12:01:54Z","updated_at":"2018-03-27T12:13:17Z","html_url":"https://github.com/gcp/leela-zero/pull/1097#discussion_r177398445","pull_request_url":"https://api.github.com/repos/gcp/leela-zero/pulls/1097","author_association":"OWNER","_links":{"self":{"href":"https://api.github.com/repos/gcp/leela-zero/pulls/comments/177398445"},"html":{"href":"https://github.com/gcp/leela-zero/pull/1097#discussion_r177398445"},"pull_request":{"href":"https://api.github.com/repos/gcp/leela-zero/pulls/1097"}}},"pull_request":{"url":"https://api.github.com/repos/gcp/leela-zero/pulls/1097","id":177269583,"html_url":"https://github.com/gcp/leela-zero/pull/1097","diff_url":"https://github.com/gcp/leela-zero/pull/1097.diff","patch_url":"https://github.com/gcp/leela-zero/pull/1097.patch","issue_url":"https://api.github.com/repos/gcp/leela-zero/issues/1097","number":1097,"state":"open","locked":false,"title":"UCTNode lazy initialization for memory footprint reduction (attempt 3 of \"Reduce the memory consumption of nodes\")","user":{"login":"ihavnoid","id":33939814,"avatar_url":"https://avatars3.githubusercontent.com/u/33939814?v=4","gravatar_id":"","url":"https://api.github.com/users/ihavnoid","html_url":"https://github.com/ihavnoid","followers_url":"https://api.github.com/users/ihavnoid/followers","following_url":"https://api.github.com/users/ihavnoid/following{/other_user}","gists_url":"https://api.github.com/users/ihavnoid/gists{/gist_id}","starred_url":"https://api.github.com/users/ihavnoid/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ihavnoid/subscriptions","organizations_url":"https://api.github.com/users/ihavnoid/orgs","repos_url":"https://api.github.com/users/ihavnoid/repos","events_url":"https://api.github.com/users/ihavnoid/events{/privacy}","received_events_url":"https://api.github.com/users/ihavnoid/received_events","type":"User","site_admin":false},"body":"- When we expand children nodes, we don't actually create the UCTNode but only keep a proxy of it.\r\n- The actual child node is created (called 'expanded' here) only if it is selected from uct_select_child\r\n  - (One more case - for ease of implementation, the root's children are always expanded)\r\n- As of this commit, we saturate around 3.45GB memory footprint when we hit MAX_TREE_SIZE (down from 8.9GB)","created_at":"2018-03-25T02:40:26Z","updated_at":"2018-03-27T12:13:17Z","closed_at":null,"merged_at":null,"merge_commit_sha":"33a8bd24e43174eee489901be1434b40eac64701","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/gcp/leela-zero/pulls/1097/commits","review_comments_url":"https://api.github.com/repos/gcp/leela-zero/pulls/1097/comments","review_comment_url":"https://api.github.com/repos/gcp/leela-zero/pulls/comments{/number}","comments_url":"https://api.github.com/repos/gcp/leela-zero/issues/1097/comments","statuses_url":"https://api.github.com/repos/gcp/leela-zero/statuses/06f6bc94e3138f94d000c8c219f5b6a0eaf9963c","head":{"label":"ihavnoid:uct_memopt_v2","ref":"uct_memopt_v2","sha":"06f6bc94e3138f94d000c8c219f5b6a0eaf9963c","user":{"login":"ihavnoid","id":33939814,"avatar_url":"https://avatars3.githubusercontent.com/u/33939814?v=4","gravatar_id":"","url":"https://api.github.com/users/ihavnoid","html_url":"https://github.com/ihavnoid","followers_url":"https://api.github.com/users/ihavnoid/followers","following_url":"https://api.github.com/users/ihavnoid/following{/other_user}","gists_url":"https://api.github.com/users/ihavnoid/gists{/gist_id}","starred_url":"https://api.github.com/users/ihavnoid/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ihavnoid/subscriptions","organizations_url":"https://api.github.com/users/ihavnoid/orgs","repos_url":"https://api.github.com/users/ihavnoid/repos","events_url":"https://api.github.com/users/ihavnoid/events{/privacy}","received_events_url":"https://api.github.com/users/ihavnoid/received_events","type":"User","site_admin":false},"repo":{"id":112053508,"name":"leela-zero","full_name":"ihavnoid/leela-zero","owner":{"login":"ihavnoid","id":33939814,"avatar_url":"https://avatars3.githubusercontent.com/u/33939814?v=4","gravatar_id":"","url":"https://api.github.com/users/ihavnoid","html_url":"https://github.com/ihavnoid","followers_url":"https://api.github.com/users/ihavnoid/followers","following_url":"https://api.github.com/users/ihavnoid/following{/other_user}","gists_url":"https://api.github.com/users/ihavnoid/gists{/gist_id}","starred_url":"https://api.github.com/users/ihavnoid/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ihavnoid/subscriptions","organizations_url":"https://api.github.com/users/ihavnoid/orgs","repos_url":"https://api.github.com/users/ihavnoid/repos","events_url":"https://api.github.com/users/ihavnoid/events{/privacy}","received_events_url":"https://api.github.com/users/ihavnoid/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/ihavnoid/leela-zero","description":"Go engine with no human-provided knowledge, modeled after the AlphaGo Zero paper.","fork":true,"url":"https://api.github.com/repos/ihavnoid/leela-zero","forks_url":"https://api.github.com/repos/ihavnoid/leela-zero/forks","keys_url":"https://api.github.com/repos/ihavnoid/leela-zero/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ihavnoid/leela-zero/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ihavnoid/leela-zero/teams","hooks_url":"https://api.github.com/repos/ihavnoid/leela-zero/hooks","issue_events_url":"https://api.github.com/repos/ihavnoid/leela-zero/issues/events{/number}","events_url":"https://api.github.com/repos/ihavnoid/leela-zero/events","assignees_url":"https://api.github.com/repos/ihavnoid/leela-zero/assignees{/user}","branches_url":"https://api.github.com/repos/ihavnoid/leela-zero/branches{/branch}","tags_url":"https://api.github.com/repos/ihavnoid/leela-zero/tags","blobs_url":"https://api.github.com/repos/ihavnoid/leela-zero/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ihavnoid/leela-zero/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ihavnoid/leela-zero/git/refs{/sha}","trees_url":"https://api.github.com/repos/ihavnoid/leela-zero/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ihavnoid/leela-zero/statuses/{sha}","languages_url":"https://api.github.com/repos/ihavnoid/leela-zero/languages","stargazers_url":"https://api.github.com/repos/ihavnoid/leela-zero/stargazers","contributors_url":"https://api.github.com/repos/ihavnoid/leela-zero/contributors","subscribers_url":"https://api.github.com/repos/ihavnoid/leela-zero/subscribers","subscription_url":"https://api.github.com/repos/ihavnoid/leela-zero/subscription","commits_url":"https://api.github.com/repos/ihavnoid/leela-zero/commits{/sha}","git_commits_url":"https://api.github.com/repos/ihavnoid/leela-zero/git/commits{/sha}","comments_url":"https://api.github.com/repos/ihavnoid/leela-zero/comments{/number}","issue_comment_url":"https://api.github.com/repos/ihavnoid/leela-zero/issues/comments{/number}","contents_url":"https://api.github.com/repos/ihavnoid/leela-zero/contents/{+path}","compare_url":"https://api.github.com/repos/ihavnoid/leela-zero/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ihavnoid/leela-zero/merges","archive_url":"https://api.github.com/repos/ihavnoid/leela-zero/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ihavnoid/leela-zero/downloads","issues_url":"https://api.github.com/repos/ihavnoid/leela-zero/issues{/number}","pulls_url":"https://api.github.com/repos/ihavnoid/leela-zero/pulls{/number}","milestones_url":"https://api.github.com/repos/ihavnoid/leela-zero/milestones{/number}","notifications_url":"https://api.github.com/repos/ihavnoid/leela-zero/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ihavnoid/leela-zero/labels{/name}","releases_url":"https://api.github.com/repos/ihavnoid/leela-zero/releases{/id}","deployments_url":"https://api.github.com/repos/ihavnoid/leela-zero/deployments","created_at":"2017-11-26T03:41:55Z","updated_at":"2017-11-26T03:41:57Z","pushed_at":"2018-03-27T05:55:54Z","git_url":"git://github.com/ihavnoid/leela-zero.git","ssh_url":"git@github.com:ihavnoid/leela-zero.git","clone_url":"https://github.com/ihavnoid/leela-zero.git","svn_url":"https://github.com/ihavnoid/leela-zero","homepage":null,"size":16710,"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,"open_issues_count":0,"license":null,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"gcp:next","ref":"next","sha":"cc143abaa6bd76f5aafb370da3248f37667d037f","user":{"login":"gcp","id":1104290,"avatar_url":"https://avatars2.githubusercontent.com/u/1104290?v=4","gravatar_id":"","url":"https://api.github.com/users/gcp","html_url":"https://github.com/gcp","followers_url":"https://api.github.com/users/gcp/followers","following_url":"https://api.github.com/users/gcp/following{/other_user}","gists_url":"https://api.github.com/users/gcp/gists{/gist_id}","starred_url":"https://api.github.com/users/gcp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gcp/subscriptions","organizations_url":"https://api.github.com/users/gcp/orgs","repos_url":"https://api.github.com/users/gcp/repos","events_url":"https://api.github.com/users/gcp/events{/privacy}","received_events_url":"https://api.github.com/users/gcp/received_events","type":"User","site_admin":false},"repo":{"id":108166281,"name":"leela-zero","full_name":"gcp/leela-zero","owner":{"login":"gcp","id":1104290,"avatar_url":"https://avatars2.githubusercontent.com/u/1104290?v=4","gravatar_id":"","url":"https://api.github.com/users/gcp","html_url":"https://github.com/gcp","followers_url":"https://api.github.com/users/gcp/followers","following_url":"https://api.github.com/users/gcp/following{/other_user}","gists_url":"https://api.github.com/users/gcp/gists{/gist_id}","starred_url":"https://api.github.com/users/gcp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gcp/subscriptions","organizations_url":"https://api.github.com/users/gcp/orgs","repos_url":"https://api.github.com/users/gcp/repos","events_url":"https://api.github.com/users/gcp/events{/privacy}","received_events_url":"https://api.github.com/users/gcp/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/gcp/leela-zero","description":"Go engine with no human-provided knowledge, modeled after the AlphaGo Zero paper.","fork":false,"url":"https://api.github.com/repos/gcp/leela-zero","forks_url":"https://api.github.com/repos/gcp/leela-zero/forks","keys_url":"https://api.github.com/repos/gcp/leela-zero/keys{/key_id}","collaborators_url":"https://api.github.com/repos/gcp/leela-zero/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/gcp/leela-zero/teams","hooks_url":"https://api.github.com/repos/gcp/leela-zero/hooks","issue_events_url":"https://api.github.com/repos/gcp/leela-zero/issues/events{/number}","events_url":"https://api.github.com/repos/gcp/leela-zero/events","assignees_url":"https://api.github.com/repos/gcp/leela-zero/assignees{/user}","branches_url":"https://api.github.com/repos/gcp/leela-zero/branches{/branch}","tags_url":"https://api.github.com/repos/gcp/leela-zero/tags","blobs_url":"https://api.github.com/repos/gcp/leela-zero/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/gcp/leela-zero/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/gcp/leela-zero/git/refs{/sha}","trees_url":"https://api.github.com/repos/gcp/leela-zero/git/trees{/sha}","statuses_url":"https://api.github.com/repos/gcp/leela-zero/statuses/{sha}","languages_url":"https://api.github.com/repos/gcp/leela-zero/languages","stargazers_url":"https://api.github.com/repos/gcp/leela-zero/stargazers","contributors_url":"https://api.github.com/repos/gcp/leela-zero/contributors","subscribers_url":"https://api.github.com/repos/gcp/leela-zero/subscribers","subscription_url":"https://api.github.com/repos/gcp/leela-zero/subscription","commits_url":"https://api.github.com/repos/gcp/leela-zero/commits{/sha}","git_commits_url":"https://api.github.com/repos/gcp/leela-zero/git/commits{/sha}","comments_url":"https://api.github.com/repos/gcp/leela-zero/comments{/number}","issue_comment_url":"https://api.github.com/repos/gcp/leela-zero/issues/comments{/number}","contents_url":"https://api.github.com/repos/gcp/leela-zero/contents/{+path}","compare_url":"https://api.github.com/repos/gcp/leela-zero/compare/{base}...{head}","merges_url":"https://api.github.com/repos/gcp/leela-zero/merges","archive_url":"https://api.github.com/repos/gcp/leela-zero/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/gcp/leela-zero/downloads","issues_url":"https://api.github.com/repos/gcp/leela-zero/issues{/number}","pulls_url":"https://api.github.com/repos/gcp/leela-zero/pulls{/number}","milestones_url":"https://api.github.com/repos/gcp/leela-zero/milestones{/number}","notifications_url":"https://api.github.com/repos/gcp/leela-zero/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/gcp/leela-zero/labels{/name}","releases_url":"https://api.github.com/repos/gcp/leela-zero/releases{/id}","deployments_url":"https://api.github.com/repos/gcp/leela-zero/deployments","created_at":"2017-10-24T18:19:43Z","updated_at":"2018-03-27T09:51:49Z","pushed_at":"2018-03-27T05:55:55Z","git_url":"git://github.com/gcp/leela-zero.git","ssh_url":"git@github.com:gcp/leela-zero.git","clone_url":"https://github.com/gcp/leela-zero.git","svn_url":"https://github.com/gcp/leela-zero","homepage":null,"size":2558,"stargazers_count":1922,"watchers_count":1922,"language":"C++","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":373,"mirror_url":null,"archived":false,"open_issues_count":184,"license":{"key":"gpl-3.0","name":"GNU General Public License v3.0","spdx_id":"GPL-3.0","url":"https://api.github.com/licenses/gpl-3.0"},"forks":373,"open_issues":184,"watchers":1922,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/gcp/leela-zero/pulls/1097"},"html":{"href":"https://github.com/gcp/leela-zero/pull/1097"},"issue":{"href":"https://api.github.com/repos/gcp/leela-zero/issues/1097"},"comments":{"href":"https://api.github.com/repos/gcp/leela-zero/issues/1097/comments"},"review_comments":{"href":"https://api.github.com/repos/gcp/leela-zero/pulls/1097/comments"},"review_comment":{"href":"https://api.github.com/repos/gcp/leela-zero/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/gcp/leela-zero/pulls/1097/commits"},"statuses":{"href":"https://api.github.com/repos/gcp/leela-zero/statuses/06f6bc94e3138f94d000c8c219f5b6a0eaf9963c"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"gcp"}}