• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Open-Sn / opensn / 29474150407

15 Jul 2026 05:22PM UTC coverage: 78.598% (-0.01%) from 78.61%
29474150407

push

github

web-flow
Merge pull request #1112 from quocdang1998/scaling-script

Update scaling tests

26435 of 33633 relevant lines covered (78.6%)

82998514.42 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

33.7
/python/lib/context.cc
1
// SPDX-FileCopyrightText: 2025 The OpenSn Authors <https://open-sn.github.io/opensn/>
2
// SPDX-License-Identifier: MIT
3

4
#include "python/lib/py_wrappers.h"
5
#include "python/lib/py_env.h"
6
#include "framework/logging/log.h"
7
#include "framework/runtime.h"
8
#include "caliper/cali.h"
9
#include "petscsys.h"
10
#include <pybind11/eval.h>
11
#include <stdexcept>
12

13
namespace opensn
14
{
15

16
namespace
17
{
18

19
// Wrap Finalize
20
void
21
WrapFinalize(py::module& context)
74✔
22
{
23
  // clang-format off
24
  // finalize
25
  context.def(
74✔
26
    "Finalize",
27
    []()
74✔
28
    {
29
      PyEnv::p_default_env.reset();
×
30
    },
×
31
    R"(
32
    Finalize OpenSn context.
33

34
    This function can only be invoked **once at the end of the runtime process**.
35

36
    In standard Python module mode, the context is automatically finalized when the interpreter ends
37
    the lifecycle of variables. However, in environments like IPython within Jupyter, functions
38
    registered with `atexit` may not be executed.
39

40
    In such cases, users must explicitly call this finalize function followed by MPI Finalize to
41
    properly terminate the context; otherwise, an MPI error will occur. This process can be
42
    registered to the ``post_execute`` event of IPython console as follows:
43

44
    .. code-block::
45

46
       from IPython import get_ipython
47

48
       def finalize_env():
49
           Finalize()
50
           MPI.Finalize()
51

52
       ipython_instance = get_ipython()
53
       if ipython_instance is not None:
54
           ipython_instance.events.register("post_execute", finalize_env)
55

56
    This approach allows the module to safely execute the Python script generated by ``nbconvert``.
57
    )"
58
  );
59
  // clang-format on
60
}
74✔
61

62
// Wrap settings
63
void
64
WrapSettings(py::module& context)
74✔
65
{
66
  // clang-format off
67
  // log settings
68
  context.def(
74✔
69
    "SetVerbosityLevel",
70
    [](unsigned int level)
74✔
71
    {
72
      log.SetVerbosity(level);
×
73
    },
74
    "Set verbosity level (0 to 3). Default is 0.",
75
    py::arg("level")
74✔
76
  );
77
  context.def(
74✔
78
    "UseColor",
79
    [](bool cfg)
74✔
80
    {
81
      log.SetColorEnabled(cfg);
39✔
82
    },
83
    "Enable/disable color output. Default is True.",
84
    py::arg("config") = true
74✔
85
  );
86
  // PETSc error handler
87
  context.def(
74✔
88
    "EnablePETScErrorHandler",
89
    []()
74✔
90
    {
91
      ::PetscOptionsSetValue(nullptr, "-no_signal_handler", "false");
×
92
    },
93
    "Allow PETSc error handler."
94
  );
95
  // Caliper reporting
96
  context.def(
74✔
97
    "SetCaliperConfig",
98
    [](const std::string& config)
74✔
99
    {
100
      if (use_caliper)
×
101
      {
102
        throw std::runtime_error("This function can only be called before enabling Cailper.");
×
103
      }
104
      cali_config = config;
×
105
    },
×
106
    R"(
107
    Set configuration to the Caliper manager.
108

109
    This function can only be called before using :py:func:`pyopensn.context.EnableCaliper`. Note
110
    that this function does not start the Caliper manager immediately.
111

112
    Parameters
113
    ----------
114
    config: str, default='runtime-report(calc.inclusive=true),max_column_width=80'
115
        Configuration.
116
    )",
117
    py::arg("config") = "runtime-report(calc.inclusive=true),max_column_width=80"
74✔
118
  );
119
  context.def(
74✔
120
    "EnableCaliper",
121
    []()
74✔
122
    {
123
      // check if caliper is already initialized
124
      if (use_caliper)
×
125
      {
126
        throw std::runtime_error("Caliper is already set.");
×
127
      }
128
      use_caliper = true;
×
129
      // initialize Caliper
130
      cali_mgr.add(cali_config.c_str());
×
131
      cali_set_global_string_byname("opensn.version", GetVersionStr().c_str());
×
132
      cali_set_global_string_byname("opensn.input", input_path.c_str());
×
133
      cali_mgr.start();
×
134
    },
×
135
    R"(
136
    Start the Caliper manager and mark the program begin.
137
    )"
138
  );
139
  // clang-format on
140
}
74✔
141

142
// Wrap sys.argv translator
143
void
144
WrapSysArgv(py::module& context)
74✔
145
{
146
  // clang-format off
147
  context.def(
148✔
148
    "InitializeWithArgv",
149
    [](py::list sys_argv)
74✔
150
    {
151
      // looping over each argument of the list
152
      for (int i_arg = 0; i_arg < sys_argv.size(); ++i_arg)
×
153
      {
154
        // skip for the first argument (Python script name)
155
        if (i_arg == 0)
×
156
        {
157
          continue;
×
158
        }
159
        // cast argument to string
160
        auto arg = sys_argv[i_arg].cast<std::string>();
×
161
        // color
162
        if (arg == "-c" || arg == "--suppress-color")
×
163
        {
164
          log.SetColorEnabled(false);
×
165
          continue;
×
166
        }
167
        // verbosity
168
        if (arg == "-v" || arg == "--verbose")
×
169
        {
170
          auto next_arg = sys_argv[++i_arg].cast<std::string>();
×
171
          char* endptr = nullptr;
×
172
          const char* str_ptr = next_arg.c_str();
×
173
          auto parsed_val = std::strtol(str_ptr, &endptr, 10);
×
174
          if (endptr != str_ptr && *endptr == '\0') {
×
175
            log.SetVerbosity(static_cast<int>(parsed_val));
×
176
            continue;
×
177
          }
178
        }
×
179
        // caliper
180
        if (arg == "--caliper")
×
181
        {
182
          auto next_arg = sys_argv[++i_arg].cast<std::string>();
×
183
          use_caliper = true;
×
184
          cali_config = next_arg;
×
185
          cali_mgr.add(cali_config.c_str());
×
186
          cali_set_global_string_byname("opensn.version", GetVersionStr().c_str());
×
187
          cali_set_global_string_byname("opensn.input", input_path.c_str());
×
188
          cali_mgr.start();
×
189
          continue;
×
190
        }
×
191
        // PETSc handler
192
        if (arg == "--allow-petsc-error-handler")
×
193
        {
194
          ::PetscOptionsSetValue(nullptr, "-no_signal_handler", "false");
×
195
          continue;
×
196
        }
197
        // execute Python statement
198
        if (arg == "--py")
×
199
        {
200
          auto next_arg = sys_argv[++i_arg].cast<std::string>();
×
201
          try
×
202
          {
203
            py::exec(next_arg);
×
204
          }
205
          catch (py::error_already_set& e)
×
206
          {
207
            py::object exc_type = e.type();
×
208
            std::string type_name = py::str(exc_type.attr("__name__"));
×
209
            log.LogAllError() << "Caught an exception of type: [" << type_name
×
210
              << "] when executing code of the sys.argv.\nException message: " << e.what() << "\n";
×
211
            e.restore();
×
212
          }
×
213
          continue;
×
214
        }
×
215
        // throw error for invalid argument
216
        throw std::runtime_error("Invalid argument: " + arg + "\n");
×
217
      }
×
218
    },
×
219
    R"(
220
    Overwrite OpenSn settings using ``sys.argv``.
221

222
    This is a temporary solution for dealing with command line argument mode of the console. Once
223
    the console is gone, this functionality will also be killed.
224

225
    Parameters
226
    ----------
227
    sys_argv: List[str], default=sys.argv
228
        Argument vector to be used. Default to ``sys.argv``.
229
    )",
230
    py::arg_v("sys_argv", py::module::import("sys").attr("argv").cast<py::list>(), "sys.argv")
222✔
231
  );
232
  // clang-format on
233
}
74✔
234

235
} // namespace
236

237
// Wrap the context components of OpenSn
238
void
239
py_context(py::module& pyopensn)
74✔
240
{
241
  py::module context = pyopensn.def_submodule("context", "Context manager module.");
74✔
242
  WrapFinalize(context);
74✔
243
  WrapSettings(context);
74✔
244
  WrapSysArgv(context);
74✔
245
}
74✔
246

247
} // namespace opensn
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc