libadc-cxx 1.0.0
Structured logging for scientific computing
Loading...
Searching...
No Matches
outpipe.ipp
Go to the documentation of this file.
1/* Copyright 2025 NTESS. See the top-level LICENSE.txt file for details.
2 *
3 * SPDX-License-Identifier: BSD-3-Clause
4 */
5#include <vector>
6#include <array>
7#include <iostream>
8#include <sstream>
9#include <ostream>
10#include <string>
11#include <cstdio>
12
13namespace adc {
14
15struct pipe_data {
16 std::string output;
17 int rc;
18 friend std::ostream &operator<<(std::ostream &os, const pipe_data &pdata) {
19 os << "proc rc: " << pdata.rc << " output: " << pdata.output;
20 return os;
21 }
22 bool operator==(const pipe_data &rhs) const {
23 return output == rhs.output &&
24 rc == rhs.rc;
25 }
26 bool operator!=(const pipe_data &rhs) const {
27 return !(rhs == *this);
28 }
29};
30
31class out_pipe {
32public:
33 static pipe_data run(const std::string &proc) {
34 int rc = 0;
35 std::array<char, 8192> scratch {};
36 std::string text;
37 FILE *pipe = popen(proc.c_str(), "r");
38 if (pipe == nullptr) {
39 throw std::runtime_error("popen() fails: " + proc);
40 }
41 try {
42 std::size_t inbytes;
43 while ((inbytes = std::fread(scratch.data(), sizeof(scratch.at(0)), sizeof(scratch), pipe)) != 0) {
44 text += std::string(scratch.data(), inbytes);
45 }
46 } catch (...) {
47 pclose(pipe);
48 throw;
49 }
50 int res = pclose(pipe);
51 rc = WEXITSTATUS(res);
52 return pipe_data{text, rc};
53 }
54
55};
56
57} // end adc
58
59#ifdef MAIN_out_pipe
60int main() {
61 pipe_data lscpu = out_pipe::run("lscpu -J");
62 std::cout << lscpu.rc << std::endl;
63 std::cout << lscpu.output << std::endl;
64 return 0;
65}
66#endif
67#ifdef MAIN_numactl
68#if 0
69available: 8 nodes (0-7)
70node 0 cpus: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 112 113 114 115 116 117 118 119 120 121 122 123 124 125
71node 0 size: 31699 MB
72node 0 free: 8914 MB
73node distances:
74#endif
75
76int main() {
77 static bool shell_done;
78 int numa_json = -1;
79 if (!shell_done) {
80 size_t numa_node_count = 0;
81 std::vector<std::string> sizes;
82 std::vector<std::string> cpulist;
83 shell_done = 1;
84 pipe_data numactl = out_pipe::run("numactl -H");
85 if (! numactl.rc) {
86 std::string line;
87 std::istringstream nss(numactl.output);
88 while (std::getline(nss, line)) {
89 size_t cp = line.find(':');
90 std::string name = line.substr(0, cp);
91 if (name == "available") {
92 std::istringstream iss(line.substr(cp+1));
93 iss >> numa_node_count;
94 }
95 if (name.substr(name.length()-4) == "cpus" ) {
96 cpulist.push_back(line.substr(cp+2));
97 }
98 if (name.substr(name.length()-4) == "size" ) {
99 sizes.push_back(line.substr(cp+2));
100 }
101 if (name.substr(name.length()-4) == "nces" )
102 break; // stop on "node distances:"
103 }
104 if (sizes.size() != numa_node_count || cpulist.size() != numa_node_count)
105 return numa_json; // inconsistent data
106 std::cout << numa_node_count << std::endl;
107 for (size_t i = 0; i < numa_node_count; i++) {
108 std::cout << sizes[i] <<std::endl;
109 std::cout << cpulist[i] <<std::endl;
110 }
111 }
112 }
113 return numa_json;
114}
115#endif
int main(int argc, char **argv)
static pipe_data run(const std::string &proc)
Definition outpipe.ipp:33
Definition adc.hpp:82
std::string output
Definition outpipe.ipp:16
friend std::ostream & operator<<(std::ostream &os, const pipe_data &pdata)
Definition outpipe.ipp:18
bool operator!=(const pipe_data &rhs) const
Definition outpipe.ipp:26
bool operator==(const pipe_data &rhs) const
Definition outpipe.ipp:22