From 91b08c22f96aef0977cecb9e264e47d08f079268 Mon Sep 17 00:00:00 2001 From: clemahieu Date: Fri, 8 Apr 2016 19:41:32 -0500 Subject: [PATCH] Adding opencl configuration object and relevant upgrades. --- rai/core_test/work_pool.cpp | 17 +++++++++- rai/node/node.cpp | 4 +-- rai/node/node.hpp | 3 -- rai/node/openclwork.cpp | 64 ++++++++++++++++++++++++++++++++----- rai/node/openclwork.hpp | 18 +++++++++-- rai/rai_landing/entry.cpp | 2 +- rai/rai_node/daemon.cpp | 55 ++++++++++++++++++++++++++++--- rai/rai_node/daemon.hpp | 4 +++ rai/rai_wallet/entry.cpp | 28 +++++++++++++--- 9 files changed, 169 insertions(+), 26 deletions(-) diff --git a/rai/core_test/work_pool.cpp b/rai/core_test/work_pool.cpp index ab6c0721..93f956b7 100644 --- a/rai/core_test/work_pool.cpp +++ b/rai/core_test/work_pool.cpp @@ -41,7 +41,7 @@ TEST (work, cancel) TEST (work, opencl) { - auto work (rai::opencl_work::create (true, 0, 1)); + auto work (rai::opencl_work::create (true, {0, 1, 1024 * 1024})); ASSERT_NE (nullptr, work); rai::work_pool pool (std::move (work)); ASSERT_NE (nullptr, pool.opencl); @@ -52,4 +52,19 @@ TEST (work, opencl) auto result (pool.generate (root)); ASSERT_FALSE (pool.work_validate (root, result)); } +} + +TEST (work, opencl_config) +{ + rai::opencl_config config1; + config1.platform = 1; + config1.device = 2; + config1.threads = 3; + boost::property_tree::ptree tree; + config1.serialize_json (tree); + rai::opencl_config config2; + ASSERT_FALSE (config2.deserialize_json (tree)); + ASSERT_EQ (1, config2.platform); + ASSERT_EQ (2, config2.device); + ASSERT_EQ (3, config2.threads); } \ No newline at end of file diff --git a/rai/node/node.cpp b/rai/node/node.cpp index a16f3c17..2eafb2ee 100644 --- a/rai/node/node.cpp +++ b/rai/node/node.cpp @@ -591,8 +591,7 @@ receive_minimum (rai::Mrai_ratio), inactive_supply (0), password_fanout (1024), io_threads (std::max (4, std::thread::hardware_concurrency ())), -work_threads (std::max (4, std::thread::hardware_concurrency ())), -opencl_work (false) +work_threads (std::max (4, std::thread::hardware_concurrency ())) { switch (rai::rai_network) { @@ -700,7 +699,6 @@ bool rai::node_config::upgrade_json (unsigned version, boost::property_tree::ptr } case 3: break; - break; default: throw std::runtime_error ("Unknown node_config version"); } diff --git a/rai/node/node.hpp b/rai/node/node.hpp index 21aa9410..d1ce04bc 100644 --- a/rai/node/node.hpp +++ b/rai/node/node.hpp @@ -307,9 +307,6 @@ public: unsigned password_fanout; unsigned io_threads; unsigned work_threads; - bool opencl_work; - unsigned opencl_platform; - unsigned opencl_device; static std::chrono::seconds constexpr keepalive_period = std::chrono::seconds (60); static std::chrono::seconds constexpr keepalive_cutoff = keepalive_period * 5; static std::chrono::minutes constexpr wallet_backup_interval = std::chrono::minutes (5); diff --git a/rai/node/openclwork.cpp b/rai/node/openclwork.cpp index f108e894..6bb91da2 100644 --- a/rai/node/openclwork.cpp +++ b/rai/node/openclwork.cpp @@ -484,7 +484,55 @@ void rai::opencl_environment::dump () } } -rai::opencl_work::opencl_work (bool & error_a, unsigned platform_a, unsigned device_a, rai::opencl_environment & environment_a) : +rai::opencl_config::opencl_config () : +platform (0), +device (0), +threads (1024 * 1024) +{ +} + +rai::opencl_config::opencl_config (unsigned platform_a, unsigned device_a, unsigned threads_a) : +platform (platform_a), +device (device_a), +threads (threads_a) +{ +} + +void rai::opencl_config::serialize_json (boost::property_tree::ptree & tree_a) const +{ + tree_a.put ("platform", std::to_string (platform)); + tree_a.put ("device", std::to_string (device)); + tree_a.put ("threads", std::to_string (threads)); +} + +bool rai::opencl_config::deserialize_json (boost::property_tree::ptree const & tree_a) +{ + auto result (false); + try + { + auto platform_l (tree_a.get ("platform")); + auto device_l (tree_a.get ("device")); + auto threads_l (tree_a.get ("threads")); + try + { + platform = std::stoull (platform_l); + device = std::stoull (device_l); + threads = std::stoull (threads_l); + } + catch (std::logic_error const &) + { + result = true; + } + } + catch (std::runtime_error const &) + { + result = true; + } + return result; +} + +rai::opencl_work::opencl_work (bool & error_a, rai::opencl_config const & config_a, rai::opencl_environment & environment_a) : +config (config_a), context (0), attempt_buffer (0), result_buffer (0), @@ -493,16 +541,16 @@ program (0), kernel (0), queue (0) { - error_a |= platform_a >= environment_a.platforms.size (); + error_a |= config.platform >= environment_a.platforms.size (); if (!error_a) { - auto & platform (environment_a.platforms [platform_a]); - error_a |= device_a >= platform.devices.size (); + auto & platform (environment_a.platforms [config.platform]); + error_a |= config.device >= platform.devices.size (); if (error_a) { rai::random_pool.GenerateBlock (reinterpret_cast (rand.s.data ()), rand.s.size () * sizeof (decltype (rand.s)::value_type)); std::array selected_devices; - selected_devices [0] = platform.devices [device_a]; + selected_devices [0] = platform.devices [config.device]; cl_context_properties contextProperties [] = { CL_CONTEXT_PLATFORM, @@ -598,7 +646,7 @@ uint64_t rai::opencl_work::generate_work (rai::work_pool & pool_a, rai::uint256_ { std::lock_guard lock (mutex); uint64_t result (0); - unsigned thread_count (rai::rai_network == rai::rai_networks::rai_test_network ? 128 : 1024 * 1024); + unsigned thread_count (rai::rai_network == rai::rai_networks::rai_test_network ? 128 : config.threads); size_t work_size [] = { thread_count, 0, 0 }; while (pool_a.work_validate (root_a, result)) { @@ -612,7 +660,7 @@ uint64_t rai::opencl_work::generate_work (rai::work_pool & pool_a, rai::uint256_ return result; } -std::unique_ptr rai::opencl_work::create (bool create_a, unsigned platform_a, unsigned device_a) +std::unique_ptr rai::opencl_work::create (bool create_a, rai::opencl_config const & config_a) { std::unique_ptr result; if (create_a) @@ -621,7 +669,7 @@ std::unique_ptr rai::opencl_work::create (bool create_a, unsi rai::opencl_environment environment (error); if (!error) { - result.reset (new rai::opencl_work (error, platform_a, device_a, environment)); + result.reset (new rai::opencl_work (error, config_a, environment)); if (error) { result.reset (); diff --git a/rai/node/openclwork.hpp b/rai/node/openclwork.hpp index 9e51f3de..3dd0ac2d 100644 --- a/rai/node/openclwork.hpp +++ b/rai/node/openclwork.hpp @@ -2,6 +2,8 @@ #include +#include + #include #include #include @@ -29,13 +31,25 @@ public: }; union uint256_union; class work_pool; +class opencl_config +{ +public: + opencl_config (); + opencl_config (unsigned, unsigned, unsigned); + void serialize_json (boost::property_tree::ptree &) const; + bool deserialize_json (boost::property_tree::ptree const &); + unsigned platform; + unsigned device; + unsigned threads; +}; class opencl_work { public: - opencl_work (bool &, unsigned, unsigned, rai::opencl_environment &); + opencl_work (bool &, rai::opencl_config const &, rai::opencl_environment &); ~opencl_work (); uint64_t generate_work (rai::work_pool &, rai::uint256_union const &); - static std::unique_ptr create (bool, unsigned, unsigned); + static std::unique_ptr create (bool, rai::opencl_config const &); + rai::opencl_config const & config; std::mutex mutex; cl_context context; cl_mem attempt_buffer; diff --git a/rai/rai_landing/entry.cpp b/rai/rai_landing/entry.cpp index c8ffd26c..e2f93d46 100644 --- a/rai/rai_landing/entry.cpp +++ b/rai/rai_landing/entry.cpp @@ -101,7 +101,7 @@ int main (int argc, char * const * argv) { rai::node_init init; auto service (boost::make_shared ()); - rai::work_pool work (rai::opencl_work::create (config.node.opencl_work, 0, 1)); + rai::work_pool work (nullptr); rai::alarm alarm (*service); auto node (std::make_shared (init, *service, working, alarm, config.node, work)); if (!init.error ()) diff --git a/rai/rai_node/daemon.cpp b/rai/rai_node/daemon.cpp index 9f30f255..ecb6fd48 100644 --- a/rai/rai_node/daemon.cpp +++ b/rai/rai_node/daemon.cpp @@ -6,12 +6,14 @@ #include rai_daemon::daemon_config::daemon_config () : -rpc_enable (false) +rpc_enable (false), +opencl_enable (false) { } void rai_daemon::daemon_config::serialize_json (boost::property_tree::ptree & tree_a) { + tree_a.put ("version", version); tree_a.put ("rpc_enable", rpc_enable); boost::property_tree::ptree rpc_l; rpc.serialize_json (rpc_l); @@ -19,6 +21,10 @@ void rai_daemon::daemon_config::serialize_json (boost::property_tree::ptree & tr boost::property_tree::ptree node_l; node.serialize_json (node_l); tree_a.add_child ("node", node_l); + tree_a.put ("opencl_enable", opencl_enable); + boost::property_tree::ptree opencl_l; + opencl.serialize_json (opencl_l); + tree_a.add_child ("opencl", opencl_l); } bool rai_daemon::daemon_config::deserialize_json (bool & upgraded_a, boost::property_tree::ptree & tree_a) @@ -28,11 +34,21 @@ bool rai_daemon::daemon_config::deserialize_json (bool & upgraded_a, boost::prop { if (!tree_a.empty ()) { + auto version_l (tree_a.get_optional ("version")); + if (!version_l) + { + tree_a.put ("version", "1"); + version_l = "1"; + } + upgraded_a |= upgrade_json (std::stoull (version_l.get ()), tree_a); rpc_enable = tree_a.get ("rpc_enable"); - auto & node_l (tree_a.get_child ("node")); - error |= node.deserialize_json (upgraded_a, node_l); auto rpc_l (tree_a.get_child ("rpc")); error |= rpc.deserialize_json (rpc_l); + auto & node_l (tree_a.get_child ("node")); + error |= node.deserialize_json (upgraded_a, node_l); + opencl_enable = tree_a.get ("opencl_enable"); + auto & opencl_l (tree_a.get_child ("opencl")); + error |= opencl.deserialize_json (opencl_l); } else { @@ -47,6 +63,37 @@ bool rai_daemon::daemon_config::deserialize_json (bool & upgraded_a, boost::prop return error; } + +bool rai_daemon::daemon_config::upgrade_json (unsigned version_a, boost::property_tree::ptree & tree_a) +{ + auto result (false); + switch (version_a) + { + case 1: + { + auto opencl_enable_l (tree_a.get_optional ("opencl_enable")); + if (!opencl_enable_l) + { + tree_a.put ("opencl_enable", "false"); + } + auto opencl_l (tree_a.get_child_optional ("opencl")); + if (!opencl_l) + { + boost::property_tree::ptree opencl_l; + opencl.serialize_json (opencl_l); + tree_a.put_child ("opencl", opencl_l); + } + tree_a.put ("version", "2"); + result = true; + } + case 2: + break; + default: + throw std::runtime_error ("Unknown daemon_config version"); + } + return result; +} + void rai_daemon::daemon::run () { auto working (rai::working_path ()); @@ -62,7 +109,7 @@ void rai_daemon::daemon::run () if (!error) { auto service (boost::make_shared ()); - rai::work_pool work (std::move (rai::opencl_work::create (config.node.opencl_work, 0, 1))); + rai::work_pool work (rai::opencl_work::create (config.opencl_enable, config.opencl)); rai::alarm alarm (*service); rai::node_init init; auto node (std::make_shared (init, *service, working, alarm, config.node, work)); diff --git a/rai/rai_node/daemon.hpp b/rai/rai_node/daemon.hpp index 9aa18d6c..3b1279c5 100644 --- a/rai/rai_node/daemon.hpp +++ b/rai/rai_node/daemon.hpp @@ -14,8 +14,12 @@ namespace rai_daemon daemon_config (); bool deserialize_json (bool &, boost::property_tree::ptree &); void serialize_json (boost::property_tree::ptree &); + bool upgrade_json (unsigned, boost::property_tree::ptree &); + unsigned version; bool rpc_enable; rai::rpc_config rpc; rai::node_config node; + bool opencl_enable; + rai::opencl_config opencl; }; } \ No newline at end of file diff --git a/rai/rai_wallet/entry.cpp b/rai/rai_wallet/entry.cpp index 811ee354..06833821 100644 --- a/rai/rai_wallet/entry.cpp +++ b/rai/rai_wallet/entry.cpp @@ -15,7 +15,8 @@ class qt_wallet_config public: qt_wallet_config () : account (0), - rpc_enable (false) + rpc_enable (false), + opencl_enable (false) { rai::random_pool.GenerateBlock (wallet.bytes.data (), wallet.bytes.size ()); assert (!wallet.is_zero ()); @@ -46,9 +47,26 @@ public: result = true; } case 3: - break; + { + auto opencl_enable_l (tree_a.get_optional ("opencl_enable")); + if (!opencl_enable_l) + { + tree_a.put ("opencl_enable", "false"); + } + auto opencl_l (tree_a.get_child_optional ("opencl")); + if (!opencl_l) + { + boost::property_tree::ptree opencl_l; + opencl.serialize_json (opencl_l); + tree_a.put_child ("opencl", opencl_l); + } + tree_a.put ("version", "4"); + result = true; + } + case 4: + break; default: - throw std::runtime_error ("Unknown qt_wallet_config version"); + throw std::runtime_error ("Unknown qt_wallet_config version"); } return result; } @@ -130,6 +148,8 @@ public: rai::node_config node; bool rpc_enable; rai::rpc_config rpc; + bool opencl_enable; + rai::opencl_config opencl; }; int run_wallet (int argc, char * const * argv) @@ -149,7 +169,7 @@ int run_wallet (int argc, char * const * argv) QApplication application (argc, const_cast (argv)); rai::set_application_icon (application); auto service (boost::make_shared ()); - rai::work_pool work (rai::opencl_work::create (config.node.opencl_work, 0, 1)); + rai::work_pool work (rai::opencl_work::create (config.opencl_enable, config.opencl)); rai::alarm alarm (*service); rai::node_init init; auto node (std::make_shared (init, *service, working, alarm, config.node, work));