diff --git a/libsrc/core/python_ngcore_export.cpp b/libsrc/core/python_ngcore_export.cpp index cf7c014f..6fee4d90 100644 --- a/libsrc/core/python_ngcore_export.cpp +++ b/libsrc/core/python_ngcore_export.cpp @@ -293,5 +293,35 @@ threads : int #endif // NETGEN_TRACE_MEMORY ; - + py::class_> (m, "Timer") + .def(py::init()) + .def("Start", static_cast::*)()const>(&Timer<>::Start), "start timer") + .def("Stop", static_cast::*)()const>(&Timer<>::Stop), "stop timer") + .def_property_readonly("time", &Timer<>::GetTime, "returns time") + .def("__enter__", static_cast::*)()const>(&Timer<>::Start)) + .def("__exit__", [](Timer<>& t, py::object, py::object, py::object) + { + t.Stop(); + }) + ; + + m.def("Timers", + []() + { + py::list timers; + for (int i = 0; i < NgProfiler::SIZE; i++) + if (!NgProfiler::timers[i].name.empty()) + { + py::dict timer; + timer["name"] = py::str(NgProfiler::timers[i].name); + timer["time"] = py::float_(NgProfiler::GetTime(i)); + timer["counts"] = py::int_(NgProfiler::GetCounts(i)); + timer["flops"] = py::float_(NgProfiler::GetFlops(i)); + timer["Gflop/s"] = py::float_(NgProfiler::GetFlops(i)/NgProfiler::GetTime(i)*1e-9); + timers.append(timer); + } + return timers; + }, "Returns list of timers" + ); + m.def("ResetTimers", &NgProfiler::Reset); } diff --git a/python/__init__.py b/python/__init__.py index 527a2ed2..ce5e3529 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -47,3 +47,14 @@ from netgen.libngpy._meshing import _Redraw def Redraw(*args, **kwargs): return _Redraw(*args, **kwargs) + +from pyngcore import Timer +def TimeFunction(func, name=None): + name = name or func.__qualname__ + timer = Timer(name) + def retfunc(*args,**kwargs): + with timer: + ret = func(*args, **kwargs) + return ret + return retfunc +