Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
shamrock_smi.cpp
Go to the documentation of this file.
1// -------------------------------------------------------//
2//
3// SHAMROCK code for hydrodynamics
4// Copyright (c) 2021-2026 Timothée David--Cléris <tim.shamrock@proton.me>
5// SPDX-License-Identifier: CeCILL Free Software License Agreement v2.1
6// Shamrock is licensed under the CeCILL 2.1 License, see LICENSE for more information
7//
8// -------------------------------------------------------//
9
16#include "shambase/memory.hpp"
18#include "shambase/string.hpp"
19#include "shambase/time.hpp"
24#include "shambackends/sycl.hpp"
26#include "shamcmdopt/cmdopt.hpp"
27#include "shamcmdopt/env.hpp"
28#include "shamcomm/logs.hpp"
32#include <unordered_map>
33#include <functional>
34#include <string>
35#include <vector>
36
37namespace {
38 static bool SHAMROCK_SMI_USE_HASH
40 "SHAMROCK_SMI_USE_HASH", "1", "use hash based string histogram for shamrock --smi")
41 == "1";
42}
43
44namespace shamsys {
45
46 void shamrock_smi_summary() {
48 shambase::throw_with_loc<std::runtime_error>("MPI should be initialized");
49 }
50
52
53 auto add_array = [&](std::string &print, std::string header, std::string data) {
54 print
55 += (header
56 + "----------------------------------------------------------------------------"
57 "---------------")
58 .substr(0, 91)
59 + "\n";
60 print += ("| id | Device name | Platform name | Type | "
61 " Memsize | units |\n");
62 print += ("----------------------------------------------------------------------------"
63 "---------------\n");
64 print += (data);
65 print += ("----------------------------------------------------------------------------"
66 "---------------\n");
67 };
68
69 std::string nodeconfig = "";
70 for_each_device([&](u32 key_global, const sycl::platform &plat, const sycl::device &dev) {
71 auto PlatformName = plat.get_info<sycl::info::platform::name>();
72 auto DeviceName = dev.get_info<sycl::info::device::name>();
73
74 auto device = sham::sycl_dev_to_sham_dev(key_global, dev);
75
76 std::string devname = shambase::trunc_str(DeviceName, 25);
77 std::string platname = shambase::trunc_str(PlatformName, 22);
78 std::string devtype = shambase::trunc_str(sham::device_type_name(device.prop.type), 6);
79
80 f64 mem = device.prop.global_mem_size;
81 std::string memstr = shambase::readable_sizeof(mem);
82
83 nodeconfig += shambase::format(
84 "| {:>2} | {:>25.25} | {:>22.22} | {:>6} | {:>12} | {:>5} | ",
85 key_global,
86 devname,
87 platname,
88 devtype,
89 memstr,
90 device.prop.max_compute_units)
91 + "\n";
92 });
93
94 std::unordered_map<std::string, int> nodeconfig_histogram
95 = shamalgs::collective::string_histogram({nodeconfig}, "@#%", SHAMROCK_SMI_USE_HASH);
96
97 if (rank == 0) {
98 std::string print = "Available devices :\n";
99 for (auto &[node_conf, count] : nodeconfig_histogram) {
100 std::string arr = "";
101 add_array(arr, shambase::format("{} x Shamrock process: ", count), node_conf);
102 print += shambase::format("\n{}\n", arr);
103 }
104 printf("%s", print.data());
105 }
106 }
107
111 shambase::throw_with_loc<std::runtime_error>("MPI should be initialized");
112 }
113
114 u32 rank = shamcomm::world_rank();
115
116 std::string print_buf = "";
117
118 for_each_device([&](u32 key_global, const sycl::platform &plat, const sycl::device &dev) {
119 auto PlatformName = plat.get_info<sycl::info::platform::name>();
120 auto DeviceName = dev.get_info<sycl::info::device::name>();
121
122 auto device = sham::sycl_dev_to_sham_dev(key_global, dev);
123
124 std::string devname = shambase::trunc_str(DeviceName, 25);
125 std::string platname = shambase::trunc_str(PlatformName, 22);
126 std::string devtype = shambase::trunc_str(sham::device_type_name(device.prop.type), 6);
127
128 f64 mem = device.prop.global_mem_size;
129 std::string memstr = shambase::readable_sizeof(mem);
130
131 print_buf += shambase::format(
132 "| {:>4} | {:>2} | {:>25.25} | {:>22.22} | {:>6} | {:>12} | {:>5} | ",
133 rank,
134 key_global,
135 devname,
136 platname,
137 devtype,
138 memstr,
139 device.prop.max_compute_units)
140 + "\n";
141 });
142
143 std::string recv;
144 shamalgs::collective::gather_str(print_buf, recv);
145 if (rank == 0) {
146 std::string print = "Available devices :\n";
147 print += ("----------------------------------------------------------------------------"
148 "----------------------\n");
149 print += ("| rank | id | Device name | Platform name | Type | "
150 " Memsize | units |\n");
151 print += ("----------------------------------------------------------------------------"
152 "----------------------\n");
153 print += (recv);
154 print += ("----------------------------------------------------------------------------"
155 "----------------------\n");
156 printf("%s\n", print.data());
157 }
158 }
159
161 void shamrock_smi_selected(bool list_all_devices) {
163 shambase::throw_with_loc<std::runtime_error>("MPI should be initialized");
164 }
165
166 if (shamsys::instance::is_initialized()) {
167
168 if (list_all_devices) {
169 shamsys::instance::print_queue_map();
170 }
171
172 sham::Device &dev
173 = shambase::get_check_ref(instance::get_compute_scheduler().ctx->device);
174
175 std::string DeviceName = dev.prop.name;
176
177 auto nolimit_if_too_large = [](u64 sz) -> std::string {
178 if (sz < u32_max) {
179 return std::to_string(sz);
180 } else {
181 return "No limit !";
182 }
183 };
184
185 std::string dev_with_id = shambase::format(
186 R"({} (id={})
187 - default_work_group_size = {}
188 - global_mem_size = {}
189 - local_mem_size = {}
190 - mem_base_addr_align = {},
191 - max_mem_alloc_size_dev = {},
192 - max_mem_alloc_size_host = {},
193 - pci_address = {})",
194 DeviceName,
195 dev.device_id,
198 nolimit_if_too_large(dev.prop.local_mem_size),
202 dev.prop.pci_address ? *dev.prop.pci_address : "Unknown");
203
204 if (!dev.prop.warnings.empty()) {
205 dev_with_id += "\n - Warnings:";
206 for (auto &warning : dev.prop.warnings) {
207 dev_with_id += shambase::format("\n - {}", warning);
208 }
209 }
210
211 std::unordered_map<std::string, int> devicename_histogram
212 = shamalgs::collective::string_histogram(
213 {dev_with_id}, "xxx\nxxx", SHAMROCK_SMI_USE_HASH);
214
215 f64 mem = dev.prop.global_mem_size;
216 u64 compute_units = dev.prop.max_compute_units;
217
218 f64 total_mem = shamalgs::collective::allreduce_sum(mem);
219 u64 n_compute_units = shamalgs::collective::allreduce_sum(compute_units);
220
221 if (shamcomm::world_rank() == 0) {
222
223 std::string print = "Selected devices : (totals can be wrong if using multiple "
224 "ranks per device)\n";
225
226 for (auto &[key, value] : devicename_histogram) {
227 print += shambase::format(" - {} x {}", value, key) + "\n";
228 }
229 print += " Total memory : " + shambase::readable_sizeof(total_mem) + "\n";
230 print += " Total compute units : " + std::to_string(n_compute_units) + "\n";
231
232 printf("%s\n", print.data());
233 }
234 }
235 }
236
237 void shamrock_smi(bool list_all_devices) {
238 if (shamcomm::world_rank() == 0) {
239 logger::raw_ln(" ----- Shamrock SMI ----- \n");
240 }
241
242 shambase::Timer timer;
243 shamcomm::mpi::Barrier(MPI_COMM_WORLD);
244 timer.start();
245
246 if (list_all_devices) {
248 } else {
249 shamrock_smi_summary();
250 }
251
252 shamrock_smi_selected(list_all_devices);
253
254 shamcomm::mpi::Barrier(MPI_COMM_WORLD);
255 timer.end();
256 if (shamcomm::world_rank() == 0) {
257 logger::info_ln(
258 "shamsys",
259 "shamrock_smi time:",
260 timer.get_time_str(),
261 "| hash based:",
262 SHAMROCK_SMI_USE_HASH ? "yes" : "no");
263 }
264 }
265
266} // namespace shamsys
Header file describing a Node Instance.
double f64
Alias for double.
std::uint32_t u32
32 bit unsigned integer
std::uint64_t u64
64 bit unsigned integer
Represents a SYCL device.
Definition Device.hpp:147
usize device_id
The id of the device.
Definition Device.hpp:152
DeviceProperties prop
Properties of the device.
Definition Device.hpp:165
Class Timer measures the time elapsed since the timer was started.
Definition time.hpp:96
std::string get_time_str() const
Converts the stored nanosecond time to a string representation.
Definition time.hpp:117
void end()
Stops the timer and stores the elapsed time in nanoseconds.
Definition time.hpp:111
void start()
Starts the timer.
Definition time.hpp:106
MPI string gather / allgather helpers (declarations; implementations in shamalgs/src/collective/gathe...
Device sycl_dev_to_sham_dev(usize i, const sycl::device &dev)
Convert a SYCL device to a shamrock backend device.
Definition Device.cpp:453
@ device
Device memory.
std::string device_type_name(DeviceType t)
Returns the name of the given device type.
Definition Device.hpp:70
void print()
Prints a log message with no arguments.
std::string readable_sizeof(double size)
given a sizeof value return a readble string Example : readable_sizeof(1024*1024*1024) -> "1....
Definition string.hpp:139
std::string trunc_str(std::string s, u32 max_len)
Truncate a string to a specified length, adding an ellipsis if necessary.
Definition string.hpp:215
void throw_with_loc(std::string message, SourceLocation loc=SourceLocation{})
Throw an exception and append the source location to it.
T & get_check_ref(const std::unique_ptr< T > &ptr, SourceLocation loc=SourceLocation())
Takes a std::unique_ptr and returns a reference to the object it holds. It throws a std::runtime_erro...
Definition memory.hpp:110
std::string getenv_str_default_register(const char *env_var, std::string default_val, std::string desc)
Get the content of the environment variable if it exist and register it documentation,...
Definition env.hpp:88
i32 world_rank()
Gives the rank of the current process in the MPI communicator.
Definition worldInfo.cpp:40
bool is_mpi_initialized()
Check if MPI is initialized.
Definition worldInfo.cpp:89
namespace for the system handling
void shamrock_smi_all()
Print SMI for all devices.
void shamrock_smi_selected(bool list_all_devices)
Print SMI for selected devices.
u32 for_each_device(std::function< void(u32, const sycl::platform &, const sycl::device &)> fct)
Iterate over all SYCL devices and perform a given function.
void shamrock_smi(bool list_all_devices)
Print information about all available SYCL devices in the cluster.
constexpr u32 u32_max
u32 max value
MPI string gather / allgather helpers (declarations; implementations in shamalgs/src/collective/gathe...
std::unordered_map< std::string, int > string_histogram(const std::vector< std::string > &inputs, std::string delimiter, bool hash_based)
Constructs a histogram from a vector of strings, counting occurrences of each unique string.
usize global_mem_size
The amount of global memory on the device in bytes.
Definition Device.hpp:101
uint64_t max_mem_alloc_size_dev
The maximum size of memory that can be allocated on the device in bytes.
Definition Device.hpp:116
uint32_t max_compute_units
The number of compute units on the device.
Definition Device.hpp:113
std::vector< std::string > warnings
Warnings emitted during property fetching.
Definition Device.hpp:134
uint32_t mem_base_addr_align
The base address alignment for memory allocations on the device in bytes.
Definition Device.hpp:122
std::optional< std::string > pci_address
PCI address of the device.
Definition Device.hpp:131
uint32_t default_work_group_size
Default work group size.
Definition Device.hpp:128
uint64_t max_mem_alloc_size_host
The maximum size of memory that can be allocated on the host in bytes.
Definition Device.hpp:119
usize local_mem_size
The amount of shared local memory on the device in bytes.
Definition Device.hpp:110
std::string name
The name of the device.
Definition Device.hpp:95
Functions related to the MPI communicator.
void Barrier(MPI_Comm comm)
MPI wrapper for MPI_Barrier.
Definition wrapper.cpp:194