Skip to content

Commit

Permalink
script_interface: Rewrite cuda_init module
Browse files Browse the repository at this point in the history
  • Loading branch information
jngrad committed Aug 2, 2022
1 parent 97bc394 commit 55797fc
Show file tree
Hide file tree
Showing 8 changed files with 239 additions and 165 deletions.
37 changes: 0 additions & 37 deletions src/python/espressomd/cuda_init.pxd

This file was deleted.

69 changes: 69 additions & 0 deletions src/python/espressomd/cuda_init.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#
# Copyright (C) 2013-2022 The ESPResSo project
#
# This file is part of ESPResSo.
#
# ESPResSo is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# ESPResSo is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#

from .script_interface import script_interface_register, ScriptInterfaceHelper


@script_interface_register
class CudaInitHandle(ScriptInterfaceHelper):
"""
Attributes
----------
device: :obj:`int`
Device id to use.
Methods
-------
list_devices()
List devices.
Returns
-------
:obj:`dict` :
Available CUDA devices sorted by device id.
"""
_so_name = "System::CudaInitHandle"
_so_creation_policy = "LOCAL"
_so_bind_methods = ("list_devices",)

def list_devices_properties(self):
"""
List devices with their properties on each host machine.
Returns
-------
:obj:`dict` :
Available CUDA devices with their properties sorted by hostname
and device id.
"""
out = self.call_method("list_devices_properties")
for listing in out.values():
for dev in listing.values():
dev["compute_capability"] = tuple(dev["compute_capability"])
return out


def gpu_available():
"""
Check whether there is at least one compatible GPU available.
"""
n_compatible_gpus = CudaInitHandle().call_method("get_n_gpus")
return n_compatible_gpus > 0
122 changes: 0 additions & 122 deletions src/python/espressomd/cuda_init.pyx

This file was deleted.

1 change: 1 addition & 0 deletions src/script_interface/system/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
target_sources(
Espresso_script_interface
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/initialize.cpp
${CMAKE_CURRENT_SOURCE_DIR}/CudaInitHandle.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Globals.cpp
${CMAKE_CURRENT_SOURCE_DIR}/System.cpp)
111 changes: 111 additions & 0 deletions src/script_interface/system/CudaInitHandle.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/*
* Copyright (C) 2013-2022 The ESPResSo project
*
* This file is part of ESPResSo.
*
* ESPResSo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ESPResSo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "CudaInitHandle.hpp"

#include "config.hpp"

#include "core/cuda_init.hpp"
#include "core/cuda_utils.hpp"

#include <string>
#include <unordered_map>
#include <utility>
#include <vector>

namespace ScriptInterface {
namespace System {

CudaInitHandle::CudaInitHandle() {
add_parameters({
#ifdef CUDA
{"device",
[this](Variant const &v) { cuda_set_device(get_value<int>(v)); },
[]() { return cuda_get_device(); }},
#endif // CUDA
});
}

#ifdef CUDA
/**
* @brief Silently ignore CUDA exceptions.
* This is useful when querying the properties of CUDA devices that may
* not have a suitable CUDA version, or when there is no compatible CUDA
* device available.
*/
template <typename F> static void skip_cuda_errors(F &&fun) {
try {
fun();
} catch (cuda_runtime_error const &) {
}
}
#endif // CUDA

Variant CudaInitHandle::do_call_method(std::string const &name,
VariantMap const &parameters) {
if (name == "list_devices") {
std::unordered_map<int, std::string> devices{};
#ifdef CUDA
auto n_gpus = 0;
skip_cuda_errors([&n_gpus]() { n_gpus = cuda_get_n_gpus(); });
for (int i = 0; i < n_gpus; ++i) {
skip_cuda_errors([&devices, i]() {
char gpu_name_buffer[4 + 64];
cuda_get_gpu_name(i, gpu_name_buffer);
devices[i] = std::string{gpu_name_buffer};
});
}
#endif // CUDA
return make_unordered_map_of_variants(devices);
}
if (name == "list_devices_properties") {
std::unordered_map<std::string, std::unordered_map<int, Variant>> dict{};
#ifdef CUDA
std::vector<EspressoGpuDevice> devices;
skip_cuda_errors([&devices]() { devices = cuda_gather_gpus(); });
for (auto const &dev : devices) {
auto const hostname = std::string{dev.proc_name};
if (dict.count(hostname) == 0) {
dict[hostname] = {};
}
std::unordered_map<std::string, Variant> dev_properties = {
{"name", std::string{dev.name}},
{"compute_capability",
Variant{std::vector<int>{
{dev.compute_capability_major, dev.compute_capability_minor}}}},
{"cores", dev.n_cores},
{"total_memory", dev.total_memory},
};
dict[hostname][dev.id] = std::move(dev_properties);
}
#endif // CUDA
return make_unordered_map_of_variants(dict);
}
if (name == "get_n_gpus") {
auto n_gpus = 0;
#ifdef CUDA
skip_cuda_errors([&n_gpus]() { n_gpus = cuda_get_n_gpus(); });
#endif // CUDA
return n_gpus;
}
return {};
}

} // namespace System
} // namespace ScriptInterface
41 changes: 41 additions & 0 deletions src/script_interface/system/CudaInitHandle.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright (C) 2013-2022 The ESPResSo project
*
* This file is part of ESPResSo.
*
* ESPResSo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ESPResSo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef ESPRESSO_SRC_SCRIPT_INTERFACE_SYSTEM_CUDA_INIT_HANDLE_HPP
#define ESPRESSO_SRC_SCRIPT_INTERFACE_SYSTEM_CUDA_INIT_HANDLE_HPP

#include "script_interface/ScriptInterface.hpp"
#include "script_interface/auto_parameters/AutoParameters.hpp"

#include <string>

namespace ScriptInterface {
namespace System {

class CudaInitHandle : public AutoParameters<CudaInitHandle> {
public:
CudaInitHandle();
Variant do_call_method(std::string const &name,
VariantMap const &parameters) override;
};

} // namespace System
} // namespace ScriptInterface

#endif
Loading

0 comments on commit 55797fc

Please sign in to comment.