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 |
45 | namespace taichi::lang::cccp { |
46 | extern bool is_c_backend_available(); |
47 | } |
48 | #endif |
49 | |
50 | namespace taichi { |
51 | |
52 | void test_raise_error() { |
53 | raise_assertion_failure_in_python("Just a test." ); |
54 | } |
55 | |
56 | void 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 | |
77 | void 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 | |