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

Volume rendering for octrees #2610

Merged
merged 68 commits into from
Sep 15, 2020

Conversation

cphyc
Copy link
Member

@cphyc cphyc commented May 27, 2020

This PR adds support for doing volume rendering for octree-based datasets (e.g. RAMSES). It is built on top of #2425 to provide vertex-centred data (not yet wired though).

It follows the same idea as #2442, but relying instead with an independent octree ray tracer. This has the advantage of making the code much simpler, but generates a bit of code repetition and requires rebuilding an octree.

Currently, it supports the yt API for volume rendering.

Features

  • support vertex centered data for trilinear interpolation
  • wire with yt volume rendering API
  • can handle any geometry, takes care of CPU domains nicely
  • handle different AMR levels
  • handle "holes" in the dataset (this means you can use an arbitrary data source for the volume renderer)
  • Deallocate properly all the stuff (i.e. find the origin of the memory leak)
  • Possible to improve "aliasing" effect? See image of galaxy in next post.
  • Merge Octree ghost zones — reloaded #2425 before merging this one.

Demo

import yt
ds = yt.load_sample('output_00080', 'info_00080.txt')
sp = ds.all_data()
sc = yt.create_scene(sp, lens_type='perspective')
source = sc[0]

source.tfh.set_bounds((3e-31, 5e-27))
source.tfh.grey_opacity = True
source.tfh.plot('transfer_function.png', profile_field='density')

sc.save('rendering.png', sigma_clip=4)

rendering

Notes on performance

The entire script above takes about 20s to run from end to end. Casting the rays and integrating the transfer function actually only takes 4s on 8 cores (with hyperthreading), 5s on 4 cores and 16s on a single core. The dataset consists of 1,749,455 cells.

@cphyc cphyc mentioned this pull request May 27, 2020
5 tasks
@cphyc cphyc changed the title [WIP] Octree raytracing Volume rendering for octress May 28, 2020
@cphyc
Copy link
Member Author

cphyc commented May 28, 2020

After quite a long time working on this, I think this should be ready for review! There's probably ways to make all this cleaner, so don't hesitate!

It is also probably still missing some tests, @matthewturk any suggestion regarding the way to go? Duplicate all 3d rendering tests already happening with grid-based datasets?

@cphyc cphyc added code frontends Things related to specific frontends new feature Something fun and new! viz: volume rendering labels May 28, 2020
@cphyc
Copy link
Member Author

cphyc commented May 28, 2020

There seems to be a compilation issue caused with an older version of gcc used on jenkins. Any guess how to solve this?

Copy link
Member

@neutrinoceros neutrinoceros left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't have time for a full review, I stopped at 8/40 files. I only have a handful of minor suggestions for those, this seems very well written as usual :)

yt/frontends/ramses/io_utils.pyx Outdated Show resolved Hide resolved
yt/fields/geometric_fields.py Outdated Show resolved Hide resolved
yt/frontends/ramses/data_structures.py Outdated Show resolved Hide resolved
yt/frontends/ramses/data_structures.py Outdated Show resolved Hide resolved
yt/frontends/ramses/data_structures.py Outdated Show resolved Hide resolved
@cphyc cphyc changed the title Volume rendering for octress Volume rendering for octrees May 28, 2020
@cphyc
Copy link
Member Author

cphyc commented May 29, 2020

I made some high-res images of a high-resolution galaxy (dx ~ 30pc). It turns out that I had some Fortran/C ordering issues (now fixed in be79cb0) which significantly improves the quality of the image (see images before (top) and after (bottom) the fix).

rendering_sigma_2
rendering_sigma_2

We can still some grid effects, but they seem "normal" to me.

Performances

Parallelized over 40 cores, each image takes about ~3s to generate (for a resolution of 1024x1024).

Eye-candy

Here's some eye-candy. This shows a galaxy at z=2, with resolution 30pc. Took 10min to render (200frames, 3,168,583 cells).
out

@cphyc cphyc added the yt-4.0 feature targeted for the yt-4.0 release label Jun 11, 2020
@cphyc cphyc marked this pull request as draft June 17, 2020 15:52
@cphyc
Copy link
Member Author

cphyc commented Jun 17, 2020

Converted this to draft because we first need to merge #2425!

@cphyc cphyc changed the base branch from yt-4.0 to master June 22, 2020 17:24
@cphyc cphyc force-pushed the indep-octree-raytracing branch 2 times, most recently from 7a39833 to 1817b1b Compare July 2, 2020 19:44
@cphyc cphyc force-pushed the indep-octree-raytracing branch from 47b367a to 06b8faf Compare July 20, 2020 09:49
@cphyc cphyc marked this pull request as ready for review July 20, 2020 09:49
@cphyc
Copy link
Member Author

cphyc commented Jul 20, 2020

There's a massive performance hit that will be resolved by 24a7343 (from #2735). Otherwise I guess it's good to go!

Copy link
Member

@neutrinoceros neutrinoceros left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can not honestly pretend I read and reviewed the core cpp part, but for the parts I did read, here are my suggestions. Great stuff as always :)

yt/utilities/lib/image_samplers.pyx Outdated Show resolved Hide resolved
yt/data_objects/octree_subset.py Outdated Show resolved Hide resolved
yt/frontends/ramses/data_structures.py Outdated Show resolved Hide resolved
RE = np.array([1, 1, 1], dtype=np.float64)
depth = data_source.ds.parameters["levelmax"]

self.octree = CythonOctreeRayTracing(LE, RE, depth)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tbh I find the naming of those classes a bit odd. CythonOctreeRayTracing sounds like the Cython version of OctreeRayTracing, not of a component of the class. But maybe I just don't understand enough of this, it could be absolutely fine.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is very odd. We should discuss better options. @matthewturk @munkm what's your opinion? The issue is that my implementation is multi-layered, there's a C++ implementation that's wrapped in a cython file that's wrapped in a python file... So we could probably get rid of most of these layers, but which ones?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed the naming so that the python file is named octree_raytracing.py, the cython wrapper is _octree_raytracing.p{xd,yx} and the C++ file is _octree_raytracing.hpp.

ds = data_source.ds

xyz = np.stack(
[data_source[_].to("unitary").value for _ in "x y z".split()], axis=-1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
[data_source[_].to("unitary").value for _ in "x y z".split()], axis=-1
[data_source[key].to("unitary").value for key in "xyz"], axis=-1

@@ -67,6 +71,10 @@ cdef class ImageSampler:
*args, **kwargs):
cdef int i

self.volume_method = kwargs.pop('volume_method', None)
if self.volume_method and self.volume_method not in ('KDTree', 'Octree'):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if self.volume_method and self.volume_method not in ('KDTree', 'Octree'):
if self.volume_method not in ('KDTree', 'Octree'):

yt/utilities/lib/image_samplers.pyx Show resolved Hide resolved
ds = data.ds

xyz = np.stack(
[data[_].to("unitary").value for _ in "x y z".split()], axis=-1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
[data[_].to("unitary").value for _ in "x y z".split()], axis=-1
[data[key].to("unitary").value for key in "xyz"], axis=-1

return image
self.zbuffer = zbuffer
self.set_sampler(camera)
assert self.sampler is not None
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
assert self.sampler is not None
if self.sampler is None:
raise RuntimeError(message...)

@cphyc
Copy link
Member Author

cphyc commented Aug 3, 2020

The failing tests are real; I'll have to dig into it.

@cphyc
Copy link
Member Author

cphyc commented Aug 3, 2020

/rebase

@matthewturk
Copy link
Member

matthewturk commented Aug 3, 2020

/rebase

Pull request is not rebaseable

cphyc added a commit to cphyc/yt that referenced this pull request Aug 10, 2020
cphyc added a commit to cphyc/yt that referenced this pull request Aug 12, 2020
@cphyc cphyc marked this pull request as draft August 12, 2020 08:57
This reverts commit c768d9d for off_axis_projection.py
@cphyc cphyc marked this pull request as ready for review August 30, 2020 09:06
setup.py Outdated Show resolved Hide resolved
Call function

Only support Ndim=3

Drop usage of "using" and rely on typedef instead

Use uint8_t instead of u_char

Fix platform in appveyor

Using uint64_t instead of uint
@cphyc cphyc force-pushed the indep-octree-raytracing branch from f8dc942 to 748e7ef Compare August 30, 2020 17:34
@cphyc
Copy link
Member Author

cphyc commented Aug 31, 2020

This is now ready to go!

@cphyc cphyc requested review from matthewturk and munkm and removed request for matthewturk and munkm August 31, 2020 09:02
Copy link
Member

@matthewturk matthewturk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should do it. One slight reservation is that we're changing the appveyor image,b ut that's not necessarily a big deal.

@cphyc
Copy link
Member Author

cphyc commented Sep 9, 2020

I think we should do it. One slight reservation is that we're changing the appveyor image, but that's not necessarily a big deal.

I am actually unsure this is still necessary. Let me try using the old one.

@cphyc
Copy link
Member Author

cphyc commented Sep 9, 2020

I think we should do it. One slight reservation is that we're changing the appveyor image,b ut that's not necessarily a big deal.

I reverted the change of the appveyor image, as it was not necessary anymore!

@neutrinoceros
Copy link
Member

@yt-fido test this please

@neutrinoceros neutrinoceros merged commit 987ef35 into yt-project:master Sep 15, 2020
@cphyc cphyc deleted the indep-octree-raytracing branch September 15, 2020 07:51
This was referenced Oct 8, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
code frontends Things related to specific frontends new feature Something fun and new! viz: volume rendering yt-4.0 feature targeted for the yt-4.0 release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants