Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Viewer Problem: How to release the GPU memory while loading next scene? #1007

Open
anonymouslosty opened this issue Oct 9, 2024 · 0 comments

Comments

@anonymouslosty
Copy link

anonymouslosty commented Oct 9, 2024

I wanted to load a new area data without closing the main window.
However when i loaded a area using 2G VRAM and tried to load a new area which need 1G VRAM,I found that it would cost more than 3GB (2GB + 1GB) VRAM rather than the 1G (2GB - 2GB + 1GB) VRAM i needed.

I changed the code in function loadNewArea in GaussianView.cpp. Is there some cache i haven't realeased?
The code are below. I am wondering how to modify the code to release the GPU memory used by last scene.
Thanks for all!

void sibr::GaussianView::loadNewArea(uint _render_w, uint _render_h, const char* file, bool _white_bg, bool _useInterop) {
	if (pos_cuda) {
		cudaFree(pos_cuda);
		pos_cuda = nullptr;
	}
	if (rot_cuda) {
		cudaFree(rot_cuda);
		rot_cuda = nullptr;
	}
	if (scale_cuda) {
		cudaFree(scale_cuda);
		scale_cuda = nullptr;
	}
	if (opacity_cuda) {
		cudaFree(opacity_cuda);
		opacity_cuda = nullptr;
	}
	if (shs_cuda) {
		cudaFree(shs_cuda);
		shs_cuda = nullptr;
	}
	if (view_cuda) {
		cudaFree(view_cuda);
		view_cuda = nullptr;
	}
	if (proj_cuda) {
		cudaFree(proj_cuda);
		proj_cuda = nullptr;
	}
	if (cam_pos_cuda) {
		cudaFree(cam_pos_cuda);
		cam_pos_cuda = nullptr;
	}
	if (background_cuda) {
		cudaFree(background_cuda);
		background_cuda = nullptr;
	}
	if (rect_cuda) {
		cudaFree(rect_cuda);
		rect_cuda = nullptr;
	}

	if (!_interop_failed) {
		if (imageBufferCuda) {
			cudaGraphicsUnregisterResource(imageBufferCuda);
			imageBufferCuda = nullptr;
		}
	}
	else {
		if (fallbackBufferCuda) {
			cudaFree(fallbackBufferCuda);
			fallbackBufferCuda = nullptr;
		}
	}
	if (imageBuffer) {
		glDeleteBuffers(1, &imageBuffer);
		imageBuffer = 0;
	}

	if (_copyRenderer) {
		delete _copyRenderer;
		_copyRenderer = nullptr;
	}

	if (gData) {
		delete gData;
		gData = nullptr;
	}

	_copyRenderer = new BufferCopyRenderer();
	_copyRenderer->flip() = true;
	_copyRenderer->width() = _render_w;
	_copyRenderer->height() = _render_h;

	std::vector<Pos> pos;
	std::vector<Rot> rot;
	std::vector<Scale> scale;
	std::vector<float> opacity;
	std::vector<SHs<3>> shs;
	int sh_degree = 3;
	if (sh_degree == 0) {
		count = loadPly<0>(file, pos, shs, opacity, scale, rot, _scenemin, _scenemax);
	}
	else if (sh_degree == 1) {
		count = loadPly<1>(file, pos, shs, opacity, scale, rot, _scenemin, _scenemax);
	}
	else if (sh_degree == 2) {
		count = loadPly<2>(file, pos, shs, opacity, scale, rot, _scenemin, _scenemax);
	}
	else if (sh_degree == 3) {
		count = loadPly<3>(file, pos, shs, opacity, scale, rot, _scenemin, _scenemax);
	}

	_boxmin = _scenemin;
	_boxmax = _scenemax;

	int P = count;

	CUDA_SAFE_CALL_ALWAYS(cudaMalloc((void**)&pos_cuda, sizeof(Pos) * P));
	CUDA_SAFE_CALL_ALWAYS(cudaMemcpy(pos_cuda, pos.data(), sizeof(Pos) * P, cudaMemcpyHostToDevice));
	CUDA_SAFE_CALL_ALWAYS(cudaMalloc((void**)&rot_cuda, sizeof(Rot) * P));
	CUDA_SAFE_CALL_ALWAYS(cudaMemcpy(rot_cuda, rot.data(), sizeof(Rot) * P, cudaMemcpyHostToDevice));
	CUDA_SAFE_CALL_ALWAYS(cudaMalloc((void**)&shs_cuda, sizeof(SHs<3>) * P));
	CUDA_SAFE_CALL_ALWAYS(cudaMemcpy(shs_cuda, shs.data(), sizeof(SHs<3>) * P, cudaMemcpyHostToDevice));
	CUDA_SAFE_CALL_ALWAYS(cudaMalloc((void**)&opacity_cuda, sizeof(float) * P));
	CUDA_SAFE_CALL_ALWAYS(cudaMemcpy(opacity_cuda, opacity.data(), sizeof(float) * P, cudaMemcpyHostToDevice));
	CUDA_SAFE_CALL_ALWAYS(cudaMalloc((void**)&scale_cuda, sizeof(Scale) * P));
	CUDA_SAFE_CALL_ALWAYS(cudaMemcpy(scale_cuda, scale.data(), sizeof(Scale) * P, cudaMemcpyHostToDevice));

	CUDA_SAFE_CALL_ALWAYS(cudaMalloc((void**)&view_cuda, sizeof(sibr::Matrix4f)));
	CUDA_SAFE_CALL_ALWAYS(cudaMalloc((void**)&proj_cuda, sizeof(sibr::Matrix4f)));
	CUDA_SAFE_CALL_ALWAYS(cudaMalloc((void**)&cam_pos_cuda, 3 * sizeof(float)));
	CUDA_SAFE_CALL_ALWAYS(cudaMalloc((void**)&background_cuda, 3 * sizeof(float)));
	CUDA_SAFE_CALL_ALWAYS(cudaMalloc((void**)&rect_cuda, 2 * P * sizeof(int)));

	float bg[3] = { _white_bg ? 1.f : 0.f, _white_bg ? 1.f : 0.f, _white_bg ? 1.f : 0.f };
	CUDA_SAFE_CALL_ALWAYS(cudaMemcpy(background_cuda, bg, 3 * sizeof(float), cudaMemcpyHostToDevice));

	gData = new GaussianData(P,
		(float*)pos.data(),
		(float*)rot.data(),
		(float*)scale.data(),
		opacity.data(),
		(float*)shs.data());

	_gaussianRenderer = new GaussianSurfaceRenderer();

	glCreateBuffers(1, &imageBuffer);
	glNamedBufferStorage(imageBuffer, _render_w * _render_h * 3 * sizeof(float), nullptr, GL_DYNAMIC_STORAGE_BIT);

	if (_useInterop) {
		if (cudaPeekAtLastError() != cudaSuccess) {
			SIBR_ERR << "" << cudaGetErrorString(cudaGetLastError()) << "";
		}
		cudaGraphicsGLRegisterBuffer(&imageBufferCuda, imageBuffer, cudaGraphicsRegisterFlagsWriteDiscard);
		_useInterop &= (cudaGetLastError() == cudaSuccess);
	}
	if (!_useInterop) {
		fallback_bytes.resize(_render_w * _render_h * 3 * sizeof(float));
		cudaMalloc(&fallbackBufferCuda, fallback_bytes.size());
		_interop_failed = true;
	}

	geomBufferFunc = resizeFunctional(&geomPtr, allocdGeom);
	binningBufferFunc = resizeFunctional(&binningPtr, allocdBinning);
	imgBufferFunc = resizeFunctional(&imgPtr, allocdImg);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant