Big Ideas


June 19, 2008: 1:41 pm: Big Ideas, Cognitive Modeling, jACT-R

As usual after a day of writing, I needed to take a break. I decided to watch an old webinar on the Eclipse communications project. Why does a psychologist/roboticist care about a platform specific communications system? Aside from the possibilities of leveraging others work on shared editing, or even chat/IM within the IDE (great for contacting me if you’ve got a question), it also opens the door to more effective distributed model execution.

As cognitive modelers we routinely have to run thousands of model iterations in order to collect enough data to do effective quantitative fits. For simple models, the time cost is negligible, but larger models can serious tax computation resources for quite sometime. My dissertation experiments lasted around two hours, and the model runs took almost 15 minutes per simulated subject. Given the parameter space I had to explore, it was common for my machine to be bogged down for days on end. My solution at the time was to VNC into other machines in the lab, update the model from SVN, then run a set of parameters. Not the most effective distribution mechanism.

Wouldn’t it be better if you could do all this from the IDE without any hassle? Imagine if you could specify the bulk model executions and then farm it out to a set of machines without any heavy lifting or sacrificing your processor cycles. The combination of OSGi bundles (which all jACT-R models are), Eclipse’s PDE, and ECF makes this possibility a very near reality (p2 will definitely help too as it will make enforcing consistent bundle states much easier).

After watching the webinar I couldn’t resist and started building the pieces. Here’s how the bad-boy will work:

  1. define the run configuration for the iterative model run
  2. then select the remote tab which will list all the discovered service capable of accepting the model run (pruned based on dependencies of your model)
  3. the model and all its dependencies is exported to a zip file and sent to the remote service
  4. the remote service unpacks, imports and compiles the content (ensuring that all the deps are met and your code will actually run) – it then executes the run configuration
  5. as the execution progresses, the service transmits the state information back to your IDE (i.e. iteration #, ETA, etc)
  6. when all is done, it packages up the working directory that the model was run in and sends it back
  7. this is then expanded into your runs/ directory as if you had executed the bulk run yourself.

This is actually a sloppy implementation of a more general functionality that Eclipse might find useful: transmitting local bundles and invoking them on a remote system.

I’ve got a weekend away from distractions coming up and I think I can get a rough implementation working by then. This will certainly make the bulk monkey runs go so much easier (remote desktop is usable but really just too much of a hassle). Of course, I could use that time to work on the spatial modeling instead.. but that’s too much like real work for a weekend.

April 9, 2008: 3:30 pm: Big Ideas

First off, I’m not talking distributed representations, no, this is entirely about implementation.

While the community is still some ways off from needing something like this, in the future many of us will be running models across much longer time-spans, both simulated and real. These models are going to seriously tax the underlying implementations. Currently jACT-R has no problems with chunk counts in the hundreds of thousands, but millions? And what about productions? Most hand-coded models don’t exceed a few dozen productions, but with production compilation enabled for a long period in dynamic environments, it’s easy to envision scenarios where the production counts will be on par with the chunks.

This scenario is rapidly approaching for us working with robots operating over anything but the most trivial time scales.

The big information companies out there manage this volume of information easily with existing database systems. Why should the ACT-R implementations have to manage their own information searches, linkages and retrievals when there are specially tailored systems that can do it so much better?

Imagine if all chunks, types and productions were backed by something like MySQL. ACT-R could be freed to maintain only the most active subset of procedural and declarative memory, while less active information would be managed by the database. This scenario carries with it a slew of useful benefits.

Scalability

The most obvious benefit of database backing would be in scalability. Database systems are designed to handle data quantities well beyond what we have attempted to this point, but quantities that are certainly within the realm of those required by long running models. By limiting ACT-R to only the immediately relevant information set, the architecture would require significantly fewer resources that could be better leveraged elsewhere.

This information subset could be intelligently managed using information we already have available. As the chunks in a buffer are changed, relevant chunks could be prefetched by following the associative links. The declarative subset would effectively be managed through the activation levels. Similarly, productions could be prefetched based on the chunktypes of the chunks currently in declarative memory. As the chunks and productions are deemed to be no longer relevant, they can be committed back to the database system (if changed) or discarded outright.

Persistence

Obviously, anything stored in a database is persisted. This gives us the ability to created bootstrapped models. I can’t count the number of times I’ve heard researchers wish they could have preexisting models of some user group. This scheme would allow us to have specific databases of different population types and knowledge. With access restrictions, we could even set up domain specific databases (i.e. mathematics knowledge) and constrain what any connected model could access (i.e. up to and including algebra education). This applies to declarative and procedural knowledge equally.

With some neat use of caching database systems, you could set up a centralized immutable system with a common knowledge base, accessed by each lab’s local database system which is accessed by all the researchers, who themselves have a local system running with write privileges for their respective models. Similarly, there is no reason that any one model would be tied to only one database system. Need a model of a high-school senior who plays video games? Point the model to an aggregating database that provides access to separate high-school level knowledge bases and then point it to a video game specific database.

Performance

Much of the scalability benefits are directly relevant to performance. What’s really nice about having multiple database systems is that the architecture could make multiple simultaneous search requests to all the databases and harvest the first result. With network latencies decreasing every year, it’s not unreasonable to expect that infrequently used information would still be accessible faster than realtime.

But how?

I can’t speak towards how one would implement such a scheme in Lisp. The lack of real threading across most implementations makes this a challenge. In jACT-R this would be relatively simple (it’s still one heck of an undertaking).

For maximum performance you’d want the system to engage in asynchronous management of the relevant information subset. Fortunately, both the procedural and declarative modules already support asynchronous modes of operation. Each would attach listeners to the buffers (for chunk additions and removals) as well as to the chunks in the buffers (to catch any changes). All the chunks associated with these active chunks could then be prefetched. Similarly, their chunk-types would be used to prefetch the productions that depend upon those chunk-types.

Since all major entities (types, chunks, productions) are represented as handles, the system can create and return these handles before the contents have been fully received and recreated from the databases. This allows the architecture to work with the chunks and productions before they are actually available, further exploiting the asynchronies. (Obviously, if the chunk or production’s contents need to be accessed, the system will block until that data is available).

While this prefetch mechanism would work well for information directly connected (through some depth), it doesn’t address the retrieval of information specified at runtime by productions. Fortunately, the retrieval module relies upon the synchrony of the declarative module. It would merely make a request from the database and immediately return a handle to a chunk. If no result is received within a specified window of time (or an empty response returned), the declarative module would just redirect the handle to point to the standard error chunk.

As chunks and productions become irrelevant, they can be checked for any parameter changes. Any changes can then be sent back to the database for persistence. Newly created chunks would be handled in the same way, only committing when the chunk is deemed to be contextually irrelevant. Fortunately, Java already supports a mechanism to keep track of object references, so other modules would still be able to prefetch information and retain it indefinitely without fear of it being reclaimed.

jACT-R already has a simple format that is easily persisted and searched in databases, and is already used to transmit information in an agnostic manner across the network: the ASTs used to bi-directionally translate between source and model.

In theory, all of this could be accomplished by extending the default implementations of the declarative and procedural modules, with custom implementations of the chunk, type and production handles (to notify the modules when they are no longer relevant).

Will this idea ever see the light of day? I sure as hell hope so. Is it anywhere on my horizon? Nope. Little old me still needs to bump up the pub count.

: 2:21 pm: Big Ideas

For the past few days I’ve been working on implementing the movement tolerance handling in the visual system (and aural, configural, manipulative), and I’m really tired of it right now. It was supposed to have been easier than this (hell, it should have been done last week) – but it ultimately required some significant refactoring of the asynchronous caching of afferent chunk encodings. Total headache.

Now as I’m getting to the final tidbits, I’m incredibly bored with it. Add to that the fact that I prefer my code to be readable, twice now I’ve refactored what I’ve already done. It will be done this week..

..but for a distraction, I’ve added a new category to document some of the crazy cool ideas I’ve been playing with in the back of my head. There are some that I converse with who believe these ideas should be held close to the chest until I can get prototypes assembled, but I’d rather throw them out there, see if they have any resonance with folks and to get some additional feedback.

Without further ado