Any programming statements that will work in C can also be used in a Swarm program. Hence, if one needs access to a programming library that can be used in C, one can also access that library in Swarm. Furthermore, functions written for C programs can be integrated into Swarm code.
One of the obscure and difficult parts of C programming is designing a program to handle command line arguments. The argc and argv[] approach is difficult to manage. Swarm has built-in tools to handle this problem.
If you compile a Swarm program, you "automatically" get some built-in command line parameters. You can see what they are when you type the program's name, followed by --help. Here is some output from the heatbugs program:
$ ./heatbugs --help Usage: lt-heatbugs [OPTION...] -s, --varyseed Run with a random seed -b, --batch Run in batch mode -m, --mode=MODE Specify mode of use (for archiving) -t, --show-current-time Show current time in control panel --no-init-file Inhibit loading of ~/.swarmArchiver -?, --help Give this help list --usage Give a short usage message -V, --version Print program version Mandatory or optional arguments to long options are also mandatory or optional for any corresponding short options. |
If you type a command line like
$ ./heatbugs -s -t |
A person might want to add command line parameters to their Swarm code if they want to automate the processing of many simulation runs. For example, if one wanted to make a simulation run 50 times for each setting of a particular parameter value, then one would need to design a way to pass that particular parameter value from the command line. The repetition of the program can be managed by a user-created script (written in some language like Perl, for example), or with a simulation tool like Drone, developed by Ted Belding of the Center for the Study of Complex Systems at the University of Michigan.
If the user wants to pass additional parameters in the command line, Swarm has built in procedures that make argument processing a bit easier than using the command line processing available in C. This functionality is found in Swarm's Arguments protocol. The details of the usage of Arguments are explained quite well in the Reference Guide to Swarm. Rather than explain every detail, we choose here to explain one worked example[1].
The first step is to edit the main.m. Add an import command for our object that will manage the parameters:
#import "MyParameters.h" |
and then change the initSwarm command to this:
initSwarmArguments (argc, argv, [MyParameters class]); |
This change tells the swarm kernel to look in your class called MyParameters for information about how to process the command line arguments.
Next, write the files MyParameters.h and MyParameters.m. Here they are:
//Parameters.h #import <defobj/Arguments.h> @interface MyParameters: Arguments_c { int numBugs; } - (int)getBugArg; @end //Parameters.m #import "MyParameters.h" #import <stdlib.h> @implementation MyParameters + createBegin: aZone { static struct argp_option options[] = { {"numBugs",'n',"N", 0, "Set numBugs", 5}, { 0 } }; MyParameters *obj = [super createBegin: aZone]; [obj addOptions: options]; return obj; } - (int)parseKey: (int)key arg: (const char*)arg { if (key == 'n') { numBugs = atoi(arg); return 0; } else return [super parseKey: key arg: arg]; } - (int) getBugArg { if (numBugs) return numBugs; else return -1; } @end |
The parseKey:arg: method indicates that when the key is n, meaning the command line passed -n after the program name, then it the corresponding argument is taken and converted to an integer (by the atoi function, the reason for which the include of stdlib.h is needed). When another class tells our parameter manager class to getBugArg, then the command line argument will be returned if there was one, otherwise it will return -1.
The only interesting wrinkle arises when it is necessary to retrieve the value of numBugs from the parameter class. When the Swarm kernel is initialized, it creates an object called arguments. Any commands that one wants to address to the MyParameters class are instead addressed to arguments. For example, when we want the HeatbugModelSwarm.m class to set the initial values, we add an import statement for MyParameters.h and then we make calls against the arguments class. The syntax is like this:
+ createBegin: aZone { HeatbugModelSwarm *obj; id <CustomProbeMap> probeMap; obj = [super createBegin: aZone]; // Now fill in various simulation parameters with default values or // grab values from MyParameters. obj->numBugs = 10; if (([arguments getBugArg] != -1))obj->numBugs=[arguments getBugArg]; [and so forth] |
This example sets the number of bugs equal to 10, but if the value is included in a command line option, then that value is incorporated.
Once the Makefile is touched up to include references to MyParameters, then the program compiles and hthe output from the help command indicates the new parameter is recognized:
$ ./heatbugs --help Usage: lt-heatbugs [OPTION...] -s, --varyseed Run with a random seed -b, --batch Run in batch mode -m, --mode=MODE Specify mode of use (for archiving) -t, --show-current-time Show current time in control panel --no-init-file Inhibit loading of ~/.swarmArchiver -n, --numBugs=N Set numBugs -?, --help Give this help list --usage Give a short usage message -V, --version Print program version Mandatory or optional arguments to long options are also mandatory or optional for any corresponding short options. Report bugs to bug-swarm@swarm.org. |
It does not make any difference whether the user starts the program with the command:
$ ./heatbugs -n 444 or $ ./heatbugs --numBugs=444. |
In either case, the probe map will indicate the initial number of bugs is 444.
[1] | This example is available in full in the package ParameterHeatbugs.tar.gz. All of the changes described here begin with the Heatbugs application distributed in the package swarmapps-2.1.tar.gz. |