apgsearch v3.1

For general discussion about Conway's Game of Life.
JohanB
Posts: 16
Joined: June 10th, 2016, 11:59 pm

Re: apgsearch v3.1

Post by JohanB » July 7th, 2016, 2:27 pm

Would it be possible to have precompiled executables for Win64 (and possibly other platforms).
Right now I have to pre-install gcc and jump through several hoops even though the OS is basically the same every time.
Esp the requirement to install Cygwin is something that's holding me back from doing this.

User avatar
Apple Bottom
Posts: 1034
Joined: July 27th, 2015, 2:06 pm
Contact:

Re: apgsearch v3.1

Post by Apple Bottom » July 8th, 2016, 6:28 pm

JohanB wrote:Would it be possible to have precompiled executables for Win64 (and possibly other platforms).
Right now I have to pre-install gcc and jump through several hoops even though the OS is basically the same every time.
Esp the requirement to install Cygwin is something that's holding me back from doing this.
I just gave it a try, using Stephan Lavavej's MinGW distro. The build fails with the following error:

Code: Select all

make: makefile:4: pipe: No error
g++  main.o includes/sha256.o includes/md5.o includes/happyhttp.o gollybase/bigint.o gollybase/lifealgo.o gollybase/qlifealgo.o gollybase/util.o gollybase/lifepoll.o gollybase/liferules.o gollybase/viewport.o gollybase/readpattern.o gollybase/qlifedraw.o -o apgmera
includes/happyhttp.o:happyhttp.cpp:(.text+0x49a): undefined reference to `__imp_inet_addr'
includes/happyhttp.o:happyhttp.cpp:(.text+0x4c5): undefined reference to `__imp_gethostbyname'
includes/happyhttp.o:happyhttp.cpp:(.text+0x52c): undefined reference to `__imp_WSAGetLastError'
includes/happyhttp.o:happyhttp.cpp:(.text+0x5d6): undefined reference to `__imp_select'
includes/happyhttp.o:happyhttp.cpp:(.text+0x5e5): undefined reference to `__WSAFDIsSet'
includes/happyhttp.o:happyhttp.cpp:(.text+0x8da): undefined reference to `__imp_inet_addr'
includes/happyhttp.o:happyhttp.cpp:(.text+0x910): undefined reference to `__imp_htons'
includes/happyhttp.o:happyhttp.cpp:(.text+0x92e): undefined reference to `__imp_socket'
includes/happyhttp.o:happyhttp.cpp:(.text+0x947): undefined reference to `__imp_connect'
includes/happyhttp.o:happyhttp.cpp:(.text+0x965): undefined reference to `__imp_gethostbyname'
includes/happyhttp.o:happyhttp.cpp:(.text+0x9fb): undefined reference to `__imp_send'
includes/happyhttp.o:happyhttp.cpp:(.text+0x16c9): undefined reference to `__imp_closesocket'
includes/happyhttp.o:happyhttp.cpp:(.text+0x1a3b): undefined reference to `__imp_send'
includes/happyhttp.o:happyhttp.cpp:(.text+0x27bc): undefined reference to `__imp_send'
includes/happyhttp.o:happyhttp.cpp:(.text+0x35d7): undefined reference to `__imp_select'
includes/happyhttp.o:happyhttp.cpp:(.text+0x35ea): undefined reference to `__WSAFDIsSet'
includes/happyhttp.o:happyhttp.cpp:(.text+0x3614): undefined reference to `__imp_recv'
collect2.exe: error: ld returned 1 exit status
make: *** [makefile:39: apgmera] Error 1
I'll see if I can fix this, but I've never really used MinGW before. Consider it a data point for now. (And here's another one: neither vanilla MinGW nor MinGW-64 seem to work, otherwise; the compilers don't recognize the new SSE registers, xmm8 to xmm15 (usually a sign of a 32-bit compiler).)
If you speak, your speech must be better than your silence would have been. — Arabian proverb

Catagolue: Apple Bottom • Life Wiki: Apple Bottom • Twitter: @_AppleBottom_

Proud member of the Pattern Raiders!

User avatar
Scorbie
Posts: 1692
Joined: December 7th, 2013, 1:05 am

Re: apgsearch v3.1

Post by Scorbie » July 8th, 2016, 9:40 pm

@applebottom interesting! I only used TDM-GCC for 64bit compilations. Your compiler seems to have a lot of unix tools. Is the compiler being maintained and what are the could things aof that one, if you may?
Also, I remember succeeding in compiling without catagoluebsupport...

Edit: @applebottom did you specify -m64 for compiling it to 64 bit exe just in case? (Regarding vanilla mingw not working)
Last edited by Scorbie on July 10th, 2016, 8:37 am, edited 3 times in total.

User avatar
Apple Bottom
Posts: 1034
Joined: July 27th, 2015, 2:06 pm
Contact:

Re: apgsearch v3.1

Post by Apple Bottom » July 9th, 2016, 5:23 am

Scorbie wrote:@applebottom interesting! I only used TDM-GCC for 64bit compilations. Your compiler seems to have a lot of unix tools. Is the compiler being maintained and what are the could things aof that one, if you may?
Also, I remember succeeding in compiling without catagoluebsupport...
Yes, it's maintained; the last version came out a little more than a month ago. Mind, I never used it before -- I only chose it because it's used to build cmix on windows platforms.

Some web-searching suggests that the above issue is due to the linker not pulling in a required library (libws2_32.a). This does exist (in MinGW\x86_64-w64-mingw32\lib), and appears to contain the unresolved symbols, but I've not been successful in getting the linker to use it.
If you speak, your speech must be better than your silence would have been. — Arabian proverb

Catagolue: Apple Bottom • Life Wiki: Apple Bottom • Twitter: @_AppleBottom_

Proud member of the Pattern Raiders!

User avatar
Scorbie
Posts: 1692
Joined: December 7th, 2013, 1:05 am

Re: apgsearch v3.1

Post by Scorbie » July 10th, 2016, 8:34 am

@Apple Bottom: I remember seeing those messages before... Sorry to say that I failed to solve that problem. I am very curious why this source is not cross-platform the problematic happyhttp seems to be cross-platform (with all those Win32...whadoyoucall thst, derivatives? Inside the code)

Edit: @applebottom regarding vanilla mingw, how about specifying -m64 just in case?

User avatar
Apple Bottom
Posts: 1034
Joined: July 27th, 2015, 2:06 pm
Contact:

Re: apgsearch v3.1

Post by Apple Bottom » July 10th, 2016, 12:08 pm

Scorbie wrote:@Apple Bottom: I remember seeing those messages before... Sorry to say that I failed to solve that problem. I am very curious why this source is not cross-platform the problematic happyhttp seems to be cross-platform (with all those Win32...whadoyoucall thst, derivatives? Inside the code)
Preprocessor directives/conditionals. And I do agree, it is ironic; my gut feeling is that there's an easy fix right around some corner, but I lack the experience to know where to look.
Edit: @applebottom regarding vanilla mingw, how about specifying -m64 just in case?
Haven't tried yet, will do so later tonight.

EDIT: Just did; here's the result:

Code: Select all

g++ -c -Wall -O3 -march=native -m64 main.cpp -o main.o
main.cpp:1:0: sorry, unimplemented: 64-bit mode not compiled in

 ^
makefile:35: recipe for target 'main.o' failed
mingw32-make: *** [main.o] Error 1
So, no dice.

EDIT 2: I used these instructions to set up MinGW, up to and including section 4 ("MinGW-w64"; the rest was tools I didn't need).

Compilation of apgmera succeeded; in particular, appending "-lws2_32" to the end of the linker invocation actually found and pulled in that library, so the network-related symbols resolved:

Code: Select all

$ make
g++ -c -Wall -O3 -march=native main.cpp -o main.o
g++ -c -Wall -O3 -march=native includes/sha256.cpp -o includes/sha256.o
g++ -c -Wall -O3 -march=native includes/md5.cpp -o includes/md5.o
g++ -c -Wall -O3 -march=native includes/happyhttp.cpp -o includes/happyhttp.o
g++ -c -Wall -O3 -march=native gollybase/bigint.cpp -o gollybase/bigint.o
g++ -c -Wall -O3 -march=native gollybase/lifealgo.cpp -o gollybase/lifealgo.o
g++ -c -Wall -O3 -march=native gollybase/qlifealgo.cpp -o gollybase/qlifealgo.o
g++ -c -Wall -O3 -march=native gollybase/util.cpp -o gollybase/util.o
g++ -c -Wall -O3 -march=native gollybase/lifepoll.cpp -o gollybase/lifepoll.o
g++ -c -Wall -O3 -march=native gollybase/liferules.cpp -o gollybase/liferules.o
g++ -c -Wall -O3 -march=native gollybase/viewport.cpp -o gollybase/viewport.o
g++ -c -Wall -O3 -march=native gollybase/readpattern.cpp -o gollybase/readpattern.o
g++ -c -Wall -O3 -march=native gollybase/qlifedraw.cpp -o gollybase/qlifedraw.o
g++  main.o includes/sha256.o includes/md5.o includes/happyhttp.o gollybase/bigint.o gollybase/lifealgo.o gollybase/qlifealgo.o gollybase/util.o gollybase/lifepoll.o gollybase/liferules.o gollybase/viewport.o gollybase/readpattern.o gollybase/qlifedraw.o -o apgmera -lws2_32
true
true                                                oo o
true                                                oo ooo
true                                                      o
true                                                oo ooo
true                                                 o o
true                                                 o o
true                                                  o
Here's the makefile I used:

Code: Select all

CC=g++

# Thanks to Andrew Trevorrow for the following routine to handle clang:
ifeq "$(shell uname)" "Darwin"
    # we're on Mac OS X, so check if clang is available
    ifeq "$(shell which clang++)" "/usr/bin/clang++"
        # assume we're on Mac OS 10.9 or later
        MACOSX_109_OR_LATER=1
    endif
endif
ifeq "$(shell uname)" "MINGW32_NT-6.1"
    # we're on Windows, using MinGW
    WIN32=1
endif
ifdef MACOSX_109_OR_LATER
    # g++ is really clang++ and there is currently no OpenMP support
    CFLAGS=-c -Wall -O3 -march=native
else
    ifdef WIN32
        CFLAGS=-c -Wall -O3 -march=native
	EXTRALIBS=-lws2_32
    else
        # assume we're using gcc with OpenMP support
        CFLAGS=-c -Wall -O3 -march=native -fopenmp -DUSE_OPEN_MP
        LDFLAGS=-fopenmp
    endif
endif

SOURCES=main.cpp includes/sha256.cpp includes/md5.cpp includes/happyhttp.cpp \
gollybase/bigint.cpp gollybase/lifealgo.cpp gollybase/qlifealgo.cpp gollybase/util.cpp \
gollybase/lifepoll.cpp gollybase/liferules.cpp gollybase/viewport.cpp \
gollybase/readpattern.cpp gollybase/qlifedraw.cpp

OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=apgmera

# Compile:
all: $(SOURCES) $(EXECUTABLE)
	true
	true                                                oo o
	true                                                oo ooo
	true                                                      o
	true                                                oo ooo
	true                                                 o o
	true                                                 o o
	true                                                  o

# Clean the build environment by deleting any object files:
clean: 
	rm -f $(OBJECTS)
	echo Clean done

$(EXECUTABLE): $(OBJECTS) 
	$(CC) $(LDFLAGS) $(OBJECTS) -o $@ $(EXTRALIBS)

.cpp.o:
	$(CC) $(CFLAGS) $< -o $@

The resulting binary works, and appears to be faster than my Cygwin-built version on the same machine (which averages ~1450 soups/second). But unfortunately networking is broken:

Code: Select all

Greetings, this is ←[1;33mapgmera v3.28←[0m, configured for ←[1;34mb3s23/C1←[0m.

Peer-reviewing hauls:

Internet does not exist.
No response!
Authentication failed.
Received no response from /verify.
Internet does not exist.
No response!
Authentication failed.
Received no response from /verify.
Internet does not exist.
No response!
Authentication failed.
Received no response from /verify.

Peer-review complete; proceeding search.

Using seed m_zEcEztDD5G8D
Universe created.
Running 100000 soups per haul:
Instruction set ←[1mAVX1←[0m supported.
10000 soups completed (1614 soups per second).
20000 soups completed (1665 soups per second).
30000 soups completed (1574 soups per second).
40000 soups completed (1575 soups per second).
Linear-growth pattern detected: ←[1;32myl144_1_16_afb5f3db909e60548f086e22ee3353ac←[0m
50000 soups completed (1500 soups per second).
Linear-growth pattern detected: ←[1;32myl144_1_16_afb5f3db909e60548f086e22ee3353ac←[0m
60000 soups completed (1601 soups per second).
70000 soups completed (1548 soups per second).
80000 soups completed (1575 soups per second).
90000 soups completed (1673 soups per second).
Linear-growth pattern detected: ←[1;32myl144_1_16_afb5f3db909e60548f086e22ee3353ac←[0m
100000 soups completed (1578 soups per second).
----------------------------------------------------------------------
100000 soups completed.
Attempting to contact payosha256.
Internet does not exist.
No response!
Connection was unsuccessful; continuing search...
----------------------------------------------------------------------
(As you can see, ANSI codes also aren't interpreted by the terminal, but that's merely a cosmetic issue.)

So it still ain't working, but we're getting somewhere.
If you speak, your speech must be better than your silence would have been. — Arabian proverb

Catagolue: Apple Bottom • Life Wiki: Apple Bottom • Twitter: @_AppleBottom_

Proud member of the Pattern Raiders!

User avatar
Scorbie
Posts: 1692
Joined: December 7th, 2013, 1:05 am

Re: apgsearch v3.1

Post by Scorbie » July 10th, 2016, 6:54 pm

@great to see that! I meant mingw-w64 instead of vanilla mingw but it is working already :) We could remove the upload functionality and send the results with Python in the next release to make it cross-platform, I think...

User avatar
muzik
Posts: 5650
Joined: January 28th, 2016, 2:47 pm
Location: Scotland

Re: apgsearch v3.1

Post by muzik » July 10th, 2016, 7:04 pm

Is there any way to, uh, increase search speed?

Sphenocorona
Posts: 549
Joined: April 9th, 2013, 11:03 pm

Re: apgsearch v3.1

Post by Sphenocorona » July 10th, 2016, 9:32 pm

muzik wrote:Is there any way to, uh, increase search speed?
Running an instance of apgsearch on every core of your CPU, and getting more raw computing power. If there was a simple way to improve the speed of the search it would have been implemented by now. From what I've seen, apgmera already uses some pretty difficult to implement methods to speed up searching; the fact that it rewrites parts of itself for the specific rule/symmetry being searched for is bordering on insane. I wouldn't be surprised if there's some things that still slow the search down and could be sped up (like classifying objects maybe) but they'll require more brainpower to figure out a better solution.

User avatar
muzik
Posts: 5650
Joined: January 28th, 2016, 2:47 pm
Location: Scotland

Re: apgsearch v3.1

Post by muzik » July 11th, 2016, 9:46 am

So, if your computer has four cores, then you should run 4 instances of apgmera for optimal search speed?



Just made a "discovery" (I'm the fourth):

https://catagolue.appspot.com/user/muzi ... iscoveries

User avatar
calcyman
Moderator
Posts: 2938
Joined: June 1st, 2009, 4:32 pm

Re: apgsearch v3.1

Post by calcyman » July 12th, 2016, 2:22 am

muzik wrote:So, if your computer has four cores, then you should run 4 instances of apgmera for optimal search speed?
Or use -p 4 in the command-line options.
What do you do with ill crystallographers? Take them to the mono-clinic!

User avatar
Apple Bottom
Posts: 1034
Joined: July 27th, 2015, 2:06 pm
Contact:

Re: apgsearch v3.1

Post by Apple Bottom » July 12th, 2016, 8:25 am

And now for something completely different...

I've occasionally been tweaking apgmera to better suit my needs, and thought that I might well share the changes with all y'all, just in case someone else might find them useful. There's no functional changes as such – the plumbing remains untouched –, but I've messed around with the porcelain, as it were. Specifically, the changes are:
  • Pressing "Q" in the console will submit the current results and the stop the client. (This is useful for when you want to free a CPU core or two for other things.)
  • Pressing "S" in the console will display the current census.
  • The -no 1 command line flag turns on reporting of new objects. (Not recommended for all rules.)
  • The -q <#> flag controls status output: 0=normal, 1=don't report rare objects, 2=also don't report progress.
  • The -t <#> flag controls how long the program should run (in seconds).
  • The -h <#> flag controls how many hauls the program should run for.
  • The -S <#> flag controls how often status messages get printed (every <#> soups).
  • Exit code indicates why the program quit: 1=requested by user; 2=all hauls done (-h); 3=time's up (-t).
  • Prepend the configured rule/symmetry to progress messages.
  • Output overall search speed in addition to current speed.
  • There's now script to quickly compile binaries for a given rule/symmetry, or all symmetries for a given rule.
  • Internal makefile changes: dependency handling, distclean target, some tweaks for Cygwin/MinGW32.
Complete patch:

Code: Select all

diff -Nru apgmera-cffe/compilerule.sh playingaround-cffe/compilerule.sh
--- apgmera-cffe/compilerule.sh	1970-01-01 01:00:00.000000000 +0100
+++ playingaround-cffe/compilerule.sh	2016-06-30 13:07:05.400386900 +0200
@@ -0,0 +1,42 @@
+#!/bin/bash
+
+function makebinary() {
+	RULE=$1
+	SYM=$2
+	
+	python rule2asm.py $RULE $SYM
+	make
+	mv -v apgmera.exe apgmera-${RULE}-${SYM}.exe
+}
+
+if [[ $# -eq 1 ]]; then
+	RULE=$1
+
+	makebinary $RULE C1
+	makebinary $RULE C2_1
+	makebinary $RULE C2_2
+	makebinary $RULE C2_4
+	makebinary $RULE C4_1
+	makebinary $RULE C4_4
+	makebinary $RULE D2_+1
+	makebinary $RULE D2_+2
+	makebinary $RULE D2_x
+	makebinary $RULE D4_+1
+	makebinary $RULE D4_+2
+	makebinary $RULE D4_+4
+	makebinary $RULE D4_x1
+	makebinary $RULE D4_x4
+	makebinary $RULE D8_1
+	makebinary $RULE D8_4
+	makebinary $RULE 8x32
+	
+elif [[ $# -eq 2 ]]; then
+	RULE=$1
+	SYM=$2
+
+	makebinary $RULE $SYM
+
+else
+	echo "Usage: $0 <rulestring> [<symmetry>]"
+
+fi
diff -Nru apgmera-cffe/main.cpp playingaround-cffe/main.cpp
--- apgmera-cffe/main.cpp	2016-06-30 18:32:21.542207300 +0200
+++ playingaround-cffe/main.cpp	2016-07-12 01:19:12.067791100 +0200
@@ -1,4 +1,3 @@
-
 #include <iostream>
 #include <vector>
 #include <sstream>
@@ -8,6 +7,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 +27,31 @@
 #include "includes/hashsoup.h"
 
 #define APG_VERSION "v3.28"
+#define APG_VERSION_EXTRA "-ab7"
+
+#define EXIT_USERQUIT	1
+#define EXIT_HAULSDONE	2
+#define EXIT_TIMESUP	3
+
+clock_t programStartupTime;
+int quietLevel = 0;
+bool newObjects = false;
+
+// 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:
@@ -1315,6 +1342,19 @@
             }
         }
 
+        if(newObjects) {
+            if(nBlocks && !census["xs4_33"])
+                std::cout << "New object: \033[1;37mxs4_33\033[0m" << std::endl;
+            if(nBlinkers && !census["xp2_7"])
+                std::cout << "New object: \033[1;31mxp2_7\033[0m" << std::endl;
+            if(nBeehives && !census["xs6_696"])
+                std::cout << "New object: \033[1;37mxs6_696\033[0m" << std::endl;
+            if(nGliders && !census["xq4_153"])
+                std::cout << "New object: \033[1;34mxq4_153\033[0m" << std::endl;
+            if(nBoats && !census["xs5_253"])
+                std::cout << "New object: \033[1;37mxs5_253\033[0m" << std::endl;
+        }
+            
         census["xs4_33"] += nBlocks;
         census["xp2_7"] += nBlinkers;
         census["xs6_696"] += nBeehives;
@@ -1324,6 +1364,22 @@
         for (unsigned int i = 0; i < objlist.size(); i++) {
             std::string apgcode = objlist[i];
             if ((ignorePathologicals == false) || (apgcode.compare("PATHOLOGICAL") != 0)) {
+                if(newObjects && !census[apgcode]) {
+                    std::cout << "New object: ";
+                    
+                    if(!apgcode.find("xp"))
+                        std::cout << "\033[1;31m";
+                    else if(!apgcode.find("xq"))
+                        std::cout << "\033[1;34m";
+                    else if(!apgcode.find("yl"))
+                        std::cout << "\033[1;32m";
+                    else if(!apgcode.find("zz"))
+                        std::cout << "\033[1;32m";
+                    else
+                        std::cout << "\033[1;37m";
+                        
+                    std::cout << apgcode << "\033[0m" << std::endl;
+                }
                 census[apgcode] += 1;
                 if (alloccur[apgcode].size() == 0 || alloccur[apgcode].back().compare(suffix) != 0) {
                     if (alloccur[apgcode].size() < 10) {
@@ -1333,30 +1389,32 @@
             }
 
             // Mention object in terminal:
+            if(!quietLevel) {
             #ifdef STANDARD_LIFE
-            if ((apgcode[0] == 'x') && (apgcode[1] == 'p')) {
-                if ((apgcode[2] != '2') || (apgcode[3] != '_')) {
-                    if (apgcode.compare("xp3_co9nas0san9oczgoldlo0oldlogz1047210127401") != 0 && apgcode.compare("xp15_4r4z4r4") != 0) {
-                        // Interesting oscillator:
-                        std::cout << "Rare oscillator detected: \033[1;31m" << apgcode << "\033[0m" << std::endl;
+                if ((apgcode[0] == 'x') && (apgcode[1] == 'p')) {
+                    if ((apgcode[2] != '2') || (apgcode[3] != '_')) {
+                        if (apgcode.compare("xp3_co9nas0san9oczgoldlo0oldlogz1047210127401") != 0 && apgcode.compare("xp15_4r4z4r4") != 0) {
+                            // Interesting oscillator:
+                            std::cout << "Rare oscillator detected: \033[1;31m" << apgcode << "\033[0m" << std::endl;
+                        }
+                    }
+                } else if ((apgcode[0] == 'x') && (apgcode[1] == 'q')) {
+                    if (apgcode.compare("xq4_153") != 0 && apgcode.compare("xq4_6frc") != 0 && apgcode.compare("xq4_27dee6") != 0 && apgcode.compare("xq4_27deee6") != 0) {
+                        std::cout << "Rare spaceship detected: \033[1;34m" << apgcode << "\033[0m" << std::endl;
                     }
+                } else if ((apgcode[0] == 'y') && (apgcode[1] == 'l')) {
+                    std::cout << "Linear-growth pattern detected: \033[1;32m" << apgcode << "\033[0m" << std::endl;
+                } else if ((apgcode[0] == 'z') && (apgcode[1] == 'z')) {
+                    std::cout << "Chaotic-growth pattern detected: \033[1;32m" << apgcode << "\033[0m" << std::endl;
                 }
-            } else if ((apgcode[0] == 'x') && (apgcode[1] == 'q')) {
-                if (apgcode.compare("xq4_153") != 0 && apgcode.compare("xq4_6frc") != 0 && apgcode.compare("xq4_27dee6") != 0 && apgcode.compare("xq4_27deee6") != 0) {
-                    std::cout << "Rare spaceship detected: \033[1;34m" << apgcode << "\033[0m" << std::endl;
-                }
-            } else if ((apgcode[0] == 'y') && (apgcode[1] == 'l')) {
-                std::cout << "Linear-growth pattern detected: \033[1;32m" << apgcode << "\033[0m" << std::endl;
-            } else if ((apgcode[0] == 'z') && (apgcode[1] == 'z')) {
-                std::cout << "Chaotic-growth pattern detected: \033[1;32m" << apgcode << "\033[0m" << std::endl;
-            }
             #else
-            if ((apgcode[0] == 'y') && (apgcode[1] == 'l')) {
-                std::cout << "Linear-growth pattern detected: \033[1;32m" << apgcode << "\033[0m" << std::endl;
-            } else if ((apgcode[0] == 'z') && (apgcode[1] == 'z')) {
-                std::cout << "Chaotic-growth pattern detected: \033[1;32m" << apgcode << "\033[0m" << std::endl;
-            }
+                if ((apgcode[0] == 'y') && (apgcode[1] == 'l')) {
+                    std::cout << "Linear-growth pattern detected: \033[1;32m" << apgcode << "\033[0m" << std::endl;
+                } else if ((apgcode[0] == 'z') && (apgcode[1] == 'z')) {
+                    std::cout << "Chaotic-growth pattern detected: \033[1;32m" << apgcode << "\033[0m" << std::endl;
+                }
             #endif
+            }
         }
 
         return false;
@@ -1547,6 +1605,10 @@
         return;
     }
 
+    // temporarily turn off reporting of new objects
+    bool oldNewObjects = newObjects;
+    newObjects = false;
+    
     std::ostringstream ss;
     ss << authstring << "\n";
     ss << "@MD5 " << stringlist[2] << "\n";
@@ -1582,12 +1644,15 @@
     }
 
     catagolueRequest(ss.str().c_str(), "/verify");
+    
+    // reenable reporting of new objects	
+    newObjects = oldNewObjects;
 
 }
 
 #ifdef USE_OPEN_MP
 
-void parallelSearch(int n, int m, std::string payoshaKey, std::string seed, int local_log) {
+int parallelSearch(int n, int m, std::string payoshaKey, std::string seed, int local_log, int soups_per_line, int hauls, int seconds) {
 
     SoupSearcher globalSoup;
 
@@ -1616,7 +1681,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;
@@ -1646,13 +1711,15 @@
         }
         std::cout << "----------------------------------------------------------------------" << std::endl;
     }
+    
+    return 0;
 
 }
 
 #endif
 
 
-void runSearch(int n, std::string payoshaKey, std::string seed, int local_log, bool testing) {
+int runSearch(int n, std::string payoshaKey, std::string seed, int local_log, int soups_per_line, int hauls, int seconds, bool testing, int *currentHauls) {
 
     // Create an empty QuickLife universe:
     lifealgo *imp2 = createUniverse("QuickLife");
@@ -1661,15 +1728,17 @@
 
     SoupSearcher soup;
 
-    clock_t start = clock();
+    clock_t start_clock = clock();
+    clock_t prev_clock  = clock();
 
     std::cout << "Running " << n << " soups per haul:" << std::endl;
 
 
     long long i = 0;
     bool finishedSearch = false;
+    int quit = 0;
 
-    while (finishedSearch == false) {
+    while ((finishedSearch == false) && !quit) {
 
         std::ostringstream ss;
         ss << i;
@@ -1678,15 +1747,59 @@
 
         i += 1;
 
-        if (i % 10000 == 0) {
-            clock_t end = clock();
+        if (i % soups_per_line == 0) {
+            clock_t curr_clock = clock();
+
+            if(!(quietLevel > 1)) {
+                std::cout << RULESTRING << "/" << SYMMETRY << ": " << i << " soups done (soups/s: " << (int) ((double) (soups_per_line) / ((double) (curr_clock - prev_clock) / CLOCKS_PER_SEC)) << " current, ";
+                std::cout << (int) (((double) i) / ((double) (curr_clock - start_clock) / CLOCKS_PER_SEC)) << " overall)";
+                std::cout << std::endl;
+            
+                prev_clock = clock();
+            }
+            
+            if(keyWaiting()) {
+                char c = fgetc(stdin);
+                if ((c == 'q') || (c == 'Q'))
+                    quit = EXIT_USERQUIT;
+                else if ((c == 's') || (c == 'S')) {
+                    long long totobjs = 0;
+
+                    std::vector<std::pair<long long, std::string> > censusList = soup.getSortedList(totobjs);
+
+                    std::cout << "----------------------------------------------------------------------" << std::endl;
+                    std::cout << "Current census:" << std::endl;
+                    std::cout << "----------------------------------------------------------------------" << std::endl;
+
+                    for (int i = censusList.size() - 1; i >= 0; i--) {
+                        if(!censusList[i].second.find("xp"))
+                            std::cout << "\033[1;31m";
+                        else if(!censusList[i].second.find("xq"))
+                            std::cout << "\033[1;34m";
+                        else if(!censusList[i].second.find("yl"))
+                            std::cout << "\033[1;32m";
+                        else if(!censusList[i].second.find("zz"))
+                            std::cout << "\033[1;32m";
+                        else
+                            std::cout << "\033[1;37m";
+                        std::cout << censusList[i].second << "\033[0m " << censusList[i].first << std::endl;
+                    }
+                    
 
-            std::cout << i << " soups completed (" << (int) (10000.0 / ((double) (end-start) / CLOCKS_PER_SEC)) << " soups per second)." << std::endl;
+                    std::cout << "----------------------------------------------------------------------" << std::endl;
+                    std::cout << "Total: " << totobjs << " objects (" << censusList.size() << " distinct)" << std::endl;
+                    std::cout << "----------------------------------------------------------------------" << std::endl;
 
-            start = clock();
+                }
+                    
+            }
+            
+            if(seconds)
+                if(((double) (curr_clock - programStartupTime) / CLOCKS_PER_SEC) > seconds)
+                    quit = EXIT_TIMESUP;
         }
 
-        if (i % n == 0) {
+        if ((i % n == 0) || quit) {
             if (testing) {
                 finishedSearch = true;
             } else {
@@ -1702,9 +1815,13 @@
             }
             std::cout << "----------------------------------------------------------------------" << std::endl;
             }
+            if(hauls && (++(*currentHauls) >= hauls) && !quit)
+                quit = EXIT_HAULSDONE;
         }
 
     }
+    
+    return quit;
 
 }
 
@@ -1736,6 +1853,11 @@
 
     // Default values:
     int soups_per_haul = 10000000;
+    int soups_per_line = 10000;
+    int hauls = 0;
+    int currentHauls = 0;
+    int *currentHaulsPointer = &currentHauls;
+    int seconds = 0;
     std::string payoshaKey = "#anon";
     std::string seed = reseed("original seed");
     int verifications = -1;
@@ -1743,6 +1865,8 @@
     int local_log = 0;
     bool testing = false;
     int nullargs = 1;
+    int quit = 0;
+    struct termios ttystate;
 
     // Extract options:
     for (int i = 1; i < argc - 1; i++) {
@@ -1759,19 +1883,32 @@
                 soups_per_haul = 100000000;
             }
             */
+        } else if (strcmp(argv[i], "-S") == 0) {
+            soups_per_line = atoi(argv[i+1]);
+        } else if (strcmp(argv[i], "-h") == 0) {
+            hauls = atoi(argv[i+1]);
+            if(hauls)
+                std::cout << "Notice: running for at most " << hauls << " hauls." << std::endl;
+        } else if (strcmp(argv[i], "-t") == 0) {
+            seconds = atoi(argv[i+1]);
+            if(seconds)
+                std::cout << "Notice: running for at most " << seconds << " seconds." << std::endl;
         } else if (strcmp(argv[i], "-v") == 0) {
             verifications = atoi(argv[i+1]);
         } else if (strcmp(argv[i], "-L") == 0) {
             local_log = atoi(argv[i+1]);
+        } else if (strcmp(argv[i], "-q") == 0) {
+            quietLevel = atoi(argv[i+1]);
         } else if (strcmp(argv[i], "-t") == 0) {
             testing = true;
+        } else if (strcmp(argv[i], "-no") == 0) {	
+            newObjects = atoi(argv[i+1]);
         } else if (strcmp(argv[i], "-p") == 0) {
             parallelisation = atoi(argv[i+1]);
         } else if (strcmp(argv[i], "--rule") == 0) {
-            std::cout << "\033[1;33mapgmera " << APG_VERSION << "\033[0m: ";
+            std::cout << "\033[1;33mapgmera " << APG_VERSION << APG_VERSION_EXTRA << "\033[0m: ";
             std::string desired_rulestring = argv[i+1];
             if (strcmp(RULESTRING, argv[i+1]) == 0) {
-                std::cout << "Rule \033[1;34m" << RULESTRING << "\033[0m is correctly configured." << std::endl;
                 nullargs += 2;
             } else {
                 std::cout << "Rule \033[1;34m" << RULESTRING << "\033[0m does not match desired rule \033[1;34m" << desired_rulestring << "\033[0m." << std::endl;
@@ -1779,7 +1916,7 @@
                 return 1;
             }
         } else if (strcmp(argv[i], "--symmetry") == 0) {
-            std::cout << "\033[1;33mapgmera " << APG_VERSION << "\033[0m: ";
+            std::cout << "\033[1;33mapgmera " << APG_VERSION << APG_VERSION_EXTRA << "\033[0m: ";
             std::string desired_symmetry = argv[i+1];
             if (strcmp(SYMMETRY, argv[i+1]) == 0) {
                 std::cout << "Symmetry \033[1;34m" << SYMMETRY << "\033[0m is correctly configured." << std::endl;
@@ -1800,12 +1937,21 @@
         verifications = (parallelisation <= 4) ? 3 : 0;
     }
 
-    std::cout << "\nGreetings, this is \033[1;33mapgmera " << APG_VERSION << "\033[0m, configured for \033[1;34m" << RULESTRING << "/" << SYMMETRY << "\033[0m.\n" << std::endl;
-
+    // turn on non-blocking reads
+    tcgetattr(STDIN_FILENO, &ttystate);
+    ttystate.c_lflag &= ~ICANON;
+    ttystate.c_cc[VMIN] = 1;
+    tcsetattr(STDIN_FILENO, TCSANOW, &ttystate);
+    
+    // take note of when we started searching
+    programStartupTime = clock();
+    
+    std::cout << "\nHowdy, this is \033[1;33mapgmera " << APG_VERSION << APG_VERSION_EXTRA << "\033[0m, configured for \033[1;34m" << RULESTRING_SLASHED << "/" << SYMMETRY << "\033[0m.\n" << std::endl;
+    
     // Initialise QuickLife:
     qlifealgo::doInitializeAlgoInfo(staticAlgoInfo::tick());
 
-    while (true) {
+    while (!quit) {
         if (verifications > 0) {
             std::cout << "Peer-reviewing hauls:\n" << std::endl;
             // Verify some hauls:
@@ -1819,17 +1965,25 @@
         std::cout << "Using seed " << seed << std::endl;
         if (parallelisation > 0) {
             #ifdef USE_OPEN_MP
-            parallelSearch(soups_per_haul, parallelisation, payoshaKey, seed, local_log);
+            quit = parallelSearch(soups_per_haul, parallelisation, payoshaKey, seed, local_log, soups_per_line, hauls, seconds);
             #else
-            runSearch(soups_per_haul, payoshaKey, seed, local_log, false);
+            quit = runSearch(soups_per_haul, payoshaKey, seed, local_log, soups_per_line, hauls, seconds, false, currentHaulsPointer);
             #endif
         } else {
-            runSearch(soups_per_haul, payoshaKey, seed, local_log, testing);
+            quit = runSearch(soups_per_haul, payoshaKey, seed, local_log, soups_per_line, hauls, seconds, testing, currentHaulsPointer);
         }
         seed = reseed(seed);
 
+/*        if(hauls && (++currentHauls >= hauls) && !quit)
+            quit = EXIT_HAULSDONE; */
+                
         if (testing) { break; }
     }
 
-    return 0;
+    // turn on blocking reads    
+    tcgetattr(STDIN_FILENO, &ttystate);
+    ttystate.c_lflag |= ICANON;
+    tcsetattr(STDIN_FILENO, TCSANOW, &ttystate);
+    
+    exit(quit);
 }
diff -Nru apgmera-cffe/makefile playingaround-cffe/makefile
--- apgmera-cffe/makefile	2016-06-30 18:32:21.542207300 +0200
+++ playingaround-cffe/makefile	2016-07-11 00:07:51.884658100 +0200
@@ -8,13 +8,22 @@
         MACOSX_109_OR_LATER=1
     endif
 endif
+ifeq "$(shell uname)" "MINGW32_NT-6.1"
+    # we're on Windows, using MinGW
+    WIN32=1
+endif
 ifdef MACOSX_109_OR_LATER
     # g++ is really clang++ and there is currently no OpenMP support
     CFLAGS=-c -Wall -O3 -march=native
 else
-    # assume we're using gcc with OpenMP support
-    CFLAGS=-c -Wall -O3 -march=native -fopenmp -DUSE_OPEN_MP
-    LDFLAGS=-fopenmp
+    ifdef WIN32
+        CFLAGS=-c -Wall -O3 -march=native
+        EXTRALIBS=-lws2_32
+    else
+        # assume we're using gcc with OpenMP support
+        CFLAGS=-c -Wall -O3 -march=native -fopenmp -DUSE_OPEN_MP
+        LDFLAGS=-fopenmp
+    endif
 endif
 
 SOURCES=main.cpp includes/sha256.cpp includes/md5.cpp includes/happyhttp.cpp \
@@ -23,7 +32,16 @@
 gollybase/readpattern.cpp gollybase/qlifedraw.cpp
 
 OBJECTS=$(SOURCES:.cpp=.o)
-EXECUTABLE=apgmera
+
+GENHEADERS=includes/lifeasm-sse2.h includes/lifeasm-avx1.h includes/lifeasm-avx2.h \
+includes/lifelogic-sse2.h includes/lifelogic-avx1.h includes/lifelogic-avx2.h \
+includes/params.h
+
+ifeq "$(shell uname -o)" "Cygwin"
+        EXECUTABLE=apgmera.exe
+else
+        EXECUTABLE=apgmera
+endif
 
 # Compile:
 all: $(SOURCES) $(EXECUTABLE)
@@ -36,10 +54,22 @@
 	true                                                 o o
 	true                                                  o
 
+depend: .depend
+
+.depend: $(SOURCES)
+	rm -f ./.depend
+	$(CC) $(CFLAGS) -MM $^>>./.depend;
+
+
 # Clean the build environment by deleting any object files:
 clean: 
 	rm -f $(OBJECTS)
+	rm -f ./.depend
 	echo Clean done
+	
+distclean:
+	rm -f $(GENHEADERS) $(OBJECTS) $(EXECUTABLE) ./.depend
+	echo Distclean done
 
 $(EXECUTABLE): $(OBJECTS) 
 	$(CC) $(LDFLAGS) $(OBJECTS) -o $@
@@ -47,3 +77,4 @@
 .cpp.o:
 	$(CC) $(CFLAGS) $< -o $@
 
+include .depend
diff -Nru apgmera-cffe/rule2asm.py playingaround-cffe/rule2asm.py
--- apgmera-cffe/rule2asm.py	2016-06-30 18:32:21.557807300 +0200
+++ playingaround-cffe/rule2asm.py	2016-06-30 13:07:05.478387000 +0200
@@ -558,6 +558,7 @@
         g.write('#define MIDDLE28 0x3ffffffcu\n')
         g.write('#define BIRTHS '+str(bee)+'\n')
         g.write('#define SURVIVALS '+str(ess)+'\n')
+        g.write('#define ' + rulestring.upper() + ' ' + rulestring + '\n')
         if (symmetry == 'C1'):
             g.write('#define C1_SYMMETRY 1\n')
         if (rulestring == 'b3s23'):
I'll be the first to admit that this is a messy patch, held together by bubblegum and duct tape, but it works.

A note regarding the "compilerule.sh" script and the -t and -h options: these are used, along with driver scripts, to automatically cycle through different symmetries in Conway Life as well as Day & Night (I've got one CPU core dedicated to these). Here's what a sample driver script may look like:

Code: Select all

#!/bin/bash

# set the title of a MinTTY terminal window
function setminttytitle() {
	echo -ne "\e]0;$1\a"
}

# this expects:
# $1 = executable (in current directory)
# $2 = number of hauls to verify
# $3 = number of soups to search
# $4 = number of soups per progress line
# $5 = number of hauls to submit before quitting (0 = infinite)
function runmera() {
	setminttytitle $1
	nice -19 ./$1 -L 1 -v $2 -k <YourPayoshaKeyHere> -n $3 -S $4 -h $5 -t 3600 -q 1

	if [ $? -eq 1 ]; then
		exit 1
	fi
}

# this expects:
# $1 = symmetry
function runlife() {
	runmera "apgmera-b3s23-$1 -no 1" 3 10000000 10000 5
}

# this expects:
# $1 = symmetry
# $2 = soups per haul
# $3 = soups per status line
function rundan() {
	runmera "apgmera-b3678s34678-$1" 0 $2 $3 5
}

while true; do
	rundan  C2_2 1500000 10000
	runlife C2_2
	rundan  C2_4 1500000 10000
	runlife C2_4
	rundan  C4_1 25000 1000
	runlife C4_1
	rundan  D4_x1 40000 1000
	runlife D4_x1
	rundan  D4_x4 40000 1000
	runlife D4_x4
	rundan  C4_4 25000 1000
	runlife C4_4
	rundan  D2_+1 125000 10000
	runlife D2_+1
	rundan  D2_+2 125000 10000
	runlife D2_+2
	rundan  D4_+1 15000 1000
	runlife D4_+1
	rundan  D4_+2 15000 1000
	runlife D4_+2
	rundan  D2_x 100000 10000
	runlife D2_x
	rundan  D8_1 10000 1000
	runlife D8_1
	rundan  8x32 8000000 25000
	runlife 8x32
	rundan  D8_4 10000 1000
	runlife D8_4
	rundan  D4_+4 15000 1000
	runlife D4_+4
	rundan  C2_1 1500000 10000
	runlife C2_1
done
If you speak, your speech must be better than your silence would have been. — Arabian proverb

Catagolue: Apple Bottom • Life Wiki: Apple Bottom • Twitter: @_AppleBottom_

Proud member of the Pattern Raiders!

User avatar
muzik
Posts: 5650
Joined: January 28th, 2016, 2:47 pm
Location: Scotland

Re: apgsearch v3.1

Post by muzik » July 12th, 2016, 8:33 am

Honestly, the q feature should have existed in the first place.

Is there any way to do that thing in vanilla apgmera?

drc
Posts: 1664
Joined: December 3rd, 2015, 4:11 pm

Re: apgsearch v3.1

Post by drc » July 12th, 2016, 12:11 pm

I got this:

Code: Select all

The next patch would create the file apgmera.exe,
which already exists!  Assume -R? [n]
I pressed y, enter, and got this:

Code: Select all

(Stripping trailing CRs from patch; use --binary to disable.)
patching file apgmera.exe
Hunk #1 FAILED at 1 (different line endings).
Not deleting file apgmera.exe as content differs from patch
1 out of 1 hunk FAILED -- saving rejects to file apgmera.exe.rej
(Stripping trailing CRs from patch; use --binary to disable.)
patching file apgmera.exe
patch: **** malformed patch at line 55: @@ -8,6 +7,9 @@

User avatar
muzik
Posts: 5650
Joined: January 28th, 2016, 2:47 pm
Location: Scotland

Re: apgsearch v3.1

Post by muzik » July 12th, 2016, 12:22 pm

Image

Heck yeah. Moving on up in the ol' searches. (now give me an xp19 already so I can be remembered forever)


dvgrn was mentioning in some discussions in the spaceship thread that we should encourage a lot more people to use apgsearch and Catagolue. How would we go around dong this?

More importantly, how do we stop events such as the infamous Apple Bottom and I crashing Catagolue when I was away from home and left my computer searching? Because that would drive away traffic pretty badly.

User avatar
Apple Bottom
Posts: 1034
Joined: July 27th, 2015, 2:06 pm
Contact:

Re: apgsearch v3.1

Post by Apple Bottom » July 12th, 2016, 1:43 pm

drc wrote:I got this:

Code: Select all

The next patch would create the file apgmera.exe,
which already exists!  Assume -R? [n]
I pressed y, enter, and got this:
That's rather strange. What command exactly did you run?

Three possible snags I can think of right now:

a) the patch applies to a clean checkout of apgmera 3.28; best untar a fresh copy to work with.
b) if you're saving this in a text editor on a Windows system, be sure to convert it to Unix line endings first so patch(1) won't get confused.
c) I've been working off this commit, as all the following ones are doc changes only. (This shouldn't make a difference, but -- famous last words.)

EDIT: line endings ARE an issue; apgmera's codebase uses DOS line endings. I probably converted it long ago and then forgot. ;) Fixing that, here's the result you SHOULD be getting:

Code: Select all

$ dir
total 392
-rw-r--r-- 1 None None  21068 Jul 12 21:10 apgmera-3.28-ab7.patch
-rwxr-x--- 1 None None 376328 Jul 12 21:10 apgmera-cffe792fb46f8a374578994bfeacbb11b60d55dd-cffe792fb46f8a374578994bfeacbb11b60d55dd.zip
$ file apgmera-3.28-ab7.patch
apgmera-3.28-ab7.patch: unified diff output, ASCII text
$ unzip apgmera-cffe792fb46f8a374578994bfeacbb11b60d55dd-cffe792fb46f8a374578994bfeacbb11b60d55dd.zip
Archive:  apgmera-cffe792fb46f8a374578994bfeacbb11b60d55dd-cffe792fb46f8a374578994bfeacbb11b60d55dd.zip
cffe792fb46f8a374578994bfeacbb11b60d55dd
   creating: apgmera-cffe792fb46f8a374578994bfeacbb11b60d55dd-cffe792fb46f8a374578994bfeacbb11b60d55dd/
  inflating: apgmera-cffe792fb46f8a374578994bfeacbb11b60d55dd-cffe792fb46f8a374578994bfeacbb11b60d55dd/README
   creating: apgmera-cffe792fb46f8a374578994bfeacbb11b60d55dd-cffe792fb46f8a374578994bfeacbb11b60d55dd/gollybase/
  inflating: apgmera-cffe792fb46f8a374578994bfeacbb11b60d55dd-cffe792fb46f8a374578994bfeacbb11b60d55dd/gollybase/bigint.cpp
  inflating: apgmera-cffe792fb46f8a374578994bfeacbb11b60d55dd-cffe792fb46f8a374578994bfeacbb11b60d55dd/gollybase/bigint.h
  inflating: apgmera-cffe792fb46f8a374578994bfeacbb11b60d55dd-cffe792fb46f8a374578994bfeacbb11b60d55dd/gollybase/lifealgo.cpp
  inflating: apgmera-cffe792fb46f8a374578994bfeacbb11b60d55dd-cffe792fb46f8a374578994bfeacbb11b60d55dd/gollybase/lifealgo.h
  inflating: apgmera-cffe792fb46f8a374578994bfeacbb11b60d55dd-cffe792fb46f8a374578994bfeacbb11b60d55dd/gollybase/lifepoll.cpp
  inflating: apgmera-cffe792fb46f8a374578994bfeacbb11b60d55dd-cffe792fb46f8a374578994bfeacbb11b60d55dd/gollybase/lifepoll.h
  inflating: apgmera-cffe792fb46f8a374578994bfeacbb11b60d55dd-cffe792fb46f8a374578994bfeacbb11b60d55dd/gollybase/liferules.cpp
  inflating: apgmera-cffe792fb46f8a374578994bfeacbb11b60d55dd-cffe792fb46f8a374578994bfeacbb11b60d55dd/gollybase/liferules.h
  inflating: apgmera-cffe792fb46f8a374578994bfeacbb11b60d55dd-cffe792fb46f8a374578994bfeacbb11b60d55dd/gollybase/platform.h
  inflating: apgmera-cffe792fb46f8a374578994bfeacbb11b60d55dd-cffe792fb46f8a374578994bfeacbb11b60d55dd/gollybase/qlifealgo.cpp
  inflating: apgmera-cffe792fb46f8a374578994bfeacbb11b60d55dd-cffe792fb46f8a374578994bfeacbb11b60d55dd/gollybase/qlifealgo.h
  inflating: apgmera-cffe792fb46f8a374578994bfeacbb11b60d55dd-cffe792fb46f8a374578994bfeacbb11b60d55dd/gollybase/qlifedraw.cpp
  inflating: apgmera-cffe792fb46f8a374578994bfeacbb11b60d55dd-cffe792fb46f8a374578994bfeacbb11b60d55dd/gollybase/readpattern.cpp
  inflating: apgmera-cffe792fb46f8a374578994bfeacbb11b60d55dd-cffe792fb46f8a374578994bfeacbb11b60d55dd/gollybase/readpattern.h
  inflating: apgmera-cffe792fb46f8a374578994bfeacbb11b60d55dd-cffe792fb46f8a374578994bfeacbb11b60d55dd/gollybase/util.cpp
  inflating: apgmera-cffe792fb46f8a374578994bfeacbb11b60d55dd-cffe792fb46f8a374578994bfeacbb11b60d55dd/gollybase/util.h
  inflating: apgmera-cffe792fb46f8a374578994bfeacbb11b60d55dd-cffe792fb46f8a374578994bfeacbb11b60d55dd/gollybase/viewport.cpp
  inflating: apgmera-cffe792fb46f8a374578994bfeacbb11b60d55dd-cffe792fb46f8a374578994bfeacbb11b60d55dd/gollybase/viewport.h
   creating: apgmera-cffe792fb46f8a374578994bfeacbb11b60d55dd-cffe792fb46f8a374578994bfeacbb11b60d55dd/includes/
  inflating: apgmera-cffe792fb46f8a374578994bfeacbb11b60d55dd-cffe792fb46f8a374578994bfeacbb11b60d55dd/includes/boolean.out
  inflating: apgmera-cffe792fb46f8a374578994bfeacbb11b60d55dd-cffe792fb46f8a374578994bfeacbb11b60d55dd/includes/happyhttp.cpp
  inflating: apgmera-cffe792fb46f8a374578994bfeacbb11b60d55dd-cffe792fb46f8a374578994bfeacbb11b60d55dd/includes/happyhttp.h
  inflating: apgmera-cffe792fb46f8a374578994bfeacbb11b60d55dd-cffe792fb46f8a374578994bfeacbb11b60d55dd/includes/hashsoup.h
  inflating: apgmera-cffe792fb46f8a374578994bfeacbb11b60d55dd-cffe792fb46f8a374578994bfeacbb11b60d55dd/includes/incubator.h
  inflating: apgmera-cffe792fb46f8a374578994bfeacbb11b60d55dd-cffe792fb46f8a374578994bfeacbb11b60d55dd/includes/md5.cpp
  inflating: apgmera-cffe792fb46f8a374578994bfeacbb11b60d55dd-cffe792fb46f8a374578994bfeacbb11b60d55dd/includes/md5.h
  inflating: apgmera-cffe792fb46f8a374578994bfeacbb11b60d55dd-cffe792fb46f8a374578994bfeacbb11b60d55dd/includes/payosha256.h
  inflating: apgmera-cffe792fb46f8a374578994bfeacbb11b60d55dd-cffe792fb46f8a374578994bfeacbb11b60d55dd/includes/sha256.cpp
  inflating: apgmera-cffe792fb46f8a374578994bfeacbb11b60d55dd-cffe792fb46f8a374578994bfeacbb11b60d55dd/includes/sha256.h
  inflating: apgmera-cffe792fb46f8a374578994bfeacbb11b60d55dd-cffe792fb46f8a374578994bfeacbb11b60d55dd/includes/vlife.h
  inflating: apgmera-cffe792fb46f8a374578994bfeacbb11b60d55dd-cffe792fb46f8a374578994bfeacbb11b60d55dd/main.cpp
  inflating: apgmera-cffe792fb46f8a374578994bfeacbb11b60d55dd-cffe792fb46f8a374578994bfeacbb11b60d55dd/makefile
  inflating: apgmera-cffe792fb46f8a374578994bfeacbb11b60d55dd-cffe792fb46f8a374578994bfeacbb11b60d55dd/recompile.sh
  inflating: apgmera-cffe792fb46f8a374578994bfeacbb11b60d55dd-cffe792fb46f8a374578994bfeacbb11b60d55dd/rule2asm.py
  inflating: apgmera-cffe792fb46f8a374578994bfeacbb11b60d55dd-cffe792fb46f8a374578994bfeacbb11b60d55dd/vlifetest.cpp
$ cd apgmera-cffe792fb46f8a374578994bfeacbb11b60d55dd-cffe792fb46f8a374578994bfeacbb11b60d55dd/
$ dos2unix *
dos2unix: Skipping gollybase, not a regular file.
dos2unix: Skipping includes, not a regular file.
dos2unix: converting file main.cpp to Unix format...
dos2unix: converting file makefile to Unix format...
dos2unix: converting file README to Unix format...
dos2unix: converting file recompile.sh to Unix format...
dos2unix: converting file rule2asm.py to Unix format...
dos2unix: converting file vlifetest.cpp to Unix format...
$ patch -p1 <../apgmera-3.28-ab7.patch
patching file compilerule.sh
patching file main.cpp
patching file makefile
patching file rule2asm.py
$ 
If you skip the conversion step, you'll get this instead:

Code: Select all

patching file compilerule.sh
patching file main.cpp
Hunk #1 FAILED at 1 (different line endings).
Hunk #2 FAILED at 8 (different line endings).
Hunk #3 FAILED at 25 (different line endings).
Hunk #4 FAILED at 1315 (different line endings).
Hunk #5 FAILED at 1324 (different line endings).
Hunk #6 FAILED at 1333 (different line endings).
Hunk #7 FAILED at 1547 (different line endings).
Hunk #8 FAILED at 1582 (different line endings).
Hunk #9 FAILED at 1616 (different line endings).
Hunk #10 FAILED at 1646 (different line endings).
Hunk #11 FAILED at 1661 (different line endings).
Hunk #12 FAILED at 1678 (different line endings).
Hunk #13 FAILED at 1702 (different line endings).
Hunk #14 FAILED at 1736 (different line endings).
Hunk #15 FAILED at 1743 (different line endings).
Hunk #16 FAILED at 1759 (different line endings).
Hunk #17 FAILED at 1779 (different line endings).
Hunk #18 FAILED at 1800 (different line endings).
Hunk #19 FAILED at 1819 (different line endings).
19 out of 19 hunks FAILED -- saving rejects to file main.cpp.rej
patching file makefile
Hunk #1 FAILED at 8 (different line endings).
Hunk #2 FAILED at 23 (different line endings).
Hunk #3 FAILED at 36 (different line endings).
Hunk #4 FAILED at 47 (different line endings).
4 out of 4 hunks FAILED -- saving rejects to file makefile.rej
patching file rule2asm.py
I'm unable to reproduce your message, though, or in fact to conceive of circumstances under which it might arise.
Last edited by Apple Bottom on July 12th, 2016, 3:17 pm, edited 1 time in total.
If you speak, your speech must be better than your silence would have been. — Arabian proverb

Catagolue: Apple Bottom • Life Wiki: Apple Bottom • Twitter: @_AppleBottom_

Proud member of the Pattern Raiders!

User avatar
muzik
Posts: 5650
Joined: January 28th, 2016, 2:47 pm
Location: Scotland

Re: apgsearch v3.1

Post by muzik » July 12th, 2016, 2:55 pm

Why do some hauls have blue links? I know yellow is uncommitted, red is rejected and green is normal

User avatar
Apple Bottom
Posts: 1034
Joined: July 27th, 2015, 2:06 pm
Contact:

Re: apgsearch v3.1

Post by Apple Bottom » July 14th, 2016, 8:06 am

Something else again. apgmera's currently got a problem where it crashes with a stack overflow when running on certain rules. I first noticed this on March 13 during alpha-testing, running version 3.04 on B3678/S35678 using seed m_W8v7RkVS4Gg4.

Calcyman investigated, and identified the offending soup, #947595:

Code: Select all

x = 16, y = 16, rule = B3678/S35678
ooboobbobbbbobbb$
oooooboboobboobb$
ooobooobbbboobbb$
bbbboobobbboooob$
ooooooobbboobbbo$
oooobooobboobbbb$
oobbboobooboobbb$
bbbobboobobobobb$
ooobboooboooobob$
boooobobobooobbb$
bboobbbbbobooobb$
bbobooobobbbbbbo$
oobboobbbbbbobbo$
ooobooooooobbobb$
bbobbboboboobobo$
boobbbbbbobbbobb!
As well as the exact location where everything goes kaboom:

Code: Select all

(gdb) bt full
#0  0x00000000004138d8 in SoupSearcher::separate (this=0x7ffde841e920, universe=0x7ffde841e700, proceedNonetheless=false, 
    curralgo=0x7868f0, suffix=...) at main.cpp:1278
        j = 0
        coords = 0x7ffde78a1200
        i = 0
        intList = {<std::_Vector_base<int, std::allocator<int> >> = {
            _M_impl = {<std::allocator<int>> = {<__gnu_cxx::new_allocator<int>> = {<No data fields>}, <No data fields>}, 
              _M_start = 0x7f1ebca72010, _M_finish = 0x7f1ebdbaee10, _M_end_of_storage = 0x7f1ebea72010}}, <No data fields>}
        population = 1505635
        ll = 4518783
        gliderstatus = 0
        annoyance = 0
        x = 21
        y = 0
        sqt = 0xfddf78
        nGliders = 0
        nBeehives = 0
He said:
Calcyman wrote: That is to say, it's currently trying to process an object with a population of 1505635, namely that huge growth pattern.

It strikes me that the segfault is caused by attempting to declare the (local, therefore on the stack!) array coords with a size of over 12 megabytes. Replacing this with a std::vector<int> seems to circumvent the segfault, but the program subsequently takes forever trying to run this enormous object for thousands of generations in QuickLife.
These stack overflows have occasionally reared their head since then in various rules, including the higher symmetries of Day & Night. With some rules they're not a big deal; with others they occurs so frequently that soup-searching those rules is all but impossible.

I got bitten by this (or at least SOME stack overflow) again today after (foolishly, perhaps) deciding to poke at B368/S12578. Dave Eppstein mentions this rule in "Growth and Decay in Life-like cellular automata", saying:
David Eppstein wrote: B368/S12578 like HighLife supports a simple replicator, in the form of a 1 × 5 block of cells; it copies itself every 13 time steps. This replicator may be used to form oscillators of arbitrarily high periods; combinations of these oscillators can form guns for a small c/8 diagonal spaceship supported by this rule. As with HighLife, it seems likely that push-pull reactions can be used to form spaceships with arbitrarily slow speeds. However, with random initial conditions, this rule forms regions of chaotic activity interspersed with other regions of small oscillators and still lifes (Fig. 6.10), indicating a mixture of Class II and Class III behavior.
(That spaceship is glider 1297.)

The rule is extremely slow to search in apgmera, thanks to replicators and PATHOLOGICALs, and the stack overflow eventually happened after about 10 hours and 328 soups, and ~43000 objects. (Not to mention about a million lines of debug output. ;)) The seed used was m_f8A3KfGPE84g.

For the benefit of anyone wanting to investigate similar rules in the future, here's a pack I used to a) produce said debug output and b) submit results after 250,000 objects had been censused (that bit's entirely untested, and knowing me therefore will likely not actually work). Note that this applies on top of 3.28-ab7.

Code: Select all

diff -Nru playingaround-cffe/main.cpp b368s12578-cffe/main.cpp
--- playingaround-cffe/main.cpp	2016-07-12 01:19:12.067791100 +0200
+++ b368s12578-cffe/main.cpp	2016-07-13 17:30:01.429069400 +0200
@@ -32,6 +32,7 @@
 #define EXIT_USERQUIT	1
 #define EXIT_HAULSDONE	2
 #define EXIT_TIMESUP	3
+#define EXIT_OBJECTSDONE 4
 
 clock_t programStartupTime;
 int quietLevel = 0;
@@ -226,14 +227,19 @@
     std::vector<std::pair<double, double> > pairlist;
     std::vector<std::pair<double, double> > pairlist2;
     double cumpop = 1.0;
+    
+    std::cout << "powerlyse(): entering, stepsize = " << stepsize << ", numsteps = " << numsteps << ", startgen = " << startgen << std::endl;
 
     for (int i = 0; i < numsteps; i++) {
+        if(!(i % 100)) {
+            std::cout << "powerlyse(): step = " << i << ", population = " << curralgo->getPopulation().toint() << "..." << std::endl;
+        }
         runPattern(curralgo, stepsize);
         cumpop += curralgo->getPopulation().toint();
         pairlist.push_back(std::make_pair(std::log(i*stepsize+startgen), std::log(cumpop)));
         pairlist2.push_back(std::make_pair(std::log(i+1), std::log(cumpop)));
     }
-
+    
     double power = regress(pairlist);
     double power2 = regress(pairlist2);
 
@@ -248,6 +254,8 @@
     } else {
         return "zz_QUADRATIC";
     }
+    
+    std::cout << "powerlyse(): finished." << std::endl;
 
 }
 
@@ -585,7 +593,11 @@
  */
 int stabilise3(vlife* curralgo) {
 
+    std::cout << "stabilise3(): entering" << std::endl;
+
     int pp = naivestab_awesome(curralgo);
+    
+    std::cout << "stabilise3(): naivestab_awesome returned " << pp << std::endl;
 
     if (pp > 0) {
         return pp;
@@ -598,7 +610,12 @@
 
     int generation = 0;
 
+    std::cout << "stabilise3(): running for 4000 steps..." << std::endl;
+
     for (int j = 0; j < 4000; j++) {
+    
+        if(!(j % 100))
+            std::cout << "stabilise3(): step = " << j << ", population = " << curralgo->totalPopulation() << std::endl;
 
         runPattern(curralgo, 30);
         generation += 30;
@@ -644,8 +661,12 @@
     }
 
     std::cout << "Failed to detect periodic behaviour!" << std::endl;
+    
+    std::cout << "stabilise3(): running pattern for 65536 steps..." << std::endl;
 
     runPattern(curralgo, 65536);
+    
+    std::cout << "stabilise3(): ...done." << std::endl;
 
     return 1280;
 
@@ -663,14 +684,15 @@
     int period = -1;
     int xdisplacement = 0;
     int ydisplacement = 0;
-
+    
+    std::cout << "getRepresentation(): maxperiod = " << maxperiod << std::endl;
+    
     if (getBoundingBox(curralgo, bbOrig)) {
 
         uint64_t hash1 = hash_rectangle(curralgo, bbOrig[0], bbOrig[1], bbOrig[2], bbOrig[3]);
         int pop1 = curralgo->getPopulation().toint();
 
         for (int i = 1; i <= maxperiod; i++) {
-
             runPattern(curralgo, 1);
 
             int boundingBox[4];
@@ -695,11 +717,16 @@
 
     if (period <= 0) {
         // std::cout << "Object is aperiodic (population = " << initpop << ")." << std::endl;
+        std::cout << "getRepresentation(): aperiodic object, calling linearlyse()..." << std::endl;
         repr = linearlyse(curralgo, 4100);
+        std::cout << "getRepresentation(): ...done." << std::endl;
         if (repr[0] != 'y') {
+            std::cout << "getRepresentation(): not a yl pattern, calling powerlyse()..." << std::endl;
             repr = powerlyse(curralgo, 32, 8000, 5380);
+            std::cout << "getRepresentation(): ...done." << std::endl;
         }
     } else {
+        std::cout << "getRepresentation(): detected period = " << period << std::endl;
         // std::cout << "Object has period " << period << "." << std::endl;
         std::ostringstream ss;
         std::string barecode = canonise(curralgo, period);
@@ -731,6 +758,8 @@
     bounds[0] = period;
     bounds[1] = xdisplacement;
     bounds[2] = ydisplacement;
+    
+    std::cout << "getRepresentation(): finished, repr = " << repr << std::endl;
 
     return repr;
 
@@ -1116,6 +1145,8 @@
         int top = celllist[1];
         int right = celllist[0];
         int bottom = celllist[1];
+        
+        std::cout << "classify(): entering, population = " << population << std::endl;
 
         for (int i = 0; i < ll; i += 2) {
             if (left > celllist[i])
@@ -1165,8 +1196,13 @@
             curralgo->endofpattern();
 
             int bounds[3];
+            
+            std::cout << "classify(): calling getRepresentation()..." << std::endl;
+            
             // repr = getRepresentation(curralgo, 4000, bounds);
             repr = getRepresentation(curralgo, 1280, bounds);
+            
+            std::cout << "classify(): ...done." << std::endl;
 
             if (repr.compare("PATHOLOGICAL") == 0) {
                 // std::cout << "Pathological object at " << left << ", " << top << ", " << right << ", " << bottom << std::endl;
@@ -1179,17 +1215,25 @@
                 // Periodic object:
                 if (bounds[1] == 0 && bounds[2] == 0) {
                     // Still-life or oscillator:
+                    std::cout << "classify(): calling pseudoBangBang() on still life or oscillator..." << std::endl;
                     elements = pseudoBangBang(curralgo, bounds[0], false);
+                    std::cout << "classify(): ...done." << std::endl;
                 } else {
                     // Spaceship:
                     if (bounds[0] <= 8) {
                         #ifdef GLIDERS_EXIST
-                        if (bounds[0] == 4)
+                        if (bounds[0] == 4) {
+                            std::cout << "classify(): calling sss()..." << std::endl;
                             elements = sss(curralgo);
+                            std::cout << "classify(): ...done." << std::endl;
+                        }
                         #endif
 
-                        if (elements.size() == 0)
+                        if (elements.size() == 0) {
+                            std::cout << "classify(): calling pseudoBangBang() on spaceship..." << std::endl;
                             elements = pseudoBangBang(curralgo, bounds[0], true);
+                            std::cout << "classify(): ...done." << std::endl;
+                        }
                     } else {
                         elements.push_back(repr);
                     }
@@ -1228,6 +1272,8 @@
 
         uint64_t cachearray[I_HEIGHT];
         uint64_t emptymatrix[I_HEIGHT];
+        
+        std::cout << "separate(): entering, proceedNonetheless = " << proceedNonetheless << ", suffix = " << suffix << std::endl;
 
         memset(emptymatrix,0, I_HEIGHT * sizeof(uint64_t));
 
@@ -1236,10 +1282,16 @@
         std::vector<std::string> objlist;
         std::vector<int> gcoordlist;
         std::vector<Incube*> gpointerlist;
+        
+        std::cout << "separate(): iterating over tiles..." << std::endl;
+        std::cout << "separate(): number of tiles = " << std::distance(universe->tiles.begin(), universe->tiles.end()) << std::endl;
 
         std::map<std::pair<int, int>, Incube>::iterator it;
         for (it = universe->tiles.begin(); it != universe->tiles.end(); it++)
         {
+        
+            std::cout << "separate(): tiles left = " << std::distance(it, universe->tiles.end()) << std::endl;
+        
             memset(cachearray, 0, I_HEIGHT * sizeof(uint64_t));
 
                     // std::cout << "blah2" << std::endl;
@@ -1262,7 +1314,10 @@
                                     gcoordlist.push_back(y);
                                     gpointerlist.push_back(sqt);
                                 } else if (gliderstatus == 0) {
+                                
+                                    std::cout << "separate(): calling universe->getComponent()..." << std::endl;
                                     vector<int> intList = universe->getComponent(sqt,x,y);
+                                    std::cout << "separate(): ...done." << std::endl;
 
                                     int population = intList.back();
                                     int ll = intList.size() - 1;
@@ -1290,7 +1345,9 @@
                                                 }
                                             }
 
+                                            std::cout << "separate(): calling classify..." << std::endl;
                                             pathologicals += classify(coords, population, objlist, curralgo);
+                                            std::cout << "separate(): ...done." << std::endl;
                                         #ifdef STANDARD_LIFE
                                         }
                                         #endif
@@ -1311,8 +1368,12 @@
                 }
             }
         }
+        
+        std::cout << "separate(): ...done." << std::endl;
 
         int gl = gpointerlist.size();
+        
+        std::cout << "separate(): checking for gliders..." << std::endl;
 
         for (int i = 0; i < gl; i++) {
             int x = gcoordlist[2*i];
@@ -1326,6 +1387,8 @@
                 }
             }
         }
+        
+        std::cout << "separate(): ...done." << std::endl;
 
         bool ignorePathologicals = false;
 
@@ -1416,13 +1479,15 @@
             #endif
             }
         }
+        
+        std::cout << "separate(): finished." << std::endl;
 
         return false;
 
     }
 
     void censusSoup(std::string seedroot, std::string suffix, lifealgo* curralgo) {
-
+    
         vlife btq;
         btq.tilesProcessed = 0;
 
@@ -1430,14 +1495,19 @@
 
         hashsoup(imp, seedroot + suffix, SYMMETRY);
 
+        std::cout << "censusSoup(): entering, seedroot = " << seedroot << ", suffix = " << suffix << std::endl;
+        std::cout << "censusSoup(): attempting to stabilize..." << std::endl;
         int duration = stabilise3(imp);
+        std::cout << "censusSoup(): stabilise3 finished, duration = " << duration << std::endl;
 
         bool failure = true;
         int attempt = 0;
 
         // Repeat until there are no pathological objects, or until five attempts have elapsed:
         while (failure) {
-
+        
+            std::cout << "censusSoup(): attempt " << attempt << std::endl;
+        
             failure = false;
 
             if (imp->totalPopulation()) {
@@ -1445,26 +1515,38 @@
                 // Convert to LifeHistory:
                 vlife universe;
                 copycells(imp, &universe, true);
-
+                
+                std::cout << "censusSoup() running in LifeHistory..." << std::endl;
+                
                 for (int j = 0; j < duration/2; j++) {
                     universe.run2gens(true);
                 }
-
+                
+                std::cout << "censusSoup(): ...done." << std::endl;
+                
                 incubator icb;
                 copycells(&universe, &icb);
-
+                
+                std::cout << "censusSoup(): attempting to separate..." << std::endl;
                 // failure = separate(&universe, (attempt >= 5), curralgo, suffix);
                 failure = separate(&icb, (attempt >= 5), curralgo, suffix);
+                std::cout << "censusSoup(): separate finished, failure = " << failure << std::endl;
 
             }
 
             // Pathological object detected:
             if (failure) {
+                std::cout << "censusSoup(): detected pathological object!" << std::endl;
                 attempt += 1;
+                std::cout << "censusSoup(): running pattern for 10000 generations..." << std::endl;
                 runPattern(imp, 10000);
+                std::cout << "censusSoup(): ...done." << std::endl;
                 duration = 4000;
             }
         }
+        
+        std::cout << "censusSoup(): finished." << std::endl;
+        
     }
 
 
@@ -1797,6 +1879,15 @@
             if(seconds)
                 if(((double) (curr_clock - programStartupTime) / CLOCKS_PER_SEC) > seconds)
                     quit = EXIT_TIMESUP;
+                    
+            
+            long long totobjs = 0;
+            std::vector<std::pair<long long, std::string> > censusList = soup.getSortedList(totobjs);
+            
+            std::cout << "Objects censused so far: " << totobjs << std::endl;
+            
+            if(totobjs > 250000)
+                quit = EXIT_OBJECTSDONE;
         }
 
         if ((i % n == 0) || quit) {
Here's the stackdump (note that Cygwin doesn't produce proper coredumps):

Code: Select all

Exception: STATUS_STACK_OVERFLOW at rip=00100429736
rax=00000000000039F0 rbx=000000000003EF3D rcx=00000000FFE030D0
rdx=000006FF710A0010 rsi=000000060207D598 rdi=00000000FFFF80D0
r8 =00000000FFFF807C r9 =00000001801523B0 r10=0000000100000000
r11=00000003FDE1F852 r12=000000060207D598 r13=0000000000000004
r14=0000000000000030 r15=0000000000000062
rbp=00000000FFFF8150 rsp=00000000FFFF80B8
program=C:\cygwin64\home\User\devel\apgmera\b368s12578-cffe\apgmera.exe, pid 6700, thread unknown (0x104C)
cs=0033 ds=002B es=002B fs=0053 gs=002B ss=002B
Stack trace:
Frame        Function    Args
000FFFF8150  00100429736 (0010042D4BA, 000FFFF80E0, 00601EE9470, 00200000000)
000FFFF8150  000001F79F0 (000FFFF80E0, 00601EE9470, 00200000000, 00100000001)
000FFFF8150  00000688560 (00601EE9470, 00200000000, 00100000001, 00000000002)
000FFFF8150  0010042D4BA (000FFFFC500, 003FDE88720, 0060003B060, 000FFFFC4E0)
000000007D0  0010042A9BA (0018031D1B8, 000FFFFC6F0, 0060003B060, 000FFFFC740)
000FFFFC700  0010040C41E (000FFFFCB00, 000FFFFCB10, 00100000001, 00100000001)
003FDE7BBE0  0010043C592 (000FFFFCC00, 0018034A930, 00180068491, 0000000002F)
000FFFFCCC0  00180047BD2 (00000000000, 00000000000, 00000000000, 00000000000)
00000000000  0018004591C (00000000000, 00000000000, 00000000000, 00000000000)
000FFFFFFF0  001800459B4 (00000000000, 00000000000, 00000000000, 00000000000)
End of stack trace
I don't know if it's the same stack overflow, but -- TL;DR, would be great to see these fixed.
If you speak, your speech must be better than your silence would have been. — Arabian proverb

Catagolue: Apple Bottom • Life Wiki: Apple Bottom • Twitter: @_AppleBottom_

Proud member of the Pattern Raiders!

User avatar
Scorbie
Posts: 1692
Joined: December 7th, 2013, 1:05 am

Re: apgsearch v3.1

Post by Scorbie » July 17th, 2016, 6:27 am

Sorry for not-trying-before-asking, but does this compile with 32bit windows with a cpu that has 64bit instructions? Thanks.

User avatar
Apple Bottom
Posts: 1034
Joined: July 27th, 2015, 2:06 pm
Contact:

Re: apgsearch v3.1

Post by Apple Bottom » July 17th, 2016, 8:43 am

Scorbie wrote:Sorry for not-trying-before-asking, but does this compile with 32bit windows with a cpu that has 64bit instructions? Thanks.
You'll need a 64-bit toolchain (i.e. C compiler etc.), which may or may not require a 64-bit OS underneath.

Going out on a hoof -- if you're using Cygwin, you'll need the 64-bit version of that, which (probably) requires a 64-bit OS, and you'll also need the Cygwin environment to run the program. If you're using MinGW, you'll probably need a 64-bit OS unless you're cross-compiling, but the resulting binary should work on 32-bit Windows versions, so long as you have a 64-bit CPU.

But take all that with a BIG chunk of salt, and try for yourself. (Also, let us know the result, no matter whether it's "it worked" or "I ran into trouble"!)
If you speak, your speech must be better than your silence would have been. — Arabian proverb

Catagolue: Apple Bottom • Life Wiki: Apple Bottom • Twitter: @_AppleBottom_

Proud member of the Pattern Raiders!

User avatar
Scorbie
Posts: 1692
Joined: December 7th, 2013, 1:05 am

Re: apgsearch v3.1

Post by Scorbie » July 17th, 2016, 10:11 am

Apple Bottom wrote:
Scorbie wrote:Sorry for not-trying-before-asking, but does this compile with 32bit windows with a cpu that has 64bit instructions? Thanks.
You'll need a 64-bit toolchain (i.e. C compiler etc.), which may or may not require a 64-bit OS underneath.

Going out on a hoof -- if you're using Cygwin, you'll need the 64-bit version of that, which (probably) requires a 64-bit OS, and you'll also need the Cygwin environment to run the program. If you're using MinGW, you'll probably need a 64-bit OS unless you're cross-compiling, but the resulting binary should work on 32-bit Windows versions, so long as you have a 64-bit CPU.

But take all that with a BIG chunk of salt, and try for yourself. (Also, let us know the result, no matter whether it's "it worked" or "I ran into trouble"!)
@Apple bottom Installed msys2 which gives me mingw-w64. I'll try with that and see if it compiles, in the upcoming tuesday.

User avatar
Scorbie
Posts: 1692
Joined: December 7th, 2013, 1:05 am

Re: apgsearch v3.1

Post by Scorbie » July 18th, 2016, 12:24 pm

msys2 32bit on 32bit OS cannot run mingw-w64_x86-64-gcc. (Thought it was a cross-compiler, but I guess not.) I guess one can compile 64bit software on 64bit only with msys2.

@Applebottom speaking of msys2, I think it is pretty nice for these kind of tasks. It works similarly to cygwin, has the pacman from Arch Linux, and seems to build native windows software without POSIX emulation or dll dependencies.

Could you follow these steps to see if it works?

1. Go to MSYS2 installer and follow instructions. You can access MSYS2 shell, mingw-w64 32bit and 64bit (target arch) shell from the start menu.
1-1. The update seems to be slightly broken for now. After you update, the symlinks in the start menu seems to be broken. Change them to:
msys2: C:\msys32\msys2_shell.cmd
mingw-w64 32bit: C:\msys32\msys2_shell.cmd -mingw32
mingw-w64 64bit: C:\msys32\msys2_shell.cmd -mingw64
2. launch msys2 shell and type pacman -S python2 make mingw-w64-x86_64-gcc.
3. get the apgmera source. In recompile.sh, change "python" to "python2". (Seems msys2, as Arch, uses python3 as the default python package.)
4. launch mingw-64 64bit shell and run recompile.sh and install any dependencies with pacman if necessary? I dunno...

This seems to be the easiest way to make it work, if the dependency is resolvable by pacman.

About the three shells, if I got it correctly:
msys2: compiles msys2 packages(?) or programs not for distribution. Depends on msys2.dll or something like that. Uses a posix emulation layer. I'm pretty sure cygwin is better that this only.
mingw-w64: compiles native 64bit binaries without dll dependency. Needs to install package mingw-w64-x86_64-gcc to work.
mingw-w32: compiles native 32bit binaries. mingw-w64-i686-gcc needed.

MSYS2 installation guide:
https://sourceforge.net/p/msys2/wiki/MS ... tallation/

User avatar
Apple Bottom
Posts: 1034
Joined: July 27th, 2015, 2:06 pm
Contact:

Re: apgsearch v3.1

Post by Apple Bottom » July 19th, 2016, 4:23 pm

Scorbie wrote:msys2 32bit on 32bit OS cannot run mingw-w64_x86-64-gcc. (Thought it was a cross-compiler, but I guess not.) I guess one can compile 64bit software on 64bit only with msys2.

@Applebottom speaking of msys2, I think it is pretty nice for these kind of tasks. It works similarly to cygwin, has the pacman from Arch Linux, and seems to build native windows software without POSIX emulation or dll dependencies.

Could you follow these steps to see if it works?

[...]
I tried, but as far as I can tell msys2 does not package g++. Perhaps it's just a matter of finding the right package, but I've not managed; it's not in the mingw-w64-x86_64-toolchain bundle.
If you speak, your speech must be better than your silence would have been. — Arabian proverb

Catagolue: Apple Bottom • Life Wiki: Apple Bottom • Twitter: @_AppleBottom_

Proud member of the Pattern Raiders!

User avatar
Scorbie
Posts: 1692
Joined: December 7th, 2013, 1:05 am

Re: apgsearch v3.1

Post by Scorbie » July 19th, 2016, 6:02 pm

Apple Bottom wrote: I tried, but as far as I can tell msys2 does not package g++. Perhaps it's just a matter of finding the right package, but I've not managed; it's not in the mingw-w64-x86_64-toolchain bundle.
You sure? You might have opened the wrong shell. You should launch mingw-w64 shell, not msys2 shell.

(I tried to make it boldface, but apparently there seems to be a typo in my previous post.

User avatar
Apple Bottom
Posts: 1034
Joined: July 27th, 2015, 2:06 pm
Contact:

Re: apgsearch v3.1

Post by Apple Bottom » July 19th, 2016, 6:15 pm

Scorbie wrote:
Apple Bottom wrote: I tried, but as far as I can tell msys2 does not package g++. Perhaps it's just a matter of finding the right package, but I've not managed; it's not in the mingw-w64-x86_64-toolchain bundle.
You sure? You might have opened the wrong shell. You should launch mingw-w64 shell, not msys2 shell.

(I tried to make it boldface, but apparently there seems to be a typo in my previous post.
Derp. Let me try that again.
$ make -j 4
g++ -c -Wall -O3 -march=native -fopenmp -DUSE_OPEN_MP main.cpp -o main.o
g++ -c -Wall -O3 -march=native -fopenmp -DUSE_OPEN_MP includes/sha256.cpp -o includes/sha256.o
g++ -c -Wall -O3 -march=native -fopenmp -DUSE_OPEN_MP includes/md5.cpp -o includes/md5.o
g++ -c -Wall -O3 -march=native -fopenmp -DUSE_OPEN_MP includes/happyhttp.cpp -o includes/happyhttp.o
g++ -c -Wall -O3 -march=native -fopenmp -DUSE_OPEN_MP gollybase/bigint.cpp -o gollybase/bigint.o
g++ -c -Wall -O3 -march=native -fopenmp -DUSE_OPEN_MP gollybase/lifealgo.cpp -o gollybase/lifealgo.o
g++ -c -Wall -O3 -march=native -fopenmp -DUSE_OPEN_MP gollybase/qlifealgo.cpp -o gollybase/qlifealgo.o
g++ -c -Wall -O3 -march=native -fopenmp -DUSE_OPEN_MP gollybase/util.cpp -o gollybase/util.o
g++ -c -Wall -O3 -march=native -fopenmp -DUSE_OPEN_MP gollybase/lifepoll.cpp -o gollybase/lifepoll.o
g++ -c -Wall -O3 -march=native -fopenmp -DUSE_OPEN_MP gollybase/liferules.cpp -o gollybase/liferules.o
g++ -c -Wall -O3 -march=native -fopenmp -DUSE_OPEN_MP gollybase/viewport.cpp -o gollybase/viewport.o
g++ -c -Wall -O3 -march=native -fopenmp -DUSE_OPEN_MP gollybase/readpattern.cpp -o gollybase/readpattern.o
g++ -c -Wall -O3 -march=native -fopenmp -DUSE_OPEN_MP gollybase/qlifedraw.cpp -o gollybase/qlifedraw.o
g++ -fopenmp main.o includes/sha256.o includes/md5.o includes/happyhttp.o gollybase/bigint.o gollybase/lifealgo.o gollybase/qlifealgo.o gollybase/util.o gollybase/lifepoll.o gollybase/liferules.o gollybase/viewport.o gollybase/readpattern.o gollybase/qlifedraw.o -o apgmera
includes/happyhttp.o:happyhttp.cpp:(.text+0x49a): undefined reference to `__imp_inet_addr'
includes/happyhttp.o:happyhttp.cpp:(.text+0x4c5): undefined reference to `__imp_gethostbyname'
includes/happyhttp.o:happyhttp.cpp:(.text+0x52c): undefined reference to `__imp_WSAGetLastError'
includes/happyhttp.o:happyhttp.cpp:(.text+0x5d6): undefined reference to `__imp_select'
includes/happyhttp.o:happyhttp.cpp:(.text+0x5e5): undefined reference to `__WSAFDIsSet'
includes/happyhttp.o:happyhttp.cpp:(.text+0x64a): undefined reference to `__imp_inet_addr'
includes/happyhttp.o:happyhttp.cpp:(.text+0x680): undefined reference to `__imp_htons'
includes/happyhttp.o:happyhttp.cpp:(.text+0x69e): undefined reference to `__imp_socket'
includes/happyhttp.o:happyhttp.cpp:(.text+0x6b7): undefined reference to `__imp_connect'
includes/happyhttp.o:happyhttp.cpp:(.text+0x6d5): undefined reference to `__imp_gethostbyname'
includes/happyhttp.o:happyhttp.cpp:(.text+0x76b): undefined reference to `__imp_send'
includes/happyhttp.o:happyhttp.cpp:(.text+0x16f9): undefined reference to `__imp_closesocket'
includes/happyhttp.o:happyhttp.cpp:(.text+0x1bec): undefined reference to `__imp_send'
includes/happyhttp.o:happyhttp.cpp:(.text+0x294c): undefined reference to `__imp_send'
includes/happyhttp.o:happyhttp.cpp:(.text+0x3b17): undefined reference to `__imp_select'
includes/happyhttp.o:happyhttp.cpp:(.text+0x3b2a): undefined reference to `__WSAFDIsSet'
includes/happyhttp.o:happyhttp.cpp:(.text+0x3b54): undefined reference to `__imp_recv'
collect2.exe: error: ld returned 1 exit status
makefile:45: recipe for target 'apgmera' failed
make: *** [apgmera] Error 1
$
OK, let's edit the makefile and link in libws2_32, as before...
$ make -j 4
g++ -c -Wall -O3 -march=native -fopenmp -DUSE_OPEN_MP main.cpp -o main.o
g++ -fopenmp main.o includes/sha256.o includes/md5.o includes/happyhttp.o gollybase/bigint.o gollybase/lifealgo.o gollybase/qlifealgo.o gollybase/util.o gollybase/lifepoll.o gollybase/liferules.o gollybase/viewport.o gollybase/readpattern.o gollybase/qlifedraw.o -o apgmera -lws2_32
true
true oo o
true oo ooo
true o
true oo ooo
true o o
true o o
true o
$
Good, so is it working?
$ ./apgmera.exe

Greetings, this is apgmera v3.28, configured for b3s23/C1.

Peer-reviewing hauls:

Internet does not exist.
No response!
Authentication failed.
Received no response from /verify.
Internet does not exist.
No response!
Authentication failed.
Received no response from /verify.
Internet does not exist.
No response!
Authentication failed.
Received no response from /verify.

Peer-review complete; proceeding search.
[...]
No.
If you speak, your speech must be better than your silence would have been. — Arabian proverb

Catagolue: Apple Bottom • Life Wiki: Apple Bottom • Twitter: @_AppleBottom_

Proud member of the Pattern Raiders!

Post Reply