Friday, March 07, 2008

Desktop software is hard, eh Google?

Blackberry curve image
I was excited to hear about Google Calendar Sync. I got a Blackberry Curve last week, and I've been playing around with the best way to get both my personal (Google) and business (Outlook) calendars sync'd with it.

We don't use Blackberry Enterprise Server, so the Outlook syncing seemed to be a bit spotty. It got some events over the air (maybe the ones for which I was e-mailed invitations), but didn't get all of them. If I plugged it in and used Blackberry Desktop Manager it worked fine -- but I didn't want to have to plug it in.

But with the Google Sync download for my phone, it started grabbing my Google Calendar items with no problem.

Google Calendar Sync seems like it's an ideal solution for me: it can keep my Outlook calendar in sync with a Google Calendar, and my phone can grab those events directly from Google over the internet. Fantastic!

Google Calendar Sync supports Microsoft Outlook 2003 and 2007 onlySo I headed over to Google, downloaded the software, and ran the install. And this is what I see: "Google Calendar Sync supports Microsoft Outlook 2003 and 2007 only"

Now, this is a brand new laptop that has only ever had Outlook 2007 on it. It's never been uninstalled, reinstalled, or anything hinky. Should be pretty vanilla.

What's worse is that there's nothing I can do. No setup pages to look at, no documentation to read. I guess I'm just SOL.

Has anyone else seen this? And more importantly: has anyone else solved this?

Technorati tags: ,

Tuesday, March 04, 2008

Where Was HPC?


Nathan Trueblood, John Powers, and I went to the Windows Server 2008 launch last week (of course, we had to show off our shiny new Certified for Server 2008 logo).

It was surprisingly well attended (and I wasn't the only one who was surprised; apparently the catering staff was as well. In the continuing battle of Microsoft vs. Ciruli on the lunch front, I lost -- no lunch for me. How hard is it to count attendees at an event that requires pre-registration??).

Anyway, there were thousands of people there. We had hundreds walking around with the cool-looking Digipede stickers, and one lucky sticker-wearer went home with an XBox.

With a triple-product launch, Microsoft had an enormous contingent there, both attending and demonstrating. In the Microsoft pavilion, they had 30 booths -- most of them centered around Server 2008. Many of those booths weren't for products that were launching: SharePoint Server was there, Microsoft Forefront, Exchange Server. Many of the booths were related to Server 2008: Hyper-V, File and Storage Solutions for Server 2008, Scalability with Server 2008.

But you know what had no mention at all? HPC Server 2008.

It was conspicuous in its absence.

Now, HPC Server 2008 won't be out for months...then again, neither will SQL Server 2008 and it was launched at this event.

So, what's the deal? While I think HPC Server 2008 will go far beyond what Windows Server 2003 CCE did (both in terms of capabilities and sales), missing an event like this shows that Microsoft still isn't thinking of the server market as a continuum. They're dividing server users into HPC (high performance computing) and what may as well be called LPC (low performance computing).

In reality, of course, there's no strict division. It's a continuum. And Microsoft should be doing everything it can to bridge the gap between HPC and "the rest of us." As Jim Gray used to refer to it: Indoor Computing. It runs the gamut.

I guess the HPC crew are huddled in Redmond, preparing for their release later this year...too bad they couldn't find the time to market to the thousands of Windows Server fans who gathered in LA last week.

Tuesday, February 26, 2008

Win an XBox 360 from Digipede at Server 2008 Launch

Wear and WinAre you going to the Windows Server 2008 / Visual Studio 2008 / SQL Server 2008 global launch in LA tomorrow?

If you'll be there, stop by the Digipede kiosk in the Partner Pavilion and pick up a nifty sticker...and it could win you an XBox 360!

The stickers are cool -- they feature Deatle, our lovable, binary mascot. And if we see you wearing one in the afternoon break, you could end up going home with an XBox 360.

See you there...

Wednesday, February 20, 2008

How Does Your Grid Help Your Multicore Problem?


One of the benefits of Digipede's object oriented programming model is the ease with which it lets you take advantage of the multiprocessor and multicore machines on your grid. The Digipede Agent knows how many cores are on each box, and it can execute work accordingly, taking advantage of the individual cores without forcing the developer to do multithreaded programming.

We've been talking about this for a while, but John Powers made a short video that makes it crystal clear.

Check it out...

Technorati tags: ,

Thursday, February 14, 2008

Worst .NET Bug I've Ever Seen

Question: What exception(s) will this code produce? And why?

while (true) {
   using (Stream sw = File.Open(strFileName, FileMode.Create)) {
         using (BinaryWriter bw = new BinaryWriter(sw)) {
            BinaryFormatter bf = new BinaryFormatter();
            bf.Serialize(bw.BaseStream, this);
         }
   }
}


Answer: Well, it seems like it shouldn't produce any exceptions. It should run forever: create a file, write data to it, close the file. Same thing, over and over again.

The usings should ensure that the BinaryWriter and Stream are closed each time through the loop.

But that's not what happens. Run it enough times, and you'll get an exception: System.IO.IOException: Cannot create a file when that file already exists. How can that file be in use? You clearly closed it last time through the loop!

Even stranger: if you follow your using with code that is doing something else with the file (like, say, moving it), you'll occasionally see a System.UnauthorizedAccessException: Access to the path is denied exception. This is a file that you clearly are authorized to access--you just created it!

Note: adding explicit calls to sw.Close() and bw.Close() doesn't change the behavior--you still get exceptions eventually.

This seems like some unholy combination of a problem between .NET, Win32, and the OS, combined with an incorrect exception being thrown sometimes.

Unfortunately, this little nasty reared its head on a customer site. And, naturally, it wasn't tightly packaged like the code above. Occasionally, inexplicably, exceptions were being thrown. It's hard to reproduce in the wild, and it took us a few days to track down and boil down.

Wow. Any .NET experts care to weigh in on why this would throw exceptions?

Watch Robert's blog to see how we ended up fixing this...

Update 2/15/2008 9:12: After a conversation with Robert, I felt I should make it clear: our software didn't have a loop like the one written above; we came up with that when trying to reproduce the behavior. He'll have more details later...

Technorati tags:

Friday, February 08, 2008

Quick visit to the 212

John Powers and I will be at the Web Services on Wall Street conference on Monday, February 11th, at the Roosevelt Hotel in Manhattan.

This conference was created by the same folks who put on the High Performance on Wall Street conference -- and that was probably the best event I attended last year.

If you're in Midtown on Monday, stop on by...

Monday, February 04, 2008

Digipede Network Free for MS MVPs

I'm very excited about this announcement.

As of today, Microsoft MVPs can get a free license to the Digipede Network Professional Edition, with 10 agent processor licenses.

Digipede joins a list of over 100 companies that make licenses free for this vibrant community of technical specialists, and we're proud to do it.

Many people outside the .NET world don't realize what a community Microsoft has fostered, and MVPs are a perfect example. They aren't Microsoft employees, but they spend a good deal of time engaging in the community, essentially helping Microsoft to evangelize the platform. They help other users on message boards, they facilitate users' groups, they put on code camps.

I can't wait to see what some of these folks do with the Digipede Framework SDK!

If you're an MVP, head over here to claim your software...

Technorati tags: , ,

Thursday, January 31, 2008

Hey, Excel: Resolver One understands .NET. Are you learning?

I've posted extensively about Excel and Excel Services, and without a doubt my biggest disappointment with Excel 2007 was the lack of .NET integration. Excel forces a developer to jump back into the 20th century to do COM development. I lamented this; I wish that the Excel team had adopted .NET.

Well, earlier this week I found a spreadsheet that goes far beyond my expectations for .NET integration: Resolver One. (BTW, when Harry Pierson and Larry O'Brien both mention a product within a couple of days of each other, check it out).

Resolver One is a powerful spreadsheet tool based on Python. It translates your spreadsheet logic into Python, and it even lets you write your spreadsheet logic in Python.

But what really impressed me was the .NET integration. They've got a very interesting take on how to integrate -- much more interesting than Microsoft's VSTO.

Rather than simply let you put .NET code behind your spreadsheet, ResolverOne actually allows you to put .NET objects into your spreadsheet cells. That's right -- simply add a reference to your DLL, then you can enter =MyClass() into a cell. It will instantiate your class, and store it "in the cell." If your constructor takes arguments, no problem: Enter something like =MyClass(B1, B2) to pass the contents of cells B1 and B2 to your constructor.

How can you take advantage of this object? Well, now other cells can use that object -- pulling properties out for example. So if your object is in cell C1 and you want to pull out one of its properties into cell D1, you can enter =C1.MyProperty.

Other great things about this product: it's $99 for a commercial license. Free for a non commercial license.

This .NET integration made it a snap for me to adapt to commanding an app on the grid. I had my standard "MonteCarloPi" grid application running after about 5 minutes of coding (I'll post that source soon). And when I say "5 minutes," I mean 5 minutes. It was ridiculously easy, and that's a very good thing. With 5 minutes of coding, I had my simple, single-threaded .NET object running in parallel on all of the multicore machines in my office, and the results were being displayed in the spreadsheet.

In a way, Resolver One's use of .NET reminded me a lot of our own use of .NET. Whereas previous spreadsheets (and grid computing software) required you to take an enormous step backwards in programming technology in order to write programs, Resolver One (and Digipede) actually leverage the programming models of .NET to make the developer more at home and more productive.

All in all, it's a very impressive product. Microsoft, are you watching?

Update 2008-01-31 12:02 Harry Pierson just listed Resolver One as one of the highlights of LANG.net, and points out that the talks should be online soon.

Update 2008-01-31 12:32 Half an hour later, Larry O'Brien calls Resolver One the most impressive application from LANG.net.

Technorati tags: , ,

Thursday, January 24, 2008

Off topic: Where's my HD Movie Rental?

This is way off topic for a grid computing blog -- but I have to get it off my chest.

I will never, ever consider buying a set-top box dedicated to online movie rentals (see Vudu, AppleTV, Netflix).

But if Microsoft or Sony announces HD rentals through an XBox 360 or the PS3, I'm buying one immediately.

Why doesn't this exist?

I want a multi-purpose box. Plays my DVDs. Plays games. HD Movie rentals online.

The XBox and PS3 already have HD out and internet connections. Can they just write this software, make some deals with studios, and be done with it? Bill, this is your chance to beat Steve to a punch for once.

Wednesday, January 23, 2008

Your Grid Ate My Battery!

I've read a lot lately about the prospect of doing cloud computing on mobile devices.

I first read about the idea at ThinkInGrid (in Spanish, no less--they've since switched to English and it's much easier for me to digest!).

Lately, with the attention on cloud computing and with Google announcing Android for mobile devices, I've seen more references. Nikita over at GridGain blogged about it and subsequently got a bunch of attention: Bob Lozano picked up on the thread, and Olga Kharif at Business Week even did a column on it.

However, with the exception of Alex Miller's post on the subject, everyone seems to skip over a very salient point: battery life is perhaps the most important feature in a mobile device.

CPUs use tons of power. Mobile OSs work very hard to preserve battery life as much as possible. My phone has games built in to it, and if I make the mistake of not exiting one of those games after playing, my battery will be gone within an hour.

While I love the idea of cloud computing, I'd never trade a single cycle of my phone's CPU in exchange for shorter battery life. I don't want a thousand free minutes--I want to be able to leave Bluetooth on all the time without draining my battery!

And this doesn't even get into the question of bandwidth.

I do think that there is life beyond servers for grid computing: we have customers with desktops and even laptops contributing cycles. But if it doesn't have an AC adaptor plugged into it, it's not going to do very much good on a grid...

Photo credit: gracey

Friday, January 18, 2008

Herb Sutter: Lawbreaker!


Herb Sutter just posted a link to his latest article in Dr. Dobb's Journal, and in it he advocates breaking the law.

Don't worry -- he's not about to get any jail time. He's offering a great take on how to break Amdahl's Law. It's very practical advice for getting the most of your multiprocessor and multicore machines.

One of the strategies he sees is Gustafson's Law: to increase the speed up of your parallelized application, do more parallel work.

Amdahl's law says that the total time taken by your application is computed thusly:

totaltime = s + p/n
(where s is the serial component of your work, p is the parallel component, and n is the number of cores), and therefore
speedup = (s + p)/(s + p/n)
John Gustafson pointed this out: What happens when you vastly increase p and n? You get a much better speedup value.

It's a very practical look at what we see in our business every day: having access to much more parallel computing power gives you the ability to take on much, much larger jobs. You do analysis that you would never dream of doing on a single core on a single machine.

Of course, Herb is talking about the difference between single core machines and multicore machines -- but the exact same concepts apply to multiple machines. If going from 1 to 4 cores changes the very nature of the work you can do, imagine what going from 4 to 400 does!

And, as Herb points out, this is very, very common.

As I like to say, "Any algorithm worth doing once is worth doing many times." If you've got earth's best stock-price algorithm, would you run it on only one stock? If you have a fantastic rendering tool, would you use it to render only one frame? Of course not. And dividing up your data doesn't make something embarrassingly parallel--it makes it delightfully parallel!


Tuesday, January 15, 2008

Sun Abandons Computers?

Strange news out of Santa Clara...

Two of my favorite reads, Nicholas Carr's Rough Type and John E. West's insideHPC, both pointed me to the same blog post by Sun's Data Center Architect, Brian Cinque. When those guys link to the same post, you know it's worth reading.

Cinque gives the broad strokes of Sun's plans for data center consolidation, which include reducing total square footage and electric consumption by 50% over the next 5 years. Admirable enough.

But Cinque continues...within two years of that, Sun plans to own ZERO data centers.

While he neglects to give any other details, it seems clear that this can only mean one thing: Sun is going to spend the next five years consolidating into a small number of data centers...and then they're going to sell them.

Clearly, after a 5 year effort of consolidation and rearchitecture, they're not going to spend the next 2 years scrapping all that work. Rather, they have decided that they'll let someone else take care of running them. Why? Well, ostensibly, it's because they think someone else can do it better/faster/cheaper then they can.

It's a bit surprising to me. Sun has spent the last year and a half convincing people to run their grid applications on Sun Grid--now they're telling the market that someone else is more qualified to run their own data centers. If I were a Sun customer, I'd be running to EC2 immediately.

On the other hand, maybe it's not so surprising at all, given that Sun now seems to be a database company...

Technorati tags: , ,

Tuesday, January 08, 2008

Partnering with Microsoft: The Ugly


My colleague John Powers has frequently posted about the good, the bad, and the ugly of partnering with Microsoft--and today's post would definitely qualify as "the ugly."

He's going through the annual process of renewing our Gold Certified status, and, as usual, he's suffering through hours of terrible user experience on their website.

I'll give a short summary here, but you should go read John's post for the full, gory detail.

Unfortunately, part of the process involves getting customer references, and that means having our best customers try to use the Microsoft partner website. This means that we are now subjecting our best, most valuable customers to the frustrations of trying to use a slow, buggy site. Our customers are already doing us a favor by filling out these forms--now Microsoft making is them take (a lot of) extra time, suffering through numerous timeouts, crashes, etc.

Put another way: Microsoft is asking us to piss off our most important customers for the sake of our partner status.

We see a lot of value in the partner program and in Gold Certified status; we're willing to put up with a lot of hassle. But asking our customers to deal with that hassle is too much.

Technorati tags:

Thursday, January 03, 2008

MSFT Supercomputing video online

Right before my weeks-long blogging blackout at the end of last year, I wrote that I was headed to Supercomputing in Reno. I never wrote an SC07 wrapup (although John Powers wrote one here), and it seems a bit late to do one now.

However, Patrick O'Rourke of Microsoft just told me about some videos they produced at SC07 and have gone online recently, including one that features an interview with me.

Check out the HPC++ page on the Microsoft site, and look for the Windows HPC in Financial Services link. It's a 9 minute video that features an interview with Jeff Wierer of Microsoft and a few different partners.

Patrick saved the best for last, by the way--my mug appears about 7 minutes in. If you watch the whole thing you'll notice, of course, that we're the only partner who can stake the claim to being all .NET.

(Note: ironically, I can't get that video to play in IE, but it works fine in Firefox. Don't tell my Microsoft friends I've got Firefox on my machine).

Technorati tags: , ,

Wednesday, January 02, 2008

Distributed F# Sample

The week between Christmas and New Year's Day is typically a slow one; I took advantage of some quiet time in the office to play with F#. What with F# becoming a "first class" .NET language and shipping with VS 2008, I wanted to see what it would take to adapt one of our standard samples (using a Monte Carlo calculation to compute Pi in parallel across different cores and machines on the grid).

I was a bit rusty in functional programming (I took Lisp in about 1990), and the eventing took a bit of research to understand, but I got something working. (See code below) I'm not sure if I've made any grievous errors -- if you see any, please let me know!

I know Don Syme recently posted about using Parallel Extensions in F#; next I'll have to take a look to see if I can extend that from using many cores to using many cores on many boxes.

Anyway, here's the F# code I ginned up:
// F# Digipede Sample

#light
open System

let mutable AccumulatedPi = 0.0

let numTasks = 100
let numIterationsPerTask = 1000000

// This function determines if a point lies within the Unit Circle
let InUnitCircle x y = sqrt(x * x + y * y)
// This is the class that will be distributed for remote computation; the DoWork
// method is overridden, and will be invoked on the objects when
// they are on the remote nodes
type MyWorker =
  class
    inherit Digipede.Framework.Api.Worker
    val mutable _Pi : double
    val _NumIterations : int new(a) = { _NumIterations=a; _Pi=0.0 }

    override x.DoWork() =
      let r = new Random(x.Task.TaskId)
      let mutable XCoord = 0.0
      let mutable YCoord = 0.0
      let mutable NumberInUnitCircle = 0

      for i = 0 to x._NumIterations do
        XCoord <- r.NextDouble()
        YCoord <- r.NextDouble()
        NumberInUnitCircle <- NumberInUnitCircle + if InUnitCircle XCoord YCoord then 1 else 0

      x._Pi <- 4.0 * double NumberInUnitCircle / (double x._NumIterations)
    end


// This function will be called (in the "master application") for each task that
// completes (see reference below)
let OnTaskCompleted (args) =
  let myArgs = (args :> Digipede.Framework.Api.TaskStatusEventArgs )
  let returnedWorker = (myArgs.Worker :?> MyWorker)
  printf " Task %d calculated %f \n" myArgs.TaskId returnedWorker._Pi
  AccumulatedPi <- AccumulatedPi + returnedWorker._Pi
  printf " Current total is %f\n" AccumulatedPi


// Ok, this is the code that is the "master" application. It will define and submit the job

// First, we instantiate a Digipede Client and tell it where the Digipede Server is
let Client = new Digipede.Framework.Api.DigipedeClient()
Client.SetUrlFromHost("myservername")

// Now, tell the system what class we're distributing. It will automatically
// determine which binaries need to be distributed to use this class
let JT = Digipede.Framework.JobTemplate.NewWorkerJobTemplate(type MyWorker ) ;
// this line tells the Digipede Agent to run these tasks "per core" on multi-core machines
JT.Control.Concurrency <- Digipede.Framework.ApplicationConcurrency.MultiplePerCore // Create a job, and add tasks to it. Each task gets a new MyWorker object
let aJob = new Digipede.Framework.Job()
aJob.Name <- "F# Job"
for i = 1 to numTasks do
let myTask = new Digipede.Framework.Task()

let mw = new MyWorker(numIterationsPerTask)
myTask.Worker <- (mw :> Digipede.Framework.Api.Worker)
aJob.Tasks.Add(myTask)


// Next, I set up some events.
(* This is like an anonymous delegate. It will get executed each time we get notified that a task has completed. *)

do aJob.TaskCompleted.Add
(fun args -> ( printf "Task %d executed on %s \n" args.TaskId args.TaskStatusSummary.ComputeResourceName ) )

do aJob.TaskFailed.Add (fun args -> ( printf "Task %d failed \n" args.TaskId) )

// Another way to handle events is to give it a function to call on task completion
// I'm doing both, which is redundant
do aJob.TaskCompleted.Add(fun args -> OnTaskCompleted args)


let sr = Client.SubmitJob(JT, aJob)

printf "Submitted job %s\n" (sr.JobId .ToString() )
printf "Waiting for results\n"

let mybool = Client.WaitForJob(sr.JobId)
printf "Job finished\n"

AccumulatedPi <- AccumulatedPi / (double numTasks) printf "Calculated pi is %f\n" AccumulatedPi Threading.Thread.Sleep(5000)


As I said before: this is my very first dabble into F#, and I may be making mistakes. But it runs, and I've figured out a couple of ways to handle events.

Technorati tags: , ,

Monday, November 12, 2007

See you at SuperComputing!

One more time: see you in Reno at SuperComputing. I've got a bunch of meetings, but when I'm not in a meeting I'll be standing in the AMD booth showing off a .NET deskside "supercomputer." (I have to put that in quotes because there will be real super computers there...)

I'll probably try to do some blogging from there, but I can guarantee you that your best bet for many, many informative blog posts will be John E. West's insideHPC. That guy finds more HPC nuggets than seems humanly possible, and he somehow manages to write about them in a way that makes it fun to read!

So watch this space, but watch that space, too.

If you're in Reno and can't find me, I'm at 510-816-7551.

Technorati tags:

Friday, November 09, 2007

Feedburned!

Seems to have been a dramatic downturn in my number of subscribers overnight--I'm down about 40%. Wow!

I'm the type of attention-seeking, fragile-ego'd blogger whose happiness depends on stats like these!

Checking my Feed stats, though, I can see what happened: Google Feedfetcher went from reporting 80 users to reporting 0! That's weird, because I use Feedfetcher...you'd think there would be at least one.

Google, can't you buy Feedburner so you can straighten this out?


Technorati tags: ,

Thursday, November 08, 2007

What Do Digipede and FreshBooks Have In Common?

I saw a post about going the extra mile by Josh Catone at Read/WriteWeb, and I wanted to give credit to one of my colleagues. Josh recounted the story that Oceanic had with FreshBooks, and notes the importance of good customer service.

I made a reference to this the other day, but I want to tell the whole story to give a hat tip to my colleague Nathan.

A couple of weeks ago, one our partners wanted to do some unsupported work with the Digipede Network. Matt Davey of Lab49 wanted to install the Digipede Network Developer Edition (which includes the server, an agent, and the SDK) on Vista. While we support Vista for the agent and the SDK, we hadn't yet upgraded our server installs to work with IIS 7 on Vista (not a problem, since most customers run our Server on Server 2003).

When Matt had a problem with the install (predictably), he contacted my colleague Nathan Trueblood. Rather than tell a valuable partner that we don't support that configuration yet, Nathan took time to figure out how to make things work for Matt. He could have said "Just install a VM and run it in there," he could have told him to wait a couple of months, he could have done a lot of other things.

Instead, he went the extra mile. He tweaked an install, and even had to use LogMeIn to help configure things properly on Matt's machine.

Matt loved it: "I have to say digipede probably have the best customer support in the world. " He also went on to create a very cool LINQ/Digipede sample.

As Josh at Read/WriteWeb put it:

But doing the little things that allow you to form a connection with your customers on a personal level can score you a lot of capital with them.
Good job, Nathan.

Social Networking Post

If you read this blog for grid computing and technical discussion, feel free to ignore this post.

If you're into the world of Web 2.0-style networking, here's how you can follow my every move:

On Facebook, I'm Dan Ciruli.
On LinkedIn, I'm Dan Ciruli
I twitter as Oaktowner.

Can't wait that long? IM me:
AIM: ciruli
MSN: dan@digipede.net
GTalk: ciruli
skype: danciruli

Wednesday, November 07, 2007

Vista: Burn!

I've neither loved nor hated my Vista experience. It's got lots of GIFWOM (Gratuitous Interface Fluff/Waste of MIPS*), but on the whole it hasn't radically changed my computer-using experience.

Today has been extremely frustrating, though. We're participating in Microsoft's Server 2008 Early Adopter Program, and we're excited to get the RC0 of Server 2008 installed on some of our machines for testing.

They haven't released a VHD yet, though, so we're stuck with downloading a 2.6GB ISO file, burning it to DVD, then installing from DVD. Fine.

However, my machine (a Compaq nc8430), my OS (Vista Business), my DVD drive (an "HL-DT-ST DVDRAM GSA-4084N ATA Device), and Roxio 9 all seemed to get in an enormous fight. And when they fight, I lose.

Burns got 95%, then stopped. Burns got 1 sector in, then stopped. The drive stopped ejecting. Roxio wouldn't shut down for any reason.

After several attempts and several reboots, I got pretty frustrated. A little Googling Live Searching brought me to this post from Rick Hallihan.

I downloaded the Windows Resource kit, and had at my disposal a command line DVD burner.

dvdburn.exe d: en_windows_server_2008_rc0_enterprise_datacenter_standard_x64_dvd.iso was all it took. A few minutes later, I was installing.

If it's this easy on the command line, why is it so hard through a GUI?

*credit for the term GIFWOM goes to my old friend and colleague Jeff Weidner (and if you want to remember what the internet was like in 1997 and people were first putting up "home pages," I highly recommend that you click on that link!

Updated 2007-11-08: added a link to the WRK.

Technorati tags: