Float evalSingleLobe(const PhaseFunctionSamplingRecord &pRec, int lobeIdx) const { Vector wi = pRec.wi; Vector wo = pRec.wo; #ifdef USE_STOC_EVAL Spectrum s1 = pRec.mRec.s1; Spectrum s2 = pRec.mRec.s2; #else Spectrum s1 = pRec.mRec.s1[lobeIdx]; Spectrum s2 = pRec.mRec.s2[lobeIdx]; #endif Float Sxx = s1[0], Syy = s1[1], Szz = s1[2]; Float Sxy = s2[0], Sxz = s2[1], Syz = s2[2]; Float res = 1.f; Float sqrSum = Sxx * Sxx + Syy * Syy + Szz * Szz + Sxy * Sxy + Sxz * Sxz + Syz * Syz; //if (!(Sxx == 0 && Syy == 0 && Szz == 0 && Sxy == 0 && Sxz == 0 && Syz == 0)) if (fabsf(sqrSum) < 1e-6f) return 0; if (m_sampleType == ESpecular) { Vector H = wi + wo; Float length = H.length(); if (length == 0) return 0.f; H /= length; res *= 0.25f * ndf(H, Sxx, Syy, Szz, Sxy, Sxz, Syz) / sigma(wi, Sxx, Syy, Szz, Sxy, Sxz, Syz); } else if (m_sampleType == EDiffuse) { Vector wm = sampleVNormal(wi, m_sampler, Sxx, Syy, Szz, Sxy, Sxz, Syz); res *= 1.f * INV_PI * std::max(0.f, dot(wo, wm)); } else if (m_sampleType == EMixed) { Vector H = wi + wo; Float length = H.length(); if (length == 0) return 0.f; H /= length; Float p1 = 0.25f * ndf(H, Sxx, Syy, Szz, Sxy, Sxz, Syz) / sigma(wi, Sxx, Syy, Szz, Sxy, Sxz, Syz); Vector wm = sampleVNormal(wi, m_sampler, Sxx, Syy, Szz, Sxy, Sxz, Syz); Float p2 = 1.f * INV_PI * std::max(0.f, dot(wo, wm)); res *= p1 * m_mixedWeight + p2 * (1.f - m_mixedWeight); } else res = 0; return res; }
// standard normal cumulative distribution function double nc(double x) { double result; if (x < -7.) result = ndf(x)/sqrt(1.+x*x); else if (x > 7.) result = 1. - nc(-x); else { result = 0.2316419; double a[5] = {0.31938153,-0.356563782,1.781477937,-1.821255978,1.330274429}; result=1./(1+result*fabs(x)); result=1-ndf(x)*(result*(a[0]+result*(a[1]+result*(a[2]+result*(a[3]+result*a[4]))))); if (x<=0.) result=1.-result; }; return result; }
bool NodeDataFactory<TYPE>::validCopyTo( const std::shared_ptr<hier::PatchDataFactory>& dst_pdf) const { TBOX_ASSERT_OBJDIM_EQUALITY2(*this, *dst_pdf); bool valid_copy = false; /* * Valid options are NodeData and OuternodeData. */ if (!valid_copy) { std::shared_ptr<NodeDataFactory<TYPE> > ndf( std::dynamic_pointer_cast<NodeDataFactory<TYPE>, hier::PatchDataFactory>(dst_pdf)); if (ndf) { valid_copy = true; } } if (!valid_copy) { std::shared_ptr<OuternodeDataFactory<TYPE> > ondf( std::dynamic_pointer_cast<OuternodeDataFactory<TYPE>, hier::PatchDataFactory>( dst_pdf)); if (ondf) { valid_copy = true; } } return valid_copy; }
// standard normal comulated density function float normcdf(float x) { float result; if (x < -7.) result = ndf(x) / sqrt(1. + x * x); else if (x > 7.) { result = 1. - normcdf(-x); /* x = -x; float tempx = ndf(x) / sqrt(1. + x * x); result = 1. - tempx; */ } else { result = 0.2316419; static float a[5] = { 0.31938153, -0.356563782, 1.781477937, -1.821255978, 1.330274429 }; result = 1. / (1 + result * fabs(x)); result = 1 - ndf(x) * (result * (a[0] + result * (a[1] + result * (a[2] + result * (a[3] + result * a[4]))))); if (x <= 0.) result = 1. - result; } return result; }
// static std::vector<double> GaussFitter::eval(const std::vector<double>& evaluation_points, const GaussFitter::GaussFitResult& model) { std::vector<double> out; out.reserve(evaluation_points.size()); boost::math::normal_distribution<> ndf(model.x0, model.sigma); double int0 = model.A / boost::math::pdf(ndf, model.x0); // intensity normalization factor of the max @ x0 (simply multiplying the CDF with A is wrong!) for (Size i = 0; i < evaluation_points.size(); ++i) { out.push_back(boost::math::pdf(ndf, evaluation_points[i]) * int0 ); } return out; }
int main(int argc, char *argv[]) { cl::SetVersionPrinter(&versionPrinter); cl::ParseCommandLineOptions(argc, argv, "llvm2kittel\n"); if (boundedIntegers && divisionConstraintType == Exact) { std::cerr << "Cannot use \"-division-constraint=exact\" in combination with \"-bounded-integers\"" << std::endl; return 333; } if (!boundedIntegers && unsignedEncoding) { std::cerr << "Cannot use \"-unsigned-encoding\" without \"-bounded-integers\"" << std::endl; return 333; } if (!boundedIntegers && bitwiseConditions) { std::cerr << "Cannot use \"-bitwise-conditions\" without \"-bounded-integers\"" << std::endl; return 333; } if (numInlines != 0 && eagerInline) { std::cerr << "Cannot use \"-inline\" in combination with \"-eager-inline\"" << std::endl; return 333; } #if LLVM_VERSION < VERSION(3, 5) llvm::OwningPtr<llvm::MemoryBuffer> owningBuffer; llvm::MemoryBuffer::getFileOrSTDIN(filename, owningBuffer); llvm::MemoryBuffer *buffer = owningBuffer.get(); #else llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> owningBuffer = llvm::MemoryBuffer::getFileOrSTDIN(filename); llvm::MemoryBuffer *buffer = NULL; if (!owningBuffer.getError()) { buffer = owningBuffer->get(); } #endif if (buffer == NULL) { std::cerr << "LLVM bitcode file \"" << filename << "\" does not exist or cannot be read." << std::endl; return 1; } llvm::LLVMContext context; std::string errMsg; #if LLVM_VERSION < VERSION(3, 5) llvm::Module *module = llvm::ParseBitcodeFile(buffer, context, &errMsg); #elif LLVM_VERSION == VERSION(3, 5) llvm::Module *module = NULL; llvm::ErrorOr<llvm::Module*> moduleOrError = llvm::parseBitcodeFile(buffer, context); std::error_code ec = moduleOrError.getError(); if (ec) { errMsg = ec.message(); } else { module = moduleOrError.get(); } #elif LLVM_VERSION == VERSION(3, 6) llvm::Module *module = NULL; llvm::ErrorOr<llvm::Module*> moduleOrError = llvm::parseBitcodeFile(buffer->getMemBufferRef(), context); std::error_code ec = moduleOrError.getError(); if (ec) { errMsg = ec.message(); } else { module = moduleOrError.get(); } #else llvm::Module *module = NULL; llvm::ErrorOr<std::unique_ptr<llvm::Module>> moduleOrError = llvm::parseBitcodeFile(buffer->getMemBufferRef(), context); std::error_code ec = moduleOrError.getError(); if (ec) { errMsg = ec.message(); } else { module = moduleOrError->get(); } #endif // check if the file is a proper bitcode file and contains a module if (module == NULL) { std::cerr << "LLVM bitcode file doesn't contain a valid module." << std::endl; return 2; } llvm::Function *function = NULL; llvm::Function *firstFunction = NULL; unsigned int numFunctions = 0; std::list<std::string> functionNames; for (llvm::Module::iterator i = module->begin(), e = module->end(); i != e; ++i) { if (i->getName() == functionname) { function = &*i; break; } else if (functionname.empty() && i->getName() == "main") { function = &*i; break; } else if (!i->isDeclaration()) { ++numFunctions; functionNames.push_back(i->getName()); if (firstFunction == NULL) { firstFunction = &*i; } } } if (function == NULL) { if (numFunctions == 0) { std::cerr << "Module does not contain any function." << std::endl; return 3; } if (functionname.empty()) { if (numFunctions == 1) { function = firstFunction; } else { std::cerr << "LLVM module contains more than one function:" << std::endl; for (std::list<std::string>::iterator i = functionNames.begin(), e = functionNames.end(); i != e; ++i) { std::cerr << " " << *i << std::endl; } std::cerr << "Please specify which function should be used." << std::endl; return 4; } } else { std::cerr << "Specified function not found." << std::endl; std::cerr << "Candidates are:" << std::endl; for (std::list<std::string>::iterator i = functionNames.begin(), e = functionNames.end(); i != e; ++i) { std::cerr << " " << *i << std::endl; } return 5; } } // check for cyclic call hierarchies HierarchyBuilder checkHierarchy; checkHierarchy.computeHierarchy(module); if (eagerInline && checkHierarchy.isCyclic()) { std::cerr << "Cannot use \"-eager-inline\" with a cyclic call hierarchy!" << std::endl; return 7; } // transform! NondefFactory ndf(module); transformModule(module, function, ndf); // name them! InstNamer namer; namer.visit(module); // check them! const llvm::Type *boolType = llvm::Type::getInt1Ty(context); const llvm::Type *floatType = llvm::Type::getFloatTy(context); const llvm::Type *doubleType = llvm::Type::getDoubleTy(context); InstChecker checker(boolType, floatType, doubleType); checker.visit(module); // print it! if (debug) { #if LLVM_VERSION < VERSION(3, 5) llvm::PassManager printPass; printPass.add(llvm::createPrintModulePass(&llvm::outs())); printPass.run(*module); #else llvm::outs() << *module << '\n'; #endif } if (dumpLL) { std::string outFile = filename.substr(0, filename.length() - 3) + ".ll"; #if LLVM_VERSION < VERSION(3, 5) std::string errorInfo; llvm::raw_fd_ostream stream(outFile.data(), errorInfo); if (errorInfo.empty()) { llvm::PassManager dumpPass; dumpPass.add(llvm::createPrintModulePass(&stream)); dumpPass.run(*module); stream.close(); } #elif LLVM_VERSION == VERSION(3, 5) std::string errorInfo; llvm::raw_fd_ostream stream(outFile.data(), errorInfo, llvm::sys::fs::F_Text); if (errorInfo.empty()) { stream << *module << '\n'; stream.close(); } #else std::error_code errorCode; llvm::raw_fd_ostream stream(outFile.data(), errorCode, llvm::sys::fs::F_Text); if (!errorCode) { stream << *module << '\n'; stream.close(); } #endif } // check for junk std::list<llvm::Instruction*> unsuitable = checker.getUnsuitableInsts(); if (!unsuitable.empty()) { std::cerr << "Unsuitable instructions detected:" << std::endl; for (std::list<llvm::Instruction*>::iterator i = unsuitable.begin(), e = unsuitable.end(); i != e; ++i) { (*i)->dump(); } return 6; } // compute recursion hierarchy HierarchyBuilder hierarchy; hierarchy.computeHierarchy(module); std::list<std::list<llvm::Function*> > sccs = hierarchy.getSccs(); std::map<llvm::Function*, std::list<llvm::Function*> > funToScc; for (std::list<std::list<llvm::Function*> >::iterator i = sccs.begin(), e = sccs.end(); i != e; ++i) { std::list<llvm::Function*> scc = *i; for (std::list<llvm::Function*>::iterator si = scc.begin(), se = scc.end(); si != se; ++si) { funToScc.insert(std::make_pair(*si, scc)); } } std::list<llvm::Function*> dependsOnList = hierarchy.getTransitivelyCalledFunctions(function); std::set<llvm::Function*> dependsOn; dependsOn.insert(dependsOnList.begin(), dependsOnList.end()); dependsOn.insert(function); std::list<std::list<llvm::Function*> > dependsOnSccs; for (std::list<std::list<llvm::Function*> >::iterator i = sccs.begin(), e = sccs.end(); i != e; ++i) { std::list<llvm::Function*> scc = *i; for (std::list<llvm::Function*>::iterator fi = scc.begin(), fe = scc.end(); fi != fe; ++fi) { llvm::Function *f = *fi; if (dependsOn.find(f) != dependsOn.end()) { dependsOnSccs.push_back(scc); break; } } } // compute may/must info, propagated conditions, and compute loop exiting blocks for all functions std::map<llvm::Function*, MayMustMap> mmMap; std::map<llvm::Function*, std::set<llvm::GlobalVariable*> > funcMayZapDirect; std::map<llvm::Function*, TrueFalseMap> tfMap; std::map<llvm::Function*, std::set<llvm::BasicBlock*> > lebMap; std::map<llvm::Function*, ConditionMap> elcMap; for (std::set<llvm::Function*>::iterator df = dependsOn.begin(), dfe = dependsOn.end(); df != dfe; ++df) { llvm::Function *func = *df; std::pair<MayMustMap, std::set<llvm::GlobalVariable*> > tmp = getMayMustMap(func); mmMap.insert(std::make_pair(func, tmp.first)); funcMayZapDirect.insert(std::make_pair(func, tmp.second)); std::set<llvm::BasicBlock*> lcbs; if (onlyLoopConditions) { lcbs = getLoopConditionBlocks(func); lebMap.insert(std::make_pair(func, lcbs)); } if (propagateConditions) { tfMap.insert(std::make_pair(func, getConditionPropagationMap(func, lcbs))); } if (explicitizeLoopConditions) { elcMap.insert(std::make_pair(func, getExplicitizedLoopConditionMap(func))); } } // transitively close funcMayZapDirect std::map<llvm::Function*, std::set<llvm::GlobalVariable*> > funcMayZap; for (std::set<llvm::Function*>::iterator df = dependsOn.begin(), dfe = dependsOn.end(); df != dfe; ++df) { llvm::Function *func = *df; std::set<llvm::GlobalVariable*> funcTransZap; std::list<llvm::Function*> funcDependsOnList = hierarchy.getTransitivelyCalledFunctions(func); std::set<llvm::Function*> funcDependsOn; funcDependsOn.insert(funcDependsOnList.begin(), funcDependsOnList.end()); funcDependsOn.insert(func); for (std::set<llvm::Function*>::iterator depfi = funcDependsOn.begin(), depfe = funcDependsOn.end(); depfi != depfe; ++depfi) { llvm::Function *depf = *depfi; std::map<llvm::Function*, std::set<llvm::GlobalVariable*> >::iterator depfZap = funcMayZapDirect.find(depf); if (depfZap == funcMayZapDirect.end()) { std::cerr << "Could not find alias information (" << __FILE__ << ":" << __LINE__ << ")!" << std::endl; exit(9876); } funcTransZap.insert(depfZap->second.begin(), depfZap->second.end()); } funcMayZap.insert(std::make_pair(func, funcTransZap)); } // convert sccs separately unsigned int num = static_cast<unsigned int>(dependsOnSccs.size()); unsigned int currNum = 0; for (std::list<std::list<llvm::Function*> >::iterator scci = dependsOnSccs.begin(), scce = dependsOnSccs.end(); scci != scce; ++scci) { std::list<llvm::Function*> scc = *scci; std::list<ref<Rule> > allRules; std::list<ref<Rule> > allCondensedRules; std::list<ref<Rule> > allKittelizedRules; std::list<ref<Rule> > allSlicedRules; if (debug) { std::cout << "========================================" << std::endl; } if ((!complexityTuples && !uniformComplexityTuples) || debug) { std::cout << "///*** " << getPartNumber(++currNum, num) << '_' << getSccName(scc) << " ***///" << std::endl; } std::set<llvm::Function*> sccSet; sccSet.insert(scc.begin(), scc.end()); std::set<std::string> complexityLHSs; for (std::list<llvm::Function*>::iterator fi = scc.begin(), fe = scc.end(); fi != fe; ++fi) { llvm::Function *curr = *fi; Converter converter(boolType, assumeIsControl, selectIsControl, onlyMultiPredIsControl, boundedIntegers, unsignedEncoding, onlyLoopConditions, divisionConstraintType, bitwiseConditions, complexityTuples || uniformComplexityTuples); std::map<llvm::Function*, MayMustMap>::iterator tmp1 = mmMap.find(curr); if (tmp1 == mmMap.end()) { std::cerr << "Could not find alias information (" << __FILE__ << ":" << __LINE__ << ")!" << std::endl; exit(9876); } MayMustMap curr_mmMap = tmp1->second; std::map<llvm::Function*, TrueFalseMap>::iterator tmp2 = tfMap.find(curr); TrueFalseMap curr_tfMap; if (tmp2 != tfMap.end()) { curr_tfMap = tmp2->second; } std::map<llvm::Function*, std::set<llvm::BasicBlock*> >::iterator tmp3 = lebMap.find(curr); std::set<llvm::BasicBlock*> curr_leb; if (tmp3 != lebMap.end()) { curr_leb = tmp3->second; } std::map<llvm::Function*, ConditionMap>::iterator tmp4 = elcMap.find(curr); ConditionMap curr_elcMap; if (tmp4 != elcMap.end()) { curr_elcMap = tmp4->second; } converter.phase1(curr, sccSet, curr_mmMap, funcMayZap, curr_tfMap, curr_leb, curr_elcMap); converter.phase2(curr, sccSet, curr_mmMap, funcMayZap, curr_tfMap, curr_leb, curr_elcMap); std::list<ref<Rule> > rules = converter.getRules(); std::list<ref<Rule> > condensedRules = converter.getCondensedRules(); std::list<ref<Rule> > kittelizedRules = kittelize(condensedRules, smtSolver); Slicer slicer(curr, converter.getPhiVariables()); std::list<ref<Rule> > slicedRules; if (noSlicing) { slicedRules = kittelizedRules; } else { slicedRules = slicer.sliceUsage(kittelizedRules); slicedRules = slicer.sliceConstraint(slicedRules); slicedRules = slicer.sliceDefined(slicedRules); slicedRules = slicer.sliceStillUsed(slicedRules, conservativeSlicing); slicedRules = slicer.sliceTrivialNondefConstraints(slicedRules); slicedRules = slicer.sliceDuplicates(slicedRules); } if (boundedIntegers) { slicedRules = kittelize(addBoundConstraints(slicedRules, converter.getBitwidthMap(), unsignedEncoding), smtSolver); } if (debug) { allRules.insert(allRules.end(), rules.begin(), rules.end()); allCondensedRules.insert(allCondensedRules.end(), condensedRules.begin(), condensedRules.end()); allKittelizedRules.insert(allKittelizedRules.end(), kittelizedRules.begin(), kittelizedRules.end()); } if (simplifyConds) { slicedRules = simplifyConstraints(slicedRules); } allSlicedRules.insert(allSlicedRules.end(), slicedRules.begin(), slicedRules.end()); if (complexityTuples || uniformComplexityTuples) { std::set<std::string> tmpLHSs = converter.getComplexityLHSs(); complexityLHSs.insert(tmpLHSs.begin(), tmpLHSs.end()); } } if (debug) { std::cout << "========================================" << std::endl; for (std::list<ref<Rule> >::iterator i = allRules.begin(), e = allRules.end(); i != e; ++i) { ref<Rule> tmp = *i; std::cout << tmp->toString() << std::endl; } std::cout << "========================================" << std::endl; for (std::list<ref<Rule> >::iterator i = allCondensedRules.begin(), e = allCondensedRules.end(); i != e; ++i) { ref<Rule> tmp = *i; std::cout << tmp->toString() << std::endl; } std::cout << "========================================" << std::endl; for (std::list<ref<Rule> >::iterator i = allKittelizedRules.begin(), e = allKittelizedRules.end(); i != e; ++i) { ref<Rule> tmp = *i; std::cout << tmp->toString() << std::endl; } std::cout << "========================================" << std::endl; } if (complexityTuples) { printComplexityTuples(allSlicedRules, complexityLHSs, std::cout); } else if (uniformComplexityTuples) { std::ostringstream startfun; startfun << "eval_" << getSccName(scc) << "_start"; std::string name = startfun.str(); printUniformComplexityTuples(allSlicedRules, complexityLHSs, name, std::cout); } else if (t2output) { std::string startFun = "eval_" + getSccName(scc) + "_start"; printT2System(allSlicedRules, startFun, std::cout); } else { for (std::list<ref<Rule> >::iterator i = allSlicedRules.begin(), e = allSlicedRules.end(); i != e; ++i) { ref<Rule> tmp = *i; std::cout << tmp->toKittelString() << std::endl; } } } return 0; }