#include <vector> #include <random> #include <cassert> #include <iostream> #include <iomanip> #include <stdexcept> #include <cstdio> #include "tclap/CmdLine.h" #include "benchmark.hpp" #include "latticeview.h" typedef unsigned short store_t; typedef double calc_t; typedef std::size_t size_t; typedef int sint_t; #include "hoshen_kopel_naive.cpp" template<typename T> void create_perc(T& field, calc_t const& p){ static std::mt19937_64 rand_gen(42); static std::uniform_real_distribution<calc_t> rand_num(0,1); for(auto& row : field){ for(auto& col : row) { if (rand_num(rand_gen) < p) col = 1; else col = 0; } } } #ifdef IMAGEMAGICK #define OUTPUT_EXT "png" #else #define IMAGEMAGICK false #define OUTPUT_EXT "ppm" #endif int main(int argc, char* argv[]){ //parse cmd args TCLAP::CmdLine cmd("Hoshen kopel", ' ', "0.1 alpha"); TCLAP::ValueArg<std::string> outputArg("o","output","Output file",false,std::string("output.") + OUTPUT_EXT,"string", cmd); TCLAP::ValueArg<size_t> dimArg("N","dim","lattice dim",false,100,"integral type", cmd); TCLAP::ValueArg<calc_t> probabilityArg("p","prop","occupation probability",false,0.59,"floating point", cmd); cmd.parse( argc, argv ); //initialize const size_t N = dimArg.getValue(); //grid size const calc_t p = probabilityArg.getValue(); // std::vector<std::vector<store_t>> field(N, std::vector<store_t>(N)); create_perc(field, p); //create random cluster BENCHMARK(hoshen_kopel_naive(field))(1000); //run algorithm if (outputArg.getValue() == "STDOUT") print_lattice_stdout(field); else { //parse output file extension std::string output = outputArg.getValue(); std::string output_ext = output.substr(output.find_last_of(".") + 1); std::string output_basename = output.substr(0, output.find_last_of(".")); if (!(output_ext == "ppm" || output_ext == "png") || output.find_last_of(".") == std::string::npos) throw std::invalid_argument("invalid file extension"); if (!IMAGEMAGICK && output_ext == "png") throw std::invalid_argument("png file extension not supported. compile with imagemagick support"); //export ppm file print_latticeV2(field,N,N,800,800, (output_basename+".ppm").c_str()); //convert to png if (output_ext == "png") { //call imagemagick std::ostringstream cmd; cmd << IMAGEMAGICK << ' ' << output_basename.c_str() << ".ppm " << output_basename.c_str() << ".png"; int exit_code = std::system(cmd.str().c_str()); if (exit_code) throw std::runtime_error(std::string("convert to png failed with error code ") + std::to_string(exit_code)); //delete ppm std::remove((output_basename+".ppm").c_str()); } } return 0; } // benchmark helper macro using std::chrono::system_clock; using std::chrono::duration; #define BENCHMARK(expr) \ [&] (std::size_t num_ops) { \ /* tic */ \ auto start = system_clock::now(); \ \ auto result = expr; \ for (int i=1; i< num_ops; i++) { \ result = expr; \ asm volatile("" : "+r" (result)); \ } \ \ /* toc */ \ auto end = system_clock::now(); \ \ auto d = duration<double>(end-start).count(); \ std::cout << "benchmark " << #expr \ << " " << d << std::endl; \ return duration<double>(end-start).count(); \ }