Skip to content

Commit

Permalink
[opengl] Reset opengl context when taichi program resets (#6987)
Browse files Browse the repository at this point in the history
  • Loading branch information
ailzhang authored Dec 27, 2022
1 parent fc6931f commit 5914971
Show file tree
Hide file tree
Showing 8 changed files with 35 additions and 22 deletions.
2 changes: 2 additions & 0 deletions taichi/program/program.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,8 @@ void Program::finalize() {
finalized_ = true;
num_instances_ -= 1;
program_impl_->dump_cache_data_to_disk();
configs.clear();
configs[main_thread_id_] = default_compile_config;
TI_TRACE("Program ({}) finalized_.", fmt::ptr(this));
}

Expand Down
4 changes: 4 additions & 0 deletions taichi/program/program.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,10 @@ class TI_DLL_EXPORT Program {
return configs[thread_id];
}

const CompileConfig &config() {
return configs[main_thread_id_];
}

struct KernelProfilerQueryResult {
int counter{0};
double min{0.0};
Expand Down
3 changes: 1 addition & 2 deletions taichi/python/export_lang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -329,8 +329,7 @@ void export_lang(py::module &m) {

py::class_<Program>(m, "Program")
.def(py::init<>())
.def("config", &Program::this_thread_config,
py::return_value_policy::reference)
.def("config", &Program::config)
.def("sync_kernel_profiler",
[](Program *program) { program->profiler->sync(); })
.def("update_kernel_profiler",
Expand Down
9 changes: 7 additions & 2 deletions taichi/rhi/opengl/opengl_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,13 @@ int opengl_max_grid_dim = 1024;
// TODO: Properly support setting GLES/GLSL in opengl backend
// without this global static boolean.
static bool kUseGles = false;
static std::optional<bool> supported; // std::nullopt

static void glfw_error_callback(int code, const char *description) {
TI_WARN("GLFW Error {}: {}", code, description);
}

bool initialize_opengl(bool use_gles, bool error_tolerance) {
static std::optional<bool> supported; // std::nullopt

TI_TRACE("initialize_opengl({}, {}) called", use_gles, error_tolerance);

if (supported.has_value()) { // this function has been called before
Expand Down Expand Up @@ -205,6 +204,12 @@ bool is_gles() {
return kUseGles;
}

void reset_opengl() {
supported = std::nullopt;
kUseGles = false;
glfwTerminate();
}

std::shared_ptr<Device> make_opengl_device() {
std::shared_ptr<Device> dev = std::make_shared<GLDevice>();
return dev;
Expand Down
1 change: 1 addition & 0 deletions taichi/rhi/opengl/opengl_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ namespace opengl {
bool initialize_opengl(bool use_gles = false, bool error_tolerance = false);
bool is_opengl_api_available(bool use_gles = false);
bool is_gles();
void reset_opengl();

std::shared_ptr<Device> make_opengl_device();

Expand Down
24 changes: 6 additions & 18 deletions taichi/rhi/opengl/opengl_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -597,26 +597,14 @@ RhiResult GLDevice::map_range(DevicePtr ptr, uint64_t size, void **mapped_ptr) {
}

RhiResult GLDevice::map(DeviceAllocation alloc, void **mapped_ptr) {
TI_ASSERT_INFO(
buffer_to_access_.find(alloc.alloc_id) != buffer_to_access_.end(),
"Buffer not created with host_read or write");
glBindBuffer(GL_SHADER_STORAGE_BUFFER, alloc.alloc_id);
check_opengl_error("glBindBuffer");
// This is pure stupidity.
// Why does `glMapBuffer` and `glMapBufferRange` uses two TOTALLY different
// enums? Whoever came up with the API is DRUNK!
GLbitfield access = buffer_to_access_.at(alloc.alloc_id);
GLenum access_oldapi;
if (bool(access & GL_MAP_READ_BIT) && bool(access & GL_MAP_WRITE_BIT)) {
access_oldapi = GL_READ_WRITE;
} else if (access & GL_MAP_WRITE_BIT) {
access_oldapi = GL_WRITE_ONLY;
} else {
access_oldapi = GL_READ_ONLY;
}
*mapped_ptr = glMapBuffer(GL_SHADER_STORAGE_BUFFER, access_oldapi);
check_opengl_error("glMapBuffer");
return RhiResult::success;

int size = 0;
glGetBufferParameteriv(GL_SHADER_STORAGE_BUFFER, GL_BUFFER_SIZE, &size);
check_opengl_error("glGetBufferParameteriv");

return map_range(alloc.get_ptr(0), size, mapped_ptr);
}

void GLDevice::unmap(DevicePtr ptr) {
Expand Down
10 changes: 10 additions & 0 deletions taichi/runtime/program_impls/opengl/opengl_program.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,16 @@ void OpenglProgramImpl::dump_cache_data_to_disk() {
mgr->dump_with_merging();
}

void OpenglProgramImpl::finalize() {
runtime_.reset();
device_.reset();
opengl::reset_opengl();
}

OpenglProgramImpl::~OpenglProgramImpl() {
finalize();
}

const std::unique_ptr<gfx::CacheManager>
&OpenglProgramImpl::get_cache_manager() {
if (!cache_manager_) {
Expand Down
4 changes: 4 additions & 0 deletions taichi/runtime/program_impls/opengl/opengl_program.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ namespace taichi::lang {
class OpenglProgramImpl : public ProgramImpl {
public:
explicit OpenglProgramImpl(CompileConfig &config);
~OpenglProgramImpl() override;

FunctionType compile(Kernel *kernel, OffloadedStmt *offloaded) override;

std::size_t get_snode_num_dynamically_allocated(
Expand All @@ -30,6 +32,8 @@ class OpenglProgramImpl : public ProgramImpl {
runtime_->synchronize();
}

void finalize() override;

StreamSemaphore flush() override {
return runtime_->flush();
}
Expand Down

0 comments on commit 5914971

Please sign in to comment.