//perform dry-run state save: //determines exactly how many bytes are needed to save state for this cartridge, //as amount varies per game (eg different RAM sizes, etc.) void System::serialize_init() { serializer s; unsigned signature = 0, version = 0; char hash[64], description[512]; s.integer(signature); s.integer(version); s.array(hash); s.array(description); serialize_all(s); serialize_size = s.size(); }
serializer System::serialize() { serializer s(serialize_size); unsigned signature = 0x31545342, version = bsnesSerializerVersion, crc32 = cartridge.crc32(); char description[512]; memset(&description, 0, sizeof description); s.integer(signature); s.integer(version); s.integer(crc32); s.array(description); serialize_all(s); return s; }
serializer System::serialize() { serializer s(serialize_size); unsigned signature = 0x31545342, version = Info::SerializerVersion; char hash[64], description[512]; memcpy(&hash, (const char*)cartridge.sha256(), 64); memset(&description, 0, sizeof description); s.integer(signature); s.integer(version); s.array(hash); s.array(description); serialize_all(s); return s; }
bool System::unserialize(serializer& s) { unsigned signature, version; char hash[64], description[512]; s.integer(signature); s.integer(version); s.array(hash); s.array(description); if(signature != 0x31545342) return false; if(version != Info::SerializerVersion) return false; power(); serialize_all(s); return true; }
void Metropolis::auto_adapt() { if(outputLevel >= EngineOutputLevel::Normal) { std::cerr << timestamp() << " Starting automatic adaptation" << std::endl; } std::vector<STM::ParName> parNames (parameters.names()); // disable thinning for the adaptation phase int oldThin = thinSize; thinSize = 1; regression_adapt(10, 100); // use the first two loops to try a regression approach int nLoops = 2; while(nLoops < minAdaptationLoops or ((not parameters.adapted()) and nLoops < maxAdaptationLoops)) { nLoops++; parameters.set_acceptance_rates(do_sample(adaptationSampleSize)); for(const auto & par : parNames) { double ratio; if(parameters.acceptance_rate(par) == 0) ratio = 1e-2; else ratio = parameters.acceptance_rate(par) / parameters.optimal_acceptance_rate(); parameters.set_sampler_variance(par, ratio*parameters.sampler_variance(par)); } if(outputLevel >= EngineOutputLevel::Talkative) { std::cerr << "\n " << timestamp() << " iter " << parameters.iteration() << "\n"; parameters.print_adaptation(isatty(fileno(stderr)), 2); // std::cerr << " " << parameters.str_acceptance_rates(isatty(fileno(stderr))) << "\n"; // std::cerr << " sampler variance:\n"; // std::cerr << " " << parameters.str_sampling_variance(isatty(fileno(stderr))) << std::endl; } currentSamples.clear(); if(saveResumeData) serialize_all(); } parameters.reset(); // adaptation samples are not included in the burnin period if(outputLevel >= EngineOutputLevel::Normal) { std::cerr << timestamp() << " Adaptation completed successfully" << std::endl; } thinSize = oldThin; }
bool System::unserialize(serializer &s) { unsigned signature, version, crc32; char description[512]; s.integer(signature); s.integer(version); s.integer(crc32); s.array(description); if(signature != 0x31545342) return false; if(version != bsnesSerializerVersion) return false; //if(crc32 != cartridge.crc32()) return false; scheduler.init(); serialize_all(s); return true; }
Metropolis::Metropolis(const std::vector<STMParameters::ParameterSettings> & inits, STMOutput::OutputQueue * const queue, STMLikelihood::Likelihood * const lhood, EngineOutputLevel outLevel, STMOutput::OutputOptions outOpt, int thin, int burnin, bool doDIC, bool rngSetSeed, int rngSeed) : // objects that are not owned by the object outputQueue(queue), likelihood(lhood), // objects that we own or share parameters(inits), rngSetSeed(rngSetSeed), rngSeed(rngSeed), burnin(burnin), rng(gsl_rng_alloc(gsl_rng_mt19937), gsl_rng_free), outputLevel(outLevel), thinSize(thin), posteriorOptions(outOpt), computeDIC(doDIC), // the parameters below have default values with no support for changing them minAdaptationLoops(5), maxAdaptationLoops(25), adaptationSampleSize(500), outputBufferSize(500) { // check pointers if(!queue || !lhood) throw std::runtime_error("Metropolis: passed null pointer on construction"); if(thin < 1) throw std::runtime_error("Metropolis: thin interval must be greater than 0"); if(posteriorOptions.method() == STMOutput::OutputMethodType::STDOUT) saveResumeData = false; else saveResumeData = true; // compute the log likelihood for the initial conditions currentLL = likelihood->compute_log_likelihood(parameters); // initialize thetaBar with parameter names thetaBar.second = 0; for(auto p : parameters.names()) thetaBar.first[p] = 0; if(saveResumeData) serialize_all(); }
void Metropolis::run_sampler(int n) { set_up_rng(); if(not parameters.adapted()) auto_adapt(); int burninCompleted = parameters.iteration(); int numCompleted = 0; // for safety, always start by re-computing the current likelihood currentLL = likelihood->compute_log_likelihood(parameters); bool computeDevianceNow = false; while(numCompleted < n) { int sampleSize; if(burninCompleted < burnin) { sampleSize = ( (burnin - burninCompleted < outputBufferSize) ? (burnin - burninCompleted) : outputBufferSize); } else { sampleSize = ((n - numCompleted < outputBufferSize) ? (n - numCompleted) : outputBufferSize); computeDevianceNow = computeDIC; } currentSamples.reserve(sampleSize); if(computeDevianceNow) sampleDeviance.reserve(sampleSize); do_sample(sampleSize, computeDevianceNow); if(burninCompleted < burnin) { burninCompleted += sampleSize; } else { if(computeDIC) prepare_deviance(); // this function takes care of clearing the old vector STMOutput::OutputBuffer buffer (currentSamples, parameters.names(), STMOutput::OutputKeyType::posterior, posteriorOptions); outputQueue->push(buffer); // note that this may block if the queue is busy numCompleted += sampleSize; } currentSamples.clear(); if(saveResumeData) serialize_all(); /* if desired: some output with the current time */ if(outputLevel >= EngineOutputLevel::Normal) { if(numCompleted == 0) { std::cerr << timestamp() << " MCMC burnin iteration " << burninCompleted << " of " << burnin << std::endl; } else { std::cerr << timestamp() << " MCMC iteration " << numCompleted << " of " << n << std::endl; } } } // end of sampling; compute DIC and output if needed if(computeDIC) { STMParameters::STModelParameters tbarPars (parameters); for(const auto & p : thetaBar.first) tbarPars.update(p); double devThetaBar = -2.0 * likelihood->compute_log_likelihood(tbarPars); double pd = DBar.first - devThetaBar; double DIC = devThetaBar + 2.0 * pd; // now just save it all std::ostringstream dicOutput; dicOutput << "pD: " << pd << "\n"; dicOutput << "Mean deviance (d-bar): " << DBar.first << "\n"; dicOutput << "Deviance of mean (d(theta-bar)): " << devThetaBar << "\n"; dicOutput << "DIC: " << DIC << "\n"; STMOutput::OutputBuffer buffer (dicOutput.str(), STMOutput::OutputKeyType::dic, posteriorOptions); outputQueue->push(buffer); } if(saveResumeData) serialize_all(); }