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

Use variant-specific registry domains #1362

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

merlinND
Copy link
Member

@merlinND merlinND commented Oct 25, 2024

Description

Previously, we could easily segfault when performing a vcall if an object was previously created with another variant. For example, a spectral_polarized BSDF and an rgb BSDF.

Other than fixing the case below, I don't think this change could hurt since we never need or want instances from different variants to participate in the same vcalls (?).

Testing

import drjit as dr
import mitsuba as mi

def test01_test_variants_switching():
    mi.set_variant('cuda_ad_mono_polarized')
    # Unused, but registers objects into the registry
    scene1 = mi.load_dict(mi.cornell_box())

    mi.set_variant('cuda_ad_rgb')
    scene2 = mi.load_dict(mi.cornell_box())
   
    # Before this PR, this would segfault when e.g. collecting the results of the BSDF vcall,
    # because the `Spectrum` types of the BSDF instances were not compatible.
    image = mi.render(scene2)
    print(image)


if __name__ == "__main__":
    test01_test_variants_switching()

Checklist

  • My code follows the style guidelines of this project
  • My changes generate no new warnings
  • My code also compiles for cuda_* and llvm_* variants. If you can't test this, please leave below
  • I have commented my code
  • I have made corresponding changes to the documentation
  • I have added tests that prove my fix is effective or that my feature works
  • I cleaned the commit history and removed any "Merge" commits
  • I give permission that the Mitsuba 3 project may redistribute my contributions under the terms of its license

Previously, we could easily segfault when performing a vcall if an object was previously created with another variant. For example, a `spectral_polarized` BSDF and an `rgb` BSDF.
@merlinND merlinND added the bug Something isn't working label Oct 25, 2024
@merlinND merlinND marked this pull request as draft October 25, 2024 13:31
@merlinND merlinND marked this pull request as ready for review October 25, 2024 19:20
@merlinND
Copy link
Member Author

merlinND commented Oct 25, 2024

This ended up being a fair bit more complicated that I expected, because now that the domain name depends on the Float, Spectrum template arguments, it cannot directly be set in the call support macros from the Name macro parameter.

But because call_support<>::Domain is used as a static constexpr field in a few places, we still have to compute the domain name in a constexpr way.
In C++17, it's possible to do constexpr string concatenation via std::array<>.

If we find a simpler solution (either to the original issue or any of the implementation steps of this PR), I would be all for it.

Copy link
Member

@njroussel njroussel left a comment

Choose a reason for hiding this comment

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

I agree that we should have some kind of a safety net for this issue.

Your suggested implementation seems fine. Changing the Domain is what makes the most sense, in my opinion.

Could you change the macros to be prefixed with MI_ instead of MTS_.

Also the CI is currently failing due to the variant_str declaration being non-constexpr. I believe that you should be able to fix that with a std::array again.

@merlinND
Copy link
Member Author

Thanks for having a look @njroussel!

I updated the macros to use MI_ instead of MTS and used domain_() instead of __domain() (matching the other DrJit methods like abs_, sin_, etc).

I tried another implementation of the constexpr string concatenation (using more std::array<char, N>) that will hopefully work across compilers.

@merlinND
Copy link
Member Author

merlinND commented Oct 28, 2024

CI fails look like:

  • MVSC: internal compiler error ( C:\BuildAgent\work\c1e5bf5b71462fab\include\mitsuba\core\class.h(254): fatal error C1001: Internal compiler error. [C:\BuildAgent\work\c1e5bf5b71462fab\build\src\mitsuba.vcxproj])
  • Others: volpath rendering tests failing. I don't know what's special about volpath since the other rendering tests are passing. I checked Medium and PhaseFunction, and they are the same as the other interfaces w.r.t. this new variant-specific domain. Maybe volpath is the only class in Mitsuba that triggers recursive vcalls, and that now somehow fails? 🤔
    • Edit: fixed (hopefully). Medium was the only class whose call_support helpers declared getters before methods. DRJIT_CALL_METHOD starts a private scope, which meant that what I declared in MI_CALL_TEMPLATE_END was private, so the custom domain name didn't get picked up. By correctly setting visibility in MI_CALL_TEMPLATE_END, this is fixed.

+ static_assert that our domain name override is detected to avoid bad surprises.
@merlinND
Copy link
Member Author

merlinND commented Oct 29, 2024

Using fewer intermediate static constexpr std::array variables I can get MSVC build without crash locally, let's see if it works on the CI as well.

Edit: CI is green!

@merlinND
Copy link
Member Author

Hi @njroussel,

Does the current state of this PR (+ the smaller one on the DrJit side: mitsuba-renderer/drjit#307) look good to you?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants