Page 1 of 2

LuxCore API - comparable quality

Posted: Thu May 24, 2018 3:31 pm
by mick
I need to compare the irradiation between scenes with different sets of lenses.

Tracing performance will be impacted by differences of the scenes, and external factors like e.g. system load. So I cannot expect that a fixed tracing duration would deliver comparable results. How can a best achieve that?

My approach would be to make only my fixed size and fixed position measurement surface visible to the camera, and run a fixed number of samples. I tried

Code: Select all

batch.haltspp = 10
and

Code: Select all

session.WaitForDone()
But WaitForDone does not return.

Stats reported 3.81M samples per sec for my 800x600 image. So I'd expect that 10spp should be achieve in a bit more than 1 sec. What's wrong?

Re: LuxCore API - comparable quality

Posted: Thu May 24, 2018 3:40 pm
by Dade
mick wrote: Thu May 24, 2018 3:31 pm I need to compare the irradiation between scenes with different sets of lenses.

Tracing performance will be impacted by differences of the scenes, and external factors like e.g. system load. So I cannot expect that a fixed tracing duration would deliver comparable results. How can a best achieve that?

My approach would be to make only my fixed size and fixed position measurement surface visible to the camera, and run a fixed number of samples. I tried

Code: Select all

batch.haltspp = 10
and

Code: Select all

session.WaitForDone()
But WaitForDone does not return.

Stats reported 3.81M samples per sec for my 800x600 image. So I'd expect that 10spp should be achieve in a bit more than 1 sec. What's wrong?
Yes, it should be done in a couple of seconds, can you post the fragment of code using session.WaitForDone() ? This fragment of code works: https://github.com/LuxCoreRender/LuxCor ... le.cpp#L55 and allows you to print some information during the rendering (instead of being stuck in WaitForDone()).

P.S. 10 samples/sec is can be a bit low has value for a noise-free image

Re: LuxCore API - comparable quality

Posted: Thu May 24, 2018 3:44 pm
by mick

Code: Select all

def render(scene):
  session = build_session(scene)
  session.Start()
  startTime = time()
  while True:
    session.WaitForDone()
    #sleep(1)
    elapsedTime = time() - startTime
    session.UpdateStats()
    stats = session.GetStats()
    print("[Elapsed time: %3d/5sec][Samples %4d][Avg. samples/sec % 3.2fM on %.1fK tris]" % (
      stats.Get("stats.renderengine.time").GetFloat(),
      stats.Get("stats.renderengine.pass").GetInt(),
      (stats.Get("stats.renderengine.total.samplesec").GetFloat() / 1000000.0),
      (stats.Get("stats.dataset.trianglecount").GetFloat() / 1000.0)))
    if elapsedTime > 5:
      break
  session.Stop()
  return session

Re: LuxCore API - comparable quality

Posted: Thu May 24, 2018 3:49 pm
by Dade
mick wrote: Thu May 24, 2018 3:44 pm

Code: Select all

def render(scene):
  session = build_session(scene)
  session.Start()
  startTime = time()
  while True:
    session.WaitForDone()
    #sleep(1)
    elapsedTime = time() - startTime
    session.UpdateStats()
    stats = session.GetStats()
    print("[Elapsed time: %3d/5sec][Samples %4d][Avg. samples/sec % 3.2fM on %.1fK tris]" % (
      stats.Get("stats.renderengine.time").GetFloat(),
      stats.Get("stats.renderengine.pass").GetInt(),
      (stats.Get("stats.renderengine.total.samplesec").GetFloat() / 1000000.0),
      (stats.Get("stats.dataset.trianglecount").GetFloat() / 1000.0)))
    if elapsedTime > 5:
      break
  session.Stop()
  return session
Uh, no, you have to remove the while loop: session.WaitForDone() is supposed to be used to wait the end of the rendering once; than the rendering is done. Just use something like:

Code: Select all

def render(scene):
  session = build_session(scene)
  session.Start()

  startTime = time()
  session.WaitForDone()
  elapsedTime = time() - startTime

  session.UpdateStats()
  stats = session.GetStats()
  print("[Elapsed time: %3d/5sec][Samples %4d][Avg. samples/sec % 3.2fM on %.1fK tris]" % (
    stats.Get("stats.renderengine.time").GetFloat(),
    stats.Get("stats.renderengine.pass").GetInt(),
    (stats.Get("stats.renderengine.total.samplesec").GetFloat() / 1000000.0),
    (stats.Get("stats.dataset.trianglecount").GetFloat() / 1000.0)))

  session.Stop()
  return session

Re: LuxCore API - comparable quality

Posted: Thu May 24, 2018 3:54 pm
by mick
Of course I don't need the loop. This is just for the time restricted approach. But that's not the issue. It should print the stats after returning from WaitForDone(), and then break anyway if more the 5 secs past.

But it hangs (processing) before reaching the print.

Re: LuxCore API - comparable quality

Posted: Thu May 24, 2018 4:01 pm
by mick
Just found out:

Code: Select all

batch.haltspp = 1
returns immediately,

Code: Select all

batch.haltspp = 2
not at all.

Re: LuxCore API - comparable quality

Posted: Thu May 24, 2018 4:06 pm
by B.Y.O.B.
Using the PATH engine and samples halt condition has the problem that it is a "soft" halt condition (it will overshoot more or less and most of the time render a few more samples than requested).

You could instead use TILEPATH engine, which will render exactly the amount of samples you request:
https://wiki.luxcorerender.org/LuxCore_ ... PATHCPU.22
You would need something like these config properties:

Code: Select all

renderengine.type = TILEPATHCPU
# This sampler must be used with this engine, no other samplers work
sampler.type = TILEPATHSAMPLER

# This controls the amount of samples per pixel
tilepath.sampling.aa.size = 3
# Stop once all pixels were sampled, do not start another pass
tile.multipass.enable = 0

Re: LuxCore API - comparable quality

Posted: Thu May 24, 2018 4:13 pm
by mick
I'm going to try TILEPATH.

But still the behavior of haltspp is strange. Now with HasDone():

Code: Select all

def render(scene):
  session = build_session(scene)
  session.Start()
  while True:
    sleep(1)
    session.UpdateStats()
    stats = session.GetStats()
    print("[Elapsed time: %3d/5sec][Samples %4d][Avg. samples/sec % 3.2fM on %.1fK tris]" % (
      stats.Get("stats.renderengine.time").GetFloat(),
      stats.Get("stats.renderengine.pass").GetInt(),
      (stats.Get("stats.renderengine.total.samplesec").GetFloat() / 1000000.0),
      (stats.Get("stats.dataset.trianglecount").GetFloat() / 1000.0)))
    if session.HasDone() > 5:
      break
  session.Stop()
  return session
produces:

Code: Select all

[Elapsed time:   4/5sec][Samples    3][Avg. samples/sec  0.30M on 0.0K tris]
[Elapsed time:   5/5sec][Samples    3][Avg. samples/sec  0.24M on 0.0K tris]
[Elapsed time:   6/5sec][Samples    3][Avg. samples/sec  0.21M on 0.0K tris]
[Elapsed time:   8/5sec][Samples    3][Avg. samples/sec  0.18M on 0.0K tris]
[Elapsed time:   9/5sec][Samples    3][Avg. samples/sec  0.16M on 0.0K tris]
[Elapsed time:  10/5sec][Samples    3][Avg. samples/sec  0.14M on 0.0K tris]
[Elapsed time:  11/5sec][Samples    3][Avg. samples/sec  0.13M on 0.0K tris]
[Elapsed time:  12/5sec][Samples    3][Avg. samples/sec  0.12M on 0.0K tris]
[Elapsed time:  13/5sec][Samples    3][Avg. samples/sec  0.11M on 0.0K tris]
[Elapsed time:  14/5sec][Samples    3][Avg. samples/sec  0.10M on 0.0K tris]
[Elapsed time:  15/5sec][Samples    3][Avg. samples/sec  0.10M on 0.0K tris]
[Elapsed time:  16/5sec][Samples    3][Avg. samples/sec  0.09M on 0.0K tris]
[Elapsed time:  17/5sec][Samples    3][Avg. samples/sec  0.08M on 0.0K tris]
[Elapsed time:  18/5sec][Samples    3][Avg. samples/sec  0.08M on 0.0K tris]
[Elapsed time:  19/5sec][Samples    3][Avg. samples/sec  0.07M on 0.0K tris]
[Elapsed time:  20/5sec][Samples    3][Avg. samples/sec  0.07M on 0.0K tris]
[Elapsed time:  21/5sec][Samples    3][Avg. samples/sec  0.07M on 0.0K tris]
[Elapsed time:  22/5sec][Samples    3][Avg. samples/sec  0.06M on 0.0K tris]
[Elapsed time:  23/5sec][Samples    3][Avg. samples/sec  0.06M on 0.0K tris]
[Elapsed time:  24/5sec][Samples    3][Avg. samples/sec  0.06M on 0.0K tris]
[Elapsed time:  25/5sec][Samples    3][Avg. samples/sec  0.06M on 0.0K tris]
[Elapsed time:  26/5sec][Samples    3][Avg. samples/sec  0.05M on 0.0K tris]
[Elapsed time:  27/5sec][Samples    3][Avg. samples/sec  0.05M on 0.0K tris]
[Elapsed time:  28/5sec][Samples    3][Avg. samples/sec  0.05M on 0.0K tris]
[Elapsed time:  29/5sec][Samples    3][Avg. samples/sec  0.05M on 0.0K tris]
[Elapsed time:  30/5sec][Samples    3][Avg. samples/sec  0.05M on 0.0K tris]

Re: LuxCore API - comparable quality

Posted: Thu May 24, 2018 4:19 pm
by Dade
mick wrote: Thu May 24, 2018 4:13 pm I'm going to try TILEPATH.

But still the behavior of haltspp is strange. Now with HasDone():

Code: Select all

def render(scene):
  session = build_session(scene)
  session.Start()
  while True:
    sleep(1)
    session.UpdateStats()
    stats = session.GetStats()
    print("[Elapsed time: %3d/5sec][Samples %4d][Avg. samples/sec % 3.2fM on %.1fK tris]" % (
      stats.Get("stats.renderengine.time").GetFloat(),
      stats.Get("stats.renderengine.pass").GetInt(),
      (stats.Get("stats.renderengine.total.samplesec").GetFloat() / 1000000.0),
      (stats.Get("stats.dataset.trianglecount").GetFloat() / 1000.0)))
    if session.HasDone() > 5:
      break
  session.Stop()
  return session
It is not correct, it should be:

Code: Select all

def render(scene):
  session = build_session(scene)
  session.Start()
  while not session.HasDone():
    sleep(1)
    session.UpdateStats()
    stats = session.GetStats()
    print("[Elapsed time: %3d/5sec][Samples %4d][Avg. samples/sec % 3.2fM on %.1fK tris]" % (
      stats.Get("stats.renderengine.time").GetFloat(),
      stats.Get("stats.renderengine.pass").GetInt(),
      (stats.Get("stats.renderengine.total.samplesec").GetFloat() / 1000000.0),
      (stats.Get("stats.dataset.trianglecount").GetFloat() / 1000.0)))
  session.Stop()
  return session

Re: LuxCore API - comparable quality

Posted: Thu May 24, 2018 4:19 pm
by mick
HasDone works with both engines. There was a problem with the break condition in my latest code. Still I guess that the is something wrong with WaitForDone().