Archive for October 2010

reverse-i-search: Quicksilver for Bash

Solomon Boulos just pointed out the most useful bash feature I’ve found so far. Reverse-i-search! Like the emacs functionality, it autocompletes the command you’re typing in according to your history file, in the order of your history file.

Access this magic by hitting “Control-R”. Start typing a command and it will autocomplete it for you. Keep hitting Control-R and it will cycle through all possible matches. Incredibly useful! It’s like using ! except you can see what it’s going to execute.

Running CUDA without running X

I want to run multiple graphics cards on CUDA without starting X, since I have a bunch of GPUs sitting in a headless box. Since the GPU drivers does not get loaded without X running (or, in ubuntu, only some of the cards gets loaded), I put together a init.d script that brings up all the nvidia GPUs on your Ubuntu 10.04 box:

#!/bin/bash

COMMAND="$1"
case $COMMAND in
start|stop|restart)

 if [ "$COMMAND" = "restart" ] || [ "$COMMAND" = "stop" ]; then
 NVIDIADEV=`ls -l /dev/nvidia* | awk '{if ($9 != "/dev/nvidiactl") a+=1}END{print a}'`
 NDEV=`expr $NVIDIADEV - 1`
 for i in `seq 0 $NDEV`; do
 unlink /dev/nvidia$i
 done
 unlink /dev/nvidiactl
 fi

 if [ "$COMMAND" = "restart" ] || [ "$COMMAND" = "start" ]; then

 modprobe nvidia

 if [ "$?" -eq 0 ]; then

 NVGA=`/usr/bin/lspci | grep VGA | wc -l`

 N=`expr $NVGA - 1`
 for i in `seq 0 $N`; do
 mknod -m 666 /dev/nvidia$i c 195 $i
 done
 mknod -m 666 /dev/nvidiactl c 195 255

 fi
 fi
 ;;

*)
 echo "$COMMAND is not supported on this job."
 ;;
esac

Coffee

Black? No, with milk and sugar. A civilized drink, by all accounts. Sweet, aromatic, only with the finest freshly ground beans. I can taste the difference, I think. At least, I can’t help but wrinkle my nose and suppress the urge to dump the black tar that comes out of the office thermos. So surely, yes, I can taste the difference. Then again, it might just be the circumstances – after midnight anything with caffeine will taste better. Although it’s a fine drink to start your day with, something about coffee makes it a drink of the night. When your desklamp and a monitor is in stark contrast to the blackness outside, the drink somehow feels at home. It’s content to sit in my cup, lazily swirling as I type. In the morning it’s a swallow-and-go experience, almost as if it wants to disappear out of the sunlight. But at night it languishes, a stray cat outside your window – not a friend, but a presence, a fog through which the rest of the world loses shape. Opportunities bristling with anticipation to be pounced on, yet happily waiting until the cup is once again standing between printouts and cables – knowing full well that the cup touching the table starts the inevitable recession of those very opportunities so close just a second before. Nothing to do but pick up the warm ceramic again. Its not a dependence, that would imply a subjugation of myself – rather, it’s the feeling of an old friend I have a brief chance to confer with. I let life stream by for a little while, conversing, bringing up memories, making plans. Energized after this brief interlude I walk on – no plans to…

I digress, the cup is now empty, the visit is over, and Haskell doesn’t learn itself.

Creating a SVN-Like Centralized Git repository

There’s a simple way to create a central git repository:

git init --bare --shared

This will create a repository that you cannot commit data to if your commit will cause any merge conflicts (it forces you to make only additions) and it has permissions set up to allow multiple users to access the repo. The config, as of git 1.7, looks like this:

[core]
	repositoryformatversion = 0
	filemode = true
	bare = true
	ignorecase = true
	sharedrepository = 1
[receive]
	denyNonFastforwards = true

Now you can clone this repository easily!

If you want to take a current local repository and create a remote central repository:

First, we clone the local repository into a new, bare repository:

cd tempdir
git clone --bare /path/to/original/repo

Then we add the denyFastForwards option and add the shared option:

git config recieve.denyNonFastforwards true
git config core.sharedrepository 1

We can now copy this new repository to whatever server we want and set all that up. Lastly, we want our original repository to point to this new repository as its primary remote repository. For this we have to set up some remotes and the like:

cd /path/to/original/repository
git remote add origin git+ssh://server/path/to/remote/repo
git config branch.master.remote origin
git config branch.master.merge refs/heads/master

The last two commands sets up the local repository to track the remote repository by default, so that it will be the repo that responds to get push and git pull.

This blog post was inspired by this, this, this and this. And my general frustration of not having all this in a little script.

New hardware! 32 core box!

Our new server just arrived! Quad socket 32 core box, dope shit! Fresh from Intel, you can hardly buy this kind of hardware.

Haskell Idioms (Part 1?)

I’m taking Stanford’s Programming Languages class, and I’m back in the happy fuzzy world of functional programming that started my computer science education back at Berkeley with Prof. Brian Harvey’s CS61A. Except this time around we’re doing it in Haskell!

Haskell, so far, has a couple of cool features that’s jumped out at me. (Features is not really the right word, rather, design decision?):

  • Lazy Evaluation – this is the big, obvious one that really influences the idioms you use to write code
  • Pattern Matching that’s so ridiculous that if I haven’t been writing Scala I would be completely lost, now I’m only 99% mind-blown.
  • Cutesy math syntax (for example, list comprehension looks just like math notation: [x * 2 | x <- originalList]
  • Multi-Branch functions. AKA, you can define multiple versions of a function (like overloading) and the correct one will be taken. Sounds like overloading, but it blows your mind combined with laziness, of which I’ll give an example in a second
  • Functions are either curried or pattern-matched. So, pretty much all my functions can be partially applied.
  • Convert prefix operators to infix using “ and infix operators to prefix using ().  Neato
  • Type Inference. I’m a huge believer in static typing with type inference these days. Eating cake while having cake is the best.

OK, that was a boring lame list of stuff that I’ll probably skip whenever I read this blog post. Notice how I blog to remember stuff.

Multi-Branch function example:

listLength [] = 0
listLength (x:xs) = 1 + listLength xs

That’s just looks cool. Straight out of a math textbook.

Helper Functions Idiom:

Haskell (obviously) has nested functions, so you can write functions using local helper functions and accumulators inside the function’s scope. For example, you can write reverse in the “simple” functional manner like so:

reverse [] = []
reverse (x:xs) = (reverse xs) ++ [x]

Using, naturally, the cons operator (:), the concatenate operator (++) and the list syntax []. This is an inefficient algorithm, since it sweeps the list twice (once going down calling reverse on the cdr of the list, once sweeping back appending elements). Or, you can write reverse sweeping the list only once, using local scope and a helper function:

reverse xs =
  let rev( [], z) = z
      rev( y:ys, z) = rev( ys, y:z )
  in rev( xs, [] )

That’s a whole lot in only 4 lines, but it only sweeps the list once to reverse it. As you can (kinda) tell, it keeps cons-sing (: operator) the first element of the rest of the list to the first element of the new list being built. That is, it puts the “next” element as the “first” element. This is how you reverse a list, if you think about it for a bit. Cool huh!

Multi-Branch Function Idiom using Laziness

Since the compiler picks the function branch that pattern matches (including type matches) what you’re calling the function on, you can write plenty of code using a haskell idiom that would epic-fail in other languages.

The idiom consists of writing a main function that generates (lazily) all possible points in the solution space and exhaustively searches through it, and writing a set of small “filter” branches of this function that guides the search to be efficient. The laziness prevents tons of temporaries, the branches guides the search.

For example, consider substring matching. You can say that finding whether a string is a substring of another string is the same as generating all suffixes of the string and checking whether your string is a prefix on any of these suffixes. Let’s just write that:

x `isSubString` s = or [x `isPrefixOf` t | t <- suffixes s ]
suffixes [] = [""]
suffixes (x:xs) = (x:xs) : suffixes xs

mind blown! zomg! So, on the first line we say, x is a substring of s if x isPrefixOf t evaluates to true for all t in suffixes of s. then we define suffixes of the empty list as the empty string, and suffixes of a non-empty list as that list, cons’ed to the suffixes of everything but the first character of the input list. And that’s all you need, it won’t generate all options, it’ll lazily evaluate things, pattern-matching the type of list to the branch of the function, going nuts.

Define your own conditionals!

Since Haskell is lazy, you can write your own if statement or boolean operator and it’s just like the real thing! In fact, you can write your own eval function in about 10 lines.

Infinite data structures!

Of course, this just comes with laziness. Just implement prime number searching or whatever.

Lots of other cool stuff in here.