void storeResults() { pLogger->info("Store BPT results"); storeResults(m_BPTRenderer, 0); pLogger->info("Store ICBPT results"); storeResults(m_ICBPTRenderer, 1); for(auto i: range(m_SkelBPTRenderers.size())) { pLogger->info("Store SkelBPT %v results", i); storeResults(m_SkelBPTRenderers[i], 2 + i); } }
// Render in a loop all rendering algorithms, one iteration at a time until each algorithm has finished // All light paths are shared by all algorithms for a given iteration bool render() { bool allDone = true; pLogger->info("Start iteration %v", m_SharedData.m_nIterationCount); // Sample light paths and setup data to project light vertices on image plane auto initFrameTime = [&](){ Timer timer; { auto taskTimer = m_InitIterationTimer.start(0); sampleLightPaths(); } { auto taskTimer = m_InitIterationTimer.start(1); buildDirectImportanceSampleTilePartitionning(); } return timer.getEllapsedTime<Microseconds>(); }(); for(auto& stats: m_RenderStatistics) { stats.renderTime += initFrameTime; } // Run all algorithms pLogger->info("Render BPT"); allDone = render(m_BPTRenderer, 0) && allDone; pLogger->info("Render ICBPT"); allDone = render(m_ICBPTRenderer, 1) && allDone; for(auto i: range(m_SkelBPTRenderers.size())) { pLogger->info("Render SkelBPT %v", i); allDone = render(m_SkelBPTRenderers[i], 2 + i) && allDone; } ++m_SharedData.m_nIterationCount; if(!m_bEqualTime && m_SharedData.m_nIterationCount == m_nRenderTimeMsOrIterationCount) { allDone = true; } if(allDone) { storeResults(); } return allDone; }
void updateAlphas(__global float *input_data, __global int *labels, __global float *training_alpha, __global float *kernelDiag, float cost, int dFeatures, int iLow, int iHigh, float fLow, float bLow, float bHigh, float paramA, float paramB, float paramC, __global float *results){ float gap = bHigh - bLow; float alpha2old = training_alpha[iLow]; float alpha1old = training_alpha[iHigh]; float alphadiff = alpha2old - alpha1old; float alpha1diff; float alpha2diff; float alpha1new; float alpha2new; float alphaSum; int lowLabel = labels[iLow]; int sign = labels[iHigh]*lowLabel; float L; float H; // find lower and upper bounds L and H if (sign < 0){ if(alphadiff < 0.0f){ L = 0.0f; H = cost + alphadiff; }else{ L = alphadiff; H = cost; } }else{ alphaSum = alpha2old + alpha1old; if (alphaSum < cost){ L = 0.0f; H = alphaSum; }else{ L = cost - alphaSum; H = cost; } } // compute and clip alpha2new but only if eta is positive, i.e. second derivative is negative float eta = kernelDiag[iLow] + kernelDiag[iHigh]; __global float *vecA = input_data + iHigh * dFeatures; __global float *vecB = input_data + iLow * dFeatures; float phiAB = ${kernelFunc}(vecA, vecB, dFeatures, paramA, paramB, paramC); eta -= 2.0f * phiAB; if (eta > 0.0f){ //compute alpha2new = alpha2old + lowLabel*(bHigh - fLow)/eta; //clip if (alpha2new < L){ alpha2new = L; }else if(alpha2new > H){ alpha2new = H; } } else{ // alpha2new can now only assume endpoints or alpha2old (this is rare) float slope = lowLabel * gap; float delta = slope * (H - L); if (delta > 0){ if (slope > 0){ alpha2new = H; }else{ alpha2new = L; } }else{ alpha2new = alpha2old; } } alpha2diff = alpha2new - alpha2old; alpha1diff = -sign * alpha2diff; alpha1new = alpha1old + alpha1diff; training_alpha[iHigh] = alpha1new; training_alpha[iLow] = alpha2new; storeResults(results, bLow, bHigh, iLow, iHigh, alpha1diff, alpha2diff); }