Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
texTestReport.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/string.hpp"
17#include "shambackends/sycl.hpp"
18#include "shamrock/version.hpp"
21#include "texTestReport.hpp"
22#include <algorithm>
23#include <sstream>
24#include <string>
25#include <vector>
26
27// start allow utf-8
28
30std::string tex_template = R"==(
31
32\documentclass[10pt]{article}
33
34\usepackage[a4paper,total={170mm,260mm},left=20mm,top=20mm,]{geometry}
35
36
37\usepackage{fancyhdr} % entêtes et pieds de pages personnalisés
38
39\pagestyle{fancy}
40\fancyhead[L]{\scriptsize \textsc{Test suite report}} % À changer
41\fancyhead[R]{\scriptsize \textsc{\textsc{SHAMROCK}}} % À changer
42\fancyfoot[C]{ \thepage}
43
44
45\usepackage{titling}
46
47\setlength{\droptitle}{-4\baselineskip} % Move the title up
48
49\pretitle{\begin{center}\Huge\bfseries} % Article title formatting
50\posttitle{\end{center}} % Article title closing formatting
51\title{\textsc{SHAMROCK} test suite report} % Article title
52\author{%
53\textsc{Timothée David--Cléris}\thanks{timothee.david--cleris@ens-lyon.fr} \\[1ex] % Your name
54\normalsize CRAL ENS de Lyon \\ % Your institution
55}
56\date{\today}
57
58\usepackage{xcolor}
59\definecolor{linkcolor}{rgb}{0,0,0.6}
60
61\usepackage{graphicx}
62\usepackage{cprotect}
63
64\usepackage[ pdftex,colorlinks=true,
65pdfstartview=ajustementV,
66linkcolor= linkcolor,
67citecolor= linkcolor,
68urlcolor= linkcolor,
69hyperindex=true,
70hyperfigures=false]
71{hyperref}
72
73
74
75\usepackage{color}
76
77
78\definecolor{GREEN}{rgb}{0,.7,0}
79\definecolor{RED}{rgb}{.8,0,0}
80
81
82\def\OK{\textcolor{GREEN}{OK}}
83\def\FAIL{\textcolor{RED}{FAIL}}
84
85\begin{document}
86\maketitle
87
88
89
90)==";
91// end allow utf-8
92
94std::string tex_template_end = R"(
95 \end{document}
96)";
97
98namespace shamtest::details {
99
101 void add_unittest_section(std::stringstream &output, std::vector<TestResult> &results) {
102
103 output << R"(\section{Unittests})"
104 << "\n\n";
105
106 using namespace details;
107
108 std::unordered_map<std::string, u32> assert_test_count;
109 std::unordered_map<std::string, u32> assert_test_count_success;
110
111 for (TestResult &res : results) {
112 if (res.type == Unittest) {
113 assert_test_count[res.name] = 0;
114 }
115 }
116
117 for (TestResult &res : results) {
118 if (res.type == Unittest) {
119 assert_test_count[res.name] += res.asserts.get_assert_count();
120 assert_test_count_success[res.name] += res.asserts.get_assert_success_count();
121 }
122 }
123
124 std::vector<std::string> strings;
125 for (auto &[key, value] : assert_test_count) {
126 strings.push_back(key);
127 }
128 std::sort(strings.begin(), strings.end());
129
130 std::string table_header = R"==(
131 \begin{center}
132 \begin{tabular}{|l|c|c|}
133 \hline
134 Test name & Status & Asserts \\ \hline \hline
135 )==";
136
137 std::string table_footer = R"==(
138 \hline
139 \end{tabular}\end{center}
140 )==";
141
142 output << table_header;
143
144 u32 table_cnt = 0;
145 for (std::string key : strings) {
146 u32 cnt = assert_test_count[key];
147 u32 cnt_suc = assert_test_count_success[key];
148
149 if (table_cnt > 50) {
150 output << table_footer << "\n\n" << table_header;
151 table_cnt = 0;
152 }
153
154 output << R"(\verb|)" << shambase::trunc_str_start(key, 64) << "| & ";
155
156 if (cnt == cnt_suc) {
157 output << R"(\OK & )";
158 } else {
159 output << R"(\FAIL & )";
160 }
161
162 output << shambase::format(R"({}/{} \\)", cnt_suc, cnt);
163 output << "\n";
164
165 table_cnt++;
166 }
167
168 output << table_footer;
169
170 output << "\n";
171
172 for (TestResult &res : results) {
173 if (res.asserts.get_assert_success_count() != res.asserts.get_assert_count()) {
174 output << "Test : " << res.name << "\n\n";
175
176 for (unsigned int j = 0; j < res.asserts.asserts.size(); j++) {
177
178 output << shambase::format_printf(
179 " - Assert [%d/%zu] \n\n", j + 1, res.asserts.asserts.size());
180
181 output << R"(\verb|)" << res.asserts.asserts[j].name << "| : ";
182
183 if (res.asserts.asserts[j].value) {
184 output << R"(\OK)";
185 } else {
186 output << R"(\FAIL)";
187 }
188
189 if ((!res.asserts.asserts[j].value)
190 && !res.asserts.asserts[j].comment.empty()) {
191 output << "\n\n $\\rightarrow$ failed assert logs :\n\n";
192 output << R"(\begin{verbatim})" << res.asserts.asserts[j].comment
193 << R"(\end{verbatim})";
194 output << "\n";
195 }
196
197 output << "\n\n";
198 }
199 }
200 }
201 }
202
204 void add_tex_output_section(std::stringstream &output, std::vector<TestResult> &results) {
205
206 output << R"(\section{Tex report})";
207
208 for (TestResult &res : results) {
209 std::string &tex_out = res.tex_output;
210
211 if (!tex_out.empty()) {
212
213 output << R"==(
214 \cprotect\subsection{ \verb+)=="
215 + res.name + R"==(+}
216 )==";
217
218 output << tex_out;
219 }
220 }
221 }
222
224 void add_queue_section(std::stringstream &output, sycl::queue &q) {
225
226 sycl::device d = q.get_device();
227 output << "device name : " << d.get_info<sycl::info::device::name>() << "\n";
228 output << "platform name : " << d.get_platform().get_info<sycl::info::platform::name>()
229 << "\n";
230 output << "device property : \n";
231 output << "global_mem_size : "
232 << shambase::readable_sizeof(d.get_info<sycl::info::device::global_mem_size>())
233 << "\n";
234 output << "global_mem_cache_size : "
235 << shambase::readable_sizeof(d.get_info<sycl::info::device::global_mem_cache_size>())
236 << "\n";
237 output << "global_mem_cache_line_size : "
239 d.get_info<sycl::info::device::global_mem_cache_line_size>())
240 << "\n";
241 output << "local_mem_size : "
242 << shambase::readable_sizeof(d.get_info<sycl::info::device::local_mem_size>())
243 << "\n";
244 output << "is_endian_little : " << d.get_info<sycl::info::device::is_endian_little>()
245 << "\n";
246 }
247
249 void add_config_section(std::stringstream &output) {
250
251 std::string cxxflags = compile_arg;
252 shambase::replace_all(cxxflags, " ", "\n");
253
254 output << R"(\section{Shamrock config})";
255 output << "\n\n";
256 output << R"(\subsection{Git info})"
257 << "\n";
258 output << R"(\begin{verbatim})"
259 << "\n";
260 output << git_info_str;
261 output << R"(\end{verbatim})"
262 << "\n";
263 output << R"(\subsection{c++ flags})"
264 << "\n";
265 output << R"(\begin{verbatim})"
266 << "\n";
267 output << cxxflags;
268 output << R"(\end{verbatim})"
269 << "\n";
270
271 output << R"(\subsection{MPI status})"
272 << "\n";
273 output << R"(\begin{verbatim})"
274 << "\n";
275 output << "world size = " << shamcomm::world_size();
276 output << R"(\end{verbatim})"
277 << "\n";
278
279 output << R"(\subsection{NodeInstance Status})"
280 << "\n";
281 output << "compute queue : "
282 << "\n";
283 output << R"(\begin{verbatim})"
284 << "\n";
285 add_queue_section(output, shamsys::instance::get_compute_queue());
286 output << R"(\end{verbatim})"
287 << "\n";
288 output << "alt queue : "
289 << "\n";
290 output << R"(\begin{verbatim})"
291 << "\n";
292 add_queue_section(output, shamsys::instance::get_alt_queue());
293 output << R"(\end{verbatim})"
294 << "\n";
295
296 output << "\n\n";
297 }
298
300 std::string make_test_report_tex(std::vector<TestResult> &results, bool mark_fail) {
301
302 std::stringstream output;
303
304 output << tex_template;
305
306 output << "Global status : ";
307
308 if (mark_fail) {
309 output << R"(\FAIL)";
310 } else {
311 output << R"(\OK)";
312 }
313
314 output << "\n\n";
315 output << R"(\tableofcontents)";
316 output << "\n\n";
317
318 add_config_section(output);
319
320 add_unittest_section(output, results);
321
322 add_tex_output_section(output, results);
323
324 output << tex_template_end;
325
326 return output.str();
327 }
328} // namespace shamtest::details
Header file describing a Node Instance.
header describing return type of a test, and the type of the test
std::uint32_t u32
32 bit unsigned integer
Namespace for internal details of the logs module.
std::string trunc_str_start(std::string s, u32 max_len)
Truncate a string to a specified length, adding an ellipsis at the start if necessary.
Definition string.hpp:239
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
void replace_all(std::string &inout, std::string_view what, std::string_view with)
replace all occurence of a search string with another
Definition string.hpp:183
void throw_with_loc(std::string message, SourceLocation loc=SourceLocation{})
Throw an exception and append the source location to it.
i32 world_size()
Gives the size of the MPI communicator.
Definition worldInfo.cpp:38
implementation details of the test library
Definition DataNode.hpp:23
void add_tex_output_section(std::stringstream &output, std::vector< TestResult > &results)
Add tex outputs from the tests to the report.
void add_config_section(std::stringstream &output)
Document details about the Shamrock status in the report.
void add_queue_section(std::stringstream &output, sycl::queue &q)
Document details about the SYCL queues status in the report.
void add_unittest_section(std::stringstream &output, std::vector< TestResult > &results)
Add the unittest section to the Tex report.
std::string make_test_report_tex(std::vector< TestResult > &results, bool mark_fail)
Make the tex report.
std::string tex_template_end
Footer of the document.
std::string tex_template
Tex report template to be used.
typedefs and macros