Distinct blue-noise sampler domains produce bit-identical sample streams

Open
#117 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
57/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Active
Tech stack
cpp

Research direction

The reproduction exercises SobolBnSampler, PmjBnSampler, and the SobolSampler control through qmc/sobolbn.h, qmc/pmjbn.h, and qmc/sobol.h. Start by tracing how newDomain and drawSample handle the domain key in the blue-noise samplers, then run the repro against the control. Done means keys 97 and 138 no longer produce identical first-coordinate streams for the reported indices, while the control remains collision-free.

Written by the indexing model from the issue text.

Description

enhancement

Distinct sibling domain keys produce identical sample streams in SobolBnSampler and PmjBnSampler. With pixel (0,0), frame 0, keys 97 and 138 yield bit-for-bit identical first-coordinate samples for indices 0…4095. The non-blue-noise SobolSampler control does not exhibit this collision.

Her is a repro case:

#include <oqmc/sobolbn.h>
#include <oqmc/pmjbn.h>
#include <oqmc/sobol.h>

#include <cstdint>
#include <iostream>
#include <vector>

template<class Sampler>
bool check(const char* name)
{
    std::vector<std::uint64_t> cache((Sampler::cacheSize + 7) / 8);
    Sampler::initialiseCache(cache.data());
    unsigned identical = 0;
    for (int index = 0; index < 4096; ++index) {
        const Sampler root(0, 0, 0, index, cache.data()); // x, y, frame, index
        std::uint32_t a[1], b[1];
        root.newDomain(97).template drawSample<1>(a);
        root.newDomain(138).template drawSample<1>(b);
        identical += a[0] == b[0];
    }
    std::cout << name << ": " << identical
              << "/4096 bit-for-bit identical sample pairs\n";
    return identical == 4096;
}

int main()
{
    const bool sobolBnCollision = check<oqmc::SobolBnSampler>("SobolBn");
    const bool pmjBnCollision = check<oqmc::PmjBnSampler>("PmjBn");
    const bool plainSobolCollision = check<oqmc::SobolSampler>("Sobol (control)");
    if (!sobolBnCollision || !pmjBnCollision || plainSobolCollision) {
        std::cerr << "Results differ from the OpenQMC 0.7.1.0 reproduction.\n";
        return 1;
    }
    return 0;
}
Dominant language
C++
Stars
106
Forks
7
PR merge metrics
No merged PRs in 30d

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from AcademySoftwareFoundation/openqmc

All issues in AcademySoftwareFoundation/openqmc

Similar issues

More C++ issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.