Woohoo! Good to see this officially released, finally. Now all we still need is the remaining symmetries to bring it up to par with 1.x, and then support for semi-totalistic rules à la 0.54+0.21i.
(Also, still waiting for that custom ASIC hardware.
)
drc wrote:Can you add what 1.0 had where you press q to quit?
Here's a patch that adds this:
Code: Select all
diff -ru apgmera-14b4/main.cpp playing-around-14b4/main.cpp
--- apgmera-14b4/main.cpp 2016-03-18 21:01:33.000000000 +0100
+++ playing-around-14b4/main.cpp 2016-03-18 22:51:02.113706700 +0100
@@ -8,6 +8,9 @@
#include <ctime>
#include <cmath>
#include <unistd.h>
+#include <sys/select.h>
+#include <termios.h>
+#include <stdio.h>
#ifdef USE_OPEN_MP
#include <omp.h>
@@ -25,6 +28,22 @@
#define APG_VERSION "v3.12"
+// determine whether there's a keystroke waiting
+int keyWaiting() {
+ struct timeval tv;
+ fd_set fds;
+
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+
+ FD_ZERO(&fds);
+ FD_SET(STDIN_FILENO, &fds); // STDIN_FILENO is 0
+
+ select(STDIN_FILENO+1, &fds, NULL, NULL, &tv);
+
+ return FD_ISSET(STDIN_FILENO, &fds);
+}
+
/*
* Produce a new seed based on the original seed, current time and PID:
*/
@@ -1624,7 +1643,7 @@
#ifdef USE_OPEN_MP
-void parallelSearch(int n, int m, std::string payoshaKey, std::string seed, int local_log) {
+bool parallelSearch(int n, int m, std::string payoshaKey, std::string seed, int local_log) {
SoupSearcher globalSoup;
@@ -1683,13 +1702,15 @@
}
std::cout << "----------------------------------------------------------------------" << std::endl;
}
+
+ return false;
}
#endif
-void runSearch(int n, std::string payoshaKey, std::string seed, int local_log, bool testing) {
+bool runSearch(int n, std::string payoshaKey, std::string seed, int local_log, bool testing) {
// Create an empty QuickLife universe:
lifealgo *imp2 = createUniverse("QuickLife");
@@ -1705,8 +1726,9 @@
long long i = 0;
bool finishedSearch = false;
+ bool quitByUser = false;
- while (finishedSearch == false) {
+ while ((finishedSearch == false) && (quitByUser == false)) {
std::ostringstream ss;
ss << i;
@@ -1721,9 +1743,15 @@
std::cout << i << " soups completed (" << (int) (10000.0 / ((double) (end-start) / CLOCKS_PER_SEC)) << " soups per second)." << std::endl;
start = clock();
+
+ if(keyWaiting()) {
+ char c = fgetc(stdin);
+ if ((c == 'q') || (c == 'Q'))
+ quitByUser = true;
+ }
}
- if (i % n == 0) {
+ if ((i % n == 0) || quitByUser) {
if (testing) {
finishedSearch = true;
} else {
@@ -1742,6 +1770,8 @@
}
}
+
+ return quitByUser;
}
@@ -1780,6 +1810,8 @@
int local_log = 0;
bool testing = false;
int nullargs = 1;
+ bool quitByUser = false;
+ struct termios ttystate;
// Extract options:
for (int i = 1; i < argc - 1; i++) {
@@ -1837,12 +1869,18 @@
verifications = (parallelisation <= 4) ? 3 : 0;
}
+ // turn on non-blocking reads
+ tcgetattr(STDIN_FILENO, &ttystate);
+ ttystate.c_lflag &= ~ICANON;
+ ttystate.c_cc[VMIN] = 1;
+ tcsetattr(STDIN_FILENO, TCSANOW, &ttystate);
+
std::cout << "\nGreetings, this is \033[1;33mapgmera " << APG_VERSION << "\033[0m, configured for \033[1;34m" << RULESTRING << "/" << SYMMETRY << "\033[0m.\n" << std::endl;
// Initialise QuickLife:
qlifealgo::doInitializeAlgoInfo(staticAlgoInfo::tick());
- while (true) {
+ while (!quitByUser) {
if (verifications > 0) {
std::cout << "Peer-reviewing hauls:\n" << std::endl;
// Verify some hauls:
@@ -1856,17 +1894,22 @@
std::cout << "Using seed " << seed << std::endl;
if (parallelisation > 0) {
#ifdef USE_OPEN_MP
- parallelSearch(soups_per_haul, parallelisation, payoshaKey, seed, local_log);
+ quitByUser = parallelSearch(soups_per_haul, parallelisation, payoshaKey, seed, local_log);
#else
- runSearch(soups_per_haul, payoshaKey, seed, local_log, false);
+ quitByUser = runSearch(soups_per_haul, payoshaKey, seed, local_log, false);
#endif
} else {
- runSearch(soups_per_haul, payoshaKey, seed, local_log, testing);
+ quitByUser = runSearch(soups_per_haul, payoshaKey, seed, local_log, testing);
}
seed = reseed(seed);
if (testing) { break; }
}
+ // turn on blocking reads
+ tcgetattr(STDIN_FILENO, &ttystate);
+ ttystate.c_lflag |= ICANON;
+ tcsetattr(STDIN_FILENO, TCSANOW, &ttystate);
+
return 0;
}
This is against 3.12, but I think it should still apply to the latest version, perhaps with some fuzz. It only works for regular searches, not parallel searches using OpenMP (further patches welcome, obviously).
gameoflifeboy wrote:In these cases, would an option to not print the progress of the search every 10000 soups speed things up noticeably even more?
Here's another patch that adds an -S <#> option to control how often progress messages are printed (default 10000, as before). Unlike the previous patch (which I already had sitting on my HD anyway), this is against 3.15:
Code: Select all
diff -ru apgmera-7c26/main.cpp playing-around-7c26/main.cpp
--- apgmera-7c26/main.cpp 2016-03-21 00:01:33.000000000 +0100
+++ playing-around-7c26/main.cpp 2016-03-23 12:53:48.704933600 +0100
@@ -1625,7 +1625,7 @@
#ifdef USE_OPEN_MP
-void parallelSearch(int n, int m, std::string payoshaKey, std::string seed, int local_log) {
+void parallelSearch(int n, int m, std::string payoshaKey, std::string seed, int local_log, int soups_per_line) {
SoupSearcher globalSoup;
@@ -1654,7 +1654,7 @@
for (long long i = offset; i < offset + n; i++) {
long long pseudoElapsed = offset + elapsed * m + threadNumber;
elapsed += 1;
- if (pseudoElapsed % 10000 == 0) {
+ if (pseudoElapsed % soups_per_line == 0) {
std::cout << pseudoElapsed << " soups processed..." << std::endl;
}
std::ostringstream ss;
@@ -1690,7 +1690,7 @@
#endif
-void runSearch(int n, std::string payoshaKey, std::string seed, int local_log, bool testing) {
+void runSearch(int n, std::string payoshaKey, std::string seed, int local_log, int soups_per_line, bool testing) {
// Create an empty QuickLife universe:
lifealgo *imp2 = createUniverse("QuickLife");
@@ -1716,10 +1716,10 @@
i += 1;
- if (i % 10000 == 0) {
+ if (i % soups_per_line == 0) {
clock_t end = clock();
- std::cout << i << " soups completed (" << (int) (10000.0 / ((double) (end-start) / CLOCKS_PER_SEC)) << " soups per second)." << std::endl;
+ std::cout << i << " soups completed (" << (int) ((double) (soups_per_line) / ((double) (end-start) / CLOCKS_PER_SEC)) << " soups per second)." << std::endl;
start = clock();
}
@@ -1774,6 +1774,7 @@
// Default values:
int soups_per_haul = 10000000;
+ int soups_per_line = 10000;
std::string payoshaKey = "#anon";
std::string seed = reseed("original seed");
int verifications = -1;
@@ -1797,6 +1798,8 @@
soups_per_haul = 100000000;
}
*/
+ } else if (strcmp(argv[i], "-S") == 0) {
+ soups_per_line = atoi(argv[i+1]);
} else if (strcmp(argv[i], "-v") == 0) {
verifications = atoi(argv[i+1]);
} else if (strcmp(argv[i], "-L") == 0) {
@@ -1857,12 +1860,12 @@
std::cout << "Using seed " << seed << std::endl;
if (parallelisation > 0) {
#ifdef USE_OPEN_MP
- parallelSearch(soups_per_haul, parallelisation, payoshaKey, seed, local_log);
+ parallelSearch(soups_per_haul, parallelisation, payoshaKey, seed, local_log, soups_per_line);
#else
- runSearch(soups_per_haul, payoshaKey, seed, local_log, false);
+ runSearch(soups_per_haul, payoshaKey, seed, local_log, soups_per_line, false);
#endif
} else {
- runSearch(soups_per_haul, payoshaKey, seed, local_log, testing);
+ runSearch(soups_per_haul, payoshaKey, seed, local_log, soups_per_line, testing);
}
seed = reseed(seed);