-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.tex
1625 lines (1270 loc) · 94.4 KB
/
main.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
\documentclass[11pt, a4paper, onecolumn, oneside]{report}
\usepackage[top=1in, right=1in, bottom=1in, left=1in]{geometry}
\usepackage{xcolor}
\usepackage{graphicx}
\usepackage{cleveref}
\usepackage{minted}
\usemintedstyle{tango}
%interactive references in pdf (slower compilation times)
\usepackage{hyperref}
\hypersetup{
colorlinks=false,
}
% Stop chapters from starting new pages
% \usepackage{etoolbox}
% \makeatletter
% \patchcmd{\chapter}{\if@openright\cleardoublepage\else\clearpage\fi}{}{}{}
% \makeatother
% Will replace minted
\usepackage{listings, color}
\definecolor{dkgreen}{rgb}{0,0.6,0}
\definecolor{gray}{rgb}{0.5,0.5,0.5}
\definecolor{mauve}{rgb}{0.58,0,0.82}
\definecolor{gray}{rgb}{0.4,0.4,0.4}
\definecolor{darkblue}{rgb}{0.0,0.0,0.6}
\definecolor{lightblue}{rgb}{0.0,0.0,0.9}
\definecolor{cyan}{rgb}{0.0,0.6,0.6}
\definecolor{darkred}{rgb}{0.6,0.0,0.0}
%\footnotesize
\lstset{
basicstyle=\ttfamily\small,
columns=fullflexible,
showstringspaces=false,
numbers=left, % where to put the line-numbers
numberstyle=\tiny\color{gray}, % the style that is used for the line-numbers
stepnumber=1,
numbersep=5pt, % how far the line-numbers are from the code
backgroundcolor=\color{white}, % choose the background color. You must add \usepackage{color}
showspaces=false, % show spaces adding particular underscores
showstringspaces=false, % underline spaces within strings
showtabs=false, % show tabs within strings adding particular underscores
frame=none, % adds a frame around the code
rulecolor=\color{black}, % if not set, the frame-color may be changed on line-breaks within not-black text (e.g. commens (green here))
tabsize=2, % sets default tabsize to 2 spaces
captionpos=b, % sets the caption-position to bottom
breaklines=true, % sets automatic line breaking
breakatwhitespace=false, % sets if automatic breaks should only happen at whitespace
title=\lstname, % show the filename of files included with \lstinputlisting;
% also try caption instead of title
commentstyle=\color{gray}\upshape
}
\lstdefinelanguage{C_}
{
keywordstyle=\color{blue},
stringstyle=\color{red},
commentstyle=\color{green},
morecomment=[l][\color{magenta}]{\#},
morecomment=[l][\color{magenta}]{\//},
morecomment=[s][\color{magenta}]{/*}{*/},
morecomment=[s][\color{magenta}]{->},
morekeywords={__FLAME_GPU_FUNC__,return,if,int,float,while,void,
__FLAME_GPU_INIT_FUNC__,__FLAME_GPU_STEP_FUNC__,
__FLAME_GPU_STEP_FUNC__, extern, unsigned,CONTINUOUS}
}
\lstdefinelanguage{XML}
{
morestring=[s][\color{mauve}]{"}{"},
morestring=[s][\color{black}]{>}{<},
morecomment=[s]{<?}{?>},
morecomment=[s][\color{dkgreen}]{<!--}{-->},
stringstyle=\color{black},
identifierstyle=\color{lightblue},
keywordstyle=\color{red},
morekeywords={xmlns,gpu}% list the attributes
}
\title{FLAME GPU Technical Report and User Guide (Depreciated docs now on ReadTheDocs)}
\author{Paul Richmond}
\date{\today}
% \date{}
% todo List:
% @todo change author to Paul / FLAME GPU contirbutors
% @todo Create nice title page
% @todo improve document formatting
% @todo better labels (meaningful rather than old section numbers)
% @todo use lstlistings with custom highlighting rules to replace slow minted compilation
% @todo Complete section on using Makefile
% @todo Complete section(s) on graph based communication
% @todo complete section on staticGraph data structure
% @todo describe instrumentation #defines
% @todo add details of host agent creation in init/step fns
\begin{document}
\maketitle
\tableofcontents
% \listoffigures
% \listoftables
% \clearpage
\chapter{Introduction}
\label{ch:1}
Agent Based Modelling is a technique for the computational simulation of complex interacting systems through the specification of the behaviour of a number of autonomous individuals acting simultaneously.
This is a bottom up approach, in contrast with the top down one of modelling the behaviour of the whole system through dynamic mathematical equations. The focus on individuals is considerably more computationally demanding, but provides a natural and flexible environment for studying systems demonstrating emergent behaviour.
Despite the obvious parallelism, traditionally frameworks for ABM fail to exploit this and are often based on highly serialised algorithms for manipulating mobile discrete agents.
Such an approach has serious implications, placing stringent limitations on both the scale of models and the speed at which they may be simulated.
The purpose of the FLAME GPU framework is to address the limitations of previous agent modelling software by targeting the high performance GPU architecture.
The framework is designed with parallelism in mind and as such allows agent models to scale to massive sizes and ensures simulations run within reasonable time constrains.
In addition to this visualisation is easily achievable as simulation data is held entirely within GPU memory where it can be rendered directly.
\section{High Level Overview of FLAME GPU}
\label{sec:11}
Technically the FLAME GPU framework is not a simulator, it is instead a template based simulation environment that maps formal descriptions of agents into simulation code.
The representation of an agent is based on the concept of a communicating X-Machine (which is an extension to the Finite State Machine which includes memory).
Whilst the X-Machine has very formal definition X-Machine agents can be thought of a state machines which are able to communicate via messages which are stored in a globally accessible message lists.
Agent functionality is exposed as a set of state transition functions which move agents from one internal state to another.
Upon changing state, agents update their internal memory through the influence of messages which may be either used as input (by iterating message lists) or as output (where information may be passed to the message lists for other agents to read).
FLAME GPU uses agent function scripting for this purpose where script is defined in a number of \emph{Agent Function Files}.
Simulation models are specified using a format called X-Machine Mark-up Language (\emph{XMML}) which is XML syntax with Schemas governing the content.
A typically XMML model file consists of a definition of a number of X-Machine agents (including state and memory information as well as a set of agent transition functions), a number of message types (each of which has a globally accessible message list) and a set of simulation layers which define the execution order of agent functions (which constitutes a single simulation iteration).
Throughout a simulation, agent data is persistent however message information (and in particular message lists) is persistent only over the lifecycle of a single iteration.
This allows a mechanism for agents to iteratively interact in a way which allows emergent global group behaviour.
The process of generating a FLAME GPU simulation is described by the 1.
The use of XML schemas forms a large part of the process where polymorphic like extension allows a base schema specification to be extended with a number of GPU specific elements.
Given an XMML model definition, template driven code generation is achieved through Extensible Stylesheet Transformations (XSLT).
XSLT is a flexible functional language based on XML (validated itself using a W3C specified Schema) and is suitable for the translation of XML documents into other document formats using a number of compliant processors (although the FLAME GPU SDK provides its own).
Through the specification of a number of \emph{XSLT Simulation Templates} a \emph{Dynamic Simulation API} is generated which links with the \emph{Agent Function Files} to generate a simulation program.
\begin{figure}[ht]
\centering
\includegraphics[width=0.70\textwidth]{img/figure1}
\caption{FLAME GPU Modelling and Simulation Processes}
\label{fig:modelling-and-simulation-process}
\end{figure}
\section{Purpose of This Document}
\label{sec:12}
The purpose of this document is to describe the functional parts which make up a FLAME GPU simulation as well as providing guidance on how to use the FLAME GPU SDK.
\Cref{ch:2} describes in detail the syntax and format of the XMML Model file.
\Cref{ch:3} describes the syntax of use of agent function scripts and how to use the dynamic simulation API and \Cref{ch:4} describes how to generate simulation code and run simulations from within the Visual Studio IDE.
This document does not act as a review of background material relating to GPU agent modelling, nor does it provide details on FLAME GPUs implementation or descriptions of the FLAME GPU examples.
For more in depth background material on agent based simulation on the GPU, the reader is directed towards the following document;
\begin{quote}
\emph{Richmond Paul, Walker Dawn, Coakley Simon, Romano Daniela (2010), "High Performance Cellular Level Agent-based Simulation with FLAME for the GPU", Briefings in Bioinformatics, 11(3), pages 334-47.}
\end{quote}
For details on the implementation including algorithms and techniques the reader is directed towards the following publication;
\begin{quote}
\emph{Richmond Paul (2011), "Template Driven Agent Based Modelling and Simulation with CUDA", GPU Computing Gems Emerald Edition (Wen-mei Hwu Editor), Morgan Kaufmann, March 2011, ISBN: 978-0-12-384988-5}
\emph{Richmond Paul, Coakley Simon, Romano Daniela (2009), "A High Performance Agent Based Modelling Framework on Graphics Card Hardware with CUDA", Proc. of 8th Int. Conf. on Autonomous Agents and Multi-Agent Systems (AAMAS 2009), May, 10--15, 2009, Budapest, Hungary}
\end{quote}
Some examples of FLAME GPU models are described in the following publications;
\begin{quote}
\emph{Richmond Paul, Coakley Simon, Romano Daniela (2009), "Cellular Level Agent Based Modelling on the Graphics Processing Unit", Proc. of HiBi09 - High Performance Computational Systems Biology, 14-16 October 2009,Trento, Italy (additional detail in the BiB paper)}
\emph{Karmakharm Twin, Richmond Paul, Romano Daniela (2010), " Agent-based Large Scale Simulation of Pedestrians With Adaptive Realistic Navigation Vector Fields", To appear in Proc. of Theory and Practice of Computer Graphics (TPCG) 2010, 6-8th September 2010, Sheffield, UK}
\end{quote}
\chapter{FLAMEGPU Model Specification}
\label{ch:2}
\section{Introduction}
\label{sec:21}
FLAME GPU models are specified using XML format within an XMML document.
The syntax of the model file is governed by two XML Schemas, an abstract base Schema describes the syntax of a basic XMML agent model (compatible with HPC and CPU versions of the FLAME framework) and a concrete GPU Schema extension this to add various bits of additional model information.
Within this chapter the XML namespace (xmlns) gpu is used to qualify the XML elements which extend the basic Schema representation.
A high level overview of a an XMML model file is described below with various sections within this chapter describing each part in more detail.
\begin{lstlisting}[language=XML]
<gpu:xmodel
xmlns:gpu="http://www.dcs.shef.ac.uk/\textasciitilde{}paul/XMMLGPU"
xmlns="http://www.dcs.shef.ac.uk/\textasciitilde{}paul/XMML">
<name>Model Name</name> <!-- optional -->
<gpu:environment>...</gpu:environment>
<xagents>...</xagents>
<messages>...</messages>
<layers>...</layers>
</gpu:xmodel>
\end{lstlisting}
\section{The Environment}
\label{sec:22}
The environment element is used to hold global information which relates to the simulation.
This information includes, zero or more constant, or global, variables (which are constant for all agents over the period of either the simulation or single simulation iteration), a single non optional function file containing agent function script (see \Cref{ch:3}) and an optional number of initialisation, step and exit functions.
\begin{lstlisting}[language=XML]
<gpu:environment>
<gpu:constants>...</gpu:constants> <!-- optional -->
<gpu:functionFiles>...</gpu:functionFiles> <!-- not optional -->
<gpu:initFunctions>...</gpu:initFunctions> <!-- optional -->
<gpu:stepFunctions>...</gpu:stepFunctions> <!-- optional -->
<gpu:endFunctions>...</gpu:endFunctions> <!-- optional -->
</gpu:environment>
\end{lstlisting}
\subsection{Simulation Constants (Global Variables)}
\label{sec:221}
Simulation constants are defined as (global) variables and may be of type int, float or double (on GPU hardware with double support i.e. CUDA Compute capability 2.0 or beyond).
Constant variables must each have a unique name which is used to reference them within simulation code and can have an optional static array length (of size greater than 0).
The description element arrayLength element and defaultValue element are all optional.
The below code shows the specification of two constant variables: the first represents a single \mintinline[fontsize=\small]{c}{int} constant (with a default value of $1$), the second indicates an \mintinline[fontsize=\small]{c}{int} array of length 5.
Simulation constants can be set either as default values as show below, within the initial agent XML file (see \cref{271}) or at run-time are described in \cref{sec:39}. Values set in initial XML values will overwrite a default value and values which are set at runtime will overwrite values set in initial agent XML files.
\begin{lstlisting}[language=XML]
<gpu:constants>
<gpu:variable>
<type>int</type>
<name>const_variable</name>
<description>none</description>
<defaultValue>1</defaultValue>
</gpu:variable>
<gpu:variable>
<type>int</type>
<name>const_array_variable</name>
<description>none</description>
<arrayLength>5</arrayLength>
</gpu:variable>
</gpu:constants>
\end{lstlisting}
\subsection{Function Files}
\label{sec:222}
The functionFiles element is not optional and must contain a single file element which defines the name of a source code file which holds the scripted agent functions.
More details on the format of the function file are given in \Cref{ch:3}.
The example below shows the correct XML format for a function file named \mintinline[fontsize=\small]{text}{functions.c}.
\begin{lstlisting}[language=XML]
<gpu:functionFiles>
<file>functions.c</file>
</gpu:functionFiles>
\end{lstlisting}
\subsection{Initialisation Functions}
\label{sec:223}
Initialisation functions are user defined functions which can be used to set constant global variables.
Any initialisation functions defined within the initFunctions element are called a single time by the automatically generated simulation code in the order that they appear during the initialisation of the simulation.
If an initFunctions element is specified there must be at least a single initFunction child element with a unique name.
\Cref{sec:391} demonstrates how to specify initialisation functions within a function file.
\begin{lstlisting}[language=XML]
<gpu:initFunctions>
<gpu:initFunction>
<gpu:name>initConstants</gpu:name>
</gpu:initFunction>
</gpu:initFunctions>
\end{lstlisting}
\subsection{Step Functions}
\label{sec:stepFunc}
Step functions are similarly defined to initialisation functions, requiring at least a single stepFunction child element if the stepFunctions element is defined. These functions are called at the end of each iteration step, i.e. after all the layers, as defined in section \ref{sec:26}, are executed each step. Example uses of this function are to calculate agent averages during the iteration step or sort functions.
\begin{lstlisting}[language=XML]
<gpu:stepFunctions>
<gpu:stepFunction>
<gpu:name>some_step_func</gpu:name>
</gpu:stepFunction>
</gpu:stepFunctions>
\end{lstlisting}
\subsection{Exit Functions}
\label{sec:exitFunc}
Exit functions are again like the other function types defined above, requiring at least a single exitFunction child element if the exitFunctions element is defined. These functions are called at the end of the whole simulation. An example use of this function would be to calculate final averages of agent variables or print out final values.
\begin{lstlisting}[language=XML]
<gpu:exitFunctions>
<gpu:exitFunction>
<gpu:name>some_exit_func</gpu:name>
</gpu:exitFunction>
</gpu:exitFunctions>
\end{lstlisting}
\section{Defining an X-Machine Agent}
\label{sec:23}
A XMML model file must contain a single xagents element which in turn must define at least a single xagent.
An xagent is an agent representation of an X-Machine and consists of a name, optional description, an internal memory set ($M$ in the formal definition), a set of agent functions (or next state partial functions, $F$, in the formal definition) and a set of states ($Q$ in the formal definition).
In addition to this FLAMEGPU requires two additional pieces of information (which are not required in the original XMML specification), a type and a \mintinline[fontsize=\small]{c}{bufferSize}.
The type element refers to the type of agent with respect to its relation with its spatial environment.
An agent type can be either discrete or continuous, discrete agents occupy non mobile 2D discrete spatial partitions (cellular automaton) where as continuous agents are assumed to occupy a continuous space environment (although in reality they may in fact be non spatial more abstract agents).
As all memory is pre-allocated on the GPU a \mintinline[fontsize=\small]{c}{bufferSize} is required to represent the largest possible size of the agent population.
That is the maximum number of x-machine agent instances of the format described by the XMML model.
There is no performance disadvantage to using a large \mintinline[fontsize=\small]{c}{bufferSize} however it is the user's responsibility to ensure that the GPU contains enough memory to support large populations of agents.
It is recommended that the bufferSize always be a power of two number (i.e.
$1024$, $2048$, $4096$, $16384$, etc) as it will most likely be rounded to one during simulation.
For discrete agents the bufferSize is currently limited to only power of 2 numbers which have squarely divisible dimensions (i.e. the square of the bufferSize must be a whole number).
If at any point in the simulation exceeds the stated bufferSize then the user will be warned at the simulation will exit.
Each expandable aspect of an XMML agent representation in the below example is discussed within this section with the exception of agent functions, which due to their dependence of the definition of messages, are discussed later in \cref{sec:25}.
\begin{lstlisting}[language=XML]
<xagents>
<gpu:xagent>
<name>AgentName</name>
<description>optional description of the agent</description>
<memory>...</memory>
<functions>...</functions>
<states>...</states>
<gpu:type>continuous</gpu:type>
<gpu:bufferSize>1024</gpu:bufferSize>
</gpu:xagent>
<gpu:xagent>
<!-- ... -->
</gpu:xagent>
</xagents>
\end{lstlisting}
\subsection{Agent Memory}
\label{sec:231}
Agent memory consists of a number of variables (at least one) which are use to hold information.
An agent variable must have a unique name and may be of type \mintinline[fontsize=\small]{c}{int}, \mintinline[fontsize=\small]{c}{float} or \mintinline[fontsize=\small]{c}{double} (CUDA compute capability 1.3 or beyond).
Default values are always $0$ unless a value is specified within the XML input states file.
There are no specified limits on the maximum number of agent variables however the performance tips noted in \cref{sec:47} should be taken into account.
Agent memory can also be defined as static sized array. For performance use sizes that are a multiple of 2(?)
Below shows an example of agent memory containing four agent variables representing an agent identifier, two positional values and a list of numbers.
\begin{lstlisting}[language=XML]
<memory>
<gpu:variable>
<type>int</type>
<name>id</name>
<description>variable description</description>
</gpu:variable>
<gpu:variable>
<type>float</type>
<name>x</name>
</gpu:variable>
<gpu:variable>
<type>float</type>
<name>y</name>
</gpu:variable>
<gpu:variable>
<type>float</type>
<name>nums</name>
<arrayLength>64</arrayLength>
</gpu:variable>
</memory>
\end{lstlisting}
\subsection{Agent States}
\label{sec:232}
Agent states are defined as a list of state elements ($Q$ in the X-Machine formal definition) with a unique and non optional name.
As simulations within FLAMEGPU can continue indefinitely (or for a fixed number of iterations), terminal states ($T$ in the formal definition) are not defined.
The initial state ($q_{0}$) must however be defined within the initialState element and must correspond with an existing and unique state name from the list of states above it.
\begin{lstlisting}[language=XML]
<states>
<gpu:state>
<name>state1</name>
</gpu:state>
<gpu:state>
<name>state2</name>
</gpu:state>
<initialState>state1</initialState>
</states>
\end{lstlisting}
\section{Defining Messages}
\label{sec:24}
Messages represent the information which is communicated between agents.
An element messages contains a list of at least one message which defines a non optional name an optional description of the message, a list of variables, a partitioning type and a \mintinline[fontsize=\small]{c}{bufferSize}.
The \mintinline[fontsize=\small]{c}{bufferSize} element is used in the same way that a bufferSize is used to define an X-Machine agent, i.e. the maximum number of this message type which may exist within the simulation at one time.
The partitioning type may be one of three currently defined message partition schemes, non partitioned (\mintinline[fontsize=\small]{c}{partitioningNone}), discrete 2D space partitioning (\mintinline[fontsize=\small]{c}{partitioningDiscrete}) or 2D/3D spatially partitioned space (\mintinline[fontsize=\small]{c}{partitioningSpatial}).
Message partition schemes are used to ensure that the most optimal cycling of messages occurs within agent functions. The use of the partitioning techniques is described within this section, as are message variables.
\begin{lstlisting}[language=XML]
<messages>
<gpu:message>
<name>message_name</name>
<description>optional message description</description>
<variables>...</variables>
...<partitioningType/>... <!-- replace with a partitioning type -->
<gpu:bufferSize>1024</gpu:bufferSize>
</gpu:message>
<gpu:message>...</gpu:message>
</messages>
\end{lstlisting}
\subsection{Message Variables}
\label{sec:241}
The message variables element consists of a number of variables (at least one) which are use to hold communication information.
A variable must have a unique name and may be of type \mintinline[fontsize=\small]{c}{int}, \mintinline[fontsize=\small]{c}{float} or \mintinline[fontsize=\small]{c}{double} (CUDA Compute capability 2.0 or beyond).
As with agent variables message variables only supports the use of single memory values (i.e. no static or dynamic arrays).
Likewise there are no specified limits on the maximum number of message variables however increased message size will have a negative effect on performance in all partitioning cases (and in particular when non partitioned messages are used).
The format of message variable specification shown below is identical to that of agent memory.
The only exception is the requirement of certain variable names which are required by certain partitioning types.
Non partitioned messages have no requirement for specific variables.
Discrete partitioning requires two \mintinline[fontsize=\small]{c}{int} type variables of name \mintinline[fontsize=\small]{c}{x} and \mintinline[fontsize=\small]{c}{y}.
Spatial partitioning requires three \mintinline[fontsize=\small]{c}{float} (or \mintinline[fontsize=\small]{c}{double}) type variables named \mintinline[fontsize=\small]{c}{x}, \mintinline[fontsize=\small]{c}{y} and \mintinline[fontsize=\small]{c}{z}.
The example below shows an example of message memory containing two message variables named id and message\_variable.
\begin{lstlisting}[language=XML]
<variables>
<gpu:variable>
<type>int</type>
<name>id</name>
<description>variable description</description>
</gpu:variable>
<gpu:variable>
<type>float</type>
<name>message_variable</name>
</gpu:variable>
</variables>
\end{lstlisting}
\subsection{Non partitioned Messages}
\label{sec:242}
None partitioned messages do not use any filtering mechanism to reduce the number of messages which will be iterated by agent functions which use the message as input.
None partitioned messages therefore require a brute force or $O(n^{2})$ message iteration loop wherever the message list is iterated.
As non partitioned messages do not require any message variables with location information the partition type is particularly suitable for communication between non spatial or more abstract agents.
Brute force iteration is obviously reasonably computationally expensive, however non partitioned message iteration requires very little overhead (or setup) and as a result for small numbers of messages it can be more efficient than either limited range technique.
There is no strict rule governing performance and different GPU hardware will produce different results depending on it capability.
It is therefore left to the user to experiment with different message partitioning types within a simulation.
The example below shows the format of the partitioningNone element tag.
\begin{lstlisting}[language=XML]
<gpu:partitioningNone/>
\end{lstlisting}
\subsection{Discrete Partitioned Messages}
\label{sec:243}
Discrete partitioned messages are messages which may only originate from non mobile discrete agents (cellular automaton).
A discrete partitioning message scheme requires the specification of a radius which indicates the range (in in 2D discrete space) which a message iteration will extend to.
A radius value of 0 indicates that only a single message will be returned from message iteration.
A value of greater than 0 indicates that message iteration will loop through ±radius in both the \mintinline[fontsize=\small]{c}{x} and a \mintinline[fontsize=\small]{c}{y} dimension (e.g.
a range of $1$ will iterate $3x3=9$ messages, a range of $2$ will iterate $5x5=25$).
In addition to this the agent memory is expected to contain x and y variables of type \mintinline[fontsize=\small]{c}{int}.
As with discrete agents it is important to ensure that messages using discrete partitioning use only supported buffer sizes (power of $2$ and squarely divisible). The width and height of the discrete message space is then defined as the square of the bufferSize value.
\begin{lstlisting}[language=XML]
<gpu:partitioningDiscrete>
<gpu:radius>1</gpu:radius>
</gpu:partitioningDiscrete>
\end{lstlisting}
\subsection{Spatially Partitioned Messages}
\label{sec:244}
Spatially partitioned messages are messages which originate from continuous spaced agents in either a 3D environment (i.e. agents with \mintinline[fontsize=\small]{c}{x}, \mintinline[fontsize=\small]{c}{y} and \mintinline[fontsize=\small]{c}{z} variables).
A spatially partitioned message scheme requires the specification of both a radius and a set of environment bounds.
The radius represents the range in which message iteration will extend to (from its originating point).
The environment bounds represent the size of the space which massages may exist within.
If a message falls outside of the environment bounds then it will be bound to the nearest possible location within it.
The space within the defined bounds is partitioned according to the radius with a total of P partitions in each dimension, where for each dimension;
$P = ceiling((max\_bound - min\_bound) / radius)$
The partitions dimensions are then used to construct a partition boundary matrix (an example of use within message iteration is provided in \cref{sec:352}) which holds the indices of messages within each area of partitioned space.
Spatially partitioned message iteration can then iterate a varying number of messages from a fixed number of adjacent partitions in partition space to ensure each message within the specified radius has been considered.
The following example defines a spatial partition in three dimensions.
For continuously spaced agents in 2D space $P$ should be equal to $1$ and therefore a \mintinline[fontsize=\small]{text}{zmin} of $0$ would require a \mintinline[fontsize=\small]{text}{zmax} value equal to radius (even in this case a message variable with name \mintinline[fontsize=\small]{c}{z} is still required).
\begin{lstlisting}[language=XML]
<gpu:partitioningSpatial>
<gpu:radius>1</gpu:radius>
<gpu:xmin>0</gpu:xmin>
<gpu:xmax>10</gpu:xmax>
<gpu:ymin>0</gpu:ymin>
<gpu:ymax>10</gpu:ymax>
<gpu:zmin>0</gpu:zmin>
<gpu:zmax>10</gpu:zmax>
</gpu:partitioningSpatial>
\end{lstlisting}
% \subsection{Graph-Based Communication Messages}
% \label{ssec:graph-comm-xml}
% \textbf{@todo}
\section{Defining an Agent function}
\label{sec:25}
An optional list of agent functions is described within an X-Machine agent representation and must contain a list of at least a single agent function element.
In turn, a function must contain a non optional name, and optional description, a current state, next state, an optional single message input, and optional single message output, an optional single agent output, an optional global function condition, an optional function condition, a reallocation flag and a random number generator flag.
The current state is defined within the currentState element and is used to filter the agent function by only applying it to agents in the specified state.
After completing the agent function agents then move into the state specified within the nextState element.
Both the current and \mintinline[fontsize=\small]{text}{nextState} values are required to have values which exist as a state/name within the state list (states) definition.
The reallocate element is used as an optional flag to indicate the possibility that an agent performing the agent function may die as a result (and hence require removing from the agent population).
By default this value is assumed true however if a value of false is specified then the processes for removing dead agents will not be executed even if an agent indicates it has died (see agent function definitions in \cref{sec:33}).
The RNG element represents a flag to indicate the requirement of random number generation within the agent function.
If this value is true then an additional parameter (demonstrated in \cref{sec:37}) is passed to the agent function which holds a number of seeds used for parallel random number generation.
\begin{lstlisting}[language=XML]
<functions>
<gpu:function>
<name>func_name</name>
<description>function description</description>
<currentState>state1</currentState>
<nextState>state2</nextState>
<inputs>...</inputs> <!-- optional -->
<outputs>...</outputs> <!-- optional -->
<xagentOutputs></xagentOutputs> <!-- optional -->
<gpu:globalCondition>...</gpu:globalCondition> <!-- optional -->
<condition>...</condition> <!-- optional -->
<gpu:reallocate>true</gpu:reallocate> <!-- optional -->
<gpu:RNG>true</gpu:RNG> <!-- optional -->
</gpu:function>
</functions>
\end{lstlisting}
\subsection{Agent Function Message Inputs}
\label{sec:251}
An agent function message input indicates that the agent function will iterate the list of messages with a name equal to that specified by the non optional messageName element.
It is therefore required that the messageName element refers to an existing message/name defined within the XMML document.
In addition to this an agent function cannot iterate a list of messages without specifying that it is an input within the XMML model file (message iteration functions are parameterised to prevent this).
\begin{lstlisting}[language=XML]
<inputs>
<gpu:input>
<messageName>message_name</messageName>
</gpu:input>
</inputs>
\end{lstlisting}
\subsection{Agent Function Message Outputs}
\label{sec:252}
An agent function message output indicates that the agent function will output a message with a name equal to that specified by the non optional messageName element.
The messageName element must therefore refer to an existing message/name defined within the XMML document.
It is not possible for an agent function script to output a message without specifying that it is an output within the XMML model file (message output functions are parameterised to prevent this).
In addition to the messageName element a message output also requires a type.
The type may be either \mintinline[fontsize=\small]{c}{single_message} or \mintinline[fontsize=\small]{c}{optional_message}, where \mintinline[fontsize=\small]{c}{single_message} indicates that every agent performing the function outputs exactly one message and \mintinline[fontsize=\small]{c}{optional_message} indicates that agent's performing the function may either output a single message or no message.
The type of messages which can be output by discrete agents are not restricted however continuous type agents can only output messages which do not use discrete message partitioning (e.g.
no partitioning or spatial partitioning).
The example below shows a message output using \mintinline[fontsize=\small]{c}{single_message} type.
This will assume every agent outputs a message, if the functions script fails to output a message for every agent a message with default values (of $0$) will be created instead.
\begin{lstlisting}[language=XML]
<outputs>
<gpu:output>
<messageName>message_name</messageName>
<gpu:type>single_message</gpu:type>
</gpu:output>
</outputs>
\end{lstlisting}
\subsection{Agent Function X-Agent Outputs}
\label{sec:253}
An agent function xagentOutput indicates that the agent function will output an agent with a name equal to that specified by the non optional xagentName element.
This differs slightly from the formal definition of an x-machine which does not explicitly define a technique for the creation of new agents but adds functionality required for dynamically changing population sizes during simulation runtime.
The xagentName element belonging to an xagentOutput element must refer to an existing agent/name defined within the XMML document.
It is not possible for an agent function script to output a agent without specifying that it is an xagntOutput within the XMML model file (agent output functions are parameterised to prevent this).
In addition to the xagentName element a message output also requires a state.
The state represents the state from the list of state elements belonging to the specified agent\textbackslash{}name that the new agent should be in after it has been created.
Only continuous type agents are allowed to output new agents (which must also be of type continuous).
The creation of new discrete agents is not permitted under any circumstance.
An \mintinline[fontsize=\small]{c}{xagentOutput} does not require a type (as is the case with a message output) and any agent function outputting an agent is assumed to be optional.
I.e. each agent performing the function may output either one or zero agents.
\begin{lstlisting}[language=XML]
<xagentOutputs>
<gpu:xagentOutput>
<xagentName>agent_name</xagentName>
<state>state1</state>
</gpu:xagentOutput>
</xagentOutputs>
\end{lstlisting}
\subsection{Function Conditions}
\label{sec:254}
An agent function condition indicates that the agent function should only be applied to agents which meet the defined condition (and in the correct state specified by \mintinline[fontsize=\small]{c}{currentState}).
Each function condition consists of three parts a left hand side statement (\mintinline[fontsize=\small]{text}{lhs}), an operator and a right hand side statement (\mintinline[fontsize=\small]{text}{rhs}).
Both the \mintinline[fontsize=\small]{text}{lhs} and \mintinline[fontsize=\small]{text}{rhs} elements may contain either a agentVariable a value or a recursive condition element.
An agentVariable element must refer to a agent variable defined within the agents list of variable names (i.e.
\mintinline[fontsize=\small]{XML}{gpu:xagent/memory/gpu:variable/name}).
A value element may refer to any numeric value or constant definition (defined within the agent function scripts).
The use of recursive conditions is demonstrated below by embedding a condition within the \mintinline[fontsize=\small]{text}{rhs} element of the top level condition.
\begin{lstlisting}[language=XML]
<condition>
<lhs>
<agentVariable>variable_name</agentVariable>
</lhs>
<operator><</operator>
<rhs>
<condition>
<lhs>
<agentVariable>variable_name2</agentVariable>
</lhs>
<operator>+</operator>
<rhs>
<value>1</value>
</rhs>
</condition>
</rhs>
</condition>
\end{lstlisting}
In the above example the function condition generates the following pseudo code function guard;
\begin{lstlisting}[language=C_]
(variable_name) < ((variable_name2)+(1))
\end{lstlisting}
The condition element may refer to any logical operator.
Care must be taken when using angled brackets which in standard form will cause the XML syntax to become invalid.
Rather than the left hand bracket (less than) the correct xml syntax of
\verb|<| should be used.
Likewise the right hand bracket (greater than) should be replaced with
\verb|>|.
\subsection{Global Function Conditions}
\label{sec:255}
An agent global function condition is similar to an agent function in its syntax however it acts as a global switch to determine if the function should be applied to either \emph{all} or \emph{none} of the agents (within the correct state specified by \verb|currentState|).
In the case of every agent evaluating the global function condition to true (or to the value specified by the \verb|mustEvaluateTo| element) the agent function is applied to \emph{all} of the agents.
In the case that any of the agents evaluate the global function condition to false (or to the logical opposite of the value specified by the \verb|mustEvaluateTo| element) then the agent function will be applied to \emph{none} of the agents.
As with an agent function condition a globalCondition consists of a left hand side statement (\verb|lhs|), an operator and a right hand side statement (\verb|rhs|).
The syntax of the left hand side statement (\verb|lhs|), the operator and the right hand side statement (\verb|rhs|) is the same as with an agent function condition and may use recursion to generate a complex conditional statement.
The maxItterations element is used to limit the number of times a function guarded by the global condition can be avoided (or evaluated as the logical opposite of the value specified by the \verb|mustEvaluateTo| element).
For example, the definition at the end of this section, resulting in the following pseudo code condition;
\begin{lstlisting}[language=C_]
(((movement) < (0.25)) == true)
\end{lstlisting}
May be evaluated as false up to $200$ times (i.e. in $200$ separate simulation iterations) before the global condition will be ignored and the function is applied to every agent.
Following maximum number of iterations being reached the iteration count is reset once the agent function has been applied.
\begin{lstlisting}[language=XML]
<gpu:globalCondition>
<lhs>
<agentVariable>movement</agentVariable>
</lhs>
<operator><</operator>
<rhs>
<value>0.25</value>
</rhs>
<gpu:maxItterations>200</gpu:maxItterations>
<gpu:mustEvaluateTo>true</gpu:mustEvaluateTo>
</gpu:globalCondition>
\end{lstlisting}
\section{Function Layers}
\label{sec:26}
Function layers represent the control flow of the simulation processes.
The sequence of layers defines the sequential order in which agent functions are executed.
Complete execution of every layer of agent functions represents a single simulation iteration which may be repeated any number of times.
Synthetically within the model definition a single layers element must contain at least one (or more) layer element.
Each layer element may contain at least one (or more) \mintinline[fontsize=\small]{XML}{gpu}:layerFunction element which defines only a name which must relate to a function name specified within a corresponding \mintinline[fontsize=\small]{text}{xagents/gpu:xagent/functions/gpu:function/name}.
Within a given layer, the order of execution of layer functions should not be assumed to be sequential (although in the current version of the software it is, future versions will execute functions within the same layer in parallel).
For the same reason functions within the same layer should not have any communication or internal dependencies (for example via message communications or execution order dependency) in which case they should instead be represented within separate layers which guarantee execution order and global synchronisation between the functions.
The below example demonstrates the syntax of specifying a simulation consisting of three agent functions.
There are no dependencies between \verb|function1| and \verb|function2| which in this case can be thought of as being functions from two different agents definitions with no shared message input or output.
\begin{lstlisting}[language=XML]
<layers>
<layer>
<gpu:layerFunction>
<name>function1</name>
</gpu:layerFunction>
<gpu:layerFunction>
<name>function2</name>
</gpu:layerFunction>
</layer>
<layer>
<gpu:layerFunction>
<name>function3</name>
</gpu:layerFunction>
</layer>
</layers>
\end{lstlisting}
\section{Initial XML Agent Data}
\label{sec:27}
The initial agent data information is stored in an XML file which is passed to the simulator as a parameter before running the simulation.
Within this initial agent data XML file, a single states element contains a single iteration number (\mintinline[fontsize=\small]{text}{itno}) and any number (including 0) of xagent elements.
The syntax of the xagent element depends on the agent definitions contained within the XMML model definition file.
A name element is always required and must represent an agent name contained within a \mintinline[fontsize=\small]{text}{xgents/gpu:agent/name} element in the XMML model definition.
Following this an element may exist for each of the named agents memory variables (\mintinline[fontsize=\small]{text}{xagents/gpu:agent/memory/gpu:variable/name}).
Each named element is then expected to contain a value of the same type as the agent memory variable defined.
If the initial agent data XML file neglects to specify the value of a variable defined within an agents memory then the value is assumed to be zero.
If an element defines a variable name which does not exist within the XMML model definition then a warning is generated and the value is ignored.
The example below represents a single agent corresponding to the agent definition in \cref{sec:23}.
\begin{lstlisting}[language=XML]
<states>
<itno>0</itno>
<xagent>
<name>AgentName</name>
<id>1</id>
<x>21.088</x>
<y>12.834</y>
<z>5.367</z>
</xagent>
<xagent>...</xagent>
</states>
\end{lstlisting}
Care must be taken in ensuring that the set of initial data for the simulation does not exceed any of the defined bufferSize (i.e. the maximum number of a given type of agents) for any of the agents.
If buffer size is exceeded during initial loading of the initial agent data then the simulation will produce an error.
Another special case to consider is the use of 2D discrete agents where the number of agents within the set of initial agent data must match exactly the bufferSize (which must also be a power of 2) defined within the XMML models agent definition.
Furthermore the simulation will expect to find initial agents stored within the XML file in row wise ascending order.
\subsection{Initial Simulation Constants}
\label{sec:271}
Simulation constants (or global variables) specified within the model file (as described in \cref{sec:229}) can be set within the initial XML agent data within an environment label between the itno and xagent elements. Environment variables should be set within an XML element with a name corresponding to the environment variable name. E.g. An environment variable defined within the model file as;
\begin{lstlisting}[language=XML]
<gpu:constants>
<gpu:variable>
<type>int</type>
<name>my_variable</name>
<description>none</description>
<defaultValue>1</defaultValue>
</gpu:variable>
</gpu:constants>
\end{lstlisting}
Could be defined within an initial XML agents file as follows;
\begin{lstlisting}[language=XML]
<states>
<itno>0</itno>
<environment>
<my_variable>2</my_variable>
</environment>
...
\end{lstlisting}
Note that the value obtained from the initial XML agents file will over-wite any default value.
\chapter{FLAMEGPU Agent Function Scripts and the Simulation API}
\label{ch:3}
\section{Introduction}
\label{sec:31}
Agent function scripts define the behaviour of agents by describing changes to memory and through the iteration and creation of messages and new agents.
The behaviour of the agent function is described from the perspective of a single agent however the simulator will apply in parallel the same agent function code to each agent which is in the correct start state (and meets any of the defined function conditions).
Agent function scripts are defined using a simple C based syntax with the agent function declarations, and more specifically the function arguments dependant on the XMML function definition.
The use of message input and output as well as random number generation will all change the function arguments in a way which is described within this section.
Likewise the simulation API functions for message communication are dependent on the definition of the simulation model contained with the XMML model definition.
A single C source file is required to hold all agent function declarations and must contain an include directive for the file ``\mintinline[fontsize=\small]{text}{header.h}'' which contains model specific agent and message structures.
Agent functions are free to use many features of common C syntax with the following important exceptions;
\begin{itemize}
\item Globally Defined Variables: i.e. Variables declared outside of any function scope.
Are not permitted and should instead be defined as global variables within the XMML model file and used as described in \cref{sec:221}.
Note: The use of pre-processor macro directives for constants is supported and can be freely used without restriction.
\item Include Directives: Are permitted however as agent functions are functions which are ran on the GPU during simulation they may not call non GPU code.
This implies that including and linking with non CUDA libraries is not supported.
\item External Function Calls: As above external function calls may only be made to CUDA \mintinline[fontsize=\small]{text}{__device__} functions.
Many common math functions calls such as \mintinline[fontsize=\small]{text}{sin}, \mintinline[fontsize=\small]{text}{cos}, etc.
are supported via native GPU implementations and can be used in exactly the same way as standard C code.
Likewise additional ``\mintinline[fontsize=\small]{text}{helper}'' functions can be defined and called from agent functions by prefixing the helper function using the \mintinline[fontsize=\small]{text}{__FLAME_GPU_FUNC__} macro (which signifies it can be run on the GPU device).
\end{itemize}
The following chapter describes the syntax and use of agent function scripts including any arguments which must be passed to the agent or simulation API functions.
As agent functions and simulation API functions are dynamic (and based on the XMML model definition) it is often easier to first define a model and use the technique described within \cref{sec:42} to automatically generate a functions file containing prototype agent function files and API system calls.
Alternatively \cref{sec:38} describes fully the expected argument order for agent function arguments.
\section{Agent and Message Data Structures}
\label{sec:32}
Access to agent and message data within the agent function scripts is provided through the use of agent and message data structures which contain variables matching those defined within the XMML definitions.
For each agent in the simulation a structure is defined within the dynamically generated header.h with the name \mintinline[fontsize=\small]{text}{xmachine_memory_agent_name}, likewise each message defines a structure with the name \mintinline[fontsize=\small]{text}{xmachine_message_message_name}.
In both cases the structures contain a number of private variables prefixed with an underscore (\mintinline[fontsize=\small]{text}{_}) which are used by the API functions and should not be modified directly.
In addition to this the simulation API defines structures of arrays to hold agent and message list information.
Agent lists are named \mintinline[fontsize=\small]{text}{xmachine_memory_agent_name_list} and message lists are named \mintinline[fontsize=\small]{text}{xmachine_message_message_name_list}.
These lists are passed as arguments to agent functions and should only be used in conjunction with the simulation API functions for message iteration and the adding of messages and agents.
List structures should never be accessed directly as doing so will produce undefined behaviour.
\section{A Basic Agent Function (Updating and Agents Memory}
\label{sec:33}
The following example shows a simplistic agent function (named \mintinline[fontsize=\small]{text}{function1}) which has no message input or output and only updates the agents internal memory.
All FLAME GPU agent functions are first prefixed with the macro definition \mintinline[fontsize=\small]{text}{__FLAME_GPU_FUNC__}.
In this basic example the agent function has only a single argument, a pointer to an agent structure of type \mintinline[fontsize=\small]{text}{xmachine_memory_myAgent} called \mintinline[fontsize=\small]{text}{xmemory}..
In the below example the agent name is myAgent and the agent memory contains two variables \mintinline[fontsize=\small]{text}{x} and \mintinline[fontsize=\small]{text}{no_movements} of type \mintinline[fontsize=\small]{text}{float} and \mintinline[fontsize=\small]{text}{int} respectively.
The return type of FLAME GPU functions is always \mintinline[fontsize=\small]{text}{int}.
A return value of anything other than $0$ indicates that the agent has dies and should be removed from the simulation (unless the agent function definition had specifically set the reallocate element value to false in which case any agent deaths will be ignored).
\begin{lstlisting}[language=C_]
__FLAME_GPU_FUNC__ int function1(xmachine_memory_myAgent* xmemory)
{
xmemory->x = xmemory->x += 0.01f;
xmemory->no_movements += 1;
return 0;
}
\end{lstlisting}
\section{Use of the Message Output Simulation API}
\label{sec:34}
Within an agent function script message output is possible by using a message output function.
For each message type defined within the XMML model definition the dynamically generated simulation API will create a message output function of the following form;
\begin{verbatim}
add_message_name_message(message_name_messages, args...);
\end{verbatim}
Where \mintinline[fontsize=\small]{text}{message_name} refers to the value of the messages name element within the message specification and \mintinline[fontsize=\small]{text}{args} is a list of named arguments which correspond to the message variables (see \cref{sec:241}).
Agent functions may only call a message output function for the message name defined within the function definitions output (see \cref{sec:252}).
This restriction is enforced as message output functions require a pointer to a message list which is passed as an argument to the agent function (\mintinline[fontsize=\small]{text}{xmachine_message_location_list} in the below example).
Agents are only permitted to output a single message per agent function and repeated calls to an add message function will result in previous message information simply being overwritten.
The example below demonstrates an agent function (\mintinline[fontsize=\small]{text}{output_message}) belonging to an agent named myAgent which outputs a message with four variables.
For clarity the message output function prototype (normally found in header.h) is also shown.
\begin{lstlisting}[language=C_]
add_location_message(xmachine_message_location_list* location_messages, int id, float x, float y, float z);
__FLAME_GPU_FUNC__ int output_message(xmachine_memory_myAgent* xmemory, xmachine_message_location_list* location_messages)
{
int id;
float x, y, z;
id = xmemory->id;
x = xmemory->x;
y = xmemory->y;
z = xmemory->z;
add_location_message(location_messages, id, x, y, z);
return 0;
}
\end{lstlisting}
\section{Use of the Message Input Simulation API}
\label{sec:35}
As with message outputs, iterating message lists (message input) within agent functions is made possible by the use of dynamically generated message API functions.
In general two functions are provided for each named message, a \mintinline[fontsize=\small]{text}{get_first_message_name_message(args...)} and \mintinline[fontsize=\small]{text}{get_next_message_name_message(args...)} the second of which can be used within a while loop until it returns a NULL value indicating the end of the message list.
The arguments of these functions differ slightly depending on the partitioning scheme used by the message.
The following subsections describe these in more detail.
Regardless of the partitioning type a number of important rules must be observed when using the message functions.
Firstly it is essential that message loop complete naturally.
I.e. the \mintinline[fontsize=\small]{text}{get_next_message_name_message} function must be called without breaking from the while loop until the end of the message list is reached.
Secondly agent functions must not directly modify messages returned from the get message functions.
Changing message data directly will result in undefined behaviour and will most likely crash the simulation
\subsection{Non Partitioned Message Iteration}
\label{sec:351}
For non partitioned messages the dynamically generated message API functions are relatively simple and the arguments which are passed to the API functions are also required by all other message partitioning schemes.
The get first message API function (i.e. \mintinline[fontsize=\small]{text}{get_first_message_name_message}) takes only a single argument which is a pointer to a message list structure (of the form \mintinline[fontsize=\small]{text}{xmachine_message_message_name_list}) which is passed as an argument to the agent function.
The get next message API function (i.e.
\mintinline[fontsize=\small]{text}{get_next_message_name_message}) takes two arguments, the previously returned message and the message list.
The below example shows a complete agent function (\mintinline[fontsize=\small]{text}{input_messages}) demonstrating the iteration of a message list (where the message name location is highlighted within the structure and API names for clarity).
The while loop continues until the get next message API function returns a NULL (or false) value.
In the below example the location message is used to calculate an average position of all the locations specified in the message list.
The agent then updates three of its positional values to move towards the average location (cohesion).
\begin{lstlisting}[language=C_]
__FLAME_GPU_FUNC__ int input_messages(xmachine_memory_myAgent* xmemory, xmachine_message_location_list* location_messages)
{
int count;
float avg_x, avg_y, agv_z,
/* Get the first location messages */
xmachine_message_location* message;
message = get_first_location_message(location_messages);
/* Loop through the messages */
while(message)
{
if((message->id != xmemory->id))
{
avg_x += message->x;
avg_y += message->y;
avg_z += message->z;
count++;
}
/* Move onto next location message */
message = get_next_location_message(message, location_messages);
}
if (count)
{
avg_x /= count;
avg_y /= count;
avg_z /= count;
}
xmemory->x += avg_x * SMALL_NUMBER;
xmemory->y += avg_y * SMALL_NUMBER;
xmemory->z += avg_z * SMALL_NUMBER;
return 0;
}
\end{lstlisting}
\subsection{Spatially Partitioned Message Iteration}
\label{sec:352}
For spatially partitioned messages the dynamically generated message API functions rely on the use of a Partition Boundary Matrix (PBM).
The PBM holds important information which determines which agents are located within the spatially partitioned areas making up the simulation environment.
Wherever a spatially partitioned message is defined as a function input (within the XMML model definition) a PMB argument should directly follow the input message list in the list of agent function arguments.
As with non partitioned messages the first argument of the get first message API function is the input message list.
The second argument is the PBM and the subsequent 3 arguments represent the position which the agent would like to read messages from (which in almost all cases is the agent position).
The get next message API function differs only from the non partitioned example in that the PBM is passed as an additional parameter.
The example below shows the same example as in the previous section but using a spatially partitioned message type (rather than the non partitioned type).
The differences between the function arguments in the previous section are highlighted in red as is the use of a helper function \mintinline[fontsize=\small]{text}{in_range}.
The purpose of the \mintinline[fontsize=\small]{text}{in_range} function is to check the distance between the agent position and the message.
This is important as the messages returned by the get next message function represent any messages within the same or adjacent partitioning cells (to the position specified by the get first message API function).
On average roughly 1/3 of these values will be within the actually range specified by the message definitions range value.
\begin{lstlisting}[language=C_]
__FLAME_GPU_FUNC__ int input_messages(xmachine_memory_location* xmemory, xmachine_message_location_list* location_messages, xmachine_message_location_PBM* partition_matrix)
{
int count;
float avg_x, avg_y, agv_z,
/* Get the first location messages */
xmachine_message_location* location_message;
message = get_first_location_message(location_messages,
partition_matrix,
xmemory->x,
xmemory->y,
xmemory->z);
/* Loop through the messages */
while(message)
{
if (in_range(message, xmemory))
{
if((message->id != xmemory->id))
{
avg_x += message->x;
avg_y += message->y;
avg_z += message->z;