mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
[yul-phaser] Phaser: Refactor object creation in runAlgorithm() into a set of factories
This commit is contained in:
parent
25e81f6bd3
commit
2d177c7623
@ -68,10 +68,77 @@ ostream& phaser::operator<<(ostream& _outputStream, Algorithm _algorithm)
|
|||||||
return _outputStream;
|
return _outputStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace
|
GeneticAlgorithmFactory::Options GeneticAlgorithmFactory::Options::fromCommandLine(po::variables_map const& _arguments)
|
||||||
{
|
{
|
||||||
|
return {
|
||||||
|
_arguments["algorithm"].as<Algorithm>(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
CharStream loadSource(string const& _sourcePath)
|
unique_ptr<GeneticAlgorithm> GeneticAlgorithmFactory::build(
|
||||||
|
Options const& _options,
|
||||||
|
size_t _populationSize,
|
||||||
|
size_t _minChromosomeLength,
|
||||||
|
size_t _maxChromosomeLength
|
||||||
|
)
|
||||||
|
{
|
||||||
|
assert(_populationSize > 0);
|
||||||
|
|
||||||
|
switch (_options.algorithm)
|
||||||
|
{
|
||||||
|
case Algorithm::Random:
|
||||||
|
return make_unique<RandomAlgorithm>(RandomAlgorithm::Options{
|
||||||
|
/* elitePoolSize = */ 1.0 / _populationSize,
|
||||||
|
/* minChromosomeLength = */ _minChromosomeLength,
|
||||||
|
/* maxChromosomeLength = */ _maxChromosomeLength,
|
||||||
|
});
|
||||||
|
case Algorithm::GEWEP:
|
||||||
|
return make_unique<GenerationalElitistWithExclusivePools>(GenerationalElitistWithExclusivePools::Options{
|
||||||
|
/* mutationPoolSize = */ 0.25,
|
||||||
|
/* crossoverPoolSize = */ 0.25,
|
||||||
|
/* randomisationChance = */ 0.9,
|
||||||
|
/* deletionVsAdditionChance = */ 0.5,
|
||||||
|
/* percentGenesToRandomise = */ 1.0 / _maxChromosomeLength,
|
||||||
|
/* percentGenesToAddOrDelete = */ 1.0 / _maxChromosomeLength,
|
||||||
|
});
|
||||||
|
default:
|
||||||
|
assertThrow(false, solidity::util::Exception, "Invalid Algorithm value.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unique_ptr<FitnessMetric> FitnessMetricFactory::build(
|
||||||
|
Program _program
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return make_unique<ProgramSize>(move(_program), RepetitionCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
Population PopulationFactory::build(
|
||||||
|
shared_ptr<FitnessMetric> _fitnessMetric
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return Population::makeRandom(
|
||||||
|
move(_fitnessMetric),
|
||||||
|
PopulationSize,
|
||||||
|
MinChromosomeLength,
|
||||||
|
MaxChromosomeLength
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
ProgramFactory::Options ProgramFactory::Options::fromCommandLine(po::variables_map const& _arguments)
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
_arguments["input-file"].as<string>(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Program ProgramFactory::build(Options const& _options)
|
||||||
|
{
|
||||||
|
CharStream sourceCode = loadSource(_options.inputFile);
|
||||||
|
return Program::load(sourceCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
CharStream ProgramFactory::loadSource(string const& _sourcePath)
|
||||||
{
|
{
|
||||||
assertThrow(boost::filesystem::exists(_sourcePath), InvalidProgram, "Source file does not exist");
|
assertThrow(boost::filesystem::exists(_sourcePath), InvalidProgram, "Source file does not exist");
|
||||||
|
|
||||||
@ -79,8 +146,6 @@ CharStream loadSource(string const& _sourcePath)
|
|||||||
return CharStream(sourceCode, _sourcePath);
|
return CharStream(sourceCode, _sourcePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
int Phaser::main(int _argc, char** _argv)
|
int Phaser::main(int _argc, char** _argv)
|
||||||
{
|
{
|
||||||
CommandLineParsingResult parsingResult = parseCommandLine(_argc, _argv);
|
CommandLineParsingResult parsingResult = parseCommandLine(_argc, _argv);
|
||||||
@ -89,10 +154,7 @@ int Phaser::main(int _argc, char** _argv)
|
|||||||
|
|
||||||
initialiseRNG(parsingResult.arguments);
|
initialiseRNG(parsingResult.arguments);
|
||||||
|
|
||||||
runAlgorithm(
|
runAlgorithm(parsingResult.arguments);
|
||||||
parsingResult.arguments["input-file"].as<string>(),
|
|
||||||
parsingResult.arguments["algorithm"].as<Algorithm>()
|
|
||||||
);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,46 +229,22 @@ void Phaser::initialiseRNG(po::variables_map const& _arguments)
|
|||||||
cout << "Random seed: " << seed << endl;
|
cout << "Random seed: " << seed << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Phaser::runAlgorithm(string const& _sourcePath, Algorithm _algorithm)
|
void Phaser::runAlgorithm(po::variables_map const& _arguments)
|
||||||
{
|
{
|
||||||
constexpr size_t populationSize = 20;
|
auto programOptions = ProgramFactory::Options::fromCommandLine(_arguments);
|
||||||
constexpr size_t minChromosomeLength = 12;
|
auto algorithmOptions = GeneticAlgorithmFactory::Options::fromCommandLine(_arguments);
|
||||||
constexpr size_t maxChromosomeLength = 30;
|
|
||||||
|
|
||||||
CharStream sourceCode = loadSource(_sourcePath);
|
Program program = ProgramFactory::build(programOptions);
|
||||||
shared_ptr<FitnessMetric> fitnessMetric = make_shared<ProgramSize>(Program::load(sourceCode), 5);
|
unique_ptr<FitnessMetric> fitnessMetric = FitnessMetricFactory::build(move(program));
|
||||||
auto population = Population::makeRandom(
|
Population population = PopulationFactory::build(move(fitnessMetric));
|
||||||
fitnessMetric,
|
|
||||||
populationSize,
|
unique_ptr<GeneticAlgorithm> geneticAlgorithm = GeneticAlgorithmFactory::build(
|
||||||
minChromosomeLength,
|
algorithmOptions,
|
||||||
maxChromosomeLength
|
population.individuals().size(),
|
||||||
|
PopulationFactory::MinChromosomeLength,
|
||||||
|
PopulationFactory::MaxChromosomeLength
|
||||||
);
|
);
|
||||||
|
|
||||||
AlgorithmRunner algorithmRunner(population, AlgorithmRunner::Options{}, cout);
|
AlgorithmRunner algorithmRunner(population, AlgorithmRunner::Options{}, cout);
|
||||||
switch (_algorithm)
|
algorithmRunner.run(*geneticAlgorithm);
|
||||||
{
|
|
||||||
case Algorithm::Random:
|
|
||||||
{
|
|
||||||
RandomAlgorithm algorithm({
|
|
||||||
/* elitePoolSize = */ 1.0 / populationSize,
|
|
||||||
/* minChromosomeLength = */ minChromosomeLength,
|
|
||||||
/* maxChromosomeLength = */ maxChromosomeLength,
|
|
||||||
});
|
|
||||||
algorithmRunner.run(algorithm);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Algorithm::GEWEP:
|
|
||||||
{
|
|
||||||
GenerationalElitistWithExclusivePools algorithm({
|
|
||||||
/* mutationPoolSize = */ 0.25,
|
|
||||||
/* crossoverPoolSize = */ 0.25,
|
|
||||||
/* randomisationChance = */ 0.9,
|
|
||||||
/* deletionVsAdditionChance = */ 0.5,
|
|
||||||
/* percentGenesToRandomise = */ 1.0 / maxChromosomeLength,
|
|
||||||
/* percentGenesToAddOrDelete = */ 1.0 / maxChromosomeLength,
|
|
||||||
});
|
|
||||||
algorithmRunner.run(algorithm);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,8 @@
|
|||||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
/**
|
/**
|
||||||
* Contains the main class that controls yul-phaser based on command-line parameters.
|
* Contains the main class that controls yul-phaser based on command-line parameters and
|
||||||
|
* associated factories for building instances of phaser's components.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
@ -23,12 +24,25 @@
|
|||||||
#include <boost/program_options.hpp>
|
#include <boost/program_options.hpp>
|
||||||
|
|
||||||
#include <istream>
|
#include <istream>
|
||||||
|
#include <memory>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
namespace solidity::langutil
|
||||||
|
{
|
||||||
|
|
||||||
|
class CharStream;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
namespace solidity::phaser
|
namespace solidity::phaser
|
||||||
{
|
{
|
||||||
|
|
||||||
|
class FitnessMetric;
|
||||||
|
class GeneticAlgorithm;
|
||||||
|
class Population;
|
||||||
|
class Program;
|
||||||
|
|
||||||
enum class Algorithm
|
enum class Algorithm
|
||||||
{
|
{
|
||||||
Random,
|
Random,
|
||||||
@ -38,10 +52,78 @@ enum class Algorithm
|
|||||||
std::istream& operator>>(std::istream& _inputStream, solidity::phaser::Algorithm& _algorithm);
|
std::istream& operator>>(std::istream& _inputStream, solidity::phaser::Algorithm& _algorithm);
|
||||||
std::ostream& operator<<(std::ostream& _outputStream, solidity::phaser::Algorithm _algorithm);
|
std::ostream& operator<<(std::ostream& _outputStream, solidity::phaser::Algorithm _algorithm);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds and validates instances of @a GeneticAlgorithm and its derived classes.
|
||||||
|
*/
|
||||||
|
class GeneticAlgorithmFactory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct Options
|
||||||
|
{
|
||||||
|
Algorithm algorithm;
|
||||||
|
|
||||||
|
static Options fromCommandLine(boost::program_options::variables_map const& _arguments);
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::unique_ptr<GeneticAlgorithm> build(
|
||||||
|
Options const& _options,
|
||||||
|
size_t _populationSize,
|
||||||
|
size_t _minChromosomeLength,
|
||||||
|
size_t _maxChromosomeLength
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds and validates instances of @a FitnessMetric and its derived classes.
|
||||||
|
*/
|
||||||
|
class FitnessMetricFactory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static constexpr size_t RepetitionCount = 5;
|
||||||
|
|
||||||
|
static std::unique_ptr<FitnessMetric> build(
|
||||||
|
Program _program
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds and validates instances of @a Population.
|
||||||
|
*/
|
||||||
|
class PopulationFactory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static constexpr size_t PopulationSize = 20;
|
||||||
|
static constexpr size_t MinChromosomeLength = 12;
|
||||||
|
static constexpr size_t MaxChromosomeLength = 30;
|
||||||
|
|
||||||
|
static Population build(
|
||||||
|
std::shared_ptr<FitnessMetric> _fitnessMetric
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds and validates instances of @a Program.
|
||||||
|
*/
|
||||||
|
class ProgramFactory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct Options
|
||||||
|
{
|
||||||
|
std::string inputFile;
|
||||||
|
|
||||||
|
static Options fromCommandLine(boost::program_options::variables_map const& _arguments);
|
||||||
|
};
|
||||||
|
|
||||||
|
static Program build(Options const& _options);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static langutil::CharStream loadSource(std::string const& _sourcePath);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main class that controls yul-phaser based on command-line parameters. The class is responsible
|
* Main class that controls yul-phaser based on command-line parameters. The class is responsible
|
||||||
* for command-line parsing, initialisation of global objects (like the random number generator),
|
* for command-line parsing, initialisation of global objects (like the random number generator),
|
||||||
* creating instances of main components and feeding them into @a AlgorithmRunner.
|
* creating instances of main components using factories and feeding them into @a AlgorithmRunner.
|
||||||
*/
|
*/
|
||||||
class Phaser
|
class Phaser
|
||||||
{
|
{
|
||||||
@ -58,7 +140,7 @@ private:
|
|||||||
static CommandLineParsingResult parseCommandLine(int _argc, char** _argv);
|
static CommandLineParsingResult parseCommandLine(int _argc, char** _argv);
|
||||||
static void initialiseRNG(boost::program_options::variables_map const& _arguments);
|
static void initialiseRNG(boost::program_options::variables_map const& _arguments);
|
||||||
|
|
||||||
static void runAlgorithm(std::string const& _sourcePath, Algorithm _algorithm);
|
static void runAlgorithm(boost::program_options::variables_map const& _arguments);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user