Adaptive stopping and sample distribution for Cycles
Needs ReviewPublic

Authored by Lukas Stockner (lukasstockner97) on Sep 29 2014, 5:34 PM.
Tags
Tokens
"Like" token, awarded by MarcoCheng."Love" token, awarded by akishin."Pterodactyl" token, awarded by sparazza."Love" token, awarded by bliblubli."Like" token, awarded by gandalf3."Manufacturing Defect?" token, awarded by leon_cheung."Love" token, awarded by tuqueque."Love" token, awarded by mirceakitsune."Mountain of Wealth" token, awarded by etoven."Like" token, awarded by januz."Mountain of Wealth" token, awarded by lordodin."Like" token, awarded by PGTART."Like" token, awarded by sdilmob."Love" token, awarded by Idlero."Love" token, awarded by monio."Mountain of Wealth" token, awarded by ace_dragon.

Details

Reviewers
Sergey Sharybin (sergey)
Group Reviewers
Cycles
Summary

This is the result of a rewrite of the adaptive sampling part of T38401, although there are large changes in some parts.

The major changes are:

  • The Warmup Samples parameter was added again, as it helps the adaptive distribution in some cases
  • All options are only available in experimental mode
  • An Error-Progressive mode was added: Instead of sampling every tile until its error is low enough, every tile is rendered for the warmup interval, and afterwards the acquire_tile always returns the tile with the worst error (with num_samples equal to the map interval) until every tile is below the error threshold. This gives the same result as non-progressive adaptive stopping and the added overhead is negligible: In my test, 3:07.54 with progressive vs. 3:06.12 without progressive. It's enabled by setting a stopping threshold while progressive rendering is used.
  • Working remaining time estimation: For non-progressive stopping, it relies only on the number of rendered tiles since the samples per tile may vary, while for progressive stopping the 1/sqrt(N) convergence of the error is used. It's not perfect, but usually, after 10% of the rendering time, the remaining time is within ~20% of the true value.
  • The occasional freezing/stopping is resolved.
  • When adaptive distribution is used, pixels might be processed by more than one thread, so in this case atomic operations are used for writing the passes (the CPU code has intrinsics for GCC, Clang, ICC and MSVC)
  • A better TVI curve is used, so that now dark areas are no longer oversampled in comparison to bright areas
  • The error value is scaled so that an error of 1 corresponds to "appears nearly noise-free if you don't zoom in"
  • A bilateral blur is now used for building the importance map for adaptive distributing after the gaussian blur, which helps in areas with single noisy pixels instead of uniformly noisy pixels (for example, the edge of the light reflection in the BMW scene). Thanks to @Adam Friesen (ace_dragon) for the idea!

As a summary of T38401, the features this patch adds are:

  • Adaptive stopping: If you set the stopping threshold to a value >0, this mode is activated. For every tile, the remaining error is estimated after a certain number of samples, controlled by the "map interval". The error exponent controls how sensitive the estimation is to outliers: The higher it gets, the more a single noisy spot influences the error value of the tile (it should stay between 2 and ~15). Once the error is below the threshold, the tile is stopped. In case the maximum amount of samples per tile is reached, the tile stops as well, even if the threshold is not reached yet. This does not affect the individual pixels in the tile, that's what adaptive distribution is for.
  • Error-progressive mode: See 3. above
  • Adaptive distribution: If this option is enabled, the samples inside every tile are also distributed accordingly to noise levels. Once the warmup interval is over, an importance map is generated and samples are drawn from it (this happens on the CPU even for GPU rendering). This helps mainly for big tiles (usually >32x32) with different levels of noise, for example, at the edge between scene and background. If this is used without adaptive stopping, every tile will still receive the same amount of samples in total.

The OpenCL code is untested, but is basically identical to the CUDA code, which works perfectly.


*NOTE*

Please keep this revision clean from comments which are not directly related to the code review process. Users feedback and questions shouldn't be asked here. This is a developers tool for core review, long discussions here only makes it so crucial info is not noticed. We don't have time to read all the comments.

Thanks for understanding.

Diff Detail

Repository
rB Blender
Branch
arcpatch-D808
There are a very large number of changes, so older changes are hidden. Show Older Changes

New patch version, the issues you mentioned inline and the code style should be addressed.

I already mentioned it on BA, but I'll do it again here: Apparently I've misunderstood you, Sergey, I thought you were against the patch as a whole because of usefulness concerns. I totally agree with having it as experimental. So, sorry for the silence (once again :D)!

intern/cycles/blender/blender_session.cpp
360

For error-progressive mode, the tiles that are currently processed should be highlighted, but for regular progressive they shouldn't be. I haven't found a cleaner way to do that, just changing the b_engine.use_highlight_tiles makes every tile that was already processed once highlighted.

459

Hm, I don't really know :D
Changing it.

intern/cycles/blender/blender_sync.cpp
580

Are you referring to the else line? If yes, changed it.

intern/cycles/kernel/kernel_compat_cpu.h
354 ↗(On Diff #3142)

Oops, you're completely right. On CPU, the atomics are useless :/

intern/cycles/kernel/kernel_compat_opencl.h
120 ↗(On Diff #3142)

Yes, but only for integer types. For floats, only atomic_xchg is supported. The trick here is based on http://suhorukov.blogspot.de/2011/12/opencl-11-atomic-operations-on-floating.html . Also, it helps for clean code to have the same function name on CUDA and OpenCL.

intern/cycles/kernel/kernel_passes.h
99

For CPU: Agreed, it's useless, as mentioned above.
For GPU: Yes, it really gives a benefit, without it big tiles are completely useless for AS, which would make it only useful for CPU. On the BMW scene, for example, it makes the front lamps look way better than with default settings, although the tile still receives no more than the configured sample amount on average.

As for the atomic flac: OK, moved it to the film parameters. Now passing the KernelGlobals along is needed, though.

intern/cycles/kernel/kernel_path.h
686

Not really, since the received sample value is needed for setting up the RNG.

intern/cycles/kernel/kernel_types.h
349

This pass is needed for the pixel redistribution, as it effectively causes different pixels to receive different amounts of samples, depending on their "noisyness". That's the reason for the atomics, the sample updating in kernel_path_trace and the changes in buffer.cpp.

350

The kernel write is needed, as it's essentially the average (squared) deviation of the samples from the mean. To calculate it, you therefore need all the individual results of each sample, not just the mean that's accumulated in the combined pass.

intern/cycles/render/film.cpp
1

Oops :D

intern/cycles/util/util_math.h
1497 ↗(On Diff #3142)

Ah, yes, they work just as fine. Precision is no issue here.

Blender build with D808 applied causes Cycles experimental SM35 CUDA kernel to fail to start with an out of memory error on my GTX 570. It works fine on my GTX 780, and the supported kernel can run the same scene on the GTX 570. In addition the experimental SM35 kernel fails to start on an empty scene on my GTX 570. If there's a fundamental reason why this shouldn't work on Fermi there should be a way to automatically disable building it for SM35 and under, and if there isn't a fundamental reason why this shouldn't work on Fermi and under then it shouldn't crash on startup. Can anyone confirm? Running Ubuntu 14.04 LTS.

Hi, the experimental kernel need much more memory than the "supported".
I cant even render the default cube with my GTX 560Ti 1.28 GB, my GTX 760 4GB work fine.
There are some patches in review to reduce mem usage, also there is AMD team to work on split Cycles kernel in micro kernels what reduce it too.
You can only disable your 570 in UP atm..
If you have the 2.5 GB 570 it is may a different problem.

Cheers, mib

Hi, the experimental kernel need much more memory than the "supported".
I cant even render the default cube with my GTX 560Ti 1.28 GB, my GTX 760 4GB work fine.
There are some patches in review to reduce mem usage, also there is AMD team to work on split Cycles kernel in micro kernels what reduce it too.
You can only disable your 570 in UP atm..
If you have the 2.5 GB 570 it is may a different problem.

Cheers, mib

Might be something with your drivers, many people are able to use AS, personally i use a Nvidea 630M it has 1 GB and i used for scenes that are quite lot more complex then a cube.
I'm using now the version that Lucas linked in the BA thread about light portals. my last big render was the new updated BMW speed test.. so thats more then a cube...

I am finding that when Progressive Refine is enabled, the render will stop after a few seconds and remain frozen. This error is unrecoverable, and requires me to force-kill blender. The problem stops when I disable the Save Buffers option.

Known issue?

Rebased to the current master, it should apply again.
Also I fixed two issues with the Cycles Debug passes enabled and added blurring of brightness for TVI calculation (should account for eye adaption a bit better).

Sorry, I forgot to add a file, it's included now.

This no longer patches against the current master.

[zauber@manjaro blender-d808]$ patch -p1 < ../D808.vson.id3829.whitespaceignore-all.diff 
patching file intern/cycles/blender/addon/properties.py
Hunk #1 succeeded at 505 (offset 1 line).
patching file intern/cycles/blender/addon/ui.py
patching file intern/cycles/blender/blender_session.h
Hunk #1 succeeded at 103 (offset 1 line).
patching file intern/cycles/blender/blender_session.cpp
Hunk #1 succeeded at 136 with fuzz 1.
Hunk #4 FAILED at 383.
Hunk #5 succeeded at 446 (offset 1 line).
Hunk #6 succeeded at 810 (offset 17 lines).
1 out of 6 hunks FAILED -- saving rejects to file intern/cycles/blender/blender_session.cpp.rej
patching file intern/cycles/blender/blender_sync.cpp
Hunk #1 succeeded at 195 (offset 1 line).
Hunk #2 succeeded at 559 (offset 34 lines).
patching file intern/cycles/device/device_cpu.cpp
Hunk #1 FAILED at 38.
Hunk #2 FAILED at 199.
Hunk #3 succeeded at 266 (offset 13 lines).
Hunk #4 succeeded at 345 (offset 13 lines).
2 out of 4 hunks FAILED -- saving rejects to file intern/cycles/device/device_cpu.cpp.rej
patching file intern/cycles/device/device_cuda.cpp
Hunk #3 succeeded at 573 (offset 1 line).
Hunk #4 succeeded at 583 (offset 1 line).
Hunk #5 succeeded at 599 (offset 1 line).
Hunk #6 FAILED at 969.
1 out of 6 hunks FAILED -- saving rejects to file intern/cycles/device/device_cuda.cpp.rej
patching file intern/cycles/device/device_opencl.cpp
Hunk #1 FAILED at 28.
Hunk #2 succeeded at 336 (offset 1 line).
Hunk #3 succeeded at 914 (offset 5 lines).
Hunk #4 succeeded at 935 (offset 5 lines).
Hunk #5 succeeded at 1073 (offset 5 lines).
1 out of 5 hunks FAILED -- saving rejects to file intern/cycles/device/device_opencl.cpp.rej
patching file intern/cycles/device/device_task.h
patching file intern/cycles/kernel/kernel.cl
patching file intern/cycles/kernel/kernel.cu
patching file intern/cycles/kernel/kernel_compat_opencl.h
patching file intern/cycles/kernel/kernel_debug.h
patching file intern/cycles/kernel/kernel_passes.h
patching file intern/cycles/kernel/kernel_path.h
patching file intern/cycles/kernel/kernel_types.h
Hunk #4 succeeded at 864 (offset 1 line).
patching file intern/cycles/render/buffers.h
patching file intern/cycles/render/buffers.cpp
patching file intern/cycles/render/film.cpp
patching file intern/cycles/render/session.h
patching file intern/cycles/render/session.cpp
patching file intern/cycles/render/tile.h
patching file intern/cycles/render/tile.cpp
Hunk #1 FAILED at 22.
Hunk #2 succeeded at 79 (offset 1 line).
Hunk #3 succeeded at 99 (offset 1 line).
Hunk #4 succeeded at 141 (offset 1 line).
Hunk #5 succeeded at 163 (offset 1 line).
Hunk #6 succeeded at 191 (offset 1 line).
Hunk #7 succeeded at 205 (offset 1 line).
Hunk #8 succeeded at 259 with fuzz 2 (offset 1 line).
Hunk #9 succeeded at 300 (offset 1 line).
1 out of 9 hunks FAILED -- saving rejects to file intern/cycles/render/tile.cpp.rej
patching file intern/cycles/util/CMakeLists.txt
patching file intern/cycles/util/util_color.h
patching file intern/cycles/util/util_importance.h (copied from intern/cycles/util/util_list.h)
patching file intern/cycles/util/util_importance.cpp
patching file intern/cycles/util/util_list.h
patching file source/blender/makesrna/intern/rna_render.c
Hunk #1 succeeded at 763 (offset 67 lines).
patching file source/blender/render/extern/include/RE_pipeline.h
Hunk #1 succeeded at 99 (offset 22 lines).
patching file source/blender/render/intern/source/render_result.c
Hunk #1 succeeded at 531 (offset 79 lines).
Hunk #2 FAILED at 620.
1 out of 2 hunks FAILED -- saving rejects to file source/blender/render/intern/source/render_result.c.rej

Hey Lukas,
Could you provide a new version of the patch for latest master?
Nice job :)

New version here, now applying again.

OpenCL split kernel has no support for adaptive sampling and/or distribution for now. It might
be possible, but I'm not too sure. The megakernel should work fine, though.

The atomic operations now use the atomic_add_float introduced for the split kernel. There is quite
some code duplication, but deduplicating more would probably turn it into a mess of macros.
The buf_x... were removed because they would either be duplicated (if inside the ifdefs) or cause
unused warnings for the CPU kernels (if outside the ifdefs).

The sample distribution now uses the same brightness smoothing as the error evaluation.
Also, it now detects fireflies and throws lots of samples on them to clear them faster.

Hi, trying new patch give error, it compiles but AD seam not work properly.

patching file intern/cycles/util/util_importance.h (copied from intern/cycles/util/util_list.h)
The next patch would create the file intern/cycles/util/util_importance.cpp,
which already exists!  Assume -R? [n] 
Apply anyway? [n] 
Skipping patch.
1 out of 1 hunk ignored

When I apply:

patching file intern/cycles/util/util_importance.h (copied from intern/cycles/util/util_list.h)
The next patch would create the file intern/cycles/util/util_importance.cpp,
which already exists!  Assume -R? [n] 
Apply anyway? [n] y
patching file intern/cycles/util/util_importance.cpp
Hunk #1 FAILED at 1.
1 out of 1 hunk FAILED -- saving rejects to file intern/cycles/util/util_importance.cpp.rej

Thanks, mib

Hi, after deleting util_importance.cpp patch applied but does not compile.
Blender b52af946cd92993dd6918797214d956070813878

[ 19%] Building CXX object intern/cycles/util/CMakeFiles/cycles_util.dir/util_importance.cpp.o
/daten/blender-git/blender/intern/cycles/util/util_importance.cpp: In function ‘bool ccl::find_passes(ccl::RenderTile&, int&, int&)’:
/daten/blender-git/blender/intern/cycles/util/util_importance.cpp:33:6: warning: no previous declaration for ‘bool ccl::find_passes(ccl::RenderTile&, int&, int&)’ [-Wmissing-declarations]
 bool find_passes(RenderTile &rtile, int &samples_pass_o, int &variance_pass_o) {
      ^
/daten/blender-git/blender/intern/cycles/util/util_importance.cpp: In constructor ‘ccl::ImportanceMap::ImportanceMap(ccl::RenderTile&)’:
/daten/blender-git/blender/intern/cycles/util/util_importance.cpp:109:2: error: ‘avgVariance’ was not declared in this scope
  avgVariance = width*height / avgVariance;
  ^
/daten/blender-git/blender/intern/cycles/util/util_importance.cpp:150:8: warning: unused variable ‘index’ [-Wunused-variable]
    int index = (rtile.offset + (rtile.y + y)*rtile.stride + rtile.x + x)*pass_stride;
        ^
intern/cycles/util/CMakeFiles/cycles_util.dir/build.make:123: recipe for target 'intern/cycles/util/CMakeFiles/cycles_util.dir/util_importance.cpp.o' failed
make[2]: *** [intern/cycles/util/CMakeFiles/cycles_util.dir/util_importance.cpp.o] Error 1
CMakeFiles/Makefile2:1291: recipe for target 'intern/cycles/util/CMakeFiles/cycles_util.dir/all' failed
make[1]: *** [intern/cycles/util/CMakeFiles/cycles_util.dir/all] Error 2
Makefile:147: recipe for target 'all' failed
make: *** [all] Error 2

Cheers, mib

I'm seeing the same issue as mib2merlin. On another note, I looked into util_importance.cpp and it looks like avgVariance is not used anywhere.

Sorry, I forgot to stage changes to util_importance.cpp before committing.
Now it should build correctly, avg_variance was indeed unused.

pls update the patch :)

New patch version: Rebased to current master, changed error exponent and improved importance calculation

Hunk #1 FAILED at 18.
1 out of 1 hunk FAILED -- saving rejects to intern/cycles/util/util_list.h.rej

Hi Lukas, patch work but does not compile on:

Opensuse 13.2/64
Intel i5 3770K
GTX 760 4 GB
Driver 352.09
gcc (SUSE Linux) 4.8.3

[ 16%] Building CXX object intern/cycles/util/CMakeFiles/cycles_util.dir/util_importance.cpp.o
/home/pepo/blender_build/blender/intern/cycles/util/util_importance.cpp: In function ‘bool ccl::find_passes(ccl::RenderTile&, int&, int&)’:
/home/pepo/blender_build/blender/intern/cycles/util/util_importance.cpp:33:6: warning: no previous declaration for ‘bool ccl::find_passes(ccl::RenderTile&, int&, int&)’ [-Wmissing-declarations]
 bool find_passes(RenderTile &rtile, int &samples_pass_o, int &variance_pass_o) {
      ^
/home/pepo/blender_build/blender/intern/cycles/util/util_importance.cpp: In function ‘float ccl::tile_error(ccl::RenderTile&)’:
/home/pepo/blender_build/blender/intern/cycles/util/util_importance.cpp:277:34: error: ‘class ccl::RenderBuffers’ has no member named ‘error_map’
  float *errmap = &rtile.buffers->error_map[0];
                                  ^
/home/pepo/blender_build/blender/intern/cycles/util/util_importance.cpp:277:9: warning: unused variable ‘errmap’ [-Wunused-variable]
  float *errmap = &rtile.buffers->error_map[0];
         ^
intern/cycles/util/CMakeFiles/cycles_util.dir/build.make:123: recipe for target 'intern/cycles/util/CMakeFiles/cycles_util.dir/util_importance.cpp.o' failed
make[2]: *** [intern/cycles/util/CMakeFiles/cycles_util.dir/util_importance.cpp.o] Error 1
CMakeFiles/Makefile2:1291: recipe for target 'intern/cycles/util/CMakeFiles/cycles_util.dir/all' failed
make[1]: *** [intern/cycles/util/CMakeFiles/cycles_util.dir/all] Error 2
Makefile:147: recipe for target 'all' failed
make: *** [all] Error 2

Thanks, mib
@lopata (lopataasdf), please add your system specs, make it easier for Lukas to fix.

@lopata (lopataasdf), please add your system specs, make it easier for Lukas to fix.

the patch is not applied for current master, it is not system specific problem :)

Thanks for the update Lukas,

the patch applies correctly here but compilation fails:

intern\cycles\util\util_importance.cpp(277) : error C2039: 'error_map' : is not a member of 'ccl::RenderBuffers'
        intern\cycles\render\buffers.h(68) : see declaration of 'ccl::RenderBuffers'
scons: *** [C:\Users\test\blendergit\build\win64-vc\intern\cycles\util\util_importance.obj] Error 2
scons: building terminated because of errors.

Sorry, I failed and forgot to stage a removed debugging line.
Also, the patch now applies again after the branched mode got its own file.

lopata (lopataasdf) added a comment.EditedJun 17 2015, 6:46 AM

Sorry, but still when applying
Hunk #1 FAILED at 18.
1 out of 1 hunk FAILED -- saving rejects to intern/cycles/util/util_list.h.rej

as far as I understand, path does not copy a file intern/cycles/util/util_list.h to intern/cycles/util/util_importance.h

try using --new-file paramether when diff

lopata (lopataasdf) added a comment.EditedJun 17 2015, 11:42 AM

p.s. when Feature Set == "Experimental", Sampling pattern is disabled. It is normal?
p.p.s AS still to give few samples in dark areas

THanks for the new patch Lukas :)

patch applies without problem for me (try to make a clean local branch before applying patch guys?). But their are 2 bugs in this version which were not in the 2.74 build you made:

Look at the white holes in the trees. Some other part are affected but it's the same problem I think (wrong transparency)

Anyway, happy to follow your progress!

Hoot215 added a subscriber: Hoot215.Aug 7 2015, 7:00 AM

Would it be possible to update this? The last working build I have for this is a development version of 2.75, and that build is on a revision with a showstopper bug with packed textures that got fixed in later revisions.

Would it be possible to implement tiles like in Luxcore? I mean, Luxcore creates many 32*32 tiles, but to efficiently use the gpu, it gives many tiles to one GPU. (i don't know how the algorithm find the optimal tile number but as it's open source, you could have a look?)

  • It would remove the need of adaptive sampling inside one tile, which is would give better performance on GPU and
  • allow to use the same tile size for CPU and GPU. At the moment, using the gpu with GPU in OpenCL make the render slower, because CPU is really slow with big tiles and the GPU stays idle in the end, waiting for the last tile being rendered.

New version, now rebased to the current master. No changes in functionality.

There was quite a long silence around this patch, so here's an update and the way I see it:
This approach kind of works, but not nearly as good as it should. It's not robust at all,
sometimes it just gets stuck on single pixels, sometimes the result is quite blotchy, sometimes
tile borders are extremely visible.
I'm looking into many different approaches currently and it looks like there is a lot of protential.
Cycles' design makes some of them impossible, but still, a big improvement should be possible.
Parts of this patch will be reusable, but the approach of just taking the variance is too unstable.

So, status of this patch is: It kind of works, but I don't consider this to be viable for master anymore.

New version, now rebased to the current master. No changes in functionality.

There was quite a long silence around this patch, so here's an update and the way I see it:
This approach kind of works, but not nearly as good as it should. It's not robust at all,
sometimes it just gets stuck on single pixels, sometimes the result is quite blotchy, sometimes
tile borders are extremely visible.
I'm looking into many different approaches currently and it looks like there is a lot of protential.
Cycles' design makes some of them impossible, but still, a big improvement should be possible.
Parts of this patch will be reusable, but the approach of just taking the variance is too unstable.

So, status of this patch is: It kind of works, but I don't consider this to be viable for master anymore.

I wouldn't quite say that. I've found this patch to be incredibly useful because it gives me a 50% or greater improvement to rendering speed, and I don't see the problems you report. At least, I don't see that when I am not using the Progressive Render option. When I have that option enabled, I do see the splotchiness you mention, and I also lose out on the performance gains I would normally have.

So, perhaps it is just that the progressive render option isn't working out?

Perhaps it could be beneficial for you to ask the Renderman developers to explain how their adaptive sampling works in RIS. It's not splotchy at all and it works really well. Even if they don't spill the secret sauce, you might get some ideas from them you can use.

I'm sure you've seen these already, but they might be interesting for other followers to take a look at. Both offer impressive speed ups and appear to be fairly trivial to add to existing path tracers. Cheers!
https://mediatech.aalto.fi/publications/graphics/GPT/
http://sglab.kaist.ac.kr/WLR/

I'm sure you've seen these already, but they might be interesting for other followers to take a look at. Both offer impressive speed ups and appear to be fairly trivial to add to existing path tracers. Cheers!
https://mediatech.aalto.fi/publications/graphics/GPT/
http://sglab.kaist.ac.kr/WLR/

I'm working here on implementing GPT "may take some time but it will be there".
about WLR, there are better papers, possibly after GPT implementation.

Hi Lukas, thanks for the update. The commit your differential apply against is broken on windows, it won't compile. So we need to do a git rebase after applying it. It would be nice to update the diff.

You know, an idea occurs to me for something that could help make this work better, by reducing the splotchiness.

Right now, the Map Update Rate setting determines the absolute minimum number of samples. What about adding a separate setting to control the minimum? That may help things somewhat.

@Zauber Paracelsus, that could be a neat idea, to have it only kicking only after x samples, and maybe ideally it should kick-in to recalculate not every x frames, but that ratio should be a curve, However i think this future is no longer being actively developed now.
Or is it still possible to compile it locally, and get this in cycles (that would be awesome) ?.

I never went into Git code, but, if it would be possible to include these peaces of code in today's blender
then i will learn how git works, and how to setup vs2015 for it. But can this still be included then ?.
Or did other already tried to build blender 2.76 with this ???

@Peter Boos (PGTART): It will compile under the 2.76 release. I have not tried compiling it under the 2.76a or 2.76b release. Getting it to compile under the current blender would require you to delve into C++ coding, rather than git. I may take a stab at updating the patch myself in a day or two, though I don't know how successful I would be at it since my skill with C++ is lacking.

Is there any news on when we might expect this to enter Blender, even as an Experimental feature? As someone who strongly struggles with noise vs. render times (no GPU support here) I'm eagerly waiting for it to happen already! Taking the forum thread into account, this has been around for over an year now.

@Mircea Kitsune (mirceakitsune): Read back a few posts. This branch has been abandoned by Lukas Stockner due to some problems with the implementation, and he said that he would be looking at some alternatives for reducing rendering times.

This is mostly a dead experiment I think. There are substantially better adaptive methods out there at this point (that Lukas has actively been researching) along with things like Gradient Domain that offer solutions that are much more production-safe. I wouldn't hold my breath for this particular adaptive branch, but if I'm wrong Lukas can correct me.

Somehow I predicted this was going to happen... hence why I kept poking the Blender team about getting this done sooner, before it got abandoned. If an alternative is in the works however, not all hope is lost. Any links to the new project please?

@Peter Boos (PGTART) You must use MSVC 2013. 2015 is not working right now.

I certainly did not abandon this patch because of slow review - I abandoned it because I realized that this is not nearly as good as it could be.
It's a direct consequence from Blender's policy of compatibility that once you've implemented something, you have to stick with it. For example, consider the 0.1 factor in the displacement code - it's annoying, but you can't change it since it would break existing scenes.
It's the same with features like AS - once you implement one approach, you have to stick to it. If you want to implement a better one later, you either break compatibility (not really great) or have two conflicting options (confusing everybody, also not great).
When I started the whole Metropolis/AS stuff, I was just hacking around on the code and trying out stuff. However, as I got more involved in Cycles development, I started to consider points like this compatibility and maintenance problem - and realized that "well, it kind of works" is simply not good enough for a feature that will be around for years and where way better implementations are possible.
That's why I abandoned this patch: It kind of works, but not good enough and not as good as it could - certainly not good enough to make it the official AS solution for years (since 2.8 is just starting, it would be quite a long time to the next version jump where you could get rid of it).

I keep saying "not as good as it could" - I'm referring to the new stuff I'm working on, based on the recent papers about Locally Weighted Regression in feature space. In particular, I'm working on combining it with contrast sensitivity models to control the bias-variance-tradeoff parameter of these algorithms. Nothing is finished or even certain yet, but it's looking promising.
Please understand that stuff like this takes a while. I'm doing this development next to other Blender/Cycles coding stuff, university and some non-Blender programming projects, and even if I was doing it full-time, state-of-the-art adaptive reconstruction filters don't write themselves. On top of this, I try to avoid another hype train like the one I started with Metro/AS - we see right here and in the Metro task where that leads to ;)
Once I have something presentable that I feel is stable enough for testing, I'll publish it, no worries :)

Thanks for the clarification! Although I wanted to hope they weren't accurate or that this might change, several people stated that this patch does too little to improve performance in production scenes. If a whole new implementation is needed to get the best effect, I can agree that's better, even if it takes a bit longer to happen. Otherwise I'm familiar with being busy with multiple software project, and not being able to get as much as you wish done... it would be wrong to expect too much, though I do hope we might see something interesting during 2016 if all goes well. Thank you and good luck!

Well c++ isn't the problem here, i can code in about 12 languages..
But i usually don't work with code distribution systems, i only once used turtoise.
At work, we have a real small dev team each works dedicated on something we never had a need for it,

I understand Lucas cons, about having a non optimal render future, ( lux has many render methods too, and not all are perfect ), i just see this as a method. And wouldn't mind for the time beeing an imperfect but fast, rendering method, maybe we can improve it here, as there are more people able of coding. However i don't have vs2013, so that would be kind of a show stopper for me, i use vs2015 now (as it is free).

@Zauber Paracelsus, if you have it as an visualstudio prj file maybe i might try to upgrade it to vs2015, done it with small vs2010 prjs,
not sure if i could do blender, as this would be not my code and also a lot larger, oh well i could give it a try.

I am worry about memory efficiency. This function memory efficiency similar to Random bucket order and not higher as hilber space filling curve or others.