• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

atconfigs/H03-Sep-2004-3,6502,613

atresults/H03-Sep-2004-

rc/H06-Apr-2005-18,56618,191

rc-test/H03-May-2022-1,5921,434

MakefileH A D03-May-20222.2 KiB7534

READMEH A D19-Jul-20058.6 KiB278192

TODOH A D27-Aug-2004528 1613

asm.scmH A D05-Apr-20052.6 KiB10885

autotest.pyH A D05-Apr-20053.6 KiB12286

basic.scmH A D07-Apr-20057.3 KiB313212

bench.pyH A D05-Apr-20052.2 KiB7659

code.scmH A D05-Apr-20051.9 KiB7149

config.scmH A D05-Apr-20051.2 KiB4332

defs.scmH A D05-Apr-20051.6 KiB7552

exhaust.cH A D08-Apr-200516.3 KiB659464

exhaust.hH A D05-Apr-20051.1 KiB5127

firstdiff.pyH A D05-Apr-2005523 2418

fm_asm.cH A D22-Jul-200537.7 KiB1,4801,201

fm_asm.hH A D05-Apr-20051.5 KiB5738

fmars.cH A D05-Apr-200510.2 KiB367300

fmars.cfgH A D08-Apr-20055.1 KiB215162

fmars.cfg-amd64H A D08-Apr-20055.1 KiB215162

fmars.cfg-athlonH A D07-Apr-20055 KiB214161

fmars.cfg-defaultH A D08-Apr-20055.1 KiB215162

fmars.cfg-pentium2and3H A D07-Apr-20055 KiB214161

fmars.hH A D05-Apr-20053.4 KiB14228

fmars.iH A D08-Apr-20052.9 KiB127107

fsh.setH A D27-Aug-20043.4 KiB351350

header.scmH A D06-Apr-20052.4 KiB131103

insn.hH A D05-Apr-20053.2 KiB15470

insn.scmH A D05-Apr-200517.2 KiB519401

misc.scmH A D05-Apr-20052.3 KiB9855

pymars.pyH A D08-Apr-20051.2 KiB5633

rcasmH A D25-Aug-2004234 86

skel.scmH A D07-Apr-20058.8 KiB293233

srfi-26.scmH A D05-Apr-20053.9 KiB9835

sumtimes.pyH A D05-Apr-2005180 117

test.plH A D05-Aug-20041.5 KiB6949

top50.setH A D03-Aug-20042.5 KiB259258

README

11) Introduction
22) Compilation
33) Using fmars
44) Redcode assembler
55) Python (SWIG) interface
66) Known issues and contact information
7
8==========
9
10
111) Introduction
12
13fmars is Fast Memory Array Redcode Simulator - a specialized simulator
14for the game of Corewars. It's designed to be of particular use in automated
15redcode optimizers and evolvers. fmars borrows the idea from Martin Ankerl's
16qmars and pushes it to the extreme - it generates source code with special
17case for every possible opcode/addressing mode combination. This allows
18some optimizations that aren't possible in other simulators. fmars is
19compatible with pMARS with an exception for p-space, which is not yet
20implemented.
21
22==========
23
24
252) Compilation
26
27To build fmars, you will need GCC (preferrably >= 3.2) and Guile 1.6
28(Scheme interpreter). It should be possible to compile fmars with a different
29compiler, but probably (at least for Intel's compiler) the performance will
30be much worse, and some of optimizations rely on GCC extensions.
31
32
33The code generator takes a list of instructions as an input, and produces
34a simulator which will be able to run warriors consisting of these
35instructions. Trying to run a warrior that contains an instruction that
36wasn't included in generator's input will cause the simulator to report an
37error.
38
39The generator can read the list of instructions either from a warrior
40assembled by pMARS, or from a file containing lines in the form:
41
42opcode.modifer a_addressing_mode b_addressing_mode
43
44The make variable INSN_FILES controls which files will be parsed, and is
45set to 'fsh.set' by default. So, to build a mars that will supports every
46warrior from Fixed Strategy Hill, and additionally a warrior 'war.red',
47issue the following command:
48
49make INSN_FILES="fsh.set war.red"
50
51where 'war.red' is a warrior preprocessed by pMARS or fmars parser. This
52should result the generation of the object file 'fm_sim.o' and the header
53file 'fm_types.h'. Then it should be possible to link the mars with your
54program. Note that header files 'insn.h' and 'exhaust.h' slightly differ
55from the ones from original exhaust.
56
57
58The quality of generated code is controlled by configuration file
59'fmars.cfg'. It includes a number of optimization options, some of which
60are processor-specific. The configuration file contains more details.
61
62
63IMPORTANT
64
65When generated with certain configuration options, the code violates
66C aliasing rules. That may sometimes result in a bad output from the
67simulator. The only reason for keeping such code is that it happens to
68work faster (with GCC 3.3). It depends on the compiler if it will work
69correctly and how much faster.
70
71If you decide to use such code, you should test it for correctness. You
72may find autotest.py useful for detecting wrong behavior of mars. If it
73happens, you have several options:
74
75- use -fno-strict-aliasing option of GCC
76- enable 'union' switch in configuration file
77- disable the offending configuration option
78
79Every solution leads to a certain slowdown. And it is hard to tell which one
80is best - you should check this for yourself.
81
82==========
83
84
853) Using fmars
86
87In order to use fmars in your programs, you should perform following steps:
88
89- allocate memory for mars
90- load warriors into exhaust format (possibly using fmars parser)
91- convert warriors from exhaust format into fmars internal format
92- for each round:
93   - clear the core
94   - load warriors (in internal format) into the core
95   - call the simulator
96- free allocated memory (both simulator and warriors)
97
98
99Example usage
100
101To allocate memory for the simulator:
102
103   #include "fmars.h"
104
105   int nwarriors = 2;
106   int coresize = 8000;
107   int processes = 8000;
108   int cycles = 80000;
109   int pspacesize = 500;
110   int maxlength = 100;
111   int rounds = 200;
112
113   fmars_mars_t *mars;
114
115   mars = fmars_alloc (nwarriors, coresize, processes, cycles, pspacesize);
116   if (mars == NULL)
117      panic ("Failed to allocate memory");
118
119
120In order to interact with the world, fmars uses (slightly modified) exhaust
121warrior format. To get a warrior in this format using fmars parser, you
122should do somethin like this (for simplicity, the example code doesn't
123check for errors and buffer overflows other than related to fmars):
124
125   #include "fm_asm.h"
126
127   int err;
128   char buf[16384];
129   warrior_t *exhaust_w1, *exhaust_w2;
130
131   /* read the file into a string */
132
133   size = read (open ("aeka.rc", O_RDONLY), buf, sizeof (buf));
134   buf[size] = 0;
135
136   /* call the parser; it will return 0 on success or error in case of an
137      error; arguments set to -1 in this example are used only for predefines
138      in the assembler */
139
140   err = fm_asm_string (buf, NULL, &exhaust_w1,
141                        nwarriors, coresize, -1, -1, -1, maxlength, -1, -1);
142   if (err)
143       panic ("Assembler error");
144
145   [repeat for the second warrior]
146
147
148The Exhaust format is convenient for transportation purposes, but for sake of
149performance, fmars uses different format internally. The internal
150representation of the warrior is tightly bound to the allocated mars, which
151means you cannot reuse the same warrior in different instances of mars.
152
153    fmars_warrior_t *w1, *w2;
154
155    w1 = fmars_bind_warrior (mars, exhaust_w1);
156    free (exhaust_w1->code);
157    free (exhaust_w1);
158
159    w2 = fmars_bind_warrior (mars, exhaust_w2);
160    free (exhaust_w2->code);
161    free (exhaust_w2);
162
163    if (w1 == NULL || w2 == NULL)
164        panic ("Failed to convert warriors");
165
166
167Now, we need to clear the core and load the warriors into it. The third
168argument of fmars_load_warrior() is warrior's unique ID ranging from
1690 to (nwarr - 1), which shouldn't be changed if the pspace is being used.
170The fourth argument is position in the core to load the warrior, and
171the fifth argument is warrior's position in the starting seqence,
172also ranging from 0 to (nwarr - 1).
173
174   int wins[]   = {0, 0};
175   int losses[] = {0, 0};
176   int ties[]   = {0, 0};
177
178   for (round = 0; round < rounds; round++)
179   {
180      fmars_clear_core (mars);
181      fmars_load_warrior (mars, w1, 0, 0, round % 2);
182      fmars_load_warrior (mars, w2, 1, 100 + random () % 7801, 1 - round % 2);
183
184
185Now we're ready to call the simulator. The return value will contain number
186of warriors that survived (or -1 in case of simulator panic), and death_tab
187will contain IDs of dead warriors, in order in which they were killed:
188
189      [still in for loop]
190
191      int alive, *death_tab;
192
193      alive = fmars_sim_multiwarrior (mars, &death_tab);
194      if (alive < 0)
195         panic ("Simulator panic (unsupported instruction?)");
196      else if (alive == 2)
197      {
198         ties[0]++;
199         ties[1]++;
200      }
201      else if (death_tab[0] == 0)
202      {
203         /* warrior with ID 0 lost */
204         losses[0]++;
205         wins[1]++;
206      }
207      else
208      {
209         wins[0]++;
210         losses[1]++;
211      }
212   } /* for */
213
214
215When we're done, we can free previously allocated memory:
216
217   fmars_free_warrior (w1);
218   fmars_free_warrior (w2);
219   fmars_free (mars);
220
221
222For more details check header files 'fmars.h' and 'fm_asm.h'.
223
224==========
225
226
2274) Redcode assembler
228
229fmars includes an easy to embed redcode parser. It is compatible with pMARS
230assembler, with following exceptions:
231
232- there are no arithmetic registers
233- the comments, including preprocessor directives, are not parsed
234- FOR/ROF loops are not allowed in EQUs
235- EQUs other than arithmetic expressions must be declared before they
236  are used
237- EQUs are not expanded when instruction modifier is expected (after dot)
238
239
240The assembler is designed to deal with correct input. It is a bit more
241allowing than pMARS (for example, you can redefine labels and EQUs),
242and gives almost no feedback on errors.
243
244
2455) Python interface
246
247fmars also includes rudimentary bindings for languages supported by
248SWIG. The makefile only supports python binding, but adding other
249languages should be trivial (see SWIG manual). You should be able
250to figure out how to use these bindings by looking at sample application,
251pymars.py (it's really simple).
252
253
254==========
255
256
2576) Known problems, bugs and future work
258
259- the Makefile is currently broken (just 'make clean' in case of problems).
260- MMX code works only for short ints as core field type
261- MMX didn't work under windows the last time I checkd
262- the simulator may not work when coresize is greater than maximal
263  value of a field type
264
265
266For future releases, I'm planning to implement p-space, clean up code a bit,
267include more friendly API for simulator and assembler, and maybe a client and
268a server for distributed computation.
269
270
271If you stumble on any unexpected behavior which wasn't mentioned in this
272file, please send me an e-mail to the address below. I'd appreciate a simple
273test case if possible.
274
275
276The author can be reached at this address:
277janeczek@gmail.com
278