1/*******************************************************************************
2 Copyright (c) The Taichi Authors (2016- ). All Rights Reserved.
3 The use of this software is governed by the LICENSE file.
4*******************************************************************************/
5
6#include "taichi/rhi/metal/metal_api.h"
7#include "taichi/runtime/gfx/runtime.h"
8#include "taichi/rhi/dx/dx_api.h"
9#include "taichi/common/core.h"
10#include "taichi/common/interface.h"
11#include "taichi/common/task.h"
12#include "taichi/math/math.h"
13#include "taichi/platform/cuda/detect_cuda.h"
14#include "taichi/program/py_print_buffer.h"
15#include "taichi/python/exception.h"
16#include "taichi/python/export.h"
17#include "taichi/python/memory_usage_monitor.h"
18#include "taichi/system/benchmark.h"
19#include "taichi/system/dynamic_loader.h"
20#include "taichi/system/hacked_signal_handler.h"
21#include "taichi/system/profiler.h"
22#include "taichi/util/offline_cache.h"
23#if defined(TI_WITH_CUDA)
24#include "taichi/rhi/cuda/cuda_driver.h"
25#endif
26
27#include "taichi/platform/amdgpu/detect_amdgpu.h"
28#if defined(TI_WITH_AMDGPU)
29#include "taichi/rhi/amdgpu/amdgpu_driver.h"
30#endif
31
32#ifdef TI_WITH_VULKAN
33#include "taichi/rhi/vulkan/vulkan_loader.h"
34#endif
35
36#ifdef TI_WITH_OPENGL
37#include "taichi/rhi/opengl/opengl_api.h"
38#endif
39
40#ifdef TI_WITH_DX12
41#include "taichi/rhi/dx12/dx12_api.h"
42#endif
43
44#ifdef TI_WITH_CC
45namespace taichi::lang::cccp {
46extern bool is_c_backend_available();
47}
48#endif
49
50namespace taichi {
51
52void test_raise_error() {
53 raise_assertion_failure_in_python("Just a test.");
54}
55
56void print_all_units() {
57 std::vector<std::string> names;
58 auto interfaces = InterfaceHolder::get_instance()->interfaces;
59 for (auto &kv : interfaces) {
60 names.push_back(kv.first);
61 }
62 std::sort(names.begin(), names.end());
63 int all_units = 0;
64 for (auto &interface_name : names) {
65 auto impls = interfaces[interface_name]->get_implementation_names();
66 std::cout << " * " << interface_name << " [" << int(impls.size()) << "]"
67 << std::endl;
68 all_units += int(impls.size());
69 std::sort(impls.begin(), impls.end());
70 for (auto &impl : impls) {
71 std::cout << " + " << impl << std::endl;
72 }
73 }
74 std::cout << all_units << " units in all." << std::endl;
75}
76
77void export_misc(py::module &m) {
78 py::class_<Config>(m, "Config"); // NOLINT(bugprone-unused-raii)
79 py::register_exception_translator([](std::exception_ptr p) {
80 try {
81 if (p)
82 std::rethrow_exception(p);
83 } catch (const ExceptionForPython &e) {
84 PyErr_SetString(PyExc_RuntimeError, e.what());
85 }
86 });
87
88 py::class_<Task, std::shared_ptr<Task>>(m, "Task")
89 .def("initialize", &Task::initialize)
90 .def("run",
91 static_cast<std::string (Task::*)(const std::vector<std::string> &)>(
92 &Task::run));
93
94 py::class_<Benchmark, std::shared_ptr<Benchmark>>(m, "Benchmark")
95 .def("run", &Benchmark::run)
96 .def("test", &Benchmark::test)
97 .def("initialize", &Benchmark::initialize);
98
99#define TI_EXPORT_LOGGING(X) \
100 m.def(#X, [](const std::string &msg) { \
101 taichi::Logger::get_instance().X(msg); \
102 });
103
104 m.def("flush_log", []() { taichi::Logger::get_instance().flush(); });
105
106 TI_EXPORT_LOGGING(trace);
107 TI_EXPORT_LOGGING(debug);
108 TI_EXPORT_LOGGING(info);
109 TI_EXPORT_LOGGING(warn);
110 TI_EXPORT_LOGGING(error);
111 TI_EXPORT_LOGGING(critical);
112
113 m.def("print_all_units", print_all_units);
114 m.def("set_core_state_python_imported", CoreState::set_python_imported);
115 m.def("set_logging_level", [](const std::string &level) {
116 Logger::get_instance().set_level(level);
117 });
118 m.def("logging_effective", [](const std::string &level) {
119 return Logger::get_instance().is_level_effective(level);
120 });
121 m.def("set_logging_level_default",
122 []() { Logger::get_instance().set_level_default(); });
123 m.def("set_core_trigger_gdb_when_crash",
124 CoreState::set_trigger_gdb_when_crash);
125 m.def("test_raise_error", test_raise_error);
126 m.def("get_default_float_size", []() { return sizeof(real); });
127 m.def("trigger_sig_fpe", []() {
128 int a = 2;
129 a -= 2;
130 return 1 / a;
131 });
132 m.def("print_profile_info",
133 [&]() { Profiling::get_instance().print_profile_info(); });
134 m.def("clear_profile_info",
135 [&]() { Profiling::get_instance().clear_profile_info(); });
136 m.def("start_memory_monitoring", start_memory_monitoring);
137 m.def("get_repo_dir", get_repo_dir);
138 m.def("get_python_package_dir", get_python_package_dir);
139 m.def("set_python_package_dir", set_python_package_dir);
140 m.def("cuda_version", get_cuda_version_string);
141 m.def("test_cpp_exception", [] {
142 try {
143 throw std::exception();
144 } catch (const std::exception &e) {
145 printf("caught.\n");
146 }
147 printf("test was successful.\n");
148 });
149 m.def("pop_python_print_buffer", []() { return py_cout.pop_content(); });
150 m.def("toggle_python_print_buffer", [](bool opt) { py_cout.enabled = opt; });
151 m.def("with_cuda", is_cuda_api_available);
152 m.def("with_amdgpu", is_rocm_api_available);
153#ifdef TI_WITH_METAL
154 m.def("with_metal", taichi::lang::metal::is_metal_api_available);
155#else
156 m.def("with_metal", []() { return false; });
157#endif
158#ifdef TI_WITH_OPENGL
159 m.def("with_opengl", taichi::lang::opengl::is_opengl_api_available,
160 py::arg("use_gles") = false);
161#else
162 m.def("with_opengl", [](bool use_gles) { return false; });
163#endif
164#ifdef TI_WITH_VULKAN
165 m.def("with_vulkan", taichi::lang::vulkan::is_vulkan_api_available);
166 m.def("set_vulkan_visible_device",
167 taichi::lang::vulkan::set_vulkan_visible_device);
168#else
169 m.def("with_vulkan", []() { return false; });
170#endif
171#ifdef TI_WITH_DX11
172 m.def("with_dx11", taichi::lang::directx11::is_dx_api_available);
173#else
174 m.def("with_dx11", []() { return false; });
175#endif
176#ifdef TI_WITH_DX12
177 m.def("with_dx12", taichi::lang::directx12::is_dx12_api_available);
178#else
179 m.def("with_dx12", []() { return false; });
180#endif
181
182#ifdef TI_WITH_CC
183 m.def("with_cc", taichi::lang::cccp::is_c_backend_available);
184#else
185 m.def("with_cc", []() { return false; });
186#endif
187
188 m.def("clean_offline_cache_files",
189 lang::offline_cache::clean_offline_cache_files);
190
191 py::class_<HackedSignalRegister>(m, "HackedSignalRegister").def(py::init<>());
192}
193
194} // namespace taichi
195