The intention of this Swarm FAQ is to support users of Swarm-2.2, which was released and now all previous versions of Swarm are topics of historical interest, but not topics of active research.
In case, for some reason I can't imagine, you want to see the FAQ that existed in 1997, it is here: http://www.ku.edu/~pauljohn/SwarmFaq/OldFAQ/FAQ.html
Users are invited to send their questions to the email list swarm-support or directly to me at pauljohn@ku.edu , in which case I will likely forward the question to swarm-support. I don't want users to put questions directly into this document anymore because many novices do not do it correctly and it is difficult for me to fix. If you are a Swarm expert, you of course are free to edit stuff in here. Just ask me for a password. Try not to damage material created by other users.
Credit for the FAQ Manager software goes to Stas Bekman, who wrote FAQ-Manager 2.0. There is now a FaqManager website on Sourceforge, http://faqmanager.sf.net
I would like to acknowledge the support of the National Science Foundation (Grant SBR-9709404), which has funded my project "Modeling Interest Groups With Swarm." Without that support, I would not be able to offer this FAQ, that's for sure.
Table of contents
If you are reading this, you probably already know.
In case you don't:
Swarm is a programming library initiated by a team of researchers at the Santa Fe Institute led by Chris Langton. To learn more about Langton and the SFI, I'd suggest you look at Mitchell Waldrop's book Complexity.
Swarm represents an attempt to gather up many different kinds of models that go under the heading of "agent-based modeling" and create a common language and programming approach.
[top]In November 1999, the Swarm Team formally departed from the Santa Fe Institute and its activities are now organized through a non-profit corporation called the Swarm Development Group (SDG).
The SDG's web presence is: www.swarm.org.
Development of the Swarm software and related issues are now organized through the GNU foundation's Savannah server: http://savannah.nongnu.org/projects/swarm. Alex Lancaster is the one who has primarily been responsible for the migration to Savannah and he is the "first among equal" project administrators.
[top]1. UCLA Resources. Benedikt Stefansson and Lars-Erik Cederman have taught Swarm courses at UCLA.
Agent based Modelling in Economics with Swarm, at http://cce.sscnet.ucla.edu/swarmcourse/
Benedikt's slides from SwarmFest 98 are available on the SFI pages (www.santafe.edu/projects/swarm).
Cederman "Computational Modeling" http://www.sscnet.ucla.edu/99S/polisci209-1
2. Rick Riolo has taught many courses in the U. of Michigan's Complex Systems Center. Here is a list of their courses http://pscs.physics.lsa.umich.edu//GRADUATE/pscs-grad.html
And here is Rick's Homepage http://www.pscs.umich.edu/PEOPLE/rlr-home.html
3. Paul Johnson, University of Kansas "Agent Based Modeling" http://lark.cc.ukans.edu/~pauljohn/ps909 This has exercises and some worked examples.
4. Pietro Terna's page on Swarm in Torino (Italy) has some very helpful links http://eco83.econ.unito.it/swarm/
[top]Swarm can run on any Linux system, most Unix systems including Mac OS X, and MS Windows under the Cygwin environment.
The Swarm CVS archive and developer pages are now on the GNU Savannah server, and you can review the information here:http://savannah.nongnu.org/projects/swarm
[top]On June 24, 1999, Nelson Minar wrote this in the mailing list:
For a bit of historical perspective, the choice of Objective C was always a compromise. When we sat down to start writing Swarm (in 1994) we couldn't find a language that suited our purposes. C++ was simply not appropriate. We thought about CLOS, or Smalltalk, or a bunch of other researchy languages, but those all seemed to obscure.
So our plan was to write our own language, based on C. Roger and I got about halfway through designing it. Then we took a look and realized that the language we designed was close enough to Objective C that we should just use that.
And as funky as Objective C is at times, I think we made the right choice. Yes, it's a bit obscure, but the language is simple and the support that is there is pretty good. Yes, it's kind of GNU/Unix centric - but until recently, we never even considered running Swarm on Windows. The good side is that it works quite well, and Swarm does some awfully nifty things that normal C systems couldn't touch.
If I were to start today, I'd use Java. That wasn't an option when we started. For what it's worth, Swarm is headed in the Java direction.
[top]The single best source is an online book about Objective-C from NeXTstep. Check it out at: http://developer.apple.com/techpubs/macosx/ObjectiveC/index.htmlApple has an Adobe pdf version here http://developer.apple.com/techpubs/macosx/System/Documentation/Developer/Cocoa/ObjectiveC/ObjC.pdf
There is another html version here: http://www.toodarkpark.org/computers/objc/index.html And there is a version in Adobe's portable document format here: http://www.gnustep.org/resources/documentation/ObjectivCBook.pdf
They seem to regularly change the address of this document, so don't panic if it has moved. We always seem to find it.
Swarm has an Objective-C related site. Check it out! http://www.santafe.edu/projects/swarm/ObjC/objective-c.html
Check it out! Be advised that SWARM supplies new libraries for the Objective-C compiler that are described in the Swarm documentation itself.
David Stes has an Objective-C site:
http://www.can.nl/~stes/compiler.html
Here's the Objective C homepage:
http://www.slip.net/~dekorte/Objective-C/
[top]Since Objective-C is equal to C with extra features, many questions can be addressed by looking for information about C, rather than Objective-C. You can always search the web, but to get you started, here are some online materials:
Steve Summit. Content from the book ``C Programming FAQs: Frequently Asked Questions'' (Addison-Wesley, 1995) http://www.eskimo.com/~scs/C-faq/top.html
The Isaac Newton Institute has this is a great list of "to the point" treatments of specific topics: http://www.newton.cam.ac.uk/computer/c_ref/C/ They have an index document in that site too (look up one directory), but the links in it don't work for me.
Introduction to C Programming, Marshall Brain.
Click here to go to the "ask jeeves" place where I found it
Offers some contrasts with Pascal. Generally nice looking too!
Steve Holmes C Programming. At http://www.strath.ac.uk/CC/Courses/NewCcourse/ccourse.html
C Tutorials. http://devrc.hypermart.net/c/index.html
Introduction to C Programming by Rob Miles, http://www.hull.ac.uk/Hull/CC_Web/docs/cnotes/c4.html This one has a cool sample program with every element linked to an explanation.
Beginner's Lessons in C. http://www.geocities.com/SiliconValley/Hills/1317/lsn1.htm
Programming in C, A.D. Marshall http://www.cs.cf.ac.uk/Dave/C/CE.html
There is a laundry list at the C Coder's Home Page: http://www.lowcountry.com/~jscottb/
[top]Yes. As of Swarm 2.0, one can write swarm programs in Java which can access the Swarm libraries, which are still written in Objective-C. This is done with the Java Native Interface.
[top]The Swarm Team offers a separate supplementary manual for Java programmers using Swarm: click here or go to the swarm homepage.
General Java online resources:
Sun's New-2-Java page of helpful stuff: http://developer.java.sun.com/developer/onlineTraining/new2java/
Nothing beats a full set of java documentation from Sun, really. They have an exaustive list of objects/methods, free for the downloading, on the same page they offer the SDK (software development kit, a combination of libraries and runtime environment that we used to call JDK): www.javasoft.com
You can also get the full text of
Programming Language (overview & links to specific languages). http://webopedia.internet.com/TERM/p/programming_language.html Follow the Java link on the Right
Other books I recently purchased:
Essentially it is a database oriented toward scientific data. It provides efficient, parallel access to named objects, which may be very large.
In the words of Marcus Daniels, (June 15, 2001), "The HDF5 support in Swarm is a way to load and save the state of a simulation. It can efficiently preserve a hierarchy of agents, and can be used to store data streams from agents to disk. HDF5 is library independent of Swarm that works with other packages, such a statistical software like R (http://www.r-project.org). It has benefits over text files such as:
"Suppose you have three dimensional array in C: int ary[1000000][30][10]. What HDF5 does is let you say: "here is the type of my thing, and here is where it resides in memory". HDF5 then looks at what kind of machine, you are using, takes complete notes, and then dumps the data in native format to storage. If someone should load this array on another sort of machine, one where the integers changed from 32 to 64 bits, say, HDF5 takes care of those conversions transparently. In the common case of using the same workstation, the data requires no conversion and is can be read and written in native format. Supposing `ary' is too big to really deal with in physical memory, HDF5 also provides features for navigating the space by slice or by defining a subspace. There is also the option of transparent gzip compression of large objects." Marcus Daniels, Feb. 27, 1999, swarm-support list
[top]Alex Lancaster just notified us that you can search the mailing list archives with the Google search engine. Do this with Google via using the "site" syntax:
site:swarm.org keyword1 keyword2
[top]Installation of precompiled binary packages can save users much time. Packages are available for RedHat linux, Debian linux, Solaris, and MS Windows. I think the best way to find official releases is to hunt on http://www.swarm.org or go to ftp://ftp.swarm.org in subdirectories like "/pub/binaries/redhat" "debian" "solaris" and so forth.
I'm a RedHat/Fedora user, so I've got some special comments on that. If you go here, http://lark.cc.ukans.edu/~pauljohn/Swarm you will see what I have. I've been doing this a while now, so you see several generations of RPMS for several Swarm editions.
[top]Precompiled packages for Swarm are available for the Redhat Package Manager System (RPM) and the Debian package manager (DEB). If your linux system is up-to-date and has the necessary packages installed, these will make Swarm a snap to install.
Look here for the array of RPMs that are available: http://lark.cc.ukans.edu/~pauljohn/Swarm.
If you don't like these RPMs, and you have the RPM software installed, consider rebuilding the binary packages from the SRPM (*.src.rpm) packages. These SRPM packages provide "pristine" source, patches, and configuration files that you can tailor to your specific location.
If you download an SRPM file, then making an RPM customized for your system will be as simple as
rpmbuild --rebuild swarm-XXX-src.rpm
If you do that as a regular user, it will try to write RPM result files into /usr/src/redhat/RPMS/i386, and it will fail. So either you need to use your root permissions to allow users to write in there or instead there is a way to write RPM results into your home directory. Contact me directly if you need help on that.
[top]Yes it is. However, since it is shipped by the million from a single vendor it is more standardised than most UNIX variants and so instructions can be simpler, and it has its own section below.
[top]Here are a few tips that might help you install Swarm on a unix/linux system.
Installing swarm forces you to make a number of decisions about which extra features you will support.
1. Decide about HDF5. Do you want to use the data format library HDF5 and its Swarm related features? It is optional. If so, install its version 1.2.2. We have had success with all 1.2x versions. I keep a copy in my swarm RPM offerings, sfi has one too. The home of HDF5 is at NCSA.
2. Decide on compiler. To compile Swarm 2.x, gcc-2.95.1 or newer is necessary. Note, if you use a Swarm RPM, you need not have gcc-2.95.1, you can still use the egcs compiler distributed with RedHat linux.
If you want to upgrade gcc, go ahead! There are RPMs for gcc-2.95 on this web site: ftp://ftp.varesearch.com/pub/support/hjl/gcc/gcc-2.95.2/ and there are gcc rpms available at other sites as well. If you are compiling gcc for yourself, you should apply the objc patch that is available at SFI. If you want patched RPMS, you can get the ones I compiled at http://lark.cc.ukans.edu/~pauljohn/software and don't forget you need the new binutils from the varesearch site. Read the README, you need the stuff in that directory plus the newer binutils to which they point you.
If you compile Swarm with this new gcc, and do not apply the patch, you will get the Big Ugly compile time and run time warnings about objects being undefined. These don't appear if you install Swarm RPMs from my site because those RPMs are built with a patched version of the compiler. The patch, made available by Marcus Daniels, applies cleanly to gcc-2.95.x. It is in the available at patches subdirectory in ftp.swarm.org/pub/swarm/src/needed.
3. Do you want to write programs in JAVA? If yes, there are considerations.
A. Which "java kit" do you want to use? Swarm (so far) works with Kaffe or the Blackdown JDK.
B. If you use Kaffe, to compile Swarm 2.x, you need to get the "jikes" java compiler version 0.47.
For jikes information, see http://www.alphaworks.ibm.com/tech/jikes. Do not use jikes other than 0-.47. I'm offering it in my site, SFI is offering it too.
C. To compile the Swarm with Java, you must have a version of "emacs" (version 20.x) installed and in your path. Xemacs will not do.
D. In order to get a JAR file out of the swarm compile (jar is a "compressed bundle" of java objects), you need a working copy of the jar program. I found my copy with the JDK from www.Blackdown.org.
4. Configure and Compile Swarm
After you unpack the Swarm source, run the "./configure" command with options you need.
To see all the possible options to configure, type "./configure --help". Here are some highlights:
--prefix=/dir . This tells where you want Swarm to be installed. Example: Specify /usr and it installs swarm in /usr/include, /usr/lib, /usr/etc.
--with-defaultdir=/dir . On a standard RedHat linux system, most software packages are installed with the prefix /usr, so the --with-defaultdir=/usr option will be sufficient to tell the compiler where to find tcl,tk,xpm, and the other requirements. If it is necessary to specify were particular libraries are available on the system, additional options can be used.
--with-srcdir = /dir . Build swarm in a clean directory, tell configure where to find the source.
--enable-subdirs . This option tells Swarm to build and install into subdirectories named "swarm" in the include and lib directories, as in /usr/include/swarm and /usr/lib/swarm. This helps to keep Swarm files separated from files belonging to other programs.
--with-hdf5dir=/dir or --without-hdf5dir . Tells Swarm to use hdf5 or not use it.
--with-jdkdir=/dir or --without-jdkdir . Tells Swarm to use a Java kit installed in /dir or not use Java at all.
On my RedHat system, I built against the Kaffe libraries, which are installed in /usr, but I used the jar program from the Blackdown JDK. So this worked:
JAR=/usr/local/jdk1.2/bin/jar JAVAC=jikes ./configure --with-defaultdir=/usr --prefix=/usr --with-jdkdir=/usr --enable-subdirs --with-hdf5dir=/usr
This is the "usual" way, and it builds swarm in the source tree itself. With Swarm 2.0.0, some users have reported a problem that Swarm would not compile. The solution is to compile swarm in a separate "build directory". As Marcus Daniels explained, "It should work if you do the build in a different build directory, e.g.
$ cd
$ mkdir -p build/swarm
$ cd build/swarm
$ $SWARMSRCDIR/configure --srcdir=$SWARMSRCDIR [etc]
In here, you either replace $SWARMSRCDIR with the path to the source or define an environment variable SWARMSRCDIR that does so.
In general, this is a good practice for compiling software because the source tree is never written in--it always stays clean!
Quick warnings/notes:
Jikes can be used whether or not your jdk is Kaffe or the Blackdown JDK. Jikes is a fast compiler. If you don't have jikes, you can still use the javac compiler in the Blackdown JDK. In place of "jikes" in the above, please give the path to your JDK's javac.
If you don't want java, cut out the JAR, JAVAC stuff, and use --without-jdkdir as a configure option.
If you don't have a jar program, then remove that part of the configure statement and then add a configure option --disable-jar.
If you don't have hdf5, change the hdf5 flag to --without-hdf5dir.
Then "make" and "make install" as usual.
If you installed in an "out of the way place", say /usr/local/swarm, then it will probably be necessary to work on the dynamic library path. On RedHat, these things are typically controlled in /etc/ld.so.conf. If you can't/don't care to make a permanent change, do this:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/swarm
That will make your swarm libraries available to the compiler. Don't forget your SWARMHOME is /usr/local/swarm in such a setup.
5. The program R is an "S+ lookalike" that can be installed before or after Swarm. In order to use the HDF5 features in R, you need to install HDF5 and compile R against that version of HDF5. Or use the RPM I'm offering.
6. Get Swarmapps. The "swarmapps-2.x.tar.gz" package contains source code you can use to compile programs.
The package called "swarmdemos-2.x.i386.rpm" is pre-compiled programs that anybody can run, even if they don't install the Swarm libraries. If you have installed Swarm, there is no need to install Swarmdemos.
[top]Let's assume you are going to try the Objective-C version of swarm first. I think that's the right way to go.
1. Install Swarm in some binary (precompiled version) for your platform. Redhat Linux users need the Swarm rpm from SDG web site or an updated Swarm RPM from my site.
Install swarm:
rpm -Uvh swarm-2.x.x.i386.rpm
If you had Swarm installed before, you probably don't need to read this, but please remember to use rpm to remove the old Swarm before installing the new one.
2. Get the swarmapps-2.x.x.tar.gz package from ftp://ftp.swarm.org, put it someplace where you can work as a user, say /home/your_name/swarm/src. Make these directories if they don't exist. Don't be root this whole time, please. Create a user account and use it.
Then cd /home/your_name/swarm and type tar xzvf src/swarmapps-2.x.x.tar.gz
That should open a new directory /home/your_name/swarm/swarmapps-2.0.1.
3. cd to swarmapps-2.x.x and pick a program, say "heatbugs", and cd into that directory.
If you installed the Swarm RPMs without any special tags, your SWARMHOME is /usr.
You can tell Swarm to use that home either by editing the Makefile in the application directory (that's my personal favorite) or by typing a shell command
export SWARMHOME=/usr
Then type
make
and it should compile. If you compiled heatbugs, when you do "ls" you should see the file "heatbugs" and you can execute it by
./heatbugs
Please note: installing Swarm may make it necessary to install other RPMs, such as glibc-devel, hdf5, and so forth. Roll with the punches. If the rpm packager says you need a package, go find it, or ask in swarm-support.
Now, about Java Swarm. There is a separate RPM for that, and which RPM you get will depend on whether you use the Sun JDK or the Kaffe implementation of Java. But you need to match up your Java kit against the swarm-jdk or swarm-kaffe package, install them, and then download some swarm programs written in java.
[top]This has changed over the years quite a bit. Swarm used to require the user to compile and install a large number of libraries. No longer should most users need to build libffi or libavcall. On a standard Linux system, you need
1. Tcl/tk (greater than 8.0.4; works with 8.3)
2. BLT. Blt version 2.4g or newer is required. If you use tcl/tk 8.2, it is necessary to have blt 2.4j, at least.
3. Jikes 0.47 is workable version! Jikes 1.15 is workable. Don't use 1.01 or versions around there, they had problems.
4. Hdf5 is optiona, but recommended. Version 1.4.3 works
5. C Library. Does it work with libc5? Unknown. It is known to work with GlibC-2.0 and 2.1.
[top]There is now an answer. User blt-2.4g or newer. blt-2.4g is the one supplied with the RedHat 6.0 distribution. It seems to be working fine for most people.
For a while we were using swarm with an alternate version, BLT-8.0-unofficial. That one was developed when one team thought that the original blt author had walked away from the project. There was an urgent need to upgrade blt-2.3 to work with tcl/tk 8.0, and so that team did revisions and gave their result a name which is, really, quite revealing.
Later, the original blt author remerged and began updating and called his new version blt-2.4. That seems to be the best one to use.
Please be aware of an undocumented change in the blt-2.4z package. The Swarm libraries use a BLT script called "bltGraph.tcl". In the new BLT, that script was renamed as "graph.tcl". So Swarm won't work unless you create a symlink in your /usr/lib/blt2.4 directory:
ln -sf /usr/lib/blt2.4/graph.tcl /usr/lib/blt2.4/bltGraph.tclIf you use the BLT RPMs I provide, that symlink is created automatically for you. [top]
Libffi is no longer a required package on most Unix systems. The exception is IRIX 6.5
These (alternative) libraries provide a portable dynamic callout interface for MessageProbes. In old versions of Swarm, this was done using a compiler feature, but that feature has since been deprecated, effectively. ffcall is the more complete library, but we didn't want to require its use since it has a stronger license than Swarm (GPL). libffi uses the same license as Swarm (LGPL). Marcus Daneils, Feb. 27, 1999 swarm-support list
[top]First, it is no longer necessary to build tclobjc separately. It is not necessary to build libffi. It is now part of the Swarm distribution.
So, you need to
Install blt2.4f or newer (it seems blt8.0-unofficial has fallen by the boards)
Install Swarm itself.
The procedure now follows the standard GNU configure-make-make install routine. There are some important details about the choice of compiler that need to be specified in the configure statements. Those details are explained in greater detail in an earlier section of this FAQ.
If you have the RPM or DEB software, you might consider grabbing the source packages and rebuilding them, or at least studying them as examples of how you might do it.
[top]I don't know SuSe myself. But in the mailing list there have been some highly informative posts! See here:
FAQ: Installing Swarm on SuSE Linux 6.2, posted by Nigel Gilbert October 30, 1999 (sorry, don't have the http, so go look in the list archive!)
That previous approach requires some heavy lifting. If I were a Suse user, I'd consider trying to skate an easier path, as described by Benedikt Staffanson on August 4, 1999. It should be here
Before that, Jan Kreft posted a big note about Suse 6.1, and Benedikt's was in large part a response to it click here .
[top]This takes some fiddling around, but luckily it is documented: http://www.santafe.edu/projects/swarm/archive/list-archive.9911/0101.html
It looks to me like it would be easier to install Swarm on the target system :)
[top]Binaries are available for MacOS X 10.3 (Panther) and 10.2 (Jaguar). However, MacOS X is a new operating system and evolving rapidly. Each new version contains more stuff for running GNU type applications such as Swarm. Also, unlike new versions of Windows, each successive iteration is running faster even on old hardware. Unless you suffer from extreme poverty, you should run the latest version.
[top]No. Not no way. Never.
[top]Source code can be be downloaded or checked out as described elsewhere in this FAQ. No special sources are needed. Binaries of the Swarm libraries and all the necessary supporting libraries which are not already included in MacOS X can be found from the Swarm site at http://savannah.nongnu.org/projects/swarm. Instructions are provided with the binary packages.
[top]No. Everything not included in the standard MacOS X package is available on Savannah. Having other packages installed may well cause trouble now and is more likely to cause trouble in the future.
[top]X11 is the software that provides the graphical display for most UNIX systems. However, MacOS X uses a proprietary Apple display called Aqua. Due to problems with BLT (any volunteers welcome to help sort this) Swarm on MacOS X uses X11. Fortunately Apple bundle X11 with Panther. However it is an optional install. If you do not have it (Applications/Utilities/X11), then just locate and double click the X11 package on the installer disks. You need to start X11 before trying to run any Swarm GUI applications.
[top]Upgrade to Panther. There used to be a beta of Apple X11 for Jaguar, but it is no longer available and will probably expire soon even if you can find a copy. The Apple X11 is based on Xfree86 and versions of that above 4.2 will run on MacOS X. However, they are much slower than Apple's version. So don't bother.
[top]Xcode (formerly Project Builder) is Apple's free Integrated Development Environment (IDE) for MacOS X. It consists of a GUI (Xcode) which can manage the files in a project, relate to version management systems such as CVS, and relate to the native build system to issue commands to compilers, linkers etc to build the project. It also contains a Class Browser and a fully featured code editor. Xcode is tightly integrated with Interface Builder which enables the simple construction of GUIs for Mac Applications.
Along with the graphical applications, the Xcode package contains all the compilers linkers and programming utilities uou need to build libraries and applications. It must be installed even if you don't want the GUI bits. It comes with every copy of MacOS X and new machine, but is not preinstalled. If you lost your disk or need updates go http://developer.apple.com. There you need to sign on as a member of ADC, which is free. Then you can access the downloads section.
[top]The BSD subsystem is a bunch of UNIX command line tools, libraries and documentation, which provide BSD UNIX and increasingly Linux like functions to MacOS X. You must have it. On Panther it is installed by default. On older systems which have been upgraded, it may be missing. As with X11, just locate the package on the installer disks and double click it.
[top]In order to be portable between operating systems, Swarm uses a GNU build system using GNU make, autoconf, automake and libtool. There also some help along the way from Emacs. For details on these things see http://www.gnu.org. Normally Xcode takes the place of autoconf, automake etc. and a program called jam takes the place of make. However, Xcode can use the GNU build system. For examples and clues see the Swarm library source code and also source for packages like Tcl/Tk (http://tcl.sourceforge.net). If you would like to help work out ways to simply develop Swarm models in Xcode then please volunteer.
[top]Windows is not my chosen operating system, but I've tested out the 2.2 release and it works fine. It is now a Cygwin framework. The file "setup.exe" is a customized version of the Cygwin setup program that will go online, download a lot of packages, including the swarm Cygwin package. I think these are on an SFI server.
Depending on which version of setup.exe you run, you will notice that the installation includes either a ton of programs or just a bare minimum. Lately, it seems to include a minimum, so you should run the installer again and get some vitals like "wget" and anything else that looks fun to you.
You ought to be able to find your way to the newest setup.exe on http://www.swarm.org.
[top]Since Fall, 2001, we have been telling users to remove Swarm-2.1.1 and instead try the new Swarm-2.2 offerings. This works fine on Windows NT or Windows 98 or Windows 2000. Marcus Daniels has been issuing new prelease versions for windows on the ftp site. There's a very detailed set of notes in the "Memos" subdirectory of this SwarmFaq web site. http://www.ku.edu/~pauljohn/SwarmFaq/Memos/pretest11Install.txt You could ask in swarm-support and describe your particular troubles.
On June 29, 2004 Pietro Terna has taken ownership of this issue and posted this "All What You Need" link: http://eco83.econ.unito.it/swarm/materiale/cd That page has a README file, which explains you can download a cdrom iso file, and also if you look in the directory "Swarm-2.2_cd" you see a bunch of files, and there's a very valuable file called "instructions.pdf". That gives detailed step by step info on how to use his packages.
Before Pietro posted his announcement, here is what I was telling people they ought to do.
1. Remove Swarm-2.1.1.
I think it is best to do this in 2 steps. First, clear your mount points. (open a terminal, and type "umount -A").
Then use the windows control panel, add/remove programs routine.
2. Install the Cygwin32 kit, available free from http://www.cygwin.com. Make sure sure you have all the development tools and the PNG library. Please run the cygwin icon (a dos command shell with bash running inside it. Make sure you can do ordinary things like "ls" and such, just to test it out.
3. Download a snapshot of Swarm-2.2 (a pretest or final version when its ready!). Download from here.
ftp://ftp.swarm.org/pub/swarm/binaries/w32/latest
4. Untar/unzip Swarm-2.2.tar.gz wherever you want. Most people just put it on C:, so it ends up as C:\Swarm-2.2
5. Mount the Swarm stuff inside Cygwin.
On 2003-09-16, MGD wrote it this way. "Go into a Cygwin shell and type "umount /Swarm-2.2". (get rid of old mounted drives). Now using Windows, not Cygwin, find all your directories with the name "Swarm-2.2". Delete them. Now in Cygwin, do "cd /cygdrive/c" and then untar the pretest. (Replace the "/c" with "/" followed by some drive of yours that has enough space for that pretest.) Now you can issue "mount 'c:\Swarm-2.2' /Swarm-2.2". (Include the single quotes, not the double quotes.)"
I have tried this on different windows systems and, oddly enough, the syntax of the mount command varies across systems. In case you get abuse from your system about mounts, take a look at the output from the mount command to see how it thinks you should mount your stuff. Try a
#mount
and a
#mount -m
will spit out a list of commands that the system thinks would re-create your existing mounts.
6. Make sure that /Swarm-2.2/bin is first in your PATH. It must be in there ahead of thecygwin things. You can do that in many ways. One way is to edit the /etc/profile that Cygwin uses. Anothe r is to edit the environment on your Windows system. That may be done in autoexec.bat on older systems or in the control panel/system/environment options on WinNT or later.
On Oct.20, 2003, Pietro Terna posted some information that is likely to be very helpful to Windows users in the swarm-support list. Some people appear to have incomplete installs of Cygwin, and this results from following the easy "let the web installer do everything approach." Instead, consider what Pietro said:
My suggestion is that of reinstalling cygwin. You have to delete two registers, with regedit (Software\Cygnus Solutions' under HKEY_LOCAL_MACHINE and/or HKEY_CURRENT_USER) and to delete the \cygwin folder.
A suggestion: with Cygwin setup.exe first of all download the packages from Internet and then Install from local directory. If something goes wrong, you have a local copy of the installation stuff.
To install Swarm you have only to unpack it; if you have it in c:\, from cygwin execute the followin lines:
cd /cygdrive/c/
tar zxf Swarm-2.2-pretest-10.tar.gz
mkdir /Swarm-2.2
mount 'c:\Swarm-2.2' /Swarm-2.2
Then create in your cygwin home directory a .bashrc file containing:
export SWARMHOME=/Swarm-2.2
export SWARMDIR=/Swarm-2.2
PATH=.:$SWARMHOME/bin:$PATH
export PATH
export LESSCHARSET=latin1
export TMPDIR=/tmp
export LTDL_LIBRARY_PATH=/Swarm-2.2/lib
alias ls='ls --color=auto'
cd
/End if Pietro Quotation /
I think my windows systems are screwed up from years of mucking around with the environment, so often I just start the cygwin shell and make sure everything is right by doing:
# export SWARMHOME=/Swarm-2.2
# export PATH=/Swarm-2.2/bin:$PATH
. The new Swarm-2.2 pretest 10 is built using gcc 3.3 which is also included. The Java native version, using gcj, also works.
For example, to compile native java jheatbugs:
# CLASSPATH=/Swarm-2.2/share/swarm/swarm.jar gcj -O2 -g --main=StartHeatbugs -L/Swarm-2.2/lib *.class /Swarm-2.2/lib/gcj{swa
rm,gnubytecode}.o -o jheatbugs
That's all one line. Then:
# export LTDL_LIBRARY_PATH=/Swarm-2.2/lib
Then to run it:
# ./jheatbugs
Please understand, if a tarball that is 2-4 megabytes in size with a name like "swarm-2002-05-14.tar.gz" is the source code for the swarm libraries. A package with the "pretest" name in it is a compiled directory full of software, it will be much much larger. If you built gcc and installed several other programs in your computer, you could take swarm-2002-05-14, open it up, and configure/make that into the swarm libraries. Instructions for compiling/installing from the source are offered elsewhere, mostly in the Unix sections of this faq.
Pietro Terna posted example files that go in your home directory on your WinXP/NT system. I posted them (after appending his name) in the Memos directory of the SwarmFaq page: (http://lark.cc.ku.edu/~pauljohn/SwarmFaq/Memos). These files are dot_bash_profile--Pietro and dot_bashrc--Pietro
Pietro wrote this: "You can also automate a part of Paul's explanations placing the attached file in your home directory in Cygwin and renaming them as follows (from the Cygwin terminal shell):
mv dot_bash_profile--Pietro .bash_profile
mv dot_bashrc--Pietro .bashrc
Recently I have tried and failed to build Swarm against the Spring 2003 edition of Cygwin.
Before Marcus posted Swarm2.2pre7 on June 30, 2003, I had fought unsuccessfuly with the Cygwin platform. The problem as that Cygwin had updated the tcl/tk and that caused some trouble. I saved a copy of the older tcl/tk that did work and posted it here:
http://lark.cc.ku.edu/~pauljohn/Swarm/miscSupportSoftware/Cygwin/tcltk-20001125-1.tar.gz
I believe you can use the Cygwin installer to remove the tcl 8.4 that it put in and install this older one. It works for some people, anyway, with Swarm-2.2-pre6.
[top]Vegard Hartman wrote to the swarm-support list (May 27, 2004):
There is something wrong with the java swarm and the current version of Cygwin. However, it is easy to get around this. Just follow the steps below and you should be able to run any java swarm application.
1. Compile your code using javacswarm
2. Compile your bytecode using gcj. The command you have to write to compile jheatbugs is($ is the prompt):
$CLASSPATH=/Swarm-2.2/share/swarm/swarm.jar gcj --main=StartHeatbugs *.class /Swarm-2.2/lib/gcj*.o -L/Swarm-2.2/lib -o jheatbugs
3. Run your application by typing:
$LTDL_LIBRARY_PATH=/Swarm-2.2/lib ./jheatbugs
[top]When the Swarm install runs, it checks to see if you have some environment variables set. Most Windows users don't have them, so on a "naked" machine, the Swarm install will add lines to the autoexec.bat that sets the "home" directory and a number of others. In Swarm-2.1.1, not so many variables are set in the environment as were set in the previous distribution. On win95/98, these are inserted into the autoexec.bat, while on winNT/2000, they are inserted into the environment
SET HOME=C:\Swarm-2.1.1 SET SWARMDIR=C:\Swarm-2.1.1
It does not need so many variables in the environment because Swarm-2.1.1 does not use Cygnus stuff and a number of the enviornment variables have now been set in the .bash_login file which is executed when a shell is created. SWARMHOME is created in there, for example.
Installing Swarm-2.0.1 on a clean win95 machine, in contrast, put these in autoexec.bat:
SET SWARMHOME=/Swarm-2.0.1/ SET MAKE_MODE=unix SET SWARMROOT=/Swarm-2.0.1 SET PS1=\u@\h[\w] $ SET CYGFS=/cygnus/cygwin-b20/ SET CYGROOT=c:\cygnus\cygwin-b20\ SET PATH=C:\WINDOWS;C:\WINDOWS\COMMAND;C:\PKWARE;C:\CYGNUS\CYGWIN~1\H-I586~1\BIN;C:\SWARM-~1.1\BIN
The "home" directory is the place where many programs like Emacs look for a configuration file. By default, it is set as c:\swarm-2.0.1.
The other environment variables are needed to make Cygnus work together with Swarm and Emacs. If you compile something inside Emacs, it will look for gcc in your path, and so the cygnus binary directory needs to be in the path.
[top]Answer: I'll suppose you don't know much about Unix. Create a directory where you want to have your swarm projects, let's call it c:\swarm. This is NOT the same place where the Swarm library is installed. It is a different place. So create such a place, like c:\swarm.
Then you want to unpack swarmapps-2_x_tar.gz into that directory. The shareware program for Windows called Winzip can extract this file for you. If you don't have Winzip, there are free tools available to un-gzip and untar this thing. I believe the GNU tar program is included in the Swarm distribution, and it can handle this with the command "tar xzvf swarmapps-2.1.1.tar.gz" I've most recently seen those tools in the utilities directory of a site that offered Emacs for windows NT: ftp://ftp.gnu.org/gnu/windows/emacs/latest/utilities/i386/.
In Winzip, a puzzle arises after you double-click on swarmapps-2_x_tar.gz. It asks for the file name of the thing inside. It prompts you with "swarmapps-1_x_tar." and you must change that to something like "swarmapps-2_x.tar" and after that Winzip will give you a list of all the files inside the tarball. You should see stuff like "heatbugs" and so forth. Click the "extract" button but when it asks for the target directory, choose your "special place" c:\swarm. That should create a directory c:\swarm\swarmapps-1.4 and under that will be directories like tutorial, heatbugs, etc.
Now fire up a "Swarm-term." In here you use Unix style commands. There is a brief recitation of Unix terms in a separate FAQ for people that use Swarm on Unix systems, but it might be useful for Windows users too. There is a link to it somewhere here in the SwarmOnlineFAQ.
For starters,type this:
ls (and hit return. I'm not typing "hit return" any more after this!)
You should see a unix-style listing of files in the directory where your swarm library is installed. Compare it against c:\Swarm-1.4.
Now, type change into the directory where your swarm code is. Use unix style directory references, as in
cd /swarm
and
ls
You should see a directory listing of your swarm programs, which now contains just swarmapps. Now type
cd swarmapps-2.x.
(Big hint. The "TAB" key will complete long words for you in a Swarm-term, so just type s and hit TAB). Type ls again to survey the offerings. Then type
cd heatbugs
You can look at the contents of these files with any Windows editor you want. Just use explorer to go to c:\swarm\swarmapps-1.4\heatbugs. Or you can use a Unix editor in the Swarm-term, if you install a Unix editor. To simply view the files, the Unix command "less filename" will work in the Swarm-term as provided.
Now you are in the heatbugs directory, look around. You see code and a Makefile. The Makefile is used by the make program, which controls the compilation process. Type
make
This is the Unix command that is used to compile software, to turn code into an executable. After it finishes, you should see a new file after you type "ls". That file is an executable called "heatbugs". In Unix, you usually type
./heatbugs
to make the program run. That will work here, but my trial experience indicates that the "./" is not necessary with the new version of Swarm-term. That should run the program and you are off to the races.
If you have Emacs, you can bring up the Swarm terminal inside Emacs by typing ESC x (or alt-x), and then type "shell" and hit return. This is a GOOD THING TO DO because the Emacs buffer will save everything, you can scroll and save it if you want to.
[top]Answer: My favorite general-purpose Windows editor was a free program called PFE, short for "Programmers File Editor." That is dead, so far as I can tell. But the Notepad++ project still exists and it is very highly popular with my graduate students. https://notepad-plus-plus.org.. Notepad++ is useful for editing files of all types and can be customized to programming languages.
Now, we are in 2016, and I've not used Windows in 10 years, except for occasional advising, so you can take my advice with a grain of salt.
I've become convinced that the best alternative is to use Emacs. This is a powerhouse Unix program that has been ported to Windows. One virtue of Emacs is that it is integrated with shell programs like bash (the Swarm-term, in other words) and you can compile and execute code from within Emacs. Emacs has color-coding for keywords. If you look back in the mailing list, you will see various tips about it.
Emacs homepage: http://www.gnu.org/software/emacs/emacs.html
There is a very excellent professor in Canada named Vincent Goulet and he has, since 2012 or so, been preparing very excellent Emacs installers for Windows and Mac. http://vgoulet.act.ulaval.ca/en/emacs. I would not consider using anything else on Mac or Win.
Why Emacs? Well, its free, incredibly powerful, likely to be around forever, available for just about any kind of computer you can find. It is a bit complicated but a good investment of effort.
[top]I'm not sure what the current advice is since I don't run windows. I recall there was a script jdkswarm in the Windows distribution, have a look at that and see if you need to edit it for your system.
Concerning an older Swarm release, Glen Ropella told me this:
1) Get the Java 2 SDK from http://java.sun.com/products/jdk/1.2/. Install that somewhere, say c:\Java\jdk-1.2.2
2) Put the JDK in your PATH. To do so, go to your HOME directory, say x:\Swarm-2.0.1, find the .bash_login file and add the followingline *before* the "export path ..." command:
PATH="/Java/jdk1.2.2/bin:$PATH"
This assumes you put the JDK kit is in the root drive in the directory Java. Where it says x:\Swarm-2.0.1, you should substitute the SWARMHOME directory. If you don't have a HOME, the swarm install creates one in c:\Swarm-2.0.1, the sameplace where SWARMHOME is.
3) Get the CLASSPATH right. One day, Marcus said "you just want to make sure that javaswarm.dll is in thePATH and that CLASSPATH has the path to swarm.jar (and then theJDK-compatible runtime of your choice in your PATH)." Glen and Marcus both say that, to do this, you add something like the following line anywhere in the .bash_login file:
export CLASSPATH="$CLASSPATH;.;x:/swarm-2.0.1/share/swarm/swarm.jar"
all on one line without the break between the ";" and the next library.
You can also write it like this:
export CLASSPATH='C:\Swarm-2.0.1\share\swarm\swarm.jar;'$CLASSPATH
(assuming your SWARMHOME is c:\Swarm-2.0.1, that is).
After doing that, you could run stuff directly, e.g."java StartHeatbugs".
[top]No, not really. Swarm assumes you have the Cygnus tools, and we know of at least a few instances in which those other tools have made swarm programs crash. In Marcus Daniels's words, "using unixdos as replacement tools for Cygwin will likely cause all sorts of problems." (swarm-support, Jan. 29, 2000).
One suggestion is to put the Cygnus tools in your path ahead of the others, if you don't want to remove the others.
[top]Yes, if you want to go through some hassle. In the swarm-support mail archive, July 19, 1999, you will find a note from Marcus Daniels outlining the procedure. http://www.santafe.edu/projects/swarm/archive/list-archive.9907/0149.html. A more recent description is here: http://www.santafe.edu/projects/swarm/archive/list-archive.0011/0090.html This superceded an earlier approach that was announced April 2, 1998 ( http://www.santafe.edu/projects/swarm/archive/list-archive.9804/0045.html)
[top]Updates may be available already on the SDG website (see above). If you need to modify the Swarm source for and rebuild under Windows, the procedure is essentially the same as it is in Unix. Assuming you can build it in Unix, there are no big problems awaiting.
If you don't want Java support, all you need is to download the existing swarm.exe file, install it, then grab the source for the new version of Swarm you want to build, untar that, and do the usual things to reinstall over your existing swarm. That is, without any frills,
$ ./configure --prefix=/Swarm-2.1.1 --without-jdkdir
$ make
$ make install
For Java users,
You can compile Swarm with Sun JDK like so:
#!/bin/sh
SWARMSRCDIR=/src/Swarm/swarm
jdk=--with-jdkdir=/cygdrive/i/jdk1.3.0_01
SWARMHOME=/Swarm-2.1.1
JAVAC=jikes
EMACS=/cygdrive/e/emacs-20.6/bin/emacs
$SWARMSRCDIR/configure --srcdir=$SWARMSRCDIR --prefix=$SWARMHOME --with-defaultdir=$SWARMHOME
$jdkmake
Marcus Daniels says,
FYI, here's the script I use to build against Borland JBuilder's JDK.The only subtlety is the use of a quoted $SWARMROOT for the prefix. Swarm expands this symbol at *runtime*. This is why the Windows InstallShield package is physically relocatable on the filesystem.#!/bin/shSWARMSRCDIR=/src/Swarm/swarmjdk=--with-jdkdir=//H/JBuilder3/java
JAVAC=jikes EMACS=//G/emacs-20.4/bin/emacs
$SWARMSRCDIR/configure--srcdir=$SWARMSRCDIR--prefix='${SWARMROOT}' --with-defaultdir=$SWARMROOT
$jdkmake -j2
Before you do this, you need to have swarm installed because it supplies the tools needed to build, or you can build the tools yourself (ex, gcc3). If you want to build Swarm against Kaffe, it should happen "automagically" if you leave off the --without-jdkdir from the configure line above.
If you want to recompie swarm with profiling, you add the complier flag -pg. In windows,this will only work if you install a couple of extra files:
MGD says:
In order to build a profiled version of Swarm for Windows, two files are needed in /Swarm-2.1.1/i686-pc-cygwin/lib:
ftp://ftp.swarm.org/pub/swarm/binaries/w32/2.1.1-fixes/{gcrt0.o,libgmon.a}
In case you download a CVS version of swarm, not a tarball, it is not ready to build. Do this first:
Go into your source tree of Swarm and run:
$ aclocal -I m4 && autoheader && automake && autoconf
$ cd libobjc
$ aclocal -I m4 && autoheader && automake && autoconf
$ cd ../avcall
$ aclocal -I .
$ autoconf
From there, proceed with the configure statement, make, and make install. THe configure statement is conceptually the same as the Unix system build.
[top]1. There used to be a file called "colors.html" at http://reality.sgi.com/nemec/colors.html, but it is not there anymore. If you find a new link, let me know.
2. If you installed the X11 libraries for MS Windows (find in Cygnus site), there is a file called rgb.txt that lists them.
[top]The three major categories of flags are
EXTRACPPFLAGS (for c preprocessor flags)
EXTRAOBJCFLAGS (for flags passed to the compiler when creating the ".o" files)
EXTRALDFLAGS (for linker flags, when the ".o" files are linked to create the program. Here are some common usages
EXTRALIBS (flag to incorporate supplemental libraries)
Why the EXTRA? On Linux systems, Swarm automatically uses CPPFLAGS=-D_GNU_SOURCE, and adding other CPPFLAGS "steps on" that usage. So you ought to use
make EXTRACPPFLAGS="-DSOME_OPTION_YOU_LIKE -DSOME_OTHER_OPTION"
Alternatively, in the application's Makefile, add a line like this:
override CPPFLAGS += "SOME_OPTION_YOU_LIKE SOME_OTHER_OPTION"
Examples
1. To turn on "screenshots" and "use pixmaps" in heatbugs, you do
make EXTRACPPFLAGS="-DSCREENSHOTS -DUSE_PIXMAP"
2. To tell the compiler not to treat warnings as errors, do this:
make EXTRAOBJCFLAGS=-Wno-error
3. To profile a program, pass the -pg flag in both the compile and link phases, as in
make EXTRAOBJCFLAGS=-pg EXTRALDFLAGS=-pg
4. Link against the Gtk widget library
$ make clean $ make EXTRALDFLAGS=-L/packages/lib EXTRALIBS='-lgtk -lglib -lgmodule'[top]
This seems to be a religious question, hard to answer without offending people.
Let me say this. Since Swarm originally developed in Unix it is in some ways more naturally suited to the X Windows System. So, if you are equally able to work in Unix/Linux or MS Windows, you probably ought to pick Unix/Linux. Let me also add this. I was a MS Windows user until I wanted to use Swarm, then I learned Linux. I find it so much more pleasant to use that I now can say, almost always, "I don't do Windows." I made a little essay about it on my linux homepage.
Applications you develop in one OS should compile in the other.
[top]Steve Railsback posted a report in 1999 that the same program running under Linux took about 30% less time than it took under Windows. Not all users have reported a difference that great.
On December 14, 1999, Marcus Daniels offered one explanation of the difference observed:
One thing that is different with Cygwin is that the C library is less integrated with the operating system. Windows does not export POSIX system calls, so some of calls need emulation glue.[top]Also, although both glibc and Cygwin use same malloc implementation, glibc takes advantage of virtual memory system calls, and Cygwin does not. I haven't run tests, but I would expect memory-intensive simulations would be faster on glibc-based systems (e.g. Linux-based systems).
A lot of users on Unix systems get this error when they try to compile an application that was written on MS Windows:
$ make
Makefile:1: Extraneous text after `ifeq' directive Makefile:3: Extraneous text after `endif' directive : No such file or directory '. Stop.m/Makefile.apple target `../../swarm-2.1
This is caused by "illegal characters" in Makefile that are inserted by Microsoft Windows programs. Some editors show the extra carriage returns as ^M.
This can be fixed by getting rid of extra carriage returns that windows inserts. Some windows editors, like PFE, have a UNIX option in the save as panel. In Emacs, do M-x: set-buffer-file-coding-system (then hit enter) and then type "undecided-unix" (without the quotes). Then save your file and it will be purged of Microsoft excess.
Marcus Daniels posted the following command which can purge those symbols as well:
$
for i in *.[hm] ; do tr -d '\r' < $i > $i.new ; mv $i.new $i ; done
This works, as far as I can see.
[top]OK, commonly asked Unix questions from Swarm users are compiled http://www.ku.edu/~pauljohn/SwarmFaq/Memos/Swarm-Unix-FAQ.html. You might also check out my new WikiWiki page: http://www.ku.edu/cgiwrap/pauljohn/twiki/view
[top]No. Files in an application directory can be edited with any text editor and executed from the command line. Linux-using-Emacs-haters might try a program called Xwpe, that supplies a Borland-style development environment, but it is not tailored to Objective-C.
[top]Answer:
1. There have been changes on this topic and I've not sorted them out completely. On Emacs version 20 or XEmacs version 20, Fontlock and color-coding for ObjC is built in. The color coding you get is not, in my opinion, very complete or useful.
One step is to tell the editor which kind of color coding you want. You have to let it know that you want "h" files to use the Obj-C mode of coloring. New versions of Emacs are supposed to know that "m" files are Objective-C files, but I still specify both h and m in the .emacs file in the home directory. Like so:.
(setq auto-mode-alist (append '(("\\.h$" . objc-mode) ("\\.m$" . objc-mode) auto-mode-alist))
The use of color is not very good even then, IMHO.
The next step is to add detail to the .emacs file to control the color editing. There has recently (September, 1997) been discussion of code in the .emacs file to use the newer fontlock package with Emacs. Look here to see the thread begin. For XEmacs users, John Eikenberry posted an excellent piece of Lisp Code that can be added to the .emacs file. Click here to see it! That code worked fine for me after fixing a few lines that were split apart by the email program used to post it. Look toward the bottom of the file, you'll see some split words.
Followup Question: I have added *.h to the auto-mode-alist; but, Emacs still fontifies my *.h files as C and not as Obj-C.
Answer: You should edit the .emacs file as described above. Make sure the *.h are appended to the alist and not pre-pended.
[top]New users often write swarm-support with vague messages about their programs having problems. We almost always have to ask for details, so why don't you save us the trouble and supply the details in the first place. We need to know these things:
Please consult the section "Debugging Tips for Swarm" as part of theUser Guide:
http://www.santafe.edu/projects/swarm/swarmdocs/userbook/swarm.tech.sgml.sect1.debug.html
http://www.santafe.edu/projects/swarm/swarmdocs/userbook/swarm.tech.sgml.sect1.debug.html
A couple of examples of gdb usage under windows are provided here:
http://www.ku.edu/~pauljohn/SwarmFaq/Memos/GDBUsage01.txt
http://www.ku.edu/~pauljohn/SwarmFaq/Memos/GDBUsage02.txt
When a program runs, it can crash if it tries to access things in memory that are not where they are supposed to be. That causes a fault (in unix) or a violation (in windows). Usually this happens if you try to use an uninialized pointer, or if you dereference a NULL pointer. If you try to use an object that has been dropped, or free memory that has already been freed, you are booking a visit to seg fault city.
Most often, it happens if you use a pointer with a bad value.
Here's a sample program, courtesy of Marcus Daniels, that causes a seg fault (as if you needed such a thing!). The pointer is not pointing at anything, so the attempt to dereference it and set a value is wrong..
#include int
main ()
{
int *ptr = NULL;
*ptr = 0;
}
Luckily, if you run your program under the GNU debugger, the backtrace will almost always point at the offending line. If at startup you see this:
*** event raised for error: InvalidArgument
*** function: object_setVariableFromExpr(), file:
/src/Swarm/swarm/src/defobj/internal.m, line: 1871
`probabConst' is not a string*** execution terminating due to error
/src/Swarm/swarm/src/defobj/Symbol.m:173 -[Error(c) _raiseEvent:]
0 [sig] COMPETITION 1111 stackdump: Dumping stack trace to
COMPETITION.EXE.stackdump
It is caused by an incorrectly formatted argument in the .scm file that supplies starting values of parameters.
Common mistakes in .scm files deal with these:
No suffix means integer (actually the capacity of the input is long long)
"F0" means float
"D0" means double float
"L0" means long double float
The suffix should be adacent (no space) to the numbers.
If you have the Swarm code, you can use the test programs to see how exactly these files look when they are written correctly. The Archiver tests
are in:
swarm/tests/defobj/archiver.m
* tests basic serialization on primitive types: both `shallow' and
`deep'
swarm/tests/collections/archiver.m
* tests basic serialization on `List' and `Map' types: both `shallow'
and `deep'
Question: At runtime, you see this:
or
Answer:Your .swarmArchiver file has been corrupted, possibly by a change in Swarm version. Delete it, all will be OK. That file is in the HOME directory of the current user. On MS windows, if there is no HOME set at the time of Swarm install, then it sets HOME as c:\swarm (or wherever you installed swarm). This is a big topic, but the first vital thing is to "profile" your program to find out where it is taking so much time.To use profiling, the GNU program called gprof must be installed. I see
it is in the Swarm-2.1.x distribution for windows and it is installed by
default in most unix/linux systems I've seen. My RedHat system says
gprof comes from the binutils package.
To build a profile, you compile your programs with the -pg compiler
flag. The way this is done in Swarm has changed now and then, but
currently you can get it with
make EXTRAOBJCFLAGS=-pg EXTRALDFLAGS=-pg
Then after you run your program a while--long enough for it to build up
some stats on it--you stop it and you should see a new file called
"gmon.out".
The gprof command produces a readable interpretation of the gmon.out
file.
In unix systems, the swarm executable is in that hidden directory .lib,
so you tell the gprof program to use that, as in:
gprof .lib/program-name-here
In windows, you do not need the .lib directory in there:
gprof ./program-name-here
Output will whir by on the screen quickly, but you can always ">" it into a
file or pipe to less, "| less"
If you are trying to set a parameter in a probe window (such as
diffuseConstant in heatbugs, say), you must press `return' after you
change a value in the parameter window and ensure that the border of
the box briefly flashes red, toensure that the parameter is actually
set to the new value, otherwise Swarm won't pick it up. Answer: If you simply change the code in one of the existing files then you should not have to change the Makefile at all. You only need to type "make" from the command line. The make script will recompile the altered files and any files that depend on the altered files and create the program executable. If you decide to create a new class/file then you'll need to edit the Makefile. You add the name of that file to the Makefile so that it will be compiled and linked into the executable. It is easy to add a new class. Look in the Makefile. It is pretty obvious: For a new class: MyObject, that means you created files: MyObject.h, MyObject.m In Makefile, you edit the OBJECTS line to add "MyObject.o".
Note: If any of the files in your program include MyObject.h, then you should add MyObject.h on the right side of the "files" line for the files which have the include. The naming conventions I follow are:
If name of class/object or defined type then first letter is upper case.
If name of variable or method then first letter is lower case.. All interior
words in a name start with an upper case. Single character variable names:
if it is a class or instance variable then upper case. if it is a local
variable then lower case. (this is the rule I break most often)
Constant or defines are all caps. So, Name of class: "Heatbug", "HeatbugObserverSwarm",
etc. ("Heatbug" is considered one word) Name of defined type: "HeatValue",
etc. Name of variable: "heatbug" is an instance of the "Heatbug" class
"heatbugObserverSwarm" is an instance of the "HeatbugObserverSwarm" class
etc. Name of method: "addLast:", "setX: Y:" etc.
I think this is a fairly typical naming convention. Ken Cline
Objective C naming conventions for Methods:
Question: What about Methods like: SetX: x Y: y Is the method
SetX: and Y: the same method or two different ones? Or is Y: a label?
Short Answer: The methods' name is SetX:Y: (colons are part of the name).
It takes two arguments.
Long Answer: In Objective-C methods are defined by the following convention: is equivalent to, in most other languages (eg C++, Java),
-(void) setXY( int x, int y )
And when calling a method you don't include the types, therefore [ myObject
setX: 3 Y: 5 ]; or myObject.setXY( 3, 5 );
__________________________________ Ken Cline kcline@c3i.saic.com The methods createBegin and createEnd are like "bookends". You can't
have one without the other. Inside those bookends, you can give commands to
an object that govern its state at the time of creation. The createBegin message
is sent to the "factory object," such as "List." The create begin message is sent
to the instance being created, such as heatbugList.
The create method is also in the same class. It can be used when an object
is to be created, which I think means a memory zone is created, but no options
need to be set and no methods need to be run as part of the object's creation.
The user can decide between the create method and the createBegin/createEnd
method on the basis of the need to specify creation-time details. The function initSwarm is in the swarm docs under the Simtools
protocol, General subheading. It is defined in the source
code in the simtools directory, simtools.m. The "init" family listed in the swarmdocs, "initSwarm", "initSwarmArgument" and so forth, are in fact macros that actually
feed parameters to a single function, _initSwarm_ , which is in the simtools.[h,m] directory.
The _initSwarm_ function triggers off a series of inits in other places:
In other words, to get a clear idea of what is entailed by initSwarm, we
have to go to each of the "sub-inits" and see what they do.
1. initDefobj provides these objects:
2. initProbing:
3. initRandom:
4. initSimtoolsGUI (only for GUI sims, not batch in the background mode)
5. initModule. (This sets up some complicated objective-c details: initializaing the phase splitting / multiple
inheritance machinery that defobj, collections, and activity use) Question: In heatbug.h, What does "Grid2d * world;"
do? Does it create a object "world"? What is the "*" do? Is
it used to declare objects?
Answer: This declares a variable called "world" which is of type
"Grid2d *". "*" is C syntax for pointer. So "Grid2d *" is a pointer to
a "Grid2d" class. That's as far as I'm going down the "what's a pointer?"
path... Ken Cline Several things that used to be classes of objects are now
treated differently. One once wrote
The first says "a pointer to a ProbeMap" (a particular frozen thing,
implying knowledge of the internal structure of a object type), and the
second says, "this object will communicate according to this protocol".
We are moving in the direction of using the latter for everything because
it provides much more flexibility. I suppose somewhere in SwarmDom there
is some propaganda about this, but I'm not sure where, offhand. The NEXTSTEP
documentation talks about it.
The practical reason to use the "id <protocol>object" notation
is that if you use the Swarm advertised interface files, e.g. you get is protocol declarations, and so you'll get those sorts of warnings.
Marcus Daniels
If you do this the old-Swarm way with a new Swarm setup, you get this
sort of error when you compile:
HeatbugObserverSwarm.m: In function `_i_HeatbugObserverSwarm__buildObjectsArgC_ArgV_':
HeatbugObserverSwarm.m:196: warning: `ActiveGraph' does not respond to
`setElement:'
Question: The Grid2d space for zoomRaster accepts only integers,
right? So the drawSelfOn method would not work if the X and Y are
doubles. However, if I just cast them as ints, I get "rounded" output,
right, so 14.544 is seen as 14 and the grid looks approximate?
Answer: Technically the values of the floats are truncated and,
one way or another, this would happen, ie you can't draw something at pixel
14.544. BTW, if you want to round then one technique would be to add 0.5
before casting to an int. A. Why do commands to build schedules and such use the M()::
sort of notation?
Answer: M() is a macro that is used in Swarm to pass the name of a method
to some other object. Ted Belding
Answer: M is short for message (or method) and to save the time
of typing @selector(myMethod). Manor.
The on-line Objective-C book provides more details about selectors
and why they are necessary.
Answer: As Ted said M(foo) is a macro that turns a method name, foo,
into a selector. Selectors are what are actually invoked to "call" a method
and method names are sort of short-hand for the entire method specification
(eg method name, parameter types, return type, etc.) as I understand it.
I don't feel I could adequately explain the selector concept so you would
be better off to take a look at an Objective-C text. (BTW, there have been
previous posts to the support list that suggest good Objective-C to use,
in case you were wondering.)
And to remove all the mystery...
defobj/defobj.h:#define M( messageName ) @selector( messageName )
That is M(foo) is equivalent to @selector(foo).
As far as the "forEach" method is concerned, this is a rather straight
forward function that simply loops thru a collection (eg List, Map, Array)
and calls the specified method for each member. Here's the code for one
version of the "forEach" method:
- (void) forEach: (SEL)aSelector { id index, member;
index = [(id)self begin: scratchZone]; while ( (member = [index next])
) { [member perform: aSelector]; } [index drop]; }
There are several "forEach" methods, the only difference is the number
of arguments they accept. That is, if you want each list member to execute
a method that requires no arguments then you would use the "forEach" method
above. For example, [myList forEach: M(print)], where print is given by:
-(void) print { printf("I am agent %s! \n", name); }
Of course, the "setBugColor" method you were asking about requires 1
argument, namely the color.
Getting back to the "forEach" code above, the only action within the
loop is to call the "perform" method. The "perform" method is defined for
the "Object" class, ie the superclass of all classes, so any class can
call this method. Note, however, that the "DefObject" class actually redefines
this method (and many other of methods in "Object") and hence most Swarm
classes actually inherit this other version of "perform".
The "perform" method performs a method call on an object using a selector
and any required arguments. That is the following 2 method calls are equivalent:
[ aBug perform: @selector(setBugColor:) with: red ];
and
[ aBug setBugColor: red ];
(where we could have "(void *) red = (void *)64").
The advantage of the "perform" method is that it allows the programmer
to write very flexible code. For example the following pseudo-code could
be easily written in Objective-C:
-prompt user for a color -check the validity of the user's entry -convert
the the user's entry from a character string to a selector -set the bug's
color to requested color
A less trivial example would be allow the user to select which "brain"
the agent will use during a particular phase of the simulation. There are
other ways to give the user a menu of choices, but the menu must be determined
statically, in other words before the code is compiled.
This is, btw, one of the reasons Objective-C was choosen as the language
to implement Swarm with. Without this flexiblity providing Swarm probing
mechanism (amoung other things) would much more complex. _________________________________________________________
Ken Cline kcline@c3i.saic.com
B. These M():: methods want only to have id's as arguments, but my methods
call for integers. Sometimes Swarm programs work, like when my arguments
are ints, but not other times. Why? I understand typecasting if you cast
an int as a float, for example, that is pretty obvious. Similarly,
it is obvious when you cast a float as int that some parts will get
truncated. But casting int as id?
Answer: The declaration for createActionTo: is:
- createActionTo: target message: (SEL)aSel : arg1 : arg2 : arg3;
which means that the args should be "id" types. An "id" is typedeffed
as:
typedef struct objc_object { struct objc_class* class_pointer; } *id;
which is *not* the same as "int a[2];"
Remember that you're not "casting int as id", you're casting "reference
to int" to "pointer to structure."
glen ropella
C. More whining about M():: and the fact that the arguments must be
of type id.
Question: I'm frustrated that all of these swarm methods require
you pass them an id or object instead of real numbers or arrays (the
C kind, not the swarm kind). I have a typedef that
creates an array, as in int[2], called dimarray. I did that because I want
to pass points in space back and forth between objects without separately
specifying the X and the Y coordinates as arguments, as is done in so many
swarm examples. This type, called "dimarray" in my code, can be cast as
an id without apparent damage, so when the getselector methods are needed
in modelActions or such--you know, M(:)::,you can cast dimarray types as
id and you don't get errors at compile or runtime.
Answer: Have you thought of making the "point" an object in and of itself?
Instead of using an array, you could be using a point in space that has
it's own state (it's coordinates plus any accounting variables you might
need) and rules (dictating display, motion, etc). This is what Nelson recommended
in the FUTURE-DESIGN text in the space library and, I think, what Ken Cline
has done. There are numerous problems with this mechanism, though.
I would suggest the following ways of doing it:
1) make the dimarray an object, give it the ability to draw itself on
a raster, then put the winners in a list to which the schedule will send
a createActionForEach: message. The membership of the list will change
over time.
2) Since you're using a raster instead of a graph or some other nonspatial
display device, I assume you think there's some spatial relationship to
the options that get selected. If you consider the voting alternatives
objects instead of 2d arrays and then give those objects the capabilities
of navigating a 2d space, then you can simply use space like heatbugs does.
The "current" point will be placed in the space and Object2dDisplay can
take care of showing those objects on the raster. If you would like to
keep track of the losers, as well, then you can have 2 spaces, a winner
space and a loser space.
glen ropella
D. [On a Related NOTE: The Swarm Meditation Exercise]
Just remember the mantra: An object is methods and data, an object is
methods and data. It's just wrappings around variables and functions, which
can be put into an isolated container and then accessed through method
calls from the outside world.
Another way to think about objects is that they are just data structures.
So whenever you need to send a bunch of related data and functionality
from one place in the program to another, think about if it makes sense
to wrap it into an object and send the objects name (read: the pointer
to the structure) to the destination, where the recipient can read the
data out of the object via it's methods.
An example might be a "coordinate object", when you need to send x,
y coordinates from one object to another. So you start out by defining
an object with only data, no functionality, with the instance variables
myX and myY (and corresponding get and set methods). Then you get the idea
that maybe it might be useful for the recipient to be able to ask the coordinate
object about how far it is away from some other point. So you throw in
a method called distance: -(double)getDistanceFromX: (int) x Y: (int) Y
which returns Euclidean distance from x,y to myX,myY. And that method could
actually be accessing a seperate object for the distance measure, so that
you can treat the distance function as an assumption in your model (that's
a real world example from one of my simulations).
Benedikt Stefansson benedikt@ucla.edu (The accidental casting of int to pointer does no damage,
but it wont cast float as int).
Question: I am trying to create a dynamic schedule using a createActionTo
message. The Swarm interface guide says that when creating an action to
with one or more arguments, the argument needs to be cast to the Objective
C id type, to whit:
[createActionTo: neurone message: M(receivePulse:) : (id) pulseAmplitude]
This seems fine if the type of the argument (i.e. pulseAmplitude in
the above e.g.) is an integer. But gcc won't allow compilation if the argument
is a float, with an error message to the effect "can't cast that arg to
a pointer". (I can send the exact code and error message if necessary).
Is this a known problem? If so, are there any workarounds? I really
need my arguments to be floats, as integers are far too coarse to represent
the variables in my model. Alex Lancaster
Answer: This is "just the way it is" in the current form of action creation
messages. I wasn't aware that the compiler refused to cast a float to an
id type, but we were aware of the restriction on double types (which are
obviously uncastable as they're twice the size). The standard work-around
would be the same as for doubles: if you don't want to go all the trouble
to create an object, then declare the method to accept an argument of type
float * or double *. Then pass the address of a float or double value in
the createAction message, casting it to (id). When you need the float or
double value in the method, dereference the passed pointer to get it.
This technique avoids the need to create a whole object just to hold
your value, but you still need to be very careful to pass the float or
double address from some allocated location that will actually still be
around whenever the scheduled action is called. Do *not* pass the address
of a local variable where you call the createAction message, because that
calling context will no longer exist when the createAction message is called.
If the float or double is already contained as an instance variable of
an object that will still exist at the time of the call, it's safe to pass
that address. If you've got no convenient container for the float or double,
it may still be just as simple to create an object to hold the value and
pass that address, or else you could allocate a raw storage block just
to hold the float or double. Whatever you allocate, you also have the responsibility
to free the allocation whenever it's no longer required by the action.
The address of a static variable is also safe, but it's hard to create
multiple actions that way that each refer to their own values. Wherever
you allocate the value, be aware that the action will not take value at
the time of action creation, but the current value at that address when
the action is actually executed.
The current technique of creating actions is the fastest and most direct
when you've got compatible argument types, but obviously inconvenient for
floats and doubles. More generic ways of creating actions are possible,
based on taking argument values off a variable argument list according
to declared types of the action's message selector, but this is potentially
more error-prone and carries extra overhead. We could add support for both
methods of action creation if the interest is great enough.
In the meantime, the best I can suggest is to pick your favorite form
of workaround from those that have been suggested.
Roger Burkhart
Question: The lack of a matrix algebra/vector passing ability
seems to be a problem for me. If the ideal array were a ten dimensional
thing, it would get really inconvenient to individually refer to
coordinates. I've gotten around some problems by passing in an object
that contains such an array. That works, until one object has to
tell the other what its array is. The only way I can figure to pass
them out is to write one method for each dimension and give them
one floating point number at a time. (Hence a method getPolX has to be
written that has "return ideal[0]" and a method getPolY has a "return ideal[1]"
and then the object that receives those messages converts them back into
an array with newarray[0]=[thatobject getX] and newarray[1]=[thatobject
getY].
Answers: You could get your desired result by having your matrix object
return a pointer to a simple C array containing the appropriate values.
I think at the core of your question is the lack of standardized collection
objects to hold anything other than other objects (or integers cast to
id). The addition of List, array, map etc objects for double values would
be a tremendous help to me in particular. I currently implement these in
C. Perhaps someone knows of a good swarm compatible objective C library
out there that already contains these objects.
Rob Kewley
Methods like `getX', `getY', etc. only make sense for about 3 dimensions,
ie x, y, and z. If you are doing more than 3 dimensions then why not have
a more general method:
-(double) getCoordinate: (int) index { if ( index > DIMENSION ) raiseEvent(
InvalidArgument, "index > Dimension!\n" ); return ideal[ index ]; }
or possibly:
-(BOOL) getCoordinates: (double []) dblArray From: (int) start To: (int)
end { int i;
if ( !dblArray ) { raiseEvent( WarningMessage, "dblArray is nil ?\n"
); return FALSE; }
if ( start > end ) { raiseEvent( WarningMessage, "start > end ?\n" );
return FALSE; }
if ( sizeof(dblArray) / sizeof( double ) <= end - start ) { raiseEvent(
WarningMessage, "dblArray is too small?\n" ); return FALSE; }
for ( i = start; i <= end; i++ ) { dblArray[ i ] = ideal[ i ]; }
return TRUE;
}
I haven't tested any of this, of course. I hope this helps.
Ken Cline
PS: Personally, I prefer to make dblArray a `double *' instead of a
`double []', but then you can't check the size. Of course, checking the
size isn't necessary so may want to just take that out ayway.
Ken Cline kcline@c3i.saic.com On Jan. 7, 2000, Benedikt S observed, in response to:
> QUESTIONS: Do I need to do something to make my string argument into a
> valid class declaration? (Similar to using sel_get_uid(argSelector) where
> argSelector is a const char*?)
>
Greetings to you,
Do something like this (the nameToObject() macro does the trick):
- createAnObject: (const char*) argClass
{
id mObject;
mObject = nameToObject(argClass);
if(!mObject)
{
raiseEvent(InvalidOperation,"Class %s not found\n",argClass);
}
mObject = [mObject create: [self getZone]];
return mObject;
}
Regards,
Benedikt You can copy some of Swarm's objects easily. If you create a list called theJones, you can copy easily:
That only works for objects created from SwarmObjects, the copy method is not inherited. However, according to Roger Burkhart's mail (check the swarm-support archive 7-24-98),
"If all you need is a simple, shallow copy of instance variables, the copy method
you need is nothing more than:
Question: I'm having to track down a bug where an object
appearing in a list is not the kind it is supposed to be (!) Does anyone
know what the syntax is for getting the class name of the offending object
back, as a printable string?
Answer1: There is a build in method [[yourObject class] name] that works. Look for notes in swarm-support by Sven N. Thommesen and Rick Riolo @ 9-24-97.
Answer2: There are two methods in the objc library (you need to #import char * class_get_class_name(Class)
char * object_get_class_name(id)
So the first returns of the name of the class for a class while the
second returns the name of the class for an object instance.
Followup Question: So, where do I find comprehensive documentation for
the objects and methods available with the GNU version of ObjectiveC?
Answer: Unfortunately, the best place is the source code itself.
On a Linux system, you can look in the rather obscure directory:
/usr/lib/gcc-lib/i486-linux/2.7.2/include/objc
The files objc.h and objc-api.h are of particular interest. While the
functions aren't documented, you'll at least get a list of functions available.
The lack of documentation is annoying and leads to such questions as -Dwight
Followup Question: What's the difference between these functions? Class
objc_get_class(const char *name) and Class objc_lookup_class(const
char *name)
Answer: They are practically the same except that objc_get_class will
trigger an error if the class does not exist; while objc_lookup_class just
returns NULL. objc_get_class is used by the compiler when it generates
code for calling a method, so if the class does not exist in the runtime
the program will abort with an error. User programs generally use objc_lookup_class
so that they can just check if a class without the program aborting.
Dwight Wilson Question: I would like to get a SELector by ascii name, and
I thought (on reading the Obj-C book from NextStep, Chapter 2, "Selectors",
page 65) that I could do:
SEL mySetXXX = sel_getUid("setXXX"); [...but that doesn't work on GNU
Obj-C]
Answer: I think the answer is "it's called sel_get_uid in gcc".
Here's how it is done in Heatbugs:
In main.m:
In HeatbugObserverSwarm.m, for the probes, instead of:
[probeDisplayManager createProbeDisplayFor: heatbugModelSwarm];
you say:
worldRaster = [ZoomRaster createBegin: [self getZone]];
and similarly for the unhappyGraph:
The archiver will use the name of the instance variable for an archiving
tag. You have to add these calls for each widget or object containing widgets
you want to save the position of.
Question: where does the geometry information get saved?
Answer: In your home directory with the filename ".swarmArchiver"
Question: Oh, incidentally, what does this code do??? (from HeatbugObserverSwarm):
Answer: It creates probe displays for the model and observer swarms, deriving
the window-geometry archiving key from the instance variable names. (`self'
is converted into a class name, e.g. HeatbugObserverSwarm).
In the past (without archiving) the same thing was done this way:
Answer 1: You define 'unsigned currentSimTime', then:
a) if the method is executed from within a swarm, you can say
currentSimTime = [ [ self getActivity ] getCurrentTime ];
b) if the method is not a swarm (e.g. an agent), you need to say
currentSimTime = [ [ parentSwarm getActivity ] getCurrentTime ];
[And of course, variable parentSwarm must be correctly initialized when
such an object is created.] Sven Thommesen
Answer 2: There's a macro, getCurrentTime(), which returns the current
running time of a simulation from within any action running within the
schedule.
If an activity running the schedule is stopped, and you're inquiring
its time from the actions within that schedule, you can get the current
time the schedule's activity object using the message [aScheduleActivity
getCurrentTime]. The macro uses this message internally from the current
running activity. You'd typically need to do this yourself only if you're
running multiple simulations in parallel and wanting to keep them coordinated
or check their status.
Roger Sven Thommesen wrote (June 19, 1998):
To make an object globally visible you first define a variable
extern id in some .h file, for example ModelSwarm.h. Then you define
id in ModelSwarm.m, BEFORE the line that says @interface ...
Then in the creation code for the ModelSwarm you add code to create the
generator and connect it to 'myGenerator'. (Don't do something like this in
a class that has multiple members, like HeatBug, for obvious reasons.) Paul E. Johnson email: pauljohn@ukans.edu (updated July 13, 1998)
Answer: You create an object, say "aNormalDist." Then, when
you need a random number, you get it by telling aNormalDist that you want
one with "[aNormalDist getDoubleSample]".
Pick the distribution you want (there are many, like "Normal,"
"Uniform" etc listed in docs). Suppose I want Normal random numbers
with mean 0 and variance 1. (Note you need to include random.h in your
file to make this work).
There are many possible random number generators, that's where
all the confusing stuff kicks in. If you don't want to be an expert,
use one of these two approaches.
1. Let Swarm do the work for you!
Create the distribution object with this code:
aNormalDist = [NormalDist createWithDefaults: [self getZone] setMean: 0
setVariance: 1] ;
The "createWithDefaults" method creates aNormalDist and it also creates
a generator from which that distribution object can get random numbers.
You never specify which random generator and you don't need to!
Which random generator is chosen is determined inside the Swarm libraries.
Each distribution you create causes the creation of a new random number
generator.
2. Force the usage of the default generator, MT19937.
This random number generator is, practically speaking, an optimum mix of
randomness and computer speed. A generator called "randomGenerator" is
created when you use the Swarm random library, and you are free to create
distributions that use it as the supplier of random numbers. This is
available globally, in any file where you want to create a
distribution. This creates the normal distribution object:
Every time you run your program, the random number generators
will start at the same "seed" and you will get the same results. If
you want to have the starting points chosen at random, do it by
adding --varyseed on the command line when you type in the name of
your program (i.e., ./heatbugs --varyseed).
If you need to start the simulation from a certain seed value,
you can control the default object "randomGenerator" with this command.
If you need more control, you can get it. Choose a random number
generator from Sven's incredible list and initialize it yourself and
access it instead of "randomGenerator". You can control the random number
seed explicitly if you want. You can also make the generators give back
information about themselves. Check the docs
Rick Riolo supplied some nice detail on further specification:
I have a run-time (or init file or GUI) settable
parameter, unsigned long seed, and then in a startRNG method I do this:
-(void) startRNG {
Several swarmers have added death to their simulation. For
instance in our military model we have a "terminateAgent" method as well
as "isDead" boolean method for confirming the agent's state.
There are several ways to implement agent death:
Simple death: When an agent dies it just "throws a switch", eg isAlive
= FALSE. Then this switch is used to suppress the agent's actions where
appropriate. For example, in Heatbug.m, we could have:
-step { if ( isAlive == FALSE ) return self; ... }
"Real" death: Alternatively, when an agent dies it could completely
decompose, that is remove any actions scheduled for it, remove the agent
from any lists it is on, and drop the object and any sub-objects from the
simulation.
The first type of death is much simpler to implement, just be sure to
suppress all interaction between the agent an its environment (ie you don't
want any zombies or ghosts roaming thru the simulation, right?).
The second type of death is better programming practice, that is it
removes the objects and frees up memory. If you had a long simulation with
lots "turn-over" in the population then "real death" could provide a significant
performance increase. However, if there is a lot of "turn-over" and births
>= deaths, then you might consider implementing some way to cache the dead,
ie reincarnation. (I'm not sure what affect instituting reincarnation will
have on the heatbug suicide rate... maybe you could investigate that?)
Warning: I mentioned "remove the agent from any lists" as if this was
straight-forward, easy thing to do, but it may be quite the opposite. To
get a better idea of how to do "death" search the archives with that word.
Ken.
PS: We chose to do "simple death" because having all those dead bodies
lying around served as a reminder to the other agents. [grin]
BTW, if you do decide to do "simple death" in heatbugs then consider:
* what heat value do dead bugs have?
* do dead bugs occupy space?
* can a live bug and a dead bug occupy the same grid element?
* how do dead bugs effect the heatspace?
* do you end the simulation when all the bugs are dead? There are built-in methods for this as of Swarm 1.3. Previous techniques which drew on native X library functions are discouraged because they are not portable. Answer. If you have the Debugger version 4.16, there is an
Objective-C patch in the Swarm ftp archive. Start the debugger inside
a program like Emacs or by typing "gdp program_name" in an xterm.
A sample session was described by Benedikt Stefansson: You can now break on Objective C methods as in
(gdb) break [Classname Selector: withArg:andArg]
or stop the program and call methods do see what is going on as in:
(gdb) call [self someMethod: 12 withArg: 345] and if you say:
(gdb) break step
where step is a method found in more than one class, GDB will print
out all the different classes that have that method and ask you which one
you want to refer to.
------------------------- More on GNU debugger:
Question: When I start gdb (in xemacs or an xterm, actually), I get
these things that look like error messages:
Answer: The behavior you just described for GDB is perfectly normal.
If you have a binary installation of Swarm, GDB won't be able to find the
corresponding code for calls within the Swarm libraries, so for example
if you step into a List or Schedule you end up in a maze of "No such file
or directory" errors. I prefer the painless installation of the binary
to being able to step through Swarm libs - it is a tradeoff.
I find that the best solution is to use "next" instead of "step", unless
I want to step through my own code. So for example if there is a piece
of code in one of your agents that says for(x=0;x<10;x++) { y=[agent
getSomething] [[list atOffset: x] setSomethingElseTo: y]; }
once you enter the loop use next to step through the loop, and the call
to list will be silently executed without the annoying "No such file or
directory" message. Then if the [agent getSomething] call involves some
algorithms within the agents you want to step trough you can use step to
go into that part. Benedikt Stefansson benedikt@ucla.edu There are two approaches. The one I am recommending is this.
Learn how to pass command line arguments to your program and
run in batch mode. Use an external program to manage the
repetitions. I have used Drone and think it is good. Because
my windows users could not get Drone to work, I created a perl
script that can do the replication and parameter sweeps
(for an arbitrary number of variables). That is here:
http://lark.cc.ukans.edu/~pauljohn/Swarm/MySwarmCode/replicator.pl
I wrote up a little tutorial for Objective-C users who
want to pass command line
arguments and may also want to watch the
simultion in GUI mode. That is here:
http://lark.cc.ukans.edu/~pauljohn/ps909/Agent-Based_Models/simpleObserverBug3-6.tar.gz
In the words of Benedikt
Stefansson, who shared with me a Perl script he wrote called "loopy",
"Quite a few Swarmers for example have rolled their own Perl
scripts or used other methods to control parameter sweeps
in experiments, which may be more efficient than trying to do
the same from within Swarm
(for example it enables poor-man's-parallelism
on multiprocessor machines)."
The alternative is to write
your Swarm code to do it on its own. This requires
some care and attention
to memory management and a detailed knowledge of the activity mechanisms
inside Swarm. I have tried pretty hard at this, and found it
unrewarding. Consider this code (
http://lark.cc.ukans.edu/~pauljohn/Swarm/MySwarmCode/repeatingHeatbugsParameter-2.0.1x.tar.gz).
Alex Lancaster's email
discusses this approach and refers the reader to the tutorial exercise
"simpleExperBug." I personally don't recommend that approach. But I know
of at least one project that has succeeded with it. As soon as I get the
reference to Steve Railsback's code that does this, I will put the URL here. Swarm has nice features for creating lists of objects. Include the collections library in your header file, then create a list using the built-in object List:
To add items at the end of the list, use the command:
[aList addLast: anObject];
When you need to work with items in collections, there are handy things called "indexes". You tell your list object to create an index, then you can use loops to do things through the list. (Adapted from an email by Ken Cline, July 21, 1998)
These commands create an index called "exampleindex" on a list "aList".
Objects in a list can also carry out methods defined in the swarm library. (more info to come here when I find time)
If you want to clean out a list but leave the objects that it held unaffected, use [aList removeAll];
To delete objects in a list and then wipe them off the list itself, you can do this:
There is a built in function that does the same thing, but emails in the list on July 10, 1997 indicated some reluctance about them.
. [Original material written by Sven Thommesen, HTML finessing and
installation to FAQ manager done by
Alex Lancaster].
As of version 1.3, Swarm has a new 'movie-making' capability, which allows us to
save to disk bitmap snapshots of either the whole screen or of individual
on-screen widgets.
While the 1.3 version of Heatbugs demonstrates how to take a snapshot of
the whole screen (the "root window"), it does not show how to snapshot
individual widgets. (And there's an error in the Heatbugs code.)
Here follows a more extensive demonstration of how to take snapshots.
A basic method to snapshot the root window looks like this:
timeNow = getCurrentTime();
// Create a file name that contains the simulation time:
sprintf(filename,"zmovie.rootwindow.%04d.png", timeNow);
// Write the bitmap snapshot to disk:
pixId = [ [[[Pixmap createBegin: graphicZone]
setWidget: nil] // ('nil'=>root window)
createEnd]
save: filename];
// Release the memory used by the Pixmap object:
[pixId drop];
return self;
}
For other objects, we need to extract a pointer to the graphical widget:
theWidget = [theEZGraph getGraph];
theWidget = [theEZBin getHistogram];
theWidget = [actionCache getPanel];
Then use theWidget instead of 'nil' in the pixmap call:
timeNow = getCurrentTime();
// Create a file name that contains the simulation time:
sprintf(filename,"zmovie.nameofmywidget.%04d.png", timeNow);
// Write the bitmap snapshot to disk:
pixId = [ [[[Pixmap createBegin: graphicZone]
setWidget: theWidget]
createEnd]
save: filename];
// Release the memory used by the Pixmap object:
[pixId drop];
return self;
}
KNOWN LIMITATIONS under X-windows:
Partial solution: move the widgets you need to take snapshots of
to the window that will have focus before starting the simulation
run. Other possibility: have the -takeSnapshot method do nothing
for, say, t < 5, then after you start the sim quickly shift focus
to the window where your widget of choice is located.
KNOWN LIMITATIONS under Win-32 (95/98/NT):
(to be filled in later)
MAKING MOVIES OUT OF THE COLLECTED .png FILES:
This is quoted verbatim from a swarm-support
message by Marcus Daniels on 9/11/1998:
Here's the script I use (adapted slightly from a script from Nelson Minar).
You need the netpbm utilities, the fuzzy bitmap utilities, and pngtopnm.
Note the first argument is for fbm2fli. The typical use of this is to
specify the display area for the FLI movie.
#!/bin/bash
# make a .fli file from the given list of .png files
# requires pngtopnm, pnmtorast, fboctree, fbm2fli
# usage: png2fli "fbm2fli arguments" 0.png 1.png ...
fbm2fliparams="$1"
shift
list="$@"
output=output.fli
octdata=/tmp/octree.$$
giflist=/tmp/fbm2fli.$$
if [ -e $output ]; then
echo "$output already exists, you need to remove it."
exit 1;
fi
echo -n 'Building the octree data. '
for f in $list; do
base=${f%.png}
echo -n "$base "
pngtopnm $f | ppmtotga | tga2fbm | fboctree -a $octdata
done # 2> /dev/null
echo
echo -n 'Converting PNG files to 8 bit GIFs. '
for f in $list; do
base=${f%.png}
tmpbase=/tmp/$base
nf=${tmpbase}.$$.gif
echo -n "${base} "
pngtopnm $f | ppmtotga | tga2fbm | fboctree -G $octdata > $nf
echo $nf >> $giflist
done # 2> /dev/null
echo
echo "Creating $output from the GIFs"
fbm2fli $fbm2fliparams $giflist $output > /dev/null 2> /dev/null
echo "Cleaning up"
echo giflist: $giflist
rm `cat $giflist`
rm $giflist $octdata
exit 0;
1998-09-11 Sven Thommesen // ======================================================================
exit 0;
// (end quote)
1998-09-11 Sven Thommesen // ====================================================================== Marcus wrote a beautiful little essay about syntax changes/issues in scheduling with the createActionForEach approach
http://www.santafe.edu/projects/swarm/archive/list-archive.0009/0026.html Ted Belding tracked down problems in assuring identical performance across platforms:
http://www.santafe.edu/projects/swarm/archive/list-archive.9812/0012.html
and
http://www.santafe.edu/projects/swarm/archive/list-archive.9904/0201.html As of Swarm 2.0, there are 2 preferred methods:
1. Create data in HDF5 format, using a program such as R, (Swarm-sugarscape 2.0.0 has an example of this)
or
2. Use Lisp Archiver to read in data.
Read More about it in this note Marcus Daniels sent: http://www.santafe.edu/projects/swarm/archive/list-archive.9909/0079.html
Heatbugs-2.0.1 uses Lisp Archiver, so look it over. Also, you can see examples in the WorkingExampleCode section of the directory in which you find this FAQ.
Many people run into "gotchas" because they do not correctly format the
numbers in the .scm file. For example:
Note that Booleans are #t and #f whereas signed chars have syntax like #\001.
Marcus Daniels said "There are serialization methods on Discreted2d. E.g., if you create a
HDF5Archiver and save the Value2dDisplay Discrete2d with
putShallow:object:, you'll get a object that can be loaded into R and
shown as an image.
See tests/space/Discrete2d.m and Sugarscape for
example code. You can take a pixmap of a ZoomRaster display, but sometimes you want to save the underlying data. You can output the data in integer format if you use Swarm's Int2dFiler protocol. Here is a concrete example. Suppose you have a class that is subclassed from Discrete2d. Suppose you have objects in that grid, and each object is able to answer a message "getOutputValue". This must return an int! Then in your subclass of the Discrete2d, you can add a method like this:
[gridfiler fileTo: filename];
return self;
}
In your schedule, then you can add a message that causes the object to write its values to a file.
Then, in Matt's words:
"Once you have the data there are many ways of analysing it. One of the easiest is to
turn it into a pgm portablr grey map.
Add an ascii header to it as follows:
e.g., in my case:
Then give it a .pgm extension and open it in xv, gimp ..etc.
I also import the raw data into apps like GRI for contouring and postscript output for
LaTeX." aylward@geog.uwa.edu.au Marcus Daniels has been
posting small programs that can be used to test specific elements of
Swarm. These are typically one file of code along with a Local
Variables statement at the end that is recognized by Emacs as the
compile command. For example:
http://www.santafe.edu/projects/swarm/archive/list-archive.9903/0145.html
and there are others like:
http://www.santafe.edu/projects/swarm/archive/list-archive.9810/0034.html
or
http://www.santafe.edu/projects/swarm/archive/list-archive.9903/0013.html
There are many times that people want to test
specific little swarm things without the distraction of a whole big
program.
I'm collecting these things and posting them here:
http://www.ku.edu/~pauljohn/SwarmFaq/WorkingExampleCode/
I'm also posting
there an Obj-c "hello world" program that a friend at UCLA asked me to
look at (because it did not work as posted on DeKorte's Obj-C page).
The files that are tarred&gzipped are ones that I have tested and run
and can say with a straight face "these are provided to you without any
warranty of fitness or merchantability..." but they work. The ones that
are .txt are ones I've just copied out of Marcus's emails.
In Marcus's examples, he has the Local Variables for the solaris setup
at SFI. Not all examples are identical because his setup changes
sometimes, but an example is something like this:
/*
Local Variables:
compile-command: "/opt/egcs/bin/gcc -o x -g -Wno-import
-L/opt/SUNWtcl/sun4/lib -R/opt/SUNWtcl/sun4/lib
-L/opt/SDGblt/2.4g/lib -R/opt/SDGblt/2.4g/lib -L/opt/SDGlibffi/1.20/lib
-R/opt/SDGlibffi/1.20/lib
-L/opt/SDGswarm/1.4.1/lib -L/opt/SDGzlib/1.1.3/lib
-L/opt/SDGhdf5/1.0.1/lib -R/opt/SDGhdf5/1.0.1/lib -L/usr/local/X11/lib
-R/usr/local/X11/lib -L/usr/openwin/lib -R/usr/openwin/lib
-L/usr/local/lib -I/opt/SDGhdf5/1.0.1/lib
-I/opt/SDGswarm/1.4.1/include x.m -lsimtools -lsimtoolsgui -lactivity
-ltkobjc -lrandom -lobjectbase -ldefobj -lcollections
-lmisc -ltclobjc -ltk8.0 -ltcl8.0 -lBLT -lsocket -ldl -lnsl
-L/usr/openwin/lib -lhdf5 -lpng -lz -lXpm -lX11 -lffi -lm -lobjc
-lposix4"
End:
*/
I have a working "boilerplate" on my RedHat Linux system like this:
/*
Local Variables:
compile-command: "egcs -o pj1 main.m -g -fno-inline -L/usr/lib/swarm
-L/usr/lib -L/usr/X11R6/lib -I/usr/include/swarm -lanalysis -lsimtools
-lsimtoolsgui -lactivity -ltkobjc -lrandom -lobjectbase -ldefobj
-lspace -lanalysis -lsimtools -lsimtoolsgui -ltkobjc -ltclobjc
-lactivity -lrandom -lobjectbase -lcollections -ldefobj -lmisc -lBLT
-ltk8.0 -ltcl8.0 -lXpm -lpng -lhdf5 -lz -lffi -lX11 -lm -lobjc -lpthread
-ldl -Wl,--rpath -Wl,/usr/lib/swarm -Wl,--rpath -Wl,/usr/lib -Wl,--rpath
-Wl,/usr/X11R6/lib -Wl,--rpath -Wl,/usr/lib -Wl,--rpath -Wl,/usr/lib "
End:
*/
When Swarm 2.0 is released, a generic, portable Local Variables command will work, as in:
/*
Local Variables:
compile-command: "${SWARMHOME}/bin/libtool-swarm --mode=link gcc -o testapp -g
-Wno-import -I${SWARMHOME}/include -L${SWARMHOME}/lib testapp.m -lswarm -lobjc"
End:
*/
On RedHat linux, the following version of this works with Swarm 2.0:
/*
Local Variables:
compile-command: "$SWARMHOME/bin/libtool-swarm --mode=link gcc -D_GNU_SOURCE -o testapp -g -Wno-import -I$SWARMHOME/include -I$SWARMHOME/include/swarm -L$SWARMHOME/lib -L$SWARMHOME/lib/swarm testapp.m -lswarm -lobjc "
End:
*/ Question: My methods "getPosition" and "getCount" cause compiler problems. They say they conflict with other methods of the same name? But I don't have any other methods with those names. What gives?
Answer: There are "getPosition" and "getCount" methods elsewhere in the Swarm library, and the "namespace" allows their use only in one class or its descendants. You can't have "getCount" in your Classes at all, because that methods is used in the Swarm List class, and you can't subclass from that.
You need to rename your methods.
Question: But I am trying to subclass and override a method and the compiler still complains.
Answer: Objective C isn't polymorphic. If you want to override a method,
the argument and return types all should match up. That means you need exactly the same interface declarations!
Question:I created a new class called "Offer" and tried to use it in
the class that had manage:Offer. All hell broke loose, error
messages at compile time appeared in manage:Offer saying that
"anOffer" was undefined.
Answer:You can't have a class name in the method's name. Its as simple as that.
http://developer.apple.com/techpubs/macosxserver/System/Documentation/Developer/YellowBox/TasksAndConcepts/ObjectiveC/grammar.htm
compare grammar.htm#724, and #740-2.
Catherine Dibble wrote up an example of how to set a list of colors that are used in your EZGraph. Check Swarm-support acvhives (http://www.santafe.edu/projects/swarm//archive/index.html), March 9, 2000, for an email entitled "Re: setColors in EZGraph".
Here is the gist of it:
[snip];
happyGraph =
[EZGraph create: self
setTitle: "Happiness of Bugs vs. Time"
setAxisLabelsX: "Time" Y: "Happiness"
setWindowGeometryRecordName: "HappyGraph"];
[happyGraph setColors: ezgraphColors count: 5];
Swarm has libraries for neural networks and genetic algorithms in the contrib-eval category. They are contributed by people in the community but the Swarm team has evaluated them and says they are OK to use.
There are more recent libraries also contributed by other users that are in the anarchy category, which means they have not been officially evaluated.
You can find the links
to these things at the swarm archive,
http://www.swarm.org/community-contrib.html
GENETIC ALGORITHMS
THere is an older package called "Breeder" which can be compiled as a
library that links with Swarm programs. It has an application
example called IPD (iterated prisoner's dilemma). Breeder was
writtten by JJ Merelo during a time at the SFI. It
has quite a nice document about it, makes it look easy to apply
Breeder.
It is not crystal clear than anybody is responsible for development
of the Breeder library. The Swarm Development Group has been updating
and bug-fixing it, to go with swarm changes, but as far as I know nobody
has stepped forward to be the "orchestrator" of the package's
development.
There is another package for GAs called "GM" by Gianluigi Ferraris
Other items in this "suite" include:
CW - Gianluigi Ferraris has implemented this learning classifier
system which includes a workbench for running experiments.
There is a third package available from the U. of Michigan's web page. This is from a project overseen by Rick Riolo, who has ground-zero involvement with GAs. The classifier system for swarm, cfs-s, can be found here:
http://www.pscs.umich.edu/Software/CFS-S.html
NEURAL NETWORKS
The evaluated package is NeuroLib. Like Breeder, it is by JJ Merelo.
See the contributed package:
bp-ct - Pietro Terna's neural network approach
(illustrated in ct-hayek.tar.gz) and discussed in Pietro's
article in Luna & Stefannson's book, Economic Simulations in Swarm.
Question:I installed Swarm. Now what?
You need some sample programs to play with. On the SDG website, there
are various packages.
The classic Swarm apps have java versions, jheatbugs and jmousetrap.
Marcus Daniels wrote a tutorial about Java Swarm, and there is a
source code package for it called SDG. I'm not putting paths here,
since they might change. Generally, you can find them at http://www.swarm.org
or ftp://ftp.swarm.org/pub/swarm.
Question:I have a Java program. How do I compile it?
Answer:
Simplest route: unzip/untar your software in a directory. Open an x-termial. (On Windows,
open the "swarm terminal"). Then cd to the software directory,
then look at the files. If there is a Makefile, try typing "make" to see if it compiles.
If it doesn't, or has no Makefile, try "javacswarm *.java", and this
should compile all the java files.
If you are
using some kind of Java program builder/IDE, it is impossible for me to tell you what to do. You chose the builder, you find out how to use it!.
Question:I have managed to compile the program, but I am not sure of how to go
about running it ?
Answer:The canonical way to run Java Swarm models is using the "javaswarm"
script. In the case of jheatbugs and Windows you'd start up the
Swarm/terminal (under Start/Programs) and run the command "javaswarm
StartHeatbugs".
Some java programs do not have a separate class like "StartHeatbugs"
so you have to investigate. Find out which java file has the "main"
function in it. That is the file whose name must follow javaswarm on
the command line. (Don't forget your friendly grep program can find
main for you: type "grep main *.java".
For Visual Cafe, or whatever, you need to get the
swarm.jar in the CLASSPATH and javaswarm.dll in the PATH.
Run "javaswarm" by itself to see the details.
If you use third party Java libraries, you may need them in the classpath, as in:
It is an environment variable. In the Swarm/terminal, supposing ptolemy.plot.jar is in the current directory, you can set it with:
There is a big java Swarm Java reference API guide. http://www.swarm.org/release-docs.html. Please be careful if you go
looking in ftp for refbook-java, because you might find the source
code for the manual, which is XML markup computer-guy stuff, and what
you want instead is a processed, finished version of the document.
I mean, if you go here: For applications, look in In Swarm ftp (ftp://ftp.swarm.org/pub/swarm). We have regrouped so the apps/java directory makes it easy to see what there is. Please note that if you are using a newer than 2.1 version of Swarm, you need one of the jheatbugs and jmousetrap programs from the testing directory. Charles Staelin started writing a java adaptation of the regular Swarm tutorial. That's available various places, butwe suggest you join the group that is revising and updating thattutorial, or at least monitor their effort.Alex Lancaster recently posted: "I've migrated it from the old SourceForgelocation): http://savannah.gnu.org/cgi-bin/viewcvs/swarm/jtutorial/ Instructions on anonymous CVS check out are at: http://savannah.gnu.org/cvs/?group=swarm Gred Madey recently posted: http://www.cse.nd.edu/courses/cse498j/www/Resources/resources.html Hope this helps. Greg Madey Here's the question:
Where is the java source to swarm.jar? It would be nice to have all that stuff about Java Native Compilier (or
whatever it is) that magically turns the compiled objective C into compiled
Java classes for the swarm.jar.
Answer
You can see everything we have in the Swarm source code. Honestly. We are hiding nothing.
That aside, please understand this. We did not rewrite Swarm in java to make the Java layer work. Instead, we created a compatible interface so that the Objective-C classes & methods can be called from Java programs. This uses the Java Native Interface. There is code in the Swarm library that creates stubs through
which the java native interface is able to access the Objective-C methods.
In the words of Marcus Daniels, "There is a program that collects data structures representating the
interfaces described in the src/MODULE/MODULE.h protocol files. For
example, it instantiates types like "method", "variable", "function",
and those types have attributes like the required argument types,
names, documentation, etc.
These data structures can be converted to various forms. One form is
is the SGML DocBook that largely comprises the Objective C reference
manual.
Another form are the Java class declarations (which include the
Javadoc markup) that relate, for the Java virtual machine, Java
methods to the native-code Swarm library via the "native" Java method
attribute. These class declarations make up the swarm.jar file.
(There are a few more classes found in java/swarm in the Swarm source
tree.)" (swarm-support email, June 23, 2000) From the Swarm team, we have jheatbugs, jmousetrap and several small programs that have been presented in swarm-support email. Many/most/all of these small program examples are collected in http://www.ku.edu/~pauljohn/SwarmFaq/WorkingExampleCode/java. That's one I dumped into the memo directory:
http://www.ku.edu/~pauljohn/SwarmFaq/Memos/JavaNamingInSwarmLibs.txt
Marcus said, "The `gui' interfaces are available if you really want them, but
you need to rebuild Swarm from source with a few changes.¹
Instead, I would suggest you go to www.jars.com and search for "plot".
`ptplot' is one that I know works.
¹ The variable *removed-protocols* in java-stub.el (or interface.el
in the snapshot sources) is a list of all the protocols that are taken
out of the Swarm/Java layer. Simply remove the lines you want back and
do a new build/install." Please see this document: http://www.ku.edu/~pauljohn/SwarmFaq/Memos/SvenArgumentsNote.txt
The 5 example programs are in http://www.ku.edu/~pauljohn/SwarmFaq/WorkingExampleCode/java with the names
TestArgs-Example-N.txt, N={1,2,3,4,5}. Here's the way to run a Java model within GDB( "StartHeatbugs" is the program)
JAVASWARMGDB=gdb5 javaswarm StartHeatbugs
Windows users should get gdb5 from swarm ftp's 2.1.1-fixes directory, then do
JAVASWARMGDB=gdb5 javaswarm StartHeatbugs
FYI, with recent versions of GDB on Linux-based systems, jdk1.2.2 may
just lock up when you say "run". (I don't know why and haven't
investigated.) If that happens to you, you may be able to start up
your model, and *then* run gdb, using the `attach' feature of gdb get
control. To run jdb, you have to be able to run your program without using the
javaswarm script. (If your script is something different, say "jdkswarm",
then please read the following as if I'm talking about jdkswarm.)
Since that javaswarm script only servers the
purpose of setting some environment variables, you just need to set
those yourself.
On my system, I know where the CLASSPATH and LD_LIBRARY_PATHS need
to be, so I can just set those in the environment and then run
my program under jdb:
Note if you set those things in the environment, then you could run a
swarm program with
If your setup is more complicated, there is a way to automagically export those settings to
make sure they are correct for your system.
Type
If you want to just directly export those settings to your
current shell's environment (that's what most users will want),
add some graves around javaswarm, as in
Verify that the CLASSPATH and LD_LIBRARY_PATH have been added
to the environment by typing "env".
After you set the environment, you can run swarm programs with java
or you can run programs under jdb.
Please note the environment differs across operating systems. In Windows,
there is no LD_LIBRARY_PATH, just the PATH. The eval `javaswarm` statement
should generate the correct environment.
If you have trouble on Windows, all I can say is that we know of
some working cases. Marcus Daniels wrote:
"I just did this on Windows 2000:
Attempting to run debug (from JDE/Debub App) I obtain, in
the last emacs line, the message 'Searching for program: permission
denied, jdb'.
If you put this in your ~/.emacs_custom, it should work with JDK 1.3
with Windows 98 or 2000:
(custom-set-variables
'(jde-db-debugger (quote ("c:\\jdk1.3\\bin\\jdb" . "Executable")))
'(jde-db-set-initial-breakpoint nil))
Question: In the java version, Heatbug subclasses nothing and is thus a
plain java object, which knows nothing of zones. (Even though
SwarmObject seems to be part of the swarm-java api.)
Why this choice, and what are the ramifications?
Answer: Subclasses of Swarm things have Objective C counterparts, and are thus
require manual memory management. Whenever there are objects that
don't talk directly to Swarm (say instances doing GUI things), then
its cleaner and more portable to benefit from Java's garbage
collection.
However, when objects do talk to Swarm a lot, those that come and go
during a run should be subclassed, because otherwise pure Java objects
introduce Objective C proxies that will prevent the Java objects from
being dropped by garbage collection (they are added to the directory
that associates Java and Objective C objects). With subclassed Swarm
objects, the directory entries will be deleted when the object is sent
-drop. Directory entries and proxies go in globalZone. DS> Is there an analog in Java for the Canvas class in Obj-C? I've
DS> looked through the on-line docs for Java, and I can't find
DS> anything called Canvas.
Marcus Daniels said>
I kind of like Diva for such things.
http://www-cad.eecs.berkeley.edu/diva
http://www.santafe.edu/projects/swarm/archive/list-archive.9910/0225.html
The GUI interfaces of (Objective C) Swarm are deliberately hidden in
the released Java interfaces. To get them back, you can edit the
java-stub.el file in the source distribution and rebuild Swarm. There is an EZBin usage example in the WorkingExampleCode directory.
Histogram and most other direct uses of Tk things, are excluded from
the Swarm Java interface. You can put them back if you edit *removed-protocols*
in java-stub.el and then rebuild Swarm from source.
These features are removed because there are Java alternatives, e.g.:
http://ptolemy.eecs.berkeley.edu/java/ptplot
Here is a Swarm Example usage!
ftp://ftp.swarm.org/pub/swarm/src/users-contrib/anarchy/jipd-grid-0.0.1.tar.gz
uses ptplot. (The relevant file is StrategyGrapher.java.) $ jdkswarm -prof FooBar
..then look at java.prof. You'll find the leak in a zone or in the multi-language directory.
To look at the former, you can use a call like:
Globals.env.globalZone.xprint ();
(or xfprint)
Suppose your program uses more and more memory.
Marcus Daniels said, "To look at the directory, you can use:
Globals.env.dumpDirectory ();
If the leak is in the latter, the easiest thing is usually to structure
the model so that objects in the population(s) are never literally handed
to Swarm calls. Marcus wrote 9-15-2000, "Here is an example that saves a single object to a .scm and .hdf file.
The first time you run it you should see "null" twice, because it is
trying to load the yet-to-be-created object from these two sources.
The second time you run it, it will have written the objects to the
.scm and .hdf files, and so you should see Item@POINTER.
The item.scm file should look like this:
class Item {
public boolean a;
public int b;
public float c;
public double d;
Item () { }
Item (boolean a, int b, float c, double d) {
this.a = a;
this.b = b;
this.c = c;
this.d = d;
}
}
public class ArchivedItem {
Item item;
public ArchivedItem () {
super ();
item = new Item (true, 1, 2.0f, 3.0);
}
void test (Archiver archiver) {
System.out.println (archiver.getObject ("item"));
archiver.putShallow$object ("item", item);
archiver.sync ();
}
static void main (String args[]) {
Globals.env.initSwarm ("ArchivedItem", "0.0",
"bug-swarm@santafe.edu", args);
Zone aZone = Globals.env.globalZone;
ArchivedItem item = new ArchivedItem ();
item.test (new HDF5ArchiverImpl (aZone, "item.hdf"));
item.test (new LispArchiverImpl (aZone, "item.scm"));
}
}
Mailing List answer:
http://www.santafe.edu/projects/swarm//archive/list-archive.0004/0011 .html
None of the commercial alternative modeling environments are advertised here. In the July 24th, 1998 issue of the
Wall Street Journal, an article appeared
with excerpts of an interview with Chris Langton. The article
mentions Swarm and some brief history of Swarm, and also describes
Chris' new company, the Swarm
Corporation and some recent work with Sun Microsystems project JINI.
There's a posting on the mailing list with the HTML of the article:
http://www.santafe.edu/projects/swarm/archive/list-archive.9807/0322.html
John Eikenberry's AI/ALife mini-howto. John just notified me that the new address of his siteis:
http://zhar.net/gnu-linux/howto/
Its also available from the Linux Documentation Project under the HOWTOs
(it is now a regular HOWTO, not a mini-howto).
http://www.linuxdoc.org/HOWTO/AI-Alife-HOWTO.html
Just when I see them, this is not supposed to be exhaustive:
Leigh Tesfatsion, ISU, "Computational Economics" Page
http://www.econ.iastate.edu/tesfatsi/ace.htm
Brookings on Agent-Based Models
http://www.brook.edu/ES/dynamics/models/history.htm Business Week 26 Feb 96 p75: ARTIFICIAL-LIFE SIMULATION SOFTWARE
Software developed at New Mexico's Santa Fe Institute uses 3-D satellite
maps of a geographical region and software "agents" that model such variables
as weather and crop yields to study why an ancient Native American culture
collapsed suddenly in the 12th century. The artificial-life simulation
software, called Swarm, produces a generic modeling tool for studying ecological
systems, economic theories and other complex systems. (Business Week 26
Feb 96 p75) Faq_Manager 2.02 has been installed, which prompts for the author's name, an email address, and it also seems to slip in a cookie that recognizes an individual to the manager. Cool!
As of May 10, 1998, the script setup has been set to remember the original author's name forever! People who edit items created by others are asked to include their name and address.
As of July 2, 1998, the previous statement is false. Faq_manager shows the name of the person who most recently edited the item. I'm looking for fixes on that.
PJ: July 13. I'm testing a fix that freezes in place the author's name.
6.3 Seg Fault due to improper format in .scm file
(08/03/2000 Paul Johnson <pauljohn@ukans.edu>)
6.4 lispArchiver runtime error
(06/05/2000 Paul Johnson <pauljohn@ukans.edu>)
*** event raised for error: InvalidArgument
*** function: _i_LispArchiver_c_lispLoadArchiver_(), file: LispArchiver.m, line
174
argument ot Archiver lispIn not a list*** execution terminating due to error
Symbol.m:173 -[Error(c) _raiseEvent:]
Aborted (core dumped)
*** event raised for error: InvalidArgument
*** function: _i_InputStream_c__getExpr(), file: /usr/local/src/redhat/BUILD/swarm-2.1.1.20000627/src/collections/InputStream.m, line: 265
cons accepts only two arguments*** execution terminating due to error
/usr/local/src/redhat/BUILD/swarm-2.1.1.20000627/src/defobj/Symbol.m:173 -[Error(c) _raiseEvent:]
Aborted (core dumped)
6.5 My program is slow. What do I do?
(03/07/2000 Paul E. Johnson <pauljohn@ukans.edu>)
6.6 I can't seem to set parameter in a probe window.
(22/05/2000 Paul Johnson <pauljohn@ukans.edu>)
7 Intermediate: Language Construct Questions, programmingtips, etc
7.1 Managing Makefiles: Suppose I change the code. What about changing the Makefile?
(12/07/2002 Paul Johnson <pauljohn@ku.edu>)
It is necessary to add this in the list of files toward the end:
MyObject.o: MyObject.m MyObject.h
7.2 Naming Conventions: Why do
you have some BIG letters and some small letters in your code?
(09/05/98 Ken Cline <kcline@c3i.saic.com>)
7.3 Create, CreateBegin: Which, when, why?
(13/07/98 Paul E. Johnson <pauljohn@ukans.edu>)
7.4 What does initSwarm do in main.m
(10/02/2000 Paul Johnson <pauljohn@ukans.edu>)
initModule (activity);
initDefobj (argc, argv,
appName, version, bugAddress,
argumentsClass,
options, optionFunc,
inhibitExecutableSearchFlag);
initProbing ();
if (![arguments getBatchModeFlag] && !forceBatchMode)
swarmGUIMode = YES;
initRandom (arguments);
if (swarmGUIMode)
initSimtoolsGUI ();
arguments (a class that handles command line arguments)
lispArchiver (stores data from many programs in ~/.swarmArchiver )
lispAppArchiver (stores data about
a single application in a application-specific location.)
[look in swarm-support Feb.10, 2000 for more from Marcus on this].
for people that have hdf5, a data file format program:
hdf5Archiver (nonapplication specific storage tools )
hdf5AppArchiver (application specific storage)
probeLibrary (a global record keeper for probes)
randomGenerator : default MT gives integers that "drive" the random
distribution drawing objects listed next
uniformIntRand integer distribution
uniformUnsRand unsigned integer distribution
uniformDblRand double distribution
probeDisplayManager (When ProbeDisplays are created, they are registered here so that the
the ObserverSwarm can request them all to be updated at once.)
7.5 Pointers to ids (which are
pointers already!). That's confusing
(09/05/98 Ken Cline <kcline@c3i.saic.com>)
7.6 Why did Swarm change from Classes to Protocols?
(09/02/2000 Paul Johnson <pauljohn@ukans.edu>)
ProbeMap * probeMap
but now we write
id <ProbeMap >probeMap
7.7 Is it OK to cast floats as
ints?
(09/05/98 ? <?>)
7.8 Trouble with M():: notation
and Observer/ModelSwarm design.
(11/06/98 Paul Johnson <pauljohn@ukans.edu>)
7.9 Even more complaining about
the requirement that arguments be id type.
(11/06/98 Paul Johnson <pauljohn@ukans.edu>)
7.10 The Problem of Passing Multi
Valued items between objects
(11/06/98 Paul Johnson <pauljohn@ukans.edu>)
7.11 How can I: create a class if I have a string representing the class name?
(06/05/2000 Paul Johnson <pauljohn@ukans.edu>)
7.12 How can I: copy agents?
(31/07/98 Paul Johnson <pauljohn@ukans.edu>)
theJones=[List create: [self getZone]];
----insert stuff defining the list----
newJonesList=[theJones copy: [self getZone]];
- copy: aZone
{
return [aZone copyIVars: self];
}
7.13 How can I: Ask objects what
class they are created from?
(31/07/98 Paul Johnson <pauljohn@ukans.edu>)
7.14 How Can I: get a selector
from the name of the method?
(11/06/98 Paul Johnson <pauljohn@ukans.edu>)
Ginger Booth
7.15 How Can I: Save Window Geometry?
(20/05/98 ? <?>)
Marcus G. Daniels <mgd@santafe.edu>
if (swarmGUIMode == 1)
{
// We've got graphics, so make a full ObserverSwarm to get GUI objects
theTopLevelSwarm = [HeatbugObserverSwarm createBegin: globalZone];
SET_WINDOW_GEOMETRY_RECORD_NAME (theTopLevelSwarm);
theTopLevelSwarm = [theTopLevelSwarm createEnd];
}
CREATE_ARCHIVED_PROBE_DISPLAY (heatbugModelSwarm);
CREATE_ARCHIVED_PROBE_DISPLAY (self)
Then for Heatworld, use the SET_WINDOW_GEOMETRY_RECORD_NAME macro.
SET_WINDOW_GEOMETRY_RECORD_NAME (worldRaster);
worldRaster = [worldRaster createEnd];
unhappyGraph = [EZGraph createBegin: [self getZone]];
[unhappyGraph enableDestroyNotification: self
notificationMethod: @selector (_unhappyGraphDeath_:)];
SET_WINDOW_GEOMETRY_RECORD_NAME (unhappyGraph);
[unhappyGraph setTitle: "Unhappiness of bugs vs. time"];
[unhappyGraph setAxisLabelsX: "time" Y: "unhappiness"];
unhappyGraph = [unhappyGraph createEnd];
CREATE_ARCHIVED_PROBE_DISPLAY (heatbugModelSwarm);
CREATE_ARCHIVED_PROBE_DISPLAY (self);
[probeDisplayManager createProbeDisplayFor: heatbugModelSwarm];
[probeDisplayManager createProbeDisplayFor: self];
7.16 How Can I: find out what
the "internal time" of the model is?
(09/05/98 ? <?>)
7.17 How Do I: Create Globally Visible Objects
(11/06/98 Paul Johnson <pauljohn@ukans.edu>)
7.18 How do I: Use Random Number
Generators?
(12/08/98 ? <?>)
aNormalDist = [NormalDist create: [self getZone]
setGenerator: randomGenerator setMean: 0
setVariance: 1] ;
If you create many distribution objects in many files, then they will all
be drawing random numbers from the default "randomGenerator." Some people
in the mailing list think (emphatically) that is the best way to go.
[randomGenerator setStateFromSeed: randomSeed];
Put that BEFORE you create your variable. Note, you have to either put an integer in place of the word "randomSeed" or define and initialize an integer "randomSeed.""
char seedBuff[32];
if ( seed == 0 )
{ seed = getpid()*time(0); sprintf(seedBuff,"%u",seed);
[self setParameterName: "seed" ToValue: seedBuff]; }
randomGeneratorR = [PMMLCG1 create: globalZone setStateFromSeed:
seed];
uniformUR = [UniformUnsigned create: globalZone setGenerator:
randomGeneratorR];
//... and so on for any other distributions I want. }
Rick Riolo
7.19 How do I manage birthing
and killing of agents?
(09/05/98 ? <?>)
7.20 How do I draw a line in aRaster object?
(17/10/98 Paul Johnson <pauljohn@ukans.edu>)
7.21 How do I use the GNU Debugger
(09/05/98 ? <?>)
warning: Unable to find dynamic linker breakpoint
function.
warning: GDB will be unable to debug shared library initializers
warning: and track explicitly loaded dynamic code.
7.22 How do I do multiple runs and parameter sweeps?
(10/09/2001 Paul Johnson <pauljohn@ukans.edu>)
7.23 How Do I: Work with Lists
(23/07/98 Paul Johnson <pauljohn@ukans.edu>)
id aList;
aList = [List create: [self getZone]];
id
This example contains some extra detail. You could just write "while([anObject next])" as people often do. This says do something while the next object in the index does not return a "false". Including the NULL portion adds some safety on some architectures. Add the variable name "anObject" gives you something to refer to inside your {}. For example, you could put things like [anObject setValueX: 4] or whatever methods you have built for the object. If you don't have anObject, you can put [anIndex get] inside the brackets to retrieve an object that the index is currently pointing to.
[aList forEach: M(drop)];
[aList removeAll];
7.24 How do I: Use the Swarm widget snapshot ('movie-making') facility?
(05/11/98 Sven Thommesen <sthomme@humsci.auburn.edu>)
-takeSnapshotOfRoot
{
char filename[40];
unsigned timeNow;
id pixId;
If we want to take snapshots of a specific widget, we replace
'nil' in the example above with the id of the widget.
// When creating the probe display, save the reference:
tempID = CREATE_ARCHIVED_PROBE_DISPLAY(modelSwarm);
// Then get the widget pointer:
theWidget = [tempID getTopLevel];
-takeSnapshotOfSomeWidget: (id
// (end quote)
7.25 CreateActionForEachHomogeneous Usage and "Speed" in list processing (Swarm 1.2+)
(08/12/2000 Paul Johnson <pauljohn@ukans.edu>)
7.26 How Can I: Assure Comparability of Results Across Platforms?
(28/06/99 Paul Johnson <pauljohn@ukans.edu>)
7.27 How can I Input Data Into a Simulation?
(14/09/2001 Paul Johnson <pauljohn@ukans.edu>)
the syntax for a float is #:myFloat 0.10F0
the syntax for a double is #:myDouble 0.10D0.
the syntax for a boolean is #:myBooleanVar #t"
See http://www.swiss.ai.mit.edu/~jaffer/r5rs_8.html#SEC58
7.28 Use R and hdf5 to get data into Swarm
(18/01/100 Paul Johnson <pauljohn@ukans.edu>)
7.29 How can I: Save data values from grid2d objects?
(15/09/99 Paul Johnson <pauljohn@ukans.edu>)
-writeValuesToFile
{
id gridfiler;
char * filename;
asprintf(&filename, "%05dWrappedGrid.txt", getCurrentTime());
gridfiler=[Int2dFiler createBegin: [self getZone]];
[gridfiler setDiscrete2dToFile: self];
[gridfiler setValueMessage: M(getOutputValue)];
gridfiler=[gridfiler createEnd];
P2
x_size y_size
max_value
.........int ascii data here.....
P2
200 200
10
7.30 How Can I: Make small test programs to explore Swarm Specifics
(18/01/100 Paul Johnson <pauljohn@ukans.edu>)
7.31 Name Space Conflicts (or Polymorphism in Swarm? No!)
(15/03/2000 Paul Johnson <pauljohn@ukans.edu>)
7.32 How Can I: Control Colors in an EZGraph
(09/06/2000 Paul Johnson <pauljohn@ukans.edu>)
-buildObjects
{
[snip]
static const char * ezgraphColors[5] =
{"black", "green", "red", "yellow", "blue"};
Then the lines you add will have those colors, in that order.
7.33 How can I use Artificial Intelligence in Swarm?
(08/12/2000 Paul Johnson <pauljohn@ukans.edu>)
8 Java-specific Material
8.1 How to run/compile Swarm Java apps?
(21/02/2001 Paul Johnson <pauljohn@ukans.edu>)
$ export CLASSPATH=ptolemy.plot.jar:$CLASSPATH
Don't put these in a permanent place like .bash_custom or the
Windows registry. If you do, you need to use an absolute path to the jar file.
[top]
8.2 Where is the Java documentation and tutorial?
(15/08/2002 Paul Johnson <pauljohn@ku.edu>)
ftp://ftp.swarm.org/pub/swarm/docs/swarmdocs-2.1/
you probably want to download something like :
ftp://ftp.swarm.org/pub/swarm/docs/swarmdocs-2.1/refbook-2.1-html.tar.gz
or the compiled refbook in some other format, say postscript.
You probably DO NOT want the docs under /pub/swarm/src/doc
To support a course I taught this past semester using Java/Swarm, Icollected a number of links to useful resources. They can be found at:
8.3 Where is your Java code that makes Swarm Java classes?
(26/06/2000 Paul Johnson <pauljohn@ukans.edu>)
8.4 Where are the Swarm Java examples
(26/06/2000 Paul Johnson <pauljohn@ukans.edu>)
8.5 Explain the C, S, and CImpl terminology
(08/09/2002 Paul Johnson <pauljohn@ku.edu>)
8.6 Which Protocols are not available in Swarm Java?
(08/12/2000 Paul Johnson <pauljohn@ukans.edu>)
8.7 How can I: Process command line arguments and use them in Swarm programs.
(10/07/2001 Sven Thommesen <sthomme@swarm.org>)
8.8 Using GDB with Java Swarm Models
(03/10/2000 Paul Johnson <pauljohn@ukans.edu>)
8.9 How to use jdb, the Java debugger
(23/07/2001 Paul Johnson <pauljohn@ukans.edu>)
$ export CLASSPATH=/usr/share/swarm/swarm.jar:/usr/share/swarm/kawa.jar:$CLASSPATH
$ export LD_LIBRARY_PATH=/usr/lib/swarm:$LD_LIBRARY_PATH
$ jdb MY_JAVA_PROGRAM
$ java MY_JAVA_PROGRAM
$ eval javaswarm
and watch as it dumps out a listing of the environment variables that are right for your system. You can copy those and use them however you want.
$ eval `javaswarm`
$ export
CLASSPATH='.;I:\Swarm-2.1.1\share\swarm\swarm.jar;I:\Swarm-2.1.1\share\swarm\kawa.jar'
$ export PATH=//I/jdk1.3.0_01/bin:$PATH
$ jdb StartHeatbugs
> run
8.10 Make the Emacs/JDE Debugger interface work
(10/07/2001 Sven Thommesen <sthomme@swarm.org>)
(setq *use-jdk* t)
8.11 Which Java Objects Should be Subclassed from Swarm?
(11/01/100 Paul Johnson <pauljohn@ukans.edu>)
8.12 How can I: Use Canvas objects in Java Swarm
(24/05/2000 Paul Johnson <pauljohn@ukans.edu>)
8.13 How can I: Get histograms and graphs in Java Swarm?
(08/12/2000 Paul Johnson <pauljohn@ukans.edu>)
8.14 Profile a Java Swarm app
(08/12/2000 Paul Johnson <pauljohn@ukans.edu>)
8.15 Find Memory Leak in multi-language app
(10/07/2001 Sven Thommesen <sthomme@swarm.org>)
8.16 LispAppArchiver Usage
(08/12/2000 Paul Johnson <pauljohn@ukans.edu>)
(list
(cons 'item
(make-instance 'Item #:a #t #:b 1 #:c 2.000000F0 #:d 3.000000D0)))
The HDF5 file should be loadable like so:
$ R
> library(hdf5)
> hdf5load("item.hdf")
It will be stored as the "item" variable":
> item
a b c d
item TRUE 1 2 3
Here's the code:
import swarm.Globals;
import swarm.defobj.HDF5ArchiverImpl;
import swarm.defobj.LispArchiverImpl;
import swarm.defobj.Archiver;
import swarm.defobj.Zone;
8.17 JBuilder: How do I use it?
(19/06/2000 ? <?>)
9 Modeling Strategy: Swarm and Other Approaches
9.1 What are the other Free, Open-Source Modeling tools?
(10/27/2003 Paul Johnson <pauljohn@ku.edu>)
MASON is a joint effort between George Mason University's ECLabEvolutionary Computation Laboratory and the GMU Center for SocialComplexity , and was designed by Sean Luke, Gabriel Catalin Balan, andLiviu Panait , with help from Claudio Cioffi-Revilla, Sean Paus, Daniel Kuebrich, and Keith Sullivan .
10 Items of Interest
10.1 Wall Street Journal on Chris Langton and Swarm
(31/07/98 Alex Lancaster <alex@santafe.edu>)
10.2 The Artificial Life FAQ
(23/11/99 Paul Johnson <pauljohn@ukans.edu>)
10.3 Cool Agent-based Modeling Sites
(05/02/2000 Paul Johnson <pauljohn@ukans.edu>)
10.4 Business Week on Swarm
(09/05/98 ? <?>)
10.5 Faq_Manager has been updated!
(13/07/98 Stas <stas@stas.com>)