Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add QueueManager (Juan Chavez's WAVES project) #414

Open
wants to merge 21 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions demos/SpatialCoop2017/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ CFLAGS_nat_debug := -g $(CFLAGS_all)

# Emscripten compiler information
CXX_web := emcc
OFLAGS_web_all := -s "EXTRA_EXPORTED_RUNTIME_METHODS=['ccall', 'cwrap']" -s TOTAL_MEMORY=67108864 --js-library $(EMP_DIR)/emp/web/library_emp.js -s EXPORTED_FUNCTIONS="['_main', '_empCppCallback']" -s DISABLE_EXCEPTION_CATCHING=1 -s NO_EXIT_RUNTIME=1 #--embed-file configs
OFLAGS_web_all := -s "EXTRA_EXPORTED_RUNTIME_METHODS=['ccall', 'cwrap']" -s TOTAL_MEMORY=67108864 --js-library $(EMP_DIR)/emp/web/library_emp.js -s EXPORTED_FUNCTIONS="['_main', '_empCppCallback', '_empDoCppCallback']" -s DISABLE_EXCEPTION_CATCHING=1 -s NO_EXIT_RUNTIME=1 -s WASM=0 #--embed-file configs
OFLAGS_web := -Oz -DNDEBUG
OFLAGS_web_debug := -g4 -pedantic -Wno-dollar-in-identifier-extension
OFLAGS_web_debug := -pedantic -Wno-dollar-in-identifier-extension

CFLAGS_web := $(CFLAGS_all) $(OFLAGS_web) $(OFLAGS_web_all)
CFLAGS_web_debug := $(CFLAGS_all) $(OFLAGS_web_debug) $(OFLAGS_web_all)
Expand Down
13 changes: 7 additions & 6 deletions demos/SpatialCoop2017/source/SimplePDWorld.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,16 +111,17 @@ class SimplePDWorld {

void Reset() { Setup(r,u,N,E); }

void Run(size_t steps=-1) {
if (steps > E) steps = E;
// Run the organisms!
size_t end_epoch = epoch + steps;
while (epoch < end_epoch) {
void Run(size_t steps=1) {
emilydolson marked this conversation as resolved.
Show resolved Hide resolved

for (size_t i = 0; i < steps; i++) {
for (size_t o = 0; o < N; o++) Repro();
epoch++;
}
}

void RunStep() {
for (size_t o = 0; o < N; o++) Repro();
}

size_t CountCoop();
void PrintNeighborInfo(std::ostream & os);
};
Expand Down
324 changes: 132 additions & 192 deletions demos/SpatialCoop2017/source/web/SimplePDWorld-web.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
// This file is part of Project Name
// Copyright (C) Michigan State University, 2017.
// Released under the MIT Software license; see doc/LICENSE
// PD WORLD EXAMPLE

#include "emp/web/web.hpp"
#include <functional>
#include <string>

#include "emp/prefab/QueueManager.hpp"
#include "../SimplePDWorld.hpp"
#include "emp/web/web.hpp"

namespace UI = emp::web;

Expand All @@ -15,210 +20,145 @@ SimplePDWorld world;
int cur_x = -1;
int cur_y = -1;

std::function<emp::SettingConfig()> SetupConfig = [](){
emp::SettingConfig config;
config.AddSetting<double>("r") = {world.GetR()};
config.AddSetting<double>("u") = {world.GetU()};
config.AddSetting<size_t>("N") = {world.GetN()};
config.AddSetting<size_t>("E") = {world.GetE()};

return config;
};

emp::SettingConfig config = SetupConfig();
emp::QueueManager run_list(config);

void DrawCanvas() {
UI::Canvas canvas = doc.Canvas("canvas");
canvas.Clear("black");
UI::Canvas canvas = doc.Canvas("canvas");
canvas.Clear("black");

const emp::vector<Org> & pop = world.GetPop();
const emp::vector<Org>& pop = world.GetPop();

if (cur_x >= 0) {
canvas.Circle(cur_x, cur_y, world_size*world.GetR(), "pink");
}
if (cur_x >= 0) {
canvas.Circle(cur_x, cur_y, world_size * world.GetR(), "pink");
}

emilydolson marked this conversation as resolved.
Show resolved Hide resolved
for (const Org & org : pop) {
if (org.coop) {
canvas.Circle(org.x*world_size, org.y*world_size, 2, "blue", "#8888FF");
} else {
canvas.Circle(org.x*world_size, org.y*world_size, 2, "#FF8888", "red");
for (const Org& org : pop) {
if (org.coop) {
canvas.Circle(org.x * world_size, org.y * world_size, 2, "blue", "#8888FF");
} else {
canvas.Circle(org.x * world_size, org.y * world_size, 2, "#FF8888", "red");
}
}
}

doc.Text("ud_text").Redraw();
doc.Text("ud_text").Redraw();
}

void CanvasClick(int x, int y) {
cur_x = x;
cur_y = y;
DrawCanvas();
cur_x = x;
cur_y = y;
DrawCanvas();
}

struct RunInfo {
size_t id;

double r;
double u;
size_t N;
size_t E;

size_t cur_epoch;
size_t num_coop;
size_t num_defect;

RunInfo(size_t _id, double _r, double _u, size_t _N, size_t _E)
: id(_id), r(_r), u(_u), N(_N), E(_E)
, cur_epoch(0), num_coop(0), num_defect(0)
{ ; }
};

struct RunList {
emp::vector<RunInfo> runs;
size_t cur_run = 0;

void AddRun(double r, double u, size_t N, size_t E) {
size_t id = runs.size();
runs.emplace_back(id, r, u, N, E);
}

bool Active() const { return cur_run < runs.size(); }
};
void TogglePlay() {
auto& anim = doc.Animate("anim_world");
anim.ToggleActive();
auto but = doc.Button("start_but");
if (anim.GetActive())
but.SetLabel("Pause");
else
but.SetLabel("Start");

but = doc.Button("run_but");
if (anim.GetActive())
but.SetLabel("Stop");
else
but.SetLabel("Fast Forward!");
}

RunList run_list;
int anim_step = 1;

void TogglePlay()
{
auto & anim = doc.Animate("anim_world");
anim.ToggleActive();
auto but = doc.Button("start_but");
if (anim.GetActive()) but.SetLabel("Pause");
else but.SetLabel("Start");

but = doc.Button("run_but");
if (anim.GetActive()) but.SetLabel("Stop");
else but.SetLabel("Fast Forward!");
}

int main()
{
doc << "<h2>Spatial Prisoner's Dilema</h2>";
auto canvas = doc.AddCanvas(world_size, world_size, "canvas");
// canvas.On("click", CanvasClick);
auto & anim = doc.AddAnimation("anim_world", [](){
if (run_list.Active()) {
size_t id = run_list.cur_run;
auto & run = run_list.runs[id];
if (run.cur_epoch == 0) { // Are we starting a new run?
world.Setup(run.r, run.u, run.N, run.E);
int main() {

std::function<std::string()> coop_func = []() { return std::to_string(world.CountCoop()); };
std::function<std::string()> defect_func = []() { return std::to_string(run_list.FrontRun().runinfo_config.GetValue<size_t>("N") - world.CountCoop()); };

run_list.AddMetric(coop_func, "Num Coop");
run_list.AddMetric(defect_func, "Num Defect");
doc << "<h2>Spatial Prisoner's Dillemma</h2>";
auto canvas = doc.AddCanvas(world_size, world_size, "canvas");
// canvas.On("click", CanvasClick);
doc.AddAnimation("anim_world", []() {
// if queue has runs
if (!run_list.IsEmpty()) {
emp::QueueManager::RunInfo & run = run_list.FrontRun(); // Referencing current run
if (run.GetEpoch() == 0) { // Are we starting a new run?
world.Setup(run.runinfo_config.GetValue<double>("r"), run.runinfo_config.GetValue<double>("u"), run.runinfo_config.GetValue<size_t>("N"), run.runinfo_config.GetValue<size_t>("E"));
DrawCanvas();
}
run.IncEpoch(anim_step);
}
world.Run(anim_step);
DrawCanvas();
}
}
world.Run(anim_step);
DrawCanvas();
if (run_list.Active()) {
size_t id = run_list.cur_run;
size_t cur_epoch = world.GetEpoch();
if (run_list.runs[id].E <= cur_epoch) { // Are we done with this run?
run_list.cur_run++;
}
run_list.runs[id].cur_epoch = cur_epoch;
run_list.runs[id].num_coop = world.CountCoop();
run_list.runs[id].num_defect = run_list.runs[id].N - run_list.runs[id].num_coop;

auto result_tab = doc.Table("result_tab");
result_tab.Freeze();
result_tab.GetCell(id+1,5).ClearChildren() << cur_epoch;
result_tab.GetCell(id+1,6).ClearChildren() << run_list.runs[id].num_coop;
result_tab.GetCell(id+1,7).ClearChildren() << run_list.runs[id].num_defect;
result_tab.Activate();
}
} );

doc << "<br>";
doc.AddButton([&anim](){
anim_step = 1;
TogglePlay();
}, "Play", "start_but");
doc.AddButton([](){ world.Run(1); DrawCanvas(); }, "Step", "step_but");
doc.AddButton([&anim](){
anim_step = 100;
TogglePlay();
}, "Fast Forward!", "run_but");
doc.AddButton([](){ world.Reset(); DrawCanvas(); }, "Randomize", "rand_but");
auto ud_text = doc.AddText("ud_text");
ud_text << " Epoch = " << UI::Live(world.epoch);

doc << "<br>Radius (<i>r</i>) = ";
doc.AddTextArea([](const std::string & str){
double r = emp::from_string<double>(str);
world.SetR(r);
}, "r_set").SetText(emp::to_string(world.GetR()));

doc << "<br>cost/benefit ratio (<i>u</i>) = ";
doc.AddTextArea([](const std::string & str){
double u = emp::from_string<double>(str);
world.SetU(u);
}, "u_set").SetText(emp::to_string(world.GetU()));


doc << "<br>Population Size (<i>N</i>) = ";
doc.AddTextArea([](const std::string & str){
size_t N = emp::from_string<size_t>(str);
world.SetN(N);
}, "N_set").SetText(emp::to_string(world.GetN()));


doc << "<br>Num Epochs on Run (<i>E</i>) = ";
doc.AddTextArea([](const std::string & str){
size_t E = emp::from_string<size_t>(str);
world.SetE(E);
}, "E_set").SetText(emp::to_string(world.GetE()));

doc << "<br>"
<< "NOTE: You must hit 'Randomize' after changing any parameters for them to take effect."
<< "<hr>"
<< "<h3>Full Runs</h3>"
<< "You can perform many runs at once with the same configuration. "
<< "Setup the configuration above, choose the number of runs, and queue them up (as many as you like, even with different parameters). "
<< "The next time you start (or fast forward) above, it will start working its way through the queued runs. "
<< "<br>"
<< "How many runs? ";

auto run_input = doc.AddTextArea([](const std::string & str){
size_t num_runs = emp::from_string<size_t>(str);
world.SetNumRuns(num_runs);
}, "run_count");
run_input.SetText(emp::to_string(world.GetNumRuns()));

doc.AddButton([run_input](){
//size_t num_runs = emp::from_string<size_t>(run_input.GetText());
size_t num_runs = world.GetNumRuns();
auto result_tab = doc.Table("result_tab");
for (int run_id = 0; run_id < num_runs; run_id++) {
run_list.AddRun(world.GetR(), world.GetU(), world.GetN(), world.GetE());

// Update the table.
int line_id = result_tab.GetNumRows();
result_tab.Rows(line_id+1);
result_tab.GetCell(line_id, 0) << run_id;
result_tab.GetCell(line_id, 1) << world.GetR();
result_tab.GetCell(line_id, 2) << world.GetU();
result_tab.GetCell(line_id, 3) << world.GetN();
result_tab.GetCell(line_id, 4) << world.GetE();
result_tab.GetCell(line_id, 5) << "Waiting..."; // world.GetE();
result_tab.GetCell(line_id, 6) << "Waiting..."; // world.CountCoop();
result_tab.GetCell(line_id, 7) << "Waiting..."; // (world.GetN() - world.CountCoop());

// Draw the new table.
result_tab.CellsCSS("border", "1px solid black");
result_tab.Redraw();
}
}, "Queue", "queue_but");

doc << "<br>";

auto result_tab = doc.AddTable(1,8, "result_tab");
result_tab.SetCSS("border-collapse", "collapse");
result_tab.SetCSS("border", "3px solid black");
result_tab.CellsCSS("border", "1px solid black");
if (!run_list.IsEmpty()) {
run_list.Update(); //calculations for table
}
});

doc << "<br>";
doc.AddButton([]() {
anim_step = 1;
TogglePlay();
}, "Play", "start_but");
doc.AddButton([]() { world.Run(1); DrawCanvas(); }, "Step", "step_but");
doc.AddButton([]() {
anim_step = 100;
TogglePlay();
}, "Fast Forward!", "run_but");
doc.AddButton([]() { world.Reset(); DrawCanvas(); }, "Randomize", "rand_but");
auto ud_text = doc.AddText("ud_text");
ud_text << " Epoch = " << UI::Live(world.epoch);

doc << "<br>Radius (<i>r</i>) = ";
doc.AddTextArea([](const std::string& str) {
double r = emp::from_string<double>(str);
world.SetR(r);
}, "r_set").SetText(emp::to_string(world.GetR()));

doc << "<br>cost/benefit ratio (<i>u</i>) = ";
doc.AddTextArea([](const std::string& str) {
double u = emp::from_string<double>(str);
world.SetU(u);
}, "u_set").SetText(emp::to_string(world.GetU()));

doc << "<br>Population Size (<i>N</i>) = ";
doc.AddTextArea([](const std::string& str) {
size_t N = emp::from_string<size_t>(str);
world.SetN(N);
}, "N_set").SetText(emp::to_string(world.GetN()));

doc << "<br>Num Epochs on Run (<i>E</i>) = ";
doc.AddTextArea([](const std::string& str) {
size_t E = emp::from_string<size_t>(str);
world.SetE(E);
}, "E_set").SetText(emp::to_string(world.GetE()));

doc << "<br>"
<< "NOTE: You must hit 'Randomize' after changing any parameters for them to take effect."
<< "<hr>"
<< "<h3>Full Runs</h3>"
<< "You can perform many runs at once with the same configuration. "
<< "Setup the configuration above, choose the number of runs, and queue them up (as many as you like, even with different parameters). "
<< "The next time you start (or fast forward) above, it will start working its way through the queued runs. "
<< "<br>"
<< "How many runs? ";

run_list.AddQueueButton([](){return SetupConfig();}, [](){return world.GetE();});

doc << "<br>";

doc << run_list.GetDiv();
run_list.BuildTable();

result_tab.GetCell(0,0).SetHeader() << "ID";
result_tab.GetCell(0,1).SetHeader() << "<i>r</i>";
result_tab.GetCell(0,2).SetHeader() << "<i>u</i>";
result_tab.GetCell(0,3).SetHeader() << "<i>N</i>";
result_tab.GetCell(0,4).SetHeader() << "<i>E</i>";
result_tab.GetCell(0,5).SetHeader() << "Epoch";
result_tab.GetCell(0,6).SetHeader() << "Num Coop";
result_tab.GetCell(0,7).SetHeader() << "Num Defect";

DrawCanvas();
}
DrawCanvas();
}
Loading